Re: Is there a way to pretty-print output for templates errors

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> > Stephen Torri <storri@xxxxxxxxx> writes:
> >
> > > I have a hard time reading the template errors I get from GCC. I was
> > > wondering if there is a flag for the compiler so that instead of getting
> > > output like below. I know I failed to present this snapshot in a
> > > preformatted output. This was deliberate to show how hard is to read
> > > this on a terminal window.
> >
> > Unfortunately there is no such option.
>
> BTW, i think the real readability improvement (besides obviously
> trying to use magic to make them shorter but understandable) would be
> had from making it visually clear where the word " to non-scalar type"
> starts.
>
> At least for me, half the time I spend trying to interpret the error
> is going through the 80 lines it spewed trying to find where the
> template it's complaining about ends and where the error it's actually
> complaining about begins.

> > Some people find the STLFilt program to be helpful:
> >     http://www.bdsoft.com/tools/stlfilt.html

Hi all,
	Years ago, I had similar gripes about reading template errors
arising from deeply nested templates and long chains of instantiations.
I put awk to work and wrote the attached makeshift filter
[balance_indent.awk] that expands templates arguments with tree-like
indenting and line-breaking.  To use it, pipe the stderr of gcc/g++
through "awk -f <the-script>".  It's probably far from perfect, but it
sure took strain off of my eyes in identifying the precise problem.  You
can customize the matching pattern at the end of the script.
	To be honest, I haven't used the script in years, and the format
of the error messages may have changed slightly over the years.  After
practice, one just sees through the falling glyphs...

Hope it helps some.

Fang
#!/usr/bin/awk -f
# "balance_indent.awk"
#	$Id: balance_indent.awk,v 1.1 2005/09/04 22:13:48 fang Exp $

# for all those unreadable template error messages in the C++ standard library

BEGIN {
	level = 0;
	indent = "    ";
	# or "\t"
	width = 80;	# terminal width, overrideable
}

# note beware of operators < and >

function auto_indent(lvl, i) {
	ret = "";
	i=0;		# local var
	for ( ; i<lvl; i++)
		ret = indent ret;
	return ret;
}

function balance_indent(str,
	# local variables
		arr, numlines, i, ilevel, joinlines) {
	gsub("\\(", "(\n", str);
	gsub("\\[", "[\n", str);
	gsub("<", "<\n", str);
	gsub(",[ \\t]*", ",\n", str);
	gsub("\\)", "\n)", str);
	gsub("\\]", "\n]", str);
	gsub(">", "\n>", str);

	# split them apart
	numlines = split(str, arr, "\\n");
	i=1;
	for ( ; i<=numlines; i++) {
		if (match(arr[i], "^\\)") || match(arr[i], "^>") ||
				match(arr[i], "^\\]")) {
			level--;
		}
		# prepend indent
		ilevel[i] = level;
		if (match(arr[i], "\\($") || match(arr[i], "<$") ||
				match(arr[i], "\\[$")) {
			level++;
		}
		# else no change in level
	}

	# glue back together
	# any intelligence about short balances?

#	joinlines = smart_join(arr, ilevel, 0, numlines-1);

	str = arr[1];
	i = 2;
	for ( ; i<=numlines; i++) {
		if (length(arr[i]))
			str = str "\n" auto_indent(ilevel[i]) arr[i];
		# else skip blank lines
	}
	return str;
}

# intelligently joins lines, recursively
function smart_join(arr, ilevel, startindex, endindex, 
	# returned arrays (by reference)
	subarr, subilevel, subnumlines, 
	# local variables
	i, is_nested, curlevel, linelength) {

	# so we know this is passed by reference
	subnumlines[0] = 0;
	is_nested = 0;
	curlevel = ilevel[startindex];

	# phase 0: scan and see if this sub-array has nested levels
	for (i=startindex+1; i<=endindex && !is_nested; i++) {
		if (ilevel[i] > curlevel)
			is_nested = 1;
	}

	if (is_nested) {

		# phase 1: partition into sections by level
		# what is one *item* in this level?
		for (i = startindex; i<=endindex; i++) {
			
		}
	} else {
		# we're in deepest level, no need to recurse
		# we have uniformly indented subarray of lines
		# see what we can combine...
		# no partial joining, just all or none

		# compute total line length (until width exceeded)
		linelength = length(auto_indent(curlevel));
		for (i=startindex; i<=endindex && linelength < width; i++) {
			linelength += length(arr[i]);
		}
		if (linelength < width) {
			# join them all
			# don't prefix with indent yet.
			subilevel[startindex] = ilevel[startindex];
			for (i=startindex; i<=endindex; i++) {
				subarray[startindex] = \
					subarray[startindex] arr[i];
			}
			subnumlines[0] = 1;
		} else {
			# don't join any, just copy back
			for (i=startindex; i<=endindex; i++) {
				subarray[i] = arr[i];
				subilevel[i] = ilevel[i];
			}
			subnumlines[0] = startindex -endindex +1;
		}
	}
}

# for almost all lines:
{
	# exceptions
	if (match($0, "^g?make") || match($0, "^distcc"))
		print;
	else	print balance_indent($0);
}


[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux