#! /bin/sh # # Copyright (C) 2000 by Kevin L. Mitchell # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # @(#)$Id: comp_et-sh.in,v 1.1 2003-03-07 02:36:10 klmitch Exp $ com_err=true c_file= c_name= c_dir= h_file= h_name= h_dir= dir= in_file= ce_prev= for ce_option do # if the previous option needed an argument, assign it... if test -n "$ce_prev"; then eval "$ce_prev=\$ce_option" ce_prev= continue fi case "$ce_option" in -*=*) ce_optarg=`echo "$ce_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) ce_optarg= ;; esac case "$ce_option" in -c_f | -c_fi | -c_fil | -c_file | \ -c-f | -c-fi | -c-fil | -c-file | \ --c_f | --c_fi | --c_fil | --c_file | \ --c-f | --c-fi | --c-fil | --c-file ) ce_prev=c_file ;; -c_f=* | -c_fi=* | -c_fil=* | -c_file=* | \ -c-f=* | -c-fi=* | -c-fil=* | -c-file=* | \ --c_f=* | --c_fi=* | --c_fil=* | --c_file=* | \ --c-f=* | --c-fi=* | --c-fil=* | --c-file=* ) c_file="$ce_optarg" ;; -c_d | -c_di | -c_dir | \ -c-d | -c-di | -c-dir | \ --c_d | --c_di | --c_dir | \ --c-d | --c-di | --c-dir ) ce_prev=c_dir ;; -c_d=* | -c_di=* | -c_dir=* | \ -c-d=* | -c-di=* | -c-dir=* | \ --c_d=* | --c_di=* | --c_dir=* | \ --c-d=* | --c-di=* | --c-dir=* ) c_dir="$ce_optarg" ;; -h_f | -h_fi | -h_fil | -h_file | \ -h-f | -h-fi | -h-fil | -h-file | \ --h_f | --h_fi | --h_fil | --h_file | \ --h-f | --h-fi | --h-fil | --h-file ) ce_prev=h_file ;; -h_f=* | -h_fi=* | -h_fil=* | -h_file=* | \ -h-f=* | -h-fi=* | -h-fil=* | -h-file=* | \ --h_f=* | --h_fi=* | --h_fil=* | --h_file=* | \ --h-f=* | --h-fi=* | --h-fil=* | --h-file=* ) h_file="$ce_optarg" ;; -h_d | -h_di | -h_dir | \ -h-d | -h-di | -h-dir | \ --h_d | --h_di | --h_dir | \ --h-d | --h-di | --h-dir ) ce_prev=h_dir ;; -h_d=* | -h_di=* | -h_dir=* | \ -h-d=* | -h-di=* | -h-dir=* | \ --h_d=* | --h_di=* | --h_dir=* | \ --h-d=* | --h-di=* | --h-dir=* ) h_dir="$ce_optarg" ;; -d | -di | -dir | \ --d | --di | --dir ) ce_prev=dir ;; -d=* | -di=* | -dir=* | \ --d=* | --di=* | --dir=* ) dir="$ce_optarg" ;; -com | -com_ | -com_e | -com_er | -com_err | \ -com- | -com-e | -com-er | -com-err | \ --com | --com_ | --com_e | --com_er | --com_err | \ --com- | --com-e | --com-er | --com-err ) ce_prev=com_err ;; -com=* | -com_=* | -com_e=* | -com_er=* | -com_err=* | \ -com-=* | -com-e=* | -com-er=* | -com-err=* | \ --com=* | --com_=* | --com_e=* | --com_er=* | --com_err=* | \ --com-=* | --com-e=* | --com-er=* | --com-err=* ) com_err="$ce_optarg" ;; -he | -hel | -help | \ --he | --hel | --help ) cat < Options: --c-file=FILE Set the output .c file to FILE --h-file=FILE Set the output .h file to FILE --com-err=OPTION Selects whether support for com_err should be used; OPTION may be either true or false --help Print this message EOF exit 0 ;; -*) echo "$0: Invalid option $ce_option; use --help to show usage" 1>&2 exit 1 ;; *) if test -n "$in_file"; then echo "$0: Can only process one file at a time" 1>&2 exit 1 fi in_file="$ce_option" ;; esac done if test -n "$ce_prev"; then echo "$0: Missing argument for option; use --help to show usage" 1>&2 exit 1 fi if test -z "$in_file"; then echo "$0: No input file specified; use --help to show usage" 1>&2 exit 1 fi if test ! -r "$in_file"; then echo "$0: Unable to read input file $in_file" 1>&2 exit 1 fi com_err=`echo "$com_err" | tr 'A-Z' 'a-z'` case "$com_err" in t | tr | tru | true | y | ye | yes) com_err=true ;; f | fa | fal | fals | false | n | no) com_err=false ;; *) echo "$0: Invalid value for --com-err; use --help to show usage" 1>&2 exit 1 ;; esac in_dir=`echo "$in_file" | sed 's%/[^/]*$%%'` in_name=`echo "$in_file" | sed -e 's%.*/%%' -e 's/\.et$//'` if test -z "$dir"; then dir="$in_dir" fi if test -z "$c_dir"; then c_dir="$dir" fi if test -z "$h_dir"; then h_dir="$dir" fi if test "$com_err" = false; then c_file="/dev/null" c_dir= elif test -z "$c_file"; then c_file="$c_dir/$in_name.c" fi c_name=`echo "$c_file" | sed 's%.*/%%'` if test -z "$h_file"; then h_file="$h_dir/$in_name.h" fi h_name=`echo "$h_file" | sed 's%.*/%%'` @AWK@ -f - "com_err=$com_err" "c_file=$c_file" "c_name=$c_name" \ "h_file=$h_file" "h_name=$h_name" "$in_file" <<\EOF BEGIN { char_shift = 64; c2n["A"] = 1; c2n["B"] = 2; c2n["C"] = 3; c2n["D"] = 4; c2n["E"] = 5; c2n["F"] = 6; c2n["G"] = 7; c2n["H"] = 8; c2n["I"] = 9; c2n["J"] = 10; c2n["K"] = 11; c2n["L"] = 12; c2n["M"] = 13; c2n["N"] = 14; c2n["O"] = 15; c2n["P"] = 16; c2n["Q"] = 17; c2n["R"] = 18; c2n["S"] = 19; c2n["T"] = 20; c2n["U"] = 21; c2n["V"] = 22; c2n["W"] = 23; c2n["X"] = 24; c2n["Y"] = 25; c2n["Z"] = 26; c2n["a"] = 27; c2n["b"] = 28; c2n["c"] = 29; c2n["d"] = 30; c2n["e"] = 31; c2n["f"] = 32; c2n["g"] = 33; c2n["h"] = 34; c2n["i"] = 35; c2n["j"] = 36; c2n["k"] = 37; c2n["l"] = 38; c2n["m"] = 39; c2n["n"] = 40; c2n["o"] = 41; c2n["p"] = 42; c2n["q"] = 43; c2n["r"] = 44; c2n["s"] = 45; c2n["t"] = 46; c2n["u"] = 47; c2n["v"] = 48; c2n["w"] = 49; c2n["x"] = 50; c2n["y"] = 51; c2n["z"] = 52; c2n["0"] = 53; c2n["1"] = 54; c2n["2"] = 55; c2n["3"] = 56; c2n["4"] = 57; c2n["5"] = 58; c2n["6"] = 59; c2n["7"] = 60; c2n["8"] = 61; c2n["9"] = 62; c2n["_"] = 63; } /^#/ { next } /^[ \t]*(error_table|et)[ \t]+[a-zA-Z][a-zA-Z0-9_]+/ { tab_num = 0; tab_name = $2; mod_base = 1000000; for (i = 1; i <= length(tab_name); i++) { tab_num = (tab_num * char_shift) + c2n[substr(tab_name, i, 1)]; } # Some awk programs don't have enough precision, so we have to play # some games here... base_low = tab_num % mod_base; base_high = int(tab_num / mod_base); base_sign = 1; # now shift it over by 8 bits... base_low = base_low * 256; base_high = (base_high * 256) + int(base_low / mod_base); base_low = base_low % mod_base; # Next, figure out the sign... if (tab_num > (128 * 256 * 256)) { # subtract 256 * 256 * 256 * 256... sub_low = 256 * 256 * 256 % mod_base; sub_high = int(256 * 256 * 256 / mod_base); sub_low = sub_low * 256; sub_high = (sub_high * 256) + int(sub_low / mod_base); sub_low = sub_low % mod_base; base_low = sub_low - base_low; base_high = sub_high - base_high; base_sign = -1; # Now correct for base_low being negative... if (base_low < 0) { base_low = base_low + mod_base; base_high--; } } curr_low = base_low; curr_high = base_high; curr_sign = base_sign; tab_count = 0; print "/*" > h_file; print " * " h_name ":" > h_file; print " * This file is automatically generated; please do not edit it." > h_file; print " */" > h_file; print "/*" > c_file; print " * " c_name ":" > c_file; print " * This file is automatically generated; please do not edit it." > c_file; print " */" > c_file; print "#if defined(__STDC__) || defined(_MSDOS) || defined(_WIN32)" > c_file; print "#define NOARGS void" > c_file; print "#else" > c_file; print "#define NOARGS" > c_file; print "#define const" > c_file; print "#endif" > c_file; print "" > c_file; print "static const char * const text[] = {" > c_file; } (cont == 1) && ($0 ~ /\\[ \t]*$/) { text = substr($0, 1, length($0) - 1); cont_buf = cont_buf text; } (cont == 1) && ($0 ~ /"[ \t]*$/) { printf "\t%s,\n", cont_buf $0 > c_file; cont = 0; } /^[ \t]*(error_code|ec)[ \t]+[A-Z_0-9]+,[ \t]*$/ { tag = substr($2, 1, length($2) - 1); if (curr_high == 0) { printf "#define %-40s (%dL)\n", tag, curr_sign * curr_low > h_file; } else { printf "#define %-40s (%d%06dL)\n", tag, curr_sign * curr_high , curr_low > h_file; } curr_low += curr_sign; if (curr_low >= mod_base) { curr_low -= mod_base; curr_high++; } if (curr_low < 0) { curr_low += mod_base; curr_high--; } tab_count++; skipone = 1; next; } /^[ \t]*(error_code|ec)[ \t]+[A-Z_0-9]+,[ \t]*".*"[ \t]*$/ { tag = substr($2, 1, length($2) - 1); if (curr_high == 0) { printf "#define %-40s (%dL)\n", tag, curr_sign * curr_low > h_file; } else { printf "#define %-40s (%d%06dL)\n", tag, curr_sign * curr_high , curr_low > h_file; } curr_low += curr_sign; if (curr_low >= mod_base) { curr_low -= mod_base; curr_high++; } if (curr_low < 0) { curr_low += mod_base; curr_high--; } text = ""; for (i = 3; i <= NF; i++) { text = text FS $i; } text = substr(text, 2, length(text) - 1); printf "\t%s,\n", text > c_file; tab_count++; } /^[ \t]*(error_code|ec)[ \t]+[A-Z_0-9]+,[ \t]*".*\\[ \t]*$/ { tag = substr($2, 1, length($2) - 1); if (curr_high == 0) { printf "#define %-40s (%dL)\n", tag, curr_sign * curr_low > h_file; } else { printf "#define %-40s (%d%06dL)\n", tag, curr_sign * curr_high , curr_low > h_file; } curr_low += curr_sign; if (curr_low >= mod_base) { curr_low -= mod_base; curr_high++; } if (curr_low < 0) { curr_low += mod_base; curr_high--; } text = ""; for (i = 3; i <= NF; i++) { text = text FS $i; } text = substr(text, 2, length(text) - 2); cont_buf = text; cont++; } /^[ \t]*".*\\[ \t]*$/ { if (skipone) { text = substr($0, 1, length($0) - 1); cont_buf = text; cont++; } skipone = 0; } { if (skipone) { printf "\t%s,\n", $0 > c_file; } skipone = 0; } END { if (com_err == "false") { print "#define initialize_" tab_name "_error_table()" > h_file; } else { print "extern void initialize_" tab_name "_error_table ();" > h_file; } if (base_high == 0) { printf "#define ERROR_TABLE_BASE_%s (%dL)\n", tab_name, base_sign * base_low > h_file; } else { printf "#define ERROR_TABLE_BASE_%s (%d%06dL)\n", tab_name, base_sign * base_high, base_low > h_file; } print "" > h_file; print "/* for compatibility with older versions... */" > h_file; print "#define init_" tab_name "_err_tbl initialize_" tab_name "_error_table" > h_file; print "#define " tab_name "_err_base ERROR_TABLE_BASE_" tab_name > h_file; print " 0" > c_file; print "};" > c_file; print "" > c_file; print "struct error_table {" > c_file; print " char const * const * msgs;" > c_file; print " long base;" > c_file; print " int n_msgs;" > c_file; print "};" > c_file; print "struct et_list {" > c_file; print " struct et_list *next;" > c_file; print " const struct error_table * table;" > c_file; print "};" > c_file; print "extern struct et_list *_et_list;" > c_file; print "" > c_file; if (base_high == 0) { printf "static const struct error_table et = { text, %dL, %d };\n", base_sign * base_low, tab_count > c_file; } else { printf "static const struct error_table et = { text, %d%06dL, %d };\n", base_sign * base_high, base_low, tab_count > c_file; } print "" > c_file; print "static struct et_list link = { 0, 0 };" > c_file; print "" > c_file; print "void initialize_" tab_name "_error_table (NOARGS) {" > c_file; print " if (!link.table) {" > c_file; print " link.next = _et_list;" > c_file; print " link.table = &et;" > c_file; print " _et_list = &link;" > c_file; print " }" > c_file; print "}"> c_file; } EOF