diff --git a/pd/src/m_class.c b/pd/src/m_class.c index a398ffb15351846dfaa22cc209dd452928a04c4a..c582318b9cdde1a9d2e290df08eb45c59bbacd5d 100644 --- a/pd/src/m_class.c +++ b/pd/src/m_class.c @@ -99,18 +99,29 @@ char *type_hint(t_symbol *s, int argc, t_atom *argv, int dostof) { if (symbol_can_float(atom_getsymbolarg(0, argc, argv), &f)) { - sprintf(hint, " (Note: this symbol message has a floatlike payload " - "which cannot be saved properly. Did you mean 'float %s'?)", - argv->a_w.w_symbol->s_name); + if (s == &s_symbol) + sprintf(hint, " (Warning: symbol message with numeric payload " + "detected. This data cannot be saved properly in a patch."); + else + sprintf(hint, " (Note: '%s' is actually a symbol atom, not " + "a float)", + argv->a_w.w_symbol->s_name); return hint; } else if (f == -1 || f == 1) { /* For values which would overflow, give a hint but don't suggest float type */ - sprintf(hint, " (Note: this symbol message has an %s floatlike " - "payload which cannot be saved properly.", - f == 1 ? "overflowing" : "underflowing"); + if (s == &s_symbol) + sprintf(hint, " (Note: this symbol message has an %s floatlike " + "payload which cannot be saved properly.", + f == 1 ? "overflowing" : "underflowing"); + else + sprintf(hint, " (Note: '%s' is actually a symbol atom. If you " + "save it Pd will parse it as a float and cause an %s " + "error.", + argv->a_w.w_symbol->s_name, + f == 1 ? "overflow" : "underflow"); return hint; } } @@ -129,13 +140,33 @@ char *type_hint(t_symbol *s, int argc, t_atom *argv, int dostof) { /* For values which would overflow, give a hint but don't suggest float type */ - sprintf(hint, " (Note: this symbol atom has an %s floatlike " + sprintf(hint, " (Note: the symbol atom '%s' has an %s floatlike " "payload which cannot be saved properly.", + s->s_name, f == 1 ? "overflowing" : "underflowing"); return hint; } } + /* Now that we've checked for symbols that could be floats, let's + catch the generic case where a user entered a symbol payload for a + "float" message. This can be typed into a messsage box, for + example. We also check for empty symbol payload here, and other + odd atom types */ + if (s && s == &s_float && argc && argv->a_type != A_FLOAT) + { + if (argv->a_type == A_SYMBOL && argv->a_w.w_symbol == &s_) + sprintf(hint, " (Expected a float argument but got empty symbol)"); + else if (argv->a_type == A_SYMBOL) + sprintf(hint, " (Expected a float argument but got '%s')", + argv->a_w.w_symbol->s_name); + else if (argv->a_type == A_POINTER) + sprintf(hint, " (Expected a float argument but got a gpointer)"); + else + sprintf(hint, " (Note: got an argument that's not a float)"); + return hint; + } + hint[0] = '\0'; return hint; } @@ -150,7 +181,7 @@ static void pd_defaultanything(t_pd *x, t_symbol *s, int argc, t_atom *argv) static void pd_defaultbang(t_pd *x) { if (*(*x)->c_listmethod != pd_defaultlist) - (*(*x)->c_listmethod)(x, 0, 0, 0); + (*(*x)->c_listmethod)(x, &s_bang, 0, 0); else (*(*x)->c_anymethod)(x, &s_bang, 0, 0); } @@ -165,7 +196,7 @@ static void pd_defaultpointer(t_pd *x, t_gpointer *gp) { t_atom at; SETPOINTER(&at, gp); - (*(*x)->c_listmethod)(x, 0, 1, &at); + (*(*x)->c_listmethod)(x, &s_pointer, 1, &at); } else { @@ -181,7 +212,7 @@ static void pd_defaultfloat(t_pd *x, t_float f) { t_atom at; SETFLOAT(&at, f); - (*(*x)->c_listmethod)(x, 0, 1, &at); + (*(*x)->c_listmethod)(x, &s_float, 1, &at); } else { @@ -197,7 +228,7 @@ static void pd_defaultsymbol(t_pd *x, t_symbol *s) { t_atom at; SETSYMBOL(&at, s); - (*(*x)->c_listmethod)(x, 0, 1, &at); + (*(*x)->c_listmethod)(x, &s_symbol, 1, &at); } else { @@ -1091,8 +1122,10 @@ badarg: message that contains it (so it can be selected when 'Find Error' is used). */ x = pd_mess_from_responder(x); - pd_error(x, "Bad arguments for message '%s' to object '%s'", - s->s_name, c->c_name->s_name); + pd_error(x, "Bad arguments for message '%s' to object '%s'%s", + s->s_name, + c->c_name->s_name, + type_hint(s, argc, argv, 1)); lastmess: last_typedmess = s; last_typedmess_pd = x; @@ -1168,7 +1201,10 @@ t_gotfn getfn(t_pd *x, t_symbol *s) for (i = c->c_nmethod, m = c->c_methods; i--; m++) if (m->me_name == s) return(m->me_fun); - pd_error(x, "%s: no method for message '%s'", c->c_name->s_name, s->s_name); + pd_error(x, "%s: no method for message '%s'%s", + c->c_name->s_name, + s->s_name, + type_hint(s, 0, 0, 1)); return((t_gotfn)nullfn); } diff --git a/pd/src/x_interface.c b/pd/src/x_interface.c index bfb69df38ccd1a179c50b50b510dad75cbb302ae..79c204023160b6b36e782d9fd6690fb9f122bb39 100644 --- a/pd/src/x_interface.c +++ b/pd/src/x_interface.c @@ -325,6 +325,12 @@ typedef struct _objectinfo { t_canvas *x_canvas; } t_objectinfo; +static t_class *debuginfo_class; + +typedef struct _debuginfo { + t_object x_obj; +} t_debuginfo; + /* used by all the *info objects */ static int info_to_console = 0; @@ -1623,12 +1629,43 @@ void objectinfo_setup(void) post("stable objectinfo methods: class"); } +void debuginfo_print(t_debuginfo *x) +{ + info_print((t_text *)x); +} + + /* replace incoming message's selector with zero and output it */ +void debuginfo_nullselector(t_debuginfo *x, t_symbol *s, int argc, + t_atom *argv) +{ + info_out((t_text *)x, 0, argc, argv); +} + +void *debuginfo_new(void) +{ + t_debuginfo *x = (t_debuginfo *)pd_new(debuginfo_class); + outlet_new(&x->x_obj, &s_anything); + return (void *)x; +} + +void debuginfo_setup(void) +{ + debuginfo_class = class_new(gensym("debuginfo"), + (t_newmethod)debuginfo_new, 0, sizeof(t_debuginfo), + CLASS_DEFAULT, 0); + class_addmethod(debuginfo_class, (t_method)debuginfo_nullselector, + gensym("null-selector"), A_GIMME, 0); + class_addmethod(debuginfo_class, (t_method)debuginfo_print, + gensym("print"), A_GIMME, 0); +} + void x_interface_setup(void) { - print_setup(); - unpost_setup(); canvasinfo_setup(); - pdinfo_setup(); classinfo_setup(); + debuginfo_setup(); objectinfo_setup(); + pdinfo_setup(); + print_setup(); + unpost_setup(); }