//////////////////////////////////////////////////////////////////////
/* Map data from file */
double normals[][] = {
	#include "normals.txt"
};

//////////////////////////////////////////////////////////////////////
/* Force a compilation error if condition is true */
#define BUILD_BUG_ON(cond) ((void)sizeof(char[1 - 2*!!(cond)]))

//////////////////////////////////////////////////////////////////////
/* using __FILE__, __LINE__ and __FUNCTION__ for debugging */
#define WHERE fprintf(stderr,"[LOG]%s:%d in %s with %s\n",__FILE__,__LINE__, __FUNCTION__, __VAR_ARGS__);

//////////////////////////////////////////////////////////////////////
/* In C99 */
typedef struct{
    int value;
    int otherValue;
} s;
s test = {.value = 15, .otherValue = 16};
/* or */
int a[100] = {1,2,[50]=3,4,5,[23]=6,7};

//////////////////////////////////////////////////////////////////////
/* Debug printing the var name and decimal value */
#define print_dec(var)  printf("%s=%d\n",#var,var);

//////////////////////////////////////////////////////////////////////
/* Using a stupid macro trick to make record definitions easier to maintain. */
#define COLUMNS(S,E) [(E) - (S) + 1]
typedef struct
{
    char studentNumber COLUMNS( 1,  9);
    char firstName     COLUMNS(10, 30);
    char lastName      COLUMNS(31, 51);
} StudentRecord;

//////////////////////////////////////////////////////////////////////
/* Escape \n in gcc using \ */
prin\
tf("i like\
trains");

//////////////////////////////////////////////////////////////////////
/* Swap 2 pointers without third temp pointer */
int * a;
int * b;
a ^= b;
b ^= a;
a ^= b;

//////////////////////////////////////////////////////////////////////
/* More of a trick of the GCC compiler, but you can give branch indication hints to the compiler (common in the Linux kernel) */
#define likely(x)       __builtin_expect((x),1)
#define unlikely(x)     __builtin_expect((x),0)

//////////////////////////////////////////////////////////////////////
/* Self documenting enums, useful for looking at memory dump */
enum state {
    stopped = 'STOP',
    running = 'RUN!',
    waiting = 'WAIT',
};

//////////////////////////////////////////////////////////////////////
table[i] = 0;
/* is the same as */
i[table] = 0;
/* and */
*(table + i) = 0;
/* Bases */
hexDigit = "0123456789abcdef"[someNybble];

//////////////////////////////////////////////////////////////////////
/* && and || as one-liner if */
1 || puts("Yes\n");
0 || puts("No\n");
1 && puts("Yes\n");
0 && puts("No\n");

//////////////////////////////////////////////////////////////////////
/* bitfields "000aaabb 0ccccddd" instead of "0000aaab bccccddd" without the ":0" */
struct {
  int    a:3;
  int    b:2;
  int     :0;
  int    c:4;
  int    d:3;
};

//////////////////////////////////////////////////////////////////////
/* Lambda's (e.g. anonymous functions) in GCC: */
#define lambda(return_type, function_body) \
    ({ return_type fn function_body fn })
/* This can be used as: */
lambda (int, (int x, int y) { return x > y; })(1, 2)
/* Which is expanded into: */
({ int fn (int x, int y) { return x > y } fn; })(1, 2)

//////////////////////////////////////////////////////////////////////
/* Gives the offset of a member field */
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

//////////////////////////////////////////////////////////////////////
/* Making syscalls in asm with gcc, those won't appear in nm/objdump */
char *argv[]={"/bin/echo","parameter test", NULL};

int main(){
  int ret;
  __asm__ volatile ("syscall"
    :"=a" (ret) // return value
    :"a"(59), // syscall number (execve)
    "D"(argv[0]), // filename
    "S"(argv), // arguments
    "d"(0) // env
    :"rcx","r11","cc");
  return 0;
}

//////////////////////////////////////////////////////////////////////
/* Macro for type overloading using gcc builtins */
#define DEBUG(x)                                               \
({                                                             \
  if (__builtin_types_compatible_p (typeof (x), int))          \
    fprintf(stderr,"int(%d)\n",x);                             \
  else if (__builtin_types_compatible_p (typeof (x), char))    \
    fprintf(stderr,"char(%c)\n",x);                            \
  else if (__builtin_types_compatible_p (typeof (x), char[]))  \
    fprintf(stderr,"char[%s]\n",x);                            \
  else                                                         \
    fprintf(stderr,"unknown type\n");                          \
})