home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #31 / NN_1992_31.iso / spool / alt / sources / 2891 < prev    next >
Encoding:
Text File  |  1992-12-28  |  9.0 KB  |  436 lines

  1. Newsgroups: alt.sources
  2. Path: sparky!uunet!wupost!csus.edu!netcom.com!thinman
  3. From: thinman@netcom.com (Technically Sweet)
  4. Subject: Re: COOL: C Object-Oriented Library: part 0 of 4
  5. Message-ID: <1992Dec28.195232.22423@netcom.com>
  6. Organization: International Foundation for Internal Freedom
  7. References: <1992Dec23.191426.10202@netcom.com> <1992Dec28.191137.13827@netcom.com>
  8. Date: Mon, 28 Dec 1992 19:52:32 GMT
  9. Lines: 425
  10.  
  11. OK, here's the fix:  substitute this lookup.c for the one in the
  12. shars.  The tests now run to completion on a Sparc.
  13.  
  14. ---------------- lookup.c ------------ snippy snippy ------------
  15.  
  16. /*
  17.  *    COOL: C Object-Oriented Library
  18.  *
  19.  *    Object and method string lookups
  20.  *
  21.  *     Copyright 1991 by Lance Norskog
  22.  *
  23.  *      June 1992: implement overloaded methods
  24.  *    Dec. 1992: fix bugs in overloaded methods
  25.  *
  26.  * Permission to use, copy, modify, and distribute this software and its
  27.  * documentation for any purpose and without fee is hereby granted, provided
  28.  * that the above copyright notice appear in all copies and that both that
  29.  * copyright notice and this permission notice appear in supporting
  30.  * documentation.  This software is provided "as is" without express or
  31.  * implied warranty.
  32.  */
  33.  
  34. #include <stdio.h>
  35. #include <setjmp.h>
  36. #ifdef    USG
  37. #include <string.h>
  38. #else
  39. #include <strings.h>
  40. #endif
  41. #include "cool.h"
  42. #include "coolint.h"
  43.  
  44. /* 
  45.  * Look up an object in the object table.
  46.  * Return error if not found.
  47.  * 
  48.  * Internal use only!
  49.  */
  50.  
  51.  
  52. object_t
  53. cool_getobject(object)
  54. object_t object;
  55. {
  56.     cint     i;
  57.  
  58.     if (ISOBJECT(object))
  59.         if (GOODGEN(object))
  60.             return object;
  61.         else    cool_raise("BadGeneration", CODEMARK);
  62.     else  {
  63.  
  64.         /* yeah yeah yeah.  This should use ob_next for a live list. */
  65.         for(i = 0; i < MAXOBJECTS; i++)
  66.             if (cool_objtab[i].ob_name && 
  67.                 cool_streq(cool_objtab[i].ob_name, 
  68.                         (char *) object))
  69.                     break;
  70.         if (i == MAXOBJECTS)
  71.             return OBJECTERR;
  72.         return (object_t) MKOBJECT(i, cool_objtab[i].ob_generation);
  73.     } 
  74. }
  75.  
  76. /* 
  77.  * Look up an object in the object table.
  78.  * Raise exception if not found.
  79.  */
  80.  
  81. object_t
  82. cool_object(object)
  83. object_t object;
  84. {
  85.     object_t obj;
  86.  
  87.     obj = cool_getobject(object);
  88.     if (obj == OBJECTERR)
  89.         cool_raise("ObjectDoesNotExist", object);
  90.     return obj;
  91. }
  92.  
  93. int
  94. cool_isobject(object)
  95. object_t object;
  96. {
  97.     object_t obj;
  98.  
  99.     obj = cool_getobject(object);
  100.     return (obj != OBJECTERR);
  101. }
  102.  
  103. /*
  104.  * Get a text name of an object.
  105.  */
  106.  
  107. char *
  108. cool_nameof(object)
  109. object_t object;
  110. {
  111.     object_t obj;
  112.  
  113.     obj = cool_getobject(object);
  114.     if (obj == OBJECTERR)
  115.         cool_raise("ObjectDoesNotExist", object);
  116.     return cool_objtab[OBJECTOF(obj)].ob_name;
  117. }
  118.  
  119. /*
  120.  * Get a class object of an object.
  121.  */
  122.  
  123. object_t
  124. cool_classof(object)
  125. object_t object;
  126. {
  127.     object_t ob;
  128.     objtab_t *obj;
  129.     int    o, p;
  130.  
  131.     ob = cool_getobject(object);
  132.     if (ob == OBJECTERR)
  133.         cool_raise("ObjectDoesNotExist", object);
  134.     obj = &cool_objtab[OBJECTOF(ob)];
  135.     return cool_objtab[OBJECTOF(ob)].ob_private[MYMETHODS]->class;
  136. }
  137.  
  138. /*
  139.  * Get a component object of an object.
  140.  */
  141.  
  142. object_t
  143. cool_componentof(object, name)
  144. object_t object;
  145. char *name;
  146. {
  147.     char *obname, fullname[128];
  148.     object_t compob;
  149.  
  150.     obname = cool_nameof(object);
  151.     sprintf(fullname, "%s.%s", obname, name);
  152.     compob = cool_getobject((object_t) fullname);
  153.     if (compob == OBJECTERR)
  154.         cool_raise("ComponentDoesNotExist", fullname);
  155.     return compob;
  156. }
  157.  
  158. /* 
  159.  * Look up a method in a particular method table.
  160.  * Internal use only!
  161.  */
  162.  
  163. method_t
  164. cool_getmethod(meth, mt)
  165. method_t    meth;
  166. methtab_t    *mt;
  167. {
  168.     cint     i, m, match;
  169.     sint    matches;
  170.  
  171.     if (ISMETHOD(meth))
  172.         return meth;
  173.     if (mt == NULL) 
  174.         return METHODERR;
  175.  
  176.     for(matches = match = m = 0; m < MAXMETHODS; m++, mt++)
  177.         if (mt->m_name && metheq(mt, (char *) meth)) {
  178.             match = m;
  179.             matches++;
  180.         }
  181. /* hack! make C keep working the old way for "Create"
  182.     if (matches == 1)
  183.         return (method_t) match;
  184. */
  185.             
  186.     /* return last match */
  187.     return (matches == 0) ? METHODERR : (method_t) match;
  188. }
  189.  
  190. /* walk methods - each time return next method with same name */
  191. method_t
  192. cool_walkmethods(object, name, mp, retp, nargsp, argsp)
  193. object_t    object;
  194. char        *name;
  195. method_t    *mp;
  196. char        **retp;
  197. int        *nargsp;
  198. char        ***argsp;
  199. {
  200.     object_t ob;
  201.     objtab_t *obj;
  202.     method_t meth;
  203.     methtab_t *mt;
  204.     int    m, p;
  205.  
  206.     ob = cool_getobject(object);
  207.     if (ob == OBJECTERR)
  208.         cool_raise("ObjectDoesNotExist", object);
  209.     obj = &cool_objtab[OBJECTOF(ob)];
  210.  
  211.     if (*mp == (method_t) -1) {
  212.         m = 0;
  213.         p = MYMETHODS;
  214.     } else {
  215.         /* Search starting after given parent/method */
  216.         m = METHODOF(*mp);
  217.         p = PARENTOF(*mp);
  218.         if (++m == MAXMETHODS) {
  219.             p--;
  220.             m = 0;
  221.         }
  222.     }
  223.     for(; p >= 0; p--, m = 0) {
  224.         if (! (mt = obj->ob_methtab[p]))
  225.             continue;
  226.         mt = &mt[m];
  227.  
  228.         for(; m < MAXMETHODS; m++, mt++)
  229.             if (cool_streq(mt->m_name, name)) {
  230.                 *mp = MKMETHOD(p, m);
  231.                 *retp = mt->m_rettype;
  232.                 *argsp = mt->m_argtypes;
  233.                 *nargsp = mt->m_nargs;
  234.                 return 1;
  235.             }
  236.     }
  237.  
  238.     /* no more of this name */
  239.     return 0;
  240. }
  241.  
  242. method_t
  243. cool_method(object, method)
  244. object_t    object;
  245. method_t    method;
  246. {
  247.     object_t ob;
  248.     objtab_t *obj;
  249.     method_t meth;
  250.     methtab_t *mt;
  251.     int    p;
  252.  
  253.     ob = cool_getobject(object);
  254.     if (ob == OBJECTERR)
  255.         cool_raise("ObjectDoesNotExist", object);
  256.     obj = &cool_objtab[OBJECTOF(ob)];
  257.     /* Search object's methods, then parents' methods */
  258.     for(p = MYMETHODS; p >= 0; p--) {
  259.         if (mt = obj->ob_methtab[p])
  260.             if ((meth = cool_getmethod(method, mt)) != METHODERR)
  261.             return MKMETHOD(p, meth);
  262.     }
  263.     cool_raise("MethodDoesNotExist", method);
  264. }
  265.  
  266.  
  267. int
  268. cool_hasmethod(object, method)
  269. object_t    object;
  270. method_t    method;
  271. {
  272.  
  273.     object_t ob;
  274.     objtab_t *obj;
  275.     method_t meth;
  276.     methtab_t *mt;
  277.     int    p;
  278.  
  279.     ob = cool_getobject(object);
  280.     if (ob == OBJECTERR)
  281.         cool_raise("ObjectDoesNotExist", object);
  282.     obj = &cool_objtab[OBJECTOF(ob)];
  283.     /* Search object's methods, then parents' methods */
  284.     for(p = MYMETHODS; p >= 0; p--) {
  285.         if (mt = obj->ob_methtab[p])
  286.             if ((meth = cool_getmethod(method, mt)) != METHODERR)
  287.             return 1;
  288.     }
  289.     return 0;
  290. }
  291.  
  292. static unsigned long argval[9];
  293. static char scmtype[9];
  294. static char cooltype[9];
  295. static char **ctype;
  296.  
  297. /* table of names corresponding to argument types */
  298. char *ctypenames[] = {
  299.     0,
  300.     "",            /* end of argument list */
  301.     "integer",
  302.     "bool",
  303.     "char",
  304.     "string",
  305.     "object",
  306.     "msg",
  307.     "double",
  308.     "ivect",        /* vector of integers */
  309.     "dvect",        /* vector of doubles */
  310.     "*",            /* anything */
  311. /* VR add-ons */
  312.     "point",        /* 3 or 4 doubles */
  313.     "homog",        /* homogeneous doubles matrix (4x4) */
  314.     (char *) 0
  315. };
  316.  
  317. /* digest an argument list.  Return number of arguments found, -1 if no list */
  318. int
  319. methdigest(mt, s)
  320. methtab_t *mt;
  321. char *s;
  322. {
  323.     int i, j;
  324.     char *rt, *at;
  325.  
  326.     mt->m_name = s;
  327.  
  328.     /* add optional return type and arg type list */
  329.     /* chop up copy of full string into words, add to list */
  330.     /* syntax: method[=[return]][:[argtype[,argtype]*]]  */
  331.     /* XXX doesn't catch case where same arg list and different return */
  332.     mt->m_rettype = (char *) 0;
  333.     for(i = 0; i < MAXARGS; i++)
  334.         mt->m_argtypes[i] = (char *) 0;
  335.     rt = index(mt->m_name, '=');
  336.     at = index(mt->m_name, ':');
  337.     if (rt && at && (rt > at) || index(mt->m_name, ' '))
  338.         cool_raise("MethodTypeSyntax", NULL);
  339.     if (at)
  340.         *at++ = '\0';
  341.     if (rt) {
  342.         *rt++ = '\0';
  343.         mt->m_rettype = rt;
  344.         /* parse out argument type */
  345.         for(j = 1; ctypenames[j]; j++)
  346.             if (cool_streq(rt, ctypenames[j]))
  347.                 mt->m_rettype = (char *) j;
  348.         if (mt->m_rettype == CANY)
  349.             cool_raise("MethodReturns*", NULL);
  350.     }
  351.     if (at) {
  352.         if (index(at, ':') || index(at, '='))
  353.             cool_raise("MethodTypeSyntax", NULL);
  354.         mt->m_argtypes[0] = at;
  355.         for(i = 1; at = index(at, ','); i++) {
  356.             *at++ = '\0';
  357.             mt->m_argtypes[i] = at;
  358.         }
  359.         for(i = 0; mt->m_argtypes[i]; i++) {
  360.             /* parse out argument type */
  361.             for(j = 1; ctypenames[j]; j++)
  362.                 if (cool_streq(mt->m_argtypes[i],ctypenames[j])) {
  363.                 mt->m_argtypes[i] = (char *) j;
  364.                 break;
  365.                 }
  366.         }
  367.         /* name: no arguments.  VOID is valid return but not arg. */
  368.         if (mt->m_argtypes[0] == CVOID) {
  369.             mt->m_argtypes[0] = 0;
  370.             return 0;
  371.         } else
  372.             return i;
  373.     }
  374.     return -1;
  375. }
  376.  
  377. metheq(mt, s)
  378. methtab_t *mt;
  379. char *s;
  380. {
  381.     int i, nargs;
  382.     methtab_t tmp;
  383.     char strbuf[256];
  384.  
  385.     strcpy(strbuf, s);
  386.     tmp.m_nargs = methdigest(&tmp, strbuf);
  387.  
  388.     if (! cool_streq(mt->m_name, tmp.m_name))
  389.         return 0;
  390.     if (mt->m_rettype && tmp.m_rettype && 
  391.             (mt->m_rettype != tmp.m_rettype))
  392.         return 0;
  393.     /* if argument list specified, it must match given method */
  394.     if ((tmp.m_nargs >= 0) && (mt->m_nargs != tmp.m_nargs))
  395.         return 0;
  396.     if (mt->m_argtypes[0] && tmp.m_argtypes[0])
  397.         if (mt->m_argtypes[0] != tmp.m_argtypes[0])
  398.             return 0;
  399.     for(i = 1; i < MAXARGS && (mt->m_argtypes[i] || tmp.m_argtypes[i]);i++)
  400.         if (mt->m_argtypes[i] != tmp.m_argtypes[i])
  401.             return 0;
  402.     return 1;
  403. }
  404.  
  405. /* junk */
  406.  
  407. #ifdef    JUNK
  408. metheq(s1, s2)
  409. char *s1, *s2;
  410. {
  411.     for(; *s1 || *s2; s1++, s2++) {
  412.         if (*s1 == *s2)
  413.             continue;
  414.         /* if one ends and other doesn't */
  415.         if  ((*s1 == '=' || *s1 == ':' || *s1 == ',') && !*s2)
  416.             return 1;
  417.         if  ((*s2 == '=' || *s2 == ':' || *s2 == ',') && !*s1)
  418.             return 1;
  419.         /* skip optional return type if arglist */
  420.         if  (*s1 == '=' && *s2 == ':')
  421.             while(*s1 != ':' && *s1)
  422.                 s1++;
  423.         if  (*s2 == '=' && *s1 == ':')
  424.             while(*s2 != ':' && *s2)
  425.                 s2++;
  426.     }
  427.     return *s1 == *s2;
  428. }
  429. #endif
  430.  
  431. -- 
  432.  
  433. Lance Norskog
  434.  
  435. Data is not information is not knowledge is not wisdom.
  436.