# Filter patterns for filterErrors
# Copyright (C) 2014 - 2018 FARGOS Development, LLC
# $Id$

BEGIN {
	MAX_LINES_TO_SAVE = 3;
	showWarnings = 1 * SHOW_WARNINGS;
	lastLineSub = MAX_LINES_TO_SAVE;
	lineCount = 0;
	dontPrint = 0;
	lastDirName = ENVIRON["PWD"]; # get working directory
	originDir = lastDirName;
	if (SHOW_COLORS == 1) {
		redOn = "\033[31;1m"
		greenOn = "\033[32;1m"
		blueOn = "\033[34;1m"
		magentaOn = "\033[35;1m"
		cyanOn = "\033[36;1m"
		resetColor = "\033[0m";
	} else {
		redOn = "";
		greenOn = "";
		blueOn = "";
		magentaOn = "";
		cyanOn = "";
		resetColor = "";
	}
}

function checkIfWarningWanted(s, _i)
{
	# ignore warnings in boost headers
	_i = index(s, "_input_facet");
	if (_i != 0) {
		return (0);
	}
	_i = index(s, "wait_until");
	if (_i != 0) {
		return (0);
	}
	# ignore declaration of 'none' shadows a global declaration
	_i = index(s, "boost/thread/future.hpp:");
	if (_i != 0) {
		return (0);
	}
	if (showWarnings > 1) { # filter deprecation
		_i = index(s, "deprecated");
		if (_i != 0) {
			return (0);
		}
	}
	return (1);
}

function emitContext(_reason, useColor)
{
	if ((length(FILENAME) > 0) && (FILENAME != "-")) {
		file = FILENAME ":"
	} else {
		file = "";
	}
	printf("%s%s%s at log line %s%s%d%s in dir %s%s%s\n",
		useColor, _reason, resetColor,
		blueOn, file, NR, resetColor,
		blueOn, lastDirName, resetColor);
	linesAvail = lineCount;
	if (linesAvail > MAX_LINES_TO_SAVE) linesAvail = MAX_LINES_TO_SAVE;
	linesSinceLastError = NR - lastErrorEnd;
	if (linesAvail > linesSinceLastError) {
#printf("Reduce number of lines for display to %d\n", linesSinceLastError);
		linesAvail = linesSincelastError;
	}
	firstSub = lastLineSub - (linesAvail - 1);
	while (firstSub < 1) {
		firstSub += MAX_LINES_TO_SAVE;
	}
	for(count=1;count<=linesAvail;count+=1) {
		if (firstSub > MAX_LINES_TO_SAVE) firstSub = 1;
		print savedLine[firstSub];
		firstSub += 1;
	}
	lastLineSub = MAX_LINES_TO_SAVE;
	lineCount = 0;
}

/^In / {
	if ((NR == 1) && (NF == 2)) {
		# assume origin directory was announced
		lastDirName = $2;
		originDir = $2;
	}
}

/Entering directory/ {
	lastDirName = $4;
	if (substr(lastDirName, 1, 1) == "'") { # begins with single quote
		lastDirName = substr(lastDirName, 2, length(lastDirName) - 2);
	}
	makeKey = substr($1, 1, 5);
	if (makeKey == "make[") {
		curStack = 1 * lastDirDepthForMake[$1];
		if (curStack == 0) {
#printf("First depth key %s %d origin=%s\n", $1, curStack, originDir);
			lastDirForMake[$1,0] = originDir;
		}
		curStack = curStack + 1;
		lastDirDepthForMake[$1] = curStack;
		lastDirForMake[$1,curStack] = lastDirName;
	}
}

/Leaving directory/ {
	dirName = $4;
	if (substr(dirName, 1, 1) == "'") { # begins with single quote
		dirName = substr(dirName, 2, length(dirName) - 2);
	}
	makeKey = substr($1, 1, 5);
	if (makeKey == "make[") {
		curStack = lastDirDepthForMake[$1];
		if (lastDirForMake[$1,curStack] == dirName) {
			# pop
			curStack = curStack - 1;
			lastDirDepthForMake[$1] = curStack;
			lastDirName = lastDirForMake[$1,curStack];
#printf("%d Leaving dir %s, inferring current %s depth %d dir is %s\n", NR, dirName, $1, curStack, lastDirName);
		} else {
printf("%d Leaving dir %s but thought was %s\n", NR, dirName, lastDirForMake[$1, curStack]);
		}
	}
}


/ error: / {
	if (inError == 0) { # announce transition
		inError = 1;
		emitContext("Saw compile error", redOn);
	} else { # already in error
		# we've already been printing context 
		lastErrorEND = NR;
	}
	print redOn $0 resetColor;
	dontPrint = 1;
}

/ warning: / {
	if (showWarnings >= 1) {
		usefulWarning = checkIfWarningWanted($0);
		if (usefulWarning != 0) {
			if (inError == 0) { # announce transition
				inError = 1;
				emitContext("Saw compile warning", magentaOn);
			}
			print magentaOn $0 resetColor;
		}
	}
	next;
}

/undefined reference/ {
	emitContext("Saw undefined reference", redOn);
	print magentaOn $0 resetColor;
	next;
}

/LOW_RESOLUTION_TIME/ { # ignore
	next;
}

/\*\*\*/ {
	makeKey = substr($1, 1, 5);
	origDir = lastDirName;
	if (makeKey == "make[") {
		curStack = lastDirDepthForMake[$1];
		inDirName = lastDirForMake[$1,curStack];
		if (inDirName != lastDirName) {
printf("Inferred working directory of %s to be %s\n", $1, inDirName);
			lastDirName = inDirName;
		}
	}
	emitContext("Saw make error", redOn);
	print redOn $0 resetColor;
	lastErrorEnd = NR;
	next;
}

# New gcc compilers emit ^ along with a sufficient number of
# tildes to underline the field in question
/ [~]*\^[~]*$/ {
	if (inError) {
		print $0; # output highlight line
#		printf("END error at %d\n", NR);
		inError = 0;
	}
	lastErrorEnd = NR;
	next;
}

{
	if (inError) {
		if (dontPrint == 0) {
			print $0;
		} else {
			dontPrint = 0;
		}
	}
	lastLineSub += 1;
	if (lastLineSub > MAX_LINES_TO_SAVE) {
		lastLineSub = 1;
	}
	savedLine[lastLineSub] = $0;
	lineCount += 1;
}
