/* GNU Mailutils -- a suite of utilities for electronic mail Copyright (C) 2006-2021 Free Software Foundation, Inc. GNU Mailutils is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GNU Mailutils is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Mailutils. If not, see . */ #define MH_FMT_DEFAULT 0 #define MH_FMT_RALIGN 0x1000 #define MH_FMT_ZEROPAD 0x2000 #define MH_FMT_COMPWS 0x4000 #define MH_WIDTH_MASK 0x0fff enum mh_opcode { /* Stop. Format: mhop_stop */ mhop_stop, /* Unconditional branch Format: mhop_branch offset */ mhop_branch, /* Branch if num reg is zero. Format: mhop_brz_num dest-off */ mhop_brzn, /* Branch if str reg is zero. Format: mhop_brz_str dest-off */ mhop_brzs, /* Set numeric register Format: mhop_setn val */ mhop_setn, /* Set string register Format: mhop_sets reg length string */ mhop_sets, /* Move value bewtween two numeric registers Format: mhop_movn dest src */ mhop_movn, /* Move value bewtween two string registers Format: mhop_movs dest src */ mhop_movs, /* Load component value into a string register Format: mhop_load reg string */ mhop_ldcomp, /* Load first width bytes of message body contents into a string register. Format: mhop_body reg */ mhop_ldbody, /* Call a function. Format: mhop_call function-pointer */ mhop_call, /* Convert string register to number reg Format: mhop_atoi */ mhop_atoi, /* Convert numeric register to string Format: mhop_itoa */ mhop_itoa, /* Print num reg */ mhop_printn, /* Print str reg */ mhop_prints, /* Print literal Format: mhop_printlit length string */ mhop_printlit, /* Set format specification. Format: mhop_fmtspec number */ mhop_fmtspec, /* Push numeric register */ mhop_pushn, /* Pop numeric register */ mhop_popn, /* Exchange top of stack value and numeric register */ mhop_xchgn, }; enum regid { R_REG, R_ARG, R_ACC }; #define MH_NREG 3 enum mh_type { mhtype_none, mhtype_num, mhtype_str }; typedef enum mh_opcode mh_opcode_t; struct mh_machine; typedef void (*mh_builtin_fp) (struct mh_fvm *); typedef union { mh_opcode_t opcode; mh_builtin_fp builtin; long num; void *ptr; size_t size; char str[1]; /* Any number of characters follows */ } mh_instr_t; #define MHI_OPCODE(m) (m).opcode #define MHI_BUILTIN(m) (m).builtin #define MHI_NUM(m) (m).num #define MHI_PTR(m) (m).ptr #define MHI_STR(m) (m).str struct mh_format { size_t progmax; /* Size of allocated program*/ size_t progcnt; /* Actual number of elements used */ mh_instr_t *prog; /* Program itself */ /* The tree and pool members are filled only if mh_format_parse was called with MH_FMT_PARSE_TREE flag */ struct node *tree; /* Parse tree */ mu_opool_t pool; /* Literal pool */ }; #define MHA_DEFAULT 0 #define MHA_IGNOREFMT 0x001 #define MHA_NOPRINT 0x002 #define MHA_PRINT_MASK 0x003 #define MHA_OPTARG 0x004 #define MHA_OPTARG_NIL 0x008 #define MHA_LITERAL 0x010 #define MHA_VOID 0x020 #define MHA_SPECIAL 0x040 #define MHA_ACC 0x080 typedef struct mh_builtin mh_builtin_t; struct mh_builtin { char *name; mh_builtin_fp fun; enum mh_type type; enum mh_type argtype; int flags; }; struct mh_string { size_t size; char *ptr; }; struct mh_fvm { long num[MH_NREG]; /* numeric registers */ struct mh_string str[MH_NREG]; /* string registers */ long *numstack; /* Stack of numeric value */ size_t maxstack; /* Stack capacity */ size_t tos; /* Top of stack (next free slot) */ size_t pc; /* Program counter */ size_t progcnt; /* Size of allocated program*/ mh_instr_t *prog; /* Program itself */ int stop; /* Stop execution immediately */ size_t width; /* Output line width */ size_t ind; /* Output line index */ mu_stream_t output; /* Output stream */ int flags; mu_list_t addrlist; /* The list of email addresses output this far */ int fmtflags; /* Current formatting flags */ mu_message_t message; /* Current message */ }; mh_builtin_t *mh_lookup_builtin (char *name, size_t len); void mh_print_fmtspec (int fmtspec);