About
Docs
Files
Support
Index

Essentials
AutoDocs
Library functions
Cooperate
Process mastering
Debug
Own debugging kit
FGE
Smart modeid pick
Loader
Shared lib. loader
Macros
Helper macros
Structs
All the structures
Logs
Library changelogs
Tools
Progs baked inside



L
O
A
D
E
R

 qdev_libloader.txt(a-pre_xxxlibs.h)
-------------------------------------


                                 1. INTRO
                          =======================

One  of the handiest things in the  'qdev'  is the library loader. With its
help  your  hands  are free from typing all these boring "OpenLibrary(...)" 
and "CloseLibrary(...)"  statements.  You can request needed libraries just
by  defining macros that are  mostly one line long. This  way  you not only
give  yourself more  comfort, but also  save on  binary size because loader
will be created at compilation time with only those features you requested!

Before you go for the example usage,  please take a look  at the variety of
features  you can  embed into your prog just by using macros. First  of all
macros start with  '___QDEV_LIBINIT_#?' . Secondly, symbol of '<...>' means 
macro really needs literal define, symbol of  '[...]'  means macro can be a
stub.   Lastly,  all   the   macros   have  no  effect  until  you  include
'a-pre_xxxlibs.h' header file. OK, so here are the features:



 1. Custom library handling
###############################

   ___QDEV_LIBINIT_EXTBASES <...>  - This macro is a container for external
                                     bases. Like when you have just created
                                     your  own  library  and want  it to be
                                     loaded with  this loader. Bases should
                                     be  defined  one  after another with a
                                     macro below.

      ___QDEV_LIBINIT_ADDBASE(base, val)  -  The very first argument 'base'
                                             is a full library declaration:
                                             struct Library *mybase  .  The
                                             other argument 'val' is a base
                                             initializer  and should be set
                                             to 0 in most cases.


   ___QDEV_LIBINIT_EXTLIBS <...>   - This  macro is a container for literal
                                     library entries. It  must be specified
                                     along with '___QDEV_LIBINIT_EXTBASES'.
                                     Library  entries must reside  one next
                                     to the other. To define them use macro
                                     below.

      ___QDEV_LIBINIT_ADDLIB(n, v, b)     - Arg. 'n' is a full library name
                                            like: "mylib.library". Arg. 'v'
                                            is the minimal library version.
                                            And argument 'b' is a symbol of
                                            the base: mybase .


   Example:

   #define ___QDEV_LIBINIT_EXTBASES                            \
           ___QDEV_LIBINIT_ADDBASE(struct Library *mybase, 0)  \
           ___QDEV_LIBINIT_ADDBASE(struct Library *hisbase, 0)

   #define ___QDEV_LIBINIT_EXTLIBS                             \
           ___QDEV_LIBINIT_ADDLIB("mylib.library", 6, mybase)  \
           ___QDEV_LIBINIT_ADDLIB("hislib.library", 7, hisbase)



 2. Built-in library handling
###############################

   ___QDEV_LIBINIT_<lib> <...>     - Each built-in library entry requires a
                                     minimal load  version.  Version can be
                                     negative  so that  the library will be
                                     treated optional. One exception to the
                                     rule  is  '___QDEV_LIBINIT_SYS'  where
                                     passing negative  value will cancel it
                                     completly. See the header file for all
                                     built-ins.


   Example:

   #define ___QDEV_LIBINIT_SYS   37
   #define ___QDEV_LIBINIT_DOS   37



 3. LibNIX stub removal
###############################

   ___QDEV_LIBINIT_NOEXTRAS [...]  - If your intention is  to code using OS
                                     API  only then define this so that the
                                     startup  code will  be more  crippled.
                                     You  do not  need to  define this when
                                     using QCRT.


   Example:

   #define ___QDEV_LIBINIT_NOEXTRAS



 4. Loader error reporting
###############################

   ___QDEV_LIBINIT_REPORTERR <...> - This macro is intended to hold a chunk
                                     of code that is responsible  for error
                                     printout. You  really  want to feed it
                                     with a macro below.

      ___QDEV_LIBINIT_REPORTDEF           - Default  error  outputing code.
                                            Currently this is 'FPrintf()'.


   Example:

   #define ___QDEV_LIBINIT_REPORTERR   ___QDEV_LIBINIT_REPORTDEF



 5. WBStartup message symbol
###############################

   ___QDEV_LIBINIT_DEFWBSTARTUP <...>
                                   - Currently  this  is  '_WBenchMsg', the
                                     'libnix' pointer.


   Example:

   #define ___QDEV_LIBINIT_DEFWBSTARTUP   WBenchMsg



 6. Workbench process handler
###############################

   ___QDEV_LIBINIT_CLIONLY <...>   - With this  macro  you tell  the loader
                                     that, whenever user launches this prog
                                     from  'Workbench', it  will be started
                                     in a CLI - QCLI. Macro expects default
                                     stream  name. This is to be  "CON:" in
                                     most cases, but can be "NIL:" as well.
                                     Either way  this can be overriden with
                                     global  or local variable 'QCLISTREAM'
                                     or prog. name one 'QCLISTREAM_<prog>'.
                                     Please note  that named variables have
                                     priority over the global!

      ___QDEV_LIBINIT_CLIQUIET            - "NIL:" stream.  Total  silence.

      ___QDEV_LIBINIT_CLISTREAM           - "CON:" stream (preferred).  The
                                            window will be opened only when
                                            some output must be done.


   Example:

   #define ___QDEV_LIBINIT_CLIONLY   ___QDEV_LIBINIT_CLISTREAM


                                 2. USAGE
                          =======================

I think  it is about  time for a little  usage example. Following code when
compiled  is  safe to run both from  CLI or Workbench. No,  it will not use
the 'ixemul.library' and please do not specify '-noixemul' switch!

    1 #define ___QDEV_LIBINIT_REPORTERR ___QDEV_LIBINIT_REPORTDEF 
    2 #define ___QDEV_LIBINIT_CLIONLY   ___QDEV_LIBINIT_CLISTREAM
    3 #define ___QDEV_LIBINIT_NOEXTRAS
    4 #define ___QDEV_LIBINIT_SYS       37
    5 #define ___QDEV_LIBINIT_DOS       37
    6
    7 #include <a-pre_xxxlibs.h>
    8
    9 int main(void)
   10 {
   11   if (pre_openlibs())
   12   {
   13     FPrintf(Output(), "Hellow teh world!\n");
   14   }
   15
   16   pre_closelibs();
   17
   18   return 0;
   19 }

   gcc -nostdlib -nostartfiles -Dnostartfiles -I/gg/include/qdev    \
   -Wall /lib/libnix/ncrt0.o myprog.c -o myprog -L/lib/libnix -lnix


You way wonder where the hell are  protos, inlines and all that? The answer
is: in the 'a-pre_xxxlibs.h' :-) . Pay attention to line 16, this statement
must always be outside any conditional!

---
megacz

  


No more fear cus pure HTML is here!
Copyright (C) 2013-2014 by Burnt Chip Dominators