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