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
|
#include "cgi"
#include <vector>
#include <stack>
#include <string.h>
#include <istream>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <memory>
#include <sys/stat.h>
#include <sys/types.h>
#include <bobcat/fnwrap1c>
#include <bobcat/a2x>
#include <bobcat/errno>
#include <bobcat/string>
#include <bobcat/x2a>
#include <bobcat/stat>
#include <bobcat/foreach>
using namespace std;
using namespace FBB;
namespace FBB
{
typedef pair<char const *const, int (*const)(int)> PairCPPFunP;
class CGIFSA
{
enum Token
{
DEFAULT = 256,
SET,
END,
};
enum State // change data.cc s_stateName when this changes
{
START,
CHECKSET,
DEFINESET,
OPENBRACKET,
LEFTCOLON,
SETNAME,
RIGHTCOLON,
N_STATES_,
STOP = N_STATES_,
};
struct Record
{
State current;
size_t token;
void (CGIFSA::*action)();
State next;
size_t (CGIFSA::*tokenizer)();
};
stack<char> d_stack;
bool *d_escape;
bool d_setEscape;
State d_state;
size_t d_tokenIdx;
string d_buffer;
size_t d_setIdx;
istream &d_in;
struct Transition
{
size_t token;
void (CGIFSA::*action)();
State next;
};
static vector<Transition> s_fsa[];
static size_t (CGIFSA::*s_tokenizer[])();
static Record const s_fsaRawData[];
static Record const *const s_fsaRawDataEnd;
static PairCPPFunP const s_charClass[];
static PairCPPFunP const *const s_charClassEnd;
static bool s_installed;
static char const *s_stateName[];
static std::string s_cgi;
public:
CGIFSA(bool *escape, istream &in = cin, bool setEscape = false);
void run();
private:
void push();
void accept();
void charRange();
void charClass();
void acceptAll(); // all elements on the stack
size_t tokenIdx();
void setEscape(size_t idx);
size_t charToken();
size_t wordToken();
static void setFsa(Record const &record);
static bool isFirst(PairCPPFunP const &cClass, string const &key);
static bool hasToken(Transition const &transition, size_t token);
static int iscgi(int ch);
};
inline bool CGIFSA::isFirst(pair<char const *const, int (*const )(int)>
const &cClass, string const &key)
{
return key == cClass.first;
}
inline bool CGIFSA::hasToken(Transition const &transition, size_t token)
{
return token == transition.token;
}
inline int CGIFSA::iscgi(int ch)
{
return s_cgi.find(ch) != std::string::npos;
}
inline void CGIFSA::setEscape(size_t idx)
{
d_escape[idx] = d_setEscape;
}
} // namespace
|