@@ -500,21 +500,29 @@ do -- tests
500500 end
501501
502502 local function assert_find (code , find )
503+ if not code :find (" >.-<" ) then error (" must define a macro with > and <" , 2 ) end
504+
505+ if find :find (" >.-<" ) then error (" must not contain > and <" , 2 ) end
506+
503507 do
504508 local gcc_code = preprocess_gcc (code )
509+ local captured = gcc_code :match (" >(.-)<" )
505510
506- if not gcc_code :find (find , nil , true ) then
511+ if find ~= captured then
512+ print (captured .. " != " .. find )
507513 print (" gcc -E fail, could not find:\n " .. find .. " \n in:\n " .. gcc_code )
508514 end
509515 end
510516
511517 do
512- code = preprocess (code )
518+ local code = preprocess (code )
519+ local captured = code :match (" >(.-)<" )
513520
514- if code :find (find , nil , true ) then return end
521+ if find ~= captured then
522+ print (captured .. " != " .. find )
523+ error (" Could not find:\n " .. find .. " \n in:\n " .. code , 2 )
524+ end
515525 end
516-
517- error (" Could not find:\n " .. find .. " \n in:\n " .. code , 2 )
518526 end
519527
520528 local function ones (count )
@@ -527,93 +535,6 @@ do -- tests
527535 return table.concat (str , " " )
528536 end
529537
530- if false then
531- assert_find (
532- " #define PREFIX(x) pre_##x \n #define SUFFIX(x) x##_post \n PREFIX(fix) SUFFIX(fix)" ,
533- " pre_fix fix_post"
534- )
535- assert_find (" #define A value \n #define STR(x) #x \n STR(A)" , " \" A\" " )
536- end
537-
538- assert_find (" #define STR(a) #a \n STR(hello world)" , " \" hello world\" " )
539- assert_find (" #define STR(x) #x \n STR( hello world )" , " \" hello world\" " )
540- assert_find (" #define S(a) a \n X(S(spaced-argument))" , " X(spaced-argument)" )
541- assert_find (" #define S(a) a \n X(S(spaced - argument))" , " X(spaced - argument)" )
542- assert_find (" #define S(a) a \n X(S( spaced - argument ))" , " X(spaced - argument)" )
543- assert_find (" #define S(a) a \n X(S( spaced- argument ))" , " X(spaced- argument)" )
544- assert_find (" #define S(a) a \n X(S( spaced -argument ))" , " X(spaced -argument)" )
545- assert_find (" #define F(x,y) x and y \n F(,)" , " and" )
546- assert_find (" #define F(...) >__VA_ARGS__< \n F(0)" , " >0<" )
547- assert_find (" #define F(...) >__VA_ARGS__< \n F()" , " ><" )
548- assert_find (" #define X(x) x \n #define Y X(1) \n >Y<" , " >1<" )
549- assert_find (" #define X(x) x \n #define Y(x) X(x) \n >Y(1)<" , " >1<" )
550- assert_find (
551- " #define REPEAT_5(x) x x x x x \n #define REPEAT_25(x) REPEAT_5(x) \n >REPEAT_25(1)<" ,
552- " >" .. ones (5 ) .. " <"
553- )
554- assert_find (
555- " #define REPEAT_5(x) x x x x x \n #define REPEAT_25(x) REPEAT_5(x) REPEAT_5(x) \n >REPEAT_25(1)<" ,
556- " >" .. ones (10 ) .. " <"
557- )
558- assert_find (
559- " #define REPEAT_5(x) x x x x x \n #define REPEAT_25(x) REPEAT_5(REPEAT_5(x)) \n >REPEAT_25(1)<" ,
560- " >" .. ones (25 ) .. " <"
561- )
562- assert_find (" #define REPEAT(x) x \n >REPEAT(1)<" , " >1<" )
563- assert_find (" #define REPEAT(x) x x \n >REPEAT(1)<" , " >1 1<" )
564- assert_find (" #define REPEAT(x) x x x \n >REPEAT(1)<" , " >1 1 1<" )
565- assert_find (" #define REPEAT(x) x x x x \n >REPEAT(1)<" , " >1 1 1 1<" )
566- assert_find (
567- " #define REPEAT_5(x) x x x x x \n #define REPEAT_25(x) REPEAT_5(x) \n >REPEAT_25(1)<" ,
568- " >1 1 1 1 1<"
569- )
570- assert_find (
571- " #define TEST 1 \n #define TEST2 2 \n static int test = TEST + TEST2;" ,
572- " = 1 + 2;"
573- )
574- assert_find (" #define TEST(x) x*x \n static int test = TEST(2);" , " =2*2;" )
575- assert_find (" #define TEST(x,y) x*y \n static int test = TEST(2,4);" , " =2*4;" )
576- assert_find (" #define TEST 1 \n #undef TEST \n static int test = TEST;" , " = TEST;" )
577- assert_find (
578- [[
579- #define MY_LIST \
580- X(Item1, "This is a description of item 1") \
581- X(Item2, "This is a description of item 2") \
582- X(Item3, "This is a description of item 3")
583-
584- #define X(name, desc) name,
585- enum ListItemType { MY_LIST }
586- #undef X]] ,
587- " enum ListItemType {Item1,Item2,Item3, }"
588- )
589- assert_find (" #define max(a,b) ((a)>(b)?(a):(b)) \n int x = max(1,2);" , " ((1)>(2)?(1):(2));" )
590- assert_find (" #define max(a,b) ((a)>(b)?(a):(b)) \n int x = max(1,2);" , " ((1)>(2)?(1):(2));" )
591- assert_find (
592- " #define STRINGIFY(a,b,c,d) #a #b #c #d \n STRINGIFY(1,2,3,4);" ,
593- " \" 1\" \" 2\" \" 3\" \" 4\" "
594- )
595- assert_find (" #define STRINGIFY(a) #a \n STRINGIFY(1);" , " \" 1\" " )
596- assert_find (" #define STRINGIFY(a) #a \n STRINGIFY((a,b,c));" , " \" (a,b,c)\" " )
597- assert_find (" #define F(...) >__VA_ARGS__< \n F(1,2,3)" , " >1,2,3<" )
598- assert_find (" #define F(...) f(0 __VA_OPT__(,) __VA_ARGS__) \n F(1)" , " f(0,1)" )
599- assert_find (" #define F(...) f(0 __VA_OPT__(,) __VA_ARGS__) \n F()" , " f(0)" )
600- assert_find (" #define F(a, b) >a##b< \n F(1,2)" , " >12<" )
601- assert_find (
602- " #define MAX(a,b) ((a)>(b)?(a):(b)) \n MAX(1+2,3*4)" ,
603- " ((a)>(b)?(a):(b)) ((1+2)>(3*4)?(1+2):(3*4))"
604- )
605- assert_find (" #define X 1 \n #define X 2 \n X" , " 2" )
606- assert_find (" #define F(x) (2*x) \n #define G(y) F(y+1) \n G(5)" , " (2*5+1)" )
607- assert_find (" #define F(x,y) x and y \n F(,)" , " and " )
608- assert_find (" #define EMPTY_ARG(a, b) a##b \n EMPTY_ARG(test, )" , " test" )
609- assert_find (" #define EMPTY_ARG(a, b) a##b \n EMPTY_ARG(, test)" , " test" )
610- assert_find (" #define EMPTY \n EMPTY" , " " )
611- assert_find (" #define A 1 \n #define B 2 \n A + B + A" , " 1 + 2 + 1" )
612- assert_find (" #define TRIPLE(x) x x x \n TRIPLE(abc)" , " abc abc abc" )
613- assert_find (" #define PLUS(a, b) a + b \n PLUS(1, 2)" , " 1 + 2" )
614- assert_find (" #define MULT(a, b) a * b \n MULT(3, 4)" , " 3 * 4" )
615- assert_find (" #define STR(x) #x \n STR(a + b)" , " \" a + b\" " )
616-
617538 -- Test argument error cases
618539 local function assert_error (code , error_msg )
619540 local success , err = pcall (function ()
@@ -623,37 +544,150 @@ enum ListItemType { MY_LIST }
623544 assert (err :find (error_msg , nil , true ), " Error message doesn't match: " .. err )
624545 end
625546
626- assert_error (" #define FUNC(a, b) a + b \n FUNC(1)" , " Argument count mismatch" )
627- assert_error (" #define FUNC(a, b, c) a + b + c \n FUNC(1, 2)" , " Argument count mismatch" )
628- assert_error (" #define FUNC(a, b) a + b \n FUNC(1, 2, 3)" , " Argument count mismatch" )
629- assert_find (
630- " #define VARIADIC(a, ...) a __VA_ARGS__ \n VARIADIC(first, second, third)" ,
631- " first second, third"
632- )
633- assert_find (" #define VARIADIC(a, ...) a __VA_ARGS__ \n VARIADIC(only)" , " only" )
634- assert_find (
635- " #define DEBUG(...) printf(\" Debug: \" __VA_ARGS__) \n DEBUG(\" Value: %d\" , x)" ,
636- " printf(\" Debug: \" \" Value: %d\" , x)"
637- )
638- assert_find (" #define EMPTY() nothing \n EMPTY()" , " nothing" )
639- assert_find (" #define COMPLEX(a) a*a \n COMPLEX(1+2)" , " 1+2*1+2" )
640- assert_find (" #define PAREN(a) (a) \n PAREN(1+2*3)" , " (1+2*3)" )
641- assert_find (" #define INNER(x) x+x \n #define OUTER(y) INNER(y) \n OUTER(5)" , " 5+5" )
642- assert_find (
643- " #define A(x) x+1 \n #define B(y) A(y*2) \n #define C(z) B(z-1) \n C(5)" ,
644- " 5-1*2+1"
645- )
646- assert_find (
647- " #define LOG(fmt, ...) printf(fmt __VA_OPT__(,) __VA_ARGS__) \n LOG(\" Hello\" )" ,
648- " printf(\" Hello\" )"
649- )
650- assert_find (
651- " #define LOG(fmt, ...) printf(fmt __VA_OPT__(,) __VA_ARGS__) \n LOG(\" Hello\" , \" World\" )" ,
652- " printf(\" Hello\" , \" World\" )"
653- )
654- assert_find (" #define COMMA(...) __VA_OPT__(,)__VA_ARGS__ \n COMMA()" , " " )
655- assert_find (" #define COMMA(...) __VA_OPT__(,)__VA_ARGS__ \n COMMA(x)" , " ,x" )
656- assert_find (" #define FUNC(a) a \n FUNC((1+2))" , " (1+2)" )
657- assert_find (" #define X 10 \n #define EXPAND(a) a \n EXPAND(X)" , " 10" )
658- assert_find (" #define JOIN(a, b) a##b\n JOIN(pre, post)" , " prepost" )
547+ do -- basic macro expansion
548+ assert_find (" #define REPEAT(x) x \n >REPEAT(1)<" , " 1" )
549+ assert_find (" #define REPEAT(x) x x \n >REPEAT(1)<" , " 1 1" )
550+ assert_find (" #define REPEAT(x) x x x \n >REPEAT(1)<" , " 1 1 1" )
551+ assert_find (" #define REPEAT(x) x x x x \n >REPEAT(1)<" , " 1 1 1 1" )
552+ assert_find (" #define TEST 1 \n #define TEST2 2 \n >TEST + TEST2<" , " 1 + 2" )
553+ assert_find (" #define TEST(x) x*x \n >TEST(2)<" , " 2*2" )
554+ assert_find (" #define TEST(x,y) x*y \n >TEST(2,4)<" , " 2*4" )
555+ assert_find (" #define X 1 \n #define X 2 \n >X<" , " 2" )
556+ assert_find (" #define A 1 \n #define B 2 \n >A + B + A<" , " 1 + 2 + 1" )
557+ assert_find (" #define TRIPLE(x) x x x \n >TRIPLE(abc)<" , " abc abc abc" )
558+ assert_find (" #define PLUS(a, b) a + b \n >PLUS(1, 2)<" , " 1 + 2" )
559+ assert_find (" #define MULT(a, b) a * b \n >MULT(3, 4)<" , " 3 * 4" )
560+ assert_find (" #define EMPTY \n >EMPTY<" , " " )
561+ assert_find (" #define EMPTY() nothing \n >EMPTY()<" , " nothing" )
562+ assert_find (" #define TEST 1 \n #undef TEST \n >TEST<" , " TEST" )
563+ end
564+
565+ do -- string operations (#)
566+ assert_find (" #define STR(a) #a \n >STR(hello world)<" , " \" hello world\" " )
567+ assert_find (" #define STR(x) #x \n >STR( hello world )<" , " \" hello world\" " )
568+ assert_find (
569+ " #define STRINGIFY(a,b,c,d) #a #b #c #d \n >STRINGIFY(1,2,3,4)<" ,
570+ " \" 1\" \" 2\" \" 3\" \" 4\" "
571+ )
572+ assert_find (" #define STRINGIFY(a) #a \n >STRINGIFY(1)<" , " \" 1\" " )
573+ assert_find (" #define STRINGIFY(a) #a \n >STRINGIFY((a,b,c))<" , " \" (a,b,c)\" " )
574+ assert_find (" #define STR(x) #x \n >STR(a + b)<" , " \" a + b\" " )
575+
576+ if false then
577+ assert_find (" #define A value \n #define STR(x) #x \n >STR(A)<" , " \" A\" " )
578+ end
579+ end
580+
581+ do -- token concatenation (##)
582+ if false then
583+ assert_find (
584+ " #define PREFIX(x) pre_##x \n #define SUFFIX(x) x##_post \n >PREFIX(fix) SUFFIX(fix)<" ,
585+ " pre_fix fix_post<"
586+ )
587+ end
588+
589+ assert_find (" #define F(a, b) a##b \n >F(1,2)<" , " 12" )
590+ assert_find (" #define EMPTY_ARG(a, b) a##b \n >EMPTY_ARG(test, )<" , " test" )
591+ assert_find (" #define EMPTY_ARG(a, b) a##b \n >EMPTY_ARG(, test)<" , " test" )
592+ assert_find (" #define JOIN(a, b) a##b \n >JOIN(pre, post)<" , " prepost" )
593+ end
594+
595+ do -- whitespace and arguments handling
596+ assert_find (" #define S(a) a \n >X(S(spaced-argument))<" , " X(spaced-argument)" )
597+ assert_find (" #define S(a) a \n >X(S(spaced - argument))<" , " X(spaced - argument)" )
598+ assert_find (" #define S(a) a \n >X(S( spaced - argument ))<" , " X(spaced - argument)" )
599+ assert_find (" #define S(a) a \n >X(S( spaced- argument ))<" , " X(spaced- argument)" )
600+ assert_find (" #define S(a) a \n >X(S( spaced -argument ))<" , " X(spaced -argument)" )
601+ assert_find (" #define F(x,y) x and y \n >F(,)<" , " and" )
602+ end
603+
604+ do -- variadic macros and VA_ARGS
605+ assert_find (" #define F(...) __VA_ARGS__ \n >F(0)<" , " 0" )
606+ assert_find (" #define F(...) __VA_ARGS__ \n >F()<" , " " )
607+ assert_find (" #define F(...) __VA_ARGS__ \n >F(1,2,3)<" , " 1,2,3" )
608+ assert_find (" #define F(...) f(0 __VA_OPT__(,) __VA_ARGS__) \n >F(1)<" , " f(0,1)" )
609+ assert_find (" #define F(...) f(0 __VA_OPT__(,) __VA_ARGS__) \n >F()<" , " f(0)" )
610+ assert_find (
611+ " #define VARIADIC(a, ...) a __VA_ARGS__ \n >VARIADIC(first, second, third)<" ,
612+ " first second, third"
613+ )
614+ assert_find (" #define VARIADIC(a, ...) a __VA_ARGS__ \n >VARIADIC(only)<" , " only" )
615+ assert_find (
616+ " #define DEBUG(...) printf(\" Debug: \" __VA_ARGS__) \n >DEBUG(\" Value: %d\" , x)<" ,
617+ " printf(\" Debug: \" \" Value: %d\" , x)"
618+ )
619+ assert_find (
620+ " #define LOG(fmt, ...) printf(fmt __VA_OPT__(,) __VA_ARGS__) \n >LOG(\" Hello\" )<" ,
621+ " printf(\" Hello\" )"
622+ )
623+ assert_find (
624+ " #define LOG(fmt, ...) printf(fmt __VA_OPT__(,) __VA_ARGS__) \n >LOG(\" Hello\" , \" World\" )<" ,
625+ " printf(\" Hello\" , \" World\" )"
626+ )
627+ assert_find (" #define COMMA(...) __VA_OPT__(,)__VA_ARGS__ \n >COMMA()<" , " " )
628+ assert_find (" #define COMMA(...) __VA_OPT__(,)__VA_ARGS__ \n >COMMA(x)<" , " ,x" )
629+ end
630+
631+ do -- nested and recursive macros
632+ assert_find (" #define X(x) x \n #define Y X(1) \n >Y<" , " 1" )
633+ assert_find (" #define X(x) x \n #define Y(x) X(x) \n >Y(1)<" , " 1" )
634+ assert_find (
635+ " #define REPEAT_5(x) x x x x x \n #define REPEAT_25(x) REPEAT_5(x) \n >REPEAT_25(1)<" ,
636+ ones (5 )
637+ )
638+ assert_find (
639+ " #define REPEAT_5(x) x x x x x \n #define REPEAT_25(x) REPEAT_5(x) REPEAT_5(x) \n >REPEAT_25(1)<" ,
640+ ones (10 )
641+ )
642+ assert_find (
643+ " #define REPEAT_5(x) x x x x x \n #define REPEAT_25(x) REPEAT_5(REPEAT_5(x)) \n >REPEAT_25(1)<" ,
644+ ones (25 )
645+ )
646+ assert_find (
647+ " #define REPEAT_5(x) x x x x x \n #define REPEAT_25(x) REPEAT_5(x) \n >REPEAT_25(1)<" ,
648+ " 1 1 1 1 1"
649+ )
650+ assert_find (" #define F(x) (2*x) \n #define G(y) F(y+1) \n >G(5)<" , " (2*5+1)" )
651+ assert_find (" #define INNER(x) x+x \n #define OUTER(y) INNER(y) \n >OUTER(5)<" , " 5+5" )
652+ assert_find (
653+ " #define A(x) x+1 \n #define B(y) A(y*2) \n #define C(z) B(z-1) \n >C(5)<" ,
654+ " 5-1*2+1"
655+ )
656+ end
657+
658+ do -- complex expressions and ternary operators
659+ assert_find (
660+ " #define max(a,b) ((a)^(b)?(a):(b)) \n int x = >max(1,2)<" ,
661+ " ((1)^(2)?(1):(2))"
662+ )
663+ assert_find (
664+ " #define MAX(a,b) ((a)^(b)?(a):(b)) \n >MAX(1+2,3*4)<" ,
665+ " ((1+2)^(3*4)?(1+2):(3*4))"
666+ )
667+ assert_find (" #define COMPLEX(a) a*a \n >COMPLEX(1+2)<" , " 1+2*1+2" )
668+ assert_find (" #define PAREN(a) (a) \n >PAREN(1+2*3)<" , " (1+2*3)" )
669+ assert_find (" #define FUNC(a) a \n >FUNC((1+2))<" , " (1+2)" )
670+ assert_find (" #define X 10 \n #define EXPAND(a) a \n >EXPAND(X)<" , " 10" )
671+ end
672+
673+ do -- multi-line macros
674+ assert_find (
675+ [[
676+ #define MY_LIST \
677+ X(Item1, "This is a description of item 1") \
678+ X(Item2, "This is a description of item 2") \
679+ X(Item3, "This is a description of item 3")
680+
681+ #define X(name, desc) name,
682+ >enum ListItemType { MY_LIST }<
683+ #undef X]] ,
684+ " enum ListItemType {Item1,Item2,Item3, }"
685+ )
686+ end
687+
688+ do -- error handling
689+ assert_error (" #define FUNC(a, b) a + b \n FUNC(1)" , " Argument count mismatch" )
690+ assert_error (" #define FUNC(a, b, c) a + b + c \n FUNC(1, 2)" , " Argument count mismatch" )
691+ assert_error (" #define FUNC(a, b) a + b \n FUNC(1, 2, 3)" , " Argument count mismatch" )
692+ end
659693end
0 commit comments