/* * gracula 3.0 * * Graphic Counter Language * * Header file * * Copyright 1999 G. Adam Stanislav * All rights reserved * * Started: 11-Jan-1999 * Updated: 18-Jun-1999 * */ #ifndef GCL_H #define GCL_H #define GCLRELEASEVERSION "3.0" #define GCLVERSION GCLRELEASEVERSION #include "gd.h" #ifdef GCLUSEC9X typedef unsigned long long counter_t; typedef long long scounter_t; #define strtoul strtoull #define atoi(s) strtoll(s, (char **)NULL, 10) #define integer "%llu" #define sinteger "%lli" #define counteger "%0*llu" #define scounteger "%0*lli" #else #ifdef GCLUSELONGLONG typedef unsigned long long counter_t; typedef long long scounter_t; #define strtoul strtouq #define atoi(s) strtoq(s, (char **)NULL, 10) #define integer "%qu" #define sinteger "%qi" #define counteger "%0*qu" #define scounteger "%0*qi" #else typedef unsigned long counter_t; typedef long scounter_t; #define integer "%lu" #define sinteger "%li" #define counteger "%0*lu" #define scounteger "%0*li" #endif /* GCLUSELONGLONG */ #endif /* GCLUSEC9X */ /* * You may change these if you need larger strings, or more digits or inhibitors. * However, please do not distribute this file if you change it! */ #define LBSIZE 1024 /* lexbuffer size */ #define MAXDIGITS 127 /* Maximum number of digits in the counter */ #define ACCEPTABLECHARS 25 #define SECONDSINAYEAR (60 * 60 * 24 * 365) /* lexanal return values */ enum { GCLPATH = 256, GCLGRAPHICNUMBER, BACKGROUND, INVIS, TRANSPARENT, EXPIRES, TOKALIGN, SHIFT, FRAME, FRAMETYPE, VERTICAL, HORIZONTAL, KERN, PAD, MINDIGITS, OPTIMIZE, SECURE, COOKIE, INHIBITOR, RELAYOR, TEXTCHAR, TEDTURNER, SILENT, REDIRECT, TODAY, PER, TIMEZONE, SECONDS, FORK, PORTABLEGCL, GROUP, GCLREVERSE, GCLPRINT, NOCOMPILE, SIGNEDCOUNTER, UNSIGNEDCOUNTER, FILEINCLUDE, GCLREGISTER, GCLINCREMENT, GCLFUDGE, GCLSIGMA, GCLPUSH, AK, TRI, TAK, INAK, ADD, INC, SUB, DEC, BAND, BOR, MUL, DIV, MOD, XOR, NE, EQU, GE, LE, CMP, SHR, SHL, LAND, LXOR, LOR, PASSIGN, INTEGER, STRING, GCLENV, PICTYPE, HSHIFT, VSHIFT, VALIGN, HALIGN, NONE, TOPBOTTOM, COUNTER, FROM, SHELL, REFERRER, CONDITION, TIMEPERIOD, NODEFAULT, USEDEFAULT, GCLERROR }; /* GCL registers and variables */ enum { REGA, REGB, REGC, REGD, /* * By inserting variables into this array we can use the same section * of code to manipulate variables as we do for registers. */ COUNT, NUMREGS }; #define count gclregs[COUNT] /* How often do we reset? */ typedef enum { WEEKLY = -1, NEVER, ANNUALY, MONTHLY, DAILY } gclreset; typedef enum { STZ, /* Server Time Zone */ UTC /* Universal Time Coordinated, p.k.a. GMT */ } gcltzone; #define SHOWCOUNT 0 #define SHOWTIME 1 #define SHOWDATE 2 #define SHOWZONE 4 #define monthfirst(x) ((x) < 0) #define yearfirst(x) ((x) == 0) #define dayfirst(x) ((x) > 0) #define VPAD TOPBOTTOM #define HPAD HSHIFT /* pad index */ enum { TPAD, BPAD, LPAD, RPAD, NUMPADS }; #define tpad pad[TPAD] #define bpad pad[BPAD] #define lpad pad[LPAD] #define rpad pad[RPAD] /* frame types */ enum { POPUP = 1, BUTTON, DEFAULTBUTTON, SHADOW, BOX, FRAMES /* number of frame types */ }; /* graphic array indices */ enum { DASH = 10, COLON, TIME, ZONE, MINUS, PLUS, SPACE, DOT, COMMA, HEADPICTURE, TAILPICTURE, /* keep the above in their place! */ BKGPICTURE, TILE, ARRAYPICTURE, PICTUREDIRECTORY, GRAPHICS }; #define arraypicture (picture[ARRAYPICTURE]) #define picturedirectory (picture[PICTUREDIRECTORY]) #define spacepicture (picture[SPACE]) #define dotpicture (picture[DOT]) #define commapicture (picture[COMMA]) #define bkgpicture (picture[BKGPICTURE]) #define headpicture (picture[HEADPICTURE]) #define tailpicture (picture[TAILPICTURE]) #define tilepicture (picture[TILE]) #define dashpicture (picture[DASH]) #define colonpicture (picture[COLON]) #define pluspicture (picture[PLUS]) #define minuspicture (picture[MINUS]) #define timepicture (picture[TIME]) #define zonepicture (picture[ZONE]) #define tileimage (defaultimage[TILE]) #define bkgimage (defaultimage[BKGPICTURE]) enum { DEFINECOMMA, DEFINECOLON, DEFINEDASH, DEFINETIME, DEFINEZONE, DEFINECHAR }; #define comma (definechar[DEFINECOMMA]) #define colon (definechar[DEFINECOLON]) #define dash (definechar[DEFINEDASH]) #define timechar (definechar[DEFINETIME]) #define zone (definechar[DEFINEZONE]) /* types of graphics in the counter layer */ enum { /* Keep HEAD at position 0 */ HEAD, TAIL, DIGITS, COMMAS, SPACES, DOTS, DASHES, COLONS, PLUSSES, MINUSES, TIMES, ZONES, GRAPHICTYPES }; /* * Note on "ternary" logic: * * GCL often uses logic that can have three states. Traditional * computer logic uses two states (e.g. FALSE and TRUE) with values * of zero and non-zero (binary logic). * * For anything else, C programs typically use "enum" which by default * starts at zero. Whenever there are three possible states (quite often * in this program), GCL uses "enum" but overrides the default values * to start at -1 instead of zero. This compiles to three values: -1, 0, 1. * * The advantage of this approach is that we can check the logic as being * less than zero, equal to zero, or greater than zero, as opposed to * equal to zero, equal to 1, equal to 2. In other words, the resultant * machine code only needs to make ONE comparison instead of three, then branch * off based on whether it is less than, equal to, or greater than, the compared * value. The gcc compiler understands this and produces highly optimized * code (at least with the -O3 switch). * * As I was writing the program, at first I used #define to declare the values * of -1, 0, 1, and hardcoded the comparisons in the program. Later, I was * using ternary logic in more and more places, and started using enums, as * well as placed the comparisons into this header file as macros. This, * hopefully, makes the code easier to read, and it certainly makes it easier * to maintain. * * But you will find some remnants of the original approach of using #define * rather than enum here. In either case, the resultant machine code should * be exactly the same regardless of which approach is used. * * In some cases, (such as "when" and "unless") I ended up using binary * logic after all but did not change the enum to two states only. It makes * no difference in the efficiency of the resultant code, while trying to * change it might have easily introduced bugs. And who needs those? */ /* redirection ternary logic */ typedef enum { UNINHIBITEDREDIRECTION = -1, NOREDIRECTION, REDIRECTORINHIBIT } gclredirection; #define uninhibitedredirection(x) ((int)(x) < 0) #define noredirection(x) ((int)(x) == 0) #define redirectorinhibit(x) ((int)(x) > 0) /* alignment/shift types */ #define TOP (-1) #define MIDDLE 0 #define BOTTOM 1 #define LEFT (-1) #define CENTER 0 #define RIGHT 1 #define UP (-1) #define DOWN 1 /* transparency permissions */ #define TRANSREQUIRED (-1) #define NOTRANS 0 #define TRANSOK 1 #define transrequired(b) (b.trans < 0) #define notrans(b) (b.trans == 0) #define transok(b) (b.trans > 0) /* image file types */ #define GIFSOURCE 1 #define GDSOURCE 2 #define XBMSOURCE 3 /* ternary conditions */ typedef enum { UNLESS = -1, NOCONDITION, WHEN } gclcondition; #define unless(x) ((x) < 0) #define when(x) ((x) > 0) typedef struct { int h[GRAPHICTYPES]; int v[GRAPHICTYPES]; } gclalign; #define halignflag (alignflag.h) #define valignflag (alignflag.v) #define hashift (ashift.h) #define vashift (ashift.v) typedef struct { char *graphic; gdImagePtr image; int gtype; int origin; int isused:1; int isarray:1; int iscreated:1; int x, y, dx, dy; } gclpic; typedef struct { int left; int top; int right; int bottom; int trans; void (*draw)(gdImagePtr, int, int, int, int); } gclframe; typedef struct { int red; int green; int blue; } rgbcolor; typedef enum { CONCEDE, INHIBIT } gclinhibitor; typedef struct inhibit { int op; gclcondition condition; gclinhibitor inhibitor; char *env; char *val; int cookie; struct inhibit *next; } inhibit; typedef enum { SERVE, RELAY } gclrelayor; typedef struct relay { int op; gclcondition condition; gclrelayor relayor; char *env; char *val; int cookie; struct relay *next; char *url; } relay; typedef struct { char *name; char *value; } cookiepair; typedef struct { int year; int month; int day; int week; } gcldate; typedef struct { gcltzone tz; long secs; } gcltimezone; typedef struct fi { FILE *fh; struct fi *prev; int lineno; char *filename; } fi; /* * Random number generator constants. These are redefinable on the C compiler * command line: Still searching for the perfect ones... */ #ifndef GCLRNDMUL #define GCLRNDMUL 11093 #elif GCLRNDMUL <= 0 #undef GCLRNDMUL #define GCLRNDMUL 11093 #endif #ifndef GCLRNDADD #define GCLRNDADD 2099711 #elif GCLRNDADD <= 0 #undef GCLRNDADD #define GCLRNDADD 2099711 #endif /* * I guess it would make sense to call unputlex "ungetlex" as it is * modeled after "ungetc" but for some unexplained reason I just * happened to type "put" instead of "get" when I first started working * on this. There is no subtle reason for the use of "put" except that * I was probably thinking about a thousand other things when I first * defined the macro, and did not feel later on there was any good * reason to change it. */ #define unputlex(c) lexstack=(c) #define token(t,v) if (!strcmp(lexbuffer,t)) return (v) #define lvtoken(t,l,v) if (!strcmp(lexbuffer,t)) {lexvalue=(l);return(v);} #define lex (l=lexanal()) #define signedinteger l=expression() #define synterr(str) syntax(str);unputlex(l);break #define polite(str) if (!syschat(str)){chars=0;continue;} #endif /* GCL_H */