brintos

brintos / linux-shallow public Read only

0
0
Text · 3.4 KiB · 904cf47 Raw
174 lines · c
1// SPDX-License-Identifier: MIT2/*3 * Copyright © 2023 Intel Corporation4 */5 6#define _GNU_SOURCE7#include <ctype.h>8#include <errno.h>9#include <stdbool.h>10#include <stdio.h>11#include <string.h>12 13#define HEADER \14	"// SPDX-License-Identifier: MIT\n" \15	"\n" \16	"/*\n" \17	" * DO NOT MODIFY.\n" \18	" *\n" \19	" * This file was generated from rules: %s\n" \20	" */\n" \21	"#ifndef _GENERATED_XE_WA_OOB_\n" \22	"#define _GENERATED_XE_WA_OOB_\n" \23	"\n" \24	"enum {\n"25 26#define FOOTER \27	"};\n" \28	"\n" \29	"#endif\n"30 31static void print_usage(FILE *f)32{33	fprintf(f, "usage: %s <input-rule-file> <generated-c-source-file> <generated-c-header-file>\n",34		program_invocation_short_name);35}36 37static void print_parse_error(const char *err_msg, const char *line,38			      unsigned int lineno)39{40	fprintf(stderr, "ERROR: %s\nERROR: %u: %.60s\n",41		err_msg, lineno, line);42}43 44static char *strip(char *line, size_t linelen)45{46	while (isspace(*(line + linelen)))47		linelen--;48 49	line[linelen - 1] = '\0';50 51	return  line + strspn(line, " \f\n\r\t\v");52}53 54#define MAX_LINE_LEN 409655static int parse(FILE *input, FILE *csource, FILE *cheader)56{57	char line[MAX_LINE_LEN + 1];58	char *name, *prev_name = NULL, *rules;59	unsigned int lineno = 0, idx = 0;60 61	while (fgets(line, sizeof(line), input)) {62		size_t linelen;63		bool is_continuation;64 65		if (line[0] == '\0' || line[0] == '#' || line[0] == '\n') {66			lineno++;67			continue;68		}69 70		linelen = strlen(line);71		if (linelen == MAX_LINE_LEN) {72			print_parse_error("line too long", line, lineno);73			return -EINVAL;74		}75 76		is_continuation = isspace(line[0]);77		name = strip(line, linelen);78 79		if (!is_continuation) {80			name = strtok(name, " \t");81			rules = strtok(NULL, "");82		} else {83			if (!prev_name) {84				print_parse_error("invalid rule continuation",85						  line, lineno);86				return -EINVAL;87			}88 89			rules = name;90			name = NULL;91		}92 93		if (rules[0] == '\0') {94			print_parse_error("invalid empty rule\n", line, lineno);95			return -EINVAL;96		}97 98		if (name) {99			fprintf(cheader, "\tXE_WA_OOB_%s = %u,\n", name, idx);100 101			/* Close previous entry before starting a new one */102			if (idx)103				fprintf(csource, ") },\n");104 105			fprintf(csource, "{ XE_RTP_NAME(\"%s\"),\n  XE_RTP_RULES(%s",106				name, rules);107			idx++;108		} else {109			fprintf(csource, ", OR,\n\t%s", rules);110		}111 112		lineno++;113		if (!is_continuation)114			prev_name = name;115	}116 117	/* Close last entry */118	if (idx)119		fprintf(csource, ") },\n");120 121	fprintf(cheader, "\t_XE_WA_OOB_COUNT = %u\n", idx);122 123	return 0;124}125 126int main(int argc, const char *argv[])127{128	enum {129		ARGS_INPUT,130		ARGS_CSOURCE,131		ARGS_CHEADER,132		_ARGS_COUNT133	};134	struct {135		const char *fn;136		const char *mode;137		FILE *f;138	} args[] = {139		[ARGS_INPUT] = { .fn = argv[1], .mode = "r" },140		[ARGS_CSOURCE] = { .fn = argv[2], .mode = "w" },141		[ARGS_CHEADER] = { .fn = argv[3], .mode = "w" },142	};143	int ret = 1;144 145	if (argc < 3) {146		fprintf(stderr, "ERROR: wrong arguments\n");147		print_usage(stderr);148		return 1;149	}150 151	for (int i = 0; i < _ARGS_COUNT; i++) {152		args[i].f = fopen(args[i].fn, args[i].mode);153		if (!args[i].f) {154			fprintf(stderr, "ERROR: Can't open %s: %m\n",155				args[i].fn);156			goto err;157		}158	}159 160	fprintf(args[ARGS_CHEADER].f, HEADER, args[ARGS_INPUT].fn);161	ret = parse(args[ARGS_INPUT].f, args[ARGS_CSOURCE].f,162		    args[ARGS_CHEADER].f);163	if (!ret)164		fprintf(args[ARGS_CHEADER].f, FOOTER);165 166err:167	for (int i = 0; i < _ARGS_COUNT; i++) {168		if (args[i].f)169			fclose(args[i].f);170	}171 172	return ret;173}174