#!/usr/bin/env sh # Show help if [ -z "$1" ] || [ "$1" = "--help" ] || [ "$1" = "-help" ]; then echo "Usage:" echo " $(basename "$0") ... <-option>... [-- ...]" echo "Or at the beginning of a C file:" echo " #!$(basename "$0") -s [...]" echo echo "To debug the program in GDB, just set CSCRIPT_GDB=1." exit 1 fi [ -n "$CSCRIPT_GDB" ] && ([ "$CSCRIPT_GDB" = "0" ] || [ "$CSCRIPT_GDB" = "false" ]) && unset CSCRIPT_GDB # Get file names, options and passed-through args basedir="." files="" opts="-Wall -pedantic" shebang_mode="" at_args="" args="" arg() { if [ -z "$shebang_mode" ] && [ -n "$at_args" ]; then args="$(printf "%s\n%s" "$args" "$1")" elif [ "$shebang_mode" = "next_is_file" ]; then basedir="$(dirname "$1")" files="$(printf "%s\n%s" "$files" "$(basename "$1")")" shebang_mode=1 elif [ -n "$shebang_mode" ]; then args="$(printf "%s\n%s" "$args" "$1")" else case "$1" in # Pass through following args --) at_args=1 ;; # Shebang mode (shebang args are not automatically separated; # the following arg is always the script filename) -s*) for a in $(eval "echo $(echo "$1" | cut -c3-)"); do arg "$a" done shebang_mode="next_is_file" ;; # Add option -*) opts="$(printf "%s\n%s" "$opts" "$1")" ;; # Add source file *) files="$(printf "%s\n%s" "$files" "$1")" ;; esac fi } for a in "$@"; do arg "$a" done [ -n "$CSCRIPT_GDB" ] && opts="$(printf "%s\n%s" "$opts" "-ggdb")" # Remove empty lines files="$(printf "%s" "$files" | grep '.')" opts="$(printf "%s" "$opts" | grep '.')" args="$(printf "%s" "$args" | grep '.')" cd "$basedir" # Check for invalid files [ -z "$files" ] && echo "No input files" && exit 1 while IFS= read -r l; do [ ! -f "$l" ] && [ ! -L "$l" ] && echo "Source file '$l' does not exist" && exit 1 done << EOF $files EOF # Compile and run C program cleanup() { printf "%s" "$files" | xargs -d'\n' sed "s@^//#!@#!@g" -i rm -f "$tmpfile" } tmpfile="$(mktemp -t "cscript.XXXXXXXXXX")" printf "%s" "$files" | xargs -d'\n' sed "s@^#!@//#!@g" -i trap 'cleanup; exit 130' INT if ! printf "%s\n%s" "$files" "$opts" | xargs -d'\n' cc -o "$tmpfile"; then cleanup exit 1 fi if [ -n "$CSCRIPT_GDB" ]; then printf "%s" "$args" | xargs -o -d'\n' gdb --args "$tmpfile" else printf "%s" "$args" | xargs -o -d'\n' "$tmpfile" fi trap - INT cleanup