1#! /usr/bin/awk -f
2
3# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
4# Use is subject to license terms.
5
6# CDDL HEADER START
7#
8# The contents of this file are subject to the terms of the
9# Common Development and Distribution License (the "License").
10# You may not use this file except in compliance with the License.
11#
12# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
13# or http://www.opensolaris.org/os/licensing.
14# See the License for the specific language governing permissions
15# and limitations under the License.
16#
17# When distributing Covered Code, include this CDDL HEADER in each
18# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
19# If applicable, add the following below this CDDL HEADER, with the
20# fields enclosed by brackets "[]" replaced with your own identifying
21# information: Portions Copyright [yyyy] [name of copyright owner]
22#
23# CDDL HEADER END
24
25#-
26#	$NetBSD: usb/devlist2h.awk,v 1.9 2001/01/18 20:28:22 jdolecek Exp $
27#  $FreeBSD: src/sys/tools/usbdevs2h.awk,v 1.7 2005/01/07 02:29:25 imp Exp $
28#
29# Copyright (c) 1995, 1996 Christopher G. Demetriou
30# All rights reserved.
31#
32# Redistribution and use in source and binary forms, with or without
33# modification, are permitted provided that the following conditions
34# are met:
35# 1. Redistributions of source code must retain the above copyright
36#    notice, this list of conditions and the following disclaimer.
37# 2. Redistributions in binary form must reproduce the above copyright
38#    notice, this list of conditions and the following disclaimer in the
39#    documentation and/or other materials provided with the distribution.
40# 3. All advertising materials mentioning features or use of this software
41#    must display the following acknowledgement:
42#      This product includes software developed by Christopher G. Demetriou.
43# 4. The name of the author may not be used to endorse or promote products
44#    derived from this software without specific prior written permission
45#
46# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
47# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
48# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
49# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
50# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
51# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
52# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
53# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
54# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
55# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56#
57
58function usage()
59{
60	print "usage: usbdevs2h.awk <srcfile> [-d|-D|-h|-H]";
61	exit 1;
62}
63
64function header(file)
65{
66	if (os == "NetBSD")
67		printf("/*\t\$NetBSD\$\t*/\n\n") > file
68	else if (os == "FreeBSD")
69		printf("/* \$FreeBSD\$ */\n\n") > file
70	else if (os == "OpenBSD")
71		printf("/*\t\$OpenBSD\$\t*/\n\n") > file
72
73	printf("/*\n") > file
74	printf(" * THIS FILE IS AUTOMATICALLY GENERATED.  DO NOT EDIT.\n") \
75	    > file
76	printf(" *\n") > file
77	printf(" * generated from:\n") > file
78	printf(" *  %s\n", VERSION) > file
79	printf(" */\n") > file
80}
81
82function header_guard(file)
83{
84	printf("\n") > file
85	printf("#ifndef\t_SYS_USB_USBDEVS_H\n") > file
86	printf("#define\t_SYS_USB_USBDEVS_H\n\n") > file
87}
88
89function header_trailer(file)
90{
91	printf("\n") > file
92	printf("#endif\t/* _SYS_USB_USBDEVS_H */\n") > file
93}
94
95function vendor(hfile)
96{
97	nvendors++
98
99	vendorindex[$2] = nvendors;		# record index for this name, for later.
100	vendors[nvendors, 1] = $2;		# name
101	vendors[nvendors, 2] = $3;		# id
102	if (hfile)
103		printf("#define\tUSB_VENDOR_%s\t%s\t", vendors[nvendors, 1],
104		    vendors[nvendors, 2]) > hfile
105
106	i = 3; f = 4;
107
108	# comments
109	ocomment = oparen = 0
110	if (f <= NF) {
111		if (hfile)
112			printf("\t/* ") > hfile
113		ocomment = 1;
114	}
115	while (f <= NF) {
116		if ($f == "#") {
117			if (hfile)
118				printf("(") > hfile
119			oparen = 1
120			f++
121			continue
122		}
123		if (oparen) {
124			if (hfile)
125				printf("%s", $f) > hfile
126			if (f < NF && hfile)
127				printf(" ") > hfile
128			f++
129			continue
130		}
131		vendors[nvendors, i] = $f
132		if (hfile)
133			printf("%s", vendors[nvendors, i]) > hfile
134		if (f < NF && hfile)
135			printf(" ") > hfile
136		i++; f++;
137	}
138	if (oparen && hfile)
139		printf(")") > hfile
140	if (ocomment && hfile)
141		printf(" */") > hfile
142	if (hfile)
143		printf("\n") > hfile
144}
145
146function product(hfile)
147{
148	nproducts++
149
150	products[nproducts, 1] = $2;		# vendor name
151	products[nproducts, 2] = $3;		# product id
152	products[nproducts, 3] = $4;		# id
153	if (hfile)
154		printf("#define\tUSB_PRODUCT_%s_%s\t%s\t", \
155		  products[nproducts, 1], products[nproducts, 2], \
156		  products[nproducts, 3]) > hfile
157
158	i=4; f = 5;
159
160	# comments
161	ocomment = oparen = 0
162	if (f <= NF) {
163		if (hfile)
164			printf("\t/* ") > hfile
165		ocomment = 1;
166	}
167	while (f <= NF) {
168		if ($f == "#") {
169			if (hfile)
170				printf("(") > hfile
171			oparen = 1
172			f++
173			continue
174		}
175		if (oparen) {
176			if (hfile)
177				printf("%s", $f) > hfile
178			if (f < NF && hfile)
179				printf(" ") > hfile
180			f++
181			continue
182		}
183		products[nproducts, i] = $f
184		if (hfile)
185			printf("%s", products[nproducts, i]) > hfile
186		if (f < NF && hfile)
187			printf(" ") > hfile
188		i++; f++;
189	}
190	if (oparen && hfile)
191		printf(")") > hfile
192	if (ocomment && hfile)
193		printf(" */") > hfile
194	if (hfile)
195		printf("\n") > hfile
196}
197
198function dump_dfile(dfile)
199{
200	printf("\n") > dfile
201	printf("const struct usb_knowndev usb_knowndevs[] = {\n") > dfile
202	for (i = 1; i <= nproducts; i++) {
203		printf("\t{\n") > dfile
204		printf("\t    USB_VENDOR_%s, USB_PRODUCT_%s_%s,\n",
205		    products[i, 1], products[i, 1], products[i, 2]) > dfile
206		printf("\t    ") > dfile
207		printf("0") > dfile
208		printf(",\n") > dfile
209
210		vendi = vendorindex[products[i, 1]];
211		printf("\t    \"") > dfile
212		j = 3;
213		needspace = 0;
214		while (vendors[vendi, j] != "") {
215			if (needspace)
216				printf(" ") > dfile
217			printf("%s", vendors[vendi, j]) > dfile
218			needspace = 1
219			j++
220		}
221		printf("\",\n") > dfile
222
223		printf("\t    \"") > dfile
224		j = 4;
225		needspace = 0;
226		while (products[i, j] != "") {
227			if (needspace)
228				printf(" ") > dfile
229			printf("%s", products[i, j]) > dfile
230			needspace = 1
231			j++
232		}
233		printf("\",\n") > dfile
234		printf("\t},\n") > dfile
235	}
236	for (i = 1; i <= nvendors; i++) {
237		printf("\t{\n") > dfile
238		printf("\t    USB_VENDOR_%s, 0,\n", vendors[i, 1]) > dfile
239		printf("\t    USB_KNOWNDEV_NOPROD,\n") > dfile
240		printf("\t    \"") > dfile
241		j = 3;
242		needspace = 0;
243		while (vendors[i, j] != "") {
244			if (needspace)
245				printf(" ") > dfile
246			printf("%s", vendors[i, j]) > dfile
247			needspace = 1
248			j++
249		}
250		printf("\",\n") > dfile
251		printf("\t    NULL,\n") > dfile
252		printf("\t},\n") > dfile
253	}
254	printf("\t{ 0, 0, 0, NULL, NULL, }\n") > dfile
255	printf("};\n") > dfile
256}
257
258BEGIN {
259
260nproducts = nvendors = 0
261# Process the command line
262for (i = 1; i < ARGC; i++) {
263	arg = ARGV[i];
264	if (arg !~ /^-[dDhH]+$/ && arg !~ /devs$/)
265		usage();
266	if (arg ~ /^-.*d/)
267		dfile="usbdevs_data.h"
268	if (arg ~ /^-.*D/)
269		dfile="/dev/stdout"
270	if (arg ~ /^-.*h/)
271		hfile="usbdevs.h"
272	if (arg ~ /^-.*H/)
273		hfile="/dev/stdout"
274	if (arg ~ /devs$/)
275		srcfile = arg;
276}
277ARGC = 1;
278line=0;
279
280while ((getline < srcfile) > 0) {
281	line++;
282	if (line == 1) {
283		VERSION = $0
284		gsub("\\$", "", VERSION)
285		if (dfile)
286			header(dfile)
287		if (hfile) {
288			header(hfile)
289			header_guard(hfile)
290		}
291		continue;
292	}
293	if ($1 == "vendor") {
294		vendor(hfile)
295		continue
296	}
297	if ($1 == "product") {
298		product(hfile)
299		continue
300	}
301	if ($0 == "")
302		blanklines++
303	if (hfile)
304		print $0 > hfile
305	if (blanklines < 2 && dfile)
306	    print $0 > dfile
307}
308
309# close off the header guard
310
311if (hfile)
312	header_trailer(hfile)
313
314# print out the match tables
315
316if (dfile)
317	dump_dfile(dfile)
318}
319