1 /* 2 * gracula 3.0 3 * 4 * Graphic Counter Language 5 * 6 * Header file 7 * 8 * Copyright 1999 G. Adam Stanislav 9 * All rights reserved 10 * 11 * Started: 11-Jan-1999 12 * Updated: 18-Jun-1999 13 * 14 */ 15 #ifndef GCL_H 16 #define GCL_H 17 18 #define GCLRELEASEVERSION "3.0" 19 #define GCLVERSION GCLRELEASEVERSION 20 21 #include "gd.h" 22 23 #ifdef GCLUSEC9X 24 typedef unsigned long long counter_t; 25 typedef long long scounter_t; 26 #define strtoul strtoull 27 #define atoi(s) strtoll(s, (char **)NULL, 10) 28 #define integer "%llu" 29 #define sinteger "%lli" 30 #define counteger "%0*llu" 31 #define scounteger "%0*lli" 32 #else 33 #ifdef GCLUSELONGLONG 34 typedef unsigned long long counter_t; 35 typedef long long scounter_t; 36 #define strtoul strtouq 37 #define atoi(s) strtoq(s, (char **)NULL, 10) 38 #define integer "%qu" 39 #define sinteger "%qi" 40 #define counteger "%0*qu" 41 #define scounteger "%0*qi" 42 #else 43 typedef unsigned long counter_t; 44 typedef long scounter_t; 45 #define integer "%lu" 46 #define sinteger "%li" 47 #define counteger "%0*lu" 48 #define scounteger "%0*li" 49 #endif /* GCLUSELONGLONG */ 50 #endif /* GCLUSEC9X */ 51 52 /* 53 * You may change these if you need larger strings, or more digits or inhibitors. 54 * However, please do not distribute this file if you change it! 55 */ 56 #define LBSIZE 1024 /* lexbuffer size */ 57 #define MAXDIGITS 127 /* Maximum number of digits in the counter */ 58 59 #define ACCEPTABLECHARS 25 60 #define SECONDSINAYEAR (60 * 60 * 24 * 365) 61 62 /* lexanal return values */ 63 enum { 64 GCLPATH = 256, 65 GCLGRAPHICNUMBER, 66 BACKGROUND, 67 INVIS, 68 TRANSPARENT, 69 EXPIRES, 70 TOKALIGN, 71 SHIFT, 72 FRAME, 73 FRAMETYPE, 74 VERTICAL, 75 HORIZONTAL, 76 KERN, 77 PAD, 78 MINDIGITS, 79 OPTIMIZE, 80 SECURE, 81 COOKIE, 82 INHIBITOR, 83 RELAYOR, 84 TEXTCHAR, 85 TEDTURNER, 86 SILENT, 87 REDIRECT, 88 TODAY, 89 PER, 90 TIMEZONE, 91 SECONDS, 92 FORK, 93 PORTABLEGCL, 94 GROUP, 95 GCLREVERSE, 96 GCLPRINT, 97 NOCOMPILE, 98 SIGNEDCOUNTER, 99 UNSIGNEDCOUNTER, 100 FILEINCLUDE, 101 GCLREGISTER, 102 GCLINCREMENT, 103 GCLFUDGE, 104 GCLSIGMA, 105 GCLPUSH, 106 AK, 107 TRI, 108 109 TAK, 110 INAK, 111 ADD, 112 INC, 113 SUB, 114 DEC, 115 BAND, 116 BOR, 117 MUL, 118 DIV, 119 MOD, 120 XOR, 121 NE, 122 EQU, 123 GE, 124 LE, 125 CMP, 126 SHR, 127 SHL, 128 LAND, 129 LXOR, 130 LOR, 131 PASSIGN, 132 INTEGER, 133 STRING, 134 GCLENV, 135 PICTYPE, 136 HSHIFT, 137 VSHIFT, 138 VALIGN, 139 HALIGN, 140 NONE, 141 TOPBOTTOM, 142 COUNTER, 143 FROM, 144 SHELL, 145 REFERRER, 146 CONDITION, 147 TIMEPERIOD, 148 NODEFAULT, 149 USEDEFAULT, 150 GCLERROR 151 }; 152 153 /* GCL registers and variables */ 154 enum { 155 REGA, 156 REGB, 157 REGC, 158 REGD, 159 /* 160 * By inserting variables into this array we can use the same section 161 * of code to manipulate variables as we do for registers. 162 */ 163 COUNT, 164 NUMREGS 165 }; 166 167 #define count gclregs[COUNT] 168 169 /* How often do we reset? */ 170 typedef enum { 171 WEEKLY = -1, 172 NEVER, 173 ANNUALY, 174 MONTHLY, 175 DAILY 176 } gclreset; 177 178 typedef enum { 179 STZ, /* Server Time Zone */ 180 UTC /* Universal Time Coordinated, p.k.a. GMT */ 181 } gcltzone; 182 183 #define SHOWCOUNT 0 184 #define SHOWTIME 1 185 #define SHOWDATE 2 186 #define SHOWZONE 4 187 188 #define monthfirst(x) ((x) < 0) 189 #define yearfirst(x) ((x) == 0) 190 #define dayfirst(x) ((x) > 0) 191 192 #define VPAD TOPBOTTOM 193 #define HPAD HSHIFT 194 195 /* pad index */ 196 enum { 197 TPAD, 198 BPAD, 199 LPAD, 200 RPAD, 201 NUMPADS 202 }; 203 204 #define tpad pad[TPAD] 205 #define bpad pad[BPAD] 206 #define lpad pad[LPAD] 207 #define rpad pad[RPAD] 208 209 /* frame types */ 210 enum { 211 POPUP = 1, 212 BUTTON, 213 DEFAULTBUTTON, 214 SHADOW, 215 BOX, 216 FRAMES /* number of frame types */ 217 }; 218 219 /* graphic array indices */ 220 enum { 221 DASH = 10, 222 COLON, 223 TIME, 224 ZONE, 225 MINUS, 226 PLUS, 227 SPACE, 228 DOT, 229 COMMA, 230 HEADPICTURE, 231 TAILPICTURE, 232 /* keep the above in their place! */ 233 BKGPICTURE, 234 TILE, 235 ARRAYPICTURE, 236 PICTUREDIRECTORY, 237 GRAPHICS 238 }; 239 240 #define arraypicture (picture[ARRAYPICTURE]) 241 #define picturedirectory (picture[PICTUREDIRECTORY]) 242 #define spacepicture (picture[SPACE]) 243 #define dotpicture (picture[DOT]) 244 #define commapicture (picture[COMMA]) 245 #define bkgpicture (picture[BKGPICTURE]) 246 #define headpicture (picture[HEADPICTURE]) 247 #define tailpicture (picture[TAILPICTURE]) 248 #define tilepicture (picture[TILE]) 249 #define dashpicture (picture[DASH]) 250 #define colonpicture (picture[COLON]) 251 #define pluspicture (picture[PLUS]) 252 #define minuspicture (picture[MINUS]) 253 #define timepicture (picture[TIME]) 254 #define zonepicture (picture[ZONE]) 255 #define tileimage (defaultimage[TILE]) 256 #define bkgimage (defaultimage[BKGPICTURE]) 257 258 enum { 259 DEFINECOMMA, 260 DEFINECOLON, 261 DEFINEDASH, 262 DEFINETIME, 263 DEFINEZONE, 264 DEFINECHAR 265 }; 266 267 #define comma (definechar[DEFINECOMMA]) 268 #define colon (definechar[DEFINECOLON]) 269 #define dash (definechar[DEFINEDASH]) 270 #define timechar (definechar[DEFINETIME]) 271 #define zone (definechar[DEFINEZONE]) 272 273 /* types of graphics in the counter layer */ 274 enum { 275 /* Keep HEAD at position 0 */ 276 HEAD, 277 TAIL, 278 DIGITS, 279 COMMAS, 280 SPACES, 281 DOTS, 282 DASHES, 283 COLONS, 284 PLUSSES, 285 MINUSES, 286 TIMES, 287 ZONES, 288 GRAPHICTYPES 289 }; 290 291 /* 292 * Note on "ternary" logic: 293 * 294 * GCL often uses logic that can have three states. Traditional 295 * computer logic uses two states (e.g. FALSE and TRUE) with values 296 * of zero and non-zero (binary logic). 297 * 298 * For anything else, C programs typically use "enum" which by default 299 * starts at zero. Whenever there are three possible states (quite often 300 * in this program), GCL uses "enum" but overrides the default values 301 * to start at -1 instead of zero. This compiles to three values: -1, 0, 1. 302 * 303 * The advantage of this approach is that we can check the logic as being 304 * less than zero, equal to zero, or greater than zero, as opposed to 305 * equal to zero, equal to 1, equal to 2. In other words, the resultant 306 * machine code only needs to make ONE comparison instead of three, then branch 307 * off based on whether it is less than, equal to, or greater than, the compared 308 * value. The gcc compiler understands this and produces highly optimized 309 * code (at least with the -O3 switch). 310 * 311 * As I was writing the program, at first I used #define to declare the values 312 * of -1, 0, 1, and hardcoded the comparisons in the program. Later, I was 313 * using ternary logic in more and more places, and started using enums, as 314 * well as placed the comparisons into this header file as macros. This, 315 * hopefully, makes the code easier to read, and it certainly makes it easier 316 * to maintain. 317 * 318 * But you will find some remnants of the original approach of using #define 319 * rather than enum here. In either case, the resultant machine code should 320 * be exactly the same regardless of which approach is used. 321 * 322 * In some cases, (such as "when" and "unless") I ended up using binary 323 * logic after all but did not change the enum to two states only. It makes 324 * no difference in the efficiency of the resultant code, while trying to 325 * change it might have easily introduced bugs. And who needs those? 326 */ 327 328 /* redirection ternary logic */ 329 typedef enum { 330 UNINHIBITEDREDIRECTION = -1, 331 NOREDIRECTION, 332 REDIRECTORINHIBIT 333 } gclredirection; 334 335 #define uninhibitedredirection(x) ((int)(x) < 0) 336 #define noredirection(x) ((int)(x) == 0) 337 #define redirectorinhibit(x) ((int)(x) > 0) 338 339 /* alignment/shift types */ 340 #define TOP (-1) 341 #define MIDDLE 0 342 #define BOTTOM 1 343 #define LEFT (-1) 344 #define CENTER 0 345 #define RIGHT 1 346 #define UP (-1) 347 #define DOWN 1 348 349 /* transparency permissions */ 350 #define TRANSREQUIRED (-1) 351 #define NOTRANS 0 352 #define TRANSOK 1 353 #define transrequired(b) (b.trans < 0) 354 #define notrans(b) (b.trans == 0) 355 #define transok(b) (b.trans > 0) 356 357 /* image file types */ 358 #define GIFSOURCE 1 359 #define GDSOURCE 2 360 #define XBMSOURCE 3 361 362 /* ternary conditions */ 363 typedef enum { 364 UNLESS = -1, 365 NOCONDITION, 366 WHEN 367 } gclcondition; 368 369 #define unless(x) ((x) < 0) 370 #define when(x) ((x) > 0) 371 372 typedef struct { 373 int h[GRAPHICTYPES]; 374 int v[GRAPHICTYPES]; 375 } gclalign; 376 377 #define halignflag (alignflag.h) 378 #define valignflag (alignflag.v) 379 #define hashift (ashift.h) 380 #define vashift (ashift.v) 381 382 typedef struct { 383 char *graphic; 384 gdImagePtr image; 385 int gtype; 386 int origin; 387 int isused:1; 388 int isarray:1; 389 int iscreated:1; 390 int x, y, dx, dy; 391 } gclpic; 392 393 typedef struct { 394 int left; 395 int top; 396 int right; 397 int bottom; 398 int trans; 399 void (*draw)(gdImagePtr, int, int, int, int); 400 } gclframe; 401 402 typedef struct { 403 int red; 404 int green; 405 int blue; 406 } rgbcolor; 407 408 typedef enum { 409 CONCEDE, 410 INHIBIT 411 } gclinhibitor; 412 413 typedef struct inhibit { 414 int op; 415 gclcondition condition; 416 gclinhibitor inhibitor; 417 char *env; 418 char *val; 419 int cookie; 420 struct inhibit *next; 421 } inhibit; 422 423 typedef enum { 424 SERVE, 425 RELAY 426 } gclrelayor; 427 428 typedef struct relay { 429 int op; 430 gclcondition condition; 431 gclrelayor relayor; 432 char *env; 433 char *val; 434 int cookie; 435 struct relay *next; 436 char *url; 437 } relay; 438 439 typedef struct { 440 char *name; 441 char *value; 442 } cookiepair; 443 444 typedef struct { 445 int year; 446 int month; 447 int day; 448 int week; 449 } gcldate; 450 451 typedef struct { 452 gcltzone tz; 453 long secs; 454 } gcltimezone; 455 456 typedef struct fi { 457 FILE *fh; 458 struct fi *prev; 459 int lineno; 460 char *filename; 461 } fi; 462 463 /* 464 * Random number generator constants. These are redefinable on the C compiler 465 * command line: Still searching for the perfect ones... 466 */ 467 #ifndef GCLRNDMUL 468 #define GCLRNDMUL 11093 469 #elif GCLRNDMUL <= 0 470 #undef GCLRNDMUL 471 #define GCLRNDMUL 11093 472 #endif 473 #ifndef GCLRNDADD 474 #define GCLRNDADD 2099711 475 #elif GCLRNDADD <= 0 476 #undef GCLRNDADD 477 #define GCLRNDADD 2099711 478 #endif 479 480 /* 481 * I guess it would make sense to call unputlex "ungetlex" as it is 482 * modeled after "ungetc" but for some unexplained reason I just 483 * happened to type "put" instead of "get" when I first started working 484 * on this. There is no subtle reason for the use of "put" except that 485 * I was probably thinking about a thousand other things when I first 486 * defined the macro, and did not feel later on there was any good 487 * reason to change it. 488 */ 489 #define unputlex(c) lexstack=(c) 490 #define token(t,v) if (!strcmp(lexbuffer,t)) return (v) 491 #define lvtoken(t,l,v) if (!strcmp(lexbuffer,t)) {lexvalue=(l);return(v);} 492 #define lex (l=lexanal()) 493 #define signedinteger l=expression() 494 #define synterr(str) syntax(str);unputlex(l);break 495 #define polite(str) if (!syschat(str)){chars=0;continue;} 496 #endif /* GCL_H */ 497