Exemple #1
0
/****************************************************************************
 * parse_assignment
 *
 * Parse the string 'arg' (which supposedly represents an assignment) into a
 * NAME and a VALUE.  If 'arg' does not conform to the proper assignment
 * syntax, exit with a usage message.  Otherwise, on return, 'arg' is broken
 * into substrings representing NAME and VALUE, and *name and *value are set
 * to point to these two substrings.
 ****************************************************************************/
static void parse_assignment(char arg[], const char **name, const char **value)
{
	static const size_t N_MATCHES = 4;
	regmatch_t match[N_MATCHES];
	regex_t assignment;

	compile_reg_expr(REG_EXTENDED | REG_NEWLINE, assignment_regex, &assignment);

	/* Does 'arg' conform to proper assignment syntax?  If not, exit with a
	 * usage message.
	 */
	if (regexec(&assignment, arg, N_MATCHES, match, 0))
		usage(stderr);

	/* Ok, we found a valid assignment.  Break it into two strings
	 * representing NAME and VALUE.
	 */
	arg[match[1].rm_eo] = '\0';
	arg[match[2].rm_eo] = '\0';
	*name = &arg[match[1].rm_so];
	*value = &arg[match[2].rm_so];

	regfree(&assignment);
}
Exemple #2
0
/****************************************************************************
 * process_input_file
 *
 * Read the contents of file 'f' and return a pointer to a list of pending
 * write operations.  Perform sanity checking on all write operations and
 * exit with an error message if there is a problem.
 ****************************************************************************/
cmos_write_t *process_input_file(FILE * f)
{
	static const int LINE_BUF_SIZE = 256;
	static const size_t N_MATCHES = 4;
	char line[LINE_BUF_SIZE];
	const char *name, *value;
	cmos_write_t *list, *item, **p;
	regex_t blank_or_comment, assignment;
	regmatch_t match[N_MATCHES];
	const cmos_entry_t *e;

	list = NULL;
	p = &list;

	compile_reg_expr(REG_EXTENDED | REG_NEWLINE, blank_or_comment_regex, &blank_or_comment);
	compile_reg_expr(REG_EXTENDED | REG_NEWLINE, assignment_regex, &assignment);

	/* each iteration processes one line from input file */
	for (line_num = 1; get_input_file_line(f, line, LINE_BUF_SIZE) == OK; line_num++) {	/* skip comments and blank lines */
		if (!regexec(&blank_or_comment, line, 0, NULL, 0))
			continue;

		/* Is this a valid assignment line?  If not, then it's a syntax
		 * error.
		 */
		if (regexec(&assignment, line, N_MATCHES, match, 0)) {
			fprintf(stderr,
				"%s: Syntax error on line %d of input file.\n",
				prog_name, line_num);
			exit(1);
		}

		/* OK, we found an assignment.  Break the line into substrings
		 * representing the lefthand and righthand sides of the assignment.
		 */
		line[match[1].rm_eo] = '\0';
		line[match[2].rm_eo] = '\0';
		name = &line[match[1].rm_so];
		value = &line[match[2].rm_so];

		/* now look up the coreboot parameter name */
		if (is_checksum_name(name)
		    || (e = find_cmos_entry(name)) == NULL) {
			fprintf(stderr,
				"%s: Error on line %d of input file: CMOS parameter "
				"%s not found.\n", prog_name, line_num, name);
			exit(1);
		}

		/* At this point, we figure out what numeric value needs to be written
		 * to which location.  At the same time, we perform sanity checking on
		 * the write operation.
		 */

		if ((item = (cmos_write_t *) malloc(sizeof(*item))) == NULL)
			out_of_memory();

		item->bit = e->bit;
		item->length = e->length;
		item->config = e->config;
		item->value = try_prepare_cmos_write(e, value);

		/* Append write operation to pending write list. */
		item->next = NULL;
		*p = item;
		p = &item->next;
	}

	regfree(&blank_or_comment);
	regfree(&assignment);
	return list;
}
Exemple #3
0
/****************************************************************************
 * process_layout_file
 *
 * Read CMOS layout information from file 'f' and add it to our internal
 * repository.
 ****************************************************************************/
static void process_layout_file(FILE * f)
{
	compile_reg_expr(REG_EXTENDED | REG_NEWLINE, blank_or_comment_regex, &blank_or_comment_expr);
	compile_reg_expr(REG_EXTENDED | REG_NEWLINE, start_entries_regex, &start_entries_expr);
	compile_reg_expr(REG_EXTENDED | REG_NEWLINE, entries_line_regex, &entries_line_expr);
	compile_reg_expr(REG_EXTENDED | REG_NEWLINE, start_enums_regex, &start_enums_expr);
	compile_reg_expr(REG_EXTENDED | REG_NEWLINE, enums_line_regex, &enums_line_expr);
	compile_reg_expr(REG_EXTENDED | REG_NEWLINE, start_checksums_regex, &start_checksums_expr);
	compile_reg_expr(REG_EXTENDED | REG_NEWLINE, checksum_line_regex, &checksum_line_expr);
	line_num = 1;
	skip_past_start(f);

	/* Skip past all entries.  We will process these later when we
	 * make a second pass through the file.
	 */
	while (!process_entry(f, 1)) ;

	/* Process all enums, adding them to our internal repository as
	 * we go. */

	if (process_enum(f, 0)) {
		fprintf(stderr, "%s: Error: CMOS layout file contains no "
			"enumerations.\n", prog_name);
		exit(1);
	}

	while (!process_enum(f, 0)) ;

	/* Go back to start of file. */
	line_num = 1;
	fseek(f, 0, SEEK_SET);

	skip_past_start(f);

	/* Process all entries, adding them to the repository as we go.
	 * We must add the entries after the enums, even though they
	 * appear in the layout file before the enums.  This is because
	 * the entries are sanity checked against the enums as they are
	 * added.
	 */

	if (process_entry(f, 0)) {
		fprintf(stderr,
			"%s: Error: CMOS layout file contains no entries.\n",
			prog_name);
		exit(1);
	}

	while (!process_entry(f, 0)) ;

	/* Skip past all enums.  They have already been processed. */
	while (!process_enum(f, 1)) ;

	/* Process CMOS checksum info. */
	process_checksum_info(f);

	/* See if there are any lines left to process.  If so, verify
	 * that they are all either blank lines or comments.
	 */
	skip_remaining_lines(f);

	regfree(&blank_or_comment_expr);
	regfree(&start_entries_expr);
	regfree(&entries_line_expr);
	regfree(&start_enums_expr);
	regfree(&enums_line_expr);
	regfree(&start_checksums_expr);
	regfree(&checksum_line_expr);
}