isl_basic_map_read: read affine constraint as two affine expressions + operator
[platform/upstream/isl.git] / isl_input.c
1 /*
2  * Copyright 2008-2009 Katholieke Universiteit Leuven
3  * Copyright 2010      INRIA Saclay
4  *
5  * Use of this software is governed by the GNU LGPLv2.1 license
6  *
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 
11  */
12
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"
21
22 struct variable {
23         char                    *name;
24         int                      pos;
25         struct variable         *next;
26 };
27
28 struct vars {
29         struct isl_ctx  *ctx;
30         int              n;
31         struct variable *v;
32 };
33
34 static struct vars *vars_new(struct isl_ctx *ctx)
35 {
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;
44 }
45
46 static void variable_free(struct variable *var)
47 {
48         while (var) {
49                 struct variable *next = var->next;
50                 free(var->name);
51                 free(var);
52                 var = next;
53         }
54 }
55
56 static void vars_free(struct vars *v)
57 {
58         if (!v)
59                 return;
60         variable_free(v->v);
61         free(v);
62 }
63
64 static struct variable *variable_new(struct vars *v, const char *name, int len,
65                                 int pos)
66 {
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;
79 }
80
81 static int vars_pos(struct vars *v, const char *s, int len)
82 {
83         int pos;
84         struct variable *q;
85
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;
91         }
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++;
100         }
101         return pos;
102 }
103
104 static struct vars *read_var_list(struct isl_stream *s, struct vars *v)
105 {
106         struct isl_token *tok;
107
108         while ((tok = isl_stream_next_token(s)) != NULL) {
109                 int p;
110                 int n = v->n;
111
112                 if (tok->type != ISL_TOKEN_IDENT)
113                         break;
114
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;
121                 }
122                 isl_token_free(tok);
123                 tok = isl_stream_next_token(s);
124                 if (!tok || tok->type != ',')
125                         break;
126
127                 isl_token_free(tok);
128         }
129         if (tok)
130                 isl_stream_push_token(s, tok);
131
132         return v;
133 error:
134         isl_token_free(tok);
135         vars_free(v);
136         return NULL;
137 }
138
139 static struct vars *read_tuple(struct isl_stream *s, struct vars *v)
140 {
141         struct isl_token *tok;
142
143         tok = isl_stream_next_token(s);
144         if (!tok || tok->type != '[') {
145                 isl_stream_error(s, tok, "expecting '['");
146                 goto error;
147         }
148         isl_token_free(tok);
149         v = read_var_list(s, v);
150         tok = isl_stream_next_token(s);
151         if (!tok || tok->type != ']') {
152                 isl_stream_error(s, tok, "expecting ']'");
153                 goto error;
154         }
155         isl_token_free(tok);
156
157         return v;
158 error:
159         if (tok)
160                 isl_token_free(tok);
161         vars_free(v);
162         return NULL;
163 }
164
165 static struct isl_basic_map *add_constraints(struct isl_stream *s,
166         struct vars **v, struct isl_basic_map *bmap);
167
168 static struct isl_basic_map *add_exists(struct isl_stream *s,
169         struct vars **v, struct isl_basic_map *bmap)
170 {
171         struct isl_token *tok;
172         int n = (*v)->n;
173         int extra;
174         int seen_paren = 0;
175         int i;
176         unsigned total;
177
178         tok = isl_stream_next_token(s);
179         if (!tok)
180                 goto error;
181         if (tok->type == '(') {
182                 seen_paren = 1;
183                 isl_token_free(tok);
184         } else
185                 isl_stream_push_token(s, tok);
186         *v = read_var_list(s, *v);
187         if (!*v)
188                 goto error;
189         extra = (*v)->n - n;
190         bmap = isl_basic_map_cow(bmap);
191         bmap = isl_basic_map_extend_dim(bmap, isl_dim_copy(bmap->dim),
192                         extra, 0, 0);
193         total = isl_basic_map_total_dim(bmap);
194         for (i = 0; i < extra; ++i) {
195                 int k;
196                 if ((k = isl_basic_map_alloc_div(bmap)) < 0)
197                         goto error;
198                 isl_seq_clr(bmap->div[k], 1+1+total);
199         }
200         if (!bmap)
201                 return NULL;
202         if (isl_stream_eat(s, ':'))
203                 goto error;
204         bmap = add_constraints(s, v, bmap);
205         if (seen_paren && isl_stream_eat(s, ')'))
206                 goto error;
207         return bmap;
208 error:
209         isl_basic_map_free(bmap);
210         return NULL;
211 }
212
213 static struct isl_vec *accept_affine(struct isl_stream *s, struct vars *v)
214 {
215         struct isl_token *tok = NULL;
216         struct isl_vec *aff;
217
218         aff = isl_vec_alloc(v->ctx, 1 + v->n);
219         isl_seq_clr(aff->el, aff->size);
220         if (!aff)
221                 return NULL;
222
223         for (;;) {
224                 tok = isl_stream_next_token(s);
225                 if (!tok) {
226                         isl_stream_error(s, NULL, "unexpected EOF");
227                         goto error;
228                 }
229                 if (tok->type == ISL_TOKEN_IDENT) {
230                         int n = v->n;
231                         int pos = vars_pos(v, tok->u.s, -1);
232                         if (pos < 0)
233                                 goto error;
234                         if (pos >= n) {
235                                 isl_stream_error(s, tok, "unknown identifier");
236                                 goto error;
237                         }
238                         isl_int_add_ui(aff->el[1 + pos], aff->el[1 + pos], 1);
239                 } else if (tok->type == ISL_TOKEN_VALUE) {
240                         struct isl_token *tok2;
241                         int n = v->n;
242                         int pos = -1;
243                         tok2 = isl_stream_next_token(s);
244                         if (tok2 && tok2->type == ISL_TOKEN_IDENT) {
245                                 pos = vars_pos(v, tok2->u.s, -1);
246                                 if (pos < 0)
247                                         goto error;
248                                 if (pos >= n) {
249                                         isl_stream_error(s, tok2,
250                                                 "unknown identifier");
251                                         isl_token_free(tok2);
252                                         goto error;
253                                 }
254                                 isl_token_free(tok2);
255                         } else if (tok2)
256                                 isl_stream_push_token(s, tok2);
257                         isl_int_add(aff->el[1 + pos],
258                                         aff->el[1 + pos], tok->u.v);
259                 } else if (tok->type == '+') {
260                         /* nothing */
261                 } else {
262                         isl_stream_push_token(s, tok);
263                         break;
264                 }
265                 isl_token_free(tok);
266         }
267
268         return aff;
269 error:
270         isl_vec_free(aff);
271         return NULL;
272 }
273
274 static struct isl_basic_map *add_constraint(struct isl_stream *s,
275         struct vars **v, struct isl_basic_map *bmap)
276 {
277         unsigned total = isl_basic_map_total_dim(bmap);
278         int k;
279         struct isl_token *tok = NULL;
280         struct isl_vec *aff1 = NULL, *aff2 = NULL;
281
282         tok = isl_stream_next_token(s);
283         if (!tok)
284                 goto error;
285         if (tok->type == ISL_TOKEN_EXISTS) {
286                 isl_token_free(tok);
287                 return add_exists(s, v, bmap);
288         }
289         isl_stream_push_token(s, tok);
290         tok = NULL;
291
292         bmap = isl_basic_map_cow(bmap);
293         bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
294         k = isl_basic_map_alloc_inequality(bmap);
295         if (k < 0)
296                 goto error;
297
298         aff1 = accept_affine(s, *v);
299         if (!aff1)
300                 goto error;
301         tok = isl_stream_next_token(s);
302         switch (tok->type) {
303         case ISL_TOKEN_LE:
304         case ISL_TOKEN_GE:
305         case '=':
306                 break;
307         default:
308                 isl_stream_error(s, tok, "missing operator");
309                 isl_stream_push_token(s, tok);
310                 goto error;
311         }
312         aff2 = accept_affine(s, *v);
313         if (!aff2)
314                 goto error;
315         isl_assert(aff1->ctx, aff1->size == 1 + total, goto error);
316         isl_assert(aff2->ctx, aff2->size == 1 + total, goto error);
317
318         if (tok->type == ISL_TOKEN_LE)
319                 isl_seq_combine(bmap->ineq[k], (*v)->ctx->negone, aff1->el,
320                                                (*v)->ctx->one, aff2->el,
321                                                aff1->size);
322         else if (tok->type == ISL_TOKEN_GE)
323                 isl_seq_combine(bmap->ineq[k], (*v)->ctx->one, aff1->el,
324                                                (*v)->ctx->negone, aff2->el,
325                                                aff1->size);
326         else {
327                 isl_seq_combine(bmap->ineq[k], (*v)->ctx->one, aff1->el,
328                                                (*v)->ctx->negone, aff2->el,
329                                                aff1->size);
330                 isl_basic_map_inequality_to_equality(bmap, k);
331         }
332         isl_token_free(tok);
333         isl_vec_free(aff1);
334         isl_vec_free(aff2);
335
336         return bmap;
337 error:
338         if (tok)
339                 isl_token_free(tok);
340         isl_vec_free(aff1);
341         isl_vec_free(aff2);
342         isl_basic_map_free(bmap);
343         return NULL;
344 }
345
346 static struct isl_basic_map *add_constraints(struct isl_stream *s,
347         struct vars **v, struct isl_basic_map *bmap)
348 {
349         struct isl_token *tok;
350
351         for (;;) {
352                 bmap = add_constraint(s, v, bmap);
353                 if (!bmap)
354                         return NULL;
355                 tok = isl_stream_next_token(s);
356                 if (!tok) {
357                         isl_stream_error(s, NULL, "unexpected EOF");
358                         goto error;
359                 }
360                 if (tok->type != ISL_TOKEN_AND)
361                         break;
362                 isl_token_free(tok);
363         }
364         isl_stream_push_token(s, tok);
365
366         return bmap;
367 error:
368         if (tok)
369                 isl_token_free(tok);
370         isl_basic_map_free(bmap);
371         return NULL;
372 }
373
374 static __isl_give isl_basic_map *basic_map_read_polylib_constraint(
375         struct isl_stream *s, __isl_take isl_basic_map *bmap)
376 {
377         int j;
378         struct isl_token *tok;
379         int type;
380         int k;
381         isl_int *c;
382         unsigned nparam;
383         unsigned dim;
384
385         if (!bmap)
386                 return NULL;
387
388         nparam = isl_basic_map_dim(bmap, isl_dim_param);
389         dim = isl_basic_map_dim(bmap, isl_dim_out);
390
391         tok = isl_stream_next_token(s);
392         if (!tok || tok->type != ISL_TOKEN_VALUE) {
393                 isl_stream_error(s, tok, "expecting coefficient");
394                 if (tok)
395                         isl_stream_push_token(s, tok);
396                 goto error;
397         }
398         if (!tok->on_new_line) {
399                 isl_stream_error(s, tok, "coefficient should appear on new line");
400                 isl_stream_push_token(s, tok);
401                 goto error;
402         }
403
404         type = isl_int_get_si(tok->u.v);
405         isl_token_free(tok);
406
407         isl_assert(s->ctx, type == 0 || type == 1, goto error);
408         if (type == 0) {
409                 k = isl_basic_map_alloc_equality(bmap);
410                 c = bmap->eq[k];
411         } else {
412                 k = isl_basic_map_alloc_inequality(bmap);
413                 c = bmap->ineq[k];
414         }
415         if (k < 0)
416                 goto error;
417
418         for (j = 0; j < dim; ++j) {
419                 tok = isl_stream_next_token(s);
420                 if (!tok || tok->type != ISL_TOKEN_VALUE) {
421                         isl_stream_error(s, tok, "expecting coefficient");
422                         if (tok)
423                                 isl_stream_push_token(s, tok);
424                         goto error;
425                 }
426                 isl_int_set(c[1 + nparam + j], tok->u.v);
427                 isl_token_free(tok);
428         }
429         for (j = 0; j < nparam; ++j) {
430                 tok = isl_stream_next_token(s);
431                 if (!tok || tok->type != ISL_TOKEN_VALUE) {
432                         isl_stream_error(s, tok, "expecting coefficient");
433                         if (tok)
434                                 isl_stream_push_token(s, tok);
435                         goto error;
436                 }
437                 isl_int_set(c[1 + j], tok->u.v);
438                 isl_token_free(tok);
439         }
440         tok = isl_stream_next_token(s);
441         if (!tok || tok->type != ISL_TOKEN_VALUE) {
442                 isl_stream_error(s, tok, "expecting coefficient");
443                 if (tok)
444                         isl_stream_push_token(s, tok);
445                 goto error;
446         }
447         isl_int_set(c[0], tok->u.v);
448         isl_token_free(tok);
449
450         return bmap;
451 error:
452         isl_basic_map_free(bmap);
453         return NULL;
454 }
455
456 static __isl_give isl_basic_map *basic_map_read_polylib(struct isl_stream *s,
457         int nparam)
458 {
459         int i;
460         struct isl_token *tok;
461         struct isl_token *tok2;
462         int n_row, n_col;
463         int on_new_line;
464         unsigned dim;
465         struct isl_basic_map *bmap = NULL;
466
467         if (nparam < 0)
468                 nparam = 0;
469
470         tok = isl_stream_next_token(s);
471         if (!tok) {
472                 isl_stream_error(s, NULL, "unexpected EOF");
473                 return NULL;
474         }
475         tok2 = isl_stream_next_token(s);
476         if (!tok2) {
477                 isl_token_free(tok);
478                 isl_stream_error(s, NULL, "unexpected EOF");
479                 return NULL;
480         }
481         n_row = isl_int_get_si(tok->u.v);
482         n_col = isl_int_get_si(tok2->u.v);
483         on_new_line = tok2->on_new_line;
484         isl_token_free(tok2);
485         isl_token_free(tok);
486         isl_assert(s->ctx, !on_new_line, return NULL);
487         isl_assert(s->ctx, n_row >= 0, return NULL);
488         isl_assert(s->ctx, n_col >= 2 + nparam, return NULL);
489         dim = n_col - 2 - nparam;
490         bmap = isl_basic_map_alloc(s->ctx, nparam, 0, dim, 0, n_row, n_row);
491         if (!bmap)
492                 return NULL;
493
494         for (i = 0; i < n_row; ++i)
495                 bmap = basic_map_read_polylib_constraint(s, bmap);
496
497         bmap = isl_basic_map_simplify(bmap);
498         bmap = isl_basic_map_finalize(bmap);
499         return bmap;
500 }
501
502 static struct isl_map *map_read_polylib(struct isl_stream *s, int nparam)
503 {
504         struct isl_token *tok;
505         struct isl_token *tok2;
506         int i, n;
507         struct isl_map *map;
508
509         tok = isl_stream_next_token(s);
510         if (!tok) {
511                 isl_stream_error(s, NULL, "unexpected EOF");
512                 return NULL;
513         }
514         tok2 = isl_stream_next_token(s);
515         if (!tok2) {
516                 isl_token_free(tok);
517                 isl_stream_error(s, NULL, "unexpected EOF");
518                 return NULL;
519         }
520         if (!tok2->on_new_line) {
521                 isl_stream_push_token(s, tok2);
522                 isl_stream_push_token(s, tok);
523                 return isl_map_from_basic_map(basic_map_read_polylib(s, nparam));
524         }
525         isl_stream_push_token(s, tok2);
526         n = isl_int_get_si(tok->u.v);
527         isl_token_free(tok);
528
529         isl_assert(s->ctx, n >= 1, return NULL);
530
531         map = isl_map_from_basic_map(basic_map_read_polylib(s, nparam));
532
533         for (i = 1; i < n; ++i)
534                 map = isl_map_union(map,
535                         isl_map_from_basic_map(basic_map_read_polylib(s, nparam)));
536
537         return map;
538 }
539
540 static struct isl_dim *set_names(struct isl_dim *dim, struct vars *vars,
541         enum isl_dim_type type, int offset, int n)
542 {
543         int i;
544         struct variable *v;
545
546         for (i = 0, v = vars->v; i < offset; ++i, v = v->next)
547                 ;
548         for (i = n - 1; i >= 0; --i, v = v->next)
549                 dim = isl_dim_set_name(dim, type, i, v->name);
550
551         return dim;
552 }
553
554 static struct isl_dim *dim_from_vars(struct vars *vars,
555         int nparam, int n_in, int n_out)
556 {
557         struct isl_dim *dim;
558
559         dim = isl_dim_alloc(vars->ctx, nparam, n_in, n_out);
560         dim = set_names(dim, vars, isl_dim_param, n_out + n_in, nparam);
561         dim = set_names(dim, vars, isl_dim_in, n_out, n_in);
562         dim = set_names(dim, vars, isl_dim_out, 0, n_out);
563
564         return dim;
565 }
566
567 static struct isl_map *map_read(struct isl_stream *s, int nparam)
568 {
569         struct isl_dim *dim;
570         struct isl_basic_map *bmap = NULL;
571         struct isl_token *tok;
572         struct vars *v = NULL;
573         int n1;
574         int n2;
575
576         tok = isl_stream_next_token(s);
577         if (!tok) {
578                 isl_stream_error(s, NULL, "unexpected EOF");
579                 goto error;
580         }
581         if (tok->type == ISL_TOKEN_VALUE) {
582                 isl_stream_push_token(s, tok);
583                 return map_read_polylib(s, nparam);
584         }
585         v = vars_new(s->ctx);
586         if (tok->type == '[') {
587                 isl_stream_push_token(s, tok);
588                 v = read_tuple(s, v);
589                 if (!v)
590                         return NULL;
591                 if (nparam >= 0)
592                         isl_assert(s->ctx, nparam == v->n, goto error);
593                 nparam = v->n;
594                 tok = isl_stream_next_token(s);
595                 if (!tok || tok->type != ISL_TOKEN_TO) {
596                         isl_stream_error(s, tok, "expecting '->'");
597                         if (tok)
598                                 isl_stream_push_token(s, tok);
599                         goto error;
600                 }
601                 isl_token_free(tok);
602                 tok = isl_stream_next_token(s);
603         }
604         if (nparam < 0)
605                 nparam = 0;
606         if (!tok || tok->type != '{') {
607                 isl_stream_error(s, tok, "expecting '{'");
608                 if (tok)
609                         isl_stream_push_token(s, tok);
610                 goto error;
611         }
612         isl_token_free(tok);
613         v = read_tuple(s, v);
614         if (!v)
615                 return NULL;
616         n1 = v->n - nparam;
617         tok = isl_stream_next_token(s);
618         if (tok && tok->type == ISL_TOKEN_TO) {
619                 isl_token_free(tok);
620                 v = read_tuple(s, v);
621                 if (!v)
622                         return NULL;
623                 n2 = v->n - n1 - nparam;
624         } else {
625                 if (tok)
626                         isl_stream_push_token(s, tok);
627                 n2 = n1;
628                 n1 = 0;
629         }
630         dim = dim_from_vars(v, nparam, n1, n2);
631         bmap = isl_basic_map_alloc_dim(dim, 0, 0, 0);
632         if (!bmap)
633                 goto error;
634         tok = isl_stream_next_token(s);
635         if (tok && tok->type == ':') {
636                 isl_token_free(tok);
637                 bmap = add_constraints(s, &v, bmap);
638                 tok = isl_stream_next_token(s);
639         }
640         if (tok && tok->type == '}') {
641                 isl_token_free(tok);
642         } else {
643                 isl_stream_error(s, tok, "unexpected isl_token");
644                 if (tok)
645                         isl_token_free(tok);
646                 goto error;
647         }
648         vars_free(v);
649
650         bmap = isl_basic_map_simplify(bmap);
651         bmap = isl_basic_map_finalize(bmap);
652         return isl_map_from_basic_map(bmap);
653 error:
654         isl_basic_map_free(bmap);
655         if (v)
656                 vars_free(v);
657         return NULL;
658 }
659
660 static struct isl_basic_map *basic_map_read(struct isl_stream *s, int nparam)
661 {
662         struct isl_map *map;
663         struct isl_basic_map *bmap;
664
665         map = map_read(s, nparam);
666         if (!map)
667                 return NULL;
668
669         isl_assert(map->ctx, map->n <= 1, goto error);
670
671         if (map->n == 0)
672                 bmap = isl_basic_map_empty_like_map(map);
673         else
674                 bmap = isl_basic_map_copy(map->p[0]);
675
676         isl_map_free(map);
677
678         return bmap;
679 error:
680         isl_map_free(map);
681         return NULL;
682 }
683
684 __isl_give isl_basic_map *isl_basic_map_read_from_file(isl_ctx *ctx,
685                 FILE *input, int nparam)
686 {
687         struct isl_basic_map *bmap;
688         struct isl_stream *s = isl_stream_new_file(ctx, input);
689         if (!s)
690                 return NULL;
691         bmap = basic_map_read(s, nparam);
692         isl_stream_free(s);
693         return bmap;
694 }
695
696 __isl_give isl_basic_set *isl_basic_set_read_from_file(isl_ctx *ctx,
697                 FILE *input, int nparam)
698 {
699         struct isl_basic_map *bmap;
700         bmap = isl_basic_map_read_from_file(ctx, input, nparam);
701         if (!bmap)
702                 return NULL;
703         isl_assert(ctx, isl_basic_map_n_in(bmap) == 0, goto error);
704         return (struct isl_basic_set *)bmap;
705 error:
706         isl_basic_map_free(bmap);
707         return NULL;
708 }
709
710 struct isl_basic_map *isl_basic_map_read_from_str(struct isl_ctx *ctx,
711                 const char *str, int nparam)
712 {
713         struct isl_basic_map *bmap;
714         struct isl_stream *s = isl_stream_new_str(ctx, str);
715         if (!s)
716                 return NULL;
717         bmap = basic_map_read(s, nparam);
718         isl_stream_free(s);
719         return bmap;
720 }
721
722 struct isl_basic_set *isl_basic_set_read_from_str(struct isl_ctx *ctx,
723                 const char *str, int nparam)
724 {
725         struct isl_basic_map *bmap;
726         bmap = isl_basic_map_read_from_str(ctx, str, nparam);
727         if (!bmap)
728                 return NULL;
729         isl_assert(ctx, isl_basic_map_n_in(bmap) == 0, goto error);
730         return (struct isl_basic_set *)bmap;
731 error:
732         isl_basic_map_free(bmap);
733         return NULL;
734 }
735
736 __isl_give isl_map *isl_map_read_from_file(struct isl_ctx *ctx,
737                 FILE *input, int nparam)
738 {
739         struct isl_map *map;
740         struct isl_stream *s = isl_stream_new_file(ctx, input);
741         if (!s)
742                 return NULL;
743         map = map_read(s, nparam);
744         isl_stream_free(s);
745         return map;
746 }
747
748 __isl_give isl_set *isl_set_read_from_file(struct isl_ctx *ctx,
749                 FILE *input, int nparam)
750 {
751         struct isl_map *map;
752         map = isl_map_read_from_file(ctx, input, nparam);
753         if (!map)
754                 return NULL;
755         isl_assert(ctx, isl_map_n_in(map) == 0, goto error);
756         return (struct isl_set *)map;
757 error:
758         isl_map_free(map);
759         return NULL;
760 }
761
762 static char *next_line(FILE *input, char *line, unsigned len)
763 {
764         char *p;
765
766         do {
767                 if (!(p = fgets(line, len, input)))
768                         return NULL;
769                 while (isspace(*p) && *p != '\n')
770                         ++p;
771         } while (*p == '#' || *p == '\n');
772
773         return p;
774 }
775
776 static struct isl_vec *isl_vec_read_from_file_polylib(struct isl_ctx *ctx,
777                 FILE *input)
778 {
779         struct isl_vec *vec = NULL;
780         char line[1024];
781         char val[1024];
782         char *p;
783         unsigned size;
784         int j;
785         int n;
786         int offset;
787
788         isl_assert(ctx, next_line(input, line, sizeof(line)), return NULL);
789         isl_assert(ctx, sscanf(line, "%u", &size) == 1, return NULL);
790
791         vec = isl_vec_alloc(ctx, size);
792
793         p = next_line(input, line, sizeof(line));
794         isl_assert(ctx, p, goto error);
795
796         for (j = 0; j < size; ++j) {
797                 n = sscanf(p, "%s%n", val, &offset);
798                 isl_assert(ctx, n != 0, goto error);
799                 isl_int_read(vec->el[j], val);
800                 p += offset;
801         }
802
803         return vec;
804 error:
805         isl_vec_free(vec);
806         return NULL;
807 }
808
809 struct isl_vec *isl_vec_read_from_file(struct isl_ctx *ctx,
810                 FILE *input, unsigned input_format)
811 {
812         if (input_format == ISL_FORMAT_POLYLIB)
813                 return isl_vec_read_from_file_polylib(ctx, input);
814         else
815                 isl_assert(ctx, 0, return NULL);
816 }