1 /* GNU Mailutils -- a suite of utilities for electronic mail 2 Copyright (C) 2006-2021 Free Software Foundation, Inc. 3 4 GNU Mailutils is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 3, or (at your option) 7 any later version. 8 9 GNU Mailutils is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ 16 17 #define MH_FMT_DEFAULT 0 18 #define MH_FMT_RALIGN 0x1000 19 #define MH_FMT_ZEROPAD 0x2000 20 #define MH_FMT_COMPWS 0x4000 21 #define MH_WIDTH_MASK 0x0fff 22 23 enum mh_opcode 24 { 25 /* Stop. Format: mhop_stop */ 26 mhop_stop, 27 /* Unconditional branch 28 Format: mhop_branch offset */ 29 mhop_branch, 30 /* Branch if num reg is zero. 31 Format: mhop_brz_num dest-off */ 32 mhop_brzn, 33 /* Branch if str reg is zero. 34 Format: mhop_brz_str dest-off */ 35 mhop_brzs, 36 37 /* Set numeric register 38 Format: mhop_setn val */ 39 mhop_setn, 40 41 /* Set string register 42 Format: mhop_sets reg length string */ 43 mhop_sets, 44 45 /* Move value bewtween two numeric registers 46 Format: mhop_movn dest src */ 47 mhop_movn, 48 49 /* Move value bewtween two string registers 50 Format: mhop_movs dest src */ 51 mhop_movs, 52 53 /* Load component value into a string register 54 Format: mhop_load reg string */ 55 mhop_ldcomp, 56 57 /* Load first width bytes of message body contents into a string register. 58 Format: mhop_body reg */ 59 mhop_ldbody, 60 61 /* Call a function. 62 Format: mhop_call function-pointer */ 63 mhop_call, 64 65 /* Convert string register to number reg 66 Format: mhop_atoi 67 */ 68 mhop_atoi, 69 70 /* Convert numeric register to string 71 Format: mhop_itoa */ 72 mhop_itoa, 73 74 /* Print num reg */ 75 mhop_printn, 76 77 /* Print str reg */ 78 mhop_prints, 79 80 /* Print literal 81 Format: mhop_printlit length string */ 82 mhop_printlit, 83 84 /* Set format specification. 85 Format: mhop_fmtspec number */ 86 mhop_fmtspec, 87 88 /* Push numeric register */ 89 mhop_pushn, 90 /* Pop numeric register */ 91 mhop_popn, 92 /* Exchange top of stack value and numeric register */ 93 mhop_xchgn, 94 }; 95 96 enum regid { R_REG, R_ARG, R_ACC }; 97 #define MH_NREG 3 98 99 enum mh_type 100 { 101 mhtype_none, 102 mhtype_num, 103 mhtype_str 104 }; 105 106 typedef enum mh_opcode mh_opcode_t; 107 108 struct mh_machine; 109 typedef void (*mh_builtin_fp) (struct mh_fvm *); 110 111 typedef union { 112 mh_opcode_t opcode; 113 mh_builtin_fp builtin; 114 long num; 115 void *ptr; 116 size_t size; 117 char str[1]; /* Any number of characters follows */ 118 } mh_instr_t; 119 120 #define MHI_OPCODE(m) (m).opcode 121 #define MHI_BUILTIN(m) (m).builtin 122 #define MHI_NUM(m) (m).num 123 #define MHI_PTR(m) (m).ptr 124 #define MHI_STR(m) (m).str 125 126 struct mh_format 127 { 128 size_t progmax; /* Size of allocated program*/ 129 size_t progcnt; /* Actual number of elements used */ 130 mh_instr_t *prog; /* Program itself */ 131 /* The tree and pool members are filled only if mh_format_parse 132 was called with MH_FMT_PARSE_TREE flag */ 133 struct node *tree; /* Parse tree */ 134 mu_opool_t pool; /* Literal pool */ 135 }; 136 137 #define MHA_DEFAULT 0 138 #define MHA_IGNOREFMT 0x001 139 #define MHA_NOPRINT 0x002 140 #define MHA_PRINT_MASK 0x003 141 142 #define MHA_OPTARG 0x004 143 #define MHA_OPTARG_NIL 0x008 144 #define MHA_LITERAL 0x010 145 #define MHA_VOID 0x020 146 #define MHA_SPECIAL 0x040 147 #define MHA_ACC 0x080 148 149 typedef struct mh_builtin mh_builtin_t; 150 151 struct mh_builtin 152 { 153 char *name; 154 mh_builtin_fp fun; 155 enum mh_type type; 156 enum mh_type argtype; 157 int flags; 158 }; 159 160 struct mh_string 161 { 162 size_t size; 163 char *ptr; 164 }; 165 166 struct mh_fvm 167 { 168 long num[MH_NREG]; /* numeric registers */ 169 struct mh_string str[MH_NREG]; /* string registers */ 170 171 long *numstack; /* Stack of numeric value */ 172 size_t maxstack; /* Stack capacity */ 173 size_t tos; /* Top of stack (next free slot) */ 174 175 size_t pc; /* Program counter */ 176 size_t progcnt; /* Size of allocated program*/ 177 mh_instr_t *prog; /* Program itself */ 178 int stop; /* Stop execution immediately */ 179 180 size_t width; /* Output line width */ 181 size_t ind; /* Output line index */ 182 mu_stream_t output; /* Output stream */ 183 int flags; 184 185 mu_list_t addrlist; /* The list of email addresses output this far */ 186 int fmtflags; /* Current formatting flags */ 187 188 mu_message_t message; /* Current message */ 189 }; 190 191 mh_builtin_t *mh_lookup_builtin (char *name, size_t len); 192 void mh_print_fmtspec (int fmtspec); 193 194