트리 다이어그램 작성 [닫기]

트리 다이어그램 작성 [닫기]

디렉토리에 프로그램 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옵션은 재귀가 감지되지 않는 한 기호 링크를 따라 -oHTML 출력을 생성합니다).

물론 이상적으로는 귀하의 언어에 적합한 호출 그래프 생성기를 살펴보는 것이 좋습니다. 이것그래서 질문은C 언어의 여러 버전이 나열되어 있으며 해당 언어를 지원하는 버전을 찾을 수 있습니다.

관련 정보