Ejemplo n.º 1
0
void get_basic_type_spec_string(pTHX_ SV **sv, u_32 flags)
{
  struct { u_32 flag; const char *str; } *pSpec, spec[] = {
    {T_SIGNED,   "signed"  },
    {T_UNSIGNED, "unsigned"},
    {T_SHORT,    "short"   },
    {T_LONGLONG, "long"    },
    {T_LONG,     "long"    },
    {T_VOID,     "void"    },
    {T_CHAR,     "char"    },
    {T_INT ,     "int"     },
    {T_FLOAT ,   "float"   },
    {T_DOUBLE ,  "double"  },
    {0,          NULL      }
  };
  int first = 1;

  CT_DEBUG(MAIN, (XSCLASS "::get_basic_type_spec_string( sv=%p, flags=0x%08lX )",
                  sv, (unsigned long) flags));

  for (pSpec = spec; pSpec->flag; ++pSpec)
  {
    if (pSpec->flag & flags)
    {
      if (*sv)
        sv_catpvf(*sv, first ? "%s" : " %s", pSpec->str);
      else
        *sv = newSVpv(CONST_CHAR(pSpec->str), 0);

      first = 0;
    }
  }
}
Ejemplo n.º 2
0
static const StringOption *get_string_option(pTHX_ const StringOption *options,
                                             int count, int value, SV *sv, const char *name)
{
  char *string = NULL;

  if (sv)
  {
    if (SvROK(sv))
      Perl_croak(aTHX_ "%s must be a string value, not a reference", name);
    else
      string = SvPV_nolen(sv);
  }

  if (string)
  {
    const StringOption *opt = options;
    int n = count;

    while (n--)
    {
      if (strEQ(string, opt->string))
        return opt;

      opt++;
    }

    if (name)
    {
      SV *str = sv_2mortal(newSVpvn("", 0));

      for (n = 0; n < count; n++)
      {
        sv_catpv(str, CONST_CHAR((options++)->string));
        if (n < count-2)
          sv_catpv(str, "', '");
        else if (n == count-2)
          sv_catpv(str, "' or '");
      }

      Perl_croak(aTHX_ "%s must be '%s', not '%s'", name, SvPV_nolen(str), string);
    }
  }
  else
  {
    while (count--)
    {
      if (value == options->value)
        return options;

      options++;
    }

    fatal("Inconsistent data detected in get_string_option()!");
  }

  return NULL;
}
Ejemplo n.º 3
0
HV *newHV_indexed(pTHX_ const CBC *THIS)
{
  dSP;
  HV *hv, *stash;
  GV *gv;
  SV *sv;
  int count;

  hv = newHV();

  sv = newSVpv(CONST_CHAR(THIS->ixhash), 0);
  stash = gv_stashpv(CONST_CHAR(THIS->ixhash), 0);
  gv = gv_fetchmethod(stash, "TIEHASH");
 
  ENTER;
  SAVETMPS;
 
  PUSHMARK(SP);
  XPUSHs(sv_2mortal(sv));
  PUTBACK;
 
  count = call_sv((SV*)GvCV(gv), G_SCALAR);

  SPAGAIN;

  if (count != 1)
    fatal("%s::TIEHASH returned %d elements instead of 1",
          THIS->ixhash, count);
 
  sv = POPs;
 
  PUTBACK;

  hv_magic(hv, (GV *)sv, PERL_MAGIC_tied);
 
  FREETMPS;
  LEAVE;

  return hv;
}
Ejemplo n.º 4
0
void handle_string_list(pTHX_ const char *option, LinkedList list, SV *sv, SV **rval)
{
  const char *str;

  if (sv)
  {
    LL_flush(list, (LLDestroyFunc) string_delete); 

    if (SvROK(sv))
    {
      sv = SvRV(sv);

      if (SvTYPE(sv) == SVt_PVAV)
      {
        AV *av = (AV *) sv;
        SV **pSV;
        int i, max = av_len(av);

        for (i = 0; i <= max; i++)
        {
          if ((pSV = av_fetch(av, i, 0)) != NULL)
          {
            SvGETMAGIC(*pSV);
            LL_push(list, string_new_fromSV(aTHX_ *pSV));
          }
          else
            fatal("NULL returned by av_fetch() in handle_string_list()");
        }
      }
      else
        Perl_croak(aTHX_ "%s wants an array reference", option);
    }
    else
      Perl_croak(aTHX_ "%s wants a reference to an array of strings", option);
  }

  if (rval)
  {
    ListIterator li;
    AV *av = newAV();

    LL_foreach(str, li, list)
      av_push(av, newSVpv(CONST_CHAR(str), 0));

    *rval = newRV_noinc((SV *) av);
  }
}
Ejemplo n.º 5
0
void add_indent(pTHX_ SV *s, int level)
{
#define MAXINDENT 16
  static const char tab[MAXINDENT] = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";

#ifndef CBC_DONT_CLAMP_TO_MAXINDENT
  if (level > MAXINDENT)
    level = MAXINDENT;
#else
  while (level > MAXINDENT)
  {
    sv_catpvn( s, tab, MAXINDENT );
    level -= MAXINDENT;
  }
#endif

  sv_catpvn(s, CONST_CHAR(tab), level);
#undef MAXINDENT
}
Ejemplo n.º 6
0
void handle_option(pTHX_ CBC *THIS, SV *opt, SV *sv_val, SV **rval, HandleOptionResult *p_res)
{
  START_OPTIONS

    FLAG_OPTION(OrderMembers,      order_members,          0, 0)

    FLAG_OPTION(Warnings,          cfg.issue_warnings,     0, 0)
    FLAG_OPTION(HasCPPComments,    cfg.has_cpp_comments,   0, 1)
    FLAG_OPTION(HasMacroVAARGS,    cfg.has_macro_vaargs,   0, 1)
    FLAG_OPTION(UnsignedChars,     cfg.unsigned_chars,     0, 0)
    FLAG_OPTION(UnsignedBitfields, cfg.unsigned_bitfields, 0, 0)

    IVAL_OPTION(PointerSize,       cfg.layout.ptr_size,           1, 0)
    IVAL_OPTION(EnumSize,          cfg.layout.enum_size,          1, 0)
    IVAL_OPTION(IntSize,           cfg.layout.int_size,           1, 0)
    IVAL_OPTION(CharSize,          cfg.layout.char_size,          1, 0)
    IVAL_OPTION(ShortSize,         cfg.layout.short_size,         1, 0)
    IVAL_OPTION(LongSize,          cfg.layout.long_size,          1, 0)
    IVAL_OPTION(LongLongSize,      cfg.layout.long_long_size,     1, 0)
    IVAL_OPTION(FloatSize,         cfg.layout.float_size,         1, 0)
    IVAL_OPTION(DoubleSize,        cfg.layout.double_size,        1, 0)
    IVAL_OPTION(LongDoubleSize,    cfg.layout.long_double_size,   1, 0)
    IVAL_OPTION(Alignment,         cfg.layout.alignment,          1, 0)
    IVAL_OPTION(CompoundAlignment, cfg.layout.compound_alignment, 1, 0)

    TRISTATE_FLAG_OPTION(HostedC, cfg.has_std_c_hosted, cfg.is_std_c_hosted, 0, 1)

    TRISTATE_INT_OPTION(StdCVersion, cfg.has_std_c, cfg.std_c_version, 0, 1)

    STRLIST_OPTION(Include, cfg.includes,   0, 1)
    STRLIST_OPTION(Define,  cfg.defines,    0, 1)
    STRLIST_OPTION(Assert,  cfg.assertions, 0, 1)

    OPTION(DisabledKeywords)
      IMPACTS_LAYOUT(0);
      disabled_keywords(aTHX_ &THIS->cfg.disabled_keywords, sv_val, rval,
                        &THIS->cfg.keywords);
      DID_CHANGE(sv_val != NULL);
    ENDOPT

    OPTION(KeywordMap)
      IMPACTS_LAYOUT(0);
      keyword_map(aTHX_ &THIS->cfg.keyword_map, sv_val, rval);
      DID_CHANGE(sv_val != NULL);
    ENDOPT

    OPTION(ByteOrder)
      IMPACTS_LAYOUT(1);
      if (sv_val)
      {
        const StringOption *pOpt = GET_STR_OPTION(ByteOrder, 0, sv_val);
        UPDATE_OPT(cfg.layout.byte_order, pOpt->value);
      }
      if (rval)
      {
        const StringOption *pOpt = GET_STR_OPTION(ByteOrder,
                                     THIS->cfg.layout.byte_order, NULL);
        *rval = newSVpv(CONST_CHAR(pOpt->string), 0);
      }
    ENDOPT

    OPTION(EnumType)
      IMPACTS_LAYOUT(0);
      if (sv_val)
      {
        const StringOption *pOpt = GET_STR_OPTION(EnumType, 0, sv_val);
        UPDATE_OPT(enumType, pOpt->value);
      }
      if (rval)
      {
        const StringOption *pOpt = GET_STR_OPTION(EnumType, THIS->enumType, NULL);
        *rval = newSVpv(CONST_CHAR(pOpt->string), 0);
      }
    ENDOPT

    OPTION(Bitfields)
      IMPACTS_LAYOUT(1);
      bitfields_option(aTHX_ &THIS->cfg.layout.bflayouter, sv_val, rval);
      DID_CHANGE(sv_val != NULL);
    ENDOPT

    INVALID_OPTION

  POST_PROCESS

    OPTION(OrderMembers)
      if (sv_val && THIS->order_members && THIS->ixhash == NULL)
        load_indexed_hash_module(aTHX_ THIS);
    ENDOPT

  END_OPTIONS
}
Ejemplo n.º 7
0
static void keyword_map(pTHX_ HashTable *current, SV *sv, SV **rval)
{
  HashTable keyword_map = NULL;

  if(sv)
  {
    if (SvROK(sv))
    {
      sv = SvRV(sv);

      if (SvTYPE(sv) == SVt_PVHV)
      {
        HV *hv = (HV *) sv;
        HE *entry;

        keyword_map = HT_new_ex(4, HT_AUTOGROW);

        (void) hv_iterinit(hv);

        while ((entry = hv_iternext(hv)) != NULL)
        {
          SV *value;
          I32 keylen;
          const char *key, *c;
          const CKeywordToken *pTok;

          c = key = hv_iterkey(entry, &keylen);

          if (*c == '\0')
            FAIL_CLEAN((aTHX_ "Cannot use empty string as a keyword"));

          while (*c == '_' || isALPHA(*c))
            c++;

          if (*c != '\0')
            FAIL_CLEAN((aTHX_ "Cannot use '%s' as a keyword", key));

          value = hv_iterval(hv, entry);

          if (!SvOK(value))
            pTok = get_skip_token();
          else
          {
            const char *map;

            if (SvROK(value))
              FAIL_CLEAN((aTHX_ "Cannot use a reference as a keyword"));

            map = SvPV_nolen(value);

            if ((pTok = get_c_keyword_token(map)) == NULL)
              FAIL_CLEAN((aTHX_ "Cannot use '%s' as a keyword", map));
          }

          (void) HT_store(keyword_map, key, (int) keylen, 0,
                          (CKeywordToken *) pTok);
        }

        if (current != NULL)
        {
          HT_destroy(*current, NULL);
          *current = keyword_map;
        }
      }
      else
        Perl_croak(aTHX_ "KeywordMap wants a hash reference");
    }
    else
      Perl_croak(aTHX_ "KeywordMap wants a hash reference");
  }

  if (rval)
  {
    HashIterator hi;
    HV *hv = newHV();
    CKeywordToken *tok;
    const char *key;
    int keylen;

    HI_init(&hi, *current);

    while (HI_next(&hi, &key, &keylen, (void **) &tok))
    {
      SV *val;
      val = tok->name == NULL ? newSV(0) : newSVpv(CONST_CHAR(tok->name), 0);
      if (hv_store(hv, key, keylen, val, 0) == NULL)
        SvREFCNT_dec(val);
    }

    *rval = newRV_noinc((SV *) hv);
  }
}
Ejemplo n.º 8
0
static void disabled_keywords(pTHX_ LinkedList *current, SV *sv, SV **rval,
                              u_32 *pKeywordMask)
{
  const char *str;
  LinkedList keyword_list = NULL;

  if (sv)
  {
    if (SvROK(sv))
    {
      sv = SvRV(sv);

      if (SvTYPE(sv) == SVt_PVAV)
      {
        AV *av = (AV *) sv;
        SV **pSV;
        int i, max = av_len(av);
        u_32 keywords = HAS_ALL_KEYWORDS;

        keyword_list = LL_new();

        for (i = 0; i <= max; i++)
        {
          if ((pSV = av_fetch(av, i, 0)) != NULL)
          {
            SvGETMAGIC(*pSV);
            str = SvPV_nolen(*pSV);

#include "token/t_keywords.c"

            success:
            LL_push(keyword_list, string_new(str));
          }
          else
            fatal("NULL returned by av_fetch() in disabled_keywords()");
        }

        if (pKeywordMask != NULL)
          *pKeywordMask = keywords;

        if (current != NULL)
        {
          LL_destroy(*current, (LLDestroyFunc) string_delete); 
          *current = keyword_list;
        }
      }
      else
        Perl_croak(aTHX_ "DisabledKeywords wants an array reference");
    }
    else
      Perl_croak(aTHX_ "DisabledKeywords wants a reference to "
                       "an array of strings");
  }

  if (rval)
  {
    ListIterator li;
    AV *av = newAV();

    LL_foreach (str, li, *current)
      av_push(av, newSVpv(CONST_CHAR(str), 0));

    *rval = newRV_noinc((SV *) av);
  }

  return;

unknown:
  LL_destroy(keyword_list, (LLDestroyFunc) string_delete);
  Perl_croak(aTHX_ "Cannot disable unknown keyword '%s'", str);
}
Ejemplo n.º 9
0
SV *single_hook_call(pTHX_ SV *self, const char *hook_id_str, const char *id_pre,
                     const char *id, const SingleHook *hook, SV *in, int mortal)
{
  dSP;
  int count;
  SV *out;

  CT_DEBUG(MAIN, ("single_hook_call(hid='%s', id='%s%s', hook=%p, in=%p(%d), mortal=%d)",
                  hook_id_str, id_pre, id, hook, in, in ? (int) SvREFCNT(in) : 0, mortal));

  assert(self != NULL);
  assert(hook != NULL);

  if (hook->sub == NULL)
    return in;

  ENTER;
  SAVETMPS;

  PUSHMARK(SP);

  if (hook->arg)
  {
    I32 ix, len;
    len = av_len(hook->arg);

    for (ix = 0; ix <= len; ++ix)
    {
      SV **pSV = av_fetch(hook->arg, ix, 0);
      SV *sv;

      if (pSV == NULL)
        fatal("NULL returned by av_fetch() in single_hook_call()");

      if (SvROK(*pSV) && sv_isa(*pSV, ARGTYPE_PACKAGE))
      {
        HookArgType type = (HookArgType) SvIV(SvRV(*pSV));

        switch (type)
        {
          case HOOK_ARG_SELF:
            sv = sv_mortalcopy(self);
            break;

          case HOOK_ARG_DATA:
            assert(in != NULL);
            sv = sv_mortalcopy(in);
            break;

          case HOOK_ARG_TYPE:
            assert(id != NULL);
            sv = sv_newmortal();
            if (id_pre)
            {
              sv_setpv(sv, id_pre);
              sv_catpv(sv, CONST_CHAR(id));
            }
            else
              sv_setpv(sv, id);
            break;

          case HOOK_ARG_HOOK:
            if (hook_id_str)
            {
              sv = sv_newmortal();
              sv_setpv(sv, hook_id_str);
            }
            else
            {
              sv = &PL_sv_undef;
            }
            break;

          default:
            fatal("Invalid hook argument type (%d) in single_hook_call()", type);
            break;
        }
      }
      else
        sv = sv_mortalcopy(*pSV);

      XPUSHs(sv);
    }
  }
  else
  {
    if (in)
    {
      /* only push the data argument */
      XPUSHs(in);
    }
  }

  PUTBACK;

  count = call_sv(hook->sub, G_SCALAR);

  SPAGAIN;

  if (count != 1)
    fatal("Hook returned %d elements instead of 1", count);

  out = POPs;

  CT_DEBUG(MAIN, ("single_hook_call: in=%p(%d), out=%p(%d)",
                  in, in ? (int) SvREFCNT(in) : 0, out, (int) SvREFCNT(out)));

  if (!mortal && in != NULL)
    SvREFCNT_dec(in);
  SvREFCNT_inc(out);

  PUTBACK;
  FREETMPS;
  LEAVE;

  if (mortal)
    sv_2mortal(out);

  CT_DEBUG(MAIN, ("single_hook_call: out=%p(%d)", out, (int) SvREFCNT(out)));

  return out;
}
Ejemplo n.º 10
0
static int load_indexed_hash_module_ex(pTHX_ CBC *THIS, const char **modlist, int num)
{
  const char *p = NULL;
  int i;

  if (THIS->ixhash != NULL)
  {
    /* a module has already been loaded */
    return 1;
  }

  for (i = 0; i < num; i++)
  {
    if (modlist[i])
    {
      SV *sv = newSVpvn("require ", 8);
      sv_catpv(sv, CONST_CHAR(modlist[i]));
      CT_DEBUG(MAIN, ("trying to require \"%s\"", modlist[i]));
      (void) eval_sv(sv, G_DISCARD);
      SvREFCNT_dec(sv);
      if ((sv = get_sv("@", 0)) != NULL && strEQ(SvPV_nolen(sv), ""))
      {
        p = modlist[i];
        break;
      }
      if (i == 0)
      {
        Perl_warn(aTHX_ "Couldn't load %s for member ordering, "
                        "trying default modules", modlist[i]);
      }
      CT_DEBUG(MAIN, ("failed: \"%s\"", sv ? SvPV_nolen(sv) : "[NULL]"));
    }
  }

  if (p == NULL)
  {
    SV *sv = newSVpvn("", 0);

    for (i = 1; i < num; i++)
    {
      if (i > 1)
      {
        if (i == num-1)
          sv_catpvn(sv, " or ", 4);
        else
          sv_catpvn(sv, ", ", 2);
      }
      sv_catpv(sv, CONST_CHAR(modlist[i]));
    }

    Perl_warn(aTHX_ "Couldn't load a module for member ordering "
                    "(consider installing %s)", SvPV_nolen(sv));
    return 0;
  }

  CT_DEBUG(MAIN, ("using \"%s\" for member ordering", p));

  THIS->ixhash = p;

  return 1;
}