From 33a764f9a52cc020885f464d6fd0b09d5d2169a2 Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Fri, 15 Oct 1999 00:22:00 +0000 Subject: [PATCH] 19991015-02:04 GMT+1 --- harbour/ChangeLog | 8 + harbour/source/compiler/genjava.c | 400 +++++++++++++++++++++++++++++- harbour/source/rtl/dates.c | 4 +- harbour/source/rtl/filesys.c | 4 + 4 files changed, 410 insertions(+), 6 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 7f0988a1cd..b7c251bec0 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,11 @@ +19991015-02:04 GMT+1 Victor Szel + * source/compiler/genjava.c + + Java source generation added to the compiler (by Matteo Baccan) + * source/rtl/filesys.c + + TOFIX: added to hb_fsIsDrv() (by Jose Lalin) + * source/rtl/dates.c + ! Some pp directives indented. + Thu Oct 14 17:29:32 1999 Gonzalo A. Diethelm * source/rtl/dates.c: diff --git a/harbour/source/compiler/genjava.c b/harbour/source/compiler/genjava.c index b45ac0503d..0be536cf96 100644 --- a/harbour/source/compiler/genjava.c +++ b/harbour/source/compiler/genjava.c @@ -6,7 +6,8 @@ * Harbour Project source code: * Compiler Java source generation * - * Copyright 1999 {list of individual authors and e-mail addresses} + * Copyright 1999 Matteo Baccan + * Based on a work of Eddie Runia * www - http://www.harbour-project.org * * This program is free software; you can redistribute it and/or modify @@ -37,17 +38,408 @@ #include "compiler.h" #include "pcode.h" #include "hberrors.h" +#include "hbver.h" + +#define SYM_NOLINK 0 /* Symbol does not have to be linked */ +#define SYM_FUNC 1 /* Defined function */ +#define SYM_EXTERN 2 /* Previously defined function */ + +static void hb_fputc( BYTE b, FILE * yyc ); +static void hb_fputs( char * szName, FILE * yyc ); + +static int _nChar = 0; void GenJava( PHB_FNAME pFileName ) { char szFileName[ _POSIX_PATH_MAX ]; + PFUNCTION pFunc /*= functions.pFirst */; + PCOMSYMBOL pSym = symbols.pFirst; + USHORT w, wLen, wVar; + LONG lPCodePos; + LONG lPad; + LONG lSymbols; + BOOL bEndProcReq; + ULONG ulCodeLength; + FILE * yyc; /* file handle for C output */ if( ! pFileName->szExtension ) pFileName->szExtension =".java"; hb_fsFNameMerge( szFileName, pFileName ); - printf( "\nGenerating Java source output to \'%s\'... ", szFileName ); - fflush( stdout ); + yyc = fopen( szFileName, "wb" ); + if( ! yyc ) + { + GenError( _szCErrors, 'E', ERR_CREATE_OUTPUT, szFileName, NULL ); + return; + } - printf( "\nNot implemented yet!\n" ); + if( ! _bQuiet ) + { + printf( "\nGenerating Java source output to \'%s\'... ", szFileName ); + fflush( stdout ); + } + + _nChar = 0; + + fprintf( yyc, "/*\n * Harbour Compiler, Build %i%s (%04d.%02d.%02d)\n", + hb_build, hb_revision, hb_year, hb_month, hb_day ); + fprintf( yyc, " * Generated JAVA source code\n */\n\n" ); + + fprintf( yyc, "public class %s\n", pFileName->szName ); + fprintf( yyc, "{\n" ); + fprintf( yyc, " public static int[] pCode =\n" ); + fprintf( yyc, " {\n" ); + fprintf( yyc, " " ); + + /* writes the symbol table */ + + if( ! _bStartProc ) + pSym = pSym->pNext; /* starting procedure is always the first symbol */ + + lSymbols = 0; /* Count number of symbols */ + while( pSym ) + { + lSymbols++; + pSym = pSym->pNext; + } + hb_fputc( ( BYTE ) ( ( lSymbols ) & 255 ), yyc ); /* Write number symbols */ + hb_fputc( ( BYTE ) ( ( lSymbols >> 8 ) & 255 ), yyc ); + hb_fputc( ( BYTE ) ( ( lSymbols >> 16 ) & 255 ), yyc ); + hb_fputc( ( BYTE ) ( ( lSymbols >> 24 ) & 255 ), yyc ); + + pSym = symbols.pFirst; + if( ! _bStartProc ) + pSym = pSym->pNext; /* starting procedure is always the first symbol */ + + while( pSym ) + { + hb_fputs( pSym->szName, yyc ); + hb_fputc( 0, yyc ); + if( pSym->cScope != FS_MESSAGE ) + hb_fputc( pSym->cScope, yyc ); + else + hb_fputc( 0, yyc ); + + /* specify the function address if it is a defined function or a + external called function */ + if( GetFunction( pSym->szName ) ) /* is it a defined function ? */ + { + hb_fputc( SYM_FUNC, yyc ); + } + else + { + if( GetFuncall( pSym->szName ) ) + { + hb_fputc( SYM_EXTERN, yyc ); + } + else + { + hb_fputc( SYM_NOLINK, yyc ); + } + } + pSym = pSym->pNext; + } + + pFunc = functions.pFirst; + if( ! _bStartProc ) + pFunc = pFunc->pNext; + + lSymbols = 0; /* Count number of symbols */ + while( pFunc ) + { + lSymbols++; + pFunc = pFunc->pNext; + } + hb_fputc( ( BYTE ) ( ( lSymbols ) & 255 ), yyc ); /* Write number symbols */ + hb_fputc( ( BYTE ) ( ( lSymbols >> 8 ) & 255 ), yyc ); + hb_fputc( ( BYTE ) ( ( lSymbols >> 16 ) & 255 ), yyc ); + hb_fputc( ( BYTE ) ( ( lSymbols >> 24 ) & 255 ), yyc ); + + /* Generate functions data + */ + pFunc = functions.pFirst; + if( ! _bStartProc ) + pFunc = pFunc->pNext; /* No implicit starting procedure */ + + while( pFunc ) + { + hb_fputs( pFunc->szName, yyc ); + hb_fputc( 0, yyc ); + /* We will have to add HB_P_ENDPROC in cases when RETURN statement + * was not used in a function/procedure - this is why we have to reserve + * one additional byte + */ + ulCodeLength = pFunc->lPCodePos + 1; + hb_fputc( ( BYTE ) ( ( ulCodeLength ) & 255 ), yyc ); /* Write size */ + hb_fputc( ( BYTE ) ( ( ulCodeLength >> 8 ) & 255 ), yyc ); + hb_fputc( ( BYTE ) ( ( ulCodeLength >> 16 ) & 255 ), yyc ); + hb_fputc( ( BYTE ) ( ( ulCodeLength >> 24 ) & 255 ), yyc ); + +/* printf( "Creating output for %s\n", pFunc->szName ); */ + + lPCodePos = 0; + lPad = 0; /* Number of bytes optimized */ + bEndProcReq = TRUE; + while( lPCodePos < pFunc->lPCodePos ) + { + switch( pFunc->pCode[ lPCodePos ] ) + { + case HB_P_AND: + case HB_P_ARRAYAT: + case HB_P_ARRAYPUT: + case HB_P_DEC: + case HB_P_DIVIDE: + case HB_P_DUPLICATE: + case HB_P_DUPLTWO: + case HB_P_ENDBLOCK: + case HB_P_EQUAL: + case HB_P_EXACTLYEQUAL: + case HB_P_FALSE: + case HB_P_FORTEST: + case HB_P_FUNCPTR: + case HB_P_GREATER: + case HB_P_GREATEREQUAL: + case HB_P_INC: + case HB_P_INSTRING: + case HB_P_LESS: + case HB_P_LESSEQUAL: + case HB_P_MINUS: + case HB_P_MODULUS: + case HB_P_MULT: + case HB_P_NEGATE: + case HB_P_NOT: + case HB_P_NOTEQUAL: + case HB_P_OR: + case HB_P_PLUS: + case HB_P_POP: + case HB_P_POPALIAS: + case HB_P_POWER: + case HB_P_PUSHALIAS: + case HB_P_PUSHNIL: + case HB_P_PUSHSELF: + case HB_P_RETVALUE: + case HB_P_SWAPALIAS: + case HB_P_SEQRECOVER: + case HB_P_TRUE: + case HB_P_ZERO: + hb_fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + break; + + case HB_P_ARRAYDIM: + case HB_P_DO: + case HB_P_FUNCTION: + case HB_P_ARRAYGEN: + case HB_P_JUMP: + case HB_P_JUMPFALSE: + case HB_P_JUMPTRUE: + case HB_P_LINE: + case HB_P_POPLOCAL: + case HB_P_POPSTATIC: + case HB_P_PUSHINT: + case HB_P_PUSHLOCAL: + case HB_P_PUSHLOCALREF: + case HB_P_PUSHSTATIC: + case HB_P_PUSHSTATICREF: + case HB_P_SEQBEGIN: + case HB_P_SEQEND: + hb_fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + hb_fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + hb_fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + break; + + case HB_P_ENDPROC: + hb_fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + if( lPCodePos == pFunc->lPCodePos ) + bEndProcReq = FALSE; + break; + + case HB_P_FRAME: + /* update the number of local variables */ + { + PVAR pLocal = pFunc->pLocals; + BYTE bLocals = 0; + + while( pLocal ) + { + pLocal = pLocal->pNext; + bLocals++; + } + + if( bLocals || pFunc->wParamCount ) + { + hb_fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + hb_fputc( ( BYTE )( bLocals - pFunc->wParamCount ), yyc ); + hb_fputc( ( BYTE )( pFunc->wParamCount ), yyc ); + lPCodePos += 2; + } + else + { + lPad += 3; + lPCodePos += 3; + } + } + break; + + case HB_P_PUSHSYM: + case HB_P_MESSAGE: + case HB_P_POPMEMVAR: + case HB_P_PUSHMEMVAR: + case HB_P_PUSHMEMVARREF: + case HB_P_POPVARIABLE: + case HB_P_PUSHVARIABLE: + case HB_P_POPFIELD: + case HB_P_PUSHFIELD: + case HB_P_POPALIASEDFIELD: + case HB_P_PUSHALIASEDFIELD: + hb_fputc( pFunc->pCode[ lPCodePos ], yyc ); + wVar = FixSymbolPos( pFunc->pCode[ lPCodePos + 1 ] + 256 * pFunc->pCode[ lPCodePos + 2 ] ); + hb_fputc( LOBYTE( wVar ), yyc ); + hb_fputc( HIBYTE( wVar ), yyc ); + lPCodePos += 3; + break; + + case HB_P_PARAMETER: + hb_fputc( pFunc->pCode[ lPCodePos ], yyc ); + wVar = FixSymbolPos( pFunc->pCode[ lPCodePos + 1 ] + 256 * pFunc->pCode[ lPCodePos + 2 ] ); + hb_fputc( LOBYTE( wVar ), yyc ); + hb_fputc( HIBYTE( wVar ), yyc ); + hb_fputc( pFunc->pCode[ lPCodePos + 3 ], yyc ); + lPCodePos +=4; + break; + + case HB_P_PUSHBLOCK: + wVar = * ( ( USHORT * ) &( pFunc->pCode [ lPCodePos + 5 ] ) ); + hb_fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + hb_fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + hb_fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + hb_fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + hb_fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + hb_fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + hb_fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + /* create the table of referenced local variables */ + while( wVar-- ) + { + hb_fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + hb_fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + } + break; + + case HB_P_PUSHDOUBLE: + { + int i; + hb_fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + for( i = 0; i < sizeof( double ); ++i ) + hb_fputc( ( ( BYTE * ) pFunc->pCode )[ lPCodePos + i ], yyc ); + hb_fputc( pFunc->pCode[ lPCodePos + sizeof( double ) ], yyc ); + lPCodePos += sizeof( double ) + 1; + } + break; + + case HB_P_PUSHLONG: + hb_fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + hb_fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + hb_fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + hb_fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + hb_fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + break; + + case HB_P_PUSHSTR: + wLen = pFunc->pCode[ lPCodePos + 1 ] + + pFunc->pCode[ lPCodePos + 2 ] * 256; + hb_fputc( pFunc->pCode[ lPCodePos ], yyc ); + hb_fputc( pFunc->pCode[ lPCodePos + 1 ], yyc ); + hb_fputc( pFunc->pCode[ lPCodePos + 2 ], yyc ); + lPCodePos += 3; + while( wLen-- ) + hb_fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + break; + + case HB_P_SFRAME: + /* we only generate it if there are statics used in this function */ + if( pFunc->bFlags & FUN_USES_STATICS ) + { + GetSymbol( _pInitFunc->szName, &w ); + w = FixSymbolPos( w ); + hb_fputc( pFunc->pCode[ lPCodePos ], yyc ); + hb_fputc( LOBYTE( w ), yyc ); + hb_fputc( HIBYTE( w ), yyc ); + } + else + lPad += 3; + lPCodePos += 3; + break; + + case HB_P_STATICS: + GetSymbol( _pInitFunc->szName, &w ); + w = FixSymbolPos( w ); + hb_fputc( pFunc->pCode[ lPCodePos ], yyc ); + hb_fputc( LOBYTE( w ), yyc ); + hb_fputc( HIBYTE( w ), yyc ); + hb_fputc( pFunc->pCode[ lPCodePos + 3 ], yyc ); + hb_fputc( pFunc->pCode[ lPCodePos + 4 ], yyc ); + lPCodePos += 5; + break; + + default: + printf( "Incorrect pcode value: %u\n", pFunc->pCode[ lPCodePos ] ); + lPCodePos = pFunc->lPCodePos; + break; + } + } + + if( bEndProcReq ) + hb_fputc( HB_P_ENDPROC, yyc ); + else + { + /* HB_P_ENDPROC was the last opcode: we have to fill the byte + * reserved earlier + */ + lPad++; + } + for( ; lPad; lPad-- ) + { + /* write additional bytes to agree with stored earlier + * function/procedure size + */ + hb_fputc( 0, yyc ); + } + pFunc = pFunc->pNext; + } + + fprintf( yyc, "\n };\n\n" ); + fprintf( yyc, " static public void main( String argv[] )\n" ); + fprintf( yyc, " {\n" ); + fprintf( yyc, " Harbour.Run( %s.pCode ); \n", pFileName->szName ); + fprintf( yyc, " }\n\n" ); + fprintf( yyc, "}\n" ); + + fclose( yyc ); + + if( ! _bQuiet ) + printf( "Done.\n" ); +} + +static void hb_fputc( BYTE b, FILE * yyc ) +{ + int x = b; + + _nChar++; + + if( _nChar > 1 ) + fprintf( yyc, ", " ); + + if( _nChar == 9 ) + { + fprintf( yyc, "\n " ); + _nChar = 1; + } + + fprintf( yyc, "0x%02X", x ); +} + +static void hb_fputs( char * szName, FILE * yyc ) +{ + int nPos = 0; + while( nPos < strlen( szName ) ) + hb_fputc( szName[ nPos++ ], yyc ); } diff --git a/harbour/source/rtl/dates.c b/harbour/source/rtl/dates.c index 51209ae6fd..be68b46aa9 100644 --- a/harbour/source/rtl/dates.c +++ b/harbour/source/rtl/dates.c @@ -82,9 +82,9 @@ #include #include #if defined( OS_UNIX_COMPATIBLE ) -#include + #include #else -#include + #include #endif #if defined(__TURBOC__) || defined(__BORLANDC__) || defined(__DJGPP__) #include diff --git a/harbour/source/rtl/filesys.c b/harbour/source/rtl/filesys.c index 0ad2b00f6e..a7fa7acbe1 100644 --- a/harbour/source/rtl/filesys.c +++ b/harbour/source/rtl/filesys.c @@ -991,6 +991,10 @@ USHORT hb_fsChDrv( BYTE nDrive ) /* NOTE: 0=A:, 1=B:, 2=C:, 3=D:, ... */ /* TODO: add documentation */ +/* TOFIX: This isn't fully compliant because Cl*pper doesn't access + the drive before checking. hb_fsIsDrv only returns TRUE + if there is a disk in the drive. */ + USHORT hb_fsIsDrv( BYTE nDrive ) { USHORT uiResult;