diff options
Diffstat (limited to 'Source/DOH/base.c')
-rw-r--r-- | Source/DOH/base.c | 943 |
1 files changed, 943 insertions, 0 deletions
diff --git a/Source/DOH/base.c b/Source/DOH/base.c new file mode 100644 index 0000000..4262e70 --- /dev/null +++ b/Source/DOH/base.c @@ -0,0 +1,943 @@ +/* ----------------------------------------------------------------------------- + * 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. + * ----------------------------------------------------------------------------- */ + +char cvsroot_base_c[] = "$Id: base.c 11097 2009-01-30 10:27:37Z bhy $"; + +#include "dohint.h" + +/* ----------------------------------------------------------------------------- + * DohDelete() + * ----------------------------------------------------------------------------- */ + +#ifndef SWIG_DEBUG_DELETE +#define SWIG_DEBUG_DELETE 0 +#endif + +void DohDelete(DOH *obj) { + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo; + + if (!obj) + return; +#if SWIG_DEBUG_DELETE + if (!DohCheck(b)) { + fputs("DOH: Fatal error. Attempt to delete a non-doh object.\n", stderr); + abort(); + } +#endif + if (b->flag_intern) + return; + assert(b->refcount > 0); + b->refcount--; + if (b->refcount <= 0) { + objinfo = b->type; + if (objinfo->doh_del) { + (objinfo->doh_del) (b); + } else { + if (b->data) + DohFree(b->data); + } + DohObjFree(b); + } +} + +/* ----------------------------------------------------------------------------- + * DohCopy() + * ----------------------------------------------------------------------------- */ + +DOH *DohCopy(const DOH *obj) { + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo; + + if (!obj) + return 0; + objinfo = b->type; + if (objinfo->doh_copy) { + DohBase *bc = (DohBase *) (objinfo->doh_copy) (b); + if ((bc) && b->meta) { + bc->meta = Copy(b->meta); + } + return (DOH *) bc; + } + return 0; +} + +void DohIncref(DOH *obj) { + Incref(obj); +} + +/* ----------------------------------------------------------------------------- + * DohClear() + * ----------------------------------------------------------------------------- */ + +void DohClear(DOH *obj) { + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo = b->type; + if (objinfo->doh_clear) + (objinfo->doh_clear) (b); +} + +/* ----------------------------------------------------------------------------- + * DohStr() + * ----------------------------------------------------------------------------- */ + +DOH *DohStr(const DOH *obj) { + char buffer[512]; + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo; + if (DohCheck(b)) { + objinfo = b->type; + if (objinfo->doh_str) { + return (objinfo->doh_str) (b); + } + sprintf(buffer, "<Object '%s' at %p>", objinfo->objname, (void *) b); + return NewString(buffer); + } else { + return NewString(obj); + } +} + +/* ----------------------------------------------------------------------------- + * DohDump() + * ----------------------------------------------------------------------------- */ + +int DohDump(const DOH *obj, DOH *out) { + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo = b->type; + if (objinfo->doh_dump) { + return (objinfo->doh_dump) (b, out); + } + return 0; +} + +/* ----------------------------------------------------------------------------- + * DohLen() - Defaults to strlen() if not a DOH object + * ----------------------------------------------------------------------------- */ +int DohLen(const DOH *obj) { + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo; + if (!b) + return 0; + if (DohCheck(b)) { + objinfo = b->type; + if (objinfo->doh_len) { + return (objinfo->doh_len) (b); + } + return 0; + } else { + return strlen((char *) obj); + } +} + +/* ----------------------------------------------------------------------------- + * DohHashVal() + * ----------------------------------------------------------------------------- */ + +int DohHashval(const DOH *obj) { + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo; + /* obj is already checked and/or converted into DohBase* */ + /* if (DohCheck(b)) */ + { + objinfo = b->type; + if (objinfo->doh_hashval) { + return (objinfo->doh_hashval) (b); + } + } + return 0; +} + +/* ----------------------------------------------------------------------------- + * DohData() + * ----------------------------------------------------------------------------- */ + +void *DohData(const DOH *obj) { + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo; + if (DohCheck(obj)) { + objinfo = b->type; + if (objinfo->doh_data) { + return (objinfo->doh_data) (b); + } + return 0; + } + return (void *) obj; +} + +/* ----------------------------------------------------------------------------- + * RawData() + * ----------------------------------------------------------------------------- */ + +static void *RawData(DohBase *b) { + DohObjInfo *objinfo = b->type; + return (objinfo->doh_data) ? (objinfo->doh_data) (b) : 0; +} + + +/* ----------------------------------------------------------------------------- + * DohCmp() + * ----------------------------------------------------------------------------- */ + +int DohCmp(const DOH *obj1, const DOH *obj2) { + DohBase *b1, *b2; + DohObjInfo *b1info, *b2info; + int c1, c2; + b1 = (DohBase *) obj1; + b2 = (DohBase *) obj2; + c1 = DohCheck(b1); + c2 = DohCheck(b2); + /* most of the times, obj2 is a plain c string */ + if (!c1 || !c2) { + if ((b1 == 0) && (b2 == 0)) + return 0; + if (b1 && !b2) + return 1; + if (!b1 && b2) + return -1; + return strcmp((char *) (c1 ? RawData(b1) : (void *) obj1), (char *) (c2 ? RawData(b2) : (void *) obj2)); + } + b1info = b1->type; + b2info = b2->type; + if ((b1info == b2info) && (b1info->doh_cmp)) + return (b1info->doh_cmp) (b1, b2); + return 1; +} + +/* ----------------------------------------------------------------------------- + * DohEqual() + * ----------------------------------------------------------------------------- */ + +int DohEqual(const DOH *obj1, const DOH *obj2) { + DohBase *b1 = (DohBase *) obj1; + DohBase *b2 = (DohBase *) obj2; + if (!b1) { + return !b2; + } else if (!b2) { + return 0; + } else { + DohObjInfo *b1info = 0; + DohObjInfo *b2info = 0; + if (DohCheck(b1)) { + b1info = b1->type; + if (DohCheck(b2)) { + b2info = b2->type; + } else { + int len = (b1info->doh_len) (b1); + char *cobj = (char *) obj2; + return len == (int) strlen(cobj) ? (memcmp(RawData(b1), cobj, len) == 0) : 0; + } + } else if (DohCheck(b2)) { + int len = (b2->type->doh_len) (b2); + char *cobj = (char *) obj1; + return len == (int) strlen(cobj) ? (memcmp(RawData(b2), cobj, len) == 0) : 0; + } else { + return strcmp((char *) obj1, (char *) obj2) == 0; + } + + if (!b1info) { + return obj1 == obj2; + } else if ((b1info == b2info)) { + return b1info->doh_equal ? (b1info->doh_equal) (b1, b2) : (b1info->doh_cmp ? (b1info->doh_cmp) (b1, b2) == 0 : (b1 == b2)); + } else { + return 0; + } + } +} + +/* ----------------------------------------------------------------------------- + * DohFirst() + * ----------------------------------------------------------------------------- */ + +DohIterator DohFirst(DOH *obj) { + DohIterator iter; + DohBase *b; + DohObjInfo *binfo; + + b = (DohBase *) obj; + if (DohCheck(b)) { + binfo = b->type; + if (binfo->doh_first) { + return (binfo->doh_first) (b); + } + } + iter.object = 0; + iter.item = 0; + iter.key = 0; + iter._current = 0; + iter._index = 0; + return iter; +} + +/* ----------------------------------------------------------------------------- + * DohNext() + * ----------------------------------------------------------------------------- */ + +DohIterator DohNext(DohIterator iter) { + DohIterator niter; + + if (iter.object) { + DohBase *b; + DohObjInfo *binfo; + + b = (DohBase *) iter.object; + binfo = b->type; + if (binfo->doh_next) { + return (binfo->doh_next) (iter); + } + } + niter = iter; + return niter; +} + +/* ----------------------------------------------------------------------------- + * DohIsMapping() + * ----------------------------------------------------------------------------- */ +int DohIsMapping(const DOH *obj) { + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo; + if (!DohCheck(b)) + return 0; + objinfo = b->type; + if (objinfo->doh_hash) + return 1; + else + return 0; +} + +/* ----------------------------------------------------------------------------- + * DohGetattr() + * ----------------------------------------------------------------------------- */ + +DOH *DohGetattr(DOH *obj, const DOH *name) { + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo = b->type; + if (objinfo->doh_hash && objinfo->doh_hash->doh_getattr) { + DOH *r = (objinfo->doh_hash->doh_getattr) (b, (DOH *) name); + return (r == DohNone) ? 0 : r; + } + return 0; +} + +/* ----------------------------------------------------------------------------- + * DohSetattr() + * ----------------------------------------------------------------------------- */ + +int DohSetattr(DOH *obj, const DOH *name, const DOH *value) { + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo = b->type; + if (objinfo->doh_hash && objinfo->doh_hash->doh_setattr) { + return (objinfo->doh_hash->doh_setattr) (b, (DOH *) name, (DOH *) value); + } + return 0; +} + +/* ----------------------------------------------------------------------------- + * DohDelattr() + * ----------------------------------------------------------------------------- */ + +int DohDelattr(DOH *obj, const DOH *name) { + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo = b->type; + if (objinfo->doh_hash && objinfo->doh_hash->doh_delattr) { + return (objinfo->doh_hash->doh_delattr) (b, (DOH *) name); + } + return 0; +} + +/* ----------------------------------------------------------------------------- + * DohCheckattr() + * ----------------------------------------------------------------------------- */ + +int DohCheckattr(DOH *obj, const DOH *name, const DOH *value) { + DOH *attr = Getattr(obj,name); + if (!attr) return 0; + return DohEqual(attr,value); +} + +/* ----------------------------------------------------------------------------- + * DohKeys() + * ----------------------------------------------------------------------------- */ + +DOH *DohKeys(DOH *obj) { + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo = b->type; + if (objinfo && objinfo->doh_hash->doh_keys) { + return (objinfo->doh_hash->doh_keys) (b); + } + return 0; +} + +/* ----------------------------------------------------------------------------- + * DohGetInt() + * ----------------------------------------------------------------------------- */ + +int DohGetInt(DOH *obj, const DOH *name) { + DOH *val; + val = Getattr(obj, (DOH *) name); + if (!val) + return 0; + if (DohIsString(val)) { + return atoi((char *) Data(val)); + } + return 0; +} + +/* ----------------------------------------------------------------------------- + * DohGetDouble() + * ----------------------------------------------------------------------------- */ + +double DohGetDouble(DOH *obj, const DOH *name) { + DOH *val; + val = Getattr(obj, (DOH *) name); + if (!val) + return 0; + if (DohIsString(val)) { + return atof((char *) Data(val)); + } + return 0; +} + +/* ----------------------------------------------------------------------------- + * DohGetChar() + * ----------------------------------------------------------------------------- */ + +char *DohGetChar(DOH *obj, const DOH *name) { + DOH *val; + val = Getattr(obj, (DOH *) name); + if (!val) + return 0; + if (DohIsString(val)) { + return (char *) Data(val); + } + return 0; +} + +/* ----------------------------------------------------------------------------- + * DohGetFlagAttr() / DohGetFlag() + * A flag is unset if the attribute (name) does not exist on the node (obj), + * or it is set to "0". If the attribute is set to any other value, + * the flag is set. + * + * DohGetFlag() returns if the flag is set or not + * DohGetFlagAttr() returns the flag value if is set, NULL otherwise + * ----------------------------------------------------------------------------- */ + + +DOH *DohGetFlagAttr(DOH *obj, const DOH *name) { + DOH *val = Getattr(obj, (DOH *) name); + if (!val) { + return NULL; + } else { + const char *cval = Char(val); + if (!cval) + return val; + return (strcmp(cval, "0") != 0) ? val : NULL; + } +} + +int DohGetFlag(DOH *obj, const DOH *name) { + return DohGetFlagAttr(obj, name) ? 1 : 0; +} + + +/* ----------------------------------------------------------------------------- + * DohGetVoid() + * ----------------------------------------------------------------------------- */ + +void *DohGetVoid(DOH *obj, const DOH *name) { + DOH *val; + val = Getattr(obj, (DOH *) name); + if (!val) + return 0; + return (void *) Data(val); +} + +/* ----------------------------------------------------------------------------- + * DohSetInt() + * ----------------------------------------------------------------------------- */ + +void DohSetInt(DOH *obj, const DOH *name, int value) { + DOH *temp; + temp = NewStringEmpty(); + Printf(temp, "%d", value); + Setattr(obj, (DOH *) name, temp); +} + +/* ----------------------------------------------------------------------------- + * DohSetDouble() + * ----------------------------------------------------------------------------- */ + +void DohSetDouble(DOH *obj, const DOH *name, double value) { + DOH *temp; + temp = NewStringEmpty(); + Printf(temp, "%0.17f", value); + Setattr(obj, (DOH *) name, temp); +} + +/* ----------------------------------------------------------------------------- + * DohSetChar() + * ----------------------------------------------------------------------------- */ + +void DohSetChar(DOH *obj, const DOH *name, char *value) { + Setattr(obj, (DOH *) name, NewString(value)); +} + +/* ----------------------------------------------------------------------------- + * DohSetFlag() + * ----------------------------------------------------------------------------- */ + +void DohSetFlagAttr(DOH *obj, const DOH *name, const DOH *attr) { + Setattr(obj, (DOH *) name, attr ? attr : NewString("0")); +} + +void DohSetFlag(DOH *obj, const DOH *name) { + Setattr(obj, (DOH *) name, NewString("1")); +} + +/* ----------------------------------------------------------------------------- + * DohSetVoid() + * ----------------------------------------------------------------------------- */ + +void DohSetVoid(DOH *obj, const DOH *name, void *value) { + Setattr(obj, (DOH *) name, NewVoid(value, 0)); +} + +/* ----------------------------------------------------------------------------- + * DohIsSequence() + * ----------------------------------------------------------------------------- */ + +int DohIsSequence(const DOH *obj) { + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo; + if (!DohCheck(b)) + return 0; + objinfo = b->type; + if (objinfo->doh_list) + return 1; + else + return 0; +} + +/* ----------------------------------------------------------------------------- + * DohGetitem() + * ----------------------------------------------------------------------------- */ + +DOH *DohGetitem(DOH *obj, int index) { + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo = b->type; + if (objinfo->doh_list && objinfo->doh_list->doh_getitem) { + return (objinfo->doh_list->doh_getitem) (b, index); + } + return 0; +} + +/* ----------------------------------------------------------------------------- + * DohSetitem() + * ----------------------------------------------------------------------------- */ + +int DohSetitem(DOH *obj, int index, const DOH *value) { + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo = b->type; + if (objinfo->doh_list && objinfo->doh_list->doh_setitem) { + return (objinfo->doh_list->doh_setitem) (b, index, (DOH *) value); + } + return -1; +} + +/* ----------------------------------------------------------------------------- + * DohDelitem() + * ----------------------------------------------------------------------------- */ + +int DohDelitem(DOH *obj, int index) { + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo = b->type; + if (objinfo->doh_list && objinfo->doh_list->doh_delitem) { + return (objinfo->doh_list->doh_delitem) (b, index); + } + return -1; +} + +/* ----------------------------------------------------------------------------- + * DohInsertitem() + * ----------------------------------------------------------------------------- */ + +int DohInsertitem(DOH *obj, int index, const DOH *value) { + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo = b->type; + if (objinfo->doh_list && objinfo->doh_list->doh_insitem) { + return (objinfo->doh_list->doh_insitem) (b, index, (DOH *) value); + } + return -1; +} + + +/* ----------------------------------------------------------------------------- + * DohDelslice() + * ----------------------------------------------------------------------------- */ + +int DohDelslice(DOH *obj, int sindex, int eindex) { + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo = b->type; + if (objinfo->doh_list && objinfo->doh_list->doh_delslice) { + return (objinfo->doh_list->doh_delslice) (b, sindex, eindex); + } + return -1; +} + +/* ----------------------------------------------------------------------------- + * DohIsFile() + * ----------------------------------------------------------------------------- */ + +int DohIsFile(const DOH *obj) { + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo; + if (!DohCheck(b)) + return 0; + objinfo = b->type; + if (objinfo->doh_file) + return 1; + else + return 0; +} + +/* ----------------------------------------------------------------------------- + * DohRead() + * ----------------------------------------------------------------------------- */ + +int DohRead(DOH *obj, void *buffer, int length) { + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo; + if (DohCheck(obj)) { + objinfo = b->type; + if ((objinfo->doh_file) && (objinfo->doh_file->doh_read)) { + return (objinfo->doh_file->doh_read) (b, buffer, length); + } + return -1; + } + /* Hmmm. Not a file. Maybe it's a real FILE */ + return fread(buffer, 1, length, (FILE *) b); +} + +/* ----------------------------------------------------------------------------- + * DohWrite() + * ----------------------------------------------------------------------------- */ + +int DohWrite(DOH *obj, void *buffer, int length) { + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo; + if (DohCheck(obj)) { + objinfo = b->type; + if ((objinfo->doh_file) && (objinfo->doh_file->doh_write)) { + return (objinfo->doh_file->doh_write) (b, buffer, length); + } + return -1; + } + /* Hmmm. Not a file. Maybe it's a real FILE */ + return fwrite(buffer, 1, length, (FILE *) b); +} + +/* ----------------------------------------------------------------------------- + * DohSeek() + * ----------------------------------------------------------------------------- */ + +int DohSeek(DOH *obj, long offset, int whence) { + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo; + if (DohCheck(obj)) { + objinfo = b->type; + if ((objinfo->doh_file) && (objinfo->doh_file->doh_seek)) { + return (objinfo->doh_file->doh_seek) (b, offset, whence); + } + return -1; + } + return fseek((FILE *) b, offset, whence); +} + +/* ----------------------------------------------------------------------------- + * DohTell() + * ----------------------------------------------------------------------------- */ + +long DohTell(DOH *obj) { + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo; + if (DohCheck(obj)) { + objinfo = b->type; + if ((objinfo->doh_file) && (objinfo->doh_file->doh_tell)) { + return (objinfo->doh_file->doh_tell) (b); + } + return -1; + } + return ftell((FILE *) b); +} + +/* ----------------------------------------------------------------------------- + * DohGetc() + * ----------------------------------------------------------------------------- */ + +int DohGetc(DOH *obj) { + static DOH *lastdoh = 0; + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo; + if (obj == lastdoh) { + objinfo = b->type; + return (objinfo->doh_file->doh_getc) (b); + } + if (DohCheck(obj)) { + objinfo = b->type; + if (objinfo->doh_file->doh_getc) { + lastdoh = obj; + return (objinfo->doh_file->doh_getc) (b); + } + return EOF; + } + return fgetc((FILE *) b); +} + +/* ----------------------------------------------------------------------------- + * DohPutc() + * ----------------------------------------------------------------------------- */ + +int DohPutc(int ch, DOH *obj) { + static DOH *lastdoh = 0; + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo; + + if (obj == lastdoh) { + objinfo = b->type; + return (objinfo->doh_file->doh_putc) (b, ch); + } + if (DohCheck(obj)) { + objinfo = b->type; + if (objinfo->doh_file->doh_putc) { + lastdoh = obj; + return (objinfo->doh_file->doh_putc) (b, ch); + } + return EOF; + } + return fputc(ch, (FILE *) b); +} + +/* ----------------------------------------------------------------------------- + * DohUngetc() + * ----------------------------------------------------------------------------- */ + +int DohUngetc(int ch, DOH *obj) { + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo; + if (DohCheck(obj)) { + objinfo = b->type; + if (objinfo->doh_file->doh_ungetc) { + return (objinfo->doh_file->doh_ungetc) (b, ch); + } + return EOF; + } + return ungetc(ch, (FILE *) b); +} + +/* ----------------------------------------------------------------------------- + * DohClose() + * ----------------------------------------------------------------------------- */ + +int DohClose(DOH *obj) { + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo; + if (DohCheck(obj)) { + objinfo = b->type; + if (objinfo->doh_file->doh_close) { + return (objinfo->doh_file->doh_close) (b); + } + return 0; + } + return fclose((FILE *) obj); +} + +/* ----------------------------------------------------------------------------- + * DohIsString() + * ----------------------------------------------------------------------------- */ + +int DohIsString(const DOH *obj) { + DohBase *b = (DohBase *) obj; + DohObjInfo *objinfo; + if (!DohCheck(b)) + return 0; + objinfo = b->type; + if (objinfo->doh_string) + return 1; + else + return 0; +} + +/* ----------------------------------------------------------------------------- + * DohReplace() + * ----------------------------------------------------------------------------- */ + +int DohReplace(DOH *src, const DOH *token, const DOH *rep, int flags) { + DohBase *b = (DohBase *) src; + DohObjInfo *objinfo; + if (!token) + return 0; + if (!rep) + rep = ""; + if (DohIsString(src)) { + objinfo = b->type; + if (objinfo->doh_string->doh_replace) { + return (objinfo->doh_string->doh_replace) (b, (DOH *) token, (DOH *) rep, flags); + } + } + return 0; +} + +/* ----------------------------------------------------------------------------- + * DohChop() + * ----------------------------------------------------------------------------- */ + +void DohChop(DOH *src) { + DohBase *b = (DohBase *) src; + DohObjInfo *objinfo; + if (DohIsString(src)) { + objinfo = b->type; + if (objinfo->doh_string->doh_chop) { + (objinfo->doh_string->doh_chop) (b); + } + } +} + +/* ----------------------------------------------------------------------------- + * DohSetFile() + * ----------------------------------------------------------------------------- */ +void DohSetfile(DOH *ho, DOH *file) { + DohBase *h = (DohBase *) ho; + DohObjInfo *objinfo; + if (!h) + return; + objinfo = h->type; + if (objinfo->doh_setfile) + (objinfo->doh_setfile) (h, file); +} + +/* ----------------------------------------------------------------------------- + * DohGetFile() + * ----------------------------------------------------------------------------- */ +DOH *DohGetfile(const DOH *ho) { + DohBase *h = (DohBase *) ho; + DohObjInfo *objinfo; + if (!h) + return 0; + objinfo = h->type; + if (objinfo->doh_getfile) + return (objinfo->doh_getfile) (h); + return 0; +} + +/* ----------------------------------------------------------------------------- + * DohSetLine() + * ----------------------------------------------------------------------------- */ +void DohSetline(DOH *ho, int l) { + DohBase *h = (DohBase *) ho; + DohObjInfo *objinfo; + if (!h) + return; + objinfo = h->type; + if (objinfo->doh_setline) + (objinfo->doh_setline) (h, l); +} + +/* ----------------------------------------------------------------------------- + * DohGetLine() + * ----------------------------------------------------------------------------- */ +int DohGetline(const DOH *ho) { + DohBase *h = (DohBase *) ho; + DohObjInfo *objinfo; + if (!h) + return 0; + objinfo = h->type; + if (objinfo->doh_getline) + return (objinfo->doh_getline) (h); + return 0; +} + +/* ----------------------------------------------------------------------------- + * DohGetmeta() + * ----------------------------------------------------------------------------- */ + +DOH *DohGetmeta(DOH *ho, const DOH *name) { + DohBase *h = (DohBase *) ho; + if (!DohCheck(ho)) + return 0; + if (!h->meta) + return 0; + return DohGetattr(h->meta, name); +} + +/* ----------------------------------------------------------------------------- + * DohGetmeta() + * ----------------------------------------------------------------------------- */ + +int DohSetmeta(DOH *ho, const DOH *name, const DOH *value) { + DohBase *h = (DohBase *) ho; + if (!DohCheck(ho)) + return 0; + if (!h->meta) + h->meta = NewHash(); + return DohSetattr(h->meta, name, value); +} + +/* ----------------------------------------------------------------------------- + * DohDelmeta() + * ----------------------------------------------------------------------------- */ + +int DohDelmeta(DOH *ho, const DOH *name) { + DohBase *h = (DohBase *) ho; + if (!DohCheck(ho)) + return 0; + if (!h->meta) + return 0; + return DohDelattr(h->meta, name); +} + +/* ----------------------------------------------------------------------------- + * DohSetmark() + * ----------------------------------------------------------------------------- */ + +void DohSetmark(DOH *ho, int x) { + DohBase *h = (DohBase *) ho; + h->flag_usermark = x; +} + +int DohGetmark(DOH *ho) { + DohBase *h = (DohBase *) ho; + return h->flag_usermark; +} + +/* ----------------------------------------------------------------------------- + * DohCall() + * + * Invokes a function via DOH. A Function is represented by a hash table with + * the following attributes: + * + * "builtin" - Pointer to built-in function (if any) + * + * (Additional attributes may be added later) + * + * Returns a DOH object with result on success. Returns NULL on error + * ----------------------------------------------------------------------------- */ + +DOH *DohCall(DOH *func, DOH *args) { + DOH *result; + DOH *(*builtin) (DOH *); + + builtin = (DOH *(*)(DOH *)) GetVoid(func, "builtin"); + if (!builtin) + return 0; + result = (*builtin) (args); + return result; +} |