linecache19 0.5.11 → 0.5.12

Sign up to get free protection for your applications and to get access to all the features.
@@ -12,8 +12,7 @@ else
12
12
  end
13
13
 
14
14
  hdrs = proc {
15
- have_header("vm_core.h") and have_header("version.h") and
16
- have_macro("RUBY_VERSION_MAJOR", "version.h")
15
+ have_header("vm_core.h") and have_header("version.h")
17
16
  }
18
17
 
19
18
  dir_config("ruby")
@@ -2,7 +2,6 @@
2
2
  Ruby 1.9 version: (7/20/2009, Mark Moseley, mark@fast-software.com)
3
3
 
4
4
  Now works with Ruby-1.9.1. Tested with p129 and p243.
5
- Old code remains and is #ifdef'd around.
6
5
 
7
6
  This does not (and can not) function identically to the 1.8 version.
8
7
  Line numbers are ordered differently. But ruby-debug doesn't seem
@@ -16,773 +15,27 @@ Ruby 1.9 version: (7/20/2009, Mark Moseley, mark@fast-software.com)
16
15
  Walking the iseq tree and decoding each instruction is pretty hairy,
17
16
  though, so until I have a really compelling reason to go that route,
18
17
  I'll leave it at this.
19
-
20
- My first stab at this walked the nodes, like before, but there's no
21
- NODE_NEWLINE node types any more. So I just output all line numbers
22
- that came in, regardless of the node type, and then sorted it and
23
- removed dups. The problem with that approach is that Ruby 1.9 is not
24
- consistently sending the debugger hook RUBY_EVENT_LINE messages for
25
- all lines. In particular:
26
-
27
- 1: def foo
28
- 2: a = 5
29
- 3: return a
30
- 4: end
31
-
32
- The disassembly of this code doesn't have a RUBY_EVENT_LINE trace
33
- message for line 3; it has it only for lines 1 and 2. Oddly, if you
34
- remove the "return", leaving just "a" on line 3, then you'll get the
35
- trace message.
36
-
37
- So the advantage of this approach is that ruby-debug won't let you
38
- set a breakpoint on lines that don't get the trace message. I think
39
- it would be more confusing to be allowed to set a breakpoint, and
40
- never break when the line does get hit, than to be prevented to set
41
- the breakpoint in the first place even when you should be able to.
42
-
43
- Ruby 1.8 version:
44
-
45
- This code creates module TraceLineNumbers with one method
46
- lnums_for_str. lnums_for_str returns an array lines for which
47
- RUBY_EVENT_LINE can be called on. In other words, the line numbers
48
- that can be traced (such as via Tracer) or stopped at in a
49
- debugger (such as ruby-debug).
50
-
51
- This code has been tested on Ruby 1.8.6; it does not work on Ruby
52
- 1.9.x. The code was created via culling from various sources.
53
-
54
- Ruby 1.8's eval.c, and rb_eval() in particular, is the definitive
55
- source of how the tree is evaluated. However we don't want to
56
- actually evaluate the code, which simplifies things. In contrast,
57
- we need lines for all branches, and not just the ones that get
58
- executed on a given run. For example in an "if" node the "then"
59
- part may or may not get executed, but we want to get the trace line
60
- numbers for the "then" part regardless.
61
-
62
- Code enclosed in the ***'s contains code from eval.c which is
63
- included for comparison.
64
-
65
- Also parse.y from Ruby 1.8 can shed light on how the nodes get
66
- created.
67
-
68
- Some legacy code in ParseTree is similar and necessarily more
69
- complex. We would have used that gem from the outside and lived
70
- with the additional bloat were it not broken for our purposes and
71
- were it not for the author's lack of interest in extending it to
72
- handle what's needed here.
73
-
74
- Finally, node_help.txt from nodewrap contains descriptions of many
75
- of the node types.
76
18
  */
77
19
  #include <ruby.h>
78
20
  #include <version.h>
79
- #if RUBY_VERSION_MAJOR == 1 && RUBY_VERSION_MINOR == 8
80
- #define RUBY_VERSION_1_8
81
- #include <node.h>
82
- #include <rubysig.h>
83
- #else
84
21
  #include <vm_core.h>
85
- #endif
86
22
  #include "trace_nums.h"
87
23
 
88
24
  VALUE mTraceLineNumbers;
89
25
 
90
- #ifdef RUBY_VERSION_1_8
91
- RUBY_EXTERN NODE *ruby_eval_tree_begin;
92
- RUBY_EXTERN int ruby_in_eval;
93
-
94
- #define nd_3rd u3.node
95
-
96
- extern struct FRAME {
97
- VALUE self;
98
- int argc;
99
- ID last_func;
100
- ID orig_func;
101
- VALUE last_class;
102
- struct FRAME *prev;
103
- struct FRAME *tmp;
104
- struct RNode *node;
105
- int iter;
106
- int flags;
107
- unsigned long uniq;
108
- } *ruby_frame;
109
-
110
- struct METHOD {
111
- VALUE klass, rklass;
112
- VALUE recv;
113
- ID id, oid;
114
- #if RUBY_VERSION_CODE > 182
115
- int safe_level;
116
- #endif
117
- NODE *body;
118
- };
119
-
120
- struct BLOCK {
121
- NODE *var;
122
- NODE *body;
123
- VALUE self;
124
- struct FRAME frame;
125
- struct SCOPE *scope;
126
- VALUE klass;
127
- NODE *cref;
128
- int iter;
129
- int vmode;
130
- int flags;
131
- int uniq;
132
- struct RVarmap *dyna_vars;
133
- VALUE orig_thread;
134
- VALUE wrapper;
135
- VALUE block_obj;
136
- struct BLOCK *outer;
137
- struct BLOCK *prev;
138
- };
139
- #endif /* RUBY_VERSION_1_8 */
140
-
141
- #define RETURN \
142
- goto finish
143
-
144
- #define EVENT_LINE(node) \
145
- rb_ary_push(ary, INT2NUM(nd_line(node)))
146
-
147
- #ifdef FINISHED
148
- #define EVENT_CALL(node) \
149
- rb_ary_push(ary, INT2NUM(nd_line(node)))
150
- #else
151
- #define EVENT_CALL(node)
152
- #endif
153
-
154
- /* Used just in debugging. */
155
- static int indent_level = 0;
156
-
157
- #ifdef RUBY_VERSION_1_8
158
- static
159
- void ln_eval(VALUE self, NODE * n, VALUE ary) {
160
- NODE * volatile contnode = 0;
161
- NODE * volatile node = n;
162
-
163
- if (RTEST(ruby_debug)) {
164
- char fmt[30] = { '\0', };
165
- snprintf(fmt, sizeof(fmt), "%%%ds", indent_level+1);
166
- fprintf(stderr, fmt, "[");
167
- indent_level += 2;
168
- }
169
-
170
- again:
171
- if (!node) RETURN;
172
-
173
- if (RTEST(ruby_debug)) {
174
- NODE *r = RNODE(node); /* For debugging */
175
- fprintf(stderr, "%s ", NODE2NAME[nd_type(node)]);
176
- }
177
-
178
- switch (nd_type(node)) {
179
- case NODE_BLOCK:
180
- while (node) {
181
- ln_eval(self, node->nd_head, ary);
182
- node = node->nd_next;
183
- }
184
-
185
- case NODE_POSTEXE: /* END { ... } */
186
- /* Nothing to do here... we are in an iter block */
187
- /***
188
- rb_f_END();
189
- nd_set_type(node, NODE_NIL); /+ exec just once +/
190
- result = Qnil;
191
- ***/
192
- break;
193
-
194
- /* begin .. end without clauses */
195
- case NODE_BEGIN:
196
- /* node for speed-up(top-level loop for -n/-p) */
197
- node = node->nd_body;
198
- goto again;
199
-
200
- /* nodes for speed-up(default match) */
201
- case NODE_MATCH:
202
- /* result = rb_reg_match2(node->nd_lit); */
203
- break;
204
-
205
- /* nodes for speed-up(literal match) */
206
- case NODE_MATCH2:
207
- /* l = */ ln_eval(self, node->nd_recv, ary);
208
- /* r = */ ln_eval(self, node->nd_value, ary);
209
- /*** result = rb_reg_match(l, r); ***/
210
- break;
211
-
212
- /* nodes for speed-up(literal match) */
213
- case NODE_MATCH3: /* z =~ /"#{var}"/ for example */
214
- /* r = */ ln_eval(self, node->nd_recv, ary);
215
- /* l = */ ln_eval(self, node->nd_value, ary);
216
- /***
217
- if (TYPE(l) == T_STRING) {
218
- result = rb_reg_match(r, l);
219
- }
220
- else {
221
- // It is possible that value can be a function call which
222
- // can trigger an call event. So to be conservative,
223
- // we have to add a line number here.
224
- result = rb_funcall(l, match, 1, r);
225
- }
226
- ****/
227
- EVENT_CALL(node);
228
- break;
229
-
230
- /* node for speed-up(top-level loop for -n/-p) */
231
- case NODE_OPT_N:
232
- /* Lots of ugliness in eval.c. */
233
- ln_eval(self, node->nd_body, ary);
234
- break;
235
-
236
- /* These nodes are empty. */
237
- case NODE_SELF:
238
- case NODE_NIL:
239
- case NODE_TRUE:
240
- case NODE_FALSE:
241
- RETURN /* (something) */;
242
-
243
- case NODE_IF:
244
- EVENT_LINE(node);
245
- ln_eval(self, node->nd_cond, ary);
246
- if (node->nd_body) {
247
- if (!node->nd_else) {
248
- node = node->nd_body;
249
- goto again;
250
- }
251
- ln_eval(self, node->nd_body, ary);
252
- }
253
- if (node->nd_else) {
254
- node = node->nd_else;
255
- goto again;
256
- }
257
- break;
258
-
259
- case NODE_WHEN:
260
- {
261
- NODE *orig_node = node;
262
- while (node) {
263
- NODE *tag;
264
-
265
- if (nd_type(node) != NODE_WHEN) goto again;
266
- tag = node->nd_head;
267
- while (tag) {
268
- EVENT_LINE(tag);
269
- if (tag->nd_head && nd_type(tag->nd_head) == NODE_WHEN) {
270
- ln_eval(self, tag->nd_head->nd_head, ary);
271
- }
272
- tag = tag->nd_next;
273
- }
274
- node = node->nd_next;
275
- }
276
- if (orig_node->nd_body) {
277
- ln_eval(self, orig_node->nd_body, ary); /* body */
278
- }
279
- RETURN /***(Qnil)***/ ;
280
- }
281
-
282
- case NODE_CASE:
283
- ln_eval(self, node->nd_head, ary); /* expr */
284
- node = node->nd_body;
285
- while (node) {
286
- NODE *tag;
287
- if (nd_type(node) != NODE_WHEN) {
288
- goto again;
289
- }
290
- tag = node->nd_head;
291
- while (tag) {
292
- EVENT_LINE(tag);
293
- if (tag->nd_head && nd_type(tag->nd_head) == NODE_WHEN) {
294
- ln_eval(self, tag->nd_head->nd_head, ary);
295
- tag = tag->nd_next;
296
- continue;
297
- }
298
- ln_eval(self, tag->nd_head, ary);
299
- tag = tag->nd_next;
300
- }
301
- ln_eval(self, node->nd_body, ary);
302
- node = node->nd_next;
303
- }
304
- RETURN /***(Qnil)***/;
305
-
306
- case NODE_WHILE:
307
- case NODE_UNTIL:
308
- /* Doesn't follow eval.c */
309
- ln_eval(self, node->nd_cond, ary);
310
- if (node->nd_body) {
311
- ln_eval(self, node->nd_body, ary);
312
- }
313
- break;
314
-
315
- case NODE_BLOCK_PASS:
316
- /*** result = block_pass(self, node); ***/
317
- ln_eval(self, node->nd_body, ary);
318
- ln_eval(self, node->nd_iter, ary);
319
- break;
320
-
321
- case NODE_ITER:
322
- case NODE_FOR:
323
- ln_eval(self, node->nd_iter, ary);
324
- if (node->nd_var != (NODE *)1
325
- && node->nd_var != (NODE *)2
326
- && node->nd_var != NULL) {
327
- ln_eval(self, node->nd_var, ary);
328
- }
329
- node = node->nd_body;
330
- goto again;
331
-
332
- case NODE_BREAK:
333
- /* break_jump(rb_eval(self, node->nd_stts)); */
334
- ln_eval(self, node->nd_stts, ary);
335
- break;
336
-
337
- case NODE_NEXT:
338
- /*** CHECK_INTS;
339
- next_jump(rb_eval(self, node->nd_stts)); ***/
340
- ln_eval(self, node->nd_stts, ary);
341
- break;
342
-
343
- case NODE_REDO:
344
- /*** CHECK_INTS;
345
- JUMP_TAG(TAG_REDO); ***/
346
- break;
347
-
348
- case NODE_RETRY:
349
- /*** CHECK_INTS;
350
- JUMP_TAG(TAG_RETRY); ***/
351
- break;
352
-
353
- case NODE_SPLAT:
354
- /*** result = splat_value(rb_eval(self, node->nd_head)); ***/
355
- ln_eval(self, node->nd_head, ary);
356
- break;
357
-
358
- case NODE_TO_ARY:
359
- /*** result = rb_ary_to_ary(rb_eval(self, node->nd_head)); ***/
360
- ln_eval(self, node->nd_head, ary);
361
- break;
362
-
363
- case NODE_SVALUE: /* a = b, c */
364
- /***
365
- result = avalue_splat(rb_eval(self, node->nd_head));
366
- if (result == Qundef) result = Qnil; ***/
367
- ln_eval(self, node->nd_head, ary);
368
- break;
369
-
370
- case NODE_YIELD:
371
- if (node->nd_head) {
372
- /*** result = rb_eval(self, node->nd_head);
373
- ruby_current_node = node; else ... ***/
374
- ln_eval(self, node->nd_head, ary);
375
- }
376
- break;
377
-
378
- case NODE_RESCUE:
379
- /* Follow ruby_parse.rb and pray for the best. */
380
- ln_eval(self, node->nd_1st, ary);
381
- ln_eval(self, node->nd_2nd, ary);
382
- ln_eval(self, node->nd_3rd, ary);
383
- break;
384
-
385
- case NODE_ENSURE:
386
- ln_eval(self, node->nd_head, ary);
387
- if (node->nd_ensr) {
388
- ln_eval(self, node->nd_ensr, ary);
389
- }
390
- break;
391
-
392
- case NODE_AND:
393
- case NODE_OR:
394
- ln_eval(self, node->nd_1st, ary);
395
- ln_eval(self, node->nd_2nd, ary);
396
- break;
397
-
398
- case NODE_NOT:
399
- /*** if (RTEST(rb_eval(self, node->nd_body))) result = Qfalse;
400
- else result = Qtrue; ***/
401
- ln_eval(self, node->nd_body, ary);
402
- break;
403
-
404
- case NODE_DOT2:
405
- case NODE_DOT3:
406
- case NODE_FLIP2:
407
- case NODE_FLIP3:
408
- ln_eval(self, node->nd_beg, ary);
409
- ln_eval(self, node->nd_end, ary);
410
- break;
411
-
412
- case NODE_RETURN:
413
- if (node->nd_stts)
414
- ln_eval(self, node->nd_stts, ary);
415
- break;
416
-
417
- case NODE_ARGSCAT:
418
- case NODE_ARGSPUSH:
419
- ln_eval(self, node->nd_head, ary);
420
- ln_eval(self, node->nd_body, ary);
421
- break;
422
-
423
- case NODE_ATTRASGN: /* literal.meth = y u1 u2 u3 */
424
- /* node id node */
425
- if (node->nd_recv == (NODE *)1) {
426
- ln_eval(self, NEW_SELF(), ary);
427
- } else {
428
- ln_eval(self, node->nd_recv, ary);
429
- }
430
- ln_eval(self, node->nd_3rd, ary);
431
- break;
432
- case NODE_CALL:
433
- case NODE_FCALL:
434
- case NODE_VCALL:
435
- if (nd_type(node) != NODE_FCALL)
436
- ln_eval(self, node->nd_recv, ary);
437
- if (node->nd_args || nd_type(node) != NODE_FCALL)
438
- ln_eval(self, node->nd_args, ary);
439
- break;
440
-
441
- case NODE_SUPER:
442
- ln_eval(self, node->nd_args, ary);
443
- break;
444
-
445
- case NODE_ZSUPER:
446
- break;
447
-
448
- case NODE_SCOPE:
449
- ln_eval(self, node->nd_next, ary);
450
- break;
451
-
452
- case NODE_OP_ASGN1:
453
- ln_eval(self, node->nd_recv, ary);
454
- #if RUBY_VERSION_CODE < 185
455
- ln_eval(self, node->nd_args->nd_next, ary);
456
- #else
457
- ln_eval(self, node->nd_args->nd_2nd, ary);
458
- #endif
459
- ln_eval(self, node->nd_args->nd_head, ary);
460
- break;
461
-
462
- case NODE_OP_ASGN2:
463
- ln_eval(self, node->nd_recv, ary);
464
- ln_eval(self, node->nd_value, ary);
465
- break;
466
-
467
- case NODE_OP_ASGN_AND:
468
- case NODE_OP_ASGN_OR:
469
- ln_eval(self, node->nd_head, ary);
470
- ln_eval(self, node->nd_value, ary);
471
- break;
472
-
473
- case NODE_MASGN:
474
- ln_eval(self, node->nd_head, ary);
475
- if (node->nd_args) {
476
- if (node->nd_args != (NODE *)-1) {
477
- ln_eval(self, node->nd_args, ary);
478
- }
479
- }
480
- ln_eval(self, node->nd_value, ary);
481
- break;
482
-
483
- case NODE_LASGN:
484
- case NODE_DASGN:
485
- case NODE_DASGN_CURR:
486
- case NODE_GASGN:
487
- case NODE_IASGN:
488
- case NODE_CDECL:
489
- case NODE_CVDECL:
490
- case NODE_CVASGN:
491
- ln_eval(self, node->nd_value, ary);
492
- break;
493
-
494
- case NODE_LVAR:
495
- case NODE_DVAR:
496
- case NODE_GVAR:
497
- case NODE_IVAR:
498
- case NODE_CONST:
499
- case NODE_CVAR:
500
- break;
501
-
502
- case NODE_BLOCK_ARG: /* u1 u3 (def x(&b) */
503
- break;
504
-
505
- case NODE_COLON2:
506
- ln_eval(self, node->nd_head, ary);
507
- break;
508
-
509
- case NODE_COLON3: /* u2 (::OUTER_CONST) */
510
- break;
511
-
512
- case NODE_NTH_REF: /* u2 u3 ($1) - u3 is local_cnt('~') ignorable? */
513
- break;
514
-
515
- case NODE_BACK_REF: /* u2 u3 ($& etc) */
516
- break;
517
-
518
- case NODE_HASH:
519
- {
520
- NODE *list;
521
- list = node->nd_head;
522
- while (list) {
523
- ln_eval(self, list->nd_head, ary);
524
- list = list->nd_next;
525
- if (list == 0)
526
- rb_bug("odd number list for Hash");
527
- ln_eval(self, list->nd_head, ary);
528
- list = list->nd_next;
529
- }
530
- }
531
- break;
532
-
533
- case NODE_ZARRAY:
534
- break;
535
-
536
- case NODE_ARRAY:
537
- {
538
- long int i = node->nd_alen;
539
- for (i=0; node; node=node->nd_next) {
540
- ln_eval(self, node->nd_head, ary);
541
- }
542
- }
543
- break;
544
-
545
- case NODE_STR: /* u1 */
546
- break;
547
-
548
- case NODE_EVSTR: /* eval of a string */
549
- ln_eval(self, node->nd_2nd, ary);
550
- break;
551
-
552
- case NODE_DSTR:
553
- case NODE_DXSTR:
554
- case NODE_DREGX:
555
- case NODE_DREGX_ONCE:
556
- case NODE_DSYM:
557
- {
558
- NODE *list = node->nd_next;
559
- while (list) {
560
- if (list->nd_head) {
561
- switch (nd_type(list->nd_head)) {
562
- case NODE_STR:
563
- ln_eval(self, list->nd_head, ary);
564
- break;
565
- case NODE_EVSTR:
566
- ln_eval(self, list->nd_head, ary);
567
- break;
568
- default:
569
- ln_eval(self, list->nd_head, ary);
570
- break;
571
- }
572
- }
573
- list = list->nd_next;
574
- }
575
- }
576
- break;
577
-
578
- case NODE_XSTR: /* u1 (%x{ls}) */
579
- /* Issues rb_funcall(self, '`'...). So I think we have to
580
- register a call event. */
581
- EVENT_CALL(node);
582
- break;
583
-
584
- case NODE_LIT:
585
- break;
586
-
587
- case NODE_DEFN:
588
- ln_eval(self, node->nd_defn, ary);
589
- break;
590
-
591
- case NODE_DEFS:
592
- if (node->nd_defn) {
593
- ln_eval(self, node->nd_recv, ary);
594
- }
595
- ln_eval(self, node->nd_defn, ary);
596
- break;
597
-
598
- case NODE_UNDEF: /* u2 (undef name, ...) */
599
- #if RUBY_VERSION_CODE >= 185
600
- /*** ...
601
- rb_undef(ruby_class, rb_to_id(rb_eval(self, node->u2.node)));
602
- ...
603
- ***/
604
- ln_eval(self, node->u2.node, ary);
605
- #endif
606
- break;
607
-
608
- case NODE_ALIAS: /* u1 u2 (alias :blah :blah2) */
609
- #if RUBY_VERSION_CODE >= 185
610
- ln_eval(self, node->nd_1st, ary);
611
- ln_eval(self, node->nd_2nd, ary);
612
- #endif
613
- break;
614
- case NODE_VALIAS: /* u1 u2 (alias $global $global2) */
615
- break;
616
-
617
- case NODE_CLASS:
618
- if (node->nd_super) {
619
- ln_eval(self, node->nd_super, ary);
620
- }
621
- ln_eval(self, node->nd_body, ary);
622
- break;
623
-
624
- case NODE_MODULE:
625
- ln_eval(self, node->nd_body, ary);
626
- break;
627
-
628
- case NODE_SCLASS:
629
- ln_eval(self, node->nd_recv, ary);
630
- ln_eval(self, node->nd_body, ary);
631
- break;
632
-
633
- case NODE_DEFINED:
634
- ln_eval(self, node->nd_head, ary);
635
- break;
636
-
637
- case NODE_NEWLINE:
638
- EVENT_LINE(node);
639
- node = node->nd_next;
640
- goto again;
641
-
642
- case NODE_CFUNC:
643
- case NODE_IFUNC:
644
- break;
645
-
646
- #if RUBY_VERSION_CODE >= 190
647
- case NODE_ERRINFO:
648
- case NODE_VALUES:
649
- case NODE_PRELUDE:
650
- case NODE_LAMBDA:
651
- rb_warn("Ruby 1.9 is very different. You shouldn't have gotten here.");
652
- break;
653
- #endif
654
-
655
- case NODE_BMETHOD: /* define_method (or rb_mod_define_method) with a block */
656
- {
657
- struct BLOCK *data;
658
- Data_Get_Struct(node->nd_cval, struct BLOCK, data);
659
- if (!(data->var == 0 || data->var == (NODE *)1 ||
660
- data->var == (NODE *)2)) {
661
- /* block doesn't have args. */
662
- ln_eval(self, data->var, ary);
663
- }
664
- ln_eval(self, data->body, ary);
665
- break;
666
- }
667
- break;
668
-
669
- #if RUBY_VERSION_CODE < 190
670
- case NODE_DMETHOD:
671
- {
672
- struct METHOD *data;
673
- Data_Get_Struct(node->nd_cval, struct METHOD, data);
674
- ln_eval(self, data->body, ary);
675
- break;
676
- }
677
- #endif
678
-
679
- case NODE_METHOD:
680
- ln_eval(self, node->nd_3rd, ary);
681
- break;
682
-
683
-
684
- case NODE_ARGS: {
685
- if (node->nd_opt) {
686
- ln_eval(self, node->nd_opt, ary);
687
- }
688
- } break;
689
-
690
- case NODE_ATTRSET:
691
- break;
692
-
693
- /*
694
- // rescue body:
695
- // begin stmt rescue exception => var; stmt; [rescue e2 => v2; s2;]* end
696
- // stmt rescue stmt
697
- // a = b rescue c
698
- // NODE_RESBODY doesn't appear in 1.8.6's rb_eval
699
- */
700
- case NODE_RESBODY:
701
- if (node->nd_3rd) {
702
- ln_eval(self, node->nd_3rd, ary);
703
- }
704
- ln_eval(self, node->nd_2nd, ary);
705
- ln_eval(self, node->nd_1st, ary);
706
- break;
707
-
708
- /* Nodes we found but have yet to decypher */
709
- /* I think these are all runtime only... not positive but... */
710
- case NODE_MEMO: /* enum.c zip */
711
- case NODE_CREF:
712
- /* #defines: */
713
- /* case NODE_LMASK: */
714
- /* case NODE_LSHIFT: */
715
-
716
- default:
717
- rb_warn("Unhandled node '%s'", NODE2NAME[nd_type(node)]);
718
- if (RNODE(node)->u1.node != NULL) rb_warning("unhandled u1 value");
719
- if (RNODE(node)->u2.node != NULL) rb_warning("unhandled u2 value");
720
- if (RNODE(node)->u3.node != NULL) rb_warning("unhandled u3 value");
721
- if (RTEST(ruby_debug))
722
- fprintf(stderr, "u1 = %p u2 = %p u3 = %p\n",
723
- (void*)node->nd_1st, (void*)node->nd_2nd, (void*)node->nd_3rd);
724
- break;
725
- }
726
- finish:
727
- if (contnode) {
728
- node = contnode;
729
- contnode = 0;
730
- goto again;
731
- }
732
- if (RTEST(ruby_debug)) {
733
- char fmt[30] = { '\0', };
734
- indent_level -= 2;
735
- snprintf(fmt, sizeof(fmt), "%%%ds", indent_level+1);
736
- fprintf(stderr, fmt, "]\n");
737
- }
738
-
739
- } /* ln_eval */
740
- #endif /* RUBY_VERSION_1_8 */
741
-
742
26
  /* Return a list of trace hook line numbers for the string in Ruby source src*/
743
27
  static VALUE
744
- lnums_for_str(VALUE self, VALUE src) {
28
+ lnums_for_str(VALUE self, VALUE src)
29
+ {
745
30
  VALUE result = rb_ary_new(); /* The returned array of line numbers. */
746
- #ifdef RUBY_VERSION_1_8
747
- NODE *node = NULL;
748
- int critical;
749
- #else
750
31
  int len;
751
32
  char *token;
752
33
  char *disasm;
753
34
  rb_thread_t *th;
754
35
  VALUE iseqval;
755
36
  VALUE disasm_val;
756
- #endif
757
37
 
758
38
  StringValue(src); /* Check that src is a string. */
759
-
760
- if (RTEST(ruby_debug)) {
761
- indent_level = 0;
762
- }
763
-
764
- #ifdef RUBY_VERSION_1_8
765
- ruby_nerrs = 0;
766
- critical = rb_thread_critical;
767
- rb_thread_critical = Qtrue;
768
-
769
- /* Making ruby_in_eval nonzero signals rb_compile_string not to save
770
- source in SCRIPT_LINES__. */
771
- ruby_in_eval++;
772
- node = rb_compile_string("(numbers_for_str)", src, 1);
773
- ruby_in_eval--;
774
-
775
- rb_thread_critical = critical;
776
-
777
- if (ruby_nerrs > 0) {
778
- ruby_nerrs = 0;
779
- ruby_eval_tree_begin = 0;
780
- rb_exc_raise(ruby_errinfo);
781
- }
782
-
783
- ln_eval(self, node, result);
784
-
785
- #else
786
39
  th = GET_THREAD();
787
40
 
788
41
  /* First compile to bytecode, using the method in eval_string_with_cref() in vm_eval.c */
@@ -800,8 +53,8 @@ lnums_for_str(VALUE self, VALUE src) {
800
53
  disasm = (char*)malloc(strlen(RSTRING_PTR(disasm_val))+1);
801
54
  strcpy(disasm, RSTRING_PTR(disasm_val));
802
55
 
803
- for (token = strtok(disasm, "\n"); token != NULL; token = strtok(NULL, "\n")) {
804
-
56
+ for (token = strtok(disasm, "\n"); token != NULL; token = strtok(NULL, "\n"))
57
+ {
805
58
  /* look only for lines tracing RUBY_EVENT_LINE (1) */
806
59
  if (strstr(token, "trace 1 ") == NULL)
807
60
  continue;
@@ -812,7 +65,8 @@ lnums_for_str(VALUE self, VALUE src) {
812
65
  if ((token[len] == '(') || (token[len] == ' '))
813
66
  continue;
814
67
 
815
- for (; len > 0; len--) {
68
+ for (; len > 0; len--)
69
+ {
816
70
  if (token[len] == ' ')
817
71
  continue;
818
72
  if ((token[len] >= '0') && (token[len] <= '9'))
@@ -822,13 +76,9 @@ lnums_for_str(VALUE self, VALUE src) {
822
76
 
823
77
  break;
824
78
  }
825
-
826
79
  }
827
80
 
828
81
  free(disasm);
829
-
830
- #endif
831
-
832
82
  return result;
833
83
  }
834
84
 
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: linecache19
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.11
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 5
8
+ - 12
9
+ version: 0.5.12
5
10
  platform: ruby
6
11
  authors:
7
12
  - R. Bernstein
@@ -10,19 +15,24 @@ autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
17
 
13
- date: 2009-08-24 00:00:00 -07:00
18
+ date: 2011-04-02 00:00:00 -08:00
14
19
  default_executable:
15
20
  dependencies:
16
21
  - !ruby/object:Gem::Dependency
17
22
  name: ruby_core_source
18
- type: :runtime
19
- version_requirement:
20
- version_requirements: !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
21
26
  requirements:
22
27
  - - ">="
23
28
  - !ruby/object:Gem::Version
29
+ segments:
30
+ - 0
31
+ - 1
32
+ - 4
24
33
  version: 0.1.4
25
- version:
34
+ type: :runtime
35
+ version_requirements: *id001
26
36
  description: |
27
37
  Linecache is a module for reading and caching lines. This may be useful for
28
38
  example in a debugger where the same lines are shown many times.
@@ -53,6 +63,8 @@ files:
53
63
  - test/lnum-diag.rb
54
64
  - test/parse-show.rb
55
65
  - test/rcov-bug.rb
66
+ - test/test-linecache.rb
67
+ - test/test-tracelines.rb
56
68
  has_rdoc: true
57
69
  homepage: http://rubyforge.org/projects/ruby-debug19
58
70
  licenses: []
@@ -63,21 +75,27 @@ rdoc_options:
63
75
  require_paths:
64
76
  - lib
65
77
  required_ruby_version: !ruby/object:Gem::Requirement
78
+ none: false
66
79
  requirements:
67
80
  - - ">="
68
81
  - !ruby/object:Gem::Version
69
- version: 1.8.2
70
- version:
82
+ segments:
83
+ - 1
84
+ - 9
85
+ - 2
86
+ version: 1.9.2
71
87
  required_rubygems_version: !ruby/object:Gem::Requirement
88
+ none: false
72
89
  requirements:
73
90
  - - ">="
74
91
  - !ruby/object:Gem::Version
92
+ segments:
93
+ - 0
75
94
  version: "0"
76
- version:
77
95
  requirements: []
78
96
 
79
97
  rubyforge_project: ruby-debug19
80
- rubygems_version: 1.3.4
98
+ rubygems_version: 1.3.7
81
99
  signing_key:
82
100
  specification_version: 3
83
101
  summary: Read file with caching