mirror of
https://github.com/johnkerl/miller.git
synced 2026-07-28 18:21:52 +00:00
mapvar-ref iterate
This commit is contained in:
parent
5c0ab667fe
commit
41fc090f23
3 changed files with 113 additions and 218 deletions
|
|
@ -1126,30 +1126,20 @@ static void mlhmmv_to_lrecs_aux_within_record(
|
|||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
void mlhmmv_to_lrecs_lashed(mlhmmv_value_t** ptop_values, int num_submaps, sllmv_t** ppkeys, sllmv_t* pnames,
|
||||
void mlhmmv_to_lrecs_lashed(mlhmmv_value_t** ptop_values, int num_submaps, mv_t* pbasenames, sllmv_t* pnames,
|
||||
sllv_t* poutrecs, int do_full_prefixing, char* flatten_separator)
|
||||
{
|
||||
|
||||
// xxx remove
|
||||
// printf("BGN\n");
|
||||
// for (int i = 0; i < num_submaps; i++) {
|
||||
// printf("KEYS %d:\n", i);
|
||||
// sllmv_print(ppkeys[i]);
|
||||
// }
|
||||
// printf("NAMES:\n");
|
||||
// sllmv_print(pnames);
|
||||
// printf("END\n");
|
||||
|
||||
// First is primary and rest are lashed to it (lookups with same keys as primary).
|
||||
if (ptop_values[0] == NULL) {
|
||||
// No such entry in the mlhmmv results in no output records
|
||||
} else if (ptop_values[0]->is_terminal) {
|
||||
} else if (ptop_values[0]->is_terminal && mv_is_present(&ptop_values[0]->mlrval)) {
|
||||
lrec_t* poutrec = lrec_unbacked_alloc();
|
||||
for (int i = 0; i < num_submaps; i++) {
|
||||
// E.g. '@v = 3' at the top level of the mlhmmv.
|
||||
if (ptop_values[i]->is_terminal) {
|
||||
if (ptop_values[i]->is_terminal && mv_is_present(&ptop_values[i]->mlrval)) {
|
||||
lrec_put(poutrec,
|
||||
mv_alloc_format_val(&ppkeys[i]->phead->value),
|
||||
mv_alloc_format_val(&pbasenames[i]),
|
||||
mv_alloc_format_val(&ptop_values[i]->mlrval), FREE_ENTRY_KEY|FREE_ENTRY_VALUE);
|
||||
}
|
||||
}
|
||||
|
|
@ -1174,7 +1164,7 @@ void mlhmmv_to_lrecs_lashed(mlhmmv_value_t** ptop_values, int num_submaps, sllmv
|
|||
oosvar_names[i] = NULL;
|
||||
} else {
|
||||
ppnext_levels[i] = ptop_values[i]->pnext_level;
|
||||
oosvar_names[i] = mv_alloc_format_val(&ppkeys[i]->phead->value);
|
||||
oosvar_names[i] = mv_alloc_format_val(&pbasenames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1204,39 +1194,41 @@ static void mlhmmv_to_lrecs_aux_across_records_lashed(
|
|||
if (prestnames != NULL) {
|
||||
// If there is a namelist entry, pull it out to its own field on the output lrecs.
|
||||
// First is iterated over and the rest are lashed (lookups with same keys as primary).
|
||||
for (mlhmmv_level_entry_t* pe = pplevels[0]->phead; pe != NULL; pe = pe->pnext) {
|
||||
mlhmmv_value_t* pfirst_level_value = &pe->level_value;
|
||||
lrec_t* pnextrec = lrec_copy(ptemplate);
|
||||
lrec_put(pnextrec,
|
||||
mv_alloc_format_val(&prestnames->value),
|
||||
mv_alloc_format_val(&pe->level_key), FREE_ENTRY_KEY|FREE_ENTRY_VALUE);
|
||||
if (pplevels[0] != NULL) {
|
||||
for (mlhmmv_level_entry_t* pe = pplevels[0]->phead; pe != NULL; pe = pe->pnext) {
|
||||
mlhmmv_value_t* pfirst_level_value = &pe->level_value;
|
||||
lrec_t* pnextrec = lrec_copy(ptemplate);
|
||||
lrec_put(pnextrec,
|
||||
mv_alloc_format_val(&prestnames->value),
|
||||
mv_alloc_format_val(&pe->level_key), FREE_ENTRY_KEY|FREE_ENTRY_VALUE);
|
||||
|
||||
if (pfirst_level_value->is_terminal) {
|
||||
for (int i = 0; i < num_levels; i++) {
|
||||
mlhmmv_value_t* plevel_value = mlhmmv_get_next_level_entry_value(pplevels[i], &pe->level_key);
|
||||
if (plevel_value != NULL && plevel_value->is_terminal) {
|
||||
lrec_put(pnextrec,
|
||||
mlr_strdup_or_die(prefixes[i]),
|
||||
mv_alloc_format_val(&plevel_value->mlrval), FREE_ENTRY_KEY|FREE_ENTRY_VALUE);
|
||||
if (pfirst_level_value->is_terminal) {
|
||||
for (int i = 0; i < num_levels; i++) {
|
||||
mlhmmv_value_t* plevel_value = mlhmmv_get_next_level_entry_value(pplevels[i], &pe->level_key);
|
||||
if (plevel_value != NULL && plevel_value->is_terminal) {
|
||||
lrec_put(pnextrec,
|
||||
mlr_strdup_or_die(prefixes[i]),
|
||||
mv_alloc_format_val(&plevel_value->mlrval), FREE_ENTRY_KEY|FREE_ENTRY_VALUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
sllv_append(poutrecs, pnextrec);
|
||||
} else {
|
||||
mlhmmv_level_t** ppnext_levels = mlr_malloc_or_die(num_levels * sizeof(mlhmmv_level_t*));
|
||||
for (int i = 0; i < num_levels; i++) {
|
||||
mlhmmv_value_t* plevel_value = mlhmmv_get_next_level_entry_value(pplevels[i], &pe->level_key);
|
||||
if (plevel_value == NULL || plevel_value->is_terminal) {
|
||||
ppnext_levels[i] = NULL;
|
||||
} else {
|
||||
ppnext_levels[i] = plevel_value->pnext_level;
|
||||
sllv_append(poutrecs, pnextrec);
|
||||
} else {
|
||||
mlhmmv_level_t** ppnext_levels = mlr_malloc_or_die(num_levels * sizeof(mlhmmv_level_t*));
|
||||
for (int i = 0; i < num_levels; i++) {
|
||||
mlhmmv_value_t* plevel_value = mlhmmv_get_next_level_entry_value(pplevels[i], &pe->level_key);
|
||||
if (plevel_value == NULL || plevel_value->is_terminal) {
|
||||
ppnext_levels[i] = NULL;
|
||||
} else {
|
||||
ppnext_levels[i] = plevel_value->pnext_level;
|
||||
}
|
||||
}
|
||||
|
||||
mlhmmv_to_lrecs_aux_across_records_lashed(ppnext_levels, prefixes, num_levels,
|
||||
prestnames->pnext, pnextrec, poutrecs, do_full_prefixing, flatten_separator);
|
||||
|
||||
free(ppnext_levels);
|
||||
lrec_free(pnextrec);
|
||||
}
|
||||
|
||||
mlhmmv_to_lrecs_aux_across_records_lashed(ppnext_levels, prefixes, num_levels,
|
||||
prestnames->pnext, pnextrec, poutrecs, do_full_prefixing, flatten_separator);
|
||||
|
||||
free(ppnext_levels);
|
||||
lrec_free(pnextrec);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -224,7 +224,7 @@ void mlhmmv_clear_level(mlhmmv_level_t* plevel);
|
|||
void mlhmmv_to_lrecs(mlhmmv_t* pmap, sllmv_t* pkeys, sllmv_t* pnames, sllv_t* poutrecs,
|
||||
int do_full_prefixing, char* flatten_separator);
|
||||
|
||||
void mlhmmv_to_lrecs_lashed(mlhmmv_value_t** ptop_values, int num_submaps, sllmv_t** ppkeys, sllmv_t* pnames,
|
||||
void mlhmmv_to_lrecs_lashed(mlhmmv_value_t** ptop_values, int num_submaps, mv_t* pbasenames, sllmv_t* pnames,
|
||||
sllv_t* poutrecs, int do_full_prefixing, char* flatten_separator);
|
||||
|
||||
// xxx rm?
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ mlr_dsl_cst_statement_t* alloc_tee(mlr_dsl_cst_t* pcst, mlr_dsl_ast_node_t* pnod
|
|||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
static void free_tee(mlr_dsl_cst_statement_t* pstatement) { // xxx from mlr_dsl_cst_statement_free
|
||||
static void free_tee(mlr_dsl_cst_statement_t* pstatement) {
|
||||
tee_state_t* pstate = pstatement->pvstate;
|
||||
|
||||
if (pstate->poutput_filename_evaluator != NULL) {
|
||||
|
|
@ -1023,119 +1023,42 @@ static void handle_emit_all_to_file(
|
|||
|
||||
// ================================================================
|
||||
struct _emit_lashed_item_t; // Forward reference
|
||||
typedef mlhmmv_value_t* emit_lashed_item_getter_t(
|
||||
struct _emit_lashed_item_t* pitem, variables_t* pvars, sllmv_t* pmvkeys);
|
||||
// Ooosvars/localvars don't need freeing; ephemeral map-literals do.
|
||||
typedef void emit_lashed_item_freer_t(struct _emit_lashed_item_t* pitem);
|
||||
|
||||
typedef struct _emit_lashed_item_t {
|
||||
// For map literals
|
||||
rxval_evaluator_xxx_deprecated_t* prhs_xevaluator;
|
||||
mlhmmv_value_t ephemeral_xvalue; // xxx rm
|
||||
|
||||
// For local variables
|
||||
int localvar_frame_relative_index;
|
||||
|
||||
// Oosvar/localvar indices ["a", 1, $2] in
|
||||
// 'for (k,v in @a[1][$2]) {...}' or
|
||||
// 'for (k,v in a[1][$2]) {...}'.
|
||||
sllv_t* pemit_keylist_evaluators;
|
||||
|
||||
emit_lashed_item_getter_t* pemit_lashed_item_getter;
|
||||
emit_lashed_item_freer_t* pemit_lashed_item_freer;
|
||||
rval_evaluator_t* pbasename_evaluator;
|
||||
rxval_evaluator_t* pitem_xevaluator;
|
||||
} emit_lashed_item_t;
|
||||
|
||||
static emit_lashed_item_t* emit_lashed_item_alloc() {
|
||||
static emit_lashed_item_t* emit_lashed_item_alloc(
|
||||
rval_evaluator_t* pbasename_evaluator,
|
||||
rxval_evaluator_t* pitem_xevaluator)
|
||||
{
|
||||
emit_lashed_item_t* pitem = mlr_malloc_or_die(sizeof(emit_lashed_item_t));
|
||||
pitem->prhs_xevaluator = NULL;
|
||||
pitem->localvar_frame_relative_index = MD_UNUSED_INDEX;
|
||||
pitem->pemit_keylist_evaluators = NULL;
|
||||
pitem->pemit_lashed_item_getter = NULL;
|
||||
pitem->pemit_lashed_item_freer = NULL;
|
||||
pitem->pbasename_evaluator = pbasename_evaluator;
|
||||
pitem->pitem_xevaluator = pitem_xevaluator;
|
||||
return pitem;
|
||||
}
|
||||
|
||||
static void emit_lashed_item_free(emit_lashed_item_t* pitem) {
|
||||
if (pitem->prhs_xevaluator != NULL) {
|
||||
pitem->prhs_xevaluator->pfree_func(pitem->prhs_xevaluator);
|
||||
}
|
||||
if (pitem->pemit_keylist_evaluators != NULL) {
|
||||
for (sllve_t* pe = pitem->pemit_keylist_evaluators->phead; pe != NULL; pe = pe->pnext) {
|
||||
rval_evaluator_t* phandler = pe->pvvalue;
|
||||
phandler->pfree_func(phandler);
|
||||
}
|
||||
sllv_free(pitem->pemit_keylist_evaluators);
|
||||
}
|
||||
pitem->pbasename_evaluator->pfree_func(pitem->pbasename_evaluator);
|
||||
pitem->pitem_xevaluator->pfree_func(pitem->pitem_xevaluator);
|
||||
free(pitem);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
static mlhmmv_value_t* oosvar_emit_lashed_item_get(
|
||||
emit_lashed_item_t* pitem, variables_t* pvars, sllmv_t* pmvkeys)
|
||||
{
|
||||
int error = 0;
|
||||
// xxx check copy or not ... also encode that into all such names.
|
||||
return mlhmmv_get_value_from_level(pvars->poosvars->proot_level, pmvkeys, &error);
|
||||
}
|
||||
static void oosvar_emit_lashed_item_free(emit_lashed_item_t* pitem) {
|
||||
// Nothing to free for oosvars: we pointed to data within the oosvar and printed it, without allocating
|
||||
// anything extra.
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
static mlhmmv_value_t* nonindexed_local_variable_emit_lashed_item_get(
|
||||
emit_lashed_item_t* pitem, variables_t* pvars, sllmv_t* pmvkeys)
|
||||
{
|
||||
local_stack_frame_t* pframe = local_stack_get_top_frame(pvars->plocal_stack);
|
||||
// xxx check for copy/reference; and annotate the method names to make that clear at a glance.
|
||||
return local_stack_frame_get_extended_from_indexed(pframe, pitem->localvar_frame_relative_index, NULL);
|
||||
}
|
||||
static void nonindexed_local_variable_emit_lashed_item_free(emit_lashed_item_t* pitem) {
|
||||
// Nothing to free for localvars: we pointed to data within the localvar and printed it, without allocating
|
||||
// anything extra.
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
static mlhmmv_value_t* indexed_local_variable_emit_lashed_item_get(
|
||||
emit_lashed_item_t* pitem, variables_t* pvars, sllmv_t* pmvkeys)
|
||||
{
|
||||
local_stack_frame_t* pframe = local_stack_get_top_frame(pvars->plocal_stack);
|
||||
// xxx check for copy/reference; and annotate the method names to make that clear at a glance.
|
||||
// xxx need to index but skip the variable name at list head ...
|
||||
return local_stack_frame_get_extended_from_indexed(pframe, pitem->localvar_frame_relative_index, NULL);
|
||||
}
|
||||
static void indexed_local_variable_emit_lashed_item_free(emit_lashed_item_t* pitem) {
|
||||
// Nothing to free for localvars: we pointed to data within the localvar and printed it, without allocating
|
||||
// anything extra.
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
static mlhmmv_value_t* map_literal_emit_lashed_item_get(
|
||||
emit_lashed_item_t* pitem, variables_t* pvars, sllmv_t* pmvkeys)
|
||||
{
|
||||
rxval_evaluator_xxx_deprecated_t* prhs_xevaluator = pitem->prhs_xevaluator;
|
||||
pitem->ephemeral_xvalue = prhs_xevaluator->pprocess_func(prhs_xevaluator->pvstate, pvars);
|
||||
return &pitem->ephemeral_xvalue;
|
||||
}
|
||||
static void map_literal_emit_lashed_item_free(emit_lashed_item_t* pitem) {
|
||||
mlhmmv_free_submap(pitem->ephemeral_xvalue);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
typedef struct _emit_lashed_state_t {
|
||||
int num_emit_lashed_items;
|
||||
emit_lashed_item_t** ppitems;
|
||||
sllv_t* pemit_namelist_evaluators;
|
||||
|
||||
rval_evaluator_t* poutput_filename_evaluator;
|
||||
FILE* stdfp;
|
||||
file_output_mode_t file_output_mode;
|
||||
sllv_t* pemit_namelist_evaluators;
|
||||
int do_full_prefixing;
|
||||
|
||||
int num_emit_lashed_items;
|
||||
emit_lashed_item_t** ppitems;
|
||||
|
||||
lrec_writer_t* psingle_lrec_writer; // emit/tee to stdout/stderr
|
||||
multi_lrec_writer_t* pmulti_lrec_writer; // emit-to-file
|
||||
|
||||
int flush_every_record;
|
||||
int do_full_prefixing;
|
||||
int flush_every_record;
|
||||
} emit_lashed_state_t;
|
||||
|
||||
static mlr_dsl_cst_statement_handler_t handle_emit_lashed;
|
||||
|
|
@ -1154,67 +1077,44 @@ mlr_dsl_cst_statement_t* alloc_emit_lashed(mlr_dsl_cst_t* pcst, mlr_dsl_ast_node
|
|||
{
|
||||
emit_lashed_state_t* pstate = mlr_malloc_or_die(sizeof(emit_lashed_state_t));
|
||||
|
||||
mlr_dsl_ast_node_t* pemit_node = pnode->pchildren->phead->pvvalue;
|
||||
mlr_dsl_ast_node_t* poutput_node = pnode->pchildren->phead->pnext->pvvalue;
|
||||
|
||||
mlr_dsl_ast_node_t* pkeylists_node = pemit_node->pchildren->phead->pvvalue;
|
||||
pstate->num_emit_lashed_items = 0;
|
||||
pstate->ppitems = NULL;
|
||||
pstate->pemit_namelist_evaluators = NULL;
|
||||
|
||||
pstate->poutput_filename_evaluator = NULL;
|
||||
pstate->stdfp = NULL;
|
||||
pstate->pemit_namelist_evaluators = NULL;
|
||||
pstate->num_emit_lashed_items = 0;
|
||||
pstate->ppitems = NULL;
|
||||
pstate->psingle_lrec_writer = NULL;
|
||||
pstate->pmulti_lrec_writer = NULL;
|
||||
|
||||
mlr_dsl_ast_node_t* pemit_node = pnode->pchildren->phead->pvvalue;
|
||||
mlr_dsl_ast_node_t* poutput_node = pnode->pchildren->phead->pnext->pvvalue;
|
||||
mlr_dsl_ast_node_t* pkeylists_node = pemit_node->pchildren->phead->pvvalue;
|
||||
|
||||
pstate->num_emit_lashed_items = pkeylists_node->pchildren->length;
|
||||
pstate->ppitems = mlr_malloc_or_die(pstate->num_emit_lashed_items * sizeof(emit_lashed_item_t*));
|
||||
int i = 0;
|
||||
for (sllve_t* pe = pkeylists_node->pchildren->phead; pe != NULL; pe = pe->pnext, i++) {
|
||||
mlr_dsl_ast_node_t* pkeylist_node = pe->pvvalue;
|
||||
emit_lashed_item_t* pitem = emit_lashed_item_alloc();
|
||||
|
||||
rval_evaluator_t* pbasename_evaluator = NULL;
|
||||
switch (pkeylist_node->type) {
|
||||
case MD_AST_NODE_TYPE_OOSVAR_KEYLIST:
|
||||
pitem->pemit_lashed_item_getter = oosvar_emit_lashed_item_get;
|
||||
pitem->pemit_lashed_item_freer = oosvar_emit_lashed_item_free;
|
||||
pitem->pemit_keylist_evaluators = allocate_keylist_evaluators_from_ast_node(
|
||||
pkeylist_node, pcst->pfmgr, type_inferencing, context_flags);
|
||||
break;
|
||||
|
||||
case MD_AST_NODE_TYPE_NONINDEXED_LOCAL_VARIABLE:
|
||||
pitem->pemit_lashed_item_getter = nonindexed_local_variable_emit_lashed_item_get;
|
||||
pitem->pemit_lashed_item_freer = nonindexed_local_variable_emit_lashed_item_free;
|
||||
pitem->pemit_keylist_evaluators = sllv_alloc();
|
||||
// xxx comment; also, this is awkward.
|
||||
sllv_push(pitem->pemit_keylist_evaluators, rval_evaluator_alloc_from_string(pkeylist_node->text));
|
||||
MLR_INTERNAL_CODING_ERROR_IF(pkeylist_node->vardef_frame_relative_index == MD_UNUSED_INDEX);
|
||||
pitem->localvar_frame_relative_index = pkeylist_node->vardef_frame_relative_index;
|
||||
break;
|
||||
|
||||
case MD_AST_NODE_TYPE_INDEXED_LOCAL_VARIABLE:
|
||||
pitem->pemit_lashed_item_getter = indexed_local_variable_emit_lashed_item_get;
|
||||
pitem->pemit_lashed_item_freer = indexed_local_variable_emit_lashed_item_free;
|
||||
pitem->pemit_keylist_evaluators = allocate_keylist_evaluators_from_ast_node(
|
||||
pkeylist_node, pcst->pfmgr, type_inferencing, context_flags);
|
||||
MLR_INTERNAL_CODING_ERROR_IF(pkeylist_node->vardef_frame_relative_index == MD_UNUSED_INDEX);
|
||||
pitem->localvar_frame_relative_index = pkeylist_node->vardef_frame_relative_index;
|
||||
pbasename_evaluator = rval_evaluator_alloc_from_string(pkeylist_node->text);
|
||||
break;
|
||||
|
||||
case MD_AST_NODE_TYPE_MAP_LITERAL:
|
||||
pitem->pemit_lashed_item_getter = map_literal_emit_lashed_item_get;
|
||||
pitem->pemit_lashed_item_freer = map_literal_emit_lashed_item_free;
|
||||
pitem->pemit_keylist_evaluators = sllv_alloc();
|
||||
sllv_push(pitem->pemit_keylist_evaluators, rval_evaluator_alloc_from_string("_"));
|
||||
pitem->prhs_xevaluator = rxval_evaluator_alloc_from_ast_xxx_deprecated(
|
||||
pkeylist_node, pcst->pfmgr, type_inferencing, context_flags);
|
||||
case MD_AST_NODE_TYPE_OOSVAR_KEYLIST:
|
||||
pbasename_evaluator = rval_evaluator_alloc_from_string(
|
||||
((mlr_dsl_ast_node_t*)pkeylist_node->pchildren->phead->pvvalue)->text);
|
||||
break;
|
||||
|
||||
default:
|
||||
MLR_INTERNAL_CODING_ERROR();
|
||||
pbasename_evaluator = rval_evaluator_alloc_from_string("_");
|
||||
break;
|
||||
}
|
||||
|
||||
pstate->ppitems[i] = pitem;
|
||||
rxval_evaluator_t* pitem_xevaluator = rxval_evaluator_alloc_from_ast(
|
||||
pkeylist_node, pcst->pfmgr, type_inferencing, context_flags);
|
||||
|
||||
pstate->ppitems[i] = emit_lashed_item_alloc(pbasename_evaluator, pitem_xevaluator);
|
||||
}
|
||||
|
||||
sllv_t* pemit_namelist_evaluators = sllv_alloc();
|
||||
|
|
@ -1260,6 +1160,13 @@ mlr_dsl_cst_statement_t* alloc_emit_lashed(mlr_dsl_cst_t* pcst, mlr_dsl_ast_node
|
|||
static void free_emit_lashed(mlr_dsl_cst_statement_t* pstatement) {
|
||||
emit_lashed_state_t* pstate = pstatement->pvstate;
|
||||
|
||||
if (pstate->ppitems != NULL) {
|
||||
for (int i = 0; i < pstate->num_emit_lashed_items; i++) {
|
||||
emit_lashed_item_free(pstate->ppitems[i]);
|
||||
}
|
||||
free(pstate->ppitems);
|
||||
}
|
||||
|
||||
if (pstate->poutput_filename_evaluator != NULL) {
|
||||
pstate->poutput_filename_evaluator->pfree_func(pstate->poutput_filename_evaluator);
|
||||
}
|
||||
|
|
@ -1272,13 +1179,6 @@ static void free_emit_lashed(mlr_dsl_cst_statement_t* pstatement) {
|
|||
sllv_free(pstate->pemit_namelist_evaluators);
|
||||
}
|
||||
|
||||
if (pstate->ppitems != NULL) {
|
||||
for (int i = 0; i < pstate->num_emit_lashed_items; i++) {
|
||||
emit_lashed_item_free(pstate->ppitems[i]);
|
||||
}
|
||||
free(pstate->ppitems);
|
||||
}
|
||||
|
||||
if (pstate->psingle_lrec_writer != NULL) {
|
||||
pstate->psingle_lrec_writer->pfree_func(pstate->psingle_lrec_writer);
|
||||
}
|
||||
|
|
@ -1361,45 +1261,48 @@ static void handle_emit_lashed_common(
|
|||
sllv_t* poutrecs,
|
||||
char* oosvar_flatten_separator)
|
||||
{
|
||||
int keys_all_non_null_or_error = TRUE;
|
||||
|
||||
sllmv_t** ppmvkeys = mlr_malloc_or_die(pstate->num_emit_lashed_items * sizeof(sllmv_t*));
|
||||
// xxx alloc array in ctor, free in dtor, reuse here
|
||||
mv_t* pbasenames = mlr_malloc_or_die(pstate->num_emit_lashed_items * sizeof(mv_t));
|
||||
for (int i = 0; i < pstate->num_emit_lashed_items; i++) {
|
||||
ppmvkeys[i] = evaluate_list(pstate->ppitems[i]->pemit_keylist_evaluators, pvars,
|
||||
&keys_all_non_null_or_error);
|
||||
rval_evaluator_t* pev = pstate->ppitems[i]->pbasename_evaluator;
|
||||
pbasenames[i] = pev->pprocess_func(pev->pvstate, pvars);
|
||||
}
|
||||
|
||||
if (keys_all_non_null_or_error) {
|
||||
int names_all_non_null_or_error = TRUE;
|
||||
sllmv_t* pmvnames = evaluate_list(pstate->pemit_namelist_evaluators, pvars,
|
||||
&names_all_non_null_or_error);
|
||||
if (names_all_non_null_or_error) {
|
||||
int names_all_non_null_or_error = TRUE;
|
||||
sllmv_t* pmvnames = evaluate_list(pstate->pemit_namelist_evaluators, pvars,
|
||||
&names_all_non_null_or_error);
|
||||
if (names_all_non_null_or_error) {
|
||||
|
||||
mlhmmv_value_t** ptop_values = mlr_malloc_or_die(
|
||||
pstate->num_emit_lashed_items * sizeof(mlhmmv_level_entry_t*));
|
||||
for (int i = 0; i < pstate->num_emit_lashed_items; i++) {
|
||||
emit_lashed_item_t* pitem = pstate->ppitems[i];
|
||||
ptop_values[i] = pitem->pemit_lashed_item_getter(pitem, pvars, ppmvkeys[i]);
|
||||
}
|
||||
|
||||
mlhmmv_to_lrecs_lashed(ptop_values, pstate->num_emit_lashed_items, ppmvkeys, pmvnames,
|
||||
poutrecs, pstate->do_full_prefixing, oosvar_flatten_separator);
|
||||
|
||||
for (int i = 0; i < pstate->num_emit_lashed_items; i++) {
|
||||
emit_lashed_item_t* pitem = pstate->ppitems[i];
|
||||
if (pitem->pemit_lashed_item_freer != NULL) {
|
||||
pitem->pemit_lashed_item_freer(pitem);
|
||||
}
|
||||
}
|
||||
|
||||
free(ptop_values);
|
||||
// xxx alloc array in ctor, free in dtor, reuse here
|
||||
boxed_xval_t* pboxed_xvals = mlr_malloc_or_die(
|
||||
pstate->num_emit_lashed_items * sizeof(boxed_xval_t));
|
||||
// xxx comment
|
||||
mlhmmv_value_t** ptop_values = mlr_malloc_or_die(
|
||||
pstate->num_emit_lashed_items * sizeof(mlhmmv_level_entry_t*));
|
||||
for (int i = 0; i < pstate->num_emit_lashed_items; i++) {
|
||||
emit_lashed_item_t* pitem = pstate->ppitems[i];
|
||||
pboxed_xvals[i] = pitem->pitem_xevaluator->pprocess_func(
|
||||
pitem->pitem_xevaluator->pvstate, pvars);
|
||||
ptop_values[i] = &pboxed_xvals[i].xval;
|
||||
}
|
||||
sllmv_free(pmvnames);
|
||||
|
||||
mlhmmv_to_lrecs_lashed(ptop_values, pstate->num_emit_lashed_items, pbasenames, pmvnames,
|
||||
poutrecs, pstate->do_full_prefixing, oosvar_flatten_separator);
|
||||
|
||||
for (int i = 0; i < pstate->num_emit_lashed_items; i++) {
|
||||
if (pboxed_xvals[i].map_is_ephemeral) {
|
||||
mlhmmv_free_submap(pboxed_xvals[i].xval);
|
||||
}
|
||||
}
|
||||
|
||||
free(ptop_values);
|
||||
free(pboxed_xvals);
|
||||
}
|
||||
sllmv_free(pmvnames);
|
||||
|
||||
for (int i = 0; i < pstate->num_emit_lashed_items; i++) {
|
||||
sllmv_free(ppmvkeys[i]);
|
||||
mv_free(&pbasenames[i]);
|
||||
}
|
||||
free(ppmvkeys);
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue