{"thread":{"id":"18504","subject":"[PATCH] git-cget: prints elements of C code in the git repository","startedAt":"2009-03-24T10:09:29Z","lastAt":"2009-03-27T11:26:34Z","messageCount":16,"participants":["Roel Kluin","Johannes Schindelin","Jeff King","Stefan Karpinski","Mike Ralphson","Ping Yin","roel kluin","Steven Tweed"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"109198","messageId":"49C8B159.2040600@gmail.com","threadId":"18504","inReplyTo":null,"subject":"[PATCH] git-cget: prints elements of C code in the git repository","fromName":"Roel Kluin","fromEmail":"roel.kluin@gmail.com","sentAt":"2009-03-24T10:09:29Z","receivedAt":"2009-03-24T10:09:29Z","isPatch":true,"sender":{"key":"roel.kluin@gmail.com","avatar":null},"body":"Maybe something like this is useful?\n------------------------------>8-------------8<---------------------------------\nAdd git-cget.sh: prints elements of C code in the git repository.\n\nSigned-off-by: Roel Kluin <roel.kluin@gmail.com>\n---\ndiff --git a/Makefile b/Makefile\nindex 1087884..c21ba91 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -260,6 +260,7 @@ BASIC_LDFLAGS =\n SCRIPT_SH += git-am.sh\n SCRIPT_SH += git-bisect.sh\n SCRIPT_SH += git-filter-branch.sh\n+SCRIPT_SH += git-cget.sh\n SCRIPT_SH += git-lost-found.sh\n SCRIPT_SH += git-merge-octopus.sh\n SCRIPT_SH += git-merge-one-file.sh\ndiff --git a/git-cget.sh b/git-cget.sh\nnew file mode 100755\nindex 0000000..08ea65f\n--- /dev/null\n+++ b/git-cget.sh\n@@ -0,0 +1,409 @@\n+#!/bin/bash\n+# FIXME: make C++ style members\n+\n+int=\"[0-9]\"\n+hex=\"[a-f0-9]\"\n+hEx=\"[A-Fa-f0-9]\"\n+HEX=\"[A-F0-9]\"\n+upp=\"[A-Z]\"\n+up_=\"[A-Z_]\"\n+low=\"[a-z0-9]\"\n+lo_=\"[a-z0-9_]\"\n+alp=\"[A-Za-z]\"\n+al_=\"[A-Za-z_]\"\n+ALN=\"[A-Z0-9]\"\n+AN_=\"[A-Z0-9_]\"\n+aln=\"[A-Za-z0-9]\"\n+an_=\"[A-Za-z0-9_]\"\n+\n+em='!'\t\t\t# because of bash banging\n+\n+D=\"$int*\\.?$int+x?$hex*[uUlL]{0,3}[fF]?\"\t\t# a number, float or hex\n+# more strict and catches it (costs one backreference for (git )grep)\n+SD=\"($int+[uUlLfF]?|$int+[uU]?[lL][lL]?|0x$hex+|0x$HEX+|$int+[lL][lL][uU]|$int*\\.$int+[fF]?)\"\n+\n+V=\"$al_+$an_*\"\t\t# variable/function name (or definition)\n+K=\"$up_+$AN_*\"\t\t# definition (in capitals)\n+\n+# to catch variables that are members or arrays:\n+W=\"[a-zA-Z0-9_>.-]*\"\n+SW=\"$V(\\[[^][]*\\]|\\[[^][]*\\[[^][]*\\][^][]*\\]|\\.$V|->$V)*\"\t # more strict, 1 backref\n+\n+s=\"[[:space:]]*\"\n+S=\"[[:space:]]+\"\n+\n+# useful to ensure the end of a variable name:\n+Q=\"[^[:alnum:]_]\"\n+Q2=\"[^[:alnum:]_>.]\" # the '>' is tricky, it's an operator as well\n+\n+# match comments\n+comm1=\"\\/\\*([^*]+|\\**[^*/])*\\*+\\/\"\t\t\t\t# 1 backref\n+comm2=\"\\/\\/([^\\n]+|[n\\\\]+)*\"\t\t\t\t# 1 backref\n+\n+# match the end of the line, including comments:\n+cendl=\"$s($comm1|$comm2|$s)*($|\\n)\"\t\t\t # 4 backrefs\n+\n+# strings and characters can contain things we want to match\n+str=\"\\\"([^\\\\\\\"]+|\\\\\\\\.)*\\\"\"\t\t\t\t\t\t # 1 backref\n+ch1=\"'[^\\\\']'\"\n+ch2=\"'\\\\\\\\.[^']*'\"\n+ch=\"$ch1|$ch2\"\n+\n+# when using grep [^\\/] also cases excludes '\\', so we correct for that\n+# match something that is not comment, string or character (c-code): 3 backrefs\n+ccode=\"([^\\\"'/]+|\\/[^*\\\"'/]|\\/?$comm1|\\/?$ch1|\\/?$ch2|\\/?$str|\\/?\\\\\\\\|\\/?$comm2)*\"\n+\n+# TODO: use backref cheaper versions\n+nps=\"[^()]*\"\n+nstdps=\"(\\($nps(\\($nps(\\($nps(\\($nps(\\($nps\\)$nps)*\\)$nps)*\\)$nps)*\\)$nps)*\\)$nps)*\"\n+npz=\"$nps$nstdps\"\n+nnps=\"\\($npz\\)\"\n+\n+ncs=\"[^}{]*\"\n+nstdcs=\"(\\{$ncs(\\{$ncs(\\{$ncs(\\{$ncs(\\{$ncs\\}$ncs)*\\}$ncs)*\\}$ncs)*\\}$ncs)*\\}$ncs)*\"\n+ncz=\"$ncs$nstdcs\"\n+nncs=\"\\{$ncz\\}\"\n+\n+delimitstr=\"s/([][{}(|)+*?\\\\/.^])/\\\\\\\\\\1/g\"\n+delimit()\n+{\n+\tsed -r \"$delimitstr\"\n+}\n+\n+# unmatch: match anything except the given.\n+#\n+# If given is a string, then it also matches longer\n+# or shorter strings.\n+#\n+# otherwise it delimits characters and then creates a match\n+#\n+unmatch()\n+{\n+\tlocal sedstr=\n+\t# TODO: unmatch numbers\n+\t# if [ -n \"`echo \"$1\" | grep -E \"^$SD$\"`\" ]; then\n+\tif [ -n \"`echo \"$1\" | grep -E \"^$V$\"`\" ]; then\n+\t\tsedstr=\":loop\n+\t\t\ts/^($an_+)?($an_)(\\|.*)?$/\\1\\|\\1[^\\2]\\3/\n+\t\t\tt loop\n+\t\t\ts/^[|](.*)$/($al_$an_{${#1}}|\\1)$an_*/\"\n+\tfi\n+\t# FIXME: unmatch non alnum characters:\n+\t# with the below \"\\*\" results in ([^\\\\]|\\\\[^*])*,\n+\t# but it should be ([^\\\\]|\\\\+[^*\\\\])*\n+\t#else\n+\t#\tlocal a=\"[^][{}(|)+*?\\\\/.^]\"\n+\t#\tlocal b=\"[][{}(|)+*?\\\\/.^]\"\n+\t#\tsedstr=\"$delimitstr\n+\t#\t\t:loop\n+\t#\t\ts/^(($a|[\\\\]$b)+)?(($a)|[\\\\]($b))(\\|.*)?$/\\1\\|\\1[^\\4\\5]\\6/\n+\t#\t\tt loop\n+\t#\t\ts/^[|](.*)$/(\\1)*/\"\n+\t#fi\n+\techo $1 | sed -r \"$sedstr\"\n+}\n+\n+# excludes testing in strings, chars and comment\n+excl_code()\n+{\n+\techo \"([^$1\\\"'/$2]*|\\/[^$1\\\"*'/$2]*|\\/?$comm1|\\/?$ch1|\\/?$ch2|\\/?$str|\\/?$comm2)*\"\n+}\n+\n+# usage: nestc \"(\" \")\" [number]\n+# only works for nesting single chars. (TODO: multiple)\n+nestc()\n+{\n+\tlocal i;\n+\t[ $# -eq 1 ] && i=5 || i=$3;\n+\t# first and 2nd are flipped to enable matching\n+\t# square brackets \"][\"\n+\tlocal p=\"$(excl_code \"$2$1\" \"$4\")\"\n+\tlocal ret=\"$p\"\n+\twhile [ $i -gt 0 ]; do\n+\t\tret=\"${p}([$1]${ret}[$2]${p})*\"\n+\t\ti=$(($i-1));\n+\tdone\n+\techo \"$ret\"\n+}\n+\n+blank_it()\n+{\n+\techo \"$1\" | sed -r \"\n+\t\t:a\n+\t\ts/([[:alnum:]])[[:space:]]+([[:alnum:]])/\\1[[:space:]]+\\2/g\n+\t\ts/[[:space:]]+/[[:space:]]*/g\n+\t\t$!{\n+\t\t\tN; ba\n+\t\t}\"\n+}\n+\n+# usage: grep_12 \"struct list_head {\" \"include/linux/slub_def.h\"\n+# greps included as well, when not found\n+grep_12()\n+{\n+\tflist=\n+\t_grep_12 \"$1\" \"$2\"\n+}\n+\n+_grep_12()\n+{\n+\tgrep -qE \"$1\" \"$2\";\n+\tif [ $? -eq 0 ]; then\n+\t\techo \"$2\";\n+\telse\n+\t\t[ -n \"$flist\" ] && flist=\"$flist|\"\n+\t\tflist=\"$flist$2\"\n+\t\tlocal b=\"${2%\\/*}\"\n+\t\tfor f in `sed -rn \"/^$s#${s}include${s}[\\\"<]/{\n+\t\t\t\t$delimitstr\n+\t\t\t\ts/^$s#${s}include$s<([^>]+)>$cendl/include\\/\\1/p\n+\t\t\t\ts/^$s#${s}include$s\\\"([^\\\"]+)\\\"$cendl/${b//\\//\\/}\\/\\1/p\n+\t\t\t\t}\" \"$2\" | grep -vE \"($flist)\" `; do\n+\t\t\t[ -f \"$f\" ] && _grep_12 \"$1\" \"$f\" && return 0;\n+\t\t\tb=\"${f%\\/*}\"\n+\t\tdone\n+\tfi\n+}\n+\n+get_matching_files()\n+{\n+\tlocal files=\"${@:2}\"\n+\tif [ -z \"$files\" ]; then\n+\t\tgrep -lE \"$1\" $(git-ls-files \"*.[ch]\");\n+\t\treturn;\n+\tfi\n+\tfor f in $files; do\n+\t\t[ -f \"$f\" ] && echo -n \"$(grep_12 \"$1\" \"$f\") \"\n+\t\t[ -d \"$f\" ] && grep -lE \"$1\" $(git-ls-files \"*.[ch]\")\n+\tdone\n+}\n+\n+\n+_sedit()\n+{\n+\tsed -r -n \"\n+\t\t:a\n+\t\t/$1/${em}b\n+\t\t/$2/${em}{\n+\t\t\tH; N; ba\n+\t\t}\n+\t\t$4\n+\t\t:b\n+\t\t/$3/${em}{\n+\t\t\tH; N; bb\n+\t\t}\n+\t\t$5\n+\t\" \"${@:6}\"\n+}\n+\n+sedit()\n+{\n+\tlocal print2=\"p\"\n+\t[ $(($1 & 4 )) -eq 4 ] && print2=\"=\"\n+\n+\tlocal stages=\"` blank_it \"$2@$3@$4\" | tr \"@\" \" \"`\"\n+\tlocal sed2str=\"/ \\+@$/{N; s/@\\n//}\";\n+\tif [ $(($1 & 1 )) -eq 1 ]; then\n+\t\t_sedit $stages \"#\" \"$print2\" \"${@:5}\" | sed -r \"$sed2str\";\n+\telse\n+\t\tlocal print1=\n+\t\t[ $(($1 & 2 )) -eq 0 ] && print1=\"`echo -e \"+@\\n=\"`\"\n+\t\t[ $1 -eq 4 ] && sed2str=\"/ \\+@$/{N; N; s/\\/\\/ vi ([^+]*) \\+@\\n([0-9]*)\\n([0-9]*)/\\1:\\2-\\3/}\"\n+\n+\t\tfor f in \"${@:5}\"; do\n+\t\t\t_sedit $stages \"i// vi $f $print1\" \"$print2\" \"$f\"\n+\t\tdone | sed -r \"$sed2str\";\n+\tfi\n+}\n+\n+get_func()\n+{\n+\t# TODO: C++ member stuff\n+\tlocal fret=\"( $V( |\\*|$comm1)*$S( |\\*|$comm1)*)+\"\n+\tlocal func_args=\"$(nestc \"(\" \")\" 10 \"+%/?#&|<>.^-\")\"\n+\tlocal func_body=\"$(nestc \"{\" \"}\" 10)\"\n+\n+\tlocal fl=\"${@:3}\"\n+\tif [ -z \"$fl\" ]; then\n+\t\tlocal match=\"^($fret)? $2 ((\\($func_args)+(\\) ($comm1 )*((\\{$func_body)+\\}?)?)?)?$\";\n+\t\tmatch=\"`blank_it \"$match\"`\";\n+\t\tfl=\"`git-ls-files \"*.[ch]\"`\"\n+\t\tfl=\"`grep -lE \"$match\" $fl`\";\n+\t\t[ -z \"$fl\" ] && return;\n+\tfi\n+\n+\tlocal stage1=\"^$fret ($2 ((\\($func_args)+(\\) ($comm1 )*((\\{$func_body)+\\}?)?)?)?)?$\";\n+\tlocal stage2=\"^$fret $2 \\($func_args\\) \\{\";\n+\tlocal stage3=\"^$fret $2 \\($func_args\\) \\{$func_body\\}\";\n+\tsedit $1 \"$stage1\" \"$stage2\" \"$stage3\" $fl\n+}\n+\n+\n+# get struct/enum/union\n+get_elem()\n+{\n+\tlocal sA=\"($S|$comm1)\"\n+\tlocal sB=\"($V$S|$V \\(\\([^()]+\\)\\) |$comm1 )*\"\n+\tlocal struct_body=\"$(nestc \"{\" \"}\" 10)\"\n+\tlocal stage1=;\n+\tlocal stage2=;\n+\tlocal stage3=;\n+\n+\tlocal match=\"^ (($sB$2)?$sA$sB)?$3($sA$sB)?((\\{$struct_body)+\\}?)?$cendl\"\n+\tmatch=\"`blank_it \"$match\"`\"\n+\tlocal fl=\"`get_matching_files \"$match\" ${@:4}`\"\n+\tif [ -n \"$fl\" ]; then\n+\t\tstage1=\"^ ($V|$V \\(\\([^()]*\\)\\)|$sB$2($sA$sB($3($sA$sB)?((\\{$struct_body)+\\}?)?)?)?)$cendl\"\n+\t\tstage2=\"^ $sB$2$sA$sB$3($sA$sB)? \\{\"\n+\t\tstage3=\"^ $sB$2$sA$sB$3($sA$sB)? \\{$struct_body\\}\"\n+\t\tsedit $1 \"$stage1\" \"$stage2\" \"$stage3\" $fl\n+\tfi\n+\n+\tmatch=\"^( (($sB$2)?($sA$sB| )\\{)?($struct_body\\})+)? $sB$3($sA$sB| );$cendl\"\n+\tmatch=\"`blank_it \"$match\"`\"\n+\tfl=\"`get_matching_files \"$match\" ${@:4}`\"\n+\tif [ -n \"$fl\" ]; then\n+\t\tstage1=\"^ ($V|$V \\(\\([^()]*\\)\\)|$sB$2(($sA$sB| )((\\{$struct_body)+(\\} $sB($3($sA$sB| );)?)?)?)?)$cendl\"\n+\t\tstage2=\"^ $sB$2($sA$sB| )\\{\"\n+\t\tstage3=\"^ $sB$2($sA$sB| )\\{$struct_body\\} $sB$3($sA$sB| );$cendl\"\n+\t\t# there can be false positives due to stage1.\n+\t\t# here we remove them\n+\t\tsedit $1 \"$stage1\" \"$stage2\" \"$stage3\" $fl |\n+\t\t\tsed -r \"/^\\/\\/ vi .* \\+[0-9]*$/{\n+\t\t\t\t:a\n+\t\t\t\t$!{\n+\t\t\t\t\td; b\n+\t\t\t\t}\n+\t\t\t\tN\n+\t\t\t\t/\\/\\/ vi .* \\+[0-9]*\\n\\/\\/ vi /${em}b\n+\t\t\t\tD; ba\n+\t\t\t}\";\n+\n+\tfi\n+}\n+\n+get_def()\n+{\n+\tlocal stage1=\"^ # define$S$2$Q\"\n+\tlocal match=\"`blank_it \"$stage1\"`\";\n+\tlocal stage2=\"^\"\n+\tlocal stage3=\"[^\\\\]$\"\n+\tsedit $1 \"$stage1\" \"$stage2\" \"$stage3\" `get_matching_files \"$match\" ${@:3}`\n+}\n+\n+get_any()\n+{\n+\tlocal defm=\" # define$S$2$Q\"\n+\tlocal sA=\"($S|$comm1)\"\n+\tlocal sB=\"($V$S|$V \\(\\([^()]+\\)\\) |$comm1 )*\"\n+\tlocal body=\"$(nestc \"{\" \"}\" 10)\"\n+\n+\tlocal elemsl=\"(($sB(struct|enum|union))?$sA$sB)?\"\n+\tlocal elemsr1=\"$2($sA$sB)?((\\{$body)+\\}?)?\"\n+\n+\tlocal fret=\"( $V( |\\*|$comm1)*$S( |\\*|$comm1)*)+\"\n+\tlocal func_args=\"$(nestc \"(\" \")\" 10 \"+%/?#^&|<>.-\")\"\n+\tlocal funcm=\"($fret)? $2 ((\\($func_args)+(\\) ($comm1 )*((\\{$body)+\\}?)?)?)?\";\n+\n+\tlocal match=\"`blank_it \"^($defm| $elemsl$elemsr1$| (($elemsl\\{)?($body\\})+)? $sB$2$sA$sB;$|$funcm$)\"`\";\n+\tdefm=\"`blank_it \"^$defm\"`\"\n+\tfuncm=\"`blank_it \"^$funcm$\"`\"\n+\tgit-grep -E \"$match\" | while read l; do\n+\t\tf=\"${l%:*}\"\n+\t\tl=\"${l#*:}\"\n+\t\tif [ \"`echo \"$l\" | grep -E \"^$defm\"`\" ]; then\n+\t\t\tget_def $1 \"$2\" $f\n+\t\telif [ \"`echo \"$l\" | grep -E \"^$funcm$\"`\" ]; then\n+\t\t\tget_func $1 \"$2\" $f\n+\t\telse\n+\t\t\tfor e in struct enum union; do\n+\t\t\t\tz=\"(($sB$e)?$sA$sB)?\"\n+\t\t\t\techo \"$l\" | grep -Eq \"`blank_it \"^ ( $z$elemsr1| (($z\\{)?($body\\})+)? $sB$2$sA$sB;)$cendl\"`\"\n+\t\t\t\t[ $? -eq 0 ] && get_elem $1 \"$e\" \"$2\" $f\n+\t\t\tdone\n+\t\tfi\n+\tdone\n+}\n+\n+usage()\n+{\n+cat << EOF\n+USAGE: git-get.sh [OPTION]... PATTERN [FILE]...\n+print elements of C code with name PATTERN in the git repository,\n+where PATTERN is a extended regular expression\n+\n+Options to specify which element(s) should be printed:\n+\t-f\tfunction\n+\t-s\tstruct\n+\t-d\tdefinition\n+\t-m\tmacro\n+\t-e\tenum\n+\t-u\tunion\n+\n+Options to alter the output:\n+\t-b\tonly print body\n+\t-n\tonly print file and lineranges\n+\t-?\tprint this help\n+\n+EOF\n+}\n+\n+parseopts()\n+{\n+\tlocal fl=\t\t\t# file list\n+\tlocal getflag=0\n+\tlocal printflag=0\n+\n+\twhile [ $# -ne 0 ]; do\n+\t\twhile getopts \"fdmseubn\" optname; do\n+\t\t\tcase \"$optname\" in\n+\t\t\t\t\"f\") getflag=$((getflag|1)) ;;\n+\t\t\t\t\"d\") getflag=$((getflag|2)) ;;\n+\t\t\t\t\"m\") getflag=$((getflag|4)) ;;\n+\t\t\t\t\"s\") getflag=$((getflag|8)) ;;\n+\t\t\t\t\"e\") getflag=$((getflag|16)) ;;\n+\t\t\t\t\"u\") getflag=$((getflag|32)) ;;\n+\t\t\t\t\"b\") printflag=3 ;;\n+\t\t\t\t\"n\") printflag=4 ;;\n+\t\t\t\t\"?\") usage; exit 0; ;;\n+\t\t\tesac\n+\t\tdone\n+\t\tshift $((OPTIND-1))\n+\t\t[ $# -eq 0 ] && break;\n+\t\tOPTIND=0\n+\t\tif [ -f \"$1\" ]; then\n+\t\t\tfl=\"$fl $1\";\n+\t\telse\n+\t\t\tname=\"$1\";\n+\t\tfi\n+\t\tshift\n+\tdone\n+\t[ -z \"$name\" ] && usage;\n+\tif [ $getflag -eq 0 ]; then\n+\t\tget_any $printflag \"$name\" $fl\n+\t\treturn;\n+\tfi\n+\t[ $((getflag&1)) -eq 1 ] && get_func $printflag \"$name\" $fl\n+\tif [ $((getflag&6)) -ne 0 ]; then\n+\t\tif [ $((getflag&6)) -eq 2 ]; then\n+\t\t\t\t\tdom=\"($S.*)?\";\t\t# print only definitions\n+\t\telif [ $((getflag&6)) -eq 4 ]; then\n+\t\t\t\t\tdom=\"\\(.*\";\t\t# print only macros\n+\t\telse\n+\t\t\tdom=\"(\\(.*|$S.*)?\";\t# catch definition or macro\n+\t\tfi\n+\t\tget_def $printflag \"$name$dom\" $fl\n+\tfi\n+\tif [ $((getflag&8)) -eq 8 ]; then\n+\t\tget_elem $printflag \"struct\" \"$name\" $fl\n+\tfi\n+\tif [ $((getflag&16)) -eq 16 ]; then\n+\t\tget_elem $printflag \"enum\" \"$name\" $fl\n+\tfi\n+\tif [ $((getflag&32)) -eq 32 ]; then\n+\t\tget_elem $printflag \"union\" \"$name\" $fl\n+\tfi\n+}\n+\n+#main\n+parseopts \"$@\"\n"},{"id":"109208","messageId":"alpine.DEB.1.00.0903241257430.7493@intel-tinevez-2-302","threadId":"18504","inReplyTo":"49C8B159.2040600@gmail.com","subject":"Re: [PATCH] git-cget: prints elements of C code in the git repository","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-03-24T12:05:34Z","receivedAt":"2009-03-24T12:05:34Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nDisclaimer: if you are offended by constructive criticism, or likely to\nanswer with insults to the comments I offer, please stop reading this mail\nnow (and please do not answer my mail, either). :-)\n\nStill with me?  Good.  Nice to meet you.\n\nJust for the record: responding to a patch is my strongest way of saying\nthat I appreciate your work.\n\nOn Tue, 24 Mar 2009, Roel Kluin wrote:\n\n> Maybe something like this is useful?\n> ------------------------------>8-------------8<---------------------------------\n> Add git-cget.sh: prints elements of C code in the git repository.\n> \n> Signed-off-by: Roel Kluin <roel.kluin@gmail.com>\n\nI really like what this tries to do.\n\nBut there are some problems:\n\n- the name is not expressive enough,\n\n- the commit message is severely lacking (I had to apply it and run it to \n  find out what problem it tries to solve),\n\n- it still uses dashed git commands,\n\n- it might be better to put it into contrib/, otherwise it needs \n  documentation with examples, and tests,\n\n- it misdetects functions: trying\n\n\t$ ./git-cget -f get_sha1.*\n\n  shows this, amongst others:\n\n-- snip --\n// vi sha1_name.c +59\n                return get_sha1_hex(hex, sha1) == 0;\n        return found;\n}\n\nstatic int match_sha(unsigned len, const unsigned char *a, const unsigned \nchar *b)\n{\n        do {\n                if (*a != *b)\n                        return 0;\n                a++;\n                b++;\n                len -= 2;\n        } while (len > 1);\n        if (len)\n                if ((*a ^ *b) & 0xf0)\n                        return 0;\n        return 1;\n}\n-- snap --\n\n- maybe it would be nicer to integrate this into git grep itself?  Maybe \n  by allowing multi-line matches and default patterns, or pattern \n  templates?\n\nCiao,\nDscho\n"},{"id":"109210","messageId":"49C8E074.4030808@gmail.com","threadId":"18504","inReplyTo":"alpine.DEB.1.00.0903241257430.7493@intel-tinevez-2-302","subject":"Re: [PATCH] git-cget: prints elements of C code in the git repository","fromName":"Roel Kluin","fromEmail":"roel.kluin@gmail.com","sentAt":"2009-03-24T13:30:28Z","receivedAt":"2009-03-24T13:30:28Z","isPatch":true,"sender":{"key":"roel.kluin@gmail.com","avatar":null},"body":"Hi Johannes,\n\nthanks for your pointers.\n\n> - the name is not expressive enough,\n\nHow about get-def? If it's too long it will become tiresome to type.\n\n> - the commit message is severely lacking (I had to apply it and run it to \n>   find out what problem it tries to solve),\n\nThis is probably better:\n\nThis script shows where elements of C code are defined in the git-repository.\nIt is still experimental, although it should work in most cases.\n\nAs invoking it with -? will tell:\n\nUSAGE: git get-def [OPTION]... PATTERN [FILE]...\nprint elements of C code with name PATTERN in the git repository,\nwhere PATTERN is an extended regular expression\n\nOptions to specify which element(s) should be printed:\n        -f      function\n        -s      struct\n        -d      definition\n        -m      macro\n        -e      enum\n        -u      union\n\nOptions to alter the output:\n        -b      only print body\n        -n      only print file and lineranges\n\nThe pattern is required.\n\nIf no files are specified it will search the entire repository for\nthe specified elements with name PATTERN.\n\nIf no element is specified, it will search for any of the above\nelements and print these when found.\n\n> - it still uses dashed git commands,\n\nShould be fixed in my next version\n\n> - it might be better to put it into contrib/, otherwise it needs \n>   documentation with examples, and tests,\n\nOk.\n\n> - it misdetects functions: trying\n> \n> \t$ ./git-cget -f get_sha1.*\n> \n>   shows this, amongst others:\n> \n> -- snip --\n> // vi sha1_name.c +59\n>                 return get_sha1_hex(hex, sha1) == 0;\n>         return found;\n> }\n> \n> static int match_sha(unsigned len, const unsigned char *a, const unsigned \n> char *b)\n> {\n>         do {\n>                 if (*a != *b)\n>                         return 0;\n>                 a++;\n>                 b++;\n>                 len -= 2;\n>         } while (len > 1);\n>         if (len)\n>                 if ((*a ^ *b) & 0xf0)\n>                         return 0;\n>         return 1;\n> }\n> -- snap --\n\nYes, it doesn't always work yet, I'll try to fix this in my next version.\n\n> - maybe it would be nicer to integrate this into git grep itself?  Maybe \n>   by allowing multi-line matches and default patterns, or pattern \n>   templates?\n\nI did attempt to program it in C, but I am more comfortable with bash. Also,\nwhat would be more appropriate for this purpose, I think, is a git sed.\n\nHowever, allowing multi-line matches may be an option, I'll look into it.\n\n> Ciao,\n> Dscho\n\nThanks,\n\nRoel\n"},{"id":"109212","messageId":"alpine.DEB.1.00.0903241449200.7493@intel-tinevez-2-302","threadId":"18504","inReplyTo":"49C8E074.4030808@gmail.com","subject":"Re: [PATCH] git-cget: prints elements of C code in the git repository","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-03-24T13:52:10Z","receivedAt":"2009-03-24T13:52:10Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Tue, 24 Mar 2009, Roel Kluin wrote:\n\n> > - the name is not expressive enough,\n> \n> How about get-def? If it's too long it will become tiresome to type.\n\nIMHO \"git grep-c\" would be more to the point...\n\n> > - the commit message is severely lacking (I had to apply it and run it \n> >   to find out what problem it tries to solve),\n> \n> This is probably better:\n> [...]\n\nYes, I like it!\n\n> > - maybe it would be nicer to integrate this into git grep itself?  \n> >   Maybe by allowing multi-line matches and default patterns, or \n> >   pattern templates?\n> \n> I did attempt to program it in C, but I am more comfortable with bash.\n\nDid I misunderstand your code?  I thought all it does is provide a way to \nmatch multiline patterns... but then, I could not do more than just \nquickly glance over the code.\n\n> Also, what would be more appropriate for this purpose, I think, is a git \n> sed.\n\nJust as it happens, this is a toy I am working on and off these days... \nstrbuf_regsub() is already done, and half the needed code is in my version \ngit grep.\n\nCiao,\nDscho\n"},{"id":"109213","messageId":"20090324135906.GA10644@coredump.intra.peff.net","threadId":"18504","inReplyTo":"49C8E074.4030808@gmail.com","subject":"Re: [PATCH] git-cget: prints elements of C code in the git repository","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-03-24T13:59:07Z","receivedAt":"2009-03-24T13:59:07Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Mar 24, 2009 at 02:30:28PM +0100, Roel Kluin wrote:\n\n> > - the commit message is severely lacking (I had to apply it and run it to \n> >   find out what problem it tries to solve),\n> \n> This is probably better:\n> \n> This script shows where elements of C code are defined in the git-repository.\n> It is still experimental, although it should work in most cases.\n\nWouldn't it be a lot easier to base this on something like ctags, which\nalready knows how to do all the parsing of C quirky C?\n\nI.e.:\n\n  git ls-files | xargs ctags\n  vi -t get_sha1\n\nWhere you can replace \"vi\" with your editor of choice. And if you really\nlike getting the definition dumped to stdout, writing a command-line\nviewer for the ctags format would be quite simple (and I would be\nsurprised if one hasn't been written already).\n\n-Peff\n"},{"id":"109214","messageId":"d4bc1a2a0903240704s34547647s28e6df83455f89c@mail.gmail.com","threadId":"18504","inReplyTo":"20090324135906.GA10644@coredump.intra.peff.net","subject":"Re: [PATCH] git-cget: prints elements of C code in the git repository","fromName":"Stefan Karpinski","fromEmail":"stefan.karpinski@gmail.com","sentAt":"2009-03-24T14:04:28Z","receivedAt":"2009-03-24T14:04:28Z","isPatch":true,"sender":{"key":"stefan.karpinski@gmail.com","avatar":"https://gravatar.com/avatar/780cfb8dd7d7dc749d7276a4ca2ec24e7f0482cfce509717c5ddd165fd2cc9d9?d=mp&s=160"},"body":"On Tue, Mar 24, 2009 at 9:59 AM, Jeff King <peff@peff.net> wrote:\n>\n> Wouldn't it be a lot easier to base this on something like ctags, which\n> already knows how to do all the parsing of C quirky C?\n\nCtags also has the advantage of handling other languages. According to\nthe man page: C, Pascal, Fortran, YACC, lex, and lisp.\n"},{"id":"109215","messageId":"alpine.DEB.1.00.0903241505080.7493@intel-tinevez-2-302","threadId":"18504","inReplyTo":"20090324135906.GA10644@coredump.intra.peff.net","subject":"Re: [PATCH] git-cget: prints elements of C code in the git repository","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-03-24T14:05:46Z","receivedAt":"2009-03-24T14:05:46Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Tue, 24 Mar 2009, Jeff King wrote:\n\n>   git ls-files | xargs ctags\n\nOr 'git ls-files -z | xargs -0r ctags', which fails with Solaris' default \nxargs, though.\n\nCiao,\nDscho\n"},{"id":"109216","messageId":"e2b179460903240738x272c884q62a666931ce99c2f@mail.gmail.com","threadId":"18504","inReplyTo":"20090324135906.GA10644@coredump.intra.peff.net","subject":"Re: [PATCH] git-cget: prints elements of C code in the git repository","fromName":"Mike Ralphson","fromEmail":"mike.ralphson@gmail.com","sentAt":"2009-03-24T14:38:06Z","receivedAt":"2009-03-24T14:38:06Z","isPatch":true,"sender":{"key":"mike.ralphson@gmail.com","avatar":"https://avatars.githubusercontent.com/u/21603?v=4"},"body":"2009/3/24 Jeff King <peff@peff.net>:\n> Wouldn't it be a lot easier to base this on something like ctags, which\n> already knows how to do all the parsing of C quirky C?\n>\n> I.e.:\n>\n>  git ls-files | xargs ctags\n>  vi -t get_sha1\n>\n> Where you can replace \"vi\" with your editor of choice.\n\nThis kind of pipeline has the benefit that it can actually work on the\n*repository*, and not just the working copy (as per the posted\nscript).\n\nAlthough this kind of tool might be useful (I might even use it myself\nfor working on git, rather than as *part of git* on my other projects,\nwhich are not written in C), it's a bit tangential even for contrib/\nisn't it?\n\n> And if you really like getting the definition dumped to stdout,\n> writing a command-line viewer for the ctags format would be\n> quite simple (and I would be surprised if one hasn't been\n> written already).\n\nhttp://users.telenet.be/bdr/pub/cshow/  ?\n\nMike\n"},{"id":"109217","messageId":"alpine.DEB.1.00.0903241555360.7493@intel-tinevez-2-302","threadId":"18504","inReplyTo":"e2b179460903240738x272c884q62a666931ce99c2f@mail.gmail.com","subject":"Re: [PATCH] git-cget: prints elements of C code in the git repository","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-03-24T14:56:23Z","receivedAt":"2009-03-24T14:56:23Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Tue, 24 Mar 2009, Mike Ralphson wrote:\n\n> 2009/3/24 Jeff King <peff@peff.net>:\n> > Wouldn't it be a lot easier to base this on something like ctags, which\n> > already knows how to do all the parsing of C quirky C?\n> >\n> > I.e.:\n> >\n> >  git ls-files | xargs ctags\n> >  vi -t get_sha1\n> >\n> > Where you can replace \"vi\" with your editor of choice.\n> \n> This kind of pipeline has the benefit that it can actually work on the \n> *repository*, and not just the working copy (as per the posted script).\n\nDid I miss something?  git ls-files pipes only the names to xargs, not the \nfull contents, right?\n\nCiao,\nDscho\n"},{"id":"109218","messageId":"46dff0320903240808p5ad287d8j9245ee9f79ff6851@mail.gmail.com","threadId":"18504","inReplyTo":"alpine.DEB.1.00.0903241449200.7493@intel-tinevez-2-302","subject":"Re: [PATCH] git-cget: prints elements of C code in the git repository","fromName":"Ping Yin","fromEmail":"pkufranky@gmail.com","sentAt":"2009-03-24T15:08:01Z","receivedAt":"2009-03-24T15:08:01Z","isPatch":true,"sender":{"key":"pkufranky@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5346?v=4"},"body":"On Tue, Mar 24, 2009 at 9:52 PM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n\n>> Also, what would be more appropriate for this purpose, I think, is a git\n>> sed.\n>\n> Just as it happens, this is a toy I am working on and off these days...\n> strbuf_regsub() is already done, and half the needed code is in my version\n> git grep.\n>\n\nthis is my version\n\n[alias]\nsed = !git ls-files --stage | grep ^100 | awk '{print $4}' | xargs sed\n\nThen i can do\n\ngit sed -i 's/A/B/g'\n"},{"id":"109222","messageId":"25e057c00903240917w56fd4c08p8bbf2edbb34fe244@mail.gmail.com","threadId":"18504","inReplyTo":"20090324135906.GA10644@coredump.intra.peff.net","subject":"Re: [PATCH] git-cget: prints elements of C code in the git repository","fromName":"roel kluin","fromEmail":"roel.kluin@gmail.com","sentAt":"2009-03-24T16:17:00Z","receivedAt":"2009-03-24T16:17:00Z","isPatch":true,"sender":{"key":"roel.kluin@gmail.com","avatar":null},"body":"> Wouldn't it be a lot easier to base this on something like ctags, which\n>  already knows how to do all the parsing of C quirky C?\n>\n>  I.e.:\n>\n>   git ls-files | xargs ctags\n>   vi -t get_sha1\n\nYou are right, I'll see what I can do with it.\n"},{"id":"109224","messageId":"d9c1caea0903240933n6dea7ddcl90a5e105c2a45b52@mail.gmail.com","threadId":"18504","inReplyTo":"e2b179460903240738x272c884q62a666931ce99c2f@mail.gmail.com","subject":"Re: [PATCH] git-cget: prints elements of C code in the git repository","fromName":"Steven Tweed","fromEmail":"orthochronous@gmail.com","sentAt":"2009-03-24T16:33:13Z","receivedAt":"2009-03-24T16:33:13Z","isPatch":true,"sender":{"key":"orthochronous@gmail.com","avatar":null},"body":"On Tue, Mar 24, 2009 at 2:38 PM, Mike Ralphson <mike.ralphson@gmail.com> wrote:\n> 2009/3/24 Jeff King <peff@peff.net>:\n> This kind of pipeline has the benefit that it can actually work on the\n> *repository*, and not just the working copy (as per the posted\n> script).\n\nSpeaking of wanting things to work with the actual repository , one\nthing that I've been meaning to continue work on if I get the time is\nbasically a 'show me any commit diff's that involve string s' (ie, the\nlocations in which a change involving s occurs rather than just\n'current file contains s (in exactly the same ways the previous\nversion did). I'm extremely unlikely to actually produce anything\nbased on that in the near future. But one thing that struck me that\nmight be reasonably useful is some way of filtering the \"context\" that\na string occurs in (is it in generic code context, in a string or in a\ncomment). These are things that tend to be reasonably parametrisable\nby regular expressions (although escaping string delimiters within in\nstrings makes completely correct behaviour tricky), so if git-grep\nitself were to be extended I'd prefer something that can be specified\nper search in a more generally usable way than something very C\nspecific. Of course this is a quite difficult task as the actual diff\nmay not contain enough lines to distinguish, eg, that it occurs within\na longer comment. (As already disclaimed, I'm unlikely to actually get\naround to doing any of this work).\n\ncheers, dave tweed\n"},{"id":"109225","messageId":"e2b179460903240937p58dff7e8u238fbe06785cdb77@mail.gmail.com","threadId":"18504","inReplyTo":"alpine.DEB.1.00.0903241555360.7493@intel-tinevez-2-302","subject":"Re: [PATCH] git-cget: prints elements of C code in the git repository","fromName":"Mike Ralphson","fromEmail":"mike.ralphson@gmail.com","sentAt":"2009-03-24T16:37:36Z","receivedAt":"2009-03-24T16:37:36Z","isPatch":true,"sender":{"key":"mike.ralphson@gmail.com","avatar":"https://avatars.githubusercontent.com/u/21603?v=4"},"body":"2009/3/24 Johannes Schindelin <Johannes.Schindelin@gmx.de>:\n>> This kind of pipeline has the benefit that it can actually work on the\n>> *repository*, and not just the working copy (as per the posted script).\n>\n> Did I miss something?  git ls-files pipes only the names to xargs, not the\n> full contents, right?\n\nSee where I wrote \"this kind of pipeline\" vs \"git ls-files\" which was\njust quoting Peff? 8-)\n\nI dunno, maybe C folk using git would only be interested in the\nindex/working copy, but that tells me this script is even more\ntenuously linked to git. We don't bundle a compiler just because it\ncan use git ls-files to work out what to compile...\n\nThe script might be best as a standalone tool which just happened to\ntake advantage of the VCS in use by reacting to its surroundings. Then\nit would also be useful by hg, svn, cvs people etc.\n\nIf it actually used the information in the repository to be able to\nrun git blame on the definitions, or show a git log -p style list of\nchanges in the definition, that might be different.\n\nMike\n"},{"id":"109311","messageId":"20090325042343.GA15498@coredump.intra.peff.net","threadId":"18504","inReplyTo":"d9c1caea0903240933n6dea7ddcl90a5e105c2a45b52@mail.gmail.com","subject":"Re: [PATCH] git-cget: prints elements of C code in the git repository","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-03-25T04:23:43Z","receivedAt":"2009-03-25T04:23:43Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Mar 24, 2009 at 04:33:13PM +0000, Steven Tweed wrote:\n\n> Speaking of wanting things to work with the actual repository , one\n> thing that I've been meaning to continue work on if I get the time is\n> basically a 'show me any commit diff's that involve string s' (ie, the\n> locations in which a change involving s occurs rather than just\n> 'current file contains s (in exactly the same ways the previous\n> version did). I'm extremely unlikely to actually produce anything\n\nHow about \"git log -S\", or does that somehow not meet your needs (and if\nnot, how)?\n\n-Peff\n"},{"id":"109626","messageId":"25e057c00903270222v7acad9ebxf2ed4242570f3de5@mail.gmail.com","threadId":"18504","inReplyTo":"alpine.DEB.1.00.0903241257430.7493@intel-tinevez-2-302","subject":"Re: [PATCH] git-cget: prints elements of C code in the git repository","fromName":"roel kluin","fromEmail":"roel.kluin@gmail.com","sentAt":"2009-03-27T09:22:42Z","receivedAt":"2009-03-27T09:22:42Z","isPatch":true,"sender":{"key":"roel.kluin@gmail.com","avatar":null},"body":"Hi Johannes,\n\n> - it misdetects functions: trying\n>\n>        $ ./git-cget -f get_sha1.*\n\nThe .* is not strict enough. What you want to do instead is:\n\n$ ./git-cget -f \"get_sha1[A-Za-z0-9_]*\"\n\nand that will give correct matches.\n\nRoel\n"},{"id":"109633","messageId":"alpine.DEB.1.00.0903271225380.12753@intel-tinevez-2-302","threadId":"18504","inReplyTo":"25e057c00903270222v7acad9ebxf2ed4242570f3de5@mail.gmail.com","subject":"Re: [PATCH] git-cget: prints elements of C code in the git repository","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-03-27T11:26:34Z","receivedAt":"2009-03-27T11:26:34Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 27 Mar 2009, roel kluin wrote:\n\n> Hi Johannes,\n> \n> > - it misdetects functions: trying\n> >\n> >        $ ./git-cget -f get_sha1.*\n> \n> The .* is not strict enough. What you want to do instead is:\n> \n> $ ./git-cget -f \"get_sha1[A-Za-z0-9_]*\"\n> \n> and that will give correct matches.\n\nNo, the problem was that it did not show a function _definition_, but \nmistook a function _call_ for a definition.\n\nCiao,\nDscho\n"}]}