"Fossies" - the Fresh Open Source Software Archive

Member "mlr-5.6.2/c/dsl/mlr_dsl_cst_unset_statements.c" (25 Aug 2019, 11665 Bytes) of package /linux/misc/mlr-5.6.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "mlr_dsl_cst_unset_statements.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 5.4.0_vs_5.5.0.

    1 #include <stdlib.h>
    2 #include "lib/mlr_globals.h"
    3 #include "lib/mlrutil.h"
    4 #include "keylist_evaluators.h"
    5 #include "mlr_dsl_cst.h"
    6 #include "context_flags.h"
    7 
    8 // ================================================================
    9 // Most statements have one item, except emit and unset.
   10 struct _unset_item_t;
   11 typedef void unset_item_handler_t(
   12     struct _unset_item_t* punset_item,
   13     variables_t*          pvars,
   14     cst_outputs_t*        pcst_outputs);
   15 
   16 typedef struct _unset_item_t {
   17     unset_item_handler_t* punset_item_handler;
   18     int                   local_variable_frame_relative_index;
   19     char*                 srec_field_name;
   20     sllv_t*               pkeylist_evaluators;
   21     rval_evaluator_t*     psrec_field_name_evaluator;
   22 } unset_item_t;
   23 
   24 static unset_item_t* alloc_blank_unset_item();
   25 static void free_unset_item(unset_item_t* punset_item);
   26 
   27 static void handle_unset_nonindexed_local_variable(
   28     unset_item_t*  punset_item,
   29     variables_t*   pvars,
   30     cst_outputs_t* pcst_outputs);
   31 
   32 static void handle_unset_indexed_local_variable(
   33     unset_item_t*  punset_item,
   34     variables_t*   pvars,
   35     cst_outputs_t* pcst_outputs);
   36 
   37 static void handle_unset_oosvar(
   38     unset_item_t*  punset_item,
   39     variables_t*   pvars,
   40     cst_outputs_t* pcst_outputs);
   41 
   42 static void handle_unset_full_srec(
   43     unset_item_t*  punset_item,
   44     variables_t*   pvars,
   45     cst_outputs_t* pcst_outputs);
   46 
   47 static void handle_unset_srec_field_name(
   48     unset_item_t*  punset_item,
   49     variables_t*   pvars,
   50     cst_outputs_t* pcst_outputs);
   51 
   52 static void handle_unset_indirect_srec_field_name(
   53     unset_item_t*  punset_item,
   54     variables_t*   pvars,
   55     cst_outputs_t* pcst_outputs);
   56 
   57 static void handle_unset_positional_srec_field_name(
   58     unset_item_t*  punset_item,
   59     variables_t*   pvars,
   60     cst_outputs_t* pcst_outputs);
   61 
   62 // ================================================================
   63 typedef struct _unset_state_t {
   64     sllv_t* punset_items;
   65 } unset_state_t;
   66 
   67 static mlr_dsl_cst_statement_handler_t handle_unset;
   68 static mlr_dsl_cst_statement_freer_t free_unset;
   69 
   70 static mlr_dsl_cst_statement_handler_t handle_unset;
   71 static mlr_dsl_cst_statement_handler_t handle_unset_all;
   72 
   73 // ----------------------------------------------------------------
   74 mlr_dsl_cst_statement_t* alloc_unset(mlr_dsl_cst_t* pcst, mlr_dsl_ast_node_t* pnode,
   75     int type_inferencing, int context_flags)
   76 {
   77     unset_state_t* pstate = mlr_malloc_or_die(sizeof(unset_state_t));
   78 
   79     pstate->punset_items = sllv_alloc();
   80 
   81     mlr_dsl_cst_statement_handler_t* pstatement_handler = handle_unset;
   82     for (sllve_t* pe = pnode->pchildren->phead; pe != NULL; pe = pe->pnext) {
   83         mlr_dsl_ast_node_t* pchild = pe->pvvalue;
   84 
   85         if (pchild->type == MD_AST_NODE_TYPE_ALL || pchild->type == MD_AST_NODE_TYPE_FULL_OOSVAR) {
   86             // The grammar allows only 'unset all', not 'unset @x, all, $y'.
   87             // So if 'all' appears at all, it's the only name. Likewise with '@*'.
   88             pstatement_handler = handle_unset_all;
   89 
   90         } else if (pchild->type == MD_AST_NODE_TYPE_FULL_SREC) {
   91             if (context_flags & IN_BEGIN_OR_END) {
   92                 fprintf(stderr, "%s: unset of $-variables is not valid within begin or end blocks.\n",
   93                     MLR_GLOBALS.bargv0);
   94                 exit(1);
   95             }
   96             unset_item_t* punset_item = alloc_blank_unset_item();
   97             punset_item->punset_item_handler = handle_unset_full_srec;
   98             sllv_append(pstate->punset_items, punset_item);
   99 
  100         } else if (pchild->type == MD_AST_NODE_TYPE_FIELD_NAME) {
  101             if (context_flags & IN_BEGIN_OR_END) {
  102                 fprintf(stderr, "%s: unset of $-variables is not valid within begin or end blocks.\n",
  103                     MLR_GLOBALS.bargv0);
  104                 exit(1);
  105             }
  106             unset_item_t* punset_item = alloc_blank_unset_item();
  107             punset_item->punset_item_handler = handle_unset_srec_field_name;
  108             punset_item->srec_field_name = pchild->text;
  109             sllv_append(pstate->punset_items, punset_item);
  110 
  111         } else if (pchild->type == MD_AST_NODE_TYPE_INDIRECT_FIELD_NAME) {
  112             if (context_flags & IN_BEGIN_OR_END) {
  113                 fprintf(stderr, "%s: unset of $-variables are not valid within begin or end blocks.\n",
  114                     MLR_GLOBALS.bargv0);
  115                 exit(1);
  116             }
  117             unset_item_t* punset_item = alloc_blank_unset_item();
  118             punset_item->punset_item_handler = handle_unset_indirect_srec_field_name;
  119             punset_item->psrec_field_name_evaluator = rval_evaluator_alloc_from_ast(
  120                 pchild->pchildren->phead->pvvalue, pcst->pfmgr, type_inferencing, context_flags);
  121             sllv_append(pstate->punset_items, punset_item);
  122 
  123         } else if (pchild->type == MD_AST_NODE_TYPE_POSITIONAL_SREC_NAME) {
  124             if (context_flags & IN_BEGIN_OR_END) {
  125                 fprintf(stderr, "%s: unset of $-variables are not valid within begin or end blocks.\n",
  126                     MLR_GLOBALS.bargv0);
  127                 exit(1);
  128             }
  129             unset_item_t* punset_item = alloc_blank_unset_item();
  130             punset_item->punset_item_handler = handle_unset_positional_srec_field_name;
  131             punset_item->psrec_field_name_evaluator = rval_evaluator_alloc_from_ast(
  132                 pchild->pchildren->phead->pvvalue, pcst->pfmgr, type_inferencing, context_flags);
  133             sllv_append(pstate->punset_items, punset_item);
  134 
  135         } else if (pchild->type == MD_AST_NODE_TYPE_OOSVAR_KEYLIST) {
  136             unset_item_t* punset_item = alloc_blank_unset_item();
  137             punset_item->punset_item_handler = handle_unset_oosvar;
  138             punset_item->pkeylist_evaluators = allocate_keylist_evaluators_from_ast_node(
  139                 pchild, pcst->pfmgr, type_inferencing, context_flags);
  140             sllv_append(pstate->punset_items, punset_item);
  141 
  142         } else if (pchild->type == MD_AST_NODE_TYPE_NONINDEXED_LOCAL_VARIABLE) {
  143             MLR_INTERNAL_CODING_ERROR_IF(pchild->vardef_frame_relative_index == MD_UNUSED_INDEX);
  144             unset_item_t* punset_item = alloc_blank_unset_item();
  145             punset_item->punset_item_handler = handle_unset_nonindexed_local_variable;
  146             punset_item->local_variable_frame_relative_index = pchild->vardef_frame_relative_index;
  147             sllv_append(pstate->punset_items, punset_item);
  148 
  149         } else if (pchild->type == MD_AST_NODE_TYPE_INDEXED_LOCAL_VARIABLE) {
  150             MLR_INTERNAL_CODING_ERROR_IF(pchild->vardef_frame_relative_index == MD_UNUSED_INDEX);
  151             unset_item_t* punset_item = alloc_blank_unset_item();
  152             punset_item->punset_item_handler = handle_unset_indexed_local_variable;
  153             punset_item->local_variable_frame_relative_index = pchild->vardef_frame_relative_index;
  154             punset_item->pkeylist_evaluators = allocate_keylist_evaluators_from_ast_node(
  155                 pchild, pcst->pfmgr, type_inferencing, context_flags);
  156             sllv_append(pstate->punset_items, punset_item);
  157 
  158         } else {
  159             MLR_INTERNAL_CODING_ERROR();
  160         }
  161     }
  162     return mlr_dsl_cst_statement_valloc(
  163         pnode,
  164         pstatement_handler,
  165         free_unset,
  166         pstate);
  167 }
  168 
  169 // ----------------------------------------------------------------
  170 static void free_unset(mlr_dsl_cst_statement_t* pstatement, context_t* _) {
  171     unset_state_t* pstate = pstatement->pvstate;
  172 
  173     for (sllve_t* pe = pstate->punset_items->phead; pe != NULL; pe = pe->pnext) {
  174         free_unset_item(pe->pvvalue);
  175     }
  176     sllv_free(pstate->punset_items);
  177 
  178     free(pstate);
  179 }
  180 
  181 // ----------------------------------------------------------------
  182 static void handle_unset(
  183     mlr_dsl_cst_statement_t* pstatement,
  184     variables_t*             pvars,
  185     cst_outputs_t*           pcst_outputs)
  186 {
  187     unset_state_t* pstate = pstatement->pvstate;
  188     for (sllve_t* pf = pstate->punset_items->phead; pf != NULL; pf = pf->pnext) {
  189         unset_item_t* punset_item = pf->pvvalue;
  190         punset_item->punset_item_handler(punset_item, pvars, pcst_outputs);
  191     }
  192 }
  193 
  194 static void handle_unset_all(
  195     mlr_dsl_cst_statement_t* pstatement,
  196     variables_t*             pvars,
  197     cst_outputs_t*           pcst_outputs)
  198 {
  199     sllmv_t* pempty = sllmv_alloc();
  200     mlhmmv_root_remove(pvars->poosvars, pempty);
  201     sllmv_free(pempty);
  202 }
  203 
  204 // ----------------------------------------------------------------
  205 static unset_item_t* alloc_blank_unset_item() {
  206     unset_item_t* punset_item = mlr_malloc_or_die(sizeof(unset_item_t));
  207 
  208     punset_item->punset_item_handler                 = NULL;
  209     punset_item->local_variable_frame_relative_index = MD_UNUSED_INDEX;
  210     punset_item->srec_field_name                     = NULL;
  211     punset_item->pkeylist_evaluators                 = NULL;
  212     punset_item->psrec_field_name_evaluator          = NULL;
  213 
  214     return punset_item;
  215 }
  216 
  217 static void free_unset_item(unset_item_t* punset_item) {
  218     if (punset_item->pkeylist_evaluators != NULL) {
  219         for (sllve_t* pe = punset_item->pkeylist_evaluators->phead; pe != NULL; pe = pe->pnext) {
  220             rval_evaluator_t* phandler = pe->pvvalue;
  221             phandler->pfree_func(phandler);
  222         }
  223         sllv_free(punset_item->pkeylist_evaluators);
  224     }
  225     if (punset_item->psrec_field_name_evaluator != NULL) {
  226         punset_item->psrec_field_name_evaluator->pfree_func(punset_item->psrec_field_name_evaluator);
  227     }
  228     free(punset_item);
  229 }
  230 
  231 static void handle_unset_nonindexed_local_variable(
  232     unset_item_t*  punset_item,
  233     variables_t*   pvars,
  234     cst_outputs_t* pcst_outputs)
  235 {
  236     local_stack_frame_t* pframe = local_stack_get_top_frame(pvars->plocal_stack);
  237     local_stack_frame_assign_terminal_nonindexed(pframe, punset_item->local_variable_frame_relative_index, mv_absent());
  238 }
  239 
  240 // As with oosvars, unset removes the key. E.g. if 'v = { 1:2, 3:4 }' then
  241 // 'unset v[1]' results in 'v = { 3:4 }'.
  242 static void handle_unset_indexed_local_variable(
  243     unset_item_t*  punset_item,
  244     variables_t*   pvars,
  245     cst_outputs_t* pcst_outputs)
  246 {
  247     int all_non_null_or_error = TRUE;
  248     sllmv_t* pmvkeys = evaluate_list(punset_item->pkeylist_evaluators, pvars, &all_non_null_or_error);
  249     if (all_non_null_or_error) {
  250         local_stack_frame_t* pframe = local_stack_get_top_frame(pvars->plocal_stack);
  251 
  252         // 'unset nonesuch[someindex]' requires the existence check first: else we'd be poking data
  253         // into the absent-value stack-frame-index-0 slot.
  254         mlhmmv_xvalue_t* pxval = local_stack_frame_ref_extended_from_indexed(pframe,
  255             punset_item->local_variable_frame_relative_index, NULL);
  256         if (pxval != NULL) {
  257             mlhmmv_level_remove(pxval->pnext_level, pmvkeys->phead);
  258         }
  259     }
  260     sllmv_free(pmvkeys);
  261 }
  262 
  263 static void handle_unset_oosvar(
  264     unset_item_t*  punset_item,
  265     variables_t*   pvars,
  266     cst_outputs_t* pcst_outputs)
  267 {
  268     int all_non_null_or_error = TRUE;
  269     sllmv_t* pmvkeys = evaluate_list(punset_item->pkeylist_evaluators, pvars, &all_non_null_or_error);
  270     if (all_non_null_or_error)
  271         mlhmmv_root_remove(pvars->poosvars, pmvkeys);
  272     sllmv_free(pmvkeys);
  273 }
  274 
  275 static void handle_unset_full_srec(
  276     unset_item_t*  punset_item,
  277     variables_t*   pvars,
  278     cst_outputs_t* pcst_outputs)
  279 {
  280     lrec_clear(pvars->pinrec);
  281 }
  282 
  283 static void handle_unset_srec_field_name(
  284     unset_item_t*  punset_item,
  285     variables_t*   pvars,
  286     cst_outputs_t* pcst_outputs)
  287 {
  288     lrec_remove(pvars->pinrec, punset_item->srec_field_name);
  289 }
  290 
  291 static void handle_unset_indirect_srec_field_name(
  292     unset_item_t*  punset_item,
  293     variables_t*   pvars,
  294     cst_outputs_t* pcst_outputs)
  295 {
  296     rval_evaluator_t* pevaluator = punset_item->psrec_field_name_evaluator;
  297     mv_t nameval = pevaluator->pprocess_func(pevaluator->pvstate, pvars);
  298     char free_flags = NO_FREE;
  299     char* field_name = mv_maybe_alloc_format_val(&nameval, &free_flags);
  300     lrec_remove(pvars->pinrec, field_name);
  301     if (free_flags & FREE_ENTRY_VALUE)
  302         free(field_name);
  303     mv_free(&nameval);
  304 }
  305 
  306 static void handle_unset_positional_srec_field_name(
  307     unset_item_t*  punset_item,
  308     variables_t*   pvars,
  309     cst_outputs_t* pcst_outputs)
  310 {
  311     rval_evaluator_t* pevaluator = punset_item->psrec_field_name_evaluator;
  312     mv_t nameval = pevaluator->pprocess_func(pevaluator->pvstate, pvars);
  313     if (!mv_is_int(&nameval)) {
  314         char free_flags = NO_FREE;
  315         char* text = mv_maybe_alloc_format_val(&nameval, &free_flags);
  316         fprintf(stderr, "%s: positional names must be integers; got \"%s\".\n", MLR_GLOBALS.bargv0, text);
  317         if (free_flags)
  318             free(text);
  319         exit(1);
  320     }
  321     // xxx typed overlay too!!
  322     int field_position = nameval.u.intv;
  323     lrec_remove_by_position(pvars->pinrec, field_position);
  324     mv_free(&nameval);
  325 }