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,val)         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
Close(obj)                      Close

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

flags is one of the following:
     DOH_REPLACE_ANY
     DOH_REPLACE_NOQUOTE
     DOH_REPLACE_ID
     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.





