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)
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)
45 45
46#define KW(x) #x 46#define KW(x) #x
47#define KWAT(x) "@" #x 47#define KWAT(x) "@" #x
48#define KWH(x) "#" #x
48 49
49static const char * const tokens[] = 50static const char * const tokens[] =
50{ 51{
@@ -87,6 +88,7 @@ static const char * const ctypes[] =
87 88
88#undef KW 89#undef KW
89#undef KWAT 90#undef KWAT
91#undef KWH
90 92
91#define is_newline(c) ((c) == '\n' || (c) == '\r') 93#define is_newline(c) ((c) == '\n' || (c) == '\r')
92 94
@@ -989,10 +991,10 @@ lex(Eo_Lexer *ls, Eo_Token *tok)
989 return TOK_NUMBER; 991 return TOK_NUMBER;
990 } 992 }
991 if (ls->current && (isalnum(ls->current) 993 if (ls->current && (isalnum(ls->current)
992 || ls->current == '@' || ls->current == '_')) 994 || ls->current == '@' || ls->current == '#' || ls->current == '_'))
993 { 995 {
994 int col = ls->column; 996 int col = ls->column;
995 Eina_Bool at_kw = (ls->current == '@'); 997 Eina_Bool pfx_kw = (ls->current == '@') || (ls->current == '#');
996 const char *str; 998 const char *str;
997 eina_strbuf_reset(ls->buff); 999 eina_strbuf_reset(ls->buff);
998 do 1000 do
@@ -1007,7 +1009,7 @@ lex(Eo_Lexer *ls, Eo_Token *tok)
1007 str); 1009 str);
1008 ls->column = col + 1; 1010 ls->column = col + 1;
1009 tok->value.s = eina_stringshare_add(str); 1011 tok->value.s = eina_stringshare_add(str);
1010 if (at_kw && tok->kw == 0) 1012 if (pfx_kw && tok->kw == 0)
1011 eo_lexer_syntax_error(ls, "invalid keyword"); 1013 eo_lexer_syntax_error(ls, "invalid keyword");
1012 return TOK_VALUE; 1014 return TOK_VALUE;
1013 } 1015 }
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
39 KWAT(private), KWAT(property), KWAT(protected), KWAT(restart), \ 39 KWAT(private), KWAT(property), KWAT(protected), KWAT(restart), \
40 KWAT(pure_virtual), \ 40 KWAT(pure_virtual), \
41 \ 41 \
42 KWH(version), \
43 \
42 KW(byte), KW(ubyte), KW(char), KW(short), KW(ushort), KW(int), KW(uint), \ 44 KW(byte), KW(ubyte), KW(char), KW(short), KW(ushort), KW(int), KW(uint), \
43 KW(long), KW(ulong), KW(llong), KW(ullong), \ 45 KW(long), KW(ulong), KW(llong), KW(ullong), \
44 \ 46 \
@@ -71,6 +73,7 @@ enum Tokens
71/* "regular" keyword and @ prefixed keyword */ 73/* "regular" keyword and @ prefixed keyword */
72#define KW(x) KW_##x 74#define KW(x) KW_##x
73#define KWAT(x) KW_at_##x 75#define KWAT(x) KW_at_##x
76#define KWH(x) KW_hash_##x
74 77
75enum Keywords 78enum Keywords
76{ 79{
@@ -80,6 +83,7 @@ enum Keywords
80 83
81#undef KW 84#undef KW
82#undef KWAT 85#undef KWAT
86#undef KWH
83 87
84enum Numbers 88enum Numbers
85{ 89{
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 @@
1#include <assert.h> 1#include <assert.h>
2#include <limits.h>
2 3
3#ifdef HAVE_CONFIG_H 4#ifdef HAVE_CONFIG_H
4# include "config.h" 5# include "config.h"
@@ -2278,10 +2279,37 @@ found_class:
2278static void 2279static void
2279parse_chunk(Eo_Lexer *ls, Eina_Bool eot) 2280parse_chunk(Eo_Lexer *ls, Eina_Bool eot)
2280{ 2281{
2282 Eina_Bool parsing_header = EINA_TRUE;
2283 Eina_Bool has_version = EINA_FALSE;
2281 while (ls->t.token >= 0) 2284 while (ls->t.token >= 0)
2282 /* set eot to EINA_TRUE so that we only allow parsing of one class */ 2285 switch (ls->t.kw)
2283 if (parse_unit(ls, eot)) 2286 {
2284 eot = EINA_TRUE; 2287 case KW_hash_version:
2288 {
2289 CASE_LOCK(ls, version, "#version specifier");
2290 if (!parsing_header)
2291 eo_lexer_syntax_error(ls, "header keyword outside of unit header");
2292 eo_lexer_get(ls);
2293
2294 check(ls, TOK_NUMBER);
2295 if (ls->t.kw != NUM_INT)
2296 eo_lexer_syntax_error(ls, "invalid #version value");
2297 if (ls->t.value.u > USHRT_MAX)
2298 eo_lexer_syntax_error(ls, "#version too high");
2299 else if (ls->t.value.u < 0)
2300 eo_lexer_syntax_error(ls, "#version too low");
2301
2302 ls->unit->version = (unsigned short)(ls->t.value.u);
2303 eo_lexer_get(ls);
2304 break;
2305 }
2306 default:
2307 parsing_header = EINA_FALSE;
2308 /* set eot to EINA_TRUE so that we only allow parsing of one class */
2309 if (parse_unit(ls, eot))
2310 eot = EINA_TRUE;
2311 break;
2312 }
2285} 2313}
2286 2314
2287Eolian_Unit * 2315Eolian_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)
572 unit->structs = eina_hash_stringshared_new(EINA_FREE_CB(database_typedecl_del)); 572 unit->structs = eina_hash_stringshared_new(EINA_FREE_CB(database_typedecl_del));
573 unit->enums = eina_hash_stringshared_new(EINA_FREE_CB(database_typedecl_del)); 573 unit->enums = eina_hash_stringshared_new(EINA_FREE_CB(database_typedecl_del));
574 unit->objects = eina_hash_stringshared_new(NULL); 574 unit->objects = eina_hash_stringshared_new(NULL);
575
576 /* baseline version; support for higher featurelevel must be specified explicitly */
577 unit->version = 1;
575} 578}
576 579
577static void 580static 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
45 Eina_Hash *structs; 45 Eina_Hash *structs;
46 Eina_Hash *enums; 46 Eina_Hash *enums;
47 Eina_Hash *objects; 47 Eina_Hash *objects;
48 unsigned short version;
48}; 49};
49 50
50typedef struct _Eolian_State_Area 51typedef struct _Eolian_State_Area