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