blob: 29fa079a0bf684eee79ba1a9de35f213704131dd [file] [log] [blame]
David Sedlákf824ad52018-10-14 23:58:15 +02001/**
2 * @file parser_yin.c
3 * @author David Sedlák <xsedla1d@stud.fit.vutbr.cz>
David Sedlák3b4db242018-10-19 16:11:01 +02004 * @brief YIN parser.
5 *
6 * Copyright (c) 2015 - 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
David Sedlákf824ad52018-10-14 23:58:15 +020013 */
David Sedlák3b4db242018-10-19 16:11:01 +020014#include <stdio.h>
15#include <stdlib.h>
16#include <unistd.h>
David Sedlákf824ad52018-10-14 23:58:15 +020017
18#include "common.h"
19#include "context.h"
20#include "libyang.h"
David Sedlák3b4db242018-10-19 16:11:01 +020021#include "xml.h"
22#include "tree_schema_internal.h"
23#include "string.h"
David Sedlákf824ad52018-10-14 23:58:15 +020024
25LY_ERR
David Sedlák3b4db242018-10-19 16:11:01 +020026match_argument_name()
David Sedlákf824ad52018-10-14 23:58:15 +020027{
28
29}
David Sedlák3b4db242018-10-19 16:11:01 +020030
31#define MOVE_START(array, offset) array = &array[offset];
32#define IF_KW(STR, LEN, SHIFT, STMT) if (!strncmp((word), STR, LEN)) {MOVE_START(word, SHIFT);kw=STMT;}
33#define IF_KW_PREFIX(STR, LEN, SHIFT) if (!strncmp((word), STR, LEN)) {MOVE_START(word, SHIFT);
34#define IF_KW_PREFIX_END }
35
36enum yang_keyword
37match_keyword(const char *word, size_t len)
38{
39 if (!word) {
40 return YANG_NONE;
41 }
42 enum yang_keyword kw = YANG_NONE;
43
44 /* try to match the keyword */
45 switch (*word) {
46 case 'a':
47 MOVE_START(word, 1);
48 IF_KW("rgument", len, 7, YANG_ARGUMENT)
49 else IF_KW("ugment", len, 6, YANG_AUGMENT)
50 else IF_KW("ction", len, 5, YANG_ACTION)
51 else IF_KW_PREFIX("ny", len, 2)
52 IF_KW("data", len, 4, YANG_ANYDATA)
53 else IF_KW("xml", len, 3, YANG_ANYXML)
54 IF_KW_PREFIX_END
55 break;
56 case 'b':
57 MOVE_START(word, 1);
58 IF_KW("ase", len, 3, YANG_BASE)
59 else IF_KW("elongs-to", len, 9, YANG_BELONGS_TO)
60 else IF_KW("it", len, 2, YANG_BIT)
61 break;
62 case 'c':
63 MOVE_START(word, 1);
64 IF_KW("ase", len, 3, YANG_CASE)
65 else IF_KW("hoice", len, 5, YANG_CHOICE)
66 else IF_KW_PREFIX("on", len, 2)
67 IF_KW("fig", len, 3, YANG_CONFIG)
68 else IF_KW_PREFIX("ta", len, 2)
69 IF_KW("ct", len, 2, YANG_CONTACT)
70 else IF_KW("iner", len, 4, YANG_CONTAINER)
71 IF_KW_PREFIX_END
72 IF_KW_PREFIX_END
73 break;
74 case 'd':
75 MOVE_START(word, 1);
76 IF_KW_PREFIX("e", len, 1)
77 IF_KW("fault", len, 5, YANG_DEFAULT)
78 else IF_KW("scription", len, 9, YANG_DESCRIPTION)
79 else IF_KW_PREFIX("viat", len, 4)
80 IF_KW("e", len, 1, YANG_DEVIATE)
81 else IF_KW("ion", len, 3, YANG_DEVIATION)
82 IF_KW_PREFIX_END
83 IF_KW_PREFIX_END
84 break;
85 case 'e':
86 MOVE_START(word, 1);
87 IF_KW("num", len, 3, YANG_ENUM)
88 else IF_KW_PREFIX("rror-", len, 5)
89 IF_KW("app-tag", len, 7, YANG_ERROR_APP_TAG)
90 else IF_KW("message", len, 7, YANG_ERROR_MESSAGE)
91 IF_KW_PREFIX_END
92 else IF_KW("xtension", len, 8, YANG_EXTENSION)
93 break;
94 case 'f':
95 MOVE_START(word, 1);
96 IF_KW("eature", len, 6, YANG_FEATURE)
97 else IF_KW("raction-digits", len, 14, YANG_FRACTION_DIGITS)
98 break;
99 case 'g':
100 MOVE_START(word, 1);
101 IF_KW("rouping", len, 7, YANG_GROUPING)
102 break;
103 case 'i':
104 MOVE_START(word, 1);
105 IF_KW("dentity", len, 7, YANG_IDENTITY)
106 else IF_KW("f-feature", len, 9, YANG_IF_FEATURE)
107 else IF_KW("mport", len, 5, YANG_IMPORT)
108 else IF_KW_PREFIX("n", len, 1)
109 IF_KW("clude", len, 5, YANG_INCLUDE)
110 else IF_KW("put", len, 3, YANG_INPUT)
111 IF_KW_PREFIX_END
112 break;
113 case 'k':
114 MOVE_START(word, 1);
115 IF_KW("ey", len, 2, YANG_KEY)
116 break;
117 case 'l':
118 MOVE_START(word, 1);
119 IF_KW_PREFIX("e", len, 1)
120 IF_KW("af-list", len, 7, YANG_LEAF_LIST)
121 else IF_KW("af", len, 2, YANG_LEAF)
122 else IF_KW("ngth", len, 4, YANG_LENGTH)
123 IF_KW_PREFIX_END
124 else IF_KW("ist", len, 3, YANG_LIST)
125 break;
126 case 'm':
127 MOVE_START(word, 1);
128 IF_KW_PREFIX("a", len, 1)
129 IF_KW("ndatory", len, 7, YANG_MANDATORY)
130 else IF_KW("x-elements", len, 10, YANG_MAX_ELEMENTS)
131 IF_KW_PREFIX_END
132 else IF_KW("in-elements", len, 11, YANG_MIN_ELEMENTS)
133 else IF_KW("ust", len, 3, YANG_MUST)
134 else IF_KW_PREFIX("od", len, 2)
135 IF_KW("ule", len, 3, YANG_MODULE)
136 else IF_KW("ifier", len, 5, YANG_MODIFIER)
137 IF_KW_PREFIX_END
138 break;
139 case 'n':
140 MOVE_START(word, 1);
141 IF_KW("amespace", len, 8, YANG_NAMESPACE)
142 else IF_KW("otification", len, 11, YANG_NOTIFICATION)
143 break;
144 case 'o':
145 MOVE_START(word, 1);
146 IF_KW_PREFIX("r", len, 1)
147 IF_KW("dered-by", len, 8, YANG_ORDERED_BY)
148 else IF_KW("ganization", len, 10, YANG_ORGANIZATION)
149 IF_KW_PREFIX_END
150 else IF_KW("utput", len, 5, YANG_OUTPUT)
151 break;
152 case 'p':
153 MOVE_START(word, 1);
154 IF_KW("ath", len, 3, YANG_PATH)
155 else IF_KW("attern", len, 6, YANG_PATTERN)
156 else IF_KW("osition", len, 7, YANG_POSITION)
157 else IF_KW_PREFIX("re", len, 2)
158 IF_KW("fix", len, 3, YANG_PREFIX)
159 else IF_KW("sence", len, 5, YANG_PRESENCE)
160 IF_KW_PREFIX_END
161 break;
162 case 'r':
163 MOVE_START(word, 1);
164 IF_KW("ange", len, 4, YANG_RANGE)
165 else IF_KW_PREFIX("e", len, 1)
166 IF_KW_PREFIX("f", len, 1)
167 IF_KW("erence", len, 6, YANG_REFERENCE)
168 else IF_KW("ine", len, 3, YANG_REFINE)
169 IF_KW_PREFIX_END
170 else IF_KW("quire-instance", len, 14, YANG_REQUIRE_INSTANCE)
171 else IF_KW("vision-date", len, 11, YANG_REVISION_DATE)
172 else IF_KW("vision", len, 6, YANG_REVISION)
173 IF_KW_PREFIX_END
174 else IF_KW("pc", len, 2, YANG_RPC)
175 break;
176 case 's':
177 MOVE_START(word, 1);
178 IF_KW("tatus", len, 5, YANG_STATUS)
179 else IF_KW("ubmodule", len, 8, YANG_SUBMODULE)
180 break;
181 case 't':
182 MOVE_START(word, 1);
183 IF_KW("ypedef", len, 6, YANG_TYPEDEF)
184 else IF_KW("ype", len, 3, YANG_TYPE)
185 break;
186 case 'u':
187 MOVE_START(word, 1);
188 IF_KW_PREFIX("ni", len, 2)
189 IF_KW("que", len, 3, YANG_UNIQUE)
190 else IF_KW("ts", len, 2, YANG_UNITS)
191 IF_KW_PREFIX_END
192 else IF_KW("ses", len, 3, YANG_USES)
193 break;
194 case 'v':
195 MOVE_START(word, 1);
196 IF_KW("alue", len, 4, YANG_VALUE)
197 break;
198 case 'w':
199 MOVE_START(word, 1);
200 IF_KW("hen", len, 3, YANG_WHEN)
201 break;
202 case 'y':
203 MOVE_START(word, 1);
204 IF_KW("ang-version", len, 11, YANG_YANG_VERSION)
205 else IF_KW("in-element", len, 10, YANG_YIN_ELEMENT)
206 break;
207 default:
208 break;
209 }
210
211 return kw;
212}
213
214LY_ERR
215parse_submodule(struct lyxml_context *xml_ctx, const char **data, struct lysp_module **mod_p)
216{
217 LY_ERR ret = 0;
218
219 const char *prefix, *name, *elem;
220 size_t prefix_len, name_len;
221
222 /* inefficient keyword check - just temporary */
223 ret = lyxml_get_element(xml_ctx, data, &prefix, &prefix_len, &name, &name_len);
224 LY_CHECK_ERR_RET(ret != LY_SUCCESS, LOGMEM(xml_ctx->ctx), LY_EMEM);
225 if ((strncmp("module", name, name_len) != 0) && (strncmp("submodule", name, name_len) != 0)) {
226 LOGVAL(xml_ctx->ctx, xml_ctx->line, &xml_ctx->line, LYVE_SYNTAX, "Invalid keyword \"%s\", expected \"module\" or \"submodule\".", name);
227 }
228
229 /* inefficient argument name check - just temporary */
230 ret = lyxml_get_attribute(xml_ctx, data, &prefix, &prefix_len, &name, &name_len);
231 LY_CHECK_ERR_RET(ret != LY_SUCCESS, LOGMEM(xml_ctx->ctx), LY_EMEM);
232 if (strncmp("name", name, name_len)) {
233 LOGVAL(xml_ctx->ctx, xml_ctx->line, &xml_ctx->line, LYVE_SYNTAX, "Invalid argument name \"%s\", expected \"name\".", name);
234 }
235
236 char *buf = NULL, *out = NULL;
237 size_t buf_len = 0, out_len = 0;
238 int dynamic;
239
240 ret = lyxml_get_string(xml_ctx, data, &buf, &buf_len, &out, &out_len, &dynamic);
241 LY_CHECK_ERR_RET(ret != LY_SUCCESS, LOGMEM(xml_ctx->ctx), LY_EMEM);
242
243 (*mod_p)->name = lydict_insert(xml_ctx->ctx, out, out_len);
244 return 0;
245}
246
247LY_ERR
248yin_parse(struct ly_ctx *ctx, const char *data, struct lysp_module **mod_p)
249{
250 LY_ERR ret = 0;
251 struct ly_parser_ctx context = {0};
252
253 struct lyxml_context xml_ctx;
254 xml_ctx.ctx = ctx;
255
256 const char *prefix, *name, *elem;
257 size_t prefix_len, name_len;
258
259 parse_submodule(&xml_ctx, &data, mod_p);
260
261 return LY_SUCCESS;
262}