blob: bacf136a564dc1b54c0b9aade3acdab1a660d083 [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;
Radek Krejcie7b95092019-05-15 11:03:07 +020048 case LYS_OUT_YIN:
FredGand944bdc2019-11-05 21:57:07 +080049 ret = yin_print_parsed(out, module);
Radek Krejcie7b95092019-05-15 11:03:07 +020050 break;
FredGand944bdc2019-11-05 21:57:07 +080051 /* TODO not yet implemented
Radek Krejcie7b95092019-05-15 11:03:07 +020052 case LYS_OUT_TREE:
53 ret = tree_print_model(out, module, target_node, line_length, options);
54 break;
55 case LYS_OUT_INFO:
56 ret = info_print_model(out, module, target_node);
57 break;
58 case LYS_OUT_JSON:
59 ret = jsons_print_model(out, module, target_node);
60 break;
61 */
62 default:
63 LOGERR(module->ctx, LY_EINVAL, "Unknown output format.");
64 ret = LY_EINVAL;
65 break;
66 }
67
68 return ret;
69}
70
71API ssize_t
72lys_print_file(FILE *f, const struct lys_module *module, LYS_OUTFORMAT format, int line_length, int options)
73{
74 struct lyout out;
75 LY_ERR ret;
76
77 LY_CHECK_ARG_RET(NULL, f, module, LY_EINVAL);
78
79 memset(&out, 0, sizeof out);
80 out.ctx = module->ctx;
81 out.type = LYOUT_STREAM;
82 out.method.f = f;
83
84 ret = lys_print_(&out, module, format, line_length, options);
85 if (ret) {
86 /* error */
87 return (-1) * ret;
88 } else {
89 /* success */
90 return (ssize_t)out.printed;
91 }
92}
93
94API ssize_t
95lys_print_path(const char *path, const struct lys_module *module, LYS_OUTFORMAT format, int line_length, int options)
96{
97 FILE *f;
98 ssize_t ret;
99
100 LY_CHECK_ARG_RET(NULL, path, module, LY_EINVAL);
101
102 f = fopen(path, "w");
103 if (!f) {
104 LOGERR(module->ctx, LY_ESYS, "Failed to open file \"%s\" (%s).", path, strerror(errno));
105 return LY_ESYS;
106 }
107
108 ret = lys_print_file(f, module, format, line_length, options);
109 fclose(f);
110 return ret;
111}
112
113API ssize_t
114lys_print_fd(int fd, const struct lys_module *module, LYS_OUTFORMAT format, int line_length, int options)
115{
116 LY_ERR ret;
117 struct lyout out;
118
119 LY_CHECK_ARG_RET(NULL, fd >= 0, module, LY_EINVAL);
120
121 memset(&out, 0, sizeof out);
122 out.ctx = module->ctx;
123 out.type = LYOUT_FD;
124 out.method.fd = fd;
125
126 ret = lys_print_(&out, module, format, line_length, options);
127
128 if (out.type == LYOUT_FDSTREAM) {
129 /* close temporary stream based on the given file descriptor */
130 fclose(out.method.f);
131 /* move the original file descriptor to the end of the output file */
132 lseek(fd, 0, SEEK_END);
133 }
134
135 if (ret) {
136 /* error */
137 return (-1) * ret;
138 } else {
139 /* success */
140 return (ssize_t)out.printed;
141 }
142}
143
144API ssize_t
145lys_print_mem(char **strp, const struct lys_module *module, LYS_OUTFORMAT format, int line_length, int options)
146{
147 struct lyout out;
148 LY_ERR ret;
149
150 LY_CHECK_ARG_RET(NULL, strp, module, LY_EINVAL);
151
152 memset(&out, 0, sizeof out);
153 out.ctx = module->ctx;
154 out.type = LYOUT_MEMORY;
155
156 ret = lys_print_(&out, module, format, line_length, options);
157 if (ret) {
158 /* error */
159 *strp = NULL;
160 return (-1) * ret;
161 } else {
162 /* success */
163 *strp = out.method.mem.buf;
164 return (ssize_t)out.printed;
165 }
166}
167
168API ssize_t
169lys_print_clb(ssize_t (*writeclb)(void *arg, const void *buf, size_t count), void *arg, const struct lys_module *module,
170 LYS_OUTFORMAT format, int line_length, int options)
171{
172 LY_ERR ret;
173 struct lyout out;
174
175 LY_CHECK_ARG_RET(NULL, writeclb, module, LY_EINVAL);
176
177 memset(&out, 0, sizeof out);
178 out.ctx = module->ctx;
179 out.type = LYOUT_CALLBACK;
180 out.method.clb.f = writeclb;
181 out.method.clb.arg = arg;
182
183 ret = lys_print_(&out, module, format, line_length, options);
184 if (ret) {
185 /* error */
186 return (-1) * ret;
187 } else {
188 /* success */
189 return (ssize_t)out.printed;
190 }
191}