Commit 9da939eb 9da939ebc7cde925ee45f405786a6b0d451b7180 by Sergey Poznyakoff

Fix premature push.

1 parent 35056a6e
...@@ -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);
......
...@@ -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
......