1N/A/***********************************************************************
1N/A* *
1N/A* This software is part of the ast package *
1N/A* Copyright (c) 1985-2011 AT&T Intellectual Property *
1N/A* and is licensed under the *
1N/A* Common Public License, Version 1.0 *
1N/A* by AT&T Intellectual Property *
1N/A* *
1N/A* A copy of the License is available at *
1N/A* http://www.opensource.org/licenses/cpl1.0.txt *
1N/A* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
1N/A* *
1N/A* Information and Software Systems Research *
1N/A* AT&T Research *
1N/A* Florham Park NJ *
1N/A* *
1N/A* Glenn Fowler <gsf@research.att.com> *
1N/A* David Korn <dgk@research.att.com> *
1N/A* Phong Vo <kpv@research.att.com> *
1N/A* *
1N/A***********************************************************************/
1N/A#pragma prototyped
1N/A/*
1N/A * fmtmsg implementation
1N/A */
1N/A
1N/A#include <ast.h>
1N/A
1N/A#if _lib_fmtmsg
1N/A
1N/ANoN(fmtmsg)
1N/A
1N/A#else
1N/A
1N/A#define MM_TABLES
1N/A
1N/A#include <fmtmsg.h>
1N/A
1N/A#define INIT_VERB 0x1
1N/A#define INIT_CONSOLE 0x2
1N/A
1N/Astatic struct
1N/A{
1N/A int console;
1N/A unsigned int init;
1N/A unsigned int mask;
1N/A} mm;
1N/A
1N/Aconst MM_table_t mm_class[] =
1N/A{
1N/A "null", 0, 0,
1N/A "hard", "HARDWARE", MM_HARD,
1N/A "soft", "SOFTWARE", MM_SOFT,
1N/A "firm", "FIRMWARE", MM_FIRM,
1N/A "appl", "APPLICATION", MM_APPL,
1N/A "util", "UTILITY", MM_UTIL,
1N/A "opsys", "KERNEL", MM_OPSYS,
1N/A "print", 0, MM_PRINT,
1N/A "console", 0, MM_CONSOLE,
1N/A "recov", "RECOVERABLE", MM_RECOVER,
1N/A "nrecov", "PANIC", MM_NRECOV,
1N/A 0, 0, 0
1N/A};
1N/A
1N/Astatic const MM_table_t mm_severity_init[] =
1N/A{
1N/A "nosev", 0, MM_NOSEV,
1N/A "halt", "HALT", MM_HALT,
1N/A "error", "ERROR", MM_ERROR,
1N/A "warn", "WARNING", MM_WARNING,
1N/A "info", "INFO", MM_INFO,
1N/A 0, 0, 0
1N/A};
1N/A
1N/Aconst MM_table_t mm_verb[] =
1N/A{
1N/A "all", 0, MM_all,
1N/A "action", 0, MM_action,
1N/A "class", 0, MM_class,
1N/A "default", 0, MM_default,
1N/A "label", 0, MM_label,
1N/A "severity", 0, MM_severity,
1N/A "source", 0, MM_source,
1N/A "tag", 0, MM_tag,
1N/A "text", 0, MM_text,
1N/A 0, 0, 0
1N/A};
1N/A
1N/Aconst MM_table_t*
1N/A_mm_severity(void)
1N/A{
1N/A static MM_table_t* severity;
1N/A
1N/A if (!severity)
1N/A {
1N/A register char* s;
1N/A register MM_table_t* p;
1N/A register int n;
1N/A register int c;
1N/A char* e;
1N/A MM_table_t* q;
1N/A
1N/A n = 0;
1N/A if ((s = getenv(MM_SEVERITY_ENV)) && *s)
1N/A {
1N/A e = s;
1N/A c = 0;
1N/A for (;;)
1N/A {
1N/A switch (*s++)
1N/A {
1N/A case 0:
1N/A break;
1N/A case ',':
1N/A if (++c > 2)
1N/A {
1N/A n = 0;
1N/A break;
1N/A }
1N/A continue;
1N/A case ':':
1N/A if (c != 2)
1N/A {
1N/A n = 0;
1N/A break;
1N/A }
1N/A c = 0;
1N/A n++;
1N/A continue;
1N/A default:
1N/A continue;
1N/A }
1N/A break;
1N/A }
1N/A if (c == 2)
1N/A n++;
1N/A else n = 0;
1N/A if (n)
1N/A {
1N/A for (p = (MM_table_t*)mm_severity_init; p->name; p++);
1N/A n += p - (MM_table_t*)mm_severity_init + 1;
1N/A if (severity = newof(0, MM_table_t, n, s - e))
1N/A {
1N/A s = (char*)severity + n * sizeof(MM_table_t);
1N/A strcpy(s, e);
1N/A p = severity;
1N/A for (q = (MM_table_t*)mm_severity_init; q->name; q++)
1N/A *p++ = *q;
1N/A p->name = s;
1N/A c = 0;
1N/A for (;;)
1N/A {
1N/A switch (*s++)
1N/A {
1N/A case 0:
1N/A break;
1N/A case ',':
1N/A switch (c++)
1N/A {
1N/A case 0:
1N/A *(s - 1) = 0;
1N/A p->value = strtol(s, NiL, 0);
1N/A break;
1N/A case 1:
1N/A p->display = s;
1N/A break;
1N/A }
1N/A continue;
1N/A case ':':
1N/A c = 0;
1N/A *(s - 1) = 0;
1N/A (++p)->name = s;
1N/A continue;
1N/A default:
1N/A continue;
1N/A }
1N/A break;
1N/A }
1N/A }
1N/A }
1N/A }
1N/A if (!severity)
1N/A severity = (MM_table_t*)mm_severity_init;
1N/A }
1N/A return (const MM_table_t*)severity;
1N/A}
1N/A
1N/Astatic char*
1N/Adisplay(register const MM_table_t* tab, int value, int mask)
1N/A{
1N/A while (tab->name)
1N/A {
1N/A if (value == tab->value || mask && (value & tab->value))
1N/A return (char*)tab->display;
1N/A tab++;
1N/A }
1N/A return 0;
1N/A}
1N/A
1N/Aint
1N/Afmtmsg(long classification, const char* label, int severity, const char* text, const char* action, const char* tag)
1N/A{
1N/A register int c;
1N/A register char* s;
1N/A register char* t;
1N/A register MM_table_t* p;
1N/A int n;
1N/A int m;
1N/A int r;
1N/A int fd;
1N/A unsigned int mask;
1N/A Sfio_t* sp;
1N/A char lab[MM_LABEL_1_MAX + MM_LABEL_2_MAX + 3];
1N/A
1N/A if (!mm.init)
1N/A {
1N/A mm.init = INIT_VERB;
1N/A if (!(s = getenv(MM_VERB_ENV)))
1N/A mm.mask = MM_default;
1N/A else for (;;)
1N/A {
1N/A if (t = strchr(s, ':'))
1N/A *t = 0;
1N/A if (!(p = (MM_table_t*)strlook(mm_verb, sizeof(MM_table_t), s)))
1N/A {
1N/A mm.mask = MM_default;
1N/A if (t)
1N/A *t = ':';
1N/A break;
1N/A }
1N/A mm.mask |= p->value;
1N/A if (!t)
1N/A break;
1N/A *t++ = ':';
1N/A s = t;
1N/A }
1N/A }
1N/A if (!(classification & (MM_CONSOLE|MM_PRINT)))
1N/A return 0;
1N/A if (!(sp = sfstropen()))
1N/A return MM_NOTOK;
1N/A r = 0;
1N/A if (s = (char*)label)
1N/A {
1N/A if (t = strchr(s, ':'))
1N/A {
1N/A if ((n = t - s) > MM_LABEL_1_MAX)
1N/A n = MM_LABEL_1_MAX;
1N/A sfprintf(sp, "%*.*s:", n, n, s);
1N/A s = ++t;
1N/A if ((n = strlen(t)) > MM_LABEL_2_MAX)
1N/A n = MM_LABEL_2_MAX;
1N/A sfprintf(sp, "%*.*s", n, n, s);
1N/A }
1N/A else
1N/A {
1N/A if ((n = strlen(t)) > MM_LABEL_1_MAX)
1N/A n = MM_LABEL_1_MAX;
1N/A sfprintf(sp, "%*.*s", n, n, s);
1N/A }
1N/A if (!(s = sfstruse(sp)))
1N/A {
1N/A sfstrclose(sp);
1N/A return MM_NOTOK;
1N/A }
1N/A strcpy(lab, s);
1N/A }
1N/A for (;;)
1N/A {
1N/A if (classification & MM_CONSOLE)
1N/A {
1N/A classification &= ~MM_CONSOLE;
1N/A if (!(mm.init & INIT_CONSOLE))
1N/A mm.console = open("/dev/console", O_WRONLY|O_APPEND|O_NOCTTY);
1N/A if (mm.console < 0)
1N/A {
1N/A r |= MM_NOCON;
1N/A continue;
1N/A }
1N/A c = MM_NOCON;
1N/A fd = mm.console;
1N/A mask = MM_all;
1N/A }
1N/A else if (classification & MM_PRINT)
1N/A {
1N/A classification &= ~MM_PRINT;
1N/A c = MM_NOMSG;
1N/A fd = 2;
1N/A mask = mm.mask;
1N/A }
1N/A else break;
1N/A if ((mask & MM_label) && label)
1N/A sfprintf(sp, "%s: ", lab);
1N/A if ((mask & MM_severity) && (s = display(mm_severity, severity, 0)))
1N/A sfprintf(sp, "%s: ", s);
1N/A n = sfstrtell(sp);
1N/A if ((mask & MM_text) && text)
1N/A sfprintf(sp, "%s\n", text);
1N/A else sfputc(sp, '\n');
1N/A if ((mask & MM_action) && action || (mask & MM_tag) && (label || tag))
1N/A {
1N/A if (fd != mm.console && (n -= 8) > 0)
1N/A sfprintf(sp, "%*.*s", n, n, "");
1N/A sfprintf(sp, "TO FIX:");
1N/A if ((mask & MM_action) && action)
1N/A sfprintf(sp, " %s", action);
1N/A if ((mask & MM_tag) && (label || tag))
1N/A {
1N/A sfprintf(sp, " ");
1N/A if (!tag || label && !strchr(tag, ':'))
1N/A sfprintf(sp, "%s%s", lab, tag ? ":" : "");
1N/A if (tag)
1N/A sfprintf(sp, "%s", tag);
1N/A }
1N/A if (mask & (MM_class|MM_source|MM_status))
1N/A {
1N/A sfputc(sp, ' ');
1N/A if ((mask & MM_source) && (m = classification & (MM_APPL|MM_UTIL|MM_OPSYS)) && (s = display(mm_class, m, 1)))
1N/A sfprintf(sp, " %s", s);
1N/A if ((mask & MM_class) && (m = classification & (MM_HARD|MM_SOFT|MM_FIRM)) && (s = display(mm_class, m, 1)))
1N/A sfprintf(sp, " %s", s);
1N/A if ((mask & MM_status) && (m = classification & (MM_RECOVER|MM_NRECOV)) && (s = display(mm_class, m, 1)))
1N/A sfprintf(sp, " %s", s);
1N/A }
1N/A sfputc(sp, '\n');
1N/A }
1N/A n = sfstrtell(sp);
1N/A if (!(s = sfstruse(sp)) || write(fd, s, n) != n)
1N/A r |= c;
1N/A }
1N/A sfstrclose(sp);
1N/A return r;
1N/A}
1N/A
1N/A#endif