diff --git a/pd/src/g_canvas.c b/pd/src/g_canvas.c index a44bc6567720deb809624bda5deea25676493845..523ec2b843bc786b342c0b783599978e4e8504dd 100644 --- a/pd/src/g_canvas.c +++ b/pd/src/g_canvas.c @@ -1716,7 +1716,7 @@ char * canvas_path_replace( { // allocate memory for the new string size_t const retlen = orilen + patcnt * (replen - patlen); - char * const returned = (char *) malloc( sizeof(char) * (retlen + 1) ); + char * returned = (char *) malloc( sizeof(char) * (retlen + 1) ); if (returned != NULL) { @@ -1741,6 +1741,23 @@ char * canvas_path_replace( } +char * canvas_parse_sys_filename_args(const char *name) +{ + //check for @sys_extra path and replace + char *final_name = NULL; + if (strstr(name, "@pd_extra") != NULL) { + t_namelist *path = pd_extrapath; + while (path->nl_next) + path = path->nl_next; + final_name = canvas_path_replace(name, "@pd_extra", path->nl_string); + } + else { + final_name = (char *) malloc( sizeof(char) * (strlen(name) + 1) ); + strcpy(final_name, name); + } + return(final_name); +} + /* utility function to read a file, looking first down the canvas's search path (set with "declare" objects in the patch and recursively in calling patches), then down the system one. The filename is the concatenation of @@ -1759,19 +1776,12 @@ int canvas_open(t_canvas *x, const char *name, const char *ext, { t_namelist *nl, thislist; int fd = -1; + int result = 0; t_canvas *y; - const char *final_name; + char *final_name; - //check for @sys_extra path and replace - if (strstr(name, "@pd_extra") != NULL) { - t_namelist *path = pd_extrapath; - while (path->nl_next) - path = path->nl_next; - final_name = canvas_path_replace(name, "@pd_extra", path->nl_string); - } - else { - final_name = name; - } + //check for sys path and replace + final_name = canvas_parse_sys_filename_args(name); /* first check if "name" is absolute (and if so, try to open) */ if (sys_open_absolute(final_name, ext, dirresult, nameresult, size, bin, &fd)) @@ -1808,8 +1818,9 @@ int canvas_open(t_canvas *x, const char *name, const char *ext, return (fd); } } - return (open_via_path((x ? canvas_getdir(x)->s_name : "."), final_name, ext, - dirresult, nameresult, size, bin)); + result = open_via_path((x ? canvas_getdir(x)->s_name : "."), final_name, ext, dirresult, nameresult, size, bin); + freebytes((void *)final_name, strlen(final_name)); + return(result); } void canvasgop_draw_move(t_canvas *x, int doit) diff --git a/pd/src/g_canvas.h b/pd/src/g_canvas.h index 66643201e1ced137946f97a2f703fc6772398db0..b4e01a937a79b1471058febbb390a16eb050076e 100644 --- a/pd/src/g_canvas.h +++ b/pd/src/g_canvas.h @@ -548,6 +548,10 @@ EXTERN int canvas_hitbox(t_canvas *x, t_gobj *y, int xpos, int ypos, int *x1p, int *y1p, int *x2p, int *y2p); EXTERN int canvas_setdeleting(t_canvas *x, int flag); +/* ---- for parsing @pd_extra and other sys paths in filenames --------------------- */ + +EXTERN char * canvas_parse_sys_filename_args(const char *name); + typedef void (*t_undofn)(t_canvas *canvas, void *buf, int action); /* a function that does UNDO/REDO */ #define UNDO_FREE 0 /* free current undo/redo buffer */ diff --git a/pd/src/s_path.c b/pd/src/s_path.c index 0025096543f2a56e33718c14fa4e22d98e685d40..131c4ab70500cf6d92655afab5d29bd3be85843f 100644 --- a/pd/src/s_path.c +++ b/pd/src/s_path.c @@ -344,6 +344,8 @@ there is no search and instead we just try to open the file literally. */ /* see also canvas_open() which, in addition, searches down the canvas-specific path. */ +EXTERN const char * canvas_parse_sys_filename_args(const char *name); + static int do_open_via_path(const char *dir, const char *name, const char *ext, char *dirresult, char **nameresult, unsigned int size, int bin, t_namelist *searchpath) @@ -351,31 +353,38 @@ static int do_open_via_path(const char *dir, const char *name, t_namelist *nl; int fd = -1; + //check for sys path and replace + const char *final_name = canvas_parse_sys_filename_args(name); + /* first check if "name" is absolute (and if so, try to open) */ - if (sys_open_absolute(name, ext, dirresult, nameresult, size, bin, &fd)) - return (fd); + if (sys_open_absolute(final_name, ext, dirresult, nameresult, size, bin, &fd)) + goto do_open_via_path_end; /* otherwise "name" is relative; try the directory "dir" first. */ - if ((fd = sys_trytoopenone(dir, name, ext, + if ((fd = sys_trytoopenone(dir, final_name, ext, dirresult, nameresult, size, bin)) >= 0) - return (fd); + goto do_open_via_path_end; /* next go through the search path */ for (nl = searchpath; nl; nl = nl->nl_next) - if ((fd = sys_trytoopenone(nl->nl_string, name, ext, + if ((fd = sys_trytoopenone(nl->nl_string, final_name, ext, dirresult, nameresult, size, bin)) >= 0) - return (fd); + goto do_open_via_path_end; /* next look in built-in paths like "extra" */ if (sys_usestdpath) for (nl = pd_extrapath; nl; nl = nl->nl_next) - if ((fd = sys_trytoopenone(nl->nl_string, name, ext, + if ((fd = sys_trytoopenone(nl->nl_string, final_name, ext, dirresult, nameresult, size, bin)) >= 0) - return (fd); + goto do_open_via_path_end; *dirresult = 0; *nameresult = dirresult; + freebytes((void *)final_name, strlen(final_name)); return (-1); +do_open_via_path_end: + freebytes((void *)final_name, strlen(final_name)); + return (fd); } /* open via path, using the global search path. */