Files
harbour-core/harbour/source/hbpp/hbpp.c
1999-05-24 09:29:16 +00:00

1136 lines
31 KiB
C

/* Harbour Preprocessor , version 0.7
author - Alexander Kresin */
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <mem.h>
#include <ctype.h>
#include "harb.h"
int Hp_Parse( int, int );
int ParseDirective( char* );
int ParseDefine( char* );
int ParseUndef( char* );
int ParseIfdef( char*, int);
int ParseCommand( char* );
int ParseExpression( char*, char* );
void WorkDefine ( char**, char**, int);
int WorkCommand ( char*, char**, char**, int);
void CmdParse ( char *ptri, int aCmdStru[100][2] );
void SkipOptional( char**, char*, int*);
int DefSearch(char *);
int ComSearch(char *,int);
void SearnRep( char*,int,char*,int,char*,int*);
int RdStr(int,char *,int,int,char*,int*,int*);
int WrStr(int,char *);
int hb_strAt(char *, int, char*, int);
int IsInStr ( char, char*);
void Stuff (char*, char*, int, int, int);
void Stringify( char *, int);
void pEnclose( char *, int, char);
int NextWord ( char**, char*);
int NextName ( char**, char*, char**);
#define isname(c) (isalnum(c) || c=='_' || (c) > 0x7e)
#define SKIPTABSPACES(sptr) while ( *sptr == ' ' || *sptr == '\t' ) (sptr)++
#define MAX_NAME 255
#define BUFF_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_BRACKET 8
#define IT_EXPR 1
#define IT_ID 2
#define IT_COMMA 3
int ParseState = 0;
int lInclude = 0;
int *aCondCompile, nCondCompile = 0, maxCondCompile = 5;
int nline=0;
int Repeate;
typedef struct
{
char *name;
char *pars;
int npars;
char *value;
} DEFINES;
DEFINES *aDefines ;
int koldefines = 0, maxdefines = 50;
typedef struct
{
char *name;
char *mpatt;
int npars;
char *value;
} COMMANDS;
#define INITIAL_ACOM_SIZE 250
COMMANDS *aCommands ;
int kolcommands = 0, maxcommands = INITIAL_ACOM_SIZE;
int main (int argc,char* argv[])
{
int handl_i,handl_o,i;
char szFileName[ _POSIX_PATH_MAX ];
FILENAME *pFileName =NULL;
if(argc<2) { printf("File name absent"); return 1; }
pFileName =SplitFilename( argv[1] );
if( !pFileName->extension )
pFileName->extension =".prg";
MakeFilename( szFileName, pFileName );
if ((handl_i = open(szFileName, O_RDONLY | O_TEXT)) == -1)
{ printf("Can't open %s",szFileName); return 1; }
pFileName->extension =".ppo";
MakeFilename( szFileName, pFileName );
if ((handl_o = open(szFileName, O_CREAT | O_WRONLY | O_TEXT)) == -1)
{ printf("Can't open %s",szFileName); return 1; }
aCondCompile = (int*) _xgrab( sizeof(int) * 5 );
aDefines = ( DEFINES * ) _xgrab( sizeof(DEFINES) * 50 );
aCommands = ( COMMANDS * ) _xgrab( sizeof(COMMANDS) * INITIAL_ACOM_SIZE );
Hp_Parse(handl_i,handl_o);
close(handl_i); close(handl_o);
/*
for (i=0;i<kolcommands;i++)
{
printf("\n%s",aCommands[i].name);
if (aCommands[i].mpatt !=NULL) printf(" /%s/",aCommands[i].mpatt);
if (aCommands[i].value !=NULL) printf(" /%s/",aCommands[i].value);
}
*/
return 0;
}
int Hp_Parse( int handl_i, int handl_o )
{
char sBuffer[BUFF_SIZE];
int iBuffer = 10, lenBuffer = 10;
char sLine[1024], sOutLine[1024];
int lChanged;
int lContinue = 0;
int lDirective;
int lens=0;
int i;
int rezParse;
while ( (i=RdStr(handl_i,sLine+lens, ((lDirective)? 1024:256)-lens,lContinue,sBuffer,&lenBuffer,&iBuffer ))>=0 )
{
if ( !lInclude ) nline++;
lens+=i;
lChanged = 0;
if( sLine[lens-1] == ';' )
{
lContinue = 1;
lens--; lens--;
while ( sLine[lens] == ' ' || sLine[lens] == '\t' ) lens--;
sLine[++lens] = '\0';
}
else { lContinue = 0; lens=0; }
if ( *sLine != '\0' && !lContinue )
{
i = 0;
while ( *(sLine+i) == ' ' || *(sLine+i) == '\t' ) i++;
if ( *(sLine+i) == '#' )
{
lDirective = 1;
if ( (rezParse=ParseDirective(sLine+i+1)) > 0 )
{
if ( !lInclude )
printf ( "\nError number %u in line %u", rezParse, nline );
return rezParse;
}
}
else
{
lDirective = 0;
if ( nCondCompile==0 || aCondCompile[nCondCompile-1])
{
if ( (rezParse = ParseExpression( sLine+i,sOutLine)) > 0 )
{
printf ( "\nError number %u in line %u", rezParse, nline );
return rezParse;
}
}
else *sLine = '\0';
}
}
if(!lInclude)
if(lDirective || lContinue) WrStr(handl_o,"\0");
else if(!lChanged) WrStr(handl_o,sLine);
}
return 0;
}
int ParseDirective( char* sLine )
{
char sDirective[11];
int i = 0;
int handl_i;
while ( *sLine != '\0' && (*sLine == ' ' || *sLine == '\t') ) sLine++;
while ( *sLine != '\0' && *sLine != ' ' && *sLine != '\t' && i<10 )
*(sDirective+i++) = tolower(*sLine++);
*(sDirective+i) = '\0';
SKIPTABSPACES(sLine);
if ( i == 4 && memcmp ( sDirective, "else", 4 ) == 0 )
{
if ( nCondCompile == 0 ) return 3001;
else aCondCompile[nCondCompile-1] = 1 - aCondCompile[nCondCompile-1];
}
else if ( i == 5 && memcmp ( sDirective, "endif", 5 ) == 0 )
{ if ( nCondCompile == 0 ) return 3001; else nCondCompile--; }
else if ( nCondCompile==0 || aCondCompile[nCondCompile-1])
{
if ( i == 7 && memcmp ( sDirective, "include", 7 ) == 0 )
{
if ( *sLine != '\"' ) return 1000;
sLine++; i = 0;
while ( *(sLine+i) != '\0' && *(sLine+i) != '\"' ) i++;
if ( *(sLine+i) != '\"' ) return 1000;
*(sLine+i) = '\0';
if ((handl_i = open(sLine, O_RDONLY | O_TEXT)) == -1)
{ printf("\nCan't open %s",sLine); return 1001; }
lInclude++;
Hp_Parse(handl_i, NULL);
lInclude--;
close(handl_i);
}
else if ( i == 6 && memcmp ( sDirective, "define", 6 ) == 0 )
ParseDefine ( sLine );
else if ( i == 5 && memcmp ( sDirective, "undef", 5 ) == 0 )
ParseUndef ( sLine );
else if ( i == 5 && memcmp ( sDirective, "ifdef", 5 ) == 0 )
ParseIfdef ( sLine, 1 );
else if ( i == 6 && memcmp ( sDirective, "ifndef", 6 ) == 0 )
ParseIfdef ( sLine, 0 );
else if ( (i == 7 && memcmp ( sDirective, "command", 7 ) == 0) ||
(i == 8 && memcmp ( sDirective, "xcommand", 8 ) == 0) )
ParseCommand ( sLine );
else if ( (i == 9 && memcmp ( sDirective, "translate", 9 ) == 0) ||
(i == 10 && memcmp ( sDirective, "xtranslate", 10 ) == 0) )
{
}
else if ( i == 6 && memcmp ( sDirective, "stdout", 6 ) == 0 )
printf ( "%s", sLine );
else if ( i == 5 && memcmp ( sDirective, "error", 5 ) == 0 )
{
printf ( " #error: %s", sLine );
return 2000;
}
else return 1;
}
return 0;
}
int ParseDefine( char* sLine)
{
char defname[MAX_NAME], pars[MAX_NAME];
int i = 0, deflen, parslen, npars = 0;
while ( *sLine != '\0' && *sLine != ' ')
{
if ( *sLine == '(' ) break;
*(defname+i++) = *sLine++;
}
*(defname+i) = '\0';
deflen = i;
if ( *sLine == '(' )
{
sLine++; i = 0;
while ( *sLine != '\0' && *sLine != ')')
{
if ( *sLine == ',' ) npars++;
if ( *sLine != ' ' && *sLine != '\t' ) *(pars+i++) = *sLine;
sLine++;
}
if ( i > 0 ) npars++;
*(pars+i) = '\0';
parslen = i;
sLine++;
}
if ( ( i = DefSearch(defname) ) >= 0 )
{
if ( aDefines[i].pars != NULL ) _xfree ( aDefines[i].pars );
_xfree ( aDefines[i].value );
}
else
{
if ( koldefines == maxdefines )
{
maxdefines += 50;
aDefines = (DEFINES *)_xrealloc( aDefines, sizeof( DEFINES ) * maxdefines );
}
i = koldefines++;
aDefines[i].name = ( char * ) _xgrab( deflen + 1 );
memcpy( aDefines[i].name,defname, deflen );
aDefines[i].name[deflen] = '\0';
}
SKIPTABSPACES(sLine);
if ( *sLine == '\0' ) aDefines[i].value = NULL;
else
{
deflen = 0;
while ( *(sLine+deflen) != '\0' ) deflen++;
aDefines[i].value = ( char * ) _xgrab( deflen + 1 );
memcpy( aDefines[i].value, sLine, deflen+1 );
aDefines[i].value[deflen] = '\0';
}
aDefines[i].npars = npars;
if ( npars > 0 )
{
aDefines[i].pars = ( char * ) _xgrab( parslen + 1 );
memcpy( aDefines[i].pars, pars, parslen+1 );
}
else aDefines[i].pars = NULL;
return 0;
}
int ParseUndef( char* sLine)
{
char defname[MAX_NAME];
int i = 0;
NextWord( &sLine, defname );
if ( ( i = DefSearch(defname) ) >= 0 )
{
_xfree ( aDefines[i].name );
_xfree ( aDefines[i].pars );
_xfree ( aDefines[i].value );
for ( ; i < koldefines-1; i++ )
{
aDefines[i].name = aDefines[i+1].name;
aDefines[i].value = aDefines[i+1].value;
aDefines[i].pars = aDefines[i+1].pars;
aDefines[i].npars = aDefines[i+1].npars;
}
koldefines--;
}
return 0;
}
int ParseIfdef( char* sLine, int usl)
{
char defname[MAX_NAME];
int i;
NextWord( &sLine, defname );
if ( *defname == '\0' ) return 3000;
if ( nCondCompile == maxCondCompile )
{
maxCondCompile += 5;
aCondCompile = (int*)_xrealloc( aCondCompile, sizeof( int ) * maxCondCompile );
}
if ( ( (i = DefSearch(defname)) >= 0 && usl )
|| ( i < 0 && !usl ) ) aCondCompile[nCondCompile] = 1;
else aCondCompile[nCondCompile] = 0;
nCondCompile++;
return 0;
}
int DefSearch(char *defname)
{
int i,j;
for ( i=0; i<koldefines; i++ )
{
for ( j=0; *(aDefines[i].name+j)==*(defname+j) &&
*(aDefines[i].name+j)!='\0'; j++ );
if ( *(aDefines[i].name+j)==*(defname+j) ) break;
}
if ( i >= koldefines ) return -1;
return i;
}
int ComSearch(char *cmdname, int ncmd)
{
int i,j;
for ( i=(ncmd)? ncmd:kolcommands-1; i >= 0; i-- )
{
for ( j=0; *(aCommands[i].name+j)==toupper(*(cmdname+j)) &&
*(aCommands[i].name+j)!='\0'; j++ );
if ( *(aCommands[i].name+j)==toupper(*(cmdname+j)) ) break;
}
return i;
}
int ParseCommand( char* sLine)
{
char cmdname[MAX_NAME], pars[MAX_NAME];
int cmdlen = 0, pattlen, ipos, i;
while ( *sLine != '\0' && *sLine != ' ') *(cmdname+cmdlen++) = *sLine++;
*(cmdname+cmdlen) = '\0';
SKIPTABSPACES(sLine);
for ( ipos=0; *(sLine+ipos) != '\0'; ipos++ )
if ( *(sLine+ipos) == '=' && *(sLine+ipos+1) == '>' ) break;
if( *(sLine+ipos) == '\0' ) return 4000;
if ( kolcommands == maxcommands )
{
maxcommands += 50;
aCommands = (COMMANDS *)_xrealloc( aCommands, sizeof( COMMANDS ) * maxcommands );
}
aCommands[kolcommands].name = ( char * ) _xgrab( cmdlen + 1 );
for ( i=0; i<cmdlen; i++ ) *(aCommands[kolcommands].name+i) = toupper(*(cmdname+i));
aCommands[kolcommands].name[cmdlen] = '\0';
if ( ipos > 1 )
{
pattlen = ipos - 2;
while ( *(sLine+pattlen) == ' ' ) pattlen--;
pattlen++;
aCommands[kolcommands].mpatt = ( char * ) _xgrab( pattlen + 1 );
memcpy( aCommands[kolcommands].mpatt, sLine, pattlen );
*(aCommands[kolcommands].mpatt+pattlen) = '\0';
}
else aCommands[kolcommands].mpatt = NULL;
ipos += 2;
while ( *(sLine+ipos) == ' ' ) ipos++;
pattlen = 0;
while ( *(sLine+ipos+pattlen) != '\0' ) pattlen++;
if ( pattlen > 0 )
{
aCommands[kolcommands].value = ( char * ) _xgrab( pattlen + 1 );
memcpy( aCommands[kolcommands].value, sLine+ipos, pattlen + 1 );
*(aCommands[kolcommands].value+pattlen) = '\0';
}
else aCommands[kolcommands].value = NULL;
kolcommands++;
return 0;
}
int ParseExpression( char* sLine, char* sOutLine)
{
char sToken[MAX_NAME];
char *ptri, *ptro;
int lenToken,npars,ndef,i;
int rezDef;
int aUsed[100], kolused = 0, lastused;
do
{
ptri = sLine; ptro = sOutLine;
rezDef = 0; lastused = kolused;
/* Look for macros from #define */
while ( ( lenToken = NextName(&ptri, sToken, &ptro) ) > 0 )
if ( (ndef=DefSearch(sToken)) >= 0 )
{
for(i=0;i<kolused;i++) if ( aUsed[i] == ndef ) break;
if ( i < kolused ) { if ( i < lastused ) return 1000; }
else
aUsed[kolused++] = ndef;
if ( aDefines[ndef].pars == NULL )
{
rezDef = 1;
ptro -= lenToken;
lenToken = 0;
while ( *(aDefines[ndef].value+lenToken) != '\0' )
*ptro++ = *(aDefines[ndef].value+lenToken++);
}
else
{
SKIPTABSPACES( ptri );
if ( *ptri == '(' )
{
npars=0; i = 0;
while ( *(ptri+i) != ')' && *(ptri+i) != '\0' )
{
if ( *(ptri+i) == ',' ) npars++;
i++;
}
if ( aDefines[ndef].npars == npars + 1 )
{
rezDef = 1;
ptro -= lenToken;
WorkDefine( &ptri, &ptro, ndef );
}
}
else *ptro++ = ' ';
}
}
*ptro = '\0';
memcpy ( sLine, sOutLine, ptro - sOutLine + 1);
}
while ( rezDef );
/* Look for definitions from #command */
ptri = sLine; ptro = sOutLine;
lenToken = NextWord( &ptri, sToken);
if ( (ndef=ComSearch(sToken,0)) >= 0 )
{
if ( (i = WorkCommand( sToken, &ptri, &ptro, ndef )) > 0 )
memcpy ( sLine, sOutLine, i+1);
}
return 0;
}
void WorkDefine ( char** ptri, char** ptro, int ndef )
{
char parfict[MAX_NAME], parreal[MAX_NAME];
char *ptrb, *ptr1, *ptr2;
int ipos = 0, ifou, ibeg;
int i;
int lenfict, lenreal, lenres;
while ( *(aDefines[ndef].value+ipos) != '\0' ) /* Copying value of macro */
{ /* to destination string */
*(*ptro+ipos) = *(aDefines[ndef].value+ipos);
ipos++;
}
*(*ptro+ipos) = '\0';
lenres = ipos;
ipos = 0; ibeg = 0;
do /* Parsing through parameters */
{ /* in macro definition */
if ( *(aDefines[ndef].pars+ipos)==',' || *(aDefines[ndef].pars+ipos)=='\0' )
{
*(parfict+ipos-ibeg) = '\0';
lenfict = ipos - ibeg;
if ( **ptri != ')' )
{
(*ptri)++; lenreal = 0; /* Parsing through real parameters */
while ( **ptri != ',' && **ptri != ')' )
{
*(parreal+lenreal++) = **ptri;
(*ptri)++;
}
*(parreal+lenreal) = '\0';
ptrb = *ptro;
while ( (ifou = hb_strAt( parfict, lenfict, ptrb, lenres-(ptrb-*ptro) )) > 0 )
{
ptrb = ptrb+ifou-1;
if ( !isname(*(ptrb-1)) && !isname(*(ptrb+lenfict)) )
{
Stuff ( parreal, ptrb, lenreal, lenfict, lenres );
lenres += lenreal - lenfict;
}
else ptrb++;
}
ibeg = ipos+1;
}
}
else *(parfict+ipos-ibeg) = *(aDefines[ndef].pars+ipos);
if ( *(aDefines[ndef].pars+ipos) == '\0' ) break;
ipos++;
}
while ( 1 );
(*ptri)++;
*ptro += lenres;
}
int WorkCommand ( char* sToken, char** ptri, char** ptro, int ndef )
{
char expreal[MAX_NAME], exppatt[MAX_NAME];
int lenreal, lenpatt;
int aCmdStru[100][2], iItem, ifiItem;
int rez, rezrestr, rezpatt, nbr;
int lenres = 0;
int ifou, i;
char *lastopti;
char *ptrin, *ptrmp, *ptr;
while ( *(aCommands[ndef].value+lenres) != '\0' ) /* Copying result pattern */
{ /* to destination string */
*(*ptro+lenres) = *(aCommands[ndef].value+lenres);
lenres++;
}
CmdParse ( *ptri, aCmdStru ); /* Parse input string */
ptrmp = aCommands[ndef].mpatt;
do
{
Repeate = 0;
rez = 1; nbr = 0;
if ( ptrmp == NULL ) rez = ( aCmdStru[0][0] )? 0:1;
else
for ( iItem=1; iItem <= aCmdStru[0][0] && rez; iItem++)
{
do
{
rezpatt = 0;
SKIPTABSPACES( ptrmp );
if ( *ptrmp == '[' ) { rezpatt = 1; nbr++; ptrmp++; lastopti = ptrmp; }
else if ( *ptrmp == ']' )
{
rezpatt = 1;
if ( Repeate ) { Repeate = 0; ptrmp = lastopti; }
else { nbr--; ptrmp++; }
}
else if ( *ptrmp == ',' )
{
if ( aCmdStru[iItem][1] == IT_COMMA ) ptrmp++;
else { rez = 0; break; }
}
else if ( *ptrmp == '<' )
{ /* ------- Match marker ------- */
if ( aCmdStru[iItem][1] == IT_COMMA ) { rez = 0; break; }
/* Copying a match pattern to 'exppatt' */
lenpatt = 0;
while ( *ptrmp != '>' && *ptrmp!= '\0' ) *(exppatt+lenpatt++) = *ptrmp++;
*(exppatt+lenpatt++) = '>';
*(exppatt+lenpatt) = '\0';
ptrmp++;
/* Copying a real expression to 'expreal' */
lenreal = 0; ptrin = *ptri + aCmdStru[iItem][0];
while ( lenreal < aCmdStru[iItem+1][0]-aCmdStru[iItem][0] )
{ *(expreal+lenreal) = *(ptrin+lenreal); lenreal++; }
if ( *(expreal+lenreal) == ' ' )
{ while ( *(expreal+lenreal) == ' ' ) lenreal--; lenreal++; }
*(expreal+lenreal) = '\0';
if ( *(exppatt+1) == '(' )
/* ---- In case of extended match marker */
{
Stringify( expreal, lenreal ); lenreal += 2;
SearnRep( exppatt,lenpatt,expreal,lenreal,*ptro,&lenres);
}
else if ( *(exppatt+1) == '*' )
/* ---- In case of wild match marker */
{
ifiItem = iItem; iItem = aCmdStru[0][0];
if ( iItem > ifiItem ) /* Copying a real expression to 'expreal' */
{
lenreal = 0; ptrin = *ptri + aCmdStru[ifiItem][0];
while ( lenreal < aCmdStru[iItem+1][0]-aCmdStru[ifiItem][0] )
{ *(expreal+lenreal) = *(ptrin+lenreal); lenreal++; }
if ( *(expreal+lenreal) == ' ' )
{ while ( *(expreal+lenreal) == ' ' ) lenreal--; lenreal++; }
*(expreal+lenreal) = '\0';
}
}
else if ( (ifou = hb_strAt(":",1,exppatt,lenpatt)) > 0 )
/* ---- In case of restricted match marker */
{
ptr = exppatt + ifou;
rezrestr = 0;
while ( *ptr != '>' )
{
if ( *ptr == '&' )
{
if ( *expreal == '&' )
{
rezrestr = 1;
break;
}
else ptr++;
}
else
{
SKIPTABSPACES( ptr );
/* Comparing real parameter and restriction value */
for ( i=0; toupper(*ptr) == toupper(*(expreal+i)) && *ptr != ','
&& *ptr != '>' && i < lenreal; i++,ptr++ );
if ( i == lenreal || *ptr == ',' || *ptr == '>' )
{
pEnclose( exppatt, ifou, '.' ); lenpatt = ifou+2;
SearnRep( exppatt,lenpatt,".T.",3,*ptro,&lenres);
rezrestr = 1;
break;
}
else
{
while ( *ptr != ',' && *ptr != '>' ) ptr++;
if ( *ptr == ',' ) ptr++;
}
}
}
if ( rezrestr == 0 )
{ /* If restricted match marker doesn't correspond to real parameter */
if ( nbr )
{
pEnclose( exppatt, ifou, '.' ); lenpatt = ifou+2;
SearnRep( exppatt,lenpatt,".F.",3,*ptro,&lenres);
rezpatt = 1; /* if was optional, go to the next */
}
else { rez = 0; break; } /* else break this rule */
}
}
else if ( (ifou = hb_strAt(",",1,exppatt,lenpatt)) > 0 )
/* ---- In case of list match marker */
{
*(exppatt+ifou-1) = '>';
*(exppatt+ifou) = '\0';
lenpatt = ifou;
ifiItem = iItem;
while ( iItem < aCmdStru[0][0] && aCmdStru[iItem+1][1] == IT_COMMA ) iItem+=2;
if ( iItem > ifiItem ) /* Copying a real expression to 'expreal' */
{
lenreal = 0; ptrin = *ptri + aCmdStru[ifiItem][0];
while ( lenreal < aCmdStru[iItem+1][0]-aCmdStru[ifiItem][0] )
{ *(expreal+lenreal) = *(ptrin+lenreal); lenreal++; }
if ( *(expreal+lenreal) == ' ' )
{ while ( *(expreal+lenreal) == ' ' ) lenreal--; lenreal++; }
*(expreal+lenreal) = '\0';
}
SearnRep( exppatt,lenpatt,expreal,lenreal,*ptro,&lenres);
}
else
/* ---- In case of regular match marker */
{
/* Search for regular result markers */
SearnRep( exppatt,lenpatt,expreal,lenreal,*ptro,&lenres);
/* Search for smart stringify result markers */
pEnclose( exppatt, lenpatt, '(' ); lenpatt += 2;
if ( *expreal != '(' )
{ Stringify( expreal, lenreal ); lenreal += 2; }
SearnRep( exppatt,lenpatt,expreal,lenreal,*ptro,&lenres);
/* Search for normal stringify result markers */
*(exppatt+1) = *(exppatt+lenpatt-2) = '\"';
if ( *expreal != '\"' )
{ Stringify( expreal, lenreal ); lenreal += 2; }
SearnRep( exppatt,lenpatt,expreal,lenreal,*ptro,&lenres);
/* Search for blockify result markers */
*(exppatt+1) = '{'; *(exppatt+lenpatt-2) = '}';
*expreal = '{'; *(expreal+lenreal-1) = '}';
Stuff ( "||", expreal+1, 2, 0, lenreal );
lenreal += 2;
SearnRep( exppatt,lenpatt,expreal,lenreal,*ptro,&lenres);
}
} /* ------- End of match marker processing ------- */
else if ( *ptrmp == '\0' ) { rez = 0; break; }
else /* ------- Key word ------- */
{
if ( aCmdStru[iItem][1] != IT_ID ) { rez = 0; break; }
ptrin = *ptri + aCmdStru[iItem][0];
for (;isname(*ptrin) && isname(*ptrmp) && toupper(*ptrin)==toupper(*ptrmp); ptrmp++, ptrin++ );
if ( *ptrmp != *ptrin )
{
if ( nbr ) { SkipOptional( &ptrmp, *ptro, &lenres); rezpatt = 1; }
else { rez = 0; break; }
}
} /* ------- End of key word processing ------- */
}
while ( rezpatt );
}
if ( rez && ptrmp != NULL)
{
SKIPTABSPACES( ptrmp );
if ( *ptrmp == ']' ) ptrmp++; nbr--;
if ( Repeate ) ptrmp = lastopti - 1;
do
{
SKIPTABSPACES( ptrmp );
if ( *ptrmp != '\0' )
if ( *ptrmp == '[' )
{
ptrmp++;
SkipOptional( &ptrmp, *ptro, &lenres);
ptrmp++;
}
else if ( *ptrmp=='<' && *(ptrmp+1)=='*' ) break;
else rez = 0;
}
while ( *ptrmp != '\0' && rez );
}
if ( !rez && (ndef = ComSearch(sToken,ndef-1))>=0 )
{
ptrmp = aCommands[ndef].mpatt;
ptrin = *ptri;
lenres = 0;
while ( *(aCommands[ndef].value+lenres) != '\0' ) /* Copying result pattern */
{ /* to destination string */
*(*ptro+lenres) = *(aCommands[ndef].value+lenres);
lenres++;
}
}
}
while ( !rez && ndef >= 0 );
*(*ptro+lenres) = '\0';
if ( rez ) return lenres;
return 0;
}
void CmdParse ( char *ptri, int aCmdStru[100][2] )
{
char *sZnaki = "+-=><*/$";
int State = State = STATE_ID_END, StBr1 = 0, StBr2 = 0, StBr3 = 0;
int i = 0;
aCmdStru[0][0] = 0;
while ( *ptri != '\0' )
{
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) && State == STATE_ID_END ) ||
*ptri==',' || *ptri=='\'' || *ptri=='\"')
{
if ( !aCmdStru[ aCmdStru[0][0] ][1] ) aCmdStru[ aCmdStru[0][0] ][1] = IT_ID;
State = STATE_ID;
aCmdStru[0][0]++;
aCmdStru[ aCmdStru[0][0] ][0] = i;
if ( *ptri == ',' )
{
State = STATE_ID_END;
aCmdStru[ aCmdStru[0][0] ][1] = IT_COMMA;
}
else if ( *ptri == '\'' )
{
State = STATE_QUOTE1;
aCmdStru[ aCmdStru[0][0] ][1] = IT_EXPR;
}
else if ( *ptri == '\"' )
{
State = STATE_QUOTE2;
aCmdStru[ aCmdStru[0][0] ][1] = IT_EXPR;
}
else
{
State = STATE_ID;
if ( isdigit(*ptri) ) aCmdStru[ aCmdStru[0][0] ][1] = IT_EXPR;
else aCmdStru[ aCmdStru[0][0] ][1] = 0;
}
}
else if ( IsInStr( *ptri, sZnaki ) ) State = STATE_EXPRES;
else if ( *ptri == '(' )
{
State = STATE_BRACKET;
StBr1 = 1;
aCmdStru[ aCmdStru[0][0] ][1] = IT_EXPR;
}
else if ( *ptri == '[' )
{
State = STATE_BRACKET;
StBr2 = 1;
aCmdStru[ aCmdStru[0][0] ][1] = IT_EXPR;
}
else if ( *ptri == '{' )
{
State = STATE_BRACKET;
StBr3 = 1;
aCmdStru[ aCmdStru[0][0] ][1] = IT_ID;
}
else if ( *ptri == ' ' ) State = STATE_ID_END;
break;
case STATE_EXPRES:
aCmdStru[ aCmdStru[0][0] ][1] = IT_EXPR;
if ( *ptri == '\'' ) State = STATE_QUOTE1;
else if ( *ptri == '\"' ) State = STATE_QUOTE2;
else if ( isname(*ptri) ) State = STATE_ID;
else if ( *ptri == '(' ) { StBr1++; State = STATE_BRACKET; }
else if ( *ptri == '[' ) { StBr2++; State = STATE_BRACKET; }
else if ( *ptri == '{' ) { StBr3++; State = STATE_BRACKET; }
break;
}
ptri++; i++;
}
if ( aCmdStru[0][0] && !aCmdStru[ aCmdStru[0][0] ][1] )
aCmdStru[ aCmdStru[0][0] ][1] = IT_ID;
aCmdStru[ aCmdStru[0][0]+1 ][0] = i;
}
void SkipOptional( char** ptri, char *ptro, int* lenres)
{
int nbr = 0, ifou, lCopy;
char exppatt[MAX_NAME];
int lenpatt;
while ( isname(**ptri) ) (*ptri)++;
SKIPTABSPACES( *ptri );
while ( **ptri != ']' || nbr )
{
if ( **ptri == '[' ) nbr++;
if ( **ptri == ']' ) nbr--;
if ( **ptri == '<' )
{
lenpatt = 0; lCopy = 1;
do /* Drag the match marker ( <...> ) */
{
if ( **ptri == ':' ) lCopy = 0;
if ( lCopy ) *(exppatt+lenpatt++) = **ptri;
(*ptri)++;
}
while ( **ptri != '>' );
*(exppatt+lenpatt++) = '>';
*(exppatt+lenpatt) = '\0';
/* Search for regular result markers */
SearnRep( exppatt,lenpatt,"",0,ptro,lenres);
/* Search for logify result markers */
pEnclose( exppatt, lenpatt, '.' ); lenpatt += 2;
SearnRep( exppatt,lenpatt,".F.",3,ptro,lenres);
/* Search for smart stringify result markers */
*(exppatt+1) = '('; *(exppatt+lenpatt-2) = ')';
SearnRep( exppatt,lenpatt,"",0,ptro,lenres);
/* Search for normal stringify result markers */
*(exppatt+1) = *(exppatt+lenpatt-2) = '\"';
SearnRep( exppatt,lenpatt,"",0,ptro,lenres);
/* Search for blockify result markers */
*(exppatt+1) = '{'; *(exppatt+lenpatt-2) = '}';
SearnRep( exppatt,lenpatt,"",0,ptro,lenres);
}
(*ptri)++;
}
}
void SearnRep( char *exppatt,int lenpatt,char *expreal,int lenreal,char *ptro, int *lenres)
{
int ifou, isdvig = 0, rezs;
char *ptr, *ptr2;
while ( (ifou = hb_strAt( exppatt, lenpatt, ptro+isdvig, *lenres-isdvig )) > 0 )
{
rezs = 0;
ptr = ptro+isdvig+ifou-2;
while ( ptr >= ptro+isdvig )
{
if ( *ptr == '[' || *ptr == ']' ) break;
ptr--;
}
if ( *ptr == '[' )
{
if ( Repeate && lenreal ) return;
ptr2 = ptro+isdvig+ifou+lenpatt-1;
while ( *ptr2 != ']' ) ptr2++;
if ( lenreal == 0 )
{
Stuff ( "", ptr, 0, ptr2-ptr+1, *lenres-(ptr-ptro) );
*lenres -= ptr2-ptr+1;
isdvig = ptr - ptro;
rezs = 1;
}
else
{
char expnew[MAX_NAME];
int lennew = ptr2-ptr-1, i;
memcpy ( expnew, ptr+1, lennew );
*(expnew + lennew) = '\0';
i = hb_strAt( exppatt, lenpatt, expnew, lennew );
Stuff ( expreal, expnew+i-1, lenreal, lenpatt, lennew );
lennew += lenreal - lenpatt;
Stuff ( expnew, ptr, lennew, 0, *lenres-(ptr-ptro)+1 );
*lenres += lennew;
isdvig = ptr - ptro + (ptr2-ptr-1) + lennew;
rezs = 1;
Repeate = 1;
}
}
if ( !rezs )
{
Stuff ( expreal, ptro+isdvig+ifou-1, lenreal, lenpatt, *lenres-ifou+1 );
*lenres += lenreal - lenpatt;
isdvig += ifou +lenreal;
}
}
}
int RdStr(int handl_i,char *buffer,int maxlen,int lDropSpaces,char* sBuffer, int* lenBuffer, int* iBuffer)
{
int readed = 0,bytes;
int State = 0;
char cha,cLast='\0';
if ( *lenBuffer == 0 ) return -1;
while(1)
{
if ( *iBuffer == *lenBuffer )
{
if ( (*lenBuffer = read(handl_i,sBuffer,BUFF_SIZE)) < 1 ) sBuffer[0] = '\n';
*iBuffer = 0;
}
cha = sBuffer[*iBuffer];
(*iBuffer)++;
if( cha == '\n' ) break;
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_QUOTE2; break;
case '\'': 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 'e':
case 'E':
if ( !State &&
readed>2 && (buffer[readed-1]=='t' || buffer[readed-1]=='T')
&& (buffer[readed-2]=='o' || buffer[readed-2]=='O')
&& (buffer[readed-3]=='n' || buffer[readed-2]=='N') )
maxlen = readed = 0;
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<maxlen && (!lDropSpaces || readed==0) &&
ParseState != STATE_COMMENT) buffer[readed++]=cha;
}
while(--readed >= 0 && ( buffer[readed] == ' ' || buffer[readed] == '\t') );
readed++;
buffer[readed]='\0';
return readed;
}
int WrStr(int handl_o,char *buffer)
{
while( *buffer != '\0' ) write(handl_o,buffer++,1);
write(handl_o,"\n",1);
return 0;
}
/* locates a substring in a string */
int hb_strAt(char *szSub, int lSubLen, char *szText, int 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 IsInStr ( char symb, char* s )
{
while ( *s != '\0' ) if ( *s++ == symb ) return 1;
return 0;
}
void Stuff (char *ptri, char * ptro, int len1, int len2, int lenres )
{
char *ptr1, *ptr2;
int i;
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);
}
void Stringify( char *stroka, int lens )
{
char *ptr = stroka + lens + 2;
*ptr-- = '\0';
*ptr-- = '\"';
for ( ; ptr > stroka; ptr-- ) *ptr = *(ptr-1);
*ptr = '\"';
}
void pEnclose( char *stroka, int lens, char symb )
{
char *ptr = stroka + lens + 2;
*ptr-- = '\0';
*ptr-- = '>';
*ptr-- = (symb=='(')? ')':(symb=='{')? '}':symb;
for ( ; ptr > stroka+1; ptr-- ) *ptr = *(ptr-1);
*ptr = symb;
}
int NextWord ( char** sSource, char* sDest )
{
int i = 0;
SKIPTABSPACES( (*sSource) );
while ( **sSource != '\0' && **sSource != ' ')
{ *sDest++ = *(*sSource)++; i++; }
*sDest = '\0';
return i;
}
int NextName ( char** sSource, char* sDest, char **sOut )
{
int i = 0;
while ( **sSource != '\0' && !isname(**sSource) )
{ if ( *sOut !=NULL ) *(*sOut)++ = **sSource; (*sSource)++; }
while ( **sSource != '\0' && isname(**sSource) )
{
if ( *sOut !=NULL ) *(*sOut)++ = **sSource;
*sDest++ = *(*sSource)++; i++;
}
*sDest = '\0';
return i;
}