#!/usr/local/bin/perl chop($date = `date`); $copywrite = <<"EOQ"; /* * Created by fab.pl * on $date * Copyright (C) 1994 Karl J. Runge */ EOQ # script to process Input Template and FABricate header file, with # 1) 'global' data structure with member for each parameter # 2) function to read in data parameters from a file # 3) function to write in data parameters stdout. # Usage: fab.pl [template] [C and header file basename] # Example Template: # npass= 200 nwarm= 20 nblks= 20 seed= -234567 # T= 1.23 H= 0.00 J= 1.00 # dim= 2 lattice= square pbc= 1 # nx= 4 ny= 4 # logfile= rover.n.out # IN SHORT: if you add "X= 5" into the above template file, fab adds "int X" # as a global variables and makes code to read it in properly. print STDERR ">>Into Fab<<\n"; if ( $#ARGV == -1 ) { # Get infile and outfile names $IN = 'input.template'; $OUT_C = 'input.c'; $OUT_H = 'input.h'; } elsif ( $#ARGV == 0 ) { $IN = $ARGV[0]; $OUT_C = 'input.c'; $OUT_H = 'input.h'; } else { $IN = $ARGV[0]; $OUT_C = "$ARGV[1]".'.c'; $OUT_H = "$ARGV[1]".'.h'; } open(IN, "$IN") || die "can't open $IN"; open(OUT_C, ">$OUT_C") || die "can't open $OUT_C"; open(OUT_H, ">$OUT_H") || die "can't open $OUT_H"; print OUT_C "$copywrite"; print OUT_H "$copywrite"; print OUT_C <<'EOQ'; #include #include "input.h" /* Define External Variables */ EOQ @IN = ; close(IN); foreach (@IN) { $_ =~ s/=/ /g; } $struct = "typedef struct input {\t\t/* Declare Struct Typedef */\n"; $global = "INPUT in;\n"; $extern = "\t\t\t\t/* External Variables */\n"."extern $global"; $fproto = "\t\t\t\t/* Function Prototypes */\n"; $funct = <<'EOQ'; INPUT* ReadInput(char *fname) { char s[10][50]; INPUT *p_in; FILE *fpin; if ( strcmp(fname,"stdin") == 0 ) { fpin = stdin; } else { fpin = fopen(fname,"r"); } p_in = (INPUT *) malloc( (unsigned) sizeof(INPUT) ); EOQ $funcp = <<'EOQ'; void WriteInput(INPUT *p_in, char *fname) { FILE *fpout; int close = 1; if ( strcmp(fname,"stdout") == 0 ) { fpout = stdout; close = 0; } else { fpout = fopen(fname,"w"); } EOQ $copyover = ''; foreach (@IN) { @words = split(/\s+/, $_); $fscanf = "\tfscanf(fpin, \""; $printf = "\tfprintf(fpout, \""; $varlist = ""; $prtlist = ""; for ($i = 0, $j = 0; $i < (@words/2); $i++) { $key = $words[$j++]; $val = $words[$j++]; ($type_pre, $type_post, $fmt) = &fmt($val); $struct .= "\t$type_pre$key$type_post;\n"; $global .= "$type_pre$key$type_post;\n"; $extern .= "extern $type_pre$key$type_post;\n"; $fscanf .= "%s $fmt"; $printf .= "$key\t$fmt"; $varlist .= "\t\t,s[$i], &$key\n"; $prtlist .= "\t\t, p_in->$key\n"; if ( $type_pre =~ /char/ ) { $copyover .= "\tstrcpy(p_in->$key, $key);\n"; } else { $copyover .= "\tp_in->$key = $key;\n"; } } chop($fscanf); $funct .= $fscanf; $funct .= "\"\n"; chop($varlist); $funct .= $varlist; $funct .= ");\n\n"; chop($printf); $funcp .= $printf; $funcp .= "\\n\"\n"; chop($prtlist); $funcp .= $prtlist; $funcp .= ");\n"; } $fproto .= <<'EOQ'; INPUT* ReadInput(char *fname); void WriteInput(INPUT *p_in, char *fname); EOQ $struct .= <<'EOQ'; } INPUT; EOQ $global .= "\n"; $extern .= "\n"; $funct .= "$copyover\n"; $funct .= <<'EOQ'; return(p_in); } EOQ $funcp .= "\tif(close) fclose(fpout);\n}\n"; print OUT_C $global; print OUT_C $funct; print OUT_C $funcp; print OUT_H $struct; print OUT_H $extern; print OUT_H $fproto; close(OUT_H); close(OUT_C); sub fmt { # sub to guess format of string, i.e. double, int, char[] local( $t1, $type_pre, $type_post, $fmt ); local($str) = @_; $t1 = $str; $t1 = $t1 + $t1; if ( $t1 != 0 || $str !~ /[A-z]/ ) { if ($str =~ /\./ || $str=~ /[eEdD]/ ) { $type_pre = "double "; $type_post = ""; $fmt = "%lf "; } else { $type_pre = "int "; $type_post = ""; $fmt = "%d "; } } else { $type_pre = "char "; $t1 = 4*length($str); # make it 4x for "safety" $type_post = "\[$t1\]"; $fmt = "%s "; } return ( ($type_pre, $type_post, $fmt) ); }