52 |
size_t msgno; /* Its number */ |
size_t msgno; /* Its number */ |
53 |
}; |
}; |
54 |
|
|
55 |
|
static char *_get_builtin_name __P((mh_builtin_fp ptr)); |
56 |
|
|
57 |
/* Functions for handling string objects. */ |
/* Functions for handling string objects. */ |
58 |
|
|
59 |
void |
void |
412 |
return mach.ind; |
return mach.ind; |
413 |
} |
} |
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 |
|
|
589 |
/* Free any memory associated with a format structure. The structure |
/* Free any memory associated with a format structure. The structure |
590 |
itself is assumed to be in static storage. */ |
itself is assumed to be in static storage. */ |
591 |
void |
void |
658 |
static void |
static void |
659 |
builtin_me (struct mh_machine *mach) |
builtin_me (struct mh_machine *mach) |
660 |
{ |
{ |
661 |
/*FIXME*/ |
char *s = mh_my_email (); |
662 |
/* mach->arg_str = "me";*/ |
strobj_free (&mach->arg_str); |
663 |
|
strobj_create (&mach->arg_str, s); |
664 |
} |
} |
665 |
|
|
666 |
static void |
static void |
755 |
static void |
static void |
756 |
builtin_profile (struct mh_machine *mach) |
builtin_profile (struct mh_machine *mach) |
757 |
{ |
{ |
758 |
/*FIXME*/ |
char *val = strobj_ptr (&mach->arg_str); |
759 |
/*mach->arg_str = "profile";*/ |
strobj_free (&mach->arg_str); |
760 |
|
strobj_create (&mach->arg_str, mh_global_profile_get (val, "")); |
761 |
} |
} |
762 |
|
|
763 |
static void |
static void |
823 |
static void |
static void |
824 |
builtin_putstr (struct mh_machine *mach) |
builtin_putstr (struct mh_machine *mach) |
825 |
{ |
{ |
826 |
/*FIXME*/ |
print_string (mach, 0, |
827 |
|
strobj_ptr (&mach->arg_str), strobj_len (&mach->arg_str)); |
828 |
} |
} |
829 |
|
|
830 |
/* putstrf expr print str in a fixed width*/ |
/* putstrf expr print str in a fixed width*/ |
831 |
static void |
static void |
832 |
builtin_putstrf (struct mh_machine *mach) |
builtin_putstrf (struct mh_machine *mach) |
833 |
{ |
{ |
834 |
/*FIXME*/ |
print_string (mach, mach->reg_num, |
835 |
|
strobj_ptr (&mach->arg_str), strobj_len (&mach->arg_str)); |
836 |
} |
} |
837 |
|
|
838 |
/* putnum expr print num*/ |
/* putnum expr print num*/ |
839 |
static void |
static void |
840 |
builtin_putnum (struct mh_machine *mach) |
builtin_putnum (struct mh_machine *mach) |
841 |
{ |
{ |
842 |
/*FIXME*/ |
char *p; |
843 |
|
asprintf (&p, "%d", mach->arg_num); |
844 |
|
print_string (mach, 0, p, strlen (p)); |
845 |
|
free (p); |
846 |
} |
} |
847 |
|
|
848 |
/* putnumf expr print num in a fixed width*/ |
/* putnumf expr print num in a fixed width*/ |
849 |
static void |
static void |
850 |
builtin_putnumf (struct mh_machine *mach) |
builtin_putnumf (struct mh_machine *mach) |
851 |
{ |
{ |
852 |
/*FIXME*/ |
char *p; |
853 |
|
asprintf (&p, "%d", mach->arg_num); |
854 |
|
print_string (mach, mach->reg_num, p, strlen (p)); |
855 |
|
free (p); |
856 |
} |
} |
857 |
|
|
858 |
static int |
static int |
1165 |
mach->arg_num = now - mu_tm2time (&tm, &tz); |
mach->arg_num = now - mu_tm2time (&tm, &tz); |
1166 |
} |
} |
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 |
|
|
1241 |
/* tws date string official 822 rendering */ |
/* tws date string official 822 rendering */ |
1242 |
static void |
static void |
1243 |
builtin_tws (struct mh_machine *mach) |
builtin_tws (struct mh_machine *mach) |
1244 |
{ |
{ |
1245 |
/*FIXME: noop*/ |
date_cvt (mach, 0); |
1246 |
} |
} |
1247 |
|
|
1248 |
/* pretty date string user-friendly rendering*/ |
/* pretty date string user-friendly rendering*/ |
1249 |
static void |
static void |
1250 |
builtin_pretty (struct mh_machine *mach) |
builtin_pretty (struct mh_machine *mach) |
1251 |
{ |
{ |
1252 |
/*FIXME: noop*/ |
date_cvt (mach, 1); |
1253 |
} |
} |
1254 |
|
|
1255 |
/* nodate date integer str not a date string */ |
/* nodate date integer str not a date string */ |
1309 |
if (rc) |
if (rc) |
1310 |
return; |
return; |
1311 |
|
|
1312 |
if (address_get_personal (addr, 1, buf, sizeof buf, &n) == 0) |
if (address_get_personal (addr, 1, buf, sizeof buf, &n) == 0 |
1313 |
strobj_create (&mach->arg_str, buf); |
&& n > 1) |
1314 |
|
{ |
1315 |
|
char *p; |
1316 |
|
asprintf (&p, "\"%s\"", buf); |
1317 |
|
strobj_create (&mach->arg_str, p); |
1318 |
|
free (p); |
1319 |
|
} |
1320 |
address_destroy (&addr); |
address_destroy (&addr); |
1321 |
} |
} |
1322 |
|
|
1323 |
|
/* FIXME: address_get_comments never returns any comments. */ |
1324 |
/* note addr string commentary text*/ |
/* note addr string commentary text*/ |
1325 |
static void |
static void |
1326 |
builtin_note (struct mh_machine *mach) |
builtin_note (struct mh_machine *mach) |
1641 |
} |
} |
1642 |
return NULL; |
return NULL; |
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 |
|
} |