diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 7c19754e02..e1fba85bbe 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,55 @@ +19990727-20:15 GMT+2 Ryszard Glab + + *source/compiler/harbour.y + * static variables can be initialized using the codeblocks + that calls functions. However static variables still cannot + be initialized with direct function call. + * changed the symbol created for function that initialize + static variable to: '(_INITSTATICS)' and generated function is + named now hb_INITSTATICS - this allows to create an user + defined function or memvar named _INITSTATICS + * the _INITSTATICS function (used to initialize static variables) + have the scope equal to (FS_INIT | FS_EXIT) - to distinguish + this function from other INIT functions. All _INITSTATICS + functions defined in the application have to be called + before normal INIT functions are called. + + *source/vm/hvm.c + * All _INITSTATICS functions defined in the application are + called before normal INIT procedures - this allows to use + static variables in INIT procedures + + *tests/working/initexit.prg + * updated code to test cooperation of INIT procedures with + static variables + + *include/rdd.api + + added forward declaration for struct _RDDFUNCS + + *source/rtl/natmsg/msgbas.c + *source/rtl/natmsg/msgcat.c + *source/rtl/natmsg/msgcz852.c + *source/rtl/natmsg/msgczkam.c + *source/rtl/natmsg/msgdut.c + *source/rtl/natmsg/msgeo.c + *source/rtl/natmsg/msgfre.c + *source/rtl/natmsg/msggal.c + *source/rtl/natmsg/msgger.c + *source/rtl/natmsg/msghu.c + *source/rtl/natmsg/msgia.c + *source/rtl/natmsg/msgita.c + *source/rtl/natmsg/msgkor.c + *source/rtl/natmsg/msgpl852.c + *source/rtl/natmsg/msgplmaz.c + *source/rtl/natmsg/msgpor.c + *source/rtl/natmsg/msgr1251.c + *source/rtl/natmsg/msgru866.c + *source/rtl/natmsg/msgspa.c + *source/rtl/natmsg/msguk.c + *source/rtl/natmsg/msgyu852.c + * corrected bug in hb_ErrorNetDescription + (was "<=" instead of "<" ;-) + 19990727-19:48 GMT+1 Bruno Cantero * source/rdd/dbcmd.c Fixed a GFP (Paul, test it) diff --git a/harbour/include/rdd.api b/harbour/include/rdd.api index bd1b7ccb42..05fdf1f624 100644 --- a/harbour/include/rdd.api +++ b/harbour/include/rdd.api @@ -455,6 +455,7 @@ typedef struct * * Informaci˘n para administrar el  rea de trabajo */ +struct _RDDFUNCS; typedef struct _AREA { diff --git a/harbour/source/compiler/harbour.y b/harbour/source/compiler/harbour.y index 3ae6638549..bcdb6631b3 100644 --- a/harbour/source/compiler/harbour.y +++ b/harbour/source/compiler/harbour.y @@ -2148,7 +2148,10 @@ void GenCCode( char *szFileName, char *szName ) /* generates the C languag if( pFunc->cScope & FS_STATIC || pFunc->cScope & FS_INIT || pFunc->cScope & FS_EXIT ) fprintf( yyc, "static " ); - fprintf( yyc, "HARBOUR HB_%s( void );\n", pFunc->szName ); + if( pFunc == _pInitFunc ) + fprintf( yyc, "HARBOUR hb_INITSTATICS( void );\n" ); + else + fprintf( yyc, "HARBOUR HB_%s( void );\n", pFunc->szName ); pFunc = pFunc->pNext; } /* write functions prototypes for called functions outside this PRG */ @@ -2173,36 +2176,47 @@ void GenCCode( char *szFileName, char *szName ) /* generates the C languag wSym = 0; /* symbols counter */ while( pSym ) { - fprintf( yyc, "{ \"%s\", ", pSym->szName ); + if( pSym->szName[ 0 ] == '(' ) + { + /* Since the normal function cannot be INIT and EXIT at the same time + * we are using these two bits to mark the special function used to + * initialize static variables + */ + fprintf( yyc, "{ \"(_INITSTATICS)\", FS_INIT | FS_EXIT, hb_INITSTATICS, 0}" ); + } + else + { + fprintf( yyc, "{ \"%s\", ", pSym->szName ); + + if( pSym->cScope & FS_STATIC ) + fprintf( yyc, "FS_STATIC" ); + + else if( pSym->cScope & FS_INIT ) + fprintf( yyc, "FS_INIT" ); + + else if( pSym->cScope & FS_EXIT ) + fprintf( yyc, "FS_EXIT" ); + + else + fprintf( yyc, "FS_PUBLIC" ); + + if( pSym->cScope & VS_MEMVAR ) + fprintf( yyc, " | FS_MEMVAR" ); + + if( ( pSym->cScope != FS_MESSAGE ) && ( pSym->cScope & FS_MESSAGE ) ) /* only for non public symbols */ + fprintf( yyc, " | FS_MESSAGE" ); + + /* specify the function address if it is a defined function or an + external called function */ + if( GetFunction( pSym->szName ) ) /* is it a function defined in this module */ + fprintf( yyc, ", HB_%s, 0 }", pSym->szName ); + else if( GetFuncall( pSym->szName ) ) /* is it a function called from this module */ + fprintf( yyc, ", HB_%s, 0 }", pSym->szName ); + else + fprintf( yyc, ", 0, 0 }" ); /* memvar */ + } ++wSym; - if( pSym->cScope & FS_STATIC ) - fprintf( yyc, "FS_STATIC" ); - - else if( pSym->cScope & FS_INIT ) - fprintf( yyc, "FS_INIT" ); - - else if( pSym->cScope & FS_EXIT ) - fprintf( yyc, "FS_EXIT" ); - - else - fprintf( yyc, "FS_PUBLIC" ); - - if( pSym->cScope & VS_MEMVAR ) - fprintf( yyc, " | FS_MEMVAR" ); - - if( ( pSym->cScope != FS_MESSAGE ) && ( pSym->cScope & FS_MESSAGE ) ) /* only for non public symbols */ - fprintf( yyc, " | FS_MESSAGE" ); - - /* specify the function address if it is a defined function or an - external called function */ - if( GetFunction( pSym->szName ) ) /* is it a function defined in this module */ - fprintf( yyc, ", HB_%s, 0 }", pSym->szName ); - else if( GetFuncall( pSym->szName ) ) /* is it a function called from this module */ - fprintf( yyc, ", HB_%s, 0 }", pSym->szName ); - else - fprintf( yyc, ", 0, 0 }" ); /* memvar */ - if( pSym != symbols.pLast ) fprintf( yyc, ",\n" ); @@ -2221,7 +2235,10 @@ void GenCCode( char *szFileName, char *szName ) /* generates the C languag if( pFunc->cScope != FS_PUBLIC ) fprintf( yyc, "static " ); - fprintf( yyc, "HARBOUR HB_%s( void )\n{\n static BYTE pcode[] = { \n", pFunc->szName ); + if( pFunc == _pInitFunc ) /* Is it (_INITSTATICS) */ + fprintf( yyc, "HARBOUR hb_INITSTATICS( void )\n{\n static BYTE pcode[] = { \n" ); + else + fprintf( yyc, "HARBOUR HB_%s( void )\n{\n static BYTE pcode[] = { \n", pFunc->szName ); lPCodePos = 0; while( lPCodePos < pFunc->lPCodePos ) @@ -2779,7 +2796,7 @@ void GenCCode( char *szFileName, char *szName ) /* generates the C languag { GetSymbol( _pInitFunc->szName, &w ); w = FixSymbolPos( w ); - fprintf( yyc, " HB_P_SFRAME, %i, %i,\t\t/* symbol _INITSTATICS */\n", + fprintf( yyc, " HB_P_SFRAME, %i, %i,\t\t/* symbol (_INITSTATICS) */\n", LOBYTE( w ), HIBYTE( w ) ); } lPCodePos += 3; @@ -2789,7 +2806,7 @@ void GenCCode( char *szFileName, char *szName ) /* generates the C languag { GetSymbol( _pInitFunc->szName, &w ); w = FixSymbolPos( w ); - fprintf( yyc, " HB_P_STATICS, %i, %i,\t\t/* symbol _INITSTATICS */\n", + fprintf( yyc, " HB_P_STATICS, %i, %i,\t\t/* symbol (_INITSTATICS) */\n", LOBYTE( w ), HIBYTE( w ) ); lPCodePos += 3; } @@ -4644,9 +4661,10 @@ void StaticDefStart( void ) functions.pLast->bFlags |= FUN_USES_STATICS; if( ! _pInitFunc ) { - _pInitFunc =FunctionNew( yy_strdup("_INITSTATICS"), FS_INIT ); + _pInitFunc =FunctionNew( yy_strdup("(_INITSTATICS)"), FS_INIT ); _pInitFunc->pOwner =functions.pLast; _pInitFunc->bFlags =FUN_USES_STATICS | FUN_PROCEDURE; + _pInitFunc->cScope =FS_INIT | FS_EXIT; functions.pLast =_pInitFunc; PushInteger( 1 ); /* the number of static variables is unknown now */ GenPCode3( HB_P_STATICS, 0, 0 ); @@ -4695,8 +4713,10 @@ void StaticDefEnd( WORD wCount ) */ void StaticAssign( void ) { - if( iVarScope == VS_STATIC ) - _pInitFunc->bFlags |= FUN_ILLEGAL_INIT; + if( iVarScope == VS_STATIC && functions.pLast->szName ) + /* function call is allowed if it is inside a codeblock + */ + _pInitFunc->bFlags |= FUN_ILLEGAL_INIT; } /* diff --git a/harbour/source/rtl/natmsg/msgbas.c b/harbour/source/rtl/natmsg/msgbas.c index 1f6a25ec3b..23eb46cc4f 100644 --- a/harbour/source/rtl/natmsg/msgbas.c +++ b/harbour/source/rtl/natmsg/msgbas.c @@ -75,7 +75,7 @@ static char *genericErrors[] = char *hb_ErrorNatDescription( ULONG ulGenError ) { - if( ulGenError <= sizeof(genericErrors)/sizeof(char*) ) + if( ulGenError < sizeof(genericErrors)/sizeof(char*) ) return genericErrors[ ulGenError ]; else return genericErrors[ 0 ]; diff --git a/harbour/source/rtl/natmsg/msgcat.c b/harbour/source/rtl/natmsg/msgcat.c index 48b670d74e..e70bf3de82 100644 --- a/harbour/source/rtl/natmsg/msgcat.c +++ b/harbour/source/rtl/natmsg/msgcat.c @@ -76,7 +76,7 @@ static char *genericErrors[] = char *hb_ErrorNatDescription( ULONG ulGenError ) { - if( ulGenError <= sizeof(genericErrors)/sizeof(char*) ) + if( ulGenError < sizeof(genericErrors)/sizeof(char*) ) return genericErrors[ ulGenError ]; else return genericErrors[ 0 ]; diff --git a/harbour/source/rtl/natmsg/msgcz852.c b/harbour/source/rtl/natmsg/msgcz852.c index afe0e42179..a23baa1ba9 100644 --- a/harbour/source/rtl/natmsg/msgcz852.c +++ b/harbour/source/rtl/natmsg/msgcz852.c @@ -90,7 +90,7 @@ static char *genericErrors[] = char *hb_ErrorNatDescription( ULONG ulGenError ) { - if( ulGenError <= sizeof(genericErrors)/sizeof(char*) ) + if( ulGenError < sizeof(genericErrors)/sizeof(char*) ) return genericErrors[ ulGenError ]; else return genericErrors[ 0 ]; diff --git a/harbour/source/rtl/natmsg/msgczkam.c b/harbour/source/rtl/natmsg/msgczkam.c index 3aa7c72aa8..034e3d520d 100644 --- a/harbour/source/rtl/natmsg/msgczkam.c +++ b/harbour/source/rtl/natmsg/msgczkam.c @@ -90,7 +90,7 @@ static char *genericErrors[] = char *hb_ErrorNatDescription( ULONG ulGenError ) { - if( ulGenError <= sizeof(genericErrors)/sizeof(char*) ) + if( ulGenError < sizeof(genericErrors)/sizeof(char*) ) return genericErrors[ ulGenError ]; else return genericErrors[ 0 ]; diff --git a/harbour/source/rtl/natmsg/msgdut.c b/harbour/source/rtl/natmsg/msgdut.c index 7cd07dd155..0edcf63e67 100644 --- a/harbour/source/rtl/natmsg/msgdut.c +++ b/harbour/source/rtl/natmsg/msgdut.c @@ -70,7 +70,7 @@ static char *genericErrors[] = char *hb_ErrorNatDescription( ULONG ulGenError ) { - if( ulGenError <= sizeof(genericErrors)/sizeof(char*) ) + if( ulGenError < sizeof(genericErrors)/sizeof(char*) ) return genericErrors[ ulGenError ]; else return genericErrors[ 0 ]; diff --git a/harbour/source/rtl/natmsg/msgeo.c b/harbour/source/rtl/natmsg/msgeo.c index e9f9689ed9..917a9baf6c 100644 --- a/harbour/source/rtl/natmsg/msgeo.c +++ b/harbour/source/rtl/natmsg/msgeo.c @@ -72,7 +72,7 @@ static char *genericErrors[] = char *hb_ErrorNatDescription( ULONG ulGenError ) { - if( ulGenError <= sizeof(genericErrors)/sizeof(char*) ) + if( ulGenError < sizeof(genericErrors)/sizeof(char*) ) return genericErrors[ ulGenError ]; else return genericErrors[ 0 ]; diff --git a/harbour/source/rtl/natmsg/msgfre.c b/harbour/source/rtl/natmsg/msgfre.c index bc6c5dc11a..ce443492fb 100644 --- a/harbour/source/rtl/natmsg/msgfre.c +++ b/harbour/source/rtl/natmsg/msgfre.c @@ -76,7 +76,7 @@ static char *genericErrors[] = char *hb_ErrorNatDescription( ULONG ulGenError ) { - if( ulGenError <= sizeof(genericErrors)/sizeof(char*) ) + if( ulGenError < sizeof(genericErrors)/sizeof(char*) ) return genericErrors[ ulGenError ]; else return genericErrors[ 0 ]; diff --git a/harbour/source/rtl/natmsg/msggal.c b/harbour/source/rtl/natmsg/msggal.c index 0550cef101..d51627ff57 100644 --- a/harbour/source/rtl/natmsg/msggal.c +++ b/harbour/source/rtl/natmsg/msggal.c @@ -76,7 +76,7 @@ static char *genericErrors[] = char *hb_ErrorNatDescription( ULONG ulGenError ) { - if( ulGenError <= sizeof(genericErrors)/sizeof(char*) ) + if( ulGenError < sizeof(genericErrors)/sizeof(char*) ) return genericErrors[ ulGenError ]; else return genericErrors[ 0 ]; diff --git a/harbour/source/rtl/natmsg/msgger.c b/harbour/source/rtl/natmsg/msgger.c index 46c1259b56..3bbe56292b 100644 --- a/harbour/source/rtl/natmsg/msgger.c +++ b/harbour/source/rtl/natmsg/msgger.c @@ -71,7 +71,7 @@ static char *genericErrors[] = char *hb_ErrorNatDescription( ULONG ulGenError ) { - if( ulGenError <= sizeof(genericErrors)/sizeof(char*) ) + if( ulGenError < sizeof(genericErrors)/sizeof(char*) ) return genericErrors[ ulGenError ]; else return genericErrors[ 0 ]; diff --git a/harbour/source/rtl/natmsg/msghu.c b/harbour/source/rtl/natmsg/msghu.c index 36b970d5d2..ca9c43142d 100644 --- a/harbour/source/rtl/natmsg/msghu.c +++ b/harbour/source/rtl/natmsg/msghu.c @@ -119,7 +119,7 @@ static char *genericErrors[] = char *hb_ErrorNatDescription( ULONG ulGenError ) { - if( ulGenError <= sizeof(genericErrors)/sizeof(char*) ) + if( ulGenError < sizeof(genericErrors)/sizeof(char*) ) return genericErrors[ ulGenError ]; else return genericErrors[ 0 ]; diff --git a/harbour/source/rtl/natmsg/msgia.c b/harbour/source/rtl/natmsg/msgia.c index 3253222f2d..c860b8a5de 100644 --- a/harbour/source/rtl/natmsg/msgia.c +++ b/harbour/source/rtl/natmsg/msgia.c @@ -74,7 +74,7 @@ static char *genericErrors[] = char *hb_ErrorNatDescription( ULONG ulGenError ) { - if( ulGenError <= sizeof(genericErrors)/sizeof(char*) ) + if( ulGenError < sizeof(genericErrors)/sizeof(char*) ) return genericErrors[ ulGenError ]; else return genericErrors[ 0 ]; diff --git a/harbour/source/rtl/natmsg/msgita.c b/harbour/source/rtl/natmsg/msgita.c index 5a2e78664e..4378857394 100644 --- a/harbour/source/rtl/natmsg/msgita.c +++ b/harbour/source/rtl/natmsg/msgita.c @@ -76,7 +76,7 @@ static char *genericErrors[] = char *hb_ErrorNatDescription( ULONG ulGenError ) { - if( ulGenError <= sizeof(genericErrors)/sizeof(char*) ) + if( ulGenError < sizeof(genericErrors)/sizeof(char*) ) return genericErrors[ ulGenError ]; else return genericErrors[ 0 ]; diff --git a/harbour/source/rtl/natmsg/msgkor.c b/harbour/source/rtl/natmsg/msgkor.c index 80971c0ce2..d85f7c7f75 100644 --- a/harbour/source/rtl/natmsg/msgkor.c +++ b/harbour/source/rtl/natmsg/msgkor.c @@ -73,7 +73,7 @@ static char *genericErrors[] = char *hb_ErrorNatDescription( ULONG ulGenError ) { - if( ulGenError <= sizeof(genericErrors)/sizeof(char*) ) + if( ulGenError < sizeof(genericErrors)/sizeof(char*) ) return genericErrors[ ulGenError ]; else return genericErrors[ 0 ]; diff --git a/harbour/source/rtl/natmsg/msgpl852.c b/harbour/source/rtl/natmsg/msgpl852.c index 949392a22c..d7cf969408 100644 --- a/harbour/source/rtl/natmsg/msgpl852.c +++ b/harbour/source/rtl/natmsg/msgpl852.c @@ -74,7 +74,7 @@ static char *genericErrors[] = char *hb_ErrorNatDescription( ULONG ulGenError ) { - if( ulGenError <= sizeof(genericErrors)/sizeof(char*) ) + if( ulGenError < sizeof(genericErrors)/sizeof(char*) ) return genericErrors[ ulGenError ]; else return genericErrors[ 0 ]; diff --git a/harbour/source/rtl/natmsg/msgpliso.c b/harbour/source/rtl/natmsg/msgpliso.c index 1b923d6e4d..3c84f38e66 100644 --- a/harbour/source/rtl/natmsg/msgpliso.c +++ b/harbour/source/rtl/natmsg/msgpliso.c @@ -74,7 +74,7 @@ static char *genericErrors[] = char *hb_ErrorNatDescription( ULONG ulGenError ) { - if( ulGenError <= sizeof(genericErrors)/sizeof(char*) ) + if( ulGenError < sizeof(genericErrors)/sizeof(char*) ) return genericErrors[ ulGenError ]; else return genericErrors[ 0 ]; diff --git a/harbour/source/rtl/natmsg/msgplmaz.c b/harbour/source/rtl/natmsg/msgplmaz.c index b85422b237..3b821005e4 100644 --- a/harbour/source/rtl/natmsg/msgplmaz.c +++ b/harbour/source/rtl/natmsg/msgplmaz.c @@ -74,7 +74,7 @@ static char *genericErrors[] = char *hb_ErrorNatDescription( ULONG ulGenError ) { - if( ulGenError <= sizeof(genericErrors)/sizeof(char*) ) + if( ulGenError < sizeof(genericErrors)/sizeof(char*) ) return genericErrors[ ulGenError ]; else return genericErrors[ 0 ]; diff --git a/harbour/source/rtl/natmsg/msgpor.c b/harbour/source/rtl/natmsg/msgpor.c index 8ed44fcf17..e0ea7bfe98 100644 --- a/harbour/source/rtl/natmsg/msgpor.c +++ b/harbour/source/rtl/natmsg/msgpor.c @@ -71,7 +71,7 @@ static char *genericErrors[] = char *hb_ErrorNatDescription( ULONG ulGenError ) { - if( ulGenError <= sizeof(genericErrors)/sizeof(char*) ) + if( ulGenError < sizeof(genericErrors)/sizeof(char*) ) return genericErrors[ ulGenError ]; else return genericErrors[ 0 ]; diff --git a/harbour/source/rtl/natmsg/msgr1251.c b/harbour/source/rtl/natmsg/msgr1251.c index d1aa68359c..c306bac53a 100644 --- a/harbour/source/rtl/natmsg/msgr1251.c +++ b/harbour/source/rtl/natmsg/msgr1251.c @@ -71,7 +71,7 @@ static char *genericErrors[] = char *hb_ErrorNatDescription( ULONG ulGenError ) { - if( ulGenError <= sizeof(genericErrors)/sizeof(char*) ) + if( ulGenError < sizeof(genericErrors)/sizeof(char*) ) return genericErrors[ ulGenError ]; else return genericErrors[ 0 ]; diff --git a/harbour/source/rtl/natmsg/msgru866.c b/harbour/source/rtl/natmsg/msgru866.c index 6de9ead3c3..33f45af033 100644 --- a/harbour/source/rtl/natmsg/msgru866.c +++ b/harbour/source/rtl/natmsg/msgru866.c @@ -71,7 +71,7 @@ static char *genericErrors[] = char *hb_ErrorNatDescription( ULONG ulGenError ) { - if( ulGenError <= sizeof(genericErrors)/sizeof(char*) ) + if( ulGenError < sizeof(genericErrors)/sizeof(char*) ) return genericErrors[ ulGenError ]; else return genericErrors[ 0 ]; diff --git a/harbour/source/rtl/natmsg/msgspa.c b/harbour/source/rtl/natmsg/msgspa.c index d8b604314a..0ff1dd110b 100644 --- a/harbour/source/rtl/natmsg/msgspa.c +++ b/harbour/source/rtl/natmsg/msgspa.c @@ -71,7 +71,7 @@ static char *genericErrors[] = char *hb_ErrorNatDescription( ULONG ulGenError ) { - if( ulGenError <= sizeof(genericErrors)/sizeof(char*) ) + if( ulGenError < sizeof(genericErrors)/sizeof(char*) ) return genericErrors[ ulGenError ]; else return genericErrors[ 0 ]; diff --git a/harbour/source/rtl/natmsg/msguk.c b/harbour/source/rtl/natmsg/msguk.c index 85b495aadc..cebe8a6351 100644 --- a/harbour/source/rtl/natmsg/msguk.c +++ b/harbour/source/rtl/natmsg/msguk.c @@ -74,7 +74,7 @@ static char *genericErrors[] = char *hb_ErrorNatDescription( ULONG ulGenError ) { - if( ulGenError <= sizeof(genericErrors)/sizeof(char*) ) + if( ulGenError < sizeof(genericErrors)/sizeof(char*) ) return genericErrors[ ulGenError ]; else return genericErrors[ 0 ]; diff --git a/harbour/source/rtl/natmsg/msgyu852.c b/harbour/source/rtl/natmsg/msgyu852.c index 3d9da6632e..7fbc309107 100644 --- a/harbour/source/rtl/natmsg/msgyu852.c +++ b/harbour/source/rtl/natmsg/msgyu852.c @@ -90,7 +90,7 @@ static char *genericErrors[] = char *hb_ErrorNatDescription( ULONG ulGenError ) { - if( ulGenError <= sizeof(genericErrors)/sizeof(char*) ) + if( ulGenError < sizeof(genericErrors)/sizeof(char*) ) return genericErrors[ ulGenError ]; else return genericErrors[ 0 ]; diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index 8cc5e68402..fd5431e1b7 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -135,6 +135,7 @@ typedef struct _SYMBOLS } SYMBOLS, * PSYMBOLS; /* structure to keep track of all modules symbol tables */ void ProcessSymbols( PSYMBOL pSymbols, WORD wSymbols ); /* statics symbols initialization */ +void DoInitStatics( void ); /* executes all _INITSTATICS functions */ void DoInitFunctions( int argc, char * argv[] ); /* executes all defined PRGs INIT functions */ void DoExitFunctions( void ); /* executes all defined PRGs EXIT functions */ void LogSymbols( void ); /* displays all dynamic symbols */ @@ -248,6 +249,11 @@ BYTE bErrorLevel = 0; /* application exit errorlevel */ /* Initialize symbol table with runtime support functions */ InitSymbolTable(); + /* Call functions that initializes static variables + * Static variables have to be initialized before any INIT functions + * because INIT function can use static variables + */ + DoInitStatics(); DoInitFunctions( argc, argv ); /* process defined INIT functions */ #ifdef HARBOUR_START_PROCEDURE @@ -2083,7 +2089,7 @@ void StackInit( void ) void SFrame( PSYMBOL pSym ) /* sets the statics frame for a function */ { /* _INITSTATICS is now the statics frame. Statics() changed it! */ - stack.iStatics = ( int ) pSym->pFunPtr; /* pSym is { "_INITSTATICS", FS_INIT, _INITSTATICS } for each PRG */ + stack.iStatics = ( int ) pSym->pFunPtr; /* pSym is { "$_INITSTATICS", FS_INIT | FS_EXIT, _INITSTATICS } for each PRG */ HB_DEBUG( "SFrame\n" ); } @@ -2176,15 +2182,43 @@ void ReleaseLocalSymbols( void ) } } -void DoExitFunctions( void ) +/* This calls all _INITSTATICS functions defined in the application. + * We are using a special symbol's scope (FS_INIT | FS_EXIT) to mark + * this function. These two bits cannot be marked at the same + * time for normal user defined functions. + */ +void DoInitStatics( void ) { PSYMBOLS pLastSymbols = pSymbols; WORD w; + SYMBOLSCOPE scope; do { for( w = 0; w < pLastSymbols->wModuleSymbols; w++ ) { - if( ( pLastSymbols->pModuleSymbols + w )->cScope & FS_EXIT ) + scope =( pLastSymbols->pModuleSymbols + w )->cScope & (FS_EXIT | FS_INIT); + if( scope == (FS_INIT | FS_EXIT) ) + { + PushSymbol( pLastSymbols->pModuleSymbols + w ); + PushNil(); + Do( 0 ); + } + } + pLastSymbols = pLastSymbols->pNext; + } while( pLastSymbols ); +} + +void DoExitFunctions( void ) +{ + PSYMBOLS pLastSymbols = pSymbols; + WORD w; + SYMBOLSCOPE scope; + + do { + for( w = 0; w < pLastSymbols->wModuleSymbols; w++ ) + { + scope =( pLastSymbols->pModuleSymbols + w )->cScope & (FS_EXIT | FS_INIT); + if( scope == FS_EXIT ) { PushSymbol( pLastSymbols->pModuleSymbols + w ); PushNil(); @@ -2199,11 +2233,13 @@ void DoInitFunctions( int argc, char * argv[] ) { PSYMBOLS pLastSymbols = pSymbols; WORD w; + SYMBOLSCOPE scope; do { for( w = 0; w < pLastSymbols->wModuleSymbols; w++ ) { - if( ( pLastSymbols->pModuleSymbols + w )->cScope & FS_INIT ) + scope =( pLastSymbols->pModuleSymbols + w )->cScope & (FS_EXIT | FS_INIT); + if( scope == FS_INIT ) { int i; diff --git a/harbour/tests/working/initexit.prg b/harbour/tests/working/initexit.prg index 8a8af0b0c9..a5e2ea14f4 100644 --- a/harbour/tests/working/initexit.prg +++ b/harbour/tests/working/initexit.prg @@ -2,34 +2,60 @@ // $Id$ // -// Testing Harbour INIT and EXIT functions +// Testing Harbour INIT and EXIT functions and initialization +// of static variables + +STATIC static_var_accessed_in_INIT_function:=10000.15 +MEMVAR _initStatics function Main() +STATIC static_var:="MAIN()" - QOut( "Hello from Main()" ) + QOut( "Hello from:", static_var ) + static_var_accessed_in_INIT_function++ + Qout( "global static=", static_var_accessed_in_INIT_function ) + + // Use PUBLIC variable created in INIT procedure + Qout( "PUBLIC variable created in INIT procedure=", _initStatics ) return nil init function SecondOne() +STATIC static_var:="SECOND()" - QOut( "Hello from Second()" ) + QOut( "Hello from:", static_var ) + static_var_accessed_in_INIT_function++ + Qout( "global static=", static_var_accessed_in_INIT_function ) return nil init function Third() +STATIC static_var:="THIRD()" - QOut( "Hello from Third()" ) + QOut( "Hello from:", static_var ) + static_var_accessed_in_INIT_function++ + Qout( "global static=", static_var_accessed_in_INIT_function ) return nil exit function Fifth() +STATIC static_var:="FIFTH()" - QOut( "Hello from Fifth()" ) + QOut( "Hello from:", static_var ) + static_var_accessed_in_INIT_function-- + Qout( "global static=", static_var_accessed_in_INIT_function ) return nil exit function Sixth() +STATIC static_var:="SIXTH()" - QOut( "Hello from Sixth()" ) + QOut( "Hello from:", static_var ) + static_var_accessed_in_INIT_function-- + Qout( "global static=", static_var_accessed_in_INIT_function ) return nil + +INIT PROCEDURE _INITSTATICS() +PUBLIC _initStatics:="_INITSTATICS" +RETURN \ No newline at end of file