[augeas-devel] [PATCH 4/8] Store pathx parse errors in internal error struct
David Lutterkort
lutter at redhat.com
Tue Sep 22 00:49:01 UTC 2009
The pathx_parse function will now store error information in a struct
error; we pass the one from struct augeas in and save it in the pathx.
---
src/augeas.c | 89 ++++++++++++++++++++++++------------------------------
src/builtin.c | 8 ++--
src/internal.h | 8 ++++-
src/pathx.c | 53 ++++++++++++++++++++++++++++----
src/transform.c | 3 +-
5 files changed, 99 insertions(+), 62 deletions(-)
diff --git a/src/augeas.c b/src/augeas.c
index e8e2fc0..f6c1c3d 100644
--- a/src/augeas.c
+++ b/src/augeas.c
@@ -129,34 +129,32 @@ static int tree_set_value(struct tree *tree, const char *value) {
return 0;
}
-/* Parse a path expression. Report errors in /augeas/pathx/error */
-static struct pathx *parse_user_pathx(const struct augeas *aug,
- bool need_nodeset,
- const char *path) {
- struct pathx *result;
- int pos;
-
- if (pathx_parse(aug->origin, path, need_nodeset, aug->symtab, &result)
- == PATHX_NOERROR)
- return result;
+/* Report pathx errors in /augeas/pathx/error */
+static void store_pathx_error(const struct augeas *aug) {
+ if (aug->error.code != AUG_EPATHX)
+ return;
struct tree *error =
tree_path_cr(aug->origin, 3, s_augeas, s_pathx, s_error);
if (error == NULL)
- return NULL;
- tree_set_value(error, pathx_error(result, NULL, &pos));
+ return;
+ tree_set_value(error, aug->error.minor_details);
struct tree *tpos = tree_child_cr(error, s_pos);
if (tpos == NULL)
- return NULL;
+ return;
+ tree_set_value(tpos, aug->error.details);
+}
- free(tpos->value);
- if (ALLOC_N(tpos->value, strlen(path) + 4) >= 0) {
- strncpy(tpos->value, path, pos);
- strcat(tpos->value, "|=|");
- strcat(tpos->value, path + pos);
- }
- return NULL;
+static struct pathx *parse_user_pathx(const struct augeas *aug,
+ bool need_nodeset,
+ const char *path) {
+ struct pathx *result;
+ struct error *err = err_of_aug(aug);
+
+ pathx_parse(aug->origin, err, path, need_nodeset, aug->symtab,
+ &result);
+ return result;
}
static const char *init_root(const char *root0) {
@@ -363,6 +361,9 @@ static void api_entry(const struct augeas *aug) {
static void api_exit(const struct augeas *aug) {
assert(aug->api_entries > 0);
((struct augeas *) aug)->api_entries -= 1;
+ if (aug->api_entries == 0) {
+ store_pathx_error(aug);
+ }
}
int aug_load(struct augeas *aug) {
@@ -399,8 +400,7 @@ int aug_get(const struct augeas *aug, const char *path, const char **value) {
api_entry(aug);
p = parse_user_pathx((struct augeas *) aug, true, path);
- if (p == NULL)
- goto error;
+ ERR_BAIL(aug);
if (value != NULL)
*value = NULL;
@@ -427,11 +427,10 @@ int aug_defvar(augeas *aug, const char *name, const char *expr) {
result = pathx_symtab_undefine(&(aug->symtab), name);
} else {
p = parse_user_pathx((struct augeas *) aug, false, expr);
- if (p == NULL)
- goto done;
+ ERR_BAIL(aug);
result = pathx_symtab_define(&(aug->symtab), name, p);
}
- done:
+ error:
free_pathx(p);
api_exit(aug);
return result;
@@ -452,8 +451,7 @@ int aug_defnode(augeas *aug, const char *name, const char *expr,
created = &cr;
p = parse_user_pathx((struct augeas *) aug, false, expr);
- if (p == NULL)
- goto done;
+ ERR_BAIL(aug);
r = pathx_expand_tree(p, &tree);
if (r < 0)
@@ -499,8 +497,7 @@ int aug_set(struct augeas *aug, const char *path, const char *value) {
api_entry(aug);
p = parse_user_pathx(aug, true, path);
- if (p == NULL)
- goto error;
+ ERR_BAIL(aug);
result = tree_set(p, value) == NULL ? -1 : 0;
free_pathx(p);
@@ -545,11 +542,10 @@ int aug_insert(struct augeas *aug, const char *path, const char *label,
api_entry(aug);
p = parse_user_pathx(aug, true, path);
- if (p == NULL)
- goto done;
+ ERR_BAIL(aug);
result = tree_insert(p, label, before);
- done:
+ error:
free_pathx(p);
api_exit(aug);
return result;
@@ -660,8 +656,7 @@ int aug_rm(struct augeas *aug, const char *path) {
api_entry(aug);
p = parse_user_pathx(aug, true, path);
- if (p == NULL)
- goto error;
+ ERR_BAIL(aug);
result = tree_rm(p);
free_pathx(p);
@@ -678,7 +673,7 @@ int tree_replace(struct tree *origin, const char *path, struct tree *sub) {
struct pathx *p = NULL;
int r;
- if (pathx_parse(origin, path, true, NULL, &p) != PATHX_NOERROR)
+ if (pathx_parse(origin, NULL, path, true, NULL, &p) != PATHX_NOERROR)
goto error;
r = tree_rm(p);
@@ -711,26 +706,24 @@ int aug_mv(struct augeas *aug, const char *src, const char *dst) {
ret = -1;
s = parse_user_pathx(aug, true, src);
- if (s == NULL)
- goto done;
+ ERR_BAIL(aug);
d = parse_user_pathx(aug, true, dst);
- if (d == NULL)
- goto done;
+ ERR_BAIL(aug);
r = pathx_find_one(s, &ts);
if (r != 1)
- goto done;
+ goto error;
r = pathx_expand_tree(d, &td);
if (r == -1)
- goto done;
+ goto error;
/* Don't move SRC into its own descendent */
t = td;
do {
if (t == ts)
- goto done;
+ goto error;
t = t->parent;
} while (! ROOT_P(t));
@@ -750,7 +743,7 @@ int aug_mv(struct augeas *aug, const char *src, const char *dst) {
tree_mark_dirty(td);
ret = 0;
- done:
+ error:
free_pathx(s);
free_pathx(d);
api_exit(aug);
@@ -772,8 +765,7 @@ int aug_match(const struct augeas *aug, const char *pathin, char ***matches) {
}
p = parse_user_pathx((struct augeas *) aug, true, pathin);
- if (p == NULL)
- goto error;
+ ERR_BAIL(aug);
for (tree = pathx_first(p); tree != NULL; tree = pathx_next(p)) {
if (! TREE_HIDDEN(tree))
@@ -901,7 +893,7 @@ static int unlink_removed_files(struct augeas *aug,
if (tf == NULL) {
/* Unlink all files in tm */
struct pathx *px = NULL;
- if (pathx_parse(tm, file_nodes, true, NULL, &px)
+ if (pathx_parse(tm, err_of_aug(aug), file_nodes, true, NULL, &px)
!= PATHX_NOERROR) {
result = -1;
continue;
@@ -1042,7 +1034,7 @@ int dump_tree(FILE *out, struct tree *tree) {
struct pathx *p;
int result;
- if (pathx_parse(tree, "/*", true, NULL, &p) != PATHX_NOERROR)
+ if (pathx_parse(tree, NULL, "/*", true, NULL, &p) != PATHX_NOERROR)
return -1;
result = print_tree(out, p, 1);
@@ -1061,8 +1053,7 @@ int aug_print(const struct augeas *aug, FILE *out, const char *pathin) {
}
p = parse_user_pathx((struct augeas *) aug, true, pathin);
- if (p == NULL)
- goto error;
+ ERR_BAIL(aug);
result = print_tree(out, p, 0);
free_pathx(p);
diff --git a/src/builtin.c b/src/builtin.c
index ce3fd3c..e066aba 100644
--- a/src/builtin.c
+++ b/src/builtin.c
@@ -212,7 +212,7 @@ static struct value *tree_set_glue(struct info *info, struct value *path,
fake = tree->origin->children;
}
- if (pathx_parse(tree->origin, path->string->str, true, NULL, &p)
+ if (pathx_parse(tree->origin, NULL, path->string->str, true, NULL, &p)
!= PATHX_NOERROR) {
result = make_pathx_exn(ref(info), p);
goto done;
@@ -253,7 +253,7 @@ static struct value *tree_clear_glue(struct info *info, struct value *path,
fake = tree->origin->children;
}
- if (pathx_parse(tree->origin, path->string->str, true, NULL, &p)
+ if (pathx_parse(tree->origin, NULL, path->string->str, true, NULL, &p)
!= PATHX_NOERROR) {
result = make_pathx_exn(ref(info), p);
goto done;
@@ -290,7 +290,7 @@ static struct value *tree_insert_glue(struct info *info, struct value *label,
struct pathx *p = NULL;
struct value *result = NULL;
- if (pathx_parse(tree->origin, path->string->str, true, NULL, &p)
+ if (pathx_parse(tree->origin, NULL, path->string->str, true, NULL, &p)
!= PATHX_NOERROR) {
result = make_pathx_exn(ref(info), p);
goto done;
@@ -337,7 +337,7 @@ static struct value *tree_rm_glue(struct info *info,
struct pathx *p = NULL;
struct value *result = NULL;
- if (pathx_parse(tree->origin, path->string->str, true, NULL, &p)
+ if (pathx_parse(tree->origin, NULL, path->string->str, true, NULL, &p)
!= PATHX_NOERROR) {
result = make_pathx_exn(ref(info), p);
goto done;
diff --git a/src/internal.h b/src/internal.h
index 441be84..aef6c0a 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -298,6 +298,10 @@ void report_error(struct error *err, aug_errcode_t errcode,
const char *format, ...)
ATTRIBUTE_FORMAT(printf, 3, 4);
+static inline struct error *err_of_aug(const struct augeas *aug) {
+ return &((struct augeas *) aug)->error;
+}
+
#define ERR_BAIL(aug) if ((aug)->error.code != AUG_NOERROR) goto error;
#define ERR_NOMEM(cond, aug) \
@@ -442,7 +446,9 @@ const char *pathx_error(struct pathx *pathx, const char **txt, int *pos);
*
* Returns 0 on success, and -1 on error
*/
-int pathx_parse(const struct tree *origin, const char *path,
+int pathx_parse(const struct tree *origin,
+ struct error *err,
+ const char *path,
bool need_nodeset,
struct pathx_symtab *symtab,
struct pathx **px);
diff --git a/src/pathx.c b/src/pathx.c
index 2a07c21..7a691d8 100644
--- a/src/pathx.c
+++ b/src/pathx.c
@@ -234,6 +234,9 @@ struct state {
struct locpath_trace *locpath_trace;
/* Symbol table for variable lookups */
struct pathx_symtab *symtab;
+ /* Error structure, used to communicate errors to struct augeas;
+ * we never own this structure, and therefore never free it */
+ struct error *error;
};
/* We consider NULL and the empty string to be equal */
@@ -1871,7 +1874,38 @@ static void parse_expr(struct state *state) {
parse_or_expr(state);
}
-int pathx_parse(const struct tree *tree, const char *txt,
+static void store_error(struct pathx *pathx) {
+ const char *pathx_msg = NULL;
+ const char *path = pathx->state->txt;
+ const pathx_errcode_t errcode = pathx->state->errcode;
+ struct error *err = pathx->state->error;
+
+ char *pos_str = NULL;
+ int pos;
+
+ if (err == NULL || errcode == PATHX_NOERROR || err->code != AUG_NOERROR)
+ return;
+
+ pathx_msg = pathx_error(pathx, NULL, &pos);
+
+ if (ALLOC_N(pos_str, strlen(path) + 4) >= 0) {
+ strncpy(pos_str, path, pos);
+ strcat(pos_str, "|=|");
+ strcat(pos_str, path + pos);
+ }
+
+ err->code = errcode == PATHX_ENOMEM ? AUG_ENOMEM : AUG_EPATHX;
+ err->minor = errcode;
+ err->details = pos_str;
+ pos_str = NULL;
+ err->minor_details = pathx_msg;
+
+ FREE(pos_str);
+}
+
+int pathx_parse(const struct tree *tree,
+ struct error *err,
+ const char *txt,
bool need_nodeset,
struct pathx_symtab *symtab,
struct pathx **pathx) {
@@ -1880,22 +1914,20 @@ int pathx_parse(const struct tree *tree, const char *txt,
*pathx = NULL;
if (ALLOC(*pathx) < 0)
- return PATHX_ENOMEM;
+ goto oom;
(*pathx)->origin = (struct tree *) tree;
/* Set up state */
- if (ALLOC((*pathx)->state) < 0) {
- free_pathx(*pathx);
- *pathx = NULL;
- return PATHX_ENOMEM;
- }
+ if (ALLOC((*pathx)->state) < 0)
+ goto oom;
state = (*pathx)->state;
state->errcode = PATHX_NOERROR;
state->txt = txt;
state->pos = txt;
state->symtab = symtab;
+ state->error = err;
if (ALLOC_N(state->value_pool, 8) < 0) {
STATE_ENOMEM;
@@ -1933,7 +1965,14 @@ int pathx_parse(const struct tree *tree, const char *txt,
}
done:
+ store_error(*pathx);
return state->errcode;
+ oom:
+ free_pathx(*pathx);
+ *pathx = NULL;
+ if (err != NULL)
+ err->code = AUG_ENOMEM;
+ return PATHX_ENOMEM;
}
/*************************************************************************
diff --git a/src/transform.c b/src/transform.c
index a9e60dc..341fc36 100644
--- a/src/transform.c
+++ b/src/transform.c
@@ -673,7 +673,8 @@ static int file_saved_event(struct augeas *aug, const char *path) {
struct tree *dummy;
int r;
- r = pathx_parse(aug->origin, AUGEAS_EVENTS_SAVED "[last()]",
+ r = pathx_parse(aug->origin, err_of_aug(aug),
+ AUGEAS_EVENTS_SAVED "[last()]",
true, NULL, &px);
if (r != PATHX_NOERROR)
return -1;
--
1.6.2.5
More information about the augeas-devel
mailing list