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 29function die(msg) { 30 print msg; 31 exit 1; 32} 33 34function cchar(str) { 35 if (str == "^[") 36 return "\\x1B"; 37 if (str == "SP") 38 return " "; 39 40 return str; 41} 42 43function csequence(str) { 44 if (str == "SP") 45 return " "; 46 47 return str; 48} 49 50BEGIN { 51FS = "\t+" 52 53while (getline > 0) { 54 if (NF == 0 || $1 ~ /^#/) 55 continue; 56 57 if (NF != 3 && NF != 4) 58 die("Invalid line layout: " NF " columns"); 59 60 split($3, sequence, " +"); 61 nsequences = 0; 62 for (s in sequence) 63 nsequences++; 64 65 prefix = ""; 66 l_prefix_name[""] = "teken_state_init"; 67 for (i = 1; i < nsequences; i++) { 68 n = prefix csequence(sequence[i]); 69 l_prefix_parent[n] = prefix; 70 l_prefix_suffix[n] = sequence[i]; 71 if (!l_prefix_name[n]) 72 l_prefix_name[n] = "teken_state_" ++npr; 73 prefix = n; 74 } 75 76 suffix = sequence[nsequences]; 77 cmd = prefix suffix; 78 79 # Fill lists 80 if (l_cmd_name[cmd] != "") 81 die(cmd " already exists"); 82 l_cmd_prefix[cmd] = prefix; 83 l_cmd_suffix[cmd] = suffix; 84 l_cmd_args[cmd] = $4; 85 l_cmd_abbr[cmd] = $1; 86 l_cmd_name[cmd] = $2; 87 l_cmd_c_name[cmd] = "teken_subr_" tolower($2); 88 gsub(" ", "_", l_cmd_c_name[cmd]); 89 90 if ($4 != "") 91 l_prefix_numbercmds[prefix]++; 92} 93 94print "/* Generated file. Do not edit. */"; 95print ""; 96 97for (p in l_prefix_name) { 98 if (l_prefix_name[p] != "teken_state_init") 99 print "static teken_state_t " l_prefix_name[p] ";"; 100} 101 102for (p in l_prefix_name) { 103 print ""; 104 print "/* '" p "' */"; 105 print "static void"; 106 print l_prefix_name[p] "(teken_t *t, teken_char_t c)"; 107 print "{"; 108 109 if (l_prefix_numbercmds[p] > 0) { 110 print ""; 111 print "\tif (teken_state_numbers(t, c))"; 112 print "\t\treturn;"; 113 } 114 115 print ""; 116 print "\tswitch (c) {"; 117 for (c in l_cmd_prefix) { 118 if (l_cmd_prefix[c] != p) 119 continue; 120 121 print "\tcase '" cchar(l_cmd_suffix[c]) "': /* " l_cmd_abbr[c] ": " l_cmd_name[c] " */"; 122 123 if (l_cmd_args[c] == "v") { 124 print "\t\t" l_cmd_c_name[c] "(t, t->t_curnum, t->t_nums);"; 125 } else { 126 printf "\t\t%s(t", l_cmd_c_name[c]; 127 split(l_cmd_args[c], args, " "); 128 for (a = 1; args[a] != ""; a++) { 129 if (args[a] == "n") 130 printf ", (t->t_curnum < %d || t->t_nums[%d] == 0) ? 1 : t->t_nums[%d]", a, (a - 1), (a - 1); 131 else if (args[a] == "r") 132 printf ", t->t_curnum < %d ? 0 : t->t_nums[%d]", a, (a - 1); 133 else 134 die("Invalid argument type: " args[a]); 135 } 136 print ");"; 137 } 138 print "\t\tbreak;"; 139 } 140 for (pc in l_prefix_parent) { 141 if (l_prefix_parent[pc] != p) 142 continue; 143 print "\tcase '" cchar(l_prefix_suffix[pc]) "':"; 144 print "\t\tteken_state_switch(t, " l_prefix_name[pc] ");"; 145 print "\t\treturn;"; 146 } 147 148 print "\tdefault:"; 149 if (l_prefix_name[p] == "teken_state_init") { 150 print "\t\tteken_subr_regular_character(t, c);"; 151 } else { 152 print "\t\tteken_printf(\"Unsupported sequence in " l_prefix_name[p] ": %u\\n\", (unsigned int)c);"; 153 } 154 print "\t\tbreak;"; 155 156 print "\t}"; 157 158 if (l_prefix_name[p] != "teken_state_init") { 159 print ""; 160 print "\tt->t_last = 0;"; 161 print "\tteken_state_switch(t, teken_state_init);"; 162 } 163 print "}"; 164} 165 166} 167