aboutsummaryrefslogtreecommitdiff
path: root/which
diff options
context:
space:
mode:
authorMartin Peach <mrpeach@users.sourceforge.net>2009-04-08 20:04:38 +0000
committerMartin Peach <mrpeach@users.sourceforge.net>2009-04-08 20:04:38 +0000
commit9bad6b5eca4ebacc5ac42cc39bebe5487e47ebc8 (patch)
treedd3ebd54b5aaead7786fe9516247b8d8a2c3a1ee /which
parent4e710aee71943a8667d5b2c4ad4e57be890e6d23 (diff)
This is an object that is supposed to output the absolute path to the Pd external or abstraction named in its argument or a message. Currently it works on linux but, mysteriously, crashes Pd on WinXp.
svn path=/trunk/externals/mrpeach/; revision=10989
Diffstat (limited to 'which')
-rw-r--r--which/which-help.pd23
-rw-r--r--which/which.c168
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 */