1# $OpenBSD: genassym.sh,v 1.6 2001/09/16 14:26:35 miod Exp $ 2# $NetBSD: genassym.sh,v 1.9 1998/04/25 19:48:27 matthias Exp $ 3 4# 5# Copyright (c) 1997 Matthias Pfaller. 6# All rights reserved. 7# 8# Redistribution and use in source and binary forms, with or without 9# modification, are permitted provided that the following conditions 10# are met: 11# 1. Redistributions of source code must retain the above copyright 12# notice, this list of conditions and the following disclaimer. 13# 2. Redistributions in binary form must reproduce the above copyright 14# notice, this list of conditions and the following disclaimer in the 15# documentation and/or other materials provided with the distribution. 16# 3. All advertising materials mentioning features or use of this software 17# must display the following acknowledgement: 18# This product includes software developed by Matthias Pfaller. 19# 4. The name of the author may not be used to endorse or promote products 20# derived from this software without specific prior written permission 21# 22# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32# 33 34# If first argument is -c, create a temporary C file, 35# compile it and execute the result. 36 37awk=${AWK:-awk} 38 39if [ $1 = '-c' ] ; then 40 shift 41 ccode=1 42else 43 ccode=0 44fi 45 46trap "rm -f /tmp/$$.c /tmp/genassym.$$" 0 1 2 3 15 47 48$awk ' 49BEGIN { 50 printf("#ifndef _KERNEL\n#define _KERNEL\n#endif\n"); 51 printf("#define offsetof(type, member) ((size_t)(&((type *)0)->member))\n"); 52 defining = 0; 53 type = "long"; 54 asmtype = "n"; 55 asmprint = ""; 56} 57 58$0 ~ /^[ \t]*#.*/ || $0 ~ /^[ \t]*$/ { 59 # Just ignore comments and empty lines 60 next; 61} 62 63$0 ~ /^config[ \t]/ { 64 type = $2; 65 asmtype = $3; 66 asmprint = $4; 67 next; 68} 69 70/^include[ \t]/ { 71 if (defining != 0) { 72 defining = 0; 73 printf("}\n"); 74 } 75 if (includes[$2] == 0) { 76 printf("#%s\n", $0); 77 includes[$2] = 1; 78 } 79 next; 80} 81 82$0 ~ /^if[ \t]/ || 83$0 ~ /^ifdef[ \t]/ || 84$0 ~ /^ifndef[ \t]/ || 85$0 ~ /^else/ || 86$0 ~ /^elif[ \t]/ || 87$0 ~ /^endif/ { 88 printf("#%s\n", $0); 89 next; 90} 91 92/^struct[ \t]/ { 93 structname = $2; 94 prefixname = toupper($3); 95 if (struct[structname] == 1) 96 next; 97 else { 98 struct[structname] = 1; 99 $0 = "define " toupper(structname) "_SIZEOF sizeof(struct " structname ")"; 100 } 101 # fall through 102} 103 104/^member[ \t]/ { 105 if (NF > 2) 106 $0 = "define " prefixname toupper($2) " offsetof(struct " structname ", " $3 ")"; 107 else 108 $0 = "define " prefixname toupper($2) " offsetof(struct " structname ", " $2 ")"; 109 # fall through 110} 111 112/^export[ \t]/ { 113 $0 = "define " $2 " " $2; 114 # fall through 115} 116 117/^define[ \t]/ { 118 if (defining == 0) { 119 defining = 1; 120 printf("void f" FNR "(void);\n"); 121 printf("void f" FNR "() {\n"); 122 if (ccode) 123 call[FNR] = "f" FNR; 124 defining = 1; 125 } 126 value = $0 127 gsub("^define[ \t]+[A-Za-z_][A-Za-z_0-9]*[ \t]+", "", value) 128 if (ccode) 129 printf("printf(\"#define " $2 " %%ld\\n\", (%s)" value ");\n", type); 130 else 131 printf("__asm(\"XYZZY %s %%%s0\" : : \"%s\" (%s));\n", $2, asmprint, asmtype, value); 132 next; 133} 134 135/^quote[ \t]/ { 136 gsub("^quote[ \t]+", ""); 137 print; 138 next; 139} 140 141{ 142 printf("syntax error in line %d\n", FNR) >"/dev/stderr"; 143 exit(1); 144} 145 146END { 147 if (defining != 0) { 148 defining = 0; 149 printf("}\n"); 150 } 151 if (ccode) { 152 printf("int main(int argc, char **argv) {"); 153 for (i in call) 154 printf(call[i] "();"); 155 printf("return(0); }\n"); 156 } 157} 158' ccode=$ccode > /tmp/$$.c || exit 1 159 160if [ $ccode = 1 ] ; then 161 "$@" /tmp/$$.c -o /tmp/genassym.$$ && /tmp/genassym.$$ 162else 163 # Kill all of the "#" and "$" modifiers; locore.s already 164 # prepends the correct "constant" modifier. 165 "$@" -S /tmp/$$.c -o -| sed -e 's/#//g' -e 's/\$//g' | \ 166 sed -n 's/.*XYZZY/#define/gp' 167fi 168