| 개요
프로프레임에서 수식 계산에 사용하는 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 |
결과는 스크립트를 돌려서 성공시킨 후에 직접 확인해 보시길 ...
찌끄러기 좀 나오는데 이런 것들은 아이체크로 걸려 주시면 됩니다.
'컴퓨터활용 > 유닉스' 카테고리의 다른 글
sprintf함수에서 포매팅 처리 방법 (0) | 2018.04.25 |
---|---|
ipcs, ipcrm 으로 공유메모리 삭제 방법 (1) | 2018.04.25 |
Lock option has no effect for the map (0) | 2017.07.19 |
dlopen error : Permission denied (0) | 2017.07.01 |
디렉토리 사용량 조회 (1) | 2017.06.18 |