xref: /haiku/src/apps/devices/usb-header.awk (revision 4a55cc230cf7566cadcbb23b1928eefff8aea9a2)
1# USB Header script
2#
3# Copyright 2006-2012, Haiku.
4# Distributed under the terms of the MIT License.
5#
6# Authors:
7#		John Drinkwater, john@nextraweb.com
8#
9# Use with http://www.linux-usb.org/usb.ids
10# run as: awk -v HEADERFILE=usbhdr.h -f usb-header.awk usb.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 usbhdr.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	inClassesDefinition = 0
26
27	# descriptive output header
28	print "#if 0" > ofile
29	print "#\tUSBHDR.H: USB Vendors, Devices\n#" > ofile
30	print "#\tGenerated by usb-header.awk, source data from the following URI:\n#\thttp://www.linux-usb.org/usb.ids\n#" > ofile
31	print "#\tHeader created on " strftime( "%A, %d %b %Y %H:%M:%S %Z", systime() ) > ofile
32	print "#endif" > ofile
33
34	# and we start with vendors..
35	print "\ntypedef struct _USB_VENTABLE\n{\n\tunsigned short\tVenId ;\n\tconst char *\tVenName ;\n}  USB_VENTABLE, *PUSB_VENTABLE ;\n" > ofile
36	print "USB_VENTABLE\tUsbVenTable [] =\n{" > ofile
37}
38
39# matches vendor - starts with an id as first thing on the line
40# because this occurs first in the header file, we output it without worry
41/^[[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]] / {
42
43	if ( vendorcount++ > 0 ) {
44		formatting = ",\n"
45	} else {
46		formatting = ""
47	}
48
49	# store vendor ID for possible devices afterwards
50	vendorid = $1
51	vendor = substr($0, 7)
52	gsub( /\"/, "&&", vendor )
53
54	printf "%s", formatting "\t{ 0x" vendorid ", \"" vendor "\" }" > ofile
55}
56
57# matches device
58/^\t[[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]] / {
59
60	device = substr($0, 8)
61	gsub( /\\/, "&&", device )
62	gsub( /\"/, "&&", device )
63
64	# store device ID for possible devices afterwards
65	deviceid = $1
66	devicecount++
67	devices[devicecount, 1] = vendorid
68	devices[devicecount, 2] = $1
69	devices[devicecount, 3] = device
70}
71
72# match device class - store data for later
73/^C [[:xdigit:]][[:xdigit:]]  / {
74
75	class = $2
76	classname = substr($0, 7)
77	gsub( /\"/, "\\\"", classname )
78
79	inClassesDefinition = 1
80
81	classcount++
82	classes[classcount, 1] = class
83	classes[classcount, 2] = "00"
84	classes[classcount, 3] = "00"
85	classes[classcount, 4] = classname
86	classes[classcount, 5] = ""
87	classes[classcount, 6] = ""
88}
89
90# match subclass, use device class data captured earlier, and output
91inClassesDefinition && (/^\t[[:xdigit:]][[:xdigit:]]  /) {
92	subclass = $1
93	subclassname = substr($0, 6)
94	gsub( /\"/, "\\\"", subclassname )
95
96	classcount++
97	classes[classcount, 1] = class
98	classes[classcount, 2] = subclass
99	classes[classcount, 3] = "00"
100	classes[classcount, 4] = classname
101	classes[classcount, 5] = subclassname
102	classes[classcount, 6] = ""
103}
104
105# match protocol
106inClassesDefinition && (/^\t\t[[:xdigit:]][[:xdigit:]]  /) {
107
108	protocol = $1
109	protocolname = substr($0, 7)
110	gsub( /\"/, "\\\"", protocolname )
111
112	classcount++
113	classes[classcount, 1] = class
114	classes[classcount, 2] = subclass
115	classes[classcount, 3] = protocol
116	classes[classcount, 4] = classname
117	classes[classcount, 5] = subclassname
118	classes[classcount, 6] = protocolname
119}
120
121#match comments
122/^#/ {
123	inClassesDefinition = false
124}
125
126
127# We've processed the file, now output.
128END {
129
130	print "\n};\n\n// Use this value for loop control during searching:\n#define\tUSB_VENTABLE_LEN\t(sizeof(UsbVenTable)/sizeof(USB_VENTABLE))\n" > ofile
131
132	if ( devicecount > 0 ) {
133
134		print "typedef struct _USB_DEVTABLE\n{\n\tunsigned short	VenId ;\n\tunsigned short	DevId ;\n\tconst char *\tChipDesc ;\n}  USB_DEVTABLE, *PUSB_DEVTABLE ;\n"  > ofile
135		print "USB_DEVTABLE\tUsbDevTable [] =\n{" > ofile
136		for (i = 1; i <= devicecount; i++) {
137
138			if (i != 1) {
139				formatting = ",\n"
140			} else {
141				formatting = ""
142			}
143			printf "%s", formatting "\t{ 0x" devices[i, 1] ", 0x" devices[i, 2] ", \"" devices[i, 3] "\" }" > ofile
144		}
145		print "\n} ;\n\n// Use this value for loop control during searching:\n#define	USB_DEVTABLE_LEN	(sizeof(UsbDevTable)/sizeof(USB_DEVTABLE))\n" > ofile
146
147	}
148
149	if ( classcount > 0 ) {
150		print "typedef struct _USB_CLASSCODETABLE\n{\n\tunsigned char	BaseClass ;\n\tunsigned char	SubClass ;\n\tunsigned char	Protocol ;" > ofile
151		print "\tconst char *\t\tBaseDesc ;\n\tconst char *\t\tSubDesc ;\n\tconst char *\t\tProtocolDesc ;\n}  USB_CLASSCODETABLE, *PUSB_CLASSCODETABLE ;\n" > ofile
152		print "USB_CLASSCODETABLE UsbClassCodeTable [] =\n{" > ofile
153		currentclass = classes[1, 1]
154		for (i = 1; i <= classcount; i++) {
155
156			if (i != 1) {
157				formatting = ",\n"
158			} else {
159				formatting = ""
160			}
161
162			# pretty print separate classes
163			if ( currentclass != classes[i, 1] ) {
164				formatting = formatting "\n"
165				currentclass = classes[i, 1]
166			}
167
168			# if the next item has the same details, we know we're to skip ourselves
169			# this is because the programming interface name needs to be used, and we dont have it ourselves
170			if ( ( classes[i, 1] != classes[i+1, 1] ) || ( classes[i, 2] != classes[i+1, 2] ) || ( classes[i, 3] != classes[i+1, 3] ) ) {
171				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
172			}
173		}
174		print "\n} ;\n\n// Use this value for loop control during searching:\n#define	USB_CLASSCODETABLE_LEN	(sizeof(UsbClassCodeTable)/sizeof(USB_CLASSCODETABLE))\n" > ofile
175
176	}
177
178
179	close(ofile)
180}
181
182
183