diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 7ebd4aebd2..89060d9416 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,15 @@ 2009-12-31 13:59 UTC+0100 Foo Bar (foo.bar foobar.org) */ +2009-03-23 02:17 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/source/pp/ppcore.c + * harbour/source/common/hbdate.c + * harbour/source/macro/macrolex.c + * harbour/source/compiler/complex.c + + added alternative support for date constant values as: d"YYYY-MM-DD" + As delimiter the following characters can be used: "-", "/", "." + Just like in t"..." + 2009-03-22 22:50 UTC+0100 Francesco Saverio Giudice (info/at/fsgiudice.com) * harbour/contrib/hbwin/win_ole.c * removed debug lines diff --git a/harbour/source/common/hbdate.c b/harbour/source/common/hbdate.c index 8df1fec19e..be625e697c 100644 --- a/harbour/source/common/hbdate.c +++ b/harbour/source/common/hbdate.c @@ -715,7 +715,8 @@ BOOL hb_timeStampStrGet( const char * szDateTime, ( int ) ( szDateTime[ 3 ] - '0' ); iMonth = ( szDateTime[ 5 ] - '0' ) * 10 + ( szDateTime[ 6 ] - '0' ); iDay = ( szDateTime[ 8 ] - '0' ) * 10 + ( szDateTime[ 9 ] - '0' ); - if( hb_dateEncode( iYear, iMonth, iDay ) != 0 ) + if( hb_dateEncode( iYear, iMonth, iDay ) != 0 || + ( iYear == 0 && iMonth == 0 && iDay == 0 ) ) { szDateTime += 10; if( *szDateTime == 'T' || *szDateTime == 't' ) @@ -742,13 +743,18 @@ BOOL hb_timeStampStrGet( const char * szDateTime, } } - if( !hb_timeStrGet( szDateTime, piHour, piMinutes, piSeconds, piMSec ) ) + if( piHour || piMinutes || piSeconds || piMSec ) { - if( szDateTime ) - fValid = FALSE; + if( !hb_timeStrGet( szDateTime, piHour, piMinutes, piSeconds, piMSec ) ) + { + if( szDateTime ) + fValid = FALSE; + } + else + fValid = TRUE; } - else - fValid = TRUE; + else if( szDateTime ) + fValid = FALSE; if( piYear ) *piYear = iYear; diff --git a/harbour/source/compiler/complex.c b/harbour/source/compiler/complex.c index 9c6975d3f9..5a3ce3959c 100644 --- a/harbour/source/compiler/complex.c +++ b/harbour/source/compiler/complex.c @@ -493,24 +493,34 @@ int hb_complex( YYSTYPE *yylval_ptr, HB_COMP_DECL ) } } case HB_PP_TOKEN_DATE: - pLex->iState = LITERAL; - if( pToken->len == 10 ) - { - int year, month, day; - hb_dateStrGet( pToken->value + 2, &year, &month, &day ); - yylval_ptr->valLong.lNumber = hb_dateEncode( year, month, day ); - } - else - yylval_ptr->valLong.lNumber = 0; + { + int iYear, iMonth, iDay; + pLex->iState = LITERAL; + if( pToken->value[ 0 ] == '0' && + ( pToken->value[ 1 ] == 'D' || pToken->value[ 1 ] == 'd' ) ) + { + if( pToken->len == 10 ) + { + hb_dateStrGet( pToken->value + 2, &iYear, &iMonth, &iDay ); + } + else + { + iYear = iMonth = iDay = 0; + if( !pToken->len == 3 || pToken->value[ 2 ] != '0' ) + iYear = -1; + } + } + else if( !hb_timeStampStrGet( pToken->value, &iYear, &iMonth, &iDay, NULL, NULL, NULL, NULL ) ) + iYear = -1; + yylval_ptr->valLong.lNumber = hb_dateEncode( iYear, iMonth, iDay ); if( yylval_ptr->valLong.lNumber == 0 && - strcmp( pToken->value + 2, "0" ) != 0 && - strcmp( pToken->value + 2, "00000000" ) != 0 ) + ( iYear != 0 || iMonth != 0 || iDay != 0 ) ) { hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_INVALID_DATE, pToken->value, NULL ); } return NUM_DATE; - + } case HB_PP_TOKEN_TIMESTAMP: pLex->iState = LITERAL; if( !hb_timeStampStrGetDT( pToken->value, diff --git a/harbour/source/macro/macrolex.c b/harbour/source/macro/macrolex.c index f37335573c..7aca133353 100644 --- a/harbour/source/macro/macrolex.c +++ b/harbour/source/macro/macrolex.c @@ -135,8 +135,8 @@ static void hb_lexIdentCopy( PHB_MACRO_LEX pLex ) } } -static int hb_lexTimestampCopy( YYSTYPE *yylval_ptr, HB_MACRO_PTR pMacro, - PHB_MACRO_LEX pLex ) +static int hb_lexTimestampGet( YYSTYPE *yylval_ptr, HB_MACRO_PTR pMacro, + PHB_MACRO_LEX pLex ) { BOOL fOK = FALSE; char * dst = pLex->pDst; @@ -162,6 +162,38 @@ static int hb_lexTimestampCopy( YYSTYPE *yylval_ptr, HB_MACRO_PTR pMacro, return TIMESTAMP; } +static int hb_lexDateGet( YYSTYPE *yylval_ptr, HB_MACRO_PTR pMacro, + PHB_MACRO_LEX pLex ) +{ + BOOL fOK = FALSE; + char * dst = pLex->pDst; + int iYear, iMonth, iDay; + + pLex->quote = FALSE; + while( pLex->ulSrc < pLex->ulLen ) + { + char ch = pLex->pString[ pLex->ulSrc++ ]; + if( ch == '"' ) + { + fOK = TRUE; + break; + } + *dst++ = ch; + } + *dst = '\0'; + if( fOK && hb_timeStampStrGet( pLex->pDst, &iYear, &iMonth, &iDay, NULL, NULL, NULL, NULL ) ) + { + yylval_ptr->valLong.lNumber = hb_dateEncode( iYear, iMonth, iDay ); + } + else + { + yylval_ptr->valLong.lNumber = 0; + hb_macroError( EG_SYNTAX, pMacro ); + } + + return NUM_DATE; +} + static int hb_lexStringCopy( YYSTYPE *yylval_ptr, HB_MACRO_PTR pMacro, PHB_MACRO_LEX pLex, char cDelim ) { @@ -564,6 +596,17 @@ int hb_macrolex( YYSTYPE *yylval_ptr, HB_MACRO_PTR pMacro ) yylval_ptr->valLong.lNumber = hb_dateEncode( year, month, day ); pLex->ulSrc = ul; + if( yylval_ptr->valLong.lNumber == 0 && + ( year != 0 || month != 0 || day != 0 ) ) + { + hb_macroError( EG_SYNTAX, pMacro ); + } + return NUM_DATE; + } + else if( ul - pLex->ulSrc == 2 && + pLex->pString[ pLex->ulSrc + 1 ] == '0' ) + { + yylval_ptr->valLong.lNumber = 0; return NUM_DATE; } ul = pLex->ulSrc; @@ -638,19 +681,21 @@ int hb_macrolex( YYSTYPE *yylval_ptr, HB_MACRO_PTR pMacro ) *pLex->pDst++ = '\0'; if( ulLen == 1 ) { - if( yylval_ptr->string[ 0 ] == 'E' && - pLex->ulLen > pLex->ulSrc && + if( pLex->ulLen > pLex->ulSrc && pLex->pString[ pLex->ulSrc ] == '"' ) { - pLex->ulSrc++; - return hb_lexStringExtCopy( yylval_ptr, pMacro, pLex ); - } - else if( yylval_ptr->string[ 0 ] == 'T' && - pLex->ulLen > pLex->ulSrc && - pLex->pString[ pLex->ulSrc ] == '"' ) - { - pLex->ulSrc++; - return hb_lexTimestampCopy( yylval_ptr, pMacro, pLex ); + switch( yylval_ptr->string[ 0 ] ) + { + case 'E': + pLex->ulSrc++; + return hb_lexStringExtCopy( yylval_ptr, pMacro, pLex ); + case 'T': + pLex->ulSrc++; + return hb_lexTimestampGet( yylval_ptr, pMacro, pLex ); + case 'D': + pLex->ulSrc++; + return hb_lexDateGet( yylval_ptr, pMacro, pLex ); + } } } else if( ulLen == 2 ) diff --git a/harbour/source/pp/ppcore.c b/harbour/source/pp/ppcore.c index ed3aff2dda..5bdcd8519a 100644 --- a/harbour/source/pp/ppcore.c +++ b/harbour/source/pp/ppcore.c @@ -1155,6 +1155,22 @@ static void hb_pp_getLine( PHB_PP_STATE pState ) else ++ul; } + else if( ( ch == 'd' || ch == 'D' ) && ulLen > 1 && pBuffer[ 1 ] == '"' ) + { + ++ul; + while( ++ul < ulLen && pBuffer[ ul ] != '"' ) {}; + hb_pp_tokenAddNext( pState, pBuffer + 2, ul - 2, + HB_PP_TOKEN_DATE ); + if( ul == ulLen ) + { + ULONG ulSkip = pBuffer - hb_membufPtr( pState->pBuffer ) + 1; + hb_membufAddCh( pState->pBuffer, '\0' ); + pBuffer = hb_membufPtr( pState->pBuffer ) + ulSkip; + hb_pp_error( pState, 'E', HB_PP_ERR_STRING_TERMINATOR, pBuffer ); + } + else + ++ul; + } #endif else if( ch == '"' || ch == '\'' || ch == '`' ) { @@ -1575,9 +1591,31 @@ static int hb_pp_tokenStr( PHB_PP_TOKEN pToken, PHB_MEM_BUFFER pBuffer, } else if( HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_TIMESTAMP ) { - hb_membufAddStr( pBuffer, "t\"" ); - hb_membufAddData( pBuffer, pToken->value, pToken->len ); - hb_membufAddCh( pBuffer, '"' ); + if( pToken->len >= 2 && pToken->value[ 0 ] == '0' && + ( pToken->value[ 1 ] == 'T' || pToken->value[ 1 ] == 't' ) ) + { + hb_membufAddData( pBuffer, pToken->value, pToken->len ); + } + else + { + hb_membufAddStr( pBuffer, "t\"" ); + hb_membufAddData( pBuffer, pToken->value, pToken->len ); + hb_membufAddCh( pBuffer, '"' ); + } + } + else if( HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_DATE ) + { + if( pToken->len >= 2 && pToken->value[ 0 ] == '0' && + ( pToken->value[ 1 ] == 'D' || pToken->value[ 1 ] == 'd' ) ) + { + hb_membufAddData( pBuffer, pToken->value, pToken->len ); + } + else + { + hb_membufAddStr( pBuffer, "t\"" ); + hb_membufAddData( pBuffer, pToken->value, pToken->len ); + hb_membufAddCh( pBuffer, '"' ); + } } else {