Skip to content
Newer
Older
100644 763 lines (626 sloc) 16.9 KB
692f58f @pjcj import Devel::Cover 0.01
authored
1 /*
7a80026 @pjcj import Devel::Cover 0.21
authored
2 * Copyright 2001-2003, Paul Johnson (pjcj@cpan.org)
692f58f @pjcj import Devel::Cover 0.01
authored
3 *
4 * This software is free. It is licensed under the same terms as Perl itself.
5 *
6 * The latest version of this software should be available from my homepage:
7 * http://www.pjcj.net
8 *
9 */
10
b6b6594 @pjcj import Devel::Cover 0.12
authored
11 #ifdef __cplusplus
12 extern "C" {
13 #endif
14
692f58f @pjcj import Devel::Cover 0.01
authored
15 #include "EXTERN.h"
16 #include "perl.h"
17 #include "XSUB.h"
18
b6b6594 @pjcj import Devel::Cover 0.12
authored
19 #ifdef __cplusplus
20 }
21 #endif
22
692f58f @pjcj import Devel::Cover 0.01
authored
23 #ifdef PERL_OBJECT
24 #define CALLOP this->*PL_op
25 #else
26 #define CALLOP *PL_op
27 #endif
28
c8c4341 @pjcj import Devel::Cover 0.15
authored
29 #define PDEB(a) a
30 #define NDEB(a)
31 #define D PerlIO_printf
32 #define L Perl_debug_log
33 #define svdump(sv) do_sv_dump(0, L, (SV *)sv, 0, 10, 1, 0);
34
ffe2236 @pjcj import Devel::Cover 0.23
authored
35 #define None 0x00000000
36 #define Statement 0x00000001
37 #define Branch 0x00000002
38 #define Condition 0x00000004
39 #define Subroutine 0x00000008
40 #define Path 0x00000010
41 #define Pod 0x00000020
42 #define Time 0x00000040
43 #define All 0xffffffff
c8c4341 @pjcj import Devel::Cover 0.15
authored
44
7a80026 @pjcj import Devel::Cover 0.21
authored
45 static unsigned Covering = All; /* Until we find out what we really want */
c8c4341 @pjcj import Devel::Cover 0.15
authored
46
47 #define collecting(criteria) (Covering & (criteria))
48
49 static HV *Cover_hv,
50 *Statements,
51 *Branches,
52 *Conditions,
53 *Times,
54 *Pending_conditionals;
55
c6cb737 @pjcj import Devel::Cover 0.18
authored
56 static int Got_condition = 0;
7a80026 @pjcj import Devel::Cover 0.21
authored
57 static OP *Profiling_op = 0;
c6cb737 @pjcj import Devel::Cover 0.18
authored
58
c8c4341 @pjcj import Devel::Cover 0.15
authored
59 typedef int seq_t;
60 #define ch_sz (sizeof(void *) + sizeof(seq_t))
61
62 struct unique /* Well, we'll be fairly unlucky if it's not */
63 {
64 void *addr;
65 seq_t seq;
66 };
692f58f @pjcj import Devel::Cover 0.01
authored
67
c8c4341 @pjcj import Devel::Cover 0.15
authored
68 union sequence /* Hack, hack, hackety hack. */
692f58f @pjcj import Devel::Cover 0.01
authored
69 {
c8c4341 @pjcj import Devel::Cover 0.15
authored
70 struct unique op;
c6cb737 @pjcj import Devel::Cover 0.18
authored
71 char ch[ch_sz + 1];
692f58f @pjcj import Devel::Cover 0.01
authored
72 };
73
b6b6594 @pjcj import Devel::Cover 0.12
authored
74 #ifdef HAS_GETTIMEOFDAY
75
76 #ifdef __cplusplus
77 extern "C" {
78 #endif
79
80 #ifdef WIN32
81 #include <time.h>
82 #else
83 #include <sys/time.h>
84 #endif
85
86 #ifdef __cplusplus
87 }
88 #endif
89
bf1430b @pjcj import Devel::Cover 0.30
authored
90 #ifdef WIN32
91 typedef double elapsed_type;
92 #else
93 typedef int elapsed_type;
94 #endif
95
96 static elapsed_type elapsed()
b6b6594 @pjcj import Devel::Cover 0.12
authored
97 {
98 static struct timeval time;
c6cb737 @pjcj import Devel::Cover 0.18
authored
99 static int sec = 0,
100 usec = 0;
bf1430b @pjcj import Devel::Cover 0.30
authored
101 elapsed_type e;
b6b6594 @pjcj import Devel::Cover 0.12
authored
102
103 gettimeofday(&time, NULL);
104 e = (time.tv_sec - sec) * 1e6 + time.tv_usec - usec;
105 sec = time.tv_sec;
106 usec = time.tv_usec;
107
108 /* fprintf(stderr, "[[[%d]]]\n", sec * 1e6 + usec); */
109
110 return e;
111 }
112
113 #endif /* HAS_GETTIMEOFDAY */
114
115 #ifdef HAS_TIMES
116
117 #ifndef HZ
118 # ifdef CLK_TCK
119 # define HZ CLK_TCK
120 # else
121 # define HZ 60
122 # endif
123 #endif
124
c8c4341 @pjcj import Devel::Cover 0.15
authored
125 static int cpu()
b6b6594 @pjcj import Devel::Cover 0.12
authored
126 {
127 static struct tms time;
c6cb737 @pjcj import Devel::Cover 0.18
authored
128 static int utime = 0,
129 stime = 0;
130 int e;
b6b6594 @pjcj import Devel::Cover 0.12
authored
131
132 #ifndef VMS
133 (void)PerlProc_times(&time);
134 #else
135 (void)PerlProc_times((tbuffer_t *)&time);
136 #endif
137
138 e = time.tms_utime - utime + time.tms_stime - stime;
139 utime = time.tms_utime;
140 stime = time.tms_stime;
141
142 /* fprintf(stderr, "<<<%d>>>\n", utime + stime); */
143
144 return e / HZ;
145 }
146
147 #endif /* HAS_TIMES */
148
c8c4341 @pjcj import Devel::Cover 0.15
authored
149 #define CAN_PROFILE defined HAS_GETTIMEOFDAY || defined HAS_TIMES
150
151 static char *get_key(OP *o)
152 {
153 static union sequence uniq;
154
155 uniq.op.addr = o;
156 uniq.op.seq = o->op_seq;
157 uniq.ch[ch_sz] = 0;
158 return uniq.ch;
159 }
160
161 static void add_branch(OP *op, int br)
162 {
c6cb737 @pjcj import Devel::Cover 0.18
authored
163 AV *branches;
c8c4341 @pjcj import Devel::Cover 0.15
authored
164 SV **count;
c6cb737 @pjcj import Devel::Cover 0.18
authored
165 int c;
c8c4341 @pjcj import Devel::Cover 0.15
authored
166 SV **tmp = hv_fetch(Branches, get_key(op), ch_sz, 1);
c6cb737 @pjcj import Devel::Cover 0.18
authored
167
c8c4341 @pjcj import Devel::Cover 0.15
authored
168 if (SvROK(*tmp))
c6cb737 @pjcj import Devel::Cover 0.18
authored
169 branches = (AV *) SvRV(*tmp);
c8c4341 @pjcj import Devel::Cover 0.15
authored
170 else
171 {
172 *tmp = newRV_inc((SV*) (branches = newAV()));
173 av_unshift(branches, 2);
174 }
175
176 count = av_fetch(branches, br, 1);
177 c = SvTRUE(*count) ? SvIV(*count) + 1 : 1;
178 sv_setiv(*count, c);
c6cb737 @pjcj import Devel::Cover 0.18
authored
179 NDEB(D(L, "Adding branch making %d at %p\n", c, op));
c8c4341 @pjcj import Devel::Cover 0.15
authored
180 }
181
c6cb737 @pjcj import Devel::Cover 0.18
authored
182 static AV *get_conditional_array(OP *op)
183 {
184 AV *conds;
185 SV **tmp = hv_fetch(Conditions, get_key(op), ch_sz, 1);
186
187 if (SvROK(*tmp))
188 conds = (AV *) SvRV(*tmp);
189 else
190 *tmp = newRV_inc((SV*) (conds = newAV()));
c8c4341 @pjcj import Devel::Cover 0.15
authored
191
c6cb737 @pjcj import Devel::Cover 0.18
authored
192 return conds;
193 }
c8c4341 @pjcj import Devel::Cover 0.15
authored
194
c6cb737 @pjcj import Devel::Cover 0.18
authored
195 static void set_conditional(OP *op, int cond, int value)
c8c4341 @pjcj import Devel::Cover 0.15
authored
196 {
c6cb737 @pjcj import Devel::Cover 0.18
authored
197 SV **count;
198 AV *conds = get_conditional_array(op);
199
200 count = av_fetch(conds, cond, 1);
201 sv_setiv(*count, value);
7a80026 @pjcj import Devel::Cover 0.21
authored
202 NDEB(D(L, "Setting %d conditional to %d at %p\n", cond, value, op));
c8c4341 @pjcj import Devel::Cover 0.15
authored
203 }
204
205 static void add_conditional(OP *op, int cond)
206 {
207 SV **count;
c6cb737 @pjcj import Devel::Cover 0.18
authored
208 int c;
209 AV *conds = get_conditional_array(op);
c8c4341 @pjcj import Devel::Cover 0.15
authored
210
211 count = av_fetch(conds, cond, 1);
212 c = SvTRUE(*count) ? SvIV(*count) + 1 : 1;
213 sv_setiv(*count, c);
214 NDEB(D(L, "Adding %d conditional making %d at %p\n", cond, c, op));
215 }
b6b6594 @pjcj import Devel::Cover 0.12
authored
216
c6cb737 @pjcj import Devel::Cover 0.18
authored
217 static OP *get_condition(pTHX)
218 {
219 char *ch;
220 AV *conds;
221 SV **sv;
222 OP *op;
f9ee5ec @pjcj import Devel::Cover 0.20
authored
223 OP *(*f)(pTHX);
c6cb737 @pjcj import Devel::Cover 0.18
authored
224 I32 i;
225
226 NDEB(D(L, "In get_condition\n"));
227
228 ch = get_key(PL_op);
229 sv = hv_fetch(Pending_conditionals, ch, ch_sz, 0);
230
231 if (sv && SvROK(*sv))
232 {
233 conds = (AV *) SvRV(*sv);
234 NDEB(D(L, "Looking through %d conditionals\n", av_len(conds)));
235
236 sv = av_fetch(conds, 0, 0);
f9ee5ec @pjcj import Devel::Cover 0.20
authored
237 f = (OP *(*)(pTHX)) SvIV(*sv);
c6cb737 @pjcj import Devel::Cover 0.18
authored
238
239 for (i = 1; i <= av_len(conds); i++)
240 {
241 sv = av_fetch(conds, i, 0);
242 op = (OP *) SvIV(*sv);
243
244 {
245 dSP;
246 SV **count;
247 int type;
248 AV *conds = get_conditional_array(op);
249 int value = SvTRUE(TOPs) ? 2 : 1;
250
251 count = av_fetch(conds, 0, 1);
252 type = SvTRUE(*count) ? SvIV(*count) : 0;
253 sv_setiv(*count, 0);
254
255 /* Check if we have come from an xor with a true right op */
256 if (type == 1)
257 value += 2;
258
259 NDEB(D(L, "%3d: Found %p\n", i, PL_op));
260 add_conditional(op, value);
261 }
262 }
263
264 av_clear(conds);
265
266 NDEB(D(L, "f is %p\n", f));
267
268 PL_op->op_ppaddr = f;
269 }
270 else
271 {
272 Perl_croak(aTHX_
273 "All is lost, I know not where to go from %p, %d: %p\n",
274 PL_op, PL_op->op_seq, sv);
275 }
276
277 Got_condition = 1;
278
279 return PL_op;
280 }
281
7a80026 @pjcj import Devel::Cover 0.21
authored
282 static void cover_cond()
692f58f @pjcj import Devel::Cover 0.01
authored
283 {
7a80026 @pjcj import Devel::Cover 0.21
authored
284 if (collecting(Branch))
285 {
286 dSP;
287 int val = SvTRUE(TOPs);
288 add_branch(PL_op, !val);
289 }
290 }
291
292 static void cover_logop()
293 {
294 /*
295 * For OP_AND, if the first operand is false, we have short
296 * circuited the second, otherwise the value of the and op is the
297 * value of the second operand.
298 *
299 * For OP_OR, if the first operand is true, we have short circuited
300 * the second, otherwise the value of the and op is the value of the
301 * second operand.
302 *
303 * We check the value of the first operand by simply looking on the
304 * stack. To check the second operand it is necessary to note the
305 * location of the next op after this logop. When we get there, we
306 * look at the stack and store the coverage information indexed to
307 * this op.
308 *
309 * This scheme also works for OP_XOR with a small modification
310 * because it doesn't short circuit. See the comment below.
311 *
312 * To find out when we get to the next op we change the op_ppaddr to
313 * point to get_condition(), which will do the necessary work and
314 * then reset and run the original op_ppaddr. We also store
315 * information in the Pending_conditionals hash. This is keyed on
316 * the op and the value is an array, the first element of which is
317 * the op_ppaddr we overwrote, and the subsequent elements are the
318 * ops about which we are collecting the condition coverage
319 * information. Note that an op may be collecting condition
320 * coverage information about a number of conditions.
321 */
322
323 if (!collecting(Condition))
324 return;
325
326 if (cLOGOP->op_first->op_type == OP_ITER)
327 {
328 /* loop - ignore it for now*/
329 }
330 else
331 {
332 dSP;
333 int left_val = SvTRUE(TOPs);
334 if (PL_op->op_type == OP_AND && left_val ||
335 PL_op->op_type == OP_ANDASSIGN && left_val ||
336 PL_op->op_type == OP_OR && !left_val ||
337 PL_op->op_type == OP_ORASSIGN && !left_val ||
338 PL_op->op_type == OP_XOR)
339 {
340 char *ch;
341 AV *conds;
342 SV **tmp,
343 *cond,
344 *ppaddr;
345 OP *next,
346 *right;
347
348 right = cLOGOP->op_first->op_sibling;
349 NDEB(op_dump(right));
350
351 if (right->op_type == OP_NEXT ||
352 right->op_type == OP_LAST ||
353 right->op_type == OP_REDO ||
ccdbd36 @pjcj import Devel::Cover 0.29
authored
354 right->op_type == OP_REDO ||
355 right->op_type == OP_GOTO ||
356 right->op_type == OP_RETURN)
7a80026 @pjcj import Devel::Cover 0.21
authored
357 {
358 /*
359 * If the right side of the op is a branch, we don't
360 * care what its value is - it won't be returning one.
361 * We're just glad to be here, so we chalk up success.
362 */
363
364 add_conditional(PL_op, 2);
365 }
366 else
367 {
368 if (PL_op->op_type == OP_XOR && left_val)
369 {
370 /*
371 * This is an xor. It does not short circuit. We
372 * have just executed the right op, rather than the
373 * left op as with and and or. When we get to next
374 * we will have already done the xor, so we can work
375 * out what the value of the left op was.
376 *
377 * We set a flag in the first element of the array
378 * to say that we had a true value from the right
379 * op.
380 */
381
382 set_conditional(PL_op, 0, 1);
383 }
384
385 NDEB(op_dump(PL_op));
386
387 next = PL_op->op_next;
388 ch = get_key(next);
389 tmp = hv_fetch(Pending_conditionals, ch, ch_sz, 1);
390
391 if (SvROK(*tmp))
392 conds = (AV *)SvRV(*tmp);
393 else
394 *tmp = newRV_inc((SV*) (conds = newAV()));
395
396 if (av_len(conds) < 0)
397 {
398 NDEB(D(L, "setting f to %p\n", next->op_ppaddr));
399 ppaddr = newSViv((IV) next->op_ppaddr);
400 av_push(conds, ppaddr);
401 }
402
403 cond = newSViv((IV) PL_op);
404 av_push(conds, cond);
405
406 NDEB(D(L, "Adding conditional %p to %d, making %d\n",
407 next, next->op_seq, av_len(conds)));
408 NDEB(svdump(Pending_conditionals));
409 NDEB(op_dump(PL_op));
410 NDEB(op_dump(next));
411
412 next->op_ppaddr = get_condition;
413 }
414 }
415 else
416 {
417 add_conditional(PL_op, 3);
418 }
419 }
420 }
692f58f @pjcj import Devel::Cover 0.01
authored
421
c8c4341 @pjcj import Devel::Cover 0.15
authored
422 #if CAN_PROFILE
7a80026 @pjcj import Devel::Cover 0.21
authored
423
424 static void cover_time()
425 {
426 SV **count;
bf1430b @pjcj import Devel::Cover 0.30
authored
427 NV c;
7a80026 @pjcj import Devel::Cover 0.21
authored
428 char *ch;
429
430 if (collecting(Time))
431 {
432 /*
433 * Profiling information is stored against Profiling_op, the one
434 * we have just run.
435 */
436
437 NDEB(D(L, "Cop at %p, op at %p, timing %p\n", PL_curcop, PL_op, Profiling_op));
438
439 if (Profiling_op)
440 {
441 ch = get_key(Profiling_op);
442 count = hv_fetch(Times, ch, ch_sz, 1);
bf1430b @pjcj import Devel::Cover 0.30
authored
443 c = (SvTRUE(*count) ? SvNV(*count) : 0) +
ccdbd36 @pjcj import Devel::Cover 0.29
authored
444 #if defined HAS_GETTIMEOFDAY
7a80026 @pjcj import Devel::Cover 0.21
authored
445 elapsed();
ccdbd36 @pjcj import Devel::Cover 0.29
authored
446 #else
447 cpu();
b6b6594 @pjcj import Devel::Cover 0.12
authored
448 #endif
bf1430b @pjcj import Devel::Cover 0.30
authored
449 sv_setnv(*count, c);
450 PDEB(D(L, "Adding time: sum %f at %p\n", c, Profiling_op));
7a80026 @pjcj import Devel::Cover 0.21
authored
451 }
452 Profiling_op = PL_op;
453 }
454 }
455
456 #endif
457
458 static int runops_cover(pTHX)
459 {
460 SV **count;
461 IV c;
462 char *ch;
e69ccba @pjcj import Devel::Cover 0.22
authored
463 HV *Files = 0;
7a80026 @pjcj import Devel::Cover 0.21
authored
464 int collecting_here = 1;
465 char *lastfile = 0;
b6b6594 @pjcj import Devel::Cover 0.12
authored
466
c8c4341 @pjcj import Devel::Cover 0.15
authored
467 NDEB(D(L, "runops_cover\n"));
692f58f @pjcj import Devel::Cover 0.01
authored
468
c8c4341 @pjcj import Devel::Cover 0.15
authored
469 if (!Cover_hv)
310cdad @pjcj import Devel::Cover 0.05
authored
470 {
c8c4341 @pjcj import Devel::Cover 0.15
authored
471 /* TODO - this probably leaks all over the place */
472
473 SV **tmp;
474
475 Cover_hv = newHV();
476
477 tmp = hv_fetch(Cover_hv, "statement", 9, 1);
478 Statements = newHV();
479 *tmp = newRV_inc((SV*) Statements);
480
481 tmp = hv_fetch(Cover_hv, "branch", 6, 1);
482 Branches = newHV();
483 *tmp = newRV_inc((SV*) Branches);
484
485 tmp = hv_fetch(Cover_hv, "condition", 9, 1);
486 Conditions = newHV();
487 *tmp = newRV_inc((SV*) Conditions);
488
489 #if CAN_PROFILE
490 tmp = hv_fetch(Cover_hv, "time", 4, 1);
491 Times = newHV();
492 *tmp = newRV_inc((SV*) Times);
493 #endif
494
495 Pending_conditionals = newHV();
496 }
497
ccdbd36 @pjcj import Devel::Cover 0.29
authored
498 #if defined HAS_GETTIMEOFDAY
7a80026 @pjcj import Devel::Cover 0.21
authored
499 elapsed();
ccdbd36 @pjcj import Devel::Cover 0.29
authored
500 #elif defined HAS_TIMES
501 cpu();
7a80026 @pjcj import Devel::Cover 0.21
authored
502 #endif
503
c8c4341 @pjcj import Devel::Cover 0.15
authored
504 for (;;)
505 {
c6cb737 @pjcj import Devel::Cover 0.18
authored
506 NDEB(D(L, "running func %p\n", PL_op->op_ppaddr));
507
508 if (Got_condition)
509 {
510 Got_condition = 0;
e69ccba @pjcj import Devel::Cover 0.22
authored
511 goto call_fptr;
c6cb737 @pjcj import Devel::Cover 0.18
authored
512 }
513
c8c4341 @pjcj import Devel::Cover 0.15
authored
514 if (!Covering)
e69ccba @pjcj import Devel::Cover 0.22
authored
515 goto call_fptr;
c8c4341 @pjcj import Devel::Cover 0.15
authored
516
517 /* Check to see whether we are interested in this file */
518
519 if (PL_op->op_type == OP_NEXTSTATE)
692f58f @pjcj import Devel::Cover 0.01
authored
520 {
c8c4341 @pjcj import Devel::Cover 0.15
authored
521 char *file = CopFILE(cCOP);
522 if (file && (!lastfile || lastfile && strNE(lastfile, file)))
523 {
e69ccba @pjcj import Devel::Cover 0.22
authored
524 if (!Files)
525 Files = get_hv("Devel::Cover::Files", FALSE);
c8c4341 @pjcj import Devel::Cover 0.15
authored
526 if (Files)
527 {
528 SV **f = hv_fetch(Files, file, strlen(file), 0);
529 collecting_here = f ? SvIV(*f) : 1;
530 NDEB(D(L, "File: %s [%d]\n", file, collecting_here));
531 }
532 lastfile = file;
533 }
b6b6594 @pjcj import Devel::Cover 0.12
authored
534 }
c8c4341 @pjcj import Devel::Cover 0.15
authored
535
536 if (!collecting_here)
7a80026 @pjcj import Devel::Cover 0.21
authored
537 {
538 #if CAN_PROFILE
539 cover_time();
540 Profiling_op = 0;
541 #endif
e69ccba @pjcj import Devel::Cover 0.22
authored
542 goto call_fptr;
7a80026 @pjcj import Devel::Cover 0.21
authored
543 }
544
545 /*
546 * We are about the run the op PL_op, so we'll collect
547 * information for it now.
548 */
c8c4341 @pjcj import Devel::Cover 0.15
authored
549
550 switch (PL_op->op_type)
551 {
552 case OP_SETSTATE:
553 case OP_NEXTSTATE:
554 case OP_DBSTATE:
555 {
556 #if CAN_PROFILE
7a80026 @pjcj import Devel::Cover 0.21
authored
557 cover_time();
c8c4341 @pjcj import Devel::Cover 0.15
authored
558 #endif
559 if (collecting(Statement))
560 {
7a80026 @pjcj import Devel::Cover 0.21
authored
561 ch = get_key(PL_op);
c8c4341 @pjcj import Devel::Cover 0.15
authored
562 count = hv_fetch(Statements, ch, ch_sz, 1);
563 c = SvTRUE(*count) ? SvIV(*count) + 1 : 1;
564 sv_setiv(*count, c);
565 NDEB(op_dump(PL_op));
566 }
567 break;
568 }
569
570 case OP_COND_EXPR:
571 {
7a80026 @pjcj import Devel::Cover 0.21
authored
572 cover_cond();
c8c4341 @pjcj import Devel::Cover 0.15
authored
573 break;
574 }
575
576 case OP_AND:
577 case OP_OR:
c6cb737 @pjcj import Devel::Cover 0.18
authored
578 case OP_ANDASSIGN:
579 case OP_ORASSIGN:
580 case OP_XOR:
c8c4341 @pjcj import Devel::Cover 0.15
authored
581 {
7a80026 @pjcj import Devel::Cover 0.21
authored
582 cover_logop();
c8c4341 @pjcj import Devel::Cover 0.15
authored
583 break;
584 }
585
586 default:
f9ee5ec @pjcj import Devel::Cover 0.20
authored
587 ; /* IBM's xlC compiler on AIX is very picky */
692f58f @pjcj import Devel::Cover 0.01
authored
588 }
e69ccba @pjcj import Devel::Cover 0.22
authored
589
590 call_fptr:
591 if (!(PL_op = CALL_FPTR(PL_op->op_ppaddr)(aTHX)))
592 {
593 #if CAN_PROFILE
594 cover_time();
595 #endif
596 break;
597 }
598
599 PERL_ASYNC_CHECK();
692f58f @pjcj import Devel::Cover 0.01
authored
600 }
601
602 TAINT_NOT;
603 return 0;
604 }
605
c8c4341 @pjcj import Devel::Cover 0.15
authored
606 static int runops_orig(pTHX)
69a8165 @pjcj import Devel::Cover 0.10
authored
607 {
c8c4341 @pjcj import Devel::Cover 0.15
authored
608 NDEB(D(L, "runops_orig\n"));
609
69a8165 @pjcj import Devel::Cover 0.10
authored
610 while ((PL_op = CALL_FPTR(PL_op->op_ppaddr)(aTHX)))
611 {
612 PERL_ASYNC_CHECK();
613 }
614
615 TAINT_NOT;
616 return 0;
617 }
618
7a80026 @pjcj import Devel::Cover 0.21
authored
619 #if 0
620 static void cv_destroy_cb(pTHX_ CV *cv)
621 {
622 SV *sv;
623 IV iv;
624 dSP;
625
626 PDEB(D(L, "cv_destroy_cb %p - %p\n", cv, Covering));
627
628 if (!Covering)
629 return;
630
631 ENTER;
632 SAVETMPS;
633
634 PUSHMARK(SP);
635
636 sv = sv_newmortal();
637 iv = PTR2IV(cv);
638 sv_setiv(newSVrv(sv, "B::CV"), iv);
639
640 XPUSHs(sv);
641 /* XPUSHs(sv_2mortal(newSViv(cv))); */
642
643 PUTBACK;
644
645 call_pv("Devel::Cover::get_cover_x", G_DISCARD);
646
647 FREETMPS;
648 LEAVE;
649
650 NDEB(svdump(cv));
651 }
652 #endif
653
692f58f @pjcj import Devel::Cover 0.01
authored
654 MODULE = Devel::Cover PACKAGE = Devel::Cover
655
656 PROTOTYPES: ENABLE
657
658 void
c8c4341 @pjcj import Devel::Cover 0.15
authored
659 set_criteria(flag)
660 unsigned flag
692f58f @pjcj import Devel::Cover 0.01
authored
661 PPCODE:
2152f1e @pjcj import Devel::Cover 0.14
authored
662 /* fprintf(stderr, "Cover set to %d\n", flag); */
c8c4341 @pjcj import Devel::Cover 0.15
authored
663 PL_runops = (Covering = flag) ? runops_cover : runops_orig;
b6b6594 @pjcj import Devel::Cover 0.12
authored
664
665 void
c8c4341 @pjcj import Devel::Cover 0.15
authored
666 add_criteria(flag)
667 unsigned flag
b6b6594 @pjcj import Devel::Cover 0.12
authored
668 PPCODE:
c8c4341 @pjcj import Devel::Cover 0.15
authored
669 PL_runops = (Covering |= flag) ? runops_cover : runops_orig;
692f58f @pjcj import Devel::Cover 0.01
authored
670
c8c4341 @pjcj import Devel::Cover 0.15
authored
671 void
672 remove_criteria(flag)
673 unsigned flag
674 PPCODE:
675 PL_runops = (Covering &= ~flag) ? runops_cover : runops_orig;
676
677 unsigned
678 get_criteria()
692f58f @pjcj import Devel::Cover 0.01
authored
679 CODE:
c8c4341 @pjcj import Devel::Cover 0.15
authored
680 RETVAL = Covering;
681 OUTPUT:
682 RETVAL
683
684 unsigned
685 coverage_none()
686 CODE:
687 RETVAL = None;
688 OUTPUT:
689 RETVAL
690
691 unsigned
692 coverage_statement()
693 CODE:
694 RETVAL = Statement;
695 OUTPUT:
696 RETVAL
697
698 unsigned
699 coverage_branch()
700 CODE:
701 RETVAL = Branch;
702 OUTPUT:
703 RETVAL
704
705 unsigned
706 coverage_condition()
707 CODE:
708 RETVAL = Condition;
709 OUTPUT:
710 RETVAL
711
712 unsigned
ffe2236 @pjcj import Devel::Cover 0.23
authored
713 coverage_subroutine()
714 CODE:
715 RETVAL = Subroutine;
716 OUTPUT:
717 RETVAL
718
719 unsigned
c8c4341 @pjcj import Devel::Cover 0.15
authored
720 coverage_path()
721 CODE:
722 RETVAL = Path;
723 OUTPUT:
724 RETVAL
725
726 unsigned
727 coverage_pod()
728 CODE:
729 RETVAL = Pod;
730 OUTPUT:
731 RETVAL
732
733 unsigned
734 coverage_time()
735 CODE:
736 RETVAL = Time;
737 OUTPUT:
738 RETVAL
739
740 unsigned
741 coverage_all()
742 CODE:
743 RETVAL = All;
744 OUTPUT:
745 RETVAL
b6b6594 @pjcj import Devel::Cover 0.12
authored
746
747 SV *
c8c4341 @pjcj import Devel::Cover 0.15
authored
748 coverage()
b6b6594 @pjcj import Devel::Cover 0.12
authored
749 CODE:
750 ST(0) = sv_newmortal();
c8c4341 @pjcj import Devel::Cover 0.15
authored
751 if (Cover_hv)
752 sv_setsv(ST(0), newRV_inc((SV*) Cover_hv));
692f58f @pjcj import Devel::Cover 0.01
authored
753 else
754 ST(0) = &PL_sv_undef;
755
756 BOOT:
ccdbd36 @pjcj import Devel::Cover 0.29
authored
757 /* PL_runops = runops_orig; */
7a80026 @pjcj import Devel::Cover 0.21
authored
758 /* PL_savebegin = TRUE; */
759 /* PL_savecheck = TRUE; */
760 /* PL_saveinit = TRUE; */
761 /* PL_saveend = TRUE; */
762 /* PL_cv_destroy_cb = cv_destroy_cb; */
Something went wrong with that request. Please try again.