QD Metrics User Manual

Version 1.01, 2004/05/27

http://www.wrotniak.net/works/qdmet/index.html


Contents

  1. What is QDMet?
  2. How to run QDMet
  3. Command line arguments and switches
  4. The program log
  5. Metrics generated
  6. Bonus: Graphic representation of results
  7. Distribution and support
  8. Version history

1. What is QDMet

QD Metrics (or just QDMet) is a program for quick-and-dirty metrics of C++ source code. It does not try to measure the code complexity or other non-trivial aspects   just the size.

In addition to lines of code (whatever that means), QDI generates a number of other, similar metrics which may be of use in determining a project size. These metrics are discussed in detail in one of the next sections of this document.

The program runs only under Windows: an flavor from 95 to XP.

2. How to run QDMet

QDMet is a command-line program. You run it from the command-line interface, passing to the program a number of arguments and switches following a pattern like

qdmet name=value name=value /switch name=value /switch ...

where the order of named arguments and switches does not matter.

When executed like this, QDMet scans all source files following a given naming pattern in a given directory (possibly with subdirectories to any nesting depth), generates the metrics, and produces a tabular report to the screen, and in a test file named "qdmet.log" in the directory from which it was run.

The program does not modify any of your files; this means that it is not capable of doing any harm, regardless of the way you may use or misuse it.

3. Command line arguments and switches

Each argument is of a form "name=value" (important: no spaces around '=' !!!); an argument with a given name may appear at most once in the list.

  • root=... specifies the root of the directory tree to scan. This can be given as an absolute path (starting from the drive letter), or a relative one, with respect to directory from which QDMet is executed. For example:

    root=c:\source\project

    or

    root=..\..\misc\

    or

    root=project

    These are customary rules in any operating system. The default is the current directory.

    Note: a forward slash can be used instead of the backslash in path names.

  • files=... specifies the files to scan; wildcards '*' and '?' can be used as per normal Windows/DOS convention, and multiple names or patterns have to be separated with semicolons (no spaces!). For example,

    files=*.cpp

    will scan all files with the ".cpp" extension, while

    files=*.c??

    will use all files with three-character ones starting from a 'c'. If you want to scan all files with any length extensions starting from 'c', use

    files=*.c*

    and to scan all *.cpp, *.cc, and *.h files, use

    files=*.cpp;*.cc;*.h

    A number of explicitly named files can also be specified:

    files=first.cpp;second.c;third.hxx;third.h

    If the 'files' argument is not given, QDMet will use a default of *.cpp;*.c;*.cc;*.cxx;*.h;*.hpp;*.hxx;*.hh.

  • /s — this switch causes QDMet to scan the whole tree of directories nested in the 'root' one. If it is not given, only the root directory will be scanned.

    Note that switches always use a forward slash!

Examples:

qdmet /s root=../develop/bxlib files=*.cpp;*.h

qdmet root=c:\src\xproj /s

qdmet /s

Note the forward slashes used in the root definition in the first example. Backslashes would be OK, too.

4. The program log

QDMet generates a log/report file named qdmet.log in the directory from which it was run (not the scanned root directory). Each line of the log contains a set of metrics for one unit or a subtotal for a given directory; the grand total is given at the end.

By "unit" we understand here any number of files in the same directory, with names differing only in extensions. For example, files "foo.cpp" and "foo.h" will be listed as one unit, "foo", unless they are in different directories.

5. Metrics generated

  • Total number of (physical) lines in files, regardless of what they contain (this is perhaps the most commonly used, and most useless, metrics available;
  • Number of lines containing comments, whether they are line comments, starting with '//',or old style '/* ... */' ones;
  • Number of empty lines;
  • Number of lines containing actual code;
  • Number of instruction terminators (semicolons) in the code lines. Some people consider this to be a better measure than just a count of lines;
  • Total number of characters (excluding newlines) in the files;
  • Number of characters in the code, i.e., excluding comments (this may be less sensitive to some quirks of coding style).

Additionally, three derivatives of the above are listed (only in the log file, not in the screen output):

  • Number of comment lines per line of code;
  • Fraction of empty lines among all lines;
  • Terminators (semicolons) per code line;
  • Characters per code line.

Actually, these four my say something on the coding style, and it is quite interesting to compare them between programmers.

Remarks:

  1. If a line contains both code and comment, it will be counted in both line categories. Thus, the code

    x = sin(t+0.0001); // safety margin

    will be counted the same way as

    x = sin(t+0.0001);
    // safety margin

  2. In character count, any leading and trailing spaces are stripped from the line, and multiple spaces are merged. For example, the line

       x = z   +   t  -  1;     // !!!

    will result in the same character count as

    x = z + t - 1; // !!!

    but _not_ in the same as

    x=z+t-1;//!!!

    This prevents the worst possible abuse of gaming the system; a better approach (which I may consider in a future version) may distinguish between "meaningful" and "non-meaningful" space, so that the third example would yield identical result as the others.

  3. Code lines containing just one character are counted as empty lines. This removes a great dependency of line counting on code layout preferred by various programmers. For example, the snippet

    if (x>0)
    {
       callCounter(x);
    }

    will be counted as two code lines, the same as

    if (x>0)
       callCounter(x);

    Of course, this does not remove all layout style dependency: the fragment

    if (x>0) callCounter(x);

    will still be counted as one code line.

6. Bonus: Graphic representation of results

QDMet is a text-only program   it satisfies a relatively simple need, and I have more interesting things to do than spiffying a trivial application with GUI bells and whistles.

Still, you can view the graphic representation of the reports with use of my other freeware program, the Statmaster (check my Web site for a download).

The easiest way to integrate both programs is to place them in the same directory, together with the StatMaster setup file for QDMet reports, "qdmet.stm.ini" (included in this distribution). Run QDMet as usual, and then execute

statmaster qdmet.stm.ini qdmet.log

to view some distributions and scatter-plots of the generated metrics. Refer to the StatMaster documentation on how the setup can be modified to fit your needs and preferences.

7. Distribution and support

QDMet is free to use for anyone except Osama bin Laden. Shareware and freeware vendors may include it in their collections as long as the whole original archive, including this document, is in the package.

Updates (new features, bug fixes) are available at the QDMet Home Page, where you can also find my email address.

Although the program is supplied on the "as is" basis, I will be glad to receive feedback: problem reports and enhancement suggestions. On the other hand, I am not planning to expand the program into advanced complexity metrics areas; there are commercial offerings (and quite expensive, too) which do that. Therefore keep your suggestions not too ambitious :)

8. Version history

1.00 2003/11/24 — Original public release.

1.01 2004/05/27 — Handles read-only files.


Legal stuff: Although the author has taken more than reasonable care to assure that the program works exactly as documented below and does not cause any damage, he assumes no responsibility, express or implied, for any results of use, misuse, or inability to use this software.


Document last updated 2005/08/12