Pyrogenesis  trunk
OgreGLSLPreprocessor.h
Go to the documentation of this file.
1 /*
2  * This source file originally came from OGRE v1.12.4 - http://www.ogre3d.org/
3  * with some tweaks as part of 0 A.D.
4  * All changes are released under the original license, as follows:
5  */
6 
7 /*
8  -----------------------------------------------------------------------------
9  This source file is part of OGRE
10  (Object-oriented Graphics Rendering Engine)
11  For the latest info, see http://www.ogre3d.org/
12 
13  Copyright (c) 2000-2014 Torus Knot Software Ltd
14 
15  Permission is hereby granted, free of charge, to any person obtaining a copy
16  of this software and associated documentation files (the "Software"), to deal
17  in the Software without restriction, including without limitation the rights
18  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19  copies of the Software, and to permit persons to whom the Software is
20  furnished to do so, subject to the following conditions:
21 
22  The above copyright notice and this permission notice shall be included in
23  all copies or substantial portions of the Software.
24 
25  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
31  THE SOFTWARE.
32  -----------------------------------------------------------------------------
33 */
34 
35 #ifndef __OGRE_CPREPROCESSOR_H__
36 #define __OGRE_CPREPROCESSOR_H__
37 
38 #include <forward_list>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <vector>
42 
43 namespace Ogre
44 {
45 
46  /**
47  * This is a simplistic C/C++-like preprocessor.
48  * It takes an non-zero-terminated string on input and outputs a
49  * non-zero-terminated string buffer.
50  *
51  * This preprocessor was designed specifically for GLSL shaders, so
52  * if you want to use it for other purposes you might want to check
53  * if the feature set it provides is enough for you.
54  *
55  * Here's a list of supported features:
56  * - Fast memory allocation-less operation (mostly).
57  * - Line continuation (backslash-newline) is swallowed.
58  * - Line numeration is fully preserved by inserting empty lines where
59  * required. This is crucial if, say, GLSL compiler reports you an error
60  * with a line number.
61  * - @c \#define: Parametrized and non-parametrized macros. Invoking a macro with
62  * less arguments than it takes assignes empty values to missing arguments.
63  * - @c \#undef: Forget defined macros
64  * - @c \#ifdef / @c \#ifndef / @c \#else / @c \#endif: Conditional suppression of parts of code.
65  * - @c \#if: Supports numeric expression of any complexity, also supports the
66  * defined() pseudo-function.
67  */
69  {
70  public:
71  /**
72  * A input token.
73  *
74  * For performance reasons most tokens will point to portions of the
75  * input stream, so no unneeded memory allocation is done. However,
76  * in some cases we must allocate different memory for token storage,
77  * in this case this is signalled by setting the Allocated member
78  * to non-zero in which case the destructor will know that it must
79  * free memory on object destruction.
80  *
81  * Again for performance reasons we use malloc/realloc/free here because
82  * C++-style new[] lacks the realloc() counterpart.
83  */
84  class Token
85  {
86  public:
87  enum Kind
88  {
89  TK_EOS, // End of input stream
90  TK_ERROR, // An error has been encountered
91  TK_WHITESPACE, // A whitespace span (but not newline)
92  TK_NEWLINE, // A single newline (CR & LF)
93  TK_LINECONT, // Line continuation ('\' followed by LF)
94  TK_NUMBER, // A number
95  TK_KEYWORD, // A keyword
96  TK_PUNCTUATION, // A punctuation character
97  TK_DIRECTIVE, // A preprocessor directive
98  TK_STRING, // A string
99  TK_COMMENT, // A block comment
100  TK_LINECOMMENT, // A line comment
101  TK_TEXT // An unparsed text (cannot be returned from GetToken())
102  };
103 
104  /// Token type
106  /// True if string was allocated (and must be freed)
107  mutable size_t Allocated;
108  union
109  {
110  /// A pointer somewhere into the input buffer
111  const char *String;
112  /// A memory-allocated string
113  char *Buffer;
114  };
115  /// Token length in bytes
116  size_t Length;
117 
118  Token () : Allocated (0), String (NULL), Length(0)
119  { }
120 
121  Token (Kind iType) : Type (iType), Allocated (0), String (NULL), Length(0)
122  { }
123 
124  Token (Kind iType, const char *iString, size_t iLength) :
125  Type (iType), Allocated (0), String (iString), Length (iLength)
126  { }
127 
128  Token (const Token &iOther)
129  {
130  Type = iOther.Type;
131  Allocated = iOther.Allocated;
132  iOther.Allocated = 0; // !!! not quite correct but effective
133  String = iOther.String;
134  Length = iOther.Length;
135  }
136 
138  { if (Allocated) free (Buffer); }
139 
140  /// Assignment operator
141  Token &operator = (const Token &iOther)
142  {
143  if (Allocated) free (Buffer);
144  Type = iOther.Type;
145  Allocated = iOther.Allocated;
146  iOther.Allocated = 0; // !!! not quite correct but effective
147  String = iOther.String;
148  Length = iOther.Length;
149  return *this;
150  }
151 
152  /// Append a string to this token
153  void Append (const char *iString, size_t iLength);
154 
155  /// Append a token to this token
156  void Append (const Token &iOther);
157 
158  /// Append given number of newlines to this token
159  void AppendNL (int iCount);
160 
161  /// Count number of newlines in this token
162  int CountNL ();
163 
164  /// Get the numeric value of the token
165  bool GetValue (long &oValue) const;
166 
167  /// Set the numeric value of the token
168  void SetValue (long iValue);
169 
170  /// Test two tokens for equality
171  bool operator == (const Token &iOther)
172  {
173  if (iOther.Length != Length)
174  return false;
175  return (memcmp (String, iOther.String, Length) == 0);
176  }
177  };
178 
179  /// A macro definition
180  class Macro
181  {
182  public:
183  /// Macro name
185  /// The names of the arguments
186  std::vector<Token> Args;
187  /// The macro value
189  /// Unparsed macro body (keeps the whole raw unparsed macro body)
191  /// A pointer to function implementation (if macro is really a func)
192  Token (*ExpandFunc) (CPreprocessor *iParent, const std::vector<Token>& iArgs);
193  /// true if macro expansion is in progress
194  bool Expanding;
195 
196  Macro(const Token& iName) : Name(iName), ExpandFunc(NULL), Expanding(false) {}
197 
198  /// Expand the macro value (will not work for functions)
199  Token Expand (const std::vector<Token>& iArgs, std::forward_list<Macro>& iMacros);
200  };
201 
202  friend class CPreprocessor::Macro;
203 
204  /// The current source text input
205  const char *Source;
206  /// The end of the source text
207  const char *SourceEnd;
208  /// Current line number
209  int Line;
210  /// True if we are at beginning of line
211  bool BOL;
212  /// A stack of 32 booleans packed into one value :)
213  unsigned EnableOutput;
214  unsigned EnableElif;
215  /// The list of macros defined so far
216  std::forward_list<Macro> MacroList;
217 
218  /**
219  * Private constructor to re-parse a single token.
220  */
221  CPreprocessor (const Token &iToken, int iLine);
222 
223  /**
224  * Stateless tokenizer: Parse the input text and return the next token.
225  * @param iExpand
226  * If true, macros will be expanded to their values
227  * @return
228  * The next token from the input stream
229  */
230  Token GetToken (bool iExpand);
231 
232  /**
233  * Handle a preprocessor directive.
234  * @param iToken
235  * The whole preprocessor directive line (until EOL)
236  * @param iLine
237  * The line where the directive begins (for error reports)
238  * @return
239  * The last input token that was not proceeded.
240  */
241  Token HandleDirective (Token &iToken, int iLine);
242 
243  /**
244  * Handle a #define directive.
245  * @param iBody
246  * The body of the directive (everything after the directive
247  * until end of line).
248  * @param iLine
249  * The line where the directive begins (for error reports)
250  * @return
251  * true if everything went ok, false if not
252  */
253  bool HandleDefine (Token &iBody, int iLine);
254 
255  /**
256  * Undefine a previously defined macro
257  * @param iBody
258  * The body of the directive (everything after the directive
259  * until end of line).
260  * @param iLine
261  * The line where the directive begins (for error reports)
262  * @return
263  * true if everything went ok, false if not
264  */
265  bool HandleUnDef (Token &iBody, int iLine);
266 
267  /**
268  * Handle an #ifdef directive.
269  * @param iBody
270  * The body of the directive (everything after the directive
271  * until end of line).
272  * @param iLine
273  * The line where the directive begins (for error reports)
274  * @return
275  * true if everything went ok, false if not
276  */
277  bool HandleIfDef (Token &iBody, int iLine);
278 
279  /**
280  * Handle an #if directive.
281  * @param iBody
282  * The body of the directive (everything after the directive
283  * until end of line).
284  * @param iLine
285  * The line where the directive begins (for error reports)
286  * @return
287  * true if everything went ok, false if not
288  */
289  bool HandleIf (Token &iBody, int iLine);
290 
291  /// @overload
292  bool HandleIf(bool val, int iLine);
293 
294  /**
295  * Handle an #elif directive.
296  * @param iBody
297  * The body of the directive (everything after the directive
298  * until end of line).
299  * @param iLine
300  * The line where the directive begins (for error reports)
301  * @return
302  * true if everything went ok, false if not
303  */
304  bool HandleElif (Token &iBody, int iLine);
305 
306  /**
307  * Handle an #else directive.
308  * @param iBody
309  * The body of the directive (everything after the directive
310  * until end of line).
311  * @param iLine
312  * The line where the directive begins (for error reports)
313  * @return
314  * true if everything went ok, false if not
315  */
316  bool HandleElse (Token &iBody, int iLine);
317 
318  /**
319  * Handle an #endif directive.
320  * @param iBody
321  * The body of the directive (everything after the directive
322  * until end of line).
323  * @param iLine
324  * The line where the directive begins (for error reports)
325  * @return
326  * true if everything went ok, false if not
327  */
328  bool HandleEndIf (Token &iBody, int iLine);
329 
330  /**
331  * Get a single function argument until next ',' or ')'.
332  * @param oArg
333  * The argument is returned in this variable.
334  * @param iExpand
335  * If false, parameters are not expanded and no expressions are
336  * allowed; only a single keyword is expected per argument.
337  * @param shouldAppendArg
338  * When true, the argument will be appended the word word __arg_
339  * e.g. #define myMacro(x) --> #define myMacro(x__arg_)
340  * This workaround a bug where calling myMacro( x ) would cause
341  * issues.
342  * @return
343  * The first unhandled token after argument.
344  */
345  Token GetArgument (Token &oArg, bool iExpand, bool shouldAppendArg);
346 
347  /**
348  * Get all the arguments of a macro: '(' arg1 { ',' arg2 { ',' ... }} ')'
349  * @param oArgs
350  * This is set to a pointer to an array of parsed arguments.
351  * @param shouldAppendArg
352  * See GetArgument.
353  * @param iExpand
354  * If false, parameters are not expanded and no expressions are
355  * allowed; only a single keyword is expected per argument.
356  */
357  Token GetArguments (std::vector<Token>& oArgs, bool iExpand, bool shouldAppendArg);
358 
359  /**
360  * Parse an expression, compute it and return the result.
361  * @param oResult
362  * A token containing the result of expression
363  * @param iLine
364  * The line at which the expression starts (for error reports)
365  * @param iOpPriority
366  * Operator priority (at which operator we will stop if
367  * proceeding recursively -- used internally. Parser stops
368  * when it encounters an operator with higher or equal priority).
369  * @return
370  * The last unhandled token after the expression
371  */
372  Token GetExpression (Token &oResult, int iLine, int iOpPriority = 0);
373 
374  /**
375  * Get the numeric value of a token.
376  * If the token was produced by expanding a macro, we will get
377  * an TEXT token which can contain a whole expression; in this
378  * case we will call GetExpression to parse it. Otherwise we
379  * just call the token's GetValue() method.
380  * @param iToken
381  * The token to get the numeric value of
382  * @param oValue
383  * The variable to put the value into
384  * @param iLine
385  * The line where the directive begins (for error reports)
386  * @return
387  * true if ok, false if not
388  */
389  bool GetValue (const Token &iToken, long &oValue, int iLine);
390 
391  /// @overload
392  /// same as above, but considers the defined() function
393  bool GetValueDef(const Token &iToken, long &oValue, int iLine);
394 
395  /**
396  * Expand the given macro, if it exists.
397  * If macro has arguments, they are collected from source stream.
398  * @param iToken
399  * A KEYWORD token containing the (possible) macro name.
400  * @return
401  * The expanded token or iToken if it is not a macro
402  */
403  Token ExpandMacro (const Token &iToken);
404 
405  /**
406  * Check if a macro is defined, and if so, return it
407  * @param iToken
408  * Macro name
409  * @return
410  * The macro object or NULL if a macro with this name does not exist
411  */
412  Macro *IsDefined (const Token &iToken);
413 
414  /**
415  * The implementation of the defined() preprocessor function
416  * @param iParent
417  * The parent preprocessor object
418  * @param iArgs
419  * The arguments themselves
420  * @return
421  * The return value encapsulated in a token
422  */
423  static Token ExpandDefined (CPreprocessor *iParent, const std::vector<Token>& iArgs);
424 
425  /**
426  * Parse the input string and return a token containing the whole output.
427  * @param iSource
428  * The source text enclosed in a token
429  * @return
430  * The output text enclosed in a token
431  */
432  Token Parse (const Token &iSource);
433 
434  /**
435  * Call the error handler
436  * @param iLine
437  * The line at which the error happened.
438  * @param iError
439  * The error string.
440  * @param iToken
441  * If not NULL contains the erroneous token
442  */
443  static void Error (int iLine, const char *iError, const Token *iToken = NULL);
444 
445  public:
446  /// Create an empty preprocessor object
448 
449  /// Destroy the preprocessor object
450  virtual ~CPreprocessor ();
451 
452  /**
453  * Define a macro without parameters.
454  * @param iMacroName
455  * The name of the defined macro
456  * @param iMacroNameLen
457  * The length of the name of the defined macro
458  * @param iMacroValue
459  * The value of the defined macro
460  * @param iMacroValueLen
461  * The length of the value of the defined macro
462  */
463  void Define (const char *iMacroName, size_t iMacroNameLen,
464  const char *iMacroValue, size_t iMacroValueLen);
465 
466  /**
467  * Define a numerical macro.
468  * @param iMacroName
469  * The name of the defined macro
470  * @param iMacroNameLen
471  * The length of the name of the defined macro
472  * @param iMacroValue
473  * The value of the defined macro
474  */
475  void Define (const char *iMacroName, size_t iMacroNameLen, long iMacroValue);
476 
477  /**
478  * Undefine a macro.
479  * @param iMacroName
480  * The name of the macro to undefine
481  * @param iMacroNameLen
482  * The length of the name of the macro to undefine
483  * @return
484  * true if the macro has been undefined, false if macro doesn't exist
485  */
486  bool Undef (const char *iMacroName, size_t iMacroNameLen);
487 
488  /**
489  * Parse the input string and return a newly-allocated output string.
490  * @note
491  * The returned preprocessed string is NOT zero-terminated
492  * (just like the input string).
493  * @param iSource
494  * The source text
495  * @param iLength
496  * The length of the source text in characters
497  * @param oLength
498  * The length of the output string.
499  * @return
500  * The output from preprocessor, allocated with malloc().
501  * The parser can actually allocate more than needed for performance
502  * reasons, but this should not be a problem unless you will want
503  * to store the returned pointer for long time in which case you
504  * might want to realloc() it.
505  * If an error has been encountered, the function returns NULL.
506  * In some cases the function may return an unallocated address
507  * that's *inside* the source buffer. You must free() the result
508  * string only if the returned address is not inside the source text.
509  */
510  char *Parse (const char *iSource, size_t iLength, size_t &oLength);
511 
512  /**
513  * Call the error handler
514  * @param iLine
515  * The line at which the error happened.
516  * @param iError
517  * The error string.
518  * @param iToken
519  * If not NULL contains the erroneous token
520  */
521  typedef void (*ErrorHandlerFunc) (int iLine, const char *iError, const Token *iToken);
522 
523  /**
524  * A pointer to the preprocessor's error handler.
525  * You can assign the address of your own function to this variable
526  * and implement your own error handling (e.g. throwing an exception etc).
527  */
529 
530  };
531 
532 } // namespace Ogre
533 
534 #endif // __OGRE_CPREPROCESSOR_H__
bool GetValueDef(const Token &iToken, long &oValue, int iLine)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: OgreGLSLPreprocessor.cpp:1048
std::vector< Token > Args
The names of the arguments.
Definition: OgreGLSLPreprocessor.h:186
static void Error(int iLine, const char *iError, const Token *iToken=NULL)
Call the error handler.
Definition: OgreGLSLPreprocessor.cpp:231
This is a simplistic C/C++-like preprocessor.
Definition: OgreGLSLPreprocessor.h:68
static Token ExpandDefined(CPreprocessor *iParent, const std::vector< Token > &iArgs)
The implementation of the defined() preprocessor function.
Definition: OgreGLSLPreprocessor.cpp:1036
Token ExpandMacro(const Token &iToken)
Expand the given macro, if it exists.
Definition: OgreGLSLPreprocessor.cpp:398
Token(Kind iType)
Definition: OgreGLSLPreprocessor.h:121
Token HandleDirective(Token &iToken, int iLine)
Handle a preprocessor directive.
Definition: OgreGLSLPreprocessor.cpp:1129
bool HandleIfDef(Token &iBody, int iLine)
Handle an #ifdef directive.
Definition: OgreGLSLPreprocessor.cpp:1007
int Line
Current line number.
Definition: OgreGLSLPreprocessor.h:209
Definition: OgreGLSLPreprocessor.h:97
const char * Source
The current source text input.
Definition: OgreGLSLPreprocessor.h:205
Definition: OgreGLSLPreprocessor.h:92
const char * SourceEnd
The end of the source text.
Definition: OgreGLSLPreprocessor.h:207
Definition: OgreGLSLPreprocessor.h:95
bool GetValue(long &oValue) const
Get the numeric value of the token.
Definition: OgreGLSLPreprocessor.cpp:105
Token GetToken(bool iExpand)
Stateless tokenizer: Parse the input text and return the next token.
Definition: OgreGLSLPreprocessor.cpp:255
void(* ErrorHandlerFunc)(int iLine, const char *iError, const Token *iToken)
Call the error handler.
Definition: OgreGLSLPreprocessor.h:521
Definition: OgreGLSLPreprocessor.h:99
void SetValue(long iValue)
Set the numeric value of the token.
Definition: OgreGLSLPreprocessor.cpp:155
Definition: OgreGLSLPreprocessor.h:89
A input token.
Definition: OgreGLSLPreprocessor.h:84
bool HandleElif(Token &iBody, int iLine)
Handle an #elif directive.
Definition: OgreGLSLPreprocessor.cpp:1069
Token GetExpression(Token &oResult, int iLine, int iOpPriority=0)
Parse an expression, compute it and return the result.
Definition: OgreGLSLPreprocessor.cpp:462
Token Body
Unparsed macro body (keeps the whole raw unparsed macro body)
Definition: OgreGLSLPreprocessor.h:190
bool Undef(const char *iMacroName, size_t iMacroNameLen)
Undefine a macro.
Definition: OgreGLSLPreprocessor.cpp:1251
Token Parse(const Token &iSource)
Parse the input string and return a token containing the whole output.
Definition: OgreGLSLPreprocessor.cpp:1271
std::forward_list< Macro > MacroList
The list of macros defined so far.
Definition: OgreGLSLPreprocessor.h:216
Token GetArguments(std::vector< Token > &oArgs, bool iExpand, bool shouldAppendArg)
Get all the arguments of a macro: &#39;(&#39; arg1 { &#39;,&#39; arg2 { &#39;,&#39; ...
Definition: OgreGLSLPreprocessor.cpp:830
Definition: OgreGLSLPreprocessor.h:100
A macro definition.
Definition: OgreGLSLPreprocessor.h:180
Kind Type
Token type.
Definition: OgreGLSLPreprocessor.h:105
bool BOL
True if we are at beginning of line.
Definition: OgreGLSLPreprocessor.h:211
void AppendNL(int iCount)
Append given number of newlines to this token.
Definition: OgreGLSLPreprocessor.cpp:165
Definition: OgreGLSLPreprocessor.h:98
unsigned EnableElif
Definition: OgreGLSLPreprocessor.h:214
Definition: OgreGLSLPreprocessor.h:91
Kind
Definition: OgreGLSLPreprocessor.h:87
virtual ~CPreprocessor()
Destroy the preprocessor object.
Definition: OgreGLSLPreprocessor.cpp:253
char * Buffer
A memory-allocated string.
Definition: OgreGLSLPreprocessor.h:113
size_t Length
Token length in bytes.
Definition: OgreGLSLPreprocessor.h:116
Definition: OgreGLSLPreprocessor.h:90
Definition: OgreGLSLPreprocessor.h:94
const char * String
A pointer somewhere into the input buffer.
Definition: OgreGLSLPreprocessor.h:111
static ErrorHandlerFunc ErrorHandler
A pointer to the preprocessor&#39;s error handler.
Definition: OgreGLSLPreprocessor.h:528
CPreprocessor()
Create an empty preprocessor object.
Definition: OgreGLSLPreprocessor.h:447
bool HandleUnDef(Token &iBody, int iLine)
Undefine a previously defined macro.
Definition: OgreGLSLPreprocessor.cpp:961
int CountNL()
Count number of newlines in this token.
Definition: OgreGLSLPreprocessor.cpp:180
void Append(const char *iString, size_t iLength)
Append a string to this token.
Definition: OgreGLSLPreprocessor.cpp:59
~Token()
Definition: OgreGLSLPreprocessor.h:137
bool Expanding
true if macro expansion is in progress
Definition: OgreGLSLPreprocessor.h:194
Token Value
The macro value.
Definition: OgreGLSLPreprocessor.h:188
bool HandleElse(Token &iBody, int iLine)
Handle an #else directive.
Definition: OgreGLSLPreprocessor.cpp:1093
Definition: OgreGLSLPreprocessor.h:93
Token Name
Macro name.
Definition: OgreGLSLPreprocessor.h:184
size_t Allocated
True if string was allocated (and must be freed)
Definition: OgreGLSLPreprocessor.h:107
Definition: OgreGLSLPreprocessor.cpp:43
Token & operator=(const Token &iOther)
Assignment operator.
Definition: OgreGLSLPreprocessor.h:141
bool operator==(const Token &iOther)
Test two tokens for equality.
Definition: OgreGLSLPreprocessor.h:171
Macro(const Token &iName)
Definition: OgreGLSLPreprocessor.h:196
Token GetArgument(Token &oArg, bool iExpand, bool shouldAppendArg)
Get a single function argument until next &#39;,&#39; or &#39;)&#39;.
Definition: OgreGLSLPreprocessor.cpp:726
bool HandleEndIf(Token &iBody, int iLine)
Handle an #endif directive.
Definition: OgreGLSLPreprocessor.cpp:1112
void Define(const char *iMacroName, size_t iMacroNameLen, const char *iMacroValue, size_t iMacroValueLen)
Define a macro without parameters.
Definition: OgreGLSLPreprocessor.cpp:1235
bool HandleIf(Token &iBody, int iLine)
Handle an #if directive.
Definition: OgreGLSLPreprocessor.cpp:1063
Definition: OgreGLSLPreprocessor.h:101
Token()
Definition: OgreGLSLPreprocessor.h:118
Definition: OgreGLSLPreprocessor.h:96
Token(const Token &iOther)
Definition: OgreGLSLPreprocessor.h:128
bool HandleDefine(Token &iBody, int iLine)
Handle a #define directive.
Definition: OgreGLSLPreprocessor.cpp:901
Macro * IsDefined(const Token &iToken)
Check if a macro is defined, and if so, return it.
Definition: OgreGLSLPreprocessor.cpp:388
unsigned EnableOutput
A stack of 32 booleans packed into one value :)
Definition: OgreGLSLPreprocessor.h:213
Token(Kind iType, const char *iString, size_t iLength)
Definition: OgreGLSLPreprocessor.h:124