Esempio n. 1
0
void read_input(char *str, int str_size)
{
    char ch;

    if (NULL == str)
    {
        run_error ("Buffer is null in read_string");
        return;
    }
    if (str_size < 0)
    {
        run_error ("Buffer size is null in read_string");
        return;
    }

    // We assume that get_console_char will "do the right thing" wrt the msg
    // pump, etc.
    while ((1 < str_size) && (!force_break))
    {
        ch = get_console_char();
        *str = ch;
        ++str;
        --str_size;
        put_console_char(ch);

        // Read just one line.
        if (ch == '\n')
            break;
    }

    if (0 < str_size)
        *str = '\0';
}
Esempio n. 2
0
PRIVATE void seg_proccheck(struct comal_line *mline, struct comal_line
			   *sline)
{
	struct proc_func_rec *mpf = &mline->lc.pfrec;
	struct proc_func_rec *spf = &sline->lc.pfrec;
	struct parm_list *mwalk = mpf->parmroot;
	struct parm_list *swalk = spf->parmroot;

	if (mline->cmd != sline->cmd)
		run_error(EXT_ERR,
			  "PROC/FUNC mismatch in external segment");

	if (mpf->id != spf->id)
		run_error(EXT_ERR,
			  "EXTERNAL PROC/FUNC not in external segment");

	if (mpf->closed && !spf->closed)
		run_error(EXT_ERR,
			  "CLOSED mismatch with PROC/FUNC in external segment");

	/*
	 * If the PROC/FUNC definition in the main program does not contain 
	 * a parameter list, the the parm check is OK. The external definition
	 * is the correct one.
	 */
	if (!mwalk)
		return;

	/*
	 * Compare the paremeter lists of the definitions in the main program
	 * and in the external segment.
	 */
	while (mwalk && swalk) {
		if (mwalk->ref != swalk->ref
		    || mwalk->array != swalk->array
		    || mwalk->id->type != swalk->id->type)
			run_error(EXT_ERR,
				  "Specified parameter list mismatch with external PROC/FUNC definition");

		mwalk = mwalk->next;
		swalk = swalk->next;
	}

	/*
	 * If at this point both mwalk and swalk are NULL, the parameter lists in the main
	 * program and the external segment are identical. If not, give an error...
	 */
	if ( (mwalk && !swalk) || (swalk && !mwalk) )
		run_error(EXT_ERR,
		  	"Number of parameters differ in external PROC/FUNC definition");
}
Esempio n. 3
0
PRIVATE int cmd_cont(struct comal_line *line)
{
	if (curenv->running != HALTED)
		run_error(CMD_ERR, "CONtinuation not possible");

	return contSYM;
}
Esempio n. 4
0
PRIVATE int cmd_load(struct comal_line *line)
{
	char *fn;

	if (!line->lc.str && !curenv->name)
		run_error(CMD_ERR, "Missing program name (to LOAD)");
	else if (check_changed()) {
		if (line->lc.str)
			fn = line->lc.str->s;
		else {
			fn = curenv->name;
			my_printf(MSG_DIALOG, 1, fn);
		}

		fn = my_strdup(MISC_POOL, fn);
		prog_load(fn);
		curenv->name = fn;
		prog_structure_scan();
		mem_freepool(PARSE_POOL);

		longjmp(RESTART, JUST_RESTART);
	}

	return 0;
}
Esempio n. 5
0
void
expand_k_data (int addl_bytes)
{
  int delta = ROUND_UP(addl_bytes, BYTES_PER_WORD); /* Keep word aligned */
  int old_size = k_data_top - K_DATA_BOT;
  int new_size = old_size + delta;
  BYTE_TYPE *p;

  if ((addl_bytes < 0) || (new_size > k_data_size_limit))
    {
      error ("Can't expand kernel data segment by %d bytes to %d bytes\n",
	     addl_bytes, new_size);
      run_error ("Use -lkdata # with # > %d\n", new_size);
    }
  k_data_seg = (mem_word *) realloc (k_data_seg, new_size);
  if (k_data_seg == NULL)
    fatal_error ("realloc failed in expand_k_data\n");

  k_data_seg_b = (BYTE_TYPE *) k_data_seg;
  k_data_seg_h = (short *) k_data_seg;
  k_data_top += delta;

  /* Zero new memory */
  for (p = k_data_seg_b + old_size / BYTES_PER_WORD;
       p < k_data_seg_b + new_size / BYTES_PER_WORD; )
    *p ++ = 0;
}
Esempio n. 6
0
void
expand_stack (int addl_bytes)
{
  int delta = ROUND_UP(addl_bytes, BYTES_PER_WORD); /* Keep word aligned */
  int old_size = STACK_TOP - stack_bot;
  int new_size = old_size + MAX (delta, old_size);
  mem_word *new_seg;
  mem_word *po, *pn;

  if ((addl_bytes < 0) || (new_size > stack_size_limit))
    {
      error ("Can't expand stack segment by %d bytes to %d bytes\n",
	     addl_bytes, new_size);
      run_error ("Use -lstack # with # > %d\n", new_size);
    }

  new_seg = (mem_word *) xmalloc (new_size);
  po = stack_seg + (old_size / BYTES_PER_WORD - 1);
  pn = new_seg + (new_size / BYTES_PER_WORD - 1);

  for ( ; po >= stack_seg ; ) *pn -- = *po --;
  for ( ; pn >= new_seg ; ) *pn -- = 0;

  free (stack_seg);
  stack_seg = new_seg;
  stack_seg_b = (BYTE_TYPE *) stack_seg;
  stack_seg_h = (short *) stack_seg;
  stack_bot -= (new_size - old_size);
}
Esempio n. 7
0
PRIVATE int cmd_enter(struct comal_line *line)
{
	FILE *yyenter;
	char tline[MAX_LINELEN];
	int stoppen = 0;
	struct comal_line *aline;

	yyenter = fopen(line->lc.str->s, "rt");

	if (!yyenter)
		run_error(OPEN_ERR, "File open error: %s",
			  sys_errlist[errno]);

	setvbuf(yyenter, NULL, _IOFBF, TEXT_BUFSIZE);
	++entering;

	while (!stoppen) {
		stoppen = (fgets(tline, MAX_LINELEN - 1, yyenter) == NULL);

		if (stoppen) {
			if (!feof(yyenter))
				run_error(CMD_ERR,
					  "Error when reading ENTER file: %s",
					  sys_errlist[errno]);
		} else {
			aline = crunch_line(tline);

			if (!aline) {
				my_nl(MSG_DIALOG);
				my_printf(MSG_DIALOG, 1,
					  "Ignored line: %s", tline);
				mem_freepool(PARSE_POOL);
			} else
				process_comal_line(aline);
		}
	}

	fclose(yyenter);
	--entering;
	prog_structure_scan();

	return 0;
}
Esempio n. 8
0
PUBLIC void seg_total_scan(struct seg_des *seg)
{
	char errtxt[MAX_LINELEN];
	struct comal_line *errline = NULL;

	if (comal_debug)
		my_printf(MSG_DEBUG, 1, "External Total scanning...");

	if (!scan_scan(seg, errtxt, &errline))
		run_error(SCAN_ERR, "SCAN error: %s", errtxt);
}
Esempio n. 9
0
PRIVATE void expand_read()
{
	sqash_hwm = read(sqash_file, sqash_buf, SQASH_BUFSIZE);

	if (sqash_hwm < 0) {
		close(sqash_file);
		run_error(SQASH_ERR, "Error when reading from file: %s",
			  sys_errlist[errno]);
	}

	sqash_i = 0;
}
Esempio n. 10
0
PRIVATE void sqash_flush()
{
	if (sqash_i > 0) {
		if (write(sqash_file, sqash_buf, sqash_i) <= 0) {
			close(sqash_file);
			run_error(SQASH_ERR,
				  "Error when writing to file: %s",
				  sys_errlist[errno]);
		}

		sqash_i = 0;
	}
}
Esempio n. 11
0
PRIVATE int cmd_save(struct comal_line *line)
{
	if (!line->lc.str && !curenv->name)
		run_error(CMD_ERR, "Missing program name (to SAVE)");
	else if (!curenv->progroot)
		run_error(CMD_ERR, "No program (to SAVE)");
	else {
		if (line->lc.str) {
			if (curenv->name)
				mem_free(curenv->name);

			curenv->name =
			    my_strdup(MISC_POOL, line->lc.str->s);
		} else
			my_printf(MSG_DIALOG, 1, curenv->name);

		sqash_2file(curenv->name);
		curenv->changed = 0;
	}

	return 0;
}
Esempio n. 12
0
PUBLIC void sqash_2file(char *fname)
{
	struct comal_line *work = curenv->progroot;
	char *s;

	sqash_file =
	    open(fname, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
		 S_IREAD | S_IWRITE);

	if (sqash_file < 0)
		run_error(OPEN_ERR, "File open error: %s",
			  sys_errlist[errno]);

	sqash_buf = mem_alloc(MISC_POOL, SQASH_BUFSIZE);
	sqash_i = 0;

	for (s=SQ_MARKER; *s; s++)
		sqash_putc(*s);

	sqash_putc(HOST_OS_CODE);
	sqash_putstr2(SQ_CONTROL, HOST_OS);
	sqash_putint(0, SQ_VERSION);
	sqash_putstr2(SQ_CONTROL, SQ_COPYRIGHT_MSG);

	while (work) {
		sqash_horse(work);
		work = work->ld->next;
	}

	sqash_putstr2(SQ_CONTROL, SQ_COPYRIGHT_MSG);
	sqash_flush();

	mem_free(sqash_buf);

	if (close(sqash_file) < 0)
		run_error(CLOSE_ERR, "Error closing file: %s",
			  sys_errlist[errno]);
}
Esempio n. 13
0
PRIVATE int cmd_del(struct comal_line *line)
{
	long from = line->lc.twonum.num1;
	long to = line->lc.twonum.num2;

	if (from == 0 && to == MAXINT)
		run_error(CMD_ERR,
			  "Please mention a line number range with DEL");

	if (prog_del(&curenv->progroot, from, to, 1))
		prog_structure_scan();

	return 0;
}
Esempio n. 14
0
PRIVATE void cmd_list_horse(struct string *filename, long from, long to)
{
	char buf[MAX_LINELEN];
	char *buf2;
	FILE *listfile;
	struct comal_line *work = curenv->progroot;

	if (filename) {
		listfile = fopen(filename->s, "wt");

		if (!listfile)
			run_error(OPEN_ERR, "File open error %s",
				  sys_errlist[errno]);

		setvbuf(listfile, NULL, _IOFBF, TEXT_BUFSIZE);
	} else {
		listfile = NULL;
		sys_setpaged(1);
	}

	while (work && work->ld->lineno < from)
		work = work->ld->next;

	while (work && work->ld->lineno <= to) {
		if (sys_escape()) {
			my_printf(MSG_DIALOG, 1, "Escape");
			break;
		}

		buf2 = buf;
		line_list(&buf2, work);

		if (listfile)
			fprintf(listfile, "%s\n", buf);
		else
			my_printf(MSG_DIALOG, 1, "%s", buf);

		work = work->ld->next;
	}

	if (listfile)
		fclose(listfile);
	else
		sys_setpaged(0);
}
Esempio n. 15
0
void*
mem_reference(mem_addr addr)
{
  if ((addr >= TEXT_BOT) && (addr < text_top))
    return addr - TEXT_BOT + (char*) text_seg;
  else if ((addr >= DATA_BOT) && (addr < data_top))
    return addr - DATA_BOT + (char*) data_seg;
  else if ((addr >= stack_bot) && (addr < STACK_TOP))
    return addr - stack_bot + (char*) stack_seg;
  else if ((addr >= K_TEXT_BOT) && (addr < k_text_top))
    return addr - K_TEXT_BOT + (char*) k_text_seg;
  else if ((addr >= K_DATA_BOT) && (addr < k_data_top))
    return addr - K_DATA_BOT + (char*) k_data_seg;
  else
    {
      run_error ("Memory address out of bounds\n");
      return NULL;
    }
}
Esempio n. 16
0
PRIVATE int cmd_list(struct comal_line *line)
{
	long from, to;
	int indent;
	struct comal_line *curline;

	if (!line->lc.listrec.id)
		cmd_list_horse(line->lc.listrec.str,
			       line->lc.listrec.twonum.num1,
			       line->lc.listrec.twonum.num2);
	else {
		curline = curenv->progroot;

		while (curline
		       &&
		       !((curline->cmd == procSYM
			  || curline->cmd == funcSYM)
			 && curline->lc.pfrec.id == line->lc.listrec.id))
			curline = curline->ld->next;

		if (!curline)
			run_error(CMD_ERR, "PROC/FUNC %s not found",
				  line->lc.listrec.id->name);

		from = curline->ld->lineno;
		indent = curline->ld->indent;
		curline = curline->ld->next;

		while (curline && curline->ld->indent > indent)
			curline = curline->ld->next;

		if (curline)
			to = curline->ld->lineno;
		else
			to = MAXINT;

		cmd_list_horse(line->lc.listrec.str, from, to);

	}

	return 0;
}
Esempio n. 17
0
PUBLIC struct comal_line *expand_fromfile(char *fname)
{
	struct comal_line *root;
	struct comal_line *line;
	struct comal_line *last = NULL;
	char *checkstr;
	char *s;
	extern int eof(int file);

	sqash_file = open(fname, O_RDONLY | O_BINARY);

	if (sqash_file < 0)
		run_error(OPEN_ERR, "File open error: %s",
			  sys_errlist[errno]);

	sqash_buf = mem_alloc(MISC_POOL, SQASH_BUFSIZE);
	sqash_i = MAXUNSIGNED;

	for (s=SQ_MARKER; *s; s++)
		if (expand_getc()!=*s)
			run_error(SQASH_ERR, "Not an OpenComal SAVE file");

	if (expand_getc()!=HOST_OS_CODE)
		run_error(SQASH_ERR,
			  "File not an OpenComal file saved under this OS");

	checkstr = expand_getstr2(SQ_CONTROL);

	if (strcmp(checkstr, HOST_OS) != 0)
		run_error(SQASH_ERR,
			  "File not an OpenComal file saved under this OS");

	mem_free(checkstr);

	if (expand_getint() != SQ_VERSION)
		run_error(SQASH_ERR,
			  "File has been saved under a different version of the Sqasher");

	checkstr = expand_getstr2(SQ_CONTROL);

	if (strcmp(checkstr, SQ_COPYRIGHT_MSG) != 0)
		fatal("Internal sqash/expand error #6");

	mem_free(checkstr);

	while (expand_peekc() == SQ_LINE) {
		line = expand_horse();

		if (last)
			last->ld->next = line;
		else
			root = line;

		last = line;
	}

	checkstr = expand_getstr2(SQ_CONTROL);

	if (strcmp(checkstr, SQ_COPYRIGHT_MSG) != 0)
		fatal("Internal sqash/expand error #7");

	if (!eof(sqash_file) || sqash_i < sqash_hwm)
		fatal("Internal sqash/expand error #8");

	mem_free(checkstr);
	mem_free(sqash_buf);

	if (close(sqash_file) < 0)
		run_error(CLOSE_ERR, "Error closing file: %s",
			  sys_errlist[errno]);

	return root;
}
Esempio n. 18
0
int
do_syscall ()
{
  /* Syscalls for the source-language version of SPIM.  These are easier to
     use than the real syscall and are portable to non-MIPS operating
     systems. */

  switch (R[REG_V0])
    {
    case PRINT_INT_SYSCALL:
      write_output (console_out, "%d", R[REG_A0]);
      break;

    case PRINT_FLOAT_SYSCALL:
      {
	float val = FPR_S (REG_FA0);

	write_output (console_out, "%.8f", val);
	break;
      }

    case PRINT_DOUBLE_SYSCALL:
      write_output (console_out, "%.18g", FPR[REG_FA0 / 2]);
      break;

    case PRINT_STRING_SYSCALL:
      write_output (console_out, "%s", mem_reference (R[REG_A0]));
      break;

    case READ_INT_SYSCALL:
      {
	static char str [256];

	read_input (str, 256);
	R[REG_RES] = atol (str);
	break;
      }

    case READ_FLOAT_SYSCALL:
      {
	static char str [256];

	read_input (str, 256);
	FPR_S (REG_FRES) = (float) atof (str);
	break;
      }

    case READ_DOUBLE_SYSCALL:
      {
	static char str [256];

	read_input (str, 256);
	FPR [REG_FRES] = atof (str);
	break;
      }

    case READ_STRING_SYSCALL:
      {
	read_input ( (char *) mem_reference (R[REG_A0]), R[REG_A1]);
	data_modified = 1;
	break;
      }

    case SBRK_SYSCALL:
      {
	mem_addr x = data_top;
	expand_data (R[REG_A0]);
	R[REG_RES] = x;
	data_modified = 1;
	break;
      }

    case PRINT_CHARACTER_SYSCALL:
      write_output (console_out, "%c", R[REG_A0]);
      break;

    case READ_CHARACTER_SYSCALL:
      {
	static char str [2];

	read_input (str, 2);
	if (*str == '\0') *str = '\n';      /* makes xspim = spim */
	R[REG_RES] = (long) str[0];
	break;
      }

    case EXIT_SYSCALL:
      spim_return_value = 0;
      return (0);

    case EXIT2_SYSCALL:
      spim_return_value = R[REG_A0];	/* value passed to spim's exit() call */
      return (0);

    case OPEN_SYSCALL:
      {
#ifdef WIN32
	R[REG_RES] = _open(mem_reference (R[REG_A0]), R[REG_A1], R[REG_A2]);
#else
	R[REG_RES] = open(mem_reference (R[REG_A0]), R[REG_A1], R[REG_A2]);
#endif
	break;
      }
		
    case READ_SYSCALL:
      {
	/* Test if address is valid */
	(void)mem_reference (R[REG_A1] + R[REG_A2] - 1);
#ifdef WIN32
	R[REG_RES] = _read(R[REG_A0], mem_reference (R[REG_A1]), R[REG_A2]);
#else
	R[REG_RES] = read(R[REG_A0], mem_reference (R[REG_A1]), R[REG_A2]);
#endif
	data_modified = 1;
	break;
      }

    case WRITE_SYSCALL:
      {
	/* Test if address is valid */
	(void)mem_reference (R[REG_A1] + R[REG_A2] - 1);
#ifdef WIN32
	R[REG_RES] = _write(R[REG_A0], mem_reference (R[REG_A1]), R[REG_A2]);
#else
	R[REG_RES] = write(R[REG_A0], mem_reference (R[REG_A1]), R[REG_A2]);
#endif
	break;
      }

    case CLOSE_SYSCALL:
      {
#ifdef WIN32
	R[REG_RES] = _close(R[REG_A0]);
#else
	R[REG_RES] = close(R[REG_A0]);
#endif
	break;
      }

    default:
      run_error ("Unknown system call: %d\n", R[REG_V0]);
      break;
    }

  return (1);
}