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