| 1 | #!/usr/bin/perl | 
| 2 | # | 
| 3 | # Usage: sfmakedepend [-s] [-e ext] [-f file] [-I incdir] [-d objdir] | 
| 4 | #                     [-m mod_ext] [-c] [-p] [-g] [-h] [-o obj_ext] | 
| 5 | #                     [-a add_ext] file ... | 
| 6 | # | 
| 7 | # This is a makedepend script for Fortran, including Fortran 90. | 
| 8 | # It searches for Fortran style includes, C preprocessor includes, | 
| 9 | # and module dependencies to the extent that I understand them. | 
| 10 | # | 
| 11 | # Your files must have an extension listed in the @suffixes list | 
| 12 | # below.  You might also want to modify $compile_string if you use | 
| 13 | # the -c or -p option.  I call the compiler $(CFT) for historical | 
| 14 | # reasons. | 
| 15 | # | 
| 16 | # The switch [-s] is for stupid Fortran compilers that don't know | 
| 17 | # how to automatically send things through the C preprocessor. | 
| 18 | # It is possible to force 'make' to invoke 'cpp' to create a .f | 
| 19 | # file from a .F file (which has cpp directives), but make won't | 
| 20 | # know that a .f file will depend on the files that the .F file | 
| 21 | # included.  This option will provide those dependencies. | 
| 22 | # | 
| 23 | # The [-e ext] switch is used with the [-s] switch for compilers | 
| 24 | # which expect an extension other than .f on source files.  For | 
| 25 | # instance, for the Connection Machine one would use "-e fcm". | 
| 26 | # | 
| 27 | # The [-f file] switch is used to change the name of the current | 
| 28 | # Makefile. | 
| 29 | # | 
| 30 | # The [-I incdir] option tells sfmakedepend to look in alternate | 
| 31 | # directories for the include files.  There can be several "-I dir" | 
| 32 | # options used at once.  The current directory is still searched | 
| 33 | # first. | 
| 34 | # | 
| 35 | # The [-d objdir] option tells sfmakedepend that the object and | 
| 36 | # module files will be built in a separate directory from the sources. | 
| 37 | # | 
| 38 | # The [-m mod_ext] option tells sfmakedepend what extension to | 
| 39 | # use for Fortran 90 module files.  The default for "use My_Mod" | 
| 40 | # is to list the dependency as "my_mod.mod" since this is what | 
| 41 | # NAG f90 and IBM xlf both use.  Let me know if other compilers | 
| 42 | # use a different filename for the module information. | 
| 43 | # | 
| 44 | # The [-c] option specifies that the Cray compiler is being used. | 
| 45 | # This compiler requires a "-p file.o" option for each object file | 
| 46 | # that contains a module used by your current source file. | 
| 47 | # | 
| 48 | # The [-p] option specifies that the Parasoft compiler is being used. | 
| 49 | # This compiler requires a "-module file.o" option for each object file | 
| 50 | # that contains a module used by your current source file. | 
| 51 | # | 
| 52 | # The [-g] option specifies that the SGI compiler is being used. | 
| 53 | # This compiler names the module file in uppercase with the extension | 
| 54 | # .kmo. | 
| 55 | # | 
| 56 | # The [-h] option specifies that the HP compiler is being used. | 
| 57 | # This compiler names the module file in uppercase with the extension | 
| 58 | # .mod (added by Patrick Jessee who also fixed an include bug). | 
| 59 | # | 
| 60 | # The [-o obj_ext] option tells sfmakedepend what extension to use for | 
| 61 | # object files.  The default is "o", but "obj", for instance, is | 
| 62 | # appropriate on MS-DOG etc.  This option was added by Dave Love. | 
| 63 | # | 
| 64 | # The [-a add_ext] option (also added by Dave Love) tells sfmakedepend | 
| 65 | # to add targets with extension add_ext to the rules for object files. | 
| 66 | # For instance, to operate with (f77) ftnchek .prj files, you could use | 
| 67 | # `-a prj' to get rules like: | 
| 68 | # foo.prj foo.o: ... | 
| 69 | # | 
| 70 | # The final arguments contain the list of source files to be | 
| 71 | # searched for dependencies. | 
| 72 | # | 
| 73 | # EXAMPLE | 
| 74 | #       sfmakedepend -I /usr/local/include *.F | 
| 75 | # | 
| 76 | # NOTES | 
| 77 | #       This makedepend script is my first attempt at using perl 5 | 
| 78 | #       objects.  Therefore, it may not be the best example of how | 
| 79 | #       to do this.  Also, it requires perl 5 and will die if you | 
| 80 | #       to use it with an older perl.  The latest version is | 
| 81 | #       available from: | 
| 82 | # | 
| 83 | #               http://marine.rutgers.edu/po/perl.html | 
| 84 | #               ftp://ahab.rutgers.edu/pub/perl/sfmakedepend | 
| 85 | # | 
| 86 | #       Fortran 90 introduces some interesting dependencies.  Two | 
| 87 | #       compilers I have access to (NAG f90 and IBM xlf) produce a | 
| 88 | #       private "mod_name.mod" file if you define "module mod_name" | 
| 89 | #       in your code.  This file is used by the compiler when you | 
| 90 | #       use the module as a consistency check (type-safe).  On the | 
| 91 | #       other hand, the Cray and Parasoft compilers store the module | 
| 92 | #       information in the object file and then files which use the | 
| 93 | #       modules need to be compiled with extra flags pointing to the | 
| 94 | #       module object files. | 
| 95 | # | 
| 96 | #       This script assumes that all the files using and defining | 
| 97 | #       modules are in the same directory and are all in the list of | 
| 98 | #       files to be searched.  It seems that the industry has not | 
| 99 | #       settled on a practical way to deal with a separate modules | 
| 100 | #       directory, anyway. | 
| 101 | # | 
| 102 | #       I sometimes include non-existent files as a compile time | 
| 103 | #       consistency check: | 
| 104 | # | 
| 105 | #          #ifndef PLOTS | 
| 106 | #          #include "must_define_PLOTS"       /* bogus include */ | 
| 107 | #          #endif | 
| 108 | # | 
| 109 | #       This program warns about include files it can't find, but | 
| 110 | #       not if there is a "bogus" on the same line. | 
| 111 | # | 
| 112 | #     * The f90 module dependencies can confuse some versions of | 
| 113 | #       make, especially of the System V variety.  We use gnu | 
| 114 | #       make because it has no problems with these dependencies. | 
| 115 | # | 
| 116 | # BUGS | 
| 117 | #       It can sometimes produce duplicate dependencies. | 
| 118 | # | 
| 119 | #       It treats C preprocessor includes the same as Fortran | 
| 120 | #       includes.  This can add unnecessary dependencies if you | 
| 121 | #       use the -s flag and both kinds of includes. | 
| 122 | # | 
| 123 | #       Please let me know if you find any others. | 
| 124 | #       Kate Hedstrom | 
| 125 | #       kate@ahab.rutgers.edu | 
| 126 | # | 
| 127 |  | 
| 128 | package source_file; | 
| 129 |  | 
| 130 | # hashes containing names of included files, modules in files | 
| 131 | %inc_files = (); | 
| 132 | %main::mod_files = (); | 
| 133 |  | 
| 134 | # Constructor | 
| 135 | sub new { | 
| 136 | my $type = shift; | 
| 137 | my $filename = shift; | 
| 138 | my $path = shift; | 
| 139 | my $self = {}; | 
| 140 | $self->{'source_file'} = $filename; | 
| 141 | $self->{'filepath'} = $path; | 
| 142 | $self->{'includes'} = {}; | 
| 143 | $self->{'uses'} = {}; | 
| 144 | $self->{'modules'} = {}; | 
| 145 | bless $self; | 
| 146 | } | 
| 147 |  | 
| 148 | sub find_includes { | 
| 149 | my $self = shift; | 
| 150 | my $file = $self->{'filepath'}; | 
| 151 | my($after, $filepath, $ref, $included, $use, $modname); | 
| 152 | local(*FILE); | 
| 153 | local($_); | 
| 154 |  | 
| 155 | if (-f $file) { | 
| 156 | open(FILE, $file) || warn "Can't open $file: $!\n"; | 
| 157 | } elsif (-f "RCS/$file,v" || -f "$file,v" ) { | 
| 158 | system("co $file"); | 
| 159 | open(FILE, $file) || warn "Can't open $file: $!\n"; | 
| 160 | $main::rcs{$file} = 1; | 
| 161 | } else { | 
| 162 | return; | 
| 163 | } | 
| 164 | while (<FILE>) { | 
| 165 | $included = ""; | 
| 166 | $use = ""; | 
| 167 | # look for Fortran style includes | 
| 168 | if (/^\s*include\s*['"]([^"']*)["']/i) { | 
| 169 | $included = $1; | 
| 170 | $after = $'; | 
| 171 | # C preprocessor style includes | 
| 172 | } elsif (/^#\s*include\s*["<]([^">]*)[">]/) { | 
| 173 | $included = $1; | 
| 174 | $after = $'; | 
| 175 | # Fortran 90 "use" | 
| 176 | } elsif (/^\s*use\s+(\w+)/i) { | 
| 177 | $use = $1; | 
| 178 | # Make the module name lowercase except for SGI & HP. | 
| 179 | # May be compiler dependent!! | 
| 180 | if ($main::sgi || $main::hp) { | 
| 181 | $use = uc($use); | 
| 182 | } else { | 
| 183 | $use = lc($use); | 
| 184 | } | 
| 185 | $self->{'uses'}{$use} = 1; | 
| 186 | # Fortran 90 module | 
| 187 | } elsif (/^\s*module\s+(\w+)/i) { | 
| 188 | $modname = $1; | 
| 189 | if ($main::sgi || $main::hp) { | 
| 190 | $modname = uc($modname); | 
| 191 | } else { | 
| 192 | $modname = lc($modname); | 
| 193 | } | 
| 194 | unless (lc($modname) eq "procedure") { | 
| 195 | $main::mod_files{$modname} = $file; | 
| 196 | $self->{'modules'}{$modname} = 1; | 
| 197 | } | 
| 198 | } | 
| 199 | if ($included) { | 
| 200 | if ( $inc_files{$included} ) { | 
| 201 | $filepath = $inc_files{$included}{'filepath'}; | 
| 202 | } else { | 
| 203 | $filepath = &main::findfile($included); | 
| 204 | $ref = new source_file($included, $filepath); | 
| 205 | $inc_files{$included} = $ref; | 
| 206 | # Search included file for includes | 
| 207 | $ref->find_includes(); | 
| 208 | } | 
| 209 | if ( $filepath ) { | 
| 210 | $self->{'includes'}{$included} = 1; | 
| 211 | } else { | 
| 212 | if ($after !~ /bogus/i) { | 
| 213 | warn "Can't find file: $included\n"; | 
| 214 | } | 
| 215 | } | 
| 216 | } | 
| 217 | } | 
| 218 | close FILE; | 
| 219 | } | 
| 220 |  | 
| 221 | sub print_includes { | 
| 222 | my $self = shift; | 
| 223 | my $target = shift; | 
| 224 | my $len_sum = shift; | 
| 225 | my $objdir = shift; | 
| 226 | my($file, $ref); | 
| 227 | my %printed = (); | 
| 228 |  | 
| 229 | foreach $file (keys %{$self->{'includes'}}) { | 
| 230 | next if $printed{$file}; | 
| 231 | $ref = $inc_files{$file}; | 
| 232 | my $len = length($ref->{'filepath'}) + length($objdir) + 2; | 
| 233 | if (($len_sum + $len > 80) && | 
| 234 | (length($target) + length($objdir) + 2 < $len_sum)) { | 
| 235 | print "\n" . $objdir . "/" . "$target:"; | 
| 236 | $len_sum = length($target) + length($objdir) + 2; | 
| 237 | } | 
| 238 | print " " . $objdir . "/" . $ref->{'filepath'}; | 
| 239 | $printed{$file} = 1; | 
| 240 | $len_sum += $len; | 
| 241 | $len_sum = $ref->print_includes($target, $len_sum, $objdir); | 
| 242 | } | 
| 243 | $len_sum; | 
| 244 | } | 
| 245 |  | 
| 246 | # return list of modules used by included files | 
| 247 | sub inc_mods { | 
| 248 | my $self = shift; | 
| 249 | my($file, $ref, $mod, @sub_list); | 
| 250 | my @list = (); | 
| 251 | my %printed = (); | 
| 252 |  | 
| 253 | foreach $mod (keys %{$self->{'uses'}}) { | 
| 254 | push(@list, $mod); | 
| 255 | } | 
| 256 |  | 
| 257 | foreach $file (keys %{$self->{'includes'}}) { | 
| 258 | next if $printed{$file}; | 
| 259 | $ref = $inc_files{$file}; | 
| 260 | $printed{$file} = 1; | 
| 261 | @sub_list = $ref->inc_mods(); | 
| 262 | @list = (@list, @sub_list); | 
| 263 | } | 
| 264 | @list; | 
| 265 | } | 
| 266 |  | 
| 267 | # filenames containing the list of modules used by file and all its includes | 
| 268 | sub find_mods { | 
| 269 | my $self = shift; | 
| 270 | my($ref, $modname, $file, @list, $base); | 
| 271 | my @module_files = (); | 
| 272 | my @mod_list = (); | 
| 273 | my @tmp_list = (); | 
| 274 |  | 
| 275 | # find modules used by include files | 
| 276 | if (%{$self->{'includes'}}) { | 
| 277 | foreach $file (keys %{$self->{'includes'}}) { | 
| 278 | $ref = $inc_files{$file}; | 
| 279 | @list = $ref->inc_mods(); | 
| 280 | @tmp_list = @mod_list; | 
| 281 | @mod_list = (@tmp_list, @list); | 
| 282 | } | 
| 283 | } | 
| 284 |  | 
| 285 | # add them to the uses list (hash ensures uniqueness) | 
| 286 | foreach $modname (@mod_list) { | 
| 287 | $self->{'uses'}{$modname} = 1; | 
| 288 | } | 
| 289 |  | 
| 290 | # now find the filename that contains the module information | 
| 291 | foreach $modname (keys %{$self->{'uses'}}) { | 
| 292 | if ($main::cray || $main::parasoft) { | 
| 293 | if ($file = $main::mod_files{$modname}) { | 
| 294 | $base = &main::basename($file, @main::suffixes); | 
| 295 | $file = $base . "." . $main::obj_ext; | 
| 296 | push(@module_files, $file); | 
| 297 | } else { | 
| 298 | warn "Don't know where module $modname lives.\n"; | 
| 299 | } | 
| 300 | } else { | 
| 301 | $modname .= "." . $main::mod_ext; | 
| 302 | push(@module_files, $modname); | 
| 303 | } | 
| 304 | } | 
| 305 | sort(@module_files); | 
| 306 | } | 
| 307 |  | 
| 308 | sub print { | 
| 309 | my $self = shift; | 
| 310 | my $objdir = shift; | 
| 311 | my $source = $self->{'source_file'}; | 
| 312 | my $compile_string = "\t" . '$(CFT) $(FFLAGS) -c'; | 
| 313 | my($base, $object, $modname, $flag, $target, $ftarget); | 
| 314 |  | 
| 315 | $base =  &main::basename($source, @main::suffixes); | 
| 316 | $target = $base . "." . $main::obj_ext; | 
| 317 | if ($main::stupid) { | 
| 318 | $ftarget = $base . "." . $main::ext; | 
| 319 | } | 
| 320 |  | 
| 321 | if ($main::cray) { | 
| 322 | $flag = " -p "; | 
| 323 | } elsif ($main::parasoft) { | 
| 324 | $flag = " -module "; | 
| 325 | } | 
| 326 |  | 
| 327 | # print out "include" dependencies | 
| 328 | if (%{$self->{'includes'}}) { | 
| 329 | my $len_sum = length($target) + 1; | 
| 330 | if ($main::add_ext) { | 
| 331 | $target .= " $base.$main::add_ext"; | 
| 332 | $len_sum += length($base) + length($main::add_ext) + 2; | 
| 333 | } | 
| 334 | print $objdir . "/" . "$target:"; | 
| 335 | $self->print_includes($target, $len_sum, $objdir); | 
| 336 | print "\n"; | 
| 337 | if ($main::stupid) { | 
| 338 | $len_sum = length($ftarget) + 1; | 
| 339 | print $objdir . "/" . "$ftarget:"; | 
| 340 | $self->print_includes($ftarget, $len_sum, $objdir); | 
| 341 | print "\n"; | 
| 342 | } | 
| 343 | } | 
| 344 |  | 
| 345 | # clean out "use" of modules in own file | 
| 346 | foreach $mod ( keys %{$self->{'uses'}} ) { | 
| 347 | if ( ${$self->{'modules'}}{$mod} ) { | 
| 348 | delete ${$self->{'uses'}}{$mod}; | 
| 349 | } | 
| 350 | } | 
| 351 |  | 
| 352 | # print out "use" dependencies | 
| 353 | if (%{$self->{'uses'}} || %{$self->{'includes'}}) { | 
| 354 | @module_files = $self->find_mods(); | 
| 355 | my $len_sum = length($target) + length($objdir) + 2; | 
| 356 | print $objdir . "/" . "$target:"; | 
| 357 | foreach $file (@module_files) { | 
| 358 | my $len = length($objdir) + length($file) + 2; | 
| 359 | if (($len_sum + $len > 80) && | 
| 360 | (length($objdir) + length($target) + 2 < $len_sum)) { | 
| 361 | print "\n" . $objdir . "/" . "$target:"; | 
| 362 | $len_sum = length($objdir) + length($target) + 2; | 
| 363 | } | 
| 364 | $len_sum += $len; | 
| 365 | print " " . $objdir . "/" . $file; | 
| 366 | } | 
| 367 | if ($main::need_f) { | 
| 368 | my $len = length($ftarget) +length($objdir) + 2; | 
| 369 | if (($len_sum + $len > 80) && | 
| 370 | (length($target) +length($objdir) + 2 < $len_sum)) { | 
| 371 | print "\n" . $objdir . "/" . "$target:"; | 
| 372 | $len_sum = length($target) +length($objdir)+ 2; | 
| 373 | } | 
| 374 | print " " . $objdir . "/" . $ftarget; | 
| 375 | } | 
| 376 | print "\n"; | 
| 377 | # extra Cray / Parasoft stuff | 
| 378 | if ($main::cray || $main::parasoft) { | 
| 379 | print $compile_string; | 
| 380 | foreach $file (@module_files) { | 
| 381 | print $flag . $file; | 
| 382 | } | 
| 383 | if ($main::stupid) { | 
| 384 | print " " . $ftarget . "\n"; | 
| 385 | } else { | 
| 386 | print " " . $source . "\n"; | 
| 387 | } | 
| 388 | } | 
| 389 | } | 
| 390 | } | 
| 391 |  | 
| 392 |  | 
| 393 | # Start of main program | 
| 394 | package main; | 
| 395 |  | 
| 396 | if ($] < 5.000) { die "Need perl 5.000 or newer\n"; } | 
| 397 | use File::Basename; | 
| 398 | use Getopt::Long; | 
| 399 | @suffixes = qw( .c .C .cc .cxx .cpp .f .F .fcm .FCM .f90 .F90 .for); | 
| 400 |  | 
| 401 | GetOptions("s", "e=s", "f=s", "I=s@", "d=s", "m=s", "c", "p", "g", "h", "o=s", "a=s") | 
| 402 | || die "problem in GetOptions"; | 
| 403 |  | 
| 404 | # For compilers that don't invoke cpp for you | 
| 405 | if ($opt_s) { | 
| 406 | $stupid = 1; | 
| 407 | } | 
| 408 | if ($opt_e) { | 
| 409 | $ext = $opt_e; | 
| 410 | } else { | 
| 411 | $ext = "f"; | 
| 412 | } | 
| 413 |  | 
| 414 | # list of directories to search, starting with current directory | 
| 415 | if (@opt_I) { | 
| 416 | @incdirs = @opt_I; | 
| 417 | } elsif (@opt_i) { | 
| 418 | @incdirs = @opt_i; | 
| 419 | } | 
| 420 |  | 
| 421 | if ($opt_D) { | 
| 422 | $objdir = $opt_D; | 
| 423 | } elsif ($opt_d) { | 
| 424 | $objdir = $opt_d; | 
| 425 | } | 
| 426 |  | 
| 427 | if ($opt_f) { | 
| 428 | $mf = $opt_f; | 
| 429 | } elsif (-f "makefile") { | 
| 430 | $mf = 'makefile'; | 
| 431 | } else { | 
| 432 | $mf = 'Makefile'; | 
| 433 | } | 
| 434 | if ( !(-f $mf)) { | 
| 435 | system "touch $mf"; | 
| 436 | } | 
| 437 |  | 
| 438 | # extension used for compiler's private module information | 
| 439 | if ($opt_m) { | 
| 440 | $mod_ext = $opt_m; | 
| 441 | } else { | 
| 442 | $mod_ext = 'mod'; | 
| 443 | } | 
| 444 |  | 
| 445 | if ($opt_c) { | 
| 446 | $cray = 1; | 
| 447 | } | 
| 448 |  | 
| 449 | if ($opt_p) { | 
| 450 | $parasoft = 1; | 
| 451 | } | 
| 452 |  | 
| 453 | if ($opt_g) { | 
| 454 | $sgi = 1; | 
| 455 | $mod_ext = 'kmo'; | 
| 456 | } | 
| 457 |  | 
| 458 | if ($opt_h) { | 
| 459 | $hp = 1; | 
| 460 | } | 
| 461 |  | 
| 462 | # need to add some more dependencies so the .f file gets created | 
| 463 | if ($stupid && ($cray || $parasoft)) { | 
| 464 | $need_f = 1; | 
| 465 | } | 
| 466 |  | 
| 467 | if ($opt_c && $opt_p) { | 
| 468 | die "Doesn't make sense to have both Cray and Parasoft options!"; | 
| 469 | } | 
| 470 |  | 
| 471 | # object file extension | 
| 472 | if ($opt_o) { | 
| 473 | $obj_ext = $opt_o; | 
| 474 | } else { | 
| 475 | $obj_ext = 'o'; | 
| 476 | } | 
| 477 |  | 
| 478 | # extension for additional targets (like .prj) | 
| 479 | if ($opt_a) { | 
| 480 | $add_ext = $opt_a; | 
| 481 | } | 
| 482 |  | 
| 483 | $mystring = '# DO NOT DELETE THIS LINE - used by make depend'; | 
| 484 |  | 
| 485 | # Search for the includes in all the files | 
| 486 | foreach $file (@ARGV) { | 
| 487 | $sources{$file} = new source_file($file, $file); | 
| 488 | $sources{$file}->find_includes(); | 
| 489 | } | 
| 490 |  | 
| 491 | # Create new Makefile with new dependencies. | 
| 492 |  | 
| 493 | open(MFILE, $mf) || die "can't read Makefile $mf: $!\n"; | 
| 494 | open(NMFILE, "> Makefile.new") || die "can't write Makefile.new: $!\n"; | 
| 495 | select(NMFILE); | 
| 496 |  | 
| 497 | while (<MFILE>) { | 
| 498 | if (!/$mystring/) { | 
| 499 | print; | 
| 500 | } else { | 
| 501 | last; | 
| 502 | } | 
| 503 | } | 
| 504 |  | 
| 505 | # comment this out if we are using make depend | 
| 506 | #print $mystring, "\n"; | 
| 507 |  | 
| 508 | # Now print out include and use dependencies in sorted order. | 
| 509 | foreach $target (sort keys(%sources)) { | 
| 510 | $sources{$target}->print($objdir); | 
| 511 | } | 
| 512 |  | 
| 513 | # print out module dependencies | 
| 514 | if ( !( $cray || $parasoft) ) { | 
| 515 | foreach $modname (sort keys(%mod_files)) { | 
| 516 | ($name, $path, $suffix) = | 
| 517 | &fileparse($sources{$mod_files{$modname}}->{'filepath'}, @suffixes); | 
| 518 | $object = $objdir . "/" . $name . "." . $obj_ext; | 
| 519 | print "$objdir/$modname.$mod_ext: $object\n"; | 
| 520 | } | 
| 521 | } | 
| 522 |  | 
| 523 | # Sort out the Makefiles | 
| 524 |  | 
| 525 | rename($mf, "$mf.old") || warn "can't overwrite $mf.old: $!\n"; | 
| 526 | rename('Makefile.new', $mf) || | 
| 527 | warn "can't move Makefile.new to $mf: $!\n"; | 
| 528 |  | 
| 529 | # Delete those RCS files we checked out | 
| 530 | foreach $file (keys %rcs) { | 
| 531 | unlink($file); | 
| 532 | } | 
| 533 |  | 
| 534 | # | 
| 535 | # End of main | 
| 536 | # | 
| 537 |  | 
| 538 | sub findfile { | 
| 539 | # Let's see if we can find the included file.  Look in current | 
| 540 | # directory first, then in directories from -I arguments.  Finally, | 
| 541 | # look for RCS files in current directory. | 
| 542 | my $file = shift; | 
| 543 | my($found, $i, $filepath); | 
| 544 |  | 
| 545 | $found = 0; | 
| 546 |  | 
| 547 | if ( -f $file ) { | 
| 548 | $found = 1; | 
| 549 | $file =~ s#^\./##;          # convert ./foo.h to foo.h | 
| 550 | return $file; | 
| 551 | } | 
| 552 | foreach $i (0 .. $#incdirs) { | 
| 553 | $filepath = $incdirs[$i]."/".$file; | 
| 554 | if ( -f $filepath ) { | 
| 555 | $found = 1; | 
| 556 | $filepath =~ s#^\./##;          # convert ./foo.h to foo.h | 
| 557 | return $filepath; | 
| 558 | } | 
| 559 | } | 
| 560 | #see if it is a checked-in RCS file | 
| 561 | if (-f "RCS/$file,v" || -f "$file,v" ) { | 
| 562 | $found = 1; | 
| 563 | system("co $file"); | 
| 564 | $filepath = $file; | 
| 565 | $rcs{$file} = 1; | 
| 566 | } | 
| 567 | if ( ! $found ) { | 
| 568 | $filepath = ""; | 
| 569 | } | 
| 570 | $filepath; | 
| 571 | } | 
| 572 |  |