/*H********************************************************************** * FILENAME : varargs.h START DATE : 10 Sept 16 * * DESCRIPTION : * Provides facilities for stepping through a list of function arguments of * an unknown number and type. * * NOTES : * This file is part of SC-CL's include library. * * The type used in va_arg is supposed to match the actual type * after default promotions. Thus, va_arg (..., short) is not valid. * * LICENSE : * * Copyright 2016 SC-CL * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither SC-CL nor its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * * Redistribution of this software in source or binary forms shall be free * of all charges or fees to the recipient of this software. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL SC-CL BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * AUTHORS : * Rocko Tompkins * Nathan James *H*/ #pragma once #ifndef _VA_LIST #define _VA_LIST typedef int* va_list; #endif /// /// Amount of space required in an argument list (ie. the stack) for an /// argument of type t. /// /// The type to be evaluated. /// #define __va_argsiz(t) \ (((sizeof(t) + sizeof(int) - 1) / sizeof(int)) * sizeof(int)) /// /// Start variable argument list processing by setting AP to point to the /// argument after pN. /// /// /// Uninitialized object of type va_list. /// After the call, it carries the information needed to retrieve the additional arguments using va_arg. /// If ap has already been passed as first argument to a previous call to va_start or va_copy, it shall be passed to va_end before calling this function. /// /// /// Name of the last named parameter in the function definition. /// The arguments extracted by subsequent calls to va_arg are those after pN. /// /// #define va_start(ap, pN) \ ((ap) = (va_list)*(va_list)((char*)(&pN) + __va_argsiz(pN))) /// /// Increment ap to the next argument in the list while returing a /// pointer to what ap pointed to first, which is of type t. /// /// /// Object of type va_list carrying information about the current retrieval state of a variable argument list. /// This object shall have been initialized by an initial call to va_start or va_copy and not have been released with va_end. /// /// /// A type name.This type name is used as the type of the expression this macro expands to(i.e., its return type). /// For a type expression to be suitable for its use with va_arg, it must be such that type* produces a pointer to type. /// The type shall be compatible with type of the extracted argument(as promoted according to the default argument promotions), /// or one be the unsigned version of the other, or one be a void pointer and the other some other pointer type. /// /// #define va_arg(ap, t) \ (((ap) = (va_list)((char*)(ap) + __va_argsiz(t))), \ *((t*)((char*)(ap) - __va_argsiz(t)))) /// /// Initializes dest as a copy of src (in its current state) /// /// /// Uninitialized object of type va_list. /// After the call, it carries the information needed to retrieve the same additional arguments as src. /// If dest has already been passed as first argument to a previous call to va_start or va_copy, it shall be passed to va_end before calling this function. /// /// /// Object of type va_list that already carries information to retrieve additional arguments with va_arg /// (i.e., it has already been passed as first argument to va_start or va_copy ans has not yet been released with va_end). /// /// #define va_copy(dest, src) ((dest) = (src)) /// /// End processing of variable argument list. In this case we do nothing. /// /// /// Object of type va_list carrying information about the current retrieval state of a variable argument list. /// This object shall have been initialized by an initial call to va_start or va_copy and not have been released with va_end. /// /// #define va_end(ap) ((void)0) /// /// Gets the variable argument param count from the last argument pN /// /// /// Name of the last named parameter in the function definition. /// /// #define va_count(pN) \ (*(int*)((char*)(&pN) + __va_argsiz(pN) + sizeof(va_list))) /// /// Gets the variable argument stack count from the last argument pN /// /// /// Name of the last named parameter in the function definition. /// /// #define va_scount(pN) \ (*(int*)((char*)(&pN) + __va_argsiz(pN) + sizeof(va_list) + sizeof(int)))