#! /usr/bin/perl
## $Id: makeopth.pl,v 3.13 2002/11/04 20:16:06 simes Exp $
## Automatically generates files opt_regt.c, opt_regcc.cc
## 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 "[ Make backups first! ]\n\n";
    print "Usage: perl makeopth.pl\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,
	  BOOL => "int ",
	  NEGBOOL => "int ",
	  TOGGLE => "int ",
	  NEGTOGGLE => "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 optcc.h
my $ior="int OptRegister";

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

open(OPTCC,"> opt_regcc.cc");
print OPTCC "/* opt_regcc.cc */\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 "#ifndef OPT_NOCPLUSINTERFACE\n";
print OPTCC "#ifdef __cplusplus\n";
print OPTCC "#include <cstring>\n";
print OPTCC "#include \"opt.h\"\n";
print OPTCC "using namespace std;\n";
foreach $k (keys %oType) {
    print OPTCC "$ior($oType{$k}*v, char c, char *n, char *B)\n";
    print OPTCC "{\n";
    print OPTCC "    return optrega(v,OPT_$k,c,n,B);\n";
    print OPTCC "}\n";
    print OPTCC "$ior($oType{$k}*v, char *n, char *B)\n";
    print OPTCC "{\n";
    print OPTCC "    return optrega(v,OPT_$k,'\\0',n,B);\n";
    print OPTCC "}\n";
    print OPTCC "$ior($oType{$k}*v, opt_TYPE o, char c, char *n, char *B)\n";
    print OPTCC "{\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)\n";
    print OPTCC "{\n";
    print OPTCC "    return optrega(v,o,'\\0',n,B);\n";
    print OPTCC "}\n";

    print OPTCC "$ior($oType{$k}*v, opt_MODE m, char c, char *n, char *B)\n";
    print OPTCC "{\n";
    print OPTCC "    int i = optrega(v,OPT_$k,c,n,B);\n";
    print OPTCC "    optmode_n(i, m);\n";
    print OPTCC "    return i;\n";
    print OPTCC "}\n";
    print OPTCC "$ior($oType{$k}*v, opt_MODE m, char *n, char *B)\n";
    print OPTCC "{\n";
    print OPTCC "    int i = optrega(v,OPT_$k,'\\0',n,B);\n";
    print OPTCC "    optmode_n(i, m);\n";
    print OPTCC "    return i;\n";
    print OPTCC "}\n";
    print OPTCC "$ior($oType{$k}*v, opt_TYPE o, opt_MODE m, char c, char *n, char *B)\n";
    print OPTCC "{\n";
    print OPTCC "    int i = optrega(v,o,c,n,B);\n";
    print OPTCC "    optmode_n(i, m);\n";
    print OPTCC "    return i;\n";
    print OPTCC "}\n";
    print OPTCC "$ior($oType{$k}*v, opt_TYPE o, opt_MODE m, char *n, char *B)\n";
    print OPTCC "{\n";
    print OPTCC "    int i = optrega(v,o,'\\0',n,B);\n";
    print OPTCC "    optmode_n(i, m);\n";
    print OPTCC "    return i;\n";
    print OPTCC "}\n";
}
print OPTCC "#endif /* __cpluscplus */\n";
print OPTCC "#endif /* OPT_NOCPLUSINTERFACE */\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 "\n/* Define the symbol OPT_NOCPLUSINTERFACE to disable the opt C++ interface */\n";
	print NEW "/* when compiling C++ programs. You may need this if your C++ */\n";
	print NEW "/* is broken! */\n";
	print NEW "#ifndef OPT_NOCPLUSINTERFACE\n\n";
	print NEW "/* OptRegister() only available on C++ systems */\n";
	print NEW "#ifdef __cplusplus\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 "extern $ior($oType{$k}*v,";
	    print NEW " opt_MODE m, char c, char *n=0, char *B=0);\n";
	    print NEW "extern $ior($oType{$k}*v,";
	    print NEW " opt_MODE m, char *n, char *B=0);\n";
	    print NEW "extern $ior($oType{$k}*v,";
	    print NEW " opt_TYPE o, opt_MODE m, char c, char *n=0, char *B=0);\n";
	    print NEW "extern $ior($oType{$k}*v,";
	    print NEW " opt_TYPE o, opt_MODE m, char *n, char *B=0);\n";
	}
	print NEW "#endif /*__cplusplus */\n";
	print NEW "#endif /* OPT_NOCPLUSINTERFACE */\n";
	print NEW "\n/* The following prototypes are deprecated and may be removed some day */\n";
	print NEW "\n#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#endif\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__
    
      



	
