Coccigrep, a semantic grep for the C language

Introduction

When diving in some code with a relative important size, I’ve often ask myself: where is this attribute used for this structure ? Where it is set ? Using grep is not a good answer to theses questions: you can’t guess the name of the variable of a given type and even an attribute name can be shared between multiple structures. I was in need of a semantic grep!

Having played a bit with coccinelle, I did know that it could be used with success to build a semantic grep for the C language. But coccinelle syntax is not easy and I decided to build something with a simplistic syntax. Something that would integrate easily into vim to be able to use it like grep. I’ve launched my preferred editor and this something is now called coccigrep.

Meet the beast

The syntax is trivial, to find where the datalink attribute of the Packet structure is set in all source*c file:

$ coccigrep  -t Packet -a datalink -o set src/source*c   
src/source-af-packet.c:300 (Packet *p):     p->datalink = ptv->datalink;
src/source-erf-dag.c:525 (Packet *pkt):     pkt->datalink = LINKTYPE_ETHERNET;

You can use coccigrep from vim. If you run in vim:

:Coccigrep -t Packet -a datalink source-*.c

The matches will appear in the quickfix list and the file corresponding to first match will be opened at the corresponding line. Note that you can use completion on structure and attribute names based on tags (generated by :make tags).

Coccigrep supports syntax highlighting through the pygments module. For example, running coccigrep -t Packet -a datalink -o test -c -A 3 -B 3 -f html /tmp/test.c will output to stdout some colorized HTML code:

/tmp/test.c: l.300 -3, l.300 +3, Packet *p
        hdrp->sll_protocol = from.sll_protocol;
    }

    while (p->datalink >= ptv->datalink) {
    	SET_PKT_LEN(p, caplen + offset);
    	if (PacketCopyData(p, ptv->data, GET_PKT_LEN(p)) == -1) {
           TmqhOutputPacketpool(ptv->tv, p);

More information and download are available from coccigrep page.