yanglint REFACTOR printing features simplified
diff --git a/tools/lint/cmd.c b/tools/lint/cmd.c
index a162f6e..344900d 100644
--- a/tools/lint/cmd.c
+++ b/tools/lint/cmd.c
@@ -77,7 +77,7 @@
"List all the loaded modules", "f:h"
},
{
- "feature", cmd_feature_opt, cmd_feature_dep, cmd_feature_exec, cmd_feature_print_fparam, cmd_feature_help, NULL,
+ "feature", cmd_feature_opt, cmd_feature_dep, cmd_feature_exec, cmd_feature_fin, cmd_feature_help, NULL,
"Print all features of module(s) with their state", "haf"
},
{
diff --git a/tools/lint/cmd.h b/tools/lint/cmd.h
index 047c580..bd2f2f2 100644
--- a/tools/lint/cmd.h
+++ b/tools/lint/cmd.h
@@ -223,13 +223,13 @@
int cmd_feature_exec(struct ly_ctx **ctx, struct yl_opt *yo, const char *posv);
/**
- * @brief Generate features for the command 'add'.
+ * @brief Printing of features ends.
*
- * @param[in,out] ctx context for libyang.
- * @param[in,out] yo context for yanglint. All necessary parameters should already be set.
+ * @param[in] ctx context for libyang. Not used.
+ * @param[in] yo context for yanglint.
* @return 0 on success.
*/
-int cmd_feature_print_fparam(struct ly_ctx *ctx, struct yl_opt *yo);
+int cmd_feature_fin(struct ly_ctx *ctx, struct yl_opt *yo);
void cmd_feature_help(void);
/* cmd_load.c */
diff --git a/tools/lint/cmd_feature.c b/tools/lint/cmd_feature.c
index 4214ce3..5c8bd82 100644
--- a/tools/lint/cmd_feature.c
+++ b/tools/lint/cmd_feature.c
@@ -99,62 +99,33 @@
int
cmd_feature_exec(struct ly_ctx **ctx, struct yl_opt *yo, const char *posv)
{
- int rc = 0;
- struct ly_set set = {0};
const struct lys_module *mod;
if (yo->feature_print_all) {
- if (print_all_features(yo->out, *ctx, yo->feature_param_format, &yo->features_output)) {
- YLMSG_E("Printing all features failed.\n");
- rc = 1;
- goto cleanup;
- }
- if (yo->feature_param_format) {
- printf("%s\n", yo->features_output);
- }
- goto cleanup;
+ print_all_features(yo->out, *ctx, yo->feature_param_format);
+ return 0;
}
mod = ly_ctx_get_module_latest(*ctx, posv);
if (!mod) {
YLMSG_E("Module \"%s\" not found.\n", posv);
- rc = 1;
- goto cleanup;
- }
-
- /* collect features of the module */
- if (collect_features(mod, &set)) {
- rc = 1;
- goto cleanup;
+ return 1;
}
if (yo->feature_param_format) {
- if (generate_features_output(mod, &set, &yo->features_output)) {
- rc = 1;
- goto cleanup;
- }
- /* don't print features and their state of each module if generating features parameter */
- goto cleanup;
+ print_feature_param(yo->out, mod);
+ } else {
+ print_features(yo->out, mod);
}
- if (yo->interactive) {
- print_features(yo->out, mod, &set);
- }
-
-cleanup:
- ly_set_erase(&set, NULL);
-
- return rc;
+ return 0;
}
int
-cmd_feature_print_fparam(struct ly_ctx *ctx, struct yl_opt *yo)
+cmd_feature_fin(struct ly_ctx *ctx, struct yl_opt *yo)
{
(void) ctx;
- if (!yo->feature_print_all && yo->feature_param_format) {
- printf("%s\n", yo->features_output);
- }
-
+ ly_print(yo->out, "\n");
return 0;
}
diff --git a/tools/lint/main_ni.c b/tools/lint/main_ni.c
index fee2b81..6f04623 100644
--- a/tools/lint/main_ni.c
+++ b/tools/lint/main_ni.c
@@ -751,9 +751,7 @@
goto cleanup;
}
}
- if ((ret = cmd_feature_print_fparam(ctx, &yo))) {
- goto cleanup;
- }
+ cmd_feature_fin(ctx, &yo);
} else if (yo.schema_out_format && yo.schema_node_path) {
if ((ret = cmd_print_exec(&ctx, &yo, NULL))) {
goto cleanup;
diff --git a/tools/lint/yl_opt.c b/tools/lint/yl_opt.c
index 67aff0e..1a6add0 100644
--- a/tools/lint/yl_opt.c
+++ b/tools/lint/yl_opt.c
@@ -82,7 +82,6 @@
/* schema */
ly_set_erase(&yo->schema_features, yl_schema_features_free);
ly_set_erase(&yo->schema_modules, NULL);
- free(yo->features_output);
/* context */
free(yo->searchpaths);
diff --git a/tools/lint/yl_opt.h b/tools/lint/yl_opt.h
index a517148..d66ae4d 100644
--- a/tools/lint/yl_opt.h
+++ b/tools/lint/yl_opt.h
@@ -106,7 +106,6 @@
LYS_OUTFORMAT schema_out_format;
ly_bool feature_param_format;
ly_bool feature_print_all;
- char *features_output;
/*
* data
diff --git a/tools/lint/yl_schema_features.c b/tools/lint/yl_schema_features.c
index 0caac17..b452496 100644
--- a/tools/lint/yl_schema_features.c
+++ b/tools/lint/yl_schema_features.c
@@ -123,142 +123,84 @@
return 0;
}
-int
-collect_features(const struct lys_module *mod, struct ly_set *set)
-{
- struct lysp_feature *f = NULL;
- uint32_t idx = 0;
-
- while ((f = lysp_feature_next(f, mod->parsed, &idx))) {
- if (ly_set_add(set, (void *)f->name, 1, NULL)) {
- YLMSG_E("Memory allocation failed.\n");
- ly_set_erase(set, NULL);
- return 1;
- }
- }
-
- return 0;
-}
-
void
-print_features(struct ly_out *out, const struct lys_module *mod, const struct ly_set *set)
+print_features(struct ly_out *out, const struct lys_module *mod)
{
- size_t max_len;
- uint32_t j;
- const char *name;
+ struct lysp_feature *f;
+ uint32_t idx;
+ size_t max_len, len;
- /* header */
ly_print(out, "%s:\n", mod->name);
- /* no features */
- if (!set->count) {
- ly_print(out, "\t(none)\n\n");
+ /* get max len, so the statuses of all the features will be aligned */
+ max_len = 0, idx = 0, f = NULL;
+ while ((f = lysp_feature_next(f, mod->parsed, &idx))) {
+ len = strlen(f->name);
+ max_len = (max_len > len) ? max_len : len;
+ }
+ if (!max_len) {
+ ly_print(out, "\t(none)\n");
return;
}
- /* get max len, so the statuses of all the features will be aligned */
- max_len = 0;
- for (j = 0; j < set->count; ++j) {
- name = set->objs[j];
- if (strlen(name) > max_len) {
- max_len = strlen(name);
- }
- }
-
/* print features */
- for (j = 0; j < set->count; ++j) {
- name = set->objs[j];
- ly_print(out, "\t%-*s (%s)\n", (int)max_len, name, lys_feature_value(mod, name) ? "off" : "on");
+ idx = 0, f = NULL;
+ while ((f = lysp_feature_next(f, mod->parsed, &idx))) {
+ ly_print(out, "\t%-*s (%s)\n", (int)max_len, f->name, lys_feature_value(mod, f->name) ? "off" : "on");
}
-
- ly_print(out, "\n");
}
-int
-generate_features_output(const struct lys_module *mod, const struct ly_set *set, char **features_param)
+void
+print_feature_param(struct ly_out *out, const struct lys_module *mod)
{
- uint32_t j;
- /*
- * features_len - length of all the features in the current module
- * added_len - length of a string to be added, = features_len + extra necessary length
- * param_len - length of the parameter before appending new string
- */
- size_t features_len, added_len, param_len;
- char *tmp;
+ struct lysp_feature *f = NULL;
+ uint32_t idx = 0;
+ uint8_t first = 1;
- features_len = 0;
- for (j = 0; j < set->count; j++) {
- features_len += strlen(set->objs[j]);
- }
-
- if (j == 0) {
- /* no features */
- added_len = strlen("-F ") + strlen(mod->name) + strlen(":");
- } else {
- /* j = comma count, -1 because of trailing comma */
- added_len = strlen("-F ") + strlen(mod->name) + strlen(":") + features_len + j - 1;
- }
-
- /* to avoid strlen(NULL) if this is the first call */
- param_len = 0;
- if (*features_param) {
- param_len = strlen(*features_param);
- }
-
- /* +1 because of white space at the beginning */
- tmp = realloc(*features_param, param_len + added_len + 1 + 1);
- if (!tmp) {
- goto error;
- } else {
- *features_param = tmp;
- }
- sprintf(*features_param + param_len, " -F %s:", mod->name);
-
- for (j = 0; j < set->count; j++) {
- strcat(*features_param, set->objs[j]);
- /* no trailing comma */
- if (j != (set->count - 1)) {
- strcat(*features_param, ",");
+ ly_print(out, " -F %s:", mod->name);
+ while ((f = lysp_feature_next(f, mod->parsed, &idx))) {
+ if (first) {
+ ly_print(out, "%s", f->name);
+ first = 0;
+ } else {
+ ly_print(out, ",%s", f->name);
}
}
-
- return 0;
-
-error:
- YLMSG_E("Memory allocation failed (%s:%d, %s).\n", __FILE__, __LINE__, strerror(errno));
- return 1;
}
-int
-print_all_features(struct ly_out *out, const struct ly_ctx *ctx, uint8_t generate_features, char **features_param)
+void
+print_all_features(struct ly_out *out, const struct ly_ctx *ctx, uint8_t feature_param)
{
- int ret = 0;
- uint32_t i = 0;
+ uint32_t i;
struct lys_module *mod;
- struct ly_set set = {0};
+ uint8_t first;
+ /* Print features for all implemented modules. */
+ first = 1;
+ i = 0;
while ((mod = ly_ctx_get_module_iter(ctx, &i)) != NULL) {
- /* only care about implemented modules */
if (!mod->implemented) {
continue;
}
-
- /* always erase the set, so the previous module's features don't carry over to the next module's features */
- ly_set_erase(&set, NULL);
-
- if (collect_features(mod, &set)) {
- ret = 1;
- goto cleanup;
+ if (first) {
+ print_features(out, mod);
+ first = 0;
+ } else {
+ ly_print(out, "\n");
+ print_features(out, mod);
}
-
- if (generate_features && generate_features_output(mod, &set, features_param)) {
- ret = 1;
- goto cleanup;
- }
- print_features(out, mod, &set);
}
-cleanup:
- ly_set_erase(&set, NULL);
- return ret;
+ if (!feature_param) {
+ return;
+ }
+ ly_print(out, "\n");
+
+ /* Print features for all implemented modules in 'feature-param' format. */
+ i = 0;
+ while ((mod = ly_ctx_get_module_iter(ctx, &i)) != NULL) {
+ if (mod->implemented) {
+ print_feature_param(out, mod);
+ }
+ }
}
diff --git a/tools/lint/yl_schema_features.h b/tools/lint/yl_schema_features.h
index 7c96ba8..7bfe9fd 100644
--- a/tools/lint/yl_schema_features.h
+++ b/tools/lint/yl_schema_features.h
@@ -57,46 +57,28 @@
int parse_features(const char *fstring, struct ly_set *fset);
/**
- * @brief Collect all features of a module.
- *
- * @param[in] mod Module to be searched for features.
- * @param[out] set Set in which the features will be stored.
- * @return 0 on success.
- * @return 1 on error.
- */
-int collect_features(const struct lys_module *mod, struct ly_set *set);
-
-/**
* @brief Print all features of a single module.
*
* @param[in] out The output handler for printing.
- * @param[in] mod Module which contains the features.
- * @param[in] set Set which holds the features.
+ * @param[in] mod Module which can contains the features.
*/
-void print_features(struct ly_out *out, const struct lys_module *mod, const struct ly_set *set);
+void print_features(struct ly_out *out, const struct lys_module *mod);
/**
- * @brief Generate a string, which will contain features paramater.
+ * @brief Print all features in the 'feature-param' format.
*
- * @param[in] mod Module, for which the string will be generated.
- * @param[in] set Set containing the features.
- * @param[out] features_param String which will contain the output.
- * @return 0 on success.
- * @return 1 on error.
+ * @param[in] out The output handler for printing.
+ * @param[in] mod Module which can contains the features.
*/
-int generate_features_output(const struct lys_module *mod, const struct ly_set *set, char **features_param);
+void print_feature_param(struct ly_out *out, const struct lys_module *mod);
/**
* @brief Print all features of all implemented modules.
*
* @param[in] out The output handler for printing.
* @param[in] ctx Libyang context.
- * @param[in] generate_features Flag expressing whether to generate features parameter.
- * @param[out] features_param String, which will contain the output if the above flag is set.
- * @return 0 on success.
- * @return 1 on error.
+ * @param[in] feature_param Flag expressing whether to print features parameter.
*/
-int print_all_features(struct ly_out *out, const struct ly_ctx *ctx, uint8_t generate_features, char **features_param);
-
+void print_all_features(struct ly_out *out, const struct ly_ctx *ctx, uint8_t feature_param);
#endif /* YL_SCHEMA_FEATURES_H_ */