eolian: initial versioning implementation
This implements initial support for specifying unit versions. The default version is 1, specifying the basic feature level. If you want to specify another version, you need to specify something like `#version 2` at the beginning of the .eo or .eot file; the version number must be higher than 0 and lower than USHRT_MAX (typically 65536). The beginning of the file is now called the "header section"; other things may be added into the header section later. Version cannot be specified twice, and it cannot be specified once other contents (like types or class definition) appear. Comments do not count as other contents, so those are fine to appear before #version. @feature
This commit is contained in:
parent
13ddc5dbc1
commit
db1b637fae
|
@ -45,6 +45,7 @@ next_char(Eo_Lexer *ls)
|
|||
|
||||
#define KW(x) #x
|
||||
#define KWAT(x) "@" #x
|
||||
#define KWH(x) "#" #x
|
||||
|
||||
static const char * const tokens[] =
|
||||
{
|
||||
|
@ -87,6 +88,7 @@ static const char * const ctypes[] =
|
|||
|
||||
#undef KW
|
||||
#undef KWAT
|
||||
#undef KWH
|
||||
|
||||
#define is_newline(c) ((c) == '\n' || (c) == '\r')
|
||||
|
||||
|
@ -989,10 +991,10 @@ lex(Eo_Lexer *ls, Eo_Token *tok)
|
|||
return TOK_NUMBER;
|
||||
}
|
||||
if (ls->current && (isalnum(ls->current)
|
||||
|| ls->current == '@' || ls->current == '_'))
|
||||
|| ls->current == '@' || ls->current == '#' || ls->current == '_'))
|
||||
{
|
||||
int col = ls->column;
|
||||
Eina_Bool at_kw = (ls->current == '@');
|
||||
Eina_Bool pfx_kw = (ls->current == '@') || (ls->current == '#');
|
||||
const char *str;
|
||||
eina_strbuf_reset(ls->buff);
|
||||
do
|
||||
|
@ -1007,7 +1009,7 @@ lex(Eo_Lexer *ls, Eo_Token *tok)
|
|||
str);
|
||||
ls->column = col + 1;
|
||||
tok->value.s = eina_stringshare_add(str);
|
||||
if (at_kw && tok->kw == 0)
|
||||
if (pfx_kw && tok->kw == 0)
|
||||
eo_lexer_syntax_error(ls, "invalid keyword");
|
||||
return TOK_VALUE;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,8 @@ enum Tokens
|
|||
KWAT(private), KWAT(property), KWAT(protected), KWAT(restart), \
|
||||
KWAT(pure_virtual), \
|
||||
\
|
||||
KWH(version), \
|
||||
\
|
||||
KW(byte), KW(ubyte), KW(char), KW(short), KW(ushort), KW(int), KW(uint), \
|
||||
KW(long), KW(ulong), KW(llong), KW(ullong), \
|
||||
\
|
||||
|
@ -71,6 +73,7 @@ enum Tokens
|
|||
/* "regular" keyword and @ prefixed keyword */
|
||||
#define KW(x) KW_##x
|
||||
#define KWAT(x) KW_at_##x
|
||||
#define KWH(x) KW_hash_##x
|
||||
|
||||
enum Keywords
|
||||
{
|
||||
|
@ -80,6 +83,7 @@ enum Keywords
|
|||
|
||||
#undef KW
|
||||
#undef KWAT
|
||||
#undef KWH
|
||||
|
||||
enum Numbers
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
|
@ -2278,10 +2279,37 @@ found_class:
|
|||
static void
|
||||
parse_chunk(Eo_Lexer *ls, Eina_Bool eot)
|
||||
{
|
||||
Eina_Bool parsing_header = EINA_TRUE;
|
||||
Eina_Bool has_version = EINA_FALSE;
|
||||
while (ls->t.token >= 0)
|
||||
/* set eot to EINA_TRUE so that we only allow parsing of one class */
|
||||
if (parse_unit(ls, eot))
|
||||
eot = EINA_TRUE;
|
||||
switch (ls->t.kw)
|
||||
{
|
||||
case KW_hash_version:
|
||||
{
|
||||
CASE_LOCK(ls, version, "#version specifier");
|
||||
if (!parsing_header)
|
||||
eo_lexer_syntax_error(ls, "header keyword outside of unit header");
|
||||
eo_lexer_get(ls);
|
||||
|
||||
check(ls, TOK_NUMBER);
|
||||
if (ls->t.kw != NUM_INT)
|
||||
eo_lexer_syntax_error(ls, "invalid #version value");
|
||||
if (ls->t.value.u > USHRT_MAX)
|
||||
eo_lexer_syntax_error(ls, "#version too high");
|
||||
else if (ls->t.value.u < 0)
|
||||
eo_lexer_syntax_error(ls, "#version too low");
|
||||
|
||||
ls->unit->version = (unsigned short)(ls->t.value.u);
|
||||
eo_lexer_get(ls);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
parsing_header = EINA_FALSE;
|
||||
/* set eot to EINA_TRUE so that we only allow parsing of one class */
|
||||
if (parse_unit(ls, eot))
|
||||
eot = EINA_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Eolian_Unit *
|
||||
|
|
|
@ -572,6 +572,9 @@ database_unit_init(Eolian_State *state, Eolian_Unit *unit, const char *file)
|
|||
unit->structs = eina_hash_stringshared_new(EINA_FREE_CB(database_typedecl_del));
|
||||
unit->enums = eina_hash_stringshared_new(EINA_FREE_CB(database_typedecl_del));
|
||||
unit->objects = eina_hash_stringshared_new(NULL);
|
||||
|
||||
/* baseline version; support for higher featurelevel must be specified explicitly */
|
||||
unit->version = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -45,6 +45,7 @@ struct _Eolian_Unit
|
|||
Eina_Hash *structs;
|
||||
Eina_Hash *enums;
|
||||
Eina_Hash *objects;
|
||||
unsigned short version;
|
||||
};
|
||||
|
||||
typedef struct _Eolian_State_Area
|
||||
|
|
Loading…
Reference in New Issue