1 /*
2  *	Generate devlist.h and classlist.h from the PCI ID file.
3  *
4  *	(c) 1999--2002 Martin Mares <mj@ucw.cz>
5  */
6 
7 #include <stdio.h>
8 #include <string.h>
9 
10 #define MAX_NAME_SIZE 79
11 
12 static void
pq(FILE * f,const char * c)13 pq(FILE *f, const char *c)
14 {
15 	while (*c) {
16 		if (*c == '"')
17 			fprintf(f, "\\\"");
18 		else {
19 			fputc(*c, f);
20 			if (*c == '?' && c[1] == '?') {
21 				/* Avoid trigraphs */
22 				fprintf(f, "\" \"");
23 			}
24 		}
25 		c++;
26 	}
27 }
28 
29 int
main(void)30 main(void)
31 {
32 	char line[1024], *c, *bra, vend[8];
33 	int vendors = 0;
34 	int mode = 0;
35 	int lino = 0;
36 	int vendor_len = 0;
37 	FILE *devf, *clsf;
38 
39 	devf = fopen("devlist.h", "w");
40 	clsf = fopen("classlist.h", "w");
41 	if (!devf || !clsf) {
42 		fprintf(stderr, "Cannot create output file!\n");
43 		return 1;
44 	}
45 
46 	while (fgets(line, sizeof(line)-1, stdin)) {
47 		lino++;
48 		if ((c = strchr(line, '\n')))
49 			*c = 0;
50 		if (!line[0] || line[0] == '#')
51 			continue;
52 		if (line[1] == ' ') {
53 			if (line[0] == 'C' && strlen(line) > 4 && line[4] == ' ') {
54 				vend[0] = line[2];
55 				vend[1] = line[3];
56 				vend[2] = 0;
57 				mode = 2;
58 			} else goto err;
59 		}
60 		else if (line[0] == '\t') {
61 			if (line[1] == '\t')
62 				continue;
63 			switch (mode) {
64 			case 1:
65 				if (strlen(line) > 5 && line[5] == ' ') {
66 					c = line + 5;
67 					while (*c == ' ')
68 						*c++ = 0;
69 					if (vendor_len + strlen(c) + 1 > MAX_NAME_SIZE) {
70 						/* Too long, try cutting off long description */
71 						bra = strchr(c, '[');
72 						if (bra && bra > c && bra[-1] == ' ')
73 							bra[-1] = 0;
74 						if (vendor_len + strlen(c) + 1 > MAX_NAME_SIZE) {
75 							fprintf(stderr, "Line %d: Device name too long\n", lino);
76 							fprintf(stderr, "%s\n", c);
77 							return 1;
78 						}
79 					}
80 					fprintf(devf, "\tDEVICE(%s,%s,\"", vend, line+1);
81 					pq(devf, c);
82 					fputs("\")\n", devf);
83 				} else goto err;
84 				break;
85 			case 2:
86 				if (strlen(line) > 3 && line[3] == ' ') {
87 					c = line + 3;
88 					while (*c == ' ')
89 						*c++ = 0;
90 					fprintf(clsf, "CLASS(%s%s, \"%s\")\n", vend, line+1, c);
91 				} else goto err;
92 				break;
93 			default:
94 				goto err;
95 			}
96 		} else if (strlen(line) > 4 && line[4] == ' ') {
97 			c = line + 4;
98 			while (*c == ' ')
99 				*c++ = 0;
100 			if (vendors)
101 				fputs("ENDVENDOR()\n\n", devf);
102 			vendors++;
103 			strcpy(vend, line);
104 			vendor_len = strlen(c);
105 			if (vendor_len + 24 > MAX_NAME_SIZE) {
106 				fprintf(stderr, "Line %d: Vendor name too long\n", lino);
107 				return 1;
108 			}
109 			fprintf(devf, "VENDOR(%s,\"", vend);
110 			pq(devf, c);
111 			fputs("\")\n", devf);
112 			mode = 1;
113 		} else {
114 		err:
115 			fprintf(stderr, "Line %d: Syntax error in mode %d: %s\n", lino, mode, line);
116 			return 1;
117 		}
118 	}
119 	fputs("ENDVENDOR()\n\
120 \n\
121 #undef VENDOR\n\
122 #undef DEVICE\n\
123 #undef ENDVENDOR\n", devf);
124 	fputs("\n#undef CLASS\n", clsf);
125 
126 	fclose(devf);
127 	fclose(clsf);
128 
129 	return 0;
130 }
131