/* * Function: TemplateInit(u_char *) * * Purpose: Calls the argument parsing function, performs final setup on data * structs, links the preproc function into the function list. * * Arguments: args => ptr to argument string * * Returns: void function * */ void TemplateInit(u_char *args) { DebugMessage(DEBUG_PLUGIN,"Preprocessor: Template Initialized\n"); /* parse the argument list from the rules file */ ParseTemplateArgs(args); /* Set the preprocessor function into the function list */ AddFuncToPreprocList(PreprocFunction); AddFuncToCleanExitList(PreprocCleanExitFunction); AddFuncToRestartList(PreprocRestartFunction); }
// <type> ::= <CV-qualifiers> <type> // ::= P <type> # pointer-to // ::= R <type> # reference-to // ::= O <type> # rvalue reference-to (C++0x) // ::= C <type> # complex pair (C 2000) // ::= G <type> # imaginary (C 2000) // ::= U <source-name> <type> # vendor extended type qualifier // ::= <builtin-type> // ::= <function-type> // ::= <class-enum-type> // ::= <array-type> // ::= <pointer-to-member-type> // ::= <template-template-param> <template-args> // ::= <template-param> // ::= <substitution> // ::= Dp <type> # pack expansion of (C++0x) // ::= Dt <expression> E # decltype of an id-expression or class // # member access (C++0x) // ::= DT <expression> E # decltype of an expression (C++0x) // static bool ParseType(State *state) { // We should check CV-qualifers, and PRGC things first. State copy = *state; if (ParseCVQualifiers(state) && ParseType(state)) { return true; } *state = copy; if (ParseCharClass(state, "OPRCG") && ParseType(state)) { return true; } *state = copy; if (ParseTwoCharToken(state, "Dp") && ParseType(state)) { return true; } *state = copy; if (ParseOneCharToken(state, 'D') && ParseCharClass(state, "tT") && ParseExpression(state) && ParseOneCharToken(state, 'E')) { return true; } *state = copy; if (ParseOneCharToken(state, 'U') && ParseSourceName(state) && ParseType(state)) { return true; } *state = copy; if (ParseBuiltinType(state) || ParseFunctionType(state) || ParseClassEnumType(state) || ParseArrayType(state) || ParsePointerToMemberType(state) || ParseSubstitution(state)) { return true; } if (ParseTemplateTemplateParam(state) && ParseTemplateArgs(state)) { return true; } *state = copy; // Less greedy than <template-template-param> <template-args>. if (ParseTemplateParam(state)) { return true; } return false; }
// <expression> ::= <template-param> // ::= <expr-primary> // ::= <unary operator-name> <expression> // ::= <binary operator-name> <expression> <expression> // ::= <trinary operator-name> <expression> <expression> // <expression> // ::= st <type> // ::= sr <type> <unqualified-name> <template-args> // ::= sr <type> <unqualified-name> static bool ParseExpression(State *state) { if (ParseTemplateParam(state) || ParseExprPrimary(state)) { return true; } State copy = *state; if (ParseOperatorName(state) && ParseExpression(state) && ParseExpression(state) && ParseExpression(state)) { return true; } *state = copy; if (ParseOperatorName(state) && ParseExpression(state) && ParseExpression(state)) { return true; } *state = copy; if (ParseOperatorName(state) && ParseExpression(state)) { return true; } *state = copy; if (ParseTwoChar(state, "st") && ParseType(state)) { return true; } *state = copy; if (ParseTwoChar(state, "sr") && ParseType(state) && ParseUnqualifiedName(state) && ParseTemplateArgs(state)) { return true; } *state = copy; if (ParseTwoChar(state, "sr") && ParseType(state) && ParseUnqualifiedName(state)) { return true; } *state = copy; return false; }
// <name> ::= <nested-name> // ::= <unscoped-template-name> <template-args> // ::= <unscoped-name> // ::= <local-name> static bool ParseName(State *state) { if (ParseNestedName(state) || ParseLocalName(state)) { return true; } State copy = *state; if (ParseUnscopedTemplateName(state) && ParseTemplateArgs(state)) { return true; } *state = copy; // Less greedy than <unscoped-template-name> <template-args>. if (ParseUnscopedName(state)) { return true; } return false; }
// This part is tricky. If we literally translate them to code, we'll // end up infinite loop. Hence we merge them to avoid the case. // // <prefix> ::= <prefix> <unqualified-name> // ::= <template-prefix> <template-args> // ::= <template-param> // ::= <substitution> // ::= # empty // <template-prefix> ::= <prefix> <(template) unqualified-name> // ::= <template-param> // ::= <substitution> static bool ParsePrefix(State *state) { bool has_something = false; while (true) { MaybeAppendSeparator(state); if (ParseTemplateParam(state) || ParseSubstitution(state) || ParseUnscopedName(state)) { has_something = true; MaybeIncreaseNestLevel(state); continue; } MaybeCancelLastSeparator(state); if (has_something && ParseTemplateArgs(state)) { return ParsePrefix(state); } else { break; } } return true; }
/* * Function: TemplateInit(u_char *) * * Purpose: Calls the argument parsing function, performs final setup on data * structs, links the preproc function into the function list. * * Arguments: args => ptr to argument string * * Returns: void function * */ static void TemplateInit(u_char *args) { DebugMessage(DEBUG_PLUGIN,"Preprocessor: Template Initialized\n"); /* * parse the argument list from the rules file */ ParseTemplateArgs(args); /* * perform any other initialization functions that are required here */ /* * Set the preprocessor function into the function list */ AddFuncToPreprocList(PreprocFunction); AddFuncToCleanExitList(PreprocCleanExitFunction, NULL); AddFuncToRestartList(PreprocRestartFunction, NULL); }