Commit f94fc702 authored by Jens Gustedt's avatar Jens Gustedt
Browse files

add documentation of macro parameters

by that we can now better check automatically if there are macro
arguments that get evaluated multiple times although they shouldn't

in many cases this will result in a better documentation of the
properties in doxygen
parent 0193eea2
......@@ -616,7 +616,7 @@ EXCLUDE_SYMLINKS = NO
# against the file with absolute path, so to exclude all test directories
# for example use the pattern */test/*
EXCLUDE_PATTERNS =
EXCLUDE_PATTERNS = p99_all.*
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the
......
......@@ -35,6 +35,7 @@ EXCLUDE_SYMBOLS += P99_IS_EQ_*
# A set of macros that are just too complicated that doxygen can make
# something reasonable out of them.
PREDEFINED += DOXYGEN
PREDEFINED += P00_DOXYGEN
PREDEFINED += P99_COMPILETIME_ASSERT(x)=
PREDEFINED += P99_BUILTIN_TYPE(x,y)="P00_BUILTIN_TYPE_ ## x ## y"
PREDEFINED += P99_BUILTIN_MAX(x)="P00_BUILTIN_MAX_ ## x"
......@@ -86,13 +87,20 @@ EXPAND_AS_DEFINED += P00_BUILTIN_TYPE_uz
EXPAND_AS_DEFINED += P00_BUILTIN_TYPE_v
EXPAND_AS_DEFINED += P00_C99_DEFARG_DOCU
EXPAND_AS_DEFINED += P00_DECLARE_ARI2STR
EXPAND_AS_DEFINED += P00_DECLARE_STRTO
EXPAND_AS_DEFINED += P00_DECLARE_STRTOU
EXPAND_AS_DEFINED += P00_DECLARE_OVERFLOW
EXPAND_AS_DEFINED += P00_DECLARE_SC
EXPAND_AS_DEFINED += P00_DECLARE_STRTO
EXPAND_AS_DEFINED += P00_DECLARE_STRTOU
EXPAND_AS_DEFINED += P00_DOCUMENT_DECLARATION_ARGUMENT
EXPAND_AS_DEFINED += P00_DOCUMENT_ID
EXPAND_AS_DEFINED += P00_DOCUMENT_MACRO_ARGUMENT
EXPAND_AS_DEFINED += P00_DOCUMENT_MULTIPLE_ARGUMENT
EXPAND_AS_DEFINED += P00_DOCUMENT_NUMBER_ARGUMENT
EXPAND_AS_DEFINED += P00_DOCUMENT_PERMITTED_ARGUMENT
EXPAND_AS_DEFINED += P00_DOCUMENT_PROMOTE
EXPAND_AS_DEFINED += P00_DOCUMENT_SIGNED
EXPAND_AS_DEFINED += P00_DOCUMENT_STATEMENT_ARGUMENT
EXPAND_AS_DEFINED += P00_DOCUMENT_TYPE_ARGUMENT
EXPAND_AS_DEFINED += P00_DOCUMENT_UNSIGNED
EXPAND_AS_DEFINED += P00_IF_CLAUSE
EXPAND_AS_DEFINED += P00_ORWL_ALIAS
......
......@@ -74,7 +74,7 @@ P99_PREFER( \
#ifdef DOXYGEN
#ifdef P00_DOXYGEN
/**
** @brief A meta-macro to protect a dependent block or statement by
** statement @a BEFORE that is executed before the block and @a AFTER
......@@ -135,6 +135,9 @@ P00_BLK_END
** @see P99_UNWIND to break through one or several nested guarded blocks
** @see P99_UNWIND_RETURN to return from the enclosing function
**/
P00_DOCUMENT_TYPE_ARGUMENT(P99_GUARDED_BLOCK, 0)
P00_DOCUMENT_DECLARATION_ARGUMENT(P99_GUARDED_BLOCK, 1)
P00_DOCUMENT_STATEMENT_ARGUMENT(P99_GUARDED_BLOCK, 4)
#define P99_GUARDED_BLOCK(T, NAME, INITIAL, BEFORE, AFTER) \
P00_BLK_START \
P00_BLK_DECL_REC(T, NAME, P00_ROBUST(INITIAL)) \
......@@ -553,6 +556,7 @@ P00_BLK_START \
** dependent block.
** @headerfile p99_c99.h "p99_c99.h"
**/
P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_INVARIANT, 0)
P99_BLOCK_DOCUMENT
#define P99_INVARIANT(EXPR) \
P99_PROTECTED_BLOCK(assert((EXPR) && "failed on entry"), assert((EXPR) && "failed on leave"))
......
......@@ -25,8 +25,8 @@
#define P00_PREFIX0(N) P00_PREFIX0_(N)
#define P00_PREFIX0_(N) 0 ## N
#define P00_STRINGIFY(X) #X
#define P99_STRINGIFY(X) P00_STRINGIFY(X)
#define P00_STRINGIFY(...) #__VA_ARGS__
#define P99_STRINGIFY(...) P00_STRINGIFY(__VA_ARGS__)
/* be sure to put all compilers that are faking gcc before gcc itself */
#if P99_COMPILER & P99_COMPILER_CLANG
......
......@@ -69,6 +69,7 @@
#ifdef P00_DOXYGEN
# define P99_CALL_DEFARG(NAME, M, ...) NAME(__VA_ARGS__)
#else
P00_DOCUMENT_NUMBER_ARGUMENT(P99_CALL_DEFARG, 1)
# define P99_CALL_DEFARG(NAME, M, ...) \
NAME(P99_IF_EQ(0,M) \
(__VA_ARGS__) \
......@@ -165,6 +166,8 @@ NAME(P99_IF_EQ(0,M) \
** @see P99_INSTANTIATE if your function is @c inline and thus you
** also have to provide an external symbol for the function.
**/
P00_DOCUMENT_TYPE_ARGUMENT(P99_PROTOTYPE, 0)
P00_DOCUMENT_TYPE_ARGUMENT(P99_PROTOTYPE, 2)
#ifdef P00_DOXYGEN
#define P00_PROTOTYPE(RT, NAME, ...) \
......@@ -391,6 +394,7 @@ P99_MACRO_END(NAME, _declare_defarg)
**/
#define P99_CALL_VA_ARG(NAME, M, T, ...) NAME(__VA_ARGS__)
#else
P00_DOCUMENT_NUMBER_ARGUMENT(P99_CALL_VA_ARG, 1)
#define P99_CALL_VA_ARG(NAME, M, T, ...) \
P99_IF_GT(P99_NARG(__VA_ARGS__), M) \
(NAME(P00__DEFARGS(NAME, M, P99_SELS(M, __VA_ARGS__)), P00_CALL_VA_ARG(NAME, T, P99_SKP(M, __VA_ARGS__)))) \
......
......@@ -59,6 +59,9 @@
**/
#define P99_DEC_DOUBLE(SIGN, INT, FRAC, ESIGN, EXP)
#else
P00_DOCUMENT_NUMBER_ARGUMENT(P99_DEC_DOUBLE, 1)
P00_DOCUMENT_NUMBER_ARGUMENT(P99_DEC_DOUBLE, 2)
P00_DOCUMENT_NUMBER_ARGUMENT(P99_DEC_DOUBLE, 4)
#define P99_DEC_DOUBLE(...) \
P99_IF_GE(P99_NARG(__VA_ARGS__), 6) \
(P00_DEC_DOUBLE(__VA_ARGS__)) \
......@@ -85,6 +88,9 @@
**/
#define P99_HEX_DOUBLE(SIGN, HEXINT, HEXFRAC, ESIGN, BINEXP)
#else
P00_DOCUMENT_NUMBER_ARGUMENT(P99_HEX_DOUBLE, 1)
P00_DOCUMENT_NUMBER_ARGUMENT(P99_HEX_DOUBLE, 2)
P00_DOCUMENT_NUMBER_ARGUMENT(P99_HEX_DOUBLE, 4)
#define P99_HEX_DOUBLE(...) \
P99_IF_GE(P99_NARG(__VA_ARGS__), 6) \
(P00_HEX_DOUBLE(__VA_ARGS__)) \
......
......@@ -22,7 +22,7 @@
#define P00_ENUM_CASE(NAME, X, I) case X: return P99_STRINGIFY(X)
#ifdef DOXYGEN
#ifdef P00_DOXYGEN
/**
** @brief Declare a simple inline function to return strings
** containing the names of enumeration constants.
......@@ -31,6 +31,10 @@
/*! @brief Get a string with the name of constant @a x of type T */ \
inline char const* P99_PASTE2(T, _getname)(T x)...
#else
P00_DOCUMENT_TYPE_ARGUMENT(P99_DECLARE_ENUM_GETNAME, 0)
P00_DOCUMENT_DECLARATION_ARGUMENT(P99_DECLARE_ENUM_GETNAME, 1)
P00_DOCUMENT_DECLARATION_ARGUMENT(P99_DECLARE_ENUM_GETNAME, 2)
P00_DOCUMENT_DECLARATION_ARGUMENT(P99_DECLARE_ENUM_GETNAME, 3)
#define P99_DECLARE_ENUM_GETNAME(T, ...) \
p99_inline \
char const* P99_PASTE2(T, _getname)(T x) { \
......@@ -79,6 +83,10 @@ P99_MACRO_END(declare_enum_getname, T)
** to prefix it with `color' such that the documentation lands inside
** the one for `color'.
**/
P00_DOCUMENT_TYPE_ARGUMENT(P99_DECLARE_ENUM, 0)
P00_DOCUMENT_DECLARATION_ARGUMENT(P99_DECLARE_ENUM, 1)
P00_DOCUMENT_DECLARATION_ARGUMENT(P99_DECLARE_ENUM, 2)
P00_DOCUMENT_DECLARATION_ARGUMENT(P99_DECLARE_ENUM, 3)
#define P99_DECLARE_ENUM(T, ...) \
/*! @see P99_DECLARE_ENUM was used for the declaration of this enumeration type */ \
/*! @see T ## _getname for access to the names of the constants as strings */ \
......
......@@ -76,6 +76,9 @@
** ((((a) + (b))) + (c))
** @endcode
**/
P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_FOR, 0)
P00_DOCUMENT_NUMBER_ARGUMENT(P99_FOR, 1)
P00_DOCUMENT_MACRO_ARGUMENT(P99_FOR, 3)
#define P99_FOR(NAME, N, OP, FUNC, ...) P99_PASTE2(P00_FOR, N)(NAME, OP, FUNC, __VA_ARGS__)
#define P00_IGN(NAME, X, I)
......@@ -102,6 +105,7 @@
/**
** @brief generate lists of names of the form <code>NAME0, NAME1, ...</code>
**/
P00_DOCUMENT_NUMBER_ARGUMENT(P99_NAME, 0)
#define P99_NAME(N, NAME) P99_FOR(NAME, N, P00_SEQ, P00_NAME_I, P99_REP(N,))
#define P00_FUNC(NAME, I, REC, X) NAME(REC, X)
......@@ -116,6 +120,7 @@
**
** @a M is the length of the list that follows it.
**/
P00_DOCUMENT_NUMBER_ARGUMENT(P99_BIGOP, 1)
#define P99_BIGOP(OP, M, ...) P99_FOR( , M, OP, P00_IDT, __VA_ARGS__)
/**
......@@ -125,6 +130,7 @@
**
** @a M is the length of the list that follows it.
**/
P00_DOCUMENT_NUMBER_ARGUMENT(P99_BIGFUNC, 1)
#define P99_BIGFUNC(FUNC, M, ...) P99_FOR(FUNC, M, P00_FUNC, P00_IDT, __VA_ARGS__)
/**
......@@ -228,6 +234,7 @@
** P99_CDIM(D, k0, k1, k2) => ((k2) + ((D)[2] * ((k1) + ((D)[1] * (k0)))))
** @endcode
**/
P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_CDIM, 0)
#define P99_CDIM(NAME, ...) P00_CDIM(P99_NARG(__VA_ARGS__), NAME, __VA_ARGS__)
......@@ -253,13 +260,15 @@
/sizeof(char[((!(sizeof(NAME) % sizeof((NAME)[0])))<<1)-1]))
#define P00_ALEN(NAME, _1, I) P99_IF_EQ_0(I)(P00_ALEN0(NAME))(P00_ALEN0((NAME)P99_REP(I,[0])))
#define P00_ALEN2(NAME, I) P00_ALEN(NAME,,I)
#define P00_ALEN2_(NAME, I, ...) P00_ALEN(NAME,,I)
#define P00_ALEN2(NAME, ...) P00_ALEN2_(NAME, __VA_ARGS__,)
#define P00_ALENS0(NAME, I, REC, _3) REC, P00_ALEN(NAME,,I)
/**
** @brief Produce a list of the lengths of the argument array @a ARR in terms of number
** of elements in the first @a N dimensions.
**/
P00_DOCUMENT_NUMBER_ARGUMENT(P99_ALENS, 1)
#define P99_ALENS(X, N) P99_FOR(X, N, P00_ALENS0, P00_ALEN, P99_REP(N,))
#define P00_ACALL1(ARR) P99_ALENS(*ARR, 1), (ARR)
......@@ -268,7 +277,7 @@
the matrix are assignment compatible to pointers of the indicated type.
Then we do the cast to the pointer to matrix type that would
otherwise be dangerous and could hide incompatibilities. */
#define P00_ACALL3(ARR, N, TYPE) P99_ALENS(*ARR, N), ((void)(TYPE*){ &((*ARR)P99_REP(N,[0])) }, (TYPE (*)P99_REP(N,[1]))(ARR))
#define P00_ACALL3(ARR, N, TYPE) P99_ALENS(*ARR, N), ((TYPE (*const)P99_REP(N,[1]))(TYPE*const){ &((*ARR)P99_REP(N,[0])) })
/* transform a list of names into size_t declarations */
#define P00_AARG_DECL(NAME, X, I) size_t const X
......@@ -283,7 +292,7 @@
#define P00_AARG_3(T, ARR, DIM) P00_AARG(T, ARR, DIM, P99_PASTE(p00_aarg_, ARR))
#define P00_AARG_2(T, ARR) P00_AARG_3(T, ARR, 1)
#ifdef DOXYGEN
#ifdef P00_DOXYGEN
/**
** @brief Produce the length of the argument array @a ARR in terms of number
** of elements.
......@@ -364,8 +373,13 @@
#define P99_AARG(TYPE, NAME, DIM, VAR)
#else
P00_DOCUMENT_NUMBER_ARGUMENT(P99_ALENS, 1)
#define P99_ALEN(...) P99_IF_EQ_1(P99_NARG(__VA_ARGS__))(P00_ALEN(__VA_ARGS__, ,0))(P00_ALEN2(__VA_ARGS__))
P00_DOCUMENT_NUMBER_ARGUMENT(P99_ACALL, 1)
P00_DOCUMENT_TYPE_ARGUMENT(P99_ACALL, 2)
#define P99_ACALL(...) P99_PASTE2(P00_ACALL, P99_NARG(__VA_ARGS__))(__VA_ARGS__)
P00_DOCUMENT_TYPE_ARGUMENT(P99_AARG, 0)
P00_DOCUMENT_NUMBER_ARGUMENT(P99_AARG, 2)
#define P99_AARG(...) P99_IF_GT(P99_NARG(__VA_ARGS__),3)(P00_AARG(__VA_ARGS__))(P99_PASTE2(P00_AARG_, P99_NARG(__VA_ARGS__))(__VA_ARGS__))
#endif
......@@ -412,7 +426,7 @@ P99_PRAGMA(PRAG)
P00_BLK_START \
P00_BLK_BEFORE(TYPE const VAR = P99_PASTE2(p00_i_, VAR))
#ifdef DOXYGEN
#ifdef P00_DOXYGEN
/**
** @ingroup preprocessor_blocks
** @brief A fortran like do-loop with bounds that are fixed at the
......@@ -478,12 +492,15 @@ P99_PRAGMA(PRAG)
**/
#define P99_PRAGMA_DO(PRAG, TYPE, VAR, LOW, LEN, INCR) for(;;)
#else
#define P99_DO(...) P99_PRAGMA_DO(, __VA_ARGS__)
#define P99_PARALLEL_DO(...) P99_PRAGMA_DO(P99_PARALLEL_PRAGMA, __VA_ARGS__)
#define P99_PRAGMA_DO(...) \
P99_IF_EQ(P99_NARG(__VA_ARGS__), 5) \
(P00_PRAGMA_DO(__VA_ARGS__, 1)) \
(P00_PRAGMA_DO(__VA_ARGS__))
P00_DOCUMENT_TYPE_ARGUMENT(P99_DO, 0)
#define P99_DO(TYPE, VAR, ...) P99_PRAGMA_DO(, TYPE, VAR, __VA_ARGS__)
P00_DOCUMENT_TYPE_ARGUMENT(P99_PARALLEL_DO, 0)
#define P99_PARALLEL_DO(TYPE, VAR, ...) P99_PRAGMA_DO(P99_PARALLEL_PRAGMA, TYPE, VAR, __VA_ARGS__)
P00_DOCUMENT_TYPE_ARGUMENT(P99_PRAGMA_DO, 1)
#define P99_PRAGMA_DO(PRAG, TYPE, VAR, ...) \
P99_IF_EQ(P99_NARG(__VA_ARGS__), 2) \
(P00_PRAGMA_DO(PRAG, TYPE, VAR, __VA_ARGS__, 1)) \
(P00_PRAGMA_DO(PRAG, TYPE, VAR, __VA_ARGS__))
#endif
#define P00_FORALL_OP(NAME, I, REC, X) REC X
......@@ -531,6 +548,7 @@ P99_IF_EQ(P99_NARG(__VA_ARGS__), 5) \
** @see P99_CDIM for a macro that computes the absolute position of a
** index N-tuple in a multi-dimensional array.
**/
P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_FORALL, 0)
#define P99_FORALL(NAME, ...) P00_FORALL(P99_NARG(__VA_ARGS__), NAME, __VA_ARGS__)
#define P00_PARALLEL_FORALL_FUNC(NAME, X, I) P99_PARALLEL_DO(size_t, X, 0, (NAME)[I])
......@@ -552,6 +570,7 @@ P99_IF_EQ(P99_NARG(__VA_ARGS__), 5) \
** @see P99_CDIM for a macro that computes the absolute position of a
** index N-tuple in a multi-dimensional array.
**/
P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_PARALLEL_FORALL, 0)
#define P99_PARALLEL_FORALL(NAME, ...) P00_PARALLEL_FORALL(P99_NARG(__VA_ARGS__), NAME, __VA_ARGS__)
......@@ -570,7 +589,7 @@ if (0) { \
matched */ \
P99_LINEID(__VA_ARGS__)
#ifdef DOXYGEN
#ifdef P00_DOXYGEN
/**
** @ingroup preprocessor_blocks
** @brief implement a range syntax for case labels.
......@@ -609,6 +628,8 @@ if (0) { \
**/
#define P99_CASERANGE(START, LEN, ...)
#else
P00_DOCUMENT_PERMITTED_ARGUMENT(P99_CASERANGE, 0)
P00_DOCUMENT_NUMBER_ARGUMENT(P99_CASERANGE, 1)
#define P99_CASERANGE(START, ...) P00_CASERANGE(START, __VA_ARGS__, _caselabel)
#endif
......
......@@ -202,6 +202,7 @@ typedef extendedInt p99x_int128;
**
** The returning expression is of type @c uintmax_t
**/
P00_DOCUMENT_MACRO_ARGUMENT(P99_TO_UNSIGNED, 1)
#define P99_TO_UNSIGNED(T, MACRO) \
((uintmax_t) \
(sizeof(T) < sizeof(signed) \
......@@ -312,6 +313,7 @@ P00_DOCUMENT_UNSIGNED(3)
** @see P99_SIGNED for a similar macro that takes an expression as an
** argument
**/
P00_DOCUMENT_TYPE_ARGUMENT(P99_ISSIGNED, 0)
#define P99_ISSIGNED(T) (P99_M1(T) < P99_0(T))
/**
......@@ -564,6 +566,7 @@ typedef enum {
** significant bits of -1 represented in @a T.
** @see ::p99_signed_representation
**/
P00_DOCUMENT_TYPE_ARGUMENT(P99_SIGNED_REPRESENTATION, 0)
#define P99_SIGNED_REPRESENTATION(T) ((p99_signed_representation)(P99_M1(T) & P99_3(T)))
......@@ -577,6 +580,7 @@ typedef enum {
/**
** @brief Give the maximum representable value of type @a T
**/
P00_DOCUMENT_TYPE_ARGUMENT(P99_TMAX, 0)
#define P99_TMAX(T) \
((T) \
(P99X__SHIFT((T)0) \
......@@ -586,6 +590,7 @@ typedef enum {
/**
** @brief Give the minimum representable value of type @a T
**/
P00_DOCUMENT_TYPE_ARGUMENT(P99_TMIN, 0)
#define P99_TMIN(T) \
((T) \
(P99X__SHIFT((T)0) \
......@@ -667,7 +672,7 @@ P99_SIGN_PROMOTE(P99_E_REPRESENTATION(EXPR) == p99_signed_representation_twos, (
**/
#define P99_TPADDING(T) ((sizeof(T)*CHAR_BIT) - P99_TWIDTH(T))
#ifdef DOXYGEN
#ifdef P00_DOXYGEN
#define P00_DECLARE_OVERFLOW(SUFF) \
/*! @brief Cast an unsigned type into a signed one as would do a two's complement representation of the signed type. */ \
/*! If the signed type is in usual two's complement this should be the identity. For other cases this is supposed to do the best possible. */ \
......@@ -839,13 +844,13 @@ P00_DECLARE_OVERFLOW(ll);
: cl) \
: cll))
#define P99_PRI(xT, F, ...) \
#define P99_PRI(xT, F, LEN) \
P99_CHOOSE5(xT, \
"%" #__VA_ARGS__ "hh" #F, \
"%" #__VA_ARGS__ "h" #F, \
"%" #__VA_ARGS__ "" #F, \
"%" #__VA_ARGS__ "l" #F, \
"%" #__VA_ARGS__ "ll" #F)
"%" #LEN "hh" #F, \
"%" #LEN "h" #F, \
"%" #LEN "" #F, \
"%" #LEN "l" #F, \
"%" #LEN "ll" #F)
/**
** @brief Promote integer expression @a x to the width of @c
......
......@@ -94,6 +94,9 @@
** - If the argument list has just one element which is empty, the
** token is produced.
**/
P00_DOCUMENT_NUMBER_ARGUMENT(P99_REP, 0)
P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_REP, 1)
P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_REP, 2)
#define P99_REP(...) P99_PASTE2(P00_REP_0_, P99_IS_LT(P99_NARG(__VA_ARGS__), 2))(__VA_ARGS__)
#define P00_REP_0_0(...) P00_REP(__VA_ARGS__)
......
......@@ -53,9 +53,9 @@
** @a N must be a decimal constant without suffixes. The value @c 0
** is special in that it evaluates to a @c 1 that is promoted to the
** promoted type of @a X.
**
** @warning @a X is evaluated @a N times, so it should not have side effects.
**/
P00_DOCUMENT_NUMBER_ARGUMENT(P99_IPOW, 0)
P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_IPOW, 1)
#define P99_IPOW(N, X) P99_IF_EQ(N,0)(P99_SIGN_PROMOTE(1, X))((P99_FOR(X, N, P00_POW, P00_POW0, P99_REP(N,))))
/**
......@@ -146,12 +146,16 @@ p00_strcat_terminate \
** each of the arguments twice; once to compute the overall length of
** the new string and then for the duplication operation.
**/
P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_STRDUP, 0)
P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_STRDUP, 1)
P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_STRDUP, 2)
#define P99_STRDUP(...) P99_STRCATS(memset(malloc(P99_STRLENS(__VA_ARGS__) + 1), 0, 1), __VA_ARGS__)
/**
** @brief Produce a list of length @a N that has the contents of 0,
** 1, , @a N-1
**/
P00_DOCUMENT_NUMBER_ARGUMENT(P99_POSS, 0)
#define P99_POSS(N) P99_FOR(,N, P00_SEQ, P00_POS,)
/**
......@@ -159,6 +163,8 @@ p00_strcat_terminate \
** X [1], ,
** @a X[@a N-1]
**/
P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_ACCESSORS, 0)
P00_DOCUMENT_NUMBER_ARGUMENT(P99_ACCESSORS, 1)
#define P99_ACCESSORS(X, N) P99_FOR(X, N, P00_SEQ, P00_ACCESSOR, )
......@@ -169,6 +175,7 @@ p00_strcat_terminate \
** NAME[0], @c V1 = @a NAME[1], ..., @c VN-1 = @a NAME[@a N-1], where
** V0, etc are the remaining arguments.
**/
P00_DOCUMENT_MULTIPLE_ARGUMENT(P99_VASSIGNS, 0)
#define P99_VASSIGNS(NAME, ...) \
P99_IF_LT(P99_NARG(__VA_ARGS__),2) \
(P99_IF_VOID(__VA_ARGS__)((void)0)(__VA_ARGS__ = (NAME)[0])) \
......
......@@ -80,6 +80,15 @@
#define P99_PASTE6(_1, _2, _3, _4, _5, _6) \
P99_PASTE2(P99_PASTE5(_1, _2, _3, _4, _5), _6)
#ifndef P00_DOCUMENT_MULTIPLE_ARGUMENT
#define P00_DOCUMENT_TYPE_ARGUMENT(MACRO, N) /*! @remark argument N of MACRO should correspond to a type */
#define P00_DOCUMENT_MULTIPLE_ARGUMENT(MACRO, N) /*! @warning argument N of MACRO may be evaluated multiple times */
#define P00_DOCUMENT_PERMITTED_ARGUMENT(MACRO, N)
#define P00_DOCUMENT_STATEMENT_ARGUMENT(MACRO, N)
#define P00_DOCUMENT_DECLARATION_ARGUMENT(MACRO, N)
#define P00_DOCUMENT_MACRO_ARGUMENT(MACRO, N) /*! @remark argument N of MACRO should correspond to a macro name */
#define P00_DOCUMENT_NUMBER_ARGUMENT(MACRO, N) /*! @remark argument N of MACRO must expand to a decimal number */
#endif
/**
** @}
......
......@@ -46,7 +46,7 @@ P99_MACRO_END(P00_DEFINE_STR3, CODE)
#define P00_STR3_0(NAME, X, I) P00_DEFINE_STR3(X)
#define P00_STR3_1(...) P99_FOR(, P99_NARG(__VA_ARGS__), P00_SEP, P00_STR3_0, __VA_ARGS__)
#ifndef DOXYGEN
#ifndef P00_DOXYGEN
P00_STR3_1(l, ll, ul, ull, uz, t, j, uj);
#endif
......
......@@ -23,6 +23,8 @@
#ifndef P99_TYPE_H_
# define P99_TYPE_H_
#include "p99_paste.h"
/**
** @addtogroup types Type facilities
** @brief Macros that help you handle different kind of types,
......@@ -41,6 +43,7 @@
** This declaration should also be suitable to be included into a C++
** source.
**/
P00_DOCUMENT_TYPE_ARGUMENT(P99_DECLARE_STRUCT, 0)
#define P99_DECLARE_STRUCT(NAME) typedef struct NAME NAME
......@@ -54,6 +57,7 @@
** This declaration should also be suitable to be included into a C++
** source.
**/
P00_DOCUMENT_TYPE_ARGUMENT(P99_DECLARE_UNION, 0)
#define P99_DECLARE_UNION(NAME) typedef union NAME NAME
/** @}
......
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