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