]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
added findmethodinchain and methodchain data types
authorGuido van Rossum <guido@python.org>
Thu, 26 Jan 1995 22:58:48 +0000 (22:58 +0000)
committerGuido van Rossum <guido@python.org>
Thu, 26 Jan 1995 22:58:48 +0000 (22:58 +0000)
Include/methodobject.h
Include/rename2.h
Objects/methodobject.c

index 1b2dd87fa31a4a94cee522c3d662ea17275d58af..946d004bd5fa40c3367b5783f9aeced0aa2ac7fa 100644 (file)
@@ -57,6 +57,14 @@ extern PyObject *PyCFunction_New
 /* Flag passed to newmethodobject */
 #define METH_VARARGS  0x0001
 
+typedef struct PyMethodChain {
+       PyMethodDef *methods;           /* Methods of this type */
+       struct PyMethodChain *link;     /* NULL or base type */
+} PyMethodChain;
+
+extern PyObject *Py_FindMethodInChain
+       Py_PROTO((PyMethodChain *, PyObject *, char *));
+
 #ifdef __cplusplus
 }
 #endif
index e95534633f395f453157e1b65f888bf1882e6f13..e648a624409787c4d8f9dfcbd274a8f39c79e6af 100644 (file)
@@ -38,6 +38,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 /* typedef ANY *PyUnivPtr; */
 #define methodlist PyMethodDef
+#define methodchain PyMethodChain
 
 #define None Py_None
 #define False Py_False
@@ -290,6 +291,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #define newrangeobject PyRange_New
 #define method PyCFunction
 #define findmethod Py_FindMethod
+#define findmethodinchain Py_FindMethodInChain
 #define getmethod PyCFunction_GetFunction
 #define getself PyCFunction_GetSelf
 #define getvarargs PyCFunction_IsVarArgs
index 61420aaa2a06cdb9bdfabf8df41aef9359678746..d9daf2349d35ae50916eefc572c2e4b142ba4580 100644 (file)
@@ -188,46 +188,73 @@ typeobject Methodtype = {
        (hashfunc)meth_hash, /*tp_hash*/
 };
 
-static object *listmethods PROTO((struct methodlist *)); /* Forward */
+/* List all methods in a chain -- helper for findmethodinchain */
 
 static object *
-listmethods(ml)
-       struct methodlist *ml;
+listmethodchain(chain)
+       struct methodchain *chain;
 {
+       struct methodchain *c;
+       struct methodlist *ml;
        int i, n;
        object *v;
-       for (n = 0; ml[n].ml_name != NULL; n++)
-               ;
+       
+       n = 0;
+       for (c = chain; c != NULL; c = c->link) {
+               for (ml = c->methods; ml->ml_name != NULL; ml++)
+                       n++;
+       }
        v = newlistobject(n);
-       if (v != NULL) {
-               for (i = 0; i < n; i++)
-                       setlistitem(v, i, newstringobject(ml[i].ml_name));
-               if (err_occurred()) {
-                       DECREF(v);
-                       v = NULL;
-               }
-               else {
-                       sortlist(v);
+       if (v == NULL)
+               return NULL;
+       i = 0;
+       for (c = chain; c != NULL; c = c->link) {
+               for (ml = c->methods; ml->ml_name != NULL; ml++) {
+                       setlistitem(v, i, newstringobject(ml->ml_name));
+                       i++;
                }
        }
+       if (err_occurred()) {
+               DECREF(v);
+               return NULL;
+       }
+       sortlist(v);
        return v;
 }
 
-/* Find a method in a module's method table.
-   Usually called from an object's getattr method. */
+/* Find a method in a method chain */
 
 object *
-findmethod(ml, op, name)
-       struct methodlist *ml;
-       object *op;
+findmethodinchain(chain, self, name)
+       struct methodchain *chain;
+       object *self;
        char *name;
 {
        if (strcmp(name, "__methods__") == 0)
-               return listmethods(ml);
-       for (; ml->ml_name != NULL; ml++) {
-               if (strcmp(name, ml->ml_name) == 0)
-                       return newmethodobject(ml, op);
+               return listmethodchain(chain);
+       while (chain != NULL) {
+               struct methodlist *ml = chain->methods;
+               for (; ml->ml_name != NULL; ml++) {
+                       if (name[0] == ml->ml_name[0] &&
+                           strcmp(name+1, ml->ml_name+1) == 0)
+                               return newmethodobject(ml, self);
+               }
+               chain = chain->link;
        }
        err_setstr(AttributeError, name);
        return NULL;
 }
+
+/* Find a method in a single method list */
+
+object *
+findmethod(methods, self, name)
+       struct methodlist *methods;
+       object *self;
+       char *name;
+{
+       struct methodchain chain;
+       chain.methods = methods;
+       chain.link = NULL;
+       return findmethodinchain(&chain, self, name);
+}