Browse Source

v2.20

tags/v2.20
Jon Foster 2 years ago
parent
commit
df0886e6ae
32 changed files with 2867 additions and 466 deletions
  1. +0
    -1
      COPYING
  2. +21
    -6
      Makefile.in
  3. +37
    -23
      README
  4. +77
    -20
      bwb_cmd.c
  5. +69
    -14
      bwb_cnd.c
  6. +108
    -22
      bwb_dio.c
  7. +46
    -20
      bwb_elx.c
  8. +26
    -5
      bwb_exp.c
  9. +59
    -19
      bwb_fnc.c
  10. +481
    -6
      bwb_inp.c
  11. +32
    -5
      bwb_int.c
  12. +6
    -1
      bwb_mes.h
  13. +52
    -23
      bwb_mth.c
  14. +116
    -13
      bwb_ops.c
  15. +7
    -2
      bwb_par.c
  16. +199
    -20
      bwb_prn.c
  17. +35
    -8
      bwb_stc.c
  18. +58
    -13
      bwb_str.c
  19. +26
    -19
      bwb_tbl.c
  20. +0
    -1
      bwb_tcc.c
  21. +376
    -23
      bwb_var.c
  22. +121
    -32
      bwbasic.c
  23. +140
    -139
      bwbasic.doc
  24. +63
    -12
      bwbasic.h
  25. +0
    -1
      bwbtest/pascaltr.bas
  26. +71
    -3
      bwx_iqc.c
  27. +0
    -1
      bwx_iqc.h
  28. +73
    -9
      bwx_tty.c
  29. +7
    -3
      bwx_tty.h
  30. +15
    -1
      configure
  31. +1
    -1
      configure.in
  32. +545
    -0
      renum.c

+ 0
- 1
COPYING View File

@@ -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.



+ 21
- 6
Makefile.in View File

@@ -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:


+ 37
- 23
README View File

@@ -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 )


+ 77
- 20
bwb_cmd.c View File

@@ -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 )
}




+ 69
- 14
bwb_cnd.c View File

@@ -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 )

}




+ 108
- 22
bwb_dio.c View File

@@ -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 */




+ 46
- 20
bwb_elx.c View File

@@ -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


+ 26
- 5
bwb_exp.c View File

@@ -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 )



+ 59
- 19
bwb_fnc.c View File

@@ -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" );


+ 481
- 6
bwb_inp.c View File

@@ -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;

}

+ 32
- 5
bwb_int.c View File

@@ -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 )

}



+ 6
- 1
bwb_mes.h View File

@@ -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[];





+ 52
- 23
bwb_mth.c View File

@@ -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 );
}
}
}




+ 116
- 13
bwb_ops.c View File

@@ -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;

}


+ 7
- 2
bwb_par.c View File

@@ -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




+ 199
- 20
bwb_prn.c View File

@@ -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 );


+ 35
- 8
bwb_stc.c View File

@@ -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 )
}




+ 58
- 13
bwb_str.c View File

@@ -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 )
}





+ 26
- 19
bwb_tbl.c View File

@@ -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 ] =
};




+ 0
- 1
bwb_tcc.c View File

@@ -2,4 +2,3 @@
establish a larger-than-usual stack of 8192 bytes for bwBASIC */

extern unsigned _stklen = 8192U;


+ 376
- 23
bwb_var.c View File

@@ -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;


+ 121
- 32
bwbasic.c View File

@@ -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);
}

+ 140
- 139
bwbasic.doc View File

@@ -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


+ 63
- 12
bwbasic.h View File

@@ -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();



+ 0
- 1
bwbtest/pascaltr.bas View File

@@ -14,4 +14,3 @@
230 print
240 next i
250 end


+ 71
- 3
bwx_iqc.c View File

@@ -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 */


+ 0
- 1
bwx_iqc.h View File

@@ -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 */


+ 73
- 9
bwx_tty.c View File

@@ -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 );


+ 7
- 3
bwx_tty.h View File

@@ -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 */

configur → configure View File

@@ -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



configur.in → configure.in View File

@@ -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)


+ 545
- 0
renum.c View File

@@ -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;
}
}

Loading…
Cancel
Save