summaryrefslogtreecommitdiff
path: root/bcc/idcc
diff options
context:
space:
mode:
Diffstat (limited to 'bcc/idcc')
-rwxr-xr-xbcc/idcc311
1 files changed, 311 insertions, 0 deletions
diff --git a/bcc/idcc b/bcc/idcc
new file mode 100755
index 0000000..a04afc8
--- /dev/null
+++ b/bcc/idcc
@@ -0,0 +1,311 @@
+#!/bin/ash
+#
+# This is a shell version of the bcc compiler driver. It's a little slower
+# than a C version but overall seems to be a lot cleaner, perhaps a C version
+# based on this might be a good idea ...
+#
+# The compiler works on a 'modal' basis certain flags given to it put the
+# compiler into specific modes, it can only be in one mode for a run.
+#
+# The mode defines the basic passes and specific options that are available
+#
+# To define a mode see the functions 'run_0' and 'run_3' for examples. The
+# variable assignments just above the definitions enable the functions.
+#
+# This script is specifically designed so the there is as little interaction
+# between the modes as is possible.
+#
+# It's run using ash because this appears to be _much_ faster than bash, it's
+# also reasonable with ksh.
+# (On other interpreters I think perl would be too big, but awk might work...)
+#
+
+TMPFIL="/tmp/cc$$"
+trap "rm -f $TMPFIL.* ; exit 1" 1 2 3 15
+TMPCNT=0
+
+FILES=
+OPTS=
+RESEXTN=
+OPTIM=no
+VERBOSE=no
+MULTISRC=no
+
+LDOPTS=
+DESTDEF=no
+LDDEST=a.out
+DEFMODE=0
+
+ccmode=
+LIBPATH="/lib:/usr/lib:/usr/bin"
+
+main() {
+ scanargs "$@"
+
+ PATH="$LIBPATH:$PATH"
+ [ "$EXEC_PREFIX" != "" ] && PATH="$EXEC_PREFIX:$PATH"
+
+ rv=0
+ LDFILES=
+ [ "$MULTISRC" = yes -o "$RESEXTN" = "" ] && DESTDEF=no
+
+ for FILE in $FILES
+ do
+ case "$FILE" in
+ *.c ) PASS=cpp ; BASE="`basename $FILE .c`" ;;
+ *.s ) PASS=as ; BASE="`basename $FILE .s`" ;;
+ * ) PASS=lnk ;;
+ esac
+
+ NAME="`basename $FILE`"
+ DEST="`dirname $FILE`/"
+ [ "$DEST" = "./" ] && DEST=
+ DEST="$DEST$BASE.$RESEXTN"
+ [ "$DESTDEF" = yes ] && DEST="$LDDEST"
+
+ STEMP=0 INTEMP=0
+ [ "$PASS" = "cpp" ] && { compile $FILE || rv=$? ; }
+ [ "$PASS" = "as" ] && { assem $FILE || rv=$? ; }
+ if [ "$PASS" = "lnk" ]
+ then
+ LDFILES="$LDFILES $FILE"
+ else
+ # If there's a fail can't link - still assembling to temps tho.
+ [ "$RESEXTN" = "" ] && RESEXTN=O
+ fi
+ [ "$STEMP" = 1 ] && rm -f "$SFILE"
+ [ "$INTEMP" = 1 ] && RMFILES="$RMFILES $FILE"
+ done
+
+ [ "$RESEXTN" != "" ] && exit $rv
+
+ [ "$VERBOSE" = yes ] &&
+ echo "$LD $SYSLIB $LDOPTS $LDFLAGS -o $LDDEST $CRT0 $LDFILES $LIBS"
+
+ $LD $SYSLIB $LDOPTS $LDFLAGS -o $LDDEST $CRT0 $LDFILES $LIBS
+ rv=$?
+ [ "$RMFILES" != "" ] && rm -f $RMFILES
+ exit "$rv"
+}
+
+scanargs() {
+ WILDOPT=no
+
+ while [ "$#" -gt 0 ]
+ do
+ case "$1" in
+ -[DU]* ) CPPDEFS="$CPPDEFS $1" ;;
+ -B?* ) PATH="`echo '.$1:$PATH' | sed 's/...//'`" ;;
+ -I?* ) CPPFLAGS="$CPPFLAGS $1" ;;
+ -L?* ) LDOPTS="$LDOPTS $1" ;;
+ -o ) LDDEST="$2"; DESTDEF=yes ; shift ;;
+ -b ) . /usr/lib/idcc/opts_$2 || exit 1; shift ;;
+ -E ) RESEXTN=i ;;
+ -S ) RESEXTN=s ;;
+ -c ) RESEXTN=o ;;
+ -O ) OPTIM=yes ;;
+ -v ) VERBOSE=yes ;;
+ -l?* ) FILES="$FILES $1" ; MULTISRC=yes ;;
+ -* ) OPTS="$OPTS `echo .$1 | sed 's/..//'`" ;;
+ * ) [ "$FILES" != "" ] && MULTISRC=yes ; FILES="$FILES $1" ;;
+ esac
+ shift
+ done
+
+ while [ "$OPTS" != "" -o "$DEFMODE" != "" ]
+ do
+ # So they can try again ... with DEFMODE if needed
+ MOPTS="$OPTS"
+ OPTS=
+
+ for opt in $MOPTS
+ do
+ # Option can be defined only for specific mode so if we haven't seen
+ # the mode yet save the opt. If we have check for conflicts too.
+ [ "$ccmode" = "" -a "$DEFMODE" != "" ] && {
+ eval "[ \"\$opt_$opt\" = yes ]" || { OPTS="$OPTS $opt" ; opt= ; }
+ }
+ [ "$opt" != "" ] && {
+ [ "$ccmode" = "" ] || {
+ eval "[ \"\$mode_$opt\" = yes ]" && {
+ echo Option "-$opt incompatible with -$ccmode" 1>&2
+ exit 2
+ }
+ }
+
+ eval "[ \"\$opt_$opt\" = yes ]" || {
+ { eval "[ \"$WILDOPT\" = yes ]" && wild_opt "-$opt" ; } || {
+ echo Option '-'$opt unknown for this mode 1>&2
+ exit 3
+ }
+ }
+
+ eval "[ \"\$opt_$opt\" = yes ]" && run_$opt
+ eval "[ \"\$mode_$opt\" = yes ]" && ccmode="$opt"
+ }
+ done
+ [ "$ccmode" = "" -a "$DEFMODE" != "" ] && OPTS="$DEFMODE $OPTS"
+ DEFMODE=
+ done
+}
+
+compile() {
+ [ -r "$FILE" ] || { echo "Cannot open $FILE" 1>&2 ; return 1 ; }
+
+ [ "$RESEXTN" = "i" ] && {
+ cpp_only $FILE
+ return
+ }
+
+ # Loop for the pass list
+ # The CCX variables _are_ expanded again.
+
+ ret=1
+ for pass in $PASSLIST
+ do
+ for extn in '' pre post inf res opt
+ do eval "CCX$extn=\"\$CC$pass$extn\""
+ done
+
+ [ "$CCX" = "" ] && continue;
+ [ "$OPTIM" = "" -a "$CCXopt" = yes ] && continue;
+
+ shuffel "$RESEXTN" $CCXres
+ [ "$VERBOSE" = yes ] &&
+ eval "echo \"$CCX $CCXpre $SFILE $CCXinf $FILE $CCXpost\""
+ eval "$CCX $CCXpre $SFILE $CCXinf $FILE $CCXpost" || return 1
+ ret=0
+ done
+ [ "$ret" = 1 ] && { echo 'CC configuration error' 1>&2 ; return $ret ; }
+
+ [ "$RESEXTN" != "s" ] && PASS=as
+ return 0
+}
+
+assem() {
+ [ -r "$FILE" ] || { echo "Cannot open $FILE" 1>&2 ; return 1 ; }
+
+ shuffel "$RESEXTN" o
+
+ n=
+ [ "$ASNAME" != "" ] && n="$ASNAME$NAME"
+
+ [ "$VERBOSE" = yes ] && echo "$AS $ASFLAGS $n $SFILE -o $FILE"
+ $AS $ASFLAGS $n $SFILE -o $FILE || return
+
+ [ "$RESEXTN" != "o" ] && PASS=lnk
+ return 0
+}
+
+if [ "2" = "$[1+1]" ] ; then inc_tmpcnt() { TMPCNT="$[$TMPCNT+1]" ; }
+else inc_tmpcnt() { TMPCNT="`expr $TMPCNT + 1`" ; }
+fi
+
+shuffel() {
+ [ "$STEMP" = 1 ] && rm -f "$SFILE"
+
+ SFILE="$FILE"
+ STEMP="$INTEMP"
+
+ if [ "$1" = "$2" ]
+ then
+ FILE="$DEST"
+ INTEMP=0
+ else
+ inc_tmpcnt
+ FILE="$TMPFIL.$TMPCNT.$2"
+ INTEMP=1
+ fi
+}
+
+mode_0=yes opt_0=yes
+run_0()
+{
+ SYSINC="-I/usr/bcc/include"
+ SYSLIB="-L/usr/bcc/lib/bcc/i86/"
+ LIBPATH="/usr/bcc/lib/bcc"
+ CRT0="-C0"
+ LIBS="-lc"
+ CGEN=
+ DEFS=
+
+ CPP="cpp"
+
+ PASSLIST=2
+ CC2="bcc-cc1" CC2pre='$SYSINC $DEFS $CPPFLAGS'
+ CC2inf='-o' CC2post='-0 $CGEN $CPPDEFS' CC2res=s
+ AS="as86" ASFLAGS='-u -w -0' ASNAME='-n '
+ LD="ld86" LDFLAGS='-i -0'
+
+ opt_ansi=yes
+ run_ansi()
+ {
+ PASSLIST="0 1 2"
+ CC0="bcc-cc1" CC0pre='$SYSINC $DEFS $CPPFLAGS' CC0inf='-o'
+ CC0post='-0 -E -D__STDC__=0 $CPPDEFS' CC0res=i
+ CC1="unproto" CC1pre='' CC1inf='' CC1post='' CC1res=k
+ CC2="bcc-cc1" CC2pre='$CGEN' CC2inf='-o' CC2post='-0' CC2res=s
+ }
+ opt_I=yes; run_I() { SYSINC= ; }
+ opt_L=yes; run_L() { SYSLIB= ; }
+ opt_s=yes; run_s() { LDFLAGS="$LDFLAGS -s" ; }
+ opt_Mf=yes; run_Mf() { LIBS=-lc_f ; CGEN='-f -c' ;}
+ opt_Md=yes; run_Md() { LIBS=-ldos ; DEFS='-D__MSDOS__' LDFLAGS='-i -0 -d' ;}
+
+ WILDOPT=yes
+ wild_opt()
+ {
+ case "$1" in
+ -O* ) OPTIM=yes ; OPTFLG="$OPTFLG $1" ;;
+ * ) return 1 ;;
+ # For normal CC operation unknowns go to the linker. ie:
+ # * ) LDFLAGS="$LDFLAGS $1" ; return 0 ;;
+ esac
+ return 0
+ }
+}
+
+mode_3=yes opt_3=yes
+run_3()
+{
+ SYSINC="-I/usr/bcc/include"
+ SYSLIB="-L/usr/bcc/lib/bcc/i386/"
+ LIBPATH="/usr/bcc/lib/bcc"
+ CRT0="-C0"
+ LIBS="-lc"
+ CGEN=
+ DEFS=
+
+ CPP="cpp"
+
+ PASSLIST=2
+ CC2="bcc-cc3" CC2pre='$SYSINC $DEFS $CPPFLAGS'
+ CC2inf='-o' CC2post='-3 $CGEN $CPPDEFS' CC2res=s
+ AS="as86" ASFLAGS='-u -w -3' ASNAME='-n '
+ LD="ld86" LDFLAGS='-i -3'
+
+ opt_ansi=yes
+ run_ansi()
+ {
+ PASSLIST="0 1 2"
+ CC0="bcc-cc3" CC0pre='$SYSINC $DEFS $CPPFLAGS' CC0inf='-o'
+ CC0post='-3 -E -D__STDC__=0 $CPPDEFS' CC0res=i
+ CC1="unproto" CC1pre='' CC1inf='' CC1post='' CC1res=k
+ CC2="bcc-cc1" CC2pre='$CGEN' CC2inf='-o' CC2post='-3' CC2res=s
+ }
+ opt_I=yes; run_I() { SYSINC= ; }
+ opt_L=yes; run_L() { SYSLIB= ; }
+ opt_s=yes; run_s() { LDFLAGS="$LDFLAGS -s" ; }
+
+ WILDOPT=yes
+ wild_opt()
+ {
+ case "$1" in
+ -O* ) OPTIM=yes ; OPTFLG="$OPTFLG $1" ;;
+ * ) return 1 ;;
+ esac
+ return 0
+ }
+}
+
+main "$@"