1186681Sed#!/usr/bin/awk -f 2186681Sed 3186681Sed#- 4186681Sed# Copyright (c) 2008-2009 Ed Schouten <ed@FreeBSD.org> 5186681Sed# All rights reserved. 6223574Sed# 7186681Sed# Redistribution and use in source and binary forms, with or without 8186681Sed# modification, are permitted provided that the following conditions 9186681Sed# are met: 10186681Sed# 1. Redistributions of source code must retain the above copyright 11186681Sed# notice, this list of conditions and the following disclaimer. 12186681Sed# 2. Redistributions in binary form must reproduce the above copyright 13186681Sed# notice, this list of conditions and the following disclaimer in the 14186681Sed# documentation and/or other materials provided with the distribution. 15223574Sed# 16186681Sed# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17186681Sed# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18186681Sed# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19186681Sed# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20186681Sed# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21186681Sed# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22186681Sed# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23186681Sed# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24186681Sed# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25186681Sed# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26186681Sed# SUCH DAMAGE. 27186681Sed# 28186681Sed# $FreeBSD$ 29186681Sed 30186681Sedfunction die(msg) { 31186681Sed print msg; 32186681Sed exit 1; 33186681Sed} 34186681Sed 35186681Sedfunction cchar(str) { 36186681Sed if (str == "^[") 37186681Sed return "\\x1B"; 38186681Sed 39186681Sed return str; 40186681Sed} 41186681Sed 42186681SedBEGIN { 43186681SedFS = "\t+" 44186681Sed 45186681Sedwhile (getline > 0) { 46186681Sed if (NF == 0 || $1 ~ /^#/) 47186681Sed continue; 48186681Sed 49186681Sed if (NF != 3 && NF != 4) 50186681Sed die("Invalid line layout: " NF " columns"); 51186681Sed 52186681Sed split($3, sequence, " +"); 53186681Sed nsequences = 0; 54186681Sed for (s in sequence) 55186681Sed nsequences++; 56186681Sed 57186681Sed prefix = ""; 58186681Sed l_prefix_name[""] = "teken_state_init"; 59186681Sed for (i = 1; i < nsequences; i++) { 60186681Sed n = prefix sequence[i]; 61186681Sed l_prefix_parent[n] = prefix; 62186681Sed l_prefix_suffix[n] = sequence[i]; 63186681Sed if (!l_prefix_name[n]) 64186681Sed l_prefix_name[n] = "teken_state_" ++npr; 65186681Sed prefix = n; 66186681Sed } 67186681Sed 68186681Sed suffix = sequence[nsequences]; 69186681Sed cmd = prefix suffix; 70186681Sed 71186681Sed # Fill lists 72186681Sed if (l_cmd_name[cmd] != "") 73186681Sed die(cmd " already exists"); 74186681Sed l_cmd_prefix[cmd] = prefix; 75186681Sed l_cmd_suffix[cmd] = suffix; 76186681Sed l_cmd_args[cmd] = $4; 77186681Sed l_cmd_abbr[cmd] = $1; 78186681Sed l_cmd_name[cmd] = $2; 79186681Sed l_cmd_c_name[cmd] = "teken_subr_" tolower($2); 80186681Sed gsub(" ", "_", l_cmd_c_name[cmd]); 81186681Sed 82186681Sed if ($4 != "") 83186681Sed l_prefix_numbercmds[prefix]++; 84186681Sed} 85186681Sed 86186681Sedprint "/* Generated file. Do not edit. */"; 87186681Sedprint ""; 88186681Sed 89186681Sedfor (p in l_prefix_name) { 90186681Sed if (l_prefix_name[p] != "teken_state_init") 91186681Sed print "static teken_state_t " l_prefix_name[p] ";"; 92186681Sed} 93186681Sed 94186681Sedfor (p in l_prefix_name) { 95186681Sed print ""; 96186681Sed print "/* '" p "' */"; 97186681Sed print "static void"; 98186681Sed print l_prefix_name[p] "(teken_t *t, teken_char_t c)"; 99186681Sed print "{"; 100186681Sed 101186681Sed if (l_prefix_numbercmds[p] > 0) { 102186681Sed print ""; 103186681Sed print "\tif (teken_state_numbers(t, c))"; 104186681Sed print "\t\treturn;"; 105186681Sed } 106186681Sed 107186681Sed print ""; 108186681Sed print "\tswitch (c) {"; 109186681Sed for (c in l_cmd_prefix) { 110186681Sed if (l_cmd_prefix[c] != p) 111186681Sed continue; 112186681Sed 113186681Sed print "\tcase '" cchar(l_cmd_suffix[c]) "': /* " l_cmd_abbr[c] ": " l_cmd_name[c] " */"; 114186681Sed 115186681Sed if (l_cmd_args[c] == "v") { 116186681Sed print "\t\t" l_cmd_c_name[c] "(t, t->t_curnum, t->t_nums);"; 117186681Sed } else { 118186681Sed printf "\t\t%s(t", l_cmd_c_name[c]; 119186681Sed split(l_cmd_args[c], args, " "); 120186681Sed for (a = 1; args[a] != ""; a++) { 121186681Sed if (args[a] == "n") 122186681Sed printf ", (t->t_curnum < %d || t->t_nums[%d] == 0) ? 1 : t->t_nums[%d]", a, (a - 1), (a - 1); 123186681Sed else if (args[a] == "r") 124186681Sed printf ", t->t_curnum < %d ? 0 : t->t_nums[%d]", a, (a - 1); 125186681Sed else 126186681Sed die("Invalid argument type: " args[a]); 127186681Sed } 128186681Sed print ");"; 129186681Sed } 130186681Sed print "\t\tbreak;"; 131186681Sed } 132186681Sed for (pc in l_prefix_parent) { 133186681Sed if (l_prefix_parent[pc] != p) 134186681Sed continue; 135186681Sed print "\tcase '" cchar(l_prefix_suffix[pc]) "':"; 136186681Sed print "\t\tteken_state_switch(t, " l_prefix_name[pc] ");"; 137186681Sed print "\t\treturn;"; 138186681Sed } 139186681Sed 140186681Sed print "\tdefault:"; 141186681Sed if (l_prefix_name[p] == "teken_state_init") { 142186681Sed print "\t\tteken_subr_regular_character(t, c);"; 143186681Sed } else { 144186681Sed print "\t\tteken_printf(\"Unsupported sequence in " l_prefix_name[p] ": %u\\n\", (unsigned int)c);"; 145186681Sed } 146186681Sed print "\t\tbreak;"; 147186681Sed 148186681Sed print "\t}"; 149186681Sed 150186681Sed if (l_prefix_name[p] != "teken_state_init") { 151186681Sed print ""; 152186681Sed print "\tteken_state_switch(t, teken_state_init);"; 153186681Sed } 154186681Sed print "}"; 155186681Sed} 156186681Sed 157186681Sed} 158