Exemplo n.º 1
0
// ----------------------------------------------------------------
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;
    }
}
Exemplo n.º 2
0
// ----------------------------------------------------------------
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;
	}
}
Exemplo n.º 3
0
// ----------------------------------------------------------------
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;
}
Exemplo n.º 4
0
// ----------------------------------------------------------------
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);
	}
}
Exemplo n.º 5
0
// ----------------------------------------------------------------
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;
}
Exemplo n.º 6
0
// ----------------------------------------------------------------
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;
}
Exemplo n.º 7
0
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;
}
Exemplo n.º 8
0
// ----------------------------------------------------------------
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;
}
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
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));
}
Exemplo n.º 11
0
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));
}
Exemplo n.º 12
0
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));
}
Exemplo n.º 13
0
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));
}
Exemplo n.º 14
0
// ----------------------------------------------------------------
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;
}
Exemplo n.º 15
0
// ----------------------------------------------------------------
sllv_t* sllv_single(void* pvvalue) {
	sllv_t* psllv = sllv_alloc();
	sllv_add(psllv, pvvalue);
	return psllv;
}
Exemplo n.º 16
0
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));
}
Exemplo n.º 17
0
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));
}
Exemplo n.º 18
0
// ----------------------------------------------------------------
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;
}
Exemplo n.º 19
0
// ----------------------------------------------------------------
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;
}