PageRenderTime 27ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

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

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