On 2016-04-25 03:41, Miller Puckette wrote:
> I think this is one for Iohannes...

indeed.
thanks for the report.

> 
> I can't seem to load abstractions by typing the full pathname anymore...
> e.g. [/tmp/output~] fails, even if /tmp/output~.pd exists.  I get
> 
> maximum object loading depth 1000 reached
>  /tmp/output~
> ... couldn't create
> 
> I tried fixing s_path.c to make it load but couldn't figure out what was
> going on.

attached you find a patch that fixes the issue with hopefully plenty of
explanation in the commit (and another issue related to the
double-loading-prevention).

fmgasdr
IOhannes
From 391e428b2f3179fbb8ec2fd6310ca84138055d87 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?IOhannes=20m=20zm=C3=B6lnig?= <[email protected]>
Date: Mon, 25 Apr 2016 13:58:25 +0200
Subject: [PATCH 1/2] fixed loading of abstractions via absolute filename

class_new() uses some magic to *also* register the "long" path
(if that was given to instantiate the object), but class_addcreator()
lacked this.
The easiest way to get this behaviour for abstractions, is to use class_new()
as well.
however, this generates a new class for each abstraction (name), which we
will never use. to prevent a glaring memleak, we keep track of all those
classpointers via a linked list.
---
 src/s_loader.c | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/src/s_loader.c b/src/s_loader.c
index 4e3f2b2..daff03b 100644
--- a/src/s_loader.c
+++ b/src/s_loader.c
@@ -449,15 +449,17 @@ static t_pd *do_create_abstraction(t_symbol*s, int argc, t_atom *argv)
     return (0);
 }
 
-/* search for abstraction; register a loader if found */
+/* search for abstraction; register a creator if found */
 static int sys_do_load_abs(t_canvas *canvas, const char *objectname,
     const char *path)
 {
     int fd;
+    static t_gobj*abstraction_classes = 0;
     char dirbuf[MAXPDSTRING], classslashclass[MAXPDSTRING], *nameptr;
         /* NULL-path is only used as a last resort,
            but we have already tried all paths */
     if (!path) return (0);
+
     snprintf(classslashclass, MAXPDSTRING, "%s/%s", objectname, objectname);
     if ((fd = sys_trytoopenone(path, objectname, ".pd",
               dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0 ||
@@ -466,9 +468,23 @@ static int sys_do_load_abs(t_canvas *canvas, const char *objectname,
         (fd = sys_trytoopenone(path, classslashclass, ".pd",
               dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0)
     {
+        t_class*c=0;
         close(fd);
-        class_addcreator((t_newmethod)do_create_abstraction,
-            gensym(objectname), A_GIMME, 0);
+            /* found an abstraction, now register it as a new pseudo-class */
+        class_set_extern_dir(gensym(dirbuf));
+        if((c=class_new(gensym(objectname),
+                        (t_newmethod)do_create_abstraction, 0,
+                        0, 0, A_GIMME, 0)))
+        {
+                /* store away the newly created class, maybe we will need it one day */
+            t_gobj*absclass=0;
+            absclass=t_getbytes(sizeof(*absclass));
+            absclass->g_pd=c;
+            absclass->g_next=abstraction_classes;
+            abstraction_classes=absclass;
+        }
+        class_set_extern_dir(&s_);
+
         return (1);
     }
     return (0);
-- 
2.8.1

From 77f0f1c12b1868e3f97516f57440c1748b4af3a1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?IOhannes=20m=20zm=C3=B6lnig?= <[email protected]>
Date: Mon, 25 Apr 2016 14:42:20 +0200
Subject: [PATCH 2/2] centrally prevent double loading of fully qualified
 classnames.

rather than duplicating the sys_putonloadlist()/sys_onloadlist() code
in each loader, we just do it once.

we also do it in a place, where we actually know the full objectname as
given by the user (e.g. "/foo/bar") rather than as a split-up pair of
path ("/foo/") and a classname ("bar").
this allows will prevent double loading of "/tmp/foo" and "/tmp/foo",
while at the same time allowing us to load both "/foo/pizza" and "/baz/pizza".

afaict, this only gets triggered when loading *directly* (via [declare])
---
 src/s_loader.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/src/s_loader.c b/src/s_loader.c
index daff03b..55aa56e 100644
--- a/src/s_loader.c
+++ b/src/s_loader.c
@@ -113,11 +113,6 @@ static int sys_do_load_lib(t_canvas *canvas, const char *objectname,
     if ((classname = strrchr(objectname, '/')))
         classname++;
     else classname = objectname;
-    if (sys_onloadlist(objectname))
-    {
-        verbose(1, "%s: already loaded", objectname);
-        return (1);
-    }
     for (i = 0, cnameptr = classname; i < MAXPDSTRING-7 && *cnameptr;
         cnameptr++)
     {
@@ -250,7 +245,6 @@ gotone:
     }
     (*makeout)();
     class_set_extern_dir(&s_);
-    sys_putonloadlist(objectname);
     return (1);
 }
 
@@ -313,6 +307,12 @@ int sys_load_lib(t_canvas *canvas, const char *classname)
     struct _loadlib_data data;
     data.canvas = canvas;
     data.ok = 0;
+
+    if (sys_onloadlist(classname))
+    {
+        verbose(1, "%s: already loaded", classname);
+        return (1);
+    }
         /* if classname is absolute, try this first */
     if (sys_isabsolutepath(classname))
     {
@@ -340,6 +340,10 @@ int sys_load_lib(t_canvas *canvas, const char *classname)
     if (!data.ok)
         sys_loadlib_iter(0, &data);
 
+    if(data.ok)
+      sys_putonloadlist(classname);
+
+
     canvas_resume_dsp(dspstate);
     return data.ok;
 }
-- 
2.8.1

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
Pd-dev mailing list
[email protected]
https://lists.puredata.info/listinfo/pd-dev

Reply via email to