136 lines
3.8 KiB
C
136 lines
3.8 KiB
C
/* $Id$ */
|
|
/* Copyright (c) 2008 Pierre Pronchery <khorben@defora.org> */
|
|
/* This file is part of DeforaOS Devel c99 */
|
|
/* c99 is not free software; you can redistribute it and/or modify it under the
|
|
* terms of the Creative Commons Attribution-NonCommercial-ShareAlike 3.0
|
|
* Unported as published by the Creative Commons organization.
|
|
*
|
|
* c99 is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
* A PARTICULAR PURPOSE. See the Creative Commons Attribution-NonCommercial-
|
|
* ShareAlike 3.0 Unported license for more details.
|
|
*
|
|
* You should have received a copy of the Creative Commons Attribution-
|
|
* NonCommercial-ShareAlike 3.0 along with c99; if not, browse to
|
|
* http://creativecommons.org/licenses/by-nc-sa/3.0/ */
|
|
|
|
|
|
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include "common.h"
|
|
#include "c99.h"
|
|
#include "../config.h"
|
|
|
|
|
|
/* private */
|
|
/* variables */
|
|
static char * _tokens[C99_CODE_COUNT] =
|
|
{
|
|
NULL, ",", "\"",
|
|
/* directives */
|
|
NULL, "#define", "#elif", "#else", "#endif", "#error", "#if", "#ifdef",
|
|
"#ifndef", "#include", "#pragma", "#undef", "#warning",
|
|
/* operators */
|
|
"&=", "&", "|", "|=", ":", "&&", "||", "==", ">>=", ">>", "##", "/=",
|
|
"/", "<<=", "<<", "--", ".", "...", "++", "=", ">=", ">", "#", "{",
|
|
"[", "<=", "<", "(", "-=", "->", "-", "%=", "%", "!=", "!", "+=", "+",
|
|
"?", "}", "]", ")", ";", "*=", "~", "*", "^=", "^",
|
|
/* more codes */
|
|
"'", "whitespace", "newline", "comment", "word", "unknown", "constant",
|
|
"identifier",
|
|
/* keywords */
|
|
"auto", "break", "case", "char", "const", "continue", "default", "do",
|
|
"double", "else", "enum", "extern", "float", "for", "goto", "if",
|
|
"inline", "int", "long", "register", "restrict", "return", "short",
|
|
"signed", "sizeof", "static", "struct", "switch", "typedef", "union",
|
|
"unsigned", "void", "volatile", "while", "_Bool", "_Complex",
|
|
"_Imaginary", "name"
|
|
};
|
|
|
|
|
|
/* protected */
|
|
/* functions */
|
|
/* useful */
|
|
/* scan */
|
|
static int _scan_skip_meta(C99 * c99);
|
|
static void _meta_error(C99 * c99, TokenCode code);
|
|
|
|
int scan(C99 * c99)
|
|
{
|
|
int ret;
|
|
char const * string;
|
|
size_t i;
|
|
int c;
|
|
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "DEBUG: %s()\n", __func__);
|
|
#endif
|
|
if(c99->token != NULL)
|
|
token_delete(c99->token);
|
|
if((ret = _scan_skip_meta(c99)) != 0
|
|
|| c99->token == NULL)
|
|
return ret;
|
|
if(token_get_code(c99->token) == C99_CODE_SQUOTE)
|
|
{
|
|
token_set_code(c99->token, C99_CODE_CONSTANT);
|
|
return 0;
|
|
}
|
|
if(token_get_code(c99->token) != C99_CODE_WORD)
|
|
return 0;
|
|
if((string = token_get_string(c99->token)) == NULL)
|
|
return 0;
|
|
for(i = C99_CODE_KEYWORD_FIRST; i <= C99_CODE_KEYWORD_LAST; i++)
|
|
if(strcmp(_tokens[i], string) == 0)
|
|
{
|
|
token_set_code(c99->token, i);
|
|
return 0;
|
|
}
|
|
c = string[0];
|
|
if(isalpha(c) || c == '_')
|
|
token_set_code(c99->token, code_type_get(c99->code, string) >= 0
|
|
? C99_CODE_TYPEDEF_NAME : C99_CODE_IDENTIFIER);
|
|
else if(isdigit(c)) /* FIXME make a stricter check? */
|
|
token_set_code(c99->token, C99_CODE_CONSTANT);
|
|
return 0;
|
|
}
|
|
|
|
static int _scan_skip_meta(C99 * c99)
|
|
{
|
|
TokenCode code;
|
|
|
|
while(cpp_scan(c99->cpp, &c99->token) == 0)
|
|
{
|
|
if(c99->token == NULL)
|
|
return 0;
|
|
if((code = token_get_code(c99->token)) != C99_CODE_WHITESPACE
|
|
&& (code < C99_CODE_META_FIRST
|
|
|| code > C99_CODE_META_LAST))
|
|
return 0;
|
|
if(code == C99_CODE_META_ERROR || code == C99_CODE_META_WARNING)
|
|
_meta_error(c99, code);
|
|
token_delete(c99->token);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static void _meta_error(C99 * c99, TokenCode code)
|
|
{
|
|
if(code == C99_CODE_META_ERROR)
|
|
c99->error_cnt++;
|
|
else
|
|
c99->warning_cnt++;
|
|
fprintf(stderr, "%s%s%s%u%s%s%s%s\n", PACKAGE ": ",
|
|
token_get_filename(c99->token), ":",
|
|
token_get_line(c99->token), ": ",
|
|
(code == C99_CODE_META_ERROR) ? "error" : "warning",
|
|
": ", token_get_string(c99->token));
|
|
}
|
|
|
|
|
|
/* accessors */
|
|
char const * tokencode_get_string(TokenCode code)
|
|
{
|
|
return _tokens[code];
|
|
}
|