19991129-22:22 GMT+1 Victor Szel <info@szelvesz.hu>

This commit is contained in:
Viktor Szakats
1999-11-29 22:10:47 +00:00
parent 73ceeb64be
commit 20a998205f
15 changed files with 488 additions and 23 deletions

View File

@@ -1,3 +1,33 @@
19991129-22:22 GMT+1 Victor Szel <info@szelvesz.hu>
* source/compiler/harbour.c
include/compiler.h
* HB_EXITLEVEL_* constants moved to the central header file.
* source/rtl/alert.prg
source/rtl/asort.prg
! Minor fixes.
* include/hbdefs.h
! HB_HANDLE - LONG -> ULONG, to suppress Borland warning in memvars.c
* source/rtl/memvars.c
! cast added to suppress Borland warning.
* source/pp/stdalone/hbpp.c
source/pp/hbpplib.c
+ Dummy compiler flag variables added for #pragma support.
* source/rtl/trace.c
- Copyright removed.
19991129-22:22 GMT+1 Jose Lalin <dezac@corevia.com>
* source/pp/hbpp.c
+ Added support for #pragma directives
Now we can include compiler settings inside PRG's
* include/hberrors.h
+ Added new #define ERR_PRAGMA_BAD_VALUE
+ tests/tstprag.prg
tests/Makefile
+ New test for pragma directives
+ doc/pragma.txt
+ a bit of info on Harbour pragmas implementation
(Uploaded by Victor Szel)
Mon Nov 29 12:45:05 1999 Gonzalo A. Diethelm <Gonzalo.Diethelm@jda.cl>
* include/hbtrace.h:

79
harbour/doc/pragma.txt Normal file
View File

@@ -0,0 +1,79 @@
#
# $Id:
#
INTRODUCTION
============
This file explains what is and how to use #pragma directive in Harbour.
PRAGMA
======
The #pragma is a directive used in many compilers to change at compile
time some flags inside the compiler itself.
USAGE
=====
Currently the #pragma directive can be used in two ways: switch mode and
command mode.
The syntax is: #pragma <Expression>[=On/Off] or
#pragma -CompilerFlag[+|-]
Remember thar you can use both modes mixed in the same module and
upper/lower case without worry.
To enable/disable a command you simply do: <CommandName>=On/Off and
for switches you do: /<SwitchName>+/-
Example: #pragma AddDebugInfo=Off /* Suppress debug info */
#pragma /B+ /* Add debug info from here */
IMPLEMENTATION
==============
This is the list of the supported commands and switchs:
* Command Switch
-----------------------------------------------
* AUTOMEMVARS =<On/Off> /A<+/->
* DEBUGINFO =<On/Off> /B<+/->
* ENABLEWARNINGS =<On/Off> /W<+/->
* EXITSEVERITY =<nLevel> /E<nLevel>
* FORCEMEMVARS =<On/Off> /V<+/->
* LINEINFO =<On/Off> /L<+/->
* NOSTARTPROC =<On/Off> /N<+/->
* PREPROCESSING =<On/Off> /P<+/->
* WARNINGLEVEL =<nLevel> /W<nLevel>
* SHORTCUTTING =<On/Off> /Z<+/->
The switchs have the same behaviour as the corresponding compiler ones
and the commands are sinonyms for the switchs.
* TRACEPRAGMAS
This command shows pragma activity when enabled.
NOTE: you can use the abbreviated commands mode by typing only the
first ten chars.
NOTES
=====
This directive is not supported in the standalone version of the Harbour
preprocessor.
EXAMPLES
========
#pragma NoStartProc=Off
/* #pragma /N- */
function Test()
return nil
This is the same as calling Harbour with the -n switch in the command line,
but with the great benefit that if you forgot to pass the switch if will be
used anyway because it is included inside the source.
=======
Regards,
Jose Lalin <dezac@corevia.com>

View File

@@ -325,6 +325,11 @@ extern USHORT hb_comp_wCaseCounter;
extern char * hb_comp_szErrors[];
extern char * hb_comp_szWarnings[];
/* /ES command line setting types */
#define HB_EXITLEVEL_DEFAULT 0
#define HB_EXITLEVEL_SETEXIT 1
#define HB_EXITLEVEL_DELTARGET 2
HB_EXPR_PTR hb_compExprNewEmpty( void );
HB_EXPR_PTR hb_compExprNewNil( void );

View File

@@ -134,8 +134,8 @@ typedef BYTE HB_ATTR;
typedef HARBOUR ( * PHB_FUNC )( void );
typedef PHB_FUNC HB_FUNC_PTR;
typedef LONG HB_HANDLE; /* handle to memvar value */
typedef char HB_SYMBOLSCOPE; /* stores symbol's scope */
typedef ULONG HB_HANDLE; /* handle to memvar value */
typedef char HB_SYMBOLSCOPE; /* stores symbol's scope */
/* Some common character constants */

View File

@@ -115,6 +115,7 @@
#define ERR_PPMEMALLOC 11
#define ERR_PPMEMREALLOC 12
#define ERR_PPMEMFREE 13
#define ERR_PRAGMA_BAD_VALUE 14
#define WARN_NONDIRECTIVE 1

View File

@@ -40,11 +40,6 @@
extern unsigned _stklen = UINT_MAX;
#endif
/* /ES command line setting types */
#define HB_EXITLEVEL_DEFAULT 0
#define HB_EXITLEVEL_SETEXIT 1
#define HB_EXITLEVEL_DELTARGET 2
typedef enum
{
LANG_C, /* C language (by default) <file.c> */

View File

@@ -33,6 +33,18 @@
*
*/
/*
* The following parts are Copyright of the individual authors.
* www - http://www.harbour-project.org
*
* Copyright 1999 Jose Lalin <dezac@corevia.com>
* Support for #pragma directive and related functions
* See doc/pragma.txt
*
* See doc/license.txt for licensing terms.
*
*/
/*
* Avoid tracing in preprocessor/compiler.
*/
@@ -48,6 +60,7 @@
#include <ctype.h>
#include "hbpp.h"
#include "hberrors.h"
#include "compiler.h"
static COMMANDS * AddCommand( char * ); /* Add new #command to an array */
static COMMANDS * AddTranslate( char * ); /* Add new #translate to an array */
@@ -89,6 +102,15 @@ static int NextName( char **, char * );
static int NextParm( char **, char * );
static BOOL OpenInclude( char *, PATHNAMES *, PHB_FNAME, FILE **, BOOL bStandardOnly, char * );
/* These are related to pragma support */
static int ParsePragma( char * );
static BOOL StringToBool( char *, BOOL );
static int StringToInt( char *, int );
static BOOL IsOnOffSwitch( char *, BOOL );
static void DebugPragma( char *, int, BOOL );
static BOOL s_bTracePragma = FALSE;
#define ISNAME( c ) ( isalnum( c ) || ( c ) == '_' || ( c ) > 0x7E )
#define MAX_NAME 255
#define MAX_EXP 1024
@@ -138,7 +160,8 @@ char * hb_pp_szErrors[] =
"#error: \'%s\'",
"Memory allocation error",
"Memory reallocation error",
"Freeing a NULL memory pointer"
"Freeing a NULL memory pointer",
"Value out of range in #pragma directive"
};
/* Table with parse warnings */
@@ -243,6 +266,10 @@ int hb_pp_ParseDirective( char * sLine )
else if( i == 4 && memcmp( sDirective, "LINE", 4 ) == 0 )
return -1;
else if( i == 6 && memcmp( sDirective, "PRAGMA", 6 ) == 0 )
ParsePragma( sLine ); /* --- #pragma --- */
else
hb_compGenError( hb_pp_szErrors, 'F', ERR_WRONG_DIRECTIVE, sDirective, NULL );
}
@@ -2258,3 +2285,286 @@ static BOOL OpenInclude( char * szFileName, PATHNAMES * pSearch, PHB_FNAME pMain
return ( *fptr ? TRUE : FALSE );
}
/* Size of abreviated pragma commands */
#define PRAGMAS_LEN 8
/* TODO: Add support for:
CompileModule /M
QuietMode /Q
RequestLib /R
TempPath /T
StdHeader /U
CheckSyntax /S
*/
static int ParsePragma( char * sLine )
{
char pragma[ MAX_NAME ];
HB_TRACE(HB_TR_DEBUG, ("ParsePragma(%s)", sLine));
HB_SKIPTABSPACES( sLine );
NextWord( &sLine, pragma, FALSE );
if( HB_ISOPTSEP( pragma[ 0 ] ) )
{
switch( pragma[ 1 ] )
{
case 'a':
case 'A':
hb_comp_bAutoMemvarAssume = IsOnOffSwitch( pragma, hb_comp_bAutoMemvarAssume );
DebugPragma( pragma, -1, hb_comp_bAutoMemvarAssume );
break;
case 'b':
case 'B':
hb_comp_bDebugInfo = IsOnOffSwitch( pragma, hb_comp_bDebugInfo );
hb_comp_bLineNumbers = hb_comp_bDebugInfo;
DebugPragma( pragma, -1, hb_comp_bDebugInfo );
break;
case 'e':
case 'E':
if( pragma[ 2 ] == 's' ||
pragma[ 2 ] == 'S' )
{
switch( pragma[ 3 ] )
{
case '\0':
case '0':
hb_comp_iExitLevel = HB_EXITLEVEL_DEFAULT;
break;
case '1':
hb_comp_iExitLevel = HB_EXITLEVEL_SETEXIT;
break;
case '2':
hb_comp_iExitLevel = HB_EXITLEVEL_DELTARGET;
break;
default:
hb_compGenError( hb_pp_szErrors, 'F', ERR_PRAGMA_BAD_VALUE, NULL, NULL );
}
DebugPragma( pragma, hb_comp_iExitLevel, FALSE );
}
break;
case 'l':
case 'L':
hb_comp_bLineNumbers = IsOnOffSwitch( pragma, hb_comp_bLineNumbers );
DebugPragma( pragma, -1, hb_comp_bLineNumbers );
break;
case 'n':
case 'N':
hb_comp_bStartProc = IsOnOffSwitch( pragma, hb_comp_bStartProc );
DebugPragma( pragma, -1, hb_comp_bStartProc );
break;
case 'p':
case 'P':
hb_comp_bPPO = IsOnOffSwitch( pragma, hb_comp_bPPO );
DebugPragma( pragma, -1, hb_comp_bPPO );
break;
case 'v':
case 'V':
hb_comp_bForceMemvars = IsOnOffSwitch( pragma, hb_comp_bForceMemvars );
DebugPragma( pragma, -1, hb_comp_bForceMemvars );
break;
case 'w':
case 'W':
if( pragma[ 2 ] != '\0' )
{
/* Check for +/- */
if( pragma[ strlen( pragma ) - 1 ] == '+' ||
pragma[ strlen( pragma ) - 1 ] == '-' )
hb_comp_iWarnings = IsOnOffSwitch( pragma, hb_comp_iWarnings != 0 ) ? 1 : 0;
else
{
/* There is -w<0,1,2,3> probably */
hb_comp_iWarnings = pragma[ 2 ] - '0';
if( hb_comp_iWarnings < 0 || hb_comp_iWarnings > 3 )
hb_compGenError( hb_pp_szErrors, 'F', ERR_PRAGMA_BAD_VALUE, NULL, NULL );
DebugPragma( pragma, -1, hb_comp_iWarnings );
}
}
break;
case 'z':
case 'Z':
hb_comp_bShortCuts = IsOnOffSwitch( pragma, hb_comp_bShortCuts );
DebugPragma( pragma, -1, hb_comp_bShortCuts );
break;
default:
break;
}
}
else
{
char * temp = hb_strupr( pragma );
if( memcmp( pragma, "AUTOMEMVARS", PRAGMAS_LEN ) == 0 )
{
hb_comp_bAutoMemvarAssume = StringToBool( temp, hb_comp_bAutoMemvarAssume );
DebugPragma( pragma, -1, hb_comp_bAutoMemvarAssume );
}
else if( memcmp( temp, "DEBUGINFO", PRAGMAS_LEN ) == 0 )
{
hb_comp_bDebugInfo = StringToBool( temp, hb_comp_bDebugInfo );
hb_comp_bLineNumbers = hb_comp_bDebugInfo;
DebugPragma( pragma, -1, hb_comp_bDebugInfo );
}
else if( memcmp( temp, "ENABLEWARNINGS", PRAGMAS_LEN ) == 0 )
{
hb_comp_iWarnings = StringToBool( temp, hb_comp_iWarnings != 0 ) ? 1 : 0;
DebugPragma( pragma, hb_comp_iWarnings, FALSE );
}
else if( memcmp( temp, "EXITSEVERITY", PRAGMAS_LEN ) == 0 )
{
hb_comp_iExitLevel = StringToInt( temp, hb_comp_iExitLevel );
if( hb_comp_iExitLevel < 0 || hb_comp_iExitLevel > 2 )
hb_compGenError( hb_pp_szErrors, 'F', ERR_PRAGMA_BAD_VALUE, NULL, NULL );
DebugPragma( pragma, hb_comp_iExitLevel, FALSE );
}
else if( memcmp( temp, "FORCEMEMVARS", PRAGMAS_LEN ) == 0 )
{
hb_comp_bForceMemvars = StringToBool( temp, hb_comp_bForceMemvars );
DebugPragma( pragma, -1, hb_comp_bForceMemvars );
}
else if( memcmp( temp, "LINEINFO", PRAGMAS_LEN ) == 0 )
{
hb_comp_bLineNumbers = StringToBool( temp, hb_comp_bLineNumbers );
DebugPragma( pragma, -1, hb_comp_bLineNumbers );
}
else if( memcmp( temp, "NOSTARTPROC", PRAGMAS_LEN ) == 0 )
{
hb_comp_bStartProc = StringToBool( temp, hb_comp_bStartProc );
DebugPragma( pragma, hb_comp_bStartProc, FALSE );
}
else if( memcmp( temp, "PREPROCESSING", PRAGMAS_LEN ) == 0 )
{
hb_comp_bPPO = StringToBool( temp, hb_comp_bPPO );
DebugPragma( pragma, -1, hb_comp_bPPO );
}
else if( memcmp( temp, "SHORTCUTTING", PRAGMAS_LEN ) == 0 )
{
hb_comp_bShortCuts = StringToBool( temp, hb_comp_bShortCuts );
DebugPragma( pragma, -1, hb_comp_bShortCuts );
}
else if( memcmp( temp, "WARNINGLEVEL", PRAGMAS_LEN ) == 0 )
{
hb_comp_iWarnings = StringToInt( temp, hb_comp_iWarnings );
if( hb_comp_iWarnings < 0 || hb_comp_iWarnings > 3 )
hb_compGenError( hb_pp_szErrors, 'F', ERR_PRAGMA_BAD_VALUE, NULL, NULL );
DebugPragma( pragma, -1, hb_comp_iWarnings );
}
else if( memcmp( temp, "TRACEPRAGMAS", PRAGMAS_LEN ) == 0 )
{
s_bTracePragma = StringToBool( temp, s_bTracePragma );
DebugPragma( pragma, -1, s_bTracePragma );
}
}
return 0;
}
/* Checks for ON/OFF within the string, sets bDefault if not found */
static BOOL StringToBool( char * str, BOOL bDefault )
{
char * pos;
BOOL bRet = bDefault;
pos = strchr( str, '=' );
if( pos )
{
long lPos = pos - str + 1;
if( str[ lPos ] == 'O' )
{
if( strlen( str ) >= 2 &&
str[ lPos + 1 ] == 'N' )
bRet = TRUE;
else if( strlen( str ) >= 3 &&
str[ lPos + 1 ] == 'F' &&
str[ lPos + 2 ] == 'F' )
bRet = FALSE;
}
}
return bRet;
}
/* Checks for +/- within the string, sets bDefault if not found */
static BOOL IsOnOffSwitch( char * str, BOOL bDefault )
{
BOOL bRet = bDefault;
long lPos = strlen( str ) - 1;
if( str[ lPos ] == '+' )
bRet = TRUE;
else if( str[ lPos ] == '-' )
bRet = FALSE;
return bRet;
}
/* Returns value after =, sets iDefault if not found */
static int StringToInt( char * str, int iDefault )
{
char * pos;
int iRet = iDefault;
pos = strchr( str, '=' );
if( pos )
{
long lPos = pos - str + 1;
if( lPos && str[ lPos ] )
iRet = str[ lPos ] - '0';
}
return iRet;
}
/* This is only to debug pragmas now */
static void DebugPragma( char * szStr, int iValue, BOOL bValue )
{
if( s_bTracePragma )
{
char * ptr = strchr( szStr, '=' );
char * temp = hb_xgrab( strlen( szStr ) + 1 );
BOOL bIsSwitch = TRUE;
* temp = '\0';
/* strip =... from szStr. Just cosmetic */
if( ptr )
{
int i = 0;
while( szStr[ i ] != '=' )
temp[ i ] = szStr[ i++ ];
temp[ i ] = '\0';
bIsSwitch = FALSE;
}
if( iValue > 0 )
printf( "#pragma %s set to %i\n", bIsSwitch ? szStr : temp, iValue );
else
printf( "#pragma %s is %s\n", bIsSwitch ? szStr : temp, bValue ? "ON" : "OFF" );
hb_xfree( temp );
}
}

View File

@@ -46,6 +46,7 @@
#include <setjmp.h>
#include "hbpp.h"
#include "compiler.h"
#include "extend.h"
#include "itemapi.h"
#include "errorapi.h"
@@ -54,6 +55,17 @@
PATHNAMES * hb_comp_pIncludePath = NULL;
PHB_FNAME hb_comp_pFileName = NULL;
/* These are need for the PP #pragma support */
BOOL hb_comp_bPPO = FALSE; /* flag indicating, is ppo output needed */
BOOL hb_comp_bStartProc = TRUE; /* holds if we need to create the starting procedure */
BOOL hb_comp_bLineNumbers = TRUE; /* holds if we need pcodes with line numbers */
BOOL hb_comp_bShortCuts = TRUE; /* .and. & .or. expressions shortcuts */
int hb_comp_iWarnings = 0; /* enable parse warnings */
BOOL hb_comp_bAutoMemvarAssume = FALSE; /* holds if undeclared variables are automatically assumed MEMVAR (-a)*/
BOOL hb_comp_bForceMemvars = FALSE; /* holds if memvars are assumed when accesing undeclared variable (-v)*/
BOOL hb_comp_bDebugInfo = FALSE; /* holds if generate debugger required info */
int hb_comp_iExitLevel = HB_EXITLEVEL_DEFAULT; /* holds if there was any warning during the compilation process */
static jmp_buf s_env;
/* TODO: Extend the function to allow directives

View File

@@ -49,6 +49,7 @@
#include "hbpp.h"
#include "hberrors.h"
#include "hbver.h"
#include "compiler.h"
static void AddSearchPath( char * szPath, PATHNAMES * * pSearchList );
static void OutTable( DEFINES * endDefine, COMMANDS * endCommand );
@@ -61,6 +62,17 @@ static int s_iWarnings = 0;
PATHNAMES * hb_comp_pIncludePath = NULL;
PHB_FNAME hb_comp_pFileName = NULL;
/* These are need for the PP #pragma support */
BOOL hb_comp_bPPO = FALSE; /* flag indicating, is ppo output needed */
BOOL hb_comp_bStartProc = TRUE; /* holds if we need to create the starting procedure */
BOOL hb_comp_bLineNumbers = TRUE; /* holds if we need pcodes with line numbers */
BOOL hb_comp_bShortCuts = TRUE; /* .and. & .or. expressions shortcuts */
int hb_comp_iWarnings = 0; /* enable parse warnings */
BOOL hb_comp_bAutoMemvarAssume = FALSE; /* holds if undeclared variables are automatically assumed MEMVAR (-a)*/
BOOL hb_comp_bForceMemvars = FALSE; /* holds if memvars are assumed when accesing undeclared variable (-v)*/
BOOL hb_comp_bDebugInfo = FALSE; /* holds if generate debugger required info */
int hb_comp_iExitLevel = HB_EXITLEVEL_DEFAULT; /* holds if there was any warning during the compilation process */
int main( int argc, char * argv[] )
{
FILE * handl_i;

View File

@@ -16,7 +16,8 @@
* www - http://www.harbour-project.org
*
* Copyright 1999 Victor Szel <info@szelvesz.hu>
* Changes for higher Clipper compatibility
* Changes for higher Clipper compatibility, console mode, extensions
* __NONOALERT()
*
* Copyright 1999 Chen Kedem <niki@actcom.co.il>
* Documentation

View File

@@ -95,7 +95,7 @@
*
* // sort two-dimensional array according to 2nd element of each pair
* aPair := { {"Sun",8}, {"Mon",1}, {"Tue",57}, {"Wed",-6} }
* ASORT( aPair,,, {| x, y | x[2] > y[2] } )
* ASORT( aPair,,, {| x, y | x[2] < y[2] } )
* // result: { {"Wed",-6}, {"Mon",1}, {"Sun",8}, {"Tue",57} }
* $TESTS$
* $STATUS$

View File

@@ -826,7 +826,7 @@ static HB_ITEM_PTR hb_memvarDebugVariable( int iScope, int iPos, char * *pszName
}
else
{
if( iPos < s_privateStackCnt )
if( ( ULONG ) iPos < s_privateStackCnt )
{
HB_DYNS_PTR pDynSym = s_privateStack[ iPos ];

View File

@@ -33,18 +33,6 @@
*
*/
/*
* The following parts are Copyright of the individual authors.
* www - http://www.harbour-project.org
*
* Copyright 1999 Victor Szel <info@szelvesz.hu>
* HB_HB_TRACEENABLE()
*
* See doc/license.txt for licensing terms.
*
*/
#include "extend.h"
HARBOUR HB_HB_TRACESTATE( void )

View File

@@ -143,6 +143,7 @@ PRG_SOURCES=\
testwarn.prg \
tstalias.prg \
tstcolor.prg \
tstprag.prg \
version.prg \
while.prg \

31
harbour/tests/tstprag.prg Normal file
View File

@@ -0,0 +1,31 @@
/*
* $Id$
*/
#pragma TracePragmas=On
#pragma ExitSeverity=1
/* Unknow pragmas will be ignored silently */
#pragma BadPragma=off
#pragma /Y+
function Main()
#pragma ShortCutting=On
/* or #pragma /Z+ */
if .t. .and. .f.
? "Always"
endif
if .f. .and. .t.
? "Never"
endif
#pragma /Z-
/* or #pragma ShortCutting=Off */
/* Pragmas with bad values will cause an error */
#pragma WarningLevel=8
return nil