1 ################################################################################ 2 # 3 # Copyright (c) 2002-2020 Marcus Holland-Moritz. All rights reserved. 4 # This program is free software; you can redistribute it and/or modify 5 # it under the same terms as Perl itself. 6 # 7 ################################################################################ 8 9 10 ################################################################################ 11 # 12 # METHOD: member 13 # 14 # WRITTEN BY: Marcus Holland-Moritz ON: Jan 2002 15 # CHANGED BY: ON: 16 # 17 ################################################################################ 18 19 void 20 CBC::member(type, offset = NULL) 21 const char *type 22 SV *offset 23 24 PREINIT: 25 CBC_METHOD(member); 26 MemberInfo mi; 27 int have_offset, off; 28 29 PPCODE: 30 off = (have_offset = DEFINED(offset)) ? SvIV(offset) : 0; 31 32 CT_DEBUG_METHOD2("'%s', %d", type, off); 33 34 CHECK_PARSE_DATA; 35 CHECK_VOID_CONTEXT; 36 37 NEED_PARSE_DATA; 38 39 if (!get_member_info(aTHX_ THIS, type, &mi, 0)) 40 Perl_croak(aTHX_ "Cannot find '%s'", type); 41 42 check_allowed_types(aTHX_ &mi, method, ALLOW_STRUCTS 43 | ALLOW_UNIONS 44 | ALLOW_ARRAYS); 45 46 if (mi.flags) 47 { 48 u_32 flags = mi.flags; 49 50 /* bitfields are not a problem without offset given */ 51 if (!have_offset) 52 flags &= ~T_HASBITFIELD; 53 54 WARN_FLAGS(type, flags); 55 } 56 57 if (have_offset) 58 { 59 if (off < 0 || off >= (int) mi.size) 60 Perl_croak(aTHX_ "Offset %d out of range (0 <= offset < %d)", off, mi.size); 61 62 if (GIMME_V == G_ARRAY) 63 { 64 ListIterator li; 65 GMSInfo info; 66 SV *member; 67 int count; 68 69 info.hit = LL_new(); 70 info.off = LL_new(); 71 info.pad = LL_new(); 72 73 (void) get_member_string(aTHX_ &mi, off, &info); 74 75 count = LL_count(info.hit) 76 + LL_count(info.off) 77 + LL_count(info.pad); 78 79 EXTEND(SP, count); 80 81 LL_foreach(member, li, info.hit) 82 PUSHs(member); 83 84 LL_foreach(member, li, info.off) 85 PUSHs(member); 86 87 LL_foreach(member, li, info.pad) 88 PUSHs(member); 89 90 LL_destroy(info.hit, NULL); 91 LL_destroy(info.off, NULL); 92 LL_destroy(info.pad, NULL); 93 94 XSRETURN(count); 95 } 96 else 97 { 98 SV *member = get_member_string(aTHX_ &mi, off, NULL); 99 PUSHs(member); 100 XSRETURN(1); 101 } 102 } 103 else 104 { 105 LinkedList list; 106 SV *member; 107 int count; 108 109 list = GIMME_V == G_ARRAY ? LL_new() : NULL; 110 count = get_all_member_strings(aTHX_ &mi, list); 111 112 if (GIMME_V == G_ARRAY) 113 { 114 ListIterator li; 115 116 EXTEND(SP, count); 117 118 LL_foreach(member, li, list) 119 PUSHs(member); 120 121 LL_destroy(list, NULL); 122 123 XSRETURN(count); 124 } 125 else 126 XSRETURN_IV(count); 127 } 128 129