aboutsummaryrefslogtreecommitdiff
path: root/tests/test/cpp/preprocessor2.scm
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test/cpp/preprocessor2.scm')
-rw-r--r--tests/test/cpp/preprocessor2.scm207
1 files changed, 172 insertions, 35 deletions
diff --git a/tests/test/cpp/preprocessor2.scm b/tests/test/cpp/preprocessor2.scm
index 7fcaaccb..4e808b8b 100644
--- a/tests/test/cpp/preprocessor2.scm
+++ b/tests/test/cpp/preprocessor2.scm
@@ -1,12 +1,14 @@
(define-module (test cpp preprocessor2)
+ :use-module ((srfi srfi-1) :select (remove))
:use-module (srfi srfi-64)
:use-module (srfi srfi-64 util)
:use-module (srfi srfi-64 test-error)
:use-module (srfi srfi-71)
:use-module (srfi srfi-88)
- :use-module ((hnh util) :select (-> unval))
+ :use-module ((hnh util) :select (-> ->> unval swap))
:use-module ((hnh util lens) :select (set))
:use-module ((hnh util io) :select (call-with-tmpfile))
+ :use-module (hnh util values)
:use-module (c preprocessor2)
:use-module ((c cpp-environment)
:select (extend-environment
@@ -35,7 +37,7 @@
)
)
:use-module ((c cpp-types)
- :select (punctuator-token? identifier-token?))
+ :select (punctuator-token? identifier-token? whitespace-token?))
:use-module (c lex2)
)
@@ -47,8 +49,6 @@
"6.10.3.5 Scope of macro definitions"
"Example 3"))
-;; TODO # if (and # elif) aren't yet implemented
-;; (test-skip (test-match-group "Conditionals" "if"))
(define apply-macro (@@ (c preprocessor2) apply-macro))
(define build-parameter-map (@@ (c preprocessor2) build-parameter-map))
@@ -82,13 +82,22 @@
(let ((env tokens (handle-preprocessing-tokens env (tokenize str))))
(drop-whitespace-both (remove-noexpand tokens))))
- (define (call-with-tmp-header string proc)
- (proc
- (call-with-tmpfile
- (lambda (port filename)
- (display string port)
- filename)
- tmpl: "/tmp/headerfile-XXXXXXX")))
+(define (make-runner string)
+ (lambda (rest)
+ (->> (tokenize string)
+ (append (tokenize rest))
+ (handle-preprocessing-tokens (make-environment))
+ (value-refx 1)
+ remove-noexpand
+ (remove whitespace-token?))))
+
+(define (call-with-tmp-header string proc)
+ (proc
+ (call-with-tmpfile
+ (lambda (port filename)
+ (display string port)
+ filename)
+ tmpl: "/tmp/headerfile-XXXXXXX")))
@@ -666,7 +675,11 @@ X
(call-with-tmp-header "__LINE__" (lambda (path)
(test-equal "__LINE__ in other file"
(lex "1")
- (run (format #f "#include \"~a\"\n" path))))))
+ (run (format #f "#include \"~a\"\n" path)))))
+
+
+ (test-error 'cpp-error (run "#include <no-such-file>\n"))
+ )
@@ -1167,12 +1180,12 @@ c
"))
(test-group "Unexpected if ends"
- (test-error "#else outside if"
- 'cpp-error (run "#else"))
- (test-error "#endif outside if"
- 'cpp-error (run "#endif"))
- (test-error "#elif outside if"
- 'cpp-error (run "#elif")))
+ (test-error "#else outside if"
+ 'misc-error (run "#else"))
+ (test-error "#endif outside if"
+ 'misc-error (run "#endif"))
+ (test-error "#elif outside if"
+ 'misc-error (run "#elif")))
(test-group "if"
(test-equal "Simple positive if"
@@ -1205,25 +1218,48 @@ b
a
#elif 1
b
+#else
+c
+#endif"))
+
+ ;; undefined indentifiers expand to 0
+ (test-equal "If with undefined identifier"
+ (lex "a")
+ (run "
+#if X == 0
+a
+#else
+b
+#endif
+"))
+
+ ;; null-defined identifiers expand to nothing, leaving an invalid equals form
+ (test-error "If with null-defined identifier"
+ 'cpp-error
+ (run "
+#define X
+#if X == 0
+a
#endif"))
+
;; Note that defined is automatically added to the environment when
;; evaluating #if.
- (test-equal "#if with defined"
- (lex "a")
- (run "
+ (test-group "defined"
+ (test-equal "#if with defined"
+ (lex "a")
+ (run "
#define X
#if defined(X)
a
#else
b
-#endif")
- )
+#endif"))
- (test-equal "#if with negative defined"
- (lex "b")
- (run "
+ (test-equal "#if with negative defined"
+ (lex "b")
+ (run "
#if defined(X)
a
#else
@@ -1231,23 +1267,124 @@ b
#endif"))
- (test-group "defined without parenthesis"
- (test-equal "negative"
- (lex "b")
- (run "#if defined X
+ (test-group "defined without parenthesis"
+ (test-equal "negative"
+ (lex "b")
+ (run "#if defined X
a
#else
b
#endif"))
- (test-equal "positive"
- (lex "a")
- (run "#define X
+ (test-equal "positive"
+ (lex "a")
+ (run "#define X
#if defined X
a
#else
b
-#endif")))
+#endif"))))
+
+
+ (test-group "Advanced if forms"
+ (let ((run (make-runner "
+#if defined X
+ #if defined Y
+ #if defined Z
+ XYZ
+ #else
+ XYz
+ #endif
+ #elif defined Z
+ XyZ
+ #else
+ Xyz
+ #endif
+#elif defined Y
+ #if defined Z
+ xYZ
+ #else
+ xYz
+ #endif
+#elif defined Z
+ xyZ
+#else
+ xyz
+#endif
+")))
+
+ ;; The above expression expands to "xyz", where the letter corresponding
+ ;; to the defined macros should be uppercase.
+
+ (test-equal "xyz"
+ (lex "xyz") (run ""))
+ (test-equal "xyZ"
+ (lex "xyZ") (run "#define Z"))
+ (test-equal "xYz"
+ (lex "xYz") (run "#define Y"))
+ (test-equal "xYZ"
+ (lex "xYZ") (run "#define Y\n#define Z"))
+ (test-equal "Xyz"
+ (lex "Xyz") (run "#define X"))
+ (test-equal "XyZ"
+ (lex "XyZ") (run "#define X\n#define Z"))
+ (test-equal "XYz"
+ (lex "XYz") (run "#define X\n#define Y"))
+ (test-equal "XYZ"
+ (lex "XYZ") (run "#define X\n#define Y\n#define Z"))))
+
+ (test-group "Needlesly complicated if tree"
+ ;; Structure borrowed from features-time64.h
+ (let ((run (make-runner "
+#if defined X
+# if X == 64
+# if ! defined (Z) || Z != 64
+ a
+# elif Y == 32
+ b
+# else
+ f
+# endif
+# elif X == 32
+# if Y > 32
+ c
+# endif
+# else
+ d
+# endif
+#else
+e
+#endif
+")))
- ;; TODO test advanced constant expression
+ (test-equal "No variables set"
+ (lex "e") (run ""))
+ ;; (test-equal "Just X"
+ ;; (lex "d")
+ ;; (run "#define X"))
+ (test-equal "Bad X"
+ (lex "d") (run "#define X 6"))
+ (test-equal "Good X and Y, no Z"
+ (lex "a")
+ (run "
+#define X 64
+#define Y 32"))
+ (test-equal "Good X and Z != 64"
+ (lex "a")
+ (run "
+#define X 64
+#define Z 63"))
+ (test-equal "Good X and Z == 64"
+ (lex "f")
+ (run "
+#define X 64
+#define Z 64"))
+ (test-equal "Good (alt) X, and good Y"
+ (lex "c")
+ (run "
+#define X 32
+#define Y 40"))
+ ))
))
+
+