print-to-file first light

This commit is contained in:
John Kerl 2016-07-09 03:32:00 -04:00
parent 745905b7ef
commit 25fdb34371
6 changed files with 113 additions and 17 deletions

View file

@ -37,6 +37,8 @@ libcontainers_la_SOURCES= \
mlr_dsl_ast.h \
mlrval.c \
mlrval.h \
multi_out.c \
multi_out.h \
parse_trie.c \
parse_trie.h \
percentile_keeper.c \

47
c/containers/multi_out.c Normal file
View file

@ -0,0 +1,47 @@
#include "lib/mlrutil.h"
#include "lib/mlr_globals.h"
#include "multi_out.h"
// ----------------------------------------------------------------
multi_out_t* multi_out_alloc() {
multi_out_t* pmo = mlr_malloc_or_die(sizeof(multi_out_t));
pmo->pnames_to_fps = lhmsv_alloc();
return pmo;
}
// ----------------------------------------------------------------
void multi_out_free(multi_out_t* pmo) {
if (pmo == NULL)
return;
lhmsv_free(pmo->pnames_to_fps);
free(pmo);
}
// ----------------------------------------------------------------
static inline FILE* multi_out_get(multi_out_t* pmo, char* filename,
char* mode, char* mode_desc)
{
FILE* outfp = lhmsv_get(pmo->pnames_to_fps, filename);
if (outfp == NULL) {
outfp = fopen(filename, mode);
if (outfp == NULL) {
perror("fopen");
fprintf(stderr, "%s: failed fopen for %s of \"%s\".\n",
MLR_GLOBALS.bargv0, mode_desc, filename);
exit(1);
}
lhmsv_put(pmo->pnames_to_fps, mlr_strdup_or_die(filename), outfp, FREE_ENTRY_KEY);
}
return outfp;
}
// ----------------------------------------------------------------
FILE* multi_out_get_for_write(multi_out_t* pmo, char* filename) {
return multi_out_get(pmo, filename, "w", "write");
}
// ----------------------------------------------------------------
FILE* multi_out_get_for_append(multi_out_t* pmo, char* filename) {
return multi_out_get(pmo, filename, "a", "append");
}

19
c/containers/multi_out.h Normal file
View file

@ -0,0 +1,19 @@
#ifndef MULTI_OUT_H
#define MULTI_OUT_H
#include <stdio.h>
#include "containers/lhmsv.h"
// ----------------------------------------------------------------
typedef struct _multi_out_t {
// xxx to do: bound the number of open files and LRU them.
lhmsv_t* pnames_to_fps;
} multi_out_t;
// ----------------------------------------------------------------
multi_out_t* multi_out_alloc();
void multi_out_free(multi_out_t* pmo);
FILE* multi_out_get_for_write(multi_out_t* pmo, char* filename);
FILE* multi_out_get_for_append(multi_out_t* pmo, char* filename);
#endif // MULTI_OUT_H

View file

@ -501,6 +501,7 @@ static mlr_dsl_cst_statement_t* alloc_blank() {
pstatement->psrec_lhs_evaluator = NULL;
pstatement->prhs_evaluator = NULL;
pstatement->poutput_filename_evaluator = NULL;
pstatement->pmulti_out = NULL;
pstatement->poosvar_rhs_keylist_evaluators = NULL;
pstatement->pemit_oosvar_namelist_evaluators = NULL;
pstatement->pvarargs = NULL;
@ -1274,7 +1275,6 @@ static mlr_dsl_cst_statement_t* alloc_edump(mlr_dsl_ast_node_t* pnode, int type_
return pstatement;
}
// xxx temp
static mlr_dsl_cst_statement_t* alloc_dump_write(mlr_dsl_ast_node_t* pnode, int type_inferencing,
int context_flags)
{
@ -1287,6 +1287,7 @@ static mlr_dsl_cst_statement_t* alloc_dump_write(mlr_dsl_ast_node_t* pnode, int
mlr_dsl_ast_node_t* pfilename_node = pnode->pchildren->phead->pvvalue;
pstatement->poutput_filename_evaluator = rval_evaluator_alloc_from_ast(pfilename_node,
type_inferencing, context_flags);
pstatement->pmulti_out = multi_out_alloc();
pstatement->pnode_handler = handle_dump_write;
return pstatement;
}
@ -1303,6 +1304,7 @@ static mlr_dsl_cst_statement_t* alloc_dump_append(mlr_dsl_ast_node_t* pnode, int
mlr_dsl_ast_node_t* pfilename_node = pnode->pchildren->phead->pvvalue;
pstatement->poutput_filename_evaluator = rval_evaluator_alloc_from_ast(pfilename_node,
type_inferencing, context_flags);
pstatement->pmulti_out = multi_out_alloc();
pstatement->pnode_handler = handle_dump_append;
return pstatement;
}
@ -1352,6 +1354,7 @@ static mlr_dsl_cst_statement_t* alloc_print_write(mlr_dsl_ast_node_t* pnode, int
pstatement->prhs_evaluator = rval_evaluator_alloc_from_ast(pvalue_node, type_inferencing, context_flags);
pstatement->poutput_filename_evaluator = rval_evaluator_alloc_from_ast(pfilename_node,
type_inferencing, context_flags);
pstatement->pmulti_out = multi_out_alloc();
pstatement->pnode_handler = handle_print_write;
return pstatement;
}
@ -1370,6 +1373,7 @@ static mlr_dsl_cst_statement_t* alloc_print_append(mlr_dsl_ast_node_t* pnode, in
pstatement->prhs_evaluator = rval_evaluator_alloc_from_ast(pvalue_node, type_inferencing, context_flags);
pstatement->poutput_filename_evaluator = rval_evaluator_alloc_from_ast(pfilename_node,
type_inferencing, context_flags);
pstatement->pmulti_out = multi_out_alloc();
pstatement->pnode_handler = handle_print_append;
return pstatement;
}
@ -1419,6 +1423,7 @@ static mlr_dsl_cst_statement_t* alloc_printn_write(mlr_dsl_ast_node_t* pnode, in
pstatement->prhs_evaluator = rval_evaluator_alloc_from_ast(pvalue_node, type_inferencing, context_flags);
pstatement->poutput_filename_evaluator = rval_evaluator_alloc_from_ast(pfilename_node,
type_inferencing, context_flags);
pstatement->pmulti_out = multi_out_alloc();
pstatement->pnode_handler = handle_printn_write;
return pstatement;
}
@ -1437,6 +1442,7 @@ static mlr_dsl_cst_statement_t* alloc_printn_append(mlr_dsl_ast_node_t* pnode, i
pstatement->prhs_evaluator = rval_evaluator_alloc_from_ast(pvalue_node, type_inferencing, context_flags);
pstatement->poutput_filename_evaluator = rval_evaluator_alloc_from_ast(pfilename_node,
type_inferencing, context_flags);
pstatement->pmulti_out = multi_out_alloc();
pstatement->pnode_handler = handle_printn_append;
return pstatement;
}
@ -1491,6 +1497,12 @@ static void cst_statement_free(mlr_dsl_cst_statement_t* pstatement) {
pstatement->prhs_evaluator->pfree_func(pstatement->prhs_evaluator);
}
if (pstatement->poutput_filename_evaluator != NULL) {
pstatement->poutput_filename_evaluator->pfree_func(pstatement->poutput_filename_evaluator);
}
multi_out_free(pstatement->pmulti_out);
if (pstatement->poosvar_rhs_keylist_evaluators != NULL) {
for (sllve_t* pe = pstatement->poosvar_rhs_keylist_evaluators->phead; pe != NULL; pe = pe->pnext) {
rval_evaluator_t* phandler = pe->pvvalue;
@ -2090,7 +2102,6 @@ static void handle_eprint(
mv_free(&val);
}
// xxx temp
static void handle_print_write(
mlr_dsl_cst_statement_t* pnode,
variables_t* pvars,
@ -2100,13 +2111,20 @@ static void handle_print_write(
rval_evaluator_t* poutput_filename_evaluator = pnode->poutput_filename_evaluator;
mv_t val = prhs_evaluator->pprocess_func(prhs_evaluator->pvstate, pvars);
mv_t filename = poutput_filename_evaluator->pprocess_func(poutput_filename_evaluator->pvstate, pvars);
// xxx to do:
// open-files manager
char free_flags;
char* sval = mv_format_val(&val, &free_flags);
printf("%s\n", sval);
if (free_flags)
char sfree_flags;
char* sval = mv_format_val(&val, &sfree_flags);
char ffree_flags;
char* fval = mv_format_val(&filename, &ffree_flags);
FILE* outfp = multi_out_get_for_write(pnode->pmulti_out, fval);
fprintf(outfp, "%s\n", sval);
if (TRUE) // xxx temp
fflush(outfp);
if (sfree_flags)
free(sval);
if (ffree_flags)
free(fval);
mv_free(&filename);
mv_free(&val);
}
@ -2120,11 +2138,20 @@ static void handle_print_append(
rval_evaluator_t* poutput_filename_evaluator = pnode->poutput_filename_evaluator;
mv_t val = prhs_evaluator->pprocess_func(prhs_evaluator->pvstate, pvars);
mv_t filename = poutput_filename_evaluator->pprocess_func(poutput_filename_evaluator->pvstate, pvars);
char free_flags;
char* sval = mv_format_val(&val, &free_flags);
printf("%s\n", sval);
if (free_flags)
char sfree_flags;
char* sval = mv_format_val(&val, &sfree_flags);
char ffree_flags;
char* fval = mv_format_val(&filename, &ffree_flags);
FILE* outfp = multi_out_get_for_append(pnode->pmulti_out, fval);
fprintf(outfp, "%s\n", sval);
if (TRUE) // xxx temp
fflush(outfp);
if (sfree_flags)
free(sval);
if (ffree_flags)
free(fval);
mv_free(&filename);
mv_free(&val);
}
@ -2160,7 +2187,6 @@ static void handle_eprintn(
mv_free(&val);
}
// xxx temp
static void handle_printn_write(
mlr_dsl_cst_statement_t* pnode,
variables_t* pvars,
@ -2170,6 +2196,7 @@ static void handle_printn_write(
rval_evaluator_t* poutput_filename_evaluator = pnode->poutput_filename_evaluator;
mv_t val = prhs_evaluator->pprocess_func(prhs_evaluator->pvstate, pvars);
mv_t filename = poutput_filename_evaluator->pprocess_func(poutput_filename_evaluator->pvstate, pvars);
// xxx open-files manager
char free_flags;
char* sval = mv_format_val(&val, &free_flags);
printf("%s", sval);

View file

@ -6,6 +6,7 @@
#include "containers/lhmsmv.h"
#include "containers/bind_stack.h"
#include "containers/loop_stack.h"
#include "containers/multi_out.h"
// ================================================================
// Concrete syntax tree (CST) derived from an abstract syntax tree (AST).
@ -121,7 +122,7 @@ typedef struct _mlr_dsl_cst_statement_t {
// For 'print > filename_expression, value_expression'
rval_evaluator_t* poutput_filename_evaluator;
// xxx open-files manager object (w/ LRU for someday; keep-open-with-fflush for now).
multi_out_t* pmulti_out;
// Assigning full srec from oosvar:
sllv_t* poosvar_rhs_keylist_evaluators;

View file

@ -12,12 +12,13 @@ TOP OF LIST:
! go through lmag article & clarify all unclears
! shorthand for sec2gmtdate
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
! universalize the dot operator. all this string(a).string(b) is going to get really old.
CONCRETE FOR TEE:
* --oflags overlays, w/ substruct data & federated substruct fcns
* UTs
* flush default on or off?
* mapper nothing
- UTs, in various then-chains
- mld
@ -28,7 +29,6 @@ CONCRETE FOR PRINT:
* mk cmt xrefs mlr -k <-> parse.l.
* undocument eprint.
* edump/eprint reworked to >/>> stderr in the parser. remove elsewhere from the code.
* universalize the dot operator. all this "a".string(b) is going to get really old.
* fflush option for print and dump? tee has one.
TEE/MULTIFILE PLACEMENT: