Skip to content
Toggle navigation
Toggle navigation
This project
Loading...
Sign in
John McEleney
/
mailutils
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Issue Boards
Files
Commits
Network
Compare
Branches
Tags
Commit
2233fe22
...
2233fe22de4e6ff71d711b833cff595bd98b2b09
authored
2002-11-12 16:27:47 +0000
by
Sergey Poznyakoff
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
Added basic code generation and debugging
1 parent
0ba30cb1
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
462 additions
and
46 deletions
include/mailutils/libsieve.h
libsieve/actions.c
libsieve/register.c
libsieve/sieve.h
libsieve/sieve.l
libsieve/sieve.y
libsieve/sv.c
libsieve/tests.c
libsieve/util.c
include/mailutils/libsieve.h
View file @
2233fe2
...
...
@@ -16,11 +16,15 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <sys/types.h>
#include <stdarg.h>
#include <mailutils/mailutils.h>
typedef
struct
sieve_machine
sieve_machine_t
;
typedef
int
(
*
sieve_instr_t
)
__P
((
sieve_machine_t
*
mach
,
list_t
*
args
));
typedef
int
(
*
sieve_handler_t
)
__P
((
sieve_machine_t
*
mach
,
list_t
args
,
list_t
tags
));
typedef
int
(
*
sieve_printf_t
)
__P
((
void
*
data
,
const
char
*
fmt
,
va_list
ap
));
typedef
int
(
*
sieve_vprintf_t
)
__P
((
void
*
data
,
const
char
*
fmt
,
va_list
ap
));
typedef
enum
{
SVT_VOID
,
...
...
@@ -32,12 +36,15 @@ typedef enum {
SVT_VALUE_LIST
}
sieve_data_type
;
typedef
struct
sieve_runtime_tag
sieve_runtime_tag_t
;
typedef
struct
{
sieve_data_type
type
;
union
{
char
*
string
;
long
number
;
list_t
list
;
sieve_runtime_tag_t
*
tag
;
}
v
;
}
sieve_value_t
;
...
...
@@ -47,10 +54,15 @@ typedef struct {
sieve_data_type
argtype
;
}
sieve_tag_def_t
;
struct
sieve_runtime_tag
{
int
tag
;
sieve_value_t
*
arg
;
};
typedef
struct
{
char
*
name
;
int
required
;
sieve_
instr_t
inst
r
;
sieve_
handler_t
handle
r
;
int
num_req_args
;
sieve_data_type
*
req_args
;
int
num_tags
;
...
...
@@ -59,18 +71,28 @@ typedef struct {
void
*
sieve_alloc
__P
((
size_t
size
));
int
sieve_open_source
__P
((
const
char
*
name
));
int
sieve_parse
__P
((
const
char
*
name
));
void
*
sieve_palloc
__P
((
list_t
*
pool
,
size_t
size
));
void
*
sieve_prealloc
__P
((
list_t
*
pool
,
void
*
ptr
,
size_t
size
));
void
sieve_pfree
__P
((
list_t
*
pool
,
void
*
ptr
));
char
*
sieve_pstrdup
__P
((
list_t
*
pool
,
const
char
*
str
));
int
sieve_compile
__P
((
sieve_machine_t
*
mach
,
const
char
*
name
,
void
*
data
,
sieve_printf_t
errfn
));
void
sieve_set_debug
__P
((
sieve_machine_t
*
mach
,
sieve_printf_t
debug
,
int
level
));
sieve_value_t
*
sieve_value_create
__P
((
sieve_data_type
type
,
void
*
data
));
sieve_register_t
*
sieve_test_lookup
__P
((
const
char
*
name
));
sieve_register_t
*
sieve_action_lookup
__P
((
const
char
*
name
));
int
sieve_register_test
__P
((
const
char
*
name
,
sieve_
instr_t
inst
r
,
int
sieve_register_test
__P
((
const
char
*
name
,
sieve_
handler_t
handle
r
,
sieve_data_type
*
arg_types
,
sieve_tag_def_t
*
tags
,
int
required
));
int
sieve_register_action
__P
((
const
char
*
name
,
sieve_
instr_t
inst
r
,
int
sieve_register_action
__P
((
const
char
*
name
,
sieve_
handler_t
handle
r
,
sieve_data_type
*
arg_types
,
sieve_tag_def_t
*
tags
,
int
required
));
void
sieve_slist_destroy
__P
((
list_t
*
plist
));
void
sieve_require
__P
((
list_t
slist
));
void
sieve_abort
__P
((
sieve_machine_t
*
mach
));
...
...
libsieve/actions.c
View file @
2233fe2
...
...
@@ -26,33 +26,39 @@
#include <sieve.h>
int
sieve_action_stop
(
sieve_machine_t
*
mach
,
list_t
*
ar
gs
)
sieve_action_stop
(
sieve_machine_t
*
mach
,
list_t
args
,
list_t
ta
gs
)
{
return
0
;
}
int
sieve_action_keep
(
sieve_machine_t
*
mach
,
list_t
*
ar
gs
)
sieve_action_keep
(
sieve_machine_t
*
mach
,
list_t
args
,
list_t
ta
gs
)
{
return
0
;
}
int
sieve_action_discard
(
sieve_machine_t
*
mach
,
list_t
*
ar
gs
)
sieve_action_discard
(
sieve_machine_t
*
mach
,
list_t
args
,
list_t
ta
gs
)
{
return
0
;
}
int
sieve_action_fileinto
(
sieve_machine_t
*
mach
,
list_t
*
ar
gs
)
sieve_action_fileinto
(
sieve_machine_t
*
mach
,
list_t
args
,
list_t
ta
gs
)
{
return
0
;
}
int
sieve_action_reject
(
sieve_machine_t
*
mach
,
list_t
*
ar
gs
)
sieve_action_reject
(
sieve_machine_t
*
mach
,
list_t
args
,
list_t
ta
gs
)
{
return
0
;
}
int
sieve_action_redirect
(
sieve_machine_t
*
mach
,
list_t
*
ar
gs
)
sieve_action_redirect
(
sieve_machine_t
*
mach
,
list_t
args
,
list_t
ta
gs
)
{
return
0
;
}
sieve_data_type
fileinto_args
[]
=
{
...
...
libsieve/register.c
View file @
2233fe2
...
...
@@ -35,7 +35,7 @@ sieve_lookup (list_t list, const char *name)
sieve_register_t
*
reg
;
if
(
!
list
||
iterator_create
(
&
itr
,
list
))
return
;
return
NULL
;
for
(
iterator_first
(
itr
);
!
iterator_is_done
(
itr
);
iterator_next
(
itr
))
{
...
...
@@ -63,7 +63,7 @@ sieve_action_lookup (const char *name)
static
int
sieve_register
(
list_t
*
list
,
const
char
*
name
,
sieve_
instr_t
inst
r
,
const
char
*
name
,
sieve_
handler_t
handle
r
,
sieve_data_type
*
arg_types
,
sieve_tag_def_t
*
tags
,
int
required
)
{
...
...
@@ -73,7 +73,7 @@ sieve_register (list_t *list,
if
(
!
reg
)
return
ENOMEM
;
reg
->
name
=
name
;
reg
->
instr
=
inst
r
;
reg
->
handler
=
handle
r
;
if
(
arg_types
)
{
...
...
@@ -111,17 +111,17 @@ sieve_register (list_t *list,
int
sieve_register_test
(
const
char
*
name
,
sieve_
instr_t
inst
r
,
sieve_register_test
(
const
char
*
name
,
sieve_
handler_t
handle
r
,
sieve_data_type
*
arg_types
,
sieve_tag_def_t
*
tags
,
int
required
)
{
return
sieve_register
(
&
test_list
,
name
,
inst
r
,
arg_types
,
tags
,
required
);
return
sieve_register
(
&
test_list
,
name
,
handle
r
,
arg_types
,
tags
,
required
);
}
int
sieve_register_action
(
const
char
*
name
,
sieve_
instr_t
inst
r
,
sieve_register_action
(
const
char
*
name
,
sieve_
handler_t
handle
r
,
sieve_data_type
*
arg_types
,
sieve_tag_def_t
*
tags
,
int
required
)
{
return
sieve_register
(
&
action_list
,
name
,
inst
r
,
arg_types
,
tags
,
required
);
return
sieve_register
(
&
action_list
,
name
,
handle
r
,
arg_types
,
tags
,
required
);
}
...
...
libsieve/sieve.h
View file @
2233fe2
...
...
@@ -16,20 +16,78 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <mailutils/libsieve.h>
#include <setjmp.h>
#define SIEVE_CODE_INCR 128
typedef
void
(
*
sieve_instr_t
)
__P
((
sieve_machine_t
*
mach
));
typedef
union
{
sieve_instr_t
instr
;
sieve_value_t
val
;
sieve_handler_t
handler
;
sieve_value_t
*
val
;
list_t
list
;
long
number
;
char
*
string
;
}
sieve_op_t
;
struct
sieve_machine
{
size_t
progsize
;
sieve_op_t
*
prog
;
list_t
memory_pool
;
/* Pool of allocated memory objects */
size_t
progsize
;
/* Number of allocated program cells */
size_t
pc
;
/* Current program counter */
sieve_op_t
*
prog
;
/* Compiled program */
long
reg
;
/* Numeric register */
list_t
stack
;
/* Runtime stack */
int
debug_level
;
sieve_printf_t
error_printer
;
sieve_printf_t
debug_printer
;
void
*
data
;
jmp_buf
errbuf
;
};
extern
char
*
sieve_filename
;
extern
int
sieve_line_num
;
extern
int
sieve_yydebug
;
extern
sieve_machine_t
*
sieve_machine
;
extern
int
sieve_error_count
;
void
sieve_error
__P
((
const
char
*
fmt
,
...));
void
sieve_debug_internal
__P
((
sieve_printf_t
printer
,
void
*
data
,
const
char
*
fmt
,
...));
void
sieve_debug
__P
((
sieve_machine_t
*
mach
,
const
char
*
fmt
,
...));
void
sieve_print_value
__P
((
sieve_value_t
*
val
,
sieve_printf_t
printer
,
void
*
data
));
void
sieve_print_value_list
__P
((
list_t
list
,
sieve_printf_t
printer
,
void
*
data
));
void
sieve_print_tag_list
__P
((
list_t
list
,
sieve_printf_t
printer
,
void
*
data
));
int
_sieve_default_error_printer
__P
((
void
*
data
,
const
char
*
fmt
,
va_list
ap
));
int
sieve_lex_begin
__P
((
const
char
*
name
));
void
sieve_lex_finish
__P
((
void
));
#define sieve_error mu_error
void
sieve_register_standard_actions
__P
((
void
));
void
sieve_register_standard_tests
__P
((
void
));
int
sieve_code
__P
((
sieve_op_t
*
op
));
int
sieve_code_instr
__P
((
sieve_instr_t
instr
));
int
sieve_code_handler
__P
((
sieve_handler_t
handler
));
int
sieve_code_list
__P
((
list_t
list
));
int
sieve_code_number
__P
((
long
num
));
int
sieve_code_test
__P
((
sieve_register_t
*
reg
,
list_t
arglist
));
int
sieve_code_action
__P
((
sieve_register_t
*
reg
,
list_t
arglist
));
void
instr_action
__P
((
sieve_machine_t
*
mach
));
void
instr_test
__P
((
sieve_machine_t
*
mach
));
void
instr_push
__P
((
sieve_machine_t
*
mach
));
void
instr_pop
__P
((
sieve_machine_t
*
mach
));
void
instr_allof
__P
((
sieve_machine_t
*
mach
));
void
instr_anyof
__P
((
sieve_machine_t
*
mach
));
void
instr_not
__P
((
sieve_machine_t
*
mach
));
...
...
libsieve/sieve.l
View file @
2233fe2
...
...
@@ -282,8 +282,9 @@ int
pop_source ()
{
struct buffer_ctx *ctx;
fclose (yyin);
if (yyin)
fclose (yyin);
#ifndef FLEX_SCANNER
lex_delete_buffer (current_buffer);
#endif
...
...
@@ -402,10 +403,17 @@ sieve_include ()
}
int
sieve_
open_source
(const char *name)
sieve_
lex_begin
(const char *name)
{
return push_source (name);
}
void
sieve_lex_finish ()
{
while (pop_source () == 0)
;
}
int
number ()
...
...
@@ -434,7 +442,7 @@ number ()
int
string ()
{
yylval.string = sieve_
alloc (
yyleng - 1);
yylval.string = sieve_
palloc (&sieve_machine->memory_pool,
yyleng - 1);
memcpy (yylval.string, yytext + 1, yyleng - 2);
yylval.string[yyleng - 2] = 0;
return STRING;
...
...
@@ -486,7 +494,7 @@ multiline_finish ()
}
/* Copy the contents */
yylval.string = sieve_
alloc (
length + 1);
yylval.string = sieve_
palloc (&sieve_machine->memory_pool,
length + 1);
p = yylval.string;
for (iterator_first (itr); !iterator_is_done (itr); iterator_next (itr))
{
...
...
libsieve/sieve.y
View file @
2233fe2
...
...
@@ -23,6 +23,9 @@
#include <stdlib.h>
#include <assert.h>
#include <sieve.h>
sieve_machine_t *sieve_machine;
int sieve_error_count;
%}
%union {
...
...
@@ -31,6 +34,7 @@
sieve_instr_t instr;
sieve_value_t *value;
list_t list;
size_t pc;
struct {
char *ident;
list_t args;
...
...
@@ -45,11 +49,14 @@
%type <value> arg
%type <list> slist stringlist arglist maybe_arglist
%type <command> command
%type <number> testlist
%type <pc> action test statement list
%%
input : /* empty */
| list
{ /* to placate bison */ }
;
list : statement
...
...
@@ -59,10 +66,15 @@ list : statement
statement : REQUIRE stringlist ';'
{
sieve_require ($2);
sieve_slist_destroy ($2);
sieve_slist_destroy (&$2);
$$ = sieve_machine->pc;
}
| action ';'
| IF cond block maybe_elsif maybe_else
{
/* FIXME!! */
$$ = sieve_machine->pc;
}
;
maybe_elsif : /* empty */
...
...
@@ -82,18 +94,45 @@ block : '{' list '}'
testlist : cond
{
if (sieve_code_instr (instr_push))
YYERROR;
$$ = 1;
}
| testlist ',' cond
{
if (sieve_code_instr (instr_push))
YYERROR;
$$ = $1 + 1;
}
;
cond : test
{ /* to placate bison */ }
| ANYOF '(' testlist ')'
{
if (sieve_code_instr (instr_anyof)
|| sieve_code_number ($3))
YYERROR;
}
| ALLOF '(' testlist ')'
{
if (sieve_code_instr (instr_allof)
|| sieve_code_number ($3))
YYERROR;
}
| NOT cond
{
if (sieve_code_instr (instr_not))
YYERROR;
}
;
test : command
{
sieve_register_t *reg = sieve_test_lookup ($1.ident);
$$ = sieve_machine->pc;
if (!reg)
sieve_error ("%s:%d: unknown test: %s",
sieve_filename, sieve_line_num,
...
...
@@ -102,7 +141,8 @@ test : command
sieve_error ("%s:%d: test `%s' has not been required",
sieve_filename, sieve_line_num,
$1.ident);
/*free unneeded memory */
if (sieve_code_test (reg, $1.args))
YYERROR;
}
;
...
...
@@ -116,6 +156,8 @@ command : IDENT maybe_arglist
action : command
{
sieve_register_t *reg = sieve_action_lookup ($1.ident);
$$ = sieve_machine->pc;
if (!reg)
sieve_error ("%s:%d: unknown action: %s",
sieve_filename, sieve_line_num,
...
...
@@ -124,7 +166,8 @@ action : command
sieve_error ("%s:%d: action `%s' has not been required",
sieve_filename, sieve_line_num,
$1.ident);
/*free unneeded memory */
if (sieve_code_action (reg, $1.args))
YYERROR;
}
;
...
...
@@ -138,11 +181,11 @@ maybe_arglist: /* empty */
arglist : arg
{
list_create (&$$);
list_append ($$,
&
$1);
list_append ($$, $1);
}
| arglist arg
{
list_append ($1,
&
$2);
list_append ($1, $2);
$$ = $1;
}
;
...
...
@@ -197,12 +240,42 @@ yyerror (char *s)
return 0;
}
/* FIXME: When posix thread support is added, sieve_machine_begin() should
aquire the global mutex, locking the current compilation session, and
sieve_machine_finish() should release it */
void
sieve_machine_begin (sieve_machine_t *mach, sieve_printf_t err, void *data)
{
memset (mach, 0, sizeof (*mach));
mach->error_printer = err ? err : _sieve_default_error_printer;
mach->data = data;
sieve_machine = mach;
sieve_error_count = 0;
sieve_code_instr (NULL);
}
void
sieve_machine_finish (sieve_machine_t *mach)
{
sieve_code_instr (NULL);
}
int
sieve_parse (const char *name)
sieve_compile (sieve_machine_t *mach, const char *name,
void *extra_data, sieve_printf_t err)
{
int rc;
sieve_machine_begin (mach, err, extra_data);
sieve_register_standard_actions ();
sieve_register_standard_tests ();
sieve_open_source (name);
return yyparse ();
sieve_lex_begin (name);
rc = yyparse ();
sieve_lex_finish ();
sieve_machine_finish (mach);
if (sieve_error_count)
rc = 1;
return rc;
}
...
...
libsieve/sv.c
View file @
2233fe2
...
...
@@ -24,18 +24,34 @@
#include <sieve.h>
int
debug_printer
(
void
*
unused
,
const
char
*
fmt
,
va_list
ap
)
{
return
vfprintf
(
stderr
,
fmt
,
ap
);
}
int
main
(
int
argc
,
char
**
argv
)
{
int
n
;
int
n
,
rc
,
debug
=
0
;
sieve_machine_t
mach
;
assert
(
argc
>
1
);
if
(
strcmp
(
argv
[
1
],
"-d"
)
==
0
)
{
sieve_yydebug
++
;
n
=
2
;
debug
++
;
assert
(
argc
>
2
);
}
else
n
=
1
;
return
sieve_parse
(
argv
[
n
]);
rc
=
sieve_compile
(
&
mach
,
argv
[
n
],
NULL
,
NULL
);
if
(
rc
==
0
)
{
if
(
debug
)
sieve_set_debug
(
&
mach
,
debug_printer
,
100
);
sieve_run
(
&
mach
);
}
return
rc
;
}
...
...
libsieve/tests.c
View file @
2233fe2
...
...
@@ -37,38 +37,45 @@
#define TAG_OVER 9
int
sieve_test_address
(
sieve_machine_t
*
mach
,
list_t
*
ar
gs
)
sieve_test_address
(
sieve_machine_t
*
mach
,
list_t
args
,
list_t
ta
gs
)
{
return
0
;
}
int
sieve_test_header
(
sieve_machine_t
*
mach
,
list_t
*
ar
gs
)
sieve_test_header
(
sieve_machine_t
*
mach
,
list_t
args
,
list_t
ta
gs
)
{
return
0
;
}
int
sieve_test_envelope
(
sieve_machine_t
*
mach
,
list_t
*
ar
gs
)
sieve_test_envelope
(
sieve_machine_t
*
mach
,
list_t
args
,
list_t
ta
gs
)
{
return
0
;
}
int
sieve_test_size
(
sieve_machine_t
*
mach
,
list_t
*
ar
gs
)
sieve_test_size
(
sieve_machine_t
*
mach
,
list_t
args
,
list_t
ta
gs
)
{
return
0
;
}
int
sieve_test_true
(
sieve_machine_t
*
mach
,
list_t
*
ar
gs
)
sieve_test_true
(
sieve_machine_t
*
mach
,
list_t
args
,
list_t
ta
gs
)
{
return
0
;
}
int
sieve_test_false
(
sieve_machine_t
*
mach
,
list_t
*
ar
gs
)
sieve_test_false
(
sieve_machine_t
*
mach
,
list_t
args
,
list_t
ta
gs
)
{
return
0
;
}
int
sieve_test_exists
(
sieve_machine_t
*
mach
,
list_t
*
ar
gs
)
sieve_test_exists
(
sieve_machine_t
*
mach
,
list_t
args
,
list_t
ta
gs
)
{
return
0
;
}
#define ADDRESS_PART \
...
...
libsieve/util.c
View file @
2233fe2
...
...
@@ -21,12 +21,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <sieve.h>
void
*
sieve_alloc
(
size_t
size
)
{
char
*
p
=
malloc
(
size
);
void
*
p
=
malloc
(
size
);
if
(
!
p
)
{
mu_error
(
"not enough memory"
);
...
...
@@ -35,6 +36,70 @@ sieve_alloc (size_t size)
return
p
;
}
void
*
sieve_palloc
(
list_t
*
pool
,
size_t
size
)
{
void
*
p
=
malloc
(
size
);
if
(
p
)
{
if
(
!*
pool
&&
list_create
(
pool
))
{
free
(
p
);
return
NULL
;
}
list_append
(
*
pool
,
p
);
}
return
p
;
}
char
*
sieve_pstrdup
(
list_t
*
pool
,
const
char
*
str
)
{
size_t
len
;
char
*
p
;
if
(
!
str
)
return
NULL
;
len
=
strlen
(
str
);
p
=
sieve_palloc
(
pool
,
len
+
1
);
if
(
p
)
{
memcpy
(
p
,
str
,
len
);
p
[
len
]
=
0
;
}
return
p
;
}
void
*
sieve_prealloc
(
list_t
*
pool
,
void
*
ptr
,
size_t
size
)
{
void
*
newptr
;
if
(
*
pool
)
list_remove
(
*
pool
,
ptr
);
newptr
=
realloc
(
ptr
,
size
);
if
(
newptr
)
{
if
(
!*
pool
&&
list_create
(
pool
))
{
free
(
newptr
);
return
NULL
;
}
list_append
(
*
pool
,
newptr
);
}
return
newptr
;
}
void
sieve_pfree
(
list_t
*
pool
,
void
*
ptr
)
{
if
(
*
pool
)
list_remove
(
*
pool
,
ptr
);
free
(
ptr
);
}
void
sieve_slist_destroy
(
list_t
*
plist
)
{
...
...
@@ -85,3 +150,164 @@ sieve_value_create (sieve_data_type type, void *data)
return
val
;
}
void
sieve_error
(
const
char
*
fmt
,
...)
{
va_list
ap
;
va_start
(
ap
,
fmt
);
sieve_error_count
++
;
sieve_machine
->
error_printer
(
sieve_machine
->
data
,
fmt
,
ap
);
va_end
(
ap
);
}
void
sieve_debug_internal
(
sieve_printf_t
printer
,
void
*
data
,
const
char
*
fmt
,
...)
{
va_list
ap
;
va_start
(
ap
,
fmt
);
printer
(
data
,
fmt
,
ap
);
va_end
(
ap
);
}
void
sieve_debug
(
sieve_machine_t
*
mach
,
const
char
*
fmt
,
...)
{
va_list
ap
;
va_start
(
ap
,
fmt
);
mach
->
debug_printer
(
mach
->
data
,
fmt
,
ap
);
va_end
(
ap
);
}
int
_sieve_default_error_printer
(
void
*
unused
,
const
char
*
fmt
,
va_list
ap
)
{
return
mu_verror
(
fmt
,
ap
);
}
char
*
sieve_type_str
(
sieve_data_type
type
)
{
switch
(
type
)
{
case
SVT_VOID
:
return
"void"
;
case
SVT_NUMBER
:
return
"number"
;
case
SVT_STRING
:
return
"string"
;
case
SVT_STRING_LIST
:
return
"string-list"
;
case
SVT_TAG
:
return
"tag"
;
case
SVT_IDENT
:
return
"ident"
;
case
SVT_VALUE_LIST
:
return
"value-list"
;
}
return
"unknown"
;
}
struct
debug_data
{
sieve_printf_t
printer
;
void
*
data
;
};
static
int
string_printer
(
char
*
s
,
struct
debug_data
*
dbg
)
{
sieve_debug_internal
(
dbg
->
printer
,
dbg
->
data
,
"
\"
%s
\"
"
,
s
);
return
0
;
}
static
int
value_printer
(
sieve_value_t
*
val
,
struct
debug_data
*
dbg
)
{
sieve_print_value
(
val
,
dbg
->
printer
,
dbg
->
data
);
sieve_debug_internal
(
dbg
->
printer
,
dbg
->
data
,
" "
);
return
0
;
}
void
sieve_print_value
(
sieve_value_t
*
val
,
sieve_printf_t
printer
,
void
*
data
)
{
struct
debug_data
dbg
;
dbg
.
printer
=
printer
;
dbg
.
data
=
data
;
sieve_debug_internal
(
printer
,
data
,
"%s("
,
sieve_type_str
(
val
->
type
));
switch
(
val
->
type
)
{
case
SVT_VOID
:
break
;
case
SVT_NUMBER
:
sieve_debug_internal
(
printer
,
data
,
"%ld"
,
val
->
v
.
number
);
break
;
case
SVT_TAG
:
case
SVT_IDENT
:
case
SVT_STRING
:
sieve_debug_internal
(
printer
,
data
,
"%s"
,
val
->
v
.
string
);
break
;
case
SVT_STRING_LIST
:
list_do
(
val
->
v
.
list
,
(
list_action_t
*
)
string_printer
,
&
dbg
);
break
;
case
SVT_VALUE_LIST
:
list_do
(
val
->
v
.
list
,
(
list_action_t
*
)
value_printer
,
&
dbg
);
}
sieve_debug_internal
(
printer
,
data
,
")"
);
}
void
sieve_print_value_list
(
list_t
list
,
sieve_printf_t
printer
,
void
*
data
)
{
sieve_value_t
val
;
val
.
type
=
SVT_VALUE_LIST
;
val
.
v
.
list
=
list
;
sieve_print_value
(
&
val
,
printer
,
data
);
}
static
int
tag_printer
(
sieve_runtime_tag_t
*
val
,
struct
debug_data
*
dbg
)
{
sieve_debug_internal
(
dbg
->
printer
,
dbg
->
data
,
"%d"
,
val
->
tag
);
if
(
val
->
arg
)
{
sieve_debug_internal
(
dbg
->
printer
,
dbg
->
data
,
"("
);
sieve_print_value
(
val
->
arg
,
dbg
->
printer
,
dbg
->
data
);
sieve_debug_internal
(
dbg
->
printer
,
dbg
->
data
,
")"
);
}
sieve_debug_internal
(
dbg
->
printer
,
dbg
->
data
,
" "
);
}
void
sieve_print_tag_list
(
list_t
list
,
sieve_printf_t
printer
,
void
*
data
)
{
struct
debug_data
dbg
;
dbg
.
printer
=
printer
;
dbg
.
data
=
data
;
list_do
(
list
,
(
list_action_t
*
)
tag_printer
,
&
dbg
);
}
void
sieve_set_debug
(
sieve_machine_t
*
mach
,
sieve_printf_t
debug
,
int
level
)
{
mach
->
debug_printer
=
debug
;
mach
->
debug_level
=
level
;
}
...
...
Please
register
or
sign in
to post a comment