From 84d5ae7c575a5032db29c2808715da0004f6e91c Mon Sep 17 00:00:00 2001 From: "David G. Holm" Date: Thu, 24 Jun 1999 02:33:05 +0000 Subject: [PATCH] See ChangeLog entry 19990623-21:30 EDT David G. Holm --- harbour/ChangeLog | 66 +++++++++++ harbour/include/box.ch | 27 +++++ harbour/include/box.h | 11 ++ harbour/include/color.ch | 11 ++ harbour/include/gtapi.h | 33 ++---- harbour/include/hbsetup.h | 20 ++++ harbour/makefile.b31 | 11 +- harbour/makefile.icc | 2 + harbour/source/compiler/harbour.l | 3 +- harbour/source/rtl/console.c | 184 +++++++++++++++++++++++++++--- harbour/source/rtl/dates.c | 9 +- harbour/source/rtl/gt/gtdos.c | 22 ++-- harbour/source/rtl/gt/gtwin.c | 30 ++--- harbour/source/rtl/gtapi.c | 8 +- harbour/source/rtl/math.c | 23 ++-- harbour/source/rtl/strcmp.c | 5 +- harbour/source/rtl/strings.c | 122 +++++++++++++++----- harbour/source/vm/hvm.c | 3 +- harbour/tests/broken/cbtest.prg | 26 +++++ harbour/tests/working/box.prg | 10 ++ 20 files changed, 505 insertions(+), 121 deletions(-) create mode 100644 harbour/include/box.ch create mode 100644 harbour/include/box.h create mode 100644 harbour/include/color.ch create mode 100644 harbour/tests/broken/cbtest.prg create mode 100644 harbour/tests/working/box.prg diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 526f7d7059..29bdbdcac4 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,69 @@ +19990623-21:30 EDT David G. Holm + * makefile.b31 + - Added support for source/rtl/copyfile.c + - source/rtl/genobj.c was moved to source/contrib + * makefile.icc + - Added support for source/rtl/copyfile.c + + include/box.ch + - New include file contributed by Phil Barnett + + include/box.h + - Moved all border type manifest constants from gtapi.h + - Removed leading underscores + + include/color.ch + - Moved all color attribute manifest constants from gtapi.h + - Removed leading underscores + * include/gtapi.h + - Moved all manifest constants for color attributes to color.ch + - Added #include + - Removed all manifest constants for cursor types + - Added #include + - Moved all manifest constants for border types to box.h + - Added #include + * include/hbsetup.h + - Added HB_STRICT_CLIPPER_COMPATIBILITY + * source/compiler/harbour.l + - Corrected yy_lex_count_lf per Paul Tucker + * source/rtl/console.c + - Added minimal DISPBOX() support for those without a working GT API + based on code contributed by Phil Barnett + * source/rtl/dates.c + - Added #include + - Added HB to front of _STRICT_CLIPPER_COMPATIBILITY and + _OPTIMIZE_DTOS manifest constants + * source/rtl.gtapi.c + - Removed leading underscores from former gtapi.h manifest constants + * source/rtl/math.c + - Set the default number of decimal digits after call to + EXP(), LOG(), and SQRT() + - Always return the value from the C/C++ compiler's log() + function. Even when the HARBOUR LOG() argument is less + than or equal to zero, in which case set the display + width to 99 to indicate overflow. + * source/rtl/strcmp.c + - Removed ability to use library functions stricmp() or strcasecmp() + * source/rtl/strings.c + - Added #include + - Added #ifdef HB_STRICT_CLIPPER_COMPATIBILITY to determine + whether to use Clipper overflow indication (a string of + asterisks) or to use the C/C++ compiler's indication + (+/-Infinity and/or +/-Not a Number) + - Added support for date and numeric arguments for first + parameter in all PAD functions (PADC, PADL, PADR) + * source/rtl/gt/gtdos.c + - Removed leading underscores from former gtapi.h manifest constants + * source/rtl/gt/gtwin.c + - Removed leading underscores from former gtapi.h manifest constants + - Changed all malloc() calls to hb_xgrab() + * source/vm/hvm.c + - In ForTest(), the number of decimal digits was being + accessed before the loop counter was popped off the + stack instead of after + + tests/broken/cbtest.prg + - Illustrates codeblock problem pointed out by Dave Pearson + + tests/working/box.prg + - New test program to demonstrate the use of DISPBOX() + based on code contributed by Phil Barnett + 19990624-08:00 WIB Andi Jahja * source/rtl/copyfile.c - function name now upper case diff --git a/harbour/include/box.ch b/harbour/include/box.ch new file mode 100644 index 0000000000..5613c8cfd5 --- /dev/null +++ b/harbour/include/box.ch @@ -0,0 +1,27 @@ +/* + * $ + */ + +// Harbour BOX.CH +// #defines for DISPBOX() + +#ifndef _BOX_CH +#define _BOX_CH + + // Single-line + #define B_SINGLE ( CHR(218) + CHR(196) + CHR(191) + CHR(179) + ; + CHR(217) + CHR(196) + CHR(192) + CHR(179) ) + + // Double-line + #define B_DOUBLE ( CHR(201) + CHR(205) + CHR(187) + CHR(186) + ; + CHR(188) + CHR(205) + CHR(200) + CHR(186) ) + + // Single-line top, double-line sides + #define B_SINGLE_DOUBLE ( CHR(214) + CHR(196) + CHR(183) + CHR(186) + ; + CHR(189) + CHR(196) + CHR(211) + CHR(186) ) + + // Double-line top, single-line sides + #define B_DOUBLE_SINGLE ( CHR(213) + CHR(205) + CHR(184) + CHR(179) + ; + CHR(190) + CHR(205) + CHR(212) + CHR(179) ) + +#endif diff --git a/harbour/include/box.h b/harbour/include/box.h new file mode 100644 index 0000000000..3758a3553c --- /dev/null +++ b/harbour/include/box.h @@ -0,0 +1,11 @@ +/* + * $ + */ + +/* strings for borders (same as box.ch, but defined for use by C) */ + /*01234567*/ +#define B_NONE " " +#define B_SINGLE "ÚÄ¿³ÙÄÀ³" +#define B_DOUBLE "ÉÍ»º¼ÍȺ" +#define B_SINGLE_DOUBLE "ÖÄ·º½ÄÓº" +#define B_DOUBLE_SINGLE "Õ͸³¾ÍÔ³" diff --git a/harbour/include/color.ch b/harbour/include/color.ch new file mode 100644 index 0000000000..23dd614616 --- /dev/null +++ b/harbour/include/color.ch @@ -0,0 +1,11 @@ +/* + * $Id$ + */ + +/* attributes for color strings */ +#define CLR_STANDARD 0 +#define CLR_ENHANCED 1 +#define CLR_BORDER 2 +#define CLR_BACKGROUND 3 +#define CLR_UNSELECTED 4 +#define CLR_LASTCOLOR CLR_UNSELECTED diff --git a/harbour/include/gtapi.h b/harbour/include/gtapi.h index c9e2c1121c..058b45c4cc 100644 --- a/harbour/include/gtapi.h +++ b/harbour/include/gtapi.h @@ -5,6 +5,13 @@ #ifndef GTAPI_H_ #define GTAPI_H_ +#include +#include +#include + +/* maximum length of color string */ +#define CLR_STRLEN 64 + /* * GTAPI.H; Screen drawing, cursor and keyboard routines for text mode * 16-bit and 32-bit MS-DOS, 16-bit and 32-bit OS/2, and 32-bit @@ -73,32 +80,6 @@ int hb_gtWrite(char * fpStr, USHORT uiLen); int hb_gtWriteAt(USHORT uiRow, USHORT uiCol, char * fpStr, USHORT uiLen); int hb_gtWriteCon(char * fpStr, USHORT uiLen); -/* maximum length of color string */ -#define CLR_STRLEN 64 - -/* cursor types */ -#define _SC_NONE 0 -#define _SC_NORMAL 1 -#define _SC_INSERT 2 -#define _SC_SPECIAL1 3 -#define _SC_SPECIAL2 4 - -/* attributes for color strings */ -#define _CLR_STANDARD 0 -#define _CLR_ENHANCED 1 -#define _CLR_BORDER 2 -#define _CLR_BACKGROUND 3 -#define _CLR_UNSELECTED 4 -#define _CLR_LASTCOLOR _CLR_UNSELECTED - -/* strings for borders (same as Clipper/Harbour ones) */ - /*01234567*/ -#define _B_NONE " " -#define _B_SINGLE "ÚÄ¿³ÙÄÀ³" -#define _B_DOUBLE "ÉÍ»º¼ÍȺ" -#define _B_SINGLE_DOUBLE "ÖÄ·º½ÄÓº" -#define _B_DOUBLE_SINGLE "Õ͸³¾ÍÔ³" - #ifndef DOS #if defined(_QC) || defined(__DOS__) || defined(MSDOS) || defined(__MSDOS__) #define DOS diff --git a/harbour/include/hbsetup.h b/harbour/include/hbsetup.h index 66ed127d70..eaed03a51d 100644 --- a/harbour/include/hbsetup.h +++ b/harbour/include/hbsetup.h @@ -32,6 +32,26 @@ */ /*#define HARBOUR_OBJ_GENERATION*/ +/* This symbol defines if we want to use strict Clipper compatibility + * + * By default it is disabled (symbol is not defined) +*/ +/*#define HB_STRICT_CLIPPER_COMPATIBILITY*/ + +/* This symbol defines if you want to have hb_stricmp() use stricmp() + * + * By default it is disabled (symbol is not defined) +*/ +/*#define HB_USE_STRICMP*/ + +/* This symbol defines if you want to have hb_stricmp() use strcasecmp() + * + * By default it is disabled (symbol is not defined) + * + * If you define both HB_USE_STRICMP and HB_USE_STRCASECMP, HB_USE_STRICMP + * will take precedence over HB_USE_STRCASECMP +*/ +/*#define HB_USE_STRCASECMP*/ /* This symbol defines if we want to use the GT API * diff --git a/harbour/makefile.b31 b/harbour/makefile.b31 index d7c5533473..8b92a33063 100644 --- a/harbour/makefile.b31 +++ b/harbour/makefile.b31 @@ -15,8 +15,8 @@ c_opt = -mh -O2 -I.\include -DUSE_GTAPI PROJECT: harbour.lib hbtools.lib terminal.lib libs\win16\terminal.lib harbour.exe -harbour.lib : arrays.obj asort.obj classes.obj codebloc.obj dates.obj \ - descend.obj dynsym.obj environ.obj error.obj \ +harbour.lib : arrays.obj asort.obj classes.obj codebloc.obj copyfile.c \ + dates.obj descend.obj dynsym.obj environ.obj error.obj \ errorapi.obj errorsys.obj extend.obj \ files.obj gtapi.obj hardcr.obj initsymb.obj itemapi.obj \ math.obj mtran.obj objfunc.obj \ @@ -45,6 +45,7 @@ arrays.obj : arrays.c extend.h types.h itemapi.h ctoharb.h asort.obj : asort.prg extend.h types.h init.h pcode.h harbour.exe classes.obj : classes.c extend.h types.h itemapi.h codebloc.obj : codebloc.c extend.h types.h +copyfile.obj : copyfile.c extend.h types.h itemapi.h errorapi.h error.ch filesys.h fileio.ch filesys.api dates.obj : dates.c extend.h types.h dates.h set.h descend.obj : descend.c extend.h types.h environ.obj : environ.c extend.h types.h @@ -73,7 +74,7 @@ initsymb.obj : source\vm\initsymb.c extend.h types.h datesx.obj : source\tools\datesx.c extend.h types.h debug.obj : source\tools\debug.c extend.h types.h ctoharb.h itemapi.h -genobj.obj : source\tools\genobj.c extend.h types.h +genobj.obj : source\contrib\genobj.c extend.h types.h io.obj : source\tools\io.c extend.h types.h mathx.obj : source\tools\mathx.c extend.h types.h stringp.obj : source\tools\stringp.prg extend.h types.h init.h pcode.h harbour.exe @@ -107,6 +108,10 @@ strright.obj : source\tools\strright.c extend.h types.h bcc -c $(c_opt) -o$@ $*.c tlib .\libs\b16\harbour.lib -+$@,, +{source\contrib}.c{obj}.obj: + bcc -c $(c_opt) -o$@ $< + tlib .\libs\b16\hbtools.lib -+$@,, + {source\vm}.c{obj}.obj: bcc -c $(c_opt) -o$@ $< tlib .\libs\b16\harbour.lib -+$@,, diff --git a/harbour/makefile.icc b/harbour/makefile.icc index 71143d6dc3..e55e3401ed 100644 --- a/harbour/makefile.icc +++ b/harbour/makefile.icc @@ -21,6 +21,7 @@ $(path_lib)\harbour.lib : \ $(path_obj)\classes.obj \ $(path_obj)\codebloc.obj \ $(path_obj)\console.obj \ + $(path_obj)\copyfile.obj \ $(path_obj)\descend.obj \ $(path_obj)\dates.obj \ $(path_obj)\dir.obj \ @@ -89,6 +90,7 @@ $(path_obj)\gtos2.obj : {$(path_c)}gtos2.c $(path_h)\extend.h $(path_h)\types. $(path_obj)\arrays.obj : {$(path_c)}arrays.c $(path_h)\extend.h $(path_h)\types.h $(path_h)\itemapi.h $(path_h)\errorapi.h $(path_h)\ctoharb.h $(path_h)\error.ch $(path_obj)\classes.obj : {$(path_c)}classes.c $(path_h)\extend.h $(path_h)\types.h $(path_h)\errorapi.h $(path_h)\ctoharb.h $(path_h)\error.ch $(path_obj)\codebloc.obj : {$(path_c)}codebloc.c $(path_h)\extend.h $(path_h)\types.h $(path_h)\itemapi.h +$(path_obj)\copyfile.obj : {$(path_c)}copyfile.c $(path_h)\extend.h $(path_h)\types.h $(path_h)\itemapi.h $(path_h)\errorapi.h $(path_h)\error.ch $(path_h)\filesys.h $(path_h)\fileio.ch $(path_h)\filesys.api $(path_obj)\dates.obj : {$(path_c)}dates.c $(path_h)\extend.h $(path_h)\types.h $(path_h)\dates.h $(path_h)\set.h $(path_h)\errorapi.h $(path_h)\error.ch $(path_obj)\datesx.obj : {$(path_c)}datesx.c $(path_h)\extend.h $(path_h)\types.h $(path_obj)\debug.obj : {$(path_c)}debug.c $(path_h)\extend.h $(path_h)\types.h $(path_h)\itemapi.h $(path_h)\ctoharb.h diff --git a/harbour/source/compiler/harbour.l b/harbour/source/compiler/harbour.l index 129ff2cfbf..94fbc9002a 100644 --- a/harbour/source/compiler/harbour.l +++ b/harbour/source/compiler/harbour.l @@ -68,8 +68,7 @@ int i_INDEX_STATE = 0; void yy_lex_count_lf( void ) { char * pTmp = yytext; - pTmp = strchr(pTmp, '\n'); - while( pTmp ) + while( ( pTmp = strchr(pTmp, '\n') ) ) { ++iLine; ++pTmp; diff --git a/harbour/source/rtl/console.c b/harbour/source/rtl/console.c index 6e39480d9e..4f2ac7ff82 100644 --- a/harbour/source/rtl/console.c +++ b/harbour/source/rtl/console.c @@ -1,3 +1,4 @@ + /* * $Id$ */ @@ -19,9 +20,8 @@ #else #include #endif -#ifdef USE_GTAPI - #include -#endif +#include /* USE_GTAPI is checked inside gtapi.h, so that + we can always get the border styles */ #define ACCEPT_BUFFER_LEN 256 /*length of input buffer for ACCEPT command */ @@ -35,9 +35,16 @@ HARBOUR HB___ACCEPT(void); HARBOUR HB_COL( void ); HARBOUR HB_DEVOUT( void ); HARBOUR HB_DEVPOS( void ); +HARBOUR HB_DISPBEGIN( void ); +HARBOUR HB_DISPBOX( void ); +HARBOUR HB_DISPCOUNT( void ); +HARBOUR HB_DISPEND( void ); +HARBOUR HB_DISPOUT( void ); HARBOUR HB___EJECT( void ); +HARBOUR HB_ISCOLOR( void ); HARBOUR HB_MAXCOL( void ); HARBOUR HB_MAXROW( void ); +HARBOUR HB_NOSNOW( void ); HARBOUR HB_OUTSTD( void ); HARBOUR HB_OUTERR( void ); HARBOUR HB_PCOL( void ); @@ -48,12 +55,6 @@ HARBOUR HB_SETPOS( void ); HARBOUR HB_SETPRC( void ); HARBOUR HB_QOUT( void ); HARBOUR HB_QQOUT( void ); -HARBOUR HB_DISPBOX( void ); -HARBOUR HB_DISPBEGIN( void ); -HARBOUR HB_DISPEND( void ); -HARBOUR HB_DISPCOUNT( void ); -HARBOUR HB_ISCOLOR( void ); -HARBOUR HB_NOSNOW( void ); static SYMBOL symbols[] = { { "__ACCEPT" , FS_PUBLIC, HB___ACCEPT , 0 }, @@ -61,10 +62,17 @@ static SYMBOL symbols[] = { { "COL" , FS_PUBLIC, HB_COL , 0 }, { "DEVOUT" , FS_PUBLIC, HB_DEVOUT , 0 }, { "DEVPOS" , FS_PUBLIC, HB_DEVPOS , 0 }, +{ "DISPBEGIN", FS_PUBLIC, HB_DISPBEGIN, 0 }, +{ "DISPBOX" , FS_PUBLIC, HB_DISPBOX , 0 }, +{ "DISPCOUNT", FS_PUBLIC, HB_DISPCOUNT, 0 }, +{ "DISPEND" , FS_PUBLIC, HB_DISPEND , 0 }, +{ "DISPOUT" , FS_PUBLIC, HB_DISPOUT , 0 }, +{ "ISCOLOR" , FS_PUBLIC, HB_ISCOLOR , 0 }, { "MAXCOL" , FS_PUBLIC, HB_MAXCOL , 0 }, { "MAXROW" , FS_PUBLIC, HB_MAXROW , 0 }, { "OUTERR" , FS_PUBLIC, HB_OUTERR , 0 }, { "OUTSTD" , FS_PUBLIC, HB_OUTSTD , 0 }, +{ "NOSNOW" , FS_PUBLIC, HB_NOSNOW , 0 }, { "PCOL" , FS_PUBLIC, HB_PCOL , 0 }, { "PROW" , FS_PUBLIC, HB_PROW , 0 }, { "ROW" , FS_PUBLIC, HB_ROW , 0 }, @@ -72,13 +80,7 @@ static SYMBOL symbols[] = { { "SETPOS" , FS_PUBLIC, HB_SETPOS , 0 }, { "SETPRC" , FS_PUBLIC, HB_SETPRC , 0 }, { "QOUT" , FS_PUBLIC, HB_QOUT , 0 }, -{ "QQOUT" , FS_PUBLIC, HB_QQOUT , 0 }, -{ "DISPBOX" , FS_PUBLIC, HB_DISPBOX , 0 }, -{ "DISPBEGIN", FS_PUBLIC, HB_DISPBEGIN, 0 }, -{ "DISPEND" , FS_PUBLIC, HB_DISPEND , 0 }, -{ "DISPCOUNT", FS_PUBLIC, HB_DISPCOUNT, 0 }, -{ "ISCOLOR" , FS_PUBLIC, HB_ISCOLOR , 0 }, -{ "NOSNOW" , FS_PUBLIC, HB_NOSNOW , 0 } +{ "QQOUT" , FS_PUBLIC, HB_QQOUT , 0 } }; void Console__InitSymbols( void ) @@ -334,6 +336,21 @@ static void hb_devout( char * fpStr, WORD uiLen ) } } +/* Output an item to the screen */ +static void hb_dispout( char * fpStr, WORD uiLen ) +{ + #ifdef USE_GTAPI + /* Display to console */ + hb_gtWrite( fpStr, uiLen ); + hb_gtGetPos( &dev_row, &dev_col ); + #else + WORD uiCount; + for( uiCount = 0; uiCount < uiLen; uiCount++ ) + printf( "%c", fpStr[ uiCount ] ); + adjust_pos( fpStr, uiLen, &dev_row, &dev_col, hb_max_row(), hb_max_col() ); + #endif +} + void hb_setpos( USHORT row, USHORT col ) { #ifdef USE_GTAPI @@ -341,8 +358,14 @@ void hb_setpos( USHORT row, USHORT col ) #else USHORT count; + if( row < dev_row && col < dev_col ) + { + printf("\n"); + dev_col = 0; + dev_row++; + } + else if( row > dev_row ) dev_col = 0; for( count = dev_row; count < row; count++ ) printf("\n"); - if( row > dev_row ) dev_col = 0; for( count = dev_col; count < col; count++ ) printf(" "); #endif dev_row = row; @@ -447,7 +470,7 @@ HARBOUR HB_DEVPOS( void ) /* Sets the screen and/or printer position */ } } -HARBOUR HB_DEVOUT( void ) /* writes a single values to the current device (screen or printer), but is not affected by SET ALTERNATE */ +HARBOUR HB_DEVOUT( void ) /* writes a single value to the current device (screen or printer), but is not affected by SET ALTERNATE */ { if( hb_pcount() > 0 ) { @@ -472,6 +495,31 @@ HARBOUR HB_DEVOUT( void ) /* writes a single values to the current device (scree } } +HARBOUR HB_DISPOUT( void ) /* writes a single value to the current device (screen or printer), but is not affected by SET ALTERNATE */ +{ + if( hb_pcount() > 0 ) + { +#ifdef USE_GTAPI + char fpOldColor[ CLR_STRLEN ]; + + if( ISCHAR(2) ) + { + hb_gtGetColorStr( fpOldColor ); + hb_gtSetColorStr( hb_parc(2) ); + } +#endif + + hb_out( 1, hb_dispout ); + +#ifdef USE_GTAPI + if( ISCHAR(2) ) + { + hb_gtSetColorStr( fpOldColor ); + } +#endif + } +} + HARBOUR HB___EJECT( void ) /* Ejects the current page from the printer */ { if( hb_stricmp( hb_set.HB_SET_DEVICE, "PRINTER" ) == 0 && hb_set_printhan >= 0 ) @@ -571,7 +619,7 @@ HARBOUR HB_DISPBOX (void) hb_gtSetColorStr(hb_parc(6)); } - if (ISCHAR(1)) + if (ISCHAR(5)) { hb_gtBox(hb_parni(1), hb_parni(2), hb_parni(3), hb_parni(4), hb_parc(5)); } @@ -589,6 +637,104 @@ HARBOUR HB_DISPBOX (void) hb_gtSetColorStr(szOldColor); } } +#else + if (ISNUM(1) && ISNUM(2) && ISNUM(3) && ISNUM(4)) + { + char * szBorderStyle = B_SINGLE; + int top = hb_parni( 1 ), left = hb_parni( 2 ); + int bottom = hb_parni( 3 ), right = hb_parni( 4 ); + int count, size = strlen( B_SINGLE ); + char Borders[ 9 ]; + + /* Set limits on the box coordinates to (0,0) and (max_row(),max_col()) */ + if( top < 0 ) top = 0; + if( left < 0 ) left = 0; + if( bottom < 0 ) bottom = 0; + if( right < 0 ) right = 0; + if( top > hb_max_row() ) top = hb_max_row(); + if( left > hb_max_col() ) left = hb_max_col(); + if( bottom > hb_max_row() ) bottom = hb_max_row(); + if( right > hb_max_col() ) right = hb_max_col(); + + /* Force the box to be drawn from top left to bottom right */ + if( top > bottom ) + { + int temp; + temp = top; + top = bottom; + bottom = temp; + } + if( left > right ) + { + int temp; + temp = right; + right = left; + left = temp; + } + + /* Determine the box style */ + if( ISCHAR( 5 ) ) + { + szBorderStyle = hb_parc( 5 ); + size = hb_parclen( 5 ); + } + else if( ISNUM( 5 ) ) + { + switch( hb_parni( 5 ) ) + { + case 2: + szBorderStyle = B_DOUBLE; + break; + case 3: + szBorderStyle = B_SINGLE_DOUBLE; + break; + case 4: + szBorderStyle = B_DOUBLE_SINGLE; + break; + default: + szBorderStyle = B_SINGLE; + } + size = strlen( szBorderStyle ); + } + /* We only need 9 characters from the source string */ + if( size > 9 ) size = 9; + /* If we have at least one character... */ + if( size ) + /* ...copy the source string */ + memcpy( Borders, szBorderStyle, size ); + else + /* If not, set the first character to a space */ + Borders[ size++ ] = ' '; + /* If there were less than 8 characters in the source... */ + for( ; size < 8; size++ ); + /* ...copy the last character into the remaining 8 border positions */ + Borders[ size ] = Borders[ size - 1 ]; + /* If there were less than 9 characters in the source... */ + if( size < 9 ) + /* ...set the fill character to space */ + Borders[ 8 ] = ' '; + + /* Draw the box */ + hb_setpos( top, left ); + printf( "%c", Borders[ 0 ] ); /* Upper left corner */ + for( size = left + 1; size < right - 1; size++ ) + printf( "%c", Borders[ 1 ] ); /* Top line */ + printf( "%c", Borders[ 2 ] ); /* Upper right corner */ + hb_setpos( top + 1, left ); + for( count = top + 1; count < bottom - 1; count++ ) + { + printf( "%c", Borders[ 3 ] ); /* Left side */ + for( size = left + 1; size < right - 1; size++ ) + printf( "%c", Borders[ 8 ] ); /* Fill */ + printf( "%c", Borders[ 7 ] ); /* Right side */ + hb_setpos( count + 1, left ); + } + printf( "%c", Borders[ 6 ] ); /* Bottom left corner */ + for( size = left + 1; size < right - 1; size++ ) + printf( "%c", Borders[ 5 ] ); /* Bottom line */ + printf( "%c", Borders[ 4 ] ); /* Bottom right corner */ + dev_col += (right - left); + } #endif } diff --git a/harbour/source/rtl/dates.c b/harbour/source/rtl/dates.c index 12cac85841..b8f16c5b7e 100644 --- a/harbour/source/rtl/dates.c +++ b/harbour/source/rtl/dates.c @@ -2,6 +2,7 @@ * $Id$ */ +#include #include #include #include @@ -11,8 +12,8 @@ #include #endif -#ifndef _STRICT_CLIPPER_COMPATIBILITY - #define _OPTIMIZE_DTOS +#ifndef HB_STRICT_CLIPPER_COMPATIBILITY + #define HB_OPTIMIZE_DTOS #endif extern STACK stack; @@ -382,14 +383,14 @@ HARBOUR HB_DTOC( void ) /* Clipper does these checks, anyway. */ HARBOUR HB_DTOS( void ) { -#ifndef _OPTIMIZE_DTOS +#ifndef HB_OPTIMIZE_DTOS if( hb_pcount() == 1 ) { if( ISDATE( 1 ) ) { #endif hb_retc( hb_pards( 1 ) ); -#ifndef _OPTIMIZE_DTOS +#ifndef HB_OPTIMIZE_DTOS } else { diff --git a/harbour/source/rtl/gt/gtdos.c b/harbour/source/rtl/gt/gtdos.c index 8eb469c782..7cc82a1144 100644 --- a/harbour/source/rtl/gt/gtdos.c +++ b/harbour/source/rtl/gt/gtdos.c @@ -184,27 +184,27 @@ int gtGetCursorStyle(void) if((start == 32) && (end == 32)) { - rc=_SC_NONE; + rc=SC_NONE; } else if((start == 6) && (end == 7)) { - rc=_SC_NORMAL; + rc=SC_NORMAL; } else if((start == 4) && (end == 7)) { - rc=_SC_INSERT; + rc=SC_INSERT; } else if((start == 0) && (end == 7)) { - rc=_SC_SPECIAL1; + rc=SC_SPECIAL1; } else if((start == 0) && (end == 3)) { - rc=_SC_SPECIAL2; + rc=SC_SPECIAL2; } else { - rc=_SC_NONE; + rc=SC_NONE; } return(rc); @@ -214,23 +214,23 @@ void gtSetCursorStyle(int style) { switch(style) { - case _SC_NONE: + case SC_NONE: gtSetCursorSize(32, 32); break; - case _SC_NORMAL: + case SC_NORMAL: gtSetCursorSize(6, 7); break; - case _SC_INSERT: + case SC_INSERT: gtSetCursorSize(4, 7); break; - case _SC_SPECIAL1: + case SC_SPECIAL1: gtSetCursorSize(0, 7); break; - case _SC_SPECIAL2: + case SC_SPECIAL2: gtSetCursorSize(0, 3); break; diff --git a/harbour/source/rtl/gt/gtwin.c b/harbour/source/rtl/gt/gtwin.c index 7d0dd7e6b6..1a78c5b864 100644 --- a/harbour/source/rtl/gt/gtwin.c +++ b/harbour/source/rtl/gt/gtwin.c @@ -73,30 +73,30 @@ void gtSetCursorStyle(int style) GetConsoleCursorInfo(HOutput, &cci); switch (style) { - case _SC_NONE: + case SC_NONE: cci.bVisible = 0; SetConsoleCursorInfo(HOutput, &cci); break; - case _SC_NORMAL: + case SC_NORMAL: cci.bVisible = 1; cci.dwSize = 12; SetConsoleCursorInfo(HOutput, &cci); break; - case _SC_INSERT: + case SC_INSERT: cci.bVisible = 1; cci.dwSize = 99; SetConsoleCursorInfo(HOutput, &cci); break; - case _SC_SPECIAL1: + case SC_SPECIAL1: cci.bVisible = 1; cci.dwSize = 49; SetConsoleCursorInfo(HOutput, &cci); break; - case _SC_SPECIAL2: + case SC_SPECIAL2: /* TODO: Why wasn't this implemented ? */ break; @@ -115,27 +115,27 @@ int gtGetCursorStyle(void) if(cci.bVisible) { /* QUESTION: Is this really correct ? IF _VISIBLE_ -> NONE */ - rc=_SC_NONE; + rc=SC_NONE; } else { switch(cci.dwSize) { case 12: - rc=_SC_NORMAL; + rc=SC_NORMAL; break; case 99: - rc=_SC_INSERT; + rc=SC_INSERT; break; case 49: - rc=_SC_SPECIAL1; + rc=SC_SPECIAL1; break; /* TODO: cannot tell if the block is upper or lower for cursor */ default: - rc=_SC_SPECIAL2; + rc=SC_SPECIAL2; } } @@ -147,7 +147,7 @@ void gtPuts(char x, char y, char attr, char *str, int len) DWORD i, dwlen; COORD coord; LPWORD pwattr; - pwattr = (LPWORD) malloc(strlen(str) * sizeof(*pwattr)); + pwattr = (LPWORD) hb_xgrab(strlen(str) * sizeof(*pwattr)); if (!pwattr) { return; @@ -170,12 +170,12 @@ void gtGetText(char x1, char y1, char x2, char y2, char *dest) LPWORD pwattr; char y, *pstr; width = (x2 - x1 + 1); - pwattr = (LPWORD) malloc(strlen(str) * sizeof(*pwattr)); + pwattr = (LPWORD) hb_xgrab(strlen(str) * sizeof(*pwattr)); if (!pwattr) { return; } - pstr = (char *)malloc(width); + pstr = (char *)hb_xgrab(width); if (!pstr) { free(pwattr); @@ -206,12 +206,12 @@ void gtPutText(char x1, char y1, char x2, char y2, char *srce) LPWORD pwattr; char y, *pstr; width = (x2 - x1 + 1); - pwattr = (LPWORD) malloc(strlen(str) * sizeof(*pwattr)); + pwattr = (LPWORD) hb_xgrab(strlen(str) * sizeof(*pwattr)); if (!pwattr) { return; } - pstr = (char *)malloc(width); + pstr = (char *)hb_xgrab(width); if (!pstr) { free(pwattr); diff --git a/harbour/source/rtl/gtapi.c b/harbour/source/rtl/gtapi.c index cb58471b7b..3da863bded 100644 --- a/harbour/source/rtl/gtapi.c +++ b/harbour/source/rtl/gtapi.c @@ -92,17 +92,17 @@ int hb_gtBox (USHORT uiTop, USHORT uiLeft, USHORT uiBottom, USHORT uiRight, char int hb_gtBoxD(USHORT uiTop, USHORT uiLeft, USHORT uiBottom, USHORT uiRight) { - return(hb_gtBox(uiTop, uiLeft, uiBottom, uiRight, _B_DOUBLE)); + return(hb_gtBox(uiTop, uiLeft, uiBottom, uiRight, B_DOUBLE)); } int hb_gtBoxS(USHORT uiTop, USHORT uiLeft, USHORT uiBottom, USHORT uiRight) { - return(hb_gtBox(uiTop, uiLeft, uiBottom, uiRight, _B_SINGLE)); + return(hb_gtBox(uiTop, uiLeft, uiBottom, uiRight, B_SINGLE)); } int hb_gtColorSelect(USHORT uiColorIndex) { - if(uiColorIndex > _CLR_LASTCOLOR) + if(uiColorIndex > CLR_LASTCOLOR) { return(1); } @@ -166,7 +166,7 @@ int hb_gtGetCursor(USHORT * uipCursorShape) int i=gtGetCursorStyle(); int rc=0; - if(i <= _SC_SPECIAL2) + if(i <= SC_SPECIAL2) { *uipCursorShape = i; } diff --git a/harbour/source/rtl/math.c b/harbour/source/rtl/math.c index b28e15e1b8..4761120760 100644 --- a/harbour/source/rtl/math.c +++ b/harbour/source/rtl/math.c @@ -2,7 +2,7 @@ * $Id$ */ -#include +#include #include #include @@ -89,7 +89,9 @@ HARBOUR HB_EXP( void ) if( pNumber ) { - hb_retnd( exp(hb_parnd(1)) ); + hb_retnd( exp( hb_parnd( 1 ) ) ); + /* Always set default number of decimals after EXP() */ + stack.Return.wDec = hb_set.HB_SET_DECIMALS; } else { @@ -141,12 +143,13 @@ HARBOUR HB_LOG( void ) if( pNumber ) { - double dNumber = hb_parnd(1); - if( dNumber > 0 ) - hb_retnd( log(dNumber) ); - else - /* TODO: return OVERFLOW */ - hb_retnd(0); + double dNumber = hb_parnd( 1 ); + hb_retnd( log( dNumber ) ); + /* Always set default number of decimals after LOG() */ + stack.Return.wDec = hb_set.HB_SET_DECIMALS; + if( dNumber <= 0.0 ) + /* Indicate overflow if called with an invalid argument */ + stack.Return.wLength = 99; } else { @@ -341,10 +344,14 @@ HARBOUR HB_SQRT( void ) double dNumber = hb_parnd(1); if( dNumber > 0 ) + { hb_retnd( sqrt(dNumber) ); + } else /* Clipper doesn't error! */ hb_retnd(0); + /* Always set default number of decimals after SQRT() */ + stack.Return.wDec = hb_set.HB_SET_DECIMALS; } else { diff --git a/harbour/source/rtl/strcmp.c b/harbour/source/rtl/strcmp.c index c7d7b9e213..b847498e36 100644 --- a/harbour/source/rtl/strcmp.c +++ b/harbour/source/rtl/strcmp.c @@ -2,16 +2,17 @@ * $Id$ */ +#include #include #include #include int hb_stricmp( const char *s1, const char *s2 ) { -#ifdef stricmp +#ifdef HB_USE_STRICMP return( stricmp( s1, s2 ) ); #else -#ifdef strcasecmp +#ifdef HB_USE_STRCASECMP return( strcasecmp( s1, s2 ) ); #else int rc = 0, c1, c2; diff --git a/harbour/source/rtl/strings.c b/harbour/source/rtl/strings.c index 11b09386a7..945c4d21b1 100644 --- a/harbour/source/rtl/strings.c +++ b/harbour/source/rtl/strings.c @@ -2,15 +2,25 @@ * $Id$ */ +#include +#include #include #include #include +#include #include extern STACK stack; +#ifdef HB_STRICT_CLIPPER_COMPATIBILITY +static double infinity = 0; +#endif + #define HB_ISSPACE(c) ((c) == 9 || (c) == 10 || (c) == 13 || (c) == 32) +/* DJGPP can sprintf a float that is almost 320 digits long */ +#define HB_MAX_DOUBLE_LENGTH 320 + HARBOUR HB_ALLTRIM( void ); HARBOUR HB_ASC( void ); HARBOUR HB_AT( void ); @@ -71,6 +81,9 @@ static SYMBOL symbols[] = { void Strings__InitSymbols( void ) { ProcessSymbols( symbols, sizeof(symbols)/sizeof( SYMBOL ) ); + #ifdef HB_STRICT_CLIPPER_COMPATIBILITY + infinity = -log( 0 ); + #endif } BOOL hb_strempty( char * szText, ULONG ulLen ) @@ -238,27 +251,69 @@ HARBOUR HB_ALLTRIM( void ) hb_retc(""); } -/* right-pads a string with spaces or supplied character */ +/* This function is used by all of the PAD functions to prepare the argument + being padded. If date, convert to string using hb_dtoc(). If numeric, + convert to unpadded string. Return pointer to string and set string length */ +static char * hb_pad_prep( PHB_ITEM pItem, char * buffer, WORD * pwSize ) +{ + char * szText = 0; + + if( pItem ) switch( pItem->wType ) + { + case IT_DATE: + szText = hb_dtoc( hb_pards( 1 ), buffer ); + *pwSize = strlen( szText ); + break; + case IT_INTEGER: + sprintf( buffer, "%d", hb_parni( 1 ) ); + szText = buffer; + *pwSize = strlen( szText ); + break; + case IT_LONG: + sprintf( buffer, "%ld", hb_parnl( 1 ) ); + szText = buffer; + *pwSize = strlen( szText ); + break; + case IT_DOUBLE: + if( pItem->wDec ) + sprintf( buffer, "%.*f", pItem->wDec, hb_parnd( 1 ) ); + else + sprintf( buffer, "%ld", hb_parnl( 1 ) ); + szText = buffer; + *pwSize = strlen( szText ); + break; + case IT_STRING: + szText = hb_parc( 1 ); + *pwSize = hb_parclen( 1 ); + break; + } + return szText; +} + +/* right-pads a date, number, or string with spaces or supplied character */ /* TEST: QOUT( "padr( 'hello', 10 ) = '" + padr( 'hello', 10 ) + "'" ) */ HARBOUR HB_PADR( void ) { - char *szText = hb_parc(1); + WORD wSize; + char buffer[ 128 ]; + PHB_ITEM pItem = hb_param( 1, IT_ANY ); + char *szText = hb_pad_prep( pItem, buffer, &wSize ); - if( hb_pcount() > 1 ) + if( szText && hb_pcount() > 1 ) { long lLen = hb_parnl(2); - if( lLen > (long)hb_parclen(1) ) + if( lLen > wSize ) { char *szResult = (char *)hb_xgrab(lLen + 1); long lPos; char cPad; - memcpy(szResult, szText, hb_parclen(1)); + memcpy(szResult, szText, wSize); cPad = ( hb_pcount() > 2? *(hb_parc(3)): ' ' ); - for( lPos = hb_parclen(1); lPos < lLen; lPos++ ) + for( lPos = wSize; lPos < lLen; lPos++ ) szResult[lPos] = cPad; hb_retclen(szResult, lLen); @@ -282,23 +337,26 @@ HARBOUR HB_PAD( void ) HB_PADR(); } -/* left-pads a string with spaces or supplied character */ +/* left-pads a date, number, or string with spaces or supplied character */ /* TEST: QOUT( "padl( 'hello', 10 ) = '" + padl( 'hello', 10 ) + "'" ) */ HARBOUR HB_PADL( void ) { - char *szText = hb_parc(1); + WORD wSize; + char buffer[ 128 ]; + PHB_ITEM pItem = hb_param( 1, IT_ANY ); + char *szText = hb_pad_prep( pItem, buffer, &wSize ); - if( hb_pcount() > 1 ) + if( szText && hb_pcount() > 1 ) { long lLen = hb_parnl(2); - if( lLen > (long) hb_parclen(1) ) + if( lLen > wSize ) { char *szResult = (char *)hb_xgrab(lLen + 1); - long lPos = lLen - hb_parclen(1); + long lPos = lLen - wSize; char cPad; - memcpy(szResult + lPos, szText, hb_parclen(1)); + memcpy(szResult + lPos, szText, wSize); cPad = (hb_pcount() > 2? *(hb_parc(3)): ' '); @@ -322,30 +380,33 @@ HARBOUR HB_PADL( void ) hb_retc(""); } -/* centre-pads a string with spaces or supplied character */ +/* centre-pads a date, number, or string with spaces or supplied character */ /* TEST: QOUT( "padc( 'hello', 10 ) = '" + padc( 'hello', 10 ) + "'" ) */ HARBOUR HB_PADC( void ) { - char *szText = hb_parc(1); + WORD wSize; + char buffer[ 128 ]; + PHB_ITEM pItem = hb_param( 1, IT_ANY ); + char *szText = hb_pad_prep( pItem, buffer, &wSize ); - if( hb_pcount() > 1 ) + if( szText && hb_pcount() > 1 ) { long lLen = hb_parnl(2); - if( lLen > (long) hb_parclen(1) ) + if( lLen > wSize ) { char *szResult = (char *)hb_xgrab(lLen + 1); char cPad; - long w, lPos = (lLen - hb_parclen(1)) / 2; + long w, lPos = (lLen - wSize) / 2; - memcpy(szResult + lPos, szText, hb_parclen(1) + 1); + memcpy(szResult + lPos, szText, wSize + 1); cPad = ( hb_pcount() > 2? *hb_parc(3): ' ' ); for( w = 0; w < lPos; w++ ) szResult[w] = cPad; - for( w = hb_parclen(1) + lPos; w < lLen; w++ ) + for( w = wSize + lPos; w < lLen; w++ ) szResult[w] = cPad; szResult[lLen] = 0; @@ -1107,10 +1168,11 @@ char * hb_str( PHB_ITEM pNumber, PHB_ITEM pWidth, PHB_ITEM pDec ) if( pNumber ) { /* Default to the width and number of decimals specified by the item, - with a limit of 9 decimal places */ + with a limit of 20 integer places and 9 decimal places */ int iWidth = pNumber->wLength; int iDec = pNumber->wDec; - + if( iWidth > 20 ) + iWidth = 20; if( iDec > 9 ) iDec = 9; if( hb_set_fixed ) @@ -1157,7 +1219,7 @@ char * hb_str( PHB_ITEM pNumber, PHB_ITEM pWidth, PHB_ITEM pDec ) int iSize = (iDec ? iWidth + 1 + iDec : iWidth); /* Be paranoid and use a large amount of padding */ - szResult = (char *)hb_xgrab( iWidth + iDec + 64 ); + szResult = (char *)hb_xgrab( HB_MAX_DOUBLE_LENGTH ); if( IS_DOUBLE( pNumber ) || iDec != 0 ) { @@ -1170,10 +1232,18 @@ char * hb_str( PHB_ITEM pNumber, PHB_ITEM pWidth, PHB_ITEM pDec ) else if( IS_DOUBLE( pNumber ) ) dNumber = pNumber->value.dNumber; - if( iDec > 0 ) - iBytes = sprintf( szResult, "%*.*f", iSize, iDec, dNumber ); + #ifdef HB_STRICT_CLIPPER_COMPATIBILITY + if( pNumber->wLength == 99 || dNumber == infinity || dNumber == -infinity ) + /* Numeric overflow */ + iBytes = iSize + 1; else - iBytes = sprintf( szResult, "%*ld", iWidth, (long)dNumber ); + #endif + { + if( iDec > 0 ) + iBytes = sprintf( szResult, "%*.*f", iSize, iDec, dNumber ); + else + iBytes = sprintf( szResult, "%*ld", iWidth, (long)dNumber ); + } } else switch( pNumber->wType & ~IT_BYREF ) { @@ -1190,7 +1260,7 @@ char * hb_str( PHB_ITEM pNumber, PHB_ITEM pWidth, PHB_ITEM pDec ) *szResult = 0; break; } - /* Set to asterisks in case of overflow (same reason for paranoia) */ + /* Set to asterisks in case of overflow */ if( iBytes > iSize ) { memset( szResult, '*', iSize ); diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index a1bf310ab2..4dc7bb9afa 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -868,11 +868,12 @@ void ForTest( void ) /* Test to check the end point of the FOR */ { double dStep; int iEqual; + WORD wDec; if( IS_NUMERIC( stack.pPos - 1 ) ) { - WORD wDec = stack.pPos->wDec; dStep = PopNumber(); + wDec = stack.pPos->wDec; if( dStep > 0 ) /* Positive loop. Use LESS */ Less(); else if( dStep < 0 ) /* Negative loop. Use GREATER */ diff --git a/harbour/tests/broken/cbtest.prg b/harbour/tests/broken/cbtest.prg new file mode 100644 index 0000000000..c6c712735c --- /dev/null +++ b/harbour/tests/broken/cbtest.prg @@ -0,0 +1,26 @@ +Function Main() +Local a := TestBlocks() + + qout( eval( a[ 1 ] ) ) // 23 + qout( eval( a[ 2 ], 42 ) ) // 42 + qout( eval( a[ 1 ] ) ) // 42 + qout( eval( a[ 2 ], 15 ) ) // 15 + + mqout( 15, eval( a[ 1 ] ) ) // 15 15 + mqout( 14, eval( a[ 1 ] ) ) // 14 15 + mqout( 42, eval( a[ 2 ], 42 ) ) // 42 42 + mqout( 14, eval( a[ 2 ], 42 ) ) // 14 42 + mqout( 42, eval( a[ 1 ] ) ) // 42 42 + mqout( 14, eval( a[ 1 ] ) ) // 14 42 + +Return( NIL ) + +Static Function TestBlocks() +Local nFoo := 23 +Return( { {|| nFoo }, {|n| nFoo := n } } ) + +Static Function mqout( nExpected, nGot ) + + qout( nExpected, nGot ) + +Return( NIL ) diff --git a/harbour/tests/working/box.prg b/harbour/tests/working/box.prg new file mode 100644 index 0000000000..b5b039cfef --- /dev/null +++ b/harbour/tests/working/box.prg @@ -0,0 +1,10 @@ +// Testing Harbour device management. + +#include "BOX.CH" +function Main() + + dispbox( 1, 1, 5, 5, B_SINGLE + 'X', 'color not supported') + dispbox( 7, 7, 13, 72, B_DOUBLE + '.') + dispbox( 14, 14, 22, 22, B_SINGLE_DOUBLE ) + +return nil