Exemplo n.º 1
0
/*
 * Read the next line from the source file
 * Return char* to the line.
 */
char* get_next_line() {
    size_t len;
    if(!fgets(line, sizeof line, input_file)) {
        /* No more lines */
        if(feof(input_file)) {
            return NULL;
        } else {
            perror(input_filename);
            exit(1);
        }
    }

    /* clean up string */
    char *newline = strnstr(line, "\n", LEX_MAX_LINE+2);
    if (!newline) {
        len = strnlen(line, LEX_MAX_LINE+2);
        if (len > LEX_MAX_LINE) {
            fprintf(stderr, "Line %d is greater than 72 chars\n", lineno);
            exit(1);
        }
        line[len] = '\n';
        line[len+1] = '\0';
    }
    lineno++;
    write_listing_line(lineno, line);
    return line;
}
/*
 * Expand a macro
 */
void
expand_macro(struct symbol *sym)
{
  struct inc_file *minc;
  struct macro_arg *arg;
  char *cp;
  int narg;
  int parcnt, d_char;

  write_listing_line(0); /* list the macro call line */

  minc = mem_alloc(sizeof(struct inc_file));
  minc->type = INC_MACRO;
  minc->v.m.sym = sym;
  minc->v.m.ml = sym->v.text;
  minc->linenum = 0;
  minc->cond_nest_count = cond_nest_count;
  minc->v.m.args = NULL;
  minc->v.m.uniq_id = unique_id_count++;
  arg = NULL;

  for(narg = 1;;narg++) {
    while(tok_char != '\n' && isspace(tok_char)) /* skip whitespace */
      read_src_char();

    if(tok_char == '\n' || tok_char == '\0' ||
       tok_char == ';' || tok_char == EOF)
      break;

    cp = line_buf_ptr-1;

    /*
     * Macro parameters are separated by commas. However, strings and
     * character constants (using double and single quotes)
     * can be used even if they contain commas. Also commas
     * inside parenthesis (such as function parameter delimiters)
     * don't count as macro parameter separators.
     *
     */

    parcnt = 0; /* parenthesis nesting count */

    while(!isspace(tok_char) &&
	  tok_char != '\n' && tok_char != '\0' &&
	  tok_char != ';' && tok_char != EOF) {
      if(parcnt == 0 && tok_char == ',')
	break;

      if(tok_char == '(') {
	parcnt++;
      } else if(tok_char == ')') {
	parcnt--;
      } else if(tok_char == '"' || tok_char == '\'') {
	/* quoted string or character constant */
	d_char = tok_char;

	do {
	  read_src_char();
	}
	while(tok_char != d_char && tok_char != '\n' &&
	      tok_char != '\0' && tok_char != EOF);

	if(tok_char != d_char)
	  break;
      }

      read_src_char();
    }

    if(narg >= 10)
      warning("Too many macro arguments (max. 9)");

    if(arg == NULL) {
      arg = mem_alloc(sizeof(struct macro_arg)
		      +(line_buf_ptr-cp-1));
      minc->v.m.args = arg;
    } else {
      arg->next = mem_alloc(sizeof(struct macro_arg)
			    +(line_buf_ptr-cp-1));
      arg = arg->next;
    }
    strncpy(arg->text, cp, line_buf_ptr-cp-1);
    arg->text[line_buf_ptr-cp-1] = '\0';
    arg->next = NULL;

    /* skip whitespace */
    while(tok_char != '\n' && isspace(tok_char))
      read_src_char();
    if(tok_char != ',')
      break;

    read_src_char();
  }

  if(tok_char != ';' && tok_char != '\n' &&
     tok_char != '\0' && tok_char != EOF)
    error(0, "Extraneous characters after a valid source line");

  minc->next = current_file;
  current_file = minc;

  line_buf_ptr = NULL;
  tok_char = ' ';
  get_token();
}