ack/lang/b/distr/abc
2016-11-27 11:37:25 +01:00

96 lines
1.8 KiB
Bash
Executable file

#!/bin/sh
BDIR="$HOME/abc"
objs="$BDIR/brt.o $BDIR/lib.o"
BC="$BDIR/b"
# compile in.b [out.s]
compile() {
if [ "${1##*.}" != "b" ]; then
echo "Error: can only compile b files" >&2
exit 1
fi
cout=$2
[ "$cout" != "" ] || cout=${1%b}s
tmp1=`mktemp`; tmp2=`mktemp`
$BC $1 $tmp2 $tmp1
retval=$?
cat $tmp1 $tmp2 > $cout
rm $tmp1 $tmp2
[ $retval -eq 0 ] || rm $cout && return $retval
echo $cout
return $retval
}
# assemble in.{sb} [out.o]
assemble() {
atmp=""
ain=$1
aout=$2;
if [ "${1##*.}" = "b" ]; then
[ "$aout" != "" ] || aout=${ain%b}o
ain=`mktemp --suffix=.s`
compile $1 $ain >/dev/null || return 1
atmp="foo"
elif [ "${1##*.}" = "s" ]; then
[ "$aout" != "" ] || aout=${ain%s}o
else
echo "Error: can only compile b and s files" >&2
exit 1
fi
as --32 -g $ain -o $aout
[ "$atmp" != "" ] && rm $ain
echo $aout
}
out=""
action="link"
while getopts "o:Sc" o
do case "$o" in
o) out="$OPTARG";;
S) action=compile;;
c) action=assemble;;
esac
done
shift $(($OPTIND - 1))
# ignore -o option if more than one file given and not linking objs
if [ $# -gt 1 ]; then
if [ "$action" != "link" ]; then
out=""
fi
fi
[ $# -ne 1 ] && havelist=yes
tmpobjs=""
for i in $@; do
if [ "$action" != "link" ]; then
[ "$havelist" = "yes" ] && echo $i:
$action $i $out >/dev/null
[ $? -eq 0 ] || break=1
else
if [ "${i##*.}" = "o" ]; then
objs="$objs $i"
else
[ "$havelist" = "yes" ] && echo $i:
ltmp=`mktemp --suffix=.o`
tmpobjs="$tmpobjs $ltmp"
assemble $i $ltmp >/dev/null
[ $? -eq 0 ] || break=1
fi
fi
done
if [ $break ]; then
[ "$tmpobjs" = "" ] || rm $tmpobjs
echo "Error" >&2
exit 1
fi
if [ "$action" = "link" ]; then
if [ "$out" = "" ]; then
out="-o a.out"
else
out="-o $out"
fi
ld -m elf_i386 -T $BDIR/link.ld $out $objs $tmpobjs
rm $tmpobjs
fi