From 385facd33ccfd567498e341d3404e3d12e67c17a Mon Sep 17 00:00:00 2001 From: Ryszard Glab Date: Thu, 20 Jul 2006 09:36:28 +0000 Subject: [PATCH] 2006-07-20 11:40 UTC+0100 Ryszard Glab * source/pp/ppcore.c * fixed bugs which I introduced * utils/hbpptest/pretest.prg * added more test cases + utils/hbpptest/pp_test.prg * new file to test preprocessor Preprocess both with Clipper and harbour and next use diff utility to compare outputs - ignore the number of white spaces (use diff -w -u ...) --- harbour/ChangeLog | 13 + harbour/source/pp/ppcore.c | 43 +-- harbour/utils/hbpptest/pp_test.prg | 471 +++++++++++++++++++++++++++++ harbour/utils/hbpptest/pretest.prg | 28 +- 4 files changed, 521 insertions(+), 34 deletions(-) create mode 100644 harbour/utils/hbpptest/pp_test.prg diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 92715970c4..bbca739971 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,19 @@ 2002-12-01 13:30 UTC+0100 Foo Bar */ + + harbour/utils/hbpptest/.cvsignore + * harbour/utils/hbpptest/pp_test.prg + + Added batch file to compare PP results between Harbour and + + +2006-07-20 11:40 UTC+0100 Ryszard Glab + + * fixed bugs which I introduced + + and harbour and next use diff utility to compare outputs - + * added more test cases + + + utils/hbpptest/pp_test.prg * new file to test preprocessor Preprocess both with Clipper and harbour and next use diff utility to compare outputs - ignore the number of white spaces (use diff -w -u ...) diff --git a/harbour/source/pp/ppcore.c b/harbour/source/pp/ppcore.c index 14b433943a..3a5654cb8a 100644 --- a/harbour/source/pp/ppcore.c +++ b/harbour/source/pp/ppcore.c @@ -1891,13 +1891,13 @@ static int WorkTranslate( char *ptri, char *ptro, COMMANDS * sttra, int *lens ) static int CommandStuff( char *ptrmp, char *inputLine, char *ptro, int *lenres, BOOL com_or_tra, BOOL com_or_xcom ) { BOOL endTranslation = FALSE; - BOOL bReplaced = FALSE; int ipos; char *lastopti[MAX_OPTIONALS], *strtopti = NULL, *strtptri = NULL; char *ptri = inputLine, *ptr, tmpname[MAX_NAME]; int isWordInside = 0; char szMatch[2]; - char *ptrmpatt = ptrmp; + char *cSkipped[MAX_OPTIONALS]; + int iSkipped = 0; /* printf( "MP: >%s<\nIn: >%s<\n", ptrmp, ptri ); @@ -1936,10 +1936,13 @@ static int CommandStuff( char *ptrmp, char *inputLine, char *ptro, int *lenres, if( ipos && TestOptional( strtopti, strtopti + ipos - 2 ) ) { /* the keyword from input is found in the pattern */ - ptr = strtopti + ipos - 2; - ptr = PrevSquare( ptr, strtopti, NULL ); + ptr = PrevSquare( strtopti + ipos - 2, strtopti, NULL ); if( ptr ) ptrmp = ptr; + if( ptr != strtopti ) + { + cSkipped[ iSkipped++ ] = strtopti; + } } } @@ -1954,17 +1957,7 @@ static int CommandStuff( char *ptrmp, char *inputLine, char *ptro, int *lenres, ptrmp++; if( !CheckOptional( ptrmp, ptri, ptro, lenres, com_or_tra, com_or_xcom ) ) { - char *ptr = ptrmp; SkipOptional( &ptrmp ); - if( !ptrmp[0] && *ptri && ptr != ptrmpatt+1 && ptri != inputLine && bReplaced ) - { - /* Start scanning from the beginning - * end of pattern but still there is an input stream to parse - * - */ - ptrmp = ptrmpatt; - strtopti = NULL; - } } break; @@ -2007,18 +2000,9 @@ static int CommandStuff( char *ptrmp, char *inputLine, char *ptro, int *lenres, } else { - char *ptr = ptrmp; if( !isWordInside ) strtopti = NULL; ptrmp++; - if( !ptrmp[0] && *ptri && ptr != ptrmpatt+1 && ptri != inputLine && bReplaced ) - { - /* Start scanning from the beginning - * end of pattern but still there is an input stream to parse - */ - ptrmp = ptrmpatt; - strtopti = NULL; - } } s_numBrackets--; } @@ -2057,11 +2041,7 @@ static int CommandStuff( char *ptrmp, char *inputLine, char *ptro, int *lenres, strtopti = NULL; if( s_numBrackets == 1 && *( ptrmp + 2 ) == '2' ) isWordInside = 1; /* restricted match marker */ - if( WorkMarkers( &ptrmp, &ptri, ptro, lenres, com_or_tra, com_or_xcom ) ) - { - bReplaced = TRUE; - } - else + if( ! WorkMarkers( &ptrmp, &ptri, ptro, lenres, com_or_tra, com_or_xcom ) ) { if( s_numBrackets ) { @@ -2073,6 +2053,11 @@ static int CommandStuff( char *ptrmp, char *inputLine, char *ptro, int *lenres, break; case '\0': + if( iSkipped ) + { + ptrmp = cSkipped[ --iSkipped ]; + break; + } if( com_or_tra ) return -1; else @@ -2092,7 +2077,7 @@ static int CommandStuff( char *ptrmp, char *inputLine, char *ptro, int *lenres, { SkipOptional( &ptrmp ); } - else + else return -1; } } diff --git a/harbour/utils/hbpptest/pp_test.prg b/harbour/utils/hbpptest/pp_test.prg new file mode 100644 index 0000000000..dfcc3ee29e --- /dev/null +++ b/harbour/utils/hbpptest/pp_test.prg @@ -0,0 +1,471 @@ +/* + * $Id$ + */ +/* Test file to check the preprocessor. + * Usage: + * 1) Preprocess it using: + * harbour -p -n pp_test.prg + * 2) Rename generated pp_test.ppo (for example into pp_test.hpp) + * 3) Preprocess it with Clipper using: + * clipper -p -n pp_test.prg + * 4) Compare Clipper generated file pp_test.ppo with file generated + * with Harbour, ignoring number of white spaces, for example: + * diff -u -w pp_test.ppo pp_test.hpp > pp_test.diff + * + * Ignore most of errors reported during compilation. + * +*/ +PROCEDURE MAIN() + +#ifdef __HARBOUR__ +#xtranslate CCC => QOUT( [2] [, []\[3\]] ) +CCC b +#endif + +#xtranslate CCCC => QOUT( \[3\] ) +CCCC c + +#xtranslate AAA [A [B ] ] => Qout([][, ]) + AAA + AAA A a + AAA A a B b + +#define RED {255,0,0} +#ifdef __HARBOUR__ +/* ---------------------------------------------------------------------*/ +#xcommand SET COOLTIP TO OF
=> ; + SM( TTH (<"form">), 1, RGB([1], ; + \[2\], ; + [, [ 3 ] ]), 0) + + SET COOLTIP TO RED OF form1 +#endif + +#xcommand SET TOOLTIP TO OF => ; + SM( TTH (<"form">), 1, RGB([1], ; + \[2\], ; + \[ 3 \]), 0) + + SET TOOLTIP TO RED OF form1 + +/* ---------------------------------------------------------------------*/ +#command ZZZ [] => QOUT( [ \[1\] ] ) + ZZZ a + ZZZ + ZZZ a[1]+2 +/* ---------------------------------------------------------------------*/ +#xtranslate _HMG_a => _HMG\[137\] + ? _bro[ a( _HMG_a [i] ) ] + +/* ---------------------------------------------------------------------*/ +#ifdef __HARBOUR__ +#define clas( x ) (x) +#xtranslate ( { [] } => (():New(

) + a :=clas( TesT{ 1,2,3} ) +#endif + +#define clas( x ) (x) +#xtranslate ( { [] } => (():New(

) + a :=clas( TEST{ 1,2,3} ) + +/* ---------------------------------------------------------------------*/ +#define DATENEW 1 +#define DATEOLD(x) x +#define datediff(x,y) ( DATEOLD(x) - DATENEW ) +#command datediff1(,) => ( DATEOLD() - DATENEW ) + ? datediff( x, y ) + +/* ---------------------------------------------------------------------*/ +#command _REGULAR_() => rm( ) + _REGULAR_(a) + _REGULAR_("a") + _REGULAR_('a') + _REGULAR_(["'a'"]) + _REGULAR_(&a.1) + _REGULAR_(&a) + _REGULAR_(&a.) + _REGULAR_(&(a)) + _REGULAR_(&a[1]) + _REGULAR_(a[1]) + _REGULAR_("['']") + + //NORMAL +#command _NORMAL_M() => nm( <"z"> ) + _NORMAL_M(a) + _NORMAL_M("a") + _NORMAL_M('a') + _NORMAL_M(["'a'"]) + _NORMAL_M(&a.1) + _NORMAL_M(&a) + _NORMAL_M(&a.) + _NORMAL_M(&(a)) + _NORMAL_M(&a[1]) + _NORMAL_M(a[1]) + _NORMAL_M("['']") + + //SMART +#command _SMART_M() => sm( <(z)> ) + _SMART_M(a) + _SMART_M("a") + _SMART_M('a') + _SMART_M(["'a'"]) + _SMART_M(&a.1) + _SMART_M(&a) + _SMART_M(&a.) + _SMART_M(&(a)) + _SMART_M(&a[1]) + _SMART_M(a[1]) + _SMART_M("['']") + + //DUMB +#command _DUMB_M() => dm( # ) + _DUMB_M(a) + _DUMB_M("a") + _DUMB_M('a') + _DUMB_M(["'a'"]) + _DUMB_M(&a.1) + _DUMB_M(&a) + _DUMB_M(&a.) + _DUMB_M(&(a)) + _DUMB_M(&a[1]) + _DUMB_M(a[1]) + _DUMB_M("['']") + +/* ---------------------------------------------------------------------*/ + // REGULAR list +#command _REGULAR_L() => rl( ) +_REGULAR_L(a,"a",'a',["'a'"],"['a']",'["a"]',&a.1,&a,&a.,&a. ,&(a),&a[1],&a.[1],&a. [2],&a&a, &a.a, a, a) + + // NORMAL list +#command _NORMAL_L() => nl( <"z"> ) +_NORMAL_L(n,"n",'a',["'a'"],"['a']",'["a"]',&a.1,&a,&a.,&a. ,&(a),&a[1],&a.[1],&a. [2],&a&a, &.a, &a.a, a, a) + + // SMART list +#command _SMART_L() => sl( <(z)> ) +_SMART_L(a,"a",'a',["'a'"],"['a']",'["a"]',&a.1,&a,&a.,&a. ,&(a),&a[1],&a.[1],&a. [2],&a&a, &.a, &a.a, a, a) + + // DUMB list +#command _DUMB_L() => dl( # ) +_DUMB_L(a,"a",'a',["'a'"],"['a']",'["a"]',&a.1,&a,&a.,&a. ,&(a),&a[1],&a.[1],&a. [2],&a&a, &.a, &a.a, a, a) + +/* ---------------------------------------------------------------------*/ + +index on LEFT( f1 , 10 ) to _tst + +/* ---------------------------------------------------------------------*/ +#xcommand SET [, ] WITH => :=[; :=] + SET v1, v2, v3 WITH 0 + +/* ---------------------------------------------------------------------*/ +#xcommand INSERT INTO ( [, ] ) VALUES ( +[, ] ) => ; +if
->( dbappend() ) ;; + + replace
-> with ;; + [ replace
-> with ; ] ; +
->( dbunlock() ) ;; +endif + + insert into test ( FIRST, LAST, STREET ) values ( "first", "last", "street" ) + +#xcommand INSERT2 INTO
( [, ] ) VALUES ( +[, ] ) => ; +if
->( dbappend() ) ;; +
-> := ;; + [
-> := ; ] ; +
->( dbunlock() ) ;; +endif + insert2 into test ( FIRST, LAST, STREET ) ; + values ( "first", "last", "street" ) + +/* ---------------------------------------------------------------------*/ +#define F1( n ) F2( n, N ) + F1( 1 ) + +#define F3( nN, Nn ) F2( nN, Nn, NN, nn, N, n ) + F3( 1, 2 ) + +/* ---------------------------------------------------------------------*/ +#command MYCOMMAND [] [MYCLAUSE ] => ; + MyFunction( {} [, ] ) + MYCOMMAND MYCLAUSE 321 "HELLO" + MYCOMMAND MYCLAUSE 321 "HELLO","all" + MYCOMMAND "HELLO","all" MYCLAUSE 321 + +#command MYCOMMAND2 [] [MYCLAUSE ] [ALL] => ; + MyFunction( {} [, ] ) + MYCOMMAND2 MYCLAUSE 321 "HELLO" + MYCOMMAND2 MYCLAUSE 321 "HELLO" ALL + MYCOMMAND2 ALL MYCLAUSE 321 "HELLO" + MYCOMMAND2 MYCLAUSE 321 "HELLO" ALL + MYCOMMAND2 MYCLAUSE 321 ALL "HELLO" + +/* + in := 'MYCOMMAND3 ALL MYCLAUSE 321 "HELLO","WORLD"' + in := 'MYCOMMAND3 MYCLAUSE 321 ALL "HELLO"' + in := 'MYCOMMAND3 MYCLAUSE 321 "HELLO" ALL' + in := 'MYCOMMAND3 MYCLAUSE 321 "HELLO"' +*/ + +#xcommand MYCOMMAND4 [] ; + [MYCLAUSE ] [MYOTHER ] => MyFunction4( {}, , ) + +/* ---------------------------------------------------------------------*/ + /* Special restricted macro match marker (used in SET FILTER TO command */ + SET FILTER TO &cVar. + SET FILTER TO &(cVar .AND. &cVar) + SET FILTER TO &cVar. .AND. cVar + +/* ---------------------------------------------------------------------*/ +#xtranslate XTRANS(( => normal( <(x)> ) +#xtranslate XTRANS(( => macro( <(x)> ) + + XTRANS( cVar ( + XTRANS( &cVar ( + XTRANS( &cVar+1 ( + XTRANS( &cVar. ( + XTRANS( (&cVar.) ( + XTRANS( &(cVar) ( + XTRANS( &cVar[3] ( + XTRANS( &cVar. [3] ( + XTRANS( &(cVar [3],&cvar) ( + XTRANS( (&cVar. [3],&cvar) ( + XTRANS( &cVar.1+5 ( + XTRANS( &cVar .AND. cVar ( + XTRANS( &cVar. .AND. cVar ( + +/* ---------------------------------------------------------------------*/ +#xtranslate MXCALL => () +#xtranslate MYCALL => ( , 'mycall' ) +#xtranslate MZCALL => ( , "mzcall" ) +#command FOO FOO => <(x)>+<(y)> +#translate BAR BAR => <(x)>+<(y)> + MYCALL &cVar ++cVar + MZCALL &cVar ++cVar + MYCALL &cVar+1 &cVar + MZCALL &cVar+1 &cVar + MXCALL &cVar + MXCALL &cVar. + MXCALL &cVar.1 + MXCALL &cVar + 1 + MYCALL &cVar &cVar + MYCALL &cVar. &cVar. + MYCALL &cVar.1 &cVar.1 + MYCALL &cVar ++cVar + MYCALL &cVar. --cVar + MYCALL &cVar.1 !cVar + MYCALL &cVar+1 &cVar + MYCALL &cVar.+1 &cVar. + MYCALL &cVar.1+1 &cVar.1 + MYCALL &cVar +1 &cVar + MYCALL &cVar. +1 &cVar. + MYCALL &cVar.1 +1 &cVar.1 + MYCALL &cVar +1 + MYCALL &cVar. +1 + MYCALL &cVar.1 +1 + FOO &cVar FOO &var. + BAR &cVar BAR &var. + FOO &cVar FOO &var.+1 + BAR &cVar BAR &var.+1 + MXCALL &cVar() + MXCALL &cVar++ + (MXCALL &cVar)++ + MXCALL &cVar.() + MXCALL &cVar.++ + (MXCALL &cVar.)++ + MXCALL &cVar.1 () + MXCALL &cVar.1 ++ + (MXCALL &cVar.1) ++ + +/* ---------------------------------------------------------------------*/ +#translate MTRANSLATE => normal_t(<"x">) +#translate MTRANSLATE => macro_t(<(x)>) +#command MCOMMAND => normal_c(<"x">) +#command MCOMMAND => macro_c(<(x)>) + MTRANSLATE &cVar + MTRANSLATE &cVar. + MTRANSLATE &(cVar) + MTRANSLATE & (cVar) + MTRANSLATE &cVar&cVar + MTRANSLATE &cVar+1 + MTRANSLATE &cVar.+1 + MTRANSLATE &cVar. .AND. .T. + MTRANSLATE &cVar++ + MTRANSLATE &cVar.++ + MTRANSLATE &cVar+=1 + MTRANSLATE &cVar.-=2 + MTRANSLATE &cVar*=1 + MTRANSLATE &cVar/=2 + MTRANSLATE &cVar%=1 + MTRANSLATE &cVar^=2 + MTRANSLATE &cVar:=1 + MTRANSLATE &cVar. .AND. .T. + MTRANSLATE &cVar .AND. .T. + MTRANSLATE &(cVar) +1 + MTRANSLATE & (cVar) +1 + MTRANSLATE &cVar.&cVar. + MTRANSLATE &cVar.&cVar.&cVar&cVar + MTRANSLATE &cVar.&(cVar) + + /* command */ + MCOMMAND &cVar + MCOMMAND &cVar. + MCOMMAND &(cVar) + MCOMMAND & (cVar) + MCOMMAND &cVar&cVar + MCOMMAND &cVar+1 + MCOMMAND &cVar.+1 + MCOMMAND &cVar. .AND. .T. + MCOMMAND &cVar++ + MCOMMAND &cVar.++ + MCOMMAND &cVar+=1 + MCOMMAND &cVar.-=2 + MCOMMAND &cVar*=1 + MCOMMAND &cVar/=2 + MCOMMAND &cVar%=12 + MCOMMAND &cVar^=2 + MCOMMAND &cVar:=1 + MCOMMAND &cVar. .AND. .T. + MCOMMAND &cVar .AND. .T. + MCOMMAND &(cVar) +1 + MCOMMAND & (cVar) +1 + MCOMMAND &cVar.&cVar. + MCOMMAND &cVar.&cVar.&cVar&cVar2 + MCOMMAND &cVar.&(cVar) + +/* ---------------------------------------------------------------------*/ + /* repeated optional clauses */ +#xcommand SET [, ] WITH => := [; :=] + SET v1 WITH 0 + SET v1, v2 WITH 0 + SET v1, v2, v3 WITH 0 + SET v1, v2, v3, v4 WITH 0 + +#command AVG [, ] TO [, ] =>; + AVERAGE( {||:=+} [, {||:=+} ] ) + AVG f1 TO s1 + AVG f1, f2 TO s1, s2 + AVG f1, f2, f3 TO s1, s2, s3 + +/* ---------------------------------------------------------------------*/ + COPY STRUCTURE EXTENDED TO teststru + +/* ---------------------------------------------------------------------*/ +#ifdef __HARBOUR__ +#command @ , GET ; + [PICTURE ] ; + [VALID ] ; + [WHEN ] ; + [CAPTION ) ; + ; AAdd( GetList, ; + _GET_( , <"var">, , <{valid}>, <{when}> ) ) ; + [; ATail(GetList):Caption := GET ; + PUSHBUTTON ; + [VALID ] ; + [WHEN ] ; + [CAPTION
] ; + [MESSAGE ] ; + [SEND ] ; + ; + => SetPos( , ] ; + [; ATail(GetList):CapRow := ATail(Getlist):row ; + ; ATail(GetList):CapCol := ATail(Getlist):col - ; + __CapLength() - 1] ; + [; ATail(GetList):message := ] ; + [; ATail(GetList):] ; + ; ATail(GetList):Display() +#endif + @ 0,1 GET a + @ 0,2 GET a PICTURE "X" + @ 0,3 GET a PICTURE "X" VALID .T. + @ 0,4 GET a PICTURE "X" VALID .T. WHEN .T. + @ 0,5 GET a PICTURE "X" VALID .T. WHEN .T. CAPTION "myget" + @ 0,6 GET a PICTURE "X" VALID .T. WHEN .T. CAPTION "myget" MESSAGE "mymess" + @ 0,7 GET a PICTURE "X" VALID .T. WHEN .T. CAPTION "myget" MESSAGE "mymess" SEND send() +/* ---------------------------------------------------------------------*/ + @ 1,1 GET a RANGE 0,100 + @ 1,2 GET a PICTURE "X" RANGE 0,100 + /* NOTE: Clipper fails here */ + @ 1,3 GET a PICTURE "X" VALID .T. RANGE 0,100 + @ 1,4 GET a PICTURE "X" WHEN .T. RANGE 0,100 + @ 1,5 GET a PICTURE "X" WHEN .T. CAPTION "myget" RANGE 0,100 + @ 1,6 GET a PICTURE "X" WHEN .T. CAPTION "myget" MESSAGE "mymess" RANGE 0,100 + @ 1,7 GET a PICTURE "X" WHEN .T. CAPTION "myget" MESSAGE "mymess" SEND send() RANGE 0,100 + @ 2,1 GET a + @ 2,2 GET a RANGE 0,100 PICTURE "X" + @ 2,3 GET a PICTURE "X" RANGE 0,100 + @ 2,4 GET a PICTURE "X" RANGE 0,100 WHEN .T. + @ 2,5 GET a PICTURE "X" RANGE 0,100 WHEN .T. CAPTION "myget" + @ 2,6 GET a PICTURE "X" RANGE 0,100 WHEN .T. CAPTION "myget" MESSAGE "mymess" + @ 2,7 GET a PICTURE "X" RANGE 0,100 WHEN .T. CAPTION "myget" MESSAGE "mymess" SEND send() + +/* ---------------------------------------------------------------------*/ +#ifdef __HARBOUR__ +#command @ , ] ; + [MESSAGE ] ; + [COLOR ] ; + [FOCUS ] ; + [STATE ] ; + [STYLE