home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-12-23 | 38.6 KB | 1,619 lines |
- Newsgroups: alt.sources
- Path: sparky!uunet!spool.mu.edu!news.cs.indiana.edu!umn.edu!csus.edu!netcom.com!thinman
- From: thinman@netcom.com (Technically Sweet)
- Subject: COOL: C Object-Oriented Library: part 2 of 4
- Message-ID: <1992Dec23.191529.10437@netcom.com>
- Organization: International Foundation for Internal Freedom
- Date: Wed, 23 Dec 1992 19:15:29 GMT
- Lines: 1609
-
- #!/bin/sh
- # This is part 02 of a multipart archive
- # ============= class.c ==============
- if test -f 'class.c' -a X"$1" != X"-c"; then
- echo 'x - skipping class.c (File already exists)'
- else
- echo 'x - extracting class.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'class.c' &&
- X/*
- X * COOL: C Object-Oriented Library
- X *
- X * COOL Class object implementation.
- X * COOL initialization routine.
- X *
- X * Copyright 1991 by Lance Norskog
- X *
- X * First cut: lots of private tables, no good.
- X * Second cut: fixed-size method tables for classes,
- X * pointers for derived objects.
- X * ... minor fixes: 2-level inheritance didn't work!
- X * March 1992: add components for 5D project.
- X * June 1992: add type list options for Scheme interface
- X * ??? 1992: integrate with Scheme memory management
- X *
- X * Permission to use, copy, modify, and distribute this software and its
- X * documentation for any purpose and without fee is hereby granted, provided
- X * that the above copyright notice appear in all copies and that both that
- X * copyright notice and this permission notice appear in supporting
- X * documentation. This software is provided "as is" without express or
- X * implied warranty.
- X */
- X
- X#include <stdio.h>
- X#include <setjmp.h>
- X#include <varargs.h>
- X#include "cool.h"
- X#include "coolint.h"
- X
- X/* Class object internal data structure */
- Xstruct cool_class {
- X/* cool_priv_t cl_private; /* starts all private data */
- X sint cl_size; /* Size of private data */
- X sint cl_gap; /* future use */
- X object_t cl_parents[MAXPARENTS]; /* Table of parents */
- X methtab_t cl_methtab[MAXMETHODS]; /* Table of methods */
- X char * cl_compnames[MAXCOMP]; /* Names of components */
- X};
- Xtypedef struct cool_class *class_t;
- X
- Xstruct {
- X cool_priv_t private;
- X struct cool_class Class;
- X} uberclass;
- X
- Xstatic sint generation = 1; /* finds use of old objects */
- X
- X/*
- X * Add an object to table.
- X */
- Xstatic object_t
- Xaddobject(name)
- Xchar *name;
- X{
- X int newob, gen;
- X char *str = cool_strdup(name);
- X
- X newob = cool_freelist;
- X if (newob == 0)
- X cool_raise("OutOfObjects", CODEMARK);
- X cool_freelist = cool_objtab[OBJECTOF(newob)].ob_next;
- X
- X /* Build object */
- X bzero(&cool_objtab[OBJECTOF(newob)], sizeof(cool_objtab[0]));
- X cool_objtab[OBJECTOF(newob)].ob_name = str;
- X gen = cool_objtab[OBJECTOF(newob)].ob_generation;
- X /* wrap around */
- X if (generation == MAXIMUMGEN)
- X generation = 1;
- X
- X return (object_t) MKOBJECT(newob, gen);
- X}
- X
- X/*
- X * Delete an object from table.
- X */
- Xstatic
- Xdelobject(obj)
- Xobjtab_t *obj;
- X{
- X /* Find an object */
- X cool_strfree(obj->ob_name);
- X obj->ob_name = (char *) 0;
- X obj->ob_next = cool_freelist;
- X obj->ob_generation = BADGEN; /* Mark object as dead */
- X cool_freelist = (sint) (obj - cool_objtab);
- X}
- X
- X/* Native method handlers */
- X
- Xstatic ret_t
- Xclass_ambiguous(priv)
- Xcool_priv_t *priv;
- X{
- X /* look up class and method's name from private data */
- X cool_raise("Ambiguous", CODEMARK);
- X}
- X
- X/*
- X * Add/replace a method to object's method table.
- X */
- Xstatic
- Xmethod_t
- Xaddmethod(obj, name, func, nargs)
- Xobjtab_t *obj;
- Xchar *name;
- Xret_t (*func)();
- Xint nargs;
- X{
- X methtab_t *meth;
- X int i, m, found;
- X char *rt, *at;
- X
- X if (ISMETHOD(name))
- X cool_raise("AddMethod", "Class '%s': Method is not a string",
- X obj->ob_name);
- X
- X if ((nargs < 0) || (nargs >= MAXARGS))
- X cool_raise("AddMethod",
- X "Class '%s' Method '%s': Too many arguments: %d",
- X obj->ob_name, name, nargs);
- X
- X meth = obj->ob_methtab[MYMETHODS];
- X for(m = 0; m < MAXMETHODS; m++, meth++) {
- X if (! meth->m_name)
- X break;
- X if (cool_streq(meth->m_name, name)) {
- X /*
- X * Overriding a previous method. Probably inherited.
- X * If this breaks an ambiguity, count down.
- X */
- X if (meth->m_func == class_ambiguous)
- X obj->ob_ambiguous--;
- X break;
- X }
- X }
- X if (m == MAXMETHODS)
- X cool_raise("TooManyMethods", NULL);
- X
- X
- X /* force given argument list to match given number of arguments */
- X meth->m_func = func;
- X meth->m_nargs = nargs;
- X found = methdigest(meth, cool_strdup(name));
- X if ((found != -1) && (found != nargs))
- X cool_raise("MethodArgumentNumbers", NULL);
- X
- X return MKMETHOD(MYMETHODS, m);
- X}
- X
- X/* Class method handlers. */
- X
- X/*
- X * Add a method to a class.
- X */
- Xstatic method_t
- Xclass_addmethod(class, name, func, nargs)
- Xclass_t class;
- Xchar *name;
- Xret_t (*func)();
- Xint nargs;
- X{
- X method_t m;
- X methtab_t *meth;
- X objtab_t *obj;
- X char args[1024];
- X
- X cool_squish(name, args);
- X obj = &cool_objtab[OBJECTOF(SELFOF(class))];
- X /* The ambiguous thing should be handled here. */
- X return addmethod(obj, name, func, nargs);
- X}
- X
- X/* Slow class creation and destruction methods. */
- X
- X/*
- X * Create an instance of a class.
- X */
- Xstatic object_t
- Xclass_create_obj(class, name)
- Xclass_t class;
- Xchar *name;
- X{
- X object_t cl, ob;
- X objtab_t *obj, *clobj, *pobj;
- X methtab_t *mt;
- X cool_priv_t *priv;
- X char compname[128];
- X int i, m, p, q;
- X
- X if (SELFOF(class) != CLASSOF(class)) {
- X cool_raise("CreateObject", "Must send Create to a class");
- X }
- X if (name == NULL)
- X name = cool_makename();
- X ob = addobject(name);
- X obj = &cool_objtab[OBJECTOF(ob)];
- X clobj = &cool_objtab[OBJECTOF(SELFOF(class))];
- X
- X /* Copy method table */
- X bcopy(clobj->ob_methtab, obj->ob_methtab, sizeof(obj->ob_methtab));
- X
- X /* Allocate private chunks of inherited classes */
- X for(i = 0; i < MAXPARENTS; i++) {
- X class_t pclass;
- X
- X if (! (p = (cint) class->cl_parents[i]))
- X continue;
- X /* Get class struct of parent. &...[1] skips cool_priv_t. */
- X pclass = (class_t)
- X &cool_objtab[OBJECTOF(p)].ob_private[MYMETHODS][1];
- X obj->ob_private[i] = (cool_priv_t *)
- X cool_malloc(pclass->cl_size);
- X }
- X /* Allocate private chunk of this class. */
- X obj->ob_private[MYMETHODS] = (cool_priv_t *)cool_malloc(class->cl_size);
- X
- X /* Fill in all privates of object, including inherited data */
- X for(i = 0; i < ALLCLASSES; i++) {
- X /* Now, we want the cool_priv_t at the beginning. */
- X priv = obj->ob_private[i];
- X if (priv) {
- X priv->self = ob;
- X priv->class = SELFOF(class);
- X }
- X }
- X if (clobj->ob_ambiguous)
- X cool_raise("AmbiguousMethods", "Class %s", clobj->ob_name);
- X
- X
- X /* Create any component objects before init this object. */
- X /* ob_components in class object are class names */
- X /* ob_components in object are individual object names */
- X for(i = 0; (i < MAXCOMP) && clobj->ob_components[i]; i++) {
- X sprintf(compname, "%s.%s", name, class->cl_compnames[i]);
- X obj->ob_components[i] = coolta(object_t,
- X clobj->ob_components[i], METHOD_CREATE, compname);
- X }
- X
- X /* Call init functions of all my method tables */
- X /* Most distant ancestor first, then recent ancestors, then my own. */
- X /* Should reserve methods 0 & 1 for init and exit. LATER */
- X for(p = 0; p < ALLCLASSES; p++) {
- X mt = clobj->ob_methtab[p];
- X if (! mt)
- X continue;
- X (* mt[METHODOF(METHOD_INIT)].m_func)(obj->ob_private[p] + 1);
- X }
- X
- X return ob;
- X}
- X
- X/*
- X * Destroy an instance of a class.
- X */
- Xstatic
- Xclass_destroy_obj(class, ob)
- Xclass_t class;
- Xobject_t ob;
- X{
- X object_t cl, comp;
- X method_t exit;
- X objtab_t *obj;
- X methtab_t *mt;
- X int i, m, p;
- X
- X /* Convert to index form */
- X ob = (object_t) OBJECTOF(cool_object(ob));
- X
- X if (SELFOF(class) != CLASSOF(class)) {
- X coolva(cool_classof(ob), METHOD_DESTROY, ob);
- X return;
- X }
- X
- X
- X obj = &cool_objtab[(cint) ob];
- X
- X if (SELFOF(class) != cool_objtab[(cint)ob].ob_private[MYMETHODS]->class)
- X cool_raise("Destroy", "Class and object don\'t match");
- X
- X /* Call Exit functions of all its method tables */
- X /* My exit first, then recent ancestors, then most distant ancestor. */
- X /* Inverse order of object creation. */
- X /* Should reserve methods 0 & 1 for init and exit. LATER */
- X for(p = ALLCLASSES - 1; p >= 0; p--) {
- X mt = obj->ob_methtab[p];
- X if (! mt)
- X continue;
- X
- X (* mt[METHODOF(METHOD_EXIT)].m_func)(obj->ob_private[p] + 1);
- X cool_free((char *) obj->ob_private[p]);
- X }
- X
- X /* Destroy all component objects after main exit methods. */
- X for(i = 0; (i < MAXCOMP) && (comp = obj->ob_components[i]); i++)
- X coolva(cool_classof(comp), METHOD_DESTROY, comp);
- X
- X /* new gen for object; catch dangling references */
- X cool_objtab[(cint) ob].ob_generation++;
- X}
- X
- X/*
- X * Cause class to inherit a method from a parent class.
- X * The parent class may have inherited the method from one of its parents.
- X * If we allowed method changing for objects, this could be a standard
- X * object method.
- X */
- Xstatic
- Xmethod_t
- Xclass_inherit(class, method, parent)
- Xclass_t class;
- Xmethod_t method;
- Xobject_t parent;
- X{
- X objtab_t *pobj;
- X methtab_t *mt;
- X int myclass, p;
- X
- X /* Rationalize. */
- X parent = cool_object(parent);
- X
- X for(p = 0; p < MAXPARENTS; p++) {
- X if (class->cl_parents[p] == parent)
- X break;
- X }
- X if(p == MAXPARENTS)
- X cool_raise("ClassIsNotAParent", CODEMARK);
- X
- X /* Force exception if bogus. */
- X method = cool_method(parent, method);
- X
- X /* copy method from parent to my method_t */
- X myclass = OBJECTOF(CLASSOF(class));
- X p = OBJECTOF(parent);
- X mt = &cool_objtab[p].ob_methtab[MYMETHODS][METHODOF(method)];
- X
- X return addmethod(&cool_objtab[myclass], mt->m_name, mt->m_func, mt->m_nargs);
- X}
- X
- X/* Stubs, Init is the first method of every class. */
- Xstatic ret_t
- Xclass_init_obj() {;}
- X
- X/* Stubs, Exit is the second method of every class. */
- Xstatic ret_t
- Xclass_exit_obj() {;}
- X
- X/* Stubs, Copy is the third method of every class. */
- Xstatic void
- Xclass_copy_obj() {;}
- X
- X/*
- X * Clone is the method of every class.
- X * Make a "deep copy" of an object.
- X */
- Xstatic object_t
- Xclass_clone_obj(class, name, newname)
- Xclass_t class;
- Xchar *name, *newname;
- X{
- X object_t cl, ob, nob, comp;
- X objtab_t *obj, *clobj, *nobj;
- X methtab_t *mt;
- X cool_priv_t *priv;
- X int i, m, p, q;
- X
- X if (SELFOF(class) != CLASSOF(class)) {
- X coolva2(cool_classof(ob), METHOD_CLONE, SELFOF(class), newname);
- X }
- X
- X
- X if (newname == NULL)
- X newname = cool_makename();
- X else
- X if (cool_getobject((object_t) newname) != OBJECTERR)
- X cool_raise("Copy Object",
- X "New name is already an object");
- X
- X ob = cool_object((object_t) name);
- X obj = &cool_objtab[OBJECTOF(ob)];
- X nob = addobject(newname);
- X nobj = &cool_objtab[OBJECTOF(nob)];
- X clobj = &cool_objtab[OBJECTOF(SELFOF(class))];
- X if (SELFOF(class) != CLASSOF(obj->ob_private[MYMETHODS] + 1))
- X cool_raise("Copy Object", "Object is not in class");
- X
- X /* Copy method table from old to new object. */
- X bcopy(obj->ob_methtab, nobj->ob_methtab, sizeof(obj->ob_methtab));
- X
- X /* Allocate private chunks of inherited classes */
- X for(i = 0; i < MAXPARENTS; i++) {
- X class_t pclass;
- X
- X if (! (p = (cint) class->cl_parents[i]))
- X continue;
- X /* Get class struct of parent. &...[1] skips cool_priv_t. */
- X pclass = (class_t)
- X &cool_objtab[OBJECTOF(p)].ob_private[MYMETHODS][1];
- X nobj->ob_private[i] = (cool_priv_t *)
- X cool_malloc(pclass->cl_size);
- X /* Copy private area */
- X bcopy(obj->ob_private[i] + 1, nobj->ob_private[i] + 1,
- X pclass->cl_size - sizeof(cool_priv_t));
- X }
- X /* Allocate private chunk of this class. */
- X nobj->ob_private[MYMETHODS] = (cool_priv_t*)cool_malloc(class->cl_size);
- X
- X
- X /* Fill in all privates of object, including inherited data */
- X for(p = 0; p < ALLCLASSES; p++) {
- X /* Now, we want the cool_priv_t at the beginning. */
- X priv = nobj->ob_private[p];
- X if (priv) {
- X /* Copy private areas */
- X bcopy(obj->ob_private[p] + 1,
- X nobj->ob_private[p] + 1,
- X class->cl_size);
- X priv->self = ob; /* replace */
- X }
- X }
- X
- X /* Call copy functions of all my method tables */
- X /* Most distant ancestor first, then recent ancestors, then my own. */
- X for(p = 0; p < ALLCLASSES; p++) {
- X mt = clobj->ob_methtab[p];
- X if (! mt)
- X continue;
- X
- X /* Call copy methods */
- X (* mt[METHODOF(METHOD_COPY)].m_func)(obj->ob_private[p] + 1,
- X nobj->ob_private[p] + 1);
- X }
- X
- X /* Clone all component objects */
- X for(i = 0; (i < MAXCOMP) && (comp = obj->ob_components[i]); i++)
- X nobj->ob_components[i] =
- X coolt(object_t, comp, METHOD_CLONE);
- X
- X return nob;
- X}
- X
- X/*
- X * Add component to class.
- X */
- X
- Xclass_component(class, compclass, compname)
- Xclass_t class;
- Xchar *compname;
- Xobject_t compclass;
- X{
- X objtab_t *clobj;
- X int i;
- X
- X /* XXX check if it's really a class */
- X compclass = cool_object(compclass); /* rationalize */
- X if (! compname)
- X cool_raise("Component", "Must have valid string for name");
- X if (SELFOF(class) != CLASSOF(class))
- X cool_raise("Component", "Must send Component to a class");
- X clobj = &cool_objtab[OBJECTOF(SELFOF(class))];
- X for(i = 0; i < MAXCOMP; i++)
- X if (! clobj->ob_components[i])
- X break;
- X if (i == MAXCOMP)
- X cool_raise("Component", "Too many components");
- X clobj->ob_components[i] = compclass;
- X class->cl_compnames[i] = cool_strdup(compname);
- X}
- X
- X#ifdef SELFISH
- X/*
- X * Cause object to possess a new parent class.
- X */
- Xstatic
- Xmethod_t
- Xobj_addparent(priv, method, parent)
- Xpriv_t priv;
- Xmethod_t method;
- Xobject_t parent;
- X{
- X int i, newob;
- X class_t class;
- X objtab_t *obj;
- X method_t meth;
- X methtab_t **methpp;
- X int p, q, r;
- X
- X parent = cool_object(parent); /* rationalize */
- X
- X /* priv[-1] is the private area */
- X obj = &cool_objtab[OBJECTOF(CLASSOF(priv))];
- X for(p = 0; p < MAXPARENTS; p++)
- X if (class->cl_parents[p] == 0)
- X break;
- X if (p == MAXPARENTS)
- X cool_raise("TooManyParents", obj->ob_name);
- X class->cl_parents[p] = parent;
- X
- X /* Copy pointers to grandparents' etc. methods */
- X methpp = cool_objtab[OBJECTOF(parent)].ob_methtab;
- X q = 0;
- X for(r = 0; (r < MAXPARENTS) && methpp[r]; r++) {
- X obj->ob_methtab[q++] = methpp[r];
- X if (q == MAXPARENTS)
- X cool_raise("TooManyParents", obj->ob_name);
- X }
- X
- X /* Don't worry about ambigous methods for now. */
- X}
- X#endif
- X
- X/*
- X * Add a new class
- X */
- X
- Xstatic object_t
- Xclass_newclass(junk, name, size, va_alist)
- Xclass_t junk; /* not used */
- Xchar *name;
- Xint size;
- Xva_dcl /* wacky varargs syntax */
- X{
- X int i, newob;
- X class_t class, pclass;
- X objtab_t *obj;
- X method_t meth;
- X methtab_t **methpp;
- X int p, q, r;
- X va_list ap;
- X
- X for(newob = 0; newob < cool_numobs; newob++)
- X if (cool_streq(cool_objtab[OBJECTOF(newob)].ob_name, name))
- X cool_raise("ClassDoesExist", name);
- X newob = (int) addobject(name);
- X obj = &cool_objtab[OBJECTOF(newob)];
- X obj->ob_ambiguous = 0;
- X for(p = 0; p < MAXPARENTS; p++) {
- X obj->ob_private[p] = (cool_priv_t *) 0;
- X obj->ob_methtab[p] = (methtab_t *) 0;
- X }
- X
- X obj->ob_private[MYMETHODS] = (cool_priv_t *)
- X cool_malloc(sizeof (struct cool_class) + sizeof (cool_priv_t));
- X /* Ignore function parameter */
- X class = (class_t) &obj->ob_private[MYMETHODS][1];
- X obj->ob_methtab[MYMETHODS] = class->cl_methtab;
- X
- X SELFOF(class) = (object_t) newob;
- X CLASSOF(class) = (object_t) newob;
- X class->cl_size = size + sizeof(cool_priv_t);
- X
- X /* Get list of parents */
- X va_start(ap);
- X for(p = 0; p < MAXPARENTS; p++) {
- X if (class->cl_parents[p] = va_arg(ap, object_t)) {
- X class->cl_parents[p] = /* do lookup */
- X cool_object(class->cl_parents[p]);
- X q = OBJECTOF(class->cl_parents[p]);
- X pclass =
- X(class_t) &(cool_objtab[q].ob_private[MYMETHODS][1]);
- X /* copy parent's list of grandparents */
- X for(q = 0; pclass->cl_parents[q] &&
- X (p+1 < MAXPARENTS) && (q < MAXPARENTS); q++)
- X class->cl_parents[++p] = pclass->cl_parents[q];
- X } else
- X break;
- X }
- X va_end(ap);
- X
- X if (p > MAXPARENTS)
- X cool_raise("TooManyParents", CODEMARK);
- X for(; p < MAXPARENTS; p++)
- X class->cl_parents[p] = 0;
- X
- X /*
- X * Copy parent's method pointer tables to our table.
- X */
- X q = 0;
- X for(p = 0; p < MAXPARENTS && class->cl_parents[p]; p++) {
- X /* Copy pointers to grandparents' etc. methods */
- X methpp = cool_objtab[OBJECTOF(class->cl_parents[p])].ob_methtab;
- X /* Copy pointer to parent's own method table */
- X obj->ob_methtab[q++] = methpp[MYMETHODS];
- X if (q == MAXPARENTS)
- X cool_raise("TooManyInherits", obj->ob_name);
- X }
- X
- X/* n.b.: Object 0 is class Class. You cannot inherit from this class. */
- X
- X {
- X /* Don't count same method second time if there are 3 or more. */
- X char searched[MAXPARENTS][MAXMETHODS];
- X int m;
- X
- X for(p = 0; p < MAXPARENTS; p++) for(m = 0; m < MAXPARENTS; m++)
- X searched[p][m] = 0;
- X
- X /* First, add all well-known methods */
- X addmethod(obj, "Create=integer:", class_create_obj, 0);
- X addmethod(obj, "Create=integer:string", class_create_obj, 1);
- X addmethod(obj, "Destroy", class_destroy_obj, 1);
- X addmethod(obj, "Method", class_addmethod, MAXARGS - 1);
- X addmethod(obj, "Inherit", class_inherit, 2);
- X addmethod(obj, "Component", class_component, 2);
- X addmethod(obj, "Clone", class_clone_obj, 2);
- X addmethod(obj, "Init", class_init_obj, 0);
- X addmethod(obj, "Exit", class_exit_obj, 0);
- X addmethod(obj, "Copy", class_copy_obj, 1);
- X
- X /*
- X * Hunt for conflicts among parents' unique methods
- X * Mark by adding our own method with func class_ambiguous
- X */
- X obj->ob_ambiguous = 0;
- X for(p = 0; class->cl_parents[p] && (p < MAXPARENTS - 1); p++,methpp++) {
- X methtab_t *mp;
- X /* for each method after base class methods,
- X hunt remaining parents for it */
- X mp = obj->ob_methtab[p];
- X for (q = p + 1; q < MAXPARENTS; q++) {
- X /* Don't search well-known methods */
- X for(m = STDMETHODS; m < MAXMETHODS; m++)
- X if (mp[m].m_name && ! searched[p][m] &&
- X ((meth = cool_getmethod((object_t) mp[m].m_name,
- X obj->ob_methtab[q])) != METHODERR)) {
- X addmethod(obj, mp[m].m_name,
- X class_ambiguous, 0);
- X obj->ob_ambiguous++;
- X searched[PARENTOF(meth)][METHODOF(meth)]=1;
- X }
- X }
- X }
- X }
- X
- X return (object_t) newob;
- X}
- X
- Xtestgcc() {
- X#ifdef __GNUC__
- X /* -fwritable-strings test */
- X "abcde"[2] = 5;
- X /*
- X * COOL must be compiled with gcc -fwritable-strings
- X * to support the string/object disambiguation trick.
- X * Note the misspelling of writable.
- X */
- X#endif
- X}
- X
- Xvoid
- Xcool_init()
- X{
- X objtab_t *obj;
- X methtab_t *meth;
- X int i;
- X
- X testgcc();
- X
- X if (cool_freelist != 0)
- X cool_raise("Coolinit", "MultipleInit");
- X
- X /* build freelist */
- X for(i = 2; i < MAXOBJECTS; i++)
- X cool_objtab[i - 1].ob_next = i;
- X cool_freelist = 1;
- X
- X /* Build Class object */
- X obj = cool_objtab;
- X obj->ob_name = "Class";
- X for(i = 0; i < MAXPARENTS; i++) {
- X obj->ob_methtab[i] = (methtab_t *) 0;
- X obj->ob_private[i] = (cool_priv_t *) 0;
- X }
- X obj->ob_private[MYMETHODS] = (cool_priv_t *) &uberclass;
- X obj->ob_methtab[MYMETHODS] = uberclass.Class.cl_methtab;
- X
- X /* Add methods */
- X addmethod(obj, "Create", class_newclass, MAXPARENTS);
- X}
- X
- X
- SHAR_EOF
- chmod 0644 class.c ||
- echo 'restore of class.c failed'
- Wc_c="`wc -c < 'class.c'`"
- test 17641 -eq "$Wc_c" ||
- echo 'class.c: original size 17641, current size' "$Wc_c"
- fi
- # ============= msg.c ==============
- if test -f 'msg.c' -a X"$1" != X"-c"; then
- echo 'x - skipping msg.c (File already exists)'
- else
- echo 'x - extracting msg.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'msg.c' &&
- X
- X/*
- X * COOL: C Object-Oriented Library
- X *
- X * Message handler
- X *
- X * Copyright 1991 by Lance Norskog
- X *
- X * Permission to use, copy, modify, and distribute this software and its
- X * documentation for any purpose and without fee is hereby granted, provided
- X * that the above copyright notice appear in all copies and that both that
- X * copyright notice and this permission notice appear in supporting
- X * documentation. This software is provided "as is" without express or
- X * implied warranty.
- X */
- X
- X#include <stdio.h> /* for NULL */
- X#include <setjmp.h>
- X#include <varargs.h>
- X#include "cool.h"
- X#include "coolint.h"
- X
- X/*
- X * Handle a message to an object.
- X */
- Xret_t
- Xcool_msg(o, m, va_alist)
- Xobject_t o;
- Xmethod_t m;
- Xva_dcl
- X{
- X objtab_t *obj;
- X methtab_t *meth;
- X cint p;
- X unsigned long args[MAXARGS];
- X va_list ap;
- X int i;
- X
- X /* Convert object and method to index form */
- X if (ISOBJECT(o)) {
- X if (! GOODGEN(o))
- X cool_raise("BadGeneration", CODEMARK);
- X } else
- X o = (object_t) cool_object(o);
- X obj = &cool_objtab[OBJECTOF(o)];
- X if (! ISMETHOD(m)) {
- X m = (method_t) cool_method(o, m);
- X }
- X
- X /* Dispatch handler function with correct parent and sizes */
- X p = PARENTOF(m);
- X /* m = METHODOF(m); debug */
- X meth = &obj->ob_methtab[p][METHODOF(m)];
- X
- X /* get args */
- X va_start(ap);
- X for(i = 0; i < meth->m_nargs; i++)
- X args[i] = va_arg(ap, unsigned long);
- X va_end(ap);
- X
- X /* Only way to do it */
- X switch(meth->m_nargs) {
- X case 0:
- X return (* meth->m_func)(obj->ob_private[p] + 1);
- X case 1:
- X return (* meth->m_func)(obj->ob_private[p] + 1,
- X args[0]);
- X case 2:
- X return (* meth->m_func)(obj->ob_private[p] + 1,
- X args[0], args[1]);
- X case 3:
- X return (* meth->m_func)(obj->ob_private[p] + 1,
- X args[0], args[1], args[2]);
- X case 4:
- X return (* meth->m_func)(obj->ob_private[p] + 1,
- X args[0], args[1], args[2], args[3]);
- X case 5:
- X return (* meth->m_func)(obj->ob_private[p] + 1,
- X args[0], args[1], args[2], args[3], args[4]);
- X case 6:
- X return (* meth->m_func)(obj->ob_private[p] + 1,
- X args[0], args[1], args[2], args[3], args[4],
- X args[5]);
- X case 7:
- X return (* meth->m_func)(obj->ob_private[p] + 1,
- X args[0], args[1], args[2], args[3], args[4],
- X args[5], args[6]);
- X case 8:
- X return (* meth->m_func)(obj->ob_private[p] + 1,
- X args[0], args[1], args[2], args[3], args[4],
- X args[5], args[6], args[7]);
- X case 9:
- X default:
- X return (* meth->m_func)(obj->ob_private[p] + 1,
- X args[0], args[1], args[2], args[3], args[4],
- X args[5], args[6], args[7], args[8]);
- X /* ... MAXARGS */
- X }
- X}
- X
- X
- SHAR_EOF
- chmod 0644 msg.c ||
- echo 'restore of msg.c failed'
- Wc_c="`wc -c < 'msg.c'`"
- test 2528 -eq "$Wc_c" ||
- echo 'msg.c: original size 2528, current size' "$Wc_c"
- fi
- # ============= lookup.c ==============
- if test -f 'lookup.c' -a X"$1" != X"-c"; then
- echo 'x - skipping lookup.c (File already exists)'
- else
- echo 'x - extracting lookup.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'lookup.c' &&
- X/*
- X * COOL: C Object-Oriented Library
- X *
- X * Object and method string lookups
- X *
- X * Copyright 1991 by Lance Norskog
- X *
- X * June 1992: implement overloaded methods
- X *
- X * Permission to use, copy, modify, and distribute this software and its
- X * documentation for any purpose and without fee is hereby granted, provided
- X * that the above copyright notice appear in all copies and that both that
- X * copyright notice and this permission notice appear in supporting
- X * documentation. This software is provided "as is" without express or
- X * implied warranty.
- X */
- X
- X#include <stdio.h>
- X#include <setjmp.h>
- X#ifdef USG
- X#include <string.h>
- X#else
- X#include <strings.h>
- X#endif
- X#include "cool.h"
- X#include "coolint.h"
- X
- X/*
- X * Look up an object in the object table.
- X * Return error if not found.
- X *
- X * Internal use only!
- X */
- X
- X
- Xobject_t
- Xcool_getobject(object)
- Xobject_t object;
- X{
- X cint i;
- X
- X if (ISOBJECT(object))
- X if (GOODGEN(object))
- X return object;
- X else cool_raise("BadGeneration", CODEMARK);
- X else {
- X
- X /* yeah yeah yeah. This should use ob_next for a live list. */
- X for(i = 0; i < MAXOBJECTS; i++)
- X if (cool_objtab[i].ob_name &&
- X cool_streq(cool_objtab[i].ob_name,
- X (char *) object))
- X break;
- X if (i == MAXOBJECTS)
- X return OBJECTERR;
- X return (object_t) MKOBJECT(i, cool_objtab[i].ob_generation);
- X }
- X}
- X
- X/*
- X * Look up an object in the object table.
- X * Raise exception if not found.
- X */
- X
- Xobject_t
- Xcool_object(object)
- Xobject_t object;
- X{
- X object_t obj;
- X
- X obj = cool_getobject(object);
- X if (obj == OBJECTERR)
- X cool_raise("ObjectDoesNotExist", object);
- X return obj;
- X}
- X
- Xint
- Xcool_isobject(object)
- Xobject_t object;
- X{
- X object_t obj;
- X
- X obj = cool_getobject(object);
- X return (obj != OBJECTERR);
- X}
- X
- X/*
- X * Get a text name of an object.
- X */
- X
- Xchar *
- Xcool_nameof(object)
- Xobject_t object;
- X{
- X object_t obj;
- X
- X obj = cool_getobject(object);
- X if (obj == OBJECTERR)
- X cool_raise("ObjectDoesNotExist", object);
- X return cool_objtab[OBJECTOF(obj)].ob_name;
- X}
- X
- X/*
- X * Get a class object of an object.
- X */
- X
- Xobject_t
- Xcool_classof(object)
- Xobject_t object;
- X{
- X object_t ob;
- X objtab_t *obj;
- X int o, p;
- X
- X ob = cool_getobject(object);
- X if (ob == OBJECTERR)
- X cool_raise("ObjectDoesNotExist", object);
- X obj = &cool_objtab[OBJECTOF(ob)];
- X return cool_objtab[OBJECTOF(ob)].ob_private[MYMETHODS]->class;
- X}
- X
- X/*
- X * Get a component object of an object.
- X */
- X
- Xobject_t
- Xcool_componentof(object, name)
- Xobject_t object;
- Xchar *name;
- X{
- X char *obname, fullname[128];
- X object_t compob;
- X
- X obname = cool_nameof(object);
- X sprintf(fullname, "%s.%s", obname, name);
- X compob = cool_getobject((object_t) fullname);
- X if (compob == OBJECTERR)
- X cool_raise("ComponentDoesNotExist", fullname);
- X return compob;
- X}
- X
- X/*
- X * Look up a method in a particular method table.
- X * Internal use only!
- X */
- X
- Xmethod_t
- Xcool_getmethod(meth, mt)
- Xmethod_t meth;
- Xmethtab_t *mt;
- X{
- X cint i, m, match;
- X sint matches;
- X
- X if (ISMETHOD(meth))
- X return meth;
- X if (mt == NULL)
- X return METHODERR;
- X
- X for(matches = match = m = 0; m < MAXMETHODS; m++, mt++)
- X if (mt->m_name && metheq(mt, (char *) meth)) {
- X match = m;
- X matches++;
- X }
- X/* hack! make C keep working the old way for "Create"
- X if (matches == 1)
- X return (method_t) match;
- X*/
- X
- X /* return last match */
- X return (matches == 0) ? METHODERR : (method_t) match;
- X}
- X
- X/* walk methods - each time return next method with same name */
- Xmethod_t
- Xcool_walkmethods(object, name, mp, retp, nargsp, argsp)
- Xobject_t object;
- Xchar *name;
- Xmethod_t *mp;
- Xchar **retp;
- Xint *nargsp;
- Xchar ***argsp;
- X{
- X object_t ob;
- X objtab_t *obj;
- X method_t meth;
- X methtab_t *mt;
- X int m, p;
- X
- X ob = cool_getobject(object);
- X if (ob == OBJECTERR)
- X cool_raise("ObjectDoesNotExist", object);
- X obj = &cool_objtab[OBJECTOF(ob)];
- X
- X if (*mp == (method_t) -1) {
- X m = 0;
- X p = MYMETHODS;
- X } else {
- X /* Search starting after given parent/method */
- X m = METHODOF(*mp);
- X p = PARENTOF(*mp);
- X if (++m == MAXMETHODS) {
- X p--;
- X m = 0;
- X }
- X }
- X for(; p >= 0; p--, m = 0) {
- X if (! (mt = obj->ob_methtab[p]))
- X continue;
- X mt = &mt[m];
- X
- X for(; m < MAXMETHODS; m++, mt++)
- X if (cool_streq(mt->m_name, name)) {
- X *mp = MKMETHOD(p, m);
- X *retp = mt->m_rettype;
- X *argsp = mt->m_argtypes;
- X *nargsp = mt->m_nargs;
- X return 1;
- X }
- X }
- X
- X /* no more of this name */
- X return 0;
- X}
- X
- Xmethod_t
- Xcool_method(object, method)
- Xobject_t object;
- Xmethod_t method;
- X{
- X object_t ob;
- X objtab_t *obj;
- X method_t meth;
- X methtab_t *mt;
- X int p;
- X
- X ob = cool_getobject(object);
- X if (ob == OBJECTERR)
- X cool_raise("ObjectDoesNotExist", object);
- X obj = &cool_objtab[OBJECTOF(ob)];
- X /* Search object's methods, then parents' methods */
- X for(p = MYMETHODS; p >= 0; p--) {
- X if (mt = obj->ob_methtab[p])
- X if ((meth = cool_getmethod(method, mt)) != METHODERR)
- X return MKMETHOD(p, meth);
- X }
- X cool_raise("MethodDoesNotExist", method);
- X}
- X
- X
- Xint
- Xcool_hasmethod(object, method)
- Xobject_t object;
- Xmethod_t method;
- X{
- X
- X object_t ob;
- X objtab_t *obj;
- X method_t meth;
- X methtab_t *mt;
- X int p;
- X
- X ob = cool_getobject(object);
- X if (ob == OBJECTERR)
- X cool_raise("ObjectDoesNotExist", object);
- X obj = &cool_objtab[OBJECTOF(ob)];
- X /* Search object's methods, then parents' methods */
- X for(p = MYMETHODS; p >= 0; p--) {
- X if (mt = obj->ob_methtab[p])
- X if ((meth = cool_getmethod(method, mt)) != METHODERR)
- X return 1;
- X }
- X return 0;
- X}
- X
- Xstatic unsigned long argval[9];
- Xstatic char scmtype[9];
- Xstatic char cooltype[9];
- Xstatic char **ctype;
- X
- X/* table of names corresponding to argument types */
- Xchar *ctypenames[] = {
- X 0,
- X "", /* end of argument list */
- X "integer",
- X "bool",
- X "char",
- X "string",
- X "object",
- X "msg",
- X "double",
- X "ivect", /* vector of integers */
- X "dvect", /* vector of doubles */
- X "*", /* anything */
- X/* VR add-ons */
- X "point", /* 3 or 4 doubles */
- X "homog", /* homogeneous doubles matrix (4x4) */
- X (char *) 0
- X};
- X
- X/* digest an argument list. Return number of arguments found, -1 if no list */
- Xint
- Xmethdigest(mt, s)
- Xmethtab_t *mt;
- Xchar *s;
- X{
- X int i, j;
- X char *rt, *at;
- X
- X mt->m_name = s;
- X
- X /* add optional return type and arg type list */
- X /* chop up copy of full string into words, add to list */
- X /* syntax: method[=[return]][:[argtype[,argtype]*]] */
- X /* XXX doesn't catch case where same arg list and different return */
- X mt->m_rettype = (char *) 0;
- X for(i = 0; i < MAXARGS; i++)
- X mt->m_argtypes[i] = (char *) 0;
- X rt = index(mt->m_name, '=');
- X at = index(mt->m_name, ':');
- X if (rt && at && (rt > at) || index(mt->m_name, ' '))
- X cool_raise("MethodTypeSyntax", NULL);
- X if (at)
- X *at++ = '\0';
- X if (rt) {
- X *rt++ = '\0';
- X mt->m_rettype = rt;
- X /* parse out argument type */
- X for(j = 1; ctypenames[j]; j++)
- X if (cool_streq(rt, ctypenames[j]))
- X mt->m_rettype = (char *) j;
- X if (mt->m_rettype == CANY)
- X cool_raise("MethodReturns*", NULL);
- X }
- X if (at) {
- X if (index(at, ':') || index(at, '='))
- X cool_raise("MethodTypeSyntax", NULL);
- X mt->m_argtypes[0] = at;
- X for(i = 1; at = index(at, ','); i++) {
- X *at++ = '\0';
- X mt->m_argtypes[i] = at;
- X }
- X for(i = 0; mt->m_argtypes[i]; i++) {
- X /* parse out argument type */
- X for(j = 1; ctypenames[j]; j++)
- X if (cool_streq(mt->m_argtypes[i],ctypenames[j]))
- X mt->m_argtypes[i] = (char *) j;
- X }
- X /* name: no arguments. VOID is valid return but not arg. */
- X if (mt->m_argtypes[0] == CVOID) {
- X mt->m_argtypes[0] = 0;
- X return 0;
- X } else
- X return i;
- X }
- X return -1;
- X}
- X
- Xmetheq(mt, s)
- Xmethtab_t *mt;
- Xchar *s;
- X{
- X int i, nargs;
- X methtab_t tmp;
- X char strbuf[256];
- X
- X strcpy(strbuf, s);
- X tmp.m_nargs = methdigest(&tmp, strbuf);
- X
- X if (! cool_streq(mt->m_name, tmp.m_name))
- X return 0;
- X if (mt->m_rettype && tmp.m_rettype &&
- X ! cool_streq(mt->m_rettype, tmp.m_rettype))
- X return 0;
- X /* if argument list specified, it must match given method */
- X if ((tmp.m_nargs >= 0) && (mt->m_nargs != tmp.m_nargs))
- X return 0;
- X if (mt->m_argtypes[0] && tmp.m_argtypes[0])
- X if (! cool_streq(mt->m_argtypes[0], tmp.m_argtypes[0]))
- X return 0;
- X for(i = 1; i < MAXARGS && (mt->m_argtypes[i] || tmp.m_argtypes[i]);i++)
- X if (! cool_streq(mt->m_argtypes[i], tmp.m_argtypes[i]))
- X return 0;
- X return 1;
- X}
- X
- X/* junk */
- X
- X#ifdef JUNK
- Xmetheq(s1, s2)
- Xchar *s1, *s2;
- X{
- X for(; *s1 || *s2; s1++, s2++) {
- X if (*s1 == *s2)
- X continue;
- X /* if one ends and other doesn't */
- X if ((*s1 == '=' || *s1 == ':' || *s1 == ',') && !*s2)
- X return 1;
- X if ((*s2 == '=' || *s2 == ':' || *s2 == ',') && !*s1)
- X return 1;
- X /* skip optional return type if arglist */
- X if (*s1 == '=' && *s2 == ':')
- X while(*s1 != ':' && *s1)
- X s1++;
- X if (*s2 == '=' && *s1 == ':')
- X while(*s2 != ':' && *s2)
- X s2++;
- X }
- X return *s1 == *s2;
- X}
- X#endif
- X
- SHAR_EOF
- chmod 0644 lookup.c ||
- echo 'restore of lookup.c failed'
- Wc_c="`wc -c < 'lookup.c'`"
- test 8509 -eq "$Wc_c" ||
- echo 'lookup.c: original size 8509, current size' "$Wc_c"
- fi
- # ============= exception.c ==============
- if test -f 'exception.c' -a X"$1" != X"-c"; then
- echo 'x - skipping exception.c (File already exists)'
- else
- echo 'x - extracting exception.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'exception.c' &&
- X
- X/*
- X * COOL: C Object-Oriented Library
- X *
- X * COOL exception system.
- X *
- X * Copyright 1991 by Lance Norskog
- X *
- X * No, this will not work with threads.
- X * You'll have to integrate the two. Somehow. Don't ask me.
- X *
- X * Permission to use, copy, modify, and distribute this software and its
- X * documentation for any purpose and without fee is hereby granted, provided
- X * that the above copyright notice appear in all copies and that both that
- X * copyright notice and this permission notice appear in supporting
- X * documentation. This software is provided "as is" without express or
- X * implied warranty.
- X */
- X
- X#include <stdio.h>
- X#include <setjmp.h>
- X#include <varargs.h>
- X#include "cool.h"
- X#include "coolint.h"
- X
- X/*
- X * Exception stack.
- X */
- X
- Xstruct exceptiontab {
- X char *exception;
- X jmp_buf jbuf;
- X} exceptions[MAXEXCEPTIONS];
- Xint topexception = 0; /* Next useable slot */
- X
- Xint *
- Xcool_pushexception(exception)
- Xchar *exception;
- X{
- X int e;
- X int * ret;
- X
- X if (topexception == MAXEXCEPTIONS)
- X cool_raise("TooManyExceptions", NULL);
- X e = topexception++;
- X exceptions[e].exception = exception; /* No need to dup */
- X/*
- X ret = exceptions[e].jbuf;
- X return ret;
- X*/
- X return exceptions[e].jbuf;
- X}
- X
- X/*
- X * Collapse exception table down to entry containing the given jump buffer.
- X */
- Xvoid
- Xcool_popexception(jbuf)
- Xjmp_buf *jbuf;
- X{
- X struct exceptiontab *ex;
- X
- X ex = (struct exceptiontab *) jbuf;
- X topexception = ex - exceptions;
- X}
- X
- Xvoid
- Xcool_raise(exception, fmt, va_alist)
- Xchar *exception, *fmt;
- Xva_dcl
- X{
- X int e;
- X va_list args;
- X
- X for(e = topexception - 1; e >= 0; e--)
- X if (cool_streq(exceptions[e].exception, exception))
- X break;
- X
- X if (e == -1) {
- X fflush(stdout);
- X fprintf(stderr, "COOL Exception: '%s': ", exception);
- X va_start(args);
- X /* NULL or "" */
- X if (fmt && fmt[0])
- X vfprintf(stderr, fmt, args);
- X va_end(args);
- X fprintf(stderr, "\n", exception);
- X abort();
- X }
- X
- X longjmp(exceptions[e].jbuf, 1);
- X}
- X
- X
- SHAR_EOF
- chmod 0644 exception.c ||
- echo 'restore of exception.c failed'
- Wc_c="`wc -c < 'exception.c'`"
- test 1895 -eq "$Wc_c" ||
- echo 'exception.c: original size 1895, current size' "$Wc_c"
- fi
- # ============= util.c ==============
- if test -f 'util.c' -a X"$1" != X"-c"; then
- echo 'x - skipping util.c (File already exists)'
- else
- echo 'x - extracting util.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'util.c' &&
- X/*
- X * COOL: C Object-Oriented Library
- X *
- X * COOL utilities. Malloc/free/realloc, strings.
- X *
- X * Copyright 1991 by Lance Norskog
- X *
- X * Permission to use, copy, modify, and distribute this software and its
- X * documentation for any purpose and without fee is hereby granted, provided
- X * that the above copyright notice appear in all copies and that both that
- X * copyright notice and this permission notice appear in supporting
- X * documentation. This software is provided "as is" without express or
- X * implied warranty.
- X */
- X
- X#include <stdio.h> /* for NULL */
- X#include <setjmp.h> /* for NULL */
- X#include "cool.h"
- X#include "coolint.h"
- X
- X/* Feb 15 92: write own static malloc to find malloc bugs */
- X
- X/*
- Xextern char *malloc(), *realloc();
- Xextern void free();
- X*/
- X
- Xchar malloc_space[512 * 1024];
- Xstatic char *newspace = malloc_space;
- X
- Xchar *
- Xcool_malloc(size)
- Xint size;
- X{
- X char *newptr;
- X
- X/*
- X if (! space)
- X newspace = space = malloc(1024 * 1024);
- X if (space == 0)
- X cool_raise("NoMoreMemory", NULL);
- X*/
- X/*
- X size += size/2;
- X size += 0x3 & (~size);
- X*/
- X size = (size + 3) & ~3;
- X newptr = newspace;
- X newspace += size;
- X if (newptr > &malloc_space[ 512 * 1024 ])
- X cool_raise("NoMoreMemory", NULL);
- X#ifdef DEBUG
- X /* add to list */
- X#endif
- X bzero(newptr, size);
- X return newptr;
- X}
- X
- Xvoid
- Xcool_free(ptr)
- Xchar *ptr;
- X{
- X#ifdef DEBUG
- X /* check list and remove */
- X#endif
- X /* free(ptr); */
- X}
- X
- Xchar *
- Xcool_realloc(ptr, size)
- Xchar *ptr;
- Xint size;
- X{
- X char *newptr = cool_malloc(size);
- X
- X#ifdef DEBUG
- X /* check list and update if necessary */
- X#endif
- X bcopy(ptr, newptr, size);
- X return newptr;
- X}
- X
- X/* String processing stuff */
- X
- X/*
- X * Duplicate an argument string for internal use.
- X * Should be a string table or something.
- X * Tough.
- X */
- Xchar *
- Xcool_strdup(str)
- Xchar *str;
- X{
- X char *ret = cool_malloc(strlen(str) + 1);
- X
- X strcpy(ret, str);
- X return ret;
- X}
- X
- X/*
- X * Free an internal duplicate string.
- X */
- Xvoid
- Xcool_strfree(str)
- Xchar *str;
- X{
- X cool_free(str);
- X}
- X
- X/*
- X * Compare two strings
- X */
- Xint
- Xcool_streq(s1, s2)
- Xchar *s1, *s2;
- X{
- X return s1 && s2 && ! strcmp(s1, s2);
- X}
- X
- X/*
- X * Squish spaces out of an argument list
- X */
- Xcool_squish(from, to)
- Xchar *from, *to;
- X{
- X while(*from) {
- X if ((*from != ' ') && (*from != '\t'))
- X *to++ = *from++;
- X else
- X from++;
- X }
- X *to = '\0';
- X}
- X
- X/*
- X * Generate unique gibberish string
- X */
- Xchar *
- Xcool_makename() {
- X static counter = 1234;
- X char buf[30];
- X
- X sprintf(buf, "ZZZ%d", counter++);
- X return cool_strdup(buf);
- X}
- X
- X/*
- X * Count number of arguments in argument string
- X */
- X/*
- X * What?
- X
- Xint
- Xcool_countargs(args)
- Xchar *args;
- X{
- X}
- X*/
- X
- X
- X
- X
- X
- X
- X
- X
- SHAR_EOF
- chmod 0644 util.c ||
- echo 'restore of util.c failed'
- Wc_c="`wc -c < 'util.c'`"
- test 2536 -eq "$Wc_c" ||
- echo 'util.c: original size 2536, current size' "$Wc_c"
- fi
- # ============= cool.h ==============
- if test -f 'cool.h' -a X"$1" != X"-c"; then
- echo 'x - skipping cool.h (File already exists)'
- else
- echo 'x - extracting cool.h (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'cool.h' &&
- X
- X/*
- X * COOL: C Object-Oriented Library
- X *
- X * Public header file
- X *
- X * Copyright 1991 by Lance Norskog
- X *
- X * Permission to use, copy, modify, and distribute this software and its
- X * documentation for any purpose and without fee is hereby granted, provided
- X * that the above copyright notice appear in all copies and that both that
- X * copyright notice and this permission notice appear in supporting
- X * documentation. This software is provided "as is" without express or
- X * implied warranty.
- X */
- X
- Xtypedef unsigned long object_t, method_t, ret_t;
- Xvoid cool_init();
- Xret_t cool_msg(/* object_t, method_t, [ args ] */);
- X
- X /* Handy type-caster */
- X#define cool(type, msg) ((type) cool_msg msg)
- X
- Xobject_t cool_object(/* object_t ob */);
- Xmethod_t cool_method(/* object_t ob, method_t m */);
- X
- Xvoid cool_raise(/* char *exception, *fmt, [ *args] */ );
- X/* Handy define for fmt/args portion */
- X#define CODEMARK "File %s, line %d", __FILE__, __LINE__
- X
- X#define cool_exception(exception, code, handler) \
- X { \
- X int * cool_jmp; \
- X cool_jmp = cool_pushexception(exception); \
- X if (setjmp(cool_jmp)) { \
- X cool_popexception(cool_jmp); \
- X handler \
- X } else { \
- X code \
- X cool_popexception(cool_jmp); \
- X } \
- X }
- X
- Xint *cool_pushexception(/* char *exception */);
- Xvoid cool_popexception(/* jmp_buf * */);
- Xchar * cool_nameof(/* object_t */);
- Xobject_t cool_classof(/* object_t */);
- Xobject_t cool_componentof(/* object_t, char * */);
- X/* later */
- X
- X/*
- X * This data structure is always the first part of the secret data of
- X * an object. It is, however, before the pointer a method handler receives.
- X */
- Xtypedef struct cool_priv {
- X object_t self; /* Inheritance: This object */
- X object_t class; /* Inheritance: Class of this object */
- X} cool_priv_t;
- X
- X#define SELFOF(priv) ((cool_priv_t *) priv)[-1].self
- X#define CLASSOF(priv) ((cool_priv_t *) priv)[-1].class
- X
- X#ifdef USG
- X#define index(s, c) (strchr(s, c))
- X#define rindex(s, c) (strrchr(s, c))
- X#endif
- SHAR_EOF
- chmod 0644 cool.h ||
- echo 'restore of cool.h failed'
- Wc_c="`wc -c < 'cool.h'`"
- test 1945 -eq "$Wc_c" ||
- echo 'cool.h: original size 1945, current size' "$Wc_c"
- fi
- true || echo 'restore of coolint.h failed'
- echo End of part 2, continue with part 3
- exit 0
- --
-
- Lance Norskog
-
- Data is not information is not knowledge is not wisdom.
-