Skip to content

Commit

Permalink
Add collected path and branch information to xdebug_get_code_coverage…
Browse files Browse the repository at this point in the history
…() output.
  • Loading branch information
derickr committed Oct 5, 2014
1 parent e961c08 commit 84a5ee3
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 7 deletions.
1 change: 1 addition & 0 deletions php_xdebug.h
Expand Up @@ -32,6 +32,7 @@
#include "xdebug_handlers.h"
#include "xdebug_hash.h"
#include "xdebug_llist.h"
#include "xdebug_branch_info.h"
#include "xdebug_code_coverage.h"

extern zend_module_entry xdebug_module_entry;
Expand Down
27 changes: 26 additions & 1 deletion xdebug_branch_info.c
Expand Up @@ -11,7 +11,7 @@
*/
#include <stdlib.h>
#include <math.h>
#include "xdebug_branch_info.h"
#include "php_xdebug.h"

ZEND_EXTERN_MODULE_GLOBALS(xdebug)

Expand Down Expand Up @@ -207,3 +207,28 @@ void xdebug_branch_info_dump(zend_op_array *opa, xdebug_branch_info *branch_info
printf("\n");
}
}

void xdebug_branch_info_add_branches_and_paths(char *filename, xdebug_branch_info *branch_info TSRMLS_DC)
{
xdebug_coverage_file *file;

if (strcmp(XG(previous_filename), filename) == 0) {
file = XG(previous_file);
} else {
/* Check if the file already exists in the hash */
if (!xdebug_hash_find(XG(code_coverage), filename, strlen(filename), (void *) &file)) {
/* The file does not exist, so we add it to the hash, and
* add a line element to the file */
file = xdmalloc(sizeof(xdebug_coverage_file));
file->name = xdstrdup(filename);
file->lines = xdebug_hash_alloc(128, xdebug_coverage_line_dtor);
file->branch_info = NULL;

xdebug_hash_add(XG(code_coverage), filename, strlen(filename), file);
}
XG(previous_filename) = file->name;
XG(previous_file) = file;
}

file->branch_info = branch_info;
}
2 changes: 1 addition & 1 deletion xdebug_branch_info.h
Expand Up @@ -20,7 +20,6 @@
#define __HAVE_XDEBUG_BRANCH_INFO_H__

#include "xdebug_set.h"
#include "php_xdebug.h"

typedef struct _xdebug_branch {
unsigned int start_lineno;
Expand Down Expand Up @@ -53,6 +52,7 @@ void xdebug_branch_post_process(xdebug_branch_info *branch_info);
void xdebug_branch_find_paths(xdebug_branch_info *branch_info);

void xdebug_branch_info_dump(zend_op_array *opa, xdebug_branch_info *branch_info TSRMLS_DC);
void xdebug_branch_info_add_branches_and_paths(char *filename, xdebug_branch_info *branch_info TSRMLS_DC);
void xdebug_branch_info_free(xdebug_branch_info *branch_info);

#endif
68 changes: 65 additions & 3 deletions xdebug_code_coverage.c
Expand Up @@ -38,6 +38,9 @@ void xdebug_coverage_file_dtor(void *data)
{
xdebug_coverage_file *file = (xdebug_coverage_file *) data;

if (file->branch_info) {
xdebug_branch_info_free(file->branch_info);
}
xdebug_hash_destroy(file->lines);
xdfree(file->name);
xdfree(file);
Expand Down Expand Up @@ -324,6 +327,7 @@ void xdebug_count_line(char *filename, int lineno, int executable, int deadcode
file = xdmalloc(sizeof(xdebug_coverage_file));
file->name = xdstrdup(filename);
file->lines = xdebug_hash_alloc(128, xdebug_coverage_line_dtor);
file->branch_info = NULL;

xdebug_hash_add(XG(code_coverage), filename, strlen(filename), file);
}
Expand Down Expand Up @@ -583,9 +587,7 @@ static void prefill_from_oparray(char *fn, zend_op_array *op_array TSRMLS_DC)
if (branch_info) {
xdebug_branch_post_process(branch_info);
xdebug_branch_find_paths(branch_info);
xdebug_branch_info_dump(op_array, branch_info TSRMLS_CC);

xdebug_branch_info_free(branch_info);
xdebug_branch_info_add_branches_and_paths(fn, branch_info TSRMLS_CC);
}
}

Expand Down Expand Up @@ -705,6 +707,60 @@ static void add_line(void *ret, xdebug_hash_element *e)
}
}

static void add_branches(zval *retval, xdebug_branch_info *branch_info TSRMLS_DC)
{
zval *branches, *branch, *out;
unsigned int i;

MAKE_STD_ZVAL(branches);
array_init(branches);

for (i = 0; i < branch_info->starts->size; i++) {
if (xdebug_set_in(branch_info->starts, i)) {
MAKE_STD_ZVAL(branch);
array_init(branch);
add_assoc_long(branch, "op_start", i);
add_assoc_long(branch, "op_end", branch_info->branches[i].end_op);
add_assoc_long(branch, "line_start", branch_info->branches[i].start_lineno);
add_assoc_long(branch, "line_end", branch_info->branches[i].end_lineno);

MAKE_STD_ZVAL(out);
array_init(out);
if (branch_info->branches[i].out[0]) {
add_index_long(out, branch_info->branches[i].out[0], 0);
}
if (branch_info->branches[i].out[1]) {
add_index_long(out, branch_info->branches[i].out[1], 0);
}
add_assoc_zval(branch, "out", out);
add_index_zval(branches, i, branch);
}
}

add_assoc_zval_ex(retval, "branches", 9, branches);
}

static void add_paths(zval *retval, xdebug_branch_info *branch_info TSRMLS_DC)
{
zval *paths, *path;
unsigned int i, j;

MAKE_STD_ZVAL(paths);
array_init(paths);

for (i = 0; i < branch_info->paths_count; i++) {
MAKE_STD_ZVAL(path);
array_init(path);

for (j = 0; j < branch_info->paths[i]->elements_count; j++) {
add_next_index_long(path, branch_info->paths[i]->elements[j]);
}
add_next_index_zval(paths, path);
}

add_assoc_zval_ex(retval, "paths", 6, paths);
}

static void add_file(void *ret, xdebug_hash_element *e)
{
xdebug_coverage_file *file = (xdebug_coverage_file*) e->ptr;
Expand All @@ -723,6 +779,12 @@ static void add_file(void *ret, xdebug_hash_element *e)
target_hash = HASH_OF(lines);
zend_hash_sort(target_hash, zend_qsort, xdebug_lineno_cmp, 0 TSRMLS_CC);

/* Add the branch and path info */
if (file->branch_info) {
add_branches(lines, file->branch_info);
add_paths(lines, file->branch_info);
}

add_assoc_zval_ex(retval, file->name, strlen(file->name) + 1, lines);
}

Expand Down
6 changes: 4 additions & 2 deletions xdebug_code_coverage.h
Expand Up @@ -22,6 +22,7 @@
#include "php.h"
#include "xdebug_hash.h"
#include "xdebug_mm.h"
#include "xdebug_branch_info.h"

typedef struct xdebug_coverage_line {
int lineno;
Expand All @@ -30,8 +31,9 @@ typedef struct xdebug_coverage_line {
} xdebug_coverage_line;

typedef struct xdebug_coverage_file {
char *name;
xdebug_hash *lines;
char *name;
xdebug_hash *lines;
xdebug_branch_info *branch_info;
} xdebug_coverage_file;

/* Needed for code coverage as Zend doesn't always add EXT_STMT when expected */
Expand Down

0 comments on commit 84a5ee3

Please sign in to comment.