diff --git a/harbour/ChangeLog b/harbour/ChangeLog index ccffa9a24c..26aebd6347 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,21 @@ +19990910-22:10 GMT+1 Victor Szel + * source/vm/hvm.c + ! Fixed the operator overloading feature. (Reported by David) + * source/compiler/harbour.y + + Added /es switch, like in Clipper. /es0 and /es is the default, no + errorlevel is raised on warning, /es1 will set errorlevel, /es2 will + set errorlevel and not generate output. + + The program header is always (even with /q) printed now, right at startup. + * "id" -> "prefix" + + /m /r /t /u @ command line switches added as todo, checks and + messages added to the source, commented out lines added to help screen. + * tests/working/Makefile + tests/working/statinit.prg + + //NOTEST removed, the missing dummy HELLO() function added, so now it + links. + * source/rtl/memvars.c + * Fixed the MEMVARBLOCK() implementation in the doc examples 8) + 19990910-15:25 EDT David G. Holm * source/rtl/gt/gtos2.c ! I forgot to remove a debug printf() call when I committed the diff --git a/harbour/source/compiler/harbour.y b/harbour/source/compiler/harbour.y index 4d8fb35bc2..6431b418ba 100644 --- a/harbour/source/compiler/harbour.y +++ b/harbour/source/compiler/harbour.y @@ -455,18 +455,25 @@ FUNCTIONS functions, funcalls; PFUNCTION _pInitFunc; SYMBOLS symbols; -BOOL _bStartProc = TRUE; /* holds if we need to create the starting procedure */ -BOOL _bLineNumbers = TRUE; /* holds if we need pcodes with line numbers */ -BOOL _bQuiet = FALSE; /* quiet mode */ -BOOL _bSyntaxCheckOnly = FALSE; /* syntax check only */ -int _iLanguage = LANG_C; /* default Harbour generated output language */ -BOOL _bRestrictSymbolLength = FALSE; /* generate 10 chars max symbols length */ -BOOL _bShortCuts = TRUE; /* .and. & .or. expressions shortcuts */ -BOOL _bWarnings = FALSE; /* enable parse warnings */ -BOOL _bAutoMemvarAssume = FALSE; /* holds if undeclared variables are automatically assumed MEMVAR */ -BOOL _bForceMemvars = FALSE; /* holds if memvars are assumed when accesing undeclared variable */ -BOOL _bDebugInfo = FALSE; /* holds if generate debugger required info */ -char _szPrefix[ 20 ] = { '\0' }; +/* /ES command line setting types */ +#define HB_EXITLEVEL_DEFAULT 0 +#define HB_EXITLEVEL_SETEXIT 1 +#define HB_EXITLEVEL_DELTARGET 2 + +BOOL _bStartProc = TRUE; /* holds if we need to create the starting procedure */ +BOOL _bLineNumbers = TRUE; /* holds if we need pcodes with line numbers */ +BOOL _bQuiet = FALSE; /* quiet mode */ +BOOL _bSyntaxCheckOnly = FALSE; /* syntax check only */ +int _iLanguage = LANG_C; /* default Harbour generated output language */ +BOOL _bRestrictSymbolLength = FALSE; /* generate 10 chars max symbols length */ +BOOL _bShortCuts = TRUE; /* .and. & .or. expressions shortcuts */ +BOOL _bWarnings = FALSE; /* enable parse warnings */ +BOOL _bAnyWarning = FALSE; /* holds if there was any warning during the compilation process */ +BOOL _bAutoMemvarAssume = FALSE; /* holds if undeclared variables are automatically assumed MEMVAR */ +BOOL _bForceMemvars = FALSE; /* holds if memvars are assumed when accesing undeclared variable */ +BOOL _bDebugInfo = FALSE; /* holds if generate debugger required info */ +char _szPrefix[ 20 ] = { '\0' }; /* holds the prefix added to the generated symbol init function name (in C output currently) */ +int _iExitLevel = HB_EXITLEVEL_DEFAULT; /* holds if there was any warning during the compilation process */ /* This variable is used to flag if variables have to be passed by reference * - it is required in DO WITH statement @@ -1349,6 +1356,8 @@ void GenWarning( char* _szWarnings[], char cPrefix, int iWarning, char * szWarni printf( "Warning %c%i ", cPrefix, iWarning ); printf( _szWarnings[ iWarning - 1 ], szWarning1, szWarning2 ); printf( "\n" ); + + _bAnyWarning = TRUE; } } @@ -1367,6 +1376,10 @@ void EXTERNAL_LINKAGE close_on_exit( void ) int harbour_main( int argc, char * argv[] ) { int iStatus = 0, iArg = 1; + BOOL bSkipGen; + + printf( "Harbour compiler build %i%s (%04d.%02d.%02d)\n", + hb_build, hb_revision, hb_year, hb_month, hb_day ); if( argc > 1 ) { @@ -1415,6 +1428,45 @@ int harbour_main( int argc, char * argv[] ) free( szDefText ); } break; + + case 'e': + case 'E': + + if( argv[ iArg ][ 2 ] == 's' || + argv[ iArg ][ 2 ] == 'S' ) + { + switch( argv[ iArg ][ 3 ] ) + { + case '\0': + case '0': + _iExitLevel = HB_EXITLEVEL_DEFAULT; + break; + + case '1': + _iExitLevel = HB_EXITLEVEL_SETEXIT; + break; + + case '2': + _iExitLevel = HB_EXITLEVEL_DELTARGET; + break; + + default: + /* NOTE: Redundant code */ + printf( "Invalid command line option: %s\n", + &argv[ iArg ][ 0 ] ); + exit( EXIT_FAILURE ); + } + } + else + { + /* NOTE: Redundant code */ + printf( "Invalid command line option: %s\n", + &argv[ iArg ][ 0 ] ); + exit( EXIT_FAILURE ); + } + + break; + #ifdef HARBOUR_OBJ_GENERATION case 'f': case 'F': @@ -1471,6 +1523,12 @@ int harbour_main( int argc, char * argv[] ) _bLineNumbers = FALSE; break; + case 'm': + case 'M': + /* TODO: Implement this switch */ + printf( "Not yet supported command line option: %s\n", &argv[ iArg ][ 0 ] ); + break; + case 'n': case 'N': _bStartProc = FALSE; @@ -1492,11 +1550,29 @@ int harbour_main( int argc, char * argv[] ) _bQuiet = TRUE; break; + case 'r': + case 'R': + /* TODO: Implement this switch */ + printf( "Not yet supported command line option: %s\n", &argv[ iArg ][ 0 ] ); + break; + case 's': case 'S': _bSyntaxCheckOnly = TRUE; break; + case 't': + case 'T': + /* TODO: Implement this switch */ + printf( "Not yet supported command line option: %s\n", &argv[ iArg ][ 0 ] ); + break; + + case 'u': + case 'U': + /* TODO: Implement this switch */ + printf( "Not yet supported command line option: %s\n", &argv[ iArg ][ 0 ] ); + break; + case 'v': case 'V': _bForceMemvars = TRUE; @@ -1539,15 +1615,15 @@ int harbour_main( int argc, char * argv[] ) break; } } + else if( argv[ iArg ][ 0 ] == '@' ) + /* TODO: Implement this switch */ + printf( "Not yet supported command line option: %s\n", &argv[ iArg ][ 0 ] ); else _pFileName = hb_fsFNameSplit( argv[ iArg ] ); + iArg++; } - if( !_bQuiet ) - printf( "Harbour compiler build %i%s (%04d.%02d.%02d)\n", - hb_build, hb_revision, hb_year, hb_month, hb_day ); - if( _pFileName ) { if( !_pFileName->szExtension ) @@ -1579,6 +1655,7 @@ int harbour_main( int argc, char * argv[] ) symbols.pLast = NULL; _pInitFunc = NULL; + _bAnyWarning = FALSE; atexit( close_on_exit ); @@ -1618,10 +1695,24 @@ int harbour_main( int argc, char * argv[] ) fclose( yyin ); files.pLast = NULL; + bSkipGen = FALSE; + + if( _bAnyWarning ) + { + if( _iExitLevel == HB_EXITLEVEL_SETEXIT ) + iStatus = 1; + if( _iExitLevel == HB_EXITLEVEL_DELTARGET ) + { + iStatus = 1; + bSkipGen = TRUE; + printf( "\nNo code generated\n" ); + } + } + #ifdef HARBOUR_OBJ_GENERATION - if( ! _bSyntaxCheckOnly && ! _bObj32 ) + if( ! _bSyntaxCheckOnly && ! bSkipGen && ! _bObj32 ) #else - if( ! _bSyntaxCheckOnly ) + if( ! _bSyntaxCheckOnly && ! bSkipGen ) #endif { if( _pInitFunc ) @@ -1702,7 +1793,8 @@ int harbour_main( int argc, char * argv[] ) GenObj32( szFileName, _pFileName->szName ); } #endif - if( lPpo ) fclose ( yyppo ); + if( lPpo ) + fclose( yyppo ); } else { @@ -1728,6 +1820,7 @@ void PrintUsage( char * szSelf ) "\t/a\t\tautomatic memvar declaration\n" "\t/b\t\tdebug info\n" "\t/d[=]\t#define \n" + "\t/es[]\tset exit severity\n" #ifdef HARBOUR_OBJ_GENERATION "\t/f\t\tgenerated object file\n" "\t\t\t /fobj32 --> Windows/Dos 32 bits OBJ\n" @@ -1740,19 +1833,24 @@ void PrintUsage( char * szSelf ) "\t\t\t /gr (Resources) --> \n" "\t/i\tadd #include file search path\n" "\t/l\t\tsuppress line number information\n" +/* TODO: "\t/m\t\tcompile module only\n" */ "\t/n\t\tno implicit starting procedure\n" "\t/o\tobject file drive and/or path\n" "\t/p\t\tgenerate pre-processed output (.ppo) file\n" "\t/q\t\tquiet\n" +/* TODO: "\t/r[]\trequest linker to search (or none)\n" */ "\t/s\t\tsyntax check only\n" +/* TODO: "\t/t\tpath for temp file creation\n" */ +/* TODO: "\t/u[]\tuse command def set in (or none)\n" */ "\t/v\t\tvariables are assumed M->\n" "\t/w\t\tenable warnings\n" - "\t/x[]\tset symbol init function name prefix\n" + "\t/x[]\tset symbol init function name prefix\n" #ifdef YYDEBUG "\t/y\t\ttrace lex & yacc activity\n" #endif "\t/z\t\tsuppress shortcutting (.and. & .or.)\n" "\t/10\t\trestrict symbol length to 10 characters\n" +/* TODO: "\t @\tcompile list of modules in \n" */ , szSelf ); } diff --git a/harbour/source/rtl/memvars.c b/harbour/source/rtl/memvars.c index 7b18b74bd1..8270239183 100644 --- a/harbour/source/rtl/memvars.c +++ b/harbour/source/rtl/memvars.c @@ -1346,7 +1346,7 @@ HARBOUR HB___MVDBGINFO( void ) * The variable is specified by its name passed as the function parameter. * $EXAMPLES$ * FUNCTION MEMVARBLOCK( cMemvar ) - * RETURN {|x| IIF( x==NIL, __MVGET( cMemvar ), __MVPUT( cMemvar, x ) ) } + * RETURN {|x| IIF( PCOUNT()==0, __MVGET( cMemvar ), __MVPUT( cMemvar, x ) ) } * $STATUS$ * * $COMPLIANCE$ @@ -1424,7 +1424,7 @@ HARBOUR HB___MVGET( void ) * If a value is not specified then the NIL is assumed * $EXAMPLES$ * FUNCTION MEMVARBLOCK( cMemvar ) - * RETURN {|x| IIF( x==NIL, __MVGET( cMemvar ), __MVPUT( cMemvar, x ) ) } + * RETURN {|x| IIF( PCOUNT()==0, __MVGET( cMemvar ), __MVPUT( cMemvar, x ) ) } * $STATUS$ * * $COMPLIANCE$ diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index 813e4b3ff5..1490cc961f 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -1174,11 +1174,8 @@ void hb_vmEqual( BOOL bExact ) hb_vmPushLogical( hb_vmPopLogical() == hb_vmPopLogical() ); else if( IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "==" ) ) - { - hb_stackPop(); - hb_stackPop(); hb_vmOperatorCall( pItem1, pItem2, "==" ); - } + else if( bExact && IS_ARRAY( pItem1 ) && IS_ARRAY( pItem2 ) ) { BOOL bResult = pItem1->item.asArray.value->pItems && pItem2->item.asArray.value->pItems && @@ -1326,13 +1323,7 @@ void hb_vmGreater( void ) } else if( IS_OBJECT( stack.pPos - 2 ) && hb_objHasMsg( stack.pPos - 2, ">" ) ) - { - PHB_ITEM pItem2 = stack.pPos - 1; - PHB_ITEM pItem1 = stack.pPos - 2; - hb_stackPop(); - hb_stackPop(); - hb_vmOperatorCall( pItem1, pItem2, ">" ); - } + hb_vmOperatorCall( stack.pPos - 2, stack.pPos - 1, ">" ); else if( ( stack.pPos - 2 )->type != ( stack.pPos - 1 )->type ) { @@ -1379,13 +1370,7 @@ void hb_vmGreaterEqual( void ) } else if( IS_OBJECT( stack.pPos - 2 ) && hb_objHasMsg( stack.pPos - 2, ">=" ) ) - { - PHB_ITEM pItem2 = stack.pPos - 1; - PHB_ITEM pItem1 = stack.pPos - 2; - hb_stackPop(); - hb_stackPop(); - hb_vmOperatorCall( pItem1, pItem2, ">=" ); - } + hb_vmOperatorCall( stack.pPos - 2, stack.pPos - 1, ">=" ); else if( ( stack.pPos - 2 )->type != ( stack.pPos - 1 )->type ) { @@ -1483,13 +1468,7 @@ void hb_vmLess( void ) } else if( IS_OBJECT( stack.pPos - 2 ) && hb_objHasMsg( stack.pPos - 2, "<" ) ) - { - PHB_ITEM pItem2 = stack.pPos - 1; - PHB_ITEM pItem1 = stack.pPos - 2; - hb_stackPop(); - hb_stackPop(); - hb_vmOperatorCall( pItem1, pItem2, "<" ); - } + hb_vmOperatorCall( stack.pPos - 2, stack.pPos - 1, "<" ); else if( ( stack.pPos - 2 )->type != ( stack.pPos - 1 )->type ) { @@ -1536,13 +1515,7 @@ void hb_vmLessEqual( void ) } else if( IS_OBJECT( stack.pPos - 2 ) && hb_objHasMsg( stack.pPos - 2, "<=" ) ) - { - PHB_ITEM pItem2 = stack.pPos - 1; - PHB_ITEM pItem1 = stack.pPos - 2; - hb_stackPop(); - hb_stackPop(); - hb_vmOperatorCall( pItem1, pItem2, "<=" ); - } + hb_vmOperatorCall( stack.pPos - 2, stack.pPos - 1, "<=" ); else if( ( stack.pPos - 2 )->type != ( stack.pPos - 1 )->type ) { @@ -1666,11 +1639,7 @@ void hb_vmNotEqual( void ) hb_vmPushLogical( hb_vmPopLogical() != hb_vmPopLogical() ); else if( IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "!=" ) ) - { - hb_stackPop(); - hb_stackPop(); hb_vmOperatorCall( pItem1, pItem2, "!=" ); - } else if( pItem1->type != pItem2->type ) { @@ -1749,11 +1718,8 @@ void hb_vmMinus( void ) hb_errRT_BASE( EG_STROVERFLOW, 1210, NULL, "-" ); } else if( IS_OBJECT( stack.pPos - 2 ) && hb_objHasMsg( stack.pPos - 2, "-" ) ) - { - hb_stackPop(); - hb_stackPop(); hb_vmOperatorCall( pItem1, pItem2, "-" ); - } + else { PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1082, NULL, "-" ); @@ -1917,11 +1883,7 @@ void hb_vmPlus( void ) } else if( IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem2, "+" ) ) - { - hb_stackPop(); - hb_stackPop(); hb_vmOperatorCall( pItem1, pItem2, "+" ); - } else { diff --git a/harbour/tests/working/Makefile b/harbour/tests/working/Makefile index fe116e0ab9..ca570fff12 100644 --- a/harbour/tests/working/Makefile +++ b/harbour/tests/working/Makefile @@ -111,6 +111,7 @@ PRG_SOURCES=\ set_num.prg \ set_test.prg \ sound.prg \ + statinit.prg \ statfun.prg \ statics.prg \ strcmp.prg \ @@ -162,7 +163,6 @@ BAD_PRG_SOURCES=\ spawn.prg \ spawn2.prg \ statics1.prg \ - statinit.prg \ statics2.prg \ test10.prg \ testid.prg \ diff --git a/harbour/tests/working/statinit.prg b/harbour/tests/working/statinit.prg index ec9efe06a6..c232811058 100644 --- a/harbour/tests/working/statinit.prg +++ b/harbour/tests/working/statinit.prg @@ -1,4 +1,3 @@ -//NOTEST // // $Id$ // @@ -13,3 +12,6 @@ FUNCTION Main() ? "This is a compiler test, so if you see this, the test was successful." RETURN NIL + +FUNCTION Hello() + RETURN NIL