summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Kolesa <d.kolesa@samsung.com>2019-05-26 18:09:34 +0200
committerDaniel Kolesa <d.kolesa@samsung.com>2019-05-26 18:16:01 +0200
commitdb1b637faea4dfc2c1acd06f282f26a5d88bdcae (patch)
tree52c1acd6f98fcd19a3be882aebf285265429fb0b
parent13ddc5dbc165f3fead4a70301073bc901dbc1269 (diff)
downloadefl-db1b637faea4dfc2c1acd06f282f26a5d88bdcae.tar.gz
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
-rw-r--r--src/lib/eolian/eo_lexer.c8
-rw-r--r--src/lib/eolian/eo_lexer.h4
-rw-r--r--src/lib/eolian/eo_parser.c34
-rw-r--r--src/lib/eolian/eolian_database.c3
-rw-r--r--src/lib/eolian/eolian_database.h1
5 files changed, 44 insertions, 6 deletions
diff --git a/src/lib/eolian/eo_lexer.c b/src/lib/eolian/eo_lexer.c
index 6b2747a130..aad79d8f71 100644
--- a/src/lib/eolian/eo_lexer.c
+++ b/src/lib/eolian/eo_lexer.c
@@ -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;
}
diff --git a/src/lib/eolian/eo_lexer.h b/src/lib/eolian/eo_lexer.h
index e9b5e7b0e0..5bc7064151 100644
--- a/src/lib/eolian/eo_lexer.h
+++ b/src/lib/eolian/eo_lexer.h
@@ -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
{
diff --git a/src/lib/eolian/eo_parser.c b/src/lib/eolian/eo_parser.c
index 524b31a383..74c76d3a7d 100644
--- a/src/lib/eolian/eo_parser.c
+++ b/src/lib/eolian/eo_parser.c
@@ -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 *
diff --git a/src/lib/eolian/eolian_database.c b/src/lib/eolian/eolian_database.c
index 93e833e9a5..0fb5a134f6 100644
--- a/src/lib/eolian/eolian_database.c
+++ b/src/lib/eolian/eolian_database.c
@@ -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
diff --git a/src/lib/eolian/eolian_database.h b/src/lib/eolian/eolian_database.h
index f74d0fa31a..0dce769370 100644
--- a/src/lib/eolian/eolian_database.h
+++ b/src/lib/eolian/eolian_database.h
@@ -45,6 +45,7 @@ struct _Eolian_Unit
Eina_Hash *structs;
Eina_Hash *enums;
Eina_Hash *objects;
+ unsigned short version;
};
typedef struct _Eolian_State_Area