The main loop

The main cfperl loop is, as follows:

Modules

Constants

Initialization, globals, grammars

cfrun loop

Actually, before the modules, two things are done. First is a preamble
(program identification, the GPL license). Then the $VERSION variable is
declared and initialized to be the same as the CVS revision. Note the use
of $Revision: 1.9 $ and $Id: c10.xml,v 1.9 2002/06/09 23:27:55 lifelogs
Exp $, which are automatically filled in by CVS on check-in. $VERSION is
introduced here, because it is (conceptually) a meta-variable: not used
directly by cfperl itself, but reflecting something about the state of
cfperl.

# {{{ modules
use Data::Dumper;
use English;
use strict;
use POSIX;
use Parse::RecDescent;
use Carp;
use File::Basename;
use AppConfig qw/:expand :argcount/;
use IO::File;
use Sys::Hostname;
# }}}

Next is the constants section. I give symbolic names to each cfengine
configuration section we handle specifically, and these symbolic names are
used throughout the cfperl source code instead of string constants. Also
the name of the "any" class is defined here as a constant, and the default
global configuration file is set. Constants make source code much easier
to maintain; always look for opportunities to use constants instead of
variables.

The initialization, globals, and grammars sections are next. I am
omitting the grammars from the code samples here, since they will be
examined in a future chapter.

Auto-flushing the output and terse output for Data::Dumper are vital
settings to aid debugging. The AppConfig options will be explained in the
section on configuration options. Having a global
$config object helps greatly in managing configuration options.

The globals are set to a default if they are scalars (a good practice to
avoid obscure bugs is to always initialize your variables -- but to never
assume that they are initialized). The cfrun queue and order, and
the classes hash will be explained in future chapters. They are defined
to be global to make access easier, since they are used throughout cfperl.

After further initializations of the defined classes and processing of
configuration options (we will explain configuration options in the section on configuration options), the process_line()
and cfrun() functions are invoked on the cfengine configuration given to
cfperl. Note that the -exec (or -e) options will run process_line() and
cfrun() earlier, on the parameter given to -e.