/* This is C source code  and below is a simple C program that includes all 
 * the keywords of the C language. See the table of keywords in section 2.6 
 * in the book, C: A Reference Manual, 5th Edition.
  */

/*
#include <stdio.h>*/     /* preprocessor directive to include a file */
/*
#include <unistd.h>
*/

/* This is a preprocessor "macro" NOT a C function/procedure! */
/*
#define swap(a,b,type) do { type t = (a); (a) = (b); (b) = (t); } while (0)
*/
/* a typedef defines a new type, in this case Color is defined as a
 * new type using an enumeration, where red=0, green=1, blue=2, white=3 
 */
typedef enum color { red, green, blue, white } Color;

/* a struct is like a public class in C++, whose size is the sum of the 
 * size of each component of the struct. 
 */
struct pair {
       int x;
       int y;
};

/* a union allocates a block of memory big enough to hold the largest datum */
union builtin_types { 
       char a;
       short b;
       int c; 
       long d;
       float e;
       double f;
};

/* static storage is local to code in this file and is initialized 
 * to all zero bytes 
 */
static char buf[128];

/* constants can't be changed */
const int true = 1;
const int false = 0;

/* z is defined externally in some other program file */
extern double z;

void error()
{
    fprintf(stderr, "program is aborting....\n");
    /* no return statement used when a proc returns void */
}

/* a procedure */
int fact(int n) {
	int m = 1;
	while (n > 0) m *= n--;
	return m;
}

/* the main entry point of the program */
int main() {
	auto enum color c;  /* auto-matically stack allocated */
	volatile struct pair p; /* volatile means don't optimize */
	register unsigned int i; /* suggestion to the compiler to use a reg */

	/* sizeof(some-type) returns the number of bytes used by that datum */
	for (i = 0; i < sizeof(buf); ++i) {
		switch(c) {
			case red: 
			   buf[i] = 'R'; 
			   break;
			case green: 
			   buf[i] = 'G'; 
			   break;
		        case blue:
			   buf[i] = 'B'; 
                           break;
			default: break;
			  
		}
		if (c == white)
		  goto abort;
		else
		  continue;
	}

	if (p.x == 0 && p.y != 0)
	  do {
	    p.x += 1;
	    p.y %= 2;
	  } while (p.x <= 64);

	if (cond)
           swap(p.x, p.y, int_);  /* do macro substitution--see swap above */

	return (p.y >= 0) ? 1 : 0;

abort:  error();
	return (-1);
}
