fe8fab98efc343fd0c7dc2e0029b67451d75ca28
[platform/upstream/isl.git] / isl_printer.c
1 #include <string.h>
2 #include <isl_printer_private.h>
3
4 static __isl_give isl_printer *file_start_line(__isl_take isl_printer *p)
5 {
6         fprintf(p->file, "%*s%s", p->indent, "", p->prefix ? p->prefix : "");
7         return p;
8 }
9
10 static __isl_give isl_printer *file_end_line(__isl_take isl_printer *p)
11 {
12         fprintf(p->file, "%s\n", p->suffix ? p->suffix : "");
13         return p;
14 }
15
16 static __isl_give isl_printer *file_flush(__isl_take isl_printer *p)
17 {
18         fflush(p->file);
19         return p;
20 }
21
22 static __isl_give isl_printer *file_print_str(__isl_take isl_printer *p,
23         const char *s)
24 {
25         fprintf(p->file, "%s", s);
26         return p;
27 }
28
29 static __isl_give isl_printer *file_print_int(__isl_take isl_printer *p, int i)
30 {
31         fprintf(p->file, "%d", i);
32         return p;
33 }
34
35 static __isl_give isl_printer *file_print_isl_int(__isl_take isl_printer *p, isl_int i)
36 {
37         isl_int_print(p->file, i, p->width);
38         return p;
39 }
40
41 static int grow_buf(__isl_keep isl_printer *p, int extra)
42 {
43         int new_size;
44         char *new_buf;
45
46         if (p->buf_size == 0)
47                 return -1;
48
49         new_size = ((p->buf_n + extra + 1) * 3) / 2;
50         new_buf = isl_realloc_array(p->ctx, p->buf, char, new_size);
51         if (!new_buf) {
52                 p->buf_size = 0;
53                 return -1;
54         }
55         p->buf = new_buf;
56         p->buf_size = new_size;
57
58         return 0;
59 }
60
61 static __isl_give isl_printer *str_print(__isl_take isl_printer *p,
62         const char *s, int len)
63 {
64         if (p->buf_n + len + 1 >= p->buf_size && grow_buf(p, len))
65                 goto error;
66         memcpy(p->buf + p->buf_n, s, len);
67         p->buf_n += len;
68
69         p->buf[p->buf_n] = '\0';
70         return p;
71 error:
72         isl_printer_free(p);
73         return NULL;
74 }
75
76 static __isl_give isl_printer *str_print_indent(__isl_take isl_printer *p,
77         int indent)
78 {
79         int i;
80
81         if (p->buf_n + indent + 1 >= p->buf_size && grow_buf(p, indent))
82                 goto error;
83         for (i = 0; i < indent; ++i)
84                 p->buf[p->buf_n++] = ' ';
85         return p;
86 error:
87         isl_printer_free(p);
88         return NULL;
89 }
90
91 static __isl_give isl_printer *str_start_line(__isl_take isl_printer *p)
92 {
93         p = str_print_indent(p, p->indent);
94         if (p->prefix)
95                 p = str_print(p, p->prefix, strlen(p->prefix));
96         return p;
97 }
98
99 static __isl_give isl_printer *str_end_line(__isl_take isl_printer *p)
100 {
101         if (p->suffix)
102                 p = str_print(p, p->suffix, strlen(p->suffix));
103         p = str_print(p, "\n", strlen("\n"));
104         return p;
105 }
106
107 static __isl_give isl_printer *str_flush(__isl_take isl_printer *p)
108 {
109         p->buf_n = 0;
110         return p;
111 }
112
113 static __isl_give isl_printer *str_print_str(__isl_take isl_printer *p,
114         const char *s)
115 {
116         return str_print(p, s, strlen(s));
117 }
118
119 static __isl_give isl_printer *str_print_int(__isl_take isl_printer *p, int i)
120 {
121         int left = p->buf_size - p->buf_n;
122         int need = snprintf(p->buf + p->buf_n, left, "%d", i);
123         if (need >= left) {
124                 if (grow_buf(p, need))
125                         goto error;
126                 left = p->buf_size - p->buf_n;
127                 need = snprintf(p->buf + p->buf_n, left, "%d", i);
128         }
129         p->buf_n += need;
130         return p;
131 error:
132         isl_printer_free(p);
133         return NULL;
134 }
135
136 static __isl_give isl_printer *str_print_isl_int(__isl_take isl_printer *p,
137         isl_int i)
138 {
139         char *s;
140         int len;
141         isl_int_print_gmp_free_t gmp_free;
142
143         s = isl_int_get_str(i);
144         len = strlen(s);
145         if (len < p->width)
146                 p = str_print_indent(p, p->width - len);
147         p = str_print(p, s, len);
148         mp_get_memory_functions(NULL, NULL, &gmp_free);
149         (*gmp_free)(s, len + 1);
150         return p;
151 }
152
153 struct isl_printer_ops {
154         __isl_give isl_printer *(*start_line)(__isl_take isl_printer *p);
155         __isl_give isl_printer *(*end_line)(__isl_take isl_printer *p);
156         __isl_give isl_printer *(*print_int)(__isl_take isl_printer *p, int i);
157         __isl_give isl_printer *(*print_isl_int)(__isl_take isl_printer *p,
158                                                 isl_int i);
159         __isl_give isl_printer *(*print_str)(__isl_take isl_printer *p,
160                                                 const char *s);
161         __isl_give isl_printer *(*flush)(__isl_take isl_printer *p);
162 };
163
164 static struct isl_printer_ops file_ops = {
165         file_start_line,
166         file_end_line,
167         file_print_int,
168         file_print_isl_int,
169         file_print_str,
170         file_flush
171 };
172
173 static struct isl_printer_ops str_ops = {
174         str_start_line,
175         str_end_line,
176         str_print_int,
177         str_print_isl_int,
178         str_print_str,
179         str_flush
180 };
181
182 __isl_give isl_printer *isl_printer_to_file(isl_ctx *ctx, FILE *file)
183 {
184         struct isl_printer *p = isl_alloc_type(ctx, struct isl_printer);
185         if (!p)
186                 return NULL;
187         p->ctx = ctx;
188         isl_ctx_ref(p->ctx);
189         p->ops = &file_ops;
190         p->file = file;
191         p->buf = NULL;
192         p->buf_n = 0;
193         p->buf_size = 0;
194         p->indent = 0;
195         p->output_format = ISL_FORMAT_ISL;
196         p->prefix = NULL;
197         p->suffix = NULL;
198         p->width = 0;
199
200         return p;
201 }
202
203 __isl_give isl_printer *isl_printer_to_str(isl_ctx *ctx)
204 {
205         struct isl_printer *p = isl_alloc_type(ctx, struct isl_printer);
206         if (!p)
207                 return NULL;
208         p->ctx = ctx;
209         isl_ctx_ref(p->ctx);
210         p->ops = &str_ops;
211         p->file = NULL;
212         p->buf = isl_alloc_array(ctx, char, 256);
213         if (!p->buf)
214                 goto error;
215         p->buf_n = 0;
216         p->buf_size = 256;
217         p->indent = 0;
218         p->output_format = ISL_FORMAT_ISL;
219         p->prefix = NULL;
220         p->suffix = NULL;
221         p->width = 0;
222
223         return p;
224 error:
225         isl_printer_free(p);
226         return NULL;
227 }
228
229 void isl_printer_free(__isl_take isl_printer *p)
230 {
231         if (!p)
232                 return;
233         free(p->buf);
234         isl_ctx_deref(p->ctx);
235         free(p);
236 }
237
238 isl_ctx *isl_printer_get_ctx(__isl_keep isl_printer *printer)
239 {
240         return printer ? printer->ctx : NULL;
241 }
242
243 __isl_give isl_printer *isl_printer_set_isl_int_width(__isl_take isl_printer *p,
244         int width)
245 {
246         if (!p)
247                 return NULL;
248
249         p->width = width;
250
251         return p;
252 }
253
254 __isl_give isl_printer *isl_printer_set_indent(__isl_take isl_printer *p,
255         int indent)
256 {
257         if (!p)
258                 return NULL;
259
260         p->indent = indent;
261
262         return p;
263 }
264
265 __isl_give isl_printer *isl_printer_indent(__isl_take isl_printer *p,
266         int indent)
267 {
268         if (!p)
269                 return NULL;
270
271         p->indent += indent;
272         if (p->indent < 0)
273                 p->indent = 0;
274
275         return p;
276 }
277
278 __isl_give isl_printer *isl_printer_set_prefix(__isl_take isl_printer *p,
279         const char *prefix)
280 {
281         if (!p)
282                 return NULL;
283
284         p->prefix = prefix;
285
286         return p;
287 }
288
289 __isl_give isl_printer *isl_printer_set_suffix(__isl_take isl_printer *p,
290         const char *suffix)
291 {
292         if (!p)
293                 return NULL;
294
295         p->suffix = suffix;
296
297         return p;
298 }
299
300 __isl_give isl_printer *isl_printer_set_output_format(__isl_take isl_printer *p,
301         int output_format)
302 {
303         if (!p)
304                 return NULL;
305
306         p->output_format = output_format;
307
308         return p;
309 }
310
311 __isl_give isl_printer *isl_printer_print_str(__isl_take isl_printer *p,
312         const char *s)
313 {
314         if (!p)
315                 return NULL;
316
317         return p->ops->print_str(p, s);
318 }
319
320 __isl_give isl_printer *isl_printer_print_int(__isl_take isl_printer *p, int i)
321 {
322         if (!p)
323                 return NULL;
324
325         return p->ops->print_int(p, i);
326 }
327
328 __isl_give isl_printer *isl_printer_print_isl_int(__isl_take isl_printer *p,
329         isl_int i)
330 {
331         if (!p)
332                 return NULL;
333
334         return p->ops->print_isl_int(p, i);
335 }
336
337 __isl_give isl_printer *isl_printer_start_line(__isl_take isl_printer *p)
338 {
339         if (!p)
340                 return NULL;
341
342         return p->ops->start_line(p);
343 }
344
345 __isl_give isl_printer *isl_printer_end_line(__isl_take isl_printer *p)
346 {
347         if (!p)
348                 return NULL;
349
350         return p->ops->end_line(p);
351 }
352
353 char *isl_printer_get_str(__isl_keep isl_printer *printer)
354 {
355         if (!printer || !printer->buf)
356                 return NULL;
357         return strdup(printer->buf);
358 }
359
360 __isl_give isl_printer *isl_printer_flush(__isl_take isl_printer *p)
361 {
362         if (!p)
363                 return NULL;
364
365         return p->ops->flush(p);
366 }