diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 27bceefff1..1078c35349 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,43 @@ +19990818-18:45 EDT David G. Holm + * config/os2/icc.cf + ! Fix to only use RDD libraries when RDD library is specified. + * include/inkey.h + + Added '#include "set.h"' to get HB_set_enum. + * source/rtl/dates.c + * Renamed hb_seconds() to hb_secondsToday() to avoid a duplicate + symbol warning when using a C++ compiler. + * source/rtl/environ.c + * Moved hb_revision to after hb_build to match Harbour build + number (e.g., "(Build 29a)"). + * source/rtl/gtapi.c + ! Moved speed enhancement display code in hb_gtWriteCon() to be + outside the switch() statement, so that forced display updates + take place immediately instead of when the next character is + processed. (This bug caused QOUT to act like QQOUT.) + ! Added a check to force the display of whatever is in 'strng' when + the buffer is full, because it's possible to write more than 500 + characters without hitting any other forced display conditions + when starting more than 500 characters away from the bottom right + corner of the screen (a 25 x 80 screen is 2000 characters). + - Commented out the calls to hb_gtDispBegin() and hb_gtDispEnd() in + hb_gtWriteCon() in anticipation of removing them, because their use + subverts the use of DISPBEGIN() and DISPEND() in Harbour code. + * source/rtl/inkey.c + - Removed '#include "set.h"', because inkey.h includes it. + + Uncommented DOS release CPU code and added '#if defined(DOS)'. + * source/rtl/tone.c + * Added support for long delays, like in Clipper. + ! OS/2 upper frequency limit is 32767. + * Limited all platforms to an upper frequency of 32767. + * source/vm/hvm.c + ! When dividing by 0, always return 0, just like Clipper. + * tests/working/mathtest.prg + * Moved modulo 0 test ahead of divide by 0 test. + * Put "error" text on a separate line. + * tests/working/sound.prg + + Calculate elapsed time, which should be close to 1.5 seconds + (except on platforms where SECONDS() only returns whole seconds). + 19990819-02:23 GMT+1 Bruno Cantero * funclist.txt source/rdd/rddsys.prg diff --git a/harbour/config/os2/icc.cf b/harbour/config/os2/icc.cf index 1347d4e78c..969f56b701 100644 --- a/harbour/config/os2/icc.cf +++ b/harbour/config/os2/icc.cf @@ -20,11 +20,17 @@ LD_OUT = /Fe LDFLAGS = /C- ifeq ($(HB_LIB_COMPILE),) LINKLIBS = $(foreach lib, $(LIBS), $(TOP)$(ROOT)source/$(lib)/$(ARCH)/$(lib)$(LIB_EXT)) +# If LIBS specifies the rdd library, add all DB drivers. +ifeq ($(findstring rdd,$(LIBS)),rdd) LINKLIBS += $(foreach lib, $(HB_DB_DRIVERS), $(TOP)$(ROOT)source/rdd/$(lib)/$(ARCH)/$(lib)$(LIB_EXT)) +endif else LINKLIBS = $(foreach lib, $(LIBS), $(lib)$(LIB_EXT)) +# If LIBS specifies the rdd library, add all DB drivers. +ifeq ($(findstring rdd,$(LIBS)),rdd) LINKELIBS += $(foreach lib, $(HB_DB_DRIVERS), $(lib)$(LIB_EXT)) endif +endif AR = ilib ARFLAGS = /NOE diff --git a/harbour/include/inkey.h b/harbour/include/inkey.h index 6294aa8918..547790e01a 100644 --- a/harbour/include/inkey.h +++ b/harbour/include/inkey.h @@ -32,6 +32,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit their web site at http://www.gnu.org/). + V 1.7 David G. Holm Added hb_releaseCPU() V 1.2 Victor Szel #include changed to #include "x". V 1.1 David G. Holm Committed to CVS. V 1.0 David G. Holm Initial version. @@ -41,6 +42,7 @@ #define HB_INKEY_H_ #include "hbdefs.h" +#include "set.h" /* for HB_inkey_enum */ /* Harbour keyboard support functions */ extern int hb_inkey ( double seconds, HB_inkey_enum event_mask, int wait, int forever ); /* Wait for keyboard input */ @@ -49,5 +51,5 @@ extern int hb_inkeyLast( void ); /* Return the value of the last key extern int hb_inkeyNext( void ); /* Return the next key without extracting it */ 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 void hb_releaseCPU( void ); /* Attempt to release a CPU time slice */ #endif diff --git a/harbour/source/rtl/dates.c b/harbour/source/rtl/dates.c index 5a815f691b..3700955829 100644 --- a/harbour/source/rtl/dates.c +++ b/harbour/source/rtl/dates.c @@ -89,7 +89,7 @@ HB_INIT_SYMBOLS_END( Dates__InitSymbols ) /* The other functions are pulled in automatically by initsymb.c */ -double hb_seconds( void ) +double hb_secondsToday( void ) { #if defined(__TURBOC__) || defined(__BORLANDC__) || defined(__DJGPP__) /* || defined(_MSC_VER) */ struct time t; @@ -702,7 +702,7 @@ HARBOUR HB_CDOW( void ) HARBOUR HB_SECONDS( void ) { if( hb_pcount() == 0 ) - hb_retnd( hb_seconds() ); + hb_retnd( hb_secondsToday() ); else { /* QUESTION: Clipper catches this at compile time! */ diff --git a/harbour/source/rtl/environ.c b/harbour/source/rtl/environ.c index a1781f4ac0..61af6b4438 100644 --- a/harbour/source/rtl/environ.c +++ b/harbour/source/rtl/environ.c @@ -210,8 +210,8 @@ HARBOUR HB_OS(void) HARBOUR HB_VERSION(void) { char hb_ver[ 80 ]; - sprintf( hb_ver, "Harbour %d.%d%s Intl. (Build %d) (%04d.%02d.%02d)", - hb_major, hb_minor, hb_revision, hb_build, hb_year, hb_month, hb_day ); + sprintf( hb_ver, "Harbour %d.%d Intl. (Build %d%s) (%04d.%02d.%02d)", + hb_major, hb_minor, hb_build, hb_revision, hb_year, hb_month, hb_day ); hb_retc( hb_ver ); } diff --git a/harbour/source/rtl/gtapi.c b/harbour/source/rtl/gtapi.c index d0daade5a3..75d90007b7 100644 --- a/harbour/source/rtl/gtapi.c +++ b/harbour/source/rtl/gtapi.c @@ -704,18 +704,16 @@ int hb_gtWriteCon(char * fpStr, ULONG length) int rc = 0, ldisp=FALSE, nLen = 0; USHORT uiRow = s_uiCurrentRow, uiCol = s_uiCurrentCol; USHORT tmpRow = s_uiCurrentRow, tmpCol = s_uiCurrentCol; - ULONG count; - char ch[2]; + int ch; char * fpPtr = fpStr; - char strng[500]; + #define STRNG_SIZE 500 + char strng[ STRNG_SIZE ]; - hb_gtDispBegin(); - - ch[1] = 0; - for(count = 0; count < length; count++) +/* hb_gtDispBegin(); */ + while( length ) { - ch [0] = *fpPtr++; - switch(ch [0]) + ch = *fpPtr++; + switch( ch ) { case 7: break; @@ -754,8 +752,7 @@ int hb_gtWriteCon(char * fpStr, ULONG length) case 13: uiCol = 0; - if( ! (*fpPtr == 0x0a )) - nLen = 0 ; + if( *fpPtr != '\n') ldisp=TRUE; /* hb_gtSetPos (uiRow, uiCol); */ break; @@ -767,51 +764,32 @@ int hb_gtWriteCon(char * fpStr, ULONG length) ++uiRow; ldisp = TRUE; } - if( ldisp ) - { - hb_gtSetPos (tmpRow, tmpCol); - if( nLen ) - rc = hb_gtWrite(strng, nLen ); - hb_gtDispEnd(); - hb_gtDispBegin(); - nLen=0; - } - if( uiRow > s_uiMaxRow ) - { - hb_gtScroll(0, 0, s_uiMaxRow, s_uiMaxCol, uiRow - s_uiMaxRow, 0); - uiRow = s_uiMaxRow; - uiCol = 0; - } - - if( ldisp ) - { - tmpRow=uiRow; tmpCol=uiCol; - hb_gtSetPos( uiRow, uiCol); - ldisp = FALSE; - } - strng[nLen++] = ch[0]; + strng[ nLen++ ] = ch; + if( nLen >= STRNG_SIZE ) ldisp = TRUE; } - if(rc) + length--; + if( ldisp || ! length ) + { + hb_gtSetPos( tmpRow, tmpCol ); + if( nLen ) + rc = hb_gtWrite( strng, nLen ); +/* hb_gtDispEnd(); */ +/* hb_gtDispBegin(); */ + nLen=0; + if( uiRow > s_uiMaxRow ) + { + hb_gtScroll( 0, 0, s_uiMaxRow, s_uiMaxCol, uiRow - s_uiMaxRow, 0 ); + uiRow = s_uiMaxRow; + uiCol = 0; + } + tmpRow=uiRow; tmpCol=uiCol; + hb_gtSetPos( uiRow, uiCol); + ldisp = FALSE; + } + if( rc ) break; } - - if( !rc ) - { - hb_gtSetPos (tmpRow, tmpCol); - if( nLen ) - rc = hb_gtWrite(strng, nLen ); - if( uiRow > s_uiMaxRow ) - { - hb_gtScroll(0, 0, s_uiMaxRow, s_uiMaxCol, uiRow - s_uiMaxRow, 0); - uiRow = s_uiMaxRow; - uiCol = 0; - } - - hb_gtSetPos (uiRow, uiCol); - } - - hb_gtDispEnd(); - +/* hb_gtDispEnd(); */ return rc; } diff --git a/harbour/source/rtl/inkey.c b/harbour/source/rtl/inkey.c index 83222d7fc7..52cc7d8172 100644 --- a/harbour/source/rtl/inkey.c +++ b/harbour/source/rtl/inkey.c @@ -29,6 +29,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit their web site at http://www.gnu.org/). + V 1.15 David G. Holm Tested Borland 3.1 hb_releaseCPU() V 1.5 Paul Tucker ReleaseCPU comments V 1.4 Victor Szel V 1.3 Victor Szel #include changed to #include "x". @@ -77,7 +78,6 @@ #include "errorapi.h" #include "extend.h" #include "init.h" -#include "set.h" #include "inkey.h" HARBOUR HB___KEYBOARD( void ); @@ -126,26 +126,25 @@ void hb_releaseCPU( void ) returns zero on failure. (means not supported) */ -/* - -#if defined(__TURBOC__) +#if defined(DOS) + #if defined(__TURBOC__) _AX = 0x1680; geninterrupt(0x2f); _AH = 0; _AL ^= 0x80; -#else + #else union REGS regs; regs.h.ah = 0x16; regs.h.al = 0x80; -#if defined(__WATCOMC__) && defined(__386__) + #if defined(__WATCOMC__) && defined(__386__) int386(0x2f, ®s, ®s); -#else + #else int86(0x2f, ®s, ®s); -#endif + #endif regs.h.ah = 0; regs.h.al ^= 0x80; + #endif #endif -*/ } int hb_inkey ( double seconds, HB_inkey_enum event_mask, int wait, int forever ) diff --git a/harbour/source/rtl/tone.c b/harbour/source/rtl/tone.c index 69a538da04..4a21a1a6ef 100644 --- a/harbour/source/rtl/tone.c +++ b/harbour/source/rtl/tone.c @@ -30,6 +30,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit their web site at http://www.gnu.org/). + V 1.4 David G. Holm Upper limit for frequency for OS/2 + DosBeep() is 32767. The CA-Clipper + Tone() function does not have an + upper limit on the duration, so I + had to add an inner loop to deal + with very long durations. There are + actually 18.2 Clipper (PC) timer + ticks per second. V 1.2 David G. Holm Added OS/2 GCC/EMX support. V 1.1 David G. Holm Split machine dependent code into hb_tone() function for internal use @@ -47,6 +55,7 @@ #include "extend.h" #include "init.h" +#include "inkey.h" /* For hb_releaseCPU() */ #if defined(HARBOUR_GCC_OS2) ULONG DosBeep (ULONG ulFrequency, ULONG ulDuration); @@ -62,16 +71,16 @@ * $SYNTAX$ * TONE( , ) --> NIL * $ARGUMENTS$ - * is a positive numeric value in the range of 37..32767 - * specifies the frequency of the tone in herts. - * + * is a non-negative numeric value that specifies the + * frequency of the tone in hertz. * is a positive numeric value which specifies the duration * of the tone in 1/18 of a second units. * $RETURNS$ * TONE() always return NIL. * $DESCRIPTION$ * TONE() is a sound function that could be used to irritate the end - * user, his or her dog and the surrounding neighborhood. + * user, his or her dog, and the surrounding neighborhood. The frequency + * is clamped to the range 0 to 32767 Hz. * $EXAMPLES$ * If lOk // Good Sound * TONE( 500, 1 ) @@ -86,11 +95,11 @@ * TONE( 800, 1 ) // same as ? CHR(7) * TONE( 32000, 200 ) // any dogs around yet? * TONE( 130.80, 1 ) // musical note - C - * TONE( 400, 0 ) // short beep in CA-Clipper - * TONE( 700 ) // short beep in CA-Clipper - * TONE( 10, 1 ) // do nothing in CA-Clipper - * TONE( -1 ) // do nothing in CA-Clipper - * TONE( ) // do nothing in CA-Clipper + * TONE( 400, 0 ) // short beep + * TONE( 700 ) // short beep + * TONE( 10, 18.2 ) // 1 second delay + * TONE( -1 ) // 1/18.2 second delay + * TONE( ) // 1/18.2 second delay * $STATUS$ * * $COMPLIANCE$ @@ -113,38 +122,71 @@ HB_INIT_SYMBOLS_END( Tone__InitSymbols ) void hb_tone( double frequency, double duration ) { /* platform specific code */ - /* - If duration is in ms, the conversion from - Clipper 1/18 sec is * 1000.0 / 18.0 - */ + /* + The conversion from Clipper timer tick units to + milliseconds is * 1000.0 / 18.2. + */ /* TODO: add more platform support */ #if defined(HARBOUR_GCC_OS2) - frequency = MIN( MAX( 0.0, frequency ), ULONG_MAX ); - duration = duration * 1000.0 / 18.0; - duration = MIN( MAX ( 0.0, duration ), ULONG_MAX ); - DosBeep( ( ULONG ) frequency, ( ULONG ) duration ); -#elif defined(OS2) - frequency = MIN( MAX( 0.0, frequency ), 65535.0 ); - duration = duration * 1000.0 / 18.0; - duration = MIN( MAX ( 0.0, duration ), 65535.0 ); - DosBeep( ( USHORT ) frequency, ( USHORT ) duration ); -#elif defined(__BORLANDC__) - frequency = MIN( MAX( 0.0, frequency ), 65535.0 ); - duration = duration * 1000.0 / 18.0; - duration = MIN( MAX ( 0.0, duration ), 65535.0 ); - sound( ( unsigned ) frequency ); - delay( ( unsigned ) duration ); - nosound(); + ULONG temp; +#elif defined(OS2) || defined(__BORLANDC__) + USHORT temp; #elif defined(__DJGPP__) - /* Note: delay() in does not work! */ - clock_t end_clock; - frequency = MIN( MAX( 0.0, frequency ), 32767.0 ); - duration = duration * CLOCKS_PER_SEC / 18.0 ; - duration = MIN( MAX ( 0.0, duration ), 65535.0 ); - sound( ( int ) frequency ); - end_clock = clock() + ( clock_t ) duration; - while( clock() < end_clock ); - sound( 0 ); + USHORT temp; /* Use USHORT, because this variable gets added to clock() + to form end_clock and we want to minimize overflow risk */ + clock_t end_clock; +#else + /* Unsupported platform. */ + ULONG temp; /* Avoid unreferenced temp */ + duration = -1; /* Exit without delay */ +#endif +#if defined(HARBOUR_GCC_OS2) || defined(OS2) || defined(__BORLANDC__) + frequency = MIN( MAX( 0.0, frequency ), 32767.0 ); + duration = duration * 1000.0 / 18.2; /* milliseconds */ +#endif +#if defined(__BORLANDC__) + sound( ( unsigned ) frequency ); +#elif defined(__DJGPP__) + /* Note: delay() in does not work! */ + frequency = MIN( MAX( 0.0, frequency ), 32767.0 ); + duration = duration * CLOCKS_PER_SEC / 18.2 ; /* clocks */ + sound( ( int ) frequency ); +#endif + while( duration > 0.0 ) + { +#if defined(HARBOUR_GCC_OS2) + temp = MIN( MAX ( 0, duration ), ULONG_MAX ); +#elif defined(OS2) || defined(__BORLANDC__) || defined(__DJGPP__) + temp = MIN( MAX ( 0, duration ), USHRT_MAX ); +#endif + duration -= temp; + if( temp <= 0 ) + { + // Ensure that the loop gets terminated when + // only a fraction of the delay time remains. + duration = -1.0; + } + else + { +#if defined(HARBOUR_GCC_OS2) + DosBeep( ( ULONG ) frequency, ( ULONG ) temp ); +#elif defined(OS2) + DosBeep( ( USHORT ) frequency, ( USHORT ) temp ); +#elif defined(__BORLANDC__) + delay( temp ); /* Probably not multi-tasking OS friendly! + TODO: Change from delay() to clock() method? */ +#elif defined(__DJGPP__) + end_clock = clock() + ( clock_t ) temp; + while( clock() < end_clock ) + hb_releaseCPU(); +#endif + } + hb_releaseCPU(); /* Try to be somewhat multi-tasking OS friendly */ + } +#if defined(__BORLANDC__) + nosound(); +#elif defined(__DJGPP__) + sound( 0 ); #endif } diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index 5902d6ac2f..e0223bd6e6 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -822,8 +822,13 @@ void hb_vmDivide( void ) double d1 = hb_vmPopDouble( &wDec1 ); /* NOTE: Clipper always returns the result of a division - with the SET number of decimal places. */ - hb_vmPushNumber( d1 / d2, hb_set.HB_SET_DECIMALS ); + with the SET number of decimal places, unless the + divisor is zero, in which case the result is zero + with zero decimal places. */ + if( d2 == 0.0 ) + hb_vmPushInteger( 0 ); + else + hb_vmPushNumber( d1 / d2, hb_set.HB_SET_DECIMALS ); } void hb_vmDo( WORD wParams ) diff --git a/harbour/tests/working/mathtest.prg b/harbour/tests/working/mathtest.prg index 16f2df6bf4..3d6daba5b6 100644 --- a/harbour/tests/working/mathtest.prg +++ b/harbour/tests/working/mathtest.prg @@ -3,8 +3,8 @@ // func main() -qout( 1 / 0 ) -qout( 1 % 0 ) + qout( 1 % 0 ) + qout( 1 / 0 ) qout( sin( 33 ) ) qout( cos( 43 ) ) qout( tan( 54 ) ) @@ -24,6 +24,7 @@ qout( 1 % 0 ) qout( max( 1.0, 1 ) ) qout( max( 1, 10 ) ) qout( min( stod( "19990101" ), stod( "20000101" ) ) ) - qout( max( stod( "19990101" ), stod( "20000101" ) ), "An argument error will appear on the next line.") + qout( max( stod( "19990101" ), stod( "20000101" ) ) ) + qout("An argument error will be generated.") qout( min( stod( "19990101" ), 20000101 ) ) return nil diff --git a/harbour/tests/working/sound.prg b/harbour/tests/working/sound.prg index 44a208021d..759db7b2f4 100644 --- a/harbour/tests/working/sound.prg +++ b/harbour/tests/working/sound.prg @@ -1,5 +1,10 @@ function main() - tone( 440, 9 ) - tone( 880, 9 ) - tone( 440, 9 ) +local start := seconds(), stop + qout( "start ", start ) + tone( 440, 9.1 ) + tone( 880, 9.1 ) + tone( 440, 9.1 ) + stop := seconds() + qout( "stop ", stop ) + qout( "duration", ( stop - start ), "(should be close to 1.5)" ) return nil