PageRenderTime 73ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

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

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

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