Electronic Archaeology
Pages: 1, 2, 3, 4

Linux Cross Reference (lxr)

This system is used to provide a cross reference of the Linux Kernel as well as the Mozilla browser. It uses a web browser as a user interface.

Click for larger view
(Click on the screenshot for a full-size view.)

Click for larger view
(Click on the screenshot for a full-size view.)

The left image shows a code listing. If you select an identifier you are taken to a page listing at every place the identifier occurs. Clicking on one of the items here takes you to the location in the file.

One of the problems with this program is that you must have access to a web server to install this. Also don't attempt to install this program unless you understand Perl well. (It has some of the most complex and uncommented regular expressions I've ever seen.)

The C/C++ Pre-processor

It takes time to make a good mess. Programs start out simple. But then the code gets ported to a new platform. A few #ifdef directives are added to handle platform difference. But then marketing wants a new variant of the program. So more #ifdef directives are added.

As time goes on, more and more conditional compilation directives are added, resulting in more and more complex code. Many of these directives are for platforms or variants that haven't been used in years, but they still remain because no one knows how to take them out.

It soon becomes impossible to tell what's compiled and what's not. That's where the pre-processor comes in. By running the code through the pre-processor, you can tell what's really compiled.

There is a simple technique for making sure that your pre-processor results reflect your current compilation.

First, compile the code normally and redirect the output of make to a log file:

$ make strange.o
g++ -g -DUNIX -DM8K -DPROD -DECHO -DSPEEDUP_CODE -c strange.cpp

Find the compilation command in the log file. Write it to a shell script.

Edit the script and change -c (and other flags) to -E (pre-processor output).

Finally, run the shell script:

$ sh -x
g++ -DUNIX -DM8K -DPROD -DECHO -DSPEEDUP_CODE -E strange.cpp > strange.pre

The following table illustrates the results:

char *save_block(char *block, int size, 
                 char *file, int line)

char *save_block(char *block, int size)

    char *result;

#ifdef LOG_CALLS
    log_message(file, line, "save_block(%p, 
                %d)", block, size);
#endif LOG_CALLS

    return (memcpy(malloc(size), block, size));

    result = find_memory(size);
    result += sizeof(struct mem_header);
    memcpy(result, block, size);
    return (result);

    return ((*alloc)(file, line, block, size));
    return ((*alloc)(block, size));

# 1 "cpp_hell.cpp"

char *save_block(char *block, int size)


return (memcpy(malloc(size), block, size));


Pre-processor and Vim

The Vim editor contains some nice commands that make it easy to view your source file alongside the pre-processor output.

Start by editing both files with the gvim by using the command:

gvim strange.cpp strange.pre

Set the scrollbind option (:set scrollbind).

Split windows vertically (:vsplit) and go to the next file (:next).

You now have two windows side by side, with the source file and the pre-processed file. (If you need help with window navigation in Vim, execute the command :help windows.

Source Navigator

The Source Navigator tool provides an integrated development environment. It provides a nice editor, a source browser, a class browser, and a cross reference.

But it's not perfect. Building the index is slow and the command interface is not the easiest to use. It also breaks on large, complex source packages.

I don't have much experience with this package. Every time I've tried it, the sources have been just too large and weird and have caused Source Navigator to crash.


O'Reilly & Associates recently released (December 2002) Practical C++ Programming, 2nd Edition.

Steve Oualline wrote his first program when he was eleven. He has written almost a dozen books on programming and Linux software.

Return to the O'Reilly Network.