gensequences revision 256281
1129199Scognet#!/usr/bin/awk -f
2129199Scognet
3129199Scognet#-
4129199Scognet# Copyright (c) 2008-2009 Ed Schouten <ed@FreeBSD.org>
5129199Scognet# All rights reserved.
6129199Scognet#
7129199Scognet# Redistribution and use in source and binary forms, with or without
8129199Scognet# modification, are permitted provided that the following conditions
9129199Scognet# are met:
10129199Scognet# 1. Redistributions of source code must retain the above copyright
11135670Scognet#    notice, this list of conditions and the following disclaimer.
12129199Scognet# 2. Redistributions in binary form must reproduce the above copyright
13129199Scognet#    notice, this list of conditions and the following disclaimer in the
14129199Scognet#    documentation and/or other materials provided with the distribution.
15135670Scognet#
16129199Scognet# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17129199Scognet# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18129199Scognet# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19129199Scognet# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20169612Swkoszek# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21129199Scognet# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22129199Scognet# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23136910Sru# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24129199Scognet# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25129199Scognet# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26129199Scognet# SUCH DAMAGE.
27129199Scognet#
28129199Scognet# $FreeBSD: stable/10/sys/teken/gensequences 223574 2011-06-26 18:25:10Z ed $
29129199Scognet
30129199Scognetfunction die(msg) {
31129199Scognet	print msg;
32129199Scognet	exit 1;
33129199Scognet}
34129199Scognet
35129199Scognetfunction cchar(str) {
36135670Scognet	if (str == "^[")
37135670Scognet		return "\\x1B";
38140479Scognet
39140479Scognet	return str;
40140479Scognet}
41140479Scognet
42160479ScognetBEGIN {
43140479ScognetFS = "\t+"
44140479Scognet
45151423Scognetwhile (getline > 0) {
46157165Scognet	if (NF == 0 || $1 ~ /^#/)
47153112Scognet		continue;
48147630Scognet
49150862Scognet	if (NF != 3 && NF != 4)
50150862Scognet		die("Invalid line layout: " NF " columns");
51150862Scognet
52160629Scognet	split($3, sequence, " +");
53160629Scognet	nsequences = 0;
54160629Scognet	for (s in sequence)
55160629Scognet		nsequences++;
56152782Scognet
57152742Scognet	prefix = "";
58152742Scognet	l_prefix_name[""] = "teken_state_init";
59153549Scognet	for (i = 1; i < nsequences; i++) {
60152742Scognet		n = prefix sequence[i];
61152742Scognet		l_prefix_parent[n] = prefix;
62152742Scognet		l_prefix_suffix[n] = sequence[i];
63152742Scognet		if (!l_prefix_name[n])
64152742Scognet			l_prefix_name[n] = "teken_state_" ++npr;
65153566Scognet		prefix = n;
66175984Sraj	}
67175984Sraj
68175984Sraj	suffix = sequence[nsequences];
69175984Sraj	cmd = prefix suffix;
70159084Scognet
71159084Scognet	# Fill lists
72159084Scognet	if (l_cmd_name[cmd] != "")
73171619Scognet		die(cmd " already exists");
74171619Scognet	l_cmd_prefix[cmd] = prefix;
75153566Scognet	l_cmd_suffix[cmd] = suffix;
76159758Scognet	l_cmd_args[cmd] = $4;
77153566Scognet	l_cmd_abbr[cmd] = $1;
78153566Scognet	l_cmd_name[cmd] = $2;
79153549Scognet	l_cmd_c_name[cmd] = "teken_subr_" tolower($2);
80153566Scognet	gsub(" ", "_", l_cmd_c_name[cmd]);
81171619Scognet
82171619Scognet	if ($4 != "")
83171619Scognet		l_prefix_numbercmds[prefix]++;
84153549Scognet}
85153566Scognet
86159557Scognetprint "/* Generated file. Do not edit. */";
87159557Scognetprint "";
88153549Scognet
89171619Scognetfor (p in l_prefix_name) {
90171619Scognet	if (l_prefix_name[p] != "teken_state_init")
91153549Scognet		print "static teken_state_t	" l_prefix_name[p] ";";
92171619Scognet}
93171619Scognet
94152742Scognetfor (p in l_prefix_name) {
95153566Scognet	print "";
96153566Scognet	print "/* '" p "' */";
97153566Scognet	print "static void";
98153566Scognet	print l_prefix_name[p] "(teken_t *t, teken_char_t c)";
99154561Scognet	print "{";
100154561Scognet
101153566Scognet	if (l_prefix_numbercmds[p] > 0) {
102153112Scognet		print "";
103154561Scognet		print "\tif (teken_state_numbers(t, c))";
104153566Scognet		print "\t\treturn;";
105153549Scognet	}
106171619Scognet
107171619Scognet	print "";
108153549Scognet	print "\tswitch (c) {";
109171619Scognet	for (c in l_cmd_prefix) {
110171619Scognet		if (l_cmd_prefix[c] != p)
111153112Scognet			continue;
112153566Scognet
113153549Scognet		print "\tcase '" cchar(l_cmd_suffix[c]) "': /* " l_cmd_abbr[c] ": " l_cmd_name[c] " */";
114171619Scognet
115150862Scognet		if (l_cmd_args[c] == "v") {
116129199Scognet			print "\t\t" l_cmd_c_name[c] "(t, t->t_curnum, t->t_nums);";
117129199Scognet		} else {
118129199Scognet			printf "\t\t%s(t", l_cmd_c_name[c];
119129199Scognet			split(l_cmd_args[c], args, " ");
120129199Scognet			for (a = 1; args[a] != ""; a++) {
121129199Scognet				if (args[a] == "n")
122129199Scognet					printf ", (t->t_curnum < %d || t->t_nums[%d] == 0) ? 1 : t->t_nums[%d]", a, (a - 1), (a - 1);
123129199Scognet				else if (args[a] == "r")
124129199Scognet					printf ", t->t_curnum < %d ? 0 : t->t_nums[%d]", a, (a - 1);
125129199Scognet				else
126129199Scognet					die("Invalid argument type: " args[a]);
127129199Scognet			}
128153549Scognet			print ");";
129153549Scognet		}
130150918Scognet		print "\t\tbreak;";
131153549Scognet	}
132153549Scognet	for (pc in l_prefix_parent) {
133153549Scognet		if (l_prefix_parent[pc] != p)
134153549Scognet			continue;
135150918Scognet		print "\tcase '" cchar(l_prefix_suffix[pc]) "':";
136135670Scognet		print "\t\tteken_state_switch(t, " l_prefix_name[pc] ");";
137135670Scognet		print "\t\treturn;";
138135670Scognet	}
139129199Scognet
140129199Scognet	print "\tdefault:";
141129199Scognet	if (l_prefix_name[p] == "teken_state_init") {
142		print "\t\tteken_subr_regular_character(t, c);";
143	} else {
144		print "\t\tteken_printf(\"Unsupported sequence in " l_prefix_name[p] ": %u\\n\", (unsigned int)c);";
145	}
146	print "\t\tbreak;";
147
148	print "\t}";
149
150	if (l_prefix_name[p] != "teken_state_init") {
151		print "";
152		print "\tteken_state_switch(t, teken_state_init);";
153	}
154	print "}";
155}
156
157}
158