This perl script will read in const.c and automatically generate a h/gsn.h
file containing some macros to declare and define gsns. The h/gsn.h will
look something like this:

GSN(reserved, 0)
GSN(armor, 1)


Using Makefile dependancies it becomes unnecessary to define, declare and
put in pointers to gsns into skill_table: all skills automatically have a
gsn assigned.

Note that I keep all my include files in a directory named "h", thus
you'll need to slightly adjust the pathnames in the script.

The file gsn-header.h is also required:

#ifdef IN_DB_C
#define GSN(x,y) int gsn_ ##x = y;
#else
#define GSN(x,y) extern int gsn_ ## x;
#endif


You should put an:

#include "gsn.h"

in every file that needs to access gsns (or in merc.h: but I found that
only 30 out of my 161 source files needed them). In db.c, you will have to
do a: 

#define IN_DB_C

before including the file: that will pull in the actual declarations.

Also, you will then want to (but it's not really necessary) to remove the
pgsn element of skill_type and remove all references to it in the
skill_table - this can be done with a bit of regexp magic, e.g.
substituting something like &gsn[^,]+, with nothing, then ^\s+NULL, with
nothing, though you'll have to be careful not to remove the wrong NULLs;
take a copy of the file and use diff afterwards to check nothing is
missing.


Also: note that the gsns created by this are named e.g. gsn_lightning_bolt
for "lighting bolt" spell. Some gsns (at least in Envy) do not have the
full skill/spell name (e.g. bash door uses gsn_bash). You'll then have to
fix it so it uses gsn_bash_door instead.



The makefile dependencies look something like this (leading spaces are a
tab):

h/gsn.h: const.cc
	scripts/gsn.pl # I keep my script in the gsn/ dir

# This doesn't really work for me, but my Makefile is a strange 270 lines
# monstrosity
db.c: h/gsn.h # We want to recompile db.c each time a new gsn is added

The script itself (requires perl 5!)

#!/usr/bin/perl

# Generate a h/gsn.h file containing

require 5.002; # The non-greedy match is important

open (GSN, ">h/gsn.h") || die "Cannot open ../h/gsn.h: $!";

$WHOAMI = `whoami`;
$HOSTNAME= `hostname -f`;
$DATE = `date`;

chop $WHOAMI;
chop $HOSTNAME;
chop $DATE;


print GSN "/* Automatically generated\n * by ", $WHOAMI, "@", $HOSTNAME, "\n * on ", $DATE, ".\n */\n\n";
print GSN "#include \"gsn-header.h\"\n";

open (CONST, "const.c") || die "Cannot open ../const.c: $!";

while (<CONST>)
{
 # This may be named differently in you code
    last if /^const\s+struct\s+skill_type/;
}


# Assuming that the skill table ends with a };
while (<CONST>)
{
    last if /^};/;
    $Table .= $_;
}


# Remove all spaces
$Table =~ s/\s+/ /g;

# Remove all comments
# NOTE: this non-greedy match requires perl5
$Table =~ s#/\*.*?\*/##g;

# Now replace }, with a newline, so each skill is on its own line
$Table =~ s/},/\n/g;

$sn = 0;

foreach $a (split ('\n', $Table))
{
    if ($a =~ /\s+{\s+"([^"]+)"/)
    {
        $Skill = $1;
        $Skill =~ s/[- ]/_/g;
        print GSN "GSN($Skill, $sn)\n";
        $sn++;
        
    }
}

close (GSN);
close (CONST);

    




==============================================================================
Erwin Andreasen   Herlev, Denmark <erwin@pip.dknet.dk>  UNIX System Programmer
<URL:http://www.abandoned.org/drylock/>     <*>         (not speaking for) DDE
==============================================================================