From a66525db9c4c07c8cff6f927bd930f62f7d1ccdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=B6rnquist?= Date: Fri, 22 Jul 2022 17:21:23 +0200 Subject: Handle nested #if trees. --- tests/test/cpp/preprocessor2.scm | 207 ++++++++++++++++++++++++++++++++------- 1 file changed, 172 insertions(+), 35 deletions(-) (limited to 'tests/test/cpp/preprocessor2.scm') 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 \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")) + )) )) + + -- cgit v1.2.3