PageRenderTime 72ms CodeModel.GetById 31ms 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

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

  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);

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