diff options
-rw-r--r-- | which/which-help.pd | 23 | ||||
-rw-r--r-- | which/which.c | 168 |
2 files changed, 191 insertions, 0 deletions
diff --git a/which/which-help.pd b/which/which-help.pd new file mode 100644 index 0000000..a1822be --- /dev/null +++ b/which/which-help.pd @@ -0,0 +1,23 @@ +#N canvas 540 295 569 267 10;
+#X obj 129 170 which tcpclient;
+#X obj 9 35 bng 15 250 50 0 empty empty output_path_to_object 17 7
+0 10 -4034 -257985 -1;
+#X text 9 7 [which] outputs the path to an object;
+#X obj 57 56 bng 15 250 50 0 empty empty set_object_name 17 7 0 10
+-4034 -257985 -1;
+#X msg 78 102 set tabdump;
+#X symbolatom 129 193 64 0 0 0 - - -;
+#X obj 57 81 symbol Gem;
+#X msg 120 144 expr;
+#X msg 99 123 counter;
+#X text 156 101 set object name;
+#X text 155 122 set object name and output path;
+#X text 227 169 argument is object name;
+#X text 130 222 2009/03/03 Martin Peach;
+#X connect 0 0 5 0;
+#X connect 1 0 0 0;
+#X connect 3 0 6 0;
+#X connect 4 0 0 0;
+#X connect 6 0 0 0;
+#X connect 7 0 0 0;
+#X connect 8 0 0 0;
diff --git a/which/which.c b/which/which.c new file mode 100644 index 0000000..b136e27 --- /dev/null +++ b/which/which.c @@ -0,0 +1,168 @@ +/* which: an external for pure data */ +/* Will output the path to the object named as its first argument */ +/* Martin Peach 20090225 */ +#include "m_pd.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> /* for strncpy strncat */ +#ifdef MSW +#include <io.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <share.h> +#include <errno.h> +#define close _close +#else +#include <unistd.h> +#endif + +static t_class *which_class; + +typedef struct _which +{ + t_object x_obj; + t_symbol *x_object_name; + t_symbol *x_object_path; + t_canvas *x_canvas; +} t_which; + +/* We took this (sys_dllextent) from s_loader.c since it's not global */ +/* Naming convention for externs. The names are kept distinct for those +who wich to make "fat" externs compiled for many platforms. Less specific +fallbacks are provided, primarily for back-compatibility; these suffice if +you are building a package which will run with a single set of compiled +objects. The specific name is the letter b, l, d, or m for BSD, linux, +darwin, or microsoft, followed by a more specific string, either "fat" for +a fat binary or an indication of the instruction set. */ + +#ifdef __FreeBSD__ +static char sys_dllextent[] = ".b_i386", sys_dllextent2[] = ".pd_freebsd"; +#endif +#ifdef __linux__ +#ifdef __x86_64__ +static char sys_dllextent[] = ".l_ia64", sys_dllextent2[] = ".pd_linux"; +#else +static char sys_dllextent[] = ".l_i386", sys_dllextent2[] = ".pd_linux"; +#endif +#endif +#ifdef __APPLE__ +#ifndef MACOSX3 +static char sys_dllextent[] = ".d_fat", sys_dllextent2[] = ".pd_darwin"; +#else +static char sys_dllextent[] = ".d_ppc", sys_dllextent2[] = ".pd_darwin"; +#endif +#endif +#ifdef MSW +static char sys_dllextent[] = ".m_i386", sys_dllextent2[] = ".dll"; +#endif + +static void which_any(t_which *x, t_symbol *s, int argc, t_atom *argv); +static void which_bang(t_which *x); +static void which_symbol(t_which *x, t_symbol *s); +static void which_set(t_which *x, t_symbol *s); +static void *which_new(t_symbol *s, int argc, t_atom *argv); +void which_setup(void); + +static void which_set(t_which *x, t_symbol *s) +{ + x->x_object_name = s; +} + +static void which_symbol(t_which *x, t_symbol *s) +{ + x->x_object_name = s; +} + +static void which_any(t_which *x, t_symbol *s, int argc, t_atom *argv) +{ + x->x_object_name = s; + which_bang(x); +} + +static void which_bang(t_which *x) +{ + int fd = -1, result = 0; + char *nameptr = 0; + char filename[MAXPDSTRING]; + char dirbuf[MAXPDSTRING]; + /* + EXTERN int canvas_open(t_canvas *x, const char *name, const char *ext, + char *dirresult, char **nameresult, unsigned int size, int bin); + */ + /* canvas_open is a 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 "name" and "ext". + "Name" may be absolute, or may be relative with slashes. + If anything can be opened, the true directory is put in the buffer + dirresult (provided by caller), which should be "size" bytes. + The "nameresult" pointer will be set somewhere in + the interior of "dirresult" and will give the file basename (with + slashes trimmed). If "bin" is set a 'binary' open is + attempted, otherwise ASCII (this only matters on Microsoft.) + If "x" is zero, the file is sought in the directory "." or in the + global path. + + */ + /* try looking in the path for (objectname).(sys_dllextent) ... */ + sys_lock(); + + x->x_canvas = canvas_getcurrent(); +post("canvas is %p", x->x_canvas); +//post("name is %s", x->x_object_name->s_name); +//post("ext is %s", sys_dllextent); +//post("ext2 is %s", sys_dllextent2); + fd = canvas_open(x->x_canvas, x->x_object_name->s_name, sys_dllextent, + dirbuf, &nameptr, MAXPDSTRING, 1); +//post("fd is %d", fd); + if (fd >= 0) post("1"); + if (fd < 0) + {/* same, with the more generic sys_dllextent2 */ + fd = canvas_open(x->x_canvas, x->x_object_name->s_name, sys_dllextent2, + dirbuf, &nameptr, MAXPDSTRING, 1); +//post("fd is %d", fd); + if (fd >= 0) post("2"); + } + if (fd < 0) + { + outlet_symbol(x->x_obj.te_outlet, gensym("not found")); + return; + } + result = _filelength(fd); + result = close(fd);/* this is crashing pd in WinXP: why? */ +//post("dirbuf: %s", dirbuf); +//post("nameptr: %s", nameptr); + /* rebuild the absolute pathname */ + strncpy(filename, dirbuf, MAXPDSTRING); + filename[MAXPDSTRING-2] = 0; + strcat(filename, "/"); + strncat(filename, nameptr, MAXPDSTRING-strlen(filename)); + filename[MAXPDSTRING-1] = 0; + x->x_object_path = gensym(filename); + outlet_symbol(x->x_obj.te_outlet, x->x_object_path); + sys_unlock(); +} + + +static void *which_new(t_symbol *s, int argc, t_atom *argv) +{ + t_which *x = (t_which *)pd_new(which_class); + x->x_object_name = s; + if ((argc >= 1)&&(argv[0].a_type == A_SYMBOL)) x->x_object_name = argv[0].a_w.w_symbol; + outlet_new(&x->x_obj, &s_anything); + x->x_canvas = canvas_getcurrent();/* canvas_getcurrent only seems to work in the _new function: why? */ + post("canvas is %p", x->x_canvas); + return (x); +} + +void which_setup(void) +{ + which_class = class_new(gensym("which"), (t_newmethod)which_new, + 0, sizeof(t_which), 0, A_DEFSYM, 0); + class_addbang(which_class, (t_method)which_bang); + class_addsymbol(which_class, (t_method)which_symbol); + class_addanything(which_class, (t_method)which_any); + class_addmethod(which_class, (t_method)which_set, gensym("set"), A_DEFSYM, 0); +} + +/* end which.c */ |