This source file includes following definitions.
- text_free_priv
- text_init
- text_finish
- text_reset
- text_subprocess_output
- text_version
- G_GNUC_PRINTF
- G_GNUC_PRINTF
- text_output_xml
- G_GNUC_PRINTF
- G_GNUC_PRINTF
- text_increment_list
- text_end_list
- text_is_quiet
- pcmk__mk_text_output
- G_GNUC_PRINTF
- G_GNUC_PRINTF
1
2
3
4
5
6
7
8
9
10 #include <stdarg.h>
11 #include <stdlib.h>
12 #include <glib.h>
13
14 #include <crm/crm.h>
15 #include <crm/common/output_internal.h>
16
17 static gboolean fancy = FALSE;
18
19 GOptionEntry pcmk__text_output_entries[] = {
20 { "text-fancy", 0, 0, G_OPTION_ARG_NONE, &fancy,
21 "Use more highly formatted output (requires --output-as=text)",
22 NULL },
23
24 { NULL }
25 };
26
27 typedef struct text_list_data_s {
28 unsigned int len;
29 char *singular_noun;
30 char *plural_noun;
31 } text_list_data_t;
32
33 typedef struct private_data_s {
34 GQueue *parent_q;
35 } private_data_t;
36
37 static void
38 text_free_priv(pcmk__output_t *out) {
39 private_data_t *priv = out->priv;
40
41 if (priv == NULL) {
42 return;
43 }
44
45 g_queue_free(priv->parent_q);
46 free(priv);
47 out->priv = NULL;
48 }
49
50 static bool
51 text_init(pcmk__output_t *out) {
52 private_data_t *priv = NULL;
53
54
55 if (out->priv != NULL) {
56 return true;
57 } else {
58 out->priv = calloc(1, sizeof(private_data_t));
59 if (out->priv == NULL) {
60 return false;
61 }
62
63 priv = out->priv;
64 }
65
66 priv->parent_q = g_queue_new();
67 return true;
68 }
69
70 static void
71 text_finish(pcmk__output_t *out, crm_exit_t exit_status, bool print, void **copy_dest) {
72
73 }
74
75 static void
76 text_reset(pcmk__output_t *out) {
77 CRM_ASSERT(out != NULL);
78
79 out->dest = freopen(NULL, "w", out->dest);
80 CRM_ASSERT(out->dest != NULL);
81
82 text_free_priv(out);
83 text_init(out);
84 }
85
86 static void
87 text_subprocess_output(pcmk__output_t *out, int exit_status,
88 const char *proc_stdout, const char *proc_stderr) {
89 if (proc_stdout != NULL) {
90 fprintf(out->dest, "%s\n", proc_stdout);
91 }
92
93 if (proc_stderr != NULL) {
94 fprintf(out->dest, "%s\n", proc_stderr);
95 }
96 }
97
98 static void
99 text_version(pcmk__output_t *out, bool extended) {
100 if (extended) {
101 fprintf(out->dest, "Pacemaker %s (Build: %s): %s\n", PACEMAKER_VERSION, BUILD_VERSION, CRM_FEATURES);
102 } else {
103 fprintf(out->dest, "Pacemaker %s\n", PACEMAKER_VERSION);
104 fprintf(out->dest, "Written by Andrew Beekhof\n");
105 }
106 }
107
108 G_GNUC_PRINTF(2, 3)
109 static void
110 text_err(pcmk__output_t *out, const char *format, ...) {
111 va_list ap;
112 int len = 0;
113
114 va_start(ap, format);
115
116
117
118
119 len = vfprintf(stderr, format, ap);
120 CRM_ASSERT(len >= 0);
121 va_end(ap);
122
123
124 fprintf(stderr, "\n");
125 }
126
127 G_GNUC_PRINTF(2, 3)
128 static void
129 text_info(pcmk__output_t *out, const char *format, ...) {
130 va_list ap;
131 int len = 0;
132
133 va_start(ap, format);
134
135
136
137
138 len = vfprintf(out->dest, format, ap);
139 CRM_ASSERT(len >= 0);
140 va_end(ap);
141
142
143 fprintf(out->dest, "\n");
144 }
145
146 static void
147 text_output_xml(pcmk__output_t *out, const char *name, const char *buf) {
148 private_data_t *priv = out->priv;
149
150 CRM_ASSERT(priv != NULL);
151 pcmk__indented_printf(out, "%s", buf);
152 }
153
154 G_GNUC_PRINTF(4, 5)
155 static void
156 text_begin_list(pcmk__output_t *out, const char *singular_noun, const char *plural_noun,
157 const char *format, ...) {
158 private_data_t *priv = out->priv;
159 text_list_data_t *new_list = NULL;
160 va_list ap;
161
162 CRM_ASSERT(priv != NULL);
163
164 va_start(ap, format);
165
166 if (fancy && format) {
167 pcmk__indented_vprintf(out, format, ap);
168 fprintf(out->dest, ":\n");
169 }
170
171 va_end(ap);
172
173 new_list = calloc(1, sizeof(text_list_data_t));
174 new_list->len = 0;
175 new_list->singular_noun = singular_noun == NULL ? NULL : strdup(singular_noun);
176 new_list->plural_noun = plural_noun == NULL ? NULL : strdup(plural_noun);
177
178 g_queue_push_tail(priv->parent_q, new_list);
179 }
180
181 G_GNUC_PRINTF(3, 4)
182 static void
183 text_list_item(pcmk__output_t *out, const char *id, const char *format, ...) {
184 private_data_t *priv = out->priv;
185 va_list ap;
186
187 CRM_ASSERT(priv != NULL);
188
189 va_start(ap, format);
190
191 if (fancy) {
192 if (id != NULL) {
193
194
195
196
197 pcmk__indented_printf(out, "%s: ", id);
198 vfprintf(out->dest, format, ap);
199 } else {
200 pcmk__indented_vprintf(out, format, ap);
201 }
202 } else {
203 pcmk__indented_vprintf(out, format, ap);
204 }
205
206 fputc('\n', out->dest);
207 va_end(ap);
208
209 out->increment_list(out);
210 }
211
212 static void
213 text_increment_list(pcmk__output_t *out) {
214 private_data_t *priv = out->priv;
215 gpointer tail;
216
217 CRM_ASSERT(priv != NULL);
218 tail = g_queue_peek_tail(priv->parent_q);
219 CRM_ASSERT(tail != NULL);
220 ((text_list_data_t *) tail)->len++;
221 }
222
223 static void
224 text_end_list(pcmk__output_t *out) {
225 private_data_t *priv = out->priv;
226 text_list_data_t *node = NULL;
227
228 CRM_ASSERT(priv != NULL);
229 node = g_queue_pop_tail(priv->parent_q);
230
231 if (node->singular_noun != NULL && node->plural_noun != NULL) {
232 if (node->len == 1) {
233 pcmk__indented_printf(out, "%d %s found\n", node->len, node->singular_noun);
234 } else {
235 pcmk__indented_printf(out, "%d %s found\n", node->len, node->plural_noun);
236 }
237 }
238
239 free(node);
240 }
241
242 static bool
243 text_is_quiet(pcmk__output_t *out) {
244 return out->quiet;
245 }
246
247 pcmk__output_t *
248 pcmk__mk_text_output(char **argv) {
249 pcmk__output_t *retval = calloc(1, sizeof(pcmk__output_t));
250
251 if (retval == NULL) {
252 return NULL;
253 }
254
255 retval->fmt_name = "text";
256 retval->request = argv == NULL ? NULL : g_strjoinv(" ", argv);
257
258 retval->init = text_init;
259 retval->free_priv = text_free_priv;
260 retval->finish = text_finish;
261 retval->reset = text_reset;
262
263 retval->register_message = pcmk__register_message;
264 retval->message = pcmk__call_message;
265
266 retval->subprocess_output = text_subprocess_output;
267 retval->version = text_version;
268 retval->info = text_info;
269 retval->err = text_err;
270 retval->output_xml = text_output_xml;
271
272 retval->begin_list = text_begin_list;
273 retval->list_item = text_list_item;
274 retval->increment_list = text_increment_list;
275 retval->end_list = text_end_list;
276
277 retval->is_quiet = text_is_quiet;
278
279 return retval;
280 }
281
282 G_GNUC_PRINTF(2, 0)
283 void
284 pcmk__indented_vprintf(pcmk__output_t *out, const char *format, va_list args) {
285 int len = 0;
286
287 if (fancy) {
288 int level = 0;
289 private_data_t *priv = out->priv;
290
291 CRM_ASSERT(priv != NULL);
292
293 level = g_queue_get_length(priv->parent_q);
294
295 for (int i = 0; i < level; i++) {
296 fprintf(out->dest, " ");
297 }
298
299 if (level > 0) {
300 fprintf(out->dest, "* ");
301 }
302 }
303
304 len = vfprintf(out->dest, format, args);
305 CRM_ASSERT(len >= 0);
306 }
307
308 G_GNUC_PRINTF(2, 3)
309 void
310 pcmk__indented_printf(pcmk__output_t *out, const char *format, ...) {
311 va_list ap;
312
313 va_start(ap, format);
314 pcmk__indented_vprintf(out, format, ap);
315 va_end(ap);
316 }