CSCI 344
Patterns and Substitution
Lab 13

I will not be in lab on May 4.  Labs 13 and 14 must be demonstrated in lab on May 11.

Write the following Perl scripts.  You may use the Internet as a reference for Perl and as a reference for UNIX/Linux commands, but you may not search for solutions to these problems--that would completely defeat the purpose of doing them.

Here is a link to a good intro to Perl:  perldoc.perl.org/perlintro.html

You may NOT use any UNIX/Linux command or utility to solve these problems.  They can all be solved with basic Perl.


1) (weight 3)  Novice C/C++ programmers often forget to include the code to prevent header files from being included multiple times.  In order to prevent multiple includes, one should insert this code in all .h file (assume the file is named foo.h):

#ifndef FOO_H
#define FOO_H

body of .h file goes here

#endif

Write a script that examines all .h files in the current directory and if necessary inserts the appropriate code to prevent a multiple include.  Do not alter the file if it correctly prevents multiple includes.  Sometimes novice programmers use the same identifier (FOO_H in the above example) in multiple .h files.  This mistake prevents this mechanism from working.

If a command line argument is given to your program, assume it is a directory name and consider all files dir/*.h

Perl has a function that is similar to the wildcard file completion in the Bash shell:

my @filenames = glob "*.h";

@filenames will now contain the names of all files in the current directory that end with .h (that is <period>h).  You can pass a full or partial pathname to glob.

Perl's rename function takes and old and new filename:   rename $filename, ${filename}.bak


2) (weight 3)  Write a Perl script that renames a class in a C++ program.  The first argument will be the old class name.  The second argument will be the new class name.  If there are no more arguments, consider all the .h and .cpp files in the current directory.  If there are more arguments (without a -d) then each is a file your program should consider.  If a -d is given, then assume the next argument is a directory, and consider all .h and .cpp files in that directory.

$ rname Expression_tree Expression
$ rname Expression_tree Expression a.h a.cpp b.h b.cpp c.h c.cpp
$ rname Expression_tree Expression -d /home/tyson/src/gpl

Rename the files named <original>.h and <original>.cpp

For example:

expression_tree.h --> expression.h
Expression_tree.h --> Expression.h

Rename all reference to <original> in the given (or implicitly given) files

For example:

Expression_tree --> Expression
expression_tree  --> expression
EXPRESSION_TREE --> EXPRESSION
expression_trees --> expressions

Note: assume that there are not stupid capitalization schemes like:  eXprEsSiON

If no files are given or found, print an error and give up.

Hint: the <> operator uses the @ARGV array.  If you manipulate the @ARGV array and use the $^I construct, it will be easier to implement.