]>
git.proxmox.com Git - mirror_frr.git/blob - tools/gen_northbound_callbacks.c
2 * Copyright (C) 2018 NetDEF, Inc.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 #define REALLY_NEED_PLAIN_GETOPT 1
27 #include "northbound.h"
29 static void __attribute__((noreturn
)) usage(int status
)
31 extern const char *__progname
;
32 fprintf(stderr
, "usage: %s [-h] [-p path] MODULE\n", __progname
);
36 static struct nb_callback_info
{
40 char return_value
[32];
44 .operation
= NB_OP_CREATE
,
45 .return_type
= "int ",
46 .return_value
= "NB_OK",
48 "enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource",
51 .operation
= NB_OP_MODIFY
,
52 .return_type
= "int ",
53 .return_value
= "NB_OK",
55 "enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource",
58 .operation
= NB_OP_DESTROY
,
59 .return_type
= "int ",
60 .return_value
= "NB_OK",
62 "enum nb_event event, const struct lyd_node *dnode",
65 .operation
= NB_OP_MOVE
,
66 .return_type
= "int ",
67 .return_value
= "NB_OK",
69 "enum nb_event event, const struct lyd_node *dnode",
72 .operation
= NB_OP_APPLY_FINISH
,
74 .return_type
= "void ",
76 .arguments
= "const struct lyd_node *dnode",
79 .operation
= NB_OP_GET_ELEM
,
80 .return_type
= "struct yang_data *",
81 .return_value
= "NULL",
82 .arguments
= "const char *xpath, const void *list_entry",
85 .operation
= NB_OP_GET_NEXT
,
86 .return_type
= "const void *",
87 .return_value
= "NULL",
89 "const void *parent_list_entry, const void *list_entry",
92 .operation
= NB_OP_GET_KEYS
,
93 .return_type
= "int ",
94 .return_value
= "NB_OK",
96 "const void *list_entry, struct yang_list_keys *keys",
99 .operation
= NB_OP_LOOKUP_ENTRY
,
100 .return_type
= "const void *",
101 .return_value
= "NULL",
103 "const void *parent_list_entry, const struct yang_list_keys *keys",
106 .operation
= NB_OP_RPC
,
107 .return_type
= "int ",
108 .return_value
= "NB_OK",
110 "const char *xpath, const struct list *input, struct list *output",
118 static void replace_hyphens_by_underscores(char *str
)
123 while ((p
= strchr(p
, '-')) != NULL
)
127 static void generate_callback_name(struct lys_node
*snode
,
128 enum nb_operation operation
, char *buffer
,
135 for (; snode
; snode
= lys_parent(snode
)) {
136 /* Skip schema-only snodes. */
137 if (CHECK_FLAG(snode
->nodetype
, LYS_USES
| LYS_CHOICE
| LYS_CASE
142 listnode_add_head(snodes
, snode
);
145 memset(buffer
, 0, size
);
146 for (ALL_LIST_ELEMENTS_RO(snodes
, ln
, snode
)) {
147 strlcat(buffer
, snode
->name
, size
);
148 strlcat(buffer
, "_", size
);
150 strlcat(buffer
, nb_operation_name(operation
), size
);
151 list_delete(&snodes
);
153 replace_hyphens_by_underscores(buffer
);
156 static void generate_callback(const struct nb_callback_info
*ncinfo
,
159 printf("static %s%s(%s)\n{\n",
160 ncinfo
->return_type
, cb_name
, ncinfo
->arguments
);
162 switch (ncinfo
->operation
) {
167 printf("\tswitch (event) {\n"
168 "\tcase NB_EV_VALIDATE:\n"
169 "\tcase NB_EV_PREPARE:\n"
170 "\tcase NB_EV_ABORT:\n"
171 "\tcase NB_EV_APPLY:\n"
172 "\t\t/* TODO: implement me. */\n"
179 printf("\t/* TODO: implement me. */\n");
183 printf("\treturn %s;\n}\n\n", ncinfo
->return_value
);
186 static int generate_callbacks(const struct lys_node
*snode
, void *arg
)
190 switch (snode
->nodetype
) {
199 return YANG_ITER_CONTINUE
;
202 for (struct nb_callback_info
*cb
= &nb_callbacks
[0];
203 cb
->operation
!= -1; cb
++) {
204 char cb_name
[BUFSIZ
];
207 || !nb_operation_is_valid(cb
->operation
, snode
))
211 char xpath
[XPATH_MAXLEN
];
213 yang_snode_get_path(snode
, YANG_PATH_DATA
, xpath
,
223 generate_callback_name((struct lys_node
*)snode
, cb
->operation
,
224 cb_name
, sizeof(cb_name
));
225 generate_callback(cb
, cb_name
);
228 return YANG_ITER_CONTINUE
;
231 static int generate_nb_nodes(const struct lys_node
*snode
, void *arg
)
235 switch (snode
->nodetype
) {
244 return YANG_ITER_CONTINUE
;
247 for (struct nb_callback_info
*cb
= &nb_callbacks
[0];
248 cb
->operation
!= -1; cb
++) {
249 char cb_name
[BUFSIZ
];
252 || !nb_operation_is_valid(cb
->operation
, snode
))
256 char xpath
[XPATH_MAXLEN
];
258 yang_snode_get_path(snode
, YANG_PATH_DATA
, xpath
,
262 "\t\t\t.xpath = \"%s\",\n",
264 printf("\t\t\t.cbs = {\n");
268 generate_callback_name((struct lys_node
*)snode
, cb
->operation
,
269 cb_name
, sizeof(cb_name
));
270 printf("\t\t\t\t.%s = %s,\n", nb_operation_name(cb
->operation
),
279 return YANG_ITER_CONTINUE
;
282 int main(int argc
, char *argv
[])
284 const char *search_path
= NULL
;
285 struct yang_module
*module
;
286 char module_name_underscores
[64];
290 while ((opt
= getopt(argc
, argv
, "hp:")) != -1) {
296 if (stat(optarg
, &st
) == -1) {
298 "error: invalid search path '%s': %s\n",
299 optarg
, strerror(errno
));
302 if (S_ISDIR(st
.st_mode
) == 0) {
304 "error: search path is not directory");
308 search_path
= optarg
;
323 ly_ctx_set_searchdir(ly_native_ctx
, search_path
);
325 /* Load all FRR native models to ensure all augmentations are loaded. */
326 yang_module_load_all();
327 module
= yang_module_find(argv
[0]);
329 /* Non-native FRR module (e.g. modules from unit tests). */
330 module
= yang_module_load(argv
[0]);
332 /* Create a nb_node for all YANG schema nodes. */
335 /* Generate callback functions. */
336 yang_snodes_iterate_module(module
->info
, generate_callbacks
, 0, NULL
);
338 strlcpy(module_name_underscores
, module
->name
,
339 sizeof(module_name_underscores
));
340 replace_hyphens_by_underscores(module_name_underscores
);
342 /* Generate frr_yang_module_info array. */
343 printf("/* clang-format off */\n"
344 "const struct frr_yang_module_info %s_info = {\n"
345 "\t.name = \"%s\",\n"
347 module_name_underscores
, module
->name
);
348 yang_snodes_iterate_module(module
->info
, generate_nb_nodes
, 0, NULL
);
350 "\t\t\t.xpath = NULL,\n"
355 /* Cleanup and exit. */