                                  SCANDEP 1.00
                                  ------------

        Purpose
        -------
        SCANDEP is a C/C++ programmer's utility to generate dependency
        lists for one or more source files.  Dependencies are displayed
        in either a hierarchical format or formats suitable for
        makefiles.  SCANDEP was developed with and for the Microsoft
        compiler (MSVC), but I know of no reason why it wouldn't work
        with source for any standard C/C++ compiler.

        SCANDEP is a DOS command-line utility, but of course it can be
        run in a DOS window under Windows or OS/2.

        If you don't know what a dependency list is, or what a dependent
        file is, then you probably don't need this program.


        Why?
        ----
        I recently needed a DOS program to generate makefile-suitable
        lists of file dependencies for a large number of C++ source
        files and assumed that it would be pretty easy to find one on
        CompuServe or the Internet.  I did find several, but none worked
        quite right.  Either they missed files for no obvious reason, or
        they automatically included all of the "system" headers (like
        stdio.h), or they didn't recognize that some of the #include
        directives were commented out.

        Particularly troubling was that most of the ones I found did not
        search for included files in the same way that C/C++ compilers
        do.  For example, MSVC never explicitly searches the current
        directory for an include file.  It looks in the directory of the
        file that does the including (and of the file that included
        that, etc.), and this may very well result in a search of the
        current directory, but it never looks in the current directory
        unless one of its "includers" lives there.  Most of the
        dependency generators I tried didn't understand this, or, more
        generally, the basic search pattern for include files.

        Anyway, this simple program is the result.  It may or may not be
        free of bugs, but it does attempt to follow the search patterns
        of MSVC (the only C/C++ compiler I'm familiar with); it
        understand comments; and it's flexible about the handling of
        system includes.


        Output formats
        --------------
        SCANDEP can generate its output in three formats; we'll describe
        these before we begin with SCANDEP's syntax and options.

        Let's assume that you have asked SCANDEP to scan the source file
        PROJECT.CPP and that we have the following project file
        structure:

            PROJECT.CPP:
            #include "project.h"
            #include "common.h"

            PROJECT.H:
            #include "stuff.h"

            STUFF.H:
            #include "common.h"

            COMMON.H:
            // no includes

        The default SCANDEP output format generates a makefile-suitable
        description block like this:

            project.obj: project.cpp \
                project.h \
                stuff.h \
                common.h

        As you can see, this block shows that the object file
        PROJECT.OBJ is dependent on the source files PROJECT.CPP,
        PROJECT.H, STUFF.H, and COMMON.H.  The block is ready for the
        addition of the necessary build commands to create PROJECT.OBJ.

        The second format conforms with that used by MSVC in makefiles
        that it creates.  MSVC users will have noted that the
        description blocks in MSVC-generated makefiles do not explicitly
        list all of the dependencies.  Instead, the dependencies
        (excluding the primary source file) are assigned to a macro, and
        the macro is used in the description block.  SCANDEP can
        generate output in this format; it would look like this:

            PROJECT_DEP = project.h \
                stuff.h \
                common.h

            project.obj: project.cpp $(PROJECT_DEP)

        The third format is not for makefiles.  It simply displays the
        include file structure in hierarchical format:

            c:\project\project.cpp
               c:\project\project.h
                  c:\project\stuff.h
                     c:\project\common.h
               c:\project\common.h

        This clearly shows that PROJECT.CPP #includes PROJECT.H and
        COMMON.H; that PROJECT.H #includes STUFF.H; and that STUFF.H
        #includes COMMON.H.  Note that, unlike the makefile blocks,
        files can appear more than once (as COMMON.H does), and that
        absolute paths are shown.


        Syntax
        ------
        The basic syntax is:

            scandep [options] {target[=ext]}

        The targets are the source files that you want to scan;
        the options affect how SCANDEP operates.

        If there are many targets or options, the command line may
        become too long, or inconvenient to type.  In that case, you
        can store the targets and/or options in a text file called
        a "response file" and run SCANDEP in this way:

            scandep @response-file

        We'll describe response files more fully below.


        Specifying targets
        ------------------
        Targets are the source files that you wish to scan.  They
        must be C/C++ source files or MSVC-compatible resource files
        (.RC extension).  You must specify at least one target, or
        SCANDEP will complain that it has nothing to do.

        The simplest usage of SCANDEP just specifies a single target:

            scandep myfile.cpp

        This will scan the target MYFILE.CPP for dependencies (i.e.,
        #include files) and create a makefile-suitable dependency
        list.  It might look like this:

            myfile.obj: myfile.cpp \
                myfile.h \
                common.h \
                stdafx.h

        Note that SCANDEP has assumed that the ultimate target file is
        MYFILE.OBJ (created from MYFILE.CPP); it has actually created
        a dependency list for MYFILE.OBJ rather than MYFILE.CPP.

        Of course, you can redirect SCANDEP's output to a text file for
        editing and/or merging into makefiles.  For example:

            scandep myfile.cpp > myfile.dep

        You can specify multiple targets, and you can use wildcards.
        Paths are OK, including paths relative to the current directory.
        For example:

            scandep *.cpp res\*.rc

        This will scan all *.CPP files in the current directory and all
        *.RC files in the subdirectory RES.  Each target produces a
        separate dependency list.


        Specifying target extensions
        ----------------------------
        In the previous example, SCANDEP assumes that the makefile
        target to be created for MYFILE.CPP is MYFILE.OBJ (since
        MYFILE.CPP would typically be compiled to MYFILE.OBJ).  SCANDEP
        recognizes three extensions:

            .CPP    -> .OBJ
            .C      -> .OBJ
            .RC     -> .RES

        If you have targets with any other extension, or if you want
        different extensions used as the makefile target, specify
        "target extensions" with your targets.  Specify the extension
        for a target by following the target with an equals sign and the
        new extension:

            target=ext

        For example, suppose you have C++ source files with the
        extension .INL that compile to .OBJ files.  SCANDEP will not
        handle these automatically because it doesn't recognize INL as a
        C++ source file.  You would need to specify the extension on the
        command line as follows:

            scandep myfile.inl=obj

        This would create the desired makefile target:

            myfile.obj: myfile.inl \
                ...

        Target extensions are a non-issue in hierarchical output
        format because SCANDEP does not create a makefile target.


        Options
        -------
        SCANDEP's options are:

          /A   Use absolute paths in dependency lists
          /Ef  Set error handling mode for #include not found
          /Er  Set error handling mode for recursive #include
          /Et  Set error handling mode for target not found
          /Ex  Set error handling mode for unknown extension
          /H   Output dependencies in hierarchical format
          /M   Output dependencies in MSVC format
          /I   Specify additional include search path(s)
          /S   Read system includes (#include <file>)
          /X   Exclude named file from dependency lists
          /?   Display brief help

        Options are case-insensitive (/a == /A).  They may be specified
        in any order, and may precede, follow, or be mixed in with
        targets.  All options are processed before any scanning
        begins.

        Multiple options must be separated by spaces, i.e., "/H /S"
        rather than "/H/S".

        The options are described in the following sections.


        /A: absolute paths
        ------------------
        When generating dependency lists, SCANDEP uses paths relative to
        the main target.  For example, suppose we have this:

            c:\one\two\myfile.cpp:
            #include "myfile.h"
            #include "\one\common.h"
            #include "\one\two\res\resource.h"

        The dependency list would look like this:

            myfile.obj: myfile.cpp \
                myfile.h \
                ..\common.h \
                res\resource.h

        Note that all paths are relative to the directory containing the
        target, MYFILE.CPP.  This allows projects to be easily moved
        without requiring makefiles to be completely re-made.

        However, if you prefer absolute paths, use the /A option:

            scandep /A myfile.cpp

        This command would generate the following dependency list:

            myfile.obj: c:\one\two\myfile.cpp \
                c:\one\two\myfile.h \
                c:\one\common.h \
                c:\one\two\res\resource.h

        Regardless of the presence or absence of /A, SCANDEP
        always uses absolute paths in three cases:

          1. For any dependent that is not located on the same drive as
             the target.

          2. For dependents that descend from a different first-level
             directory than the target.

          3. For system includes, i.e., those enclosed in <>:

                #include <stdio.h>

             Note that system includes are only scanned if the /S option
             is present.

        An example of case 2: if MYFILE.CPP also #included
        c:\x\y\some.h, the list would be:

            myfile.obj: myfile.cpp \
                myfile.h \
                ..\common.h \
                res\resource.h \
                c:\x\y\some.h

        As you can see, the full path from the root is specified for
        SOME.H; it is not relative to the location of MYFILE.CPP.  This
        is because SOME.H lies below the first-level directory X rather
        than MYFILE's first-level directory ONE.


        /E: error handling modes
        ------------------------
        Certain potentially recoverable errors can occur when scanning
        for dependencies. These are:

            - Target file not found.

            - #include file not found.

            - Unknown target extensions (extension not .C, .CPP, or .RC,
              and no target extension provided).

            - Recursive includes (a file that directly or indirectly
              #includes itself).

        You can control how SCANDEP responds to each of these situations
        using the /E option.  /E is followed by a single letter
        specifying an error condition:

            /Ef: include not found
            /Er: recursive include
            /Et: target not found
            /Ex: unknown extension

        Following the error condition is a single digit, which must be
        0, 1, 2, or 3 (e.g., /Er2).  These mean:

            0: ignore the error
            1: report the error but continue processing
            2: report the error and exit
            3: report the error, display a list of active source files,
               and exit

        The default settings are:

            /Ef2 (error exit on #include not found)
            /Er1 (report recursive includes but continue)
            /Et2 (error exit on target not found)
            /Ex2 (error exit on unknown extensions)

        Mode 3 affects /Ef and /Er only.  For /Et and /Ex, mode 3 is the
        same as mode 2.


        /H: use hierarchical output format
        ----------------------------------
        Adding the /H option causes SCANDEP to generate its output in
        the hierarchical format described above:

            scandep /h myfile.cpp

        When /H is specified, /A has no effect (the output always uses
        absolute paths), and unknown target extensions are of no
        significance.  /H overrides /M; if both are specified, the
        output will be in hierarchical format.


        /I: specify include path
        ------------------------
        When searching for #included files, SCANDEP follows the standard
        MSVC search pattern (see online help for #include).  This
        includes the directories containing all "parent" files of the
        file being included and the directories specified by the
        environment variable INCLUDE.

        MSVC provides the /I option, which allows you to specify
        additional directories search; SCANDEP provides a very similar
        option.  To use it, just specify /I followed by a directory
        name:

            scandep /I\projects\common myfile.cpp

        To specify multiple directories, either use multiple /I options
        or use a PATH-like specification, separating directories with
        semicolons:

            scandep /I\projects\common /I\toolkit\include ...
            scandep /I\projects\common;\toolkit\include ...

        In either case, SCANDEP adds \PROJECTS\COMMON and
        \TOOLKIT\INCLUDE to its list of searchable directories.  These
        directories are searched before the INCLUDE variable
        directories, by the way.

        MSVC users: note that, unlike MSVC, there is no space between /I
        and the directory name.


        /M: use MSVC format
        -------------------
        Adding the /M option causes SCANDEP to generate dependencies in
        "MSVC format" as described above:

            scandep /m myfile.cpp

        In this format, dependencies are assigned to makefile macros,
        and the macros are used in the description blocks.


        /S: scan system includes
        ------------------------
        Normally, SCANDEP ignores the "system" includes, i.e., include
        files specified with <>:

            #include "myfile.h"  // SCANDEP scans this...
            #include <stdio.h>   // ...but not this

        This is because system headers rarely change and are typically
        not included in makefiles.

        However, you can force SCANDEP to scan the system headers by
        using the /S option:

            scandep /s myfile.cpp


        /X: exclude dependents
        ----------------------
        Occasionally you may wish to exclude specific dependents from
        dependency lists.  Do this with the /X option, which is followed
        by a filename.  For example:

            scandep myfile.cpp /Xresource.h

        This command would omit RESOURCE.H from all dependency lists.

        Note that SCANDEP doesn't scan excluded files for dependencies.
        In other words, both the excluded file and its dependents are
        omitted from the output.

        The filename as specified must exactly match the filename
        provided in the #include directive.  If you've used
        "/Xresource.h", then SCANDEP will recognize and exclude:

            #include "resource.h"

        but not:

            #include "c:\myfile\resource.h"

        /X excludes dependents (include files), not targets.  If your
        target is *.C, all C source files will be scanned; you can't
        exclude a specific C source file by using, for example,
        "/Xuseless.c".


        /?: display brief help
        ----------------------
        The /? option displays a screen comtaining a brief summary of
        SCANDEP's syntax and options.

            scandep /?

        If /? is used, all other options and targets are ignored;
        SCANDEP displays the help screen and terminates.


        Using response files
        --------------------
        If the command line grows too long, or if you want to run
        SCANDEP regularly on a particular project, you can use a
        response file.

        To create a response file, use your regular text editor to
        create a text file containing any number of targets and/or
        options.  Lines in the response file may be empty; they may
        contain one target or option; or they may contain multiple
        targets and/or options (just like the command line).  However,
        individual lines are limited to 500 characters.

        A response file might look like this:

            myfile.cpp
            fileiter.cpp
            sources.cpp
            res\resource.cpp
            common.cpp
            /Xresource.h /S
            /I\library\include
            /M

        To use the response file, simply put its name on the command
        line follwing an @, e.g.:

            scandep @scandep.rf

        It's perfectly OK to mix command line options and targets with a
        response file:

            scandep /S target.c @scandep.rf

        You can use multiple response files, but they can't be nested.


        Errorlevels
        -----------
        SCANDEP returns one of the following DOS errorlevels on
        completion:

            0   no errors
            1   recursive header found (/Er2 mode)
            2   unknown target extension (/Ex2)
            3   include file not found (/Ef2)
            4   include file could not be opened
            5   target not found (/Et2)
            254 system exception (out of memory, file I/O error)
            255 usage error; response file not found; response file line
                too long


        Implementation limits
        ---------------------
        1. Source files are assumed to be text files consisting of lines
        no longer than 2000 characters.  Excess characters are
        discarded.

        2. Response files are assumed to be text files consisting of
        lines no longer than 500 characters.  Longer lines will generate
        an error.

        3. SCANDEP does not recognize the RCINCLUDE directive in MSC
        resource files.

        4. SCANDEP is a DOS program and it can run out of memory if many
        targets are specified, if the dependency lists are extremely
        large or if not much memory is available.  Try reducing the
        number of targets per run.


        Problems/comments/suggestions
        -----------------------------
        Please report any problems and send any comments or suggestions
        to me at the email addresses below.


        Release history
        ---------------
        6/26/97 v1.00: initial release


        Copyright/License/Warranty
        --------------------------
        This document and the program file SCANDEP.EXE ("the software")
        are copyrighted by the author.  If you are an individual, the
        copyright owner hereby licenses you to use the software, make
        as many copies of the software and documentation as you wish,
        give such copies to anyone, and distribute the software and
        documentation via electronic means.  There is no charge for any
        of the above.

        However, you are specifically prohibited from charging, or
        requesting donations, for any such copies, however made; and
        from distributing the software and/or documentation with
        commercial products without prior permission.  An exception is
        granted to not-for-profit user's groups, which are authorized to
        charge a small fee (not to exceed $7) for materials, handling,
        postage, and general overhead.

        Businesses, institutions, and governmental entities must obtain
        a specific license agreement from The Cove Software Group in
        order to use the software.

        No copy of the software may be distributed or given away without
        this document; and this notice must not be removed.

        There is no warranty of any kind, and the copyright owner is not
        liable for damages of any kind.  By using this free software,
        you agree to this.

        The software and documentation are:

                             Copyright (C) 1997 by
                             Christopher J. Dunford
                            The Cove Software Group
                               10551 Rivulet Row
                            Columbia, Maryland 21044

                              Tel: (410) 992-9371
                             CompuServe: 76703,2002
                          email: cd@cis.compuserve.com
