1 /* Copyright (C) 2000 Free Software Foundation, Inc.  */
2 
3 /* { dg-do run } */
4 /* { dg-options "-std=c99 -pedantic-errors" } */
5 
6 /* Test ## behavior and corner cases thoroughly.  The macro expander
7    failed many of these during development.  */
8 
9 #ifndef __WCHAR_TYPE__
10 #define __WCHAR_TYPE__ int
11 #endif
12 typedef __WCHAR_TYPE__ wchar_t;
13 
14 extern int strcmp (const char *, const char *);
15 #if DEBUG
16 extern int puts (const char *);
17 #else
18 #define puts(X)
19 #endif
20 extern void abort (void);
21 #define err(str) do { puts(str); abort(); } while (0)
22 
23 #define EMPTY
24 #define str(x) #x
25 #define xstr(x) str(x)
26 #define glue(x, y) x ## y
27 #define xglue(x, y) glue (x, y)
28 #define glue3(x, y, z) x ## y ## z
29 #define glue_var(x, ...) x ## __VA_ARGS__
30 
31 #define __muldi3 __NDW(mul, 3 = 50)
32 #define __NDW(a,b) __ ## a ## di ## b
33 #define m3 NDW()
34 #define NDW(x) m3 ## x = 50
35 #define five 5
36 #define fifty int fif ## ty
37 
38 /* Defines a function called glue, returning what it is passed.  */
39 int glue (glue,) (int x)
40 {
41   return x;
42 }
43 
main()44 int main ()
45 {
46   /* m3 and __muldi3 would sometimes cause an infinite loop.  Ensure
47      we only expand fifty once.  */
48   fifty = 50, m3, __muldi3;
49 
50   /* General glue and macro expanding test.  */
51   int five0 = xglue (glue (fi, ve), 0);
52 
53   /* Tests only first and last tokens are pasted, and pasting to form
54      the != operator.  Should expand to: if (five0 != 50).  */
55   if (glue3 (fi, ve0 !,= glue (EMPTY 5, 0)))
56     err ("five0 != 50");
57 
58   /* Test varags pasting, and pasting to form the >> operator.  */
59   if (glue_var(50 >, > 1 != 25))
60     err ("Operator >> pasting");
61 
62   /* The LHS should not attempt to expand twice, and thus becomes a
63      call to the function glue.  */
64   if (glue (gl, ue) (12) != 12)
65     err ("Recursive macros");
66 
67   /* Test placemarker pasting.  The glued lines should all appear
68      neatly in the same column and below each other, though we don't
69      test that here.  */
70   {
71     int glue3(a, b, ) = 1, glue3(a,,) = 1;
72     glue3(a, , b)++;
73     glue3(, a, b)++;
74     glue3(,a,)++;
75     glue3(,,a)++;
76     if (a != 3 || ab != 3 glue3(,,))
77       err ("Placemarker pasting");
78   }
79 
80   /* Test that macros in arguments are not expanded.  */
81   {
82     int glue (EMPTY,1) = 123, glue (T, EMPTY) = 123;
83     if (EMPTY1 != 123 || TEMPTY != 123)
84       err ("Pasted arguments macro expanding");
85   }
86 
87   /* Test various paste combinations.  */
88   {
89     const wchar_t* wc_array = glue(L, "wide string");
90     wchar_t wc = glue(L, 'w');
91     const char * hh = xstr(xglue(glue(%, :), glue(%, :)));
92     int array glue (<, :) 1 glue (:, >) = glue(<, %) 1 glue(%, >);
93     int x = 4;
94 
95     if (array[0] != 1)
96       err ("Digraph pasting");
97 
98     x glue (>>, =) 1;		/* 2 */
99     x glue (<<, =) 1;		/* 4 */
100     x glue (*, =) 2;		/* 8 */
101     x glue (+, =) 100;		/* 108 */
102     x glue (-, =) 50;		/* 58 */
103     x glue (/, =) 2;		/* 29 */
104     x glue (%, =) 20;		/* 9 */
105     x glue (&, =) 254;		/* 8 */
106     x glue (|, =) 16;		/* 24 */
107     x glue (^, =) 18;		/* 10 */
108 
109     if (x != 10 || 0 glue (>, =) 1 glue (|, |) 1 glue (<, =) 0)
110       err ("Various operator pasting");
111     if (strcmp (hh, "%:%:"))
112       err ("Pasted digraph spelling");
113     if ((glue (., 1) glue (!, =) .1))
114       err ("Pasted numbers 1");
115     /* glue3 here will only work if we paste left-to-right.  If a
116        future implementation does not do this, change the test.  */
117     if (glue3 (1.0e, +, 1) != 10.0)
118       err ("Pasted numbers 2");
119   }
120 
121   return 0;
122 }
123