2007-11-23 03:55 UTC+0200 Mindaugas Kavaliauskas (dbtopas/at/dbtopas.lt)

* harbour/source/include/hbcompdf.h
  * harbour/source/include/hbexprop.h
  * harbour/source/include/hbexprb.c
  * harbour/source/compiler/cmdcheck.c
  * harbour/source/compiler/hbmain.c
    + added i18n support
      Implemented -j[filename] switch to indicate output filename. Default 
      filename is <sourcefilename>.pot. If switch -o is used, this file
      is created in speficied output path.
      Output file format is compatible with 'gettext' utils, but not all
      available features are implemented.
      Harbour level function HB_i18nGettext( cText [, cContext ] ) sould be
      used to indicate translatable strings.
      All this commit is commented using #ifdef HB_I18N_SUPPORT and is in 
      development stage. Please, do not use it yet.
This commit is contained in:
Mindaugas Kavaliauskas
2007-11-23 01:55:37 +00:00
parent ba2612c815
commit ce44121edc
6 changed files with 331 additions and 0 deletions

View File

@@ -8,6 +8,23 @@
2002-12-01 13:30 UTC+0100 Foo Bar <foo.bar@foobar.org>
*/
2007-11-23 03:55 UTC+0200 Mindaugas Kavaliauskas (dbtopas/at/dbtopas.lt)
* harbour/source/include/hbcompdf.h
* harbour/source/include/hbexprop.h
* harbour/source/include/hbexprb.c
* harbour/source/compiler/cmdcheck.c
* harbour/source/compiler/hbmain.c
+ added i18n support
Implemented -j[filename] switch to indicate output filename. Default
filename is <sourcefilename>.pot. If switch -o is used, this file
is created in speficied output path.
Output file format is compatible with 'gettext' utils, but not all
available features are implemented.
Harbour level function HB_i18nGettext( cText [, cContext ] ) sould be
used to indicate translatable strings.
All this commit is commented using #ifdef HB_I18N_SUPPORT and is in
development stage. Please, do not use it yet.
2007-11-23 01:28 UTC+0100 Viktor Szakats (harbour.01 syenar.hu)
+ gtwvg/common.mak
+ gtwvg/make_b32.bat

View File

@@ -551,6 +551,24 @@ typedef struct HB_MACRO_ /* a macro compiled pcode container */
#define HB_COMP_PARAM pComp
#define HB_COMP_DECL HB_COMP_PTR HB_COMP_PARAM
#ifdef HB_I18N_SUPPORT
typedef struct _HB_I18NSTRING
{
char* szText;
char* szContext;
UINT uiLine;
UINT* pLine;
UINT uiLineCount;
} HB_I18NSTRING, * PHB_I18NSTRING;
typedef struct _HB_I18NTABLE
{
PHB_I18NSTRING pString;
ULONG uiCount;
ULONG uiAllocated;
} HB_I18NTABLE, * PHB_I18NTABLE;
#endif
typedef struct _HB_COMP_LEX
{
PHB_PP_STATE pPP;
@@ -604,6 +622,11 @@ typedef struct _HB_COMP
PHB_FNAME pFileName;
PHB_FNAME pOutPath;
PHB_FNAME pPpoPath;
#ifdef HB_I18N_SUPPORT
PHB_FNAME pI18nFileName;
PHB_I18NTABLE pI18n;
BOOL fI18n;
#endif
void ( * outStdFunc ) ( void *, const char* );
void ( * outErrFunc ) ( void *, const char* );

View File

@@ -1643,6 +1643,26 @@ static HB_EXPR_FUNC( hb_compExprUseFunCall )
{
hb_compExprReduceUPPER( pSelf, HB_COMP_PARAM );
}
#ifdef HB_I18N_SUPPORT
#ifndef HB_MACRO_SUPPORT
else if( strcmp( "HB_I18NGETTEXT", pName->value.asSymbol ) == 0 && usCount )
{
HB_EXPR_PTR pArg = pParms->value.asList.pExprList;
// TODO: do we need to add empty string also?
// TODO: add context, line number
if( HB_COMP_PARAM->fI18n && pArg->ExprType == HB_ET_STRING && pArg->ulLength > 0 )
{
if( usCount == 2 && pArg->pNext->ExprType == HB_ET_STRING && pArg->pNext->ulLength > 0 )
hb_compI18nAdd( HB_COMP_PARAM, pArg->value.asString.string,
pArg->pNext->value.asString.string, HB_COMP_PARAM->currLine );
else
hb_compI18nAdd( HB_COMP_PARAM, pArg->value.asString.string, NULL,
HB_COMP_PARAM->currLine );
}
}
#endif
#endif
}
}
break;

View File

@@ -198,6 +198,10 @@ extern BOOL hb_compExprReduceSTOD( HB_EXPR_PTR pSelf, USHORT usCount, HB_COMP_DE
extern BOOL hb_compExprReduceCTOD( HB_EXPR_PTR, HB_COMP_DECL );
extern BOOL hb_compExprReduceUPPER( HB_EXPR_PTR, HB_COMP_DECL );
#ifdef HB_I18N_SUPPORT
extern void hb_compI18nAdd( HB_COMP_DECL, const char* szText, const char* szContext, UINT uiLine );
#endif
HB_EXTERN_END
#endif /* HB_EXPROP_H_ */

View File

@@ -342,6 +342,15 @@ static void hb_compChkEnvironVar( HB_COMP_DECL, char *szSwitch )
hb_pp_addSearchPath( HB_COMP_PARAM->pLex->pPP, s + 1, FALSE );
break;
#ifdef HB_I18N_SUPPORT
case 'j':
case 'J':
HB_COMP_PARAM->fI18n = TRUE;
if( s[ 1 ] )
HB_COMP_PARAM->pI18nFileName = hb_fsFNameSplit( s + 1 );
break;
#endif
case 'k':
case 'K':
{
@@ -754,6 +763,15 @@ void hb_compChkCompilerSwitch( HB_COMP_DECL, int iArg, char *Args[] )
j = strlen( Args[i] );
continue;
#ifdef HB_I18N_SUPPORT
case 'j':
case 'J':
Args[i] += ( j - 1 );
hb_compChkEnvironVar( HB_COMP_PARAM, Args[i] );
j = strlen( Args[i] );
continue;
#endif
case 'k':
case 'K':
Args[i] += ( j - 1 );

View File

@@ -4010,6 +4010,228 @@ void hb_compCodeBlockRewind( HB_COMP_DECL )
}
}
#ifdef HB_I18N_SUPPORT
/* ============================ I18N ============================ */
PHB_I18NTABLE hb_compI18nCreate( void )
{
PHB_I18NTABLE pI18n;
pI18n = ( PHB_I18NTABLE ) hb_xgrab( sizeof( HB_I18NTABLE ) );
pI18n->pString = NULL;
pI18n->uiCount = 0;
pI18n->uiAllocated = 0;
return pI18n;
}
void hb_compI18nFree( PHB_I18NTABLE pI18n )
{
UINT ui;
if( pI18n->pString )
{
for( ui = 0; ui < pI18n->uiCount; ui++ )
{
if( pI18n->pString[ ui ].szText )
hb_xfree( pI18n->pString[ ui ].szText );
if( pI18n->pString[ ui ].szContext )
hb_xfree( pI18n->pString[ ui ].szContext );
if( pI18n->pString[ ui ].pLine )
hb_xfree( pI18n->pString[ ui ].pLine );
}
hb_xfree( pI18n->pString );
}
hb_xfree( pI18n );
}
static int hb_compI18nCompare( PHB_I18NSTRING pString, const char* pText, const char* pContext )
{
int i;
i = strcmp( pString->szText, pText );
if( i == 0 )
{
if( pContext )
{
if( pString->szContext )
return strcmp( pString->szContext, pContext );
else
return -1;
}
else
{
if( pString->szContext )
return 1;
else
return 0;
}
}
return i;
}
void hb_compI18nAdd( HB_COMP_DECL, const char* szText, const char* szContext, UINT uiLine )
{
PHB_I18NTABLE pI18n;
PHB_I18NSTRING pString;
UINT uiLeft, uiRight, uiMiddle;
int iCompare;
pI18n = HB_COMP_PARAM->pI18n;
if( ! pI18n )
return;
if( pI18n->uiCount >= pI18n->uiAllocated )
{
if( pI18n->pString )
{
pI18n->uiAllocated += 32;
pI18n->pString = ( PHB_I18NSTRING ) hb_xrealloc( pI18n->pString, sizeof( HB_I18NSTRING )
* pI18n->uiAllocated );
}
else
{
pI18n->pString = ( PHB_I18NSTRING ) hb_xgrab( sizeof( HB_I18NSTRING ) * 32 );
pI18n->uiAllocated = 32;
}
}
uiLeft = 0;
uiRight = pI18n->uiCount;
while( uiLeft < uiRight )
{
uiMiddle = ( uiLeft + uiRight ) >> 1;
iCompare = hb_compI18nCompare( & pI18n->pString[ uiMiddle ], szText, szContext );
if( iCompare == 0 )
{
pString = & pI18n->pString[ uiMiddle ];
if( pString->pLine )
{
pString->pLine = ( UINT* ) hb_xrealloc( pString->pLine, ( pString->uiLineCount + 1 ) * sizeof( UINT ) );
pString->pLine[ pString->uiLineCount ] = uiLine;
pString->uiLineCount++;
}
else
{
pString->pLine = ( UINT* ) hb_xgrab( sizeof( UINT ) );
pString->pLine[ 0 ] = uiLine;
pString->uiLineCount = 1;
}
return;
}
else if( iCompare < 0 )
uiLeft = uiMiddle + 1;
else
uiRight = uiMiddle;
}
memmove( & pI18n->pString[ uiLeft + 1 ], & pI18n->pString[ uiLeft ], ( pI18n->uiCount - uiLeft ) * sizeof( PHB_I18NSTRING ) );
pString = & pI18n->pString[ uiLeft ];
pString->szText = ( char* ) hb_xgrab( strlen( szText ) + 1 );
strcpy( pString->szText, szText );
if( szContext )
{
pString->szContext = ( char* ) hb_xgrab( strlen( szContext ) + 1 );
strcpy( pString->szContext, szContext );
}
else
pString->szContext = NULL;
pString->uiLine = uiLine;
pString->pLine = NULL;
pString->uiLineCount = 0;
pI18n->uiCount++;
}
BOOL hb_compI18nSave( HB_COMP_DECL )
{
PHB_I18NTABLE pI18n;
PHB_I18NSTRING pString;
HB_FNAME pFileName;
char szFileName[ _POSIX_PATH_MAX + 1 ];
char* szText;
UINT uiIndex, uiLine;
FILE* file;
pI18n = HB_COMP_PARAM->pI18n;
pFileName.szPath = pFileName.szName = pFileName.szExtension = pFileName.szDrive = NULL;
if( HB_COMP_PARAM->pOutPath )
{
pFileName.szDrive = HB_COMP_PARAM->pOutPath->szDrive;
pFileName.szPath = HB_COMP_PARAM->pOutPath->szPath;
}
if( HB_COMP_PARAM->pI18nFileName )
{
if( HB_COMP_PARAM->pI18nFileName->szName )
pFileName.szName = HB_COMP_PARAM->pI18nFileName->szName;
if( HB_COMP_PARAM->pI18nFileName->szExtension )
pFileName.szExtension = HB_COMP_PARAM->pI18nFileName->szExtension;
if( HB_COMP_PARAM->pI18nFileName->szPath )
{
pFileName.szDrive = HB_COMP_PARAM->pI18nFileName->szDrive;
pFileName.szPath = HB_COMP_PARAM->pI18nFileName->szPath;
}
}
if( ! pFileName.szName )
pFileName.szName = HB_COMP_PARAM->pFileName->szName;
if( ! pFileName.szExtension )
pFileName.szExtension = ".pot";
hb_fsFNameMerge( szFileName, & pFileName );
file = hb_fopen( szFileName, "wb" );
if( ! file )
{
/* TODO: do we need to interupt compilation ? */
hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_CREATE_OUTPUT, szFileName, NULL );
return FALSE;
}
szText = hb_verHarbour();
fprintf( file, "#\n# This file is generated by: %s\n#\n\n", szText );
hb_xfree( szText );
strcpy( szFileName, HB_COMP_PARAM->pFileName->szName );
for( uiIndex = 0; uiIndex < pI18n->uiCount; uiIndex++ )
{
pString = & pI18n->pString[ uiIndex ];
fprintf( file, "#: %s:%d", szFileName, pString->uiLine );
for( uiLine = 0; uiLine < pString->uiLineCount; uiLine++ )
fprintf( file, " %s:%d", szFileName, pString->pLine[ uiLine ] );
fprintf( file, "\n#, c-format\n" );
if( pString->szContext )
fprintf( file, "msgctxt \"%s\"\n", pString->szContext );
fprintf( file, "msgid \"%s\"\nmsgstr \"\"\n\n", pString->szText );
}
fclose( file );
return TRUE;
}
#endif
/* ************************************************************************* */
@@ -4133,6 +4355,20 @@ void hb_compCompileEnd( HB_COMP_DECL )
hb_compSwitchKill( HB_COMP_PARAM );
hb_compElseIfKill( HB_COMP_PARAM );
#ifdef HB_I18N_SUPPORT
if( HB_COMP_PARAM->pI18n )
{
hb_compI18nFree( HB_COMP_PARAM->pI18n );
HB_COMP_PARAM->pI18n = NULL;
}
if( HB_COMP_PARAM->pI18nFileName )
{
hb_xfree( HB_COMP_PARAM->pI18nFileName );
HB_COMP_PARAM->pI18nFileName = NULL;
}
#endif
if( HB_COMP_PARAM->pMainFileName )
{
if( HB_COMP_PARAM->pFileName != HB_COMP_PARAM->pMainFileName )
@@ -4318,6 +4554,13 @@ static int hb_compCompile( HB_COMP_DECL, const char * szPrg, int iFileType )
hb_compOutStd( HB_COMP_PARAM, buffer );
}
#ifdef HB_I18N_SUPPORT
if( HB_COMP_PARAM->fI18n )
{
HB_COMP_PARAM->pI18n = hb_compI18nCreate();
}
#endif
/* Generate the starting procedure frame */
if( HB_COMP_PARAM->fStartProc )
{
@@ -4500,6 +4743,12 @@ static int hb_compCompile( HB_COMP_DECL, const char * szPrg, int iFileType )
}
hb_compGenOutput( HB_COMP_PARAM, HB_COMP_PARAM->iLanguage );
#ifdef HB_I18N_SUPPORT
if( HB_COMP_PARAM->pI18n )
{
hb_compI18nSave( HB_COMP_PARAM );
}
#endif
}
}
}