042-ccscm-stdarg-gate.scm (2119B)
1 ;; tests/cc-pp/42-ccscm-stdarg-gate.scm 2 ;; 3 ;; cc.scm pre-defines CCSCM as an empty object macro so test fixtures 4 ;; can wrap their stdarg.h include in `#ifndef CCSCM ... #else ... #endif` 5 ;; and route around #include (which cc.scm rejects). This test pins 6 ;; that contract: with CCSCM in the initial-defines table, the #include 7 ;; in the then-branch is never processed, the else branch's typedef 8 ;; emits its tokens, and the else branch's function-like macro is 9 ;; registered and expanded at the call site. 10 11 (define src 12 "#ifndef CCSCM\n#include <stdarg.h>\n#else\ntypedef char *va_list;\n#define va_start(ap, n) __builtin_va_start(ap, n)\n#endif\nva_list ap;\nvoid f(int n) { va_start(ap, n); }\n") 13 14 (define ccscm (cons "CCSCM" (%macro 'obj '() '()))) 15 (define toks (lex-tokenize src "src.c")) 16 (define out (pp-expand toks (list ccscm))) 17 18 ;; Helper: fail with a status-encoded reason if `cond` is false. 19 (define (must cond status) 20 (if cond #t (sys-exit status))) 21 22 ;; #include must NOT have been processed (it would have raised die from 23 ;; %pp-do-include and aborted with status 1 before getting here). 24 25 ;; Walk `out` and assert: the typedef line is present, ap (va_list ident) 26 ;; is present, and the va_start expansion landed on __builtin_va_start. 27 (define (find-ident name toks) 28 (cond 29 ((null? toks) #f) 30 ((and (eq? (tok-kind (car toks)) 'IDENT) 31 (bv= (tok-value (car toks)) name)) 32 toks) 33 (else (find-ident name (cdr toks))))) 34 35 (must (find-ident "va_list" out) 11) 36 (must (find-ident "ap" out) 12) 37 (must (find-ident "f" out) 13) 38 (must (find-ident "__builtin_va_start" out) 14) 39 40 ;; Negative: __builtin_va_start should appear (from the macro body), but 41 ;; the literal `va_start` identifier should NOT survive expansion at the 42 ;; call site. 43 (define (count-ident name toks) 44 (let loop ((ts toks) (n 0)) 45 (cond 46 ((null? ts) n) 47 ((and (eq? (tok-kind (car ts)) 'IDENT) 48 (bv= (tok-value (car ts)) name)) 49 (loop (cdr ts) (+ n 1))) 50 (else (loop (cdr ts) n))))) 51 52 (must (= (count-ident "va_start" out) 0) 15) 53 54 (sys-exit 0)