@@ -339,4 +339,3 @@ consider it more useful to permit linking proprietary applications with the | |||
library. If this is what you want to do, use the GNU Library General | |||
Public License instead of this License. | |||
@@ -1,5 +1,10 @@ | |||
# Unix Makefile for Bywater BASIC Interpreter | |||
##---------------------------------------------------------------## | |||
## NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, ## | |||
## 11/1995 (eidetics@cerf.net). ## | |||
##---------------------------------------------------------------## | |||
srcdir = @srcdir@ | |||
VPATH = @srcdir@ | |||
@@ -11,8 +16,12 @@ INSTALL_DATA = @INSTALL_DATA@ | |||
DEFS = @DEFS@ | |||
CFLAGS = -O | |||
LDFLAGS = -s | |||
# Revised by JBV | |||
#CFLAGS = -O | |||
CFLAGS = -g -ansi | |||
# Revised by JBV | |||
#LDFLAGS = -s | |||
prefix = /usr/local | |||
exec_prefix = $(prefix) | |||
@@ -45,15 +54,21 @@ TESTFILES= \ | |||
mlifthen.bas on.bas onerr.bas onerrlbl.bas ongosub.bas\ | |||
opentest.bas option.bas putget.bas random.bas selcase.bas\ | |||
snglfunc.bas stop.bas term.bas whilwend.bas width.bas\ | |||
writeinp.bas | |||
writeinp.bas pascaltr.bas | |||
DISTFILES= $(CFILES) $(HFILES) $(MISCFILES) | |||
all: bwbasic | |||
# Revised by JBV | |||
#all: bwbasic | |||
all: bwbasic renum | |||
bwbasic: $(OFILES) | |||
$(CC) $(OFILES) -lm -o $@ $(LDFLAGS) | |||
# Added by JBV | |||
renum: | |||
$(CC) renum.c -o renum | |||
$(OFILES): $(HFILES) | |||
.c.o: | |||
@@ -86,8 +101,9 @@ distclean: clean | |||
realclean: distclean | |||
rm -f TAGS | |||
# Version number changed from 2.10 to 2.20 by JBV | |||
dist: $(DISTFILES) | |||
echo bwbasic-2.10 > .fname | |||
echo bwbasic-2.20 > .fname | |||
rm -rf `cat .fname` | |||
mkdir `cat .fname` | |||
ln $(DISTFILES) `cat .fname` | |||
@@ -98,4 +114,3 @@ dist: $(DISTFILES) | |||
# Prevent GNU make v3 from overflowing arg limit on SysV. | |||
.NOEXPORT: | |||
@@ -1,14 +1,17 @@ | |||
Bywater Software Announces | |||
README file for | |||
Bywater BASIC Interpreter/Shell, version 2.10 | |||
Bywater BASIC Interpreter/Shell, version 2.20 | |||
--------------------------------------------- | |||
Copyright (c) 1993, Ted A. Campbell | |||
for bwBASIC version 2.10, 11 October 1993 | |||
Version 2.20 modifications by Jon B. Volkoff, | |||
25 November 1995 | |||
DESCRIPTION: | |||
@@ -29,40 +32,50 @@ DESCRIPTION: | |||
for information on which you should contact the author. | |||
IMPROVEMENTS OVER PREVIOUS VERSION (1.11): | |||
IMPROVEMENTS OVER PREVIOUS VERSION (2.10): | |||
* Plugged numerous memory leaks, resolved memory overruns and allocation | |||
difficulties. | |||
* General cleanup and bug fixes, too many to list in detail here. | |||
The major problem areas addressed were: | |||
- RUN command with file name argument | |||
- nested and cascaded FOR-NEXT loops | |||
- PRINT USING | |||
- EOF, LOF functions | |||
- string concatenation | |||
- operator hierarchy | |||
- multi-level expression evaluation | |||
- hex constant interpretation | |||
- hex and octal constants in INPUT and DATA statements | |||
* now compilable on "stock" (older K&R specification) C compilers; | |||
* Added a CLOSE all files feature (when no argument supplied). | |||
* implements ANSI-BASIC-style structured programming, with | |||
called subroutines, multi-line functions, multi-line IF-THEN | |||
ELSE statements, SELECT CASE statements, etc.; | |||
* Added a unary minus sign operator. | |||
* new enhancements to the interactive environment, such as DO NUM | |||
and DO UNNUM to number or unnumber all program lines; | |||
* Added a MID$ command to complement the MID$ function. | |||
* addition of some hardware-specific commands such as CLS, LOCATE, | |||
and INKEY$ (at present for IBM PC and compatibles, using the | |||
Microsoft QuickC compiler), opening the way for more hardware- | |||
specific commands and functions in the future; | |||
* Added a RENUM facility in a standalone program. | |||
* general improvements to reliability and portability, including | |||
more extensive testing than previous versions; | |||
* Added checking in configure for unistd.h (important on Sun systems). | |||
OBTAINING THE SOURCE CODE: | |||
The source code for bwBASIC 2.10 will be posted to network news | |||
groups and is available immediately by anonymous ftp. To obtain | |||
the source code, ftp to site ftp.eng.umd.edu, cd to pub/basic and | |||
get the file bwbasic-2.10.tar.gz. | |||
The source code for bwBASIC 2.20 is available immediately by | |||
anonymous ftp. To obtain the source code, ftp to site ftp.netcom.com, | |||
cd to pub/rh/rhn and get the file bwbasic-2.20.uu. Or you may receive | |||
a copy by e-mail by writing to Jon Volkoff at eidetics@cerf.net. | |||
COMMUNICATIONS: | |||
email: tcamp@delphi.com | |||
email: tcamp@delphi.com (for Ted Campbell) | |||
eidetics@cerf.net (for Jon Volkoff) | |||
A LIST OF BASIC COMMANDS AND FUNCTIONS IMPLEMENTED in bwBASIC 2.10: | |||
A LIST OF BASIC COMMANDS AND FUNCTIONS IMPLEMENTED in bwBASIC 2.20: | |||
Be aware that many of these commands and functions will not be | |||
available unless you have set certain flags in the header files. | |||
@@ -96,7 +109,7 @@ A LIST OF BASIC COMMANDS AND FUNCTIONS IMPLEMENTED in bwBASIC 2.10: | |||
DIM variable(elements...)[variable(elements...)]... | |||
DO NUM|UNNUM | |||
DO [WHILE expression] | |||
EDIT (* depends on variable BWB.EDITOR$) | |||
EDIT (* depends on variable BWB.EDITOR$) | |||
ELSE | |||
ELSEIF | |||
END FUNCTION | IF | SELECT | SUB | |||
@@ -110,7 +123,7 @@ A LIST OF BASIC COMMANDS AND FUNCTIONS IMPLEMENTED in bwBASIC 2.10: | |||
EXIT FOR|DO | |||
EXP( number ) | |||
FIELD [#] device-number, number AS string-variable [, number AS string-variable...] | |||
FILES filespec$ (* depends on variable BWB.FILES$) | |||
FILES filespec$ (* depends on variable BWB.FILES$) | |||
FOR counter = start TO finish [STEP increment] | |||
FUNCTION function-definition | |||
GET [#] device-number [, record-number] | |||
@@ -156,6 +169,7 @@ A LIST OF BASIC COMMANDS AND FUNCTIONS IMPLEMENTED in bwBASIC 2.10: | |||
RANDOMIZE number | |||
READ variable[, variable]... | |||
REM string | |||
RENUM | |||
RESTORE line | |||
RETURN | |||
RIGHT$( string$, number-of-spaces ) | |||
@@ -46,6 +46,14 @@ | |||
***************************************************************/ | |||
/*---------------------------------------------------------------*/ | |||
/* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */ | |||
/* 11/1995 (eidetics@cerf.net). */ | |||
/* */ | |||
/* Those additionally marked with "DD" were at the suggestion of */ | |||
/* Dale DePriest (daled@cadence.com). */ | |||
/*---------------------------------------------------------------*/ | |||
#include <stdio.h> | |||
#include <math.h> | |||
#include <ctype.h> | |||
@@ -710,7 +718,8 @@ bwb_on( l ) | |||
/* get memory for line and buffer */ | |||
if ( ( oline = calloc( 1, sizeof( struct bwb_line ) ) ) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( oline = CALLOC( 1, sizeof( struct bwb_line ), "bwb_on") ) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in bwb_on(): failed to find memory for oline" ); | |||
@@ -718,7 +727,8 @@ bwb_on( l ) | |||
bwb_error( err_getmem ); | |||
#endif | |||
} | |||
if ( ( oline->buffer = calloc( 1, MAXSTRINGSIZE + 1 ) ) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( oline->buffer = CALLOC( 1, MAXSTRINGSIZE + 1, "bwb_on") ) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in bwb_on(): failed to find memory for oline buffer" ); | |||
@@ -983,22 +993,27 @@ bwb_run( l ) | |||
bwb_error( bwb_ebuf ); | |||
} | |||
bwb_fload( input ); /* load program */ | |||
bwb_run( &CURTASK bwb_start ); /* and call bwb_run() recursively */ | |||
/* Next line removed by JBV (unnecessary recursion asks for trouble) */ | |||
/* bwb_run( &CURTASK bwb_start ); */ /* and call bwb_run() recursively */ | |||
current = &CURTASK bwb_start; /* JBV */ | |||
} | |||
/* else if it is a line number, execute the program in memory | |||
at that line number */ | |||
else | |||
{ | |||
/* Removed by JBV */ | |||
/* else | |||
{ */ | |||
if ( current == NULL ) | |||
{ | |||
/* Removed by JBV */ | |||
/* if ( current == NULL ) | |||
{ */ | |||
if ( e != NULL ) | |||
{ | |||
/* Added expression type check and changed loop boundaries (JBV) */ | |||
if (( e != NULL ) && ( e->type != STRING )) | |||
{ | |||
go_lnumber = (int) exp_getnval( e ); | |||
} | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_run(): element detected <%s>, lnumber <%d>", | |||
@@ -1015,6 +1030,8 @@ bwb_run( l ) | |||
} | |||
} | |||
/* } */ /* Removed by JBV */ | |||
if ( current == NULL ) | |||
{ | |||
sprintf( bwb_ebuf, err_lnnotfound, go_lnumber ); | |||
@@ -1037,7 +1054,7 @@ bwb_run( l ) | |||
CURTASK exsc = 0; | |||
bwb_setexec( current, 0, EXEC_NORM ); | |||
} | |||
/* } */ /* Removed by JBV */ | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_run(): function complete." ); | |||
@@ -1178,6 +1195,7 @@ bwb_xload( l ) | |||
#endif | |||
{ | |||
FILE *loadfile; | |||
struct exp_ese *e; /* JBV */ | |||
/* Get an argument for filename */ | |||
@@ -1188,13 +1206,31 @@ bwb_xload( l ) | |||
case '\n': | |||
case '\r': | |||
case ':': | |||
bwb_error( err_nofn ); /* Added by JBV (bug found by DD) */ | |||
return bwb_zline( l ); | |||
default: | |||
break; | |||
} | |||
bwb_const( l->buffer, CURTASK progfile, &( l->position ) ); | |||
/* Section added by JBV (bug found by DD) */ | |||
e = bwb_exp( l->buffer, FALSE, &( l->position ) ); | |||
if ( e->type != STRING ) | |||
{ | |||
#if PROG_ERRORS | |||
sprintf( bwb_ebuf, "in bwb_xload(): Missing filespec" ); | |||
bwb_error( bwb_ebuf ); | |||
#else | |||
bwb_error( err_syntax ); | |||
#endif | |||
return bwb_zline( l ); | |||
} | |||
/* This line removed by JBV (no longer required) */ | |||
/* bwb_const( l->buffer, CURTASK progfile, &( l->position ) ); */ | |||
str_btoc( CURTASK progfile, exp_getsval( e ) ); /* JBV */ | |||
if ( ( loadfile = fopen( CURTASK progfile, "r" )) == NULL ) | |||
{ | |||
sprintf( bwb_ebuf, err_openfile, CURTASK progfile ); | |||
@@ -1214,7 +1250,7 @@ bwb_xload( l ) | |||
FUNCTION: bwb_save() | |||
DESCRIPTION: This C function implements the BASIC | |||
LOAD command. | |||
SAVE command. | |||
SYNTAX: SAVE file-name | |||
@@ -1231,6 +1267,7 @@ bwb_save( l ) | |||
{ | |||
FILE *outfile; | |||
static char filename[ MAXARGSIZE ]; | |||
struct exp_ese *e; /* JBV */ | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_save(): entered function." ); | |||
@@ -1253,7 +1290,24 @@ bwb_save( l ) | |||
break; | |||
} | |||
bwb_const( l->buffer, filename, &( l->position ) ); | |||
/* Section added by JBV (bug found by DD) */ | |||
e = bwb_exp( l->buffer, FALSE, &( l->position ) ); | |||
if ( e->type != STRING ) | |||
{ | |||
#if PROG_ERRORS | |||
sprintf( bwb_ebuf, "in bwb_save(): Missing filespec" ); | |||
bwb_error( bwb_ebuf ); | |||
#else | |||
bwb_error( err_syntax ); | |||
#endif | |||
return bwb_zline( l ); | |||
} | |||
/* This line removed by JBV (no longer required) */ | |||
/* bwb_const( l->buffer, filename, &( l->position ) ); */ | |||
str_btoc( filename, exp_getsval( e ) ); /* JBV */ | |||
if ( ( outfile = fopen( filename, "w" )) == NULL ) | |||
{ | |||
sprintf( bwb_ebuf, err_openfile, filename ); | |||
@@ -1476,7 +1530,7 @@ xl_line( file, l ) | |||
if (( file == stdout ) || ( file == stderr )) | |||
{ | |||
if ( l->xnum == TRUE ) | |||
if ( l->xnum == (char) TRUE ) /* Better recast this one (JBV) */ | |||
{ | |||
sprintf( tbuf, "%7d: %s\n", l->number, l->buffer ); | |||
} | |||
@@ -1490,7 +1544,7 @@ xl_line( file, l ) | |||
else | |||
{ | |||
if ( l->xnum == TRUE ) | |||
if ( l->xnum == (char) TRUE ) /* Better recast this one (JBV) */ | |||
{ | |||
fprintf( file, "%d %s\n", l->number, l->buffer ); | |||
} | |||
@@ -1556,7 +1610,8 @@ bwb_delete( l ) | |||
{ | |||
if ( current != l ) | |||
{ | |||
if (( current->xnum == TRUE ) && ( current->number == s )) | |||
/* Following line revised by JBV */ | |||
if (( current->xnum == (char) TRUE ) && ( current->number == s )) | |||
{ | |||
f = TRUE; | |||
previous = p; | |||
@@ -1589,7 +1644,8 @@ bwb_delete( l ) | |||
{ | |||
if ( current != l ) | |||
{ | |||
if (( current->xnum == TRUE) && ( current->number == e )) | |||
/* Following line revised by JBV */ | |||
if (( current->xnum == (char) TRUE) && ( current->number == e )) | |||
{ | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_delete(): end line number is <%d>", | |||
@@ -1989,7 +2045,9 @@ bwb_xnew( l ) | |||
{ | |||
if ( wait != TRUE ) | |||
{ | |||
free( previous ); | |||
/* Revised to FREE pass-thru call by JBV */ | |||
FREE( previous, "bwb_xnew" ); | |||
previous = NULL; /* JBV */ | |||
} | |||
wait = FALSE; | |||
previous = current; | |||
@@ -2214,4 +2272,3 @@ bwb_zline( l ) | |||
} | |||
@@ -23,6 +23,14 @@ | |||
***************************************************************/ | |||
/*---------------------------------------------------------------*/ | |||
/* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */ | |||
/* 11/1995 (eidetics@cerf.net). */ | |||
/* */ | |||
/* Those additionally marked with "DD" were at the suggestion of */ | |||
/* Dale DePriest (daled@cadence.com). */ | |||
/*---------------------------------------------------------------*/ | |||
#include <stdio.h> | |||
#include <math.h> | |||
#include <ctype.h> | |||
@@ -180,7 +188,11 @@ bwb_if( l ) | |||
} | |||
else | |||
{ | |||
bwb_setexec( endif_line, 0, CURTASK excs[ CURTASK exsc ].code ); | |||
/* Following line incorrect, replaced by next two (bug found by DD) */ | |||
/* bwb_setexec( endif_line, 0, CURTASK excs[ CURTASK exsc ].code ); */ | |||
bwb_incexec(); /* JBV */ | |||
bwb_setexec( endif_line, 0, EXEC_IFFALSE ); /* JBV */ | |||
endif_line->position = 0; | |||
return endif_line; | |||
} | |||
@@ -265,13 +277,14 @@ bwb_if( l ) | |||
if ( els != FALSE ) | |||
{ | |||
l->position = els + strlen( CMD_ELSE ) + 1; | |||
bwb_setexec( l, els, EXEC_NORM ); | |||
/* bwb_setexec( l, els, EXEC_NORM ); */ /* Nope (JBV) */ | |||
bwb_setexec( l, els, CURTASK excs[ CURTASK exsc ].code ); /* JBV */ | |||
return l; | |||
} | |||
} | |||
/* if neither then nor else were found, advance to next line */ | |||
/* DO NOT advance to next segment (only if TRUE should we do that */ | |||
/* DO NOT advance to next segment (only if TRUE should we do that) */ | |||
l->next->position = 0; | |||
return l->next; | |||
@@ -437,7 +450,13 @@ bwb_else( l ) | |||
/* If the code is EXEC_NORM, then this is a continuation of a single- | |||
line IF...THEN...ELSE... statement and we should return */ | |||
if ( CURTASK excs[ CURTASK exsc ].code == EXEC_NORM ) | |||
/*----------------------------------------------------------------------*/ | |||
/* Well, not really... better to check for EXEC_IFTRUE or EXEC_IFFALSE, */ | |||
/* and if not equal, then blow entirely out of current line (JBV) */ | |||
/*----------------------------------------------------------------------*/ | |||
/* Section removed by JBV */ | |||
/* if ( CURTASK excs[ CURTASK exsc ].code == EXEC_NORM ) | |||
{ | |||
#if INTENSIVE_DEBUG | |||
@@ -446,6 +465,20 @@ bwb_else( l ) | |||
#endif | |||
return bwb_zline( l ); | |||
} */ | |||
/* Section added by JBV */ | |||
if (( CURTASK excs[ CURTASK exsc ].code != EXEC_IFTRUE ) && | |||
( CURTASK excs[ CURTASK exsc ].code != EXEC_IFFALSE )) | |||
{ | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_else(): no EXEC_IFTRUE or EXEC_IFFALSE" ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
l->next->position = 0; | |||
return l->next; | |||
} | |||
endif_line = find_endif( l, &else_line ); | |||
@@ -1751,6 +1784,14 @@ bwb_for( l ) | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
/*--------------------------------------------------------------*/ | |||
/* Make sure we are in the right FOR-NEXT level! */ | |||
/* If we aren't (which could happen for legit reasons), fix the */ | |||
/* exec stack. */ | |||
/* JBV, 9/20/95 */ | |||
/*--------------------------------------------------------------*/ | |||
if (v == CURTASK excs[ CURTASK exsc].local_variable) bwb_decexec(); | |||
/* at this point one should find an equals sign ('=') */ | |||
adv_ws( l->buffer, &( l->position ) ); | |||
@@ -1972,9 +2013,7 @@ bwb_next( l ) | |||
#endif | |||
{ | |||
char tbuf[ MAXSTRINGSIZE + 1 ]; | |||
#if INTENSIVE_DEBUG | |||
struct bwb_variable *v; | |||
#endif | |||
struct bwb_variable *v; /* Relocated from INTENSIVE_DEBUG (JBV) */ | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_next(): entered function, cmdnum <%d> exsc level <%d> code <%d>", | |||
@@ -1997,13 +2036,19 @@ bwb_next( l ) | |||
/* read the argument, if there is one */ | |||
/* Relocated from MULTISEG_LINES (JBV) */ | |||
exp_getvfname( &( l->buffer[ l->position ] ), tbuf ); | |||
if (strlen(tbuf) != 0) | |||
{ | |||
/* Relocated from INTENSIVE_DEBUG (JBV) */ | |||
v = var_find( tbuf ); | |||
#if MULTISEG_LINES /* not currently needed otherwise */ | |||
exp_getvfname( &( l->buffer[ l->position ] ), tbuf ); | |||
l->position += strlen( tbuf ); | |||
#if INTENSIVE_DEBUG | |||
v = var_find( tbuf ); | |||
sprintf( bwb_ebuf, "in bwb_next(): variable name detected <%s>.", v->name ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
@@ -2011,6 +2056,15 @@ bwb_next( l ) | |||
/* decrement or increment the value */ | |||
/*--------------------------------------------------------------*/ | |||
/* Make sure we are in the right FOR-NEXT level! */ | |||
/* If we aren't (which could happen for legit reasons), fix the */ | |||
/* exec stack. */ | |||
/* JBV, 9/20/95 */ | |||
/*--------------------------------------------------------------*/ | |||
while (v != CURTASK excs[ CURTASK exsc].local_variable) bwb_decexec(); | |||
} | |||
var_setnval( CURTASK excs[ CURTASK exsc ].local_variable, | |||
var_getnval( CURTASK excs[ CURTASK exsc ].local_variable ) | |||
+ (bnumber) CURTASK excs[ CURTASK exsc ].for_step ); | |||
@@ -2077,12 +2131,14 @@ bwb_next( l ) | |||
= CURTASK excs[ CURTASK exsc ].for_position; | |||
bwb_setexec( CURTASK excs[ CURTASK exsc ].for_line, | |||
CURTASK excs[ CURTASK exsc ].for_position, EXEC_FOR ); | |||
return CURTASK excs[ CURTASK exsc ].for_line; /* Added (JBV) */ | |||
#else | |||
bwb_setexec( CURTASK excs[ CURTASK exsc - 1 ].line, | |||
CURTASK excs[ CURTASK exsc - 1 ].position, EXEC_FOR ); | |||
#endif | |||
return CURTASK excs[ CURTASK exsc - 1 ].line; | |||
return CURTASK excs[ CURTASK exsc - 1 ].line; /* Relocated (JBV) */ | |||
#endif | |||
} | |||
@@ -2168,7 +2224,8 @@ bwb_exitfor( l ) | |||
/* set the next line in the exec stack */ | |||
next_line->position = 0; | |||
bwb_setexec( next_line, 0, EXEC_NORM ); | |||
/* bwb_setexec( next_line, 0, EXEC_NORM ); */ /* WRONG (JBV) */ | |||
bwb_setexec( next_line, 0, CURTASK excs[ CURTASK exsc ].code ); /* JBV */ | |||
return next_line; | |||
@@ -2405,5 +2462,3 @@ var_setnval( v, i ) | |||
} | |||
@@ -23,6 +23,11 @@ | |||
***************************************************************/ | |||
/*---------------------------------------------------------------*/ | |||
/* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */ | |||
/* 11/1995 (eidetics@cerf.net). */ | |||
/*---------------------------------------------------------------*/ | |||
#include <stdio.h> | |||
#include "bwbasic.h" | |||
@@ -352,7 +357,7 @@ bwb_open( l ) | |||
if ( e->type == STRING ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "String where number was expected for record length" ); | |||
bwb_error( "String where number was expected for dev number" ); | |||
#else | |||
bwb_error( err_syntax ); | |||
#endif | |||
@@ -490,6 +495,9 @@ bwb_open( l ) | |||
/* assign values to device table */ | |||
/* Random mode has a default record length (JBV) */ | |||
if (mode == DEVMODE_RANDOM && rlen == -1) rlen = 128; | |||
dev_table[ req_devnumber ].mode = mode; | |||
dev_table[ req_devnumber ].cfp = fp; | |||
dev_table[ req_devnumber ].reclen = rlen; | |||
@@ -497,11 +505,17 @@ bwb_open( l ) | |||
dev_table[ req_devnumber ].loc = 0; | |||
strcpy( dev_table[ req_devnumber ].filename, devname ); | |||
/* File length finding routine, added by JBV */ | |||
fseek( dev_table[ req_devnumber ].cfp, 0, SEEK_END ); | |||
dev_table[ req_devnumber ].lof = ftell( dev_table[ req_devnumber ].cfp ); | |||
fseek( dev_table[ req_devnumber ].cfp, 0, SEEK_SET ); | |||
/* allocate a character buffer for random access */ | |||
if (( mode == DEVMODE_RANDOM ) && ( previous_buffer != TRUE )) | |||
{ | |||
if ( ( dev_table[ req_devnumber ].buffer = calloc( rlen + 1, 1 )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( dev_table[ req_devnumber ].buffer = CALLOC( rlen + 1, 1, "bwb_open" )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in bwb_open(): failed to find memory for device buffer" ); | |||
@@ -552,14 +566,21 @@ bwb_close( l ) | |||
{ | |||
struct exp_ese *e; | |||
char atbuf[ MAXSTRINGSIZE + 1 ]; | |||
int blanket_close; /* JBV */ | |||
register int n; /* JBV */ | |||
blanket_close = -1; /* JBV */ | |||
req_devnumber = 0; /* JBV */ | |||
/* loop to get device numbers to close */ | |||
do | |||
{ | |||
if ( l->buffer[ l->position ] == ',' && blanket_close == 0) | |||
++( l->position); /* JBV */ | |||
adv_ws( l->buffer, &( l->position ) ); | |||
if ( l->buffer[ l->position ] =='#' ) | |||
if ( l->buffer[ l->position ] == '#') | |||
{ | |||
++( l->position ); | |||
} | |||
@@ -579,7 +600,31 @@ bwb_close( l ) | |||
return bwb_zline( l ); | |||
} | |||
req_devnumber = (int) exp_getnval( e ); | |||
/*-------------------------------------------------------------*/ | |||
/* Added the following section for blanket close feature (JBV) */ | |||
/*-------------------------------------------------------------*/ | |||
if (blanket_close == -1) | |||
if (strlen(atbuf) != 0) blanket_close = 0; | |||
else blanket_close = 1; | |||
if (blanket_close == 0) req_devnumber = (int) exp_getnval( e ); | |||
else | |||
{ | |||
++req_devnumber; | |||
/* Find the next device in use */ | |||
for (n = req_devnumber; n < DEF_DEVICES; ++n) | |||
{ | |||
req_devnumber = -1; | |||
if (( dev_table[ n ].mode != DEVMODE_CLOSED ) && | |||
( dev_table[ n ].mode != DEVMODE_AVAILABLE ) ) | |||
{ | |||
req_devnumber = n; | |||
break; | |||
} | |||
} | |||
if (req_devnumber == -1) break; /* Skidoo if no more to close */ | |||
} | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_close(): requested device number <%d>", | |||
@@ -633,13 +678,20 @@ bwb_close( l ) | |||
dev_table[ req_devnumber ].mode = DEVMODE_CLOSED; | |||
/* Revised to FREE pass-thru call by JBV */ | |||
if ( dev_table[ req_devnumber ].buffer != NULL ) | |||
{ | |||
FREE( dev_table[ req_devnumber ].buffer, "bwb_close" ); /* JBV */ | |||
dev_table[ req_devnumber ].buffer = NULL; /* JBV */ | |||
} | |||
/* eat up any remaining whitespace */ | |||
adv_ws( l->buffer, &( l->position ) ); | |||
} | |||
while ( l->buffer[ l->position ] == ',' ); | |||
while ( l->buffer[ l->position ] == ',' || blanket_close == 1); /* JBV */ | |||
/* return next line number in sequence */ | |||
@@ -680,7 +732,9 @@ bwb_chdir( l ) | |||
if ( init == FALSE ) | |||
{ | |||
init = TRUE; | |||
if ( ( atbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( atbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "bwb_chdir" )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in bwb_chdir(): failed to find memory for atbuf" ); | |||
@@ -758,7 +812,9 @@ bwb_rmdir( l ) | |||
if ( init == FALSE ) | |||
{ | |||
init = TRUE; | |||
if ( ( atbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( atbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "bwb_rmdir" )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in rmdir(): failed to find memory for atbuf" ); | |||
@@ -835,7 +891,9 @@ bwb_mkdir( l ) | |||
if ( init == FALSE ) | |||
{ | |||
init = TRUE; | |||
if ( ( atbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( atbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "bwb_mkdir" )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in bwb_mkdir(): failed to find memory for atbuf" ); | |||
@@ -916,7 +974,9 @@ bwb_kill( l ) | |||
if ( init == FALSE ) | |||
{ | |||
init = TRUE; | |||
if ( ( atbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( atbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "bwb_kill" )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in bwb_kill(): failed to find memory for atbuf" ); | |||
@@ -998,7 +1058,9 @@ bwb_name( l ) | |||
if ( init == FALSE ) | |||
{ | |||
init = TRUE; | |||
if ( ( atbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( atbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "bwb_name" )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in bwb_name(): failed to find memory for atbuf" ); | |||
@@ -1006,7 +1068,8 @@ bwb_name( l ) | |||
bwb_error( err_getmem ); | |||
#endif | |||
} | |||
if ( ( btbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( btbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "bwb_name" )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in bwb_name(): failed to find memory for btbuf" ); | |||
@@ -1269,7 +1332,9 @@ bwb_field( l ) | |||
#if DONTDOTHIS | |||
if ( b->sbuffer != NULL ) | |||
{ | |||
free( b->sbuffer ); | |||
/* Revised to FREE pass-thru call by JBV */ | |||
FREE( b->sbuffer, "bwb_field" ); | |||
b->sbuffer = NULL; /* JBV */ | |||
} | |||
#endif | |||
@@ -1281,7 +1346,7 @@ bwb_field( l ) | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_field(): buffer <%lXh> var <%s> buffer <%lXh>", | |||
(long) dev_table[ dev_number ].buffer, v->name, (long) b->buffer ); | |||
(long) dev_table[ dev_number ].buffer, v->name, (long) b->sbuffer ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
@@ -1466,7 +1531,7 @@ dio_lrset( l, rset ) | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in dio_lrset(): startpos <%d> buffer <%lX>", | |||
startpos, (long) d->buffer ); | |||
startpos, (long) d->sbuffer ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
@@ -1510,6 +1575,7 @@ bwb_get( l ) | |||
register int i; | |||
struct exp_ese *e; | |||
char atbuf[ MAXSTRINGSIZE + 1 ]; | |||
long offset; /* JBV */ | |||
/* first read device number */ | |||
@@ -1583,9 +1649,10 @@ bwb_get( l ) | |||
/* wind the c file up to the proper point */ | |||
if ( fseek( dev_table[ dev_number ].cfp, | |||
(long) (( rec_number - 1 ) * dev_table[ dev_number ].reclen ), | |||
SEEK_SET ) != 0 ) | |||
/* Added by JBV */ | |||
offset = (long) (( rec_number - 1 ) * dev_table[ dev_number ].reclen); | |||
if ( fseek( dev_table[ dev_number ].cfp, offset, SEEK_SET ) != 0 ) | |||
{ | |||
#if PROG_ERRORS | |||
sprintf( bwb_ebuf, "in bwb_get(): fseek() failed, rec number <%d> offset <%ld>", | |||
@@ -1599,6 +1666,7 @@ bwb_get( l ) | |||
/* read the requested bytes into the buffer */ | |||
dev_table[ dev_number ].loc = offset; /* Slight bug fix (JBV) */ | |||
for ( i = 0; i < dev_table[ dev_number ].reclen; ++i ) | |||
{ | |||
dev_table[ dev_number ].buffer[ i ] = | |||
@@ -1639,6 +1707,7 @@ bwb_put( l ) | |||
register int i; | |||
struct exp_ese *e; | |||
char atbuf[ MAXSTRINGSIZE + 1 ]; | |||
long offset; /* JBV */ | |||
/* first read device number */ | |||
@@ -1649,7 +1718,23 @@ bwb_put( l ) | |||
} | |||
adv_element( l->buffer, &( l->position ), atbuf ); | |||
dev_number = atoi( atbuf ); | |||
/* dev_number = atoi( atbuf ); */ /* Not quite right (JBV) */ | |||
/* Added by JBV */ | |||
pos = 0; | |||
e = bwb_exp( atbuf, FALSE, &pos ); | |||
if ( e->type != NUMBER ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in bwb_put(): Number was expected for device number" ); | |||
#else | |||
bwb_error( err_syntax ); | |||
#endif | |||
return bwb_zline( l ); | |||
} | |||
dev_number = (int) exp_getnval( e ); | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_put(): device <%d>", dev_number ); | |||
@@ -1709,9 +1794,10 @@ bwb_put( l ) | |||
/* wind the c file up to the proper point */ | |||
if ( fseek( dev_table[ dev_number ].cfp, | |||
(long) (( rec_number - 1 ) * dev_table[ dev_number ].reclen ), | |||
SEEK_SET ) != 0 ) | |||
/* Added by JBV */ | |||
offset = (long) (( rec_number - 1 ) * dev_table[ dev_number ].reclen); | |||
if ( fseek( dev_table[ dev_number ].cfp, offset, SEEK_SET ) != 0 ) | |||
{ | |||
#if PROG_ERRORS | |||
sprintf( bwb_ebuf, "in bwb_get(): fseek() failed, rec number <%d> offset <%ld>", | |||
@@ -1732,6 +1818,7 @@ bwb_put( l ) | |||
/* write the requested bytes to the file */ | |||
dev_table[ dev_number ].loc = offset; /* Slight bug fix (JBV) */ | |||
for ( i = 0; i < dev_table[ dev_number ].reclen; ++i ) | |||
{ | |||
fputc( dev_table[ dev_number ].buffer[ i ], | |||
@@ -1804,4 +1891,3 @@ dio_flush( dev_number ) | |||
#endif /* COMMON_CMDS */ | |||
@@ -23,6 +23,14 @@ | |||
****************************************************************/ | |||
/*---------------------------------------------------------------*/ | |||
/* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */ | |||
/* 11/1995 (eidetics@cerf.net). */ | |||
/* */ | |||
/* Those additionally marked with "DD" were at the suggestion of */ | |||
/* Dale DePriest (daled@cadence.com). */ | |||
/*---------------------------------------------------------------*/ | |||
#include <stdio.h> | |||
#include <ctype.h> | |||
#include <math.h> | |||
@@ -193,7 +201,8 @@ exp_strconst( expression ) | |||
/* read the string up until the next double quotation mark */ | |||
while( expression[ e_pos ] != '\"' ) | |||
/* While yer at it, check for a null terminator too (JBV, found by DD) */ | |||
while(( expression[ e_pos ] != '\"') && ( expression[ e_pos ] != '\0' )) | |||
{ | |||
CURTASK exps[ CURTASK expsc ].string[ s_pos ] = expression[ e_pos ]; | |||
++e_pos; | |||
@@ -219,7 +228,11 @@ exp_strconst( expression ) | |||
/* advance past last double quotation mark */ | |||
++CURTASK exps[ CURTASK expsc ].pos_adv; | |||
/*-------------------------------------------------------------*/ | |||
/* Of course, it doesn't hurt to make sure it's really a quote */ | |||
/* (JBV, found by DD) */ | |||
/*-------------------------------------------------------------*/ | |||
if ( expression[ e_pos ] == '\"' ) ++CURTASK exps[ CURTASK expsc ].pos_adv; | |||
/* return */ | |||
@@ -654,6 +667,8 @@ exp_numconst( expression ) | |||
case 'd': | |||
case 'E': | |||
case 'e': | |||
case 'F': /* Don't forget these! (JBV) */ | |||
case 'f': | |||
CURTASK exps[ CURTASK expsc ].string[ s_pos ] = expression[ CURTASK exps[ CURTASK expsc ].pos_adv ]; | |||
++CURTASK exps[ CURTASK expsc ].pos_adv; /* advance to next character */ | |||
@@ -718,7 +733,8 @@ exp_function( expression ) | |||
int paren_level; | |||
int n_args; | |||
struct bwb_variable *v; | |||
struct bwb_variable argv[ MAX_FARGS ]; | |||
/* struct bwb_variable argv[ MAX_FARGS ]; */ /* Removed by JBV */ | |||
struct bwb_variable *argv; /* Added by JBV */ | |||
bstring *b; | |||
#if INTENSIVE_DEBUG | |||
char tbuf[ MAXSTRINGSIZE + 1 ]; | |||
@@ -728,6 +744,18 @@ exp_function( expression ) | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
/*-----------------------------------------------------------*/ | |||
/* Added by JBV */ | |||
/* Required because adding a simple "static" modifier in the */ | |||
/* argv declaration doesn't work for recursive calls! */ | |||
/*-----------------------------------------------------------*/ | |||
if ( ( argv = (struct bwb_variable *) CALLOC( MAX_FARGS, | |||
sizeof( struct bwb_variable ), "exp_function" )) == NULL ) | |||
{ | |||
bwb_error( err_getmem ); | |||
return NULL; | |||
} | |||
/* assign pointers to argument stack */ | |||
/* get the function name */ | |||
@@ -1014,6 +1042,13 @@ exp_function( expression ) | |||
v = CURTASK exps[ CURTASK expsc ].function->vector ( n_args, &( argv[ 0 ] ), | |||
CURTASK exps[ CURTASK expsc ].function->id ); | |||
/*-------------------------------------------------*/ | |||
/* Now free the argv memory */ | |||
/* (some other less fortunate routine may need it) */ | |||
/* JBV, 10/95 */ | |||
/*-------------------------------------------------*/ | |||
FREE( argv, "exp_function" ); | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in exp_function(): return from function vector, type <%c>", | |||
v->type ); | |||
@@ -1117,7 +1152,7 @@ exp_variable( expression ) | |||
{ | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in exp_variable(): variable <%s> has 1 dimension", | |||
CURTASK exps[ CURTASK expsc ].xvar->name ); | |||
CURTASK exps[ CURTASK expsc ].xvar->name ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
pos = strlen( v->name ); | |||
@@ -1128,10 +1163,8 @@ exp_variable( expression ) | |||
else | |||
{ | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in exp_variable(): level <%d> variable <%s> has <%d> dimensions", | |||
CURTASK expsc, | |||
v->name, | |||
v->dimensions ); | |||
sprintf( bwb_ebuf, "in exp_variable(): variable <%s> has > 1 dimensions", | |||
CURTASK exps[ CURTASK expsc ].xvar->name ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
dim_getparams( expression, &pos, &n_params, &pp ); | |||
@@ -1144,25 +1177,18 @@ exp_variable( expression ) | |||
} | |||
#if INTENSIVE_DEBUG | |||
if ( v->dimensions > 1 ) | |||
for ( n = 0; n < v->dimensions; ++ n ) | |||
{ | |||
sprintf( bwb_ebuf, "in exp_variable(): exec stack level <%d>", | |||
CURTASK exsc ); | |||
sprintf( bwb_ebuf, "in exp_variable(): var <%s> array_pos element <%d> is <%d>.", | |||
v->name, n, v->array_pos[ n ] ); | |||
bwb_debug( bwb_ebuf ); | |||
for ( n = 0; n < v->dimensions; ++n ) | |||
{ | |||
sprintf( bwb_ebuf, " variable <%s> array_pos element <%d> is <%d>.", | |||
v->name, n, v->array_pos[ n ] ); | |||
bwb_debug( bwb_ebuf ); | |||
} | |||
} | |||
#endif | |||
/* assign the type and value at this level */ | |||
CURTASK exps[ CURTASK expsc ].type = (char) v->type; | |||
CURTASK exps[ CURTASK expsc ].xvar = v; | |||
switch( v->type ) | |||
{ | |||
case STRING: | |||
@@ -1180,7 +1206,7 @@ exp_variable( expression ) | |||
break; | |||
default: | |||
CURTASK exps[ CURTASK expsc ].nval = var_getnval( v ); | |||
break; | |||
break; | |||
} | |||
#if INTENSIVE_DEBUG | |||
@@ -23,6 +23,11 @@ | |||
****************************************************************/ | |||
/*---------------------------------------------------------------*/ | |||
/* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */ | |||
/* 11/1995 (eidetics@cerf.net). */ | |||
/*---------------------------------------------------------------*/ | |||
#include <stdio.h> | |||
#include <ctype.h> | |||
#include <math.h> | |||
@@ -71,7 +76,7 @@ bwb_exp( expression, assignment, position ) | |||
entry_level = CURTASK expsc; | |||
err_condition = FALSE; | |||
/* advance past whitespace or beginningg of line segment */ | |||
/* advance past whitespace or beginning of line segment */ | |||
#if MULTISEG_LINES | |||
if ( expression[ *position ] == ':' ) | |||
@@ -192,6 +197,7 @@ bwb_exp( expression, assignment, position ) | |||
case OP_XOR: | |||
case OP_IMPLIES: | |||
case OP_EQUIV: | |||
case OP_NEGATION: /* JBV */ | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_exp(): operator detected." ); | |||
@@ -595,7 +601,7 @@ exp_findop( expression ) | |||
{ | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_findop() loop position <%d> char 0x%x", | |||
sprintf( bwb_ebuf, "in exp_findop() loop position <%d> char 0x%x", | |||
c, expression[ position ] ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
@@ -692,8 +698,8 @@ exp_findop( expression ) | |||
FUNCTION: exp_isnc() | |||
DESCRIPTION: This function reads the expression to find | |||
if a logical or mathematical operation is | |||
required at this point. | |||
if a numerical constant is present at this | |||
point. | |||
***************************************************************/ | |||
@@ -706,6 +712,7 @@ exp_isnc( expression ) | |||
char *expression; | |||
#endif | |||
{ | |||
char tbuf[ MAXVARNAMESIZE + 1 ]; /* JBV */ | |||
switch( expression[ 0 ] ) | |||
{ | |||
@@ -752,6 +759,20 @@ exp_isnc( expression ) | |||
return OP_NULL; | |||
} | |||
/*--------------------------------------------------------*/ | |||
/* Check for unary minus sign added by JBV. */ | |||
/* Could be prefixing a parenthetical expression or a */ | |||
/* variable name. */ | |||
/* But parentheses won't show up in expression (cbuf), so */ | |||
/* just check for expression and variable name lengths. */ | |||
/*--------------------------------------------------------*/ | |||
if (expression[0] == '-') | |||
{ | |||
if (strlen(expression) == 1) return OP_NEGATION; | |||
exp_getvfname(&expression[1], tbuf); | |||
if (strlen(tbuf) != 0) return OP_NEGATION; | |||
} | |||
/* failing these tests, the argument must be a numerical | |||
constant preceded by a plus or minus sign */ | |||
@@ -1112,7 +1133,7 @@ exp_getvfname( source, destination ) | |||
while( source[ s_pos ] != '\0' ) | |||
{ | |||
/* all aphabetical characters are acceptable */ | |||
/* all alphabetical characters are acceptable */ | |||
if ( isalpha( source[ s_pos ] ) != 0 ) | |||
@@ -24,6 +24,11 @@ | |||
****************************************************************/ | |||
/*---------------------------------------------------------------*/ | |||
/* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */ | |||
/* 11/1995 (eidetics@cerf.net). */ | |||
/*---------------------------------------------------------------*/ | |||
#define FSTACKSIZE 32 | |||
#include <stdio.h> | |||
@@ -130,7 +135,9 @@ fnc_find( buffer ) | |||
if ( init == FALSE ) | |||
{ | |||
init = TRUE; | |||
if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( tbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "fnc_find" )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in fnc_find(): failed to find memory for tbuf" ); | |||
@@ -314,7 +321,9 @@ fnc_date( argc, argv, unique_id ) | |||
{ | |||
init = TRUE; | |||
var_make( &nvar, STRING ); | |||
if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( tbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "fnc_date" )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in fnc_date(): failed to get memory for tbuf" ); | |||
@@ -368,7 +377,9 @@ fnc_time( argc, argv, unique_id ) | |||
{ | |||
init = TRUE; | |||
var_make( &nvar, STRING ); | |||
if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( tbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "fnc_time" )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in fnc_time(): failed to get memory for tbuf" ); | |||
@@ -516,7 +527,9 @@ fnc_len( argc, argv, unique_id ) | |||
{ | |||
init = TRUE; | |||
var_make( &nvar, NUMBER ); | |||
if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( tbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "fnc_len" )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in fnc_len(): failed to get memory for tbuf" ); | |||
@@ -637,8 +650,9 @@ fnc_timer( argc, argv, unique_id ) | |||
} | |||
time( &now ); | |||
/* Following statement was (bnumber) (JBV) */ | |||
* var_findnval( &nvar, nvar.array_pos ) | |||
= (float) fmod( (bnumber) now, (bnumber) (60*60*24)); | |||
= (float) fmod( (double) now, (double) (60*60*24)); | |||
return &nvar; | |||
} | |||
@@ -952,7 +966,9 @@ fnc_asc( argc, argv, unique_id ) | |||
{ | |||
init = TRUE; | |||
var_make( &nvar, NUMBER ); | |||
if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( tbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "fnc_asc" )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in fnc_asc(): failed to get memory for tbuf" ); | |||
@@ -1046,7 +1062,9 @@ fnc_string( argc, argv, unique_id ) | |||
{ | |||
init = TRUE; | |||
var_make( &nvar, STRING ); | |||
if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( tbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "fnc_string" )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in fnc_string(): failed to get memory for tbuf" ); | |||
@@ -1097,7 +1115,7 @@ fnc_string( argc, argv, unique_id ) | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in fnc_string(): argument <%s> arg type <%c>, length <%d>", | |||
argv[ 1 ].string, argv[ 1 ].type, length ); | |||
tbuf, argv[ 1 ].type, length ); | |||
bwb_debug( bwb_ebuf ); | |||
sprintf( bwb_ebuf, "in fnc_string(): type <%c>, c <0x%x>=<%c>", | |||
argv[ 1 ].type, c, c ); | |||
@@ -1320,7 +1338,9 @@ fnc_space( argc, argv, unique_id ) | |||
{ | |||
init = TRUE; | |||
var_make( &nvar, (int) STRING ); | |||
if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( tbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "fnc_space" )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in fnc_space(): failed to get memory for tbuf" ); | |||
@@ -1513,7 +1533,7 @@ fnc_erl( argc, argv, unique_id ) | |||
DESCRIPTION: This C function implements the BASIC | |||
LOC() function. As implemented here, | |||
this only workd for random-acess files. | |||
this only works for random-acess files. | |||
SYNTAX: LOC( device-number ) | |||
@@ -1611,6 +1631,7 @@ fnc_eof( argc, argv, unique_id ) | |||
static struct bwb_variable nvar; | |||
static int init = FALSE; | |||
int dev_number; | |||
int cur_pos, end_pos; /* JBV */ | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in fnc_loc(): received f_arg <%f> ", | |||
@@ -1661,7 +1682,19 @@ fnc_eof( argc, argv, unique_id ) | |||
bwb_error( err_devnum ); | |||
* var_findnval( &nvar, nvar.array_pos ) = (bnumber) TRUE; | |||
} | |||
else if ( feof( dev_table[ dev_number ].cfp ) == 0 ) | |||
/*------------------------------------------------------*/ | |||
/* feof() finds EOF when you read past the end of file. */ | |||
/* This is not how BASIC works, at least not GWBASIC. */ | |||
/* The EOF function should return an EOF indication */ | |||
/* when you are <at> the end of the file, not past it. */ | |||
/* This routine was modified to reflect this. */ | |||
/* (JBV, 10/15/95) */ | |||
/*------------------------------------------------------*/ | |||
/* else if ( feof( dev_table[ dev_number ].cfp ) == 0 ) */ | |||
else if ( ftell( dev_table[ dev_number ].cfp ) != | |||
dev_table [ dev_number ].lof ) | |||
{ | |||
* var_findnval( &nvar, nvar.array_pos ) = (bnumber) FALSE; | |||
} | |||
@@ -1698,10 +1731,12 @@ fnc_lof( argc, argv, unique_id ) | |||
static struct bwb_variable nvar; | |||
static int init = FALSE; | |||
int dev_number; | |||
#if UNIX_CMDS | |||
/* Following section no longer needed, removed by JBV */ | |||
/* #if UNIX_CMDS | |||
static struct stat statbuf; | |||
int r; | |||
#endif | |||
#endif */ | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in fnc_lof(): received f_arg <%f> ", | |||
@@ -1742,7 +1777,8 @@ fnc_lof( argc, argv, unique_id ) | |||
/* stat the file */ | |||
#if UNIX_CMDS | |||
/* Following section no longer needed, removed by JBV */ | |||
/* #if UNIX_CMDS | |||
r = stat( dev_table[ dev_number ].filename, &statbuf ); | |||
@@ -1760,13 +1796,15 @@ fnc_lof( argc, argv, unique_id ) | |||
return NULL; | |||
} | |||
* var_findnval( &nvar, nvar.array_pos ) = (bnumber) statbuf.st_size; | |||
* var_findnval( &nvar, nvar.array_pos ) = (bnumber) statbuf.st_size; */ | |||
#else | |||
/* #else */ /* Removed by JBV, no longer needed */ | |||
* var_findnval( &nvar, nvar.array_pos ) = (bnumber) FALSE; | |||
/* * var_findnval( &nvar, nvar.array_pos ) = (bnumber) FALSE; */ | |||
* var_findnval( &nvar, nvar.array_pos ) = | |||
(bnumber) dev_table[ dev_number ].lof; /* JBV */ | |||
#endif | |||
/* #endif */ /* Removed by JBV, no longer needed */ | |||
return &nvar; | |||
} | |||
@@ -1806,7 +1844,9 @@ fnc_test( argc, argv, unique_id ) | |||
{ | |||
init = TRUE; | |||
var_make( &rvar, NUMBER ); | |||
if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( tbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "fnc_test" )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in fnc_test(): failed to get memory for tbuf" ); | |||
@@ -29,6 +29,11 @@ | |||
***************************************************************/ | |||
/*---------------------------------------------------------------*/ | |||
/* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */ | |||
/* 11/1995 (eidetics@cerf.net). */ | |||
/*---------------------------------------------------------------*/ | |||
#include <stdio.h> | |||
#include <ctype.h> | |||
#include <math.h> | |||
@@ -47,6 +52,7 @@ static int inp_assign( char *b, struct bwb_variable *v ); | |||
static int inp_advws( FILE *f ); | |||
static int inp_xgetc( FILE *f, int is_string ); | |||
static int inp_eatcomma( FILE *f ); | |||
static bnumber inp_numconst( char *expression ); /* JBV */ | |||
#else | |||
static struct bwb_line *bwb_xinp(); | |||
static struct bwb_line *inp_str(); | |||
@@ -55,10 +61,12 @@ static int inp_assign(); | |||
static int inp_advws(); | |||
static int inp_xgetc(); | |||
static int inp_eatcomma(); | |||
static bnumber inp_numconst(); /* JBV */ | |||
#endif | |||
static char_saved = FALSE; | |||
static cs; | |||
static int last_inp_adv_rval = FALSE; /* JBV */ | |||
/*************************************************************** | |||
@@ -621,7 +629,15 @@ bwb_input( l ) | |||
/* advance past semicolon to beginning of variable */ | |||
suppress_qm = inp_adv( l->buffer, &( l->position ) ); | |||
/*--------------------------------------------------------*/ | |||
/* Since inp_const was just called and inp_adv is called */ | |||
/* within that, it will have already noted and passed the */ | |||
/* comma by the time it gets here. Therefore one must */ | |||
/* refer instead to the last returned value for inp_adv! */ | |||
/* (JBV, 10/95) */ | |||
/*--------------------------------------------------------*/ | |||
/* suppress_qm = inp_adv( l->buffer, &( l->position ) ); */ | |||
suppress_qm = last_inp_adv_rval; | |||
/* print the prompt string */ | |||
@@ -772,7 +788,12 @@ bwb_xinp( l, f ) | |||
tbuf ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
* var_findnval( v, v->array_pos ) = (bnumber) atof( tbuf ); | |||
/*------------------------------------------------------------*/ | |||
/* atof call replaced by inp_numconst, gets all input formats */ | |||
/* (JBV, 10/95) */ | |||
/*------------------------------------------------------------*/ | |||
/* * var_findnval( v, v->array_pos ) = (bnumber) atof( tbuf ); */ | |||
* var_findnval( v, v->array_pos ) = inp_numconst( tbuf ); | |||
break; | |||
} /* end of switch for type-specific input */ | |||
@@ -801,7 +822,7 @@ bwb_xinp( l, f ) | |||
FUNCTION: inp_advws() | |||
DESCRIPTION: This C function advances past whitespace | |||
inoput from a particular file or device. | |||
input from a particular file or device. | |||
***************************************************************/ | |||
@@ -1118,7 +1139,12 @@ inp_assign( b, v ) | |||
} | |||
else | |||
{ | |||
*( var_findnval( v, v->array_pos )) = (bnumber) atof( b ); | |||
/*------------------------------------------------------------*/ | |||
/* atof call replaced by inp_numconst, gets all input formats */ | |||
/* (JBV, 10/95) */ | |||
/*------------------------------------------------------------*/ | |||
/* *( var_findnval( v, v->array_pos )) = (bnumber) atof( b ); */ | |||
*( var_findnval( v, v->array_pos )) = inp_numconst( b ); | |||
} | |||
break; | |||
@@ -1178,8 +1204,10 @@ inp_adv( b, c ) | |||
case '\0': /* end of line */ | |||
case ':': /* end of line segment */ | |||
rval = TRUE; | |||
last_inp_adv_rval = rval; /* JBV */ | |||
return rval; | |||
default: | |||
last_inp_adv_rval = rval; /* JBV */ | |||
return rval; | |||
} | |||
} | |||
@@ -1318,6 +1346,8 @@ bwb_line( l ) | |||
FILE *inp_device; | |||
char tbuf[ MAXSTRINGSIZE + 1 ]; | |||
char pstring[ MAXSTRINGSIZE + 1 ]; | |||
struct exp_ese *e; /* JBV */ | |||
int pos; /* JBV */ | |||
/* assign default values */ | |||
@@ -1351,7 +1381,10 @@ bwb_line( l ) | |||
++l->position; | |||
adv_element( l->buffer, &( l->position ), tbuf ); | |||
adv_ws( l->buffer, &( l->position )); | |||
dev_no = atoi( tbuf ); | |||
/* dev_no = atoi( tbuf ); */ /* We really need more, added next (JBV) */ | |||
pos = 0; | |||
e = bwb_exp( tbuf, FALSE, &pos ); | |||
dev_no = (int) exp_getnval( e ); | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_line(): file number requested <%d>", dev_no ); | |||
@@ -1437,4 +1470,446 @@ bwb_line( l ) | |||
#endif /* COMMON_CMDS */ | |||
/*************************************************************** | |||
FUNCTION: inp_numconst() | |||
DESCRIPTION: This function interprets a numerical | |||
constant. Added by JBV 10/95 | |||
***************************************************************/ | |||
#if ANSI_C | |||
bnumber | |||
inp_numconst( char *expression ) | |||
#else | |||
bnumber | |||
inp_numconst( expression ) | |||
char *expression; | |||
#endif | |||
{ | |||
int base; /* numerical base for the constant */ | |||
static struct bwb_variable mantissa; /* mantissa of floating-point number */ | |||
static int init = FALSE; /* is mantissa variable initialized? */ | |||
int exponent; /* exponent for floating point number */ | |||
int man_start; /* starting point of mantissa */ | |||
int s_pos; /* position in build string */ | |||
int build_loop; | |||
int need_pm; | |||
int i; | |||
bnumber d; | |||
/* Expression stack stuff */ | |||
char type; | |||
bnumber nval; | |||
char string[ MAXSTRINGSIZE + 1 ]; | |||
int pos_adv; | |||
/* initialize the variable if necessary */ | |||
#if INTENSIVE_DEBUG | |||
strcpy( mantissa.name, "(mantissa)" ); | |||
#endif | |||
if ( init == FALSE ) | |||
{ | |||
init = TRUE; | |||
var_make( &mantissa, NUMBER ); | |||
} | |||
/* be sure that the array_pos[ 0 ] for mantissa is set to dim_base; | |||
this is necessary because mantissa might be used before dim_base | |||
is set */ | |||
mantissa.array_pos[ 0 ] = dim_base; | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in inp_numconst(): received <%s>, eval <%c>", | |||
expression, expression[ 0 ] ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
need_pm = FALSE; | |||
nval = (bnumber) 0; | |||
/* check the first character(s) to determine numerical base | |||
and starting point of the mantissa */ | |||
switch( expression[ 0 ] ) | |||
{ | |||
case '-': | |||
case '+': | |||
case '0': | |||
case '1': | |||
case '2': | |||
case '3': | |||
case '4': | |||
case '5': | |||
case '6': | |||
case '7': | |||
case '8': | |||
case '9': | |||
case '.': | |||
base = 10; /* decimal constant */ | |||
man_start = 0; /* starts at position 0 */ | |||
need_pm = FALSE; | |||
break; | |||
case '&': /* hex or octal constant */ | |||
if ( ( expression[ 1 ] == 'H' ) || ( expression[ 1 ] == 'h' )) | |||
{ | |||
base = 16; /* hexadecimal constant */ | |||
man_start = 2; /* starts at position 2 */ | |||
} | |||
else | |||
{ | |||
base = 8; /* octal constant */ | |||
if ( ( expression[ 1 ] == 'O' ) || ( expression[ 1 ] == 'o' )) | |||
{ | |||
man_start = 2; /* starts at position 2 */ | |||
} | |||
else | |||
{ | |||
man_start = 1; /* starts at position 1 */ | |||
} | |||
} | |||
break; | |||
default: | |||
#if PROG_ERRORS | |||
sprintf( bwb_ebuf, "expression <%s> is not a numerical constant.", | |||
expression ); | |||
bwb_error( bwb_ebuf ); | |||
#else | |||
bwb_error( err_syntax ); | |||
#endif | |||
return (bnumber) 0; | |||
} | |||
/* now build the mantissa according to the numerical base */ | |||
switch( base ) | |||
{ | |||
case 10: /* decimal constant */ | |||
/* initialize counters */ | |||
pos_adv = man_start; | |||
type = NUMBER; | |||
string[ 0 ] = '\0'; | |||
s_pos = 0; | |||
exponent = 0; | |||
build_loop = TRUE; | |||
/* loop to build the string */ | |||
while ( build_loop == TRUE ) | |||
{ | |||
switch( expression[ pos_adv ] ) | |||
{ | |||
case '-': /* prefixed plus or minus */ | |||
case '+': | |||
/* in the first position, a plus or minus sign can | |||
be added to the beginning of the string to be | |||
scanned */ | |||
if ( pos_adv == man_start ) | |||
{ | |||
string[ s_pos ] = expression[ pos_adv ]; | |||
++pos_adv; /* advance to next character */ | |||
++s_pos; | |||
string[ s_pos ] = '\0'; | |||
} | |||
/* but in any other position, the plus or minus sign | |||
must be taken as an operator and thus as terminating | |||
the string to be scanned */ | |||
else | |||
{ | |||
build_loop = FALSE; | |||
} | |||
break; | |||
case '.': /* note at least single precision */ | |||
case '0': /* or ordinary digit */ | |||
case '1': | |||
case '2': | |||
case '3': | |||
case '4': | |||
case '5': | |||
case '6': | |||
case '7': | |||
case '8': | |||
case '9': | |||
string[ s_pos ] = expression[ pos_adv ]; | |||
++pos_adv; /* advance to next character */ | |||
++s_pos; | |||
string[ s_pos ] = '\0'; | |||
break; | |||
case '#': /* Microsoft-type precision indicator; ignored but terminates */ | |||
case '!': /* Microsoft-type precision indicator; ignored but terminates */ | |||
++pos_adv; /* advance to next character */ | |||
type = NUMBER; | |||
exponent = FALSE; | |||
build_loop = FALSE; | |||
break; | |||
case 'E': /* exponential, single precision */ | |||
case 'e': | |||
++pos_adv; /* advance to next character */ | |||
type = NUMBER; | |||
exponent = TRUE; | |||
build_loop = FALSE; | |||
break; | |||
case 'D': /* exponential, double precision */ | |||
case 'd': | |||
++pos_adv; /* advance to next character */ | |||
type = NUMBER; | |||
exponent = TRUE; | |||
build_loop = FALSE; | |||
break; | |||
default: /* anything else, terminate */ | |||
build_loop = FALSE; | |||
break; | |||
} | |||
} | |||
/* assign the value to the mantissa variable */ | |||
#if NUMBER_DOUBLE | |||
sscanf( string, "%lf", var_findnval( &mantissa, mantissa.array_pos )); | |||
#else | |||
sscanf( string, "%f", var_findnval( &mantissa, mantissa.array_pos )); | |||
#endif | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in inp_numconst(): read mantissa, string <%s> val <%lf>", | |||
string, var_getnval( &mantissa ) ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
/* test if integer bounds have been exceeded */ | |||
if ( type == NUMBER ) | |||
{ | |||
i = (int) var_getnval( &mantissa ); | |||
d = (bnumber) i; | |||
if ( d != var_getnval( &mantissa )) | |||
{ | |||
type = NUMBER; | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in inp_numconst(): integer bounds violated, promote to NUMBER" ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
} | |||
} | |||
/* read the exponent if there is one */ | |||
if ( exponent == TRUE ) | |||
{ | |||
/* allow a plus or minus once at the beginning */ | |||
need_pm = TRUE; | |||
/* initialize counters */ | |||
string[ 0 ] = '\0'; | |||
s_pos = 0; | |||
build_loop = TRUE; | |||
/* loop to build the string */ | |||
while ( build_loop == TRUE ) | |||
{ | |||
switch( expression[ pos_adv ] ) | |||
{ | |||
case '-': /* prefixed plus or minus */ | |||
case '+': | |||
if ( need_pm == TRUE ) /* only allow once */ | |||
{ | |||
string[ s_pos ] = expression[ pos_adv ]; | |||
++pos_adv; /* advance to next character */ | |||
++s_pos; | |||
string[ s_pos ] = '\0'; | |||
} | |||
else | |||
{ | |||
build_loop = FALSE; | |||
} | |||
break; | |||
case '0': /* or ordinary digit */ | |||
case '1': | |||
case '2': | |||
case '3': | |||
case '4': | |||
case '5': | |||
case '6': | |||
case '7': | |||
case '8': | |||
case '9': | |||
string[ s_pos ] = expression[ pos_adv ]; | |||
++pos_adv; /* advance to next character */ | |||
++s_pos; | |||
string[ s_pos ] = '\0'; | |||
need_pm = FALSE; | |||
break; | |||
default: /* anything else, terminate */ | |||
build_loop = FALSE; | |||
break; | |||
} | |||
} /* end of build loop for exponent */ | |||
/* assign the value to the user variable */ | |||
#if NUMBER_DOUBLE | |||
sscanf( string, "%lf", &nval ); | |||
#else | |||
sscanf( string, "%f", &nval ); | |||
#endif | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in inp_numconst(): exponent is <%d>", | |||
(int) nval ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
} /* end of exponent search */ | |||
if ( nval == (bnumber) 0 ) | |||
{ | |||
nval = var_getnval( &mantissa ); | |||
} | |||
else | |||
{ | |||
nval = var_getnval( &mantissa ) | |||
* pow( (bnumber) 10.0, (bnumber) nval ); | |||
} | |||
break; | |||
case 8: /* octal constant */ | |||
/* initialize counters */ | |||
pos_adv = man_start; | |||
type = NUMBER; | |||
string[ 0 ] = '\0'; | |||
s_pos = 0; | |||
exponent = 0; | |||
build_loop = TRUE; | |||
/* loop to build the string */ | |||
while ( build_loop == TRUE ) | |||
{ | |||
switch( expression[ pos_adv ] ) | |||
{ | |||
case '0': /* or ordinary digit */ | |||
case '1': | |||
case '2': | |||
case '3': | |||
case '4': | |||
case '5': | |||
case '6': | |||
case '7': | |||
string[ s_pos ] = expression[ pos_adv ]; | |||
++pos_adv; /* advance to next character */ | |||
++s_pos; | |||
string[ s_pos ] = '\0'; | |||
break; | |||
default: /* anything else, terminate */ | |||
build_loop = FALSE; | |||
break; | |||
} | |||
} | |||
/* now scan the string to determine the number */ | |||
sscanf( string, "%o", &i ); | |||
nval = (bnumber) i; | |||
break; | |||
case 16: /* hexadecimal constant */ | |||
/* initialize counters */ | |||
pos_adv = man_start; | |||
type = NUMBER; | |||
string[ 0 ] = '\0'; | |||
s_pos = 0; | |||
exponent = 0; | |||
build_loop = TRUE; | |||
/* loop to build the string */ | |||
while ( build_loop == TRUE ) | |||
{ | |||
switch( expression[ pos_adv ] ) | |||
{ | |||
case '0': /* or ordinary digit */ | |||
case '1': | |||
case '2': | |||
case '3': | |||
case '4': | |||
case '5': | |||
case '6': | |||
case '7': | |||
case '8': | |||
case '9': | |||
case 'A': | |||
case 'a': | |||
case 'B': | |||
case 'b': | |||
case 'C': | |||
case 'c': | |||
case 'D': | |||
case 'd': | |||
case 'E': | |||
case 'e': | |||
case 'F': /* Don't forget these! (JBV) */ | |||
case 'f': | |||
string[ s_pos ] = expression[ pos_adv ]; | |||
++pos_adv; /* advance to next character */ | |||
++s_pos; | |||
string[ s_pos ] = '\0'; | |||
break; | |||
default: /* anything else, terminate */ | |||
build_loop = FALSE; | |||
break; | |||
} | |||
} | |||
/* now scan the string to determine the number */ | |||
sscanf( string, "%x", &i ); | |||
nval = (bnumber) i; | |||
break; | |||
} | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in inp_numconst(): precision <%c> value <%lf>", | |||
type, nval ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
return nval; | |||
} |
@@ -23,6 +23,14 @@ | |||
***************************************************************/ | |||
/*---------------------------------------------------------------*/ | |||
/* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */ | |||
/* 11/1995 (eidetics@cerf.net). */ | |||
/* */ | |||
/* Those additionally marked with "DD" were at the suggestion of */ | |||
/* Dale DePriest (daled@cadence.com). */ | |||
/*---------------------------------------------------------------*/ | |||
#include <stdio.h> | |||
#include <ctype.h> | |||
@@ -85,7 +93,7 @@ adv_element( buffer, pos, element ) | |||
case '=': | |||
case ' ': | |||
case '\t': | |||
case '\0': | |||
/* case '\0': */ /* Removed by JBV (found by DD) */ | |||
case '\n': | |||
case '\r': | |||
if ( str_const == TRUE ) | |||
@@ -101,6 +109,15 @@ adv_element( buffer, pos, element ) | |||
} | |||
break; | |||
case '\0': /* Added by JBV (found by DD) */ | |||
if ( str_const == TRUE ) /* termination of string constant */ | |||
{ | |||
element[ e_pos ] = '\"'; | |||
element[ ++e_pos ] = '\0'; | |||
} | |||
return TRUE; | |||
break; | |||
case '\"': /* string constant */ | |||
element[ e_pos ] = buffer[ *pos ]; | |||
++e_pos; | |||
@@ -328,7 +345,9 @@ line_start( buffer, pos, lnpos, lnum, cmdpos, cmdnum, startpos ) | |||
if ( init == FALSE ) | |||
{ | |||
init = TRUE; | |||
if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( tbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "line_start")) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in line_start(): failed to get memory for tbuf" ); | |||
@@ -736,7 +755,9 @@ bwb_numseq( buffer, start, end ) | |||
if ( init == FALSE ) | |||
{ | |||
init = TRUE; | |||
if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( tbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "bwb_numseq")) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in bwb_numseq(): failed to find memory for tbuf" ); | |||
@@ -867,7 +888,14 @@ bwb_freeline( l ) | |||
/* free arguments if there are any */ | |||
free( l ); | |||
/* Revised to FREE pass-thru calls by JBV */ | |||
if (l->buffer != NULL) | |||
{ | |||
FREE( l->buffer, "bwb_freeline" ); | |||
l->buffer = NULL; /* JBV */ | |||
} | |||
FREE( l, "bwb_freeline" ); | |||
l = NULL; /* JBV */ | |||
return TRUE; | |||
} | |||
@@ -952,4 +980,3 @@ is_eol( buffer, position ) | |||
} | |||
@@ -23,6 +23,10 @@ | |||
***************************************************************/ | |||
/*---------------------------------------------------------------*/ | |||
/* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */ | |||
/* 11/1995 (eidetics@cerf.net). */ | |||
/*---------------------------------------------------------------*/ | |||
#ifndef TRUE | |||
#define TRUE 1 | |||
@@ -391,6 +395,7 @@ | |||
#define CMD_DEFINT "DEFINT" | |||
#define CMD_DEFSNG "DEFSNG" | |||
#define CMD_DEFSTR "DEFSTR" | |||
#define CMD_MID "MID$" | |||
#define CMD_CALL "CALL" | |||
#define CMD_SUB "SUB" | |||
#define CMD_FUNCTION "FUNCTION" | |||
@@ -409,6 +414,7 @@ | |||
#define CMD_RANDOMIZE "RANDOMIZE" | |||
#define CMD_FILES "FILES" | |||
#define CMD_EDIT "EDIT" | |||
#define CMD_RENUM "RENUM" | |||
#define CMD_ERASE "ERASE" | |||
#define CMD_SWAP "SWAP" | |||
#define CMD_NAME "NAME" | |||
@@ -471,4 +477,3 @@ extern char err_noprogfile[]; | |||
@@ -23,6 +23,11 @@ | |||
****************************************************************/ | |||
/*---------------------------------------------------------------*/ | |||
/* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */ | |||
/* 11/1995 (eidetics@cerf.net). */ | |||
/*---------------------------------------------------------------*/ | |||
#include <stdio.h> | |||
#include <ctype.h> | |||
#include <math.h> | |||
@@ -154,8 +159,9 @@ fnc_core( argc, argv, unique_id ) | |||
switch( unique_id ) | |||
{ | |||
case F_ABS: | |||
/* Added double recast here (JBV) */ | |||
* var_findnval( &nvar, nvar.array_pos ) = | |||
(bnumber) fabs( var_getnval( &( argv[ 0 ] ) ) ); | |||
(bnumber) fabs( (double) var_getnval( &( argv[ 0 ] ) ) ); | |||
break; | |||
case F_ATN: | |||
* var_findnval( &nvar, nvar.array_pos ) | |||
@@ -166,8 +172,9 @@ fnc_core( argc, argv, unique_id ) | |||
= (bnumber) cos( (double) var_getnval( &( argv[ 0 ] ) ) ); | |||
break; | |||
case F_EXP: | |||
/* Added double recast here (JBV) */ | |||
* var_findnval( &nvar, nvar.array_pos ) | |||
= (bnumber) exp( var_getnval( &( argv[ 0 ] ) ) ); | |||
= (bnumber) exp( (double) var_getnval( &( argv[ 0 ] ) ) ); | |||
break; | |||
case F_INT: | |||
* var_findnval( &nvar, nvar.array_pos ) | |||
@@ -178,7 +185,9 @@ fnc_core( argc, argv, unique_id ) | |||
= (bnumber) log( (double) var_getnval( &( argv[ 0 ] ) ) ); | |||
break; | |||
case F_RND: | |||
* var_findnval( &nvar, nvar.array_pos ) = (float) rand() / RAND_MAX; | |||
/* Added bnumber recast here (JBV) */ | |||
* var_findnval( &nvar, nvar.array_pos ) | |||
= (bnumber) ( (float) rand() / RAND_MAX ); | |||
break; | |||
case F_SGN: | |||
nval = var_getnval( &( argv[ 0 ] )); | |||
@@ -296,8 +305,9 @@ fnc_abs( argc, argv, unique_id ) | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
/* Added double recast here (JBV) */ | |||
* var_findnval( &nvar, nvar.array_pos ) = | |||
(bnumber) fabs( var_getnval( &( argv[ 0 ] ) ) ); | |||
(bnumber) fabs( (double) var_getnval( &( argv[ 0 ] ) ) ); | |||
return &nvar; | |||
@@ -339,7 +349,9 @@ fnc_rnd( argc, argv, unique_id ) | |||
var_make( &nvar, NUMBER ); | |||
} | |||
* var_findnval( &nvar, nvar.array_pos ) = (float) rand() / RAND_MAX; | |||
/* Added bnumber recast here (JBV) */ | |||
* var_findnval( &nvar, nvar.array_pos ) | |||
= (bnumber) ( (float) rand() / RAND_MAX ); | |||
return &nvar; | |||
} | |||
@@ -987,8 +999,9 @@ fnc_exp( argc, argv, unique_id ) | |||
/* assign values */ | |||
/* Added double recast here (JBV) */ | |||
* var_findnval( &nvar, nvar.array_pos ) | |||
= (bnumber) exp( var_getnval( &( argv[ 0 ] ) ) ); | |||
= (bnumber) exp( (double) var_getnval( &( argv[ 0 ] ) ) ); | |||
return &nvar; | |||
} | |||
@@ -1030,7 +1043,9 @@ fnc_val( argc, argv, unique_id ) | |||
{ | |||
init = TRUE; | |||
var_make( &nvar, NUMBER ); | |||
if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( tbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "fnc_val" )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in fnc_val(): failed to get memory for tbuf" ); | |||
@@ -1078,6 +1093,9 @@ fnc_val( argc, argv, unique_id ) | |||
/* read the value */ | |||
str_btoc( tbuf, var_getsval( &( argv[ 0 ] ) )); | |||
if ( strlen( tbuf ) == 0 ) /* JBV */ | |||
*var_findnval( &nvar, nvar.array_pos ) = (bnumber) 0; | |||
else | |||
#if NUMBER_DOUBLE | |||
sscanf( tbuf, "%lf", | |||
var_findnval( &nvar, nvar.array_pos ) ); | |||
@@ -1122,7 +1140,9 @@ fnc_str( argc, argv, unique_id ) | |||
{ | |||
init = TRUE; | |||
var_make( &nvar, STRING ); | |||
if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( tbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "fnc_str" )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in fnc_str(): failed to get memory for tbuf" ); | |||
@@ -1203,7 +1223,9 @@ fnc_hex( argc, argv, unique_id ) | |||
{ | |||
init = TRUE; | |||
var_make( &nvar, STRING ); | |||
if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( tbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "fnc_hex" )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in fnc_hex(): failed to get memory for tbuf" ); | |||
@@ -1278,7 +1300,9 @@ fnc_oct( argc, argv, unique_id ) | |||
{ | |||
init = TRUE; | |||
var_make( &nvar, STRING ); | |||
if ( ( tbuf = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( tbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "fnc_oct" )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in fnc_oct(): failed to get memory for tbuf" ); | |||
@@ -1314,7 +1338,9 @@ fnc_oct( argc, argv, unique_id ) | |||
/* format as octal integer */ | |||
sprintf( tbuf, "%o", (int) var_getnval( &( argv[ 0 ] ) ) ); | |||
/* Revised by JBV */ | |||
/* sprintf( tbuf, "%o", (int) var_getnval( &( argv[ 0 ] ) ) ); */ | |||
sprintf( tbuf, "%o", (int) trnc_int( (bnumber) var_getnval( &( argv[ 0 ] )) ) ); | |||
str_ctob( var_findsval( &nvar, nvar.array_pos ), tbuf ); | |||
return &nvar; | |||
} | |||
@@ -1388,6 +1414,7 @@ fnc_mki( argc, argv, unique_id ) | |||
for ( i = 0; i < sizeof( int ); ++i ) | |||
{ | |||
tbuf[ i ] = an_integer.the_chars[ i ]; | |||
tbuf[ i + 1 ] = '\0'; | |||
} | |||
b = var_getsval( &nvar ); | |||
b->length = sizeof( int ); | |||
@@ -1545,6 +1572,7 @@ fnc_mks( argc, argv, unique_id ) | |||
for ( i = 0; i < sizeof( float ); ++i ) | |||
{ | |||
tbuf[ i ] = a_float.the_chars[ i ]; | |||
tbuf[ i + 1 ] = '\0'; | |||
} | |||
b = var_getsval( &nvar ); | |||
b->length = sizeof( float ); | |||
@@ -1807,7 +1835,7 @@ fnc_cvs( argc, argv, unique_id ) | |||
DESCRIPTION: This C function implements the BASIC | |||
function CSNG(). As implemented, | |||
this is a pseudo-function, since | |||
all bwBASIC numerial values have the | |||
all bwBASIC numerical values have the | |||
same precision. | |||
SYNTAX: CSNG( number ) | |||
@@ -1955,18 +1983,19 @@ trnc_int( x ) | |||
bnumber x; | |||
#endif | |||
{ | |||
bnumber sign; | |||
double sign; /* Was bnumber (JBV) */ | |||
if ( x < (bnumber) 0.0 ) | |||
{ | |||
sign = (bnumber) -1.0; | |||
sign = (double) -1.0; /* Was bnumber (JBV) */ | |||
} | |||
else | |||
{ | |||
sign = (bnumber) 1.0; | |||
sign = (double) 1.0; /* Was bnumber (JBV) */ | |||
} | |||
return (bnumber) ( floor( fabs( x )) * sign ); | |||
/* Added double recast here (JBV) */ | |||
return (bnumber) ( floor( fabs( (double) x )) * sign ); | |||
} | |||
/*************************************************************** | |||
@@ -1991,27 +2020,27 @@ round_int( x ) | |||
if ( x < (bnumber) 0.00 ) | |||
{ | |||
if ( (bnumber) fabs( (bnumber) floor( x ) - x ) < (bnumber) 0.500 ) | |||
/* Added double recasts here (JBV) */ | |||
if ( (bnumber) fabs( (bnumber) floor( (double) x ) - x ) < (bnumber) 0.500 ) | |||
{ | |||
return (bnumber) floor( x ); | |||
return (bnumber) floor( (double) x ); | |||
} | |||
else | |||
{ | |||
return (bnumber) ceil( x ); | |||
return (bnumber) ceil( (double) x ); | |||
} | |||
} | |||
else | |||
{ | |||
if ( ( x - (bnumber) floor( x )) < (bnumber) 0.500 ) | |||
if ( ( x - (bnumber) floor( (double) x )) < (bnumber) 0.500 ) | |||
{ | |||
return (bnumber) floor( x ); | |||
return (bnumber) floor( (double) x ); | |||
} | |||
else | |||
{ | |||
return (bnumber) ceil( x ); | |||
return (bnumber) ceil( (double) x ); | |||
} | |||
} | |||
} | |||
@@ -23,6 +23,11 @@ | |||
****************************************************************/ | |||
/*---------------------------------------------------------------*/ | |||
/* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */ | |||
/* 11/1995 (eidetics@cerf.net). */ | |||
/*---------------------------------------------------------------*/ | |||
#include <stdio.h> | |||
#include <ctype.h> | |||
#include <math.h> | |||
@@ -52,6 +57,7 @@ static int op_or( int level, int precision ); | |||
static int op_and( int level, int precision ); | |||
static int op_not( int level, int precision ); | |||
static int op_xor( int level, int precision ); | |||
static int op_negation( int level, int precision ); /* JBV */ | |||
static int op_islevelstr( int level ); | |||
static int op_getprecision( int level ); | |||
static int op_isoperator( int operation ); | |||
@@ -76,6 +82,7 @@ static int op_or(); | |||
static int op_and(); | |||
static int op_not(); | |||
static int op_xor(); | |||
static int op_negation(); /* JBV */ | |||
static int op_islevelstr(); | |||
static int op_getprecision(); | |||
static int op_isoperator(); | |||
@@ -312,6 +319,10 @@ op_oplevel( level ) | |||
op_exponent( level, precision ); | |||
break; | |||
case OP_NEGATION: /* JBV */ | |||
op_negation( level, precision ); | |||
break; | |||
default: | |||
#if PROG_ERRORS | |||
sprintf( bwb_ebuf, "PROGRAMMING ERROR: operator <%d> not (yet) supported.", CURTASK exps[ level ].operation ); | |||
@@ -395,8 +406,10 @@ op_add( level, precision ) | |||
#endif | |||
{ | |||
int error_condition; | |||
static bstring b; /* JBV */ | |||
error_condition = FALSE; | |||
b.rab = FALSE; /* JBV */ | |||
switch( precision ) | |||
{ | |||
@@ -435,8 +448,15 @@ op_add( level, precision ) | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
str_cat( exp_getsval( &( CURTASK exps[ level - 1 ] ) ), | |||
exp_getsval( &( CURTASK exps[ level + 1 ] ) ) ); | |||
/* Removed by JBV (incomplete, modifies wrong string variable!) */ | |||
/* str_cat( exp_getsval( &( CURTASK exps[ level - 1 ] ) ), | |||
exp_getsval( &( CURTASK exps[ level + 1 ] ) ) ); */ | |||
/* Added by JBV */ | |||
str_btob( &b, exp_getsval( &( CURTASK exps[ level - 1 ] ) ) ); | |||
str_cat( &b, exp_getsval( &( CURTASK exps[ level + 1 ] ) ) ); | |||
str_btob( &( CURTASK exps[ level - 1 ].sval ), &b ); | |||
CURTASK exps[ level - 1 ].operation = CONST_STRING; | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in op_add(): str_cat() returns <%d>-byte string to level <%d>", | |||
@@ -730,11 +750,7 @@ op_assign( level, precision ) | |||
case NUMBER: | |||
* var_findnval( CURTASK exps[ level - 1 ].xvar, | |||
#ifdef OLDWAY | |||
CURTASK exps[ level - 1 ].xvar->array_pos ) = | |||
#else | |||
CURTASK exps[ level - 1 ].array_pos ) = | |||
#endif | |||
CURTASK exps[ level - 1 ].array_pos ) = | |||
CURTASK exps[ level - 1 ].nval = | |||
exp_getnval( &( CURTASK exps[ level + 1 ] ) ); | |||
break; | |||
@@ -1522,7 +1538,7 @@ op_intdiv( level, precision ) | |||
FUNCTION: op_or() | |||
DESCRIPTION: This function compares two integers and | |||
performs a logical NOT on them. | |||
performs a logical OR on them. | |||
***************************************************************/ | |||
@@ -1579,7 +1595,7 @@ op_or( level, precision ) | |||
FUNCTION: op_and() | |||
DESCRIPTION: This function compares two integers and | |||
performs a logical NOT on them. | |||
performs a logical AND on them. | |||
***************************************************************/ | |||
@@ -1636,8 +1652,8 @@ op_and( level, precision ) | |||
FUNCTION: op_not() | |||
DESCRIPTION: This function compares two integers and | |||
performs a logical NOT on them. | |||
DESCRIPTION: This function performs a logical NOT on | |||
the integer to the right. | |||
***************************************************************/ | |||
@@ -1682,7 +1698,7 @@ op_not( level, precision ) | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in op_not(): result is <%d>, precision <%c>", | |||
(int) r, precision ); | |||
(unsigned int) exp_getnval( &( CURTASK exps[ level ] )), precision ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
@@ -1713,7 +1729,7 @@ op_not( level, precision ) | |||
FUNCTION: op_xor() | |||
DESCRIPTION: This function compares two integers and | |||
performs a logical NOT on them. | |||
performs a logical XOR on them. | |||
***************************************************************/ | |||
@@ -1767,6 +1783,83 @@ op_xor( level, precision ) | |||
/*************************************************************** | |||
FUNCTION: op_negation() | |||
DESCRIPTION: This function performs a negation on the | |||
element to the right. | |||
Added by JBV 10/95 | |||
***************************************************************/ | |||
#if ANSI_C | |||
static int | |||
op_negation( int level, int precision ) | |||
#else | |||
static int | |||
op_negation( level, precision ) | |||
int level; | |||
int precision; | |||
#endif | |||
{ | |||
switch( precision ) | |||
{ | |||
case STRING: | |||
/* both sides of the operation should be numbers for | |||
logical comparison; if not, report an error */ | |||
#if PROG_ERRORS | |||
sprintf( bwb_ebuf, "Strings cannot be compared logically." ); | |||
bwb_error( bwb_ebuf ); | |||
#else | |||
bwb_error( err_mismatch ); | |||
#endif | |||
break; | |||
default: | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in op_negation(): argument is <%f>, precision <%c>", | |||
exp_getnval( &( CURTASK exps[ level + 1 ] )), precision ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
CURTASK exps[ level ].nval = (bnumber) | |||
-( exp_getnval( &( CURTASK exps[ level + 1 ] )) ); | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in op_negation(): result is <%f>, precision <%c>", | |||
exp_getnval( &( CURTASK exps[ level ] )), precision ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
break; | |||
} | |||
/* set variable type to requested precision (JBV) */ | |||
CURTASK exps[ level ].type = (char) precision; | |||
CURTASK exps[ level ].operation = NUMBER; | |||
/* decrement the stack once */ | |||
op_pulldown( 1 ); | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in op_negation(): CURTASK expsc <%d>, level <%d> result <%f>", | |||
CURTASK expsc, level, CURTASK exps[ CURTASK expsc ].nval ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
return TRUE; | |||
} | |||
/*************************************************************** | |||
FUNCTION: op_islevelstr() | |||
DESCRIPTION: This function determines whether the | |||
@@ -1903,8 +1996,18 @@ op_pulldown( how_far ) | |||
while ( CURTASK expsc >= ( level + how_far ) ) | |||
{ | |||
/*------------------------------------------------------*/ | |||
/* But before memcpy, deallocate sbuffer for level, and */ | |||
/* afterwards, set sbuffer for level + how_far to NULL! */ | |||
/* Else konfusion reigns the next time around... (JBV) */ | |||
/*------------------------------------------------------*/ | |||
if( CURTASK exps[ level ].sval.sbuffer != NULL ) /* JBV */ | |||
FREE( CURTASK exps[ level ].sval.sbuffer, "op_pulldown" ); | |||
memcpy( &CURTASK exps[ level ], &CURTASK exps[ level + how_far ], | |||
(size_t) ( sizeof( struct exp_ese )) ); | |||
CURTASK exps[ level + how_far ].sval.sbuffer = NULL; /* JBV */ | |||
++level; | |||
} | |||
@@ -25,6 +25,11 @@ | |||
***************************************************************/ | |||
/*---------------------------------------------------------------*/ | |||
/* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */ | |||
/* 11/1995 (eidetics@cerf.net). */ | |||
/*---------------------------------------------------------------*/ | |||
#include <stdio.h> | |||
#include "bwbasic.h" | |||
@@ -69,7 +74,8 @@ bwb_newtask( task_requested ) | |||
/* get memory for task structure */ | |||
if ( ( bwb_tasks[ task_requested ] = calloc( 1, sizeof( struct bwb_task ) ) ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( bwb_tasks[ task_requested ] = CALLOC( 1, sizeof( struct bwb_task ), "bwb_newtask" ) ) | |||
== NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
@@ -107,4 +113,3 @@ bwb_newtask( task_requested ) | |||
#endif | |||
@@ -23,6 +23,11 @@ | |||
***************************************************************/ | |||
/*---------------------------------------------------------------*/ | |||
/* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */ | |||
/* 11/1995 (eidetics@cerf.net). */ | |||
/*---------------------------------------------------------------*/ | |||
#include <stdio.h> | |||
#include <ctype.h> | |||
#include <math.h> | |||
@@ -103,7 +108,9 @@ bwb_print( l ) | |||
if ( init == FALSE ) | |||
{ | |||
init = TRUE; | |||
if ( ( s_buffer = calloc( MAXSTRINGSIZE + 1, sizeof(char) ) ) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( s_buffer = CALLOC( MAXSTRINGSIZE + 1, sizeof(char), "bwb_print") ) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in bwb_print(): failed to get memory for s_buffer" ); | |||
@@ -232,6 +239,9 @@ bwb_xprint( l, f ) | |||
static char *element; | |||
static char *prnbuf; | |||
static int init = FALSE; | |||
register int i, j; /* JBV */ | |||
int dig_pos, dec_pos; /* JBV */ | |||
char tbuf[ MAXSTRINGSIZE + 1 ]; /* JBV */ | |||
#if INTENSIVE_DEBUG || TEST_BSTRING | |||
bstring *b; | |||
#endif | |||
@@ -241,7 +251,9 @@ bwb_xprint( l, f ) | |||
if ( init == FALSE ) | |||
{ | |||
init = TRUE; | |||
if ( ( format_string = calloc( MAXSTRINGSIZE + 1, sizeof(char) ) ) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( format_string = CALLOC( MAXSTRINGSIZE + 1, sizeof(char), "bwb_xprint") ) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in bwb_xprint(): failed to get memory for format_string" ); | |||
@@ -249,7 +261,8 @@ bwb_xprint( l, f ) | |||
bwb_error( err_getmem ); | |||
#endif | |||
} | |||
if ( ( output_string = calloc( MAXSTRINGSIZE + 1, sizeof(char) ) ) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( output_string = CALLOC( MAXSTRINGSIZE + 1, sizeof(char), "bwb_xprint") ) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in bwb_xprint(): failed to get memory for output_string" ); | |||
@@ -257,7 +270,8 @@ bwb_xprint( l, f ) | |||
bwb_error( err_getmem ); | |||
#endif | |||
} | |||
if ( ( element = calloc( MAXSTRINGSIZE + 1, sizeof(char) ) ) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( element = CALLOC( MAXSTRINGSIZE + 1, sizeof(char), "bwb_xprint") ) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in bwb_xprint(): failed to get memory for element buffer" ); | |||
@@ -265,7 +279,8 @@ bwb_xprint( l, f ) | |||
bwb_error( err_getmem ); | |||
#endif | |||
} | |||
if ( ( prnbuf = calloc( MAXSTRINGSIZE + 1, sizeof(char) ) ) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( prnbuf = CALLOC( MAXSTRINGSIZE + 1, sizeof(char), "bwb_xprint") ) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in bwb_xprint(): failed to get memory for prnbuf" ); | |||
@@ -425,8 +440,9 @@ bwb_xprint( l, f ) | |||
bwb_error( err_mismatch ); | |||
#endif | |||
} | |||
sprintf( output_string, "%.*s", format->width, | |||
element ); | |||
if ( format->width == -1 ) /* JBV */ | |||
sprintf( output_string, "%s", element ); | |||
else sprintf( output_string, "%.*s", format->width, element ); | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_xprint(): output string <%s>", | |||
@@ -434,7 +450,7 @@ bwb_xprint( l, f ) | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
prn_xprintf( f, output_string ); | |||
prn_xxprintf( f, output_string ); /* Was prn_xprintf (JBV) */ | |||
break; | |||
case NUMBER: | |||
@@ -449,22 +465,116 @@ bwb_xprint( l, f ) | |||
if ( format->exponential == TRUE ) | |||
{ | |||
sprintf( output_string, "%e", | |||
exp_getnval( e ) ); | |||
/*------------------------------------------------------*/ | |||
/* NOTE: Width and fill have no effect on C exponential */ | |||
/* format (JBV) */ | |||
/*------------------------------------------------------*/ | |||
if ( format->sign == TRUE ) /* Added by JBV */ | |||
sprintf( output_string, "%+e", exp_getnval( e ) ); | |||
else | |||
sprintf( output_string, "%e", exp_getnval( e ) ); | |||
} | |||
else | |||
{ | |||
/*---------------------------------------------------*/ | |||
/* NOTE: Minus, commas, and money are only valid for */ | |||
/* floating point format (JBV) */ | |||
/*---------------------------------------------------*/ | |||
if ( format->sign == TRUE ) /* Added by JBV */ | |||
sprintf( output_string, "%+*.*f", | |||
format->width, format->precision, exp_getnval( e ) ); | |||
else if ( format->minus == TRUE ) /* Added by JBV */ | |||
{ | |||
sprintf( output_string, "%*.*f", | |||
format->width, format->precision, exp_getnval( e ) ); | |||
for (i = 0; i < strlen( output_string ); ++i ) | |||
{ | |||
if ( output_string[ i ] != ' ' ) | |||
{ | |||
if ( output_string[ i ] == '-' ) | |||
{ | |||
output_string[ i ] = ' '; | |||
strcat( output_string, "-" ); | |||
} | |||
else strcat( output_string, " " ); | |||
break; | |||
} | |||
} | |||
} | |||
else | |||
sprintf( output_string, "%*.*f", | |||
format->width, format->precision, exp_getnval( e ) ); | |||
if ( format->commas == TRUE ) /* Added by JBV */ | |||
{ | |||
dig_pos = -1; | |||
dec_pos = -1; | |||
for ( i = 0; i < strlen( output_string ); ++i ) | |||
{ | |||
if ( ( isdigit( output_string[ i ] ) != 0 ) | |||
&& ( dig_pos == -1 ) ) | |||
dig_pos = i; | |||
if ( ( output_string[ i ] == '.' ) | |||
&& ( dec_pos == -1 ) ) | |||
dec_pos = i; | |||
if ( ( dig_pos != -1 ) && ( dec_pos != -1 ) ) break; | |||
} | |||
if ( dec_pos == -1 ) dec_pos = strlen( output_string ); | |||
j = 0; | |||
for ( i = 0; i < strlen( output_string ); ++i ) | |||
{ | |||
if ( ( ( dec_pos - i ) % 3 == 0 ) | |||
&& ( i > dig_pos ) && ( i < dec_pos ) ) | |||
{ | |||
tbuf[ j ] = ','; | |||
++j; | |||
tbuf[ j ] = '\0'; | |||
} | |||
tbuf[ j ] = output_string[ i ]; | |||
++j; | |||
tbuf[ j ] = '\0'; | |||
} | |||
strcpy( output_string, | |||
&tbuf[ strlen( tbuf ) - strlen( output_string ) ] ); | |||
} | |||
if ( format->money == TRUE ) /* Added by JBV */ | |||
{ | |||
for ( i = 0; i < strlen( output_string ); ++i ) | |||
{ | |||
if ( output_string[ i ] != ' ' ) | |||
{ | |||
if ( i > 0 ) | |||
{ | |||
if ( isdigit( output_string[ i ] ) == 0 ) | |||
{ | |||
output_string[ i - 1 ] | |||
= output_string[ i ]; | |||
output_string[ i ] = '$'; | |||
} | |||
else output_string[ i - 1 ] = '$'; | |||
} | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
if ( format->fill == '*' ) /* Added by JBV */ | |||
for ( i = 0; i < strlen( output_string ); ++i ) | |||
{ | |||
if ( output_string[ i ] != ' ' ) break; | |||
output_string[ i ] = '*'; | |||
} | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_xprint(): output number <%f> string <%s>", | |||
exp_getnval( e ), output_string ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
prn_xprintf( f, output_string ); | |||
prn_xxprintf( f, output_string ); /* Was prn_xprintf (JBV) */ | |||
break; | |||
default: | |||
@@ -521,7 +631,9 @@ bwb_xprint( l, f ) | |||
break; | |||
#endif | |||
case ',': /* tab over */ | |||
xputc( f, '\t' ); | |||
/* Tab only if there's no format specification! (JBV) */ | |||
if (( fs_pos == -1 ) || ( strlen( element ) == 0 )) | |||
xputc( f, '\t' ); | |||
++l->position; | |||
adv_ws( l->buffer, &( l->position ) ); | |||
break; | |||
@@ -536,6 +648,9 @@ bwb_xprint( l, f ) | |||
} /* end of loop through print elements */ | |||
if (( fs_pos > -1 ) && ( strlen( element ) > 0 )) | |||
format = get_prnfmt( format_string, &fs_pos, f ); /* Finish up (JBV) */ | |||
/* call prn_cr() to print a CR if it is not overridden by a | |||
concluding ';' mark */ | |||
@@ -593,7 +708,7 @@ get_prnfmt( buffer, position, f ) | |||
/* advance past whitespace */ | |||
adv_ws( buffer, position ); | |||
/* adv_ws( buffer, position ); */ /* Don't think we want this (JBV) */ | |||
/* check first character: a lost can be decided right here */ | |||
@@ -610,7 +725,9 @@ get_prnfmt( buffer, position, f ) | |||
switch( buffer[ *position ] ) | |||
{ | |||
case ' ': /* end of this format segment */ | |||
loop = FALSE; | |||
xxputc( f, buffer[ *position ] ); /* Gotta output it (JBV) */ | |||
++( *position ); /* JBV */ | |||
if (retstruct.type != FALSE) loop = FALSE; /* JBV */ | |||
break; | |||
case '\0': /* end of format string */ | |||
case '\n': | |||
@@ -619,13 +736,20 @@ get_prnfmt( buffer, position, f ) | |||
return &retstruct; | |||
case '_': /* print next character as literal */ | |||
++( *position ); | |||
xputc( f, buffer[ *position ] ); | |||
xxputc( f, buffer[ *position ] ); /* Not xputc, no tabs (JBV) */ | |||
++( *position ); | |||
break; | |||
case '!': | |||
retstruct.type = STRING; | |||
retstruct.width = 1; | |||
++( *position ); /* JBV */ | |||
return &retstruct; | |||
case '&': /* JBV */ | |||
retstruct.type = STRING; | |||
retstruct.width = -1; | |||
++( *position ); | |||
return &retstruct; | |||
case '\\': | |||
@@ -649,18 +773,22 @@ get_prnfmt( buffer, position, f ) | |||
} | |||
return &retstruct; | |||
case '$': | |||
++retstruct.width; /* JBV */ | |||
++( *position ); | |||
retstruct.money = TRUE; | |||
if ( buffer[ *position ] == '$' ) | |||
{ | |||
++retstruct.width; /* JBV */ | |||
++( *position ); | |||
} | |||
break; | |||
case '*': | |||
++retstruct.width; /* JBV */ | |||
++( *position ); | |||
retstruct.fill = '*'; | |||
if ( buffer[ *position ] == '*' ) | |||
{ | |||
++retstruct.width; /* JBV */ | |||
++( *position ); | |||
} | |||
break; | |||
@@ -670,14 +798,17 @@ get_prnfmt( buffer, position, f ) | |||
break; | |||
case '#': | |||
retstruct.type = NUMBER; /* for now */ | |||
++( *position ); | |||
for ( retstruct.width = 1; buffer[ *position ] == '#'; ++( *position ) ) | |||
/* ++( *position ); */ /* Removed by JBV */ | |||
/* The initial condition shouldn't be retstruct.width = 1 (JBV) */ | |||
for ( ; buffer[ *position ] == '#'; ++( *position ) ) | |||
{ | |||
++retstruct.width; | |||
} | |||
if ( buffer[ *position ] == ',' ) | |||
{ | |||
retstruct.commas = TRUE; | |||
++retstruct.width; /* JBV */ | |||
++( *position ); /* JBV */ | |||
} | |||
if ( buffer[ *position ] == '.' ) | |||
{ | |||
@@ -706,6 +837,11 @@ get_prnfmt( buffer, position, f ) | |||
} | |||
return &retstruct; | |||
default: /* JBV */ | |||
xxputc( f, buffer[ *position ] ); /* Gotta output it (JBV) */ | |||
++( *position ); | |||
break; | |||
} | |||
} /* end of loop */ | |||
@@ -838,6 +974,42 @@ prn_xprintf( f, buffer ) | |||
/*************************************************************** | |||
FUNCTION: prn_xxprintf() | |||
DESCRIPTION: This function outputs a null-terminated | |||
string to a specified file or output | |||
device without expanding tabs. | |||
Added by JBV 10/95 | |||
***************************************************************/ | |||
#if ANSI_C | |||
int | |||
prn_xxprintf( FILE *f, char *buffer ) | |||
#else | |||
int | |||
prn_xxprintf( f, buffer ) | |||
FILE *f; | |||
char *buffer; | |||
#endif | |||
{ | |||
char *p; | |||
/* DO NOT try anything so stupid as to run bwb_debug() from | |||
here, because it will create an endless loop. And don't | |||
ask how I know. */ | |||
for ( p = buffer; *p != '\0'; ++p ) | |||
{ | |||
xxputc( f, *p ); | |||
} | |||
return TRUE; | |||
} | |||
/*************************************************************** | |||
FUNCTION: xputc() | |||
DESCRIPTION: This function outputs a character to a | |||
@@ -1111,11 +1283,11 @@ prn_precision( v ) | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in prn_precision(): fmod( %f, %f ) = %.12f", | |||
nval, d, fmod( nval, d ) ); | |||
nval, d, fmod( (double) nval, (double) d ) ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
if ( fmod( nval, d ) < 0.0000001 ) | |||
if ( fmod( (double) nval, (double) d ) < 0.0000001 ) /* JBV */ | |||
{ | |||
return r; | |||
} | |||
@@ -1187,6 +1359,8 @@ bwb_lerror( l ) | |||
{ | |||
char tbuf[ MAXSTRINGSIZE + 1 ]; | |||
int n; | |||
struct exp_ese *e; /* JBV */ | |||
int pos; /* JBV */ | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_lerror(): entered function " ); | |||
@@ -1211,7 +1385,12 @@ bwb_lerror( l ) | |||
/* get the variable name or numerical constant */ | |||
adv_element( l->buffer, &( l->position ), tbuf ); | |||
n = atoi( tbuf ); | |||
/* n = atoi( tbuf ); */ /* Removed by JBV */ | |||
/* Added by JBV */ | |||
pos = 0; | |||
e = bwb_exp( tbuf, FALSE, &pos ); | |||
n = (int) exp_getnval( e ); | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_lerror(): error number is <%d> ", n ); | |||
@@ -29,6 +29,11 @@ | |||
***************************************************************/ | |||
/*---------------------------------------------------------------*/ | |||
/* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */ | |||
/* 11/1995 (eidetics@cerf.net). */ | |||
/*---------------------------------------------------------------*/ | |||
#include <stdio.h> | |||
#include <ctype.h> | |||
@@ -184,12 +189,22 @@ fslt_clear() | |||
while ( c != NULL ) | |||
{ | |||
n = c->next; | |||
free( c ); | |||
/* Revised to FREE pass-thru call by JBV */ | |||
FREE( c, "fslt_clear" ); | |||
c = n; | |||
} | |||
next = current->next; | |||
free( current ); | |||
/* Revised to FREE pass-thru calls by JBV */ | |||
if (current->name != NULL) | |||
{ | |||
FREE( current->name, "fslt_clear" ); /* JBV */ | |||
current->name = NULL; /* JBV */ | |||
} | |||
FREE( current, "fslt_clear" ); | |||
current = NULL; /* JBV */ | |||
} | |||
/* reset linkage */ | |||
@@ -360,6 +375,18 @@ scan_element( buffer, pos, element ) | |||
} | |||
break; | |||
case '(': /* MID$ command termination (JBV) */ | |||
/* If MID$ is here, get out */ | |||
if (strcmp(element, CMD_MID) == 0) | |||
return TRUE; | |||
/* else add it to the accumulation element */ | |||
element[ e_pos ] = buffer[ *pos ]; | |||
++e_pos; | |||
++( *pos ); | |||
element[ e_pos ] = '\0'; | |||
break; | |||
default: | |||
element[ e_pos ] = buffer[ *pos ]; | |||
++e_pos; | |||
@@ -428,7 +455,8 @@ fslt_add( line, position, code ) | |||
/* get memory for name buffer */ | |||
if ( ( name = calloc( 1, strlen( tbuf ) + 1 ) ) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( name = CALLOC( 1, strlen( tbuf ) + 1, "fslt_add" ) ) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in fslt_add(): failed to get memory for name buffer" ); | |||
@@ -442,7 +470,7 @@ fslt_add( line, position, code ) | |||
/* get memory for fslt structure */ | |||
if ( ( f = calloc( 1, sizeof( struct fslte ) ) ) == NULL ) | |||
if ( ( f = CALLOC( 1, sizeof( struct fslte ), "fslt_add" ) ) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in fslt_add(): failed to get memory for fslt structure" ); | |||
@@ -1898,7 +1926,7 @@ var_pos( firstvar, p ) | |||
FUNCTION: fslt_addcallvar() | |||
DESCRIPTION: This function adds a calling variable | |||
to the FUNCTION-SUB lookuop table at | |||
to the FUNCTION-SUB lookup table at | |||
a specific level. | |||
***************************************************************/ | |||
@@ -1932,7 +1960,7 @@ fslt_addcallvar( v ) | |||
/*************************************************************** | |||
FUNCTION: expufnc() | |||
FUNCTION: exp_ufnc() | |||
DESCRIPTION: This C function interprets a user-defined | |||
function, returning its value at the current | |||
@@ -2158,7 +2186,7 @@ exp_ufnc( expression ) | |||
FUNCTION: fslt_addlocalvar() | |||
DESCRIPTION: This function adds a local variable | |||
to the FUNCTION-SUB lookuop table at | |||
to the FUNCTION-SUB lookup table at | |||
a specific level. | |||
***************************************************************/ | |||
@@ -2275,4 +2303,3 @@ is_label( buffer ) | |||
} | |||
@@ -23,6 +23,11 @@ | |||
***************************************************************/ | |||
/*---------------------------------------------------------------*/ | |||
/* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */ | |||
/* 11/1995 (eidetics@cerf.net). */ | |||
/*---------------------------------------------------------------*/ | |||
#include <stdio.h> | |||
#include "bwbasic.h" | |||
@@ -64,7 +69,8 @@ str_btob( d, s ) | |||
/* get memory for new buffer */ | |||
if ( ( t = (char *) calloc( s->length + 1, 1 )) == NULL ) | |||
/* Following section removed by JBV (no more mass string reallocation) */ | |||
/* if ( ( t = (char *) CALLOC( s->length + 1, 1, "str_btob" )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in str_btob(): failed to get memory for new buffer" ); | |||
@@ -72,14 +78,30 @@ str_btob( d, s ) | |||
bwb_error( err_getmem ); | |||
#endif | |||
return FALSE; | |||
} | |||
} */ | |||
/* write the c string to the b string */ | |||
/* Only one of these two conditions necessitates reallocation (JBV) */ | |||
if ( ( d->sbuffer == NULL ) || ( d->rab == TRUE ) ) | |||
{ | |||
if ( ( t = (char *) CALLOC( MAXSTRINGSIZE + 1, 1, "str_btob" )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in str_btob(): failed to get memory for new buffer" ); | |||
#else | |||
bwb_error( err_getmem ); | |||
#endif | |||
return FALSE; | |||
} | |||
} | |||
else t = d->sbuffer; /* Leave well enough alone (JBV) */ | |||
/* write the b string to the temp c string */ | |||
t[ 0 ] = '\0'; | |||
for ( i = 0; i < (int) s->length; ++i ) | |||
{ | |||
t[ i ] = s->sbuffer[ i ]; | |||
t[ i + 1 ] = '\0'; /* JBV */ | |||
#if INTENSIVE_DEBUG | |||
tbuf[ i ] = s->sbuffer[ i ]; | |||
tbuf[ i + 1 ] = '\0'; | |||
@@ -96,18 +118,22 @@ str_btob( d, s ) | |||
} | |||
#endif | |||
if (( d->rab != TRUE ) && ( d->sbuffer != NULL )) | |||
/* Following section removed by JBV (no more mass string reallocation) */ | |||
/* if (( d->rab != TRUE ) && ( d->sbuffer != NULL )) | |||
{ | |||
#if INTENSIVE_DEBUG | |||
sprintf( tbuf, "in str_btob(): deallocating string memory" ); | |||
bwb_debug ( tbuf ); | |||
#endif | |||
free( d->sbuffer ); | |||
FREE( d->sbuffer, "str_btob" ); | |||
d->sbuffer = NULL; | |||
} | |||
else | |||
{ | |||
d->rab = (char) FALSE; | |||
} | |||
} */ | |||
d->rab = (char) FALSE; /* JBV */ | |||
/* reassign buffer */ | |||
@@ -162,7 +188,21 @@ str_ctob( s, buffer ) | |||
/* get memory for new buffer */ | |||
if ( ( t = (char *) calloc( strlen( buffer ) + 1, 1 )) == NULL ) | |||
/* Following section removed by JBV (no more mass string reallocation) */ | |||
/* if ( ( t = (char *) CALLOC( strlen( buffer ) + 1, 1, "str_ctob" )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in str_ctob(): failed to get memory for new buffer" ); | |||
#else | |||
bwb_error( err_getmem ); | |||
#endif | |||
return FALSE; | |||
} */ | |||
/* Only one of these two conditions necessitates reallocation (JBV) */ | |||
if ( ( s->sbuffer == NULL ) || ( s->rab == TRUE ) ) | |||
{ | |||
if ( ( t = (char *) CALLOC( MAXSTRINGSIZE + 1, 1, "str_ctob" )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in str_ctob(): failed to get memory for new buffer" ); | |||
@@ -171,13 +211,16 @@ str_ctob( s, buffer ) | |||
#endif | |||
return FALSE; | |||
} | |||
} | |||
else t = s->sbuffer; /* Leave well enough alone (JBV) */ | |||
/* write the c string to the b string */ | |||
/* write the c string to the temp c string */ | |||
t[ 0 ] = '\0'; | |||
for ( i = 0; i < (int) strlen( buffer ); ++i ) | |||
{ | |||
t[ i ] = buffer[ i ]; | |||
t[ i + 1 ] = '\0'; /* JBV */ | |||
#if INTENSIVE_DEBUG | |||
tbuf[ i ] = buffer[ i ]; | |||
tbuf[ i + 1 ] = '\0'; | |||
@@ -194,14 +237,18 @@ str_ctob( s, buffer ) | |||
} | |||
#endif | |||
if (( s->rab != TRUE ) && ( s->sbuffer != NULL )) | |||
/* Following section removed by JBV (no more mass string reallocation) */ | |||
/* if (( s->rab != TRUE ) && ( s->sbuffer != NULL )) | |||
{ | |||
free( s->sbuffer ); | |||
FREE( s->sbuffer, "str_ctob" ); | |||
s->sbuffer = NULL; | |||
} | |||
else | |||
{ | |||
s->rab = (char) FALSE; | |||
} | |||
} */ | |||
s->rab = (char) FALSE; /* JBV */ | |||
/* reassign buffer */ | |||
@@ -351,5 +398,3 @@ str_cmp( a, b ) | |||
} | |||
@@ -24,6 +24,11 @@ | |||
***************************************************************/ | |||
/*---------------------------------------------------------------*/ | |||
/* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */ | |||
/* 11/1995 (eidetics@cerf.net). */ | |||
/*---------------------------------------------------------------*/ | |||
#include <stdio.h> | |||
#include "bwbasic.h" | |||
@@ -71,6 +76,7 @@ struct bwb_command bwb_cmdtable[ COMMANDS ] = | |||
{ CMD_DEFINT, bwb_dint }, | |||
{ CMD_DEFSNG, bwb_dsng }, | |||
{ CMD_DEFSTR, bwb_dstr }, | |||
{ CMD_MID, bwb_mid }, /* Added this extension (JBV) */ | |||
#if IMP_CMDCLS | |||
{ CMD_CLS, bwb_cls }, | |||
#endif | |||
@@ -120,6 +126,7 @@ struct bwb_command bwb_cmdtable[ COMMANDS ] = | |||
{ CMD_RSET, bwb_rset }, | |||
{ CMD_FIELD, bwb_field }, | |||
{ CMD_LINE, bwb_line }, | |||
{ CMD_RENUM, bwb_renum }, /* Added this extension (JBV) */ | |||
#endif | |||
/* The remainder are the core functions defined for ANSI Minimal BASIC */ | |||
@@ -243,30 +250,31 @@ struct bwb_function bwb_prefuncs[ FUNCTIONS ] = | |||
struct bwb_op exp_ops[ N_OPERATORS ] = | |||
{ | |||
{ "NOT", OP_NOT, 12 }, /* multiple-character operators */ | |||
{ "NOT", OP_NOT, 2 }, /* multiple-character operators */ | |||
{ "AND", OP_AND, 13 }, /* should be tested first because */ | |||
{ "OR", OP_OR, 14 }, /* e.g. a ">=" would be matched */ | |||
{ "XOR", OP_XOR, 15 }, /* as "=" if the single-character */ | |||
{ "IMP", OP_IMPLIES, 16 }, /* operator came first */ | |||
{ "EQV", OP_EQUIV, 17 }, | |||
{ "MOD", OP_MODULUS, 4 }, | |||
{ "<>", OP_NOTEQUAL, 7 }, | |||
{ "<=", OP_LTEQ, 10 }, | |||
{ "=<", OP_LTEQ, 10 }, /* allow either form */ | |||
{ ">=", OP_GTEQ, 11 }, | |||
{ "=>", OP_GTEQ, 11 }, /* allow either form */ | |||
{ "<", OP_LESSTHAN, 8 }, | |||
{ ">", OP_GREATERTHAN, 9 }, | |||
{ "MOD", OP_MODULUS, 5 }, | |||
{ "<>", OP_NOTEQUAL, 8 }, | |||
{ "<=", OP_LTEQ, 11 }, | |||
{ "=<", OP_LTEQ, 11 }, /* allow either form */ | |||
{ ">=", OP_GTEQ, 12 }, | |||
{ "=>", OP_GTEQ, 12 }, /* allow either form */ | |||
{ "<", OP_LESSTHAN, 9 }, | |||
{ ">", OP_GREATERTHAN, 10 }, | |||
{ "^", OP_EXPONENT, 0 }, | |||
{ "*", OP_MULTIPLY, 2 }, | |||
{ "/", OP_DIVIDE, 2 }, | |||
{ "\\", OP_INTDIVISION, 3 }, | |||
{ "+", OP_ADD, 5 }, | |||
{ "-", OP_SUBTRACT, 5 }, | |||
{ "=", OP_EQUALS, 6 }, | |||
{ "=", OP_ASSIGN, 6 }, /* don't worry: OP_EQUALS will be converted to OP_ASSIGN if necessary */ | |||
{ ";", OP_STRJOIN, 18 }, | |||
{ ",", OP_STRTAB, 19 } | |||
{ "*", OP_MULTIPLY, 3 }, | |||
{ "/", OP_DIVIDE, 3 }, | |||
{ "\\", OP_INTDIVISION, 4 }, | |||
{ "+", OP_ADD, 6 }, | |||
{ "-", OP_SUBTRACT, 6 }, | |||
{ "=", OP_EQUALS, 7 }, | |||
{ "=", OP_ASSIGN, 18 }, /* don't worry: OP_EQUALS will be converted to OP_ASSIGN if necessary */ | |||
{ ";", OP_STRJOIN, 19 }, | |||
{ ",", OP_STRTAB, 20 }, | |||
{ "-", OP_NEGATION, 1 } /* Right below exponentiation (JBV) */ | |||
}; | |||
/* Error messages used more than once */ | |||
@@ -332,4 +340,3 @@ char *err_table[ N_ERRORS ] = | |||
}; | |||
@@ -2,4 +2,3 @@ | |||
establish a larger-than-usual stack of 8192 bytes for bwBASIC */ | |||
extern unsigned _stklen = 8192U; | |||
@@ -29,6 +29,11 @@ | |||
***************************************************************/ | |||
/*---------------------------------------------------------------*/ | |||
/* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */ | |||
/* 11/1995 (eidetics@cerf.net). */ | |||
/*---------------------------------------------------------------*/ | |||
#include <stdio.h> | |||
#include <ctype.h> | |||
#include <math.h> | |||
@@ -162,6 +167,8 @@ bwb_erase( l ) | |||
struct bwb_variable *v; | |||
struct bwb_variable *p; /* previous variable in linked list */ | |||
char tbuf[ MAXSTRINGSIZE + 1 ]; | |||
bstring *sp; /* JBV */ | |||
register int n; /* JBV */ | |||
/* loop while arguments are available */ | |||
@@ -200,17 +207,39 @@ bwb_erase( l ) | |||
/* deallocate memory */ | |||
free( v->array_sizes ); | |||
free( v->array_pos ); | |||
/* Revised to FREE pass-thru calls by JBV */ | |||
FREE( v->array_sizes, "bwb_erase" ); | |||
v->array_sizes = NULL; /* JBV */ | |||
FREE( v->array_pos , "bwb_erase"); | |||
v->array_pos = NULL; /* JBV */ | |||
if ( v->type == NUMBER ) | |||
{ | |||
free( v->memnum ); | |||
/* Revised to FREE pass-thru call by JBV */ | |||
FREE( v->memnum, "bwb_erase" ); | |||
v->memnum = NULL; /* JBV */ | |||
} | |||
else | |||
{ | |||
free( v->memstr ); | |||
/* Following section added by JBV */ | |||
sp = v->memstr; | |||
for ( n = 0; n < (int) v->array_units; ++n ) | |||
{ | |||
if ( sp[ n ].sbuffer != NULL ) | |||
{ | |||
/* Revised to FREE pass-thru call by JBV */ | |||
FREE( sp[ n ].sbuffer, "bwb_erase" ); | |||
sp[ n ].sbuffer = NULL; | |||
} | |||
sp[ n ].rab = FALSE; | |||
sp[ n ].length = 0; | |||
} | |||
/* Revised to FREE pass-thru call by JBV */ | |||
FREE( v->memstr, "bwb_erase" ); | |||
v->memstr = NULL; /* JBV */ | |||
} | |||
free( v ); | |||
/* Revised to FREE pass-thru call by JBV */ | |||
FREE( v, "bwb_erase" ); | |||
v = NULL; /* JBV */ | |||
/* check for comma */ | |||
@@ -412,7 +441,8 @@ bwb_clear( l ) | |||
{ | |||
if ( sp[ n ].sbuffer != NULL ) | |||
{ | |||
free( sp[ n ].sbuffer ); | |||
/* Revised to FREE pass-thru call by JBV */ | |||
FREE( sp[ n ].sbuffer, "bwb_clear" ); | |||
sp[ n ].sbuffer = NULL; | |||
} | |||
sp[ n ].rab = FALSE; | |||
@@ -447,6 +477,8 @@ var_delcvars() | |||
{ | |||
struct bwb_variable *v; | |||
struct bwb_variable *p; /* previous variable */ | |||
bstring *sp; /* JBV */ | |||
register int n; /* JBV */ | |||
p = &CURTASK var_start; | |||
for ( v = CURTASK var_start.next; v != &CURTASK var_end; v = v->next ) | |||
@@ -462,15 +494,35 @@ var_delcvars() | |||
/* deallocate memory */ | |||
free( v->array_sizes ); | |||
free( v->array_pos ); | |||
/* Revised to FREE pass-thru calls by JBV */ | |||
FREE( v->array_sizes, "var_delcvars" ); | |||
v->array_sizes = NULL; /* JBV */ | |||
FREE( v->array_pos, "var_delcvars" ); | |||
v->array_pos = NULL; /* JBV */ | |||
if ( v->type == NUMBER ) | |||
{ | |||
free( v->memnum ); | |||
/* Revised to FREE pass-thru call by JBV */ | |||
FREE( v->memnum, "var_delcvars" ); | |||
v->memnum = NULL; /* JBV */ | |||
} | |||
else | |||
{ | |||
free( v->memstr ); | |||
/* Following section added by JBV */ | |||
sp = v->memstr; | |||
for ( n = 0; n < (int) v->array_units; ++n ) | |||
{ | |||
if ( sp[ n ].sbuffer != NULL ) | |||
{ | |||
/* Revised to FREE pass-thru call by JBV */ | |||
FREE( sp[ n ].sbuffer, "var_delcvars" ); | |||
sp[ n ].sbuffer = NULL; | |||
} | |||
sp[ n ].rab = FALSE; | |||
sp[ n ].length = 0; | |||
} | |||
/* Revised to FREE pass-thru call by JBV */ | |||
FREE( v->memstr, "var_delcvars" ); | |||
v->memstr = NULL; /* JBV */ | |||
} | |||
} | |||
@@ -480,7 +532,9 @@ var_delcvars() | |||
/* deallocate the variable itself */ | |||
free( v ); | |||
/* Revised to FREE pass-thru call by JBV */ | |||
FREE( v, "var_delcvars" ); | |||
v = NULL; /* JBV */ | |||
} | |||
@@ -617,6 +671,246 @@ bwb_dstr( l ) | |||
/*********************************************************** | |||
FUNCTION: bwb_mid() | |||
DESCRIPTION: This function implements the BASIC | |||
MID$ command. | |||
Same as MID$ function, except it will set | |||
the desired substring and not return its | |||
value. Added by JBV 10/95 | |||
SYNTAX: MID$( string-variable$, start-position-in-string | |||
[, number-of-spaces ] ) = expression | |||
***********************************************************/ | |||
#if ANSI_C | |||
struct bwb_line * | |||
bwb_mid( struct bwb_line *l ) | |||
#else | |||
struct bwb_line * | |||
bwb_mid( l ) | |||
struct bwb_line *l; | |||
#endif | |||
{ | |||
char tbuf[ MAXSTRINGSIZE + 1 ]; | |||
char source_string[ MAXSTRINGSIZE + 1 ]; | |||
struct bwb_variable *v; | |||
static int pos; | |||
bstring *d; | |||
int *pp; | |||
int n_params; | |||
int p; | |||
register int n; | |||
int startpos, numchars, endpos; | |||
int source_counter, source_length, target_length; | |||
int target_terminate; | |||
struct exp_ese *e; | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_mid(): MID$ command" ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
/* Get past left parenthesis */ | |||
adv_ws( l->buffer, &( l->position ) ); | |||
++( l->position ); | |||
adv_ws( l->buffer, &( l->position ) ); | |||
/* Get variable name and find variable */ | |||
bwb_getvarname( l->buffer, tbuf, &( l->position ) ); | |||
v = var_find( tbuf ); | |||
if ( v == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
sprintf( bwb_ebuf, "in bwb_mid(): failed to find variable" ); | |||
bwb_error( bwb_ebuf ); | |||
#else | |||
bwb_error( err_syntax ); | |||
#endif | |||
} | |||
if ( v->type != STRING ) | |||
{ | |||
#if PROG_ERRORS | |||
sprintf( bwb_ebuf, "in bwb_mid(): assignment must be to string variable" ); | |||
bwb_error( bwb_ebuf ); | |||
#else | |||
bwb_error( err_syntax ); | |||
#endif | |||
} | |||
/* read subscripts */ | |||
pos = 0; | |||
if ( ( v->dimensions == 1 ) && ( v->array_sizes[ 0 ] == 1 )) | |||
{ | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_mid(): variable <%s> has 1 dimension", | |||
v->name ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
n_params = 1; | |||
pp = &p; | |||
pp[ 0 ] = dim_base; | |||
} | |||
else | |||
{ | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_mid(): variable <%s> has > 1 dimensions", | |||
v->name ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
dim_getparams( l->buffer, &( l->position ), &n_params, &pp ); | |||
} | |||
CURTASK exps[ CURTASK expsc ].pos_adv = pos; | |||
for ( n = 0; n < v->dimensions; ++n ) | |||
{ | |||
v->array_pos[ n ] = pp[ n ]; | |||
} | |||
/* get bstring pointer */ | |||
d = var_findsval( v, pp ); | |||
/* Get past next comma and white space */ | |||
adv_ws( l->buffer, &( l->position ) ); | |||
++( l->position ); | |||
adv_ws( l->buffer, &( l->position ) ); | |||
/* Get starting position (expression) */ | |||
adv_element( l->buffer, &( l->position ), tbuf ); | |||
pos = 0; | |||
e = bwb_exp( tbuf, FALSE, &pos ); | |||
startpos = (int) exp_getnval( e ); | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_mid(): startpos <%d> buffer <%lX>", | |||
startpos, (long) d->sbuffer ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
/* Get past next comma and white space (if they exist) */ | |||
adv_ws( l->buffer, &( l->position ) ); | |||
if (l->buffer[l->position] == ',') | |||
{ | |||
target_terminate = 0; | |||
++( l->position ); | |||
adv_ws( l->buffer, &( l->position ) ); | |||
adv_element( l->buffer, &( l->position ), tbuf ); | |||
pos = 0; | |||
e = bwb_exp( tbuf, FALSE, &pos ); | |||
numchars = (int) exp_getnval( e ); | |||
if ( numchars == 0 ) | |||
{ | |||
#if PROG_ERRORS | |||
sprintf( bwb_ebuf, "in bwb_mid(): destination string no. of chars out of range" ); | |||
bwb_error( bwb_ebuf ); | |||
#else | |||
bwb_error( "Argument out of range" ); | |||
#endif | |||
} | |||
} | |||
else | |||
{ | |||
target_terminate = 1; | |||
numchars = 0; | |||
} | |||
if ( numchars < 0 ) | |||
{ | |||
#if PROG_ERRORS | |||
sprintf( bwb_ebuf, "in bwb_mid(): negative string length" ); | |||
bwb_error( bwb_ebuf ); | |||
#else | |||
bwb_error( "Negative string length" ); | |||
#endif | |||
} | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_mid(): numchars <%d> target_terminate <%d>", numchars, target_terminate ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
/* Get past equal sign */ | |||
adv_ws( l->buffer, &( l->position ) ); | |||
if (l->buffer[l->position] == ')') | |||
{ | |||
++(l->position); | |||
adv_ws( l->buffer, &( l->position ) ); | |||
} | |||
++(l->position); | |||
adv_ws( l->buffer, &( l->position ) ); | |||
/* Evaluate string expression */ | |||
e = bwb_exp( l->buffer, FALSE, &( l->position ) ); | |||
if ( e->type != STRING ) | |||
{ | |||
#if PROG_ERRORS | |||
sprintf( bwb_ebuf, "in bwb_mid(): assignment must be from string expression" ); | |||
bwb_error( bwb_ebuf ); | |||
#else | |||
bwb_error( err_syntax ); | |||
#endif | |||
} | |||
/* Prepare to MID the string */ | |||
str_btoc( source_string, exp_getsval( e ) ); | |||
str_btoc( tbuf, d ); | |||
target_length = strlen( tbuf ); | |||
if ( startpos > ( target_length + 1 ) ) | |||
{ | |||
#if PROG_ERRORS | |||
sprintf( bwb_ebuf, "in bwb_mid(): non-contiguous string created" ); | |||
bwb_error( bwb_ebuf ); | |||
#else | |||
bwb_error( "Non-contiguous string created" ); | |||
#endif | |||
} | |||
if ( startpos < 1 ) | |||
{ | |||
#if PROG_ERRORS | |||
sprintf( bwb_ebuf, "in bwb_mid(): destination string start position out of range" ); | |||
bwb_error( bwb_ebuf ); | |||
#else | |||
bwb_error( "Argument out of range" ); | |||
#endif | |||
} | |||
source_length = strlen( source_string ); | |||
if ( numchars == 0 ) numchars = source_length; | |||
endpos = startpos + numchars - 1; | |||
/* MID the string */ | |||
if ( endpos < startpos ) tbuf[ startpos - 1 ] = '\0'; | |||
else | |||
{ | |||
source_counter = 0; | |||
for ( n = startpos - 1; n < endpos; ++n ) | |||
{ | |||
if ( source_counter < source_length ) | |||
tbuf[ n ] = source_string[ source_counter ]; | |||
else | |||
tbuf[ n ] = ' '; | |||
++source_counter; | |||
} | |||
/* Terminate if indicated or characters were added */ | |||
if ( ( endpos > target_length ) || ( target_terminate == 1 ) ) | |||
tbuf[ endpos ] = '\0'; | |||
} | |||
str_ctob( d, tbuf ); | |||
#if MULTISEG_LINES | |||
adv_eos( l->buffer, &( l->position )); | |||
#endif | |||
return bwb_zline( l ); | |||
} | |||
/*********************************************************** | |||
Function: var_defx() | |||
DESCRIPTION: This function is a generalized DEFxxx handler. | |||
@@ -886,6 +1180,7 @@ bwb_getvarname( lb, sb, n ) | |||
case ';': | |||
case '(': /* beginning of parameter list for dimensioned array */ | |||
case '+': /* add variables */ | |||
case '=': /* Don't forget this one (JBV) */ | |||
sb[ s ] = 0; | |||
return TRUE; | |||
default: | |||
@@ -1029,7 +1324,8 @@ var_new( name ) | |||
/* get memory for new variable */ | |||
if ( ( v = (struct bwb_variable *) calloc( 1, sizeof( struct bwb_variable ) )) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( v = (struct bwb_variable *) CALLOC( 1, sizeof( struct bwb_variable ), "var_new" )) | |||
== NULL ) | |||
{ | |||
bwb_error( err_getmem ); | |||
@@ -1299,7 +1595,8 @@ bwb_dim( l ) | |||
/* assign memory for parameters */ | |||
if ( ( newvar->array_sizes = (int *) calloc( n_params, sizeof( int ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( newvar->array_sizes = (int *) CALLOC( n_params, sizeof( int ), "bwb_dim" )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
sprintf( bwb_ebuf, "in line %d: Failed to find memory for array_sizes for <%s>", | |||
@@ -1323,7 +1620,8 @@ bwb_dim( l ) | |||
/* assign memory for current position */ | |||
if ( ( newvar->array_pos = (int *) calloc( n_params, sizeof( int ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( newvar->array_pos = (int *) CALLOC( n_params, sizeof( int ), "bwb_dim" )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
sprintf( bwb_ebuf, "in line %d: Failed to find memory for array_pos for <%s>", | |||
@@ -1364,8 +1662,13 @@ bwb_dim( l ) | |||
(long) ( newvar->array_units + 1 ) * sizeof( bstring )); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
if ( ( newvar->memnum = calloc( newvar->array_units, sizeof( bstring) )) == NULL ) | |||
{ | |||
/*------------------------------------------------------*/ | |||
/* memnum, not memstr, was used here -- incorrect (JBV) */ | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
/*------------------------------------------------------*/ | |||
if ( ( newvar->memstr = (bstring *) | |||
CALLOC( newvar->array_units, sizeof( bstring), "bwb_dim" )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
sprintf( bwb_ebuf, "in line %d: Failed to find memory for array <%s>", | |||
l->number, newvar->name ); | |||
@@ -1385,8 +1688,10 @@ bwb_dim( l ) | |||
(long) ( newvar->array_units + 1 ) * sizeof( double )); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( np = (bnumber *) | |||
calloc( newvar->array_units, sizeof( bnumber ) )) == NULL ) | |||
CALLOC( newvar->array_units, sizeof( bnumber ), "bwb_dim" )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
sprintf( bwb_ebuf, "in line %d: Failed to find memory for array <%s>", | |||
@@ -1544,6 +1849,9 @@ dim_getparams( buffer, pos, n_params, pp ) | |||
int x_pos, s_pos; | |||
struct exp_ese *e; | |||
char tbuf[ MAXSTRINGSIZE + 1 ]; | |||
#if INTENSIVE_DEBUG | |||
register int n; | |||
#endif | |||
/* set initial values */ | |||
@@ -1825,8 +2133,7 @@ var_findnval( v, pp ) | |||
for ( n = 0; n < v->dimensions; ++n ) | |||
{ | |||
sprintf( bwb_ebuf, | |||
"in var_findnval(): dimensioned variable <%s> pos <%d> <%d>.", | |||
v->name, | |||
"in var_findnval(): dimensioned variable pos <%d> <%d>.", | |||
n, pp[ n ] ); | |||
bwb_debug( bwb_ebuf ); | |||
} | |||
@@ -1864,6 +2171,8 @@ var_findsval( v, pp ) | |||
bstring *p; | |||
#if INTENSIVE_DEBUG | |||
register int n; | |||
sprintf( bwb_ebuf, "in var_findsval(): entered, var <%s>", v->name ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
@@ -2014,6 +2323,8 @@ var_make( v, type ) | |||
{ | |||
size_t data_size; | |||
bstring *b; | |||
bstring *sp; /* JBV */ | |||
register int n; /* JBV */ | |||
#if TEST_BSTRING | |||
static int tnumber = 0; | |||
#endif | |||
@@ -2032,9 +2343,48 @@ var_make( v, type ) | |||
/* get memory for array */ | |||
/* First kleanup the joint (JBV) */ | |||
if (v->memnum != NULL) | |||
{ | |||
/* Revised to FREE pass-thru call by JBV */ | |||
FREE(v->memnum, "var_make"); | |||
v->memnum = NULL; | |||
} | |||
if (v->memstr != NULL) | |||
{ | |||
/* Remember to deallocate those far-flung branches! (JBV) */ | |||
sp = v->memstr; | |||
for ( n = 0; n < (int) v->array_units; ++n ) | |||
{ | |||
if ( sp[ n ].sbuffer != NULL ) | |||
{ | |||
/* Revised to FREE pass-thru call by JBV */ | |||
FREE( sp[ n ].sbuffer, "var_make" ); | |||
sp[ n ].sbuffer = NULL; | |||
} | |||
sp[ n ].rab = FALSE; | |||
sp[ n ].length = 0; | |||
} | |||
/* Revised to FREE pass-thru call by JBV */ | |||
FREE(v->memstr, "var_make"); | |||
v->memstr = NULL; | |||
} | |||
/* Revised to FREE pass-thru calls by JBV */ | |||
if (v->array_sizes != NULL) | |||
{ | |||
FREE(v->array_sizes, "var_make"); | |||
v->array_sizes = NULL; /* JBV */ | |||
} | |||
if (v->array_pos != NULL) | |||
{ | |||
FREE(v->array_pos, "var_make"); | |||
v->array_pos = NULL; /* JBV */ | |||
} | |||
if ( v->type == NUMBER ) | |||
{ | |||
if ( ( v->memnum = calloc( 2, sizeof( bnumber ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( v->memnum = CALLOC( 2, sizeof( bnumber ), "var_make" )) == NULL ) | |||
{ | |||
bwb_error( err_getmem ); | |||
return FALSE; | |||
@@ -2042,7 +2392,8 @@ var_make( v, type ) | |||
} | |||
else | |||
{ | |||
if ( ( v->memstr = calloc( 2, sizeof( bstring ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( v->memstr = CALLOC( 2, sizeof( bstring ), "var_make" )) == NULL ) | |||
{ | |||
bwb_error( err_getmem ); | |||
return FALSE; | |||
@@ -2051,13 +2402,15 @@ var_make( v, type ) | |||
/* get memory for array_sizes and array_pos */ | |||
if ( ( v->array_sizes = (int *) calloc( 2, sizeof( int ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( v->array_sizes = (int *) CALLOC( 2, sizeof( int ), "var_make" )) == NULL ) | |||
{ | |||
bwb_error( err_getmem ); | |||
return FALSE; | |||
} | |||
if ( ( v->array_pos = (int *) calloc( 2, sizeof( int ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( v->array_pos = (int *) CALLOC( 2, sizeof( int ), "var_make" )) == NULL ) | |||
{ | |||
bwb_error( err_getmem ); | |||
return FALSE; | |||
@@ -28,6 +28,11 @@ | |||
***************************************************************/ | |||
/*---------------------------------------------------------------*/ | |||
/* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */ | |||
/* 11/1995 (eidetics@cerf.net). */ | |||
/*---------------------------------------------------------------*/ | |||
#include <stdio.h> | |||
#include <ctype.h> | |||
#include <math.h> | |||
@@ -153,7 +158,8 @@ bwb_init( argc, argv ) | |||
/* Memory allocation */ | |||
/* eXecute TeXT stack */ | |||
if ( ( xtxts = calloc( XTXTSTACKSIZE, sizeof( struct xtxtsl ) ) ) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( xtxts = CALLOC( XTXTSTACKSIZE, sizeof( struct xtxtsl ), "bwb_init") ) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in bwb_init(): failed to find memory for xtxts" ); | |||
@@ -164,7 +170,8 @@ bwb_init( argc, argv ) | |||
/* expression stack */ | |||
if ( ( exps = calloc( ESTACKSIZE, sizeof( struct exp_ese ) ) ) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( exps = CALLOC( ESTACKSIZE, sizeof( struct exp_ese ), "bwb_init") ) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in bwb_init(): failed to find memory for exps" ); | |||
@@ -175,7 +182,8 @@ bwb_init( argc, argv ) | |||
/* EXEC stack */ | |||
if ( ( excs = calloc( EXECLEVELS, sizeof( struct exse ) ) ) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( excs = CALLOC( EXECLEVELS, sizeof( struct exse ), "bwb_init") ) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in bwb_init(): failed to find memory for excs" ); | |||
@@ -197,8 +205,8 @@ bwb_init( argc, argv ) | |||
exsc = -1; | |||
expsc = 0; | |||
xtxtsc = 0; | |||
bwb_start.position = 1; | |||
bwb_l = &bwb_start; | |||
bwb_start.position = 0; | |||
bwb_l = &bwb_start; | |||
var_init( 0 ); | |||
fnc_init( 0 ); | |||
@@ -208,7 +216,8 @@ bwb_init( argc, argv ) | |||
/* character buffers */ | |||
if ( ( bwb_ebuf = calloc( MAXSTRINGSIZE + 1, sizeof(char) ) ) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( bwb_ebuf = CALLOC( MAXSTRINGSIZE + 1, sizeof(char), "bwb_init") ) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in bwb_init(): failed to find memory for bwb_ebuf" ); | |||
@@ -216,7 +225,8 @@ bwb_init( argc, argv ) | |||
bwb_error( err_getmem ); | |||
#endif | |||
} | |||
if ( ( read_line = calloc( MAXREADLINESIZE + 1, sizeof(char) ) ) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( read_line = CALLOC( MAXREADLINESIZE + 1, sizeof(char), "bwb_init") ) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in bwb_init(): failed to find memory for read_line" ); | |||
@@ -248,7 +258,8 @@ bwb_init( argc, argv ) | |||
/* assign memory for the device table */ | |||
#if COMMON_CMDS | |||
if ( ( dev_table = calloc( DEF_DEVICES, sizeof( struct dev_element ) ) ) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( dev_table = CALLOC( DEF_DEVICES, sizeof( struct dev_element ), "bwb_init") ) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in bwb_init(): failed to find memory for dev_table" ); | |||
@@ -399,9 +410,9 @@ bwb_init( argc, argv ) | |||
++program_run; | |||
if (( argc > 1 ) && ( program_run == 1 )) | |||
{ | |||
if ( ( input = fopen( argv[ 1 ], "r" )) == NULL ) | |||
strcpy( CURTASK progfile, argv[ 1 ] ); /* JBV */ | |||
if ( ( input = fopen( CURTASK progfile, "r" )) == NULL ) /* JBV */ | |||
{ | |||
strcpy( CURTASK progfile, argv[ 1 ] ); | |||
strcat( CURTASK progfile, ".bas" ); | |||
if ( ( input = fopen( CURTASK progfile, "r" )) == NULL ) | |||
{ | |||
@@ -412,7 +423,7 @@ bwb_init( argc, argv ) | |||
} | |||
if ( input != NULL ) | |||
{ | |||
strcpy( CURTASK progfile, argv[ 1 ] ); | |||
/* strcpy( CURTASK progfile, argv[ 1 ] ); */ /* Removed by JBV */ | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in main(): progfile is <%s>.", CURTASK progfile ); | |||
bwb_debug( bwb_ebuf ); | |||
@@ -442,6 +453,7 @@ bwb_interact( void ) | |||
bwb_interact() | |||
#endif | |||
{ | |||
char tbuf[ MAXSTRINGSIZE + 1 ]; /* JBV */ | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_interact(): ready to read from keyboard" ); | |||
@@ -451,6 +463,7 @@ bwb_interact() | |||
/* take input from keyboard */ | |||
bwb_gets( read_line ); | |||
bwb_stripcr( read_line ); /* JBV */ | |||
/* If there is no line number, execute the line as received */ | |||
@@ -459,6 +472,17 @@ bwb_interact() | |||
bwb_xtxtline( read_line ); | |||
} | |||
/*-----------------------------------------------------------------*/ | |||
/* Another possibility: if read_line is a numeric constant, delete */ | |||
/* the indicated line number (JBV) */ | |||
/*-----------------------------------------------------------------*/ | |||
else if ( is_numconst( read_line ) == TRUE ) | |||
{ | |||
strcpy(tbuf, read_line); | |||
sprintf(read_line, "delete %s\0", tbuf); | |||
bwb_xtxtline( read_line ); | |||
} | |||
/* If there is a line number, add the line to the file in memory */ | |||
else | |||
@@ -553,7 +577,9 @@ bwb_ladd( buffer, replace ) | |||
if ( init == FALSE ) | |||
{ | |||
init = TRUE; | |||
if ( ( s_buffer = calloc( (size_t) MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( s_buffer = CALLOC( (size_t) MAXSTRINGSIZE + 1, sizeof( char ), "bwb_ladd" )) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in bwb_ladd(): failed to find memory for s_buffer" ); | |||
@@ -571,7 +597,8 @@ bwb_ladd( buffer, replace ) | |||
/* get memory for this line */ | |||
if ( ( l = (struct bwb_line *) calloc( (size_t) 1, sizeof( struct bwb_line ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( l = (struct bwb_line *) CALLOC( (size_t) 1, sizeof( struct bwb_line ), "bwb_ladd")) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in bwb_ladd(): failed to find memory for new line" ); | |||
@@ -648,7 +675,7 @@ bwb_ladd( buffer, replace ) | |||
/* replace a previously existing line */ | |||
if ( ( l->xnum == TRUE ) | |||
if ( ( l->xnum == (char) TRUE ) /* Better recast this one (JBV) */ | |||
&& ( previous->number == l->number ) | |||
&& ( replace == TRUE ) | |||
) | |||
@@ -666,7 +693,10 @@ bwb_ladd( buffer, replace ) | |||
/* free the current line */ | |||
free( l ); | |||
/* Revised to FREE pass-thru calls by JBV */ | |||
/* if (l->buffer != NULL) FREE( l->buffer, "bwb_ladd" ); */ | |||
/* FREE( l, "bwb_ladd" ); */ | |||
bwb_freeline( l ); /* JBV */ | |||
/* and return */ | |||
@@ -724,8 +754,10 @@ bwb_ladd( buffer, replace ) | |||
/* attempt to link line number has failed; free memory */ | |||
free( l->buffer ); | |||
free( l ); | |||
/* Revised to FREE pass-thru calls by JBV */ | |||
/* if (l->buffer != NULL) FREE( l->buffer, "bwb_ladd" ); */ | |||
/* FREE( l, "bwb_ladd" ); */ | |||
bwb_freeline( l ); /* JBV */ | |||
sprintf( bwb_ebuf, ERR_LINENO ); | |||
bwb_error( bwb_ebuf ); | |||
@@ -810,14 +842,16 @@ bwb_xtxtline( buffer ) | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
if ( CURTASK xtxts[ CURTASK xtxtsc ].l.buffer != NULL ) | |||
{ | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_xtxtline(): freeing buffer memory" ); | |||
bwb_debug( bwb_ebuf ); | |||
#endif | |||
free( CURTASK xtxts[ CURTASK xtxtsc ].l.buffer ); | |||
} | |||
/* Removed by JBV (no longer needed, done by ln_asbuf) */ | |||
/* if ( CURTASK xtxts[ CURTASK xtxtsc ].l.buffer != NULL ) | |||
{ */ | |||
/* #if INTENSIVE_DEBUG */ | |||
/* sprintf( bwb_ebuf, "in bwb_xtxtline(): freeing buffer memory" ); | |||
bwb_debug( bwb_ebuf ); */ | |||
/* #endif */ | |||
/* Revised to FREE pass-thru call by JBV */ | |||
/* FREE( CURTASK xtxts[ CURTASK xtxtsc ].l.buffer, "bwb_xtxtline" ); | |||
} */ | |||
/* copy the whole line to the line structure buffer */ | |||
@@ -938,8 +972,10 @@ bwb_decexec() | |||
if ( CURTASK excs[ CURTASK exsc ].code == EXEC_ON ) | |||
{ | |||
free( CURTASK excs[ CURTASK exsc ].while_line->buffer ); | |||
free( CURTASK excs[ CURTASK exsc ].while_line ); | |||
/* Revised to FREE pass-thru calls by JBV */ | |||
/* FREE( CURTASK excs[ CURTASK exsc ].while_line->buffer, "bwb_decexec" ); */ | |||
/* FREE( CURTASK excs[ CURTASK exsc ].while_line, "bwb_decexec" ); */ | |||
bwb_freeline( CURTASK excs[ CURTASK exsc ].while_line ); /* JBV */ | |||
bwb_decexec(); | |||
} | |||
@@ -1236,14 +1272,18 @@ ln_asbuf( l, s ) | |||
#endif | |||
{ | |||
#if DONTDOTHIS /* but why not? */ | |||
/* Reinstated by JBV */ | |||
/* #if DONTDOTHIS */ /* but why not? */ | |||
if ( l->buffer != NULL ) | |||
{ | |||
free( l->buffer ); | |||
/* Revised to FREE pass-thru call by JBV */ | |||
FREE( l->buffer, "ln_asbuf" ); | |||
l->buffer = NULL; /* JBV */ | |||
} | |||
#endif | |||
/* #endif */ | |||
if ( ( l->buffer = calloc( strlen( s ) + 2, sizeof( char ) ) ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( l->buffer = CALLOC( strlen( s ) + 2, sizeof( char ), "ln_asbuf") ) | |||
== NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
@@ -1341,7 +1381,9 @@ break_mes( x ) | |||
if ( init == FALSE ) | |||
{ | |||
init = TRUE; | |||
if ( ( tmp_buffer = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( tmp_buffer = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "break_mes")) == NULL ) | |||
{ | |||
#if PROG_ERRORS | |||
bwb_error( "in break_mes(): failed to find memory for tmp_buffer" ); | |||
@@ -1448,3 +1490,50 @@ is_ln( buffer ) | |||
} | |||
/*************************************************************** | |||
FUNCTION: CALLOC() | |||
DESCRIPTION: Pass-thru function to calloc() for debugging | |||
purposes. Added by JBV 10/95 | |||
***************************************************************/ | |||
void * | |||
#if ANSI_C | |||
CALLOC( size_t nelem, size_t elsize, char *str ) | |||
#else | |||
CALLOC( nelem, elsize, str ) | |||
size_t nelem; | |||
size_t elsize; | |||
char *str; | |||
#endif | |||
{ | |||
void *ptr; | |||
ptr = calloc(nelem, elsize); | |||
/* printf("%x %x\n", ptr, mallocblksize(ptr)); */ | |||
return ptr; | |||
} | |||
/*************************************************************** | |||
FUNCTION: FREE() | |||
DESCRIPTION: Pass-thru function to free() for debugging | |||
purposes. Added by JBV 10/95 | |||
***************************************************************/ | |||
void | |||
#if ANSI_C | |||
FREE( void *ptr, char *str ) | |||
#else | |||
FREE( ptr, str ) | |||
void *ptr; | |||
char *str; | |||
#endif | |||
{ | |||
/* printf("%x\n", ptr); */ | |||
free(ptr); | |||
} |
@@ -271,27 +271,27 @@ CONTENTS: | |||
bwBASIC recognizes the following operators, with their level | |||
of precedence given (1 = highest): | |||
^ 1 exponentiation | |||
* 2 multiplication | |||
/ 2 division | |||
\ 3 integer division | |||
+ 5 addition | |||
- 5 subtraction | |||
= 6 equality or assignment | |||
MOD 4 modulus (remainder) arithmetic | |||
<> 7 inequality | |||
< 8 less than | |||
> 9 greater than | |||
<= 10 less than or equal to | |||
=< 10 less than or equal to | |||
>= 11 greater than or equal to | |||
=> 11 greater than or equal to | |||
NOT 12 negation | |||
AND 13 conjunction | |||
OR 14 disjunction | |||
XOR 15 exclusive or | |||
IMP 16 implication | |||
EQV 17 equivalence | |||
^ 1 exponentiation | |||
* 2 multiplication | |||
/ 2 division | |||
\ 3 integer division | |||
+ 5 addition | |||
- 5 subtraction | |||
= 6 equality or assignment | |||
MOD 4 modulus (remainder) arithmetic | |||
<> 7 inequality | |||
< 8 less than | |||
> 9 greater than | |||
<= 10 less than or equal to | |||
=< 10 less than or equal to | |||
>= 11 greater than or equal to | |||
=> 11 greater than or equal to | |||
NOT 12 negation | |||
AND 13 conjunction | |||
OR 14 disjunction | |||
XOR 15 exclusive or | |||
IMP 16 implication | |||
EQV 17 equivalence | |||
4.h. Numerical Precision (NOT) | |||
@@ -312,30 +312,30 @@ CONTENTS: | |||
associated command or function to be implemented. These flags | |||
are as follows: | |||
(core) Commands and Functions in any implementation of | |||
bwBASIC; these are the ANSI Minimal BASIC core | |||
(core) Commands and Functions in any implementation of | |||
bwBASIC; these are the ANSI Minimal BASIC core | |||
INTERACTIVE Commands supporting the interactive programming | |||
environment | |||
INTERACTIVE Commands supporting the interactive programming | |||
environment | |||
COMMON_CMDS Commands beyond ANSI Minimal BASIC which are common | |||
to Full ANSI BASIC and Microsoft BASICs | |||
COMMON_CMDS Commands beyond ANSI Minimal BASIC which are common | |||
to Full ANSI BASIC and Microsoft BASICs | |||
COMMON_FUNCS Functions beyond the ANSI Mimimal BASIC core, but | |||
common to both ANSI Full BASIC and Microsoft-style | |||
BASIC varieties | |||
COMMON_FUNCS Functions beyond the ANSI Mimimal BASIC core, but | |||
common to both ANSI Full BASIC and Microsoft-style | |||
BASIC varieties | |||
UNIX_CMDS Commands which require Unix-style directory and | |||
environment routines not specified in C | |||
UNIX_CMDS Commands which require Unix-style directory and | |||
environment routines not specified in C | |||
STRUCT_CMDS Commands related to structured programming; all | |||
of these are part of the Full ANSI BASIC standard | |||
STRUCT_CMDS Commands related to structured programming; all | |||
of these are part of the Full ANSI BASIC standard | |||
ANSI_FUNCS Functions unique to ANSI Full BASIC | |||
ANSI_FUNCS Functions unique to ANSI Full BASIC | |||
MS_CMDS Commands unique to Microsoft BASICs | |||
MS_CMDS Commands unique to Microsoft BASICs | |||
MS_FUNCS Functions unique to Microsoft BASICs | |||
MS_FUNCS Functions unique to Microsoft BASICs | |||
------------------------------------------ | |||
@@ -379,7 +379,7 @@ CONTENTS: | |||
Description: CASE introduces an element of a SELECT CASE statement | |||
(see SELECT CASE). CASE IF introduces a conditional | |||
SELECT CASE element, and CASE ELSE introduces a | |||
default SELECT CASE element. | |||
default SELECT CASE element. | |||
Dependencies: STRUCT_CMDS | |||
@@ -548,8 +548,8 @@ CONTENTS: | |||
As implemented under bwBASIC, DATE$ cannot be used for | |||
assignment (i.e., to set the system date). | |||
Note: bwBASIC presently (v2.10) does not allow assignment | |||
to a function. | |||
Note: bwBASIC presently (v2.10) does not allow assignment | |||
to a function. | |||
Dependencies: COMMON_FUNCS | |||
@@ -783,7 +783,7 @@ CONTENTS: | |||
Command: EXIT [FOR] | |||
Description: EXIT by itself exits from a DO...LOOP loop; | |||
EXIT FOR exits from a FOR...NEXT loop. | |||
EXIT FOR exits from a FOR...NEXT loop. | |||
Dependencies: STRUCT_CMDS | |||
@@ -913,9 +913,9 @@ CONTENTS: | |||
Function: INKEY$ | |||
Description: INKEY$ reads the status of the keyboard, and a single | |||
keypress, if available. If a keypress is not available, | |||
then INKEY$ immediately returns a null string (""). | |||
Currently (v2.10) implemented in bwx_iqc.c only. | |||
keypress, if available. If a keypress is not available, | |||
then INKEY$ immediately returns a null string (""). | |||
Currently (v2.10) implemented in bwx_iqc.c only. | |||
Dependencies: IMP_IQC and IMP_CMDLOC | |||
@@ -944,8 +944,8 @@ CONTENTS: | |||
As implemented in bwBASIC, INSTR cannot be used for | |||
assignments. | |||
Note: bwBASIC presently (v2.10) does not allow assignment | |||
to a function. | |||
Note: bwBASIC presently (v2.10) does not allow assignment | |||
to a function. | |||
Dependencies: MS_FUNCS | |||
@@ -1039,7 +1039,7 @@ CONTENTS: | |||
Command: LOCATE line, column | |||
Description: LOCATE addresses trhe curor to a specified line and | |||
column. Currently (v2.10) implemented in bwx_iqc.c only. | |||
column. Currently (v2.10) implemented in bwx_iqc.c only. | |||
Dependencies: IMP_IQC and IMP_CMDLOC | |||
@@ -1237,29 +1237,29 @@ CONTENTS: | |||
a number of formatting marks may appear in the format | |||
string: | |||
! prints the first character of a string | |||
! prints the first character of a string | |||
\\ prints 2+x characters of a string, where x = | |||
\\ prints 2+x characters of a string, where x = | |||
the number of spaces between the backslashes | |||
& variable-length string field | |||
& variable-length string field | |||
# represents a single digit in output format for | |||
a number | |||
# represents a single digit in output format for | |||
a number | |||
. decimal point in a number | |||
. decimal point in a number | |||
+ sign of a number (will output + or -) | |||
+ sign of a number (will output + or -) | |||
- trailing minus after a number | |||
- trailing minus after a number | |||
** fill leading spaces with asterisks | |||
** fill leading spaces with asterisks | |||
$$ output dollar sign in front of a number | |||
$$ output dollar sign in front of a number | |||
^^ output number in exponential format | |||
^^ output number in exponential format | |||
_ output next character literally | |||
_ output next character literally | |||
As currently implemented, the exponential format | |||
will be that used by the C compiler. | |||
@@ -1281,8 +1281,8 @@ CONTENTS: | |||
Command: QUIT | |||
Description: QUIT is a synonym for SYSTEM; with INTERACTIVE | |||
environment, it exits the program to the | |||
operating system (or the calling program). | |||
environment, it exits the program to the | |||
operating system (or the calling program). | |||
Dependencies: INTERACTIVE | |||
@@ -1542,8 +1542,8 @@ CONTENTS: | |||
As implemented under bwBASIC, TIME$ cannot be used for | |||
assignment (i.e., to set the system time). | |||
Note: bwBASIC presently (v2.10) does not allow assignment | |||
to a function. | |||
Note: bwBASIC presently (v2.10) does not allow assignment | |||
to a function. | |||
Dependencies: COMMON_FUNCS | |||
@@ -1677,107 +1677,107 @@ CONTENTS: | |||
ting-system-specific functions or terminal-specific functions | |||
that cannot be universally provided. Some specific examples: | |||
CLOAD Relies on CP/M or MSDOS conventions for binary | |||
CLOAD Relies on CP/M or MSDOS conventions for binary | |||
executable files. | |||
CONT See RESUME below (programmer ignorance?). | |||
CONT See RESUME below (programmer ignorance?). | |||
DEF USR Relies on CP/M or MSDOS conventions for binary | |||
DEF USR Relies on CP/M or MSDOS conventions for binary | |||
executable files. | |||
FRE() The ability to report the amount of free memory | |||
remaining is system-specific due to varying patterns | |||
of memory allocation and access; consequently this | |||
ability is not present in ANSI or earlier versions | |||
FRE() The ability to report the amount of free memory | |||
remaining is system-specific due to varying patterns | |||
of memory allocation and access; consequently this | |||
ability is not present in ANSI or earlier versions | |||
of C and this function is not available in bwBASIC. | |||
INPUT$() C by itself is not able to read unechoed keyboard | |||
input, and can read keyboard input only after a | |||
Carriage-Return has been entered. | |||
INPUT$() C by itself is not able to read unechoed keyboard | |||
input, and can read keyboard input only after a | |||
Carriage-Return has been entered. | |||
INP Calls to hardware ports, like machine-language | |||
routines, are highly system-specific and cannot | |||
be implemented in C alone. | |||
INP Calls to hardware ports, like machine-language | |||
routines, are highly system-specific and cannot | |||
be implemented in C alone. | |||
LLIST See LPRINT below. | |||
LLIST See LPRINT below. | |||
LPOS See LPRINT below. | |||
LPOS See LPRINT below. | |||
LPRINT and LLIST, etc., require access to a printer device, | |||
and this varies from one system to another. Users | |||
might try OPENing the printer device on their own | |||
operating system (e.g., "/dev/lp" on Unix systems, | |||
or "PRN" under DOS) and see if printing can be done | |||
from bwBASIC in this way. | |||
LPRINT and LLIST, etc., require access to a printer device, | |||
and this varies from one system to another. Users | |||
might try OPENing the printer device on their own | |||
operating system (e.g., "/dev/lp" on Unix systems, | |||
or "PRN" under DOS) and see if printing can be done | |||
from bwBASIC in this way. | |||
NULL In this case, I am convinced that NULL is no longer | |||
necessary, since very few printers now require NULLs | |||
at the end of lines. | |||
NULL In this case, I am convinced that NULL is no longer | |||
necessary, since very few printers now require NULLs | |||
at the end of lines. | |||
OUT See INP above (calls to hardware ports). | |||
OUT See INP above (calls to hardware ports). | |||
PEEK() PEEK and POKE enabled earlier BASICs to address | |||
particular memory locations. Although bwBASIC | |||
could possibly implement this command (POKE) and | |||
this function (PEEK()), the limitation would be | |||
highly limited by the different systems for | |||
memory access in different systems. | |||
PEEK() PEEK and POKE enabled earlier BASICs to address | |||
particular memory locations. Although bwBASIC | |||
could possibly implement this command (POKE) and | |||
this function (PEEK()), the limitation would be | |||
highly limited by the different systems for | |||
memory access in different systems. | |||
POKE see PEEK() above. | |||
POKE see PEEK() above. | |||
RENUM Since unnumbered lines can be entered and | |||
executed under bwBASIC, it would not be | |||
possible to implement a RENUM routine. | |||
Instead, bwBASIC uses DO NUM and DO UNNUM. | |||
RENUM Since unnumbered lines can be entered and | |||
executed under bwBASIC, it would not be | |||
possible to implement a RENUM routine. | |||
Instead, bwBASIC uses DO NUM and DO UNNUM. | |||
RESUME Is this possible under C? If so, I | |||
simply have failed to figure it out yet. | |||
Mea culpa (but not maxima). | |||
RESUME Is this possible under C? If so, I | |||
simply have failed to figure it out yet. | |||
Mea culpa (but not maxima). | |||
USR See CALL and DEF USR above (machine language | |||
subroutines). | |||
USR See CALL and DEF USR above (machine language | |||
subroutines). | |||
VARPTR See PEEK and POKE above. | |||
VARPTR See PEEK and POKE above. | |||
WAIT See INP and OUT above. | |||
WAIT See INP and OUT above. | |||
There are other commands, functions, and implementation details | |||
that I am working on, and which are on the agenda list for future | |||
versions of bwBASIC. These agenda include: | |||
PARACT i.e., the ability to execute PARallel ACTions. This | |||
is described in ANSI BASIC, although I have not seen it | |||
implemented before. It will offer a rough, non- | |||
preemptive form of multitasking within the scope | |||
of a BASIC program. Programmers will note points at which | |||
there are already hooks for PARACT in bwBASIC. | |||
XMEM PC-type computers need to be able to use extended | |||
memory. If we could use extended memory for program | |||
lines, variables, and function defitions, we could | |||
write much longer programs. This would entail, | |||
however, a fairly serious rewriting of the program | |||
to utilize memory handles for these storage features | |||
instead of direct memory pointers. | |||
Windows The addition of memory handles in addition to the | |||
non-preemptive execution of program lines (in a | |||
crude form, already present) will make it possible | |||
to develop implementations for Windows and perhaps | |||
for other graphical user interfaces. But what form | |||
should this take? I have in mind presently a BASIC | |||
that would run in the background, appearing only | |||
as an icon in the GUI space, with pop-up editors | |||
and output windows. Thus, the interpreted language | |||
would serve a purpose something like 'cron' (a task | |||
scheduler) under Unix systems. You may have some | |||
reflections that would help me in this. | |||
Graphics Here we face fairly critical differences in different | |||
styles and implementations of graphics, e.g., between | |||
GWBASIC, ANSI BASIC, VisualBASIC, etc. But it's | |||
possible that Graphics commands and functions could | |||
be added. These would all be implementation-specific. | |||
PARACT i.e., the ability to execute PARallel ACTions. This | |||
is described in ANSI BASIC, although I have not seen it | |||
implemented before. It will offer a rough, non- | |||
preemptive form of multitasking within the scope | |||
of a BASIC program. Programmers will note points at which | |||
there are already hooks for PARACT in bwBASIC. | |||
XMEM PC-type computers need to be able to use extended | |||
memory. If we could use extended memory for program | |||
lines, variables, and function defitions, we could | |||
write much longer programs. This would entail, | |||
however, a fairly serious rewriting of the program | |||
to utilize memory handles for these storage features | |||
instead of direct memory pointers. | |||
Windows The addition of memory handles in addition to the | |||
non-preemptive execution of program lines (in a | |||
crude form, already present) will make it possible | |||
to develop implementations for Windows and perhaps | |||
for other graphical user interfaces. But what form | |||
should this take? I have in mind presently a BASIC | |||
that would run in the background, appearing only | |||
as an icon in the GUI space, with pop-up editors | |||
and output windows. Thus, the interpreted language | |||
would serve a purpose something like 'cron' (a task | |||
scheduler) under Unix systems. You may have some | |||
reflections that would help me in this. | |||
Graphics Here we face fairly critical differences in different | |||
styles and implementations of graphics, e.g., between | |||
GWBASIC, ANSI BASIC, VisualBASIC, etc. But it's | |||
possible that Graphics commands and functions could | |||
be added. These would all be implementation-specific. | |||
The ANSI Standard for full BASIC does not specify which particular | |||
commands or functions must be implemented, and in fact the standard | |||
@@ -1878,3 +1878,4 @@ CONTENTS: | |||
9. COMMUNICATIONS: | |||
email: tcamp@delphi.com | |||
@@ -23,6 +23,10 @@ | |||
***************************************************************/ | |||
/*---------------------------------------------------------------*/ | |||
/* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */ | |||
/* 11/1995 (eidetics@cerf.net). */ | |||
/*---------------------------------------------------------------*/ | |||
#ifndef TRUE | |||
#define TRUE -1 | |||
@@ -37,7 +41,7 @@ | |||
/* Version number */ | |||
#define VERSION "2.10" /* Current version number */ | |||
#define VERSION "2.20" /* Current version number */ | |||
/*************************************************************** | |||
@@ -50,10 +54,14 @@ | |||
It is the most minimal, but the most | |||
universal hardware implementation. | |||
If you pick IMP_TTY then check the settings | |||
in bwx_tty.h for your system. | |||
***************************************************************/ | |||
#define IMP_TTY TRUE /* simple TTY-style interface using stdio */ | |||
#define IMP_IQC FALSE /* IBM PC, Microsoft QuickC Compiler */ | |||
#define ALLOW_RENUM TRUE /* Added by JBV */ | |||
#if IMP_TTY | |||
#include "bwx_tty.h" | |||
@@ -109,6 +117,11 @@ | |||
#define HAVE_STDLIB FALSE /* Compiler has <stdlib.h> header */ | |||
#endif | |||
/* configure sets this (section added by JBV) */ | |||
#ifndef HAVE_UNISTD | |||
#define HAVE_UNISTD FALSE /* Compiler has <unistd.h> header */ | |||
#endif | |||
#ifdef __STDC__ | |||
#define HAVE_SYSTYPES TRUE | |||
#else | |||
@@ -149,8 +162,8 @@ | |||
#if CFG_CUSTOM | |||
#define COMMAND_SHELL TRUE /* allow command shell processing */ | |||
#define PROFILE FALSE /* interpret profile at beginning */ | |||
#define NUMBER_DOUBLE FALSE /* define BASIC number as double: default is float*/ | |||
#define PROFILE TRUE /* interpret profile at beginning */ | |||
#define NUMBER_DOUBLE TRUE /* define BASIC number as double: default is float*/ | |||
#define MULTISEG_LINES TRUE /* allow multi-segment lines delimited by ':' */ | |||
#define PARACT FALSE /* Implement PARallen ACTion (Multi-tasking) interpreter */ | |||
#define INTERACTIVE TRUE /* interactive programming environment and related commands */ | |||
@@ -191,10 +204,13 @@ | |||
You can specify debugging options here. | |||
Defining DEBUG true provides some useful commands: | |||
CMDS, VARS, FNCS | |||
***************************************************************/ | |||
#define DEBUG FALSE /* current debugging */ | |||
#define PROG_ERRORS FALSE /* identify serious programming errors */ | |||
#define DEBUG FALSE /* current debugging */ | |||
#define PROG_ERRORS FALSE /* identify serious programming errors */ | |||
/* and print extensive error messages */ | |||
/* This will override messages defined in */ | |||
/* bwb_mes.h, and almost all messages will be in English */ | |||
@@ -212,7 +228,11 @@ | |||
bwbasic.h: This ends the section of definitions that | |||
users of bwBASIC will normally need to | |||
specify. The following are internally defined | |||
specify. The following are internally defined. | |||
Note that you may need to set up the default | |||
FILES command and the default editor below. | |||
See Part I-G | |||
***************************************************************/ | |||
@@ -297,6 +317,11 @@ | |||
#include <stdlib.h> | |||
#endif | |||
/* Section added by JBV */ | |||
#if HAVE_UNISTD | |||
#include <unistd.h> | |||
#endif | |||
#if HAVE_SYSTYPES | |||
#include <sys/types.h> | |||
#endif | |||
@@ -319,7 +344,7 @@ | |||
#define CMDS_DIR 0 | |||
#endif | |||
#if COMMON_CMDS | |||
#define CMDS_COMMON 24 | |||
#define CMDS_COMMON 25 /* Was 24 (JBV) */ | |||
#else | |||
#define CMDS_COMMON 0 | |||
#endif | |||
@@ -376,9 +401,22 @@ | |||
/* ERROR: MULTISEG_LINES and STRUCT_CMDS cannot be defined together! */ | |||
#endif | |||
#define DEF_EDITOR "" /* default editor */ | |||
#define DEF_FILES "" /* default "files" command */ | |||
#define DEF_COLORS 0 /* default # of colors */ | |||
/*************************************************************** | |||
bwbasic.h: Part I-G: Define User Defaults | |||
Defining your default editor and files commands | |||
is a good idea. You must supply the file name | |||
for the editor to use. These defaults can be | |||
changed from inside the program or in your profile | |||
program by setting the appropriate variables | |||
shown below. | |||
***************************************************************/ | |||
#define DEF_EDITOR "vi" /* default editor */ | |||
#define DEF_FILES "ls -Fx" /* default "files" command */ | |||
#define DEF_COLORS 256 /* default # of colors */ | |||
#define DEFVNAME_EDITOR "BWB.EDITOR$" /* default variable name for EDITOR */ | |||
#define DEFVNAME_PROMPT "BWB.PROMPT$" /* default variable name for PROMPT */ | |||
#define DEFVNAME_FILES "BWB.FILES$" /* default variable name for FILES */ | |||
@@ -400,9 +438,9 @@ | |||
#define MAX_DIMS 64 /* maximum # of dimensions */ | |||
#define ESTACKSIZE 64 /* elements in expression stack */ | |||
#define XTXTSTACKSIZE 16 /* elements in eXecute TeXT stack */ | |||
#define N_OPERATORS 24 /* number of operators defined */ | |||
#define N_OPERATORS 25 /* number of operators defined */ | |||
#define N_ERRORS 25 /* number of errors defined */ | |||
#define MAX_PRECEDENCE 19 /* highest (last) level of precedence */ | |||
#define MAX_PRECEDENCE 20 /* highest (last) level of precedence */ | |||
#define MININTSIZE -32767 /* minimum integer size */ | |||
#define MAXINTSIZE 32767 /* maximum integer size */ | |||
#define DEF_SUBSCRIPT 11 /* default subscript */ | |||
@@ -622,6 +660,7 @@ struct dev_element | |||
int reclen; /* record length for random access */ | |||
int next_record; /* next record to read/write */ | |||
int loc; /* location in file */ | |||
int lof; /* length of file in bytes (JBV) */ | |||
char filename[ MAXFILENAMESIZE + 1 ];/* filename */ | |||
FILE *cfp; /* C file pointer for this device */ | |||
char *buffer; /* pointer to character buffer for random access */ | |||
@@ -783,6 +822,8 @@ extern struct bwb_op exp_ops[ N_OPERATORS ]; /* the table itself, filled in in b | |||
***************************************************************/ | |||
#if ANSI_C | |||
extern void *CALLOC(size_t nelem, size_t elsize, char *str); /* JBV */ | |||
extern void FREE(void *ptr, char *str); /* JBV */ | |||
extern void bwb_init( int argc, char **argv ); | |||
extern int bwb_fload( FILE *file ); | |||
extern int bwb_ladd( char *buffer, int replace ); | |||
@@ -853,6 +894,7 @@ extern struct bwb_line *bwb_ddbl( struct bwb_line *l ); | |||
extern struct bwb_line *bwb_dint( struct bwb_line *l ); | |||
extern struct bwb_line *bwb_dsng( struct bwb_line *l ); | |||
extern struct bwb_line *bwb_dstr( struct bwb_line *l ); | |||
extern struct bwb_line *bwb_mid( struct bwb_line *l ); | |||
extern struct bwb_line *bwb_clear( struct bwb_line *l ); | |||
extern struct bwb_line *bwb_erase( struct bwb_line *l ); | |||
extern struct bwb_line *bwb_swap( struct bwb_line *l ); | |||
@@ -941,6 +983,7 @@ extern int prn_precision( struct bwb_variable *v ); | |||
extern int * prn_getcol( FILE *f ); | |||
extern int prn_getwidth( FILE *f ); | |||
extern int prn_xprintf( FILE *f, char *buffer ); | |||
extern int prn_xxprintf( FILE *f, char *buffer ); /* JBV */ | |||
extern int bwb_strtoupper( char *buffer ); | |||
extern int getcmdnum( char *cmdstr ); | |||
@@ -1008,12 +1051,16 @@ extern struct bwb_line *bwb_renum( struct bwb_line *l ); | |||
#endif | |||
#if UNIX_CMDS | |||
#if !HAVE_UNISTD /* Not needed if one has <unistd.h> (JBV) */ | |||
extern int rmdir( char *path ); | |||
extern int chdir( char *path ); | |||
#endif | |||
#if !HAVE_SYSSTAT /* Not needed if one has <sys/stat.h> (JBV) */ | |||
#if MKDIR_ONE_ARG | |||
extern int mkdir( char *path ); | |||
#else | |||
extern int mkdir( char *path, unsigned short permissions ); | |||
#endif /* JBV */ | |||
#endif | |||
#endif | |||
@@ -1081,6 +1128,8 @@ extern struct bwb_variable *fnc_test( int argc, struct bwb_variable *argv, int u | |||
#else /* ANSI_C */ | |||
extern void *CALLOC(); /* JBV */ | |||
extern void FREE(); /* JBV */ | |||
extern void bwb_init(); | |||
extern int bwb_fload(); | |||
extern int bwb_ladd(); | |||
@@ -1151,6 +1200,7 @@ extern struct bwb_line *bwb_ddbl(); | |||
extern struct bwb_line *bwb_dint(); | |||
extern struct bwb_line *bwb_dsng(); | |||
extern struct bwb_line *bwb_dstr(); | |||
extern struct bwb_line *bwb_mid(); | |||
extern struct bwb_line *bwb_clear(); | |||
extern struct bwb_line *bwb_erase(); | |||
extern struct bwb_line *bwb_swap(); | |||
@@ -1238,6 +1288,7 @@ extern int prn_precision(); | |||
extern int * prn_getcol(); | |||
extern int prn_getwidth(); | |||
extern int prn_xprintf(); | |||
extern int prn_xxprintf(); /* JBV */ | |||
extern int bwb_strtoupper(); | |||
extern int getcmdnum(); | |||
@@ -14,4 +14,3 @@ | |||
230 print | |||
240 next i | |||
250 end | |||
@@ -25,6 +25,14 @@ | |||
***************************************************************/ | |||
/*---------------------------------------------------------------*/ | |||
/* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */ | |||
/* 11/1995 (eidetics@cerf.net). */ | |||
/* */ | |||
/* Those additionally marked with "DD" were at the suggestion of */ | |||
/* Dale DePriest (daled@cadence.com). */ | |||
/*---------------------------------------------------------------*/ | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <setjmp.h> | |||
@@ -303,7 +311,9 @@ bwx_shell( struct bwb_line *l ) | |||
if ( init == FALSE ) | |||
{ | |||
init = TRUE; | |||
if ( ( s_buffer = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( s_buffer = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
{ | |||
bwb_error( err_getmem ); | |||
return FALSE; | |||
@@ -425,9 +435,63 @@ bwb_edit( struct bwb_line *l ) | |||
system( tbuf ); | |||
#endif | |||
/* open edited file for read */ | |||
if ( ( loadfile = fopen( CURTASK progfile, "r" )) == NULL ) | |||
{ | |||
sprintf( bwb_ebuf, err_openfile, CURTASK progfile ); | |||
bwb_error( bwb_ebuf ); | |||
iqc_setpos(); | |||
return bwb_zline( l ); | |||
} | |||
/* clear current contents */ | |||
bwb_new( l ); | |||
bwb_new( l ); /* Relocated by JBV (bug found by DD) */ | |||
/* and (re)load the file into memory */ | |||
bwb_fload( loadfile ); | |||
iqc_setpos(); | |||
return bwb_zline( l ); | |||
} | |||
/*************************************************************** | |||
FUNCTION: bwb_renum() | |||
DESCRIPTION: This function implements the BASIC RENUM | |||
command by shelling out to a default | |||
renumbering program called "renum". | |||
Added by JBV 10/95 | |||
SYNTAX: RENUM | |||
***************************************************************/ | |||
#if ANSI_C | |||
struct bwb_line * | |||
bwb_renum( struct bwb_line *l ) | |||
#else | |||
struct bwb_line * | |||
bwb_renum( l ) | |||
struct bwb_line *l; | |||
#endif | |||
{ | |||
char tbuf[ MAXSTRINGSIZE + 1 ]; | |||
FILE *loadfile; | |||
sprintf( tbuf, "renum %s\0", CURTASK progfile ); | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_renum(): command line <%s>", tbuf ); | |||
bwb_debug( bwb_ebuf ); | |||
#else | |||
system( tbuf ); | |||
#endif | |||
/* open edited file for read */ | |||
@@ -440,6 +504,10 @@ bwb_edit( struct bwb_line *l ) | |||
return bwb_zline( l ); | |||
} | |||
/* clear current contents */ | |||
bwb_new( l ); /* Relocated by JBV (bug found by DD) */ | |||
/* and (re)load the file into memory */ | |||
bwb_fload( loadfile ); | |||
@@ -530,7 +598,7 @@ fnc_inkey( int argc, struct bwb_variable *argv ) | |||
if ( init == FALSE ) | |||
{ | |||
init = TRUE; | |||
var_make( &nvar, STRING ); | |||
var_make( &nvar, STRING, "fnc_inkey" ); | |||
} | |||
/* check arguments */ | |||
@@ -37,4 +37,3 @@ | |||
#define MKDIR_ONE_ARG TRUE /* TRUE if your mkdir has but one argument; | |||
FALSE if it has two */ | |||
#define PERMISSIONS 493 /* permissions to set in Unix-type system */ | |||
@@ -28,17 +28,25 @@ | |||
***************************************************************/ | |||
/*---------------------------------------------------------------*/ | |||
/* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */ | |||
/* 11/1995 (eidetics@cerf.net). */ | |||
/* */ | |||
/* Those additionally marked with "DD" were at the suggestion of */ | |||
/* Dale DePriest (daled@cadence.com). */ | |||
/*---------------------------------------------------------------*/ | |||
#include <stdio.h> | |||
#include "bwbasic.h" | |||
#include "bwb_mes.h" | |||
#if HAVE_LONGJMP | |||
#if HAVE_LONGJUMP /* Revised by JBV (bug found by DD) */ | |||
#include <setjmp.h> | |||
#endif | |||
extern int prn_col; | |||
#if HAVE_LONGJMP | |||
#if HAVE_LONGJUMP /* Revised by JBV (bug found by DD) */ | |||
extern jmp_buf mark; | |||
#endif | |||
@@ -69,7 +77,7 @@ main( argc, argv ) | |||
bwb_init( argc, argv ); | |||
#if HAVE_LONGJMP | |||
#if HAVE_LONGJUMP /* Revised by JBV (bug found by DD) */ | |||
#if INTERACTIVE | |||
setjmp( mark ); | |||
#endif | |||
@@ -82,7 +90,8 @@ main( argc, argv ) | |||
bwb_mainloop(); | |||
} | |||
bwx_terminate(); /* in case of ^D exit in Unix systems */ | |||
bwx_terminate(); /* allow ^D (Unix) exit with grace */ | |||
} | |||
@@ -267,9 +276,6 @@ void | |||
bwx_terminate() | |||
#endif | |||
{ | |||
#if INTENSIVE_DEBUG | |||
fprintf( stderr, "Normal Termination\n" ); | |||
#endif | |||
exit( 0 ); | |||
} | |||
@@ -301,7 +307,9 @@ bwx_shell( l ) | |||
if ( init == FALSE ) | |||
{ | |||
init = TRUE; | |||
if ( ( s_buffer = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL ) | |||
/* Revised to CALLOC pass-thru call by JBV */ | |||
if ( ( s_buffer = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "bwx_shell" )) == NULL ) | |||
{ | |||
bwb_error( err_getmem ); | |||
return FALSE; | |||
@@ -425,9 +433,61 @@ bwb_edit( l ) | |||
system( tbuf ); | |||
#endif | |||
/* open edited file for read */ | |||
if ( ( loadfile = fopen( CURTASK progfile, "r" )) == NULL ) | |||
{ | |||
sprintf( bwb_ebuf, err_openfile, CURTASK progfile ); | |||
bwb_error( bwb_ebuf ); | |||
return bwb_zline( l ); | |||
} | |||
/* clear current contents */ | |||
bwb_new( l ); | |||
bwb_new( l ); /* Relocated by JBV (bug found by DD) */ | |||
/* and (re)load the file into memory */ | |||
bwb_fload( loadfile ); | |||
return bwb_zline( l ); | |||
} | |||
/*************************************************************** | |||
FUNCTION: bwb_renum() | |||
DESCRIPTION: This function implements the BASIC RENUM | |||
command by shelling out to a default | |||
renumbering program called "renum". | |||
Added by JBV 10/95 | |||
SYNTAX: RENUM | |||
***************************************************************/ | |||
#if ANSI_C | |||
struct bwb_line * | |||
bwb_renum( struct bwb_line *l ) | |||
#else | |||
struct bwb_line * | |||
bwb_renum( l ) | |||
struct bwb_line *l; | |||
#endif | |||
{ | |||
char tbuf[ MAXSTRINGSIZE + 1 ]; | |||
FILE *loadfile; | |||
sprintf( tbuf, "renum %s\0", CURTASK progfile ); | |||
#if INTENSIVE_DEBUG | |||
sprintf( bwb_ebuf, "in bwb_renum(): command line <%s>", tbuf ); | |||
bwb_debug( bwb_ebuf ); | |||
#else | |||
system( tbuf ); | |||
#endif | |||
/* open edited file for read */ | |||
@@ -439,6 +499,10 @@ bwb_edit( l ) | |||
return bwb_zline( l ); | |||
} | |||
/* clear current contents */ | |||
bwb_new( l ); /* Relocated by JBV (bug found by DD) */ | |||
/* and (re)load the file into memory */ | |||
bwb_fload( loadfile ); | |||
@@ -27,6 +27,11 @@ | |||
***************************************************************/ | |||
/*---------------------------------------------------------------*/ | |||
/* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */ | |||
/* 11/1995 (eidetics@cerf.net). */ | |||
/*---------------------------------------------------------------*/ | |||
#define IMP_IDSTRING "TTY" /* unique ID string for this implementation */ | |||
/* Definitions indicating which commands and functions are implemented */ | |||
@@ -36,8 +41,7 @@ | |||
#define IMP_CMDLOC 0 /* 0 if LOCATE is not implemented, 1 if it is */ | |||
#define IMP_CMDCOLOR 0 /* 0 if COLOR is not implemented, 1 if it is */ | |||
#define UNIX_CMDS FALSE | |||
#define UNIX_CMDS TRUE /* It better be for UNIX systems (JBV) */ | |||
#define MKDIR_ONE_ARG FALSE /* TRUE if your mkdir has but one argument; | |||
FALSE if it has two */ | |||
#define PERMISSIONS 493 /* permissions to set in Unix-type system */ | |||
#define PERMISSIONS 644 /* permissions to set in Unix-type system */ |
@@ -22,6 +22,10 @@ | |||
# Ignores all args except --srcdir, --prefix, --exec-prefix, --no-create, and | |||
# --with-PACKAGE unless this script has special code to handle it. | |||
##---------------------------------------------------------------## | |||
## NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, ## | |||
## 11/1995 (eidetics@cerf.net). ## | |||
##---------------------------------------------------------------## | |||
for arg | |||
do | |||
@@ -213,6 +217,17 @@ if test -z "$err"; then | |||
fi | |||
rm -f conftest* | |||
# unistd.h checking added by JBV | |||
echo checking for unistd.h | |||
cat > conftest.c <<EOF | |||
#include <unistd.h> | |||
EOF | |||
err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"` | |||
if test -z "$err"; then | |||
DEFS="$DEFS -DHAVE_UNISTD=1" | |||
fi | |||
rm -f conftest* | |||
echo checking for raise | |||
cat > conftest.c <<EOF | |||
#include <sys/types.h> | |||
@@ -300,4 +315,3 @@ EOF | |||
chmod +x config.status | |||
test -n "$no_create" || ./config.status | |||
@@ -6,7 +6,7 @@ AC_PROG_INSTALL | |||
AC_SIZE_T | |||
AC_HEADER_CHECK(string.h, AC_DEFINE(HAVE_STRING)) | |||
AC_HEADER_CHECK(stdlib.h, AC_DEFINE(HAVE_STDLIB)) | |||
AC_HEADER_CHECK(unistd.h, AC_DEFINE(HAVE_UNISTD)) | |||
AC_COMPILE_CHECK(raise, [#include <sys/types.h> | |||
#include <signal.h>], [raise(1);], AC_DEFINE(HAVE_RAISE)) | |||
AC_OUTPUT(Makefile) | |||
@@ -0,0 +1,545 @@ | |||
/*-------------------------------------------------------------------*/ | |||
/* renum.c -- Renumbers a BASIC program in an ASCII file. */ | |||
/* Originally written in HP 2000 BASIC by David Lance Robinson, 1977 */ | |||
/* Adapted to MS BASIC and translated to C 4/1995 by Jon B. Volkoff */ | |||
/* (eidetics@cerf.net) */ | |||
/*-------------------------------------------------------------------*/ | |||
#include <stdio.h> | |||
int instr(); | |||
char *midstr1(); | |||
char *midstr2(); | |||
void binary_search(void); | |||
int f2, l2, n, x; | |||
int sidx[1500][2]; | |||
char rstr[255]; | |||
main(argc, argv) | |||
int argc; | |||
char *argv[]; | |||
{ | |||
int f, d, s, p, s1, t, l, g; | |||
int c, f1, c1, i, f8, r, l1, l3; | |||
int v1, f6, l6, b, f9, x9, b1, p8, p9, a, d9; | |||
char pstr[255], sstr[255], f9str[255], s9str[255], tempstr[255]; | |||
FILE *fdin, *fdout; | |||
int skip, bp, temp, getout, disp_msg; | |||
f = 1; | |||
if (argc > 1) strcpy(pstr, argv[1]); | |||
else | |||
{ | |||
printf("Program in file? "); | |||
gets(pstr); | |||
} | |||
if (strlen(pstr) == 0) strcpy(pstr, "0.doc"); | |||
fdin = fopen(pstr, "r"); | |||
if (fdin == NULL) | |||
{ | |||
printf("Unable to open input file\n"); | |||
exit(1); | |||
} | |||
strcpy(f9str, pstr); | |||
strcpy(pstr, "editfl"); | |||
fdout = fopen(pstr, "w"); | |||
if (fdout == NULL) | |||
{ | |||
printf("Unable to open editfl output file\n"); | |||
exit(1); | |||
} | |||
/* Main program begins here */ | |||
s = 0; l2 = 0; d = 0; | |||
f2 = 10000; | |||
printf ("PLEASE WAIT A FEW SECONDS!\n"); | |||
while (fgets(pstr, 255, fdin) != NULL) | |||
{ | |||
pstr[strlen(pstr) - 1] = '\0'; | |||
p = instr(pstr, " "); | |||
if (p != 0 && p <= 5) | |||
{ | |||
n = atoi(midstr2(pstr, 1, p)); | |||
if (n != 0) | |||
{ | |||
s++; | |||
sidx[s][0] = n; | |||
s1 = s; | |||
while (s1 >= 2) | |||
{ | |||
s1--; | |||
if (sidx[s1][0] < sidx[s1 + 1][0]) break; | |||
if (sidx[s1][0] == sidx[s1 + 1][0]) | |||
{ | |||
printf("ERROR !!! MORE THAN ONE STATEMENT FOR A "); | |||
printf("STATEMENT NUMBER\n"); | |||
exit(1); | |||
} | |||
t = sidx[s1][0]; | |||
sidx[s1][0] = sidx[s1 + 1][0]; | |||
sidx[s1 + 1][0] = t; | |||
} | |||
} | |||
} | |||
} | |||
fclose(fdin); | |||
if (s == 0) | |||
{ | |||
printf("NO PROGRAM IS IN THE FILE!\n"); | |||
exit(1); | |||
} | |||
for (l = 1; l <= s; l++) | |||
sidx[l][1] = sidx[l][0]; | |||
g = 1; | |||
disp_msg = 1; | |||
/*------------------------------------------------------------------------*/ | |||
/* Find out how and what to renumber (using HP BASIC renumber parameters) */ | |||
/* MS BASIC renumber is: RENUM (newnum) (,(oldnum) (,increment)) */ | |||
/*------------------------------------------------------------------------*/ | |||
while(1) | |||
{ | |||
if (disp_msg == 1) | |||
{ | |||
printf("RENUMBER (-starting number (,interval (,first statement "); | |||
printf("(,last))))\n"); | |||
disp_msg = 0; | |||
} | |||
skip = 0; | |||
bp = 0; | |||
printf("RENUMBER-"); | |||
gets(pstr); | |||
p = strlen(pstr); | |||
if (g == 0) | |||
{ | |||
if (strlen(pstr) == 0) break; | |||
if (p == 0) skip = 1; | |||
else | |||
{ | |||
t = atoi(midstr2(pstr, 1, 1)); | |||
if (t == 0) break; | |||
} | |||
} | |||
if (strlen(pstr) == 0) skip = 1; | |||
if (skip == 0) | |||
{ | |||
c = instr(pstr, ","); | |||
temp = 0; if (c != 0) temp = -1; | |||
f1 = atoi(midstr2(pstr, 1, p + temp*(p - c + 1))); | |||
if (f1 == 0) bp = 1; | |||
if (c == 0) skip = 2; | |||
} | |||
if (skip == 0 && bp == 0) | |||
{ | |||
c1 = instr(midstr1(pstr, c + 1), ",") + c; | |||
temp = 0; if (c1 != c) temp = -1; | |||
i = atoi(midstr2(pstr, c + 1, p + temp*(p - c1 + 1) - c)); | |||
if (i == 0) bp = 1; | |||
if (c1 == c) skip = 3; | |||
} | |||
if (skip == 0 && bp == 0) | |||
{ | |||
c = instr(midstr1(pstr, c1 + 1), ",") + c1; | |||
temp = 0; if (c != c1) temp = -1; | |||
f8 = atoi(midstr2(pstr, c1 + 1, p + temp*(p - c + 1) - c1)); | |||
if (f8 == 0) bp = 1; | |||
if (c == c1) skip = 4; | |||
} | |||
if (skip == 0 && bp == 0) | |||
{ | |||
l = atoi(midstr1(pstr, c + 1)); | |||
if (l == 0) bp = 1; | |||
} | |||
if (bp == 0) switch (skip) | |||
{ | |||
case 1: | |||
f1 = 10; | |||
i = 10; | |||
f8 = 1; | |||
l = 99999; | |||
break; | |||
case 2: | |||
i = 10; | |||
f8 = 1; | |||
l = 99999; | |||
break; | |||
case 3: | |||
f8 = 1; | |||
l = 99999; | |||
break; | |||
case 4: | |||
l = 99999; | |||
break; | |||
} | |||
if (f1 < 1 || i == 0 || f8 < 1 || l < 1) bp = 1; | |||
if (f1 > 99999 || i > 99999 || f8 > 99999 || l > 99999 || f8 > l) | |||
bp = 1; | |||
c = 0; | |||
for (r = 1; r <= s; r++) | |||
if (sidx[r][0] >= f8 && sidx[r][0] <= l) c = c + 1; | |||
if (c == 0) | |||
{ | |||
printf("There is nothing to renumber !!\n"); | |||
disp_msg = 1; | |||
} | |||
/*------------------------------------*/ | |||
/* Make list of new statement numbers */ | |||
/*------------------------------------*/ | |||
l1 = f1 + (c - 1)*i; | |||
if (l1 < 1 || l1 > 99999) bp = 1; | |||
x = 0; c = 0; | |||
if (bp == 0 && disp_msg == 0) for (r = 1; r <= s; r++) | |||
{ | |||
if (sidx[r][0] < f8 || sidx[r][0] > l) | |||
if (sidx[r][1] >= f1 && sidx[r][1] <= l1) | |||
{ | |||
printf("SEQUENCE NUMBER OVERLAP\n"); | |||
exit(1); | |||
} | |||
else {} | |||
else | |||
{ | |||
if (sidx[r][0] != f1 + c*i) | |||
{ | |||
if (x == 0) | |||
{ | |||
if (r < f2) f2 = r; | |||
x = 1; | |||
} | |||
if (r > l2) l2 = r; | |||
} | |||
sidx[r][1] = f1 + c*i; | |||
c++; | |||
l3 = r; | |||
} | |||
} | |||
if (bp == 0 && disp_msg == 0) g = 0; | |||
if (bp == 1) printf("BAD PARAMETER\n"); | |||
} | |||
/*-------------------*/ | |||
/* Start renumbering */ | |||
/*-------------------*/ | |||
if (l2 == 0) | |||
{ | |||
printf("NOTHING RENUMBERED!\n"); | |||
exit(1); | |||
} | |||
printf("RENUMBERING\n"); | |||
/* for (r = 1; r <= s; r ++) | |||
printf("%d -> %d\n", sidx[r][0], sidx[r][1]); */ | |||
printf("VERIFY? "); | |||
gets(pstr); | |||
v1 = 0; | |||
if (strcmp(midstr2(pstr, 1, 1), "N") == 0) v1 = 1; | |||
fdin = fopen(f9str, "r"); | |||
if (fdin == NULL) | |||
{ | |||
printf("Unable to open input file\n"); | |||
exit(1); | |||
} | |||
f6 = sidx[f2][0]; | |||
l6 = sidx[l2][0]; | |||
while (fgets(pstr, 255, fdin) != NULL) | |||
{ | |||
pstr[strlen(pstr) - 1] = '\0'; | |||
b = instr(pstr, " "); | |||
if (b != 0) | |||
{ | |||
n = atoi(midstr2(pstr, 1, b)); | |||
if (n != 0) | |||
{ | |||
if (n >= f6 && n <= l6) | |||
{ | |||
binary_search(); | |||
if (x == 0) | |||
{ | |||
strcat(rstr, midstr1(pstr, b)); | |||
strcpy(pstr, rstr); | |||
b = instr(pstr, " "); | |||
} | |||
} | |||
b++; | |||
/*-------------------------------------------------------------*/ | |||
/* There are differences, of course, between processing for HP */ | |||
/* BASIC and MS BASIC. */ | |||
/* */ | |||
/* CONVERT, PRINT USING, and MAT PRINT USING changes are not */ | |||
/* applicable in MS BASIC. */ | |||
/* */ | |||
/* Had to also add capability for multiple statements here. */ | |||
/*-------------------------------------------------------------*/ | |||
while(1) | |||
{ | |||
if (strcmp(midstr2(pstr, b, 3), "REM") == 0 || | |||
strcmp(midstr2(pstr, b, 1), "'") == 0) break; | |||
f9 = 0; | |||
skip = 0; | |||
for (x9 = b; x9 <= strlen(pstr); x9++) | |||
{ | |||
if ((char)(*midstr2(pstr, x9, 1)) == 34) | |||
{ | |||
if (f9 == 0) | |||
f9 = 1; | |||
else | |||
f9 = 0; | |||
} | |||
else if (strcmp(midstr2(pstr, x9, 1), ":") == 0 && | |||
f9 == 0) | |||
{ | |||
b1 = x9 - 1; | |||
skip = 1; | |||
break; | |||
} | |||
} | |||
if (skip == 0) b1 = strlen(pstr); | |||
t = instr("GOSGOTIF ON RESRET", midstr2(pstr, b, 3)); | |||
temp = (t + 5)/3; | |||
if (temp != 1) | |||
{ | |||
if (temp == 2 || temp == 3 || temp == 4 || temp == 6 || | |||
temp == 7) | |||
{ | |||
/*-------------------------------------------------*/ | |||
/* Change GOSUB, GOTO, IF, RESTORE, RESUME, RETURN */ | |||
/* routine. */ | |||
/* Go word by word through the statement. */ | |||
/*-------------------------------------------------*/ | |||
getout = 0; | |||
p8 = b; | |||
strcpy(s9str, " "); | |||
} | |||
else if (temp == 5) | |||
{ | |||
/*---------------------------------------------------*/ | |||
/* Change ON event/expression GOSUB/GOTO routine. */ | |||
/* Find starting point appropriate to this statement */ | |||
/* type. */ | |||
/*---------------------------------------------------*/ | |||
getout = 1; | |||
for (x9 = b1; x9 >= b; x9--) | |||
{ | |||
if (strcmp(midstr2(pstr, x9, 1), " ") == 0) | |||
{ | |||
p8 = x9 + 1; | |||
getout = 0; | |||
break; | |||
} | |||
} | |||
if (getout == 0) strcpy(s9str, ","); | |||
} | |||
/* Start looping here */ | |||
if (getout == 0) while(1) | |||
{ | |||
f9 = 0; | |||
skip = 0; | |||
for (x9 = p8; x9 <= b1; x9++) | |||
{ | |||
if ((char)(*midstr2(pstr, x9, 1)) == 34) | |||
{ | |||
if (f9 == 0) | |||
f9 = 1; | |||
else | |||
f9 = 0; | |||
} | |||
else if (strcmp(midstr2(pstr, x9, 1), s9str) == 0 && | |||
f9 == 0) | |||
{ | |||
p9 = x9 - 1; | |||
skip = 1; | |||
break; | |||
} | |||
} | |||
if (skip == 0) p9 = b1; | |||
skip = 0; | |||
for (x9 = p8; x9 <= p9; x9++) | |||
{ | |||
a = (char)(*midstr2(pstr, x9, 1)); | |||
if (a < 48 || a > 57) | |||
{ | |||
skip = 1; | |||
break; | |||
} | |||
} | |||
if (skip == 0) | |||
{ | |||
/*---------------------*/ | |||
/* Found a line number */ | |||
/*---------------------*/ | |||
n = atoi(midstr2(pstr, p8, p9 - p8 + 1)); | |||
if (n != 0) | |||
{ | |||
if (n >= f6 && n <= l6) | |||
{ | |||
binary_search(); | |||
if (x == 0) | |||
{ | |||
if (p9 == strlen(pstr)) | |||
{ | |||
strcpy(tempstr, midstr2(pstr, 1, p8 - 1)); | |||
strcat(tempstr, rstr); | |||
strcpy(pstr, tempstr); | |||
} | |||
else | |||
{ | |||
strcpy(tempstr, midstr2(pstr, 1, p8 - 1)); | |||
strcat(tempstr, rstr); | |||
strcat(tempstr, midstr1(pstr, p9 + 1)); | |||
strcpy(pstr, tempstr); | |||
} | |||
/*-----------------------------------*/ | |||
/* Adjust indices to account for new */ | |||
/* substring length, if any. */ | |||
/*-----------------------------------*/ | |||
d9 = strlen(rstr) - (p9 - p8 + 1); | |||
p9 = p9 + d9; | |||
b1 = b1 + d9; | |||
} | |||
} | |||
} | |||
} | |||
p8 = p9 + 2; | |||
if (p8 > b1) break; | |||
} | |||
} | |||
/*--------------------------------------------------*/ | |||
/* No more words to process in the statement, go to */ | |||
/* next statement. */ | |||
/*--------------------------------------------------*/ | |||
if (b1 == strlen(pstr)) break; | |||
b = b1 + 2; | |||
} | |||
} | |||
} | |||
fprintf(fdout, "%s\n", pstr); | |||
if (v1 == 0) printf("%s\n", pstr); | |||
} | |||
fclose(fdin); | |||
fclose(fdout); | |||
sprintf(tempstr, "mv editfl %s\0", f9str); | |||
system(tempstr); | |||
} | |||
int instr(astr, bstr) | |||
char *astr, *bstr; | |||
{ | |||
int p; | |||
p = strstr(astr, bstr); | |||
if (p == NULL) p = (int)(astr) - 1; | |||
p = p - (int)(astr) + 1; | |||
return p; | |||
} | |||
char *midstr1(astr, start) | |||
char *astr; | |||
int start; | |||
{ | |||
static char tempstr[255]; | |||
char *startptr; | |||
strcpy(tempstr, astr); | |||
startptr = (char *)((long)(tempstr) + start - 1); | |||
return startptr; | |||
} | |||
char *midstr2(astr, start, len) | |||
char *astr; | |||
int start, len; | |||
{ | |||
static char tempstr[255]; | |||
char *startptr, *endptr; | |||
strcpy(tempstr, astr); | |||
startptr = (char *)((long)(tempstr) + start - 1); | |||
endptr = (char *)((long)(tempstr) + start + len - 1); | |||
strcpy(endptr, "\0"); | |||
return startptr; | |||
} | |||
void binary_search(void) | |||
{ | |||
int f5, l5, m; | |||
f5 = f2; | |||
l5 = l2 + 1; | |||
while(1) | |||
{ | |||
m = (f5 + l5)/2; | |||
if (sidx[m][0] == n) | |||
{ | |||
sprintf(rstr, "%d\0", sidx[m][1]); | |||
x = 0; | |||
return; | |||
} | |||
if (m == f5 || m == l5) | |||
{ | |||
x = 1; | |||
return; | |||
} | |||
if (sidx[m][0] < n) | |||
f5 = m; | |||
else | |||
l5 = m; | |||
} | |||
} |