/* ** 'insert_line' adds the line in 'line' to the Basic program ** if new or replaces it if it already exists. */ static void insert_line(byte *line) { int32 lendiff, newline, newlength; byte *bp, *prev; newline = get_lineno(line); newlength = get_linelen(line); if (last_added!=NIL && newline>=get_lineno(last_added)) bp = last_added; else { bp = basicvars.start; } prev = NIL; while (newline>=get_lineno(bp)) { /* Work out where line goes */ prev = bp; bp+=get_linelen(bp); } if (prev!=NIL && newline==get_lineno(prev)) { /* Replacing a line */ lendiff = newlength-get_linelen(prev); if (lendiff!=0) { /* Old and new lines are not the same length */ if (basicvars.top+lendiff>=basicvars.himem) error(ERR_NOROOM); /* No room for line */ memmove(prev+newlength, bp, basicvars.top-bp+ENDMARKSIZE); basicvars.top+=lendiff; } memmove(prev, line, newlength); last_added = prev; } else { /* Adding a line */ if (basicvars.top+newlength>=basicvars.himem) error(ERR_NOROOM); /* No room for line */ memmove(bp+newlength, bp, basicvars.top-bp+ENDMARKSIZE); memmove(bp, line, newlength); basicvars.top+=newlength; last_added = bp; } adjust_heaplimits(); }
/* ** 'delete range' is called to delete a range of lines from 'low' to ** 'high'. The lines themselves do not have to be present, in which case ** lines from the nearest one above to nearest below will be disposed of */ void delete_range(int32 low, int32 high) { byte *lowline, *highline; if (low>high) return; lowline = find_line(low); if (get_lineno(lowline)==ENDLINENO) return; /* No lines are in the range to delete */ clear_refs(); highline = find_line(high); if (get_lineno(highline)==high) highline+=get_linelen(highline); memmove(lowline, highline, basicvars.top-highline+ENDMARKSIZE); basicvars.top-=(highline-lowline); adjust_heaplimits(); last_added = NIL; }
/* ** 'isvalidprog' checks the program in memory to make sure that it is okay. ** It returns 'true' if the program is okay, otherwise it returns 'false' */ static boolean isvalidprog(void) { int32 lastline; byte *p; boolean isnotfirst; lastline = 0; isnotfirst = FALSE; /* So that line number 0 is not flagged as an error */ p = basicvars.start; while (!AT_PROGEND(p)) { if (!isvalid(p) || (isnotfirst && get_lineno(p) <= lastline)) return FALSE; lastline = get_lineno(p); isnotfirst = TRUE; p+=get_linelen(p); } return AT_PROGEND(p); }
/* ** 'edit_line' is the main line editing routine. */ void edit_line(void) { if (basicvars.misc_flags.badprogram) error(ERR_BADPROG); clear_refs(); basicvars.misc_flags.validsaved = FALSE; /* If program is edited mark save area contents as bad */ if (isempty(thisline)) /* Empty line = delete line */ delete_line(get_lineno(thisline)); else { insert_line(thisline); } }
/* ** 'delete_line' deletes the line passed to it in 'line', if it ** exists */ void delete_line(int32 line) { int32 length; byte *p; p = find_line(line); if (get_lineno(p)==line) { /* Need an exact match. Cannot delete just anything... */ length = get_linelen(p); memmove(p, p+length, basicvars.top-p-length+ENDMARKSIZE); basicvars.top-=length; adjust_heaplimits(); last_added = NIL; } }
int main (int argc, char **argv) { int i; arff_info_t *info; for (i = 1; i < (argc - 1); i += 2) { info = read_arff (argv[i], argv[i + 1]); if (info == NULL) { printf ("read_arff failed: %s, lineno=%i\n", get_last_error (), get_lineno ()); } else { print_arff_info (info); release_read_info (info); } } return 0; }
struct compile_error expr_parse(struct input ci, struct expr_environ *env, struct parse_options opts, struct objcode **ocode) { struct compile_error ret; struct chain locals = new_chain(); struct proto_obj outp; char *end_ptr; int error = -E_OK, prev_stat=NADA, input_counter = 0; ret = init_ce(); *ocode = NULL; end_ptr = ""; /*force an input read ("" != NULL) */ //error = load_expr(&outp, expr); error = po_init(&outp, opts.n_args, opts.n_rets); while (error == -E_OK && end_ptr != NULL) { char *startptr = end_ptr; data_t tmp_data; int tmp_int; char *ident = NULL; if (eatspace(startptr, &end_ptr)) { /* do nothing */ } else if (*startptr == TERM) { startptr = end_ptr = get_input(ci); } else if (prev_stat == NADA && atodata_load(startptr, &end_ptr, &tmp_data)){ error = inject_data(&outp, tmp_data); prev_stat = NADA; } else if (prev_stat == ARG || prev_stat == NCLEAR) { if (atoint_load(startptr, &end_ptr, &tmp_int)) { if (prev_stat == ARG) error = inject_arg(&outp, tmp_int); else error = inject_nclear(&outp, tmp_int); } else { error = -EXPR_EXPECTING_INT; } prev_stat = NADA; } else if (loadtok(&ident, startptr, &end_ptr)) { int l_index; struct expr_var *tmp_var; if (prev_stat == NADA) { int kwn = strtoKW(ident); switch (kwn) { case KW_VARSET: prev_stat = VARSET; break; case KW_ARG: prev_stat = ARG; break; case KW_FULLCLEAR: error = inject_clear(&outp); prev_stat = NADA; break; case KW_NCLEAR: prev_stat = NCLEAR; break; default: /* not a kw */ { struct expr_func *tmp_fn; struct expr_const *tmp_const; int l_index; if ((l_index = strtoLocal(&locals, ident )) != _NO_SUCH_LOCAL) { error = inject_localvar_get(&outp, l_index); } else if ((tmp_var = strtoVar(&env->vars, ident)) != NULL) { error = inject_globalvar_get(&outp, tmp_var); } else if ((tmp_fn = strtoFun(env, ident)) != NULL) { error = inject_fn(&outp, tmp_fn); } else if ((tmp_const = strtoConst(env, ident)) != NULL) { error = inject_const(&outp, tmp_const); } else { error = -EXPR_NOSYM; } } } } else { if (strtoKW(ident) != NOT_A_KW) { if (prev_stat == VARSET) error = -EXPR_EXPECTING_VAR; else error = -EXPR_EXPECTING_VALUE; } else if (prev_stat == VARSET) { if ((l_index = strtoLocal(&locals, ident )) != _NO_SUCH_LOCAL) { error = inject_localvar_set(&outp, l_index); } else if ((tmp_var = strtoVar(&env->vars, ident)) != NULL) { error = inject_globalvar_set(&outp, tmp_var); } else { l_index =inject_localvar_setdeclare( &outp); if (l_index < 0) { error = l_index; } else { error = ins_local(&locals, ident, l_index); } } } else { error = -EXPR_NOSYM; } prev_stat = NADA; } } else { error = -EXPR_NOSYM; } input_counter += end_ptr - startptr; if (error != -E_OK) { ret.pos = input_counter; ret.lineno = get_lineno(ci); ret.type = error; if (ident != NULL) { ret.fname = ident; ident = NULL; /* prevent free() */ } else { ret.fname = strndup(startptr, end_ptr - startptr); } } free(ident); } { char *bad_string; switch (ret.type) { case -EXPR_ARG_OORANGE: ret.n = query_bad_argument(&outp); break; case -EXPR_FEWARGS: ret.n = query_bf_in(&outp); ret.m = query_bf_real(&outp); break; default: /* <-- includes EXPECTING_STH */ break; case -E_OK: { int nr = query_excess_rets(&outp); if (!opts.auto_clear && nr > 0) ret.type = -EXPR_MANYVALUES; if (ret.type != -E_OK) ret.n = query_n_rets(&outp); else if ((*ocode = po_compile(&outp))==NULL) ret.type = query_status(&outp); } break; } if (ret.fname == NULL && (bad_string = query_bad_fname(&outp)) != NULL) { ret.fname = strdup(bad_string); } } destroy_locals(&locals); if (*ocode == NULL) { po_abort(&outp); } return ret; }
/* ** 'read_textfile' reads a Basic program that is in text form, ** storing it at 'base'. 'limit' marks the highest address it can ** occupy. If any of the lines are missing line numbers then they ** are added at the end. Lines are numbered from 1 and go up by 1. ** The idea here is that the line numbers will correspond to the ** number of the line in the original text file making it easier ** to find out what line an error occured in.'silent' is set to ** TRUE if no message is to be displayed if line numbers are ** added. The program is tokenised as it is stored. The function ** returns the size of the tokenised program. ** This code assumes that fgets() returning a null pointer marks ** the end of the file. It could indicate an I/O error on the file. */ static int32 read_textfile(FILE *textfile, byte *base, byte *limit, boolean silent) { int length; byte *filebase; char *result; byte tokenline[MAXSTATELEN]; boolean gzipped = FALSE; #ifdef HAVE_ZLIB_H gzFile gzipfile; #endif fseek (textfile, 0, 0); tokenline[2] = 0; fread (tokenline, 1, 3, textfile); gzipped = (tokenline[0] == 0x1F && tokenline[1] == 0x8B && tokenline[2] == 8); if (gzipped) { #ifdef HAVE_ZLIB_H fclose (textfile); gzipfile = gzopen (basicvars.filename, "r"); if (gzipfile==NIL) error(ERR_FILEIO, basicvars.filename); #else error(ERR_NOGZIP); #endif } else { textfile = freopen(basicvars.filename, "r", textfile); /* Close and reopen the file as a text file */ if (textfile==NIL) error(ERR_FILEIO, basicvars.filename); } needsnumbers = FALSE; /* This will be set by tokenise_line() above */ basicvars.linecount = 0; /* Number of line being read from file */ filebase = base; #ifdef HAVE_ZLIB_H if (gzipped) result = gzgets(gzipfile, basicvars.stringwork, INPUTLEN); else #endif result = fgets(basicvars.stringwork, INPUTLEN, textfile); if (result!=NIL && basicvars.stringwork[0]=='#') { /* Ignore first line if it starts with a '#' */ #ifdef HAVE_ZLIB_H if (gzipped) result = gzgets(gzipfile, basicvars.stringwork, INPUTLEN); else #endif result = fgets(basicvars.stringwork, INPUTLEN, textfile); } while (result!=NIL) { basicvars.linecount++; length = strlen(basicvars.stringwork); /* First, get rid of any trailing blanks, line feeds and so forth */ do length--; while (length>=0 && isspace(basicvars.stringwork[length])); length++; basicvars.stringwork[length] = NUL; tokenize(basicvars.stringwork, tokenline, HASLINE); if (get_lineno(tokenline)==NOLINENO) { save_lineno(tokenline, 0); /* Otherwise renumber goes a bit funny */ needsnumbers = TRUE; } length = get_linelen(tokenline); if (length>0) { /* Line length is not zero so include line */ if (base+length>=limit) { /* No room left */ #ifdef HAVE_ZLIB_H if (gzipped) gzclose (gzipfile); else #endif fclose(textfile); error(ERR_NOROOM); } memmove(base, tokenline, length); base+=length; } #ifdef HAVE_ZLIB_H if (gzipped) result = gzgets(gzipfile, basicvars.stringwork, INPUTLEN); else #endif result = fgets(basicvars.stringwork, INPUTLEN, textfile); } #ifdef HAVE_ZLIB_H if (gzipped) gzclose (gzipfile); else #endif fclose(textfile); basicvars.linecount = 0; if (base+ENDMARKSIZE>=limit) error(ERR_NOROOM); mark_end(base); if (needsnumbers) { /* Line numbers are missing */ renumber_program(filebase, 1, 1); if (!silent) error(WARN_RENUMBERED); } return ALIGN(base-filebase+ENDMARKSIZE); }