summaryrefslogtreecommitdiff
path: root/parse.y
diff options
context:
space:
mode:
authormame <mame@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-07-01 16:55:30 +0000
committermame <mame@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-07-01 16:55:30 +0000
commit5874de95e8df1d051001cf53614c1d245c1ac5ae (patch)
tree3bd25f3a413a1637a826552181c1568b3bbeb9c0 /parse.y
parent498324c5d3cd08c2c306a4f91e3a11b7fda22835 (diff)
* Add coverage measurement constant COVERAGE__. This constant is not
for casual use. Usage: (1) assign {} to COVERAGE__, (2) require or load Ruby source file, and (3) COVERAGE__["sourcefilepath"] will return an array whose elements represent number of executions per line of source code. * vm_core.h: add field of coverage array to iseq. * iseq.c (prepare_iseq_build): ditto. * insns.def (trace): update coverage array. * parse.y (coverage): create and initialize coverage array. * compile.h (ADD_TRACE): add trace instruction to update covearge array. * thread.c (clear_coverage): delete coverage array when forking. Otherwise, double count of coverage may occur. * lib/coverage.rb: sample coverage measurement tool. * error.c: distinguish explicitly between parse_in_eval and mild_compile_error. * load.c: ditto. * vm_eval.c: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@17781 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'parse.y')
-rw-r--r--parse.y47
1 files changed, 39 insertions, 8 deletions
diff --git a/parse.y b/parse.y
index 4b42870a0c..54d728a1d0 100644
--- a/parse.y
+++ b/parse.y
@@ -249,6 +249,7 @@ struct parser_params {
NODE *parser_eval_tree_begin;
NODE *parser_eval_tree;
VALUE debug_lines;
+ VALUE coverage;
int nerr;
#else
/* Ripper only */
@@ -322,6 +323,7 @@ static int parser_yyerror(struct parser_params*, const char*);
#define ruby_eval_tree (parser->parser_eval_tree)
#define ruby_eval_tree_begin (parser->parser_eval_tree_begin)
#define ruby_debug_lines (parser->debug_lines)
+#define ruby_coverage (parser->coverage)
#endif
static int yylex(void*, void*);
@@ -4668,6 +4670,32 @@ debug_lines(const char *f)
}
static VALUE
+coverage(const char *f, int n)
+{
+ if (rb_const_defined_at(rb_cObject, rb_intern("COVERAGE__"))) {
+ VALUE hash = rb_const_get_at(rb_cObject, rb_intern("COVERAGE__"));
+ if (TYPE(hash) == T_HASH) {
+ VALUE fname = rb_str_new2(f);
+ VALUE lines = rb_ary_new2(n);
+ int i;
+ for (i = 0; i < n; i++) RARRAY_PTR(lines)[i] = Qnil;
+ RARRAY(lines)->len = n;
+ rb_hash_aset(hash, fname, lines);
+ return lines;
+ }
+ }
+ return 0;
+}
+
+static int
+e_option_supplied(struct parser_params *parser)
+{
+ if (strcmp(ruby_sourcefile, "-e") == 0)
+ return Qtrue;
+ return Qfalse;
+}
+
+static VALUE
yycompile0(VALUE arg, int tracing)
{
int n;
@@ -4683,11 +4711,19 @@ yycompile0(VALUE arg, int tracing)
rb_ary_push(ruby_debug_lines, str);
} while (--n);
}
+
+ if (!e_option_supplied(parser)) {
+ ruby_coverage = coverage(ruby_sourcefile, ruby_sourceline);
+ }
}
parser_prepare(parser);
n = yyparse((void*)parser);
+ if (ruby_coverage) {
+ rb_ary_freeze(ruby_coverage);
+ }
ruby_debug_lines = 0;
+ ruby_coverage = 0;
compile_for_eval = 0;
lex_strterm = 0;
@@ -4750,6 +4786,9 @@ lex_getline(struct parser_params *parser)
if (ruby_debug_lines && !NIL_P(line)) {
rb_ary_push(ruby_debug_lines, line);
}
+ if (ruby_coverage && !NIL_P(line)) {
+ rb_ary_push(ruby_coverage, Qnil);
+ }
#endif
return line;
}
@@ -8126,14 +8165,6 @@ assign_in_cond(struct parser_params *parser, NODE *node)
return 1;
}
-static int
-e_option_supplied(struct parser_params *parser)
-{
- if (strcmp(ruby_sourcefile, "-e") == 0)
- return Qtrue;
- return Qfalse;
-}
-
static void
warn_unless_e_option(struct parser_params *parser, NODE *node, const char *str)
{