#! /usr/bin/awk -f

#	$Maekawa: hiddefs2h.awk,v 1.4 2000/04/02 21:02:14 maekawa Exp $

# Copyright (c) 1995, 1996 Christopher G. Demetriou
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
#    must display the following acknowledgement:
#      This product includes software developed by Christopher G. Demetriou.
# 4. The name of the author may not be used to endorse or promote products
#    derived from this software without specific prior written permission
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

BEGIN {
	nitemtypes = nitems = ncolls = 0;
	nupages = nutypes = nusages = 0;

	hfile = "hiddefs.h"
	dfile = "hiddefs_data.h"
}

NR == 1 {
	VERSION = $0;
	gsub("\\$", "", VERSION);

	printf("/*\t\$Maekawa\$\t*/\n\n") > dfile;
	printf("/*\n") > dfile;
	printf(" * THIS FILE IS AUTOMATICALLY GENERATED.  DO NOT EDIT.\n") \
	    > dfile;
	printf(" *\n") > dfile;
	printf(" * generated from:\n") > dfile;
	printf(" *\t%s\n", VERSION) > dfile;
	printf(" */\n\n") > dfile;

	printf("/*\t\$Maekawa\$\t*/\n\n") > hfile;
	printf("/*\n") > hfile;
	printf(" * THIS FILE IS AUTOMATICALLY GENERATED.  DO NOT EDIT.\n") \
	    > hfile;
	printf(" *\n") > hfile;
	printf(" * generated from:\n") > hfile;
	printf(" *\t%s\n", VERSION) > hfile;
	printf(" */\n\n") > hfile;

	next
}

$1 == "itemtype" {
	nitemtypes++;

	itemindex[$2] = nitemtypes;
	itemtypes[nitemtypes, 1] = $2;
	itemtypes[nitemtypes, 2] = $3;

	printf("#define\tHID_ITEM_TYPE_%s\t\t%s\n",
		itemtypes[nitemtypes, 1], itemtypes[nitemtypes, 2]) > hfile;

	next;
}

$1 == "item" {
	nitems++;

	items[nitems, 1] = $2;
	items[nitems, 2] = $3;
	items[nitems, 3] = $4;

	printf("#define\tHID_%s_ITEM_%s\t\t%s\n",
	       items[nitems, 1], items[nitems, 2], items[nitems, 3]) > hfile;

	i = 4; f = 5;

	oparen = 0;
	while (f <= NF) {
		if ($f == "#") {
			oparen = 1;
			f++;
			continue;
		}
		if (oparen) {
			f++;
			continue;
		}
		items[nitems, i] = $f;
		i++; f++;
	}

	next
}

$1 == "collection" {
	ncolls++;

	colls[ncolls, 1] = $2;
	colls[ncolls, 2] = $3;

	printf("#define\tHID_COLLECTION_%s\t%s\n",
		colls[ncolls, 1], colls[ncolls, 2]) > hfile;

	i = 3; f = 4;
	oparen = 0;
	while (f <= NF) {
		if ($f == "#") {
			oparen = 1;
			f++;
			continue;
		}
		if (oparen) {
			f++;
			continue;
		}
		colls[ncolls, i] = $f;
		i++; f++;
	}

	next
}

$1 == "usagepage" {
	nupages++;

	pageindex[$2] = nupages;
	upages[nupages, 1] = $2;
	upages[nupages, 2] = $3;

	printf("#define\tHID_USAGE_PAGE_%s\t\t%s\n", upages[nupages, 1],
	       upages[nupages, 2]) > hfile;

	i = 3; f = 4;

	oparen = 0;
	while (f <= NF) {
		if ($f == "#") {
			oparen = 1;
			f++;
			continue;
		}
		if (oparen) {
			f++;
			continue;
		}
		upages[nupages, i] = $f;
		i++; f++;
	}

	next
}

$1 == "usagetype" {
	nutypes++;

	utypes[nutypes, 1] = $2;
	utypes[nutypes, 2] = $3;
	utypes[nutypes, 3] = $4;

	printf("#define\t%s\t0x%08x",
	       utypes[nutypes, 3], 2 ** (nutypes - 2)) > hfile;

	i = 4; f = 5;

	ocomment = oparen = 0;
	if (f <= NF) {
		printf("\t/* ") > hfile;
		ocomment = 1;
	}
	while (f <= NF) {
		if ($f == "#") {
			printf("(") > hfile;
			oparen = 1;
			f++;
			continue;
		}
		if (oparen) {
			printf("%s", $f) > hfile;
			if (f < NF)
				printf(" ") > hfile;
			f++;
			continue;
		}
		items[nitems, i] = $f;
		printf("%s", items[nitems, i]) > hfile;
		if (f < NF)
			printf(" ") > hfile;
		i++; f++;
	}
	if (oparen)
		printf(")") > hfile;
	if (ocomment)
		printf(" */") > hfile;
	printf("\n") > hfile;

	next;
}

$1 == "usage" {
	nusages++;

	usages[nusages, 1] = $2;
	usages[nusages, 2] = $3;
	usages[nusages, 3] = $4;

	i = 4; f = 5;

	oparen = 0;
	while (f <= NF) {
		if ($f == "#") {
			oparen = 1;
			f++;
			continue;
		}
		if (oparen) {
			f++;
			continue;
		}
		usages[nusages, i] = $f;
		i++; f++;
	}

	next
}

{
	if ($0 == "")
		blanklins++;
	printf $0 > hfile;
	if (blanklines < 2)
		printf("\n") > hfile;
}

END {
	printf("/*\n * Item Table\n */\n") > dfile;
	printf("struct hid_item {\n") > dfile;
	printf("\tu_int8_t\ttype;\n") > dfile;
	printf("\tu_int8_t\ttag;\n") > dfile;
	printf("\tchar\t\t*name;\n") > dfile;
	printf("};\n\n") > dfile;

	printf("struct hid_item hid_items[] = {\n") > dfile;
	for (i = 1 ; i <= nitems ; i++) {
		itemi = itemindex[items[i, 1]];
		printf("\t{\n") > dfile;
		printf("\t\tHID_ITEM_TYPE_%s,\n", itemtypes[itemi, 1]) > dfile;
		printf("\t\tHID_%s_ITEM_%s,\n", itemtypes[itemi, 1],
			items[i, 2]) > dfile;
		j = 4;
		needspace = 0;
		printf("\t\t\"") > dfile;
		while (items[i, j] != "") {
			if (needspace)
				printf(" ") > dfile;
			printf("%s", items[i, j]) > dfile;
			needspace = 1;
			j++;
		}
		printf("\",\n") > dfile;
		printf("\t},\n") > dfile;
	}
	printf("\t{ 0xff, 0xff, NULL, }\n};\n") > dfile;

	printf("\n/*\n * Collection Table\n */\n") > dfile;

	printf("struct hid_collection {\n") > dfile;
	printf("\tu_int8_t\ttype;\n") > dfile;
	printf("\tchar\t\t*name;\n") > dfile;
	printf("};\n\n") > dfile;

	printf("struct hid_collection hid_collections[] = {\n") > dfile;
	for (i = 1 ; i <= ncolls ; i++) {
		printf("\t{\n") > dfile;
		printf("\t\tHID_COLLECTION_%s,\n", colls[i, 1]) > dfile;
		printf("\t\t\"") > dfile;
		if (colls[i, 3] != "") {
			j = 3;
			needspace = 0;
			while (colls[i, j] != "") {
				if (needspace)
					printf(" ") > dfile;
				printf("%s", colls[i, j]) > dfile;
				needspace = 1;
				j++;
			}
		}
		printf("\",\n") > dfile;
		printf("\t},\n") > dfile;
	}
	printf("\t{ 0xff, NULL, }\n};\n") > dfile;

	printf("\n/*\n * Usage Page Table\n */\n") > dfile;

	printf("struct hid_usage_page {\n") > dfile;
	printf("\tu_int16_t\tpage;\n") > dfile;
	printf("\tchar\t\t*name;\n") > dfile;
	printf("};\n\n") > dfile;

	printf("struct hid_usage_page hid_usage_pages[] = {\n") > dfile;
	for (i = 1 ; i <= nupages ; i++) {
		printf("\t{\n") > dfile;
		printf("\t\tHID_USAGE_PAGE_%s,\n", upages[i, 1]) > dfile;
		printf("\t\t\"") > dfile;
		j = 3;
		needspace = 0;
		while (upages[i, j] != "") {
			if (needspace)
				printf(" ") > dfile;
			printf("%s", upages[i, j]) > dfile;
			needspace = 1;
			j++;
		}
		printf("\",\n") > dfile;
		printf("\t},\n") > dfile;
	}
	printf("\t{ 0xffff, NULL, }\n};\n") > dfile;

	printf("\n/*\n * Usage Table\n */\n") > dfile;

	printf("struct hid_usage {\n") > dfile;
	printf("\tu_int16_t\tpage;\n") > dfile;
	printf("\tu_int16_t\tusage;\n") > dfile;
	printf("\tchar\t\t*name;\n") > dfile;
	printf("\tu_int32_t\ttype;\n") > dfile;
	printf("};\n\n") > dfile;

	printf("struct hid_usage hid_usages[] = {\n") > dfile;
	for (i = 1 ; i <= nusages ; i++) {
		pagei = pageindex[usages[i, 1]];

		printf("\t{\n") > dfile;
		printf("\t\tHID_USAGE_PAGE_%s,\n", upages[pagei, 1]) > dfile;
		printf("\t\t%s, \"", usages[i, 3]) > dfile;
		j = 4;
		needspace = 0;
		while (usages[i, j] != "") {
			if (needspace)
				printf(" ") > dfile;
			printf("%s", usages[i, j]) > dfile;
			needspace = 1;
			j++;
		}
		printf("\",\n") > dfile;
		printf("\t\t%s,\n\t},\n", usages[i, 2]) > dfile;
	}
	printf("\t{ 0xffff, 0xffff, NULL, NONE, }\n};\n") > dfile;
}
