summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--ChangeLog10
-rw-r--r--NEWS7
-rw-r--r--configure.ac2
-rw-r--r--src/bi_sieve.m42
-rw-r--r--src/bi_sprintf.m419
-rw-r--r--src/prog.c276
-rw-r--r--src/prog.h4
-rw-r--r--src/snarf.m470
8 files changed, 270 insertions, 120 deletions
diff --git a/ChangeLog b/ChangeLog
index 3602649..5ab7946 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
12008-09-08 Sergey Poznyakoff <gray@gnu.org.ua>
2
3 * src/snarf.m4, src/bi_sprintf.m4, src/prog.h, src/bi_sieve.m4,
4 Ported r1655 from trunk.
5
6 * src/prog.c: Ported r1655 and r1660 from trunk.
7
8 * NEWS: Update, set version number 4.4.1.
9 * configure.ac: set version number 4.4.1.
10
12008-03-10 Sergey Poznyakoff <gray@gnu.org.ua> 112008-03-10 Sergey Poznyakoff <gray@gnu.org.ua>
2 12
3 * doc/mailfromd.texi: Spell check. Add missing acknowledgments. 13 * doc/mailfromd.texi: Spell check. Add missing acknowledgments.
diff --git a/NEWS b/NEWS
index 674dbae..a212fcc 100644
--- a/NEWS
+++ b/NEWS
@@ -1,10 +1,15 @@
1Mailfromd NEWS -- history of user-visible changes. 2008-03-10 1Mailfromd NEWS -- history of user-visible changes. 2008-09-09
2Copyright (C) 2005, 2006, 2007, 2008 Sergey Poznyakoff 2Copyright (C) 2005, 2006, 2007, 2008 Sergey Poznyakoff
3See the end of file for copying conditions. 3See the end of file for copying conditions.
4 4
5Please send mailfromd bug reports to <bug-mailfromd@gnu.org.ua> 5Please send mailfromd bug reports to <bug-mailfromd@gnu.org.ua>
6 6
7 7
8Version 4.4.1
9
10* Fix stack reallocation.
11
12
8Version 4.4, 2008-03-10 13Version 4.4, 2008-03-10
9 14
10* The --domain option is withdrawn. 15* The --domain option is withdrawn.
diff --git a/configure.ac b/configure.ac
index 5a14617..5a6e224 100644
--- a/configure.ac
+++ b/configure.ac
@@ -17,7 +17,7 @@
17AC_PREREQ(2.59) 17AC_PREREQ(2.59)
18m4_define([MF_VERSION_MAJOR], 4) 18m4_define([MF_VERSION_MAJOR], 4)
19m4_define([MF_VERSION_MINOR], 4) 19m4_define([MF_VERSION_MINOR], 4)
20dnl m4_define([MF_VERSION_PATCH], 0) 20m4_define([MF_VERSION_PATCH], 1)
21AC_INIT([mailfromd], 21AC_INIT([mailfromd],
22 MF_VERSION_MAJOR.MF_VERSION_MINOR[]m4_ifdef([MF_VERSION_PATCH],.MF_VERSION_PATCH), 22 MF_VERSION_MAJOR.MF_VERSION_MINOR[]m4_ifdef([MF_VERSION_PATCH],.MF_VERSION_PATCH),
23 [bug-mailfromd@gnu.org.ua]) 23 [bug-mailfromd@gnu.org.ua])
diff --git a/src/bi_sieve.m4 b/src/bi_sieve.m4
index 04ae8f9..0c5af27 100644
--- a/src/bi_sieve.m4
+++ b/src/bi_sieve.m4
@@ -151,7 +151,7 @@ MF_DEFUN(sieve, NUMBER, STRING script, OPTIONAL, NUMBER dbg)
151 mu_sieve_set_logger(mach, _sieve_action_log); 151 mu_sieve_set_logger(mach, _sieve_action_log);
152 152
153 rc = mu_sieve_compile(mach, script); 153 rc = mu_sieve_compile(mach, script);
154 if (rc == 0){ 154 if (rc == 0) {
155 mu_stream_t mstr = env_get_stream(env); 155 mu_stream_t mstr = env_get_stream(env);
156 mu_attribute_t attr; 156 mu_attribute_t attr;
157 mu_message_t msg; 157 mu_message_t msg;
diff --git a/src/bi_sprintf.m4 b/src/bi_sprintf.m4
index afd63d3..051d2dc 100644
--- a/src/bi_sprintf.m4
+++ b/src/bi_sprintf.m4
@@ -150,8 +150,7 @@ MF_DEFUN_VARARGS(sprintf, STRING, STRING format)
150 if (isdigit(*p)) { 150 if (isdigit(*p)) {
151 char *q = get_num(p, &n); 151 char *q = get_num(p, &n);
152 if (*q == '$') { 152 if (*q == '$') {
153 num = (unsigned) MF_VA_ARG(n-1, 153 MF_VA_ARG(n-1, NUMBER, num);
154 NUMBER);
155 p = q + 1; 154 p = q + 1;
156 if (num < 0) { 155 if (num < 0) {
157 flags |= FMT_SPACEPFX; 156 flags |= FMT_SPACEPFX;
@@ -161,7 +160,7 @@ MF_DEFUN_VARARGS(sprintf, STRING, STRING format)
161 break; 160 break;
162 } 161 }
163 } 162 }
164 num = MF_VA_ARG(i, NUMBER); 163 MF_VA_ARG(i, NUMBER, num);
165 i++; 164 i++;
166 if (num < 0) { 165 if (num < 0) {
167 /* A negative field width is taken 166 /* A negative field width is taken
@@ -193,14 +192,14 @@ MF_DEFUN_VARARGS(sprintf, STRING, STRING format)
193 if (isdigit(*p)) { 192 if (isdigit(*p)) {
194 char *q = get_num(p, &n); 193 char *q = get_num(p, &n);
195 if (*q == '$') { 194 if (*q == '$') {
196 num = MF_VA_ARG(n-1, NUMBER); 195 MF_VA_ARG(n-1, NUMBER, num);
197 if (num > 0) 196 if (num > 0)
198 prec = (unsigned) num; 197 prec = (unsigned) num;
199 p = q + 1; 198 p = q + 1;
200 break; 199 break;
201 } 200 }
202 } 201 }
203 num = MF_VA_ARG(i, NUMBER); 202 MF_VA_ARG(i, NUMBER, num);
204 i++; 203 i++;
205 if (num > 0) 204 if (num > 0)
206 prec = (unsigned) num; 205 prec = (unsigned) num;
@@ -211,7 +210,7 @@ MF_DEFUN_VARARGS(sprintf, STRING, STRING format)
211 argnum = i++; 210 argnum = i++;
212 switch (*p) { 211 switch (*p) {
213 case 's': 212 case 's':
214 str = MF_VA_ARG(argnum,STRING); 213 MF_VA_ARG(argnum, STRING, str);
215 n = strlen(str); 214 n = strlen(str);
216 if (prec && prec < n) 215 if (prec && prec < n)
217 n = prec; 216 n = prec;
@@ -235,7 +234,7 @@ MF_DEFUN_VARARGS(sprintf, STRING, STRING format)
235 234
236 case 'i': 235 case 'i':
237 case 'd': 236 case 'd':
238 num = MF_VA_ARG(argnum,NUMBER); 237 MF_VA_ARG(argnum, NUMBER, num);
239 if (num < 0) { 238 if (num < 0) {
240 negative = 1; 239 negative = 1;
241 num = - num; 240 num = - num;
@@ -290,7 +289,7 @@ MF_DEFUN_VARARGS(sprintf, STRING, STRING format)
290 break; 289 break;
291 290
292 case 'u': 291 case 'u':
293 num = MF_VA_ARG(argnum,NUMBER); 292 MF_VA_ARG(argnum, NUMBER, num);
294 /* If a precision is given with a 293 /* If a precision is given with a
295 numeric conversion, the 0 flag is ignored. 294 numeric conversion, the 0 flag is ignored.
296 */ 295 */
@@ -323,7 +322,7 @@ MF_DEFUN_VARARGS(sprintf, STRING, STRING format)
323 322
324 case 'x': 323 case 'x':
325 case 'X': 324 case 'X':
326 num = MF_VA_ARG(argnum,NUMBER); 325 MF_VA_ARG(argnum, NUMBER, num);
327 /* If a precision is given with a 326 /* If a precision is given with a
328 numeric conversion, the 0 flag is ignored. 327 numeric conversion, the 0 flag is ignored.
329 */ 328 */
@@ -369,7 +368,7 @@ MF_DEFUN_VARARGS(sprintf, STRING, STRING format)
369 break; 368 break;
370 369
371 case 'o': 370 case 'o':
372 num = MF_VA_ARG(argnum,NUMBER); 371 MF_VA_ARG(argnum, NUMBER, num);
373 /* If a precision is given with a 372 /* If a precision is given with a
374 numeric conversion, the 0 flag is ignored. 373 numeric conversion, the 0 flag is ignored.
375 */ 374 */
diff --git a/src/prog.c b/src/prog.c
index 2662110..9dc17da 100644
--- a/src/prog.c
+++ b/src/prog.c
@@ -235,6 +235,10 @@ disable_prog_trace(const char *modlist)
235 235
236/* Run-time evaluation */ 236/* Run-time evaluation */
237 237
238/* Max. number of C locals to save in struct eval_environ for eventual fixups.
239 See comment to env_fixup_autos, below. */
240#define MAX_AUTO_PTR 128
241
238struct eval_environ { 242struct eval_environ {
239 prog_counter_t pc; /* Program counter */ 243 prog_counter_t pc; /* Program counter */
240 244
@@ -253,6 +257,10 @@ struct eval_environ {
253 /* Temporary heap space */ 257 /* Temporary heap space */
254 size_t temp_start; 258 size_t temp_start;
255 size_t temp_size; 259 size_t temp_size;
260
261 STKVAL *auto_ptr[MAX_AUTO_PTR]; /* Pointers to C automatic variables
262 referring to dataseg. */
263 size_t numautos; /* Number of entries in auto_ptr. */
256 264
257 /* Sendmail interaction data: */ 265 /* Sendmail interaction data: */
258 SMFICTX *ctx; /* Milter Context */ 266 SMFICTX *ctx; /* Milter Context */
@@ -328,12 +336,52 @@ env_get_stream(eval_environ_t env)
328 return env->stream; 336 return env->stream;
329} 337}
330 338
339
340/* A call to expand_dataseg (see below) invalidates any C variables that
341 pointed to dataseg before the call. To avoid dereferencing invalid memory
342 pointers, the addresses of such C variables are stored in env->auto_ptr
343 using env_register_auto (it is done by get_string_arg). When
344 expand_dataseg is called, it calls env_fixup_autos and passes it the
345 offset of new dataseg from old one. env_fixup_autos adds this value to
346 every address in auto_ptr, thereby fixing them.
347
348 The auto_ptr array is cleared (by calling env_unregister_autos) after
349 executing each instruction (see eval_environment).
350 */
351void
352env_register_auto(eval_environ_t env, void *ptr)
353{
354 if (env->numautos == MAX_AUTO_PTR)
355 runtime_error(env, "INTERNAL ERROR at %s:%d, please report",
356 __FILE__, __LINE__);
357 env->auto_ptr[env->numautos++] = ptr;
358}
359
360void
361env_unregister_autos(eval_environ_t env)
362{
363 env->numautos = 0;
364}
365
366void
367env_fixup_autos(eval_environ_t env, ptrdiff_t offset)
368{
369 int i;
370 for (i = 0; i < env->numautos; i++) {
371 STKVAL *pptr = env->auto_ptr[i];
372 *pptr += offset;
373 }
374}
375
376
331#define STACK_EXPAND_BLOCK 64 377#define STACK_EXPAND_BLOCK 64
332 378
333static int 379static int
334expand_dataseg(eval_environ_t env, size_t count, const char *errtext) 380expand_dataseg(eval_environ_t env, size_t count, const char *errtext)
335{ 381{
336 STKVAL *newds; 382 STKVAL *newds;
383 ptrdiff_t offset;
384
337 count = ((count + STACK_EXPAND_BLOCK - 1) / STACK_EXPAND_BLOCK) 385 count = ((count + STACK_EXPAND_BLOCK - 1) / STACK_EXPAND_BLOCK)
338 * STACK_EXPAND_BLOCK; 386 * STACK_EXPAND_BLOCK;
339 newds = realloc(env->dataseg, 387 newds = realloc(env->dataseg,
@@ -346,6 +394,7 @@ expand_dataseg(eval_environ_t env, size_t count, const char *errtext)
346 return 1; 394 return 1;
347 } 395 }
348 396
397 offset = (char*)newds - (char*)env->dataseg;
349 env->dataseg = newds; 398 env->dataseg = newds;
350 env->stack_size += count; 399 env->stack_size += count;
351 env->tos += count; 400 env->tos += count;
@@ -353,6 +402,7 @@ expand_dataseg(eval_environ_t env, size_t count, const char *errtext)
353 memmove(newds + env->tos, newds + env->tos - count, 402 memmove(newds + env->tos, newds + env->tos - count,
354 (datasize + env->stack_size - env->tos) 403 (datasize + env->stack_size - env->tos)
355 * sizeof newds[0]); 404 * sizeof newds[0]);
405 env_fixup_autos(env, offset);
356 mu_error(_("Warning: stack segment expanded, new size=%lu"), 406 mu_error(_("Warning: stack segment expanded, new size=%lu"),
357 (unsigned long) env->stack_size); 407 (unsigned long) env->stack_size);
358 return 0; 408 return 0;
@@ -462,10 +512,11 @@ get_immediate(eval_environ_t env, unsigned n)
462 return prog[env->pc + n + 1]; 512 return prog[env->pc + n + 1];
463} 513}
464 514
465const char * 515void
466get_literal(eval_environ_t env, unsigned n) 516get_literal(eval_environ_t env, unsigned n, const char **p)
467{ 517{
468 return (char*)(env->dataseg + (size_t) get_immediate(env, n)); 518 *p = (char*)(env->dataseg + (size_t) get_immediate(env, n));
519 env_register_auto(env, p);
469} 520}
470 521
471STKVAL 522STKVAL
@@ -474,25 +525,31 @@ get_arg(eval_environ_t env, unsigned n)
474 return env->dataseg[env->tos + n + 1]; 525 return env->dataseg[env->tos + n + 1];
475} 526}
476 527
477char * 528void
478get_string_arg(eval_environ_t env, unsigned n) 529get_string_arg(eval_environ_t env, unsigned n, char **p)
479{ 530{
480 return (char*) (env->dataseg + (size_t) get_arg(env, n)); 531 *p = (char*) (env->dataseg + (size_t) get_arg(env, n));
532 env_register_auto(env, p);
481} 533}
482 534
483size_t 535void
484get_numeric_arg(eval_environ_t env, unsigned n) 536get_numeric_arg(eval_environ_t env, unsigned n, long *np)
485{ 537{
486 return (size_t) get_arg(env, n); 538 *np = (long) get_arg(env, n);
539}
540
541void
542get_pointer_arg(eval_environ_t env, unsigned n, void **p)
543{
544 *p = (void*) get_arg(env, n);
487} 545}
488 546
489void 547void
490push(eval_environ_t env, STKVAL val) 548push(eval_environ_t env, STKVAL val)
491{ 549{
492 if (env->tos < env->toh) 550 if (env->tos < env->toh)
493 runtime_error(env, "INTERNAL ERROR at %s:%d, please report", 551 runtime_error(env, "INTERNAL ERROR at %s:%d, please report",
494 __FILE__, __LINE__); 552 __FILE__, __LINE__);
495
496 if (env->tos == env->toh) { 553 if (env->tos == env->toh) {
497 debug2(100, "tos=%lu, toh=%lu", 554 debug2(100, "tos=%lu, toh=%lu",
498 (unsigned long) env->tos, 555 (unsigned long) env->tos,
@@ -591,8 +648,8 @@ pushs(eval_environ_t env, char *s)
591void 648void
592instr_locus(eval_environ_t env) 649instr_locus(eval_environ_t env)
593{ 650{
594 env->locus.file = get_literal(env, 0);
595 env->locus.line = (size_t) get_immediate(env, 1); 651 env->locus.line = (size_t) get_immediate(env, 1);
652 get_literal(env, 0, &env->locus.file);
596 if (PROG_TRACE_ENGINE) 653 if (PROG_TRACE_ENGINE)
597 prog_trace(env, "LOCUS"); 654 prog_trace(env, "LOCUS");
598 advance_pc(env, 2); 655 advance_pc(env, 2);
@@ -687,6 +744,14 @@ instr_stkalloc(eval_environ_t env)
687 unsigned n = (unsigned) get_immediate(env, 0); 744 unsigned n = (unsigned) get_immediate(env, 0);
688 if (PROG_TRACE_ENGINE) 745 if (PROG_TRACE_ENGINE)
689 prog_trace(env, "STKALLOC %p", n); 746 prog_trace(env, "STKALLOC %p", n);
747 if (env->tos - n < env->toh) {
748 debug3(100, "tos=%lu, toh=%lu, delta=%u",
749 (unsigned long) env->tos,
750 (unsigned long) env->toh,
751 n);
752 expand_dataseg(env, env->toh - (env->tos - n),
753 _("Out of stack space; increase #pragma stacksize"));
754 }
690 env->tos -= n; 755 env->tos -= n;
691 advance_pc(env, 1); 756 advance_pc(env, 1);
692} 757}
@@ -743,10 +808,13 @@ dump_backref(prog_counter_t i)
743void 808void
744instr_ston(eval_environ_t env) 809instr_ston(eval_environ_t env)
745{ 810{
746 char *s = get_string_arg(env, 0); 811 char *s;
747 char *p; 812 char *p;
748 long v = strtol(s, &p, 0); 813 long v;
749 814
815 get_string_arg(env, 0, &s);
816 v = strtol(s, &p, 0);
817
750 adjust_stack(env, 1); 818 adjust_stack(env, 1);
751 if (PROG_TRACE_ENGINE) 819 if (PROG_TRACE_ENGINE)
752 prog_trace(env, "STON %s", s); 820 prog_trace(env, "STON %s", s);
@@ -761,7 +829,7 @@ instr_ston(eval_environ_t env)
761void 829void
762instr_ntos(eval_environ_t env) 830instr_ntos(eval_environ_t env)
763{ 831{
764 long v = (long) get_numeric_arg(env, 0); 832 long v = (long) get_arg(env, 0);
765 char buf[NUMERIC_BUFSIZE_BOUND]; 833 char buf[NUMERIC_BUFSIZE_BOUND];
766 834
767 adjust_stack(env, 1); 835 adjust_stack(env, 1);
@@ -776,8 +844,8 @@ instr_ntos(eval_environ_t env)
776void 844void
777instr_cmp(eval_environ_t env) 845instr_cmp(eval_environ_t env)
778{ 846{
779 long l = (long) get_numeric_arg(env, 1); 847 long l = (long) get_arg(env, 1);
780 long r = (long) get_numeric_arg(env, 0); 848 long r = (long) get_arg(env, 0);
781 adjust_stack(env, 2); 849 adjust_stack(env, 2);
782 if (PROG_TRACE_ENGINE) 850 if (PROG_TRACE_ENGINE)
783 prog_trace(env, "CMP %ld %ld", l, r); 851 prog_trace(env, "CMP %ld %ld", l, r);
@@ -787,8 +855,10 @@ instr_cmp(eval_environ_t env)
787void 855void
788instr_symbol(eval_environ_t env) 856instr_symbol(eval_environ_t env)
789{ 857{
790 char *symbol = (char *) get_literal(env, 0); 858 char *symbol, *s;
791 char *s = env->getsym(env->data, symbol); 859
860 get_literal(env, 0, (const char **)&symbol);
861 s = env->getsym(env->data, symbol);
792 862
793 if (PROG_TRACE_ENGINE) 863 if (PROG_TRACE_ENGINE)
794 prog_trace(env, "SYMBOL %s", symbol); 864 prog_trace(env, "SYMBOL %s", symbol);
@@ -815,8 +885,8 @@ dump_symbol(prog_counter_t i)
815void 885void
816instr_eqn(eval_environ_t env) 886instr_eqn(eval_environ_t env)
817{ 887{
818 long a = (long) get_numeric_arg(env, 1); 888 long a = (long) get_arg(env, 1);
819 long b = (long) get_numeric_arg(env, 0); 889 long b = (long) get_arg(env, 0);
820 if (PROG_TRACE_ENGINE) 890 if (PROG_TRACE_ENGINE)
821 prog_trace(env, "EQN %ld %ld", a, b); 891 prog_trace(env, "EQN %ld %ld", a, b);
822 adjust_stack(env, 2); 892 adjust_stack(env, 2);
@@ -826,8 +896,9 @@ instr_eqn(eval_environ_t env)
826void 896void
827instr_eqs(eval_environ_t env) 897instr_eqs(eval_environ_t env)
828{ 898{
829 char *a = get_string_arg(env, 1); 899 char *a, *b;
830 char *b = get_string_arg(env, 0); 900 get_string_arg(env, 1, &a);
901 get_string_arg(env, 0, &b);
831 if (PROG_TRACE_ENGINE) 902 if (PROG_TRACE_ENGINE)
832 prog_trace(env, "EQS %s %s", a, b); 903 prog_trace(env, "EQS %s %s", a, b);
833 adjust_stack(env, 2); 904 adjust_stack(env, 2);
@@ -837,8 +908,8 @@ instr_eqs(eval_environ_t env)
837void 908void
838instr_nen(eval_environ_t env) 909instr_nen(eval_environ_t env)
839{ 910{
840 long a = (long) get_numeric_arg(env, 1); 911 long a = (long) get_arg(env, 1);
841 long b = (long) get_numeric_arg(env, 0); 912 long b = (long) get_arg(env, 0);
842 if (PROG_TRACE_ENGINE) 913 if (PROG_TRACE_ENGINE)
843 prog_trace(env, "NEN %ld %ld", a, b); 914 prog_trace(env, "NEN %ld %ld", a, b);
844 adjust_stack(env, 2); 915 adjust_stack(env, 2);
@@ -848,8 +919,10 @@ instr_nen(eval_environ_t env)
848void 919void
849instr_nes(eval_environ_t env) 920instr_nes(eval_environ_t env)
850{ 921{
851 char *a = get_string_arg(env, 1); 922 char *a, *b;
852 char *b = get_string_arg(env, 0); 923
924 get_string_arg(env, 1, &a);
925 get_string_arg(env, 0, &b);
853 if (PROG_TRACE_ENGINE) 926 if (PROG_TRACE_ENGINE)
854 prog_trace(env, "NES %s %s", a, b); 927 prog_trace(env, "NES %s %s", a, b);
855 adjust_stack(env, 2); 928 adjust_stack(env, 2);
@@ -859,8 +932,8 @@ instr_nes(eval_environ_t env)
859void 932void
860instr_ltn(eval_environ_t env) 933instr_ltn(eval_environ_t env)
861{ 934{
862 long a = (long) get_numeric_arg(env, 1); 935 long a = (long) get_arg(env, 1);
863 long b = (long) get_numeric_arg(env, 0); 936 long b = (long) get_arg(env, 0);
864 if (PROG_TRACE_ENGINE) 937 if (PROG_TRACE_ENGINE)
865 prog_trace(env, "LTN %ld %ld", a, b); 938 prog_trace(env, "LTN %ld %ld", a, b);
866 adjust_stack(env, 2); 939 adjust_stack(env, 2);
@@ -870,8 +943,10 @@ instr_ltn(eval_environ_t env)
870void 943void
871instr_lts(eval_environ_t env) 944instr_lts(eval_environ_t env)
872{ 945{
873 char *a = get_string_arg(env, 1); 946 char *a, *b;
874 char *b = get_string_arg(env, 0); 947
948 get_string_arg(env, 1, &a);
949 get_string_arg(env, 0, &b);
875 if (PROG_TRACE_ENGINE) 950 if (PROG_TRACE_ENGINE)
876 prog_trace(env, "LTS %s %s", a, b); 951 prog_trace(env, "LTS %s %s", a, b);
877 adjust_stack(env, 2); 952 adjust_stack(env, 2);
@@ -881,8 +956,8 @@ instr_lts(eval_environ_t env)
881void 956void
882instr_len(eval_environ_t env) 957instr_len(eval_environ_t env)
883{ 958{
884 long a = (long) get_numeric_arg(env, 1); 959 long a = (long) get_arg(env, 1);
885 long b = (long) get_numeric_arg(env, 0); 960 long b = (long) get_arg(env, 0);
886 if (PROG_TRACE_ENGINE) 961 if (PROG_TRACE_ENGINE)
887 prog_trace(env, "LEN %ld %ld", a, b); 962 prog_trace(env, "LEN %ld %ld", a, b);
888 adjust_stack(env, 2); 963 adjust_stack(env, 2);
@@ -892,8 +967,10 @@ instr_len(eval_environ_t env)
892void 967void
893instr_les(eval_environ_t env) 968instr_les(eval_environ_t env)
894{ 969{
895 char *a = get_string_arg(env, 1); 970 char *a, *b;
896 char *b = get_string_arg(env, 0); 971
972 get_string_arg(env, 1, &a);
973 get_string_arg(env, 0, &b);
897 if (PROG_TRACE_ENGINE) 974 if (PROG_TRACE_ENGINE)
898 prog_trace(env, "LES %s %s", a, b); 975 prog_trace(env, "LES %s %s", a, b);
899 adjust_stack(env, 2); 976 adjust_stack(env, 2);
@@ -903,8 +980,8 @@ instr_les(eval_environ_t env)
903void 980void
904instr_gtn(eval_environ_t env) 981instr_gtn(eval_environ_t env)
905{ 982{
906 long a = (long) get_numeric_arg(env, 1); 983 long a = (long) get_arg(env, 1);
907 long b = (long) get_numeric_arg(env, 0); 984 long b = (long) get_arg(env, 0);
908 if (PROG_TRACE_ENGINE) 985 if (PROG_TRACE_ENGINE)
909 prog_trace(env, "GTN %ld %ld", a, b); 986 prog_trace(env, "GTN %ld %ld", a, b);
910 adjust_stack(env, 2); 987 adjust_stack(env, 2);
@@ -914,8 +991,10 @@ instr_gtn(eval_environ_t env)
914void 991void
915instr_gts(eval_environ_t env) 992instr_gts(eval_environ_t env)
916{ 993{
917 char *a = get_string_arg(env, 1); 994 char *a, *b;
918 char *b = get_string_arg(env, 0); 995
996 get_string_arg(env, 1, &a);
997 get_string_arg(env, 0, &b);
919 if (PROG_TRACE_ENGINE) 998 if (PROG_TRACE_ENGINE)
920 prog_trace(env, "GTS %s %s", a, b); 999 prog_trace(env, "GTS %s %s", a, b);
921 adjust_stack(env, 2); 1000 adjust_stack(env, 2);
@@ -925,8 +1004,8 @@ instr_gts(eval_environ_t env)
925void 1004void
926instr_gen(eval_environ_t env) 1005instr_gen(eval_environ_t env)
927{ 1006{
928 long a = (long) get_numeric_arg(env, 1); 1007 long a = (long) get_arg(env, 1);
929 long b = (long) get_numeric_arg(env, 0); 1008 long b = (long) get_arg(env, 0);
930 if (PROG_TRACE_ENGINE) 1009 if (PROG_TRACE_ENGINE)
931 prog_trace(env, "GEN %ld %ld", a, b); 1010 prog_trace(env, "GEN %ld %ld", a, b);
932 adjust_stack(env, 2); 1011 adjust_stack(env, 2);
@@ -936,8 +1015,10 @@ instr_gen(eval_environ_t env)
936void 1015void
937instr_ges(eval_environ_t env) 1016instr_ges(eval_environ_t env)
938{ 1017{
939 char *a = get_string_arg(env, 1); 1018 char *a, *b;
940 char *b = get_string_arg(env, 0); 1019
1020 get_string_arg(env, 1, &a);
1021 get_string_arg(env, 0, &b);
941 if (PROG_TRACE_ENGINE) 1022 if (PROG_TRACE_ENGINE)
942 prog_trace(env, "GES %s %s", a, b); 1023 prog_trace(env, "GES %s %s", a, b);
943 adjust_stack(env, 2); 1024 adjust_stack(env, 2);
@@ -948,7 +1029,7 @@ instr_ges(eval_environ_t env)
948void 1029void
949instr_bz(eval_environ_t env) 1030instr_bz(eval_environ_t env)
950{ 1031{
951 long v = (long) get_numeric_arg(env, 0); 1032 long v = (long) get_arg(env, 0);
952 long off = (long) get_immediate(env, 0); 1033 long off = (long) get_immediate(env, 0);
953 1034
954 if (PROG_TRACE_ENGINE) 1035 if (PROG_TRACE_ENGINE)
@@ -968,7 +1049,7 @@ dump_branch (prog_counter_t i)
968void 1049void
969instr_bnz(eval_environ_t env) 1050instr_bnz(eval_environ_t env)
970{ 1051{
971 long v = (long) get_numeric_arg(env, 0); 1052 long v = (long) get_arg(env, 0);
972 long off = (long) get_immediate(env, 0); 1053 long off = (long) get_immediate(env, 0);
973 1054
974 if (PROG_TRACE_ENGINE) 1055 if (PROG_TRACE_ENGINE)
@@ -992,7 +1073,7 @@ instr_jmp(eval_environ_t env)
992void 1073void
993instr_not(eval_environ_t env) 1074instr_not(eval_environ_t env)
994{ 1075{
995 long v = (long) get_numeric_arg(env, 0); 1076 long v = (long) get_arg(env, 0);
996 if (PROG_TRACE_ENGINE) 1077 if (PROG_TRACE_ENGINE)
997 prog_trace(env, "NOT %ld", v); 1078 prog_trace(env, "NOT %ld", v);
998 adjust_stack(env, 1); 1079 adjust_stack(env, 1);
@@ -1003,8 +1084,8 @@ instr_not(eval_environ_t env)
1003void 1084void
1004instr_logand(eval_environ_t env) 1085instr_logand(eval_environ_t env)
1005{ 1086{
1006 unsigned long a = (unsigned long) get_numeric_arg(env, 1); 1087 unsigned long a = (unsigned long) get_arg(env, 1);
1007 unsigned long b = (unsigned long) get_numeric_arg(env, 0); 1088 unsigned long b = (unsigned long) get_arg(env, 0);
1008 adjust_stack(env, 2); 1089 adjust_stack(env, 2);
1009 if (PROG_TRACE_ENGINE) 1090 if (PROG_TRACE_ENGINE)
1010 prog_trace(env, "LOGAND %lu %lu", a, b); 1091 prog_trace(env, "LOGAND %lu %lu", a, b);
@@ -1014,8 +1095,8 @@ instr_logand(eval_environ_t env)
1014void 1095void
1015instr_logor(eval_environ_t env) 1096instr_logor(eval_environ_t env)
1016{ 1097{
1017 unsigned long a = (unsigned long) get_numeric_arg(env, 1); 1098 unsigned long a = (unsigned long) get_arg(env, 1);
1018 unsigned long b = (unsigned long) get_numeric_arg(env, 0); 1099 unsigned long b = (unsigned long) get_arg(env, 0);
1019 adjust_stack(env, 2); 1100 adjust_stack(env, 2);
1020 if (PROG_TRACE_ENGINE) 1101 if (PROG_TRACE_ENGINE)
1021 prog_trace(env, "LOGOR %lu %lu", a, b); 1102 prog_trace(env, "LOGOR %lu %lu", a, b);
@@ -1025,8 +1106,8 @@ instr_logor(eval_environ_t env)
1025void 1106void
1026instr_logxor(eval_environ_t env) 1107instr_logxor(eval_environ_t env)
1027{ 1108{
1028 unsigned long a = (unsigned long) get_numeric_arg(env, 1); 1109 unsigned long a = (unsigned long) get_arg(env, 1);
1029 unsigned long b = (unsigned long) get_numeric_arg(env, 0); 1110 unsigned long b = (unsigned long) get_arg(env, 0);
1030 adjust_stack(env, 2); 1111 adjust_stack(env, 2);
1031 if (PROG_TRACE_ENGINE) 1112 if (PROG_TRACE_ENGINE)
1032 prog_trace(env, "LOGXOR %lu %lu", a, b); 1113 prog_trace(env, "LOGXOR %lu %lu", a, b);
@@ -1036,7 +1117,7 @@ instr_logxor(eval_environ_t env)
1036void 1117void
1037instr_lognot(eval_environ_t env) 1118instr_lognot(eval_environ_t env)
1038{ 1119{
1039 unsigned long v = (unsigned long) get_numeric_arg(env, 0); 1120 unsigned long v = (unsigned long) get_arg(env, 0);
1040 if (PROG_TRACE_ENGINE) 1121 if (PROG_TRACE_ENGINE)
1041 prog_trace(env, "LOGNOT %ld", v); 1122 prog_trace(env, "LOGNOT %ld", v);
1042 adjust_stack(env, 1); 1123 adjust_stack(env, 1);
@@ -1047,8 +1128,8 @@ instr_lognot(eval_environ_t env)
1047void 1128void
1048instr_add(eval_environ_t env) 1129instr_add(eval_environ_t env)
1049{ 1130{
1050 long a = (long) get_numeric_arg(env, 1); 1131 long a = (long) get_arg(env, 1);
1051 long b = (long) get_numeric_arg(env, 0); 1132 long b = (long) get_arg(env, 0);
1052 adjust_stack(env, 2); 1133 adjust_stack(env, 2);
1053 if (PROG_TRACE_ENGINE) 1134 if (PROG_TRACE_ENGINE)
1054 prog_trace(env, "ADD %ld %ld", a, b); 1135 prog_trace(env, "ADD %ld %ld", a, b);
@@ -1058,8 +1139,8 @@ instr_add(eval_environ_t env)
1058void 1139void
1059instr_sub(eval_environ_t env) 1140instr_sub(eval_environ_t env)
1060{ 1141{
1061 long a = (long) get_numeric_arg(env, 1); 1142 long a = (long) get_arg(env, 1);
1062 long b = (long) get_numeric_arg(env, 0); 1143 long b = (long) get_arg(env, 0);
1063 adjust_stack(env, 2); 1144 adjust_stack(env, 2);
1064 if (PROG_TRACE_ENGINE) 1145 if (PROG_TRACE_ENGINE)
1065 prog_trace(env, "SUB %ld %ld", a, b); 1146 prog_trace(env, "SUB %ld %ld", a, b);
@@ -1069,8 +1150,8 @@ instr_sub(eval_environ_t env)
1069void 1150void
1070instr_mul(eval_environ_t env) 1151instr_mul(eval_environ_t env)
1071{ 1152{
1072 long a = (long) get_numeric_arg(env, 1); 1153 long a = (long) get_arg(env, 1);
1073 long b = (long) get_numeric_arg(env, 0); 1154 long b = (long) get_arg(env, 0);
1074 adjust_stack(env, 2); 1155 adjust_stack(env, 2);
1075 if (PROG_TRACE_ENGINE) 1156 if (PROG_TRACE_ENGINE)
1076 prog_trace(env, "MUL %ld %ld", a, b); 1157 prog_trace(env, "MUL %ld %ld", a, b);
@@ -1080,8 +1161,8 @@ instr_mul(eval_environ_t env)
1080void 1161void
1081instr_div(eval_environ_t env) 1162instr_div(eval_environ_t env)
1082{ 1163{
1083 long a = (long) get_numeric_arg(env, 1); 1164 long a = (long) get_arg(env, 1);
1084 long b = (long) get_numeric_arg(env, 0); 1165 long b = (long) get_arg(env, 0);
1085 adjust_stack(env, 2); 1166 adjust_stack(env, 2);
1086 if (PROG_TRACE_ENGINE) 1167 if (PROG_TRACE_ENGINE)
1087 prog_trace(env, "DIV %ld %ld", a, b); 1168 prog_trace(env, "DIV %ld %ld", a, b);
@@ -1094,7 +1175,7 @@ instr_div(eval_environ_t env)
1094void 1175void
1095instr_neg(eval_environ_t env) 1176instr_neg(eval_environ_t env)
1096{ 1177{
1097 long v = (long) get_numeric_arg(env, 0); 1178 long v = (long) get_arg(env, 0);
1098 if (PROG_TRACE_ENGINE) 1179 if (PROG_TRACE_ENGINE)
1099 prog_trace(env, "NEG %ld", v); 1180 prog_trace(env, "NEG %ld", v);
1100 adjust_stack(env, 1); 1181 adjust_stack(env, 1);
@@ -1135,9 +1216,11 @@ void
1135instr_regmatch(eval_environ_t env) 1216instr_regmatch(eval_environ_t env)
1136{ 1217{
1137 int v; 1218 int v;
1138 size_t index = (size_t)get_numeric_arg(env, 0); 1219 size_t index = (size_t)get_arg(env, 0);
1139 regex_t *re = &regtab[index].re; 1220 regex_t *re = &regtab[index].re;
1140 char *string = get_string_arg(env, 1); 1221 char *string;
1222
1223 get_string_arg(env, 1, &string);
1141 adjust_stack(env, 2); 1224 adjust_stack(env, 2);
1142 1225
1143 if (PROG_TRACE_ENGINE) 1226 if (PROG_TRACE_ENGINE)
@@ -1167,9 +1250,11 @@ instr_regcomp(eval_environ_t env)
1167 int v; 1250 int v;
1168 char buffer[REGEX_STRING_BUFSIZE]; 1251 char buffer[REGEX_STRING_BUFSIZE];
1169 size_t expr_off = (size_t)get_arg(env, 0); 1252 size_t expr_off = (size_t)get_arg(env, 0);
1170 char *expr = get_string_arg(env, 0); 1253 char *expr;
1171 size_t index = (size_t) get_immediate(env, 0); 1254 size_t index = (size_t) get_immediate(env, 0);
1172 struct rt_regex *rtx = &regtab[index]; 1255 struct rt_regex *rtx = &regtab[index];
1256
1257 get_string_arg(env, 0, &expr);
1173 1258
1174 advance_pc(env, 1); 1259 advance_pc(env, 1);
1175 adjust_stack(env, 1); 1260 adjust_stack(env, 1);
@@ -1211,8 +1296,10 @@ dump_regcomp(prog_counter_t i)
1211void 1296void
1212instr_fnmatch(eval_environ_t env) 1297instr_fnmatch(eval_environ_t env)
1213{ 1298{
1214 char *string = get_string_arg(env, 1); 1299 char *string, *pattern;
1215 char *pattern = get_string_arg(env, 0); 1300
1301 get_string_arg(env, 1, &string);
1302 get_string_arg(env, 0, &pattern);
1216 adjust_stack(env, 2); 1303 adjust_stack(env, 2);
1217 if (PROG_TRACE_ENGINE) 1304 if (PROG_TRACE_ENGINE)
1218 prog_trace(env, "FNMATCH %s %s", string, pattern); 1305 prog_trace(env, "FNMATCH %s %s", string, pattern);
@@ -1258,8 +1345,10 @@ fn_matcher(const char *string, void *data)
1258void 1345void
1259instr_fnmatch_mx(eval_environ_t env) 1346instr_fnmatch_mx(eval_environ_t env)
1260{ 1347{
1261 char *string = get_string_arg(env, 1); 1348 char *string, *pattern;
1262 char *pattern = get_string_arg(env, 0); 1349
1350 get_string_arg(env, 1, &string);
1351 get_string_arg(env, 0, &pattern);
1263 adjust_stack(env, 2); 1352 adjust_stack(env, 2);
1264 1353
1265 if (PROG_TRACE_ENGINE) 1354 if (PROG_TRACE_ENGINE)
@@ -1277,9 +1366,11 @@ void
1277instr_regmatch_mx(eval_environ_t env) 1366instr_regmatch_mx(eval_environ_t env)
1278{ 1367{
1279 int rc; 1368 int rc;
1280 size_t index = (size_t)get_numeric_arg(env, 0); 1369 size_t index = (size_t)get_arg(env, 0);
1281 regex_t *re = &regtab[index].re; 1370 regex_t *re = &regtab[index].re;
1282 char *string = get_string_arg(env, 1); 1371 char *string;
1372
1373 get_string_arg(env, 1, &string);
1283 adjust_stack(env, 2); 1374 adjust_stack(env, 2);
1284 1375
1285 if (PROG_TRACE_ENGINE) 1376 if (PROG_TRACE_ENGINE)
@@ -1307,9 +1398,12 @@ void
1307instr_result(eval_environ_t env) 1398instr_result(eval_environ_t env)
1308{ 1399{
1309 sfsistat status = (sfsistat) get_immediate(env, 0); 1400 sfsistat status = (sfsistat) get_immediate(env, 0);
1310 char *code = (char *) get_literal(env, 1); 1401 char *code, *xcode;
1311 char *xcode = (char *) get_literal(env, 2); 1402 char *message;
1312 char *message = get_string_arg(env, 0); 1403
1404 get_string_arg(env, 0, &message);
1405 get_literal(env, 1, (const char**)&code);
1406 get_literal(env, 2, (const char**)&xcode);
1313 1407
1314 if (PROG_TRACE_ENGINE) 1408 if (PROG_TRACE_ENGINE)
1315 prog_trace(env, "RESULT %d %s %s %s", 1409 prog_trace(env, "RESULT %d %s %s %s",
@@ -1350,11 +1444,13 @@ void
1350instr_header(eval_environ_t env) 1444instr_header(eval_environ_t env)
1351{ 1445{
1352 struct old_header_node *hdr = xmalloc (sizeof(*hdr)); 1446 struct old_header_node *hdr = xmalloc (sizeof(*hdr));
1447 char *value;
1353 1448
1354 hdr->opcode = (enum header_opcode) get_immediate(env, 0); 1449 hdr->opcode = (enum header_opcode) get_immediate(env, 0);
1355 hdr->name = get_literal(env, 1); 1450 get_literal(env, 1, &hdr->name);
1356 hdr->value = strdup(get_string_arg(env, 0)); 1451 get_string_arg(env, 0, &value);
1357 1452 hdr->value = strdup(value);
1453
1358 advance_pc(env, 2); 1454 advance_pc(env, 2);
1359 adjust_stack(env, 1); 1455 adjust_stack(env, 1);
1360 1456
@@ -1382,9 +1478,10 @@ dump_header(prog_counter_t i)
1382void 1478void
1383instr_builtin(eval_environ_t env) 1479instr_builtin(eval_environ_t env)
1384{ 1480{
1385 const char *name = get_literal(env, 0); 1481 const char *name;
1386 void (*handler)(eval_environ_t) = get_immediate(env, 1); 1482 void (*handler)(eval_environ_t) = get_immediate(env, 1);
1387 1483
1484 get_literal(env, 0, &name);
1388 if (PROG_TRACE_ENGINE) 1485 if (PROG_TRACE_ENGINE)
1389 prog_trace(env, "BUILTIN %s", name); 1486 prog_trace(env, "BUILTIN %s", name);
1390 advance_pc(env, 2); 1487 advance_pc(env, 2);
@@ -1400,10 +1497,14 @@ dump_builtin(prog_counter_t i)
1400void 1497void
1401instr_concat(eval_environ_t env) 1498instr_concat(eval_environ_t env)
1402{ 1499{
1403 char *left = get_string_arg(env, 1); 1500 char *left, *right;
1404 char *right = get_string_arg(env, 0); 1501 size_t off;
1405 size_t off = heap_reserve(env, strlen(left) + strlen(right) + 1); 1502 char *res;
1406 char *res = (char*) env_data_ref(env, off); 1503
1504 get_string_arg(env, 1, &left);
1505 get_string_arg(env, 0, &right);
1506 off = heap_reserve(env, strlen(left) + strlen(right) + 1);
1507 res = (char*) env_data_ref(env, off);
1407 1508
1408 strcat(strcpy(res, left), right); 1509 strcat(strcpy(res, left), right);
1409 adjust_stack(env, 2); 1510 adjust_stack(env, 2);
@@ -1422,7 +1523,7 @@ void
1422instr_asgn(eval_environ_t env) 1523instr_asgn(eval_environ_t env)
1423{ 1524{
1424 STKVAL val = get_arg(env, 1); 1525 STKVAL val = get_arg(env, 1);
1425 size_t dest = get_numeric_arg(env, 0); 1526 size_t dest = (size_t) get_arg(env, 0);
1426 adjust_stack(env, 2); 1527 adjust_stack(env, 2);
1427 if (PROG_TRACE_ENGINE) 1528 if (PROG_TRACE_ENGINE)
1428 prog_trace(env, "ASGN %lu=%lu", 1529 prog_trace(env, "ASGN %lu=%lu",
@@ -1576,8 +1677,9 @@ instr_pushreg(eval_environ_t env)
1576void 1677void
1577instr_funcall(eval_environ_t env) 1678instr_funcall(eval_environ_t env)
1578{ 1679{
1579 const char *name = get_literal(env, 0); 1680 const char *name;
1580 prog_counter_t pc = (prog_counter_t) get_immediate(env, 1); 1681 prog_counter_t pc = (prog_counter_t) get_immediate(env, 1);
1682 get_literal(env, 0, &name);
1581 advance_pc(env, 2); 1683 advance_pc(env, 2);
1582 if (PROG_TRACE_ENGINE) 1684 if (PROG_TRACE_ENGINE)
1583 prog_trace(env, "FUNCALL %s (%lu)", name, (unsigned long)pc); 1685 prog_trace(env, "FUNCALL %s (%lu)", name, (unsigned long)pc);
@@ -1760,6 +1862,8 @@ env_init(eval_environ_t env)
1760 env->matchcount = 0; 1862 env->matchcount = 0;
1761 env->string = NULL; 1863 env->string = NULL;
1762 1864
1865 env->numautos = 0;
1866
1763 /* Initialize catch functions */ 1867 /* Initialize catch functions */
1764 memcpy (env->catch, env->defcatch, sizeof env->catch); 1868 memcpy (env->catch, env->defcatch, sizeof env->catch);
1765 1869
@@ -1806,8 +1910,10 @@ eval_environment(eval_environ_t env, prog_counter_t start)
1806 runtime_error(env, _("pc out of range")); 1910 runtime_error(env, _("pc out of range"));
1807 if (!prog[env->pc]) 1911 if (!prog[env->pc])
1808 break; 1912 break;
1809 if (setjmp(env->catch_jmp) == 0) 1913 if (setjmp(env->catch_jmp) == 0) {
1810 (*(prog[env->pc]))(env); 1914 (*(prog[env->pc]))(env);
1915 env_unregister_autos(env);
1916 }
1811 } 1917 }
1812 return 0; 1918 return 0;
1813} 1919}
diff --git a/src/prog.h b/src/prog.h
index c18ab87..ef97282 100644
--- a/src/prog.h
+++ b/src/prog.h
@@ -31,8 +31,8 @@ void runtime_warning(eval_environ_t env, const char *fmt, ...);
31void runtime_error(eval_environ_t env, const char *fmt, ...) 31void runtime_error(eval_environ_t env, const char *fmt, ...)
32 ATTRIBUTE_NORETURN; 32 ATTRIBUTE_NORETURN;
33STKVAL get_arg(eval_environ_t env, unsigned n); 33STKVAL get_arg(eval_environ_t env, unsigned n);
34char *get_string_arg(eval_environ_t env, unsigned n); 34void get_string_arg(eval_environ_t env, unsigned n, char **ptr);
35size_t get_numeric_arg(eval_environ_t env, unsigned n); 35void get_numeric_arg(eval_environ_t env, unsigned n, long *np);
36void push(eval_environ_t env, STKVAL val); 36void push(eval_environ_t env, STKVAL val);
37STKVAL pop(eval_environ_t env); 37STKVAL pop(eval_environ_t env);
38STKVAL *env_data_ref(eval_environ_t env, size_t off); 38STKVAL *env_data_ref(eval_environ_t env, size_t off);
diff --git a/src/snarf.m4 b/src/snarf.m4
index 6d41932..7ceb4af 100644
--- a/src/snarf.m4
+++ b/src/snarf.m4
@@ -79,25 +79,49 @@ m4_define([<__mf_c_getarg>],m4_dnl
79[<m4_ifelse($1,STRING,get_string_arg,$1,NUMBER,get_numeric_arg, ERROR )>]) 79[<m4_ifelse($1,STRING,get_string_arg,$1,NUMBER,get_numeric_arg, ERROR )>])
80 80
81/* mf_c_argdcl(TYPE NAME) -- translate Mailfromd declaration "TYPE NAME" 81/* mf_c_argdcl(TYPE NAME) -- translate Mailfromd declaration "TYPE NAME"
82 * into the corresponding C one, followed by an equals sign, a typecast, 82 * into the corresponding C one:
83 * and the name of corresponding get_.*_arg function 83 *
84 * e.g.: 84 * mf_c_argdcl(STRING str) => char *str
85 * mf_c_argdcl(STRING str) => char *str = (char*) get_string_arg
86 */ 85 */
87m4_define([<mf_c_argdcl>],m4_dnl 86m4_define([<mf_c_argdcl>],m4_dnl
88[<m4_regexp([<$1>],[<\(\w+\)\W+\(\w+\)>],[<__mf_c_type(\1)>] \2 = ([<__mf_c_type(\1)>]) [<__mf_c_getarg(\1)>])>]) 87[<m4_regexp([<$1>],[<\(\w+\)\W+\(\w+\)>],[<__mf_c_type(\1)>] \2)>])
88
89/* mf_c_arginit(TYPE NAME, NUM) -- translate Mailfromd declaration "TYPE NAME"
90 * into the corresponding C initialization:
91 *
92 * mf_c_argdcl(STRING str) => get_string_arg(env, NUM, &str)
93 */
94m4_define([<mf_c_arginit>],m4_dnl
95[<m4_regexp([<$1>],[<\(\w+\)\W+\(\w+\)>],[<__mf_c_getarg(\1)(env, $2, &\2)>])>])
96
97/* __mf_c_argdcl_list(NARG, LIST) -- translate Mailfromd declaration list
98 * into a set of corresponding C variable declarations.
99 * For more details, see mf_c_arglist below.
100 */
101m4_define([<__mf_c_argdcl_list>],m4_dnl
102[<m4_ifelse($2, , ,$2,[<OPTIONAL>],[<m4_dnl
103__mf_c_argdcl_list($1, m4_shift(m4_shift($@)))>],
104[<mf_c_argdcl($2);
105 __mf_c_argdcl_list(m4_incr($1), m4_shift(m4_shift($@)))>])>])
106
107/* __mf_c_arginit_list(NARG, LIST) -- translate Mailfromd declaration list
108 * into a set of corresponding C variable initializations.
109 * For more details, see mf_c_arglist below.
110 */
111m4_define([<__mf_c_arginit_list>],m4_dnl
112[<m4_ifelse($2, , ,$2,[<OPTIONAL>],[<m4_dnl
113__mf_c_arginit_list($1, m4_shift(m4_shift($@)))>],
114[<mf_c_arginit($2, m4_eval($1));
115 __mf_c_arginit_list(m4_incr($1), m4_shift(m4_shift($@)))>])>])
89 116
90/* __mf_c_arglist(NARG, LIST) -- translate Mailfromd declaration list 117/* __mf_c_arglist(NARG, LIST) -- translate Mailfromd declaration list
91 * into a set of corresponding C variable declarations with initializations. 118 * into a set of corresponding C variable declarations and initializations.
92 * Arguments: 119 * Arguments:
93 * NARG -- ordinal number of the first variable in LIST 120 * NARG -- ordinal number of the first variable in LIST
94 * LIST -- comma-separated list of Mailfromd declarations 121 * LIST -- comma-separated list of Mailfromd declarations
95 */ 122 */
96m4_define([<__mf_c_arglist>],m4_dnl 123m4_define([<__mf_c_arglist>],[<__mf_c_argdcl_list($@)
97[<m4_ifelse($2, , ,$2,[<OPTIONAL>],[<m4_dnl 124__mf_c_arginit_list($@)>])
98__mf_c_arglist($1, m4_shift(m4_shift($@)))>],
99[<mf_c_argdcl($2)(env, m4_eval($1));
100 __mf_c_arglist(m4_incr($1), m4_shift(m4_shift($@)))>])>])
101 125
102/* mf_c_arglist(LIST) -- translate Mailfromd declaration list 126/* mf_c_arglist(LIST) -- translate Mailfromd declaration list
103 * into a set of corresponding C variable declarations with initializations. 127 * into a set of corresponding C variable declarations with initializations.
@@ -105,23 +129,29 @@ __mf_c_arglist($1, m4_shift(m4_shift($@)))>],
105 * variables. 129 * variables.
106 * E.g.: 130 * E.g.:
107 * mf_c_arglist(STRING a, NUMBER n) => 131 * mf_c_arglist(STRING a, NUMBER n) =>
108 * char *a = (char*)get_string_arg(env, 0); 132 * char *a;
109 * long n = (long)get_numeric_arg(env, 1); 133 * long n;
134 * get_string_arg(env, 0, &a);
135 * get_numeric_arg(env, 1, &n);
110 * adjust_stack(env, 2); 136 * adjust_stack(env, 2);
111 * 137 *
112 * Or, if the builtin takes optional parameters: 138 * Or, if the builtin takes optional parameters:
113 * 139 *
114 * mf_c_arglist(STRING a, NUMBER n) => 140 * mf_c_arglist(STRING a, NUMBER n) =>
115 * long __bi_argcnt = (long)get_numeric_arg(env, 0); 141 * long __bi_argcnt;
116 * char *a = (char*)get_string_arg(env, 1); 142 * char *a;
117 * long n = (long)get_numeric_arg(env, 2); 143 * long n;
144 * get_string_arg(env, 1, &a);
145 * get_numeric_arg(env, 2, &n);
146 * get_numeric_arg(env, 0, &__bi_argcnt);
118 * adjust_stack(env, __bi_argcnt + 1); 147 * adjust_stack(env, __bi_argcnt + 1);
119 */ 148 */
120m4_define([<mf_c_arglist>],m4_dnl 149m4_define([<mf_c_arglist>],m4_dnl
121[< 150[<
122m4_pushdef([<__ARG1__>], m4_ifelse(__MF_VARARGS__,1,1,[<__mf_has_optarg($@)>])) 151m4_pushdef([<__ARG1__>], m4_ifelse(__MF_VARARGS__,1,1,[<__mf_has_optarg($@)>]))
123m4_ifelse(__ARG1__,0,,[<long __bi_argcnt = (long)get_numeric_arg(env, 0);>]) 152m4_ifelse(__ARG1__,0,,[<long __bi_argcnt;>])
124__mf_c_arglist(__ARG1__, $@) 153__mf_c_arglist(__ARG1__, $@)
154m4_ifelse(__ARG1__,0,,[<get_numeric_arg(env, 0, &__bi_argcnt);>])
125 adjust_stack(env, m4_ifelse(__ARG1__,0,mf_argcount($@),__bi_argcnt + 1)); 155 adjust_stack(env, m4_ifelse(__ARG1__,0,mf_argcount($@),__bi_argcnt + 1));
126m4_popdef([<__ARG1__>])m4_dnl 156m4_popdef([<__ARG1__>])m4_dnl
127>]) 157>])
@@ -429,13 +459,13 @@ m4_ifelse(__MF_VARARGS__,1,[<__mf_va_count>],
429)m4_dnl 459)m4_dnl
430m4_define([<__mf_error_code>],1)>])>]) 460m4_define([<__mf_error_code>],1)>])>])
431 461
432/* MF_VA_ARG(N, TYPE) -- Produce a code for returning Nth argument of the 462/* MF_VA_ARG(N, TYPE, VAR) -- Produce a code for assigning to VAR the Nth
433 given TYPE in a vararg section. */ 463 argument of the given TYPE in a vararg section. */
434m4_define([<MF_VA_ARG>],[<m4_dnl 464m4_define([<MF_VA_ARG>],[<m4_dnl
435m4_ifdef([<__MF_VA_START_USED__>],m4_dnl 465m4_ifdef([<__MF_VA_START_USED__>],m4_dnl
436[<m4_pushdef([<__ARGN__>],[<$1+mf_argcount(__MF_ARGLIST__)>]) 466[<m4_pushdef([<__ARGN__>],[<$1+mf_argcount(__MF_ARGLIST__)>])
437 ((__bi_argcnt > __ARGN__) ?m4_dnl 467 ((__bi_argcnt > __ARGN__) ?m4_dnl
438 __mf_c_getarg($2)(env, __ARGN__ + 1) :m4_dnl 468 __mf_c_getarg($2)(env, __ARGN__ + 1, &$3) :m4_dnl
439 (MF_THROW(mfe_range, "Argument %d is not supplied", __ARGN__),m4_dnl 469 (MF_THROW(mfe_range, "Argument %d is not supplied", __ARGN__),m4_dnl
440(__mf_c_type($2)) 0))m4_dnl 470(__mf_c_type($2)) 0))m4_dnl
441m4_popdef([<__ARGN__>])>], 471m4_popdef([<__ARGN__>])>],

Return to:

Send suggestions and report system problems to the System administrator.