Adaptive Framework  0.9.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
afw_flag.c
Go to the documentation of this file.
1 // See the 'COPYING' file in the project root for licensing information.
2 /*
3  * Adaptive Framework Trace
4  *
5  * Copyright (c) 2010-2023 Clemson University
6  *
7  */
8 
9 
15 #include "afw_internal.h"
16 
20 typedef struct {
21  const afw_flag_t *flag;
22 
23 
25 
26 
27 
28 static void
29 impl_insure_flags_mutable(afw_xctx_t *xctx)
30 {
31  afw_boolean_t *flags;
32  afw_size_t count;
33 
34  if (!xctx->flags_is_mutable_copy ||
35  xctx->env->flags_count_allocated != xctx->flags_count)
36  {
37  count = xctx->env->flags_count_allocated;
38  flags = afw_xctx_malloc(count * sizeof(afw_boolean_t), xctx);
39  memcpy(flags, (void *)xctx->env->default_flags, count * sizeof(afw_boolean_t));
40  xctx->flags = flags;
41  xctx->flags_count = count;
42  xctx->flags_is_mutable_copy = true;
43  }
44 }
45 
46 
47 
48 static void
49 impl_set_applicable_flags(
50  const afw_utf8_t *flag_id,
51  afw_boolean_t set_to,
52  afw_boolean_t required,
53  afw_boolean_t *flags,
54  afw_size_t flags_count,
55  afw_xctx_t *xctx)
56 {
57  const afw_flag_t *flag;
58  afw_size_t i;
59 
60  flag = afw_environment_get_flag(flag_id, xctx);
61  if (!flag) {
62  if (!required) {
63  return;
64  }
65  AFW_THROW_ERROR_FZ(general, xctx,
66  "Flag %" AFW_UTF8_FMT " is not registered",
67  AFW_UTF8_FMT_ARG(flag_id));
68  }
69 
70  for (i = 0;
71  i < flag->applicable_flags_count_allocated && i < flags_count;
72  i++)
73  {
74  if (flag->applicable_flags[i]) {
75  flags[i] = set_to;
76  }
77  }
78 }
79 
80 
81 
82 static void
83 impl_flag_add_included_by(
84  afw_flag_t *flag,
85  afw_flag_t *included_by,
86  afw_xctx_t *xctx)
87 {
88  const afw_pool_t *p = xctx->env->p;
89  const afw_iterator_t *iterator;
90  const afw_utf8_t *flag_id;
91  const afw_data_type_t *data_type;
92  afw_boolean_t *new_applicable;
93  afw_flag_t *parent;
94  afw_size_t i;
95  afw_boolean_t already_included;
96 
97 
98  /* Determined if flag id has already been added once. */
99  already_included = false;
100  if (included_by->includes_value) for (iterator = NULL;;) {
101  afw_list_get_next_internal(included_by->includes_value->internal,
102  &iterator, &data_type, (const void **)&flag_id, xctx);
103  if (!flag_id) break;
104  if (afw_utf8_equal(flag_id, flag->flag_id)) {
105  already_included = true;
106  break;
107  }
108  }
109 
110  /* If not an included_by->includes_value, make one. */
111  else {
112  included_by->includes_value = (const afw_value_list_t *)
115  afw_data_type_string, p, xctx),
116  p, xctx);
117  }
118 
119  /* If not already included, add includes and included by. */
120  if (!already_included) {
121 
122  /* Add included_by to this flags included_by. */
123  if (!flag->included_by_value) {
124  flag->included_by_value = (const afw_value_list_t *)
127  afw_data_type_string, p, xctx),
128  p, xctx);
129  }
130  afw_list_add_value(flag->included_by_value->internal,
131  included_by->flag_id_value, xctx);
132 
133  /* Add flag to includes of included_by. */
134  afw_list_add_value(included_by->includes_value->internal,
135  flag->flag_id_value, xctx);
136  }
137 
138 
139  /* Set all of flag's applicable flags in included_by's applicable flags. */
140  for (i = 0; i < flag->applicable_flags_count_allocated; i++) {
141  if (flag->applicable_flags[i]) {
142  if (i >= included_by->applicable_flags_count_allocated) {
143  /* Causes memory leak. */
144  new_applicable = afw_pool_calloc(p,
145  xctx->env->flags_count_allocated * sizeof(afw_boolean_t),
146  xctx);
147  memcpy(new_applicable,
148  (const void *)included_by->applicable_flags,
149  (included_by->applicable_flags_count_allocated *
150  sizeof(afw_boolean_t)));
151  included_by->applicable_flags = new_applicable;
152  included_by->applicable_flags_count_allocated =
153  xctx->env->flags_count_allocated;
154  }
155  ((afw_boolean_t *)included_by->applicable_flags)[i] = true;
156  }
157  }
158 
159 
160  /* Add flag to this included_by and to all the flags it is included by. */
161  if (included_by->included_by_value) for (iterator = NULL;;) {
162  afw_list_get_next_internal(included_by->included_by_value->internal,
163  &iterator, &data_type, (const void **)&flag_id, xctx);
164  if (!flag_id) break;
165  parent = (afw_flag_t *)afw_environment_get_flag(flag_id, xctx);
166  if (!parent) {
167  AFW_THROW_ERROR_Z(general, "Unexpected situation", xctx);
168  }
169  impl_flag_add_included_by(included_by, parent, xctx);
170  }
171 }
172 
173 
174 
175 /* Refresh env->pub.default_flags based on env->default_flag_ids. */
176 static void
177 impl_refresh_default_flags(afw_xctx_t *xctx)
178 {
179  afw_environment_t *env = (afw_environment_t *)xctx->env;
180  afw_environment_internal_t *internal_env =
181  (afw_environment_internal_t *)xctx->env;
182  const afw_utf8_t * const * flag_id;
183  const afw_pool_t *temp_p = NULL;
184  afw_boolean_t *flags;
185  afw_size_t flags_count;
186 
187  if (!internal_env->default_flag_ids) return;
188 
189  AFW_LOCK_BEGIN(xctx->env->flags_lock) {
190  temp_p = afw_pool_create(xctx->p, xctx);
191  flags_count = env->flags_count_allocated;
192  flags = afw_pool_calloc(temp_p, sizeof(afw_boolean_t) * flags_count,
193  xctx);
194  for (flag_id = internal_env->default_flag_ids; *flag_id; flag_id++) {
195  impl_set_applicable_flags(*flag_id, true, false, flags, flags_count,
196  xctx);
197  }
198  memcpy((void *)env->default_flags, flags,
199  sizeof(afw_boolean_t) * flags_count);
200  }
201  AFW_LOCK_END;
202 
203  if (temp_p) {
204  afw_pool_destroy(temp_p, xctx);
205  }
206 }
207 
208 
209 
210 /* Register core flags. */
212 afw_flag_internal_early_register_core(afw_xctx_t *xctx)
213 {
214  afw_environment_t *env = (afw_environment_t *)xctx->env;
215 
216  /* Register flag unspecified */
218  &afw_s_a_flag_unspecified,
219  &afw_s_a_flag_unspecified_brief,
220  &afw_s_a_flag_unspecified_description,
221  NULL,
222  xctx);
223 
224  /* Register flag debug:detail */
226  &afw_s_a_flag_debug_detail,
227  &afw_s_a_flag_debug_detail_brief,
228  &afw_s_a_flag_debug_detail_description,
229  NULL,
230  xctx);
231 
232  /* Register flag debug */
234  &afw_s_a_flag_debug,
235  &afw_s_a_flag_debug_brief,
236  &afw_s_a_flag_debug_description,
237  &afw_s_a_flag_debug_detail,
238  xctx);
239 
240 #ifdef AFW_LOCK_DEBUG
241  /* Register flag debug:lock */
243  &afw_s_a_flag_debug_lock,
244  &afw_s_a_flag_debug_lock_brief,
245  &afw_s_a_flag_debug_lock_description,
246  &afw_s_a_flag_debug,
247  xctx);
248 #endif
249 
250 #ifdef AFW_POOL_DEBUG
251  /* Register flag debug:pool:detail */
253  &afw_s_a_flag_debug_pool_detail,
254  &afw_s_a_flag_debug_pool_detail_brief,
255  &afw_s_a_flag_debug_pool_detail_description,
256  &afw_s_a_flag_debug_detail,
257  xctx);
260  &afw_s_a_flag_debug_pool_detail,
261  xctx)->flag_index;
262 
263  /* Register flag debug:pool */
265  &afw_s_a_flag_debug_pool,
266  &afw_s_a_flag_debug_pool_brief,
267  &afw_s_a_flag_debug_pool_description,
268  &afw_s_a_flag_debug,
269  xctx);
271  &afw_s_a_flag_debug_pool,
272  &afw_s_a_flag_debug_detail,
273  xctx);
274  env->flag_index_debug_pool =
276  &afw_s_a_flag_debug_pool,
277  xctx)->flag_index;
278 #endif
279 
280  /* Register flag debug:print:detail */
282  &afw_s_a_flag_debug_function_active_detail,
283  &afw_s_a_flag_debug_function_active_detail_brief,
284  &afw_s_a_flag_debug_function_active_detail_description,
285  &afw_s_a_flag_debug_detail,
286  xctx);
289  &afw_s_a_flag_debug_function_active_detail,
290  xctx)->flag_index;
291 
292  /* Register flag debug:print */
294  &afw_s_a_flag_debug_function_active,
295  &afw_s_a_flag_debug_function_active_brief,
296  &afw_s_a_flag_debug_function_active_description,
297  &afw_s_a_flag_debug,
298  xctx);
300  &afw_s_a_flag_debug_function_active,
301  &afw_s_a_flag_debug_detail,
302  xctx);
304  &afw_s_a_flag_debug_function_active,
305  &afw_s_a_flag_debug_function_active_detail,
306  xctx);
309  &afw_s_a_flag_debug_function_active,
310  xctx)->flag_index;
311 
312  /* Register flag response:error */
314  &afw_s_a_flag_response_error,
315  &afw_s_a_flag_response_error_brief,
316  &afw_s_a_flag_response_error_description,
317  NULL,
318  xctx);
319 
320  /* Register flag response:error:backtrace */
322  &afw_s_a_flag_response_error_backtrace,
323  &afw_s_a_flag_response_error_backtrace_brief,
324  &afw_s_a_flag_response_error_backtrace_description,
325  &afw_s_a_flag_response_error,
326  xctx);
329  &afw_s_a_flag_response_error_backtrace,
330  xctx)->flag_index;
331 
332  /* Register flag response:error:backtraceEvaluation */
334  &afw_s_a_flag_response_error_backtraceEvaluation,
335  &afw_s_a_flag_response_error_backtraceEvaluation_brief,
336  &afw_s_a_flag_response_error_backtraceEvaluation_description,
337  &afw_s_a_flag_response_error,
338  xctx);
341  &afw_s_a_flag_response_error_backtraceEvaluation,
342  xctx)->flag_index;
343 
344  /* Register flag response:error:contextual */
346  &afw_s_a_flag_response_error_contextual,
347  &afw_s_a_flag_response_error_contextual_brief,
348  &afw_s_a_flag_response_error_contextual_description,
349  &afw_s_a_flag_response_error,
350  xctx);
353  &afw_s_a_flag_response_error_contextual,
354  xctx)->flag_index;
355 
356  /* Register flag response:error:hasAdditionalDetail */
358  &afw_s_a_flag_response_error_hasAdditionalDetail,
359  &afw_s_a_flag_response_error_hasAdditionalDetail_brief,
360  &afw_s_a_flag_response_error_hasAdditionalDetail_description,
361  &afw_s_a_flag_response_error,
362  xctx);
365  &afw_s_a_flag_response_error_hasAdditionalDetail,
366  xctx)->flag_index;
368  &afw_s_a_flag_response_error_hasAdditionalDetail,
369  &afw_s_a_flag_response_error_backtrace,
370  xctx);
372  &afw_s_a_flag_response_error_hasAdditionalDetail,
373  &afw_s_a_flag_response_error_backtraceEvaluation,
374  xctx);
376  &afw_s_a_flag_response_error_hasAdditionalDetail,
377  &afw_s_a_flag_response_error_contextual,
378  xctx);
379 
380  /* Register response:console, stderr, and stdout. */
382  &afw_s_a_flag_response_console,
383  &afw_s_a_flag_response_console_brief,
384  &afw_s_a_flag_response_console_description,
385  NULL,
386  xctx);
388  &afw_s_a_flag_response_console_stream,
389  &afw_s_a_flag_response_console_stream_brief,
390  &afw_s_a_flag_response_console_stream_description,
391  NULL,
392  xctx);
394  &afw_s_a_flag_response_console,
395  &afw_s_a_flag_response_console_stream,
396  xctx);
397 
399  &afw_s_a_flag_response_stderr,
400  &afw_s_a_flag_response_stderr_brief,
401  &afw_s_a_flag_response_stderr_description,
402  NULL,
403  xctx);
405  &afw_s_a_flag_response_stderr_stream,
406  &afw_s_a_flag_response_stderr_stream_brief,
407  &afw_s_a_flag_response_stderr_stream_description,
408  NULL,
409  xctx);
411  &afw_s_a_flag_response_stderr,
412  &afw_s_a_flag_response_stderr_stream,
413  xctx);
414 
416  &afw_s_a_flag_response_stdout,
417  &afw_s_a_flag_response_stdout_brief,
418  &afw_s_a_flag_response_stdout_description,
419  NULL,
420  xctx);
422  &afw_s_a_flag_response_stdout_stream,
423  &afw_s_a_flag_response_stdout_stream_brief,
424  &afw_s_a_flag_response_stdout_stream_description,
425  NULL,
426  xctx);
428  &afw_s_a_flag_response_stdout,
429  &afw_s_a_flag_response_stdout_stream,
430  xctx);
431 
432 
433  /* Register flag trace:detail */
435  &afw_s_a_flag_trace_detail,
436  &afw_s_a_flag_trace_detail_brief,
437  &afw_s_a_flag_trace_detail_description,
438  NULL,
439  xctx);
440 
441  /* Register flag trace */
443  &afw_s_a_flag_trace,
444  &afw_s_a_flag_trace_brief,
445  &afw_s_a_flag_trace_description,
446  &afw_s_a_flag_trace_detail,
447  xctx);
448 
449  /* Register flag trace:adaptor:detail */
451  &afw_s_a_flag_trace_adaptor_detail,
452  &afw_s_a_flag_trace_adaptor_detail_brief,
453  &afw_s_a_flag_trace_adaptor_detail_description,
454  &afw_s_a_flag_trace_detail,
455  xctx);
456 
457  /* Register flag trace:adaptor */
459  &afw_s_a_flag_trace_adaptor,
460  &afw_s_a_flag_trace_adaptor_brief,
461  &afw_s_a_flag_trace_adaptor_description,
462  &afw_s_a_flag_trace,
463  xctx);
465  &afw_s_a_flag_trace_adaptor,
466  &afw_s_a_flag_trace_adaptor_detail,
467  xctx);
468 
469  /* Register flag trace:authorizationHandler:detail */
471  &afw_s_a_flag_trace_authorizationHandler_detail,
472  &afw_s_a_flag_trace_authorizationHandler_detail_brief,
473  &afw_s_a_flag_trace_authorizationHandler_detail_description,
474  &afw_s_a_flag_trace_detail,
475  xctx);
476 
477  /* Register flag trace:authorizationHandler */
479  &afw_s_a_flag_trace_authorizationHandler,
480  &afw_s_a_flag_trace_authorizationHandler_brief,
481  &afw_s_a_flag_trace_authorizationHandler_description,
482  &afw_s_a_flag_trace,
483  xctx);
485  &afw_s_a_flag_trace_authorizationHandler,
486  &afw_s_a_flag_trace_authorizationHandler_detail,
487  xctx);
488 
489  /* Register flag trace:evaluation:detail */
491  &afw_s_a_flag_trace_evaluation_detail,
492  &afw_s_a_flag_trace_evaluation_detail_brief,
493  &afw_s_a_flag_trace_evaluation_detail_description,
494  &afw_s_a_flag_trace_detail,
495  xctx);
498  &afw_s_a_flag_trace_evaluation_detail,
499  xctx)->flag_index;
500 
501  /* Register flag trace:request:detail */
503  &afw_s_a_flag_trace_request_detail,
504  &afw_s_a_flag_trace_request_detail_brief,
505  &afw_s_a_flag_trace_request_detail_description,
506  &afw_s_a_flag_trace_detail,
507  xctx);
510  &afw_s_a_flag_trace_request_detail,
511  xctx)->flag_index;
512 
513  /* Register flag trace:request */
515  &afw_s_a_flag_trace_request,
516  &afw_s_a_flag_trace_request_brief,
517  &afw_s_a_flag_trace_request_description,
518  &afw_s_a_flag_trace,
519  xctx);
521  &afw_s_a_flag_trace_request,
522  &afw_s_a_flag_trace_request_detail,
523  xctx);
526  &afw_s_a_flag_trace_request,
527  xctx)->flag_index;
528 
529 }
530 
531 
532 /* Get flag by index */
533 AFW_DEFINE(const afw_flag_t *)
535  afw_size_t flag_index,
536  afw_xctx_t *xctx)
537 {
538  return (flag_index < xctx->env->flags_count_allocated)
539  ? xctx->env->flag_by_index[flag_index]
540  : NULL;
541 }
542 
543 
544 /* Get the flag index for a flag id. */
547  const afw_utf8_t *flag_id,
548  afw_xctx_t *xctx)
549 {
550  const afw_flag_t *flag;
551 
552  flag = afw_environment_get_flag(flag_id, xctx);
553  if (!flag) {
554  AFW_THROW_ERROR_FZ(general, xctx,
555  "%" AFW_UTF8_FMT " is not a registered flagId",
556  AFW_UTF8_FMT_ARG(flag_id));
557  }
558  return flag->flag_index;
559 }
560 
561 
562 
563 /* Determine if flag for flag id is set in xctx. */
566  const afw_utf8_t *flag_id,
567  afw_xctx_t *xctx)
568 {
569  afw_size_t flag_index;
570 
571  flag_index = afw_flag_get_index(flag_id, xctx);
572  return afw_flag_is_active(flag_index, xctx);
573 }
574 
575 
576 
577 /* Register a flag. */
578 AFW_DECLARE(void)
580  const afw_utf8_t *flag_id,
581  const afw_utf8_t *brief,
582  const afw_utf8_t *description,
583  const afw_utf8_t *included_by_flag_id,
584  afw_xctx_t *xctx)
585 {
586  afw_environment_t *env = (afw_environment_t *)xctx->env;
587  afw_environment_internal_t *internal_env =
588  (afw_environment_internal_t *)xctx->env;
589  const afw_pool_t *p = env->p;
590  afw_flag_t *self;
591  afw_flag_t *included_by;
592  afw_size_t flags_count_allocated;
593  afw_boolean_t *flags;
594  afw_flag_t **flag_by_index;
595 
597  {
598  if (afw_environment_get_flag(flag_id, xctx)) {
599  AFW_THROW_ERROR_FZ(general, xctx,
600  "Flag %" AFW_UTF8_FMT " is already registered",
601  AFW_UTF8_FMT_ARG(flag_id));
602  }
603 
604  self = afw_pool_calloc_type(p, afw_flag_t, xctx);
605  self->flag_id = flag_id;
606  self->flag_id_value = afw_value_create_string(flag_id, p, xctx);
607  self->brief = brief;
608  self->description = description;
609  self->object = afw_runtime_object_create_indirect(
610  &afw_s__AdaptiveFlag_, self->flag_id, self, p, xctx);
611  self->object_value = afw_value_create_object(self->object,
612  p, xctx);
613  self->flag_index = (env->flags_count_registered)++;
614  flags_count_allocated = env->flags_count_allocated;
615  if (self->flag_index >= env->flags_count_allocated) {
616  /*
617  * This causes a small one time leak. If too bad adjust
618  * AFW_FLAG_INITIAL_ALLOCATED_COUNT.
619  */
620  if (flags_count_allocated == 0) {
621  flags_count_allocated = AFW_FLAG_INITIAL_ALLOCATED_COUNT;
622  }
623  else {
624  flags_count_allocated = flags_count_allocated * 2;
625  }
626 
627  /* env->flags */
628  flags = afw_pool_calloc(p,
629  flags_count_allocated * sizeof(afw_boolean_t), xctx);
630  memcpy(flags, (void *)env->default_flags,
631  env->flags_count_allocated * sizeof(afw_boolean_t));
632  env->default_flags = (AFW_ATOMIC const afw_boolean_t *)flags;
633 
634  /* env->flag_by_index */
635  flag_by_index = afw_pool_calloc(p,
636  flags_count_allocated * sizeof(afw_flag_t **), xctx);
637  memcpy(flag_by_index, (void *)env->flag_by_index,
638  env->flags_count_allocated * sizeof(afw_flag_t **));
639  env->flag_by_index = (const afw_flag_t * AFW_ATOMIC *)flag_by_index;
640 
641  /* Set new allocated size now. */
642  env->flags_count_allocated = flags_count_allocated;
643 
644  /* Set internal base xctx flags. */
645  internal_env->base_xctx->flags =
647  internal_env->base_xctx->flags_count =
649  }
650 
651  self->applicable_flags = afw_pool_calloc(p,
652  flags_count_allocated * sizeof(afw_boolean_t), xctx);
653  self->applicable_flags_count_allocated = flags_count_allocated;
654 
655  ((afw_boolean_t *)self->applicable_flags)[self->flag_index] = true;
656 
658  afw_environemnt_registry_type_flag, flag_id, self, xctx);
659 
660  ((const afw_flag_t * AFW_ATOMIC *)env->flag_by_index)[self->flag_index] =
661  self;
662 
663  if (included_by_flag_id) {
664  included_by = (afw_flag_t *)afw_environment_registry_get(
665  afw_environemnt_registry_type_flag,
666  included_by_flag_id, xctx);
667  if (!included_by) {
668  AFW_THROW_ERROR_FZ(general, xctx,
669  "included_by_flag_id %" AFW_UTF8_FMT
670  " not found for flag_id %" AFW_UTF8_FMT,
671  AFW_UTF8_FMT_ARG(included_by_flag_id),
672  AFW_UTF8_FMT_ARG(flag_id));
673  }
674  impl_flag_add_included_by(self, included_by, xctx);
675  }
676 
677  afw_runtime_env_set_object(self->object, false, xctx);
678 
679  impl_refresh_default_flags(xctx);
680  }
681  AFW_LOCK_END;
682 }
683 
684 
685 
686 /* Add another include_by flag to a registered flag. */
687 AFW_DECLARE(void)
689  const afw_utf8_t *flag_id,
690  const afw_utf8_t *included_by_flag_id,
691  afw_xctx_t *xctx)
692 {
693  afw_flag_t *flag;
694  afw_flag_t *included_by;
695 
696  flag = (afw_flag_t *)afw_environment_get_flag(flag_id, xctx);
697  included_by = (afw_flag_t *)afw_environment_get_flag(included_by_flag_id, xctx);
698 
699  if (!flag || !included_by) {
700  AFW_THROW_ERROR_Z(general,
701  "Both flag_id and included_by_flag_id must already be registered",
702  xctx);
703  }
704 
705  AFW_LOCK_BEGIN(xctx->env->flags_lock) {
706  impl_flag_add_included_by(flag, included_by, xctx);
707  }
708  AFW_LOCK_END;
709 }
710 
711 
712 
715 /* Set flag to default value. */
716 AFW_DEFINE(void)
718  const afw_utf8_t *flag_id,
719  afw_boolean_t set_to,
720  afw_xctx_t *xctx)
721 {
722  afw_environment_internal_t *internal_env =
723  (afw_environment_internal_t *)xctx->env;
724  const afw_utf8_t **id;
725  const afw_pool_t *new_p;
726  const afw_utf8_t **new_ids;
727  const afw_utf8_t **new_id;
728  afw_size_t count;
729 
730  AFW_LOCK_BEGIN(xctx->env->flags_lock) {
731  /* Locate flag_id in defaults. */
732  count = 0;
733  if (internal_env->default_flag_ids) {
734  for (id = (const afw_utf8_t **)internal_env->default_flag_ids;
735  *id && !afw_utf8_equal(*id, flag_id);
736  id++, count++);
737  }
738 
739  /* If set and not already in list, add it. */
740  if (set_to) {
741  if (!internal_env->default_flag_ids || !*id) {
742  new_p = afw_pool_create(internal_env->pub.p, xctx);
743  new_ids = afw_pool_malloc(new_p,
744  (count + 2) * sizeof(afw_utf8_t **), xctx);
745  new_id = new_ids;
746  if (internal_env->default_flag_ids) {
747  for (id = (const afw_utf8_t **)internal_env->default_flag_ids;
748  *id;
749  id++, new_id++)
750  {
751  *new_id = afw_utf8_clone(*id, new_p, xctx);
752  }
753  }
754  *new_id++ = afw_utf8_clone(flag_id, new_p, xctx);
755  *new_id = NULL;
756  internal_env->default_flag_ids = new_ids;
757  if (internal_env->default_flags_ids_p) {
758  afw_pool_destroy(internal_env->default_flags_ids_p, xctx);
759  }
760  internal_env->default_flags_ids_p = new_p;
761  }
762  }
763 
764  /* If unset and is in list, remove id. */
765  else if (internal_env->default_flag_ids && *id) {
766  for (; *id; id++) {
767  *id = *(id + 1);
768  }
769  }
770 
771  impl_refresh_default_flags(xctx);
772  }
773  AFW_LOCK_END;
774 }
775 
776 
777 
778 /* Set flag in xctx. */
779 AFW_DEFINE(void)
781  const afw_utf8_t *flag_id,
782  afw_boolean_t set_to,
783  afw_xctx_t *xctx)
784 {
785  if (xctx == ((afw_environment_internal_t *)xctx->env)->base_xctx) {
786  afw_flag_set_default(flag_id, set_to, xctx);
787  }
788 
789  impl_insure_flags_mutable(xctx);
790  impl_set_applicable_flags(flag_id, set_to, true,
791  (afw_boolean_t *)xctx->flags, xctx->flags_count, xctx);
792 }
793 
794 
795 /* Set xctx default flags plus one or more additional flags. */
796 AFW_DEFINE(void)
798  const afw_utf8_t * const *flag_ids,
799  afw_xctx_t *xctx)
800 {
801  const afw_utf8_t * const *flag_id;
802  afw_boolean_t *flags;
803  afw_size_t flags_count;
804 
805  flags_count = xctx->env->flags_count_allocated;
806  flags = afw_xctx_malloc(flags_count * sizeof(afw_boolean_t), xctx);
807  memcpy(flags, (void *)xctx->env->default_flags,
808  flags_count * sizeof(afw_boolean_t));
809  xctx->flags = flags;
810  xctx->flags_count = flags_count;
811  xctx->flags_is_mutable_copy = true;
812 
813  for (flag_id = flag_ids; *flag_id; flag_id++) {
814  impl_set_applicable_flags(*flag_id, true, true,
815  flags, flags_count, xctx);
816  }
817 }
818 
819 
820 
821 /* Set new default flags list. */
822 AFW_DEFINE(void)
824  const afw_list_t *default_flag_ids,
825  afw_xctx_t *xctx)
826 {
827  afw_environment_internal_t *internal_env =
828  (afw_environment_internal_t *)xctx->env;
829  const afw_pool_t *p;
830  afw_size_t count;
831  const afw_utf8_t **ids;
832  const afw_utf8_t **id;
833  const afw_utf8_t *s;
834  const afw_data_type_t *data_type;
835  const afw_iterator_t *iterator;
836 
837  AFW_LOCK_BEGIN(xctx->env->flags_lock) {
838  p = afw_pool_create(xctx->env->p, xctx);
839  count = afw_list_get_count(default_flag_ids, xctx);
840  ids = afw_pool_malloc(p, (count + 1) * sizeof(afw_utf8_t *), xctx);
841  ids[count] = NULL;
842 
843  iterator = NULL;
844  for (id = ids;; id++) {
845  afw_list_get_next_internal(default_flag_ids,
846  &iterator, &data_type, (const void **)&s, xctx);
847  if (!s) break;
848  if (!afw_data_type_is_string(data_type)) {
849  AFW_THROW_ERROR_Z(general,
850  "Default flagIds most all be strings", xctx);
851  }
852  *id = afw_utf8_clone(s, p, xctx);
853  }
854 
855  internal_env->default_flag_ids = ids;
856  if (internal_env->default_flags_ids_p) {
857  afw_pool_destroy(internal_env->default_flags_ids_p, xctx);
858  }
859  internal_env->default_flags_ids_p = p;
860  impl_refresh_default_flags(xctx);
861  }
862  AFW_LOCK_END;
863 
864 }
AFW_DEFINE(const afw_object_t *)
#define AFW_DEFINE_INTERNAL(type)
Define an internal function for /src/afw/ source*.c files.
#define AFW_DECLARE(type)
Declare a public afw function.
Adaptive Framework Core Internal.
afw_value_create_list(const afw_list_t *internal, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for unmanaged data type list value.
afw_value_create_object(const afw_object_t *internal, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for unmanaged data type object value.
afw_value_create_string(const afw_utf8_t *internal, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for unmanaged data type string value.
afw_data_type_string
Data type struct for string.
#define afw_data_type_is_string(A_DATA_TYPE)
Macro to determine if data type is string.
#define AFW_UTF8_FMT_ARG(A_STRING)
Convenience Macro for use with AFW_UTF8_FMT to specify arg.
Definition: afw_common.h:605
struct afw_iterator_s afw_iterator_t
_Bool afw_boolean_t
Definition: afw_common.h:373
#define AFW_UTF8_FMT
Format string specifier used for afw_utf8_t.
Definition: afw_common.h:588
apr_size_t afw_size_t
size_t.
Definition: afw_common.h:151
afw_environment_registry_register(int type_number, const afw_utf8_t *key, const void *value, afw_xctx_t *xctx)
Register a value by key for a registry type.
const afw_flag_t * afw_environment_get_flag(const afw_utf8_t *flag_id, afw_xctx_t *xctx)
Get the flag instance associated with flag_id.
afw_environment_registry_get(int type_number, const afw_utf8_t *key, afw_xctx_t *xctx)
Get the value associated with a key for a registry type.
#define AFW_THROW_ERROR_FZ(code, xctx, format_z,...)
Macro used to set error and 0 rv in xctx and throw it.
Definition: afw_error.h:319
#define AFW_THROW_ERROR_Z(code, message_z, xctx)
Macro used to set error and 0 rv in xctx and throw it.
Definition: afw_error.h:283
afw_boolean_t afw_flag_by_id_is_active(const afw_utf8_t *flag_id, afw_xctx_t *xctx)
Determine if flag for flag id is set in xctx.
Definition: afw_flag.c:565
afw_flag_set_default(const afw_utf8_t *flag_id, afw_boolean_t set_to, afw_xctx_t *xctx)
Set the default value of a flag.
Definition: afw_flag.c:717
#define afw_flag_is_active(flag_index, xctx)
Determine if flag for flag index is set in xctx.
Definition: afw_flag.h:84
afw_flag_set_to_defaults_plus_array(const afw_utf8_t *const *flag_ids, afw_xctx_t *xctx)
Set xctx default flags plus one or more additional flags.
Definition: afw_flag.c:797
afw_flag_get_by_index(afw_size_t flag_index, afw_xctx_t *xctx)
Get flag by index.
Definition: afw_flag.c:534
afw_flag_set_default_flag_ids(const afw_list_t *default_flag_ids, afw_xctx_t *xctx)
Set a new default flags list.
Definition: afw_flag.c:823
afw_flag_set(const afw_utf8_t *flag_id, afw_boolean_t set_to, afw_xctx_t *xctx)
Set a flag in xctx.
Definition: afw_flag.c:780
void afw_flag_environment_register_flag(const afw_utf8_t *flag_id, const afw_utf8_t *brief, const afw_utf8_t *description, const afw_utf8_t *included_by_flag_id, afw_xctx_t *xctx)
Register a flag definition.
Definition: afw_flag.c:579
afw_flag_get_index(const afw_utf8_t *flag_id, afw_xctx_t *xctx)
Get the flag index for a flag id.
Definition: afw_flag.c:546
void afw_flag_add_included_by(const afw_utf8_t *flag_id, const afw_utf8_t *included_by_flag_id, afw_xctx_t *xctx)
Add another include_by flag to a registered flag.
Definition: afw_flag.c:688
#define afw_list_get_next_internal(instance, iterator, data_type, internal, xctx)
Call method get_next_internal of interface afw_list.
#define afw_list_get_count(instance, xctx)
Call method get_count of interface afw_list.
afw_list_add_value(const afw_list_t *instance, const afw_value_t *value, afw_xctx_t *xctx)
Call method add_value of interface afw_list_setter.
Definition: afw_list.c:104
#define afw_list_of_create(data_type, p, xctx)
Create an list of a specific data type in memory.
Definition: afw_list.h:64
#define AFW_LOCK_BEGIN(instance)
Macro to begin a lock section.
Definition: afw_lock.h:191
#define AFW_LOCK_END
Macro to end a lock section.
Definition: afw_lock.h:202
#define afw_pool_destroy(instance, xctx)
Call method destroy of interface afw_pool.
#define afw_pool_malloc(instance, size, xctx)
Call method malloc of interface afw_pool.
#define afw_pool_calloc(instance, size, xctx)
Call method calloc of interface afw_pool.
#define afw_pool_calloc_type(instance, type, xctx)
Macro to allocate cleared memory to hold type in pool.
Definition: afw_pool.h:167
const afw_pool_t * afw_pool_create(const afw_pool_t *parent, afw_xctx_t *xctx)
Create a new pool.
afw_runtime_object_create_indirect(const afw_utf8_t *object_type_id, const afw_utf8_t *object_id, void *internal, const afw_pool_t *p, afw_xctx_t *xctx)
Create an indirect runtime object.
Definition: afw_runtime.c:481
afw_runtime_env_set_object(const afw_object_t *object, afw_boolean_t overwrite, afw_xctx_t *xctx)
Set an object pointer in the environment's runtime objects.
Definition: afw_runtime.c:210
afw_boolean_t afw_utf8_equal(const afw_utf8_t *s1, const afw_utf8_t *s2)
Check to see if a string equals another string.
const afw_utf8_t * afw_utf8_clone(const afw_utf8_t *string, const afw_pool_t *p, afw_xctx_t *xctx)
Clone a utf-8 string into a specific pool.
Definition: afw_utf8.h:347
#define afw_xctx_malloc(size, xctx)
Macro to allocate uncleared memory in xctx's pool.
Definition: afw_xctx.h:209
Interface afw_data_type public struct.
Struct for typedef afw_environment_t defined in afw_common.h.
Definition: afw_common.h:1383
AFW_ATOMIC const afw_boolean_t * default_flags
Default flags array indexed by flag_index.
Definition: afw_common.h:1519
afw_size_t flag_index_trace_request_detail
Flag index of trace:request:detail.
Definition: afw_common.h:1576
AFW_ATOMIC afw_size_t flags_count_allocated
The number of flags allocated in global_flags.
Definition: afw_common.h:1504
afw_size_t flag_index_debug_pool
Flag index of debug:pool.
Definition: afw_common.h:1537
afw_size_t flag_index_response_error_hasAdditionalDetail
Flag index of response:error:hasAdditionalDetail.
Definition: afw_common.h:1552
afw_size_t flag_index_response_error_contextual
Flag index of response:error:contextual.
Definition: afw_common.h:1549
afw_size_t flag_index_debug_function_active_detail
Flag index of debug:function_active:detail.
Definition: afw_common.h:1534
afw_size_t flag_index_trace_evaluation_detail
Flag index of trace:evaluation:detail.
Definition: afw_common.h:1570
const afw_pool_t * p
Pool used to hold environment.
Definition: afw_common.h:1386
afw_size_t flag_index_response_error_backtraceEvaluation
Flag index of response:error:backtraceEvaluation.
Definition: afw_common.h:1546
afw_size_t flag_index_debug_function_active
Flag index of debug:function_active.
Definition: afw_common.h:1531
const afw_lock_t * flags_lock
Lock for protecting changes to flags (internal to afw_flag.c).
Definition: afw_common.h:1498
const afw_flag_t *AFW_ATOMIC const * flag_by_index
Flag struct indexed by flag_index.
Definition: afw_common.h:1528
afw_size_t flag_index_debug_pool_detail
Flag index of debug:pool:detail.
Definition: afw_common.h:1540
afw_size_t flag_index_response_error_backtrace
Flag index of response:error:backtrace.
Definition: afw_common.h:1543
AFW_ATOMIC afw_size_t flags_count_registered
The number of flags registered.
Definition: afw_common.h:1507
afw_size_t flag_index_trace_request
Flag index of trace:request.
Definition: afw_common.h:1573
Struct used for a registered flag.
Definition: afw_flag.h:32
const afw_value_list_t * included_by_value
list value of all flags that include this flag.
Definition: afw_flag.h:66
const afw_value_t * flag_id_value
sting value of objectId of this flag.
Definition: afw_flag.h:42
const afw_boolean_t * applicable_flags
Applicable flags indexed by associated flag_index.
Definition: afw_flag.h:57
const afw_utf8_t * flag_id
objectId of this flag.
Definition: afw_flag.h:39
afw_size_t flag_index
Index of this flag in flags array.
Definition: afw_flag.h:51
const afw_value_list_t * includes_value
list value of all other flags this flag includes.
Definition: afw_flag.h:69
afw_size_t applicable_flags_count_allocated
Count of applicable_flags.
Definition: afw_flag.h:54
Interface afw_list public struct.
Interface afw_pool public struct.
NFC normalized UTF-8 string.
Definition: afw_common.h:545
struct for data type list values.
Interface afw_xctx public struct.