File Coverage

xsubs/compound.xs
Criterion Covered Total %
statement 86 86 100.0
branch 86 104 82.6
condition n/a
subroutine n/a
pod n/a
total 172 190 90.5


line stmt bran cond sub pod time code
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: compound_names / struct_names / union_names
13             #
14             # WRITTEN BY: Marcus Holland-Moritz ON: Aug 2002
15             # CHANGED BY: ON:
16             #
17             ################################################################################
18              
19             void
20             CBC::compound_names()
21             ALIAS:
22             struct_names = 1
23             union_names = 2
24              
25             PREINIT:
26 7917           CBC_METHOD_VAR;
27             ListIterator li;
28             Struct *pStruct;
29 7917           int count = 0;
30             U32 context;
31             u_32 mask;
32              
33             PPCODE:
34 7917           switch (ix)
35             {
36             case 1: /* struct_names */
37 59           CBC_METHOD_SET("struct_names");
38 59           mask = T_STRUCT;
39 59           break;
40             case 2: /* union_names */
41 57           CBC_METHOD_SET("union_names");
42 57           mask = T_UNION;
43 57           break;
44             default: /* compound_names */
45 7801           CBC_METHOD_SET("compound_names");
46 7801           mask = T_STRUCT | T_UNION;
47 7801           break;
48             }
49              
50             CT_DEBUG_METHOD;
51              
52 7917 100         CHECK_PARSE_DATA;
53 7899 100         CHECK_VOID_CONTEXT;
    100          
    100          
54              
55 7881 50         context = GIMME_V;
56              
57 17150 100         LL_foreach(pStruct, li, THIS->cpi.structs)
    100          
58 9269 100         if (pStruct->identifier[0] &&
    50          
59 8923 100         pStruct->declarations &&
60 8923           pStruct->tflags & mask)
61             {
62 8550 100         if (context == G_ARRAY)
63 5690 50         XPUSHs(sv_2mortal(newSVpv(pStruct->identifier, 0)));
64 8550           count++;
65             }
66              
67 7881 100         if (context == G_ARRAY)
68 5280           XSRETURN(count);
69             else
70 7899           XSRETURN_IV(count);
71              
72              
73             ################################################################################
74             #
75             # METHOD: compound / struct / union
76             #
77             # WRITTEN BY: Marcus Holland-Moritz ON: Aug 2002
78             # CHANGED BY: ON:
79             #
80             ################################################################################
81              
82             void
83             CBC::compound(...)
84             ALIAS:
85             struct = 1
86             union = 2
87              
88             PREINIT:
89 555           CBC_METHOD_VAR;
90             Struct *pStruct;
91             U32 context;
92             u_32 mask;
93              
94             PPCODE:
95 555           switch(ix)
96             {
97             case 1: /* struct */
98 222           CBC_METHOD_SET("struct");
99 222           mask = T_STRUCT;
100 222           break;
101             case 2: /* union */
102 92           CBC_METHOD_SET("union");
103 92           mask = T_UNION;
104 92           break;
105             default: /* compound */
106 241           CBC_METHOD_SET("compound");
107 241           mask = T_STRUCT | T_UNION;
108 241           break;
109             }
110              
111             CT_DEBUG_METHOD;
112              
113 555 100         CHECK_PARSE_DATA;
114 535 100         CHECK_VOID_CONTEXT;
    100          
    100          
115              
116 517 50         context = GIMME_V;
117              
118 517 100         if (context == G_SCALAR && items != 2)
    100          
119             {
120 23 100         if (items > 1)
121 2           XSRETURN_IV(items-1);
122 21 100         else if (mask == (T_STRUCT|T_UNION))
123 7           XSRETURN_IV(LL_count(THIS->cpi.structs));
124             else
125             {
126             ListIterator li;
127 14           int count = 0;
128              
129 378 100         LL_foreach(pStruct, li, THIS->cpi.structs)
    100          
130 364 100         if (pStruct->tflags & mask)
131 182           count++;
132              
133 14           XSRETURN_IV(count);
134             }
135             }
136              
137 494 50         NEED_PARSE_DATA;
    100          
138              
139 494 100         if (items > 1)
140             {
141             int i;
142              
143 844 100         for (i = 1; i < items; i++)
144             {
145             const char *name;
146 447           u_32 limit = mask;
147              
148 447 50         name = SvPV_nolen(ST(i));
149              
150             /* skip optional union/struct */
151 447 100         if(mask & T_UNION &&
    100          
152 34 50         name[0] == 'u' &&
153 34 50         name[1] == 'n' &&
154 34 50         name[2] == 'i' &&
155 34 50         name[3] == 'o' &&
156 34 50         name[4] == 'n' &&
157 34           isSPACE(name[5]))
158             {
159 34           name += 6;
160 34           limit = T_UNION;
161             }
162             else
163 413 100         if(mask & T_STRUCT &&
    100          
164 41 50         name[0] == 's' &&
165 41 50         name[1] == 't' &&
166 41 50         name[2] == 'r' &&
167 41 50         name[3] == 'u' &&
168 41 50         name[4] == 'c' &&
169 41 50         name[5] == 't' &&
170 41           isSPACE(name[6]))
171             {
172 41           name += 7;
173 41           limit = T_STRUCT;
174             }
175              
176 462 100         while (isSPACE(*name))
177 15           name++;
178              
179 447           pStruct = HT_get(THIS->cpi.htStructs, name, 0, 0);
180              
181 447 100         if (pStruct && pStruct->tflags & limit)
    100          
182 360           PUSHs(sv_2mortal(get_struct_spec_def(aTHX_ &THIS->cfg, pStruct)));
183             else
184 87           PUSHs(&PL_sv_undef);
185             }
186              
187 397           XSRETURN(items-1);
188             }
189             else
190             {
191             ListIterator li;
192 97           int count = 0;
193              
194 506 100         LL_foreach(pStruct, li, THIS->cpi.structs)
    100          
195 409 100         if (pStruct->tflags & mask)
196             {
197 273 50         XPUSHs(sv_2mortal(get_struct_spec_def(aTHX_ &THIS->cfg, pStruct)));
198 273           count++;
199             }
200              
201 97           XSRETURN(count);
202             }
203