08
Jun
12

Auto-generate C++ Classes Using Perl, Part I

This is the first part of a post about a short utility I have written in Perl. I use it to generate C++ header and source files with method stubs depending on the arguments given. In this post I will be explaining some more general Perl techniques I use that aren’t specific to this file.

For reference you can download the full source here.

Usage

Here is the documentation section at the top of the file.

#D
#D  dgc_header: Create a dummy C++ file
#D
#&  Usage: dgc_header <name> <options> <file-types>
#&         dgc_header -help
#D
#D  -help       - Summarise command syntax
#D  -doc        - Print this quick reference manual
#D  <name>      - Name of class, function or file
#D  <options>
#D    -q -query : ask the user for function names, return values and arguments
#D  <file-type> - Types of file to be generated:-
#D    -header   : Generate <name>.h
#D    -source   : Generate <name>.C
#D
#D  Note: this will overwrite any files with the same name as the created files
#D        as standard.

This is all comments so I am only including this here to show the method I use to get usage or help text from perl scripts. The following are the functions I use to parse the file itself to output help text. That way the usage only needs to be in one place.

This is a snippet from the start to get the location of the script.

use Cwd 'abs_path';
$self_prog = abs_path($0);

The variable self_prog is the location of the file being run. This is then used in one of two functions, print_help() or print_usage(). These vary only in how much detail they go into. The function print_usage() will only print the comments denoted by #& but print_help() will print comments of the types #& and #D. I will only show print_help() here but print_usage() is at line 263 in the file.

#------------------------------------------------------------------------------
sub print_help()
{
  open(INPUT,"$self_prog");
  while(<INPUT>) {
    if(/^#[D\&]/) {
      s/^#[D\&]  //;
      s/^#[D\&]//;
      warn $_;
      }
    }
  close(INPUT);
}

This function does the following. It will read each line of the file and check if the file begins with a # followed by either a D or a &. If it does then it will print that line to standard output with the initial two characters and whitespace removed. It does this by using regular expressions and substitution. If you haven’t seen regular expressions before then this is a good tutorial on them.

Parsing Command Line Input

Parsing the help text from the file is all well and good but how are the functions called? I know that I’ve seen many ways of doing this in different scripts but this is the way that I find the easiest to use. This is of course a matter of opinion and stems from Perl’s there’s more than one way to do it philosophy. Here is my parse_input() function.

#------------------------------------------------------------------------------
sub parse_input() {
    while (defined($ARGV[0])) {
        $parse = $ARGV[0];
        for ($parse) {
            /^-h$/ || /^-help$/ and do {
                print_usage();
                print("For more info type dgc_header -doc\n");
                exit;
            };

            /^-doc$/ and do {
                print_help();
                exit;
            };
            /^-source$/ and do {
                $source = 1;
                shift @ARGV;
                last;
            };
            /^-header$/ and do {
                $header = 1;
                shift @ARGV;
                last;
            };
            /^-q$/ || /^-query$/ and do {
                $query = 1;
                shift @ARGV;
                last;
            };
            do {
                $class_name = $parse;
                shift @ARGV;
            };
        }
    }
}

This works by the following simple algorithm:

  1. Check if the array of command line arguments is defined, if it is not then end.
  2. Get the first item in the array.
  3. Check it against some pattern, if it matches do some operation on it then delete the first entry and go to 1.

I call parse_input() on entry to the script so that all the flags and variables are in the correct state before any operations are done. I use regular expressions in this loop because I feel they are one of the most unique and powerful utilities in Perl so I use them as often as I can.

As I have mentioned above and is clear from the title this is only part one of an article. This is because I have not said anything about the actual C++ code generation. Of course as I have included a link to the full source file you can always read ahead, otherwise the second part will be here shortly!

Not had enough perl? Here’s Part II. The source file is now script.

Advertisements

0 Responses to “Auto-generate C++ Classes Using Perl, Part I”



  1. Leave a Comment

What did you think?

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: