#if !defined (NET_FOSSIL_SCM_FSL_CONFIG_H_INCLUDED) #define NET_FOSSIL_SCM_FSL_CONFIG_H_INCLUDED #include "autoconfig.h" /* auto-generated */ #if HAVE_C99_INT || (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) /* C99 fixed integers... */ #if defined(__cplusplus) && !defined(__STDC_FORMAT_MACROS) /* inttypes.h needs this for the PRI* and SCN* macros in C++ mode. */ # define __STDC_FORMAT_MACROS #endif #include #include #define FSL_HAS_FIXED_INTEGERS 1 #else #define FSL_HAS_FIXED_INTEGERS 0 #endif /* C99 */ #if !defined(FSL_AUX_SCHEMA) #error "Expecting FSL_AUX_SCHEMA to be defined by the configuration bits." #endif #if !defined(FSL_LIBRARY_VERSION) #error "Expecting FSL_LIBRARY_VERSION to be defined by the configuration bits." #endif #if FSL_HAS_FIXED_INTEGERS typedef int16_t fsl_int16_t; typedef uint16_t fsl_uint16_t; typedef int32_t fsl_int32_t; typedef uint32_t fsl_uint32_t; typedef int64_t fsl_int64_t; typedef uint64_t fsl_uint64_t; #define FSL_INT32_T_PFMT PRIi32 #define FSL_INT32_T_SFMT SCNi32 #define FSL_UINT32_T_PFMT PRIu32 #define FSL_UINT32_T_SFMT SCNu32 #define FSL_INT64_T_PFMT PRIi64 #define FSL_INT64_T_SFMT SCNi64 #define FSL_UINT64_T_PFMT PRIu64 #define FSL_UINT64_T_SFMT SCNu64 #else /* Guess some reasonable defaults... TODO: some of the printf/scanf bits need customization for 64-vs-32 bits. See FSL_SIZE_T_PFMT for some important notes regarding formatting strings and sizeof()s. */ typedef short fsl_int16_t; typedef unsigned short fsl_uint16_t; typedef int fsl_int32_t; typedef unsigned int fsl_uint32_t; #define FSL_INT32_T_PFMT "i" #define FSL_INT32_T_SFMT "i" #define FSL_UINT32_T_PFMT "u" #define FSL_UINT32_T_SFMT "u" #if defined(HAVE_LONG_LONG) && HAVE_LONG_LONG #if defined(_MSC_VER) || defined(__BORLANDC__) typedef __int64 fsl_int64_t; typedef unsigned __int64 fsl_uint64_t; #else typedef long long int fsl_int64_t; typedef unsigned long long int fsl_uint64_t; #endif #define FSL_INT64_T_PFMT "lli" #define FSL_INT64_T_SFMT "lli" #define FSL_UINT64_T_PFMT "llu" #define FSL_UINT64_T_SFMT "llu" #else /* We have no long long... */ #if defined(_MSC_VER) || defined(__BORLANDC__) typedef __int64 fsl_int64_t; typedef unsigned __int64 fsl_uint64_t; #else /* Make up a 64-bit integer type... WARNING: on 32-bit platforms 'long' is very likely to be 4 bytes, meaning that Fossil, while "generally functional and correct," and certainly won't overrun any values on normal repos, could run into overflow problems on some operations, e.g. the /stat page of the fossil(1) repo needs to count above 2GB at times. We "could" use sqlite_int64, BUT that header isn't included yet and we cannot, for portability reasons involving some of the lower-level config macros, include that header first. We "could" include it not first, though. Okay, let's try falling back to that one... */ #include typedef sqlite3_int64 fsl_int64_t; typedef sqlite3_uint64 fsl_uint64_t; #endif /* end MSC or BORLAND */ #define FSL_INT64_T_PFMT "lli" #define FSL_INT64_T_SFMT "lli" #define FSL_UINT64_T_PFMT "llu" #define FSL_UINT64_T_SFMT "llu" #endif /* HAVE_LONG_LONG */ #endif /* end configurable numeric bits. Moving on to fixed and derived numeric bits... */ /** @typedef some_int_type fsl_int_t ** ** fsl_int_t is a signed integer type used to denote "relative" ** ranges and lengths, or to tell a routine that it should try to ** figure out the length of some byte array itself (e.g. by using ** fsl_strlen() on it). It is provided primarily for ** documentation/readability purposes, to avoid confusion with the ** widely varying integer semantics used by various APIs. This type ** is never used as a return type for functions which use "error code ** semantics." Those always use an unadorned integer type or some ** API-specific enum type. ** ** The library typedefs this to a 64-bit type if possible, else ** a 32-bit type. **/ typedef fsl_int64_t fsl_int_t; /** ** The unsigned counterpart of fsl_int_t. */ typedef fsl_uint64_t fsl_uint_t; /** ** printf format specifier for fsl_int_t. */ #define FSL_INT_T_PFMT FSL_INT64_T_PFMT /** ** scanf format specifier for fsl_int_t. */ #define FSL_INT_T_SFMT FSL_INT64_T_SFMT /** ** printf format specifier for fsl_uint_t. */ #define FSL_UINT_T_PFMT FSL_UINT64_T_PFMT /** ** scanf format specifier for fsl_uint_t. */ #define FSL_UINT_T_SFMT FSL_UINT64_T_SFMT /** @def FSL_INT_T_PFMT ** ** Fossil's fsl_int_t equivalent of C99's PRIi32 and friends. */ /** @def FSL_INT_T_SFMT ** ** Fossil's fsl_int_t equivalent of C99's SCNi32 and friends. */ /** @def FSL_UINT_T_PFMT ** ** Fossil's fsl_int_t equivalent of C99's PRIu32 and friends. */ /** @def FSL_UINT_T_SFMT ** ** Fossil's fsl_int_t equivalent of C99's SCNu32 and friends. */ /** ** fsl_double_t is the double type used by the library. It is ** currently hard-coded to double but the API allows for it to ** eventually be used with long double, or potentially even with ** integers as a substitute (but note that Fossil generally stores ** times in Julian Date format, which requires double precision). */ typedef double fsl_double_t; /** @def FSL_DOUBLE_T_PFMT ** ** Fossil's fsl_double_t-equivalent of FSL_INT_T_PFMT and friends. */ #define FSL_DOUBLE_T_PFMT "f" /** @def FSL_JULIAN_T_PFMT ** ** An output format specifier for Julian-format doubles. */ #define FSL_JULIAN_T_PFMT ".17g" /** ** fsl_size_t is an unsigned integer type used to denote absolute ** ranges and lengths. It is provided primarily for ** documentation/readability purposes, to avoid confusion with the ** widely varying integer semantics used by various APIs. **/ typedef fsl_uint_t fsl_size_t; /** @def FSL_SIZE_T_PFMT ** ** Fossil's fsl_size_t equivalent of C99's PRIu32 and friends. ** ** ACHTUNG: when passing arguments of this type of fsl_appendf(), or ** any function which uses it for formatting purposes, it is very ** important if if you pass _literal integers_ OR enum values, that ** they be cast to fsl_size_t, or the va_list handling might extract ** the wrong number of bytes from the argument list, leading to ** really weird side-effects via what is effectively memory ** corruption. ** ** That warning applies primarily to the following typedefs and their ** format specifiers: fsl_size_t, fsl_int_t, fsl_uint_t, fsl_id_t. ** ** The warning does not apply to strongly-typed arguments, ** e.g. variables of the proper type, so long as the format specifier ** string matches the argument type. ** ** For example: ** ** @code ** fsl_size_t sz = 3; ** fsl_fprintf( stdout, "%"FSL_SIZE_T_PFMT" %"FSL_SIZE_T_PFMT\n", ** sz, // OK! ** 3 // BAD! See below... ** ); ** @endcode ** ** The "fix" is to cast the literal 3 to a fsl_size_t resp. the type ** appropriate for the format specifier. That ensures that there is ** no (or much less ;) confusion when va_arg() extracts arguments ** from the variadic array. ** ** Reminders to self: ** ** @code ** int i = 0; ** f_out(("#%d: %"FSL_ID_T_PFMT" %"FSL_ID_T_PFMT" %"FSL_ID_T_PFMT"\n", ** ++i, 1, 2, 3)); ** f_out(("#%d: %"FSL_SIZE_T_PFMT" %"FSL_ID_T_PFMT" %"FSL_SIZE_T_PFMT"\n", ** ++i, (fsl_size_t)1, (fsl_id_t)2, (fsl_size_t)3)); ** // This one is the (generally) problematic case: ** f_out(("#%d: %"FSL_SIZE_T_PFMT" %"FSL_ID_T_PFMT" %"FSL_SIZE_T_PFMT"\n", ** ++i, 1, 2, 3)); ** @endcode ** ** The above was Tested with gcc, clang, tcc on a 32-bit linux ** platform. i could reproduce the above problem on all combinations ** i tried. Current code (20130824) seems to be behaving will. ** */ #define FSL_SIZE_T_PFMT FSL_UINT_T_PFMT /** @def FSL_SIZE_T_SFMT ** ** Fossil's fsl_int_t equivalent of C99's SCNu32 and friends. */ #define FSL_SIZE_T_SFMT FSL_UINT_T_SFMT /** ** fsl_id_t is a signed integer type used to store database record ** IDs. It is provided primarily for documentation/readability purposes, ** to avoid confusion with the widely varying integer semantics used ** by various APIs. ** ** This type "could" be 32-bit (instead of 64) because the ** oldest/largest Fossil repo (the TCL tree, with 15 years of ** history) currently (August 2013) has only 131k RIDs. HOWEVER, ** changing this type can have side-effects vis-a-vis va_arg() deep ** in the fsl_appendf() implementation if FSL_ID_T_PFMT is not 100% ** correct for this typedef. After changing this, _make sure_ to do a ** full clean rebuild and test thoroughly because changing a sizeof ** can produce weird side-effects (effectively memory corruption) on ** unclean rebuilds. **/ typedef fsl_int32_t fsl_id_t; /** @def FSL_ID_T_PFMT ** ** Fossil's fsl_id_t equivalent of C99's PRIi32 and friends. ** ** ACHTUNG: see FSL_SIZE_T_PFMT for important details. */ #define FSL_ID_T_PFMT FSL_INT32_T_PFMT /** @def FSL_ID_T_SFMT ** ** Fossil's fsl_id_t equivalent of C99's SCNi32 and friends. */ #define FSL_ID_T_SFMT FSL_INT32_T_SFMT /** ** The type used to represent type values. Unless noted otherwise, ** the general convention is Unix Epoch. That said, Fossil internally ** uses Julian Date for times, so this typedef is clearly the result ** of over-specification/over-thinking the problem. THAT said, ** application-level code more commonly works with Unix timestamps, ** so... here it is. Over-specified, perhaps, but not 100% ** unjustifiable. */ typedef fsl_int64_t /*uint64 instead of int64?*/ fsl_time_t; #endif /* NET_FOSSIL_SCM_FSL_CONFIG_H_INCLUDED */