1 /*
2 * This file is part of the Yices SMT Solver.
3 * Copyright (C) 2017 SRI International.
4 *
5 * Yices is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * Yices is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with Yices. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 /*
20 * Writer: wrapper that provides functions to write either to a FILE or to a string buffer.
21 * We currently support only putc, puts, and flush
22 */
23
24 #ifndef __WRITER_H
25 #define __WRITER_H
26
27 #include <stdio.h>
28 #include <stdbool.h>
29
30 #include "utils/string_buffers.h"
31
32 /*
33 * Data structure:
34 * - output = either a FILE or a string buffer
35 * - is_stream: true for FILE/false for string buffers
36 * - print_failed: true after an error
37 * - print_errno = errno when the error was detected
38 */
39 typedef struct writer_s {
40 union {
41 FILE *stream;
42 string_buffer_t buffer;
43 } output;
44 bool is_stream;
45 bool print_failed;
46 int print_errno;
47 } writer_t;
48
49
50
51 /*
52 * Initialize for the given filename
53 * - tries to open the file with mode "w"
54 * - returns -1 if the file can't be opened.
55 * set print_failed to true and store the errno
56 * - returns 0 otherwise (print_failed is false and errno is 0)
57 */
58 extern int32_t init_file_writer(writer_t *writer, const char *filename);
59
60 /*
61 * Initialize with an open stream f
62 * - f must be open and writable
63 */
64 extern void init_stream_writer(writer_t *writer, FILE *f);
65
66 /*
67 * Initialize for standard output or standard error
68 */
init_stdout_writer(writer_t * writer)69 static inline void init_stdout_writer(writer_t *writer) {
70 init_stream_writer(writer, stdout);
71 }
72
init_stderr_writer(writer_t * writer)73 static inline void init_stderr_writer(writer_t *writer) {
74 init_stream_writer(writer, stderr);
75 }
76
77 /*
78 * Initialize for a string buffer
79 */
80 extern void init_string_writer(writer_t *writer);
81
82
83 /*
84 * Close:
85 * - for a stream writer: close the stream
86 * - for a string writer: append '\0' to the buffer
87 * return code = EOF if fclose fails, 0 otherwise
88 */
89 extern int close_writer(writer_t *writer);
90
91
92 /*
93 * Check the type of writer
94 */
is_stream_writer(writer_t * writer)95 static inline bool is_stream_writer(writer_t *writer) {
96 return writer->is_stream;
97 }
98
is_string_writer(writer_t * writer)99 static inline bool is_string_writer(writer_t *writer) {
100 return !writer->is_stream;
101 }
102
103 /*
104 * Extract the string constructed by writer
105 * - this must be a string writer
106 * - the returned string is '\0'-terminated
107 * - its length is returned in *len
108 *
109 * The returned string must be freed when no-longer needed (by a call
110 * to safe_free in utils/memalloc.h).
111 */
112 extern char *writer_get_string(writer_t *writer, uint32_t *len);
113
114
115 /*
116 * Delete:
117 * - delete the buffer (do nothing if this is a stream writer)
118 */
119 extern void delete_writer(writer_t *writer);
120
121
122
123 /*
124 * Print a character, a string, flush
125 * - if writer->print_failed is true, these functions do nothing and exit
126 * - otherwise, they perform the IO operation. If this fails, writer->print_failed
127 * is set to true and errno is stored in writer->print_errno.
128 */
129 extern void writer_putc(writer_t *writer, char c);
130 extern void writer_puts(writer_t *writer, const char *s);
131 extern void writer_flush(writer_t *writer);
132
133
134 /*
135 * Check error flag + errno
136 */
writer_failed(writer_t * writer)137 static inline bool writer_failed(writer_t *writer) {
138 return writer->print_failed;
139 }
140
writer_errno(writer_t * writer)141 static inline int writer_errno(writer_t *writer) {
142 return writer->print_errno;
143 }
144
145
146 #endif /* __WRITER_H */
147