Add scanner-utils.h for common scanner functions
authorRan Benita <ran234@gmail.com>
Thu, 14 Mar 2013 12:31:55 +0000 (14:31 +0200)
committerDaniel Stone <daniel@fooishbar.org>
Mon, 1 Apr 2013 17:20:54 +0000 (18:20 +0100)
We want to share the same functions for another scanner.

Signed-off-by: Ran Benita <ran234@gmail.com>
Makefile.am
src/xkbcomp/rules.c
src/xkbcomp/scanner-utils.h [new file with mode: 0644]

index f7e7fb1..99a49f5 100644 (file)
@@ -43,6 +43,7 @@ libxkbcommon_la_SOURCES = \
        src/xkbcomp/rules.c \
        src/xkbcomp/rules.h \
        src/xkbcomp/scanner.l \
+       src/xkbcomp/scanner-utils.h \
        src/xkbcomp/symbols.c \
        src/xkbcomp/types.c \
        src/xkbcomp/vmod.c \
index 3f71760..ec4a7aa 100644 (file)
@@ -57,6 +57,7 @@
 #include "xkbcomp-priv.h"
 #include "rules.h"
 #include "include.h"
+#include "scanner-utils.h"
 
 /*
  * The rules file
 
 /* Scanner / Lexer */
 
-/* Point to some substring in the file; used to avoid copying. */
-struct sval {
-    const char *start;
-    unsigned int len;
-};
-typedef darray(struct sval) darray_sval;
-
-static inline bool
-svaleq(struct sval s1, struct sval s2)
-{
-    return s1.len == s2.len && strncmp(s1.start, s2.start, s1.len) == 0;
-}
-
-static inline bool
-svaleq_prefix(struct sval s1, struct sval s2)
-{
-    return s1.len <= s2.len && strncmp(s1.start, s2.start, s1.len) == 0;
-}
-
 /* Values returned with some tokens, like yylval. */
 union lvalue {
     struct sval string;
@@ -170,15 +152,6 @@ struct location {
     int line, column;
 };
 
-struct scanner {
-    const char *s;
-    size_t pos;
-    size_t len;
-    int line, column;
-    const char *file_name;
-    struct xkb_context *ctx;
-};
-
 enum rules_token {
     TOK_END_OF_FILE = 0,
     TOK_END_OF_LINE,
@@ -190,18 +163,6 @@ enum rules_token {
     TOK_ERROR
 };
 
-static void
-scanner_init(struct scanner *s, struct xkb_context *ctx,
-             const char *string, size_t len, const char *file_name)
-{
-    s->s = string;
-    s->len = len;
-    s->pos = 0;
-    s->line = s->column = 1;
-    s->file_name = file_name;
-    s->ctx = ctx;
-}
-
 /* C99 is stupid. Just use the 1 variant when there are no args. */
 #define scanner_error1(scanner, loc, msg) \
     log_warn(scanner->ctx, "rules/%s:%d:%d: " msg "\n", \
@@ -210,61 +171,6 @@ scanner_init(struct scanner *s, struct xkb_context *ctx,
     log_warn(scanner->ctx, "rules/%s:%d:%d: " fmt "\n", \
              scanner->file_name, loc->line, loc->column, __VA_ARGS__)
 
-static char
-peek(struct scanner *s)
-{
-    return s->pos < s->len ? s->s[s->pos] : '\0';
-}
-
-static bool
-eof(struct scanner *s)
-{
-    return peek(s) == '\0';
-}
-
-static bool
-eol(struct scanner *s)
-{
-    return peek(s) == '\n';
-}
-
-static char
-next(struct scanner *s)
-{
-    if (eof(s))
-        return '\0';
-    if (eol(s)) {
-        s->line++;
-        s->column = 1;
-    }
-    else {
-        s->column++;
-    }
-    return s->s[s->pos++];
-}
-
-static bool
-chr(struct scanner *s, char ch)
-{
-    if (peek(s) != ch)
-        return false;
-    s->pos++; s->column++;
-    return true;
-}
-
-static bool
-str(struct scanner *s, const char *string, size_t len)
-{
-    if (s->len - s->pos < len)
-        return false;
-    if (strncasecmp(s->s + s->pos, string, len) != 0)
-        return false;
-    s->pos += len; s->column += len;
-    return true;
-}
-
-#define lit(s, literal) str(s, literal, sizeof(literal) - 1)
-
 static enum rules_token
 lex(struct scanner *s, union lvalue *val, struct location *loc)
 {
diff --git a/src/xkbcomp/scanner-utils.h b/src/xkbcomp/scanner-utils.h
new file mode 100644 (file)
index 0000000..74870ea
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * Copyright © 2012 Ran Benita <ran234@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef XKBCOMP_SCANNER_UTILS_H
+#define XKBCOMP_SCANNER_UTILS_H
+
+#include <ctype.h>
+
+/* Point to some substring in the file; used to avoid copying. */
+struct sval {
+    const char *start;
+    unsigned int len;
+};
+typedef darray(struct sval) darray_sval;
+
+static inline bool
+svaleq(struct sval s1, struct sval s2)
+{
+    return s1.len == s2.len && strncmp(s1.start, s2.start, s1.len) == 0;
+}
+
+static inline bool
+svaleq_prefix(struct sval s1, struct sval s2)
+{
+    return s1.len <= s2.len && strncmp(s1.start, s2.start, s1.len) == 0;
+}
+
+struct scanner {
+    const char *s;
+    size_t pos;
+    size_t len;
+    char buf[1024];
+    size_t buf_pos;
+    int line, column;
+    const char *file_name;
+    struct xkb_context *ctx;
+};
+
+static inline void
+scanner_init(struct scanner *s, struct xkb_context *ctx,
+             const char *string, size_t len, const char *file_name)
+{
+    s->s = string;
+    s->len = len;
+    s->pos = 0;
+    s->line = s->column = 1;
+    s->file_name = file_name;
+    s->ctx = ctx;
+}
+
+static inline char
+peek(struct scanner *s)
+{
+    return s->pos < s->len ? s->s[s->pos] : '\0';
+}
+
+static inline bool
+eof(struct scanner *s)
+{
+    return peek(s) == '\0';
+}
+
+static inline bool
+eol(struct scanner *s)
+{
+    return peek(s) == '\n';
+}
+
+/*
+ * Use the check_nl variant when the current char might be a new line;
+ * just an optimization.
+ */
+static inline char
+next(struct scanner *s)
+{
+    if (eof(s))
+        return '\0';
+    if (eol(s)) {
+        s->line++;
+        s->column = 1;
+    }
+    else {
+        s->column++;
+    }
+    return s->s[s->pos++];
+}
+
+static inline bool
+chr(struct scanner *s, char ch)
+{
+    if (peek(s) != ch)
+        return false;
+    s->pos++; s->column++;
+    return true;
+}
+
+static inline bool
+str(struct scanner *s, const char *string, size_t len)
+{
+    if (s->len - s->pos < len)
+        return false;
+    if (strncasecmp(s->s + s->pos, string, len) != 0)
+        return false;
+    s->pos += len; s->column += len;
+    return true;
+}
+
+#define lit(s, literal) str(s, literal, sizeof(literal) - 1)
+
+static inline bool
+buf_append(struct scanner *s, char ch)
+{
+    if (s->buf_pos + 1 >= sizeof(s->buf))
+        return false;
+    s->buf[s->buf_pos++] = ch;
+    return true;
+}
+
+static inline bool
+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';
+    return i > 0;
+}
+
+#endif