Mercurial > hg > Applications > mh
diff uip/fmtdump.c @ 0:bce86c4163a3
Initial revision
author | kono |
---|---|
date | Mon, 18 Apr 2005 23:46:02 +0900 |
parents | |
children | 441a2190cfae |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uip/fmtdump.c Mon Apr 18 23:46:02 2005 +0900 @@ -0,0 +1,518 @@ +/* fmtdump.c - compile format file and dump out instructions */ +#ifndef lint +static char ident[] = "@(#)$Id$"; +#endif + +#include "../h/mh.h" +#include "../h/formatsbr.h" +#include "../h/fmtcompile.h" +#include "../h/scansbr.h" +#include <stdio.h> +#ifdef LOCALE +#include <locale.h> +#endif + + +static struct swit switches[] = { +#define FORMSW 0 + "form formatfile", 0, +#define FMTSW 1 + "format string", 5, + +#define HELPSW 2 + "help", 4, + + NULL, 0 +}; + + +/* for assignlabel */ +static struct format *lvec[128]; +static lused = 0; + +static char *f_typestr(), *c_typestr(); +static void fmt_dump(), dumpone(), assignlabel(), litputs(), litputc(); +static int findlabel(); + +/* */ + +/* ARGSUSED */ + +main (argc, argv) +int argc; +char *argv[]; +{ + int ncomps; + char *cp, + *form = NULL, + *format = NULL, + buf[100], + **ap, + **argp, + *nfs, + *arguments[MAXARGS]; + struct format *fmt; + +#ifdef LOCALE + setlocale(LC_ALL, ""); +#endif +#ifdef JAPAN + ml_init(); +#endif /* JAPAN */ + invo_name = r1bindex (argv[0], '/'); + if ((cp = m_find (invo_name)) != NULL) { + ap = brkstring (cp = getcpy (cp), " ", "\n"); + ap = copyip (ap, arguments); + } + else + ap = arguments; + (void) copyip (argv + 1, ap); + argp = arguments; + +/* */ + + while (cp = *argp++) { + if (*cp == '-') + switch (smatch (++cp, switches)) { + case AMBIGSW: + ambigsw (cp, switches); + done (1); + case UNKWNSW: + adios (NULLCP, "-%s unknown", cp); + case HELPSW: + (void) sprintf (buf, "%s [switches]", + invo_name); + help (buf, switches); + done (1); + + case FORMSW: + if (!(form = *argp++) || *form == '-') + adios (NULLCP, "missing argument to %s", argp[-2]); + format = NULL; + continue; + case FMTSW: + if (!(format = *argp++) || *format == '-') + adios (NULLCP, "missing argument to %s", argp[-2]); + form = NULL; + continue; + + } + if (form) + adios (NULLCP, "only one form at a time!"); + else + form = cp; + } + + nfs = new_fs (form, format, FORMAT); /* must be before chdir() */ + ncomps = fmt_compile(nfs, &fmt); + + fmt_dump(fmt); + done(0); +} + +static void +fmt_dump (fmth) +register struct format *fmth; +{ + int i; + register struct format *fmt, *addr; + + /* Assign labels */ + for (fmt = fmth; fmt; ++fmt) { + i = fmt->f_type; + if (i == FT_IF_S || + i == FT_IF_S_NULL || + i == FT_IF_V_EQ || + i == FT_IF_V_NE || + i == FT_IF_V_GT || + i == FT_IF_MATCH || + i == FT_IF_AMATCH || + i == FT_GOTO) { + addr = fmt + fmt->f_skip; + if (findlabel(addr) < 0) + assignlabel(addr); + } + if (fmt->f_type == FT_DONE && fmt->f_value == 0) + break; + } + + /* Dump them out! */ + for (fmt = fmth; fmt; ++fmt) { + dumpone(fmt); + if (fmt->f_type == FT_DONE && fmt->f_value == 0) + break; + } +} + +static void +dumpone(fmt) + register struct format *fmt; +{ + register int i; + + if ((i = findlabel(fmt)) >= 0) + printf("L%d:", i); + putchar('\t'); + + fputs(f_typestr((int)fmt->f_type), stdout); + + switch (fmt->f_type) { + + case FT_COMP: + case FT_LS_COMP: + case FT_LV_COMPFLAG: + case FT_LV_COMP: + printf(", comp "); + litputs(fmt->f_comp->c_name); + if (fmt->f_comp->c_type) + printf(", c_type %s", c_typestr(fmt->f_comp->c_type)); + if (fmt->f_comp->c_flags) + printf(", c_flags %d", fmt->f_comp->c_flags); + break; + + case FT_LV_SEC: + case FT_LV_MIN: + case FT_LV_HOUR: + case FT_LV_MDAY: + case FT_LV_MON: + case FT_LS_MONTH: + case FT_LS_LMONTH: + case FT_LS_ZONE: + case FT_LV_YEAR: + case FT_LV_WDAY: + case FT_LS_DAY: + case FT_LS_WEEKDAY: + case FT_LV_YDAY: + case FT_LV_ZONE: + case FT_LV_CLOCK: + case FT_LV_RCLOCK: + case FT_LV_DAYF: + case FT_LV_ZONEF: + case FT_LV_DST: + case FT_LS_822DATE: + case FT_LS_PRETTY: + case FT_LOCALDATE: + case FT_GMTDATE: + case FT_PARSEDATE: + printf(", c_name "); + litputs(fmt->f_comp->c_name); + if (fmt->f_comp->c_type) + printf(", c_type %s", c_typestr(fmt->f_comp->c_type)); + if (fmt->f_comp->c_flags) + printf(", c_flags %d", fmt->f_comp->c_flags); + break; + + case FT_LS_ADDR: + case FT_LS_PERS: + case FT_LS_MBOX: + case FT_LS_HOST: + case FT_LS_PATH: + case FT_LS_GNAME: + case FT_LS_NOTE: + case FT_LS_822ADDR: + case FT_LV_HOSTTYPE: + case FT_LV_INGRPF: + case FT_LV_NOHOSTF: + case FT_LS_FRIENDLY: + case FT_PARSEADDR: + case FT_MYMBOX: + printf(", c_name "); + litputs(fmt->f_comp->c_name); + if (fmt->f_comp->c_type) + printf(", c_type %s", c_typestr(fmt->f_comp->c_type)); + if (fmt->f_comp->c_flags) + printf(", c_flags %d", fmt->f_comp->c_flags); + break; + + case FT_COMPF: + printf(", width %d, fill '", fmt->f_width); + litputc(fmt->f_fill); + printf("' name "); + litputs(fmt->f_comp->c_name); + if (fmt->f_comp->c_type) + printf(", c_type %s", c_typestr(fmt->f_comp->c_type)); + if (fmt->f_comp->c_flags) + printf(", c_flags %d", fmt->f_comp->c_flags); + break; + + case FT_STRF: + case FT_NUMF: + printf(", width %d, fill '", fmt->f_width); + litputc(fmt->f_fill); + putchar('\''); + break; + + case FT_LIT: +#ifdef FT_LIT_FORCE + case FT_LIT_FORCE: +#endif + putchar(' '); + litputs(fmt->f_text); + break; + + case FT_LITF: + printf(", width %d, fill '", fmt->f_width); + litputc(fmt->f_fill); + printf("' "); + litputs(fmt->f_text); + break; + + case FT_CHAR: + putchar(' '); + putchar('\''); + litputc(fmt->f_char); + putchar('\''); + break; + + + case FT_IF_S: + case FT_IF_S_NULL: + case FT_IF_MATCH: + case FT_IF_AMATCH: + printf(" continue else goto"); + case FT_GOTO: + i = findlabel(fmt + fmt->f_skip); + printf(" L%d", i); + break; + + case FT_IF_V_EQ: + case FT_IF_V_NE: + case FT_IF_V_GT: + i = findlabel(fmt + fmt->f_skip); + printf(" %d continue else goto L%d", fmt->f_value, i); + break; + + case FT_V_EQ: + case FT_V_NE: + case FT_V_GT: + case FT_LV_LIT: + case FT_LV_PLUS_L: + case FT_LV_MINUS_L: + case FT_LV_DIVIDE_L: + case FT_LV_MODULO_L: + printf(" value %d", fmt->f_value); + break; + + case FT_LS_LIT: + printf(" str "); + litputs(fmt->f_text); + break; + + case FT_LS_GETENV: + printf(" getenv "); + litputs(fmt->f_text); + break; + + case FT_LS_TRIM: + printf(", width %d", fmt->f_width); + break; + + case FT_LV_DAT: + printf(", value dat[%d]", fmt->f_value); + break; + } + putchar('\n'); +} + +static int +findlabel(addr) + register struct format *addr; +{ + register int i; + + for (i = 0; i < lused; ++i) + if (addr == lvec[i]) + return(i); + return(-1); +} + +static void +assignlabel(addr) + register struct format *addr; +{ + lvec[lused++] = addr; +} + +static char * +f_typestr(t) + int t; +{ + static char buf[32]; + + switch (t) { + case FT_COMP: return("COMP"); + case FT_COMPF: return("COMPF"); + case FT_LIT: return("LIT"); + case FT_LITF: return("LITF"); +#ifdef FT_LIT_FORCE + case FT_LIT_FORCE: return("LIT_FORCE"); +#endif + case FT_CHAR: return("CHAR"); + case FT_NUM: return("NUM"); + case FT_NUMF: return("NUMF"); + case FT_STR: return("STR"); + case FT_STRF: return("STRF"); + case FT_STRFW: return("STRFW"); + case FT_PUTADDR: return("PUTADDR"); + case FT_LS_COMP: return("LS_COMP"); + case FT_LS_LIT: return("LS_LIT"); + case FT_LS_GETENV: return("LS_GETENV"); + case FT_LS_TRIM: return("LS_TRIM"); + case FT_LV_COMP: return("LV_COMP"); + case FT_LV_COMPFLAG: return("LV_COMPFLAG"); + case FT_LV_LIT: return("LV_LIT"); + case FT_LV_DAT: return("LV_DAT"); + case FT_LV_STRLEN: return("LV_STRLEN"); + case FT_LV_PLUS_L: return("LV_PLUS_L"); + case FT_LV_MINUS_L: return("LV_MINUS_L"); + case FT_LV_DIVIDE_L: return("LV_DIVIDE_L"); + case FT_LV_MODULO_L: return("LV_MODULO_L"); + case FT_LV_CHAR_LEFT: return("LV_CHAR_LEFT"); + case FT_LS_MONTH: return("LS_MONTH"); + case FT_LS_LMONTH: return("LS_LMONTH"); + case FT_LS_ZONE: return("LS_ZONE"); + case FT_LS_DAY: return("LS_DAY"); + case FT_LS_WEEKDAY: return("LS_WEEKDAY"); + case FT_LS_822DATE: return("LS_822DATE"); + case FT_LS_PRETTY: return("LS_PRETTY"); + case FT_LV_SEC: return("LV_SEC"); + case FT_LV_MIN: return("LV_MIN"); + case FT_LV_HOUR: return("LV_HOUR"); + case FT_LV_MDAY: return("LV_MDAY"); + case FT_LV_MON: return("LV_MON"); + case FT_LV_YEAR: return("LV_YEAR"); + case FT_LV_YDAY: return("LV_YDAY"); + case FT_LV_WDAY: return("LV_WDAY"); + case FT_LV_ZONE: return("LV_ZONE"); + case FT_LV_CLOCK: return("LV_CLOCK"); + case FT_LV_RCLOCK: return("LV_RCLOCK"); + case FT_LV_DAYF: return("LV_DAYF"); + case FT_LV_DST: return("LV_DST"); + case FT_LV_ZONEF: return("LV_ZONEF"); + case FT_LS_ADDR: return("LS_ADDR"); + case FT_LS_PERS: return("LS_PERS"); + case FT_LS_MBOX: return("LS_MBOX"); + case FT_LS_HOST: return("LS_HOST"); + case FT_LS_PATH: return("LS_PATH"); + case FT_LS_GNAME: return("LS_GNAME"); + case FT_LS_NOTE: return("LS_NOTE"); + case FT_LS_822ADDR: return("LS_822ADDR"); + case FT_LS_FRIENDLY: return("LS_FRIENDLY"); + case FT_LV_HOSTTYPE: return("LV_HOSTTYPE"); + case FT_LV_INGRPF: return("LV_INGRPF"); + case FT_LV_NOHOSTF: return("LV_NOHOSTF"); + case FT_LOCALDATE: return("LOCALDATE"); + case FT_GMTDATE: return("GMTDATE"); + case FT_PARSEDATE: return("PARSEDATE"); + case FT_PARSEADDR: return("PARSEADDR"); + case FT_FORMATADDR: return("FORMATADDR"); + case FT_MYMBOX: return("MYMBOX"); +#ifdef FT_ADDTOSEQ + case FT_ADDTOSEQ: return("ADDTOSEQ"); +#endif + case FT_SAVESTR: return("SAVESTR"); +#ifdef FT_PAUSE + case FT_PAUSE: return ("PAUSE"); +#endif + case FT_DONE: return("DONE"); + case FT_NOP: return("NOP"); + case FT_GOTO: return("GOTO"); + case FT_IF_S_NULL: return("IF_S_NULL"); + case FT_IF_S: return("IF_S"); + case FT_IF_V_EQ: return("IF_V_EQ"); + case FT_IF_V_NE: return("IF_V_NE"); + case FT_IF_V_GT: return("IF_V_GT"); + case FT_IF_MATCH: return("IF_MATCH"); + case FT_IF_AMATCH: return("IF_AMATCH"); + case FT_S_NULL: return("S_NULL"); + case FT_S_NONNULL: return("S_NONNULL"); + case FT_V_EQ: return("V_EQ"); + case FT_V_NE: return("V_NE"); + case FT_V_GT: return("V_GT"); + case FT_V_MATCH: return("V_MATCH"); + case FT_V_AMATCH: return("V_AMATCH"); +#ifdef MIME_HEADERS + case FT_LS_HENCODE: return("LS_HENCODE"); + case FT_LS_HDECODE: return("LS_HDECODE"); +#endif /* MIME_HEADERS */ + default: + (void)sprintf(buf, "/* ??? #%d */", t); + return(buf); + } +} + +#define FNORD(v, s) if (t & (v)) { \ + if (i++ > 0) \ + strcat(buf, "|"); \ + strcat(buf, s); } + +static char * +c_typestr(t) + int t; +{ + register int i; + static char buf[64]; + + buf[0] = '\0'; + if (t & ~(CT_ADDR|CT_DATE|CT_MYMBOX|CT_ADDRPARSE)) + (void)sprintf(buf, "0x%x ", t); + strcat(buf, "<"); + i = 0; + FNORD(CT_ADDR, "ADDR"); + FNORD(CT_DATE, "DATE"); + FNORD(CT_MYMBOX, "MYMBOX"); + FNORD(CT_ADDRPARSE, "ADDRPARSE"); + strcat(buf, ">"); + return(buf); +#undef FNORD +} + +static void +litputs(s) + register char *s; +{ + if (s) { + putc('"', stdout); +#ifdef JAPAN + ml_pretty_fputs(s, stdout); +#else /* JAPAN */ + while (*s) + litputc(*s++); +#endif /* JAPAN */ + putc('"', stdout); + } else + fputs("<nil>", stdout); +} + +static void +litputc(c) + char c; +{ + if (c & ~ 0177) { + putc('M', stdout); + putc('-', stdout); + c &= 0177; + } + if (c < 0x20 || c == 0177) { + if (c == '\b') { + putc('\\', stdout); + putc('b', stdout); + } else if (c == '\f') { + putc('\\', stdout); + putc('f', stdout); + } else if (c == '\n') { + putc('\\', stdout); + putc('n', stdout); + } else if (c == '\r') { + putc('\\', stdout); + putc('r', stdout); + } else if (c == '\t') { + putc('\\', stdout); + putc('t', stdout); + } else { + putc('^', stdout); + putc(c ^ 0x40, stdout); /* DEL to ?, others to alpha */ + } + } else + putc(c, stdout); +}