컴퓨터활용/유닉스

pfmNumCalc 인자 개수 체크 쉘

멜번초이 2017. 12. 16. 22:26

개요 

프로프레임에서 수식 계산에 사용하는 pfmNumCalc 라는 함수가 있다.  계산식을 자유롭게 기술할 수 있기 때문에 참 유용한 함수이고 많이들 사용한다. 그런데 문제는 파라미터 포매팅 개수와 아규먼트 인자의 개수가 다를 경우에 문제가 발생될 수 있다.  개수가 다를 경우에 어떤 예기치 않은 문제가 발생될 수 있기 때문에 꼼꼼하게 체크해야 하지만 워낙에 개발자들이 바쁘시다 보니 많이들 놓칠 수 있다. 

쉘 프로그램을 이용해서 일괄적으로 한꺼번에 모든 프로그램의 인자 개수를 체크하는 로직을 만들어 봤다. 프로프레임 엔지니어나 일반 개발자들도 잘 응용해서 사용하면 유용할 거 같아서 공개한다. 필요한 부분을 수정해서 본인의 용도에 맞게 사용하면 좋을 것이다.


| 아이디어

pfmNumCalc 함수 뒤에는 포매팅 문자열이 뒤따라 온다. 다행스럽게도 여기 포매팅에는 % 문자가 들어있는데 이거 개수와 아규먼트 개수를 나열할 때 구분하는 콤마(,) 문자 개수를 비교하는 것이 이 쉘의 아이디어 이다. 

pfmNumCalc(&target, "(%n * %s) / %ld + %s", numVar1, strVar2, lVar3 ); 

위와 같은 예제 코드가 있을 경우 포매팅에 나열된 % 는 4개이지만 뒤에 나열된 인자 수는 3개이므로 이런 경우 계산 과정에서 문제가 발생될 수 있다.  콤마개수가 % 보다 하나 더 많기 때문에 최종 비교하기 전에 (33라인) 하나를 빼 주는 로직을 추가했다. 전체 쉘은 좀더 간단해 질 수 있는데 파일명과 라인번호를 붙여 주기 위해서 약간 로직이 더 추가 되어 있어서 전체 스크립트는 간단하다. 이로직을 만드는 데는 김신근 수석이 도왔다.  %문자와 , 문자의 개수를 카운트할 때 tr 명령을 이용한다. (16라인, 19라인)

검색을 시작하는 구간식별을 위해 pfmNumCalc( 나 pfmNumCalc   (  의 패턴이 나오면 카운팅을 시작한다. 80라인) 그리고 검색을 중단하기위해서 pfmNumCalc 함수의 끝을 식별하는 방법으로는 ); 나 )  ; 을 사용한다. (29라인)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#!/usr/bin/ksh
 
SRC_HOME=/nbsdev/compile
LOG_HOME=/tmp
LOG_FILE=$LOG_HOME/err.log
 
UPMU_ID=$1
 
file_list=`ls $SRC_HOME/$UPMU_ID/src/*/*.c`
total_cnt=`ls $SRC_HOME/$UPMU_ID/src/*/*.c | wc -l`
 
# =========================================================
# count % and , character in line 
# =========================================================
function count_comma {
  format_cnt=`echo "$line" | tr -cd "%" | wc -m`
  ((format_sum=$format_sum+$format_cnt))
    
  comma_cnt=`echo "$line" | tr -cd "," | wc -m`
  ((comma_sum=$comma_sum+$comma_cnt))    
  msg=($format_sum:$comma_cnt/$comma_sum) ${PGM_ID}:${lineno}:$line
  echo $msg >> $LOG_HOME/$PGM_ID.temp    
}
 
# =========================================================
# check whether end condition of pfmNumCalc function block
# =========================================================
function check_end {
  fnend=`echo "$line" | egrep "\);|\) *;"|wc -l`
  if [ fnend -eq 1 ];then
    fnstart=0
    fnend=0
    ((comma_sum=$comma_sum-1)) 
    if [ $format_sum -ne $comma_sum ];then 
      echo "====================================================="
      echo " INCORRECT !! $format_sum :$comma_sum  LOOK BELOW    "
      echo "====================================================="
      cat $LOG_HOME/${PGM_ID}.temp >> $LOG_FILE
    fi
    comma_sum=0
    format_sum=0
    cat $LOG_HOME/${PGM_ID}.temp
    rm -f $LOG_HOME/${PGM_ID}.temp 2>/dev/null 
  fi
}
 
# =========================================================
# MAIN PROCEDURE 
# =========================================================
startblock=0
fnstart=0
cnt=0
ifline=0
format_cnt=0
format_sum=0
comma_cnt=0
comma_sum=0
 
for FILE in $file_list
do
  PGM_ID=`echo $FILE | rev | cut -d/ -f1 | fev | cut -d. -f1`
  lineno=0
  
  ((cnt=$cnt+1))
  
  echo "($cnt/$total_cnt) $PGM_ID starting .."
  
  # skip when not found pfmNumCalc 
  func_exist=`egrep pfmNumCalc $FILE | wc -l`
  if [ $func_exist -eq 0 ];then 
    continue
  fi
 
  # main logic for each line   
  while IFS= read -r line; do 
    ((lineno=$lineno+1))
    
    if [ $fnstart -ne 1 ];then 
      > $LOG_HOME/$PGM_ID.temp
      fnstart=`echo "$line" | egrep "pfmNumCalc\(|pfmNumCalc *("|wc -l`
      if [ $fnstart -eq  1 ];then
        count_comma
        check_end
      fi
    else 
      count_comma 
      check_end
    fi
  done < "$FILE"
  rm -f $LOG_HOME/$PGM_ID.temp 2>/dev/null
done
cs

결과는 스크립트를 돌려서 성공시킨 후에 직접 확인해 보시길 ...

찌끄러기 좀 나오는데 이런 것들은 아이체크로 걸려 주시면 됩니다.