xref: /freebsd/sys/teken/gensequences (revision 732a02b4e77866604a120a275c082bb6221bd2ff)
1#!/usr/bin/awk -f
2
3#-
4# Copyright (c) 2008-2009 Ed Schouten <ed@FreeBSD.org>
5# All rights reserved.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
10# 1. Redistributions of source code must retain the above copyright
11#    notice, this list of conditions and the following disclaimer.
12# 2. Redistributions in binary form must reproduce the above copyright
13#    notice, this list of conditions and the following disclaimer in the
14#    documentation and/or other materials provided with the distribution.
15#
16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26# SUCH DAMAGE.
27#
28# $FreeBSD$
29
30function die(msg) {
31	print msg;
32	exit 1;
33}
34
35function cchar(str) {
36	if (str == "^[")
37		return "\\x1B";
38	if (str == "SP")
39		return " ";
40
41	return str;
42}
43
44function csequence(str) {
45	if (str == "SP")
46		return " ";
47
48	return str;
49}
50
51BEGIN {
52FS = "\t+"
53
54while (getline > 0) {
55	if (NF == 0 || $1 ~ /^#/)
56		continue;
57
58	if (NF != 3 && NF != 4)
59		die("Invalid line layout: " NF " columns");
60
61	split($3, sequence, " +");
62	nsequences = 0;
63	for (s in sequence)
64		nsequences++;
65
66	prefix = "";
67	l_prefix_name[""] = "teken_state_init";
68	for (i = 1; i < nsequences; i++) {
69		n = prefix csequence(sequence[i]);
70		l_prefix_parent[n] = prefix;
71		l_prefix_suffix[n] = sequence[i];
72		if (!l_prefix_name[n])
73			l_prefix_name[n] = "teken_state_" ++npr;
74		prefix = n;
75	}
76
77	suffix = sequence[nsequences];
78	cmd = prefix suffix;
79
80	# Fill lists
81	if (l_cmd_name[cmd] != "")
82		die(cmd " already exists");
83	l_cmd_prefix[cmd] = prefix;
84	l_cmd_suffix[cmd] = suffix;
85	l_cmd_args[cmd] = $4;
86	l_cmd_abbr[cmd] = $1;
87	l_cmd_name[cmd] = $2;
88	l_cmd_c_name[cmd] = "teken_subr_" tolower($2);
89	gsub(" ", "_", l_cmd_c_name[cmd]);
90
91	if ($4 != "")
92		l_prefix_numbercmds[prefix]++;
93}
94
95print "/* Generated file. Do not edit. */";
96print "";
97
98for (p in l_prefix_name) {
99	if (l_prefix_name[p] != "teken_state_init")
100		print "static teken_state_t	" l_prefix_name[p] ";";
101}
102
103for (p in l_prefix_name) {
104	print "";
105	print "/* '" p "' */";
106	print "static void";
107	print l_prefix_name[p] "(teken_t *t, teken_char_t c)";
108	print "{";
109
110	if (l_prefix_numbercmds[p] > 0) {
111		print "";
112		print "\tif (teken_state_numbers(t, c))";
113		print "\t\treturn;";
114	}
115
116	print "";
117	print "\tswitch (c) {";
118	for (c in l_cmd_prefix) {
119		if (l_cmd_prefix[c] != p)
120			continue;
121
122		print "\tcase '" cchar(l_cmd_suffix[c]) "': /* " l_cmd_abbr[c] ": " l_cmd_name[c] " */";
123
124		if (l_cmd_args[c] == "v") {
125			print "\t\t" l_cmd_c_name[c] "(t, t->t_curnum, t->t_nums);";
126		} else {
127			printf "\t\t%s(t", l_cmd_c_name[c];
128			split(l_cmd_args[c], args, " ");
129			for (a = 1; args[a] != ""; a++) {
130				if (args[a] == "n")
131					printf ", (t->t_curnum < %d || t->t_nums[%d] == 0) ? 1 : t->t_nums[%d]", a, (a - 1), (a - 1);
132				else if (args[a] == "r")
133					printf ", t->t_curnum < %d ? 0 : t->t_nums[%d]", a, (a - 1);
134				else
135					die("Invalid argument type: " args[a]);
136			}
137			print ");";
138		}
139		print "\t\tbreak;";
140	}
141	for (pc in l_prefix_parent) {
142		if (l_prefix_parent[pc] != p)
143			continue;
144		print "\tcase '" cchar(l_prefix_suffix[pc]) "':";
145		print "\t\tteken_state_switch(t, " l_prefix_name[pc] ");";
146		print "\t\treturn;";
147	}
148
149	print "\tdefault:";
150	if (l_prefix_name[p] == "teken_state_init") {
151		print "\t\tteken_subr_regular_character(t, c);";
152	} else {
153		print "\t\tteken_printf(\"Unsupported sequence in " l_prefix_name[p] ": %u\\n\", (unsigned int)c);";
154	}
155	print "\t\tbreak;";
156
157	print "\t}";
158
159	if (l_prefix_name[p] != "teken_state_init") {
160		print "";
161		print "\tt->t_last = 0;";
162		print "\tteken_state_switch(t, teken_state_init);";
163	}
164	print "}";
165}
166
167}
168