public/ITextParsers.h
author Phong Dang <teame06@gmail.com>
Wed Aug 01 07:29:40 2007 +0000 (2007-08-01)
changeset 1241 2e8046793bc9
parent 1226 478550a4d5ec
child 1330 ab94316bb52b
permissions -rw-r--r--
Added check to make sure player are alive to perform sm_slap, sm_burn, sm_slay.
     1 /**
     2  * vim: set ts=4 :
     3  * ================================================================
     4  * SourceMod
     5  * Copyright (C) 2004-2007 AlliedModders LLC.  All rights reserved.
     6  * ================================================================
     7  *
     8  * This program is free software; you can redistribute it and/or 
     9  * modify it under the terms of the GNU General Public License, 
    10  * version 3.0, as published by the Free Software Foundation.
    11  * 
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    15  * GNU General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    19  *
    20  * As a special exception, AlliedModders LLC gives you permission to 
    21  * link the code of this program (as well as its derivative works) to 
    22  * "Half-Life 2," the "Source Engine," the "SourcePawn JIT," and any 
    23  * Game MODs that run on software by the Valve Corporation.  You must 
    24  * obey the GNU General Public License in all respects for all other 
    25  * code used. Additionally, AlliedModders LLC grants this exception 
    26  * to all derivative works. AlliedModders LLC defines further 
    27  * exceptions, found in LICENSE.txt (as of this writing, version 
    28  * JULY-31-2007), or <http://www.sourcemod.net/license.php>.
    29  *
    30  * Version: $Id$
    31  */
    32 
    33 #ifndef _INCLUDE_SOURCEMOD_TEXTPARSERS_INTERFACE_H_
    34 #define _INCLUDE_SOURCEMOD_TEXTPARSERS_INTERFACE_H_
    35 
    36 /**
    37  * @file ITextParsers.h
    38  * @brief Defines various text/file parsing functions, as well as UTF-8 support code.
    39  */
    40 
    41 #include <IShareSys.h>
    42 
    43 namespace SourceMod
    44 {
    45 	/**
    46 	 * The INI file format is defined as:
    47 	 * WHITESPACE: 0x20, \n, \t, \r
    48 	 * IDENTIFIER: A-Z a-z 0-9 _ - , + . $ ? / 
    49 	 * STRING: Any set of symbols
    50 	 * 
    51 	 * Basic syntax is comprised of SECTIONs.
    52 	 * A SECTION is defined as:
    53 	 * [SECTIONNAME]
    54 	 * OPTION
    55 	 * OPTION
    56 	 * OPTION...
    57 	 *
    58 	 * SECTIONNAME is an IDENTIFIER.
    59 	 * OPTION can be repeated any number of times, once per line.
    60 	 * OPTION is defined as one of:
    61 	 *  KEY = "VALUE"
    62 	 *  KEY = VALUE
    63 	 *  KEY
    64 	 * Where KEY is an IDENTIFIER and VALUE is a STRING.
    65 	 * 
    66 	 * WHITESPACE should always be omitted.
    67 	 * COMMENTS should be stripped, and are defined as text occurring in:
    68 	 * ;<TEXT>
    69 	 * 
    70 	 * Example file below.  Note that
    71 	 * The second line is technically invalid.  The event handler
    72 	 * must decide whether this should be allowed.
    73 	 * --FILE BELOW--
    74 	 * [gaben]
    75 	 * hi = clams
    76 	 * bye = "NO CLAMS"
    77 	 *
    78 	 * [valve]
    79 	 * cannot
    80 	 * maintain
    81 	 * products
    82 	 */
    83 
    84 	/**
    85 	 * @brief Contains parse events for INI files.
    86 	 */
    87 	class ITextListener_INI
    88 	{
    89 	public:
    90 		/**
    91 		 * @brief Called when a new section is encountered in an INI file.
    92 		 * 
    93 		 * @param section		Name of section in between the [ and ] characters.
    94 		 * @param invalid_tokens True if invalid tokens were detected in the name.
    95 		 * @param close_bracket	True if a closing bracket was detected, false otherwise.
    96 		 * @param extra_tokens	True if extra tokens were detected on the line.
    97 		 * @param curtok		Contains current token in the line where the section name starts.
    98 		 *						You can add to this offset when failing to point to a token.
    99 		 * @return				True to keep parsing, false otherwise.
   100 		 */
   101 		virtual bool ReadINI_NewSection(const char *section,
   102 										bool invalid_tokens,
   103 										bool close_bracket,
   104 										bool extra_tokens,
   105 										unsigned int *curtok)
   106 		{
   107 			return true;
   108 		}
   109 
   110 		/**
   111 		 * @brief Called when encountering a key/value pair in an INI file.
   112 		 * 
   113 		 * @param key			Name of key.
   114 		 * @param value			String containing value (with quotes stripped, if any).
   115 		 * @param invalid_tokens Whether or not the key contained invalid tokens.
   116 		 * @param equal_token	There was an '=' sign present (in case the value is missing).
   117 		 * @param quotes		Whether value was enclosed in quotes.
   118 		 * @param curtok		Contains the token index of the start of the value string.  
   119 		 *						This can be changed when returning false.
   120 		 * @return				True to keep parsing, false otherwise.
   121 		 */
   122 		virtual bool ReadINI_KeyValue(const char *key, 
   123 									  const char *value, 
   124 									  bool invalid_tokens,
   125 									  bool equal_token,
   126 									  bool quotes,
   127 									  unsigned int *curtok)
   128 		{
   129 			return true;
   130 		}
   131 
   132 		/**
   133 		 * @brief Called after a line has been preprocessed, if it has text.
   134 		 *
   135 		 * @param line			Contents of line.
   136 		 * @param curtok		Pointer to optionally store failed position in string.
   137 		 * @return				True to keep parsing, false otherwise.
   138 		 */
   139 		virtual bool ReadINI_RawLine(const char *line, unsigned int *curtok)
   140 		{
   141 			return true;
   142 		}
   143 	};
   144 
   145 	/**
   146 	 * :TODO: write this in CFG (context free grammar) format so it makes sense
   147 	 * 
   148 	 * The SMC file format is defined as:
   149 	 * WHITESPACE: 0x20, \n, \t, \r
   150 	 * IDENTIFIER: Any ASCII character EXCLUDING ", {, }, ;, //, / *, or WHITESPACE.
   151 	 * STRING: Any set of symbols enclosed in quotes.
   152 	 * Note: if a STRING does not have quotes, it is parsed as an IDENTIFIER.
   153 	 *
   154 	 * Basic syntax is comprised of SECTIONBLOCKs.
   155 	 * A SECTIONBLOCK defined as:
   156 	 *
   157 	 * SECTIONNAME
   158 	 * {
   159 	 *    OPTION
   160 	 * }
   161 	 * 
   162 	 * OPTION can be repeated any number of times inside a SECTIONBLOCK.
   163 	 * A new line will terminate an OPTION, but there can be more than one OPTION per line.
   164 	 * OPTION is defined any of:
   165 	 * 	  "KEY"  "VALUE"
   166 	 *    SECTIONBLOCK
   167 	 *
   168 	 * SECTIONNAME, KEY, VALUE, and SINGLEKEY are strings
   169 	 * SECTIONNAME cannot have trailing characters if quoted, but the quotes can be optionally removed.
   170 	 * If SECTIONNAME is not enclosed in quotes, the entire sectionname string is used (minus surrounding whitespace).
   171 	 * If KEY is not enclosed in quotes, the key is terminated at first whitespace.
   172 	 * If VALUE is not properly enclosed in quotes, the entire value string is used (minus surrounding whitespace).
   173 	 * The VALUE may have inner quotes, but the key string may not.
   174 	 *
   175 	 * For an example, see configs/permissions.cfg
   176 	 *
   177 	 * WHITESPACE should be ignored.
   178 	 * Comments are text occurring inside the following tokens, and should be stripped
   179 	 * unless they are inside literal strings:
   180 	 *  ;<TEXT>
   181 	 *  //<TEXT>
   182 	 *  / *<TEXT> */
   183 
   184 	/**
   185 	 * @brief Lists actions to take when an SMC parse hook is done.
   186 	 */
   187 	enum SMCParseResult
   188 	{
   189 		SMCParse_Continue,		/**< Continue parsing */
   190 		SMCParse_Halt,			/**< Stop parsing here */
   191 		SMCParse_HaltFail		/**< Stop parsing and return SMCParseError_Custom */
   192 	};
   193 
   194 	/**
   195 	 * @brief Lists error codes possible from parsing an SMC file.
   196 	 */
   197 	enum SMCParseError
   198 	{
   199 		SMCParse_Okay = 0,			/**< No error */
   200 		SMCParse_StreamOpen,		/**< Stream failed to open */
   201 		SMCParse_StreamError,		/**< The stream died... somehow */
   202 		SMCParse_Custom,			/**< A custom handler threw an error */
   203 		SMCParse_InvalidSection1,	/**< A section was declared without quotes, and had extra tokens */
   204 		SMCParse_InvalidSection2,	/**< A section was declared without any header */
   205 		SMCParse_InvalidSection3,	/**< A section ending was declared with too many unknown tokens */
   206 		SMCParse_InvalidSection4,	/**< A section ending has no matching beginning */
   207 		SMCParse_InvalidSection5,	/**< A section beginning has no matching ending */
   208 		SMCParse_InvalidTokens,		/**< There were too many unidentifiable strings on one line */
   209 		SMCParse_TokenOverflow,		/**< The token buffer overflowed */
   210 		SMCParse_InvalidProperty1,	/**< A property was declared outside of any section */
   211 	};
   212 
   213 	/**
   214 	 * @brief Describes the events available for reading an SMC stream.
   215 	 */
   216 	class ITextListener_SMC
   217 	{
   218 	public:
   219 		/**
   220 		 * @brief Called when starting parsing.
   221 		 */
   222 		virtual void ReadSMC_ParseStart()
   223 		{
   224 		};
   225 
   226 		/**
   227 		 * @brief Called when ending parsing.
   228 		 *
   229 		 * @param halted			True if abnormally halted, false otherwise.
   230 		 * @param failed			True if parsing failed, false otherwise.
   231 		 */
   232 		virtual void ReadSMC_ParseEnd(bool halted, bool failed)
   233 		{
   234 		}
   235 
   236 		/**
   237 		 * @brief Called when a warning occurs.
   238 		 * @param error				By-reference variable containing the error message of the warning.
   239 		 * @param tokens			Pointer to the token stream causing the error.
   240 		 * @return					SMCParseResult directive.
   241 		 */
   242 		virtual SMCParseResult ReadSMC_OnWarning(SMCParseError &error, const char *tokens)
   243 		{
   244 			return SMCParse_HaltFail;
   245 		}
   246 
   247 		/**
   248 		 * @brief Called when entering a new section
   249 		 *
   250 		 * @param name			Name of section, with the colon omitted.
   251 		 * @param opt_quotes	Whether or not the option string was enclosed in quotes.
   252 		 * @return				SMCParseResult directive.
   253 		 */
   254 		virtual SMCParseResult ReadSMC_NewSection(const char *name, bool opt_quotes)
   255 		{
   256 			return SMCParse_Continue;
   257 		}
   258 
   259 		/**
   260 		 * @brief Called when encountering a key/value pair in a section.
   261 		 * 
   262 		 * @param key			Key string.
   263 		 * @param value			Value string.  If no quotes were specified, this will be NULL, 
   264 								and key will contain the entire string.
   265 		 * @param key_quotes	Whether or not the key was in quotation marks.
   266 		 * @param value_quotes	Whether or not the value was in quotation marks.
   267 		 * @return				SMCParseResult directive.
   268 		 */
   269 		virtual SMCParseResult ReadSMC_KeyValue(const char *key, 
   270 												const char *value, 
   271 												bool key_quotes, 
   272 												bool value_quotes)
   273 		{
   274 			return SMCParse_Continue;
   275 		}
   276 
   277 		/**
   278 		 * @brief Called when leaving the current section.
   279 		 *
   280 		 * @return				SMCParseResult directive.
   281 		 */
   282 		virtual SMCParseResult ReadSMC_LeavingSection()
   283 		{
   284 			return SMCParse_Continue;
   285 		}
   286 
   287 		/**
   288 		 * @brief Called after an input line has been preprocessed.
   289 		 *
   290 		 * @param line			String containing line input.
   291 		 * @param curline		Number of line in file.
   292 		 * @return				SMCParseResult directive.
   293 		 */
   294 		virtual SMCParseResult ReadSMC_RawLine(const char *line, unsigned int curline)
   295 		{
   296 			return SMCParse_Continue;
   297 		}
   298 	};	
   299 
   300 	#define SMINTERFACE_TEXTPARSERS_NAME		"ITextParsers"
   301 	#define SMINTERFACE_TEXTPARSERS_VERSION		1
   302 
   303 	/**
   304 	 * @brief Contains various text stream parsing functions.
   305 	 */
   306 	class ITextParsers : public SMInterface
   307 	{
   308 	public:
   309 		virtual const char *GetInterfaceName()
   310 		{
   311 			return SMINTERFACE_TEXTPARSERS_NAME;
   312 		}
   313 		virtual unsigned int GetInterfaceVersion()
   314 		{
   315 			return SMINTERFACE_TEXTPARSERS_VERSION;
   316 		}
   317 	public:
   318 		/**
   319 		 * @brief Parses an INI-format file.
   320 		 *
   321 		 * @param file			Path to file.
   322 		 * @param ini_listener	Event handler for reading file.
   323 		 * @param line			If non-NULL, will contain last line parsed (0 if file could not be opened).
   324 		 * @param col			If non-NULL, will contain last column parsed (undefined if file could not be opened).
   325 		 * @return				True if parsing succeeded, false if file couldn't be opened or there was a syntax error.
   326 		 */
   327 		virtual bool ParseFile_INI(const char *file, 
   328 									ITextListener_INI *ini_listener,
   329 									unsigned int *line,
   330 									unsigned int *col) =0;
   331 
   332 		/**
   333 		 * @brief Parses an SMC-format text file.
   334 		 * Note that the parser makes every effort to obey broken syntax.
   335 		 * For example, if an open brace is missing, but the section name has a colon,
   336 		 * it will let you know.  It is up to the event handlers to decide whether to be strict or not.
   337 		 *
   338 		 * @param file			Path to file.
   339 		 * @param smc_listener	Event handler for reading file.
   340 		 * @param line			If non-NULL, will contain last line parsed (0 if file could not be opened).
   341 		 * @param col			If non-NULL, will contain last column parsed (undefined if file could not be opened).
   342 		 * @return				An SMCParseError result code.
   343 		 */
   344 		virtual SMCParseError ParseFile_SMC(const char *file, 
   345 									ITextListener_SMC *smc_listener, 
   346 									unsigned int *line, 
   347 									unsigned int *col) =0;
   348 
   349 		/**
   350 		 * @brief Converts an SMCParseError to a string.
   351 		 *
   352 		 * @param err			SMCParseError.
   353 		 * @return				String error message, or NULL if none.
   354 		 */
   355 		virtual const char *GetSMCErrorString(SMCParseError err) =0;
   356 
   357 	public:
   358 		/**
   359 		 * @brief Returns the number of bytes that a multi-byte character contains in a UTF-8 stream.
   360 		 * If the current character is not multi-byte, the function returns 1.
   361 		 *
   362 		 * @param stream		Pointer to multi-byte ANSI character string.
   363 		 * @return				Number of bytes in current character.
   364 		 */
   365 		virtual unsigned int GetUTF8CharBytes(const char *stream) =0;
   366 	};
   367 }
   368 
   369 #endif //_INCLUDE_SOURCEMOD_TEXTPARSERS_INTERFACE_H_