Adaptive Framework  0.9.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
afw_value_template_definition.c
Go to the documentation of this file.
1 // See the 'COPYING' file in the project root for licensing information.
2 /*
3  * Interface afw_value Implementation for Template Definition
4  *
5  * Copyright (c) 2010-2023 Clemson University
6  *
7  */
8 
9 
15 #include "afw_internal.h"
16 
17 
18 #define impl_afw_value_optional_release NULL
19 #define impl_afw_value_get_reference NULL
20 
21 
22 /* Inf specific is always data type. */
23 #define AFW_IMPLEMENTATION_SPECIFIC (const void *)&afw_data_type_template_direct
24 
25 /* Define inf variables for data_type and fully_evaluated_data_type. */
26 #define AFW_IMPLEMENTATION_INF_VARIABLES \
27  (const void *)&afw_data_type_template_direct, \
28  NULL
29 
30 #define impl_afw_value_get_evaluated_meta \
31  afw_value_internal_get_evaluated_meta_default
32 
33 #define impl_afw_value_get_evaluated_metas \
34  afw_value_internal_get_evaluated_metas_default
35 
36 /* Declares and rti/inf defines for interface afw_value */
37 #define AFW_IMPLEMENTATION_ID "template_definition"
38 #define AFW_IMPLEMENTATION_INF_SPECIFIER AFW_DEFINE_CONST_DATA
39 #define AFW_IMPLEMENTATION_INF_LABEL afw_value_template_definition_inf
41 
42 
43 /* Create function for template definition value. */
44 AFW_DEFINE(const afw_value_t *)
46  const afw_compile_value_contextual_t *contextual,
47  afw_size_t count,
48  const afw_value_t * const * values,
49  const afw_pool_t *p,
50  afw_xctx_t *xctx)
51 {
53 
54  if (count <= 0) return afw_value_null;
55 
56  result = afw_pool_calloc(p, sizeof(afw_value_template_definition_t), xctx);
57  result->inf = &afw_value_template_definition_inf;
58  result->contextual = contextual;
59  result->count = count;
60  result->values = afw_memory_dup(values,
61  count * sizeof(afw_value_t *),
62  p, xctx);
63 
64  return (afw_value_t *)result;
65 }
66 
67 
68 /*
69  * Implementation of method optional_evaluate for interface afw_value.
70  */
71 const afw_value_t *
73  const afw_value_t * instance,
74  const afw_pool_t * p,
75  afw_xctx_t *xctx)
76 {
78  (const afw_value_template_definition_t *)instance;
79 
80  afw_size_t i;
81  const afw_value_t * const * v;
82  const afw_utf8_t **strings;
83  const afw_utf8_t **s;
84  const afw_value_t *a_value;
85  afw_size_t len;
86  afw_utf8_octet_t *concat;
88  const afw_value_t *result;
89  const afw_compile_value_contextual_t *saved_contextual;
90 
91  /* Push value on evaluation stack. */
93  saved_contextual = xctx->error->contextual;
94  xctx->error->contextual = self->contextual;
95 
96  /* If just one value, evaluate it. */
97  if (self->count == 1) {
98  result = afw_value_evaluate(*(self->values), p, xctx);
99  }
100 
101  /* If no values, return empty string value. */
102  else if (self->count == 0) {
103  result = afw_value_empty_string;
104  }
105 
106  /* If more than one value, produce concatenated string. */
107  else {
108  strings = afw_pool_calloc(p, sizeof(afw_utf8_t *) * self->count,
109  xctx);
110  for (i = 0, v = self->values, len = 0, s = strings;
111  i < self->count;
112  i++, v++, s++)
113  {
114  a_value = afw_value_evaluate(*v, p, xctx);
115  *s = afw_value_as_utf8(a_value, p, xctx);
116  if (*s) {
117  len += (*s)->len;
118  }
119  }
120 
121  concat = NULL;
122  if (len > 0) {
123  concat = afw_pool_calloc(p, len, xctx);
124  for (i = 0, c = concat, s = strings; i < self->count; i++, s++) {
125  if (*s && (*s)->len > 0) {
126  memcpy(c, (*s)->s, (*s)->len);
127  c += (*s)->len;
128  }
129  }
130  }
131 
132  result = afw_value_make_single_string(concat, len, p, xctx);
133  }
134 
135  /* Pop value from evaluation stack and return result. */
137  xctx->error->contextual = saved_contextual;
138  return result;
139 }
140 
141 /*
142  * Implementation of method get_data_type for interface afw_value.
143  */
144 const afw_data_type_t *
145 impl_afw_value_get_data_type(
146  const afw_value_t * instance,
147  afw_xctx_t *xctx)
148 {
149  return afw_data_type_template;
150 }
151 
152 /*
153  * Implementation of method get_evaluated_data_type for interface afw_value.
154  */
155 const afw_data_type_t *
156 impl_afw_value_get_evaluated_data_type(
157  const afw_value_t * instance,
158  afw_xctx_t *xctx)
159 {
160  return NULL;
161 }
162 
163 
164 /*
165  * Implementation of method get_evaluated_data_type_parameter for interface
166  * afw_value.
167  */
168 const afw_utf8_t *
169 impl_afw_value_get_evaluated_data_type_parameter(
170  const afw_value_t * instance,
171  afw_xctx_t *xctx)
172 {
173  return NULL;
174 }
175 
176 
177 /*
178  * Implementation of method compiler_listing for interface afw_value.
179  */
180 void
181 impl_afw_value_produce_compiler_listing(
182  const afw_value_t *instance,
183  const afw_writer_t *writer,
184  afw_xctx_t *xctx)
185 {
186  const afw_value_template_definition_t *self =
187  (const afw_value_template_definition_t *)instance;
188  afw_size_t i;
189 
190  afw_value_compiler_listing_begin_value(writer, instance,
191  self->contextual, xctx);
192  afw_writer_write_z(writer, ": [", xctx);
193  afw_writer_write_eol(writer, xctx);
194  afw_writer_increment_indent(writer, xctx);
195 
196  AFW_VALUE_COMPILER_LISTING_IF_NOT_LIMIT_EXCEEDED
197  for (i = 0; i < self->count; i++) {
198  afw_value_compiler_listing_value(self->values[i], writer, xctx);
199  }
200 
201  afw_writer_decrement_indent(writer, xctx);
202  afw_writer_write_z(writer, "]", xctx);
203  afw_writer_write_eol(writer, xctx);
204 }
205 
206 /*
207  * Implementation of method decompile for interface afw_value.
208  */
209 void
210 impl_afw_value_decompile(
211  const afw_value_t * instance,
212  const afw_writer_t * writer,
213  afw_xctx_t *xctx)
214 {
215  const afw_value_template_definition_t *self =
216  (const afw_value_template_definition_t *)instance;
217  afw_value_string_t string_value;
218 
219  if (self->count == 0) {
220  afw_writer_write_z(writer, "null", xctx);
221  return;
222  }
223 
224  if (self->count == 1) {
225  afw_value_decompile(self->values[0], writer, xctx);
226  return;
227  }
228 
229  afw_writer_write_z(writer, "evaluate_template(", xctx);
230 
231  /*impl_decompile_template(self, writer, xctx);*/
232  string_value.inf = &afw_value_evaluated_string_inf;
233  string_value.internal.s = self->contextual->compiled_value->full_source->s +
234  self->contextual->value_offset;
235  string_value.internal.len = self->contextual->value_size;
236  afw_value_decompile((const afw_value_t *)&string_value, writer, xctx);
237 
238  afw_writer_write_z(writer, ")", xctx);
239 }
240 
241 
242 /*
243  * Implementation of method get_info for interface afw_value.
244  */
245 void
246 impl_afw_value_get_info(
247  const afw_value_t *instance,
248  afw_value_info_t *info,
249  const afw_pool_t *p,
250  afw_xctx_t *xctx)
251 {
252  const afw_value_template_definition_t *self =
253  (const afw_value_template_definition_t *)instance;
254 
255  afw_memory_clear(info);
256  info->value_inf_id = &instance->inf->rti.implementation_id;
257  info->contextual = self->contextual;
258 }
AFW_DEFINE(const afw_object_t *)
Adaptive Framework Core Internal.
Interface afw_interface implementation declares.
afw_value_evaluated_string_inf
Unmanaged evaluated value inf for data type string.
afw_data_type_template
Data type struct for template.
char afw_utf8_octet_t
8 bits of utf-8 codepoint.
Definition: afw_common.h:236
apr_size_t afw_size_t
size_t.
Definition: afw_common.h:151
#define afw_memory_clear(to)
Clear preallocated memory for sizeof(*(to)).
Definition: afw_memory.h:47
void * afw_memory_dup(const void *from, apr_size_t size, const afw_pool_t *p, afw_xctx_t *xctx)
Duplicate a block of memory into specified pool.
Definition: afw_memory.h:88
#define afw_pool_calloc(instance, size, xctx)
Call method calloc of interface afw_pool.
const afw_value_t * impl_afw_value_optional_evaluate(const afw_value_t *instance, const afw_pool_t *p, afw_xctx_t *xctx)
#define afw_value_decompile(instance, writer, xctx)
Call method decompile of interface afw_value.
#define afw_value_evaluate(value, p, xctx)
Evaluate value if needed using specific pool.
Definition: afw_value.h:841
afw_value_template_definition_create(const afw_compile_value_contextual_t *contextual, afw_size_t count, const afw_value_t *const *values, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for template definition value.
afw_value_as_utf8(const afw_value_t *value, const afw_pool_t *p, afw_xctx_t *xctx)
Definition: afw_value.c:456
afw_value_empty_string
Adaptive value empty string.
Definition: afw_value.h:342
afw_value_null
Adaptive value null.
Definition: afw_value.h:320
afw_value_template_definition_inf
Value template inf.
Definition: afw_value.h:303
afw_value_make_single_string(const afw_utf8_octet_t *s, afw_size_t len, const afw_pool_t *p, afw_xctx_t *xctx)
Definition: afw_value.c:478
#define afw_writer_increment_indent(instance, xctx)
Call method increment_indent of interface afw_writer.
#define afw_writer_write_eol(instance, xctx)
Call method write_eol of interface afw_writer.
#define afw_writer_decrement_indent(instance, xctx)
Call method decrement_indent of interface afw_writer.
#define afw_writer_write_z(writer, s_z, xctx)
Call afw_writer_write() with zero terminated string.
Definition: afw_writer.h:35
#define afw_xctx_evaluation_stack_push_value(VALUE, xctx)
Push VALUE onto execution stack.
Definition: afw_xctx.h:78
#define afw_xctx_evaluation_stack_pop_value(xctx)
Pop top VALUE off execution stack.
Definition: afw_xctx.h:113
Contextual information provided in some values.
Interface afw_data_type public struct.
const afw_compile_value_contextual_t * contextual
Contextual information or NULL.
Definition: afw_error.h:83
Interface afw_pool public struct.
NFC normalized UTF-8 string.
Definition: afw_common.h:545
Filled in by afw_value get_info method.
Definition: afw_value.h:49
Interface afw_value public struct.
struct for data type string values.
Struct for template value.
Interface afw_writer public struct.
Interface afw_xctx public struct.