PageRenderTime 68ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/tags/harbour-2.0.0/examples/pp/hbppcore.c

#
C | 2238 lines | 1836 code | 262 blank | 140 comment | 600 complexity | 598256b2d2509c94bbd09e2d8ef0755e 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
  1. /*
  2. * $Id: hbppcore.c 11201 2009-06-03 10:26:40Z vszakats $
  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 (harbour.01 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 COPYING 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 <ctype.h>
  75. #include "hbppdef.h"
  76. #include "hbcomp.h"
  77. #include "hbdate.h"
  78. #if !defined(__MINGW32CE__) && !( defined( _MSC_VER ) && defined( HB_OS_WIN_CE ) )
  79. # include <errno.h>
  80. #endif
  81. int hb_pp_ParseDefine_( char * ); /* Process #define directive */
  82. static COMMANDS *AddCommand( char * ); /* Add new #command to an array */
  83. static COMMANDS *AddTranslate( char * ); /* Add new #translate to an array */
  84. static DEFINES *DefSearch( char *, int, BOOL * );
  85. static COMMANDS *ComSearch( char *, COMMANDS * );
  86. static COMMANDS *TraSearch( char *, COMMANDS * );
  87. static int ParseUndef( char * ); /* Process #undef directive */
  88. static int ParseIfdef( char *, int ); /* Process #ifdef directive */
  89. static void ParseCommand( char *, BOOL, BOOL ); /* Process #command or #translate directive */
  90. static void ConvertPatterns( char *, int, char *, int ); /* Converting result pattern in #command and #translate */
  91. static int WorkDefine( char **, char *, DEFINES * ); /* Replace fragment of code with a #defined result text */
  92. static int WorkPseudoF( char **, char *, DEFINES * ); /* Replace pseudofunction with a #defined result text */
  93. static int WorkCommand( char *, char *, COMMANDS * );
  94. static int WorkTranslate( char *, char *, COMMANDS *, int * );
  95. static int CommandStuff( char *, char *, char *, int *, BOOL, BOOL );
  96. static int RemoveSlash( char * );
  97. static int WorkMarkers( char **, char **, char *, int *, BOOL, BOOL );
  98. static int getExpReal( char *, char **, BOOL, int, BOOL, BOOL );
  99. static BOOL isExpres( char *, BOOL );
  100. static BOOL TestOptional( char *, char * );
  101. static BOOL CheckOptional( char *, char *, char *, int *, BOOL, BOOL );
  102. static void SkipOptional( char ** );
  103. static void SearnRep( char *, char *, int, char *, int * );
  104. static int ReplacePattern( char, char *, int, char *, int );
  105. static void pp_rQuotes( char *, char * );
  106. static int md_strAt( char *, int, char *, BOOL, BOOL, BOOL, int );
  107. #define MD_STR_AT_IGNORECASE 0 /* search ignoring case */
  108. #define MD_STR_AT_USESUBCASE 1 /* use case specified in search string (old) */
  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. static int IsMacroVar( char *szText, BOOL isCommand );
  122. static void RemoveOptional( char *cpatt );
  123. static int ConvertOptional( char *cpatt, int len, BOOL bLeft );
  124. #define ISNAME( c ) ( isalnum( c ) || ( c ) == '_' || ( c ) > 0x7E )
  125. #define MAX_NAME 255
  126. #define MAX_EXP 2048
  127. #define PATTERN_SIZE 2048
  128. #define STATE_INIT 0
  129. #define STATE_NORMAL 1
  130. #define STATE_COMMENT 2
  131. #define STATE_QUOTE1 3
  132. #define STATE_QUOTE2 4
  133. #define STATE_QUOTE3 5
  134. #define STATE_ID_END 6
  135. #define STATE_ID 7
  136. #define STATE_EXPRES 8
  137. #define STATE_EXPRES_ID 9
  138. #define STATE_BRACKET 10
  139. #define IT_EXPR 1
  140. #define IT_ID 2
  141. #define IT_COMMA 3
  142. #define IT_ID_OR_EXPR 4
  143. #define HB_PP_MAX_INCLUDES FOPEN_MAX - 5 - 1
  144. #define HB_PP_MATCH_MARK '\1'
  145. #define HB_PP_OPT_START '\2'
  146. #define HB_PP_OPT_END '\3'
  147. /* Ron Pinkas added 2000-01-24 */
  148. #define IS_2CHAR_OPERATOR( p ) ( p[0] && p[1] && ( 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. 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. /* END, Ron Pinkas added 2000-01-24 */
  162. static int s_kolAddDefs = 0;
  163. static int s_kolAddComs = 0;
  164. static int s_kolAddTras = 0;
  165. static int s_ParseState;
  166. static int s_maxCondCompile;
  167. static int s_aIsRepeate[5];
  168. static int s_Repeate;
  169. static BOOL s_bReplacePat = TRUE;
  170. static int s_numBrackets;
  171. static char s_groupchar;
  172. static char s_prevchar;
  173. /* additional buffers for expressions */
  174. static char *s_expreal = NULL; /* allocation inside WorkMarkers */
  175. static char *s_expcopy = NULL; /* allocation inside SearnExp */
  176. /* global variables */
  177. int *hb_pp_aCondCompile = NULL;
  178. int hb_pp_nCondCompile = 0;
  179. BOOL hb_pp_NestedLiteralString = FALSE;
  180. BOOL hb_pp_LiteralEscSeq = FALSE;
  181. unsigned int hb_pp_MaxTranslateCycles = 1024;
  182. int hb_pp_StreamBlock = 0;
  183. char *hb_pp_STD_CH = NULL;
  184. /* Ron Pinkas added 2000-11-21 */
  185. static BOOL s_bArray = FALSE;
  186. /* Table with parse errors */
  187. const char *hb_pp_szErrors[] = {
  188. "Can\'t open #include file: \'%s\'; %s",
  189. "#else does not match #ifdef",
  190. "#endif does not match #ifdef",
  191. "Bad filename in #include",
  192. "#define without parameters",
  193. "Missing => in #translate/#command \'%s\' [%s]'",
  194. "Error in pattern definition",
  195. "Cycled #define",
  196. "Invalid name follows #: \'%s\'",
  197. "\'%s\'",
  198. "Memory allocation error",
  199. "Memory reallocation error",
  200. "Freeing a NULL memory pointer",
  201. "Value out of range in #pragma directive",
  202. "Can\'t open command definitions file: \'%s\'",
  203. "Invalid command definitions file name: \'%s\'",
  204. "Too many nested #includes, can\'t open: \'%s\'",
  205. "Input buffer overflow",
  206. "Label missing in #define '%s'",
  207. "Comma or right parenthesis missing in #define '%s'",
  208. "Label duplicated in #define '%s(%s)'",
  209. };
  210. /* Table with warnings */
  211. const char *hb_pp_szWarnings[] = {
  212. "1Redefinition or duplicate definition of #define %s",
  213. "1No directives in command definitions file"
  214. };
  215. void hb_pp_SetRules_( HB_INCLUDE_FUNC_PTR pIncludeFunc, BOOL bQuiet )
  216. {
  217. HB_TRACE( HB_TR_DEBUG, ( "hb_pp_SetRules_()" ) );
  218. if( hb_pp_STD_CH )
  219. {
  220. if( *hb_pp_STD_CH > ' ' )
  221. {
  222. hb_comp_pFileName = hb_fsFNameSplit( hb_pp_STD_CH );
  223. if( hb_comp_pFileName->szName )
  224. {
  225. char szFileName[HB_PATH_MAX];
  226. if( !hb_comp_pFileName->szExtension )
  227. hb_comp_pFileName->szExtension = ".ch";
  228. hb_fsFNameMerge( szFileName, hb_comp_pFileName );
  229. if( ( *pIncludeFunc ) ( szFileName, hb_comp_pIncludePath ) )
  230. {
  231. hb_pp_Init( );
  232. hb_pp_ReadRules( );
  233. if( s_kolAddComs || s_kolAddTras || s_kolAddDefs > 3 )
  234. {
  235. if( !bQuiet )
  236. printf( "Loaded: %i Commands, %i Translates, %i Defines from: %s\n", s_kolAddComs, s_kolAddTras, s_kolAddDefs - 3, szFileName );
  237. }
  238. else
  239. {
  240. hb_compGenWarning( NULL, hb_pp_szWarnings, 'I', HB_PP_WARN_NO_DIRECTIVES, NULL /*szFileName */ , NULL );
  241. }
  242. fclose( hb_comp_files.pLast->handle );
  243. hb_xfree( hb_comp_files.pLast->pBuffer );
  244. hb_xfree( hb_comp_files.pLast->szFileName );
  245. hb_xfree( hb_comp_files.pLast );
  246. hb_comp_files.pLast = NULL;
  247. hb_comp_files.iFiles = 0;
  248. hb_xfree( ( void * ) hb_comp_pFileName );
  249. hb_comp_pFileName = NULL;
  250. }
  251. else
  252. {
  253. hb_compGenError( NULL, hb_pp_szErrors, 'F', HB_PP_ERR_CANNOT_OPEN_RULES, szFileName, NULL );
  254. }
  255. }
  256. else
  257. {
  258. hb_compGenError( NULL, hb_pp_szErrors, 'F', HB_PP_ERR_BAD_RULES_FILE_NAME, hb_pp_STD_CH, NULL );
  259. }
  260. }
  261. else
  262. {
  263. if( !bQuiet )
  264. printf( "Standard command definitions excluded.\n" );
  265. hb_pp_Init( );
  266. }
  267. hb_xfree( hb_pp_STD_CH );
  268. }
  269. else
  270. {
  271. hb_pp_Table( );
  272. hb_pp_Init( );
  273. }
  274. }
  275. void hb_pp_Free( void )
  276. {
  277. DEFINES *stdef;
  278. COMMANDS *stcmd;
  279. HB_TRACE( HB_TR_DEBUG, ( "hb_pp_Free()" ) );
  280. while( s_kolAddDefs )
  281. {
  282. stdef = hb_pp_topDefine;
  283. if( stdef->pars )
  284. hb_xfree( stdef->pars );
  285. if( stdef->value )
  286. hb_xfree( stdef->value );
  287. if( stdef->name )
  288. hb_xfree( stdef->name );
  289. hb_pp_topDefine = stdef->last;
  290. hb_xfree( stdef );
  291. s_kolAddDefs--;
  292. }
  293. while( s_kolAddComs )
  294. {
  295. stcmd = hb_pp_topCommand;
  296. if( stcmd->mpatt )
  297. hb_xfree( stcmd->mpatt );
  298. if( stcmd->value )
  299. hb_xfree( stcmd->value );
  300. hb_xfree( stcmd->name );
  301. hb_pp_topCommand = stcmd->last;
  302. hb_xfree( stcmd );
  303. s_kolAddComs--;
  304. }
  305. while( s_kolAddTras )
  306. {
  307. stcmd = hb_pp_topTranslate;
  308. if( stcmd->mpatt )
  309. hb_xfree( stcmd->mpatt );
  310. if( stcmd->value )
  311. hb_xfree( stcmd->value );
  312. hb_xfree( stcmd->name );
  313. hb_pp_topTranslate = stcmd->last;
  314. hb_xfree( stcmd );
  315. s_kolAddTras--;
  316. }
  317. if( hb_pp_aCondCompile )
  318. {
  319. hb_xfree( ( void * ) hb_pp_aCondCompile );
  320. hb_pp_aCondCompile = NULL;
  321. }
  322. hb_pp_InternalFree();
  323. if( s_expreal )
  324. {
  325. hb_xfree( ( void *) s_expreal );
  326. s_expreal = NULL;
  327. }
  328. if( s_expcopy )
  329. {
  330. hb_xfree( ( void *) s_expcopy );
  331. s_expcopy = NULL;
  332. }
  333. }
  334. void hb_pp_Init( void )
  335. {
  336. HB_TRACE( HB_TR_DEBUG, ( "hb_pp_Init()" ) );
  337. hb_pp_Free( );
  338. s_ParseState = 0;
  339. s_maxCondCompile = 5;
  340. s_bReplacePat = TRUE;
  341. s_prevchar = 'A';
  342. if( !hb_pp_aCondCompile )
  343. hb_pp_aCondCompile = ( int * ) hb_xgrab( sizeof( int ) * 5 );
  344. hb_pp_nCondCompile = 0;
  345. {
  346. char sOS[64];
  347. char sVer[64];
  348. char *pSrc, *pDst;
  349. char *szPlatform = hb_verPlatform( );
  350. int n;
  351. hb_strncpy( sOS, "__PLATFORM__", sizeof( sOS ) - 1 );
  352. pSrc = szPlatform;
  353. n = strlen( sOS );
  354. pDst = sOS;
  355. while( *pSrc && *pSrc != ' ' && n < ( int ) sizeof( sOS ) - 1 )
  356. {
  357. if( *pSrc == '_' || ( *pSrc >= 'A' && *pSrc <= 'Z' ) || ( *pSrc >= 'a' && *pSrc <= 'z' ) || ( *pSrc >= '0' && *pSrc <= '9' ) )
  358. {
  359. pDst[n++] = *pSrc;
  360. }
  361. pSrc++;
  362. }
  363. pDst[n] = 0;
  364. n = 0;
  365. pDst = sVer;
  366. pDst[n++] = '"';
  367. if( *pSrc == ' ' )
  368. {
  369. while( *( ++pSrc ) && n < ( int ) sizeof( sVer ) - 2 )
  370. pDst[n++] = *pSrc;
  371. }
  372. pDst[n++] = '"';
  373. pDst[n] = 0;
  374. hb_pp_AddDefine_( sOS, sVer );
  375. #ifdef HB_OS_UNIX
  376. hb_strncpy( &sOS[12], "UNIX", sizeof( sOS ) - 13 );
  377. hb_pp_AddDefine_( sOS, sVer );
  378. #endif
  379. hb_xfree( szPlatform );
  380. }
  381. {
  382. char szResult[6];
  383. USHORT usHarbour = ( 256 * HB_VER_MAJOR ) + HB_VER_MINOR;
  384. /*
  385. This updates __HARBOUR__ on every change of HB_VER_MAJOR / HB_VER_MINOR
  386. HIBYTE is the HB_VER_MAJOR value and the LOBYTE is the HB_VER_MINOR value.
  387. The check below is to ensure that __HARBOUR__ gets the
  388. value of 1 by default
  389. */
  390. hb_snprintf( szResult, sizeof( szResult ), "%05d", ( usHarbour ? usHarbour : 1 ) );
  391. hb_pp_AddDefine_( "__HARBOUR__", szResult );
  392. }
  393. {
  394. int iYear, iMonth, iDay;
  395. char szResult[11];
  396. hb_dateToday( &iYear, &iMonth, &iDay );
  397. hb_dateStrPut( szResult + 1, iYear, iMonth, iDay );
  398. szResult[ 0 ] = '"';
  399. szResult[ 9 ] = '"';
  400. szResult[ 10 ] = '\0';
  401. hb_pp_AddDefine_( "__DATE__", szResult );
  402. hb_dateTimeStr( szResult + 1 );
  403. szResult[ 0 ] = '"';
  404. szResult[ 9 ] = '"';
  405. szResult[ 10 ] = '\0';
  406. hb_pp_AddDefine_( "__TIME__", szResult );
  407. }
  408. {
  409. char szResult[11];
  410. hb_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 HB_START_PROCEDURE
  427. hb_pp_AddDefine_( "__HB_MAIN__", HB_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[HB_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( hb_fsMaxFilesError() )
  488. hb_compGenError( NULL, hb_pp_szErrors, 'F', HB_PP_ERR_TOO_MANY_INCLUDES, sLine, NULL );
  489. else
  490. {
  491. #if defined(__CYGWIN__) || defined(__IBMCPP__) || defined(__LCC__) || defined( HB_OS_WIN_CE )
  492. hb_compGenError( NULL, hb_pp_szErrors, 'F', HB_PP_ERR_CANNOT_OPEN, sLine, "" );
  493. #else
  494. hb_compGenError( NULL, hb_pp_szErrors, 'F', HB_PP_ERR_CANNOT_OPEN, sLine, strerror( errno ) );
  495. #endif
  496. }
  497. }
  498. }
  499. else if( i >= 4 && i <= 6 && memcmp( sDirective, "DEFINE", i ) == 0 )
  500. hb_pp_ParseDefine_( sLine ); /* --- #define --- */
  501. else if( i >= 4 && i <= 5 && memcmp( sDirective, "UNDEF", i ) == 0 )
  502. ParseUndef( sLine ); /* --- #undef --- */
  503. else if( ( i >= 4 && i <= 7 && memcmp( sDirective, "COMMAND", i ) == 0 ) || ( i >= 4 && i <= 8 && memcmp( sDirective, "XCOMMAND", i ) == 0 ) )
  504. /* --- #command --- */
  505. ParseCommand( sLine, ( i == 7 ) ? FALSE : TRUE, TRUE );
  506. else
  507. if( ( i >= 4 && i <= 9 && memcmp( sDirective, "TRANSLATE", i ) == 0 )
  508. || ( i >= 4 && i <= 10 && memcmp( sDirective, "XTRANSLATE", i ) == 0 ) )
  509. /* --- #translate --- */
  510. ParseCommand( sLine, ( i == 9 ) ? FALSE : TRUE, FALSE );
  511. else if( i >= 4 && i <= 6 && memcmp( sDirective, "STDOUT", i ) == 0 )
  512. printf( "%s\n", sLine ); /* --- #stdout --- */
  513. else if( i >= 4 && i <= 5 && memcmp( sDirective, "ERROR", i ) == 0 )
  514. /* --- #error --- */
  515. hb_compGenError( NULL, hb_pp_szErrors, 'E', HB_PP_ERR_EXPLICIT, sLine, NULL );
  516. else if( i == 4 && memcmp( sDirective, "LINE", 4 ) == 0 )
  517. return -1;
  518. else if( i == 6 && memcmp( sDirective, "PRAGMA", 6 ) == 0 )
  519. {
  520. hb_pp_strocpy( sParse, sParse + 6 );
  521. bIgnore = hb_pp_ParsePragma( sParse ); /* --- #pragma --- */
  522. }
  523. else
  524. hb_compGenError( NULL, hb_pp_szErrors, 'F', HB_PP_ERR_WRONG_DIRECTIVE, sDirective, NULL );
  525. }
  526. return bIgnore;
  527. }
  528. int hb_pp_ParseDefine_( char *sLine )
  529. {
  530. char defname[MAX_NAME], pars[MAX_NAME + 1];
  531. int i, npars = -1;
  532. DEFINES *lastdef;
  533. HB_TRACE( HB_TR_DEBUG, ( "hb_pp_ParseDefine_(%s)", sLine ) );
  534. HB_SKIPTABSPACES( sLine );
  535. if( ISNAME( ( BYTE ) * sLine ) )
  536. {
  537. char *cParams = NULL;
  538. NextName( &sLine, defname );
  539. if( *sLine == '(' ) /* If pseudofunction was found */
  540. {
  541. int iParLen = 0;
  542. int iLen;
  543. sLine++;
  544. HB_SKIPTABSPACES( sLine );
  545. npars = 0;
  546. while( *sLine && *sLine != ')' )
  547. {
  548. if( ISNAME( ( BYTE ) * sLine ) )
  549. {
  550. NextName( &sLine, pars );
  551. iLen = strlen( pars );
  552. if( cParams == NULL )
  553. {
  554. /* 'xy0' -> '~xy0' */
  555. cParams = ( char * ) hb_xgrab( iLen + 2 );
  556. }
  557. else
  558. {
  559. /* '~xy0' -> '~xy,~ab0' */
  560. char *cPos;
  561. cPos = strstr( cParams, pars );
  562. if( cPos && ( cPos[iLen] == ',' || cPos[iLen] == '\0' ) )
  563. {
  564. cPos--;
  565. if( *cPos == '\001' )
  566. hb_compGenError( NULL, hb_pp_szErrors, 'F', HB_PP_ERR_LABEL_DUPL_IN_DEFINE, defname, pars );
  567. }
  568. cParams = ( char * ) hb_xrealloc( cParams, iParLen + iLen + 3 );
  569. cParams[iParLen++] = ',';
  570. cParams[iParLen] = '\0';
  571. }
  572. cParams[iParLen] = '\001';
  573. memcpy( cParams + iParLen + 1, pars, iLen + 1 );
  574. iParLen += iLen + 1;
  575. npars++;
  576. HB_SKIPTABSPACES( sLine );
  577. }
  578. else
  579. hb_compGenError( NULL, hb_pp_szErrors, 'F', HB_PP_ERR_LABEL_MISSING_IN_DEFINE, defname, NULL );
  580. if( *sLine == ',' )
  581. {
  582. sLine++;
  583. HB_SKIPTABSPACES( sLine );
  584. if( *sLine == ')' )
  585. hb_compGenError( NULL, hb_pp_szErrors, 'F', HB_PP_ERR_LABEL_MISSING_IN_DEFINE, defname, NULL );
  586. }
  587. }
  588. HB_SKIPTABSPACES( sLine );
  589. if( *sLine == '\0' )
  590. hb_compGenError( NULL, hb_pp_szErrors, 'F', HB_PP_ERR_PARE_MISSING_IN_DEFINE, defname, NULL );
  591. sLine++;
  592. }
  593. HB_SKIPTABSPACES( sLine );
  594. if( cParams )
  595. {
  596. char *tmp = cParams;
  597. char *cPos;
  598. int iPar, iLen, iPos, iOldPos;
  599. iLen = strlen( sLine );
  600. for( i = 0; i < npars; i++ )
  601. {
  602. /*1z,1y */
  603. cPos = strchr( tmp, ',' );
  604. if( cPos )
  605. iPar = cPos - tmp;
  606. else
  607. iPar = strlen( tmp );
  608. memcpy( pars, tmp, iPar );
  609. pars[iPar] = '\0';
  610. iOldPos = 0;
  611. while( ( iPos = md_strAt( pars + 1, iPar - 1, sLine + iOldPos, TRUE, FALSE, FALSE, MD_STR_AT_IGNORECASE ) ) != 0 )
  612. {
  613. if( sLine[iOldPos + iPos] != '\001' )
  614. {
  615. hb_pp_Stuff( pars, sLine + iOldPos + iPos - 1, iPar, iPar - 1, iLen - iPos - iOldPos );
  616. iLen++;
  617. }
  618. iOldPos += iPos + iPar;
  619. }
  620. if( cPos )
  621. tmp = cPos + 1;
  622. }
  623. }
  624. lastdef = hb_pp_AddDefine_( defname, ( *sLine == '\0' ) ? NULL : sLine );
  625. if( lastdef )
  626. {
  627. lastdef->npars = npars;
  628. lastdef->pars = cParams;
  629. }
  630. else if( cParams )
  631. hb_xfree( cParams );
  632. }
  633. else
  634. hb_compGenError( NULL, hb_pp_szErrors, 'F', HB_PP_ERR_DEFINE_ABSENT, NULL, NULL );
  635. return 0;
  636. }
  637. DEFINES *hb_pp_AddDefine_( char *defname, char *value )
  638. {
  639. BOOL isNew;
  640. DEFINES *stdef;
  641. int len = strlen( defname );
  642. HB_TRACE( HB_TR_DEBUG, ( "hb_pp_AddDefine_(%s, %s)", defname, value ) );
  643. stdef = DefSearch( defname, len, &isNew );
  644. if( stdef != NULL )
  645. {
  646. hb_compGenWarning( NULL, hb_pp_szWarnings, 'I', HB_PP_WARN_DEFINE_REDEF, defname, NULL );
  647. if( isNew )
  648. {
  649. if( stdef->pars )
  650. hb_xfree( stdef->pars );
  651. if( stdef->value )
  652. hb_xfree( stdef->value );
  653. }
  654. else
  655. return NULL;
  656. }
  657. else
  658. {
  659. stdef = ( DEFINES * ) hb_xgrab( sizeof( DEFINES ) );
  660. stdef->last = hb_pp_topDefine;
  661. hb_pp_topDefine = stdef;
  662. stdef->name = hb_strdup( defname );
  663. stdef->namelen = len;
  664. stdef->npars = -1;
  665. s_kolAddDefs++;
  666. }
  667. stdef->value = ( value == NULL ) ? NULL : hb_strdup( value );
  668. stdef->pars = NULL;
  669. return stdef;
  670. }
  671. static int ParseUndef( char *sLine )
  672. {
  673. char defname[MAX_NAME];
  674. DEFINES *stdef;
  675. BOOL isNew;
  676. int len;
  677. HB_TRACE( HB_TR_DEBUG, ( "ParseUndef(%s)", sLine ) );
  678. NextWord( &sLine, defname, FALSE );
  679. len = strlen( defname );
  680. if( ( stdef = DefSearch( defname, len, &isNew ) ) != NULL )
  681. {
  682. if( isNew )
  683. {
  684. if( stdef->pars )
  685. hb_xfree( stdef->pars );
  686. if( stdef->value )
  687. hb_xfree( stdef->value );
  688. hb_xfree( stdef->name );
  689. }
  690. stdef->pars = NULL;
  691. stdef->value = NULL;
  692. stdef->name = NULL;
  693. stdef->namelen = 0;
  694. }
  695. return 0;
  696. }
  697. static int ParseIfdef( char *sLine, int usl )
  698. {
  699. char defname[MAX_NAME];
  700. DEFINES *stdef;
  701. int len = 0;
  702. HB_TRACE( HB_TR_DEBUG, ( "ParseIfdef(%s, %d)", sLine, usl ) );
  703. if( hb_pp_nCondCompile == 0 || hb_pp_aCondCompile[hb_pp_nCondCompile - 1] )
  704. {
  705. len = NextWord( &sLine, defname, FALSE );
  706. if( *defname == '\0' )
  707. hb_compGenError( NULL, hb_pp_szErrors, 'F', HB_PP_ERR_DEFINE_ABSENT, NULL, NULL );
  708. }
  709. if( hb_pp_nCondCompile == s_maxCondCompile )
  710. {
  711. s_maxCondCompile += 5;
  712. hb_pp_aCondCompile = ( int * ) hb_xrealloc( hb_pp_aCondCompile, sizeof( int ) * s_maxCondCompile );
  713. }
  714. if( hb_pp_nCondCompile == 0 || hb_pp_aCondCompile[hb_pp_nCondCompile - 1] )
  715. {
  716. if( ( ( stdef = DefSearch( defname, len, NULL ) ) != NULL && usl ) || ( stdef == NULL && !usl ) )
  717. hb_pp_aCondCompile[hb_pp_nCondCompile] = 1;
  718. else
  719. hb_pp_aCondCompile[hb_pp_nCondCompile] = 0;
  720. }
  721. else
  722. hb_pp_aCondCompile[hb_pp_nCondCompile] = 0;
  723. hb_pp_nCondCompile++;
  724. return 0;
  725. }
  726. static DEFINES *DefSearch( char *defname, int len, BOOL * isNew )
  727. {
  728. int kol = 0, j;
  729. DEFINES *stdef = hb_pp_topDefine;
  730. HB_TRACE( HB_TR_DEBUG, ( "DefSearch(%s)", defname ) );
  731. while( stdef != NULL )
  732. {
  733. kol++;
  734. if( stdef->name != NULL && stdef->namelen == len )
  735. {
  736. for( j = 0; *( stdef->name + j ) == *( defname + j ) && *( stdef->name + j ) != '\0'; j++ ) ;
  737. if( *( stdef->name + j ) == *( defname + j ) )
  738. {
  739. if( isNew )
  740. *isNew = ( s_kolAddDefs >= kol );
  741. return stdef;
  742. }
  743. }
  744. stdef = stdef->last;
  745. }
  746. return NULL;
  747. }
  748. static COMMANDS *ComSearch( char *cmdname, COMMANDS * stcmdStart )
  749. {
  750. COMMANDS *stcmd = ( stcmdStart ) ? stcmdStart : hb_pp_topCommand;
  751. HB_TRACE( HB_TR_DEBUG, ( "ComSearch(%s, %p)", cmdname, stcmdStart ) );
  752. while( stcmd != NULL )
  753. {
  754. int j;
  755. for( j = 0; ( *( stcmd->name + j ) == HB_TOUPPER( *( cmdname + j ) ) ) &&
  756. ( *( stcmd->name + j ) != '\0' ) && ( ( stcmd->com_or_xcom ) ? 1 : ( j < 4 || ISNAME( ( BYTE ) * ( cmdname + j + 1 ) ) ) ); j++ ) ;
  757. if( ( *( stcmd->name + j ) == HB_TOUPPER( *( cmdname + j ) ) )
  758. || ( !stcmd->com_or_xcom && j >= 4 && *( stcmd->name + j ) != '\0' && *( cmdname + j ) == '\0' ) )
  759. break;
  760. stcmd = stcmd->last;
  761. }
  762. return stcmd;
  763. }
  764. static COMMANDS *TraSearch( char *cmdname, COMMANDS * sttraStart )
  765. {
  766. int j;
  767. COMMANDS *sttra = ( sttraStart ) ? sttraStart : hb_pp_topTranslate;
  768. HB_TRACE( HB_TR_DEBUG, ( "TraSearch(%s, %p)", cmdname, sttraStart ) );
  769. while( sttra != NULL )
  770. {
  771. for( j = 0; *( sttra->name + j ) == HB_TOUPPER( *( cmdname + j ) ) &&
  772. *( sttra->name + j ) != '\0' && ( ( sttra->com_or_xcom ) ? 1 : ( j < 4 || ISNAME( ( BYTE ) * ( cmdname + j + 1 ) ) ) ); j++ ) ;
  773. if( *( sttra->name + j ) == HB_TOUPPER( *( cmdname + j ) )
  774. || ( !sttra->com_or_xcom && j >= 4 && *( sttra->name + j ) != '\0' && *( cmdname + j ) == '\0' ) )
  775. break;
  776. sttra = sttra->last;
  777. }
  778. return sttra;
  779. }
  780. static void ParseCommand( char *sLine, BOOL com_or_xcom, BOOL com_or_tra )
  781. {
  782. #if !defined(HB_PP_DEBUG_MEMORY)
  783. static char mpatt[PATTERN_SIZE];
  784. #else
  785. char *mpatt = ( char * ) hb_xgrab( PATTERN_SIZE );
  786. #endif
  787. char *rpatt;
  788. char cmdname[MAX_NAME];
  789. COMMANDS *stcmd;
  790. int mlen, rlen;
  791. int ipos;
  792. /* Ron Pinkas added 2000-12-03 */
  793. BOOL bOk = FALSE;
  794. HB_TRACE( HB_TR_DEBUG, ( "ParseCommand(%s, %d, %d)", sLine, com_or_xcom, com_or_tra ) );
  795. HB_SKIPTABSPACES( sLine );
  796. ipos = 0;
  797. /* JFL 2000-09-19 */
  798. /* This was the original line as Alexander wrote it */
  799. /* while( *sLine != '\0' && *sLine != ' ' && *sLine != '\t' && *sLine != '<' && *sLine != '=' && ( *sLine != '(' || ipos == 0 ) ) */
  800. /* Now the line #xtranslate = name(.. => will be allowed */
  801. /* I changed it to the following to allow < and = to be the first char within a translate or xtranslate */
  802. while( *sLine != '\0' && *sLine != ' ' && *sLine != '\t'
  803. && ( *sLine != '<' || ipos == 0 ) && ( *sLine != '=' || ipos == 0 ) && ( *sLine != '(' || ipos == 0 ) )
  804. {
  805. /* Ron Pinkas added 2000-01-24 */
  806. if( !ISNAME( ( BYTE ) * sLine ) )
  807. {
  808. if( *sLine == '[' && ipos )
  809. break;
  810. if( IS_2CHAR_OPERATOR( sLine ) )
  811. {
  812. *( cmdname + ipos++ ) = *sLine++;
  813. *( cmdname + ipos++ ) = *sLine++;
  814. break;
  815. }
  816. else
  817. {
  818. *( cmdname + ipos++ ) = *sLine++;
  819. break;
  820. }
  821. }
  822. /* END, Ron Pinkas added 2000-01-24 */
  823. *( cmdname + ipos++ ) = *sLine++;
  824. }
  825. *( cmdname + ipos ) = '\0';
  826. if( !ipos )
  827. {
  828. #if defined(HB_PP_DEBUG_MEMORY)
  829. hb_xfree( ( void * ) mpatt );
  830. #endif
  831. return;
  832. }
  833. hb_strupr( cmdname );
  834. HB_SKIPTABSPACES( sLine );
  835. /* Ron Pinkas added 2000-12-03 */
  836. ipos = 0;
  837. while( *sLine )
  838. {
  839. mpatt[ipos++] = *sLine;
  840. if( *sLine == '=' )
  841. {
  842. int i = ipos;
  843. sLine++;
  844. mpatt[i++] = *sLine;
  845. while( *sLine && ( *sLine == ' ' || *sLine == '\t' ) )
  846. {
  847. sLine++;
  848. mpatt[i++] = *sLine;
  849. }
  850. if( *sLine == '>' )
  851. {
  852. ipos = ipos - 2;
  853. while( mpatt[ipos] == ' ' || mpatt[ipos] == '\t' )
  854. {
  855. ipos--;
  856. }
  857. mpatt[ipos + 1] = '\0';
  858. sLine++;
  859. bOk = TRUE;
  860. break;
  861. }
  862. ipos = i;
  863. }
  864. sLine++;
  865. }
  866. /* End - Ron Pinkas added 2000-12-03 */
  867. /* Ron Pinkas modified 2000-12-03
  868. if( (ipos = hb_strAt( "=>", 2, sLine, strlen(sLine) )) > 0 ) */
  869. if( bOk )
  870. {
  871. /* Ron Pinkas removed 2000-12-03
  872. stroncpy( mpatt, sLine, ipos-1 ); */
  873. mlen = strotrim( mpatt, TRUE );
  874. /* Ron Pinkas removed 2000-12-03
  875. sLine += ipos + 1; */
  876. HB_SKIPTABSPACES( sLine );
  877. /* hb_pp_strocpy( rpatt, sLine ); */
  878. rpatt = sLine;
  879. rlen = strotrim( rpatt, TRUE );
  880. ConvertPatterns( mpatt, mlen, rpatt, rlen );
  881. RemoveSlash( mpatt );
  882. rlen = RemoveSlash( rpatt );
  883. if( com_or_tra )
  884. stcmd = AddCommand( cmdname );
  885. else
  886. stcmd = AddTranslate( cmdname );
  887. stcmd->com_or_xcom = com_or_xcom;
  888. stcmd->mpatt = hb_strdup( mpatt );
  889. stcmd->value = ( rlen > 0 ) ? hb_strdup( rpatt ) : NULL;
  890. }
  891. else
  892. {
  893. sLine -= ( ipos + 1 );
  894. hb_compGenError( NULL, hb_pp_szErrors, 'F', HB_PP_ERR_COMMAND_DEFINITION, cmdname, sLine );
  895. }
  896. #if defined(HB_PP_DEBUG_MEMORY)
  897. hb_xfree( ( void * ) mpatt );
  898. #endif
  899. }
  900. /* Remove escape characters and check '[' optional markers
  901. */
  902. static int ConvertOptional( char *cpatt, int len, BOOL bLeft )
  903. {
  904. int i = 0;
  905. while( cpatt[i] != '\0' )
  906. {
  907. if( cpatt[i] == '"' || cpatt[i] == '\'' )
  908. {
  909. char c = cpatt[i];
  910. i++;
  911. while( cpatt[i] && cpatt[i] != c )
  912. {
  913. i++;
  914. }
  915. i++;
  916. continue; /* skip "strings" */
  917. }
  918. if( cpatt[i] == '[' )
  919. {
  920. if( i && cpatt[i - 1] == '\\' )
  921. {
  922. hb_pp_Stuff( "", cpatt + i - 1, 0, 1, len - i + 1 );
  923. len--;
  924. continue;
  925. }
  926. else
  927. {
  928. int j = i + 1;
  929. int iOpenBrackets = 1;
  930. BOOL bOption = FALSE;
  931. while( cpatt[j] && iOpenBrackets )
  932. {
  933. if( cpatt[j] == '[' && cpatt[j - 1] != '\\' )
  934. iOpenBrackets++;
  935. else if( cpatt[j] == ']' && cpatt[j - 1] != '\\' )
  936. {
  937. if( --iOpenBrackets == 0 && ( bOption || bLeft ) )
  938. {
  939. cpatt[i] = HB_PP_OPT_START;
  940. cpatt[j] = HB_PP_OPT_END;
  941. }
  942. }
  943. else if( cpatt[j] == '<' )
  944. {
  945. j++;
  946. while( cpatt[j] == ' ' || cpatt[j] == '\t' )
  947. j++;
  948. if( strchr( "*(!-{.\"", cpatt[j] ) || ISNAME( ( BYTE ) cpatt[j] ) )
  949. {
  950. bOption = TRUE;
  951. continue;
  952. }
  953. }
  954. else if( cpatt[j] == '"' || cpatt[j] == '\'' )
  955. {
  956. char c = cpatt[j];
  957. j++;
  958. while( cpatt[j] && cpatt[j] != c )
  959. {
  960. j++;
  961. }
  962. }
  963. j++;
  964. }
  965. if( iOpenBrackets )
  966. {
  967. hb_compGenError( NULL, hb_pp_szErrors, 'F', HB_PP_ERR_PATTERN_DEFINITION, cpatt + i, NULL );
  968. }
  969. }
  970. }
  971. else if( cpatt[i] == ']' )
  972. {
  973. if( i && cpatt[i - 1] == '\\' )
  974. {
  975. hb_pp_Stuff( "", cpatt + i - 1, 0, 1, len - i + 1 );
  976. len--;
  977. continue;
  978. }
  979. }
  980. i++;
  981. }
  982. return len;
  983. }
  984. static void RemoveOptional( char *cpatt )
  985. {
  986. int i = 0;
  987. int len = strlen( cpatt );
  988. int iOpenBra = 0;
  989. while( cpatt[i] != '\0' )
  990. {
  991. if( cpatt[i] == '"' || cpatt[i] == '\'' )
  992. {
  993. char c = cpatt[i++];
  994. while( cpatt[i] && cpatt[i] != c )
  995. {
  996. i++;
  997. }
  998. if( cpatt[i] )
  999. i++;
  1000. continue; /* skip "strings" */
  1001. }
  1002. if( cpatt[i] == '[' )
  1003. {
  1004. i++;
  1005. iOpenBra++;
  1006. while( cpatt[i] && iOpenBra )
  1007. {
  1008. if( cpatt[i] == '[' )
  1009. iOpenBra++;
  1010. else if( cpatt[i] == ']' )
  1011. iOpenBra--;
  1012. i++;
  1013. }
  1014. continue; /* skip [strings] */
  1015. }
  1016. if( cpatt[i] == HB_PP_OPT_START || cpatt[i] == HB_PP_OPT_END )
  1017. {
  1018. hb_pp_Stuff( "", cpatt + i, 0, 1, len - i + 1 );
  1019. len--;
  1020. }
  1021. else
  1022. i++;
  1023. }
  1024. }
  1025. /* ConvertPatterns()
  1026. * Converts result pattern in #command and #translate to inner format
  1027. */
  1028. static void ConvertPatterns( char *mpatt, int mlen, char *rpatt, int rlen )
  1029. {
  1030. int i = 0, ipos, ifou;
  1031. int explen, rmlen;
  1032. char exppatt[MAX_NAME], expreal[5] = " 0";
  1033. char lastchar = '@', exptype;
  1034. char *ptr, *ptrtmp;
  1035. HB_TRACE( HB_TR_DEBUG, ( "ConvertPatterns(%s, %d, %s, %d)", mpatt, mlen, rpatt, rlen ) );
  1036. expreal[0] = HB_PP_MATCH_MARK;
  1037. mlen = ConvertOptional( mpatt, mlen, TRUE ); /* left pattern */
  1038. rlen = ConvertOptional( rpatt, rlen, FALSE ); /* right pattern */
  1039. while( *( mpatt + i ) != '\0' )
  1040. {
  1041. if( mpatt[i] == '"' || mpatt[i] == '\'' )
  1042. {
  1043. char c = mpatt[i];
  1044. i++;
  1045. while( mpatt[i] && mpatt[i] != c )
  1046. {
  1047. i++;
  1048. }
  1049. i++;
  1050. continue; /* skip "strings" */
  1051. }
  1052. if( *( mpatt + i ) == '<' )
  1053. {
  1054. if( i && mpatt[ i-1 ] == '\\' )
  1055. {
  1056. i++;
  1057. continue;
  1058. }
  1059. /* Drag match marker, determine it type */
  1060. explen = 0;
  1061. ipos = i;
  1062. i++;
  1063. exptype = '0';
  1064. while( *( mpatt + i ) == ' ' || *( mpatt + i ) == '\t' )
  1065. i++;
  1066. if( *( mpatt + i ) == '*' ) /* Wild match marker */
  1067. {
  1068. exptype = '3';
  1069. i++;
  1070. }
  1071. else if( *( mpatt + i ) == '(' ) /* Extended expression match marker */
  1072. {
  1073. exptype = '4';
  1074. i++;
  1075. }
  1076. else if( *( mpatt + i ) == '!' ) /* Minimal expression match marker */
  1077. {
  1078. exptype = '5';
  1079. i++;
  1080. }
  1081. ptr = mpatt + i;
  1082. while( *ptr != '>' )
  1083. {
  1084. if( *ptr == '\0' || *ptr == '<' || *ptr == '[' || *ptr == ']' )
  1085. {
  1086. hb_compGenError( NULL, hb_pp_szErrors, 'F', HB_PP_ERR_PATTERN_DEFINITION, NULL, NULL );
  1087. return;
  1088. }
  1089. ptr++;
  1090. }
  1091. while( *( mpatt + i ) != '>' )
  1092. {
  1093. if( *( mpatt + i ) == ',' ) /* List match marker */
  1094. {
  1095. exptype = '1';
  1096. while( *( mpatt + i ) != '>' )
  1097. i++;
  1098. break;
  1099. }
  1100. else if( *( mpatt + i ) == ':' ) /* Restricted match marker */
  1101. {
  1102. exptype = '2';
  1103. *( mpatt + i-- ) = ' ';
  1104. break;
  1105. }
  1106. if( *( mpatt + i ) != ' ' && *( mpatt + i ) != '\t' )
  1107. *( exppatt + explen++ ) = *( mpatt + i );
  1108. i++;
  1109. }
  1110. if( exptype == '3' )
  1111. {
  1112. if( *( exppatt + explen - 1 ) == '*' )
  1113. explen--;
  1114. else
  1115. hb_compGenError( NULL, hb_pp_szErrors, 'F', HB_PP_ERR_PATTERN_DEFINITION, NULL, NULL );
  1116. }
  1117. else if( exptype == '4' )
  1118. {
  1119. if( *( exppatt + explen - 1 ) == ')' )
  1120. explen--;
  1121. else
  1122. hb_compGenError( NULL, hb_pp_szErrors, 'F', HB_PP_ERR_PATTERN_DEFINITION, NULL, NULL );
  1123. }
  1124. else if( exptype == '5' )
  1125. {
  1126. if( *( exppatt + explen - 1 ) == '!' )
  1127. explen--;
  1128. else
  1129. hb_compGenError( NULL, hb_pp_szErrors, 'F', HB_PP_ERR_PATTERN_DEFINITION, NULL, NULL );
  1130. }
  1131. rmlen = i - ipos + 1;
  1132. /* Convert match marker into inner format */
  1133. lastchar = ( lastchar != 'Z' ) ? ( ( char ) ( ( unsigned int ) lastchar + 1 ) ) : 'a';
  1134. expreal[1] = lastchar;
  1135. expreal[2] = exptype;
  1136. hb_pp_Stuff( expreal, mpatt + ipos, 4, rmlen, mlen - ipos );
  1137. mlen += 4 - rmlen;
  1138. i += 4 - rmlen;
  1139. /* Look for appropriate result markers */
  1140. ptr = rpatt;
  1141. while( ( ifou = hb_strAt( exppatt, explen, ptr, rlen - ( ptr - rpatt ) ) ) > 0 )
  1142. {
  1143. /* Convert result marker into inner format */
  1144. ifou--;
  1145. ptr += ifou;
  1146. ptrtmp = ptr + 1;
  1147. rmlen = explen;
  1148. exptype = '0'; /* regular result marker */
  1149. do
  1150. {
  1151. ptr--;
  1152. rmlen++;
  1153. ifou--;
  1154. if( *ptr == '<' )
  1155. continue;
  1156. else if( *ptr == '\"' )
  1157. exptype = '2'; /* normal stringify result marker */
  1158. else if( *ptr == '(' )
  1159. exptype = '3'; /* Smart stringify result marker */
  1160. else if( *ptr == '{' )
  1161. exptype = '4'; /* Blockify result marker */
  1162. else if( *ptr == '.' )
  1163. exptype = '5'; /* Logify result marker */
  1164. else if( *ptr == '-' )
  1165. exptype = '6'; /* ommit (remove) result marker */
  1166. else if( *ptr == ' ' || *ptr == '\t' )
  1167. continue;
  1168. else
  1169. ifou = -1;
  1170. }
  1171. while( ifou >= 0 && *ptr != '<' && *( ptr - 1 ) != '\\' );
  1172. if( ifou >= 0 && *ptr == '<' )
  1173. {
  1174. ptr += rmlen++;
  1175. while( *ptr != '\0' && *ptr != '>' && *( ptr - 1 ) != '\\' )
  1176. {
  1177. if( *ptr != ' ' && *ptr != '\t' && *ptr != '\"' && *ptr != ')' && *ptr != '}' && *ptr != '.' && *ptr != '-' )
  1178. {
  1179. ifou = -1;
  1180. break;
  1181. }
  1182. rmlen++;
  1183. ptr++;
  1184. }
  1185. if( ifou >= 0 && *ptr == '>' )
  1186. {
  1187. ptr -= rmlen;
  1188. ptr++;
  1189. if( exptype == '0' && *( ptr - 1 ) == '#' && *( ptr - 2 ) != '\\' )
  1190. {
  1191. exptype = '1'; /* dumb stringify result marker */
  1192. ptr--;
  1193. rmlen++;
  1194. }
  1195. expreal[2] = exptype;
  1196. hb_pp_Stuff( expreal, ptr, 4, rmlen, rlen + ( rpatt - ptr ) );
  1197. rlen += 4 - rmlen;
  1198. }
  1199. else
  1200. ptr = ptrtmp;
  1201. }
  1202. else
  1203. ptr = ptrtmp;
  1204. }
  1205. }
  1206. i++;
  1207. }
  1208. }
  1209. static COMMANDS *AddCommand( char *cmdname )
  1210. {
  1211. COMMANDS *stcmd;
  1212. HB_TRACE( HB_TR_DEBUG, ( "AddCommand(%s)", cmdname ) );
  1213. stcmd = ( COMMANDS * ) hb_xgrab( sizeof( COMMANDS ) );
  1214. stcmd->last = hb_pp_topCommand;
  1215. hb_pp_topCommand = stcmd;
  1216. stcmd->name = hb_strdup( cmdname );
  1217. stcmd->namelen = strlen( cmdname );
  1218. s_kolAddComs++;
  1219. return stcmd;
  1220. }
  1221. static COMMANDS *AddTranslate( char *traname )
  1222. {
  1223. COMMANDS *sttra;
  1224. HB_TRACE( HB_TR_DEBUG, ( "AddTranslate(%s)", traname ) );
  1225. sttra = ( COMMANDS * ) hb_xgrab( sizeof( COMMANDS ) );
  1226. sttra->last = hb_pp_topTranslate;
  1227. hb_pp_topTranslate = sttra;
  1228. sttra->name = hb_strdup( traname );
  1229. sttra->namelen = strlen( traname );
  1230. s_kolAddTras++;
  1231. return sttra;
  1232. }
  1233. int hb_pp_ParseExpression( char *sLine, char *sOutLine, BOOL bSplitLines )
  1234. {
  1235. #if !defined(HB_PP_DEBUG_MEMORY)
  1236. static char rpatt[PATTERN_SIZE];
  1237. #else
  1238. char *rpatt = ( char * ) hb_xgrab( PATTERN_SIZE );
  1239. #endif
  1240. char sToken[MAX_NAME];
  1241. char *ptri, *ptro, *ptrb;
  1242. int lenToken, i, ipos, isdvig, lens;
  1243. int ifou;
  1244. int rezDef, rezTra, rezCom;
  1245. unsigned int kolpass = 0;
  1246. DEFINES *stdef;
  1247. COMMANDS *stcmd;
  1248. HB_TRACE( HB_TR_DEBUG, ( "hb_pp_ParseExpression(%s, %s)", sLine, sOutLine ) );
  1249. do
  1250. {
  1251. strotrim( sLine, FALSE );
  1252. rezDef = 0;
  1253. rezTra = 0;
  1254. rezCom = 0;
  1255. isdvig = 0;
  1256. do
  1257. {
  1258. ptro = sOutLine;
  1259. ptri = sLine + isdvig;
  1260. if( bSplitLines )
  1261. ipos = md_strAt( ";", 1, ptri, TRUE, FALSE, FALSE, MD_STR_AT_IGNORECASE );
  1262. else
  1263. ipos = 0;
  1264. if( ipos > 0 )
  1265. {
  1266. *( ptri + ipos - 1 ) = '\0';
  1267. }
  1268. HB_SKIPTABSPACES( ptri );
  1269. if( *ptri == '#' )
  1270. {
  1271. int bIgnore;
  1272. hb_strncpy( rpatt, ptri, PATTERN_SIZE - 1 );
  1273. bIgnore = hb_pp_ParseDirective_( rpatt );
  1274. if( ipos > 0 )
  1275. {
  1276. ipos--;
  1277. *( sLine + isdvig + ipos - 1 ) = ';';
  1278. *( sLine + isdvig + ipos ) = ' ';
  1279. }
  1280. lens = strlen( sLine + isdvig );
  1281. if( bIgnore )
  1282. hb_pp_Stuff( " ", sLine + isdvig, 0, ( ipos ) ? ipos : lens, lens );
  1283. else
  1284. hb_pp_Stuff( rpatt, sLine + isdvig, strlen( rpatt ), ( ipos ) ? ipos : lens, lens );
  1285. if( ipos > 0 )
  1286. {
  1287. ipos = 1;
  1288. }
  1289. }
  1290. else
  1291. { /* Look for macros from #define */
  1292. while( ( lenToken = NextName( &ptri, sToken ) ) > 0 )
  1293. {
  1294. #if 0
  1295. printf( "Token: >%s< Line: >%s<\n", sToken, sLine );
  1296. #endif
  1297. if( ( stdef = DefSearch( sToken, lenToken, NULL ) ) != NULL )
  1298. {
  1299. ptrb = ptri - lenToken;
  1300. if( ( i = WorkDefine( &ptri, ptro, stdef ) ) >= 0 )
  1301. {
  1302. rezDef++;
  1303. lens = strlen( ptrb );
  1304. if( ipos > 0 )
  1305. {
  1306. *( ptrb + lens ) = ';';
  1307. lens += strlen( ptrb + lens + 1 );
  1308. }
  1309. hb_pp_Stuff( ptro, ptrb, i, ptri - ptrb, lens + 1 );
  1310. if( ipos > 0 )
  1311. {
  1312. ipos += i - ( ptri - ptrb );
  1313. *( sLine + isdvig + ipos - 1 ) = '\0';
  1314. }
  1315. ptri += i - ( ptri - ptrb );
  1316. }
  1317. }
  1318. }
  1319. if( rezDef == 0 )
  1320. {
  1321. /* Look for definitions from #translate */
  1322. stcmd = hb_pp_topTranslate;
  1323. while( stcmd != NULL )
  1324. {
  1325. ptri = sLine + isdvig;
  1326. lenToken = stcmd->namelen;
  1327. while( ( ifou = md_strAt( stcmd->name, lenToken, ptri, TRUE, FALSE, FALSE, MD_STR_AT_USESUBCASE ) ) > 0 )
  1328. {
  1329. ptri += ifou - 1;
  1330. if( ( i = WorkTranslate( ptri + lenToken, ptro, stcmd, &lens ) ) >= 0 )
  1331. {
  1332. lens += lenToken;
  1333. while( lens > 0 && ( *( ptri + lens - 1 ) == ' ' || *( ptri + lens - 1 ) == '\t' ) )
  1334. {
  1335. lens--;
  1336. }
  1337. if( ipos > 0 )
  1338. {
  1339. *( sLine + isdvig + ipos - 1 ) = ';';
  1340. }
  1341. hb_pp_Stuff( ptro, ptri, i, lens, strlen( ptri ) );
  1342. rezTra = 1;
  1343. if( ipos > 0 )
  1344. {
  1345. ipos += i - lens;
  1346. *( sLine + isdvig + ipos - 1 ) = '\0';
  1347. }
  1348. ptri += i;
  1349. }
  1350. else
  1351. {
  1352. ptri += lenToken;
  1353. }
  1354. }
  1355. stcmd = stcmd->last;
  1356. }
  1357. } /* rezDef == 0 */
  1358. /* Look for definitions from #command */
  1359. /* JFL ! Was 3 but insufficient in most cases */
  1360. /* I know this is a new hardcoded limit ... any better idea's welcome */
  1361. if( rezDef == 0 && rezTra == 0 && kolpass < 20 )
  1362. {
  1363. ptri = sLine + isdvig;
  1364. HB_SKIPTABSPACES( ptri );
  1365. if( ISNAME( ( BYTE ) * ptri ) )
  1366. {
  1367. NextName( &ptri, sToken );
  1368. }
  1369. else
  1370. {
  1371. /* Ron Pinkas commented 2000-01-24
  1372. i = 0;
  1373. while( *ptri != ' ' && *ptri != '\t' && *ptri != '\0' && *ptri != '\"' && *ptri != '\'' && *ptri != '(' && !ISNAME( ( BYTE ) *ptri ) )
  1374. {
  1375. *(sToken+i) = *ptri++;
  1376. i++;
  1377. }
  1378. *(sToken+i) = '\0';
  1379. */
  1380. /* Ron Pinkas added 2000-01-24 */
  1381. if( IS_2CHAR_OPERATOR( ptri ) )
  1382. {
  1383. sToken[0] = *ptri++;
  1384. sToken[1] = *ptri++;
  1385. sToken[2] = '\0';
  1386. }
  1387. else
  1388. {
  1389. sToken[0] = *ptri++;
  1390. sToken[1] = '\0';
  1391. }
  1392. /* END, Ron Pinkas added 2000-01-24 */
  1393. }
  1394. HB_SKIPTABSPACES( ptri );
  1395. if( ( *ptri == '\0'
  1396. || ( *ptri != '='
  1397. && ( !IsInStr( *ptri, ":/+*-%^" )
  1398. || *( ptri + 1 ) != '=' ) && ( *ptri != '-'
  1399. || *( ptri + 1 ) != '>' ) ) ) && ( stcmd = ComSearch( sToken, NULL ) ) != NULL )
  1400. {
  1401. ptro = sOutLine;
  1402. i = WorkCommand( ptri, ptro, stcmd );
  1403. ptri = sLine + isdvig;
  1404. if( ipos > 0 )
  1405. {
  1406. *( ptri + ipos - 1 ) = ';';
  1407. }
  1408. if( i >= 0 )
  1409. {
  1410. if( isdvig + ipos > 0 )
  1411. {
  1412. lens = strlen( sLine + isdvig );
  1413. hb_pp_Stuff( ptro, sLine + isdvig, i, ( ipos ) ? ipos - 1 : lens, lens );
  1414. if( ipos > 0 )
  1415. {
  1416. ipos = i + 1;
  1417. }
  1418. }
  1419. else
  1420. {
  1421. memcpy( sLine, sOutLine, i + 1 );
  1422. }
  1423. }
  1424. rezCom = 1;
  1425. }
  1426. else if( ipos > 0 )
  1427. {
  1428. *( sLine + isdvig + ipos - 1 ) = ';';
  1429. }
  1430. }
  1431. else if( ipos > 0 )
  1432. {
  1433. *( sLine + isdvig + ipos - 1 ) = ';';
  1434. }
  1435. }
  1436. isdvig += ipos;
  1437. }
  1438. while( ipos != 0 );
  1439. kolpass++;
  1440. if( kolpass > hb_pp_MaxTranslateCycles && ( rezDef || rezTra || rezCom ) )
  1441. {
  1442. hb_compGenError( NULL, hb_pp_szErrors, 'F', HB_PP_ERR_RECURSE, NULL, NULL );
  1443. break;
  1444. }
  1445. }
  1446. while( rezDef || rezTra || rezCom );
  1447. RemoveOptional( sLine );
  1448. if( *sOutLine )
  1449. {
  1450. RemoveOptional( sOutLine );
  1451. }
  1452. #if defined(HB_PP_DEBUG_MEMORY)
  1453. hb_xfree( ( void * ) rpatt );
  1454. #endif
  1455. return 0;
  1456. }
  1457. static int WorkDefine( char **ptri, char *ptro, DEFINES * stdef )
  1458. {
  1459. int npars, lens;
  1460. char *ptr;
  1461. HB_TRACE( HB_TR_DEBUG, ( "WorkDefine(%p, %s, %p)", ptri, ptro, stdef ) );
  1462. if( stdef->npars < 0 )
  1463. {
  1464. lens = hb_pp_strocpy( ptro, stdef->value );
  1465. }
  1466. else
  1467. {
  1468. HB_SKIPTABSPACES( *ptri );
  1469. if( **ptri == '(' )
  1470. {
  1471. npars = 0;
  1472. ptr = *ptri;
  1473. do
  1474. {
  1475. ptr++;
  1476. if( NextParm( &ptr, NULL ) > 0 )
  1477. {
  1478. npars++;
  1479. }
  1480. }
  1481. while( *ptr != ')' && *ptr != '\0' );
  1482. if( *ptr == ')' && stdef->npars == npars )
  1483. {
  1484. /* Ron Pinkas added 2000-11-21 */
  1485. char *pTmp = ptr + 1;
  1486. while( *pTmp && ( *pTmp == ' ' || *pTmp == '\t' ) )
  1487. {
  1488. pTmp++;
  1489. }
  1490. if( *pTmp == '[' )
  1491. {
  1492. s_bArray = TRUE;
  1493. }
  1494. /* END - Ron Pinkas added 2000-11-21 */
  1495. lens = WorkPseudoF( ptri, ptro, stdef );
  1496. }
  1497. else
  1498. {
  1499. return -1;
  1500. }
  1501. }
  1502. else
  1503. {
  1504. return -1;
  1505. }
  1506. }
  1507. return lens;
  1508. }
  1509. static int WorkPseudoF( char **ptri, char *ptro, DEFINES * stdef )
  1510. {
  1511. char parfict[MAX_NAME], *ptrreal;
  1512. char *ptrb;
  1513. int ipos, ifou, ibeg;
  1514. int lenfict, lenreal, lenres;
  1515. HB_TRACE( HB_TR_DEBUG, ( "WorkPseudoF(%p, %s, %p)", ptri, ptro, stdef ) );
  1516. lenres = hb_pp_strocpy( ptro, stdef->value ); /* Copying value of macro to destination string */
  1517. if( stdef->pars )
  1518. {
  1519. ipos = 0;
  1520. ibeg = 0;
  1521. for( ;; ) /* Parsing through parameters */
  1522. { /* in macro definition */
  1523. if( *( stdef->pars + ipos ) == ',' || *( stdef->pars + ipos ) == '\0' )
  1524. {
  1525. *( parfict + ipos - ibeg ) = '\0';
  1526. lenfict = ipos - ibeg;
  1527. if( **ptri != ')' )
  1528. {
  1529. ( *ptri )++; /* Get next real parameter */
  1530. HB_SKIPTABSPACES( *ptri );
  1531. ptrreal = *ptri;
  1532. lenreal = NextParm( ptri, NULL );
  1533. ptrb = ptro;
  1534. while( ( ifou = hb_strAt( parfict, lenfict, ptrb, lenres - ( ptrb - ptro ) ) ) > 0 )
  1535. {
  1536. ptrb = ptrb + ifou - 1;
  1537. if( !ISNAME( ( BYTE ) * ( ptrb - 1 ) ) && !ISNAME( ( BYTE ) * ( ptrb + lenfict ) ) )
  1538. {
  1539. hb_pp_Stuff( ptrreal, ptrb, lenreal, lenfict, lenres + ( ptro - ptrb ) );
  1540. lenres += lenreal - lenfict;
  1541. ptrb += lenreal;
  1542. }
  1543. else
  1544. {
  1545. ptrb++;
  1546. }
  1547. }
  1548. ibeg = ipos + 1;
  1549. }
  1550. }
  1551. else
  1552. {
  1553. *( parfict + ipos - ibeg ) = *( stdef->pars + ipos );
  1554. }
  1555. if( *( stdef->pars + ipos ) == '\0' )
  1556. {
  1557. break;
  1558. }
  1559. ipos++;
  1560. }
  1561. }
  1562. else
  1563. {
  1564. while( **ptri != ')' )
  1565. {
  1566. ( *ptri )++;
  1567. }
  1568. }
  1569. ( *ptri )++;
  1570. return lenres;
  1571. }
  1572. static int WorkCommand( char *ptri, char *ptro, COMMANDS * stcmd )
  1573. {
  1574. int rez;
  1575. int lenres;
  1576. char *ptrmp;
  1577. char *sToken = stcmd->name;
  1578. HB_TRACE( HB_TR_DEBUG, ( "WorkCommand(%s, %s, %p)", ptri, ptro, stcmd ) );
  1579. do
  1580. {
  1581. lenres = hb_pp_strocpy( ptro, stcmd->value ); /* Copying result pattern */
  1582. ptrmp = stcmd->mpatt; /* Pointer to a match pattern */
  1583. s_Repeate = 0;
  1584. s_groupchar = '@';
  1585. rez = CommandStuff( ptrmp, ptri, ptro, &lenres, TRUE, stcmd->com_or_xcom );
  1586. stcmd = stcmd->last;
  1587. if( rez < 0 && stcmd != NULL )
  1588. stcmd = ComSearch( sToken, stcmd );
  1589. }
  1590. while( rez < 0 && stcmd != NULL );
  1591. *( ptro + lenres ) = '\0';
  1592. if( rez >= 0 )
  1593. {
  1594. return lenres;
  1595. }
  1596. return -1;
  1597. }
  1598. static int WorkTranslate( char *ptri, char *ptro, COMMANDS * sttra, int *lens )
  1599. {
  1600. int rez;
  1601. int lenres;
  1602. char *ptrmp;
  1603. char *sToken = sttra->name;
  1604. HB_TRACE( HB_TR_DEBUG, ( "WorkTranslate(%s, %s, %p, %p)", ptri, ptro, sttra, lens ) );
  1605. do
  1606. {
  1607. lenres = hb_pp_strocpy( ptro, sttra->value );
  1608. ptrmp = sttra->mpatt;
  1609. s_Repeate = 0;
  1610. s_groupchar = '@';
  1611. rez = CommandStuff( ptrmp, ptri, ptro, &lenres, FALSE, sttra->com_or_xcom );
  1612. sttra = sttra->last;
  1613. if( rez < 0 && sttra != NULL )
  1614. {
  1615. sttra = TraSearch( sToken, sttra );
  1616. }
  1617. }
  1618. while( rez < 0 && sttra != NULL );
  1619. *( ptro + lenres ) = '\0';
  1620. if( rez >= 0 )
  1621. {
  1622. *lens = rez;
  1623. return lenres;
  1624. }
  1625. return -1;
  1626. }
  1627. #define MAX_OPTIONALS 64
  1628. static int CommandStuff( char *ptrmp, char *inputLine, char *ptro, int *lenres, BOOL com_or_tra, BOOL com_or_xcom )
  1629. {
  1630. BOOL endTranslation = FALSE;
  1631. int ipos;
  1632. char *lastopti[MAX_OPTIONALS], *strtopti = NULL, *strtptri = NULL;
  1633. char *ptri = inputLine, *ptr, tmpname[MAX_NAME];
  1634. int isWordInside = 0;
  1635. char szMatch[2];
  1636. char *cSkipped[MAX_OPTIONALS];
  1637. int iSkipped = 0;
  1638. /*
  1639. printf( "MP: >%s<\nIn: >%s<\n", ptrmp, ptri );
  1640. */
  1641. HB_TRACE( HB_TR_DEBUG, ( "CommandStuff(%s, %s, %s, %p, %d, %d)", ptrmp, inputLine, ptro, lenres, com_or_tra, com_or_xcom ) );
  1642. s_numBrackets = 0;
  1643. HB_SKIPTABSPACES( ptri );
  1644. if( ptrmp == NULL )
  1645. {
  1646. if( *ptri != '\0' )
  1647. return -1;
  1648. }
  1649. else
  1650. {
  1651. while( *ptri != '\0' && !endTranslation )
  1652. {
  1653. HB_SKIPTABSPACES( ptrmp );
  1654. if( *ptrmp == HB_PP_OPT_START && !s_numBrackets && !strtopti )
  1655. {
  1656. /* Store start position of outermost optional in pattern */
  1657. strtopti = ptrmp;
  1658. }
  1659. if( !s_numBrackets && strtopti && strtptri != ptri &&
  1660. ( ISNAME( ( BYTE ) * ptri ) || *ptri == '&' ) )
  1661. {
  1662. /* Input stream starts with a word or macro -store the position
  1663. * which matches the outermost optional in pattern
  1664. */
  1665. strtptri = ptri;
  1666. ptrmp = strtopti;
  1667. ptr = ptri;
  1668. ipos = NextName( &ptr, tmpname ); /* get starting keyword */
  1669. ipos = md_strAt( tmpname, ipos, strtopti, TRUE, TRUE, TRUE, MD_STR_AT_USESUBCASE );
  1670. if( ipos && TestOptional( strtopti, strtopti + ipos - 2 ) )
  1671. {
  1672. /* the keyword from input is found in the pattern */
  1673. ptr = PrevSquare( strtopti + ipos - 2, strtopti, NULL );
  1674. if( ptr )
  1675. ptrmp = ptr;
  1676. if( ptr != strtopti )
  1677. {
  1678. cSkipped[ iSkipped++ ] = strtopti;
  1679. }
  1680. }
  1681. }
  1682. switch ( *ptrmp )
  1683. {
  1684. case HB_PP_OPT_START:
  1685. if( !s_numBrackets )
  1686. isWordInside = 0;
  1687. s_numBrackets++;
  1688. s_aIsRepeate[s_Repeate] = 0;
  1689. lastopti[s_Repeate++] = ptrmp;
  1690. ptrmp++;
  1691. if( !CheckOptional( ptrmp, ptri, ptro, lenres, com_or_tra, com_or_xcom ) )
  1692. {
  1693. SkipOptional( &ptrmp );
  1694. }
  1695. break;
  1696. case HB_PP_OPT_END:
  1697. if( s_Repeate )
  1698. {
  1699. s_Repeate--;
  1700. if( s_aIsRepeate[s_Repeate] )
  1701. {
  1702. if( ISNAME( ( BYTE ) * ptri ) )
  1703. {
  1704. ptr = ptri;
  1705. ipos = NextName( &ptr, tmpname );
  1706. ipos = md_strAt( tmpname, ipos, ptrmp, TRUE, TRUE, TRUE, MD_STR_AT_USESUBCASE );
  1707. if( ipos && TestOptional( ptrmp + 1, ptrmp + ipos - 2 ) )
  1708. {
  1709. ptr = PrevSquare( ptrmp + ipos - 2, ptrmp + 1, NULL );
  1710. if( !ptr || CheckOptional( ptrmp + 1, ptri, ptro, lenres, com_or_tra, com_or_xcom ) )
  1711. {
  1712. ptrmp = lastopti[s_Repeate];
  1713. ptrmp++;
  1714. s_Repeate++;
  1715. SkipOptional( &ptrmp );
  1716. s_numBrackets++;
  1717. ptrmp++;
  1718. strtptri = ptri;
  1719. }
  1720. else
  1721. ptrmp = lastopti[s_Repeate];
  1722. }
  1723. else
  1724. {
  1725. ptrmp = lastopti[s_Repeate];
  1726. }
  1727. }
  1728. else
  1729. {
  1730. ptrmp = lastopti[s_Repeate];
  1731. }
  1732. }
  1733. else
  1734. {
  1735. if( !isWordInside )
  1736. strtopti = NULL;
  1737. ptrmp++;
  1738. }
  1739. s_numBrackets--;
  1740. }
  1741. else
  1742. {
  1743. if( !isWordInside )
  1744. strtopti = NULL;
  1745. s_numBrackets--;
  1746. ptrmp++;
  1747. }
  1748. break;
  1749. case ',':
  1750. if( s_numBrackets == 1 )
  1751. isWordInside = 1;
  1752. if( !s_numBrackets )
  1753. strtopti = NULL;
  1754. if( *ptri == ',' )
  1755. {
  1756. ptrmp++;
  1757. ptri++;
  1758. }
  1759. else
  1760. {
  1761. if( s_numBrackets )
  1762. {
  1763. SkipOptional( &ptrmp );
  1764. }
  1765. else
  1766. return -1;
  1767. }
  1768. break;
  1769. case HB_PP_MATCH_MARK: /* Match marker */
  1770. if( !s_numBrackets )
  1771. strtopti = NULL;
  1772. if( s_numBrackets == 1 && *( ptrmp + 2 ) == '2' )
  1773. isWordInside = 1; /* restricted match marker */
  1774. if( ! WorkMarkers( &ptrmp, &ptri, ptro, lenres, com_or_tra, com_or_xcom ) )
  1775. {
  1776. if( s_numBrackets )
  1777. {
  1778. SkipOptional( &ptrmp );
  1779. }
  1780. else
  1781. return -1;
  1782. }
  1783. break;
  1784. case '\0':
  1785. if( iSkipped )
  1786. {
  1787. ptrmp = cSkipped[ --iSkipped ];
  1788. break;
  1789. }
  1790. if( com_or_tra )
  1791. return -1;
  1792. else
  1793. endTranslation = TRUE;
  1794. break;
  1795. default: /* Key word */
  1796. if( s_numBrackets == 1 )
  1797. isWordInside = 1;
  1798. if( !s_numBrackets )
  1799. strtopti = NULL;
  1800. ptr = ptri;
  1801. if( *ptri == ',' || truncmp( &ptri, &ptrmp, !com_or_xcom ) )
  1802. {
  1803. ptri = ptr;
  1804. if( s_numBrackets )
  1805. {
  1806. SkipOptional( &ptrmp );
  1807. }
  1808. else
  1809. return -1;
  1810. }
  1811. }
  1812. HB_SKIPTABSPACES( ptri );
  1813. };
  1814. }
  1815. if( *ptrmp != '\0' )
  1816. {
  1817. if( s_Repeate )
  1818. {
  1819. s_Repeate = 0;
  1820. ptrmp = lastopti[0];
  1821. }
  1822. s_numBrackets = 0;
  1823. do
  1824. {
  1825. HB_SKIPTABSPACES( ptrmp );
  1826. if( *ptrmp != '\0' )
  1827. switch ( *ptrmp )
  1828. {
  1829. case HB_PP_OPT_START:
  1830. ptrmp++;
  1831. SkipOptional( &ptrmp );
  1832. ptrmp++;
  1833. break;
  1834. case HB_PP_OPT_END:
  1835. ptrmp++;
  1836. break;
  1837. default:
  1838. return -1;
  1839. }
  1840. }
  1841. while( *ptrmp != '\0' );
  1842. }
  1843. szMatch[0] = HB_PP_MATCH_MARK;
  1844. szMatch[1] = '\0';
  1845. SearnRep( szMatch, "", 0, ptro, lenres );
  1846. *( ptro + *lenres ) = '\0';
  1847. if( com_or_tra )
  1848. return 1;
  1849. else
  1850. return ( ptri - inputLine );
  1851. }
  1852. static int RemoveSlash( char *cpatt )
  1853. {
  1854. int i = 0;
  1855. int lenres = strlen( cpatt );
  1856. while( cpatt[i] != '\0' )
  1857. {
  1858. if( cpatt[i] == '"' || cpatt[i] == '\'' )
  1859. {
  1860. char c = cpatt[i];
  1861. i++;
  1862. while( cpatt[i] && cpatt[i] != c )
  1863. {
  1864. i++;
  1865. }
  1866. i++;
  1867. continue; /* skip "strings" */
  1868. }
  1869. if( cpatt[i] == '[' )
  1870. {
  1871. i++;
  1872. while( cpatt[i] && cpatt[i] != ']' )
  1873. {
  1874. i++;
  1875. }
  1876. i++;
  1877. continue; /* skip [strings] */
  1878. }
  1879. if( cpatt[i] == '\\' )
  1880. {
  1881. hb_pp_Stuff( "", cpatt + i, 0, 1, lenres - i + 1 );
  1882. lenres--;
  1883. i++;
  1884. }
  1885. else
  1886. i++;
  1887. }
  1888. return lenres;
  1889. }
  1890. static int WorkMarkers( char **ptrmp, char **ptri, char *ptro, int *lenres, BOOL com_or_tra, BOOL com_or_xcom )
  1891. {
  1892. #if ! defined(HB_PP_DEBUG_MEMORY)
  1893. char exppatt[MAX_NAME];
  1894. #else
  1895. char *exppatt = ( char * ) hb_xgrab( MAX_NAME );
  1896. #endif
  1897. int lenreal = 0, maxlenreal, lenpatt;
  1898. int rezrestr, ipos, nBra;
  1899. char *ptr, *ptrtemp;
  1900. HB_TRACE( HB_TR_DEBUG, ( "WorkMarkers(%p, %p, %s, %p)", ptrmp, ptri, ptro, lenres ) );
  1901. maxlenreal = HB_PP_STR_SIZE;
  1902. if( s_expreal == NULL )
  1903. s_expreal = ( char * ) hb_xgrab( maxlenreal + 1 );
  1904. /* Copying a match pattern to 'exppatt' */
  1905. lenpatt = stroncpy( exppatt, *ptrmp, 4 );
  1906. *ptrmp += 4;
  1907. HB_SKIPTABSPACES( *ptrmp );
  1908. /* JFL removed 12/11/2001 to allow param like (,,3) as allowed by clipper */
  1909. /*
  1910. if( **ptri == ',' )
  1911. {
  1912. if( s_numBrackets )
  1913. {
  1914. return 0;
  1915. }
  1916. } */
  1917. ptrtemp = *ptrmp;
  1918. if( *( exppatt + 2 ) != '2' && *ptrtemp == HB_PP_OPT_END )
  1919. {
  1920. ptrtemp++;
  1921. HB_SKIPTABSPACES( ptrtemp );
  1922. while( *ptrtemp == HB_PP_OPT_START )
  1923. {
  1924. nBra = 0;
  1925. ptrtemp++;
  1926. while( ( *ptrtemp != HB_PP_OPT_END || nBra ) && *ptrtemp != '\0' )
  1927. {
  1928. if( *ptrtemp == HB_PP_OPT_START )
  1929. {
  1930. nBra++;
  1931. }
  1932. else if( *ptrtemp == HB_PP_OPT_END )
  1933. {
  1934. nBra--;
  1935. }
  1936. ptrtemp++;
  1937. }
  1938. ptrtemp++;
  1939. HB_SKIPTABSPACES( ptrtemp );
  1940. }
  1941. }
  1942. if( *( exppatt + 2 ) != '2' && *ptrtemp != HB_PP_MATCH_MARK
  1943. && *ptrtemp != ',' && *ptrtemp != HB_PP_OPT_START && *ptrtemp != HB_PP_OPT_END && *ptrtemp != '\0' )
  1944. {
  1945. lenreal = strincpy( s_expreal, ptrtemp );
  1946. if( ( ipos = md_strAt( s_expreal, lenreal, *ptri, TRUE, TRUE, FALSE, MD_STR_AT_USESUBCASE ) ) > 0 )
  1947. {
  1948. if( ptrtemp >