PageRenderTime 69ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

/tags/troff/harbour/source/pp/hbpp.c

#
C | 2107 lines | 1850 code | 182 blank | 75 comment | 906 complexity | a5c519ac84fcdf8815559fec2397a0d3 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: hbpp.c 2000 2000-01-17 19:18:07Z alkresin $
  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 1999 Jose Lalin <dezac@corevia.com>
  39. * Support for #pragma directive and related functions
  40. * See doc/pragma.txt
  41. *
  42. * See doc/license.txt for licensing terms.
  43. *
  44. */
  45. /*
  46. * Avoid tracing in preprocessor/compiler.
  47. */
  48. #if ! defined(HB_TRACE_UTILS)
  49. #if defined(HB_TRACE_LEVEL)
  50. #undef HB_TRACE_LEVEL
  51. #endif
  52. #endif
  53. #include <stdio.h>
  54. #include <stdlib.h>
  55. #include <string.h>
  56. #include <ctype.h>
  57. #include "hbpp.h"
  58. #include "hberrors.h"
  59. #include "compiler.h"
  60. static COMMANDS * AddCommand( char * ); /* Add new #command to an array */
  61. static COMMANDS * AddTranslate( char * ); /* Add new #translate to an array */
  62. static DEFINES * DefSearch( char *, BOOL * );
  63. static COMMANDS * ComSearch( char *, COMMANDS * );
  64. static COMMANDS * TraSearch( char *, COMMANDS * );
  65. static int ParseDefine( char * ); /* Process #define directive */
  66. static int ParseUndef( char * ); /* Process #undef directive */
  67. static int ParseIfdef( char *, int ); /* Process #ifdef directive */
  68. static void ParseCommand( char *, BOOL, BOOL ); /* Process #command or #translate directive */
  69. static void ConvertPatterns( char *, int, char *, int ); /* Converting result pattern in #command and #translate */
  70. static int WorkDefine( char **, char *, DEFINES * ); /* Replace fragment of code with a #defined result text */
  71. static int WorkPseudoF( char **, char *, DEFINES * ); /* Replace pseudofunction with a #defined result text */
  72. static int WorkCommand( char *, char *, COMMANDS * );
  73. static int WorkTranslate( char *, char *, COMMANDS *, int * );
  74. static int CommandStuff( char *, char *, char *, int *, BOOL, BOOL );
  75. static int RemoveSlash( char * );
  76. static int WorkMarkers( char **, char **, char *, int *, BOOL );
  77. static int getExpReal( char *, char **, BOOL, int );
  78. static BOOL isExpres( char * );
  79. static BOOL TestOptional( char *, char * );
  80. static BOOL CheckOptional( char *, char *, char *, int *, BOOL, BOOL );
  81. static void SkipOptional( char ** );
  82. static void SearnRep( char *, char *, int, char *, int * );
  83. static int ReplacePattern( char, char *, int, char *, int );
  84. static void pp_rQuotes( char *, char * );
  85. static int md_strAt( char *, int, char *, BOOL, BOOL );
  86. static char * PrevSquare( char * , char *, int * );
  87. static int IsInStr( char, char * );
  88. static int stroncpy( char *, char *, int );
  89. static int strincpy( char *, char * );
  90. static BOOL truncmp( char **, char **, BOOL );
  91. static BOOL strincmp( char *, char **, BOOL );
  92. static int strotrim( char * );
  93. static int NextWord( char **, char *, BOOL );
  94. static int NextName( char **, char * );
  95. static int NextParm( char **, char * );
  96. static BOOL OpenInclude( char *, PATHNAMES *, PHB_FNAME, FILE **, BOOL bStandardOnly, char * );
  97. /* These are related to pragma support */
  98. static int ParsePragma( char * );
  99. static BOOL StringToBool( char *, BOOL );
  100. static int StringToInt( char *, int );
  101. static BOOL IsOnOffSwitch( char *, BOOL );
  102. static void DebugPragma( char *, int, BOOL );
  103. static BOOL s_bTracePragma = FALSE;
  104. #define ISNAME( c ) ( isalnum( c ) || ( c ) == '_' || ( c ) > 0x7E )
  105. #define MAX_NAME 255
  106. #define MAX_EXP 1024
  107. #define PATTERN_SIZE 2048
  108. #define STATE_INIT 0
  109. #define STATE_NORMAL 1
  110. #define STATE_COMMENT 2
  111. #define STATE_QUOTE1 3
  112. #define STATE_QUOTE2 4
  113. #define STATE_ID_END 5
  114. #define STATE_ID 6
  115. #define STATE_EXPRES 7
  116. #define STATE_EXPRES_ID 8
  117. #define STATE_BRACKET 9
  118. #define IT_EXPR 1
  119. #define IT_ID 2
  120. #define IT_COMMA 3
  121. #define IT_ID_OR_EXPR 4
  122. static int s_kolAddDefs = 0;
  123. static int s_ParseState = 0;
  124. static int s_maxCondCompile = 5;
  125. static int s_aIsRepeate[ 5 ];
  126. static int s_Repeate;
  127. static BOOL s_bReplacePat = TRUE;
  128. static int s_numBrackets;
  129. static char s_groupchar;
  130. int hb_pp_lInclude = 0;
  131. int * hb_pp_aCondCompile;
  132. int hb_pp_nCondCompile = 0;
  133. /* Table with parse errors */
  134. char * hb_pp_szErrors[] =
  135. {
  136. "Can\'t open #include file: \'%s\'",
  137. "#else does not match #ifdef",
  138. "#endif does not match #ifdef",
  139. "Bad filename in #include",
  140. "#define without parameters",
  141. "Missing => in #translate/#command",
  142. "Error in pattern definition",
  143. "Cycled #define",
  144. "Invalid name follows #: \'%s\'",
  145. "#error: \'%s\'",
  146. "Memory allocation error",
  147. "Memory reallocation error",
  148. "Freeing a NULL memory pointer",
  149. "Value out of range in #pragma directive"
  150. };
  151. /* Table with parse warnings */
  152. /* NOTE: The first character stores the warning's level that triggers this
  153. * warning. The warning's level is set by -w<n> command line option.
  154. */
  155. char * hb_pp_szWarnings[] =
  156. {
  157. "3Non directive in include file %s(%s)"
  158. };
  159. int hb_pp_ParseDirective( char * sLine )
  160. {
  161. char sDirective[MAX_NAME];
  162. char szInclude[_POSIX_PATH_MAX];
  163. int i;
  164. FILE* handl_i;
  165. HB_TRACE(HB_TR_DEBUG, ("hb_pp_ParseDirective(%s)", sLine));
  166. i = NextName( &sLine, sDirective );
  167. hb_strupr( sDirective );
  168. HB_SKIPTABSPACES(sLine);
  169. if( i == 4 && memcmp( sDirective, "ELSE", 4 ) == 0 )
  170. { /* --- #else --- */
  171. if( hb_pp_nCondCompile == 0 )
  172. hb_compGenError( hb_pp_szErrors, 'F', ERR_DIRECTIVE_ELSE, NULL, NULL );
  173. else if( hb_pp_nCondCompile == 1 || hb_pp_aCondCompile[hb_pp_nCondCompile-2] )
  174. hb_pp_aCondCompile[hb_pp_nCondCompile-1] = 1 - hb_pp_aCondCompile[hb_pp_nCondCompile-1];
  175. }
  176. else if( i == 5 && memcmp( sDirective, "ENDIF", 5 ) == 0 )
  177. { /* --- #endif --- */
  178. if( hb_pp_nCondCompile == 0 )
  179. hb_compGenError( hb_pp_szErrors, 'F', ERR_DIRECTIVE_ENDIF, NULL, NULL );
  180. else hb_pp_nCondCompile--;
  181. }
  182. else if( i == 5 && memcmp( sDirective, "IFDEF", 5 ) == 0 )
  183. ParseIfdef( sLine, TRUE ); /* --- #ifdef --- */
  184. else if( i == 6 && memcmp( sDirective, "IFNDEF", 6 ) == 0 )
  185. ParseIfdef( sLine, FALSE ); /* --- #ifndef --- */
  186. else if( hb_pp_nCondCompile==0 || hb_pp_aCondCompile[hb_pp_nCondCompile-1])
  187. {
  188. if( i == 7 && memcmp( sDirective, "INCLUDE", 7 ) == 0 )
  189. { /* --- #include --- */
  190. char cDelimChar;
  191. if( *sLine != '\"' && *sLine != '\'' && *sLine != '<' )
  192. hb_compGenError( hb_pp_szErrors, 'F', ERR_WRONG_NAME, NULL, NULL );
  193. cDelimChar = *sLine;
  194. if( cDelimChar == '<' )
  195. cDelimChar = '>';
  196. else if( cDelimChar == '`' )
  197. cDelimChar = '\'';
  198. sLine++; i = 0;
  199. while( *(sLine+i) != '\0' && *(sLine+i) != cDelimChar ) i++;
  200. if( *(sLine+i) != cDelimChar )
  201. hb_compGenError( hb_pp_szErrors, 'F', ERR_WRONG_NAME, NULL, NULL );
  202. *(sLine+i) = '\0';
  203. /* if((handl_i = fopen(sLine, "r")) == NULL) */
  204. if( OpenInclude( sLine, hb_comp_pIncludePath, hb_comp_pFileName, &handl_i, ( cDelimChar == '>' ), szInclude ) )
  205. {
  206. hb_pp_lInclude++;
  207. hb_pp_Parse(handl_i, 0, szInclude );
  208. hb_pp_lInclude--;
  209. fclose(handl_i);
  210. }
  211. else
  212. hb_compGenError( hb_pp_szErrors, 'F', ERR_CANNOT_OPEN, sLine, NULL );
  213. }
  214. else if( i == 6 && memcmp( sDirective, "DEFINE", 6 ) == 0 )
  215. ParseDefine( sLine ); /* --- #define --- */
  216. else if( i == 5 && memcmp( sDirective, "UNDEF", 5 ) == 0 )
  217. ParseUndef( sLine ); /* --- #undef --- */
  218. else if( (i == 7 && memcmp( sDirective, "COMMAND", 7 ) == 0) ||
  219. (i == 8 && memcmp( sDirective, "XCOMMAND", 8 ) == 0) )
  220. /* --- #command --- */
  221. ParseCommand( sLine, (i==7)? FALSE:TRUE, TRUE );
  222. else if( (i == 9 && memcmp( sDirective, "TRANSLATE", 9 ) == 0) ||
  223. (i == 10 && memcmp( sDirective, "XTRANSLATE", 10 ) == 0) )
  224. /* --- #translate --- */
  225. ParseCommand( sLine, (i==9)? FALSE:TRUE, FALSE );
  226. else if( i == 6 && memcmp( sDirective, "STDOUT", 6 ) == 0 )
  227. printf( "%s\n", sLine ); /* --- #stdout --- */
  228. else if( i == 5 && memcmp( sDirective, "ERROR", 5 ) == 0 )
  229. /* --- #error --- */
  230. hb_compGenError( hb_pp_szErrors, 'E', ERR_EXPLICIT, sLine, NULL );
  231. else if( i == 4 && memcmp( sDirective, "LINE", 4 ) == 0 )
  232. return -1;
  233. else if( i == 6 && memcmp( sDirective, "PRAGMA", 6 ) == 0 )
  234. ParsePragma( sLine ); /* --- #pragma --- */
  235. else
  236. hb_compGenError( hb_pp_szErrors, 'F', ERR_WRONG_DIRECTIVE, sDirective, NULL );
  237. }
  238. return 0;
  239. }
  240. static int ParseDefine( char * sLine )
  241. {
  242. char defname[MAX_NAME], pars[MAX_NAME];
  243. int i, npars = -1;
  244. DEFINES * lastdef;
  245. HB_TRACE(HB_TR_DEBUG, ("ParseDefine(%s)", sLine));
  246. HB_SKIPTABSPACES( sLine );
  247. if( isalpha( *sLine ) || *sLine == '_' || *sLine > 0x7e )
  248. {
  249. NextName( &sLine, defname );
  250. if( *sLine == '(' ) /* If pseudofunction was found */
  251. {
  252. sLine++; i = 0;
  253. npars = 0;
  254. while( *sLine != '\0' && *sLine != ')')
  255. {
  256. if( *sLine == ',' ) npars++;
  257. if( *sLine != ' ' && *sLine != '\t' ) *(pars+i++) = *sLine;
  258. sLine++;
  259. }
  260. if( i > 0 ) npars++;
  261. *(pars+i) = '\0';
  262. sLine++;
  263. }
  264. HB_SKIPTABSPACES(sLine);
  265. lastdef = hb_pp_AddDefine( defname, ( *sLine == '\0' )? NULL : sLine );
  266. lastdef->npars = npars;
  267. lastdef->pars = ( npars <= 0 )? NULL : hb_strdup( pars );
  268. }
  269. else
  270. hb_compGenError( hb_pp_szErrors, 'F', ERR_DEFINE_ABSENT, NULL, NULL );
  271. return 0;
  272. }
  273. DEFINES * hb_pp_AddDefine( char * defname, char * value )
  274. {
  275. BOOL isNew;
  276. DEFINES* stdef = DefSearch( defname, &isNew );
  277. HB_TRACE(HB_TR_DEBUG, ("hb_pp_AddDefine(%s, %s)", defname, value));
  278. if( stdef != NULL )
  279. {
  280. if( isNew )
  281. {
  282. if( stdef->pars ) hb_xfree( stdef->pars );
  283. if( stdef->value ) hb_xfree( stdef->value );
  284. }
  285. }
  286. else
  287. {
  288. stdef = ( DEFINES * ) hb_xgrab( sizeof( DEFINES ) );
  289. stdef->last = hb_pp_topDefine;
  290. hb_pp_topDefine = stdef;
  291. stdef->name = hb_strdup( defname );
  292. s_kolAddDefs++;
  293. }
  294. stdef->value = ( value == NULL )? NULL : hb_strdup( value );
  295. return stdef;
  296. }
  297. static int ParseUndef( char * sLine )
  298. {
  299. char defname[MAX_NAME];
  300. DEFINES* stdef;
  301. BOOL isNew;
  302. HB_TRACE(HB_TR_DEBUG, ("ParseUndef(%s)", sLine));
  303. NextWord( &sLine, defname, FALSE );
  304. if( ( stdef = DefSearch(defname, &isNew ) ) != NULL )
  305. {
  306. if( isNew )
  307. {
  308. if( stdef->pars ) hb_xfree( stdef->pars );
  309. if( stdef->value ) hb_xfree( stdef->value );
  310. hb_xfree( stdef->name );
  311. }
  312. stdef->name = NULL;
  313. }
  314. return 0;
  315. }
  316. static int ParseIfdef( char * sLine, int usl )
  317. {
  318. char defname[ MAX_NAME ];
  319. DEFINES * stdef;
  320. HB_TRACE(HB_TR_DEBUG, ("ParseIfdef(%s, %d)", sLine, usl));
  321. if( hb_pp_nCondCompile==0 || hb_pp_aCondCompile[hb_pp_nCondCompile-1])
  322. {
  323. NextWord( &sLine, defname, FALSE );
  324. if( *defname == '\0' )
  325. hb_compGenError( hb_pp_szErrors, 'F', ERR_DEFINE_ABSENT, NULL, NULL );
  326. }
  327. if( hb_pp_nCondCompile == s_maxCondCompile )
  328. {
  329. s_maxCondCompile += 5;
  330. hb_pp_aCondCompile = (int*)hb_xrealloc( hb_pp_aCondCompile, sizeof( int ) * s_maxCondCompile );
  331. }
  332. if( hb_pp_nCondCompile==0 || hb_pp_aCondCompile[hb_pp_nCondCompile-1])
  333. {
  334. if( ( (stdef = DefSearch(defname,NULL)) != NULL && usl )
  335. || ( stdef == NULL && !usl ) ) hb_pp_aCondCompile[hb_pp_nCondCompile] = 1;
  336. else hb_pp_aCondCompile[hb_pp_nCondCompile] = 0;
  337. }
  338. else
  339. hb_pp_aCondCompile[ hb_pp_nCondCompile ] = 0;
  340. hb_pp_nCondCompile++;
  341. return 0;
  342. }
  343. static DEFINES * DefSearch( char * defname, BOOL * isNew )
  344. {
  345. int kol = 0,j;
  346. DEFINES * stdef = hb_pp_topDefine;
  347. HB_TRACE(HB_TR_DEBUG, ("DefSearch(%s)", defname));
  348. while( stdef != NULL )
  349. {
  350. kol++;
  351. if( stdef->name != NULL )
  352. {
  353. for( j=0; *(stdef->name+j) == *(defname+j) &&
  354. *(stdef->name+j) != '\0'; j++ );
  355. if( *(stdef->name+j) == *(defname+j) )
  356. {
  357. if( isNew ) *isNew = ( s_kolAddDefs >= kol );
  358. return stdef;
  359. }
  360. }
  361. stdef = stdef->last;
  362. }
  363. return NULL;
  364. }
  365. static COMMANDS * ComSearch( char * cmdname, COMMANDS * stcmdStart )
  366. {
  367. COMMANDS * stcmd = ( stcmdStart ) ? stcmdStart : hb_pp_topCommand;
  368. HB_TRACE(HB_TR_DEBUG, ("ComSearch(%s, %p)", cmdname, stcmdStart));
  369. while( stcmd != NULL )
  370. {
  371. int j;
  372. for( j=0; (*(stcmd->name+j)==toupper(*(cmdname+j))) &&
  373. (*(stcmd->name+j)!='\0') &&
  374. ((stcmd->com_or_xcom)? 1:(j<4 || ISNAME(*(cmdname+j+1)))); j++ );
  375. if( (*(stcmd->name+j)==toupper(*(cmdname+j))) ||
  376. ( !stcmd->com_or_xcom && j >= 4 && *(stcmd->name+j)!='\0'
  377. && *(cmdname+j) == '\0' ) )
  378. break;
  379. stcmd = stcmd->last;
  380. }
  381. return stcmd;
  382. }
  383. static COMMANDS * TraSearch( char * cmdname, COMMANDS * sttraStart )
  384. {
  385. int j;
  386. COMMANDS *sttra = ( sttraStart ) ? sttraStart : hb_pp_topTranslate;
  387. HB_TRACE(HB_TR_DEBUG, ("TraSearch(%s, %p)", cmdname, sttraStart));
  388. while( sttra != NULL )
  389. {
  390. for( j=0; *(sttra->name+j)==toupper(*(cmdname+j)) &&
  391. *(sttra->name+j)!='\0' &&
  392. ((sttra->com_or_xcom)? 1:(j<4 || ISNAME(*(cmdname+j+1)))); j++ );
  393. if( *(sttra->name+j)==toupper(*(cmdname+j)) ||
  394. ( !sttra->com_or_xcom && j >= 4 &&
  395. *(sttra->name+j)!='\0' && *(cmdname+j) == '\0' ) )
  396. break;
  397. sttra = sttra->last;
  398. }
  399. return sttra;
  400. }
  401. static void ParseCommand( char * sLine, BOOL com_or_xcom, BOOL com_or_tra )
  402. {
  403. static char mpatt[ PATTERN_SIZE ];
  404. static char rpatt[ PATTERN_SIZE ];
  405. char cmdname[ MAX_NAME ];
  406. COMMANDS * stcmd;
  407. int mlen,rlen;
  408. int ipos;
  409. HB_TRACE(HB_TR_DEBUG, ("ParseCommand(%s, $d, $d)", sLine, com_or_xcom, com_or_tra));
  410. NextWord( &sLine, cmdname, FALSE );
  411. hb_strupr( cmdname );
  412. HB_SKIPTABSPACES(sLine);
  413. if( (ipos = hb_strAt( "=>", 2, sLine, strlen(sLine) )) > 0 )
  414. {
  415. stroncpy( mpatt, sLine, ipos-1 );
  416. RemoveSlash( mpatt );
  417. mlen = strotrim( mpatt );
  418. sLine += ipos + 1;
  419. HB_SKIPTABSPACES(sLine);
  420. hb_pp_strocpy( rpatt, sLine );
  421. rlen = strotrim( rpatt );
  422. ConvertPatterns( mpatt, mlen, rpatt, rlen );
  423. if( com_or_tra )
  424. stcmd = AddCommand( cmdname );
  425. else
  426. stcmd = AddTranslate( cmdname );
  427. stcmd->com_or_xcom = com_or_xcom;
  428. stcmd->mpatt = hb_strdup( mpatt );
  429. stcmd->value = ( rlen > 0 ) ? hb_strdup( rpatt ) : NULL;
  430. }
  431. else
  432. hb_compGenError( hb_pp_szErrors, 'F', ERR_COMMAND_DEFINITION, NULL, NULL );
  433. }
  434. /* ConvertPatterns()
  435. * Converts result pattern in #command and #translate to inner format
  436. */
  437. static void ConvertPatterns( char * mpatt, int mlen, char * rpatt, int rlen )
  438. {
  439. int i = 0, ipos, ifou;
  440. int explen, rmlen;
  441. char exppatt[ MAX_NAME ], expreal[ 5 ] = "\1 0";
  442. char lastchar = '@', exptype;
  443. char * ptr;
  444. HB_TRACE(HB_TR_DEBUG, ("ConvertPatterns(%s, $d, %s, $d)", mpatt, mlen, rpatt, rlen));
  445. while( *(mpatt+i) != '\0' )
  446. {
  447. if( *(mpatt+i) == '<' )
  448. { /* Drag match marker, determine it type */
  449. explen = 0; ipos = i; i++; exptype = '0';
  450. while( *(mpatt+i) == ' ' || *(mpatt+i) == '\t' ) i++;
  451. if( *(mpatt+i) == '*' ) /* Wild match marker */
  452. { exptype = '3'; i++; }
  453. else if( *(mpatt+i) == '(' ) /* Extended expression match marker */
  454. { exptype = '4'; i++; }
  455. while( *(mpatt+i) != '>' )
  456. {
  457. if( *(mpatt+i) == ',' ) /* List match marker */
  458. {
  459. exptype = '1';
  460. while( *(mpatt+i) != '>' ) i++;
  461. break;
  462. }
  463. else if( *(mpatt+i) == ':' ) /* Restricted match marker */
  464. {
  465. exptype = '2';
  466. *(mpatt+i--) = ' ';
  467. break;
  468. }
  469. if( *(mpatt+i) != ' ' && *(mpatt+i) != '\t' )
  470. *(exppatt+explen++) = *(mpatt+i);
  471. i++;
  472. }
  473. if( exptype == '3' )
  474. {
  475. if( *(exppatt+explen-1) == '*' ) explen--;
  476. else
  477. hb_compGenError( hb_pp_szErrors, 'F', ERR_PATTERN_DEFINITION, NULL, NULL );
  478. }
  479. else if( exptype == '4' )
  480. {
  481. if( *(exppatt+explen-1) == ')' ) explen--;
  482. else
  483. hb_compGenError( hb_pp_szErrors, 'F', ERR_PATTERN_DEFINITION, NULL, NULL );
  484. }
  485. rmlen = i - ipos + 1;
  486. /* Convert match marker into inner format */
  487. lastchar = (lastchar!='Z') ? ( (char) ( (unsigned int)lastchar + 1 ) ):
  488. 'a';
  489. expreal[1] = lastchar;
  490. expreal[2] = exptype;
  491. hb_pp_Stuff( expreal, mpatt+ipos, 4, rmlen, mlen );
  492. mlen += 4 - rmlen;
  493. i += 4 - rmlen;
  494. /* Look for appropriate result markers */
  495. ptr = rpatt;
  496. while( (ifou = hb_strAt( exppatt, explen, ptr, rlen-(ptr-rpatt) )) > 0 )
  497. {
  498. /* Convert result marker into inner format */
  499. ptr += ifou;
  500. if( *(ptr-2) == '<' && *(ptr+explen-1) == '>' &&
  501. *(ptr-3) != '\\' && *(ptr+explen-2) != '\\' ) /* <...> */
  502. {
  503. if( *(ptr-3) == '#' && *(ptr-4) != '\\' ) /* #<...> */
  504. { exptype = '1'; ptr -= 3; rmlen = explen+3; }
  505. else
  506. { exptype = '0'; ptr -= 2; rmlen = explen+2; }
  507. }
  508. else if( *(ptr-3) == '<' && *(ptr+explen) == '>' &&
  509. *(ptr-4) != '\\' && *(ptr+explen-1) != '\\' ) /* < ... > */
  510. {
  511. ptr -= 2;
  512. if( *ptr == '\"' ) exptype = '2';
  513. else if( *ptr == '(' ) exptype = '3';
  514. else if( *ptr == '{' ) exptype = '4';
  515. else if( *ptr == '.' ) exptype = '5';
  516. ptr--;
  517. rmlen = explen+4;
  518. }
  519. else continue;
  520. expreal[2] = exptype;
  521. hb_pp_Stuff( expreal, ptr, 4, rmlen, rlen );
  522. rlen += 4 - rmlen;
  523. }
  524. }
  525. i++;
  526. }
  527. }
  528. static COMMANDS * AddCommand( char * cmdname )
  529. {
  530. COMMANDS * stcmd;
  531. HB_TRACE(HB_TR_DEBUG, ("AddCommand(%s)", cmdname));
  532. stcmd = ( COMMANDS * ) hb_xgrab( sizeof( COMMANDS ) );
  533. stcmd->last = hb_pp_topCommand;
  534. hb_pp_topCommand = stcmd;
  535. stcmd->name = hb_strdup( cmdname );
  536. return stcmd;
  537. }
  538. static COMMANDS* AddTranslate( char * traname )
  539. {
  540. COMMANDS * sttra;
  541. HB_TRACE(HB_TR_DEBUG, ("AddTranslate(%s)", traname));
  542. sttra = ( COMMANDS * ) hb_xgrab( sizeof( COMMANDS ) );
  543. sttra->last = hb_pp_topTranslate;
  544. hb_pp_topTranslate = sttra;
  545. sttra->name = hb_strdup( traname );
  546. return sttra;
  547. }
  548. int hb_pp_ParseExpression( char * sLine, char * sOutLine )
  549. {
  550. char sToken[MAX_NAME];
  551. char * ptri, * ptro, * ptrb;
  552. int lenToken, i, ipos, isdvig, lens;
  553. int ifou;
  554. int rezDef, rezTra, rezCom, kolpass = 0;
  555. DEFINES * stdef;
  556. COMMANDS * stcmd;
  557. HB_TRACE(HB_TR_DEBUG, ("hb_pp_ParseExpression(%s, %s)", sLine, sOutLine));
  558. do
  559. {
  560. strotrim( sLine );
  561. rezDef = 0; rezTra = 0; rezCom = 0;
  562. isdvig = 0;
  563. do
  564. {
  565. ptro = sOutLine;
  566. ptri = sLine + isdvig;
  567. ipos = md_strAt( ";", 1, ptri, TRUE, FALSE );
  568. if( ipos > 0 ) *(ptri+ipos-1) = '\0';
  569. HB_SKIPTABSPACES( ptri );
  570. if( *ptri == '#' )
  571. {
  572. hb_pp_ParseDirective( ptri+1 );
  573. if( ipos > 0 ) *( sLine + isdvig + ipos - 1 ) = ';';
  574. lens = strlen( sLine+isdvig );
  575. hb_pp_Stuff( " ", sLine+isdvig, 0, (ipos)? ipos:lens, lens );
  576. if( ipos > 0 ) ipos = 1;
  577. }
  578. else
  579. { /* Look for macros from #define */
  580. while( ( lenToken = NextName( &ptri, sToken ) ) > 0 )
  581. if( (stdef=DefSearch(sToken,NULL)) != NULL )
  582. {
  583. ptrb = ptri - lenToken;
  584. if( ( i = WorkDefine( &ptri, ptro, stdef ) ) >= 0 )
  585. {
  586. rezDef++;
  587. lens = strlen( ptrb );
  588. if( ipos > 0 )
  589. {
  590. *(ptrb+lens) = ';';
  591. lens += strlen( ptrb+lens+1 );
  592. }
  593. hb_pp_Stuff( ptro, ptrb, i, ptri-ptrb, lens+1 );
  594. if( ipos > 0 )
  595. {
  596. ipos += i - (ptri-ptrb);
  597. *(sLine + isdvig + ipos - 1) = '\0';
  598. }
  599. ptri += i - (ptri-ptrb);
  600. }
  601. }
  602. /* Look for definitions from #translate */
  603. stcmd = hb_pp_topTranslate;
  604. while( stcmd != NULL )
  605. {
  606. ptri = sLine + isdvig;
  607. lenToken = strlen(stcmd->name);
  608. while( ( ifou = md_strAt( stcmd->name, lenToken,
  609. ptri, TRUE, FALSE )) > 0 )
  610. {
  611. ptri += ifou -1;
  612. if( (i = WorkTranslate( ptri+lenToken, ptro, stcmd, &lens )) >= 0 )
  613. {
  614. lens += lenToken;
  615. while( lens > 0 &&
  616. (*(ptri+lens-1)==' ' || *(ptri+lens-1)=='\t') )
  617. lens--;
  618. if( ipos > 0 ) *(sLine+isdvig+ipos-1) = ';';
  619. hb_pp_Stuff( ptro, ptri, i, lens, strlen(ptri) );
  620. rezTra = 1;
  621. if( ipos > 0 )
  622. {
  623. ipos += i - lens;
  624. *(sLine+isdvig+ipos-1) = '\0';
  625. }
  626. ptri += i;
  627. }
  628. else
  629. ptri += lenToken;
  630. }
  631. stcmd = stcmd->last;
  632. }
  633. /* Look for definitions from #command */
  634. if( kolpass < 3 )
  635. {
  636. ptri = sLine + isdvig;
  637. HB_SKIPTABSPACES( ptri );
  638. if( ISNAME( *ptri ) )
  639. NextName( &ptri, sToken );
  640. else
  641. {
  642. i = 0;
  643. while( *ptri != ' ' && *ptri != '\t' && *ptri != '\0' &&
  644. *ptri != '\"' && *ptri != '\'' && *ptri != '(' &&
  645. !ISNAME(*ptri) )
  646. {
  647. *(sToken+i) = *ptri++;
  648. i++;
  649. }
  650. *(sToken+i) = '\0';
  651. }
  652. HB_SKIPTABSPACES( ptri );
  653. if( ( *ptri == '\0' || ( *ptri != '=' &&
  654. (!IsInStr(*ptri,":/*+-") || *(ptri+1) != '=') &&
  655. ( *ptri != '-' || *(ptri+1) != '>' ) ) )
  656. && ( stcmd = ComSearch(sToken,NULL) ) != NULL )
  657. {
  658. ptro = sOutLine;
  659. i = WorkCommand( ptri, ptro, stcmd );
  660. ptri = sLine + isdvig;
  661. if( ipos > 0 ) *(ptri+ipos-1) = ';';
  662. if( i >= 0 )
  663. {
  664. if( isdvig + ipos > 0 )
  665. {
  666. lens = strlen( sLine+isdvig );
  667. hb_pp_Stuff( ptro, sLine+isdvig, i, (ipos)? ipos-1:lens, lens );
  668. if( ipos > 0 ) ipos = i + 1;
  669. }
  670. else
  671. memcpy( sLine, sOutLine, i+1);
  672. }
  673. rezCom = 1;
  674. }
  675. else if( ipos > 0 ) *(sLine+isdvig+ipos-1) = ';';
  676. }
  677. else if( ipos > 0 )
  678. *(sLine+isdvig+ipos-1) = ';';
  679. }
  680. isdvig += ipos;
  681. }
  682. while( ipos != 0 );
  683. kolpass++;
  684. if( kolpass > 20 && rezDef )
  685. {
  686. hb_compGenError( hb_pp_szErrors, 'F', ERR_RECURSE, NULL, NULL );
  687. break;
  688. }
  689. }
  690. while( rezDef || rezTra || rezCom );
  691. return 0;
  692. }
  693. static int WorkDefine( char ** ptri, char * ptro, DEFINES * stdef )
  694. {
  695. int npars, lens;
  696. char * ptr;
  697. HB_TRACE(HB_TR_DEBUG, ("WorkDefine(%p, %s, %p)", ptri, ptro, stdef));
  698. if( stdef->npars < 0 )
  699. lens = hb_pp_strocpy( ptro,stdef->value );
  700. else
  701. {
  702. HB_SKIPTABSPACES( *ptri );
  703. if( **ptri == '(' )
  704. {
  705. npars = 0; ptr = *ptri;
  706. do
  707. {
  708. ptr++;
  709. if( NextParm( &ptr, NULL ) > 0 ) npars++;
  710. }
  711. while( *ptr != ')' && *ptr != '\0' );
  712. if( *ptr == ')' && stdef->npars == npars )
  713. lens = WorkPseudoF( ptri, ptro, stdef );
  714. else return -1;
  715. }
  716. else return -1;
  717. }
  718. return lens;
  719. }
  720. static int WorkPseudoF( char ** ptri, char * ptro, DEFINES * stdef )
  721. {
  722. char parfict[ MAX_NAME ], * ptrreal;
  723. char * ptrb;
  724. int ipos, ifou, ibeg;
  725. int lenfict, lenreal, lenres;
  726. HB_TRACE(HB_TR_DEBUG, ("WorkPseudoF(%p, %s, %p)", ptri, ptro, stdef));
  727. lenres = hb_pp_strocpy( ptro, stdef->value ); /* Copying value of macro to destination string */
  728. if( stdef->pars )
  729. {
  730. ipos = 0; ibeg = 0;
  731. do /* Parsing through parameters */
  732. { /* in macro definition */
  733. if( *(stdef->pars+ipos) == ',' || *(stdef->pars+ipos) == '\0' )
  734. {
  735. *(parfict+ipos-ibeg) = '\0';
  736. lenfict = ipos - ibeg;
  737. if( **ptri != ')' )
  738. {
  739. (*ptri)++; /* Get next real parameter */
  740. HB_SKIPTABSPACES( *ptri );
  741. ptrreal = *ptri;
  742. lenreal = NextParm( ptri, NULL);
  743. ptrb = ptro;
  744. while( (ifou = hb_strAt( parfict, lenfict, ptrb, lenres-(ptrb-ptro) )) > 0 )
  745. {
  746. ptrb = ptrb+ifou-1;
  747. if( !ISNAME(*(ptrb-1)) && !ISNAME(*(ptrb+lenfict)) )
  748. {
  749. hb_pp_Stuff( ptrreal, ptrb, lenreal, lenfict, lenres );
  750. lenres += lenreal - lenfict;
  751. ptrb += lenreal;
  752. }
  753. else ptrb++;
  754. }
  755. ibeg = ipos+1;
  756. }
  757. }
  758. else *(parfict+ipos-ibeg) = *(stdef->pars+ipos);
  759. if( *(stdef->pars+ipos) == '\0' ) break;
  760. ipos++;
  761. }
  762. while( 1 );
  763. }
  764. else while( **ptri != ')' ) (*ptri)++;
  765. (*ptri)++;
  766. return lenres;
  767. }
  768. static int WorkCommand( char * ptri, char * ptro, COMMANDS * stcmd )
  769. {
  770. int rez;
  771. int lenres;
  772. char * ptrmp;
  773. char * sToken = stcmd->name;
  774. HB_TRACE(HB_TR_DEBUG, ("WorkCommand(%s, %s, %p)", ptri, ptro, stcmd));
  775. do
  776. {
  777. lenres = hb_pp_strocpy( ptro, stcmd->value ); /* Copying result pattern */
  778. ptrmp = stcmd->mpatt; /* Pointer to a match pattern */
  779. s_Repeate = 0;
  780. s_groupchar = '@';
  781. rez = CommandStuff( ptrmp, ptri, ptro, &lenres, TRUE, stcmd->com_or_xcom );
  782. stcmd = stcmd->last;
  783. if( rez < 0 && stcmd != NULL ) stcmd = ComSearch(sToken, stcmd);
  784. }
  785. while( rez < 0 && stcmd != NULL );
  786. *(ptro+lenres) = '\0';
  787. if( rez >= 0 ) return lenres;
  788. return -1;
  789. }
  790. static int WorkTranslate( char * ptri, char * ptro, COMMANDS * sttra, int * lens )
  791. {
  792. int rez;
  793. int lenres;
  794. char * ptrmp;
  795. char * sToken = sttra->name;
  796. HB_TRACE(HB_TR_DEBUG, ("WorkTranslate(%s, %s, %p, %p)", ptri, ptro, sttra, lens));
  797. do
  798. {
  799. lenres = hb_pp_strocpy( ptro, sttra->value );
  800. ptrmp = sttra->mpatt;
  801. s_Repeate = 0;
  802. s_groupchar = '@';
  803. rez = CommandStuff( ptrmp, ptri, ptro, &lenres, FALSE, sttra->com_or_xcom );
  804. sttra = sttra->last;
  805. if( rez < 0 && sttra != NULL ) sttra = TraSearch(sToken, sttra);
  806. }
  807. while( rez < 0 && sttra != NULL );
  808. *(ptro+lenres) = '\0';
  809. if( rez >= 0 )
  810. {
  811. *lens = rez;
  812. return lenres;
  813. }
  814. return -1;
  815. }
  816. static int CommandStuff( char * ptrmp, char * inputLine, char * ptro, int * lenres, BOOL com_or_tra, BOOL com_or_xcom )
  817. {
  818. BOOL endTranslation = FALSE;
  819. int ipos;
  820. char * lastopti[ 3 ], * strtopti = NULL, * strtptri = NULL;
  821. char * ptri = inputLine, * ptr, tmpname[ MAX_NAME ];
  822. HB_TRACE(HB_TR_DEBUG, ("CommandStuff(%s, %s, %s, %p, %d, %d)", ptrmp, inputLine, ptro, lenres, com_or_tra, com_or_xcom));
  823. s_numBrackets = 0;
  824. HB_SKIPTABSPACES( ptri );
  825. if( ptrmp == NULL ) { if( *ptri != '\0' ) return -1; }
  826. else
  827. while( *ptri != '\0' && !endTranslation )
  828. {
  829. HB_SKIPTABSPACES( ptrmp );
  830. if( *ptrmp == '[' && !s_numBrackets && !strtopti )
  831. strtopti = ptrmp;
  832. if( !s_numBrackets && strtopti && strtptri != ptri &&
  833. ( ISNAME( *ptri ) || *ptri=='&' ) )
  834. {
  835. strtptri = ptri;
  836. ptrmp = strtopti;
  837. ptr = ptri;
  838. ipos = NextName( &ptr, tmpname );
  839. ipos = md_strAt( tmpname, ipos, strtopti, TRUE, TRUE );
  840. if( ipos && TestOptional( strtopti, strtopti+ipos-2 ) )
  841. {
  842. ptr = strtopti+ipos-2;
  843. ptr = PrevSquare( ptr, strtopti, NULL );
  844. if( ptr )
  845. ptrmp = ptr;
  846. }
  847. }
  848. switch( *ptrmp ) {
  849. case '[':
  850. s_numBrackets++;
  851. s_aIsRepeate[ s_Repeate ] = 0;
  852. lastopti[s_Repeate++] = ptrmp;
  853. ptrmp++;
  854. if( !CheckOptional( ptrmp, ptri, ptro, lenres, com_or_tra, com_or_xcom ) )
  855. SkipOptional( &ptrmp );
  856. break;
  857. case ']':
  858. if( s_Repeate )
  859. {
  860. s_Repeate--;
  861. if( s_aIsRepeate[ s_Repeate ] )
  862. {
  863. if( ISNAME(*ptri) )
  864. {
  865. ptr = ptri;
  866. ipos = NextName( &ptr, tmpname );
  867. ipos = md_strAt( tmpname, ipos, ptrmp, TRUE, TRUE );
  868. if( ipos && TestOptional( ptrmp+1, ptrmp+ipos-2 ) )
  869. {
  870. ptr = PrevSquare( ptrmp+ipos-2, ptrmp+1, NULL );
  871. if( !ptr || CheckOptional( ptrmp+1, ptri, ptro, lenres, com_or_tra, com_or_xcom ) )
  872. {
  873. ptrmp = lastopti[s_Repeate];
  874. ptrmp++;
  875. s_Repeate++;
  876. SkipOptional( &ptrmp );
  877. s_numBrackets++;
  878. ptrmp++;
  879. strtptri = ptri;
  880. }
  881. else
  882. ptrmp = lastopti[s_Repeate];
  883. }
  884. else
  885. ptrmp = lastopti[s_Repeate];
  886. }
  887. else
  888. ptrmp = lastopti[s_Repeate];
  889. }
  890. else ptrmp++;
  891. s_numBrackets--;
  892. }
  893. else { s_numBrackets--; ptrmp++; }
  894. break;
  895. case ',':
  896. if( !s_numBrackets ) strtopti = NULL;
  897. if( *ptri == ',' ) { ptrmp++; ptri++; }
  898. else
  899. {
  900. if( s_numBrackets )
  901. {
  902. SkipOptional( &ptrmp );
  903. }
  904. else return -1;
  905. }
  906. break;
  907. case '\1': /* Match marker */
  908. if( !s_numBrackets ) strtopti = NULL;
  909. if( !WorkMarkers( &ptrmp, &ptri, ptro, lenres, com_or_xcom ) )
  910. {
  911. if( s_numBrackets )
  912. {
  913. SkipOptional( &ptrmp );
  914. }
  915. else return -1;
  916. }
  917. break;
  918. case '\0':
  919. if( com_or_tra )
  920. return -1;
  921. else endTranslation = TRUE;
  922. break;
  923. default: /* Key word */
  924. if( !s_numBrackets ) strtopti = NULL;
  925. ptr = ptri;
  926. if( *ptri == ',' || truncmp( &ptri, &ptrmp, !com_or_xcom ) )
  927. {
  928. ptri = ptr;
  929. if( s_numBrackets )
  930. {
  931. SkipOptional( &ptrmp );
  932. }
  933. else return -1;
  934. }
  935. }
  936. HB_SKIPTABSPACES( ptri );
  937. };
  938. if( *ptrmp != '\0' )
  939. {
  940. if( s_Repeate ) { s_Repeate = 0; ptrmp = lastopti[0]; }
  941. s_numBrackets = 0;
  942. do
  943. {
  944. HB_SKIPTABSPACES( ptrmp );
  945. if( *ptrmp != '\0' )
  946. switch( *ptrmp ) {
  947. case '[':
  948. ptrmp++;
  949. SkipOptional( &ptrmp );
  950. ptrmp++;
  951. break;
  952. case ']': ptrmp++; break;
  953. default:
  954. return -1;
  955. }
  956. }
  957. while( *ptrmp != '\0' );
  958. }
  959. SearnRep( "\1","",0,ptro,lenres);
  960. *(ptro + *lenres) = '\0';
  961. *lenres = RemoveSlash( ptro ); /* Removing '\' from result string */
  962. if( com_or_tra ) return 1; else return (ptri-inputLine);
  963. }
  964. static int RemoveSlash( char * stroka )
  965. {
  966. char *ptr = stroka;
  967. int State = STATE_INIT;
  968. BOOL bDirective = FALSE;
  969. int lenres = strlen( stroka );
  970. HB_TRACE(HB_TR_DEBUG, ("RemoveSlash(%s)", stroka));
  971. while( *ptr != '\0' )
  972. {
  973. switch( State ) {
  974. case STATE_INIT:
  975. if( *ptr != ' ' && *ptr != '\t' ) State = STATE_NORMAL;
  976. if( *ptr == '#' ) bDirective = TRUE;
  977. case STATE_NORMAL:
  978. if( *ptr == '\'' ) State = STATE_QUOTE1;
  979. else if( *ptr == '\"' ) State = STATE_QUOTE2;
  980. else if( *ptr == ';' )
  981. {
  982. State = STATE_INIT;
  983. bDirective = FALSE;
  984. }
  985. else if( !bDirective )
  986. {
  987. if( *ptr == '\\' && ( *(ptr+1) == '[' || *(ptr+1) == ']' ||
  988. *(ptr+1) == '{' || *(ptr+1) == '}' || *(ptr+1) == '<' ||
  989. *(ptr+1) == '>' || *(ptr+1) == '\'' || *(ptr+1) == '\"' ) )
  990. {
  991. hb_pp_Stuff( "", ptr, 0, 1, lenres - (ptr - stroka) );
  992. lenres--;
  993. ptr++;
  994. }
  995. }
  996. break;
  997. case STATE_QUOTE1:
  998. if( *ptr == '\'' ) State = STATE_NORMAL;
  999. break;
  1000. case STATE_QUOTE2:
  1001. if( *ptr == '\"' ) State = STATE_NORMAL;
  1002. break;
  1003. }
  1004. ptr++;
  1005. }
  1006. return lenres;
  1007. }
  1008. static int WorkMarkers( char ** ptrmp, char ** ptri, char * ptro, int * lenres, BOOL com_or_xcom )
  1009. {
  1010. static char expreal[ MAX_EXP ];
  1011. char exppatt[ MAX_NAME ];
  1012. int lenreal = 0, maxlenreal = HB_PP_STR_SIZE, lenpatt;
  1013. int rezrestr, ipos;
  1014. char * ptr, * ptrtemp;
  1015. HB_TRACE(HB_TR_DEBUG, ("WorkMarkers(%p, %p, %s, %p)", ptrmp, ptri, ptro, lenres));
  1016. /* Copying a match pattern to 'exppatt' */
  1017. lenpatt = stroncpy( exppatt, *ptrmp, 4 );
  1018. *ptrmp += 4;
  1019. HB_SKIPTABSPACES( *ptrmp );
  1020. if( **ptri == ',' )
  1021. {
  1022. if( s_numBrackets )
  1023. {
  1024. return 0;
  1025. }
  1026. }
  1027. ptrtemp = *ptrmp;
  1028. if( *(exppatt+2) != '2' && *ptrtemp == ']' )
  1029. {
  1030. ptrtemp++;
  1031. HB_SKIPTABSPACES( ptrtemp );
  1032. }
  1033. if( *(exppatt+2) != '2' && *ptrtemp != '\1' && *ptrtemp != ',' &&
  1034. *ptrtemp != '[' && *ptrtemp != ']' && *ptrtemp != '\0' )
  1035. {
  1036. lenreal = strincpy( expreal, ptrtemp );
  1037. if( (ipos = md_strAt( expreal, lenreal, *ptri, TRUE, TRUE )) > 0 )
  1038. {
  1039. if( ptrtemp > *ptrmp )
  1040. {
  1041. if( ipos == 1 )
  1042. {
  1043. if( s_numBrackets )
  1044. {
  1045. return 0;
  1046. }
  1047. }
  1048. else
  1049. {
  1050. maxlenreal = ipos - 1;
  1051. lenreal = 0;
  1052. }
  1053. }
  1054. else
  1055. {
  1056. lenreal = stroncpy( expreal, *ptri, ipos-1 );
  1057. if( ipos > 1 && isExpres( expreal ) )
  1058. *ptri += lenreal;
  1059. else
  1060. {
  1061. if( s_numBrackets )
  1062. {
  1063. return 0;
  1064. }
  1065. else lenreal = 0;
  1066. }
  1067. }
  1068. }
  1069. else
  1070. {
  1071. if( s_numBrackets )
  1072. {
  1073. return 0;
  1074. }
  1075. else lenreal = 0;
  1076. }
  1077. }
  1078. if( *(exppatt+2) == '4' ) /* ---- extended match marker */
  1079. {
  1080. if( !lenreal ) lenreal = getExpReal( expreal, ptri, FALSE, maxlenreal );
  1081. SearnRep( exppatt,expreal,lenreal,ptro,lenres);
  1082. }
  1083. else if( *(exppatt+2) == '3' ) /* ---- wild match marker */
  1084. {
  1085. lenreal = hb_pp_strocpy( expreal, *ptri );
  1086. *ptri += lenreal;
  1087. SearnRep( exppatt,expreal,lenreal,ptro,lenres);
  1088. }
  1089. else if( *(exppatt+2) == '2' ) /* ---- restricted match marker */
  1090. {
  1091. while( **ptrmp != '>' ) *(exppatt+lenpatt++) = *((*ptrmp)++);
  1092. *(exppatt+lenpatt) = '\0';
  1093. (*ptrmp)++;
  1094. ptr = exppatt + 4;
  1095. rezrestr = 0;
  1096. while( *ptr != '\0' )
  1097. {
  1098. if( *ptr == '&' )
  1099. {
  1100. if( **ptri == '&' )
  1101. {
  1102. rezrestr = 1;
  1103. /* (*ptri)++; */
  1104. lenreal = getExpReal( expreal, ptri, FALSE, maxlenreal );
  1105. SearnRep( exppatt,expreal,lenreal,ptro,lenres);
  1106. break;
  1107. }
  1108. else ptr++;
  1109. }
  1110. else
  1111. {
  1112. HB_SKIPTABSPACES( ptr );
  1113. /* Comparing real parameter and restriction value */
  1114. ptrtemp = ptr;
  1115. if( !strincmp( *ptri, &ptr, !com_or_xcom ) )
  1116. {
  1117. lenreal = stroncpy( expreal, *ptri, (ptr-ptrtemp) );
  1118. *ptri += lenreal;
  1119. SearnRep( exppatt,expreal,lenreal,ptro,lenres);
  1120. rezrestr = 1;
  1121. break;
  1122. }
  1123. else
  1124. {
  1125. while( *ptr != ',' && *ptr != '\0' ) ptr++;
  1126. if( *ptr == ',' ) ptr++;
  1127. }
  1128. }
  1129. }
  1130. if( rezrestr == 0 )
  1131. { /* If restricted match marker doesn't correspond to real parameter */
  1132. if( s_numBrackets )
  1133. {
  1134. return 0;
  1135. }
  1136. else return 0;
  1137. }
  1138. }
  1139. else if( *(exppatt+2) == '1' ) /* ---- list match marker */
  1140. {
  1141. if( !lenreal ) lenreal = getExpReal( expreal, ptri, TRUE, maxlenreal );
  1142. SearnRep( exppatt,expreal,lenreal,ptro,lenres);
  1143. }
  1144. else /* ---- regular match marker */
  1145. {
  1146. /* Copying a real expression to 'expreal' */
  1147. if( !lenreal ) lenreal = getExpReal( expreal, ptri, FALSE, maxlenreal );
  1148. SearnRep( exppatt,expreal,lenreal,ptro,lenres);
  1149. }
  1150. return 1;
  1151. }
  1152. static int getExpReal( char * expreal, char ** ptri, BOOL prlist, int maxrez )
  1153. {
  1154. int lens = 0;
  1155. char * sZnaki = "+-=><*/$.:#%!^";
  1156. int State;
  1157. int StBr1 = 0, StBr2 = 0, StBr3 = 0;
  1158. BOOL rez = FALSE;
  1159. HB_TRACE(HB_TR_DEBUG, ("getExpReal(%s, %p, %d, %d)", expreal, ptri, prlist, maxrez));
  1160. HB_SKIPTABSPACES( *ptri );
  1161. State = (**ptri=='\'' || **ptri=='\"')? STATE_EXPRES:STATE_ID;
  1162. while( **ptri != '\0' && !rez && lens < maxrez )
  1163. {
  1164. switch( State ) {
  1165. case STATE_QUOTE1:
  1166. if(**ptri=='\'')
  1167. State = (StBr1==0 && StBr2==0 && StBr3==0)? STATE_ID_END:STATE_BRACKET;
  1168. break;
  1169. case STATE_QUOTE2:
  1170. if(**ptri=='\"')
  1171. State = (StBr1==0 && StBr2==0 && StBr3==0)? STATE_ID_END:STATE_BRACKET;
  1172. break;
  1173. case STATE_BRACKET:
  1174. if( **ptri == '\'' ) State = STATE_QUOTE1;
  1175. else if( **ptri == '\"' ) State = STATE_QUOTE2;
  1176. else if( **ptri == '(' ) StBr1++;
  1177. else if( **ptri == '[' ) StBr2++;
  1178. else if( **ptri == '{' ) StBr3++;
  1179. else if( **ptri == ')' )
  1180. { StBr1--; if (StBr1==0 && StBr2==0 && StBr3==0) State = STATE_ID_END; }
  1181. else if( **ptri == ']' )
  1182. { StBr2--; if (StBr1==0 && StBr2==0 && StBr3==0) State = STATE_ID_END; }
  1183. else if( **ptri == '}' )
  1184. { StBr3--; if (StBr1==0 && StBr2==0 && StBr3==0) State = STATE_ID_END; }
  1185. break;
  1186. case STATE_ID:
  1187. case STATE_ID_END:
  1188. if( ( (ISNAME(**ptri) || **ptri=='\\' || **ptri=='&') && State == STATE_ID_END ) ||
  1189. **ptri==',' || **ptri=='\'' || **ptri=='\"' || **ptri==')' )
  1190. {
  1191. if( **ptri == ',' )
  1192. {
  1193. if( !prlist ) rez = TRUE;
  1194. State = STATE_EXPRES;
  1195. }
  1196. else rez = TRUE;
  1197. }
  1198. else if( IsInStr( **ptri, sZnaki ) )
  1199. {
  1200. State = STATE_EXPRES;
  1201. }
  1202. else if( **ptri == '(' )
  1203. {
  1204. State = STATE_BRACKET;
  1205. StBr1 = 1;
  1206. }
  1207. else if( **ptri == '[' )
  1208. {
  1209. State = STATE_BRACKET;
  1210. StBr2 = 1;
  1211. }
  1212. else if( **ptri == '{' )
  1213. {
  1214. State = STATE_BRACKET;
  1215. StBr3 = 1;
  1216. }
  1217. else if( **ptri == ' ' ) State = STATE_ID_END;
  1218. break;
  1219. case STATE_EXPRES:
  1220. case STATE_EXPRES_ID:
  1221. if( **ptri == '\'' ) State = STATE_QUOTE1;
  1222. else if( **ptri == '\"' ) State = STATE_QUOTE2;
  1223. else if( ISNAME(**ptri) ) State = STATE_EXPRES_ID;
  1224. else if( **ptri == ' ' )
  1225. {
  1226. if( State == STATE_EXPRES_ID ) State = STATE_ID_END;
  1227. else if( lens > 2 && ( ( *(*ptri-2)=='+' && *(*ptri-1)=='+' ) ||
  1228. ( *(*ptri-2)=='-' && *(*ptri-1)=='-' ) ) )
  1229. State = STATE_ID_END;
  1230. }
  1231. else if( **ptri == '(' ) { StBr1++; State = STATE_BRACKET; }
  1232. else if( **ptri == '[' ) { StBr2++; State = STATE_BRACKET; }
  1233. else if( **ptri == '{' ) { StBr3++; State = STATE_BRACKET; }
  1234. else if( **ptri == ',' ) { if ( !prlist ) rez = TRUE; State = STATE_EXPRES; }
  1235. else if( **ptri == '.' && *(*ptri-2) == '.' &&
  1236. ( *(*ptri-1) == 'T' || *(*ptri-1) == 'F' ||
  1237. *(*ptri-1) == 't' || *(*ptri-1) == 'f' ) )
  1238. State = STATE_ID_END;
  1239. else State = STATE_EXPRES;
  1240. break;
  1241. }
  1242. if( !rez )
  1243. {
  1244. if( expreal != NULL ) *expreal++ = **ptri;
  1245. (*ptri)++;
  1246. lens++;
  1247. }
  1248. }
  1249. if( expreal != NULL )
  1250. {
  1251. if( *(expreal-1) == ' ' ) { expreal--; lens--; };
  1252. *expreal = '\0';
  1253. }
  1254. return lens;
  1255. }
  1256. static BOOL isExpres( char * stroka )
  1257. {
  1258. int l1,l2;
  1259. HB_TRACE(HB_TR_DEBUG, ("isExpres(%s)", stroka));
  1260. l1 = strlen( stroka );
  1261. l2 = getExpReal( NULL, &stroka, FALSE, HB_PP_STR_SIZE );
  1262. return ( l1 <= l2 );
  1263. }
  1264. static BOOL TestOptional( char *ptr1, char *ptr2 )
  1265. {
  1266. int nbr = 0;
  1267. BOOL flagname = FALSE;
  1268. int statevar = 0;
  1269. HB_TRACE(HB_TR_DEBUG, ("TestOptional(%s, %s)", ptr1, ptr2));
  1270. while( ptr1 <= ptr2 )
  1271. {
  1272. if( *ptr1 == '[' ) nbr++;
  1273. else if( *ptr1 == ']' )
  1274. {
  1275. if( nbr )
  1276. {
  1277. nbr--;
  1278. flagname = FALSE;
  1279. }
  1280. else return 0;
  1281. }
  1282. else if( *ptr1 == '\1' && *(ptr1+2) == '2' && nbr ) statevar = 1;
  1283. else if( *ptr1 == '>' && statevar ) statevar = 0;
  1284. else if( *ptr1 != ' ' && *ptr1 != '\t' && !statevar )
  1285. {
  1286. if( nbr ) flagname = TRUE;
  1287. else return 0;
  1288. }
  1289. ptr1++;
  1290. }
  1291. /* if( !flagname )
  1292. while( *ptr1 != ']' )
  1293. {
  1294. if( *ptr1 == '[' || *ptr1 == '\0' ) return 0;
  1295. ptr1++;
  1296. } */
  1297. return !flagname;
  1298. }
  1299. static BOOL CheckOptional( char * ptrmp, char * ptri, char * ptro, int * lenres, BOOL com_or_tra, BOOL com_or_xcom )
  1300. {
  1301. int save_numBr = s_numBrackets, save_Repeate = s_Repeate;
  1302. BOOL endTranslation = FALSE;
  1303. BOOL bResult = TRUE;
  1304. char * lastInputptr[ 5 ];
  1305. char * lastopti[ 3 ], *ptr;
  1306. HB_SYMBOL_UNUSED( com_or_tra );
  1307. HB_TRACE(HB_TR_DEBUG, ("CheckOptional(%s, %s, %s, %p, %d, %d)", ptrmp, ptri, ptro, lenres, com_or_tra, com_or_xcom));
  1308. s_bReplacePat = FALSE;
  1309. lastInputptr[s_Repeate] = ptri;
  1310. while( *ptri != '\0' && !endTranslation && bResult )
  1311. {
  1312. HB_SKIPTABSPACES( ptrmp );
  1313. switch( *ptrmp ) {
  1314. case '[':
  1315. s_numBrackets++;
  1316. s_aIsRepeate[ s_Repeate ] = 0;
  1317. lastInputptr[s_Repeate] = ptri;
  1318. lastopti[s_Repeate++] = ptrmp;
  1319. ptrmp++;
  1320. break;
  1321. case ']':
  1322. if( s_numBrackets == save_numBr )
  1323. endTranslation = TRUE;
  1324. else
  1325. {
  1326. if( s_Repeate )
  1327. {
  1328. s_Repeate--;
  1329. ptrmp = lastopti[s_Repeate];
  1330. }
  1331. else ptrmp++;
  1332. s_numBrackets--;
  1333. }
  1334. break;
  1335. case ',':
  1336. if( *ptri == ',' ) { ptrmp++; ptri++; }
  1337. else
  1338. {
  1339. if( s_numBrackets - save_numBr > 0 )
  1340. {
  1341. SkipOptional( &ptrmp );
  1342. ptri = lastInputptr[s_Repeate];
  1343. }
  1344. else bResult = FALSE;
  1345. }
  1346. break;
  1347. case '\1': /* Match marker */
  1348. if( !WorkMarkers( &ptrmp, &ptri, ptro, lenres, com_or_xcom ) )
  1349. {
  1350. if( s_numBrackets - save_numBr > 0 )
  1351. {
  1352. SkipOptional( &ptrmp );
  1353. ptri = lastInputptr[s_Repeate];
  1354. }
  1355. else bResult = FALSE;
  1356. }
  1357. break;
  1358. case '\0':
  1359. bResult = FALSE;
  1360. default: /* Key word */
  1361. ptr = ptri;
  1362. if( *ptri == ',' || truncmp( &ptri, &ptrmp, !com_or_xcom ) )
  1363. {
  1364. ptri = ptr;
  1365. if( s_numBrackets - save_numBr > 0 )
  1366. {
  1367. SkipOptional( &ptrmp );
  1368. ptri = lastInputptr[s_Repeate];
  1369. }
  1370. else bResult = FALSE;
  1371. }
  1372. }
  1373. HB_SKIPTABSPACES( ptri );
  1374. };
  1375. if( *ptri == '\0' )
  1376. {
  1377. do
  1378. {
  1379. HB_SKIPTABSPACES( ptrmp );
  1380. if( *ptrmp == '[' )
  1381. {
  1382. ptrmp++;
  1383. SkipOptional( &ptrmp );
  1384. }
  1385. else if( *ptrmp == ']' )
  1386. break;
  1387. else
  1388. {
  1389. bResult = 0;
  1390. break;
  1391. }
  1392. }
  1393. while( 1 );
  1394. }
  1395. s_Repeate = save_Repeate;
  1396. s_numBrackets = save_numBr;
  1397. s_bReplacePat = TRUE;
  1398. return bResult;
  1399. }
  1400. static void SkipOptional( char ** ptri )
  1401. {
  1402. int nbr = 0;
  1403. HB_TRACE(HB_TR_DEBUG, ("SkipOptional(%p)", ptri));
  1404. while( **ptri != ']' || nbr )
  1405. {
  1406. switch( **ptri ) {
  1407. case '[': nbr++; break;
  1408. case ']': nbr--; break;
  1409. case '\1':
  1410. (*ptri) += 3;
  1411. if( *(*ptri-1) == '2' )
  1412. while( **ptri != '>' ) (*ptri)++;
  1413. break;
  1414. }
  1415. (*ptri)++;
  1416. }
  1417. if( **ptri == ']' && s_numBrackets > 0 )
  1418. {
  1419. if( s_Repeate ) s_Repeate--;
  1420. s_numBrackets--; (*ptri)++;
  1421. }
  1422. }
  1423. static void SearnRep( char * exppatt, char * expreal, int lenreal, char * ptro, int * lenres )
  1424. {
  1425. static char expnew[ MAX_EXP ];
  1426. int ifou, isdvig = 0;
  1427. BOOL rezs;
  1428. int kolmarkers;
  1429. int lennew, i;
  1430. char lastchar = '0';
  1431. char *ptr, *ptr2, *ptrOut = ptro;
  1432. HB_TRACE(HB_TR_DEBUG, ("SearnRep(%s, %s, %d, %s, %p)", exppatt, expreal, lenreal, ptro, lenres));
  1433. if( *(exppatt+1) == '\0' ) *( ptro + *lenres ) = '\0';
  1434. while( (ifou = md_strAt( exppatt, (*(exppatt+1))? 2:1, ptrOut, FALSE, FALSE )) > 0 )
  1435. {
  1436. rezs = FALSE;
  1437. ptr = ptrOut + ifou - 2;
  1438. kolmarkers = 0;
  1439. ptr = PrevSquare( ptr, ptrOut, &kolmarkers );
  1440. if( ptr )
  1441. {
  1442. if( s_Repeate ) s_aIsRepeate[ s_Repeate - 1 ]++;
  1443. if( !s_bReplacePat ) return;
  1444. ptr2 = ptrOut + ifou + 3;
  1445. while( *ptr2 != ']' || *(ptr2-1) == '\\' )
  1446. {
  1447. if( *ptr2 == '\1' ) kolmarkers++;
  1448. ptr2++;
  1449. }
  1450. if( s_Repeate && lenreal && kolmarkers && lastchar != '0' &&
  1451. *(ptrOut + ifou

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