C++ class Var
Author: kio@little-bat.de

        Copyright (C) 2001 Günter Woigk
        kio@little-bat.de

        This file is free software

        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

        Permission to use, copy, modify, distribute, and sell this software and
        its documentation for any purpose is hereby granted without fee, provided
        that the above copyright notice appear in all copies and that both that
        copyright notice and this permission notice appear in supporting
        documentation, and that the name of the copyright holder not be used
        in advertising or publicity pertaining to distribution of the software
        without specific, written prior permission.  The copyright holder makes no
        representations about the suitability of this software for any purpose.
        It is provided "as is" without express or implied warranty.

        THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
        INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
        EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
        CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
        DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
        TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
        PERFORMANCE OF THIS SOFTWARE.

        ----------------------------------------------------------------------------

        class Var           version 0.95        last modified: 21.nov.2001
        ---------

      o This class implements variables e.g. for script interpreter, compiler, assembler, database clients etc.

      o It is supplied as source.
        It has been tested with a test suite, though that does not guarantee anything...
        It compiles with my headers under CodeWarrior 11 on MacOS.
        Adaptions to your MacOS environment my need some minor quirks, e.g. defining types like 'uint'.
        Adaptions to other platforms may additionally require the replacement of some (few!) MacOS toolbox calls.
        class Var requires class String or a class of equivalent functionality.

        Supported data types
        --------------------

        isVoid:     no data assigned yet
        isNumber:   double float number
        isText:     text strings
        isProc:     executable code (basic support for script subroutines)
        isList:     1-dimensional array or list. Arrays/lists may be nested to any depth.

        Highlights
        ----------

      o All variables may be named and retrieved by name
        including variables within lists by use of dot-separated names.

      o Powerfull string operations, based on the class String library
        including transparent memory sharing for string texts.

      o Powerfull list/array operations
        including things like sorting and automatic list/array resizing.

      o Support for left-sided subslicer in lists/arrays and strings,
        requiered e.g. for:  a[n..m] = b

      o Support for object oriented programming:
        list/array items may be accessed by name
        list/array item names are preserved during list/array assignments
        list/array items may be executable code (code is shared between multiple instances)

        Suggested implementation
        ------------------------

      o Define one global hook variable as a list. Start with this variable as your current context.

            Var* globals = new Var(isList);
            Var* context = globals;

      o Put all global variables in this list, appending new defined variables at the end of the list.

            globals->Append(new Var(new_vars_name));

      o To create a local context, append a lokal hook variable to the current hook variable
        and make it a list and remember it to be your new current hook.

            Var* v = new Var("locals",isList);
            context->Append(v);
            context = v;

      o To search for variables (by name, of course) start in the current context
        and retry with the globals list if you did not find it.

            Var* v = context->FindItem(the_name_to_find);
            if (v==NULL) v = globals->FindItem(the_name_to_find);
            if (v==NULL) Handle_Var_Not_Found();

        Quirks
        ------

      o For the sake of speed, text strings may be shared.
        Before overwriting some characters within a string's text buffer, e.g. s[123]='x'; the string must be made writable.
        This is not neccessary before overwriting the string itself,      e.g. s="anton"; s=b; or a=LeftString(b,n).
        See class String documentation for details.
        This also applies to text and proc variables and variable names.

      o All variables which you put into lists must be allocated with new, because list items are deleted if lists are
        destroyed or re-assigned new data.

        Member functions - Overview: (simplified)
        -----------------------------------------

        (For operations on strings also see the class String documentation!)

      o Var creators
            Var     ( )                             unnamed empty variable; type=isVoid
            Var     ( vtype )                       unnamed empty variable; type=vtype; value=0.0/""/{}
            Var     ( name, vtype )                 named   empty variable
            Var     ( name, value )                 named   variable from numeric value
            Var     ( name, text )                  named   variable from text

      o Automatic type conversion creators
            Var     ( value )                       unnamed variable from numeric value (float or int)
            Var     ( text )                        unnamed variable from text (String, c-string or pascal-string)

      o Operators
            Var&    operator=   ( qData )           assignment: qData may be Var, text or numeric value,
                                                    source and target may intersect; e.g.: a[n]=a or a=a[n]

            Var&    operator[]  ( index )           access item in list variable

            Var     operator+   ( qData )           add qData. Works with number, text and list
            Var&    operator+=  ( qData )           ""
            Var     operator-   ( qData )           subtract qData. Works with number and list
            Var&    operator-=  ( qData )           ""
            Var     operator*   ( qData )           multiply qData. Works with number, text and list
            Var&    operator*=  ( qData )           ""
            Var     operator/   ( qData )           divide qData. Works with number and list
            Var&    operator/=  ( qData )           ""
            Var     operator%   ( qData )           modulo qData. Works with number and list
            Var&    operator%=  ( qData )           ""

            bool    operator==  ( qData )           works with all data types and with all mixtures of data types
            bool    operator!=  ( qData )           ""
            bool    operator>   ( qData )           ""
            bool    operator>=  ( qData )           ""
            bool    operator<   ( qData )           ""
            bool    operator<=  ( qData )           ""

      o Functions
            void    SetType     ( vtype )           clear variable and set new data type manually
            vtype   GetType     ( )                 querry data type

            Var*    Parent      ( )                 access parent list or NULL if this Var is not within a list
            uint    Index       ( )                 querry own index in parent list or any arbitrary value if not in a list

            String& Name        ( )                 querry variable's name
            void    SetName     ( name )            redefine variable's name
            Var*    FindItem    ( name )            find item or sub-item of any depth in list

            double  Value       ( )                 access contents of numeric variable
            Var&    MaxVar      ( Var& q )          returns reference to bigger variable (any data type mix)
            Var&    MinVar      ( Var& q )          returns reference to smaller variable (any data type mix)

            String& Text        ( )                 access contents of text variable
          - Examples for class String usage:
            uchar&  Text()[index]                   access individual characters (with range check)
            void    Text().MakeWritable()           make text writable (because text is frequently shared)

            String& Proc        ( )                 access executable data (by your interpreter or what else)

            int     ListSize    ( )                 querry list size
            void    ShrinkToFit ( bool rec )        free spare memory occupied by list, purge trailing void variables in list, opt. recursively
            bool    Contains    ( Var& that )       test if this Var contains that Var

            void    ResizeList  ( newsize )         shrink or grow list manually
            void    InsertItem  ( index )           insert empty (isVoid) variable; trailing list moves to make room
            void    DeleteItem  ( index )           remove variable; trailing list moves to close room
            void    AppendItem  ( Var )             append variable to list
            void    AppendList  ( Var )             concatenate lists
            void    Sort        ( )                 sort list
            void    RSort       ( )                 backward sort list
            Var&    MaxVar      ( )                 find maximum value in list (items may be any type)
            Var&    MinVar      ( )                 find minimum value in list (items may be any type)
            void    ConvertCharset ( destiny )      convert string or all strings within list e.g. to html °
            String  ListVar     ( bool e, bool n )  create a text listing of the contents of this variable, opt. escaped, opt. with names

      o Misc. Utilities
            String  Escaped     ( text )            replace special chars by escape sequence, e.g.:   a\\bcde
            String  UnEscaped   ( text )            undo escape
            String  Quoted      ( text )            escape text and put it in quotes: "a\\bcde.."
            String  UnQuoted    ( text )            undo quote

                                                    °) ConvertCharset() still work in progress