[PD-dev] [PD] can't load abstractions using fuill pathname?
Miller Puckette
msp at ucsd.edu
Mon Apr 25 17:14:36 CEST 2016
Cool, that fixed it, thanks. Will read the notes when I wake up a bit more...
meanwhile will attempt to put out a test2 with several bug fixes in zooming
and the clone object.
cheers
Miller
On Mon, Apr 25, 2016 at 02:47:59PM +0200, IOhannes m zmoelnig wrote:
> 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?= <zmoelnig at iem.at>
> 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?= <zmoelnig at iem.at>
> 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
>
> _______________________________________________
> Pd-dev mailing list
> Pd-dev at lists.iem.at
> https://lists.puredata.info/listinfo/pd-dev
More information about the Pd-dev
mailing list