#!/usr/bin/perl # VBDebug # Copyright (c) 1998 Peter Santoro use strict; use Cwd; require 5.003; my $VERSION = 1.01; # Initialize variables my $inputDirectory = "."; my $outputDirectory = "vbdebug"; my $filename; my @dirStack; # validate input directory if( @ARGV > 0 ) { $inputDirectory = $ARGV[0]; die $0 . " error: invalid input directory " . $inputDirectory . "\n" unless -d $inputDirectory; } # create output directory push( @dirStack, Cwd::getcwd() ); chdir( $inputDirectory ); mkdir( $outputDirectory, 00666 ); if( ! ( -d $outputDirectory ) ) { chdir( pop( @dirStack ) ); die $0 . " error: can't create output directory " . $inputDirectory . "\\" . $outputDirectory . "\n"; } # loop through VB source files and insert VB debugging code while ( $filename = < *.bas *.cls *.frm > ) { my $prompt = $inputDirectory . "\\" . $outputDirectory . "\\" . $filename . "\n"; print( $prompt ); open( INFILE, $filename ); translateFile( $filename, $outputDirectory . "\\" . $filename ); close( INFILE ); } chdir( pop( @dirStack ) ); exit; # ---------------------------------------------------------- sub translateFile($$) { # translate source file my( $infile, $outfile ) = @_; # get parameters my $funcType; my $funcName; my $lineno = 0; open ( OUTFILE, ">$outfile" ); while( $_ = ) { print( OUTFILE $_ ); $lineno++; if( atStartOfFuncOrSubOrProp( \$funcType, \$funcName ) ) { outputProlog( $infile, $funcType, $funcName, \$lineno ); locateEndOfFuncOrSubOrProp( \$lineno ); outputEpilog( $infile, $funcType, $funcName, \$lineno ); } } close OUTFILE; } sub outputProlog($$$$) { my( $infile, $functype, $funcname, $lineno ) = @_; # get parameters my $loc; $$lineno += 4; print( OUTFILE "\n#If fDebug Then\n" ); print( OUTFILE " If fTraceEnabled Then\n" ); $loc = "[" . $infile . ":" . "$$lineno" . "] "; print( OUTFILE " OutputDebugString\( \"" . $loc . "Entering ".$functype." ".$funcname."\" \+ chr\(10\) \)\;\n" ); print( OUTFILE " End If\n" ); print( OUTFILE "#End If\n\n" ); $$lineno += 3; } sub outputEpilog($$$$) { my( $infile, $functype, $funcname, $lineno ) = @_; # get parameters my $loc; $$lineno += 4; print( OUTFILE "\n#If fDebug Then\n" ); print( OUTFILE " If fTraceEnabled Then\n" ); $loc = "[" . $infile . ":" . "$$lineno" . "] "; print( OUTFILE " OutputDebugString\( \"" . $loc . "Leaving ".$functype." ".$funcname."\" \+ chr\(10\) \)\;\n" ); print( OUTFILE " End If\n" ); print( OUTFILE "#End If\n\n" ); print( OUTFILE $_ ); # output last line of function, sub, or property $$lineno += 4; } sub locateEndOfFuncOrSubOrProp($) { my( $lineno ) = @_; # get parameters $_ = ; while( ! atEndOfFuncOrSubOrProp() ) { print( OUTFILE $_ ); $$lineno++; $_ = ; } } sub atStartOfFuncOrSubOrProp($$) { my @list; my( $functype, $funcname ) = @_; # get parameters if( $_ =~ /^\s*(Public|Private)\s+(Sub|Function|Property)/i ) { @list = split( /\s+|\(/, $_); $$funcname = $list[2]; $$functype = $list[1]; 1; } elsif( $_ =~ /^\s*(Sub|Function|Property)/i ) { @list = split( /\s+|\(/, $_); $$funcname = $list[1]; $$functype = $list[0]; 1; } else { 0; } } sub atEndOfFuncOrSubOrProp() { if( $_ =~ /^\s*End\s+(Sub|Function|Property)/i ) { 1; } else { 0; } } # ---------------------------------------------------------- __END__ =head1 NAME VBDebug =head1 DESCRIPTION This script inserts trace statements into Visual Basic source code. It can be used to assist the programmer with debugging Visual Basic applications. At runtime, trace messages are sent to VB's debugging window. A future version may support logging to a file. =head1 README Please rename this distribution to VBDebug.pl before using. Usage: perl VBDebug.pl [VB-source-directory] - if used, the optional parameter C is the directory containing the VB source code to be translated - otherwise the current directory is assumed Notes: This script was not designed to undo previous VBDebug translations. Instead, it creates its translated source C<*.BAS, *.CLS, *.FRM> files in a C subdirectory. Your original source files are not modified. This design is safer and was easier to implement (no undo required) than the alternative which directly modifies your original source files. Therefore, you should always run this script against untranslated VB source code. As a precaution, you might want to run this script against a copy of your source files. A conditional compilation variable C is used to control whether the inserted trace statements will be compiled into your application. In addition, the C boolean is used to toggle tracing on or off at runtime. You must add the C boolean to your source code and enable the conditional compilation variable C. This script has been tested with source code produced by Visual Basic 4.0 and 5.0. Limitations of current release: 1. Script ignores Exit Sub, Exit Function, and Exit Property keyword combinations 2. Lacks support for logging to a file =head1 PREREQUISITES This script requires the C and C modules and C or better. =head1 OSNAMES MSWin32 =head1 SCRIPT CATEGORIES Win32 Win32/Utilities =head1 VERSION 1.01 =head1 HISTORY Version 1.01 ------------ - Updated documentation. Version 1.00 ------------ - Released. =head1 AUTHOR Peter Santoro peter@pscomp.com =head1 COPYRIGHT Copyright (c) 1998 Peter Santoro. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself; however, you must leave this copyright statement intact. =head1 DATE December 23, 1998 =head1 SOURCE This distribution can also be found at the author's web site http://www.connix.com/~psantoro/ =cut