isl_output.c: reuse print_disjunct for printing in Omega format
[isl.git] / isl_printer.c
blob4458e9728b159ab98aad24461253a1e1b7636046
1 #include <string.h>
2 #include <isl_int.h>
3 #include <isl_printer_private.h>
5 static __isl_give isl_printer *file_start_line(__isl_take isl_printer *p)
7 fprintf(p->file, "%*s%s", p->indent, "", p->prefix ? p->prefix : "");
8 return p;
11 static __isl_give isl_printer *file_end_line(__isl_take isl_printer *p)
13 fprintf(p->file, "%s\n", p->suffix ? p->suffix : "");
14 return p;
17 static __isl_give isl_printer *file_flush(__isl_take isl_printer *p)
19 fflush(p->file);
20 return p;
23 static __isl_give isl_printer *file_print_str(__isl_take isl_printer *p,
24 const char *s)
26 fprintf(p->file, "%s", s);
27 return p;
30 static __isl_give isl_printer *file_print_double(__isl_take isl_printer *p,
31 double d)
33 fprintf(p->file, "%g", d);
34 return p;
37 static __isl_give isl_printer *file_print_int(__isl_take isl_printer *p, int i)
39 fprintf(p->file, "%d", i);
40 return p;
43 static __isl_give isl_printer *file_print_isl_int(__isl_take isl_printer *p, isl_int i)
45 isl_int_print(p->file, i, p->width);
46 return p;
49 static int grow_buf(__isl_keep isl_printer *p, int extra)
51 int new_size;
52 char *new_buf;
54 if (p->buf_size == 0)
55 return -1;
57 new_size = ((p->buf_n + extra + 1) * 3) / 2;
58 new_buf = isl_realloc_array(p->ctx, p->buf, char, new_size);
59 if (!new_buf) {
60 p->buf_size = 0;
61 return -1;
63 p->buf = new_buf;
64 p->buf_size = new_size;
66 return 0;
69 static __isl_give isl_printer *str_print(__isl_take isl_printer *p,
70 const char *s, int len)
72 if (p->buf_n + len + 1 >= p->buf_size && grow_buf(p, len))
73 goto error;
74 memcpy(p->buf + p->buf_n, s, len);
75 p->buf_n += len;
77 p->buf[p->buf_n] = '\0';
78 return p;
79 error:
80 isl_printer_free(p);
81 return NULL;
84 static __isl_give isl_printer *str_print_indent(__isl_take isl_printer *p,
85 int indent)
87 int i;
89 if (p->buf_n + indent + 1 >= p->buf_size && grow_buf(p, indent))
90 goto error;
91 for (i = 0; i < indent; ++i)
92 p->buf[p->buf_n++] = ' ';
93 return p;
94 error:
95 isl_printer_free(p);
96 return NULL;
99 static __isl_give isl_printer *str_start_line(__isl_take isl_printer *p)
101 p = str_print_indent(p, p->indent);
102 if (p->prefix)
103 p = str_print(p, p->prefix, strlen(p->prefix));
104 return p;
107 static __isl_give isl_printer *str_end_line(__isl_take isl_printer *p)
109 if (p->suffix)
110 p = str_print(p, p->suffix, strlen(p->suffix));
111 p = str_print(p, "\n", strlen("\n"));
112 return p;
115 static __isl_give isl_printer *str_flush(__isl_take isl_printer *p)
117 p->buf_n = 0;
118 return p;
121 static __isl_give isl_printer *str_print_str(__isl_take isl_printer *p,
122 const char *s)
124 return str_print(p, s, strlen(s));
127 static __isl_give isl_printer *str_print_double(__isl_take isl_printer *p,
128 double d)
130 int left = p->buf_size - p->buf_n;
131 int need = snprintf(p->buf + p->buf_n, left, "%g", d);
132 if (need >= left) {
133 if (grow_buf(p, need))
134 goto error;
135 left = p->buf_size - p->buf_n;
136 need = snprintf(p->buf + p->buf_n, left, "%g", d);
138 p->buf_n += need;
139 return p;
140 error:
141 isl_printer_free(p);
142 return NULL;
145 static __isl_give isl_printer *str_print_int(__isl_take isl_printer *p, int i)
147 int left = p->buf_size - p->buf_n;
148 int need = snprintf(p->buf + p->buf_n, left, "%d", i);
149 if (need >= left) {
150 if (grow_buf(p, need))
151 goto error;
152 left = p->buf_size - p->buf_n;
153 need = snprintf(p->buf + p->buf_n, left, "%d", i);
155 p->buf_n += need;
156 return p;
157 error:
158 isl_printer_free(p);
159 return NULL;
162 static __isl_give isl_printer *str_print_isl_int(__isl_take isl_printer *p,
163 isl_int i)
165 char *s;
166 int len;
168 s = isl_int_get_str(i);
169 len = strlen(s);
170 if (len < p->width)
171 p = str_print_indent(p, p->width - len);
172 p = str_print(p, s, len);
173 isl_int_free_str(s);
174 return p;
177 struct isl_printer_ops {
178 __isl_give isl_printer *(*start_line)(__isl_take isl_printer *p);
179 __isl_give isl_printer *(*end_line)(__isl_take isl_printer *p);
180 __isl_give isl_printer *(*print_double)(__isl_take isl_printer *p,
181 double d);
182 __isl_give isl_printer *(*print_int)(__isl_take isl_printer *p, int i);
183 __isl_give isl_printer *(*print_isl_int)(__isl_take isl_printer *p,
184 isl_int i);
185 __isl_give isl_printer *(*print_str)(__isl_take isl_printer *p,
186 const char *s);
187 __isl_give isl_printer *(*flush)(__isl_take isl_printer *p);
190 static struct isl_printer_ops file_ops = {
191 file_start_line,
192 file_end_line,
193 file_print_double,
194 file_print_int,
195 file_print_isl_int,
196 file_print_str,
197 file_flush
200 static struct isl_printer_ops str_ops = {
201 str_start_line,
202 str_end_line,
203 str_print_double,
204 str_print_int,
205 str_print_isl_int,
206 str_print_str,
207 str_flush
210 __isl_give isl_printer *isl_printer_to_file(isl_ctx *ctx, FILE *file)
212 struct isl_printer *p = isl_alloc_type(ctx, struct isl_printer);
213 if (!p)
214 return NULL;
215 p->ctx = ctx;
216 isl_ctx_ref(p->ctx);
217 p->ops = &file_ops;
218 p->file = file;
219 p->buf = NULL;
220 p->buf_n = 0;
221 p->buf_size = 0;
222 p->indent = 0;
223 p->output_format = ISL_FORMAT_ISL;
224 p->prefix = NULL;
225 p->suffix = NULL;
226 p->width = 0;
228 return p;
231 __isl_give isl_printer *isl_printer_to_str(isl_ctx *ctx)
233 struct isl_printer *p = isl_alloc_type(ctx, struct isl_printer);
234 if (!p)
235 return NULL;
236 p->ctx = ctx;
237 isl_ctx_ref(p->ctx);
238 p->ops = &str_ops;
239 p->file = NULL;
240 p->buf = isl_alloc_array(ctx, char, 256);
241 if (!p->buf)
242 goto error;
243 p->buf_n = 0;
244 p->buf[0] = '\0';
245 p->buf_size = 256;
246 p->indent = 0;
247 p->output_format = ISL_FORMAT_ISL;
248 p->prefix = NULL;
249 p->suffix = NULL;
250 p->width = 0;
252 return p;
253 error:
254 isl_printer_free(p);
255 return NULL;
258 void *isl_printer_free(__isl_take isl_printer *p)
260 if (!p)
261 return NULL;
262 free(p->buf);
263 isl_ctx_deref(p->ctx);
264 free(p);
266 return NULL;
269 isl_ctx *isl_printer_get_ctx(__isl_keep isl_printer *printer)
271 return printer ? printer->ctx : NULL;
274 FILE *isl_printer_get_file(__isl_keep isl_printer *printer)
276 if (!printer)
277 return NULL;
278 if (!printer->file)
279 isl_die(isl_printer_get_ctx(printer), isl_error_invalid,
280 "not a file printer", return NULL);
281 return printer->file;
284 __isl_give isl_printer *isl_printer_set_isl_int_width(__isl_take isl_printer *p,
285 int width)
287 if (!p)
288 return NULL;
290 p->width = width;
292 return p;
295 __isl_give isl_printer *isl_printer_set_indent(__isl_take isl_printer *p,
296 int indent)
298 if (!p)
299 return NULL;
301 p->indent = indent;
303 return p;
306 __isl_give isl_printer *isl_printer_indent(__isl_take isl_printer *p,
307 int indent)
309 if (!p)
310 return NULL;
312 p->indent += indent;
313 if (p->indent < 0)
314 p->indent = 0;
316 return p;
319 __isl_give isl_printer *isl_printer_set_prefix(__isl_take isl_printer *p,
320 const char *prefix)
322 if (!p)
323 return NULL;
325 p->prefix = prefix;
327 return p;
330 __isl_give isl_printer *isl_printer_set_suffix(__isl_take isl_printer *p,
331 const char *suffix)
333 if (!p)
334 return NULL;
336 p->suffix = suffix;
338 return p;
341 __isl_give isl_printer *isl_printer_set_output_format(__isl_take isl_printer *p,
342 int output_format)
344 if (!p)
345 return NULL;
347 p->output_format = output_format;
349 return p;
352 int isl_printer_get_output_format(__isl_keep isl_printer *p)
354 if (!p)
355 return -1;
356 return p->output_format;
359 __isl_give isl_printer *isl_printer_print_str(__isl_take isl_printer *p,
360 const char *s)
362 if (!p)
363 return NULL;
364 if (!s)
365 return isl_printer_free(p);
367 return p->ops->print_str(p, s);
370 __isl_give isl_printer *isl_printer_print_double(__isl_take isl_printer *p,
371 double d)
373 if (!p)
374 return NULL;
376 return p->ops->print_double(p, d);
379 __isl_give isl_printer *isl_printer_print_int(__isl_take isl_printer *p, int i)
381 if (!p)
382 return NULL;
384 return p->ops->print_int(p, i);
387 __isl_give isl_printer *isl_printer_print_isl_int(__isl_take isl_printer *p,
388 isl_int i)
390 if (!p)
391 return NULL;
393 return p->ops->print_isl_int(p, i);
396 __isl_give isl_printer *isl_printer_start_line(__isl_take isl_printer *p)
398 if (!p)
399 return NULL;
401 return p->ops->start_line(p);
404 __isl_give isl_printer *isl_printer_end_line(__isl_take isl_printer *p)
406 if (!p)
407 return NULL;
409 return p->ops->end_line(p);
412 char *isl_printer_get_str(__isl_keep isl_printer *printer)
414 if (!printer || !printer->buf)
415 return NULL;
416 return strdup(printer->buf);
419 __isl_give isl_printer *isl_printer_flush(__isl_take isl_printer *p)
421 if (!p)
422 return NULL;
424 return p->ops->flush(p);