Fix premature push.
Showing
7 changed files
with
163 additions
and
163 deletions
... | @@ -25,7 +25,6 @@ static char args_doc[] = N_("[FILE]"); | ... | @@ -25,7 +25,6 @@ static char args_doc[] = N_("[FILE]"); |
25 | static char *format_str; | 25 | static char *format_str; |
26 | static mh_format_t format; | 26 | static mh_format_t format; |
27 | static int dump_option; | 27 | static int dump_option; |
28 | static int disass_option; | ||
29 | static int debug_option; | 28 | static int debug_option; |
30 | static char *input_file; | 29 | static char *input_file; |
31 | static size_t width; | 30 | static size_t width; |
... | @@ -42,9 +41,6 @@ static struct mu_option options[] = { | ... | @@ -42,9 +41,6 @@ static struct mu_option options[] = { |
42 | { "dump", 0, NULL, MU_OPTION_HIDDEN, | 41 | { "dump", 0, NULL, MU_OPTION_HIDDEN, |
43 | N_("dump the listing of compiled format code"), | 42 | N_("dump the listing of compiled format code"), |
44 | mu_c_bool, &dump_option }, | 43 | mu_c_bool, &dump_option }, |
45 | { "disassemble", 0, NULL, MU_OPTION_HIDDEN, | ||
46 | N_("dump disassembled format code"), | ||
47 | mu_c_bool, &disass_option }, | ||
48 | { "debug", 0, NULL, MU_OPTION_DEFAULT, | 44 | { "debug", 0, NULL, MU_OPTION_DEFAULT, |
49 | N_("enable parser debugging output"), | 45 | N_("enable parser debugging output"), |
50 | mu_c_bool, &debug_option }, | 46 | mu_c_bool, &debug_option }, |
... | @@ -62,8 +58,11 @@ static void | ... | @@ -62,8 +58,11 @@ static void |
62 | run (void) | 58 | run (void) |
63 | { | 59 | { |
64 | mu_message_t msg = mh_file_to_message (NULL, input_file); | 60 | mu_message_t msg = mh_file_to_message (NULL, input_file); |
65 | mh_format (format, msg, msgno, width, mu_strout); | 61 | char *output; |
66 | mu_printf ("\n"); | 62 | |
63 | mh_format (&format, msg, msgno, width, &output); | ||
64 | |||
65 | mu_printf ("%s\n", output); | ||
67 | } | 66 | } |
68 | 67 | ||
69 | int | 68 | int |
... | @@ -91,16 +90,14 @@ main (int argc, char **argv) | ... | @@ -91,16 +90,14 @@ main (int argc, char **argv) |
91 | mu_error (_("Format string not specified")); | 90 | mu_error (_("Format string not specified")); |
92 | return 1; | 91 | return 1; |
93 | } | 92 | } |
94 | if (mh_format_parse (&format, format_str, MH_FMT_PARSE_TREE)) | 93 | if (mh_format_parse (format_str, &format)) |
95 | { | 94 | { |
96 | mu_error (_("Bad format string")); | 95 | mu_error (_("Bad format string")); |
97 | exit (1); | 96 | exit (1); |
98 | } | 97 | } |
99 | 98 | ||
100 | if (dump_option) | 99 | if (dump_option) |
101 | mh_format_dump_code (format); | 100 | mh_format_dump (&format); |
102 | if (disass_option) | ||
103 | mh_format_dump_disass (format); | ||
104 | 101 | ||
105 | if (input_file) | 102 | if (input_file) |
106 | run (); | 103 | run (); | ... | ... |
... | @@ -65,6 +65,11 @@ | ... | @@ -65,6 +65,11 @@ |
65 | 65 | ||
66 | #include <mu_umaxtostr.h> | 66 | #include <mu_umaxtostr.h> |
67 | 67 | ||
68 | #define MH_FMT_RALIGN 0x1000 | ||
69 | #define MH_FMT_ZEROPAD 0x2000 | ||
70 | #define MH_FMT_COMPWS 0x4000 | ||
71 | #define MH_WIDTH_MASK 0x0fff | ||
72 | |||
68 | #define MH_SEQUENCES_FILE ".mh_sequences" | 73 | #define MH_SEQUENCES_FILE ".mh_sequences" |
69 | #define MH_USER_PROFILE ".mh_profile" | 74 | #define MH_USER_PROFILE ".mh_profile" |
70 | #define MH_GLOBAL_PROFILE "mh-profile" | 75 | #define MH_GLOBAL_PROFILE "mh-profile" |
... | @@ -73,6 +78,118 @@ | ... | @@ -73,6 +78,118 @@ |
73 | 78 | ||
74 | #define is_true(arg) ((arg) == NULL||mu_true_answer_p (arg) == 1) | 79 | #define is_true(arg) ((arg) == NULL||mu_true_answer_p (arg) == 1) |
75 | 80 | ||
81 | enum mh_opcode | ||
82 | { | ||
83 | /* 0. Stop. Format: mhop_stop */ | ||
84 | mhop_stop, | ||
85 | /* 1. Branch. | ||
86 | Format: mhop_branch offset */ | ||
87 | mhop_branch, | ||
88 | /* 2. Assign to numeric register | ||
89 | Format: mhop_num_asgn */ | ||
90 | mhop_num_asgn, | ||
91 | /* 3. Assign to string register | ||
92 | Format: mhop_str_asgn */ | ||
93 | mhop_str_asgn, | ||
94 | /* 4. Numeric arg follows. | ||
95 | Format: mhop_num_arg number */ | ||
96 | mhop_num_arg, | ||
97 | /* 5. String arg follows. | ||
98 | Format: mhop_str_arg length string */ | ||
99 | mhop_str_arg, | ||
100 | /* 6. Branch if reg_num is zero. | ||
101 | Format: mhop_num_branch dest-off */ | ||
102 | mhop_num_branch, | ||
103 | /* 7. Branch if reg_str is zero. | ||
104 | Format: mhop_str_branch dest-off */ | ||
105 | mhop_str_branch, | ||
106 | /* 8. Set str to the value of the header component | ||
107 | Format: mhop_header */ | ||
108 | mhop_header, | ||
109 | |||
110 | /* 9. Read message body contents into str. | ||
111 | Format: mhop_body */ | ||
112 | mhop_body, | ||
113 | |||
114 | /* 10. Call a function. | ||
115 | Format: mhop_call function-pointer */ | ||
116 | mhop_call, | ||
117 | |||
118 | /* 11. assign reg_num to arg_num */ | ||
119 | mhop_num_to_arg, | ||
120 | |||
121 | /* 12. assign reg_str to arg_str */ | ||
122 | mhop_str_to_arg, | ||
123 | |||
124 | /* 13. Convert arg_str to arg_num */ | ||
125 | mhop_str_to_num, | ||
126 | |||
127 | /* 14. Convert arg_num to arg_str */ | ||
128 | mhop_num_to_str, | ||
129 | |||
130 | /* 15. Print reg_num */ | ||
131 | mhop_num_print, | ||
132 | |||
133 | /* 16. Print reg_str */ | ||
134 | mhop_str_print, | ||
135 | |||
136 | /* 17. Set format specification. | ||
137 | Format: mhop_fmtspec number */ | ||
138 | mhop_fmtspec, | ||
139 | |||
140 | /* 18. Noop */ | ||
141 | mhop_nop | ||
142 | }; | ||
143 | |||
144 | enum mh_type | ||
145 | { | ||
146 | mhtype_none, | ||
147 | mhtype_num, | ||
148 | mhtype_str | ||
149 | }; | ||
150 | |||
151 | typedef enum mh_opcode mh_opcode_t; | ||
152 | |||
153 | struct mh_machine; | ||
154 | typedef void (*mh_builtin_fp) (struct mh_machine *); | ||
155 | |||
156 | typedef union { | ||
157 | mh_opcode_t opcode; | ||
158 | mh_builtin_fp builtin; | ||
159 | int num; | ||
160 | void *ptr; | ||
161 | char str[1]; /* Any number of characters follows */ | ||
162 | } mh_instr_t; | ||
163 | |||
164 | #define MHI_OPCODE(m) (m).opcode | ||
165 | #define MHI_BUILTIN(m) (m).builtin | ||
166 | #define MHI_NUM(m) (m).num | ||
167 | #define MHI_PTR(m) (m).ptr | ||
168 | #define MHI_STR(m) (m).str | ||
169 | |||
170 | typedef struct mh_format mh_format_t; | ||
171 | |||
172 | struct mh_format | ||
173 | { | ||
174 | size_t progsize; /* Size of allocated program*/ | ||
175 | mh_instr_t *prog; /* Program itself */ | ||
176 | }; | ||
177 | |||
178 | #define MHA_REQUIRED 0 | ||
179 | #define MHA_OPTARG 1 | ||
180 | #define MHA_OPT_CLEAR 2 | ||
181 | |||
182 | typedef struct mh_builtin mh_builtin_t; | ||
183 | |||
184 | struct mh_builtin | ||
185 | { | ||
186 | char *name; | ||
187 | mh_builtin_fp fun; | ||
188 | int type; | ||
189 | int argtype; | ||
190 | int optarg; | ||
191 | }; | ||
192 | |||
76 | typedef struct | 193 | typedef struct |
77 | { | 194 | { |
78 | const char *name; | 195 | const char *name; |
... | @@ -167,22 +284,14 @@ int mu_getans (const char *variants, const char *fmt, ...) | ... | @@ -167,22 +284,14 @@ int mu_getans (const char *variants, const char *fmt, ...) |
167 | int mh_check_folder (const char *pathname, int confirm); | 284 | int mh_check_folder (const char *pathname, int confirm); |
168 | int mh_makedir (const char *p); | 285 | int mh_makedir (const char *p); |
169 | 286 | ||
170 | typedef struct mh_format *mh_format_t; | 287 | int mh_format (mh_format_t *fmt, mu_message_t msg, size_t msgno, |
171 | 288 | size_t width, char **pret); | |
172 | int mh_format (mh_format_t fmt, mu_message_t msg, size_t msgno, | 289 | int mh_format_str (mh_format_t *fmt, char *str, size_t width, char **pret); |
173 | size_t width, mu_stream_t str); | 290 | void mh_format_dump (mh_format_t *fmt); |
174 | int mh_format_str (mh_format_t fmt, char *str, size_t width, char **pret); | 291 | int mh_format_parse (char *format_str, mh_format_t *fmt); |
175 | |||
176 | void mh_format_dump_code (mh_format_t fmt); | ||
177 | void mh_format_dump_disass (mh_format_t fmt); | ||
178 | |||
179 | #define MH_FMT_PARSE_DEFAULT 0 | ||
180 | #define MH_FMT_PARSE_TREE 0x01 | ||
181 | int mh_format_parse (mh_format_t *fmt, char *format_str, int flags); | ||
182 | |||
183 | void mh_format_debug (int val); | 292 | void mh_format_debug (int val); |
184 | void mh_format_free (mh_format_t fmt); | 293 | void mh_format_free (mh_format_t *fmt); |
185 | void mh_format_destroy (mh_format_t *fmt); | 294 | mh_builtin_t *mh_lookup_builtin (char *name, int *rest); |
186 | 295 | ||
187 | void mh_error (const char *fmt, ...) MU_PRINTFLIKE(1,2); | 296 | void mh_error (const char *fmt, ...) MU_PRINTFLIKE(1,2); |
188 | void mh_err_memory (int fatal); | 297 | void mh_err_memory (int fatal); |
... | @@ -241,7 +350,7 @@ int mh_whom_file (const char *filename, int check); | ... | @@ -241,7 +350,7 @@ int mh_whom_file (const char *filename, int check); |
241 | int mh_whom_message (mu_message_t msg, int check); | 350 | int mh_whom_message (mu_message_t msg, int check); |
242 | 351 | ||
243 | void mh_set_reply_regex (const char *str); | 352 | void mh_set_reply_regex (const char *str); |
244 | int mh_decode_2047 (char const *text, char **decoded_text); | 353 | int mh_decode_2047 (char *text, char **decoded_text); |
245 | const char *mh_charset (const char *); | 354 | const char *mh_charset (const char *); |
246 | 355 | ||
247 | int mh_alias_read (char const *name, int fail); | 356 | int mh_alias_read (char const *name, int fail); | ... | ... |
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
... | @@ -15,146 +15,34 @@ | ... | @@ -15,146 +15,34 @@ |
15 | You should have received a copy of the GNU General Public License | 15 | You should have received a copy of the GNU General Public License |
16 | along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ | 16 | along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ |
17 | 17 | ||
18 | #define MH_FMT_DEFAULT 0 | 18 | typedef struct /* A string object type */ |
19 | #define MH_FMT_RALIGN 0x1000 | ||
20 | #define MH_FMT_ZEROPAD 0x2000 | ||
21 | #define MH_FMT_COMPWS 0x4000 | ||
22 | #define MH_WIDTH_MASK 0x0fff | ||
23 | |||
24 | enum mh_opcode | ||
25 | { | ||
26 | /* Stop. Format: mhop_stop */ | ||
27 | mhop_stop, | ||
28 | /* Unconditional branch | ||
29 | Format: mhop_branch offset */ | ||
30 | mhop_branch, | ||
31 | /* Branch if num reg is zero. | ||
32 | Format: mhop_brz_num dest-off */ | ||
33 | mhop_brzn, | ||
34 | /* Branch if str reg is zero. | ||
35 | Format: mhop_brz_str dest-off */ | ||
36 | mhop_brzs, | ||
37 | |||
38 | /* Set numeric register | ||
39 | Format: mhop_setn val */ | ||
40 | mhop_setn, | ||
41 | |||
42 | /* Set string register | ||
43 | Format: mhop_sets reg length string */ | ||
44 | mhop_sets, | ||
45 | |||
46 | /* Move value bewtween two numeric registers | ||
47 | Format: mhop_movn dest src */ | ||
48 | mhop_movn, | ||
49 | |||
50 | /* Move value bewtween two string registers | ||
51 | Format: mhop_movs dest src */ | ||
52 | mhop_movs, | ||
53 | |||
54 | /* Load component value into a string register | ||
55 | Format: mhop_load reg string */ | ||
56 | mhop_ldcomp, | ||
57 | |||
58 | /* Load first width bytes of message body contents into a string register. | ||
59 | Format: mhop_body reg */ | ||
60 | mhop_ldbody, | ||
61 | |||
62 | /* Call a function. | ||
63 | Format: mhop_call function-pointer */ | ||
64 | mhop_call, | ||
65 | |||
66 | /* Convert string register to number reg | ||
67 | Format: mhop_atoi reg | ||
68 | */ | ||
69 | mhop_atoi, | ||
70 | |||
71 | /* Convert numeric register to string | ||
72 | Format: mhop_itoa reg */ | ||
73 | mhop_itoa, | ||
74 | |||
75 | /* Print num reg */ | ||
76 | mhop_printn, | ||
77 | |||
78 | /* Print str reg */ | ||
79 | mhop_prints, | ||
80 | |||
81 | /* Set format specification. | ||
82 | Format: mhop_fmtspec number */ | ||
83 | mhop_fmtspec, | ||
84 | }; | ||
85 | |||
86 | enum regid { R_REG, R_ARG }; | ||
87 | |||
88 | enum mh_type | ||
89 | { | 19 | { |
90 | mhtype_none, | 20 | int size; /* Allocated size or 0 for static storage */ |
91 | mhtype_num, | 21 | char *ptr; /* Actual data */ |
92 | mhtype_str | 22 | } |
93 | }; | 23 | strobj_t; |
94 | |||
95 | typedef enum mh_opcode mh_opcode_t; | ||
96 | |||
97 | struct mh_machine; | ||
98 | typedef void (*mh_builtin_fp) (struct mh_machine *); | ||
99 | |||
100 | typedef union { | ||
101 | mh_opcode_t opcode; | ||
102 | mh_builtin_fp builtin; | ||
103 | long num; | ||
104 | void *ptr; | ||
105 | char str[1]; /* Any number of characters follows */ | ||
106 | } mh_instr_t; | ||
107 | |||
108 | #define MHI_OPCODE(m) (m).opcode | ||
109 | #define MHI_BUILTIN(m) (m).builtin | ||
110 | #define MHI_NUM(m) (m).num | ||
111 | #define MHI_PTR(m) (m).ptr | ||
112 | #define MHI_STR(m) (m).str | ||
113 | |||
114 | struct mh_format | ||
115 | { | ||
116 | size_t progmax; /* Size of allocated program*/ | ||
117 | size_t progcnt; /* Actual number of elements used */ | ||
118 | mh_instr_t *prog; /* Program itself */ | ||
119 | struct node *tree; | ||
120 | mu_opool_t pool; | ||
121 | }; | ||
122 | 24 | ||
123 | #define MHA_REQUIRED 0 | 25 | #define strobj_ptr(p) ((p)->ptr ? (p)->ptr : "") |
124 | #define MHA_OPTARG 1 | 26 | #define strobj_len(p) (strobj_is_null(p) ? 0 : strlen((p)->ptr)) |
125 | #define MHA_OPT_CLEAR 2 | 27 | #define strobj_is_null(p) ((p)->ptr == NULL) |
126 | #define MHA_VOID 3 | 28 | #define strobj_is_static(p) ((p)->size == 0) |
127 | 29 | ||
128 | typedef struct mh_builtin mh_builtin_t; | ||
129 | |||
130 | struct mh_builtin | ||
131 | { | ||
132 | char *name; | ||
133 | mh_builtin_fp fun; | ||
134 | enum mh_type type; | ||
135 | enum mh_type argtype; | ||
136 | int optarg; | ||
137 | }; | ||
138 | |||
139 | struct mh_string | ||
140 | { | ||
141 | size_t size; | ||
142 | char *ptr; | ||
143 | }; | ||
144 | |||
145 | struct mh_machine | 30 | struct mh_machine |
146 | { | 31 | { |
147 | long num[2]; /* numeric registers */ | 32 | strobj_t reg_str; /* String register */ |
148 | struct mh_string str[2]; /* string registers */ | 33 | int reg_num; /* Numeric register */ |
34 | |||
35 | strobj_t arg_str; /* String argument */ | ||
36 | long arg_num; /* Numeric argument */ | ||
149 | 37 | ||
150 | size_t pc; /* Program counter */ | 38 | size_t pc; /* Program counter */ |
151 | size_t progcnt; /* Size of allocated program*/ | 39 | size_t progsize; /* Size of allocated program*/ |
152 | mh_instr_t *prog; /* Program itself */ | 40 | mh_instr_t *prog; /* Program itself */ |
153 | int stop; /* Stop execution immediately */ | 41 | int stop; /* Stop execution immediately */ |
154 | 42 | ||
155 | size_t width; /* Output line width */ | 43 | mu_opool_t pool; /* Output buffer */ |
156 | size_t ind; /* Output line index */ | 44 | size_t width; /* Output buffer width */ |
157 | mu_stream_t output; /* Output stream */ | 45 | size_t ind; /* Output buffer index */ |
158 | 46 | ||
159 | mu_list_t addrlist; /* The list of email addresses output this far */ | 47 | mu_list_t addrlist; /* The list of email addresses output this far */ |
160 | int fmtflags; /* Current formatting flags */ | 48 | int fmtflags; /* Current formatting flags */ |
... | @@ -163,5 +51,9 @@ struct mh_machine | ... | @@ -163,5 +51,9 @@ struct mh_machine |
163 | size_t msgno; /* Its number */ | 51 | size_t msgno; /* Its number */ |
164 | }; | 52 | }; |
165 | 53 | ||
166 | mh_builtin_t *mh_lookup_builtin (char *name, size_t len); | 54 | void strobj_free (strobj_t *obj); |
167 | void mh_print_fmtspec (int fmtspec); | 55 | void strobj_create (strobj_t *lvalue, const char *str); |
56 | void strobj_set (strobj_t *lvalue, char *str); | ||
57 | void strobj_assign (strobj_t *lvalue, strobj_t *rvalue); | ||
58 | void strobj_copy (strobj_t *lvalue, strobj_t *rvalue); | ||
59 | void strobj_realloc (strobj_t *obj, size_t length); | ... | ... |
... | @@ -913,7 +913,7 @@ mh_charset (const char *dfl) | ... | @@ -913,7 +913,7 @@ mh_charset (const char *dfl) |
913 | } | 913 | } |
914 | 914 | ||
915 | int | 915 | int |
916 | mh_decode_2047 (char const *text, char **decoded_text) | 916 | mh_decode_2047 (char *text, char **decoded_text) |
917 | { | 917 | { |
918 | const char *charset = mh_charset (NULL); | 918 | const char *charset = mh_charset (NULL); |
919 | if (!charset) | 919 | if (!charset) | ... | ... |
... | @@ -46,7 +46,7 @@ enum mhl_datatype | ... | @@ -46,7 +46,7 @@ enum mhl_datatype |
46 | typedef union mhl_value { | 46 | typedef union mhl_value { |
47 | char *str; | 47 | char *str; |
48 | int num; | 48 | int num; |
49 | mh_format_t fmt; | 49 | mh_format_t *fmt; |
50 | } mhl_value_t; | 50 | } mhl_value_t; |
51 | 51 | ||
52 | typedef struct mhl_variable | 52 | typedef struct mhl_variable |
... | @@ -151,6 +151,7 @@ parse_variable (locus_t *loc, mu_list_t formlist, char *str) | ... | @@ -151,6 +151,7 @@ parse_variable (locus_t *loc, mu_list_t formlist, char *str) |
151 | { | 151 | { |
152 | size_t i; | 152 | size_t i; |
153 | struct mu_wordsplit ws; | 153 | struct mu_wordsplit ws; |
154 | mh_format_t fmt; | ||
154 | int wsflags; | 155 | int wsflags; |
155 | 156 | ||
156 | if (strncmp (str, "ignores=", 8) == 0 && str[8] != '"') | 157 | if (strncmp (str, "ignores=", 8) == 0 && str[8] != '"') |
... | @@ -218,14 +219,15 @@ parse_variable (locus_t *loc, mu_list_t formlist, char *str) | ... | @@ -218,14 +219,15 @@ parse_variable (locus_t *loc, mu_list_t formlist, char *str) |
218 | break; | 219 | break; |
219 | 220 | ||
220 | case dt_format: | 221 | case dt_format: |
221 | if (mh_format_parse (&stmt->v.variable.value.fmt, value, | 222 | if (mh_format_parse (value, &fmt)) |
222 | MH_FMT_PARSE_DEFAULT)) | ||
223 | { | 223 | { |
224 | mu_error (_("%s:%d: bad format string"), | 224 | mu_error (_("%s:%d: bad format string"), |
225 | loc->filename, | 225 | loc->filename, |
226 | loc->line); | 226 | loc->line); |
227 | exit (1); | 227 | exit (1); |
228 | } | 228 | } |
229 | stmt->v.variable.value.fmt = mu_alloc (sizeof (mh_format_t)); | ||
230 | *stmt->v.variable.value.fmt = fmt; | ||
229 | break; | 231 | break; |
230 | 232 | ||
231 | case dt_flag: | 233 | case dt_flag: |
... | @@ -454,7 +456,7 @@ struct eval_env | ... | @@ -454,7 +456,7 @@ struct eval_env |
454 | int ivar[I_MAX]; | 456 | int ivar[I_MAX]; |
455 | int bvar[B_MAX]; | 457 | int bvar[B_MAX]; |
456 | char *svar[S_MAX]; | 458 | char *svar[S_MAX]; |
457 | mh_format_t fvar[F_MAX]; | 459 | mh_format_t *fvar[F_MAX]; |
458 | char *prefix; | 460 | char *prefix; |
459 | }; | 461 | }; |
460 | 462 | ... | ... |
-
Please register or sign in to post a comment