xref: /haiku/src/apps/devices/usb-header.awk (revision c75dc6af6be733ff428fc6ed4da5518f6e9a37ad)
14ea3e0d3SJérôme Duval# USB Header script
24ea3e0d3SJérôme Duval#
34ea3e0d3SJérôme Duval# Copyright 2006-2012, Haiku.
44ea3e0d3SJérôme Duval# Distributed under the terms of the MIT License.
54ea3e0d3SJérôme Duval#
64ea3e0d3SJérôme Duval# Authors:
74ea3e0d3SJérôme Duval#		John Drinkwater, john@nextraweb.com
84ea3e0d3SJérôme Duval#
94ea3e0d3SJérôme Duval# Use with http://www.linux-usb.org/usb.ids
104ea3e0d3SJérôme Duval# run as: awk -v HEADERFILE=usbhdr.h -f usb-header.awk usb.ids
114ea3e0d3SJérôme Duval
124ea3e0d3SJérôme DuvalBEGIN {
134ea3e0d3SJérôme Duval
144ea3e0d3SJérôme Duval	# field separator, defining because user could have overridden
154ea3e0d3SJérôme Duval	FS = " "
164ea3e0d3SJérôme Duval
174ea3e0d3SJérôme Duval	# Pass this in from outside with -v HEADERFILE=filenametouse
184ea3e0d3SJérôme Duval	# we require usbhdr.h for our system
194ea3e0d3SJérôme Duval	ofile = HEADERFILE
204ea3e0d3SJérôme Duval
214ea3e0d3SJérôme Duval	# possibly use this in the future
224ea3e0d3SJérôme Duval	cleanvalues = "[^A-Za-z0-9{}\"'&@?!*.,:;+<> \\t\\/_\\[\\]=#()-]"
234ea3e0d3SJérôme Duval	# ToDo: currently IDs aren't checked, we dumbly assume the source is clean
244ea3e0d3SJérôme Duval
25edeaa9c0SJérôme Duval	inClassesDefinition = 0
26edeaa9c0SJérôme Duval
274ea3e0d3SJérôme Duval	# descriptive output header
284ea3e0d3SJérôme Duval	print "#if 0" > ofile
294ea3e0d3SJérôme Duval	print "#\tUSBHDR.H: USB Vendors, Devices\n#" > ofile
304ea3e0d3SJérôme Duval	print "#\tGenerated by usb-header.awk, source data from the following URI:\n#\thttp://www.linux-usb.org/usb.ids\n#" > ofile
314ea3e0d3SJérôme Duval	print "#\tHeader created on " strftime( "%A, %d %b %Y %H:%M:%S %Z", systime() ) > ofile
324ea3e0d3SJérôme Duval	print "#endif" > ofile
334ea3e0d3SJérôme Duval
344ea3e0d3SJérôme Duval	# and we start with vendors..
354ea3e0d3SJérôme Duval	print "\ntypedef struct _USB_VENTABLE\n{\n\tunsigned short\tVenId ;\n\tconst char *\tVenName ;\n}  USB_VENTABLE, *PUSB_VENTABLE ;\n" > ofile
364ea3e0d3SJérôme Duval	print "USB_VENTABLE\tUsbVenTable [] =\n{" > ofile
374ea3e0d3SJérôme Duval}
384ea3e0d3SJérôme Duval
394ea3e0d3SJérôme Duval# matches vendor - starts with an id as first thing on the line
404ea3e0d3SJérôme Duval# because this occurs first in the header file, we output it without worry
414ea3e0d3SJérôme Duval/^[[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]] / {
424ea3e0d3SJérôme Duval
434ea3e0d3SJérôme Duval	if ( vendorcount++ > 0 ) {
444ea3e0d3SJérôme Duval		formatting = ",\n"
454ea3e0d3SJérôme Duval	} else {
464ea3e0d3SJérôme Duval		formatting = ""
474ea3e0d3SJérôme Duval	}
484ea3e0d3SJérôme Duval
494ea3e0d3SJérôme Duval	# store vendor ID for possible devices afterwards
504ea3e0d3SJérôme Duval	vendorid = $1
514ea3e0d3SJérôme Duval	vendor = substr($0, 7)
5224502382SJérôme Duval	gsub( /\"/, "&&", vendor )
534ea3e0d3SJérôme Duval
54*c75dc6afSPulkoMandy	# Remove double interrogation points that may be interpreted as trigraphs
55*c75dc6afSPulkoMandy	gsub( /\?\?\?/, "xxx", vendor )
56*c75dc6afSPulkoMandy	gsub( /\?\?/, "xx", vendor )
57*c75dc6afSPulkoMandy
58d7a4a01fSJérôme Duval	printf "%s", formatting "\t{ 0x" vendorid ", \"" vendor "\" }" > ofile
594ea3e0d3SJérôme Duval}
604ea3e0d3SJérôme Duval
614ea3e0d3SJérôme Duval# matches device
624ea3e0d3SJérôme Duval/^\t[[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]] / {
634ea3e0d3SJérôme Duval
644ea3e0d3SJérôme Duval	device = substr($0, 8)
6524502382SJérôme Duval	gsub( /\\/, "&&", device )
6624502382SJérôme Duval	gsub( /\"/, "&&", device )
674ea3e0d3SJérôme Duval
68*c75dc6afSPulkoMandy	# Remove double interrogation points that may be interpreted as trigraphs
69*c75dc6afSPulkoMandy	gsub( /\?\?\?/, "xxx", device )
70*c75dc6afSPulkoMandy	gsub( /\?\?/, "xx", device )
71*c75dc6afSPulkoMandy
724ea3e0d3SJérôme Duval	# store device ID for possible devices afterwards
734ea3e0d3SJérôme Duval	deviceid = $1
744ea3e0d3SJérôme Duval	devicecount++
754ea3e0d3SJérôme Duval	devices[devicecount, 1] = vendorid
764ea3e0d3SJérôme Duval	devices[devicecount, 2] = $1
774ea3e0d3SJérôme Duval	devices[devicecount, 3] = device
784ea3e0d3SJérôme Duval}
794ea3e0d3SJérôme Duval
80edeaa9c0SJérôme Duval# match device class - store data for later
81edeaa9c0SJérôme Duval/^C [[:xdigit:]][[:xdigit:]]  / {
82edeaa9c0SJérôme Duval
83edeaa9c0SJérôme Duval	class = $2
84edeaa9c0SJérôme Duval	classname = substr($0, 7)
85edeaa9c0SJérôme Duval	gsub( /\"/, "\\\"", classname )
86edeaa9c0SJérôme Duval
87edeaa9c0SJérôme Duval	inClassesDefinition = 1
88edeaa9c0SJérôme Duval
89edeaa9c0SJérôme Duval	classcount++
90edeaa9c0SJérôme Duval	classes[classcount, 1] = class
91edeaa9c0SJérôme Duval	classes[classcount, 2] = "00"
92edeaa9c0SJérôme Duval	classes[classcount, 3] = "00"
93edeaa9c0SJérôme Duval	classes[classcount, 4] = classname
94edeaa9c0SJérôme Duval	classes[classcount, 5] = ""
95edeaa9c0SJérôme Duval	classes[classcount, 6] = ""
96edeaa9c0SJérôme Duval}
97edeaa9c0SJérôme Duval
98edeaa9c0SJérôme Duval# match subclass, use device class data captured earlier, and output
99edeaa9c0SJérôme DuvalinClassesDefinition && (/^\t[[:xdigit:]][[:xdigit:]]  /) {
100edeaa9c0SJérôme Duval	subclass = $1
101edeaa9c0SJérôme Duval	subclassname = substr($0, 6)
102edeaa9c0SJérôme Duval	gsub( /\"/, "\\\"", subclassname )
103edeaa9c0SJérôme Duval
104edeaa9c0SJérôme Duval	classcount++
105edeaa9c0SJérôme Duval	classes[classcount, 1] = class
106edeaa9c0SJérôme Duval	classes[classcount, 2] = subclass
107edeaa9c0SJérôme Duval	classes[classcount, 3] = "00"
108edeaa9c0SJérôme Duval	classes[classcount, 4] = classname
109edeaa9c0SJérôme Duval	classes[classcount, 5] = subclassname
110edeaa9c0SJérôme Duval	classes[classcount, 6] = ""
111edeaa9c0SJérôme Duval}
112edeaa9c0SJérôme Duval
113edeaa9c0SJérôme Duval# match protocol
114edeaa9c0SJérôme DuvalinClassesDefinition && (/^\t\t[[:xdigit:]][[:xdigit:]]  /) {
115edeaa9c0SJérôme Duval
116edeaa9c0SJérôme Duval	protocol = $1
117edeaa9c0SJérôme Duval	protocolname = substr($0, 7)
118edeaa9c0SJérôme Duval	gsub( /\"/, "\\\"", protocolname )
119edeaa9c0SJérôme Duval
120edeaa9c0SJérôme Duval	classcount++
121edeaa9c0SJérôme Duval	classes[classcount, 1] = class
122edeaa9c0SJérôme Duval	classes[classcount, 2] = subclass
123edeaa9c0SJérôme Duval	classes[classcount, 3] = protocol
124edeaa9c0SJérôme Duval	classes[classcount, 4] = classname
125edeaa9c0SJérôme Duval	classes[classcount, 5] = subclassname
126edeaa9c0SJérôme Duval	classes[classcount, 6] = protocolname
127edeaa9c0SJérôme Duval}
128edeaa9c0SJérôme Duval
129edeaa9c0SJérôme Duval#match comments
130edeaa9c0SJérôme Duval/^#/ {
131edeaa9c0SJérôme Duval	inClassesDefinition = false
132edeaa9c0SJérôme Duval}
133edeaa9c0SJérôme Duval
134edeaa9c0SJérôme Duval
1354ea3e0d3SJérôme Duval# We've processed the file, now output.
1364ea3e0d3SJérôme DuvalEND {
1374ea3e0d3SJérôme Duval
1384ea3e0d3SJérôme Duval	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
1394ea3e0d3SJérôme Duval
1404ea3e0d3SJérôme Duval	if ( devicecount > 0 ) {
1414ea3e0d3SJérôme Duval
1424ea3e0d3SJérôme Duval		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
1434ea3e0d3SJérôme Duval		print "USB_DEVTABLE\tUsbDevTable [] =\n{" > ofile
1444ea3e0d3SJérôme Duval		for (i = 1; i <= devicecount; i++) {
1454ea3e0d3SJérôme Duval
1464ea3e0d3SJérôme Duval			if (i != 1) {
1474ea3e0d3SJérôme Duval				formatting = ",\n"
1484ea3e0d3SJérôme Duval			} else {
1494ea3e0d3SJérôme Duval				formatting = ""
1504ea3e0d3SJérôme Duval			}
151d7a4a01fSJérôme Duval			printf "%s", formatting "\t{ 0x" devices[i, 1] ", 0x" devices[i, 2] ", \"" devices[i, 3] "\" }" > ofile
1524ea3e0d3SJérôme Duval		}
1534ea3e0d3SJérôme Duval		print "\n} ;\n\n// Use this value for loop control during searching:\n#define	USB_DEVTABLE_LEN	(sizeof(UsbDevTable)/sizeof(USB_DEVTABLE))\n" > ofile
1544ea3e0d3SJérôme Duval
1554ea3e0d3SJérôme Duval	}
1564ea3e0d3SJérôme Duval
157edeaa9c0SJérôme Duval	if ( classcount > 0 ) {
158edeaa9c0SJérôme Duval		print "typedef struct _USB_CLASSCODETABLE\n{\n\tunsigned char	BaseClass ;\n\tunsigned char	SubClass ;\n\tunsigned char	Protocol ;" > ofile
159edeaa9c0SJérôme Duval		print "\tconst char *\t\tBaseDesc ;\n\tconst char *\t\tSubDesc ;\n\tconst char *\t\tProtocolDesc ;\n}  USB_CLASSCODETABLE, *PUSB_CLASSCODETABLE ;\n" > ofile
160edeaa9c0SJérôme Duval		print "USB_CLASSCODETABLE UsbClassCodeTable [] =\n{" > ofile
161edeaa9c0SJérôme Duval		currentclass = classes[1, 1]
162edeaa9c0SJérôme Duval		for (i = 1; i <= classcount; i++) {
163edeaa9c0SJérôme Duval
164edeaa9c0SJérôme Duval			if (i != 1) {
165edeaa9c0SJérôme Duval				formatting = ",\n"
166edeaa9c0SJérôme Duval			} else {
167edeaa9c0SJérôme Duval				formatting = ""
168edeaa9c0SJérôme Duval			}
169edeaa9c0SJérôme Duval
170edeaa9c0SJérôme Duval			# pretty print separate classes
171edeaa9c0SJérôme Duval			if ( currentclass != classes[i, 1] ) {
172edeaa9c0SJérôme Duval				formatting = formatting "\n"
173edeaa9c0SJérôme Duval				currentclass = classes[i, 1]
174edeaa9c0SJérôme Duval			}
175edeaa9c0SJérôme Duval
176edeaa9c0SJérôme Duval			# if the next item has the same details, we know we're to skip ourselves
177edeaa9c0SJérôme Duval			# this is because the programming interface name needs to be used, and we dont have it ourselves
178edeaa9c0SJérôme Duval			if ( ( classes[i, 1] != classes[i+1, 1] ) || ( classes[i, 2] != classes[i+1, 2] ) || ( classes[i, 3] != classes[i+1, 3] ) ) {
179edeaa9c0SJérôme Duval				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
180edeaa9c0SJérôme Duval			}
181edeaa9c0SJérôme Duval		}
182edeaa9c0SJérôme Duval		print "\n} ;\n\n// Use this value for loop control during searching:\n#define	USB_CLASSCODETABLE_LEN	(sizeof(UsbClassCodeTable)/sizeof(USB_CLASSCODETABLE))\n" > ofile
183edeaa9c0SJérôme Duval
184edeaa9c0SJérôme Duval	}
185edeaa9c0SJérôme Duval
186edeaa9c0SJérôme Duval
1874ea3e0d3SJérôme Duval	close(ofile)
1884ea3e0d3SJérôme Duval}
1894ea3e0d3SJérôme Duval
1904ea3e0d3SJérôme Duval
191