find, grep, ctags, cscope, global 본문

Programming

find, grep, ctags, cscope, global

halatha 2009. 8. 17. 17:15
2009/08/17 - [Programming] - diff, find, md5sum, patch

그냥 grep으로 찾을 때 너무 많은 파일을 검색하므로 원하는 종류의 파일에서만 찾으려면
$ find . -name [file name] -exec grep -Hn [string to find] {} \;

grep
-R: recursively search in directories
-I: skip binary files
-w: search those which is identical to whole word
-H: print file name
-n: print line number

함수 선언/구현된 곳을 찾으려면
일단 source 작성 시 규칙을 가지고 있어야 한다. 예를 들어 여기서는 선언/구현인 경우 함수 이름과 괄호 사이에 공백을 하나 넣었다.



$ ctags -R
$ vi -t foobar # foobar 구현부가 있는 파일을 바로 open
:tag foobar
ctrl + T <-> ctrl + ]

tag stack 검사:
:tags

tag file 위치 지정
:set tags=./tags,tags,/home/user/lazyness/commontags

:help tags



cscope

$ cscope -R

tab, return, ctrl + N, 아래 화살표: 다음 입력 필드로 이동
ctrl + P, 위 화살표: 직전 입력 필드로 이동
ctrl + B: (history) 직전 입력 필드로 이동해 입력값을 채워 줌
ctrl + F: (history) 다음 입력 필드로 이동해 입력값을 채워 줌
ctrl + C: 검색 시 대소문자 구분 on/off
ctrl + R: 교차 참조 파일 재생성
!: shell로 잠시 빠져 나감
ctrl + I: screen refresh
?: 도움말 화면
ctrl + D: exit from cscope

<결과 목록이 출력된 후>
1-9: 목록에서 나온 결과를 선택해서 바로 편집기를 띄움
space, +, ctrl + V: 다음 목록 화면 표시
-: 직전 목록 화면 표시
ctrl + E: 목록 순서대로 편집 시작
>: 출력 목록을 파일에 덧붙임
|: 출력 목록을 셸 명령으로 파이프
위(아래) 화살표: 출력 목록 내에서 위(아래)로 이동

<치환 명령>
Change this text string: foobar 입력후 엔터를 누른 화면에서
1-9: 목록에서 나온 결과 중 특정 행을 선택하거나 해제
*: 출력된 모든 행을 선택하거나 해제
space, +: 다음 목록 화면 표시
-: 직전 목록 화면 표시
A: 모든 행을 바꾼다고 선택
ctrl + D: 선택된 행을 변경하고 치환 기능 종료
ESC: 변경하지 않고 치환 기능 종료
1을 입력해 선택하면 번호 옆에 '>'이 출력



Tcl language를 위한 tag file 생성
$ egrep -n '^[ \t]*proc[ ]+[a-zA-Z][a-zA-Z0-9]*[ ]+\{.+\}[ ]+\{[ ]*$' *tcl > tcltags
$ awk -f tags.awk tcltags | sort > tags
$ cat tags.awk
{
    printf("%s", $2)
    split($1, a, ":")
    printf("\t./%s\t%s;\"\tf\n", a[1], a[2])
}

본격적인 프로그램을 위해 필요한 구체적인 ectags 파일 형식은 http://ctags.sourceforge.net/FORMAT 참조

규모가 큰 프로젝트를 위한 cscope index 구축
1. code를 원하는 directory에 압축 해제
$ tar xvpfz linux-x.x.x.tar.gz
2. find 명령으로 kernel 내부에서 index를 원하는 file list 생성
-prune: -path에 들어오는 directory 내부로 탐색하지 말라는 option
!: NOT
-o: 조건 양쪽을 OR로 연결
$ export LNX=`pwd`/linux-x.x.x
$ find $LNX \
 -path "$LNX/arch/*" ! -path "$LNX/arch/i386*" -prune -o \
 -path "$LNX/include/asm-*" ! -path "$LNX/include/asm-i386*" -prune -o \
 -path "$LNX/tmp*" -prune -o \
 -path "$LNX/Documentation*" -prune -o \
 -path "$LNX/scripts*" -prune -o \
 -name "*.[chxsS]" -print > ./cscope.files
3. cscope database file을 batch로 생성. 2.에서 생성한 cscope.files가 batch 작업을 실행하는 directory에 존재해야 함
-b: 검색 화면으로 들어가지 않고 교차 참조만 생성
-q: 빠른 심볼 참조를 위해 역 색인을 만드는 옵션(기본 database file인 cscope.out 이외에 cscope.in.out, cscope.po.out이라는 file 두 개가 더 생성)
-k: kernel mode option(기본 include directory path인 /usr/include를 무시)
$ cscope -b -q -k
4. database를 사용. 만일 code가 변경되었다면 다시 3번 실행
-d: 교차 참조 색인을 만들지 않고 바로 검색 화면으로 들어감
$ cscope -d

cscope를 vim에서 인식하도록 하려면 map file(http://cscope.sourceforge.net/cscope_maps.vim)을 $HOME/.vimrc에 넣으면 됨



global
vi, emacs뿐만 아니라 bash, less등과도 결합이 가능
중복을 허용해 특정 객체(ex. c function)가 존재하는(선언, 참조되는) 위치를 빠르게 알려줌
여러 버전을 하나로 묶어서 정의된 함수 위치를 모두 출력할 수 있다
정규 표현식 및 함수 이름 완성 기능 제공

$ gtags # gtags command를 이용해 index database 생성
$ global foo # foo라는 함수를 찾음
$ global -r foo # foo를 참조하는 함수를 찾음
$ global -x foo # foo라는 함수를 찾고 세부 정보를 표시
$ global -P foobar # foobar가 들어간 파일을 찾음
$ global -f myproj/foobar.c # foobar.c에 들어있는 함수 목록 나열
$ global -x my_print # 여러 version을 동시에 비교
$ global -c foo # foo로 시작하는 함수 목록 나열

탐색한 모든 파일을 순서대로 열기
$ global -x my_print | awk '{printf "view +%s %s\n", $2, $3 }'
view +100 myproj/ver1/foobar_util.c
view +100 myproj/ver2/foobar_util.c
$ !! | bash

bash shell에서 GNU global이 제공하는 자동 파일 완성 기능 통합
$ funcs()
> {
>     local cur
>     cur=${COMP_WORDS[COMP_CWORD]}
>     COMPREPLY=(`global -c $cur`)
> }
$ complete -F funcs global
$ global foo[TAB][TAB]
foo            foobar
$ global foob[TAB]
$ global foobar
myproj/foobar.c

GNU global을 bash shell로 활성화시켜 사용
GNU global package의 globash.rc file을 읽어 bash shell로 시작
$ bash --rcfile /GNU/global/installed/directory/share/gtags/globash.rc
새로 bash가 뜨고 prompt가 [/home/...]/myproj로 변경: 현재 directory는 /home/.../myproj이고, project 시작 directory가 /home/...이라는 의미
[/home/...] x foo # global x foo와 동일
> 1 foo     6 myproj/foobar.c     void foo()
[/home/...] r     # global r foo와 동일. foo는 자동으로 붙음
> 1 myproj/foobar.c
[/home/...] x my_print # 여러 버전을 동시에 비교
> 1 my_print     20 myproj/ver1/foobar_util.c void my_print(char *ptr)
2 my_print     20 myproj/ver2/foobar_util.c void my_print(char *ptr, int len)
[/home/...] show 2 # ver2/foobar_util.c를 vi로 열어서 my_print를 보여준다
[/home/...] show -l 2 # ver2/foobar_util.c를 less로 열어서 my_print를 보여 준다
[/home/...] P foobar # global xP foobar와 동일
> 1 path     1 myproj/foobar.c
2 path     1 myproj/foobar_test.c
[/home/...] pop    # 직전 결과로 돌아감
[/home/...] show   # ver1/foobar_util.c를 vi로 열어서 my_print를 보여준다

참고
'vi 시작하기 개정 6판', 린다 램/아놀드 로빈스 저, 서울시립대학교 LUG 역, 한빛미디어 2001년 출간
마이크로소프트 인텔리센스: http://msdn2.microsoft.com/ko-kr/library/hcw1s69b(VS.80).aspx
ectags: http://ctags.sourceforge.net
tcl language를 위한 tags script: http://wiki.tcl.tk/2974
cscope: http://cscope.sourceforge.net
cscope(win32): http://iamphet.nm.ru/cscope/index.html
cscope 활용법: http://docs.sun.com/source/806-3567/cscope.html
GNU global: http://www.gnu.org/software/global

Comments