[alt.sources] superfluous #include spotter

gregory@agcsun.UUCP (Gregory Bloom) (10/03/90)

Here is incspot.c, a REE-LEE-CHEE-ZEE program that I use to ferret out
unnecessary #include statements in a project so as to minimize impact
of header file changes.

To use, just compile and invoke it in the directory of your choice.
incspot will test each #include in *.c using cc.  Of course, this
could take a while, so you should plan to go get a ham sandwich
or something while it is running.

It does not recurse to identify superfluous dependent #includes, so
you might want to run it a second time after cleaning up a first pass
to be sure you got everything.


-------------------------------CUT HERE----------------------------------------

/*-----------------------------------------------------------------------------
/*
/*   incspot.c
/*
/*   An incredibly crude program to point out unnecessary #include statements
/*
/*   G. Bloom  7/19/90
/*
/*   agcsun!gregory@boulder.colorado.edu
/*
/*-----------------------------------------------------------------------------
*/

#include <stdio.h>

#define  MAX_LINE_LEN  1024

main ()
{
    FILE *ls, *source_file, *temp_file, *temp_source;
    char source_file_name[256];
    char source_line[MAX_LINE_LEN], temp_line[MAX_LINE_LEN];
    int line_count, temp_count;

        /* open a pipe to an ls of all .c source files */
    ls = popen ("ls *.c", "r");

        /* while there are .c files left to process */
    while (fgets (source_file_name, 256, ls) != (char *)NULL)
    {
            /* blow newline */
        source_file_name[strlen (source_file_name) - 1] = 0;

            /* open a read stream into this .c source */
        source_file = fopen (source_file_name, "r");


            /* for each line in this file... */
        for (line_count = 0; 
             fgets (source_line, MAX_LINE_LEN, source_file) != (char *)NULL;
             line_count++)
        {
            if (strncmp (source_line, "#include", 8) == 0)
            {
                    /* create a new temp file to compile without one #include */
                temp_file = fopen ("incspot_temp.c", "w");

                    /* open a second read stream to copy this source to temp */
                temp_source = fopen (source_file_name, "r");

                    /* copy this source to temp except this #include */
                for (temp_count = 0;
                     fgets (temp_line, 1024, temp_source) != (char *)NULL;
                     temp_count++)
                {
                        /* skip #include */
                    if (temp_count != line_count)
                        fputs (temp_line, temp_file);
                }

                fclose (temp_source);
                fclose (temp_file);

                    /* see if the temp compiles without this #include */
                if (system ("cc -c incspot_temp.c 2> /dev/null") == 0)
                {
                        /* blow newline */
                    source_line[strlen (source_line) - 1] = 0;

                        /* tell the user this #include in this file is bogus */
                    printf ("%s line #%d: %s\n", 
                            source_file_name, line_count + 1, source_line);
                }
            }
        }

            /* we're through checking this source */
        fclose (source_file);

    }  /* while (there are sources to check) */

        /* tidy up */
    pclose (ls);
    unlink ("incspot_temp.c");
    unlink ("incspot_temp.o");
}


-------------------------------CUT HERE----------------------------------------


Have fun.


Gregory Bloom
agcsun!gregory@boulder.colorado.edu