#!/bin/bash -eu

# inf-to-pciids
# by Sam Morris <sam@robots.org.uk>
# version 20050808

# Reads in a Windows .INF file from a driver, and prints out a list of all the
# PCI Vendor/Product/Subsystem Vendor/Subsystem Product IDs supported by the
# driver, along with the corresponding device descriptions.

# Thanks to Brian Catlin for <http://www.wd-3.com/archive/InfFiles.htm>

# BUG: eliminate use of foo

IFS="$IFS,="

inf=$(fromdos < ${1:?Usage: $0 file.inf} | grep -v '^;')

function getstring {
	#local tmp=string_$1
	#test -n "${!tmp}" && echo "${!tmp}" && return

	local state=0
	while read line; do
		case $state in
		0)
			test "$line" = "[Strings]" && state=1
			;;
		1)
			read key foo value <<< "$line"
			if test "%$key%" = "$1"; then
				#eval string_$1=$value
				echo $value
				return
			fi
			;;
		esac
	done <<< "$inf"
}

function getsections {
	local line mfg section postfixes
	local state=0
	while read line; do
		case $state in
		0)
			test "$line" = "[Manufacturer]" && state=1
			;;
		1)
			test -z "$line" && break #TODO: allow empty lines

			read mfg foo section postfixes <<< "$line"
			echo $section
			for postfix in $postfixes; do
				echo $section.$postfix
			done
			;;
		esac
	done <<< "$inf"
}

sections=$(getsections)

state=0
while read line; do
	case $state in
	0)
		for section in $sections; do
			if test "$line" = "[$section]"; then
				sections=$(sed "s/$section//" <<< $sections) #TODO: increase specifity
				state=1
				break
			fi
		done
		;;
	1)
		if test -z "$line"; then #TODO: allow empy lines
			state=0
		else
			read name foo section id <<< "$line"
			vend=$(cut -c  8-11 <<< "$id")
			prod=$(cut -c 17-20 <<< "$id")
			sub_vend=$(cut -c 33-36 <<< "$id")
			sub_prod=$(cut -c 29-32 <<< "$id")
			echo $vend:$prod $sub_vend:$sub_prod $(getstring $name)
		fi
		;;
	esac
done <<< "$inf"
