2014-12-28 5 views
0

GNU M4에서 비어 있지 않은 인수 (args는 `'과 같지 않음)가 얼마나 많은지를 결정하는 함수를 작성하려고했습니다.매크로에 비어 있지 않은 args의 수가 전달되었습니다.

는과 같이 호출해야하는데 : 첫 번째 인수는 항상 0을해야

ne_nargs(0, `1', `') 
# 1 

ne_nargs(0, `') 
# 0 

ne_nargs(0, `1') 
# 1 

하는 것으로. 여기

는 내가 지금까지 가지고 코드입니다 :

define(`ne_nargs', `ifelse(`$#', `1`, $1, 
    `ifelse(`$2', `', `pushdef(`$2', $1)ne_nargs(shift([email protected]))', 
    `pushdef(`$2', incr($1))ne_nargs(shift([email protected]))')')') 

그리고 여기에 대한 의사 코드입니다 :

if (number_of_args == 1); then 
    return first_arg; // which is `0` by default. 
else if (second_arg == ''); then 
    second_arg = first_arg; 
    return ne_nargs(shift(all_args)); 
else 
    second_arg = (++first_arg); 
    return ne_nargs(shift(all_args)); 

ne_nargs(`0', `', `1', `i', `', `l') 

# what I get 
m4:test.m4:8: empty string treated as 0 in builtin `incr' 
m4:test.m4:8: empty string treated as 0 in builtin `incr' 
1 

# what I expect 
3 

내가 알아낼 수 없습니다 ne_nargs의 정의에서 내가 잘못하고있는 것, 그리고 매크로의 일부를 추상화하는 여러 가지 방법을 시도한 후에, 나는 줄 준비가되어있다. 쪽으로.

답변

1

덮어 쓰려고하면 안됩니다. [email protected]; $ 2을 (를) 덮어 쓰는 것이 분명히 [email protected]에 영향을 미치지 않는다는 경고에서 알 수 있습니다.

`$0(`$1', shift(shift([email protected])))' 

그래서 다음 작품 : 워드 프로세서의 join example 대신에 두 번째 인수를 이동

define(`ne_nargs', `ifelse(`$#', `2', `ifelse(`$2', `', `$1', incr(`$1'))', 
    `ifelse(`$2', `', `$0(`$1', shift(shift([email protected])))', 
    `$0(incr($1), shift(shift([email protected])))')')') 
ne_nargs(`0', `', `1', `i', `', `l') 

(I 정리하는 좋은 방법을 재귀 호출을 모르는 2 인자 때문에 통화를 독립적으로 확인할 필요가 없으므로 DRYness에 대해 걱정할 경우 개선해야 할 부분이있을 수 있습니다.)

관련 문제