#!/usr/bin/perl
##
## using the given arguments, build a list of modules. There must be
## a .mod file for each argument
##
## this program should be run in the current directory.
##
#
# Note to module developers: the MAGIC_MODNUMBER is generated every time
# this program is run. Since it is stored in the clean file of the binary
# db you cannot rebuild the modules and use the same binary db without
# dumping the binary db to text. To specify your own magic number run
# this program with the argument '-m' followed by a number.
#
sub die {
print "@_";
`rm -f moddef.h`;
exit(0);
}
$nmods = 0;
@mods = ();
$magic = time();
$write=1;
@args = @ARGV;
@arg_save = ();
if ($#args == -1) {
open(TMP, "modbuild.last");
$tmp = <TMP>;
chop($tmp);
close(TMP);
@args = split(/ /, $tmp);
}
doargs:
for ($x=0; $x <= $#args; $x++) {
$_ = $args[$x];
if (/^-m(.*)/) {
## ohh, a special magic number!
$rest = $1;
if (length($rest)) {
$magic = $rest;
} else {
$x++;
$magic = $args[$x];
}
if ($magic !~ /[0-9]+/) {
&die("Invalid magic number \"$magic\"\n");
}
push(@arg_save, "-m$magic");
} else {
$nmods++;
push(@mods, $_);
push(@arg_save, $_);
}
}
$arg_save = join(" ", @arg_save);
`echo $arg_save > modbuild.last`;
if ($write) {
## open moddef.h now, add to it as we go
open(DEF, ">moddef.h") || die("Unable to open moddef.h");
print DEF <<END;
/*
// Full copyright information is available in the file ../doc/CREDITS
*/
#ifndef _moddef_h_
#define _moddef_h_
#include "native.h"
#include "native.h"
END
foreach $mod (@mods) {
print DEF "#include \"$mod.h\"\n";
}
print DEF<<END;
#define NUM_MODULES $nmods
#ifdef _native_
module_t * cold_modules[] = {
END
foreach $mod (@mods) {
print DEF " \&${mod}_module,\n";
}
print DEF "};\n#endif\n\n";
}
## now frob each module file
$struct = "";
$defn = 0;
$objects = "";
foreach $mod (@mods) {
if (!(-f "./$mod.mod")) {
print "No module found by the name of $mod.mod\n";
next;
}
open(MOD, "$mod.mod");
while (<MOD>) {
chop;
(/^\s*#/ || /^\s*$/) && next;
s/\s+/ /g;
s/^\s*//g;
s/\s*$//g;
if (/^objs\s*(.*)$/) {
$objects .= " " . $1;
next;
} elsif (/^native\s*(.*)$/) {
$_ = $1;
} else {
print "Ignoring unknown directive \"$_\".\n";
next;
}
($ref, $func) = split(/\s+/, $_);
($ref !~ /\./) && &die("Object reference \"$ref\" is invalid.\n");
($obj, $name) = split(/\./, $ref);
($obj =~ /^#/) &&
&die("Native methods may only be specified with object names.\n");
$obj =~ s/^\$//;
($obj =~ /[^a-z0-9_]/) &&
&die("Object name \"$obj\" contains invalid characters.\n");
$name =~ s/\(\s*\)//g;
($name =~ /[^a-z0-9_]/) &&
&die("Native method name \"$name\" contains invalid characters.\n");
$def = $name;
$def =~ tr/[a-z]/[A-Z]/;
$defo = $obj;
$defo =~ tr/[a-z]/[A-Z]/;
if ($func !~ /^native_/) { $func = "native_$func"; }
print DEF "#define NATIVE_${defo}_${def} $defn\n";
$buf = sprintf(" {%-15s %-20s %s},\n",
"\"$obj\",", "\"$name\",", "$func");
$struct .= $buf;
$defn++;
}
}
if ($write) {
print DEF <<END;
#define NATIVE_LAST $defn
#define MAGIC_MODNUMBER $magic\n
#ifdef _native_
native_t natives[NATIVE_LAST] = {
$struct};
#else
extern native_t natives[NATIVE_LAST];
#endif
#endif
END
close(DEF);
}
$objs = "";
for (split(/\s+/, $objects)) {
s/\s+/ /g;
s/^\s*//g;
s/\s*$//g;
(!$_) && next;
!(/^modules\//) && ($_ = "modules/$_");
print "$_ ";
}
print "\n";