Beispiel #1
0
static struct test *read_tests(void) {
    char *fname;
    FILE *fp;
    char line[BUFSIZ];
    struct test *result = NULL, *t = NULL;
    int lc = 0;
    bool append_cmd = true;

    if (asprintf(&fname, "%s/tests/run.tests", abs_top_srcdir) < 0)
        die("asprintf fname");

    if ((fp = fopen(fname, "r")) == NULL)
        die("fopen run.tests");

    while (fgets(line, BUFSIZ, fp) != NULL) {
        lc += 1;
        char *s = skipws(line);
        if (*s == '#' || *s == '\0')
            continue;
        if (*s == ':')
            s += 1;
        char *eos = s + strlen(s) - 2;
        if (eos >= s && *eos == ':') {
            *eos++ = '\n';
            *eos = '\0';
        }

        if (looking_at(s, KW_TEST)) {
            if (ALLOC(t) < 0)
                die_oom();
            list_append(result, t);
            append_cmd = true;
            s = token(s + strlen(KW_TEST), &(t->name));
            s = inttok(s, &t->result);
            s = errtok(s, &t->errcode);
        } else if (looking_at(s, KW_PRINTS)) {
            s = skipws(s + strlen(KW_PRINTS));
            t->out_present = looking_at(s, KW_SOMETHING);
            append_cmd = false;
        } else if (looking_at(s, KW_USE)) {
            if (t->module !=NULL)
                die("Can use at most one module in a test");
            s = token(s + strlen(KW_USE), &(t->module));
        } else {
            char **buf = append_cmd ? &(t->cmd) : &(t->out);
            if (*buf == NULL) {
                *buf = strdup(s);
                if (*buf == NULL)
                    die_oom();
            } else {
                if (REALLOC_N(*buf, strlen(*buf) + strlen(s) + 1) < 0)
                    die_oom();
                strcat(*buf, s);
            }
        }
        if (t->out != NULL)
            t->out_present = true;
    }
    return result;
}
Beispiel #2
0
/* Check if line is "@end ..." for current command.  If so, advance LINE. */
int
is_end_current_command (ELEMENT *current, char **line,
                        enum command_id *end_cmd)
{
  char *linep;
  char *cmdname;

  linep = *line;

  linep += strspn (linep, whitespace_chars);
  if (!looking_at (linep, "@end"))
    return 0;

  linep += 4;
  if (!strchr (whitespace_chars, *linep))
    return 0;

  linep += strspn (linep, whitespace_chars);
  cmdname = read_command_name (&linep);
  *end_cmd = lookup_command (cmdname);
  free (cmdname);
  if (*end_cmd != current->cmd)
    return 0;

  *line = linep;
  return 1;
}
Beispiel #3
0
/* 835 */
ELEMENT *
parse_texi_file (char *filename)
{
  char *linep, *line = 0;
  ELEMENT *root = new_element (ET_text_root);
  ELEMENT *preamble = 0;

  input_push_file (filename);

  /* Check for preamble. */
  do
    {
      ELEMENT *l;

      /* FIXME: _next_text isn't used in Perl. */
      line = next_text ();
      if (!line)
        abort (); /* Empty file? */

      linep = line; 
      linep += strspn (linep, whitespace_chars);
      if (*linep && !looking_at (linep, "\\input"))
        {
          /* This line is not part of the preamble.  Shove back
             into input stream. */
          input_push_text (line);
          break;
        }

      if (!preamble)
        preamble = new_element (ET_preamble);

      l = new_element (ET_preamble_text);
      text_append (&l->text, line);
      add_to_element_contents (preamble, l);
    }
  while (1);

  if (preamble)
    add_to_element_contents (root, preamble);

  root = parse_texi (root);
  return root;
} /* 916 */
Beispiel #4
0
/* Return the absolute position of the beginning of a tags table in this
   binding starting the search at binding->start. */
long
find_tags_table (SEARCH_BINDING *binding)
{
  SEARCH_BINDING tmp_search;
  long position;

  tmp_search.buffer = binding->buffer;
  tmp_search.start = binding->start;
  tmp_search.end = binding->end;
  tmp_search.flags = S_FoldCase;

  while ((position = find_node_separator (&tmp_search)) != -1 )
    {
      tmp_search.start = position;
      tmp_search.start += skip_node_separator (tmp_search.buffer
          + tmp_search.start);

      if (looking_at (TAGS_TABLE_BEG_LABEL, &tmp_search))
        return position;
    }
  return -1;
}
Beispiel #5
0
static struct match *parse_config(const char *filename)
{
    char line[MAX_LINE], *p;
    FILE *f;
    struct match *list = NULL;
    struct match **ep = &list;
    struct match *m;

    if (!filename)
	filename = syslinux_config_file();

    f = fopen(filename, "r");
    if (!f)
	return list;

    while (fgets(line, sizeof line, f)) {
	p = skipspace(line);

	if (!looking_at(p, "#"))
	    continue;
	p = skipspace(p + 1);

	if (!looking_at(p, "dev"))
	    continue;
	p = skipspace(p + 3);

	m = malloc(sizeof(struct match));
	if (!m)
	    continue;

	memset(m, 0, sizeof *m);
	m->rid_max = 0xff;

	for (;;) {
	    p = skipspace(p);

	    if (looking_at(p, "did")) {
		p = get_did(p + 3, &m->did, &m->did_mask);
	    } else if (looking_at(p, "sid")) {
		p = get_did(p + 3, &m->sid, &m->sid_mask);
	    } else if (looking_at(p, "rid")) {
		p = get_rid_range(p + 3, &m->rid_min, &m->rid_max);
	    } else {
		char *e;

		e = strchr(p, '\n');
		if (*e)
		    *e = '\0';
		e = strchr(p, '\r');
		if (*e)
		    *e = '\0';

		m->filename = strdup(p);
		if (!m->filename)
		    m->did = -1;
		break;		/* Done with this line */
	    }
	}

	dprintf("DEV DID %08x/%08x SID %08x/%08x RID %02x-%02x CMD %s\n",
		m->did, m->did_mask, m->sid, m->sid_mask,
		m->rid_min, m->rid_max, m->filename);

	*ep = m;
	ep = &m->next;
    }

    return list;
}
Beispiel #6
0
char *
read_line (void)
{
  char *line;

  if (!last_line_reusable) {
    int length;
    char *beginning;
    char *end;

  read_next_line:
    line = NULL;
    while (!line && !string_list_is_empty (&list_files)) {
      line = utils_fgets (list_files.first->file, &length);
      if (!line)
	string_list_delete_first_item (&list_files);
    }

    if (!line)
      return NULL;

    list_files.first->line_number++;

    for (beginning = line; *beginning; beginning++) {
      if (!isspace (*beginning))
	break;
    }

    for (end = line + length; end > beginning; end--) {
      if (!isspace (*(end - 1)))
	break;
    }

    *end = 0;
    if (*beginning) {
      char *scan;

      for (scan = beginning; scan < end; scan++) {
	if (*scan == '$') {
	  if (* ++scan == '$') {
	    char *copy_scan;

	    for (copy_scan = scan; copy_scan < end; copy_scan++)
	      *copy_scan = *(copy_scan + 1);

	    end--;
	  }
	  else {
	    char *second_delimiter_scan;

	    for (second_delimiter_scan = scan + 1;
		 second_delimiter_scan < end; second_delimiter_scan++) {
	      if (*second_delimiter_scan == '$')
		break;
	    }

	    if (second_delimiter_scan < end) {
	      const char *substitution;
	      int substitution_length;
	      char *new_line;

	      *second_delimiter_scan = 0;

	      substitution = association_list_find_association (&substitutions,
								scan);
	      if (!substitution) {
		print_error ("undefined substitution symbol `%s'", scan);
		goto error;
	      }

	      substitution_length = strlen (substitution);
	      new_line
		= utils_cat_as_strings (NULL,
					beginning, (scan - 1) - beginning,
					substitution, substitution_length,
					second_delimiter_scan + 1,
					end - (second_delimiter_scan + 1),
					NULL);
	      scan	= new_line + (((scan - 1) - beginning)
				      + substitution_length);
	      beginning = new_line;
	      end	= scan + (end - (second_delimiter_scan + 1));

	      utils_free (line);
	      line = new_line;
	    }
	    else {
	      print_error ("warning: possible unterminated substitution");
	      break;
	    }
	  }
	}
      }

      if (looking_at ("@include_list", &beginning)) {
	if (*beginning) {
	  FILE *new_list_file = fopen (beginning, "r");

	  if (new_list_file) {
	    string_list_prepend_from_buffer (&list_files,
					     beginning, end - beginning);
	    list_files.first->file = new_list_file;
	    list_files.first->line_number = 0;
	  }
	  else {
	    print_error ("can't open file %s for reading", beginning);
	    string_list_empty (&list_files);
	  }
	}
	else {
	  print_error ("name of file to include is missing");
	  string_list_empty (&list_files);
	}

	utils_free (line);
	goto read_next_line;
      }
      else if (looking_at ("@if", &beginning)) {
	const PredefinedCondition *condition = get_condition (&beginning);

	if (!condition)
	  goto error;

	push_condition_stack (condition, 0);

	utils_free (line);
	goto read_next_line;
      }
      else if (looking_at ("@ifnot", &beginning)) {
	const PredefinedCondition *condition = get_condition (&beginning);

	if (!condition)
	  goto error;

	push_condition_stack (condition, 1);

	utils_free (line);
	goto read_next_line;
      }
      else if (looking_at ("@else", &beginning)) {
	if (!condition_stack || condition_stack->is_in_else_clause) {
	  print_error ("unexpected `@else'");
	  goto error;
	}

	condition_stack->is_in_else_clause = 1;

	utils_free (line);
	goto read_next_line;
      }
      else if (looking_at ("@endif", &beginning)) {
	if (!condition_stack) {
	  print_error ("unexpected `@endif'");
	  goto error;
	}

	pop_condition_stack ();

	utils_free (line);
	goto read_next_line;
      }
    }

    if (condition_stack
	&& !(condition_stack->is_true ^ condition_stack->is_in_else_clause)) {
      /* In conditioned block and with false condition: skip line. */
      utils_free (line);
      goto read_next_line;
    }

    string_list_add_from_buffer (&lines, beginning, end - beginning);
    utils_free (line);
  }

  last_line_reusable = 0;
  return lines.last->text;

 error:
  string_list_empty (&list_files);
  utils_free (line);

  return NULL;
}
Beispiel #7
0
static int
do_parse_lists (FILE *h_file, FILE *c_file, const ListDescription *lists)
{
  int k;
  int result = 1;
  int had_c_includes = 0;
  int had_h_includes = 0;
  int in_list = 0;
  int equal_to_last = 0;
  int h_file_line_length = 0;
  int num_c_file_array_elements = 0;
  int pending_linefeeds = 0;
  const char *h_file_enum_name = NULL;
  const char *c_file_array_name = NULL;
  char *last_identifier = NULL;
  char *pending_h_comment = NULL;
  char *pending_c_comment = NULL;
  char *pending_eol_comment = NULL;
  StringBuffer c_file_arrays[NUM_LIST_SORT_ORDERS];
  StringBuffer *list_c_file_array = NULL;
  StringBuffer h_file_enums;

  string_buffer_init (&h_file_top, 0x2000, 0x1000);
  string_buffer_init (&h_file_bottom, 0x2000, 0x1000);
  string_buffer_init (&h_file_enums, 0x2000, 0x1000);

  string_buffer_init (&c_file_top, 0x2000, 0x1000);
  string_buffer_init (&c_file_bottom, 0x2000, 0x1000);
  for (k = 0; k < NUM_LIST_SORT_ORDERS; k++)
    string_buffer_init (&c_file_arrays[k], 0x2000, 0x1000);

  while (1) {
    char *line = read_line ();

    if (!line) {
      while (lists->name && lists->multiple_lists_allowed)
	lists++;

      if (!condition_stack) {
	if (!lists->name) {
	  result = 0;

	  if (lists->list_finalizer) {
	    if (lists->list_finalizer (NULL))
	      result = 1;
	  }
	}
	else {
	  fprintf (stderr,
		   "%s: unexpected end of file: list of type `%s' expected\n",
		   short_program_name, lists->name);
	}
      }
      else {
	fprintf (stderr,
		 "%s: unexpected end of file: condition `%s' unterminated\n",
		 short_program_name, condition_stack->condition->identifier);
      }

      break;
    }

    if (! *line)
      continue;

    if (line[0] == '#') {
      if (line[1] == '>') {
	line = line + 2;
	while (isspace (*line))
	  line++;

	utils_free (pending_h_comment);
	pending_h_comment = utils_duplicate_string (line);

	utils_free (pending_c_comment);
	pending_c_comment = utils_duplicate_string (line);
      }

      continue;
    }

    if (in_list) {
      if (line[0] != '}') {
	char first_char = line[0];
	const char *identifier = NULL;

	if (first_char != '=' && first_char != '+') {
	  if (lists->line_parser1) {
	    if (lists->line_parser1 (&line))
	      break;

	    if (!line)
	      continue;

	    while (*line && isspace (*line))
	      line++;
	  }
	}
	else {
	  if (!h_file_enum_name) {
	    print_error ("`+' and `=' directives are not allowed "
			 "in lists that don't generate enumerations");
	    break;
	  }

	  do
	    line++;
	  while (isspace (*line));
	}

	if ((!pending_eol_comment || ! *pending_eol_comment)
	    && last_identifier
	    && h_file_enum_name)
	  string_buffer_cat_string (&h_file_enums, ",\n");

	if (pending_eol_comment) {
	  if (*pending_eol_comment && h_file_enum_name) {
	    string_buffer_cprintf (&h_file_enums, ",%s/* %s */\n",
				   TABBING (7, h_file_line_length + 1),
				   pending_eol_comment);
	  }

	  utils_free (pending_eol_comment);
	  pending_eol_comment = NULL;
	}

	if (pending_h_comment) {
	  if (*pending_h_comment && h_file_enum_name) {
	    if (last_identifier)
	      string_buffer_add_character (&h_file_enums, '\n');
	    string_buffer_cat_strings (&h_file_enums,
				       "  /* ", pending_h_comment, " */\n",
				       NULL);
	  }

	  utils_free (pending_h_comment);
	  pending_h_comment = NULL;
	}

	if (h_file_enum_name) {
	  identifier = parse_thing (IDENTIFIER, &line, "identifier");
	  if (!identifier)
	    break;

	  string_buffer_cat_strings (&h_file_enums, "  ", identifier, NULL);
	  h_file_line_length = 2 + strlen (identifier);

	  if (first_char == '=' || equal_to_last) {
	    string_buffer_cat_strings (&h_file_enums,
				       " = ", last_identifier, NULL);
	    h_file_line_length += 3 + strlen (last_identifier);
	  }

	  utils_free (last_identifier);
	  last_identifier = utils_duplicate_string (identifier);
	}

	if (first_char != '+') {
	  if (first_char != '=') {
	    if (c_file_array_name && *lists->c_file_array_type) {
	      if (num_c_file_array_elements > 0) {
		string_buffer_add_character (list_c_file_array, ',');
		string_buffer_add_characters (list_c_file_array, '\n',
					      1 + pending_linefeeds);
	      }

	      if (pending_c_comment) {
		if (*pending_c_comment) {
		  if (num_c_file_array_elements > 0)
		    string_buffer_add_character (list_c_file_array, '\n');

		  string_buffer_cat_strings (list_c_file_array,
					     "  /* ", pending_c_comment,
					     " */\n", NULL);
		}

		utils_free (pending_c_comment);
		pending_c_comment = NULL;
	      }
	    }

	    if (c_file_array_name)
	      num_c_file_array_elements++;

	    pending_linefeeds = 0;
	    if (lists->line_parser2 (list_c_file_array, &line, identifier,
				     &pending_eol_comment, &pending_linefeeds))
	      break;

	    if (*line) {
	      print_error ("unexpected characters at the end of line");
	      break;
	    }

	    if (pending_linefeeds < 0) {
	      pending_linefeeds = 0;
	      if (! *line) {
		while (1) {
		  line = read_line ();

		  if (line && ! *line)
		    pending_linefeeds++;
		  else {
		    reuse_last_line (&line);
		    break;
		  }
		}
	      }
	    }
	  }

	  equal_to_last = 0;
	}
	else {
	  if (equal_to_last) {
	    print_error ("second inserted identifier in a row; "
			 "did you mean `='?");
	    break;
	  }

	  equal_to_last = 1;
	}
      }
      else {
	if (!last_identifier && num_c_file_array_elements == 0) {
	  print_error ("empty list `%s'", lists->name);
	  break;
	}

	if (pending_eol_comment) {
	  if (*pending_eol_comment && h_file_enum_name) {
	    string_buffer_cprintf (&h_file_enums, "%s/* %s */",
				   TABBING (7, h_file_line_length),
				   pending_eol_comment);
	  }

	  utils_free (pending_eol_comment);
	  pending_eol_comment = NULL;
	}

	if (lists->list_finalizer) {
	  if (lists->list_finalizer (list_c_file_array))
	    break;
	}

	if (h_file_enum_name) {
	  if (strcmp (h_file_enum_name, "unnamed") != 0) {
	    string_buffer_cat_strings (&h_file_enums,
				       "\n} ", h_file_enum_name, ";\n", NULL);
	  }
	  else
	    string_buffer_cat_string (&h_file_enums, "\n};\n");
	}

	if (c_file_array_name && *lists->c_file_array_type)
	  string_buffer_cat_string (list_c_file_array, "\n};\n");

	if (!lists->multiple_lists_allowed)
	  lists++;

	in_list = 0;
      }
    }
    else {
      if (looking_at ("@include", &line) || looking_at ("@c_include", &line)) {
	if (! *line) {
	  print_error ("filename expected");
	  break;
	}

	if (!had_c_includes) {
	  fputs ("\n\n", c_file);
	  had_c_includes = 1;
	}

	fprintf (c_file, "#include %s\n", line);
      }
      else if (looking_at ("@h_include", &line)) {
	if (! *line) {
	  print_error ("filename expected");
	  break;
	}

	if (had_h_includes != 1) {
	  fputs ((had_h_includes == 0 ? "\n\n" : "\n"), h_file);
	  had_h_includes = 1;
	}

	fprintf (h_file, "#include %s\n", line);
      }
      else if (looking_at ("@define_condition", &line)) {
	const PredefinedCondition *condition = get_condition (&line);

	if (!condition)
	  break;

	if (had_h_includes != 2) {
	  fputs ((had_h_includes == 0 ? "\n\n" : "\n"), h_file);
	  had_h_includes = 2;
	}

	fprintf (h_file, "#define %s%s%d\n",
		 condition->identifier,
		 TABBING (4, 8 + strlen (condition->identifier)),
		 condition->value);
      }
      else {
	const char *identifier = parse_thing (IDENTIFIER, &line, "list name");

	if (!identifier)
	  break;

	if (!lists->name) {
	  print_error ("unexpected list beginning");
	  break;
	}

	if (lists->multiple_lists_allowed
	    && strcmp (identifier, lists->name) != 0
	    && (lists + 1)->name)
	  lists++;

	if (strcmp (identifier, lists->name) == 0) {
	  if (looking_at ("-", &line)) {
	    if (lists->enumeration_required) {
	      print_error ("enumeration name expected");
	      break;
	    }

	    h_file_enum_name = NULL;
	  }
	  else {
	    h_file_enum_name = parse_thing (IDENTIFIER, &line,
					    "enumeration name");
	    if (!h_file_enum_name)
	      break;
	  }

	  if (!lists->c_file_array_type) {
	    if (!looking_at ("-", &line)) {
	      print_error ("unexpected array name");
	      break;
	    }

	    c_file_array_name = NULL;
	  }
	  else {
	    if (looking_at ("-", &line)) {
	      print_error ("array name expected");
	      break;
	    }

	    c_file_array_name = parse_thing (IDENTIFIER, &line,
					     "array name");
	    if (!c_file_array_name)
	      break;
	  }

	  if (*line != '{') {
	    print_error ("list opening brace expected");
	    break;
	  }

	  if (*(line + 1)) {
	    print_error ("unexpected characters at the end of line");
	    break;
	  }

	  if (pending_h_comment) {
	    if (*pending_h_comment && h_file_enum_name) {
	      string_buffer_cat_strings (&h_file_enums,
					 "/* ", pending_h_comment, " */\n",
					 NULL);
	    }

	    utils_free (pending_h_comment);
	    pending_h_comment = NULL;
	  }

	  assert (0 <= lists->sort_order
		  && lists->sort_order <= NUM_LIST_SORT_ORDERS);
	  list_c_file_array = &c_file_arrays[lists->sort_order];

	  if (h_file_enum_name) {
	    if (strcmp (h_file_enum_name, "unnamed") != 0)
	      string_buffer_cat_string (&h_file_enums, "\n\ntypedef enum {\n");
	    else
	      string_buffer_cat_string (&h_file_enums, "\n\nenum {\n");
	  }

	  if (c_file_array_name && *lists->c_file_array_type) {
	    string_buffer_cat_strings (list_c_file_array,
				       "\n\n", lists->c_file_array_type,
				       c_file_array_name, "[] = {\n", NULL);
	  }

	  if (lists->list_initializer) {
	    if (lists->list_initializer (list_c_file_array,
					 h_file_enum_name, c_file_array_name))
	      break;
	  }

	  in_list		    = 1;
	  equal_to_last		    = 0;
	  num_c_file_array_elements = 0;
	  pending_linefeeds	    = 1;

	  utils_free (last_identifier);
	  last_identifier = NULL;
	}
	else {
	  print_error ("list name `%s' expected, got `%s'",
		       lists->name, identifier);
	  break;
	}
      }
    }
  }

  if (h_file_top.length > 0)
    fwrite (h_file_top.string, h_file_top.length, 1, h_file);

  if (h_file_enums.length > 0)
    fwrite (h_file_enums.string, h_file_enums.length, 1, h_file);

  if (h_file_bottom.length > 0)
    fwrite (h_file_bottom.string, h_file_bottom.length, 1, h_file);

  string_buffer_dispose (&h_file_top);
  string_buffer_dispose (&h_file_bottom);
  string_buffer_dispose (&h_file_enums);

  if (c_file_top.length > 0)
    fwrite (c_file_top.string, c_file_top.length, 1, c_file);

  for (k = 0; k < NUM_LIST_SORT_ORDERS; k++) {
    fwrite (c_file_arrays[k].string, c_file_arrays[k].length, 1, c_file);
    string_buffer_dispose (&c_file_arrays[k]);
  }

  if (c_file_bottom.length > 0)
    fwrite (c_file_bottom.string, c_file_bottom.length, 1, c_file);

  string_buffer_dispose (&c_file_top);
  string_buffer_dispose (&c_file_bottom);

  utils_free (last_identifier);
  utils_free (pending_h_comment);
  utils_free (pending_c_comment);
  utils_free (pending_eol_comment);

  string_list_empty (&lines);

  return result;
}
Beispiel #8
0
int
parse_list_main (int argc, char *argv[],
		 const ListDescriptionSet *list_sets, int num_sets,
		 const PredefinedCondition *conditions)
{
  int option;
  int result = 255;

  utils_remember_program_name (argv[0]);

  while ((option = getopt_long (argc, argv, "D:", parse_list_options, NULL))
	 != -1) {
    switch (option) {
    case OPTION_HELP:
      print_usage (stdout);
      printf ("%s", help_string);

      result = 0;
      goto exit_parse_list_main;

    case 'D':
      {
	const char *delimiter = strchr (optarg, '=');

	if (delimiter) {
	  if (memchr (optarg, '$', delimiter - optarg)) {
	    fprintf (stderr,
		     ("%s: fatal: "
		      "substitution name cannot contain dollar signs\n"),
		     short_program_name);
	    goto exit_parse_list_main;
	  }

	  string_list_add_from_buffer (&substitutions,
				       optarg, delimiter - optarg);
	  substitutions.last->association
	    = utils_duplicate_string (delimiter + 1);
	}
	else {
	  string_list_add (&substitutions, optarg);
	  substitutions.last->association = utils_duplicate_string ("");
	}
      }

      break;

    default:
      fprintf (stderr, "Try `%s --help' for more information.\n",
	       full_program_name);
      goto exit_parse_list_main;
    }
  }

  if (argc - optind == 3) {
    char *list_file_name = argv[optind];
    char *h_file_name	 = argv[optind + 1];
    char *c_file_name	 = argv[optind + 2];
    FILE *list_file	 = open_file (list_file_name, 0);

    if (list_file) {
      char *line;
      const ListDescription *lists = NULL;
      int k;

      string_list_prepend (&list_files, list_file_name);
      list_files.first->file = list_file;
      list_files.first->line_number = 0;

      do
	line = read_line ();
      while (line && (! *line || *line == '#'));

      if (looking_at ("@mode", &line)) {
	const char *mode = parse_thing (IDENTIFIER, &line, "mode name");

	if (mode) {
	  for (k = 0; k < num_sets; k++) {
	    if (strcmp (mode, list_sets[k].mode_name) == 0) {
	      lists = list_sets[k].lists;
	      break;
	    }
	  }

	  if (!lists)
	    print_error ("fatal: unknown mode `%s'", mode);
	}
      }
      else
	print_error ("fatal: `@mode' expected");

      if (lists) {
	FILE *h_file = open_file (h_file_name, 1);

	if (h_file) {
	  FILE *c_file = open_file (c_file_name, 1);

	  if (c_file) {
	    static const char *preamble =
	      "/* This file is automatically generated by `%s'.\n"
	      " * Do not modify it, edit `%s' instead.\n"
	      " */\n";

	    int n;
	    int h_file_name_length = strlen (h_file_name);

	    fprintf (h_file, preamble, short_program_name, list_file_name);
	    fprintf (c_file, preamble, short_program_name, list_file_name);

	    for (k = h_file_name_length; k >= 1; k--) {
	      if (h_file_name[k - 1] == DIRECTORY_SEPARATOR)
		break;
	    }

	    for (n = 0; k < h_file_name_length; k++) {
	      if (isalnum (h_file_name[k]))
		h_file_name[n++] = toupper (h_file_name[k]);
	      else if (h_file_name[k] == '.'
		       || h_file_name[k] == '_'
		       || h_file_name[k] == '-')
		h_file_name[n++] = '_';
	    }

	    h_file_name[n] = 0;
	    if (n > 4 && strcmp (h_file_name + n - 4, "_NEW") == 0)
	      h_file_name[n - 4] = 0;

	    fprintf (h_file, "\n\n#ifndef QUARRY_%s\n#define QUARRY_%s\n",
		     h_file_name, h_file_name);

	    predefined_conditions = conditions;
	    result = do_parse_lists (h_file, c_file, lists);

	    fprintf (h_file, "\n\n#endif /* QUARRY_%s */\n", h_file_name);

	    fclose (c_file);
	  }

	  fclose (h_file);
	}
      }

      string_list_empty (&list_files);

      while (condition_stack)
	pop_condition_stack ();
    }
  }
  else {
    print_usage (stderr);
    fprintf (stderr, "Try `%s --help' for more information.\n",
	     full_program_name);
  }

 exit_parse_list_main:
  string_list_empty (&substitutions);
  utils_free_program_name_strings ();

  return result;
}
Beispiel #9
0
const char *
parse_thing (Thing thing, char **line, const char *type)
{
  const char *value;

  while (*line && ! **line)
    *line = read_line ();

  if (! *line) {
    print_error ("%s expected", type);
    return NULL;
  }

  value = *line;

  if (thing != STRING && thing != STRING_OR_NULL
      && (thing != STRING_OR_IDENTIFIER || **line != '"')) {
    do {
      int expected_character;

      switch (thing) {
      case IDENTIFIER:
      case STRING_OR_IDENTIFIER:
	expected_character = (isalpha (**line) || **line == '_'
			      || (*line != value && isdigit (**line)));
	break;

      case PROPERTY_IDENTIFIER:
	expected_character = isupper (**line);
	break;

      case FIELD_NAME:
	expected_character = (isalpha (**line)
			      || **line == '_' || ** line == '['
			      || (*line != value && (isdigit (**line)
						     || **line == '.'
						     || **line == ']')));
	break;

      case INTEGER_NUMBER:
	expected_character = isdigit (**line);
	break;

      case FLOATING_POINT_NUMBER:
	expected_character = isdigit (**line) || **line == '.';
	break;

      case TIME_VALUE:
	expected_character = (isdigit (**line)
			      || **line == ':' || **line == '.');
	break;

      default:
	assert (0);
      }

      if (!expected_character) {
	print_error ("unexpected character '%c' in %s", **line, type);
	return NULL;
      }

      (*line)++;
    } while (**line && !isspace (**line));
  }
  else {
    if (thing == STRING_OR_NULL) {
      char *possible_null = *line;

      if (looking_at ("NULL", line)) {
	*(possible_null + 4) = 0;
	return possible_null;
      }
    }

    if (**line != '"') {
      print_error ("string%s expected",
		   (thing == STRING ? "" : (thing == STRING_OR_NULL
					    ? " or NULL" : "or identifier")));
      return NULL;
    }

    while (1) {
      (*line)++;

      if (! **line || (**line == '\\' && ! *(*line + 1))) {
	print_error ("unterminated string");
	return NULL;
      }

      if (**line == '"') {
	(*line)++;
	break;
      }

      if (**line == '\\')
	(*line)++;
    }
  }

  if (**line) {
    **line = 0;
    do
      (*line)++;
    while (isspace (**line));
  }

  return value;
}