Beispiel #1
0
static Eina_Bool
eval_exp(const Eolian_Expression *expr, Eolian_Expression_Mask mask,
         Eolian_Expression *out)
{
   switch (expr->type)
     {
      case EOLIAN_EXPR_INT:
      case EOLIAN_EXPR_LONG:
      case EOLIAN_EXPR_LLONG:
        {
           if (!(mask & EOLIAN_MASK_SINT))
             return expr_type_error(expr, EOLIAN_MASK_SINT, mask);
           *out = *expr;
           return EINA_TRUE;
        }
      case EOLIAN_EXPR_UINT:
      case EOLIAN_EXPR_ULONG:
      case EOLIAN_EXPR_ULLONG:
        {
           if (!(mask & EOLIAN_MASK_UINT))
             return expr_type_error(expr, EOLIAN_MASK_UINT, mask);
           *out = *expr;
           return EINA_TRUE;
        }
      case EOLIAN_EXPR_FLOAT:
      case EOLIAN_EXPR_DOUBLE:
        {
           if (!(mask & EOLIAN_MASK_FLOAT))
             return expr_type_error(expr, EOLIAN_MASK_FLOAT, mask);
           *out = *expr;
           return EINA_TRUE;
        }
      case EOLIAN_EXPR_STRING:
        {
           if (!(mask & EOLIAN_MASK_STRING))
             return expr_type_error(expr, EOLIAN_MASK_STRING, mask);
           *out = *expr;
           return EINA_TRUE;
        }
      case EOLIAN_EXPR_NULL:
        {
           if (!(mask & EOLIAN_MASK_NULL))
             return expr_type_error(expr, EOLIAN_MASK_NULL, mask);
           *out = *expr;
           return EINA_TRUE;
        }
      case EOLIAN_EXPR_CHAR:
        {
           if (!(mask & EOLIAN_MASK_CHAR))
             return expr_type_error(expr, EOLIAN_MASK_CHAR, mask);
           *out = *expr;
           return EINA_TRUE;
        }
      case EOLIAN_EXPR_BOOL:
        {
           if (!(mask & EOLIAN_MASK_BOOL))
             return expr_type_error(expr, EOLIAN_MASK_BOOL, mask);
           *out = *expr;
           return EINA_TRUE;
        }
      case EOLIAN_EXPR_NAME:
        {
           const Eolian_Variable *var = eolian_variable_constant_get_by_name
             (expr->value.s);
           const Eolian_Expression *exp = NULL;

           if (!var)
             {
                const Eolian_Type *etp;
                const Eolian_Enum_Type_Field *fl;

                /* try aliases, hoping it'll be enum */
                char *fulln = NULL, *memb = NULL;

                if (!split_enum_name(expr->value.s, &fulln, &memb))
                  return expr_error(expr, "undefined variable");

                /* assert int here, as we're clearly dealing with enum */
                if (!(mask & EOLIAN_MASK_INT))
                  return expr_type_error(expr, EOLIAN_MASK_INT, mask);

                etp = eolian_type_alias_get_by_name(fulln);
                while (etp && (etp->type == EOLIAN_TYPE_ALIAS
                            || etp->type == EOLIAN_TYPE_REGULAR))
                  etp = eolian_type_base_type_get(etp);

                if (!etp) etp = eolian_type_enum_get_by_name(fulln);
                if (!etp || etp->type != EOLIAN_TYPE_ENUM)
                  {
                     free(fulln);
                     return expr_error(expr, "undefined variable");
                  }

                fl = eolian_type_enum_field_get(etp, memb);
                if (fl) exp = eolian_type_enum_field_value_get(fl, EINA_TRUE);
                free(fulln);

                if (!exp)
                  return expr_error(expr, "invalid enum field");
             }
           else
             exp = var->value;

           if (!exp)
             return expr_error(expr, "undefined variable");

           return eval_exp(exp, mask, out);
        }
      case EOLIAN_EXPR_UNARY:
        return eval_unary(expr, mask, out);
      case EOLIAN_EXPR_BINARY:
        return eval_binary(expr, mask, out);
      default:
        assert(EINA_FALSE);
        return EINA_FALSE;
     }

   return EINA_TRUE;
}
Beispiel #2
0
static Eina_Bool
_validate_ref(const char *ref, const Eolian_Object *info)
{
   if (eolian_declaration_get_by_name(ref))
     return EINA_TRUE;

   const char *suffix = strrchr(ref, '.');
   if (!suffix) goto failed;

   Eina_Stringshare *base = eina_stringshare_add_length(ref, suffix - ref);

   const Eolian_Type *tp = eolian_type_struct_get_by_name(base);
   if (tp)
     {
        eina_stringshare_del(base);
        if (!eolian_type_struct_field_get(tp, suffix + 1))
          goto failed;
        return EINA_TRUE;
     }

   tp = eolian_type_enum_get_by_name(base);
   if (tp)
     {
        eina_stringshare_del(base);
        if (!eolian_type_enum_field_get(tp, suffix + 1))
          goto failed;
        return EINA_TRUE;
     }

   const Eolian_Class *cl = eolian_class_get_by_name(base);
   if (cl)
     {
        eina_stringshare_del(base);
        if (!eolian_class_function_get_by_name(cl, suffix + 1, EOLIAN_UNRESOLVED))
          goto failed;
        return EINA_TRUE;
     }

   Eolian_Function_Type ftype = EOLIAN_UNRESOLVED;
   if (!strcmp(suffix, ".get"))
     ftype = EOLIAN_PROP_GET;
   else if (!strcmp(suffix, ".set"))
     ftype = EOLIAN_PROP_SET;

   const char *meth;
   if (ftype != EOLIAN_UNRESOLVED)
     {
        eina_stringshare_del(base);
        meth = suffix - 1;
        while ((meth != ref) && (*meth != '.')) --meth;
        if (meth == ref) goto failed;
        base = eina_stringshare_add_length(ref, meth - ref);
        cl = eolian_class_get_by_name(base);
        eina_stringshare_del(base);
     }

   if (!cl) goto failed;

   char *ameth = strndup(meth + 1, suffix - meth - 1);
   const Eolian_Function *fn = eolian_class_function_get_by_name(cl, ameth, ftype);
   free(ameth);

   if (!fn) goto failed;
   return EINA_TRUE;

failed:
   fprintf(stderr, "eolian:%s:%d:%d: failed validating reference '%s'\n",
       info->file, info->line, info->column, ref);
   return EINA_FALSE;
}
Beispiel #3
0
static void
_generate_ref(const char *refn, Eina_Strbuf *wbuf, Eina_Bool use_legacy)
{
   const Eolian_Declaration *decl = eolian_declaration_get_by_name(refn);
   if (decl)
     {
        char *n = strdup(eolian_declaration_name_get(decl));
        char *p = n;
        while ((p = strchr(p, '.'))) *p = '_';
        eina_strbuf_append(wbuf, n);
        free(n);
        return;
     }

   /* not a plain declaration, so it must be struct/enum field or func */
   const char *sfx = strrchr(refn, '.');
   if (!sfx) goto noref;

   Eina_Stringshare *bname = eina_stringshare_add_length(refn, sfx - refn);

   const Eolian_Type *tp = eolian_type_struct_get_by_name(bname);
   if (tp)
     {
        if (!eolian_type_struct_field_get(tp, sfx + 1))
          {
             eina_stringshare_del(bname);
             goto noref;
          }
        _generate_ref(bname, wbuf, use_legacy);
        eina_strbuf_append(wbuf, sfx);
        eina_stringshare_del(bname);
        return;
     }

   tp = eolian_type_enum_get_by_name(bname);
   if (tp)
     {
        const Eolian_Enum_Type_Field *efl = eolian_type_enum_field_get(tp, sfx + 1);
        if (!efl)
          {
             eina_stringshare_del(bname);
             goto noref;
          }
        _generate_ref(bname, wbuf, use_legacy);
        Eina_Stringshare *str = eolian_type_enum_field_c_name_get(efl);
        eina_strbuf_append_char(wbuf, '.');
        eina_strbuf_append(wbuf, str);
        eina_stringshare_del(str);
        eina_stringshare_del(bname);
        return;
     }

   const Eolian_Class *cl = eolian_class_get_by_name(bname);
   const Eolian_Function *fn = NULL;
   Eolian_Function_Type ftype = EOLIAN_UNRESOLVED;
   if (!cl)
     {
        const char *mname;
        if (!strcmp(sfx, ".get")) ftype = EOLIAN_PROP_GET;
        else if (!strcmp(sfx, ".set")) ftype = EOLIAN_PROP_SET;
        if (ftype != EOLIAN_UNRESOLVED)
          {
             eina_stringshare_del(bname);
             mname = sfx - 1;
             while ((mname != refn) && (*mname != '.')) --mname;
             if (mname == refn) goto noref;
             bname = eina_stringshare_add_length(refn, mname - refn);
             cl = eolian_class_get_by_name(bname);
             eina_stringshare_del(bname);
          }
        if (cl)
          {
             char *meth = strndup(mname + 1, sfx - mname - 1);
             fn = eolian_class_function_get_by_name(cl, meth, ftype);
             if (ftype == EOLIAN_UNRESOLVED)
               ftype = eolian_function_type_get(fn);
             free(meth);
          }
     }
   else
     {
        fn = eolian_class_function_get_by_name(cl, sfx + 1, ftype);
        ftype = eolian_function_type_get(fn);
     }

   if (!fn) goto noref;

   Eina_Stringshare *fcn = eolian_function_full_c_name_get(fn, ftype, use_legacy);
   if (!fcn) goto noref;
   eina_strbuf_append(wbuf, fcn);
   eina_stringshare_del(fcn);
   return;
noref:
   eina_strbuf_append(wbuf, refn);
}