Blame isl-0.14/isl_printer.c

Packit fb9d21
#include <string.h>
Packit fb9d21
#include <isl_int.h>
Packit fb9d21
#include <isl_printer_private.h>
Packit fb9d21
Packit fb9d21
static __isl_give isl_printer *file_start_line(__isl_take isl_printer *p)
Packit fb9d21
{
Packit fb9d21
	fprintf(p->file, "%s%*s%s", p->indent_prefix ? p->indent_prefix : "",
Packit fb9d21
				    p->indent, "", p->prefix ? p->prefix : "");
Packit fb9d21
	return p;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
static __isl_give isl_printer *file_end_line(__isl_take isl_printer *p)
Packit fb9d21
{
Packit fb9d21
	fprintf(p->file, "%s\n", p->suffix ? p->suffix : "");
Packit fb9d21
	return p;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
static __isl_give isl_printer *file_flush(__isl_take isl_printer *p)
Packit fb9d21
{
Packit fb9d21
	fflush(p->file);
Packit fb9d21
	return p;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
static __isl_give isl_printer *file_print_str(__isl_take isl_printer *p,
Packit fb9d21
	const char *s)
Packit fb9d21
{
Packit fb9d21
	fprintf(p->file, "%s", s);
Packit fb9d21
	return p;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
static __isl_give isl_printer *file_print_double(__isl_take isl_printer *p,
Packit fb9d21
	double d)
Packit fb9d21
{
Packit fb9d21
	fprintf(p->file, "%g", d);
Packit fb9d21
	return p;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
static __isl_give isl_printer *file_print_int(__isl_take isl_printer *p, int i)
Packit fb9d21
{
Packit fb9d21
	fprintf(p->file, "%d", i);
Packit fb9d21
	return p;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
static __isl_give isl_printer *file_print_isl_int(__isl_take isl_printer *p, isl_int i)
Packit fb9d21
{
Packit fb9d21
	isl_int_print(p->file, i, p->width);
Packit fb9d21
	return p;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
static int grow_buf(__isl_keep isl_printer *p, int extra)
Packit fb9d21
{
Packit fb9d21
	int new_size;
Packit fb9d21
	char *new_buf;
Packit fb9d21
Packit fb9d21
	if (p->buf_size == 0)
Packit fb9d21
		return -1;
Packit fb9d21
Packit fb9d21
	new_size = ((p->buf_n + extra + 1) * 3) / 2;
Packit fb9d21
	new_buf = isl_realloc_array(p->ctx, p->buf, char, new_size);
Packit fb9d21
	if (!new_buf) {
Packit fb9d21
		p->buf_size = 0;
Packit fb9d21
		return -1;
Packit fb9d21
	}
Packit fb9d21
	p->buf = new_buf;
Packit fb9d21
	p->buf_size = new_size;
Packit fb9d21
Packit fb9d21
	return 0;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
static __isl_give isl_printer *str_print(__isl_take isl_printer *p,
Packit fb9d21
	const char *s, int len)
Packit fb9d21
{
Packit fb9d21
	if (p->buf_n + len + 1 >= p->buf_size && grow_buf(p, len))
Packit fb9d21
		goto error;
Packit fb9d21
	memcpy(p->buf + p->buf_n, s, len);
Packit fb9d21
	p->buf_n += len;
Packit fb9d21
Packit fb9d21
	p->buf[p->buf_n] = '\0';
Packit fb9d21
	return p;
Packit fb9d21
error:
Packit fb9d21
	isl_printer_free(p);
Packit fb9d21
	return NULL;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
static __isl_give isl_printer *str_print_indent(__isl_take isl_printer *p,
Packit fb9d21
	int indent)
Packit fb9d21
{
Packit fb9d21
	int i;
Packit fb9d21
Packit fb9d21
	if (p->buf_n + indent + 1 >= p->buf_size && grow_buf(p, indent))
Packit fb9d21
		goto error;
Packit fb9d21
	for (i = 0; i < indent; ++i)
Packit fb9d21
		p->buf[p->buf_n++] = ' ';
Packit fb9d21
	return p;
Packit fb9d21
error:
Packit fb9d21
	isl_printer_free(p);
Packit fb9d21
	return NULL;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
static __isl_give isl_printer *str_start_line(__isl_take isl_printer *p)
Packit fb9d21
{
Packit fb9d21
	if (p->indent_prefix)
Packit fb9d21
		p = str_print(p, p->indent_prefix, strlen(p->indent_prefix));
Packit fb9d21
	p = str_print_indent(p, p->indent);
Packit fb9d21
	if (p->prefix)
Packit fb9d21
		p = str_print(p, p->prefix, strlen(p->prefix));
Packit fb9d21
	return p;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
static __isl_give isl_printer *str_end_line(__isl_take isl_printer *p)
Packit fb9d21
{
Packit fb9d21
	if (p->suffix)
Packit fb9d21
		p = str_print(p, p->suffix, strlen(p->suffix));
Packit fb9d21
	p = str_print(p, "\n", strlen("\n"));
Packit fb9d21
	return p;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
static __isl_give isl_printer *str_flush(__isl_take isl_printer *p)
Packit fb9d21
{
Packit fb9d21
	p->buf_n = 0;
Packit fb9d21
	return p;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
static __isl_give isl_printer *str_print_str(__isl_take isl_printer *p,
Packit fb9d21
	const char *s)
Packit fb9d21
{
Packit fb9d21
	return str_print(p, s, strlen(s));
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
static __isl_give isl_printer *str_print_double(__isl_take isl_printer *p,
Packit fb9d21
	double d)
Packit fb9d21
{
Packit fb9d21
	int left = p->buf_size - p->buf_n;
Packit fb9d21
	int need = snprintf(p->buf + p->buf_n, left, "%g", d);
Packit fb9d21
	if (need >= left) {
Packit fb9d21
		if (grow_buf(p, need))
Packit fb9d21
			goto error;
Packit fb9d21
		left = p->buf_size - p->buf_n;
Packit fb9d21
		need = snprintf(p->buf + p->buf_n, left, "%g", d);
Packit fb9d21
	}
Packit fb9d21
	p->buf_n += need;
Packit fb9d21
	return p;
Packit fb9d21
error:
Packit fb9d21
	isl_printer_free(p);
Packit fb9d21
	return NULL;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
static __isl_give isl_printer *str_print_int(__isl_take isl_printer *p, int i)
Packit fb9d21
{
Packit fb9d21
	int left = p->buf_size - p->buf_n;
Packit fb9d21
	int need = snprintf(p->buf + p->buf_n, left, "%d", i);
Packit fb9d21
	if (need >= left) {
Packit fb9d21
		if (grow_buf(p, need))
Packit fb9d21
			goto error;
Packit fb9d21
		left = p->buf_size - p->buf_n;
Packit fb9d21
		need = snprintf(p->buf + p->buf_n, left, "%d", i);
Packit fb9d21
	}
Packit fb9d21
	p->buf_n += need;
Packit fb9d21
	return p;
Packit fb9d21
error:
Packit fb9d21
	isl_printer_free(p);
Packit fb9d21
	return NULL;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
static __isl_give isl_printer *str_print_isl_int(__isl_take isl_printer *p,
Packit fb9d21
	isl_int i)
Packit fb9d21
{
Packit fb9d21
	char *s;
Packit fb9d21
	int len;
Packit fb9d21
Packit fb9d21
	s = isl_int_get_str(i);
Packit fb9d21
	len = strlen(s);
Packit fb9d21
	if (len < p->width)
Packit fb9d21
		p = str_print_indent(p, p->width - len);
Packit fb9d21
	p = str_print(p, s, len);
Packit fb9d21
	isl_int_free_str(s);
Packit fb9d21
	return p;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
struct isl_printer_ops {
Packit fb9d21
	__isl_give isl_printer *(*start_line)(__isl_take isl_printer *p);
Packit fb9d21
	__isl_give isl_printer *(*end_line)(__isl_take isl_printer *p);
Packit fb9d21
	__isl_give isl_printer *(*print_double)(__isl_take isl_printer *p,
Packit fb9d21
		double d);
Packit fb9d21
	__isl_give isl_printer *(*print_int)(__isl_take isl_printer *p, int i);
Packit fb9d21
	__isl_give isl_printer *(*print_isl_int)(__isl_take isl_printer *p,
Packit fb9d21
						isl_int i);
Packit fb9d21
	__isl_give isl_printer *(*print_str)(__isl_take isl_printer *p,
Packit fb9d21
						const char *s);
Packit fb9d21
	__isl_give isl_printer *(*flush)(__isl_take isl_printer *p);
Packit fb9d21
};
Packit fb9d21
Packit fb9d21
static struct isl_printer_ops file_ops = {
Packit fb9d21
	file_start_line,
Packit fb9d21
	file_end_line,
Packit fb9d21
	file_print_double,
Packit fb9d21
	file_print_int,
Packit fb9d21
	file_print_isl_int,
Packit fb9d21
	file_print_str,
Packit fb9d21
	file_flush
Packit fb9d21
};
Packit fb9d21
Packit fb9d21
static struct isl_printer_ops str_ops = {
Packit fb9d21
	str_start_line,
Packit fb9d21
	str_end_line,
Packit fb9d21
	str_print_double,
Packit fb9d21
	str_print_int,
Packit fb9d21
	str_print_isl_int,
Packit fb9d21
	str_print_str,
Packit fb9d21
	str_flush
Packit fb9d21
};
Packit fb9d21
Packit fb9d21
__isl_give isl_printer *isl_printer_to_file(isl_ctx *ctx, FILE *file)
Packit fb9d21
{
Packit fb9d21
	struct isl_printer *p = isl_alloc_type(ctx, struct isl_printer);
Packit fb9d21
	if (!p)
Packit fb9d21
		return NULL;
Packit fb9d21
	p->ctx = ctx;
Packit fb9d21
	isl_ctx_ref(p->ctx);
Packit fb9d21
	p->ops = &file_ops;
Packit fb9d21
	p->file = file;
Packit fb9d21
	p->buf = NULL;
Packit fb9d21
	p->buf_n = 0;
Packit fb9d21
	p->buf_size = 0;
Packit fb9d21
	p->indent = 0;
Packit fb9d21
	p->output_format = ISL_FORMAT_ISL;
Packit fb9d21
	p->indent_prefix = NULL;
Packit fb9d21
	p->prefix = NULL;
Packit fb9d21
	p->suffix = NULL;
Packit fb9d21
	p->width = 0;
Packit fb9d21
Packit fb9d21
	return p;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
__isl_give isl_printer *isl_printer_to_str(isl_ctx *ctx)
Packit fb9d21
{
Packit fb9d21
	struct isl_printer *p = isl_calloc_type(ctx, struct isl_printer);
Packit fb9d21
	if (!p)
Packit fb9d21
		return NULL;
Packit fb9d21
	p->ctx = ctx;
Packit fb9d21
	isl_ctx_ref(p->ctx);
Packit fb9d21
	p->ops = &str_ops;
Packit fb9d21
	p->file = NULL;
Packit fb9d21
	p->buf = isl_alloc_array(ctx, char, 256);
Packit fb9d21
	if (!p->buf)
Packit fb9d21
		goto error;
Packit fb9d21
	p->buf_n = 0;
Packit fb9d21
	p->buf[0] = '\0';
Packit fb9d21
	p->buf_size = 256;
Packit fb9d21
	p->indent = 0;
Packit fb9d21
	p->output_format = ISL_FORMAT_ISL;
Packit fb9d21
	p->indent_prefix = NULL;
Packit fb9d21
	p->prefix = NULL;
Packit fb9d21
	p->suffix = NULL;
Packit fb9d21
	p->width = 0;
Packit fb9d21
Packit fb9d21
	return p;
Packit fb9d21
error:
Packit fb9d21
	isl_printer_free(p);
Packit fb9d21
	return NULL;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
__isl_null isl_printer *isl_printer_free(__isl_take isl_printer *p)
Packit fb9d21
{
Packit fb9d21
	if (!p)
Packit fb9d21
		return NULL;
Packit fb9d21
	free(p->buf);
Packit fb9d21
	free(p->indent_prefix);
Packit fb9d21
	free(p->prefix);
Packit fb9d21
	free(p->suffix);
Packit fb9d21
	isl_ctx_deref(p->ctx);
Packit fb9d21
	free(p);
Packit fb9d21
Packit fb9d21
	return NULL;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
isl_ctx *isl_printer_get_ctx(__isl_keep isl_printer *printer)
Packit fb9d21
{
Packit fb9d21
	return printer ? printer->ctx : NULL;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
FILE *isl_printer_get_file(__isl_keep isl_printer *printer)
Packit fb9d21
{
Packit fb9d21
	if (!printer)
Packit fb9d21
		return NULL;
Packit fb9d21
	if (!printer->file)
Packit fb9d21
		isl_die(isl_printer_get_ctx(printer), isl_error_invalid,
Packit fb9d21
			"not a file printer", return NULL);
Packit fb9d21
	return printer->file;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
__isl_give isl_printer *isl_printer_set_isl_int_width(__isl_take isl_printer *p,
Packit fb9d21
	int width)
Packit fb9d21
{
Packit fb9d21
	if (!p)
Packit fb9d21
		return NULL;
Packit fb9d21
Packit fb9d21
	p->width = width;
Packit fb9d21
Packit fb9d21
	return p;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
__isl_give isl_printer *isl_printer_set_indent(__isl_take isl_printer *p,
Packit fb9d21
	int indent)
Packit fb9d21
{
Packit fb9d21
	if (!p)
Packit fb9d21
		return NULL;
Packit fb9d21
Packit fb9d21
	p->indent = indent;
Packit fb9d21
Packit fb9d21
	return p;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
__isl_give isl_printer *isl_printer_indent(__isl_take isl_printer *p,
Packit fb9d21
	int indent)
Packit fb9d21
{
Packit fb9d21
	if (!p)
Packit fb9d21
		return NULL;
Packit fb9d21
Packit fb9d21
	p->indent += indent;
Packit fb9d21
	if (p->indent < 0)
Packit fb9d21
		p->indent = 0;
Packit fb9d21
Packit fb9d21
	return p;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
/* Replace the indent prefix of "p" by "prefix".
Packit fb9d21
 */
Packit fb9d21
__isl_give isl_printer *isl_printer_set_indent_prefix(__isl_take isl_printer *p,
Packit fb9d21
	const char *prefix)
Packit fb9d21
{
Packit fb9d21
	if (!p)
Packit fb9d21
		return NULL;
Packit fb9d21
Packit fb9d21
	free(p->indent_prefix);
Packit fb9d21
	p->indent_prefix = prefix ? strdup(prefix) : NULL;
Packit fb9d21
Packit fb9d21
	return p;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
__isl_give isl_printer *isl_printer_set_prefix(__isl_take isl_printer *p,
Packit fb9d21
	const char *prefix)
Packit fb9d21
{
Packit fb9d21
	if (!p)
Packit fb9d21
		return NULL;
Packit fb9d21
Packit fb9d21
	free(p->prefix);
Packit fb9d21
	p->prefix = prefix ? strdup(prefix) : NULL;
Packit fb9d21
Packit fb9d21
	return p;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
__isl_give isl_printer *isl_printer_set_suffix(__isl_take isl_printer *p,
Packit fb9d21
	const char *suffix)
Packit fb9d21
{
Packit fb9d21
	if (!p)
Packit fb9d21
		return NULL;
Packit fb9d21
Packit fb9d21
	free(p->suffix);
Packit fb9d21
	p->suffix = suffix ? strdup(suffix) : NULL;
Packit fb9d21
Packit fb9d21
	return p;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
__isl_give isl_printer *isl_printer_set_output_format(__isl_take isl_printer *p,
Packit fb9d21
	int output_format)
Packit fb9d21
{
Packit fb9d21
	if (!p)
Packit fb9d21
		return NULL;
Packit fb9d21
Packit fb9d21
	p->output_format = output_format;
Packit fb9d21
Packit fb9d21
	return p;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
int isl_printer_get_output_format(__isl_keep isl_printer *p)
Packit fb9d21
{
Packit fb9d21
	if (!p)
Packit fb9d21
		return -1;
Packit fb9d21
	return p->output_format;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
__isl_give isl_printer *isl_printer_print_str(__isl_take isl_printer *p,
Packit fb9d21
	const char *s)
Packit fb9d21
{
Packit fb9d21
	if (!p)
Packit fb9d21
		return NULL;
Packit fb9d21
	if (!s)
Packit fb9d21
		return isl_printer_free(p);
Packit fb9d21
Packit fb9d21
	return p->ops->print_str(p, s);
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
__isl_give isl_printer *isl_printer_print_double(__isl_take isl_printer *p,
Packit fb9d21
	double d)
Packit fb9d21
{
Packit fb9d21
	if (!p)
Packit fb9d21
		return NULL;
Packit fb9d21
Packit fb9d21
	return p->ops->print_double(p, d);
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
__isl_give isl_printer *isl_printer_print_int(__isl_take isl_printer *p, int i)
Packit fb9d21
{
Packit fb9d21
	if (!p)
Packit fb9d21
		return NULL;
Packit fb9d21
Packit fb9d21
	return p->ops->print_int(p, i);
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
__isl_give isl_printer *isl_printer_print_isl_int(__isl_take isl_printer *p,
Packit fb9d21
	isl_int i)
Packit fb9d21
{
Packit fb9d21
	if (!p)
Packit fb9d21
		return NULL;
Packit fb9d21
Packit fb9d21
	return p->ops->print_isl_int(p, i);
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
__isl_give isl_printer *isl_printer_start_line(__isl_take isl_printer *p)
Packit fb9d21
{
Packit fb9d21
	if (!p)
Packit fb9d21
		return NULL;
Packit fb9d21
Packit fb9d21
	return p->ops->start_line(p);
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
__isl_give isl_printer *isl_printer_end_line(__isl_take isl_printer *p)
Packit fb9d21
{
Packit fb9d21
	if (!p)
Packit fb9d21
		return NULL;
Packit fb9d21
Packit fb9d21
	return p->ops->end_line(p);
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
char *isl_printer_get_str(__isl_keep isl_printer *printer)
Packit fb9d21
{
Packit fb9d21
	if (!printer || !printer->buf)
Packit fb9d21
		return NULL;
Packit fb9d21
	return strdup(printer->buf);
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
__isl_give isl_printer *isl_printer_flush(__isl_take isl_printer *p)
Packit fb9d21
{
Packit fb9d21
	if (!p)
Packit fb9d21
		return NULL;
Packit fb9d21
Packit fb9d21
	return p->ops->flush(p);
Packit fb9d21
}