#!/usr/bin/env bash
# usage: transform.sh [--stdout] [--stderr] [--file] transform1 transform2 ... -- [goblint args] file.c
# runs goblint with the given transformations active and outputs the transformed file to stdout
# - unless --stdout/--stderr is passed, supress those streams
# - if --file is passed, output to a temporary file and print its path to stdout

set -eu -o pipefail

function main() {
  local -a trans_args=()
  local stdout=0 stderr=0 file=0 output_file

  while [ $# -gt 0 ]; local arg="$1"; shift; do
    case $arg in
      --) break ;;
      --stdout) stdout=1 ;;
      --stderr) stderr=1 ;;
      --file) file=1 ;;
      *) trans_args+=( "--set" "trans.activated[+]" "$arg" ) ;;
    esac
  done

  if (( file == 1 && ( stdout == 1 || stderr == 1 ) )); then
    printf '%s\n' '--file and --stdout/--stderr are mutually exclusive'; exit 1; fi

  output_file="$(mktemp ./transformed.c.XXXXXX)"

  # save stdout to FD 3 (automatic FD allocation not availble on Macintosh's bash)
  exec 3>&1
  if (( stdout != 1 )); then exec 1>/dev/null; fi
  if (( stderr != 1 )); then exec 2>/dev/null; fi

  # turn off backtraces
  OCAMLRUNPARAM="${OCAMLRUNPARAM:-},b=0" \
    goblint "${trans_args[@]}" --set trans.output "$output_file" "$@" || result=$?

  # remove the 'Generated by CIL v. X.X.X' header, use -i'.tmp' for Macintosh systems
  sed -i'.tmp' '1,3d' "$output_file"
  if [ $file = 0 ]; then
    cat "$output_file" 1>&3
    rm "$output_file"
  else
    printf '%s\n' "$output_file" 1>&3
  fi

  return "${result-0}"
}

main "$@"
