I have a large codebase that I've been tasked with porting to 64 bits. The code compiles, but it prints a very large amount of incompatible pointer warnings (as is to be expected.) Is there any way I can have gcc print the line on which the error occurs? At this point I'm just using gcc's error messages to try to track down assumptions that need to be modified, and having to look up every one is not fun.
views:
72answers:
5Use -W option to control which warnings you want to display. this parameter explained here.
Also you can use this trick to suppress progressive outputs:
gcc ... 1>/dev/nul
By the time the compiler emits an error message, the actual source line is long gone, (particularly in C) - it has been transformed to a token stream, then to an abstract syntax tree, then to a decorated syntax tree... gcc has enough on its plate with the many steps of compiling, so it intentionally does not include functionality to reopen the file and re-retrieve the original source. That's what editors are for, and virtually all of them have commands to start a compilation and jump to the next error at a keypress. Do yourself a favor and use a modern editor to browse errors (and maybe even fix them semi-automatically).
This little script should work, but I can't test it right now. sorry if need edit.
LAST_ERROR_LINE=`(gcc ... 2>&1 >/dev/null ) | grep error | tail -n1`
FILE=`echo $LAST_ERROR_LINE | cut -f1 -d':'`
LINE=`echo $LAST_ERROR_LINE | cut -f2 -d':'`
sed -n "${LINE}p" $FILE
Perhaps a script to print the desired lines would help. If you are using csh (unlikely!) use:
make ... |& show_gcc_line
with show_gcc_line
the following script:
#!/bin/csh
# Read and echo each line. And, if it starts with "foobar:123:", print line 123
# of foobar, using find(1) to find it, prefaced by ---------------.
set input="$<"
while ( "$input" )
echo "$input"
set loc=`echo "$input" | sed -n 's/^\([^ :]*\):\([0-9]*\):.*/\1 \2/p'`
if ( $#loc ) then
find . -name $loc[1] | xargs sed -n $loc[2]s/^/---------------/p
endif
set input="$<"
end
And for bash, use make ... 2>&1 | show_gcc_line
with:
#!/bin/bash
# Read and echo each line. And, if it starts with "foobar:123:", print line 123
# of foobar, using find(1) to find it, prefaced by ---------------.
while read input
do
echo "$input"
loc=$(echo "$input" | sed -n 's/^\([^ :]*\):\([0-9]*\):.*/\1 \2/p')
if [ ${#loc} -gt 0 ]
then
find . -name ${loc% *} | xargs sed -n ${loc#* }s/^/---------------/p
fi
done
I've blatantly stolen Joseph Quinsey's answer for this. The only difference is I've attempted to make the code easier to understand:
For bash, use make 2>&1 | show_gcc_line
with show_gcc_line
the following script:
#!/bin/bash
# Read and echo each line only if it is an error or warning message
# The lines printed will start something like "foobar:123:" so that
# line 123 of file foobar will be printed.
while read input
do
loc=$(echo "$input" | sed -n 's/^\([^ :]*\):\([0-9]*\):.*/\1 \2/p')
len=${#loc}
file=${loc% *}
line=${loc#* }
if [ $len -gt 0 ]
then
echo "$input"
echo "$(sed -n ${line}p $file)"
echo
fi
done
This was partly because I did not like the formatting of the original. This only prints the warnings/errors, followed by the line of code causing the problem, followed by a blank line. I've removed the string of hyphens too.