PageRenderTime 57ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/beta1/harbour/utils/hbpp/hbppcore.c

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

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