home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 2: PC / frozenfish_august_1995.bin / bbs / d09xx / d0948.lha / Snoopy / Ini / ini.manual < prev    next >
Text File  |  1993-12-20  |  16KB  |  413 lines

  1.  
  2.  
  3.                                 ini.library
  4.                             Release Version 2.0
  5.  
  6.                           I-WANT-TO-BE-FREE-WARE
  7.                           written by Gerson Kurz
  8.  
  9.                                 Nov.21,1993
  10.  
  11.    PURPOSE
  12.     The ini.library was written to give the amiga user a more consistent
  13.     configuration file format, and programmers a much easier way of 
  14.     storing config or project information on disks. 
  15.     
  16.     Most programs have config files to store global settings and such. 
  17.     These files have all different structures people in the real world
  18.     (the users) cannot examine or understand; and, worse yet, often differ
  19.     from version to version. We all know the hassle with those 'old->new'
  20.     configuration file converters...With the ini.library this changes: you
  21.     have access to a standardized ini file format known from other
  22.     operating systems such as unix, windows and so on; it allows
  23.     you to save your config stuff much easier (less code), and it
  24.     enables the user to read and even modify configuration data with
  25.     a simple text editor (or, a wide-range field for unemployed PD
  26.     programmers: using an INI editor)
  27.     
  28.     As the ini.library is I-WANT-TO-BE-FREE-WARE you are ENCOURAGED to
  29.     use it - its free of charge! (go ahead, do it!) and it offers much
  30.     more comfort to your applications. PD dealers, diskmags, everyone,
  31.     I'd like you to push'n'hype the ini.library ;-). 
  32.     
  33.     INI files are plain line-oriented ASCII texts that can contain three
  34.     possible types of lines : COMMENTS, HEADERS and VARIABLES. COMMENTS are
  35.     lines that include additional information not used by the parser.
  36.     You can use these comment lines to give the user ideas about what
  37.     your variables mean and what reasonable changes s(he) is allowed
  38.     to make to that variables. HEADERS are identifiers for sections and
  39.     are enclosed in [] brackets. A SECTION is a group of zero to infinite (?)
  40.     number of variables and provides a simple but efficient means of
  41.     logically grouping data. VARIABLES are simple statements in the
  42.     form "<variable>=<contents>" where both <variable> and <contents>
  43.     could be virtually anything - you name it. 
  44.  
  45.     Each INI file must start with a sequence of 4 characters ";INI"
  46.     otherwise the ini.library will return the INIERROR_INVALID_INI_FILE. 
  47.     This was included to prevent misuse of the ini.library: imagine your
  48.     program has a 'load user configuration' menu and the user tries out
  49.     some binary hack or an IFF picture (you know users, don't you?! ;-)
  50.     If you watch out for INIERROR_INVALID_INI_FILE, you can send the user
  51.     a message of complaint and ignore its wishes -> great. 
  52.     Since this is a cause for many first-time problems, from version 2.1
  53.     upwards this checking can be made optional; see ini_NewConfig() for
  54.     details
  55.  
  56.    COMMENTS
  57.     Comments can be placed anywhere [well, almost]. If you want
  58.     to have a full-line comment, place a ';' or a '*' in the first
  59.     column of that line. Anything after these two characters will be ignored.
  60.     If you want to place a comment at the end of a line you should use
  61.     the ';' sign ONLY. Also note that if you make a comment after a 
  62.     variable you should probably enclose its contents in quotation marks;
  63.     otherwise the whitespaces between the last character of the contents
  64.     and the comment start will be part of the contents. This is
  65.     no problem if you are using integer or boolean variables; it might
  66.     be a problem for SOME string variables, but doesn't necessarily have
  67.     to - its up to your interpretation of the input data.
  68.     
  69.     Examples:
  70.     
  71.         ;INI for MUIMon release version
  72.         
  73.         * another piece of wisdom
  74.         best part of munich=ULTRAWORLD ; 100% wild techno
  75.         
  76.  
  77.    SECTIONS
  78.     Sections are used to group variables logically. You should try to place
  79.     all your data in groups so that your inifiles have a more consistent
  80.     look and both you and the user can find data easier. The concept of
  81.     sections can have various usages, one is to handle logic groupings
  82.     for one program, another is to handle data related to different
  83.     programs accessing the same INI file, yet another is to just make
  84.     your INI more readable. Of course,the ini.library is flexible enough
  85.     to ignore sections altogether, but you shouldn't force it! Sections
  86.     cost you nothing and make for a lot better programs.
  87.  
  88.    HEADERS
  89.     Headers start a new section. Headers are strings enclosed in
  90.     [] brackets and can be any string you like. Everything following
  91.     a header is logically assigned to that header - up to the next
  92.     section header or an end-of-file. 
  93.  
  94.     Examples:
  95.  
  96.         [drivers]
  97.         pc0=storage:dosdrivers/pc0
  98.         cd=devs:CDROM
  99.  
  100.         [Disko Lovers,International]        
  101.         best ULTRAWORLD DJs=MONIKA,TIN-A-303,BLEEP & TRIPPLE R,DJ HELL
  102.         ; hi to SMC all ravers around the globe. See you on MAYDAY V
  103.  
  104.         [hermeneutic philosophy revisited]
  105.         zizek=no meta language exists
  106.    
  107.    VARIABLES
  108.     Variables are basically strings that are assigned a name. The
  109.     names is what you search for, the strings is what you get -it is as
  110.     simple as that. For instance, in "TABS=8" the string "TABS" is
  111.     the name (also called the variable), the string "8" is its value.
  112.     The interpretation of the string value is up to you. The ini.library
  113.     provides three basic types of interpretation : Strings, Integers (LONGs)
  114.     and  boolean Values (BOOLs). You can of course add your own
  115.     interpretations as you like, and this is why the ini concept is so
  116.     flexible: You can virtually store ALL information you need in such
  117.     a way that it is represented as an ASCII string. If you want your
  118.     strings to be of a certain length, you can enclose them in
  119.     brackets, for example such as in
  120.     
  121.         user="T\"N\"I and THE DREAM TEAM"
  122.  
  123.     where you can assign the string >T"N"I AND THE DREAM TEAM< to
  124.     the variable named >user<. Note that a sequence of \" is used
  125.     as an escape character in the above example.
  126.  
  127.     If you have ideas for additional datatypes of general interest
  128.     the ini.library should understand, please contact me. If possible,
  129.     I'll include them.
  130.  
  131.     Examples:
  132.     --------------------------------------------------------------
  133.        ;INI
  134.        
  135.        [GLOBAL]
  136.        user="T'N'I and The Dream Team" ;from INTENSE Records
  137.        tabs=8
  138.        indent=YES
  139.     autofold=FALSE
  140.     preferences=
  141.        
  142.        [DIRECTORYS]
  143.        home=work:assembler/
  144.        ; add multiple directorys by using '+' or ','
  145.        include=include:+dh1:more_includes/
  146.        libs=dh2:code/libs/asm/+lib:+disko:love
  147.        
  148.     --------------------------------------------------------------
  149.     The above example shows you some ideas of inifiles: Two groups
  150.     are part of this inifile: GLOBAL and DIRECTORYS. Each section
  151.     can (but doesn't have to) have different variables, each variable
  152.     can be any string enclosed in quotation marks or from the = sign
  153.     to the end of the line. If you want to add comments, enclose the
  154.     string in quotes, and add a comment like in the "user=" line above.
  155.     Note that the feature described as "add multiple directorys by ..."
  156.     is a description of an add-on datatype used by the application for
  157.     this INI file and NOT provided by the ini.library itself. 
  158.  
  159.     Now you should be able to read inifiles. More complex features such
  160.     as section protection and file location are described in the
  161.     "programmers.guide" document which should be part of this distribution.
  162.  
  163.    HINTS
  164.     If you decide to use the ini.library -WHICH I STRONGLY HOPE YOU DO-
  165.     you should always check for error returns - you may never know when
  166.     they come in handy for you.
  167.  
  168.     If you save your files, make use of the grouping feature; that is,
  169.     at least provide some GLOBAL section so that the user knows what
  170.     he's up for. It makes INIfiles more readable and doesn't cost
  171.     you anything.
  172.  
  173.    LIMITATIONS
  174.        Yes, there are some.
  175.        
  176.     * currently no whitespaces before and after the "=" are allowed.
  177.       This means that the two following lines are different for 
  178.       the ini.library parser functions
  179.       
  180.              ultraworld=great
  181.              ultraworld = great
  182.  
  183.       There is a simple workaround for this: just do your own variable
  184.       and contents parsing (explicit datatypes, see above). Future
  185.       versions WILL include a fix on that, I PROMISE.
  186.  
  187.        * the ini.library uses approximately twice as much memory as the
  188.          ini file is in size (less for larger files). This is not a
  189.          problem for most users, because inifiles seldom grow over
  190.          a size of some 10-20 kb (even on windows I haven't seen a inifile
  191.          larger than 25kb up to this day), and many applications not even
  192.          reach a 5kb limit. (You can write a LOT variables in a 5 kb file).
  193.       However, this memory is needed only while your parser is active,
  194.       (i.e. between calls to ini_New() and ini_Delete() ). Afterwards,
  195.       only the library code (5kb) is kept in memory. 
  196.  
  197.     PROGRAMMING
  198.     The ini.library has a very comfortable programmers interface.
  199.     In the following paragraphs I'll tell you about the general
  200.     concepts and design questions; detailed function descriptions
  201.     should be obtained by looking at the autodocs-file ini.doc or
  202.     the autoguide(tm) file ini.guide.  But lets start with some
  203.     conventions:
  204.  
  205.     INTERNAL CONVENTIONS
  206.     All ini.library functions scratch ONLY the return register (d0).
  207.     ALL other registers are preserved; something most assembly
  208.     programmers will be gratefull for.
  209.  
  210.     Most functions (except for very few exceptions) will return an
  211.     error code in d0 you SHOULD examine. Detailed error codes are
  212.     given in the includefiles.
  213.  
  214.     BASIC IDEAS
  215.     The two most important functions are (like in C++)
  216.  
  217.     ini_New() - the INI object constructor
  218.     ini_Delete() - the INI object destructor
  219.  
  220.     ini_New() opens an INI file ("constructs" an INI object) and ini_Delete()
  221.     closes it ("destructs" the INI object). The INI object is represented as
  222.     the INIPARSER structure defined in the includes; you have to allocate 
  223.     enough memory for it (sizeof(INIPARSER)=ip_SIZEOF). The Destructor should
  224.     be called ALWAYS, even if ini_New() failes, otherwise you'll probably loose
  225.     some memory.... Examples :
  226.  
  227.     ;-------------------------------------------------------------
  228.     void ReadIni( void )
  229.     {
  230.         INIPARSER parser; /* local variable */
  231.         
  232.         if( ini_New( "<filename>", &parser ) == INIERROR_NONE )
  233.         {
  234.             /* examine file */
  235.         }
  236.         ini_Delete( &parser );
  237.     }
  238.     ;-------------------------------------------------------------
  239.     ReadIni:    lea    filename(pc),a0
  240.             lea    parser(pc),a1
  241.             movea.l    IniBase,a6
  242.             jsr    _LVOini_New(a6)
  243.             cmpi.l    #INIERROR_NONE,d0
  244.             bne.b    .SKIPERROR
  245.             ; ...
  246.             ; examine file
  247.             ; ...
  248.     .SKIPERROR    lea    parser(pc),a0
  249.             movea.l    IniBase,a6
  250.             jsr    _LVOini_Delete(a6)
  251.             rts
  252.     ; to keep it simple: global space for the INIPARSER
  253.     parser:        ds.b    ip_SIZEOF
  254.     filename:    dc.b    "<filename>",0
  255.     ;-------------------------------------------------------------
  256.  
  257.     All user functions of the ini.library require the parser as an argument,
  258.     so I guess you could call them "methods" on the INI object. The three 
  259.     basic examination functions are 
  260.  
  261.     ini_GetString(),
  262.     ini_GetInteger() and
  263.     ini_GetBool().
  264.  
  265.     A detailed description is given in the autodocs; for now lets just take
  266.     a look at ini_GetInteger. It looks something like this :
  267.  
  268.     INIERROR error = ini_GetInteger( INIPARSER *parser,
  269.                      STRPTR head,
  270.                      STRPTR var,
  271.                      LONG defaultLong,
  272.                      LONG *target );
  273.  
  274.     The "INIPARSER *parser" is, of course, the INI object you should know
  275.     already. "head" is the section you're looking for, and "var" is the
  276.     name of the variable. Example :
  277.  
  278.     ;-------------------------------------------------------------
  279.     ;INI-Example
  280.     
  281.     [global]
  282.     tabs=8
  283.     
  284.     ;-------------------------------------------------------------
  285.     Here head would be "global" and var "tabs". The (signed) Integer 
  286.     "defaultLong" will be used if the var cannot be found, and "target"
  287.     is the place to write back the value. As you see, "target" will be
  288.     written to always, either the correct value or the "defaultLong" value,
  289.     so you can skip the error handling if you are satisfied with default
  290.     values in case something goes wrong. This function would be called 
  291.  
  292.     ;-------------------------------------------------------------
  293.         long tabs;
  294.         ...
  295.         ini_GetInteger( &parser, "global", "tabs", 8, &tabs )
  296.         ...        
  297.     ;-------------------------------------------------------------
  298.         ...
  299.         lea    parser(pc),a0
  300.         lea    head_global(pc),a1
  301.         lea    var_tabs(pc),a2
  302.         moveq    #8,d0
  303.         lea    tabs(pc),a3
  304.         movea.l    IniBase,a6        
  305.         jsr    _LVOini_GetInteger(a6)
  306.         ...
  307.     tabs:        ds.l    1
  308.     head_global:    dc.b    "global",0
  309.     var_tabs:    dc.b    "tabs",0
  310.     ;-------------------------------------------------------------
  311.  
  312.     EXAMINING A WHOLE SECTION
  313.     
  314.     You can loop thru a section line-per-line, e.g. if you don't know the
  315.     exact structure of a section. Some example : You want to make your
  316.     menus user configurable (see examples/configmenus.c). You could create
  317.     some INI file like the following :
  318.  
  319.     ;-------------------------------------------------------------
  320.     ;INI-file for user-configurable menus
  321.  
  322.     [menus]
  323.     title=Project
  324.     item="About...",about,?
  325.     item="Load",load,L
  326.     ...
  327.     title=Preferences
  328.     ...
  329.     (and so on)
  330.     ;-------------------------------------------------------------
  331.  
  332.     Of course, your program doesn't know how exactly the "menus" section
  333.     looks like, so you have to read line-per-line. You can do this very simple:
  334.     The functino ini_GetHeader() will give you a pointer to a structure
  335.     INILINEINFO (defined in the includes). This structure is the
  336.     internal representation of lines in an INI file. All INILINEINFOs
  337.     are part of an anchored standard amiga-list (see exec/nodes), so you
  338.     can loop through them. Each INILINEINFO has a field called "ili_flags"
  339.     which contains the type of entry used. Basically, what you would do
  340.     in the above example is : find all INILINEINFOs following the section
  341.     header for "menus" up to the next section header (ili_flags = HEADER)
  342.     or the end-of-file (=end-of-list). Example:
  343.  
  344.     ;-------------------------------------------------------------
  345.     {
  346.         INILINEINFO *info,*header;
  347.         
  348.         if( ( header = ini_GetHeader( &parser, "menus" ) ) != NULL )
  349.         {
  350.             for( info = (INILINEINFO *)header->node.ln_Succ;
  351.                  info->node.ln_Succ && info->ili_type != INIFLAG_HEADER;
  352.                  info = (INILINEINFO *)info->node.ln_Succ )
  353.             {
  354.                /* deal with it */
  355.             }
  356.         }
  357.     }
  358.     ;-------------------------------------------------------------
  359.         ...
  360.         lea    parser(pc),a0
  361.         lea    head_menus(pc),a1
  362.         jsr    _LVOini_GetHeader(a6)
  363.         tst.l    d0
  364.         beq    .SKIPIT
  365.         movea.l    d0,a5
  366.         move.l    LN_SUCC(a5),a5
  367.     .FORLOOP
  368.         tst.l    LN_SUCC(a5)
  369.         beq.b    .SKIPIT
  370.         cmpi.b    #INIFLAG_HEADER,ili_flags(a5)
  371.         bne.b    .SKIPIT
  372.         ; deal with it
  373.         movea.l    LN_SUCC(a5),a5
  374.         bra.b    .FORLOOP
  375.     .SKIPIT
  376.         ...
  377.     head_menus: dc.b "menus",0
  378.     ;-------------------------------------------------------------
  379.  
  380.     
  381.     
  382.     AUTHOR
  383.     Send your bug reports, ideas, love letters, fresh'n'phunky vinyl to 
  384.  
  385.     Gerson Kurz
  386.     Karl K÷glsperger Str.7 / A303
  387.     (yes, its APPARTMENT 303, not Roland TB 303 ;-)
  388.     80939 Mⁿnchen
  389.     West Germany
  390.  
  391.     This tool is dedicated to the **ULTRAWORLD** (Fuck the Sperrstunde!)
  392.  
  393.               ** The INI.LIBRARY is I-WANT-TO-BE-FREE-WARE **
  394.                dedicated to the global house & techno scene
  395.                           written by Gerson Kurz
  396.  
  397.     The ini.library may be used by and FREELY distributed with any
  398.     application be it commercial or public domain.  There are no
  399.     pagan users fees, Trump-esque licenses, or other forms of rabid
  400.     capitalist trickery associated with using this library and the
  401.     example files.  You do not even have to acknowledge the secret
  402.     of your superb and efficient config handling you gain by using
  403.     the ini.library.  The only limitation is that you may not alter
  404.     the actual executable of the ini.library, nor sell the product and
  405.     its examples as a distinct product (i.e.  represent it as such).
  406.     I don't give any guarantee for the fitness of the ini.library for
  407.     any purpose : use at own risk.
  408.  
  409.     SPECIAL NOTE
  410.     Is there anybody out there who likes to write manuals ?! (I HATE IT)
  411.     I would like to get in contact with you, because I'd like to have
  412.     a better manual for this library (and some other programs of mine).
  413.