m4_divert(-1)m4_dnl -*- m4 -*- # This file is part of mailfromd. # Copyright (C) 2006, 2007 Sergey Poznyakoff # # This program 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. # # This program 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 this program. If not, see . m4_changequote([<,>]) m4_changecom(/*,*/) /* MF_MODULE_NAME() - Returns the name of the current module. */ m4_define([],[]) /* MF_SOURCE_DEBUG_NAME(MODULE) - Initialize the "debug" name for the MODULE. */ m4_define([],[]m4_dnl m4_translit(m4_patsubst($1,\(.*/\)?\(.*\)\.m4,\2),[],[])>]) /* MF_MODULE_MASK() - Returns BUILTIN_MASK_ constant for the current module. */ m4_define([],[]MF_MODULE_NAME()>]) /* __mf_argtype(arg) -- return Mailfromd value type code corresponding to * ARG: * __mf_argtype(STRING) => dtype_string * __mf_argtype(NUMBER) => dtype_number * __mf_argtype(anything) => dtype_unspecified */ m4_define([<__mf_argtype>],m4_dnl []) /* mf_argtype(TYPE NAME) -- return Mailfromd value type code corresponding to * TYPE. See __mf_argtype above. */ m4_define([],m4_dnl [<__mf_argtype(m4_patsubst([<$1>],[<[ \t].*>],))>]) /* mf_typelist(arglist) -- convert ARGLIST into a list of corresponding * Mailfromd value type codes. e.g.: * mf_typelist(STRING a, NUMBER b) => dtype_string, dtype_number */ m4_define([],m4_dnl [], m4_dnl, $1, [], [], []m4_dnl [])>]) /* __mf_has_optarg(ARGS..) -- return 1 if ARGS contain OPTIONAL keyword, and * 0 otherwise */ m4_define([<__mf_has_optarg>],m4_dnl [], 1,[])>]) /* __mf_c_type(TYPE) -- return a C type corresponding to the Mailfromd one */ m4_define([<__mf_c_type>],m4_dnl []) /* __mf_c_getarg(TYPE) -- return a get_(.*)_arg function for the given MFL * TYPE */ m4_define([<__mf_c_getarg>],m4_dnl []) /* mf_c_argdcl(TYPE NAME) -- translate Mailfromd declaration "TYPE NAME" * into the corresponding C one, followed by an equals sign, a typecast, * and the name of corresponding get_.*_arg function * e.g.: * mf_c_argdcl(STRING str) => char *str = (char*) get_string_arg */ m4_define([],m4_dnl [],[<\(\w+\)\W+\(\w+\)>],[<__mf_c_type(\1)>] \2 = ([<__mf_c_type(\1)>]) [<__mf_c_getarg(\1)>])>]) /* __mf_c_arglist(NARG, LIST) -- translate Mailfromd declaration list * into a set of corresponding C variable declarations with initializations. * Arguments: * NARG -- ordinal number of the first variable in LIST * LIST -- comma-separated list of Mailfromd declarations */ m4_define([<__mf_c_arglist>],m4_dnl [],[], [])>]) /* mf_c_arglist(LIST) -- translate Mailfromd declaration list * into a set of corresponding C variable declarations with initializations. * Insert an instruction to adjust the stack parameters after obtaining the * variables. * E.g.: * mf_c_arglist(STRING a, NUMBER n) => * char *a = (char*)get_string_arg(env, 0); * long n = (long)get_numeric_arg(env, 1); * adjust_stack(env, 2); * * Or, if the builtin takes optional parameters: * * mf_c_arglist(STRING a, NUMBER n) => * long __bi_argcnt = (long)get_numeric_arg(env, 0); * char *a = (char*)get_string_arg(env, 1); * long n = (long)get_numeric_arg(env, 2); * adjust_stack(env, __bi_argcnt + 1); */ m4_define([],m4_dnl [< m4_pushdef([<__ARG1__>], m4_ifelse(__MF_VARARGS__,1,1,[<__mf_has_optarg($@)>])) m4_ifelse(__ARG1__,0,,[]) __mf_c_arglist(__ARG1__, $@) adjust_stack(env, m4_ifelse(__ARG1__,0,mf_argcount($@),__bi_argcnt + 1)); m4_popdef([<__ARG1__>])m4_dnl >]) /* __mf_printf_type(TYPE) -- translate the Mailfromd data type TYPE into the * printf metacharacter useful to output it. */ m4_define([<__mf_printf_type>],m4_dnl []) /* mf_printf_macro(TYPE NAME) -- translate TYPE to the printf metacharacter * for use in *printf functions. */ m4_define([],m4_dnl [<%[<>]m4_regexp([<$1>],[<\(\w+\)\W+.*>],[<__mf_printf_type(\1)>])>]) /* mf_printf_list(LIST) -- convert the list of Mailfromd variable declarations * to a space-separated list of printf macros to print them: * mf_printf_list(STRING a, NUMBER b) => %s %lu */ m4_define([],m4_dnl [],m4_dnl [],m4_dnl [< mf_printf_macro($1)[<>]mf_printf_list(m4_shift($@))>])>]) /* __mf_argname(TYPE NAME) -- return NAME */ m4_define([<__mf_argname>],m4_dnl [],\1)>]) /* mf_argnames(LIST) -- extract names from the Mailfromd declaration list: * mf_argnames(STRING a, NUMBER b) => a, b */ m4_define([],m4_dnl [],m4_dnl $1,[],[],m4_dnl [<__mf_argname($1), mf_argnames(m4_shift($@))>])>]) /* __mf_defined_argname(TYPE NAME) -- Same as __mf_argname, but wrap the * argument into MF_OPTVAL if necessary */ m4_define([<__mf_defined_argname>],m4_dnl [],"",0))>],m4_dnl [<__mf_argname($2)>])>]) /* __mf_defined_argnames(LIST) -- Same as __mf_argnames, but arguments after * the OPTIONAL keywords are protected by MF_OPTVAL */ m4_define([<__mf_defined_argnames>],m4_dnl [],m4_dnl $2,[],[<__mf_defined_argnames(1,m4_shift(m4_shift($@)))>],m4_dnl [<__mf_defined_argname($1,$2), m4_dnl __mf_defined_argnames($1,m4_shift(m4_shift($@)))>])>]) /* mf_defined_argnames(LIST) -- Same as mf_argnames, but arguments after * the OPTIONAL keywords are protected by MF_OPTVAL */ m4_define([],m4_dnl [<__mf_defined_argnames(0,$@)>]) /* __mf_argpos(POS,NEEDLE,STACK...) - Return position at which NEEDLE occurs in * STACK * Arguments: * POS - Current position * NEEDLE - String to find * STACK - Argument list * Example: * __mf_argpos(0, x, a, b, x) => 2 */ m4_define([<__mf_argpos>],m4_dnl []$2[< )>],[<__mf_argpos(m4_incr($1), $2, m4_shift(m4_shift(m4_shift($@))))>])>]) /* mf_argpos(ARG, TYPE1 ARG1, TYPE2 ARG2 ...) - Return (zero-based) position * of ARG in the argument list: * * mf_argpos(x, STRING a, NUMBER b, OPTIONAL, STRING x) => 3 */ m4_define([],m4_dnl [<__mf_argpos(0, $1, mf_argnames(m4_shift($@)))>]) /* __mf_defined(NAME, ARGS...) -- Scan ARGS... for the definition * of the built-in function parameter NAME, and return a C conditional * expression that yields true if it is defined. * ARGS are parameter declarations in the form: * TYPE NAME */ m4_define([<__mf_defined>], [ mf_argpos($1,__MF_ARGLIST__)>])>]) /* MF_DEFINED(NAME) -- Return a C conditional expression * that yields true if the parameter NAME is defined. * * __MF_ARGLIST__ => STRING a, NUMBER b, OPTIONAL, STRING x * MF_DEFINED(x) => (__bi_argcnt > 2) * * __MF_ARGLIST__ => STRING a, NUMBER b, STRING x * MF_DEFINED(x) => (1) */ m4_define([], [],([<__mf_defined($1, __MF_ARGLIST__)>]),m4_dnl [])>])>]) /* MF_OPTVAL(NAME[, DEFVAL]) -- If the parameter NAME is defined, return * its value, otherwise return DEFVAL or 0 */ m4_define([], [],m4_dnl [<(MF_DEFINED($1) ? $1 : m4_ifelse([<$2>],,0,$2))>],m4_dnl [])>])>]) /* __mf_check_end() -- signal error if the previous MF_DEFUN statement was * not properly closed with END */ m4_define([<__mf_check_end>],m4_dnl [],m4_dnl []__MF_FUNCTION__[<' was not closed ) m4_popdef([<__MF_FUNCTION__>]) m4_define([<__mf_error_code>],1)>])>]) /* MF_STATE(state) - Declare next MF_DEFUN as valid only in the given state. * The state argument is any valid milter state, as declared in * enum smtp_state (see mailfromd.h around line 74--87), but withouth the * `smtp_state_' prefix. * * Multiple occurrences of MF_STATE accumulate. */ m4_define([], [],m4_dnl [],__MF_STATE__[< | EXMASK(smtp_state_$1)>])>],m4_dnl [],[])>])>]) /* MF_CAPTURE - Declare next MF_DEFUN as requiring message capturing */ m4_define([], [],,[],1)>])>]) /* env_get_stream - a wrapper around the library function of the same name. * Expand to the function invocation only if the current function is declared * with capture attribute or the invocation is issued outside of a defun. */ m4_define([],m4_dnl [],m4_dnl [],[<[]($@)>],m4_dnl []__MF_FUNCTION__[<' is not declared with MF_CAPTURE>] ) m4_define([<__mf_error_code>],1)>])>],m4_dnl [])>]) /* mf_optcount(ARGS...) -- Return the number of optional arguments in ARGS */ m4_define([],[],m4_eval($# - 1),[])>]) /* __mf_argcount(COUNT, ARGS...) -- Auxiliary function for mf_argcount * COUNT is number of arguments counted so far * ARGS are the rest of the arguments */ m4_define([<__mf_argcount>],[],[<__mf_argcount($1, m4_shift(m4_shift($@)))>],m4_dnl [<__mf_argcount(m4_incr($1), m4_shift(m4_shift($@)))>])>]) /* mf_argcount(ARGS...) -- Return the number of arguments in ARGS, not * counting eventual OPTIONAL modifier. */ m4_define([],[]) /* mf_prog_trace(fname[, args...]) */ m4_define([],[]mf_printf_list(m4_shift($@))"m4_dnl m4_ifelse($2,,,[<,mf_defined_argnames(m4_shift($@))>]));>]) /* __mf_defun(VARARG, NAME, RETTYPE, ARGS...) -- Begin a built-in function declaration */ m4_define([<__mf_defun>],m4_dnl [<__mf_check_end[<>]m4_dnl void bi_$2(eval_environ_t env) m4_pushdef([<__MF_FUNCTION__>], $2)m4_dnl m4_pushdef([<__MF_ARGLIST__>], []) m4_pushdef([<__MF_VARARGS__>], $1)m4_dnl m4_divert(1)m4_dnl va_builtin_install_ex("$2", bi_$2,m4_dnl m4_ifdef([<__MF_STATE__>],__MF_STATE__,0),m4_dnl m4_ifdef([<__MF_CAPTURE__>],__MF_CAPTURE__,0),m4_dnl __mf_argtype($3),m4_dnl mf_argcount(m4_shift(m4_shift(m4_shift($@)))),m4_dnl mf_optcount(m4_shift(m4_shift(m4_shift($@)))),m4_dnl $1,m4_dnl mf_typelist(m4_shift(m4_shift(m4_shift($@))))); m4_divert(0)m4_dnl { mf_c_arglist(m4_shift(m4_shift(m4_shift($@)))) if (prog_trace_option & MF_MODULE_MASK) mf_prog_trace($2,m4_shift(m4_shift(m4_shift($@)))); >]) m4_define([],[<__mf_defun(0, $@)>]) m4_define([],[],m4_dnl [],1)>])>]) /* MF_RETURN(value) - Return a numeric value */ m4_define([],[< m4_ifdef([<__MF_VA_START_USED__>],[] used before [] ) m4_define([<__mf_error_code>],1)>],[])>]) /* MF_RETURN_STRING(value) - Return a string value */ m4_define([],[],[] used before [] ) m4_define([<__mf_error_code>],1)>],[])>]) /* MF_ALLOC_HEAP(off, len) - Allocate LEN bytes from the heap */ m4_define([],[] = heap_reserve(env, $2)))>]) /* MF_ALLOC_HEAP_TEMP(len) - Temporarly allocate LEN bytes from the heap. */ m4_define([],[]) /* MF_COPY_STRING(off, string) - Copy STRING to the heap. Return the * pointer to the copy. */ m4_define([],[]) /* MF_OBSTACK_BEGIN() - Begin temporary space manipulations * NOTE: No other heap manipulation function can be used between * MF_OBSTACK_BEGIN and MF_OBSTACK_CANCEL/MF_RETURN_OBSTACK */ m4_define([],[]) m4_define([],[])heap_obstack_grow(env, __s, strlen(__s)); } while (0)>],[])heap_obstack_grow(env, $1, $2)>])>]) m4_define([],[]) m4_dnl /* MF_OBSTACK_CANCEL - Cancel temporary heap allocation initiated by m4_dnl * MF_OBSTACK_BEGIN m4_fnl */ m4_dnl m4_define([],[]) /* MF_RETURN_OBSTACK() - Relocate and return temporary space */ m4_define([],[]) /* MF_VA_START() -- Begin a code section for handing varying number of arguments. */ m4_define([],[< m4_ifelse(__MF_VARARGS__,1,[],m4___file__:m4___line__)m4_dnl unroll_stack(env, __bi_argcnt + 1)>], [] used but `__MF_FUNCTION__' does not take variable number of arguments )m4_dnl m4_define([<__mf_error_code>],1)>])>]) /* MF_VA_END() -- End a section, started with MF_VA_START */ m4_define([],[],[])m4_dnl adjust_stack(env, __bi_argcnt + 1)>],m4_dnl [] without previous [] ) m4_define([<__mf_error_code>],1)>])>]) /* __mf_va_count() -- return number of variable arguments passed to the current vararg function */ m4_define([<__mf_va_count>],[]) /* MF_VA_COUNT() -- return actual number of variable arguments passed to the function. Bail out if the function is not a vararg one. */ m4_define([],[], [] used but `__MF_FUNCTION__' does not take variable number of arguments )m4_dnl m4_define([<__mf_error_code>],1)>])>]) /* MF_VA_ARG(N, TYPE) -- Produce a code for returning Nth argument of the given TYPE in a vararg section. */ m4_define([],[],m4_dnl [],[<$1+mf_argcount(__MF_ARGLIST__)>]) ((__bi_argcnt > __ARGN__) ?m4_dnl __mf_c_getarg($2)(env, __ARGN__ + 1) :m4_dnl (MF_THROW(mf_range, "Argument %d is not supplied", __ARGN__),m4_dnl (__mf_c_type($2)) 0))m4_dnl m4_popdef([<__ARGN__>])>], [] without previous [] ) m4_define([<__mf_error_code>],1)>])>]) /* MF_VAR(name,type) - Declare a global variable NAME of type TYPE. */ m4_define([],[off; m4_divert(0)m4_dnl >]) /* MF_VAR_REF(name[, value]) - Reference global variable NAME * In one-argument form, return its value. In two-arguments form, assign * the VALUE to it. */ m4_define([],[]) /* MF_VAR_SET_STRING(name, value) - Set variable NAME to the string VALUE */ m4_define([],[< { size_t off; if ($2) MF_COPY_STRING(off, $2); else off = 0; MF_VAR_REF($1, off); } >]) /* MF_VAR_INC(name) - Increment the value of the global variable NAME */ m4_define([],[]) /* MF_DECLARE_DATA(name, init [, destr]) - Declare private data for * the current module. * NAME - data identifier. * INIT - initialization function (void init(void)) * DESTR - destructor function (void destr(void*)) */ m4_define([],[< m4_define([<__MF_PRIV_ID__>],$1_id) static int __MF_PRIV_ID__; m4_divert(1)m4_dnl __MF_PRIV_ID__ = builtin_priv_register($2, m4_dnl m4_ifelse($3,,NULL,$3)); m4_divert(0)m4_dnl >]) /* MF_GET_DATA - Return pointer to the private data, declared with * MF_DECLARE_DATA */ m4_define([],[],[],m4_dnl [] first) ) m4_define([<__mf_error_code>],1) >])>]) /* MF_THROW(exception, ...) */ m4_define([],[],m4_dnl "__MF_FUNCTION__", NULL), m4_shift($@))>]) /* MF_ASSERT(cond, exception, ...) */ m4_define([],[]) /* END -- Finish the built-in function declaration, created with MF_DEFUN */ m4_define([],m4_dnl [],[] )m4_dnl m4_errprint(>]__MF_VA_START_USED__[<: This is the location of [] )m4_dnl m4_define([<__mf_error_code>],1)m4_dnl m4_undefine([<__MF_VA_START_USED__>])>])m4_dnl m4_popdef([<__MF_FUNCTION__>])m4_dnl m4_popdef([<__MF_ARGLIST__>])m4_dnl m4_popdef([<__MF_VARARGS__>])m4_dnl m4_undefine([<__MF_CAPTURE__>])m4_dnl m4_undefine([<__MF_STATE__>])m4_dnl }>]) /* MF_INIT(CODE) -- create the initialization function for the curent module. * The function will be named MODNAME_init_builtin. */ m4_define([],m4_dnl [<__mf_check_end[<>]m4_dnl m4_undefine([<__MF_PRIV_ID__>])m4_dnl m4_define([<__MF_INIT__>],1) void MF_MODULE_NAME()_init_builtin() { m4_undivert(1) $1 }>]) m4_m4wrap([<__mf_check_end m4_ifdef([<__MF_INIT__>],,[] not defined ) m4_define([<__mf_error_code>],1)>]) m4_ifdef([<__mf_error_code>],[])>]) m4_divert(0)m4_dnl /* -*- buffer-read-only: t -*- vi: set ro: THIS FILE IS GENERATED AUTOMATICALLY. PLEASE DO NOT EDIT. */ MF_SOURCE_DEBUG_NAME(SOURCE) #ifdef HAVE_CONFIG_H # include #endif #include #include "mailfromd.h" #include "prog.h" #include "builtin.h" m4_dnl End of snarf.m4