Example #1
0
/*
** '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();
}
Example #2
0
/*
** '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;
}
Example #3
0
/*
** '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);
}
Example #4
0
/*
** '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);
  }
}
Example #5
0
/*
** '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;
  }
}
Example #6
0
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;
}
Example #7
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;
}
Example #8
0
/*
** '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);
}