Skip to content

Commit ed5acc5

Browse files
committed
yanglint FEATURE initial version of yanglint(1)
Source codes are mostly taken from libyang 1.0 and slightly modified for libyang 2.0. A lot of functionality is still missing since it is not yet provided by libyang 2.0
1 parent 92cc851 commit ed5acc5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+10447
-31
lines changed

CMakeLists.txt

+16-17
Original file line numberDiff line numberDiff line change
@@ -185,20 +185,17 @@ set(libsrc
185185
src/xml.c
186186
src/xpath.c)
187187

188-
#set(lintsrc
189-
# tools/lint/main.c
190-
# tools/lint/main_ni.c
191-
# tools/lint/commands.c
192-
# tools/lint/completion.c
193-
# tools/lint/configuration.c
194-
# linenoise/linenoise.c)
188+
set(lintsrc
189+
tools/lint/main.c
190+
tools/lint/main_ni.c
191+
tools/lint/commands.c
192+
tools/lint/completion.c
193+
tools/lint/configuration.c
194+
tools/lint/linenoise/linenoise.c)
195195

196196
#set(resrc
197197
# tools/re/main.c)
198198

199-
#set(yang2yinsrc
200-
# tools/yang2yin/main.c)
201-
202199
set(headers
203200
src/libyang.h
204201
src/context.h
@@ -340,19 +337,21 @@ endif(ENABLE_BUILD_TESTS)
340337
#
341338
#configure_file(${PROJECT_SOURCE_DIR}/src/plugin_config.h.in ${PROJECT_BINARY_DIR}/src/plugin_config.h)
342339

340+
# config file for tools
341+
configure_file(${PROJECT_SOURCE_DIR}/tools/config.h.in ${PROJECT_BINARY_DIR}/tools/config.h @ONLY)
342+
343343
# yanglint
344-
#add_executable(yanglint ${lintsrc})
345-
#target_link_libraries(yanglint yang)
346-
#install(TARGETS yanglint DESTINATION ${CMAKE_INSTALL_BINDIR})
347-
#install(FILES ${PROJECT_SOURCE_DIR}/tools/lint/yanglint.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
344+
add_executable(yanglint ${lintsrc})
345+
target_link_libraries(yanglint yang)
346+
install(TARGETS yanglint DESTINATION ${CMAKE_INSTALL_BINDIR})
347+
install(FILES ${PROJECT_SOURCE_DIR}/tools/lint/yanglint.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
348+
target_include_directories(yanglint BEFORE PRIVATE ${PROJECT_BINARY_DIR}/tools)
348349

349350
#yangre
350351
#add_executable(yangre ${resrc})
351352
#target_link_libraries(yangre yang)
352353
#install(TARGETS yangre DESTINATION ${CMAKE_INSTALL_BINDIR})
353-
354-
# yang2yin
355-
#add_executable(yang2yin ${yang2yinsrc})
354+
#target_include_directories(yangre BEFORE PRIVATE ${PROJECT_BINARY_DIR}/tools)
356355

357356
if(ENABLE_VALGRIND_TESTS)
358357
set(ENABLE_BUILD_TESTS ON)

src/context.c

+44
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,36 @@ ly_ctx_unset_searchdirs(struct ly_ctx *ctx, const char *value)
153153
return LY_SUCCESS;
154154
}
155155

156+
API LY_ERR
157+
ly_ctx_unset_searchdir(struct ly_ctx *ctx, unsigned int index)
158+
{
159+
LY_CHECK_ARG_RET(ctx, ctx, LY_EINVAL);
160+
161+
if (!ctx->search_paths.count) {
162+
return LY_SUCCESS;
163+
}
164+
165+
if (index >= ctx->search_paths.count) {
166+
LOGARG(ctx, value);
167+
return LY_EINVAL;
168+
} else {
169+
return ly_set_rm_index(&ctx->search_paths, index, free);
170+
}
171+
172+
return LY_SUCCESS;
173+
}
174+
175+
API const struct lys_module *
176+
ly_ctx_load_module(struct ly_ctx *ctx, const char *name, const char *revision)
177+
{
178+
struct lys_module *result = NULL;
179+
180+
LY_CHECK_ARG_RET(ctx, ctx, name, NULL);
181+
182+
LY_CHECK_RET(lysp_load_module(ctx, name, revision, 1, 0, &result), NULL);
183+
return result;
184+
}
185+
156186
API LY_ERR
157187
ly_ctx_new(const char *search_dir, int options, struct ly_ctx **new_ctx)
158188
{
@@ -163,6 +193,8 @@ ly_ctx_new(const char *search_dir, int options, struct ly_ctx **new_ctx)
163193
int i;
164194
LY_ERR rc = LY_SUCCESS;
165195

196+
LY_CHECK_ARG_RET(NULL, new_ctx, LY_EINVAL);
197+
166198
ctx = calloc(1, sizeof *ctx);
167199
LY_CHECK_ERR_RET(!ctx, LOGMEM(NULL), LY_EMEM);
168200

@@ -280,6 +312,18 @@ ly_ctx_get_module_imp_clb(const struct ly_ctx *ctx, void **user_data)
280312
return ctx->imp_clb;
281313
}
282314

315+
API const struct lys_module *
316+
ly_ctx_get_module_iter(const struct ly_ctx *ctx, unsigned int *index)
317+
{
318+
LY_CHECK_ARG_RET(ctx, ctx, index, NULL);
319+
320+
for ( ; *index < (unsigned)ctx->list.count; (*index)++) {
321+
return ctx->list.objs[(*index)++];
322+
}
323+
324+
return NULL;
325+
}
326+
283327
/**
284328
* @brief Iterate over the modules in the given context. Returned modules must match the given key at the offset of
285329
* lysp_module and lysc_module structures (they are supposed to be placed at the same offset in both structures).

src/context.h

+49
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,25 @@ LY_ERR ly_ctx_set_searchdir(struct ly_ctx *ctx, const char *search_dir);
104104
/**
105105
* @brief Clean the search path(s) from the libyang context
106106
*
107+
* To remove the search path by its index, use ly_ctx_unset_searchdir().
108+
*
107109
* @param[in] ctx Context to be modified.
108110
* @param[in] value Searchdir to be removed, use NULL to remove them all.
109111
* @return LY_ERR return value
110112
*/
111113
LY_ERR ly_ctx_unset_searchdirs(struct ly_ctx *ctx, const char *value);
112114

115+
/**
116+
* @brief Remove the specific search path from the libyang context.
117+
*
118+
* To remove the search path by its value, use ly_ctx_unset_searchdirs().
119+
*
120+
* @param[in] ctx Context to be modified.
121+
* @param[in] index Index of the searchdir to be removed.
122+
* @return LY_ERR return value
123+
*/
124+
LY_ERR ly_ctx_unset_searchdir(struct ly_ctx *ctx, unsigned int index);
125+
113126
/**
114127
* @brief Get the NULL-terminated list of the search paths in libyang context. Do not modify the result!
115128
*
@@ -231,6 +244,25 @@ struct lys_module *ly_ctx_get_module_latest(const struct ly_ctx *ctx, const char
231244
*/
232245
struct lys_module *ly_ctx_get_module_implemented(const struct ly_ctx *ctx, const char *name);
233246

247+
/**
248+
* @brief Get the (only) implemented YANG module specified by its name.
249+
*
250+
* @param[in] ctx Context where to search.
251+
* @param[in] name Name of the YANG module to get.
252+
* @return The only implemented YANG module revision of the given name in the given context. NULL if there is no
253+
* implemented module of the given name.
254+
*/
255+
/**
256+
* @brief Iterate over all modules in the given context.
257+
*
258+
* @param[in] ctx Context with the modules.
259+
* @param[in,out] index Index of the next module to get. Value of 0 starts from the beginning.
260+
* The value is updated with each call, so to iterate over all modules the same variable is supposed
261+
* to be used in all calls starting with value 0.
262+
* @return Next context module, NULL if the last was already returned.
263+
*/
264+
const struct lys_module *ly_ctx_get_module_iter(const struct ly_ctx *ctx, unsigned int *index);
265+
234266
/**
235267
* @brief Get YANG module of the given namespace and revision.
236268
*
@@ -292,6 +324,23 @@ void ly_ctx_reset_latests(struct ly_ctx *ctx);
292324
*/
293325
LY_ERR ly_ctx_module_implement(struct ly_ctx *ctx, struct lys_module *mod);
294326

327+
/**
328+
* @brief Try to find the model in the searchpaths of \p ctx and load it into it. If custom missing
329+
* module callback is set, it is used instead.
330+
*
331+
* The context itself is searched for the requested module first. If \p revision is not specified
332+
* (the module of the latest revision is requested) and there is implemented revision of the requested
333+
* module in the context, this implemented revision is returned despite there might be a newer revision.
334+
* This behavior is cause by the fact that it is not possible to have multiple implemented revisions of
335+
* the same module in the context.
336+
*
337+
* @param[in] ctx Context to add to.
338+
* @param[in] name Name of the module to load.
339+
* @param[in] revision Optional revision date of the module. If not specified, the latest revision is loaded.
340+
* @return Pointer to the data model structure, NULL if not found or some error occurred.
341+
*/
342+
const struct lys_module *ly_ctx_load_module(struct ly_ctx *ctx, const char *name, const char *revision);
343+
295344
/**
296345
* @brief Free all internal structures of the specified context.
297346
*

src/tree_schema.c

+13-11
Original file line numberDiff line numberDiff line change
@@ -427,19 +427,19 @@ lys_feature_change(const struct lys_module *mod, const char *name, int value)
427427
}
428428

429429
API LY_ERR
430-
lys_feature_enable(struct lys_module *module, const char *feature)
430+
lys_feature_enable(const struct lys_module *module, const char *feature)
431431
{
432432
LY_CHECK_ARG_RET(NULL, module, feature, LY_EINVAL);
433433

434-
return lys_feature_change(module, feature, 1);
434+
return lys_feature_change((struct lys_module*)module, feature, 1);
435435
}
436436

437437
API LY_ERR
438-
lys_feature_disable(struct lys_module *module, const char *feature)
438+
lys_feature_disable(const struct lys_module *module, const char *feature)
439439
{
440440
LY_CHECK_ARG_RET(NULL, module, feature, LY_EINVAL);
441441

442-
return lys_feature_change(module, feature, 0);
442+
return lys_feature_change((struct lys_module*)module, feature, 0);
443443
}
444444

445445
API int
@@ -517,11 +517,11 @@ lys_parse_mem_submodule(struct ly_ctx *ctx, const char *data, LYS_INFORMAT forma
517517
memcpy(&context.grps_nodes, &main_ctx->grps_nodes, sizeof main_ctx->grps_nodes);
518518

519519
switch (format) {
520+
/* TODO not yet supported
520521
case LYS_IN_YIN:
521-
/* TODO not yet supported
522522
mod = yin_read_module();
523-
*/
524523
break;
524+
*/
525525
case LYS_IN_YANG:
526526
ret = yang_parse_submodule(&context, data, &submod);
527527
break;
@@ -589,11 +589,11 @@ lys_parse_mem_module(struct ly_ctx *ctx, const char *data, LYS_INFORMAT format,
589589
mod->ctx = ctx;
590590

591591
switch (format) {
592+
/* TODO not yet supported
592593
case LYS_IN_YIN:
593-
/* TODO not yet supported
594594
mod = yin_read_module();
595-
*/
596595
break;
596+
*/
597597
case LYS_IN_YANG:
598598
ret = yang_parse_module(&context, data, mod);
599599
break;
@@ -1004,10 +1004,12 @@ lys_search_localfile(const char * const *searchpaths, int cwd, const char *name,
10041004

10051005
/* get type according to filename suffix */
10061006
flen = strlen(file->d_name);
1007-
if (!strcmp(&file->d_name[flen - 4], ".yin")) {
1008-
format_aux = LYS_IN_YIN;
1009-
} else if (!strcmp(&file->d_name[flen - 5], ".yang")) {
1007+
if (!strcmp(&file->d_name[flen - 5], ".yang")) {
10101008
format_aux = LYS_IN_YANG;
1009+
/* TODO YIN parser
1010+
} else if (!strcmp(&file->d_name[flen - 4], ".yin")) {
1011+
format_aux = LYS_IN_YIN;
1012+
*/
10111013
} else {
10121014
/* not supportde suffix/file format */
10131015
continue;

src/tree_schema.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -1595,7 +1595,7 @@ struct lys_module {
15951595
* @param[in] feature Name of the feature to enable. To enable all features at once, use asterisk (`*`) character.
15961596
* @return LY_ERR value.
15971597
*/
1598-
LY_ERR lys_feature_enable(struct lys_module *module, const char *feature);
1598+
LY_ERR lys_feature_enable(const struct lys_module *module, const char *feature);
15991599

16001600
/**
16011601
* @brief Disable specified feature in the module
@@ -1606,7 +1606,7 @@ LY_ERR lys_feature_enable(struct lys_module *module, const char *feature);
16061606
* @param[in] feature Name of the feature to disable. To disable all features at once, use asterisk (`*`) character.
16071607
* @return LY_ERR value
16081608
*/
1609-
LY_ERR lys_feature_disable(struct lys_module *module, const char *feature);
1609+
LY_ERR lys_feature_disable(const struct lys_module *module, const char *feature);
16101610

16111611
/**
16121612
* @brief Get the current status of the specified feature in the module.

src/tree_schema_helpers.c

+10
Original file line numberDiff line numberDiff line change
@@ -747,8 +747,18 @@ lysp_load_module(struct ly_ctx *ctx, const char *name, const char *revision, int
747747
if (!*mod) {
748748
/* try to get the module from the context */
749749
if (revision) {
750+
/* get the specific revision */
750751
*mod = (struct lys_module*)ly_ctx_get_module(ctx, name, revision);
752+
} else if (implement) {
753+
/* prefer the implemented module instead of the latest one */
754+
*mod = (struct lys_module*)ly_ctx_get_module_implemented(ctx, name);
755+
if (!*mod) {
756+
/* there is no implemented module in the context, try to get the latest revision module */
757+
goto latest_in_the_context;
758+
}
751759
} else {
760+
/* get the requested module of the latest revision in the context */
761+
latest_in_the_context:
752762
*mod = (struct lys_module*)ly_ctx_get_module_latest(ctx, name);
753763
}
754764
}

src/tree_schema_internal.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,9 @@ LY_ERR lysp_type_find(const char *id, struct lysp_node *start_node, struct lysp_
129129
* @param[in] ctx libyang context.
130130
* @param[in] name Name of the module to load.
131131
* @param[in] revison Optional revision of the module to load. If NULL, the newest revision is loaded.
132-
* @param[in] implement Flag if the loaded module is supposed to be marked as implemented.
132+
* @param[in] implement Flag if the loaded module is supposed to be marked as implemented. If revision is NULL and implement flag set,
133+
* the implemented module in the context is returned despite it might not be of the latest revision, because in this case the module
134+
* of the latest revision can not be made implemented.
133135
* @param[in] require_parsed Flag to require parsed module structure in case the module is already in the context,
134136
* but only the compiled structure is available.
135137
* @param[out] mod Parsed module structure.

tools/config.h.in

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* @file config.h
3+
* @author Radek Krejci <[email protected]>
4+
* @brief various variables detected by cmake
5+
*
6+
* Copyright (c) 2019 CESNET, z.s.p.o.
7+
*
8+
* This source code is licensed under BSD 3-Clause License (the "License").
9+
* You may not use this file except in compliance with the License.
10+
* You may obtain a copy of the License at
11+
*
12+
* https://opensource.org/licenses/BSD-3-Clause
13+
*/
14+
15+
#ifndef YANGLINT_CONFIG_H_
16+
#define YANGLINT_CONFIG_H_
17+
18+
#define _DEFAULT_SOURCE
19+
#define _GNU_SOURCE
20+
21+
#define PROJECT_VERSION "@LIBYANG_VERSION@" /**< libyang project version string */
22+
23+
#endif /* YANGLINT_CONFIG_H_ */

0 commit comments

Comments
 (0)