Code: Select all
#ifndef _STRING_H
#include <string.h> /* for strlen */
#endif
#ifndef _UNISTD_H
#include <unistd.h> /* for write */
#endif
#ifndef _STDLIB_H
#include <stdlib.h> /* for exit */
#endif
/* use fast bit shift ops to convert a string of 4 chars to an int*/
#define C4I(a,b,c,d) ((((((((d))<<8)|(c))<<8)|(b))<<8)|(a))
#define S2I(s) C4I(s[0], s[1], s[2], s[3])
/* convert 8 chars to long long (you can't switch-case a string) */
#define C8LL(a,b,c,d,e,f,g,h) ((((((((((((((((long long)h)<<8)|\
((long long)g))<<8)|((long long)f))<<8)|((long long)e))<<8)|\
((long long)d))<<8)|((long long)c))<<8)|((long long)b))<<8)|((long long)a))
#define S2LL(s) C8LL(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7])
/* for lossy string compression - useful for switch comparison of strings */
#define C2I(c) switch(c){ \
case '\0' : (0); break; \
case 'a' : case 'A' : (1); break: \
case 'b' : case 'B' : (2); break: \
case 'c' : case 'C' : (3); break: \
case 'd' : case 'D' : (4); break: \
case 'e' : case 'E' : (5); break: \
case 'f' : case 'F' : (6); break: \
case 'g' : case 'G' : (7); break: \
case 'h' : case 'H' : (8); break: \
case 'i' : case 'I' : (9); break: \
case 'j' : case 'J' : (10); break: \
case 'k' : case 'K' : (11); break: \
case 'l' : case 'L' : (12); break: \
case 'm' : case 'M' : (13); break: \
case 'n' : case 'N' : (14); break: \
case 'o' : case 'O' : (15); break: \
case 'p' : case 'P' : (16); break: \
case 'q' : case 'Q' : (17); break: \
case 'r' : case 'R' : (18); break: \
case 's' : case 'S' : (19); break: \
case 't' : case 'T' : (20); break: \
case 'u' : case 'U' : (21); break: \
case 'v' : case 'V' : (22); break: \
case 'w' : case 'W' : (23); break: \
case 'x' : case 'X' : (24); break: \
case 'y' : case 'Y' : (25); break: \
case 'z' : case 'Z' : (26); break: \
case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : case '#' : case '+' : (27); break: \
case '(' : case ')' : case '{' : case '}' : case '[' : case ']' : case '\"' : case '\'' : case '<' : case '>' : case '/' : case '\\' : (28); break: \
case ' ' : case '.' : case '-' : case '_' : case '~' : case ',' : (29); break: \
case ':' : case ';' : case '|' : case '!' : case '@' : case '$' : case '%' : case '&' : case '*' : (30); break: \
default : (31); break; }
#define ULL (unsigneed long long)
/* this one is case insensitive & bumps it up to 12 chars
* with room for 4 more bits, but it combines non-alpha characters */
#define S12LL(s) \
( ((s[0])==0)? 0 : ULL C2I(s[0]) | \
((s[1])==0)? 0 : ULL C2I(s[1])<<5)) | \
((s[2])==0)? 0 : ULL C2I(s[2])<<10)) | \
((s[3])==0)? 0 : ULL C2I(s[3])<<15)) | \
((s[4])==0)? 0 : ULL C2I(s[4])<<20)) | \
((s[5])==0)? 0 : ULL C2I(s[5])<<25)) | \
((s[6])==0)? 0 : ULL C2I(s[6])<<30)) | \
((s[7])==0)? 0 : ULL C2I(s[7])<<35)) | \
((s[8])==0)? 0 : ULL C2I(s[8])<<40)) | \
((s[9])==0)? 0 : ULL C2I(s[9])<<45)) | \
((s[10])==0)? 0 : ULL C2I(s[10])<<50)) | \
((s[11])==0)? 0 : ULL C2I(s[11])<<55)) \
) /* generate 2nd string in bash with "${word:12:99}" for longer strings */
/* this is an example of how to uses strings as sprites */
/* acceptable values in shape strings are 0123 - Set by the -'0'*/
#define shapeit444(s) ( ( s[0]-'0' )|( s[1]-'0'<<2 )|( s[2]-'0'<<4 )|\
( s[3]-'0'<<6 )|( s[4]-'0'<<8 )|( s[5]-'0'<<10 )|( s[6]-'0'<<12 )|\
( s[7]-'0'<<14 )|( s[8]-'0'<<16 )|( s[9]-'0'<<18 )|( s[10]-'0'<<20 )|\
( s[11]-'0'<<22 )|( s[12]-'0'<<24 )|( s[13]-'0'<<26 )|( s[14]-'0'<<28 )|\
( s[15]-'0'<<30 ) )
#define EXAMPLESHAPE444 shapeit( \
( "1023" \
"1022" \
"1000" \
"1111" ))
#define BIT(x) (1 << (x)) /*bit 3 would be 0000100 */
#define NUM_ELEMENTS(a) (sizeof(a)/sizeof(a[0])) /* argc is useless */
#define MAX(a, b) ((a < b) ? b : a)
#define MIN(a, b) ((a > b) ? b : a)
#define ABS(a) ((a < 0) ? -a : a)
#define SWAP(a, b) do { a ^= b; b ^= a; a ^= b; } while ( 0 )
/* write is much much smaller than printf */
#define W1(s) ((NULL != s) ? write(1,s, strlen(s)) : write(1,"", 1) )
#define W2(s) ((NULL != s) ? write(2,s, strlen(s)) : write(2,"", 1) )
/* only works with constant integers such as __LINE__ macro to convert to strings */
#define D2S(n) D2S_(n)
#define D2S_(n) #n
#define LINE_NO D2S(__LINE__)
/* GNU helper crap for verbose debugging, could probably be simplified */
#ifdef __STDC__
#define HAVE_STDC 1
#else
#define HAVE_STDC 0
#endif
#ifdef __STDC_VERSION__
#define HAVE_STDC_VERSION 1
#else
#define HAVE_STDC_VERSION 0
#endif
#ifdef __GNUC__
#define HAVE_GNUC 1
#else
#define HAVE_GNUC 0
#endif
#ifdef __OPTIMIZE__
#define HAVE_OPTIMIZE 1
#else
#define HAVE_OPTIMIZE 0
#endif
#ifdef __OPTIMIZE_SIZE__
#define HAVE_OPTIMIZE_SIZE 1
#else
#define HAVE_OPTIMIZE_SIZE 0
#endif
#ifdef __NO_INLINE__
#define HAVE_NO_INLINE 1
#else
#define HAVE_NO_INLINE 0
#endif
#ifdef __STDC_HOSTED__
#define HAVE_HOSTED 1
#else
#define HAVE_HOSTED 0
#endif
#ifdef __STRICT_ANSI__
#define HAVE_STRICT 1
#else
#define HAVE_STRICT 0
#endif
#ifdef DEBUG
#define D(s) W2("START Debug message : \n");W2(s); \
W2("\n\tIn function: ");W2(__func__); \
W2(", from file: ");W2(__FILE__); \
W2(", line:");W2(LINE_NO); \
W2("\n\tInclude at a depth of: ");W2(D2S(__INCLUDE_LEVEL__)); \
W2(", from base file:");W2(__BASE_FILE__); \
W2("\n\tCompiled Date: ");W2(__DATE__); \
W2(", at Time: ");W2(__TIME__); \
W2("\n\tMax values are char: ");W2(D2S(__SCHAR_MAX__)); \
W2(", short: ");W2(D2S(__SHRT_MAX__)); \
W2(", int: ");W2(D2S(__INT_MAX__)); \
W2(",\n\t long: ");W2(D2S(__LONG_MAX__)); \
W2(", long long: ");W2(D2S(__LONG_LONG_MAX__)); \
if (HAVE_STDC) W2("\n\tConforms to ISO Standard C"); \
if (HAVE_STDC_VERSION){ W2("\n\tC standard version=");W2(D2S(__STDC_VERSION__)); } \
if (HAVE_GNUC) { W2("\n\tgcc version ");W2(__VERSION__); } \
if (HAVE_OPTIMIZE) {W2("\n\tOptimized build");}else{W2("\n\tUn-ptimized build");} \
if (HAVE_OPTIMIZE_SIZE) W2("\n\tOptimized for size"); \
if (HAVE_NO_INLINE) {W2("\n\tInlining not disabled");}else{W2("\n\tInlining disabled");} \
if (HAVE_HOSTED) W2("\n\tHosted environment"); \
if (HAVE_STRICT) W2("\n\tUsing strict ansi"); \
W2("\nEND Debug message\n")
#else
#define D(s) /* when -DNDEBUG is passed at build, no debugging messages */
#endif
#define DIE(s,i) D(s);exit(i)
{ /* for CGI strings */
#ifndef _STDLIB_H
#include <stdlib.h> /* for getenv */
#endif
#define QUERY_STRING (char *)getenv("QUERY_STRING")
#define GATEWAY_INTERFACE (char *)getenv("GATEWAY_INTERFACE")
#define REMOTE_ADDR (char *)getenv("REMOTE_ADDR")
#define HTTP_USER_AGENT (char *)getenv("HTTP_USER_AGENT")
#define REMOTE_PORT (char *)getenv("REMOTE_PORT")
#define HTTP_ACCEPT (char *)getenv("HTTP_ACCEPT")
#define SCRIPT_FILENAME (char *)getenv("SCRIPT_FILENAME")
#define HTTP_HOST (char *)getenv("HTTP_HOST")
#define REQUEST_URI (char *)getenv("REQUEST_URI")
#define SERVER_SOFTWARE (char *)getenv("SERVER_SOFTWARE")
#define HTTP_ACCEPT_LANGUAGE (char *)getenv("HTTP_ACCEPT_LANGUAGE")
#define SERVER_PROTOCOL (char *)getenv("SERVER_PROTOCOL")
#define PATH_INFO (char *)getenv("PATH_INFO")
#define REQUEST_METHOD (char *)getenv("REQUEST_METHOD")
#define PWD (char *)getenv("PWD")
#define SCRIPT_NAME (char *)getenv("SCRIPT_NAME")
} /* CGI strings */
#define CHAR(x) ((char)(x))
#define INT(x) ((int)(x))
#define LONGLONG(x) ((long long)(x))
#define FLOAT(x) ((float *)(x))
#define DOUBLE(x) ((double)(x))
#define CHAR_(x) ((char *)(x))
/* these could be macros defined to 0,1,2,3...*/
enum { up,down,left,right };
enum { UP,DOWN,LEFT,RIGHT };
enum { north,south,west,east };
enum { NORTH,SOUTH,WEST,EAST };