source: trunk/third/nmh/uip/fmtdump.c @ 12455

Revision 12455, 11.0 KB checked in by danw, 26 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r12454, which included commits to RCS files with non-trunk default branches.
Line 
1
2/*
3 * fmtdump.c -- compile format file and dump out instructions
4 *
5 * $Id: fmtdump.c,v 1.1.1.1 1999-02-07 18:14:13 danw Exp $
6 */
7
8#include <h/mh.h>
9#include <h/fmt_scan.h>
10#include <h/fmt_compile.h>
11#include <h/scansbr.h>
12
13static struct swit switches[] = {
14#define FORMSW              0
15    { "form formatfile", 0 },
16#define FMTSW               1
17    { "format string", 5 },
18#define VERSIONSW           2
19    { "version", 0 },
20#define HELPSW              3
21    { "help", 4 },
22    { NULL, 0 }
23};
24
25/* for assignlabel */
26static struct format *lvec[128];
27static lused = 0;
28
29/*
30 * static prototypes
31 */
32static void fmt_dump (struct format *);
33static void dumpone(struct format *);
34static int findlabel(struct format *);
35static void assignlabel(struct format *);
36static char *f_typestr(int);
37static char *c_typestr(int);
38static void litputs(char *);
39static void litputc(char);
40
41
42int
43main (int argc, char **argv)
44{
45    int ncomps;
46    char *cp, *form = NULL, *format = NULL;
47    char buf[BUFSIZ], *nfs, **argp, **arguments;
48    struct format *fmt;
49
50#ifdef LOCALE
51    setlocale(LC_ALL, "");
52#endif
53    invo_name = r1bindex (argv[0], '/');
54
55    /* read user profile/context */
56    context_read();
57
58    arguments = getarguments (invo_name, argc, argv, 1);
59    argp = arguments;
60
61    while ((cp = *argp++)) {
62        if (*cp == '-') {
63            switch (smatch (++cp, switches)) {
64                case AMBIGSW:
65                    ambigsw (cp, switches);
66                    done (1);
67                case UNKWNSW:
68                    adios (NULL, "-%s unknown", cp);
69
70                case HELPSW:
71                    snprintf (buf, sizeof(buf), "%s [switches]", invo_name);
72                    print_help (buf, switches, 1);
73                    done (1);
74                case VERSIONSW:
75                    print_version(invo_name);
76                    done (1);
77
78                case FORMSW:
79                    if (!(form = *argp++) || *form == '-')
80                        adios (NULL, "missing argument to %s", argp[-2]);
81                    format = NULL;
82                    continue;
83                case FMTSW:
84                    if (!(format = *argp++) || *format == '-')
85                        adios (NULL, "missing argument to %s", argp[-2]);
86                    form = NULL;
87                    continue;
88
89            }
90        }
91        if (form)
92            adios (NULL, "only one form at a time!");
93        else
94            form = cp;
95    }
96
97    /*
98     * Get new format string.  Must be before chdir().
99     */
100    nfs = new_fs (form, format, FORMAT);
101    ncomps = fmt_compile(nfs, &fmt);
102
103    fmt_dump(fmt);
104    done(0);
105}
106
107static void
108fmt_dump (struct format *fmth)
109{
110        int i;
111        register struct format *fmt, *addr;
112
113        /* Assign labels */
114        for (fmt = fmth; fmt; ++fmt) {
115                i = fmt->f_type;
116                if (i == FT_IF_S ||
117                    i == FT_IF_S_NULL ||
118                    i == FT_IF_V_EQ ||
119                    i == FT_IF_V_NE ||
120                    i == FT_IF_V_GT ||
121                    i == FT_IF_MATCH ||
122                    i == FT_IF_AMATCH ||
123                    i == FT_GOTO) {
124                        addr = fmt + fmt->f_skip;
125                        if (findlabel(addr) < 0)
126                                assignlabel(addr);
127                }
128                if (fmt->f_type == FT_DONE && fmt->f_value == 0)
129                        break;
130        }
131
132        /* Dump them out! */
133        for (fmt = fmth; fmt; ++fmt) {
134                dumpone(fmt);
135                if (fmt->f_type == FT_DONE && fmt->f_value == 0)
136                        break;
137        }
138}
139
140static void
141dumpone(struct format *fmt)
142{
143        register int i;
144
145        if ((i = findlabel(fmt)) >= 0)
146                printf("L%d:", i);
147        putchar('\t');
148
149        fputs(f_typestr((int)fmt->f_type), stdout);
150
151        switch (fmt->f_type) {
152
153        case FT_COMP:
154        case FT_LS_COMP:
155        case FT_LV_COMPFLAG:
156        case FT_LV_COMP:
157                printf(", comp ");
158                litputs(fmt->f_comp->c_name);
159                if (fmt->f_comp->c_type)
160                        printf(", c_type %s", c_typestr(fmt->f_comp->c_type));
161                if (fmt->f_comp->c_flags)
162                        printf(", c_flags %d", fmt->f_comp->c_flags);
163                break;
164
165        case FT_LV_SEC:
166        case FT_LV_MIN:
167        case FT_LV_HOUR:
168        case FT_LV_MDAY:
169        case FT_LV_MON:
170        case FT_LS_MONTH:
171        case FT_LS_LMONTH:
172        case FT_LS_ZONE:
173        case FT_LV_YEAR:
174        case FT_LV_WDAY:
175        case FT_LS_DAY:
176        case FT_LS_WEEKDAY:
177        case FT_LV_YDAY:
178        case FT_LV_ZONE:
179        case FT_LV_CLOCK:
180        case FT_LV_RCLOCK:
181        case FT_LV_DAYF:
182        case FT_LV_ZONEF:
183        case FT_LV_DST:
184        case FT_LS_822DATE:
185        case FT_LS_PRETTY:
186        case FT_LOCALDATE:
187        case FT_GMTDATE:
188        case FT_PARSEDATE:
189                printf(", c_name ");
190                litputs(fmt->f_comp->c_name);
191                if (fmt->f_comp->c_type)
192                        printf(", c_type %s", c_typestr(fmt->f_comp->c_type));
193                if (fmt->f_comp->c_flags)
194                        printf(", c_flags %d", fmt->f_comp->c_flags);
195                break;
196
197        case FT_LS_ADDR:
198        case FT_LS_PERS:
199        case FT_LS_MBOX:
200        case FT_LS_HOST:
201        case FT_LS_PATH:
202        case FT_LS_GNAME:
203        case FT_LS_NOTE:
204        case FT_LS_822ADDR:
205        case FT_LV_HOSTTYPE:
206        case FT_LV_INGRPF:
207        case FT_LV_NOHOSTF:
208        case FT_LS_FRIENDLY:
209        case FT_PARSEADDR:
210        case FT_MYMBOX:
211                printf(", c_name ");
212                litputs(fmt->f_comp->c_name);
213                if (fmt->f_comp->c_type)
214                        printf(", c_type %s", c_typestr(fmt->f_comp->c_type));
215                if (fmt->f_comp->c_flags)
216                        printf(", c_flags %d", fmt->f_comp->c_flags);
217                break;
218
219        case FT_COMPF:
220                printf(", width %d, fill '", fmt->f_width);
221                litputc(fmt->f_fill);
222                printf("' name ");
223                litputs(fmt->f_comp->c_name);
224                if (fmt->f_comp->c_type)
225                        printf(", c_type %s", c_typestr(fmt->f_comp->c_type));
226                if (fmt->f_comp->c_flags)
227                        printf(", c_flags %d", fmt->f_comp->c_flags);
228                break;
229
230        case FT_STRF:
231        case FT_NUMF:
232                printf(", width %d, fill '", fmt->f_width);
233                litputc(fmt->f_fill);
234                putchar('\'');
235                break;
236
237        case FT_LIT:
238#ifdef FT_LIT_FORCE
239        case FT_LIT_FORCE:
240#endif
241                putchar(' ');
242                litputs(fmt->f_text);
243                break;
244
245        case FT_LITF:
246                printf(", width %d, fill '", fmt->f_width);
247                litputc(fmt->f_fill);
248                printf("' ");
249                litputs(fmt->f_text);
250                break;
251
252        case FT_CHAR:
253                putchar(' ');
254                putchar('\'');
255                litputc(fmt->f_char);
256                putchar('\'');
257                break;
258
259
260        case FT_IF_S:
261        case FT_IF_S_NULL:
262        case FT_IF_MATCH:
263        case FT_IF_AMATCH:
264                printf(" continue else goto");
265        case FT_GOTO:
266                i = findlabel(fmt + fmt->f_skip);
267                printf(" L%d", i);
268                break;
269
270        case FT_IF_V_EQ:
271        case FT_IF_V_NE:
272        case FT_IF_V_GT:
273                i = findlabel(fmt + fmt->f_skip);
274                printf(" %d continue else goto L%d", fmt->f_value, i);
275                break;
276
277        case FT_V_EQ:
278        case FT_V_NE:
279        case FT_V_GT:
280        case FT_LV_LIT:
281        case FT_LV_PLUS_L:
282        case FT_LV_MINUS_L:
283        case FT_LV_DIVIDE_L:
284        case FT_LV_MODULO_L:
285                printf(" value %d", fmt->f_value);
286                break;
287
288        case FT_LS_LIT:
289                printf(" str ");
290                litputs(fmt->f_text);
291                break;
292
293        case FT_LS_GETENV:
294                printf(" getenv ");
295                litputs(fmt->f_text);
296                break;
297
298        case FT_LS_DECODECOMP:
299                printf(", comp ");
300                litputs(fmt->f_comp->c_name);
301                break;
302
303        case FT_LS_DECODE:
304                break;
305
306        case FT_LS_TRIM:
307                printf(", width %d", fmt->f_width);
308                break;
309
310        case FT_LV_DAT:
311                printf(", value dat[%d]", fmt->f_value);
312                break;
313        }
314        putchar('\n');
315}
316
317static int
318findlabel(struct format *addr)
319{
320        register int i;
321
322        for (i = 0; i < lused; ++i)
323                if (addr == lvec[i])
324                        return(i);
325        return(-1);
326}
327
328static void
329assignlabel(struct format *addr)
330{
331        lvec[lused++] = addr;
332}
333
334static char *
335f_typestr(int t)
336{
337        static char buf[32];
338
339        switch (t) {
340        case FT_COMP: return("COMP");
341        case FT_COMPF: return("COMPF");
342        case FT_LIT: return("LIT");
343        case FT_LITF: return("LITF");
344#ifdef  FT_LIT_FORCE
345        case FT_LIT_FORCE: return("LIT_FORCE");
346#endif
347        case FT_CHAR: return("CHAR");
348        case FT_NUM: return("NUM");
349        case FT_NUMF: return("NUMF");
350        case FT_STR: return("STR");
351        case FT_STRF: return("STRF");
352        case FT_STRFW: return("STRFW");
353        case FT_PUTADDR: return("PUTADDR");
354        case FT_LS_COMP: return("LS_COMP");
355        case FT_LS_LIT: return("LS_LIT");
356        case FT_LS_GETENV: return("LS_GETENV");
357        case FT_LS_DECODECOMP: return("FT_LS_DECODECOMP");
358        case FT_LS_DECODE: return("FT_LS_DECODE");
359        case FT_LS_TRIM: return("LS_TRIM");
360        case FT_LV_COMP: return("LV_COMP");
361        case FT_LV_COMPFLAG: return("LV_COMPFLAG");
362        case FT_LV_LIT: return("LV_LIT");
363        case FT_LV_DAT: return("LV_DAT");
364        case FT_LV_STRLEN: return("LV_STRLEN");
365        case FT_LV_PLUS_L: return("LV_PLUS_L");
366        case FT_LV_MINUS_L: return("LV_MINUS_L");
367        case FT_LV_DIVIDE_L: return("LV_DIVIDE_L");
368        case FT_LV_MODULO_L: return("LV_MODULO_L");
369        case FT_LV_CHAR_LEFT: return("LV_CHAR_LEFT");
370        case FT_LS_MONTH: return("LS_MONTH");
371        case FT_LS_LMONTH: return("LS_LMONTH");
372        case FT_LS_ZONE: return("LS_ZONE");
373        case FT_LS_DAY: return("LS_DAY");
374        case FT_LS_WEEKDAY: return("LS_WEEKDAY");
375        case FT_LS_822DATE: return("LS_822DATE");
376        case FT_LS_PRETTY: return("LS_PRETTY");
377        case FT_LV_SEC: return("LV_SEC");
378        case FT_LV_MIN: return("LV_MIN");
379        case FT_LV_HOUR: return("LV_HOUR");
380        case FT_LV_MDAY: return("LV_MDAY");
381        case FT_LV_MON: return("LV_MON");
382        case FT_LV_YEAR: return("LV_YEAR");
383        case FT_LV_YDAY: return("LV_YDAY");
384        case FT_LV_WDAY: return("LV_WDAY");
385        case FT_LV_ZONE: return("LV_ZONE");
386        case FT_LV_CLOCK: return("LV_CLOCK");
387        case FT_LV_RCLOCK: return("LV_RCLOCK");
388        case FT_LV_DAYF: return("LV_DAYF");
389        case FT_LV_DST: return("LV_DST");
390        case FT_LV_ZONEF: return("LV_ZONEF");
391        case FT_LS_ADDR: return("LS_ADDR");
392        case FT_LS_PERS: return("LS_PERS");
393        case FT_LS_MBOX: return("LS_MBOX");
394        case FT_LS_HOST: return("LS_HOST");
395        case FT_LS_PATH: return("LS_PATH");
396        case FT_LS_GNAME: return("LS_GNAME");
397        case FT_LS_NOTE: return("LS_NOTE");
398        case FT_LS_822ADDR: return("LS_822ADDR");
399        case FT_LS_FRIENDLY: return("LS_FRIENDLY");
400        case FT_LV_HOSTTYPE: return("LV_HOSTTYPE");
401        case FT_LV_INGRPF: return("LV_INGRPF");
402        case FT_LV_NOHOSTF: return("LV_NOHOSTF");
403        case FT_LOCALDATE: return("LOCALDATE");
404        case FT_GMTDATE: return("GMTDATE");
405        case FT_PARSEDATE: return("PARSEDATE");
406        case FT_PARSEADDR: return("PARSEADDR");
407        case FT_FORMATADDR: return("FORMATADDR");
408        case FT_MYMBOX: return("MYMBOX");
409#ifdef  FT_ADDTOSEQ
410        case FT_ADDTOSEQ: return("ADDTOSEQ");
411#endif
412        case FT_SAVESTR: return("SAVESTR");
413#ifdef  FT_PAUSE
414        case FT_PAUSE: return ("PAUSE");
415#endif
416        case FT_DONE: return("DONE");
417        case FT_NOP: return("NOP");
418        case FT_GOTO: return("GOTO");
419        case FT_IF_S_NULL: return("IF_S_NULL");
420        case FT_IF_S: return("IF_S");
421        case FT_IF_V_EQ: return("IF_V_EQ");
422        case FT_IF_V_NE: return("IF_V_NE");
423        case FT_IF_V_GT: return("IF_V_GT");
424        case FT_IF_MATCH: return("IF_MATCH");
425        case FT_IF_AMATCH: return("IF_AMATCH");
426        case FT_S_NULL: return("S_NULL");
427        case FT_S_NONNULL: return("S_NONNULL");
428        case FT_V_EQ: return("V_EQ");
429        case FT_V_NE: return("V_NE");
430        case FT_V_GT: return("V_GT");
431        case FT_V_MATCH: return("V_MATCH");
432        case FT_V_AMATCH: return("V_AMATCH");
433        default:
434                printf(buf, "/* ??? #%d */", t);
435                return(buf);
436        }
437}
438
439#define FNORD(v, s) if (t & (v)) { \
440        if (i++ > 0) \
441                strcat(buf, "|"); \
442        strcat(buf, s); }
443
444static char *
445c_typestr(int t)
446{
447        register int i;
448        static char buf[64];
449
450        buf[0] = '\0';
451        if (t & ~(CT_ADDR|CT_DATE|CT_MYMBOX|CT_ADDRPARSE))
452                printf(buf, "0x%x ", t);
453        strcat(buf, "<");
454        i = 0;
455        FNORD(CT_ADDR, "ADDR");
456        FNORD(CT_DATE, "DATE");
457        FNORD(CT_MYMBOX, "MYMBOX");
458        FNORD(CT_ADDRPARSE, "ADDRPARSE");
459        strcat(buf, ">");
460        return(buf);
461#undef FNORD
462}
463
464static void
465litputs(char *s)
466{
467        if (s) {
468                putc('"', stdout);
469                while (*s)
470                        litputc(*s++);
471                putc('"', stdout);
472        } else
473                fputs("<nil>", stdout);
474}
475
476static void
477litputc(char c)
478{
479        if (c & ~ 0177) {
480                putc('M', stdout);
481                putc('-', stdout);
482                c &= 0177;
483        }
484        if (c < 0x20 || c == 0177) {
485                if (c == '\b') {
486                        putc('\\', stdout);
487                        putc('b', stdout);
488                } else if (c == '\f') {
489                        putc('\\', stdout);
490                        putc('f', stdout);
491                } else if (c == '\n') {
492                        putc('\\', stdout);
493                        putc('n', stdout);
494                } else if (c == '\r') {
495                        putc('\\', stdout);
496                        putc('r', stdout);
497                } else if (c == '\t') {
498                        putc('\\', stdout);
499                        putc('t', stdout);
500                } else {
501                        putc('^', stdout);
502                        putc(c ^ 0x40, stdout); /* DEL to ?, others to alpha */
503                }
504        } else
505                putc(c, stdout);
506}
Note: See TracBrowser for help on using the repository browser.