edje_cc now supports "lazEDC", a more concise version of EDC
authorMike Blumenkrantz <zmike@samsung.com>
Fri, 21 Mar 2014 20:58:24 +0000 (16:58 -0400)
committerMike Blumenkrantz <zmike@samsung.com>
Fri, 25 Apr 2014 14:52:14 +0000 (10:52 -0400)
in today's modern world of fast-paced, HTML5-driven, C++-riddled
development, nobody wants to spend hours typing out long words like
"description" or "mouse_events" or "name". there's no time for it
and certainly nobody is going to allocate budget for this sort of
keyboard-related nonsense.
enter lazEDC: the solution for edje-loving keyboard jockeys everywhere.
by breaking the parser of edje_cc with the strength of 10 frenchmen,
new, shorter keywords such as "nomouse" can be used in place of lengthy,
rambling statements like "mouse_events: 0", and things like

part { name: "clip"; type: RECT; description { state: "default" 0.0; }}

can now be written as

rect { "clip"; }

with the exact same effect.

initial tests show that complex and terrible edc files such as the infamous
"genlist.edc" can be reduced in size by over 15% using these new features.

see edcref for docs, and genlist.edc for examples

@feature

@awesome

src/bin/edje/edje_cc.h
src/bin/edje/edje_cc_handlers.c
src/bin/edje/edje_cc_parse.c

index 273a696..f9f362b 100644 (file)
@@ -196,8 +196,12 @@ void    check_arg_count(int n);
 void    check_min_arg_count(int n);
 
 int     object_handler_num(void);
+int     object_handler_short_num(void);
 int     statement_handler_num(void);
+int     statement_handler_short_num(void);
+int     statement_handler_short_single_num(void);
 int     nested_handler_num(void);
+int     nested_handler_short_num(void);
 
 void    reorder_parts(void);
 void    source_edd(void);
@@ -215,7 +219,9 @@ void    using_file(const char *filename, const char type);
 
 void    error_and_abort(Eet_File *ef, const char *fmt, ...);
 
-
+void stack_push_quick(const char *str);
+void stack_pop_quick(Eina_Bool check_last, Eina_Bool do_free);
+Eina_Bool edje_cc_handlers_wildcard(void);
 void edje_cc_handlers_hierarchy_alloc(void);
 void edje_cc_handlers_hierarchy_free(void);
 void edje_cc_handlers_pop_notify(const char *token);
@@ -252,10 +258,15 @@ extern Eina_List             *codes;
 extern Eina_List             *defines;
 extern Eina_List             *aliases;
 extern New_Object_Handler     object_handlers[];
+extern New_Object_Handler     object_handlers_short[];
 extern New_Statement_Handler  statement_handlers[];
+extern New_Statement_Handler  statement_handlers_short[];
+extern New_Statement_Handler  statement_handlers_short_single[];
 extern New_Nested_Handler     nested_handlers[];
+extern New_Nested_Handler     nested_handlers_short[];
 extern int                    compress_mode;
 extern int                    threads;
 extern int                   anotate;
+extern Eina_Bool current_group_inherit;
 
 #endif
index b285029..0b865a8 100644 (file)
  *        </ul>
  *      </ul>
  *    </ul>
+ *    <li>@ref sec_lazedc "LazEDC"</li>
+ *    <ul>
+ *       <li>@ref sec_lazedc_synonyms "Synonyms"</li>
+ *       <li>@ref sec_lazedc_shorthand "Shorthand"</li>
+ *    </ul>
  * </ul>
  *
  * @author Andres Blanc (dresb) andresblanc@gmail.com
@@ -269,6 +274,7 @@ static void st_collections_group_parts_part_table_items_item_position(void);
 static void st_collections_group_parts_part_table_items_item_span(void);
 
 static void ob_collections_group_parts_part_description(void);
+static void ob_collections_group_parts_part_desc(void);
 static void st_collections_group_parts_part_description_inherit(void);
 static void st_collections_group_parts_part_description_source(void);
 static void st_collections_group_parts_part_description_state(void);
@@ -410,6 +416,21 @@ static void st_collections_group_physics_world_z(void);
 static void st_collections_group_physics_world_depth(void);
 #endif
 
+/* short */
+static void st_collections_group_parts_part_precise(void);
+static void st_collections_group_parts_part_imprecise(void);
+static void st_collections_group_parts_part_mouse(void);
+static void st_collections_group_parts_part_nomouse(void);
+static void st_collections_group_parts_part_repeat(void);
+static void st_collections_group_parts_part_norepeat(void);
+static void st_collections_group_parts_part_description_vis(void);
+static void st_collections_group_parts_part_description_hid(void);
+static void ob_collections_group_parts_part_short(void);
+
+static void st_collections_group_mouse(void);
+static void st_collections_group_nomouse(void);
+static void st_collections_group_broadcast(void);
+static void st_collections_group_nobroadcast(void);
 /*****/
 
 
@@ -706,6 +727,157 @@ New_Statement_Handler statement_handlers[] =
      PROGRAM_STATEMENTS("collections.group")
 };
 
+/**
+   @edcsubsection{lazedc,LazEDC}
+ */
+
+/**
+    @page edcref
+    @block
+        LazEDC
+    @context
+        ..
+        collections.group { "test";
+           parts {
+              rect { "clip"; }
+              rect { "test"; nomouse; repeat; precise;
+                 clip: "clip";
+                 desc { "default";
+                    color: 255 0 0 255;
+                    rel2.relative: 0.5 1;
+                 }
+              }
+              rect { "test2"; inherit: "test";
+                 clip: "clip";
+                 desc { "default";
+                    rel1.relative: 0.5 0;
+                    rel2.relative: 1 1;
+                 }
+                 desc { "t2"; inherit: "default";
+                    color: 0 255 0 255;
+                 }
+                 desc { "t3"; inherit: "default";
+                    color: 0 0 255 255;
+                 }
+              }
+              program { signal: "load"; name: "start";
+                 sequence {
+                    action: STATE_SET "t2";
+                    target: "test2";
+                    transition: LINEAR 0.6;
+                    in: 0.5 0;
+                    action: STATE_SET "t3";
+                    target: "test2";
+                    transition: LINEAR 0.3;
+                    name: "del";
+                 }
+              }
+           }
+        }
+        ..
+    @description
+        LazEDC is an advanced form of EDC which allows the developer to
+        leave out or shorten various forms. Parts can be created by using
+        their type names, and the "name" and "state" keywords can be omitted entirely.
+        Additionally, default description blocks will be automatically created with default
+        values even if the description isn't explicitly specified.
+        @note Failing to use quotes for block names will trigger syntax errors
+        if a block name is the same as an existing EDC keyword.
+    @since 1.10
+    @endblock
+*/
+
+/**
+   @edcsubsection{lazedc_synonyms,Synonyms}
+ */
+
+/**
+    @page edcref
+    @block
+        Synonyms
+    @context
+    group {
+       parts {
+          part {
+             before -> insert_before
+             after -> insert_after
+             ignore -> ignore_flags
+             pointer -> pointer_mode
+             alt_font -> use_alternate_font_metrics
+             clip -> clip_to
+          }
+       }
+    }
+
+    @description
+        These statements on the left are identical to their original keywords on the right.
+    @since 1.10
+    @endblock
+*/
+
+
+New_Statement_Handler statement_handlers_short[] =
+{
+     {"collections.group.parts.part.before", st_collections_group_parts_part_insert_before},
+     {"collections.group.parts.part.after", st_collections_group_parts_part_insert_after},
+     {"collections.group.parts.part.ignore", st_collections_group_parts_part_ignore_flags},
+     {"collections.group.parts.part.pointer", st_collections_group_parts_part_pointer_mode},
+     {"collections.group.parts.part.alt_font", st_collections_group_parts_part_use_alternate_font_metrics},
+     {"collections.group.parts.part.clip", st_collections_group_parts_part_clip_to_id},
+};
+
+/**
+   @edcsubsection{lazedc_shorthand,Shorthand}
+ */
+
+/**
+    @page edcref
+    @block
+        Shorthand
+    @context
+    group {
+       broadcast; -> broadcast_signal: 1;
+       nobroadcast; -> broadcast_signal: 0;
+       mouse; -> mouse_events: 1;
+       nomouse; -> mouse_events: 0;
+       parts {
+          part {
+             mouse; -> mouse_events: 1;
+             nomouse; -> mouse_events: 0;
+             repeat; -> repeat_events: 1;
+             norepeat; -> repeat_events: 0;
+             precise; -> precise_is_inside: 1;
+             imprecise; -> precise_is_inside: 0;
+             desc {
+                vis; -> visible: 1;
+                hid; -> visible: 0;
+             }
+          }
+       }
+    }
+
+    @description
+        These statements on the left have the same meaning as statements on the right,
+        but they are shorter.
+    @since 1.10
+    @endblock
+*/
+New_Statement_Handler statement_handlers_short_single[] =
+{
+     {"collections.group.parts.part.mouse", st_collections_group_parts_part_mouse},
+     {"collections.group.parts.part.nomouse", st_collections_group_parts_part_nomouse},
+     {"collections.group.parts.part.repeat", st_collections_group_parts_part_repeat},
+     {"collections.group.parts.part.norepeat", st_collections_group_parts_part_norepeat},
+     {"collections.group.parts.part.precise", st_collections_group_parts_part_precise},
+     {"collections.group.parts.part.imprecise", st_collections_group_parts_part_imprecise},
+     {"collections.group.parts.part.description.vis", st_collections_group_parts_part_description_vis},
+     {"collections.group.parts.part.description.hid", st_collections_group_parts_part_description_hid},
+     {"collections.group.mouse", st_collections_group_mouse},
+     {"collections.group.nomouse", st_collections_group_nomouse},
+     {"collections.group.broadcast", st_collections_group_broadcast},
+     {"collections.group.nobroadcast", st_collections_group_nobroadcast},
+};
+
 #define PROGRAM_OBJECTS(PREFIX) \
      {PREFIX".program", ob_collections_group_programs_program}, /* dup */ \
      {PREFIX".program.script", ob_collections_group_programs_program_script}, /* dup */ \
@@ -847,10 +1019,74 @@ New_Object_Handler object_handlers[] =
      PROGRAM_OBJECTS("collections.group")
 };
 
+/**
+   @edcsubsection{lazedc_blocks,Blocks}
+ */
+
+/**
+    @page edcref
+    @block
+        Blocks
+    @context
+    parts {
+       rect{}
+       text{}
+       image{}
+       swallow{}
+       textblock{}
+       group{}
+       box{}
+       table{}
+       external{}
+       proxy{}
+       spacer{}
+       part {
+          desc {
+          }
+       }
+    }
+
+    @description
+        Lowercase part types can be specified as blocks with the same effect as part { type: TYPE; }
+        The "description" block can also be shortened to "desc".
+        
+    @since 1.10
+    @endblock
+*/
+New_Object_Handler object_handlers_short[] =
+{
+     {"collections.group.parts.rect", ob_collections_group_parts_part_short},
+     {"collections.group.parts.text", ob_collections_group_parts_part_short},
+     {"collections.group.parts.image", ob_collections_group_parts_part_short},
+     {"collections.group.parts.swallow", ob_collections_group_parts_part_short},
+     {"collections.group.parts.textblock", ob_collections_group_parts_part_short},
+     {"collections.group.parts.group", ob_collections_group_parts_part_short},
+     {"collections.group.parts.box", ob_collections_group_parts_part_short},
+     {"collections.group.parts.table", ob_collections_group_parts_part_short},
+     {"collections.group.parts.external", ob_collections_group_parts_part_short},
+     {"collections.group.parts.proxy", ob_collections_group_parts_part_short},
+     {"collections.group.parts.spacer", ob_collections_group_parts_part_short},
+     {"collections.group.parts.part.desc", ob_collections_group_parts_part_desc},
+};
+
 New_Nested_Handler nested_handlers[] = {
      {"collections.group.parts", "part", NULL, edje_cc_handlers_hierarchy_pop }
 };
 
+New_Nested_Handler nested_handlers_short[] = {
+     {"collections.group.parts", "rect", NULL, edje_cc_handlers_hierarchy_pop },
+     {"collections.group.parts", "text", NULL, edje_cc_handlers_hierarchy_pop },
+     {"collections.group.parts", "image", NULL, edje_cc_handlers_hierarchy_pop },
+     {"collections.group.parts", "swallow", NULL, edje_cc_handlers_hierarchy_pop },
+     {"collections.group.parts", "textblock", NULL, edje_cc_handlers_hierarchy_pop },
+     {"collections.group.parts", "group", NULL, edje_cc_handlers_hierarchy_pop },
+     {"collections.group.parts", "box", NULL, edje_cc_handlers_hierarchy_pop },
+     {"collections.group.parts", "table", NULL, edje_cc_handlers_hierarchy_pop },
+     {"collections.group.parts", "external", NULL, edje_cc_handlers_hierarchy_pop },
+     {"collections.group.parts", "proxy", NULL, edje_cc_handlers_hierarchy_pop },
+     {"collections.group.parts", "spacer", NULL, edje_cc_handlers_hierarchy_pop },
+};
+
 /*****/
 
 int
@@ -860,17 +1096,41 @@ object_handler_num(void)
 }
 
 int
+object_handler_short_num(void)
+{
+   return sizeof(object_handlers_short) / sizeof (New_Object_Handler);
+}
+
+int
 statement_handler_num(void)
 {
    return sizeof(statement_handlers) / sizeof (New_Object_Handler);
 }
 
 int
+statement_handler_short_num(void)
+{
+   return sizeof(statement_handlers_short) / sizeof (New_Object_Handler);
+}
+
+int
+statement_handler_short_single_num(void)
+{
+   return sizeof(statement_handlers_short_single) / sizeof (New_Object_Handler);
+}
+
+int
 nested_handler_num(void)
 {
    return sizeof(nested_handlers) / sizeof (New_Nested_Handler);
 }
 
+int
+nested_handler_short_num(void)
+{
+   return sizeof(nested_handlers_short) / sizeof (New_Nested_Handler);
+}
+
 static void
 _edje_part_description_fill(Edje_Part_Description_Spec_Fill *fill)
 {
@@ -2036,6 +2296,26 @@ ob_styles_style(void)
    edje_file->styles = eina_list_append(edje_file->styles, stl);
 }
 
+static void
+_style_name(char *name)
+{
+   Edje_Style *stl, *tstl;
+   Eina_List *l;
+
+   stl = eina_list_last_data_get(edje_file->styles);
+   free(stl->name);
+   stl->name = name;
+   EINA_LIST_FOREACH(edje_file->styles, l, tstl)
+     {
+        if (stl->name && tstl->name && (stl != tstl) && (!strcmp(stl->name, tstl->name)))
+          {
+             ERR("parse error %s:%i. There is already a style named \"%s\"",
+          file_in, line - 1, stl->name);
+             exit(-1);
+          }
+     }
+}
+
 /**
     @page edcref
     @property
@@ -2049,20 +2329,7 @@ ob_styles_style(void)
 static void
 st_styles_style_name(void)
 {
-   Edje_Style *stl, *tstl;
-   Eina_List *l;
-
-   stl = eina_list_data_get(eina_list_last(edje_file->styles));
-   stl->name = parse_str(0);
-   EINA_LIST_FOREACH(edje_file->styles, l, tstl)
-     {
-       if (stl->name && tstl->name && (stl != tstl) && (!strcmp(stl->name, tstl->name)))
-         {
-            ERR("parse error %s:%i. There is already a style named \"%s\"",
-                file_in, line - 1, stl->name);
-            exit(-1);
-         }
-     }
+   _style_name(parse_str(0));
 }
 
 /**
@@ -2534,6 +2801,10 @@ ob_collections_group(void)
         ERR("A collection without a name was detected, that's not allowed.");
         exit(-1);
      }
+   current_program = NULL;
+   current_part = NULL;
+   current_desc = NULL;
+
    current_group_inherit = EINA_FALSE;
 
    current_de = mem_alloc(SZ(Edje_Part_Collection_Directory_Entry));
@@ -2564,35 +2835,20 @@ ob_collections_group(void)
 #endif
 }
 
-/**
-    @page edcref
-    @property
-        name
-    @parameters
-        [group name]
-    @effect
-        The name that will be used by the application to load the resulting
-        Edje object and to identify the group to swallow in a GROUP part. If a
-        group with the same name exists already it will be completely overriden
-        by the new group.
-    @endproperty
-*/
 static void
-st_collections_group_name(void)
+_group_name(char *name)
 {
    Edje_Part_Collection_Directory_Entry *alias;
    Edje_Part_Collection_Directory_Entry *older;
    Edje_Part_Collection *current_pc;
    Eina_List *l = NULL;
 
-   check_arg_count(1);
-
    current_pc = eina_list_data_get(eina_list_last(edje_collections));
 
    if (current_de->entry)
      goto double_named_group;
 
-   current_de->entry = parse_str(0);
+   current_de->entry = name;
    current_pc->part = current_de->entry;
 
    older = eina_hash_find(edje_file->collection, current_de->entry);
@@ -2620,6 +2876,26 @@ double_named_group:
    exit(-1);
 }
 
+/**
+    @page edcref
+    @property
+        name
+    @parameters
+        [group name]
+    @effect
+        The name that will be used by the application to load the resulting
+        Edje object and to identify the group to swallow in a GROUP part. If a
+        group with the same name exists already it will be completely overriden
+        by the new group.
+    @endproperty
+*/
+static void
+st_collections_group_name(void)
+{
+   check_arg_count(1);
+   _group_name(parse_str(0));
+}
+
 typedef struct _Edje_List_Foreach_Data Edje_List_Foreach_Data;
 struct _Edje_List_Foreach_Data
 {
@@ -2734,6 +3010,7 @@ _part_copy(Edje_Part *ep, Edje_Part *ep2)
    ob_collections_group_parts_part_description();
    ed = ep->default_desc;
    parent_desc = ed2 = ep2->default_desc;
+   free((void*)ed->state.name);
    ed->state.name = STRDUP(ed2->state.name);
    ed->state.value = ed2->state.value;
    st_collections_group_parts_part_description_inherit();
@@ -3133,6 +3410,28 @@ st_collections_group_broadcast_signal(void)
    pc->broadcast_signal = parse_bool(0);
 }
 
+static void
+st_collections_group_broadcast(void)
+{
+   Edje_Part_Collection *pc;
+
+   check_arg_count(0);
+
+   pc = eina_list_data_get(eina_list_last(edje_collections));
+   pc->broadcast_signal = 1;
+}
+
+static void
+st_collections_group_nobroadcast(void)
+{
+   Edje_Part_Collection *pc;
+
+   check_arg_count(0);
+
+   pc = eina_list_data_get(eina_list_last(edje_collections));
+   pc->broadcast_signal = 0;
+}
+
 /**
    @edcsubsection{collections_group_script,Script}
  */
@@ -3302,6 +3601,28 @@ st_collections_group_mouse_events(void)
    pcp->default_mouse_events = parse_bool(0);
 }
 
+static void
+st_collections_group_mouse(void)
+{
+   Edje_Part_Collection_Parser *pcp;
+
+   check_arg_count(0);
+
+   pcp = eina_list_data_get(eina_list_last(edje_collections));
+   pcp->default_mouse_events = 1;
+}
+
+static void
+st_collections_group_nomouse(void)
+{
+   Edje_Part_Collection_Parser *pcp;
+
+   check_arg_count(0);
+
+   pcp = eina_list_data_get(eina_list_last(edje_collections));
+   pcp->default_mouse_events = 0;
+}
+
 /**
    @edcsubsection{collections_group_limits,Limits}
  */
@@ -3505,6 +3826,7 @@ edje_cc_handlers_part_make(int id)
           }
         id = pc->parts_count - 1;
      }
+
    current_part = pc->parts[id] = ep;
    pcp = (Edje_Part_Collection_Parser *)pc;
 
@@ -3539,7 +3861,45 @@ edje_cc_handlers_part_make(int id)
 }
 
 static void
-ob_collections_group_parts_part(void)
+_part_type_set(unsigned int type)
+{
+   /* handle type change of inherited part */
+   if (type != current_part->type)
+     {
+        Edje_Part_Description_Common *new, *previous;
+        Edje_Part_Collection *pc;
+        Edje_Part *ep;
+        unsigned int i;
+
+        /* we don't free old part as we don't remove all reference to them */
+        part_description_image_cleanup(current_part);
+
+        pc = eina_list_data_get(eina_list_last(edje_collections));
+        ep = current_part;
+
+        previous = ep->default_desc;
+        if (previous)
+          {
+             new = _edje_part_description_alloc(type, pc->part, ep->name);
+             memcpy(new, previous, sizeof (Edje_Part_Description_Common));
+
+             ep->default_desc = new;
+          }
+
+        for (i = 0; i < ep->other.desc_count; i++)
+          {
+             previous = ep->other.desc[i];
+             new = _edje_part_description_alloc(type, pc->part, ep->name);
+             memcpy(new, previous, sizeof (Edje_Part_Description_Common));
+             ep->other.desc[i] = new;
+          }
+     }
+
+   current_part->type = type;
+}
+
+static void
+_part_create(void)
 {
    Edje_Part *cp = current_part;  /* Save to restore on pop    */
    Edje_Part *ep = edje_cc_handlers_part_make(-1); /* This changes current_part */
@@ -3553,6 +3913,38 @@ ob_collections_group_parts_part(void)
      prnt->nested_children_count++;
 }
 
+static void
+ob_collections_group_parts_part_short(void)
+{
+   unsigned int type;
+
+   type = parse_enum(-1,
+                  "none", EDJE_PART_TYPE_NONE,
+                  "rect", EDJE_PART_TYPE_RECTANGLE,
+                  "text", EDJE_PART_TYPE_TEXT,
+                  "image", EDJE_PART_TYPE_IMAGE,
+                  "swallow", EDJE_PART_TYPE_SWALLOW,
+                  "textblock", EDJE_PART_TYPE_TEXTBLOCK,
+                  "group", EDJE_PART_TYPE_GROUP,
+                  "box", EDJE_PART_TYPE_BOX,
+                  "table", EDJE_PART_TYPE_TABLE,
+                  "external", EDJE_PART_TYPE_EXTERNAL,
+                  "proxy", EDJE_PART_TYPE_PROXY,
+                  "spacer", EDJE_PART_TYPE_SPACER,
+                  NULL);
+
+   stack_pop_quick(EINA_TRUE, EINA_TRUE);
+   stack_push_quick("part");
+   _part_create();
+   _part_type_set(type);
+}
+
+static void
+ob_collections_group_parts_part(void)
+{
+   _part_create();
+}
+
 static void *
 _part_desc_free(Edje_Part_Description_Common *ed)
 {
@@ -3627,7 +4019,7 @@ st_collections_group_parts_part_inherit(void)
         if (strcmp(pc->parts[i]->name, name)) continue;
         pname = current_part->name;
         current_part->name = NULL;
-        _part_free(current_part);
+        current_part = _part_free(current_part);
         edje_cc_handlers_part_make(id);
         _part_copy(current_part, pc->parts[i]);
         free((void*)current_part->name);
@@ -3731,6 +4123,47 @@ st_collections_group_program_remove(void)
      }
 }
 
+static Eina_Bool
+_part_name_check(void)
+{
+   unsigned int i;
+   Edje_Part_Collection *pc;
+   Edje_Part *ep = current_part;
+
+   if (!ep->name) return EINA_FALSE;
+
+   pc = eina_list_data_get(eina_list_last(edje_collections));
+
+   for (i = 0; i < (pc->parts_count - 1); i++)
+     {  /* Compare name only if did NOT updated ep from hircy pop */
+        if ((ep != pc->parts[i]) &&
+              (pc->parts[i]->name &&
+               (!strcmp(pc->parts[i]->name, ep->name))))
+          {
+             Edje_Part_Parser *epp;
+
+             epp = (Edje_Part_Parser *)pc->parts[i];
+             if (!epp->can_override)
+               {
+                  ERR("parse error %s:%i. There is already a part of the name %s",
+                      file_in, line - 1, ep->name);
+                  exit(-1);
+               }
+             else
+               {
+                  pc->parts_count--;
+                  pc->parts = realloc(pc->parts, pc->parts_count * sizeof (Edje_Part *));
+                  current_part = pc->parts[i];
+                  edje_cc_handlers_hierarchy_rename(ep, current_part);
+                  free(ep);
+                  epp->can_override = EINA_FALSE;
+                  break;
+               }
+          }
+     }
+   return EINA_TRUE;
+}
+
 /**
     @page edcref
     @property
@@ -3815,46 +4248,13 @@ st_collections_group_part_remove(void)
 static void
 st_collections_group_parts_part_name(void)
 {
-   Edje_Part_Collection *pc;
    Edje_Part *ep;
-   Edje_Part_Parser *epp;
 
    check_arg_count(1);
 
-   pc = eina_list_data_get(eina_list_last(edje_collections));
    ep = current_part;
    ep->name = parse_str(0);
-
-   if (ep->name)
-     {
-        unsigned int i;
-
-        for (i = 0; i < (pc->parts_count - 1); i++)
-          {  /* Compare name only if did NOT updated ep from hircy pop */
-             if ((ep != pc->parts[i]) &&
-                   (pc->parts[i]->name &&
-                    (!strcmp(pc->parts[i]->name, ep->name))))
-               {
-                  epp = (Edje_Part_Parser *)pc->parts[i];
-                  if (!epp->can_override)
-                    {
-                       ERR("parse error %s:%i. There is already a part of the name %s",
-                           file_in, line - 1, ep->name);
-                       exit(-1);
-                    }
-                  else
-                    {
-                       pc->parts_count--;
-                       pc->parts = realloc(pc->parts, pc->parts_count * sizeof (Edje_Part *));
-                       current_part = pc->parts[i];
-                       edje_cc_handlers_hierarchy_rename(ep, current_part);
-                       free(ep);
-                       epp->can_override = EINA_FALSE;
-                       break;
-                    }
-               }
-          }
-     }
+   _part_name_check();
 }
 
 /**
@@ -3901,39 +4301,7 @@ st_collections_group_parts_part_type(void)
                     "SPACER", EDJE_PART_TYPE_SPACER,
                      NULL);
 
-   /* handle type change of inherited part */
-   if (type != current_part->type)
-     {
-        Edje_Part_Description_Common *new, *previous;
-        Edje_Part_Collection *pc;
-        Edje_Part *ep;
-        unsigned int i;
-
-        /* we don't free old part as we don't remove all reference to them */
-        part_description_image_cleanup(current_part);
-
-        pc = eina_list_data_get(eina_list_last(edje_collections));
-        ep = current_part;
-
-        previous = ep->default_desc;
-        if (previous)
-          {
-             new = _edje_part_description_alloc(type, pc->part, ep->name);
-             memcpy(new, previous, sizeof (Edje_Part_Description_Common));
-
-             ep->default_desc = new;
-          }
-
-        for (i = 0; i < ep->other.desc_count; i++)
-          {
-             previous = ep->other.desc[i];
-             new = _edje_part_description_alloc(type, pc->part, ep->name);
-             memcpy(new, previous, sizeof (Edje_Part_Description_Common));
-             ep->other.desc[i] = new;
-          }
-     }
-
-   current_part->type = type;
+   _part_type_set(type);
 }
 
 /**
@@ -4099,6 +4467,20 @@ st_collections_group_parts_part_mouse_events(void)
    current_part->mouse_events = parse_bool(0);
 }
 
+static void
+st_collections_group_parts_part_mouse(void)
+{
+   check_arg_count(0);
+   current_part->mouse_events = 1;
+}
+
+static void
+st_collections_group_parts_part_nomouse(void)
+{
+   check_arg_count(0);
+   current_part->mouse_events = 0;
+}
+
 /**
     @page edcref
     @property
@@ -4118,6 +4500,22 @@ st_collections_group_parts_part_repeat_events(void)
    current_part->repeat_events = parse_bool(0);
 }
 
+static void
+st_collections_group_parts_part_repeat(void)
+{
+   check_arg_count(0);
+
+   current_part->repeat_events = 1;
+}
+
+static void
+st_collections_group_parts_part_norepeat(void)
+{
+   check_arg_count(0);
+
+   current_part->repeat_events = 0;
+}
+
 /**
     @page edcref
     @property
@@ -4214,6 +4612,22 @@ st_collections_group_parts_part_precise_is_inside(void)
    current_part->precise_is_inside = parse_bool(0);
 }
 
+static void
+st_collections_group_parts_part_precise(void)
+{
+   check_arg_count(0);
+
+   current_part->precise_is_inside = 1;
+}
+
+static void
+st_collections_group_parts_part_imprecise(void)
+{
+   check_arg_count(0);
+
+   current_part->precise_is_inside = 0;
+}
+
 /**
     @page edcref
     @property
@@ -5362,6 +5776,14 @@ ob_collections_group_parts_part_description(void)
    ed->minmul.h = FROM_INT(1);
 }
 
+static void
+ob_collections_group_parts_part_desc(void)
+{
+   stack_pop_quick(EINA_TRUE, EINA_TRUE);
+   stack_push_quick("description");
+   ob_collections_group_parts_part_description();
+}
+
 /**
     @page edcref
     @property
@@ -5629,6 +6051,45 @@ st_collections_group_parts_part_description_source(void)
    free(name);
 }
 
+static void
+_part_description_state_update(Edje_Part_Description_Common *ed)
+{
+   Edje_Part *ep = current_part;
+
+   if (ed == ep->default_desc) return;
+   if ((ep->default_desc->state.name && !strcmp(ed->state.name, ep->default_desc->state.name) && ed->state.value == ep->default_desc->state.value) ||
+       (!ep->default_desc->state.name && !strcmp(ed->state.name, "default") && ed->state.value == ep->default_desc->state.value))
+     {
+        if (ep->type == EDJE_PART_TYPE_IMAGE)
+          _edje_part_description_image_remove((Edje_Part_Description_Image*) ed);
+
+        free(ed);
+        ep->other.desc_count--;
+        ep->other.desc = realloc(ep->other.desc,
+                                 sizeof (Edje_Part_Description_Common*) * ep->other.desc_count);
+        current_desc = ep->default_desc;
+     }
+   else if (ep->other.desc_count)
+     {
+        unsigned int i;
+        for (i = 0; i < ep->other.desc_count - 1; ++i)
+          {
+             if (!strcmp(ed->state.name, ep->other.desc[i]->state.name) && ed->state.value == ep->other.desc[i]->state.value)
+               {
+                  if (ep->type == EDJE_PART_TYPE_IMAGE)
+                    _edje_part_description_image_remove((Edje_Part_Description_Image*) ed);
+
+                  free(ed);
+                  ep->other.desc_count--;
+                  ep->other.desc = realloc(ep->other.desc,
+                                           sizeof (Edje_Part_Description_Common*) * ep->other.desc_count);
+                  current_desc = ep->other.desc[i];
+                  break;
+               }
+          }
+     }
+}
+
 /**
     @page edcref
     @property
@@ -5671,41 +6132,7 @@ st_collections_group_parts_part_description_state(void)
      ed->state.value = 0.0;
    else
      ed->state.value = parse_float_range(1, 0.0, 1.0);
-
-   if (ed != ep->default_desc)
-     {
-        if ((ep->default_desc->state.name && !strcmp(s, ep->default_desc->state.name) && ed->state.value == ep->default_desc->state.value) ||
-            (!ep->default_desc->state.name && !strcmp(s, "default") && ed->state.value == ep->default_desc->state.value))
-          {
-             if (ep->type == EDJE_PART_TYPE_IMAGE)
-               _edje_part_description_image_remove((Edje_Part_Description_Image*) ed);
-
-             free(ed);
-             ep->other.desc_count--;
-             ep->other.desc = realloc(ep->other.desc,
-                                      sizeof (Edje_Part_Description_Common*) * ep->other.desc_count);
-             current_desc = ep->default_desc;
-          }
-        else if (ep->other.desc_count)
-          {
-             unsigned int i;
-             for (i = 0; i < ep->other.desc_count - 1; ++i)
-               {
-                  if (!strcmp(s, ep->other.desc[i]->state.name) && ed->state.value == ep->other.desc[i]->state.value)
-                    {
-                       if (ep->type == EDJE_PART_TYPE_IMAGE)
-                         _edje_part_description_image_remove((Edje_Part_Description_Image*) ed);
-
-                       free(ed);
-                       ep->other.desc_count--;
-                       ep->other.desc = realloc(ep->other.desc,
-                                                sizeof (Edje_Part_Description_Common*) * ep->other.desc_count);
-                       current_desc = ep->other.desc[i];
-                       break;
-                    }
-               }
-          }
-     }
+   _part_description_state_update(ed);
 }
 
 /**
@@ -5733,6 +6160,37 @@ st_collections_group_parts_part_description_visible(void)
 
    current_desc->visible = parse_bool(0);
 }
+
+static void
+st_collections_group_parts_part_description_vis(void)
+{
+   check_arg_count(0);
+
+   if (current_part->type == EDJE_PART_TYPE_SPACER)
+     {
+       ERR("parse error %s:%i. SPACER part can't have a visibility defined",
+           file_in, line - 1);
+       exit(-1);
+     }
+
+   current_desc->visible = 1;
+}
+
+static void
+st_collections_group_parts_part_description_hid(void)
+{
+   check_arg_count(0);
+
+   if (current_part->type == EDJE_PART_TYPE_SPACER)
+     {
+       ERR("parse error %s:%i. SPACER part can't have a visibility defined",
+           file_in, line - 1);
+       exit(-1);
+     }
+
+   current_desc->visible = 0;
+}
+
 /**
     @page edcref
     @property
@@ -9319,30 +9777,16 @@ ob_collections_group_programs_program(void)
    current_program = ep;
 }
 
-/**
-    @page edcref
-    @property
-        name
-    @parameters
-        [program name]
-    @effect
-        Symbolic name of program as a unique identifier.
-    @endproperty
-*/
 static void
-st_collections_group_programs_program_name(void)
+_program_name(char *name)
 {
    Edje_Part_Collection *pc;
    Eina_List *l;
    void *pl;
 
-   check_arg_count(1);
-
-   _program_sequence_check();
-
    pc = eina_list_data_get(eina_list_last(edje_collections));
-   if (current_program->name) free((void *)current_program->name);
-   current_program->name = parse_str(0);
+   free((void *)current_program->name);
+   current_program->name = name;
 
    _edje_program_check(current_program->name, current_program, pc->programs.fnmatch, pc->programs.fnmatch_count);
    _edje_program_check(current_program->name, current_program, pc->programs.strcmp, pc->programs.strcmp_count);
@@ -9350,9 +9794,26 @@ st_collections_group_programs_program_name(void)
    _edje_program_check(current_program->name, current_program, pc->programs.strrncmp, pc->programs.strrncmp_count);
    _edje_program_check(current_program->name, current_program, pc->programs.nocmp, pc->programs.nocmp_count);
 
-
    EINA_LIST_FOREACH(current_program_lookups, l, pl)
-     program_lookup_rename(pl, current_program->name);
+     program_lookup_rename(pl, name);
+}
+
+/**
+    @page edcref
+    @property
+        name
+    @parameters
+        [program name]
+    @effect
+        Symbolic name of program as a unique identifier.
+    @endproperty
+*/
+static void
+st_collections_group_programs_program_name(void)
+{
+   check_arg_count(1);
+   _program_sequence_check();
+   _program_name(parse_str(0));
 }
 
 /**
@@ -10402,6 +10863,9 @@ edje_cc_handlers_hierarchy_pop(void)
                      file_in, line - 1, current_de->entry, current_part->name);
                  exit(-1);
             }
+        /* auto-add default desc if it was omitted */
+        if (!current_part->default_desc)
+          ob_collections_group_parts_part_description();
      }
 
    if (info)
@@ -10416,3 +10880,66 @@ edje_cc_handlers_hierarchy_pop(void)
         free(info);
      }
 }
+
+Eina_Bool
+edje_cc_handlers_wildcard(void)
+{
+   char *token, *last;
+
+   token = eina_list_last_data_get(stack);
+   last = eina_list_data_get(eina_list_prev(eina_list_last(stack)));
+   if (!last) return EINA_FALSE;
+   if (last)
+     {
+        char *end;
+
+        end = strrchr(last, '.');
+        if (end) last = end + 1;
+     }
+   if (!last) return EINA_FALSE;
+   if (current_part)
+     {
+        if ((!strcmp(last, "part")) && (!current_part->name))
+          {
+             Eina_Bool ret;
+
+             free((void*)current_part->name);
+             current_part->name = token;
+             ret = _part_name_check();
+             if (ret)
+               stack_pop_quick(EINA_FALSE, EINA_FALSE);
+             return ret;
+          }
+        if (current_desc && ((!strcmp(last, "desc")) || (!strcmp(last, "description"))))
+          {
+             if ((!current_desc->state.name) || strcmp(current_desc->state.name, token))
+               {
+                  free((char*)current_desc->state.name);
+                  current_desc->state.name = token;
+                  _part_description_state_update(current_desc);
+               }
+             stack_pop_quick(EINA_FALSE, current_desc->state.name != token);
+             return EINA_TRUE;
+          }
+     }
+   if (current_program && ((!strcmp(last, "program")) || (!strcmp(last, "sequence"))))
+     {
+        _program_sequence_check();
+        _program_name(token);
+        stack_pop_quick(EINA_FALSE, EINA_FALSE);
+        return EINA_TRUE;
+     }
+   if (current_de && (!strcmp(last, "group")))
+     {
+        _group_name(token);
+        stack_pop_quick(EINA_FALSE, EINA_FALSE);
+        return EINA_TRUE;
+     }
+   if (edje_file->styles && (!strcmp(last, "style")))
+     {
+         _style_name(token);
+         stack_pop_quick(EINA_FALSE, EINA_FALSE);
+         return EINA_TRUE;
+     }
+   return EINA_FALSE;
+}
index 81c1b60..b640526 100644 (file)
@@ -58,8 +58,10 @@ static int strstrip(const char *in, char *out, size_t size);
 int        line = 0;
 Eina_List *stack = NULL;
 Eina_Array params;
+static int had_quote = 0;
 
 static char  file_buf[4096];
+static int   did_wildcard = 0;
 static int   verbatim = 0;
 static int   verbatim_line1 = 0;
 static int   verbatim_line2 = 0;
@@ -108,8 +110,12 @@ _parse_param_get(int n)
 }
 
 static Eina_Hash *_new_object_hash = NULL;
+static Eina_Hash *_new_object_short_hash = NULL;
 static Eina_Hash *_new_statement_hash = NULL;
+static Eina_Hash *_new_statement_short_hash = NULL;
+static Eina_Hash *_new_statement_short_single_hash = NULL;
 static Eina_Hash *_new_nested_hash = NULL;
+static Eina_Hash *_new_nested_short_hash = NULL;
 static void
 fill_object_statement_hashes(void)
 {
@@ -118,8 +124,12 @@ fill_object_statement_hashes(void)
    if (_new_object_hash) return;
 
    _new_object_hash = eina_hash_string_superfast_new(NULL);
+   _new_object_short_hash = eina_hash_string_superfast_new(NULL);
    _new_statement_hash = eina_hash_string_superfast_new(NULL);
+   _new_statement_short_hash = eina_hash_string_superfast_new(NULL);
+   _new_statement_short_single_hash = eina_hash_string_superfast_new(NULL);
    _new_nested_hash = eina_hash_string_superfast_new(NULL);
+   _new_nested_short_hash = eina_hash_string_superfast_new(NULL);
 
    n = object_handler_num();
    for (i = 0; i < n; i++)
@@ -127,18 +137,42 @@ fill_object_statement_hashes(void)
         eina_hash_direct_add(_new_object_hash, object_handlers[i].type,
                              &(object_handlers[i]));
      }
+   n = object_handler_short_num();
+   for (i = 0; i < n; i++)
+     {
+        eina_hash_direct_add(_new_object_short_hash, object_handlers_short[i].type,
+                             &(object_handlers_short[i]));
+     }
    n = statement_handler_num();
    for (i = 0; i < n; i++)
      {
         eina_hash_direct_add(_new_statement_hash, statement_handlers[i].type,
                              &(statement_handlers[i]));
      }
+   n = statement_handler_short_num();
+   for (i = 0; i < n; i++)
+     {
+        eina_hash_direct_add(_new_statement_short_hash, statement_handlers_short[i].type,
+                             &(statement_handlers_short[i]));
+     }
+   n = statement_handler_short_single_num();
+   for (i = 0; i < n; i++)
+     {
+        eina_hash_direct_add(_new_statement_short_single_hash, statement_handlers_short_single[i].type,
+                             &(statement_handlers_short_single[i]));
+     }
    n = nested_handler_num();
    for (i = 0; i < n; i++)
      {
         eina_hash_direct_add(_new_nested_hash, nested_handlers[i].type,
                              &(nested_handlers[i]));
      }
+   n = nested_handler_short_num();
+   for (i = 0; i < n; i++)
+     {
+        eina_hash_direct_add(_new_nested_short_hash, nested_handlers_short[i].type,
+                             &(nested_handlers_short[i]));
+     }
 }
 
 static void
@@ -151,20 +185,32 @@ new_object(void)
    fill_object_statement_hashes();
    id = stack_id();
    oh = eina_hash_find(_new_object_hash, id);
+   if (!oh)
+     oh = eina_hash_find(_new_object_short_hash, id);
    if (oh)
      {
         if (oh->func) oh->func();
      }
    else
      {
-        sh = eina_hash_find(_new_statement_hash, id);
-        if (!sh)
+        if (had_quote)
+          did_wildcard = edje_cc_handlers_wildcard();
+        if (!did_wildcard)
           {
-             ERR("%s:%i unhandled keyword %s",
-                 file_in, line - 1,
-                 (char *)eina_list_data_get(eina_list_last(stack)));
-             err_show();
-             exit(-1);
+             sh = eina_hash_find(_new_statement_hash, id);
+             if (!sh)
+               sh = eina_hash_find(_new_statement_short_hash, id);
+             if (!sh)
+               sh = eina_hash_find(_new_statement_short_single_hash, id);
+             if ((!sh) && (!did_wildcard) && (!had_quote) && (!edje_cc_handlers_wildcard()))
+               {
+                  ERR("%s:%i unhandled keyword %s",
+                      file_in, line - 1,
+                      (char *)eina_list_data_get(eina_list_last(stack)));
+                  err_show();
+                  exit(-1);
+               }
+             did_wildcard = !sh;
           }
      }
 }
@@ -173,10 +219,12 @@ static void
 new_statement(void)
 {
    const char *id;
-   New_Statement_Handler *sh;
+   New_Statement_Handler *sh = NULL;
    fill_object_statement_hashes();
    id = stack_id();
    sh = eina_hash_find(_new_statement_hash, id);
+   if (!sh)
+     sh = eina_hash_find(_new_statement_short_hash, id);
    if (sh)
      {
         if (sh->func) sh->func();
@@ -191,6 +239,21 @@ new_statement(void)
      }
 }
 
+static Eina_Bool
+new_statement_single(void)
+{
+   const char *id;
+   New_Statement_Handler *sh = NULL;
+   fill_object_statement_hashes();
+   id = stack_id();
+   sh = eina_hash_find(_new_statement_short_single_hash, id);
+   if (sh)
+     {
+        if (sh->func) sh->func();
+     }
+   return !!sh;
+}
+
 static char *
 perform_math (char *input)
 {
@@ -235,9 +298,10 @@ next_token(char *p, char *end, char **new_p, int *delim)
    int in_comment_ss  = 0;
    int in_comment_cpp = 0;
    int in_comment_sa  = 0;
-   int had_quote = 0;
    int is_escaped = 0;
 
+   had_quote = 0;
+
    *delim = 0;
    if (p >= end) return NULL;
    while (p < end)
@@ -444,6 +508,8 @@ stack_push(char *token)
              tmp[eina_strbuf_length_get(stack_buf) - token_length - 1] = '\0';
 
              nested = eina_hash_find(_new_nested_hash, tmp);
+             if (!nested)
+               nested = eina_hash_find(_new_nested_short_hash, tmp);
              if (nested)
                {
                   if (!strcmp(token, nested->token) &&
@@ -500,6 +566,8 @@ stack_pop(void)
           {
              hierarchy[lookup - hierarchy] = '\0';
              nested = eina_hash_find(_new_nested_hash, hierarchy);
+             if (!nested)
+               nested = eina_hash_find(_new_nested_short_hash, hierarchy);
              if (nested && nested->func_pop) nested->func_pop();
              lookup = strrchr(hierarchy + eina_strbuf_length_get(stack_buf) - tmp_length, '.');
           }
@@ -507,6 +575,8 @@ stack_pop(void)
         hierarchy[eina_strbuf_length_get(stack_buf) - 1 - tmp_length] = '\0';
 
         nested = eina_hash_find(_new_nested_hash, hierarchy);
+        if (!nested)
+          nested = eina_hash_find(_new_nested_short_hash, hierarchy);
         if (nested)
           {
              if (nested->func_pop) nested->func_pop();
@@ -535,6 +605,38 @@ stack_pop(void)
    free(tmp);
 }
 
+void
+stack_push_quick(const char *str)
+{
+   char *s;
+
+   s = mem_strdup(str);
+   stack = eina_list_append(stack, s);
+   eina_strbuf_append_char(stack_buf, '.');
+   eina_strbuf_append(stack_buf, s);
+}
+
+void
+stack_pop_quick(Eina_Bool check_last, Eina_Bool do_free)
+{
+   char *tmp, *str;
+
+   str = tmp = eina_list_last_data_get(stack);
+   if (check_last)
+     {
+        char *end;
+
+        end = strrchr(tmp, '.');
+        if (end)
+          tmp = end + 1;
+     }
+   eina_strbuf_remove(stack_buf,
+                           eina_strbuf_length_get(stack_buf) - strlen(tmp) - 1,
+                           eina_strbuf_length_get(stack_buf)); /* remove: '.tmp' */
+   stack = eina_list_remove_list(stack, eina_list_last(stack));
+   if (do_free) free(str);
+}
+
 static const char *
 stack_id(void)
 {
@@ -592,6 +694,12 @@ parse(char *data, off_t size)
                }
              else if (*token == ';')
                {
+                  if (did_wildcard)
+                    {
+                       free(token);
+                       did_wildcard = 0;
+                       continue;
+                    }
                   if (do_params)
                     {
                        void *param;
@@ -604,6 +712,11 @@ parse(char *data, off_t size)
                        /* remove top from stack */
                        stack_pop();
                     }
+                  else
+                    {
+                       if (new_statement_single())
+                         stack_pop();
+                    }
                }
              else if (*token == '{')
                {
@@ -1044,13 +1157,25 @@ parse_enum(int n, ...)
    int result;
    va_list va;
 
-   str = _parse_param_get(n);
-   if (!str)
+   if (n >= 0)
      {
-        ERR("%s:%i no parameter supplied as argument %i",
-            file_in, line - 1, n + 1);
-        err_show();
-        exit(-1);
+        str = _parse_param_get(n);
+        if (!str)
+          {
+             ERR("%s:%i no parameter supplied as argument %i",
+                 file_in, line - 1, n + 1);
+             err_show();
+             exit(-1);
+          }
+     }
+   else
+     {
+        char *end;
+
+        str = eina_list_last_data_get(stack);
+        end = strrchr(str, '.');
+        if (end)
+          str = end + 1;
      }
 
    va_start(va, n);