N.B. You will only get one stack overflow exception.
The stack is left in an unstable state (the guard page at the
end of the stack has been converted to a normal stack page but
there is no room for a new guard page below it).
The next stack fault will walk off the bottom of the stack and the process
will be terminated immediately, no debugger, no nothing.
=for html
=item *
Reduce case 2 false positives from bitfield declarations
=item *
Catch as part of case 3:
if (x |= Y)
=back
=head1 HOW TO GET MORE COMPLETE RESULTS
You'll have to do some work and specify the behaviour of
your private functions to the Perl script via one of the L.
You should place these options in an optionfile so you don't have to enter them
repeatedly.
If you have a function, C, that allocates memory and returns the allocated memory,
you would use the C option, i.e. C.
=head1 QUICK START
=over 4
=item 1
If you don't have Perl installed, install the latest
=for html Win32 version from ActiveState
=item 2
=for html
Copy typo.pl to your machine.
=item 3
Copy either win32.txt or ce.txt to your machine.
=item 4
Go to the topmost directory in your source and type the following:
perl c:\bin\typo.pl -optionfile:c:\bin\win32.txt c >c:\temp\typo.out
=item 5
To view the script's output, use any text editor or the typo viewer app
=back
=head1 USAGE
=over 4
=item To examine all text files from the current directory down
perl typo.pl
=item To examine a list of files from STDIN
perl typo.pl -
C will examine
all writable text files in a directory
=for html

=item To examine all C/C++ files in the current directory down
perl typo.pl c
=item To examine a single file
perl typo.pl
the path to filename can be a partial or full path
=for html

=item To ignore certain files:
perl typo.pl -ignore:[,[,...]]
ignores filenames that match the given patterns
'*' is only valid wilcard character
=for html

=item To scan files that have a modification date/time later than given
perl typo.pl -newer:,, ,,
scans files that have a mod. date/time later than
given, i.e. -newer:1998,1,31,4,30 => Jan 31, 1998 04:30
=for html

=item To print out the time when the script starts and stops scanning
perl typo.pl -showtime
=item To print out the # of comments and which functions were seen
perl typo.pl -showstats
=item To print out the file that the script is currently processing
perl typo.pl -showprogress
=item To enable nonbuffered output
perl typo.pl -nonbuffered
=item To enable line-by-line disabling of specific cases
perl typo.pl -notypo
Code must be annotated with the word "NO_TYPO"
on the line to be disabled for typo reporting.
To specify certain cases to be disabled, use
the format S where XX, YY
represent the specific cases that are disabled.
=for html

=item To check the results of additional functions
perl typo.pl -cfr:[,[,...]]
scans results of specified functions to see
if they are used before they have been checked for success
=for html

=item To use a text file to specify a list of options
perl typo.pl -optionfile:
reads in all the lines of the specified file and parses
each line as a possible option
=for html

=item To specify directories to look for option files
perl typo.pl -optiondir:[,[,...]]
specifies directories to be searched if the option file
cannot be found in the current directory. This option should
be specified before -optionfile. If directories are not
specified with trailing backslashes, then backslashes
will be appended.
=for html

=item To add to list that checks on function results
perl typo.pl -checked:[,[,...]]
informs script that the specified functions will
check the result from previous function calls
so there's no need to report use before check typo
i.e. if you specify C, then
x = malloc(16);
foobar(x);
won't report a typo.
=for html

=item To add to list that doesn't deref/access function results
perl typo.pl -noderef:[,[,...]]
informs script that the specified functions will
not dereference the result from previous function calls
so there's no need to report use before check typo yet.
i.e. if you specify C, then
x = malloc(16);
Output("%8.8lX\n", x);
won't report a typo yet.
=for html

=item To add to list that checks on function results similar to operator new
perl typo.pl -new:[,[,...]]
informs script that the specified functions behave
similar to C for case 34.
=for html

=item To check the results of functions that return handles
perl typo.pl -fn:HANDLE:[,[,...]]
scans results of specified functions to see
if they're used before they've been checked
for success and if the result is compared to
C.
=for html

=item To check the results of functions that return HRESULTs
perl typo.pl -fn:HR:[,[,...]]
scans results of specified functions to see
if they're used before they've been checked for success
and if the result is tested via
C or C macros.
=for html

=item To add to the function list that return the length of strings
perl typo.pl -fn:LEN:[,[,...]]
scans for use of specified functions that are used for
finding the lengths of null-terminated strings
=for html

=item To add to the function list that could overflow buffers
perl typo.pl -fn:OVERFLOW:[,[,...]]
scans for use of specified functions that can overflow
buffers passed to them
=for html

=item To add to the function list that behaves like C
perl typo.pl -fn:REALLOC:[,[,...]]
scans for use of specified functions that behave
like realloc (case 17)
=for html

=item To add to the function list that are ignorable asserts
perl typo.pl -fn:SAFEASSERT:[,[,...]]
specifies assert functions that are ignored for case 4
=item To add to the function list that can throw exceptions
perl typo.pl -fn:THROW:[,[,...]]
scans for specified functions to see if they're used in a C
=for html

=item To add to the function list that don't return a value
perl typo.pl -fn:VOID:[,[,...]]
prevents reports of case 32 for functions that don't
return a value.
=for html

=item To add to the function list that terminate a case statement
perl typo.pl -endcase:[,[,...]]
informs script that the specified functions behave
similar to C statement for case 19.
=for html

=item To add to list of #defines that may not be always defined
perl typo.pl -temp_defined:[,[,...]]
informs script that the specified defines may
not always be available.
=for html

=item To specify that C, C, C, C,
C, and C preprocessor directives should be handled
perl typo.pl -ifdef
There should be accompanying use of the C option B you want
the script to never check code within C's, C's, etc.
=for html

=item To specify symbols and their values for C, C, C, and C
preprocessor directives, use the C option:
perl typo.pl -define:[=]
This must be used with the C option
=for html

=item To print out metrics about the scanned files:
perl typo.pl -kloc:[1 | 2]
=over 4
=item 1
specifies functionality and display similar to Code metric app
=item 2
specifies functionality and display similar to Code metric app but also
displays the number of functions in a file.
=back
=for html
=item To specify that string constants should be extracted from the scanned files:
perl typo.pl -extract_strings:[c | m | r | s]
=over 4
=item C
specifies strings from C/C++ source code files should be extracted
=item C
specifies strings from message compiler (.MC) files should be extracted
=item C
specifies strings from resource (.RC, .RCV, .DLG) files should be extracted
=item C
specifies that the strings should be stripped,
mostly removing escaped character constants, Menu accelerators, and strings that
look like filenames
=back
=item To print out help
perl typo.pl -help
perl typo.pl -h
perl typo.pl -?
=item To specify the version of the typo.pl script required
perl typo.pl -version:
=back
=head1 ERRORS
Following potential programming errors are flagged:
=over 4
=item 1
semicolon appended to an if statement
if (x == y);
exit(1);
=item 2
use of C<==> instead of C<=> in assignment statements, handles C/C too.
X == Y;
X - NULL;
=item 3
assignment of a number in an if statement, probably meant a comparison
if (x = 3)
=item 4
assignment within an Assert
ASSERT(Z = 4);
=item 5
increment/decrement of ptr, ptr's contents not modified, may have meant to modify ptr's contents
*ptr++;
=item 6
logical AND with a number
x = y && 1;
=item 7
logical OR with a number
x = y || 2;
=item 8
bitwise-AND/OR/XOR of number compared to another value
may have undesired result due to C precedence rules since bitwise-AND/OR/XOR has lower precedence than
the comparison operators.
if (x & 1 == 0)
=item 9
referencing C/C instead of invoking them
punk->Release;
=item 0
whitespace following a line-continuation character
#define X stuff \
=item 1
shift or mod operator ( <>, % ) followed by +,-,*,/ may
have undesired result due to C precedence rules.
The shift operator has lower precedence.
x = (y << 1 + 1);
is seen by the compiler as
x = y << (1 +1);
=item 2
very basic check for uninitialized vars in for-loops
for (ULONG i; i; ++i)
=item 3
misspelling Microsoft
Copyright 1999 Micorsoft Corporation
=item 4
swapping the last two args of C may set 0 bytes
memset(buf, nCount, 0);
=item 5
swapping the last two args of C may set 0 bytes
FillMemory(pAction, 0, sizeof(Action));
=item 6
LocalReAlloc/GlobalReAlloc may fail without MOVEABLE flag
pv1 = LocalReAlloc(pv, cbNew, 0);
=item 7
assigning result of realloc to same var that's realloced
may result in leaked memory if realloc fails since C
will overwrite original value
p = (char *)realloc(p, 100);
=item 9
ReAlloc flags in wrong place or using ReAlloc flags for
a different realloc API,
pv1 = LocalReAlloc(pv, cbNew, GMEM_MOVEABLE);
i.e. passing C to C, it's not
an error to the compiler, but I'd say you were
playing with fire.
=item 9
C statement without a C/C/C/C
case 2:
Foo();
case 3:
Bar();
break;
If you add a comment with the text C or C
before the next case statement, then the script will not emit a warning.
=item 0
comparing C return value vs C for failure
problem is that C returns C
on failure
hFile = CreateFile(...);
if (hFile == NULL)
=item 1
casting a 32-bit number (may not be 64-bit safe)
if (p == (HANDLE)0xffffffff)
=item 2
casting a 7-digit hex number with high-bit set of
first digit, may have meant to add an extra digit?
if (p == 0xfff0000)
=item 3
comparing functions that return handles to
C for failure, problem is that
these functions return C on failure
h = CreateFileMapping(...);
if (h == INVALID_HANDLE_VALUE)
=item 4
comparing C/C/C/C return value
to anything other than C, which is the
documented return value when a failure occurs.
fh = OpenFile(...);
if (fh < 0)
=item 5
comparing C result to C is wrong since C
fails by throwing an exception, not returning C.
pv = alloca(10);
if (pv == NULL)
{
goto Done;
}
=item 6
C fails by throwing an exception, so check to
see if C is within a C
BOOL foo(void)
{
PVOID pv;
pv = alloca(10);
return bar(pv);
}
=for html
N.B. You will only get one stack overflow exception.
The stack is left in an unstable state (the guard page at the
end of the stack has been converted to a normal stack page but
there is no room for a new guard page below it).
The next stack fault will walk off the bottom of the stack and the process
will be terminated immediately, no debugger, no nothing.
=for html

=item 7
check to see if the result from C or
C is checked at the first if-stmt.
hwnd = CreateWindow(...);
ShowWindow(hwnd, SW_SHOW);
N.B. I'd like to make this more flexible, as long as
the return value is checked before the value is used.
=item 8
check for multiple inequality comparisons of the same
var separated by "||",
i.e. C
in this case, if x == 0, the second comparison will
succeed and the code will enter the if-stmt body.
Programmer probably meant C instead of C.
=item 9
similar to 28, check for cases of the form:
if ((x == 0) && (x == 1))
=item 0
if a function result is used before it has
been checked for success
pv = LocalAlloc(...);
strcpy(pv, sz);
=item 1
check for use of C/C
strcpy(d, s);
=item 2
check to see if function result was stored somewhere
=item 3
trying to take the logical inverse of a number
x = !3;
=item 4
if the result from the C operator is used before
it has been checked for success
p = new CLASS;
p->DoIt();
=item 5
function that throws exception on error is not
in a C.
void foo()
{
InitializeCriticalSection(&crit);
.
.
.
}
=item 6
check for misspelled defined symbols. User must do
most of the investigative work. The script will
note all the symbols used in C,C,C,C
statements and print them out at the end.
=item 7
check for bitwise-Cing one number with another
x = 10 ^ 2;
=item 8
wrong flags used with C
MapViewOfFile(hfileMap, PAGE_READWRITE, 0, 0, 0x1000);
should be
MapViewOfFile(hfileMap, FILE_MAP_WRITE, 0, 0, 0x1000);
=item 9
wrong flags used with C
CreateFile(szFile, FILE_MAP_WRITE, ...);
should be
CreateFile(szFile, GENERIC_READ | GENERIC_WRITE, ...);
=item 0
duplicate flags passed to C
CreateFile(szFile, GENERIC_WRITE | GENERIC_WRITE, ...);
=item 1
complain about returning unchecked function results
=item 2
using C function result w/no check
=item 3
double semicolon
x = 0;;
=item 4
calculating memory needed incorrectly by
using C instead of C
c = strlen(sz+1);
p = malloc(c);
if (p) strcpy(p, sz);
=item 5
assigning C to C field of C
should use C (= -1)
var.boolVarl = TRUE;
=item 6
empty statement after C/C loop
while (pFoo);
=item 7
use of C, probably meant C
C/C++ precedence rules have C before C
if (!x & 3)
=item 8
testing a #define for a value instead of existence
=item 9
test a char for C<0> instead of C, i.e.
user meant to test for null terminator instead of number 0
=item 0
use of a disallowed function
TerminateThread();
=item 1
use of a disallowed string
=item 2
filling object with zeros
memset(this, 0, sizeof(this));
=back
=head1 MICROSOFT VISUAL STUDIO INTEGRATION
=over 4
=item 1
Select Tools.Customize menu item from MSDEV
=item 2
Click the Add button.
=item 3
Type "Typo" in the edit control and hit OK. Ignore the warning
about invalid path.
=item 4
In the Command edit control, enter perl.exe. Specify the
full pathname to perl.exe if it isn't on your PATH.
=item 5
In the Arguments edit control, enter the path to typo.pl.
=item 6
In the initial directory edit control, select one of the
directory entries from the dropdown menu, i.e. File Directory,
Current Directory, Target Directory, or Workspace Directory,
or enter a directory of your own.
=item 7
Make sure the "Redirect to Output Window" checkbox is set.
=item 8
Hit Close.
=back
You can now run TYPO.PL from Visual Studio and double-click on the
captured output to have it locate the potential error for you.
=head1 HISTORY
=over 4
=item Jan 06 1996
Created.
=for html

=item Jan 26 1996
Repeatedly replace parenthesized expressions (PE)
with '_' for errors 1 and 2.
Tweak C<==> case to remove PEs before checking
for unbalanced parentheses or lines that begin
with &&,||,==, or = * ==.
Tweak C<==> case to check previous line for
unterminated for-loop or line ending with
C or C.
=for html

=item Jan 29 1996
Adjust error 1 and 3 regexp so script
can find errors of the form C or
C
Print line number of error too
Released as Version 1.0.
=for html

=item Feb 08 1996
Suggestion:
Look for assignment within an C
Modify output so one can use typo.pl from Microsoft Visual Studio
to locate errors
Released as Version 1.0.1.
=for html

=item Apr 04 1996
Suggestion:
Look for pattern of the form C
Suggestion:
For assignment statements that use C<==>,
ignore previous lines which look like part of
C :> constructs or an assignment.
Check for C or C. Authour probably meant
to use bitwise versions.
Remove spaces from a copy of the current line to
make patterns simpler.
Allow user to specify list of files by piping
list of files to perl, i.e. C.
=for html