/* * $Id$ */ /* * Harbour Project source code: * Preprocessor core module * * Copyright 1999 Alexander S.Kresin * www - http://www.harbour-project.org * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version, with one exception: * * The exception is that if you link the Harbour Runtime Library (HRL) * and/or the Harbour Virtual Machine (HVM) with other files to produce * an executable, this does not by itself cause the resulting executable * to be covered by the GNU General Public License. Your use of that * executable is in no way restricted on account of linking the HRL * and/or HVM code into it. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit * their web site at http://www.gnu.org/). * */ /* * Avoid tracing in preprocessor/compiler. */ #if ! defined(HB_TRACE_UTILS) #if defined(HB_TRACE_LEVEL) #undef HB_TRACE_LEVEL #endif #endif #include #if ( defined(_MSC_VER) || defined(__IBMCPP__) || defined(__MINGW32_) ) #include #elif defined(__GNUC__) #include #include #else #include #endif #include #include #include "hbpp.h" #include "hberrors.h" int Hp_Parse( FILE*, FILE*, char * ); int ParseDirective( char* ); /* Parsing preprocessor directives ( #... ) */ int ParseDefine( char* ); /* Process #define directive */ DEFINES* AddDefine ( char*, char* ); /* Add new #define to a linked list */ int ParseUndef( char* ); /* Process #undef directive */ int ParseIfdef( char*, int); /* Process #ifdef directive */ void ParseCommand( char*, int, int ); /* Process #command or #translate directive */ void ConvertPatterns ( char*, int, char*, int ); /* Converting result pattern in #command and #translate */ COMMANDS* AddCommand ( char * ); /* Add new #command to an array */ COMMANDS* AddTranslate ( char * ); /* Add new #translate to an array */ int ParseExpression( char*, char* ); /* Parsing a line ( without preprocessor directive ) */ int WorkDefine ( char**, char*, DEFINES * ); /* Replace fragment of code with a #defined result text */ int WorkPseudoF ( char**, char*, DEFINES*); /* Replace pseudofunction with a #defined result text */ int WorkCommand ( char*, char*, COMMANDS* ); int WorkTranslate ( char*, char*, COMMANDS*, int* ); int CommandStuff ( char *, char *, char *, int*, int, int ); int RemoveSlash( char * ); int WorkMarkers( char**, char**, char*, int*, int ); int getExpReal ( char *, char **, int, int ); int isExpres ( char* ); int TestOptional( char*, char* ); int CheckOptional( char*, char*, char*, int*, int, int ); void SkipOptional( char** ); DEFINES* DefSearch(char *); COMMANDS* ComSearch( char *, COMMANDS* ); COMMANDS* TraSearch( char *, COMMANDS* ); void SearnRep( char*,char*,int,char*,int*); int ReplacePattern ( char, char*, int, char*, int ); void pp_rQuotes( char *, char * ); int pp_RdStr(FILE*,char *,int,int,char*,int*,int*); int pp_WrStr(FILE*,char *); int pp_strAt(char *, int, char*, int); int md_strAt(char *, int, char*, int, int); char* PrevSquare( char* , char*, int* ); int IsInStr ( char, char*); void pp_Stuff (char*, char*, int, int, int); int strocpy (char*, char* ); int stroncpy (char*, char*, int); int strincpy (char*, char*); int truncmp (char**, char**, int); int strincmp (char*, char**, int); int strolen ( char* ); void stroupper ( char* ); int strotrim ( char* ); char* strodup ( char * ); int NextWord ( char**, char*, int); int NextName ( char**, char* ); int NextParm ( char**, char* ); int Include( char *, PATHNAMES *, FILE** ); BOOL OpenInclude( char *, PATHNAMES *, FILE**, BOOL bStandardOnly, char * ); #define ISNAME(c) (isalnum(c) || (c)=='_' || (c) > 0x7e) #define MAX_NAME 255 #define MAX_EXP 1024 #define PATTERN_SIZE 2048 #define STATE_INIT 0 #define STATE_NORMAL 1 #define STATE_COMMENT 2 #define STATE_QUOTE1 3 #define STATE_QUOTE2 4 #define STATE_ID_END 5 #define STATE_ID 6 #define STATE_EXPRES 7 #define STATE_EXPRES_ID 8 #define STATE_BRACKET 9 #define IT_EXPR 1 #define IT_ID 2 #define IT_COMMA 3 #define IT_ID_OR_EXPR 4 int ParseState = 0; int lInclude = 0; int *aCondCompile, nCondCompile = 0, maxCondCompile = 5; int nline=0; int aIsRepeate[5], Repeate; int lReplacePat = 1; int numBrackets; char groupchar; /* Table with parse errors */ char * _szPErrors[] = { "Can\'t open #include file: \'%s\'", "#else does not match #ifdef", "#endif does not match #ifdef", "Bad filename in #include", "#define without parameters", "Missing => in #translate/#command", "Error in pattern definition", "Cycled #define", "Invalid name follows #: \'%s\'", "#error: \'%s\'", "Memory allocation error", "Memory reallocation error", "Freeing a NULL memory pointer" }; /* Table with parse warnings */ /* NOTE: The first character stores the warning's level that triggers this * warning. The warning's level is set by -w command line option. */ char * _szPWarnings[] = { "3Non directive in include file %s(%s)" }; int ParseDirective( char* sLine ) { char sDirective[MAX_NAME]; char szInclude[_POSIX_PATH_MAX]; int i; FILE* handl_i; HB_TRACE(HB_TR_DEBUG, ("ParseDirective(%s)", sLine)); i = NextName( &sLine, sDirective ); stroupper( sDirective ); SKIPTABSPACES(sLine); if ( i == 4 && memcmp ( sDirective, "ELSE", 4 ) == 0 ) { /* --- #else --- */ if ( nCondCompile == 0 ) GenError( _szPErrors, 'P', ERR_DIRECTIVE_ELSE, NULL, NULL ); else if ( nCondCompile == 1 || aCondCompile[nCondCompile-2] ) aCondCompile[nCondCompile-1] = 1 - aCondCompile[nCondCompile-1]; } else if ( i == 5 && memcmp ( sDirective, "ENDIF", 5 ) == 0 ) { /* --- #endif --- */ if ( nCondCompile == 0 ) GenError( _szPErrors, 'P', ERR_DIRECTIVE_ENDIF, NULL, NULL ); else nCondCompile--; } else if ( i == 5 && memcmp ( sDirective, "IFDEF", 5 ) == 0 ) ParseIfdef ( sLine, TRUE ); /* --- #ifdef --- */ else if ( i == 6 && memcmp ( sDirective, "IFNDEF", 6 ) == 0 ) ParseIfdef ( sLine, FALSE ); /* --- #ifndef --- */ else if ( nCondCompile==0 || aCondCompile[nCondCompile-1]) { if ( i == 7 && memcmp ( sDirective, "INCLUDE", 7 ) == 0 ) { /* --- #include --- */ char cDelimChar; if ( *sLine != '\"' && *sLine != '\'' && *sLine != '<' ) GenError( _szPErrors, 'P', ERR_WRONG_NAME, NULL, NULL ); cDelimChar = *sLine; if (cDelimChar == '<') cDelimChar = '>'; sLine++; i = 0; while ( *(sLine+i) != '\0' && *(sLine+i) != cDelimChar ) i++; if ( *(sLine+i) != cDelimChar ) GenError( _szPErrors, 'P', ERR_WRONG_NAME, NULL, NULL ); *(sLine+i) = '\0'; /* if ((handl_i = fopen(sLine, "r")) == NULL) */ if ( !OpenInclude( sLine, _pIncludePath, &handl_i, (cDelimChar == '>'), szInclude ) ) GenError( _szPErrors, 'P', ERR_CANNOT_OPEN, sLine, NULL ); lInclude++; Hp_Parse(handl_i, 0, szInclude ); lInclude--; fclose(handl_i); } else if ( i == 6 && memcmp ( sDirective, "DEFINE", 6 ) == 0 ) ParseDefine ( sLine ); /* --- #define --- */ else if ( i == 5 && memcmp ( sDirective, "UNDEF", 5 ) == 0 ) ParseUndef ( sLine ); /* --- #undef --- */ else if ( (i == 7 && memcmp ( sDirective, "COMMAND", 7 ) == 0) || (i == 8 && memcmp ( sDirective, "XCOMMAND", 8 ) == 0) ) /* --- #command --- */ ParseCommand ( sLine, (i==7)? FALSE:TRUE, TRUE ); else if ( (i == 9 && memcmp ( sDirective, "TRANSLATE", 9 ) == 0) || (i == 10 && memcmp ( sDirective, "XTRANSLATE", 10 ) == 0) ) /* --- #translate --- */ ParseCommand ( sLine, (i==9)? FALSE:TRUE, FALSE ); else if ( i == 6 && memcmp ( sDirective, "STDOUT", 6 ) == 0 ) printf ( "%s\n", sLine ); /* --- #stdout --- */ else if ( i == 5 && memcmp ( sDirective, "ERROR", 5 ) == 0 ) /* --- #error --- */ GenError( _szPErrors, 'P', ERR_EXPLICIT, sLine, NULL ); else if ( i == 4 && memcmp ( sDirective, "LINE", 4 ) == 0 ) return -1; else GenError( _szPErrors, 'P', ERR_WRONG_DIRECTIVE, sDirective, NULL ); } return 0; } int ParseDefine( char* sLine) { char defname[MAX_NAME], pars[MAX_NAME]; int i, npars = -1; DEFINES *lastdef; HB_TRACE(HB_TR_DEBUG, ("ParseDefine(%s)", sLine)); SKIPTABSPACES( sLine ); if( isalpha( *sLine ) || *sLine == '_' || *sLine > 0x7e ) { NextName( &sLine, defname ); if ( *sLine == '(' ) /* If pseudofunction was found */ { sLine++; i = 0; npars = 0; while ( *sLine != '\0' && *sLine != ')') { if ( *sLine == ',' ) npars++; if ( *sLine != ' ' && *sLine != '\t' ) *(pars+i++) = *sLine; sLine++; } if ( i > 0 ) npars++; *(pars+i) = '\0'; sLine++; } SKIPTABSPACES(sLine); lastdef = AddDefine ( defname, ( *sLine == '\0' )? NULL : sLine ); lastdef->npars = npars; lastdef->pars = ( npars <= 0 )? NULL : strodup ( pars ); } else GenError( _szPErrors, 'P', ERR_DEFINE_ABSENT, NULL, NULL ); return 0; } DEFINES* AddDefine ( char* defname, char* value ) { DEFINES* stdef = DefSearch( defname ); HB_TRACE(HB_TR_DEBUG, ("AddDefine(%s, %s)", defname, value)); if ( stdef != NULL ) stdef->pars = NULL; else { stdef = ( DEFINES * ) hb_xgrab( sizeof( DEFINES ) ); stdef->last = topDefine; topDefine = stdef; stdef->name = strodup ( defname ); } stdef->value = ( value == NULL )? NULL : strodup ( value ); return stdef; } int ParseUndef( char* sLine) { char defname[MAX_NAME]; DEFINES* stdef; HB_TRACE(HB_TR_DEBUG, ("ParseUndef(%s)", sLine)); NextWord( &sLine, defname, FALSE ); if ( ( stdef = DefSearch(defname) ) != NULL ) stdef->name = NULL; return 0; } int ParseIfdef( char* sLine, int usl) { char defname[MAX_NAME]; DEFINES *stdef; HB_TRACE(HB_TR_DEBUG, ("ParseIfdef(%s, %d)", sLine, usl)); if ( nCondCompile==0 || aCondCompile[nCondCompile-1]) { NextWord( &sLine, defname, FALSE ); if ( *defname == '\0' ) GenError( _szPErrors, 'P', ERR_DEFINE_ABSENT, NULL, NULL ); } if ( nCondCompile == maxCondCompile ) { maxCondCompile += 5; aCondCompile = (int*)hb_xrealloc( aCondCompile, sizeof( int ) * maxCondCompile ); } if ( nCondCompile==0 || aCondCompile[nCondCompile-1]) { if ( ( (stdef = DefSearch(defname)) != NULL && usl ) || ( stdef == NULL && !usl ) ) aCondCompile[nCondCompile] = 1; else aCondCompile[nCondCompile] = 0; } else aCondCompile[nCondCompile] = 0; nCondCompile++; return 0; } DEFINES* DefSearch(char *defname) { int j; DEFINES * stdef = topDefine; HB_TRACE(HB_TR_DEBUG, ("DefSearch(%s)", defname)); while( stdef != NULL ) { if( stdef->name != NULL ) { for ( j=0; *(stdef->name+j) == *(defname+j) && *(stdef->name+j) != '\0'; j++ ); if ( *(stdef->name+j) == *(defname+j) ) return stdef; } stdef = stdef->last; } return NULL; } COMMANDS* ComSearch(char *cmdname, COMMANDS *stcmdStart) { int j; COMMANDS *stcmd = ( stcmdStart )? stcmdStart:topCommand; HB_TRACE(HB_TR_DEBUG, ("ComSearch(%s, %p)", cmdname, stcmdStart)); while( stcmd != NULL ) { for ( j=0; (*(stcmd->name+j)==toupper(*(cmdname+j))) && (*(stcmd->name+j)!='\0') && ((stcmd->com_or_xcom)? 1:(j<4 || ISNAME(*(cmdname+j+1)))); j++ ); if ( (*(stcmd->name+j)==toupper(*(cmdname+j))) || ( !stcmd->com_or_xcom && j >= 4 && *(stcmd->name+j)!='\0' && *(cmdname+j) == '\0' ) ) break; stcmd = stcmd->last; } return stcmd; } COMMANDS* TraSearch(char *cmdname, COMMANDS *sttraStart) { int j; COMMANDS *sttra = ( sttraStart )? sttraStart:topTranslate; HB_TRACE(HB_TR_DEBUG, ("TraSearch(%s, %p)", cmdname, sttraStart)); while( sttra != NULL ) { for ( j=0; *(sttra->name+j)==toupper(*(cmdname+j)) && *(sttra->name+j)!='\0' && ((sttra->com_or_xcom)? 1:(j<4 || ISNAME(*(cmdname+j+1)))); j++ ); if ( *(sttra->name+j)==toupper(*(cmdname+j)) || ( !sttra->com_or_xcom && j >= 4 && *(sttra->name+j)!='\0' && *(cmdname+j) == '\0' ) ) break; sttra = sttra->last; } return sttra; } void ParseCommand( char* sLine, int com_or_xcom, int com_or_tra ) { static char mpatt[PATTERN_SIZE], rpatt[PATTERN_SIZE]; char cmdname[MAX_NAME]; COMMANDS *stcmd; int mlen,rlen; int ipos; HB_TRACE(HB_TR_DEBUG, ("ParseCommand(%s, $d, $d)", sLine, com_or_xcom, com_or_tra)); NextWord( &sLine, cmdname, FALSE ); stroupper( cmdname ); SKIPTABSPACES(sLine); if ( (ipos = pp_strAt( "=>", 2, sLine, strolen(sLine) )) > 0 ) stroncpy( mpatt, sLine, ipos-1 ); else GenError( _szPErrors, 'P', ERR_COMMAND_DEFINITION, NULL, NULL ); mlen = strotrim( mpatt ); sLine += ipos + 1; SKIPTABSPACES(sLine); strocpy( rpatt, sLine ); rlen = strotrim( rpatt ); ConvertPatterns ( mpatt, mlen, rpatt, rlen ); if ( com_or_tra ) stcmd = AddCommand ( cmdname ); else stcmd = AddTranslate ( cmdname ); stcmd->com_or_xcom = com_or_xcom; stcmd->mpatt = strodup ( mpatt ); stcmd->value = ( rlen > 0 )? strodup ( rpatt ) : NULL; } /* ConvertPatterns() * Converts result pattern in #command and #translate to inner format */ void ConvertPatterns ( char *mpatt, int mlen, char *rpatt, int rlen ) { int i = 0, ipos, ifou; int explen,rmlen; char exppatt[MAX_NAME], expreal[5] = "\1 0"; char lastchar = '@', exptype; char *ptr; HB_TRACE(HB_TR_DEBUG, ("ConvertPatterns(%s, $d, %s, $d)", mpatt, mlen, rpatt, rlen)); while ( *(mpatt+i) != '\0' ) { if ( *(mpatt+i) == '<' ) { /* Drag match marker, determine it type */ explen = 0; ipos = i; i++; exptype = '0'; while( *(mpatt+i) == ' ' || *(mpatt+i) == '\t' ) i++; if ( *(mpatt+i) == '*' ) /* Wild match marker */ { exptype = '3'; i++; } else if ( *(mpatt+i) == '(' ) /* Extended expression match marker */ { exptype = '4'; i++; } while ( *(mpatt+i) != '>' ) { if ( *(mpatt+i) == ',' ) /* List match marker */ { exptype = '1'; while ( *(mpatt+i) != '>' ) i++; break; } else if ( *(mpatt+i) == ':' ) /* Restricted match marker */ { exptype = '2'; *(mpatt+i--) = ' '; break; } if( *(mpatt+i) != ' ' && *(mpatt+i) != '\t' ) *(exppatt+explen++) = *(mpatt+i); i++; } if ( exptype == '3' ) { if ( *(exppatt+explen-1) == '*' ) explen--; else GenError( _szPErrors, 'P', ERR_PATTERN_DEFINITION, NULL, NULL ); } else if ( exptype == '4' ) { if ( *(exppatt+explen-1) == ')' ) explen--; else GenError( _szPErrors, 'P', ERR_PATTERN_DEFINITION, NULL, NULL ); } rmlen = i - ipos + 1; /* Convert match marker into inner format */ lastchar = (lastchar!='Z')? ( (char) ( (unsigned int)lastchar + 1 ) ): 'a'; expreal[1] = lastchar; expreal[2] = exptype; pp_Stuff ( expreal, mpatt+ipos, 4, rmlen, mlen ); mlen += 4 - rmlen; i += 4 - rmlen; /* Look for appropriate result markers */ ptr = rpatt; while ( (ifou = pp_strAt( exppatt, explen, ptr, rlen-(ptr-rpatt) )) > 0 ) { /* Convert result marker into inner format */ ptr += ifou; if ( *(ptr-2) == '<' && *(ptr+explen-1) == '>' && *(ptr-3) != '\\' && *(ptr+explen-2) != '\\' ) /* <...> */ { if ( *(ptr-3) == '#' && *(ptr-4) != '\\' ) /* #<...> */ { exptype = '1'; ptr -= 3; rmlen = explen+3; } else { exptype = '0'; ptr -= 2; rmlen = explen+2; } } else if ( *(ptr-3) == '<' && *(ptr+explen) == '>' && *(ptr-4) != '\\' && *(ptr+explen-1) != '\\' ) /* < ... > */ { ptr -= 2; if ( *ptr == '\"' ) exptype = '2'; else if ( *ptr == '(' ) exptype = '3'; else if ( *ptr == '{' ) exptype = '4'; else if ( *ptr == '.' ) exptype = '5'; ptr--; rmlen = explen+4; } else continue; expreal[2] = exptype; pp_Stuff ( expreal, ptr, 4, rmlen, rlen ); rlen += 4 - rmlen; } } i++; } } COMMANDS* AddCommand ( char *cmdname ) { COMMANDS *stcmd; HB_TRACE(HB_TR_DEBUG, ("AddCommand(%s)", cmdname)); stcmd = ( COMMANDS * ) hb_xgrab( sizeof( COMMANDS ) ); stcmd->last = topCommand; topCommand = stcmd; stcmd->name = strodup ( cmdname ); return stcmd; } COMMANDS* AddTranslate ( char *traname ) { COMMANDS *sttra; HB_TRACE(HB_TR_DEBUG, ("AddTranslate(%s)", traname)); sttra = ( COMMANDS * ) hb_xgrab( sizeof( COMMANDS ) ); sttra->last = topTranslate; topTranslate = sttra; sttra->name = strodup ( traname ); return sttra; } int ParseExpression( char* sLine, char* sOutLine ) { char sToken[MAX_NAME]; char *ptri, *ptro, *ptrb; int lenToken, i, ipos, isdvig, lens; int ifou; int rezDef, rezTra, rezCom, kolpass = 0; DEFINES *stdef; COMMANDS *stcmd; HB_TRACE(HB_TR_DEBUG, ("ParseExpression(%s, %s)", sLine, sOutLine)); do { strotrim ( sLine ); rezDef = 0; rezTra = 0; rezCom = 0; isdvig = 0; do { ptro = sOutLine; ptri = sLine + isdvig; ipos = md_strAt( ";", 1, ptri, TRUE, FALSE ); if ( ipos > 0 ) *(ptri+ipos-1) = '\0'; SKIPTABSPACES( ptri ); if ( *ptri == '#' ) { ParseDirective( ptri+1 ); if ( ipos > 0 ) *( sLine + isdvig + ipos - 1 ) = ';'; lens = strolen( sLine+isdvig ); pp_Stuff ( " ", sLine+isdvig, 0, (ipos)? ipos:lens, lens ); if( ipos > 0 ) ipos = 1; } else { /* Look for macros from #define */ while ( ( lenToken = NextName( &ptri, sToken ) ) > 0 ) if ( (stdef=DefSearch(sToken)) != NULL ) { ptrb = ptri - lenToken; if ( ( i = WorkDefine ( &ptri, ptro, stdef ) ) >= 0 ) { rezDef++; lens = strolen( ptrb ); if ( ipos > 0 ) { *(ptrb+lens) = ';'; lens += strolen( ptrb+lens+1 ); } pp_Stuff ( ptro, ptrb, i, ptri-ptrb, lens+1 ); if ( ipos > 0 ) { ipos += i - (ptri-ptrb); *(sLine + isdvig + ipos - 1) = '\0'; } ptri += i - (ptri-ptrb); } } /* Look for definitions from #translate */ stcmd = topTranslate; while( stcmd != NULL ) { ptri = sLine + isdvig; lenToken = strolen(stcmd->name); while( ( ifou = md_strAt( stcmd->name, lenToken, ptri, TRUE, FALSE )) > 0 ) { ptri += ifou -1; if( (i = WorkTranslate( ptri+lenToken, ptro, stcmd, &lens )) >= 0 ) { lens += lenToken; while ( lens > 0 && (*(ptri+lens-1)==' ' || *(ptri+lens-1)=='\t') ) lens--; if ( ipos > 0 ) *(sLine+isdvig+ipos-1) = ';'; pp_Stuff( ptro, ptri, i, lens, strolen(ptri) ); rezTra = 1; if ( ipos > 0 ) { ipos += i - lens; *(sLine+isdvig+ipos-1) = '\0'; } ptri += i; } else ptri += lenToken; } stcmd = stcmd->last; } /* Look for definitions from #command */ if ( kolpass < 3 ) { ptri = sLine + isdvig; SKIPTABSPACES( ptri ); if ( ISNAME(*ptri) ) NextName( &ptri, sToken ); else { i = 0; while ( *ptri != ' ' && *ptri != '\t' && *ptri != '\0' && *ptri != '\"' && *ptri != '\'' && *ptri != '(' && !ISNAME(*ptri) ) { *(sToken+i) = *ptri++; i++; } *(sToken+i) = '\0'; } SKIPTABSPACES( ptri ); if ( ( *ptri == '\0' || ( *ptri != '=' && (!IsInStr(*ptri,":/*+-") || *(ptri+1) != '=') && ( *ptri != '-' || *(ptri+1) != '>' ) ) ) && ( stcmd = ComSearch(sToken,NULL) ) != NULL ) { ptro = sOutLine; i = WorkCommand( ptri, ptro, stcmd ); ptri = sLine + isdvig; if ( ipos > 0 ) *(ptri+ipos-1) = ';'; if ( i >= 0 ) { if ( isdvig + ipos > 0 ) { lens = strolen( sLine+isdvig ); pp_Stuff ( ptro, sLine+isdvig, i, (ipos)? ipos-1:lens, lens ); if( ipos > 0 ) ipos = i + 1; } else memcpy ( sLine, sOutLine, i+1); } rezCom = 1; } else if ( ipos > 0 ) *(sLine+isdvig+ipos-1) = ';'; } else if ( ipos > 0 ) *(sLine+isdvig+ipos-1) = ';'; } isdvig += ipos; } while ( ipos != 0 ); kolpass++; if( kolpass > 20 && rezDef ) GenError( _szPErrors, 'P', ERR_RECURSE, NULL, NULL ); } while ( rezDef || rezTra || rezCom ); return 0; } int WorkDefine ( char** ptri, char* ptro, DEFINES *stdef ) { int npars, lens; char *ptr; HB_TRACE(HB_TR_DEBUG, ("WorkDefine(%p, %s, %p)", ptri, ptro, stdef)); if ( stdef->npars < 0 ) lens = strocpy( ptro,stdef->value ); else { SKIPTABSPACES( *ptri ); if ( **ptri == '(' ) { npars = 0; ptr = *ptri; do { ptr++; if ( NextParm( &ptr, NULL ) > 0 ) npars++; } while ( *ptr != ')' && *ptr != '\0' ); if ( *ptr == ')' && stdef->npars == npars ) lens = WorkPseudoF( ptri, ptro, stdef ); else return -1; } else return -1; } return lens; } int WorkPseudoF ( char** ptri, char* ptro, DEFINES *stdef ) { char parfict[MAX_NAME], *ptrreal; char *ptrb; int ipos, ifou, ibeg; int lenfict, lenreal, lenres; HB_TRACE(HB_TR_DEBUG, ("WorkPseudoF(%p, %s, %p)", ptri, ptro, stdef)); lenres = strocpy( ptro, stdef->value ); /* Copying value of macro to destination string */ if ( stdef->pars ) { ipos = 0; ibeg = 0; do /* Parsing through parameters */ { /* in macro definition */ if ( *(stdef->pars+ipos) == ',' || *(stdef->pars+ipos) == '\0' ) { *(parfict+ipos-ibeg) = '\0'; lenfict = ipos - ibeg; if ( **ptri != ')' ) { (*ptri)++; /* Get next real parameter */ SKIPTABSPACES( *ptri ); ptrreal = *ptri; lenreal = NextParm( ptri, NULL); ptrb = ptro; while ( (ifou = pp_strAt( parfict, lenfict, ptrb, lenres-(ptrb-ptro) )) > 0 ) { ptrb = ptrb+ifou-1; if ( !ISNAME(*(ptrb-1)) && !ISNAME(*(ptrb+lenfict)) ) { pp_Stuff ( ptrreal, ptrb, lenreal, lenfict, lenres ); lenres += lenreal - lenfict; ptrb += lenreal; } else ptrb++; } ibeg = ipos+1; } } else *(parfict+ipos-ibeg) = *(stdef->pars+ipos); if ( *(stdef->pars+ipos) == '\0' ) break; ipos++; } while ( 1 ); } else while ( **ptri != ')' ) (*ptri)++; (*ptri)++; return lenres; } int WorkCommand ( char* ptri, char* ptro, COMMANDS *stcmd ) { int rez; int lenres; char *ptrmp; char *sToken = stcmd->name; HB_TRACE(HB_TR_DEBUG, ("WorkCommand(%s, %s, %p)", ptri, ptro, stcmd)); do { lenres = strocpy ( ptro, stcmd->value ); /* Copying result pattern */ ptrmp = stcmd->mpatt; /* Pointer to a match pattern */ Repeate = 0; groupchar = '@'; rez = CommandStuff ( ptrmp, ptri, ptro, &lenres, TRUE, stcmd->com_or_xcom ); stcmd = stcmd->last; if ( rez < 0 && stcmd != NULL ) stcmd = ComSearch(sToken, stcmd); } while ( rez < 0 && stcmd != NULL ); *(ptro+lenres) = '\0'; if ( rez >= 0 ) return lenres; return -1; } int WorkTranslate ( char* ptri, char* ptro, COMMANDS *sttra, int *lens ) { int rez; int lenres; char *ptrmp; char *sToken = sttra->name; HB_TRACE(HB_TR_DEBUG, ("WorkTranslate(%s, %s, %p, %p)", ptri, ptro, sttra, lens)); do { lenres = strocpy ( ptro, sttra->value ); ptrmp = sttra->mpatt; Repeate = 0; groupchar = '@'; rez = CommandStuff ( ptrmp, ptri, ptro, &lenres, FALSE, sttra->com_or_xcom ); sttra = sttra->last; if ( rez < 0 && sttra != NULL ) sttra = TraSearch(sToken, sttra); } while ( rez < 0 && sttra != NULL ); *(ptro+lenres) = '\0'; if ( rez >= 0 ) { *lens = rez; return lenres; } return -1; } int CommandStuff ( char *ptrmp, char *inputLine, char * ptro, int *lenres, int com_or_tra, int com_or_xcom ) { int endTranslation = FALSE, ipos; char *lastopti[3], *strtopti = NULL, *strtptri = NULL; char *ptri = inputLine, *ptr, tmpname[MAX_NAME]; HB_TRACE(HB_TR_DEBUG, ("CommandStuff(%s, %s, %s, %p, %d, %d)", ptrmp, inputLine, ptro, lenres, com_or_tra, com_or_xcom)); numBrackets = 0; SKIPTABSPACES( ptri ); if ( ptrmp == NULL ) { if ( *ptri != '\0' ) return -1; } else while ( *ptri != '\0' && !endTranslation ) { SKIPTABSPACES( ptrmp ); if( *ptrmp == '[' && !numBrackets && !strtopti ) strtopti = ptrmp; if( !numBrackets && strtopti && strtptri != ptri && ISNAME( *ptri ) ) { strtptri = ptri; ptrmp = strtopti; ptr = ptri; ipos = NextName( &ptr, tmpname ); ipos = md_strAt( tmpname, ipos, strtopti, TRUE, TRUE ); if( ipos && TestOptional( strtopti, strtopti+ipos-2 ) ) { ptr = strtopti+ipos-2; ptr = PrevSquare( ptr, strtopti, NULL ); if( ptr ) ptrmp = ptr; } } switch ( *ptrmp ) { case '[': numBrackets++; aIsRepeate[ Repeate ] = 0; lastopti[Repeate++] = ptrmp; ptrmp++; if( !CheckOptional( ptrmp, ptri, ptro, lenres, com_or_tra, com_or_xcom ) ) SkipOptional( &ptrmp ); break; case ']': if( Repeate ) { Repeate--; if( aIsRepeate[ Repeate ] ) { if( ISNAME(*ptri) ) { ptr = ptri; ipos = NextName( &ptr, tmpname ); ipos = md_strAt( tmpname, ipos, ptrmp, TRUE, TRUE ); if( ipos && TestOptional( ptrmp+1, ptrmp+ipos-2 ) ) { ptr = PrevSquare( ptrmp+ipos-2, ptrmp+1, NULL ); if( !ptr || CheckOptional( ptrmp+1, ptri, ptro, lenres, com_or_tra, com_or_xcom ) ) { ptrmp = lastopti[Repeate]; ptrmp++; Repeate++; SkipOptional( &ptrmp ); numBrackets++; ptrmp++; strtptri = ptri; } else ptrmp = lastopti[Repeate]; } else ptrmp = lastopti[Repeate]; } else ptrmp = lastopti[Repeate]; } else ptrmp++; numBrackets--; } else { numBrackets--; ptrmp++; } break; case ',': if( !numBrackets ) strtopti = NULL; if ( *ptri == ',' ) { ptrmp++; ptri++; } else { if ( numBrackets ) { SkipOptional( &ptrmp ); } else return -1; } break; case '\1': /* Match marker */ if( !numBrackets ) strtopti = NULL; if ( !WorkMarkers( &ptrmp, &ptri, ptro, lenres, com_or_xcom ) ) { if ( numBrackets ) { SkipOptional( &ptrmp ); } else return -1; } break; case '\0': if ( com_or_tra ) return -1; else endTranslation = TRUE; break; default: /* Key word */ if( !numBrackets ) strtopti = NULL; ptr = ptri; if ( *ptri == ',' || truncmp( &ptri, &ptrmp, !com_or_xcom ) ) { ptri = ptr; if ( numBrackets ) { SkipOptional( &ptrmp ); } else return -1; } } SKIPTABSPACES( ptri ); }; if ( *ptrmp != '\0' ) { if ( Repeate ) { Repeate = 0; ptrmp = lastopti[0]; } numBrackets = 0; do { SKIPTABSPACES( ptrmp ); if ( *ptrmp != '\0' ) switch ( *ptrmp ) { case '[': ptrmp++; SkipOptional( &ptrmp ); ptrmp++; break; case ']': ptrmp++; break; default: return -1; } } while ( *ptrmp != '\0' ); } SearnRep( "\1","",0,ptro,lenres); *(ptro + *lenres) = '\0'; *lenres = RemoveSlash( ptro ); /* Removing '\' from result string */ if ( com_or_tra ) return 1; else return (ptri-inputLine); } int RemoveSlash( char *stroka ) { char *ptr = stroka; int State = STATE_INIT, lDirective = FALSE; int lenres = strolen( stroka ); HB_TRACE(HB_TR_DEBUG, ("RemoveSlash(%s)", stroka)); while( *ptr != '\0' ) { switch( State ) { case STATE_INIT: if( *ptr != ' ' && *ptr != '\t' ) State = STATE_NORMAL; if( *ptr == '#' ) lDirective = TRUE; case STATE_NORMAL: if( *ptr == '\'' ) State = STATE_QUOTE1; else if( *ptr == '\"' ) State = STATE_QUOTE2; else if( *ptr == ';' ) { State = STATE_INIT; lDirective = FALSE; } else if( !lDirective ) { if( *ptr == '\\' && ( *(ptr+1) == '[' || *(ptr+1) == ']' || *(ptr+1) == '{' || *(ptr+1) == '}' || *(ptr+1) == '<' || *(ptr+1) == '>' || *(ptr+1) == '\'' || *(ptr+1) == '\"' ) ) { pp_Stuff ( "", ptr, 0, 1, lenres - (ptr - stroka) ); lenres--; ptr++; } } break; case STATE_QUOTE1: if( *ptr == '\'' ) State = STATE_NORMAL; break; case STATE_QUOTE2: if( *ptr == '\"' ) State = STATE_NORMAL; break; } ptr++; } return lenres; } int WorkMarkers( char **ptrmp, char **ptri, char *ptro, int *lenres, int com_or_xcom ) { static char expreal[MAX_EXP]; char exppatt[MAX_NAME]; int lenreal = 0, maxlenreal = STR_SIZE, lenpatt; int rezrestr, ipos; char *ptr, *ptrtemp; HB_TRACE(HB_TR_DEBUG, ("WorkMarkers(%p, %p, %s, %p)", ptrmp, ptri, ptro, lenres)); /* Copying a match pattern to 'exppatt' */ lenpatt = stroncpy ( exppatt, *ptrmp, 4 ); *ptrmp += 4; SKIPTABSPACES ( *ptrmp ); if ( **ptri == ',' ) { if ( numBrackets ) { return 0; } } ptrtemp = *ptrmp; if ( *(exppatt+2) != '2' && *ptrtemp == ']' ) { ptrtemp++; SKIPTABSPACES ( ptrtemp ); } if ( *(exppatt+2) != '2' && *ptrtemp != '\1' && *ptrtemp != ',' && *ptrtemp != '[' && *ptrtemp != ']' && *ptrtemp != '\0' ) { lenreal = strincpy ( expreal, ptrtemp ); if ( (ipos = md_strAt( expreal, lenreal, *ptri, TRUE, TRUE )) > 0 ) { if ( ptrtemp > *ptrmp ) { if ( ipos == 1 ) { if ( numBrackets ) { return 0; } } else { maxlenreal = ipos - 1; lenreal = 0; } } else { lenreal = stroncpy( expreal, *ptri, ipos-1 ); if ( ipos > 1 && isExpres ( expreal ) ) *ptri += lenreal; else { if ( numBrackets ) { return 0; } } } } else { if ( numBrackets ) { return 0; } else lenreal = 0; } } if ( *(exppatt+2) == '4' ) /* ---- extended match marker */ { if ( !lenreal ) lenreal = getExpReal ( expreal, ptri, FALSE, maxlenreal ); SearnRep( exppatt,expreal,lenreal,ptro,lenres); } else if ( *(exppatt+2) == '3' ) /* ---- wild match marker */ { lenreal = strocpy ( expreal, *ptri ); *ptri += lenreal; SearnRep( exppatt,expreal,lenreal,ptro,lenres); } else if ( *(exppatt+2) == '2' ) /* ---- restricted match marker */ { while ( **ptrmp != '>' ) *(exppatt+lenpatt++) = *((*ptrmp)++); *(exppatt+lenpatt) = '\0'; (*ptrmp)++; ptr = exppatt + 4; rezrestr = 0; while ( *ptr != '\0' ) { if ( *ptr == '&' ) { if ( **ptri == '&' ) { rezrestr = 1; /* (*ptri)++; */ lenreal = getExpReal ( expreal, ptri, FALSE, maxlenreal ); SearnRep( exppatt,expreal,lenreal,ptro,lenres); break; } else ptr++; } else { SKIPTABSPACES( ptr ); /* Comparing real parameter and restriction value */ ptrtemp = ptr; if ( !strincmp ( *ptri, &ptr, !com_or_xcom ) ) { lenreal = stroncpy( expreal, *ptri, (ptr-ptrtemp) ); *ptri += lenreal; SearnRep( exppatt,expreal,lenreal,ptro,lenres); rezrestr = 1; break; } else { while ( *ptr != ',' && *ptr != '\0' ) ptr++; if ( *ptr == ',' ) ptr++; } } } if ( rezrestr == 0 ) { /* If restricted match marker doesn't correspond to real parameter */ if ( numBrackets ) { return 0; } else return 0; } } else if ( *(exppatt+2) == '1' ) /* ---- list match marker */ { if ( !lenreal ) lenreal = getExpReal ( expreal, ptri, TRUE, maxlenreal ); SearnRep( exppatt,expreal,lenreal,ptro,lenres); } else /* ---- regular match marker */ { /* Copying a real expression to 'expreal' */ if ( !lenreal ) lenreal = getExpReal ( expreal, ptri, FALSE, maxlenreal ); SearnRep( exppatt,expreal,lenreal,ptro,lenres); } return 1; } int getExpReal ( char *expreal, char **ptri, int prlist, int maxrez ) { int lens = 0; char *sZnaki = "+-=><*/$.&:#%!^"; int State; int StBr1 = 0, StBr2 = 0, StBr3 = 0; int rez = 0; HB_TRACE(HB_TR_DEBUG, ("getExpReal(%s, %p, %d, %d)", expreal, ptri, prlist, maxrez)); SKIPTABSPACES ( *ptri ); State = (**ptri=='\'' || **ptri=='\"')? STATE_EXPRES:STATE_ID; while ( **ptri != '\0' && !rez && lens < maxrez ) { switch ( State ) { case STATE_QUOTE1: if(**ptri=='\'') State = (StBr1==0 && StBr2==0 && StBr3==0)? STATE_ID_END:STATE_BRACKET; break; case STATE_QUOTE2: if(**ptri=='\"') State = (StBr1==0 && StBr2==0 && StBr3==0)? STATE_ID_END:STATE_BRACKET; break; case STATE_BRACKET: if ( **ptri == '\'' ) State = STATE_QUOTE1; else if ( **ptri == '\"' ) State = STATE_QUOTE2; else if ( **ptri == '(' ) StBr1++; else if ( **ptri == '[' ) StBr2++; else if ( **ptri == '{' ) StBr3++; else if ( **ptri == ')' ) { StBr1--; if (StBr1==0 && StBr2==0 && StBr3==0) State = STATE_ID_END; } else if ( **ptri == ']' ) { StBr2--; if (StBr1==0 && StBr2==0 && StBr3==0) State = STATE_ID_END; } else if ( **ptri == '}' ) { StBr3--; if (StBr1==0 && StBr2==0 && StBr3==0) State = STATE_ID_END; } break; case STATE_ID: case STATE_ID_END: if ( ( (ISNAME(**ptri) || **ptri=='\\') && State == STATE_ID_END ) || **ptri==',' || **ptri=='\'' || **ptri=='\"' || **ptri==')' ) { if ( **ptri == ',' ) { if ( !prlist ) rez = 1; State = STATE_EXPRES; } else rez = 1; } else if ( IsInStr( **ptri, sZnaki ) ) { State = STATE_EXPRES; } else if ( **ptri == '(' ) { State = STATE_BRACKET; StBr1 = 1; } else if ( **ptri == '[' ) { State = STATE_BRACKET; StBr2 = 1; } else if ( **ptri == '{' ) { State = STATE_BRACKET; StBr3 = 1; } else if ( **ptri == ' ' ) State = STATE_ID_END; break; case STATE_EXPRES: case STATE_EXPRES_ID: if ( **ptri == '\'' ) State = STATE_QUOTE1; else if ( **ptri == '\"' ) State = STATE_QUOTE2; else if ( ISNAME(**ptri) ) State = STATE_EXPRES_ID; else if ( **ptri == ' ' ) { if( State == STATE_EXPRES_ID ) State = STATE_ID_END; else if( lens > 2 && ( ( *(*ptri-2)=='+' && *(*ptri-1)=='+' ) || ( *(*ptri-2)=='-' && *(*ptri-1)=='-' ) ) ) State = STATE_ID_END; } else if ( **ptri == '(' ) { StBr1++; State = STATE_BRACKET; } else if ( **ptri == '[' ) { StBr2++; State = STATE_BRACKET; } else if ( **ptri == '{' ) { StBr3++; State = STATE_BRACKET; } else if ( **ptri == ',' ) { if ( !prlist ) rez = 1; State = STATE_EXPRES; } else if( **ptri == '.' && *(*ptri-2) == '.' && ( *(*ptri-1) == 'T' || *(*ptri-1) == 'F' || *(*ptri-1) == 't' || *(*ptri-1) == 'f' ) ) State = STATE_ID_END; else State = STATE_EXPRES; break; } if ( !rez ) { if ( expreal != NULL ) *expreal++ = **ptri; (*ptri)++; lens++; } } if ( expreal != NULL ) { if ( *(expreal-1) == ' ' ) { expreal--; lens--; }; *expreal = '\0'; } return lens; } int isExpres ( char* stroka ) { HB_TRACE(HB_TR_DEBUG, ("isExpres(%s)", stroka)); if ( strolen ( stroka ) > getExpReal ( NULL, &stroka, FALSE, STR_SIZE ) ) return 0; else return 1; } int TestOptional( char *ptr1, char *ptr2 ) { int nbr = 0, flagname = 0, statevar = 0; HB_TRACE(HB_TR_DEBUG, ("TestOptional(%s, %s)", ptr1, ptr2)); while( ptr1 <= ptr2 ) { if( *ptr1 == '[' ) nbr++; else if( *ptr1 == ']' ) { if( nbr ) { nbr--; flagname = 0; } else return 0; } else if( *ptr1 == '\1' && *(ptr1+2) == '2' && nbr ) statevar = 1; else if( *ptr1 == '>' && statevar ) statevar = 0; else if( *ptr1 != ' ' && *ptr1 != '\t' && !statevar ) { if( nbr ) flagname = 1; else return 0; } ptr1++; } /* if( !flagname ) while( *ptr1 != ']' ) { if( *ptr1 == '[' || *ptr1 == '\0' ) return 0; ptr1++; } */ return !flagname; } int CheckOptional( char* ptrmp, char* ptri, char* ptro, int* lenres, int com_or_tra, int com_or_xcom ) { int save_numBr = numBrackets, save_Repeate = Repeate; int endTranslation = FALSE, result = TRUE; char *lastInputptr[5]; char *lastopti[3], *ptr; HB_TRACE(HB_TR_DEBUG, ("CheckOptional(%s, %s, %s, %p, %d, %d)", ptrmp, ptri, ptro, lenres, com_or_tra, com_or_xcom)); lReplacePat = FALSE; lastInputptr[Repeate] = ptri; while ( *ptri != '\0' && !endTranslation && result ) { SKIPTABSPACES( ptrmp ); switch ( *ptrmp ) { case '[': numBrackets++; aIsRepeate[ Repeate ] = 0; lastInputptr[Repeate] = ptri; lastopti[Repeate++] = ptrmp; ptrmp++; break; case ']': if( numBrackets == save_numBr ) endTranslation = TRUE; else { if( Repeate ) { Repeate--; ptrmp = lastopti[Repeate]; } else ptrmp++; numBrackets--; } break; case ',': if ( *ptri == ',' ) { ptrmp++; ptri++; } else { if ( numBrackets - save_numBr > 0 ) { SkipOptional( &ptrmp ); ptri = lastInputptr[Repeate]; } else result = FALSE; } break; case '\1': /* Match marker */ if ( !WorkMarkers( &ptrmp, &ptri, ptro, lenres, com_or_xcom ) ) { if ( numBrackets - save_numBr > 0 ) { SkipOptional( &ptrmp ); ptri = lastInputptr[Repeate]; } else result = FALSE; } break; case '\0': result = FALSE; default: /* Key word */ ptr = ptri; if ( *ptri == ',' || truncmp( &ptri, &ptrmp, !com_or_xcom ) ) { ptri = ptr; if ( numBrackets - save_numBr > 0 ) { SkipOptional( &ptrmp ); ptri = lastInputptr[Repeate]; } else result = FALSE; } } SKIPTABSPACES( ptri ); }; if ( *ptri == '\0' ) { do { SKIPTABSPACES( ptrmp ); if( *ptrmp == '[' ) { ptrmp++; SkipOptional( &ptrmp ); } else if( *ptrmp == ']' ) break; else { result = 0; break; } } while ( 1 ); } Repeate = save_Repeate; numBrackets = save_numBr; lReplacePat = TRUE; return result ; } void SkipOptional( char** ptri ) { int nbr = 0; HB_TRACE(HB_TR_DEBUG, ("SkipOptional(%p)", ptri)); while ( **ptri != ']' || nbr ) { switch ( **ptri ) { case '[': nbr++; break; case ']': nbr--; break; case '\1': (*ptri) += 3; if ( *(*ptri-1) == '2' ) while ( **ptri != '>' ) (*ptri)++; break; } (*ptri)++; } if ( **ptri == ']' && numBrackets > 0 ) { if ( Repeate ) Repeate--; numBrackets--; (*ptri)++; } } void SearnRep( char *exppatt,char *expreal,int lenreal,char *ptro, int *lenres) { int ifou, isdvig = 0, rezs; int kolmarkers; int lennew, i; char lastchar = '0'; static char expnew[MAX_EXP]; char *ptr, *ptr2, *ptrOut = ptro; HB_TRACE(HB_TR_DEBUG, ("SearnRep(%s, %s, %d, %s, %p)", exppatt, expreal, lenreal, ptro, lenres)); if( *(exppatt+1) == '\0' ) *( ptro + *lenres ) = '\0'; while ( (ifou = md_strAt( exppatt, (*(exppatt+1))? 2:1, ptrOut, FALSE, FALSE )) > 0 ) { rezs = 0; ptr = ptrOut + ifou - 2; kolmarkers = 0; ptr = PrevSquare( ptr, ptrOut, &kolmarkers ); if ( ptr ) { if( Repeate ) aIsRepeate[ Repeate - 1 ]++; if( !lReplacePat ) return; ptr2 = ptrOut + ifou + 3; while ( *ptr2 != ']' || *(ptr2-1) == '\\' ) { if ( *ptr2 == '\1' ) kolmarkers++; ptr2++; } if ( Repeate && lenreal && kolmarkers && lastchar != '0' && *(ptrOut + ifou + 2) == '0' ) { isdvig += ifou; rezs = 1; } else { if ( lenreal == 0 ) { if( numBrackets >= 2 ) { isdvig += ifou; continue; } else { pp_Stuff ( "", ptr, 0, ptr2-ptr+1, *lenres-(ptr-ptro) ); *lenres -= ptr2-ptr+1; isdvig = ptr - ptro; rezs = 1; } } else { lennew = ptr2-ptr-1; memcpy ( expnew, ptr+1, lennew ); *(expnew + lennew++) = ' '; *(expnew + lennew) = '\0'; while ( (i = pp_strAt( exppatt, 2, expnew, lennew )) > 0 ) lennew += ReplacePattern ( exppatt[2], expreal, lenreal, expnew+i-1, lennew ); if ( kolmarkers ) { groupchar = (char) ( (unsigned int)groupchar + 1 ); for ( i=0; i 0 ); } else { pp_rQuotes( expreal, sQuotes ); pp_Stuff ( sQuotes, ptro, 2, 4, lenres ); pp_Stuff ( expreal, ptro+1, lenreal, 0, lenres ); rmlen = lenreal + 2; } break; case '3': /* Smart stringify result marker */ if ( patttype == '1' ) /* list match marker */ { pp_Stuff ( "", ptro, 0, 4, lenres ); lenres -= 4; rmlen = 0; do { ifou = md_strAt( ",", 1, expreal, FALSE, TRUE ); lenitem = (ifou)? ifou-1:lenreal; if( *expreal != '\0' ) { if ( !lenitem || *expreal == '(' || *expreal == '&' || (*expreal=='\"' && *(expreal+lenitem-1)=='\"') || (*expreal == '\'' && *(expreal+lenitem-1)=='\'') ) { if( ifou ) lenitem++; pp_Stuff ( (*expreal=='&')? expreal+1:expreal, ptro, (*expreal=='&')? lenitem-1:lenitem, 0, lenres ); } else { i = (ifou)? 3:2; pp_rQuotes( expreal, sQuotes ); pp_Stuff ( sQuotes, ptro, i, 0, lenres ); pp_Stuff ( expreal, ptro+1, lenitem, 0, lenres+i ); ptro += i; rmlen += i; } ptro += lenitem; rmlen += lenitem; } expreal += ifou; lenreal -= ifou; } while ( ifou > 0 ); } else if ( !lenreal || *expreal == '(' || *expreal == '&' || (*expreal=='\"' && *(expreal+lenreal-1)=='\"') || (*expreal == '\'' && *(expreal+lenreal-1)=='\'') ) pp_Stuff ( (*expreal=='&')? expreal+1:expreal, ptro, (*expreal=='&')? lenreal-1:lenreal, 4, lenres ); else { pp_rQuotes( expreal, sQuotes ); pp_Stuff ( sQuotes, ptro, 2, 4, lenres ); pp_Stuff ( expreal, ptro+1, lenreal, 0, lenres ); rmlen = lenreal + 2; } break; case '4': /* Blockify result marker */ if ( !lenreal ) pp_Stuff ( expreal, ptro, lenreal, 4, lenres ); else if ( patttype == '1' ) /* list match marker */ { pp_Stuff ( "", ptro, 0, 4, lenres ); lenres -= 4; rmlen = 0; do { ifou = md_strAt( ",", 1, expreal, FALSE, TRUE ); lenitem = (ifou)? ifou-1:lenreal; if( *expreal != '\0' ) { i = (ifou)? 5:4; pp_Stuff ( "{||},", ptro, i, 0, lenres ); pp_Stuff ( expreal, ptro+3, lenitem, 0, lenres+i ); ptro += i + lenitem; rmlen += i + lenitem; } expreal += ifou; lenreal -= ifou; } while ( ifou > 0 ); } else { pp_Stuff ( "{||}", ptro, 4, 4, lenres ); pp_Stuff ( expreal, ptro+3, lenreal, 0, lenres ); rmlen = lenreal + 4; } break; case '5': /* Logify result marker */ rmlen = 3; if ( !lenreal ) { pp_Stuff ( ".F.", ptro, 3, 4, lenres ); } else pp_Stuff ( ".T.", ptro, 3, 4, lenres ); break; } return rmlen - 4; } void pp_rQuotes( char *expreal, char *sQuotes ) { int lQuote1 = 0, lQuote2 = 0; HB_TRACE(HB_TR_DEBUG, ("pp_rQuotes(%s, %s)", expreal, sQuotes)); while( *expreal != '\0' ) { if( *expreal == '\"' ) lQuote2 = 1; else if( *expreal == '\'' ) lQuote1 = 1; expreal++; } if( lQuote2 ) { if( lQuote1 ) { *sQuotes = '['; *(sQuotes+1) = ']'; } else { *sQuotes = '\''; *(sQuotes+1) = '\''; } } else { *sQuotes = '\"'; *(sQuotes+1) = '\"'; } } int pp_RdStr(FILE* handl_i,char *buffer,int maxlen,int lDropSpaces,char* sBuffer, int* lenBuffer, int* iBuffer) { int readed = 0; int State = 0; char cha,cLast='\0'; HB_TRACE(HB_TR_DEBUG, ("pp_RdStr(%p, %s, %d, %d, %s, %p, %p)", handl_i, buffer, maxlen, lDropSpaces, sBuffer, lenBuffer, iBuffer)); if ( *lenBuffer == 0 ) return -1; while(1) { if ( *iBuffer == *lenBuffer ) { if ( (*lenBuffer = fread(sBuffer,1,BUFF_SIZE,handl_i)) < 1 ) sBuffer[0] = '\n'; *iBuffer = 0; } cha = sBuffer[*iBuffer]; (*iBuffer)++; if( cha == '\n' ) break; if ( maxlen > 0 ) { switch ( ParseState ) { case STATE_COMMENT: if ( cha == '/' && cLast == '*' ) { ParseState = STATE_NORMAL; cha = ' '; } cLast = cha; break; case STATE_QUOTE1: if(cha=='\'') ParseState = STATE_NORMAL; break; case STATE_QUOTE2: if(cha=='\"') ParseState = STATE_NORMAL; break; default: switch ( cha ) { case '[': ParseState = STATE_BRACKET; break; case ']': ParseState = STATE_NORMAL; break; case '\"': if( ParseState != STATE_BRACKET ) ParseState = STATE_QUOTE2; break; case '\'': if( ParseState != STATE_BRACKET ) ParseState = STATE_QUOTE1; break; case '&': if ( readed>0 && buffer[readed-1] == '&' ) { maxlen = 0; readed--; } break; case '/': if ( readed>0 && buffer[readed-1] == '/' ) { maxlen = 0; readed--; } break; case '*': if ( readed > 0 && buffer[readed-1] == '/' ) { ParseState = STATE_COMMENT; readed--; } else if ( !State ) maxlen = readed = 0; break; } } if ( cha != ' ' && cha != '\t' ) State = 1; if( lDropSpaces && State ) lDropSpaces = 0; if( readed= 0 && ( buffer[readed] == ' ' || buffer[readed] == '\t') ); readed++; buffer[readed]='\0'; return readed; } int pp_WrStr(FILE* handl_o,char *buffer) { int lens = strolen(buffer); HB_TRACE(HB_TR_DEBUG, ("pp_WrStr(%p, %s)", handl_o, buffer)); fwrite(buffer,lens,1,handl_o); if ( *(buffer+lens-1) != '\n' ) fwrite("\n",1,1,handl_o); return 0; } /* locates a substring in a string */ int pp_strAt(char *szSub, int lSubLen, char *szText, int lLen) { HB_TRACE(HB_TR_DEBUG, ("pp_strAt(%s, %d, %s, %d)", szSub, lSubLen, szText, lLen)); if( lSubLen ) { if( lLen >= lSubLen ) { long lPos = 0, lSubPos = 0; while( lPos < lLen && lSubPos < lSubLen ) { if( *(szText + lPos) == *(szSub + lSubPos) ) { lSubPos++; lPos++; } else if( lSubPos ) lSubPos = 0; else lPos++; } return (lSubPos < lSubLen? 0: lPos - lSubLen + 1); } else return 0; } else return 1; } int md_strAt(char *szSub, int lSubLen, char *szText, int checkword, int checkPrth) { int State = STATE_NORMAL; long lPos = 0, lSubPos = 0; int kolPrth = 0; int lCase = ( *szSub == '\1' )? 0:1; HB_TRACE(HB_TR_DEBUG, ("md_strAt(%s, %d, %s, %d, %d)", szSub, lSubLen, szText, checkword, checkPrth)); while( *(szText+lPos) != '\0' && lSubPos < lSubLen ) { if( State == STATE_QUOTE1 ) { if ( *(szText+lPos) == '\'' ) State = STATE_NORMAL; lPos++; } else if( State == STATE_QUOTE2 ) { if ( *(szText+lPos) == '\"' ) State = STATE_NORMAL; lPos++; } else { if ( *(szText+lPos) == '\"' && ( lPos == 0 || *(szText+lPos-1) != '\\' ) ) { State = STATE_QUOTE2; lPos++; continue; } else if ( *(szText+lPos) == '\'' && ( lPos == 0 || *(szText+lPos-1) != '\\' ) ) { State = STATE_QUOTE1; lPos++; continue; } else if ( *(szText+lPos) == '(' ) kolPrth++; else if ( *(szText+lPos) == ')' ) kolPrth--; if( !lSubPos && checkPrth && ( (kolPrth > 1) || (kolPrth == 1 && *(szText+lPos) != '(') || (kolPrth == 0 && *(szText+lPos) == ')')) ) { lPos++; continue; } if( ( lCase && toupper(*(szText + lPos)) == toupper(*(szSub + lSubPos)) ) || ( !lCase && *(szText + lPos) == *(szSub + lSubPos) ) ) { lSubPos++; lPos++; if ( lSubPos >= lSubLen && checkword && ( ( ISNAME(*szSub) && lPos>lSubPos && ISNAME(*(szText+lPos-lSubPos-1)) ) || ( ISNAME(*(szSub+lSubLen-1)) && ISNAME(*(szText+lPos)) ) ) ) lSubPos = 0; } else if( lSubPos ) lSubPos = 0; else lPos++; } } return (lSubPos < lSubLen? 0: lPos - lSubLen + 1); } char* PrevSquare( char* ptr, char* bound, int *kolmark ) { int State = STATE_NORMAL; HB_TRACE(HB_TR_DEBUG, ("PrevSquare(%s, %s, %d)", ptr, bound, *kolmark)); while( ptr > bound ) { if( State == STATE_QUOTE1 ) { if( *ptr == '\'' ) State = STATE_NORMAL; } else if( State == STATE_QUOTE2 ) { if( *ptr == '\"' ) State = STATE_NORMAL; } else { if( *ptr == '\"' && *(ptr-1) != '\\' ) State = STATE_QUOTE2; else if( *ptr == '\'' && *(ptr-1) != '\\' ) State = STATE_QUOTE1; else if( kolmark && *ptr == '\1' ) (*kolmark)++; else if( ( *ptr == '[' || *ptr == ']' ) && *(ptr-1) != '\\' ) break; } ptr--; } return ( *ptr == '[' && State == STATE_NORMAL )? ptr:NULL; } int IsInStr ( char symb, char* s ) { HB_TRACE(HB_TR_DEBUG, ("IsInStr(%c, %s)", symb, s)); while ( *s != '\0' ) if ( *s++ == symb ) return 1; return 0; } void pp_Stuff (char *ptri, char * ptro, int len1, int len2, int lenres ) { char *ptr1, *ptr2; int i; HB_TRACE(HB_TR_DEBUG, ("pp_Stuff(%s, %s, %d, %d, %d)", ptri, ptro, len1, len2, lenres)); if ( len1 > len2 ) { ptr1 = ptro+lenres; ptr2 = ptro + lenres + len1 - len2; for ( ; ptr1 >= ptro; ptr1--,ptr2-- ) *ptr2 = *ptr1; } else { ptr1 = ptro + len2; ptr2 = ptro + len1; for ( ; ptr1 <= ptro+lenres; ptr1++,ptr2++ ) *ptr2 = *ptr1; } ptr2 = ptro; for ( i=0; i < len1; i++ ) *ptr2++ = *(ptri+i); } int strocpy (char* ptro, char* ptri ) { int lens = 0; HB_TRACE(HB_TR_DEBUG, ("strocpy(%s, %s)", ptro, ptri)); if ( ptri != NULL ) while ( *ptri != '\0' ) { *ptro++ = *ptri++; lens++; } *ptro = '\0'; return lens; } int stroncpy (char* ptro, char* ptri, int lens ) { int i = 0; HB_TRACE(HB_TR_DEBUG, ("stroncpy(%s, %s, %d)", ptro, ptri, lens)); for ( ; i < lens; i++ ) *(ptro+i) = *ptri++; i--; while ( i > 0 && *(ptro+i) == ' ' ) i--; i++; *(ptro+i) = '\0'; return i; } int truncmp (char** ptro, char** ptri, int lTrunc ) { char *ptrb = *ptro, co, ci; HB_TRACE(HB_TR_DEBUG, ("truncmp(%p, %p, %d)", ptro, ptri, lTrunc)); for ( ; **ptri != ' ' && **ptri != '\t' && **ptri != ',' && **ptri != '[' && **ptri != ']' && **ptri != '\1' && **ptri != '\0' && toupper(**ptri)==toupper(**ptro); (*ptro)++, (*ptri)++ ); co = *(*ptro-1); ci = **ptri; if ( ( ( ci == ' ' || ci == ',' || ci == '[' || ci == ']' || ci == '\1' || ci == '\0' ) && ( ( !ISNAME(**ptro) && ISNAME(co) ) || ( !ISNAME(co) ) ) ) ) return 0; else if ( lTrunc && *ptro-ptrb >= 4 && ISNAME(ci) && !ISNAME(**ptro) && ISNAME(co) ) { while( ISNAME(**ptri) ) (*ptri)++; return 0; } return 1; } int strincmp (char* ptro, char** ptri, int lTrunc ) { char *ptrb = ptro, co, ci; HB_TRACE(HB_TR_DEBUG, ("strincmp(%s, %p)", ptro, ptri)); for ( ; **ptri != ',' && **ptri != '[' && **ptri != ']' && **ptri != '\1' && **ptri != '\0' && toupper(**ptri)==toupper(*ptro); ptro++, (*ptri)++ ); co = *(ptro-1); ci = **ptri; if ( ( ( ci == ' ' || ci == ',' || ci == '[' || ci == ']' || ci == '\1' || ci == '\0' ) && ( ( !ISNAME(*ptro) && ISNAME(co) ) || ( !ISNAME(co) ) ) ) ) return 0; else if ( lTrunc && ptro-ptrb >= 4 && ISNAME(ci) && !ISNAME(*ptro) && ISNAME(co) ) { // while( ISNAME(**ptri) ) (*ptri)++; return 0; } return 1; } int strincpy (char* ptro, char* ptri ) { int lens = 0; HB_TRACE(HB_TR_DEBUG, ("strincpy(%s, %s)", ptro, ptri)); for ( ; *ptri != ' ' && *ptri != ',' && *ptri != '[' && *ptri != ']' && *ptri != '\1' && *ptri != '\0'; ptro++, ptri++, lens++ ) *ptro = *ptri; return lens; } char* strodup ( char *stroka ) { char *ptr; int lens = 0; HB_TRACE(HB_TR_DEBUG, ("strodup(%s)", stroka)); while ( *(stroka+lens) != '\0' ) lens++; ptr = ( char * ) hb_xgrab( lens + 1 ); memcpy( ptr, stroka, lens+1 ); *(ptr+lens) = '\0'; return ptr; } int strolen ( char *stroka ) { int lens = 0; HB_TRACE(HB_TR_DEBUG, ("strolen(%s)", stroka)); while ( *(stroka+lens) != '\0' ) lens++; return lens; } void stroupper ( char *stroka ) { HB_TRACE(HB_TR_DEBUG, ("stroupper(%s)", stroka)); while ( *stroka != '\0' ) { *stroka = toupper(*stroka); stroka++; } } int strotrim ( char *stroka ) { char *ptr = stroka, lastc = '0', curc; int lens = 0, State = STATE_NORMAL; HB_TRACE(HB_TR_DEBUG, ("strotrim(%s)", stroka)); while ( ( curc = *stroka ) != '\0' ) { if ( State == STATE_QUOTE1 ) { if (curc == '\'') State = STATE_NORMAL; } else if ( State == STATE_QUOTE2 ) { if (curc=='\"') State = STATE_NORMAL; } else { if ( curc == '\'' ) State = STATE_QUOTE1; else if ( curc == '\"' ) State = STATE_QUOTE2; else if ( curc == '\t' ) curc = ' '; } if ( State != STATE_NORMAL || curc != ' ' || ( curc==' ' && lastc != ' ' && lastc != ',' && lastc != '(' && *(stroka+1)!=',') ) { *ptr++ = curc; lastc = curc; lens++; } stroka++; } *ptr = '\0'; return lens; } int NextWord ( char** sSource, char* sDest, int lLower ) { int i = 0; HB_TRACE(HB_TR_DEBUG, ("NextWord(%p, %s, %d)", sSource, sDest, lLower)); SKIPTABSPACES( (*sSource) ); while ( **sSource != '\0' && **sSource != ' ' && **sSource != '\t' && **sSource != '(') { *sDest++ = (lLower)? tolower(**sSource):**sSource; (*sSource)++; i++; } *sDest = '\0'; return i; } int NextName ( char** sSource, char* sDest ) { int lenName = 0, State = STATE_NORMAL; HB_TRACE(HB_TR_DEBUG, ("NextName(%p, %s)", sSource, sDest)); while ( **sSource != '\0' && ( !ISNAME(**sSource) || State != STATE_NORMAL ) ) { if ( State == STATE_QUOTE1 ) { if ( **sSource == '\'' ) State = STATE_NORMAL; } else if ( State == STATE_QUOTE2 ) { if ( **sSource == '\"' ) State = STATE_NORMAL; } else if ( **sSource == '\"' ) State = STATE_QUOTE2; else if ( **sSource == '\'' ) State = STATE_QUOTE1; (*sSource)++; } while ( **sSource != '\0' && ISNAME(**sSource) ) { *sDest++ = *(*sSource)++; lenName++; } *sDest = '\0'; return lenName; } int NextParm ( char** sSource, char* sDest ) { int lenName = 0, State = STATE_NORMAL, StBr = 0; HB_TRACE(HB_TR_DEBUG, ("NextParm(%p, %s)", sSource, sDest)); SKIPTABSPACES( (*sSource) ); while ( **sSource != '\0' ) { if ( State == STATE_QUOTE1 ) { if ( **sSource == '\'' ) State = STATE_NORMAL; } else if ( State == STATE_QUOTE2 ) { if ( **sSource == '\"' ) State = STATE_NORMAL; } else if ( **sSource == '\"' ) State = STATE_QUOTE2; else if ( **sSource == '\'' ) State = STATE_QUOTE1; else if ( **sSource == '(' ) StBr++; else if ( **sSource == ')' || **sSource == ',' ) { if( !StBr ) break; if( **sSource == ')' ) StBr--; } if ( sDest != NULL ) *sDest++ = **sSource; (*sSource)++; lenName++; } if ( sDest != NULL ) *sDest = '\0'; return lenName; } BOOL OpenInclude( char * szFileName, PATHNAMES *pSearch, FILE** fptr, BOOL bStandardOnly, char * szInclude ) { PHB_FNAME pFileName; HB_TRACE(HB_TR_DEBUG, ("OpenInclude(%s, %p, %p, %d)", szFileName, pSearch, fptr, (int) bStandardOnly)); if ( bStandardOnly ) { *fptr = 0; szInclude[ 0 ] = '\0'; } else { pFileName = hb_fsFNameSplit( szFileName ); pFileName->szPath = _pFileName->szPath; hb_fsFNameMerge( szInclude, pFileName ); *fptr = fopen( szInclude, "r" ); hb_xfree( pFileName ); } if ( !*fptr && pSearch ) { pFileName = hb_fsFNameSplit( szFileName ); pFileName->szName = szFileName; pFileName->szExtension = NULL; while ( pSearch && !*fptr ) { pFileName->szPath = pSearch->szPath; hb_fsFNameMerge( szInclude, pFileName ); *fptr = fopen( szInclude, "r" ); pSearch = pSearch->pNext; } hb_xfree( pFileName ); } return ( *fptr ? TRUE : FALSE ); }