// ---------------------------------------------------------------- static sllv_t* mapper_tail_process(lrec_t* pinrec, context_t* pctx, void* pvstate) { mapper_tail_state_t* pstate = pvstate; if (pinrec != NULL) { slls_t* pgroup_by_field_values = mlr_selected_values_from_record(pinrec, pstate->pgroup_by_field_names); sllv_t* precord_list_for_group = lhmslv_get(pstate->precord_lists_by_group, pgroup_by_field_values); if (precord_list_for_group == NULL) { precord_list_for_group = sllv_alloc(); lhmslv_put(pstate->precord_lists_by_group, slls_copy(pgroup_by_field_values), precord_list_for_group); } if (precord_list_for_group->length >= pstate->tail_count) { lrec_t* porec = sllv_pop(precord_list_for_group); if (porec != NULL) lrec_free(porec); } sllv_add(precord_list_for_group, pinrec); return NULL; } else { sllv_t* poutrecs = sllv_alloc(); for (lhmslve_t* pa = pstate->precord_lists_by_group->phead; pa != NULL; pa = pa->pnext) { sllv_t* precord_list_for_group = pa->pvvalue; for (sllve_t* pb = precord_list_for_group->phead; pb != NULL; pb = pb->pnext) { sllv_add(poutrecs, pb->pvdata); } } sllv_add(poutrecs, NULL); return poutrecs; } }
// ---------------------------------------------------------------- static sllv_t* mapper_group_like_process(lrec_t* pinrec, context_t* pctx, void* pvstate) { mapper_group_like_state_t* pstate = pvstate; if (pinrec != NULL) { slls_t* pkey_field_names = mlr_reference_keys_from_record(pinrec); sllv_t* plist = lhmslv_get(pstate->precords_by_key_field_names, pkey_field_names); if (plist == NULL) { plist = sllv_alloc(); sllv_add(plist, pinrec); lhmslv_put(pstate->precords_by_key_field_names, slls_copy(pkey_field_names), plist); } else { sllv_add(plist, pinrec); } return NULL; } else { sllv_t* poutput = sllv_alloc(); for (lhmslve_t* pe = pstate->precords_by_key_field_names->phead; pe != NULL; pe = pe->pnext) { sllv_t* plist = pe->pvvalue; for (sllve_t* pf = plist->phead; pf != NULL; pf = pf->pnext) { sllv_add(poutput, pf->pvdata); } } sllv_add(poutput, NULL); return poutput; } }
// ---------------------------------------------------------------- mlr_dsl_ast_node_t* mlr_dsl_ast_node_alloc_binary(char* text, int type, mlr_dsl_ast_node_t* pa, mlr_dsl_ast_node_t* pb) { mlr_dsl_ast_node_t* pnode = mlr_dsl_ast_node_alloc(text, type); pnode->pchildren = sllv_alloc(); sllv_add(pnode->pchildren, pa); sllv_add(pnode->pchildren, pb); return pnode; }
// ---------------------------------------------------------------- static void lrec_writer_pprint_process(FILE* output_stream, lrec_t* prec, void* pvstate) { lrec_writer_pprint_state_t* pstate = pvstate; int drain = FALSE; if (prec == NULL) { drain = TRUE; } else { if (pstate->pprev_keys != NULL && !lrec_keys_equal_list(prec, pstate->pprev_keys)) { drain = TRUE; } } if (drain) { if (pstate->num_blocks_written > 0LL) // separate blocks with empty line fputs(pstate->ors, output_stream); print_and_free_record_list(pstate->precords, output_stream, pstate->ors, pstate->ofs, pstate->left_align); if (pstate->pprev_keys != NULL) { slls_free(pstate->pprev_keys); pstate->pprev_keys = NULL; } pstate->precords = sllv_alloc(); pstate->num_blocks_written++; } if (prec != NULL) { sllv_add(pstate->precords, prec); if (pstate->pprev_keys == NULL) pstate->pprev_keys = mlr_copy_keys_from_record(prec); } }
// ---------------------------------------------------------------- static char* test_sllv_append() { mu_assert_lf(0 == 0); sllv_t* pa = sllv_alloc(); sllv_add(pa, "a"); sllv_add(pa, "b"); sllv_add(pa, "c"); mu_assert_lf(pa->length == 3); sllve_t* pe = pa->phead; mu_assert_lf(pe != NULL); mu_assert_lf(streq(pe->pvdata, "a")); pe = pe->pnext; mu_assert_lf(pe != NULL); mu_assert_lf(streq(pe->pvdata, "b")); pe = pe->pnext; mu_assert_lf(pe != NULL); mu_assert_lf(streq(pe->pvdata, "c")); pe = pe->pnext; mu_assert_lf(pe == NULL); sllv_t* pb = sllv_alloc(); sllv_add(pb, "d"); sllv_add(pb, "e"); mu_assert_lf(pb->length == 2); pe = pb->phead; mu_assert_lf(pe != NULL); mu_assert_lf(streq(pe->pvdata, "d")); pe = pe->pnext; mu_assert_lf(pe != NULL); mu_assert_lf(streq(pe->pvdata, "e")); pe = pe->pnext; mu_assert_lf(pe == NULL); pa = sllv_append(pa, pb); mu_assert_lf(pa->length == 5); mu_assert_lf(pb->length == 2); pe = pa->phead; mu_assert_lf(pe != NULL); mu_assert_lf(streq(pe->pvdata, "a")); pe = pe->pnext; mu_assert_lf(pe != NULL); mu_assert_lf(streq(pe->pvdata, "b")); pe = pe->pnext; mu_assert_lf(pe != NULL); mu_assert_lf(streq(pe->pvdata, "c")); pe = pe->pnext; mu_assert_lf(pe != NULL); mu_assert_lf(streq(pe->pvdata, "d")); pe = pe->pnext; mu_assert_lf(pe != NULL); mu_assert_lf(streq(pe->pvdata, "e")); pe = pe->pnext; mu_assert_lf(pe == NULL); pe = pb->phead; mu_assert_lf(pe != NULL); mu_assert_lf(streq(pe->pvdata, "d")); pe = pe->pnext; mu_assert_lf(pe != NULL); mu_assert_lf(streq(pe->pvdata, "e")); pe = pe->pnext; mu_assert_lf(pe == NULL); return NULL; }
// ---------------------------------------------------------------- mlr_dsl_ast_node_t* mlr_dsl_ast_node_append_arg( mlr_dsl_ast_node_t* pa, mlr_dsl_ast_node_t* pb) { if (pa->pchildren == NULL) pa->pchildren = sllv_alloc(); sllv_add(pa->pchildren, pb); return pa; }
static sllv_t* mlr_dsl_cst_alloc_from_statement_list(sllv_t* pasts, int type_inferencing) { sllv_t* pstatements = sllv_alloc(); for (sllve_t* pe = pasts->phead; pe != NULL; pe = pe->pnext) { mlr_dsl_ast_node_t* past = pe->pvvalue; mlr_dsl_cst_statement_t* pstatement = cst_statement_alloc(past, type_inferencing); sllv_add(pstatements, pstatement); } return pstatements; }
// ---------------------------------------------------------------- static sllv_t* mapper_stats1_emit(mapper_stats1_state_t* pstate) { sllv_t* poutrecs = sllv_alloc(); for (lhmslve_t* pa = pstate->groups->phead; pa != NULL; pa = pa->pnext) { slls_t* pgroup_by_field_values = pa->key; lrec_t* poutrec = lrec_unbacked_alloc(); // Add in a=s,b=t fields: sllse_t* pb = pstate->pgroup_by_field_names->phead; sllse_t* pc = pgroup_by_field_values->phead; for ( ; pb != NULL && pc != NULL; pb = pb->pnext, pc = pc->pnext) { lrec_put(poutrec, pb->value, pc->value, 0); } // Add in fields such as x_sum=#, y_count=#, etc.: lhmsv_t* group_to_acc_field = pa->pvvalue; // for "x", "y" for (lhmsve_t* pd = group_to_acc_field->phead; pd != NULL; pd = pd->pnext) { char* value_field_name = pd->key; lhmsv_t* acc_field_to_acc_state = pd->pvvalue; for (sllse_t* pe = pstate->paccumulator_names->phead; pe != NULL; pe = pe->pnext) { char* acc_name = pe->value; if (streq(acc_name, fake_acc_name_for_setups)) continue; acc_t* pacc = lhmsv_get(acc_field_to_acc_state, acc_name); if (pacc == NULL) { fprintf(stderr, "%s stats1: internal coding error: acc_name \"%s\" has gone missing.\n", MLR_GLOBALS.argv0, acc_name); exit(1); } pacc->pemit_func(pacc->pvstate, value_field_name, acc_name, poutrec); } } sllv_add(poutrecs, poutrec); } sllv_add(poutrecs, NULL); return poutrecs; }
int main(int argc, char** argv) { sllv_t* precords = sllv_alloc(); sllv_add(precords, lrec_literal_2("a","1", "b","10")); sllv_add(precords, lrec_literal_2("a","1", "b","11")); sllv_add(precords, lrec_literal_2("a","2", "b","12")); sllv_add(precords, lrec_literal_2("a","2", "b","13")); sllv_add(precords, lrec_literal_2("a","3", "b","14")); sllv_add(precords, lrec_literal_2("a","3", "b","15")); lrec_reader_t* preader = lrec_reader_in_memory_alloc(precords); printf("#=%d\n", precords->length); while (TRUE) { lrec_t* precord = preader->pprocess_func(NULL, preader->pvstate, NULL); if (precord == NULL) break; lrec_print(precord); } return 0; }
void ap_define_string_list_flag(ap_state_t* pstate, char* flag_name, slls_t** pplist) { sllv_add(pstate->pflag_defs, ap_flag_def_alloc(flag_name, AP_STRING_LIST_FLAG, 0, pplist, 2)); }
void ap_define_string_flag(ap_state_t* pstate, char* flag_name, char** pstring) { sllv_add(pstate->pflag_defs, ap_flag_def_alloc(flag_name, AP_STRING_FLAG, 0, pstring, 2)); }
void ap_define_double_flag(ap_state_t* pstate, char* flag_name, double* pdoubleval) { sllv_add(pstate->pflag_defs, ap_flag_def_alloc(flag_name, AP_DOUBLE_FLAG, 0, pdoubleval, 2)); }
void ap_define_int_value_flag(ap_state_t* pstate, char* flag_name, int intval, int* pintval) { sllv_add(pstate->pflag_defs, ap_flag_def_alloc(flag_name, AP_INT_VALUE_FLAG, intval, pintval, 1)); }
// ---------------------------------------------------------------- cli_opts_t* parse_command_line(int argc, char** argv) { cli_opts_t* popts = mlr_malloc_or_die(sizeof(cli_opts_t)); memset(popts, 0, sizeof(*popts)); popts->irs = DEFAULT_RS; popts->ifs = DEFAULT_FS; popts->ips = DEFAULT_PS; popts->allow_repeat_ifs = FALSE; popts->allow_repeat_ips = FALSE; popts->ors = DEFAULT_RS; popts->ofs = DEFAULT_FS; popts->ops = DEFAULT_PS; popts->ofmt = DEFAULT_OFMT; popts->plrec_reader = NULL; popts->plrec_writer = NULL; popts->filenames = NULL; popts->ifmt = "dkvp"; char* ofmt = "dkvp"; popts->use_mmap_for_read = TRUE; int left_align_pprint = TRUE; int have_rand_seed = FALSE; unsigned rand_seed = 0; int argi = 1; for (; argi < argc; argi++) { if (argv[argi][0] != '-') break; else if (streq(argv[argi], "-h")) main_usage(argv[0], 0); else if (streq(argv[argi], "--help")) main_usage(argv[0], 0); else if (streq(argv[argi], "--help-all-verbs")) usage_all_verbs(argv[0]); else if (streq(argv[argi], "--help-all-functions") || streq(argv[argi], "-f")) { lrec_evaluator_function_usage(stdout, NULL); exit(0); } else if (streq(argv[argi], "--help-function") || streq(argv[argi], "--hf")) { check_arg_count(argv, argi, argc, 2); lrec_evaluator_function_usage(stdout, argv[argi+1]); exit(0); } else if (streq(argv[argi], "--rs")) { check_arg_count(argv, argi, argc, 2); popts->ors = popts->irs = sep_from_arg(argv[argi+1], argv[0]); argi++; } else if (streq(argv[argi], "--irs")) { check_arg_count(argv, argi, argc, 2); popts->irs = sep_from_arg(argv[argi+1], argv[0]); argi++; } else if (streq(argv[argi], "--ors")) { check_arg_count(argv, argi, argc, 2); popts->ors = sep_from_arg(argv[argi+1], argv[0]); argi++; } else if (streq(argv[argi], "--fs")) { check_arg_count(argv, argi, argc, 2); popts->ofs = popts->ifs = sep_from_arg(argv[argi+1], argv[0]); argi++; } else if (streq(argv[argi], "--ifs")) { check_arg_count(argv, argi, argc, 2); popts->ifs = sep_from_arg(argv[argi+1], argv[0]); argi++; } else if (streq(argv[argi], "--ofs")) { check_arg_count(argv, argi, argc, 2); popts->ofs = sep_from_arg(argv[argi+1], argv[0]); argi++; } else if (streq(argv[argi], "--repifs")) { popts->allow_repeat_ifs = TRUE; } else if (streq(argv[argi], "-p")) { popts->ifmt = "nidx"; ofmt = "nidx"; popts->ifs = ' '; popts->ofs = ' '; popts->allow_repeat_ifs = TRUE; } else if (streq(argv[argi], "--ps")) { check_arg_count(argv, argi, argc, 2); popts->ops = popts->ips = sep_from_arg(argv[argi+1], argv[0]); argi++; } else if (streq(argv[argi], "--ips")) { check_arg_count(argv, argi, argc, 2); popts->ips = sep_from_arg(argv[argi+1], argv[0]); argi++; } else if (streq(argv[argi], "--ops")) { check_arg_count(argv, argi, argc, 2); popts->ops = sep_from_arg(argv[argi+1], argv[0]); argi++; } else if (streq(argv[argi], "--dkvp")) { popts->ifmt = ofmt = "dkvp"; } else if (streq(argv[argi], "--idkvp")) { popts->ifmt = "dkvp"; } else if (streq(argv[argi], "--odkvp")) { ofmt = "dkvp"; } else if (streq(argv[argi], "--csv")) { popts->ifmt = ofmt = "csv"; } else if (streq(argv[argi], "--icsv")) { popts->ifmt = "csv"; } else if (streq(argv[argi], "--ocsv")) { ofmt = "csv"; } else if (streq(argv[argi], "--nidx")) { popts->ifmt = ofmt = "nidx"; } else if (streq(argv[argi], "--inidx")) { popts->ifmt = "nidx"; } else if (streq(argv[argi], "--onidx")) { ofmt = "nidx"; } else if (streq(argv[argi], "--xtab")) { popts->ifmt = ofmt = "xtab"; } else if (streq(argv[argi], "--ixtab")) { popts->ifmt = "xtab"; } else if (streq(argv[argi], "--oxtab")) { ofmt = "xtab"; } else if (streq(argv[argi], "--ipprint")) { popts->ifmt = "csv"; popts->ifs = ' '; popts->allow_repeat_ifs = TRUE; } else if (streq(argv[argi], "--opprint")) { ofmt = "pprint"; } else if (streq(argv[argi], "--pprint")) { popts->ifmt = "csv"; popts->ifs = ' '; popts->allow_repeat_ifs = TRUE; ofmt = "pprint"; } else if (streq(argv[argi], "--right")) { left_align_pprint = FALSE; } else if (streq(argv[argi], "--ofmt")) { check_arg_count(argv, argi, argc, 2); popts->ofmt = argv[argi+1]; argi++; } // xxx put into online help. else if (streq(argv[argi], "--mmap")) { popts->use_mmap_for_read = TRUE; } else if (streq(argv[argi], "--no-mmap")) { popts->use_mmap_for_read = FALSE; } else if (streq(argv[argi], "--seed")) { check_arg_count(argv, argi, argc, 2); if (sscanf(argv[argi+1], "0x%x", &rand_seed) == 1) { have_rand_seed = TRUE; } else if (sscanf(argv[argi+1], "%u", &rand_seed) == 1) { have_rand_seed = TRUE; } else { main_usage(argv[0], 1); } argi++; } else nusage(argv[0], argv[argi]); } if (streq(ofmt, "dkvp")) popts->plrec_writer = lrec_writer_dkvp_alloc(popts->ors, popts->ofs, popts->ops); else if (streq(ofmt, "csv")) popts->plrec_writer = lrec_writer_csv_alloc(popts->ors, popts->ofs); else if (streq(ofmt, "nidx")) popts->plrec_writer = lrec_writer_nidx_alloc(popts->ors, popts->ofs); else if (streq(ofmt, "xtab")) popts->plrec_writer = lrec_writer_xtab_alloc(); else if (streq(ofmt, "pprint")) popts->plrec_writer = lrec_writer_pprint_alloc(left_align_pprint); else { main_usage(argv[0], 1); } if ((argc - argi) < 1) { main_usage(argv[0], 1); } popts->pmapper_list = sllv_alloc(); while (TRUE) { check_arg_count(argv, argi, argc, 1); char* verb = argv[argi]; mapper_setup_t* pmapper_setup = look_up_mapper_setup(verb); if (pmapper_setup == NULL) { fprintf(stderr, "%s: verb \"%s\" not found. Please use \"%s --help\" for a list.\n", argv[0], verb, argv[0]); exit(1); } if ((argc - argi) >= 2) { if (streq(argv[argi+1], "-h") || streq(argv[argi+1], "--help")) { pmapper_setup->pusage_func(argv[0], verb); exit(0); } } // It's up to the parse func to print its usage on CLI-parse failure. mapper_t* pmapper = pmapper_setup->pparse_func(&argi, argc, argv); if (pmapper == NULL) { exit(1); } sllv_add(popts->pmapper_list, pmapper); // xxx cmt if (argi >= argc || !streq(argv[argi], "then")) break; argi++; } popts->filenames = &argv[argi]; // No filenames means read from standard input, and standard input cannot be mmapped. if (argi == argc) popts->use_mmap_for_read = FALSE; popts->plrec_reader = lrec_reader_alloc(popts->ifmt, popts->use_mmap_for_read, popts->irs, popts->ifs, popts->allow_repeat_ifs, popts->ips, popts->allow_repeat_ips); if (popts->plrec_reader == NULL) main_usage(argv[0], 1); if (have_rand_seed) { mtrand_init(rand_seed); } else { mtrand_init_default(); } return popts; }
// ---------------------------------------------------------------- sllv_t* sllv_single(void* pvvalue) { sllv_t* psllv = sllv_alloc(); sllv_add(psllv, pvvalue); return psllv; }
void ap_define_char_flag(ap_state_t* pstate, char* flag_name, char* pcharval) { sllv_add(pstate->pflag_defs, ap_flag_def_alloc(flag_name, AP_CHAR_FLAG, 0, pcharval, 2)); }
void ap_define_int_flag(ap_state_t* pstate, char* flag_name, int* pintval) { sllv_add(pstate->pflag_defs, ap_flag_def_alloc(flag_name, AP_INT_FLAG, 0, pintval, 2)); }
// ---------------------------------------------------------------- static mlr_dsl_cst_statement_t* cst_statement_alloc(mlr_dsl_ast_node_t* past, int type_inferencing) { mlr_dsl_cst_statement_t* pstatement = mlr_malloc_or_die(sizeof(mlr_dsl_cst_statement_t)); pstatement->ast_node_type = past->type; pstatement->pitems = sllv_alloc(); if (past->type == MD_AST_NODE_TYPE_SREC_ASSIGNMENT) { if ((past->pchildren == NULL) || (past->pchildren->length != 2)) { fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", MLR_GLOBALS.argv0, __FILE__, __LINE__); exit(1); } mlr_dsl_ast_node_t* pleft = past->pchildren->phead->pvvalue; mlr_dsl_ast_node_t* pright = past->pchildren->phead->pnext->pvvalue; if (pleft->type != MD_AST_NODE_TYPE_FIELD_NAME) { fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", MLR_GLOBALS.argv0, __FILE__, __LINE__); exit(1); } else if (pleft->pchildren != NULL) { fprintf(stderr, "%s: coding error detected in file %s at line %d.\n", MLR_GLOBALS.argv0, __FILE__, __LINE__); exit(1); } sllv_add(pstatement->pitems, mlr_dsl_cst_statement_item_alloc( pleft->text, MLR_DSL_CST_LHS_TYPE_SREC, lrec_evaluator_alloc_from_ast(pright, type_inferencing))); } else if (past->type == MD_AST_NODE_TYPE_OOSVAR_ASSIGNMENT) { if ((past->pchildren == NULL) || (past->pchildren->length != 2)) { fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", MLR_GLOBALS.argv0, __FILE__, __LINE__); exit(1); } mlr_dsl_ast_node_t* pleft = past->pchildren->phead->pvvalue; mlr_dsl_ast_node_t* pright = past->pchildren->phead->pnext->pvvalue; if (pleft->type != MD_AST_NODE_TYPE_OOSVAR_NAME) { fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", MLR_GLOBALS.argv0, __FILE__, __LINE__); exit(1); } else if (pleft->pchildren != NULL) { fprintf(stderr, "%s: coding error detected in file %s at line %d.\n", MLR_GLOBALS.argv0, __FILE__, __LINE__); exit(1); } sllv_add(pstatement->pitems, mlr_dsl_cst_statement_item_alloc( pleft->text, MLR_DSL_CST_LHS_TYPE_OOSVAR, lrec_evaluator_alloc_from_ast(pright, type_inferencing))); } else if (past->type == MD_AST_NODE_TYPE_MOOSVAR_ASSIGNMENT) { // xxx stub: make an sllv of lrec_evaluators. } else if (past->type == MD_AST_NODE_TYPE_FILTER) { mlr_dsl_ast_node_t* pnode = past->pchildren->phead->pvvalue; sllv_add(pstatement->pitems, mlr_dsl_cst_statement_item_alloc( NULL, MLR_DSL_CST_LHS_TYPE_OOSVAR, lrec_evaluator_alloc_from_ast(pnode, type_inferencing))); } else if (past->type == MD_AST_NODE_TYPE_GATE) { mlr_dsl_ast_node_t* pnode = past->pchildren->phead->pvvalue; sllv_add(pstatement->pitems, mlr_dsl_cst_statement_item_alloc( NULL, MLR_DSL_CST_LHS_TYPE_OOSVAR, lrec_evaluator_alloc_from_ast(pnode, type_inferencing))); } else if (past->type == MD_AST_NODE_TYPE_EMIT) { // Loop over oosvar names to emit in e.g. 'emit @a, @b, @c'. for (sllve_t* pe = past->pchildren->phead; pe != NULL; pe = pe->pnext) { mlr_dsl_ast_node_t* pnode = pe->pvvalue; sllv_add(pstatement->pitems, mlr_dsl_cst_statement_item_alloc( pnode->text, MLR_DSL_CST_LHS_TYPE_OOSVAR, lrec_evaluator_alloc_from_ast(pnode, type_inferencing))); } } else if (past->type == MD_AST_NODE_TYPE_DUMP) { // xxx stub } else { // Bare-boolean statement sllv_add(pstatement->pitems, mlr_dsl_cst_statement_item_alloc( NULL, MLR_DSL_CST_LHS_TYPE_OOSVAR, // xxx wtf lrec_evaluator_alloc_from_ast(past, type_inferencing))); } return pstatement; }
// ---------------------------------------------------------------- cli_opts_t* parse_command_line(int argc, char** argv) { cli_opts_t* popts = mlr_malloc_or_die(sizeof(cli_opts_t)); memset(popts, 0, sizeof(*popts)); popts->irs = NULL; popts->ifs = NULL; popts->ips = NULL; popts->allow_repeat_ifs = NEITHER_TRUE_NOR_FALSE; popts->allow_repeat_ips = NEITHER_TRUE_NOR_FALSE; popts->ors = NULL; popts->ofs = NULL; popts->ops = NULL; popts->ofmt = DEFAULT_OFMT; popts->oquoting = DEFAULT_OQUOTING; popts->plrec_reader = NULL; popts->plrec_writer = NULL; popts->filenames = NULL; popts->ifile_fmt = "dkvp"; popts->ofile_fmt = "dkvp"; popts->use_mmap_for_read = TRUE; int left_align_pprint = TRUE; int have_rand_seed = FALSE; unsigned rand_seed = 0; int argi = 1; for (; argi < argc; argi++) { if (argv[argi][0] != '-') break; else if (streq(argv[argi], "--version")) { #ifdef HAVE_CONFIG_H printf("Miller version >= %s.\n", PACKAGE_VERSION); #else printf("Miller version >= %s.\n", MLR_VERSION); #endif // HAVE_CONFIG_H exit(0); } else if (streq(argv[argi], "-h")) main_usage(argv[0], 0); else if (streq(argv[argi], "--help")) main_usage(argv[0], 0); else if (streq(argv[argi], "--help-all-verbs")) usage_all_verbs(argv[0]); else if (streq(argv[argi], "--help-all-functions") || streq(argv[argi], "-f")) { lrec_evaluator_function_usage(stdout, NULL); exit(0); } else if (streq(argv[argi], "--help-function") || streq(argv[argi], "--hf")) { check_arg_count(argv, argi, argc, 2); lrec_evaluator_function_usage(stdout, argv[argi+1]); exit(0); } else if (streq(argv[argi], "--rs")) { check_arg_count(argv, argi, argc, 2); popts->ors = sep_from_arg(argv[argi+1], argv[0]); popts->irs = sep_from_arg(argv[argi+1], argv[0]); argi++; } else if (streq(argv[argi], "--irs")) { check_arg_count(argv, argi, argc, 2); popts->irs = sep_from_arg(argv[argi+1], argv[0]); argi++; } else if (streq(argv[argi], "--ors")) { check_arg_count(argv, argi, argc, 2); popts->ors = sep_from_arg(argv[argi+1], argv[0]); argi++; } else if (streq(argv[argi], "--fs")) { check_arg_count(argv, argi, argc, 2); popts->ofs = sep_from_arg(argv[argi+1], argv[0]); popts->ifs = sep_from_arg(argv[argi+1], argv[0]); argi++; } else if (streq(argv[argi], "--ifs")) { check_arg_count(argv, argi, argc, 2); popts->ifs = sep_from_arg(argv[argi+1], argv[0]); argi++; } else if (streq(argv[argi], "--ofs")) { check_arg_count(argv, argi, argc, 2); popts->ofs = sep_from_arg(argv[argi+1], argv[0]); argi++; } else if (streq(argv[argi], "--repifs")) { popts->allow_repeat_ifs = TRUE; } else if (streq(argv[argi], "-p")) { popts->ifile_fmt = "nidx"; popts->ofile_fmt = "nidx"; popts->ifs = " "; popts->ofs = " "; popts->allow_repeat_ifs = TRUE; } else if (streq(argv[argi], "--ps")) { check_arg_count(argv, argi, argc, 2); popts->ops = sep_from_arg(argv[argi+1], argv[0]); popts->ips = sep_from_arg(argv[argi+1], argv[0]); argi++; } else if (streq(argv[argi], "--ips")) { check_arg_count(argv, argi, argc, 2); popts->ips = sep_from_arg(argv[argi+1], argv[0]); argi++; } else if (streq(argv[argi], "--ops")) { check_arg_count(argv, argi, argc, 2); popts->ops = sep_from_arg(argv[argi+1], argv[0]); argi++; } else if (streq(argv[argi], "--csv")) { popts->ifile_fmt = popts->ofile_fmt = "csv"; } else if (streq(argv[argi], "--icsv")) { popts->ifile_fmt = "csv"; } else if (streq(argv[argi], "--ocsv")) { popts->ofile_fmt = "csv"; } else if (streq(argv[argi], "--csvlite")) { popts->ifile_fmt = popts->ofile_fmt = "csvlite"; } else if (streq(argv[argi], "--icsvlite")) { popts->ifile_fmt = "csvlite"; } else if (streq(argv[argi], "--ocsvlite")) { popts->ofile_fmt = "csvlite"; } else if (streq(argv[argi], "--dkvp")) { popts->ifile_fmt = popts->ofile_fmt = "dkvp"; } else if (streq(argv[argi], "--idkvp")) { popts->ifile_fmt = "dkvp"; } else if (streq(argv[argi], "--odkvp")) { popts->ofile_fmt = "dkvp"; } else if (streq(argv[argi], "--nidx")) { popts->ifile_fmt = popts->ofile_fmt = "nidx"; } else if (streq(argv[argi], "--inidx")) { popts->ifile_fmt = "nidx"; } else if (streq(argv[argi], "--onidx")) { popts->ofile_fmt = "nidx"; } else if (streq(argv[argi], "--xtab")) { popts->ifile_fmt = popts->ofile_fmt = "xtab"; } else if (streq(argv[argi], "--ixtab")) { popts->ifile_fmt = "xtab"; } else if (streq(argv[argi], "--oxtab")) { popts->ofile_fmt = "xtab"; } else if (streq(argv[argi], "--ipprint")) { popts->ifile_fmt = "csvlite"; popts->ifs = " "; popts->allow_repeat_ifs = TRUE; } else if (streq(argv[argi], "--opprint")) { popts->ofile_fmt = "pprint"; } else if (streq(argv[argi], "--pprint")) { popts->ifile_fmt = "csvlite"; popts->ifs = " "; popts->allow_repeat_ifs = TRUE; popts->ofile_fmt = "pprint"; } else if (streq(argv[argi], "--right")) { left_align_pprint = FALSE; } else if (streq(argv[argi], "--ofmt")) { check_arg_count(argv, argi, argc, 2); popts->ofile_fmt = argv[argi+1]; argi++; } else if (streq(argv[argi], "--quote-all")) { popts->oquoting = QUOTE_ALL; } else if (streq(argv[argi], "--quote-none")) { popts->oquoting = QUOTE_NONE; } else if (streq(argv[argi], "--quote-minimal")) { popts->oquoting = QUOTE_MINIMAL; } else if (streq(argv[argi], "--quote-numeric")) { popts->oquoting = QUOTE_NUMERIC; } // xxx put into online help. else if (streq(argv[argi], "--mmap")) { popts->use_mmap_for_read = TRUE; } else if (streq(argv[argi], "--no-mmap")) { popts->use_mmap_for_read = FALSE; } else if (streq(argv[argi], "--seed")) { check_arg_count(argv, argi, argc, 2); if (sscanf(argv[argi+1], "0x%x", &rand_seed) == 1) { have_rand_seed = TRUE; } else if (sscanf(argv[argi+1], "%u", &rand_seed) == 1) { have_rand_seed = TRUE; } else { main_usage(argv[0], 1); } argi++; } else nusage(argv[0], argv[argi]); } lhmss_t* default_rses = get_default_rses(); lhmss_t* default_fses = get_default_fses(); lhmss_t* default_pses = get_default_pses(); lhmsi_t* default_repeat_ifses = get_default_repeat_ifses(); lhmsi_t* default_repeat_ipses = get_default_repeat_ipses(); if (popts->irs == NULL) popts->irs = lhmss_get(default_rses, popts->ifile_fmt); if (popts->ifs == NULL) popts->ifs = lhmss_get(default_fses, popts->ifile_fmt); if (popts->ips == NULL) popts->ips = lhmss_get(default_pses, popts->ifile_fmt); if (popts->allow_repeat_ifs == NEITHER_TRUE_NOR_FALSE) popts->allow_repeat_ifs = lhmsi_get(default_repeat_ifses, popts->ifile_fmt); if (popts->allow_repeat_ips == NEITHER_TRUE_NOR_FALSE) popts->allow_repeat_ips = lhmsi_get(default_repeat_ipses, popts->ifile_fmt); if (popts->ors == NULL) popts->ors = lhmss_get(default_rses, popts->ofile_fmt); if (popts->ofs == NULL) popts->ofs = lhmss_get(default_fses, popts->ofile_fmt); if (popts->ops == NULL) popts->ops = lhmss_get(default_pses, popts->ofile_fmt); if (popts->irs == NULL) { fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", argv[0], __FILE__, __LINE__); exit(1); } if (popts->ifs == NULL) { fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", argv[0], __FILE__, __LINE__); exit(1); } if (popts->ips == NULL) { fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", argv[0], __FILE__, __LINE__); exit(1); } if (popts->allow_repeat_ifs == NEITHER_TRUE_NOR_FALSE) { fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", argv[0], __FILE__, __LINE__); exit(1); } if (popts->allow_repeat_ips == NEITHER_TRUE_NOR_FALSE) { fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", argv[0], __FILE__, __LINE__); exit(1); } if (popts->ors == NULL) { fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", argv[0], __FILE__, __LINE__); exit(1); } if (popts->ofs == NULL) { fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", argv[0], __FILE__, __LINE__); exit(1); } if (popts->ops == NULL) { fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", argv[0], __FILE__, __LINE__); exit(1); } if (streq(popts->ofile_fmt, "pprint") && strlen(popts->ofs) != 1) { fprintf(stderr, "%s: OFS for PPRINT format must be single-character; got \"%s\".\n", argv[0], popts->ofs); return NULL; } if (streq(popts->ofile_fmt, "dkvp")) popts->plrec_writer = lrec_writer_dkvp_alloc(popts->ors, popts->ofs, popts->ops); else if (streq(popts->ofile_fmt, "csv")) popts->plrec_writer = lrec_writer_csv_alloc(popts->ors, popts->ofs, popts->oquoting); else if (streq(popts->ofile_fmt, "csvlite")) popts->plrec_writer = lrec_writer_csvlite_alloc(popts->ors, popts->ofs); else if (streq(popts->ofile_fmt, "nidx")) popts->plrec_writer = lrec_writer_nidx_alloc(popts->ors, popts->ofs); else if (streq(popts->ofile_fmt, "xtab")) popts->plrec_writer = lrec_writer_xtab_alloc(popts->ofs, popts->ops); else if (streq(popts->ofile_fmt, "pprint")) popts->plrec_writer = lrec_writer_pprint_alloc(popts->ors, popts->ofs[0], left_align_pprint); else { main_usage(argv[0], 1); } if ((argc - argi) < 1) { main_usage(argv[0], 1); } popts->pmapper_list = sllv_alloc(); while (TRUE) { check_arg_count(argv, argi, argc, 1); char* verb = argv[argi]; mapper_setup_t* pmapper_setup = look_up_mapper_setup(verb); if (pmapper_setup == NULL) { fprintf(stderr, "%s: verb \"%s\" not found. Please use \"%s --help\" for a list.\n", argv[0], verb, argv[0]); exit(1); } if ((argc - argi) >= 2) { if (streq(argv[argi+1], "-h") || streq(argv[argi+1], "--help")) { pmapper_setup->pusage_func(argv[0], verb); exit(0); } } // It's up to the parse func to print its usage on CLI-parse failure. mapper_t* pmapper = pmapper_setup->pparse_func(&argi, argc, argv); if (pmapper == NULL) { exit(1); } sllv_add(popts->pmapper_list, pmapper); // xxx cmt if (argi >= argc || !streq(argv[argi], "then")) break; argi++; } popts->filenames = &argv[argi]; // No filenames means read from standard input, and standard input cannot be mmapped. if (argi == argc) popts->use_mmap_for_read = FALSE; popts->plrec_reader = lrec_reader_alloc(popts->ifile_fmt, popts->use_mmap_for_read, popts->irs, popts->ifs, popts->allow_repeat_ifs, popts->ips, popts->allow_repeat_ips); if (popts->plrec_reader == NULL) main_usage(argv[0], 1); if (have_rand_seed) { mtrand_init(rand_seed); } else { mtrand_init_default(); } return popts; }