(mh_format_dump): New function. Produces the
listing of compiled format code. (builtin_me, builtin_profile, builtin_putstr, print_string, builtin_putnum, builtin_putnumf, builtin_tws, builtin_pretty): Implemented. (builtin_pers): Enclose the return in a pair of double-quotes.
Showing
1 changed file
with
289 additions
and
12 deletions
... | @@ -52,6 +52,8 @@ struct mh_machine | ... | @@ -52,6 +52,8 @@ struct mh_machine |
52 | size_t msgno; /* Its number */ | 52 | size_t msgno; /* Its number */ |
53 | }; | 53 | }; |
54 | 54 | ||
55 | static char *_get_builtin_name __P((mh_builtin_fp ptr)); | ||
56 | |||
55 | /* Functions for handling string objects. */ | 57 | /* Functions for handling string objects. */ |
56 | 58 | ||
57 | void | 59 | void |
... | @@ -410,6 +412,180 @@ mh_format (mh_format_t *fmt, message_t msg, size_t msgno, | ... | @@ -410,6 +412,180 @@ mh_format (mh_format_t *fmt, message_t msg, size_t msgno, |
410 | return mach.ind; | 412 | return mach.ind; |
411 | } | 413 | } |
412 | 414 | ||
415 | void | ||
416 | mh_format_dump (mh_format_t *fmt) | ||
417 | { | ||
418 | mh_instr_t *prog = fmt->prog; | ||
419 | size_t pc = 1; | ||
420 | int stop = 0; | ||
421 | |||
422 | while (!stop) | ||
423 | { | ||
424 | mh_opcode_t opcode; | ||
425 | int num; | ||
426 | |||
427 | printf ("% 4.4ld: ", (long) pc); | ||
428 | switch (opcode = MHI_OPCODE(prog[pc++])) | ||
429 | { | ||
430 | case mhop_stop: | ||
431 | printf ("stop"); | ||
432 | stop = 1; | ||
433 | break; | ||
434 | |||
435 | case mhop_branch: | ||
436 | num = MHI_NUM(prog[pc++]); | ||
437 | printf ("branch %d, %lu", | ||
438 | num, (unsigned long) pc + num - 1); | ||
439 | break; | ||
440 | |||
441 | case mhop_num_asgn: | ||
442 | printf ("num_asgn"); | ||
443 | break; | ||
444 | |||
445 | case mhop_str_asgn: | ||
446 | printf ("str_asgn"); | ||
447 | break; | ||
448 | |||
449 | case mhop_num_arg: | ||
450 | num = MHI_NUM(prog[pc++]); | ||
451 | printf ("num_arg %d", num); | ||
452 | break; | ||
453 | |||
454 | case mhop_str_arg: | ||
455 | { | ||
456 | size_t skip = MHI_NUM(prog[pc++]); | ||
457 | char *s = MHI_STR(prog[pc]); | ||
458 | printf ("str_arg \""); | ||
459 | for (; *s; s++) | ||
460 | { | ||
461 | switch (*s) | ||
462 | { | ||
463 | case '\a': | ||
464 | printf ("\\a"); | ||
465 | break; | ||
466 | |||
467 | case '\b': | ||
468 | printf ("\\b"); | ||
469 | break; | ||
470 | |||
471 | case '\f': | ||
472 | printf ("\\f"); | ||
473 | break; | ||
474 | |||
475 | case '\n': | ||
476 | printf ("\\n"); | ||
477 | break; | ||
478 | |||
479 | case '\r': | ||
480 | printf ("\\r"); | ||
481 | break; | ||
482 | |||
483 | case '\t': | ||
484 | printf ("\\t"); | ||
485 | break; | ||
486 | |||
487 | case '"': | ||
488 | printf ("\\\""); | ||
489 | break; | ||
490 | |||
491 | default: | ||
492 | if (isprint (*s)) | ||
493 | putchar (*s); | ||
494 | else | ||
495 | printf ("\\%03o", *s); | ||
496 | break; | ||
497 | } | ||
498 | } | ||
499 | printf ("\""); | ||
500 | pc += skip; | ||
501 | } | ||
502 | break; | ||
503 | |||
504 | case mhop_num_branch: | ||
505 | num = MHI_NUM(prog[pc++]); | ||
506 | printf ("num_branch %d, %lu", | ||
507 | num, (unsigned long) (pc + num - 1)); | ||
508 | break; | ||
509 | |||
510 | case mhop_str_branch: | ||
511 | num = MHI_NUM(prog[pc++]); | ||
512 | printf ("str_branch %d, %lu", | ||
513 | num, (unsigned long) (pc + num - 1)); | ||
514 | break; | ||
515 | |||
516 | case mhop_call: | ||
517 | { | ||
518 | char *name = _get_builtin_name (MHI_BUILTIN (prog[pc++])); | ||
519 | printf ("call %s", name ? name : "UNKNOWN"); | ||
520 | } | ||
521 | break; | ||
522 | |||
523 | case mhop_header: | ||
524 | printf ("header"); | ||
525 | break; | ||
526 | |||
527 | case mhop_body: | ||
528 | printf ("body"); | ||
529 | |||
530 | case mhop_num_to_arg: | ||
531 | printf ("num_to_arg"); | ||
532 | break; | ||
533 | |||
534 | /* assign reg_str to arg_str */ | ||
535 | case mhop_str_to_arg: | ||
536 | printf ("str_to_arg"); | ||
537 | break; | ||
538 | |||
539 | /* Convert arg_str to arg_num */ | ||
540 | case mhop_str_to_num: | ||
541 | printf ("str_to_num"); | ||
542 | break; | ||
543 | |||
544 | /* Convert arg_num to arg_str */ | ||
545 | case mhop_num_to_str: | ||
546 | printf ("num_to_str"); | ||
547 | break; | ||
548 | |||
549 | case mhop_num_print: | ||
550 | printf ("print"); | ||
551 | break; | ||
552 | |||
553 | case mhop_str_print: | ||
554 | printf ("str_print"); | ||
555 | break; | ||
556 | |||
557 | case mhop_fmtspec: | ||
558 | { | ||
559 | int space = 0; | ||
560 | |||
561 | num = MHI_NUM(prog[pc++]); | ||
562 | printf ("fmtspec: %#x, ", num); | ||
563 | if (num & MH_FMT_RALIGN) | ||
564 | { | ||
565 | printf ("MH_FMT_RALIGN"); | ||
566 | space++; | ||
567 | } | ||
568 | if (num & MH_FMT_ZEROPAD) | ||
569 | { | ||
570 | if (space) | ||
571 | printf ("|"); | ||
572 | printf ("MH_FMT_ZEROPAD"); | ||
573 | space++; | ||
574 | } | ||
575 | if (space) | ||
576 | printf ("; "); | ||
577 | printf ("%d", num & MH_WIDTH_MASK); | ||
578 | } | ||
579 | break; | ||
580 | |||
581 | default: | ||
582 | mh_error ("Unknown opcode: %x", opcode); | ||
583 | abort (); | ||
584 | } | ||
585 | printf ("\n"); | ||
586 | } | ||
587 | } | ||
588 | |||
413 | /* Free any memory associated with a format structure. The structure | 589 | /* Free any memory associated with a format structure. The structure |
414 | itself is assumed to be in static storage. */ | 590 | itself is assumed to be in static storage. */ |
415 | void | 591 | void |
... | @@ -482,8 +658,9 @@ builtin_timenow (struct mh_machine *mach) | ... | @@ -482,8 +658,9 @@ builtin_timenow (struct mh_machine *mach) |
482 | static void | 658 | static void |
483 | builtin_me (struct mh_machine *mach) | 659 | builtin_me (struct mh_machine *mach) |
484 | { | 660 | { |
485 | /*FIXME*/ | 661 | char *s = mh_my_email (); |
486 | /* mach->arg_str = "me";*/ | 662 | strobj_free (&mach->arg_str); |
663 | strobj_create (&mach->arg_str, s); | ||
487 | } | 664 | } |
488 | 665 | ||
489 | static void | 666 | static void |
... | @@ -578,8 +755,9 @@ builtin_getenv (struct mh_machine *mach) | ... | @@ -578,8 +755,9 @@ builtin_getenv (struct mh_machine *mach) |
578 | static void | 755 | static void |
579 | builtin_profile (struct mh_machine *mach) | 756 | builtin_profile (struct mh_machine *mach) |
580 | { | 757 | { |
581 | /*FIXME*/ | 758 | char *val = strobj_ptr (&mach->arg_str); |
582 | /*mach->arg_str = "profile";*/ | 759 | strobj_free (&mach->arg_str); |
760 | strobj_create (&mach->arg_str, mh_global_profile_get (val, "")); | ||
583 | } | 761 | } |
584 | 762 | ||
585 | static void | 763 | static void |
... | @@ -645,28 +823,36 @@ builtin_trim (struct mh_machine *mach) | ... | @@ -645,28 +823,36 @@ builtin_trim (struct mh_machine *mach) |
645 | static void | 823 | static void |
646 | builtin_putstr (struct mh_machine *mach) | 824 | builtin_putstr (struct mh_machine *mach) |
647 | { | 825 | { |
648 | /*FIXME*/ | 826 | print_string (mach, 0, |
827 | strobj_ptr (&mach->arg_str), strobj_len (&mach->arg_str)); | ||
649 | } | 828 | } |
650 | 829 | ||
651 | /* putstrf expr print str in a fixed width*/ | 830 | /* putstrf expr print str in a fixed width*/ |
652 | static void | 831 | static void |
653 | builtin_putstrf (struct mh_machine *mach) | 832 | builtin_putstrf (struct mh_machine *mach) |
654 | { | 833 | { |
655 | /*FIXME*/ | 834 | print_string (mach, mach->reg_num, |
835 | strobj_ptr (&mach->arg_str), strobj_len (&mach->arg_str)); | ||
656 | } | 836 | } |
657 | 837 | ||
658 | /* putnum expr print num*/ | 838 | /* putnum expr print num*/ |
659 | static void | 839 | static void |
660 | builtin_putnum (struct mh_machine *mach) | 840 | builtin_putnum (struct mh_machine *mach) |
661 | { | 841 | { |
662 | /*FIXME*/ | 842 | char *p; |
843 | asprintf (&p, "%d", mach->arg_num); | ||
844 | print_string (mach, 0, p, strlen (p)); | ||
845 | free (p); | ||
663 | } | 846 | } |
664 | 847 | ||
665 | /* putnumf expr print num in a fixed width*/ | 848 | /* putnumf expr print num in a fixed width*/ |
666 | static void | 849 | static void |
667 | builtin_putnumf (struct mh_machine *mach) | 850 | builtin_putnumf (struct mh_machine *mach) |
668 | { | 851 | { |
669 | /*FIXME*/ | 852 | char *p; |
853 | asprintf (&p, "%d", mach->arg_num); | ||
854 | print_string (mach, mach->reg_num, p, strlen (p)); | ||
855 | free (p); | ||
670 | } | 856 | } |
671 | 857 | ||
672 | static int | 858 | static int |
... | @@ -979,18 +1165,91 @@ builtin_rclock (struct mh_machine *mach) | ... | @@ -979,18 +1165,91 @@ builtin_rclock (struct mh_machine *mach) |
979 | mach->arg_num = now - mu_tm2time (&tm, &tz); | 1165 | mach->arg_num = now - mu_tm2time (&tm, &tz); |
980 | } | 1166 | } |
981 | 1167 | ||
1168 | struct | ||
1169 | { | ||
1170 | const char *std; | ||
1171 | const char *dst; | ||
1172 | int utc_offset; /* offset from GMT (hours) */ | ||
1173 | } tzs[] = { | ||
1174 | { "GMT", "BST", 0 }, | ||
1175 | { "EST", "EDT", -5 }, | ||
1176 | { "CST", "CDT", -6 }, | ||
1177 | { "MST", "MDT", -7 }, | ||
1178 | { "PST", "PDT", -8 }, | ||
1179 | { NULL, 0} | ||
1180 | }; | ||
1181 | |||
1182 | static void | ||
1183 | date_cvt (struct mh_machine *mach, int pretty) | ||
1184 | { | ||
1185 | struct tm tm; | ||
1186 | mu_timezone tz; | ||
1187 | char buf[80]; | ||
1188 | int i, len; | ||
1189 | const char *tzname = NULL; | ||
1190 | |||
1191 | if (_parse_date (mach, &tm, &tz)) | ||
1192 | return; | ||
1193 | |||
1194 | if (pretty) | ||
1195 | { | ||
1196 | for (i = 0; tzs[i].std; i++) | ||
1197 | { | ||
1198 | int offset = tzs[i].utc_offset; | ||
1199 | int dst = 0; | ||
1200 | |||
1201 | #ifdef HAVE_STRUCT_TM_TM_ISDST | ||
1202 | if (tm.tm_isdst) | ||
1203 | dst = -1; | ||
1204 | #endif | ||
1205 | |||
1206 | if (tz.utc_offset == (offset + dst) * 3600) | ||
1207 | { | ||
1208 | if (dst) | ||
1209 | tzname = tzs[i].dst; | ||
1210 | else | ||
1211 | tzname = tzs[i].std; | ||
1212 | break; | ||
1213 | } | ||
1214 | } | ||
1215 | } | ||
1216 | |||
1217 | len = strftime (buf, sizeof buf, | ||
1218 | "%a, %d %b %Y %H:%M:%S ", &tm); | ||
1219 | if (tzname) | ||
1220 | snprintf (buf + len, sizeof(buf) - len, "%s", tzname); | ||
1221 | else | ||
1222 | { | ||
1223 | int min, hrs, sign; | ||
1224 | int offset = tz.utc_offset; | ||
1225 | |||
1226 | if (offset < 0) | ||
1227 | { | ||
1228 | sign = '-'; | ||
1229 | offset = - offset; | ||
1230 | } | ||
1231 | else | ||
1232 | sign = '+'; | ||
1233 | min = offset / 60; | ||
1234 | hrs = min / 60; | ||
1235 | min %= 60; | ||
1236 | snprintf (buf + len, sizeof(buf) - len, "%c%02d%02d", sign, hrs, min); | ||
1237 | } | ||
1238 | strobj_create (&mach->arg_str, buf); | ||
1239 | } | ||
1240 | |||
982 | /* tws date string official 822 rendering */ | 1241 | /* tws date string official 822 rendering */ |
983 | static void | 1242 | static void |
984 | builtin_tws (struct mh_machine *mach) | 1243 | builtin_tws (struct mh_machine *mach) |
985 | { | 1244 | { |
986 | /*FIXME: noop*/ | 1245 | date_cvt (mach, 0); |
987 | } | 1246 | } |
988 | 1247 | ||
989 | /* pretty date string user-friendly rendering*/ | 1248 | /* pretty date string user-friendly rendering*/ |
990 | static void | 1249 | static void |
991 | builtin_pretty (struct mh_machine *mach) | 1250 | builtin_pretty (struct mh_machine *mach) |
992 | { | 1251 | { |
993 | /*FIXME: noop*/ | 1252 | date_cvt (mach, 1); |
994 | } | 1253 | } |
995 | 1254 | ||
996 | /* nodate date integer str not a date string */ | 1255 | /* nodate date integer str not a date string */ |
... | @@ -1050,11 +1309,18 @@ builtin_pers (struct mh_machine *mach) | ... | @@ -1050,11 +1309,18 @@ builtin_pers (struct mh_machine *mach) |
1050 | if (rc) | 1309 | if (rc) |
1051 | return; | 1310 | return; |
1052 | 1311 | ||
1053 | if (address_get_personal (addr, 1, buf, sizeof buf, &n) == 0) | 1312 | if (address_get_personal (addr, 1, buf, sizeof buf, &n) == 0 |
1054 | strobj_create (&mach->arg_str, buf); | 1313 | && n > 1) |
1314 | { | ||
1315 | char *p; | ||
1316 | asprintf (&p, "\"%s\"", buf); | ||
1317 | strobj_create (&mach->arg_str, p); | ||
1318 | free (p); | ||
1319 | } | ||
1055 | address_destroy (&addr); | 1320 | address_destroy (&addr); |
1056 | } | 1321 | } |
1057 | 1322 | ||
1323 | /* FIXME: address_get_comments never returns any comments. */ | ||
1058 | /* note addr string commentary text*/ | 1324 | /* note addr string commentary text*/ |
1059 | static void | 1325 | static void |
1060 | builtin_note (struct mh_machine *mach) | 1326 | builtin_note (struct mh_machine *mach) |
... | @@ -1375,3 +1641,14 @@ mh_lookup_builtin (char *name, int *rest) | ... | @@ -1375,3 +1641,14 @@ mh_lookup_builtin (char *name, int *rest) |
1375 | } | 1641 | } |
1376 | return NULL; | 1642 | return NULL; |
1377 | } | 1643 | } |
1644 | |||
1645 | char * | ||
1646 | _get_builtin_name (mh_builtin_fp ptr) | ||
1647 | { | ||
1648 | mh_builtin_t *bp; | ||
1649 | |||
1650 | for (bp = builtin_tab; bp->name; bp++) | ||
1651 | if (bp->fun == ptr) | ||
1652 | return bp->name; | ||
1653 | return NULL; | ||
1654 | } | ... | ... |
-
Please register or sign in to post a comment