Ticket #94: pci-header.2.awk

File pci-header.2.awk, 6.7 KB (added by johndrinkwater, 18 years ago)

Cleaner, nicer formatting, and w/ comments

Line 
1# PCI Header script
2#
3# Copyright 2006, Haiku.
4# Distributed under the terms of the MIT License.
5#
6# Authors:
7# John Drinkwater, john@nextraweb.com
8#
9# Use with http://pciids.sourceforge.net/pci.ids
10# run as: awk -v HEADERFILE=pcihdr.h -f pci-header.awk pci.ids
11
12BEGIN {
13
14 # field separator, defining because user could have overridden
15 FS = " "
16
17 # Pass this in from outside with -v HEADERFILE=filenametouse
18 # we require pcihdr.h for our system
19 ofile = HEADERFILE
20
21 # possibly use this in the future
22 cleanvalues = "[^A-Za-z0-9{}\"'&@?!*.,:;+<> \\t\\/_\\[\\]=#()-]"
23 # ToDo: currently IDs aren't checked, we dumbly assume the source is clean
24
25 # descriptive output header
26 print "#if 0" > ofile
27 print "#\tPCIHDR.H: PCI Vendors, Devices, and Class Type information\n#" > ofile
28 print "#\tGenerated by pci-header.awk, source data from the following URI:\n#\thttp://pciids.sourceforge.net/pci.ids\n#" > ofile
29 print "#\tHeader created on " strftime( "%A, %d %b %Y %H:%M:%S %Z", systime() ) > ofile
30 print "#endif" > ofile
31
32 # and we start with vendors..
33 print "\ntypedef struct _PCI_VENTABLE\n{\n\tunsigned short\tVenId ;\n\tchar *\tVenFull ;\n} PCI_VENTABLE, *PPCI_VENTABLE ;\n" > ofile
34 print "PCI_VENTABLE\tPciVenTable [] =\n{" > ofile
35}
36
37# matches vendor - starts with an id as first thing on the line
38# because this occurs first in the header file, we output it without worry
39/^[[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]] / {
40
41 if ( vendorcount++ > 0 ) {
42 formatting = ",\n"
43 } else {
44 formatting = ""
45 }
46
47 # store vendor ID for possible devices afterwards
48 vendorid = $1
49 vendor = substr($0, 7)
50 gsub( /\"/, "\\\"", vendor )
51
52 printf formatting "\t{ 0x" vendorid ", \"" vendor "\" }" > ofile
53}
54
55# matches device
56/^\t[[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]] / {
57
58 device = substr($0, 8)
59 gsub( /\"/, "\\\"", device )
60
61 devicecount++
62 devices[devicecount, 1] = vendorid
63 devices[devicecount, 2] = $1
64 devices[devicecount, 3] = device
65}
66
67# matches subvendor device
68/^\t\t[[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]] / {
69
70 device = substr($0, 14)
71 gsub( /\"/, "\\\"", device )
72
73 devicecount++
74 devices[devicecount, 1] = $1
75 devices[devicecount, 2] = $2
76 devices[devicecount, 3] = device
77}
78
79# match device class - store data for later
80/^C [[:xdigit:]][[:xdigit:]] / {
81
82 class = $2
83 classname = substr($0, 7)
84 gsub( /\"/, "\\\"", classname )
85}
86
87# match subclass, use device class data captured earlier, and output
88/^\t[[:xdigit:]][[:xdigit:]] / {
89
90 subclass = $1
91 subclassname = substr($0, 6)
92 gsub( /\"/, "\\\"", subclassname )
93
94 classcount++
95 classes[classcount, 1] = class
96 classes[classcount, 2] = subclass
97 classes[classcount, 3] = "00"
98 classes[classcount, 4] = classname
99 classes[classcount, 5] = subclassname
100 classes[classcount, 6] = ""
101}
102
103# match programming interface
104/^\t\t[[:xdigit:]][[:xdigit:]] / {
105
106 proginterface = $1
107 proginterfacename = substr($0, 7)
108 gsub( /\"/, "\\\"", proginterfacename )
109
110 classcount++
111 classes[classcount, 1] = class
112 classes[classcount, 2] = subclass
113 classes[classcount, 3] = proginterface
114 classes[classcount, 4] = classname
115 classes[classcount, 5] = subclassname
116 classes[classcount, 6] = proginterfacename
117}
118
119# We've processed the file, now output.
120END {
121
122 print "\n};\n\n// Use this value for loop control during searching:\n#define\tPCI_VENTABLE_LEN\t(sizeof(PciVenTable)/sizeof(PCI_VENTABLE))\n" > ofile
123
124 if ( devicecount > 0 ) {
125
126 print "typedef struct _PCI_DEVTABLE\n{\n\tunsigned short VenId ;\n\tunsigned short DevId ;\n\tchar *\tChipDesc ;\n} PCI_DEVTABLE, *PPCI_DEVTABLE ;\n" > ofile
127 print "PCI_DEVTABLE\tPciDevTable [] =\n{" > ofile
128 for (i = 1; i <= devicecount; i++) {
129
130 if (i != 1) {
131 formatting = ",\n"
132 } else {
133 formatting = ""
134 }
135 printf formatting "\t{ 0x" devices[i, 1] ", 0x" devices[i, 2] ", \"" devices[i, 3] "\" }" > ofile
136 }
137 print "\n} ;\n\n// Use this value for loop control during searching:\n#define PCI_DEVTABLE_LEN (sizeof(PciDevTable)/sizeof(PCI_DEVTABLE))\n" > ofile
138
139 }
140
141 if ( classcount > 0 ) {
142 print "typedef struct _PCI_CLASSCODETABLE\n{\n\tunsigned char BaseClass ;\n\tunsigned char SubClass ;\n\tunsigned char ProgIf ;" > ofile
143 print "\tchar *\t\tBaseDesc ;\n\tchar *\t\tSubDesc ;\n\tchar *\t\tProgDesc ;\n} PCI_CLASSCODETABLE, *PPCI_CLASSCODETABLE ;\n" > ofile
144 print "PCI_CLASSCODETABLE PciClassCodeTable [] =\n{" > ofile
145 currentclass = classes[1, 1]
146 for (i = 1; i <= classcount; i++) {
147
148 if (i != 1) {
149 formatting = ",\n"
150 } else {
151 formatting = ""
152 }
153
154 # pretty print separate classes
155 if ( currentclass != classes[i, 1] ) {
156 formatting = formatting "\n"
157 currentclass = classes[i, 1]
158 }
159
160 # if the next item has the same details, we know we're to skip ourselves
161 # this is because the programming interface name needs to be used, and we dont have it ourselves
162 if ( ( classes[i, 1] != classes[i+1, 1] ) || ( classes[i, 2] != classes[i+1, 2] ) || ( classes[i, 3] != classes[i+1, 3] ) ) {
163 printf formatting "\t{ 0x" classes[i, 1] ", 0x" classes[i, 2] ", 0x" classes[i, 3] ", \"" classes[i, 4] "\", \"" classes[i, 5] "\", \"" classes[i, 6] "\" }" > ofile
164 }
165 }
166 print "\n} ;\n\n// Use this value for loop control during searching:\n#define PCI_CLASSCODETABLE_LEN (sizeof(PciClassCodeTable)/sizeof(PCI_CLASSCODETABLE))\n" > ofile
167
168 }
169
170 # this is rather ugly, maybe we should include this in a seperate file, and pull it in ?
171 print "char *\tPciCommandFlags [] =\n{\n\t\"I/O Access\",\n\t\"Memory Access\",\n\t\"Bus Mastering\",\n\t\"Special Cycles\",\n\t\"Memory Write & Invalidate\",\n\t\"Palette Snoop\",\n\t\"Parity Errors\",\n\t\"Wait Cycles\",\n\t\"System Errors\",\n\t\"Fast Back-To-Back\",\n\t\"Reserved 10\",\n\t\"Reserved 11\",\n\t\"Reserved 12\",\n\t\"Reserved 13\",\n\t\"Reserved 14\",\n\t\"Reserved 15\"\n} ;\n" > ofile
172 print "// Use this value for loop control during searching:\n#define PCI_COMMANDFLAGS_LEN (sizeof(PciCommandFlags)/sizeof(char *))\n" > ofile
173 print "char *\tPciStatusFlags [] =\n{\n\t\"Reserved 0\",\n\t\"Reserved 1\",\n\t\"Reserved 2\",\n\t\"Reserved 3\",\n\t\"Reserved 4\",\n\t\"66 MHz Capable\",\n\t\"User-Defined Features\",\n\t\"Fast Back-To-Back\",\n\t\"Data Parity Reported\",\n\t\"\",\n\t\"\",\n\t\"Signalled Target Abort\",\n\t\"Received Target Abort\",\n\t\"Received Master Abort\",\n\t\"Signalled System Error\",\n\t\"Detected Parity Error\"\n} ;\n" > ofile
174 print "// Use this value for loop control during searching:\n#define PCI_STATUSFLAGS_LEN (sizeof(PciStatusFlags)/sizeof(char *))\n" > ofile
175 print "char *\tPciDevSelFlags [] =\n{\n\t\"Fast Devsel Speed\",\n\t\"Medium Devsel Speed\",\n\t\"Slow Devsel Speed\",\n\t\"Reserved 9&10\"\n} ;\n" > ofile
176 print "// Use this value for loop control during searching:\n#define PCI_DEVSELFLAGS_LEN (sizeof(PciDevSelFlags)/sizeof(char *))\n\n" > ofile
177
178 close(ofile)
179}
180
181