2017-10-27 11:49:02 -07:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "edje_cc.h"
|
|
|
|
|
|
|
|
#define MESSAGE_OVERRIDE
|
|
|
|
|
|
|
|
typedef struct _Code_Symbol
|
|
|
|
{
|
|
|
|
const char *name;
|
|
|
|
const char *tag;
|
|
|
|
Eina_List *args;
|
|
|
|
char *body;
|
|
|
|
Eina_Bool is_public : 1;
|
|
|
|
} Code_Symbol;
|
|
|
|
|
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
TOKEN_TYPE_INVALID = -1,
|
|
|
|
TOKEN_TYPE_EOF,
|
2018-02-26 13:15:30 -08:00
|
|
|
TOKEN_TYPE_COLON = (1 << 0),
|
|
|
|
TOKEN_TYPE_SEMICOLON = (1 << 1),
|
|
|
|
TOKEN_TYPE_COMMA = (1 << 2),
|
|
|
|
TOKEN_TYPE_PARENS = (1 << 3),
|
|
|
|
TOKEN_TYPE_BRACES = (1 << 4),
|
2017-10-27 11:49:02 -07:00
|
|
|
TOKEN_TYPE_EQUAL_MARK = (1 << 5),
|
2018-02-26 13:15:30 -08:00
|
|
|
TOKEN_TYPE_PUBLIC = (1 << 6),
|
2017-10-27 11:49:02 -07:00
|
|
|
TOKEN_TYPE_IDENTIFIER = (1 << 7)
|
|
|
|
} Token_Type;
|
|
|
|
|
|
|
|
typedef struct _Token
|
|
|
|
{
|
2018-02-26 13:15:30 -08:00
|
|
|
char *str;
|
2017-10-27 11:49:02 -07:00
|
|
|
Token_Type type;
|
|
|
|
} Token;
|
|
|
|
|
|
|
|
static void code_parse_internal(Code *code);
|
|
|
|
static Token *next_token(char **begin, char *end);
|
|
|
|
|
|
|
|
static void
|
|
|
|
code_parse(Code *code)
|
|
|
|
{
|
|
|
|
Edje_Part_Collection_Parser *pcp;
|
|
|
|
Code *base;
|
|
|
|
Eina_List *l;
|
|
|
|
int id;
|
|
|
|
|
2017-11-21 06:48:28 -08:00
|
|
|
if (code->is_lua || code->parsed) return;
|
2017-10-27 11:49:02 -07:00
|
|
|
|
|
|
|
id = eina_list_data_idx(codes, code);
|
|
|
|
pcp = eina_list_nth(edje_collections, id);
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(pcp->base_codes, l, base)
|
2017-11-21 06:48:28 -08:00
|
|
|
code_parse(base);
|
2017-10-27 11:49:02 -07:00
|
|
|
|
|
|
|
if (code->shared)
|
|
|
|
code_parse_internal(code);
|
|
|
|
|
|
|
|
code->parsed = EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
code_parse_internal(Code *code)
|
|
|
|
{
|
2017-11-03 22:41:44 -07:00
|
|
|
Code_Symbol *sym = NULL, *func = NULL;
|
2018-04-08 19:14:07 -07:00
|
|
|
Token *token, *tmp = NULL;
|
2017-10-27 11:49:02 -07:00
|
|
|
char *begin = code->shared;
|
|
|
|
char *end = begin + strlen(begin);
|
|
|
|
char *body;
|
2017-10-31 00:27:38 -07:00
|
|
|
Eina_Array *name_stack;
|
2017-10-27 11:49:02 -07:00
|
|
|
Eina_Bool is_args = EINA_FALSE;
|
|
|
|
Eina_Bool is_public = EINA_FALSE;
|
|
|
|
int depth = 0;
|
|
|
|
|
2017-10-31 00:27:38 -07:00
|
|
|
name_stack = eina_array_new(4);
|
2017-10-27 11:49:02 -07:00
|
|
|
|
|
|
|
while ((token = next_token(&begin, end)))
|
|
|
|
{
|
|
|
|
if (token->type == TOKEN_TYPE_EOF)
|
|
|
|
break;
|
|
|
|
|
|
|
|
// Variables in script cannot be initialized by assignment.
|
|
|
|
// Skip until value assignment expression ends.
|
|
|
|
if (token->type == TOKEN_TYPE_EQUAL_MARK)
|
|
|
|
{
|
|
|
|
while ((tmp = next_token(&begin, end)))
|
|
|
|
{
|
|
|
|
if ((tmp->type == TOKEN_TYPE_COMMA) ||
|
|
|
|
(tmp->type == TOKEN_TYPE_SEMICOLON))
|
|
|
|
{
|
2018-04-19 21:10:58 -07:00
|
|
|
if (token->str) free(token->str);
|
|
|
|
free(token);
|
|
|
|
|
2017-10-27 11:49:02 -07:00
|
|
|
token = tmp;
|
2018-05-10 21:49:23 -07:00
|
|
|
tmp = NULL;
|
2017-10-27 11:49:02 -07:00
|
|
|
break;
|
|
|
|
}
|
2018-04-08 19:14:07 -07:00
|
|
|
|
|
|
|
if (tmp->str) free(tmp->str);
|
|
|
|
free(tmp);
|
2017-10-27 11:49:02 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (token->type)
|
|
|
|
{
|
|
|
|
case TOKEN_TYPE_COLON:
|
|
|
|
if (!sym)
|
|
|
|
sym = mem_alloc(SZ(Code_Symbol));
|
2017-10-31 00:27:38 -07:00
|
|
|
sym->tag = eina_array_pop(name_stack);
|
2017-10-27 11:49:02 -07:00
|
|
|
break;
|
2018-02-26 13:15:30 -08:00
|
|
|
|
2017-10-27 11:49:02 -07:00
|
|
|
case TOKEN_TYPE_SEMICOLON:
|
2017-10-31 00:27:38 -07:00
|
|
|
if (eina_array_count(name_stack))
|
2017-10-27 11:49:02 -07:00
|
|
|
{
|
|
|
|
if (!sym)
|
|
|
|
sym = mem_alloc(SZ(Code_Symbol));
|
2017-10-31 00:27:38 -07:00
|
|
|
sym->name = eina_array_pop(name_stack);
|
2017-10-27 11:49:02 -07:00
|
|
|
sym->is_public = is_public;
|
|
|
|
code->vars = eina_list_append(code->vars, sym);
|
|
|
|
sym = NULL;
|
|
|
|
}
|
|
|
|
is_public = EINA_FALSE;
|
|
|
|
break;
|
2018-02-26 13:15:30 -08:00
|
|
|
|
2017-10-27 11:49:02 -07:00
|
|
|
case TOKEN_TYPE_COMMA:
|
|
|
|
if (!sym)
|
|
|
|
sym = mem_alloc(SZ(Code_Symbol));
|
2017-10-31 00:27:38 -07:00
|
|
|
sym->name = eina_array_pop(name_stack);
|
2017-10-27 11:49:02 -07:00
|
|
|
if (is_args)
|
|
|
|
func->args = eina_list_append(func->args, sym);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sym->is_public = is_public;
|
|
|
|
code->vars = eina_list_append(code->vars, sym);
|
|
|
|
}
|
|
|
|
sym = NULL;
|
|
|
|
break;
|
2018-02-26 13:15:30 -08:00
|
|
|
|
2017-10-27 11:49:02 -07:00
|
|
|
case TOKEN_TYPE_PARENS:
|
|
|
|
is_args = !is_args;
|
|
|
|
if (is_args)
|
|
|
|
{
|
|
|
|
if (!sym)
|
|
|
|
func = mem_alloc(SZ(Code_Symbol));
|
|
|
|
else
|
|
|
|
{
|
|
|
|
func = sym;
|
|
|
|
sym = NULL;
|
|
|
|
}
|
2017-10-31 00:27:38 -07:00
|
|
|
func->name = eina_array_pop(name_stack);
|
2017-10-27 11:49:02 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-10-31 00:27:38 -07:00
|
|
|
if (eina_array_count(name_stack))
|
2017-10-27 11:49:02 -07:00
|
|
|
{
|
|
|
|
if (!sym)
|
|
|
|
sym = mem_alloc(SZ(Code_Symbol));
|
2017-10-31 00:27:38 -07:00
|
|
|
sym->name = eina_array_pop(name_stack);
|
2017-10-27 11:49:02 -07:00
|
|
|
func->args = eina_list_append(func->args, sym);
|
|
|
|
}
|
|
|
|
sym = func;
|
|
|
|
}
|
|
|
|
break;
|
2018-02-26 13:15:30 -08:00
|
|
|
|
2017-10-27 11:49:02 -07:00
|
|
|
case TOKEN_TYPE_BRACES:
|
|
|
|
depth = 1;
|
|
|
|
body = begin;
|
|
|
|
while ((tmp = next_token(&begin, end)))
|
|
|
|
{
|
|
|
|
if (tmp->type == TOKEN_TYPE_BRACES)
|
|
|
|
{
|
|
|
|
switch (tmp->str[0])
|
|
|
|
{
|
|
|
|
case '{':
|
|
|
|
depth++;
|
|
|
|
break;
|
2018-02-26 13:15:30 -08:00
|
|
|
|
2017-10-27 11:49:02 -07:00
|
|
|
case '}':
|
|
|
|
depth--;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!depth)
|
|
|
|
break;
|
2018-04-08 19:14:07 -07:00
|
|
|
|
|
|
|
if (tmp->str) free(tmp->str);
|
|
|
|
free(tmp);
|
2017-10-27 11:49:02 -07:00
|
|
|
}
|
fix various trivial null derefs
Summary:
CIDs 1401081, 1401044, 1400983, 1400960, 1400927, 1400799, 1396946, 1396944,
1383851, 1383847, 1382211, 1379921, 1379921
Reviewers: cedric
Reviewed By: cedric
Subscribers: #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D10452
2019-10-18 10:30:10 -07:00
|
|
|
if (!sym) break;
|
2017-10-27 11:49:02 -07:00
|
|
|
if ((begin - 1) > body)
|
|
|
|
{
|
|
|
|
sym->body = mem_alloc(sizeof(char) * (begin - body - 1));
|
|
|
|
strncpy(sym->body, body, (begin - body - 2));
|
|
|
|
}
|
|
|
|
sym->is_public = is_public;
|
|
|
|
code->func = eina_list_append(code->func, sym);
|
|
|
|
sym = NULL;
|
|
|
|
is_public = EINA_FALSE;
|
|
|
|
break;
|
2018-02-26 13:15:30 -08:00
|
|
|
|
2017-10-27 11:49:02 -07:00
|
|
|
case TOKEN_TYPE_PUBLIC:
|
|
|
|
is_public = EINA_TRUE;
|
|
|
|
break;
|
2018-02-26 13:15:30 -08:00
|
|
|
|
2017-10-27 11:49:02 -07:00
|
|
|
case TOKEN_TYPE_IDENTIFIER:
|
2017-10-31 00:27:38 -07:00
|
|
|
eina_array_push(name_stack, token->str);
|
2017-10-27 11:49:02 -07:00
|
|
|
token->str = NULL;
|
|
|
|
break;
|
2018-02-26 13:15:30 -08:00
|
|
|
|
2017-10-27 11:49:02 -07:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (token->str)
|
|
|
|
free(token->str);
|
|
|
|
free(token);
|
2018-04-08 19:14:07 -07:00
|
|
|
|
|
|
|
if (tmp)
|
|
|
|
{
|
|
|
|
if (tmp->str) free(tmp->str);
|
|
|
|
free(tmp);
|
2018-05-10 18:44:55 -07:00
|
|
|
tmp = NULL;
|
2018-04-08 19:14:07 -07:00
|
|
|
}
|
2017-10-27 11:49:02 -07:00
|
|
|
}
|
|
|
|
|
2018-04-08 19:29:41 -07:00
|
|
|
if (token)
|
|
|
|
{
|
|
|
|
if (token->str)
|
|
|
|
free(token->str);
|
|
|
|
free(token);
|
|
|
|
}
|
|
|
|
|
2017-10-31 00:27:38 -07:00
|
|
|
eina_array_free(name_stack);
|
2017-10-27 11:49:02 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static Token *
|
|
|
|
next_token(char **begin, char *end)
|
|
|
|
{
|
|
|
|
char buf[PATH_MAX] = { 0, };
|
|
|
|
char *src;
|
|
|
|
int index;
|
|
|
|
Token *token;
|
|
|
|
Eina_Bool parsed = EINA_FALSE;
|
|
|
|
|
|
|
|
if (!begin || (*begin >= end))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
token = mem_alloc(SZ(Token));
|
|
|
|
token->type = TOKEN_TYPE_INVALID;
|
|
|
|
|
|
|
|
src = *begin - 1;
|
|
|
|
index = 0;
|
|
|
|
|
|
|
|
while (++src < end)
|
|
|
|
{
|
|
|
|
char ch = *src;
|
|
|
|
|
|
|
|
switch (ch)
|
|
|
|
{
|
|
|
|
case ' ':
|
|
|
|
case '\t':
|
|
|
|
case '\n':
|
2018-02-26 13:15:30 -08:00
|
|
|
if (index > 0)
|
|
|
|
parsed = EINA_TRUE;
|
|
|
|
break;
|
|
|
|
|
2017-10-27 11:49:02 -07:00
|
|
|
case ':':
|
|
|
|
case ';':
|
|
|
|
case ',':
|
|
|
|
case '(':
|
|
|
|
case ')':
|
|
|
|
case '{':
|
|
|
|
case '}':
|
|
|
|
case '=':
|
2018-02-26 13:15:30 -08:00
|
|
|
if (!index)
|
|
|
|
{
|
|
|
|
buf[index++] = ch;
|
|
|
|
src++;
|
|
|
|
}
|
|
|
|
goto exit;
|
|
|
|
|
2017-10-27 11:49:02 -07:00
|
|
|
default:
|
2018-02-26 13:15:30 -08:00
|
|
|
if (parsed)
|
|
|
|
goto exit;
|
|
|
|
buf[index++] = ch;
|
|
|
|
break;
|
2017-10-27 11:49:02 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
exit:
|
|
|
|
switch (buf[0])
|
|
|
|
{
|
2018-02-26 13:15:30 -08:00
|
|
|
case ':':
|
|
|
|
token->type = TOKEN_TYPE_COLON;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ';':
|
|
|
|
token->type = TOKEN_TYPE_SEMICOLON;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ',':
|
|
|
|
token->type = TOKEN_TYPE_COMMA;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '(':
|
|
|
|
case ')':
|
|
|
|
token->type = TOKEN_TYPE_PARENS;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '{':
|
|
|
|
case '}':
|
|
|
|
token->type = TOKEN_TYPE_BRACES;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '=':
|
|
|
|
token->type = TOKEN_TYPE_EQUAL_MARK;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '\0':
|
|
|
|
token->type = TOKEN_TYPE_EOF;
|
|
|
|
break;
|
2017-10-27 11:49:02 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (token->type < 0)
|
|
|
|
{
|
|
|
|
if (!strcmp(buf, "public"))
|
|
|
|
token->type = TOKEN_TYPE_PUBLIC;
|
|
|
|
else
|
|
|
|
token->type = TOKEN_TYPE_IDENTIFIER;
|
|
|
|
}
|
|
|
|
|
|
|
|
*begin = src;
|
|
|
|
token->str = strdup(buf);
|
|
|
|
return token;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_push_symbol(Eina_List **total, Code_Symbol *sym, Edje_Part_Collection *pc)
|
|
|
|
{
|
|
|
|
Eina_List *list, *l;
|
|
|
|
Code_Symbol *sym2;
|
|
|
|
|
|
|
|
list = *total;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(list, l, sym2)
|
|
|
|
{
|
|
|
|
if (!strcmp(sym2->name, sym->name))
|
|
|
|
{
|
|
|
|
WRN("Symbols in group \"%s\" have same name \"%s\". Latter defined "
|
2018-06-21 03:15:47 -07:00
|
|
|
"will shadow former one.", pc->part, sym->name);
|
2017-10-27 11:49:02 -07:00
|
|
|
list = eina_list_remove(list, sym2);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
list = eina_list_append(list, sym);
|
|
|
|
*total = list;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
script_rewrite(Code *code)
|
|
|
|
{
|
|
|
|
Edje_Part_Collection *pc;
|
|
|
|
Edje_Part_Collection_Parser *pcp;
|
|
|
|
Code *base;
|
|
|
|
Eina_List *l, *ll;
|
|
|
|
int id, count;
|
|
|
|
Eina_Strbuf *buf;
|
|
|
|
Eina_List *vars = NULL;
|
|
|
|
Eina_List *func = NULL;
|
|
|
|
#ifdef MESSAGE_OVERRIDE
|
|
|
|
Eina_List *message = NULL;
|
|
|
|
#endif
|
|
|
|
Code_Symbol *sym, *arg;
|
|
|
|
|
|
|
|
code_parse(code);
|
|
|
|
|
|
|
|
id = eina_list_data_idx(codes, code);
|
|
|
|
pc = eina_list_nth(edje_collections, id);
|
|
|
|
pcp = (Edje_Part_Collection_Parser *)pc;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(pcp->base_codes, l, base)
|
|
|
|
{
|
|
|
|
EINA_LIST_FOREACH(base->vars, ll, sym)
|
|
|
|
_push_symbol(&vars, sym, pc);
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(base->func, ll, sym)
|
|
|
|
{
|
|
|
|
#ifndef MESSAGE_OVERRIDE
|
|
|
|
_push_symbol(&func, sym, pc);
|
|
|
|
#else
|
|
|
|
if (strcmp(sym->name, "message"))
|
|
|
|
_push_symbol(&func, sym, pc);
|
|
|
|
else
|
|
|
|
message = eina_list_append(message, sym);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(code->vars, l, sym)
|
|
|
|
_push_symbol(&vars, sym, pc);
|
|
|
|
EINA_LIST_FOREACH(code->func, l, sym)
|
|
|
|
{
|
|
|
|
#ifndef MESSAGE_OVERRIDE
|
|
|
|
_push_symbol(&func, sym, pc);
|
|
|
|
#else
|
|
|
|
if (strcmp(sym->name, "message"))
|
|
|
|
_push_symbol(&func, sym, pc);
|
|
|
|
else
|
|
|
|
message = eina_list_append(message, sym);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
buf = eina_strbuf_new();
|
|
|
|
|
|
|
|
if (vars)
|
|
|
|
{
|
|
|
|
count = 0;
|
|
|
|
EINA_LIST_FOREACH(vars, l, sym)
|
|
|
|
{
|
|
|
|
if (!sym->is_public) continue;
|
|
|
|
|
|
|
|
if (count++)
|
|
|
|
eina_strbuf_append(buf, ", ");
|
|
|
|
else
|
|
|
|
eina_strbuf_append(buf, "public ");
|
|
|
|
|
|
|
|
if (sym->tag)
|
|
|
|
eina_strbuf_append_printf(buf, "%s:", sym->tag);
|
|
|
|
eina_strbuf_append(buf, sym->name);
|
|
|
|
}
|
|
|
|
if (count)
|
|
|
|
eina_strbuf_append(buf, ";\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (func)
|
|
|
|
{
|
|
|
|
EINA_LIST_FOREACH(func, l, sym)
|
|
|
|
{
|
|
|
|
eina_strbuf_append(buf, "\n");
|
|
|
|
if (sym->is_public)
|
|
|
|
eina_strbuf_append(buf, "public ");
|
|
|
|
|
|
|
|
if (sym->tag)
|
|
|
|
eina_strbuf_append_printf(buf, "%s:", sym->tag);
|
|
|
|
eina_strbuf_append_printf(buf, "%s(", sym->name);
|
|
|
|
|
|
|
|
count = 0;
|
|
|
|
EINA_LIST_FOREACH(sym->args, ll, arg)
|
|
|
|
{
|
|
|
|
if (count++)
|
|
|
|
eina_strbuf_append(buf, ", ");
|
|
|
|
|
|
|
|
if (arg->tag)
|
|
|
|
eina_strbuf_append_printf(buf, "%s:", arg->tag);
|
|
|
|
eina_strbuf_append(buf, arg->name);
|
|
|
|
}
|
|
|
|
eina_strbuf_append(buf, ") {");
|
|
|
|
if (sym->body)
|
|
|
|
{
|
|
|
|
eina_strbuf_append(buf, sym->body);
|
|
|
|
eina_strbuf_rtrim(buf);
|
|
|
|
}
|
|
|
|
eina_strbuf_append(buf, "\n}\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef MESSAGE_OVERRIDE
|
|
|
|
if (message)
|
|
|
|
{
|
|
|
|
eina_strbuf_append(buf, "\npublic message(Msg_Type:type, id, ...) {");
|
|
|
|
EINA_LIST_FOREACH(message, l, sym)
|
|
|
|
{
|
|
|
|
eina_strbuf_append(buf, sym->body);
|
|
|
|
eina_strbuf_rtrim(buf);
|
|
|
|
eina_strbuf_append(buf, "\n");
|
|
|
|
}
|
|
|
|
eina_strbuf_append(buf, "}\n");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
code->shared = eina_strbuf_string_steal(buf);
|
|
|
|
code->original = strdup(code->shared);
|
|
|
|
eina_strbuf_free(buf);
|
|
|
|
|
2017-11-21 06:48:28 -08:00
|
|
|
eina_list_free(code->vars);
|
|
|
|
eina_list_free(code->func);
|
|
|
|
|
|
|
|
code->vars = vars;
|
|
|
|
code->func = func;
|
2017-10-27 11:49:02 -07:00
|
|
|
}
|
2018-02-26 13:15:30 -08:00
|
|
|
|