1 #include "array.h"
2 
3 #include <string.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 
data_config_copy(const data_unset * s)7 static data_unset *data_config_copy(const data_unset *s) {
8 	data_config *src = (data_config *)s;
9 	data_config *ds = data_config_init();
10 
11 	buffer_copy_string_buffer(ds->key, src->key);
12 	buffer_copy_string_buffer(ds->comp_key, src->comp_key);
13 	array_free(ds->value);
14 	ds->value = array_init_array(src->value);
15 	return (data_unset *)ds;
16 }
17 
data_config_free(data_unset * d)18 static void data_config_free(data_unset *d) {
19 	data_config *ds = (data_config *)d;
20 
21 	buffer_free(ds->key);
22 	buffer_free(ds->op);
23 	buffer_free(ds->comp_key);
24 
25 	array_free(ds->value);
26 	array_free(ds->childs);
27 
28 	if (ds->string) buffer_free(ds->string);
29 #ifdef HAVE_PCRE_H
30 	if (ds->regex) pcre_free(ds->regex);
31 	if (ds->regex_study) pcre_free(ds->regex_study);
32 #endif
33 
34 	free(d);
35 }
36 
data_config_reset(data_unset * d)37 static void data_config_reset(data_unset *d) {
38 	data_config *ds = (data_config *)d;
39 
40 	/* reused array elements */
41 	buffer_reset(ds->key);
42 	buffer_reset(ds->comp_key);
43 	array_reset(ds->value);
44 }
45 
data_config_insert_dup(data_unset * dst,data_unset * src)46 static int data_config_insert_dup(data_unset *dst, data_unset *src) {
47 	UNUSED(dst);
48 
49 	src->free(src);
50 
51 	return 0;
52 }
53 
data_config_print(const data_unset * d,int depth)54 static void data_config_print(const data_unset *d, int depth) {
55 	data_config *ds = (data_config *)d;
56 	array *a = (array *)ds->value;
57 	size_t i;
58 	size_t maxlen;
59 
60 	if (0 == ds->context_ndx) {
61 		fprintf(stdout, "config {\n");
62 	}
63 	else {
64 		fprintf(stdout, "$%s %s \"%s\" {\n",
65 				ds->comp_key->ptr, ds->op->ptr, ds->string->ptr);
66 		array_print_indent(depth + 1);
67 		fprintf(stdout, "# block %d\n", ds->context_ndx);
68 	}
69 	depth ++;
70 
71 	maxlen = array_get_max_key_length(a);
72 	for (i = 0; i < a->used; i ++) {
73 		data_unset *du = a->data[i];
74 		size_t len = strlen(du->key->ptr);
75 		size_t j;
76 
77 		array_print_indent(depth);
78 		fprintf(stdout, "%s", du->key->ptr);
79 		for (j = maxlen - len; j > 0; j --) {
80 			fprintf(stdout, " ");
81 		}
82 		fprintf(stdout, " = ");
83 		du->print(du, depth);
84 		fprintf(stdout, "\n");
85 	}
86 
87 	if (ds->childs) {
88 		fprintf(stdout, "\n");
89 		for (i = 0; i < ds->childs->used; i ++) {
90 			data_unset *du = ds->childs->data[i];
91 
92 			/* only the 1st block of chaining */
93 			if (NULL == ((data_config *)du)->prev) {
94 				fprintf(stdout, "\n");
95 				array_print_indent(depth);
96 				du->print(du, depth);
97 				fprintf(stdout, "\n");
98 			}
99 		}
100 	}
101 
102 	depth --;
103 	array_print_indent(depth);
104 	fprintf(stdout, "}");
105 	if (0 != ds->context_ndx) {
106 		fprintf(stdout, " # end of $%s %s \"%s\"",
107 				ds->comp_key->ptr, ds->op->ptr, ds->string->ptr);
108 	}
109 
110 	if (ds->next) {
111 		fprintf(stdout, "\n");
112 		array_print_indent(depth);
113 		fprintf(stdout, "else ");
114 		ds->next->print((data_unset *)ds->next, depth);
115 	}
116 }
117 
data_config_init(void)118 data_config *data_config_init(void) {
119 	data_config *ds;
120 
121 	ds = calloc(1, sizeof(*ds));
122 
123 	ds->key = buffer_init();
124 	ds->op = buffer_init();
125 	ds->comp_key = buffer_init();
126 	ds->value = array_init();
127 	ds->childs = array_init();
128 	ds->childs->is_weakref = 1;
129 
130 	ds->copy = data_config_copy;
131 	ds->free = data_config_free;
132 	ds->reset = data_config_reset;
133 	ds->insert_dup = data_config_insert_dup;
134 	ds->print = data_config_print;
135 	ds->type = TYPE_CONFIG;
136 
137 	return ds;
138 }
139