디렉토리에 프로그램 P11이 있고 이 프로그램이 2개의 다른 프로그램 P21과 P22를 호출한다고 가정합니다. P21과 P22는 각각 2-2개의 다른 프로그램을 호출합니다.
즉
Level-1: |--------------P11-------------|
Level-2: |--------P21----------| |----------P22----------|...
Level-3: P31 P32 P33 P34...
. . . .
. . . .
수형도와 마찬가지로 100개의 레벨이 있고 각 레벨에는 100개의 노드가 있으므로 총 1000개의 노드가 있습니다.
이와 같은 트리 구조를 제공하려면 쉘 스크립트가 필요합니다.
예를 들어, 쉘 스크립트 프로그램은 -' MYPGM.sh
'입니다.
런타임 시 매개변수가 필요합니다. 여기에 프로그램 이름(예: P11)을 제공할 수 있습니다. 그리고 스크립트는 그러한 트리 다이어그램을 제공합니다.
출력 구조는 위에 제공된 다이어그램과 같은 형식일 필요는 없습니다. 색인이나 제안하는 모든 것을 사용할 수 있습니다. 예를 들어 출력 파일은 다음과 같습니다.
1. P11
1.1 P21 - 1.2 P22
1.1.1 P31 - 1.1.2 P32 – 1.2.1 P33 – 1.2.2 P34
즉, 각 프로그램의 인덱스 = 상위 프로그램의 인덱스 + "." + 해당 상위 프로그램의 일련 번호입니다.
사실은 레벨 수와 각 레벨의 노드 수를 알 수 없지만 매우 크다는 것입니다.
다른 프로그램을 호출하기 위한 프로그램 구문은 다음과 같습니다.
'CHILD_PGM_NAME'에게 전화 걸기
특정 프로그램에서 서브루틴을 찾는 명령은 다음과 같습니다.
egrep '^CALL| CALL ' $pgm_name > call_output | cut -d'"' -f2 call_output > call_output_cut | cat call_output_cut
막혔습니다. 위의 출력 파일을 얻기 위해 이 명령을 반복하는 방법입니다.
누구든지 제안을 할 수 있나요?
답변1
이 문제에는 awk, python, perl 또는 이와 유사한 것을 제안합니다. 아래의 시작점은 아직 액세스되지 않은 경우 "프로그램"을 대기열에 추가하는 Perl 스크립트입니다. 출력은 그래픽 시각화 형식입니다(@derobert가 제안한 대로).
#!/usr/bin/perl
print "digraph{\n rankdir=LR \n";
my %visited = ();
while(<>){ # for all lines in all files in @ARGV
$visited{$ARGV}=1; # $ARGV = current file
if(/\bCALL\s*"(.+?)"/) {
print "$ARGV -> $1;\n" ;
push @ARGV,$1 unless $visited{$1};
$visited{$1}=1;
}
}
print "}\n";
용법:
perl calltree p1 > x.dot
dot -Tpdf -o x.pdf x.dot
아니면 (@derobert에게 감사드립니다)
dot -Tx11 x.dot
지금 차트를 확인해 보세요.
@muru가 지적했듯이 이것은 일반적으로 나무가 아닙니다.
답변2
@JJoao의 방법은 확실히 사용하기에 가장 좋습니다. 그러나 나는 흥미로울 수 있는 매우 비효율적인 스크립트를 작성했습니다.
#! /bin/bash
SRC_DIR="/path/to/programs"
TMP_DIR="/tmp/tree"
declare -A FUNCS
iterate ()
(
program="$1"
FUNCS["$program"]="$TMP_DIR/$program"
mkdir "${FUNCS[$program]}"
grep -Po '(?<=\bCALL ")[^"]*' "$SRC_DIR/$program" | while read child
do
if [[ -n ${FUNCS[$child]} ]]
then
ln -s "${FUNCS[$child]}" "${FUNCS[$program]}/$child"
else
iterate "$child"
fi
done
)
[[ -n $1 ]] && { iterate "$1"; tree -dlo call-graph.html -H "$TMP_DIR" "$TMP_DIR"; }
rm -rf "$TMP_DIR"
디렉토리를 생성합니다나무, 각 디렉터리는 함수를 나타내며 해당 함수가 호출하는 다른 디렉터리/함수에 대한 기호 링크를 포함합니다. 이 tree
프로그램은 자연스럽게 나무를 그리는 데 능숙합니다(이 -l
옵션은 재귀가 감지되지 않는 한 기호 링크를 따라 -o
HTML 출력을 생성합니다).
물론 이상적으로는 귀하의 언어에 적합한 호출 그래프 생성기를 살펴보는 것이 좋습니다. 이것그래서 질문은C 언어의 여러 버전이 나열되어 있으며 해당 언어를 지원하는 버전을 찾을 수 있습니다.