add generic isl_map_project_out
[isl.git] / isl_input.c
blob06267b2caed2004437822f3544eb6f4858c00908
1 /*
2 * Copyright 2008-2009 Katholieke Universiteit Leuven
3 * Copyright 2010 INRIA Saclay
5 * Use of this software is governed by the GNU LGPLv2.1 license
7 * Written by Sven Verdoolaege, K.U.Leuven, Departement
8 * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
9 * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
10 * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France
13 #include <ctype.h>
14 #include <stdio.h>
15 #include <string.h>
16 #include <strings.h>
17 #include <isl_set.h>
18 #include <isl_seq.h>
19 #include "isl_stream.h"
20 #include "isl_map_private.h"
22 struct variable {
23 char *name;
24 int pos;
25 struct variable *next;
28 struct vars {
29 struct isl_ctx *ctx;
30 int n;
31 struct variable *v;
34 static struct vars *vars_new(struct isl_ctx *ctx)
36 struct vars *v;
37 v = isl_alloc_type(ctx, struct vars);
38 if (!v)
39 return NULL;
40 v->ctx = ctx;
41 v->n = 0;
42 v->v = NULL;
43 return v;
46 static void variable_free(struct variable *var)
48 while (var) {
49 struct variable *next = var->next;
50 free(var->name);
51 free(var);
52 var = next;
56 static void vars_free(struct vars *v)
58 if (!v)
59 return;
60 variable_free(v->v);
61 free(v);
64 static struct variable *variable_new(struct vars *v, const char *name, int len,
65 int pos)
67 struct variable *var;
68 var = isl_alloc_type(v->ctx, struct variable);
69 if (!var)
70 goto error;
71 var->name = strdup(name);
72 var->name[len] = '\0';
73 var->pos = pos;
74 var->next = v->v;
75 return var;
76 error:
77 variable_free(v->v);
78 return NULL;
81 static int vars_pos(struct vars *v, const char *s, int len)
83 int pos;
84 struct variable *q;
86 if (len == -1)
87 len = strlen(s);
88 for (q = v->v; q; q = q->next) {
89 if (strncmp(q->name, s, len) == 0 && q->name[len] == '\0')
90 break;
92 if (q)
93 pos = q->pos;
94 else {
95 pos = v->n;
96 v->v = variable_new(v, s, len, v->n);
97 if (!v->v)
98 return -1;
99 v->n++;
101 return pos;
104 static struct vars *read_var_list(struct isl_stream *s, struct vars *v)
106 struct isl_token *tok;
108 while ((tok = isl_stream_next_token(s)) != NULL) {
109 int p;
110 int n = v->n;
112 if (tok->type != ISL_TOKEN_IDENT)
113 break;
115 p = vars_pos(v, tok->u.s, -1);
116 if (p < 0)
117 goto error;
118 if (p < n) {
119 isl_stream_error(s, tok, "expecting unique identifier");
120 goto error;
122 isl_token_free(tok);
123 tok = isl_stream_next_token(s);
124 if (!tok || tok->type != ',')
125 break;
127 isl_token_free(tok);
129 if (tok)
130 isl_stream_push_token(s, tok);
132 return v;
133 error:
134 isl_token_free(tok);
135 vars_free(v);
136 return NULL;
139 static struct isl_vec *accept_affine(struct isl_stream *s, struct vars *v)
141 struct isl_token *tok = NULL;
142 struct isl_vec *aff;
143 int sign = 1;
145 aff = isl_vec_alloc(v->ctx, 1 + v->n);
146 isl_seq_clr(aff->el, aff->size);
147 if (!aff)
148 return NULL;
150 for (;;) {
151 tok = isl_stream_next_token(s);
152 if (!tok) {
153 isl_stream_error(s, NULL, "unexpected EOF");
154 goto error;
156 if (tok->type == ISL_TOKEN_IDENT) {
157 int n = v->n;
158 int pos = vars_pos(v, tok->u.s, -1);
159 if (pos < 0)
160 goto error;
161 if (pos >= n) {
162 isl_stream_error(s, tok, "unknown identifier");
163 goto error;
165 if (sign > 0)
166 isl_int_add_ui(aff->el[1 + pos],
167 aff->el[1 + pos], 1);
168 else
169 isl_int_sub_ui(aff->el[1 + pos],
170 aff->el[1 + pos], 1);
171 sign = 1;
172 } else if (tok->type == ISL_TOKEN_VALUE) {
173 struct isl_token *tok2;
174 int n = v->n;
175 int pos = -1;
176 tok2 = isl_stream_next_token(s);
177 if (tok2 && tok2->type == ISL_TOKEN_IDENT) {
178 pos = vars_pos(v, tok2->u.s, -1);
179 if (pos < 0)
180 goto error;
181 if (pos >= n) {
182 isl_stream_error(s, tok2,
183 "unknown identifier");
184 isl_token_free(tok2);
185 goto error;
187 isl_token_free(tok2);
188 } else if (tok2)
189 isl_stream_push_token(s, tok2);
190 if (sign < 0)
191 isl_int_neg(tok->u.v, tok->u.v);
192 isl_int_add(aff->el[1 + pos],
193 aff->el[1 + pos], tok->u.v);
194 sign = 1;
195 } else if (tok->type == '-') {
196 sign = -sign;
197 } else if (tok->type == '+') {
198 /* nothing */
199 } else {
200 isl_stream_push_token(s, tok);
201 break;
203 isl_token_free(tok);
206 return aff;
207 error:
208 isl_vec_free(aff);
209 return NULL;
212 static struct isl_basic_map *add_div_definition(struct isl_stream *s,
213 struct vars *v, struct isl_basic_map *bmap, int k)
215 struct isl_token *tok;
216 int seen_paren = 0;
217 struct isl_vec *aff;
219 if (isl_stream_eat(s, '['))
220 goto error;
222 tok = isl_stream_next_token(s);
223 if (!tok)
224 goto error;
225 if (tok->type == '(') {
226 seen_paren = 1;
227 isl_token_free(tok);
228 } else
229 isl_stream_push_token(s, tok);
231 aff = accept_affine(s, v);
232 if (!aff)
233 goto error;
235 isl_seq_cpy(bmap->div[k] + 1, aff->el, aff->size);
237 isl_vec_free(aff);
239 if (seen_paren && isl_stream_eat(s, ')'))
240 goto error;
241 if (isl_stream_eat(s, '/'))
242 goto error;
244 tok = isl_stream_next_token(s);
245 if (!tok)
246 goto error;
247 if (tok->type != ISL_TOKEN_VALUE) {
248 isl_stream_error(s, tok, "expected denominator");
249 isl_stream_push_token(s, tok);
250 goto error;
252 isl_int_set(bmap->div[k][0], tok->u.v);
253 isl_token_free(tok);
255 if (isl_stream_eat(s, ']'))
256 goto error;
258 if (isl_basic_map_add_div_constraints(bmap, k) < 0)
259 goto error;
261 return bmap;
262 error:
263 isl_basic_map_free(bmap);
264 return NULL;
267 static struct isl_basic_map *read_defined_var_list(struct isl_stream *s,
268 struct vars *v, struct isl_basic_map *bmap)
270 struct isl_token *tok;
272 while ((tok = isl_stream_next_token(s)) != NULL) {
273 int k;
274 int p;
275 int n = v->n;
276 unsigned total = isl_basic_map_total_dim(bmap);
278 if (tok->type != ISL_TOKEN_IDENT)
279 break;
281 p = vars_pos(v, tok->u.s, -1);
282 if (p < 0)
283 goto error;
284 if (p < n) {
285 isl_stream_error(s, tok, "expecting unique identifier");
286 goto error;
288 isl_token_free(tok);
290 bmap = isl_basic_map_cow(bmap);
291 bmap = isl_basic_map_extend_dim(bmap, isl_dim_copy(bmap->dim),
292 1, 0, 2);
294 if ((k = isl_basic_map_alloc_div(bmap)) < 0)
295 goto error;
296 isl_seq_clr(bmap->div[k], 1 + 1 + total);
298 tok = isl_stream_next_token(s);
299 if (tok && tok->type == '=') {
300 isl_token_free(tok);
301 bmap = add_div_definition(s, v, bmap, k);
302 tok = isl_stream_next_token(s);
305 if (!tok || tok->type != ',')
306 break;
308 isl_token_free(tok);
310 if (tok)
311 isl_stream_push_token(s, tok);
313 return bmap;
314 error:
315 isl_token_free(tok);
316 isl_basic_map_free(bmap);
317 return NULL;
320 static struct vars *read_tuple(struct isl_stream *s, struct vars *v)
322 struct isl_token *tok;
324 tok = isl_stream_next_token(s);
325 if (!tok || tok->type != '[') {
326 isl_stream_error(s, tok, "expecting '['");
327 goto error;
329 isl_token_free(tok);
330 v = read_var_list(s, v);
331 tok = isl_stream_next_token(s);
332 if (!tok || tok->type != ']') {
333 isl_stream_error(s, tok, "expecting ']'");
334 goto error;
336 isl_token_free(tok);
338 return v;
339 error:
340 if (tok)
341 isl_token_free(tok);
342 vars_free(v);
343 return NULL;
346 static struct isl_basic_map *add_constraints(struct isl_stream *s,
347 struct vars **v, struct isl_basic_map *bmap);
349 static struct isl_basic_map *add_exists(struct isl_stream *s,
350 struct vars **v, struct isl_basic_map *bmap)
352 struct isl_token *tok;
353 int n = (*v)->n;
354 int extra;
355 int seen_paren = 0;
356 int i;
357 unsigned total;
359 tok = isl_stream_next_token(s);
360 if (!tok)
361 goto error;
362 if (tok->type == '(') {
363 seen_paren = 1;
364 isl_token_free(tok);
365 } else
366 isl_stream_push_token(s, tok);
368 bmap = read_defined_var_list(s, *v, bmap);
369 if (!bmap)
370 goto error;
372 if (isl_stream_eat(s, ':'))
373 goto error;
374 bmap = add_constraints(s, v, bmap);
375 if (seen_paren && isl_stream_eat(s, ')'))
376 goto error;
377 return bmap;
378 error:
379 isl_basic_map_free(bmap);
380 return NULL;
383 static struct isl_basic_map *add_constraint(struct isl_stream *s,
384 struct vars **v, struct isl_basic_map *bmap)
386 unsigned total = isl_basic_map_total_dim(bmap);
387 int k;
388 struct isl_token *tok = NULL;
389 struct isl_vec *aff1 = NULL, *aff2 = NULL;
391 tok = isl_stream_next_token(s);
392 if (!tok)
393 goto error;
394 if (tok->type == ISL_TOKEN_EXISTS) {
395 isl_token_free(tok);
396 return add_exists(s, v, bmap);
398 isl_stream_push_token(s, tok);
399 tok = NULL;
401 bmap = isl_basic_map_cow(bmap);
402 bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
403 k = isl_basic_map_alloc_inequality(bmap);
404 if (k < 0)
405 goto error;
407 aff1 = accept_affine(s, *v);
408 if (!aff1)
409 goto error;
410 tok = isl_stream_next_token(s);
411 switch (tok->type) {
412 case ISL_TOKEN_LT:
413 case ISL_TOKEN_GT:
414 case ISL_TOKEN_LE:
415 case ISL_TOKEN_GE:
416 case '=':
417 break;
418 default:
419 isl_stream_error(s, tok, "missing operator");
420 isl_stream_push_token(s, tok);
421 tok = NULL;
422 goto error;
424 aff2 = accept_affine(s, *v);
425 if (!aff2)
426 goto error;
427 isl_assert(aff1->ctx, aff1->size == 1 + total, goto error);
428 isl_assert(aff2->ctx, aff2->size == 1 + total, goto error);
430 if (tok->type == ISL_TOKEN_LE)
431 isl_seq_combine(bmap->ineq[k], (*v)->ctx->negone, aff1->el,
432 (*v)->ctx->one, aff2->el,
433 aff1->size);
434 else if (tok->type == ISL_TOKEN_GE)
435 isl_seq_combine(bmap->ineq[k], (*v)->ctx->one, aff1->el,
436 (*v)->ctx->negone, aff2->el,
437 aff1->size);
438 else if (tok->type == ISL_TOKEN_LT) {
439 isl_seq_combine(bmap->ineq[k], (*v)->ctx->negone, aff1->el,
440 (*v)->ctx->one, aff2->el,
441 aff1->size);
442 isl_int_sub_ui(bmap->ineq[k][0], bmap->ineq[k][0], 1);
443 } else if (tok->type == ISL_TOKEN_GT) {
444 isl_seq_combine(bmap->ineq[k], (*v)->ctx->one, aff1->el,
445 (*v)->ctx->negone, aff2->el,
446 aff1->size);
447 isl_int_sub_ui(bmap->ineq[k][0], bmap->ineq[k][0], 1);
448 } else {
449 isl_seq_combine(bmap->ineq[k], (*v)->ctx->one, aff1->el,
450 (*v)->ctx->negone, aff2->el,
451 aff1->size);
452 isl_basic_map_inequality_to_equality(bmap, k);
454 isl_token_free(tok);
455 isl_vec_free(aff1);
456 isl_vec_free(aff2);
458 return bmap;
459 error:
460 if (tok)
461 isl_token_free(tok);
462 isl_vec_free(aff1);
463 isl_vec_free(aff2);
464 isl_basic_map_free(bmap);
465 return NULL;
468 static struct isl_basic_map *add_constraints(struct isl_stream *s,
469 struct vars **v, struct isl_basic_map *bmap)
471 struct isl_token *tok;
473 for (;;) {
474 bmap = add_constraint(s, v, bmap);
475 if (!bmap)
476 return NULL;
477 tok = isl_stream_next_token(s);
478 if (!tok) {
479 isl_stream_error(s, NULL, "unexpected EOF");
480 goto error;
482 if (tok->type != ISL_TOKEN_AND)
483 break;
484 isl_token_free(tok);
486 isl_stream_push_token(s, tok);
488 return bmap;
489 error:
490 if (tok)
491 isl_token_free(tok);
492 isl_basic_map_free(bmap);
493 return NULL;
496 static struct isl_basic_map *read_disjunct(struct isl_stream *s,
497 struct vars **v, __isl_take isl_dim *dim)
499 struct isl_basic_map *bmap;
501 bmap = isl_basic_map_alloc_dim(dim, 0, 0, 0);
502 if (!bmap)
503 return NULL;
505 bmap = add_constraints(s, v, bmap);
506 bmap = isl_basic_map_simplify(bmap);
507 bmap = isl_basic_map_finalize(bmap);
508 return bmap;
511 static struct isl_map *read_disjuncts(struct isl_stream *s,
512 struct vars **v, __isl_take isl_dim *dim)
514 struct isl_token *tok;
515 struct isl_map *map;
517 tok = isl_stream_next_token(s);
518 if (!tok) {
519 isl_stream_error(s, NULL, "unexpected EOF");
520 goto error;
522 if (tok->type == '}') {
523 isl_stream_push_token(s, tok);
524 return isl_map_universe(dim);
526 isl_stream_push_token(s, tok);
528 map = isl_map_empty(isl_dim_copy(dim));
529 for (;;) {
530 struct isl_basic_map *bmap;
532 bmap = read_disjunct(s, v, isl_dim_copy(dim));
533 map = isl_map_union(map, isl_map_from_basic_map(bmap));
535 tok = isl_stream_next_token(s);
536 if (!tok || tok->type != ISL_TOKEN_OR)
537 break;
538 isl_token_free(tok);
540 if (tok)
541 isl_stream_push_token(s, tok);
543 isl_dim_free(dim);
544 return map;
545 error:
546 isl_dim_free(dim);
547 return NULL;
550 static __isl_give isl_basic_map *basic_map_read_polylib_constraint(
551 struct isl_stream *s, __isl_take isl_basic_map *bmap)
553 int j;
554 struct isl_token *tok;
555 int type;
556 int k;
557 isl_int *c;
558 unsigned nparam;
559 unsigned dim;
561 if (!bmap)
562 return NULL;
564 nparam = isl_basic_map_dim(bmap, isl_dim_param);
565 dim = isl_basic_map_dim(bmap, isl_dim_out);
567 tok = isl_stream_next_token(s);
568 if (!tok || tok->type != ISL_TOKEN_VALUE) {
569 isl_stream_error(s, tok, "expecting coefficient");
570 if (tok)
571 isl_stream_push_token(s, tok);
572 goto error;
574 if (!tok->on_new_line) {
575 isl_stream_error(s, tok, "coefficient should appear on new line");
576 isl_stream_push_token(s, tok);
577 goto error;
580 type = isl_int_get_si(tok->u.v);
581 isl_token_free(tok);
583 isl_assert(s->ctx, type == 0 || type == 1, goto error);
584 if (type == 0) {
585 k = isl_basic_map_alloc_equality(bmap);
586 c = bmap->eq[k];
587 } else {
588 k = isl_basic_map_alloc_inequality(bmap);
589 c = bmap->ineq[k];
591 if (k < 0)
592 goto error;
594 for (j = 0; j < dim; ++j) {
595 tok = isl_stream_next_token(s);
596 if (!tok || tok->type != ISL_TOKEN_VALUE) {
597 isl_stream_error(s, tok, "expecting coefficient");
598 if (tok)
599 isl_stream_push_token(s, tok);
600 goto error;
602 isl_int_set(c[1 + nparam + j], tok->u.v);
603 isl_token_free(tok);
605 for (j = 0; j < nparam; ++j) {
606 tok = isl_stream_next_token(s);
607 if (!tok || tok->type != ISL_TOKEN_VALUE) {
608 isl_stream_error(s, tok, "expecting coefficient");
609 if (tok)
610 isl_stream_push_token(s, tok);
611 goto error;
613 isl_int_set(c[1 + j], tok->u.v);
614 isl_token_free(tok);
616 tok = isl_stream_next_token(s);
617 if (!tok || tok->type != ISL_TOKEN_VALUE) {
618 isl_stream_error(s, tok, "expecting coefficient");
619 if (tok)
620 isl_stream_push_token(s, tok);
621 goto error;
623 isl_int_set(c[0], tok->u.v);
624 isl_token_free(tok);
626 return bmap;
627 error:
628 isl_basic_map_free(bmap);
629 return NULL;
632 static __isl_give isl_basic_map *basic_map_read_polylib(struct isl_stream *s,
633 int nparam)
635 int i;
636 struct isl_token *tok;
637 struct isl_token *tok2;
638 int n_row, n_col;
639 int on_new_line;
640 unsigned dim;
641 struct isl_basic_map *bmap = NULL;
643 if (nparam < 0)
644 nparam = 0;
646 tok = isl_stream_next_token(s);
647 if (!tok) {
648 isl_stream_error(s, NULL, "unexpected EOF");
649 return NULL;
651 tok2 = isl_stream_next_token(s);
652 if (!tok2) {
653 isl_token_free(tok);
654 isl_stream_error(s, NULL, "unexpected EOF");
655 return NULL;
657 n_row = isl_int_get_si(tok->u.v);
658 n_col = isl_int_get_si(tok2->u.v);
659 on_new_line = tok2->on_new_line;
660 isl_token_free(tok2);
661 isl_token_free(tok);
662 isl_assert(s->ctx, !on_new_line, return NULL);
663 isl_assert(s->ctx, n_row >= 0, return NULL);
664 isl_assert(s->ctx, n_col >= 2 + nparam, return NULL);
665 dim = n_col - 2 - nparam;
666 bmap = isl_basic_map_alloc(s->ctx, nparam, 0, dim, 0, n_row, n_row);
667 if (!bmap)
668 return NULL;
670 for (i = 0; i < n_row; ++i)
671 bmap = basic_map_read_polylib_constraint(s, bmap);
673 bmap = isl_basic_map_simplify(bmap);
674 bmap = isl_basic_map_finalize(bmap);
675 return bmap;
678 static struct isl_map *map_read_polylib(struct isl_stream *s, int nparam)
680 struct isl_token *tok;
681 struct isl_token *tok2;
682 int i, n;
683 struct isl_map *map;
685 tok = isl_stream_next_token(s);
686 if (!tok) {
687 isl_stream_error(s, NULL, "unexpected EOF");
688 return NULL;
690 tok2 = isl_stream_next_token(s);
691 if (!tok2) {
692 isl_token_free(tok);
693 isl_stream_error(s, NULL, "unexpected EOF");
694 return NULL;
696 if (!tok2->on_new_line) {
697 isl_stream_push_token(s, tok2);
698 isl_stream_push_token(s, tok);
699 return isl_map_from_basic_map(basic_map_read_polylib(s, nparam));
701 isl_stream_push_token(s, tok2);
702 n = isl_int_get_si(tok->u.v);
703 isl_token_free(tok);
705 isl_assert(s->ctx, n >= 1, return NULL);
707 map = isl_map_from_basic_map(basic_map_read_polylib(s, nparam));
709 for (i = 1; i < n; ++i)
710 map = isl_map_union(map,
711 isl_map_from_basic_map(basic_map_read_polylib(s, nparam)));
713 return map;
716 static struct isl_dim *set_names(struct isl_dim *dim, struct vars *vars,
717 enum isl_dim_type type, int offset, int n)
719 int i;
720 struct variable *v;
722 for (i = 0, v = vars->v; i < offset; ++i, v = v->next)
724 for (i = n - 1; i >= 0; --i, v = v->next)
725 dim = isl_dim_set_name(dim, type, i, v->name);
727 return dim;
730 static struct isl_dim *dim_from_vars(struct vars *vars,
731 int nparam, int n_in, int n_out)
733 struct isl_dim *dim;
735 dim = isl_dim_alloc(vars->ctx, nparam, n_in, n_out);
736 dim = set_names(dim, vars, isl_dim_param, n_out + n_in, nparam);
737 dim = set_names(dim, vars, isl_dim_in, n_out, n_in);
738 dim = set_names(dim, vars, isl_dim_out, 0, n_out);
740 return dim;
743 static struct isl_map *map_read(struct isl_stream *s, int nparam)
745 struct isl_dim *dim = NULL;
746 struct isl_map *map = NULL;
747 struct isl_token *tok;
748 struct vars *v = NULL;
749 int n1;
750 int n2;
752 tok = isl_stream_next_token(s);
753 if (!tok) {
754 isl_stream_error(s, NULL, "unexpected EOF");
755 goto error;
757 if (tok->type == ISL_TOKEN_VALUE) {
758 isl_stream_push_token(s, tok);
759 return map_read_polylib(s, nparam);
761 v = vars_new(s->ctx);
762 if (tok->type == '[') {
763 isl_stream_push_token(s, tok);
764 v = read_tuple(s, v);
765 if (!v)
766 return NULL;
767 if (nparam >= 0)
768 isl_assert(s->ctx, nparam == v->n, goto error);
769 nparam = v->n;
770 tok = isl_stream_next_token(s);
771 if (!tok || tok->type != ISL_TOKEN_TO) {
772 isl_stream_error(s, tok, "expecting '->'");
773 if (tok)
774 isl_stream_push_token(s, tok);
775 goto error;
777 isl_token_free(tok);
778 tok = isl_stream_next_token(s);
780 if (nparam < 0)
781 nparam = 0;
782 if (!tok || tok->type != '{') {
783 isl_stream_error(s, tok, "expecting '{'");
784 if (tok)
785 isl_stream_push_token(s, tok);
786 goto error;
788 isl_token_free(tok);
789 v = read_tuple(s, v);
790 if (!v)
791 return NULL;
792 n1 = v->n - nparam;
793 tok = isl_stream_next_token(s);
794 if (tok && tok->type == ISL_TOKEN_TO) {
795 isl_token_free(tok);
796 v = read_tuple(s, v);
797 if (!v)
798 return NULL;
799 n2 = v->n - n1 - nparam;
800 } else {
801 if (tok)
802 isl_stream_push_token(s, tok);
803 n2 = n1;
804 n1 = 0;
806 dim = dim_from_vars(v, nparam, n1, n2);
807 tok = isl_stream_next_token(s);
808 if (!tok) {
809 isl_stream_error(s, NULL, "unexpected EOF");
810 goto error;
812 if (tok->type == ':') {
813 isl_token_free(tok);
814 map = read_disjuncts(s, &v, isl_dim_copy(dim));
815 tok = isl_stream_next_token(s);
816 } else
817 map = isl_map_universe(isl_dim_copy(dim));
818 if (tok && tok->type == '}') {
819 isl_token_free(tok);
820 } else {
821 isl_stream_error(s, tok, "unexpected isl_token");
822 if (tok)
823 isl_token_free(tok);
824 goto error;
826 vars_free(v);
827 isl_dim_free(dim);
829 return map;
830 error:
831 isl_dim_free(dim);
832 isl_map_free(map);
833 if (v)
834 vars_free(v);
835 return NULL;
838 static struct isl_basic_map *basic_map_read(struct isl_stream *s, int nparam)
840 struct isl_map *map;
841 struct isl_basic_map *bmap;
843 map = map_read(s, nparam);
844 if (!map)
845 return NULL;
847 isl_assert(map->ctx, map->n <= 1, goto error);
849 if (map->n == 0)
850 bmap = isl_basic_map_empty_like_map(map);
851 else
852 bmap = isl_basic_map_copy(map->p[0]);
854 isl_map_free(map);
856 return bmap;
857 error:
858 isl_map_free(map);
859 return NULL;
862 __isl_give isl_basic_map *isl_basic_map_read_from_file(isl_ctx *ctx,
863 FILE *input, int nparam)
865 struct isl_basic_map *bmap;
866 struct isl_stream *s = isl_stream_new_file(ctx, input);
867 if (!s)
868 return NULL;
869 bmap = basic_map_read(s, nparam);
870 isl_stream_free(s);
871 return bmap;
874 __isl_give isl_basic_set *isl_basic_set_read_from_file(isl_ctx *ctx,
875 FILE *input, int nparam)
877 struct isl_basic_map *bmap;
878 bmap = isl_basic_map_read_from_file(ctx, input, nparam);
879 if (!bmap)
880 return NULL;
881 isl_assert(ctx, isl_basic_map_n_in(bmap) == 0, goto error);
882 return (struct isl_basic_set *)bmap;
883 error:
884 isl_basic_map_free(bmap);
885 return NULL;
888 struct isl_basic_map *isl_basic_map_read_from_str(struct isl_ctx *ctx,
889 const char *str, int nparam)
891 struct isl_basic_map *bmap;
892 struct isl_stream *s = isl_stream_new_str(ctx, str);
893 if (!s)
894 return NULL;
895 bmap = basic_map_read(s, nparam);
896 isl_stream_free(s);
897 return bmap;
900 struct isl_basic_set *isl_basic_set_read_from_str(struct isl_ctx *ctx,
901 const char *str, int nparam)
903 struct isl_basic_map *bmap;
904 bmap = isl_basic_map_read_from_str(ctx, str, nparam);
905 if (!bmap)
906 return NULL;
907 isl_assert(ctx, isl_basic_map_n_in(bmap) == 0, goto error);
908 return (struct isl_basic_set *)bmap;
909 error:
910 isl_basic_map_free(bmap);
911 return NULL;
914 __isl_give isl_map *isl_map_read_from_file(struct isl_ctx *ctx,
915 FILE *input, int nparam)
917 struct isl_map *map;
918 struct isl_stream *s = isl_stream_new_file(ctx, input);
919 if (!s)
920 return NULL;
921 map = map_read(s, nparam);
922 isl_stream_free(s);
923 return map;
926 __isl_give isl_map *isl_map_read_from_str(struct isl_ctx *ctx,
927 const char *str, int nparam)
929 struct isl_map *map;
930 struct isl_stream *s = isl_stream_new_str(ctx, str);
931 if (!s)
932 return NULL;
933 map = map_read(s, nparam);
934 isl_stream_free(s);
935 return map;
938 __isl_give isl_set *isl_set_read_from_file(struct isl_ctx *ctx,
939 FILE *input, int nparam)
941 struct isl_map *map;
942 map = isl_map_read_from_file(ctx, input, nparam);
943 if (!map)
944 return NULL;
945 isl_assert(ctx, isl_map_n_in(map) == 0, goto error);
946 return (struct isl_set *)map;
947 error:
948 isl_map_free(map);
949 return NULL;
952 struct isl_set *isl_set_read_from_str(struct isl_ctx *ctx,
953 const char *str, int nparam)
955 struct isl_map *map;
956 map = isl_map_read_from_str(ctx, str, nparam);
957 if (!map)
958 return NULL;
959 isl_assert(ctx, isl_map_n_in(map) == 0, goto error);
960 return (struct isl_set *)map;
961 error:
962 isl_map_free(map);
963 return NULL;
966 static char *next_line(FILE *input, char *line, unsigned len)
968 char *p;
970 do {
971 if (!(p = fgets(line, len, input)))
972 return NULL;
973 while (isspace(*p) && *p != '\n')
974 ++p;
975 } while (*p == '#' || *p == '\n');
977 return p;
980 static struct isl_vec *isl_vec_read_from_file_polylib(struct isl_ctx *ctx,
981 FILE *input)
983 struct isl_vec *vec = NULL;
984 char line[1024];
985 char val[1024];
986 char *p;
987 unsigned size;
988 int j;
989 int n;
990 int offset;
992 isl_assert(ctx, next_line(input, line, sizeof(line)), return NULL);
993 isl_assert(ctx, sscanf(line, "%u", &size) == 1, return NULL);
995 vec = isl_vec_alloc(ctx, size);
997 p = next_line(input, line, sizeof(line));
998 isl_assert(ctx, p, goto error);
1000 for (j = 0; j < size; ++j) {
1001 n = sscanf(p, "%s%n", val, &offset);
1002 isl_assert(ctx, n != 0, goto error);
1003 isl_int_read(vec->el[j], val);
1004 p += offset;
1007 return vec;
1008 error:
1009 isl_vec_free(vec);
1010 return NULL;
1013 struct isl_vec *isl_vec_read_from_file(struct isl_ctx *ctx,
1014 FILE *input, unsigned input_format)
1016 if (input_format == ISL_FORMAT_POLYLIB)
1017 return isl_vec_read_from_file_polylib(ctx, input);
1018 else
1019 isl_assert(ctx, 0, return NULL);