1 1.1 thorpej #!/bin/sh - 2 1.8 christos # $NetBSD: genassym.sh,v 1.8 2014/01/06 22:43:15 christos Exp $ 3 1.1 thorpej # 4 1.1 thorpej # Copyright (c) 1997 Matthias Pfaller. 5 1.1 thorpej # All rights reserved. 6 1.1 thorpej # 7 1.1 thorpej # Redistribution and use in source and binary forms, with or without 8 1.1 thorpej # modification, are permitted provided that the following conditions 9 1.1 thorpej # are met: 10 1.1 thorpej # 1. Redistributions of source code must retain the above copyright 11 1.1 thorpej # notice, this list of conditions and the following disclaimer. 12 1.1 thorpej # 2. Redistributions in binary form must reproduce the above copyright 13 1.1 thorpej # notice, this list of conditions and the following disclaimer in the 14 1.1 thorpej # documentation and/or other materials provided with the distribution. 15 1.1 thorpej # 16 1.1 thorpej # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 1.1 thorpej # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 1.1 thorpej # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 1.1 thorpej # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 1.1 thorpej # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 1.1 thorpej # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 1.1 thorpej # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 1.1 thorpej # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 1.1 thorpej # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 1.1 thorpej # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 1.1 thorpej # 27 1.1 thorpej 28 1.8 christos progname="$(basename "${0}")" 29 1.4 apb : ${AWK:=awk} 30 1.1 thorpej 31 1.1 thorpej ccode=0 # generate temporary C file, compile it, execute result 32 1.1 thorpej fcode=0 # generate Forth code 33 1.1 thorpej 34 1.1 thorpej usage() 35 1.1 thorpej { 36 1.1 thorpej 37 1.1 thorpej echo "usage: ${progname} [-c | -f] -- compiler command" >&2 38 1.1 thorpej } 39 1.1 thorpej 40 1.8 christos set -e 41 1.8 christos 42 1.6 dsl while getopts cf i 43 1.6 dsl do 44 1.1 thorpej case "$i" in 45 1.6 dsl c) 46 1.1 thorpej ccode=1 47 1.6 dsl ;; 48 1.6 dsl f) 49 1.1 thorpej fcode=1 50 1.6 dsl ;; 51 1.1 thorpej esac 52 1.1 thorpej done 53 1.8 christos shift "$(($OPTIND - 1))" 54 1.6 dsl if [ $# -eq 0 ]; then 55 1.6 dsl usage 56 1.6 dsl exit 1 57 1.6 dsl fi 58 1.1 thorpej 59 1.1 thorpej # Deal with any leading environment settings.. 60 1.1 thorpej 61 1.8 christos while [ -n "$1" ] 62 1.1 thorpej do 63 1.1 thorpej case "$1" in 64 1.1 thorpej *=*) 65 1.1 thorpej eval export "$1" 66 1.1 thorpej shift 67 1.1 thorpej ;; 68 1.1 thorpej *) 69 1.1 thorpej break 70 1.1 thorpej ;; 71 1.1 thorpej esac 72 1.1 thorpej done 73 1.1 thorpej 74 1.8 christos genassym_temp="$(mktemp -d "${TMPDIR-/tmp}/genassym.XXXXXX")" 75 1.8 christos 76 1.1 thorpej 77 1.8 christos if [ ! -d $genassym_temp ]; then 78 1.1 thorpej echo "${progname}: unable to create temporary directory" >&2 79 1.1 thorpej exit 1 80 1.1 thorpej fi 81 1.1 thorpej trap "rm -rf $genassym_temp" 0 1 2 3 15 82 1.1 thorpej 83 1.4 apb $AWK ' 84 1.1 thorpej BEGIN { 85 1.7 matt printf("#if __GNUC__ >= 4\n"); 86 1.7 matt printf("#define offsetof(type, member) __builtin_offsetof(type, member)\n"); 87 1.7 matt printf("#else\n"); 88 1.1 thorpej printf("#define offsetof(type, member) ((size_t)(&((type *)0)->member))\n"); 89 1.7 matt printf("#endif\n"); 90 1.1 thorpej defining = 0; 91 1.1 thorpej type = "long"; 92 1.1 thorpej asmtype = "n"; 93 1.1 thorpej asmprint = ""; 94 1.1 thorpej } 95 1.1 thorpej 96 1.1 thorpej { 97 1.1 thorpej doing_member = 0; 98 1.1 thorpej } 99 1.1 thorpej 100 1.1 thorpej $0 ~ /^[ \t]*#.*/ || $0 ~ /^[ \t]*$/ { 101 1.1 thorpej # Just ignore comments and empty lines 102 1.1 thorpej next; 103 1.1 thorpej } 104 1.1 thorpej 105 1.1 thorpej $0 ~ /^config[ \t]/ { 106 1.1 thorpej type = $2; 107 1.1 thorpej asmtype = $3; 108 1.1 thorpej asmprint = $4; 109 1.1 thorpej next; 110 1.1 thorpej } 111 1.1 thorpej 112 1.1 thorpej /^include[ \t]/ { 113 1.1 thorpej if (defining != 0) { 114 1.1 thorpej defining = 0; 115 1.1 thorpej printf("}\n"); 116 1.1 thorpej } 117 1.1 thorpej printf("#%s\n", $0); 118 1.1 thorpej next; 119 1.1 thorpej } 120 1.1 thorpej 121 1.1 thorpej $0 ~ /^if[ \t]/ || 122 1.1 thorpej $0 ~ /^ifdef[ \t]/ || 123 1.1 thorpej $0 ~ /^ifndef[ \t]/ || 124 1.1 thorpej $0 ~ /^else/ || 125 1.1 thorpej $0 ~ /^elif[ \t]/ || 126 1.1 thorpej $0 ~ /^endif/ { 127 1.1 thorpej printf("#%s\n", $0); 128 1.1 thorpej next; 129 1.1 thorpej } 130 1.1 thorpej 131 1.1 thorpej /^struct[ \t]/ { 132 1.1 thorpej structname = $2; 133 1.1 thorpej $0 = "define " structname "_SIZEOF sizeof(struct " structname ")"; 134 1.1 thorpej # fall through 135 1.1 thorpej } 136 1.1 thorpej 137 1.1 thorpej /^member[ \t]/ { 138 1.1 thorpej if (NF > 2) 139 1.1 thorpej $0 = "define " $2 " offsetof(struct " structname ", " $3 ")"; 140 1.1 thorpej else 141 1.1 thorpej $0 = "define " $2 " offsetof(struct " structname ", " $2 ")"; 142 1.1 thorpej doing_member = 1; 143 1.1 thorpej # fall through 144 1.1 thorpej } 145 1.1 thorpej 146 1.1 thorpej /^export[ \t]/ { 147 1.1 thorpej $0 = "define " $2 " " $2; 148 1.1 thorpej # fall through 149 1.1 thorpej } 150 1.1 thorpej 151 1.1 thorpej /^define[ \t]/ { 152 1.1 thorpej if (defining == 0) { 153 1.1 thorpej defining = 1; 154 1.1 thorpej printf("void f" FNR "(void);\n"); 155 1.3 matt printf("void f" FNR "(void) {\n"); 156 1.1 thorpej if (ccode) 157 1.1 thorpej call[FNR] = "f" FNR; 158 1.1 thorpej defining = 1; 159 1.1 thorpej } 160 1.1 thorpej value = $0 161 1.1 thorpej gsub("^define[ \t]+[A-Za-z_][A-Za-z_0-9]*[ \t]+", "", value) 162 1.1 thorpej if (ccode) 163 1.1 thorpej printf("printf(\"#define " $2 " %%ld\\n\", (%s)" value ");\n", type); 164 1.1 thorpej else if (fcode) { 165 1.1 thorpej if (doing_member) 166 1.2 itohy printf("__asm(\"XYZZY : %s d# %%%s0 + ;\" : : \"%s\" (%s));\n", $2, asmprint, asmtype, value); 167 1.1 thorpej else 168 1.1 thorpej printf("__asm(\"XYZZY d# %%%s0 constant %s\" : : \"%s\" (%s));\n", asmprint, $2, asmtype, value); 169 1.1 thorpej } else 170 1.1 thorpej printf("__asm(\"XYZZY %s %%%s0\" : : \"%s\" (%s));\n", $2, asmprint, asmtype, value); 171 1.1 thorpej next; 172 1.1 thorpej } 173 1.1 thorpej 174 1.1 thorpej /^quote[ \t]/ { 175 1.1 thorpej gsub("^quote[ \t]+", ""); 176 1.1 thorpej print; 177 1.1 thorpej next; 178 1.1 thorpej } 179 1.1 thorpej 180 1.1 thorpej { 181 1.1 thorpej printf("syntax error in line %d\n", FNR) >"/dev/stderr"; 182 1.1 thorpej exit(1); 183 1.1 thorpej } 184 1.1 thorpej 185 1.1 thorpej END { 186 1.1 thorpej if (defining != 0) { 187 1.1 thorpej defining = 0; 188 1.1 thorpej printf("}\n"); 189 1.1 thorpej } 190 1.1 thorpej if (ccode) { 191 1.1 thorpej printf("int main(int argc, char **argv) {"); 192 1.1 thorpej for (i in call) 193 1.1 thorpej printf(call[i] "();"); 194 1.1 thorpej printf("return(0); }\n"); 195 1.1 thorpej } 196 1.1 thorpej } 197 1.8 christos ' ccode="$ccode" fcode="$fcode" > "${genassym_temp}/assym.c" || exit 1 198 1.1 thorpej 199 1.8 christos if [ "$ccode" = 1 ]; then 200 1.8 christos "$@" "${genassym_temp}/assym.c" -o "${genassym_temp}/genassym" && \ 201 1.8 christos "${genassym_temp}/genassym" 202 1.8 christos elif [ "$fcode" = 1 ]; then 203 1.1 thorpej # Kill all of the "#" and "$" modifiers; locore.s already 204 1.1 thorpej # prepends the correct "constant" modifier. 205 1.8 christos "$@" -S "${genassym_temp}/assym.c" -o - | sed -e 's/\$//g' | \ 206 1.1 thorpej sed -n 's/.*XYZZY//gp' 207 1.1 thorpej else 208 1.1 thorpej # Kill all of the "#" and "$" modifiers; locore.s already 209 1.1 thorpej # prepends the correct "constant" modifier. 210 1.8 christos "$@" -S "${genassym_temp}/assym.c" -o - > \ 211 1.8 christos "${genassym_temp}/genassym.out" && \ 212 1.8 christos sed -e 's/#//g' -e 's/\$//g' < "${genassym_temp}/genassym.out" | \ 213 1.1 thorpej sed -n 's/.*XYZZY/#define/gp' 214 1.1 thorpej fi 215