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
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Pd-dev mailing list [email protected] https://lists.puredata.info/listinfo/pd-dev
