blob: b0c188b9bff18b1f8dbd36d3d59f3a1e7419e595 [file] [log] [blame]
Radek Krejcia5bba312020-01-09 15:41:20 +01001/**
2 * @file printer.h
3 * @author Radek Krejci <rkrejci@cesnet.cz>
4 * @brief Generic libyang printer structures and 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#ifndef LY_PRINTER_H_
16#define LY_PRINTER_H_
17
Radek Krejci535ea9f2020-05-29 16:01:05 +020018#include <stdio.h>
Radek Krejcia5bba312020-01-09 15:41:20 +010019#include <unistd.h>
20
Radek Krejci535ea9f2020-05-29 16:01:05 +020021#include "log.h"
22
Radek Krejcia5bba312020-01-09 15:41:20 +010023/**
24 * @brief Printer output structure specifying where the data are printed.
25 */
Radek Krejci241f6b52020-05-21 18:13:49 +020026struct ly_out;
Radek Krejcia5bba312020-01-09 15:41:20 +010027
28/**
29 * @brief Types of the printer's output
30 */
Radek Krejci241f6b52020-05-21 18:13:49 +020031typedef enum LY_OUT_TYPE {
32 LY_OUT_ERROR = -1, /**< error value to indicate failure of the functions returning LY_OUT_TYPE */
33 LY_OUT_FD, /**< file descriptor printer */
34 LY_OUT_FDSTREAM, /**< internal replacement for LY_OUT_FD in case vdprintf() is not available */
35 LY_OUT_FILE, /**< FILE stream printer */
36 LY_OUT_FILEPATH, /**< filepath printer */
37 LY_OUT_MEMORY, /**< memory printer */
38 LY_OUT_CALLBACK /**< callback printer */
39} LY_OUT_TYPE;
Radek Krejcia5bba312020-01-09 15:41:20 +010040
41/**
42 * @brief Get output type of the printer handler.
43 *
44 * @param[in] out Printer handler.
45 * @return Type of the printer's output.
46 */
Radek Krejci241f6b52020-05-21 18:13:49 +020047LY_OUT_TYPE ly_out_type(const struct ly_out *out);
Radek Krejcia5bba312020-01-09 15:41:20 +010048
49/**
50 * @brief Reset the output medium to write from its beginning, so the following printer function will rewrite the current data
51 * instead of appending.
52 *
53 * Note that in case the underlying output is not seekable (stream referring a pipe/FIFO/socket or the callback output type),
54 * nothing actually happens despite the function succeeds. Also note that the medium is not returned to the state it was when
55 * the handler was created. For example, file is seeked into the offset zero, not to the offset where it was opened when
Radek Krejci241f6b52020-05-21 18:13:49 +020056 * ly_out_new_file() was called.
Radek Krejcia5bba312020-01-09 15:41:20 +010057 *
58 * @param[in] out Printer handler.
59 * @return LY_SUCCESS in case of success
60 * @return LY_ESYS in case of failure
61 */
Radek Krejci241f6b52020-05-21 18:13:49 +020062LY_ERR ly_out_reset(struct ly_out *out);
Radek Krejcia5bba312020-01-09 15:41:20 +010063
64/**
65 * @brief Create printer handler using callback printer function.
66 *
67 * @param[in] writeclb Pointer to the printer callback function writing the data (see write(2)).
68 * @param[in] arg Optional caller-specific argument to be passed to the @p writeclb callback.
69 * @return NULL in case of memory allocation error.
70 * @return Created printer handler supposed to be passed to different ly*_print_*() functions.
71 */
Radek Krejci241f6b52020-05-21 18:13:49 +020072struct ly_out *ly_out_new_clb(ssize_t (*writeclb)(void *arg, const void *buf, size_t count), void *arg);
Radek Krejcia5bba312020-01-09 15:41:20 +010073
74/**
75 * @brief Get or reset callback function associated with a callback printer handler.
76 *
77 * @param[in] out Printer handler.
78 * @param[in] fd Optional value of a new file descriptor for the handler. If -1, only the current file descriptor value is returned.
79 * @return Previous value of the file descriptor.
80 */
Radek Krejci241f6b52020-05-21 18:13:49 +020081ssize_t (*ly_out_clb(struct ly_out *out, ssize_t (*writeclb)(void *arg, const void *buf, size_t count)))(void *arg, const void *buf, size_t count);
Radek Krejcia5bba312020-01-09 15:41:20 +010082
83/**
84 * @brief Get or reset callback function's argument aasociated with a callback printer handler.
85 *
86 * @param[in] out Printer handler.
87 * @param[in] arg caller-specific argument to be passed to the callback function associated with the printer handler.
88 * If NULL, only the current file descriptor value is returned.
89 * @return The previous callback argument.
90 */
Radek Krejci241f6b52020-05-21 18:13:49 +020091void *ly_out_clb_arg(struct ly_out *out, void *arg);
Radek Krejcia5bba312020-01-09 15:41:20 +010092
93/**
94 * @brief Create printer handler using file descriptor.
95 *
96 * @param[in] fd File descriptor to use.
97 * @return NULL in case of error.
98 * @return Created printer handler supposed to be passed to different ly*_print_*() functions.
99 */
Radek Krejci241f6b52020-05-21 18:13:49 +0200100struct ly_out *ly_out_new_fd(int fd);
Radek Krejcia5bba312020-01-09 15:41:20 +0100101
102/**
103 * @brief Get or reset file descriptor printer handler.
104 *
105 * @param[in] out Printer handler.
106 * @param[in] fd Optional value of a new file descriptor for the handler. If -1, only the current file descriptor value is returned.
107 * @return Previous value of the file descriptor. Note that caller is responsible for closing the returned file descriptor in case of setting new descriptor @p fd.
108 * @return -1 in case of error when setting up the new file descriptor.
109 */
Radek Krejci241f6b52020-05-21 18:13:49 +0200110int ly_out_fd(struct ly_out *out, int fd);
Radek Krejcia5bba312020-01-09 15:41:20 +0100111
112/**
113 * @brief Create printer handler using file stream.
114 *
115 * @param[in] f File stream to use.
116 * @return NULL in case of error.
117 * @return Created printer handler supposed to be passed to different ly*_print_*() functions.
118 */
Radek Krejci241f6b52020-05-21 18:13:49 +0200119struct ly_out *ly_out_new_file(FILE *f);
Radek Krejcia5bba312020-01-09 15:41:20 +0100120
121/**
122 * @brief Get or reset file stream printer handler.
123 *
124 * @param[in] out Printer handler.
125 * @param[in] f Optional new file stream for the handler. If NULL, only the current file stream is returned.
126 * @return Previous file stream of the handler. Note that caller is responsible for closing the returned stream in case of setting new stream @p f.
127 */
Radek Krejci241f6b52020-05-21 18:13:49 +0200128FILE *ly_out_file(struct ly_out *out, FILE *f);
Radek Krejcia5bba312020-01-09 15:41:20 +0100129
130/**
131 * @brief Create printer handler using memory to dump data.
132 *
133 * @param[in] strp Pointer to store the resulting data. If it points to a pointer to an allocated buffer and
134 * @p size of the buffer is set, the buffer is used (and extended if needed) to store the printed data.
135 * @param[in] size Size of the buffer provided via @p strp. In case it is 0, the buffer for the printed data
136 * is newly allocated even if @p strp points to a pointer to an existing buffer.
137 * @return NULL in case of error.
138 * @return Created printer handler supposed to be passed to different ly*_print_*() functions.
139 */
Radek Krejci241f6b52020-05-21 18:13:49 +0200140struct ly_out *ly_out_new_memory(char **strp, size_t size);
Radek Krejcia5bba312020-01-09 15:41:20 +0100141
142/**
143 * @brief Get or change memory where the data are dumped.
144 *
145 * @param[in] out Printer handler.
Radek Krejcibaeb8382020-05-27 16:44:53 +0200146 * @param[in] strp Optional new string pointer to store the resulting data, same rules as in ly_out_new_memory() are applied.
Radek Krejcia5bba312020-01-09 15:41:20 +0100147 * @param[in] size Size of the buffer provided via @p strp. In case it is 0, the buffer for the printed data
Radek Krejcibaeb8382020-05-27 16:44:53 +0200148 * is newly allocated even if @p strp points to a pointer to an existing buffer. In case the @p strp is NULL, this
149 * parameter is ignored.
Radek Krejcia5bba312020-01-09 15:41:20 +0100150 * @return Previous dumped data. Note that the caller is responsible to free the data in case of changing string pointer @p strp.
151 */
Radek Krejci241f6b52020-05-21 18:13:49 +0200152char *ly_out_memory(struct ly_out *out, char **strp, size_t size);
Radek Krejcia5bba312020-01-09 15:41:20 +0100153
154/**
155 * @brief Create printer handler file of the given filename.
156 *
157 * @param[in] filepath Path of the file where to write data.
158 * @return NULL in case of error.
159 * @return Created printer handler supposed to be passed to different ly*_print_*() functions.
160 */
Radek Krejci241f6b52020-05-21 18:13:49 +0200161struct ly_out *ly_out_new_filepath(const char *filepath);
Radek Krejcia5bba312020-01-09 15:41:20 +0100162
163/**
164 * @brief Get or change the filepath of the file where the printer prints the data.
165 *
166 * Note that in case of changing the filepath, the current file is closed and a new one is
167 * created/opened instead of renaming the previous file. Also note that the previous filepath
168 * string is returned only in case of not changing it's value.
169 *
170 * @param[in] out Printer handler.
171 * @param[in] filepath Optional new filepath for the handler. If and only if NULL, the current filepath string is returned.
172 * @return Previous filepath string in case the @p filepath argument is NULL.
173 * @return NULL if changing filepath succeedes and ((void *)-1) otherwise.
174 */
Radek Krejci241f6b52020-05-21 18:13:49 +0200175const char *ly_out_filepath(struct ly_out *out, const char *filepath);
Radek Krejcia5bba312020-01-09 15:41:20 +0100176
177/**
178 * @brief Generic printer of the given format string into the specified output.
179 *
Radek Krejci241f6b52020-05-21 18:13:49 +0200180 * Alternatively, ly_write() can be used.
Radek Krejcia5bba312020-01-09 15:41:20 +0100181 *
182 * @param[in] out Output specification.
183 * @param[in] format format string to be printed.
184 * @return LY_ERR value, number of the printed bytes is updated in lyout::printed.
Radek Krejcibaeb8382020-05-27 16:44:53 +0200185 * @return The number of printed bytes.
186 * @return Negative value in case of error, absolute value of the return code maps to LY_ERR value.
Radek Krejcia5bba312020-01-09 15:41:20 +0100187 */
Radek Krejcibaeb8382020-05-27 16:44:53 +0200188ssize_t ly_print(struct ly_out *out, const char *format, ...);
Radek Krejcia5bba312020-01-09 15:41:20 +0100189
190/**
191 * @brief Generic printer of the given string buffer into the specified output.
192 *
Radek Krejci241f6b52020-05-21 18:13:49 +0200193 * Alternatively, ly_print() can be used.
Radek Krejcia5bba312020-01-09 15:41:20 +0100194 *
195 * As an extension for printing holes (skipping some data until they are known),
196 * ly_write_skip() and ly_write_skipped() can be used.
197 *
198 * @param[in] out Output specification.
199 * @param[in] buf Memory buffer with the data to print.
200 * @param[in] len Length of the data to print in the @p buf.
Radek Krejcibaeb8382020-05-27 16:44:53 +0200201 * @return The number of printed bytes.
202 * @return Negative value in case of error, absolute value of the return code maps to LY_ERR value.
Radek Krejcia5bba312020-01-09 15:41:20 +0100203 */
Radek Krejcibaeb8382020-05-27 16:44:53 +0200204ssize_t ly_write(struct ly_out *out, const char *buf, size_t len);
Radek Krejcia5bba312020-01-09 15:41:20 +0100205
206/**
207 * @brief Free the printer handler.
208 * @param[in] out Printer handler to free.
Radek Krejci241f6b52020-05-21 18:13:49 +0200209 * @param[in] clb_arg_destructor Freeing function for printer callback (LY_OUT_CALLBACK) argument.
210 * @param[in] destroy Flag to free allocated buffer (for LY_OUT_MEMORY) or to
211 * close stream/file descriptor (for LY_OUT_FD, LY_OUT_FDSTREAM and LY_OUT_FILE)
Radek Krejcia5bba312020-01-09 15:41:20 +0100212 */
Radek Krejci241f6b52020-05-21 18:13:49 +0200213void ly_out_free(struct ly_out *out, void (*clb_arg_destructor)(void *arg), int destroy);
Radek Krejcia5bba312020-01-09 15:41:20 +0100214
215#endif /* LY_PRINTER_H_ */