Commit 1adeecb1 authored by Milo Yip's avatar Milo Yip

Merge pull request #106 from pah/doc/config-error

Add Doxygen documentation for configuration macros and error handling
parents c0a7922d 1621ba3a
......@@ -764,7 +764,8 @@ WARN_LOGFILE =
# spaces.
# Note: If this tag is empty the current directory is searched.
INPUT = ./include/ \
INPUT = ./include/rapidjson/rapidjson.h \
./include/ \
./readme.md \
./doc/features.md \
./doc/tutorial.md \
......
......@@ -27,6 +27,7 @@ namespace rapidjson {
//! Maps error code of parsing into error message.
/*!
\ingroup RAPIDJSON_ERRORS
\param parseErrorCode Error code obtained in parsing.
\return the error message.
\note User can make a copy of this function for localization.
......
......@@ -21,12 +21,17 @@
#ifndef RAPIDJSON_ERROR_ERROR_H__
#define RAPIDJSON_ERROR_ERROR_H__
/*! \file error.h */
/*! \defgroup RAPIDJSON_ERRORS RapidJSON error handling */
///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_ERROR_CHARTYPE
//! Character type of error messages.
/*! The default charater type is char.
On Windows, user can define this macro as TCHAR for supporting both
/*! \ingroup RAPIDJSON_ERRORS
The default character type is \c char.
On Windows, user can define this macro as \c TCHAR for supporting both
unicode/non-unicode settings.
*/
#ifndef RAPIDJSON_ERROR_CHARTYPE
......@@ -36,9 +41,10 @@
///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_ERROR_STRING
//! Macro for converting string literial to RAPIDJSON_ERROR_CHARTYPE[].
/*! By default this conversion macro does nothing.
On Windows, user can define this macro as _T(x) for supporting both
//! Macro for converting string literial to \ref RAPIDJSON_ERROR_CHARTYPE[].
/*! \ingroup RAPIDJSON_ERRORS
By default this conversion macro does nothing.
On Windows, user can define this macro as \c _T(x) for supporting both
unicode/non-unicode settings.
*/
#ifndef RAPIDJSON_ERROR_STRING
......@@ -51,7 +57,8 @@ namespace rapidjson {
// ParseErrorCode
//! Error code of parsing.
/*! \see GenericReader::Parse, GenericReader::GetParseErrorCode
/*! \ingroup RAPIDJSON_ERRORS
\see GenericReader::Parse, GenericReader::GetParseErrorCode
*/
enum ParseErrorCode {
kParseErrorNone = 0, //!< No error.
......@@ -83,6 +90,7 @@ enum ParseErrorCode {
//! Result of parsing (wraps ParseErrorCode)
/*!
\ingroup RAPIDJSON_ERRORS
\code
Document doc;
ParseResult ok = doc.Parse("[42]");
......@@ -126,15 +134,15 @@ private:
};
//! Function pointer type of GetParseError().
/*! This is the prototype for GetParseError_X(), where X is a locale.
User can dynamically change locale in runtime, e.g.:
/*! \ingroup RAPIDJSON_ERRORS
This is the prototype for \c GetParseError_X(), where \c X is a locale.
User can dynamically change locale in runtime, e.g.:
\code
GetParseErrorFunc GetParseError = GetParseError_En; // or whatever
const RAPIDJSON_ERROR_CHARTYPE* s = GetParseError(document.GetParseErrorCode());
\endcode
*/
typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode);
} // namespace rapidjson
......
......@@ -27,7 +27,22 @@
/*!\file rapidjson.h
\brief common definitions and configuration
\todo Complete Doxygen documentation for configure macros.
\see RAPIDJSON_CONFIG
*/
/*! \defgroup RAPIDJSON_CONFIG RapidJSON configuration
\brief Configuration macros for library features
Some RapidJSON features are configurable to adapt the library to a wide
variety of platforms, environments and usage scenarios. Most of the
features can be configured in terms of overriden or predefined
preprocessor macros at compile-time.
Some additional customization is available in the \ref RAPIDJSON_ERRORS APIs.
\note These macros should be given on the compiler command-line
(where applicable) to avoid inconsistent values when compiling
different translation units of a single application.
*/
#include <cstdlib> // malloc(), realloc(), free()
......@@ -36,8 +51,16 @@
///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_NO_INT64DEFINE
// Here defines int64_t and uint64_t types in global namespace
// If user have their own definition, can define RAPIDJSON_NO_INT64DEFINE to disable this.
/*! \def RAPIDJSON_NO_INT64DEFINE
\ingroup RAPIDJSON_CONFIG
\brief Use external 64-bit integer types.
RapidJSON requires the 64-bit integer types \c int64_t and \c uint64_t types
to be available at global scope.
If users have their own definition, define RAPIDJSON_NO_INT64DEFINE to
prevent RapidJSON from defining its own types.
*/
#ifndef RAPIDJSON_NO_INT64DEFINE
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
#ifdef _MSC_VER
......@@ -49,12 +72,16 @@
#include <inttypes.h>
#endif
//!@endcond
#ifdef RAPIDJSON_DOXYGEN_RUNNING
#define RAPIDJSON_NO_INT64DEFINE
#endif
#endif // RAPIDJSON_NO_INT64TYPEDEF
///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_FORCEINLINE
#ifndef RAPIDJSON_FORCEINLINE
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
#ifdef _MSC_VER
#define RAPIDJSON_FORCEINLINE __forceinline
#elif defined(__GNUC__) && __GNUC__ >= 4
......@@ -62,6 +89,7 @@
#else
#define RAPIDJSON_FORCEINLINE
#endif
//!@endcond
#endif // RAPIDJSON_FORCEINLINE
///////////////////////////////////////////////////////////////////////////////
......@@ -70,13 +98,17 @@
#define RAPIDJSON_BIGENDIAN 1 //!< Big endian machine
//! Endianness of the machine.
/*! GCC 4.6 provided macro for detecting endianness of the target machine. But other
/*!
\def RAPIDJSON_ENDIAN
\ingroup RAPIDJSON_CONFIG
GCC 4.6 provided macro for detecting endianness of the target machine. But other
compilers may not have this. User can define RAPIDJSON_ENDIAN to either
\ref RAPIDJSON_LITTLEENDIAN or \ref RAPIDJSON_BIGENDIAN.
Implemented with reference to
https://gcc.gnu.org/onlinedocs/gcc-4.6.0/cpp/Common-Predefined-Macros.html
http://www.boost.org/doc/libs/1_42_0/boost/detail/endian.hpp
Default detection implemented with reference to
\li https://gcc.gnu.org/onlinedocs/gcc-4.6.0/cpp/Common-Predefined-Macros.html
\li http://www.boost.org/doc/libs/1_42_0/boost/detail/endian.hpp
*/
#ifndef RAPIDJSON_ENDIAN
// Detect with GCC 4.6's macro
......@@ -108,18 +140,22 @@
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
# elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__)
# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
# elif defined(RAPIDJSON_DOXYGEN_RUNNING)
# define RAPIDJSON_ENDIAN
# else
# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.
# endif
#endif // RAPIDJSON_ENDIAN
///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_ALIGNSIZE
// RAPIDJSON_ALIGN
//! Data alignment of the machine.
/*!
Some machine requires strict data alignment.
Currently the default uses 4 bytes alignment. User can customize this.
/*! \ingroup RAPIDJSON_CONFIG
\param x pointer to align
Some machines require strict data alignment. Currently the default uses 4 bytes
alignment. User can customize by defining the RAPIDJSON_ALIGN function macro.,
*/
#ifndef RAPIDJSON_ALIGN
#define RAPIDJSON_ALIGN(x) ((x + 3u) & ~3u)
......@@ -141,13 +177,30 @@
///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_SIMD
// Enable SSE2 optimization.
//#define RAPIDJSON_SSE2
/*! \def RAPIDJSON_SIMD
\ingroup RAPIDJSON_CONFIG
\brief Enable SSE2/SSE4.2 optimization.
RapidJSON supports optimized implementations for some parsing operations
based on the SSE2 or SSE4.2 SIMD extensions on modern Intel-compatible
processors.
To enable these optimizations, two different symbols can be defined;
\code
// Enable SSE2 optimization.
#define RAPIDJSON_SSE2
// Enable SSE4.2 optimization.
//#define RAPIDJSON_SSE42
// Enable SSE4.2 optimization.
#define RAPIDJSON_SSE42
\endcode
#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
\c RAPIDJSON_SSE42 takes precedence, if both are defined.
If any of these symbols is defined, RapidJSON defines the macro
\c RAPIDJSON_SIMD to indicate the availability of the optimized code.
*/
#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) \
|| defined(RAPIDJSON_DOXYGEN_RUNNING)
#define RAPIDJSON_SIMD
#endif
......@@ -155,9 +208,29 @@
// RAPIDJSON_NO_SIZETYPEDEFINE
#ifndef RAPIDJSON_NO_SIZETYPEDEFINE
/*! \def RAPIDJSON_NO_SIZETYPEDEFINE
\ingroup RAPIDJSON_CONFIG
\brief User-provided \c SizeType definition.
In order to avoid using 32-bit size types for indexing strings and arrays,
define this preprocessor symbol and provide the type rapidjson::SizeType
before including RapidJSON:
\code
#define RAPIDJSON_NO_SIZETYPEDEFINE
namespace rapidjson { typedef ::std::size_t SizeType; }
#include "rapidjson/..."
\endcode
\see rapidjson::SizeType
*/
#ifdef RAPIDJSON_DOXYGEN_RUNNING
#define RAPIDJSON_NO_SIZETYPEDEFINE
#endif
namespace rapidjson {
//! Use 32-bit array/string indices even for 64-bit platform, instead of using size_t.
/*! User may override the SizeType by defining RAPIDJSON_NO_SIZETYPEDEFINE.
//! Size type (for string lengths, array sizes, etc.)
/*! RapidJSON uses 32-bit array/string indices even on 64-bit platforms,
instead of using \c size_t. Users may override the SizeType by defining
\ref RAPIDJSON_NO_SIZETYPEDEFINE.
*/
typedef unsigned SizeType;
} // namespace rapidjson
......@@ -167,8 +240,12 @@ typedef unsigned SizeType;
// RAPIDJSON_ASSERT
//! Assertion.
/*! By default, rapidjson uses C assert() for assertion.
/*! \ingroup RAPIDJSON_CONFIG
By default, rapidjson uses C \c assert() for internal assertions.
User can override it by defining RAPIDJSON_ASSERT(x) macro.
\note Parsing errors are handled and can be customized by the
\ref RAPIDJSON_ERRORS APIs.
*/
#ifndef RAPIDJSON_ASSERT
#include <cassert>
......@@ -200,7 +277,7 @@ template<int x> struct StaticAssertTest {};
//!@endcond
/*! \def RAPIDJSON_STATIC_ASSERT
\brief (internal) macro to check for conditions at compile-time
\brief (Internal) macro to check for conditions at compile-time
\param x compile-time condition
\hideinitializer
*/
......
......@@ -21,8 +21,7 @@
#ifndef RAPIDJSON_READER_H_
#define RAPIDJSON_READER_H_
// Copyright (c) 2011 Milo Yip (miloyip@gmail.com)
// Version 0.1
/*! \file reader.h */
#include "rapidjson.h"
#include "encodings.h"
......@@ -46,6 +45,7 @@ RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
RAPIDJSON_DIAG_OFF(4702) // unreachable code
#endif
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
#define RAPIDJSON_NOTHING /* deliberately empty */
#ifndef RAPIDJSON_PARSE_ERROR_EARLY_RETURN
#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN(value) \
......@@ -55,15 +55,57 @@ RAPIDJSON_DIAG_OFF(4702) // unreachable code
#endif
#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID \
RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
//!@endcond
/*! \def RAPIDJSON_PARSE_ERROR_NORETURN
\ingroup RAPIDJSON_ERRORS
\brief Macro to indicate a parse error.
\param parseErrorCode \ref rapidjson::ParseErrorCode of the error
\param offset position of the error in JSON input (\c size_t)
This macros can be used as a customization point for the internal
error handling mechanism of RapidJSON.
A common usage model is to throw an exception instead of requiring the
caller to explicitly check the \ref rapidjson::GenericReader::Parse's
return value:
\code
#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode,offset) \
throw ParseException(parseErrorCode, #parseErrorCode, offset)
#include <stdexcept> // std::runtime_error
#include "rapidjson/error/error.h" // rapidjson::ParseResult
struct ParseException : std::runtime_error, rapidjson::ParseResult {
ParseException(rapidjson::ParseErrorCode code, const char* msg, size_t offset)
: std::runtime_error(msg), ParseResult(code, offset) {}
};
#include "rapidjson/reader.h"
\endcode
\see RAPIDJSON_PARSE_ERROR, rapidjson::GenericReader::Parse
*/
#ifndef RAPIDJSON_PARSE_ERROR_NORETURN
#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset) \
RAPIDJSON_MULTILINEMACRO_BEGIN \
RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
parseResult_.Set(parseErrorCode,offset); \
SetParseError(parseErrorCode, offset); \
RAPIDJSON_MULTILINEMACRO_END
#endif
/*! \def RAPIDJSON_PARSE_ERROR
\ingroup RAPIDJSON_ERRORS
\brief (Internal) macro to indicate and handle a parse error.
\param parseErrorCode \ref rapidjson::ParseErrorCode of the error
\param offset position of the error in JSON input (\c size_t)
Invokes RAPIDJSON_PARSE_ERROR_NORETURN and stops the parsing.
\see RAPIDJSON_PARSE_ERROR_NORETURN
\hideinitializer
*/
#ifndef RAPIDJSON_PARSE_ERROR
#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset) \
RAPIDJSON_MULTILINEMACRO_BEGIN \
......@@ -421,6 +463,9 @@ public:
//! Get the position of last parsing error in input, 0 otherwise.
size_t GetErrorOffset() const { return parseResult_.Offset(); }
protected:
void SetParseError(ParseErrorCode code, size_t offset) { parseResult_.Set(code, offset); }
private:
// Prohibit copy constructor & assignment operator.
GenericReader(const GenericReader&);
......@@ -632,6 +677,7 @@ private:
// This function handles the prefix/suffix double quotes, escaping, and optional encoding validation.
template<unsigned parseFlags, typename SEncoding, typename TEncoding, typename InputStream, typename OutputStream>
RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) {
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
static const char escape[256] = {
Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/',
......@@ -641,6 +687,7 @@ private:
Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
};
#undef Z16
//!@endcond
RAPIDJSON_ASSERT(is.Peek() == '\"');
is.Take(); // Skip '\"'
......@@ -933,6 +980,8 @@ private:
};
RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) {
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
#define N NumberToken
#define N16 N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N
// Maps from ASCII to Token
......@@ -949,6 +998,7 @@ private:
};
#undef N
#undef N16
//!@endcond
if (sizeof(Ch) == 1 || unsigned(c) < 256)
return (Token)tokenMap[(unsigned char)c];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment