aboutsummaryrefslogtreecommitdiff
path: root/shared/common/loud.c
diff options
context:
space:
mode:
Diffstat (limited to 'shared/common/loud.c')
-rw-r--r--shared/common/loud.c288
1 files changed, 251 insertions, 37 deletions
diff --git a/shared/common/loud.c b/shared/common/loud.c
index d176eb0..4f64110 100644
--- a/shared/common/loud.c
+++ b/shared/common/loud.c
@@ -9,23 +9,92 @@
#include "m_pd.h"
#include "common/loud.h"
-#define LOUD_ERROR_DEFAULT "error (miXed): "
+/* The 'shared_' calls do not really belong here,
+ LATER find them a permanent home. */
-/* LATER move it somewhere else */
-t_symbol *loud_floatsym(void)
+/* FIXME compatibility mode should be a standard Pd feature */
+static t_symbol *shared_compatibility = 0;
+static t_class *sharedcompatibility_class = 0;
+static t_pd *sharedcompatibility_target = 0;
+static t_symbol *sharedps_hashcompatibility = 0;
+static t_symbol *sharedps_max = 0;
+
+static void sharedcompatibility_bang(t_pd *x)
{
- static t_symbol *s = 0;
- return (s ? s : (s = gensym("noninteger float")));
+ if (sharedps_hashcompatibility)
+ {
+ if (shared_compatibility && sharedps_hashcompatibility->s_thing)
+ pd_symbol(sharedps_hashcompatibility->s_thing,
+ shared_compatibility);
+ }
+ else bug("sharedcompatibility_bang");
}
-/* LATER move it somewhere else */
-char *loud_symbolname(t_symbol *s, char *nullname)
+static void sharedcompatibility_symbol(t_pd *x, t_symbol *s)
{
- return (s && s != &s_ ? s->s_name : nullname);
+ shared_compatibility = s;
+}
+
+static void sharedcompatibility_setup(t_symbol *s)
+{
+ if (sharedcompatibility_class || sharedcompatibility_target)
+ bug("sharedcompatibility_setup");
+ sharedps_hashcompatibility = gensym("#compatibility");
+ sharedps_max = gensym("max");
+ sharedcompatibility_class = class_new(sharedps_hashcompatibility,
+ 0, 0, sizeof(t_pd),
+ CLASS_PD | CLASS_NOINLET, 0);
+ class_addbang(sharedcompatibility_class, sharedcompatibility_bang);
+ class_addsymbol(sharedcompatibility_class, sharedcompatibility_symbol);
+ sharedcompatibility_target = pd_new(sharedcompatibility_class);
+ pd_bind(sharedcompatibility_target, sharedps_hashcompatibility);
+ if (s)
+ pd_symbol(sharedps_hashcompatibility->s_thing, s);
+ else
+ pd_bang(sharedps_hashcompatibility->s_thing);
}
-/* LATER move it somewhere else */
-int loud_matchignorecase(char *test, char *pattern)
+void shared_usecompatibility(void)
+{
+ if (!sharedcompatibility_class)
+ sharedcompatibility_setup(0);
+}
+
+void shared_setcompatibility(t_symbol *s)
+{
+ post("setting compatibility mode to '%s'", (s ? s->s_name : "none"));
+ if (sharedcompatibility_class)
+ {
+ if (sharedps_hashcompatibility->s_thing)
+ pd_symbol(sharedps_hashcompatibility->s_thing, s);
+ else
+ bug("shared_setcompatibility");
+ }
+ else sharedcompatibility_setup(s);
+}
+
+t_symbol *shared_getcompatibility(void)
+{
+ if (!sharedcompatibility_class)
+ sharedcompatibility_setup(0);
+ return (shared_compatibility);
+}
+
+void shared_setmaxcompatibility(void)
+{
+ if (!sharedcompatibility_class)
+ sharedcompatibility_setup(0);
+ shared_setcompatibility(sharedps_max);
+}
+
+int shared_getmaxcompatibility(void)
+{
+ if (!sharedcompatibility_class)
+ sharedcompatibility_setup(0);
+ return (shared_compatibility == sharedps_max);
+}
+
+int shared_matchignorecase(char *test, char *pattern)
{
char ct, cp;
for (ct = *test, cp = *pattern; ct && cp; ct = *++test, cp = *++pattern)
@@ -37,7 +106,20 @@ int loud_matchignorecase(char *test, char *pattern)
return (ct == cp);
}
-/* LATER move it somewhere else */
+struct _loudcontext
+{
+ t_pd *lc_caller; /* an object reporting trouble */
+ char *lc_callername;
+ int lc_cnsize;
+ /* during object creation, use the following: */
+ t_symbol *lc_selector; /* creation message selector (class name) */
+ int lc_ac; /* creation message arguments */
+ t_atom *lc_av; /* void out of creation context */
+ int lc_andindent;
+};
+
+#define LOUD_ERROR_DEFAULT "error (miXed):"
+
char *loud_ordinal(int n)
{
static char buf[16]; /* assuming 10-digit INT_MAX */
@@ -60,32 +142,27 @@ char *loud_ordinal(int n)
void loud_error(t_pd *x, char *fmt, ...)
{
+ char buf[MAXPDSTRING];
va_list ap;
va_start(ap, fmt);
+ vsprintf(buf, fmt, ap);
if (x)
{
- char buf[MAXPDSTRING];
- fprintf(stderr, "%s's ", class_getname(*x));
- vsprintf(buf, fmt, ap);
+ startpost("%s's ", class_getname(*x));
pd_error(x, buf);
}
- else
- {
- fputs(LOUD_ERROR_DEFAULT, stderr);
- vfprintf(stderr, fmt, ap);
- putc('\n', stderr);
- }
+ else post("%s %s", LOUD_ERROR_DEFAULT, buf);
va_end(ap);
}
void loud_errand(t_pd *x, char *fmt, ...)
{
+ char buf[MAXPDSTRING];
va_list ap;
va_start(ap, fmt);
- fprintf(stderr, "%*s", (int)(x ? strlen(class_getname(*x)) + 10
- : strlen(LOUD_ERROR_DEFAULT)), "");
- vfprintf(stderr, fmt, ap);
- putc('\n', stderr);
+ vsprintf(buf, fmt, ap);
+ post("%*s%s", (int)(x ? strlen(class_getname(*x)) + 10
+ : strlen(LOUD_ERROR_DEFAULT) + 1), "", buf);
va_end(ap);
}
@@ -113,11 +190,14 @@ int loud_checkint(t_pd *x, t_float f, int *valuep, t_symbol *mess)
return (1);
else
{
+ static t_symbol *floatsym = 0;
+ if (!floatsym)
+ floatsym = gensym("noninteger float");
if (mess == &s_float)
- loud_nomethod(x, loud_floatsym());
+ loud_nomethod(x, floatsym);
else if (mess)
loud_error(x, "\"%s\" argument invalid for message \"%s\"",
- loud_floatsym()->s_name, mess->s_name);
+ floatsym->s_name, mess->s_name);
return (0);
}
}
@@ -129,13 +209,13 @@ void loud_classarg(t_class *c)
void loud_warning(t_pd *x, char *who, char *fmt, ...)
{
+ char buf[MAXPDSTRING];
va_list ap;
va_start(ap, fmt);
- fprintf(stderr, "warning (%s): ",
- (x ? class_getname(*x) : (who ? who : "miXed")));
- vfprintf(stderr, fmt, ap);
+ vsprintf(buf, fmt, ap);
+ post("warning (%s): %s",
+ (x ? class_getname(*x) : (who ? who : "miXed")), buf);
va_end(ap);
- putc('\n', stderr);
}
void loud_notimplemented(t_pd *x, char *name)
@@ -148,13 +228,16 @@ void loud_notimplemented(t_pd *x, char *name)
void loud_incompatible(t_class *c, char *fmt, ...)
{
- va_list ap;
- va_start(ap, fmt);
- fprintf(stderr, "'%s' class incompatibility warning:\n\t",
- class_getname(c));
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- putc('\n', stderr);
+ if (shared_getmaxcompatibility())
+ {
+ char buf[MAXPDSTRING];
+ va_list ap;
+ va_start(ap, fmt);
+ vsprintf(buf, fmt, ap);
+ post("'%s' class incompatibility warning:\n\t%s",
+ class_getname(c), buf);
+ va_end(ap);
+ }
}
void loud_incompatible_max(t_class *c, int maxmax, char *what)
@@ -222,3 +305,134 @@ int loud_floatarg(t_class *c, int which, int ac, t_atom *av,
}
return (result);
}
+
+void loudx_error(t_loudcontext *lc, char *fmt, ...)
+{
+ char buf[MAXPDSTRING];
+ va_list ap;
+ va_start(ap, fmt);
+ vsprintf(buf, fmt, ap);
+ if (lc->lc_caller)
+ {
+ startpost("%s's ", (lc->lc_callername ?
+ lc->lc_callername : class_getname(*lc->lc_caller)));
+ pd_error(lc->lc_caller, buf);
+ }
+ else
+ {
+ if (lc->lc_callername)
+ post("error (%s): %s", lc->lc_callername, buf);
+ else if (lc->lc_selector)
+ post("error (%s): %s", lc->lc_selector->s_name, buf);
+ else
+ post("%s %s", LOUD_ERROR_DEFAULT, buf);
+ }
+ va_end(ap);
+}
+
+void loudx_errand(t_loudcontext *lc, char *fmt, ...)
+{
+ char buf[MAXPDSTRING];
+ va_list ap;
+ va_start(ap, fmt);
+ vsprintf(buf, fmt, ap);
+ post("%*s%s", lc->lc_andindent, "", buf);
+ va_end(ap);
+}
+
+void loudx_nomethod(t_loudcontext *lc, t_symbol *s)
+{
+ loudx_error(lc, "doesn't understand \"%s\"", s->s_name);
+}
+
+void loudx_messarg(t_loudcontext *lc, t_symbol *s)
+{
+ loudx_error(lc, "bad arguments for message \"%s\"", s->s_name);
+}
+
+void loudx_warning(t_loudcontext *lc, char *fmt, ...)
+{
+ char buf[MAXPDSTRING];
+ va_list ap;
+ va_start(ap, fmt);
+ vsprintf(buf, fmt, ap);
+ if (lc->lc_callername)
+ post("warning (%s): %s", lc->lc_callername, buf);
+ else if (lc->lc_selector)
+ post("warning (%s): %s", lc->lc_selector->s_name, buf);
+ else
+ post("warning (miXed): %s", buf);
+ va_end(ap);
+}
+
+void loudx_setcontext(t_loudcontext *lc, t_pd *caller, char *callername,
+ t_symbol *s, int ac, t_atom *av)
+{
+ if (lc->lc_callername)
+ freebytes(lc->lc_callername, lc->lc_cnsize);
+ lc->lc_caller = caller;
+ if (callername)
+ {
+ lc->lc_cnsize = strlen(callername) + 1;
+ lc->lc_callername = getbytes(lc->lc_cnsize);
+ strcpy(lc->lc_callername, callername);
+ }
+ else
+ {
+ lc->lc_callername = 0;
+ lc->lc_cnsize = 0;
+ }
+ lc->lc_selector = s;
+ lc->lc_ac = ac;
+ lc->lc_av = av;
+ if (callername)
+ lc->lc_andindent = lc->lc_cnsize + 9;
+ else if (caller)
+ lc->lc_andindent = strlen(class_getname(*caller)) + 10;
+ else if (s)
+ lc->lc_andindent = strlen(s->s_name) + 10;
+ else
+ lc->lc_andindent = strlen(LOUD_ERROR_DEFAULT) + 1;
+}
+
+/* must call before going out of creation context */
+void loudx_setcaller(t_loudcontext *lc, t_pd *caller, char *callerfmt, ...)
+{
+ va_list ap;
+ va_start(ap, callerfmt);
+ if (callerfmt)
+ {
+ char buf[MAXPDSTRING];
+ vsprintf(buf, callerfmt, ap);
+ loudx_setcontext(lc, caller, buf, lc->lc_selector, 0, 0);
+ }
+ else loudx_setcontext(lc, caller, 0, lc->lc_selector, 0, 0);
+ va_end(ap);
+}
+
+t_symbol *loudx_getselector(t_loudcontext *lc)
+{
+ return (lc->lc_selector);
+}
+
+t_atom *loudx_getarguments(t_loudcontext *lc, int *acp)
+{
+ *acp = lc->lc_ac;
+ return (lc->lc_av);
+}
+
+void loudx_freecontext(t_loudcontext *lc)
+{
+ if (lc->lc_callername)
+ freebytes(lc->lc_callername, lc->lc_cnsize);
+ freebytes(lc, sizeof(*lc));
+}
+
+t_loudcontext *loudx_newcontext(t_pd *caller, char *callername,
+ t_symbol *s, int ac, t_atom *av)
+{
+ t_loudcontext *lc = getbytes(sizeof(*lc));
+ lc->lc_callername = 0;
+ loudx_setcontext(lc, caller, callername, s, ac, av);
+ return (lc);
+}