#! /usr/bin/perl # lst2xml: Transform old (pci.lst) Discover data to new XML-based format # AUTHORS: Eric Gillespie # John R. Daily # Josh Bressers # # Copyright 2002 Progeny Linux Systems, Inc. # Copyright 2002 Hewlett-Packard Company # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. # $Progeny$ use strict; use warnings; my %CLASSES = ( 'isdn'=>'isdn', 'bridge'=>'bridge', 'ethernet'=>'network', 'unknown'=>'unknown', 'video'=>'video', 'ide'=>'ide', 'scsi'=>'scsi', 'usb'=>'usb', 'sound'=>'sound', 'modem'=>'modem', 'tvcard'=>'multimedia', 'joystick'=>'gameport', 'scanner'=>'scanner', 'printer'=>'printer', 'webcam'=>'webcam', 'floppy'=>'floppy', 'mouse'=>0 # We don't care about this in Discover ); my %PCI_CLASSES = ( 'isdn'=>'0204', 'bridge'=>'0600', 'network'=>'0200', 'unknown'=>'0000', 'video'=>'0300', 'ide'=>'0101', 'scsi'=>'0100', 'usb'=>'0c03', 'sound'=>'0401', 'modem'=>'0703', 'multimedia'=>'0400', # Used to be 'tvcard' 'gameport'=>'0904' # Used to be 'joystick' ); my %PCMCIA_CLASSES = ( 'isdn'=>'isdn', 'bridge'=>'bridge', 'network'=>'network', 'unknown'=>'unknown', 'video'=>'video', 'sound'=>'sound', 'modem'=>'modem', 'multimedia'=>'multimedia', 'gameport'=>'gameport' ); my %USB_CLASSES = ( 'unknown'=>'0000', 'scanner'=>'ffff', # XXX ??? 'printer'=>'0101', 'isdn'=>'1030', 'webcam'=>'ff00', 'network'=>'0206', 'modem'=>'0202', 'gameport'=>'0300', 'floppy'=>'0804' ); my %REMAP_CLASSES = ( 'isdn'=>'broadband', 'bridge'=>'bridge', 'ethernet'=>'network', 'unknown'=>'miscellaneous', 'video'=>'display', 'ide'=>'bridge', 'scsi'=>'bridge', 'usb'=>'bridge', 'sound'=>'audio', 'modem'=>'modem', 'multimedia'=>'video', 'tvcard'=>'video', 'joystick'=>'bridge', 'gameport'=>'bridge', 'scanner'=>'imaging', 'printer'=>'printer', 'webcam'=>'video', 'floppy'=>'removabledisk', 'network'=>'network' ); sub encode_non_ascii { my ($value) = @_; my ($i, $newval, @chars); @chars = unpack('C*', $value); for($i = 0; $i < @chars; $i++) { if ($chars[$i] > 127) { $newval = sprintf("&#x%X;", $chars[$i]); if ($i == 0) { $value = $newval . substr($value, 1); } elsif ($i == @chars - 1) { $value = substr($value, 0, $i) . $newval; } else { $value = substr($value, 0, $i) . $newval . substr($value, $i+1); } } } return $value; } sub make_busclass { my $bus = shift; my $bus_upper = shift; my $id; my $class; my $try; my @keys; if (not open(BUSCLASSFOO, ">${bus}-busclass.xml")) { die("Could not open ${bus}-busclass.xml\n"); } print(BUSCLASSFOO < EOF $try = '@keys = keys(%'; $try .= $bus_upper; $try .= '_CLASSES);'; eval $try; foreach $class (@keys) { $try = '$id = $'; # 'cperl-mode is sub-optimal $try .= $bus_upper; $try .= '_CLASSES{$class};'; eval $try; print(BUSCLASSFOO " \n"); } print(BUSCLASSFOO "\n"); close(BUSCLASSFOO); } unless (@ARGV) { die "Need valid file as first argument\n"; } MAIN: { my @data; my $busclass; my $bus; my $bus_upper; my $class; my $new_class; my $class_name; my $filename; my $interface_type; my $model_id; my $module; my $serverbin; my $text; my $try; my $vendor; my $vendor_id; foreach $filename (@ARGV) { if (not -e $filename) { die "Need valid file as first argument\n"; } if (not $filename =~ /\/?(\w+)\.lst/) { die "Need file with name .lst, where is a type " . "of hardware\n"; } $bus = $1; $bus_upper = $1; $bus_upper =~ tr/a-z/A-Z/; make_busclass($bus, $bus_upper); if (not open(VENDORS, ">${bus}-vendor.xml")) { die "Must be able to open ${bus}-vendor.xml " . "for writing\n"; } if (not open(HARDWARE, ">${bus}-device.xml")) { die "Must be able to open ${bus}-device.xml " . "for writing\n"; } if (not open(LST, $filename)) { die "Must be able to open $filename for reading\n"; } print HARDWARE < EOF print VENDORS < EOF while() { $class = $model_id = $vendor_id = $class_name = $module = $text = $serverbin = ''; s/&/&/g; s//>/g; s/"/"/g; s/'/'/g; #"cperl-mode is suboptimal $_ = encode_non_ascii($_); if (/^(\w+) (.*)$/) { $vendor_id = $1; $vendor = $2; print(VENDORS " \n"); } elsif (/^\s+\w/) { s/^\s+//; s/\s+$//; @data = split(/\t+/); if (@data != 4) { print(STDERR "Error: Wrong number of fields in $_\n"); next; } $model_id = $data[0]; $class_name = $data[1]; $module = $data[2]; $text = $data[3]; if ($class_name eq 'pmc') { next; } $new_class = $CLASSES{$class_name}; if (not defined($new_class)) { die("Couldn't find $class_name in CLASSES\n"); } if (not $new_class) { # A device we don't care about, such as mice next; } $try = '$busclass = $'; # 'cperl-mode is sub-optimal $try .= $bus_upper; $try .= '_CLASSES{$new_class};'; eval $try; if (not defined($busclass)) { die("Couldn't find $new_class " . "in ${bus_upper}_CLASSES\n"); } $vendor_id = substr($model_id, 0, 4); $model_id = substr($model_id, 4); if ($module =~ /:/) { @data = split(/:/, $module); $interface_type = "xfree86"; $module = $data[1]; if ($module =~ /(.*)\((.*)\)/) { $module = $2; $serverbin = $1; } else { $serverbin = $module; $module = ''; } } elsif ($module eq 'unknown' || $module eq 'ignore') { $interface_type = ""; } else { $interface_type = "linux"; } print HARDWARE < EOF if ($interface_type) { print HARDWARE < EOF } if ($interface_type eq 'linux') { print HARDWARE < $module EOF } elsif ($interface_type eq 'xfree86') { if ($serverbin eq 'XFree86') { print HARDWARE < $serverbin $module EOF } else { print HARDWARE < $serverbin EOF } } if ($interface_type) { print HARDWARE < EOF } print HARDWARE < EOF } } print HARDWARE "\n"; print VENDORS "\n"; close(LST); close(HARDWARE); close(VENDORS); } } # vim:set ai et sts=4 sw=4: