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