]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Name mangling, what the heck!
authorGuido van Rossum <guido@python.org>
Sat, 24 Aug 1996 06:21:31 +0000 (06:21 +0000)
committerGuido van Rossum <guido@python.org>
Sat, 24 Aug 1996 06:21:31 +0000 (06:21 +0000)
Python/compile.c

index b6e2dd8bf2ba5f4614eb42d679dcdd7661753fcd..0ecf69c721b8d892b7d376132f0f5dc9484d3804 100644 (file)
@@ -35,6 +35,10 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    XXX other JAR tricks?
 */
 
+#ifndef NO_PRIVATE_NAME_MANGLING
+#define PRIVATE_NAME_MANGLING
+#endif
+
 #include "allobjects.h"
 
 #include "node.h"
@@ -252,6 +256,9 @@ struct compiling {
        int c_nblocks;          /* current block stack level */
        char *c_filename;       /* filename of current node */
        char *c_name;           /* name of object (e.g. function) */
+#ifdef PRIVATE_NAME_MANGLING
+       char *c_private;        /* for private name mangling */
+#endif
 };
 
 
@@ -304,6 +311,8 @@ static void com_addopname PROTO((struct compiling *, int, node *));
 static void com_list PROTO((struct compiling *, node *, int));
 static int com_argdefs PROTO((struct compiling *, node *));
 static int com_newlocal PROTO((struct compiling *, char *));
+static codeobject *icompile PROTO((struct _node *, struct compiling *));
+static codeobject *jcompile PROTO((struct _node *, char *, struct compiling *));
 
 static int
 com_init(c, filename)
@@ -489,6 +498,41 @@ com_addname(c, v)
        return com_add(c, c->c_names, v);
 }
 
+#ifdef PRIVATE_NAME_MANGLING
+static int
+com_mangle(c, name, buffer, maxlen)
+       struct compiling *c;
+       char *name;
+       char *buffer;
+       int maxlen;
+{
+       /* Name mangling: __private becomes _classname_private.
+          This is independent from how the name is used. */
+       char *p;
+       int nlen, plen;
+       nlen = strlen(name);
+       if (nlen+1 >= maxlen)
+               return 0; /* Don't mangle __extremely_long_names */
+       if (name[nlen-1] == '_' && name[nlen-2] == '_')
+               return 0; /* Don't mangle __whatever__ */
+       p = c->c_private;
+       /* Strip leading underscores from class name */
+       while (*p == '_')
+               p++;
+       if (*p == '\0')
+               return 0; /* Don't mangle if class is just underscores */
+       plen = strlen(p);
+       if (plen + nlen >= maxlen)
+               plen = maxlen-nlen-1; /* Truncate class name if too long */
+       /* buffer = "_" + p[:plen] + name[1:] # i.e. plen+nlen bytes */
+       buffer[0] = '_';
+       strncpy(buffer+1, p, plen);
+       strcpy(buffer+plen+1, name+1);
+       /* fprintf(stderr, "mangle %s -> %s\n", name, buffer); */
+       return 1;
+}
+#endif
+
 static void
 com_addopnamestr(c, op, name)
        struct compiling *c;
@@ -497,6 +541,13 @@ com_addopnamestr(c, op, name)
 {
        object *v;
        int i;
+#ifdef PRIVATE_NAME_MANGLING
+       char buffer[256];
+       if (name != NULL && name[0] == '_' && name[1] == '_' &&
+           c->c_private != NULL &&
+           com_mangle(c, name, buffer, (int)sizeof(buffer)))
+               name = buffer;
+#endif
        if (name == NULL || (v = newstringobject(name)) == NULL) {
                c->c_errors++;
                i = 255;
@@ -1382,7 +1433,7 @@ com_test(c, n)
                object *v;
                int i;
                int ndefs = com_argdefs(c, CHILD(n, 0));
-               v = (object *) compile(CHILD(n, 0), c->c_filename);
+               v = (object *) icompile(CHILD(n, 0), c);
                if (v == NULL) {
                        c->c_errors++;
                        i = 255;
@@ -2285,7 +2336,7 @@ com_funcdef(c, n)
 {
        object *v;
        REQ(n, funcdef); /* funcdef: 'def' NAME parameters ':' suite */
-       v = (object *)compile(n, c->c_filename);
+       v = (object *)icompile(n, c);
        if (v == NULL)
                c->c_errors++;
        else {
@@ -2333,7 +2384,7 @@ com_classdef(c, n)
                com_addoparg(c, BUILD_TUPLE, 0);
        else
                com_bases(c, CHILD(n, 3));
-       v = (object *)compile(n, c->c_filename);
+       v = (object *)icompile(n, c);
        if (v == NULL)
                c->c_errors++;
        else {
@@ -2706,6 +2757,9 @@ compile_classdef(c, n)
        REQ(n, classdef);
        /* classdef: 'class' NAME ['(' testlist ')'] ':' suite */
        c->c_name = STR(CHILD(n, 1));
+#ifdef PRIVATE_NAME_MANGLING
+       c->c_private = c->c_name;
+#endif
        ch = CHILD(n, NCH(n)-1); /* The suite */
        doc = get_docstring(ch);
        if (doc != NULL) {
@@ -2877,11 +2931,34 @@ codeobject *
 compile(n, filename)
        node *n;
        char *filename;
+{
+       return jcompile(n, filename, NULL);
+}
+
+static codeobject *
+icompile(n, base)
+       node *n;
+       struct compiling *base;
+{
+       return jcompile(n, base->c_filename, base);
+}
+
+static codeobject *
+jcompile(n, filename, base)
+       node *n;
+       char *filename;
+       struct compiling *base;
 {
        struct compiling sc;
        codeobject *co;
        if (!com_init(&sc, filename))
                return NULL;
+#ifdef PRIVATE_NAME_MANGLING
+       if (base)
+               sc.c_private = base->c_private;
+       else
+               sc.c_private = NULL;
+#endif
        compile_node(&sc, n);
        com_done(&sc);
        if ((TYPE(n) == funcdef || TYPE(n) == lambdef) && sc.c_errors == 0) {