#!/usr/bin/perl -w ##### # written by Niles Johnson, June 2007 # # defines one sub, CMR, and uses this to make # several GIFT files compatible with Mac OS # # developed for Mac OS 10.3.9, but may work # for later versions also # # the last file modification is similar to # the previous ones, but does not use the # CMR sub, because CMR can match only # single-line strings # # the last file modification uses a variant # of the CMR code which reads an entire file # at once, so that it can match a multi-line # string # # I would love to use the same sub for all of # these modifications, but file slurping is # notably slower than line-by-line reading # (although perhaps these files are so small) # (that this is irrelevant) ##### ##### # changes or additions to improve # this script are welcome! ##### use strict; sub CMR; # Check, Match, Replace sub CMR { ###### filename variables ###### # arguments are stored in array @_ my $arg = shift; # we will print output to temporary file my $tmp = "$arg.tmp.$$"; # and save original file my $bak = "$arg.bak"; ###### search/replace variables ###### # what we're doing my $doing = shift; # check string # (to see if this file has already # been modified by this sub) my $check = shift; # string to match: my $match = shift; # string which will replace match: my $replace = shift; ###### flagging ###### # we set flag to 1 if this file # is modified by this sub # # if the match string is not found # then the flag remains at 0 # # if the check string is found # then the flag remains at 0 # (or is set to 0) # and the loop quits # # the file is replaced by a # modified version only if the # flag is set to 1 by the end # of the while loop my $flag = 0; # default output, if no match occurs my $nomatch = " $doing pattern not found\n"; ###### and the execution ###### print "$arg: Checking $doing..\n"; open(FILE, "< $arg") or die " can't open $arg: $!\n"; open(NEW, "> $tmp") or die " can't open $tmp: $!\n"; # step through each line of FILE: while (){ # line is stored as default variable $_ chomp; # check (this line) for an indication that # this file has already been modified # # if the check matches, then set the flag to 0 # and exit this while loop if ($_ =~ /$check/){ print " $doing appears to have already been accomplished\n"; $nomatch = ""; $flag = 0; last; } # otherwise.. if (/$match/){ $flag = 1; $nomatch = ""; } # do the search/replace on this line s/$match/$replace/; # and print output to tmp file print NEW "$_\n"; } close(FILE) or die " can't close $arg: $!\n"; close(NEW) or die " can't close $tmp: $!\n"; # if match has succeeded and # check string has not been found.. if ($flag==1){ # backup the original file rename("$arg", "$bak") or die " can't rename $arg to $bak: $!\n"; # and move tmp file to replace original file rename("$tmp", "$arg") or die " can't rename $tmp to $arg: $!\n"; # and then notify user print " $doing is now APPLE compatible.\n"; } # otherwise, just notify the user and remove the tmp file else { print $nomatch; print " $doing appears to already be APPLE compatible.\n"; print " file has not been modified.\n"; `rm -f $tmp` } } #################################################### ################ end of sub ######################## #################################################### my @malloc_list = ( "libSquirePPM/new_executable.c", "libSquirePPM/ppm_comment.c", "libSquirePPM/ppm_error.c", "libSquirePPM/ppm_io.c", "libSquirePPM/ppm_memory.c", "libSquirePPM/ppm_normalize.c", "libSquirePPM/ppm_plane.c", "libSquirePPM/ppm_subimage.c", "FeatureExtraction/extract_block_features.c", "FeatureExtraction/extract_features.c", "FeatureExtraction/gabor.c", "FeatureExtraction/write_feature_descs.c" ); # malloc.h inclusion: my $file; foreach $file (@malloc_list) { # apply the Check/Match/Replace sub to files in list CMR( $file, #doing "malloc.h inclusion", #check "#ifdef __HAVE_MALLOC_H__", #match "#include ", # replace " #ifdef __HAVE_MALLOC_H__ #include #endif " ); } # values.h inclusion: CMR( "LibSquirePPM/ppm_normalize.c", "values.h inclusion", "#ifdef __HAVE_VALUES_H__", "#include ", " #ifdef __HAVE_VALUES_H__ #include #endif " ); # netinet/in.h inclusion: CMR( "GIFTServer/CTCPSocket.h", "netinet.h inclusion", "#ifdef __APPLE__", "#include ", "#include #ifdef __APPLE__ #include #endif " ); # locale exclusion: CMR( "scripts/perl/gift-add-collection.pre-pl", "locale exclusion", "# comment out for APPLE compatibility", "open LOCALELIST", "# comment out for APPLE compatibility # open LOCALELIST" ); # lib inclusion: CMR( "GIFTServer/Makefile.am", "LIB inclusion", "# for APPLE compatibility", "# include directories", "# for APPLE compatibility LIBS = -ldl # include directories" ); # lCredentials modification: # requires multiline (ml) match my $mlarg = "GIFTServer/CDomainSocket.cc"; my $mltmp = "$mlarg.tmp.$$"; my $mlbak = "$mlarg.bak"; ###### search/replace variables ###### my $mldoing = "lCredentials modification"; my $mlcheck = "#ifndef __APPLE__"; my $mlmatch1 = ' { struct ucred lCredentials;'; my $mlmatch2 = ' << "Group ID: " << lCredentials.gid << endl; } }'; my $mlreplace1 = "#ifndef __APPLE__\n".$mlmatch1; my $mlreplace2 = $mlmatch2."\n#endif\n"; ###### flagging ###### my $mlflag = 0; my $mlnomatch = " $mldoing pattern not found\n"; ###### and the execution ###### print "$mlarg: Checking $mldoing..\n"; open(FILE, "< $mlarg") or die " can't open $mlarg: $!\n"; open(NEW, "> $mltmp") or die " can't open $mltmp: $!\n"; # slurp FILE (read whole file instead of line by line): # save line termination character as variable $TermChar my $TermChar = $/; # undefine line termination character undef $/; # set variable $slurp to contents of file # (by default, sets variable only to first line of file) # (but with line termination character undefined) # (takes entire contents of file as "first line") my $slurp = ; # reset line termination character using saved value $/ = $TermChar; # check (whole file) for an indication that # this file has already been modified # # if the check matches, then set the flag to 0 # and exit this while loop if ($slurp =~ /$mlcheck/){ print " $mldoing appears to have already been accomplished\n"; $mlnomatch = ""; $mlflag = 0; } # otherwise.. else{ if (($slurp =~ /$mlmatch1/) && ($slurp =~ /$mlmatch2/)){ $mlflag = 1; $mlnomatch = ""; } # do the search/replace $slurp =~ s/$mlmatch1/$mlreplace1/; $slurp =~ s/$mlmatch2/$mlreplace2/; # and print output to tmp file print NEW "$slurp"; } close(FILE) or die " can't close $mlarg: $!\n"; close(NEW) or die " can't close $mltmp: $!\n"; # if match has succeeded and # check string has not been found.. if ($mlflag==1){ # backup the original file rename("$mlarg", "$mlbak") or die " can't rename $mlarg to $mlbak: $!\n"; # and move tmp file to replace original file rename("$mltmp", "$mlarg") or die " can't rename $mltmp to $mlarg: $!\n"; # and then notify user print " $mldoing is now APPLE compatible.\n"; } # otherwise, just notify the user and remove the tmp file else { print $mlnomatch; print " $mldoing appears to already be APPLE compatible.\n"; print " file has not been modified.\n"; `rm -f $mltmp` } __END__ # SAMPLE OUTPUT # first run: # libSquirePPM/new_executable.c: Checking malloc.h inclusion.. # malloc.h inclusion is now APPLE compatible. # libSquirePPM/ppm_comment.c: Checking malloc.h inclusion.. # malloc.h inclusion is now APPLE compatible. # libSquirePPM/ppm_error.c: Checking malloc.h inclusion.. # malloc.h inclusion is now APPLE compatible. # libSquirePPM/ppm_io.c: Checking malloc.h inclusion.. # malloc.h inclusion is now APPLE compatible. # libSquirePPM/ppm_memory.c: Checking malloc.h inclusion.. # malloc.h inclusion is now APPLE compatible. # libSquirePPM/ppm_normalize.c: Checking malloc.h inclusion.. # malloc.h inclusion is now APPLE compatible. # libSquirePPM/ppm_plane.c: Checking malloc.h inclusion.. # malloc.h inclusion is now APPLE compatible. # libSquirePPM/ppm_subimage.c: Checking malloc.h inclusion.. # malloc.h inclusion is now APPLE compatible. # FeatureExtraction/extract_block_features.c: Checking malloc.h inclusion.. # malloc.h inclusion is now APPLE compatible. # FeatureExtraction/extract_features.c: Checking malloc.h inclusion.. # malloc.h inclusion is now APPLE compatible. # FeatureExtraction/gabor.c: Checking malloc.h inclusion.. # malloc.h inclusion is now APPLE compatible. # FeatureExtraction/write_feature_descs.c: Checking malloc.h inclusion.. # malloc.h inclusion is now APPLE compatible. # LibSquirePPM/ppm_normalize.c: Checking values.h inclusion.. # values.h inclusion is now APPLE compatible. # GIFTServer/CTCPSocket.h: Checking netinet.h inclusion.. # netinet.h inclusion is now APPLE compatible. # scripts/perl/gift-add-collection.pre-pl: Checking locale exclusion.. # locale exclusion is now APPLE compatible. # GIFTServer/Makefile.am: Checking LIB inclusion.. # LIB inclusion is now APPLE compatible. # GIFTServer/CDomainSocket.cc: Checking lCredentials modification.. # lCredentials modification is now APPLE compatible. # second (or more) runs: # libSquirePPM/new_executable.c: Checking malloc.h inclusion.. # malloc.h inclusion appears to have already been accomplished # malloc.h inclusion appears to already be APPLE compatible. # file has not been modified. # libSquirePPM/ppm_comment.c: Checking malloc.h inclusion.. # malloc.h inclusion appears to have already been accomplished # malloc.h inclusion appears to already be APPLE compatible. # file has not been modified. # libSquirePPM/ppm_error.c: Checking malloc.h inclusion.. # malloc.h inclusion appears to have already been accomplished # malloc.h inclusion appears to already be APPLE compatible. # file has not been modified. # libSquirePPM/ppm_io.c: Checking malloc.h inclusion.. # malloc.h inclusion appears to have already been accomplished # malloc.h inclusion appears to already be APPLE compatible. # file has not been modified. # libSquirePPM/ppm_memory.c: Checking malloc.h inclusion.. # malloc.h inclusion appears to have already been accomplished # malloc.h inclusion appears to already be APPLE compatible. # file has not been modified. # libSquirePPM/ppm_normalize.c: Checking malloc.h inclusion.. # malloc.h inclusion appears to have already been accomplished # malloc.h inclusion appears to already be APPLE compatible. # file has not been modified. # libSquirePPM/ppm_plane.c: Checking malloc.h inclusion.. # malloc.h inclusion appears to have already been accomplished # malloc.h inclusion appears to already be APPLE compatible. # file has not been modified. # libSquirePPM/ppm_subimage.c: Checking malloc.h inclusion.. # malloc.h inclusion appears to have already been accomplished # malloc.h inclusion appears to already be APPLE compatible. # file has not been modified. # FeatureExtraction/extract_block_features.c: Checking malloc.h inclusion.. # malloc.h inclusion appears to have already been accomplished # malloc.h inclusion appears to already be APPLE compatible. # file has not been modified. # FeatureExtraction/extract_features.c: Checking malloc.h inclusion.. # malloc.h inclusion appears to have already been accomplished # malloc.h inclusion appears to already be APPLE compatible. # file has not been modified. # FeatureExtraction/gabor.c: Checking malloc.h inclusion.. # malloc.h inclusion appears to have already been accomplished # malloc.h inclusion appears to already be APPLE compatible. # file has not been modified. # FeatureExtraction/write_feature_descs.c: Checking malloc.h inclusion.. # malloc.h inclusion appears to have already been accomplished # malloc.h inclusion appears to already be APPLE compatible. # file has not been modified. # LibSquirePPM/ppm_normalize.c: Checking values.h inclusion.. # values.h inclusion appears to have already been accomplished # values.h inclusion appears to already be APPLE compatible. # file has not been modified. # GIFTServer/CTCPSocket.h: Checking netinet.h inclusion.. # netinet.h inclusion appears to have already been accomplished # netinet.h inclusion appears to already be APPLE compatible. # file has not been modified. # scripts/perl/gift-add-collection.pre-pl: Checking locale exclusion.. # locale exclusion appears to have already been accomplished # locale exclusion appears to already be APPLE compatible. # file has not been modified. # GIFTServer/Makefile.am: Checking LIB inclusion.. # LIB inclusion appears to have already been accomplished # LIB inclusion appears to already be APPLE compatible. # file has not been modified. # GIFTServer/CDomainSocket.cc: Checking lCredentials modification.. # lCredentials modification appears to have already been accomplished # lCredentials modification appears to already be APPLE compatible. # file has not been modified.