본문 바로가기

4.개발 및 운영 환경

[NSIS] LogicLib이용한 if, switch, while, for, loopuntil문 사용하기

[NSIS] LogicLib이용한 if, switch, while, for, loopuntil문 사용하기

Writer: http://ospace.tistory.com/(ospace114@empal.com) 2008.08.29

개요

NSIS를 사용하다보면 값을 비교해서 원하는 처리를 하려면 StrCmp 명령어를 사용해서 처리를 했다.
반복적인 루프를 만들려면 goto 명령어와 label를 사용해서 작성을 해야했다.
이는 상당히 번거롭고 머리를 아프게 만드는 작업이다. 그렇다고 해서 NSIS 도움말에서 if문이나 for문을 검색해도 나오지를 않는다. 그러나 우연하게 NSIS 도움말에서 원하는 것이 발견이 되었다.

들어가기

if문, swith문, while문, for문, loopuntil문을 사용할 수 있게 도와주는게 LogicLib.nsh 파일이다. 이안에 해당 문들이 정의되어 있다. 이 파일은 NSIS가 설치된 폴더에서 Include폴더에 들어있다.
기본적으로 모던 UI를 사용하고 있다면 굳이 따로 포함시킬필요는 없다.
혹시 문제가 발생한다면 아래 명령어을 파일 앞에 추가하면 된다.

!include LogicLib.nsh

아래 나오는 예제는 NSIS에 있는 예제를 그대로 사용했다. 그러므로 원본을 참고하려면 아래 참조[1]를 보면 될 것이다.

이전 방식

이전 방식이라고는 하지만 LogicLib를 사용하는 안는 것뿐이다. 이때 사용하는게 StrCmp, StrCmpS이다.
뒤에 S가 붙은 것은 대소문자 구별하여 비교한다는 의미이다.

실제 예제를 보자.

StrCmp $0 'some value' 0 +3
  MessageBox MB_OK '$$0 is some value'
  Goto done
StrCmp $0 'some other value' 0 +3
  MessageBox MB_OK '$$0 is some other value'
  Goto done
# else
  MessageBox MB_OK '$$0 is "$0"'
done:

$0 변수에 저장된 값이 "some value"인가 "some other value"인가에 따라서 3가지 처리로 구분된다.
주의 할 것은 StrCmp의 뒤에 나오는 0과 +3값이다. 점프하는 줄 수이다. 0는 바로 다음줄이고 +3은 다음 줄 포함해서 3번째 줄로 이동한다. 그래서 위의 예제는 +3에 의해서 다음 StrCmp로 이동한다. 이를 NSIS에서는 상대적인 이동(relative jump)라고 한다.
그리고 라벨 "done:"를 이용한 이동도 가능하다. 주의 할 것은 이 라벨이 전역적이라는 것이다. 즉, 다른 곳에 비슷한 라벨을 사용하면, 개발하다가 착각할 수 있기 때문이다.

그리고 "# else"는 주석이다. else문으로 착각하면 안된다.

위의 코드는 이해하기 힘들고 상당히 복잡한 구조를 가진다. 어쩔 수 없다. 이렇게라고 된다면 이렇게 사용해야지...그러나 더 쉬운 방법이 있으니 참조해보자.

IF 문 사용

${If} $0 == 'some value'
  MessageBox MB_OK '$$0 is some value'
${ElseIf} $0 == 'some other value'
  MessageBox MB_OK '$$0 is some other value'
${Else}
  MessageBox MB_OK '$$0 is "$0"'
${EndIf}

상당히 깔끔하고 보기도 쉽다. 단지 if문과 elseif문 등을 쓰는데 조금 번거롭다는 것 뿐이다. 기능은 앞의 것과 동일하다.

그리고 ip문에서 중복 비교하는 경우가 있다. 예를 들어 두 변수 값이 모두 공배이어야 실행되게하는 경우이다.
일반 IF문 처럼 and나 or 연산자가 없지만, 아래와 같이 사용이 가능하다.

${If} $0 == ''
${AndIf} $1 == ''
  MessageBox MB_OK|MB_ICONSTOP 'both are empty!'
${EndIf}

위의 예제에서는 $0와 $1이 모두 빈 값이면 메시지박스를 뛰운다.

SWITCH 문 사용

${Switch} $0
  ${Case} 'some value'
    MessageBox MB_OK '$$0 is some value'
    ${Break}
  ${Case} 'some other value'
    MessageBox MB_OK '$$0 is some other value'
    ${Break}
  ${Default}
    MessageBox MB_OK '$$0 is "$0"'
    ${Break}
${EndSwitch}

Switch문 역시 깔끔하다. If문이 더 깔끔하다고 느끼겠지만, 엄연히 비교하는 방법이 틀리기에 적당히 알아서 쓰면 된다.

Loop문 사용

이제 Loop문 종류를 살펴보겠다. 종류로는 While, For, LoopUntil이 제공된다.
먼저, While문을 보겠다.

StrCpy $R1 0
${While} $R1 < 5
  IntOp $R1 $R1 + 1
  DetailPrint $R1
${EndWhile}

While문은 조건이 참이면 계속 실행한다. 추가로 NSIS에서 값 대입은 대입연산자("=")가 없기에 StrCpy라는 명령어를 사용해야한다. 위의 "StrCpy $R1 0"는 $R1에 0값을 넣는다라는 의미이다. 여기서 알수 있는 사실 하나는 숫자나 문자를 구별하지 않는다는 점이다.
그리고 IntOp로 값 연산을 한다. InterOp역시 NSIS에서 연산작업을 할 수 있게하는 스크립트이다.

다음으로 for문을 보겠다.

${For} $R1 1 5
  DetailPrint $R1
${Next}

For문를 보면 $R1값이 1에서 5까지 증가하면서 처리한다.
다음은 LoopUntil문을 살펴보겠다.

StrCpy $R1 0
${Do}
  IntOp $R1 $R1 + 1
  DetailPrint $R1
${LoopUntil} $R1 >= 5

이것 역시 앞의 For문과 같이 1에서 5까지 증가하면서 처리한다. 여기서는 중간에 증가연산이 필요하다.

결론

이상으로 기본적인 LogicLib예제를 살펴보았다. 지금은 간략히 살펴본 것이라서 이외에 다른 여러가지 사용 방법이 있다. 자세한 참조는 NSIS 설치폴더의 Example 폴더에 있는 LogicLib.nsi 파일을 참조하면 여러기자 방법을 살펴볼 수 있다. 필자도 필요할 때마다 보기에 아직 LogicLib.nsi 파일 전부는 보지못했다.

지금까지 내용이 여러분에게 도움이 되었으면 하는 바람이다.

참조

[1] NSIS User Manual, "2.3 Scripting structure"

반응형