|
@@ -51,11 +51,8 @@ int fixup_regexpNL_none(void** param, int param_no); /* textops */
|
|
|
{ \
|
|
|
if ((param_no > (maxp)) || (param_no < (minp))) \
|
|
|
return E_UNSPEC; \
|
|
|
- if (*param){ \
|
|
|
- fparam_free_contents((fparam_t*)*param); \
|
|
|
- pkg_free(*param); \
|
|
|
- *param=0; \
|
|
|
- } \
|
|
|
+ if (*param) \
|
|
|
+ fparam_free_restore(param); \
|
|
|
return 0; \
|
|
|
}
|
|
|
|
|
@@ -150,7 +147,7 @@ int fixup_regexpNL_none(void** param, int param_no); /* textops */
|
|
|
int ret; \
|
|
|
if (param && *param){ \
|
|
|
p=(param_no>(no1))? *param - (long)&((fparam_t*)0)->v : *param;\
|
|
|
- if ((ret=fixup_free_fpt_##suffix(&p, param_no))==0) *param=0; \
|
|
|
+ if ((ret=fixup_free_fpt_##suffix(&p, param_no))==0) *param=p; \
|
|
|
return ret; \
|
|
|
} \
|
|
|
return 0; \
|
|
@@ -169,24 +166,286 @@ int fixup_regexpNL_none(void** param, int param_no); /* textops */
|
|
|
|
|
|
FIXUP_F1T(str_null, 1, 1, FPARAM_STR)
|
|
|
FIXUP_F1T(str_str, 1, 2, FPARAM_STR)
|
|
|
+FIXUP_F1T(str_all, 1, 100, FPARAM_STR)
|
|
|
|
|
|
-/* TODO: int can be converted in place, no need for pkg_malloc'ed fparam_t*/
|
|
|
+/*
|
|
|
+ no free fixups possible for unit_*
|
|
|
+ (they overwrite the pointer with the converted number => the original
|
|
|
+ value cannot be recovered)
|
|
|
FIXUP_F1T(uint_null, 1, 1, FPARAM_INT)
|
|
|
FIXUP_F1T(uint_uint, 1, 2, FPARAM_INT)
|
|
|
+*/
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+int fixup_uint_uint(void** param, int param_no)
|
|
|
+{
|
|
|
+ str s;
|
|
|
+ unsigned int num;
|
|
|
+
|
|
|
+ s.s = *param;
|
|
|
+ s.len = strlen(s.s);
|
|
|
+ if (likely(str2int(&s, &num) == 0)) {
|
|
|
+ *param = (void*)(long)num;
|
|
|
+ } else
|
|
|
+ /* not a number */
|
|
|
+ return E_UNSPEC;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+int fixup_uint_null(void** param, int param_no)
|
|
|
+{
|
|
|
+ if (param_no == 1)
|
|
|
+ return fixup_uint_uint(param, param_no);
|
|
|
+ return E_UNSPEC;
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
+/* fixup_regexp_null() has to be written "by hand", since
|
|
|
+ it needs to save the original pointer (the fixup users expects
|
|
|
+ a pointer to the regex in *param and hence the original value
|
|
|
+ needed on free cannot be recovered directly).
|
|
|
FIXUP_F1T(regexp_null, 1, 1, FPARAM_REGEX)
|
|
|
+*/
|
|
|
|
|
|
+struct regex_fixup {
|
|
|
+ regex_t regex; /* compiled regex */
|
|
|
+ void* orig; /* original pointer */
|
|
|
+};
|
|
|
+
|
|
|
+int fixup_regexp_null(void** param, int param_no)
|
|
|
+{
|
|
|
+ struct regex_fixup* re;
|
|
|
+
|
|
|
+ if (param_no != 1)
|
|
|
+ return E_UNSPEC;
|
|
|
+ if ((re=pkg_malloc(sizeof(*re))) ==0) {
|
|
|
+ ERR("No memory left\n");
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
+ if (regcomp(&re->regex, *param,
|
|
|
+ REG_EXTENDED|REG_ICASE|REG_NEWLINE))
|
|
|
+ goto error;
|
|
|
+ re->orig = *param;
|
|
|
+ *param = re;
|
|
|
+ return 0;
|
|
|
+error:
|
|
|
+ if (re)
|
|
|
+ pkg_free(re);
|
|
|
+ return E_UNSPEC;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+int fixup_free_regexp_null(void** param, int param_no)
|
|
|
+{
|
|
|
+ struct regex_fixup* re;
|
|
|
+
|
|
|
+ if (param_no != 1)
|
|
|
+ return E_UNSPEC;
|
|
|
+ if (*param) {
|
|
|
+ re = *param;
|
|
|
+ *param = re->orig;
|
|
|
+ regfree(&re->regex);
|
|
|
+ pkg_free(re);
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/* fixup_pvar_*() has to be written "by hand", since
|
|
|
+ it needs to save the original pointer (the fixup users expects
|
|
|
+ a pointer to the pv_spec_t in *param and hence the original value
|
|
|
+ needed on free cannot be recovered directly).
|
|
|
FIXUP_F1T(pvar_null, 1, 1, FPARAM_PVS)
|
|
|
FIXUP_F1T(pvar_pvar, 1, 2, FPARAM_PVS)
|
|
|
+*/
|
|
|
+
|
|
|
+struct pvs_fixup {
|
|
|
+ pv_spec_t pvs; /* parsed pv spec */
|
|
|
+ void* orig; /* original pointer */
|
|
|
+};
|
|
|
+
|
|
|
+int fixup_pvar_all(void** param, int param_no)
|
|
|
+{
|
|
|
+ struct pvs_fixup* pvs_f;
|
|
|
+ str name;
|
|
|
+
|
|
|
+ pvs_f = 0;
|
|
|
+ name.s = *param;
|
|
|
+ name.len = strlen(name.s);
|
|
|
+ trim(&name);
|
|
|
+ if (name.len == 0 || name.s[0] != '$')
|
|
|
+ /* not a pvs id */
|
|
|
+ goto error;
|
|
|
+ if ((pvs_f=pkg_malloc(sizeof(*pvs_f))) == 0) {
|
|
|
+ ERR("No memory left\n");
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
+ if (pv_parse_spec2(&name, &pvs_f->pvs, 1) == 0)
|
|
|
+ /* not a valid pvs identifier */
|
|
|
+ goto error;
|
|
|
+ pvs_f->orig = *param;
|
|
|
+ *param = pvs_f;
|
|
|
+ return 0;
|
|
|
+error:
|
|
|
+ if (pvs_f)
|
|
|
+ pkg_free(pvs_f);
|
|
|
+ return E_UNSPEC;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+int fixup_free_pvar_all(void** param, int param_no)
|
|
|
+{
|
|
|
+ struct pvs_fixup* pvs_f;
|
|
|
+
|
|
|
+ if (*param) {
|
|
|
+ pvs_f = *param;
|
|
|
+ *param = pvs_f->orig;
|
|
|
+ pv_spec_free_contents(&pvs_f->pvs);
|
|
|
+ pkg_free(pvs_f);
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+int fixup_pvar_pvar(void** param, int param_no)
|
|
|
+{
|
|
|
+ if (param_no > 2)
|
|
|
+ return E_UNSPEC;
|
|
|
+ return fixup_free_pvar_all(param, param_no);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+int fixup_free_pvar_pvar(void** param, int param_no)
|
|
|
+{
|
|
|
+ if (param_no > 2)
|
|
|
+ return E_UNSPEC;
|
|
|
+ return fixup_free_pvar_all(param, param_no);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+int fixup_pvar_null(void** param, int param_no)
|
|
|
+{
|
|
|
+ if (param_no != 1)
|
|
|
+ return E_UNSPEC;
|
|
|
+ return fixup_pvar_all(param, param_no);
|
|
|
+}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+int fixup_free_pvar_null(void** param, int param_no)
|
|
|
+{
|
|
|
+ if (param_no != 1)
|
|
|
+ return E_UNSPEC;
|
|
|
+ return fixup_free_pvar_all(param, param_no);
|
|
|
+}
|
|
|
+
|
|
|
+/* must be written "by hand", see above (fixup_pvar_pvar).
|
|
|
FIXUP_F2T(pvar_str, 1, 2, 1, FPARAM_PVS, FPARAM_STR)
|
|
|
FIXUP_F2T(pvar_str_str, 1, 3, 1, FPARAM_PVS, FPARAM_STR)
|
|
|
+*/
|
|
|
+
|
|
|
+int fixup_pvar_str(void** param, int param_no)
|
|
|
+{
|
|
|
+ if (param_no == 1)
|
|
|
+ return fixup_pvar_all(param, param_no);
|
|
|
+ else if (param_no == 2)
|
|
|
+ return fixup_str_str(param, param_no);
|
|
|
+ return E_UNSPEC;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+int fixup_free_pvar_str(void** param, int param_no)
|
|
|
+{
|
|
|
+ if (param_no == 1)
|
|
|
+ return fixup_free_pvar_all(param, param_no);
|
|
|
+ else if (param_no == 2)
|
|
|
+ return fixup_free_str_str(param, param_no);
|
|
|
+ return E_UNSPEC;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+int fixup_pvar_str_str(void** param, int param_no)
|
|
|
+{
|
|
|
+ if (param_no == 1)
|
|
|
+ return fixup_pvar_all(param, param_no);
|
|
|
+ else if (param_no == 2 || param_no == 3)
|
|
|
+ return fixup_str_all(param, param_no);
|
|
|
+ return E_UNSPEC;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+int fixup_free_pvar_str_str(void** param, int param_no)
|
|
|
+{
|
|
|
+ if (param_no == 1)
|
|
|
+ return fixup_free_pvar_all(param, param_no);
|
|
|
+ else if (param_no == 2 || param_no == 3)
|
|
|
+ return fixup_free_str_all(param, param_no);
|
|
|
+ return E_UNSPEC;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
|
|
|
FIXUP_F2FP(igp_null, 1, 1, 1, FPARAM_INT|FPARAM_PVS, 0)
|
|
|
FIXUP_F2FP(igp_igp, 1, 2, 2, FPARAM_INT|FPARAM_PVS, 0)
|
|
|
-FIXUP_F2FP(igp_pvar, 1, 2, 1, FPARAM_INT|FPARAM_PVS, FPARAM_PVS)
|
|
|
|
|
|
+/* must be declared by hand, because of the pvar special handling
|
|
|
+ (see above)
|
|
|
+FIXUP_F2FP(igp_pvar, 1, 2, 1, FPARAM_INT|FPARAM_PVS, FPARAM_PVS)
|
|
|
FIXUP_F2FP_T(igp_pvar_pvar, 1, 3, 1, FPARAM_INT|FPARAM_PVS, FPARAM_PVS)
|
|
|
+*/
|
|
|
+
|
|
|
+int fixup_igp_pvar(void** param, int param_no)
|
|
|
+{
|
|
|
+ if (param_no == 1)
|
|
|
+ return fixup_igp_null(param, param_no);
|
|
|
+ else if (param_no == 2)
|
|
|
+ return fixup_pvar_all(param, param_no);
|
|
|
+ return E_UNSPEC;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+int fixup_free_igp_pvar(void** param, int param_no)
|
|
|
+{
|
|
|
+ if (param_no == 1)
|
|
|
+ return fixup_free_igp_null(param, param_no);
|
|
|
+ else if (param_no == 2)
|
|
|
+ return fixup_free_pvar_all(param, param_no);
|
|
|
+ return E_UNSPEC;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+int fixup_igp_pvar_pvar(void** param, int param_no)
|
|
|
+{
|
|
|
+ if (param_no == 1)
|
|
|
+ return fixup_igp_null(param, param_no);
|
|
|
+ else if (param_no == 2 || param_no == 3)
|
|
|
+ return fixup_pvar_all(param, param_no);
|
|
|
+ return E_UNSPEC;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+int fixup_free_igp_pvar_pvar(void** param, int param_no)
|
|
|
+{
|
|
|
+ if (param_no == 1)
|
|
|
+ return fixup_free_igp_null(param, param_no);
|
|
|
+ else if (param_no == 2 || param_no == 3)
|
|
|
+ return fixup_free_pvar_all(param, param_no);
|
|
|
+ return E_UNSPEC;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
|
|
|
/** macro for declaring a spve fixup and the corresponding free_fixup
|
|
|
* for a function expecting first no1 params as fparam converted spve
|
|
@@ -203,21 +462,16 @@ FIXUP_F2FP_T(igp_pvar_pvar, 1, 3, 1, FPARAM_INT|FPARAM_PVS, FPARAM_PVS)
|
|
|
int fixup_##suffix (void** param, int param_no) \
|
|
|
{ \
|
|
|
int ret; \
|
|
|
- char * bkp; \
|
|
|
fparam_t* fp; \
|
|
|
if (param_no<=(no1)){ \
|
|
|
if ((ret=fix_param_types(FPARAM_PVE, param))<0){ \
|
|
|
- ERR("Cannot convert function parameter %d to" #type2 "\n", \
|
|
|
+ ERR("Cannot convert function parameter %d to spve \n", \
|
|
|
param_no);\
|
|
|
return E_UNSPEC; \
|
|
|
} else{ \
|
|
|
fp=(fparam_t*)*param; \
|
|
|
if ((ret==0) && (fp->v.pve->spec.getf==0)){ \
|
|
|
- bkp=fp->orig; \
|
|
|
- fp->orig=0; /* make sure orig string is not freed */ \
|
|
|
- fparam_free_contents(fp); \
|
|
|
- pkg_free(fp); \
|
|
|
- *param=bkp; \
|
|
|
+ fparam_free_restore(param); \
|
|
|
return fix_param_types(FPARAM_STR, param); \
|
|
|
} else if (ret==1) \
|
|
|
return fix_param_types(FPARAM_STR, param); \
|
|
@@ -229,11 +483,9 @@ FIXUP_F2FP_T(igp_pvar_pvar, 1, 3, 1, FPARAM_INT|FPARAM_PVS, FPARAM_PVS)
|
|
|
int fixup_free_##suffix (void** param, int param_no) \
|
|
|
{ \
|
|
|
if (param && *param){ \
|
|
|
- if (param_no<=(no1)){ \
|
|
|
- fparam_free_contents((fparam_t*)*param); \
|
|
|
- pkg_free(*param); \
|
|
|
- *param=0; \
|
|
|
- } else \
|
|
|
+ if (param_no<=(no1)) \
|
|
|
+ fparam_free_restore(param); \
|
|
|
+ else \
|
|
|
return fixup_free_spvet_##suffix(param, param_no); \
|
|
|
} \
|
|
|
return 0; \
|