From a31d12a9a09471faa8e6a4546169e73fdf25c0fb Mon Sep 17 00:00:00 2001 From: Ryszard Glab Date: Wed, 29 Oct 2003 19:38:11 +0000 Subject: [PATCH] Changelog 2003-10-29 20:15 UTC+0100 Ryszard Glab --- harbour/ChangeLog | 85 ++++++++++ harbour/doc/en/compiler.txt | 2 + harbour/include/hbapi.h | 2 +- harbour/include/hbapigt.h | 1 + harbour/include/hbcomp.h | 1 + harbour/include/hbexprb.c | 167 +++++++++--------- harbour/include/hbvm.h | 7 + harbour/source/compiler/cmdcheck.c | 4 + harbour/source/compiler/exproptb.c | 2 +- harbour/source/compiler/harbour.c | 1 + harbour/source/compiler/harbour.y | 1 + harbour/source/compiler/hbusage.c | 1 + harbour/source/macro/macrob.c | 2 +- harbour/source/rtl/gtapi.c | 9 +- harbour/source/rtl/gtcrs/Makefile | 7 + harbour/source/rtl/gtcrs/eterm.map | 61 +++++++ harbour/source/rtl/gtcrs/gtcrs.c | 3 +- harbour/source/rtl/gtcrs/kbdcrs.c | 251 ++++++++++++++++++---------- harbour/source/rtl/gtcrs/keymap.prg | 179 ++++++++++++++++++++ harbour/source/rtl/gtcrs/linux.map | 31 ++++ harbour/source/rtl/inkey.c | 47 +++--- harbour/source/vm/cmdarg.c | 55 +++++- harbour/source/vm/hvm.c | 40 +++-- harbour/tests/keywords.prg | 8 +- 24 files changed, 759 insertions(+), 208 deletions(-) create mode 100644 harbour/source/rtl/gtcrs/eterm.map create mode 100644 harbour/source/rtl/gtcrs/keymap.prg create mode 100644 harbour/source/rtl/gtcrs/linux.map diff --git a/harbour/ChangeLog b/harbour/ChangeLog index d15148ee94..c4d396a84c 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,91 @@ 2002-12-01 23:12 UTC+0100 Foo Bar */ +2003-10-29 20:15 UTC+0100 Ryszard Glab + * include/hbexprb.c + * source/compiler/exproptb.c + * source/macro/macrob.c + *fixed generation of pcode for {|| &var} + *see below + + * include/hbcomp.h + * source/compiler/cmdcheck.c + * source/compiler/harbour.c + * source/compiler/harbour.y + * source/compiler/hbusage.c + * doc/en/compiler.txt + *added support for DO WITH @variable + *a new compatibility flag -ks was added to enable support for + strings as array of bytes (it is enabled by default). The support + for strings as bytes array is disabled if you use -kc switch + (Clipper compatibility mode) + *when xbase mode is not used (-kc or -kch) then compiler doesn't + generate the pcode for these xbase extended features + For example: + memv:="2,3" + a:={1, &memv, 4} + will generate a runtime 'syntax error' without -kx switch + or will create an array with four elements if -kx was used. + The above rule will apply also for: + var[&index] + func( &argument ) + (expr1, ¯o ) + Notice that the xbase mode is enabled by default. + + * source/rtl/gtapi.c + *fixed GPF in hb_gtBox() when no string was passed + + * source/rtl/gtcrs/gtcrs.c + *improved recognition of xterm compatible terminals + + * source/rtl/gtcrs/Makefile + * source/rtl/gtcrs/kbdcrs.c + + source/rtl/gtcrs/keymap.prg + + source/rtl/gtcrs/eterm.map + + source/rtl/gtcrs/linux.map + *the support for runtime definition of keycodes mapping was added + (translation from terminal key sequences into INKEY() codes) + +eterm.map and linux.map are example files with keycode mapping + +HB_GT_KEYMAP() function was added + + * include/hbapi.h + *Changed declaration of hb_cmdargProcessVM() + + * include/hbapigt.h + * include/hbvm.h + * source/rtl/inkey.c + * source/vm/cmdarg.c + * source/vm/hvm.c + *new function hb_vmFlagEnabled() to query compatibility + at runtime + *new internal command line arguments were added to control + application at runtime: + //FLAGS:switches + this flag controls compatibility issues of the virtual + machine + Available switches: + c - Clipper compatibility + h - Harbour extensions (enabled by default) + s - enable support for strings as array of bytes (enabled + by default) + For example: + myapp //FLAGS:ch + will disable support for strings as array of bytes + + //CANCEL:key + //CANCELEX:keyex + this flag allows change the keycode of application cancel + request (usually Alt-C) - using normal INKEY() keycodes + or extended keycodes (CANCELEX) + For example: + myapp //CANCEL:304 + will change Alt-c into Alt-b for cancelling (Alt-c is used + to insert polish diactric letter) + + * tests/keywords.prg + *fixed to suppress warnings for FIELD and IN keywords if passed + by reference + 2003-10-25 14:45 UTC+0100 Ryszard Glab * include/hbexprb.c * source/compiler/exproptb.c diff --git a/harbour/doc/en/compiler.txt b/harbour/doc/en/compiler.txt index 0e61d1f1f5..96a0527795 100644 --- a/harbour/doc/en/compiler.txt +++ b/harbour/doc/en/compiler.txt @@ -80,6 +80,8 @@ * * /kr use runtime settings for the macro compiler * + * /ks enable support for strings as array of bytes (default) + * * /kx other xbase dialects extensions (default) * * /k? invoke help information diff --git a/harbour/include/hbapi.h b/harbour/include/hbapi.h index d1cd338d69..ac921aa219 100644 --- a/harbour/include/hbapi.h +++ b/harbour/include/hbapi.h @@ -466,7 +466,7 @@ extern BOOL hb_cmdargIsInternal( const char * szArg ); /* determine if a str 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) */ -extern void hb_cmdargProcessVM( void ); /* Check for command line internal arguments */ +extern ULONG hb_cmdargProcessVM( int*, int* ); /* Check for command line internal arguments */ /* Symbol management */ extern PHB_SYMB hb_symbolNew( char * szName ); /* create a new symbol */ diff --git a/harbour/include/hbapigt.h b/harbour/include/hbapigt.h index 4fc88dd54f..9b63059779 100644 --- a/harbour/include/hbapigt.h +++ b/harbour/include/hbapigt.h @@ -278,6 +278,7 @@ extern int hb_inkeyNext( HB_inkey_enum event_mask ); /* Return the extern void hb_inkeyPoll( void ); /* Poll the console keyboard to stuff the Harbour buffer */ extern void hb_inkeyReset( BOOL allocate ); /* Reset the Harbour keyboard buffer */ extern int hb_inkeyTranslate( int key, HB_inkey_enum event_make ); /* Translation extended codes to normal codes, if needed */ +extern void hb_inkeySetCancelKeys( int CancelKey, int CancelKeyEx ); /* Set keycodes for Cancel key (usually K_ALT_C) */ /* Mouse related declarations */ diff --git a/harbour/include/hbcomp.h b/harbour/include/hbcomp.h index 51470fc7ed..27942911c8 100644 --- a/harbour/include/hbcomp.h +++ b/harbour/include/hbcomp.h @@ -536,6 +536,7 @@ extern ULONG hb_comp_Supported; #define HB_COMPFLAG_HARBOUR 1 /* -kh */ #define HB_COMPFLAG_XBASE 2 /* -kx */ #define HB_COMPFLAG_HB_INLINE 4 /* -ki */ +#define HB_COMPFLAG_ARRSTR 8 /* -ks strings as array of bytes */ #define HB_COMPFLAG_RT_MACRO 64 /* -kr */ #ifdef HB_MACRO_SUPPORT diff --git a/harbour/include/hbexprb.c b/harbour/include/hbexprb.c index 051bb2a5f4..56fdcc2268 100644 --- a/harbour/include/hbexprb.c +++ b/harbour/include/hbexprb.c @@ -516,48 +516,48 @@ static void hb_compExprCodeblockEarly( HB_EXPR_PTR pSelf ) { HB_EXPR_PTR pExpr; - HB_EXPR_PCODE0( hb_compCodeBlockStart ); - /* check first expression */ pExpr = pSelf->value.asCodeblock.pExprList; if( pExpr->ExprType == HB_ET_MACRO && pExpr->value.asMacro.cMacroOp ) { - /* simple macro variable expansion: &variable - * 'szMacro' is a variable name - * {|| &variable} => &( '{||' + variable +'}' ) - */ - HB_EXPR_PTR pVar, pNew; + /* simple macro variable expansion: &variable + * 'szMacro' is a variable name + * {|| &variable} => &( '{||' + variable +'}' ) + */ + HB_EXPR_PTR pVar, pNew; - pVar = hb_compExprNewVar( pExpr->value.asMacro.szMacro ); - pNew = hb_compExprNewString( "{||" ); - pNew = hb_compExprSetOperand( hb_compExprNewPlus( pNew ), pVar ); - pNew = hb_compExprSetOperand( hb_compExprNewPlus( pNew ), hb_compExprNewString( "}" ) ); - pNew = hb_compExprNewMacro( pNew, 0, NULL ); - HB_EXPR_USE( pNew, HB_EA_PUSH_PCODE ); - hb_compExprDelete( pNew ); + pVar = hb_compExprNewVar( pExpr->value.asMacro.szMacro ); + pNew = hb_compExprNewString( "{||" ); + pNew = hb_compExprSetOperand( hb_compExprNewPlus( pNew ), pVar ); + pNew = hb_compExprSetOperand( hb_compExprNewPlus( pNew ), hb_compExprNewString( "}" ) ); + pNew = hb_compExprNewMacro( pNew, 0, NULL ); + HB_EXPR_USE( pNew, HB_EA_PUSH_PCODE ); + hb_compExprDelete( pNew ); } else { - /* everything else is macro compiled at runtime - * {|| &variable+1} => &( '{|| &variable+1}' ) - */ - HB_EXPR_PTR pNew; - char *szDupl; - BOOL bUseTextSubst; + /* everything else is macro compiled at runtime + * {|| &variable+1} => &( '{|| &variable+1}' ) + */ + HB_EXPR_PTR pNew; + char *szDupl; + BOOL bUseTextSubst; - szDupl = hb_strupr( hb_strdup( pSelf->value.asCodeblock.string ) ); - if( !hb_compExprIsValidMacro( szDupl, &bUseTextSubst ) ) - { - hb_compErrorCodeblock( pSelf->value.asCodeblock.string ); - hb_compErrorMacro( pSelf->value.asCodeblock.string ); - } - hb_xfree( szDupl ); - pNew = hb_compExprNewMacro( hb_compExprNewString(pSelf->value.asCodeblock.string), 0, NULL ); - HB_EXPR_USE( pNew, HB_EA_PUSH_PCODE ); - hb_compExprDelete( pNew ); + HB_EXPR_PCODE0( hb_compCodeBlockStart ); + + szDupl = hb_strupr( hb_strdup( pSelf->value.asCodeblock.string ) ); + if( !hb_compExprIsValidMacro( szDupl, &bUseTextSubst ) ) + { + hb_compErrorCodeblock( pSelf->value.asCodeblock.string ); + hb_compErrorMacro( pSelf->value.asCodeblock.string ); + } + hb_xfree( szDupl ); + pNew = hb_compExprNewMacro( hb_compExprNewString(pSelf->value.asCodeblock.string), 0, NULL ); + HB_EXPR_USE( pNew, HB_EA_PUSH_PCODE ); + hb_compExprDelete( pNew ); + HB_EXPR_PCODE0( hb_compCodeBlockStop ); } - HB_EXPR_PCODE0( hb_compCodeBlockStop ); } #endif /*HB_MACRO_SUPPORT*/ #endif /*SIMPLEX*/ @@ -1121,28 +1121,29 @@ static HB_EXPR_FUNC( hb_compExprUseArrayAt ) case HB_EA_POP_PCODE: { - #ifndef HB_C52_STRICT BOOL bRemoveRef = FALSE; - - /* to manage strings as bytes arrays, they must be pushed by reference */ - /* arrays also are passed by reference */ - if( pSelf->value.asList.pExprList->ExprType == HB_ET_VARIABLE ) - { - pSelf->value.asList.pExprList->ExprType = HB_ET_VARREF; - bRemoveRef = TRUE; - } - #endif +/* #ifndef HB_C52_STRICT */ + if( HB_COMP_ISSUPPORTED(HB_COMPFLAG_ARRSTR) ) + /* to manage strings as bytes arrays, they must be pushed by reference */ + /* arrays also are passed by reference */ + if( pSelf->value.asList.pExprList->ExprType == HB_ET_VARIABLE ) + { + pSelf->value.asList.pExprList->ExprType = HB_ET_VARREF; + bRemoveRef = TRUE; + } +/* #endif */ HB_EXPR_USE( pSelf->value.asList.pExprList, HB_EA_PUSH_PCODE ); HB_EXPR_USE( pSelf->value.asList.pIndex, HB_EA_PUSH_PCODE ); HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_ARRAYPOP ); - #ifndef HB_C52_STRICT - if( bRemoveRef ) - { - pSelf->value.asList.pExprList->ExprType = HB_ET_VARIABLE; - } - #endif +/* #ifndef HB_C52_STRICT */ + if( HB_COMP_ISSUPPORTED(HB_COMPFLAG_ARRSTR) ) + if( bRemoveRef ) + { + pSelf->value.asList.pExprList->ExprType = HB_ET_VARIABLE; + } +/* #endif */ } break; @@ -1211,16 +1212,18 @@ static HB_EXPR_FUNC( hb_compExprUseMacro ) else if( pSelf->value.asMacro.SubType != HB_ET_MACRO_ALIASED ) { - if( pSelf->value.asMacro.SubType & HB_ET_MACRO_ARGLIST ) - { - /* funCall( ¯o ) - */ - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROPUSHARG ); + if( HB_COMP_ISSUPPORTED(HB_COMPFLAG_XBASE) ) + { + if( pSelf->value.asMacro.SubType & HB_ET_MACRO_ARGLIST ) + { + /* funCall( ¯o ) + */ + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROPUSHARG ); - /* Always add add byte to pcode indicating requested macro compiler flag. */ - #if defined( HB_MACRO_SUPPORT ) + /* Always add add byte to pcode indicating requested macro compiler flag. */ + #if defined( HB_MACRO_SUPPORT ) HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_COMPFLAG_RT_MACRO ); - #else + #else HB_EXPR_GENPCODE1( hb_compGenPData1, ( ( hb_comp_Supported & HB_COMPFLAG_HARBOUR ? HB_SM_HARBOUR : 0 ) | @@ -1229,34 +1232,38 @@ static HB_EXPR_FUNC( hb_compExprUseMacro ) ( hb_comp_Supported & HB_COMPFLAG_RT_MACRO ? HB_SM_RT_MACRO : 0 ) ) ); - #endif + #endif - /* Generate push symbol for the symbol the possible extra macro arguments will be for. */ - HB_EXPR_USE( pSelf->value.asMacro.pFunCall->value.asFunCall.pFunName, HB_EA_PUSH_PCODE ); - } - else if( pSelf->value.asMacro.SubType & HB_ET_MACRO_LIST ) - { - /* { ¯o } - */ - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROPUSHLIST ); - } - else if( pSelf->value.asMacro.SubType & HB_ET_MACRO_INDEX ) - { - /* var[ ¯o ] */ - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROPUSHINDEX ); - } - else if( pSelf->value.asMacro.SubType & HB_ET_MACRO_PARE ) - { - /* var := (somevalue, ¯o) - in xbase compatibility mode - * EVAL( {|| ¯o} ) - in all cases - */ - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROPUSHPARE ); - } - else - { + /* Generate push symbol for the symbol the possible extra macro arguments will be for. */ + HB_EXPR_USE( pSelf->value.asMacro.pFunCall->value.asFunCall.pFunName, HB_EA_PUSH_PCODE ); + } + else if( pSelf->value.asMacro.SubType & HB_ET_MACRO_LIST ) + { + /* { ¯o } + */ + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROPUSHLIST ); + } + else if( pSelf->value.asMacro.SubType & HB_ET_MACRO_INDEX ) + { + /* var[ ¯o ] */ + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROPUSHINDEX ); + } + else if( pSelf->value.asMacro.SubType & HB_ET_MACRO_PARE ) + { + /* var := (somevalue, ¯o) - in xbase compatibility mode + * EVAL( {|| ¯o} ) - in all cases + */ + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROPUSHPARE ); + } + else + { + /* usual ¯o */ + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROPUSH ); + } + } + else /* usual ¯o */ HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_MACROPUSH ); - } } if( ( pSelf->value.asMacro.SubType != HB_ET_MACRO_SYMBOL ) && diff --git a/harbour/include/hbvm.h b/harbour/include/hbvm.h index ef8fa13e81..c51c4b8b22 100644 --- a/harbour/include/hbvm.h +++ b/harbour/include/hbvm.h @@ -105,6 +105,13 @@ extern void hb_vmPushDate( long lDate ); /* pushes a long date onto the sta extern void hb_vmPushSymbol( PHB_SYMB pSym ); /* pushes a function pointer onto the stack */ extern void hb_vmPushPointer( void * ); /* push an item of HB_IT_POINTER type */ +/* various flags for supported features +*/ +#define HB_VMFLAG_HARBOUR 1 /* enable Harbour extension */ +#define HB_VMFLAG_ARRSTR 2 /* support for string as array of bytes -ks */ + +extern ULONG hb_vmFlagEnabled( ULONG flag); + #if defined(HB_EXTERN_C) } #endif diff --git a/harbour/source/compiler/cmdcheck.c b/harbour/source/compiler/cmdcheck.c index f3feb52834..94860dc00a 100644 --- a/harbour/source/compiler/cmdcheck.c +++ b/harbour/source/compiler/cmdcheck.c @@ -654,6 +654,10 @@ void hb_compChkEnvironVar( char * szSwitch ) hb_comp_Supported |= HB_COMPFLAG_RT_MACRO; break; + case 's': + hb_comp_Supported |= HB_COMPFLAG_ARRSTR; + break; + default: hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_BADOPTION, s, NULL ); break; diff --git a/harbour/source/compiler/exproptb.c b/harbour/source/compiler/exproptb.c index a86698e1d2..2d17d59091 100644 --- a/harbour/source/compiler/exproptb.c +++ b/harbour/source/compiler/exproptb.c @@ -5,6 +5,6 @@ /* hbexprb.c is also included from ../macro/macro.c * However it produces a slighty different code if used in * macro compiler (there is an additional parameter passed to some functions) - * 1.6 - ignore this magic number - this is used to force compilation + * 1.7 - ignore this magic number - this is used to force compilation */ #include "hbexprb.c" diff --git a/harbour/source/compiler/harbour.c b/harbour/source/compiler/harbour.c index 599ae23e37..fcc0186783 100644 --- a/harbour/source/compiler/harbour.c +++ b/harbour/source/compiler/harbour.c @@ -191,6 +191,7 @@ int main( int argc, char * argv[] ) hb_comp_Supported = HB_COMPFLAG_HARBOUR; hb_comp_Supported |= HB_COMPFLAG_XBASE; hb_comp_Supported |= HB_COMPFLAG_HB_INLINE; + hb_comp_Supported |= HB_COMPFLAG_ARRSTR; /* First check the environment variables */ hb_compChkCompilerSwitch( 0, NULL ); diff --git a/harbour/source/compiler/harbour.y b/harbour/source/compiler/harbour.y index 0e98e70cdf..0f7651f8cb 100644 --- a/harbour/source/compiler/harbour.y +++ b/harbour/source/compiler/harbour.y @@ -1676,6 +1676,7 @@ DoArgList : ',' { $$ = hb_compExprAddListExpr( hb_compExp ; DoArgument : IdentName { $$ = hb_compExprNewVarRef( $1 ); } + | '@' IdentName { $$ = hb_compExprNewVarRef( $2 ); } | '@' IdentName '(' DummyArgList ')' { $$ = hb_compExprNewFunRef( $2 ); } | SimpleExpression { $$ = $1; } | PareExpList { $$ = $1; } diff --git a/harbour/source/compiler/hbusage.c b/harbour/source/compiler/hbusage.c index 87a52cd36c..d5f2c2e69b 100644 --- a/harbour/source/compiler/hbusage.c +++ b/harbour/source/compiler/hbusage.c @@ -119,6 +119,7 @@ void hb_compPrintModes( void ) "\n h Harbour mode (default)", "\n i enable support for HB_INLINE", "\n r runtime settings enabled", + "\n c string as bytes array enabled", "\n x extended xbase mode", "\n ? this info", "\n" diff --git a/harbour/source/macro/macrob.c b/harbour/source/macro/macrob.c index a0aad4042a..cddf0da718 100644 --- a/harbour/source/macro/macrob.c +++ b/harbour/source/macro/macrob.c @@ -5,7 +5,7 @@ /* hbexprb.c is also included from ../compiler/exproptb.c * However it produces a slighty different code if used in * macro compiler (there is an additional parameter passed to some functions) - * 4 - ignore this magic number - this is used to force compilation + * 1.6 - ignore this magic number - this is used to force compilation */ #define HB_MACRO_SUPPORT diff --git a/harbour/source/rtl/gtapi.c b/harbour/source/rtl/gtapi.c index 008cc1c81b..82ce7aabba 100644 --- a/harbour/source/rtl/gtapi.c +++ b/harbour/source/rtl/gtapi.c @@ -179,8 +179,13 @@ USHORT hb_gtBox( SHORT Top, SHORT Left, SHORT Bottom, SHORT Right, BYTE * pbyFra short [vszakats] */ cPadChar = ' '; - for( tmp = 0; *pbyFrame && tmp < 9; tmp++ ) - cPadChar = szBox[ tmp ] = *pbyFrame++; + if( pbyFrame ) + { + for( tmp = 0; *pbyFrame && tmp < 9; tmp++ ) + cPadChar = szBox[ tmp ] = *pbyFrame++; + } + else + tmp = 0; while( tmp < 8 ) szBox[ tmp++ ] = cPadChar; szBox[ tmp ] = '\0'; diff --git a/harbour/source/rtl/gtcrs/Makefile b/harbour/source/rtl/gtcrs/Makefile index e39d0241d6..3936d166ee 100644 --- a/harbour/source/rtl/gtcrs/Makefile +++ b/harbour/source/rtl/gtcrs/Makefile @@ -9,6 +9,13 @@ C_SOURCES=\ mousecrs.c \ kbdcrs.c \ +PRG_SOURCES=\ + keymap.prg + +PRG_HEADERS=\ + eterm.map \ + linux.map \ + LIBNAME=gtcrs include $(TOP)$(ROOT)config/lib.cf diff --git a/harbour/source/rtl/gtcrs/eterm.map b/harbour/source/rtl/gtcrs/eterm.map new file mode 100644 index 0000000000..2863c6c542 --- /dev/null +++ b/harbour/source/rtl/gtcrs/eterm.map @@ -0,0 +1,61 @@ +// +// $Id$ +// +//Mapping of Eterm key sequences on Slackware8.1 into Harbour INKEY() codes +//Ctrl-PgDn +30:\033[6^ +//Ctrl-PgUp +31:\033[5^ +//Ctrl-Up +397:\033Oa +//Ctrl-Down +401:\033Ob +//Ctrl-Right +2:\033Oc +//Ctrl-Left +26:\033Od +//Ctrl-Home +29:\033[7^ +//Ctrl-End +23:\033[8^ +//Ctrl-Ins +402:\033[2^ +//Alt-Ins +418:\033\033[2~ +//Alt-Del +419:\033\033[3~ +//Alt-Home +407:\033\033[7~ +//Alt-End +415:\033\033[8~ +//Ctrl-F1..F10 +-20:\033[11^ +-21:\033[12^ +-22:\033[13^ +-23:\033[14^ +-24:\033[15^ +-25:\033[17^ +-26:\033[18^ +-27:\033[19^ +-28:\033[20^ +-29:\033[21^ +//Ctrl-F11 +-44:\033[23^ +//Ctrl-F12 +-45:\033[24^ +//Shift-F11 +-42:\033[23$ +//Shift-F12 +-43:\033[24$ +//Shift-Home +1:\033[7$ +//Shift-End +6:\033[8$ +//Alt-Esc +257:\033\033 +//BackSpace +8:\x7F +//Alt-BackSpace +270:\033\x7F +//Alt-Space as Alt-Tab +421:\033\x20 diff --git a/harbour/source/rtl/gtcrs/gtcrs.c b/harbour/source/rtl/gtcrs/gtcrs.c index cd0bacf042..34343c6fb6 100644 --- a/harbour/source/rtl/gtcrs/gtcrs.c +++ b/harbour/source/rtl/gtcrs/gtcrs.c @@ -128,7 +128,8 @@ static void hb_gt_terminal_Init( void ) { char * tmp = hb_getenv( "TERM" ); - s_under_xterm = tmp && tmp[ 0 ] != '\0' && ( strncmp( tmp, "xterm", 5 ) == 0 ); + tmp = hb_strupr( tmp ); + s_under_xterm = tmp && tmp[ 0 ] != '\0' && ( strstr( tmp, "TERM" ) != NULL ); if( tmp ) hb_xfree( ( void * ) tmp ); } diff --git a/harbour/source/rtl/gtcrs/kbdcrs.c b/harbour/source/rtl/gtcrs/kbdcrs.c index 86f6f50d2c..9ae190c887 100644 --- a/harbour/source/rtl/gtcrs/kbdcrs.c +++ b/harbour/source/rtl/gtcrs/kbdcrs.c @@ -64,7 +64,9 @@ extern int hb_mouse_xevent( char *, HB_inkey_enum ); extern int hb_mouse_key( void ); static void hb_gt_Add_terminfo_keymap( int, char * ); -static void hb_gt_Add_keymap( int, char * ); +static void hb_gt_Add_alt_terminfo_keymap( int, char * ); +static void hb_gt_Add_keymap( int, char *, BOOL ); +static void hb_gt_ClearKeymap( void ); /* max number of characters in a keymapped string */ #define HB_MAX_KEYMAP_CHARS 16 @@ -73,6 +75,7 @@ struct key_map_struc { int inkey_code; int length; + BOOL bFreemem; char * key_string; struct key_map_struc * Next; }; @@ -95,7 +98,8 @@ void hb_gt_keyboard_Init( void ) { char * tmp = hb_getenv( "TERM" ); - s_under_xterm = tmp && tmp[ 0 ] != '\0' && ( strncmp( tmp, "xterm", 5 ) == 0 ); + tmp = hb_strupr( tmp ); + s_under_xterm = tmp && tmp[ 0 ] != '\0' && ( strstr( tmp, "TERM" ) != NULL ); if( tmp ) hb_xfree( ( void * ) tmp ); } @@ -119,8 +123,8 @@ void hb_gt_keyboard_Init( void ) /* workaraound for xterm bug */ hb_gt_Add_terminfo_keymap( K_UP, "cuu1" ); hb_gt_Add_terminfo_keymap( K_RIGHT, "cuf1" ); - hb_gt_Add_keymap( K_LEFT, "\033[D" ); - hb_gt_Add_keymap( K_DOWN, "\033[B" ); + hb_gt_Add_keymap( K_LEFT, "\033[D", FALSE ); + hb_gt_Add_keymap( K_DOWN, "\033[B", FALSE ); } else { @@ -173,97 +177,103 @@ void hb_gt_keyboard_Init( void ) hb_gt_Add_terminfo_keymap( K_PGUP, "ka3" ); hb_gt_Add_terminfo_keymap( K_END, "kc1" ); hb_gt_Add_terminfo_keymap( K_PGDN, "kc3" ); - hb_gt_Add_keymap( K_ALT_A, "\033a" ); - hb_gt_Add_keymap( K_ALT_A, "\033A" ); - hb_gt_Add_keymap( K_ALT_B, "\033b" ); - hb_gt_Add_keymap( K_ALT_B, "\033B" ); - hb_gt_Add_keymap( K_ALT_C, "\033c" ); - hb_gt_Add_keymap( K_ALT_C, "\033C" ); - hb_gt_Add_keymap( K_ALT_D, "\033d" ); - hb_gt_Add_keymap( K_ALT_D, "\033D" ); - hb_gt_Add_keymap( K_ALT_E, "\033e" ); - hb_gt_Add_keymap( K_ALT_E, "\033E" ); - hb_gt_Add_keymap( K_ALT_F, "\033f" ); - hb_gt_Add_keymap( K_ALT_F, "\033F" ); - hb_gt_Add_keymap( K_ALT_G, "\033g" ); - hb_gt_Add_keymap( K_ALT_G, "\033G" ); - hb_gt_Add_keymap( K_ALT_H, "\033h" ); - hb_gt_Add_keymap( K_ALT_H, "\033H" ); - hb_gt_Add_keymap( K_ALT_I, "\033i" ); - hb_gt_Add_keymap( K_ALT_I, "\033I" ); - hb_gt_Add_keymap( K_ALT_J, "\033j" ); - hb_gt_Add_keymap( K_ALT_J, "\033J" ); - hb_gt_Add_keymap( K_ALT_K, "\033k" ); - hb_gt_Add_keymap( K_ALT_K, "\033K" ); - hb_gt_Add_keymap( K_ALT_L, "\033l" ); - hb_gt_Add_keymap( K_ALT_L, "\033L" ); - hb_gt_Add_keymap( K_ALT_M, "\033m" ); - hb_gt_Add_keymap( K_ALT_M, "\033M" ); - hb_gt_Add_keymap( K_ALT_N, "\033n" ); - hb_gt_Add_keymap( K_ALT_N, "\033N" ); - hb_gt_Add_keymap( K_ALT_O, "\033o" ); - hb_gt_Add_keymap( K_ALT_O, "\033O" ); - hb_gt_Add_keymap( K_ALT_P, "\033p" ); - hb_gt_Add_keymap( K_ALT_P, "\033P" ); - hb_gt_Add_keymap( K_ALT_Q, "\033q" ); - hb_gt_Add_keymap( K_ALT_Q, "\033Q" ); - hb_gt_Add_keymap( K_ALT_R, "\033r" ); - hb_gt_Add_keymap( K_ALT_R, "\033R" ); - hb_gt_Add_keymap( K_ALT_S, "\033s" ); - hb_gt_Add_keymap( K_ALT_S, "\033S" ); - hb_gt_Add_keymap( K_ALT_T, "\033t" ); - hb_gt_Add_keymap( K_ALT_T, "\033T" ); - hb_gt_Add_keymap( K_ALT_U, "\033u" ); - hb_gt_Add_keymap( K_ALT_U, "\033U" ); - hb_gt_Add_keymap( K_ALT_V, "\033v" ); - hb_gt_Add_keymap( K_ALT_V, "\033V" ); - hb_gt_Add_keymap( K_ALT_W, "\033w" ); - hb_gt_Add_keymap( K_ALT_W, "\033W" ); - hb_gt_Add_keymap( K_ALT_X, "\033x" ); - hb_gt_Add_keymap( K_ALT_X, "\033X" ); - hb_gt_Add_keymap( K_ALT_Y, "\033y" ); - hb_gt_Add_keymap( K_ALT_Y, "\033Y" ); - hb_gt_Add_keymap( K_ALT_Z, "\033z" ); - hb_gt_Add_keymap( K_ALT_Z, "\033Z" ); - hb_gt_Add_keymap( K_ALT_1, "\0331" ); - hb_gt_Add_keymap( K_ALT_2, "\0332" ); - hb_gt_Add_keymap( K_ALT_3, "\0333" ); - hb_gt_Add_keymap( K_ALT_4, "\0334" ); - hb_gt_Add_keymap( K_ALT_5, "\0335" ); - hb_gt_Add_keymap( K_ALT_6, "\0336" ); - hb_gt_Add_keymap( K_ALT_7, "\0337" ); - hb_gt_Add_keymap( K_ALT_8, "\0338" ); - hb_gt_Add_keymap( K_ALT_9, "\0339" ); - hb_gt_Add_keymap( K_ALT_0, "\0330" ); - hb_gt_Add_keymap( K_ALT_ENTER, "\033\n" ); - hb_gt_Add_keymap( K_ALT_EQUALS, "\033=" ); + hb_gt_Add_keymap( K_ALT_A, "\033a", FALSE ); + hb_gt_Add_keymap( K_ALT_A, "\033A", FALSE ); + hb_gt_Add_keymap( K_ALT_B, "\033b", FALSE ); + hb_gt_Add_keymap( K_ALT_B, "\033B", FALSE ); + hb_gt_Add_keymap( K_ALT_C, "\033c", FALSE ); + hb_gt_Add_keymap( K_ALT_C, "\033C", FALSE ); + hb_gt_Add_keymap( K_ALT_D, "\033d", FALSE ); + hb_gt_Add_keymap( K_ALT_D, "\033D", FALSE ); + hb_gt_Add_keymap( K_ALT_E, "\033e", FALSE ); + hb_gt_Add_keymap( K_ALT_E, "\033E", FALSE ); + hb_gt_Add_keymap( K_ALT_F, "\033f", FALSE ); + hb_gt_Add_keymap( K_ALT_F, "\033F", FALSE ); + hb_gt_Add_keymap( K_ALT_G, "\033g", FALSE ); + hb_gt_Add_keymap( K_ALT_G, "\033G", FALSE ); + hb_gt_Add_keymap( K_ALT_H, "\033h", FALSE ); + hb_gt_Add_keymap( K_ALT_H, "\033H", FALSE ); + hb_gt_Add_keymap( K_ALT_I, "\033i", FALSE ); + hb_gt_Add_keymap( K_ALT_I, "\033I", FALSE ); + hb_gt_Add_keymap( K_ALT_J, "\033j", FALSE ); + hb_gt_Add_keymap( K_ALT_J, "\033J", FALSE ); + hb_gt_Add_keymap( K_ALT_K, "\033k", FALSE ); + hb_gt_Add_keymap( K_ALT_K, "\033K", FALSE ); + hb_gt_Add_keymap( K_ALT_L, "\033l", FALSE ); + hb_gt_Add_keymap( K_ALT_L, "\033L", FALSE ); + hb_gt_Add_keymap( K_ALT_M, "\033m", FALSE ); + hb_gt_Add_keymap( K_ALT_M, "\033M", FALSE ); + hb_gt_Add_keymap( K_ALT_N, "\033n", FALSE ); + hb_gt_Add_keymap( K_ALT_N, "\033N", FALSE ); + hb_gt_Add_keymap( K_ALT_O, "\033o", FALSE ); + hb_gt_Add_keymap( K_ALT_O, "\033O", FALSE ); + hb_gt_Add_keymap( K_ALT_P, "\033p", FALSE ); + hb_gt_Add_keymap( K_ALT_P, "\033P", FALSE ); + hb_gt_Add_keymap( K_ALT_Q, "\033q", FALSE ); + hb_gt_Add_keymap( K_ALT_Q, "\033Q", FALSE ); + hb_gt_Add_keymap( K_ALT_R, "\033r", FALSE ); + hb_gt_Add_keymap( K_ALT_R, "\033R", FALSE ); + hb_gt_Add_keymap( K_ALT_S, "\033s", FALSE ); + hb_gt_Add_keymap( K_ALT_S, "\033S", FALSE ); + hb_gt_Add_keymap( K_ALT_T, "\033t", FALSE ); + hb_gt_Add_keymap( K_ALT_T, "\033T", FALSE ); + hb_gt_Add_keymap( K_ALT_U, "\033u", FALSE ); + hb_gt_Add_keymap( K_ALT_U, "\033U", FALSE ); + hb_gt_Add_keymap( K_ALT_V, "\033v", FALSE ); + hb_gt_Add_keymap( K_ALT_V, "\033V", FALSE ); + hb_gt_Add_keymap( K_ALT_W, "\033w", FALSE ); + hb_gt_Add_keymap( K_ALT_W, "\033W", FALSE ); + hb_gt_Add_keymap( K_ALT_X, "\033x", FALSE ); + hb_gt_Add_keymap( K_ALT_X, "\033X", FALSE ); + hb_gt_Add_keymap( K_ALT_Y, "\033y", FALSE ); + hb_gt_Add_keymap( K_ALT_Y, "\033Y", FALSE ); + hb_gt_Add_keymap( K_ALT_Z, "\033z", FALSE ); + hb_gt_Add_keymap( K_ALT_Z, "\033Z", FALSE ); + hb_gt_Add_keymap( K_ALT_1, "\0331", FALSE ); + hb_gt_Add_keymap( K_ALT_2, "\0332", FALSE ); + hb_gt_Add_keymap( K_ALT_3, "\0333", FALSE ); + hb_gt_Add_keymap( K_ALT_4, "\0334", FALSE ); + hb_gt_Add_keymap( K_ALT_5, "\0335", FALSE ); + hb_gt_Add_keymap( K_ALT_6, "\0336", FALSE ); + hb_gt_Add_keymap( K_ALT_7, "\0337", FALSE ); + hb_gt_Add_keymap( K_ALT_8, "\0338", FALSE ); + hb_gt_Add_keymap( K_ALT_9, "\0339", FALSE ); + hb_gt_Add_keymap( K_ALT_0, "\0330", FALSE ); + hb_gt_Add_keymap( K_ALT_ENTER, "\033\n", FALSE ); + hb_gt_Add_keymap( K_ALT_EQUALS, "\033=", FALSE ); + hb_gt_Add_keymap( KP_ALT_SLASH, "\033/", FALSE ); + hb_gt_Add_keymap( KP_ALT_MINUS, "\033-", FALSE ); + /* + */ + hb_gt_Add_alt_terminfo_keymap( K_ALT_PGUP, "kpp" ); + hb_gt_Add_alt_terminfo_keymap( K_ALT_PGDN, "knp" ); + hb_gt_Add_alt_terminfo_keymap( K_ALT_F1, "kf1" ); + hb_gt_Add_alt_terminfo_keymap( K_ALT_F2, "kf2" ); + hb_gt_Add_alt_terminfo_keymap( K_ALT_F3, "kf3" ); + hb_gt_Add_alt_terminfo_keymap( K_ALT_F4, "kf4" ); + hb_gt_Add_alt_terminfo_keymap( K_ALT_F5, "kf5" ); + hb_gt_Add_alt_terminfo_keymap( K_ALT_F6, "kf6" ); + hb_gt_Add_alt_terminfo_keymap( K_ALT_F7, "kf7" ); + hb_gt_Add_alt_terminfo_keymap( K_ALT_F8, "kf8" ); + hb_gt_Add_alt_terminfo_keymap( K_ALT_F9, "kf9" ); + hb_gt_Add_alt_terminfo_keymap( K_ALT_F10, "kf10" ); + hb_gt_Add_alt_terminfo_keymap( K_ALT_F11, "kf11" ); + hb_gt_Add_alt_terminfo_keymap( K_ALT_F12, "kf12" ); + } void hb_gt_keyboard_Exit( void ) { - int i, k; - struct key_map_struc *tmp; - HB_TRACE(HB_TR_DEBUG, ("hb_kbd_Exit()")); - for( i = 0; i < HB_HASH_KEY; i++ ) - { - tmp = s_keymap_table[ i ]; - k = 0; - while( tmp ) - { - s_keymap_table[ i ] = tmp->Next; - hb_xfree( tmp ); - tmp = s_keymap_table[ i ]; - k++; - } - } + hb_gt_ClearKeymap(); } int hb_gt_ExtendedKeySupport() { return 0; } + int hb_gt_ReadKey( HB_inkey_enum eventmask ) { static char key_codes[ HB_MAX_KEYMAP_CHARS + 1 ]; /* buffer for multi-characters keycodes */ @@ -296,11 +306,13 @@ int hb_gt_ReadKey( HB_inkey_enum eventmask ) int i = 0; BYTE sum; - key_codes[ 0 ] = sum = ch; + key_codes[ 0 ] = ch; + sum = ch; while( ( ch = getch() ) != ERR && i <= HB_MAX_KEYMAP_CHARS ) { key_codes[ ++i ] = ch; -/*fprintf( stderr, "key%i=%i(%c)\n", i, ch, ch ); +/* +fprintf( stderr, "key%i=%i(%c)\n", i, ch, ch ); fflush( stderr ); */ sum += ch; @@ -354,7 +366,7 @@ fflush( stderr ); } -static void hb_gt_Add_keymap( int InkeyCode, char *key_string ) +static void hb_gt_Add_keymap( int InkeyCode, char *key_string, BOOL bxfree ) { struct key_map_struc * keymap; int iLength = strlen( key_string ); @@ -372,6 +384,7 @@ static void hb_gt_Add_keymap( int InkeyCode, char *key_string ) keymap->key_string = key_string; keymap->length = iLength; keymap->Next = NULL; + keymap->bFreemem = bxfree; if( s_keymap_table[ sum ] ) { @@ -391,5 +404,69 @@ static void hb_gt_Add_terminfo_keymap( int InkeyCode, char * capname ) code = tigetstr( capname ); if( ( code != NULL ) && ( code != ( char * ) -1 ) ) - hb_gt_Add_keymap( InkeyCode, code ); + hb_gt_Add_keymap( InkeyCode, code, FALSE ); +} + +static void hb_gt_Add_alt_terminfo_keymap( int InkeyCode, char * capname ) +{ + char * code; + + code = tigetstr( capname ); + if( ( code != NULL ) && ( code != ( char * ) -1 ) ) + { + int iLen = strlen( code ); + char *acode; + + acode = (char *)hb_xgrab( iLen+2 ); + acode[0] = '\033'; + memcpy( acode+1, code, iLen+1 ); + hb_gt_Add_keymap( InkeyCode, acode, TRUE ); + } +} + +static void hb_gt_ClearKeymap( void ) +{ + int i, k; + struct key_map_struc *tmp; + + for( i = 0; i < HB_HASH_KEY; i++ ) + { + tmp = s_keymap_table[ i ]; + k = 0; + while( tmp ) + { + s_keymap_table[ i ] = tmp->Next; + if( tmp->bFreemem ) + hb_xfree( tmp->key_string ); + hb_xfree( tmp ); + tmp = s_keymap_table[ i ]; + k++; + } + s_keymap_table[ i ] = NULL; + } +} + +/* + Add definition of nonstandard keycode mapping + for example: + HB_GT_ADDKEYMAP( 0 ) //Clear all default keymaps + HB_GT_ADDKEYMAP( 30,"\033[6^" ) //Ctrl+PgDn +*/ +HB_FUNC( HB_GT_ADDKEYMAP ) +{ + if( ISNUM( 1 ) && ISCHAR( 2 ) ) + { + char * code; + int len = hb_parclen(2); + + code = hb_xgrab( len + 1 ); + memcpy( code, hb_parc(2), len ); + code[ len ] = '\0'; + hb_gt_Add_keymap( hb_parni( 1 ), code, TRUE ); + } + else if( ISNUM( 1 ) ) + { + if( hb_parni(1) == 0 ) + hb_gt_ClearKeymap(); + } } diff --git a/harbour/source/rtl/gtcrs/keymap.prg b/harbour/source/rtl/gtcrs/keymap.prg new file mode 100644 index 0000000000..807ec08e3a --- /dev/null +++ b/harbour/source/rtl/gtcrs/keymap.prg @@ -0,0 +1,179 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * Harbour level definition of keyboard mapping + * + * Copyright 2003 Ryszard Glab + * 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, or (at your option) + * any later version. + * + * 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 software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). + * + * As a special exception, the Harbour Project gives permission for + * additional uses of the text contained in its release of Harbour. + * + * The exception is that, if you link the Harbour libraries 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 Harbour library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the Harbour + * Project under the name Harbour. If you copy code from other + * Harbour Project or Free Software Foundation releases into a copy of + * Harbour, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for Harbour, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * + */ + +/* + Load user specified keymap which was specified as a command line argument + //KEYMAP:full_path_to_file + + The keymap file should contine definitions of byte sequences that should be + translated into a single INKEY() value - a single line for a single + inkey code (see include/inkey.ch for valid INKEY codes\\\\\0. + Additionally it can contain "CLEAR' keyword to clear default keymaps + + Format of file + [CLEAR] + : + + Example: + CLEAR + //Ctrl-Pgup + 31:\033]5^ + //Ctrl-PgDn + 30:\033]6^ + + Keycodes can contain: + octal codes \012 (three digits) + or: + hex codes \x0F + or: + if you need a backslash then use '\\' +*/ + +PROCEDURE HB_GT_KEYMAP( cFile ) +LOCAL cKeymap, i, nKeys, cLine, nPos, nKey, nLen +LOCAL j, cCode, cChar, cChar2, nAsc + + IF( EMPTY(cFile) ) + cFile = HB_ARGSTRING( "KEYMAP" ) + ENDIF + IF( !EMPTY(cFile) ) + cKeymap := MEMOREAD( cFile ) + IF( !EMPTY(cKeymap) ) + nKeys := MLCOUNT( cKeymap ) + FOR i:=1 TO nKeys + cLine := ALLTRIM( MEMOLINE( cKeymap, 196, i ) ) + IF( !EMPTY(cLine) ) + IF( cLine = '//' ) + + ELSEIF( UPPER(cLine) = 'CLEAR' ) + HB_GT_ADDKEYMAP(0) // Clear all default keymaps + + ELSEIF((nPos:=AT(':',cLine)) > 0 ) + nKey := VAL( LEFT( cLine, nPos-1 ) ) + cLine := SUBSTR( cLine, nPos+1 ) + j :=1 + nLen := LEN(cLine) + cCode := "" + DO WHILE( j <= nLen ) + cChar := SUBSTR( cLine, j, 1 ) + cChar2 := SUBSTR(cLine,j+1,1) + IF( cChar == '\' .and. cChar2 $ '0123' ) + //OCTAL NUMBER < 377 (255 decimal) + nAsc := Octal2Num(SUBSTR(cLine,j+1,3) ) + IF( nAsc >= 0 ) + cCode += CHR( nAsc ) + ELSE + cCode := "" + EXIT //ignore errorneous code + ENDIF + j += 4 + ELSEIF( cChar2 == 'X' .OR. cChar2 == 'x' ) + //Hex number + nAsc := Hex2Num( SUBSTR(cLine, j+2, 2 ) ) + IF( nAsc >=0 ) + cCode += CHR( nAsc ) + ELSE + cCode := "" + EXIT //ignore errorneous code + ENDIF + j += 4 + ELSEIF( cChar2 == '\' ) + cCode += '\' + j += 2 + ELSE + cCode += cChar + ++j + ENDIF + ENDDO + IF( !EMPTY(cCode) .AND. nKey != 0 ) + HB_GT_ADDKEYMAP( nKey, cCode ) + ENDIF + ENDIF + ENDIF + NEXT + ENDIF + ENDIF + +RETURN + +// +STATIC FUNCTION Octal2Num( cOctal ) +LOCAL i, c, nMult:=1, nVal:=0 + + FOR i:=0 TO 2 + c := SUBSTR( cOctal, 3-i, 1 ) + IF( c $ '01234567' ) + nVal += ((ASC( c ) - ASC( '0' )) * nMult) + nMult *= 8 + ELSE + RETURN -1 + ENDIF + NEXT + +RETURN nVal + +STATIC FUNCTION Hex2Num( cOctal ) +LOCAL i, c, nMult:=1, nVal:=0 + + FOR i:=0 TO 1 + c := SUBSTR( cOctal, 2-i, 1 ) + IF( c $ '01234567' ) + nVal += ((ASC( c ) - ASC( '0' )) * nMult) + ELSEIF( c $ 'ABCDEF' ) + nVal += ((ASC( c ) - ASC( 'A' ) + 10 ) * nMult) + ELSE + RETURN -1 + ENDIF + nMult *= 16 + NEXT + +RETURN nVal diff --git a/harbour/source/rtl/gtcrs/linux.map b/harbour/source/rtl/gtcrs/linux.map new file mode 100644 index 0000000000..3dee12546c --- /dev/null +++ b/harbour/source/rtl/gtcrs/linux.map @@ -0,0 +1,31 @@ +// +// $Id$ +// +//Mapping of Linux console +//(Slackware 8.1 /usr/share/kbd/keymaps/i386/qwerty/pl2.map) +//Ctrl-PgUp +//31: +//Ctrl-PgDn +//30: +//Alt-Esc +257:\033\033 +//Alt-BackSpace +270:\033\x7F +//Alt-Space as Alt-Tab +421:\033\x20 +//Ctrl-Up +397:\033\033[A +//Ctrl-Down +401:\033\033[B +//Ctrl-Right +2:\033\033[C +//Ctrl-Left +26:\033\033[D +//Ctrl-Home +29:\033\033[1~ +//Ctrl-End +23:\033\033[4~ +//Ctrl-Ins +402:\033\033[2~ +//Ctrl-Del +403:\033\033[3~ diff --git a/harbour/source/rtl/inkey.c b/harbour/source/rtl/inkey.c index 556430d235..2c6a73932f 100644 --- a/harbour/source/rtl/inkey.c +++ b/harbour/source/rtl/inkey.c @@ -88,6 +88,8 @@ static int s_inkeyLast; /* Last key extracted from Harbour keyboard buf static BOOL s_inkeyPoll; /* Flag to override no polling when TYPEAHEAD is 0 */ static int s_inkeyForce; /* Variable to hold keyboard input when TYPEAHEAD is 0 */ static HB_inkey_enum s_eventmask; +static int s_InkeyAltC = K_ALT_C; +static int s_InkeyAltCEx = HB_K_ALT_C; static int hb_inkeyFetch( void ) /* Extract the next key from the keyboard buffer */ { @@ -212,25 +214,26 @@ void hb_inkeyPoll( void ) /* Poll the console keyboard to stuff the Harbour { int ch = hb_gt_ReadKey( s_eventmask ); - switch( ch ) - { - case HB_BREAK_FLAG: /* Check for Ctrl+Break */ - if( !hb_set.HB_SET_CANCEL ) ch = 0; /* Ignore if cancel disabled */ - case HB_K_ALT_C: /* Check for extended Alt+C */ - case K_ALT_C: /* Check for normal Alt+C */ - if( hb_set.HB_SET_CANCEL ) - { - ch = 3; /* Pretend it's a Ctrl+C */ - hb_vmRequestCancel();/* Request cancellation */ - } - break; - case HB_K_ALT_D: /* Check for extended Alt+D */ - case K_ALT_D: /* Check for normal Alt+D */ - if( hb_set.HB_SET_DEBUG ) - { - ch = 0; /* Make the keystroke disappear */ - hb_vmRequestDebug(); /* Request the debugger */ - } + if( (ch==s_InkeyAltC) || (ch==s_InkeyAltCEx) ) + { + if( hb_set.HB_SET_CANCEL ) + { + ch = 3; /* Pretend it's a Ctrl+C */ + hb_vmRequestCancel();/* Request cancellation */ + } + } + else if( ch == HB_BREAK_FLAG ) /* Check for Ctrl+Break */ + { + if( !hb_set.HB_SET_CANCEL ) + ch = 0; /* Ignore if cancel disabled */ + } + else if( (ch==K_ALT_D) || (ch==HB_K_ALT_D) ) + { + if( hb_set.HB_SET_DEBUG ) + { + ch = 0; /* Make the keystroke disappear */ + hb_vmRequestDebug(); /* Request the debugger */ + } } hb_inkeyPut( ch ); @@ -273,6 +276,12 @@ void hb_inkeyReset( BOOL allocate ) /* Reset the keyboard buffer */ } } +void hb_inkeySetCancelKeys( int CancelKey, int CancelKeyEx ) +{ + s_InkeyAltC = CancelKey; + s_InkeyAltCEx = CancelKeyEx; +} + HB_FUNC( INKEY ) { USHORT uiPCount = hb_pcount(); diff --git a/harbour/source/vm/cmdarg.c b/harbour/source/vm/cmdarg.c index 024eeb653d..83634b180c 100644 --- a/harbour/source/vm/cmdarg.c +++ b/harbour/source/vm/cmdarg.c @@ -51,6 +51,7 @@ */ #include "hbapi.h" +#include "hbvm.h" #include "hbmemory.ch" /* Command line argument management */ @@ -283,8 +284,11 @@ HB_FUNC( HB_ARGV ) } /* Check for command line internal arguments */ -void hb_cmdargProcessVM( void ) +ULONG hb_cmdargProcessVM( int *pCancelKey, int *pCancelKeyEx ) { + char * cFlags; + ULONG ulFlags = (HB_VMFLAG_HARBOUR | HB_VMFLAG_ARRSTR); + if( hb_cmdargCheck( "INFO" ) ) { { @@ -312,4 +316,53 @@ void hb_cmdargProcessVM( void ) if( hb_cmdargCheck( "BUILD" ) ) hb_verBuildInfo(); + + if( (cFlags=hb_cmdargString( "FLAGS" )) != NULL ) + { + int i = 1; + while( cFlags[ i ] ) + { + switch( cFlags[ i++ ] ) + { + case 'c': + /* clear all flags - minimal set of features */ + ulFlags = 0; + break; + + case 'h': + /* default Harbour mode */ + ulFlags |= HB_VMFLAG_HARBOUR; + break; +/* + case 'x': + ulFlags |= HB_VMFLAG_XBASE; + break; + + case 'r': + ulFlags |= HB_VMFLAG_RT_MACRO; + break; +*/ + case 's': + ulFlags |= HB_VMFLAG_ARRSTR; + break; + } + } + hb_xfree( cFlags ); + } + + if( (cFlags=hb_cmdargString( "CANCEL" )) != NULL ) + { + int iVal = atoi( cFlags ); + if( iVal ) + *pCancelKey = iVal; + hb_xfree( cFlags ); + } + if( (cFlags=hb_cmdargString( "CANCELEX" )) != NULL ) + { + int iVal = atoi( cFlags ); + if( iVal ) + *pCancelKeyEx = iVal; + hb_xfree( cFlags ); + } + return ulFlags; } diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index eafc0b0082..ab5f3ca402 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -223,6 +223,17 @@ static BOOL s_bDebugRequest; /* debugger invoked via the VM */ static BOOL s_bDebugShowLines; /* update source code line on the debugger display */ static BOOL s_bDebuggerIsWorking; /* to know when __DBGENTRY is beeing invoked */ +/* Various compatibility flags +*/ +static ULONG s_VMFlags; +#undef hb_vmFlagEnabled +#define hb_vmFlagEnabled(flag) (s_VMFlags & (flag)) + +/* Keycodes to stop virtual machine +*/ +static int s_VMCancelKey = K_ALT_C; +static int s_VMCancelKeyEx = HB_K_ALT_C; + /* Stores the position on the stack of current SEQUENCE envelope or 0 if no * SEQUENCE is active */ @@ -313,8 +324,9 @@ void HB_EXPORT hb_vmInit( BOOL bStartMainProc ) HB_LANG_SELECT_DEFAULT( HB_LANG_DEFAULT ); /* Check for some internal switches */ - hb_cmdargProcessVM(); - + s_VMFlags = hb_cmdargProcessVM( &s_VMCancelKey, &s_VMCancelKeyEx ); + hb_inkeySetCancelKeys( s_VMCancelKey, s_VMCancelKeyEx ); + /* Initialize opcodes profiler support arrays */ { ULONG ul; @@ -493,12 +505,8 @@ void HB_EXPORT hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols ) { int ch = hb_gt_ReadKey( hb_set.HB_SET_EVENTMASK ); - switch( ch ) - { - case HB_K_ALT_C: /* Check for extended Alt+C */ - case K_ALT_C: /* Check for normal Alt+C */ + if( (ch == s_VMCancelKey) || (ch == s_VMCancelKeyEx) ) hb_vmRequestCancel();/* Request cancellation */ - } } } #endif @@ -2835,8 +2843,8 @@ static void hb_vmArrayPush( void ) return; } -#ifndef HB_C52_STRICT - if( HB_IS_STRING( pArray ) ) +/* #ifndef HB_C52_STRICT */ + if( (hb_vmFlagEnabled(HB_VMFLAG_ARRSTR)) && (HB_IS_STRING( pArray )) ) { BYTE b = 0; HB_ITEM item; @@ -2854,7 +2862,7 @@ static void hb_vmArrayPush( void ) hb_itemClear( &item ); return; } -#endif +/* #endif */ if( HB_IS_OBJECT( pArray ) && hb_objHasMsg( pArray, "__OpArrayIndex" ) ) { @@ -2923,8 +2931,8 @@ static void hb_vmArrayPop( void ) return; } -#ifndef HB_C52_STRICT - if( HB_IS_STRING( pArray ) ) +/* #ifndef HB_C52_STRICT */ + if( (hb_vmFlagEnabled(HB_VMFLAG_ARRSTR)) && (HB_IS_STRING( pArray )) ) { if( ulIndex > 0 && ulIndex <= pArray->item.asString.length ) { @@ -2943,7 +2951,7 @@ static void hb_vmArrayPop( void ) return; } -#endif +/* #endif */ if( HB_IS_ARRAY( pArray ) ) { @@ -4978,6 +4986,12 @@ void hb_vmRequestCancel( void ) } } +#undef hb_vmFlagEnabled +ULONG hb_vmFlagEnabled( ULONG flags ) +{ + return s_VMFlags & (flags); +} + void hb_vmRequestDebug( void ) { HB_TRACE(HB_TR_DEBUG, ("hb_vmRequestDebug()")); diff --git a/harbour/tests/keywords.prg b/harbour/tests/keywords.prg index 205f679cf0..377192b667 100644 --- a/harbour/tests/keywords.prg +++ b/harbour/tests/keywords.prg @@ -574,8 +574,10 @@ FIEL fiel FIELD( FIEL(0) ) - DO field +#ifndef HB_CLIPPER_COMPATIBLE + DO field //Incorrect number of arguments DO field WITH field //field cannot be passed by a reference +#endif WHILE field fiel :=field +1 ENDDO @@ -654,7 +656,9 @@ FIELD field IN field EVAL( {|in| in}, in ) DO in - DO in WITH in //field cannot be passed by a reference +#ifndef HB_CLIPPER_COMPATIBLE + DO in WITH in //IN cannot be passed by a reference +#endif RETURN in