1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
#ifndef recipenode_h
#define recipenode_h
static const char recipenode_h_rcsid[]="$Id: recipenode.h,v 1.9 2004/01/15 03:12:13 mrsam Exp $";
#include "buffer.h"
class Recipe;
/////////////////////////////////////////////////////////////////////////////
//
// RecipeNode class - one "clause" in a recipe file, such as an "if"
// statement, or an expression.
//
// All RecipeNodes which represent a single recipe file are linked in a
// doubly-linked list anchored in their Recipe object.
//
// The RecipeNodes are arranged in a hierarchical format:
//
// prevNode/nextNode is the doubly-linked list anchored in the Recipe
// object. All RecipeNodes dynamically allocated by the Recipe class
// are on this list.
//
// firstChild/lastChild is a doubly-linked list of RecipeNodes that are
// considered descendants of this node. For example, a node that
// represents an "||" (logical or operation) will have two descendants,
// the left side, and the right side, of the expression. This RecipeNode
// itself is on the descendant list of its parent. All descendants of
// a RecipeNode have the parentNode pointer point to this RecipeNode.
// prevSibling/nextSibling is a doubly-linked list of all descendants of
// a single RecipeNode.
//
// This provides a generic linkage that is used to built a hierarchy that
// represents the logical layout of a recipe file. The remaining fields
// store information pertaining to each individual kind of a RecipeNode
// object. The nodeType field designates what kind of a RecipeNode object
// this is, which remaining fields are used depends on the nodeType field.
//
// The Recipe class calls the Evaluate() function of the first RecipeNode
// that represents that entire recipe file. The set of Evaluate() functions
// are logically involved to actually execute the given recipe file.
//
/////////////////////////////////////////////////////////////////////////////
class RecipeNode {
RecipeNode *prevNode, *nextNode; // List of all nodes in
// this recipe.
RecipeNode *parentNode; // Parent of this node.
RecipeNode *prevSibling, *nextSibling; // Siblings of this node.
RecipeNode *firstChild, *lastChild; // Its own children.
Buffer str;
int linenum;
void dollarexpand(Recipe &, Buffer &);
int dollarexpand(Recipe &, Buffer &, int);
public:
friend class Recipe;
enum RecipeNodeType {
statementlist,
assignment,
qstring,
sqstring,
btstring,
regexpr,
add,
subtract,
multiply,
divide,
lessthan,
lessthanoreq,
greaterthan,
greaterthanoreq,
equal,
notequal,
concat,
logicalor,
logicaland,
bitwiseor,
bitwiseand,
logicalnot,
bitwisenot,
strlessthan,
strlessthanoreq,
strgreaterthan,
strgreaterthanoreq,
strequal,
strnotequal,
strlength,
strsubstr,
strregexp,
ifelse,
whileloop,
deliver,
delivercc,
exception,
echo,
xfilter,
dotlock,
flock,
logfile,
log,
include,
exit,
foreach,
getaddr,
lookup,
escape,
to_lower,
to_upper,
hasaddr,
gdbmopen,
gdbmclose,
gdbmfetch,
gdbmstore,
timetoken,
importtoken,
unset
} nodeType;
RecipeNode(RecipeNodeType);
~RecipeNode() {}
void Evaluate(Recipe &, Buffer &);
private:
void AppendSibling(RecipeNode *);
void EvaluateString(Recipe &r, Buffer &b);
void EvaluateStrRegExp(Recipe &, Buffer &, Buffer *);
void EvaluateRegExp(Recipe &, Buffer &, Buffer *);
static void ParseRegExp(const Buffer &, Buffer &, Buffer &);
static int boolean(const Buffer &);
void rfc822getaddr(Buffer &);
int rfc822hasaddr(Buffer &);
int rfc822hasaddr(const char *, Buffer &);
void SpecialEscape(Buffer &);
int dolookup(Buffer &, Buffer &, Buffer &);
} ;
#endif
|