This is the README file for gracula v3.0, the compiler/interpreter for
Graphic Counter Language.

Copyright 1999 G. Adam Stanislav
All rights reserved

The code for gracula consists of the following source files:

gcl.c
gcl.h
gcdefaults.c
gcldefaults.h

The code for a sample GCL application, sec2000, is in the file sec2000.c.
But see below how you can achieve the same result in plain GCL!

These files are Copyright (c) 1999 G. Adam Stanislav. All rights reserved.

Additionally, several files from Thomas Boutell's gd1.3 packages are
included, with some modifications to work better with gracula. These files
are:

gd.c
gd.h
mtables.c

The following notice applies to these three files only:

     Portions copyright 1994, 1995, 1996, 1997, 1998, by Cold Spring
     Harbor Laboratory. Funded under Grant P41-RR02188 by the National
     Institutes of Health.
     
     Portions copyright 1996, 1997, 1998, by Boutell.Com, Inc.
     
     GIF decompression code copyright 1990, 1991, 1993, by David Koblas
     (koblas@netcom.com).
     
     Non-LZW-based GIF compression code copyright 1998, by Hutchison
     Avenue Software Corporation (http://www.hasc.com/, info@hasc.com).
     
     Permission has been granted to copy and distribute gd in any
     context, including a commercial application, provided that this
     notice is present in user-accessible supporting documentation.
     
     This does not affect your ownership of the derived work itself, and
     the intent is to assure proper credit for the authors of gd, not to
     interfere with your productive use of gd. If you have questions,
     ask. "Derived works" includes all programs that utilize the
     library. Credit must be given in user-accessible documentation.
     
     Permission to use, copy, modify, and distribute this software and
     its documentation for any purpose and without fee is hereby
     granted, provided that the above copyright notice appear in all
     copies and that both that copyright notice and this permission
     notice appear in supporting documentation. This software is
     provided "as is" without express or implied warranty.

End of gd1.3 notice.

Except for the three files from gd1.3, this package is distributed under
the terms of the WHIZ KID TECHNOMAGIC NO-NONSENSE LICENCE. Please read
the file NNL for details. No ammendment has been specified.

The name of the executable program has been changed starting with v2.20
from gcl to gracula. This happened for two reasons:

        1. GNU Common Lisp is also distributed as gcl. So, a conflict is
           possible on systems that contain both programs.

        2. To allow for a clear distinction between GCL, the language, and
           gracula the compiler/interpreter for the language.

Secondly, versions prior to 2.20 suggested the installation of the program
in /usr/bin. Starting with v2.20, the program is installed to /usr/local/bin
by default. As of v2.30, the suggested location for graphic files is in the
/usr/local/share/gracula/pix directory.

If you have many existing counters that expect the program to be /usr/bin/gcl,
you can create a symbolic link, for example:

        ln -fs /usr/local/bin/gracula /usr/bin/gcl

You can also convert your existing counters to look for /usr/local/bin/gracula
in the future by entering the following command from your Unix command line:

        echo "#!/usr/local/bin/gracula" >> mycounter.gcl

You need to substitute the name of your counter for "mycounter.gcl". Also, if
your counter passes command line parameters from the #! line, you need to
enter those.

For example, if your existing counter uses "#%/usr/bin/gcl -tmaz", enter:

        echo "#!/usr/local/bin/gracula -tmaz" >> mycounter.gcl

Please remember to use the DOUBLE >>, not the single > (which would overwrite
your counter instead of appending to it).

COMPILATION AND INSTALLATION
============================

* Under FreeBSD
  -------------

Gracula is in the graphics category of the FreeBSD ports collection. All you
have to do is type at the shell prompt:

	cd /usr/ports/graphics/gracula
	make install

To upgrade from a previous version, first make sure your ports collection is
up to date. Then type:

	cd /usr/ports/graphics/gracula
	make clean install -DFORCE_PKG_REGISTER

* Under other systems
  -------------------

To compile the source code, simply type

        make

To install the compiled software, type

        make install

If you wish to create the symbolic link mentioned above, type:

        make gcl

You can always find the latest version of gracula at:

        ftp.whizkidtech.net/gcl/
        www.whizkidtech.net/gcl/

INFORMATION
===========

You can also find an introductory tutorial, FAQ, and other pertinent
information at www.whizkidtech.net/gcl/.

You can find interesting scripts and counter art in Count Gracula's Gallery,
located at http://www.whizkidtech.net/gcl/gallery/.

A mailing list for gracula users exists. You can subscribe to it at:

        www.onelist.com/subscribe/gracula

This is highly recommended for several reasons:

        - announcements of new versions will go on the list first;
        - GCL documentation generally lags behind gracula capabilities,
          so the list is a perfect place for the how-do-I-do-this type
          of questions;
        - others may come up with ideas I have not thought of.

LANGUAGE OVERVIEW
=================

Graphic Counter Language consists of a set of keywords. It also understands
compiler directives, and allows for comments. Note that this overview is NOT
exhaustive. Please visit http://www.whizkidtech.net/gcl/ and read the FAQ and
the introductory tutorial. Alas, even those are not exhaustive because I spend
more time updating the software than its documentation... You can always
subscribe to the mailing list, and ask questions there. Or, you can read
its archives even if you do not subscribe. See the INFORMATION section above
for details.

I should probably write a book on GCL. This would force me to take enough time
to write complete documentation.

Comments and most compiler directives start with an octothorp (`#'). No compiler
directive starts with two of them, so it is a good idea to start comments with
a double octothorp (`##'). That way you can be sure that a new version of GCL
(and gracula) will not interpret an old comment as a new compiler directive.

* The `#!' directive
  ------------------

Strictly speaking, this is not a GCL directive but a shell directive. Most Unix
shells understand it to execute the appropriate language interpreter providing
the file starts with this directive.

For example, suppose a script named counter.gcl starts with the following line:

#!/usr/local/bin/gracula -maz

Now, suppose you enter the following command at your shell prompt:

	./counter.gcl -ld

The shell will examine the start of the file, and find the #! directive. It
will then interpret your command as if you have typed:

	/usr/local/bin/gracula -maz ./counter.gcl -ld

That means, among other things, that you can incorporate command line switches
directly into your script, but you can still override them on the command line.

* The image directives
  --------------------

The `G' in `GCL' stands for `graphic'. It is possible to build a version of
gracula with all graphics built in (we will talk about that later), but in
many cases you may want to prefer to use the image directives, as they offer
the flexibility of using different images in different counters and timers.

Gracula can take image data from four sources:

	- Built-in images;
	- Individual image files;
	- Files in a directory;
	- Image array.

You can use any combination of the four sources in your script.

Gracula understands 23 image directives to determine where the image should
come from. If none is given, it will use the built-in images. By default,
the built-in images are null, i.e., no images are built in, unless you build
them in yourself.

Secondly, if an image is not specified, but an image directory is, gracula
will use a file with a default name from that directory. The default names
are: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, dash, colon, time, zone, minus, plus, comma,
head, tail, bkg, tile, and array. Each has the extension of gif, gd, or xbm,
as appropriate.

The directives are `#0' - `#9' for the images of digits 0-9, `#-' for the
image of the dash, `#%' for the colon, `#^' for time, `#@' for zone, `#<' for
minus, `#>' for plus, `#,' for comma, `#~' for space, `#;' for dot, `#:' for
head, `#.' for tail, `#$' for background, `#+' for tile, `#[' for image array
file, and `[/' for the image directory described in the previous paragraph.
Note that the quotes are not part of the directive.

Some things worth noticing about these images are:

	`#^' (time) is an image of letter `T', while `#@' (zone) is an image
	of letter `Z'. These are used in timers in accordance with ISO 8601.

	`#-' (dash) and `#<' (minus) may be the same image or they may be
	different. They, too, are used in accordance with ISO 8601.

There are several ways to use image directives. The first way, which is valid
for all 23 image directives, follows the directive by a path (in double quotes),
followed by `gif', `gd', or `xbm' (no quotes).

For example:

	#/ "/usr/local/share/gracula/pix/odometer" gd

This tells gracula to look for default image files in the directory specified
and to treat them as gd graphic files. So, if it needs to render the digit 0,
and has no explicit information about its image, it will attempt to read it from
the /usr/local/share/gracula/pix/odometer/0.gd file. If the file does not
exist, gracula will use the built-in image for digit 0, if one exists. If
even that fails, gracula will simply not render the image.

The image for digit 0 from the above example could also be listed explicitly:

	#0 "/usr/local/share/gracula/pix/odometer/0.gd" gd

The second way is to define the location of the image in the image array.

Fo example:

	#0 [0, 0, 10, 16]

This tells gracula that the image for digit 0 starts at coordinates (0, 0) of
the array (upper left corner), and is 10 pixels wide and 16 pixels high.

It is not necessary to define an image if you do not want to use it. For
example, a date may be rendered without dashes. Simply do not define any image
for a dash, right? Right, as long as you do not have a built-in image for a
dash... In that case, you can instruct gracula not to use it:

	#- nodefault

You may also tell it explicitly that no image is defined and to use default if
one exists:

	#- default

What if you use the same directive several times? Gracula will use the last one.
Same holds true about all other directives and keywords. That way you can modify
an active counter without editing it in a text editor. An active counter is one
that is being used on a web site. You never want to edit it directly because
you would lose count on anyone who was counted on the web while you were editing
the file. Instead, you can append the changes using the double `>>' symbol.

For example, suppose you want to stop using a dash in the script `counter.gcl'.
Just enter the following from the Unix command line:

	% echo "#- default" >> counter.gcl

Make sure not to use the single `>' or you will overwrite the file instead of
appending to it. Also, the `%' denotes your command line prompt, not something
you should type. Your prompt may be different.

* The `utc' and `stz' directives
  ------------------------------

The web is international. Displaying date and time is meaningful only in
relation to a time zone.

The `utc' directive tells gracula to use Universal Time Coordinated (previously
known as GMT), while the `stz' directive tells it to use "Server Time Zone,"
i.e., the time zone your web server considers its own.

Optionally, these two directives may be followed by a `+' or a `-' and the
time difference from utc or stz in SECONDS.

For example, www.whizkidtech.net is hosted by pair Networks in Pittsburgh.
Its stz is Eastern Zone, whether standard or daylight-saving, depending on the
time of the year. But I want the timers to be shown using the Central Zone,
because I live in that zone. So, I use the following directive:

	stz - 3600

That tells gracula to display time and date as it is one hour (3600 seconds)
West of stz.

If my web site was hosted by a California host, I would use:

	stz + 7200

because I am 2 hours East of California. Note that this is an arithmetic
expression, hence the plus sign is not optional.

* The `count' variable
  --------------------

This is where gracula keeps track of the count. Unless inhibited, gracula
increases this value by 1 each time it runs the script. It can come in these
forms:

	count = 1234

This will set count to 1234

	count = ${COUNT}

This will set count to the value specified in environment variable COUNT. If
the variable starts with digits 1 - 9, gracula treats it as a decimal number;
if with 0x, as a hexadecimal number, or if with 0, as an octal number. This is
the same convention as used by the C programming language. If the environment
variable does not start with a number, or if it does not exist, count will be
set to 0.

Note that this will only work with the INITIAL value. Next time around, the
count will be increased by 1 again.

	count = `someprogram -options`

This works similar, except it will read the stdout output of the program
specified and set the count to its value. Again, it works only the first time.
But, if you want it to work every time, use the `-n' command line option which
prevents gracula from compiling a new version of the script. That way, every
time is the first time, in a manner of speaking.

Better yet, use the `nocompile' directive (new to version 2.30). Unlike the `-n'
command line option it cannot be overridden from the command line. So even if
some malicious cracker runs your script using the `-N' option, gracula will not
compile the script. You can always change it later by appending `nocompile none'
or `nocompile default' to your script.

By the way, you can use a script to do nothing but produce the count, then
use different scripts to display the count using different images.

For example, create a simple counter, simple.gcl:

	#!/usr/local/bin/gracula
	count = 1

This counter will output its count as text to stdout without inserting any
commas, then increase the value of count.

Then you can create several scripts which look something like this:

	#!/usr/local/bin/gracula
	#/ "/usr/local/share/gracula/pix/dir" gd
	nocompile
	count = `/usr/local/bin/simple.gcl -lot -1`

Each time you run one of these scripts, they will get their count from
simple.gcl, and display it using whatever images are defined in the script.
(The `-l' (local) option tells it not to output the HTTP header information,
the`-o' option to omit commas from the output, and the `-t' option to output
text rather than a gif image. The `-1' option makes sure simple.gcl does not
print extra leading zeros in its output. They would make your script interpret
the number as being octal rather than decimal.)

Now, let's try something more advanced. Suppose you want to show a random count
each time you run your script, but you want to keep track of how many times
it was run. You produce a simple program that prints a random number to stdout.
Let's assume you call it `random'. But how do you use it?

If you do something like:

	nocompile
	count = `/usr/local/bin/random`

it will show the random counter every time, but it will not keep track of how
many times the script was run because of the nocompile direction. But if you
remove the nocompile direction, it will show a random number the first time,
and then just increase it by one the next time.

The solution becomes simple if you recall that you can use any keyword and
directive repeatedly, and gracula will use the last occurence:

	#!/usr/local/bin/gracula
	#/ "/usr/local/share/gracula/pix/dir" gd
	nocompile
	count = `/usr/local/bin/simple.gcl -c`
	count = `/usr/local/bin/random`

In this script, you run simple.gcl with the `-c' option (compile only). It will
produce no output, just recompile the script, thus increasing its count. The
value of count will be 0 (because of no output). Then you run `random' and
assign its output to count, and display it.

Note that you can use an environment variable or a program anywhere in your
script where an integer is expected.

You can do the same whenever a string is expected. For example:

	#/ ${PICDIR} gd

In some cases, GCL allows you to use either a string or an integer... In that
case, the environment variable or program output is interpreted as a text
string unless it is followed by an exclamation point, in which case it is
treated an an integer. However, you can only use the exclamation point whenever
such an ambiguity would exist. Otherwise you cannot use it.

Just remember, if you want it to happen every time, use the `nocompile'
directive. If you want it to happen only the first time, do not use the
`nocompile' directive.

Here is another example of advanced GCL use. In this case, you write a program
that returns the name of the directory containing your images, depending on the
season. This will allow you to automatically adjust the imagery depending on
the time of the year. Let's call that program seasgra (for seasonal graphics).

Here is the magic script:

	#!/usr/local/bin/gracula
	nocompile
	#/ `/usr/localbin/seasgra` gd
	count = `/usr/local/bin/simple.gcl -lot -1`

A four-line script that displays a counter of a different design depending on
the season. How is that for power and flexibility? Heck, you can probably come
up with ideas of your own! If you do, please share them with everyone on the
gracula mailing list.

Anyway, back to the count variable and its options.

	count++

This will increase current value of count by 1.

	count--

This will decrease current value of count by 1. You can also use it to test
what the biggest possible count is.Just do the following:

	count = 0
	count--

This will assign 0 to the count, then decrease it by 1. But because count is
an unsigned integer, it will have the same effect as assigning the highest
possible value to it (if you do not know how binary numbers are represented
insode computers, just take my word for it please).

Then run it with the -lt switch. For example, if your script is named
script.gcl, type:

	% gracula script.gcl -lt

It will print the highest possible value of the counter. This depends on your
system and on the compile-time options you used. (See below about the advanced
use of count.)

	count += 1000
	count += ${OFFSET}
	count += `program -options`

This will increase the count by 1000 (or by the value of the environment
variable OFFSET, or the output of program).

	count -= 1000
	count -= ${OFFSET}
	count -= `program -options`

This will decrease the count by the value specified.

Remember, if you want to change the count of an active counter, append the
appropriate command from the Unix command line, do not edit the file:

	% echo "count += 10000" >> counter.gcl

Incidentally, you can use $(OFFSET) instead of ${OFFSET}. And as long as
the name of the environment variable consists of characters only, you can
skip the brackets altogether (i.e., you can use just $OFFSET).

* Advanced use of count
  ---------------------

Starting with version 2.40, count is treated as a true variable. That means
you can use it wherever an integer value is expected. You can even assign it
to itself:

	count = count

I am not sure why you would want to do that, but it is legal GCL.

You can also assign a negative value to it, e.g.:

	count = -1

You could do it indirectly before anyway (count = 0 count -= 1), so why not
allow it.

Further, you can use the new `signed' keyword to tell gracula you want to
display the count as a signed value. And you can use the `unsigned' keyword
to tell it to treat everything as unsigned values (that is the default).

More on that when we talk about registers.

* The `print' keyword
  -------------------

Used instead of the count keyword, it allows you to display an arbitrary value.
It accepts a string as its parameter. The string should contain digits 0 - 9,
and any of the GCL characters for dash (-), comma (,), space (~), dot (;),
colon (%), minus (<), plus (>), time (^), and zone (@).

Additionally, it will accept their "real-life" counterparts (:+TZ .) and convert
them internally to its own representation. It will ignore anything else.

And, of course, it will accept an environment variable or output of a program.

Examples:

	nocompile
	print "1950-04-23^00%30>01"

This will display the day, time, and time zone of my birth.

Note that it will not group digits nor separate groups by commas. However,
if you follow the string by an exclamation point, it will assume the string
contains a textual representation of an integer (decimal, octal, or hexadecimal)
and then it will use commas for separation.

Example:

	nocompile
	print `/usr/local/bin/sec2000` !

This will behave exactly like the example in the COUNTDOWN TO 2000 section.
However, it cannot be followed by something like count -= 3600. This is because
the `print' and the `count' keywords cancel each other out! The `print' keyword
does not set the value of `count', it defines a string to be printed.

The `print' keyword first appeared in v2.30 of GCL/gracula.

* Text strings
  ------------

A text string is enclosed in double quotes ("). Any character may be escaped
by a backslash - this allows you to have a double quote inside the string.
Only the double quote and backslash itself need to be escaped. There are no
special escaped characters. So "\n" is the same as "n" - it does not denote
a newline (as it does in C).

The string must end on the same line it was started on. However, if your editor
does not allow you to do that, you can use a backslash as the last character
on the line, then continue on a different line. For example, these two strings
are identical:

"/usr/local/share/gracula/pix/dir"

"/us\
r/lo\

cal/\

sha\
re\

/\

gracula/\
pi\

x/dir"

Same rules apply to shell calls enclosed in backticks, e.g.

`/u\

sr/local\

/\
\

bin/\

sec\

2000\

`

is the same as `/usr/local/bin/sec2000`.

It is NOT true of GCL keywords, integers, and directives! However, operators
may be split (without a backslash), e.g.

	count
	 -
	 =
	1000

is the same as count -= 1000, or, for that matter, count-=1000. Similarly,

	count
	-
	-

is the same as count-- or count --.

This is not to suggest you should code like that! It is simply to inform you
how GCL and gracula process text strings.

* The `now' function
  ------------------

This function returns the number of seconds since the epoch. It is the same
as the `time()' function of C.

* The registers
  -------------

Starting with version 2.40, GCL contains four registers named a, b, c, and d.
Unlike everything else in GCL, the register names are NOT case sensitive, so
you can also refer to them as A, B, C, and D. Indeed, as of version 3.0, GCL is
no longer case sensitive, so you can freely mix upper and lower case.

Registers can be assigned values (their starting value is 0). They can be
used anywhere an integer is expected. And they can perform the four arithmetic
operations of addition, subtraction, multiplication, and division.

Suppose you want to display a random count using random colors. You need to
use an array image with black digits, so you can use the `colorize' keyword.

Define environment variables RNDMUL and RNDADD to produce random numbers (of
course, you can just hardcode their values in the script). Then do something
like this:

01:	unsigned
02:	nocompile
03:	a  = now
04:	a *= ${RNDMUL}
05:	a += ${RNDADD}
06:	b  = a
07:	b *= ${RNDMUL}
08:	b += ${RNDADD}
09:	c  = b
10:	c *= ${RNDMUL}
11:	c += ${RNDADD}
12:	d  = c
13:	d *= ${RNDMUL}
14:	d += ${RNDADD}
15:
16:	colorize a b c
17:	count = d

Do not use the line numbers, of course. They are here only so I can analyze
the code for you. Nor are the real line numbers, since you will want to
define your images first (or last).

So, what does it do? Line 01 tells gracula to treat everything as unsigned
values. This is the default, but you could have used `signed' somewhere
else in the code.

Line 02 prevents gracula from compiling your code, as that would remove it
all and only keep the final values. The result would no longer be random.

Line 03 uses the `now' function as the seed for the random number generator.
Lines 04 and 05 turn the seed into a random number. Lines 06, 09, and 12, seed
the rest of the registers. The rest of the lines, up to 14 calculate additional
random numbers and store them in the registers.

Line 15 is there for increased readability. Line 16 changes black pixels in
the array image to some random color. Line 17 sets the count to yet another
random value.

Go ahead, play with it. Just don't forget to set the environment variables.

Note that you can use the `signed' and `unsigned' keywords repeatedly to
influence your arithmetics. Example:

	a = -15
	b = -2
	c = a
	signed
	c /= b
	unsigned
	a /= b

Can you figure out the final values of A and C?

Because the c /= b statement divides two signed integers, C will be 7. But
because the integers are treated as unsigned in the final division, A = 0.
That is because -2 is represented by a larger unsigned binary number than
-15...

What if you divide by 0? GCL will simply ignore it. So, the result would be
the same as if you divided by 1 (not because that is mathematically correct
but because no division actually takes place).

* Assignment operators
  ------------------

The following operators are available to assign values to registers and the
count variables:

	=    assignment. E.g. A = count will assign the value of `count'
	     to register A.

	+=   addition. A += B will add the value of register B to register A.

	-=   subtraction. A -= 2 will subtract 2 from register A.

	&=   binary AND. A &= B will assign the result of binary AND operation
	     of the values of registers A and B.

	|=   binary OR. A |= pop will pop off a value from the stack and store
	     the result of the binary OR of the value of register A and the
	     popped value in A.

	^=   binary XOR. A ^= C will store the result of the binary XOR
	     operation of the bits of A and C in A.

	++   increment. A++ will increase the value of A by 1.

	--   decrement. A-- will decrease the value of A by 1.

Except for `++' and `--' all assignement operators have a left hand side (LHS)
and right hand side (RHS). The `++' and `--' assignment operators have only
LHS.

A register or a variable are the only acceptable LHS. Any numeric expression
may go on the RHS. For example:

	count += a * 3 + random % c + b == d ^^ pop - now

Here `count' is LHS, `+=' is an assignment operator. The rest of the assignment
is is the RHS.

As with all GCL operators, white space is ignored, so you can write:

	count
	+
	+

Or, you can write the above example as:

	count+=a*3+random%c+b==d^^pop-now

Note that the increment and decrement operations are true assignments in GCL.
Therefore, they must FOLLOW the register or variable they modify. In other
words, a-- is an assignment (i.e., it is functional equivalent of a = a - 1),
while --a is a numeric expression. That is, b = --a is the same as b = a. You
can think of it as b = - (-a) to see why.

* More on `signed'
  ----------------

Note that addition, subtraction, and multiplication, result in the same
value whether it is signed or unsigned. But division does not. That has
nothing to do with GCL, by the way: That is the way most computers work.

Whether the result displayed by gracula is signed or unsigned depends on the
FINAL `signed' or `unsigned' keyword used in your script. It does not matter
whether it appears before or after you assign the final value to `count'.

However, when assigning a value from registers, environment, program ouputs,
or the `count' variable to anything that expects an unsigned value (such
as `colorize'), the curent state of `signed' or `unsigned' is considered
at the time of assignment. If the current state is `signed' and the value
represents a negative value, its absolute value is assigned. If the current
state is `unsigned', the value is assigned as is.

That means that our random example would yield different color if line 01
said `signed'. They would still be equally random, though.

COUNTDOWN TO 2000
=================

The enclosed program sec2000 does nothing but print the number of seconds,
minutes, hours, or days till the year 2000. You can use it within a GCL
script like this:

	nocompile
	count = `/usr/local/bin/sec2000`
	signed

You can then adjust it from UTC to your time zone by adding something like

	count -= 3600

For more options, please read the file sec2000.c.

* The GCL version
  ---------------

In version 2.40, you no longer need an external program for the countdown to
the Year 2000. You can write it in plain GCL, just like this:

	count  = 946684800
	count -= now
	signed
	nocompile

As simple as that! And if you want to adjust it to some other time zone, you
can still use count -= 3600 (or whatever value), or you can simply adjust
the 946684800 as necessary. That number, by the way, is what the value of
`now' will be on January 1, 2000, at 00:00 UTC. At least on my Unix system.

In version 3.0, you can further simplify it by using numeric expressions:

	count = 946684800 - now
	signed
	nocompile

INCLUDING FILES
===============

As of version 2.40, you can include other files in your script. Use the `#?'
directive.

Suppose you want to use Dominique Voillemot's clock.gcl to display the countdown
to the Year 2000, you can do:

	#? "/usr/local/bin/clock.gcl"
	nocompile
	signed
	count  = 946684800
	count -= now

This is also useful when you want to use the same design in several counters:

	#!/usr/local/bin/gracula
	#? "/usr/local/bin/clock.gcl"
	nocompile none	## i.e., compile
	count = 1	## or whatever starting value you want

This will compile everything, including the contents of clock.gcl into your
script. Once it is compiled, the `#?' directive will have disappeared, so
there is no performance hit on your counter.

CONTROLLING INCREMENTS
======================

Unless inhibited by the `-i' command line switch or by the use of inhibitors,
whenever a GCL file is compiled, the value of `count' is incremented by 1.
This is the default behavior, but can be changed by several methods.

* The `increment' keyword
  -----------------------

This keyword controls the value by which `count' is incremented. In its simplest
form, the keyword is simply followed by an integer:

	increment -1

This will "increment" the count by -1, i.e., it will actually decrement it by 1.

You can also define a range of incrementation:

	increment [5, 11]

In this case, the count will be incremented by a random number between 5 and 11.

	increment [-10, 10]

This will create an "oscillating" counter as the count will be increased by a
random value between -10 and 10. That means that in the long run, the count
will oscillate around some constant value, but in the short run it will move
up and down.

* The `fudge' keyword
  -------------------

This keyword allows you to fudge the counter by some factor. For example,

	fudge 5

will create the fudge factor of 5. The count will be increased by a random
value between 1 and fudge factor * 2 - 1. So, in the case listed above, it
will be increased by a random value between 1 and 9. That gives you an AVERAGE
increase of 5. You will know, over the long run, that the actual number of hits
was 5 times less than shown. This will allow you to fudge the visible count
without it being obvious.

The maximum fudge factor is 1023. If you use a higher number, GCL will truncate
it by masking out the extra bits.

If you really need a higher fudge factor, use:

	increment [1, nnnn]

where nnnn is your fudge factor * 2 - 1. The fudge keyword is just a shortcut
for that notation anyway.

* The `sigma' keyword
  -------------------

This keyword allows you to SIMULATE real life statistics. Statistical analysis
often comes up with a mean and a sigma. For example, statistical analysis of
people killed by drunk drivers in an average minute could come up with the
mean of 1000 and a sigma of 17 (these are not actual number from those
statistics, just a made-up example). To put it simply (and to simplify the
science of statistics), in any given minute the number of people killed by
drunk drivers would be 1000 +/- 17, or anywhere between 983 and 1017. As I
said, this is a simplification. In reality, in any given minute the actual
number can be outside of that range, but in most minutes it will be somewhere
within that range.

Now, you could create a web site against drunk driving in which you would
create a simulation of how many people were killed in the last minute. You
would use the sigma keyword, like this:

	sigma 17 1000

In other words, the `sigma' keyword is followed first by the sigma, then by
the mean.

If you use the `sigma' keyword, the `count' variable will be ignored (indeed,
the GCL compiler will set it to mean).

The three keywords described in this section are mutually exclusive. That is,
if you follow a `sigma' by a `fudge', `sigma' will be discarded, and `fudge'
will be used. Or, if you follow `increment' by `sigma', `increment' will be
discarded, and `sigma' will be used.

RANDOM NUMBERS
==============

The `random' function of GCL can be used anywhere an integer is expected.
So, you can rewrite the script for the display of a random number in
random colors shown above like this:

	#!/usr/local/bin/gracula
	#? "/usr/local/bin/black.gcl"
	colorize random random random
	count = random
	nocompile

Not only is this simpler, but the random number generator used by gracula is
better than the one in the example script. Or so I think. :-)

Note that `random' will always produce a positive random number. So, if you
compiled gracula to use 64 bits, the random number will have 63 significant
bits.

However, there also is the `srandom' function which will produce a random number
that may be positive or negative. Again, if you compiled gracula to use 64 bits,
the srandom function will return a 64-bit random number.

GROUPING DIGITS
===============

By default, the GCL interpreter separates digits into groups of three and
displays a comma between them.

This behavior can be modified with the `group' keyword:

	group 4

This tells the interpreter to use groups of 4 rather than 3.

	group dots

This tells it to use dots instead of commas.

	group spaces

Here, GCL will uses spaces as a separator instead of commas.

	group 3 commas

This is the default behavior. Note that the `-o' command line switch tells
gracula to omit grouping altogether. You can also effectively turn off grouping
by using a large value with the `group' keyword:

	group 1000

This effectively turns off grouping since the maximum number of digits gracula
will display is 127. However, the `-o' switch is more effective and flexible.

Note that in the future the default behavior will probably change to the use
of spaces as the default separator to conform with international standards.
To make the transition painless, the compiler of the version 2.40 will write
`group commas' to the compiled GCL scripts even if it is the default.

THE GCL STACK
=============

In some cases four registers may not be enough. GCL also contains a stack
which is 16 levels deep. You can push values on it, pop them, and you can
read the current value on the top of the stack without popping it.

Note that the contents of the stack are undefined until you push something
on them. They are also undefined after you pop everything you pushed.

If you push more than 16 values on the stack without popping them, the values
on the bottom of the stack will be lost.

* The `push' keyword
  ------------------

You can push a value on the stack by using the `push' keyword followed by
the value.

Examples:

	push -5		- this pushes -5 on the top of the stack
	push !8		- this pushes 0 (logical not 8) on the tos
	push ~count	- pushes count with its bits reversed on tos
	push ${VALUE}	- pushes the integer value in the environment
			  variable VALUE on the top of the stack
	push tos	- pushes the value of the top of the stack on
			  the top of the stack
	push pop	- pops the top of the stack and pushes it right
			  back. Quite useless, but possible

* The `pop' function
  ------------------

This function removes the value from the top of the stack and returns its
value.

Example:

	push 1
	push 2
	push 3
	colorize pop pop pop

This is the same as `colorize 3 2 1' (remember, the values are popped in the
opposite order as they are pushed).

* The `tos' function
  ------------------

This function returns the value of the top of the stack without popping it.

Example:

	push random
	colorize tos tos pop

This will change the black pixels in the array image to a random shade of gray.
But can you see something wrong with it? While it is valid GCL, it may produce
a color identical to the background.

That is easily fixed. Suppose you show this counter on a white background. You
may limit the range of available shades of gray:

	push random & 127
	colorize tos tos pop

Or:

	push random % 128
	colorize tos tos pop

NUMERIC EXPRESSIONS
===================

The addition of numeric expressions was one of the two reasons to bump up the
major version from 2 to 3 (control statements was the other).

A numeric expression can be a variable (count), a function (tos, pop, now,
random, srandom, signed, unsigned), a register (A - D), a constant, or a value
read from an environment variable or the output of a program.

Note about `signed' and `unsigned': You have already learned about these
keywords as directives to tell the GCL interpreter whether to treat numbers
as signed or unsigned. In numeric expressions, however, they are used as
functions which return 0 or 1 depending on the current state defined by the
signed and unsigned directives.

Additionally, a numeric expression can be a numeric expression followed by
an arithmetic or logical operator followed by a numeric expression.

Also, a numeric expression can be a numeric expression followed by the `?'
operator, followed by a numeric expression, optionally followed by ':' and
another numeric expression.

Finally, a numeric expression can be a unary operator followed by a numeric
expression.

The last three paragraphs should be read recursively (e.g. -+-+a is the unary
operator `-' followed by the unary operator `+' followed by the unary
operator `-' followed by the unary operator `+' followed by the register A).

Any numeric expression may be surrounded by parentheses. These are used to
modify the operator precedence. A numeric expression surrounded by parentheses
is evaluated before any operator outside the parentheses is applied. E.g.,
5 - 7 + 2 yields 0, while 5 - (7 + 2) yields -4.

Examples of numeric expressions are:

	random
	tos * a
	`sec2000` / (60 * 60 * 24)
	a ^^ b || !c ? now : 0
	(a ^^ b || !c) * now

Note that the last two examples yield the same result.

* Operators
  ---------

The following operators exist in GCL, in increasing order of precedence:

	? ?:
	||
	^^
	&&
	|
	^
	&
	== !=
	< <= > >= <>
	<< >>
	+ -
	* / %
	! ~ + - <> \ (unary)

C programmers will recognize most of GCL operators. The rest of them I had to
make up.

The very first one, `?', is a result of GCL philosophy of graceful recovery.
Because GCL is often used as a CGI program, it never aborts the interpretation
of a script. Whenever it encounters a syntax error, it tries to recover from it
gracefully. It does that by assuming that when it sees something that does not
belong there, that something is the first keyword of the next statement.

Originally, I was adding the C ?: operator exactly as in C. For example:

	count = a > 0 ? 1000 : 2000

That is an equivalent of:

	if a > 0 count = 1000 else count = 2000

I had to decide how to recover from a syntax error in which you forget to type
the `: 2000' part of it. Once I came to a decision, it made sense not to
consider this construct a syntax error at all, but valid GCL. After all, if GCL
accepts it in a predefined way, it is not an error, it is part of the language.

As a result the `?' operator was born. It returns the expression on the left of
it if that expression is not 0, otherwise the expression on the right.

For example:

	a = b ? c

is the equivalent of:

	if b a = b else a = c

Another operator not found in C is `^^'. This is the logical XOR operator:

	a ^^ b

This returns 1 if either a or b is 0 and the other in not zero. If they are both
0 or neither is 0, it returns 0. For all practical purposes it is the shortcut
version of:

	a && !b || !a && b

The `<>' operator compares the value on its left to the value on its right, and
returns -1, 0, or 1 depending on the result of the comparison:

	a <> b

This is a shortcut way of the following:

	a < b ? -1 : a > b ? 1 : 0

There also is a unary operator `<>' which returns -1 if the value to its right
is negative, 1 if it is positive, 0 if it is 0. So what will this return:

	<>-3

Either 1 or -1. How so? Remember, by default all numeric values are considered
unsigned in GCL unless you override it with the signed statement. So, if the
current state is unsiged, <>-3 will return 1, otherwise it will return -1.

The unary `\' operator returns the absolute value of the expression on its
right. What that means, again, depends on the signed or unsigned state. So,
\-3 can return -3 (which is actually a very big unsigned number) or 3.

Please note that not all operators return a different result depending on the
current state of signed.

The `>', `<', `>=', '<=', '<>', `/', `%', and `\' depend on the current state
of signed. The rest of them (including `-') do not.

Incidentally, `a / 0' and `a % 0' are mathematically undefined. GCL ignores
them: Both operations will return `a'.

Most operators are evaluated from left to right. `3 - 2 + 7' yields 8, not -6,
because it is the same as (3 - 2) + 7, not 3 - (2 + 7).

Similarly, `6 / 3 * 4' will return 8, not 0, because it is the same as (6 / 3)
* 4, not 6 / (3 * 4).

The comparison and shift operators are evaluated from right to left. Thus,
`1 << 1 << 2' equals 16, not 8, because it is the same as 1 << (1 << 2) ,
not (1 << 1) << 2.

Note: If you want, you may use `=' for comparison (instead of '=='). You may
also use ':=' for assignment (e.g. count := 1000). This is to accomodate
Pascal programmers.

FLOW CONTROL
============

GCL is designed with maximum speed in mind. It is often used on the web to
display access counters. On a busy web site it has to be able to handle many
counter request in rapid succession.

For that reason, GCL is designed in such a way that it can be processed in
one pass. That means, a GCL file is processed statement after statement, moving
forward, never looking back. GCL contains no loops, such as `for', `while',
`until', or whatever they are called in various languages.

It does, however, contain several conditional statements that do not require
looking back.

* The `if-then-else'  statement
  -----------------------------

The `then' keyword is optional. Pascal programmers are used to it, C programmers
are not. Take your pick. The basic syntax is:

	IF expression THEN statement ELSE statement
	IF expression statement ELSE statement
	IF expression THEN statement
	IF expression statement

Expressions were explained above. If an expression unequals 0, the statement
is executed. Otherwise, it is not. Or, in the case of the if-else constructs,
if expression unequals 0, the first statement is executed, otherwise the
second one.

Note that you may place a comma after the expression and after the else if you
feel the urge. For that matter, you can place a comma anywhere. Or a semicolon.
Or a period.

Example:

	If a = 15, then count = 30. Else, count = 55.

This is the officially recommended style for GCL programs.

Under GCL, everything that is not an expression is a statement. That includes
assignments, directives, even the #! construct which is there only for the
command shell. It is important to know what constitutes an individual statement.
For example, `signed count = pop' are TWO statements, not one. The first one
is `signed', the second `count = pop'. So if you write something like:

	if a == 15 signed count = pop
	else unsigned count = random

You will get a syntax error, and you will always get un unsigned random count.
This is what will really happen:

	if a == 15 signed	## change state to signed if a == 15
	count = pop		## always happens
	else			## SYNTAX ERROR - reported and forgotten
	unsigned		## always happens
	count = random		## always happens

Note that you MAY terminate any statement with a semicolon, comma, or a period.
You certainly do not have to, but it is the officially recommended GCL style.
In the above case the error would be immediately evident had you written it this
way:

	If a == 15, signed, count = pop.
	Else, unsigned, count = random.

Can you achieve what you really want here? Certainly. GCL allows you to use
compound statements. A compound statement is a series of statements surrounded
by squiggles. This is just like C. Or, surrounded by `begin' and `end'. This
is just like Pascal.

So, our above example can be properly rewritten as:

	if (a == 15) {
		signed;
		count = pop;
	}
	else {
		unsigned;
		count = random;
	}

The parentheses around the `a == 15' expression are not required but C
programmers are used to them.

Or, you could rewrite it the Pascal way:

	IF A = 15 THEN
	BEGIN
		Signed;
		Count := Pop
	END
	ELSE
	BEGIN
		Unsigned;
		Count := Random
	END.

Or in several other ways... The recommended style is:

	If a = 15, { signed, count = pop }.
	Else, { unsigned, count = random }.

Except for the squiggles, it looks almost like regular human language.

As an exercise, can you figure out what this one does:

	if signed unsigned else signed

And how does it differ from:

	signed ? unsigned : signed

Hint: it does differ. One is a statement, the other an expression.

* The `tri' statement
  -------------------

The if-else construct only offers a choice between two options. It is often
necessary to choose from three options. If you check the C source code for
gracula, especially the macros defined in gcl.h, you will see how often that
is the case in this program alone.

The `tri' statement follows this syntax:

	tri expression
	statement
	statement
	statement

This is identical to the following:

	a = expression
	if a < 0 statement
	else if a == 0 statement
	else statement

Of course, the tri statement is simpler, and does not waste a register.
As an example, let us assume we have three GCL scripts which use completely
different graphics. The scripts are called counter1.gcl, counter2.gcl, and
counter3.gcl. They are located in /usr/local/bin.

Further, we have a counter we want to use to get the count from, and save
the next value of count in. It is called main.gcl, and resides in the same
directory. We would like to randomly choose one of the three scripts for the
graphical appearance of a counter. Here is a script to accomplish just that:

	#!/usr/local/bin/gracula
	tri random % 3 - 1
	#? "/usr/local/bin/counter1.gcl" ;
	#? "/usr/local/bin/counter2.gcl" ;
	#? "/usr/local/bin/counter3.gcl" .
	nocompile
	count = `/usr/local/bin/main.gcl -lot -1`

Here, `tri' is followed by the expression `random % 3 - 1'. This produces a
random number between -1 and 1. The fact we have not used `signed' is
irrelevant: The tri condition is always treated as a signed value.

The condition is followed by three include statements. Gracula will only
include one of them, depending on the value of the randomly calculated
condition. Regardless of what any of the include files say about the
value of `count' (or even if they use the `print' statement), it will be
overriden by the value returned from main.gcl. Please note that the `-lot'
option is very important. The `-l' tells main.gcl not to send out the
http header (which would evaluate to 0). The `-o' switch tells it not to
insert commas (or spaces, dots...) in the result (which would make us
read only the value up to the first comma). The `-t' switch will force
it to give us text, not GIF.

What about the `-1'? It will override any GCL command that may be telling
main.gcl to show at least a certain number of digits. Without it, main.gcl
might send us the count with some leading zeros and gracula would think it
was an octal number rather than decimal.

The semicolons and the period after the statements are optional. I put them
there to indicate to you where each statement ends.

How about a counter that displays positive values in blue, negative ones in
red, and zero in black? Create a script which uses an array image of black
digits, use some other script (like main.gcl above) to give you the count,
then end your script with:

	tri <>count
	colorize 255 0 0
	colorize 0 0 0
	colorize 0 0 255

Don't forget to use `nocompile' somewhere in the script!

* The array statement
  -------------------

Sometimes we need to make choices from any number of options. The array
statement gives us a condition and an array of options. C programmers will
immediately think of the C switch statement. It is similar but much more
powerful. Here is its basic syntax:

	[ expression
		expression statement
		expression statement
		...
		expression statement
		default statement
	]

There can be any number of `expression statement' and `default statement'
occurances. They are evaluated and executed, or not, in the order you list
them.

The first expression is evaluated. Each of the other expressions is compared
to the first expression. If they are equal, the statement is executed. If not,
it is not executed.

What about default? Think of it as "none of the above". If none of the
expressions evaluated before the default statement was equal to the first
expression, the default statement is executed.

The fact that another default statement may have been executed will not stop
another default statement. Otherwise, it would make no sense to allow for more
than one default statement.

More than one expression may equal to the first expression. All of their
corresponding statements will be executed.

Any of these expressions can be constants, variables, functions, arithmetic
expressions, whatever... But here is just a simple example which does the same
as the one listed in the paragraph on the `tri' statement:

	#!/usr/local/bin/gracula
	nocompile
	[ random % 3
		0 #? "/usr/local/bin/counter1.gcl"
		1 #? "/usr/local/bin/counter2.gcl"
		default #? "/usr/local/bin/counter2.gcl"
	]
	count = `/usr/local/bin/main.gcl -lot -1`

I think this one is fairly self-explanatory.

INHIBITORS AND RELAYS
=====================

Inhibitors have been in GCL since the beginning but I do not believe I talked
much about them. That's actually good because I discovered a weird bug in them
while working on relays. Relays are new to v3.0 (although I had them in mind
much earlier).

Both inhibitors and relays are conditional statements. But do not confuse them
with flow control we talked about before. They do not control the flow of
your program, but rather what your program will or will not do. Their most
obvious use is for web security. And yes, they really only make sense when
used on the web (as I discuss below, GCL has perfectly good uses off the
web, too).

Because both inhibitors and relays use the same type of conditions, let me
talk about those first.

* Conditions
  ----------

I repeat, conditions have nothing to use with flow control (if-else, and such).
Flow control uses EXPRESSIONS, not conditions. You cannot use an expression for
a condition. Nor can you replace a condition with an expression.

Also, expressions are used before the statement they modify. Conditions are part
of the statement itself. Indeed, they are always at the END of the statement.

A condition always starts with either `when' or `unless'. This is followed by
one of three possibilities:

	from string
	cookie string = string
	string = string

By string I mean a quoted string, i.e., some text enclosed in double quotes.

The string following `from' should be a valid email address, such as
"me@mydomain.com".

The `from "me@mydomain.com"' condition is true if the caller's browser tells
your web server that the caller's email address is me@mydomain.com. Otherwise,
the condition is false. Indeed, it may be false even if that IS the caller's
email address, but his browser does not tell your server about it. This is
often the case, no thanks to spammers. So, the from condition is generally
unreliable.

The `cookie' condition is useful if your web server sends http cookies to
users. Cookies come in the form of "a=b;c=d;e=f". In this case,

	cookie "c" = "d"

will make the condition true.

	cookie "a" = "b"

will also make the condition true.

	cookie "b" = "a"

will make the condition FALSE. That is because in cookies "a=b" is not the
same as "b=a".

Finally, the `string = string' condition is the most generic one. The string on
the left is the name of an environment variable. The one on the right is its
value (or contents). CGI programs receive such environment variables from the
server, and you can test them.

For example:

	"HTTP_REFERER" = "http://www.mydomain.com/mypage.html"

This condition is true if your counter is being called by mypage.html on the
www.mydomain.com web site. Otherwise it is false.

Now, remember, these are not the full conditions. They are preceded by either
`when' or `unless'. The full condition is true if `when' is followed by
something true, or if `unless' is followed by something false. Otherwise,
the full condition is false.

* Inhibitors
  ----------

An inhibitor will either inhibit the counter or not. That depends on which
inhibitor you are using, and on its condition.

When a counter is inhibited, its future value is not changed. Normally, it is
increased by one (unless you use one of the variety of increment keywords
discussed earlier). That is how the next caller gets a count one higher than
current caller.

Why would you want to inhibit the counter? There are two main reasons I can
think of, although you may come up with others.

The first one is that you may not want to increase the counter when YOU access
your web page. That way you know how many people other than you visited your
web site.

The other one is to prevent theft of services, or just plain malicious
cracking. Suppose someone does not like you, and adds the URL of your counter
to a highly visited web page of his. Without the use of inhibitors, your
counter will increase its value every time someone visits HIS page, in
addition to yours. You will get the false sense of having more visitors than
you really do. You will be upset when you compare the reported number of hits
with your logs. And, gods forbid, you will think GCL is not working right!

There are two possible inhibitors: `inhibit' and `concede'. The first one
will inhibit the counter, the second will turn any inhibition off. Both
will do that only if the condition is true.

Here is how I inhibit my counters whenever I call my web site. Although I
do not use cookies with my web site, I wrote a CGI page once just to send
myself a cookie. For the sake of argument, let's assume the cookie is:

	"caller=adam"

It is actually something else, but this will do for illustration. Now, all
I had to do is append to all my counters the following line:

	inhibit when cookie "caller" = "adam"

That way, when I call my web site, my counter tells me exactly how many
visitors I had on each page, but it does not count me. I could have used
the `from' condition, but I would have had to let my browser reveal my email
address to every web site I call, and I do not want to do that. Again,
no thank you, spammers!

And how do you prevent someone else from increasing your counter maliciously?
The easiest way is by the use of the HTTP_REFERER (note, just one `R' between
the two E's). If you are not exactly sure what its value is, use the GCL
feature of expanding environment variables to strings like this:

	inhibit unless "HTTP_REFERER" = ${HTTP_REFERER}

Then call your web page. Gracula will expand it, and write the expanded version
to your script when it compiles it for the first time.

After that, take a look at your script. It will contain something like this:

	inhibit unless "HTTP_REFERER" = "http://www.mysite.com/mypage.html"

Or whatever is right for your system.

You may use as many inhibitors in your counter as you want. They are evaluated
in the order you enter them. This is important! Make sure an inhibitor does
not cancel one you do not want cancelled. Suppose you do something like this:

	inhibit unless "HTTP_REFERER" = "http://mysite.com/mypage.com"
	inhibit unless "HTTP_REFERER" = "http://www.mysite.com/mypage.com"

You may want that because both address the same page. But it will not work!
That is because the second statement overrides the first. The proper way to do
it is:

	inhibit unless "HTTP_REFERER" = "http://mysite.com/mypage.html"
	concede when "HTPP_REFERER" = "http://www.mysite.com/mypage.html"

Can you see the difference? The second statement makes an exception to the
first one instead of overriding it.

What if you want to change an active counter's inhibitions? Remember, you
can use as many inhibitors as you want, so just appending new ones will not
work. And as discussed elsewhere, you never want to edit an active counter
because you will lose count of whoever calls your web site while you are
editing. So to change your inhibitors to the above, first create a text file,
like this:

	inhibit none ## this wipes out all existing inhibitors
	inhibit unless "HTTP_REFERER" = "http://mysite.com/mypage.html"
	concede when "HTTP_REFERER" = "http://www.mysite.com/mypage.html"

Assuming the text file is named `changes' and your counter `mycounter.gcl',
just type the following your counter's directory:

	cat changes >> mycounter.gcl

Don't forget to use the DOUBLE `>>' or else you will overwrite the counter
instead of appending to it.

And, by the way, using `concede none' would work as well.

* Relays
  ------

Relays will redirect the caller to a different URL based on the condition.
This will prevent someone else from displaying your counter on his web site.
Or, it will allow it.

They come in two forms:

	relay string condition
	serve condition

The condition is the same as in inhibitors. The string, in this case, is the
URL to wherever you want to relay the caller. It can be a graphic, or another
counter. The graphic can say something nasty, or something polite, that's
your choice. No string comes after `serve' because that is telling GCL not to
relay the caller somewhere else.

Example:

	relay "http://go.hell.to/nasty.gif" unless "HTTP_REFERER" = "..."
	serve from "me@mydomain.com"

The "...", of course, needs to be your web page URL. I just did not have
enough room on the line to spell it out (of course, it does not have to
all go on one line).

This sends every one trying to access your counter from some cracker's site
to go.hell.to/nasty.gif. Everyone, that is, except you (assuming your
browser is set up to reveal your address).

Please note that you should not relay someone to a graphic on someone else's
web site unless you have their permission. Otherwise, you will be doing to
others what you do not want others to do to you. The best thing, in my humble
opinion, is to send them a banner advertising your site. While callers will not
be able to click through to your site, of course, they will at least learn
about its existence. Heck, it does not have to be just a banner, it can be
a full-page ad. :-)

Suppose you want to set up a mini-server for others to use counters, but
you want them all to access it using the same URL. You want to redirect
your customers to their counters, but display some graphic in any other
case. Remember (from the FAQ) the `redirect' keyword:

	redirect "http://www.mydomain.com/mybanner.gif"
	relay "http://www.mydomain.com/counter1.gcl" when
		"HTTP_REFERER" = "http://www.mycustomer1.com/home.html"
	relay "http://www.mydomain.com/counter2.gcl" when
		"HTTP_REFERER" = "http://www.mycustomer2.com/home.html"
	[etc...]

This is not the most efficient way of doing it. Letting the customers use
the URL of their counter is more efficient. But it serves as illustration.

Similar to what we discussed in the paragraph on inhibitors, you can use
`relay none' (or `serve none') when you want to start from scratch.

One final note: Relays do not inhibit the counter. If you want a counter
relayed and inhibited, use both relays and inhibitors in your script. That
may sound like extra work, but it offers you maximum flexibility.

* The "starts with" operator
  --------------------------

Sometimes you may want to inhibit (or concede, relay, serve) an entire domain.
Simply replace the `=' with `:='. This is the "starts with" operator.

Example:

	inhibit unless "HTTP_REFERER" := "http://www.mydomain.com/"

This will inhibit the counter unless the value of the environment variable
HTTP_REFERER starts with "http://www.mydomain.com/".

Hint:

Use the trailing slash. If you only used "http://www.mydomain.com", without
the slash, a malicious cracker could duplicate it. If his domain is cracker.com,
he can easily set up an "http://www.mydomain.com.cracker.com" and that will
match the requirement of the string starting with "http://www.mydomain.com".
But it will NOT match "http://www.mydomain.com/".

There is no "ends with" operator because that would be completely unsafe.

As usual, if you want allow the increase of the counter with or without
the "www" in your domain, use two statements:

	inhibit unless "HTTP_REFERER" := "http://www.mydomain.com/"
	concede when "HTTP_REFERER" := "http://mydomain.com/"

And so on for any other domains. Of course, you do not need to stop with
domains:

	inhibit unless "HTTP_REFERER" := "http://www.mydomain.com/mydirectory/"
	inhibit unless "HTTP_REFERER" := "http://www.myisp.com/~myaccount/"

All of these are perfectly valid GCL.

THE PERSIAN FLAW
================

Do you know what Persian flaw is? Perhaps everyone knows that Persians have made
the most beautiful carpets ever produced on this planet. Yet, every single one
of them has some small flaw in it.

Is it because Persian carpet makers could not get it quite right? No! They put
a flaw in every carpet they made on purpose. Their reason was that only God
could create something perfect. So if they made a perfect carpet, they would be
defying God, in a way.

I have been told repeatedly, several versions back, that GCL had achieved
everything a graphic counter language could. I knew that was not the case,
because I knew from day one all the things I wanted in it. Version 3.0 has
everything in that I originally planned. That is not to say I cannot come up
with further ideas, but they probably will be on a smaller scale.

But I assure you that GCL is not flawless. Indeed, it contains a Persian flaw.
A flaw that is there by my choice. It is very subtle. Some of you, having read
the Introductory Tutorial, the FAQ, and this README file may have discovered it.
But I bet most of you did not. :-) If you feel like it, stop reading and try to
figure it out. You can always come back (of course, it can hit you in the mean
time, so you'll be probably better off reading on).

Just to set the record straight, my motivation is completely different from the
Persians. As far as I am concerned, whoever or whatever designed the world we
live in also placed flaws into it on purpose. Not because he, she, they, or it,
could not make a perfect world but because it knew that a perfect world would be
perfectly boring. I have always held on to the belief that perfection is for
neurotics.

OK, now what the heck is that flaw? Consider a section of an actual script:

	# ... declare some images above
	invis 255 255 255
	trans
	align commas bottom
	count = 946684800
	count -= now
	signed
	nocompile

You will recognize it as the script for a countdown to the Year 2000. But it
does not work. It always displays a negative number. Even in 1999. Obviously,
is should show a negative number in 2000 and later, but not in 1999. Can you
figure out what is wrong with it? It is the victim of the Persian flaw in GCL
design.

If you still cannot see it, let's try rewriting it:

	# ... declare some images above
	invis 255 255 255
	trans
	align commas bottom
	count = 946684800 - now
	signed
	nocompile

But, oops, this script always shows the count of 0. Before or after the Year
2000. Except it shows 1 during the first second of the Year 2000. Can you see
it yet? If not, let's rewrite it again:

	# ... declare some images above
	invis 255 255 255
	trans
	align commas bottom count = 946684800 - now
	signed
	nocompile

Remember, `align commas bottom' is either followed by an expression, or it
just implies a 0. And it does not matter whether the expression is on the
same line or another. In this case, the programmer's intent was to assign
a value to the `count' variable. `count = 9446684800 - now' is a valid GCL
assignment. But it is also a valid expression! Consider this:

	if (count = 946684800 - now) then ...

Aha! Because count equals 0, it evaluates to 0 any time except the first
second of the Year 2000 when it evaluates to 1 because at that second now
is equal to 946684800.

It is quite easy to fix, by the way. Here are several solutions:

	# ... declare some images above
	invis 255 255 255
	trans
	{ align commas bottom }
	count = 946684800 - now
	signed
	nocompile


	# ... declare some images above
	invis 255 255 255
	trans
	align commas bottom
	{ count = 946684800 - now }
	signed
	nocompile


	# ... declare some images above
	invis 255 255 255
	trans
	align commas bottom
	{}
	count = 946684800 - now
	signed
	nocompile

How about this?

	# ... declare some images above
	invis 255 255 255
	trans
	align commas bottom
	signed
	count = 946684800 - now
	nocompile

Nope! `Signed', too can be both a statement and an expression! This will
work in 1999 and surprise you in 2000 by showing a very big positive number.

But, yes, changing the order of statements to make them unambiguous is one
of possible solutions. Like this, for example:

	# ... declare some images above
	invis 255 255 255
	trans
	align commas bottom
	nocompile
	count = 946684800 - now
	signed

However, the best solution is to use the recommended coding style which
separates all numeric expressions by a comma, and ends each statement
with a period. It also starts each comment with two octothorps:

	## ... declare some images above
	Invis 255, 255, 255.
	Trans.
	Align commas bottom.
	Nocompile.
	Count = 946684800 - now.
	Signed.

So, by now it should be clear what the Persian flaw of GCL is: It can be
ambiguous on occasion. Just like real human languages are.

NATURAL LANGUAGE PROCESSING
===========================

Talking of real human languages...

Some of the operators we have studied so far can also be replaced by keywords.
Instead of `&&' you can write `and'. Instead of `||' you can write `or'. Instead
of '=' you can write `equal' or `equals'. Instead of '>' you can write `greater'
or `larger'. Instead of `<' you can write `lesser' or `smaller'. Instead of `^^'
just use `xor'. Instead of '+' you can get away with `plus' or `positive'. And,
of course, instead of `-' you may use `minus' or `negative'. You can replace `%'
with `modulo' or `modulus'. Or `<>' with `sign'.

Oh, and, by the way, you can use `include' for `#?' if you want. And you may use
`otherwise' instead of `else'.

Big deal, you may be yawning. All right, here's something else: You can use ANY
word in any language anywhere in your script as long as it is not a GCL keyword.
And you can use commas, semicolons, periods, and apostrophes, anywhere you want,
except inside a numeric expression.

All right, let me give you an example:

	Computer,

	This is the Captain...

	Let's use signed numbers for this calculation.

	If some random number is greater than another random number...
	Oh, let's begin by setting the value of count equal to positive 17.
	Also, let's colorize this somewhat. Set the red factor to 255;
	the green one to 0. Also, leave the blue factor at 0. That should
	end the result of this condition.

	Otherwise, just make count equal negative 17.


What will GCL see here? This:

	signed
	if random > random {
		count = +17
		colorize 255 0 0
	}
	else
		count = -17

To make that clear, let me repeat it here with GCL keywords in capital letters:

	computer,

	this is the captain...

	let's use SIGNED numbers for this calculation.

	IF some RANDOM number is GREATER than another RANDOM number...
	oh, let's BEGIN by setting the value of COUNT EQUAL to POSITIVE 17.
	also, let's COLORIZE this somewhat. set the red factor to 255;
	the green one to 0. also, leave the blue factor at 0. that should
	END the result of this condition.

	OTHERWISE, just make COUNT EQUAL NEGATIVE 17.

Did I mention ANY language? Even those that do not fit in to the old ASCII
character set? French? Slovak? Russian? Arabic? Japanese? Persian?

Yep! Gracula will accept any character greater than 127 (maximum ASCII value)
and treat it as an acceptable character for any unquoted text string. This
allows you to enter text like the one above in any of the ISO 8859 series
of standards. It also allows you to write your script in Unicode. You may
encode your Unicode text into UTF-8. Gracula will accept it without complaints.
The only catch is you still have to put some GCL commands in your text. :-)

Don't have what it takes to convert to UTF-8? Just use my i18ntools. If you are
a FreeBSD user, just type:

	cd /usr/ports/converters/i18ntools
	make install

Everyone else can download the tools from http://www.whizkidtech.net/i18n/
and use their makefiles to build them.

USING GRACULA AS UNIX FILTER
============================

Please note carefully that GCL stands for Graphic Counter Language. It is NOT
a WEB counter language. Of course, it can be used on the web. But it can also
be used in ANY application that requires a graphic counter or timer.

When no GCL script is specified, gracula reads the script from stdin, and
compiles to stdout. Of course, if you use the -n switch (or the nocompile
directive), it will not compile.

Suppose you want to write an X application to display current time graphically.
You could simply create a loop where you run code like this once a second:

	gcl = popen("/usr/local/bin/gracula -lnmaz", "r+");
	fprintf(gcl, gclscript);
	i = 0;
	while((c = fgetc(gcl)) != EOF)
		gif[i++] = c;
	pclose(gcl);
	displaygif(gif, i);

Here we assume that displaygif() is a function you have written to display
a gif image from a buffer, and that it expects to receive a pointer to the
buffer and the number of bytes in the buffer. Also we assume that gclscript
is a text string containing some GCL script.

We have used the `-l' option to prevent gracula from outputting an HTTP
header, and the `-n' option to stop it from outputting a compiled version
of the script. The `-maz' options will produce a timer displaying current
date, time, and time zone.

Alternately, in a counter, you can decide not to use the `-n' switch and let
gracula tell you the next value of count. In that case, you need to separate
the compiled script from the gif. This is easy because the last line of the
compiled script will contain "count = nnnn" where nnnn is an integer.

This line will end with a newline character, after which the data of the GIF
file will follow.

Note that if you use the `-p' switch, the compiled output will NOT end with
the count, but it will not create a GIF image either. There is generally
no reason to use the `-p' switch when popening gracula.

Please make sure to abide by the license whenever distributing gracula with
other programs. You will find its terms very favorable. I will be pleased if
you let me know that you are using gracula with your program. You can email
me to gcl@whizkidtech.net.

COMMAND LINE OPTIONS
====================

Again, this is just an incomplete overview. Read the web site and the mailing
list for others.

	-k (make) allows you to create your own defaults. Gracula will
	   read your GCL file and produce gcldefaults.h and gcldefaults.c
	   files. You then recompile gracula, and voila, your defaults
	   (including images) are built in.

	   If you ever need to port your GCL files to a system with
	   different defaults, append the `portable' keyword to your
	   script. Normally, gracula does not write defaults into the
	   script when compiling it. This is to save time. However,
	   with the `portable' keyword, it will write everything in.

	   Once you have ported your script to a system with different
	   defaults, you can append `portable none' to it. Gracula will,
	   once again, produces smaller compiled scripts.

	-p (publish) allows you to share your scripts with others.
	   It will produce a nice, commented, script and send it to
	   stdout. Hint: Set the GCLAUTHOR environment variable to
	   your name. The published script will then contain your
	   copyright.

	-g (gallery) will produce gif output containing all your
	   images. This is useful to show off what a script can do.
	   It is also useful as a quick diagnostic: If you made any
	   mistakes, you will see them instantly.

	-i (inhibit) will recompile the script but not increase the
	   value of the counter.

	-t (text) will produce a text counter/timer which can be
	   included in SSI.

	-l (local) will NOT produce any HTTP header, just the gif
	   or text output.

	-o (omit grouping) will NOT divide the counter intro groups
	   separated by commas, dots, or spaces.

	-a (date) will show current date instead of a counter.

	-m (time) will show current time instead of a counter.

	-z (zone) will show the letter `Z' if used with the `utc'
	   directive without an offset in seconds, or the time
	   offset in +/-hh:mm:ss otherwise. Typically combined
	   with -a and -m.

	-h (help) shows all command line options.

Well, this is just an overview of some of the features of GCL and gracula.
I sure hope I whetted your appetite. See you on my website and on the gracula
mailing list. Again, you can subscribe to it at

	http://www.onelist.com/subscribe/gracula

