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>
#include <sys/types.h>
#include <sys/stat.h>
-#include <ctype.h>
#include <errno.h>
#include <unistd.h>
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;
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);
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++;
}
}
/* 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++;
}
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;
}
*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;
#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;
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;
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, '#')) {
/* 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");
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");