00001 00029 #ifndef __OGRE_CPREPROCESSOR_H__ 00030 #define __OGRE_CPREPROCESSOR_H__ 00031 00032 #include <string.h> 00033 #include <stdlib.h> 00034 00035 namespace Ogre { 00036 00061 class CPreprocessor 00062 { 00076 class Token 00077 { 00078 public: 00079 enum Kind 00080 { 00081 TK_EOS, // End of input stream 00082 TK_ERROR, // An error has been encountered 00083 TK_WHITESPACE, // A whitespace span (but not newline) 00084 TK_NEWLINE, // A single newline (CR & LF) 00085 TK_LINECONT, // Line continuation ('\' followed by LF) 00086 TK_NUMBER, // A number 00087 TK_KEYWORD, // A keyword 00088 TK_PUNCTUATION, // A punctuation character 00089 TK_DIRECTIVE, // A preprocessor directive 00090 TK_STRING, // A string 00091 TK_COMMENT, // A block comment 00092 TK_LINECOMMENT, // A line comment 00093 TK_TEXT // An unparsed text (cannot be returned from GetToken()) 00094 }; 00095 00097 Kind Type; 00099 mutable size_t Allocated; 00100 union 00101 { 00103 const char *String; 00105 char *Buffer; 00106 }; 00108 size_t Length; 00109 00110 Token () : Allocated (0), String (NULL) 00111 { } 00112 00113 Token (Kind iType) : Type (iType), Allocated (0), String (NULL) 00114 { } 00115 00116 Token (Kind iType, const char *iString, size_t iLength) : 00117 Type (iType), Allocated (0), String (iString), Length (iLength) 00118 { } 00119 00120 Token (const Token &iOther) 00121 { 00122 Type = iOther.Type; 00123 Allocated = iOther.Allocated; 00124 iOther.Allocated = 0; // !!! not quite correct but effective 00125 String = iOther.String; 00126 Length = iOther.Length; 00127 } 00128 00129 ~Token () 00130 { if (Allocated) free (Buffer); } 00131 00133 Token &operator = (const Token &iOther) 00134 { 00135 if (Allocated) free (Buffer); 00136 Type = iOther.Type; 00137 Allocated = iOther.Allocated; 00138 iOther.Allocated = 0; // !!! not quite correct but effective 00139 String = iOther.String; 00140 Length = iOther.Length; 00141 return *this; 00142 } 00143 00145 void Append (const char *iString, size_t iLength); 00146 00148 void Append (const Token &iOther); 00149 00151 void AppendNL (int iCount); 00152 00154 int CountNL (); 00155 00157 bool GetValue (long &oValue) const; 00158 00160 void SetValue (long iValue); 00161 00163 bool operator == (const Token &iOther) 00164 { 00165 if (iOther.Length != Length) 00166 return false; 00167 return (memcmp (String, iOther.String, Length) == 0); 00168 } 00169 }; 00170 00172 class Macro 00173 { 00174 public: 00176 Token Name; 00178 int NumArgs; 00180 Token *Args; 00182 Token Value; 00184 Token Body; 00186 Macro *Next; 00188 Token (*ExpandFunc) (CPreprocessor *iParent, int iNumArgs, Token *iArgs); 00190 bool Expanding; 00191 00192 Macro (const Token &iName) : 00193 Name (iName), NumArgs (0), Args (NULL), Next (NULL), 00194 ExpandFunc (NULL), Expanding (false) 00195 { } 00196 00197 ~Macro () 00198 { delete [] Args; delete Next; } 00199 00201 Token Expand (int iNumArgs, Token *iArgs, Macro *iMacros); 00202 }; 00203 00204 friend class CPreprocessor::Macro; 00205 00207 const char *Source; 00209 const char *SourceEnd; 00211 int Line; 00213 bool BOL; 00215 unsigned EnableOutput; 00217 Macro *MacroList; 00218 00222 CPreprocessor (const Token &iToken, int iLine); 00223 00231 Token GetToken (bool iExpand); 00232 00242 Token HandleDirective (Token &iToken, int iLine); 00243 00254 bool HandleDefine (Token &iBody, int iLine); 00255 00266 bool HandleUnDef (Token &iBody, int iLine); 00267 00278 bool HandleIfDef (Token &iBody, int iLine); 00279 00290 bool HandleIf (Token &iBody, int iLine); 00291 00302 bool HandleElse (Token &iBody, int iLine); 00303 00314 bool HandleEndIf (Token &iBody, int iLine); 00315 00326 Token GetArgument (Token &oArg, bool iExpand); 00327 00338 Token GetArguments (int &oNumArgs, Token *&oArgs, bool iExpand); 00339 00353 Token GetExpression (Token &oResult, int iLine, int iOpPriority = 0); 00354 00370 bool GetValue (const Token &iToken, long &oValue, int iLine); 00371 00380 Token ExpandMacro (const Token &iToken); 00381 00389 Macro *IsDefined (const Token &iToken); 00390 00402 static Token ExpandDefined (CPreprocessor *iParent, int iNumArgs, Token *iArgs); 00403 00411 Token Parse (const Token &iSource); 00412 00422 void Error (int iLine, const char *iError, const Token *iToken = NULL); 00423 00424 public: 00426 CPreprocessor () : MacroList (NULL) 00427 { } 00428 00430 virtual ~CPreprocessor (); 00431 00443 void Define (const char *iMacroName, size_t iMacroNameLen, 00444 const char *iMacroValue, size_t iMacroValueLen); 00445 00455 void Define (const char *iMacroName, size_t iMacroNameLen, long iMacroValue); 00456 00466 bool Undef (const char *iMacroName, size_t iMacroNameLen); 00467 00490 char *Parse (const char *iSource, size_t iLength, size_t &oLength); 00491 00507 typedef void (*ErrorHandlerFunc) ( 00508 void *iData, int iLine, const char *iError, 00509 const char *iToken, size_t iTokenLen); 00510 00516 static ErrorHandlerFunc ErrorHandler; 00517 00519 void *ErrorData; 00520 }; 00521 00522 } // namespace Ogre 00523 00524 #endif // __OGRE_CPREPROCESSOR_H__
Copyright © 2012 Torus Knot Software Ltd
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Last modified Fri May 25 2012 21:48:50