Module: TraceLineNumbers

Defined in:
lib/tracelines19.rb,
ext/trace_nums/trace_nums.c

Overview

require ‘ruby-debug’ ; Debugger.start(:post-mortem => true)

Constant Summary collapse

@@SRC_DIR =
File.expand_path(File.dirname(__FILE__))

Class Method Summary collapse

Class Method Details

.lnums_for_file(file) ⇒ Object

Return an array of lines numbers that could be stopped at given a file name of a Ruby program.



17
18
19
# File 'lib/tracelines19.rb', line 17

def lnums_for_file(file)
  lnums_for_str(File.read(file))
end

.lnums_for_str(src) ⇒ Object

Return a list of trace hook line numbers for the string in Ruby source src



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'ext/trace_nums/trace_nums.c', line 27

static VALUE 
lnums_for_str(VALUE self, VALUE src)
{
  VALUE result = rb_ary_new(); /* The returned array of line numbers. */
  int len;
  char *token;
  char *disasm;
  rb_thread_t *th;
  VALUE iseqval;
  VALUE disasm_val;

  StringValue(src); /* Check that src is a string. */
  th = GET_THREAD();

  /* First compile to bytecode, using the method in eval_string_with_cref() in vm_eval.c */
  th->parse_in_eval++;
  th->mild_compile_error++;
  iseqval = rb_iseq_compile(src, rb_str_new_cstr("(numbers_for_str)"), INT2FIX(1));
  th->mild_compile_error--;
  th->parse_in_eval--;

  /* Disassemble the bytecode into text and parse into lines */
  disasm_val = rb_iseq_disasm(iseqval);
  if (disasm_val == Qnil)
    return(result);

  disasm = (char*)malloc(strlen(RSTRING_PTR(disasm_val))+1);
  strcpy(disasm, RSTRING_PTR(disasm_val));

  for (token = strtok(disasm, "\n"); token != NULL; token = strtok(NULL, "\n")) 
  {
    /* look only for lines tracing RUBY_EVENT_LINE (1) */
    if (strstr(token, "trace            1 ") == NULL)
      continue;
    len = strlen(token) - 1;
    if (token[len] != ')') 
      continue;
    len--;
    if ((token[len] == '(') || (token[len] == ' '))
      continue;
      
    for (; len > 0; len--)
    {
      if (token[len] == ' ') 
        continue;
      if ((token[len] >= '0') && (token[len] <= '9')) 
        continue;
      if (token[len] == '(')
        rb_ary_push(result, INT2NUM(atoi(token + len + 1))); /* trace found */

      break;
    }
  }

  free(disasm);
  return result;
}

.lnums_for_str_array(string_array, newline = '') ⇒ Object

Return an array of lines numbers that could be stopped at given a file name of a Ruby program. We assume the each line has n at the end. If not set the newline parameters to n.



26
27
28
# File 'lib/tracelines19.rb', line 26

def lnums_for_str_array(string_array, newline='')
  lnums_for_str(string_array.join(newline))
end