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

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

#
C | 2271 lines | 1786 code | 286 blank | 199 comment | 660 complexity | 26a17f72d5c4b7b4ec0d8994f62e6476 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 6271 2004-04-02 11:14:37Z rglab $
  3. */
  4. /*
  5. * Harbour Project source code:
  6. * Preprocessor core module
  7. *
  8. * Copyright 1999 Alexander S.Kresin <alex@belacy.belgorod.su>
  9. * www - http://www.harbour-project.org
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; either version 2, or (at your option)
  14. * any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this software; see the file COPYING. If not, write to
  23. * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  24. * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/).
  25. *
  26. * As a special exception, the Harbour Project gives permission for
  27. * additional uses of the text contained in its release of Harbour.
  28. *
  29. * The exception is that, if you link the Harbour libraries with other
  30. * files to produce an executable, this does not by itself cause the
  31. * resulting executable to be covered by the GNU General Public License.
  32. * Your use of that executable is in no way restricted on account of
  33. * linking the Harbour library code into it.
  34. *
  35. * This exception does not however invalidate any other reasons why
  36. * the executable file might be covered by the GNU General Public License.
  37. *
  38. * This exception applies only to the code released by the Harbour
  39. * Project under the name Harbour. If you copy code from other
  40. * Harbour Project or Free Software Foundation releases into a copy of
  41. * Harbour, as the General Public License permits, the exception does
  42. * not apply to the code that you add in this way. To avoid misleading
  43. * anyone as to the status of such modified files, you must delete
  44. * this exception notice from them.
  45. *
  46. * If you write modifications of your own for Harbour, it is your choice
  47. * whether to permit this exception to apply to your modifications.
  48. * If you do not wish that, delete this exception notice.
  49. *
  50. */
  51. /*
  52. * The following parts are Copyright of the individual authors.
  53. * www - http://www.harbour-project.org
  54. *
  55. * Copyright 1999-2001 Viktor Szakats <viktor.szakats@syenar.hu>
  56. * __DATE__, __TIME__, __HB_MAIN__ support
  57. *
  58. * Copyright 2000 Ron Pinkas <Ron@Profit-Master.com>
  59. *
  60. * hb_pp_SetRules() and related code for supportting
  61. * replaceable rules with -w switch
  62. *
  63. * See doc/license.txt for licensing terms.
  64. *
  65. */
  66. /*
  67. * Avoid tracing in preprocessor/compiler.
  68. */
  69. #if ! defined(HB_TRACE_UTILS)
  70. #if defined(HB_TRACE_LEVEL)
  71. #undef HB_TRACE_LEVEL
  72. #endif
  73. #endif
  74. #include <time.h>
  75. #include <errno.h>
  76. #include "hbpp.h"
  77. #include "hbcomp.h"
  78. #if defined( OS_UNIX_COMPATIBLE )
  79. #include <sys/timeb.h>
  80. #else
  81. #include <sys\timeb.h>
  82. #endif
  83. int hb_pp_ParseDefine( char * ); /* Process #define directive */
  84. static COMMANDS * AddCommand( char * ); /* Add new #command to an array */
  85. static COMMANDS * AddTranslate( char * ); /* Add new #translate to an array */
  86. static DEFINES * DefSearch( char *, BOOL * );
  87. static COMMANDS * ComSearch( char *, COMMANDS * );
  88. static COMMANDS * TraSearch( char *, COMMANDS * );
  89. static int ParseUndef( char * ); /* Process #undef directive */
  90. static int ParseIfdef( char *, int ); /* Process #ifdef directive */
  91. static void ParseCommand( char *, BOOL, BOOL ); /* Process #command or #translate directive */
  92. static void ConvertPatterns( char *, int, char *, int ); /* Converting result pattern in #command and #translate */
  93. static int WorkDefine( char **, char *, DEFINES * ); /* Replace fragment of code with a #defined result text */
  94. static int WorkPseudoF( char **, char *, DEFINES * ); /* Replace pseudofunction with a #defined result text */
  95. static int WorkCommand( char *, char *, COMMANDS * );
  96. static int WorkTranslate( char *, char *, COMMANDS *, int * );
  97. static int CommandStuff( char *, char *, char *, int *, BOOL, BOOL );
  98. static int RemoveSlash( char * );
  99. static int WorkMarkers( char **, char **, char *, int *, BOOL );
  100. static int getExpReal( char *, char **, BOOL, int, BOOL );
  101. static BOOL isExpres( char *, BOOL );
  102. static BOOL TestOptional( char *, char * );
  103. static BOOL CheckOptional( char *, char *, char *, int *, BOOL, BOOL );
  104. static void SkipOptional( char ** );
  105. static void SearnRep( char *, char *, int, char *, int * );
  106. static int ReplacePattern( char, char *, int, char *, int );
  107. static void pp_rQuotes( char *, char * );
  108. static int md_strAt( char *, int, char *, BOOL, BOOL, BOOL );
  109. static char * PrevSquare( char * , char *, int * );
  110. static int IsInStr( char, char * );
  111. static int stroncpy( char *, char *, int );
  112. static int strincpy( char *, char * );
  113. static BOOL truncmp( char **, char **, BOOL );
  114. static BOOL strincmp( char *, char **, BOOL );
  115. static int strotrim( char *, BOOL ); /* Ron Pinkas 2001-02-14 added 2nd parameter */
  116. static int NextWord( char **, char *, BOOL );
  117. static int NextName( char **, char * );
  118. static int NextParm( char **, char * );
  119. static BOOL OpenInclude( char *, HB_PATHNAMES *, PHB_FNAME, BOOL bStandardOnly, char * );
  120. static BOOL IsIdentifier( char *szProspect );
  121. #define ISNAME( c ) ( isalnum( ( int ) c ) || ( c ) == '_' || ( c ) > 0x7E )
  122. #define MAX_NAME 255
  123. #define MAX_EXP 2048
  124. #define PATTERN_SIZE 2048
  125. #define STATE_INIT 0
  126. #define STATE_NORMAL 1
  127. #define STATE_COMMENT 2
  128. #define STATE_QUOTE1 3
  129. #define STATE_QUOTE2 4
  130. #define STATE_QUOTE3 5
  131. #define STATE_ID_END 6
  132. #define STATE_ID 7
  133. #define STATE_EXPRES 8
  134. #define STATE_EXPRES_ID 9
  135. #define STATE_BRACKET 10
  136. #define IT_EXPR 1
  137. #define IT_ID 2
  138. #define IT_COMMA 3
  139. #define IT_ID_OR_EXPR 4
  140. #define HB_PP_MAX_INCLUDES FOPEN_MAX - 5 - 1
  141. /* Ron Pinkas added 2000-01-24 */
  142. #define IS_2CHAR_OPERATOR( p ) ( p[0] && p[1] && ( strncmp( p, ":=", 2 ) == 0 || \
  143. strncmp( p, "+=", 2 ) == 0 || \
  144. strncmp( p, "-=", 2 ) == 0 || \
  145. strncmp( p, "*=", 2 ) == 0 || \
  146. strncmp( p, "/=", 2 ) == 0 || \
  147. strncmp( p, "^=", 2 ) == 0 || \
  148. strncmp( p, "==", 2 ) == 0 || \
  149. strncmp( p, "<>", 2 ) == 0 || \
  150. strncmp( p, "<=", 2 ) == 0 || \
  151. strncmp( p, ">=", 2 ) == 0 || \
  152. strncmp( p, "++", 2 ) == 0 || \
  153. strncmp( p, "--", 2 ) == 0 || \
  154. strncmp( p, "->", 2 ) == 0 ) )
  155. /* END, Ron Pinkas added 2000-01-24 */
  156. static int s_kolAddDefs = 0;
  157. static int s_kolAddComs = 0;
  158. static int s_kolAddTras = 0;
  159. static int s_ParseState;
  160. static int s_maxCondCompile;
  161. static int s_aIsRepeate[ 5 ];
  162. static int s_Repeate;
  163. static BOOL s_bReplacePat = TRUE;
  164. static int s_numBrackets;
  165. static char s_groupchar;
  166. static char s_prevchar;
  167. int * hb_pp_aCondCompile = NULL;
  168. int hb_pp_nCondCompile = 0;
  169. BOOL hb_ppInsideTextBlock = FALSE;
  170. BOOL hb_ppNestedLiteralString = FALSE;
  171. char * hb_pp_STD_CH = NULL;
  172. /* Ron Pinkas added 2000-11-21 */
  173. static BOOL s_bArray = FALSE;
  174. #if defined(__WATCOMC__)
  175. extern BOOL hb_pp_bInline;
  176. extern int hb_pp_LastOutLine;
  177. #endif
  178. /* Table with parse errors */
  179. char * hb_pp_szErrors[] =
  180. {
  181. "Can\'t open #include file: \'%s\'; %s",
  182. "#else does not match #ifdef",
  183. "#endif does not match #ifdef",
  184. "Bad filename in #include",
  185. "#define without parameters",
  186. "Missing => in #translate/#command \'%s\' [%s]'",
  187. "Error in pattern definition",
  188. "Cycled #define",
  189. "Invalid name follows #: \'%s\'",
  190. "\'%s\'",
  191. "Memory allocation error",
  192. "Memory reallocation error",
  193. "Freeing a NULL memory pointer",
  194. "Value out of range in #pragma directive",
  195. "Can\'t open command definitions file: \'%s\'",
  196. "Invalid command definitions file name: \'%s\'",
  197. "Too many nested #includes, can\'t open: \'%s\'",
  198. "Input buffer overflow",
  199. "Label missing in #define '%s'",
  200. "Comma or right parenthesis missing in #define '%s'",
  201. "Label duplicated in #define '%s(%s)'",
  202. };
  203. /* Table with warnings */
  204. char * hb_pp_szWarnings[] =
  205. {
  206. "1Redefinition or duplicate definition of #define %s",
  207. "1No directives in command definitions file"
  208. };
  209. void hb_pp_SetRules( HB_INCLUDE_FUNC_PTR hb_compInclude, BOOL hb_comp_bQuiet )
  210. {
  211. HB_TRACE(HB_TR_DEBUG, ("hb_pp_SetRules()"));
  212. if( hb_pp_STD_CH )
  213. {
  214. if( *hb_pp_STD_CH > ' ' )
  215. {
  216. hb_comp_pFileName = hb_fsFNameSplit( hb_pp_STD_CH );
  217. if( hb_comp_pFileName->szName )
  218. {
  219. char szFileName[ _POSIX_PATH_MAX ];
  220. if( ! hb_comp_pFileName->szExtension )
  221. hb_comp_pFileName->szExtension = ".ch";
  222. hb_fsFNameMerge( szFileName, hb_comp_pFileName );
  223. if( (* hb_compInclude)( szFileName, hb_comp_pIncludePath ) )
  224. {
  225. /*
  226. printf( "Loading Standard Rules from: \'%s\'\n", szFileName );
  227. */
  228. hb_pp_Init();
  229. hb_pp_ReadRules();
  230. /*
  231. {
  232. COMMANDS * stcmd;
  233. DEFINES * stdef;
  234. stcmd = hb_pp_topCommand;
  235. while ( stcmd )
  236. {
  237. printf( "Command: %s Pattern: %s\n", stcmd->name, stcmd->mpatt );
  238. stcmd = stcmd->last;
  239. }
  240. stcmd = hb_pp_topTranslate;
  241. while ( stcmd )
  242. {
  243. printf( "Translate: %s \nPattern: %s\n", stcmd->name, stcmd->mpatt );
  244. stcmd = stcmd->last;
  245. }
  246. stdef = hb_pp_topDefine;
  247. while ( stdef && s_kolAddDefs > 3 )
  248. {
  249. printf( "Define: %s Value: %s\n", stdef->name, stdef->value );
  250. stdef = stdef->last;
  251. s_kolAddDefs--;
  252. }
  253. }
  254. */
  255. if ( s_kolAddComs || s_kolAddTras || s_kolAddDefs > 3 )
  256. {
  257. if( ! hb_comp_bQuiet )
  258. printf( "Loaded: %i Commands, %i Translates, %i Defines from: %s\n", s_kolAddComs, s_kolAddTras, s_kolAddDefs - 3, szFileName );
  259. }
  260. else
  261. {
  262. hb_compGenWarning( hb_pp_szWarnings, 'I', HB_PP_WARN_NO_DIRECTIVES, NULL /*szFileName*/, NULL );
  263. }
  264. fclose( hb_comp_files.pLast->handle );
  265. hb_xfree( hb_comp_files.pLast->pBuffer );
  266. hb_xfree( hb_comp_files.pLast );
  267. hb_comp_files.pLast = NULL;
  268. hb_comp_files.iFiles = 0;
  269. hb_xfree( ( void * ) hb_comp_pFileName );
  270. hb_comp_pFileName = NULL;
  271. s_kolAddComs = 0;
  272. s_kolAddTras = 0;
  273. s_kolAddDefs = 0;
  274. }
  275. else
  276. {
  277. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_CANNOT_OPEN_RULES, szFileName, NULL );
  278. }
  279. }
  280. else
  281. {
  282. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_BAD_RULES_FILE_NAME, hb_pp_STD_CH, NULL );
  283. }
  284. }
  285. else
  286. {
  287. if( ! hb_comp_bQuiet )
  288. printf( "Standard command definitions excluded.\n" );
  289. hb_pp_Init();
  290. }
  291. }
  292. else
  293. {
  294. hb_pp_Table();
  295. hb_pp_Init();
  296. }
  297. }
  298. void hb_pp_Free( void )
  299. {
  300. DEFINES * stdef;
  301. COMMANDS * stcmd;
  302. HB_TRACE(HB_TR_DEBUG, ("hb_pp_Free()"));
  303. while( s_kolAddDefs )
  304. {
  305. stdef = hb_pp_topDefine;
  306. if( stdef->pars ) hb_xfree( stdef->pars );
  307. if( stdef->value ) hb_xfree( stdef->value );
  308. if( stdef->name ) hb_xfree( stdef->name );
  309. hb_pp_topDefine = stdef->last;
  310. hb_xfree( stdef );
  311. s_kolAddDefs--;
  312. }
  313. while( s_kolAddComs )
  314. {
  315. stcmd = hb_pp_topCommand;
  316. if( stcmd->mpatt ) hb_xfree( stcmd->mpatt );
  317. if( stcmd->value ) hb_xfree( stcmd->value );
  318. hb_xfree( stcmd->name );
  319. hb_pp_topCommand = stcmd->last;
  320. hb_xfree( stcmd );
  321. s_kolAddComs--;
  322. }
  323. while( s_kolAddTras )
  324. {
  325. stcmd = hb_pp_topTranslate;
  326. if( stcmd->mpatt ) hb_xfree( stcmd->mpatt );
  327. if( stcmd->value ) hb_xfree( stcmd->value );
  328. hb_xfree( stcmd->name );
  329. hb_pp_topTranslate = stcmd->last;
  330. hb_xfree( stcmd );
  331. s_kolAddTras--;
  332. }
  333. }
  334. void hb_pp_Init( void )
  335. {
  336. HB_TRACE(HB_TR_DEBUG, ("hb_pp_Init()"));
  337. hb_pp_Free();
  338. s_ParseState = 0;
  339. s_maxCondCompile = 5;
  340. s_bReplacePat = TRUE;
  341. s_prevchar = 'A';
  342. if( !hb_pp_aCondCompile )
  343. hb_pp_aCondCompile = ( int * ) hb_xgrab( sizeof( int ) * 5 );
  344. hb_pp_nCondCompile = 0;
  345. {
  346. char szResult[ 6 ];
  347. USHORT usHarbour = ( 256 * HB_VER_MAJOR ) + HB_VER_MINOR;
  348. /*
  349. This updates __HARBOUR__ on every change of HB_VER_MAJOR / HB_VER_MINOR
  350. HIBYTE is the HB_VER_MAJOR value and the LOBYTE is the HB_VER_MINOR value.
  351. The check below is to ensure that __HARBOUR__ gets the
  352. value of 1 by default
  353. */
  354. sprintf( szResult, "%05d", ( usHarbour ? usHarbour : 1 ) );
  355. hb_pp_AddDefine( "__HARBOUR__", szResult );
  356. }
  357. {
  358. char szResult[ 11 ];
  359. time_t t;
  360. struct tm * oTime;
  361. time( &t );
  362. oTime = localtime( &t );
  363. sprintf( szResult, "\"%04d%02d%02d\"", oTime->tm_year + 1900, oTime->tm_mon + 1, oTime->tm_mday );
  364. hb_pp_AddDefine( "__DATE__", szResult );
  365. sprintf( szResult, "\"%02d:%02d:%02d\"", oTime->tm_hour, oTime->tm_min, oTime->tm_sec );
  366. hb_pp_AddDefine( "__TIME__", szResult );
  367. }
  368. #ifdef HARBOUR_START_PROCEDURE
  369. hb_pp_AddDefine( "__HB_MAIN__", HARBOUR_START_PROCEDURE );
  370. #endif
  371. }
  372. /* Table with parse warnings */
  373. /* NOTE: The first character stores the warning's level that triggers this
  374. * warning. The warning's level is set by -w<n> command line option.
  375. */
  376. int hb_pp_ParseDirective( char * sLine )
  377. {
  378. char sDirective[ MAX_NAME ];
  379. char szInclude[ _POSIX_PATH_MAX ];
  380. int i;
  381. HB_TRACE(HB_TR_DEBUG, ("hb_pp_ParseDirective(%s)", sLine));
  382. i = NextName( &sLine, sDirective );
  383. hb_strupr( sDirective );
  384. HB_SKIPTABSPACES(sLine);
  385. if( i == 4 && memcmp( sDirective, "ELSE", 4 ) == 0 )
  386. { /* --- #else --- */
  387. if( hb_pp_nCondCompile == 0 )
  388. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_DIRECTIVE_ELSE, NULL, NULL );
  389. else if( hb_pp_nCondCompile == 1 || hb_pp_aCondCompile[hb_pp_nCondCompile-2] )
  390. hb_pp_aCondCompile[hb_pp_nCondCompile-1] = 1 - hb_pp_aCondCompile[hb_pp_nCondCompile-1];
  391. }
  392. else if( i >= 4 && i <= 5 && memcmp( sDirective, "ENDIF", i ) == 0 )
  393. { /* --- #endif --- */
  394. if( hb_pp_nCondCompile == 0 )
  395. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_DIRECTIVE_ENDIF, NULL, NULL );
  396. else hb_pp_nCondCompile--;
  397. }
  398. else if( i >= 4 && i <= 5 && memcmp( sDirective, "IFDEF", i ) == 0 )
  399. ParseIfdef( sLine, TRUE ); /* --- #ifdef --- */
  400. else if( i >= 4 && i <= 6 && memcmp( sDirective, "IFNDEF", i ) == 0 )
  401. ParseIfdef( sLine, FALSE ); /* --- #ifndef --- */
  402. else if( hb_pp_nCondCompile==0 || hb_pp_aCondCompile[hb_pp_nCondCompile-1])
  403. {
  404. if( i >= 4 && i <= 7 && memcmp( sDirective, "INCLUDE", i ) == 0 )
  405. { /* --- #include --- */
  406. char cDelimChar;
  407. if( *sLine != '\"' && *sLine != '\'' && *sLine != '<' )
  408. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_WRONG_NAME, NULL, NULL );
  409. cDelimChar = *sLine;
  410. if( cDelimChar == '<' )
  411. cDelimChar = '>';
  412. else if( cDelimChar == '`' )
  413. cDelimChar = '\'';
  414. sLine++; i = 0;
  415. while( *(sLine+i) != '\0' && *(sLine+i) != cDelimChar ) i++;
  416. if( *(sLine+i) != cDelimChar )
  417. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_WRONG_NAME, NULL, NULL );
  418. *(sLine+i) = '\0';
  419. if( !OpenInclude( sLine, hb_comp_pIncludePath, hb_comp_pFileName, ( cDelimChar == '>' ), szInclude ) )
  420. {
  421. if( errno == 0 || errno == EMFILE )
  422. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_TOO_MANY_INCLUDES, sLine, NULL );
  423. else
  424. {
  425. #if defined(__CYGWIN__) || defined(__IBMCPP__)
  426. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_CANNOT_OPEN, sLine, "" );
  427. #else
  428. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_CANNOT_OPEN, sLine, sys_errlist[ errno ] );
  429. #endif
  430. }
  431. }
  432. }
  433. else if( i >= 4 && i <= 6 && memcmp( sDirective, "DEFINE", i ) == 0 )
  434. hb_pp_ParseDefine( sLine ); /* --- #define --- */
  435. else if( i >= 4 && i <= 5 && memcmp( sDirective, "UNDEF", i ) == 0 )
  436. ParseUndef( sLine ); /* --- #undef --- */
  437. else if( (i >= 4 && i <= 7 && memcmp( sDirective, "COMMAND", i ) == 0) ||
  438. (i >= 4 && i <= 8 && memcmp( sDirective, "XCOMMAND", i ) == 0) )
  439. /* --- #command --- */
  440. ParseCommand( sLine, (i==7)? FALSE:TRUE, TRUE );
  441. else if( (i >= 4 && i <= 9 && memcmp( sDirective, "TRANSLATE", i ) == 0) ||
  442. (i >= 4 && i <= 10 && memcmp( sDirective, "XTRANSLATE", i ) == 0) )
  443. /* --- #translate --- */
  444. ParseCommand( sLine, (i==9)? FALSE:TRUE, FALSE );
  445. else if( i >= 4 && i <= 6 && memcmp( sDirective, "STDOUT", i ) == 0 )
  446. printf( "%s\n", sLine ); /* --- #stdout --- */
  447. else if( i >= 4 && i <= 5 && memcmp( sDirective, "ERROR", i ) == 0 )
  448. /* --- #error --- */
  449. hb_compGenError( hb_pp_szErrors, 'E', HB_PP_ERR_EXPLICIT, sLine, NULL );
  450. else if( i == 4 && memcmp( sDirective, "LINE", 4 ) == 0 )
  451. return -1;
  452. else if( i == 6 && memcmp( sDirective, "PRAGMA", 6 ) == 0 )
  453. hb_pp_ParsePragma( sLine ); /* --- #pragma --- */
  454. else
  455. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_WRONG_DIRECTIVE, sDirective, NULL );
  456. }
  457. return 0;
  458. }
  459. int hb_pp_ParseDefine( char * sLine )
  460. {
  461. char defname[ MAX_NAME ], pars[ MAX_NAME+1 ];
  462. int i, npars = -1;
  463. DEFINES * lastdef;
  464. HB_TRACE(HB_TR_DEBUG, ("hb_pp_ParseDefine(%s)", sLine));
  465. HB_SKIPTABSPACES( sLine );
  466. if( ISNAME( *sLine ) )
  467. {
  468. char *cParams = NULL;
  469. NextName( &sLine, defname );
  470. if( *sLine == '(' ) /* If pseudofunction was found */
  471. {
  472. int iParLen = 0;
  473. int iLen;
  474. sLine++;
  475. HB_SKIPTABSPACES( sLine );
  476. i = 0;
  477. npars = 0;
  478. while( *sLine && *sLine != ')' )
  479. {
  480. if( ISNAME(*sLine) )
  481. {
  482. NextName( &sLine, pars );
  483. iLen = strlen( pars );
  484. if( cParams == NULL )
  485. {
  486. /* 'xy0' -> '~xy0' */
  487. cParams = ( char * ) hb_xgrab( iLen+2 );
  488. }
  489. else
  490. {
  491. /* '~xy0' -> '~xy,~ab0' */
  492. char *cPos;
  493. cPos = strstr( cParams, pars );
  494. if( cPos && (cPos[iLen]==',' || cPos[iLen]=='\0') )
  495. {
  496. cPos--;
  497. if( *cPos == '\001' )
  498. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_LABEL_DUPL_IN_DEFINE, defname, pars );
  499. }
  500. cParams = ( char * ) hb_xrealloc( cParams, iParLen+iLen+3 );
  501. cParams[iParLen++] = ',';
  502. cParams[iParLen] = '\0';
  503. }
  504. cParams[iParLen] = '\001';
  505. strcpy( cParams+iParLen+1, pars );
  506. iParLen += iLen+1;
  507. npars++;
  508. HB_SKIPTABSPACES( sLine );
  509. }
  510. else
  511. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_LABEL_MISSING_IN_DEFINE, defname, NULL );
  512. if( *sLine == ',' )
  513. {
  514. sLine++;
  515. HB_SKIPTABSPACES( sLine );
  516. if( *sLine == ')' )
  517. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_LABEL_MISSING_IN_DEFINE, defname, NULL );
  518. }
  519. }
  520. HB_SKIPTABSPACES(sLine);
  521. if( *sLine == '\0' )
  522. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_PARE_MISSING_IN_DEFINE, defname, NULL );
  523. sLine++;
  524. }
  525. HB_SKIPTABSPACES(sLine);
  526. if( cParams )
  527. {
  528. char *tmp = cParams;
  529. char *cPos;
  530. int iPar, iLen, iPos, iOldPos;
  531. iLen = strlen( sLine );
  532. for(i=0; i<npars; i++ )
  533. {
  534. /*1z,1y*/
  535. cPos =strchr( tmp, ',' );
  536. if( cPos )
  537. iPar = cPos - tmp;
  538. else
  539. iPar = strlen( tmp );
  540. memcpy( pars, tmp, iPar );
  541. pars[ iPar ] = '\0';
  542. iPos = iOldPos = 0;
  543. while( (iPos = md_strAt( pars+1, iPar-1, sLine+iOldPos, TRUE, FALSE, FALSE )) )
  544. {
  545. if( sLine[iOldPos+iPos] != '\001' )
  546. {
  547. hb_pp_Stuff( pars, sLine+iOldPos+iPos-1, iPar, iPar-1, iLen-iPos-iOldPos );
  548. iLen++;
  549. }
  550. iOldPos +=iPos + iPar;
  551. }
  552. tmp = cPos+1;
  553. }
  554. }
  555. lastdef = hb_pp_AddDefine( defname, ( *sLine == '\0' ) ? NULL : sLine );
  556. lastdef->npars = npars;
  557. lastdef->pars = cParams;
  558. }
  559. else
  560. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_DEFINE_ABSENT, NULL, NULL );
  561. return 0;
  562. }
  563. DEFINES * hb_pp_AddDefine( char * defname, char * value )
  564. {
  565. BOOL isNew;
  566. DEFINES * stdef;
  567. HB_TRACE(HB_TR_DEBUG, ("hb_pp_AddDefine(%s, %s)", defname, value));
  568. stdef = DefSearch( defname, &isNew );
  569. if( stdef != NULL )
  570. {
  571. hb_compGenWarning( hb_pp_szWarnings, 'I', HB_PP_WARN_DEFINE_REDEF, defname, NULL );
  572. if( isNew )
  573. {
  574. if( stdef->pars ) hb_xfree( stdef->pars );
  575. if( stdef->value ) hb_xfree( stdef->value );
  576. }
  577. }
  578. else
  579. {
  580. stdef = ( DEFINES * ) hb_xgrab( sizeof( DEFINES ) );
  581. stdef->last = hb_pp_topDefine;
  582. hb_pp_topDefine = stdef;
  583. stdef->name = hb_strdup( defname );
  584. stdef->npars = -1;
  585. s_kolAddDefs++;
  586. }
  587. stdef->value = ( value == NULL ) ? NULL : hb_strdup( value );
  588. stdef->pars = NULL;
  589. return stdef;
  590. }
  591. static int ParseUndef( char * sLine )
  592. {
  593. char defname[ MAX_NAME ];
  594. DEFINES * stdef;
  595. BOOL isNew;
  596. HB_TRACE(HB_TR_DEBUG, ("ParseUndef(%s)", sLine));
  597. NextWord( &sLine, defname, FALSE );
  598. if( ( stdef = DefSearch(defname, &isNew ) ) != NULL )
  599. {
  600. if( isNew )
  601. {
  602. if( stdef->pars ) hb_xfree( stdef->pars );
  603. if( stdef->value ) hb_xfree( stdef->value );
  604. hb_xfree( stdef->name );
  605. }
  606. stdef->pars = NULL;
  607. stdef->value = NULL;
  608. stdef->name = NULL;
  609. }
  610. return 0;
  611. }
  612. static int ParseIfdef( char * sLine, int usl )
  613. {
  614. char defname[ MAX_NAME ];
  615. DEFINES * stdef;
  616. HB_TRACE(HB_TR_DEBUG, ("ParseIfdef(%s, %d)", sLine, usl));
  617. if( hb_pp_nCondCompile==0 || hb_pp_aCondCompile[hb_pp_nCondCompile-1])
  618. {
  619. NextWord( &sLine, defname, FALSE );
  620. if( *defname == '\0' )
  621. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_DEFINE_ABSENT, NULL, NULL );
  622. }
  623. if( hb_pp_nCondCompile == s_maxCondCompile )
  624. {
  625. s_maxCondCompile += 5;
  626. hb_pp_aCondCompile = (int*)hb_xrealloc( hb_pp_aCondCompile, sizeof( int ) * s_maxCondCompile );
  627. }
  628. if( hb_pp_nCondCompile==0 || hb_pp_aCondCompile[hb_pp_nCondCompile-1])
  629. {
  630. if( ( (stdef = DefSearch(defname,NULL)) != NULL && usl )
  631. || ( stdef == NULL && !usl ) ) hb_pp_aCondCompile[hb_pp_nCondCompile] = 1;
  632. else hb_pp_aCondCompile[hb_pp_nCondCompile] = 0;
  633. }
  634. else
  635. hb_pp_aCondCompile[ hb_pp_nCondCompile ] = 0;
  636. hb_pp_nCondCompile++;
  637. return 0;
  638. }
  639. static DEFINES * DefSearch( char * defname, BOOL * isNew )
  640. {
  641. int kol = 0,j;
  642. DEFINES * stdef = hb_pp_topDefine;
  643. HB_TRACE(HB_TR_DEBUG, ("DefSearch(%s)", defname));
  644. while( stdef != NULL )
  645. {
  646. kol++;
  647. if( stdef->name != NULL )
  648. {
  649. for( j=0; *(stdef->name+j) == *(defname+j) &&
  650. *(stdef->name+j) != '\0'; j++ );
  651. if( *(stdef->name+j) == *(defname+j) )
  652. {
  653. if( isNew ) *isNew = ( s_kolAddDefs >= kol );
  654. return stdef;
  655. }
  656. }
  657. stdef = stdef->last;
  658. }
  659. return NULL;
  660. }
  661. static COMMANDS * ComSearch( char * cmdname, COMMANDS * stcmdStart )
  662. {
  663. COMMANDS * stcmd = ( stcmdStart ) ? stcmdStart : hb_pp_topCommand;
  664. HB_TRACE(HB_TR_DEBUG, ("ComSearch(%s, %p)", cmdname, stcmdStart));
  665. while( stcmd != NULL )
  666. {
  667. int j;
  668. for( j=0; (*(stcmd->name+j)==toupper(*(cmdname+j))) &&
  669. (*(stcmd->name+j)!='\0') &&
  670. ((stcmd->com_or_xcom)? 1:(j<4 || ISNAME(*(cmdname+j+1)))); j++ );
  671. if( (*(stcmd->name+j)==toupper(*(cmdname+j))) ||
  672. ( !stcmd->com_or_xcom && j >= 4 && *(stcmd->name+j)!='\0'
  673. && *(cmdname+j) == '\0' ) )
  674. break;
  675. stcmd = stcmd->last;
  676. }
  677. return stcmd;
  678. }
  679. static COMMANDS * TraSearch( char * cmdname, COMMANDS * sttraStart )
  680. {
  681. int j;
  682. COMMANDS *sttra = ( sttraStart ) ? sttraStart : hb_pp_topTranslate;
  683. HB_TRACE(HB_TR_DEBUG, ("TraSearch(%s, %p)", cmdname, sttraStart));
  684. while( sttra != NULL )
  685. {
  686. for( j=0; *(sttra->name+j)==toupper(*(cmdname+j)) &&
  687. *(sttra->name+j)!='\0' &&
  688. ((sttra->com_or_xcom)? 1:(j<4 || ISNAME(*(cmdname+j+1)))); j++ );
  689. if( *(sttra->name+j)==toupper(*(cmdname+j)) ||
  690. ( !sttra->com_or_xcom && j >= 4 &&
  691. *(sttra->name+j)!='\0' && *(cmdname+j) == '\0' ) )
  692. break;
  693. sttra = sttra->last;
  694. }
  695. return sttra;
  696. }
  697. static void ParseCommand( char * sLine, BOOL com_or_xcom, BOOL com_or_tra )
  698. {
  699. static char mpatt[ PATTERN_SIZE ];
  700. char *rpatt;
  701. char cmdname[ MAX_NAME ];
  702. COMMANDS * stcmd;
  703. int mlen,rlen;
  704. int ipos;
  705. /* Ron Pinkas added 2000-12-03 */
  706. BOOL bOk = FALSE;
  707. HB_TRACE(HB_TR_DEBUG, ("ParseCommand(%s, %d, %d)", sLine, com_or_xcom, com_or_tra));
  708. HB_SKIPTABSPACES( sLine );
  709. ipos = 0;
  710. /* JFL 2000-09-19 */
  711. /* This was the original line as Alexander wrote it */
  712. /* while( *sLine != '\0' && *sLine != ' ' && *sLine != '\t' && *sLine != '<' && *sLine != '=' && ( *sLine != '(' || ipos == 0 ) ) */
  713. /* Now the line #xtranslate = name(.. => will be allowed */
  714. /* I changed it to the following to allow < and = to be the first char within a translate or xtranslate */
  715. while( *sLine != '\0' && *sLine != ' ' && *sLine != '\t' && ( *sLine != '<' || ipos == 0 ) && ( *sLine != '=' || ipos == 0 ) && ( *sLine != '(' || ipos == 0 ) )
  716. {
  717. /* Ron Pinkas added 2000-01-24 */
  718. if( ! ISNAME( *sLine ) )
  719. {
  720. if( *sLine == '[' && ipos )
  721. break;
  722. if( IS_2CHAR_OPERATOR( sLine ) )
  723. {
  724. *(cmdname+ipos++) = *sLine++;
  725. *(cmdname+ipos++) = *sLine++;
  726. break;
  727. }
  728. else
  729. {
  730. *(cmdname+ipos++) = *sLine++;
  731. break;
  732. }
  733. }
  734. /* END, Ron Pinkas added 2000-01-24 */
  735. *(cmdname+ipos++) = *sLine++;
  736. }
  737. *(cmdname+ipos) = '\0';
  738. if( !ipos )
  739. {
  740. return;
  741. }
  742. hb_strupr( cmdname );
  743. HB_SKIPTABSPACES(sLine);
  744. /* Ron Pinkas added 2000-12-03 */
  745. ipos = 0;
  746. while( *sLine )
  747. {
  748. mpatt[ipos++] = *sLine;
  749. if( *sLine == '=' )
  750. {
  751. int i = ipos;
  752. sLine++;
  753. mpatt[i++] = *sLine;
  754. while( *sLine && ( *sLine == ' ' || *sLine == '\t' ) )
  755. {
  756. sLine++;
  757. mpatt[i++] = *sLine;
  758. }
  759. if( *sLine == '>' )
  760. {
  761. ipos = ipos - 2;
  762. while( mpatt[ipos] == ' ' || mpatt[ipos] == '\t' )
  763. {
  764. ipos--;
  765. }
  766. mpatt[ipos + 1] = '\0';
  767. sLine++;
  768. bOk = TRUE;
  769. break;
  770. }
  771. ipos = i;
  772. }
  773. sLine++;
  774. }
  775. /* End - Ron Pinkas added 2000-12-03 */
  776. /* Ron Pinkas modified 2000-12-03
  777. if( (ipos = hb_strAt( "=>", 2, sLine, strlen(sLine) )) > 0 ) */
  778. if( bOk )
  779. {
  780. /* Ron Pinkas removed 2000-12-03
  781. stroncpy( mpatt, sLine, ipos-1 ); */
  782. RemoveSlash( mpatt );
  783. mlen = strotrim( mpatt, TRUE );
  784. /* Ron Pinkas removed 2000-12-03
  785. sLine += ipos + 1; */
  786. HB_SKIPTABSPACES(sLine);
  787. /* hb_pp_strocpy( rpatt, sLine ); */
  788. rpatt = sLine;
  789. rlen = strotrim( rpatt, TRUE );
  790. ConvertPatterns( mpatt, mlen, rpatt, rlen );
  791. if( com_or_tra )
  792. stcmd = AddCommand( cmdname );
  793. else
  794. stcmd = AddTranslate( cmdname );
  795. stcmd->com_or_xcom = com_or_xcom;
  796. stcmd->mpatt = hb_strdup( mpatt );
  797. stcmd->value = ( rlen > 0 ) ? hb_strdup( rpatt ) : NULL;
  798. /* JFL */
  799. /*
  800. printf( "Parsecommand Name: %s Pat: %s Val: %s\n", stcmd->name, stcmd->mpatt, stcmd->value );
  801. */
  802. }
  803. else
  804. {
  805. sLine -= ( ipos + 1 );
  806. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_COMMAND_DEFINITION, cmdname, sLine );
  807. }
  808. }
  809. /* ConvertPatterns()
  810. * Converts result pattern in #command and #translate to inner format
  811. */
  812. static void ConvertPatterns( char * mpatt, int mlen, char * rpatt, int rlen )
  813. {
  814. int i = 0, ipos, ifou;
  815. int explen, rmlen;
  816. char exppatt[ MAX_NAME ], expreal[ 5 ] = "\1 0";
  817. char lastchar = '@', exptype;
  818. char * ptr, * ptrtmp;
  819. HB_TRACE(HB_TR_DEBUG, ("ConvertPatterns(%s, %d, %s, %d)", mpatt, mlen, rpatt, rlen));
  820. while( *(mpatt+i) != '\0' )
  821. {
  822. if( *(mpatt+i) == '<' )
  823. { /* Drag match marker, determine it type */
  824. explen = 0; ipos = i; i++; exptype = '0';
  825. while( *(mpatt+i) == ' ' || *(mpatt+i) == '\t' ) i++;
  826. if( *(mpatt+i) == '*' ) /* Wild match marker */
  827. { exptype = '3'; i++; }
  828. else if( *(mpatt+i) == '(' ) /* Extended expression match marker */
  829. { exptype = '4'; i++; }
  830. else if( *(mpatt+i) == '!' ) /* Extended expression match marker */
  831. { exptype = '5'; i++; }
  832. ptr = mpatt + i;
  833. while( *ptr != '>' )
  834. {
  835. if( *ptr == '\0' || *ptr == '<' || *ptr == '[' || *ptr == ']' )
  836. {
  837. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_PATTERN_DEFINITION, NULL, NULL );
  838. return;
  839. }
  840. ptr++;
  841. }
  842. while( *(mpatt+i) != '>' )
  843. {
  844. if( *(mpatt+i) == ',' ) /* List match marker */
  845. {
  846. exptype = '1';
  847. while( *(mpatt+i) != '>' ) i++;
  848. break;
  849. }
  850. else if( *(mpatt+i) == ':' ) /* Restricted match marker */
  851. {
  852. exptype = '2';
  853. *(mpatt+i--) = ' ';
  854. break;
  855. }
  856. if( *(mpatt+i) != ' ' && *(mpatt+i) != '\t' )
  857. *(exppatt+explen++) = *(mpatt+i);
  858. i++;
  859. }
  860. if( exptype == '3' )
  861. {
  862. if( *(exppatt+explen-1) == '*' ) explen--;
  863. else
  864. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_PATTERN_DEFINITION, NULL, NULL );
  865. }
  866. else if( exptype == '4' )
  867. {
  868. if( *(exppatt+explen-1) == ')' ) explen--;
  869. else
  870. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_PATTERN_DEFINITION, NULL, NULL );
  871. }
  872. else if( exptype == '5' )
  873. {
  874. if( *(exppatt+explen-1) == '!' ) explen--;
  875. else
  876. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_PATTERN_DEFINITION, NULL, NULL );
  877. }
  878. rmlen = i - ipos + 1;
  879. /* Convert match marker into inner format */
  880. lastchar = (lastchar!='Z') ? ( (char) ( (unsigned int)lastchar + 1 ) ):
  881. 'a';
  882. expreal[1] = lastchar;
  883. expreal[2] = exptype;
  884. hb_pp_Stuff( expreal, mpatt+ipos, 4, rmlen, mlen-ipos );
  885. mlen += 4 - rmlen;
  886. i += 4 - rmlen;
  887. /* Look for appropriate result markers */
  888. ptr = rpatt;
  889. while( (ifou = hb_strAt( exppatt, explen, ptr, rlen-(ptr-rpatt) )) > 0 )
  890. {
  891. /* Convert result marker into inner format */
  892. ifou --;
  893. ptr += ifou;
  894. ptrtmp = ptr + 1;
  895. rmlen = explen;
  896. exptype = '0';
  897. do
  898. {
  899. ptr--;
  900. rmlen++;
  901. ifou--;
  902. if( *ptr == '<' )
  903. continue;
  904. else if( *ptr == '\"' )
  905. exptype = '2';
  906. else if( *ptr == '(' )
  907. exptype = '3';
  908. else if( *ptr == '{' )
  909. exptype = '4';
  910. else if( *ptr == '.' )
  911. exptype = '5';
  912. else if( *ptr == '-' )
  913. exptype = '6';
  914. else if( *ptr == ' ' || *ptr == '\t' )
  915. continue;
  916. else
  917. ifou = -1;
  918. }
  919. while( ifou >= 0 && *ptr!='<' && *(ptr-1)!= '\\' );
  920. if( ifou >=0 && *ptr=='<' )
  921. {
  922. ptr += rmlen++;
  923. while( *ptr != '\0' && *ptr != '>' && *(ptr-1) != '\\' )
  924. {
  925. if( *ptr != ' ' && *ptr != '\t' && *ptr != '\"' && *ptr != ')' && *ptr != '}' && *ptr != '.' && *ptr != '-' )
  926. {
  927. ifou = -1;
  928. break;
  929. }
  930. rmlen++;
  931. ptr++;
  932. }
  933. if( ifou >=0 && *ptr=='>' )
  934. {
  935. ptr -= rmlen;
  936. ptr++;
  937. if( exptype == '0' && *(ptr-1) == '#' && *(ptr-2) != '\\' )
  938. {
  939. exptype = '1';
  940. ptr--;
  941. rmlen++;
  942. }
  943. expreal[2] = exptype;
  944. hb_pp_Stuff( expreal, ptr, 4, rmlen, rlen+(rpatt-ptr) );
  945. rlen += 4 - rmlen;
  946. }
  947. else
  948. ptr = ptrtmp;
  949. }
  950. else
  951. ptr = ptrtmp;
  952. }
  953. }
  954. i++;
  955. }
  956. }
  957. static COMMANDS * AddCommand( char * cmdname )
  958. {
  959. COMMANDS * stcmd;
  960. HB_TRACE(HB_TR_DEBUG, ("AddCommand(%s)", cmdname));
  961. stcmd = ( COMMANDS * ) hb_xgrab( sizeof( COMMANDS ) );
  962. stcmd->last = hb_pp_topCommand;
  963. hb_pp_topCommand = stcmd;
  964. stcmd->name = hb_strdup( cmdname );
  965. s_kolAddComs++;
  966. return stcmd;
  967. }
  968. static COMMANDS* AddTranslate( char * traname )
  969. {
  970. COMMANDS * sttra;
  971. HB_TRACE(HB_TR_DEBUG, ("AddTranslate(%s)", traname));
  972. sttra = ( COMMANDS * ) hb_xgrab( sizeof( COMMANDS ) );
  973. sttra->last = hb_pp_topTranslate;
  974. hb_pp_topTranslate = sttra;
  975. sttra->name = hb_strdup( traname );
  976. s_kolAddTras++;
  977. return sttra;
  978. }
  979. int hb_pp_ParseExpression( char * sLine, char * sOutLine )
  980. {
  981. static char rpatt[ PATTERN_SIZE ];
  982. char sToken[MAX_NAME];
  983. char * ptri, * ptro, * ptrb;
  984. int lenToken, i, ipos, isdvig, lens;
  985. int ifou;
  986. int rezDef, rezTra, rezCom, kolpass = 0;
  987. DEFINES * stdef;
  988. COMMANDS * stcmd;
  989. HB_TRACE(HB_TR_DEBUG, ("hb_pp_ParseExpression(%s, %s)", sLine, sOutLine));
  990. #if 0
  991. printf( "Line: >%s<\n", sLine );
  992. #endif
  993. do
  994. {
  995. strotrim( sLine, FALSE );
  996. #if 0
  997. printf( "Trimed: >%s<\n", sLine );
  998. #endif
  999. rezDef = 0; rezTra = 0; rezCom = 0;
  1000. isdvig = 0;
  1001. do
  1002. {
  1003. ptro = sOutLine;
  1004. ptri = sLine + isdvig;
  1005. ipos = md_strAt( ";", 1, ptri, TRUE, FALSE, FALSE );
  1006. if( ipos > 0 )
  1007. {
  1008. *(ptri+ipos-1) = '\0';
  1009. }
  1010. HB_SKIPTABSPACES( ptri );
  1011. if( *ptri == '#' )
  1012. {
  1013. hb_pp_strocpy( rpatt, ptri+1 );
  1014. hb_pp_ParseDirective( rpatt );
  1015. if( ipos > 0 )
  1016. {
  1017. *( sLine + isdvig + ipos - 1 ) = ';';
  1018. }
  1019. lens = strlen( sLine + isdvig );
  1020. hb_pp_Stuff( " ", sLine + isdvig, 0, (ipos)? ipos:lens, lens );
  1021. if( ipos > 0 )
  1022. {
  1023. ipos = 1;
  1024. }
  1025. }
  1026. else
  1027. { /* Look for macros from #define */
  1028. while( ( lenToken = NextName( &ptri, sToken ) ) > 0 )
  1029. {
  1030. #if 0
  1031. printf( "Token: >%s< Line: >%s<\n", sToken, sLine );
  1032. #endif
  1033. if( (stdef=DefSearch(sToken,NULL)) != NULL )
  1034. {
  1035. ptrb = ptri - lenToken;
  1036. if( ( i = WorkDefine( &ptri, ptro, stdef ) ) >= 0 )
  1037. {
  1038. rezDef++;
  1039. lens = strlen( ptrb );
  1040. if( ipos > 0 )
  1041. {
  1042. *(ptrb+lens) = ';';
  1043. lens += strlen( ptrb+lens+1 );
  1044. }
  1045. hb_pp_Stuff( ptro, ptrb, i, ptri-ptrb, lens+1 );
  1046. if( ipos > 0 )
  1047. {
  1048. ipos += i - (ptri-ptrb);
  1049. *(sLine + isdvig + ipos - 1) = '\0';
  1050. }
  1051. ptri += i - (ptri-ptrb);
  1052. }
  1053. }
  1054. }
  1055. #if 0
  1056. if( *sOutLine )
  1057. printf( "*After #defines: >%s<\n", sOutLine );
  1058. else
  1059. printf( "After #defines: >%s<\n", sLine );
  1060. #endif
  1061. if( rezDef == 0 )
  1062. {
  1063. /* Look for definitions from #translate */
  1064. stcmd = hb_pp_topTranslate;
  1065. while( stcmd != NULL )
  1066. {
  1067. ptri = sLine + isdvig;
  1068. lenToken = strlen(stcmd->name);
  1069. while( ( ifou = md_strAt( stcmd->name, lenToken, ptri, TRUE, FALSE, FALSE )) > 0 )
  1070. {
  1071. ptri += ifou -1;
  1072. if( ( i = WorkTranslate( ptri+lenToken, ptro, stcmd, &lens ) ) >= 0 )
  1073. {
  1074. lens += lenToken;
  1075. while( lens > 0 && (*(ptri+lens-1)==' ' || *(ptri+lens-1)=='\t') )
  1076. {
  1077. lens--;
  1078. }
  1079. if( ipos > 0 )
  1080. {
  1081. *(sLine+isdvig+ipos-1) = ';';
  1082. }
  1083. hb_pp_Stuff( ptro, ptri, i, lens, strlen(ptri) );
  1084. rezTra = 1;
  1085. if( ipos > 0 )
  1086. {
  1087. ipos += i - lens;
  1088. *(sLine+isdvig+ipos-1) = '\0';
  1089. }
  1090. ptri += i;
  1091. }
  1092. else
  1093. {
  1094. ptri += lenToken;
  1095. }
  1096. }
  1097. stcmd = stcmd->last;
  1098. }
  1099. } /* rezDef == 0 */
  1100. #if 0
  1101. if( *sOutLine )
  1102. printf( "*After #translate: >%s<\n", sOutLine );
  1103. else
  1104. printf( "After #translate: >%s<\n", sLine );
  1105. #endif
  1106. /* Look for definitions from #command */
  1107. /* JFL ! Was 3 but insufficient in most cases */
  1108. /* I know this is a new hardcoded limit ... any better idea's welcome */
  1109. if( rezDef==0 && rezTra==0 && kolpass < 20 )
  1110. {
  1111. ptri = sLine + isdvig;
  1112. HB_SKIPTABSPACES( ptri );
  1113. if( ISNAME( *ptri ) )
  1114. {
  1115. NextName( &ptri, sToken );
  1116. }
  1117. else
  1118. {
  1119. /* Ron Pinkas commented 2000-01-24
  1120. i = 0;
  1121. while( *ptri != ' ' && *ptri != '\t' && *ptri != '\0' && *ptri != '\"' && *ptri != '\'' && *ptri != '(' && !ISNAME(*ptri) )
  1122. {
  1123. *(sToken+i) = *ptri++;
  1124. i++;
  1125. }
  1126. *(sToken+i) = '\0';
  1127. */
  1128. /* Ron Pinkas added 2000-01-24 */
  1129. if( IS_2CHAR_OPERATOR( ptri ) )
  1130. {
  1131. sToken[0] = *ptri++;
  1132. sToken[1] = *ptri++;
  1133. sToken[2] = '\0';
  1134. }
  1135. else
  1136. {
  1137. sToken[0] = *ptri++;
  1138. sToken[1] = '\0';
  1139. }
  1140. /* END, Ron Pinkas added 2000-01-24 */
  1141. }
  1142. HB_SKIPTABSPACES( ptri );
  1143. #if 0
  1144. printf( "Token: %s\n", sToken );
  1145. #endif
  1146. if( ( *ptri == '\0' || ( *ptri != '=' && (!IsInStr(*ptri,":/+*-%^") || *(ptri+1) != '=') &&
  1147. ( *ptri != '-' || *(ptri+1) != '>' ) ) ) && ( stcmd = ComSearch(sToken,NULL) ) != NULL )
  1148. {
  1149. ptro = sOutLine;
  1150. i = WorkCommand( ptri, ptro, stcmd );
  1151. ptri = sLine + isdvig;
  1152. if( ipos > 0 )
  1153. {
  1154. *(ptri+ipos-1) = ';';
  1155. }
  1156. if( i >= 0 )
  1157. {
  1158. if( isdvig + ipos > 0 )
  1159. {
  1160. lens = strlen( sLine+isdvig );
  1161. hb_pp_Stuff( ptro, sLine+isdvig, i, (ipos)? ipos-1:lens, lens );
  1162. if( ipos > 0 )
  1163. {
  1164. ipos = i + 1;
  1165. }
  1166. }
  1167. else
  1168. {
  1169. memcpy( sLine, sOutLine, i+1);
  1170. }
  1171. }
  1172. rezCom = 1;
  1173. }
  1174. else if( ipos > 0 )
  1175. {
  1176. *(sLine+isdvig+ipos-1) = ';';
  1177. }
  1178. }
  1179. else if( ipos > 0 )
  1180. {
  1181. *(sLine+isdvig+ipos-1) = ';';
  1182. }
  1183. }
  1184. isdvig += ipos;
  1185. }
  1186. while( ipos != 0 );
  1187. kolpass++;
  1188. if( kolpass > 750 && rezDef )
  1189. {
  1190. hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_RECURSE, NULL, NULL );
  1191. break;
  1192. }
  1193. }
  1194. while( rezDef || rezTra || rezCom );
  1195. #if 0
  1196. if( *sOutLine )
  1197. printf( "Out: >%s<\n", sOutLine );
  1198. else
  1199. printf( "Out: >%s<\n", sLine );
  1200. #endif
  1201. return 0;
  1202. }
  1203. static int WorkDefine( char ** ptri, char * ptro, DEFINES * stdef )
  1204. {
  1205. int npars, lens;
  1206. char * ptr;
  1207. HB_TRACE(HB_TR_DEBUG, ("WorkDefine(%p, %s, %p)", ptri, ptro, stdef));
  1208. if( stdef->npars < 0 )
  1209. {
  1210. lens = hb_pp_strocpy( ptro,stdef->value );
  1211. }
  1212. else
  1213. {
  1214. HB_SKIPTABSPACES( *ptri );
  1215. if( **ptri == '(' )
  1216. {
  1217. npars = 0; ptr = *ptri;
  1218. do
  1219. {
  1220. ptr++;
  1221. if( NextParm( &ptr, NULL ) > 0 )
  1222. {
  1223. npars++;
  1224. }
  1225. }
  1226. while( *ptr != ')' && *ptr != '\0' );
  1227. if( *ptr == ')' && stdef->npars == npars )
  1228. {
  1229. /* Ron Pinkas added 2000-11-21 */
  1230. char *pTmp = ptr + 1;
  1231. while( *pTmp && ( *pTmp == ' ' || *pTmp == '\t' ) )
  1232. {
  1233. pTmp++;
  1234. }
  1235. if( *pTmp == '[' )
  1236. {
  1237. s_bArray = TRUE;
  1238. }
  1239. /* END - Ron Pinkas added 2000-11-21 */
  1240. lens = WorkPseudoF( ptri, ptro, stdef );
  1241. }
  1242. else
  1243. {
  1244. return -1;
  1245. }
  1246. }
  1247. else
  1248. {
  1249. return -1;
  1250. }
  1251. }
  1252. return lens;
  1253. }
  1254. static int WorkPseudoF( char ** ptri, char * ptro, DEFINES * stdef )
  1255. {
  1256. char parfict[ MAX_NAME ], * ptrreal;
  1257. char * ptrb;
  1258. int ipos, ifou, ibeg;
  1259. int lenfict, lenreal, lenres;
  1260. HB_TRACE(HB_TR_DEBUG, ("WorkPseudoF(%p, %s, %p)", ptri, ptro, stdef));
  1261. lenres = hb_pp_strocpy( ptro, stdef->value ); /* Copying value of macro to destination string */
  1262. if( stdef->pars )
  1263. {
  1264. ipos = 0; ibeg = 0;
  1265. do /* Parsing through parameters */
  1266. { /* in macro definition */
  1267. if( *(stdef->pars+ipos) == ',' || *(stdef->pars+ipos) == '\0' )
  1268. {
  1269. *(parfict+ipos-ibeg) = '\0';
  1270. lenfict = ipos - ibeg;
  1271. if( **ptri != ')' )
  1272. {
  1273. (*ptri)++; /* Get next real parameter */
  1274. HB_SKIPTABSPACES( *ptri );
  1275. ptrreal = *ptri;
  1276. lenreal = NextParm( ptri, NULL);
  1277. ptrb = ptro;
  1278. while( (ifou = hb_strAt( parfict, lenfict, ptrb, lenres-(ptrb-ptro) )) > 0 )
  1279. {
  1280. ptrb = ptrb+ifou-1;
  1281. if( !ISNAME(*(ptrb-1)) && !ISNAME(*(ptrb+lenfict)) )
  1282. {
  1283. hb_pp_Stuff( ptrreal, ptrb, lenreal, lenfict, lenres+(ptro-ptrb) );
  1284. lenres += lenreal - lenfict;
  1285. ptrb += lenreal;
  1286. }
  1287. else
  1288. {
  1289. ptrb++;
  1290. }
  1291. }
  1292. ibeg = ipos+1;
  1293. }
  1294. }
  1295. else
  1296. {
  1297. *(parfict+ipos-ibeg) = *(stdef->pars+ipos);
  1298. }
  1299. if( *(stdef->pars+ipos) == '\0' )
  1300. {
  1301. break;
  1302. }
  1303. ipos++;
  1304. }
  1305. while( 1 );
  1306. }
  1307. else
  1308. {
  1309. while( **ptri != ')' )
  1310. {
  1311. (*ptri)++;
  1312. }
  1313. }
  1314. (*ptri)++;
  1315. return lenres;
  1316. }
  1317. static int WorkCommand( char * ptri, char * ptro, COMMANDS * stcmd )
  1318. {
  1319. int rez;
  1320. int lenres;
  1321. char * ptrmp;
  1322. char * sToken = stcmd->name;
  1323. HB_TRACE(HB_TR_DEBUG, ("WorkCommand(%s, %s, %p)", ptri, ptro, stcmd));
  1324. do
  1325. {
  1326. lenres = hb_pp_strocpy( ptro, stcmd->value ); /* Copying result pattern */
  1327. ptrmp = stcmd->mpatt; /* Pointer to a match pattern */
  1328. s_Repeate = 0;
  1329. s_groupchar = '@';
  1330. rez = CommandStuff( ptrmp, ptri, ptro, &lenres, TRUE, stcmd->com_or_xcom );
  1331. stcmd = stcmd->last;
  1332. if( rez < 0 && stcmd != NULL ) stcmd = ComSearch(sToken, stcmd);
  1333. }
  1334. while( rez < 0 && stcmd != NULL );
  1335. *(ptro+lenres) = '\0';
  1336. if( rez >= 0 ) return lenres;
  1337. return -1;
  1338. }
  1339. static int WorkTranslate( char * ptri, char * ptro, COMMANDS * sttra, int * lens )
  1340. {
  1341. int rez;
  1342. int lenres;
  1343. char * ptrmp;
  1344. char * sToken = sttra->name;
  1345. HB_TRACE(HB_TR_DEBUG, ("WorkTranslate(%s, %s, %p, %p)", ptri, ptro, sttra, lens));
  1346. do
  1347. {
  1348. lenres = hb_pp_strocpy( ptro, sttra->value );
  1349. ptrmp = sttra->mpatt;
  1350. s_Repeate = 0;
  1351. s_groupchar = '@';
  1352. rez = CommandStuff( ptrmp, ptri, ptro, &lenres, FALSE, sttra->com_or_xcom );
  1353. sttra = sttra->last;
  1354. if( rez < 0 && sttra != NULL )
  1355. {
  1356. sttra = TraSearch(sToken, sttra);
  1357. }
  1358. }
  1359. while( rez < 0 && sttra != NULL );
  1360. *(ptro+lenres) = '\0';
  1361. if( rez >= 0 )
  1362. {
  1363. *lens = rez;
  1364. return lenres;
  1365. }
  1366. return -1;
  1367. }
  1368. static int CommandStuff( char * ptrmp, char * inputLine, char * ptro, int * lenres, BOOL com_or_tra, BOOL com_or_xcom )
  1369. {
  1370. BOOL endTranslation = FALSE;
  1371. int ipos;
  1372. char * lastopti[ 3 ], * strtopti = NULL, * strtptri = NULL;
  1373. char * ptri = inputLine, * ptr, tmpname[ MAX_NAME ];
  1374. int isWordInside = 0;
  1375. /*
  1376. printf( "MP: >%s<\nIn: >%s<\n", ptrmp, ptri );
  1377. */
  1378. HB_TRACE(HB_TR_DEBUG, ("CommandStuff(%s, %s, %s, %p, %d, %d)", ptrmp, inputLine, ptro, lenres, com_or_tra, com_or_xcom));
  1379. s_numBrackets = 0;
  1380. HB_SKIPTABSPACES( ptri );
  1381. if( ptrmp == NULL ) { if( *ptri != '\0' ) return -1; }
  1382. else
  1383. while( *ptri != '\0' && !endTranslation )
  1384. {
  1385. HB_SKIPTABSPACES( ptrmp );
  1386. if( *ptrmp == '[' && !s_numBrackets && !strtopti )
  1387. strtopti = ptrmp;
  1388. if( !s_numBrackets && strtopti && strtptri != ptri &&
  1389. ( ISNAME( *ptri ) || *ptri=='&' ) )
  1390. {
  1391. strtptri = ptri;
  1392. ptrmp = strtopti;
  1393. ptr = ptri;
  1394. ipos = NextName( &ptr, tmpname );
  1395. ipos = md_strAt( tmpname, ipos, strtopti, TRUE, TRUE, TRUE );
  1396. if( ipos && TestOptional( strtopti, strtopti+ipos-2 ) )
  1397. {
  1398. ptr = strtopti+ipos-2;
  1399. ptr = PrevSquare( ptr, strtopti, NULL );
  1400. if( ptr )
  1401. ptrmp = ptr;
  1402. }
  1403. }
  1404. switch( *ptrmp ) {
  1405. case '[':
  1406. if( !s_numBrackets ) isWordInside = 0;
  1407. s_numBrackets++;
  1408. s_aIsRepeate[ s_Repeate ] = 0;
  1409. lastopti[s_Repeate++] = ptrmp;
  1410. ptrmp++;
  1411. if( !CheckOptional( ptrmp, ptri, ptro, lenres, com_or_tra, com_or_xcom ) )
  1412. SkipOptional( &ptrmp );
  1413. break;
  1414. case ']':
  1415. if( s_Repeate )
  1416. {
  1417. s_Repeate--;
  1418. if( s_aIsRepeate[ s_Repeate ] )
  1419. {
  1420. if( ISNAME(*ptri) )
  1421. {
  1422. ptr = ptri;
  1423. ipos = NextName( &ptr, tmpname );
  1424. ipos = md_strAt( tmpname, ipos, ptrmp, TRUE, TRUE, TRUE );
  1425. if( ipos && TestOptional( ptrmp+1, ptrmp+ipos-2 ) )
  1426. {
  1427. ptr = PrevSquare( ptrmp+ipos-2, ptrmp+1, NULL );
  1428. if( !ptr || CheckOptional( ptrmp+1

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