#! /usr/bin/gawk -f # Last edited on 2009-09-27 19:29:28 by stolfilocal BEGIN{ USAGE = ( "povray 2>&1 | tee povray.log | reformat-povray-output" ); # Filters any POVRAY messages, removing crap and reformatting # error messages to match C compiler's output. # Status: # 0 = preamble # 1 = normal # 2 = error context lines # 3 = error message lines state = 1; # Parsing state. file = "???"; # (In states 2 and 3.) File where current error is. lnum = 1; # (In states 2 and 3.) Line number of current error. emsg = "???" # (In state 3.) Current text of error message. nlin = 0; # (In state 3.) Number of lines joined into {emsg}. } /./{ # General line cleanup: gsub(/[\015]/, "\n", $0); gsub(/[\012] *$/, "", $0); # Debug: # printf " × %s\n", $0; } /^Persistence of Vision\(tm\)/{ printf " %s\n", $0; if (state != 1) { flush_error(); sequence_warning("unexpected header line"); } state = 0; next; } /^ *Clock value:/{ printf " %s\n", $0; if (state != 0) { flush_error(); sequence_warning("unexpected end of header line"); } state = 1; next; } /^File:[ ]*.*[ ]Line:[ ]*[0-9]+[ ]*$/ { # Start of error context lines flush_error(); if ((state != 1) && (state != 3)) { sequence_warning("unexpected error-start line"); } # Grab file name and line number: file = $2; lnum = $4; emsg = "???"; nlin = 0; # Reset error context: split("", ctx); nctx = 0; state = 2; next; } (match($0, /^([ ][ ]|[^ ])/) && (state == 3)) { # Does not look like an error message continuation line. flush_error(); # Set normal state and fall through to normal processing: state = 1; } /^Parse (Error|Warning):/ { # End of context lines, start of error message lines: if (state != 2) { flush_error(); sequence_warning("unexpected error-end line"); # Pretend that there was an error-start line: file = "???"; lnum = "1"; } # Initialize {emsg,nlin}, remove the "Parse Error:", and # fall through to the normal {state == 3} processing: gsub(/^Parse Error: */, "", $0); gsub(/^Parse Warning: */, "warning: ", $0); state = 3; emsg = ""; nlin = 1; } END { flush_error(); } (state == 0) { # Skipping header. next; } (state == 1) { # Normal state. printf " %s\n", $0; next; } (state == 2) { # Gobbling up error-context lines. ctx[nctx] = $0; nctx++; next; } (state == 3) { # Gobbling up error-message lines. lin = $0; gsub(/^[ ]+/, "", lin); gsub(/[ ]+$/, "", lin); emsg = (emsg " " lin); nlin++; if ((match(emsg, /([.]|instead) *$/)) || (nlin >= 4)) { flush_error(); state = 1; } else { state = 3; } next; } function flush_error() { # Prints out the current error, if any: if ((state == 2) || (state == 3)) { print_error(file,lnum,ctx,emsg); file = ""; lnum = ""; emsg = ""; nlin = 0; } } function print_error(file,lnum,ctx,emsg, i) { printf "%s:%s: %s\n",file,lnum,emsg; for (i = 0; i < nctx; i++) { printf " %s\n", ctx[i]; } printf "\n"; } function sequence_warning(msg) { printf "!! povray output is malformed: %s\n",msg; }