scanner: prefix functions with `scanner_` to avoid symbol conflicts
authorRan Benita <ran@unusedvar.com>
Mon, 14 Mar 2022 14:44:13 +0000 (16:44 +0200)
committerRan Benita <ran@unusedvar.com>
Mon, 14 Mar 2022 14:45:19 +0000 (16:45 +0200)
Particularly `eof()` in mingw-w64.

Fixes: https://github.com/xkbcommon/libxkbcommon/pull/285
Reported-by: Marko Lindqvist
Signed-off-by: Ran Benita <ran@unusedvar.com>
src/compose/parser.c
src/scanner-utils.h
src/xkbcomp/rules.c
src/xkbcomp/scanner.c

index 08018f2..69abc49 100644 (file)
@@ -126,18 +126,18 @@ lex(struct scanner *s, union lvalue *val)
 {
 skip_more_whitespace_and_comments:
     /* Skip spaces. */
-    while (is_space(peek(s)))
-        if (next(s) == '\n')
+    while (is_space(scanner_peek(s)))
+        if (scanner_next(s) == '\n')
             return TOK_END_OF_LINE;
 
     /* Skip comments. */
-    if (chr(s, '#')) {
-        skip_to_eol(s);
+    if (scanner_chr(s, '#')) {
+        scanner_skip_to_eol(s);
         goto skip_more_whitespace_and_comments;
     }
 
     /* See if we're done. */
-    if (eof(s)) return TOK_END_OF_FILE;
+    if (scanner_eof(s)) return TOK_END_OF_FILE;
 
     /* New token. */
     s->token_line = s->line;
@@ -145,14 +145,14 @@ skip_more_whitespace_and_comments:
     s->buf_pos = 0;
 
     /* LHS Keysym. */
-    if (chr(s, '<')) {
-        while (peek(s) != '>' && !eol(s) && !eof(s))
-            buf_append(s, next(s));
-        if (!chr(s, '>')) {
+    if (scanner_chr(s, '<')) {
+        while (scanner_peek(s) != '>' && !scanner_eol(s) && !scanner_eof(s))
+            scanner_buf_append(s, scanner_next(s));
+        if (!scanner_chr(s, '>')) {
             scanner_err(s, "unterminated keysym literal");
             return TOK_ERROR;
         }
-        if (!buf_append(s, '\0')) {
+        if (!scanner_buf_append(s, '\0')) {
             scanner_err(s, "keysym literal is too long");
             return TOK_ERROR;
         }
@@ -162,46 +162,46 @@ skip_more_whitespace_and_comments:
     }
 
     /* Colon. */
-    if (chr(s, ':'))
+    if (scanner_chr(s, ':'))
         return TOK_COLON;
-    if (chr(s, '!'))
+    if (scanner_chr(s, '!'))
         return TOK_BANG;
-    if (chr(s, '~'))
+    if (scanner_chr(s, '~'))
         return TOK_TILDE;
 
     /* String literal. */
-    if (chr(s, '\"')) {
-        while (!eof(s) && !eol(s) && peek(s) != '\"') {
-            if (chr(s, '\\')) {
+    if (scanner_chr(s, '\"')) {
+        while (!scanner_eof(s) && !scanner_eol(s) && scanner_peek(s) != '\"') {
+            if (scanner_chr(s, '\\')) {
                 uint8_t o;
-                if (chr(s, '\\')) {
-                    buf_append(s, '\\');
+                if (scanner_chr(s, '\\')) {
+                    scanner_buf_append(s, '\\');
                 }
-                else if (chr(s, '"')) {
-                    buf_append(s, '"');
+                else if (scanner_chr(s, '"')) {
+                    scanner_buf_append(s, '"');
                 }
-                else if (chr(s, 'x') || chr(s, 'X')) {
-                    if (hex(s, &o))
-                        buf_append(s, (char) o);
+                else if (scanner_chr(s, 'x') || scanner_chr(s, 'X')) {
+                    if (scanner_hex(s, &o))
+                        scanner_buf_append(s, (char) o);
                     else
                         scanner_warn(s, "illegal hexadecimal escape sequence in string literal");
                 }
-                else if (oct(s, &o)) {
-                    buf_append(s, (char) o);
+                else if (scanner_oct(s, &o)) {
+                    scanner_buf_append(s, (char) o);
                 }
                 else {
-                    scanner_warn(s, "unknown escape sequence (%c) in string literal", peek(s));
+                    scanner_warn(s, "unknown escape sequence (%c) in string literal", scanner_peek(s));
                     /* Ignore. */
                 }
             } else {
-                buf_append(s, next(s));
+                scanner_buf_append(s, scanner_next(s));
             }
         }
-        if (!chr(s, '\"')) {
+        if (!scanner_chr(s, '\"')) {
             scanner_err(s, "unterminated string literal");
             return TOK_ERROR;
         }
-        if (!buf_append(s, '\0')) {
+        if (!scanner_buf_append(s, '\0')) {
             scanner_err(s, "string literal is too long");
             return TOK_ERROR;
         }
@@ -215,11 +215,11 @@ skip_more_whitespace_and_comments:
     }
 
     /* Identifier or include. */
-    if (is_alpha(peek(s)) || peek(s) == '_') {
+    if (is_alpha(scanner_peek(s)) || scanner_peek(s) == '_') {
         s->buf_pos = 0;
-        while (is_alnum(peek(s)) || peek(s) == '_')
-            buf_append(s, next(s));
-        if (!buf_append(s, '\0')) {
+        while (is_alnum(scanner_peek(s)) || scanner_peek(s) == '_')
+            scanner_buf_append(s, scanner_next(s));
+        if (!scanner_buf_append(s, '\0')) {
             scanner_err(s, "identifier is too long");
             return TOK_ERROR;
         }
@@ -233,7 +233,7 @@ skip_more_whitespace_and_comments:
     }
 
     /* Discard rest of line. */
-    skip_to_eol(s);
+    scanner_skip_to_eol(s);
 
     scanner_err(s, "unrecognized token");
     return TOK_ERROR;
@@ -243,68 +243,68 @@ static enum rules_token
 lex_include_string(struct scanner *s, struct xkb_compose_table *table,
                    union lvalue *val_out)
 {
-    while (is_space(peek(s)))
-        if (next(s) == '\n')
+    while (is_space(scanner_peek(s)))
+        if (scanner_next(s) == '\n')
             return TOK_END_OF_LINE;
 
     s->token_line = s->line;
     s->token_column = s->column;
     s->buf_pos = 0;
 
-    if (!chr(s, '\"')) {
+    if (!scanner_chr(s, '\"')) {
         scanner_err(s, "include statement must be followed by a path");
         return TOK_ERROR;
     }
 
-    while (!eof(s) && !eol(s) && peek(s) != '\"') {
-        if (chr(s, '%')) {
-            if (chr(s, '%')) {
-                buf_append(s, '%');
+    while (!scanner_eof(s) && !scanner_eol(s) && scanner_peek(s) != '\"') {
+        if (scanner_chr(s, '%')) {
+            if (scanner_chr(s, '%')) {
+                scanner_buf_append(s, '%');
             }
-            else if (chr(s, 'H')) {
+            else if (scanner_chr(s, 'H')) {
                 const char *home = secure_getenv("HOME");
                 if (!home) {
                     scanner_err(s, "%%H was used in an include statement, but the HOME environment variable is not set");
                     return TOK_ERROR;
                 }
-                if (!buf_appends(s, home)) {
+                if (!scanner_buf_appends(s, home)) {
                     scanner_err(s, "include path after expanding %%H is too long");
                     return TOK_ERROR;
                 }
             }
-            else if (chr(s, 'L')) {
+            else if (scanner_chr(s, 'L')) {
                 char *path = get_locale_compose_file_path(table->locale);
                 if (!path) {
                     scanner_err(s, "failed to expand %%L to the locale Compose file");
                     return TOK_ERROR;
                 }
-                if (!buf_appends(s, path)) {
+                if (!scanner_buf_appends(s, path)) {
                     free(path);
                     scanner_err(s, "include path after expanding %%L is too long");
                     return TOK_ERROR;
                 }
                 free(path);
             }
-            else if (chr(s, 'S')) {
+            else if (scanner_chr(s, 'S')) {
                 const char *xlocaledir = get_xlocaledir_path();
-                if (!buf_appends(s, xlocaledir)) {
+                if (!scanner_buf_appends(s, xlocaledir)) {
                     scanner_err(s, "include path after expanding %%S is too long");
                     return TOK_ERROR;
                 }
             }
             else {
-                scanner_err(s, "unknown %% format (%c) in include statement", peek(s));
+                scanner_err(s, "unknown %% format (%c) in include statement", scanner_peek(s));
                 return TOK_ERROR;
             }
         } else {
-            buf_append(s, next(s));
+            scanner_buf_append(s, scanner_next(s));
         }
     }
-    if (!chr(s, '\"')) {
+    if (!scanner_chr(s, '\"')) {
         scanner_err(s, "unterminated include statement");
         return TOK_ERROR;
     }
-    if (!buf_append(s, '\0')) {
+    if (!scanner_buf_append(s, '\0')) {
         scanner_err(s, "include path is too long");
         return TOK_ERROR;
     }
index dbf4eaa..cede0ff 100644 (file)
@@ -85,7 +85,7 @@ scanner_init(struct scanner *s, struct xkb_context *ctx,
 }
 
 static inline char
-peek(struct scanner *s)
+scanner_peek(struct scanner *s)
 {
     if (unlikely(s->pos >= s->len))
         return '\0';
@@ -93,19 +93,19 @@ peek(struct scanner *s)
 }
 
 static inline bool
-eof(struct scanner *s)
+scanner_eof(struct scanner *s)
 {
     return s->pos >= s->len;
 }
 
 static inline bool
-eol(struct scanner *s)
+scanner_eol(struct scanner *s)
 {
-    return peek(s) == '\n';
+    return scanner_peek(s) == '\n';
 }
 
 static inline void
-skip_to_eol(struct scanner *s)
+scanner_skip_to_eol(struct scanner *s)
 {
     const char *nl = memchr(s->s + s->pos, '\n', s->len - s->pos);
     const size_t new_pos = nl ? (size_t) (nl - s->s) : s->len;
@@ -114,11 +114,11 @@ skip_to_eol(struct scanner *s)
 }
 
 static inline char
-next(struct scanner *s)
+scanner_next(struct scanner *s)
 {
-    if (unlikely(eof(s)))
+    if (unlikely(scanner_eof(s)))
         return '\0';
-    if (unlikely(eol(s))) {
+    if (unlikely(scanner_eol(s))) {
         s->line++;
         s->column = 1;
     }
@@ -129,16 +129,16 @@ next(struct scanner *s)
 }
 
 static inline bool
-chr(struct scanner *s, char ch)
+scanner_chr(struct scanner *s, char ch)
 {
-    if (likely(peek(s) != ch))
+    if (likely(scanner_peek(s) != ch))
         return false;
     s->pos++; s->column++;
     return true;
 }
 
 static inline bool
-str(struct scanner *s, const char *string, size_t len)
+scanner_str(struct scanner *s, const char *string, size_t len)
 {
     if (s->len - s->pos < len)
         return false;
@@ -148,10 +148,10 @@ str(struct scanner *s, const char *string, size_t len)
     return true;
 }
 
-#define lit(s, literal) str(s, literal, sizeof(literal) - 1)
+#define scanner_lit(s, literal) scanner_str(s, literal, sizeof(literal) - 1)
 
 static inline bool
-buf_append(struct scanner *s, char ch)
+scanner_buf_append(struct scanner *s, char ch)
 {
     if (s->buf_pos + 1 >= sizeof(s->buf))
         return false;
@@ -160,7 +160,7 @@ buf_append(struct scanner *s, char ch)
 }
 
 static inline bool
-buf_appends(struct scanner *s, const char *str)
+scanner_buf_appends(struct scanner *s, const char *str)
 {
     int ret;
     ret = snprintf(s->buf + s->buf_pos, sizeof(s->buf) - s->buf_pos, "%s", str);
@@ -171,20 +171,20 @@ buf_appends(struct scanner *s, const char *str)
 }
 
 static inline bool
-oct(struct scanner *s, uint8_t *out)
+scanner_oct(struct scanner *s, uint8_t *out)
 {
     int i;
-    for (i = 0, *out = 0; peek(s) >= '0' && peek(s) <= '7' && i < 3; i++)
-        *out = *out * 8 + next(s) - '0';
+    for (i = 0, *out = 0; scanner_peek(s) >= '0' && scanner_peek(s) <= '7' && i < 3; i++)
+        *out = *out * 8 + scanner_next(s) - '0';
     return i > 0;
 }
 
 static inline bool
-hex(struct scanner *s, uint8_t *out)
+scanner_hex(struct scanner *s, uint8_t *out)
 {
     int i;
-    for (i = 0, *out = 0; is_xdigit(peek(s)) && i < 2; i++) {
-        const char c = next(s);
+    for (i = 0, *out = 0; is_xdigit(scanner_peek(s)) && i < 2; i++) {
+        const char c = scanner_next(s);
         const char offset = (c >= '0' && c <= '9' ? '0' :
                              c >= 'a' && c <= 'f' ? 'a' - 10 : 'A' - 10);
         *out = *out * 16 + c - offset;
index 099500a..2d3d9d8 100644 (file)
@@ -86,49 +86,49 @@ lex(struct scanner *s, union lvalue *val)
 {
 skip_more_whitespace_and_comments:
     /* Skip spaces. */
-    while (chr(s, ' ') || chr(s, '\t') || chr(s, '\r'));
+    while (scanner_chr(s, ' ') || scanner_chr(s, '\t') || scanner_chr(s, '\r'));
 
     /* Skip comments. */
-    if (lit(s, "//")) {
-        skip_to_eol(s);
+    if (scanner_lit(s, "//")) {
+        scanner_skip_to_eol(s);
     }
 
     /* New line. */
-    if (eol(s)) {
-        while (eol(s)) next(s);
+    if (scanner_eol(s)) {
+        while (scanner_eol(s)) scanner_next(s);
         return TOK_END_OF_LINE;
     }
 
     /* Escaped line continuation. */
-    if (chr(s, '\\')) {
+    if (scanner_chr(s, '\\')) {
         /* Optional \r. */
-        chr(s, '\r');
-        if (!eol(s)) {
+        scanner_chr(s, '\r');
+        if (!scanner_eol(s)) {
             scanner_err(s, "illegal new line escape; must appear at end of line");
             return TOK_ERROR;
         }
-        next(s);
+        scanner_next(s);
         goto skip_more_whitespace_and_comments;
     }
 
     /* See if we're done. */
-    if (eof(s)) return TOK_END_OF_FILE;
+    if (scanner_eof(s)) return TOK_END_OF_FILE;
 
     /* New token. */
     s->token_line = s->line;
     s->token_column = s->column;
 
     /* Operators and punctuation. */
-    if (chr(s, '!')) return TOK_BANG;
-    if (chr(s, '=')) return TOK_EQUALS;
-    if (chr(s, '*')) return TOK_STAR;
+    if (scanner_chr(s, '!')) return TOK_BANG;
+    if (scanner_chr(s, '=')) return TOK_EQUALS;
+    if (scanner_chr(s, '*')) return TOK_STAR;
 
     /* Group name. */
-    if (chr(s, '$')) {
+    if (scanner_chr(s, '$')) {
         val->string.start = s->s + s->pos;
         val->string.len = 0;
-        while (is_ident(peek(s))) {
-            next(s);
+        while (is_ident(scanner_peek(s))) {
+            scanner_next(s);
             val->string.len++;
         }
         if (val->string.len == 0) {
@@ -139,15 +139,15 @@ skip_more_whitespace_and_comments:
     }
 
     /* Include statement. */
-    if (lit(s, "include"))
+    if (scanner_lit(s, "include"))
         return TOK_INCLUDE;
 
     /* Identifier. */
-    if (is_ident(peek(s))) {
+    if (is_ident(scanner_peek(s))) {
         val->string.start = s->s + s->pos;
         val->string.len = 0;
-        while (is_ident(peek(s))) {
-            next(s);
+        while (is_ident(scanner_peek(s))) {
+            scanner_next(s);
             val->string.len++;
         }
         return TOK_IDENTIFIER;
@@ -376,46 +376,46 @@ matcher_include(struct matcher *m, struct scanner *parent_scanner,
         return;
     }
 
-    while (!eof(&s) && !eol(&s)) {
-        if (chr(&s, '%')) {
-            if (chr(&s, '%')) {
-                buf_append(&s, '%');
+    while (!scanner_eof(&s) && !scanner_eol(&s)) {
+        if (scanner_chr(&s, '%')) {
+            if (scanner_chr(&s, '%')) {
+                scanner_buf_append(&s, '%');
             }
-            else if (chr(&s, 'H')) {
+            else if (scanner_chr(&s, 'H')) {
                 const char *home = secure_getenv("HOME");
                 if (!home) {
                     scanner_err(&s, "%%H was used in an include statement, but the HOME environment variable is not set");
                     return;
                 }
-                if (!buf_appends(&s, home)) {
+                if (!scanner_buf_appends(&s, home)) {
                     scanner_err(&s, "include path after expanding %%H is too long");
                     return;
                 }
             }
-            else if (chr(&s, 'S')) {
+            else if (scanner_chr(&s, 'S')) {
                 const char *default_root = xkb_context_include_path_get_system_path(m->ctx);
-                if (!buf_appends(&s, default_root) || !buf_appends(&s, "/rules")) {
+                if (!scanner_buf_appends(&s, default_root) || !scanner_buf_appends(&s, "/rules")) {
                     scanner_err(&s, "include path after expanding %%S is too long");
                     return;
                 }
             }
-            else if (chr(&s, 'E')) {
+            else if (scanner_chr(&s, 'E')) {
                 const char *default_root = xkb_context_include_path_get_extra_path(m->ctx);
-                if (!buf_appends(&s, default_root) || !buf_appends(&s, "/rules")) {
+                if (!scanner_buf_appends(&s, default_root) || !scanner_buf_appends(&s, "/rules")) {
                     scanner_err(&s, "include path after expanding %%E is too long");
                     return;
                 }
             }
             else {
-                scanner_err(&s, "unknown %% format (%c) in include statement", peek(&s));
+                scanner_err(&s, "unknown %% format (%c) in include statement", scanner_peek(&s));
                 return;
             }
         }
         else {
-            buf_append(&s, next(&s));
+            scanner_buf_append(&s, scanner_next(&s));
         }
     }
-    if (!buf_append(&s, '\0')) {
+    if (!scanner_buf_append(&s, '\0')) {
         scanner_err(&s, "include path is too long");
         return;
     }
index b349499..e502216 100644 (file)
@@ -34,14 +34,14 @@ number(struct scanner *s, int64_t *out, int *out_tok)
     const char *start = s->s + s->pos;
     char *end;
 
-    if (lit(s, "0x")) {
-        while (is_xdigit(peek(s))) next(s);
+    if (scanner_lit(s, "0x")) {
+        while (is_xdigit(scanner_peek(s))) scanner_next(s);
         is_hex = true;
     }
     else {
-        while (is_digit(peek(s))) next(s);
-        is_float = chr(s, '.');
-        while (is_digit(peek(s))) next(s);
+        while (is_digit(scanner_peek(s))) scanner_next(s);
+        is_float = scanner_chr(s, '.');
+        while (is_digit(scanner_peek(s))) scanner_next(s);
     }
     if (s->s + s->pos == start)
         return false;
@@ -69,16 +69,16 @@ _xkbcommon_lex(YYSTYPE *yylval, struct scanner *s)
 
 skip_more_whitespace_and_comments:
     /* Skip spaces. */
-    while (is_space(peek(s))) next(s);
+    while (is_space(scanner_peek(s))) scanner_next(s);
 
     /* Skip comments. */
-    if (lit(s, "//") || chr(s, '#')) {
-        skip_to_eol(s);
+    if (scanner_lit(s, "//") || scanner_chr(s, '#')) {
+        scanner_skip_to_eol(s);
         goto skip_more_whitespace_and_comments;
     }
 
     /* See if we're done. */
-    if (eof(s)) return END_OF_FILE;
+    if (scanner_eof(s)) return END_OF_FILE;
 
     /* New token. */
     s->token_line = s->line;
@@ -86,28 +86,28 @@ skip_more_whitespace_and_comments:
     s->buf_pos = 0;
 
     /* String literal. */
-    if (chr(s, '\"')) {
-        while (!eof(s) && !eol(s) && peek(s) != '\"') {
-            if (chr(s, '\\')) {
+    if (scanner_chr(s, '\"')) {
+        while (!scanner_eof(s) && !scanner_eol(s) && scanner_peek(s) != '\"') {
+            if (scanner_chr(s, '\\')) {
                 uint8_t o;
-                if      (chr(s, '\\')) buf_append(s, '\\');
-                else if (chr(s, 'n'))  buf_append(s, '\n');
-                else if (chr(s, 't'))  buf_append(s, '\t');
-                else if (chr(s, 'r'))  buf_append(s, '\r');
-                else if (chr(s, 'b'))  buf_append(s, '\b');
-                else if (chr(s, 'f'))  buf_append(s, '\f');
-                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);
+                if      (scanner_chr(s, '\\')) scanner_buf_append(s, '\\');
+                else if (scanner_chr(s, 'n'))  scanner_buf_append(s, '\n');
+                else if (scanner_chr(s, 't'))  scanner_buf_append(s, '\t');
+                else if (scanner_chr(s, 'r'))  scanner_buf_append(s, '\r');
+                else if (scanner_chr(s, 'b'))  scanner_buf_append(s, '\b');
+                else if (scanner_chr(s, 'f'))  scanner_buf_append(s, '\f');
+                else if (scanner_chr(s, 'v'))  scanner_buf_append(s, '\v');
+                else if (scanner_chr(s, 'e'))  scanner_buf_append(s, '\033');
+                else if (scanner_oct(s, &o))   scanner_buf_append(s, (char) o);
                 else {
                     scanner_warn(s, "unknown escape sequence in string literal");
                     /* Ignore. */
                 }
             } else {
-                buf_append(s, next(s));
+                scanner_buf_append(s, scanner_next(s));
             }
         }
-        if (!buf_append(s, '\0') || !chr(s, '\"')) {
+        if (!scanner_buf_append(s, '\0') || !scanner_chr(s, '\"')) {
             scanner_err(s, "unterminated string literal");
             return ERROR_TOK;
         }
@@ -118,10 +118,10 @@ skip_more_whitespace_and_comments:
     }
 
     /* Key name literal. */
-    if (chr(s, '<')) {
-        while (is_graph(peek(s)) && peek(s) != '>')
-            buf_append(s, next(s));
-        if (!buf_append(s, '\0') || !chr(s, '>')) {
+    if (scanner_chr(s, '<')) {
+        while (is_graph(scanner_peek(s)) && scanner_peek(s) != '>')
+            scanner_buf_append(s, scanner_next(s));
+        if (!scanner_buf_append(s, '\0') || !scanner_chr(s, '>')) {
             scanner_err(s, "unterminated key name literal");
             return ERROR_TOK;
         }
@@ -131,29 +131,29 @@ skip_more_whitespace_and_comments:
     }
 
     /* Operators and punctuation. */
-    if (chr(s, ';')) return SEMI;
-    if (chr(s, '{')) return OBRACE;
-    if (chr(s, '}')) return CBRACE;
-    if (chr(s, '=')) return EQUALS;
-    if (chr(s, '[')) return OBRACKET;
-    if (chr(s, ']')) return CBRACKET;
-    if (chr(s, '(')) return OPAREN;
-    if (chr(s, ')')) return CPAREN;
-    if (chr(s, '.')) return DOT;
-    if (chr(s, ',')) return COMMA;
-    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;
+    if (scanner_chr(s, ';')) return SEMI;
+    if (scanner_chr(s, '{')) return OBRACE;
+    if (scanner_chr(s, '}')) return CBRACE;
+    if (scanner_chr(s, '=')) return EQUALS;
+    if (scanner_chr(s, '[')) return OBRACKET;
+    if (scanner_chr(s, ']')) return CBRACKET;
+    if (scanner_chr(s, '(')) return OPAREN;
+    if (scanner_chr(s, ')')) return CPAREN;
+    if (scanner_chr(s, '.')) return DOT;
+    if (scanner_chr(s, ',')) return COMMA;
+    if (scanner_chr(s, '+')) return PLUS;
+    if (scanner_chr(s, '-')) return MINUS;
+    if (scanner_chr(s, '*')) return TIMES;
+    if (scanner_chr(s, '/')) return DIVIDE;
+    if (scanner_chr(s, '!')) return EXCLAM;
+    if (scanner_chr(s, '~')) return INVERT;
 
     /* Identifier. */
-    if (is_alpha(peek(s)) || peek(s) == '_') {
+    if (is_alpha(scanner_peek(s)) || scanner_peek(s) == '_') {
         s->buf_pos = 0;
-        while (is_alnum(peek(s)) || peek(s) == '_')
-            buf_append(s, next(s));
-        if (!buf_append(s, '\0')) {
+        while (is_alnum(scanner_peek(s)) || scanner_peek(s) == '_')
+            scanner_buf_append(s, scanner_next(s));
+        if (!scanner_buf_append(s, '\0')) {
             scanner_err(s, "identifier too long");
             return ERROR_TOK;
         }