keymap-dump: use consistent order set/latch/lock (style)
[platform/upstream/libxkbcommon.git] / src / xkbcomp / scanner.c
index 0296c58..1ce6137 100644 (file)
 #include "parser-priv.h"
 #include "scanner-utils.h"
 
-int
-scanner_error(YYLTYPE *yylloc, struct scanner *s, const char *msg)
-{
-    log_err(s->ctx, "%s:%d:%d: %s\n",
-            s->file_name, yylloc->first_line, yylloc->first_column, msg);
-    return ERROR_TOK;
-}
-
 static bool
-number(struct scanner *s, int64_t *out, enum yytokentype *out_tok)
+number(struct scanner *s, int64_t *out, int *out_tok)
 {
     bool is_float = false, is_hex = false;
     const char *start = s->s + s->pos;
     char *end;
 
     if (lit(s, "0x")) {
-        while (isxdigit(peek(s))) next(s);
+        while (is_xdigit(peek(s))) next(s);
         is_hex = true;
     }
     else {
-        while (isdigit(peek(s))) next(s);
+        while (is_digit(peek(s))) next(s);
         is_float = chr(s, '.');
-        while (isdigit(peek(s))) next(s);
+        while (is_digit(peek(s))) next(s);
     }
     if (s->s + s->pos == start)
         return false;
@@ -67,17 +59,17 @@ number(struct scanner *s, int64_t *out, enum yytokentype *out_tok)
 }
 
 int
-_xkbcommon_lex(YYSTYPE *yylval, YYLTYPE *yylloc, struct scanner *s)
+_xkbcommon_lex(YYSTYPE *yylval, struct scanner *s)
 {
-    enum yytokentype tok;
+    int tok;
 
 skip_more_whitespace_and_comments:
     /* Skip spaces. */
-    while (isspace(peek(s))) next(s);
+    while (is_space(peek(s))) next(s);
 
     /* Skip comments. */
     if (lit(s, "//") || chr(s, '#')) {
-        while (!eof(s) && !eol(s)) next(s);
+        skip_to_eol(s);
         goto skip_more_whitespace_and_comments;
     }
 
@@ -85,8 +77,8 @@ skip_more_whitespace_and_comments:
     if (eof(s)) return END_OF_FILE;
 
     /* New token. */
-    yylloc->first_line = yylloc->last_line = s->line;
-    yylloc->first_column = yylloc->last_column = s->column;
+    s->token_line = s->line;
+    s->token_column = s->column;
     s->buf_pos = 0;
 
     /* String literal. */
@@ -103,29 +95,34 @@ skip_more_whitespace_and_comments:
                 else if (chr(s, 'v'))  buf_append(s, '\v');
                 else if (chr(s, 'e'))  buf_append(s, '\033');
                 else if (oct(s, &o))   buf_append(s, (char) o);
-                else return scanner_error(yylloc, s,
-                                          "illegal escape sequence in string literal");
+                else {
+                    scanner_warn(s, "unknown escape sequence in string literal");
+                    /* Ignore. */
+                }
             } else {
                 buf_append(s, next(s));
             }
         }
-        if (!buf_append(s, '\0') || !chr(s, '\"'))
-            return scanner_error(yylloc, s, "unterminated string literal");
+        if (!buf_append(s, '\0') || !chr(s, '\"')) {
+            scanner_err(s, "unterminated string literal");
+            return ERROR_TOK;
+        }
         yylval->str = strdup(s->buf);
         if (!yylval->str)
-            return scanner_error(yylloc, s, "scanner out of memory");
+            return ERROR_TOK;
         return STRING;
     }
 
     /* Key name literal. */
     if (chr(s, '<')) {
-        while (isgraph(peek(s)) && peek(s) != '>')
+        while (is_graph(peek(s)) && peek(s) != '>')
             buf_append(s, next(s));
-        if (s->buf_pos == 0)
-            return scanner_error(yylloc, s, "empty key name literal");
-        if (!buf_append(s, '\0') || !chr(s, '>'))
-            return scanner_error(yylloc, s, "unterminated key name literal");
-        yylval->sval = xkb_atom_intern(s->ctx, s->buf, s->buf_pos - 1);
+        if (!buf_append(s, '\0') || !chr(s, '>')) {
+            scanner_err(s, "unterminated key name literal");
+            return ERROR_TOK;
+        }
+        /* Empty key name literals are allowed. */
+        yylval->atom = xkb_atom_intern(s->ctx, s->buf, s->buf_pos - 1);
         return KEYNAME;
     }
 
@@ -143,35 +140,41 @@ skip_more_whitespace_and_comments:
     if (chr(s, '+')) return PLUS;
     if (chr(s, '-')) return MINUS;
     if (chr(s, '*')) return TIMES;
+    if (chr(s, '/')) return DIVIDE;
     if (chr(s, '!')) return EXCLAM;
     if (chr(s, '~')) return INVERT;
 
     /* Identifier. */
-    if (isalpha(peek(s)) || peek(s) == '_') {
+    if (is_alpha(peek(s)) || peek(s) == '_') {
         s->buf_pos = 0;
-        while (isalnum(peek(s)) || peek(s) == '_')
+        while (is_alnum(peek(s)) || peek(s) == '_')
             buf_append(s, next(s));
-        if (!buf_append(s, '\0'))
-            return scanner_error(yylloc, s, "identifier too long");
+        if (!buf_append(s, '\0')) {
+            scanner_err(s, "identifier too long");
+            return ERROR_TOK;
+        }
 
         /* Keyword. */
-        tok = keyword_to_token(s->buf);
+        tok = keyword_to_token(s->buf, s->buf_pos - 1);
         if (tok != -1) return tok;
 
         yylval->str = strdup(s->buf);
         if (!yylval->str)
-            return scanner_error(yylloc, s, "scanner out of memory");
+            return ERROR_TOK;
         return IDENT;
     }
 
     /* Number literal (hexadecimal / decimal / float). */
     if (number(s, &yylval->num, &tok)) {
-        if (tok == ERROR_TOK)
-            return scanner_error(yylloc, s, "malformed number literal");
+        if (tok == ERROR_TOK) {
+            scanner_err(s, "malformed number literal");
+            return ERROR_TOK;
+        }
         return tok;
     }
 
-    return scanner_error(yylloc, s, "unrecognized token");
+    scanner_err(s, "unrecognized token");
+    return ERROR_TOK;
 }
 
 XkbFile *
@@ -179,7 +182,7 @@ XkbParseString(struct xkb_context *ctx, const char *string, size_t len,
                const char *file_name, const char *map)
 {
     struct scanner scanner;
-    scanner_init(&scanner, ctx, string, len, file_name);
+    scanner_init(&scanner, ctx, string, len, file_name, NULL);
     return parse(ctx, &scanner, map);
 }
 
@@ -189,7 +192,7 @@ XkbParseFile(struct xkb_context *ctx, FILE *file,
 {
     bool ok;
     XkbFile *xkb_file;
-    const char *string;
+    char *string;
     size_t size;
 
     ok = map_file(file, &string, &size);