[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4. 새로운 매크로를 정의하는 방법

매크로는 다양한 방법으로 정의될수 있으며, 재정의되거나 삭제될 수 있다. 또 한 이전의 값을 잃어버리지 않고 매크로를 재정의하는 것이 가능하며 나중에 다 시 가져올 수도 있다.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.1 매크로를 정의하기

정의하거나 재정의하는 일반적인 방법은 내장 매크로인 define을 사용하는 것 이다.

 
define(name [, expansion])

위에서 nameexpansion으로 정의된다. 만일 expansion이 주어지지 않는다면 name은 텅 빈 것으로 정의된다.

define은 확장되지 않는다.

다음의 예는 매크로 foo를 텍스트 ‘Hello World.’로 정의한다.

 
define(`foo', `Hello world.')
⇒
foo
⇒Hello world.

위에서 빈라인이 나타나는 것은 뉴라인문자는 매크로 정의의 일부분이 아니라 서 출력으로 복사된 것이다. 이것은 매크로 dnl을 사용하여 제거할 수 있다. 자세 한 것은 See section 입력에서 공백문자 제거하기.

define 매크로는 인자가 있을 때에만 인식된다.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.2 매크로와 인자

매크로는 인자를 가질수 있다. n번째 인자는 확장 텍스트에서 $N으로 사용하 며 이것은 매크로가 확장될 때 n번째의 실제적인 인자로 교체된다. 여기에 두 개 의 인자를 가지는 매크로의 예제가 있다. 간단하게 두 개의 인자의 순서를 바꾸 는 것이다.

 
define(`exch', `$2, $1')
⇒
exch(arg1, arg2)
⇒arg2, arg1

인자를 define으로 예약하고자 한다면 아래 예에서와 같이 사용할 수 있다.

 
define(`exch', `$2, $1')
⇒
define(exch(``expansion text'', ``macro''))
⇒
macro
⇒expansion text

쌍따옴표로 둘러쳐진 표현식을 보려면 See section 매크로의 인자를 따옴표로 묶기.

GNU m4는 ‘$’ 다음에 한자리수 이상의 십진수가 올 수 있다. 매크로는 인자의 수에는 제한이 없다. 이 점이 한자리 수만 올수 있는 UNIX 버전의 m4와는 다른 점이다.

특별하게, $0 은 항상 매크로 자신의 이름으로 확장된다는 점이다.

 
define(`test', ``Macro name: $0'')
⇒
test
⇒Macro name: test

만일 확장된 텍스트안에 따옴표로 둘러싸인 텍스트를 넣고 싶다면, 그 따옴표 는 따옴표 처리된 문자열 속에 내장되어야 한다. 다음과 같이,

 
define(`foo', `This is macro `foo'.')
⇒
foo
⇒This is macro foo.

확장된 텍스트 안에 있는 ‘foo’는 확장되지 않는다. 그것이 따옴표로 묶여진 이 상은 더 이상 명칭이 아니다.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.3 매크로에서 특별한 인자

활성화된 인자의 개수와 전체 인자에 접근할 수 있는 특별한 표기법이 있다.

매크로 호출에서 활성화된 인자의 개수는 확장된 텍스트에서 $# 으로 참조할 수 있다. 그래서, 매크로는 다음과 같이 인자의 개수를 보여줄 수도 있다.

 
define(`nargs', `$#')
⇒
nargs
⇒0
nargs()
⇒1
nargs(arg1, arg2, arg3)
⇒3

$* 표기법은 확장된 텍스트에서 모든 활성화된 인자를 참조할 수 있도록 해준다. 참조할 때는 따옴표 없이, 사이에 쉼표가 온다. 예를 들면

 
define(`echo', `$*')
⇒
echo(arg1,    arg2, arg3 , arg4)
⇒arg1,arg2,arg3 ,arg4

가끔 각각의 인자가 따옴표로 처리될 필요성이 있다면 $@ 표기법이 그것을 취급한다. 이것은 각각의 인자를 따옴표 처리한다는 것만 제외하면 $* 과 같다. 간단한 예를 하나 들어보자.

 
define(`echo', `$@')
⇒
echo(arg1,    arg2, arg3 , arg4)
⇒arg1,arg2,arg3 ,arg4

어느때 어느 것을 사용해야 하는가? 물론 이것들은 확장된 텍스트를 m4가 다시 읽을 때에는 다 먹혀든다. 차이점을 보도록 하자.

 
define(`echo1', `$*')
⇒
define(`echo2', `$@')
⇒
define(`foo', `This is macro `foo'.')
⇒
echo1(foo)
⇒This is macro This is macro foo..
echo2(foo)
⇒This is macro foo.

이해가 잘되지 않는 다면, See section 매크로 호출을 추적하기.

확장된 텍스트에서의 ‘$’ 부호 다음에 아무것도 따라오지 않는다면, m4는 이것을 간단히 다른 텍스트처럼 매크로 확장으로 이해한다.

 
define(`foo', `$$$ hello $$$')
⇒
foo
⇒$$$ hello $$$

$12’와 같이 어떤 것을 매크로로 확장하기를 바란다면, $ 다음에 한쌍의 따옴 표를 써주면 된다. 이것은 m4 로 하여금 $ 부호가 인자를 참조하지 않도록 한다.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.4 매크로의 삭제

하나의 매크로 정의는 undefine으로 삭제될 수 있다.

 
undefine(name)

name은 삭제될 매크로 명칭이다. 매크로 명칭은 보통 따옴표로 둘러싸는 것이 필요한데, 그렇지 않으면 확장될 것이다.

undefine 의 확장은 되지 않는다.

 
foo
⇒foo
define(`foo', `expansion text')
⇒
foo
⇒expansion text
undefine(`foo')
⇒
foo
⇒foo

name이 아무런 매크로 정의도 가지지 않는다면 에러로 처리되고 undefine은 아무 일도 하지 않는다.

undefine 매크로는 인자가 있을 때에만 인식된다.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.5 매크로 명칭 변경하기

이미 정의된 매크로는 그 명칭을 변경할 수 있다. 내장 매크로 defn 이 이런 일을 한다.

 
defn(name)

이것은 따옴표가 붙은 name의 정의로 확장된다. 인자가 정의된 매크로가 아 니라면 확장은 되지 않는다.

name 이 사용자 정의 매크로라면, 따옴표 있는 정의는 간단하게 따옴표있는 확장 텍스트로 된다. name 이 내장된 것이라면 그 확장은 내장되어 있는 내부 정의를 가르키는 특별한 토큰이 된다. 이 토큰은 define 이나 pushdef 의 두 번째 인자로서만 의미가 있고 다른 문맥에서 사용된다면 무시된다.

이해하기에 가장 좋은 방법은 예를 들어보는 것이다. 아래는 undefinezap으로 바꾸는 방법을 보여준다.

 
define(`zap', defn(`undefine'))
⇒
zap(`undefine')
⇒
undefine(`zap')
⇒undefine(zap)

이 방법에서 defn 은 매크로 정의나 모든 내장 매크로의 정의를 복사하는 방법 으로 사용될 수 있다. 원래 매크로가 제거되었다 할지라도 다른 이름은 그 정의에 접근할 수 있다.

defn 매크로는 인자가 있을 때에만 인식된다.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.6 임시로 다시 정의하는 매크로

매크로를 임시로 다시 정의할 수 있다. 나중에 이전에 정의해둔 상태로 되돌아 갈 수도 있다. 이러한 일을 하는 것은 내장 매크로 pushdefpopdef이다.

 
pushdef(name [, expansion])
popdef(name)

이것은 defineundefine 관계와 아주 유사하다.

이 매크로는 스택과 비슷하게 작동한다. 하나의 매크로는 pushdef를 사용하여 임시로 재정의할 수 있다. pushdef는 이미 존재하는 name의 정의를 다른 것으로 치환하며 새로운 정의를 하기 전에 이전에 정의된 것을 저장한다. 이전에 정의된 것이 없다면, pushdef는 정확하게 define과 같다.

현재 하나의 매크로가 여러개의 정의를 가지고 있다고 가정하자. 당연히 그 중 하나의 정의만 사용할 수 있을 것이다. 가장 꼭대기의 정의는 popdef로 제거할 수 있다. 이전에 정의된 것이 없다면 popdefundefine과 같다.

 
define(`foo', `Expansion one.')
⇒
foo
⇒Expansion one.
pushdef(`foo', `Expansion two.')
⇒
foo
⇒Expansion two.
popdef(`foo')
⇒
foo
⇒Expansion one.
popdef(`foo')
⇒
foo
⇒foo

여러개로 정의된 하나의 매크로가 define으로 재정의된다면, 최상위의 정의는 새로운 정의로 대치된다. undefine으로 제거한다면, 최상위 하나만이 아닌 모든 정의가 사라질 것이다.

 
define(`foo', `Expansion one.')
⇒
foo
⇒Expansion one.
pushdef(`foo', `Expansion two.')
⇒
foo
⇒Expansion two.
define(`foo', `Second expansion two.')
⇒
foo
⇒Second expansion two.
undefine(`foo')
⇒
foo
⇒foo

내장 매크로 pushdefdefn으로 임시로 재정의하는 것이 가능하다.

pushdefpopdef 매크로는 인자가 있을 때에만 인식된다.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.7 간접적인 매크로 호출

어떤 매크로던지 indir로 간접적으로 호출할 수 있다.

 
indir(name, ...)

이것은 매크로 name을 호출할 때 그것의 나머지 인자가 건네진다. 이것은 바람직 하지 못한 명칭의 매크로 호출에 사용된다. define은 그러한 명칭이 정의되는 것을 허용한다.

 
define(`$$internal$macro', `Internal macro (name `$0')')
⇒
$$internal$macro
⇒$$internal$macro
indir(`$$internal$macro')
⇒Internal macro (name $$internal$macro)

여기에서 주의 할 점은 커다란 매크로 패키지 내에서 이미 정의된 것을 가지고 있을 수도 있다는 점인 데, 그렇다고 우연히 호출되는 일은 없을 것이다. 그것들은 단지 내장 매크로 indir로만 호출될 수 있을 것이다.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.8 간접적으로 내장 매크로 호출하기

내장 매크로는 builtin을 사용하여 간접적으로 호출할 수 있다.

 
builtin(name, ...)

이것은 내장 매크로 name을 호출하는 데 나머지 인자가 건네진다. 이렇게 사용한다면 name은 원래의 정의와는 다른 정의를 가질 수 있을 것이다.

builtin 매크로는 인자가 있을 때에만 인식된다.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Autobuild on June 15, 2016 using texi2html 1.82.