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