PageRenderTime 66ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

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

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

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