blob: c07ea79ea341f3e1eafdcabe1b062d45f714ac0c [file] [log] [blame]
Radek Krejcie7b95092019-05-15 11:03:07 +02001/**
2 * @file printer_schema.c
3 * @author Radek Krejci <rkrejci@cesnet.cz>
4 * @brief Generic schema printers functions.
5 *
6 * Copyright (c) 2015 - 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#include "common.h"
16
17#include <errno.h>
18#include <stdio.h>
19#include <string.h>
20#include <unistd.h>
21
22#include "log.h"
23#include "printer_internal.h"
24#include "tree_schema.h"
25
26/**
27 * @brief Common schema printer.
28 *
29 * @param[in] out Prepared structure defining the type and details of the printer output.
30 * @param[in] module Schema to print.
31 * @param[in] format Output format.
32 * @param[in] line_length Maximum characters to be printed on a line, 0 for unlimited. Only for #LYS_OUT_TREE printer.
33 * @param[in] options Schema output options (see @ref schemaprinterflags).
34 * @return LY_ERR value, number of the printed bytes is updated in lyout::printed.
35 */
36static LY_ERR
37lys_print_(struct lyout *out, const struct lys_module *module, LYS_OUTFORMAT format, int UNUSED(line_length), int UNUSED(options))
38{
39 LY_ERR ret;
40
41 switch (format) {
42 case LYS_OUT_YANG:
43 ret = yang_print_parsed(out, module);
44 break;
45 case LYS_OUT_YANG_COMPILED:
46 ret = yang_print_compiled(out, module);
47 break;
48 /* TODO not yet implemented
49 case LYS_OUT_YIN:
50 lys_disable_deviations((struct lys_module *)module);
51 ret = yin_print_model(out, module);
52 lys_enable_deviations((struct lys_module *)module);
53 break;
54 case LYS_OUT_TREE:
55 ret = tree_print_model(out, module, target_node, line_length, options);
56 break;
57 case LYS_OUT_INFO:
58 ret = info_print_model(out, module, target_node);
59 break;
60 case LYS_OUT_JSON:
61 ret = jsons_print_model(out, module, target_node);
62 break;
63 */
64 default:
65 LOGERR(module->ctx, LY_EINVAL, "Unknown output format.");
66 ret = LY_EINVAL;
67 break;
68 }
69
70 return ret;
71}
72
73API ssize_t
74lys_print_file(FILE *f, const struct lys_module *module, LYS_OUTFORMAT format, int line_length, int options)
75{
76 struct lyout out;
77 LY_ERR ret;
78
79 LY_CHECK_ARG_RET(NULL, f, module, LY_EINVAL);
80
81 memset(&out, 0, sizeof out);
82 out.ctx = module->ctx;
83 out.type = LYOUT_STREAM;
84 out.method.f = f;
85
86 ret = lys_print_(&out, module, format, line_length, options);
87 if (ret) {
88 /* error */
89 return (-1) * ret;
90 } else {
91 /* success */
92 return (ssize_t)out.printed;
93 }
94}
95
96API ssize_t
97lys_print_path(const char *path, const struct lys_module *module, LYS_OUTFORMAT format, int line_length, int options)
98{
99 FILE *f;
100 ssize_t ret;
101
102 LY_CHECK_ARG_RET(NULL, path, module, LY_EINVAL);
103
104 f = fopen(path, "w");
105 if (!f) {
106 LOGERR(module->ctx, LY_ESYS, "Failed to open file \"%s\" (%s).", path, strerror(errno));
107 return LY_ESYS;
108 }
109
110 ret = lys_print_file(f, module, format, line_length, options);
111 fclose(f);
112 return ret;
113}
114
115API ssize_t
116lys_print_fd(int fd, const struct lys_module *module, LYS_OUTFORMAT format, int line_length, int options)
117{
118 LY_ERR ret;
119 struct lyout out;
120
121 LY_CHECK_ARG_RET(NULL, fd >= 0, module, LY_EINVAL);
122
123 memset(&out, 0, sizeof out);
124 out.ctx = module->ctx;
125 out.type = LYOUT_FD;
126 out.method.fd = fd;
127
128 ret = lys_print_(&out, module, format, line_length, options);
129
130 if (out.type == LYOUT_FDSTREAM) {
131 /* close temporary stream based on the given file descriptor */
132 fclose(out.method.f);
133 /* move the original file descriptor to the end of the output file */
134 lseek(fd, 0, SEEK_END);
135 }
136
137 if (ret) {
138 /* error */
139 return (-1) * ret;
140 } else {
141 /* success */
142 return (ssize_t)out.printed;
143 }
144}
145
146API ssize_t
147lys_print_mem(char **strp, const struct lys_module *module, LYS_OUTFORMAT format, int line_length, int options)
148{
149 struct lyout out;
150 LY_ERR ret;
151
152 LY_CHECK_ARG_RET(NULL, strp, module, LY_EINVAL);
153
154 memset(&out, 0, sizeof out);
155 out.ctx = module->ctx;
156 out.type = LYOUT_MEMORY;
157
158 ret = lys_print_(&out, module, format, line_length, options);
159 if (ret) {
160 /* error */
161 *strp = NULL;
162 return (-1) * ret;
163 } else {
164 /* success */
165 *strp = out.method.mem.buf;
166 return (ssize_t)out.printed;
167 }
168}
169
170API ssize_t
171lys_print_clb(ssize_t (*writeclb)(void *arg, const void *buf, size_t count), void *arg, const struct lys_module *module,
172 LYS_OUTFORMAT format, int line_length, int options)
173{
174 LY_ERR ret;
175 struct lyout out;
176
177 LY_CHECK_ARG_RET(NULL, writeclb, module, LY_EINVAL);
178
179 memset(&out, 0, sizeof out);
180 out.ctx = module->ctx;
181 out.type = LYOUT_CALLBACK;
182 out.method.clb.f = writeclb;
183 out.method.clb.arg = arg;
184
185 ret = lys_print_(&out, module, format, line_length, options);
186 if (ret) {
187 /* error */
188 return (-1) * ret;
189 } else {
190 /* success */
191 return (ssize_t)out.printed;
192 }
193}