Replace ctype.h functions with ascii ones
authorRan Benita <ran234@gmail.com>
Mon, 14 Oct 2013 15:59:53 +0000 (18:59 +0300)
committerRan Benita <ran234@gmail.com>
Mon, 14 Oct 2013 15:59:53 +0000 (18:59 +0300)
ctype.h is locale-dependent, so using it in our scanners is not optimal.
Let's be deterministic with our own simple functions.

Signed-off-by: Ran Benita <ran234@gmail.com>
src/context.c
src/utils.h
src/xkbcomp/rules.c
src/xkbcomp/scanner-utils.h
src/xkbcomp/scanner.c

index 1e148da..bf76ac2 100644 (file)
@@ -26,7 +26,6 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <ctype.h>
 #include <errno.h>
 #include <unistd.h>
 
@@ -246,7 +245,7 @@ log_level(const char *level) {
 
     errno = 0;
     lvl = strtol(level, &endptr, 10);
-    if (errno == 0 && (endptr[0] == '\0' || isspace(endptr[0])))
+    if (errno == 0 && (endptr[0] == '\0' || is_space(endptr[0])))
         return lvl;
     if (istreq_prefix("crit", level))
         return XKB_LOG_LEVEL_CRITICAL;
index 5cd6e57..0f4a388 100644 (file)
@@ -117,6 +117,47 @@ max(int misc, int other)
     return (misc > other) ? misc : other;
 }
 
+/* ctype.h is locale-dependent and has other oddities. */
+static inline bool
+is_space(char ch)
+{
+    return ch == ' ' || (ch >= '\t' && ch <= '\r');
+}
+
+static inline bool
+is_alpha(char ch)
+{
+    return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
+}
+
+static inline bool
+is_digit(char ch)
+{
+    return ch >= '0' && ch <= '9';
+}
+
+static inline bool
+is_alnum(char ch)
+{
+    return is_alpha(ch) || is_digit(ch);
+}
+
+static inline bool
+is_xdigit(char ch)
+{
+    return
+        (ch >= '0' && ch <= '9') ||
+        (ch >= 'a' && ch <= 'f') ||
+        (ch >= 'A' && ch <= 'F');
+}
+
+static inline bool
+is_graph(char ch)
+{
+    /* See table in ascii(7). */
+    return ch >= '!' && ch <= '~';
+}
+
 bool
 map_file(FILE *file, const char **string_out, size_t *size_out);
 
index de8822b..54468a0 100644 (file)
@@ -209,7 +209,7 @@ skip_more_whitespace_and_comments:
     if (chr(s, '$')) {
         val->string.start = s->s + s->pos;
         val->string.len = 0;
-        while (isgraph(peek(s))) {
+        while (is_graph(peek(s))) {
             next(s);
             val->string.len++;
         }
@@ -222,10 +222,10 @@ skip_more_whitespace_and_comments:
     }
 
     /* Identifier. */
-    if (isgraph(peek(s))) {
+    if (is_graph(peek(s))) {
         val->string.start = s->s + s->pos;
         val->string.len = 0;
-        while (isgraph(peek(s))) {
+        while (is_graph(peek(s))) {
             next(s);
             val->string.len++;
         }
@@ -339,8 +339,8 @@ struct matcher {
 static struct sval
 strip_spaces(struct sval v)
 {
-    while (v.len > 0 && isspace(v.start[0])) { v.len--; v.start++; }
-    while (v.len > 0 && isspace(v.start[v.len - 1])) v.len--;
+    while (v.len > 0 && is_space(v.start[0])) { v.len--; v.start++; }
+    while (v.len > 0 && is_space(v.start[v.len - 1])) v.len--;
     return v;
 }
 
@@ -444,7 +444,7 @@ extract_layout_index(const char *s, size_t max_len, xkb_layout_index_t *out)
     *out = XKB_LAYOUT_INVALID;
     if (max_len < 3)
         return -1;
-    if (s[0] != '[' || !isdigit(s[1]) || s[2] != ']')
+    if (s[0] != '[' || !is_digit(s[1]) || s[2] != ']')
         return -1;
     if (s[1] - '0' < 1 || s[1] - '0' > XKB_MAX_GROUPS)
         return -1;
index 350be66..21ba6d8 100644 (file)
@@ -24,8 +24,6 @@
 #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;
index b5477d3..4e7d70b 100644 (file)
@@ -53,13 +53,13 @@ number(struct scanner *s, int64_t *out, int *out_tok)
     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;
@@ -85,7 +85,7 @@ _xkbcommon_lex(YYSTYPE *yylval, struct scanner *s)
 
 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, '#')) {
@@ -133,7 +133,7 @@ skip_more_whitespace_and_comments:
 
     /* 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 (!buf_append(s, '\0') || !chr(s, '>'))
             return scanner_error(s, "unterminated key name literal");
@@ -160,9 +160,9 @@ skip_more_whitespace_and_comments:
     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(s, "identifier too long");