// (c) 1988-2007 Electronic Arts Inc.

const char *SPIT_history[] =
{
"------------------------------------------------------------------",
"                                                                  ",
"                       Build Make & WEB v2.61                     ",
"                                                                  ",
"               by Rick Friesen and FrANK G. Barchard              ",
"                                                                  ",
"                     Main program - Jan 23, 2003                  ",
"                                                                  ",
"------------------------------------------------------------------",
"                                                                  ",
" Version Date   SE History:                                       ",
" ------- ----   -- --------                                       ",
"    1.00 880101 RF Rick Friesen original version for IBM          ",
"    1.10 920214 FB updated to new memory manager for IBM          ",
"    1.11 920218 FB errm/errs  files removed for onscreen errors   ",
"    1.12 920221 FB allow  extra /Ddef for NEC to define MCGA      ",
"    1.13 920224 FB generalized more for Amiga library             ",
"    1.14 920225 FB obj/src mix up bug fix                         ",
"    1.15 920302 FB MASM6  ML                                      ",
"    1.16 920318 FB accept tabs or spaces  for qedit/S same as ASM ",
"    1.17 920330 FB better EOF detect                              ",
"    1.18 920410 FB optimization on for MSC 6.0                    ",
"    1.19 920415 FB /Zp1 for HIGHC compatibility                   ",
"    1.20 920419 FB Large model build for MSC                      ",
"    1.21 920528 FB FMTowns                                        ",
"    1.22 920609 FB Debug  compile options (for size)              ",
"    1.23 920703 FB EAC library names                              ",
"    1.24 920714 FB Sound  library integrated...need more line spac",
"    1.25 920819 FB /nologo for MSC7/masm6, RSP file use 6 columns ",
"    1.26 920901 FB /W3 /WX for C  and assembler                   ",
"    1.27 920903 FB /W2 /Cp for assembler                          ",
"    1.28 920910 FB wmake,err,model dependent                      ",
"    1.29 920917 FB spit 2.0 MSC                                   ",
"    1.30 921001 FB Watcom version, generate 286 code  only        ",
"    1.31 921001 FB Define IS286 for asm model and ifdefs          ",
"    1.32 921006 FB MODEL.inc  define is286 (command line too int) ",
"    1.33 921105 FB /Gy for function level linking                 ",
"    1.34 921114 FB source files followed  by object files         ",
"    1.35 921115 FB default to sml models  only. * for all         ",
"    1.36 921122 FB count  objects for each model                  ",
"    1.37 921124 FB debug  version of libraries                    ",
"    1.38 921127 FB flat model libraries (previously protected mode",
"    1.39 921202 FB wcc386p call directly  for faster compiles     ",
"    1.40 921208 FB /Ob2 for auto  inlining in MSC                 ",
"    1.41 921221 FB /Ob1 to enable inlining, but must  be explicite",
"    1.42 921222 FB delete destination object  before compiling    ",
"    1.43 921223 FB removed del,use wmake  option, removed /Cp & /O",
"    1.44 930106 FB put error  log back into makes                 ",
"    1.45 930208 FB /DDEBUG and models for cl's (bug)              ",
"    1.46 930209 FB /w2 for watcom warning level                   ",
"    1.47 930209 FB 'fnt'  type/memory model field seperated       ",
"    1.48 930214 FB header file generation for fonts.   3 passes   ",
"    1.49 930301 FB large  model make warnings not fatal - kludge  ",
"    1.50 930320 FB @type  for flatmodel (too quiet with /s silence",
"    1.51 930419 FB /d2 for watcom                                 ",
"    1.52 930426 FB minimize fnt commands  for memory              ",
"    1.53 930512 FB /d2 out again, /w25 for Watcom, type err       ",
"    1.54 930525 FB Mac version (MPW)  for 3DO                     ",
"    1.55 930604 FB cr/nl, arm compiler and make file  format      ",
"    1.56 930607 FB response file  for armlib                      ",
"    1.57 930611 FB -g removed and -O  inserted for armcc optimizat",
"    1.58 930618 FB fonts  rule based                              ",
"    1.59 930623 FB database have  libs for PC on line 0, Mac line ",
"    1.60 930624 FB 386 compile option /G3 for MSVC8.0             ",
"    1.61 930715 FB armasm for 3DO                                 ",
"    1.62 930721 FB -zps0  stack check on for armcc (required)     ",
"    1.63 930723 FB fonts  - no len field anymore                  ",
"    1.64 930726 FB skip blank lines/fnt rule  for 3do fonts       ",
"    1.65 930728 FB defaults for all fields except file name/fntcc ",
"    1.66 930827 FB -d GREEN/lib.lst                               ",
"    1.67 930902 FB DEBUG  default, .fnt->.vfn and .3fn            ",
"    1.68 930903 FB small  model debug                             ",
"    1.69 930908 FB V102 for new 1.02  system (as well as GREEN)   ",
"    1.70 930913 FB -pd DEBUG  for arm assembly                    ",
"    1.71 931001 FB GREEN/V102 removed                             ",
"    1.72 931123 FB Canabilized to work in small model for GNU     ",
"    1.73 940318 FB Added -i eac/incl for internal includes on 3DO ",
"    1.74 940424 FB Removed far  from fonts                        ",
"    1.75 940509 FB lib,eac first line define lib, define 2, (c) 94",
"    1.76 940611 FB config file for each lib                       ",
"    1.77 940614 FB allow quotes and \n's in config files          ",
"    1.78 940617 FB quick lookup defines, mac version for 3do      ",
"    1.79 940618 FB better line parse for mac, only load cfg once  ",
"    1.80 940627 FB only do 1 define                               ",
"    1.81 940629 FB different asm cfg for mac                      ",
"    1.82 940812 FB ; to comment to end of line in middle of line  ",
"    1.83 940816 FB second arg to specify target/hash back in      ",
"    1.84 940819 FB source to object                               ",
"    1.85 940906 FB OBJFIRST in .cfg files for object,source       ",
"    1.86 950403 FB lst file contain -c catagory for doc           ",
"    1.87 950407 FB DIRSEP for SGI, \t for tabs                    ",
"    1.88 950409 FB dest dir def                                   ",
"    1.89 950424 FB extra define allow -opt or /opt verbatim       ",
"    1.90 950509 FB extra srcdir,src parms for DO and DB (for Yggy)",
"    1.91 950512 FB pass 1 open files use cfg file names           ",
"    1.92 950512 FB dirsep string                                  ",
"    1.93 950718 FB Mac same as PC except configline               ",
"    1.94 950821 FB 3 -> TH for Mac 3DO, 3 lines of cfgs           ",
"    1.95 951022 FB lib.lst use catagory for help system           ",
"    1.96 951026 FB SGI line in libdb                              ",
"    1.97 951212 FB lib.lst file contain object file names         ",
"    1.98 960119 FB DEBUG, no models, asis def, prototypes         ",
"    1.99 960125 FB removed eacfil                                 ",
"    2.00 960213 FB no line continuation if last obj, pass 4 count ",
"    2.01 960712 FB always use dir                                 ",
"    2.02 960712 YK additional parameters to MSTART                ",
"    2.03 961112 FB dont crash on bad directory                    ",
"    2.10 961112 FB debug,abort and nondebug libraries (DAZ)       ",
"    2.11 970203 FB renamed bmw, 3 libs, rating, doc               ",
"    2.12 970408 FB 4th lib - t for timing                         ",
"    2.13 970410 FB * for source dir means use dest as source dir  ",
"    2.14 970411 FB DEBUG and fix for T/D lib                      ",
"    2.15 970416 FB source folder for each lib                     ",
"    2.16 970507 FB for each lib, have default * directory         ",
"    2.17 970627 FB pad .lst file with spaces into columns         ",
"    2.18 970825 FB v lib for voyeur which has prologue/epilogue   ",
"    2.19 971016 FB add section to dependency to allow eacmath.h   ",
"    2.20 980226 FB dir line use .cfg, add libsrc.lst              ",
"    2.21 980305 FB numbered defines                               ",
"    2.22 980311 FB number up to 9                                 ",
"    2.23 980325 FB more libraries for 3rash                       ",
"    2.24 980702 FB getdefine strings up to 1024                   ",
"    2.25 980915 FB list2 only has rating>=2 files                 ",
"    2.26 980921 FB RSPFORMATNP output every 42 lines (252 objs)   ",
"    2.27 980922 FB // for comments ok                             ",
"    2.28 980924 FB NL every 5 columns                             ",
"    2.29 981008 FB -c to override the config files, END directive ",
"    2.30 981027 FB one line show all cfg files                    ",
"    2.31 981118 FB ignore DEBUG section - confused .err file      ",
"    2.33 990111 FB -pc,-mac,-sgi for newline styles               ",
"    2.34 990119 FB author/se field                                ",
"    2.35 990122 KW placed double quotes around author output      ",
"    2.36 990412 FB allow empty lines to contain spaces            ",
"    2.37 990526 FB cpp language defines (c,cpp,asm,usr). libdb 2  ",
"    2.38 990625 FB vsm same as usr. libdb 3                       ",
"    2.39 990701 FB changed vsm to dsm                             ",
"    2.40 991115 FB OBJFIRST check 'Y' for yes                     ",
"    2.41 991117 FB ASMEXTENSION                                   ",
"    2.42 991216 FB FSTOP0, FSTOP1 etc                             ",
"    2.43 991221 FB FSTOP0 logic was failing on 3 and more         ",
"    2.44 000423 FB .h for header - section, author, rating        ",
"    2.45 000615 FB bumped maxline to 4096 and 8 defines           ",
"    2.46 000914 FB libc.lst for just c/cpp files                  ",
"    2.47 000918 FB libsrcc/SOURCELISTNAMEC                        ",
"    2.48 000928 FB OSX use unix line                              ",
"    2.49 010201 FB check that files open ok                       ",
"    2.50 010427 FB multiline getdefine                            ",
"    2.51 010508 FB author in .cfg file                            ",
"    2.52 010925 FB remove def2, try ../*.cfg                      ",
"    2.53 010925 FB libdbversion 2 removes mac line too            ",
"    2.54 011002 FB list0 file rate >=0, libsrc0                   ",
"    2.55 020426 KW added doxygen support                          ",
"    2.56 020426 KW libdoxy.lst - includes all files               ",
"    2.57 020625 FB getdefine more robust string check eof         ",
"    2.58 020626 FB -time support, leak fix                        ",
"    2.59 020720 FB configes free                                  ",
"    2.60 030113 FB ignore missing config files                    ",
"    2.61 030123 FB default is no extension for rule now (was c)   ",
"                                                                  ",
"------------------------------------------------------------------",
"\0"
};

/****************************************************************/
/*  Spit Setup                                                  */
/****************************************************************/

#include <stdarg.h>
#include "spit.h"
#include "stdgimex.h"
#include "findfile.h"
#include "stdgimex.h"


const char TextVersion[]="2.61 (Samba) 2007.12.4";
#define TOOL_VERSION 261
#define TOOL_NAME "bmw"

#define LIBDBVERSION 2

char OPTcfgfile[SPITMAXLINE];
int OPTnewlinetype;

/*#define strupr(s)   { int i; for (i=0; (s)[i]; ++i) (s)[i]=toupper((s)[i]); } */

#define VLEVEL  3
#define MAXLIBS 100

#define MAXREGS 128

/* rules for assembler */

#define FLATASMDEP      getdefine(  1,"FLATASMDEP")
#define FLATASM0        getdefine(  2,"FLATASM0")
#define FLATASM1        getdefine(  3,"FLATASM1")
#define FLATASM2        getdefine(  4,"FLATASM2")
#define FLATASM3        getdefine(  5,"FLATASM3")
#define FLATASM4        getdefine(  6,"FLATASM4")
#define FLATASM5        getdefine(  7,"FLATASM5")
#define FLATASM6        getdefine(  8,"FLATASM6")
#define FLATASM7        getdefine(  9,"FLATASM7")
#define FLATASM8        getdefine( 10,"FLATASM8")
#define FLATASM9        getdefine( 11,"FLATASM9")

/* rules for c++ */

#define FLATCPPDEP      getdefine( 71,"FLATCPPDEP")
#define FLATCPP0        getdefine( 72,"FLATCPP0")
#define FLATCPP1        getdefine( 73,"FLATCPP1")
#define FLATCPP2        getdefine( 74,"FLATCPP2")
#define FLATCPP3        getdefine( 75,"FLATCPP3")
#define FLATCPP4        getdefine( 76,"FLATCPP4")
#define FLATCPP5        getdefine( 77,"FLATCPP5")
#define FLATCPP6        getdefine( 78,"FLATCPP6")
#define FLATCPP7        getdefine( 79,"FLATCPP7")
#define FLATCPP8        getdefine( 80,"FLATCPP8")
#define FLATCPP9        getdefine( 81,"FLATCPP9")


/* rules for C */

#define FLATCDEP        getdefine( 12,"FLATCDEP")
#define FLATC0          getdefine( 13,"FLATC0")
#define FLATC1          getdefine( 14,"FLATC1")
#define FLATC2          getdefine( 15,"FLATC2")
#define FLATC3          getdefine( 16,"FLATC3")
#define FLATC4          getdefine( 17,"FLATC4")
#define FLATC5          getdefine( 18,"FLATC5")
#define FLATC6          getdefine( 19,"FLATC6")
#define FLATC7          getdefine( 20,"FLATC7")
#define FLATC8          getdefine( 21,"FLATC8")
#define FLATC9          getdefine( 22,"FLATC9")

/* rules for fonts */

#define FLATDSMDEP      getdefine( 23,"FLATDSMDEP")
#define FLATDSM0        getdefine( 24,"FLATDSM0")
#define FLATDSM1        getdefine( 25,"FLATDSM1")
#define FLATDSM2        getdefine( 26,"FLATDSM2")
#define FLATDSM3        getdefine( 27,"FLATDSM3")
#define FLATDSM4        getdefine( 28,"FLATDSM4")
#define FLATDSM5        getdefine( 29,"FLATDSM5")
#define FLATDSM6        getdefine( 30,"FLATDSM6")
#define FLATDSM7        getdefine( 31,"FLATDSM7")
#define FLATDSM8        getdefine( 32,"FLATDSM8")
#define FLATDSM9        getdefine( 33,"FLATDSM9")

/* response files etc */

#define SOURCELISTNAME  getdefine( 34,"SOURCELISTNAME")
#define SOURCELISTNAME0 getdefine(100,"SOURCELISTNAME0")
#define SOURCELISTNAMEC getdefine( 97,"SOURCELISTNAMEC")
#define FILELISTNAME    getdefine( 35,"FILELISTNAME")
#define FILELISTNAME2   getdefine( 82,"FILELISTNAME2")
#define FILELISTNAME0   getdefine( 99,"FILELISTNAME0")
#define FILELISTNAMEDOXY    getdefine(101,"FILELISTNAMEDOXY")
#define FILELISTNAMEDOXY2   getdefine(102,"FILELISTNAMEDOXY2")
#define FILELISTNAMEDOXY0   getdefine(103,"FILELISTNAMEDOXY0")
#define FILELISTNAMEC   getdefine( 96,"FILELISTNAMEC")
#define HEADERFILENAME  getdefine( 36,"HEADERFILENAME")
#define MAKEFILENAME0   getdefine( 37,"MAKEFILENAME0")
#define MAKEFILENAME1   getdefine( 38,"MAKEFILENAME1")
#define MAKEFILENAME2   getdefine( 39,"MAKEFILENAME2")
#define MAKEFILENAME3   getdefine( 40,"MAKEFILENAME3")
#define MAKEFILENAME4   getdefine( 41,"MAKEFILENAME4")
#define MAKEFILENAME5   getdefine( 42,"MAKEFILENAME5")
#define MAKEFILENAME6   getdefine( 43,"MAKEFILENAME6")
#define MAKEFILENAME7   getdefine( 44,"MAKEFILENAME7")
#define MAKEFILENAME8   getdefine( 45,"MAKEFILENAME8")
#define MAKEFILENAME9   getdefine( 46,"MAKEFILENAME9")
#define RSPFILENAME     getdefine( 47,"RSPFILENAME")
#define RSPFORMAT       getdefine( 48,"RSPFORMAT")
#define RSPFORMATNL     getdefine( 49,"RSPFORMATNL")
#define RSPFORMATNP     getdefine( 83,"RSPFORMATNP")
#define DEPFORMAT       getdefine( 50,"DEPFORMAT")
#define DEPFORMATNL     getdefine( 51,"DEPFORMATNL")
#define MSTART          getdefine( 52,"MSTART")
#define RSPFLATSTART    getdefine( 53,"RSPFLATSTART")
#define EXTRAASMDEF     getdefine( 54,"EXTRAASMDEF")
#define EXTRACPPDEF     getdefine( 84,"EXTRACPPDEF")
#define EXTRACDEF       getdefine( 55,"EXTRACDEF")
#define EXTRADSMDEF     getdefine( 56,"EXTRADSMDEF")
#define RSPSTOP         getdefine( 57,"RSPSTOP")
#define FSTOP           getdefine( 58,"FSTOP")
#define FSTOP0          getdefine( 86,"FSTOP0")
#define FSTOP1          getdefine( 87,"FSTOP1")
#define FSTOP2          getdefine( 88,"FSTOP2")
#define FSTOP3          getdefine( 89,"FSTOP3")
#define FSTOP4          getdefine( 90,"FSTOP4")
#define FSTOP5          getdefine( 91,"FSTOP5")
#define FSTOP6          getdefine( 92,"FSTOP6")
#define FSTOP7          getdefine( 93,"FSTOP7")
#define FSTOP8          getdefine( 94,"FSTOP8")
#define FSTOP9          getdefine( 95,"FSTOP9")
#define OBJFIRST        getdefine( 59,"OBJFIRST")
#define ASMEXTENSION    getdefine( 85,"ASMEXTENSION")
#define DIRSEP          getdefine( 60,"DIRSEP")
#define OBJDIR0         getdefine( 61,"OBJDIR0")
#define OBJDIR1         getdefine( 62,"OBJDIR1")
#define OBJDIR2         getdefine( 63,"OBJDIR2")
#define OBJDIR3         getdefine( 64,"OBJDIR3")
#define OBJDIR4         getdefine( 65,"OBJDIR4")
#define OBJDIR5         getdefine( 66,"OBJDIR5")
#define OBJDIR6         getdefine( 67,"OBJDIR6")
#define OBJDIR7         getdefine( 68,"OBJDIR7")
#define OBJDIR8         getdefine( 69,"OBJDIR8")
#define OBJDIR9         getdefine( 70,"OBJDIR9")

#define AUTHOR          getdefine( 98,"AUTHOR")


FILE    *makef0=0;
FILE    *makef1=0;
FILE    *makef2=0;
FILE    *makef3=0;
FILE    *makef4=0;
FILE    *makef5=0;
FILE    *makef6=0;
FILE    *makef7=0;
FILE    *makef8=0;
FILE    *makef9=0;
int     numobjf;
int     dirs;
int     morelines=1;
char    *s;
char    *lineptr;
char    *parseptr;
char    sourcelist[MAXLIBS][100];
char    sourcelist0[MAXLIBS][100];
char    sourcelistc[MAXLIBS][100];
char    makelist[MAXLIBS][100];
char    makelist2[MAXLIBS][100];
char    makelist0[MAXLIBS][100];
char    makelistc[MAXLIBS][100];
char    makelistdoxy[MAXLIBS][100];
char    makelistdoxy2[MAXLIBS][100];
char    makelistdoxy0[MAXLIBS][100];
char    makeheader[MAXLIBS][100];
char    makefile0[MAXLIBS][100];
char    makefile1[MAXLIBS][100];
char    makefile2[MAXLIBS][100];
char    makefile3[MAXLIBS][100];
char    makefile4[MAXLIBS][100];
char    makefile5[MAXLIBS][100];
char    makefile6[MAXLIBS][100];
char    makefile7[MAXLIBS][100];
char    makefile8[MAXLIBS][100];
char    makefile9[MAXLIBS][100];
char    fmakersp[MAXLIBS][100];
int     objectcount[MAXLIBS];

char    *configfile[MAXLIBS];   // config file pointers (loaded)

char    src[32];
char    obj[32];
char    typ[32];
char    flags[32];
char    flags2[32];
char    section[32];
char    author[32];
char    rating[32];
char    srcdir[32];
char    dstdir[32];
char    dstdef[32];

char    dir[MAXLIBS+1][16];
char    def[MAXLIBS+1][16];
char    cfg[MAXLIBS+1][16];
char    star[MAXLIBS+1][16];

int     d;
int     dbopts;
char    *m;
char    makeextraasmdef[100];
char    makeextracppdef[100];
char    makeextracdef[100];
char    makeextradsmdef[100];
char    flagsextraasmdef[100];
char    flagsextracppdef[100];
char    flagsextracdef[100];
char    flagsextradsmdef[100];

char    libdbversion[16];
char    makename[16];
char    libname[16];

char    **OPTtargets;
int     OPTnumtargets;

/****************************************************************/
/*  BMW Routines                                                */
/****************************************************************/

#define BMWMAXLINE 4096

static void BMW_fprintf(FILE *__fp, const char *__format, ... )
{
    va_list arglist;
    char tempstr[BMWMAXLINE];

    if (__fp)
    {
        va_start(arglist, __format);
        vsprintf(tempstr, __format, arglist);
        fprintf(__fp,"%s",tempstr);
        va_end(arglist);
    }
}

int BMW_fileexist(char *nextname)
{
    int ok=0;
    GSTREAM *g;
    g = gopen(nextname);
    if (g)
    {
        ok = 1;
        gclose(g);
    }
    return(ok);
}


struct quickregstruct
{
    char *start;
} quickregtbl[MAXREGS][MAXLIBS];

static char *getdefine(int reg, char *label)
{
    static char ret[BMWMAXLINE*8];
    static int  nextret=0;
    char *r=0;

    char *s=0;
    char *ds;
    int l;
    int dig;

    if (reg<MAXREGS)
        s = quickregtbl[reg][d].start;

    if (!s)
    {
        l = strlen(label);
        ret[nextret] = 0;
        s = configfile[d];
        if (s)
        {
            while (*s)
            {
                if (!strncmp(s,"#define",7))
                {
                    s += 7;
                    while (*s==' ' || *s=='\t')
                        ++s;

                    if (!strncmp(s,label,l))  /* "#define LABEL " */
                    {
                        s += l;
                        if (*s==(char)'\t' || *s==' ')
                        {
                            while (*s==(char)'\t' || *s==' ')
                                ++s;
                            if (reg<MAXREGS)
                                quickregtbl[reg][d].start = s; /* remember */
                            break;
                        }
                    }
                }
                while (*s && *s!=(char)13 && *s!=(char)10)
                    ++s;

                if (*s==(char)10 || *s==(char)13)
                {
                    ++s;
                    if ((*s==(char)10 || *s==(char)13) && (*s!=*(s-1)))
                        ++s;
                }
            }

            if (!s)
                printf("define '%s' NOT FOUND!\n",label);
        }
    }

    if (s)
    {
        int quotedelimiter=0;
        if (*s=='"')
        {
            ++s;
            quotedelimiter = 1;
        }
        ds = ret+nextret;
        while (*s && (
            (quotedelimiter==0 && (*s!=(char)13 && *s!=(char)10))
         || (quotedelimiter==1 && (*s!='"'))))
        {
            if (*s=='\\')
            {
                ++s;
                if (*s=='n' || *s==(char)10 || *s==(char)13)
                {
                    switch (OPTnewlinetype)
                    {
                        case 0: /* PC style cr/lf */
                            *ds++ = (char)13;
                            *ds++ = (char)10;
                            break;

                        case 1: /* Mac style cr */
                            *ds++ = (char)13;
                            break;

                        default:    /* unix,linux,osx,beos,amiga,3do style lf */
                            *ds++ = (char)10;
                            break;
                    }
                    if (*s=='n')
                        ++s;
                    else if (*s==(char)10)
                    {
                        ++s;
                        if (*s==(char)13)
                            ++s;
                    }
                    else if (*s==(char)13)
                    {
                        ++s;
                        if (*s==(char)10)
                            ++s;
                    }
                }
                else if (*s=='t')
                {
                    *ds++ = '\t';
                    ++s;
                }
                else
                {
                    if (isdigit(*s))
                    {
                        dig = 0;
                        while (isdigit(*s))
                        {
                            dig = dig*8+*s-'0'; /* octal */
                            ++s;
                        }
                        *ds++ = (char) dig;
                    }
                    else
                        *ds++ = *s++;
                }
            }
            else
                *ds++ = *s++;
        }
        *ds = 0;
    }
    r = ret+nextret;
    if (OPTverbose>=6)
        printf("getdefine(%s) %s\n",label,r);
    nextret = (nextret+BMWMAXLINE)&(BMWMAXLINE*8-1); /* 8 different strings of MAXDEFINE */
    return(r);
}

static int parse(char *d)
{
    int n=0;

    /* ignore leading white spaces */

    while (*parseptr==(char)' ' || *parseptr==(char)'\t')
    {
        ++parseptr;
    }
    *d=0;

    for (;;)
    {
        char c;

        c=*parseptr;
        if (c=='\t') c = ' ';
        if (c==(char)10 || c==(char)13 || c==(char)0 || c==(char)';' || (c=='/' && parseptr[1]=='/'))
        {
            break;
        }
        if (c==',')
        {
            ++parseptr;
            break;
        }
        *d++ = c;
        ++parseptr;
        ++n;
    }

    /* remove trailing white spaces */

    while (n)
    {
        if (*(d-1)==(char)' ' || *(d-1)==(char)'\t')
        {
            --d;
            --n;
        }
        else
            break;
    }
    *d=0;
    return(n);
}


static void nextline(void)
{
    char  c;

    do
    {
        do
        {
            c=*lineptr++;
        } while ((unsigned char)c>=(unsigned char)' ' || c=='\t');

        if (c==(char)10)
        {
            if (*lineptr==(char)13)
                ++lineptr;
            c=*lineptr;
        }
        else if (c==(char)13)
        {
            if (*lineptr==(char)10)
                ++lineptr;
            c=*lineptr;
        }

        while (*lineptr==' ' || *lineptr=='\t')
        {
            c=*++lineptr;
        }

    } while (c==(char)10 || c==(char)13 || c==';' || (c=='/' && lineptr[1]=='/'));

    if (c==26 || !c)      /* ctrl-z */
        morelines=0;

    if (!strnicmp(lineptr,"END",3) && (unsigned char)lineptr[3]<=(unsigned char)' ')
    {
        morelines=0;
    }
}

static void parseline(void)
{
    parseptr=lineptr;
    nextline();

    parse(src);
    parse(obj);
    parse(typ);
    parse(flags);
    if (atoi(libdbversion)<2)
        parse(flags2);
    parse(section);
    author[0] = 0;
    if (atoi(libdbversion)>=1)
        parse(author);
    parse(rating);
    parse(srcdir);

    if (!obj[0])     strcpy(obj,src);
    if (!typ[0])     strcpy(typ,""); // allow null rule for installer rating 0 files with no extensions
    if (!section[0]) strcpy(section,"\"MISC\"");
    if (!author[0])  strcpy(author,"*");
    if (!rating[0])  strcpy(rating,"3");
    if (!srcdir[0])  strcpy(srcdir,"*");
    if (!strcmp(srcdir,"*"))
        strcpy(srcdir,star[d]);
    if (!strcmp(author,"*"))
    {
        if (AUTHOR)
        {
            strcpy(author,AUTHOR);
        }
        else
        {
            strcpy(author,"\"\"");
        }
    }

    if (*parseptr==(char)10 || *parseptr==(char)13 || *parseptr==(char)0)
        parseptr = dir[0];    /* for dest dir */
}

/****************************************************************/
/*  Parse directories line                                      */
/****************************************************************/

static void ParseDirectoriesLine(void)
{
    struct SPITMEM infile={0,0};
    char cfgname[BMWMAXLINE];

    lineptr=s;

    parseptr=lineptr;
    parse(libdbversion);    /* version ie 2 */

    if (atoi(libdbversion)>LIBDBVERSION)
        printf("\nwarning - this data base requires a newer version of BMW\n");

    parse(makename);        /* lib */
    parse(libname);         /* eac */
    if (atoi(libdbversion)<1) /* no version */
    {
        strcpy(libname,makename);
        strcpy(makename,libdbversion);
    }
    nextline();

    parseptr=lineptr;

#if defined(_MSC_VER)
    parseptr=lineptr;   /* PC use 1st line of libdb */
    nextline();
    nextline();
#else
    nextline();
    parseptr=lineptr;   /* unix/osx use 2nd line */
    nextline();
#endif
    if (atoi(libdbversion)<2) // skip mac line
        nextline();

    d=0;
    while (parse(dir[d]))
    {
        parse(def[d]);
        parse(cfg[d]);
        parse(star[d]);

        if (!def[d][0])
            strcpy(def[d],dir[d]);
        if (!cfg[d][0])
            strcpy(cfg[d],dir[d]);
        if (!star[d][0])
            strcpy(star[d],dir[d]);

        if (OPTcfgfile[0])
            sprintf(cfgname,"%s",OPTcfgfile);
        else
            sprintf(cfgname,"%s.cfg",cfg[d]);

        if (OPTverbose>=4)
        {
            printf("%s %s %s %s\n",dir[d],def[d],cfgname,star[d]);
            SPIT_flush();
        }

        configfile[d] = NULL;

        if (!BMW_fileexist(cfgname))
        {
            char cfgname2[BMWMAXLINE];

            sprintf(cfgname2,"..%c%s.cfg",SPITDIRSYM,cfg[d]);

            if (BMW_fileexist(cfgname2))
                strcpy(cfgname,cfgname2);
        }

        if (BMW_fileexist(cfgname))
        {
            if (SPIT_loadfilev(&infile, cfgname,OPTverbose==2?1:OPTverbose))
            {
                configfile[d] = infile.ptr;
                if (OPTverbose>=4)
                    printf("ok.\n");
            }
        }

        sprintf(sourcelist[d], SOURCELISTNAME, dir[d], makename);
        sprintf(sourcelist0[d],SOURCELISTNAME0,dir[d], makename);
        sprintf(sourcelistc[d],SOURCELISTNAMEC,dir[d], makename);
        sprintf(makelist[d],   FILELISTNAME,   dir[d], makename);
        sprintf(makelist2[d],  FILELISTNAME2,  dir[d], makename);
        sprintf(makelist0[d],  FILELISTNAME0,  dir[d], makename);
        sprintf(makelistdoxy[d], FILELISTNAMEDOXY, dir[d], makename);
        sprintf(makelistdoxy2[d],FILELISTNAMEDOXY2,dir[d], makename);
        sprintf(makelistdoxy0[d],FILELISTNAMEDOXY0,dir[d], makename);
        sprintf(makelistc[d],  FILELISTNAMEC,  dir[d], makename);
        sprintf(makeheader[d], HEADERFILENAME, dir[d], makename);
        sprintf(makefile0[d],  MAKEFILENAME0,  dir[d], makename);
        sprintf(makefile1[d],  MAKEFILENAME1,  dir[d], makename);
        sprintf(makefile2[d],  MAKEFILENAME2,  dir[d], makename);
        sprintf(makefile3[d],  MAKEFILENAME3,  dir[d], makename);
        sprintf(makefile4[d],  MAKEFILENAME4,  dir[d], makename);
        sprintf(makefile5[d],  MAKEFILENAME5,  dir[d], makename);
        sprintf(makefile6[d],  MAKEFILENAME6,  dir[d], makename);
        sprintf(makefile7[d],  MAKEFILENAME7,  dir[d], makename);
        sprintf(makefile8[d],  MAKEFILENAME8,  dir[d], makename);
        sprintf(makefile9[d],  MAKEFILENAME9,  dir[d], makename);
        sprintf(fmakersp[d],   RSPFILENAME,    dir[d], makename);

        d++;
    }
    if (OPTverbose>=2 && OPTverbose<=2)
        printf("\n");
    dirs=d;
}


static int istarget(char *dest)
{
    int ok=1;
    int i;

    if (OPTnumtargets && OPTtargets && dest)
    {
        ok = 0;

        for (i=0; i<OPTnumtargets && OPTtargets[i] && !ok; ++i)
        {
            if (!stricmp(dest,OPTtargets[i]))
                ok = 1;
        }
    }
    return(ok);
}

static void makeextraoptions(char *d, char *def, char *opts)
{
    if (*opts=='-' || *opts=='/')
        sprintf(d," %s",opts);
    else
        sprintf(d,def,opts);
    return;
}

/****************************************************************/
/*  Pass 0: Count number of object files in each lib            */
/****************************************************************/

static int Pass0(void)
{
    morelines=1;
    lineptr=s;      /* goto first line of actual data base */
    nextline();
    nextline();
    nextline();
    if (atoi(libdbversion)<2)
        nextline();
    numobjf = 0;
    while (morelines)
    {
        parseline();

        while (parse(dstdir))
        {
            if (stricmp(dstdir,"NONE")==0 || stricmp(typ,"ABS")==0) break;


            if (stricmp(dstdir,dir[d])==0)
            {
                if (atoi(rating)>=1)
                    ++numobjf;
                break;
            }
        }
    }
    objectcount[d] = numobjf;
    return(0);
}





/****************************************************************/
/*  Pass 1: RSP file objects,header,list and info file          */
/****************************************************************/


static int Pass1(void)
{
    FILE *srclst=0;
    FILE *srclst0=0;
    FILE *srclstc=0;
    FILE *makelst=0;
    FILE *makelst2=0;
    FILE *makelst0=0;
    FILE *makelstdoxy=0;
    FILE *makelstdoxy2=0;
    FILE *makelstdoxy0=0;
    FILE *makelstc=0;
    FILE *makeh=0;
    FILE *rspf=0;
    int ok=0;
    char rootpath[SPITMAXLINE];

#ifdef __PPU__
    strcpy(rootpath,".");
#else
    RGetCWD(rootpath, SPITMAXLINE);
#endif

    if (OPTverbose)
    {
        if (OPTverbose>=3)
            printf("DIRECTORY=%s, (*=%s) %d obj",dir[d],star[d],objectcount[d]);
        else
            printf("%s, ",dir[d]);
        SPIT_flush();
    }

    if (stricmp(dir[d],def[d]))
    {
        makeextraoptions(makeextraasmdef,EXTRAASMDEF,def[d]);
        makeextraoptions(makeextracppdef,EXTRACPPDEF,def[d]);
        makeextraoptions(makeextradsmdef,EXTRADSMDEF,def[d]);
        makeextraoptions(makeextracdef,  EXTRACDEF,def[d]);
    }
    else
    {
        strcpy(makeextraasmdef,"");
        strcpy(makeextracppdef,"");
        strcpy(makeextradsmdef,"");
        strcpy(makeextracdef,"");
    }
    if (OPTverbose>=3)
    {
        printf("%s ",makeextradsmdef);
    }
                             rspf     = fopen(fmakersp[d],"wb");    if (!rspf)    { printf("Cannot open '%s'. Skipping. ",fmakersp[d]);   goto getout; }
    if (sourcelist[d][0])    srclst   = fopen(sourcelist[d],"wb");  /* optional */
    if (sourcelist0[d][0])   srclst0  = fopen(sourcelist0[d],"wb"); /* optional */
    if (sourcelistc[d][0])   srclstc  = fopen(sourcelistc[d],"wb"); /* optional */
                             makelst  = fopen(makelist[d],"wb");    if (!makelst) { printf("Cannot open '%s'. Skipping. ",makelist[d]);   goto getout; }
    if (makelist2[d][0])     makelst2 = fopen(makelist2[d],"wb");   /* optional */
    if (makelist0[d][0])     makelst0 = fopen(makelist0[d],"wb");   /* optional */
    if (makelistdoxy[d][0])  makelstdoxy  = fopen(makelistdoxy[d],"wb");    /* optional */
    if (makelistdoxy2[d][0]) makelstdoxy2 = fopen(makelistdoxy2[d],"wb");   /* optional */
    if (makelistdoxy0[d][0]) makelstdoxy0 = fopen(makelistdoxy0[d],"wb");   /* optional */
    if (makelistc[d][0])     makelstc = fopen(makelistc[d],"wb");   /* optional */
                             makeh    = fopen(makeheader[d],"wb");  if (!makeh) { printf("Cannot open '%s'.",makeheader[d]); }

    if (makeh)
        fprintf(makeh, "/* Copyright (C) Electronic Arts Canada Inc. 1992-2001.  All rights reserved. */\n\n");
    fprintf(rspf, RSPFLATSTART,  libname,dir[d]);

    morelines=1;
    lineptr=s;      /* goto first line of actual data base */
    nextline();
    nextline();
    nextline();
    if (atoi(libdbversion)<2)
        nextline();
    numobjf = 0;
    if (makelstdoxy)
        fprintf(makelstdoxy,"INPUT += \\\n");
    if (makelstdoxy2)
        fprintf(makelstdoxy2,"INPUT += \\\n");
    if (makelstdoxy0)
        fprintf(makelstdoxy0,"INPUT += \\\n");
    while (morelines)
    {
        parseline();
        if (OPTverbose>=VLEVEL)
        {
            printf("   1 %s\r",src);
            SPIT_flush();
        }

        while (parse(dstdir))
        {
            if (stricmp(dstdir,"NONE")==0) break;

            if (stricmp(dstdir,dir[d])==0)
            {
                char *ext=0;
                int validdoxyfile = 1;
                if (stricmp(typ,"asm")==0 || stricmp(typ,"s")==0)
                    ext = ASMEXTENSION;
                if (stricmp(typ,"asm")==0 || stricmp(typ,"s")==0 || stricmp(typ,"inc")==0)
                    validdoxyfile = 0;
                if (!ext)
                    ext = typ;

                char extension[SPITMAXLINE];
                sprintf(extension,"%s%s",ext[0]?".":"",ext);

                if (srclst && atoi(rating)>=1)
                    fprintf(srclst,"%s%s%s%s\n",srcdir,DIRSEP,src,extension);
                if (srclst0 && atoi(rating)>=0)
                    fprintf(srclst0,"%s%s%s%s\n",srcdir,DIRSEP,src,extension);
                if (srclstc && atoi(rating)>=1 && (stricmp(ext,ASMEXTENSION)))
                    fprintf(srclstc,"%s%s%s%s\n",srcdir,DIRSEP,src,extension);
                fprintf(makelst,".h\"%s\",\"%s\",%-32s %s%s%s%s=%s.obj\n",section,author,rating,srcdir,DIRSEP,src,extension,obj);
                if (makelst2 && atoi(rating)>=2)
                    fprintf(makelst2,".h\"%s\",\"%s\",%-32s %s%s%s%s=%s.obj\n",section,author,rating,srcdir,DIRSEP,src,extension,obj);
                if (makelst0 && atoi(rating)>=0)
                    fprintf(makelst0,".h\"%s\",\"%s\",%-32s %s%s%s%s=%s.obj\n",section,author,rating,srcdir,DIRSEP,src,extension,obj);
                if (makelstdoxy && validdoxyfile)
                    fprintf(makelstdoxy,"%s%s%s%s%s%s \\\n",rootpath,DIRSEP,srcdir,DIRSEP,src,extension);
                if (makelstdoxy2 && atoi(rating)>=2 && validdoxyfile)
                    fprintf(makelstdoxy2,"%s%s%s%s%s%s \\\n",rootpath,DIRSEP,srcdir,DIRSEP,src,extension);
                if (makelstdoxy0 && atoi(rating)>=0 && validdoxyfile)
                    fprintf(makelstdoxy0,"%s%s%s%s%s%s \\\n",rootpath,DIRSEP,srcdir,DIRSEP,src,extension);
                if (makelstc && atoi(rating)>=1 && (stricmp(ext,ASMEXTENSION)))
                    fprintf(makelstc,".h\"%s\",\"%s\",%-32s %s%s%s%s=%s.obj\n",section,author,rating,srcdir,DIRSEP,src,extension,obj);

                if (stricmp(typ,"ABS")==0)
                    break;

                if (makeh && atoi(rating)>=1)
                    fprintf(makeh,"extern char %s[];\n", src);

                if (atoi(rating)>=1)
                {
                    ++numobjf;
                    if (numobjf!=objectcount[d])
                    {
                        if (numobjf%255==0)
                        {
                            char *np=RSPFORMATNP;
                            if (*np)
                                fprintf(rspf, RSPFORMATNP,obj);
                            else
                                fprintf(rspf, RSPFORMATNL,obj);
                        }
                        else
                        {
                            if (numobjf%5==0)
                                fprintf(rspf, RSPFORMATNL,obj);
                            else
                                fprintf(rspf, RSPFORMAT,obj);
                        }
                    }
                    else
                        fprintf(rspf, RSPFORMAT,obj);
                }

                break;
            }
        }
    }
    if (makeh)
        fprintf(makeh,"\n");
    fprintf(rspf,RSPSTOP);
    ok = 1;

getout:
    if (srclst)   fclose(srclst);   srclst = 0;
    if (srclst0)  fclose(srclst0);  srclst0 = 0;
    if (srclstc)  fclose(srclstc);  srclstc = 0;
    if (makelst)  fclose(makelst);  makelst = 0;
    if (makelst2) fclose(makelst2); makelst2 = 0;
    if (makelst0) fclose(makelst0); makelst0 = 0;
    if (makelstdoxy)  fclose(makelstdoxy);  makelstdoxy = 0;
    if (makelstdoxy2) fclose(makelstdoxy2); makelstdoxy2 = 0;
    if (makelstdoxy0) fclose(makelstdoxy0); makelstdoxy0 = 0;
    if (makelstc) fclose(makelstc); makelstc = 0;
    if (makeh)    fclose(makeh);    makeh = 0;
    if (rspf)     fclose(rspf);     rspf = 0;
    return(ok);
}


/****************************************************************/
/*  Pass 2: make file target list                               */
/****************************************************************/

static int Pass2(void)
{
    int ok=0;

    if (makefile0[d][0]) makef0=fopen(makefile0[d],"wb"); if (!makef0) { printf("Cannot open '%s'. Skipping. ",makefile0[d]); goto getout; }
    if (makefile1[d][0]) makef1=fopen(makefile1[d],"wb");
    if (makefile2[d][0]) makef2=fopen(makefile2[d],"wb");
    if (makefile3[d][0]) makef3=fopen(makefile3[d],"wb");
    if (makefile4[d][0]) makef4=fopen(makefile4[d],"wb");
    if (makefile5[d][0]) makef5=fopen(makefile5[d],"wb");
    if (makefile6[d][0]) makef6=fopen(makefile6[d],"wb");
    if (makefile7[d][0]) makef7=fopen(makefile7[d],"wb");
    if (makefile8[d][0]) makef8=fopen(makefile8[d],"wb");
    if (makefile9[d][0]) makef9=fopen(makefile9[d],"wb");

    BMW_fprintf(makef0,MSTART, dir[d], OBJDIR0, libname, cfg[d]);
    BMW_fprintf(makef1,MSTART, dir[d], OBJDIR1, libname, cfg[d]);
    BMW_fprintf(makef2,MSTART, dir[d], OBJDIR2, libname, cfg[d]);
    BMW_fprintf(makef3,MSTART, dir[d], OBJDIR3, libname, cfg[d]);
    BMW_fprintf(makef4,MSTART, dir[d], OBJDIR4, libname, cfg[d]);
    BMW_fprintf(makef5,MSTART, dir[d], OBJDIR5, libname, cfg[d]);
    BMW_fprintf(makef6,MSTART, dir[d], OBJDIR6, libname, cfg[d]);
    BMW_fprintf(makef7,MSTART, dir[d], OBJDIR7, libname, cfg[d]);
    BMW_fprintf(makef8,MSTART, dir[d], OBJDIR8, libname, cfg[d]);
    BMW_fprintf(makef9,MSTART, dir[d], OBJDIR9, libname, cfg[d]);

    morelines=1;
    lineptr=s;      /* goto first line of actual data base */
    nextline();
    nextline();
    nextline();
    if (atoi(libdbversion)<2)
        nextline();
    numobjf = 0;
    while (morelines)
    {
        parseline();
        if (OPTverbose>=VLEVEL)
        {
            printf("   2 %s\r",src);
            SPIT_flush();
        }

        while (parse(dstdir))
        {
            if (stricmp(dstdir,"NONE")==0 || stricmp(typ,"ABS")==0 || (atoi(rating)<1)) break;

            if (stricmp(dstdir,dir[d])==0)
            {
                ++numobjf;
                if (numobjf%5==0 && numobjf!=objectcount[d])
                {
                    BMW_fprintf(makef0,DEPFORMATNL,dstdir,OBJDIR0,obj);
                    BMW_fprintf(makef1,DEPFORMATNL,dstdir,OBJDIR1, obj);
                    BMW_fprintf(makef2,DEPFORMATNL,dstdir,OBJDIR2, obj);
                    BMW_fprintf(makef3,DEPFORMATNL,dstdir,OBJDIR3, obj);
                    BMW_fprintf(makef4,DEPFORMATNL,dstdir,OBJDIR4, obj);
                    BMW_fprintf(makef5,DEPFORMATNL,dstdir,OBJDIR5, obj);
                    BMW_fprintf(makef6,DEPFORMATNL,dstdir,OBJDIR6, obj);
                    BMW_fprintf(makef7,DEPFORMATNL,dstdir,OBJDIR7, obj);
                    BMW_fprintf(makef8,DEPFORMATNL,dstdir,OBJDIR8, obj);
                    BMW_fprintf(makef9,DEPFORMATNL,dstdir,OBJDIR9, obj);
                }
                else
                {
                    BMW_fprintf(makef0,DEPFORMAT,dstdir,OBJDIR0,obj);
                    BMW_fprintf(makef1,DEPFORMAT,dstdir,OBJDIR1, obj);
                    BMW_fprintf(makef2,DEPFORMAT,dstdir,OBJDIR2, obj);
                    BMW_fprintf(makef3,DEPFORMAT,dstdir,OBJDIR3, obj);
                    BMW_fprintf(makef4,DEPFORMAT,dstdir,OBJDIR4, obj);
                    BMW_fprintf(makef5,DEPFORMAT,dstdir,OBJDIR5, obj);
                    BMW_fprintf(makef6,DEPFORMAT,dstdir,OBJDIR6, obj);
                    BMW_fprintf(makef7,DEPFORMAT,dstdir,OBJDIR7, obj);
                    BMW_fprintf(makef8,DEPFORMAT,dstdir,OBJDIR8, obj);
                    BMW_fprintf(makef9,DEPFORMAT,dstdir,OBJDIR9, obj);
                }

                break;
            }
        }
    }

    {
        char *fstop;
        fstop = FSTOP0; if (!*fstop) fstop = FSTOP; BMW_fprintf(makef0,fstop);
        fstop = FSTOP1; if (!*fstop) fstop = FSTOP; BMW_fprintf(makef1,fstop);
        fstop = FSTOP2; if (!*fstop) fstop = FSTOP; BMW_fprintf(makef2,fstop);
        fstop = FSTOP3; if (!*fstop) fstop = FSTOP; BMW_fprintf(makef3,fstop);
        fstop = FSTOP4; if (!*fstop) fstop = FSTOP; BMW_fprintf(makef4,fstop);
        fstop = FSTOP5; if (!*fstop) fstop = FSTOP; BMW_fprintf(makef5,fstop);
        fstop = FSTOP6; if (!*fstop) fstop = FSTOP; BMW_fprintf(makef6,fstop);
        fstop = FSTOP7; if (!*fstop) fstop = FSTOP; BMW_fprintf(makef7,fstop);
        fstop = FSTOP8; if (!*fstop) fstop = FSTOP; BMW_fprintf(makef8,fstop);
        fstop = FSTOP9; if (!*fstop) fstop = FSTOP; BMW_fprintf(makef9,fstop);
    }
    ok = 1;

getout:
    return(ok);
}



/****************************************************************/
/*  Pass 3: makes for each object                               */
/****************************************************************/

static void Pass3(void)
{
    int objfirst=0;
    char defbuf[100];
    char *f = OBJFIRST;

    if (*f)
    {
        if (tolower(*f)=='y')
            objfirst = 1;
    }

    morelines=1;
    lineptr=s;      /* goto first line of actual data base */
    nextline();
    nextline();
    nextline();
    if (atoi(libdbversion)<2)
        nextline();
    while (morelines)
    {
        parseline();
        if (OPTverbose>=VLEVEL)
        {
            printf("   3 %s\r",src);
            SPIT_flush();
        }

        while (parse(dstdir))
        {
            if (stricmp(dstdir,"NONE")==0 || stricmp(typ,"ABS")==0 || (atoi(rating)<1)) break;

            if (stricmp(dstdir,dir[d])==0)
            {
                strcpy(dstdef,dstdir);
                strupr(dstdef);

                flagsextraasmdef[0] = 0;
                flagsextracppdef[0] = 0;
                flagsextradsmdef[0] = 0;
                flagsextracdef[0] = 0;
                if (flags[0])
                {
                    makeextraoptions(flagsextraasmdef,EXTRAASMDEF,flags);
                    makeextraoptions(flagsextracppdef,EXTRACPPDEF,flags);
                    makeextraoptions(flagsextradsmdef,EXTRADSMDEF,flags);
                    makeextraoptions(flagsextracdef,EXTRACDEF,flags);
                }

                if (flags2[0])
                {
                    makeextraoptions(defbuf,EXTRAASMDEF,flags2);  strcat(flagsextraasmdef,defbuf);
                    makeextraoptions(defbuf,EXTRACPPDEF,flags2);  strcat(flagsextracppdef,defbuf);
                    makeextraoptions(defbuf,EXTRADSMDEF,flags2);  strcat(flagsextradsmdef,defbuf);
                    makeextraoptions(defbuf,EXTRACDEF,flags2);    strcat(flagsextracdef,defbuf);
                }

/*                dbopts = 0; */
/*                if (!strcmp(section,"DEBUG")) */
/*                    dbopts = 1; */

                if (stricmp(typ,"asm")==0 || stricmp(typ,"s")==0)
                {
                    BMW_fprintf(makef0,FLATASMDEP,dstdir,OBJDIR0,obj,srcdir,src,section);
                    BMW_fprintf(makef1,FLATASMDEP,dstdir,OBJDIR1,obj,srcdir,src,section);
                    BMW_fprintf(makef2,FLATASMDEP,dstdir,OBJDIR2,obj,srcdir,src,section);
                    BMW_fprintf(makef3,FLATASMDEP,dstdir,OBJDIR3,obj,srcdir,src,section);
                    BMW_fprintf(makef4,FLATASMDEP,dstdir,OBJDIR4,obj,srcdir,src,section);
                    BMW_fprintf(makef5,FLATASMDEP,dstdir,OBJDIR5,obj,srcdir,src,section);
                    BMW_fprintf(makef6,FLATASMDEP,dstdir,OBJDIR6,obj,srcdir,src,section);
                    BMW_fprintf(makef7,FLATASMDEP,dstdir,OBJDIR7,obj,srcdir,src,section);
                    BMW_fprintf(makef8,FLATASMDEP,dstdir,OBJDIR8,obj,srcdir,src,section);
                    BMW_fprintf(makef9,FLATASMDEP,dstdir,OBJDIR9,obj,srcdir,src,section);
                    if (objfirst)
                    {
                        BMW_fprintf(makef0,FLATASM0,dstdef,makeextraasmdef,flagsextraasmdef,dstdir,OBJDIR0,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef1,FLATASM1,dstdef,makeextraasmdef,flagsextraasmdef,dstdir,OBJDIR1,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef2,FLATASM2,dstdef,makeextraasmdef,flagsextraasmdef,dstdir,OBJDIR2,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef3,FLATASM3,dstdef,makeextraasmdef,flagsextraasmdef,dstdir,OBJDIR3,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef4,FLATASM4,dstdef,makeextraasmdef,flagsextraasmdef,dstdir,OBJDIR4,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef5,FLATASM5,dstdef,makeextraasmdef,flagsextraasmdef,dstdir,OBJDIR5,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef6,FLATASM6,dstdef,makeextraasmdef,flagsextraasmdef,dstdir,OBJDIR6,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef7,FLATASM7,dstdef,makeextraasmdef,flagsextraasmdef,dstdir,OBJDIR7,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef8,FLATASM8,dstdef,makeextraasmdef,flagsextraasmdef,dstdir,OBJDIR8,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef9,FLATASM9,dstdef,makeextraasmdef,flagsextraasmdef,dstdir,OBJDIR9,obj,srcdir,src,srcdir,src);
                    }
                    else
                    {
                        BMW_fprintf(makef0,FLATASM0,dstdef,makeextraasmdef,flagsextraasmdef,srcdir,src,dstdir,OBJDIR0,obj,srcdir,src);
                        BMW_fprintf(makef1,FLATASM1,dstdef,makeextraasmdef,flagsextraasmdef,srcdir,src,dstdir,OBJDIR1,obj,srcdir,src);
                        BMW_fprintf(makef2,FLATASM2,dstdef,makeextraasmdef,flagsextraasmdef,srcdir,src,dstdir,OBJDIR2,obj,srcdir,src);
                        BMW_fprintf(makef3,FLATASM3,dstdef,makeextraasmdef,flagsextraasmdef,srcdir,src,dstdir,OBJDIR3,obj,srcdir,src);
                        BMW_fprintf(makef4,FLATASM4,dstdef,makeextraasmdef,flagsextraasmdef,srcdir,src,dstdir,OBJDIR4,obj,srcdir,src);
                        BMW_fprintf(makef5,FLATASM5,dstdef,makeextraasmdef,flagsextraasmdef,srcdir,src,dstdir,OBJDIR5,obj,srcdir,src);
                        BMW_fprintf(makef6,FLATASM6,dstdef,makeextraasmdef,flagsextraasmdef,srcdir,src,dstdir,OBJDIR6,obj,srcdir,src);
                        BMW_fprintf(makef7,FLATASM7,dstdef,makeextraasmdef,flagsextraasmdef,srcdir,src,dstdir,OBJDIR7,obj,srcdir,src);
                        BMW_fprintf(makef8,FLATASM8,dstdef,makeextraasmdef,flagsextraasmdef,srcdir,src,dstdir,OBJDIR8,obj,srcdir,src);
                        BMW_fprintf(makef9,FLATASM9,dstdef,makeextraasmdef,flagsextraasmdef,srcdir,src,dstdir,OBJDIR9,obj,srcdir,src);
                    }
                }

                if (stricmp(typ,"cpp")==0 || stricmp(typ,"c++")==0)
                {
                    BMW_fprintf(makef0,FLATCPPDEP,dstdir,OBJDIR0,obj,srcdir,src,section);
                    BMW_fprintf(makef1,FLATCPPDEP,dstdir,OBJDIR1,obj,srcdir,src,section);
                    BMW_fprintf(makef2,FLATCPPDEP,dstdir,OBJDIR2,obj,srcdir,src,section);
                    BMW_fprintf(makef3,FLATCPPDEP,dstdir,OBJDIR3,obj,srcdir,src,section);
                    BMW_fprintf(makef4,FLATCPPDEP,dstdir,OBJDIR4,obj,srcdir,src,section);
                    BMW_fprintf(makef5,FLATCPPDEP,dstdir,OBJDIR5,obj,srcdir,src,section);
                    BMW_fprintf(makef6,FLATCPPDEP,dstdir,OBJDIR6,obj,srcdir,src,section);
                    BMW_fprintf(makef7,FLATCPPDEP,dstdir,OBJDIR7,obj,srcdir,src,section);
                    BMW_fprintf(makef8,FLATCPPDEP,dstdir,OBJDIR8,obj,srcdir,src,section);
                    BMW_fprintf(makef9,FLATCPPDEP,dstdir,OBJDIR9,obj,srcdir,src,section);
                    if (objfirst)
                    {
                        BMW_fprintf(makef0,FLATCPP0,dstdef,makeextracppdef,flagsextracppdef,dstdir,OBJDIR0,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef1,FLATCPP1,dstdef,makeextracppdef,flagsextracppdef,dstdir,OBJDIR1,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef2,FLATCPP2,dstdef,makeextracppdef,flagsextracppdef,dstdir,OBJDIR2,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef3,FLATCPP3,dstdef,makeextracppdef,flagsextracppdef,dstdir,OBJDIR3,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef4,FLATCPP4,dstdef,makeextracppdef,flagsextracppdef,dstdir,OBJDIR4,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef5,FLATCPP5,dstdef,makeextracppdef,flagsextracppdef,dstdir,OBJDIR5,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef6,FLATCPP6,dstdef,makeextracppdef,flagsextracppdef,dstdir,OBJDIR6,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef7,FLATCPP7,dstdef,makeextracppdef,flagsextracppdef,dstdir,OBJDIR7,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef8,FLATCPP8,dstdef,makeextracppdef,flagsextracppdef,dstdir,OBJDIR8,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef9,FLATCPP9,dstdef,makeextracppdef,flagsextracppdef,dstdir,OBJDIR9,obj,srcdir,src,srcdir,src);
                    }
                    else
                    {
                        BMW_fprintf(makef0,FLATCPP0,dstdef,makeextracppdef,flagsextracppdef,srcdir,src,dstdir,OBJDIR0,obj,srcdir,src);
                        BMW_fprintf(makef1,FLATCPP1,dstdef,makeextracppdef,flagsextracppdef,srcdir,src,dstdir,OBJDIR1,obj,srcdir,src);
                        BMW_fprintf(makef2,FLATCPP2,dstdef,makeextracppdef,flagsextracppdef,srcdir,src,dstdir,OBJDIR2,obj,srcdir,src);
                        BMW_fprintf(makef3,FLATCPP3,dstdef,makeextracppdef,flagsextracppdef,srcdir,src,dstdir,OBJDIR3,obj,srcdir,src);
                        BMW_fprintf(makef4,FLATCPP4,dstdef,makeextracppdef,flagsextracppdef,srcdir,src,dstdir,OBJDIR4,obj,srcdir,src);
                        BMW_fprintf(makef5,FLATCPP5,dstdef,makeextracppdef,flagsextracppdef,srcdir,src,dstdir,OBJDIR5,obj,srcdir,src);
                        BMW_fprintf(makef6,FLATCPP6,dstdef,makeextracppdef,flagsextracppdef,srcdir,src,dstdir,OBJDIR6,obj,srcdir,src);
                        BMW_fprintf(makef7,FLATCPP7,dstdef,makeextracppdef,flagsextracppdef,srcdir,src,dstdir,OBJDIR7,obj,srcdir,src);
                        BMW_fprintf(makef8,FLATCPP8,dstdef,makeextracppdef,flagsextracppdef,srcdir,src,dstdir,OBJDIR8,obj,srcdir,src);
                        BMW_fprintf(makef9,FLATCPP9,dstdef,makeextracppdef,flagsextracppdef,srcdir,src,dstdir,OBJDIR9,obj,srcdir,src);
                    }
                }


                if (stricmp(typ,"c")==0)
                {
                    BMW_fprintf(makef0,FLATCDEP,dstdir,OBJDIR0,obj,srcdir,src,section);
                    BMW_fprintf(makef1,FLATCDEP,dstdir,OBJDIR1,obj,srcdir,src,section);
                    BMW_fprintf(makef2,FLATCDEP,dstdir,OBJDIR2,obj,srcdir,src,section);
                    BMW_fprintf(makef3,FLATCDEP,dstdir,OBJDIR3,obj,srcdir,src,section);
                    BMW_fprintf(makef4,FLATCDEP,dstdir,OBJDIR4,obj,srcdir,src,section);
                    BMW_fprintf(makef5,FLATCDEP,dstdir,OBJDIR5,obj,srcdir,src,section);
                    BMW_fprintf(makef6,FLATCDEP,dstdir,OBJDIR6,obj,srcdir,src,section);
                    BMW_fprintf(makef7,FLATCDEP,dstdir,OBJDIR7,obj,srcdir,src,section);
                    BMW_fprintf(makef8,FLATCDEP,dstdir,OBJDIR8,obj,srcdir,src,section);
                    BMW_fprintf(makef9,FLATCDEP,dstdir,OBJDIR9,obj,srcdir,src,section);
                    if (objfirst)
                    {
                        BMW_fprintf(makef0,(dbopts)?FLATC1:FLATC0,dstdef,makeextracdef,flagsextracdef,dstdir,OBJDIR0,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef1,FLATC1,                dstdef,makeextracdef,flagsextracdef,dstdir,OBJDIR1,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef2,FLATC2,                dstdef,makeextracdef,flagsextracdef,dstdir,OBJDIR2,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef3,FLATC3,                dstdef,makeextracdef,flagsextracdef,dstdir,OBJDIR3,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef4,FLATC4,                dstdef,makeextracdef,flagsextracdef,dstdir,OBJDIR4,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef5,FLATC5,                dstdef,makeextracdef,flagsextracdef,dstdir,OBJDIR5,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef6,FLATC6,                dstdef,makeextracdef,flagsextracdef,dstdir,OBJDIR6,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef7,FLATC7,                dstdef,makeextracdef,flagsextracdef,dstdir,OBJDIR7,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef8,FLATC8,                dstdef,makeextracdef,flagsextracdef,dstdir,OBJDIR8,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef9,FLATC9,                dstdef,makeextracdef,flagsextracdef,dstdir,OBJDIR9,obj,srcdir,src,srcdir,src);
                    }
                    else
                    {
                        BMW_fprintf(makef0,(dbopts)?FLATC1:FLATC0,dstdef,makeextracdef,flagsextracdef,srcdir,src,dstdir,OBJDIR0,obj,srcdir,src);
                        BMW_fprintf(makef1,FLATC1,                dstdef,makeextracdef,flagsextracdef,srcdir,src,dstdir,OBJDIR1,obj,srcdir,src);
                        BMW_fprintf(makef2,FLATC2,                dstdef,makeextracdef,flagsextracdef,srcdir,src,dstdir,OBJDIR2,obj,srcdir,src);
                        BMW_fprintf(makef3,FLATC3,                dstdef,makeextracdef,flagsextracdef,srcdir,src,dstdir,OBJDIR3,obj,srcdir,src);
                        BMW_fprintf(makef4,FLATC4,                dstdef,makeextracdef,flagsextracdef,srcdir,src,dstdir,OBJDIR4,obj,srcdir,src);
                        BMW_fprintf(makef5,FLATC5,                dstdef,makeextracdef,flagsextracdef,srcdir,src,dstdir,OBJDIR5,obj,srcdir,src);
                        BMW_fprintf(makef6,FLATC6,                dstdef,makeextracdef,flagsextracdef,srcdir,src,dstdir,OBJDIR6,obj,srcdir,src);
                        BMW_fprintf(makef7,FLATC7,                dstdef,makeextracdef,flagsextracdef,srcdir,src,dstdir,OBJDIR7,obj,srcdir,src);
                        BMW_fprintf(makef8,FLATC8,                dstdef,makeextracdef,flagsextracdef,srcdir,src,dstdir,OBJDIR8,obj,srcdir,src);
                        BMW_fprintf(makef9,FLATC9,                dstdef,makeextracdef,flagsextracdef,srcdir,src,dstdir,OBJDIR9,obj,srcdir,src);
                    }
                }

                if (stricmp(typ,"vsm")==0 || stricmp(typ,"dsm")==0 || stricmp(typ,"usr")==0)
                {
                    BMW_fprintf(makef0,FLATDSMDEP,dstdir,OBJDIR0,obj,srcdir,src,section);
                    BMW_fprintf(makef1,FLATDSMDEP,dstdir,OBJDIR1,obj,srcdir,src,section);
                    BMW_fprintf(makef2,FLATDSMDEP,dstdir,OBJDIR2,obj,srcdir,src,section);
                    BMW_fprintf(makef3,FLATDSMDEP,dstdir,OBJDIR3,obj,srcdir,src,section);
                    BMW_fprintf(makef4,FLATDSMDEP,dstdir,OBJDIR4,obj,srcdir,src,section);
                    BMW_fprintf(makef5,FLATDSMDEP,dstdir,OBJDIR5,obj,srcdir,src,section);
                    BMW_fprintf(makef6,FLATDSMDEP,dstdir,OBJDIR6,obj,srcdir,src,section);
                    BMW_fprintf(makef7,FLATDSMDEP,dstdir,OBJDIR7,obj,srcdir,src,section);
                    BMW_fprintf(makef8,FLATDSMDEP,dstdir,OBJDIR8,obj,srcdir,src,section);
                    BMW_fprintf(makef9,FLATDSMDEP,dstdir,OBJDIR9,obj,srcdir,src,section);
                    if (objfirst)
                    {
                        BMW_fprintf(makef0,FLATDSM0,dstdef,makeextradsmdef,flagsextradsmdef,dstdir,OBJDIR0,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef1,FLATDSM1,dstdef,makeextradsmdef,flagsextradsmdef,dstdir,OBJDIR1,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef2,FLATDSM2,dstdef,makeextradsmdef,flagsextradsmdef,dstdir,OBJDIR2,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef3,FLATDSM3,dstdef,makeextradsmdef,flagsextradsmdef,dstdir,OBJDIR3,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef4,FLATDSM4,dstdef,makeextradsmdef,flagsextradsmdef,dstdir,OBJDIR4,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef5,FLATDSM5,dstdef,makeextradsmdef,flagsextradsmdef,dstdir,OBJDIR5,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef6,FLATDSM6,dstdef,makeextradsmdef,flagsextradsmdef,dstdir,OBJDIR6,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef7,FLATDSM7,dstdef,makeextradsmdef,flagsextradsmdef,dstdir,OBJDIR7,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef8,FLATDSM8,dstdef,makeextradsmdef,flagsextradsmdef,dstdir,OBJDIR8,obj,srcdir,src,srcdir,src);
                        BMW_fprintf(makef9,FLATDSM9,dstdef,makeextradsmdef,flagsextradsmdef,dstdir,OBJDIR9,obj,srcdir,src,srcdir,src);
                    }
                    else
                    {
                        BMW_fprintf(makef0,FLATDSM0,dstdef,makeextradsmdef,flagsextradsmdef,srcdir,src,dstdir,OBJDIR0,obj,srcdir,src);
                        BMW_fprintf(makef1,FLATDSM1,dstdef,makeextradsmdef,flagsextradsmdef,srcdir,src,dstdir,OBJDIR1,obj,srcdir,src);
                        BMW_fprintf(makef2,FLATDSM2,dstdef,makeextradsmdef,flagsextradsmdef,srcdir,src,dstdir,OBJDIR2,obj,srcdir,src);
                        BMW_fprintf(makef3,FLATDSM3,dstdef,makeextradsmdef,flagsextradsmdef,srcdir,src,dstdir,OBJDIR3,obj,srcdir,src);
                        BMW_fprintf(makef4,FLATDSM4,dstdef,makeextradsmdef,flagsextradsmdef,srcdir,src,dstdir,OBJDIR4,obj,srcdir,src);
                        BMW_fprintf(makef5,FLATDSM5,dstdef,makeextradsmdef,flagsextradsmdef,srcdir,src,dstdir,OBJDIR5,obj,srcdir,src);
                        BMW_fprintf(makef6,FLATDSM6,dstdef,makeextradsmdef,flagsextradsmdef,srcdir,src,dstdir,OBJDIR6,obj,srcdir,src);
                        BMW_fprintf(makef7,FLATDSM7,dstdef,makeextradsmdef,flagsextradsmdef,srcdir,src,dstdir,OBJDIR7,obj,srcdir,src);
                        BMW_fprintf(makef8,FLATDSM8,dstdef,makeextradsmdef,flagsextradsmdef,srcdir,src,dstdir,OBJDIR8,obj,srcdir,src);
                        BMW_fprintf(makef9,FLATDSM9,dstdef,makeextradsmdef,flagsextradsmdef,srcdir,src,dstdir,OBJDIR9,obj,srcdir,src);
                    }
                }
                break;
            }
        }
    }
}


#if 0
/*
;
; ABSTRACT
;
; bmw - Build Make & WEB files from a data base
;
; SUMMARY
;
; bmw -options <database> <target>
;     @file     response file, containing a list of options and files
;     -c<name>  specify a config file to override database config files
;     -nologo   disable banner
;     -time     show execution time
;     -v0       no console output
;     -v1       prints source file name and errors
;     -v2       status line for each file (default)
;     -v3       additional info
;     -v6       debug info
;
; DESCRIPTION
;
; BMW creates make files for multi-platform projects, using
; a shared database.  It builds makes files for release, debug and assert,
; versions of a technology.  C++, C, assembler, documentation
; and a user defined builder can all be configured with a config file
; that resembles a C macro file.
; BMW also outputs lists of source files used, for documentation and
; installer purposes
;
; Basic usage of bmw is
;   bmw libdb
;   make -f unix/libz.mak
;
; The following is an example libdb:
;
; 2,lib,crapi
; pc,,,,ps2,,,,xbox,,,,gc,,,,unix,,,
; unix,,,
;
; see http://tools.eac.ea.com/util/bmw.htm
; ;name       ,,lng,flags   ,component,se,rate,source ,targets
; ;----         --- -----    --------- -- ---- ------  -------
; copenlib    ,,cpp,        ,COPEN    ,fb,3   ,cmn    ,pc,ps2,xbox,gc,unix
; cremap      ,,cpp,        ,COPEN    ,fb,3   ,cmn    ,pc,ps2,xbox,gc,unix
; nil         ,,cpp,        ,CRAPI    ,fb,2   ,cmn    ,pc,ps2,xbox,gc,unix
; wu          ,,cpp,        ,CRAPI    ,fb,3   ,cmn    ,pc,ps2,xbox,gc,unix
; wu555       ,,cpp,        ,CRAPI    ,fb,3   ,cmn    ,pc,ps2,xbox,gc,unix
; wu777       ,,cpp,        ,CRAPI    ,fb,3   ,cmn    ,pc,ps2,xbox,gc,unix
; exact       ,,cpp,        ,CRAPI    ,fb,2   ,cmn    ,pc,ps2,xbox,gc,unix
; alpha       ,,cpp,        ,CRAPI    ,fb,2   ,cmn    ,pc,ps2,xbox,gc,unix
; fu          ,,cpp,        ,CRAPI    ,fb,3   ,cmn    ,pc,ps2,xbox,gc,unix
; END
;
; First line of libdb:
;   <libdb version #>, <output filename prefix>, <name of library>
;   libdb version # should always be 2, but these are the other values:
;     0 initial version
;     1 added SE column
;     2 removed def2, and mac line (use osx)
;   output filename prefix is used for output filenames. ie libz.mak
;   name of library passed into start for make (MSTART) and response
;     file start (RSPFLATSTART).  Its often not used.
;
; Second and third lines define the target platforms.  Both lines are in
;   the same format: Second is for PC based build, while third is for unix
;   or OSX based builds.
;   For example platform there are 4 fields, but only the first field is
;   required.  The example above uses defaults.  A most complex example
;   would be (from gimex libdb):
;
;   rt,RT,pc,cmn
;
;   Field  Name      Example  Description
;   0      platform  rt       target platform, used primarily in 'targets'
;   1      define    RT       an extra define passed to compiler. ie /DRT=1
;   2      config    pc       name of config file to use. ie pc.cfg
;   3      star      cmn      if * specified for source folder, use this folder instead
;
; The main database fields:
;   After the third line, there must be a blank line, and typically optional
;   comment lines.  From the crapi example:
;
;   name       ,,lng,flags   ,component,se,rate,source ,targets
;   ----         --- -----    --------- -- ---- ------  -------
;   wu         ,,cpp,        ,CRAPI    ,fb,3   ,cmn    ,pc,ps2,xbox,gc,unix
;
; Field              Description
; name               source file name, without extension
; (destination name) optional output filename for object file
; flags              extra defines, or if flag, if - or / is first character
; component          output in documentation response files
; se                 engineer, for documentation response files
; rate               rating 0..5 for documentation and installer response files. 3 default
; source             source folder. normally 'cmn' or platform. can use * so that each target has source in target folder
; targets            one or more targets from 2nd/3rd line
;
; END keyword stops libdb parsing.  END is optional, but allows the user
;   to place libdb entries after it that will be ignored (removed)
;
; Example pc.cfg:
;
;   /* rules for CPP */
;
;   #define FLATCPPDEP      "%s\\%s\\%s.obj: %s\\%s.cpp\n"
;   #define FLATCPP0        " $(ICL)   /c /W3 /WX /GB /GF /Qopenmp /MT /nologo /O2               /DWIN32_LEAN_AND_MEAN /D%s%s%s /Fd$(BLDLIB).pdb /Fo%s\\%s\\%s %s\\%s.cpp\n\n"
;   #define FLATCPP1        " $(ICL)   /c /W3 /WX /GB /GF /Qopenmp /MT /nologo /Od /Zi /DDEBUG=1 /DWIN32_LEAN_AND_MEAN /D%s%s%s /Fd$(BLDLIB).pdb /Fo%s\\%s\\%s %s\\%s.cpp\n\n"
;   #define FLATCPP2        " $(ICL)   /c /W3 /WX /GB /GF /Qopenmp /MD /nologo /O2               /DWIN32_LEAN_AND_MEAN /D%s%s%s /Fd$(BLDLIB).pdb /Fo%s\\%s\\%s %s\\%s.cpp\n\n"
;
;   /* rules for C */
;
;   #define FLATCDEP        "%s\\%s\\%s.obj: %s\\%s.c\n"
;   #define FLATC0          " $(ICL)   /c /W3 /WX /GB /GF /Qopenmp /MT /nologo /O2               /DWIN32_LEAN_AND_MEAN /D%s%s%s /Fd$(BLDLIB).pdb /Fo%s\\%s\\%s %s\\%s.c\n\n"
;   #define FLATC1          " $(ICL)   /c /W3 /WX /GB /GF /Qopenmp /MT /nologo /Od /Zi /DDEBUG=1 /DWIN32_LEAN_AND_MEAN /D%s%s%s /Fd$(BLDLIB).pdb /Fo%s\\%s\\%s %s\\%s.c\n\n"
;   #define FLATC2          " $(ICL)   /c /W3 /WX /GB /GF /Qopenmp /MD /nologo /O2               /DWIN32_LEAN_AND_MEAN /D%s%s%s /Fd$(BLDLIB).pdb /Fo%s\\%s\\%s %s\\%s.c\n\n"
;
;   /* rules for ASM */
;
;   #define FLATASMDEP      "%s\\%s\\%s.obj: %s\\%s.asm\n"
;   #define FLATASM0        " @ml /c /Cp /Cx /Zi /coff /W2 /WX /nologo /DMASM /D%s%s%s                     /Fo%s\\%s\\%s %s\\%s.asm\n\n"
;   #define FLATASM1        " @ml /c /Cp /Cx /Zi /coff /W2 /WX /nologo /DMASM /DDEBUG /D%s%s%s             /Fo%s\\%s\\%s %s\\%s.asm\n\n"
;   #define FLATASM2        " @ml /c /Cp /Cx /Zi /coff /W2 /WX /nologo /DMASM /D%s%s%s                     /Fo%s\\%s\\%s %s\\%s.asm\n\n"
;
;   /* misc */
;
;   #define SOURCELISTNAME0 "%s\\%ssrc0.lst"
;   #define FILELISTNAME    "%s\\%s.lst"
;   #define HEADERFILENAME  "%s\\%s.h"
;   #define MAKEFILENAME0   "%s\\%sz.mak"
;   #define MAKEFILENAME1   "%s\\%sd.mak"
;   #define MAKEFILENAME2   "%s\\%sm.mak"
;   #define RSPFILENAME     "%s\\%s.rsp"
;
;   #define RSPFORMAT       " %8s.obj"
;   #define RSPFORMATNL     " %8s.obj\n"
;   #define DEPFORMAT       "%s\\%s\\%s.obj "
;   #define DEPFORMATNL     "%s\\%s\\%s.obj \\\n"
;
;   #define MSTART          "ALL : \\\n"
;   #define RSPFLATSTART    ""
;
;   #define EXTRAASMDEF     " /D%s"
;   #define EXTRACPPDEF     " /D%s"
;   #define EXTRACDEF       " /D%s"
;   #define EXTRAUSRDEF     " /D%s"
;
//;   #define RSPSTOP         "\n\n"
//;   #define FSTOP           "\n\techo build done.\n\n
//;   cmn\\fssread.cpp cmn\\gssread.cpp cmn\\xssread.cpp cmn\\mssread.cpp cmn\\sssread.cpp cmn\\fshread.cpp cmn\\pshread.cpp cmn\\nshread.cpp cmn\\gshread.cpp cmn\\xshread.cpp cmn\\vshread.cpp cmn\\mshread.cpp cmn\\sshread.cpp cmn\\ashread.cpp: cmn\\shread.cpp cmn\\shpread.h cmn\\shpgimex.h cmn\\shpcmn.h\n\n
//;   cmn\\fsswrite.cpp cmn\\gsswrite.cpp cmn\\xsswrite.cpp cmn\\msswrite.cpp cmn\\ssswrite.cpp cmn\\fshwrite.cpp cmn\\pshwrite.cpp cmn\\nshwrite.cpp cmn\\gshwrite.cpp cmn\\xshwrite.cpp cmn\\vshwrite.cpp cmn\\mshwrite.cpp cmn\\sshwrite.cpp cmn\\ashwrite.cpp: cmn\\shwrite.cpp cmn\\shpwrite.h cmn\\shpgimex.h cmn\\shpcmn.h\n\n
//;   cmn\\ffnread.cpp cmn\\pfnread.cpp cmn\\nfnread.cpp cmn\\gfnread.cpp cmn\\xfnread.cpp cmn\\mfnread.cpp cmn\\sfnread.cpp: cmn\\fntread.cpp\n\n
//;   cmn\\ffnwrite.cpp cmn\\pfnwrite.cpp cmn\\nfnwrite.cpp cmn\\gfnwrite.cpp cmn\\xfnwrite.cpp cmn\\mfnwrite.cpp cmn\\sfnwrite.cpp: cmn\\fntwrite.cpp\n\n"
;
;
;   #define OBJFIRST        "Y"
;   #define DIRSEP          "\\"
;
;   #define OBJDIR0         "objz"
;   #define OBJDIR1         "objd"
;   #define OBJDIR2         "objm"
;
; Example ps2.cfg:
;
;
;   /* rules for CPP */
;
;   #define FLATCPPDEP      "%s/%s/%s.o: %s/%s.cpp\n"
;   #define FLATCPP0        "\t@echo compiling $@\n\t@ee-gcc -O2    -xc++ -Wall -fno-common -fomit-frame-pointer -fno-rtti -fno-exceptions -ffast-math -c -D%s%s%s -Ips2 -Icmn %s/%s.cpp -o %s/%s/%s.o\n\t@ee-strip --strip-debug $@\n\n"
;   #define FLATCPP1        "\t@echo compiling $@\n\t@ee-gcc -O2    -xc++ -Wall -fno-common -fomit-frame-pointer -fno-rtti -fno-exceptions -ffast-math -c -D%s%s%s -Ips2 -Icmn %s/%s.cpp -o %s/%s/%s.o\n\n"
;   #define FLATCPP2        "\t@echo compiling $@\n\t@ee-gcc -O0 -g -xc++ -Wall -fno-common -fomit-frame-pointer -fno-rtti -fno-exceptions -ffast-math -c -D%s%s%s -Ips2 -Icmn %s/%s.cpp -o %s/%s/%s.o\n\n"
;
;   /* rules for C */
;
;   #define FLATCDEP        "%s/%s/%s.o: %s/%s.c\n"
;   #define FLATC0          "\t@echo compiling $@\n\t@ee-gcc -O2    -Wall -fno-common -fomit-frame-pointer -ffast-math -c                        -D%s%s%s -Ips2 -Icmn %s/%s.c -o %s/%s/%s.o\n\t@ee-strip --strip-debug $@\n\n"
;   #define FLATC1          "\t@echo compiling $@\n\t@ee-gcc -O2    -Wall -fno-common -fomit-frame-pointer -ffast-math -c -DDEBUG=1 -DTRACEMEM=1 -D%s%s%s -Ips2 -Icmn %s/%s.c -o %s/%s/%s.o\n\n"
;   #define FLATC2          "\t@echo compiling $@\n\t@ee-gcc -O0 -g -Wall -fno-common                      -ffast-math -c -DDEBUG=2 -DTRACEMEM=1 -D%s%s%s -Ips2 -Icmn %s/%s.c -o %s/%s/%s.o\n\n"
;
;   /* rules for ASM */
;
;   #define FLATASMDEP      "%s/%s/%s.o: %s/%s.s\n"
;   #define FLATASM0        "\t@echo assembling $@\n\t@ee-as                  --defsym %s=1%s%s %s/%s.s -o %s/%s/%s.o\n\t@ee-strip --strip-debug $@\n\n"
;   #define FLATASM1        "\t@echo assembling $@\n\t@ee-as --defsym DEBUG=1 --defsym %s=1%s%s %s/%s.s -o %s/%s/%s.o\n\n"
;   #define FLATASM2        "\t@echo assembling $@\n\t@ee-as --defsym DEBUG=2 --defsym %s=1%s%s %s/%s.s -o %s/%s/%s.o\n\n"
;   #define FLATASM3        ""
;
;   /* rules for DSM */
;
;   #define FLATDSMDEP      "%s/%s/%s.o: %s/%s.dsm\n"
;   #define FLATDSM0        "\t@echo assembling $@\n\t@ee-dvp-as                  --defsym %s=1%s%s -I$(EACINCLUDES) %s/%s.dsm -o %s/%s/%s.o\n\n"
;   #define FLATDSM1        "\t@echo assembling $@\n\t@ee-dvp-as --defsym DEBUG=1 --defsym %s=1%s%s -I$(EACINCLUDES) %s/%s.dsm -o %s/%s/%s.o\n\n"
;   #define FLATDSM2        "\t@echo assembling $@\n\t@ee-dvp-as --defsym DEBUG=2 --defsym %s=1%s%s -I$(EACINCLUDES) %s/%s.dsm -o %s/%s/%s.o\n\n"
;   #define FLATDSM3        ""
;
;   /* misc */
;
;   #define SOURCELISTNAME0 "%s\\%ssrc0.lst"
;   #define SOURCELISTNAME  "%s\\%ssrc.lst"
;   #define FILELISTNAME    "%s\\%s.lst"
;   #define FILELISTNAME2   "%s\\%s2.lst"
;   #define HEADERFILENAME  "%s\\%s.h"
;   #define MAKEFILENAME0   "%s\\%sz.mak"
;   #define MAKEFILENAME1   "%s\\%sa.mak"
;   #define MAKEFILENAME2   "%s\\%sd.mak"
;   #define MAKEFILENAME3   "%s\\%sk.mak"
;   #define RSPFILENAME     "%s\\%s.rsp"
;
;   #define RSPFORMAT       "%s.o\n"
;   #define RSPFORMATNL     "%s.o\n"
;   #define RSPFORMATNP     "%s.o\n"
;   #define DEPFORMAT       "%s\\%s\\%s.o "
;   #define DEPFORMATNL     "%s\\%s\\%s.o \\\n"
;
;   #define MSTART          "ALL : \\\n"
;   #define RSPFLATSTART    ""
;
;   #define EXTRAASMDEF     " --defsym %s=1"
;   #define EXTRACDEF       " -D%s"
;   #define EXTRADSMDEF     " --defsym %s=1"
;
;   #define RSPSTOP         "\n\n"
;   #define FSTOP           "\n\t@echo Linking...\n\n"
;
;   #define ASMEXTENSION    "s"
;   #define OBJFIRST        ""
;   #define DIRSEP          "\\"
;
;   #define OBJDIR0         "objz"
;   #define OBJDIR1         "obja"
;   #define OBJDIR2         "objd"
;   #define OBJDIR3         ""
;
; RETURNS
;
; none
;
; SEE ALSO
;
; abstract, Spit
;
; SAMPLE OUTPUT
;
; >bmw libdb
; BMW v2.52 (flags) 010925 by FrANK G. Barchard, EAC
; libdb: Reading, pc.cfg ps2.cfg
; DIRECTORY=pc, (*=pc) 9 obj
; DIRECTORY=ps2, (*=ps2) 9 obj
;
; END ABSTRACT
;
*/
#endif

void SPIT_reset(void)
{
    int i,j;

    memset(quickregtbl,0,sizeof(quickregtbl));

    for (i=0; i<MAXREGS; ++i)
    {
        for (j=0; j<MAXLIBS; ++j)
        {
            quickregtbl[i][j].start = 0;
        }
    }

    for (j=0; j<MAXLIBS; ++j)
        configfile[j] = NULL;

    OPTdestdir = 0; /* disable SPIT from checking for destination directories */
    OPTcfgfile[0] = 0;
#if defined(__WATCOMC__) || defined(_MSC_VER)
    OPTnewlinetype = 0;   /* crlf */
#elif defined(applec) || defined(powerc) || defined (__powerc)
    OPTnewlinetype = 1;   /* cr */
#else
    OPTnewlinetype = 2;   /* lf */
#endif
    return;
}

void SPIT_usage(const char *prgname, const char *envname, const char *urlname, int utype)
{
    printf("BMW v%s by FrANK G. Barchard, EAC\n",TextVersion);

    if (utype)
        printf("USAGE: %s -options <database>\n", prgname);

    switch (utype)
    {
        case 0:
        case 1:
            break;

        case 2:
            puts("     @ response file       ");
            puts("    -c specify a config file to override database config files");
            puts("    -v verbose");
          printf("type '%s -h' for more help\n",    prgname);
          printf("type '%s -help' for web page (%s)\n", prgname, urlname);
            break;

        case 3:
            puts("");
          printf("VERSION: %s v%s, Spit v%.2f\n",SPIT_MACHINE,TextVersion,(float)SPIT_VERSION/100.0f);
            puts("SUMMARY: BMW builds make files for the EAC makerary");
          printf("         SPIT environment variable is %s\n",envname);
            puts("");
            puts("    @file     response file, containing a list of options and files");
            puts("    -c<name>  specify a config file to override database config files");
            puts("    -nologo   disable banner");
            puts("    -time     show execution time");
            puts("    -v0       no console output");
            puts("    -v1       prints source file name and errors");
            puts("    -v2       status line for each file (default)");
            puts("    -v3       additional info");
            break;

        default:
            break;
    }
}

char *SPIT_opt(const char *optptr)
{
    const char *d;
    int i;
    char optbuf[SPITMAXLINE];

    for (i=0; (unsigned char)optptr[i]>(unsigned char)' '; ++i)
        optbuf[i] = (char) tolower((int)optptr[i]);
    optbuf[i] = 0;

    if (!stricmp(optbuf,"pc") || !stricmp(optbuf,"ibm") || !stricmp(optbuf,"dos") || !stricmp(optbuf,"pc") || !stricmp(optbuf,"crlf"))
    {
        OPTnewlinetype = 0;
        d = optptr+i;
    }
    else if (!stricmp(optbuf,"mac") || !stricmp(optbuf,"mpw") || !stricmp(optbuf,"ppc") || !stricmp(optbuf,"cr"))
    {
        OPTnewlinetype = 1;
        d = optptr+i;
    }
    else if (!stricmp(optbuf,"sgi") || !stricmp(optbuf,"unix")  || !stricmp(optbuf,"osx") || !stricmp(optbuf,"lf"))
    {
        OPTnewlinetype = 2;
        d = optptr+i;
    }
    else
    {
        switch (tolower(*optptr))
        {
            case 'c':
                d = SPIT_getfield( OPTcfgfile,optptr+1,1,0);
                break;

            default:
                d = 0;
        }
    }
    return((char *)d);
}

int main(int argc, char **argv)
{
    int more;
    struct SPITMEM infile={0,0};

    SPIT_init(SPIT_reset, SPIT_usage, SPIT_opt, SPIT_history);

    double totaltime = SPIT_gettime();
    do
    {
        more = SPIT_parse(argc, argv, TOOL_NAME, TOOL_VERSION);

        if (SPITargnum)
        {
            OPTtargets = (char **) 0;
            OPTnumtargets = 0;
            if (SPITargnum>=2)
            {
                OPTtargets = &SPITsargv[1];
                OPTnumtargets = SPITargnum-1;
            }

            if (SPIT_loadfile(&infile, SPITsargv[0]))
            {
                if (OPTverbose>=4)
                    printf("Parsing,\n");

                s = infile.ptr;

                ParseDirectoriesLine();

                for (d=0;d<dirs;++d)
                {
                    if (istarget(dir[d]))
                    {
                        Pass0();
                        if (!Pass1()) goto getout;
                        if (!Pass2()) goto getout;
                        Pass3();
    getout:
                        if (makef0) fclose(makef0); makef0 = 0;
                        if (makef1) fclose(makef1); makef1 = 0;
                        if (makef2) fclose(makef2); makef2 = 0;
                        if (makef3) fclose(makef3); makef3 = 0;
                        if (makef4) fclose(makef4); makef4 = 0;
                        if (makef5) fclose(makef5); makef5 = 0;
                        if (makef6) fclose(makef6); makef6 = 0;
                        if (makef7) fclose(makef7); makef7 = 0;
                        if (makef8) fclose(makef8); makef8 = 0;
                        if (makef9) fclose(makef9); makef9 = 0;
                        if (OPTverbose>=3)
                        {
                            printf("\n");
                            SPIT_flush();
                        }
                    }
                }
            }

            for (int j=0; j<MAXLIBS; ++j)
            {
                if (configfile[j])
                {
                    gfree(configfile[j]);
                    configfile[j] = NULL;
                }
            }

            SPIT_free(&infile);
            if (OPTverbose==1)
                puts("");
        }
    } while (more>0);

    SPIT_restore();

    if (galloccount)
        printf("galloccount = %i\n", galloccount);

    totaltime = SPIT_gettime()-totaltime;


    if (OPTtime)
    {
        if (totaltime>=60000.0)
            printf("TIME " TOOL_NAME " totaltime %.2f ms (%.2f seconds) (%.2f minutes)\n",totaltime,totaltime/1000.0,totaltime/60000.0);
        else if (totaltime>=1000.0)
            printf("TIME " TOOL_NAME " totaltime %.2f ms (%.2f seconds)\n",totaltime,totaltime/1000.0);
        else
            printf("TIME " TOOL_NAME " totaltime %.2f ms\n",totaltime);
    }


    return(0);
}

