Skip to contentSkip to conversation

git-cget: prints elements of C code in the git repository

PATCH Superseded Roel Kluin 7 participants 16 messages Jun 15, 2016 Kbuild

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore

Roel Kluin

author
#0 lore raw

PATCH 1/1 git-cget: prints elements of C code in the git repository

Maybe something like this is useful? ------------------------------>8-------------8<--------------------------------- Add git-cget.sh: prints elements of C code in the git repository.

---

Makefile +1 -0
index 1087884..c21ba91 100644
@@ -260,6 +260,7 @@ BASIC_LDFLAGS =
 SCRIPT_SH += git-am.sh
 SCRIPT_SH += git-bisect.sh
 SCRIPT_SH += git-filter-branch.sh
+SCRIPT_SH += git-cget.sh
 SCRIPT_SH += git-lost-found.sh
 SCRIPT_SH += git-merge-octopus.sh
 SCRIPT_SH += git-merge-one-file.sh
git-cget.sh new file +409 -0

409 lines not on this page · raw message

#1 lore raw

Hi,

Disclaimer: if you are offended by constructive criticism, or likely to answer with insults to the comments I offer, please stop reading this mail now (and please do not answer my mail, either). :-)

Still with me? Good. Nice to meet you.

Just for the record: responding to a patch is my strongest way of saying that I appreciate your work.

Quoted 5 lines · Roel Kluin

Maybe something like this is useful? ------------------------------>8-------------8<--------------------------------- Add git-cget.sh: prints elements of C code in the git repository.

I really like what this tries to do.

But there are some problems:

- the name is not expressive enough,

- the commit message is severely lacking (I had to apply it and run it to find out what problem it tries to solve),

- it still uses dashed git commands,

- it might be better to put it into contrib/, otherwise it needs documentation with examples, and tests,

- it misdetects functions: trying

	$ ./git-cget -f get_sha1.*

shows this, amongst others:

-- snip --
// vi sha1_name.c +59

                return get_sha1_hex(hex, sha1) == 0;
        return found;
}

static int match_sha(unsigned len, const unsigned char *a, const unsigned char *b)

{
        do {
                if (*a != *b)
                        return 0;
                a++;
                b++;
                len -= 2;
        } while (len > 1);
        if (len)
                if ((*a ^ *b) & 0xf0)
                        return 0;
        return 1;
}

-- snap --

- maybe it would be nicer to integrate this into git grep itself? Maybe by allowing multi-line matches and default patterns, or pattern templates?

Ciao,
Dscho

author
#2 lore raw

Hi Johannes,

thanks for your pointers.

Quoted 1 line

- the name is not expressive enough,

How about get-def? If it's too long it will become tiresome to type.

Quoted 2 lines

- the commit message is severely lacking (I had to apply it and run it to find out what problem it tries to solve),

This is probably better:

This script shows where elements of C code are defined in the git-repository. It is still experimental, although it should work in most cases.

As invoking it with -? will tell:

USAGE: git get-def [OPTION]... PATTERN [FILE]...
print elements of C code with name PATTERN in the git repository, where PATTERN is an extended regular expression

Options to specify which element(s) should be printed:

        -f      function
        -s      struct
        -d      definition
        -m      macro
        -e      enum
        -u      union

Options to alter the output:
-b only print body
-n only print file and lineranges

The pattern is required.

If no files are specified it will search the entire repository for the specified elements with name PATTERN.

If no element is specified, it will search for any of the above elements and print these when found.

Quoted 1 line

- it still uses dashed git commands,

Should be fixed in my next version

Quoted 2 lines

- it might be better to put it into contrib/, otherwise it needs documentation with examples, and tests,

Ok.

Quoted 27 lines

- it misdetects functions: trying

	$ ./git-cget -f get_sha1.*

shows this, amongst others:

-- snip --
// vi sha1_name.c +59

                return get_sha1_hex(hex, sha1) == 0;
        return found;
}

static int match_sha(unsigned len, const unsigned char *a, const unsigned char *b)

{
        do {
                if (*a != *b)
                        return 0;
                a++;
                b++;
                len -= 2;
        } while (len > 1);
        if (len)
                if ((*a ^ *b) & 0xf0)
                        return 0;
        return 1;
}
Quoted 1 line

-- snap --

Yes, it doesn't always work yet, I'll try to fix this in my next version.

Quoted 3 lines

- maybe it would be nicer to integrate this into git grep itself? Maybe by allowing multi-line matches and default patterns, or pattern templates?

I did attempt to program it in C, but I am more comfortable with bash. Also, what would be more appropriate for this purpose, I think, is a git sed.

However, allowing multi-line matches may be an option, I'll look into it.

Quoted 2 lines

Ciao,
Dscho

Thanks,

Roel

#3 lore raw
Quoted 7 lines · Roel Kluin
Quoted 2 lines

- the commit message is severely lacking (I had to apply it and run it to find out what problem it tries to solve),

This is probably better:

This script shows where elements of C code are defined in the git-repository. It is still experimental, although it should work in most cases.

Wouldn't it be a lot easier to base this on something like ctags, which already knows how to do all the parsing of C quirky C?

I.e.:

git ls-files | xargs ctags
vi -t get_sha1

Where you can replace "vi" with your editor of choice. And if you really like getting the definition dumped to stdout, writing a command-line viewer for the ctags format would be quite simple (and I would be surprised if one hasn't been written already).

-Peff

author
#4 lore raw
Quoted 7 lines

Wouldn't it be a lot easier to base this on something like ctags, which
already knows how to do all the parsing of C quirky C?

I.e.:

git ls-files | xargs ctags
vi -t get_sha1

You are right, I'll see what I can do with it.

#6 lore raw
In reply to Jeff King
Quoted 3 lines · Jeff King

Wouldn't it be a lot easier to base this on something like ctags, which already knows how to do all the parsing of C quirky C?

Ctags also has the advantage of handling other languages. According to the man page: C, Pascal, Fortran, YACC, lex, and lisp.

#7 lore raw
In reply to Jeff King

2009/3/24 Jeff King <[email protected]>:

Quoted 9 lines

Wouldn't it be a lot easier to base this on something like ctags, which already knows how to do all the parsing of C quirky C?

I.e.:

 git ls-files | xargs ctags
 vi -t get_sha1

Where you can replace "vi" with your editor of choice.

This kind of pipeline has the benefit that it can actually work on the *repository*, and not just the working copy (as per the posted script).

Although this kind of tool might be useful (I might even use it myself for working on git, rather than as *part of git* on my other projects, which are not written in C), it's a bit tangential even for contrib/ isn't it?

Quoted 4 lines

And if you really like getting the definition dumped to stdout, writing a command-line viewer for the ctags format would be quite simple (and I would be surprised if one hasn't been written already).

http://users.telenet.be/bdr/pub/cshow/ ?

Mike

#8 lore raw

Hi,

Quoted 6 lines · Mike Ralphson

2009/3/24 Jeff King <[email protected]>:

Quoted 5 lines

Wouldn't it be a lot easier to base this on something like ctags, which already knows how to do all the parsing of C quirky C?

I.e.:

Quoted 7 lines
Quoted 4 lines

 git ls-files | xargs ctags
 vi -t get_sha1

Where you can replace "vi" with your editor of choice.

This kind of pipeline has the benefit that it can actually work on the *repository*, and not just the working copy (as per the posted script).

Did I miss something? git ls-files pipes only the names to xargs, not the full contents, right?

Ciao,
Dscho

#9 lore raw

2009/3/24 Johannes Schindelin <[email protected]>:

Quoted 5 lines
Quoted 2 lines

This kind of pipeline has the benefit that it can actually work on the *repository*, and not just the working copy (as per the posted script).

Did I miss something? git ls-files pipes only the names to xargs, not the full contents, right?

See where I wrote "this kind of pipeline" vs "git ls-files" which was just quoting Peff? 8-)

I dunno, maybe C folk using git would only be interested in the index/working copy, but that tells me this script is even more tenuously linked to git. We don't bundle a compiler just because it can use git ls-files to work out what to compile...

The script might be best as a standalone tool which just happened to take advantage of the VCS in use by reacting to its surroundings. Then it would also be useful by hg, svn, cvs people etc.

If it actually used the information in the repository to be able to run git blame on the definitions, or show a git log -p style list of changes in the definition, that might be different.

Mike

#10 lore raw
In reply to Mike Ralphson
Quoted 4 lines · Mike Ralphson

2009/3/24 Jeff King <[email protected]>:
This kind of pipeline has the benefit that it can actually work on the *repository*, and not just the working copy (as per the posted script).

Speaking of wanting things to work with the actual repository , one thing that I've been meaning to continue work on if I get the time is basically a 'show me any commit diff's that involve string s' (ie, the locations in which a change involving s occurs rather than just 'current file contains s (in exactly the same ways the previous version did). I'm extremely unlikely to actually produce anything based on that in the near future. But one thing that struck me that might be reasonably useful is some way of filtering the "context" that a string occurs in (is it in generic code context, in a string or in a comment). These are things that tend to be reasonably parametrisable by regular expressions (although escaping string delimiters within in strings makes completely correct behaviour tricky), so if git-grep itself were to be extended I'd prefer something that can be specified per search in a more generally usable way than something very C specific. Of course this is a quite difficult task as the actual diff may not contain enough lines to distinguish, eg, that it occurs within a longer comment. (As already disclaimed, I'm unlikely to actually get around to doing any of this work).

cheers, dave tweed

#11 lore raw
Quoted 6 lines · Steven Tweed

Speaking of wanting things to work with the actual repository , one thing that I've been meaning to continue work on if I get the time is basically a 'show me any commit diff's that involve string s' (ie, the locations in which a change involving s occurs rather than just 'current file contains s (in exactly the same ways the previous version did). I'm extremely unlikely to actually produce anything

How about "git log -S", or does that somehow not meet your needs (and if not, how)?

-Peff

#12 lore raw
In reply to Roel Kluin

Hi,

Quoted 3 lines · Roel Kluin
Quoted 1 line

- the name is not expressive enough,

How about get-def? If it's too long it will become tiresome to type.

IMHO "git grep-c" would be more to the point...

Quoted 5 lines
Quoted 2 lines

- the commit message is severely lacking (I had to apply it and run it to find out what problem it tries to solve),

This is probably better:
[...]

Yes, I like it!

Quoted 5 lines
Quoted 3 lines

- maybe it would be nicer to integrate this into git grep itself? Maybe by allowing multi-line matches and default patterns, or pattern templates?

I did attempt to program it in C, but I am more comfortable with bash.

Did I misunderstand your code? I thought all it does is provide a way to match multiline patterns... but then, I could not do more than just quickly glance over the code.

Quoted 2 lines

Also, what would be more appropriate for this purpose, I think, is a git sed.

Just as it happens, this is a toy I am working on and off these days... strbuf_regsub() is already done, and half the needed code is in my version git grep.

Ciao,
Dscho

#13 lore raw
Quoted 7 lines · Johannes Schindelin
Quoted 2 lines

Also, what would be more appropriate for this purpose, I think, is a git sed.

Just as it happens, this is a toy I am working on and off these days... strbuf_regsub() is already done, and half the needed code is in my version git grep.

this is my version

[alias]
sed = !git ls-files --stage | grep ^100 | awk '{print $4}' | xargs sed

Then i can do

git sed -i 's/A/B/g'

author
#14 lore raw
In reply to Johannes Schindelin

Hi Johannes,

Quoted 3 lines

- it misdetects functions: trying

       $ ./git-cget -f get_sha1.*

The .* is not strict enough. What you want to do instead is:

$ ./git-cget -f "get_sha1[A-Za-z0-9_]*"

and that will give correct matches.

Roel

#15 lore raw

Hi,

Quoted 11 lines · roel kluin

Hi Johannes,

Quoted 3 lines

- it misdetects functions: trying

       $ ./git-cget -f get_sha1.*

The .* is not strict enough. What you want to do instead is:

$ ./git-cget -f "get_sha1[A-Za-z0-9_]*"

and that will give correct matches.

No, the problem was that it did not show a function _definition_, but mistook a function _call_ for a definition.

Ciao,
Dscho