Michal Vasko | 1324b6c | 2018-09-07 11:16:23 +0200 | [diff] [blame] | 1 | /** |
| 2 | * @file common.c |
| 3 | * @author Michal Vasko <mvasko@cesnet.cz> |
| 4 | * @brief common internal definitions for libyang |
| 5 | * |
| 6 | * Copyright (c) 2018 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 | */ |
Michal Vasko | 841d1a9 | 2018-09-07 15:40:31 +0200 | [diff] [blame] | 14 | #define _XOPEN_SOURCE |
Michal Vasko | 1324b6c | 2018-09-07 11:16:23 +0200 | [diff] [blame] | 15 | |
| 16 | #include <stdlib.h> |
Michal Vasko | 841d1a9 | 2018-09-07 15:40:31 +0200 | [diff] [blame] | 17 | #include <stdio.h> |
| 18 | #include <ctype.h> |
| 19 | #include <string.h> |
| 20 | #include <time.h> |
| 21 | |
Michal Vasko | 5825771 | 2018-09-12 11:11:38 +0200 | [diff] [blame] | 22 | #include "common.h" |
Michal Vasko | 841d1a9 | 2018-09-07 15:40:31 +0200 | [diff] [blame] | 23 | #include "tree_schema.h" |
Michal Vasko | 1324b6c | 2018-09-07 11:16:23 +0200 | [diff] [blame] | 24 | |
Radek Krejci | c59bc97 | 2018-09-17 16:13:06 +0200 | [diff] [blame] | 25 | const char *const ly_stmt_list[] = { |
| 26 | [YANG_ACTION] = "action", |
| 27 | [YANG_ANYDATA] = "anydata", |
| 28 | [YANG_ANYXML] = "anyxml", |
| 29 | [YANG_ARGUMENT] = "argument", |
| 30 | [YANG_AUGMENT] = "augment", |
| 31 | [YANG_BASE] = "base", |
| 32 | [YANG_BELONGS_TO] = "belongs-to", |
| 33 | [YANG_BIT] = "bit", |
| 34 | [YANG_CASE] = "case", |
| 35 | [YANG_CHOICE] = "choice", |
| 36 | [YANG_CONFIG] = "config", |
| 37 | [YANG_CONTACT] = "contact", |
| 38 | [YANG_CONTAINER] = "container", |
| 39 | [YANG_CUSTOM] = "<extension-instance>", |
| 40 | [YANG_DEFAULT] = "default", |
| 41 | [YANG_DESCRIPTION] = "description", |
| 42 | [YANG_DEVIATE] = "deviate", |
| 43 | [YANG_DEVIATION] = "deviation", |
| 44 | [YANG_ENUM] = "enum", |
| 45 | [YANG_ERROR_APP_TAG] = "error-app-tag", |
| 46 | [YANG_ERROR_MESSAGE] = "error-message", |
| 47 | [YANG_EXTENSION] = "extension", |
| 48 | [YANG_FEATURE] = "feature", |
| 49 | [YANG_FRACTION_DIGITS] = "fraction-digits", |
| 50 | [YANG_GROUPING] = "grouping", |
| 51 | [YANG_IDENTITY] = "identitiy", |
| 52 | [YANG_IF_FEATURE] = "if-feature", |
| 53 | [YANG_IMPORT] = "import", |
| 54 | [YANG_INCLUDE] = "include", |
| 55 | [YANG_INPUT] = "input", |
| 56 | [YANG_KEY] = "key", |
| 57 | [YANG_LEAF] = "leaf", |
| 58 | [YANG_LEAF_LIST] = "leaf-list", |
| 59 | [YANG_LENGTH] = "length", |
| 60 | [YANG_LIST] = "list", |
| 61 | [YANG_MANDATORY] = "mandatory", |
| 62 | [YANG_MAX_ELEMENTS] = "max-elements", |
| 63 | [YANG_MIN_ELEMENTS] = "min-elements", |
| 64 | [YANG_MODIFIER] = "modifier", |
| 65 | [YANG_MODULE] = "module", |
| 66 | [YANG_MUST] = "must", |
| 67 | [YANG_NAMESPACE] = "namespace", |
| 68 | [YANG_NOTIFICATION] = "notification", |
| 69 | [YANG_ORDERED_BY] = "ordered-by", |
| 70 | [YANG_ORGANIZATION] = "organization", |
| 71 | [YANG_OUTPUT] = "output", |
| 72 | [YANG_PATH] = "path", |
| 73 | [YANG_PATTERN] = "pattern", |
| 74 | [YANG_POSITION] = "position", |
| 75 | [YANG_PREFIX] = "prefix", |
| 76 | [YANG_PRESENCE] = "presence", |
| 77 | [YANG_RANGE] = "range", |
| 78 | [YANG_REFERENCE] = "reference", |
| 79 | [YANG_REFINE] = "refine", |
| 80 | [YANG_REQUIRE_INSTANCE] = "require-instance", |
| 81 | [YANG_REVISION] = "revision", |
| 82 | [YANG_REVISION_DATE] = "revision-date", |
| 83 | [YANG_RPC] = "rpc", |
| 84 | [YANG_STATUS] = "status", |
| 85 | [YANG_SUBMODULE] = "submodule", |
| 86 | [YANG_TYPE] = "type", |
| 87 | [YANG_TYPEDEF] = "typedef", |
| 88 | [YANG_UNIQUE] = "unique", |
| 89 | [YANG_UNITS] = "units", |
| 90 | [YANG_USES] = "uses", |
| 91 | [YANG_VALUE] = "value", |
| 92 | [YANG_WHEN] = "when", |
| 93 | [YANG_YANG_VERSION] = "yang-version", |
| 94 | [YANG_YIN_ELEMENT] = "yin-element", |
| 95 | [YANG_SEMICOLON] = ";", |
| 96 | [YANG_LEFT_BRACE] = "{", |
| 97 | [YANG_RIGHT_BRACE] = "}", |
| 98 | }; |
| 99 | |
| 100 | const char *const lyext_substmt_list[] = { |
| 101 | [LYEXT_SUBSTMT_ARGUMENT] = "argument", |
| 102 | [LYEXT_SUBSTMT_BASE] = "base", |
| 103 | [LYEXT_SUBSTMT_BELONGSTO] = "belongs-to", |
| 104 | [LYEXT_SUBSTMT_CONTACT] = "contact", |
| 105 | [LYEXT_SUBSTMT_DEFAULT] = "default", |
| 106 | [LYEXT_SUBSTMT_DESCRIPTION] = "description", |
| 107 | [LYEXT_SUBSTMT_ERRTAG] = "error-app-tag", |
| 108 | [LYEXT_SUBSTMT_ERRMSG] = "error-message", |
| 109 | [LYEXT_SUBSTMT_KEY] = "key", |
| 110 | [LYEXT_SUBSTMT_NAMESPACE] = "namespace", |
| 111 | [LYEXT_SUBSTMT_ORGANIZATION] = "organization", |
| 112 | [LYEXT_SUBSTMT_PATH] = "path", |
| 113 | [LYEXT_SUBSTMT_PREFIX] = "prefix", |
| 114 | [LYEXT_SUBSTMT_PRESENCE] = "presence", |
| 115 | [LYEXT_SUBSTMT_REFERENCE] = "reference", |
| 116 | [LYEXT_SUBSTMT_REVISIONDATE] = "revision-date", |
| 117 | [LYEXT_SUBSTMT_UNITS] = "units", |
| 118 | [LYEXT_SUBSTMT_VALUE] = "value", |
| 119 | [LYEXT_SUBSTMT_VERSION] = "yang-version", |
| 120 | [LYEXT_SUBSTMT_MODIFIER] = "modifier", |
| 121 | [LYEXT_SUBSTMT_REQINSTANCE] = "require-instance", |
| 122 | [LYEXT_SUBSTMT_YINELEM] = "yin-element", |
| 123 | [LYEXT_SUBSTMT_CONFIG] = "config", |
| 124 | [LYEXT_SUBSTMT_MANDATORY] = "mandatory", |
| 125 | [LYEXT_SUBSTMT_ORDEREDBY] = "ordered-by", |
| 126 | [LYEXT_SUBSTMT_STATUS] = "status", |
| 127 | [LYEXT_SUBSTMT_FRACDIGITS] = "fraction-digits", |
| 128 | [LYEXT_SUBSTMT_MAX] = "max-elements", |
| 129 | [LYEXT_SUBSTMT_MIN] = "min-elements", |
| 130 | [LYEXT_SUBSTMT_POSITION] = "position", |
| 131 | [LYEXT_SUBSTMT_UNIQUE] = "unique", |
| 132 | [LYEXT_SUBSTMT_IFFEATURE] = "if-feature", |
| 133 | }; |
| 134 | |
| 135 | const char *const ly_devmod_list[] = { |
| 136 | [LYS_DEV_NOT_SUPPORTED] = "not-supported", |
| 137 | [LYS_DEV_ADD] = "add", |
| 138 | [LYS_DEV_DELETE] = "delete", |
| 139 | [LYS_DEV_REPLACE] = "replace", |
| 140 | }; |
| 141 | |
Michal Vasko | 1324b6c | 2018-09-07 11:16:23 +0200 | [diff] [blame] | 142 | void * |
| 143 | ly_realloc(void *ptr, size_t size) |
| 144 | { |
| 145 | void *new_mem; |
| 146 | |
| 147 | new_mem = realloc(ptr, size); |
| 148 | if (!new_mem) { |
| 149 | free(ptr); |
| 150 | } |
| 151 | |
| 152 | return new_mem; |
| 153 | } |
Michal Vasko | 841d1a9 | 2018-09-07 15:40:31 +0200 | [diff] [blame] | 154 | |
Radek Krejci | d972c25 | 2018-09-25 13:23:39 +0200 | [diff] [blame] | 155 | size_t |
| 156 | LY_VCODE_INSTREXP_len(const char *str) |
| 157 | { |
| 158 | size_t len = 0; |
| 159 | if (!str) { |
| 160 | return len; |
| 161 | } else if (!str[0]) { |
| 162 | return 1; |
| 163 | } |
| 164 | for (len = 1; len < LY_VCODE_INSTREXP_MAXLEN && str[len]; ++len); |
| 165 | return len; |
| 166 | } |
| 167 | |
Radek Krejci | f345c01 | 2018-09-19 11:12:59 +0200 | [diff] [blame] | 168 | LY_ERR |
Michal Vasko | 5825771 | 2018-09-12 11:11:38 +0200 | [diff] [blame] | 169 | lysp_check_date(struct ly_ctx *ctx, const char *date, int date_len, const char *stmt) |
Michal Vasko | 841d1a9 | 2018-09-07 15:40:31 +0200 | [diff] [blame] | 170 | { |
| 171 | int i; |
| 172 | struct tm tm, tm_; |
| 173 | char *r; |
| 174 | |
Radek Krejci | f345c01 | 2018-09-19 11:12:59 +0200 | [diff] [blame] | 175 | LY_CHECK_ARG_RET(ctx, date, LY_EINVAL); |
| 176 | LY_CHECK_ERR_RET(date_len != LY_REV_SIZE - 1, LOGARG(ctx, date_len), LY_EINVAL); |
Michal Vasko | 841d1a9 | 2018-09-07 15:40:31 +0200 | [diff] [blame] | 177 | |
| 178 | /* check format */ |
| 179 | for (i = 0; i < date_len; i++) { |
| 180 | if (i == 4 || i == 7) { |
| 181 | if (date[i] != '-') { |
| 182 | goto error; |
| 183 | } |
| 184 | } else if (!isdigit(date[i])) { |
| 185 | goto error; |
| 186 | } |
| 187 | } |
| 188 | |
| 189 | /* check content, e.g. 2018-02-31 */ |
| 190 | memset(&tm, 0, sizeof tm); |
| 191 | r = strptime(date, "%Y-%m-%d", &tm); |
| 192 | if (!r || r != &date[LY_REV_SIZE - 1]) { |
| 193 | goto error; |
| 194 | } |
| 195 | memcpy(&tm_, &tm, sizeof tm); |
| 196 | mktime(&tm_); /* mktime modifies tm_ if it refers invalid date */ |
| 197 | if (tm.tm_mday != tm_.tm_mday) { /* e.g 2018-02-29 -> 2018-03-01 */ |
| 198 | /* checking days is enough, since other errors |
| 199 | * have been checked by strptime() */ |
| 200 | goto error; |
| 201 | } |
| 202 | |
Radek Krejci | f345c01 | 2018-09-19 11:12:59 +0200 | [diff] [blame] | 203 | return LY_SUCCESS; |
Michal Vasko | 841d1a9 | 2018-09-07 15:40:31 +0200 | [diff] [blame] | 204 | |
| 205 | error: |
Michal Vasko | 5825771 | 2018-09-12 11:11:38 +0200 | [diff] [blame] | 206 | LOGVAL(ctx, LY_VLOG_NONE, NULL, LY_VCODE_INVAL, date_len, date, stmt); |
Radek Krejci | f345c01 | 2018-09-19 11:12:59 +0200 | [diff] [blame] | 207 | return LY_EINVAL; |
Michal Vasko | 841d1a9 | 2018-09-07 15:40:31 +0200 | [diff] [blame] | 208 | } |