The CVS ID isn't needed anymore.
[dragonfly.git] / tools / tools / pciid / mk_pci_vendors.pl
CommitLineData
a88a1786
SW
1#!/usr/bin/perl -w
2#
3# Copyright (C) 2001 Sheldon Hearn. All rights reserved.
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions
7# are met:
8# 1. Redistributions of source code must retain the above copyright
9# notice, this list of conditions and the following disclaimer.
10# 2. Redistributions in binary form must reproduce the above copyright
11# notice, this list of conditions and the following disclaimer in the
12# documentation and/or other materials provided with the distribution.
13#
14# THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
15# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
18# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24# SUCH DAMAGE.
25#
26# $FreeBSD: src/tools/tools/pciid/mk_pci_vendors.pl,v 1.5 2004/06/28 11:46:48 mux Exp $
d58b42a8 27# $DragonFly: src/tools/tools/pciid/mk_pci_vendors.pl,v 1.2 2008/03/08 20:17:38 swildner Exp $
a88a1786 28#
d58b42a8 29# usage: mk_pci_vendors [-lq] [-p pcidevs.txt] [-v vendors.txt] [-x pci.ids]
a88a1786 30#
d58b42a8 31# Generate src/share/misc/pci_vendors from the Hart, Boemler and Mares lists,
a88a1786
SW
32# currently available at:
33#
34# Boemler: http://www.pcidatabase.com/reports.php?type=tab-delimeted
35# Hart: http://members.datafast.net.au/dft0802/downloads/pcidevs.txt
d58b42a8 36# Mares: http://pciids.sourceforge.net/pci.ids
a88a1786 37#
d58b42a8
SW
38# -l Where an entry is found in the Boemler and the Hart lists, use the
39# entry with the longest description. The -l option doesn't affect
40# the Mares list whose entries are only used if they are new. The
41# default is for the Boemler file to override the Hart file to
42# override the Mares file.
a88a1786
SW
43# -q Do not print diagnostics.
44# -p Specify the pathname of the Hart file. (Default ./pcidevs.txt)
45# -v Specify the pathname of the Boemler file. (Default ./vendors.txt)
d58b42a8 46# -x Specify the pathname of the Mares file. (Default ./pci.ids)
a88a1786
SW
47#
48use strict;
49use Getopt::Std;
50
51my $PROGNAME = 'mk_pci_vendors';
52my $VENDORS_FILE = 'vendors.txt';
53my $PCIDEVS_FILE = 'pcidevs.txt';
d58b42a8 54my $PCIIDS_FILE = 'pci.ids';
a88a1786
SW
55
56my $cur_vendor;
57my %opts;
58my %vendors;
59my ($descr, $existing, $id, $line, $rv, $winner, $optlused);
60
61my $IS_VENDOR = 1;
62my $IS_DEVICE = 2;
63my $V_DESCR = 0;
64my $V_DEVSL = 1;
65my $W_NOCONTEST = 0;
66my $W_VENDORS = 1;
67my $W_PCIDEVS = 2;
68
69sub clean_descr($);
70sub vendors_parse($\$\$);
71sub pcidevs_parse($\$\$);
d58b42a8 72sub pciids_parse($\$\$);
a88a1786 73
d58b42a8
SW
74if (not getopts('lp:qv:x:', \%opts) or @ARGV > 0) {
75 print STDERR "usage: $PROGNAME [-lq] [-p pcidevs.txt] [-v vendors.txt] [-x pci.ids]\n";
a88a1786
SW
76 exit 1;
77}
78
79if (not defined($opts{p})) {
80 $opts{p} = $PCIDEVS_FILE;
81}
82if (not defined($opts{v})) {
83 $opts{v} = $VENDORS_FILE;
84}
d58b42a8
SW
85if (not defined($opts{x})) {
86 $opts{x} = $PCIIDS_FILE;
87}
a88a1786
SW
88foreach (('l', 'q')) {
89 if (not exists($opts{$_})) {
90 $opts{$_} = 0;
91 } else {
92 $opts{$_} = 1;
93 }
94}
95
96open(VENDORS, "< $opts{v}") or
97 die "$PROGNAME: $opts{v}: $!\n";
98while ($line = <VENDORS>) {
99 chomp($line);
100 $rv = vendors_parse($line, $id, $descr);
101 if ($rv == $IS_VENDOR) {
102 if (exists($vendors{$id})) {
103 die "$PROGNAME: $id: duplicate vendor ID\n";
104 }
105 $vendors{$id} = [$descr, {}];
106 $cur_vendor = $id;
107 } elsif ($rv == $IS_DEVICE) {
108 ${$vendors{$cur_vendor}->[$V_DEVSL]}{$id} = $descr;
109 }
110}
111close(VENDORS);
112
113open(PCIDEVS, "< $opts{p}") or
114 die "$PROGNAME: $opts{p}: $!\n";
115while ($line = <PCIDEVS>) {
116 chomp($line);
117 $rv = pcidevs_parse($line, $id, $descr);
118 if ($rv == $IS_VENDOR) {
119 if (not exists($vendors{$id})) {
120 $vendors{$id} = [$descr, {}];
121 $winner = $W_NOCONTEST;
122 } elsif ($opts{l}) {
123 $existing = $vendors{$id}->[$V_DESCR];
124 if (length($existing) < length($descr)) {
125 $vendors{$id}->[$V_DESCR] = $descr;
126 $winner = $W_PCIDEVS;
127 } else {
128 $winner = $W_VENDORS;
129 }
130 } else {
131 $winner = $W_VENDORS;
132 }
133 $cur_vendor = $id;
134 if (not $opts{q} and $winner != $W_NOCONTEST) {
135 $existing = $vendors{$id}->[$V_DESCR];
136 print STDERR "$PROGNAME: ",
137 $winner == $W_VENDORS ? "Boemler" : "Hart",
138 " vendor wins: $id\t$existing\n";
139 }
140 } elsif ($rv == $IS_DEVICE) {
141 if (not exists(${$vendors{$cur_vendor}->[$V_DEVSL]}{$id})) {
142 ${$vendors{$cur_vendor}->[$V_DEVSL]}{$id} = $descr;
143 $winner = $W_NOCONTEST;
144 } elsif ($opts{l}) {
145 $existing = ${$vendors{$cur_vendor}->[$V_DEVSL]}{$id};
146 if (length($existing) < length($descr)) {
147 ${$vendors{$cur_vendor}->[$V_DEVSL]}{$id} =
148 $descr;
149 $winner = $W_PCIDEVS;
150 } else {
151 $winner = $W_VENDORS;
152 }
153 } else {
154 $winner = $W_VENDORS;
155 }
156 if (not $opts{q} and $winner != $W_NOCONTEST) {
157 $existing = ${$vendors{$cur_vendor}->[$V_DEVSL]}{$id};
158 print STDERR "$PROGNAME: ",
159 $winner == $W_VENDORS ? "Boemler" : "Hart",
160 " device wins: $id\t$existing\n";
161 }
162 }
163}
164close(PCIDEVS);
165
d58b42a8
SW
166open(PCIIDS, "< $opts{x}") or
167 die "$PROGNAME: $opts{x}: $!\n";
168while ($line = <PCIIDS>) {
169 chomp($line);
170 $rv = pciids_parse($line, $id, $descr);
171 if ($rv == $IS_VENDOR) {
172 if (not exists($vendors{$id})) {
173 $vendors{$id} = [$descr, {}];
174 }
175 $cur_vendor = $id;
176 } elsif ($rv == $IS_DEVICE) {
177 if (not exists(${$vendors{$cur_vendor}->[$V_DEVSL]}{$id})) {
178 ${$vendors{$cur_vendor}->[$V_DEVSL]}{$id} = $descr;
179 }
180 }
181}
182close(PCIIDS);
183
a88a1786
SW
184$optlused = $opts{l} ? "with" : "without";
185print <<HEADER_END;
a88a1786
SW
186;
187; Automatically generated by src/tools/tools/pciid/mk_pci_vendors.pl
188; ($optlused the -l option), using the following source lists:
189;
190; http://www.pcidatabase.com/reports.php?type=tab-delimeted
191; http://members.datafast.net.au/dft0802/downloads/pcidevs.txt
d58b42a8 192; http://pciids.sourceforge.net/pci.ids
a88a1786
SW
193;
194; Manual edits on this file will be lost!
195;
196HEADER_END
197
198foreach $cur_vendor (sort keys %vendors) {
199 $id = $cur_vendor;
200 $descr = $vendors{$id}->[$V_DESCR];
201 print "$id\t$descr\n";
202 foreach $id (sort keys %{$vendors{$cur_vendor}->[$V_DEVSL]}) {
203 $descr = ${$vendors{$cur_vendor}->[$V_DEVSL]}{$id};
204 print "\t$id\t$descr\n";
205 }
206}
207exit 0;
208
209
210# Parse a line from the Boemler file and place the ID and description
211# in the scalars referenced by $id_ref and $descr_ref.
212#
213# On success, returns $IS_VENDOR if the line represents a vendor entity
214# or $IS_DEVICE if the line represents a device entity.
215#
216# Returns 0 on failure.
217#
218sub vendors_parse($\$\$)
219{
220 my ($line, $id_ref, $descr_ref) = @_;
221
222 if ($line =~ /^([A-Fa-f0-9]{4})\t([^\t].+?)\s*$/) {
223 ($$id_ref, $$descr_ref) = (uc($1), clean_descr($2));
224 return $IS_VENDOR;
225 } elsif ($line =~ /^\t([A-Fa-f0-9]{4})\t([^\t].+?)\s*$/) {
226 ($$id_ref, $$descr_ref) = (uc($1), clean_descr($2));
227 return $IS_DEVICE;
228 } elsif (not $opts{q} and
229 $line !~ /^\s*$/ and $line !~ /^;/) {
230 chomp($line);
231 print STDERR "$PROGNAME: ignored Boemler: $line\n";
232 }
233
234 return 0;
235}
236
237# Parse a line from the Hart file and place the ID and description
238# in the scalars referenced by $id_ref and $descr_ref.
239#
240# On success, returns $IS_VENDOR if the line represents a vendor entity
241# or $IS_DEVICE if the line represents a device entity.
242#
243# Returns 0 on failure.
244#
245sub pcidevs_parse($\$\$)
246{
247 my ($line, $id_ref, $descr_ref) = @_;
248 my $descr;
249
250 if ($line =~ /^V\t([A-Fa-f0-9]{4})\t([^\t].+?)\s*$/) {
251 ($$id_ref, $$descr_ref) = (uc($1), clean_descr($2));
252 return $IS_VENDOR;
253 } elsif ($line =~ /^D\t([A-Fa-f0-9]{4})\t([^\t].+?)\s*$/) {
254 ($$id_ref, $$descr_ref) = (uc($1), clean_descr($2));
255 return $IS_DEVICE;
256 } elsif (not $opts{q} and
257 $line !~ /^\s*$/ and $line !~ /^[;ORSX]/) {
258 print STDERR "$PROGNAME: ignored Hart: $line\n";
259 }
260
261 return 0;
262}
263
d58b42a8
SW
264# Parse a line from the Mares file and place the ID and description
265# in the scalars referenced by $id_ref and $descr_ref.
266#
267# On success, returns $IS_VENDOR if the line represents a vendor entity
268# or $IS_DEVICE if the line represents a device entity.
269#
270# Returns 0 on failure.
271#
272sub pciids_parse($\$\$)
273{
274 my ($line, $id_ref, $descr_ref) = @_;
275 my $descr;
276
277 if ($line =~ /^([A-Fa-f0-9]{4}) (.+?)$/) {
278 ($$id_ref, $$descr_ref) = (uc($1), clean_descr($2));
279 return $IS_VENDOR;
280 } elsif ($line =~ /^\t([A-Fa-f0-9]{4}) (.+?)$/) {
281 ($$id_ref, $$descr_ref) = (uc($1), clean_descr($2));
282 return $IS_DEVICE;
283 } elsif (not $opts{q} and
284 $line !~ /^\s*$/ and $line !~ /^#/) {
285 chomp($line);
286 print STDERR "$PROGNAME: ignored Mares: $line\n";
287 }
288
289 return 0;
290}
291
a88a1786
SW
292sub clean_descr($)
293{
294 my ($descr) = @_;
295
296 return $descr;
297}