=============================================================================
STL Error Message Decryptor for visual C++
==============================================================================

Written by  Leor Zolman
            leor@bdsoft.com
            www.bdsoft.com
            STLFilt web page: www.bdsoft.com/tools/stlfilt.html

STLFilt.pl (the Perl script):       Release 2.04  (10/02/2001)
CL.CPP (The Proxy CL):              Release 2.21  (9/28/2001)
STLTask Taskbar Icon Controller:    Release 2.03  (9/14/2001)

See QUICKSTART.txt for a brief overview and quick setup instructions.

 ****************************************************************************
 * Please do not redistribute any part of this package directly; rather,    *
 * to ensure folks get the latest version, please direct anyone interested  *
 * to download the latest stlfilt.zip directly from its web page:           *
 *                                                                          *
 *      www.bdsoft.com/tools/stlfilt.html                                   *
 *                                                                          *
 * The version of stlfilt.zip available on the CUJ website is *not* the     *
 * latest version.                                                          *
 ****************************************************************************

This package is updated frequently; check the web page for the date of the
latest posting, and click on the version numbers in the component table
to see reverse-chronological revision logs for CL/STLFilt.pl and STLTask.

 ****************************************************************************
 *  To be notified of updates and have the opportunity to participate in a  *
 *  forum with other filter users, send email to:                           *
 *             majordomo@www.bdsoft.com                                     *
 *  with the line "subscribe stlfilter" in the message body.                *
 ****************************************************************************

======================
What's in this archive
======================

README.txt:     You're reading it: purpose, bugs/limitations, manifest, 
                acknowledgments and shameless self-promotion are  all to 
                be found here.

GLOSSARY.txt    Definition of terms used in this software and documentation.

QUICKSTART.txt: Fast track setup instructions, for the impatient. Contains
                just the essential instructions (compiled from the other
                documents in this distribution) necessary to get the Decryptor
                components up and running quickly.

README-STLTask.txt
                Supplementary documentation on using the STLTask.EXE program.

README-hashed-containers.txt
                Supplementary documentation on hash-based container support.

README-VC7.txt  Supplementary VC7/Visual Studio.NET notes.

CL.EXE          The CL-spoofing proxy compiler. Replaces the stock CL.EXE
                during Visual Studio compilations, and invokes it indirectly.

STLTask.EXE     Taskbar-based Proxy CL control utility.
                STLTask controls Proxy CL installation/uninstallation, filter
                toggling, clipboard filtering and preparation for applying a 
                Visual Studio Service Pack.
                STLTask provides an alternative to STLFilt.BAT to toggle the
                filter control file. The installation/uninstallation feature
                of STLTask is provided for situations where the Proxy CL does 
                not work correctly, e.g., complex projects, projects built
                with third-party tools (such as TrueTime), projects having a 
                mixture of C++ and non-C++ (idl/odl?) targets on the 
                same command line, etc. The "Uninstall" feature makes it 
                easy to just get the Proxy CL totally out of the picture for
                these types of builds, then bring it back for later work by
                selecting "Install".


PROXY-CL.INI    ASCII configuration file for use with CL.EXE and STLTask.EXE.
                Edit this file as appropriate for your system, place it in the
                Windows directory (C:\Windows or C:\Winnt, etc.) and the
                will override the built-in settings of CL.EXE and STLTask.EXE.

STLFilt.pl:     The Perl script.

STLFilt.BAT     Low-bandwidth batch file utility to toggle the filtering
                control file. Say
                    stlfilt on
                or
                    stlfilt off
                to control filtering. Most useful when working from within
                Visual Studio (you can run STLFilt.BAT from a DOS window, or
                install options to invoke it directly into the VC++ "Tools"
                menu) or using makefiles. When compiling directly from the 
                command line, just choose between running CL or CL2 (CL2.EXE
                is the recommended name for the copy of the native CL.EXE).

                Note: STLFilt.BAT and STLTask.EXE cooperate, and may be run
                interchangeably to enable/disable Proxy CL filtering.

CL.cpp:         Source to the Proxy CL program.

STLTask-src.zip Source code to the STLTask utility. Installation of the
                wxWindows library is required to build STLTask.EXE.

CUSTOMIZE.txt:  Instructions for rebuilding CL.EXE and STLTask.EXE from
                their source code, and for using the STLFilt.bat batch file
                for enabling/disabling filtering.

Samples.zip     A slew of CPP files that draw various STL-related errors.
                Try 'em with and without the filter!

CL-log.txt      Revision log for CL.cpp and STLFilt.pl

STLTASK-log.txt Revision log for STLTask.cpp
                
README-STLport.txt
                Some notes regarding STLPort-specific filtering issues
                in the Perl script

=======
Purpose
=======

The idea is to shorten the length of VC++ STL-related error messages
so that the most vital information from a message fits within
the visible portion of the status bar line at the bottom of the Visual
Studio IDE (see item "4." in the section below entitled "The CUJ Article"
for instruction on enabling the status bar).

Lots of things you don't usually need to see are deleted, e.g.:

    --> The qualifiers "std::", "class", "struct", "__thiscall" and
        "__cdecl" disappear
    --> Iterators are radically shortened to either just "IT", "iter", or,
        for a container "cont", "cont::iter" (you pick which form to use).
        You can then typically deduce the type details from the remaining
        context of error messages
    --> Any functors of the form less<whatever> are deleted; others are left
        intact. Thus the default "less<...>" functors don't clutter the
        messages when dealing with associative containers
    --> strings, istreams and ostreams of <char>, their traits, etc. reduce
        to just "string", "istream", "ostream", etc. Ahhh!
    --> iostream iterators are recognized and abbreviated
    --> Allocators in type names totally disappear, and allocators in function
        parameter lists reduce to just "alloc" (good riddance...)
 
Currently, all standard and hash-based containers have been addressed,
for the distribution version of the VC++6 library, version 3.08 of the
Dinkumware library, STLPort 4.x *AND* Visual C++ 7 (".NET", currently in beta).

There are certainly cases I'll have overlooked, and some I just didn't know
how to filter. Feedback is welcome, but here's the disclaimer:

        The reason I wrote this was to make it possible to teach
        C++ using the Koenig/Moo approach without scaring away students
        due to outlandishly complicated STL error messages. Thus, the filter
        leaves enough information to isolate the *most common* errors (wrong
        number of arguments, wrong argument type, etc.) in standard container
        operations involving most everyday data types. STL power users
        are always free to disable filtering to track down errors where the
        deleted detail is needed, then re-enable filtering when such details
        may no longer be needed. Two methods are provided to enable/disable
        filtering:
            1) The STLFilt.BAT file is low-bandwidth
            2) the STLTask tray icon program is convenient to use and allows
                instantaneous installation/uninstallation/reinstallation of
                the Proxy CL at any time.
 
============
How it Works
============

1. Nuts and Bolts

When installed/active, the Proxy CL is found by the MSVC IDE and invoked as if
it were the native CL.EXE program. The Proxy CL checks for the existence of the
controlling toggle file (FILTERING.ON). If the toggle file is *not* detected,
the Proxy CL simply invokes the native CL.EXE (usually renamed to CL2.EXE) with
the same command arguments it was itself invoked with. This yields ordinary
error message output.

If the toggle file *is* detected AND the file type being compiled qualifies
for filtering (see the fourth item in the Bugs/Limitations section below for
details on how the Proxy CL makes this determination), then the Proxy CL sets 
up an interprocess pipe between the native CL.EXE and an invocation of Perl.
The native CL's output stream is then piped into the standard input of the
Perl process (executing the STLFilt.pl script) to simplify STL-related 
messages. The output of the Perl script is then captured by the MSVC IDE 
and displayed in its output area, while the process status code of the *native*
CL process controls the subsequent behavior of the IDE's build sequence.


2. Rationale

While the command-line processing that the Proxy CL has to perform is a bit on
the tricky side, it seems to now handle most MSVC-generated build scripts
satisfactorily (the exception being third-party-based builds, such as when
using tools such as TrueTime). The main benefit of the toggle file scheme I'm
using for enabling/disabling filtering is that it does not require constant
file renaming--my theory is that if major EXE files are constantly having to be
renamed, that is asking for trouble.

In the early days of the filter there were several persistent bugs in
the processing of MSVC-generated build scripts, so I did give STLTask (the 
taskbar utility) the power to install/uninstall the filter (see the description
of Active/Inactive in GLOSSARY.txt) to make it easier to run native 
builds unencumbered by Proxy CL bugs. This installation/uninstallation copies
either the Proxy CL (CL.STL) or the native CL (CL2.EXE) over CL.EXE.
Because of the possibility of crashes etc. in the middle of such operations, 
STLTask tries *real hard* to make sure the files remain in a consistent state. 
If there is any doubt as to the current status of the filter (installed or not 
installed?) upon startup, STLTask resets everything to the native MSVC 
configuration (Proxy CL uninstalled) by default.


===============
The CUJ Article
===============

For background information on the origins and philosophy of this package,
see my article in July, 2001 issue of The C/C++ Users Journal.
The article was the Web Feature for July, 2001--that means it is now
and forever available for viewing in its entirety on the CUJ web site, at
the following URL:
    http://www.cuj.com/articles/2001/0107/0107b/0107b.htm?topic=articles

Several substantive changes made to the software since the CUJ article was
frozen for publication render portions of the article out-of-date. They are:

    1. The iterator policy setting in STLFilt.pl was changed from a numeric
        value (1, 2 or 3) to a symbolic value (S, M or L). The original '1'
        setting corresponds to the new 'L' ("Long" or "Large" expansion), and
        the original '3' corresponds to the new 'S' ("Small" or "Short"
        expansion).  The new 'M' means, of course, "Medium" expansion. (Thanks
        to Scott Meyers for suggesting the use of symbolic, rather than
        numeric, designations.)
    2. The STLTask taskbar-based utility was added as a GUI-based alternative
        to the STLFilt.BAT batch file
    3. STLPort and VC7/.NET library support has been added to STLFilt.pl.
        The same Perl script now works with all four libraries.
    4. Hash-based containers are now supported (for all libraries that have
        them, anyway...i.e., all libraries *except* native VC6)
    5. The "fine-print status line" I mention in the article actually has a
        name, as I finally learned: the "status bar", and it is turned on and 
        off within Visual Studio via the Tools...Options...Workspace
        checkbox labeled "Display status bar". I recommend you leave it turned
        on; most of the time, this will alleviate the need to scroll the output
        window.
    6. The installation instructions in the article say to place the Proxy
        CL.EXE "somewhere along your system PATH". Beginning with v2.1 of
        CL.CPP (and v2.0 of STLTask), the Proxy CL should be placed directly
        into MSVC's bin directory (...\VC98\bin or ...\VC7\bin).
        See QUICKSTART.txt for the current installation procedure.
    7.  Precompiled versions of both CL.EXE and STLTask.EXE are now included 
        in the distribution. Both programs read configuration information at 
        startup from a config file (Proxy-CL.INI) placed into the Windows
        directory. If the config file is not present, then all options default
        to values configured in the source code and compiled into the programs.
        

================
Bugs/Limitations
================

==> Of the various Perl implementations out there, ActiveState seems to
    work best. I've had several reports of interprocess bugs when using
    the filter in conjunction with other Perls, such as MKS and Cygwin.
    Therefore, if you experience strange errors involving zombie Perl
    processes and such, first try installing and using ActiveState Perl
    for filtering. You should then still be able to use your *other*
    Perl(s) for whatever else you've been using them for.

==> There are some string-related STL errors I haven't yet figured out how
    to filter (see tstring.cpp in the samples.zip archive, for example). 
    If someone can suggest an approach to these kinds of constructs, I'd 
    be glad to try to handle them...

==> Support for indirect (@filename) command lines is limited to fairly
    typical cases; The proxy CL, when detecting @filename as the *only* 
    argument on the command line, opens the indirect file and looks at only
    the *last* item on the *last* line of it. Filtering is performed only if
    this item has an acceptable C++ extension (one of the entries in the
    filterExt array of strings). That name may have quotation marks around
    it. Thus, indirect command files with more than one line's worth of
    source file names (or when the source file is not the last thing on
    the last line) may behave incorrectly if there is a mixture of
    filtering-enabled and non-filtering-enabled extensions. So far, no one
    has reported to me any VC-generated projects that my scheme fails to
    properly process, but that doesn't necessarily mean it isn't going to
    happen...

    When the 1st command line arg to CL is *not* an indirect "@" filename,
    then it scans argv right-to-left looking for the first argument that is
    neither a filename with an "object file" extension (one of the strings
    in the objExt array) nor a string with no extension at all (assumes those
    are options). The decision whether to filter or not is made based on the
    first argument (working from right to left) that *isn't* one of those
    things.

==> Command lines containing escaped double-quotes, as in /D definitions,
    probably won't be handled correctly by CL. It now handles all '"' char-
    acters by prepending a backslash to them. Going further, so as to
    generally handle lines such as:
        ... /DHAIRY="Here's a double quote: \" and a backslash: \\"
    would require a full-blown state-driven parser here to handle *all* the
    permutations...for now, anyway, the only way to compile such lines is
    to uninstall the filter.

When any of the above issues arise and you wish to revert to standard
error messages, the easiest thing to do is use STLTask to "uninstall" the
proxy CL until you need filtering again. Then use STLTask to "install"
again. 

If you have problems relating to the project file issues described above,
you might try doing a "compile only" from Visual Studio, with filtering
enabled, instead of building a project.

==================
Debugging Features
==================

CL.CPP and STLTask.EXE have debugging features built-in. CL.CPP supports
runtime debug configuration: set the DEBUG configuration option to true 
to log status messages to a file named CL-dblog.txt in the directory 
configured by the DEBUG_DIR option. For project files, when debugging is
enabled CL.EXE will also make a copy of the temporary project file named
"atfile.txt" and place it into the DEBUG_DIR directory. This may help 
to determine why CL fails to properly handle a project build.

STLTask.CPP debugging must be configured at compile time. Set the DEBUG 
symbol to 1 and define the DEBUG_DIR symbol to the name of your
desired log file directory, and STLTask will log various status info to
a file named "debug.out" in the specified directory.

If you run into a situation where the Proxy CL fails, please let
me know so I can fix it. If you understand the problem and can describe the
circumstances, that's great...if not, I'd be glad to help figure out the
problem and hopefully fix CL for the future; please reduce the project to
the minimum possible configuration that results in CL failure, zip it up
and email it to me (leor@bdsoft.com). I'll do my best to determine the 
problem and correct it. This program is as reliable as it is now *only*
because folks like you informed me about the problems (and even fixed them
for me on many occasions!)

===============
Acknowledgments
===============


Thanks to:

Dave Smallberg for the error filtering idea (wish I'd thought of it myself)

Scott Meyers for putting on his ESTL seminar -- the event that
   inspired this project. 

Thomas Becker for writing the Win32 interprocess communication code in CL.CPP

The folks who took the time to email me with bugs and suggestions, and/or
helped with debugging:

    Thomas Becker
    Wilka
    Sam Saariste
    Scott Lewandowski
    Scott Meyers
    Tom Malcolmson
    Jan Stette
    Dominic Mathieu
    Michael Cook
    Andy Philpotts
    Rob Bishop
    John Hattan
    Derek Price
    Bill Torpey
    John Penney
    Jonathan Sambrook 
    Argos
    Matthew Douglass
    Dave Conrad
    Scott McCaskill
    Paul Suggs
    Karl Lean
    Benoit Goudreault-Emond

==========
My Courses
==========

For my day job, I teach on-site programming seminars. Specifically:


==> C++ for non-C Programmers
                   Very intensive, 5-day workshop teaching C++ for those who
                   have never programmed in C. 
                   Prerequisite: *SOME* programming experience, but it
                        doesn't matter in what language.
                   Note: My next course design project is to replace this
                   course with one that teaches C++ using the Koenig/Moo
                   approach. For now, I still teach C++ the old-fashioned way.

==> An Effective Introduction to the Standard Template Library (STL)
                   Course by Scott Meyers, who needs no introduction.
                   Teaches the STL to experienced C++ programmers. 4 Days.
                   Prerequisite: Real-world programming experience in C++. 

==> C++ and Object-Oriented Programming
                   5-Day course by Dan Saks, another C++ guru you probably
                   know about.
                   Teaches C++ assuming GOOD (working) knowledge of C. More in
                   depth on OO and C++ subtleties than the first course above.

==> Introduction to Programming in C
                   My own C programming course. Some programming experience
                   (not necessarily in C) is the only prerequisite.
                   4 or 5 days; 5 preferred.
                   What can I say? Not too many folks are still learning
                   "just" C anymore, but if you have two weeks available to
                   learn C++ in, it works out a lot better to take C first and
                   then the C++ and OOP course above than it does to cram
                   both C and C++ into one week. That is, at least until
                   I write a course based on the Keonig/Moo approach...

==> Object-Oriented Programming in Java
                   My (I'm co-author) Java course. Does NOT presume any C/C++
                   experience. Uses all public domain / shareware tools (Sun's
                   JDK, ModelWorks' JPadPro (awesome IDE!). 5 Days.
                   Everyone gets a CD full of Java goodies.
                   Again, presumes only some programming experience in SOME
                   language.

==> Introduction to Unix (2-3 days)
==> Korn Shell Programming (3 days)
==> Perl Programming (3 days)

                    I license materials for the three Unix courses above 
                    from a fellow instructor. Good, solid courses, all of 'em.
                    The Perl course is mostly platform-independent, but
                    includes some Unix-specific functionality.

To give feedback on this package, or get additional information on having one
of the courses listed above delivered at your site, please contact:

    Leor Zolman
    BD Software
    74 Marblehead Street
    North Reading, MA 01864-1527
    voice/FAX: 978-664-4178
    email: leor@bdsoft.com
    web: www.bdsoft.com

===============================================================================
