PageRenderTime 45ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/tags/old-eval-stack/harbour/source/pp/ppcore.c

#
C | 2340 lines | 1881 code | 286 blank | 173 comment | 771 complexity | 98778e3ee31cbd2793cbf0cb20e3c88f 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: ppcore.c 3583 2000-12-03 18:49:52Z ronpinkas $
  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 of the License, or
  14. * (at your option) any later version, with one exception:
  15. *
  16. * The exception is that if you link the Harbour Runtime Library (HRL)
  17. * and/or the Harbour Virtual Machine (HVM) with other files to produce
  18. * an executable, this does not by itself cause the resulting executable
  19. * to be covered by the GNU General Public License. Your use of that
  20. * executable is in no way restricted on account of linking the HRL
  21. * and/or HVM code into it.
  22. *
  23. * This program is distributed in the hope that it will be useful,
  24. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  26. * GNU General Public License for more details.
  27. *
  28. * You should have received a copy of the GNU General Public License
  29. * along with this program; if not, write to the Free Software
  30. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit
  31. * their web site at http://www.gnu.org/).
  32. *
  33. */
  34. /*
  35. * The following parts are Copyright of the individual authors.
  36. * www - http://www.harbour-project.org
  37. *
  38. * Copyright 2000 Victor Szakats <info@szelvesz.hu>
  39. * __DATE__, __TIME__, __HB_MAIN__ support
  40. *
  41. * Copyright 2000 Ron Pinkas <Ron@Profit-Master.com>
  42. *
  43. * hb_pp_SetRules() and related code for supportting
  44. * replaceable rules with -w switch
  45. *
  46. * See doc/license.txt for licensing terms.
  47. *
  48. */
  49. /*
  50. * Avoid tracing in preprocessor/compiler.
  51. */
  52. #if ! defined(HB_TRACE_UTILS)
  53. #if defined(HB_TRACE_LEVEL)
  54. #undef HB_TRACE_LEVEL
  55. #endif
  56. #endif
  57. #include <stdio.h>
  58. #include <stdlib.h>
  59. #include <string.h>
  60. #include <ctype.h>
  61. #include <time.h>
  62. #include <errno.h>
  63. #include "hbpp.h"
  64. #include "hbcomp.h"
  65. #if defined( OS_UNIX_COMPATIBLE )
  66. #include <sys/timeb.h>
  67. #else
  68. #include <sys\timeb.h>
  69. #endif
  70. int hb_pp_ParseDefine( char * ); /* Process #define directive */
  71. static COMMANDS * AddCommand( char * ); /* Add new #command to an array */
  72. static COMMANDS * AddTranslate( char * ); /* Add new #translate to an array */
  73. static DEFINES * DefSearch( char *, BOOL * );
  74. static COMMANDS * ComSearch( char *, COMMANDS * );
  75. static COMMANDS * TraSearch( char *, COMMANDS * );
  76. static int ParseUndef( char * ); /* Process #undef directive */
  77. static int ParseIfdef( char *, int ); /* Process #ifdef directive */
  78. static void ParseCommand( char *, BOOL, BOOL ); /* Process #command or #translate directive */
  79. static void ConvertPatterns( char *, int, char *, int ); /* Converting result pattern in #command and #translate */
  80. static int WorkDefine( char **, char *, DEFINES * ); /* Replace fragment of code with a #defined result text */
  81. static int WorkPseudoF( char **, char *, DEFINES * ); /* Replace pseudofunction with a #defined result text */
  82. static int WorkCommand( char *, char *, COMMANDS * );
  83. static int WorkTranslate( char *, char *, COMMANDS *, int * );
  84. static int CommandStuff( char *, char *, char *, int *, BOOL, BOOL );
  85. static int RemoveSlash( char * );
  86. static int WorkMarkers( char **, char **, char *, int *, BOOL );
  87. static int getExpReal( char *, char **, BOOL, int, BOOL );
  88. static BOOL isExpres( char * );
  89. static BOOL TestOptional( char *, char * );
  90. static BOOL CheckOptional( char *, char *, char *, int *, BOOL, BOOL );
  91. static void SkipOptional( char ** );
  92. static void SearnRep( char *, char *, int, char *, int * );
  93. static int ReplacePattern( char, char *, int, char *, int );
  94. static void pp_rQuotes( char *, char * );
  95. static int md_strAt( char *, int, char *, BOOL, BOOL, BOOL );
  96. static char * PrevSquare( char * , char *, int * );
  97. static int IsInStr( char, char * );
  98. static int stroncpy( char *, char *, int );
  99. static int strincpy( char *, char * );
  100. static BOOL truncmp( char **, char **, BOOL );
  101. static BOOL strincmp( char *, char **, BOOL );
  102. static int strotrim( char * );
  103. static int NextWord( char **, char *, BOOL );
  104. static int NextName( char **, char * );
  105. static int NextParm( char **, char * );
  106. static BOOL OpenInclude( char *, PATHNAMES *, PHB_FNAME, BOOL bStandardOnly, char * );
  107. void CloseInclude( void );
  108. #define ISNAME( c ) ( isalnum( ( int ) c ) || ( c ) == '_' || ( c ) > 0x7E )
  109. #define MAX_NAME 255
  110. #define MAX_EXP 2048
  111. #define PATTERN_SIZE 2048
  112. #define STATE_INIT 0
  113. #define STATE_NORMAL 1
  114. #define STATE_COMMENT 2
  115. #define STATE_QUOTE1 3
  116. #define STATE_QUOTE2 4
  117. #define STATE_QUOTE3 5
  118. #define STATE_ID_END 6
  119. #define STATE_ID 7
  120. #define STATE_EXPRES 8
  121. #define STATE_EXPRES_ID 9
  122. #define STATE_BRACKET 10
  123. #define IT_EXPR 1
  124. #define IT_ID 2
  125. #define IT_COMMA 3
  126. #define IT_ID_OR_EXPR 4
  127. #define HB_PP_MAX_INCLUDES FOPEN_MAX - 5 - 1
  128. static int s_kolAddDefs = 0;
  129. static int s_kolAddComs = 0;
  130. static int s_kolAddTras = 0;
  131. static int s_ParseState;
  132. static int s_maxCondCompile;
  133. static int s_aIsRepeate[ 5 ];
  134. static int s_Repeate;
  135. static BOOL s_bReplacePat;
  136. static int s_numBrackets;
  137. static char s_groupchar;
  138. static char s_prevchar;
  139. int * hb_pp_aCondCompile = NULL;
  140. int hb_pp_nCondCompile = 0;
  141. char * hb_pp_STD_CH = NULL;
  142. /* Ron Pinkas added 2000-11-21 */
  143. static BOOL s_bArray = FALSE;
  144. /* Table with parse errors */
  145. char * hb_pp_szErrors[] =
  146. {
  147. "Can\'t open #include file: \'%s\'; %s",
  148. "#else does not match #ifdef",
  149. "#endif does not match #ifdef",
  150. "Bad filename in #include",
  151. "#define without parameters",
  152. "Missing => in #translate/#command \'%s\' [%s]'",
  153. "Error in pattern definition",
  154. "Cycled #define",
  155. "Invalid name follows #: \'%s\'",
  156. "#error: \'%s\'",
  157. "Memory allocation error",
  158. "Memory reallocation error",
  159. "Freeing a NULL memory pointer",
  160. "Value out of range in #pragma directive",
  161. "Can\'t open command definitions file: \'%s\'",
  162. "Invalid command definitions file name: \'%s\'",
  163. "Too many nested #includes, can\'t open: \'%s\'",
  164. "Input buffer overflow"
  165. };
  166. /* Table with warnings */
  167. char * hb_pp_szWarnings[] =
  168. {
  169. "1Redefinition or duplicate definition of #define %s",
  170. "1No directives in command definitions file"
  171. };
  172. void hb_pp_SetRules( HB_INCLUDE_FUNC_PTR hb_compInclude, BOOL hb_comp_bQuiet )
  173. {
  174. HB_TRACE(HB_TR_DEBUG, ("hb_pp_SetRules()"));
  175. if( hb_pp_STD_CH )
  176. {
  177. if( *hb_pp_STD_CH > ' ' )
  178. {
  179. hb_comp_pFileName = hb_fsFNameSplit( hb_pp_STD_CH );
  180. if( hb_comp_pFileName->szName )
  181. {
  182. char szFileName[ _POSIX_PATH_MAX ];
  183. if( ! hb_comp_pFileName->szExtension )
  184. hb_comp_pFileName->szExtension = ".ch";
  185. hb_fsFNameMerge( szFileName, hb_comp_pFileName );
  186. if( (* hb_compInclude)( szFileName, hb_comp_pIncludePath ) )
  187. {
  188. /*
  189. printf( "Loading Standard Rules from: \'%s\'\n", szFileName );
  190. */
  191. hb_pp_Init();
  192. hb_pp_ReadRules();
  193. /*
  194. {
  195. COMMANDS * stcmd;
  196. DEFINES * stdef;
  197. stcmd = hb_pp_topCommand;
  198. while ( stcmd )
  199. {
  200. printf( "Command: %s Pattern: %s\n", stcmd->name, stcmd->mpatt );
  201. stcmd = stcmd->last;
  202. }
  203. stcmd = hb_pp_topTranslate;
  204. while ( stcmd )
  205. {
  206. printf( "Translate: %s \nPattern: %s\n", stcmd->name, stcmd->mpatt );
  207. stcmd = stcmd->last;
  208. }
  209. stdef = hb_pp_topDefine;
  210. while ( stdef && s_kolAddDefs > 3 )
  211. {
  212. printf( "Define: %s Value: %s\n", stdef->name, stdef->value );
  213. stdef = stdef->last;
  214. s_kolAddDefs--;
  215. }
  216. }
  217. */
  218. if ( s_kolAddComs || s_kolAddTras || s_kolAddDefs > 3 )
  219. {
  220. if( ! hb_comp_bQuiet )
  221. printf( "Loaded: %i Commands, %i Translates, %i Defines from: %s\n", s_kolAddComs, s_kolAddTras, s_kolAddDefs - 3, szFileName );
  222. }
  223. else
  224. {
  225. hb_compGenWarning( hb_pp_szWarnings, 'I', HB_PP_WARN_NO_DIRECTIVES, NULL /*szFileName*/, NULL );
  226. }
  227. fclose( hb_comp_files.pLast->handle );
  228. hb_xfree( hb_comp_files.pLast->pBuffer );
  229. hb_xfree( hb_comp_files.pLast );
  230. hb_comp_files.pLast = NULL;
  231. hb_comp_files.iFiles = 0;
  232. hb_xfree( ( void * ) hb_comp_pFileName );
  233. hb_comp_pFileName = NULL;
  234. s_kolAddComs = 0;
  235. s_kolAddTras = 0;
  236. s_kolAddDefs = 0;
  237. }
  238. else
  239. {
  240. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_CANNOT_OPEN_RULES, szFileName, NULL );
  241. }
  242. }
  243. else
  244. {
  245. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_BAD_RULES_FILE_NAME, hb_pp_STD_CH, NULL );
  246. }
  247. }
  248. else
  249. {
  250. if( ! hb_comp_bQuiet )
  251. printf( "Standard command definitions excluded.\n" );
  252. hb_pp_Init();
  253. }
  254. }
  255. else
  256. {
  257. hb_pp_Table();
  258. hb_pp_Init();
  259. }
  260. }
  261. void hb_pp_Init( void )
  262. {
  263. DEFINES * stdef;
  264. COMMANDS * stcmd;
  265. HB_TRACE(HB_TR_DEBUG, ("hb_pp_Init()"));
  266. while( s_kolAddDefs )
  267. {
  268. stdef = hb_pp_topDefine;
  269. if( stdef->pars ) hb_xfree( stdef->pars );
  270. if( stdef->value ) hb_xfree( stdef->value );
  271. if( stdef->name ) hb_xfree( stdef->name );
  272. hb_pp_topDefine = stdef->last;
  273. hb_xfree( stdef );
  274. s_kolAddDefs--;
  275. }
  276. while( s_kolAddComs )
  277. {
  278. stcmd = hb_pp_topCommand;
  279. if( stcmd->mpatt ) hb_xfree( stcmd->mpatt );
  280. if( stcmd->value ) hb_xfree( stcmd->value );
  281. hb_xfree( stcmd->name );
  282. hb_pp_topCommand = stcmd->last;
  283. hb_xfree( stcmd );
  284. s_kolAddComs--;
  285. }
  286. while( s_kolAddTras )
  287. {
  288. stcmd = hb_pp_topTranslate;
  289. if( stcmd->mpatt ) hb_xfree( stcmd->mpatt );
  290. if( stcmd->value ) hb_xfree( stcmd->value );
  291. hb_xfree( stcmd->name );
  292. hb_pp_topTranslate = stcmd->last;
  293. hb_xfree( stcmd );
  294. s_kolAddTras--;
  295. }
  296. s_ParseState = 0;
  297. s_maxCondCompile = 5;
  298. s_bReplacePat = TRUE;
  299. s_prevchar = 'A';
  300. if( !hb_pp_aCondCompile )
  301. hb_pp_aCondCompile = ( int * ) hb_xgrab( sizeof( int ) * 5 );
  302. hb_pp_nCondCompile = 0;
  303. {
  304. char szResult[ 6 ];
  305. USHORT usHarbour = ( 256 * HB_VER_MAJOR ) + HB_VER_MINOR;
  306. /*
  307. This updates __HARBOUR__ on every change of HB_VER_MAJOR / HB_VER_MINOR
  308. HIBYTE is the HB_VER_MAJOR value and the LOBYTE is the HB_VER_MINOR value.
  309. The check below is to ensure that __HARBOUR__ gets the
  310. value of 1 by default
  311. */
  312. sprintf( szResult, "%05d", ( usHarbour ? usHarbour : 1 ) );
  313. hb_pp_AddDefine( "__HARBOUR__", szResult );
  314. }
  315. {
  316. char szResult[ 11 ];
  317. time_t t;
  318. struct tm * oTime;
  319. time( &t );
  320. oTime = localtime( &t );
  321. sprintf( szResult, "\"%04d%02d%02d\"", oTime->tm_year + 1900, oTime->tm_mon + 1, oTime->tm_mday );
  322. hb_pp_AddDefine( "__DATE__", szResult );
  323. sprintf( szResult, "\"%02d:%02d:%02d\"", oTime->tm_hour, oTime->tm_min, oTime->tm_sec );
  324. hb_pp_AddDefine( "__TIME__", szResult );
  325. }
  326. #ifdef HARBOUR_START_PROCEDURE
  327. hb_pp_AddDefine( "__HB_MAIN__", HARBOUR_START_PROCEDURE );
  328. #endif
  329. }
  330. /* Table with parse warnings */
  331. /* NOTE: The first character stores the warning's level that triggers this
  332. * warning. The warning's level is set by -w<n> command line option.
  333. */
  334. int hb_pp_ParseDirective( char * sLine )
  335. {
  336. char sDirective[ MAX_NAME ];
  337. char szInclude[ _POSIX_PATH_MAX ];
  338. int i;
  339. HB_TRACE(HB_TR_DEBUG, ("hb_pp_ParseDirective(%s)", sLine));
  340. i = NextName( &sLine, sDirective );
  341. hb_strupr( sDirective );
  342. HB_SKIPTABSPACES(sLine);
  343. if( i == 4 && memcmp( sDirective, "ELSE", 4 ) == 0 )
  344. { /* --- #else --- */
  345. if( hb_pp_nCondCompile == 0 )
  346. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_DIRECTIVE_ELSE, NULL, NULL );
  347. else if( hb_pp_nCondCompile == 1 || hb_pp_aCondCompile[hb_pp_nCondCompile-2] )
  348. hb_pp_aCondCompile[hb_pp_nCondCompile-1] = 1 - hb_pp_aCondCompile[hb_pp_nCondCompile-1];
  349. }
  350. else if( i >= 4 && i <= 5 && memcmp( sDirective, "ENDIF", i ) == 0 )
  351. { /* --- #endif --- */
  352. if( hb_pp_nCondCompile == 0 )
  353. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_DIRECTIVE_ENDIF, NULL, NULL );
  354. else hb_pp_nCondCompile--;
  355. }
  356. else if( i >= 4 && i <= 5 && memcmp( sDirective, "IFDEF", i ) == 0 )
  357. ParseIfdef( sLine, TRUE ); /* --- #ifdef --- */
  358. else if( i >= 4 && i <= 6 && memcmp( sDirective, "IFNDEF", i ) == 0 )
  359. ParseIfdef( sLine, FALSE ); /* --- #ifndef --- */
  360. else if( hb_pp_nCondCompile==0 || hb_pp_aCondCompile[hb_pp_nCondCompile-1])
  361. {
  362. if( i >= 4 && i <= 7 && memcmp( sDirective, "INCLUDE", i ) == 0 )
  363. { /* --- #include --- */
  364. char cDelimChar;
  365. if( *sLine != '\"' && *sLine != '\'' && *sLine != '<' )
  366. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_WRONG_NAME, NULL, NULL );
  367. cDelimChar = *sLine;
  368. if( cDelimChar == '<' )
  369. cDelimChar = '>';
  370. else if( cDelimChar == '`' )
  371. cDelimChar = '\'';
  372. sLine++; i = 0;
  373. while( *(sLine+i) != '\0' && *(sLine+i) != cDelimChar ) i++;
  374. if( *(sLine+i) != cDelimChar )
  375. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_WRONG_NAME, NULL, NULL );
  376. *(sLine+i) = '\0';
  377. if( !OpenInclude( sLine, hb_comp_pIncludePath, hb_comp_pFileName, ( cDelimChar == '>' ), szInclude ) )
  378. {
  379. if( errno == 0 || errno == EMFILE )
  380. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_TOO_MANY_INCLUDES, sLine, NULL );
  381. else
  382. {
  383. #if defined(__CYGWIN__) || defined(__IBMCPP__)
  384. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_CANNOT_OPEN, sLine, "" );
  385. #else
  386. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_CANNOT_OPEN, sLine, sys_errlist[ errno ] );
  387. #endif
  388. }
  389. }
  390. }
  391. else if( i >= 4 && i <= 6 && memcmp( sDirective, "DEFINE", i ) == 0 )
  392. hb_pp_ParseDefine( sLine ); /* --- #define --- */
  393. else if( i >= 4 && i <= 5 && memcmp( sDirective, "UNDEF", i ) == 0 )
  394. ParseUndef( sLine ); /* --- #undef --- */
  395. else if( (i >= 4 && i <= 7 && memcmp( sDirective, "COMMAND", i ) == 0) ||
  396. (i >= 4 && i <= 8 && memcmp( sDirective, "XCOMMAND", i ) == 0) )
  397. /* --- #command --- */
  398. ParseCommand( sLine, (i==7)? FALSE:TRUE, TRUE );
  399. else if( (i >= 4 && i <= 9 && memcmp( sDirective, "TRANSLATE", i ) == 0) ||
  400. (i >= 4 && i <= 10 && memcmp( sDirective, "XTRANSLATE", i ) == 0) )
  401. /* --- #translate --- */
  402. ParseCommand( sLine, (i==9)? FALSE:TRUE, FALSE );
  403. else if( i >= 4 && i <= 6 && memcmp( sDirective, "STDOUT", i ) == 0 )
  404. printf( "%s\n", sLine ); /* --- #stdout --- */
  405. else if( i >= 4 && i <= 5 && memcmp( sDirective, "ERROR", i ) == 0 )
  406. /* --- #error --- */
  407. hb_compGenError( hb_pp_szErrors, 'E', HB_PP_ERR_EXPLICIT, sLine, NULL );
  408. else if( i == 4 && memcmp( sDirective, "LINE", 4 ) == 0 )
  409. return -1;
  410. else if( i == 6 && memcmp( sDirective, "PRAGMA", 6 ) == 0 )
  411. hb_pp_ParsePragma( sLine ); /* --- #pragma --- */
  412. else
  413. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_WRONG_DIRECTIVE, sDirective, NULL );
  414. }
  415. return 0;
  416. }
  417. int hb_pp_ParseDefine( char * sLine )
  418. {
  419. char defname[ MAX_NAME ], pars[ MAX_NAME ];
  420. int i, npars = -1;
  421. DEFINES * lastdef;
  422. HB_TRACE(HB_TR_DEBUG, ("hb_pp_ParseDefine(%s)", sLine));
  423. HB_SKIPTABSPACES( sLine );
  424. if( ISNAME( *sLine ) )
  425. {
  426. NextName( &sLine, defname );
  427. if( *sLine == '(' ) /* If pseudofunction was found */
  428. {
  429. sLine++; i = 0;
  430. npars = 0;
  431. while( *sLine != '\0' && *sLine != ')')
  432. {
  433. if( *sLine == ',' ) npars++;
  434. if( *sLine != ' ' && *sLine != '\t' ) *(pars+i++) = *sLine;
  435. sLine++;
  436. }
  437. if( i > 0 ) npars++;
  438. *(pars+i) = '\0';
  439. sLine++;
  440. }
  441. HB_SKIPTABSPACES(sLine);
  442. lastdef = hb_pp_AddDefine( defname, ( *sLine == '\0' ) ? NULL : sLine );
  443. lastdef->npars = npars;
  444. lastdef->pars = ( npars <= 0 ) ? NULL : hb_strdup( pars );
  445. }
  446. else
  447. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_DEFINE_ABSENT, NULL, NULL );
  448. return 0;
  449. }
  450. DEFINES * hb_pp_AddDefine( char * defname, char * value )
  451. {
  452. BOOL isNew;
  453. DEFINES * stdef;
  454. HB_TRACE(HB_TR_DEBUG, ("hb_pp_AddDefine(%s, %s)", defname, value));
  455. stdef = DefSearch( defname, &isNew );
  456. if( stdef != NULL )
  457. {
  458. hb_compGenWarning( hb_pp_szWarnings, 'I', HB_PP_WARN_DEFINE_REDEF, defname, NULL );
  459. if( isNew )
  460. {
  461. if( stdef->pars ) hb_xfree( stdef->pars );
  462. if( stdef->value ) hb_xfree( stdef->value );
  463. }
  464. }
  465. else
  466. {
  467. stdef = ( DEFINES * ) hb_xgrab( sizeof( DEFINES ) );
  468. stdef->last = hb_pp_topDefine;
  469. hb_pp_topDefine = stdef;
  470. stdef->name = hb_strdup( defname );
  471. stdef->npars = -1;
  472. s_kolAddDefs++;
  473. }
  474. stdef->value = ( value == NULL ) ? NULL : hb_strdup( value );
  475. stdef->pars = NULL;
  476. return stdef;
  477. }
  478. static int ParseUndef( char * sLine )
  479. {
  480. char defname[ MAX_NAME ];
  481. DEFINES * stdef;
  482. BOOL isNew;
  483. HB_TRACE(HB_TR_DEBUG, ("ParseUndef(%s)", sLine));
  484. NextWord( &sLine, defname, FALSE );
  485. if( ( stdef = DefSearch(defname, &isNew ) ) != NULL )
  486. {
  487. if( isNew )
  488. {
  489. if( stdef->pars ) hb_xfree( stdef->pars );
  490. if( stdef->value ) hb_xfree( stdef->value );
  491. hb_xfree( stdef->name );
  492. }
  493. stdef->pars = NULL;
  494. stdef->value = NULL;
  495. stdef->name = NULL;
  496. }
  497. return 0;
  498. }
  499. static int ParseIfdef( char * sLine, int usl )
  500. {
  501. char defname[ MAX_NAME ];
  502. DEFINES * stdef;
  503. HB_TRACE(HB_TR_DEBUG, ("ParseIfdef(%s, %d)", sLine, usl));
  504. if( hb_pp_nCondCompile==0 || hb_pp_aCondCompile[hb_pp_nCondCompile-1])
  505. {
  506. NextWord( &sLine, defname, FALSE );
  507. if( *defname == '\0' )
  508. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_DEFINE_ABSENT, NULL, NULL );
  509. }
  510. if( hb_pp_nCondCompile == s_maxCondCompile )
  511. {
  512. s_maxCondCompile += 5;
  513. hb_pp_aCondCompile = (int*)hb_xrealloc( hb_pp_aCondCompile, sizeof( int ) * s_maxCondCompile );
  514. }
  515. if( hb_pp_nCondCompile==0 || hb_pp_aCondCompile[hb_pp_nCondCompile-1])
  516. {
  517. if( ( (stdef = DefSearch(defname,NULL)) != NULL && usl )
  518. || ( stdef == NULL && !usl ) ) hb_pp_aCondCompile[hb_pp_nCondCompile] = 1;
  519. else hb_pp_aCondCompile[hb_pp_nCondCompile] = 0;
  520. }
  521. else
  522. hb_pp_aCondCompile[ hb_pp_nCondCompile ] = 0;
  523. hb_pp_nCondCompile++;
  524. return 0;
  525. }
  526. static DEFINES * DefSearch( char * defname, BOOL * isNew )
  527. {
  528. int kol = 0,j;
  529. DEFINES * stdef = hb_pp_topDefine;
  530. HB_TRACE(HB_TR_DEBUG, ("DefSearch(%s)", defname));
  531. while( stdef != NULL )
  532. {
  533. kol++;
  534. if( stdef->name != NULL )
  535. {
  536. for( j=0; *(stdef->name+j) == *(defname+j) &&
  537. *(stdef->name+j) != '\0'; j++ );
  538. if( *(stdef->name+j) == *(defname+j) )
  539. {
  540. if( isNew ) *isNew = ( s_kolAddDefs >= kol );
  541. return stdef;
  542. }
  543. }
  544. stdef = stdef->last;
  545. }
  546. return NULL;
  547. }
  548. static COMMANDS * ComSearch( char * cmdname, COMMANDS * stcmdStart )
  549. {
  550. COMMANDS * stcmd = ( stcmdStart ) ? stcmdStart : hb_pp_topCommand;
  551. HB_TRACE(HB_TR_DEBUG, ("ComSearch(%s, %p)", cmdname, stcmdStart));
  552. while( stcmd != NULL )
  553. {
  554. int j;
  555. for( j=0; (*(stcmd->name+j)==toupper(*(cmdname+j))) &&
  556. (*(stcmd->name+j)!='\0') &&
  557. ((stcmd->com_or_xcom)? 1:(j<4 || ISNAME(*(cmdname+j+1)))); j++ );
  558. if( (*(stcmd->name+j)==toupper(*(cmdname+j))) ||
  559. ( !stcmd->com_or_xcom && j >= 4 && *(stcmd->name+j)!='\0'
  560. && *(cmdname+j) == '\0' ) )
  561. break;
  562. stcmd = stcmd->last;
  563. }
  564. return stcmd;
  565. }
  566. static COMMANDS * TraSearch( char * cmdname, COMMANDS * sttraStart )
  567. {
  568. int j;
  569. COMMANDS *sttra = ( sttraStart ) ? sttraStart : hb_pp_topTranslate;
  570. HB_TRACE(HB_TR_DEBUG, ("TraSearch(%s, %p)", cmdname, sttraStart));
  571. while( sttra != NULL )
  572. {
  573. for( j=0; *(sttra->name+j)==toupper(*(cmdname+j)) &&
  574. *(sttra->name+j)!='\0' &&
  575. ((sttra->com_or_xcom)? 1:(j<4 || ISNAME(*(cmdname+j+1)))); j++ );
  576. if( *(sttra->name+j)==toupper(*(cmdname+j)) ||
  577. ( !sttra->com_or_xcom && j >= 4 &&
  578. *(sttra->name+j)!='\0' && *(cmdname+j) == '\0' ) )
  579. break;
  580. sttra = sttra->last;
  581. }
  582. return sttra;
  583. }
  584. static void ParseCommand( char * sLine, BOOL com_or_xcom, BOOL com_or_tra )
  585. {
  586. static char mpatt[ PATTERN_SIZE ];
  587. static char rpatt[ PATTERN_SIZE ];
  588. char cmdname[ MAX_NAME ];
  589. COMMANDS * stcmd;
  590. int mlen,rlen;
  591. int ipos;
  592. /* Ron Pinkas added 2000-12-03 */
  593. BOOL bOk = FALSE;
  594. HB_TRACE(HB_TR_DEBUG, ("ParseCommand(%s, %d, %d)", sLine, com_or_xcom, com_or_tra));
  595. HB_SKIPTABSPACES( sLine );
  596. ipos = 0;
  597. /* JFL 2000-09-19 */
  598. /* This was the original line as Alexander wrote it */
  599. /* while( *sLine != '\0' && *sLine != ' ' && *sLine != '\t' && *sLine != '<' && *sLine != '=' && ( *sLine != '(' || ipos == 0 ) ) */
  600. /* Now the line #xtranslate = name(.. => will be allowed */
  601. /* I changed it to the following to allow < and = to be the first char within a translate or xtranslate */
  602. while( *sLine != '\0' && *sLine != ' ' && *sLine != '\t' && ( *sLine != '<' || ipos == 0 ) && ( *sLine != '=' || ipos == 0 ) && ( *sLine != '(' || ipos == 0 ) )
  603. {
  604. *(cmdname+ipos++) = *sLine++;
  605. }
  606. *(cmdname+ipos) = '\0';
  607. if( !ipos ) return;
  608. hb_strupr( cmdname );
  609. HB_SKIPTABSPACES(sLine);
  610. /* Ron Pinkas added 2000-12-03 */
  611. ipos = 0;
  612. while( *sLine )
  613. {
  614. mpatt[ipos++] = *sLine;
  615. if( *sLine == '=' )
  616. {
  617. int i = ipos;
  618. sLine++;
  619. mpatt[i++] = *sLine;
  620. while( *sLine && ( *sLine == ' ' || *sLine == '\t' ) )
  621. {
  622. sLine++;
  623. mpatt[i++] = *sLine;
  624. }
  625. if( *sLine == '>' )
  626. {
  627. ipos = ipos - 2;
  628. while( mpatt[ipos] == ' ' || mpatt[ipos] == '\t' )
  629. {
  630. ipos--;
  631. }
  632. mpatt[ipos + 1] = '\0';
  633. sLine++;
  634. bOk = TRUE;
  635. break;
  636. }
  637. ipos = i;
  638. }
  639. sLine++;
  640. }
  641. /* End - Ron Pinkas added 2000-12-03 */
  642. /* Ron Pinkas modified 2000-12-03
  643. if( (ipos = hb_strAt( "=>", 2, sLine, strlen(sLine) )) > 0 ) */
  644. if( bOk )
  645. {
  646. /* Ron Pinkas removed 2000-12-03
  647. stroncpy( mpatt, sLine, ipos-1 ); */
  648. RemoveSlash( mpatt );
  649. mlen = strotrim( mpatt );
  650. /* Ron Pinkas removed 2000-12-03
  651. sLine += ipos + 1; */
  652. HB_SKIPTABSPACES(sLine);
  653. hb_pp_strocpy( rpatt, sLine );
  654. rlen = strotrim( rpatt );
  655. ConvertPatterns( mpatt, mlen, rpatt, rlen );
  656. if( com_or_tra )
  657. stcmd = AddCommand( cmdname );
  658. else
  659. stcmd = AddTranslate( cmdname );
  660. stcmd->com_or_xcom = com_or_xcom;
  661. stcmd->mpatt = hb_strdup( mpatt );
  662. stcmd->value = ( rlen > 0 ) ? hb_strdup( rpatt ) : NULL;
  663. /* JFL */
  664. /*
  665. printf( "Parsecommand Name: %s Pat: %s Val: %s\n", stcmd->name, stcmd->mpatt, stcmd->value );
  666. */
  667. }
  668. else
  669. {
  670. sLine -= ( ipos + 1 );
  671. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_COMMAND_DEFINITION, cmdname, sLine );
  672. }
  673. }
  674. /* ConvertPatterns()
  675. * Converts result pattern in #command and #translate to inner format
  676. */
  677. static void ConvertPatterns( char * mpatt, int mlen, char * rpatt, int rlen )
  678. {
  679. int i = 0, ipos, ifou;
  680. int explen, rmlen;
  681. char exppatt[ MAX_NAME ], expreal[ 5 ] = "\1 0";
  682. char lastchar = '@', exptype;
  683. char * ptr;
  684. HB_TRACE(HB_TR_DEBUG, ("ConvertPatterns(%s, %d, %s, %d)", mpatt, mlen, rpatt, rlen));
  685. while( *(mpatt+i) != '\0' )
  686. {
  687. if( *(mpatt+i) == '<' )
  688. { /* Drag match marker, determine it type */
  689. explen = 0; ipos = i; i++; exptype = '0';
  690. while( *(mpatt+i) == ' ' || *(mpatt+i) == '\t' ) i++;
  691. if( *(mpatt+i) == '*' ) /* Wild match marker */
  692. { exptype = '3'; i++; }
  693. else if( *(mpatt+i) == '(' ) /* Extended expression match marker */
  694. { exptype = '4'; i++; }
  695. while( *(mpatt+i) != '>' )
  696. {
  697. if( *(mpatt+i) == ',' ) /* List match marker */
  698. {
  699. exptype = '1';
  700. while( *(mpatt+i) != '>' ) i++;
  701. break;
  702. }
  703. else if( *(mpatt+i) == ':' ) /* Restricted match marker */
  704. {
  705. exptype = '2';
  706. *(mpatt+i--) = ' ';
  707. break;
  708. }
  709. if( *(mpatt+i) != ' ' && *(mpatt+i) != '\t' )
  710. *(exppatt+explen++) = *(mpatt+i);
  711. i++;
  712. }
  713. if( exptype == '3' )
  714. {
  715. if( *(exppatt+explen-1) == '*' ) explen--;
  716. else
  717. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_PATTERN_DEFINITION, NULL, NULL );
  718. }
  719. else if( exptype == '4' )
  720. {
  721. if( *(exppatt+explen-1) == ')' ) explen--;
  722. else
  723. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_PATTERN_DEFINITION, NULL, NULL );
  724. }
  725. rmlen = i - ipos + 1;
  726. /* Convert match marker into inner format */
  727. lastchar = (lastchar!='Z') ? ( (char) ( (unsigned int)lastchar + 1 ) ):
  728. 'a';
  729. expreal[1] = lastchar;
  730. expreal[2] = exptype;
  731. hb_pp_Stuff( expreal, mpatt+ipos, 4, rmlen, mlen );
  732. mlen += 4 - rmlen;
  733. i += 4 - rmlen;
  734. /* Look for appropriate result markers */
  735. ptr = rpatt;
  736. while( (ifou = hb_strAt( exppatt, explen, ptr, rlen-(ptr-rpatt) )) > 0 )
  737. {
  738. /* Convert result marker into inner format */
  739. ptr += ifou;
  740. if( *(ptr-2) == '<' && *(ptr+explen-1) == '>' &&
  741. *(ptr-3) != '\\' && *(ptr+explen-2) != '\\' ) /* <...> */
  742. {
  743. if( *(ptr-3) == '#' && *(ptr-4) != '\\' ) /* #<...> */
  744. { exptype = '1'; ptr -= 3; rmlen = explen+3; }
  745. else
  746. { exptype = '0'; ptr -= 2; rmlen = explen+2; }
  747. }
  748. else if( *(ptr-3) == '<' && *(ptr+explen) == '>' &&
  749. *(ptr-4) != '\\' && *(ptr+explen-1) != '\\' ) /* < ... > */
  750. {
  751. ptr -= 2;
  752. if( *ptr == '\"' ) exptype = '2';
  753. else if( *ptr == '(' ) exptype = '3';
  754. else if( *ptr == '{' ) exptype = '4';
  755. else if( *ptr == '.' ) exptype = '5';
  756. else if( *ptr == '-' ) exptype = '6';
  757. ptr--;
  758. rmlen = explen+4;
  759. }
  760. else continue;
  761. expreal[2] = exptype;
  762. hb_pp_Stuff( expreal, ptr, 4, rmlen, rlen );
  763. rlen += 4 - rmlen;
  764. }
  765. }
  766. i++;
  767. }
  768. }
  769. static COMMANDS * AddCommand( char * cmdname )
  770. {
  771. COMMANDS * stcmd;
  772. HB_TRACE(HB_TR_DEBUG, ("AddCommand(%s)", cmdname));
  773. stcmd = ( COMMANDS * ) hb_xgrab( sizeof( COMMANDS ) );
  774. stcmd->last = hb_pp_topCommand;
  775. hb_pp_topCommand = stcmd;
  776. stcmd->name = hb_strdup( cmdname );
  777. s_kolAddComs++;
  778. return stcmd;
  779. }
  780. static COMMANDS* AddTranslate( char * traname )
  781. {
  782. COMMANDS * sttra;
  783. HB_TRACE(HB_TR_DEBUG, ("AddTranslate(%s)", traname));
  784. sttra = ( COMMANDS * ) hb_xgrab( sizeof( COMMANDS ) );
  785. sttra->last = hb_pp_topTranslate;
  786. hb_pp_topTranslate = sttra;
  787. sttra->name = hb_strdup( traname );
  788. return sttra;
  789. }
  790. int hb_pp_ParseExpression( char * sLine, char * sOutLine )
  791. {
  792. char sToken[MAX_NAME];
  793. char * ptri, * ptro, * ptrb;
  794. int lenToken, i, ipos, isdvig, lens;
  795. int ifou;
  796. int rezDef, rezTra, rezCom, kolpass = 0;
  797. DEFINES * stdef;
  798. COMMANDS * stcmd;
  799. HB_TRACE(HB_TR_DEBUG, ("hb_pp_ParseExpression(%s, %s)", sLine, sOutLine));
  800. do
  801. {
  802. strotrim( sLine );
  803. rezDef = 0; rezTra = 0; rezCom = 0;
  804. isdvig = 0;
  805. do
  806. {
  807. ptro = sOutLine;
  808. ptri = sLine + isdvig;
  809. ipos = md_strAt( ";", 1, ptri, TRUE, FALSE, FALSE );
  810. if( ipos > 0 )
  811. {
  812. *(ptri+ipos-1) = '\0';
  813. }
  814. HB_SKIPTABSPACES( ptri );
  815. if( *ptri == '#' )
  816. {
  817. hb_pp_ParseDirective( ptri+1 );
  818. if( ipos > 0 )
  819. {
  820. *( sLine + isdvig + ipos - 1 ) = ';';
  821. }
  822. lens = strlen( sLine + isdvig );
  823. hb_pp_Stuff( " ", sLine + isdvig, 0, (ipos)? ipos:lens, lens );
  824. if( ipos > 0 )
  825. {
  826. ipos = 1;
  827. }
  828. }
  829. else
  830. { /* Look for macros from #define */
  831. while( ( lenToken = NextName( &ptri, sToken ) ) > 0 )
  832. {
  833. if( (stdef=DefSearch(sToken,NULL)) != NULL )
  834. {
  835. ptrb = ptri - lenToken;
  836. if( ( i = WorkDefine( &ptri, ptro, stdef ) ) >= 0 )
  837. {
  838. rezDef++;
  839. lens = strlen( ptrb );
  840. if( ipos > 0 )
  841. {
  842. *(ptrb+lens) = ';';
  843. lens += strlen( ptrb+lens+1 );
  844. }
  845. hb_pp_Stuff( ptro, ptrb, i, ptri-ptrb, lens+1 );
  846. if( ipos > 0 )
  847. {
  848. ipos += i - (ptri-ptrb);
  849. *(sLine + isdvig + ipos - 1) = '\0';
  850. }
  851. ptri += i - (ptri-ptrb);
  852. }
  853. }
  854. }
  855. #if 0
  856. printf( "Line: >%s<\n", ptri );
  857. printf( "Out: >%s<\n", ptro );
  858. #endif
  859. /* Look for definitions from #translate */
  860. stcmd = hb_pp_topTranslate;
  861. while( stcmd != NULL )
  862. {
  863. ptri = sLine + isdvig;
  864. lenToken = strlen(stcmd->name);
  865. while( ( ifou = md_strAt( stcmd->name, lenToken, ptri, TRUE, FALSE, FALSE )) > 0 )
  866. {
  867. ptri += ifou -1;
  868. if( ( i = WorkTranslate( ptri+lenToken, ptro, stcmd, &lens ) ) >= 0 )
  869. {
  870. lens += lenToken;
  871. while( lens > 0 && (*(ptri+lens-1)==' ' || *(ptri+lens-1)=='\t') )
  872. {
  873. lens--;
  874. }
  875. if( ipos > 0 )
  876. {
  877. *(sLine+isdvig+ipos-1) = ';';
  878. }
  879. hb_pp_Stuff( ptro, ptri, i, lens, strlen(ptri) );
  880. rezTra = 1;
  881. if( ipos > 0 )
  882. {
  883. ipos += i - lens;
  884. *(sLine+isdvig+ipos-1) = '\0';
  885. }
  886. ptri += i;
  887. }
  888. else
  889. {
  890. ptri += lenToken;
  891. }
  892. }
  893. stcmd = stcmd->last;
  894. }
  895. /* Look for definitions from #command */
  896. /* JFL ! Was 3 but insufficient in most cases */
  897. /* I know this is a new hardcoded limit ... any better idea's welcome */
  898. if( kolpass < 20 )
  899. {
  900. ptri = sLine + isdvig;
  901. HB_SKIPTABSPACES( ptri );
  902. if( ISNAME( *ptri ) )
  903. {
  904. NextName( &ptri, sToken );
  905. }
  906. else
  907. {
  908. i = 0;
  909. while( *ptri != ' ' && *ptri != '\t' && *ptri != '\0' && *ptri != '\"' && *ptri != '\'' && *ptri != '(' && !ISNAME(*ptri) )
  910. {
  911. *(sToken+i) = *ptri++;
  912. i++;
  913. }
  914. *(sToken+i) = '\0';
  915. }
  916. HB_SKIPTABSPACES( ptri );
  917. if( ( *ptri == '\0' || ( *ptri != '=' && (!IsInStr(*ptri,":/+*-%^") || *(ptri+1) != '=') &&
  918. ( *ptri != '-' || *(ptri+1) != '>' ) ) ) && ( stcmd = ComSearch(sToken,NULL) ) != NULL )
  919. {
  920. ptro = sOutLine;
  921. i = WorkCommand( ptri, ptro, stcmd );
  922. ptri = sLine + isdvig;
  923. if( ipos > 0 )
  924. {
  925. *(ptri+ipos-1) = ';';
  926. }
  927. if( i >= 0 )
  928. {
  929. if( isdvig + ipos > 0 )
  930. {
  931. lens = strlen( sLine+isdvig );
  932. hb_pp_Stuff( ptro, sLine+isdvig, i, (ipos)? ipos-1:lens, lens );
  933. if( ipos > 0 )
  934. {
  935. ipos = i + 1;
  936. }
  937. }
  938. else
  939. {
  940. memcpy( sLine, sOutLine, i+1);
  941. }
  942. }
  943. rezCom = 1;
  944. }
  945. else if( ipos > 0 )
  946. {
  947. *(sLine+isdvig+ipos-1) = ';';
  948. }
  949. }
  950. else if( ipos > 0 )
  951. {
  952. *(sLine+isdvig+ipos-1) = ';';
  953. }
  954. }
  955. isdvig += ipos;
  956. }
  957. while( ipos != 0 );
  958. kolpass++;
  959. if( kolpass > 20 && rezDef )
  960. {
  961. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_RECURSE, NULL, NULL );
  962. break;
  963. }
  964. }
  965. while( rezDef || rezTra || rezCom );
  966. return 0;
  967. }
  968. static int WorkDefine( char ** ptri, char * ptro, DEFINES * stdef )
  969. {
  970. int npars, lens;
  971. char * ptr;
  972. HB_TRACE(HB_TR_DEBUG, ("WorkDefine(%p, %s, %p)", ptri, ptro, stdef));
  973. if( stdef->npars < 0 )
  974. {
  975. lens = hb_pp_strocpy( ptro,stdef->value );
  976. }
  977. else
  978. {
  979. HB_SKIPTABSPACES( *ptri );
  980. if( **ptri == '(' )
  981. {
  982. npars = 0; ptr = *ptri;
  983. do
  984. {
  985. ptr++;
  986. if( NextParm( &ptr, NULL ) > 0 )
  987. {
  988. npars++;
  989. }
  990. }
  991. while( *ptr != ')' && *ptr != '\0' );
  992. if( *ptr == ')' && stdef->npars == npars )
  993. {
  994. /* Ron Pinkas added 2000-11-21 */
  995. char *pTmp = ptr + 1;
  996. while( *pTmp && ( *pTmp == ' ' || *pTmp == '\t' ) )
  997. {
  998. pTmp++;
  999. }
  1000. if( *pTmp == '[' )
  1001. {
  1002. s_bArray = TRUE;
  1003. }
  1004. /* END - Ron Pinkas added 2000-11-21 */
  1005. lens = WorkPseudoF( ptri, ptro, stdef );
  1006. }
  1007. else
  1008. {
  1009. return -1;
  1010. }
  1011. }
  1012. else
  1013. {
  1014. return -1;
  1015. }
  1016. }
  1017. return lens;
  1018. }
  1019. static int WorkPseudoF( char ** ptri, char * ptro, DEFINES * stdef )
  1020. {
  1021. char parfict[ MAX_NAME ], * ptrreal;
  1022. char * ptrb;
  1023. int ipos, ifou, ibeg;
  1024. int lenfict, lenreal, lenres;
  1025. HB_TRACE(HB_TR_DEBUG, ("WorkPseudoF(%p, %s, %p)", ptri, ptro, stdef));
  1026. lenres = hb_pp_strocpy( ptro, stdef->value ); /* Copying value of macro to destination string */
  1027. if( stdef->pars )
  1028. {
  1029. ipos = 0; ibeg = 0;
  1030. do /* Parsing through parameters */
  1031. { /* in macro definition */
  1032. if( *(stdef->pars+ipos) == ',' || *(stdef->pars+ipos) == '\0' )
  1033. {
  1034. *(parfict+ipos-ibeg) = '\0';
  1035. lenfict = ipos - ibeg;
  1036. if( **ptri != ')' )
  1037. {
  1038. (*ptri)++; /* Get next real parameter */
  1039. HB_SKIPTABSPACES( *ptri );
  1040. ptrreal = *ptri;
  1041. lenreal = NextParm( ptri, NULL);
  1042. ptrb = ptro;
  1043. while( (ifou = hb_strAt( parfict, lenfict, ptrb, lenres-(ptrb-ptro) )) > 0 )
  1044. {
  1045. ptrb = ptrb+ifou-1;
  1046. if( !ISNAME(*(ptrb-1)) && !ISNAME(*(ptrb+lenfict)) )
  1047. {
  1048. hb_pp_Stuff( ptrreal, ptrb, lenreal, lenfict, lenres );
  1049. lenres += lenreal - lenfict;
  1050. ptrb += lenreal;
  1051. }
  1052. else
  1053. {
  1054. ptrb++;
  1055. }
  1056. }
  1057. ibeg = ipos+1;
  1058. }
  1059. }
  1060. else
  1061. {
  1062. *(parfict+ipos-ibeg) = *(stdef->pars+ipos);
  1063. }
  1064. if( *(stdef->pars+ipos) == '\0' )
  1065. {
  1066. break;
  1067. }
  1068. ipos++;
  1069. }
  1070. while( 1 );
  1071. }
  1072. else
  1073. {
  1074. while( **ptri != ')' )
  1075. {
  1076. (*ptri)++;
  1077. }
  1078. }
  1079. (*ptri)++;
  1080. return lenres;
  1081. }
  1082. static int WorkCommand( char * ptri, char * ptro, COMMANDS * stcmd )
  1083. {
  1084. int rez;
  1085. int lenres;
  1086. char * ptrmp;
  1087. char * sToken = stcmd->name;
  1088. HB_TRACE(HB_TR_DEBUG, ("WorkCommand(%s, %s, %p)", ptri, ptro, stcmd));
  1089. do
  1090. {
  1091. lenres = hb_pp_strocpy( ptro, stcmd->value ); /* Copying result pattern */
  1092. ptrmp = stcmd->mpatt; /* Pointer to a match pattern */
  1093. s_Repeate = 0;
  1094. s_groupchar = '@';
  1095. rez = CommandStuff( ptrmp, ptri, ptro, &lenres, TRUE, stcmd->com_or_xcom );
  1096. stcmd = stcmd->last;
  1097. if( rez < 0 && stcmd != NULL ) stcmd = ComSearch(sToken, stcmd);
  1098. }
  1099. while( rez < 0 && stcmd != NULL );
  1100. *(ptro+lenres) = '\0';
  1101. if( rez >= 0 ) return lenres;
  1102. return -1;
  1103. }
  1104. static int WorkTranslate( char * ptri, char * ptro, COMMANDS * sttra, int * lens )
  1105. {
  1106. int rez;
  1107. int lenres;
  1108. char * ptrmp;
  1109. char * sToken = sttra->name;
  1110. HB_TRACE(HB_TR_DEBUG, ("WorkTranslate(%s, %s, %p, %p)", ptri, ptro, sttra, lens));
  1111. do
  1112. {
  1113. lenres = hb_pp_strocpy( ptro, sttra->value );
  1114. ptrmp = sttra->mpatt;
  1115. s_Repeate = 0;
  1116. s_groupchar = '@';
  1117. rez = CommandStuff( ptrmp, ptri, ptro, &lenres, FALSE, sttra->com_or_xcom );
  1118. sttra = sttra->last;
  1119. if( rez < 0 && sttra != NULL )
  1120. {
  1121. sttra = TraSearch(sToken, sttra);
  1122. }
  1123. }
  1124. while( rez < 0 && sttra != NULL );
  1125. *(ptro+lenres) = '\0';
  1126. if( rez >= 0 )
  1127. {
  1128. *lens = rez;
  1129. return lenres;
  1130. }
  1131. return -1;
  1132. }
  1133. static int CommandStuff( char * ptrmp, char * inputLine, char * ptro, int * lenres, BOOL com_or_tra, BOOL com_or_xcom )
  1134. {
  1135. BOOL endTranslation = FALSE;
  1136. int ipos;
  1137. char * lastopti[ 3 ], * strtopti = NULL, * strtptri = NULL;
  1138. char * ptri = inputLine, * ptr, tmpname[ MAX_NAME ];
  1139. int isWordInside = 0;
  1140. /*
  1141. printf( "MP: >%s<\nIn: >%s<\n", ptrmp, ptri );
  1142. */
  1143. HB_TRACE(HB_TR_DEBUG, ("CommandStuff(%s, %s, %s, %p, %d, %d)", ptrmp, inputLine, ptro, lenres, com_or_tra, com_or_xcom));
  1144. s_numBrackets = 0;
  1145. HB_SKIPTABSPACES( ptri );
  1146. if( ptrmp == NULL ) { if( *ptri != '\0' ) return -1; }
  1147. else
  1148. while( *ptri != '\0' && !endTranslation )
  1149. {
  1150. HB_SKIPTABSPACES( ptrmp );
  1151. if( *ptrmp == '[' && !s_numBrackets && !strtopti )
  1152. strtopti = ptrmp;
  1153. if( !s_numBrackets && strtopti && strtptri != ptri &&
  1154. ( ISNAME( *ptri ) || *ptri=='&' ) )
  1155. {
  1156. strtptri = ptri;
  1157. ptrmp = strtopti;
  1158. ptr = ptri;
  1159. ipos = NextName( &ptr, tmpname );
  1160. ipos = md_strAt( tmpname, ipos, strtopti, TRUE, TRUE, TRUE );
  1161. if( ipos && TestOptional( strtopti, strtopti+ipos-2 ) )
  1162. {
  1163. ptr = strtopti+ipos-2;
  1164. ptr = PrevSquare( ptr, strtopti, NULL );
  1165. if( ptr )
  1166. ptrmp = ptr;
  1167. }
  1168. }
  1169. switch( *ptrmp ) {
  1170. case '[':
  1171. if( !s_numBrackets ) isWordInside = 0;
  1172. s_numBrackets++;
  1173. s_aIsRepeate[ s_Repeate ] = 0;
  1174. lastopti[s_Repeate++] = ptrmp;
  1175. ptrmp++;
  1176. if( !CheckOptional( ptrmp, ptri, ptro, lenres, com_or_tra, com_or_xcom ) )
  1177. SkipOptional( &ptrmp );
  1178. break;
  1179. case ']':
  1180. if( s_Repeate )
  1181. {
  1182. s_Repeate--;
  1183. if( s_aIsRepeate[ s_Repeate ] )
  1184. {
  1185. if( ISNAME(*ptri) )
  1186. {
  1187. ptr = ptri;
  1188. ipos = NextName( &ptr, tmpname );
  1189. ipos = md_strAt( tmpname, ipos, ptrmp, TRUE, TRUE, TRUE );
  1190. if( ipos && TestOptional( ptrmp+1, ptrmp+ipos-2 ) )
  1191. {
  1192. ptr = PrevSquare( ptrmp+ipos-2, ptrmp+1, NULL );
  1193. if( !ptr || CheckOptional( ptrmp+1, ptri, ptro, lenres, com_or_tra, com_or_xcom ) )
  1194. {
  1195. ptrmp = lastopti[s_Repeate];
  1196. ptrmp++;
  1197. s_Repeate++;
  1198. SkipOptional( &ptrmp );
  1199. s_numBrackets++;
  1200. ptrmp++;
  1201. strtptri = ptri;
  1202. }
  1203. else
  1204. ptrmp = lastopti[s_Repeate];
  1205. }
  1206. else
  1207. ptrmp = lastopti[s_Repeate];
  1208. }
  1209. else
  1210. ptrmp = lastopti[s_Repeate];
  1211. }
  1212. else
  1213. {
  1214. if( !isWordInside ) strtopti = NULL;
  1215. ptrmp++;
  1216. }
  1217. s_numBrackets--;
  1218. }
  1219. else
  1220. {
  1221. if( !isWordInside ) strtopti = NULL;
  1222. s_numBrackets--; ptrmp++;
  1223. }
  1224. break;
  1225. case ',':
  1226. if( s_numBrackets == 1 ) isWordInside = 1;
  1227. if( !s_numBrackets ) strtopti = NULL;
  1228. if( *ptri == ',' ) { ptrmp++; ptri++; }
  1229. else
  1230. {
  1231. if( s_numBrackets )
  1232. {
  1233. SkipOptional( &ptrmp );
  1234. }
  1235. else return -1;
  1236. }
  1237. break;
  1238. case '\1': /* Match marker */
  1239. if( !s_numBrackets ) strtopti = NULL;
  1240. if( s_numBrackets == 1 && *(ptrmp+2) == '2' ) isWordInside = 1; /* restricted match marker */
  1241. if( !WorkMarkers( &ptrmp, &ptri, ptro, lenres, com_or_xcom ) )
  1242. {
  1243. if( s_numBrackets )
  1244. {
  1245. SkipOptional( &ptrmp );
  1246. }
  1247. else return -1;
  1248. }
  1249. break;
  1250. case '\0':
  1251. if( com_or_tra )
  1252. return -1;
  1253. else endTranslation = TRUE;
  1254. break;
  1255. default: /* Key word */
  1256. if( s_numBrackets == 1 ) isWordInside = 1;
  1257. if( !s_numBrackets ) strtopti = NULL;
  1258. ptr = ptri;
  1259. if( *ptri == ',' || truncmp( &ptri, &ptrmp, !com_or_xcom ) )
  1260. {
  1261. ptri = ptr;
  1262. if( s_numBrackets )
  1263. {
  1264. SkipOptional( &ptrmp );
  1265. }
  1266. else return -1;
  1267. }
  1268. }
  1269. HB_SKIPTABSPACES( ptri );
  1270. };
  1271. if( *ptrmp != '\0' )
  1272. {
  1273. if( s_Repeate ) { s_Repeate = 0; ptrmp = lastopti[0]; }
  1274. s_numBrackets = 0;
  1275. do
  1276. {
  1277. HB_SKIPTABSPACES( ptrmp );
  1278. if( *ptrmp != '\0' )
  1279. switch( *ptrmp ) {
  1280. case '[':
  1281. ptrmp++;
  1282. SkipOptional( &ptrmp );
  1283. ptrmp++;
  1284. break;
  1285. case ']': ptrmp++; break;
  1286. default:
  1287. return -1;
  1288. }
  1289. }
  1290. while( *ptrmp != '\0' );
  1291. }
  1292. SearnRep( "\1","",0,ptro,lenres);
  1293. *(ptro + *lenres) = '\0';
  1294. *lenres = RemoveSlash( ptro ); /* Removing '\' from result string */
  1295. if( com_or_tra ) return 1; else return (ptri-inputLine);
  1296. }
  1297. static int RemoveSlash( char * stroka )
  1298. {
  1299. char *ptr = stroka;
  1300. int State = STATE_INIT;
  1301. BOOL bDirective = FALSE;
  1302. int lenres = strlen( stroka );
  1303. HB_TRACE(HB_TR_DEBUG, ("RemoveSlash(%s)", stroka));
  1304. while( *ptr != '\0' )
  1305. {
  1306. switch( State ) {
  1307. case STATE_INIT:
  1308. if( *ptr != ' ' && *ptr != '\t' ) State = STATE_NORMAL;
  1309. if( *ptr == '#' ) bDirective = TRUE;
  1310. case STATE_NORMAL:
  1311. if( *ptr == '\'' ) State = STATE_QUOTE1;
  1312. else if( *ptr == '\"' ) State = STATE_QUOTE2;
  1313. else if( *ptr == '[' ) State = STATE_QUOTE3;
  1314. else if( *ptr == ';' )
  1315. {
  1316. State = STATE_INIT;
  1317. bDirective = FALSE;
  1318. }
  1319. else if( !bDirective )
  1320. {
  1321. if( *ptr == '\\' && ( *(ptr+1) == '[' || *(ptr+1) == ']' ||
  1322. *(ptr+1) == '{' || *(ptr+1) == '}' || *(ptr+1) == '<' ||
  1323. *(ptr+1) == '>' || *(ptr+1) == '\'' || *(ptr+1) == '\"' ) )
  1324. {
  1325. hb_pp_Stuff( "", ptr, 0, 1, lenres - (ptr - stroka) );
  1326. lenres--;
  1327. }
  1328. }
  1329. break;
  1330. case STATE_QUOTE1:
  1331. if( *ptr == '\'' ) State = STATE_NORMAL;
  1332. break;
  1333. case STATE_QUOTE2:
  1334. if( *ptr == '\"' ) State = STATE_NORMAL;
  1335. break;
  1336. case STATE_QUOTE3:
  1337. if( *ptr == ']' ) State = STATE_NORMAL;
  1338. break;
  1339. }
  1340. ptr++;
  1341. }
  1342. return lenres;
  1343. }
  1344. static int WorkMarkers( char ** ptrmp, char ** ptri, char * ptro, int * lenres, BOOL com_or_xcom )
  1345. {
  1346. static char expreal[ MAX_EXP ];
  1347. char exppatt[ MAX_NAME ];
  1348. int lenreal = 0, maxlenreal = HB_PP_STR_SIZE, lenpatt;
  1349. int rezrestr, ipos, nBra;
  1350. char * ptr, * ptrtemp;
  1351. HB_TRACE(HB_TR_DEBUG, ("WorkMarkers(%p, %p, %s, %p)", ptrmp, ptri, ptro, lenres));
  1352. /* Copying a match pattern to 'exppatt' */
  1353. lenpatt = stroncpy( exppatt, *ptrmp, 4 );
  1354. *ptrmp += 4;
  1355. HB_SKIPTABSPACES( *ptrmp );
  1356. if( **ptri == ',' )
  1357. {
  1358. if( s_numBrackets )
  1359. {
  1360. return 0;
  1361. }
  1362. }
  1363. ptrtemp = *ptrmp;
  1364. if( *(exppatt+2) != '2' && *ptrtemp == ']' )
  1365. {
  1366. ptrtemp++;
  1367. HB_SKIPTABSPACES( ptrtemp );
  1368. while( *ptrtemp == '[' )
  1369. {
  1370. nBra = 0;
  1371. ptrtemp++;
  1372. while( ( *ptrtemp != ']' || nBra ) && *ptrtemp != '\0')
  1373. {
  1374. if( *ptrtemp == '[' ) nBra++;
  1375. else if( *ptrtemp == ']' ) nBra --;
  1376. ptrtemp++;
  1377. }
  1378. ptrtemp++;
  1379. HB_SKIPTABSPACES( ptrtemp );
  1380. }
  1381. }
  1382. if( *(exppatt+2) != '2' && *ptrtemp != '\1' && *ptrtemp != ',' &&
  1383. *ptrtemp != '[' && *ptrtemp != ']' && *ptrtemp != '\0' )
  1384. {
  1385. lenreal = strincpy( expreal, ptrtemp );
  1386. if( (ipos = md_strAt( expreal, lenreal, *ptri, TRUE, TRUE, FALSE )) > 0 )
  1387. {
  1388. if( ptrtemp > *ptrmp )
  1389. {
  1390. if( ipos == 1 )
  1391. {
  1392. if( s_numBrackets )
  1393. {
  1394. return 0;
  1395. }
  1396. }
  1397. else
  1398. {
  1399. maxlenreal = ipos - 1;
  1400. lenreal = 0;
  1401. }
  1402. }
  1403. else
  1404. {
  1405. lenreal = stroncpy( expreal, *ptri, ipos-1 );
  1406. if( ipos > 1 && isExpres( expreal ) )
  1407. {
  1408. /*
  1409. printf( "Accepted: >%s<\n", expreal );
  1410. */
  1411. *ptri += lenreal;
  1412. }
  1413. else
  1414. {
  1415. if( s_numBrackets )
  1416. {
  1417. return 0;
  1418. }
  1419. else lenreal = 0;
  1420. }
  1421. }
  1422. }
  1423. else
  1424. {
  1425. if( s_numBrackets )
  1426. {
  1427. return 0;
  1428. }
  1429. else lenreal = 0;
  1430. }
  1431. }
  1432. if( *(exppatt+2) == '4' ) /* ---- extended match marker */
  1433. {
  1434. if( !lenreal ) lenreal = getExpReal( expreal, ptri, FALSE, maxlenreal, FALSE );
  1435. SearnRep( exppatt,expreal,lenreal,ptro,lenres);
  1436. }
  1437. else if( *(exppatt+2) == '3' ) /* ---- wild match marker */
  1438. {
  1439. lenreal = hb_pp_strocpy( expreal, *ptri );
  1440. *ptri += lenreal;
  1441. SearnRep( exppatt,expreal,lenreal,ptro,lenres);
  1442. }
  1443. else if( *(exppatt+2) == '2' ) /* ---- restricted match marker */
  1444. {
  1445. while( **ptrmp != '>' ) *(exppatt+lenpatt++) = *((*ptrmp)++);
  1446. *(exppatt+lenpatt) = '\0';
  1447. (*ptrmp)++;
  1448. ptr = exppatt + 4;
  1449. rezrestr = 0;
  1450. while( *ptr != '\0' )
  1451. {
  1452. if( *ptr == '&' )
  1453. {
  1454. if( **ptri == '&' )
  1455. {
  1456. rezrestr = 1;
  1457. /* (*ptri)++; */
  1458. lenreal = getExpReal( expreal, ptri, FALSE, maxlenreal, FALSE );
  1459. SearnRep( exppatt,expreal,lenreal,ptro,lenres);
  1460. break;
  1461. }
  1462. else ptr++;
  1463. }
  1464. else
  1465. {
  1466. HB_SKIPTABSPACES( ptr );
  1467. /* Comparing real parameter and restriction value */
  1468. ptrtemp = ptr;
  1469. if( !strincmp( *ptri, &ptr, !com_or_xcom ) )
  1470. {
  1471. lenreal = stroncpy( expreal, *ptri, (ptr-ptrtemp) );
  1472. *ptri += lenreal;
  1473. SearnRep( exppatt,expreal,lenreal,ptro,lenres);
  1474. rezrestr = 1;
  1475. break;
  1476. }
  1477. else
  1478. {
  1479. while( *ptr != ',' && *ptr != '\0' ) ptr++;
  1480. if( *ptr == ',' ) ptr++;
  1481. }
  1482. }
  1483. }
  1484. if( rezrestr == 0 )
  1485. { /* If restricted match marker doesn't correspond to real parameter */
  1486. if( s_numBrackets )
  1487. {
  1488. return 0;
  1489. }
  1490. else return 0;
  1491. }
  1492. }
  1493. else if( *(exppatt+2) == '1' ) /* ---- list match marker */
  1494. {
  1495. if( !lenreal ) lenreal = getExpReal( expreal, ptri, TRUE, maxlenreal, FALSE );
  1496. if( lenreal )
  1497. SearnRep( exppatt,expreal,lenreal,ptro,lenres);
  1498. else return 0;
  1499. }
  1500. else /* ---- regular match marker */
  1501. {
  1502. /* Copying a real expression to 'expreal' */
  1503. if( !lenreal ) lenreal = getExpReal( expreal, ptri, FALSE, maxlenreal, FALSE );
  1504. /*
  1505. printf("Len: %i Pat: %s Exp: %s\n", lenreal, exppatt, expreal );
  1506. */
  1507. if( lenreal )
  1508. SearnRep( exppatt,expreal,lenreal,ptro,lenres);
  1509. else return 0;
  1510. }
  1511. return 1;
  1512. }
  1513. static int getExpReal( char * expreal, char ** ptri, BOOL prlist, int maxrez, BOOL bStrict )
  1514. {
  1515. int lens = 0;
  1516. char * sZnaki = "+-=><*/$.:#%!^";
  1517. int State;
  1518. int StBr1 = 0, StBr2 = 0, StBr3 = 0;
  1519. BOOL rez = FALSE;
  1520. /* Ron Pinkas added 2000-06-02 */
  1521. BOOL bMacro = FALSE;
  1522. /* Ron Pinkas end 2000-06-02 */
  1523. /* Ron Pinkas added 2000-06-17 */
  1524. char cLastChar = '\0';
  1525. /* Ron Pinkas end 2000-06-17 */
  1526. HB_TRACE(HB_TR_DEBUG, ("getExpReal(%s, %p, %d, %d, %d)", expreal, ptri, prlist, maxrez, bStrict));
  1527. HB_SKIPTABSPACES( *ptri );
  1528. State = ( **ptri=='\'' || **ptri=='\"' || **ptri=='[' ) ? STATE_EXPRES: STATE_ID;
  1529. while( **ptri != '\0' && !rez && lens < maxrez )
  1530. {
  1531. /* Added by Ron Pinkas 2000-11-08 ( removed lots of related scattered logic below! */
  1532. if( **ptri == '"' )
  1533. {
  1534. if( expreal != NULL )
  1535. {
  1536. *expreal++ = **ptri;
  1537. }
  1538. (*ptri)++;
  1539. lens++;
  1540. while( **ptri != '\0' && lens < maxrez )
  1541. {
  1542. if( expreal != NULL )
  1543. {
  1544. *expreal++ = **ptri;
  1545. }
  1546. if( **ptri == '"' )
  1547. {
  1548. break;
  1549. }
  1550. (*ptri)++;
  1551. lens++;
  1552. }
  1553. (*ptri)++;
  1554. lens++;
  1555. State = ( StBr1==0 && StBr2==0 && StBr3==0 )? STATE_ID_END: STATE_BRACKET;
  1556. continue;
  1557. }
  1558. else if( **ptri == '\'' )
  1559. {
  1560. char *pString;
  1561. if( expreal != NULL )
  1562. {
  1563. *expreal++ = **ptri;
  1564. }
  1565. (*ptri)++;
  1566. lens++;
  1567. pString = expreal;
  1568. while( **ptri != '\0' && lens < maxrez )
  1569. {
  1570. if( expreal != NULL )
  1571. {
  1572. *expreal++ = **ptri;
  1573. }
  1574. if( **ptri == '\'' )
  1575. {
  1576. break;
  1577. }
  1578. (*ptri)++;
  1579. lens++;
  1580. }
  1581. if( expreal != NULL )
  1582. {
  1583. *(expreal - 1) = '\0';
  1584. if( strchr( pString, '"' ) == NULL )
  1585. {
  1586. *(pString - 1) = '"';
  1587. *(expreal - 1) = '"';
  1588. }
  1589. else
  1590. {
  1591. *(expreal - 1) = '\'';
  1592. }
  1593. }
  1594. (*ptri)++;
  1595. lens++;
  1596. State = ( StBr1==0 && StBr2==0 && StBr3==0 )? STATE_ID_END: STATE_BRACKET;
  1597. continue;
  1598. }
  1599. else if( **ptri == '[' && ( State == STATE_EXPRES || ( cLastChar != ')' && cLastChar != ']' && cLastChar != '}' && ! ISNAME( cLastChar ) ) ) )
  1600. {
  1601. char *pString;
  1602. if( expreal != NULL )
  1603. {
  1604. *expreal++ = **ptri;
  1605. }
  1606. (*ptri)++;
  1607. lens++;
  1608. pString = expreal;
  1609. while( **ptri != '\0' && lens < maxrez )
  1610. {
  1611. if( expreal != NULL )
  1612. {
  1613. *expreal++ = **ptri;
  1614. }
  1615. if( **ptri == ']' )
  1616. {
  1617. break;
  1618. }
  1619. (*ptri)++;
  1620. lens++;
  1621. }
  1622. if( expreal != NULL )
  1623. {
  1624. *(expreal - 1) = '\0';
  1625. if( strchr( pString, '"' ) == NULL )
  1626. {
  1627. *(pString - 1) = '"';
  1628. *(expreal - 1) = '"';
  1629. }
  1630. else if( strchr( pString, '\'' ) == NULL )
  1631. {
  1632. *(pString - 1) = '\'';
  1633. *(expreal - 1) = '\'';
  1634. }
  1635. else
  1636. {
  1637. *(expreal - 1) = ']';
  1638. }
  1639. }
  1640. (*ptri)++;
  1641. lens++;
  1642. State = ( StBr1==0 && StBr2==0 && StBr3==0 )? STATE_ID_END: STATE_BRACKET;
  1643. continue;
  1644. }
  1645. /* END - Added by Ron Pinkas 2000-11-05 */
  1646. switch( State )
  1647. {
  1648. case STATE_BRACKET:
  1649. {
  1650. if( **ptri == '(' )
  1651. {
  1652. StBr1++;
  1653. }
  1654. else if( **ptri == '[' )
  1655. {
  1656. StBr2++;
  1657. }
  1658. else if( **ptri == '{' )
  1659. {
  1660. StBr3++;
  1661. }
  1662. else if( **ptri == ')' )
  1663. {
  1664. StBr1--;
  1665. if( StBr1==0 && StBr2==0 && StBr3==0 )
  1666. {
  1667. State = STATE_ID_END;
  1668. }
  1669. }
  1670. else if( **ptri == ']' )
  1671. {
  1672. StBr2--;
  1673. if( StBr1==0 && StBr2==0 && StBr3==0 )
  1674. {
  1675. State = STATE_ID_END;
  1676. }
  1677. }
  1678. else if( **ptri == '}' )
  1679. {
  1680. StBr3--;
  1681. if( StBr1==0 && StBr2==0 && StBr3==0 )
  1682. {
  1683. State = STATE_ID_END;
  1684. }
  1685. }
  1686. break;
  1687. }
  1688. case STATE_ID:
  1689. case STATE_ID_END:
  1690. {
  1691. if( ( (ISNAME(**ptri) || **ptri=='\\' || **ptri=='&') && State == STATE_ID_END ) || **ptri==',' )
  1692. {
  1693. if( **ptri == ',' )
  1694. {
  1695. if( ! prlist )
  1696. {
  1697. rez = TRUE;
  1698. }
  1699. State = STATE_EXPRES;
  1700. }
  1701. else
  1702. {
  1703. rez = TRUE;
  1704. }
  1705. }
  1706. else if( IsInStr( **ptri, sZnaki ) )
  1707. {
  1708. /* Ron Pinkas added 2000-06-02 */
  1709. if( **ptri=='.' && bMacro )
  1710. {
  1711. /* Macro terminator '.' */
  1712. if( *(*ptri+1)==' ' )
  1713. State = STATE_ID_END;
  1714. bMacro = FALSE;
  1715. }
  1716. else
  1717. /* Ron Pinkas end 2000-06-02 */
  1718. State = STATE_EXPRES;
  1719. }
  1720. else if( **ptri == '(' )
  1721. {
  1722. State = STATE_BRACKET;
  1723. StBr1 = 1;
  1724. }
  1725. else if( **ptri == '[' )
  1726. {
  1727. StBr2++;
  1728. State = STATE_BRACKET;
  1729. }
  1730. else if( **ptri == '{' )
  1731. {
  1732. State = STATE_BRACKET;
  1733. StBr3 = 1;
  1734. }
  1735. /* Ron Pinkas added 2000-06-02 */
  1736. else if( **ptri == '&' )
  1737. {
  1738. bMacro = TRUE;
  1739. }
  1740. /* Ron Pinkas end 2000-06-02 */
  1741. else if( **ptri == ' ' )
  1742. {
  1743. State = STATE_ID_END;
  1744. /* Ron Pinkas added 2000-06-02 */
  1745. bMacro = FALSE;
  1746. /* Ron Pinkas end 2000-06-02 */
  1747. }
  1748. break;
  1749. }
  1750. case STATE_EXPRES:
  1751. case STATE_EXPRES_ID:
  1752. {
  1753. if( **ptri == '[' )
  1754. {
  1755. StBr2++;
  1756. State = STATE_BRACKET;
  1757. }
  1758. else if( ISNAME(**ptri) )
  1759. {
  1760. State = STATE_EXPRES_ID;
  1761. }
  1762. else if( **ptri == ' ' )
  1763. {
  1764. if( State == STATE_EXPRES_ID )
  1765. {
  1766. State = STATE_ID_END;
  1767. }
  1768. else if( lens > 2 && ( ( *(*ptri-2)=='+' && *(*ptri-1)=='+' ) ||
  1769. ( *(*ptri-2)=='-' && *(*ptri-1)=='-' ) ) )
  1770. {
  1771. State = STATE_ID_END;
  1772. }
  1773. }
  1774. /* Ron Pinkas added 2000-06-14 */
  1775. else if( **ptri == ')' && StBr1 == 0 )
  1776. {
  1777. rez = TRUE;
  1778. }
  1779. /* Ron Pinkas end 2000-06-14 */
  1780. else if( **ptri == '(' )
  1781. {
  1782. StBr1++;
  1783. State = STATE_BRACKET;
  1784. }
  1785. else if( **ptri == '{' )
  1786. {
  1787. StBr3++;
  1788. State = STATE_BRACKET;
  1789. }
  1790. else if( **ptri == ',' )
  1791. {
  1792. if( !prlist )
  1793. {
  1794. rez = TRUE; State = STATE_EXPRES;
  1795. }
  1796. }
  1797. else if( **ptri == '.' && *(*ptri-2) == '.' &&
  1798. ( *(*ptri-1) == 'T' || *(*ptri-1) == 'F' ||
  1799. *(*ptri-1) == 't' || *(*ptri-1) == 'f' ) )
  1800. {
  1801. State = STATE_ID_END;
  1802. }
  1803. else
  1804. {
  1805. State = STATE_EXPRES;
  1806. }
  1807. break;
  1808. }
  1809. }
  1810. if( !rez )
  1811. {
  1812. /* Ron Pinkas added 2000-06-17 */
  1813. if( **ptri != ' ' && **ptri != '\t' )
  1814. {
  1815. cLastChar = **ptri;
  1816. }
  1817. /* Ron Pinkas end 2000-06-17 */
  1818. if( expreal != NULL )
  1819. *expreal++ = **ptri;
  1820. (*ptri)++;
  1821. lens++;
  1822. }
  1823. }
  1824. if( expreal != NULL )
  1825. {
  1826. if( *(expreal-1) == ' ' )
  1827. {
  1828. expreal--;
  1829. lens--;
  1830. }
  1831. *expreal = '\0';
  1832. }
  1833. /* Ron Pinkas added 2000-06-21 */
  1834. if( bStrict )
  1835. {
  1836. if( State == STATE_QUOTE1 || State == STATE_QUOTE2 || State == STATE_QUOTE3 ||
  1837. State == STATE_BRACKET || StBr1 || StBr2 || StBr3 )
  1838. {
  1839. /* Alexander should we include this???
  1840. expreal = NULL;
  1841. */
  1842. lens = 0;
  1843. }
  1844. }
  1845. /* Ron Pinkas end 2000-06-21 */
  1846. #if 0
  1847. if( expreal && lens )
  1848. printf( "\nLen=%i >%s<\n", lens, expreal-lens );
  1849. #endif
  1850. return lens;
  1851. }
  1852. static BOOL isExpres( char * stroka )
  1853. {
  1854. int l1,l2;
  1855. HB_TRACE(HB_TR_DEBUG, ("isExpres(%s)", stroka));
  1856. #if 0
  1857. printf( "Exp: >%s<\n", stroka );
  1858. #endif
  1859. l1 = strlen( stroka );
  1860. l2 = getExpReal( NULL, &stroka, FALSE, HB_PP_STR_SIZE, TRUE );
  1861. #if 0
  1862. printf( "Len1: %i Len2: %i RealExp: >%s< Last: %c\n", l1, l2, stroka - l2, ( stroka - l2 )[l1-1] );
  1863. #endif
  1864. /* Ron Pinkas modified 2000-06-17 Expression can't be valid if last charcter is one of these: ":/+*-%^=(<>"
  1865. return ( l1 <= l2 );
  1866. */
  1867. return ( l1 <= l2 && ! IsInStr( ( stroka - l2 )[l1-1], ":/+*-%^=(<>[{" ) );
  1868. }
  1869. static BOOL TestOptional( char *ptr1, char *ptr2 )
  1870. {
  1871. int nbr = 0;
  1872. BOOL flagname = FALSE;
  1873. int statevar = 0;
  1874. HB_TRACE(HB_TR_DEBUG, ("TestOptional(%s, %s)", ptr1, ptr2));
  1875. while( ptr1 <= ptr2 )
  1876. {
  1877. if( *ptr1 == '[' ) nbr++;
  1878. else if( *ptr1 == ']' )
  1879. {
  1880. if( nbr )
  1881. {
  1882. nbr--;
  1883. flagname = FALSE;
  1884. }
  1885. else return 0;
  1886. }
  1887. else if( *ptr1 == '\1' && *(ptr1+2) == '2' && nbr ) statevar = 1;
  1888. else if( *ptr1 == '>' && statevar ) statevar = 0;
  1889. else if( *ptr1 != ' ' && *ptr1 != '\t' && !statevar )
  1890. {
  1891. if( nbr ) flagname = TRUE;
  1892. else return 0;
  1893. }
  1894. ptr1++;
  1895. }
  1896. /* if( !flagname )
  1897. while( *ptr1 != ']' )
  1898. {
  1899. if( *ptr1 == '[' || *ptr1 == '\0' ) return 0;
  1900. ptr1++;
  1901. } */
  1902. return !flagname;
  1903. }
  1904. static BOOL CheckOptional( char * ptrmp, char * ptri, char * ptro, int * lenres, BOOL com_or_tra, BOOL com_or_xcom )
  1905. {
  1906. int save_numBr = s_numBrackets, save_Repeate = s_Repeate;
  1907. BOOL endTranslation = FALSE;
  1908. BOOL bResult = TRUE;
  1909. char * lastInputptr[ 5 ];
  1910. char * lastopti[ 3 ], *ptr;
  1911. HB_SYMBOL_UNUSED( com_or_tra );
  1912. HB_TRACE(HB_TR_DEBUG, ("CheckOptional(%s, %s, %s, %p, %d, %d)", ptrmp, ptri, ptro, lenres, com_or_tra, com_or_xcom));
  1913. s_bReplacePat = FALSE;
  1914. lastInputptr[s_Repeate] = ptri;
  1915. while( *ptri != '\0' && !endTranslation && bResult )
  1916. {
  1917. HB_SKIPTABSPACES( ptrmp );
  1918. switch( *ptrmp ) {
  1919. case '[':
  1920. s_numBrackets++;
  1921. s_aIsRepeate[ s_Repeate ] = 0;
  1922. lastInputptr[s_Repeate] = ptri;
  1923. lastopti[s_Repeate++] = ptrmp;
  1924. ptrmp++;
  1925. break;
  1926. case ']':
  1927. if( s_numBrackets == save_numBr )
  1928. endTranslation = TRUE;
  1929. else
  1930. {
  1931. if( s_Repeate )
  1932. {
  1933. s_Repeate--;
  1934. ptrmp = lastopti[s_Repeate];
  1935. }
  1936. else ptrmp++;
  1937. s_numBrackets--;
  1938. }
  1939. break;
  1940. case ',':
  1941. if( *ptri == ',' ) { ptrmp++; ptri++; }
  1942. else
  1943. {
  1944. if( s_numBrackets - save_numBr > 0 )
  1945. {
  1946. SkipOptional( &ptrmp );
  1947. ptri = lastInputptr[s_Repeate];
  1948. }
  1949. else bResult = FALSE;
  1950. }
  1951. break;
  1952. case '\1': /* Match marker */
  1953. if( !WorkMarkers( &ptrmp, &ptri, ptro, lenres, com_or_xcom ) )
  1954. {
  1955. if( s_numBrackets - save_numBr > 0 )
  1956. {
  1957. SkipOptional( &ptrmp );
  1958. ptri = lastInputptr[s_Repeate];
  1959. }
  1960. else bResult = FALSE;
  1961. }
  1962. break;
  1963. case '\0':
  1964. bResult = FALSE;
  1965. default: /* Key word */
  1966. ptr = ptri;
  1967. if( *ptri == ',' || truncmp( &ptri, &ptrmp, !com_or_xcom ) )
  1968. {
  1969. ptri = ptr;
  1970. if( s_numBrackets - save_numBr > 0 )
  1971. {
  1972. SkipOptional( &ptrmp );
  1973. ptri = lastInputptr[s_Repeate];
  1974. }
  1975. else bResult = FALSE;
  1976. }
  1977. }
  1978. HB_SKIPTABSPACES( ptri );
  1979. };
  1980. if( *ptri == '\0' )
  1981. {
  1982. do
  1983. {
  1984. HB_SKIPTABSPACES( ptrmp );
  1985. if( *ptrmp == '[' )
  1986. {
  1987. ptrmp++;
  1988. SkipOptional( &ptrmp );
  1989. }
  1990. else if( *ptrmp == ']' )
  1991. break;
  1992. else
  1993. {
  1994. bResult = 0;
  1995. break;
  1996. }
  1997. }
  1998. while( 1 );
  1999. }
  2000. s_Repeate = save_Repeate;
  2001. s_numBrackets = save_numBr;
  2002. s_bReplacePat = TRUE;
  2003. return bResult;
  2004. }
  2005. static void SkipOptional( char ** ptri )
  2006. {
  2007. int nbr = 0;
  2008. HB_TRACE(HB_TR_DEBUG, ("SkipOptional(%p)", ptri));
  2009. while( **ptri != ']' || nbr )
  2010. {
  2011. switch( **ptri ) {
  2012. case '[': nbr++; break;
  2013. case ']': nbr--; break;
  2014. case '\1':
  2015. (*ptri) += 3;
  2016. if( *(*ptri-1) == '2' )
  2017. while( **ptri != '>' ) (*ptri)++;
  2018. break;
  2019. }
  2020. (*ptri)++;
  2021. }
  2022. if( **ptri == ']' && s_numBrackets > 0 )
  2023. {
  2024. if( s_Repeate ) s_Repeate--;
  2025. s_numBrackets--; (*ptri)++;
  2026. }
  2027. }
  2028. static void SearnRep( char * exppatt, char * expreal, int lenreal, char * ptro, int * lenres )
  2029. {
  2030. static char expnew[ MAX_EXP ];
  2031. int ifou, isdvig = 0;
  2032. BOOL rezs;
  2033. int kolmarkers;
  2034. int lennew, i;
  2035. char lastchar = '0';
  2036. char *ptr, *ptr2, *ptrOut = ptro;
  2037. HB_TRACE(HB_TR_DEBUG, ("SearnRep(%s, %s, %d, %s, %p)", exppatt, expreal, lenreal, ptro, lenres));
  2038. if( *(exppatt+1) == '\0' ) *( ptro + *lenres