git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@155 626c5289-ae23-0410-ae9c-e8d60b6d4f22
1157 lines
35 KiB
C
1157 lines
35 KiB
C
/* -----------------------------------------------------------------------------
|
|
* base.c
|
|
*
|
|
* This file contains the function entry points for dispatching methods on
|
|
* DOH objects. A number of small utility functions are also included.
|
|
*
|
|
* Author(s) : David Beazley (beazley@cs.uchicago.edu)
|
|
*
|
|
* Copyright (C) 1999-2000. The University of Chicago
|
|
* See the file LICENSE for information on usage and redistribution.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
static char cvsroot[] = "$Header$";
|
|
|
|
#include "dohint.h"
|
|
|
|
static DohObjInfo DohBaseType = {
|
|
"Base", /* objname */
|
|
sizeof(DohBase), /* objsize */
|
|
0, /* doh_del */
|
|
0, /* doh_copy */
|
|
0, /* doh_clear */
|
|
0, /* doh_scope */
|
|
0, /* doh_str */
|
|
0, /* doh_data */
|
|
0, /* doh_dump */
|
|
0, /* doh_len */
|
|
0, /* doh_hash */
|
|
0, /* doh_cmp */
|
|
0, /* doh_mapping */
|
|
0, /* doh_sequence */
|
|
0, /* doh_file */
|
|
0, /* doh_string */
|
|
0, /* doh_callable */
|
|
0, /* doh_positional */
|
|
0, /* reserved5 */
|
|
0, /* reserved6 */
|
|
0, /* user1 */
|
|
0, /* user2 */
|
|
0, /* user3 */
|
|
0, /* user4 */
|
|
};
|
|
|
|
static int doh_debug_level = 0;
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohTrace()
|
|
*
|
|
* This function is used to print tracing information during debugging.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
void
|
|
DohTrace(int level, char *fmt, ...) {
|
|
va_list ap;
|
|
va_start(ap,fmt);
|
|
if (level & doh_debug_level) {
|
|
printf("DOH %x:", level);
|
|
vprintf(fmt,ap);
|
|
}
|
|
va_end(ap);
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohDebug()
|
|
*
|
|
* Set the DOH tracing level.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
void
|
|
DohDebug(int d) {
|
|
doh_debug_level = d;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohDelete()
|
|
*
|
|
* Delete an object by decreasing its reference count. Calls the object
|
|
* destructor if the reference count is zero after the decrement.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
void
|
|
DohDelete(DOH *obj) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohDelete %x\n",obj);
|
|
if (!DohCheck(b)) return;
|
|
if (b->flags & DOH_FLAG_INTERN) return;
|
|
b->refcount--;
|
|
if (b->refcount == 0) {
|
|
if (b->objinfo->doh_del) (b->objinfo->doh_del)(obj);
|
|
}
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohIntern()
|
|
*
|
|
* Flips the intern bit on an object forcing it to be never be garbage collected.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
void
|
|
DohIntern(DOH *obj) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohIntern %x\n", obj);
|
|
if (!DohCheck(b)) return;
|
|
b->flags = b->flags | DOH_FLAG_INTERN;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohCopy()
|
|
*
|
|
* Make a copy of an object.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
DOH *
|
|
DohCopy(DOH *obj) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohCopy %x\n",obj);
|
|
if (!DohCheck(b)) {
|
|
DohTrace(DOH_UNKNOWN,"Unknown object %x passed to Copy.\n", obj);
|
|
return 0;
|
|
}
|
|
if (b->objinfo->doh_copy) return (b->objinfo->doh_copy)(obj);
|
|
DohTrace(DOH_UNSUPPORTED,"No copy method defined for type '%s'\n", b->objinfo->objname);
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohClear()
|
|
*
|
|
* Clear the contents of an object.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
void
|
|
DohClear(DOH *obj) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohClear %x\n",obj);
|
|
if (!DohCheck(b)) {
|
|
DohTrace(DOH_UNKNOWN,"Unknown object %x passed to Clear.\n",obj);
|
|
return;
|
|
}
|
|
if (b->objinfo->doh_clear) {
|
|
(b->objinfo->doh_clear)(obj);
|
|
return;
|
|
}
|
|
DohTrace(DOH_UNSUPPORTED, "No clear method defined for type '%s'\n", b->objinfo->objname);
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohSetScope()
|
|
*
|
|
* Manually change the scope level of an object.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
void
|
|
DohSetScope(DOH *obj, int s) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohScope %x\n",obj);
|
|
if (!DohCheck(b)) {
|
|
DohTrace(DOH_UNKNOWN,"Unknown object %x passed to Scope.\n",obj);
|
|
return;
|
|
}
|
|
if (b->objinfo->doh_scope) {
|
|
(b->objinfo->doh_scope)(obj,s);
|
|
return;
|
|
}
|
|
if (s < b->scope) b->scope = s;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohStr()
|
|
*
|
|
* Create a string representation of an object. If the object has no str method
|
|
* a generic representation of the form <Object 'name' at %x> is created.
|
|
* Non-DOH objects are assumed to
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
DOH *
|
|
DohStr(DOH *obj) {
|
|
DOH *s;
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohStr %x\n",obj);
|
|
if (DohCheck(b)) {
|
|
if (b->objinfo->doh_str) {
|
|
return (b->objinfo->doh_str)(b);
|
|
}
|
|
s = NewString("<Object ");
|
|
Printf(s,"'%s' at %x>", b->objinfo->objname, b);
|
|
Seek(s,0,SEEK_SET);
|
|
return s;
|
|
} else {
|
|
DohTrace(DOH_CONVERSION, "Creating new string from unknown object %x (assuming char *).\n", obj);
|
|
return NewString(obj);
|
|
}
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohDump()
|
|
*
|
|
* Serialize an object onto an output stream.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
DohDump(DOH *obj, DOH *out) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohDump %x, %x\n",obj,out);
|
|
if (DohCheck(obj)) {
|
|
if (b->objinfo->doh_dump) {
|
|
return (b->objinfo->doh_dump)(b,out);
|
|
}
|
|
DohTrace(DOH_UNSUPPORTED,"No dump method defined for type '%s'\n", b->objinfo->objname);
|
|
} else {
|
|
DohTrace(DOH_UNKNOWN, "Unknown object %x passed to Dump.\n",obj);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohLen()
|
|
*
|
|
* Return the length of an object. If a non-DOH object is passed, strlen()
|
|
* is invoked on it.
|
|
* ----------------------------------------------------------------------------- */
|
|
int
|
|
DohLen(DOH *obj) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohLen %x\n",obj);
|
|
if (!b) return 0;
|
|
if (DohCheck(b)) {
|
|
if (b->objinfo->doh_len) {
|
|
return (b->objinfo->doh_len)(obj);
|
|
}
|
|
DohTrace(DOH_UNSUPPORTED, "No len method defined for type '%s'\n", b->objinfo->objname);
|
|
} else {
|
|
DohTrace(DOH_CONVERSION, "Using strlen() on unknown object %x.\n", obj);
|
|
return strlen((char *) obj);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohHashVal()
|
|
*
|
|
* Compute the integer hash value of an object. Only needed for objects that
|
|
* need to serve as a keys.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
DohHashval(DOH *obj) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohHashval %x\n",obj);
|
|
if (DohCheck(b)) {
|
|
if (b->objinfo->doh_hash) {
|
|
return (b->objinfo->doh_hash)(obj);
|
|
}
|
|
DohTrace(DOH_UNSUPPORTED,"No hash method defined for type '%s'\n", b->objinfo->objname);
|
|
} else {
|
|
DohTrace(DOH_UNKNOWN,"Unknown object %x passed to Hashval.\n", obj);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohData()
|
|
*
|
|
* Return pointer to the raw data stored inside an object (when applicable).
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
void *
|
|
DohData(DOH *obj) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohData %x\n",obj);
|
|
if (DohCheck(obj)) {
|
|
if (b->objinfo) {
|
|
if (b->objinfo->doh_data) {
|
|
return (b->objinfo->doh_data)(obj);
|
|
}
|
|
}
|
|
DohTrace(DOH_UNSUPPORTED,"No data method defined for type '%s'\n", b->objinfo->objname);
|
|
return 0;
|
|
}
|
|
DohTrace(DOH_CONVERSION, "Unknown object %x passed to Data being returned as-is.\n", obj);
|
|
return (char *) obj;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohGetLine()
|
|
*
|
|
* Return the line number associated with an object or -1 if unspecified.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
DohGetline(DOH *obj) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohGetline %x\n",obj);
|
|
if (DohCheck(obj)) {
|
|
if (b->objinfo->doh_position && b->objinfo->doh_position->doh_getline) {
|
|
return (b->objinfo->doh_position->doh_getline)(obj);
|
|
} else {
|
|
DohTrace(DOH_UNSUPPORTED,"No getline method defined for type '%s'\n", b->objinfo->objname);
|
|
return -1;
|
|
}
|
|
}
|
|
DohTrace(DOH_UNKNOWN, "Unknown object %x passed to Getline.\n", obj);
|
|
return -1;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohSetLine()
|
|
*
|
|
* Set the line number associated with an object.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
void
|
|
DohSetline(DOH *obj, int line) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohSetline %x, %d\n",obj, line);
|
|
if (DohCheck(obj)) {
|
|
if (b->objinfo->doh_position && b->objinfo->doh_position->doh_setline) {
|
|
(b->objinfo->doh_position->doh_setline)(obj, line);
|
|
return;
|
|
}
|
|
DohTrace(DOH_UNSUPPORTED,"No setline method defined for type '%s'\n", b->objinfo->objname);
|
|
} else {
|
|
DohTrace(DOH_UNKNOWN, "Unknown object %x passed to Setline.\n", obj);
|
|
}
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohGetfile()
|
|
*
|
|
* Get the file associated with an object.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
DOH *
|
|
DohGetfile(DOH *obj) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohGetfile %x\n",obj);
|
|
if (DohCheck(obj)) {
|
|
if (b->objinfo->doh_position && b->objinfo->doh_position->doh_getfile) {
|
|
return (b->objinfo->doh_position->doh_getfile)(obj);
|
|
}
|
|
DohTrace(DOH_UNSUPPORTED,"No getfile method defined for type '%s'\n", b->objinfo->objname);
|
|
} else {
|
|
DohTrace(DOH_UNKNOWN, "Unknown object %x passed to Getfile.\n", obj);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohSetfile()
|
|
*
|
|
* Set the file associated with an object.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
void
|
|
DohSetfile(DOH *obj, DOH *file) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohSetfile %x, %x\n",obj,file);
|
|
if (DohCheck(obj)) {
|
|
if (b->objinfo->doh_position && b->objinfo->doh_position->doh_setfile) {
|
|
(b->objinfo->doh_position->doh_setfile)(obj,file);
|
|
return;
|
|
}
|
|
DohTrace(DOH_UNSUPPORTED,"No setfile method defined for type '%s'\n", b->objinfo->objname);
|
|
} else {
|
|
DohTrace(DOH_UNKNOWN, "Unknown object %x passed to Setfile.\n", obj);
|
|
}
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohCmp()
|
|
*
|
|
* Compare two objects. If either of the objects are non-DOH objects, the
|
|
* objects are compared using strcmp().
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
DohCmp(DOH *obj1, DOH *obj2) {
|
|
DohBase *b1, *b2;
|
|
DohTrace(DOH_CALLS,"DohCmp %x, %x\n",obj1,obj2);
|
|
b1 = (DohBase *) obj1;
|
|
b2 = (DohBase *) obj2;
|
|
if ((!DohCheck(b1)) || (!DohCheck(b2))) {
|
|
return strcmp((char *) DohData(b1),(char *) DohData(b2));
|
|
}
|
|
if (b1->objinfo->doh_cmp) {
|
|
return (b1->objinfo->doh_cmp)(b1,b2);
|
|
}
|
|
DohTrace(DOH_UNSUPPORTED,"No cmp method defined for type '%s'\n", b1->objinfo->objname);
|
|
return 1;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
* Mapping Interface
|
|
* ---------------------------------------------------------------------- */
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohIsMapping()
|
|
*
|
|
* Return 1 if an object defines a mapping interface.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
DohIsMapping(DOH *obj) {
|
|
DohBase *b = (DohBase *) obj;
|
|
if (!DohCheck(b)) return 0;
|
|
if (b->objinfo->doh_mapping) return 1;
|
|
else return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohGetattr()
|
|
*
|
|
* Get an attribute from a mapping object.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
DOH *
|
|
DohGetattr(DOH *obj, DOH *name) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohGetattr %x, %x\n",obj,name);
|
|
if (DohIsMapping(b)) {
|
|
if (b->objinfo->doh_mapping->doh_getattr) {
|
|
return (b->objinfo->doh_mapping->doh_getattr)(obj,name);
|
|
}
|
|
}
|
|
if (DohCheck(b)) {
|
|
DohTrace(DOH_UNSUPPORTED,"No getattr method defined for type '%s'\n", b->objinfo->objname);
|
|
} else {
|
|
DohTrace(DOH_UNKNOWN,"Unknown object %x passed to Getattr.\n", obj);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohSetattr()
|
|
*
|
|
* Set an attribute in a mapping object.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
DohSetattr(DOH *obj, DOH *name, DOH *value) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohSetattr %x, %x, %x\n",obj,name, value);
|
|
if (DohIsMapping(b)) {
|
|
if (b->objinfo->doh_mapping->doh_setattr) {
|
|
return (b->objinfo->doh_mapping->doh_setattr)(obj,name,value);
|
|
}
|
|
}
|
|
if (DohCheck(b)) {
|
|
DohTrace(DOH_UNSUPPORTED, "No setattr method defined for type '%s'\n", b->objinfo->objname);
|
|
} else {
|
|
DohTrace(DOH_UNKNOWN,"Unknown object %x passed to Setattr\n", obj);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohDelattr()
|
|
*
|
|
* Delete an attribute in a mapping object.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
void
|
|
DohDelattr(DOH *obj, DOH *name) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohDelattr %x, %x\n",obj,name);
|
|
if (DohIsMapping(obj)) {
|
|
if (b->objinfo->doh_mapping->doh_delattr) {
|
|
(b->objinfo->doh_mapping->doh_delattr)(obj,name);
|
|
return;
|
|
}
|
|
}
|
|
if (DohCheck(obj)) {
|
|
DohTrace(DOH_UNSUPPORTED, "No delattr method defined for type '%s'\n", b->objinfo->objname);
|
|
} else {
|
|
DohTrace(DOH_UNKNOWN,"Unknown object %x passed to Delattr\n",obj);
|
|
}
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohFirstkey()
|
|
*
|
|
* Return the first key value in a mapping object.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
DOH *
|
|
DohFirstkey(DOH *obj) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohFirstkey %x\n",obj);
|
|
if (DohIsMapping(obj)) {
|
|
if (b->objinfo->doh_mapping->doh_firstkey) {
|
|
return (b->objinfo->doh_mapping->doh_firstkey)(obj);
|
|
}
|
|
}
|
|
if (DohCheck(obj)) {
|
|
DohTrace(DOH_UNSUPPORTED,"No firstkey method defined for type '%s'\n", b->objinfo->objname);
|
|
} else {
|
|
DohTrace(DOH_UNKNOWN,"Unknown object %x passed to DohFirstkey\n",obj);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohNextkey()
|
|
*
|
|
* Return the next key in a mapping object.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
DOH *
|
|
DohNextkey(DOH *obj) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohNextkey %x\n",obj);
|
|
if (DohIsMapping(obj)) {
|
|
if (b->objinfo->doh_mapping->doh_nextkey) {
|
|
return (b->objinfo->doh_mapping->doh_nextkey)(obj);
|
|
}
|
|
}
|
|
if (DohCheck(obj)) {
|
|
DohTrace(DOH_UNSUPPORTED,"No nextkey method defined for type '%s'\n", b->objinfo->objname);
|
|
} else {
|
|
DohTrace(DOH_UNKNOWN,"Unknown object %x passed to DohNextkey\n",obj);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohGetInt()
|
|
*
|
|
* Return an element as an integer.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
DohGetInt(DOH *obj, DOH *name) {
|
|
DOH *val;
|
|
DohTrace(DOH_CALLS,"DohGetInt %x, %x\n",obj,name);
|
|
val = Getattr(obj,name);
|
|
if (!val) return 0;
|
|
if (DohIsString(val)) {
|
|
return atoi(Data(val));
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohGetDouble()
|
|
*
|
|
* Return an element as a double.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
double
|
|
DohGetDouble(DOH *obj, DOH *name) {
|
|
DOH *val;
|
|
DohTrace(DOH_CALLS,"DohGetDouble %x, %x\n",obj,name);
|
|
val = Getattr(obj,name);
|
|
if (!val) return 0;
|
|
if (DohIsString(val)) {
|
|
return atof(Data(val));
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohGetChar()
|
|
*
|
|
* Return an element as a char *
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
char *
|
|
DohGetChar(DOH *obj, DOH *name) {
|
|
DOH *val;
|
|
DohTrace(DOH_CALLS,"DohGetChar %x, %x\n",obj,name);
|
|
val = Getattr(obj,name);
|
|
if (!val) return 0;
|
|
if (DohIsString(val)) {
|
|
return (char *) Data(val);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohSetInt()
|
|
*
|
|
* Set an attribute as an integer
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
void
|
|
DohSetInt(DOH *obj, DOH *name, int value) {
|
|
DOH *temp;
|
|
DohTrace(DOH_CALLS,"DohSetInt %x, %x, %d\n", obj, name, value);
|
|
temp = NewString("");
|
|
Printf(temp,"%d",value);
|
|
Setattr(obj,name,temp);
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohSetDouble()
|
|
*
|
|
* Set an attribute as a double
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
void
|
|
DohSetDouble(DOH *obj, DOH *name, double value) {
|
|
DOH *temp;
|
|
DohTrace(DOH_CALLS,"DohSetDouble %x, %x, %g\n", obj, name, value);
|
|
temp = NewString("");
|
|
Printf(temp,"%0.17f",value);
|
|
Setattr(obj,name,temp);
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohSetChar()
|
|
*
|
|
* Set an attribute as a string.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
void
|
|
DohSetChar(DOH *obj, DOH *name, char *value) {
|
|
DOH *temp;
|
|
DohTrace(DOH_CALLS,"DohSetChar %x, %x, %g\n", obj, name, value);
|
|
temp = NewString(value);
|
|
Setattr(obj,name,temp);
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
* Sequence Interface
|
|
* ---------------------------------------------------------------------- */
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohIsSequence()
|
|
*
|
|
* Return 1 if an object supports sequence methods.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
DohIsSequence(DOH *obj) {
|
|
DohBase *b = (DohBase *) obj;
|
|
if (!DohCheck(b)) return 0;
|
|
if (b->objinfo->doh_sequence) return 1;
|
|
else return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohGetitem()
|
|
*
|
|
* Return an item from a sequence.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
DOH *
|
|
DohGetitem(DOH *obj, int index) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohGetitem %x, %d\n",obj,index);
|
|
if (DohIsSequence(obj)) {
|
|
if (b->objinfo->doh_sequence->doh_getitem) {
|
|
return (b->objinfo->doh_sequence->doh_getitem)(obj,index);
|
|
}
|
|
}
|
|
if (DohCheck(obj)) {
|
|
DohTrace(DOH_UNSUPPORTED,"No getitem method defined for type '%s'\n", b->objinfo->objname);
|
|
} else {
|
|
DohTrace(DOH_UNKNOWN,"Unknown object %x passed to DohGetitem\n",obj);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohSetitem()
|
|
*
|
|
* Set an item in a sequence.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
DohSetitem(DOH *obj, int index, DOH *value) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohSetitem %x, %d, %x\n",obj,index, value);
|
|
if (DohIsSequence(obj)) {
|
|
if (b->objinfo->doh_sequence->doh_setitem) {
|
|
return (b->objinfo->doh_sequence->doh_setitem)(obj,index,value);
|
|
}
|
|
}
|
|
if (DohCheck(obj)) {
|
|
DohTrace(DOH_UNSUPPORTED,"No setitem method defined for type '%s'\n", b->objinfo->objname);
|
|
} else {
|
|
DohTrace(DOH_UNKNOWN,"Unknown object %x passed to DohSetitem\n",obj);
|
|
}
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohDelitem()
|
|
*
|
|
* Delete an item in a sequence.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
DohDelitem(DOH *obj, int index) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohDelitem %x, %d\n",obj,index);
|
|
if (DohIsSequence(obj)) {
|
|
if (b->objinfo->doh_sequence->doh_delitem) {
|
|
return (b->objinfo->doh_sequence->doh_delitem)(obj,index);
|
|
}
|
|
}
|
|
if (DohCheck(obj)) {
|
|
DohTrace(DOH_UNSUPPORTED,"No delitem method defined for type '%s'\n", b->objinfo->objname);
|
|
} else {
|
|
DohTrace(DOH_UNKNOWN,"Unknown object %x passed to DohDelitem\n",obj);
|
|
}
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohInsertitem()
|
|
*
|
|
* Insert an item into a sequence.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
DohInsertitem(DOH *obj, int index, DOH *value) {
|
|
int no = 0;
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohInsertitem %x, %d, %x\n",obj,index, value);
|
|
if (DohIsSequence(obj)) {
|
|
if (b->objinfo->doh_sequence->doh_insitem) {
|
|
return (b->objinfo->doh_sequence->doh_insitem)(obj,index,value);
|
|
}
|
|
}
|
|
if (DohCheck(obj)) {
|
|
DohTrace(DOH_UNSUPPORTED,"No insitem method defined for type '%s'\n", b->objinfo->objname);
|
|
} else {
|
|
DohTrace(DOH_UNKNOWN,"Unknown object %x passed to DohInsertitem\n",obj);
|
|
}
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohFirstitem()
|
|
*
|
|
* Get the first item in a sequence
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
DOH *
|
|
DohFirstitem(DOH *obj) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohFirstitem %x\n");
|
|
if (DohIsSequence(obj)) {
|
|
if (b->objinfo->doh_sequence->doh_firstitem) {
|
|
return (b->objinfo->doh_sequence->doh_firstitem)(obj);
|
|
}
|
|
}
|
|
if (DohCheck(obj)) {
|
|
DohTrace(DOH_UNSUPPORTED,"No firstitem method defined for type '%s'\n", b->objinfo->objname);
|
|
} else {
|
|
DohTrace(DOH_UNKNOWN,"Unknown object %x passed to DohFirstitem\n",obj);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohNextitem()
|
|
*
|
|
* Get the next item in a sequence.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
DOH *
|
|
DohNextitem(DOH *obj) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohNextitem %x\n");
|
|
if (DohIsSequence(obj)) {
|
|
if (b->objinfo->doh_sequence->doh_nextitem) {
|
|
return (b->objinfo->doh_sequence->doh_nextitem)(obj);
|
|
}
|
|
}
|
|
if (DohCheck(obj)) {
|
|
DohTrace(DOH_UNSUPPORTED,"No nextitem method defined for type '%s'\n", b->objinfo->objname);
|
|
} else {
|
|
DohTrace(DOH_UNKNOWN,"Unknown object %x passed to DohNextitem\n",obj);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* File methods
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohIsFile()
|
|
*
|
|
* Return 1 if an object supports file methods.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
DohIsFile(DOH *obj) {
|
|
DohBase *b = (DohBase *) obj;
|
|
if (!DohCheck(b)) return 0;
|
|
if (b->objinfo->doh_file) return 1;
|
|
else return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohRead()
|
|
*
|
|
* Read bytes from an object. Implicitly converts to a FILE *.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
DohRead(DOH *obj, void *buffer, int length) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohRead %x, %x, %d\n",obj,buffer,length);
|
|
if (DohIsFile(obj)) {
|
|
if (b->objinfo->doh_file->doh_read) {
|
|
return (b->objinfo->doh_file->doh_read)(obj,buffer,length);
|
|
}
|
|
} else if (!DohCheck(b)) {
|
|
/* Hmmm. Not a file. Maybe it's a real FILE */
|
|
DohTrace(DOH_CONVERSION,"Unknown object %x converted to FILE * in DohRead\n",b);
|
|
return fread(buffer,1,length,(FILE *) b);
|
|
}
|
|
DohTrace(DOH_UNSUPPORTED,"No read method defined for type '%s'\n", b->objinfo->objname);
|
|
return -1;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohWrite()
|
|
*
|
|
* Write bytes to an object. Implicitly converts to a FILE *
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
DohWrite(DOH *obj, void *buffer, int length) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohWrite %x, %x, %d\n",obj,buffer,length);
|
|
if (DohIsFile(obj)) {
|
|
if (b->objinfo->doh_file->doh_write) {
|
|
return (b->objinfo->doh_file->doh_write)(obj,buffer,length);
|
|
}
|
|
}
|
|
if (!DohCheck(b)) {
|
|
/* Hmmm. Not a file. Maybe it's a real FILE */
|
|
DohTrace(DOH_CONVERSION,"Unknown object %x converted to FILE * in DohWrite\n",b);
|
|
return fwrite(buffer,1,length,(FILE *) b);
|
|
}
|
|
DohTrace(DOH_UNSUPPORTED,"No write method defined for type '%s'\n", b->objinfo->objname);
|
|
return -1;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohSeek()
|
|
*
|
|
* Seek to a new position.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
DohSeek(DOH *obj, long offset, int whence) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohSeek %x, %d, %d\n",obj,offset,whence);
|
|
if (DohIsFile(obj)) {
|
|
if (b->objinfo->doh_file->doh_seek) {
|
|
return (b->objinfo->doh_file->doh_seek)(obj,offset,whence);
|
|
}
|
|
}
|
|
if (!DohCheck(b)) {
|
|
DohTrace(DOH_CONVERSION,"Unknown object %x converted to FILE * in DohSeek\n",b);
|
|
return fseek((FILE *) b, offset, whence);
|
|
}
|
|
DohTrace(DOH_UNSUPPORTED,"No seek method defined for type '%s'\n", b->objinfo->objname);
|
|
return -1;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohTell()
|
|
*
|
|
* Return current file pointer.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
long
|
|
DohTell(DOH *obj) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohTell %x\n",obj);
|
|
if (DohIsFile(obj)) {
|
|
if (b->objinfo->doh_file->doh_tell) {
|
|
return (b->objinfo->doh_file->doh_tell)(obj);
|
|
}
|
|
}
|
|
if (!DohCheck(b)) {
|
|
DohTrace(DOH_CONVERSION,"Unknown object %x converted to FILE * in DohTell\n",b);
|
|
return ftell((FILE *) b);
|
|
}
|
|
DohTrace(DOH_UNSUPPORTED,"No tell method defined for type '%s'\n", b->objinfo->objname);
|
|
return -1;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohGetc()
|
|
*
|
|
* Return a character
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
DohGetc(DOH *obj) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohGetc %x\n",obj);
|
|
if (DohIsFile(obj)) {
|
|
if (b->objinfo->doh_file->doh_getc) {
|
|
return (b->objinfo->doh_file->doh_getc)(obj);
|
|
}
|
|
}
|
|
if (!DohCheck(b)) {
|
|
DohTrace(DOH_CONVERSION,"Unknown object %x converted to FILE * in DohGetc\n",b);
|
|
return fgetc((FILE *) b);
|
|
}
|
|
DohTrace(DOH_UNSUPPORTED,"No getc method defined for type '%s'\n", b->objinfo->objname);
|
|
return EOF;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohPutc()
|
|
*
|
|
* Put a character.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
DohPutc(int ch, DOH *obj) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohPutc '%c',%x\n",ch,obj);
|
|
if (DohIsFile(obj)) {
|
|
if (b->objinfo->doh_file->doh_putc) {
|
|
return (b->objinfo->doh_file->doh_putc)(obj,ch);
|
|
}
|
|
}
|
|
if (!DohCheck(b)) {
|
|
DohTrace(DOH_CONVERSION,"Unknown object %x converted to FILE * in DohPutc\n",b);
|
|
return fputc(ch,(FILE *) b);
|
|
}
|
|
DohTrace(DOH_UNSUPPORTED,"No putc method defined for type '%s'\n", b->objinfo->objname);
|
|
return EOF;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohUngetc()
|
|
*
|
|
* Put a character back on the input stream.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
DohUngetc(int ch, DOH *obj) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohUngetc '%c',%x\n",ch,obj);
|
|
if (DohIsFile(obj)) {
|
|
if (b->objinfo->doh_file->doh_ungetc) {
|
|
return (b->objinfo->doh_file->doh_ungetc)(obj,ch);
|
|
}
|
|
}
|
|
if (!DohCheck(b)) {
|
|
DohTrace(DOH_CONVERSION,"Unknown object %x converted to FILE * in DohUngetc\n",b);
|
|
return ungetc(ch,(FILE *) b);
|
|
}
|
|
DohTrace(DOH_UNSUPPORTED,"No ungetc method defined for type '%s'\n", b->objinfo->objname);
|
|
return EOF;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohClose()
|
|
*
|
|
* Close a file object.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
DohClose(DOH *obj) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohClose %x\n",obj);
|
|
if (DohIsFile(obj)) {
|
|
if (b->objinfo->doh_file->doh_close) {
|
|
return (b->objinfo->doh_file->doh_close)(obj);
|
|
}
|
|
}
|
|
if (!DohCheck(b)) {
|
|
DohTrace(DOH_CONVERSION,"Unknown object %x converted to FILE * in DohClose\n",b);
|
|
return fclose((FILE *) obj);
|
|
}
|
|
DohTrace(DOH_UNSUPPORTED,"No close method defined for type '%s'\n", b->objinfo->objname);
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* String methods
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohIsString()
|
|
*
|
|
* Return 1 if an object supports string methods.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
DohIsString(DOH *obj) {
|
|
DohBase *b = (DohBase *) obj;
|
|
if (!DohCheck(b)) return 0;
|
|
if (b->objinfo->doh_string) return 1;
|
|
else return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohReplace()
|
|
*
|
|
* Perform string replacement.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
DohReplace(DOH *src, DOH *token, DOH *rep, int flags) {
|
|
DohBase *b = (DohBase *) src;
|
|
DohTrace(DOH_CALLS, "DohReplace %x\n", src);
|
|
if (DohIsString(src)) {
|
|
if (b->objinfo->doh_string->doh_replace) {
|
|
return (b->objinfo->doh_string->doh_replace)(src,token,rep,flags);
|
|
}
|
|
}
|
|
if (DohCheck(b)) {
|
|
DohTrace(DOH_UNSUPPORTED, "No replace method defined for type '%s'\n", b->objinfo->objname);
|
|
} else {
|
|
DohTrace(DOH_UNKNOWN,"Unknown object %x passed to Replace\n", b);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohChop()
|
|
*
|
|
* Chop whitespace at the end of a string.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
void
|
|
DohChop(DOH *src) {
|
|
DohBase *b = (DohBase *) src;
|
|
DohTrace(DOH_CALLS, "DohChop %x\n", src);
|
|
if (DohIsString(src)) {
|
|
if (b->objinfo->doh_string->doh_chop) {
|
|
(b->objinfo->doh_string->doh_chop)(src);
|
|
}
|
|
}
|
|
if (DohCheck(b)) {
|
|
DohTrace(DOH_UNSUPPORTED, "No chop method defined for type '%s'\n", b->objinfo->objname);
|
|
} else {
|
|
DohTrace(DOH_UNKNOWN,"Unknown object %x passed to Chop\n", b);
|
|
}
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* Callable methods
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohIsCallable()
|
|
*
|
|
* Return 1 if an object supports callable methods.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
DohIsCallable(DOH *obj) {
|
|
DohBase *b = (DohBase *) obj;
|
|
if (!DohCheck(b)) return 0;
|
|
if (b->objinfo->doh_callable) return 1;
|
|
else return 0;
|
|
}
|
|
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohCall()
|
|
*
|
|
* Perform a function call on an object.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
DOH *
|
|
DohCall(DOH *obj, DOH *args) {
|
|
DohBase *b = (DohBase *) obj;
|
|
DohTrace(DOH_CALLS,"DohCall %x\n",obj);
|
|
if (DohCheck(b)) {
|
|
if ((b->objinfo->doh_callable) && (b->objinfo->doh_callable->doh_call)) {
|
|
return (b->objinfo->doh_callable->doh_call)(b,args);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohInit()
|
|
*
|
|
* Initialize an object.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
void
|
|
DohInit(DOH *b) {
|
|
DohBase *bs = (DohBase *) b;
|
|
bs->refcount = 1;
|
|
bs->objinfo = &DohBaseType;
|
|
bs->flags = 0;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohXBase_setfile()
|
|
*
|
|
* Set file location (default method).
|
|
* ----------------------------------------------------------------------------- */
|
|
void
|
|
DohXBase_setfile(DOH *ho, DOH *file) {
|
|
DohXBase *h = (DohXBase *) ho;
|
|
if (!DohCheck(file)) file = NewString(file);
|
|
h->file = file;
|
|
Incref(h->file);
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohXBase_getfile()
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
DOH *
|
|
DohXBase_getfile(DOH *ho) {
|
|
DohXBase *h = (DohXBase *) ho;
|
|
return h->file;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohXBase_setline()
|
|
* ----------------------------------------------------------------------------- */
|
|
void
|
|
DohXBase_setline(DOH *ho, int l) {
|
|
DohXBase *h = (DohXBase *) ho;
|
|
h->line = l;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohXBase_getline()
|
|
* ----------------------------------------------------------------------------- */
|
|
int
|
|
DohXBase_getline(DOH *ho) {
|
|
DohXBase *h = (DohXBase *) ho;
|
|
return h->line;
|
|
}
|
|
|
|
static DohPositionalMethods XBasePositionalMethods = {
|
|
DohXBase_setfile,
|
|
DohXBase_getfile,
|
|
DohXBase_setline,
|
|
DohXBase_getline
|
|
};
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* DohXInit()
|
|
*
|
|
* Initialize an extended object.
|
|
* ----------------------------------------------------------------------------- */
|
|
void
|
|
DohXInit(DOH *b) {
|
|
DohXBase *bs = (DohXBase *) b;
|
|
bs->file = 0;
|
|
bs->line = 0;
|
|
bs->objinfo->doh_position = &XBasePositionalMethods;
|
|
}
|
|
|
|
|
|
|
|
|