48
48
struct sieve_variable *error_var;
50
struct hash_table *variables;
51
ARRAY_DEFINE(variable_index, struct sieve_variable *);
50
HASH_TABLE(const char *, struct sieve_variable *) variables;
51
ARRAY(struct sieve_variable *) variable_index;
54
54
struct sieve_variable_scope_binary {
67
67
struct sieve_variable_scope *sieve_variable_scope_create
68
(struct sieve_instance *svinst, const struct sieve_extension *ext)
68
(struct sieve_instance *svinst, const struct sieve_extension *ext)
70
70
struct sieve_variable_scope *scope;
78
78
scope->svinst = svinst;
81
scope->variables = hash_table_create
82
(default_pool, pool, 0, strcase_hash, (hash_cmp_callback_t *)strcasecmp);
81
hash_table_create(&scope->variables, pool, 0, strcase_hash, strcasecmp);
83
82
p_array_init(&scope->variable_index, pool, 128);
122
121
if ( scope->error_var == NULL ) {
123
122
new_var->identifier = "@ERROR@";
124
123
new_var->index = 0;
126
125
scope->error_var = new_var;
130
129
return scope->error_var;
133
132
new_var->identifier = p_strdup(scope->pool, identifier);
134
133
new_var->index = array_count(&scope->variable_index);
137
(scope->variables, (void *) new_var->identifier, (void *) new_var);
135
hash_table_insert(scope->variables, new_var->identifier, new_var);
138
136
array_append(&scope->variable_index, &new_var, 1);
146
144
struct sieve_variable *var;
148
var = (struct sieve_variable *)
149
hash_table_lookup(scope->variables, identifier);
146
var = hash_table_lookup(scope->variables, identifier);
151
148
if ( var == NULL && declare ) {
152
149
var = sieve_variable_scope_declare(scope, identifier);
158
155
struct sieve_variable *sieve_variable_scope_import
159
156
(struct sieve_variable_scope *scope, struct sieve_variable *var)
161
struct sieve_variable *new_var;
158
struct sieve_variable *new_var;
163
160
new_var = p_new(scope->pool, struct sieve_variable, 1);
164
161
memcpy(new_var, var, sizeof(struct sieve_variable));
167
(scope->variables, (void *) new_var->identifier, (void *) new_var);
169
/* Not entered into the index because it is an external variable
163
hash_table_insert(scope->variables, new_var->identifier, new_var);
165
/* Not entered into the index because it is an external variable
170
166
* (This can be done unlimited; only limited by the size of the external scope)
188
184
bool sieve_variable_scope_iterate
189
185
(struct sieve_variable_scope_iter *iter, struct sieve_variable **var_r)
193
if ( !hash_table_iterate(iter->hctx, &key, &value) )
196
*var_r = (struct sieve_variable *) value;
189
return hash_table_iterate
190
(iter->hctx, iter->scope->variables, &key, var_r);
200
193
void sieve_variable_scope_iterate_deinit
226
219
(struct sieve_variable_scope *scope, unsigned int index)
228
221
struct sieve_variable * const *var;
230
if ( index >= array_count(&scope->variable_index) )
223
if ( index >= array_count(&scope->variable_index) )
233
var = array_idx(&scope->variable_index, index);
226
var = array_idx(&scope->variable_index, index);
238
231
/* Scope binary */
240
233
struct sieve_variable_scope *sieve_variable_scope_binary_dump
241
(struct sieve_instance *svinst, const struct sieve_extension *ext,
234
(struct sieve_instance *svinst, const struct sieve_extension *ext,
242
235
const struct sieve_dumptime_env *denv, sieve_size_t *address)
244
237
struct sieve_variable_scope *local_scope;
247
240
sieve_offset_t end_offset;
249
/* Read scope size */
242
/* Read scope size */
250
243
sieve_code_mark(denv);
251
244
if ( !sieve_binary_read_unsigned(denv->sblock, address, &scope_size) )
254
247
/* Read offset */
256
249
if ( !sieve_binary_read_offset(denv->sblock, address, &end_offset) )
259
252
/* Create scope */
260
253
local_scope = sieve_variable_scope_create(svinst, ext);
262
255
/* Read and dump scope itself */
264
sieve_code_dumpf(denv, "VARIABLES SCOPE [%u] (end: %08x)",
257
sieve_code_dumpf(denv, "VARIABLES SCOPE [%u] (end: %08x)",
265
258
scope_size, (unsigned int) (pc + end_offset));
267
260
for ( i = 0; i < scope_size; i++ ) {
268
261
string_t *identifier;
271
264
if (!sieve_binary_read_string(denv->sblock, address, &identifier) ) {
275
268
sieve_code_dumpf(denv, "%3d: '%s'", i, str_c(identifier));
277
270
(void) sieve_variable_scope_declare(local_scope, str_c(identifier));
280
273
return local_scope;
311
304
struct sieve_variable_scope *scope;
312
305
struct sieve_variable_scope_binary *scpbin;
313
306
unsigned int scope_size;
314
const char *ext_name =
307
const char *ext_name =
315
308
( ext == NULL ? "variables" : sieve_extension_name(ext) );
317
310
sieve_offset_t end_offset;
319
/* Read scope size */
312
/* Read scope size */
320
313
if ( !sieve_binary_read_unsigned(sblock, address, &scope_size) ) {
322
315
(svinst, "%s: variable scope: failed to read size", ext_name);
326
319
/* Check size limit */
327
320
if ( scope_size > EXT_VARIABLES_MAX_SCOPE_SIZE ) {
328
321
sieve_sys_error(svinst,
329
"%s: variable scope: size exceeds the limit (%u > %u)",
322
"%s: variable scope: size exceeds the limit (%u > %u)",
330
323
ext_name, scope_size, EXT_VARIABLES_MAX_SCOPE_SIZE );
334
327
/* Read offset */
336
329
if ( !sieve_binary_read_offset(sblock, address, &end_offset) ) {
337
330
sieve_sys_error(svinst,
338
331
"%s: variable scope: failed to read end offset", ext_name);
342
335
/* Create scope */
343
336
scope = sieve_variable_scope_create(svinst, ext);
358
351
const struct sieve_extension *ext = scpbin->scope->ext;
359
352
struct sieve_instance *svinst = scpbin->scope->svinst;
360
const char *ext_name =
353
const char *ext_name =
361
354
( ext == NULL ? "variables" : sieve_extension_name(ext) );
364
357
if ( scpbin->sblock != NULL ) {
365
358
sieve_size_t *address = &scpbin->address;
367
/* Read scope itself */
360
/* Read scope itself */
368
361
for ( i = 0; i < scpbin->size; i++ ) {
369
362
struct sieve_variable *var;
370
363
string_t *identifier;
384
377
scpbin->sblock = NULL;
387
380
return scpbin->scope;
390
383
unsigned int sieve_variable_scope_binary_get_size
391
384
(struct sieve_variable_scope_binary *scpbin)
393
if ( scpbin->sblock != NULL )
386
if ( scpbin->sblock != NULL )
394
387
return scpbin->size;
396
389
return array_count(&scpbin->scope->variable_index);
403
396
struct sieve_variable_storage {
405
398
struct sieve_variable_scope *scope;
406
399
struct sieve_variable_scope_binary *scope_bin;
407
400
unsigned int max_size;
408
ARRAY_DEFINE(var_values, string_t *);
401
ARRAY(string_t *) var_values;
411
404
struct sieve_variable_storage *sieve_variable_storage_create
412
405
(pool_t pool, struct sieve_variable_scope_binary *scpbin)
414
407
struct sieve_variable_storage *storage;
416
409
storage = p_new(pool, struct sieve_variable_storage, 1);
417
410
storage->pool = pool;
418
411
storage->scope_bin = scpbin;
419
412
storage->scope = NULL;
421
414
storage->max_size = sieve_variable_scope_binary_get_size(scpbin);
423
416
p_array_init(&storage->var_values, pool, 4);
437
430
bool sieve_variable_get_identifier
438
(struct sieve_variable_storage *storage, unsigned int index,
431
(struct sieve_variable_storage *storage, unsigned int index,
439
432
const char **identifier)
441
434
struct sieve_variable * const *var;
480
473
(struct sieve_variable_storage *storage, unsigned int index, string_t **value)
484
477
if ( index < array_count(&storage->var_values) ) {
485
478
string_t * const *varent;
487
480
varent = array_idx(&storage->var_values, index);
489
482
*value = *varent;
490
483
} else if ( !sieve_variable_valid(storage, index) )
496
489
bool sieve_variable_get_modifiable
497
490
(struct sieve_variable_storage *storage, unsigned int index, string_t **value)
501
494
if ( value == NULL ) value = &dummy;
503
496
if ( !sieve_variable_get(storage, index, value) )
506
499
if ( *value == NULL ) {
507
500
*value = str_new(storage->pool, 256);
508
array_idx_set(&storage->var_values, index, value);
501
array_idx_set(&storage->var_values, index, value);
514
507
bool sieve_variable_assign
515
(struct sieve_variable_storage *storage, unsigned int index,
508
(struct sieve_variable_storage *storage, unsigned int index,
516
509
const string_t *value)
518
511
string_t *varval;
520
if ( !sieve_variable_get_modifiable(storage, index, &varval) )
513
if ( !sieve_variable_get_modifiable(storage, index, &varval) )
523
516
str_truncate(varval, 0);
537
530
static void ext_variables_ast_free
538
(const struct sieve_extension *ext ATTR_UNUSED,
531
(const struct sieve_extension *ext ATTR_UNUSED,
539
532
struct sieve_ast *ast ATTR_UNUSED, void *context)
541
534
struct sieve_variable_scope *local_scope =
569
562
struct sieve_variable_scope *local_scope = (struct sieve_variable_scope *)
570
563
sieve_ast_extension_get_context(ast, this_ext);
572
565
return local_scope;
579
572
static struct ext_variables_validator_context *
580
573
ext_variables_validator_context_create
581
574
(const struct sieve_extension *this_ext, struct sieve_validator *valdtr)
583
576
pool_t pool = sieve_validator_pool(valdtr);
584
577
struct ext_variables_validator_context *ctx;
585
578
struct sieve_ast *ast = sieve_validator_ast(valdtr);
587
580
ctx = p_new(pool, struct ext_variables_validator_context, 1);
588
581
ctx->modifiers = sieve_validator_object_registry_create(valdtr);
589
582
ctx->namespaces = sieve_validator_object_registry_create(valdtr);
596
589
struct ext_variables_validator_context *ext_variables_validator_context_get
597
590
(const struct sieve_extension *this_ext, struct sieve_validator *valdtr)
599
struct ext_variables_validator_context *ctx =
592
struct ext_variables_validator_context *ctx =
600
593
(struct ext_variables_validator_context *)
601
594
sieve_validator_extension_get_context(valdtr, this_ext);
603
596
if ( ctx == NULL ) {
604
597
ctx = ext_variables_validator_context_create(this_ext, valdtr);
611
604
(const struct sieve_extension *this_ext, struct sieve_validator *valdtr)
613
606
struct ext_variables_validator_context *ctx;
615
608
/* Create our context */
616
609
ctx = ext_variables_validator_context_get(this_ext, valdtr);
618
611
ext_variables_register_core_modifiers(this_ext, ctx);
620
613
ctx->active = TRUE;
623
616
struct sieve_variable *ext_variables_validator_get_variable
624
(const struct sieve_extension *this_ext, struct sieve_validator *validator,
617
(const struct sieve_extension *this_ext, struct sieve_validator *validator,
625
618
const char *variable, bool declare)
627
struct ext_variables_validator_context *ctx =
620
struct ext_variables_validator_context *ctx =
628
621
ext_variables_validator_context_get(this_ext, validator);
630
623
return sieve_variable_scope_get_variable(ctx->local_scope, variable, declare);
633
626
struct sieve_variable_scope *sieve_ext_variables_get_local_scope
634
627
(const struct sieve_extension *var_ext, struct sieve_validator *validator)
636
struct ext_variables_validator_context *ctx =
629
struct ext_variables_validator_context *ctx =
637
630
ext_variables_validator_context_get(var_ext, validator);
639
632
return ctx->local_scope;
642
635
bool sieve_ext_variables_is_active
643
636
(const struct sieve_extension *var_ext, struct sieve_validator *valdtr)
645
struct ext_variables_validator_context *ctx =
638
struct ext_variables_validator_context *ctx =
646
639
ext_variables_validator_context_get(var_ext, valdtr);
648
641
return ( ctx != NULL && ctx->active );
652
645
* Code generation
655
648
bool ext_variables_generator_load
656
649
(const struct sieve_extension *ext, const struct sieve_codegen_env *cgenv)
658
struct sieve_variable_scope *local_scope =
651
struct sieve_variable_scope *local_scope =
659
652
ext_variables_ast_get_local_scope(ext, cgenv->ast);
660
653
unsigned int count = sieve_variable_scope_size(local_scope);
661
654
sieve_size_t jump;
667
660
if ( count > 0 ) {
668
661
unsigned int size, i;
669
struct sieve_variable *const *vars =
662
struct sieve_variable *const *vars =
670
663
sieve_variable_scope_get_variables(local_scope, &size);
672
for ( i = 0; i < size; i++ ) {
665
for ( i = 0; i < size; i++ ) {
673
666
sieve_binary_emit_cstring(cgenv->sblock, vars[i]->identifier);
677
670
sieve_binary_resolve_offset(cgenv->sblock, jump);
683
* Interpreter context
676
* Interpreter context
686
679
struct ext_variables_interpreter_context {
690
683
struct sieve_variable_scope_binary *local_scope_bin;
692
685
struct sieve_variable_storage *local_storage;
693
ARRAY_DEFINE(ext_storages, struct sieve_variable_storage *);
686
ARRAY(struct sieve_variable_storage *) ext_storages;
696
689
static void ext_variables_interpreter_free
697
690
(const struct sieve_extension *ext ATTR_UNUSED,
698
691
struct sieve_interpreter *interp ATTR_UNUSED, void *context)
700
struct ext_variables_interpreter_context *ctx =
693
struct ext_variables_interpreter_context *ctx =
701
694
(struct ext_variables_interpreter_context *)context;
703
696
sieve_variable_scope_binary_unref(&ctx->local_scope_bin);
712
705
static struct ext_variables_interpreter_context *
713
706
ext_variables_interpreter_context_create
714
(const struct sieve_extension *this_ext, struct sieve_interpreter *interp,
707
(const struct sieve_extension *this_ext, struct sieve_interpreter *interp,
715
708
struct sieve_variable_scope_binary *scpbin)
717
710
pool_t pool = sieve_interpreter_pool(interp);
718
711
struct ext_variables_interpreter_context *ctx;
720
713
ctx = p_new(pool, struct ext_variables_interpreter_context, 1);
721
714
ctx->pool = pool;
722
715
ctx->local_scope = NULL;
723
716
ctx->local_scope_bin = scpbin;
724
717
ctx->local_storage = sieve_variable_storage_create(pool, scpbin);
725
p_array_init(&ctx->ext_storages, pool,
718
p_array_init(&ctx->ext_storages, pool,
726
719
sieve_extensions_get_count(this_ext->svinst));
728
721
sieve_interpreter_extension_register
734
727
bool ext_variables_interpreter_load
735
(const struct sieve_extension *ext, const struct sieve_runtime_env *renv,
728
(const struct sieve_extension *ext, const struct sieve_runtime_env *renv,
736
729
sieve_size_t *address)
738
731
struct sieve_variable_scope_binary *scpbin;
763
756
struct sieve_variable_storage *sieve_ext_variables_runtime_get_storage
764
(const struct sieve_extension *var_ext, const struct sieve_runtime_env *renv,
757
(const struct sieve_extension *var_ext, const struct sieve_runtime_env *renv,
765
758
const struct sieve_extension *ext)
767
struct ext_variables_interpreter_context *ctx =
760
struct ext_variables_interpreter_context *ctx =
768
761
ext_variables_interpreter_context_get(var_ext, renv->interp);
769
762
struct sieve_variable_storage * const *storage;
771
764
if ( ext == NULL )
772
765
return ctx->local_storage;
786
779
(const struct sieve_extension *var_ext, const struct sieve_runtime_env *renv,
787
780
const struct sieve_extension *ext, struct sieve_variable_storage *storage)
789
struct ext_variables_interpreter_context *ctx =
782
struct ext_variables_interpreter_context *ctx =
790
783
ext_variables_interpreter_context_get(var_ext, renv->interp);
792
785
if ( ctx == NULL || ext == NULL || storage == NULL )
795
788
if ( ext->id < 0 ) return;
797
790
array_idx_set(&ctx->ext_storages, (unsigned int) ext->id, &storage);