xref: /netbsd-src/usr.bin/genassym/genassym.sh (revision 5eb5e1c36d78b4049251269d50b617a5ef205adc)
15ecc953bSthorpej#!/bin/sh -
2*5eb5e1c3Schristos#	$NetBSD: genassym.sh,v 1.8 2014/01/06 22:43:15 christos Exp $
35ecc953bSthorpej#
45ecc953bSthorpej# Copyright (c) 1997 Matthias Pfaller.
55ecc953bSthorpej# All rights reserved.
65ecc953bSthorpej#
75ecc953bSthorpej# Redistribution and use in source and binary forms, with or without
85ecc953bSthorpej# modification, are permitted provided that the following conditions
95ecc953bSthorpej# are met:
105ecc953bSthorpej# 1. Redistributions of source code must retain the above copyright
115ecc953bSthorpej#    notice, this list of conditions and the following disclaimer.
125ecc953bSthorpej# 2. Redistributions in binary form must reproduce the above copyright
135ecc953bSthorpej#    notice, this list of conditions and the following disclaimer in the
145ecc953bSthorpej#    documentation and/or other materials provided with the distribution.
155ecc953bSthorpej#
165ecc953bSthorpej# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
175ecc953bSthorpej# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
185ecc953bSthorpej# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
195ecc953bSthorpej# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
205ecc953bSthorpej# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
215ecc953bSthorpej# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
225ecc953bSthorpej# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
235ecc953bSthorpej# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
245ecc953bSthorpej# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
255ecc953bSthorpej# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
265ecc953bSthorpej#
275ecc953bSthorpej
28*5eb5e1c3Schristosprogname="$(basename "${0}")"
29cd5c0f94Sapb: ${AWK:=awk}
305ecc953bSthorpej
315ecc953bSthorpejccode=0		# generate temporary C file, compile it, execute result
325ecc953bSthorpejfcode=0		# generate Forth code
335ecc953bSthorpej
345ecc953bSthorpejusage()
355ecc953bSthorpej{
365ecc953bSthorpej
375ecc953bSthorpej	echo "usage: ${progname} [-c | -f] -- compiler command" >&2
385ecc953bSthorpej}
395ecc953bSthorpej
40*5eb5e1c3Schristosset -e
41*5eb5e1c3Schristos
42e2fd1f1dSdslwhile getopts cf i
43e2fd1f1dSdsldo
445ecc953bSthorpej	case "$i" in
45e2fd1f1dSdsl	c)
465ecc953bSthorpej		ccode=1
47e2fd1f1dSdsl		;;
48e2fd1f1dSdsl	f)
495ecc953bSthorpej		fcode=1
50e2fd1f1dSdsl		;;
515ecc953bSthorpej	esac
525ecc953bSthorpejdone
53*5eb5e1c3Schristosshift "$(($OPTIND - 1))"
54e2fd1f1dSdslif [ $# -eq 0 ]; then
55e2fd1f1dSdsl	usage
56e2fd1f1dSdsl	exit 1
57e2fd1f1dSdslfi
585ecc953bSthorpej
595ecc953bSthorpej# Deal with any leading environment settings..
605ecc953bSthorpej
61*5eb5e1c3Schristoswhile [ -n "$1" ]
625ecc953bSthorpejdo
635ecc953bSthorpej	case "$1" in
645ecc953bSthorpej	*=*)
655ecc953bSthorpej		eval export "$1"
665ecc953bSthorpej		shift
675ecc953bSthorpej		;;
685ecc953bSthorpej	*)
695ecc953bSthorpej		break
705ecc953bSthorpej		;;
715ecc953bSthorpej	esac
725ecc953bSthorpejdone
735ecc953bSthorpej
74*5eb5e1c3Schristosgenassym_temp="$(mktemp -d "${TMPDIR-/tmp}/genassym.XXXXXX")"
755ecc953bSthorpej
76*5eb5e1c3Schristos
77*5eb5e1c3Schristosif [ ! -d $genassym_temp ]; then
785ecc953bSthorpej	echo "${progname}: unable to create temporary directory" >&2
795ecc953bSthorpej	exit 1
805ecc953bSthorpejfi
815ecc953bSthorpejtrap "rm -rf $genassym_temp" 0 1 2 3 15
825ecc953bSthorpej
83cd5c0f94Sapb$AWK '
845ecc953bSthorpejBEGIN {
85c2812102Smatt	printf("#if __GNUC__ >= 4\n");
86c2812102Smatt	printf("#define	offsetof(type, member) __builtin_offsetof(type, member)\n");
87c2812102Smatt	printf("#else\n");
885ecc953bSthorpej	printf("#define	offsetof(type, member) ((size_t)(&((type *)0)->member))\n");
89c2812102Smatt	printf("#endif\n");
905ecc953bSthorpej	defining = 0;
915ecc953bSthorpej	type = "long";
925ecc953bSthorpej	asmtype = "n";
935ecc953bSthorpej	asmprint = "";
945ecc953bSthorpej}
955ecc953bSthorpej
965ecc953bSthorpej{
975ecc953bSthorpej	doing_member = 0;
985ecc953bSthorpej}
995ecc953bSthorpej
1005ecc953bSthorpej$0 ~ /^[ \t]*#.*/ || $0 ~ /^[ \t]*$/ {
1015ecc953bSthorpej	# Just ignore comments and empty lines
1025ecc953bSthorpej	next;
1035ecc953bSthorpej}
1045ecc953bSthorpej
1055ecc953bSthorpej$0 ~ /^config[ \t]/ {
1065ecc953bSthorpej	type = $2;
1075ecc953bSthorpej	asmtype = $3;
1085ecc953bSthorpej	asmprint = $4;
1095ecc953bSthorpej	next;
1105ecc953bSthorpej}
1115ecc953bSthorpej
1125ecc953bSthorpej/^include[ \t]/ {
1135ecc953bSthorpej	if (defining != 0) {
1145ecc953bSthorpej		defining = 0;
1155ecc953bSthorpej		printf("}\n");
1165ecc953bSthorpej	}
1175ecc953bSthorpej	printf("#%s\n", $0);
1185ecc953bSthorpej	next;
1195ecc953bSthorpej}
1205ecc953bSthorpej
1215ecc953bSthorpej$0 ~ /^if[ \t]/ ||
1225ecc953bSthorpej$0 ~ /^ifdef[ \t]/ ||
1235ecc953bSthorpej$0 ~ /^ifndef[ \t]/ ||
1245ecc953bSthorpej$0 ~ /^else/ ||
1255ecc953bSthorpej$0 ~ /^elif[ \t]/ ||
1265ecc953bSthorpej$0 ~ /^endif/ {
1275ecc953bSthorpej	printf("#%s\n", $0);
1285ecc953bSthorpej	next;
1295ecc953bSthorpej}
1305ecc953bSthorpej
1315ecc953bSthorpej/^struct[ \t]/ {
1325ecc953bSthorpej	structname = $2;
1335ecc953bSthorpej	$0 = "define " structname "_SIZEOF sizeof(struct " structname ")";
1345ecc953bSthorpej	# fall through
1355ecc953bSthorpej}
1365ecc953bSthorpej
1375ecc953bSthorpej/^member[ \t]/ {
1385ecc953bSthorpej	if (NF > 2)
1395ecc953bSthorpej		$0 = "define " $2 " offsetof(struct " structname ", " $3 ")";
1405ecc953bSthorpej	else
1415ecc953bSthorpej		$0 = "define " $2 " offsetof(struct " structname ", " $2 ")";
1425ecc953bSthorpej	doing_member = 1;
1435ecc953bSthorpej	# fall through
1445ecc953bSthorpej}
1455ecc953bSthorpej
1465ecc953bSthorpej/^export[ \t]/ {
1475ecc953bSthorpej	$0 = "define " $2 " " $2;
1485ecc953bSthorpej	# fall through
1495ecc953bSthorpej}
1505ecc953bSthorpej
1515ecc953bSthorpej/^define[ \t]/ {
1525ecc953bSthorpej	if (defining == 0) {
1535ecc953bSthorpej		defining = 1;
1545ecc953bSthorpej		printf("void f" FNR "(void);\n");
1550c07a5e9Smatt		printf("void f" FNR "(void) {\n");
1565ecc953bSthorpej		if (ccode)
1575ecc953bSthorpej			call[FNR] = "f" FNR;
1585ecc953bSthorpej		defining = 1;
1595ecc953bSthorpej	}
1605ecc953bSthorpej	value = $0
1615ecc953bSthorpej	gsub("^define[ \t]+[A-Za-z_][A-Za-z_0-9]*[ \t]+", "", value)
1625ecc953bSthorpej	if (ccode)
1635ecc953bSthorpej		printf("printf(\"#define " $2 " %%ld\\n\", (%s)" value ");\n", type);
1645ecc953bSthorpej	else if (fcode) {
1655ecc953bSthorpej		if (doing_member)
1663c46d522Sitohy			printf("__asm(\"XYZZY : %s d# %%%s0 + ;\" : : \"%s\" (%s));\n", $2, asmprint, asmtype, value);
1675ecc953bSthorpej		else
1685ecc953bSthorpej			printf("__asm(\"XYZZY d# %%%s0 constant %s\" : : \"%s\" (%s));\n", asmprint, $2, asmtype, value);
1695ecc953bSthorpej	} else
1705ecc953bSthorpej		printf("__asm(\"XYZZY %s %%%s0\" : : \"%s\" (%s));\n", $2, asmprint, asmtype, value);
1715ecc953bSthorpej	next;
1725ecc953bSthorpej}
1735ecc953bSthorpej
1745ecc953bSthorpej/^quote[ \t]/ {
1755ecc953bSthorpej	gsub("^quote[ \t]+", "");
1765ecc953bSthorpej	print;
1775ecc953bSthorpej	next;
1785ecc953bSthorpej}
1795ecc953bSthorpej
1805ecc953bSthorpej{
1815ecc953bSthorpej	printf("syntax error in line %d\n", FNR) >"/dev/stderr";
1825ecc953bSthorpej	exit(1);
1835ecc953bSthorpej}
1845ecc953bSthorpej
1855ecc953bSthorpejEND {
1865ecc953bSthorpej	if (defining != 0) {
1875ecc953bSthorpej		defining = 0;
1885ecc953bSthorpej		printf("}\n");
1895ecc953bSthorpej	}
1905ecc953bSthorpej	if (ccode) {
1915ecc953bSthorpej		printf("int main(int argc, char **argv) {");
1925ecc953bSthorpej		for (i in call)
1935ecc953bSthorpej			printf(call[i] "();");
1945ecc953bSthorpej		printf("return(0); }\n");
1955ecc953bSthorpej	}
1965ecc953bSthorpej}
197*5eb5e1c3Schristos' ccode="$ccode" fcode="$fcode" > "${genassym_temp}/assym.c" || exit 1
1985ecc953bSthorpej
199*5eb5e1c3Schristosif [ "$ccode" = 1 ]; then
200*5eb5e1c3Schristos	"$@" "${genassym_temp}/assym.c" -o "${genassym_temp}/genassym" && \
201*5eb5e1c3Schristos	    "${genassym_temp}/genassym"
202*5eb5e1c3Schristoselif [ "$fcode" = 1 ]; then
2035ecc953bSthorpej	# Kill all of the "#" and "$" modifiers; locore.s already
2045ecc953bSthorpej	# prepends the correct "constant" modifier.
205*5eb5e1c3Schristos	"$@" -S "${genassym_temp}/assym.c" -o - | sed -e 's/\$//g' | \
2065ecc953bSthorpej	    sed -n 's/.*XYZZY//gp'
2075ecc953bSthorpejelse
2085ecc953bSthorpej	# Kill all of the "#" and "$" modifiers; locore.s already
2095ecc953bSthorpej	# prepends the correct "constant" modifier.
210*5eb5e1c3Schristos	"$@" -S "${genassym_temp}/assym.c" -o - > \
211*5eb5e1c3Schristos	    "${genassym_temp}/genassym.out" && \
212*5eb5e1c3Schristos	    sed -e 's/#//g' -e 's/\$//g' < "${genassym_temp}/genassym.out" | \
2135ecc953bSthorpej	    sed -n 's/.*XYZZY/#define/gp'
2145ecc953bSthorpejfi
215