X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fxkbcomp%2Fscanner.c;h=57babbb20439a86f95a25f9b56628f8697400177;hb=9d15c6a7a1834b02bcbabd4de736f58979759f29;hp=aef9a62f6d2277b8249a131afb3e7794b9195c2e;hpb=409f27d7836b61b81c672e7737e42d75f15a072a;p=platform%2Fupstream%2Flibxkbcommon.git diff --git a/src/xkbcomp/scanner.c b/src/xkbcomp/scanner.c index aef9a62..57babbb 100644 --- a/src/xkbcomp/scanner.c +++ b/src/xkbcomp/scanner.c @@ -21,30 +21,12 @@ * DEALINGS IN THE SOFTWARE. */ +#include "config.h" + #include "xkbcomp-priv.h" #include "parser-priv.h" #include "scanner-utils.h" -static void -scanner_log(enum xkb_log_level level, struct scanner *s, const char *msg) -{ - xkb_log_cond_level(s->ctx, level, "%s:%d:%d: %s\n", s->file_name, - s->token_line, s->token_column, msg); -} - -int -scanner_error(struct scanner *s, const char *msg) -{ - scanner_log(XKB_LOG_LEVEL_ERROR, s, msg); - return ERROR_TOK; -} - -void -scanner_warn(struct scanner *s, const char *msg) -{ - scanner_log(XKB_LOG_LEVEL_WARNING, s, msg); -} - static bool number(struct scanner *s, int64_t *out, int *out_tok) { @@ -52,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 (isxdigit(peek(s))) next(s); + if (scanner_lit(s, "0x")) { + while (is_xdigit(scanner_peek(s))) scanner_next(s); is_hex = true; } else { - while (isdigit(peek(s))) next(s); - is_float = chr(s, '.'); - while (isdigit(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; @@ -68,6 +50,8 @@ number(struct scanner *s, int64_t *out, int *out_tok) if (is_hex) *out = strtoul(start, &end, 16); else if (is_float) + /* The parser currently just ignores floats, so the cast is + * fine - the value doesn't matter. */ *out = strtod(start, &end); else *out = strtoul(start, &end, 10); @@ -85,16 +69,16 @@ _xkbcommon_lex(YYSTYPE *yylval, struct scanner *s) skip_more_whitespace_and_comments: /* Skip spaces. */ - while (isspace(peek(s))) next(s); + while (is_space(scanner_peek(s))) scanner_next(s); /* Skip comments. */ - if (lit(s, "//") || chr(s, '#')) { - while (!eof(s) && !eol(s)) next(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; @@ -102,89 +86,111 @@ 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); + size_t start_pos = s->pos; + 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) && is_valid_char((char) o)) + scanner_buf_append(s, (char) o); + else if (s->pos > start_pos) + scanner_warn_with_code(s, + XKB_WARNING_INVALID_ESCAPE_SEQUENCE, + "invalid octal escape sequence (%.*s) in string literal", + (int) (s->pos - start_pos + 1), &s->s[start_pos - 1]); + /* Ignore. */ else { - scanner_warn(s, "unknown escape sequence in string literal"); + scanner_warn_with_code(s, + XKB_WARNING_UNKNOWN_CHAR_ESCAPE_SEQUENCE, + "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 (!buf_append(s, '\0') || !chr(s, '\"')) - return scanner_error(s, "unterminated string literal"); + if (!scanner_buf_append(s, '\0') || !scanner_chr(s, '\"')) { + scanner_err(s, "unterminated string literal"); + return ERROR_TOK; + } yylval->str = strdup(s->buf); if (!yylval->str) - return scanner_error(s, "scanner out of memory"); + return ERROR_TOK; return STRING; } /* Key name literal. */ - if (chr(s, '<')) { - while (isgraph(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 (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; + } /* Empty key name literals are allowed. */ - yylval->sval = xkb_atom_intern(s->ctx, s->buf, s->buf_pos - 1); + yylval->atom = xkb_atom_intern(s->ctx, s->buf, s->buf_pos - 1); return KEYNAME; } /* 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 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 (isalpha(peek(s)) || peek(s) == '_') { + if (is_alpha(scanner_peek(s)) || scanner_peek(s) == '_') { s->buf_pos = 0; - while (isalnum(peek(s)) || peek(s) == '_') - buf_append(s, next(s)); - if (!buf_append(s, '\0')) - return scanner_error(s, "identifier too long"); + 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; + } /* Keyword. */ - tok = keyword_to_token(s->buf); - if ((int) tok != -1) return tok; + 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(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(s, "malformed number literal"); + if (tok == ERROR_TOK) { + scanner_err_with_code(s, XKB_ERROR_MALFORMED_NUMBER_LITERAL, + "malformed number literal"); + return ERROR_TOK; + } return tok; } - return scanner_error(s, "unrecognized token"); + scanner_err(s, "unrecognized token"); + return ERROR_TOK; } XkbFile * @@ -192,7 +198,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); } @@ -202,12 +208,13 @@ 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); if (!ok) { - log_err(ctx, "Couldn't read XKB file %s: %s\n", + log_err(ctx, XKB_LOG_MESSAGE_NO_ID, + "Couldn't read XKB file %s: %s\n", file_name, strerror(errno)); return NULL; }