From b68bf527f0c2e4c1df3b1b0fd2e4f718c87e6d66 Mon Sep 17 00:00:00 2001 From: Eddie Runia Date: Mon, 24 May 1999 09:29:16 +0000 Subject: [PATCH] Preprocessor added --- harbour/ChangeLog | 4 + harbour/source/hbpp/a.prg | 15 + harbour/source/hbpp/build.bat | 1 + harbour/source/hbpp/build32.bat | 1 + harbour/source/hbpp/c.prg | 16 + harbour/source/hbpp/exam2.ch | 2 + harbour/source/hbpp/example.ch | 3 + harbour/source/hbpp/harb.c | 156 ++++ harbour/source/hbpp/hbpp.c | 1135 ++++++++++++++++++++++++++++++ harbour/source/hbpp/makefile.b16 | 8 + harbour/source/hbpp/makefile.b32 | 8 + 11 files changed, 1349 insertions(+) create mode 100644 harbour/source/hbpp/a.prg create mode 100644 harbour/source/hbpp/build.bat create mode 100644 harbour/source/hbpp/build32.bat create mode 100644 harbour/source/hbpp/c.prg create mode 100644 harbour/source/hbpp/exam2.ch create mode 100644 harbour/source/hbpp/example.ch create mode 100644 harbour/source/hbpp/harb.c create mode 100644 harbour/source/hbpp/hbpp.c create mode 100644 harbour/source/hbpp/makefile.b16 create mode 100644 harbour/source/hbpp/makefile.b32 diff --git a/harbour/ChangeLog b/harbour/ChangeLog index a4483f7960..c7c9e6c98f 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,7 @@ +19990524-10:25 CET Alexander Kressin (upload Eddie Runia) + * source/hbpp + added preprocessor + 19990524-08:10 CET Les Griffiths (upload Eddie Runia) * source/rtl/files.c a step in right the direction diff --git a/harbour/source/hbpp/a.prg b/harbour/source/hbpp/a.prg new file mode 100644 index 0000000000..a4d3b6b896 --- /dev/null +++ b/harbour/source/hbpp/a.prg @@ -0,0 +1,15 @@ +#include "example.ch" +Private x,ar,y + x = " /* 111 */ " + /* comment string 1 + string 2 + string 3 */ + ar = { 1000, 2000, 3000, 4000,; && Comment + 5000, 6000, 7000 } +#ifdef MAXPOS + y = MAXPOS +#else + y = MINPOS +#endif + y = MAX(y,10) +return \ No newline at end of file diff --git a/harbour/source/hbpp/build.bat b/harbour/source/hbpp/build.bat new file mode 100644 index 0000000000..c9bf4f08c2 --- /dev/null +++ b/harbour/source/hbpp/build.bat @@ -0,0 +1 @@ +\borlandc\bin\make -fmakefile.b16 \ No newline at end of file diff --git a/harbour/source/hbpp/build32.bat b/harbour/source/hbpp/build32.bat new file mode 100644 index 0000000000..cba138725a --- /dev/null +++ b/harbour/source/hbpp/build32.bat @@ -0,0 +1 @@ +make -fmakefile.b32 diff --git a/harbour/source/hbpp/c.prg b/harbour/source/hbpp/c.prg new file mode 100644 index 0000000000..a8c6acf239 --- /dev/null +++ b/harbour/source/hbpp/c.prg @@ -0,0 +1,16 @@ +#include "std.ch" + @ 1,1,10,10 BOX ORAMKA + @ 2, 3 SAY "Hello,world" + SET DATE BRITISH + USE JOUPL SHARED INDEX JOUPI1 + SET FILTER TO + SEEK STR(A->NOMER,10) + go top + DO WHILE x>1 + skip 3 + ENDDO + LOCATE FOR Family = "Johnson" + ? "Family:", Family, "--" + REPLACE PARAM1 WITH 3, PARAM2 WITH "Hello", PARAM3 WITH PARAM4 * 2 + STORE 10 to x,y,z +return \ No newline at end of file diff --git a/harbour/source/hbpp/exam2.ch b/harbour/source/hbpp/exam2.ch new file mode 100644 index 0000000000..4bd2677a28 --- /dev/null +++ b/harbour/source/hbpp/exam2.ch @@ -0,0 +1,2 @@ +#define MAX(arg1, arg2) IIF(arg1>arg2, arg1, arg2) +#define MIN(arg1, arg2) IIF(arg1 +#include +#include +#include "harb.h" +/* + * Split given filename into path, name and extension +*/ +FILENAME *SplitFilename( char *szFilename ) +{ + FILENAME *pName =(FILENAME *)OurMalloc( sizeof(FILENAME) ); + int iLen = strlen(szFilename); + int iSlashPos, iDotPos; + int iPos; + + pName->path =pName->name =pName->extension =NULL; + + iSlashPos =iLen-1; + iPos =0; + while( iSlashPos >= 0 && !IS_PATH_SEP(szFilename[ iSlashPos ]) ) + --iSlashPos; + if( iSlashPos == 0 ) + { + /* root path -> \filename */ + pName->_buffer[ 0 ] =PATH_DELIMITER[ 0 ]; + pName->_buffer[ 1 ] ='\x0'; + pName->path =pName->_buffer; + iPos =2; /* first free position after the slash */ + } + else if( iSlashPos > 0 ) + { + /* path with separator -> path\filename */ + memcpy( pName->_buffer, szFilename, iSlashPos ); + pName->_buffer[ iSlashPos ] ='\x0'; + pName->path =pName->_buffer; + iPos =iSlashPos +1; /* first free position after the slash */ + } + + iDotPos =iLen-1; + while( iDotPos > iSlashPos && szFilename[ iDotPos ] != '.' ) + --iDotPos; + if( (iDotPos-iSlashPos) > 1 ) + { + /* the dot was found + * and there is at least one character between a slash and a dot + */ + if( iDotPos == iLen-1 ) + { + /* the dot is the last character -use it as extension name */ + pName->extension =pName->_buffer+iPos; + pName->_buffer[ iPos++ ] ='.'; + pName->_buffer[ iPos++ ] ='\x0'; + } + else + { + pName->extension =pName->_buffer+iPos; + /* copy rest of the string with terminating ZERO character */ + memcpy( pName->extension, szFilename+iDotPos+1, iLen-iDotPos ); + iPos +=iLen-iDotPos; + } + } + else + /* there is no dot in the filename or it is '.filename' */ + iDotPos =iLen; + + pName->name =pName->_buffer+iPos; + memcpy( pName->name, szFilename+iSlashPos+1, iDotPos-iSlashPos-1 ); + pName->name[ iDotPos-iSlashPos-1 ] ='\x0'; + + return pName; +} + +/* + * This function joins path, name and extension into a string with a filename +*/ +char *MakeFilename( char *szFileName, FILENAME *pFileName ) +{ + if( pFileName->path && pFileName->path[ 0 ] ) + { + /* we have not empty path specified */ + int iLen =strlen(pFileName->path); + strcpy( szFileName, pFileName->path ); + /* if the path is a root directory then we don't need to add path separator */ + if( !(IS_PATH_SEP(pFileName->path[ 0 ]) && pFileName->path[ 0 ] == '\x0') ) + { + /* add the path separator only in cases: + * when a name doesn't start with it + * when the path doesn't end with it + */ + if( !( IS_PATH_SEP(pFileName->name[ 0 ]) || IS_PATH_SEP(pFileName->path[ iLen-1 ]) ) ) + { + szFileName[ iLen++ ] =PATH_DELIMITER[ 0 ]; + szFileName[ iLen ] ='\x0'; + } + } + strcpy( szFileName+iLen, pFileName->name ); + } + else + strcpy( szFileName, pFileName->name ); + + if( pFileName->extension ) + { + int iLen =strlen(szFileName); + + if( !(pFileName->extension[ 0 ] == '.' || pFileName->name[ iLen-1 ] == '.') ) + { + /* add extension separator only when extansion doesn't contain it */ + szFileName[ iLen++ ] ='.'; + szFileName[ iLen ] ='\x0'; + } + strcpy( szFileName+iLen, pFileName->extension ); + } + + return szFileName; +} + +void * OurMalloc( LONG lSize ) +{ + void * pMem = malloc( lSize ); + + if( ! pMem ) + printf( "\nCan't allocate memory!\n" ); + + return pMem; +} + +void * _xgrab( ULONG ulSize ) /* allocates fixed memory */ +{ + void * pMem = malloc( ulSize ); + + if( ! pMem ) + { + printf( "\n_xgrab error: can't allocate memory!\n" ); + exit( 1 ); + } + + return pMem; +} + +void * _xrealloc( void * pMem, ULONG ulSize ) /* reallocates memory */ +{ + void * pResult = realloc( pMem, ulSize ); + + if( ! pResult ) + { + printf( "\n_xrealloc error: can't reallocate memory!\n" ); + exit( 1 ); + } + + return pResult; +} + +void _xfree( void * pMem ) /* frees fixed memory */ +{ + if( pMem ) + free( pMem ); +} diff --git a/harbour/source/hbpp/hbpp.c b/harbour/source/hbpp/hbpp.c new file mode 100644 index 0000000000..835892b729 --- /dev/null +++ b/harbour/source/hbpp/hbpp.c @@ -0,0 +1,1135 @@ +/* Harbour Preprocessor , version 0.7 + author - Alexander Kresin */ +#include +#include +#include +#include +#include +#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=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 ) 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 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= 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= 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; +} diff --git a/harbour/source/hbpp/makefile.b16 b/harbour/source/hbpp/makefile.b16 new file mode 100644 index 0000000000..a5e68265e6 --- /dev/null +++ b/harbour/source/hbpp/makefile.b16 @@ -0,0 +1,8 @@ +# makefile for Borland C/C++ 16 bits + +PROJECT: hbpp.exe + +hbpp.exe : hbpp.c harb.c + \borlandc\bin\bcc -ml hbpp.c harb.c + del hbpp.obj + del harb.obj diff --git a/harbour/source/hbpp/makefile.b32 b/harbour/source/hbpp/makefile.b32 new file mode 100644 index 0000000000..0351ec0f20 --- /dev/null +++ b/harbour/source/hbpp/makefile.b32 @@ -0,0 +1,8 @@ +# makefile for Borland C/C++ 32 bits + +PROJECT: hbpp.exe + +hbpp.exe : hbpp.c harb.c + bcc32 -O2 -I\borland\cbuilder\include hbpp.c harb.c + del hbpp.obj + del harb.obj