exec perl -x -S $0 ${1+"$@"}
if ($] !~ /^5\..*/) {
foreach (split(/:/, $ENV{PATH})) { exec("$_/perl5", "-x", "-S", $0, @ARGV) if (-x "$_/perl5");
}
die "Your perl is too old; I need perl 5.\n";
}
eval join("\n", <DATA>);
if ($@) { die "$@"; }
__END__
require 5;
use strict;
my $enum_size = 0;
my @enum_values = ();
my $CC;
while ($ last unless ($ARGV[0] =~ m/^(\S+)=(\S+)$/);
eval "\$$1='$2';";
die "$@" if ($@);
shift @ARGV;
}
my $use_gcc_extension = ($CC and $CC eq 'gcc');
die "wrong number of arguments" if ($my ($cfile, $hfile) = @ARGV;
open CFILE, ">$cfile";
open HFILE, ">$hfile";
my $blank = "";
my $version = "\$Revision: 1.13 $blank";
$version =~ s/.Revision: (.*) /$1/;
print HFILE "/* auto-generated by config2header $version */\n";
print CFILE "/* auto-generated by config2header $version */\n";
print HFILE "#ifndef INCLUDED_IMAPOPTS_H\n";
print HFILE "#define INCLUDED_IMAPOPTS_H\n";
print HFILE "\n";
my @opttype = ("OPT_NOTOPT","OPT_STRING","OPT_INT","OPT_SWITCH","OPT_ENUM","OPT_STRINGLIST","OPT_BITFIELD");
print HFILE "enum opttype {\n";
while (my $opt = pop (@opttype)) {
if ($ print HFILE " $opt\n";
} else {
print HFILE " $opt,\n";
}
}
print HFILE "};\n\n";
print HFILE <<EOF
enum imapopt {
IMAPOPT_ZERO = 0,
EOF
;
print CFILE <<EOF
/* DO NOT EDIT */
/* THIS FILE AUTOMATICALLY GENERATED BY config2header $version */
struct imapopt_s imapopts[] =
{
{ IMAPOPT_ZERO, "", 0, { NULL }, OPT_NOTOPT, { { NULL, IMAP_ENUM_ZERO } } },
EOF
;
while (<STDIN>) {
next if (/^\
if (m|{\s*\"(.*?)\"\s*,\s*(\"?.*?\"?)\s*,\s*(.*?)\s*(\(.*\))?\s*}|) {
my $opt = $1;
my $def;
my $enums = "";
print HFILE " IMAPOPT_", uc($opt), ",\n";
if ($3 eq "STRING") {
$def = $use_gcc_extension
? "(union config_value)((const char *) $2)"
: "{(void *)($2)}";
} elsif ($3 eq "ENUM") {
my @values = eval $4;
my $e;
my $v;
my $count = 0;
$def = substr($2, 1, -1);
$e = "IMAP_ENUM_" . uc($opt) . "_" . uc($def);
$def = $use_gcc_extension
? "(union config_value)((enum enum_value) $e)"
: "{(void *)($e)}";
foreach $v (@values) {
$e = "IMAP_ENUM_" . uc($opt) . "_" . uc($v);
$enums .= "{ \"$v\" , $e }, ";
if (!$count) { $e .= " = 0"; }
push(@enum_values, $e);
$count += 1; }
if ($count > $enum_size) { $enum_size = $count; }
} elsif ($3 eq "STRINGLIST") {
my @values = eval $4;
my $v;
my $count = 0;
$def = $use_gcc_extension
? "(union config_value)((const char *) $2)"
: "{(void*)($2)}";
foreach $v (@values) {
$enums .= "{ \"$v\" , IMAP_ENUM_ZERO }, ";
$count += 1; }
if ($count > $enum_size) { $enum_size = $count; }
} elsif ($3 eq "BITFIELD") {
my @values;
my $e;
my $v;
my $count = 0;
$def = substr($2, 1, -1);
@values = split(' ', $def);
$e = "";
foreach $v (@values) {
$e .= "IMAP_ENUM_" . uc($opt) . "_" . uc($v) . "|";
}
$e .= "0";
$def = $use_gcc_extension
? "(union config_value)((unsigned long) $e)"
: "{(void *)($e)}";
@values = eval $4;
foreach $v (@values) {
$e = "IMAP_ENUM_" . uc($opt) . "_" . uc($v);
$enums .= "{ \"$v\" , $e }, ";
$e .= " = (1<<$count)";
push(@enum_values, $e);
$count += 1; }
if ($count > $enum_size) { $enum_size = $count; }
} else {
$def = $use_gcc_extension
? "(union config_value)((long) $2)"
: "{(void*)$2}";
}
print CFILE " { IMAPOPT_", uc($opt), ", \"$1\", 0, $def, OPT_$3, { $enums { NULL, IMAP_ENUM_ZERO } } },\n";
} else {
}
}
print HFILE <<EOF
IMAPOPT_LAST
};
enum enum_value {
IMAP_ENUM_ZERO = 0,
EOF
;
while (my $e = pop (@enum_values)) {
if ($ print HFILE " $e\n";
} else {
print HFILE " $e,\n";
}
}
my $dummy_field = $use_gcc_extension ? '' : 'void *dummy;';
print HFILE <<EOF
};
union config_value {
$dummy_field
const char *s; /* OPT_STRING, OPT_STRINGLIST */
long i; /* OPT_INT */
long b; /* OPT_SWITCH */
enum enum_value e; /* OPT_ENUM */
unsigned long x; /* OPT_BITFIELD */
};
struct enum_option_s {
const char *name;
const enum enum_value val;
};
struct imapopt_s {
const enum imapopt opt;
const char *optname;
int seen;
union config_value val;
const enum opttype t;
EOF
;
print HFILE " const struct enum_option_s enum_options[MAX_ENUM_OPTS+1];\n";
print HFILE <<EOF
};
extern struct imapopt_s imapopts[];
EOF
;
print CFILE <<EOF
{ IMAPOPT_LAST, NULL, 0, { NULL }, OPT_NOTOPT, { { NULL, IMAP_ENUM_ZERO } } }
};
/* c code goes here */
EOF
;