Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 44 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ set(format_sources
src/*.h
src/plugins_exts/*
src/plugins_types/*)

#
# options
#
Expand All @@ -249,6 +250,7 @@ option(ENABLE_YANGLINT_INTERACTIVE "Enable interactive CLI yanglint" ON)
option(ENABLE_TOOLS "Build binary tools 'yanglint' and 'yangre'" ON)
option(ENABLE_COMMON_TARGETS "Define common custom target names such as 'doc' or 'uninstall', may cause conflicts when using add_subdirectory() to build this project" ON)
option(BUILD_SHARED_LIBS "By default, shared libs are enabled. Turn off for a static build." ON)
option(ENABLE_CBOR_SUPPORT "Enable CBOR support with libcbor" ON)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, an option is probably redundant. You can just search for libcbor and if found, the support will be added, otherwise not.

set(YANG_MODULE_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/yang/modules/libyang" CACHE STRING "Directory where to copy the YANG modules to")

if(ENABLE_INTERNAL_DOCS)
Expand Down Expand Up @@ -316,6 +318,42 @@ if(ENABLE_COVERAGE)
gen_coverage_enable(${ENABLE_TESTS})
endif()

if(ENABLE_CBOR_SUPPORT)
find_package(PkgConfig)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is pkg-config really required? We have used it only when necessary, the else() branch should be fine except may be better to add a new FindCBOR.cmake module file.

if(PKG_CONFIG_FOUND)
pkg_check_modules(LIBCBOR REQUIRED libcbor)
if(LIBCBOR_FOUND)
message(STATUS "libcbor found, enabling CBOR support")
add_definitions(-DENABLE_CBOR_SUPPORT)
include_directories(${LIBCBOR_INCLUDE_DIRS})
# Add CBOR parser files to the library sources
list(APPEND libsrc src/parser_cbor.c src/lcbor.c src/printer_cbor.c)
list(APPEND headers src/lcbor.h)
# Add CBOR files to format sources
list(APPEND format_sources src/parser_cbor.c src/lcbor.h src/lcbor.c src/printer_cbor.c)
else()
message(FATAL_ERROR "libcbor not found! Please install libcbor development package or disable CBOR support with -DENABLE_CBOR_SUPPORT=OFF")
endif()
else()
# Fallback to find_path and find_library if pkg-config is not available
find_path(LIBCBOR_INCLUDE_DIR cbor.h)
find_library(LIBCBOR_LIBRARY cbor)
if(LIBCBOR_INCLUDE_DIR AND LIBCBOR_LIBRARY)
message(STATUS "libcbor found via find_path/find_library, enabling CBOR support")
add_definitions(-DENABLE_CBOR_SUPPORT)
include_directories(${LIBCBOR_INCLUDE_DIR})
set(LIBCBOR_LIBRARIES ${LIBCBOR_LIBRARY})
# Add CBOR parser files to the library sources
list(APPEND libsrc src/parser_cbor.c src/lcbor.c src/printer_cbor.c)
list(APPEND headers src/lcbor.h)
# Add CBOR files to format sources
list(APPEND format_sources src/parser_cbor.c src/lcbor.h src/lcbor.c src/printer_cbor.c)
else()
message(FATAL_ERROR "libcbor not found! Please install libcbor development package or disable CBOR support with -DENABLE_CBOR_SUPPORT=OFF")
endif()
endif()
endif()

if ("${BUILD_TYPE_UPPER}" STREQUAL "DEBUG")
# enable before adding tests to let them detect that format checking is available - one of the tests is format checking
source_format_enable(0.77)
Expand Down Expand Up @@ -408,6 +446,11 @@ find_package(PCRE2 10.21 REQUIRED)
include_directories(${PCRE2_INCLUDE_DIRS})
target_link_libraries(yang ${PCRE2_LIBRARIES})

# link libcbor if CBOR support is enabled
if(ENABLE_CBOR_SUPPORT)
target_link_libraries(yang ${LIBCBOR_LIBRARIES})
endif()

# XXHash include and library
find_package(XXHash)
if(XXHASH_FOUND)
Expand Down Expand Up @@ -497,4 +540,4 @@ add_custom_target(cclean
COMMAND make clean
COMMAND find . -iname '*cmake*' -not -name CMakeLists.txt -not -path './CMakeModules*' -exec rm -rf {} +
COMMAND rm -rf Makefile Doxyfile
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
131 changes: 131 additions & 0 deletions src/lcbor.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/**
* @file lcbor.h
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just cbor.c would probably fit better, like lyb.c and lyb.h.

* @author MeherRushi <[email protected]>
* @brief CBOR data parser for libyang (abstraction over libcbor)
*
* Copyright (c) 2020 - 2023 CESNET, z.s.p.o.
*
* This source code is licensed under BSD 3-Clause License (the "License").
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*/

#ifdef ENABLE_CBOR_SUPPORT
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems redundant if the define is around the whole file, the file should just not be compiled at all if disabled. In all the new files.


#include <assert.h>
#include <ctype.h>
#include <errno.h>

#include "in_internal.h"
#include "lcbor.h"
#include "log.h"
#include "ly_common.h"

const char *
lycbor_token2str(enum cbor_type cbortype)
{
switch (cbortype) {
case CBOR_TYPE_UINT:
return "unsigned integer";
case CBOR_TYPE_NEGINT:
return "negative integer";
case CBOR_TYPE_BYTESTRING:
return "byte string";
case CBOR_TYPE_STRING:
return "string";
case CBOR_TYPE_ARRAY:
return "array";
case CBOR_TYPE_MAP:
return "map";
case CBOR_TYPE_TAG:
return "tag";
case CBOR_TYPE_FLOAT_CTRL:
return "decimals and special values (true, false, nil, ...)";
}

return "";
}

/**
* @brief Free CBOR context.
*
* @param[in] cborctx CBOR context to free.
*/
void lycbor_ctx_free(struct lycbor_ctx *cborctx)
{
if (cborctx)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant if and maybe the whole function.

{
free(cborctx);
}
}

/**
* @brief Detect CBOR format variant from input data.
*
* @param[in] in Input structure to analyze.
* @param[out] format Detected format.
* @return LY_ERR value.
*/
static LY_ERR
lydcbor_detect_format(struct ly_in *in, enum lyd_cbor_format *format)
{
/* Simple heuristic: try to parse as CBOR and examine structure */
/* For now, default to named format */
(void)in;
*format = LYD_CBOR_NAMED;
return LY_SUCCESS;
}

/**
* @brief Create new CBOR context for parsing.
*
* @param[in] ctx libyang context.
* @param[in] in Input handler.
* @param[out] cborctx_p Pointer to store the created CBOR context.
* @return LY_ERR value.
*/
LY_ERR
lycbor_ctx_new(const struct ly_ctx *ctx, struct ly_in *in, struct lycbor_ctx **cborctx_p)
{
/* TODO : Need to restructure error handling here */
LY_ERR ret = LY_SUCCESS;
struct lycbor_ctx *cborctx;
struct cbor_load_result result = {0};
enum lyd_cbor_format format;

assert(ctx && in && cborctx_p);

/* TODO : error handling after the detect_format function call */
ret = lydcbor_detect_format(in, &format);

/* Allocate and initialize CBOR context */
cborctx = calloc(1, sizeof *cborctx);
LY_CHECK_ERR_RET(!cborctx, LOGMEM(ctx), LY_EMEM);
cborctx->ctx = ctx;
cborctx->in = in;
cborctx->format = format;

/* load and parse CBOR data */
cborctx->cbor_data = cbor_load(in->current, in->length, &result);
if (!cborctx->cbor_data) {
LOGVAL(ctx, LYVE_SYNTAX, "Failed to parse CBOR data.");
free(cborctx);
return LY_EVALID;
}
if (result.error.code != CBOR_ERR_NONE) {
LOGVAL(ctx, LYVE_SYNTAX, "CBOR parsing error (code %d).", result.error.code);
cbor_decref(&cborctx->cbor_data);
free(cborctx);
return LY_EVALID;
}

/* input line logging */
ly_log_location(NULL, NULL, NULL, in);

*cborctx_p = cborctx;
return ret;
}

#endif /* ENABLE_CBOR_SUPPORT */
77 changes: 77 additions & 0 deletions src/lcbor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
* @file lcbor.h
* @author MeherRushi <[email protected]>
* @brief CBOR data parser routines for libyang (abstraction over libcbor)
*
* Copyright (c) 2020 - 2023 CESNET, z.s.p.o.
*
* This source code is licensed under BSD 3-Clause License (the "License").
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*/

#ifndef LY_LCBOR_H_
#define LY_LCBOR_H_

#ifdef ENABLE_CBOR_SUPPORT

#include <stddef.h>
#include <stdint.h>
/* using libcbor as the low-level parser */
#include <cbor.h>


#include "log.h"
#include "set.h"

struct ly_ctx;
struct ly_in;

/**
* @brief CBOR format variants for different encoding schemes
*/
enum lyd_cbor_format
{
LYD_CBOR_NAMED, /**< CBOR with named identifiers (JSON-like) */
LYD_CBOR_SID /**< CBOR with Schema Item identifiers (future implementation) */
};

struct lycbor_ctx {
const struct ly_ctx *ctx; /**< libyang context */
struct ly_in *in; /**< input structure */

cbor_item_t *cbor_data; /**< parsed CBOR data */

enum lyd_cbor_format format; /**< CBOR format variant */

struct {
cbor_item_t *cbor_data; /**< parsed CBOR data */
enum lyd_cbor_format format; /**< CBOR format variant */
const char *input;
} backup;
};

/**
* @brief Create new CBOR context for parsing.
*
* @param[in] ctx libyang context.
* @param[in] in Input handler.
* @param[out] cborctx_p Pointer to store the created CBOR context.
* @return LY_ERR value.
*/
LY_ERR
lycbor_ctx_new(const struct ly_ctx *ctx, struct ly_in *in, struct lycbor_ctx **cborctx_p);

/**
* @brief Free CBOR context.
*
* @param[in] cborctx CBOR context to free.
*/
void
lycbor_ctx_free(struct lycbor_ctx *cborctx);

#endif /* ENABLE_CBOR_SUPPORT */

#endif /* LY_LCBOR_H_ */
1 change: 1 addition & 0 deletions src/log.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ typedef enum {
LYVE_SEMANTICS, /**< generic semantic error */
LYVE_SYNTAX_XML, /**< XML-related syntax error */
LYVE_SYNTAX_JSON, /**< JSON-related syntax error */
LYVE_SYNTAX_CBOR, /**< CBOR-related syntax error */
LYVE_DATA, /**< YANG data does not reflect some of the module restrictions */

LYVE_OTHER /**< Unknown error */
Expand Down
Loading
Loading