コード例 #1
0
ファイル: configuration.c プロジェクト: ejona86/quarry
void
configuration_set_string_list_value (StringList *configuration_variable,
				     const StringList *string_list)
{
  assert (configuration_variable);
  assert (string_list);

  string_list_empty (configuration_variable);
  string_list_duplicate_items (configuration_variable, string_list);
}
コード例 #2
0
ファイル: configuration.c プロジェクト: ejona86/quarry
void
configuration_set_string_list_value_steal_strings
  (StringList *configuration_variable, StringList *string_list)
{
  assert (configuration_variable);
  assert (string_list);

  string_list_empty (configuration_variable);
  string_list_steal_items (configuration_variable, string_list);
}
コード例 #3
0
ファイル: veentry.cpp プロジェクト: OpenVZ/vzmigrate
/* 0 - ipadd, 1 - ipdel*/
static int ipset(const char *ctid, const char *cmd, struct string_list *iplist)
{
	int rc;
	struct string_list argv;
	struct string_list_el *p;

	if (string_list_empty(iplist))
		return 0;

	string_list_init(&argv);

	string_list_add(&argv, BIN_VZCTL);
	string_list_add(&argv, "--skiplock");
	string_list_add(&argv, "--skipowner");
	string_list_add(&argv, "set");
	string_list_add(&argv, ctid);

	string_list_for_each(iplist, p) {
		string_list_add(&argv, cmd);
		string_list_add(&argv, p->s);
	}
コード例 #4
0
ファイル: util.c プロジェクト: OpenVZ/vzmigrate
/* run arglist[0] with arglist and redirect std{in,out,err} */
int run_rw(int in, int out, int err, struct string_list *arglist)
{
	pid_t pid, wpid;
	int status, retcode;
	char *fn;

	if (string_list_empty(arglist)) {
		fprintf(stderr, "arglist is empty\n");
		return -1;
	}
	fn = arglist->tqh_first->s;

	wpid = fork();
	if (wpid < 0) {
		fprintf(stderr, "fork() err: %m\n");
		return -1;
	} else if (wpid == 0) {
		char **argv;
		int i;

		string_list_to_array(arglist, &argv);
		for (i = 0; argv[i]; i++)
			printf("%s ", argv[i]);
		printf("\n");
		fflush(stdout);

		/* allow C-c for child */
		signal(SIGINT, SIG_DFL);
		close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO);
		dup2(in, STDIN_FILENO);
		dup2(out, STDOUT_FILENO);
		dup2(err, STDERR_FILENO);
		close(in); close(out); close(err);
		/* TODO: last syncronization before start */
		execvp(fn, (char *const *)argv);
		fprintf(stderr, "execve(%s) err: %m\n", fn);
		fflush(stderr);
		exit(-1);
	}

	while ((pid = waitpid(wpid, &status, 0)) == -1)
		if (errno != EINTR)
			break;
	if (pid < 0) {
		fprintf(stderr, "waitpid() err: %m\n");
		return -1;
	}

	if (WIFEXITED(status)) {
		if ((retcode = WEXITSTATUS(status))) {
			fprintf(stderr, "%s failed, exitcode=%d\n",
				fn, retcode);
			return -1;
		}
	} else if (WIFSIGNALED(status)) {
		fprintf(stderr, "%s got signal %d\n",
			fn, WTERMSIG(status));
		return -1;
	} else {
		fprintf(stderr, "%s exited with status %d\n", fn, status);
		return -1;
	}
	return 0;
}
コード例 #5
0
ファイル: configuration.c プロジェクト: ejona86/quarry
int
configuration_read_from_file (const ConfigurationSection *sections,
			      int num_sections, const char *filename)
{
  FILE *file = fopen (filename, "r");

  if (file) {
    const ConfigurationSection *current_section = NULL;
    void *current_section_structure = NULL;
    char *line;

    while ((line = utils_fgets (file, NULL)) != NULL) {
      char *scan;
      int parsing_section_name = 0;

      for (scan = line; *scan == ' ' || *scan == '\t';)
	scan++;

      if (*scan == '[') {
	do
	  scan++;
	while (*scan == ' ' || *scan == '\t');

	parsing_section_name = 1;
      }

      if (IS_ACCEPTABLE_NAME_CHARACTER (*scan)) {
	const char *name = scan;
	char *name_pointer = scan;
	char name_terminating_character;

	while (1) {
	  do
	    *name_pointer++ = *scan++;
	  while (IS_ACCEPTABLE_NAME_CHARACTER (*scan));

	  while (*scan == ' ' || *scan == '\t')
	    scan++;

	  if (IS_ACCEPTABLE_NAME_CHARACTER (*scan))
	    *name_pointer++ = ' ';
	  else
	    break;
	}

	name_terminating_character = *scan;
	*name_pointer = 0;

	if (!parsing_section_name
	    && name_terminating_character == '='
	    && current_section) {
	  const ConfigurationValue *value;
	  int k;

	  for (k = 0, value = current_section->values;
	       k < current_section->num_values; k++, value++) {
	    if (strcasecmp (value->name, name) == 0)
	      break;
	  }

	  if (k < current_section->num_values) {
	    void *field = (((char *) current_section_structure)
			   + value->field_offset);

	    scan++;

	    if (value->type & VALUE_TYPE_IS_NULLABLE) {
	      const char *null_scan = scan;
	      int is_null = 0;

	      while (*null_scan == ' ' || *null_scan == '\t')
		null_scan++;

	      if (strncasecmp (null_scan, "null", 4) == 0) {
		null_scan += 4;
		while (*null_scan == ' ' || *null_scan == '\t')
		  null_scan++;

		if (!*null_scan || *null_scan == '\n' || *null_scan == '\r') {
		  /* FIXME: Not exactly right since we don't always
		   *	    assign a value below.
		   */
		  is_null = 1;
		}
	      }

	      /* FIXME: Not nice. */
	      * ((int *) (field) - 1) = is_null;
	    }

	    if (! (value->type & VALUE_TYPE_IS_NULLABLE
		   && * ((int *) (field) - 1))) {
	      if ((value->type & ~VALUE_TYPE_IS_NULLABLE)
		  != VALUE_TYPE_STRING_LIST) {
		char *string = parse_string (&scan, 0);

		if (string) {
		  if ((value->type & ~VALUE_TYPE_IS_NULLABLE)
		      == VALUE_TYPE_STRING) {
		    utils_free (* (char **) field);
		    * (char **) field = string;
		  }
		  else {
		    char *actual_contents = NULL;
		    char *whitespace_scan;
		    int enumeration_value = 0;

		    for (actual_contents = string;
			 *actual_contents == ' ' || *actual_contents == '\t';)
		      actual_contents++;

		    if ((value->type & ~VALUE_TYPE_IS_NULLABLE)
			== VALUE_TYPE_ENUMERATION) {
		      const char *value_string;
		      int actual_contents_length;

		      /* Trim trailing whitespace. */
		      for (whitespace_scan
			     = (actual_contents
				+ (strlen (actual_contents) - 1));
			   (whitespace_scan >= actual_contents
			    && (*whitespace_scan == ' '
				|| *whitespace_scan == '\t'));)
			whitespace_scan--;

		      *(whitespace_scan + 1) = 0;
		      actual_contents_length = ((whitespace_scan + 1)
						- actual_contents);

		      for (value_string = value->enumeration_values_as_strings,
			     enumeration_value = 0;
			   *value_string; enumeration_value++) {
			do {
			  int value_string_length = strlen (value_string);

			  if (actual_contents_length == value_string_length
			      && (strcasecmp (actual_contents, value_string)
				  == 0)) {
			    * (int *) field = enumeration_value;
			    goto enumeration_value_found;
			  }

			  value_string += value_string_length + 1;
			} while (*value_string);

			value_string++;
		      }
		    }

		    /* Find first whitespace character and break line
		     * at its position.
		     */
		    for (whitespace_scan = actual_contents;
			 (*whitespace_scan != ' ' && *whitespace_scan != '\t'
			  && *whitespace_scan != 0);)
		      whitespace_scan++;

		    *whitespace_scan = 0;

		    switch (value->type & ~VALUE_TYPE_IS_NULLABLE) {
		    case VALUE_TYPE_BOOLEAN:
		    case VALUE_TYPE_BOOLEAN_WRITE_TRUE_ONLY:
		      if (strcasecmp (actual_contents, "true") == 0
			  || strcasecmp (actual_contents, "yes") == 0
			  || strcmp (actual_contents, "1") == 0)
			* (int *) field = 1;
		      else if (strcasecmp (actual_contents, "false") == 0
			       || strcasecmp (actual_contents, "no") == 0
			       || strcmp (actual_contents, "0") == 0)
			* (int *) field = 0;

		      break;

		    case VALUE_TYPE_INT:
		      parse_integer (actual_contents, (int *) field);
		      break;

		    case VALUE_TYPE_ENUMERATION:
		      {
			int numeric_value;

			/* A second attempt, try to parse as numeric
			 * value.  Placed separately, because we have
			 * a different `actual_contents' here, more
			 * suited for numeric parsing.
			 */
			if (parse_integer (actual_contents, &numeric_value)
			    && 0 <= numeric_value
			    && numeric_value < enumeration_value)
			  * (int *) field = numeric_value;
		      }

		      break;

		    case VALUE_TYPE_REAL:
		      utils_parse_double (actual_contents, (double *) field);
		      break;

		    case VALUE_TYPE_COLOR:
		      {
			int num_digits;

			if (*actual_contents == '#')
			  actual_contents++;

			for (num_digits = 0;
			     ((('0' <= *actual_contents
				&& *actual_contents <= '9')
			       || ('a' <= *actual_contents
				   && *actual_contents <= 'f')
			       || ('A' <= *actual_contents
				   && *actual_contents <= 'F'))
			      && num_digits <= 6);
			     num_digits++)
			  actual_contents++;

			if (num_digits == 6 || num_digits == 3) {
			  int red;
			  int green;
			  int blue;

			  if (num_digits == 6) {
			    sscanf (actual_contents - 6, "%2x%2x%2x",
				    &red, &green, &blue);
			  }
			  else {
			    sscanf (actual_contents - 3, "%1x%1x%1x",
				    &red, &green, &blue);
			    red   *= 0x11;
			    green *= 0x11;
			    blue  *= 0x11;
			  }

			  ((QuarryColor *) field)->red   = red;
			  ((QuarryColor *) field)->green = green;
			  ((QuarryColor *) field)->blue  = blue;
			}
		      }

		      break;

		    case VALUE_TYPE_TIME:
		      {
			int seconds = utils_parse_time (actual_contents);

			if (seconds >= 0)
			  * (int *) field = seconds;
		      }

		      break;

		    default:
		      assert (0);
		    }

		  enumeration_value_found:

		    utils_free (string);
		  }
		}
	      }
	      else {
		int first_value = 1;

		do {
		  char *string = parse_string (&scan, ',');

		  if (string) {
		    if (first_value) {
		      string_list_empty (field);
		      first_value = 0;
		    }

		    string_list_add_ready (field, string);
		  }
		  else
		    break;
		} while (*scan++ == ',');
	      }
	    }
	  }
	}
	else if (parsing_section_name
		 && (name_terminating_character == ']'
		     || name_terminating_character == '"')) {
	  int k;
	  const ConfigurationSection *section;

	  current_section = NULL;

	  for (k = 0, section = sections; k < num_sections; k++, section++) {
	    if (strcasecmp (section->name, name) == 0)
	      break;
	  }

	  if (k < num_sections) {
	    if (section->is_repeatable) {
	      char *section_name = NULL;

	      if (name_terminating_character == '"') {
		*scan = name_terminating_character;
		section_name = parse_string (&scan, '"');
	      }

	      if (*scan == ']') {
		string_list_add_ready (section->section_structure,
				       section_name);
		current_section = section;
		current_section_structure = ((StringList *)
					     section->section_structure)->last;

		if (section->section_structure_init)
		  section->section_structure_init (current_section_structure);
	      }
	    }
	    else if (!section->is_repeatable
		     && name_terminating_character == ']') {
	      current_section = section;
	      current_section_structure = section->section_structure;
	    }
	  }
	}
      }

      utils_free (line);
    }

    fclose (file);
    return 1;
  }

  return 0;
}
コード例 #6
0
ファイル: string-list.c プロジェクト: ejona86/quarry
void
string_list_delete (void *abstract_list)
{
  string_list_empty (abstract_list);
  utils_free (abstract_list);
}
コード例 #7
0
ファイル: parse-list.c プロジェクト: ejona86/quarry
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;
}
コード例 #8
0
ファイル: parse-list.c プロジェクト: ejona86/quarry
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;
}
コード例 #9
0
ファイル: parse-list.c プロジェクト: ejona86/quarry
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;
}