aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormescalinum <mescalinum@users.sourceforge.net>2011-10-28 19:25:27 +0000
committermescalinum <mescalinum@users.sourceforge.net>2011-10-28 19:25:27 +0000
commit30fb06bce3c76c7f37d8649aa33927f38ed194a9 (patch)
tree83783794bfe5f28afcb94731de53b88eabcb436e
parent7376fa909b828167badf549834f532046ada066d (diff)
add open menu
svn path=/trunk/externals/loaders/tclpd/; revision=15671
-rw-r--r--Makefile3
-rw-r--r--hashtable.c17
-rw-r--r--hashtable.h5
-rw-r--r--tcl_class.c26
-rw-r--r--tcl_extras.h7
-rw-r--r--tcl_loader.c11
6 files changed, 59 insertions, 10 deletions
diff --git a/Makefile b/Makefile
index 7b64039..f9a1893 100644
--- a/Makefile
+++ b/Makefile
@@ -37,7 +37,8 @@ EXTRA_DIST = tcl.i tcl_extras.h tclpd.tcl $(TCLPD_SOURCES) ChangeLog.txt AUTHORS
ALL_CFLAGS = $(PD_INCLUDES) -std=c99 -I/usr/include/tcl8.5 \
-I/Library/Frameworks/Tcl.framework/Headers \
- -Wall -W -Wno-unused-parameter
+ -Wall -W -Wno-unused-parameter \
+ -DHASHTABLE_COPY_KEYS
ALL_LDFLAGS =
SHARED_LDFLAGS =
ALL_LIBS =
diff --git a/hashtable.c b/hashtable.c
index 0b4409f..c2fa96f 100644
--- a/hashtable.c
+++ b/hashtable.c
@@ -15,19 +15,27 @@ uint32_t hash_str(const char *s) {
list_node_t* list_add(list_node_t* head, const char* k, void* v) {
list_node_t* n = (list_node_t*)malloc(sizeof(list_node_t));
n->next = head;
+#ifdef HASHTABLE_COPY_KEYS
n->k = strdup(k);
+#else
+ n->k = k;
+#endif
n->v = v;
return n;
}
list_node_t* list_remove(list_node_t* head, const char* k) {
+ if(!head) return NULL;
+
list_node_t* tmp;
// head remove
while(head && strcmp(head->k, k) == 0) {
tmp = head;
head = head->next;
+#ifdef HASHTABLE_COPY_KEYS
free(tmp->k);
+#endif
free(tmp);
}
@@ -39,6 +47,9 @@ list_node_t* list_remove(list_node_t* head, const char* k) {
{
tmp = p->next;
p->next = p->next->next;
+#ifdef HASHTABLE_COPY_KEYS
+ free(tmp->k);
+#endif
free(tmp);
continue;
}
@@ -48,14 +59,14 @@ list_node_t* list_remove(list_node_t* head, const char* k) {
return head;
}
-void* list_get(list_node_t* head, const char* k) {
+list_node_t* list_get(list_node_t* head, const char* k) {
while(head) {
if(strcmp(head->k, k) == 0) {
- return head->v;
+ return head;
}
head = head->next;
}
- return (void*)0;
+ return NULL;
}
size_t list_length(list_node_t* head) {
diff --git a/hashtable.h b/hashtable.h
index 0baca4c..f2d1a4a 100644
--- a/hashtable.h
+++ b/hashtable.h
@@ -19,7 +19,7 @@ typedef struct hash_table {
uint32_t hash_str(const char *s);
list_node_t* list_add(list_node_t* head, const char* k, void* v);
list_node_t* list_remove(list_node_t* head, const char* k);
-void* list_get(list_node_t* head, const char* k);
+list_node_t* list_get(list_node_t* head, const char* k);
size_t list_length(list_node_t* head);
hash_table_t* hashtable_new(size_t size);
@@ -37,7 +37,8 @@ static inline void hashtable_remove(hash_table_t* ht, const char* name) {
static inline void* hashtable_get(hash_table_t* ht, const char* name) {
uint32_t h = hash_str(name) % ht->sz;
- return list_get(ht->t[h], name);
+ list_node_t* n = list_get(ht->t[h], name);
+ return n ? n->v : NULL;
}
#endif // HASHTABLE_H_INCLUDED
diff --git a/tcl_class.c b/tcl_class.c
index 08fe2e6..596e28d 100644
--- a/tcl_class.c
+++ b/tcl_class.c
@@ -6,6 +6,7 @@
static hash_table_t* class_table = NULL;
static hash_table_t* object_table = NULL;
+static hash_table_t* source_table = NULL;
#define class_table_add(n, c) hashtable_add(class_table, n, (void*)c)
#define class_table_remove(n) hashtable_remove(class_table, n)
@@ -32,6 +33,8 @@ t_class* tclpd_class_new(const char* name, int flags) {
// is this really necessary given that there is already a 'anything' handler?
class_addmethod(c, (t_method)tclpd_loadbang, gensym("loadbang"), A_NULL);
+ class_addmethod(c, (t_method)tclpd_open, gensym("menu-open"), A_NULL);
+
char buf[80];
Tcl_Obj* res;
int res_i;
@@ -80,6 +83,11 @@ t_tcl* tclpd_new(t_symbol* classsym, int ac, t_atom* at) {
x->ninlets = 1 /* qlass->c_firstin ??? */;
x->x_glist = (t_glist*)canvas_getcurrent();
+ x->source_file = (char *)hashtable_get(source_table, name);
+ if(!x->source_file) {
+ post("tclpd: missing source file information. open command will not work.");
+ }
+
x->classname = Tcl_NewStringObj(name, -1);
char so[64];
snprintf(so, 64, "tclpd.%s.x%lx", name, objectSequentialId++);
@@ -224,6 +232,13 @@ void tclpd_loadbang(t_tcl* x) {
tclpd_inlet_anything(x, 0, gensym("loadbang"), 0, NULL);
}
+void tclpd_open(t_tcl *x) {
+ if(!x->source_file)
+ return;
+
+ sys_vgui("::pd_menucommands::menu_openfile {%s}\n", x->source_file);
+}
+
/* Tcl glue: */
t_proxyinlet* tclpd_add_proxyinlet(t_tcl* x) {
@@ -370,3 +385,14 @@ void tclpd_class_namespace_init(const char* classname) {
classname, classname, classname);
Tcl_Eval(tcl_for_pd, cmd);
}
+
+void source_table_remove(const char *object_name) {
+ if(!source_table)
+ source_table = hashtable_new(1 << 7);
+ hashtable_remove(source_table, object_name);
+}
+
+void source_table_add(const char *object_name, const char *source_file) {
+ source_table_remove(object_name);
+ hashtable_add(source_table, object_name, strdup(source_file));
+}
diff --git a/tcl_extras.h b/tcl_extras.h
index 0f563a8..283816d 100644
--- a/tcl_extras.h
+++ b/tcl_extras.h
@@ -16,11 +16,15 @@
typedef struct _t_tcl {
t_object o;
+ int ninlets;
t_glist* x_glist;
+
+ char *source_file;
+
+ // Tcl-interpreter related objects:
Tcl_Obj* self;
Tcl_Obj* classname;
Tcl_Obj* dispatcher;
- int ninlets;
} t_tcl;
typedef struct _t_proxyinlet {
@@ -65,6 +69,7 @@ void tclpd_free (t_tcl* self);
void tclpd_anything(t_tcl* self, t_symbol* s, int ac, t_atom* at);
void tclpd_inlet_anything(t_tcl *self, int inlet, t_symbol *s, int ac, t_atom *at);
void tclpd_loadbang(t_tcl* x);
+void tclpd_open(t_tcl* x);
t_proxyinlet* tclpd_add_proxyinlet(t_tcl* x);
t_tcl* tclpd_get_instance(const char* objectSequentialId);
t_pd* tclpd_get_instance_pd(const char* objectSequentialId);
diff --git a/tcl_loader.c b/tcl_loader.c
index 0766a8c..5167cec 100644
--- a/tcl_loader.c
+++ b/tcl_loader.c
@@ -2,6 +2,10 @@
#include <string.h>
#include <unistd.h>
+/* from tcl_class.c: */
+//void source_table_remove(const char *object_name);
+void source_table_add(const char *object_name, const char *source_path);
+
extern int tclpd_do_load_lib(t_canvas *canvas, char *objectname) {
#ifdef DEBUG
post("Tcl loader: registering tcl class loader mechanism");
@@ -20,12 +24,12 @@ extern int tclpd_do_load_lib(t_canvas *canvas, char *objectname) {
return (1);
}
- /* try looking in the path for (objectname).(tcl) ... */
+ /* try looking in the path for (objectname).(tcl) ... */
if ((fd = canvas_open(canvas, objectname, ".tcl",
dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0)
goto gotone;
- /* next try (objectname)/(classname).(tcl) ... */
+ /* next try (objectname)/(classname).(tcl) ... */
strncpy(filename, objectname, MAXPDSTRING);
filename[MAXPDSTRING-2] = 0;
strcat(filename, "/");
@@ -40,7 +44,7 @@ extern int tclpd_do_load_lib(t_canvas *canvas, char *objectname) {
gotone:
close(fd);
class_set_extern_dir(gensym(dirbuf));
- /* rebuild the absolute pathname */
+ /* rebuild the absolute pathname */
strncpy(filename, dirbuf, MAXPDSTRING);
filename[MAXPDSTRING-2] = 0;
strcat(filename, "/");
@@ -55,6 +59,7 @@ gotone:
// load tcl external:
result = Tcl_EvalFile(tcl_for_pd, filename);
if(result == TCL_OK) {
+ source_table_add(objectname, filename);
post("Tcl loader: loaded %s", filename);
} else {
post("Tcl loader: error trying to load %s", filename);