Commit 731f1a77 authored by Jonathan Wilkes's avatar Jonathan Wilkes

Merge branch 'port-unpost'

parents 7cf5bc2e ae2556be
#N canvas 430 62 555 619 10;
#X obj 0 585 cnv 15 552 21 empty \$0-pddp.cnv.footer empty 20 12 0
14 -228856 -66577 0;
#X obj 0 0 cnv 15 552 40 empty \$0-pddp.cnv.header unpost 3 12 0 18
-204280 -1 0;
#X obj 0 279 cnv 3 550 3 empty \$0-pddp.cnv.inlets inlets 8 12 0 13
-228856 -1 0;
#N canvas 497 325 482 332 META 0;
#X text 12 145 LIBRARY internal;
#X text 12 185 WEBSITE http://crca.ucsd.edu/~msp/;
#X text 12 45 LICENSE SIBSD;
#X text 12 165 AUTHOR Miller Puckette;
#X text 12 225 HELP_PATCH_AUTHORS Jonathan Wilkes revised the patch
to conform to the PDDP template for Pd version 0.42.;
#X text 12 25 KEYWORDS control storage;
#X text 12 205 RELEASE_DATE 1997;
#X text 12 65 DESCRIPTION reroute console messages to an outlet;
#X text 12 85 INLET_0 anything;
#X text 12 125 OUTLET_1 anything;
#X text 12 105 OUTLET_0 symbol;
#X restore 500 587 pd META;
#X obj 0 336 cnv 3 550 3 empty \$0-pddp.cnv.outlets outlets 8 12 0
13 -228856 -1 0;
#X obj 0 503 cnv 3 550 3 empty \$0-pddp.cnv.argument arguments 8 12
0 13 -228856 -1 0;
#X obj 0 553 cnv 3 550 3 empty \$0-pddp.cnv.more_info more_info 8 12
0 13 -228856 -1 0;
#X obj 78 352 cnv 17 3 17 empty \$0-pddp.cnv.let.0 0 5 9 0 16 -228856
-162280 0;
#N canvas 215 545 428 131 Related_objects 0;
#X obj 1 1 cnv 15 425 20 empty \$0-pddp.cnv.subheading empty 3 12 0
14 -204280 -1 0;
#X text 7 1 [unpost] Related Objects;
#X obj 22 36 print;
#X restore 101 587 pd Related_objects;
#X obj 78 295 cnv 17 3 17 empty \$0-pddp.cnv.let.0 0 5 9 0 16 -228856
-162280 0;
#X obj 4 587 pddp/pddplink all_about_help_patches.pd -text Usage Guide
;
#X text 11 20 reroute console messages to an outlet;
#X obj 502 12 unpost;
#X msg 58 60 bad_method;
#X obj 58 112 unpost;
#X symbolatom 58 194 0 0 0 0 - - -;
#X text 98 351 symbol;
#X text 168 351 - outputs the console messages. The messages triggered
by the right outlet are split at newlines. Then each resulting line
is converted to a symbol and output in sequence. (This means a single
message to the inlet of [unpost] may trigger multiple messages to this
outlet.;
#X text 99 295 anything;
#X text 169 295 - then input is sent to the right outlet;
#X obj 78 432 cnv 17 3 17 empty \$0-pddp.cnv.let.1 1 5 9 0 16 -228856
-162280 0;
#X text 98 431 anything;
#X obj 91 163 print redirected;
#X msg 81 85 1;
#X obj 91 141 + 41;
#X msg 238 60 bad_method;
#X symbolatom 238 194 0 0 0 0 - - -;
#X obj 271 163 print redirected;
#X msg 261 85 1;
#X obj 271 141 + 41;
#X obj 238 112 unpost error;
#X text 319 112 <- only reroute errors;
#X text 168 431 - the message sent to the inlet is received to this
outlet. Any console messages which are triggered from the rest of object
chain connected below it will get forwarded to the left outlet. If
the "error" argument was given \, then only error messages will be
redirected to the left outlet.;
#X text 81 520 1) symbol;
#X text 171 520 - the symbol "error" will only redirect error messages.
All other console messages will get printed as usual.;
#X connect 13 0 14 0;
#X connect 14 0 15 0;
#X connect 14 1 24 0;
#X connect 23 0 14 0;
#X connect 24 0 22 0;
#X connect 25 0 30 0;
#X connect 28 0 30 0;
#X connect 29 0 27 0;
#X connect 30 0 26 0;
#X connect 30 1 29 0;
......@@ -14,6 +14,7 @@
#endif
t_printhook sys_printhook;
t_printhook sys_printhook_error;
int sys_printtostderr;
/* escape characters for tcl/tk */
......@@ -51,11 +52,13 @@ static void doerror(const void *object, const char *s)
char upbuf[MAXPDSTRING];
upbuf[MAXPDSTRING-1]=0;
// what about sys_printhook_error ?
if (sys_printhook)
if (sys_printhook || sys_printhook_error)
{
snprintf(upbuf, MAXPDSTRING-1, "error: %s", s);
(*sys_printhook)(upbuf);
if (sys_printhook_error)
(*sys_printhook_error)(upbuf);
if (sys_printhook)
(*sys_printhook)(upbuf);
}
else if (sys_printtostderr)
fprintf(stderr, "error: %s", s);
......
......@@ -64,7 +64,7 @@ static void *print_new(t_symbol *sel, int argc, t_atom *argv)
static void print_bang(t_print *x)
{
if (sys_nogui)
if (sys_nogui || sys_printhook)
post("%s%sbang", x->x_sym->s_name, (*x->x_sym->s_name ? ": " : ""));
else
{
......@@ -78,7 +78,7 @@ static void print_bang(t_print *x)
static void print_pointer(t_print *x, t_gpointer *gp)
{
if (sys_nogui)
if (sys_nogui || sys_printhook)
post("%s%s(gpointer)", x->x_sym->s_name,
(*x->x_sym->s_name ? ": " : ""));
else
......@@ -93,7 +93,7 @@ static void print_pointer(t_print *x, t_gpointer *gp)
static void print_float(t_print *x, t_floatarg f)
{
if (sys_nogui)
if (sys_nogui || sys_printhook)
post("%s%s" FLOAT_SPECIFIER, x->x_sym->s_name,
(*x->x_sym->s_name ? ": " : ""), f);
else
......@@ -108,7 +108,7 @@ static void print_float(t_print *x, t_floatarg f)
static void print_symbol(t_print *x, t_symbol *s)
{
if (sys_nogui)
if (sys_nogui || sys_printhook)
post("%s%s%s", x->x_sym->s_name, (*x->x_sym->s_name ? ": " : ""),
s->s_name);
else
......@@ -126,7 +126,7 @@ static void print_anything(t_print *x, t_symbol *s, int argc, t_atom *argv)
{
char buf[MAXPDSTRING];
t_atom at;
if (sys_nogui)
if (sys_nogui || sys_printhook)
{
startpost("%s%s", x->x_sym->s_name, (*x->x_sym->s_name ? ":" : ""));
if (s && (s != &s_list || (argc && argv->a_type != A_FLOAT)))
......@@ -164,6 +164,134 @@ static void print_setup(void)
class_addanything(print_class, print_anything);
}
/* -------------------------- unpost ------------------------------ */
#define NEWBUFSIZE MAXPDSTRING * 2
static t_class *unpost_class;
typedef struct _unpost {
t_object x_obj;
t_outlet *x_out0;
t_outlet *x_out1;
int x_all;
} t_unpost;
typedef struct _unpost_frame {
t_unpost *u_self;
char *u_buf;
unsigned int u_bufsize;
unsigned int u_index;
} t_unpost_frame;
static t_unpost_frame *current_unpost;
static void *unpost_frame_new(t_unpost *x)
{
t_unpost_frame *u = (t_unpost_frame *)t_getbytes(sizeof(t_unpost_frame));
u->u_self = x;
u->u_buf = (char *)t_getbytes(sizeof(char) * NEWBUFSIZE);
u->u_buf[0] = '\0';
u->u_bufsize = NEWBUFSIZE;
u->u_index = 0;
return u;
}
static void unpost_frame_resize(t_unpost_frame *u, int newsize)
{
u->u_buf = (char *)t_resizebytes(u->u_buf, sizeof(*u->u_buf) * u->u_bufsize,
sizeof(*u->u_buf) * newsize);
u->u_bufsize = newsize;
}
static void unpost_frame_free(t_unpost_frame* u)
{
t_freebytes(u->u_buf, sizeof(*u->u_buf));
u->u_buf = NULL;
}
static void *unpost_new(t_symbol *s)
{
t_unpost *x = (t_unpost *)pd_new(unpost_class);
x->x_all = s != gensym("error");
x->x_out0 = outlet_new(&x->x_obj, &s_symbol);
x->x_out1 = outlet_new(&x->x_obj, &s_symbol);
return x;
}
extern t_printhook sys_printhook;
extern t_printhook sys_printhook_error;
static void unpost_printhook(const char *s) {
t_unpost *x = current_unpost->u_self;
/* does strlen include terminator? can't remember... */
unsigned int needbytes = strlen(current_unpost->u_buf) + strlen(s) + 1;
if (needbytes >= current_unpost->u_bufsize)
{
/* Raise the bufsize to NEWBUFSIZE * n where n is a power of two that
will fit the number of bytes we need) */
unsigned int n = ((needbytes / NEWBUFSIZE) >> 1) +
(needbytes % NEWBUFSIZE != 0);
unpost_frame_resize(current_unpost,
current_unpost->u_bufsize * (1 << n));
}
else if (strlen(current_unpost->u_buf) + strlen(s) <
current_unpost->u_bufsize / 4)
{
/* Pretty sure I prematurely optimized here. There's no good reason to
shrink the buffer in the midst of receiving some enormous number of
posts from an object chain. Besides, we free the buffer once the
object chain downstream from the [unpost] outlet finishes computing.
Anyhow, here we are. */
unpost_frame_resize(current_unpost,
(current_unpost->u_bufsize / 4 < NEWBUFSIZE) ?
NEWBUFSIZE :
current_unpost->u_bufsize / 4);
}
strcat(current_unpost->u_buf, s);
const char *p;
const char *d = current_unpost->u_buf, *dd = d;
for (;;) {
p = strchr(d, '\n');
if (!p) break;
/* To avoid infinite recursion, let's reset our hooks before we
send to the right outlet. */
t_printhook print_backup = sys_printhook,
error_backup = sys_printhook_error;
sys_printhook = NULL;
sys_printhook_error = NULL;
outlet_symbol(x->x_out0, gensym(d));
sys_printhook = print_backup;
sys_printhook_error = error_backup;
d = p + 1;
}
if (d != dd)
{
char *q = strdup(d);
strcpy(current_unpost->u_buf, q);
t_freebytes(q, sizeof(*q) * strlen(q));
}
}
static void unpost_anything(t_unpost *x, t_symbol *s, int argc, t_atom *argv)
{
t_printhook *myhook = x->x_all ? &sys_printhook : &sys_printhook_error;
t_printhook backup1 = *myhook;
t_unpost_frame *backup2 = current_unpost;
*myhook = unpost_printhook;
current_unpost = unpost_frame_new(x);
outlet_anything(x->x_out1, s, argc, argv);
*myhook = backup1;
unpost_frame_free(current_unpost);
current_unpost = backup2;
}
static void unpost_setup(void)
{
unpost_class = class_new(gensym("unpost"), (t_newmethod)unpost_new, 0,
sizeof(t_unpost), 0, A_DEFSYM, 0);
class_addanything(unpost_class, unpost_anything);
}
/* --------------pdinfo, canvasinfo, classinfo, objectinfo --------------- */
static t_class *canvasinfo_class;
......@@ -1497,6 +1625,7 @@ void objectinfo_setup(void)
void x_interface_setup(void)
{
print_setup();
unpost_setup();
canvasinfo_setup();
pdinfo_setup();
classinfo_setup();
......
......@@ -37,6 +37,10 @@ is handy for some binbuf tests.;
#X obj 391 374 spigot;
#X obj 407 440 route 1;
#X obj 407 495 print success;
#X obj 145 358 rtest unpost_sanity;
#X obj 145 414 rtest unpost_error;
#X obj 145 465 rtest unpost_print;
#X obj 145 516 rtest unpost_long_message;
#X connect 0 0 1 0;
#X connect 1 0 7 0;
#X connect 1 1 29 0;
......@@ -56,9 +60,13 @@ is handy for some binbuf tests.;
#X connect 15 0 13 0;
#X connect 16 0 17 0;
#X connect 17 0 18 0;
#X connect 18 0 32 0;
#X connect 20 0 21 0;
#X connect 21 0 22 0;
#X connect 22 0 14 0;
#X connect 29 0 7 0;
#X connect 30 0 31 0;
#X connect 30 1 2 0;
#X connect 32 0 33 0;
#X connect 33 0 34 0;
#X connect 34 0 35 0;
#N canvas 34 75 582 396 12;
#N canvas 37 104 582 396 12;
#X obj 36 25 inlet;
#X msg 152 97 click 0 0 0 0 0;
#X msg 152 122 \$1;
......
#N canvas 170 138 650 396 12;
#X obj 36 25 inlet;
#X obj 36 349 outlet;
#X msg 36 63 unknown_method;
#X obj 61 126 unpost error;
#X obj 36 226 list;
#X obj 36 251 route bang;
#X text 155 16 Unpost takes an argument "error" to set it to only redirect
error messages. Here we make sure it redirects an error message.;
#X obj 36 88 trigger bang anything bang;
#X obj 142 181 float;
#X text 189 181 <- trigger an error;
#X obj 36 276 f 0;
#X msg 103 276 1;
#X obj 36 309 list append unpost with "error" argument should redirect
an error message;
#X connect 0 0 2 0;
#X connect 2 0 7 0;
#X connect 3 0 4 1;
#X connect 3 1 8 0;
#X connect 4 0 5 0;
#X connect 5 0 10 0;
#X connect 5 1 11 0;
#X connect 7 0 4 0;
#X connect 7 1 3 0;
#X connect 7 2 4 1;
#X connect 10 0 12 0;
#X connect 11 0 12 0;
#X connect 12 0 1 0;
#N canvas 170 138 650 396 12;
#X obj 36 25 inlet;
#X obj 36 349 outlet;
#X msg 36 63 unknown_method;
#X text 155 16 Unpost takes an argument "error" to set it to only redirect
error messages. Here we make sure it doesn't allow non-error messages
through;
#X obj 61 126 unpost error;
#X obj 142 211 print -n;
#X obj 36 226 list;
#X obj 36 88 trigger bang bang bang;
#X obj 36 251 route bang;
#X obj 36 309 list append unpost with "error" argument should not redirect
non-error messages;
#X obj 36 276 f 1;
#X msg 103 276 0;
#X msg 142 186 unpost_error test message;
#X connect 0 0 2 0;
#X connect 2 0 7 0;
#X connect 4 0 6 1;
#X connect 4 1 12 0;
#X connect 6 0 8 0;
#X connect 7 0 6 0;
#X connect 7 1 4 0;
#X connect 7 2 6 1;
#X connect 8 0 10 0;
#X connect 8 1 11 0;
#X connect 9 0 1 0;
#X connect 10 0 9 0;
#X connect 11 0 9 0;
#X connect 12 0 5 0;
#N canvas 86 182 696 396 12;
#X obj 36 25 inlet;
#X obj 36 349 outlet;
#X obj 36 266 f 1;
#X text 155 16 Unpost should be able to handle long messages. Here
we trigger one by sending a list of all the class names to the left
inlet of unpost.;
#X msg 36 63 classlist;
#X obj 36 88 unpost;
#X obj 75 116 pdinfo;
#X obj 75 148 print long_message;
#X obj 36 113 b;
#X obj 36 299 list append unpost should print long messages without
crashing;
#X connect 0 0 4 0;
#X connect 2 0 9 0;
#X connect 4 0 5 0;
#X connect 5 0 8 0;
#X connect 5 1 6 0;
#X connect 6 0 7 0;
#X connect 8 0 2 0;
#X connect 9 0 1 0;
#N canvas 35 102 696 396 12;
#X obj 36 25 inlet;
#X obj 36 349 outlet;
#X msg 36 63 unknown_method;
#X obj 36 266 f 1;
#X obj 528 228 print unpost_print;
#X obj 378 146 unpost;
#X msg 528 146 testing unpost...;
#X obj 198 228 print unpost_print;
#X msg 198 146 testing unpost error...;
#X obj 58 146 unpost error;
#X obj 139 171 float;
#X obj 58 171 b;
#X msg 58 201 test message;
#X obj 36 88 trigger bang anything bang bang bang;
#X text 155 16 Unpost allows printing from the left outlet *without*
redirecting back to the outlet. This prevents infinite loops. Without
this protection this test would crash.;
#X obj 36 299 list append when unpost's left-outlet messages are printed
to the console an infinite loop should not occur;
#X obj 58 228 print -n;
#X obj 378 228 print -n;
#X obj 378 171 b;
#X msg 378 196 test message;
#X obj 417 171 print test;
#X connect 0 0 2 0;
#X connect 2 0 13 0;
#X connect 3 0 15 0;
#X connect 5 0 18 0;
#X connect 5 1 20 0;
#X connect 6 0 4 0;
#X connect 8 0 7 0;
#X connect 9 0 11 0;
#X connect 9 1 10 0;
#X connect 11 0 12 0;
#X connect 12 0 16 0;
#X connect 13 0 3 0;
#X connect 13 1 9 0;
#X connect 13 2 8 0;
#X connect 13 3 5 0;
#X connect 13 4 6 0;
#X connect 15 0 1 0;
#X connect 18 0 19 0;
#X connect 19 0 17 0;
#N canvas 164 80 650 396 12;
#X obj 36 25 inlet;
#X obj 36 309 outlet;
#X text 155 16 Unpost is used to redirect messages from the console.
We need it for some of the following tests \, so we make sure it operates
correctly here first.;
#X obj 61 136 unpost;
#X msg 36 63 unknown_method;
#X obj 100 166 float;
#X obj 36 166 list;
#X obj 36 88 trigger bang anything bang;
#X obj 36 191 route bang;
#X obj 36 269 list append unpost should redirect an error message;
#X msg 103 225 1;
#X obj 36 226 f 0;
#X connect 0 0 4 0;
#X connect 3 0 6 1;
#X connect 3 1 5 0;
#X connect 4 0 7 0;
#X connect 6 0 8 0;
#X connect 7 0 6 0;
#X connect 7 1 3 0;
#X connect 7 2 6 1;
#X connect 8 0 11 0;
#X connect 8 1 10 0;
#X connect 9 0 1 0;
#X connect 10 0 9 0;
#X connect 11 0 9 0;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment