DOH  (Dave's Object Hack)

Overview:
---------
DOH is a small C library that provides a number of simple yet powerful
data structures. The data structures are built around a dynamic typing
model in which any given object is allowed to support one or more
classes of operations.  Furthermore, a simple garbage collection
scheme and a variety of interesting library methods are available.
All and all, the operation of DOH makes massive abuse of the C type
system and would probably make the language purists scream and
performance addicts run away in horror.  However, I really don't
care--so there! However, for the rest of us, DOH is actually kind of
fun to use. This is only a short description of the methods and is no
way meant to be exhaustive.

Common Operations (for all types)
---------------------------------
Delete(obj)             Decrease the reference count and destroy if zero
Copy(obj)               Make a copy of an object.
Clear(obj)              Clear an object.
Setscope(obj)           Set scope of an object (guru's only)
Str(obj)                Create a string representation of obj.
Data(obj)               Return pointer to raw data in an object
Char(obj)               Convert to a char *
Len(obj)                Length of an object
Hash(obj)               Hash value (used for mapping)
Cmp(obj1,obj2)          Compare two objects.
Name(obj)               Return the object name
First(obj)              Return first object (iterator)
Next(obj)               Return next object
Dump(obj,out)           Serialize on out
Load(in)                Unserialize from in
First(obj)              Iterator
Next(iter)              Next iterator

Mapping Operations (for hash table behavior)
--------------------------------------------
Getattr(hash,key)              Get an attribute
Setattr(hash,key,value)        Set an attribute
Delattr(hash,key)              Delete an attribute
First(hash)                    Get first object (iterator)
Next(hash)                     Get next object
GetInt(hash,key)               Get attribute as an 'int'
SetInt(hash,key,ivalue)        Set attribute as an 'int'
GetDouble(hash,key)            Get attribute as a 'double'
SetDouble(hash,key,dvalue)     Set Attribute as a 'double'
GetChar(hash,key)              Get attribute as a 'char *'

Sequence Operations
-------------------
Getitem(list,index)             Get an item
Setitem(list,index,val)         Set an item
Delitem(list,index)             Delete an item
Insert(list,index,val)          Insert an item
Append(list,val)                Append to end
Push(list,val)                  Insert at beginning

File Operations
---------------
Read(obj,buffer,len)            Read data
Write(obj,buffer,len)           Write data
Getc(obj)                       Get a character
Putc(ch,obj)                    Put a character
Ungetc(ch,obj)                  Put character back on input stream
Seek(obj,offset,whence)         Seek
Tell(obj)                       Return file pointer
Delete(obj)                     Decrease the reference count, close file if zero

String Operations
-----------------
Replace(obj, orig, rep, flags)  Replace occurrences of orig with rep.
Chop(obj)                       Remove trailing whitespace

flags is one of the following:
    DOH_REPLACE_ID
    DOH_REPLACE_ID_BEGIN
    DOH_REPLACE_ID_END
    DOH_REPLACE_NUMBER_END

and can be combined with one or more of the following:
    DOH_REPLACE_ANY
    DOH_REPLACE_NOQUOTE
    DOH_REPLACE_NOCOMMENT
    DOH_REPLACE_FIRST

Callable Operations
-------------------
Call(obj, args)                 Perform a function call with arguments args.

Miscellaneous library functions
-------------------------------
NewScope()                      Create a new scope
DelScope(s)                     Delete scope s
Readline(in)                    Read a line of input from in
Printf(out,fmt,...)             Formatted output
DohEncoding(name, fn)           Register a format encoding for Printf

Currently Available datatypes
------------------------------
NewString(char *initial)                            Strings
NewHash()                                           Hash
NewList()                                           List
NewVoid(void *ptr, void (*del)(void *))             Void
NewFile(char *filename, char *mode, List *newfiles) File
NewCallable(DOH *(*func)(DOH *, DOH *))             Callable object


Odds and ends:

  1.   All objects are of type 'DOH *'
  2.   When in doubt, see rule (1)
  3.   In certain cases, DOH performs implicit conversions
       of 'char *' to an appropriate DOH string representation. 
       For operations involving files, DOH works with many
       kinds of objects including FILE *, DOH File objects,
       and DOH strings.  Don't even ask how this works.

  4.   More complete documentation is forthcoming.





