#!/usr/bin/env bash

# Does checks on C-language files in homework submissions (generates .i, .s, .o and executable using gcc).
# Run from hwsubmit/core directory with $1 being the homework number
# and $2 the basename for the .c file, for example "cchecks 1 hello"


#### NEED TO EDIT TO SHOW MISSING FILES AS WELL AS DIFFs

hwno=$1
base=$2

for stud in *; do
  pushd $stud/.graded/$hwno
  cp /dev/null checkdiffs
  if [[ -e $base.c ]]; then
    basetype="`file $base.c`"
    if [[ ! ("$basetype" =~ "ASCII") || ("$basetype" =~ "assembler") ]]; then
      echo "Unexpected type: $basetype" >> checkdiffs
    fi
    gcc -E -o $base-check.i $base.c >&$base-preprocess.errors
    gcc -S -o $base-check.s $base-check.i >&$base-compile.errors
    gcc -S -m32 -o $base-check.s32 $base-check.i >&$base-m32compile.errors
    gcc -c -o $base-check.o $base-check.s >&$base-assemble.errors
    gcc -o $base-check $base-check.o >&$base-link.errors
    ./$base-check > $base-check.out
  else
    echo "No $base.c" >> checkdiffs
  fi
  if [[ -e $base.i ]]; then
    basetype="`file $base.i`"
    if [[ ! ("$basetype" =~ "ASCII") || ("$basetype" =~ "assembler") ]]; then
      echo "Unexpected type: $basetype" >> checkdiffs
    fi
    if [[ -e $base-check.i ]]; then
      diff -q $base-check.i $base.i >> checkdiffs
    else
      gcc -S -o $base-check.s $base.i >&$base-compile.errors
      gcc -S -m32 -o $base-check.s32 $base.i >&$base-m32compile.errors
    fi
  else
    echo "No $base.i" >> checkdiffs
  fi
  if [[ -e $base.s ]]; then
    basetype="`file $base.s`"
    if [[ ! ("$basetype" =~ "assembler") ]]; then
      echo "Unexpected type: $basetype" >> checkdiffs
    fi
    if [[ -e $base-check.s ]]; then
      diff -q $base-check.s $base.s >> checkdiffs
    else
      gcc -c -o $base-check.o $base.s >&$base-assemble.errors
    fi
  else
    echo "No $base.s" >> checkdiffs
  fi
  if [[ -e $base.o ]]; then
    basetype="`file $base.o`"
    if [[ ! ("$basetype" =~ "relocatable") ]]; then
      echo "Unexpected type: $basetype" >> checkdiffs
    fi
    if [[ -e $base-check.o ]]; then
      diff -q $base-check.o $base.o >> checkdiffs
    else
      gcc -o $base-check $base.o >&$base-link.errors
    fi
  else
    echo "No $base.o" >> checkdiffs
  fi
  if [[ -e $base ]]; then
    basetype="`file $base`"
    if [[ ! ("$basetype" =~ "executable") ]]; then
      echo "Unexpected type: $basetype" >> checkdiffs
    fi
    if [[ -e $base-check ]]; then
      diff -q $base-check $base >> checkdiffs
    else
      ./$base > $base-check.out
    fi
  else
    echo "No $base" >> checkdiffs
  fi
  if [[ -e $base-check.out ]]; then
    basetype="`file $base-check.out`"
    if [[ ! ("$basetype" =~ "ASCII") ]]; then
      echo "Unexpected type: $basetype" >> checkdiffs
    fi
  else
    echo "No $base-check.out" >> checkdiffs
  fi

  popd
done
