Home | History | Annotate | Line # | Download | only in genassym
      1 #!/bin/sh -
      2 #	$NetBSD: genassym.sh,v 1.8 2014/01/06 22:43:15 christos 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="$(basename "${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 set -e
     41 
     42 while getopts cf i
     43 do
     44 	case "$i" in
     45 	c)
     46 		ccode=1
     47 		;;
     48 	f)
     49 		fcode=1
     50 		;;
     51 	esac
     52 done
     53 shift "$(($OPTIND - 1))"
     54 if [ $# -eq 0 ]; then
     55 	usage
     56 	exit 1
     57 fi
     58 
     59 # Deal with any leading environment settings..
     60 
     61 while [ -n "$1" ]
     62 do
     63 	case "$1" in
     64 	*=*)
     65 		eval export "$1"
     66 		shift
     67 		;;
     68 	*)
     69 		break
     70 		;;
     71 	esac
     72 done
     73 
     74 genassym_temp="$(mktemp -d "${TMPDIR-/tmp}/genassym.XXXXXX")"
     75 
     76 
     77 if [ ! -d $genassym_temp ]; then
     78 	echo "${progname}: unable to create temporary directory" >&2
     79 	exit 1
     80 fi
     81 trap "rm -rf $genassym_temp" 0 1 2 3 15
     82 
     83 $AWK '
     84 BEGIN {
     85 	printf("#if __GNUC__ >= 4\n");
     86 	printf("#define	offsetof(type, member) __builtin_offsetof(type, member)\n");
     87 	printf("#else\n");
     88 	printf("#define	offsetof(type, member) ((size_t)(&((type *)0)->member))\n");
     89 	printf("#endif\n");
     90 	defining = 0;
     91 	type = "long";
     92 	asmtype = "n";
     93 	asmprint = "";
     94 }
     95 
     96 {
     97 	doing_member = 0;
     98 }
     99 
    100 $0 ~ /^[ \t]*#.*/ || $0 ~ /^[ \t]*$/ {
    101 	# Just ignore comments and empty lines
    102 	next;
    103 }
    104 
    105 $0 ~ /^config[ \t]/ {
    106 	type = $2;
    107 	asmtype = $3;
    108 	asmprint = $4;
    109 	next;
    110 }
    111 
    112 /^include[ \t]/ {
    113 	if (defining != 0) {
    114 		defining = 0;
    115 		printf("}\n");
    116 	}
    117 	printf("#%s\n", $0);
    118 	next;
    119 }
    120 
    121 $0 ~ /^if[ \t]/ ||
    122 $0 ~ /^ifdef[ \t]/ ||
    123 $0 ~ /^ifndef[ \t]/ ||
    124 $0 ~ /^else/ ||
    125 $0 ~ /^elif[ \t]/ ||
    126 $0 ~ /^endif/ {
    127 	printf("#%s\n", $0);
    128 	next;
    129 }
    130 
    131 /^struct[ \t]/ {
    132 	structname = $2;
    133 	$0 = "define " structname "_SIZEOF sizeof(struct " structname ")";
    134 	# fall through
    135 }
    136 
    137 /^member[ \t]/ {
    138 	if (NF > 2)
    139 		$0 = "define " $2 " offsetof(struct " structname ", " $3 ")";
    140 	else
    141 		$0 = "define " $2 " offsetof(struct " structname ", " $2 ")";
    142 	doing_member = 1;
    143 	# fall through
    144 }
    145 
    146 /^export[ \t]/ {
    147 	$0 = "define " $2 " " $2;
    148 	# fall through
    149 }
    150 
    151 /^define[ \t]/ {
    152 	if (defining == 0) {
    153 		defining = 1;
    154 		printf("void f" FNR "(void);\n");
    155 		printf("void f" FNR "(void) {\n");
    156 		if (ccode)
    157 			call[FNR] = "f" FNR;
    158 		defining = 1;
    159 	}
    160 	value = $0
    161 	gsub("^define[ \t]+[A-Za-z_][A-Za-z_0-9]*[ \t]+", "", value)
    162 	if (ccode)
    163 		printf("printf(\"#define " $2 " %%ld\\n\", (%s)" value ");\n", type);
    164 	else if (fcode) {
    165 		if (doing_member)
    166 			printf("__asm(\"XYZZY : %s d# %%%s0 + ;\" : : \"%s\" (%s));\n", $2, asmprint, asmtype, value);
    167 		else
    168 			printf("__asm(\"XYZZY d# %%%s0 constant %s\" : : \"%s\" (%s));\n", asmprint, $2, asmtype, value);
    169 	} else
    170 		printf("__asm(\"XYZZY %s %%%s0\" : : \"%s\" (%s));\n", $2, asmprint, asmtype, value);
    171 	next;
    172 }
    173 
    174 /^quote[ \t]/ {
    175 	gsub("^quote[ \t]+", "");
    176 	print;
    177 	next;
    178 }
    179 
    180 {
    181 	printf("syntax error in line %d\n", FNR) >"/dev/stderr";
    182 	exit(1);
    183 }
    184 
    185 END {
    186 	if (defining != 0) {
    187 		defining = 0;
    188 		printf("}\n");
    189 	}
    190 	if (ccode) {
    191 		printf("int main(int argc, char **argv) {");
    192 		for (i in call)
    193 			printf(call[i] "();");
    194 		printf("return(0); }\n");
    195 	}
    196 }
    197 ' ccode="$ccode" fcode="$fcode" > "${genassym_temp}/assym.c" || exit 1
    198 
    199 if [ "$ccode" = 1 ]; then
    200 	"$@" "${genassym_temp}/assym.c" -o "${genassym_temp}/genassym" && \
    201 	    "${genassym_temp}/genassym"
    202 elif [ "$fcode" = 1 ]; then
    203 	# Kill all of the "#" and "$" modifiers; locore.s already
    204 	# prepends the correct "constant" modifier.
    205 	"$@" -S "${genassym_temp}/assym.c" -o - | sed -e 's/\$//g' | \
    206 	    sed -n 's/.*XYZZY//gp'
    207 else
    208 	# Kill all of the "#" and "$" modifiers; locore.s already
    209 	# prepends the correct "constant" modifier.
    210 	"$@" -S "${genassym_temp}/assym.c" -o - > \
    211 	    "${genassym_temp}/genassym.out" && \
    212 	    sed -e 's/#//g' -e 's/\$//g' < "${genassym_temp}/genassym.out" | \
    213 	    sed -n 's/.*XYZZY/#define/gp'
    214 fi
    215