#! /usr/bin/gawk -f
# Last edited on 2003-12-14 12:37:59 by stolfi


BEGIN{
  usage = ( ARGV[0] " < MAKE.log > MAKE.errs" );
  abort = -1;
  
  # Reads the messages printed by a "make index" run, and prints all
  # lines that look like significant error and warning messages. The
  # lines are morphed into the standard compilation error format
  # "{NNNNN}/main.pov:{LLL}: {MESSAGE}" where NNNNN is the student's
  # RA number and LLL is the line number.  The script mostly assumes that 
  # all errors occur in the "main.pov" source file, and relies on
  # the "Entering directory" messages printed by GNU "make".
  
  ra = "NOSTUD";
  fname = "NOFILE";
  lnum = 0;
  clear_errors();
}

/^make\[.* Entering directory/ {
  dir = $4; gsub(/[`']/, "", dir);
  nra = dir; gsub (/^.*[\/]/, "", nra);
  if (nra != ra)
    { flush_errors();
      printf "%s: === begin ==============================\n", nra; 
      ra = nra; 
      clear_errors();
    }
  fname = "NOFILE";
  lnum = 0;
  next;
}

/^make[\[:].* Error/ {
  save_error(sprintf("%s: %s", ra, $0)); 
  fname = "NOFILE";
  lnum = 0;
  next;
}

/^convert:/ {
  save_error(sprintf("%s: %s", ra, $0));
  fname = "NOFILE";
  lnum = 0;
  next;
}

/Possible Rendering Error: Maximum trace level/ { next; }

/Warning Stream to console/ { next; }

/File: .*  Line: .*/ {
  loc = $0;
  gsub(/^.*File:/, "File:", loc);
  fname = $2; 
  if (fname !~ /^[\/]/) { fname = ( ra "/" fname ); }
  lnum = $4;
  next;
}

/^(Error|Warning):/ {
  msg = $0;
  while(1)
    { gsub (/^.*(Error|Warning): */, "", msg);
      gsub (/ +$/, "", msg);
      if (msg != "") { break; }
      if ((getline msg) <= 0) { msg = "EOF"; break; } 
    }
  if (msg ~ /3.1, you must add interior.*glass_old.inc/) { next; }
  save_error(sprintf("%s:%s: %s", fname, lnum, msg)); 
  next;
}

// { next; }

END {
  flush_errors();
}

function clear_errors()
{
  split("", err);
  split("", errct);
  nerr = 0;
}

function flush_errors(   i)
{
  for (i = 0; i < nerr; i++) { print err[i], ("[×" errct[err[i]] "]"); }
}

function save_error(msg)
{
  if (msg in errct)
    { errct[msg]++; }
  else
    { errct[msg] = 1;
      err[nerr] = msg; nerr++;
    }
}