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