// Basic parsing tests.
// This file should compile with an ANSI compliant C++ compiler.

// character literal tests
char character_literal_1 = 'c';
char character_literal_2 = '\'';
char character_literal_3 = L'c';
char character_literal_4 = L'\233';

// String literal tests
const char* string_literal_1 = "string \"literal\"";
const __wchar_t* string_literal_2 = L"\003\003";

// Verify that the literal 'L' prefix can be used
// as a variable name.
int L = 1;
int LL = 11;

// Check number literals: Verify that 0 works
int number_literals_1 = 0;
int number_literals_2 = 0U;
int number_literals_3 = 0u;
int number_literals_4 = 0L;
int number_literals_5 = 0l;

// Check number literals: Verify that two digits work
int number_literals_6 = 10;
int number_literals_7 = 10U;
int number_literals_8 = 10u;
int number_literals_9 = 10L;
int number_literals_10 = 10l;

// Check number literals: Verify octal numbers
// Make sure that ccdoc accepts illegal octals (like 08).
int number_literals_11 = 07;
int number_literals_12 = 01234567L;

// Check number literals: Verify hex numbers
int number_literals_13 = 0xabcdefL;
int number_literals_14 = 0XABCDEFU;

// Check number literals: Verify floating point numbers
double number_literals_15 = 3.14159;
double number_literals_16 = .71;
double number_literals_17 = 12.;
double number_literals_18 = 6.02e-23;
double number_literals_19 = 6e-23;
double number_literals_20 = 6e23;
double number_literals_21 = 6E23;

// Verify that trailing backslashes are stripped.
char \
 trailing_backslash \
 = 'a' \
 ;

// Check tri-graph sequence conversions.
// This confused the gcc compiler.
#ifdef __ccdoc__
??=define trigraph_check(a,b,c,d) ??/
  ??< ??/
  a ??( b ??) ??'= ??- c ??' ( d ??! 27 ) ; ??/
  ??>
#endif

// Check identifier handling.
int identifier;
int _identifier;
int __identifier;
int $identifier;
int identifier$;
int identifier$$L;
int Lidentifier__;
int identifier1;

// Check punc_ops: {}()[]~,;
void punc_op_1(int b) {int a[2];a[0]=~b;a[1]=b;}

// Check punc_ops: !, !=
void punc_op_2(int a,int b) {if(a!=b)if(!b)b=a;}

// Check punc_ops: %, %=
// Check alternative token conversion:
//  <%   --> {
//  %>   --> }
void punc_op_3(int& a,int b,int& c,int d,int e) <%a%=b;c=d%e;%>

// Check alternative token conversion:
//  %:   --> #
//  %:%: --> ##
%:define punc_op_4(a) "" %:%: a %:%: ""
%:define punc_op_5(a) "" %: a

// Check punc_ops: &, &&, &=
void punc_op_6(int a,int b) {if(a&&b)a&=b;else a=b&27;}

// Check punc_ops: *, *=
void punc_op_7(int& a,int b,int c) {a*=b*c;}

// Check punc_ops: +, ++, +=
void punc_op_8(int& a,int b,int c) {a+=++b+c;}

// Check punc_ops: -, --, -=,
void punc_op_9(int& a,int b,int c) {a-=--b-c;}

// Check punc_ops: .*, ., ->*, ->
void punc_op_10() {
  struct S {mutable int i;};
  S cs = {1};
  int S::* pm = &S::i;
  cs.*pm = 88;
  S* pcs = &cs;
  pcs->*pm = 99;
  pcs->i = 10;
  cs.i = 5;
}

// Check punc_ops: ...
void punc_op_11(const char* fmt, ...) {
}

// Check punc_ops: /, /=
void punc_op_12(int& a) {a/=(128/8);}

// Check punc_ops: :, ::
#include <cstdlib>
void punc_op_13() {
  struct S {unsigned a:2;unsigned b:4;};
  S s;
  s.b = 0;
  if(std::getenv("punc_op_13"))
    s.a = 1;
}

// Check punc_ops: <:, :>
int punc_op_14 <: 10 :> ; // this s/b converted to punc_op_14[10]

// Check punc_ops: <, <<, <<=, <=
void punc_op_15(int a,int b) {if(a<b)a=b<<1;else if(b<=a)b<<=2;}

// Check punc_ops: =,==
void punc_op_16(int a,int b) {if(a==b)a=b+1;}

// Check punc_ops: >, >>, >>=, >=
void punc_op_17(int a,int b) {if(a>b)a=b>>1;else if(b>=a)b>>=2;}

// Check punc_ops: ^, ^=
void punc_op_18(int& a,int& b,int c) {a=b^c;b^=c;}

// Check punc_ops: |, |=, ||
void punc_op_19(int& a,int b,int c) {if(b||c)a|=b||c;}

// Check /**@#-*/, /**@#+*/
/**@#-*/
int this_should_be_ignored_1;
/**@#+*/
int this_should_not_be_ignored_1;

// Check /**@#=<char>*/
#define insert_semi int a;
insert_semi /**@#=;*/

// Check variables and function variables
const char* var1 = "foo bar spam";
int var2[2] = {1,2};
int (*var3)( (*f)(int a=5), int b) = 0;
int (*(var4))(int a[4]) = 0;

// Check multiple declarations.
int var10,var11,var12;
int var20=3,var21=2;
int (*var30)(),(*(var31))()=0,var32;

// Check operators
bool operator == (const char* x1,const char* x2) {return ::strcmp(x1,x2) == 0;}
