|
- /***************************************************************
-
- bwb_var.c Variable-Handling 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). */
- /* */
- /* Those additionally marked with "DD" were at the suggestion of */
- /* Dale DePriest (daled@cadence.com). */
- /* */
- /* Version 3.00 by Howard Wulf, AF5NE */
- /* */
- /* Version 3.10 by Howard Wulf, AF5NE */
- /* */
- /* Version 3.20 by Howard Wulf, AF5NE */
- /* */
- /*---------------------------------------------------------------*/
-
-
-
- #include "bwbasic.h"
-
-
- /* Prototypes for functions visible to this file only */
-
- static void clear_virtual (VirtualType * Z);
- static void clear_virtual_by_variable (VariableType * Variable);
- static int dim_check (VariableType * variable);
- static size_t dim_unit (VariableType * v, int *pp);
- static LineType *dio_lrset (LineType * l, int rset);
- static void field_clear (FieldType * Field);
- static FieldType *field_new (void);
- static VirtualType *find_virtual_by_variable (VariableType * Variable);
- static LineType *internal_swap (LineType * l);
- static VariableType *mat_islocal (char *buffer);
- static VirtualType *new_virtual (void);
- static int var_defx (LineType * l, int TypeCode);
- static VariableType *var_islocal (char *buffer, int dimensions);
- static void var_link_new_variable (VariableType * v);
-
- extern int
- var_init (void)
- {
- assert( My != NULL );
-
- My->VariableHead = NULL;
-
- return TRUE;
- }
-
- extern LineType *
- bwb_COMMON (LineType * l)
- {
- /*
- SYNTAX: COMMON scalar
- SYNTAX: COMMON matrix( dimnesions ) ' COMMON A(1), B(2), C(3)
- SYNTAX: COMMON matrix( [, [,]] ) ' COMMON A(), B(,), C(,,)
- */
-
- assert (l != NULL);
-
- do
- {
- int dimensions;
- VariableType *variable;
- char varname[NameLengthMax + 1];
-
- dimensions = 0;
- /* get variable name and find variable */
- if (line_read_varname (l, varname) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (line_skip_LparenChar (l))
- {
- line_skip_spaces (l); /* keep this */
- if (bwb_isdigit (l->buffer[l->position]))
- {
- /* COMMON A(3) : DIM A( 5, 10, 20 ) */
- if (line_read_integer_expression (l, &dimensions) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- }
- else
- {
- /* COMMON A(,,) : DIM A( 5, 10, 20 ) */
- dimensions++;
- while (line_skip_seperator (l));
- {
- dimensions++;
- }
- }
- if (line_skip_RparenChar (l) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- }
- if ((variable = var_find (varname, dimensions, TRUE)) == NULL)
- {
- WARN_VARIABLE_NOT_DECLARED;
- return (l);
- }
-
- /* mark as COMMON */
- variable->VariableFlags |= VARIABLE_COMMON;
- }
- while (line_skip_seperator (l));
-
- return (l);
- }
-
- extern LineType *
- bwb_ERASE (LineType * l)
- {
- /*
- SYNTAX: ERASE variable [, ...] ' ERASE A, B, C
- */
-
- assert (l != NULL);
- assert( My != NULL );
-
- do
- {
- char varname[NameLengthMax + 1];
-
- /* get variable name and find variable */
-
- if (line_read_varname (l, varname))
- {
- /* erase all matching SCALAR and ARRAY variables */
- int dimensions;
-
- for (dimensions = 0; dimensions < MAX_DIMS; dimensions++)
- {
- VariableType *variable;
-
- variable = var_find (varname, dimensions, FALSE);
- if (variable != NULL)
- {
- /* found a variable */
- VariableType *p; /* previous variable in linked list */
-
- /* find then previous variable in chain */
- if (variable == My->VariableHead)
- {
- /* free head */
- My->VariableHead = variable->next;
- variable->next = NULL;
- var_free (variable);
- }
- else
- {
- /* free tail */
- for (p = My->VariableHead; p != NULL && p->next != variable;
- p = p->next)
- {
- ;
- }
- if (p == NULL)
- {
- /* this should never happen */
- WARN_INTERNAL_ERROR;
- return NULL;
- }
- if (p->next != variable)
- {
- /* this should never happen */
- WARN_INTERNAL_ERROR;
- return NULL;
- }
- /* reassign linkage */
- p->next = variable->next;
- variable->next = NULL;
- var_free (variable);
- }
- }
- }
- }
- }
- while (line_skip_seperator (l));
- return (l);
- }
-
- static LineType *
- internal_swap (LineType * l)
- {
- VariableType *lhs;
- VariableType *rhs;
-
- assert (l != NULL);
-
- if (line_skip_LparenChar (l))
- {
- /* optional */
- }
-
- /* get left variable */
- if ((lhs = line_read_scalar (l)) == NULL)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
-
- /* get required comma */
- if (line_skip_seperator (l) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
-
- /* get right variable */
- if ((rhs = line_read_scalar (l)) == NULL)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
-
- if (line_skip_RparenChar (l))
- {
- /* optional */
- }
-
- /* check to be sure that both variables are compatible */
- if (VAR_IS_STRING (rhs) != VAR_IS_STRING (lhs))
- {
- WARN_TYPE_MISMATCH;
- return (l);
- }
-
- /* swap the values */
- {
- VariantType L;
- VariantType R;
- CLEAR_VARIANT (&L);
- CLEAR_VARIANT (&R);
-
- if (var_get (lhs, &L) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (var_get (rhs, &R) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
-
- if (var_set (lhs, &R) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (var_set (rhs, &L) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- }
- /* return */
- return (l);
- }
-
- extern LineType *
- bwb_EXCHANGE (LineType * l)
- {
- /*
- SYNTAX: EXCHANGE variable, variable
- SYNTAX: EXCHANGE ( variable, variable )
- */
-
- assert (l != NULL);
- return internal_swap (l);
- }
-
-
-
- extern LineType *
- bwb_SWAP (LineType * l)
- {
- /*
- SYNTAX: SWAP variable, variable
- SYNTAX: SWAP ( variable, variable )
- */
-
- assert (l != NULL);
- return internal_swap (l);
- }
-
- extern VariableType *
- var_free (VariableType * variable)
- {
- /*
- Release all the memory associated with a specific variable.
- This function returns NULL, so you can use it like this:
- variable = var_new(...);
- ...
- variable = var_free( variable );
- */
-
-
- if (variable != NULL)
- {
- if (variable->next != NULL)
- {
- /* This allows variable chains to be easily released. */
- variable->next = var_free (variable->next);
- }
- /* cleanup this variable */
- field_free_variable (variable);
- clear_virtual_by_variable (variable);
- if (VAR_IS_STRING (variable))
- {
- if (variable->Value.String != NULL)
- {
- int j;
- for (j = 0; j < variable->array_units; j++)
- {
- if (variable->Value.String[j].sbuffer != NULL)
- {
- free (variable->Value.String[j].sbuffer);
- }
- variable->Value.String[j].length = 0;
- }
- free (variable->Value.String);
- variable->Value.String = NULL;
- }
- }
- else
- {
- if (variable->Value.Number != NULL)
- {
- free (variable->Value.Number);
- variable->Value.Number = NULL;
- }
- }
- free (variable);
- }
- return NULL;
- }
-
- extern void
- var_CLEAR (void)
- {
- /*
- free all variables except PRESET
- */
- VariableType *variable;
- assert( My != NULL );
-
-
- for (variable = My->VariableHead; variable != NULL;)
- {
- if (variable->VariableFlags & VARIABLE_PRESET)
- {
- /* keep */
- variable = variable->next;
- }
- else if (variable == My->VariableHead)
- {
- /* free head */
- My->VariableHead = variable->next;
- variable->next = NULL;
- var_free (variable);
- variable = My->VariableHead;
- }
- else
- {
- /* free tail */
- VariableType *z;
- z = variable->next;
- variable->next = NULL;
- var_free (variable);
- variable = z;
- }
- }
- }
-
- extern LineType *
- bwb_CLEAR (LineType * l)
- {
- /*
- SYNTAX: CLEAR
- */
-
- assert (l != NULL);
- var_CLEAR ();
- line_skip_eol (l);
- return (l);
- }
-
-
- LineType *
- bwb_CLR (LineType * l)
- {
-
- assert (l != NULL);
- return bwb_CLEAR (l);
- }
-
- /***********************************************************
-
- FUNCTION: var_delcvars()
-
- DESCRIPTION: This function deletes all variables
- in memory except those previously marked
- as common.
-
- ***********************************************************/
-
- int
- var_delcvars (void)
- {
- VariableType *v;
-
- assert( My != NULL );
-
- for (v = My->VariableHead; v != NULL;)
- {
- if (v->VariableFlags & VARIABLE_PRESET)
- {
- /* keep */
- v = v->next;
- }
- else if (v->VariableFlags & VARIABLE_COMMON)
- {
- /* keep */
- v = v->next;
- }
- else if (v == My->VariableHead)
- {
- /* free head */
- My->VariableHead = v->next;
- v->next = NULL;
- var_free (v);
- v = My->VariableHead;
- }
- else
- {
- /* free tail */
- VariableType *z; /* next variable */
-
- z = v->next;
- v->next = NULL;
- var_free (v);
- v = z;
- }
- }
- return TRUE;
- }
-
- /***********************************************************
-
- 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
-
- ***********************************************************/
-
- LineType *
- bwb_MID4 (LineType * l)
- {
- /* MID$( target$, start% [ , length% ] ) = source$ */
- VariableType *variable;
- VariantType target;
- int start;
- int length;
- VariantType source;
- int maxlen;
-
- assert (l != NULL);
-
- CLEAR_VARIANT (&source);
- CLEAR_VARIANT (&target);
- start = 0;
- length = 0;
- maxlen = 0;
- if (line_skip_LparenChar (l) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if ((variable = line_read_scalar (l)) == NULL)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (VAR_IS_STRING (variable))
- {
- /* OK */
- }
- else
- {
- /* ERROR */
- WARN_TYPE_MISMATCH;
- return (l);
- }
- if (var_get (variable, &target) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (target.VariantTypeCode != StringTypeCode)
- {
- WARN_TYPE_MISMATCH;
- return (l);
- }
- if (line_skip_seperator (l) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (line_read_integer_expression (l, &start) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (start < 1)
- {
- WARN_ILLEGAL_FUNCTION_CALL;
- return (l);
- }
- if (start > target.Length)
- {
- WARN_ILLEGAL_FUNCTION_CALL;
- return (l);
- }
- maxlen = 1 + target.Length - start;
- if (line_skip_seperator (l))
- {
- if (line_read_integer_expression (l, &length) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (length < 0)
- {
- WARN_ILLEGAL_FUNCTION_CALL;
- return (l);
- }
- }
- else
- {
- length = -1; /* MAGIC */
- }
- if (line_skip_RparenChar (l) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- /* skip the equal sign */
- if (line_skip_EqualChar (l) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (line_read_expression (l, &source) == FALSE) /* bwb_MID4 */
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (source.VariantTypeCode != StringTypeCode)
- {
- WARN_TYPE_MISMATCH;
- return (l);
- }
- if (length == -1 /* MAGIC */ )
- {
- length = source.Length;
- }
- length = MIN (length, maxlen);
- length = MIN (length, source.Length);
- if (length < 0)
- {
- WARN_INTERNAL_ERROR;
- return (l);
- }
- if (length > 0)
- {
- int i;
-
- start--; /* BASIC to C */
- for (i = 0; i < length; i++)
- {
- target.Buffer[start + i] = source.Buffer[i];
- }
- target.Buffer[target.Length] = NulChar;
- if (var_set (variable, &target) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- }
- RELEASE_VARIANT (&source);
- RELEASE_VARIANT (&target);
- return (l);
- }
-
-
- /***********************************************************
-
- FUNCTION: bwb_ddbl()
-
- DESCRIPTION: This function implements the BASIC
- DEFDBL command.
-
- SYNTAX: DEFDBL letter[-letter](, letter[-letter])...
-
- ***********************************************************/
-
- LineType *
- bwb_DEFBYT (LineType * l)
- {
- /*
- DEFBYT letter[-letter](, letter[-letter])...
- */
-
- assert (l != NULL);
- var_defx (l, ByteTypeCode);
- return (l);
- }
-
- LineType *
- bwb_DEFCUR (LineType * l)
- {
- /*
- DEFCUR letter[-letter](, letter[-letter])...
- */
-
- assert (l != NULL);
- var_defx (l, CurrencyTypeCode);
- return (l);
- }
-
- LineType *
- bwb_DEFDBL (LineType * l)
- {
- /*
- DEFDBL letter[-letter](, letter[-letter])...
- */
-
- assert (l != NULL);
- var_defx (l, DoubleTypeCode);
- return (l);
- }
-
- /***********************************************************
-
- FUNCTION: bwb_dint()
-
- DESCRIPTION: This function implements the BASIC
- DEFINT command.
-
- SYNTAX: DEFINT letter[-letter](, letter[-letter])...
-
- ***********************************************************/
-
- LineType *
- bwb_DEFINT (LineType * l)
- {
- /*
- DEFINT letter[-letter](, letter[-letter])...
- */
-
- assert (l != NULL);
- var_defx (l, IntegerTypeCode);
- return (l);
- }
-
- LineType *
- bwb_DEFLNG (LineType * l)
- {
- /*
- DEFLNG letter[-letter](, letter[-letter])...
- */
-
- assert (l != NULL);
- var_defx (l, LongTypeCode);
- return (l);
- }
-
- /***********************************************************
-
- FUNCTION: bwb_dsng()
-
- DESCRIPTION: This function implements the BASIC
- DEFSNG command.
-
- SYNTAX: DEFSNG letter[-letter](, letter[-letter])...
-
- ***********************************************************/
-
- LineType *
- bwb_DEFSNG (LineType * l)
- {
- /*
- DEFSNG letter[-letter](, letter[-letter])...
- */
-
- assert (l != NULL);
- var_defx (l, SingleTypeCode);
- return (l);
- }
-
- /***********************************************************
-
- FUNCTION: bwb_dstr()
-
- DESCRIPTION: This function implements the BASIC
- DEFSTR command.
-
- SYNTAX: DEFSTR letter[-letter](, letter[-letter])...
-
- ***********************************************************/
-
- LineType *
- bwb_DEFSTR (LineType * l)
- {
- /*
- DEFSTR letter[-letter](, letter[-letter])...
- */
-
- assert (l != NULL);
- var_defx (l, StringTypeCode);
- return (l);
- }
-
- LineType *
- bwb_TEXT (LineType * l)
- {
- /*
- TEXT letter[-letter](, letter[-letter])...
- */
-
- assert (l != NULL);
- var_defx (l, StringTypeCode);
- return (l);
- }
-
- LineType *
- bwb_TRACE (LineType * l)
- {
- assert (l != NULL);
-
- return bwb_TRACE_ON(l);
- }
-
- LineType *
- bwb_TRACE_ON (LineType * l)
- {
- assert (l != NULL);
- assert( My != NULL );
- assert( My->SYSOUT != NULL );
- assert( My->SYSOUT->cfp != NULL );
-
- fprintf (My->SYSOUT->cfp, "Trace is ON\n");
- ResetConsoleColumn ();
- My->IsTraceOn = TRUE;
-
- return (l);
- }
-
- LineType *
- bwb_TRACE_OFF (LineType * l)
- {
-
- assert (l != NULL);
- assert( My != NULL );
- assert( My->SYSOUT != NULL );
- assert( My->SYSOUT->cfp != NULL );
-
- fprintf (My->SYSOUT->cfp, "Trace is OFF\n");
- ResetConsoleColumn ();
- My->IsTraceOn = FALSE;
-
- return (l);
- }
-
- int
- VarTypeIndex (char C)
- {
-
- switch (C)
- {
- case 'A':
- return 0;
- case 'B':
- return 1;
- case 'C':
- return 2;
- case 'D':
- return 3;
- case 'E':
- return 4;
- case 'F':
- return 5;
- case 'G':
- return 6;
- case 'H':
- return 7;
- case 'I':
- return 8;
- case 'J':
- return 9;
- case 'K':
- return 10;
- case 'L':
- return 11;
- case 'M':
- return 12;
- case 'N':
- return 13;
- case 'O':
- return 14;
- case 'P':
- return 15;
- case 'Q':
- return 16;
- case 'R':
- return 17;
- case 'S':
- return 18;
- case 'T':
- return 19;
- case 'U':
- return 20;
- case 'V':
- return 21;
- case 'W':
- return 22;
- case 'X':
- return 23;
- case 'Y':
- return 24;
- case 'Z':
- return 25;
- case 'a':
- return 0;
- case 'b':
- return 1;
- case 'c':
- return 2;
- case 'd':
- return 3;
- case 'e':
- return 4;
- case 'f':
- return 5;
- case 'g':
- return 6;
- case 'h':
- return 7;
- case 'i':
- return 8;
- case 'j':
- return 9;
- case 'k':
- return 10;
- case 'l':
- return 11;
- case 'm':
- return 12;
- case 'n':
- return 13;
- case 'o':
- return 14;
- case 'p':
- return 15;
- case 'q':
- return 16;
- case 'r':
- return 17;
- case 's':
- return 18;
- case 't':
- return 19;
- case 'u':
- return 20;
- case 'v':
- return 21;
- case 'w':
- return 22;
- case 'x':
- return 23;
- case 'y':
- return 24;
- case 'z':
- return 25;
- }
- return -1;
- }
-
- /***********************************************************
-
- Function: var_defx()
-
- DESCRIPTION: This function is a generalized DEFxxx handler.
-
- ***********************************************************/
-
- static int
- var_defx (LineType * l, int TypeCode)
- {
- /*
- DEFxxx letter[-letter](, letter[-letter])...
- */
-
- assert (l != NULL);
- assert( My != NULL );
- assert( My->DefaultVariableType != NULL );
-
- do
- {
- char firstc;
- char lastc;
- int first;
- int last;
- int c;
-
- /* find a sequence of letters for variables */
- if (line_read_letter_sequence (l, &firstc, &lastc) == FALSE)
- {
- /* DEFINT 0-9 */
- WARN_SYNTAX_ERROR;
- return FALSE;
- }
- first = VarTypeIndex (firstc);
- if (first < 0)
- {
- /* DEFINT 0-Z */
- WARN_SYNTAX_ERROR;
- return FALSE;
- }
- last = VarTypeIndex (lastc);
- if (last < 0)
- {
- /* DEFINT A-9 */
- WARN_SYNTAX_ERROR;
- return FALSE;
- }
- if (first > last)
- {
- /* DEFINT Z-A */
- WARN_SYNTAX_ERROR;
- return FALSE;
- }
- for (c = first; c <= last; c++)
- {
- My->DefaultVariableType[c] = TypeCode; /* var_defx */
- }
- }
- while (line_skip_seperator (l));
-
- return TRUE;
-
- }
-
- /***************************************************************
-
- FUNCTION: var_find()
-
- DESCRIPTION: This C function attempts to find a variable
- name matching the argument in buffer. If
- it fails to find a matching name, it
- sets up a new variable with that name.
-
- ***************************************************************/
-
- VariableType *
- mat_find (char *name)
- {
- /*
- similar to var_find, but returns the first matrix found
- */
- VariableType *v;
- assert( My != NULL );
-
-
- /* check for NULL variable name */
- if (name == NULL)
- {
- WARN_INTERNAL_ERROR;
- return NULL;
- }
- if (is_empty_string (name))
- {
- WARN_SYNTAX_ERROR;
- return NULL;
- }
- /* check for a local variable at this EXEC level */
-
- v = mat_islocal (name);
- if (v != NULL)
- {
- return v;
- }
- /* now run through the global variable list and try to find a match */
- for (v = My->VariableHead; v != NULL; v = v->next)
- {
- assert( v != NULL );
- if (v->dimensions > 0)
- {
- if (bwb_stricmp (v->name, name) == 0)
- {
- return v;
- }
- }
- }
- return NULL;
- }
-
- VariableType *
- var_find (char *name, int dimensions, int IsImplicit)
- {
- VariableType *v;
- int n;
-
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
- assert( My->DefaultVariableType != NULL );
-
- /* check for NULL variable name */
- if (name == NULL)
- {
- WARN_INTERNAL_ERROR;
- return NULL;
- }
- if (is_empty_string (name))
- {
- WARN_SYNTAX_ERROR;
- return NULL;
- }
- if (dimensions < 0)
- {
- WARN_INTERNAL_ERROR;
- return NULL;
- }
-
- /* check for a local variable at this EXEC level */
-
- v = var_islocal (name, dimensions);
- if (v != NULL)
- {
- return v;
- }
- /* now run through the global variable list and try to find a match */
- for (v = My->VariableHead; v != NULL; v = v->next)
- {
- assert( v != NULL );
- if (v->dimensions == dimensions)
- {
- if (bwb_stricmp (v->name, name) == 0)
- {
- return v;
- }
- }
- }
- if (IsImplicit == FALSE)
- {
- return NULL;
- }
- if (My->CurrentVersion->OptionFlags & OPTION_EXPLICIT_ON)
- {
- /* NO implicit creation - all variables must be created via DIM */
- WARN_VARIABLE_NOT_DECLARED;
- return NULL;
- }
- if (My->CurrentVersion->OptionFlags & OPTION_STRICT_ON)
- {
- if (dimensions > 0)
- {
- /* Implicit ARRAY is not allowed */
- WARN_VARIABLE_NOT_DECLARED;
- return NULL;
- }
- }
-
- /* this is a IMPLICIT variable, so initialize it... */
-
- /* initialize new variable */
- if ((v = (VariableType *) calloc (1, sizeof (VariableType))) == NULL)
- {
- WARN_OUT_OF_MEMORY;
- return NULL;
- }
-
- /* copy the name into the appropriate structure */
-
- assert( v != NULL );
- bwb_strcpy (v->name, name);
-
- /* determine variable TypeCode */
- v->VariableTypeCode = var_nametype (name);
- if (v->VariableTypeCode == NulChar)
- {
- /* variable name has no declared TypeCode */
- n = VarTypeIndex (name[0]);
- if (n < 0)
- {
- v->VariableTypeCode = DoubleTypeCode; /* default */
- }
- else
- {
- v->VariableTypeCode = My->DefaultVariableType[n];
- }
- }
- v->VariableFlags = 0;
- v->dimensions = dimensions;
- v->array_units = 1;
- for (n = 0; n < v->dimensions; n++)
- {
- v->LBOUND[n] = My->CurrentVersion->OptionBaseInteger; /* implicit lower bound */
- v->UBOUND[n] = 10; /* implicit upper bound */
- if (v->UBOUND[n] < v->LBOUND[n])
- {
- WARN_SUBSCRIPT_OUT_OF_RANGE;
- return NULL;
- }
- v->VINDEX[n] = v->LBOUND[n];
- v->array_units *= v->UBOUND[n] - v->LBOUND[n] + 1;
- }
-
- /* assign array memory */
- if (VAR_IS_STRING (v))
- {
- if ((v->Value.String =
- (StringType *) calloc (v->array_units, sizeof (StringType))) == NULL)
- {
- WARN_OUT_OF_MEMORY;
- return NULL;
- }
- }
- else
- {
- if ((v->Value.Number =
- (DoubleType *) calloc (v->array_units, sizeof (DoubleType))) == NULL)
- {
- WARN_OUT_OF_MEMORY;
- return NULL;
- }
- }
-
- /* insert variable at the beginning of the variable chain */
- v->next = My->VariableHead;
- My->VariableHead = v;
- return v;
- }
-
- /***************************************************************
-
- FUNCTION: var_new()
-
- DESCRIPTION: This function assigns memory for a new variable.
-
- ***************************************************************/
-
- VariableType *
- var_new (char *name, char TypeCode)
- {
- VariableType *v;
-
-
- /* get memory for new variable */
-
- if (name == NULL)
- {
- WARN_INTERNAL_ERROR;
- return NULL;
- }
- if (is_empty_string (name))
- {
- WARN_SYNTAX_ERROR;
- return NULL;
- }
- if ((v = (VariableType *) calloc (1, sizeof (VariableType))) == NULL)
- {
- WARN_OUT_OF_MEMORY;
- return NULL;
- }
- /* copy the name into the appropriate structure */
-
- assert( v != NULL );
- bwb_strcpy (v->name, name);
-
- /* set memory in the new variable */
- var_make (v, TypeCode);
-
- /* and return */
-
- return v;
-
- }
-
-
- /***************************************************************
-
- FUNCTION: bwb_dim()
-
- DESCRIPTION: This function implements the BASIC DIM
- statement, allocating memory for a
- dimensioned array of variables.
-
- SYNTAX: DIM variable(elements...)[,variable(elements...)]
-
- ***************************************************************/
-
- static void
- var_link_new_variable (VariableType * v)
- {
- /*
- We are called by DIM, so this is an explicitly created variable.
- There are only two possibilities:
- 1. We are a LOCAL variable of a SUB or FUNCTION.
- 2. We are a GLOBAL variable.
- */
-
- assert (v != NULL);
- assert( My != NULL );
-
- if (My->StackHead != NULL)
- {
- StackType *StackItem;
- for (StackItem = My->StackHead; StackItem != NULL;
- StackItem = StackItem->next)
- {
- if (StackItem->LoopTopLine != NULL)
- {
- switch (StackItem->LoopTopLine->cmdnum)
- {
- case C_FUNCTION:
- case C_SUB:
- /* we have found a FUNCTION or SUB boundary, must be LOCAL */
- v->next = StackItem->local_variable;
- StackItem->local_variable = v;
- return;
- /* break; */
- }
- }
- }
- }
- /* no FUNCTION or SUB on the stack, must be GLOBAL */
- v->next = My->VariableHead;
- My->VariableHead = v;
- }
-
-
- static VirtualType *
- new_virtual (void)
- {
- VirtualType *Z;
- assert( My != NULL );
-
-
- /* look for an empty slot */
- for (Z = My->VirtualHead; Z != NULL; Z = Z->next)
- {
- if (Z->Variable == NULL)
- {
- /* FOUND */
- return Z;
- }
- }
- /* NOT FOUND */
- if ((Z = (VirtualType *) calloc (1, sizeof (VirtualType))) == NULL)
- {
- WARN_OUT_OF_MEMORY;
- return NULL;
- }
- Z->next = My->VirtualHead;
- My->VirtualHead = Z;
- return Z;
- }
- static void
- clear_virtual (VirtualType * Z)
- {
-
- assert (Z != NULL);
-
- Z->Variable = NULL;
- Z->FileNumber = 0;
- Z->FileOffset = 0;
- Z->FileLength = 0;
- }
- static void
- clear_virtual_by_variable (VariableType * Variable)
- {
- VirtualType *Z;
-
- assert (Variable != NULL);
- assert( My != NULL );
-
- for (Z = My->VirtualHead; Z != NULL; Z = Z->next)
- {
- if (Z->Variable == Variable)
- {
- /* FOUND */
- clear_virtual (Z);
- }
- }
- }
- extern void
- clear_virtual_by_file (int FileNumber)
- {
- /* called by file_clear() */
- VirtualType *Z;
-
- assert( My != NULL );
-
- for (Z = My->VirtualHead; Z != NULL; Z = Z->next)
- {
- if (Z->FileNumber == FileNumber)
- {
- /* FOUND */
- clear_virtual (Z);
- }
- }
- }
- static VirtualType *
- find_virtual_by_variable (VariableType * Variable)
- {
- VirtualType *Z;
-
- assert (Variable != NULL);
- assert( My != NULL );
-
- for (Z = My->VirtualHead; Z != NULL; Z = Z->next)
- {
- if (Z->Variable == Variable)
- {
- /* FOUND */
- return Z;
- }
- }
- /* NOT FOUND */
- return NULL;
- }
-
- LineType *
- bwb_LOCAL (LineType * l)
- {
- /* only supported inside a FUNCTION or SUB */
-
- assert (l != NULL);
- return bwb_DIM (l);
- }
-
- LineType *
- bwb_DIM (LineType * l)
- {
- int FileNumber; /* the file might not be OPEN when the variable is declared */
- size_t FileOffset; /* from beginning of file */
- int FileLength; /* sizeof( DoubleType ) or Fixed String Length */
-
- assert (l != NULL);
- assert( My != NULL );
- assert( My->DefaultVariableType != NULL );
-
-
- FileNumber = 0;
- FileOffset = 0;
- FileLength = 0;
- if (line_skip_FilenumChar (l))
- {
- /* DIM # filenum , ... */
- if (line_read_integer_expression (l, &FileNumber) == FALSE)
- {
- WARN_BAD_FILE_NUMBER;
- return (l);
- }
- if (FileNumber <= 0)
- {
- WARN_BAD_FILE_NUMBER;
- return (l);
- }
- if (line_skip_seperator (l) == FALSE)
- {
- WARN_BAD_FILE_NUMBER;
- return (l);
- }
- FileOffset = 0;
- FileLength = 0;
- }
-
- do
- {
- VariableType *v;
- int n;
- int dimensions;
- int LBOUND[MAX_DIMS];
- int UBOUND[MAX_DIMS];
- char TypeCode;
- char varname[NameLengthMax + 1];
-
-
- /* Get variable name */
- if (line_read_varname (l, varname) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
-
- /* read parameters */
- dimensions = 0;
- if (line_peek_LparenChar (l))
- {
- if (line_read_array_redim (l, &dimensions, LBOUND, UBOUND) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- /* check array dimensions */
- for (n = 0; n < dimensions; n++)
- {
- if (UBOUND[n] < LBOUND[n])
- {
- WARN_SUBSCRIPT_OUT_OF_RANGE;
- return (l);
- }
- }
- }
-
- /* determine variable TypeCode */
- TypeCode = var_nametype (varname);
- if (TypeCode == NulChar)
- {
- /* variable has no explicit TypeCode char */
- TypeCode = line_read_type_declaration (l); /* AS DOUBLE and so on */
- if (TypeCode == NulChar)
- {
- /* variable has no declared TypeCode */
- int i;
- i = VarTypeIndex (varname[0]);
- if (i < 0)
- {
- TypeCode = DoubleTypeCode; /* default */
- }
- else
- {
- TypeCode = My->DefaultVariableType[i];
- }
- }
- }
-
- switch (TypeCode)
- {
- case ByteTypeCode:
- /* DIM # file_num , var_name AS BYTE */
- FileLength = sizeof (ByteType);
- break;
- case IntegerTypeCode:
- /* DIM # file_num , var_name AS INTEGER */
- FileLength = sizeof (IntegerType);
- break;
- case LongTypeCode:
- /* DIM # file_num , var_name AS LONG */
- FileLength = sizeof (LongType);
- break;
- case CurrencyTypeCode:
- /* DIM # file_num , var_name AS CURRENCY */
- FileLength = sizeof (CurrencyType);
- break;
- case SingleTypeCode:
- /* DIM # file_num , var_name AS SINGLE */
- FileLength = sizeof (SingleType);
- break;
- case DoubleTypeCode:
- /* DIM # file_num , var_name AS DOUBLE */
- FileLength = sizeof (DoubleType);
- break;
- case StringTypeCode:
- /* DIM # file_num , var_name AS STRING * fixed_length */
-
- FileLength = 16; /* default */
- if (line_skip_StarChar (l) || line_skip_EqualChar (l))
- {
- /* optional fixed length */
- if (line_read_integer_expression (l, &FileLength) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (FileLength <= 0)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (FileLength > MAXLEN)
- {
- WARN_STRING_TOO_LONG; /* bwb_DIM */
- FileLength = MAXLEN;
- }
- }
- break;
- default:
- {
- WARN_INTERNAL_ERROR;
- return (l);
- }
- }
-
- v = var_find (varname, dimensions, FALSE);
- if (v == NULL)
- {
- /* a new variable */
- if ((v = (VariableType *) calloc (1, sizeof (VariableType))) == NULL)
- {
- WARN_OUT_OF_MEMORY;
- return (l);
- }
- bwb_strcpy (v->name, varname);
- v->VariableTypeCode = TypeCode;
- /* assign array dimensions */
- v->dimensions = dimensions;
- for (n = 0; n < dimensions; n++)
- {
- v->LBOUND[n] = LBOUND[n];
- v->UBOUND[n] = UBOUND[n];
- }
- /* assign initial array position */
- for (n = 0; n < dimensions; n++)
- {
- v->VINDEX[n] = v->LBOUND[n];
- }
- /* calculate the array size */
- v->array_units = 1;
- for (n = 0; n < dimensions; n++)
- {
- v->array_units *= v->UBOUND[n] - v->LBOUND[n] + 1;
- }
- /* assign array memory */
-
- if (FileNumber > 0)
- {
- /* the new variable is VIRTUAL */
- v->VariableFlags = VARIABLE_VIRTUAL;
- /* if( TRUE ) */
- {
- /* OK */
- VirtualType *Z;
- Z = find_virtual_by_variable (v);
- if (Z == NULL)
- {
- Z = new_virtual ();
- if (Z == NULL)
- {
- WARN_OUT_OF_MEMORY;
- return (l);
- }
- Z->Variable = v;
- }
- /* update file information */
- Z->FileNumber = FileNumber;
- Z->FileOffset = FileOffset;
- Z->FileLength = FileLength;
- FileOffset += FileLength * v->array_units;
- }
- }
- else if (VAR_IS_STRING (v))
- {
- if ((v->Value.String =
- (StringType *) calloc (v->array_units,
- sizeof (StringType))) == NULL)
- {
- WARN_OUT_OF_MEMORY;
- return (l);
- }
- }
- else
- {
- if ((v->Value.Number =
- (DoubleType *) calloc (v->array_units,
- sizeof (DoubleType))) == NULL)
- {
- WARN_OUT_OF_MEMORY;
- return (l);
- }
- }
- /* set place at beginning of variable chain */
- var_link_new_variable (v);
-
- /* end of conditional for new variable */
- }
- else
- {
- /* old variable */
- if (v->VariableTypeCode != TypeCode)
- {
- WARN_TYPE_MISMATCH;
- return (l);
- }
-
- /* check to be sure the number of dimensions is the same */
- if (v->dimensions != dimensions)
- {
- WARN_REDIMENSION_ARRAY;
- return (l);
- }
- /* check to be sure sizes for each dimension are the same */
- for (n = 0; n < dimensions; n++)
- {
- if (v->LBOUND[n] != LBOUND[n])
- {
- WARN_REDIMENSION_ARRAY;
- return (l);
- }
- if (v->UBOUND[n] != UBOUND[n])
- {
- WARN_REDIMENSION_ARRAY;
- return (l);
- }
- }
- if (FileNumber > 0)
- {
- /* the existing variable MUST be Virtual */
- if (v->VariableFlags & VARIABLE_VIRTUAL)
- {
- /* OK */
- VirtualType *Z;
- Z = find_virtual_by_variable (v);
- if (Z == NULL)
- {
- Z = new_virtual ();
- if (Z == NULL)
- {
- WARN_OUT_OF_MEMORY;
- return (l);
- }
- Z->Variable = v;
- }
- /* update file information */
- Z->FileNumber = FileNumber;
- Z->FileOffset = FileOffset;
- Z->FileLength = FileLength;
- FileOffset += FileLength * v->array_units;
- }
- else
- {
- /* the existing variable is NOT virtual */
- WARN_TYPE_MISMATCH;
- return (l);
- }
- }
- else
- {
- /* the existing variable CANNOT be Virtual */
- if (v->VariableFlags & VARIABLE_VIRTUAL)
- {
- /* the existing variable IS virtual */
- WARN_TYPE_MISMATCH;
- return (l);
- }
- else
- {
- /* OK */
- }
- }
- /* end of conditional for old variable */
- }
-
- }
- while (line_skip_seperator (l));
-
- /* return */
- return (l);
- }
-
-
-
-
- /***************************************************************
-
- FUNCTION: dim_unit()
-
- DESCRIPTION: This function calculates the unit
- position for an array.
-
- ***************************************************************/
-
- static size_t
- dim_unit (VariableType * v, int *pp)
- {
- size_t r;
- size_t b;
- int n;
-
- assert (v != NULL);
- assert (pp != NULL);
-
- /* Calculate and return the address of the dimensioned array */
-
- /* Check EACH dimension for out-of-bounds, AND check correct number
- * of dimensions. NBS_P076_0250 errors correctly. */
-
- /*
- Ux = Upper bound of dimension
- Lx = Lower bound of dimension
- Ix = Selected idex in dimension
-
- dimensions b
- 0 1
- 1 b0 * ( U0 - L0 + 1 )
- 2 b1 * ( U1 - L1 + 1 )
- 3 b2 * ( U2 - L2 + 1 )
-
-
- dimensions r
- 0 0
- 1 r0 + ( I0 - L0 ) * b0
- 2 r1 + ( I1 - L1 ) * b1
- 3 r2 + ( I2 - L2 ) * b2
-
- */
-
- r = 0;
- b = 1;
- for (n = 0; n < v->dimensions; n++)
- {
- if (pp[n] < v->LBOUND[n] || pp[n] > v->UBOUND[n])
- {
- WARN_SUBSCRIPT_OUT_OF_RANGE;
- return 0;
- }
- r += b * (pp[n] - v->LBOUND[n]);
- b *= v->UBOUND[n] - v->LBOUND[n] + 1;
- }
-
-
- if (r > v->array_units)
- {
- WARN_SUBSCRIPT_OUT_OF_RANGE;
- return 0;
- }
- return r;
-
- }
-
-
- /***************************************************************
-
- FUNCTION: bwb_option()
-
- DESCRIPTION: This function implements the BASIC OPTION
- BASE statement, designating the base (1 or
- 0) for addressing DIM arrays.
-
- SYNTAX: OPTION BASE number
-
- ***************************************************************/
-
- void
- OptionVersionSet (int i)
- {
- assert( i >= 0 && i < NUM_VERSIONS );
- assert( My != NULL );
-
- My->CurrentVersion = &bwb_vertable[i];
- }
-
- LineType *
- bwb_OPTION (LineType * l)
- {
- assert (l != NULL);
-
- WARN_SYNTAX_ERROR;
- return (l);
- }
-
- LineType *
- bwb_OPTION_ANGLE (LineType * l)
- {
- assert (l != NULL);
-
- WARN_SYNTAX_ERROR;
- return (l);
- }
-
- LineType *
- bwb_OPTION_ANGLE_DEGREES (LineType * l)
- {
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- /* OPTION ANGLE DEGREES */
- My->CurrentVersion->OptionFlags |= OPTION_ANGLE_DEGREES;
- My->CurrentVersion->OptionFlags &= ~OPTION_ANGLE_GRADIANS;
- return (l);
- }
-
- LineType *
- bwb_OPTION_ANGLE_GRADIANS (LineType * l)
- {
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- /* OPTION ANGLE GRADIANS */
- My->CurrentVersion->OptionFlags &= ~OPTION_ANGLE_DEGREES;
- My->CurrentVersion->OptionFlags |= OPTION_ANGLE_GRADIANS;
- return (l);
- }
-
- LineType *
- bwb_OPTION_ANGLE_RADIANS (LineType * l)
- {
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- /* OPTION ANGLE RADIANS */
- My->CurrentVersion->OptionFlags &= ~OPTION_ANGLE_DEGREES;
- My->CurrentVersion->OptionFlags &= ~OPTION_ANGLE_GRADIANS;
- return (l);
- }
-
- LineType *
- bwb_OPTION_ARITHMETIC (LineType * l)
- {
- assert (l != NULL);
- WARN_SYNTAX_ERROR;
- return (l);
- }
-
- LineType *
- bwb_OPTION_ARITHMETIC_DECIMAL (LineType * l)
- {
- /* OPTION ARITHMETIC DECIMAL */
- assert (l != NULL);
- return (l);
- }
-
- LineType *
- bwb_OPTION_ARITHMETIC_FIXED (LineType * l)
- {
- /* OPTION ARITHMETIC FIXED */
- assert (l != NULL);
- return (l);
- }
-
- LineType *
- bwb_OPTION_ARITHMETIC_NATIVE (LineType * l)
- {
- /* OPTION ARITHMETIC NATIVE */
- assert (l != NULL);
- return (l);
- }
-
- LineType *
- bwb_OPTION_BASE (LineType * l)
- {
- /* OPTION BASE integer */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_range_integer (l,
- &(My->CurrentVersion->OptionBaseInteger),
- MININT, MAXINT);
- }
-
- LineType *
- bwb_OPTION_BUGS (LineType * l)
- {
- assert (l != NULL);
- WARN_SYNTAX_ERROR;
- return (l);
- }
-
- LineType *
- bwb_OPTION_BUGS_BOOLEAN (LineType * l)
- {
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- /* OPTION BUGS BOOLEAN */
- My->CurrentVersion->OptionFlags |= OPTION_BUGS_BOOLEAN;
- return (l);
- }
-
- LineType *
- bwb_OPTION_BUGS_ON (LineType * l)
- {
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- /* OPTION BUGS ON */
- My->CurrentVersion->OptionFlags |= OPTION_BUGS_ON;
- return (l);
- }
-
- LineType *
- bwb_OPTION_BUGS_OFF (LineType * l)
- {
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- /* OPTION BUGS OFF */
- My->CurrentVersion->OptionFlags &= ~OPTION_BUGS_ON;
- My->CurrentVersion->OptionFlags &= ~OPTION_BUGS_BOOLEAN;
- return (l);
- }
-
- LineType *
- bwb_option_punct_char (LineType * l, char *c)
- {
- /* OPTION ... char$ */
-
- assert (l != NULL);
- assert (c != NULL);
-
- {
- char *Value;
- char C;
-
- Value = NULL;
- if (line_read_string_expression (l, &Value) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (Value == NULL)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- C = Value[0];
- free (Value);
- /* OK */
- if (bwb_ispunct (C))
- {
- /* enable */
- *c = C;
- }
- else
- {
- /* disable */
- *c = NulChar;
- }
- }
- return (l);
- }
-
- LineType *
- bwb_option_range_integer (LineType * l, int *Integer, int MinVal, int MaxVal)
- {
- /* OPTION ... integer */
-
- assert (l != NULL);
- assert (Integer != NULL);
- assert (MinVal < MaxVal);
-
- {
- int Value;
-
- Value = 0;
- if (line_read_integer_expression (l, &Value) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (Value < MinVal || Value > MaxVal)
- {
- WARN_ILLEGAL_FUNCTION_CALL;
- return (l);
- }
- *Integer = Value;
- }
- return (l);
- }
-
- LineType *
- bwb_OPTION_PUNCT_COMMENT (LineType * l)
- {
- /* OPTION PUNCT COMMENT char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l, &(My->CurrentVersion->OptionCommentChar));
- }
-
- LineType *
- bwb_OPTION_COMPARE (LineType * l)
- {
- assert (l != NULL);
- WARN_SYNTAX_ERROR;
- return (l);
- }
-
- LineType *
- bwb_OPTION_COMPARE_BINARY (LineType * l)
- {
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- /* OPTION COMPARE BINARY */
- My->CurrentVersion->OptionFlags &= ~OPTION_COMPARE_TEXT;
- return (l);
- }
-
- LineType *
- bwb_OPTION_COMPARE_DATABASE (LineType * l)
- {
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- /* OPTION COMPARE DATABASE */
- My->CurrentVersion->OptionFlags |= OPTION_COMPARE_TEXT;
- return (l);
- }
-
- LineType *
- bwb_OPTION_COMPARE_TEXT (LineType * l)
- {
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- /* OPTION COMPARE TEXT */
- My->CurrentVersion->OptionFlags |= OPTION_COMPARE_TEXT;
- return (l);
- }
-
- LineType *
- bwb_OPTION_COVERAGE (LineType * l)
- {
- assert (l != NULL);
- WARN_SYNTAX_ERROR;
- return (l);
- }
-
- LineType *
- bwb_OPTION_COVERAGE_ON (LineType * l)
- {
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- /* OPTION COVERAGE ON */
- My->CurrentVersion->OptionFlags |= OPTION_COVERAGE_ON;
- return (l);
- }
-
- LineType *
- bwb_OPTION_COVERAGE_OFF (LineType * l)
- {
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- /* OPTION COVERAGE OFF */
- My->CurrentVersion->OptionFlags &= ~OPTION_COVERAGE_ON;
- return (l);
- }
-
- LineType *
- bwb_OPTION_DATE (LineType * l)
- {
- /* OPTION DATE format$ */
- char *Value;
-
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
-
- Value = NULL;
- if (line_read_string_expression (l, &Value) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (Value == NULL)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- /* OK */
- My->CurrentVersion->OptionDateFormat = Value;
- #if FALSE /* keep this ... */
- /*
- ** Yes, this can theoretically cause a memory leak.
- ** No, we are not going to fix it.
- ** This command is only supported in the profile.
- ** This will only execute at most once,
- ** so there is no actual memory leak.
- **
- */
- free (Value);
- #endif
- return (l);
- }
-
- LineType *
- bwb_OPTION_DIGITS (LineType * l)
- {
- int Value;
-
- assert (l != NULL);
- assert( My != NULL );
-
- /* OPTION DIGITS integer */
- Value = 0;
- if (line_read_integer_expression (l, &Value))
- {
- /* OK */
- if (Value == 0)
- {
- /* default */
- Value = SIGNIFICANT_DIGITS;
- }
- if (Value < MINIMUM_DIGITS || Value > MAXIMUM_DIGITS)
- {
- WARN_ILLEGAL_FUNCTION_CALL;
- return (l);
- }
- My->OptionDigitsInteger = Value;
- }
- return (l);
- }
-
- LineType *
- bwb_OPTION_DISABLE (LineType * l)
- {
- assert (l != NULL);
- WARN_SYNTAX_ERROR;
- return (l);
- }
-
- LineType *
- bwb_OPTION_DISABLE_COMMAND (LineType * l)
- {
- /* OPTION DISABLE COMMAND name$ */
- int IsFound;
- char *Value;
-
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
-
- IsFound = FALSE;
- Value = NULL;
-
- /* Get COMMAND */
- if (line_read_string_expression (l, &Value) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (Value == NULL)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- /* OK */
- {
- /* Name */
- int i;
- for (i = 0; i < NUM_COMMANDS; i++)
- {
- if (bwb_stricmp (Value, IntrinsicCommandTable[i].name) == 0)
- {
- /* FOUND */
- /* DISABLE COMMAND */
- IntrinsicCommandTable[i].OptionVersionBitmask &=
- ~My->CurrentVersion->OptionVersionValue;
- IsFound = TRUE;
- }
- }
- }
- free (Value);
- if (IsFound == FALSE)
- {
- /* display warning message */
- fprintf (My->SYSOUT->cfp, "IGNORED: %s\n", l->buffer);
- ResetConsoleColumn ();
- }
- return (l);
- }
-
-
- LineType *
- bwb_OPTION_DISABLE_FUNCTION (LineType * l)
- {
- /* OPTION DISABLE FUNCTION name$ */
- int IsFound;
-
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
-
- IsFound = FALSE;
- /* Get FUNCTION */
- {
- char *Value;
-
- Value = NULL;
- if (line_read_string_expression (l, &Value) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (Value == NULL)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- /* OK */
- {
- /* Name */
- int i;
- for (i = 0; i < NUM_FUNCTIONS; i++)
- {
- if (bwb_stricmp (Value, IntrinsicFunctionTable[i].Name) == 0)
- {
- /* FOUND */
- /* DISABLE FUNCTION */
- IntrinsicFunctionTable[i].OptionVersionBitmask &=
- ~My->CurrentVersion->OptionVersionValue;
- IsFound = TRUE;
- }
- }
- }
- free (Value);
- }
- if (IsFound == FALSE)
- {
- /* display warning message */
- fprintf (My->SYSOUT->cfp, "IGNORED: %s\n", l->buffer);
- ResetConsoleColumn ();
- }
- return (l);
- }
-
- LineType *
- bwb_OPTION_EDIT (LineType * l)
- {
- /* OPTION EDIT string$ */
- char *Value;
-
- assert (l != NULL);
- assert( My != NULL );
-
- Value = NULL;
- if (line_read_string_expression (l, &Value) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (Value == NULL)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- /* OK */
- My->OptionEditString = Value;
- #if FALSE /* keep this ... */
- /*
- ** Yes, this can theoretically cause a memory leak.
- ** No, we are not going to fix it.
- ** This command is only supported in the profile.
- ** This will only execute at most once,
- ** so there is no actual memory leak.
- **
- */
- free (Value);
- #endif
- return (l);
- }
-
- LineType *
- bwb_OPTION_EXTENSION (LineType * l)
- {
- /* OPTION EXTENSION ext$ */
- char *Value;
-
- assert (l != NULL);
- assert( My != NULL );
-
- Value = NULL;
- if (line_read_string_expression (l, &Value) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (Value == NULL)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- /* OK */
- My->OptionExtensionString = Value;
- #if FALSE /* keep this ... */
- /*
- ** Yes, this can theoretically cause a memory leak.
- ** No, we are not going to fix it.
- ** This command is only supported in the profile.
- ** This command will only execute at most once,
- ** so there is no actual memory leak.
- **
- */
- free (Value);
- #endif
- return (l);
- }
-
- LineType *
- bwb_OPTION_FILES (LineType * l)
- {
- /* OPTION FILES name$ */
- char *Value;
-
- assert (l != NULL);
- assert( My != NULL );
-
-
- Value = NULL;
- if (line_read_string_expression (l, &Value) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (Value == NULL)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- /* OK */
- My->OptionFilesString = Value;
- #if FALSE /* keep this ... */
- /*
- ** Yes, this can theoretically cause a memory leak.
- ** No, we are not going to fix it.
- ** This command is only supported in the profile.
- ** This will only execute at most once,
- ** so there is no actual memory leak.
- **
- */
- free (Value);
- #endif
- return (l);
- }
-
- LineType *
- bwb_OPTION_PROMPT (LineType * l)
- {
- /* OPTION PROMPT prompt$ */
- char *Value;
-
- assert (l != NULL);
- assert( My != NULL );
-
-
- Value = NULL;
- if (line_read_string_expression (l, &Value) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (Value == NULL)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- /* OK */
- My->OptionPromptString = Value;
- #if FALSE /* keep this ... */
- /*
- ** Yes, this can theoretically cause a memory leak.
- ** No, we are not going to fix it.
- ** This command is only supported in the profile.
- ** This will only execute at most once,
- ** so there is no actual memory leak.
- **
- */
- free (Value);
- #endif
- return (l);
- }
-
- LineType *
- bwb_OPTION_RENUM (LineType * l)
- {
- /* OPTION RENUM name$ */
- char *Value;
-
- assert (l != NULL);
- assert( My != NULL );
-
-
- Value = NULL;
- if (line_read_string_expression (l, &Value) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (Value == NULL)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- /* OK */
- My->OptionRenumString = Value;
- #if FALSE /* keep this ... */
- /*
- ** Yes, this can theoretically cause a memory leak.
- ** No, we are not going to fix it.
- ** This command is only supported in the profile.
- ** This will only execute at most once,
- ** so there is no actual memory leak.
- **
- */
- free (Value);
- #endif
- return (l);
- }
-
- LineType *
- bwb_OPTION_ENABLE (LineType * l)
- {
- assert (l != NULL);
- WARN_SYNTAX_ERROR;
- return (l);
- }
-
- LineType *
- bwb_OPTION_ENABLE_COMMAND (LineType * l)
- {
- /* OPTION ENABLE COMMAND name$ */
- int IsFound;
-
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
-
- IsFound = FALSE;
- /* Get COMMAND */
- {
- char *Value;
-
- Value = NULL;
- if (line_read_string_expression (l, &Value) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (Value == NULL)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- /* OK */
- {
- /* Name */
- int i;
- for (i = 0; i < NUM_COMMANDS; i++)
- {
- if (bwb_stricmp (Value, IntrinsicCommandTable[i].name) == 0)
- {
- /* FOUND */
- /* ENABLE COMMAND */
- IntrinsicCommandTable[i].OptionVersionBitmask |=
- My->CurrentVersion->OptionVersionValue;
- IsFound = TRUE;
- }
- }
- }
- free (Value);
- }
- if (IsFound == FALSE)
- {
- /* display warning message */
- fprintf (My->SYSOUT->cfp, "IGNORED: %s\n", l->buffer);
- ResetConsoleColumn ();
- }
- return (l);
- }
-
- LineType *
- bwb_OPTION_ENABLE_FUNCTION (LineType * l)
- {
- /* OPTION ENABLE FUNCTION name$ */
- int IsFound;
-
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
-
- IsFound = FALSE;
- /* Get FUNCTION */
- {
- char *Value;
-
- Value = NULL;
- if (line_read_string_expression (l, &Value) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (Value == NULL)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- /* OK */
- {
- /* Name */
- int i;
- for (i = 0; i < NUM_FUNCTIONS; i++)
- {
- if (bwb_stricmp (Value, IntrinsicFunctionTable[i].Name) == 0)
- {
- /* FOUND */
- /* ENABLE FUNCTION */
- IntrinsicFunctionTable[i].OptionVersionBitmask |=
- My->CurrentVersion->OptionVersionValue;
- IsFound = TRUE;
- }
- }
- }
- free (Value);
- }
- if (IsFound == FALSE)
- {
- /* display warning message */
- fprintf (My->SYSOUT->cfp, "IGNORED: %s\n", l->buffer);
- ResetConsoleColumn ();
- }
- return (l);
- }
-
- LineType *
- bwb_OPTION_ERROR (LineType * l)
- {
- assert (l != NULL);
- WARN_SYNTAX_ERROR;
- return (l);
- }
-
- LineType *
- bwb_OPTION_ERROR_GOSUB (LineType * l)
- {
- /* OPTION ERROR GOSUB */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- My->CurrentVersion->OptionFlags |= OPTION_ERROR_GOSUB;
- return (l);
- }
-
- LineType *
- bwb_OPTION_ERROR_GOTO (LineType * l)
- {
- /* OPTION ERROR GOTO */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- My->CurrentVersion->OptionFlags &= ~OPTION_ERROR_GOSUB;
- return (l);
- }
-
- LineType *
- bwb_OPTION_EXPLICIT (LineType * l)
- {
- /* OPTION EXPLICIT */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- My->CurrentVersion->OptionFlags |= OPTION_EXPLICIT_ON;
- return (l);
- }
-
-
- LineType *
- bwb_OPTION_PUNCT_IMAGE (LineType * l)
- {
- /* OPTION PUNCT IMAGE char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l, &(My->CurrentVersion->OptionImageChar));
- }
-
- LineType *
- bwb_OPTION_IMPLICIT (LineType * l)
- {
- /* OPTION IMPLICIT */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- My->CurrentVersion->OptionFlags &= ~OPTION_EXPLICIT_ON;
- return (l);
- }
-
- LineType *
- bwb_OPTION_INDENT (LineType * l)
- {
- /* OPTION INDENT integer */
- assert (l != NULL);
- assert( My != NULL );
-
- return bwb_option_range_integer (l, &(My->OptionIndentInteger), 0, 7);
- }
-
- LineType *
- bwb_OPTION_PUNCT_INPUT (LineType * l)
- {
- /* OPTION PUNCT INPUT char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l, &(My->CurrentVersion->OptionInputChar));
- }
-
- LineType *
- bwb_OPTION_LABELS (LineType * l)
- {
- assert (l != NULL);
- WARN_SYNTAX_ERROR;
- return (l);
- }
-
- LineType *
- bwb_OPTION_LABELS_ON (LineType * l)
- {
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- /* OPTION LABELS ON */
- My->CurrentVersion->OptionFlags |= OPTION_LABELS_ON;
- return (l);
- }
-
- LineType *
- bwb_OPTION_LABELS_OFF (LineType * l)
- {
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- /* OPTION LABELS OFF */
- My->CurrentVersion->OptionFlags &= ~OPTION_LABELS_ON;
- return (l);
- }
-
- LineType *
- bwb_OPTION_PUNCT_PRINT (LineType * l)
- {
- /* OPTION PUNCT PRINT char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l, &(My->CurrentVersion->OptionPrintChar));
- }
-
- LineType *
- bwb_OPTION_PUNCT_QUOTE (LineType * l)
- {
- /* OPTION PUNCT QUOTE char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l, &(My->CurrentVersion->OptionQuoteChar));
- }
-
- LineType *
- bwb_OPTION_ROUND (LineType * l)
- {
- assert (l != NULL);
- WARN_SYNTAX_ERROR;
- return (l);
- }
-
- LineType *
- bwb_OPTION_ROUND_BANK (LineType * l)
- {
- /* OPTION ROUND BANK */
- assert (l != NULL);
- assert( My != NULL );
-
- My->OptionRoundType = C_OPTION_ROUND_BANK;
- return (l);
- }
-
- LineType *
- bwb_OPTION_ROUND_MATH (LineType * l)
- {
- /* OPTION ROUND MATH */
- assert (l != NULL);
- assert( My != NULL );
-
- My->OptionRoundType = C_OPTION_ROUND_MATH;
- return (l);
- }
-
- LineType *
- bwb_OPTION_ROUND_TRUNCATE (LineType * l)
- {
- /* OPTION ROUND TRUNCATE */
- assert (l != NULL);
- assert( My != NULL );
-
- My->OptionRoundType = C_OPTION_ROUND_TRUNCATE;
- return (l);
- }
-
- LineType *
- bwb_OPTION_SCALE (LineType * l)
- {
- /* OPTION SCALE integer */
- assert (l != NULL);
- assert( My != NULL );
-
- return bwb_option_range_integer (l, &(My->OptionScaleInteger),
- MINIMUM_SCALE, MAXIMUM_SCALE);
- }
-
-
- LineType *
- bwb_OPTION_SLEEP (LineType * l)
- {
- /* OPTION SLEEP number */
- assert (l != NULL);
- assert( My != NULL );
-
- if (line_read_numeric_expression (l, &My->OptionSleepDouble) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- return (l);
- }
-
- LineType *
- bwb_OPTION_STDERR (LineType * l)
- {
- /* OPTION STDERR filename$ */
-
- assert (l != NULL);
- assert( My != NULL );
- assert( My->SYSPRN != NULL );
- assert( My->SYSPRN->cfp != NULL );
-
-
- if (line_is_eol (l))
- {
- bwb_fclose (My->SYSPRN->cfp);
- My->SYSPRN->cfp = stderr;
- }
- else
- {
- char *Value;
-
- Value = NULL;
- if (line_read_string_expression (l, &Value) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (Value == NULL)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- /* OK */
- if (is_empty_string (Value))
- {
- bwb_fclose (My->SYSPRN->cfp);
- My->SYSPRN->cfp = stderr;
- }
- else
- {
- bwb_fclose (My->SYSPRN->cfp);
- My->SYSPRN->cfp = fopen (Value, "w+");
- if (My->SYSPRN->cfp == NULL)
- {
- /* sane default */
- My->SYSPRN->cfp = stderr;
- WARN_BAD_FILE_NAME;
- }
- }
- free (Value);
- }
- return (l);
- }
-
- LineType *
- bwb_OPTION_STDIN (LineType * l)
- {
- /* OPTION STDIN filename$ */
-
- assert (l != NULL);
- assert( My != NULL );
- assert( My->SYSIN != NULL );
- assert( My->SYSIN->cfp != NULL );
-
- if (line_is_eol (l))
- {
- bwb_fclose (My->SYSIN->cfp);
- My->SYSIN->cfp = stdin;
- }
- else
- {
- char *Value;
-
- Value = NULL;
- if (line_read_string_expression (l, &Value) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (Value == NULL)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- /* OK */
- if (is_empty_string (Value))
- {
- bwb_fclose (My->SYSIN->cfp);
- My->SYSIN->cfp = stdin;
- }
- else
- {
- bwb_fclose (My->SYSIN->cfp);
- My->SYSIN->cfp = fopen (Value, "r");
- if (My->SYSIN->cfp == NULL)
- {
- /* sane default */
- My->SYSIN->cfp = stdin;
- WARN_BAD_FILE_NAME;
- }
- }
- free (Value);
- }
- return (l);
- }
-
- LineType *
- bwb_OPTION_STDOUT (LineType * l)
- {
- /* OPTION STDOUT filename$ */
-
- assert (l != NULL);
- assert( My != NULL );
- assert( My->SYSOUT != NULL );
- assert( My->SYSOUT->cfp != NULL );
-
- if (line_is_eol (l))
- {
- bwb_fclose (My->SYSOUT->cfp);
- My->SYSOUT->cfp = stdout;
- }
- else
- {
- char *Value;
-
- Value = NULL;
- if (line_read_string_expression (l, &Value) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (Value == NULL)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- /* OK */
- if (is_empty_string (Value))
- {
- bwb_fclose (My->SYSOUT->cfp);
- My->SYSOUT->cfp = stdout;
- }
- else
- {
- bwb_fclose (My->SYSOUT->cfp);
- My->SYSOUT->cfp = fopen (Value, "w+");
- if (My->SYSOUT->cfp == NULL)
- {
- /* sane default */
- My->SYSOUT->cfp = stdout;
- WARN_BAD_FILE_NAME;
- }
- }
- free (Value);
- }
- return (l);
- }
-
- LineType *
- bwb_OPTION_PUNCT_STATEMENT (LineType * l)
- {
- /* OPTION PUNCT STATEMENT char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l,
- &(My->CurrentVersion->OptionStatementChar));
- }
-
- LineType *
- bwb_OPTION_STRICT (LineType * l)
- {
- assert (l != NULL);
- WARN_SYNTAX_ERROR;
- return (l);
- }
-
- LineType *
- bwb_OPTION_STRICT_ON (LineType * l)
- {
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- /* OPTION STRICT ON */
- My->CurrentVersion->OptionFlags |= OPTION_STRICT_ON;
- return (l);
- }
-
- LineType *
- bwb_OPTION_STRICT_OFF (LineType * l)
- {
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- /* OPTION STRICT OFF */
- My->CurrentVersion->OptionFlags &= ~OPTION_STRICT_ON;
- return (l);
- }
-
- LineType *
- bwb_OPTION_PUNCT (LineType * l)
- {
- assert (l != NULL);
- WARN_SYNTAX_ERROR;
- return (l);
- }
-
- LineType *
- bwb_OPTION_PUNCT_STRING (LineType * l)
- {
- /* OPTION PUNCT STRING char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l, &(My->CurrentVersion->OptionStringChar));
- }
-
- LineType *
- bwb_OPTION_PUNCT_DOUBLE (LineType * l)
- {
- /* OPTION PUNCT DOUBLE char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l, &(My->CurrentVersion->OptionDoubleChar));
- }
-
- LineType *
- bwb_OPTION_PUNCT_SINGLE (LineType * l)
- {
- /* OPTION PUNCT SINGLE char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l, &(My->CurrentVersion->OptionSingleChar));
- }
-
- LineType *
- bwb_OPTION_PUNCT_CURRENCY (LineType * l)
- {
- /* OPTION PUNCT CURRENCY char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l, &(My->CurrentVersion->OptionCurrencyChar));
- }
-
- LineType *
- bwb_OPTION_PUNCT_LONG (LineType * l)
- {
- /* OPTION PUNCT LONG char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l, &(My->CurrentVersion->OptionLongChar));
- }
-
- LineType *
- bwb_OPTION_PUNCT_INTEGER (LineType * l)
- {
- /* OPTION PUNCT INTEGER char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l, &(My->CurrentVersion->OptionIntegerChar));
- }
-
- LineType *
- bwb_OPTION_PUNCT_BYTE (LineType * l)
- {
- /* OPTION PUNCT BYTE char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l, &(My->CurrentVersion->OptionByteChar));
- }
-
- LineType *
- bwb_OPTION_PUNCT_LPAREN (LineType * l)
- {
- /* OPTION PUNCT LPAREN char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l, &(My->CurrentVersion->OptionLparenChar));
- }
-
- LineType *
- bwb_OPTION_PUNCT_RPAREN (LineType * l)
- {
- /* OPTION PUNCT RPAREN char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l, &(My->CurrentVersion->OptionRparenChar));
- }
-
- LineType *
- bwb_OPTION_PUNCT_FILENUM (LineType * l)
- {
- /* OPTION PUNCT FILENUM char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l, &(My->CurrentVersion->OptionFilenumChar));
- }
-
- LineType *
- bwb_OPTION_PUNCT_AT (LineType * l)
- {
- /* OPTION PUNCT AT char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l, &(My->CurrentVersion->OptionAtChar));
- }
-
- LineType *
- bwb_OPTION_RECLEN (LineType * l)
- {
- /* OPTION RECLEN integer */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_range_integer (l,
- &(My->CurrentVersion->OptionReclenInteger),
- 0, MAXINT);
- }
-
- LineType *
- bwb_OPTION_TERMINAL (LineType * l)
- {
- assert (l != NULL);
- WARN_SYNTAX_ERROR;
- return (l);
- }
-
- LineType *
- bwb_OPTION_TERMINAL_NONE (LineType * l)
- {
- /* OPTION TERMINAL NONE */
- assert (l != NULL);
- assert( My != NULL );
-
- My->OptionTerminalType = C_OPTION_TERMINAL_NONE;
- return (l);
- }
-
- LineType *
- bwb_OPTION_TERMINAL_ADM (LineType * l)
- {
- /* OPTION TERMINAL ADM-3A */
- assert (l != NULL);
- assert( My != NULL );
-
- My->OptionTerminalType = C_OPTION_TERMINAL_ADM;
- return (l);
- }
-
- LineType *
- bwb_OPTION_TERMINAL_ANSI (LineType * l)
- {
- /* OPTION TERMINAL ANSI */
- assert (l != NULL);
- assert( My != NULL );
-
- My->OptionTerminalType = C_OPTION_TERMINAL_ANSI;
- return (l);
- }
-
- LineType *
- bwb_OPTION_TIME (LineType * l)
- {
- /* OPTION TIME format$ */
- char *Value;
-
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- Value = NULL;
- if (line_read_string_expression (l, &Value) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (Value == NULL)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- /* OK */
- My->CurrentVersion->OptionTimeFormat = Value;
- #if FALSE /* keep this ... */
- /*
- ** Yes, this can theoretically cause a memory leak.
- ** No, we are not going to fix it.
- ** This command is only supported in the profile.
- ** This will only execute at most once,
- ** so there is no actual memory leak.
- **
- */
- free (Value);
- #endif
- return (l);
- }
-
- LineType *
- bwb_OPTION_TRACE (LineType * l)
- {
-
- assert (l != NULL);
- WARN_SYNTAX_ERROR;
- return (l);
- }
-
- LineType *
- bwb_OPTION_TRACE_ON (LineType * l)
- {
- /* OPTION TRACE ON */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- My->CurrentVersion->OptionFlags |= OPTION_TRACE_ON;
- return (l);
- }
-
- LineType *
- bwb_OPTION_TRACE_OFF (LineType * l)
- {
- /* OPTION TRACE OFF */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- My->CurrentVersion->OptionFlags &= ~OPTION_TRACE_ON;
- return (l);
- }
-
- LineType *
- bwb_OPTION_USING (LineType * l)
- {
- assert (l != NULL);
- WARN_SYNTAX_ERROR;
- return (l);
- }
-
- LineType *
- bwb_OPTION_USING_DIGIT (LineType * l)
- {
- /* OPTION USING DIGIT char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l, &(My->CurrentVersion->OptionUsingDigit));
- }
-
- LineType *
- bwb_OPTION_USING_COMMA (LineType * l)
- {
- /* OPTION USING COMMA char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l, &(My->CurrentVersion->OptionUsingComma));
- }
-
- LineType *
- bwb_OPTION_USING_PERIOD (LineType * l)
- {
- /* OPTION USING PERIOD char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l, &(My->CurrentVersion->OptionUsingPeriod));
- }
-
- LineType *
- bwb_OPTION_USING_PLUS (LineType * l)
- {
- /* OPTION USING PLUS char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l, &(My->CurrentVersion->OptionUsingPlus));
- }
-
- LineType *
- bwb_OPTION_USING_MINUS (LineType * l)
- {
- /* OPTION USING MINUS char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l, &(My->CurrentVersion->OptionUsingMinus));
- }
-
- LineType *
- bwb_OPTION_USING_EXRAD (LineType * l)
- {
- /* OPTION USING EXRAD char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l, &(My->CurrentVersion->OptionUsingExrad));
- }
-
- LineType *
- bwb_OPTION_USING_DOLLAR (LineType * l)
- {
- /* OPTION USING DOLLAR char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l, &(My->CurrentVersion->OptionUsingDollar));
- }
-
- LineType *
- bwb_OPTION_USING_FILLER (LineType * l)
- {
- /* OPTION USING FILLER char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l, &(My->CurrentVersion->OptionUsingFiller));
- }
-
- LineType *
- bwb_OPTION_USING_LITERAL (LineType * l)
- {
- /* OPTION USING LITERAL char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l, &(My->CurrentVersion->OptionUsingLiteral));
- }
-
- LineType *
- bwb_OPTION_USING_FIRST (LineType * l)
- {
- /* OPTION USING FIRST char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l, &(My->CurrentVersion->OptionUsingFirst));
- }
-
- LineType *
- bwb_OPTION_USING_ALL (LineType * l)
- {
- /* OPTION USING ALL char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l, &(My->CurrentVersion->OptionUsingAll));
- }
-
- LineType *
- bwb_OPTION_USING_LENGTH (LineType * l)
- {
- /* OPTION USING LENGTH char$ */
- assert (l != NULL);
- assert( My != NULL );
- assert( My->CurrentVersion != NULL );
-
- return bwb_option_punct_char (l, &(My->CurrentVersion->OptionUsingLength));
- }
-
- extern LineType *
- bwb_OPTION_VERSION (LineType * l)
- {
- /* OPTION VERSION [version$] */
- char *Name;
- int i;
-
- assert (l != NULL);
- assert( My != NULL );
- assert( My->SYSOUT != NULL );
- assert( My->SYSOUT->cfp != NULL );
-
-
- Name = NULL;
- if (line_is_eol (l))
- {
- /* OPTIONAL */
- }
- else if (line_read_string_expression (l, &Name))
- {
- if (is_empty_string (Name) == FALSE)
- {
- /* a version was specified */
- for (i = 0; i < NUM_VERSIONS; i++)
- {
- if (bwb_stricmp (Name, bwb_vertable[i].Name) == 0)
- {
- /* FOUND */
- OptionVersionSet (i);
- return (l);
- }
- }
- /* NOT FOUND */
- fprintf (My->SYSOUT->cfp, "OPTION VERSION \"%s\" IS INVALID\n", Name);
- }
- }
- fprintf (My->SYSOUT->cfp, "VALID CHOICES ARE:\n");
- for (i = 0; i < NUM_VERSIONS; i++)
- {
- char *tbuf;
-
- tbuf = My->ConsoleOutput;
- bwb_strcpy (tbuf, "\"");
- bwb_strcat (tbuf, bwb_vertable[i].Name);
- bwb_strcat (tbuf, "\"");
- fprintf (My->SYSOUT->cfp, "OPTION VERSION %-16s ' %s\n", tbuf,
- bwb_vertable[i].Description);
- }
- ResetConsoleColumn ();
- line_skip_eol (l);
- return (l);
- }
-
- LineType *
- bwb_OPTION_ZONE (LineType * l)
- {
- /* OPTION ZONE integer */
- int Value;
-
- assert (l != NULL);
- assert( My != NULL );
-
- Value = 0;
- if (line_read_integer_expression (l, &Value))
- {
- /* OK */
- if (Value == 0)
- {
- /* default */
- Value = ZONE_WIDTH;
- }
- if (Value < MINIMUM_ZONE || Value > MAXIMUM_ZONE)
- {
- WARN_ILLEGAL_FUNCTION_CALL;
- return (l);
- }
- My->OptionZoneInteger = Value;
- }
- return (l);
- }
-
-
-
- int
- var_get (VariableType * variable, VariantType * variant)
- {
- size_t offset;
-
- /* check sanity */
- if (variable == NULL)
- {
- WARN_INTERNAL_ERROR;
- return FALSE;
- }
- if (variant == NULL)
- {
- WARN_INTERNAL_ERROR;
- return FALSE;
- }
-
- /* Check subscripts */
- if (dim_check (variable) == FALSE)
- {
- WARN_SUBSCRIPT_OUT_OF_RANGE;
- return FALSE;
- }
-
- /* Determine offset from array base ( for scalars the offset is always zero ) */
- offset = dim_unit (variable, variable->VINDEX);
-
- CLEAR_VARIANT (variant);
-
- /* Force compatibility */
- variant->VariantTypeCode = variable->VariableTypeCode;
-
- if (variable->VariableTypeCode == StringTypeCode)
- {
- /* Variable is a STRING */
- StringType Value;
-
- Value.sbuffer = NULL;
- Value.length = 0;
- /* both STRING */
-
- if (variable->VariableFlags & VARIABLE_VIRTUAL) /* var_get() */
- {
- /* get file information */
- VirtualType *Z;
- FileType *F;
-
- Z = find_virtual_by_variable (variable);
- if (Z == NULL)
- {
- WARN_INTERNAL_ERROR;
- return FALSE;
- }
- offset *= Z->FileLength; /* Byte offset */
- offset += Z->FileOffset; /* Beginning of this data */
- /* update file information */
- F = find_file_by_number (Z->FileNumber);
- if (F == NULL)
- {
- WARN_BAD_FILE_MODE;
- return FALSE;
- }
- if (F->DevMode != DEVMODE_VIRTUAL)
- {
- WARN_BAD_FILE_MODE;
- return FALSE;
- }
- if (F->cfp == NULL)
- {
- WARN_BAD_FILE_MODE;
- return FALSE;
- }
- if (fseek (F->cfp, offset, SEEK_SET) != 0)
- {
- WARN_BAD_FILE_MODE;
- return FALSE;
- }
- Value.length = Z->FileLength;
- if ((Value.sbuffer =
- (char *) calloc (Value.length + 1 /* NulChar */ ,
- sizeof (char))) == NULL)
- {
- WARN_OUT_OF_MEMORY;
- return FALSE;
- }
- if (fread (Value.sbuffer, Value.length, 1, F->cfp) != 1)
- {
- WARN_DISK_IO_ERROR;
- return FALSE;
- }
- }
- else
- {
- StringType *string;
-
- string = variable->Value.String;
- if (string == NULL)
- {
- WARN_INTERNAL_ERROR;
- return FALSE;
- }
- string += offset;
- if (str_btob (&Value, string) == FALSE)
- {
- WARN_INTERNAL_ERROR;
- return FALSE;
- }
- }
- variant->Buffer = Value.sbuffer;
- variant->Length = Value.length;
- }
- else
- {
- /* Variable is a NUMBER */
- DoubleType Value;
- /* both NUMBER */
-
- if (variable->VariableFlags & VARIABLE_VIRTUAL) /* var_get() */
- {
- /* get file information */
- VirtualType *Z;
- FileType *F;
-
- Z = find_virtual_by_variable (variable);
- if (Z == NULL)
- {
- WARN_INTERNAL_ERROR;
- return FALSE;
- }
- offset *= Z->FileLength; /* Byte offset */
- offset += Z->FileOffset; /* Beginning of this data */
- /* update file information */
- F = find_file_by_number (Z->FileNumber);
- if (F == NULL)
- {
- WARN_BAD_FILE_MODE;
- return FALSE;
- }
- if (F->DevMode != DEVMODE_VIRTUAL)
- {
- WARN_BAD_FILE_MODE;
- return FALSE;
- }
- if (F->cfp == NULL)
- {
- WARN_BAD_FILE_MODE;
- return FALSE;
- }
- if (fseek (F->cfp, offset, SEEK_SET) != 0)
- {
- WARN_BAD_FILE_MODE;
- return FALSE;
- }
- switch (variable->VariableTypeCode)
- {
- case ByteTypeCode:
- {
- ByteType X;
- if (fread (&X, sizeof (X), 1, F->cfp) != 1)
- {
- WARN_DISK_IO_ERROR;
- return FALSE;
- }
- Value = X;
- }
- break;
- case IntegerTypeCode:
- {
- IntegerType X;
- if (fread (&X, sizeof (X), 1, F->cfp) != 1)
- {
- WARN_DISK_IO_ERROR;
- return FALSE;
- }
- Value = X;
- }
- break;
- case LongTypeCode:
- {
- LongType X;
- if (fread (&X, sizeof (X), 1, F->cfp) != 1)
- {
- WARN_DISK_IO_ERROR;
- return FALSE;
- }
- Value = X;
- }
- break;
- case CurrencyTypeCode:
- {
- CurrencyType X;
- if (fread (&X, sizeof (X), 1, F->cfp) != 1)
- {
- WARN_DISK_IO_ERROR;
- return FALSE;
- }
- Value = X;
- }
- break;
- case SingleTypeCode:
- {
- SingleType X;
- if (fread (&X, sizeof (X), 1, F->cfp) != 1)
- {
- WARN_DISK_IO_ERROR;
- return FALSE;
- }
- Value = X;
- }
- break;
- case DoubleTypeCode:
- {
- DoubleType X;
- if (fread (&X, sizeof (X), 1, F->cfp) != 1)
- {
- WARN_DISK_IO_ERROR;
- return FALSE;
- }
- Value = X;
- }
- break;
- case StringTypeCode:
- {
- WARN_INTERNAL_ERROR;
- return FALSE;
- }
- /* break; */
- default:
- {
- WARN_INTERNAL_ERROR;
- return FALSE;
- }
- }
- }
- else
- {
- DoubleType *number;
-
- number = variable->Value.Number;
- if (number == NULL)
- {
- WARN_INTERNAL_ERROR;
- return FALSE;
- }
- number += offset;
- /* copy value */
- Value = *number;
- }
-
- /* VerifyNumeric */
- if (isnan (Value))
- {
- /*** FATAL - INTERNAL ERROR - SHOULD NEVER HAPPEN ***/
- WARN_INTERNAL_ERROR;
- return FALSE;
- }
- if (isinf (Value))
- {
- /* - Evaluation of an expression results in an overflow
- * (nonfatal, the recommended recovery procedure is to supply
- * machine in- finity with the algebraically correct sign and
- * continue). */
- if (Value < 0)
- {
- Value = MINDBL;
- }
- else
- {
- Value = MAXDBL;
- }
- if (WARN_OVERFLOW)
- {
- /* ERROR */
- return FALSE;
- }
- /* CONTINUE */
- }
- /* OK */
- switch (variable->VariableTypeCode)
- {
- case ByteTypeCode:
- case IntegerTypeCode:
- case LongTypeCode:
- case CurrencyTypeCode:
- /* integer values */
- Value = bwb_rint (Value);
- break;
- case SingleTypeCode:
- case DoubleTypeCode:
- /* float values */
- break;
- default:
- /* ERROR */
- WARN_INTERNAL_ERROR;
- return FALSE;
- /* break; */
- }
- variant->Number = Value;
- }
- return TRUE;
- }
-
- int
- var_set (VariableType * variable, VariantType * variant)
- {
- size_t offset;
-
- assert( My != NULL );
- assert( My->SYSOUT != NULL );
- assert( My->SYSOUT->cfp != NULL );
-
- /* check sanity */
- if (variable == NULL)
- {
- WARN_INTERNAL_ERROR;
- return FALSE;
- }
- if (variant == NULL)
- {
- WARN_INTERNAL_ERROR;
- return FALSE;
- }
-
- /* check CONST */
- if (variable->VariableFlags & (VARIABLE_CONSTANT))
- {
- /* attempting to assign to a constant */
- WARN_VARIABLE_NOT_DECLARED;
- return FALSE;
- }
-
- /* Check subscripts */
- if (dim_check (variable) == FALSE)
- {
- WARN_SUBSCRIPT_OUT_OF_RANGE;
- return FALSE;
- }
-
- /* Determine offset from array base ( for scalars the offset is always zero ) */
- offset = dim_unit (variable, variable->VINDEX);
-
- /* Verify compatibility */
- if (variable->VariableTypeCode == StringTypeCode)
- {
- /* Variable is a STRING */
- StringType Value;
-
- /* Verify value is a STRING */
- if (variant->VariantTypeCode != StringTypeCode)
- {
- WARN_TYPE_MISMATCH;
- return FALSE;
- }
- Value.sbuffer = variant->Buffer;
- Value.length = variant->Length;
- /* both STRING */
-
- if (variable->VariableFlags & VARIABLE_VIRTUAL) /* var_set() */
- {
- /* get file information */
- VirtualType *Z;
- FileType *F;
- int count;
-
- Z = find_virtual_by_variable (variable);
- if (Z == NULL)
- {
- WARN_INTERNAL_ERROR;
- return FALSE;
- }
- offset *= Z->FileLength; /* Byte offset */
- offset += Z->FileOffset; /* Beginning of this data */
- /* update file information */
- F = find_file_by_number (Z->FileNumber);
- if (F == NULL)
- {
- WARN_BAD_FILE_MODE;
- return FALSE;
- }
- if (F->DevMode != DEVMODE_VIRTUAL)
- {
- WARN_BAD_FILE_MODE;
- return FALSE;
- }
- if (F->cfp == NULL)
- {
- WARN_BAD_FILE_MODE;
- return FALSE;
- }
- if (fseek (F->cfp, offset, SEEK_SET) != 0)
- {
- WARN_BAD_FILE_MODE;
- return FALSE;
- }
- count = MIN (Value.length, Z->FileLength);
- if (fwrite (Value.sbuffer, sizeof (char), count, F->cfp) != count)
- {
- WARN_DISK_IO_ERROR;
- return FALSE;
- }
- /* PADR */
- while (count < Z->FileLength)
- {
- if (fputc (' ', F->cfp) == EOF)
- {
- WARN_BAD_FILE_MODE;
- return FALSE;
- }
- count++;
- }
- }
- else
- {
- StringType *string;
-
- string = variable->Value.String;
- if (string == NULL)
- {
- WARN_INTERNAL_ERROR;
- return FALSE;
- }
- string += offset;
- if (str_btob (string, &Value) == FALSE)
- {
- WARN_INTERNAL_ERROR;
- return FALSE;
- }
- }
- if (variable->VariableFlags & VARIABLE_DISPLAY) /* var_set() */
- {
- if (My->ThisLine) /* var_set() */
- {
- if (My->ThisLine->LineFlags & (LINE_USER)) /* var_set() */
- {
- /* immediate mode */
- }
- else
- {
- fprintf (My->SYSOUT->cfp, "#%d %s=%s\n", My->ThisLine->number, variable->name, variant->Buffer); /* var_set() */
- ResetConsoleColumn ();
- }
- }
- }
- }
- else
- {
- /* Variable is a NUMBER */
- DoubleType Value;
-
- /* Verify value is a NUMBER */
- if (variant->VariantTypeCode == StringTypeCode)
- {
- WARN_TYPE_MISMATCH;
- return FALSE;
- }
-
- /* both NUMBER */
-
- /* VerifyNumeric */
- if (isnan (variant->Number))
- {
- /*** FATAL - INTERNAL ERROR - SHOULD NEVER HAPPEN ***/
- WARN_INTERNAL_ERROR;
- return FALSE;
- }
- if (isinf (variant->Number))
- {
- /* - Evaluation of an expression results in an overflow
- * (nonfatal, the recommended recovery procedure is to supply
- * machine in- finity with the algebraically correct sign and
- * continue). */
- if (variant->Number < 0)
- {
- variant->Number = MINDBL;
- }
- else
- {
- variant->Number = MAXDBL;
- }
- if (WARN_OVERFLOW)
- {
- /* ERROR */
- return FALSE;
- }
- /* CONTINUE */
- }
- /* OK */
- switch (variable->VariableTypeCode)
- {
- case ByteTypeCode:
- variant->Number = bwb_rint (variant->Number);
- if (variant->Number < MINBYT)
- {
- if (WARN_OVERFLOW)
- {
- return FALSE;
- }
- variant->Number = MINBYT;
- }
- else if (variant->Number > MAXBYT)
- {
- if (WARN_OVERFLOW)
- {
- return FALSE;
- }
- variant->Number = MAXBYT;
- }
- break;
- case IntegerTypeCode:
- variant->Number = bwb_rint (variant->Number);
- if (variant->Number < MININT)
- {
- if (WARN_OVERFLOW)
- {
- return FALSE;
- }
- variant->Number = MININT;
- }
- else if (variant->Number > MAXINT)
- {
- if (WARN_OVERFLOW)
- {
- return FALSE;
- }
- variant->Number = MAXINT;
- }
- break;
- case LongTypeCode:
- variant->Number = bwb_rint (variant->Number);
- if (variant->Number < MINLNG)
- {
- if (WARN_OVERFLOW)
- {
- return FALSE;
- }
- variant->Number = MINLNG;
- }
- else if (variant->Number > MAXLNG)
- {
- if (WARN_OVERFLOW)
- {
- return FALSE;
- }
- variant->Number = MAXLNG;
- }
- break;
- case CurrencyTypeCode:
- variant->Number = bwb_rint (variant->Number);
- if (variant->Number < MINCUR)
- {
- if (WARN_OVERFLOW)
- {
- return FALSE;
- }
- variant->Number = MINCUR;
- }
- else if (variant->Number > MAXCUR)
- {
- if (WARN_OVERFLOW)
- {
- return FALSE;
- }
- variant->Number = MAXCUR;
- }
- break;
- case SingleTypeCode:
- if (variant->Number < MINSNG)
- {
- if (WARN_OVERFLOW)
- {
- return FALSE;
- }
- variant->Number = MINSNG;
- }
- else if (variant->Number > MAXSNG)
- {
- if (WARN_OVERFLOW)
- {
- return FALSE;
- }
- variant->Number = MAXSNG;
- }
- break;
- case DoubleTypeCode:
- if (variant->Number < MINDBL)
- {
- if (WARN_OVERFLOW)
- {
- return FALSE;
- }
- variant->Number = MINDBL;
- }
- else if (variant->Number > MAXDBL)
- {
- if (WARN_OVERFLOW)
- {
- return FALSE;
- }
- variant->Number = MAXDBL;
- }
- break;
- default:
- WARN_INTERNAL_ERROR;
- return FALSE;
- /* break; */
- }
- Value = variant->Number;
- if (variable->VariableFlags & VARIABLE_VIRTUAL) /* var_set() */
- {
- /* get file information */
- VirtualType *Z;
- FileType *F;
-
- Z = find_virtual_by_variable (variable);
- if (Z == NULL)
- {
- WARN_INTERNAL_ERROR;
- return FALSE;
- }
- offset *= Z->FileLength; /* Byte offset */
- offset += Z->FileOffset; /* Beginning of this data */
- /* update file information */
- F = find_file_by_number (Z->FileNumber);
- if (F == NULL)
- {
- WARN_BAD_FILE_MODE;
- return FALSE;
- }
- if (F->DevMode != DEVMODE_VIRTUAL)
- {
- WARN_BAD_FILE_MODE;
- return FALSE;
- }
- if (F->cfp == NULL)
- {
- WARN_BAD_FILE_MODE;
- return FALSE;
- }
- if (fseek (F->cfp, offset, SEEK_SET) != 0)
- {
- WARN_BAD_FILE_MODE;
- return FALSE;
- }
- switch (variable->VariableTypeCode)
- {
- case ByteTypeCode:
- {
- ByteType X;
- X = Value;
- if (fwrite (&X, sizeof (X), 1, F->cfp) != 1)
- {
- WARN_DISK_IO_ERROR;
- return FALSE;
- }
- }
- break;
- case IntegerTypeCode:
- {
- IntegerType X;
- X = Value;
- if (fwrite (&X, sizeof (X), 1, F->cfp) != 1)
- {
- WARN_DISK_IO_ERROR;
- return FALSE;
- }
- }
- break;
- case LongTypeCode:
- {
- LongType X;
- X = Value;
- if (fwrite (&X, sizeof (X), 1, F->cfp) != 1)
- {
- WARN_DISK_IO_ERROR;
- return FALSE;
- }
- }
- break;
- case CurrencyTypeCode:
- {
- CurrencyType X;
- X = Value;
- if (fwrite (&X, sizeof (X), 1, F->cfp) != 1)
- {
- WARN_DISK_IO_ERROR;
- return FALSE;
- }
- }
- break;
- case SingleTypeCode:
- {
- SingleType X;
- X = Value;
- if (fwrite (&X, sizeof (X), 1, F->cfp) != 1)
- {
- WARN_DISK_IO_ERROR;
- return FALSE;
- }
- }
- break;
- case DoubleTypeCode:
- {
- DoubleType X;
- X = Value;
- if (fwrite (&X, sizeof (X), 1, F->cfp) != 1)
- {
- WARN_DISK_IO_ERROR;
- return FALSE;
- }
- }
- break;
- case StringTypeCode:
- {
- WARN_INTERNAL_ERROR;
- return FALSE;
- }
- /* break; */
- default:
- {
- WARN_INTERNAL_ERROR;
- return FALSE;
- }
- }
- }
- else
- {
- DoubleType *number;
- number = variable->Value.Number;
- if (number == NULL)
- {
- WARN_INTERNAL_ERROR;
- return FALSE;
- }
- number += offset;
- *number = Value;
- }
- if (variable->VariableFlags & VARIABLE_DISPLAY) /* var_set() */
- {
- if (My->ThisLine) /* var_set() */
- {
- if (My->ThisLine->LineFlags & (LINE_USER)) /* var_set() */
- {
- /* immediate mode */
- }
- else
- {
- FormatBasicNumber (Value, My->NumLenBuffer);
- fprintf (My->SYSOUT->cfp, "#%d %s=%s\n", My->ThisLine->number, variable->name, My->NumLenBuffer); /* var_set() */
- ResetConsoleColumn ();
- }
- }
- }
- }
- return TRUE;
- }
-
- /***************************************************************
-
- FUNCTION: dim_check()
-
- DESCRIPTION: This function checks subscripts of a
- specific variable to be sure that they
- are within the correct range.
-
- ***************************************************************/
-
- static int
- dim_check (VariableType * variable)
- {
- /* Check for validly allocated array */
- int n;
-
- assert (variable != NULL);
-
-
- if (variable->VariableFlags & VARIABLE_VIRTUAL) /* var_set() */
- {
- if (variable->Value.String != NULL)
- {
- WARN_INTERNAL_ERROR;
- return FALSE;
- }
- if (variable->Value.Number != NULL)
- {
- WARN_INTERNAL_ERROR;
- return FALSE;
- }
- }
- else if (VAR_IS_STRING (variable))
- {
- if (variable->Value.String == NULL)
- {
- WARN_INTERNAL_ERROR;
- return FALSE;
- }
- }
- else
- {
- if (variable->Value.Number == NULL)
- {
- WARN_INTERNAL_ERROR;
- return FALSE;
- }
- }
- /* Now check subscript values */
- for (n = 0; n < variable->dimensions; n++)
- {
- if (variable->VINDEX[n] < variable->LBOUND[n]
- || variable->VINDEX[n] > variable->UBOUND[n])
- {
- WARN_SUBSCRIPT_OUT_OF_RANGE;
- return FALSE;
- }
- }
- /* No problems found */
- return TRUE;
- }
-
- /***************************************************************
-
- FUNCTION: var_make()
-
- DESCRIPTION: This function initializes a variable,
- allocating necessary memory for it.
-
- ***************************************************************/
-
- int
- var_make (VariableType * variable, char TypeCode)
- {
- /* ALL variables are created here */
-
- assert (variable != NULL);
-
- switch (TypeCode)
- {
- case ByteTypeCode:
- case IntegerTypeCode:
- case LongTypeCode:
- case CurrencyTypeCode:
- case SingleTypeCode:
- case DoubleTypeCode:
- case StringTypeCode:
- /* OK */
- break;
- default:
- /* ERROR */
- WARN_TYPE_MISMATCH;
- return FALSE;
- }
-
- variable->VariableTypeCode = TypeCode;
-
- /* get memory for array */
-
- /* First cleanup the joint (JBV) */
- if (variable->Value.Number != NULL)
- {
- free (variable->Value.Number);
- variable->Value.Number = NULL;
- }
- if (variable->Value.String != NULL)
- {
- /* Remember to deallocate those far-flung branches! (JBV) */
- StringType *sp; /* JBV */
- int n; /* JBV */
-
- sp = variable->Value.String;
- for (n = 0; n < (int) variable->array_units; n++)
- {
- if (sp[n].sbuffer != NULL)
- {
- free (sp[n].sbuffer);
- sp[n].sbuffer = NULL;
- }
- sp[n].length = 0;
- }
- free (variable->Value.String);
- variable->Value.String = NULL;
- }
-
- variable->dimensions = 0;
- variable->array_units = 1;
-
- if (VAR_IS_STRING (variable))
- {
- if ((variable->Value.String =
- calloc (variable->array_units, sizeof (StringType))) == NULL)
- {
- WARN_OUT_OF_MEMORY;
- return FALSE;
- }
- }
- else
- {
- if ((variable->Value.Number =
- calloc (variable->array_units, sizeof (DoubleType))) == NULL)
- {
- WARN_OUT_OF_MEMORY;
- return FALSE;
- }
- }
- return TRUE;
-
- }
-
- /***************************************************************
-
- FUNCTION: var_islocal()
-
- DESCRIPTION: This function determines whether the string
- pointed to by 'buffer' has the name of
- a local variable at the present EXEC stack
- level.
-
- ***************************************************************/
-
- static VariableType *
- mat_islocal (char *buffer)
- {
- /*
- similar to var_islocal, but returns first matrix found.
- */
-
- assert (buffer != NULL);
- assert( My != NULL );
-
- if (My->StackHead != NULL)
- {
- StackType *StackItem;
- for (StackItem = My->StackHead; StackItem != NULL;
- StackItem = StackItem->next)
- {
- if (StackItem->LoopTopLine != NULL)
- {
- switch (StackItem->LoopTopLine->cmdnum)
- {
- case C_DEF:
- case C_FUNCTION:
- case C_SUB:
- /* we have found a FUNCTION or SUB boundary */
- {
- VariableType *variable;
-
- for (variable = StackItem->local_variable; variable != NULL;
- variable = variable->next)
- {
- if (variable->dimensions > 0)
- {
- if (bwb_stricmp (variable->name, buffer) == 0)
- {
- /* FOUND */
- return variable;
- }
- }
- }
- }
- /* we have checked all the way to a FUNCTION or SUB boundary */
- /* NOT FOUND */
- return NULL;
- /* break; */
- }
- }
- }
- }
- /* NOT FOUND */
- return NULL;
- }
-
-
- static VariableType *
- var_islocal (char *buffer, int dimensions)
- {
-
- assert (buffer != NULL);
- assert( My != NULL );
-
- if (My->StackHead != NULL)
- {
- StackType *StackItem;
- for (StackItem = My->StackHead; StackItem != NULL;
- StackItem = StackItem->next)
- {
- if (StackItem->LoopTopLine != NULL)
- {
- switch (StackItem->LoopTopLine->cmdnum)
- {
- case C_DEF:
- case C_FUNCTION:
- case C_SUB:
- /* we have found a FUNCTION or SUB boundary */
- {
- VariableType *variable;
-
- for (variable = StackItem->local_variable; variable != NULL;
- variable = variable->next)
- {
- if (variable->dimensions == dimensions)
- {
- if (bwb_stricmp (variable->name, buffer) == 0)
- {
- /* FOUND */
- return variable;
- }
- }
- }
- }
- /* we have checked all the way to a FUNCTION or SUB boundary */
- /* NOT FOUND */
- return NULL;
- /* break; */
- }
- }
- }
- }
- /* NOT FOUND */
- return NULL;
- }
-
- /***************************************************************
-
- FUNCTION: bwb_vars()
-
- DESCRIPTION: This function implements the Bywater-
- specific debugging command VARS, which
- gives a list of all variables defined
- in memory.
-
- ***************************************************************/
-
-
- LineType *
- bwb_VARS (LineType * l)
- {
- VariableType *variable;
-
- assert (l != NULL);
- assert( My != NULL );
- assert( My->SYSOUT != NULL );
- assert( My->SYSOUT->cfp != NULL );
-
- /* run through the variable list and print variables */
-
-
- fprintf (My->SYSOUT->cfp, "%-*s %-6s %-4s %s\n", NameLengthMax, "Name",
- "Type", "Dims", "Value");
-
- for (variable = My->VariableHead; variable != NULL;
- variable = variable->next)
- {
- VariantType variant;
- CLEAR_VARIANT (&variant);
-
- if (var_get (variable, &variant) == FALSE)
- {
- WARN_VARIABLE_NOT_DECLARED;
- return (l);
- }
- if (variant.VariantTypeCode == StringTypeCode)
- {
- fprintf (My->SYSOUT->cfp, "%-*s %-6s %-4d %s\n", NameLengthMax,
- variable->name, "STRING", variable->dimensions,
- variant.Buffer);
- }
- else
- {
- FormatBasicNumber (variant.Number, My->NumLenBuffer);
- fprintf (My->SYSOUT->cfp, "%-*s %-6s %-4d %s\n", NameLengthMax,
- variable->name, "NUMBER", variable->dimensions,
- My->NumLenBuffer);
- }
- RELEASE_VARIANT (&variant);
- }
- ResetConsoleColumn ();
- return (l);
- }
-
- /***************************************************************
-
- FUNCTION: bwb_field()
-
- DESCRIPTION: This C function implements the BASIC
- FIELD command.
-
- ***************************************************************/
-
- static void
- field_clear (FieldType * Field)
- {
- int i;
-
- assert (Field != NULL);
-
- Field->File = NULL;
- Field->FieldOffset = 0;
- Field->FieldLength = 0;
- Field->Var = NULL;
- for (i = 0; i < MAX_DIMS; i++)
- {
- Field->VINDEX[i] = 0;
- }
- }
-
- static FieldType *
- field_new (void)
- {
- /* search for an empty slot */
- FieldType *Field;
-
- assert( My != NULL );
-
- for (Field = My->FieldHead; Field != NULL; Field = Field->next)
- {
- if (Field->File == NULL || Field->Var == NULL)
- {
- field_clear (Field);
- return Field;
- }
- }
- /* not found */
- if ((Field = calloc (1, sizeof (FieldType))) == NULL)
- {
- WARN_OUT_OF_MEMORY;
- return NULL;
- }
- Field->next = My->FieldHead;
- My->FieldHead = Field;
- return Field;
- }
-
- void
- field_close_file (FileType * File)
- {
- /* a CLOSE of a file is in progress, release associated fields */
- FieldType *Field;
-
- assert (File != NULL);
- assert( My != NULL );
-
- for (Field = My->FieldHead; Field != NULL; Field = Field->next)
- {
- if (Field->File == File)
- {
- Field->File = NULL;
- Field->Var = NULL;
- }
- }
- }
- void
- field_free_variable (VariableType * Var)
- {
- /* an ERASE of a variable is in progress, release associated fields */
- FieldType *Field;
-
- assert (Var != NULL);
- assert( My != NULL );
-
- for (Field = My->FieldHead; Field != NULL; Field = Field->next)
- {
- if (Field->Var == Var)
- {
- Field->File = NULL;
- Field->Var = NULL;
- }
- }
- }
-
-
- void
- field_get (FileType * File)
- {
- /* a GET of the RANDOM file is in progress, update variables from FILE buffer */
- FieldType *Field;
-
- assert( My != NULL );
-
- if (File == NULL)
- {
- WARN_BAD_FILE_NUMBER;
- return;
- }
- if (File->buffer == NULL)
- {
- WARN_BAD_FILE_MODE;
- return;
- }
- for (Field = My->FieldHead; Field != NULL; Field = Field->next)
- {
- if (Field->File == File && Field->Var != NULL)
- {
- /* from file to variable */
- VariantType variant;
- CLEAR_VARIANT (&variant);
-
- if (Field->FieldOffset < 0)
- {
- WARN_FIELD_OVERFLOW;
- return;
- }
- if (Field->FieldLength <= 0)
- {
- WARN_FIELD_OVERFLOW;
- return;
- }
- if ((Field->FieldOffset + Field->FieldLength) > File->width)
- {
- WARN_FIELD_OVERFLOW;
- return;
- }
- variant.VariantTypeCode = StringTypeCode;
- variant.Length = Field->FieldLength;
- if ((variant.Buffer =
- (char *) calloc (variant.Length + 1 /* NulChar */ ,
- sizeof (char))) == NULL)
- {
- WARN_OUT_OF_MEMORY;
- return;
- }
- /* if( TRUE ) */
- {
- int i;
-
- for (i = 0; i < Field->Var->dimensions; i++)
- {
- Field->Var->VINDEX[i] = Field->VINDEX[i];
- }
- }
- /* if( TRUE ) */
- {
- int i;
- char *Buffer;
-
- Buffer = File->buffer;
- Buffer += Field->FieldOffset;
- for (i = 0; i < variant.Length; i++)
- {
- variant.Buffer[i] = Buffer[i];
- }
- variant.Buffer[variant.Length] = NulChar;
- }
- if (var_set (Field->Var, &variant) == FALSE)
- {
- WARN_VARIABLE_NOT_DECLARED;
- return;
- }
- RELEASE_VARIANT (&variant);
- }
- }
- }
- void
- field_put (FileType * File)
- {
- /* a PUT of the RANDOM file is in progress, update FILE buffer from variables */
- FieldType *Field;
-
- assert( My != NULL );
-
- if (File == NULL)
- {
- WARN_BAD_FILE_NUMBER;
- return;
- }
- if (File->buffer == NULL)
- {
- WARN_BAD_FILE_MODE;
- return;
- }
- for (Field = My->FieldHead; Field != NULL; Field = Field->next)
- {
- if (Field->File == File && Field->Var != NULL)
- {
- /* from variable to file */
- VariantType variant;
- CLEAR_VARIANT (&variant);
-
- if (Field->FieldOffset < 0)
- {
- WARN_FIELD_OVERFLOW;
- return;
- }
- if (Field->FieldLength <= 0)
- {
- WARN_FIELD_OVERFLOW;
- return;
- }
- if ((Field->FieldOffset + Field->FieldLength) > File->width)
- {
- WARN_FIELD_OVERFLOW;
- return;
- }
- /* if( TRUE ) */
- {
- int i;
-
- for (i = 0; i < Field->Var->dimensions; i++)
- {
- Field->Var->VINDEX[i] = Field->VINDEX[i];
- }
- }
- if (var_get (Field->Var, &variant) == FALSE)
- {
- WARN_VARIABLE_NOT_DECLARED;
- return;
- }
- if (variant.VariantTypeCode != StringTypeCode)
- {
- WARN_TYPE_MISMATCH;
- return;
- }
- /* if( TRUE ) */
- {
- int i;
- int n;
- char *Buffer;
-
- i = 0;
- n = 0;
- Buffer = File->buffer;
- Buffer += Field->FieldOffset;
-
- if (variant.Buffer != NULL)
- {
- n = MIN (variant.Length, Field->FieldLength);
- }
- for (i = 0; i < n; i++)
- {
- Buffer[i] = variant.Buffer[i];
- }
- for (i = n; i < Field->FieldLength; i++)
- {
- /* Pad on the right with spaces */
- Buffer[i] = ' ';
- }
- }
- RELEASE_VARIANT (&variant);
- }
- }
- }
-
-
- LineType *
- bwb_FIELD (LineType * l)
- {
- FileType *File;
- int FileNumber;
- int FieldOffset;
-
- assert (l != NULL);
-
- FileNumber = 0;
- FieldOffset = 0;
-
- /* first read device number */
- if (line_skip_FilenumChar (l))
- {
- /* optional */
- }
- if (line_read_integer_expression (l, &FileNumber) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (FileNumber <= 0)
- {
- /* FIELD # 0 is an error */
- WARN_BAD_FILE_NUMBER;
- return (l);
- }
- File = find_file_by_number (FileNumber);
- if (File == NULL)
- {
- WARN_BAD_FILE_NUMBER;
- return (l);
- }
- if (File->DevMode != DEVMODE_RANDOM)
- {
- WARN_BAD_FILE_MODE;
- return (l);
- }
- /* loop to read variables */
-
-
- /* read the comma and advance beyond it */
- while (line_skip_seperator (l))
- {
- int FieldLength;
- VariableType *variable;
- VariantType variant;
-
- CLEAR_VARIANT (&variant);
-
- /* first find the size of the field */
- FieldLength = 0;
- if (line_read_integer_expression (l, &FieldLength) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (FieldLength <= 0)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
-
- /* read the AS */
- if (line_skip_word (l, "AS") == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
-
- /* read the string variable name */
- if ((variable = line_read_scalar (l)) == NULL)
- {
- WARN_VARIABLE_NOT_DECLARED;
- return (l);
- }
-
- if (VAR_IS_STRING (variable))
- {
- /* OK */
- }
- else
- {
- WARN_TYPE_MISMATCH;
- return (l);
- }
- /* check for overflow of record length */
- if ((FieldOffset + FieldLength) > File->width)
- {
- WARN_FIELD_OVERFLOW;
- return (l);
- }
- /* set buffer */
- variant.VariantTypeCode = StringTypeCode;
- /* if( TRUE ) */
- {
- FieldType *Field;
- int i;
-
- Field = field_new ();
- if (Field == NULL)
- {
- WARN_OUT_OF_MEMORY;
- return (l);
- }
- Field->File = File;
- Field->FieldOffset = FieldOffset;
- Field->FieldLength = FieldLength;
- Field->Var = variable;
- for (i = 0; i < variable->dimensions; i++)
- {
- Field->VINDEX[i] = variable->VINDEX[i];
- }
- variant.Length = FieldLength;
- if ((variant.Buffer =
- (char *) calloc (variant.Length + 1 /* NulChar */ ,
- sizeof (char))) == NULL)
- {
- WARN_OUT_OF_MEMORY;
- return (l);
- }
- bwb_memset (variant.Buffer, ' ', variant.Length);
- variant.Buffer[variant.Length] = NulChar;
- }
- if (var_set (variable, &variant) == FALSE)
- {
- WARN_VARIABLE_NOT_DECLARED;
- return (l);
- }
- RELEASE_VARIANT (&variant);
- FieldOffset += FieldLength;
- }
- /* return */
- return (l);
- }
-
- /***************************************************************
-
- FUNCTION: bwb_lset()
-
- DESCRIPTION: This C function implements the BASIC
- LSET command.
-
- SYNTAX: LSET string-variable$ = expression
-
- ***************************************************************/
-
- LineType *
- bwb_LSET (LineType * l)
- {
-
- assert (l != NULL);
- return dio_lrset (l, FALSE);
- }
-
- /***************************************************************
-
- FUNCTION: bwb_rset()
-
- DESCRIPTION: This C function implements the BASIC
- RSET command.
-
- SYNTAX: RSET string-variable$ = expression
-
- ***************************************************************/
-
- LineType *
- bwb_RSET (LineType * l)
- {
-
- assert (l != NULL);
- return dio_lrset (l, TRUE);
- }
-
- /***************************************************************
-
- FUNCTION: dio_lrset()
-
- DESCRIPTION: This C function implements the BASIC
- RSET and LSET commands.
-
- ***************************************************************/
-
- static LineType *
- dio_lrset (LineType * l, int rset)
- {
- /* LSET and RSET */
- VariantType variant;
- int n;
- int i;
- int startpos;
- VariableType *v;
- VariantType t;
- VariantType *T;
-
- assert (l != NULL);
-
- T = &t;
- CLEAR_VARIANT (T);
- CLEAR_VARIANT (&variant);
- /* get the variable */
- if ((v = line_read_scalar (l)) == NULL)
- {
- WARN_VARIABLE_NOT_DECLARED;
- return (l);
- }
- if (VAR_IS_STRING (v) == FALSE)
- {
- WARN_TYPE_MISMATCH;
- return (l);
- }
-
- /* skip the equals sign */
- if (line_skip_EqualChar (l) == FALSE)
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
-
- /* get the value */
- if (line_read_expression (l, T) == FALSE) /* dio_lrset */
- {
- WARN_SYNTAX_ERROR;
- return (l);
- }
- if (T->VariantTypeCode != StringTypeCode)
- {
- WARN_TYPE_MISMATCH;
- return (l);
- }
- if (var_get (v, &variant) == FALSE)
- {
- WARN_VARIABLE_NOT_DECLARED;
- return (l);
- }
- /* determine starting position */
- startpos = 0;
- if (rset == TRUE && T->Length < variant.Length)
- {
- /*
- LET A$ = "123_456" ' variant.Length = 7
- LET B$ = "789" ' T->Length = 3
- RSET A$ = B$ ' startpos = 4
- PRINT "[";A$;"]" ' [123_789]
- */
- startpos = variant.Length - T->Length;
- }
- /* write characters to new position */
- for (n = startpos, i = 0;
- (n < (int) variant.Length) && (i < (int) T->Length); n++, i++)
- {
- variant.Buffer[n] = T->Buffer[i];
- }
- if (var_set (v, &variant) == FALSE)
- {
- WARN_VARIABLE_NOT_DECLARED;
- return (l);
- }
- /* OK */
- RELEASE_VARIANT (T);
- RELEASE_VARIANT (&variant);
-
- return (l);
- }
-
- /* EOF */
|