#!/usr/bin/awk -f
#
# PCMCIA config analyzing script for pcmcia_socket agent 
#				Shuu Yamaguchi <shuu@dotAster.com>
#
# $Id: pcmcia_socket_analyze,v 1.1 2003/11/13 07:19:46 shuu Exp shuu $
#

function check_flag(flag,mesg) {
	if (flag == 0) {
		printf(mesg);
		exit(1);
	}
}

function debug_version(num,val) {
	if (!debug)
		return
	printf("D:card(%d):v(1/%d)=%s\n", num,version_num[num],val);
}

function print_bind(val,to) {
	if (to == 0 || to == 1) {
		printf(" bind(%d) %s =>",to,val);
	} else {
		printf(" bind %s =>",val);
	}
	printf(" class %s",class[val]);
	printf(" module %s",mod_1[val]);
	if (module_num[val] == 2) {
		printf(" %s",mod_2[val]);
	}
}

BEGIN {
	FS="[, \t]+";
	devnum = 0;
	cardnum = 0;
#	debug = 1;
}
/^[[:space:]]*#/ {
	next
}
/^$/ {
	device_flag = 0;
	card_flag = 0;
	next
}

# (;_;)
{
	gsub(/^[[:space:]]*/,"");
}

# device config
$1 == "device" {
	if (debug) {
		printf("D:device %s\n",$2);
	}
	device_flag = 1;
	devname[devnum] = $2;
	next
}
$1 == "class" {
	check_flag(device_flag,"device flag is invalid\n");
	class[devname[devnum]] = $2
	if (debug) {
		printf("D:class:%s\n",$2);
	}
	# cb_enabler will be ignored
	if ($3 == "module") {
		gsub(/.*module /,"");
		sub(/", "/,"\"@\"");
		module_num[devname[devnum]] = split($0,mod,"@");
		mod_1[devname[devnum]] = mod[1];
		if (debug) {
			printf("D:module(1):%s\n",mod[1]);
		}
		if (module_num[devname[devnum]] == 2) {
			mod_2[devname[devnum]] = mod[2];
			if (debug) {
				printf("D:module(2):%s\n",mod[2]);
			}
		}
	} else {
		printf("3rd item is not module\n");
		exit(1);
	} 
	devnum++;
	next
}

# card config
$1 == "card" {
	card_flag = 1;
	match($0,/".*"/);
	cardname[cardnum] = substr($0,RSTART,RLENGTH);
	if (debug) {
		printf("D:card(%d) %s\n",cardnum,cardname[cardnum]);
	}
	ano_num[cardnum] = 0;
	tuple_num[cardnum] = 0;
	version_num[cardnum] = 0;
	man_num[cardnum] = 0;
	cis_num[cardnum] = 0;
	pci_num[cardnum] = 0;
	func_num[cardnum] = 0;
	pre_cardnum = cardnum;
	cardnum++;
	next;
}
$1 == "anonymous" {
	check_flag(card_flag,"card flag is invalid\n");
	ano_num[pre_cardnum] = 1;
	next;
}
$1 == "tuple" {
	check_flag(card_flag,"card flag is invalid\n");
	tuple_num[pre_cardnum] = 1;
	next;
}
$1 == "function" {
	check_flag(card_flag,"card flag is invalid\n");
	func_num[pre_cardnum] = 1;
	funcname[pre_cardnum] = $2;
	if (debug) {
		printf("D:card(%d):f=%s\n",funcname[pre_cardnum]);
	}
}
$1 == "version" {
	check_flag(card_flag,"card flag is invalid\n");
	match($0,/".*"/);
	ss = substr($0,RSTART,RLENGTH);
	gsub(/", "/,"\"@\"",ss);
	version_num[pre_cardnum] = split(ss,ver,"@");
	if (version_num[pre_cardnum] >= 1) {
		version_1[pre_cardnum] = ver[1];
		debug_version(pre_cardnum,version_1[pre_cardnum]);
		if (version_num[pre_cardnum] >= 2) {
			version_2[pre_cardnum] = ver[2];
			debug_version(pre_cardnum,version_2[pre_cardnum]);
			if (version_num[pre_cardnum] >= 3) {
				version_3[pre_cardnum] = ver[3];
				debug_version(pre_cardnum,version_3[pre_cardnum]);
				if (version_num[pre_cardnum] == 4) {
					version_4[pre_cardnum] = ver[4];
					debug_version(pre_cardnum,version_4[pre_cardnum]);
				}
			}
		}
	}
	next;
}
$1 == "manfid" {
	check_flag(card_flag,"card flag is invalid\n");
	man_num[pre_cardnum] = 1;
	man_1[pre_cardnum] = $2
	man_2[pre_cardnum] = $3
	if (debug) {
		printf("D:card(%d):m1=%s\n",
		pre_cardnum, man_1[pre_cardnum]);
		printf("D:card(%d):m2=%s\n",
		pre_cardnum, man_2[pre_cardnum]);
	}
	next;
}

$1 == "pci" {
	check_flag(card_flag,"card flag is invalid\n");
	pci_num[pre_cardnum] = 1;
	pci_1[pre_cardnum] = $2
	pci_2[pre_cardnum] = $3
	if (debug) {
		printf("D:card(%d):p1=%s\n",
		pre_cardnum, pci_1[pre_cardnum]);
		printf("D:card(%d):p2=%s\n",
		pre_cardnum, pci_2[pre_cardnum]);
	}
	next;
}

$1 == "cis" {
	check_flag(card_flag,"card flag is invalid\n");
	cis_num[pre_cardnum] = 1;
	match($0,/".*"/);
	cisname[pre_cardnum] = substr($0,RSTART,RLENGTH);
	if (debug) {
		printf("D:card(%d):c=%s\n", pre_cardnum, cisname[pre_cardnum]);
	}
	next;
}

$1 == "bind" {
	if (card_flag == 0) {
		printf("card flag is invalid\n");
		exit(1);
	}
	if (NF == 2) {
		bind_num[pre_cardnum] = 1;
		bind_1[pre_cardnum] = $2;
		if (debug) {
			printf("D:card(%d):b(1/1)=%s\n", pre_cardnum, bind_1[pre_cardnum]);
		}
	} else if (NF == 3) {
		bind_num[pre_cardnum] = 2;
		match($0,/".*"/);
		ss = substr($0,RSTART,RLENGTH);
		gsub(/", "/,"\"@\"",ss);
		split(ss,bin,"@");
		bind_1[pre_cardnum] = bin[1];
		bind_2[pre_cardnum] = bin[2];
		bind_to[pre_cardnum] = 0;
		if (debug) {
			printf("D:card(%d):b(1/2)=%s\n", pre_cardnum, bind_1[pre_cardnum]);
			printf("D:card(%d):b(2/2)=%s\n", pre_cardnum, bind_2[pre_cardnum]);
		}
	} else if (NF == 7) {
		bind_num[pre_cardnum] = 2;
		bind_1[pre_cardnum] = $2;
		bind_2[pre_cardnum] = $5;
		bind_to[pre_cardnum] = 1;
		if (debug) {
			printf("D:card(%d):b(1/2)=%s -> 0\n", pre_cardnum, bind_1[pre_cardnum]);
			printf("D:card(%d):b(2/2)=%s -> 1\n", pre_cardnum, bind_2[pre_cardnum]);
		}
	}
	next;
}

END {
	if (debug) {
		printf("CARD %d\n",cardnum);
	}
	for(i = 0;i < cardnum;i++) {
		printf("%03d(m%d,v%d,f%d,p%d,c%d,b%d):card %s",
			i,man_num[i],version_num[i],
			func_num[i],
			pci_num[i],
			cis_num[i],
			bind_num[i],
			cardname[i]);
		if (ano_num[i] != 0) {
			printf(" anonymous");
		}
		if (man_num[i] != 0) {
			printf(" manifd %s %s",
				man_1[i],man_2[i]);
		}
		if (version_num[i] >= 1) {
			printf(" version %s",version_1[i]);
			if (version_num[i] >= 2) {
				printf(" %s",version_2[i]);
				if (version_num[i] >= 3) {
					printf(" %s",version_3[i]);
					if (version_num[i] == 4) {
						printf(" %s",version_4[i]);
					}
				}
			}
		}
		if (func_num[i] != 0) {
			printf(" function %s",funcname[i]);
		}
		if (pci_num[i] != 0) {
			printf(" pci %s %s", pci_1[i],pci_2[i]);
		}
		if (cis_num[i] != 0) {
			printf(" cis %s",cisname[i]);
		}
		if (bind_num[i] == 1) {
			print_bind(bind_1[i],-1);
		} else {
			if (bind_to[i] == 1) {
				print_bind(bind_1[i],0);
				print_bind(bind_2[i],1);
			} else {
				print_bind(bind_1[i],-1);
				print_bind(bind_2[i],-1);
			}
		}
		printf("\n");
	}
}

