|
- /***************************************************************
-
- bwb_dio.c Device Input/Output Routines
- for Bywater BASIC Interpreter
-
- Copyright (c) 1993, Ted A. Campbell
- Bywater Software
-
- email: tcamp@delphi.com
-
- Copyright and Permissions Information:
-
- All U.S. and international rights are claimed by the author,
- Ted A. Campbell.
-
- This software is released under the terms of the GNU General
- Public License (GPL), which is distributed with this software
- in the file "COPYING". The GPL specifies the terms under
- which users may copy and use the software in this distribution.
-
- A separate license is available for commercial distribution,
- for information on which you should contact the author.
-
- ***************************************************************/
-
- /*---------------------------------------------------------------*/
- /* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */
- /* 11/1995 (eidetics@cerf.net). */
- /*---------------------------------------------------------------*/
-
- #include <stdio.h>
-
- #include "bwbasic.h"
- #include "bwb_mes.h"
-
- #if HAVE_SYSSTAT
- #include <sys/stat.h>
- #endif
-
- #ifndef SEEK_SET
- #define SEEK_SET 0
- #endif
-
- #if INTENSIVE_DEBUG
- #define RANDOM_FILLCHAR 'X'
- #else
- #define RANDOM_FILLCHAR ' '
- #endif
-
- #if COMMON_CMDS
- struct dev_element *dev_table; /* table of devices */
- #endif
-
- static struct bwb_variable *v;
- static int pos;
- static int req_devnumber;
- static int rlen;
- static int mode;
-
- #if ANSI_C
- static struct bwb_line *dio_lrset( struct bwb_line *l, int rset );
- static int dio_flush( int dev_number );
- #else
- static struct bwb_line *dio_lrset();
- static int dio_flush();
- #endif
-
- #if COMMON_CMDS
-
- /***************************************************************
-
- FUNCTION: bwb_open()
-
- DESCRIPTION: This function implements the BASIC OPEN
- command to open a stream for device input/output.
-
- SYNTAX: 1. OPEN "I"|"O"|"R", [#]n, filename [,rlen]
- 2. OPEN filename [FOR INPUT|OUTPUT|APPEND|] AS [#]n [LEN=n]
-
- ***************************************************************/
-
- #if ANSI_C
- struct bwb_line *
- bwb_open( struct bwb_line *l )
- #else
- struct bwb_line *
- bwb_open( l )
- struct bwb_line *l;
- #endif
- {
- FILE *fp;
- struct exp_ese *e;
- int previous_buffer;
- char atbuf[ MAXSTRINGSIZE + 1 ];
- char first[ MAXSTRINGSIZE + 1 ];
- char devname[ MAXSTRINGSIZE + 1 ];
-
- /* initialize */
-
- mode = req_devnumber = rlen = -1;
- previous_buffer = FALSE;
-
- /* get the first expression element up to comma or whitespace */
-
- adv_element( l->buffer, &( l->position ), atbuf );
-
- /* parse the first expression element */
-
- pos = 0;
- e = bwb_exp( atbuf, FALSE, &pos );
- str_btoc( first, exp_getsval( e ) );
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_open(): first element is <%s>",
- first );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* test for syntactical form: if a comma follows the first element,
- then the syntax is form 1 (the old CP/M BASIC format); otherwise we
- presume form 2 */
-
- adv_ws( l->buffer, &( l->position ) );
-
- /* Parse syntax Form 1 (OPEN "x",#n, devname...) */
-
- if ( l->buffer[ l->position ] == ',' )
- {
-
- /* parse the next element to get the device number */
-
- ++( l->position ); /* advance beyond comma */
- adv_ws( l->buffer, &( l->position ) );
- if ( l->buffer[ l->position ] == '#' )
- {
- ++( l->position );
- adv_ws( l->buffer, &( l->position ) );
- }
-
- adv_element( l->buffer, &( l->position ), atbuf );
-
- pos = 0;
- e = bwb_exp( atbuf, FALSE, &pos );
- if ( e->type == STRING )
- {
- #if PROG_ERRORS
- bwb_error( "String where number was expected for device number" );
- #else
- bwb_error( err_syntax );
- #endif
- return bwb_zline( l );
- }
- req_devnumber = (int) exp_getnval( e );
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_open(): syntax 1, req dev number is %d",
- req_devnumber );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* parse the next element to get the devname */
-
- adv_ws( l->buffer, &( l->position ) ); /* advance past whitespace */
- ++( l->position ); /* advance past comma */
- adv_element( l->buffer, &( l->position ), atbuf );
-
- pos = 0;
- e = bwb_exp( atbuf, FALSE, &pos );
- if ( e->type != STRING )
- {
- #if PROG_ERRORS
- bwb_error( "in bwb_open(): number where string was expected for devname" );
- #else
- bwb_error( err_syntax );
- #endif
- return bwb_zline( l );
- }
- str_btoc( devname, exp_getsval( e ) );
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_open(): syntax 1, devname <%s>",
- devname );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* see if there is another element; if so, parse it to get the
- record length */
-
- adv_ws( l->buffer, &( l->position ) );
- if ( l->buffer[ l->position ] == ',' )
- {
-
- ++( l->position ); /* advance beyond comma */
- adv_element( l->buffer, &( l->position ), atbuf );
-
- pos = 0;
- e = bwb_exp( atbuf, FALSE, &pos );
- if ( e->type == STRING )
- {
- #if PROG_ERRORS
- bwb_error( "String where number was expected for record length" );
- #else
- bwb_error( err_syntax );
- #endif
- return bwb_zline( l );
- }
- rlen = (int) exp_getnval( e );
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_open(): syntax 1, record length is %d",
- rlen );
- bwb_debug( bwb_ebuf );
- #endif
-
- }
-
- /* the first letter of the first should indicate the
- type of file opening requested: test this letter,
- then parse accordingly */
-
- /* open file for sequential INPUT */
-
- if ( ( first[ 0 ] == 'i' ) || ( first[ 0 ] == 'I' ))
- {
- mode = DEVMODE_INPUT;
- }
-
- /* open file for sequential OUTPUT */
-
- else if ( ( first[ 0 ] == 'o' ) || ( first[ 0 ] == 'O' ))
- {
- mode = DEVMODE_OUTPUT;
- }
-
- /* open file for RANDOM access input and output */
-
- else if ( ( first[ 0 ] == 'r' ) || ( first[ 0 ] == 'R' ))
- {
- mode = DEVMODE_RANDOM;
- }
-
- /* error: none of the appropriate modes found */
-
- else
- {
- #if PROG_ERRORS
- sprintf( bwb_ebuf, "in bwb_open(): invalid mode" );
- bwb_error( bwb_ebuf );
- #else
- bwb_error( err_syntax );
- #endif
- }
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_open(): syntax 1, mode is %d", mode );
- bwb_debug( bwb_ebuf );
- #endif
-
- }
-
- /* Parse syntax Form 2 (OPEN devname FOR mode AS#n ... ) */
-
- else
- {
-
- /* save the devname from first */
-
- strcpy( devname, first );
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_open(): syntax 2, devname <%s>",
- devname );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* get the next element */
-
- adv_element( l->buffer, &( l->position ), atbuf );
-
- /* check for "FOR mode" statement */
-
- bwb_strtoupper( atbuf );
- if ( strcmp( atbuf, "FOR" ) == 0 )
- {
- adv_element( l->buffer, &( l->position ), atbuf );
- bwb_strtoupper( atbuf );
- if ( strcmp( atbuf, "INPUT" ) == 0 )
- {
- mode = DEVMODE_INPUT;
- }
- else if ( strcmp( atbuf, "OUTPUT" ) == 0 )
- {
- mode = DEVMODE_OUTPUT;
- }
- else if ( strcmp( atbuf, "APPEND" ) == 0 )
- {
- mode = DEVMODE_RANDOM;
- }
- else
- {
- #if PROG_ERRORS
- bwb_error( "in bwb_open(): Invalid device i/o mode specified" );
- #else
- bwb_error( err_syntax );
- #endif
- return bwb_zline( l );
- }
-
- /* get the next element */
-
- adv_element( l->buffer, &( l->position ), atbuf );
-
- }
- else
- {
- mode = DEVMODE_RANDOM;
- }
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_open(): syntax 2, mode is %d", mode );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* This leaves us with the next element in the atbuf: it
- should read "AS" */
-
- bwb_strtoupper( atbuf );
- if ( strcmp( atbuf, "AS" ) != 0 )
- {
- #if PROG_ERRORS
- bwb_error( "in bwb_open(): expected AS statement" );
- #else
- bwb_error( err_syntax );
- #endif
- return bwb_zline( l );
- }
-
- /* get the next element */
-
- adv_ws( l->buffer, &( l->position ) );
-
- if ( l->buffer[ l->position ] == '#' )
- {
- ++( l->position );
- }
-
- adv_element( l->buffer, &( l->position ), atbuf );
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_open(): string to parse for req dev number <%s>",
- atbuf );
- bwb_debug( bwb_ebuf );
- #endif
-
- pos = 0;
- e = bwb_exp( atbuf, FALSE, &pos );
- if ( e->type == STRING )
- {
- #if PROG_ERRORS
- bwb_error( "String where number was expected for dev number" );
- #else
- bwb_error( err_syntax );
- #endif
- return bwb_zline( l );
- }
- req_devnumber = (int) exp_getnval( e );
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_open(): syntax 2, req dev number is %d",
- req_devnumber );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* Check for LEN = n statement */
-
- adv_element( l->buffer, &( l->position ), atbuf );
- bwb_strtoupper( atbuf );
- if ( strncmp( atbuf, "LEN", (size_t) 3 ) == 0 )
- {
-
- pos = l->position - strlen( atbuf );
- while( ( l->buffer[ pos ] != '=' ) && ( l->buffer[ pos ] != '\0' ))
- {
- ++pos;
- }
- if ( l->buffer[ pos ] == '\0' )
- {
- #if PROG_ERRORS
- bwb_error( "Failed to find equals sign after LEN element" );
- #else
- bwb_error( err_syntax );
- #endif
- return bwb_zline( l );
- }
- ++pos; /* advance past equal sign */
-
- e = bwb_exp( l->buffer, FALSE, &pos );
-
- if ( e->type == STRING )
- {
- #if PROG_ERRORS
- bwb_error( "String where number was expected for record length" );
- #else
- bwb_error( err_syntax );
- #endif
- return bwb_zline( l );
- }
- rlen = (int) exp_getnval( e );
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_open(): syntax 2, record length is %d",
- rlen );
- bwb_debug( bwb_ebuf );
- #endif
-
- }
-
- } /* end of syntax 2 */
-
- /* check for valid requested device number */
-
- if ( ( req_devnumber < 0 ) || ( req_devnumber >= DEF_DEVICES ))
- {
- #if PROG_ERRORS
- bwb_error( "in bwb_open(): Requested device number is out of range." );
- #else
- bwb_error( err_devnum );
- #endif
- return bwb_zline( l );
- }
-
- if ( dev_table[ req_devnumber ].mode == DEVMODE_CLOSED )
- {
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_open(): using previously closed file (and buffer)" );
- bwb_debug( bwb_ebuf );
- #endif
- previous_buffer = TRUE;
- }
-
- if ( ( dev_table[ req_devnumber ].mode != DEVMODE_CLOSED ) &&
- ( dev_table[ req_devnumber ].mode != DEVMODE_AVAILABLE ) )
- {
- #if PROG_ERRORS
- bwb_error( "in bwb_open(): Requested device number is already in use." );
- #else
- bwb_error( err_devnum );
- #endif
-
- return bwb_zline( l );
- }
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_open(): ready to open device <%s> mode <%d>",
- devname, mode );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* attempt to open the file */
-
- switch( mode )
- {
- case DEVMODE_OUTPUT:
- fp = fopen( devname, "w" );
- break;
- case DEVMODE_INPUT:
- fp = fopen( devname, "r" );
- break;
- case DEVMODE_APPEND:
- fp = fopen( devname, "a" );
- break;
- case DEVMODE_RANDOM:
- fp = fopen( devname, "r+" );
- if ( fp == NULL )
- {
- fp = fopen( devname, "w" );
- fclose( fp );
- fp = fopen( devname, "r+" );
- }
- break;
- }
-
- /* check for valid file opening */
-
- if ( fp == NULL )
- {
- #if PROG_ERRORS
- sprintf( bwb_ebuf, "Failed to open device <%s>", devname );
- bwb_error( bwb_ebuf );
- #else
- bwb_error( err_dev );
- #endif
- return bwb_zline( 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;
- dev_table[ req_devnumber ].next_record = 1;
- 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 ))
- {
- /* 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" );
- #else
- bwb_error( err_getmem );
- #endif
- return bwb_zline( l );
- }
-
- dio_flush( req_devnumber );
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_open(): allocated new random-access buffer" );
- bwb_debug( bwb_ebuf );
- #endif
-
- }
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_open(): file is open now; end of function" );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* return next line number in sequence */
-
- return bwb_zline( l );
- }
-
- /***************************************************************
-
- FUNCTION: bwb_close()
-
- DESCRIPTION: This function implements the BASIC CLOSE
- command to close a stream for device input/output.
-
- SYNTAX: CLOSE [#]n [,[#]n...]
-
- ***************************************************************/
-
- #if ANSI_C
- struct bwb_line *
- bwb_close( struct bwb_line *l )
- #else
- struct bwb_line *
- bwb_close( l )
- struct bwb_line *l;
- #endif
- {
- 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 ] == '#')
- {
- ++( l->position );
- }
-
- adv_element( l->buffer, &( l->position ), atbuf );
-
- pos = 0;
- e = bwb_exp( atbuf, FALSE, &pos );
-
- if ( e->type == STRING )
- {
- #if PROG_ERRORS
- bwb_error( "String where number was expected for device number" );
- #else
- bwb_error( err_syntax );
- #endif
- return bwb_zline( l );
- }
-
- /*-------------------------------------------------------------*/
- /* 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>",
- req_devnumber );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* check for valid requested device number */
-
- if ( ( req_devnumber < 0 ) || ( req_devnumber >= DEF_DEVICES ))
- {
- #if PROG_ERRORS
- bwb_error( "in bwb_close(): Requested device number is out if range." );
- #else
- bwb_error( err_devnum );
- #endif
- return bwb_zline( l );
- }
-
- if (( dev_table[ req_devnumber ].mode == DEVMODE_CLOSED ) ||
- ( dev_table[ req_devnumber ].mode == DEVMODE_AVAILABLE ) )
- {
- #if PROG_ERRORS
- bwb_error( "in bwb_close(): Requested device number is not in use." );
- #else
- bwb_error( err_devnum );
- #endif
-
- return bwb_zline( l );
- }
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_close(): closing device# <%d>",
- req_devnumber );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* attempt to close the file */
-
- if ( fclose( dev_table[ req_devnumber ].cfp ) != 0 )
- {
- #if PROG_ERRORS
- bwb_error( "in bwb_close(): Failed to close the device" );
- #else
- bwb_error( err_dev );
- #endif
- return bwb_zline( l );
- }
-
- /* mark the device in the table as unavailable */
-
- 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 ] == ',' || blanket_close == 1); /* JBV */
-
- /* return next line number in sequence */
-
- return bwb_zline( l );
- }
-
- #endif /* COMMON_CMDS */
-
- /***************************************************************
-
- FUNCTION: bwb_chdir()
-
- DESCRIPTION: This function implements the BASIC CHDIR
- command to switch logged directories.
-
- SYNTAX: CHDIR pathname$
-
- ***************************************************************/
-
- #if UNIX_CMDS
- #if ANSI_C
- struct bwb_line *
- bwb_chdir( struct bwb_line *l )
- #else
- struct bwb_line *
- bwb_chdir( l )
- struct bwb_line *l;
- #endif
- {
- int r;
- static int position;
- struct exp_ese *e;
- static char *atbuf;
- static int init = FALSE;
-
- /* get memory for temporary buffers if necessary */
-
- if ( init == FALSE )
- {
- init = TRUE;
-
- /* 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" );
- #else
- bwb_error( err_getmem );
- #endif
- }
- }
-
- /* get the next element in atbuf */
-
- adv_element( l->buffer, &( l->position ), atbuf );
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_chdir(): argument is <%s>", atbuf );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* interpret the argument */
-
- position = 0;
- e = bwb_exp( atbuf, FALSE, &position );
-
- if ( e->type != STRING )
- {
- bwb_error( err_argstr );
- return bwb_zline( l );
- }
-
- /* try to chdir to the requested directory */
-
- str_btoc( atbuf, &( e->sval ) );
- r = chdir( atbuf );
-
- /* detect error */
-
- if ( r == -1 )
- {
- bwb_error( err_opsys );
- return bwb_zline( l );
- }
-
- return bwb_zline( l );
-
- }
-
- /***************************************************************
-
- FUNCTION: bwb_rmdir()
-
- DESCRIPTION: This function implements the BASIC CHDIR
- command to remove a subdirectory.
-
- SYNTAX: RMDIR pathname$
-
- ***************************************************************/
-
- #if ANSI_C
- struct bwb_line *
- bwb_rmdir( struct bwb_line *l )
- #else
- struct bwb_line *
- bwb_rmdir( l )
- struct bwb_line *l;
- #endif
- {
- int r;
- static int position;
- struct exp_ese *e;
- static char *atbuf;
- static int init = FALSE;
-
- /* get memory for temporary buffers if necessary */
-
- if ( init == FALSE )
- {
- init = TRUE;
-
- /* 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" );
- #else
- bwb_error( err_getmem );
- #endif
- }
- }
-
- /* get the next element in atbuf */
-
- adv_element( l->buffer, &( l->position ), atbuf );
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_rmdir(): argument is <%s>", atbuf );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* interpret the argument */
-
- position = 0;
- e = bwb_exp( atbuf, FALSE, &position );
-
- if ( e->type != STRING )
- {
- bwb_error( err_argstr );
- return bwb_zline( l );
- }
-
- /* try to remove the requested directory */
-
- str_btoc( atbuf, &( e->sval ) );
- r = rmdir( atbuf );
-
- /* detect error */
-
- if ( r == -1 )
- {
- bwb_error( err_opsys );
- }
-
- return bwb_zline( l );
-
- }
-
- /***************************************************************
-
- FUNCTION: bwb_mkdir()
-
- DESCRIPTION: This function implements the BASIC MKDIR
- command to create a new subdirectory.
-
- SYNTAX: MKDIR pathname$
-
- ***************************************************************/
-
- #if ANSI_C
- struct bwb_line *
- bwb_mkdir( struct bwb_line *l )
- #else
- struct bwb_line *
- bwb_mkdir( l )
- struct bwb_line *l;
- #endif
- {
- int r;
- static int position;
- struct exp_ese *e;
- static char *atbuf;
- static int init = FALSE;
-
- /* get memory for temporary buffers if necessary */
-
- if ( init == FALSE )
- {
- init = TRUE;
-
- /* 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" );
- #else
- bwb_error( err_getmem );
- #endif
- }
- }
-
- /* get the next element in atbuf */
-
- adv_element( l->buffer, &( l->position ), atbuf );
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_mkdir(): argument is <%s>", atbuf );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* interpret the argument */
-
- position = 0;
- e = bwb_exp( atbuf, FALSE, &position );
-
- if ( e->type != STRING )
- {
- bwb_error( err_argstr );
- return bwb_zline( l );
- }
-
- /* try to make the requested directory */
-
- str_btoc( atbuf, &( e->sval ) );
- #if MKDIR_ONE_ARG
- r = mkdir( atbuf );
- #else
- r = mkdir( atbuf, PERMISSIONS );
- #endif
-
- /* detect error */
-
- if ( r == -1 )
- {
- bwb_error( err_opsys );
- }
-
- return bwb_zline( l );
-
- }
-
- /***************************************************************
-
- FUNCTION: bwb_kill()
-
- DESCRIPTION: This function implements the BASIC KILL
- command to erase a disk file.
-
- SYNTAX: KILL filename
-
- ***************************************************************/
-
- #if ANSI_C
- struct bwb_line *
- bwb_kill( struct bwb_line *l )
- #else
- struct bwb_line *
- bwb_kill( l )
- struct bwb_line *l;
- #endif
- {
- int r;
- static int position;
- struct exp_ese *e;
- static char *atbuf;
- static int init = FALSE;
-
- /* get memory for temporary buffers if necessary */
-
- if ( init == FALSE )
- {
- init = TRUE;
-
- /* 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" );
- #else
- bwb_error( err_getmem );
- #endif
- }
- }
-
- /* get the next element in atbuf */
-
- adv_element( l->buffer, &( l->position ), atbuf );
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_kill(): argument is <%s>", atbuf );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* interpret the argument */
-
- position = 0;
- e = bwb_exp( atbuf, FALSE, &position );
-
- if ( e->type != STRING )
- {
- bwb_error( err_argstr );
- return bwb_zline( l );
- }
-
- /* try to delete the specified file */
-
- str_btoc( atbuf, &( e->sval ) );
- r = remove( atbuf );
-
- /* detect error */
-
- if ( r == -1 )
- {
- bwb_error( err_opsys );
- }
-
- return bwb_zline( l );
-
- }
-
- #endif /* UNIX_CMDS */
-
- #if COMMON_CMDS
-
- /***************************************************************
-
- FUNCTION: bwb_name()
-
- DESCRIPTION: This function implements the BASIC NAME
- command to rename a disk file.
-
- SYNTAX: NAME old_filename AS new_filename
-
- ***************************************************************/
-
- #if ANSI_C
- struct bwb_line *
- bwb_name( struct bwb_line *l )
- #else
- struct bwb_line *
- bwb_name( l )
- struct bwb_line *l;
- #endif
- {
- int r;
- static int position;
- struct exp_ese *e;
- static char *atbuf;
- static char *btbuf;
- static int init = FALSE;
-
- /* get memory for temporary buffers if necessary */
-
- if ( init == FALSE )
- {
- init = TRUE;
-
- /* 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" );
- #else
- bwb_error( err_getmem );
- #endif
- }
- /* 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" );
- #else
- bwb_error( err_getmem );
- #endif
- }
- }
-
- /* get the first argument in atbuf */
-
- adv_element( l->buffer, &( l->position ), atbuf );
-
- /* interpret the first argument */
-
- position = 0;
- e = bwb_exp( atbuf, FALSE, &position );
-
- if ( e->type != STRING )
- {
- bwb_error( err_argstr );
- return bwb_zline( l );
- }
-
- /* this argument must be copied back to atbuf, else the next
- call to bwb_exp() will overwrite the structure to which e
- refers */
-
- str_btoc( atbuf, &( e->sval ) );
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_name(): old name is <%s>", atbuf );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* get the second argument in btbuf */
-
- adv_element( l->buffer, &( l->position ), btbuf );
- bwb_strtoupper( btbuf );
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_name(): AS string is <%s>", btbuf );
- bwb_debug( bwb_ebuf );
- #endif
-
- if ( strcmp( btbuf, "AS" ) != 0 )
- {
- bwb_error( err_syntax );
- return bwb_zline( l );
- }
-
- /* get the third argument in btbuf */
-
- adv_element( l->buffer, &( l->position ), btbuf );
-
- /* interpret the third argument */
-
- position = 0;
- e = bwb_exp( btbuf, FALSE, &position );
-
- if ( e->type != STRING )
- {
- bwb_error( err_argstr );
- return bwb_zline( l );
- }
-
- str_btoc( btbuf, &( e->sval ) );
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_name(): new name is <%s>", btbuf );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* try to rename the file */
-
- r = rename( atbuf, btbuf );
-
- /* detect error */
-
- if ( r != 0 )
- {
- bwb_error( err_opsys );
- }
-
- return bwb_zline( l );
-
- }
-
- /***************************************************************
-
- FUNCTION: bwb_field()
-
- DESCRIPTION: This C function implements the BASIC
- FIELD command.
-
- ***************************************************************/
-
- #if ANSI_C
- struct bwb_line *
- bwb_field( struct bwb_line *l )
- #else
- struct bwb_line *
- bwb_field( l )
- struct bwb_line *l;
- #endif
- {
- int dev_number;
- int length;
- struct exp_ese *e;
- struct bwb_variable *v;
- bstring *b;
- int current_pos;
- char atbuf[ MAXSTRINGSIZE + 1 ];
-
- current_pos = 0;
-
- /* first read device number */
-
- adv_ws( l->buffer, &( l->position ) );
- if ( l->buffer[ l->position ] =='#' )
- {
- ++( l->position );
- }
-
- adv_element( l->buffer, &( l->position ), atbuf );
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_field(): device# buffer <%s>", atbuf );
- bwb_debug( bwb_ebuf );
- #endif
-
- pos = 0;
- e = bwb_exp( atbuf, FALSE, &pos );
-
- if ( e->type != NUMBER )
- {
- #if PROG_ERRORS
- bwb_error( "in bwb_field(): 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_field(): device <%d>", dev_number );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* be sure that the requested device is open */
-
- if (( dev_table[ dev_number ].mode == DEVMODE_CLOSED ) ||
- ( dev_table[ req_devnumber ].mode == DEVMODE_AVAILABLE ) )
- {
- #if PROG_ERRORS
- bwb_error( "in bwb_field(): Requested device number is not in use." );
- #else
- bwb_error( err_devnum );
- #endif
- return bwb_zline( l );
- }
-
- /* loop to read variables */
-
- do
- {
-
- /* read the comma and advance beyond it */
-
- adv_ws( l->buffer, &( l->position ) );
- if ( l->buffer[ l->position ] ==',' )
- {
- ++( l->position );
- }
-
- /* first find the size of the field */
-
- adv_element( l->buffer, &( l->position ), atbuf ); /* get element */
-
- pos = 0;
- e = bwb_exp( atbuf, FALSE, &pos );
-
- if ( e->type != NUMBER )
- {
- #if PROG_ERRORS
- bwb_error( "in bwb_field(): number value for field size not found" );
- #else
- bwb_error( err_syntax );
- #endif
- return bwb_zline( l );
- }
-
- length = (int) exp_getnval( e );
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_field(): device <%d> length <%d> buf <%s>",
- dev_number, length, &( l->buffer[ l->position ] ) );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* read the AS */
-
- adv_element( l->buffer, &( l->position ), atbuf ); /* get element */
- bwb_strtoupper( atbuf );
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_field(): AS element <%s>", atbuf );
- bwb_debug( bwb_ebuf );
- #endif
-
- if ( strncmp( atbuf, "AS", 2 ) != 0 )
- {
- #if PROG_ERRORS
- bwb_error( "in bwb_field(): AS statement not found" );
- #else
- bwb_error( err_syntax );
- #endif
- return bwb_zline( l );
- }
-
- /* read the string variable name */
-
- adv_element( l->buffer, &( l->position ), atbuf ); /* get element */
- v = var_find( atbuf );
-
- if ( v->type != STRING )
- {
- #if PROG_ERRORS
- bwb_error( "in bwb_field(): string variable name not found" );
- #else
- bwb_error( err_syntax );
- #endif
- return bwb_zline( l );
- }
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_field(): device <%d> var <%s> length <%d>",
- dev_number, v->name, length );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* check for overflow of record length */
-
- if ( ( current_pos + length ) > dev_table[ dev_number ].reclen )
- {
- #if PROG_ERRORS
- bwb_error( "in bwb_field(): record length exceeded" );
- #else
- bwb_error( err_overflow );
- #endif
- return bwb_zline( l );
- }
-
- /* set buffer */
-
- b = var_findsval( v, v->array_pos );
-
- #if DONTDOTHIS
- if ( b->sbuffer != NULL )
- {
- /* Revised to FREE pass-thru call by JBV */
- FREE( b->sbuffer, "bwb_field" );
- b->sbuffer = NULL; /* JBV */
- }
- #endif
-
- b->sbuffer = dev_table[ dev_number ].buffer + current_pos;
- b->length = (unsigned int) length; /* Was unsigned char (JBV 9/4/97) */
- b->rab = TRUE;
-
- current_pos += length;
-
- #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->sbuffer );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* eat up any remaining whitespace */
-
- adv_ws( l->buffer, &( l->position ) );
-
- }
-
- while ( l->buffer[ l->position ] == ',' );
-
- /* return */
-
- return bwb_zline( l );
-
- }
-
- /***************************************************************
-
- FUNCTION: bwb_lset()
-
- DESCRIPTION: This C function implements the BASIC
- LSET command.
-
- SYNTAX: LSET string-variable$ = expression
-
- ***************************************************************/
-
- #if ANSI_C
- struct bwb_line *
- bwb_lset( struct bwb_line *l )
- #else
- struct bwb_line *
- bwb_lset( l )
- struct bwb_line *l;
- #endif
- {
- return dio_lrset( l, FALSE );
- }
-
- /***************************************************************
-
- FUNCTION: bwb_rset()
-
- DESCRIPTION: This C function implements the BASIC
- RSET command.
-
- SYNTAX: RSET string-variable$ = expression
-
- ***************************************************************/
-
- #if ANSI_C
- struct bwb_line *
- bwb_rset( struct bwb_line *l )
- #else
- struct bwb_line *
- bwb_rset( l )
- struct bwb_line *l;
- #endif
- {
- return dio_lrset( l, TRUE );
- }
-
- /***************************************************************
-
- FUNCTION: dio_lrset()
-
- DESCRIPTION: This C function implements the BASIC
- RSET and LSET commands.
-
- ***************************************************************/
-
- #if ANSI_C
- static struct bwb_line *
- dio_lrset( struct bwb_line *l, int rset )
- #else
- static struct bwb_line *
- dio_lrset( l, rset )
- struct bwb_line *l;
- int rset;
- #endif
- {
- char varname[ MAXVARNAMESIZE + 1 ];
- bstring *d, *s;
- int *pp;
- int n_params;
- int p;
- register int n, i;
- int startpos;
- struct exp_ese *e;
-
- /* find the variable name */
-
- bwb_getvarname( l->buffer, varname, &( l->position ));
-
- v = var_find( varname );
-
- if ( v == NULL )
- {
- #if PROG_ERRORS
- sprintf( bwb_ebuf, "in dio_lrset(): 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 dio_lrset(): 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 dio_lrset(): 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 dio_lrset(): 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 );
-
- /* find equals sign */
-
- adv_ws( l->buffer, &( l->position ));
- if ( l->buffer[ l->position ] != '=' )
- {
- #if PROG_ERRORS
- sprintf( bwb_ebuf, "in dio_lrset(): failed to find equal sign" );
- bwb_error( bwb_ebuf );
- #else
- bwb_error( err_syntax );
- #endif
- }
- ++( l->position );
- adv_ws( l->buffer, &( l->position ));
-
- /* read remainder of line to get value */
-
- e = bwb_exp( l->buffer, FALSE, &( l->position ) );
- s = exp_getsval( e );
-
- /* set starting position */
-
- startpos = 0;
- if ( rset == TRUE )
- {
- if ( s->length < d->length )
- {
- startpos = d->length - s->length;
- }
- }
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in dio_lrset(): startpos <%d> buffer <%lX>",
- startpos, (long) d->sbuffer );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* write characters to new position */
-
- i = 0;
- for ( n = startpos; ( i < (int) s->length ) && ( n < (int) d->length ); ++n )
- {
- d->sbuffer[ n ] = s->sbuffer[ i ];
- ++i;
- }
-
- /* return */
-
- return bwb_zline( l );
-
- }
-
- /***************************************************************
-
- FUNCTION: bwb_get()
-
- DESCRIPTION: This C function implements the BASIC
- GET command.
-
- SYNTAX: GET [#] device-number [, record-number]
-
- ***************************************************************/
-
- #if ANSI_C
- struct bwb_line *
- bwb_get( struct bwb_line *l )
- #else
- struct bwb_line *
- bwb_get( l )
- struct bwb_line *l;
- #endif
- {
- int dev_number;
- int rec_number;
- register int i;
- struct exp_ese *e;
- char atbuf[ MAXSTRINGSIZE + 1 ];
- long offset; /* JBV */
-
- /* first read device number */
-
- adv_ws( l->buffer, &( l->position ) );
- if ( l->buffer[ l->position ] =='#' )
- {
- ++( l->position );
- }
-
- adv_element( l->buffer, &( l->position ), atbuf );
-
- pos = 0;
- e = bwb_exp( atbuf, FALSE, &pos );
-
- if ( e->type != NUMBER )
- {
- #if PROG_ERRORS
- bwb_error( "in bwb_get(): 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_get(): device <%d>", dev_number );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* be sure that the requested device is open */
-
- if ( ( dev_table[ dev_number ].mode == DEVMODE_CLOSED ) ||
- ( dev_table[ req_devnumber ].mode == DEVMODE_AVAILABLE ) )
- {
- #if PROG_ERRORS
- bwb_error( "in bwb_get(): Requested device number is not in use." );
- #else
- bwb_error( err_devnum );
- #endif
- return bwb_zline( l );
- }
-
- /* see if there is a comma (and record number) */
-
- adv_ws( l->buffer, &( l->position ) );
- if ( l->buffer[ l->position ] == ',' ) /* yes, there is a comma */
- {
- ++( l->position );
-
- /* get the record number element */
-
- adv_element( l->buffer, &( l->position ), atbuf );
-
- pos = 0;
- e = bwb_exp( atbuf, FALSE, &pos );
- rec_number = (int) exp_getnval( e );
-
- }
-
- else /* no record number given */
- {
- rec_number = dev_table[ dev_number ].next_record;
- }
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_get(): record number <%d>", rec_number );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* wind the c file up to the proper point */
-
- /* 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>",
- rec_number, (long) (( rec_number - 1 ) * dev_table[ dev_number ].reclen ) );
- bwb_error( bwb_ebuf );
- #else
- bwb_error( err_dev );
- #endif
- return bwb_zline( 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 ] =
- (char) fgetc( dev_table[ dev_number ].cfp );
- ++( dev_table[ dev_number ].loc );
- }
-
- /* increment (or reset) the current record */
-
- dev_table[ dev_number ].next_record = rec_number + 1;
-
- return bwb_zline( l );
-
- }
-
- /***************************************************************
-
- FUNCTION: bwb_put()
-
- DESCRIPTION: This C function implements the BASIC
- PUT command.
-
- SYNTAX: PUT [#] device-number [, record-number]
-
- ***************************************************************/
-
- #if ANSI_C
- struct bwb_line *
- bwb_put( struct bwb_line *l )
- #else
- struct bwb_line *
- bwb_put( l )
- struct bwb_line *l;
- #endif
- {
- int dev_number;
- int rec_number;
- register int i;
- struct exp_ese *e;
- char atbuf[ MAXSTRINGSIZE + 1 ];
- long offset; /* JBV */
-
- /* first read device number */
-
- adv_ws( l->buffer, &( l->position ) );
- if ( l->buffer[ l->position ] =='#' )
- {
- ++( l->position );
- }
-
- adv_element( l->buffer, &( l->position ), 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 );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* be sure that the requested device is open */
-
- if ( ( dev_table[ dev_number ].mode == DEVMODE_CLOSED ) ||
- ( dev_table[ req_devnumber ].mode == DEVMODE_AVAILABLE ) )
- {
- #if PROG_ERRORS
- bwb_error( "in bwb_put(): Requested device number is not in use." );
- #else
- bwb_error( err_devnum );
- #endif
- return bwb_zline( l );
- }
-
- /* see if there is a comma (and record number) */
-
- adv_ws( l->buffer, &( l->position ) );
- if ( l->buffer[ l->position ] == ',' ) /* yes, there is a comma */
- {
- ++( l->position );
-
- /* get the record number element */
-
- adv_element( l->buffer, &( l->position ), atbuf );
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_put(): rec no buffer <%s>", atbuf );
- bwb_debug( bwb_ebuf );
- #endif
-
- pos = 0;
- e = bwb_exp( atbuf, FALSE, &pos );
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_put(): return type <%c>", e->type );
- bwb_debug( bwb_ebuf );
- #endif
-
- rec_number = (int) exp_getnval( e );
-
- }
-
- else /* no record number given */
- {
- rec_number = dev_table[ dev_number ].next_record;
- }
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_put(): record number <%d>", rec_number );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* wind the c file up to the proper point */
-
- /* 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>",
- rec_number, (long) (( rec_number - 1 ) * dev_table[ dev_number ].reclen ) );
- bwb_error( bwb_ebuf );
- #else
- bwb_error( err_dev );
- #endif
- return bwb_zline( l );
- }
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_put(): ready to write to file, buffer <%lXh>",
- (long) dev_table[ dev_number ].buffer );
- bwb_debug( bwb_ebuf );
- prn_xprintf( stderr, "Buffer: <" );
- #endif
-
- /* 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 ],
- dev_table[ dev_number ].cfp );
- #if INTENSIVE_DEBUG
- xputc( stderr, dev_table[ dev_number ].buffer[ i ] );
- #endif
- ++( dev_table[ dev_number ].loc );
- }
-
- #if INTENSIVE_DEBUG
- prn_xprintf( stderr, ">\n" );
- sprintf( bwb_ebuf, "in bwb_put(): write to file complete" );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* flush the buffer */
-
- dio_flush( dev_number );
-
- /* increment (or reset) the current record */
-
- dev_table[ dev_number ].next_record = rec_number + 1;
-
- return bwb_zline( l );
-
- }
-
- /***************************************************************
-
- FUNCTION: dio_flush()
-
- DESCRIPTION: This C function flushes the random-access
- buffer associated with file dev_number.
-
- ***************************************************************/
-
- #if ANSI_C
- static int
- dio_flush( int dev_number )
- #else
- static int
- dio_flush( dev_number )
- int dev_number;
- #endif
- {
- register int n;
-
- if ( dev_table[ dev_number ].mode != DEVMODE_RANDOM )
- {
- #if PROG_ERRORS
- sprintf( bwb_ebuf, "in dio_flush(): only random-access buffers can be flushed" );
- bwb_error( bwb_ebuf );
- #else
- bwb_error( err_dev );
- #endif
- }
-
- /* fill buffer with blanks (or 'X' for test) */
-
- for ( n = 0; n < dev_table[ req_devnumber ].reclen; ++n )
- {
- dev_table[ req_devnumber ].buffer[ n ] = RANDOM_FILLCHAR;
- }
-
- return TRUE;
-
- }
-
- #endif /* COMMON_CMDS */
-
|