#!/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 ($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";