============================================================================
                    QuickBASIC Metacommand Extender 1.2
============================================================================
                          by Plasma / Jon Petrosky              [04-20-2002]
                              www.phatcode.net

                            Freeware/Open Source

                 (If you modify it and want to distrubute
                 it, just make sure my name stays with it)


============================================================================
Contents
============================================================================

1. Introduction
2. Using QBMCX
3. Extended Metacommands
4. General Tips
5. Closing Words


============================================================================
1. Introduction
============================================================================

What Exactly Is This?
---------------------
QuickBASIC Metacommand Extender, or QBMCX for short, is a utility which
automates command-line compiling with QuickBASIC 4.5, based on custom
metacommands placed in the source code. All you have to do is run a simple
batch file, and your main module and all other modules (.BAS) will
automatically be compiled and linked to any specified libraries (.LIB) or
object files (.OBJ). Then your program will be run.

How Does That Help Me?
----------------------
If you've ever compiled from the command-line, you know that it is a pain in
the ace, unless you set up a custom batch file for each project. (This can
be a pain in itself!)

The best use of QBMCX, however, is probably setting it up for use with an
alternative IDE. (such as MED, Code Edit, SynEdit, Visual SlickEdit, etc.)
If the IDE supports assigning hotkeys to custom tools, you can easily set it
up so that your program is automatically compiled, linked, and run when you
hit F5!

Note
----
If you plan to use QBMCX with the MED IDE, I recommend downloading the
"QuickBASIC for the MED IDE" package from our website, if you aren't already
using it. This program automates the setup process and adds QuickBASIC
syntax to MED. Grab it at http://www.phatcode.net/

Another Note
------------
QBMCX is designed for use with the QuickBASIC 4.5 compiler. I haven't tested
it with any other versions (such as 4.0 or PDS 7.1). The QB 4.5 compiler is
included with QBMCX, so you shouldn't have any problems unless your source
was written specifically for a different version.

Files Included
--------------
QBMCX is stand-alone. That means that you don't need to already have QB, but
if you already have a copy of QB somewhere, QBMCX won't mess with it.

BC.EXE        Microsoft QuickBASIC Compiler 4.50
BCOM45.LIB    Alternate run-time-module library
BRUN45.LIB    Run-time-library module
LINK.EXE      Microsoft Overlay Linker 3.69
MAKE.BAT      Generic MAKE batch file
MAKE.PIF      PIF for MAKE batch file so that annoying window closes ;)
              (included with QB4MED only)
NOCOM.OBJ     "No Communications" stub file
NOEM.OBJ      "No Emulation" stub file
QB.BI         Assembly/Interrupt support include file
QB.LIB        Assembly/Interrupt support library
QBMCX.BAS     QBMCX source code. Yes, it's open source! :)
QBMCX.EXE     QBMCX main executable
QBMCX.TXT     What you're reading right now
SMALLERR.OBJ  "Small (short) Error Messages" stub file

Simply copy all the included files to a directory of your choice. If you
plan to use QBMCX directly from the command-line, you should probably add
that directory to your PATH statement in your C:\AUTOEXEC.BAT file. That
way, QBMCX will work no matter which directory you're in. Do to this, open
up C:\AUTOEXEC.BAT in a plain text editor like Notepad or Edit. Add this
line at the end of the file:

PATH=%PATH%;C:\QBMCX

Where C:\QBMCX is the folder you copied QBMCX to. (If you used a different
folder, just substitute that in.) You'll have to restart for that PATH
setting to take effect.

(If you plan to use QBMCX from an alternative IDE, you don't need to worry
about changing your PATH statement. Also, if you are using the "QuickBASIC
for the MED IDE" package, you don't need to copy any files, just run the
setup program!)

About QBMCX
-----------
This little utility started out as a quick-n-dirty program to compile
programs quickly from the command line or an alternative IDE. (The QB IDE
was out of the question, since it is a memory HOG!)

However, I also needed flexibility, but I didn't want to have to type lots
of command-line switches or make custom batch files for every project. This
is where the "extended" metacommands come into play.

If you've used QB before, you've probably used a few of the built-in
metacommands:

'$dynamic
'$static
'$include: 'include.bi'

The metacommands give the compiler information on how to compile the program
(in the case of $dynamic or $static, how to allocate memory, or which files
to include, with $include).

So I thought, why not just make a program that scans the source for custom
"metacommands", and then calls BC and LINK based on the metacommands given.
It worked out pretty well. :) No messy switches, and your programs will run
in the QB IDE as well as with QBMCX, because QB interprets nonsupported
metacommands as simply comments.


============================================================================
Using QBMCX
============================================================================

QBMCX
-----
Ok, enough rambling. To use QBMCX, you must specify the filename of your
source code on the command line, along with one or more switches that tell
QBMCX what actions to take. Here's a breakdown of the syntax:

QBMCX infile.ext [, outfile.ext] /c[ompile] /l[ink] /r[un] /?|/h[elp]

infile.ext  - filename of your main BAS source file (the main module)

outfile.ext - filename of the output BAS file, after it has been parsed.
              This file will be overwritten if it already exists, and will
              be deleted after it is compiled. (It is only a temporary
              file.) If no filename is given, infile.TMP will be used. (It
              is easiest just to leave this blank!)

/c or /compile - This will compile your main module and all BAS modules
                 defined in your main module with the $bas metacommand.

/l or /link - This will link your main module object, all BAS module objects
              (must have been previously compiled or use /c), and all
              OBJs/LIBs defined in your main module with the $obj/$lib
              metacommands.

/r or /run - This will run your program (must be compiled and linked first).
             All programs defined in your main module with the $run or
             $run_after metacommands will also run (before your program with
             $run or after your program with $run_after) in the order they
             are defined.

/? or /h or /help - Displays command-line help.


Hrmmm, that's a mouthful! Basically, you can choose to compile, link, or run
your program. (Or any combination of these.) Just remember /c to compile, /l
to link, and /r to run. If you want to do more than one thing, you can
combine multiple switches, like "/c /l".

Most of the time you'll probably want to compile, link, and run. To do this,
you can use "/c /l /r", or you can just *leave out the switches*. If QBMCX
finds no switches on the command-line, it assumes that you want to compile,
link, and run.

How QBMCX Works
---------------
When you run QBMCX, it opens your source code, and scans it line-by-line,
reading all the metacommands and replacing macros accordingly (more on
macros later). Because the code must be altered if a macro is encountered,
QBMCX creates a temporary file from your original source and modifies that.
So your original source code *is never modified in any way*.

QBMCX continues scanning your source code until the "$end_meta" metacommand
is encountered. At this point, it stops scanning and simply copies the rest
of the lines over to the temporary file. (Note: QBMCX scans only your main
module! Other modules specified with the $bas metacommand will be compiled/
linked, but all metacommands and macros in other modules will be ignored!)

QBMCX then creates a temporary batch file named TEMP.BAT in the current
directory. This batch file is based on the metacommands read from your
source, and will take care of compiling all your modules, linking with
object files and libraries, and running programs. The batch file will also
delete the temporary file QBMCX created from your source code.

QBMCX now ends at this point. Now you're probably thinking, "This is stupid.
Now I have to run this batch file? WTF?!"

Actually, there's a good reason for this...QBMCX *could* run BC and LINK
directly, but since it would remain resident in memory, there would not be
as much memory available. So a batch file is created, and this is run when
QBMCX has ended.

To automate this process, you should use the MAKE.BAT file! This batch file
takes the given parameters, passes them to QBMCX, runs the temporary batch
file that QBMCX generates, and then deletes the temporary batch file.

So instead of typing: QBMCX myprog.bas   or   QBMCX whatever.bas /c /l
just use:             MAKE myprog.bas    or   MAKE whatever.bas /c /l

If you use MAKE, you don't have to worry about running the temporary batch
file, and the whole process is just about transparent. This is as easy as it
gets :)


============================================================================
Extended Metacommands
============================================================================

Below is the complete list of all supported extended metacommands. If you
try to use a metacommand that is not supported, QBMCX will just treat it as
a comment and ignore it. Note that all metacommands must be proceeded with
either REM or an apostrophe, and all underscores (_) are optional. Also
note that metacommands are not case sensitive.

For example, any one of these is a valid metacommand:

'$no_cls
'$NoCLS
REM $nocls
REM $NO_CLS

Multiple metacommands can also be combined on one line, like so:

'$com_buffer: 256  $lib: 'qb.bi'  $debug

Now onto the commands...

Basic
-----
$bas: 'filename.ext'        Compile and link with this BAS file
$obj: 'filename.ext'        Link with this OBJ file
$lib: 'filename.ext'        Link with this LIB file
$run: 'filename.ext'        Run this program before running the main
                              program
$run_after: 'filename.ext'  Run this program after running the main program
$end_meta                   Stop looking for metacommands/macros
                            (all metas/macros past this will be ignored)

Options
-------
$stack: n        Set the stack size to n
$seg: n          Set the number of LINK segments to n (also $segments)
$com_buffer: n   Set the com buffer size to n
$huge            Enable huge (>64K) array support (also $ah)
$on_error        Enable ON ERROR/RESUME n trapping
$resume_next     Enable ON ERROR/RESUME 0|NEXT trapping
$row_major       Store arrays in row major order
$event           Enable event handlers ON PLAY, ON PEN, ON TIMER, etc.
$obj_string      Store strings in the object table instead of the symbol
                   table
$hi_end          High end of segment (also $high_end)
$no_string_pack  Don't pack the strings in the EXE
$code_pack       Pack the code
$data_pack       Pack the data
$hi              Load as high in memory as possible
                 (also $high, $load_hi, $load_high)
$near            Use near calls if possible

Stub Files
----------
$no_com     Disable com support (links to NOCOM.OBJ stub)
$no_emu     Disable FPemu support (links to NOEM.OBJ stub)
$small_err  Use short error messages (links to SMALLERR.OBJ stub) 

Debugging
---------
$debug      Enable CTRL+BREAK
$no_cls     Doesn't clear the screen before program(s) are run
$pause      Pauses after running BC and LINK (for debugging purposes)
$pause_all  Pauses between every program, including BC and LINK
            (for debugging purposes)
$save_temp  Doesn't delete temporary files
            (all OBJs created from compiling)
$del_exe    Deletes the exe after it is run (also $delete_exe)

Macros
------
There are two macros included with QBMCX, the __TIME__ AND __DATE__ macro.
To use them, insert either __TIME__ or __DATE__ anywhere in your program.
When QBMCX encounters this, it will be replaced with either the current time
or current date. (Note that macros *are* case sensitive!)

For example: PRINT "Compiled on __DATE__ at __TIME__"

__TIME__  Insert the time file processing started (=compile time)
__DATE__  Insert the date file processing started (=compile date)

There are 3 metacommands which control the output of macros:

$format_time  Format the time inserted with the __TIME__ macro
              (14:23:34 becomes 2:23 pm)
$format_date  Format the date inserted with the __DATE__ macro
              (12/07/2001 becomes December 7, 2001)
$end_meta     Stop looking for metacommands/macros
              (all metas/macros past this will be ignored)

Old Metacommands
----------------
Of course, QB's built-in metacommands still work...

$dynamic  Allocate memory dynamically at run time (recommended)
$static   Allocate all needed memory at the beginning of your program

$include: 'filename.ext'  Include specified file


============================================================================
4. General Tips
============================================================================

* To speed up processing time, use $end_meta as soon as possible. This way,
  QBMCX will not waste time scanning additional lines. If you use a macro,
  use it near the beginning of your program and use $end_meta right after
  the macro.

  For example, the following program will take a few seconds to process,
  because every line needs to be scanned:

  '$dynamic
  '$include: 'qb.bi'
  '$lib: 'qb.lib'
  '$near
  '$debug

  'Imagine 10,000 lines of code here :)

  PRINT "Build 2343534 - Compiled on __DATE__ at __TIME__"
  END

  It will go much quicker if only the first few lines are scanned. This can
  be accomplished by using the macros early in the program, and using
  $end_meta as soon as possible:

  '$dynamic
  '$include: 'qb.bi'
  '$lib: 'qb.lib'
  '$near
  '$debug

  Info$ = "Build 2343534 - Compiled on __DATE__ at __TIME__"

  '$end_meta

  'Imagine 10,000 lines of code here :)

  PRINT Info$
  END

* Use the MAKE.BAT batch file instead of QBMCX.EXE! MAKE takes care of
  running and deleting the temporary batch files QBMCX creates.

* All EXEs created with QBMCX are stand-alone (they don't require
  BRUN45.EXE)


============================================================================
5. Closing Words
============================================================================

Well, I originally didn't even plan on releasing this, but I thought I might
as well...I find QBMCX very useful, especially when used with MED.

I'm not really sure what the future plans are for QBMCX, if any. If I find
any big bugs, I'll probably fix 'em. If anybody has any suggestions, I may
add some more features as well.

Anyway, if you find QBMCX useful, please send $30 to -- just kidding! Maybe
an email would be nice ;)

Signing off,
Plasma
-------------------
plasma@phatcode.net


[End of File - Last modified: April 20, 2002 - 2:40 pm]