1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
/* Copyright (c) 2002-2016 Pigeonhole authors, see the included COPYING file
*/
#include "lib.h"
#include "str.h"
#include "ostream.h"
#include "sieve-common.h"
#include "sieve-script.h"
#include "sieve-binary.h"
#include "sieve-code.h"
#include "sieve-interpreter.h"
#include "sieve-runtime.h"
#include "sieve-runtime-trace.h"
static inline string_t *_trace_line_new
(const struct sieve_runtime_env *renv, sieve_size_t address, unsigned int cmd_line)
{
string_t *trline;
unsigned int i;
trline = t_str_new(128);
if ( (renv->trace->config.flags & SIEVE_TRFLG_ADDRESSES) > 0 )
str_printfa(trline, "%08llx: ", (unsigned long long) address);
if ( cmd_line > 0 )
str_printfa(trline, "%4d: ", cmd_line);
else
str_append(trline, " ");
for ( i = 0; i < renv->trace->indent; i++ )
str_append(trline, " ");
return trline;
}
static inline void _trace_line_print
(string_t *trline, const struct sieve_runtime_env *renv)
{
sieve_trace_log_write_line(renv->trace->log, trline);
}
static inline void _trace_line_print_empty
(const struct sieve_runtime_env *renv)
{
sieve_trace_log_write_line(renv->trace->log, NULL);
}
/*
* Trace errors
*/
void _sieve_runtime_trace_error
(const struct sieve_runtime_env *renv, const char *fmt, va_list args)
{
string_t *trline = _trace_line_new(renv, renv->pc, 0);
str_printfa(trline, "%s: #ERROR#: ", sieve_operation_mnemonic(renv->oprtn));
str_vprintfa(trline, fmt, args);
_trace_line_print(trline, renv);
}
void _sieve_runtime_trace_operand_error
(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd,
const char *fmt, va_list args)
{
string_t *trline = _trace_line_new(renv, oprnd->address,
sieve_runtime_get_source_location(renv, oprnd->address));
str_printfa(trline, "%s: #ERROR#: ", sieve_operation_mnemonic(renv->oprtn));
if ( oprnd->field_name != NULL )
str_printfa(trline, "%s: ", oprnd->field_name);
str_vprintfa(trline, fmt, args);
_trace_line_print(trline, renv);
}
/*
* Trace info
*/
static inline void ATTR_FORMAT(4, 0) _sieve_runtime_trace_vprintf
(const struct sieve_runtime_env *renv, sieve_size_t address,
unsigned int cmd_line, const char *fmt, va_list args)
{
string_t *trline = _trace_line_new(renv, address, cmd_line);
str_vprintfa(trline, fmt, args);
_trace_line_print(trline, renv);
}
static inline void ATTR_FORMAT(4, 5) _sieve_runtime_trace_printf
(const struct sieve_runtime_env *renv, sieve_size_t address,
unsigned int cmd_line, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
_sieve_runtime_trace_vprintf(renv, address, cmd_line, fmt, args);
va_end(args);
}
void ATTR_FORMAT(2, 0) _sieve_runtime_trace
(const struct sieve_runtime_env *renv, const char *fmt, va_list args)
{
_sieve_runtime_trace_vprintf
(renv, renv->oprtn->address, sieve_runtime_get_command_location(renv),
fmt, args);
}
void _sieve_runtime_trace_address
(const struct sieve_runtime_env *renv, sieve_size_t address,
const char *fmt, va_list args)
{
_sieve_runtime_trace_vprintf
(renv, address, sieve_runtime_get_source_location(renv, address), fmt,
args);
}
/*
* Trace boundaries
*/
void _sieve_runtime_trace_begin(const struct sieve_runtime_env *renv)
{
const char *script_name = ( renv->script != NULL ?
sieve_script_name(renv->script) : sieve_binary_path(renv->sbin) );
_trace_line_print_empty(renv);
_sieve_runtime_trace_printf(renv, renv->pc, 0,
"## Started executing script '%s'", script_name);
}
void _sieve_runtime_trace_end(const struct sieve_runtime_env *renv)
{
const char *script_name = ( renv->script != NULL ?
sieve_script_name(renv->script) : sieve_binary_path(renv->sbin) );
_sieve_runtime_trace_printf(renv, renv->pc, 0,
"## Finished executing script '%s'", script_name);
_trace_line_print_empty(renv);
}
void _sieve_runtime_trace_sep(const struct sieve_runtime_env *renv)
{
_trace_line_print_empty(renv);
}
|