/*
* transform.c: support for building and running transformers
*
- * Copyright (C) 2007-2011 David Lutterkort
+ * Copyright (C) 2007-2016 David Lutterkort
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
goto done;
}
-static int filter_matches(struct tree *xfm, const char *path) {
+int filter_matches(struct tree *xfm, const char *path) {
int found = 0;
list_for_each(f, xfm->children) {
if (is_incl(f) && fnmatch_normalize(f->value, path, fnm_flags) == 0) {
ERR_NOMEM(r < 0, aug);
file = tree_fpath_cr(aug, path);
+ file->file = true;
ERR_BAIL(aug);
/* Set 'path' */
parent = tree_fpath_cr(aug, fpath);
ERR_RET(aug);
+ parent->file = true;
tree_unlink_children(aug, parent);
list_append(parent->children, sub);
list_for_each(s, sub) {
struct lns_error *err = NULL;
struct span *span = NULL;
int result = -1, r, text_len = 0;
+ struct info *info = NULL;
path = file_name_path(aug, filename);
ERR_NOMEM(path == NULL, aug);
text_len = strlen(text);
text = append_newline(text, text_len);
- struct info *info;
make_ref(info);
make_ref(info->filename);
info->filename->str = strdup(filename);
info->first_line = 1;
if (aug->flags & AUG_ENABLE_SPAN) {
+ /* Allocate the span already to capture a reference to
+ info->filename */
span = make_span(info);
ERR_NOMEM(span == NULL, info);
}
tree = lns_get(info, lens, text, &err);
- unref(info, info);
-
if (err != NULL) {
err_status = "parse_failed";
goto done;
/* top level node span entire file length */
if (span != NULL && tree != NULL) {
tree->parent->span = span;
+ span = NULL;
tree->parent->span->span_start = 0;
tree->parent->span->span_end = text_len;
}
store_error(aug, filename + strlen(aug->root) - 1, path, err_status,
errno, err, text);
error:
+ unref(info, info);
free_lns_error(err);
free(path);
+ free_span(span);
free_tree(tree);
free(text);
return result;
struct info *info = NULL;
struct lns_error *err = NULL;
struct tree *tree = NULL;
- struct span *span = NULL;
int result = -1;
const char *err_status = NULL;
struct lens *lens = NULL;
goto error;
}
- unref(info, info);
-
tree_freplace(aug, path, tree);
ERR_BAIL(aug);
- /* top level node span entire file length */
- if (span != NULL && tree != NULL) {
- tree->parent->span = span;
- tree->parent->span->span_start = 0;
- tree->parent->span->span_end = strlen(text);
- }
-
tree = NULL;
result = 0;
error:
+ unref(info, info);
store_error(aug, NULL, path, err_status, errno, err, text);
free_tree(tree);
free_lns_error(err);
return l->value;
}
-static struct lens *xfm_lens(struct augeas *aug,
- struct tree *xfm, const char **lens_name) {
+struct lens *xfm_lens(struct augeas *aug,
+ struct tree *xfm, const char **lens_name) {
struct tree *l = NULL;
for (l = xfm->children;
if (l == NULL || l->value == NULL)
return NULL;
- *lens_name = l->value;
+ if (lens_name != NULL)
+ *lens_name = l->value;
return lens_from_name(aug, l->value);
}
char *v = msg ? strdup(msg) : NULL;
char *l = strdup("error");
- if (l == NULL || v == NULL)
+ if (l == NULL || v == NULL) {
+ free(v);
+ free(l);
return;
+ }
tree_append(xfm, l, v);
}
int r;
err = tree_fpath_cr(aug, ep);
+ FREE(ep);
if (err == NULL)
return;
return result;
}
-int transform_load(struct augeas *aug, struct tree *xfm) {
+int transform_load(struct augeas *aug, struct tree *xfm, const char *file) {
int nmatches = 0;
char **matches;
const char *lens_name;
// FIXME: Record an error and return 0
return -1;
}
+
r = filter_generate(xfm, aug->root, &nmatches, &matches);
if (r == -1)
return -1;
for (int i=0; i < nmatches; i++) {
const char *filename = matches[i] + strlen(aug->root) - 1;
struct tree *finfo = file_info(aug, filename);
+
+ if (file != NULL && STRNEQ(filename, file)) {
+ FREE(matches[i]);
+ continue;
+ }
+
if (finfo != NULL && !finfo->dirty &&
tree_child(finfo, s_lens) != NULL) {
+ /* We have a potential conflict: since FINFO is not marked as
+ dirty (see aug_load for how the dirty flag on nodes under
+ /augeas/files is used during loading), we already processed
+ it with another lens. The other lens is recorded in
+ FINFO. If it so happens that the lenses are actually the
+ same, we silently move on, as this duplication does no
+ harm. If they are different we definitely have a problem and
+ need to record an error and remove the work the first lens
+ did. */
const char *s = xfm_lens_name(finfo);
- char *fpath = file_name_path(aug, matches[i]);
- transform_file_error(aug, "mxfm_load", filename,
- "Lenses %s and %s could be used to load this file",
- s, lens_name);
- aug_rm(aug, fpath);
- free(fpath);
+ struct lens *other_lens = lens_from_name(aug, s);
+ if (lens != other_lens) {
+ char *fpath = file_name_path(aug, matches[i]);
+ transform_file_error(aug, "mxfm_load", filename,
+ "Lenses %s and %s could be used to load this file",
+ s, lens_name);
+ aug_rm(aug, fpath);
+ free(fpath);
+ }
} else if (!file_current(aug, matches[i], finfo)) {
load_file(aug, lens, lens_name, matches[i]);
}
struct memstream ms;
bool ms_open = false;
const char *err_status = NULL;
- char *dyn_err_status = NULL;
struct lns_error *err = NULL;
struct lens *lens = NULL;
int result = -1, r;
result = 0;
done:
- {
- const char *emsg =
- dyn_err_status == NULL ? err_status : dyn_err_status;
- store_error(aug, NULL, path, emsg, errno, err, text_in);
- }
- free(dyn_err_status);
+ store_error(aug, NULL, path, err_status, errno, err, text_in);
lens_release(lens);
if (result < 0) {
free(*text_out);
file_path = path->value + strlen(AUGEAS_FILES_TREE);
path = NULL;
- if (file_path == NULL) {
- err_status = "no path for file";
- goto error;
- }
-
meta_path = path_of_tree(tree);
if (meta_path == NULL) {
err_status = "path_of_tree";