argument parsing: add ISL_ARG_USER_OPT_CHOICE
[platform/upstream/isl.git] / isl_stream.c
index f88ec07..4d684ec 100644 (file)
@@ -95,6 +95,8 @@ void isl_stream_error(struct isl_stream *s, struct isl_token *tok, char *msg)
        if (tok) {
                if (tok->type < 256)
                        fprintf(stderr, "got '%c'\n", tok->type);
+               else if (tok->type == ISL_TOKEN_IDENT)
+                       fprintf(stderr, "got ident '%s'\n", tok->u.s);
                else
                        fprintf(stderr, "got token type %d\n", tok->type);
        }
@@ -108,12 +110,8 @@ static struct isl_stream* isl_stream_new(struct isl_ctx *ctx)
                return NULL;
        s->ctx = ctx;
        isl_ctx_ref(s->ctx);
-       s->size = 256;
        s->file = NULL;
        s->str = NULL;
-       s->buffer = isl_alloc_array(ctx, char, s->size);
-       if (!s->buffer)
-               goto error;
        s->len = 0;
        s->line = 1;
        s->col = 0;
@@ -123,6 +121,10 @@ static struct isl_stream* isl_stream_new(struct isl_ctx *ctx)
                s->tokens[i] = NULL;
        s->n_token = 0;
        s->keywords = NULL;
+       s->size = 256;
+       s->buffer = isl_alloc_array(ctx, char, s->size);
+       if (!s->buffer)
+               goto error;
        return s;
 error:
        isl_stream_free(s);
@@ -140,9 +142,11 @@ struct isl_stream* isl_stream_new_file(struct isl_ctx *ctx, FILE *file)
 
 struct isl_stream* isl_stream_new_str(struct isl_ctx *ctx, const char *str)
 {
-    struct isl_stream *s = isl_stream_new(ctx);
-    s->str = str;
-    return s;
+       struct isl_stream *s = isl_stream_new(ctx);
+       if (!s)
+               return NULL;
+       s->str = str;
+       return s;
 }
 
 static int isl_stream_getc(struct isl_stream *s)
@@ -183,7 +187,7 @@ static int isl_stream_push_char(struct isl_stream *s, int c)
 {
        if (s->len >= s->size) {
                s->size = (3*s->size)/2;
-               s->buffer = isl_realloc_array(ctx, s->buffer, char, s->size);
+               s->buffer = isl_realloc_array(s->ctx, s->buffer, char, s->size);
                if (!s->buffer)
                        return -1;
        }
@@ -215,6 +219,8 @@ static enum isl_token_type check_keywords(struct isl_stream *s)
                return ISL_TOKEN_INFTY;
        if (!strcasecmp(s->buffer, "NaN"))
                return ISL_TOKEN_NAN;
+       if (!strcasecmp(s->buffer, "max"))
+               return ISL_TOKEN_MAX;
 
        if (!s->keywords)
                return ISL_TOKEN_IDENT;
@@ -230,6 +236,17 @@ static enum isl_token_type check_keywords(struct isl_stream *s)
        return ISL_TOKEN_IDENT;
 }
 
+int isl_stream_skip_line(struct isl_stream *s)
+{
+       int c;
+
+       while ((c = isl_stream_getc(s)) != -1 && c != '\n')
+               /* nothing */
+               ;
+
+       return c == -1 ? -1 : 0;
+}
+
 static struct isl_token *next_token(struct isl_stream *s, int same_line)
 {
        int c;
@@ -251,10 +268,10 @@ static struct isl_token *next_token(struct isl_stream *s, int same_line)
        /* skip spaces and comment lines */
        while ((c = isl_stream_getc(s)) != -1) {
                if (c == '#') {
-                       while ((c = isl_stream_getc(s)) != -1 && c != '\n')
-                               /* nothing */
-                               ;
-                       if (c == -1 || (same_line && c == '\n'))
+                       if (isl_stream_skip_line(s) < 0)
+                               break;
+                       c = '\n';
+                       if (same_line)
                                break;
                } else if (!isspace(c) || (same_line && c == '\n'))
                        break;
@@ -355,6 +372,7 @@ static struct isl_token *next_token(struct isl_stream *s, int same_line)
                        isl_stream_error(s, NULL, "unterminated string");
                        goto error;
                }
+               isl_stream_push_char(s, '\0');
                tok->u.s = strdup(s->buffer);
                return tok;
        }
@@ -369,7 +387,7 @@ static struct isl_token *next_token(struct isl_stream *s, int same_line)
                }
                if (c != -1)
                        isl_stream_ungetc(s, c);
-               tok->type = ':';
+               tok->type = (enum isl_token_type) ':';
                return tok;
        }
        if (c == '>') {
@@ -380,10 +398,16 @@ static struct isl_token *next_token(struct isl_stream *s, int same_line)
                if ((c = isl_stream_getc(s)) == '=') {
                        tok->type = ISL_TOKEN_GE;
                        return tok;
-               }
+               } else if (c == '>') {
+                       if ((c = isl_stream_getc(s)) == '=') {
+                               tok->type = ISL_TOKEN_LEX_GE;
+                               return tok;
+                       }
+                       tok->type = ISL_TOKEN_LEX_GT;
+               } else
+                       tok->type = ISL_TOKEN_GT;
                if (c != -1)
                        isl_stream_ungetc(s, c);
-               tok->type = ISL_TOKEN_GT;
                return tok;
        }
        if (c == '<') {
@@ -394,10 +418,16 @@ static struct isl_token *next_token(struct isl_stream *s, int same_line)
                if ((c = isl_stream_getc(s)) == '=') {
                        tok->type = ISL_TOKEN_LE;
                        return tok;
-               }
+               } else if (c == '<') {
+                       if ((c = isl_stream_getc(s)) == '=') {
+                               tok->type = ISL_TOKEN_LEX_LE;
+                               return tok;
+                       }
+                       tok->type = ISL_TOKEN_LEX_LT;
+               } else
+                       tok->type = ISL_TOKEN_LT;
                if (c != -1)
                        isl_stream_ungetc(s, c);
-               tok->type = ISL_TOKEN_LT;
                return tok;
        }
        if (c == '&') {
@@ -512,9 +542,9 @@ int isl_stream_is_empty(struct isl_stream *s)
        return 0;
 }
 
-static int free_keyword(void *p)
+static int free_keyword(void **p, void *user)
 {
-       struct isl_keyword *keyword = p;
+       struct isl_keyword *keyword = *p;
 
        free(keyword->name);
        free(keyword);
@@ -522,6 +552,17 @@ static int free_keyword(void *p)
        return 0;
 }
 
+void isl_stream_flush_tokens(struct isl_stream *s)
+{
+       int i;
+
+       if (!s)
+               return;
+       for (i = 0; i < s->n_token; ++i)
+               isl_token_free(s->tokens[i]);
+       s->n_token = 0;
+}
+
 void isl_stream_free(struct isl_stream *s)
 {
        if (!s)
@@ -533,7 +574,7 @@ void isl_stream_free(struct isl_stream *s)
                isl_token_free(tok);
        }
        if (s->keywords) {
-               isl_hash_table_foreach(s->ctx, s->keywords, free_keyword);
+               isl_hash_table_foreach(s->ctx, s->keywords, &free_keyword, NULL);
                isl_hash_table_free(s->ctx, s->keywords);
        }
        isl_ctx_deref(s->ctx);