DBD: DdsBuilDer
---------------
This is a tool to make it much easier to select and build Micro-C programs.

use: DBD ?
    to get command syntax information!

It will prompt you for what to build, you can simply select a single .C file
to build it... you can also select a .DBD file which contains a list of
several files to compile and link together!

Once you have selected what to build, you will be prompted for the memory model
(if applicable) and the various steps of the compile process will run
to build and link it.

DBD has a fairly powerful "scripting" language which control what commands are
issued to perform a build. I have provided DBD.INI which is set to build with
my own Micro-C compiler(s), however you can modify this if you wish to support
other toolsets. See DBD.INI

DBD.INI file:
-------------
DBD reads it's initial settings from DBD.INI.
It searches for this file both in the current directory and the directory from
which the program was loaded! ** If it can **
** Command argument 0 (argv[0]) should contain the full path to the program
    file, however under newer Windows, this is not guaranteed. If you run a
    program from the command line, argv[0] only has the command name that was
    "typed" - If it was launched by searching your PATH, that directory path
    will NOT be available to the program!

the .INI file contains two sections which look like commands:

Initial Settings:
-----------------
BUILD   name...
    Defines a "type of build" to perform. I use this to select the target
    CPU that my compiler will build for,

EXT .DBD.C.H...

    This defines the file extensions that will be offered as buildable files.
    .DBD is normally first, as a file with the first extension in the list is
    assumed to contain a "multifile list" of the files belongiong the the
    program to build.

EDIT    editor command text
    Defines the command that DBD will use to invoke the editor the first
    time. Note this is a "printf" format argument, and "%s" is the name
    of the file to edit.

REDIT   editor command text
    As above, used to RE-EDIT a file after an error has been detected.
    Has an additional "%u" available which indicates the line position.

ARG argument text
    Enters a command line argument as if it had been tyoes on the command line

OPTION  characters
    Defines extra characgters which can be specified as command line
    options. The can be read as bits 0+ of ~O (See below)
    eg: OPTION AB
        DBD         : ~O & 255 == 3
        DBD -A      : ~O & 255 == 1
        DBD -B      : ~O & 255 == 2
        DBD -AB     : ~O & 255 == 3

OPTHLP  help text

    Defines a line of text to be output as part of the command help.
    Used to document OPTIONS

TMPFS letter size

    Creates a DVM "ram" drive, size if size of drive of 256 byte
    sectors (max 2047). Drive letter IS case sensitive, make sure you
    use the correct case to access the DVM drive, and the other case if
    you need to access a host drive with the same letter!
    Does "nothing" in DOS(box)/Win32 version.

INIEND

    Ends "Initial Settings" and begins defining the "build script" which
    is esentially a programming language which tells DBD how to perform a
    build.


Script lines may contain:
-------------------------
    ~c
        "escape" character sequences (see below)
    SYM
        a "symbol" consisting of a word beginning with 'A'-'Z' and
        containing that + '0'-'9'. STMS are replaced  by there SET
        value when encountered in subsequent lines.
    EXPRESSION
        A value expression consisting of numbers (0+) and:
            Monadic operators:
                !v          Not: 1 if v equals 0, 0 otherwise
                -v          Negate: 0-v
                ~v          bitwise compliment
            Dyadic operators:
                v1 + v2     Add
                v1 - v2     Subtract
                v1 * v2     Multiply
                v1 / v2     Divide
                v1 % v2     Modulus (remainder after divide)
                v1 & v2     bitwise AND
                v1 | v2     "" OR
                v1 ^ v2     "" XOR
                v1 && v2    logical AND:     0 if v1 == 0, otherwise v2
                v1 || v2    logical OR:     v1 if v1 != 0, otherwise v2
                v1 == v2    compare : 1 if v1 equals v2, otherwise
                v1 =  v2    ""
                v1 != v2    "" not equals
                v1 <  v2    "" less than
                v1 <= v2    "" "" or equals
                v1 >  v2    "" greater than
                v1 >= v2    "" "" or equals
    'text'text' 1 if texts match, 0 otherwise (quotes: '"`)


Escape characters sequences:
----------------------------
    ~B      Build type selected at startup
    ~L      Line numner in script
    ~E      Error status of last CMD
                0   = No Error
                1+  = Error reported in this line
                -1  = Error occured, no line reported
    ~R      ReturnValue from: CMD, ENV, LOOKUP, MENU, MSET
    ~S      System tyoe: 0=Dvm 1=Dos/Win32 2=DosBox
    ~O      Command line option bits (zss OPTION)
    ~:      no effect other than so separate adjacent symbol names:
                eg: if SYM X is 'Y' : X1 gives "X1", X~:1 gives "Y1"
    ~;      effectively ends the source line (used for line comment
    The following handle a "multifile" list, this contains:
        Just the one source file when a single file was selected to build
        All filenames in a selected .DBD file
      ~N        Number of files in multifile list
      ~P        Position (0-(~N-1)) ""
      ~F        Full filename (with .EXT) at ~P in ""
      ~G        name only (no .EXT) ""
      ~T        type (0+ = position in EXT list) ""
      ~+        move to next ~P multifile list                              *1
      ~-        reset ~P to 0                                               *1
    The following are only effective within CMD
        ~_      causes command to be via exec() and marks point             *1
                    between exename and arguments, otherwise system()
        ~.      "" but has effect only under DVM                            *1
    The following are only effective in ESCAN and signify "wildcards"
    ~?      matches any single character
    ~*      matches any group of one or more characters
    ~#      "" and indicates the position to extract error line number

      *1    these perform the indicated "side effect" only, and do not put
            anything in the output.  see: NOOP


Script lines MUST begin with one of the following commands:
-----------------------------------------------------------
sym     a "Symbol"

SET sym text

    sets SYM to contain TEXT.

DSET ""

    sets SYM to contain TEXT only if has not been already defined.

EQU sym expression

    sets SYM to contain the value of EXPRESSION.

ENV sym envname [deftxt]

    sets SYM to the content of environment variable ENVNAME
    sets ~R to 1 if ENVNAME exists
    if ENVNAME does not exist, sets SYM to DEFTXT [""], and ~R to 0

PRINT text

    prints TEXT on the console.

PAUSE text

    as above, but also displays '?' and waits for a key.
        SPACE   = proceed
        ESC     = Abort

ERROR text

    like "" and terminates

IF expression

    begins an IF blcok, and performs the follong lines (up to END or ELSE)
    only in expression is true (not 0).

ELSE [expression]

    follows IF and performs the following lines only if no IF have been
    executed. If EXPRESSION is provided, it must be true (not 0), otherwise
    this block will also be skipped.

END

    Terminates an IF or WHILE block.
    If no block is active, terminates the script.

WHILE expression

    Begins a WHILE block, and performs the following lines (up to END)
    as long as EXPRESSION remains true.

GOTO label

    Transfers script execution to the LABELed line.
    NOTE: GOTO is unaware of BLOCKS or the CALL stack, which means that
    trasfering into or those may not work as you might think, as an
    END/RETURN would still be required.

CALL label

    Places the next script line position on an internal stack, and then
    trasfers like GOTO. The "subroutine" can transfer control back to the
    line after CALL with RETURN

RETURN

    Terminates a CALLed block and transfers scrip execution back to the
    line immediatly following that CALL.

ESCAN strng...

    Sets ErrorSCAN strings. The output of a CoMmanD is searched for these
    string to termine errors, Special characterss:
        ~?      matches any singlt character
        ~*      matches one or more characters
        ~#      "" and retrieves a line number with the line with the Error
                from this location.

CMD text

    Performs a command on the system.
    Note the ~_(~.) escape codes, if present the command will be performed
    by direct execution (exec) otherwise is is passed as a commmand back
    to the host system.
    (exec) has less overhead but:
        A: does not support "shell" operations like redirection, pipes etc.
        B: must be the full path/name of the program to be executed.
    **  This is very important in DVM as (exec) runs another .DVM within the
        same virtual machine.
    sets ~R to the exit value returned by the command.

MENU title item...

    Performs an on-screen menu allowing the user to select an ITEM.
    The item number (0+) is assigned to the ~R return value.

MSET sym ""

    Menu SET - like "" but also assigned the name of the selected item to SYM.

LOOKUP sym

    sets ~R to an internal ID number (1+) for SYM
    ~R will contain 0 if the symbol is not defined!

DEL filename

    Deletes the indicated file.

NOOP text

    Prerform MO OPeration .. but DOES evaluate TEXT.
    This can be useful if TEXT contains escape codes which have
    side effects (eg: ~+ and ~-)


Technical notes:
----------------
** DBD detects errors in the build commands that it runs by examining their
   console output.  Please NOTE:

    Under DVM (Dunfield Virtual Machine) it makes use of a DVM feature allowing
    console output of a program to be captured to a file.  This only works with
    .DVM programs,  and means that if you run something "native" in a buildstep
    that may encounter errors - they won't be detected.

    Many non-DVM environments do not have a reliable way to capture console
    output (eg: DOSBOX cannot redirect stderr). To capture console output, DBD
    clears the screen, runs the command then reads the screen buffer.
    This works well with my tools which typically only output 1 or 2 lines for
    an error, and stops trying after 10 errors.
    I have used compilers where a single error can cause many lines of extra
    "nonsense errors" on later lines causeing the one that matters to be lost
    - tools like this may not work well with DBD.

    If these prove to be a problem with your build tools, and you want to use
    DBD ... contact me to see if we can come up with a solution.

Dave Dunfield   -   https://dunfield.themindfactory.com
