#! /packages/bin/perl
## $Id: makeopth.pl,v 3.6 1999/11/22 13:44:11 jt Exp $
## Automatically generates file opt_regt.c
## Automatically generates the part of opt.h that is between the lines
## BEGIN_AUTOGENERATED and END_AUTOGENERATED
## This is not expected to be part of the usual `make' process; it's
## just a convenience for the developer (me).

if (@ARGV) {
    print "Usage: cp opt.h tmp.h             ;; just in case!\n";
    print "       perl makeopth.pl\n";
    print "-> generates a new 'opt_regt.c', alters 'opt.h'\n";
    exit;
}


%oType = (
	  INT => "int ",
	  SHORT => "short ",
	  LONG => "long ",
	  CHAR => "char ",
	  UINT => "unsigned int ",
	  USHORT => "unsigned short ",
	  ULONG => "unsigned long ",
	  UCHAR => "unsigned char ",
	  FLOAT => "float ",
	  DOUBLE => "double ",
	  STRING => "char *",
	  );
	  
%oTypeAll = (
	  NUL => "void ",
	  %oType,
	  FLAG => "int ",
	  NEGFLAG => "int ",
	  ABSFLAG => "int ",
	  ABSNEGFLAG => "int ",
	  INTLEVEL => "int ",
	  CSTRING => "char ",
	  UNDELIM => "char *",
	  UNSINT => "unsigned int ",
	  VSTRING => "char *",
	  UNDELIMV => "char *",
	  UNDELIMC => "char ",
	  );

print "Making new opt_regt.c file...";

open(OPTU,"> opt_regt.c");
print OPTU "/* opt_regt.c */\n";
print OPTU "/* Note: this file generated automatically from makeopth.pl */\n";
print OPTU "/* Edits to this file may be lost! */\n";
print OPTU "#include \"opt.h\"\n";

$inlineint = "int"; ## 'inline int' doesn't work with g++
foreach $k (keys %oTypeAll) {
    print OPTU "$inlineint\n";
    print OPTU "optrega_$k($oTypeAll{$k}*v, char c, char *n, char *B) {\n";
    print OPTU "      return optrega(v,OPT_$k,c,n,B);\n}\n";
    print OPTU "$inlineint\n";
    print OPTU "optreg_$k($oTypeAll{$k}*v, char c, char *B) {\n";
    print OPTU "      return optreg(v,OPT_$k,c,B);\n}\n";
    print OPTU "$inlineint\n";
    print OPTU "optregc_$k($oTypeAll{$k}*v, char c) {\n";
    print OPTU "      return optregc(v,OPT_$k,c);\n}\n";
    print OPTU "$inlineint\n";
    print OPTU "optregs_$k($oTypeAll{$k}*v, char *n) {\n";
    print OPTU "      return optregs(v,OPT_$k,n);\n}\n";
    print OPTU "$inlineint\n";
    print OPTU "optregcb_$k($oTypeAll{$k}*v, char c, char *B) {\n";
    print OPTU "      return optregcb(v,OPT_$k,c,B);\n}\n";
    print OPTU "$inlineint\n";
    print OPTU "optregsb_$k($oTypeAll{$k}*v, char *s, char *B) {\n";
    print OPTU "      return optregsb(v,OPT_$k,s,B);\n}\n";
}
close OPTU;

print "ok\n";

## used for C++ version: opt_reg.cc and opt_cc.h
my $ior="int OptRegister";

print "Making new opt_regcc.c file...";

open(OPTCC,"> opt_regcc.c");
print OPTCC "/* opt_regcc.c */\n";
print OPTCC "/* Note: this file generated automatically from makeopth.pl */\n";
print OPTCC "/* Edits to this file may be lost! */\n";
print OPTCC "/* C++ bindings for opt */\n";
print OPTCC "#ifdef __cplusplus\n";
print OPTCC "#include <string.h>\n";
print OPTCC "#include \"opt.h\"\n";

foreach $k (keys %oType) {
    print OPTCC "$ior($oType{$k}*v, char c, char *n=0, char *B=0)\n";
    print OPTCC "{\n";
    print OPTCC "    if(!n) {n=strdup(\".\"); n[0]=c; n[1]='\\0';}\n";
    print OPTCC "    if(!B) {B=strdup(n); }\n";
    print OPTCC "    return optrega(v,OPT_$k,c,n,B);\n";
    print OPTCC "}\n";
    print OPTCC "$ior($oType{$k}*v, char *n=0, char *B=0)\n";
    print OPTCC "{\n";
    print OPTCC "    if(!B) {B=strdup(n); }\n";
    print OPTCC "    return optregsb(v,OPT_$k,n,B);\n";
    print OPTCC "}\n";
    print OPTCC "$ior($oType{$k}*v, opt_TYPE o, char c, char *n=0, char *B=0)\n";
    print OPTCC "{\n";
    print OPTCC "    if(!n) {n=strdup(\".\"); n[0]=c; n[1]='\\0';}\n";
    print OPTCC "    if(!B) {B=strdup(n); }\n";
    print OPTCC "    return optrega(v,o,c,n,B);\n";
    print OPTCC "}\n";
    print OPTCC "$ior($oType{$k}*v, opt_TYPE o, char *n, char *B=0)\n";
    print OPTCC "{\n";
    print OPTCC "    if(!B) {B=strdup(n); }\n";
    print OPTCC "    return optregsb(v,o,n,B);\n";
    print OPTCC "}\n";
}
print OPTCC "#endif /* __cpluscplus */\n";
close OPTCC;

print "ok\n";

#################################################################3
print "Altering opt.h file...";

open(OPTH,"opt.h");
open(NEW,">tmp-opt.h");
$ag=0;
while (<OPTH>) {
    if (/BEGIN_AUTOGENERATED/) {
	$ag=1;
    }
    print NEW if ($ag == 0);
    if (/END_AUTOGENERATED/) {
	print NEW "/* BEGIN_AUTOGENERATED */\n";
	print NEW "#ifdef __cplusplus\nextern \"C\" {\n#endif\n";
	foreach $k (keys %oTypeAll) {
	    print NEW "#define $k OPT_$k /* ...but use the OPT_$k */\n";
	    print NEW "extern int ";
	    print NEW "optrega_$k($oTypeAll{$k}*v, char c, char *n, char *B);\n";
	    print NEW "extern int ";
	    print NEW "optreg_$k($oTypeAll{$k}*v, char c, char *B);\n";
	    print NEW "extern int ";
	    print NEW "optregc_$k($oTypeAll{$k}*v, char c);\n";
	    print NEW "extern int ";
	    print NEW "optregs_$k($oTypeAll{$k}*v, char *n);\n";
	    print NEW "extern int ";
	    print NEW "optregcb_$k($oTypeAll{$k}*v, char c, char *B);\n";
	    print NEW "extern int ";
	    print NEW "optregsb_$k($oTypeAll{$k}*v, char *s, char *B);\n";
	}
	print NEW "#ifdef __cplusplus\n}\n";

	print NEW "/* OptRegister() only available on C++ systems */\n";
	foreach $k (keys %oType) {
	    print NEW "extern $ior($oType{$k}*v,";
	    print NEW " char c, char *n=0, char *B=0);\n";
	    print NEW "extern $ior($oType{$k}*v,";
	    print NEW " char *n, char *B=0);\n";
	    print NEW "extern $ior($oType{$k}*v,";
	    print NEW " opt_TYPE o, char c, char *n=0, char *B=0);\n";
	    print NEW "extern $ior($oType{$k}*v,";
	    print NEW " opt_TYPE o, char *n, char *B=0);\n";
	}

	print NEW "#endif /* __cplusplus */\n";
	print NEW "/* END_AUTOGENERATED */\n";
	$ag=0;
    }
}
close OPTH;
close NEW;

open(OPTH,">opt.h");
open(NEW,"tmp-opt.h");
while (<NEW>) {
    print OPTH;
}
close OPTH;
close NEW;
unlink "tmp-opt.h";

print "ok\n";

__END__
    
      



	
