Convert-Binary-C

 view release on metacpan or  search on metacpan

xsubs/compound.xs  view on Meta::CPAN

################################################################################
#
# Copyright (c) 2002-2024 Marcus Holland-Moritz. All rights reserved.
# This program is free software; you can redistribute it and/or modify
# it under the same terms as Perl itself.
#
################################################################################


################################################################################
#
#   METHOD: compound_names / struct_names / union_names
#
#   WRITTEN BY: Marcus Holland-Moritz             ON: Aug 2002
#   CHANGED BY:                                   ON:
#
################################################################################

void
CBC::compound_names()
  ALIAS:
    struct_names = 1
    union_names  = 2

  PREINIT:
    CBC_METHOD_VAR;
    ListIterator li;
    Struct *pStruct;
    int count = 0;
    U32 context;
    u_32 mask;

  PPCODE:
    switch (ix)
    {
      case 1:  /* struct_names */
        CBC_METHOD_SET("struct_names");
        mask = T_STRUCT;
        break;
      case 2:  /* union_names */
        CBC_METHOD_SET("union_names");
        mask = T_UNION;
        break;
      default: /* compound_names */
        CBC_METHOD_SET("compound_names");
        mask = T_STRUCT | T_UNION;
        break;
    }

    CT_DEBUG_METHOD;

    CHECK_PARSE_DATA;
    CHECK_VOID_CONTEXT;

    context = GIMME_V;

    LL_foreach(pStruct, li, THIS->cpi.structs)
      if (pStruct->identifier[0] &&
          pStruct->declarations &&
          pStruct->tflags & mask)
      {
        if (context == G_ARRAY)
          XPUSHs(sv_2mortal(newSVpv(pStruct->identifier, 0)));
        count++;
      }

    if (context == G_ARRAY)
      XSRETURN(count);
    else
      XSRETURN_IV(count);


################################################################################
#
#   METHOD: compound / struct / union
#
#   WRITTEN BY: Marcus Holland-Moritz             ON: Aug 2002
#   CHANGED BY:                                   ON:
#
################################################################################

void
CBC::compound(...)
  ALIAS:
    struct = 1
    union  = 2

  PREINIT:
    CBC_METHOD_VAR;
    Struct *pStruct;
    U32 context;
    u_32 mask;

  PPCODE:
    switch(ix)
    {
      case 1:  /* struct */
        CBC_METHOD_SET("struct");
        mask = T_STRUCT;
        break;
      case 2:  /* union */
        CBC_METHOD_SET("union");
        mask = T_UNION;
        break;
      default: /* compound */
        CBC_METHOD_SET("compound");
        mask = T_STRUCT | T_UNION;
        break;
    }

    CT_DEBUG_METHOD;

    CHECK_PARSE_DATA;
    CHECK_VOID_CONTEXT;

    context = GIMME_V;

    if (context == G_SCALAR && items != 2)
    {
      if (items > 1)
        XSRETURN_IV(items-1);
      else if (mask == (T_STRUCT|T_UNION))
        XSRETURN_IV(LL_count(THIS->cpi.structs));
      else
      {
        ListIterator li;
        int count = 0;

        LL_foreach(pStruct, li, THIS->cpi.structs)
          if (pStruct->tflags & mask)
            count++;

        XSRETURN_IV(count);
      }
    }

    NEED_PARSE_DATA;

    if (items > 1)
    {
      int i;

      for (i = 1; i < items; i++)
      {
        const char *name;
        u_32 limit = mask;

        name = SvPV_nolen(ST(i));

        /* skip optional union/struct */
        if(mask & T_UNION && 
           name[0] == 'u' && 
           name[1] == 'n' && 
           name[2] == 'i' && 



( run in 1.963 second using v1.01-cache-2.11-cpan-71847e10f99 )