Miscellaneous builtin macros

기본적으로 매크로에 () 가 없으면 매크로로 인식되지 않습니다.

errprint

errprint ( String . . . )
매크로의 확장 결과는 void 입니다.

format 매크로의 경우 출력이 m4 입력으로 들어가서 결과가 다시 확장되지만 errprint 매크로는 출력이 직접 stderr 로 출력되기 때문에 결과에 확장이 발생하지 않습니다. 그리고 매크로 확장 결과도 void 가 되므로 debugging 할 때 활용할 수 있습니다.

$ m4 <<\@                             $ m4 <<\@ 2> /dev/null     # 2> /dev/null 추가 
define(`foo', 100)                    define(`foo', 100)
format(`format: foo')                 format(`format: foo')
errprint(`errprint: foo')             errprint(`errprint: foo')
@                                     @

format: 100                           format: 100
errprint: foo    # 결과에 확장이 발생하지 않는다.

_foreach 매크로의 ifelse 에서 $2 값을 trace 하기위해 앞에 errprint(`$2') 를 추가

$ m4 <<\@
define(`dquote', ``$@'')
define(`dquote_elt', `ifelse(`$#', `0', `', `$#', `1', ```$1''',
                             ```$1'',$0(shift($@))')')

define(`foreach', `pushdef(`$1')_$0(`$1',
    (dquote(dquote_elt$2)), `$3')popdef(`$1')')
define(`_arg1', `$1')
define(`_foreach', `ifelse(errprint(`$2')`$2', `(`')', `',           # errprint 추가
    `define(`$1', _arg1$2)$3`'$0(`$1', (dquote(shift$2)), `$3')')')

foreach(`str', `(foo, bar, foobar)', `Word was: str
')
@

(``foo'',``bar'',``foobar'')Word was: foo
(``bar'',``foobar'')Word was: bar
(``foobar'')Word was: foobar
(`')

인수를 복수개 이상 사용하면 각각 공백으로 분리되어 출력됩니다.

$ m4 <<\@ 
errprint(`111', `222', `333')errprint(`444')
@

111 222 333444                  # 인수들이 공백으로 분리된다.

__file__ , __line__ , __program__

오류가 발생했을 때 위치정보를 표시하기 위해 제공되는 매크로입니다. 확장 결과는 quote 되어 출력됩니다.

$ m4 <<\@                   $ m4 <<\@ 
__file__                    1111111111
__line__                    2222222222
__program__                 errprint(__program__:__file__:__line__: `input error
@                           ')dnl
                            3333333333
stdin                       @
2                           
m4                          1111111111
                            2222222222
                            m4:stdin:3: input error
                            3333333333
$ m4 <<\@
define(`echo', `$@')dnl
define(`foo', ``foo :' echo(__line__
__line__)')dnl
`echo' : echo(__line__
__line__)
m4wrap(`m4wrap1 : foo
')dnl
foo(errprint(`errprint' : __line__       # errprint 매크로는 확장 결과가 void 이므로
__line__                                 # 이후에 foo() 가 실행된다.
))   
`__line__' : __line__
m4wrap(`m4wrap2 : __line__
')dnl
@

echo : 4
5
errprint : 8
9
foo : 8
8
__line__ : 11
m4wrap2 : 12
m4wrap1 : foo : 6
6

m4exit

m4exit ( exitcode )

M4 프로그램 실행을 종료할 때 사용합니다. 프로그램 실행이 정상 종료되는 것이 아니므로 m4wrap 과 divert 된 내용은 모두 discard 됩니다. exitcode 는 shell 의 종료 상태 값을 지정합니다.

$ m4 <<\@
1111111111 
m4wrap(`cleanup')dnl
divert(1)dnl
2222222222
@

1111111111
2222222222           # 정상 종료 시에는 divert 된 내용과
cleanup              # m4wrap 스트링이 모두 출력된다.
--------------------

$ m4 <<\@
1111111111 
m4wrap(`cleanup')dnl
divert(1)dnl
2222222222
m4exit(5)
@
                     # m4exit 에 의해 프로그램 실행이 abort 되어
1111111111           # m4wrap, divert 된 내용이 모두 discard 된다.

$ echo $?            # shell 종료 상태 값
5

fatal_error 사용자 정의 매크로

fatal_error ( Message )

$ m4 <<\@
define(`fatal_error',
       `errprint(__program__:__file__:__line__`: fatal error: $*
')m4exit(1)')dnl
1111111111
m4wrap(`cleanup')dnl
divert(1)dnl
2222222222
fatal_error(`divert(1) 중에 오류가 발생했습니다.')
@

1111111111
m4:stdin:8: fatal error: divert(1) 중에 오류가 발생했습니다.