tags:

views:

72

answers:

5

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.

+1  A: 

Use -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
Ehsan
Well I'd like to be able to see the source line itself for the error.
Alex
A: 

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).

Kilian Foth
A: 

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
Ehsan
+2  A: 

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
Joseph Quinsey
+2  A: 

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.

James Morris
+1 But maybe it should be done, for example, in Python? _Shell_ scripting is apparently _passe_.
Joseph Quinsey
@James: Also, typically, you need to use something like **find**, because Makefiles often change the directory. I've _assumed_ that everything is at or below the top-level directory.
Joseph Quinsey
@James: Unless, of course, the OP's legacy code coders have read _Recursive Make Considered Harmful_ http://aegis.sourceforge.net/auug97.pdf
Joseph Quinsey
My removal of the `find` command was short-sighted.
James Morris
@Joseph: I guess they have!
James Morris