PageRenderTime 62ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/build42/harbour/source/pp/ppcore.c

#
C | 2292 lines | 1816 code | 281 blank | 195 comment | 645 complexity | f668ae6746483a7d3a12920e734cb9b3 MD5 | raw file
Possible License(s): AGPL-1.0, BSD-3-Clause, CC-BY-SA-3.0, LGPL-3.0, GPL-2.0, LGPL-2.0, LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * $Id: ppcore.c 5899 2003-04-04 07:18:24Z alkresin $
  3. */
  4. /*
  5. * Harbour Project source code:
  6. * Preprocessor core module
  7. *
  8. * Copyright 1999 Alexander S.Kresin <alex@belacy.belgorod.su>
  9. * www - http://www.harbour-project.org
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; either version 2, or (at your option)
  14. * any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this software; see the file COPYING. If not, write to
  23. * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  24. * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/).
  25. *
  26. * As a special exception, the Harbour Project gives permission for
  27. * additional uses of the text contained in its release of Harbour.
  28. *
  29. * The exception is that, if you link the Harbour libraries with other
  30. * files to produce an executable, this does not by itself cause the
  31. * resulting executable to be covered by the GNU General Public License.
  32. * Your use of that executable is in no way restricted on account of
  33. * linking the Harbour library code into it.
  34. *
  35. * This exception does not however invalidate any other reasons why
  36. * the executable file might be covered by the GNU General Public License.
  37. *
  38. * This exception applies only to the code released by the Harbour
  39. * Project under the name Harbour. If you copy code from other
  40. * Harbour Project or Free Software Foundation releases into a copy of
  41. * Harbour, as the General Public License permits, the exception does
  42. * not apply to the code that you add in this way. To avoid misleading
  43. * anyone as to the status of such modified files, you must delete
  44. * this exception notice from them.
  45. *
  46. * If you write modifications of your own for Harbour, it is your choice
  47. * whether to permit this exception to apply to your modifications.
  48. * If you do not wish that, delete this exception notice.
  49. *
  50. */
  51. /*
  52. * The following parts are Copyright of the individual authors.
  53. * www - http://www.harbour-project.org
  54. *
  55. * Copyright 1999-2001 Viktor Szakats <viktor.szakats@syenar.hu>
  56. * __DATE__, __TIME__, __HB_MAIN__ support
  57. *
  58. * Copyright 2000 Ron Pinkas <Ron@Profit-Master.com>
  59. *
  60. * hb_pp_SetRules() and related code for supportting
  61. * replaceable rules with -w switch
  62. *
  63. * See doc/license.txt for licensing terms.
  64. *
  65. */
  66. /*
  67. * Avoid tracing in preprocessor/compiler.
  68. */
  69. #if ! defined(HB_TRACE_UTILS)
  70. #if defined(HB_TRACE_LEVEL)
  71. #undef HB_TRACE_LEVEL
  72. #endif
  73. #endif
  74. #include <time.h>
  75. #include <errno.h>
  76. #include "hbpp.h"
  77. #include "hbcomp.h"
  78. #if defined( OS_UNIX_COMPATIBLE )
  79. #include <sys/timeb.h>
  80. #else
  81. #include <sys\timeb.h>
  82. #endif
  83. int hb_pp_ParseDefine( char * ); /* Process #define directive */
  84. static COMMANDS * AddCommand( char * ); /* Add new #command to an array */
  85. static COMMANDS * AddTranslate( char * ); /* Add new #translate to an array */
  86. static DEFINES * DefSearch( char *, BOOL * );
  87. static COMMANDS * ComSearch( char *, COMMANDS * );
  88. static COMMANDS * TraSearch( char *, COMMANDS * );
  89. static int ParseUndef( char * ); /* Process #undef directive */
  90. static int ParseIfdef( char *, int ); /* Process #ifdef directive */
  91. static void ParseCommand( char *, BOOL, BOOL ); /* Process #command or #translate directive */
  92. static void ConvertPatterns( char *, int, char *, int ); /* Converting result pattern in #command and #translate */
  93. static int WorkDefine( char **, char *, DEFINES * ); /* Replace fragment of code with a #defined result text */
  94. static int WorkPseudoF( char **, char *, DEFINES * ); /* Replace pseudofunction with a #defined result text */
  95. static int WorkCommand( char *, char *, COMMANDS * );
  96. static int WorkTranslate( char *, char *, COMMANDS *, int * );
  97. static int CommandStuff( char *, char *, char *, int *, BOOL, BOOL );
  98. static int RemoveSlash( char * );
  99. static int WorkMarkers( char **, char **, char *, int *, BOOL );
  100. static int getExpReal( char *, char **, BOOL, int, BOOL );
  101. static BOOL isExpres( char *, BOOL );
  102. static BOOL TestOptional( char *, char * );
  103. static BOOL CheckOptional( char *, char *, char *, int *, BOOL, BOOL );
  104. static void SkipOptional( char ** );
  105. static void SearnRep( char *, char *, int, char *, int * );
  106. static int ReplacePattern( char, char *, int, char *, int );
  107. static void pp_rQuotes( char *, char * );
  108. static int md_strAt( char *, int, char *, BOOL, BOOL, BOOL );
  109. static char * PrevSquare( char * , char *, int * );
  110. static int IsInStr( char, char * );
  111. static int stroncpy( char *, char *, int );
  112. static int strincpy( char *, char * );
  113. static BOOL truncmp( char **, char **, BOOL );
  114. static BOOL strincmp( char *, char **, BOOL );
  115. static int strotrim( char *, BOOL ); /* Ron Pinkas 2001-02-14 added 2nd parameter */
  116. static int NextWord( char **, char *, BOOL );
  117. static int NextName( char **, char * );
  118. static int NextParm( char **, char * );
  119. static BOOL OpenInclude( char *, HB_PATHNAMES *, PHB_FNAME, BOOL bStandardOnly, char * );
  120. static BOOL IsIdentifier( char *szProspect );
  121. #define ISNAME( c ) ( isalnum( ( int ) c ) || ( c ) == '_' || ( c ) > 0x7E )
  122. #define MAX_NAME 255
  123. #define MAX_EXP 2048
  124. #define PATTERN_SIZE 2048
  125. #define STATE_INIT 0
  126. #define STATE_NORMAL 1
  127. #define STATE_COMMENT 2
  128. #define STATE_QUOTE1 3
  129. #define STATE_QUOTE2 4
  130. #define STATE_QUOTE3 5
  131. #define STATE_ID_END 6
  132. #define STATE_ID 7
  133. #define STATE_EXPRES 8
  134. #define STATE_EXPRES_ID 9
  135. #define STATE_BRACKET 10
  136. #define IT_EXPR 1
  137. #define IT_ID 2
  138. #define IT_COMMA 3
  139. #define IT_ID_OR_EXPR 4
  140. #define HB_PP_MAX_INCLUDES FOPEN_MAX - 5 - 1
  141. /* Ron Pinkas added 2000-01-24 */
  142. #define IS_2CHAR_OPERATOR( p ) ( p[0] && p[1] && ( strncmp( p, ":=", 2 ) == 0 || \
  143. strncmp( p, "+=", 2 ) == 0 || \
  144. strncmp( p, "-=", 2 ) == 0 || \
  145. strncmp( p, "*=", 2 ) == 0 || \
  146. strncmp( p, "/=", 2 ) == 0 || \
  147. strncmp( p, "^=", 2 ) == 0 || \
  148. strncmp( p, "==", 2 ) == 0 || \
  149. strncmp( p, "<>", 2 ) == 0 || \
  150. strncmp( p, "<=", 2 ) == 0 || \
  151. strncmp( p, ">=", 2 ) == 0 || \
  152. strncmp( p, "++", 2 ) == 0 || \
  153. strncmp( p, "--", 2 ) == 0 || \
  154. strncmp( p, "->", 2 ) == 0 ) )
  155. /* END, Ron Pinkas added 2000-01-24 */
  156. static int s_kolAddDefs = 0;
  157. static int s_kolAddComs = 0;
  158. static int s_kolAddTras = 0;
  159. static int s_ParseState;
  160. static int s_maxCondCompile;
  161. static int s_aIsRepeate[ 5 ];
  162. static int s_Repeate;
  163. static BOOL s_bReplacePat = TRUE;
  164. static int s_numBrackets;
  165. static char s_groupchar;
  166. static char s_prevchar;
  167. int * hb_pp_aCondCompile = NULL;
  168. int hb_pp_nCondCompile = 0;
  169. BOOL hb_ppInsideTextBlock = FALSE;
  170. char * hb_pp_STD_CH = NULL;
  171. /* Ron Pinkas added 2000-11-21 */
  172. static BOOL s_bArray = FALSE;
  173. #if defined(__WATCOMC__)
  174. extern BOOL hb_pp_bInline;
  175. extern int hb_pp_LastOutLine;
  176. #endif
  177. /* Table with parse errors */
  178. char * hb_pp_szErrors[] =
  179. {
  180. "Can\'t open #include file: \'%s\'; %s",
  181. "#else does not match #ifdef",
  182. "#endif does not match #ifdef",
  183. "Bad filename in #include",
  184. "#define without parameters",
  185. "Missing => in #translate/#command \'%s\' [%s]'",
  186. "Error in pattern definition",
  187. "Cycled #define",
  188. "Invalid name follows #: \'%s\'",
  189. "\'%s\'",
  190. "Memory allocation error",
  191. "Memory reallocation error",
  192. "Freeing a NULL memory pointer",
  193. "Value out of range in #pragma directive",
  194. "Can\'t open command definitions file: \'%s\'",
  195. "Invalid command definitions file name: \'%s\'",
  196. "Too many nested #includes, can\'t open: \'%s\'",
  197. "Input buffer overflow"
  198. };
  199. /* Table with warnings */
  200. char * hb_pp_szWarnings[] =
  201. {
  202. "1Redefinition or duplicate definition of #define %s",
  203. "1No directives in command definitions file"
  204. };
  205. void hb_pp_SetRules( HB_INCLUDE_FUNC_PTR hb_compInclude, BOOL hb_comp_bQuiet )
  206. {
  207. HB_TRACE(HB_TR_DEBUG, ("hb_pp_SetRules()"));
  208. if( hb_pp_STD_CH )
  209. {
  210. if( *hb_pp_STD_CH > ' ' )
  211. {
  212. hb_comp_pFileName = hb_fsFNameSplit( hb_pp_STD_CH );
  213. if( hb_comp_pFileName->szName )
  214. {
  215. char szFileName[ _POSIX_PATH_MAX ];
  216. if( ! hb_comp_pFileName->szExtension )
  217. hb_comp_pFileName->szExtension = ".ch";
  218. hb_fsFNameMerge( szFileName, hb_comp_pFileName );
  219. if( (* hb_compInclude)( szFileName, hb_comp_pIncludePath ) )
  220. {
  221. /*
  222. printf( "Loading Standard Rules from: \'%s\'\n", szFileName );
  223. */
  224. hb_pp_Init();
  225. hb_pp_ReadRules();
  226. /*
  227. {
  228. COMMANDS * stcmd;
  229. DEFINES * stdef;
  230. stcmd = hb_pp_topCommand;
  231. while ( stcmd )
  232. {
  233. printf( "Command: %s Pattern: %s\n", stcmd->name, stcmd->mpatt );
  234. stcmd = stcmd->last;
  235. }
  236. stcmd = hb_pp_topTranslate;
  237. while ( stcmd )
  238. {
  239. printf( "Translate: %s \nPattern: %s\n", stcmd->name, stcmd->mpatt );
  240. stcmd = stcmd->last;
  241. }
  242. stdef = hb_pp_topDefine;
  243. while ( stdef && s_kolAddDefs > 3 )
  244. {
  245. printf( "Define: %s Value: %s\n", stdef->name, stdef->value );
  246. stdef = stdef->last;
  247. s_kolAddDefs--;
  248. }
  249. }
  250. */
  251. if ( s_kolAddComs || s_kolAddTras || s_kolAddDefs > 3 )
  252. {
  253. if( ! hb_comp_bQuiet )
  254. printf( "Loaded: %i Commands, %i Translates, %i Defines from: %s\n", s_kolAddComs, s_kolAddTras, s_kolAddDefs - 3, szFileName );
  255. }
  256. else
  257. {
  258. hb_compGenWarning( hb_pp_szWarnings, 'I', HB_PP_WARN_NO_DIRECTIVES, NULL /*szFileName*/, NULL );
  259. }
  260. fclose( hb_comp_files.pLast->handle );
  261. hb_xfree( hb_comp_files.pLast->pBuffer );
  262. hb_xfree( hb_comp_files.pLast );
  263. hb_comp_files.pLast = NULL;
  264. hb_comp_files.iFiles = 0;
  265. hb_xfree( ( void * ) hb_comp_pFileName );
  266. hb_comp_pFileName = NULL;
  267. s_kolAddComs = 0;
  268. s_kolAddTras = 0;
  269. s_kolAddDefs = 0;
  270. }
  271. else
  272. {
  273. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_CANNOT_OPEN_RULES, szFileName, NULL );
  274. }
  275. }
  276. else
  277. {
  278. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_BAD_RULES_FILE_NAME, hb_pp_STD_CH, NULL );
  279. }
  280. }
  281. else
  282. {
  283. if( ! hb_comp_bQuiet )
  284. printf( "Standard command definitions excluded.\n" );
  285. hb_pp_Init();
  286. }
  287. }
  288. else
  289. {
  290. hb_pp_Table();
  291. hb_pp_Init();
  292. }
  293. }
  294. void hb_pp_Free( void )
  295. {
  296. DEFINES * stdef;
  297. COMMANDS * stcmd;
  298. HB_TRACE(HB_TR_DEBUG, ("hb_pp_Free()"));
  299. while( s_kolAddDefs )
  300. {
  301. stdef = hb_pp_topDefine;
  302. if( stdef->pars ) hb_xfree( stdef->pars );
  303. if( stdef->value ) hb_xfree( stdef->value );
  304. if( stdef->name ) hb_xfree( stdef->name );
  305. hb_pp_topDefine = stdef->last;
  306. hb_xfree( stdef );
  307. s_kolAddDefs--;
  308. }
  309. while( s_kolAddComs )
  310. {
  311. stcmd = hb_pp_topCommand;
  312. if( stcmd->mpatt ) hb_xfree( stcmd->mpatt );
  313. if( stcmd->value ) hb_xfree( stcmd->value );
  314. hb_xfree( stcmd->name );
  315. hb_pp_topCommand = stcmd->last;
  316. hb_xfree( stcmd );
  317. s_kolAddComs--;
  318. }
  319. while( s_kolAddTras )
  320. {
  321. stcmd = hb_pp_topTranslate;
  322. if( stcmd->mpatt ) hb_xfree( stcmd->mpatt );
  323. if( stcmd->value ) hb_xfree( stcmd->value );
  324. hb_xfree( stcmd->name );
  325. hb_pp_topTranslate = stcmd->last;
  326. hb_xfree( stcmd );
  327. s_kolAddTras--;
  328. }
  329. }
  330. void hb_pp_Init( void )
  331. {
  332. HB_TRACE(HB_TR_DEBUG, ("hb_pp_Init()"));
  333. hb_pp_Free();
  334. s_ParseState = 0;
  335. s_maxCondCompile = 5;
  336. s_bReplacePat = TRUE;
  337. s_prevchar = 'A';
  338. if( !hb_pp_aCondCompile )
  339. hb_pp_aCondCompile = ( int * ) hb_xgrab( sizeof( int ) * 5 );
  340. hb_pp_nCondCompile = 0;
  341. {
  342. char szResult[ 6 ];
  343. USHORT usHarbour = ( 256 * HB_VER_MAJOR ) + HB_VER_MINOR;
  344. /*
  345. This updates __HARBOUR__ on every change of HB_VER_MAJOR / HB_VER_MINOR
  346. HIBYTE is the HB_VER_MAJOR value and the LOBYTE is the HB_VER_MINOR value.
  347. The check below is to ensure that __HARBOUR__ gets the
  348. value of 1 by default
  349. */
  350. sprintf( szResult, "%05d", ( usHarbour ? usHarbour : 1 ) );
  351. hb_pp_AddDefine( "__HARBOUR__", szResult );
  352. }
  353. {
  354. char szResult[ 11 ];
  355. time_t t;
  356. struct tm * oTime;
  357. time( &t );
  358. oTime = localtime( &t );
  359. sprintf( szResult, "\"%04d%02d%02d\"", oTime->tm_year + 1900, oTime->tm_mon + 1, oTime->tm_mday );
  360. hb_pp_AddDefine( "__DATE__", szResult );
  361. sprintf( szResult, "\"%02d:%02d:%02d\"", oTime->tm_hour, oTime->tm_min, oTime->tm_sec );
  362. hb_pp_AddDefine( "__TIME__", szResult );
  363. }
  364. #ifdef HARBOUR_START_PROCEDURE
  365. hb_pp_AddDefine( "__HB_MAIN__", HARBOUR_START_PROCEDURE );
  366. #endif
  367. }
  368. /* Table with parse warnings */
  369. /* NOTE: The first character stores the warning's level that triggers this
  370. * warning. The warning's level is set by -w<n> command line option.
  371. */
  372. int hb_pp_ParseDirective( char * sLine )
  373. {
  374. char sDirective[ MAX_NAME ];
  375. char szInclude[ _POSIX_PATH_MAX ];
  376. int i;
  377. HB_TRACE(HB_TR_DEBUG, ("hb_pp_ParseDirective(%s)", sLine));
  378. i = NextName( &sLine, sDirective );
  379. hb_strupr( sDirective );
  380. HB_SKIPTABSPACES(sLine);
  381. if( i == 4 && memcmp( sDirective, "ELSE", 4 ) == 0 )
  382. { /* --- #else --- */
  383. if( hb_pp_nCondCompile == 0 )
  384. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_DIRECTIVE_ELSE, NULL, NULL );
  385. else if( hb_pp_nCondCompile == 1 || hb_pp_aCondCompile[hb_pp_nCondCompile-2] )
  386. hb_pp_aCondCompile[hb_pp_nCondCompile-1] = 1 - hb_pp_aCondCompile[hb_pp_nCondCompile-1];
  387. }
  388. else if( i >= 4 && i <= 5 && memcmp( sDirective, "ENDIF", i ) == 0 )
  389. { /* --- #endif --- */
  390. if( hb_pp_nCondCompile == 0 )
  391. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_DIRECTIVE_ENDIF, NULL, NULL );
  392. else hb_pp_nCondCompile--;
  393. }
  394. else if( i >= 4 && i <= 5 && memcmp( sDirective, "IFDEF", i ) == 0 )
  395. ParseIfdef( sLine, TRUE ); /* --- #ifdef --- */
  396. else if( i >= 4 && i <= 6 && memcmp( sDirective, "IFNDEF", i ) == 0 )
  397. ParseIfdef( sLine, FALSE ); /* --- #ifndef --- */
  398. else if( hb_pp_nCondCompile==0 || hb_pp_aCondCompile[hb_pp_nCondCompile-1])
  399. {
  400. if( i >= 4 && i <= 7 && memcmp( sDirective, "INCLUDE", i ) == 0 )
  401. { /* --- #include --- */
  402. char cDelimChar;
  403. if( *sLine != '\"' && *sLine != '\'' && *sLine != '<' )
  404. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_WRONG_NAME, NULL, NULL );
  405. cDelimChar = *sLine;
  406. if( cDelimChar == '<' )
  407. cDelimChar = '>';
  408. else if( cDelimChar == '`' )
  409. cDelimChar = '\'';
  410. sLine++; i = 0;
  411. while( *(sLine+i) != '\0' && *(sLine+i) != cDelimChar ) i++;
  412. if( *(sLine+i) != cDelimChar )
  413. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_WRONG_NAME, NULL, NULL );
  414. *(sLine+i) = '\0';
  415. if( !OpenInclude( sLine, hb_comp_pIncludePath, hb_comp_pFileName, ( cDelimChar == '>' ), szInclude ) )
  416. {
  417. if( errno == 0 || errno == EMFILE )
  418. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_TOO_MANY_INCLUDES, sLine, NULL );
  419. else
  420. {
  421. #if defined(__CYGWIN__) || defined(__IBMCPP__)
  422. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_CANNOT_OPEN, sLine, "" );
  423. #else
  424. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_CANNOT_OPEN, sLine, sys_errlist[ errno ] );
  425. #endif
  426. }
  427. }
  428. }
  429. else if( i >= 4 && i <= 6 && memcmp( sDirective, "DEFINE", i ) == 0 )
  430. hb_pp_ParseDefine( sLine ); /* --- #define --- */
  431. else if( i >= 4 && i <= 5 && memcmp( sDirective, "UNDEF", i ) == 0 )
  432. ParseUndef( sLine ); /* --- #undef --- */
  433. else if( (i >= 4 && i <= 7 && memcmp( sDirective, "COMMAND", i ) == 0) ||
  434. (i >= 4 && i <= 8 && memcmp( sDirective, "XCOMMAND", i ) == 0) )
  435. /* --- #command --- */
  436. ParseCommand( sLine, (i==7)? FALSE:TRUE, TRUE );
  437. else if( (i >= 4 && i <= 9 && memcmp( sDirective, "TRANSLATE", i ) == 0) ||
  438. (i >= 4 && i <= 10 && memcmp( sDirective, "XTRANSLATE", i ) == 0) )
  439. /* --- #translate --- */
  440. ParseCommand( sLine, (i==9)? FALSE:TRUE, FALSE );
  441. else if( i >= 4 && i <= 6 && memcmp( sDirective, "STDOUT", i ) == 0 )
  442. printf( "%s\n", sLine ); /* --- #stdout --- */
  443. else if( i >= 4 && i <= 5 && memcmp( sDirective, "ERROR", i ) == 0 )
  444. /* --- #error --- */
  445. hb_compGenError( hb_pp_szErrors, 'E', HB_PP_ERR_EXPLICIT, sLine, NULL );
  446. else if( i == 4 && memcmp( sDirective, "LINE", 4 ) == 0 )
  447. return -1;
  448. else if( i == 6 && memcmp( sDirective, "PRAGMA", 6 ) == 0 )
  449. hb_pp_ParsePragma( sLine ); /* --- #pragma --- */
  450. else
  451. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_WRONG_DIRECTIVE, sDirective, NULL );
  452. }
  453. return 0;
  454. }
  455. int hb_pp_ParseDefine( char * sLine )
  456. {
  457. char defname[ MAX_NAME ], pars[ MAX_NAME ];
  458. int i, npars = -1;
  459. DEFINES * lastdef;
  460. HB_TRACE(HB_TR_DEBUG, ("hb_pp_ParseDefine(%s)", sLine));
  461. HB_SKIPTABSPACES( sLine );
  462. if( ISNAME( *sLine ) )
  463. {
  464. NextName( &sLine, defname );
  465. if( *sLine == '(' ) /* If pseudofunction was found */
  466. {
  467. sLine++; i = 0;
  468. npars = 0;
  469. while( *sLine != '\0' && *sLine != ')')
  470. {
  471. if( *sLine == ',' ) npars++;
  472. if( *sLine != ' ' && *sLine != '\t' ) *(pars+i++) = *sLine;
  473. sLine++;
  474. }
  475. if( i > 0 ) npars++;
  476. *(pars+i) = '\0';
  477. sLine++;
  478. }
  479. HB_SKIPTABSPACES(sLine);
  480. lastdef = hb_pp_AddDefine( defname, ( *sLine == '\0' ) ? NULL : sLine );
  481. lastdef->npars = npars;
  482. lastdef->pars = ( npars <= 0 ) ? NULL : hb_strdup( pars );
  483. }
  484. else
  485. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_DEFINE_ABSENT, NULL, NULL );
  486. return 0;
  487. }
  488. DEFINES * hb_pp_AddDefine( char * defname, char * value )
  489. {
  490. BOOL isNew;
  491. DEFINES * stdef;
  492. HB_TRACE(HB_TR_DEBUG, ("hb_pp_AddDefine(%s, %s)", defname, value));
  493. stdef = DefSearch( defname, &isNew );
  494. if( stdef != NULL )
  495. {
  496. hb_compGenWarning( hb_pp_szWarnings, 'I', HB_PP_WARN_DEFINE_REDEF, defname, NULL );
  497. if( isNew )
  498. {
  499. if( stdef->pars ) hb_xfree( stdef->pars );
  500. if( stdef->value ) hb_xfree( stdef->value );
  501. }
  502. }
  503. else
  504. {
  505. stdef = ( DEFINES * ) hb_xgrab( sizeof( DEFINES ) );
  506. stdef->last = hb_pp_topDefine;
  507. hb_pp_topDefine = stdef;
  508. stdef->name = hb_strdup( defname );
  509. stdef->npars = -1;
  510. s_kolAddDefs++;
  511. }
  512. stdef->value = ( value == NULL ) ? NULL : hb_strdup( value );
  513. stdef->pars = NULL;
  514. return stdef;
  515. }
  516. static int ParseUndef( char * sLine )
  517. {
  518. char defname[ MAX_NAME ];
  519. DEFINES * stdef;
  520. BOOL isNew;
  521. HB_TRACE(HB_TR_DEBUG, ("ParseUndef(%s)", sLine));
  522. NextWord( &sLine, defname, FALSE );
  523. if( ( stdef = DefSearch(defname, &isNew ) ) != NULL )
  524. {
  525. if( isNew )
  526. {
  527. if( stdef->pars ) hb_xfree( stdef->pars );
  528. if( stdef->value ) hb_xfree( stdef->value );
  529. hb_xfree( stdef->name );
  530. }
  531. stdef->pars = NULL;
  532. stdef->value = NULL;
  533. stdef->name = NULL;
  534. }
  535. return 0;
  536. }
  537. static int ParseIfdef( char * sLine, int usl )
  538. {
  539. char defname[ MAX_NAME ];
  540. DEFINES * stdef;
  541. HB_TRACE(HB_TR_DEBUG, ("ParseIfdef(%s, %d)", sLine, usl));
  542. if( hb_pp_nCondCompile==0 || hb_pp_aCondCompile[hb_pp_nCondCompile-1])
  543. {
  544. NextWord( &sLine, defname, FALSE );
  545. if( *defname == '\0' )
  546. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_DEFINE_ABSENT, NULL, NULL );
  547. }
  548. if( hb_pp_nCondCompile == s_maxCondCompile )
  549. {
  550. s_maxCondCompile += 5;
  551. hb_pp_aCondCompile = (int*)hb_xrealloc( hb_pp_aCondCompile, sizeof( int ) * s_maxCondCompile );
  552. }
  553. if( hb_pp_nCondCompile==0 || hb_pp_aCondCompile[hb_pp_nCondCompile-1])
  554. {
  555. if( ( (stdef = DefSearch(defname,NULL)) != NULL && usl )
  556. || ( stdef == NULL && !usl ) ) hb_pp_aCondCompile[hb_pp_nCondCompile] = 1;
  557. else hb_pp_aCondCompile[hb_pp_nCondCompile] = 0;
  558. }
  559. else
  560. hb_pp_aCondCompile[ hb_pp_nCondCompile ] = 0;
  561. hb_pp_nCondCompile++;
  562. return 0;
  563. }
  564. static DEFINES * DefSearch( char * defname, BOOL * isNew )
  565. {
  566. int kol = 0,j;
  567. DEFINES * stdef = hb_pp_topDefine;
  568. HB_TRACE(HB_TR_DEBUG, ("DefSearch(%s)", defname));
  569. while( stdef != NULL )
  570. {
  571. kol++;
  572. if( stdef->name != NULL )
  573. {
  574. for( j=0; *(stdef->name+j) == *(defname+j) &&
  575. *(stdef->name+j) != '\0'; j++ );
  576. if( *(stdef->name+j) == *(defname+j) )
  577. {
  578. if( isNew ) *isNew = ( s_kolAddDefs >= kol );
  579. return stdef;
  580. }
  581. }
  582. stdef = stdef->last;
  583. }
  584. return NULL;
  585. }
  586. static COMMANDS * ComSearch( char * cmdname, COMMANDS * stcmdStart )
  587. {
  588. COMMANDS * stcmd = ( stcmdStart ) ? stcmdStart : hb_pp_topCommand;
  589. HB_TRACE(HB_TR_DEBUG, ("ComSearch(%s, %p)", cmdname, stcmdStart));
  590. while( stcmd != NULL )
  591. {
  592. int j;
  593. for( j=0; (*(stcmd->name+j)==toupper(*(cmdname+j))) &&
  594. (*(stcmd->name+j)!='\0') &&
  595. ((stcmd->com_or_xcom)? 1:(j<4 || ISNAME(*(cmdname+j+1)))); j++ );
  596. if( (*(stcmd->name+j)==toupper(*(cmdname+j))) ||
  597. ( !stcmd->com_or_xcom && j >= 4 && *(stcmd->name+j)!='\0'
  598. && *(cmdname+j) == '\0' ) )
  599. break;
  600. stcmd = stcmd->last;
  601. }
  602. return stcmd;
  603. }
  604. static COMMANDS * TraSearch( char * cmdname, COMMANDS * sttraStart )
  605. {
  606. int j;
  607. COMMANDS *sttra = ( sttraStart ) ? sttraStart : hb_pp_topTranslate;
  608. HB_TRACE(HB_TR_DEBUG, ("TraSearch(%s, %p)", cmdname, sttraStart));
  609. while( sttra != NULL )
  610. {
  611. for( j=0; *(sttra->name+j)==toupper(*(cmdname+j)) &&
  612. *(sttra->name+j)!='\0' &&
  613. ((sttra->com_or_xcom)? 1:(j<4 || ISNAME(*(cmdname+j+1)))); j++ );
  614. if( *(sttra->name+j)==toupper(*(cmdname+j)) ||
  615. ( !sttra->com_or_xcom && j >= 4 &&
  616. *(sttra->name+j)!='\0' && *(cmdname+j) == '\0' ) )
  617. break;
  618. sttra = sttra->last;
  619. }
  620. return sttra;
  621. }
  622. static void ParseCommand( char * sLine, BOOL com_or_xcom, BOOL com_or_tra )
  623. {
  624. static char mpatt[ PATTERN_SIZE ];
  625. static char rpatt[ PATTERN_SIZE ];
  626. char cmdname[ MAX_NAME ];
  627. COMMANDS * stcmd;
  628. int mlen,rlen;
  629. int ipos;
  630. /* Ron Pinkas added 2000-12-03 */
  631. BOOL bOk = FALSE;
  632. HB_TRACE(HB_TR_DEBUG, ("ParseCommand(%s, %d, %d)", sLine, com_or_xcom, com_or_tra));
  633. HB_SKIPTABSPACES( sLine );
  634. ipos = 0;
  635. /* JFL 2000-09-19 */
  636. /* This was the original line as Alexander wrote it */
  637. /* while( *sLine != '\0' && *sLine != ' ' && *sLine != '\t' && *sLine != '<' && *sLine != '=' && ( *sLine != '(' || ipos == 0 ) ) */
  638. /* Now the line #xtranslate = name(.. => will be allowed */
  639. /* I changed it to the following to allow < and = to be the first char within a translate or xtranslate */
  640. while( *sLine != '\0' && *sLine != ' ' && *sLine != '\t' && ( *sLine != '<' || ipos == 0 ) && ( *sLine != '=' || ipos == 0 ) && ( *sLine != '(' || ipos == 0 ) )
  641. {
  642. /* Ron Pinkas added 2000-01-24 */
  643. if( ! ISNAME( *sLine ) )
  644. {
  645. if( *sLine == '[' && ipos )
  646. break;
  647. if( IS_2CHAR_OPERATOR( sLine ) )
  648. {
  649. *(cmdname+ipos++) = *sLine++;
  650. *(cmdname+ipos++) = *sLine++;
  651. break;
  652. }
  653. else
  654. {
  655. *(cmdname+ipos++) = *sLine++;
  656. break;
  657. }
  658. }
  659. /* END, Ron Pinkas added 2000-01-24 */
  660. *(cmdname+ipos++) = *sLine++;
  661. }
  662. *(cmdname+ipos) = '\0';
  663. if( !ipos )
  664. {
  665. return;
  666. }
  667. hb_strupr( cmdname );
  668. HB_SKIPTABSPACES(sLine);
  669. /* Ron Pinkas added 2000-12-03 */
  670. ipos = 0;
  671. while( *sLine )
  672. {
  673. mpatt[ipos++] = *sLine;
  674. if( *sLine == '=' )
  675. {
  676. int i = ipos;
  677. sLine++;
  678. mpatt[i++] = *sLine;
  679. while( *sLine && ( *sLine == ' ' || *sLine == '\t' ) )
  680. {
  681. sLine++;
  682. mpatt[i++] = *sLine;
  683. }
  684. if( *sLine == '>' )
  685. {
  686. ipos = ipos - 2;
  687. while( mpatt[ipos] == ' ' || mpatt[ipos] == '\t' )
  688. {
  689. ipos--;
  690. }
  691. mpatt[ipos + 1] = '\0';
  692. sLine++;
  693. bOk = TRUE;
  694. break;
  695. }
  696. ipos = i;
  697. }
  698. sLine++;
  699. }
  700. /* End - Ron Pinkas added 2000-12-03 */
  701. /* Ron Pinkas modified 2000-12-03
  702. if( (ipos = hb_strAt( "=>", 2, sLine, strlen(sLine) )) > 0 ) */
  703. if( bOk )
  704. {
  705. /* Ron Pinkas removed 2000-12-03
  706. stroncpy( mpatt, sLine, ipos-1 ); */
  707. RemoveSlash( mpatt );
  708. mlen = strotrim( mpatt, TRUE );
  709. /* Ron Pinkas removed 2000-12-03
  710. sLine += ipos + 1; */
  711. HB_SKIPTABSPACES(sLine);
  712. hb_pp_strocpy( rpatt, sLine );
  713. rlen = strotrim( rpatt, TRUE );
  714. ConvertPatterns( mpatt, mlen, rpatt, rlen );
  715. if( com_or_tra )
  716. stcmd = AddCommand( cmdname );
  717. else
  718. stcmd = AddTranslate( cmdname );
  719. stcmd->com_or_xcom = com_or_xcom;
  720. stcmd->mpatt = hb_strdup( mpatt );
  721. stcmd->value = ( rlen > 0 ) ? hb_strdup( rpatt ) : NULL;
  722. /* JFL */
  723. /*
  724. printf( "Parsecommand Name: %s Pat: %s Val: %s\n", stcmd->name, stcmd->mpatt, stcmd->value );
  725. */
  726. }
  727. else
  728. {
  729. sLine -= ( ipos + 1 );
  730. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_COMMAND_DEFINITION, cmdname, sLine );
  731. }
  732. }
  733. /* ConvertPatterns()
  734. * Converts result pattern in #command and #translate to inner format
  735. */
  736. static void ConvertPatterns( char * mpatt, int mlen, char * rpatt, int rlen )
  737. {
  738. int i = 0, ipos, ifou;
  739. int explen, rmlen;
  740. char exppatt[ MAX_NAME ], expreal[ 5 ] = "\1 0";
  741. char lastchar = '@', exptype;
  742. char * ptr, * ptrtmp;
  743. HB_TRACE(HB_TR_DEBUG, ("ConvertPatterns(%s, %d, %s, %d)", mpatt, mlen, rpatt, rlen));
  744. while( *(mpatt+i) != '\0' )
  745. {
  746. if( *(mpatt+i) == '<' )
  747. { /* Drag match marker, determine it type */
  748. explen = 0; ipos = i; i++; exptype = '0';
  749. while( *(mpatt+i) == ' ' || *(mpatt+i) == '\t' ) i++;
  750. if( *(mpatt+i) == '*' ) /* Wild match marker */
  751. { exptype = '3'; i++; }
  752. else if( *(mpatt+i) == '(' ) /* Extended expression match marker */
  753. { exptype = '4'; i++; }
  754. else if( *(mpatt+i) == '!' ) /* Extended expression match marker */
  755. { exptype = '5'; i++; }
  756. ptr = mpatt + i;
  757. while( *ptr != '>' )
  758. {
  759. if( *ptr == '\0' || *ptr == '<' || *ptr == '[' || *ptr == ']' )
  760. {
  761. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_PATTERN_DEFINITION, NULL, NULL );
  762. return;
  763. }
  764. ptr++;
  765. }
  766. while( *(mpatt+i) != '>' )
  767. {
  768. if( *(mpatt+i) == ',' ) /* List match marker */
  769. {
  770. exptype = '1';
  771. while( *(mpatt+i) != '>' ) i++;
  772. break;
  773. }
  774. else if( *(mpatt+i) == ':' ) /* Restricted match marker */
  775. {
  776. exptype = '2';
  777. *(mpatt+i--) = ' ';
  778. break;
  779. }
  780. if( *(mpatt+i) != ' ' && *(mpatt+i) != '\t' )
  781. *(exppatt+explen++) = *(mpatt+i);
  782. i++;
  783. }
  784. if( exptype == '3' )
  785. {
  786. if( *(exppatt+explen-1) == '*' ) explen--;
  787. else
  788. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_PATTERN_DEFINITION, NULL, NULL );
  789. }
  790. else if( exptype == '4' )
  791. {
  792. if( *(exppatt+explen-1) == ')' ) explen--;
  793. else
  794. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_PATTERN_DEFINITION, NULL, NULL );
  795. }
  796. else if( exptype == '5' )
  797. {
  798. if( *(exppatt+explen-1) == '!' ) explen--;
  799. else
  800. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_PATTERN_DEFINITION, NULL, NULL );
  801. }
  802. rmlen = i - ipos + 1;
  803. /* Convert match marker into inner format */
  804. lastchar = (lastchar!='Z') ? ( (char) ( (unsigned int)lastchar + 1 ) ):
  805. 'a';
  806. expreal[1] = lastchar;
  807. expreal[2] = exptype;
  808. hb_pp_Stuff( expreal, mpatt+ipos, 4, rmlen, mlen );
  809. mlen += 4 - rmlen;
  810. i += 4 - rmlen;
  811. /* Look for appropriate result markers */
  812. ptr = rpatt;
  813. while( (ifou = hb_strAt( exppatt, explen, ptr, rlen-(ptr-rpatt) )) > 0 )
  814. {
  815. /* Convert result marker into inner format */
  816. ifou --;
  817. ptr += ifou;
  818. ptrtmp = ptr + 1;
  819. rmlen = explen;
  820. exptype = '0';
  821. do
  822. {
  823. ptr--;
  824. rmlen++;
  825. ifou--;
  826. if( *ptr == '<' )
  827. continue;
  828. else if( *ptr == '\"' )
  829. exptype = '2';
  830. else if( *ptr == '(' )
  831. exptype = '3';
  832. else if( *ptr == '{' )
  833. exptype = '4';
  834. else if( *ptr == '.' )
  835. exptype = '5';
  836. else if( *ptr == '-' )
  837. exptype = '6';
  838. else if( *ptr == ' ' || *ptr == '\t' )
  839. continue;
  840. else
  841. ifou = -1;
  842. }
  843. while( ifou >= 0 && *ptr!='<' && *(ptr-1)!= '\\' );
  844. if( ifou >=0 && *ptr=='<' )
  845. {
  846. ptr += rmlen++;
  847. while( *ptr != '\0' && *ptr != '>' && *(ptr-1) != '\\' )
  848. {
  849. if( *ptr != ' ' && *ptr != '\t' && *ptr != '\"' && *ptr != ')' && *ptr != '}' && *ptr != '.' && *ptr != '-' )
  850. {
  851. ifou = -1;
  852. break;
  853. }
  854. rmlen++;
  855. ptr++;
  856. }
  857. if( ifou >=0 && *ptr=='>' )
  858. {
  859. ptr -= rmlen;
  860. ptr++;
  861. if( exptype == '0' && *(ptr-1) == '#' && *(ptr-2) != '\\' )
  862. {
  863. exptype = '1';
  864. ptr--;
  865. rmlen++;
  866. }
  867. expreal[2] = exptype;
  868. hb_pp_Stuff( expreal, ptr, 4, rmlen, rlen );
  869. rlen += 4 - rmlen;
  870. }
  871. else
  872. ptr = ptrtmp;
  873. }
  874. else
  875. ptr = ptrtmp;
  876. }
  877. }
  878. i++;
  879. }
  880. }
  881. static COMMANDS * AddCommand( char * cmdname )
  882. {
  883. COMMANDS * stcmd;
  884. HB_TRACE(HB_TR_DEBUG, ("AddCommand(%s)", cmdname));
  885. stcmd = ( COMMANDS * ) hb_xgrab( sizeof( COMMANDS ) );
  886. stcmd->last = hb_pp_topCommand;
  887. hb_pp_topCommand = stcmd;
  888. stcmd->name = hb_strdup( cmdname );
  889. s_kolAddComs++;
  890. return stcmd;
  891. }
  892. static COMMANDS* AddTranslate( char * traname )
  893. {
  894. COMMANDS * sttra;
  895. HB_TRACE(HB_TR_DEBUG, ("AddTranslate(%s)", traname));
  896. sttra = ( COMMANDS * ) hb_xgrab( sizeof( COMMANDS ) );
  897. sttra->last = hb_pp_topTranslate;
  898. hb_pp_topTranslate = sttra;
  899. sttra->name = hb_strdup( traname );
  900. s_kolAddTras++;
  901. return sttra;
  902. }
  903. int hb_pp_ParseExpression( char * sLine, char * sOutLine )
  904. {
  905. char sToken[MAX_NAME];
  906. char * ptri, * ptro, * ptrb;
  907. int lenToken, i, ipos, isdvig, lens;
  908. int ifou;
  909. int rezDef, rezTra, rezCom, kolpass = 0;
  910. DEFINES * stdef;
  911. COMMANDS * stcmd;
  912. HB_TRACE(HB_TR_DEBUG, ("hb_pp_ParseExpression(%s, %s)", sLine, sOutLine));
  913. #if 0
  914. printf( "Line: >%s<\n", sLine );
  915. #endif
  916. do
  917. {
  918. strotrim( sLine, FALSE );
  919. #if 0
  920. printf( "Trimed: >%s<\n", sLine );
  921. #endif
  922. rezDef = 0; rezTra = 0; rezCom = 0;
  923. isdvig = 0;
  924. do
  925. {
  926. ptro = sOutLine;
  927. ptri = sLine + isdvig;
  928. ipos = md_strAt( ";", 1, ptri, TRUE, FALSE, FALSE );
  929. if( ipos > 0 )
  930. {
  931. *(ptri+ipos-1) = '\0';
  932. }
  933. HB_SKIPTABSPACES( ptri );
  934. if( *ptri == '#' )
  935. {
  936. hb_pp_ParseDirective( ptri+1 );
  937. if( ipos > 0 )
  938. {
  939. *( sLine + isdvig + ipos - 1 ) = ';';
  940. }
  941. lens = strlen( sLine + isdvig );
  942. hb_pp_Stuff( " ", sLine + isdvig, 0, (ipos)? ipos:lens, lens );
  943. if( ipos > 0 )
  944. {
  945. ipos = 1;
  946. }
  947. }
  948. else
  949. { /* Look for macros from #define */
  950. while( ( lenToken = NextName( &ptri, sToken ) ) > 0 )
  951. {
  952. #if 0
  953. printf( "Token: >%s< Line: >%s<\n", sToken, sLine );
  954. #endif
  955. if( (stdef=DefSearch(sToken,NULL)) != NULL )
  956. {
  957. ptrb = ptri - lenToken;
  958. if( ( i = WorkDefine( &ptri, ptro, stdef ) ) >= 0 )
  959. {
  960. rezDef++;
  961. lens = strlen( ptrb );
  962. if( ipos > 0 )
  963. {
  964. *(ptrb+lens) = ';';
  965. lens += strlen( ptrb+lens+1 );
  966. }
  967. hb_pp_Stuff( ptro, ptrb, i, ptri-ptrb, lens+1 );
  968. if( ipos > 0 )
  969. {
  970. ipos += i - (ptri-ptrb);
  971. *(sLine + isdvig + ipos - 1) = '\0';
  972. }
  973. ptri += i - (ptri-ptrb);
  974. }
  975. }
  976. }
  977. #if 0
  978. if( *sOutLine )
  979. printf( "*After #defines: >%s<\n", sOutLine );
  980. else
  981. printf( "After #defines: >%s<\n", sLine );
  982. #endif
  983. /* Look for definitions from #translate */
  984. stcmd = hb_pp_topTranslate;
  985. while( stcmd != NULL )
  986. {
  987. ptri = sLine + isdvig;
  988. lenToken = strlen(stcmd->name);
  989. while( ( ifou = md_strAt( stcmd->name, lenToken, ptri, TRUE, FALSE, FALSE )) > 0 )
  990. {
  991. ptri += ifou -1;
  992. if( ( i = WorkTranslate( ptri+lenToken, ptro, stcmd, &lens ) ) >= 0 )
  993. {
  994. lens += lenToken;
  995. while( lens > 0 && (*(ptri+lens-1)==' ' || *(ptri+lens-1)=='\t') )
  996. {
  997. lens--;
  998. }
  999. if( ipos > 0 )
  1000. {
  1001. *(sLine+isdvig+ipos-1) = ';';
  1002. }
  1003. hb_pp_Stuff( ptro, ptri, i, lens, strlen(ptri) );
  1004. rezTra = 1;
  1005. if( ipos > 0 )
  1006. {
  1007. ipos += i - lens;
  1008. *(sLine+isdvig+ipos-1) = '\0';
  1009. }
  1010. ptri += i;
  1011. }
  1012. else
  1013. {
  1014. ptri += lenToken;
  1015. }
  1016. }
  1017. stcmd = stcmd->last;
  1018. }
  1019. #if 0
  1020. if( *sOutLine )
  1021. printf( "*After #translate: >%s<\n", sOutLine );
  1022. else
  1023. printf( "After #translate: >%s<\n", sLine );
  1024. #endif
  1025. /* Look for definitions from #command */
  1026. /* JFL ! Was 3 but insufficient in most cases */
  1027. /* I know this is a new hardcoded limit ... any better idea's welcome */
  1028. if( kolpass < 20 )
  1029. {
  1030. ptri = sLine + isdvig;
  1031. HB_SKIPTABSPACES( ptri );
  1032. if( ISNAME( *ptri ) )
  1033. {
  1034. NextName( &ptri, sToken );
  1035. }
  1036. else
  1037. {
  1038. /* Ron Pinkas commented 2000-01-24
  1039. i = 0;
  1040. while( *ptri != ' ' && *ptri != '\t' && *ptri != '\0' && *ptri != '\"' && *ptri != '\'' && *ptri != '(' && !ISNAME(*ptri) )
  1041. {
  1042. *(sToken+i) = *ptri++;
  1043. i++;
  1044. }
  1045. *(sToken+i) = '\0';
  1046. */
  1047. /* Ron Pinkas added 2000-01-24 */
  1048. if( IS_2CHAR_OPERATOR( ptri ) )
  1049. {
  1050. sToken[0] = *ptri++;
  1051. sToken[1] = *ptri++;
  1052. sToken[2] = '\0';
  1053. }
  1054. else
  1055. {
  1056. sToken[0] = *ptri++;
  1057. sToken[1] = '\0';
  1058. }
  1059. /* END, Ron Pinkas added 2000-01-24 */
  1060. }
  1061. HB_SKIPTABSPACES( ptri );
  1062. #if 0
  1063. printf( "Token: %s\n", sToken );
  1064. #endif
  1065. if( ( *ptri == '\0' || ( *ptri != '=' && (!IsInStr(*ptri,":/+*-%^") || *(ptri+1) != '=') &&
  1066. ( *ptri != '-' || *(ptri+1) != '>' ) ) ) && ( stcmd = ComSearch(sToken,NULL) ) != NULL )
  1067. {
  1068. ptro = sOutLine;
  1069. i = WorkCommand( ptri, ptro, stcmd );
  1070. ptri = sLine + isdvig;
  1071. if( ipos > 0 )
  1072. {
  1073. *(ptri+ipos-1) = ';';
  1074. }
  1075. if( i >= 0 )
  1076. {
  1077. if( isdvig + ipos > 0 )
  1078. {
  1079. lens = strlen( sLine+isdvig );
  1080. hb_pp_Stuff( ptro, sLine+isdvig, i, (ipos)? ipos-1:lens, lens );
  1081. if( ipos > 0 )
  1082. {
  1083. ipos = i + 1;
  1084. }
  1085. }
  1086. else
  1087. {
  1088. memcpy( sLine, sOutLine, i+1);
  1089. }
  1090. }
  1091. rezCom = 1;
  1092. }
  1093. else if( ipos > 0 )
  1094. {
  1095. *(sLine+isdvig+ipos-1) = ';';
  1096. }
  1097. }
  1098. else if( ipos > 0 )
  1099. {
  1100. *(sLine+isdvig+ipos-1) = ';';
  1101. }
  1102. }
  1103. isdvig += ipos;
  1104. }
  1105. while( ipos != 0 );
  1106. kolpass++;
  1107. if( kolpass > 750 && rezDef )
  1108. {
  1109. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_RECURSE, NULL, NULL );
  1110. break;
  1111. }
  1112. }
  1113. while( rezDef || rezTra || rezCom );
  1114. #if 0
  1115. if( *sOutLine )
  1116. printf( "Out: >%s<\n", sOutLine );
  1117. else
  1118. printf( "Out: >%s<\n", sLine );
  1119. #endif
  1120. return 0;
  1121. }
  1122. static int WorkDefine( char ** ptri, char * ptro, DEFINES * stdef )
  1123. {
  1124. int npars, lens;
  1125. char * ptr;
  1126. HB_TRACE(HB_TR_DEBUG, ("WorkDefine(%p, %s, %p)", ptri, ptro, stdef));
  1127. if( stdef->npars < 0 )
  1128. {
  1129. lens = hb_pp_strocpy( ptro,stdef->value );
  1130. }
  1131. else
  1132. {
  1133. HB_SKIPTABSPACES( *ptri );
  1134. if( **ptri == '(' )
  1135. {
  1136. npars = 0; ptr = *ptri;
  1137. do
  1138. {
  1139. ptr++;
  1140. if( NextParm( &ptr, NULL ) > 0 )
  1141. {
  1142. npars++;
  1143. }
  1144. }
  1145. while( *ptr != ')' && *ptr != '\0' );
  1146. if( *ptr == ')' && stdef->npars == npars )
  1147. {
  1148. /* Ron Pinkas added 2000-11-21 */
  1149. char *pTmp = ptr + 1;
  1150. while( *pTmp && ( *pTmp == ' ' || *pTmp == '\t' ) )
  1151. {
  1152. pTmp++;
  1153. }
  1154. if( *pTmp == '[' )
  1155. {
  1156. s_bArray = TRUE;
  1157. }
  1158. /* END - Ron Pinkas added 2000-11-21 */
  1159. lens = WorkPseudoF( ptri, ptro, stdef );
  1160. }
  1161. else
  1162. {
  1163. return -1;
  1164. }
  1165. }
  1166. else
  1167. {
  1168. return -1;
  1169. }
  1170. }
  1171. return lens;
  1172. }
  1173. static int WorkPseudoF( char ** ptri, char * ptro, DEFINES * stdef )
  1174. {
  1175. char parfict[ MAX_NAME ], * ptrreal;
  1176. char * ptrb;
  1177. int ipos, ifou, ibeg;
  1178. int lenfict, lenreal, lenres;
  1179. HB_TRACE(HB_TR_DEBUG, ("WorkPseudoF(%p, %s, %p)", ptri, ptro, stdef));
  1180. lenres = hb_pp_strocpy( ptro, stdef->value ); /* Copying value of macro to destination string */
  1181. if( stdef->pars )
  1182. {
  1183. ipos = 0; ibeg = 0;
  1184. do /* Parsing through parameters */
  1185. { /* in macro definition */
  1186. if( *(stdef->pars+ipos) == ',' || *(stdef->pars+ipos) == '\0' )
  1187. {
  1188. *(parfict+ipos-ibeg) = '\0';
  1189. lenfict = ipos - ibeg;
  1190. if( **ptri != ')' )
  1191. {
  1192. (*ptri)++; /* Get next real parameter */
  1193. HB_SKIPTABSPACES( *ptri );
  1194. ptrreal = *ptri;
  1195. lenreal = NextParm( ptri, NULL);
  1196. ptrb = ptro;
  1197. while( (ifou = hb_strAt( parfict, lenfict, ptrb, lenres-(ptrb-ptro) )) > 0 )
  1198. {
  1199. ptrb = ptrb+ifou-1;
  1200. if( !ISNAME(*(ptrb-1)) && !ISNAME(*(ptrb+lenfict)) )
  1201. {
  1202. hb_pp_Stuff( ptrreal, ptrb, lenreal, lenfict, lenres );
  1203. lenres += lenreal - lenfict;
  1204. ptrb += lenreal;
  1205. }
  1206. else
  1207. {
  1208. ptrb++;
  1209. }
  1210. }
  1211. ibeg = ipos+1;
  1212. }
  1213. }
  1214. else
  1215. {
  1216. *(parfict+ipos-ibeg) = *(stdef->pars+ipos);
  1217. }
  1218. if( *(stdef->pars+ipos) == '\0' )
  1219. {
  1220. break;
  1221. }
  1222. ipos++;
  1223. }
  1224. while( 1 );
  1225. }
  1226. else
  1227. {
  1228. while( **ptri != ')' )
  1229. {
  1230. (*ptri)++;
  1231. }
  1232. }
  1233. (*ptri)++;
  1234. return lenres;
  1235. }
  1236. static int WorkCommand( char * ptri, char * ptro, COMMANDS * stcmd )
  1237. {
  1238. int rez;
  1239. int lenres;
  1240. char * ptrmp;
  1241. char * sToken = stcmd->name;
  1242. HB_TRACE(HB_TR_DEBUG, ("WorkCommand(%s, %s, %p)", ptri, ptro, stcmd));
  1243. do
  1244. {
  1245. lenres = hb_pp_strocpy( ptro, stcmd->value ); /* Copying result pattern */
  1246. ptrmp = stcmd->mpatt; /* Pointer to a match pattern */
  1247. s_Repeate = 0;
  1248. s_groupchar = '@';
  1249. rez = CommandStuff( ptrmp, ptri, ptro, &lenres, TRUE, stcmd->com_or_xcom );
  1250. stcmd = stcmd->last;
  1251. if( rez < 0 && stcmd != NULL ) stcmd = ComSearch(sToken, stcmd);
  1252. }
  1253. while( rez < 0 && stcmd != NULL );
  1254. *(ptro+lenres) = '\0';
  1255. if( rez >= 0 ) return lenres;
  1256. return -1;
  1257. }
  1258. static int WorkTranslate( char * ptri, char * ptro, COMMANDS * sttra, int * lens )
  1259. {
  1260. int rez;
  1261. int lenres;
  1262. char * ptrmp;
  1263. char * sToken = sttra->name;
  1264. HB_TRACE(HB_TR_DEBUG, ("WorkTranslate(%s, %s, %p, %p)", ptri, ptro, sttra, lens));
  1265. do
  1266. {
  1267. lenres = hb_pp_strocpy( ptro, sttra->value );
  1268. ptrmp = sttra->mpatt;
  1269. s_Repeate = 0;
  1270. s_groupchar = '@';
  1271. rez = CommandStuff( ptrmp, ptri, ptro, &lenres, FALSE, sttra->com_or_xcom );
  1272. sttra = sttra->last;
  1273. if( rez < 0 && sttra != NULL )
  1274. {
  1275. sttra = TraSearch(sToken, sttra);
  1276. }
  1277. }
  1278. while( rez < 0 && sttra != NULL );
  1279. *(ptro+lenres) = '\0';
  1280. if( rez >= 0 )
  1281. {
  1282. *lens = rez;
  1283. return lenres;
  1284. }
  1285. return -1;
  1286. }
  1287. static int CommandStuff( char * ptrmp, char * inputLine, char * ptro, int * lenres, BOOL com_or_tra, BOOL com_or_xcom )
  1288. {
  1289. BOOL endTranslation = FALSE;
  1290. int ipos;
  1291. char * lastopti[ 3 ], * strtopti = NULL, * strtptri = NULL;
  1292. char * ptri = inputLine, * ptr, tmpname[ MAX_NAME ];
  1293. int isWordInside = 0;
  1294. /*
  1295. printf( "MP: >%s<\nIn: >%s<\n", ptrmp, ptri );
  1296. */
  1297. HB_TRACE(HB_TR_DEBUG, ("CommandStuff(%s, %s, %s, %p, %d, %d)", ptrmp, inputLine, ptro, lenres, com_or_tra, com_or_xcom));
  1298. s_numBrackets = 0;
  1299. HB_SKIPTABSPACES( ptri );
  1300. if( ptrmp == NULL ) { if( *ptri != '\0' ) return -1; }
  1301. else
  1302. while( *ptri != '\0' && !endTranslation )
  1303. {
  1304. HB_SKIPTABSPACES( ptrmp );
  1305. if( *ptrmp == '[' && !s_numBrackets && !strtopti )
  1306. strtopti = ptrmp;
  1307. if( !s_numBrackets && strtopti && strtptri != ptri &&
  1308. ( ISNAME( *ptri ) || *ptri=='&' ) )
  1309. {
  1310. strtptri = ptri;
  1311. ptrmp = strtopti;
  1312. ptr = ptri;
  1313. ipos = NextName( &ptr, tmpname );
  1314. ipos = md_strAt( tmpname, ipos, strtopti, TRUE, TRUE, TRUE );
  1315. if( ipos && TestOptional( strtopti, strtopti+ipos-2 ) )
  1316. {
  1317. ptr = strtopti+ipos-2;
  1318. ptr = PrevSquare( ptr, strtopti, NULL );
  1319. if( ptr )
  1320. ptrmp = ptr;
  1321. }
  1322. }
  1323. switch( *ptrmp ) {
  1324. case '[':
  1325. if( !s_numBrackets ) isWordInside = 0;
  1326. s_numBrackets++;
  1327. s_aIsRepeate[ s_Repeate ] = 0;
  1328. lastopti[s_Repeate++] = ptrmp;
  1329. ptrmp++;
  1330. if( !CheckOptional( ptrmp, ptri, ptro, lenres, com_or_tra, com_or_xcom ) )
  1331. SkipOptional( &ptrmp );
  1332. break;
  1333. case ']':
  1334. if( s_Repeate )
  1335. {
  1336. s_Repeate--;
  1337. if( s_aIsRepeate[ s_Repeate ] )
  1338. {
  1339. if( ISNAME(*ptri) )
  1340. {
  1341. ptr = ptri;
  1342. ipos = NextName( &ptr, tmpname );
  1343. ipos = md_strAt( tmpname, ipos, ptrmp, TRUE, TRUE, TRUE );
  1344. if( ipos && TestOptional( ptrmp+1, ptrmp+ipos-2 ) )
  1345. {
  1346. ptr = PrevSquare( ptrmp+ipos-2, ptrmp+1, NULL );
  1347. if( !ptr || CheckOptional( ptrmp+1, ptri, ptro, lenres, com_or_tra, com_or_xcom ) )
  1348. {
  1349. ptrmp = lastopti[s_Repeate];
  1350. ptrmp++;
  1351. s_Repeate++;
  1352. SkipOptional( &ptrmp );
  1353. s_numBrackets++;
  1354. ptrmp++;
  1355. strtptri = ptri;
  1356. }
  1357. else
  1358. ptrmp = lastopti[s_Repeate];
  1359. }
  1360. else
  1361. ptrmp = lastopti[s_Repeate];
  1362. }
  1363. else
  1364. ptrmp = lastopti[s_Repeate];
  1365. }
  1366. else
  1367. {
  1368. if( !isWordInside ) strtopti = NULL;
  1369. ptrmp++;
  1370. }
  1371. s_numBrackets--;
  1372. }
  1373. else
  1374. {
  1375. if( !isWordInside ) strtopti = NULL;
  1376. s_numBrackets--; ptrmp++;
  1377. }
  1378. break;
  1379. case ',':
  1380. if( s_numBrackets == 1 ) isWordInside = 1;
  1381. if( !s_numBrackets ) strtopti = NULL;
  1382. if( *ptri == ',' ) { ptrmp++; ptri++; }
  1383. else
  1384. {
  1385. if( s_numBrackets )
  1386. {
  1387. SkipOptional( &ptrmp );
  1388. }
  1389. else return -1;
  1390. }
  1391. break;
  1392. case '\1': /* Match marker */
  1393. if( !s_numBrackets ) strtopti = NULL;
  1394. if( s_numBrackets == 1 && *(ptrmp+2) == '2' ) isWordInside = 1; /* restricted match marker */
  1395. if( !WorkMarkers( &ptrmp, &ptri, ptro, lenres, com_or_xcom ) )
  1396. {
  1397. if( s_numBrackets )
  1398. {
  1399. SkipOptional( &ptrmp );
  1400. }
  1401. else return -1;
  1402. }
  1403. break;
  1404. case '\0':
  1405. if( com_or_tra )
  1406. return -1;
  1407. else endTranslation = TRUE;
  1408. break;
  1409. default: /* Key word */
  1410. if( s_numBrackets == 1 ) isWordInside = 1;
  1411. if( !s_numBrackets ) strtopti = NULL;
  1412. ptr = ptri;
  1413. if( *ptri == ',' || truncmp( &ptri, &ptrmp, !com_or_xcom ) )
  1414. {
  1415. ptri = ptr;
  1416. if( s_numBrackets )
  1417. {
  1418. SkipOptional( &ptrmp );
  1419. }
  1420. else return -1;
  1421. }
  1422. }
  1423. HB_SKIPTABSPACES( ptri );
  1424. };
  1425. if( *ptrmp != '\0' )
  1426. {
  1427. if( s_Repeate ) { s_Repeate = 0; ptrmp = lastopti[0]; }
  1428. s_numBrackets = 0;
  1429. do
  1430. {
  1431. HB_SKIPTABSPACES( ptrmp );
  1432. if( *ptrmp != '\0' )
  1433. switch( *ptrmp ) {
  1434. case '[':
  1435. ptrmp++;
  1436. SkipOptional( &ptrmp );
  1437. ptrmp++;
  1438. break;
  1439. case ']': ptrmp++; break;
  1440. default:
  1441. return -1;
  1442. }
  1443. }

Large files files are truncated, but you can click here to view the full file