Exemple #1
0
// ----------------------------------------------------------------
// xxx check for semantics comparable to mt_get_boolean_strict
void mt_get_double_strict(mv_t* pval) {
	if (pval->type == MT_NULL)
		return;
	if (pval->type == MT_ERROR)
		return;
	if (pval->type == MT_DOUBLE)
		return;
	if (pval->type == MT_STRING) {
		double dblv;
		if (!mlr_try_double_from_string(pval->u.strv, &dblv)) {
			pval->type = MT_ERROR;
			pval->u.intv = 0;
		} else {
			pval->type = MT_DOUBLE;
			pval->u.dblv = dblv;
		}
	} else if (pval->type == MT_INT) {
		pval ->type = MT_DOUBLE;
		pval->u.dblv = (double)pval->u.intv;
	} else if (pval->type == MT_BOOL) {
		pval->type = MT_ERROR;
		pval->u.intv = 0;
	}
	// xxx else panic
}
Exemple #2
0
double mlr_double_from_string_or_die(char* string) {
	double d;
	if (!mlr_try_double_from_string(string, &d)) {
		fprintf(stderr, "Couldn't parse \"%s\" as number.\n", string);
		exit(1);
	}
	return d;
}
Exemple #3
0
// ----------------------------------------------------------------
static int is_percentile_acc_name(char* acc_name) {
	double percentile;
	// sscanf(acc_name, "p%lf", &percentile) allows "p74x" et al. which isn't ok.
	if (acc_name[0] != 'p')
		return FALSE;
	if (!mlr_try_double_from_string(&acc_name[1], &percentile))
		return FALSE;
	if (percentile < 0.0 || percentile > 100.0) {
		fprintf(stderr, "%s stats1: percentile \"%s\" outside range [0,100].\n",
			MLR_GLOBALS.argv0, acc_name);
		exit(1);
	}
	return TRUE;
}
Exemple #4
0
// ----------------------------------------------------------------
mv_t s_ss_dot_func(mv_t* pval1, mv_t* pval2) {
	int len1 = strlen(pval1->u.strv);
	int len2 = strlen(pval1->u.strv);
	int len3 = len1 + len2 + 1; // for the null-terminator byte
	char* string3 = mlr_malloc_or_die(len3);
	strcpy(&string3[0], pval1->u.strv);
	strcpy(&string3[len1], pval2->u.strv);

	// xxx encapsulate this:
	free(pval1->u.strv);
	free(pval2->u.strv);
	pval1->u.strv = NULL;
	pval2->u.strv = NULL;

	mv_t rv = {.type = MT_STRING, .u.strv = string3};
	return rv;
}

// ----------------------------------------------------------------
mv_t s_sss_sub_func(mv_t* pval1, mv_t* pval2, mv_t* pval3) {
	char* substr = strstr(pval1->u.strv, pval2->u.strv);
	if (substr == NULL) {
		return *pval1;
	} else {
		int  len1 = substr - pval1->u.strv;
		int olen2 = strlen(pval2->u.strv);
		int nlen2 = strlen(pval3->u.strv);
		int  len3 = strlen(&pval1->u.strv[len1 + olen2]);
		int  len4 = len1 + nlen2 + len3;

		char* string4 = mlr_malloc_or_die(len4);
		strncpy(&string4[0],    pval1->u.strv, len1);
		strncpy(&string4[len1], pval3->u.strv, nlen2);
		strncpy(&string4[len1+nlen2], &pval1->u.strv[len1+olen2], len3);

		free(pval1->u.strv);
		free(pval2->u.strv);
		free(pval3->u.strv);
		pval1->u.strv = NULL;
		pval2->u.strv = NULL;
		pval3->u.strv = NULL;

		mv_t rv = {.type = MT_STRING, .u.strv = string4};
		return rv;
	}
}

// ----------------------------------------------------------------
// xxx cmt mem-mgt & contract. similar to lrec-mapper contract.
mv_t s_s_tolower_func(mv_t* pval1) {
	char* string = strdup(pval1->u.strv);
	for (char* c = string; *c; c++)
		*c = tolower(*c);
	// xxx encapsulate this:
	free(pval1->u.strv);
	pval1->u.strv = NULL;

	mv_t rv = {.type = MT_STRING, .u.strv = string};
	return rv;
}

// xxx cmt mem-mgt & contract. similar to lrec-mapper contract.
mv_t s_s_toupper_func(mv_t* pval1) {
	char* string = strdup(pval1->u.strv);
	for (char* c = string; *c; c++)
		*c = toupper(*c);
	// xxx encapsulate this:
	free(pval1->u.strv);
	pval1->u.strv = NULL;

	mv_t rv = {.type = MT_STRING, .u.strv = string};
	return rv;
}

// ----------------------------------------------------------------
mv_t s_f_sec2gmt_func(mv_t* pval1) {
	ERROR_OUT(*pval1);
	mt_get_double_nullable(pval1);
	NULL_OUT(*pval1);
	if (pval1->type != MT_DOUBLE)
		return MV_ERROR;
	time_t clock = (time_t) pval1->u.dblv;
	struct tm tm;
	struct tm *ptm = gmtime_r(&clock, &tm);
	// xxx use retval which is size_t
	// xxx error-check all of this ...
	char* string = mlr_malloc_or_die(32);
	(void)strftime(string, 32, "%Y-%m-%dT%H:%M:%SZ", ptm);

	mv_t rv = {.type = MT_STRING, .u.strv = string};
	return rv;
}

mv_t i_s_gmt2sec_func(mv_t* pval1) {
	struct tm tm;
	if (*pval1->u.strv == '\0') {
		return MV_NULL;
	} else {
		strptime(pval1->u.strv, "%Y-%m-%dT%H:%M:%SZ", &tm);
		time_t t = timegm(&tm);

		mv_t rv = {.type = MT_INT, .u.intv = (long long)t};
		return rv;
	}
}

// ----------------------------------------------------------------
mv_t i_s_strlen_func(mv_t* pval1) {
	mv_t rv = {.type = MT_INT, .u.intv = strlen(pval1->u.strv)};
	return rv;
}

// ----------------------------------------------------------------
static mv_t int_i_n(mv_t* pa) { return (mv_t) {.type = MT_NULL,  .u.intv = 0}; }
static mv_t int_i_e(mv_t* pa) { return (mv_t) {.type = MT_ERROR, .u.intv = 0}; }
static mv_t int_i_b(mv_t* pa) { return (mv_t) {.type = MT_INT,   .u.intv = pa->u.boolv ? 1 : 0}; }
static mv_t int_i_d(mv_t* pa) { return (mv_t) {.type = MT_INT,   .u.intv = (long long)round(pa->u.dblv)}; }
static mv_t int_i_i(mv_t* pa) { return (mv_t) {.type = MT_INT,   .u.intv = pa->u.intv}; }
static mv_t int_i_s(mv_t* pa) {
	mv_t retval = (mv_t) {.type = MT_INT };
	if (*pa->u.strv == '\0')
		return MV_NULL;
	if (!mlr_try_int_from_string(pa->u.strv, &retval.u.intv))
		retval.type = MT_ERROR;
	return retval;
}

static mv_unary_func_t* int_dispositions[MT_MAX] = {
    /*NULL*/   int_i_n,
    /*ERROR*/  int_i_e,
    /*BOOL*/   int_i_b,
    /*DOUBLE*/ int_i_d,
    /*INT*/    int_i_i,
    /*STRING*/ int_i_s,
};

mv_t i_x_int_func(mv_t* pval1) { return (int_dispositions[pval1->type])(pval1); }

// ----------------------------------------------------------------
// xxx i'm using double & long long but saying double & int. this is confusing & needs fixing.
static mv_t float_f_n(mv_t* pa) { return (mv_t) {.type = MT_NULL,   .u.intv = 0}; }
static mv_t float_f_e(mv_t* pa) { return (mv_t) {.type = MT_ERROR,  .u.intv = 0}; }
static mv_t float_f_b(mv_t* pa) { return (mv_t) {.type = MT_DOUBLE, .u.dblv = pa->u.boolv ? 1.0 : 0.0}; }
static mv_t float_f_d(mv_t* pa) { return (mv_t) {.type = MT_DOUBLE, .u.dblv = pa->u.dblv}; }
static mv_t float_f_i(mv_t* pa) { return (mv_t) {.type = MT_DOUBLE, .u.dblv = pa->u.intv}; }
static mv_t float_f_s(mv_t* pa) {
	mv_t retval = (mv_t) {.type = MT_DOUBLE };
	if (*pa->u.strv == '\0')
		return MV_NULL;
	if (!mlr_try_double_from_string(pa->u.strv, &retval.u.dblv))
		retval.type = MT_ERROR;
	return retval;
}

static mv_unary_func_t* float_dispositions[MT_MAX] = {
    /*NULL*/   float_f_n,
    /*ERROR*/  float_f_e,
    /*BOOL*/   float_f_b,
    /*DOUBLE*/ float_f_d,
    /*INT*/    float_f_i,
    /*STRING*/ float_f_s,
};

mv_t f_x_float_func(mv_t* pval1) { return (float_dispositions[pval1->type])(pval1); }

// ----------------------------------------------------------------
static mv_t boolean_b_n(mv_t* pa) { return (mv_t) {.type = MT_NULL,  .u.intv = 0}; }
static mv_t boolean_b_e(mv_t* pa) { return (mv_t) {.type = MT_ERROR, .u.intv = 0}; }
static mv_t boolean_b_b(mv_t* pa) { return (mv_t) {.type = MT_BOOL,  .u.boolv = pa->u.boolv}; }
static mv_t boolean_b_d(mv_t* pa) { return (mv_t) {.type = MT_BOOL,  .u.boolv = (pa->u.dblv == 0.0) ? FALSE : TRUE}; }
static mv_t boolean_b_i(mv_t* pa) { return (mv_t) {.type = MT_BOOL,  .u.boolv = (pa->u.intv == 0LL) ? FALSE : TRUE}; }
static mv_t boolean_b_s(mv_t* pa) { return (mv_t) {.type = MT_BOOL,
		.u.boolv = (streq(pa->u.strv, "true") || streq(pa->u.strv, "TRUE")) ? TRUE : FALSE
	};
}

static mv_unary_func_t* boolean_dispositions[MT_MAX] = {
    /*NULL*/   boolean_b_n,
    /*ERROR*/  boolean_b_e,
    /*BOOL*/   boolean_b_b,
    /*DOUBLE*/ boolean_b_d,
    /*INT*/    boolean_b_i,
    /*STRING*/ boolean_b_s,
};

mv_t b_x_boolean_func(mv_t* pval1) { return (boolean_dispositions[pval1->type])(pval1); }

// ----------------------------------------------------------------
static mv_t string_s_n(mv_t* pa) { return (mv_t) {.type = MT_NULL,   .u.intv = 0}; }
static mv_t string_s_e(mv_t* pa) { return (mv_t) {.type = MT_ERROR,  .u.intv = 0}; }
static mv_t string_s_b(mv_t* pa) { return (mv_t) {.type = MT_STRING, .u.strv = strdup(pa->u.boolv?"true":"false")}; }
static mv_t string_s_d(mv_t* pa) {
	return (mv_t) {.type = MT_STRING, .u.strv = mlr_alloc_string_from_double(pa->u.dblv, MLR_GLOBALS.ofmt)};
}
static mv_t string_s_i(mv_t* pa) { return (mv_t) {.type = MT_STRING, .u.strv = mlr_alloc_string_from_ll(pa->u.intv)}; }
static mv_t string_s_s(mv_t* pa) { return (mv_t) {.type = MT_STRING, .u.strv = pa->u.strv}; }

static mv_unary_func_t* string_dispositions[MT_MAX] = {
    /*NULL*/   string_s_n,
    /*ERROR*/  string_s_e,
    /*BOOL*/   string_s_b,
    /*DOUBLE*/ string_s_d,
    /*INT*/    string_s_i,
    /*STRING*/ string_s_s,
};

mv_t s_x_string_func(mv_t* pval1) { return (string_dispositions[pval1->type])(pval1); }

// ----------------------------------------------------------------
static mv_t hexfmt_s_n(mv_t* pa) { return (mv_t) {.type = MT_NULL,   .u.intv = 0}; }
static mv_t hexfmt_s_e(mv_t* pa) { return (mv_t) {.type = MT_ERROR,  .u.intv = 0}; }
static mv_t hexfmt_s_b(mv_t* pa) { return (mv_t) {.type = MT_STRING, .u.strv = strdup(pa->u.boolv?"0x1":"0x0")}; }
static mv_t hexfmt_s_d(mv_t* pa) {
	return (mv_t) {.type = MT_STRING, .u.strv = mlr_alloc_hexfmt_from_ll((long long)pa->u.dblv)};
}
static mv_t hexfmt_s_i(mv_t* pa) { return (mv_t) {.type = MT_STRING, .u.strv = mlr_alloc_hexfmt_from_ll(pa->u.intv)}; }
static mv_t hexfmt_s_s(mv_t* pa) { return (mv_t) {.type = MT_STRING, .u.strv = pa->u.strv}; }

static mv_unary_func_t* hexfmt_dispositions[MT_MAX] = {
    /*NULL*/   hexfmt_s_n,
    /*ERROR*/  hexfmt_s_e,
    /*BOOL*/   hexfmt_s_b,
    /*DOUBLE*/ hexfmt_s_d,
    /*INT*/    hexfmt_s_i,
    /*STRING*/ hexfmt_s_s,
};

mv_t s_x_hexfmt_func(mv_t* pval1) { return (hexfmt_dispositions[pval1->type])(pval1); }

// ----------------------------------------------------------------
static mv_t fmtnum_s_ns(mv_t* pa, mv_t* pfmt) { return (mv_t) {.type = MT_NULL,   .u.intv = 0}; }
static mv_t fmtnum_s_es(mv_t* pa, mv_t* pfmt) { return (mv_t) {.type = MT_ERROR,  .u.intv = 0}; }
static mv_t fmtnum_s_bs(mv_t* pa, mv_t* pfmt) { return (mv_t) {.type = MT_STRING, .u.strv = strdup(pa->u.boolv?"0x1":"0x0")}; }
static mv_t fmtnum_s_ds(mv_t* pa, mv_t* pfmt) {
	return (mv_t) {.type = MT_STRING, .u.strv = mlr_alloc_string_from_double(pa->u.dblv, pfmt->u.strv)};
}
static mv_t fmtnum_s_is(mv_t* pa, mv_t* pfmt) {
	return (mv_t) {.type = MT_STRING, .u.strv = mlr_alloc_string_from_ll_and_format(pa->u.intv, pfmt->u.strv)};
}
static mv_t fmtnum_s_ss(mv_t* pa, mv_t* pfmt) { return (mv_t) {.type = MT_ERROR, .u.intv = 0}; }

static mv_binary_func_t* fmtnum_dispositions[MT_MAX] = {
    /*NULL*/   fmtnum_s_ns,
    /*ERROR*/  fmtnum_s_es,
    /*BOOL*/   fmtnum_s_bs,
    /*DOUBLE*/ fmtnum_s_ds,
    /*INT*/    fmtnum_s_is,
    /*STRING*/ fmtnum_s_ss,
};

mv_t s_xs_fmtnum_func(mv_t* pval1, mv_t* pval2) { return (fmtnum_dispositions[pval1->type])(pval1, pval2); }

// ----------------------------------------------------------------
// xxx cmt us!!!!

static mv_t op_n_xx(mv_t* pa, mv_t* pb) { return (mv_t) {.type = MT_NULL, .u.intv = 0}; }
static mv_t op_e_xx(mv_t* pa, mv_t* pb) { return (mv_t) {.type = MT_ERROR, .u.intv = 0}; }

static  mv_t eq_b_ii(mv_t* pa, mv_t* pb) { return (mv_t) {.type = MT_BOOL, .u.boolv = pa->u.intv == pb->u.intv}; }
static  mv_t ne_b_ii(mv_t* pa, mv_t* pb) { return (mv_t) {.type = MT_BOOL, .u.boolv = pa->u.intv != pb->u.intv}; }
static  mv_t gt_b_ii(mv_t* pa, mv_t* pb) { return (mv_t) {.type = MT_BOOL, .u.boolv = pa->u.intv >  pb->u.intv}; }
static  mv_t ge_b_ii(mv_t* pa, mv_t* pb) { return (mv_t) {.type = MT_BOOL, .u.boolv = pa->u.intv >= pb->u.intv}; }
static  mv_t lt_b_ii(mv_t* pa, mv_t* pb) { return (mv_t) {.type = MT_BOOL, .u.boolv = pa->u.intv <  pb->u.intv}; }
static  mv_t le_b_ii(mv_t* pa, mv_t* pb) { return (mv_t) {.type = MT_BOOL, .u.boolv = pa->u.intv <= pb->u.intv}; }

static  mv_t eq_b_ff(mv_t* pa, mv_t* pb) { return (mv_t) {.type = MT_BOOL, .u.boolv = pa->u.dblv == pb->u.dblv}; }
static  mv_t ne_b_ff(mv_t* pa, mv_t* pb) { return (mv_t) {.type = MT_BOOL, .u.boolv = pa->u.dblv != pb->u.dblv}; }
static  mv_t gt_b_ff(mv_t* pa, mv_t* pb) { return (mv_t) {.type = MT_BOOL, .u.boolv = pa->u.dblv >  pb->u.dblv}; }
static  mv_t ge_b_ff(mv_t* pa, mv_t* pb) { return (mv_t) {.type = MT_BOOL, .u.boolv = pa->u.dblv >= pb->u.dblv}; }
static  mv_t lt_b_ff(mv_t* pa, mv_t* pb) { return (mv_t) {.type = MT_BOOL, .u.boolv = pa->u.dblv <  pb->u.dblv}; }
static  mv_t le_b_ff(mv_t* pa, mv_t* pb) { return (mv_t) {.type = MT_BOOL, .u.boolv = pa->u.dblv <= pb->u.dblv}; }

static  mv_t eq_b_fi(mv_t* pa, mv_t* pb) { return (mv_t) {.type = MT_BOOL, .u.boolv = pa->u.dblv == pb->u.intv}; }
static  mv_t ne_b_fi(mv_t* pa, mv_t* pb) { return (mv_t) {.type = MT_BOOL, .u.boolv = pa->u.dblv != pb->u.intv}; }
static  mv_t gt_b_fi(mv_t* pa, mv_t* pb) { return (mv_t) {.type = MT_BOOL, .u.boolv = pa->u.dblv >  pb->u.intv}; }
static  mv_t ge_b_fi(mv_t* pa, mv_t* pb) { return (mv_t) {.type = MT_BOOL, .u.boolv = pa->u.dblv >= pb->u.intv}; }
static  mv_t lt_b_fi(mv_t* pa, mv_t* pb) { return (mv_t) {.type = MT_BOOL, .u.boolv = pa->u.dblv <  pb->u.intv}; }
static  mv_t le_b_fi(mv_t* pa, mv_t* pb) { return (mv_t) {.type = MT_BOOL, .u.boolv = pa->u.dblv <= pb->u.intv}; }

static  mv_t eq_b_if(mv_t* pa, mv_t* pb) { return (mv_t) {.type = MT_BOOL, .u.boolv = pa->u.intv == pb->u.dblv}; }
static  mv_t ne_b_if(mv_t* pa, mv_t* pb) { return (mv_t) {.type = MT_BOOL, .u.boolv = pa->u.intv != pb->u.dblv}; }
static  mv_t gt_b_if(mv_t* pa, mv_t* pb) { return (mv_t) {.type = MT_BOOL, .u.boolv = pa->u.intv >  pb->u.dblv}; }
static  mv_t ge_b_if(mv_t* pa, mv_t* pb) { return (mv_t) {.type = MT_BOOL, .u.boolv = pa->u.intv >= pb->u.dblv}; }
static  mv_t lt_b_if(mv_t* pa, mv_t* pb) { return (mv_t) {.type = MT_BOOL, .u.boolv = pa->u.intv <  pb->u.dblv}; }
static  mv_t le_b_if(mv_t* pa, mv_t* pb) { return (mv_t) {.type = MT_BOOL, .u.boolv = pa->u.intv <= pb->u.dblv}; }

static  mv_t eq_b_xs(mv_t* pa, mv_t* pb) {
	char* a = mt_format_val(pa);
	mv_t rv = {.type = MT_BOOL, .u.boolv = strcmp(a, pb->u.strv) == 0};
	free(a);
	return rv;
}
static  mv_t ne_b_xs(mv_t* pa, mv_t* pb) {
	char* a = mt_format_val(pa);
	mv_t rv = {.type = MT_BOOL, .u.boolv = strcmp(a, pb->u.strv) != 0};
	free(a);
	return rv;
}
static  mv_t gt_b_xs(mv_t* pa, mv_t* pb) {
	char* a = mt_format_val(pa);
	mv_t rv = {.type = MT_BOOL, .u.boolv = strcmp(a, pb->u.strv) >  0};
	free(a);
	return rv;
}
static  mv_t ge_b_xs(mv_t* pa, mv_t* pb) {
	char* a = mt_format_val(pa);
	mv_t rv = {.type = MT_BOOL, .u.boolv = strcmp(a, pb->u.strv) >= 0};
	free(a);
	return rv;
}
static  mv_t lt_b_xs(mv_t* pa, mv_t* pb) {
	char* a = mt_format_val(pa);
	mv_t rv = {.type = MT_BOOL, .u.boolv = strcmp(a, pb->u.strv) <  0};
	free(a);
	return rv;
}
static  mv_t le_b_xs(mv_t* pa, mv_t* pb) {
	char* a = mt_format_val(pa);
	mv_t rv = {.type = MT_BOOL, .u.boolv = strcmp(a, pb->u.strv) <= 0};
	free(a);
	return rv;
}

static  mv_t eq_b_sx(mv_t* pa, mv_t* pb) {
	char* b = mt_format_val(pb);
	mv_t rv = {.type = MT_BOOL, .u.boolv = strcmp(pa->u.strv, b) == 0};
	free(b);
	return rv;
}
static  mv_t ne_b_sx(mv_t* pa, mv_t* pb) {
	char* b = mt_format_val(pb);
	mv_t rv = {.type = MT_BOOL, .u.boolv = strcmp(pa->u.strv, b) != 0};
	free(b);
	return rv;
}
static  mv_t gt_b_sx(mv_t* pa, mv_t* pb) {
	char* b = mt_format_val(pb);
	mv_t rv = {.type = MT_BOOL, .u.boolv = strcmp(pa->u.strv, b) >  0};
	free(b);
	return rv;
}
static  mv_t ge_b_sx(mv_t* pa, mv_t* pb) {
	char* b = mt_format_val(pb);
	mv_t rv = {.type = MT_BOOL, .u.boolv = strcmp(pa->u.strv, b) >= 0};
	free(b);
	return rv;
}
static  mv_t lt_b_sx(mv_t* pa, mv_t* pb) {
	char* b = mt_format_val(pb);
	mv_t rv = {.type = MT_BOOL, .u.boolv = strcmp(pa->u.strv, b) <  0};
	free(b);
	return rv;
}
static  mv_t le_b_sx(mv_t* pa, mv_t* pb) {
	char* b = mt_format_val(pb);
	mv_t rv = {.type = MT_BOOL, .u.boolv = strcmp(pa->u.strv, b) <= 0};
	free(b);
	return rv;
}

static mv_t eq_b_ss(mv_t*pa, mv_t*pb) {return (mv_t){.type=MT_BOOL, .u.boolv=strcmp(pa->u.strv, pb->u.strv) == 0};}
static mv_t ne_b_ss(mv_t*pa, mv_t*pb) {return (mv_t){.type=MT_BOOL, .u.boolv=strcmp(pa->u.strv, pb->u.strv) != 0};}
static mv_t gt_b_ss(mv_t*pa, mv_t*pb) {return (mv_t){.type=MT_BOOL, .u.boolv=strcmp(pa->u.strv, pb->u.strv) >  0};}
static mv_t ge_b_ss(mv_t*pa, mv_t*pb) {return (mv_t){.type=MT_BOOL, .u.boolv=strcmp(pa->u.strv, pb->u.strv) >= 0};}
static mv_t lt_b_ss(mv_t*pa, mv_t*pb) {return (mv_t){.type=MT_BOOL, .u.boolv=strcmp(pa->u.strv, pb->u.strv) <  0};}
static mv_t le_b_ss(mv_t*pa, mv_t*pb) {return (mv_t){.type=MT_BOOL, .u.boolv=strcmp(pa->u.strv, pb->u.strv) <= 0};}

static mv_binary_func_t* eq_dispositions[MT_MAX][MT_MAX] = {
    //         NULL      ERROR    BOOL     DOUBLE   INT      STRING
    /*NULL*/   {op_n_xx, op_e_xx, op_e_xx, op_n_xx, op_n_xx, op_n_xx},
    /*ERROR*/  {op_e_xx, op_e_xx, op_e_xx, op_e_xx, op_e_xx, op_e_xx},
    /*BOOL*/   {op_e_xx, op_e_xx, op_e_xx, op_e_xx, op_e_xx, op_e_xx},
    /*DOUBLE*/ {op_n_xx, op_e_xx, op_e_xx, eq_b_ff, eq_b_fi, eq_b_xs},
    /*INT*/    {op_n_xx, op_e_xx, op_e_xx, eq_b_if, eq_b_ii, eq_b_xs},
    /*STRING*/ {op_n_xx, op_e_xx, op_e_xx, eq_b_sx, eq_b_sx, eq_b_ss},
};

static mv_binary_func_t* ne_dispositions[MT_MAX][MT_MAX] = {
    //         NULL      ERROR    BOOL     DOUBLE   INT      STRING
    /*NULL*/   {op_n_xx, op_e_xx, op_e_xx, op_n_xx, op_n_xx, op_n_xx},
    /*ERROR*/  {op_e_xx, op_e_xx, op_e_xx, op_e_xx, op_e_xx, op_e_xx},
    /*BOOL*/   {op_e_xx, op_e_xx, op_e_xx, op_e_xx, op_e_xx, op_e_xx},
    /*DOUBLE*/ {op_n_xx, op_e_xx, op_e_xx, ne_b_ff, ne_b_fi, ne_b_xs},
    /*INT*/    {op_n_xx, op_e_xx, op_e_xx, ne_b_if, ne_b_ii, ne_b_xs},
    /*STRING*/ {op_n_xx, op_e_xx, op_e_xx, ne_b_sx, ne_b_sx, ne_b_ss},
};

static mv_binary_func_t* gt_dispositions[MT_MAX][MT_MAX] = {
    //         NULL      ERROR    BOOL     DOUBLE   INT      STRING
    /*NULL*/   {op_n_xx, op_e_xx, op_e_xx, op_n_xx, op_n_xx, op_n_xx},
    /*ERROR*/  {op_e_xx, op_e_xx, op_e_xx, op_e_xx, op_e_xx, op_e_xx},
    /*BOOL*/   {op_e_xx, op_e_xx, op_e_xx, op_e_xx, op_e_xx, op_e_xx},
    /*DOUBLE*/ {op_n_xx, op_e_xx, op_e_xx, gt_b_ff, gt_b_fi, gt_b_xs},
    /*INT*/    {op_n_xx, op_e_xx, op_e_xx, gt_b_if, gt_b_ii, gt_b_xs},
    /*STRING*/ {op_n_xx, op_e_xx, op_e_xx, gt_b_sx, gt_b_sx, gt_b_ss},
};

static mv_binary_func_t* ge_dispositions[MT_MAX][MT_MAX] = {
    //         NULL      ERROR    BOOL     DOUBLE   INT      STRING
    /*NULL*/   {op_n_xx, op_e_xx, op_e_xx, op_n_xx, op_n_xx, op_n_xx},
    /*ERROR*/  {op_e_xx, op_e_xx, op_e_xx, op_e_xx, op_e_xx, op_e_xx},
    /*BOOL*/   {op_e_xx, op_e_xx, op_e_xx, op_e_xx, op_e_xx, op_e_xx},
    /*DOUBLE*/ {op_n_xx, op_e_xx, op_e_xx, ge_b_ff, ge_b_fi, ge_b_xs},
    /*INT*/    {op_n_xx, op_e_xx, op_e_xx, ge_b_if, ge_b_ii, ge_b_xs},
    /*STRING*/ {op_n_xx, op_e_xx, op_e_xx, ge_b_sx, ge_b_sx, ge_b_ss},
};

static mv_binary_func_t* lt_dispositions[MT_MAX][MT_MAX] = {
    //         NULL      ERROR    BOOL     DOUBLE   INT      STRING
    /*NULL*/   {op_n_xx, op_e_xx, op_e_xx, op_n_xx, op_n_xx, op_n_xx},
    /*ERROR*/  {op_e_xx, op_e_xx, op_e_xx, op_e_xx, op_e_xx, op_e_xx},
    /*BOOL*/   {op_e_xx, op_e_xx, op_e_xx, op_e_xx, op_e_xx, op_e_xx},
    /*DOUBLE*/ {op_n_xx, op_e_xx, op_e_xx, lt_b_ff, lt_b_fi, lt_b_xs},
    /*INT*/    {op_n_xx, op_e_xx, op_e_xx, lt_b_if, lt_b_ii, lt_b_xs},
    /*STRING*/ {op_n_xx, op_e_xx, op_e_xx, lt_b_sx, lt_b_sx, lt_b_ss},
};

static mv_binary_func_t* le_dispositions[MT_MAX][MT_MAX] = {
    //         NULL      ERROR    BOOL     DOUBLE   INT      STRING
    /*NULL*/   {op_n_xx, op_e_xx, op_e_xx, op_n_xx, op_n_xx, op_n_xx},
    /*ERROR*/  {op_e_xx, op_e_xx, op_e_xx, op_e_xx, op_e_xx, op_e_xx},
    /*BOOL*/   {op_e_xx, op_e_xx, op_e_xx, op_e_xx, op_e_xx, op_e_xx},
    /*DOUBLE*/ {op_n_xx, op_e_xx, op_e_xx, le_b_ff, le_b_fi, le_b_xs},
    /*INT*/    {op_n_xx, op_e_xx, op_e_xx, le_b_if, le_b_ii, le_b_xs},
    /*STRING*/ {op_n_xx, op_e_xx, op_e_xx, le_b_sx, le_b_sx, le_b_ss},
};

mv_t eq_op_func(mv_t* pval1, mv_t* pval2) { return (eq_dispositions[pval1->type][pval2->type])(pval1, pval2); }
mv_t ne_op_func(mv_t* pval1, mv_t* pval2) { return (ne_dispositions[pval1->type][pval2->type])(pval1, pval2); }
mv_t gt_op_func(mv_t* pval1, mv_t* pval2) { return (gt_dispositions[pval1->type][pval2->type])(pval1, pval2); }
mv_t ge_op_func(mv_t* pval1, mv_t* pval2) { return (ge_dispositions[pval1->type][pval2->type])(pval1, pval2); }
mv_t lt_op_func(mv_t* pval1, mv_t* pval2) { return (lt_dispositions[pval1->type][pval2->type])(pval1, pval2); }
mv_t le_op_func(mv_t* pval1, mv_t* pval2) { return (le_dispositions[pval1->type][pval2->type])(pval1, pval2); }
Exemple #5
0
// ----------------------------------------------------------------
int ap_parse(ap_state_t* pstate, char* verb, int* pargi, int argc, char** argv) {

	int argi = *pargi;
	int ok = TRUE;

	while (argi < argc) {
		if (argv[argi][0] != '-') {
			break;
		}
		if (streq(argv[argi], "-h") || streq(argv[argi], "--help")) {
			ok = FALSE;
			break;
		}

		ap_flag_def_t* pdef = ap_find(pstate, argv[argi]);
		if (pdef == NULL) {
			ok = FALSE;
			break;
		}

		if ((argc-argi) < pdef->count) {
			fprintf(stderr, "%s %s: option %s requires an argument.\n",
				argv[0], verb, argv[argi]);
			fprintf(stderr, "\n");
			ok = FALSE;
			break;
		}

		if (pdef->type == AP_INT_VALUE_FLAG) {
			*(int *)pdef->pval = pdef->intval;
		} else if (pdef->type == AP_CHAR_FLAG) {
			if (!try_sep_from_arg(argv[argi+1], (char *)pdef->pval)) {
				fprintf(stderr, "%s %s: couldn't parse \"%s\" after \"%s\" as character.\n",
					argv[0], verb, argv[argi+1], argv[argi]);
				fprintf(stderr, "\n");
			}

		} else if (pdef->type == AP_INT_FLAG) {
			if (sscanf(argv[argi+1], "%d", (int *)pdef->pval) != 1) {
				fprintf(stderr, "%s %s: couldn't parse \"%s\" after \"%s\" as integer.\n",
					argv[0], verb, argv[argi+1], argv[argi]);
				fprintf(stderr, "\n");
			}

		} else if (pdef->type == AP_DOUBLE_FLAG) {
			if (!mlr_try_double_from_string(argv[argi+1], (double *)pdef->pval)) {
				fprintf(stderr, "%s %s: couldn't parse \"%s\" after \"%s\" as double.\n",
					argv[0], verb, argv[argi+1], argv[argi]);
				fprintf(stderr, "\n");
			}
		} else if (pdef->type == AP_STRING_FLAG) {
			char** pstring = pdef->pval;
			*pstring = argv[argi+1];
			pdef->pval = pstring;
		} else if (pdef->type == AP_STRING_LIST_FLAG) {
			slls_t** pplist = pdef->pval;

			if (*pplist != NULL)
				slls_free(*pplist);
			*pplist = slls_from_line(argv[argi+1], ',', FALSE);

			pdef->pval = pplist;
		} else {
			ok = FALSE;
			fprintf(stderr, "argparse.c: coding error: flag-def type %x not recognized.\n", pdef->type);
			fprintf(stderr, "\n");
			break;
		}

		argi += pdef->count;
	}

	*pargi = argi;
	return ok;
}