19990919-06:21 GMT+1
This commit is contained in:
@@ -1,3 +1,54 @@
|
||||
19990919-06:21 GMT+1 Victor Szel <info@szelvesz.hu>
|
||||
|
||||
* source/vm/hvm.c
|
||||
+ Added support for CA-Clipper undocumented _APPMAIN starting function,
|
||||
if this is defined, Harbour will start it first, overriding the default
|
||||
starting proc.
|
||||
! Fixed the case when no PUBLIC functions were declared with no
|
||||
explicit starting procedure. Now it will silently exit (STRICT mode)
|
||||
or show a proper unrecoverable error message, instead of a possible GPF,
|
||||
* __XHELP() - hb_dynsymFindName() changed to hb_dynsymFind()
|
||||
* source/rtl/environ.c
|
||||
include/extend.h
|
||||
+ hb_version() added, separated from HB_VERSION(), to make it callable
|
||||
from C, too. //INFO needed it.
|
||||
* source/rtl/console.c
|
||||
+ Added undocumented //STDERR feature, when specified it will redirect
|
||||
all stderr output to stdout.
|
||||
* source/rtl/alert.prg
|
||||
+ ALERT() now handles the //NOALERT switch.
|
||||
The NOALERT feature is now always turned on, not only in STRICT mode.
|
||||
+ __NONOALERT() undocumented Clipper function added.
|
||||
* source/rtl/hvm.c
|
||||
+ source/rtl/cmdarg.c
|
||||
source/rtl/Makefile
|
||||
include/extend.h
|
||||
makefile.*
|
||||
makefile.vc (with extra care taken to retain the alphabetical order :-))
|
||||
+ Internal command line and environment variable support added.
|
||||
//INFO //F:30 //TEMPPATH:"C:\TEMP", SET HARBOUR=F30;X00,
|
||||
SET CLIPPER=E0 INFO, now can be queried from Harbour runtime.
|
||||
+ API added to reach the above functionality.
|
||||
+ Harbour argument handling functions added:
|
||||
__ARGC()
|
||||
__ARGV()
|
||||
__ARGCHECK()
|
||||
__ARGGET()
|
||||
! Now the internal parameters (//INFO) are no more passed to the Harbour
|
||||
MAIN and INIT functions.
|
||||
+ Harbour now prints the version when //INFO switch is speficied.
|
||||
* source/rtl/fm.c
|
||||
+ Will always print some memory info when the //INFO switch was specified.
|
||||
* include/clipdefs.h
|
||||
+ Added WORD, DWORD typedefs.
|
||||
* source/rtl/strings.c
|
||||
include/extend.h
|
||||
+ hb_strnicmp() added.
|
||||
% hb_stricmp() formatted, variable scopes adjusted, int type changed to
|
||||
char.
|
||||
* source/rtl/classes.c
|
||||
* Small modification.
|
||||
|
||||
19990918-17:42 GMT+1 Victor Szel <info@szelvesz.hu>
|
||||
|
||||
* source/rtl/set.c
|
||||
|
||||
@@ -62,6 +62,7 @@ typedef SHORTP PSHORT;
|
||||
typedef USHORT* USHORTP;
|
||||
typedef USHORTP PUSHORT;
|
||||
|
||||
typedef unsigned int WORD;
|
||||
typedef WORD* WORDP;
|
||||
typedef WORDP PWORD;
|
||||
|
||||
@@ -71,6 +72,7 @@ typedef LONGP PLONG;
|
||||
typedef ULONG* ULONGP;
|
||||
typedef ULONGP PULONG;
|
||||
|
||||
typedef unsigned long DWORD;
|
||||
typedef DWORD* DWORDP;
|
||||
typedef DWORDP PDWORD;
|
||||
|
||||
|
||||
@@ -317,6 +317,7 @@ extern PHB_ITEM hb_arrayClone( PHB_ITEM pArray );
|
||||
#define HB_STRGREATER_RIGHT 2
|
||||
|
||||
extern int hb_stricmp( const char * s1, const char * s2 );
|
||||
extern int hb_strnicmp( const char * s1, const char * s2, ULONG ulLen );
|
||||
extern int hb_strgreater( char * szText1, char * szText2 );
|
||||
extern void hb_strupr( char * szText );
|
||||
extern BOOL hb_strMatchRegExp( char * szString, char * szMask );
|
||||
@@ -346,6 +347,15 @@ extern void hb_dynsymLog( void ); /* displays all dynamic symbol
|
||||
extern void hb_dynsymRelease( void ); /* releases the memory of the dynamic symbol table */
|
||||
extern void hb_dynsymEval( PHB_DYNS_FUNC, void * ); /* enumerates all dynamic symbols */
|
||||
|
||||
/* Command line and environment argument management */
|
||||
extern void hb_cmdargInit( int argc, char * argv[] );
|
||||
extern int hb_cmdargARGC( void );
|
||||
extern char ** hb_cmdargARGV( void );
|
||||
extern BOOL hb_cmdargIsInternal( const char * szArg );
|
||||
extern BOOL hb_cmdargCheck( const char * pszName ); /* Check if a given internal switch (like //INFO) was set */
|
||||
extern char * hb_cmdargString( const char * pszName ); /* Returns the string value of an internal switch (like //TEMPPATH:"C:\") */
|
||||
extern int hb_cmdargNum( const char * pszName ); /* Returns the numeric value of an internal switch (like //F:90) */
|
||||
|
||||
/* Symbol management */
|
||||
extern PHB_SYMB hb_symbolNew( char * szName );
|
||||
|
||||
@@ -378,6 +388,9 @@ extern char * hb_consoleGetNewLine( void );
|
||||
extern void hb_tone( double dFrequency, double dDuration );
|
||||
extern char * hb_setColor( char * );
|
||||
|
||||
/* misc */
|
||||
extern char * hb_version( USHORT uiMode );
|
||||
|
||||
/* Please leave these at the bottom of this file */
|
||||
|
||||
#ifdef HARBOUR_STRICT_CLIPPER_COMPATIBILITY
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
PROJECT: harbour.lib libs\b16\terminal.lib libs\win16\terminal.lib harbour.exe
|
||||
|
||||
harbour.lib : arrays.obj asort.obj classes.obj codebloc.obj dates.obj \
|
||||
dates2.obj datesx.obj \
|
||||
dates2.obj datesx.obj cmdarg.obj \
|
||||
debug.obj descend.obj devoutp.obj dynsym.obj environ.obj terror.obj \
|
||||
errorapi.obj errorsys.obj harbinit.obj extend.obj files.obj fm.obj \
|
||||
hardcr.obj initsymb.obj itemapi.obj math.obj memofile.obj memvars.obj \
|
||||
@@ -36,6 +36,7 @@ console.obj : console.c extend.h hbdefs.h
|
||||
arrays.obj : arrays.c extend.h hbdefs.h
|
||||
asort.obj : asort.c extend.h hbdefs.h
|
||||
classes.obj : classes.c extend.h hbdefs.h
|
||||
cmdarg.obj : cmdarg.c extend.h hbdefs.h
|
||||
codebloc.obj : codebloc.c extend.h hbdefs.h
|
||||
dates.obj : dates.c extend.h hbdefs.h
|
||||
dates2.obj : dates2.c extend.h hbdefs.h
|
||||
|
||||
@@ -18,7 +18,7 @@ c_opt = -mh -O2 -I.\include -DHARBOUR_USE_GTAPI
|
||||
|
||||
PROJECT: harbour.lib hbtools.lib terminal.lib libs\win16\terminal.lib
|
||||
|
||||
harbour.lib : arrays.obj asort.obj classes.obj codebloc.obj copyfile.obj \
|
||||
harbour.lib : arrays.obj asort.obj classes.obj codebloc.obj copyfile.obj cmdarg.obj \
|
||||
dates.obj descend.obj devoutp.obj dir.obj dynsym.obj environ.obj \
|
||||
terror.obj errorapi.obj errorsys.obj harbinit.obj extend.obj \
|
||||
filesys.obj gtapi.obj hardcr.obj initsymb.obj itemapi.obj \
|
||||
@@ -79,6 +79,7 @@ transfrm.obj : transfrm.c extend.h hbdefs.h ctoharb.h set.h dates.h
|
||||
gtdos.obj : source\rtl\gt\gtdos.c extend.h hbdefs.h gtapi.h
|
||||
msguk.obj : source\rtl\natmsg\msguk.c extend.h hbdefs.h
|
||||
|
||||
cmdarg.obj : source\vm\cmdarg.c extend.h hbdefs.h
|
||||
debug.obj : source\vm\debug.c extend.h hbdefs.h ctoharb.h itemapi.h
|
||||
dynsym.obj : source\vm\dynsym.c extend.h hbdefs.h
|
||||
initsymb.obj : source\vm\initsymb.c extend.h hbdefs.h
|
||||
|
||||
@@ -20,7 +20,7 @@ harbour.lib : achoice.obj adir.obj alert.obj arrays.obj asort.obj \
|
||||
browdb.obj \
|
||||
classes.obj codebloc.obj copyfile.obj \
|
||||
dates.obj dates2.obj datesx.obj debug.obj debugger.obj descend.obj devoutp.obj \
|
||||
dir.obj do.obj dynsym.obj environ.obj terror.obj \
|
||||
dir.obj do.obj dynsym.obj environ.obj terror.obj cmdarg.obj \
|
||||
errorapi.obj errorsys.obj harbinit.obj extend.obj fileread.obj filesys.obj fm.obj \
|
||||
hardcr.obj hb_f.obj hvm.obj initsymb.obj inkey.obj itemapi.obj \
|
||||
langapi.obj math.obj mathx.obj memofile.obj memvars.obj menuto.obj mtran.obj msges.obj \
|
||||
@@ -35,6 +35,7 @@ arrays.obj : arrays.c extend.h hbdefs.h
|
||||
asort.obj : asort.c extend.h hbdefs.h
|
||||
browdb.obj : browdb.c extend.h hbdefs.h
|
||||
classes.obj : classes.c extend.h hbdefs.h
|
||||
cmdarg.obj : cmdarg.c extend.h hbdefs.h
|
||||
codebloc.obj : codebloc.c extend.h hbdefs.h
|
||||
copyfile.obj : copyfile.c extend.h hbdefs.h
|
||||
dates.obj : dates.c extend.h hbdefs.h
|
||||
|
||||
@@ -18,7 +18,7 @@ PROJECT: harbour.exe harbour.lib libs\b32\terminal.lib libs\win32\terminal.lib
|
||||
|
||||
harbour.lib : arrays.obj asort.obj classes.obj codebloc.obj alert.obj \
|
||||
dates.obj dates2.obj datesx.obj debug.obj descend.obj devoutp.obj \
|
||||
dir.obj dynsym.obj environ.obj terror.obj menu.obj \
|
||||
dir.obj dynsym.obj environ.obj terror.obj menu.obj cmdarg.obj \
|
||||
errorapi.obj errorsys.obj harbinit.obj extend.obj files.obj \
|
||||
hardcr.obj hb_f.obj initsymb.obj inkey.obj itemapi.obj memvars.obj \
|
||||
memofile.obj math.obj mathx.obj msguk.obj mtran.obj objfunc.obj \
|
||||
@@ -31,6 +31,7 @@ copyfile.obj : copyfile.c extend.h hbdefs.h
|
||||
arrays.obj : arrays.c extend.h hbdefs.h
|
||||
asort.obj : asort.c extend.h hbdefs.h
|
||||
classes.obj : classes.c extend.h hbdefs.h
|
||||
cmdarg.obj : cmdarg.c extend.h hbdefs.h
|
||||
codebloc.obj : codebloc.c extend.h hbdefs.h
|
||||
dates.obj : dates.c extend.h hbdefs.h
|
||||
dates2.obj : dates2.c extend.h hbdefs.h
|
||||
|
||||
@@ -64,6 +64,7 @@ HARBOUR_LIB_OBJS = \
|
||||
$(OBJ_DIR)\asort.obj \
|
||||
$(OBJ_DIR)\browdb.obj \
|
||||
$(OBJ_DIR)\classes.obj \
|
||||
$(OBJ_DIR)\cmdarg.obj \
|
||||
$(OBJ_DIR)\codebloc.obj \
|
||||
$(OBJ_DIR)\console.obj \
|
||||
$(OBJ_DIR)\copyfile.obj \
|
||||
@@ -531,6 +532,9 @@ $(OBJ_DIR)\tbrwtext.obj : $(DEBUG_DIR)\tbrwtext.c
|
||||
# VM source dependencies below. Add as needed
|
||||
#
|
||||
|
||||
$(OBJ_DIR)\cmdarg.obj : $(VM_DIR)\cmdarg.c
|
||||
$(CC) $(CLIBFLAGS) -Fo$@ $**
|
||||
|
||||
$(OBJ_DIR)\debug.obj : $(VM_DIR)\debug.c
|
||||
$(CC) $(CLIBFLAGS) -Fo$@ $**
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
// This is fixed.
|
||||
// ; nDelay parameter is a Harbour addition.
|
||||
|
||||
STATIC s_lNoAlert := NIL
|
||||
|
||||
FUNCTION Alert( xMessage, aOptions, cColorNorm, nDelay )
|
||||
LOCAL nChoice
|
||||
LOCAL aSay, nPos, nWidth, nOpWidth, nInitRow, nInitCol, iEval
|
||||
@@ -55,13 +57,11 @@ FUNCTION Alert( xMessage, aOptions, cColorNorm, nDelay )
|
||||
/* if it is not, the console mode is choosed here */
|
||||
LOCAL lConsole := .F.
|
||||
|
||||
#ifdef HARBOUR_STRICT_CLIPPER_COMPATIBILITY
|
||||
// TODO: Enable this when we have a function for querying the command line
|
||||
// parameters.
|
||||
// IF "//NOALERT" $ /* Upper( cCommandLine ) */
|
||||
// QUIT
|
||||
// ENDIF
|
||||
#endif
|
||||
DEFAULT s_lNoAlert TO __argCheck( "NOALERT" )
|
||||
|
||||
IF s_lNoAlert
|
||||
QUIT
|
||||
ENDIF
|
||||
|
||||
aSay := {}
|
||||
|
||||
@@ -277,3 +277,11 @@ FUNCTION Alert( xMessage, aOptions, cColorNorm, nDelay )
|
||||
ENDIF
|
||||
|
||||
RETURN nChoice
|
||||
|
||||
/* Undocumented CA-Clipper functions */
|
||||
|
||||
PROCEDURE __NONOALERT()
|
||||
|
||||
s_lNoAlert := .F.
|
||||
|
||||
RETURN
|
||||
|
||||
@@ -756,7 +756,7 @@ HARBOUR HB___CLSINSTSUPER( void )
|
||||
|
||||
for( uiClass = 0; ! bFound && uiClass < s_uiClasses; uiClass++ )
|
||||
{ /* Locate the entry */
|
||||
if( !hb_stricmp( pString->item.asString.value, s_pClasses[ uiClass ].szName ) )
|
||||
if( hb_stricmp( pString->item.asString.value, s_pClasses[ uiClass ].szName ) == 0 )
|
||||
{
|
||||
hb_retni( uiClass + 1 ); /* Entry + 1 = hb___msgClsH */
|
||||
bFound = TRUE;
|
||||
|
||||
@@ -124,7 +124,10 @@ void hb_consoleInitialize( void )
|
||||
|
||||
s_iFilenoStdout = fileno( stdout );
|
||||
hb_fsSetDevMode( s_iFilenoStdout, FM_BINARY );
|
||||
s_iFilenoStderr = fileno( stderr );
|
||||
if( hb_cmdargCheck( "STDERR" ) ) /* Undocumented CA-Clipper switch */
|
||||
s_iFilenoStderr = s_iFilenoStdout;
|
||||
else
|
||||
s_iFilenoStderr = fileno( stderr );
|
||||
hb_fsSetDevMode( s_iFilenoStderr, FM_BINARY );
|
||||
|
||||
#ifdef HARBOUR_USE_GTAPI
|
||||
|
||||
@@ -281,17 +281,21 @@ HARBOUR HB_OS( void )
|
||||
#endif /* __MPW__ */
|
||||
}
|
||||
|
||||
HARBOUR HB_VERSION( void )
|
||||
{
|
||||
char hb_ver[ 80 ];
|
||||
/* The caller must free the returned buffer. */
|
||||
|
||||
sprintf( hb_ver, "Harbour %d.%d Intl. (Build %d%s) (%04d.%02d.%02d)",
|
||||
#define HB_VERSION_BUFFER_LEN 80
|
||||
|
||||
char * hb_version( USHORT uiMode )
|
||||
{
|
||||
char * pszVersion = hb_xgrab( HB_VERSION_BUFFER_LEN );
|
||||
|
||||
sprintf( pszVersion, "Harbour %d.%d Intl. (Build %d%s) (%04d.%02d.%02d)",
|
||||
hb_major, hb_minor, hb_build, hb_revision, hb_year, hb_month, hb_day );
|
||||
|
||||
if( hb_pcount() == 1 )
|
||||
if( uiMode != 0 )
|
||||
{
|
||||
/* Optionally include the Compiler name and version, if available. */
|
||||
char * compiler = (char *) 0;
|
||||
char * compiler = ( char * ) NULL;
|
||||
int version = 0;
|
||||
|
||||
#if defined(__IBMCPP__)
|
||||
@@ -327,21 +331,28 @@ HARBOUR HB_VERSION( void )
|
||||
#endif
|
||||
if( compiler )
|
||||
{
|
||||
strncat( hb_ver, " (", sizeof( hb_ver ) );
|
||||
strncat( hb_ver, compiler, sizeof( hb_ver ) );
|
||||
strncat( pszVersion, " (", HB_VERSION_BUFFER_LEN );
|
||||
strncat( pszVersion, compiler, HB_VERSION_BUFFER_LEN );
|
||||
if( version )
|
||||
{
|
||||
char buf[ 40 ];
|
||||
sprintf( buf, "(%d)", version );
|
||||
strncat( hb_ver, " ", sizeof( hb_ver ) );
|
||||
strncat( hb_ver, buf, sizeof( hb_ver ) );
|
||||
strncat( pszVersion, " ", HB_VERSION_BUFFER_LEN );
|
||||
strncat( pszVersion, buf, HB_VERSION_BUFFER_LEN );
|
||||
}
|
||||
strncat( hb_ver, ")", sizeof( hb_ver ) );
|
||||
hb_ver[ sizeof( hb_ver ) - 1 ] = '\0';
|
||||
strncat( pszVersion, ")", HB_VERSION_BUFFER_LEN );
|
||||
pszVersion[ HB_VERSION_BUFFER_LEN - 1 ] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
hb_retc( hb_ver );
|
||||
return pszVersion;
|
||||
}
|
||||
|
||||
HARBOUR HB_VERSION( void )
|
||||
{
|
||||
char * pszVersion = hb_version( hb_pcount() > 0 ? 1 : 0 );
|
||||
hb_retc( pszVersion );
|
||||
hb_xfree( pszVersion );
|
||||
}
|
||||
|
||||
HARBOUR HB_GETENV( void )
|
||||
|
||||
@@ -147,12 +147,20 @@ void hb_xinit( void ) /* Initialize fixed memory subsystem */
|
||||
void hb_xexit( void ) /* Deinitialize fixed memory subsystem */
|
||||
{
|
||||
#ifdef HB_FM_STATISTICS
|
||||
if( s_ulMemoryBlocks )
|
||||
if( s_ulMemoryBlocks || hb_cmdargCheck( "INFO" ) )
|
||||
{
|
||||
printf( "\n\ntotal memory blocks allocated: %lu\n", s_ulMemoryMaxBlocks );
|
||||
printf( "memory maximum size consumed: %ld\n", s_ulMemoryMaxConsumed );
|
||||
printf( "memory blocks not released: %ld\n", s_ulMemoryBlocks );
|
||||
printf( "memory size not released: %ld\n", s_ulMemoryConsumed );
|
||||
printf( hb_consoleGetNewLine() );
|
||||
printf( "total memory blocks allocated: %lu", s_ulMemoryMaxBlocks );
|
||||
printf( hb_consoleGetNewLine() );
|
||||
printf( "memory maximum size consumed: %ld", s_ulMemoryMaxConsumed );
|
||||
if( s_ulMemoryBlocks )
|
||||
{
|
||||
printf( hb_consoleGetNewLine() );
|
||||
printf( "memory blocks not released: %ld", s_ulMemoryBlocks );
|
||||
printf( hb_consoleGetNewLine() );
|
||||
printf( "memory size not released: %ld", s_ulMemoryConsumed );
|
||||
}
|
||||
printf( hb_consoleGetNewLine() );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
* hb_strEmpty()
|
||||
* hb_strMatchDOS()
|
||||
* hb_STRZERO()
|
||||
* hb_strnicmp()
|
||||
*
|
||||
* See doc/license.txt for licensing terms.
|
||||
*
|
||||
@@ -99,27 +100,73 @@ BOOL hb_strEmpty( char * szText, ULONG ulLen )
|
||||
return bRetVal;
|
||||
}
|
||||
|
||||
int hb_stricmp( const char *s1, const char *s2 )
|
||||
int hb_stricmp( const char * s1, const char * s2 )
|
||||
{
|
||||
int rc = 0, c1, c2;
|
||||
ULONG l1, l2, count;
|
||||
int rc = 0;
|
||||
ULONG l1 = strlen( s1 );
|
||||
ULONG l2 = strlen( s2 );
|
||||
ULONG count;
|
||||
|
||||
if( l1 < l2 )
|
||||
count = l1;
|
||||
else
|
||||
count = l2;
|
||||
|
||||
l1 = strlen( s1 );
|
||||
l2 = strlen( s2 );
|
||||
if( l1 < l2 ) count = l1;
|
||||
else count = l2;
|
||||
while( rc == 0 && count > 0 )
|
||||
{
|
||||
char c1 = toupper( *s1++ );
|
||||
char c2 = toupper( *s2++ );
|
||||
|
||||
if( c1 != c2 )
|
||||
rc = ( c1 < c2 ? -1 : 1 );
|
||||
|
||||
count--;
|
||||
c1 = toupper( *s1++ );
|
||||
c2 = toupper( *s2++ );
|
||||
if( c1 != c2 ) rc = ( c1 < c2 ? -1 : 1 );
|
||||
}
|
||||
|
||||
if( rc == 0 && l1 != l2 )
|
||||
{
|
||||
if( l1 < l2 ) rc = -1;
|
||||
else rc = 1;
|
||||
if( l1 < l2 )
|
||||
rc = -1;
|
||||
else
|
||||
rc = 1;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int hb_strnicmp( const char * s1, const char * s2, ULONG count )
|
||||
{
|
||||
int rc = 0;
|
||||
ULONG l1 = strlen( s1 );
|
||||
ULONG l2 = strlen( s2 );
|
||||
|
||||
if( l1 > count )
|
||||
l1 = count;
|
||||
|
||||
if( l1 < l2 )
|
||||
count = l1;
|
||||
else
|
||||
count = l2;
|
||||
|
||||
while( rc == 0 && count > 0 )
|
||||
{
|
||||
char c1 = toupper( *s1++ );
|
||||
char c2 = toupper( *s2++ );
|
||||
|
||||
if( c1 != c2 )
|
||||
rc = ( c1 < c2 ? -1 : 1 );
|
||||
|
||||
count--;
|
||||
}
|
||||
|
||||
if( rc == 0 && l1 != l2 )
|
||||
{
|
||||
if( l1 < l2 )
|
||||
rc = -1;
|
||||
else
|
||||
rc = 1;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -512,7 +559,7 @@ HARBOUR HB_PADC( void )
|
||||
hb_retc( "" );
|
||||
}
|
||||
|
||||
ULONG hb_strAt( char *szSub, ULONG ulSubLen, char *szText, ULONG ulLen )
|
||||
ULONG hb_strAt( char * szSub, ULONG ulSubLen, char * szText, ULONG ulLen )
|
||||
{
|
||||
if( ulSubLen )
|
||||
{
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
ROOT = ../../
|
||||
|
||||
C_SOURCES=\
|
||||
cmdarg.c \
|
||||
debug.c \
|
||||
dynsym.c \
|
||||
hvm.c \
|
||||
|
||||
261
harbour/source/vm/cmdarg.c
Normal file
261
harbour/source/vm/cmdarg.c
Normal file
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Harbour Project source code:
|
||||
* Command line and environment argument management
|
||||
*
|
||||
* Copyright 1999 Victor Szel <info@szelvesz.hu>
|
||||
* www - http://www.harbour-project.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version, with one exception:
|
||||
*
|
||||
* The exception is that if you link the Harbour Runtime Library (HRL)
|
||||
* and/or the Harbour Virtual Machine (HVM) with other files to produce
|
||||
* an executable, this does not by itself cause the resulting executable
|
||||
* to be covered by the GNU General Public License. Your use of that
|
||||
* executable is in no way restricted on account of linking the HRL
|
||||
* and/or HVM code into it.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit
|
||||
* their web site at http://www.gnu.org/).
|
||||
*
|
||||
*/
|
||||
|
||||
#include "extend.h"
|
||||
|
||||
/* Command line argument management */
|
||||
static int s_argc = 0;
|
||||
static char ** s_argv = NULL;
|
||||
|
||||
static char * hb_cmdargGet( const char * pszName, BOOL bRetValue );
|
||||
|
||||
void hb_cmdargInit( int argc, char * argv[] )
|
||||
{
|
||||
s_argc = argc;
|
||||
s_argv = argv;
|
||||
}
|
||||
|
||||
int hb_cmdargARGC( void )
|
||||
{
|
||||
return s_argc;
|
||||
}
|
||||
|
||||
char ** hb_cmdargARGV( void )
|
||||
{
|
||||
return s_argv;
|
||||
}
|
||||
|
||||
BOOL hb_cmdargIsInternal( const char * szArg )
|
||||
{
|
||||
return strlen( szArg ) >= 2 &&
|
||||
szArg[ 0 ] == '/' &&
|
||||
szArg[ 1 ] == '/';
|
||||
}
|
||||
|
||||
static char * hb_cmdargGet( const char * pszName, BOOL bRetValue )
|
||||
{
|
||||
int i;
|
||||
char * pszEnvVar;
|
||||
|
||||
/* Check the command line first */
|
||||
|
||||
for( i = 1; i < s_argc; i++ )
|
||||
{
|
||||
if( hb_cmdargIsInternal( s_argv[ i ] ) &&
|
||||
hb_strnicmp( s_argv[ i ] + 2, pszName, strlen( pszName ) ) == 0 )
|
||||
{
|
||||
if( bRetValue )
|
||||
{
|
||||
char * pszPos = s_argv[ i ] + 2 + strlen( pszName );
|
||||
char * pszRetVal;
|
||||
|
||||
if( *pszPos == ':' )
|
||||
pszPos++;
|
||||
|
||||
pszRetVal = ( char * ) hb_xgrab( strlen( pszPos ) + 1 );
|
||||
strcpy( pszRetVal, pszPos );
|
||||
|
||||
return pszRetVal;
|
||||
}
|
||||
else
|
||||
return s_argv[ i ] + 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check the environment variable */
|
||||
|
||||
pszEnvVar = getenv( "HARBOUR" );
|
||||
|
||||
if( pszEnvVar == NULL )
|
||||
pszEnvVar = getenv( "CLIPPER" );
|
||||
|
||||
if( pszEnvVar != NULL )
|
||||
{
|
||||
static const char * szSeparator = " ;,\t";
|
||||
char * pszNext;
|
||||
|
||||
/* Step through all envvar switches. */
|
||||
|
||||
/* NOTE: CA-Clipper don't need the switches to be separated by any chars
|
||||
at all, Harbour is more strict/standard in this respect, it
|
||||
requires the switches to be separated. */
|
||||
|
||||
pszNext = pszEnvVar;
|
||||
|
||||
while( *pszNext )
|
||||
{
|
||||
char * pszEnd;
|
||||
|
||||
/* Search for the end of this switch */
|
||||
while( *pszNext && strchr( szSeparator, *pszNext ) == NULL )
|
||||
pszNext++;
|
||||
|
||||
pszEnd = pszNext;
|
||||
|
||||
/* Skip the separators after the switch */
|
||||
while( *pszNext && strchr( szSeparator, *pszNext ) )
|
||||
pszNext++;
|
||||
|
||||
/* Check the switch */
|
||||
|
||||
/* The // is optional in the envvar */
|
||||
if( hb_cmdargIsInternal( pszEnvVar ) )
|
||||
pszEnvVar += 2;
|
||||
|
||||
if( hb_strnicmp( pszEnvVar, pszName, strlen( pszName ) ) == 0 )
|
||||
{
|
||||
if( bRetValue )
|
||||
{
|
||||
char * pszPos = pszEnvVar + strlen( pszName );
|
||||
char * pszRetVal;
|
||||
|
||||
/* Skip value separator colon. */
|
||||
if( *pszPos == ':' )
|
||||
pszPos++;
|
||||
|
||||
pszRetVal = ( char * ) hb_xgrab( pszEnd - pszPos + 1 );
|
||||
strncpy( pszRetVal, pszPos, pszEnd - pszPos );
|
||||
pszRetVal[ pszEnd - pszPos ] = '\0';
|
||||
|
||||
return pszRetVal;
|
||||
}
|
||||
else
|
||||
return pszEnvVar;
|
||||
}
|
||||
|
||||
/* Step to the next switch */
|
||||
pszEnvVar = pszNext;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL hb_cmdargCheck( const char * pszName )
|
||||
{
|
||||
return hb_cmdargGet( pszName, FALSE ) != NULL;
|
||||
}
|
||||
|
||||
/* NOTE: Pointer must be freed with hb_xfree() if not NULL */
|
||||
|
||||
char * hb_cmdargString( const char * pszName )
|
||||
{
|
||||
return hb_cmdargGet( pszName, TRUE );
|
||||
}
|
||||
|
||||
int hb_cmdargNum( const char * pszName )
|
||||
{
|
||||
char * pszValue = hb_cmdargGet( pszName, TRUE );
|
||||
|
||||
if( pszValue )
|
||||
{
|
||||
int iValue = strlen( pszValue ) > 0 ? atoi( pszValue ) : -1;
|
||||
|
||||
hb_xfree( pszValue );
|
||||
|
||||
return iValue;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check if an internal switch has been set */
|
||||
|
||||
HARBOUR HB___ARGCHECK( void )
|
||||
{
|
||||
hb_retl( ISCHAR( 1 ) ? hb_cmdargCheck( hb_parc( 1 ) ) : FALSE );
|
||||
}
|
||||
|
||||
/* Returns the value of an internal switch */
|
||||
|
||||
HARBOUR HB___ARGSTRING( void )
|
||||
{
|
||||
if( ISCHAR( 1 ) )
|
||||
{
|
||||
char * pszValue = hb_cmdargString( hb_parc( 1 ) );
|
||||
|
||||
if( pszValue )
|
||||
{
|
||||
hb_retc( pszValue );
|
||||
hb_xfree( pszValue );
|
||||
}
|
||||
}
|
||||
else
|
||||
hb_retc( "" );
|
||||
}
|
||||
|
||||
/* Returns the number of command line arguments passed to the application, this
|
||||
also includes the internal arguments. */
|
||||
|
||||
HARBOUR HB___ARGC( void )
|
||||
{
|
||||
hb_retni( s_argc - 1 );
|
||||
}
|
||||
|
||||
/* Returns a command line argument passed to the application. Calling it with
|
||||
the parameter zero, it will return the name of the executable, as written
|
||||
in the command line. */
|
||||
|
||||
HARBOUR HB___ARGV( void )
|
||||
{
|
||||
if( ISNUM( 1 ) )
|
||||
{
|
||||
int argc = hb_parni( 1 );
|
||||
|
||||
hb_retc( ( argc >= 0 && argc < s_argc ) ? s_argv[ argc ] : "" );
|
||||
}
|
||||
else
|
||||
hb_retc( "" );
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
void hb_cmdargTEST( void )
|
||||
{
|
||||
char * pszArg;
|
||||
|
||||
printf("INFO: %i\n", hb_cmdargCheck( "INFO" ) );
|
||||
printf(" F: %s\n", pszArg = hb_cmdargString( "F" ) ); if( pszArg ) hb_xfree( pszArg );
|
||||
printf(" Fn: %i\n", hb_cmdargNum( "F" ) );
|
||||
printf("TEMP: %s\n", pszArg = hb_cmdargString( "TEMP" ) ); if( pszArg ) hb_xfree( pszArg );
|
||||
|
||||
printf("INFO: %i\n", hb_cmdargCheck( "INFO" ) );
|
||||
printf(" F: %s\n", pszArg = hb_cmdargString( "F" ) ); if( pszArg ) hb_xfree( pszArg );
|
||||
printf(" Fn: %i\n", hb_cmdargNum( "F" ) );
|
||||
printf("TEMP: %s\n", pszArg = hb_cmdargString( "TEMP" ) ); if( pszArg ) hb_xfree( pszArg );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -33,6 +33,18 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* The following parts are Copyright of the individual authors.
|
||||
* www - http://www.harbour-project.org
|
||||
*
|
||||
* Copyright 1999 Victor Szel <info@szelvesz.hu>
|
||||
* HB_WORD()
|
||||
* HB___XHELP()
|
||||
*
|
||||
* See doc/license.txt for licensing terms.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MPW__
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
@@ -68,7 +80,7 @@ static void hb_vmSwapAlias( void ); /* swaps items on the eval stack an
|
||||
static ERRCODE hb_vmSelectWorkarea( PHB_ITEM ); /* select the workarea using a given item or a substituted value */
|
||||
|
||||
static void hb_vmDoInitStatics( void ); /* executes all _INITSTATICS functions */
|
||||
static void hb_vmDoInitFunctions( int argc, char * argv[] ); /* executes all defined PRGs INIT functions */
|
||||
static void hb_vmDoInitFunctions( void ); /* executes all defined PRGs INIT functions */
|
||||
static void hb_vmDoExitFunctions( void ); /* executes all defined PRGs EXIT functions */
|
||||
static void hb_vmReleaseLocalSymbols( void ); /* releases the memory of the local symbols linked list */
|
||||
|
||||
@@ -145,10 +157,10 @@ static USHORT s_uiActionRequest = 0;
|
||||
|
||||
int main( int argc, char * argv[] )
|
||||
{
|
||||
int i;
|
||||
|
||||
HB_DEBUG( "main\n" );
|
||||
|
||||
hb_cmdargInit( argc, argv );
|
||||
|
||||
/* initialize internal data structures */
|
||||
aStatics.type = IT_NIL;
|
||||
stack.Return.type = IT_NIL;
|
||||
@@ -165,29 +177,71 @@ int main( int argc, char * argv[] )
|
||||
#endif
|
||||
hb_vmSymbolInit_RT(); /* initialize symbol table with runtime support functions */
|
||||
|
||||
/* Check for some internal switches */
|
||||
|
||||
if( hb_cmdargCheck( "INFO" ) )
|
||||
{
|
||||
char * pszVersion = hb_version( 1 );
|
||||
|
||||
printf( pszVersion );
|
||||
printf( hb_consoleGetNewLine() );
|
||||
|
||||
hb_xfree( pszVersion );
|
||||
}
|
||||
|
||||
/* Call functions that initializes static variables
|
||||
* Static variables have to be initialized before any INIT functions
|
||||
* because INIT function can use static variables
|
||||
*/
|
||||
hb_vmDoInitStatics();
|
||||
hb_vmDoInitFunctions( argc, argv ); /* process defined INIT functions */
|
||||
hb_vmDoInitFunctions(); /* process defined INIT functions */
|
||||
|
||||
#ifdef HARBOUR_START_PROCEDURE
|
||||
/* This is undocumented CA-Clipper, if there's a function called _APPMAIN
|
||||
it will be executed first. */
|
||||
{
|
||||
PHB_DYNS pDynSym = hb_dynsymFind( HARBOUR_START_PROCEDURE );
|
||||
PHB_DYNS pDynSym = hb_dynsymFind( "_APPMAIN" );
|
||||
|
||||
if( pDynSym )
|
||||
s_pSymStart = pDynSym->pSymbol;
|
||||
#ifdef HARBOUR_START_PROCEDURE
|
||||
else
|
||||
hb_errInternal( 9999, "Can\'t locate the starting procedure: \'%s\'", HARBOUR_START_PROCEDURE, NULL );
|
||||
}
|
||||
#endif
|
||||
{
|
||||
pDynSym = hb_dynsymFind( HARBOUR_START_PROCEDURE );
|
||||
|
||||
hb_vmPushSymbol( s_pSymStart ); /* pushes first FS_PUBLIC defined symbol to the stack */
|
||||
hb_vmPushNil(); /* places NIL at self */
|
||||
for( i = 1; i < argc; i++ ) /* places application parameters on the stack */
|
||||
hb_vmPushString( argv[ i ], strlen( argv[ i ] ) );
|
||||
hb_vmDo( argc - 1 ); /* invoke it with number of supplied parameters */
|
||||
if( pDynSym )
|
||||
s_pSymStart = pDynSym->pSymbol;
|
||||
else
|
||||
hb_errInternal( 9999, "Can\'t locate the starting procedure: \'%s\'", HARBOUR_START_PROCEDURE, NULL );
|
||||
}
|
||||
#else
|
||||
#ifndef HARBOUR_STRICT_CLIPPER_COMPATIBLE
|
||||
else
|
||||
hb_errInternal( 9999, "Starting procedure not found", NULL, NULL );
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
if( s_pSymStart )
|
||||
{
|
||||
int i;
|
||||
int iArgCount;
|
||||
|
||||
hb_vmPushSymbol( s_pSymStart ); /* pushes first FS_PUBLIC defined symbol to the stack */
|
||||
hb_vmPushNil(); /* places NIL at self */
|
||||
|
||||
iArgCount = 0;
|
||||
for( i = 1; i < argc; i++ ) /* places application parameters on the stack */
|
||||
{
|
||||
/* Filter out any parameters beginning with //, like //INFO */
|
||||
if( ! hb_cmdargIsInternal( argv[ i ] ) )
|
||||
{
|
||||
hb_vmPushString( argv[ i ], strlen( argv[ i ] ) );
|
||||
iArgCount++;
|
||||
}
|
||||
}
|
||||
|
||||
hb_vmDo( iArgCount ); /* invoke it with number of supplied parameters */
|
||||
}
|
||||
|
||||
hb_vmQuit();
|
||||
|
||||
@@ -2849,7 +2903,7 @@ static void hb_vmDoExitFunctions( void )
|
||||
} while( pLastSymbols );
|
||||
}
|
||||
|
||||
static void hb_vmDoInitFunctions( int argc, char * argv[] )
|
||||
static void hb_vmDoInitFunctions( void )
|
||||
{
|
||||
PSYMBOLS pLastSymbols = s_pSymbols;
|
||||
|
||||
@@ -2866,15 +2920,27 @@ static void hb_vmDoInitFunctions( int argc, char * argv[] )
|
||||
|
||||
if( scope == FS_INIT )
|
||||
{
|
||||
int argc = hb_cmdargARGC();
|
||||
char ** argv = hb_cmdargARGV();
|
||||
|
||||
int i;
|
||||
int iArgCount;
|
||||
|
||||
hb_vmPushSymbol( pLastSymbols->pModuleSymbols + ui );
|
||||
hb_vmPushNil();
|
||||
|
||||
iArgCount = 0;
|
||||
for( i = 1; i < argc; i++ ) /* places application parameters on the stack */
|
||||
hb_vmPushString( argv[ i ], strlen( argv[ i ] ) );
|
||||
{
|
||||
/* Filter out any parameters beginning with //, like //INFO */
|
||||
if( ! hb_cmdargIsInternal( argv[ i ] ) )
|
||||
{
|
||||
hb_vmPushString( argv[ i ], strlen( argv[ i ] ) );
|
||||
iArgCount++;
|
||||
}
|
||||
}
|
||||
|
||||
hb_vmDo( argc - 1 );
|
||||
hb_vmDo( iArgCount );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3181,7 +3247,7 @@ void hb_vmRequestCancel( void )
|
||||
|
||||
HARBOUR HB___XHELP( void )
|
||||
{
|
||||
PHB_DYNS pDynSym = hb_dynsymFindName( "HELP" );
|
||||
PHB_DYNS pDynSym = hb_dynsymFind( "HELP" );
|
||||
|
||||
if( pDynSym )
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user