From 0fec83ebc89bd6b86f772d942b7c39b13f773d3a Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 12 Jun 2014 13:45:06 -0400 Subject: Add a C89 compliance test for the headers. Technically we still require a couple things from C99 like "bool", but it works with -std=c89 under gcc. --- libdimension/Doxyfile.in | 2 +- libdimension/dimension.h | 23 +---- libdimension/dimension/array.h | 40 ++++---- libdimension/dimension/camera.h | 10 +- libdimension/dimension/canvas.h | 18 ++-- libdimension/dimension/color.h | 90 +++++++++-------- libdimension/dimension/compiler.h | 33 +++++- libdimension/dimension/dictionary.h | 2 +- libdimension/dimension/finish.h | 50 +++++----- libdimension/dimension/future.h | 2 +- libdimension/dimension/geometry.h | 194 ++++++++++++++++++++---------------- libdimension/dimension/interior.h | 4 +- libdimension/dimension/light.h | 12 +-- libdimension/dimension/malloc.h | 2 +- libdimension/dimension/map.h | 2 +- libdimension/dimension/object.h | 55 +++++----- libdimension/dimension/pattern.h | 6 +- libdimension/dimension/pigment.h | 16 +-- libdimension/dimension/pigments.h | 4 +- libdimension/dimension/pool.h | 4 +- libdimension/dimension/scene.h | 58 +++++------ libdimension/dimension/tcolor.h | 34 +++---- libdimension/dimension/texture.h | 12 +-- libdimension/dimension/timer.h | 10 +- libdimension/tests/Makefile.am | 6 ++ libdimension/tests/c89.c | 32 ++++++ 26 files changed, 396 insertions(+), 325 deletions(-) create mode 100644 libdimension/tests/c89.c diff --git a/libdimension/Doxyfile.in b/libdimension/Doxyfile.in index 0193155..d52fe97 100644 --- a/libdimension/Doxyfile.in +++ b/libdimension/Doxyfile.in @@ -40,4 +40,4 @@ HTML_FILE_EXTENSION = .html GENERATE_LATEX = YES LATEX_OUTPUT = latex -PREDEFINED = "__STDC_VERSION__=199901L" "__GNUC__" +PREDEFINED = "__STDC_VERSION__=201112L" "__GNUC__" diff --git a/libdimension/dimension.h b/libdimension/dimension.h index 57458c1..19b43bc 100644 --- a/libdimension/dimension.h +++ b/libdimension/dimension.h @@ -40,26 +40,11 @@ #define DIMENSION_H #ifdef __cplusplus -// We've been included from a C++ file; mark everything here as extern "C" +/* We've been included from a C++ file; mark everything here as extern "C" */ extern "C" { #endif -// Common macros - -/** - * @internal - * @def DMNSN_FUNC - * @brief Expands to the name of the current function - */ -#ifdef __GNUC__ - #define DMNSN_FUNC __PRETTY_FUNCTION__ -#elif __STDC_VERSION__ >= 199901L - #define DMNSN_FUNC __func__ -#else - #define DMNSN_FUNC "" -#endif - -// Common types +/* Common types */ /** * Generic callback type. @@ -73,7 +58,7 @@ typedef void dmnsn_callback_fn(void *ptr); */ typedef void dmnsn_free_fn(void *ptr); -// Include all the libdimension headers +/* Include all the libdimension headers */ #include #include #include @@ -112,4 +97,4 @@ typedef void dmnsn_free_fn(void *ptr); } #endif -#endif // DIMENSION_H +#endif /* DIMENSION_H */ diff --git a/libdimension/dimension/array.h b/libdimension/dimension/array.h index 9b38e29..9261a0e 100644 --- a/libdimension/dimension/array.h +++ b/libdimension/dimension/array.h @@ -23,16 +23,16 @@ * Simple dynamic arrays. */ -#include // For size_t -#include // For qsort() -#include // For memcpy() +#include /* For size_t */ +#include /* For qsort() */ +#include /* For memcpy() */ -/// Dynamic array type. +/** Dynamic array type. */ typedef struct dmnsn_array { - void *ptr; ///< @internal The actual memory. - size_t obj_size; ///< @internal The size of each object. - size_t length; ///< @internal The current size of the array. - size_t capacity; ///< @internal The size of the allocated space. + void *ptr; /**< @internal The actual memory. */ + size_t obj_size; /**< @internal The size of each object. */ + size_t length; /**< @internal The current size of the array. */ + size_t capacity; /**< @internal The size of the allocated space. */ } dmnsn_array; /** @@ -46,9 +46,9 @@ dmnsn_init_array(dmnsn_array *array, size_t obj_size) { array->obj_size = obj_size; array->length = 0; - array->capacity = 2; // Start with capacity of 2 + array->capacity = 2; /* Start with capacity of 2 */ - // Allocate the memory + /* Allocate the memory */ array->ptr = dmnsn_malloc(array->capacity*array->obj_size); } @@ -134,8 +134,8 @@ DMNSN_INLINE void dmnsn_array_resize(dmnsn_array *array, size_t length) { if (length > array->capacity) { - // Resize if we don't have enough capacity - array->capacity = length*2; // We are greedy + /* Resize if we don't have enough capacity */ + array->capacity = length*2; /* We are greedy */ array->ptr = dmnsn_realloc(array->ptr, array->obj_size*array->capacity); } @@ -197,7 +197,7 @@ DMNSN_INLINE void dmnsn_array_set(dmnsn_array *array, size_t i, const void *obj) { if (i >= dmnsn_array_size(array)) { - // Resize if i is out of range + /* Resize if i is out of range */ dmnsn_array_resize(array, i + 1); } memcpy((char *)array->ptr + array->obj_size*i, obj, array->obj_size); @@ -259,8 +259,8 @@ dmnsn_array_pop(dmnsn_array *array, void *obj) { size_t size = dmnsn_array_size(array); dmnsn_assert(size > 0, "Array is empty."); - dmnsn_array_get(array, size - 1, obj); // Copy the object - dmnsn_array_resize(array, size - 1); // Shrink the array + dmnsn_array_get(array, size - 1, obj); /* Copy the object */ + dmnsn_array_resize(array, size - 1); /* Shrink the array */ } /** @@ -277,11 +277,11 @@ dmnsn_array_insert(dmnsn_array *array, size_t i, const void *obj) size = i + 1; dmnsn_array_resize(array, size); - // Move the elements at and after `i' 1 to the right + /* Move the elements at and after `i' 1 to the right */ memmove((char *)array->ptr + array->obj_size*(i + 1), (char *)array->ptr + array->obj_size*i, array->obj_size*(size - i - 1)); - // Insert `obj' at `i' + /* Insert `obj' at `i' */ memcpy((char *)array->ptr + array->obj_size*i, obj, array->obj_size); } @@ -295,11 +295,11 @@ dmnsn_array_remove(dmnsn_array *array, size_t i) { size_t size = dmnsn_array_size(array); dmnsn_assert(i < size, "Array index out of bounds."); - // Move the array elements after `i' 1 to the left + /* Move the array elements after `i' 1 to the left */ memmove((char *)array->ptr + array->obj_size*i, (char *)array->ptr + array->obj_size*(i + 1), array->obj_size*(size - i - 1)); - // Decrease the size by 1 + /* Decrease the size by 1 */ dmnsn_array_resize(array, size - 1); } @@ -337,7 +337,7 @@ dmnsn_array_sort(dmnsn_array *array, dmnsn_array_comparator_fn *comparator) qsort(array->ptr, dmnsn_array_size(array), array->obj_size, comparator); } -// Macros to shorten array iteration +/* Macros to shorten array iteration */ /** * Iterate over an array. For example, diff --git a/libdimension/dimension/camera.h b/libdimension/dimension/camera.h index 30a01cc..3c6494c 100644 --- a/libdimension/dimension/camera.h +++ b/libdimension/dimension/camera.h @@ -23,7 +23,7 @@ * Cameras. */ -// Forward-declare dmnsn_camera +/* Forward-declare dmnsn_camera */ typedef struct dmnsn_camera dmnsn_camera; /** @@ -36,12 +36,12 @@ typedef struct dmnsn_camera dmnsn_camera; typedef dmnsn_line dmnsn_camera_ray_fn(const dmnsn_camera *camera, double x, double y); -/// A camera. +/** A camera. */ struct dmnsn_camera { - // Callback functions - dmnsn_camera_ray_fn *ray_fn; ///< Camera ray callback. + /* Callback functions */ + dmnsn_camera_ray_fn *ray_fn; /**< Camera ray callback. */ - dmnsn_matrix trans; ///< Transformation matrix. + dmnsn_matrix trans; /**< Transformation matrix. */ }; /** diff --git a/libdimension/dimension/canvas.h b/libdimension/dimension/canvas.h index 765260d..d03a37e 100644 --- a/libdimension/dimension/canvas.h +++ b/libdimension/dimension/canvas.h @@ -25,12 +25,12 @@ #include -/// A canvas, or image. +/** A canvas, or image. */ typedef struct dmnsn_canvas { - size_t width; ///< Canvas width. - size_t height; ///< Canvas height. + size_t width; /**< Canvas width. */ + size_t height; /**< Canvas height. */ - /// An array of dmnsn_canvas_optimizers. + /** An array of dmnsn_canvas_optimizers. */ dmnsn_array *optimizers; /** @@ -51,12 +51,12 @@ typedef struct dmnsn_canvas { typedef void dmnsn_canvas_optimizer_fn(const dmnsn_canvas *canvas, void *ptr, size_t x, size_t y); -/// Canvas optimizer. +/** Canvas optimizer. */ typedef struct dmnsn_canvas_optimizer { - dmnsn_canvas_optimizer_fn *optimizer_fn; ///< Optimizer callback. - dmnsn_free_fn *free_fn; ///< Destructor callback. + dmnsn_canvas_optimizer_fn *optimizer_fn; /**< Optimizer callback. */ + dmnsn_free_fn *free_fn; /**< Destructor callback. */ - void *ptr; ///< Generic pointer. + void *ptr; /**< Generic pointer. */ } dmnsn_canvas_optimizer; /** @@ -87,7 +87,7 @@ dmnsn_canvas_optimizer * dmnsn_canvas_find_optimizer(const dmnsn_canvas *canvas, dmnsn_canvas_optimizer_fn *optimizer_fn); -// Pixel accessors +/* Pixel accessors */ /** * Get the color of a pixel. diff --git a/libdimension/dimension/color.h b/libdimension/dimension/color.h index 3eacbfe..afc4a5c 100644 --- a/libdimension/dimension/color.h +++ b/libdimension/dimension/color.h @@ -25,19 +25,19 @@ #include -/// A color value. +/** A color value. */ typedef struct { - double R; ///< Red component. - double G; ///< Green component. - double B; ///< Blue component. + double R; /**< Red component. */ + double G; /**< Green component. */ + double B; /**< Blue component. */ } dmnsn_color; -/// A standard format string for colors. +/** A standard format string for colors. */ #define DMNSN_COLOR_FORMAT "Color<%g, %g, %g>" -/// The appropriate arguements to printf() a color. +/** The appropriate arguements to printf() a color. */ #define DMNSN_COLOR_PRINTF(c) (c).R, (c).G, (c).B -/// Construct a new color. +/** Construct a new color. */ DMNSN_INLINE dmnsn_color dmnsn_new_color(double R, double G, double B) { @@ -45,17 +45,19 @@ dmnsn_new_color(double R, double G, double B) return ret; } -/// Apply sRGB gamma +/** Apply sRGB gamma */ DMNSN_INLINE double dmnsn_sRGB_gamma(double Clinear) { - // If C represents R, G, and B, then the sRGB values are now found as follows: - // - // { 12.92*Clinear, Clinear <= 0.0031308 - // Csrgb = { 1/2.4 - // { (1.055)*Clinear - 0.055, Clinear > 0.0031308 + /* + * If C represents R, G, and B, then the sRGB values are now found as follows: + * + * { 12.92*Clinear, Clinear <= 0.0031308 + * Csrgb = { 1/2.4 + * { (1.055)*Clinear - 0.055, Clinear > 0.0031308 + */ if (Clinear == 1.0) { - return 1.0; // Map 1.0 to 1.0 instead of 0.9999999999999999 + return 1.0; /* Map 1.0 to 1.0 instead of 0.9999999999999999 */ } else if (Clinear > 0.0031308) { return 1.055*pow(Clinear, 1.0/2.4) - 0.055; } else { @@ -63,7 +65,7 @@ dmnsn_sRGB_gamma(double Clinear) } } -/// Convert to sRGB space. +/** Convert to sRGB space. */ DMNSN_INLINE dmnsn_color dmnsn_color_to_sRGB(dmnsn_color color) { @@ -74,18 +76,20 @@ dmnsn_color_to_sRGB(dmnsn_color color) ); } -/// Remove sRGB gamma +/** Remove sRGB gamma */ DMNSN_INLINE double dmnsn_sRGB_inverse_gamma(double CsRGB) { - // If C represents R, G, and B, then the Clinear values are now found as - // follows: - // - // { Csrgb/12.92, Csrgb <= 0.04045 - // Clinear = { 2.4 - // { ((Csrgb + 0.055)/1.055) , Csrgb > 0.04045 + /* + * If C represents R, G, and B, then the Clinear values are now found as + * follows: + * + * { Csrgb/12.92, Csrgb <= 0.04045 + * Clinear = { 2.4 + * { ((Csrgb + 0.055)/1.055) , Csrgb > 0.04045 + */ if (CsRGB == 1.0) { - return 1.0; // Map 1.0 to 1.0 instead of 0.9999999999999999 + return 1.0; /* Map 1.0 to 1.0 instead of 0.9999999999999999 */ } else if (CsRGB <= 0.040449936) { return CsRGB/12.92; } else { @@ -93,7 +97,7 @@ dmnsn_sRGB_inverse_gamma(double CsRGB) } } -/// Convert from sRGB space. +/** Convert from sRGB space. */ DMNSN_INLINE dmnsn_color dmnsn_color_from_sRGB(dmnsn_color color) { @@ -104,35 +108,35 @@ dmnsn_color_from_sRGB(dmnsn_color color) ); } -/// Greyscale color intensity. +/** Greyscale color intensity. */ DMNSN_INLINE double dmnsn_color_intensity(dmnsn_color color) { return 0.2126*color.R + 0.7152*color.G + 0.0722*color.B; } -/// Add two colors together. +/** Add two colors together. */ DMNSN_INLINE dmnsn_color dmnsn_color_add(dmnsn_color lhs, dmnsn_color rhs) { return dmnsn_new_color(lhs.R + rhs.R, lhs.G + rhs.G, lhs.B + rhs.B); } -/// Subtract two colors. +/** Subtract two colors. */ DMNSN_INLINE dmnsn_color dmnsn_color_sub(dmnsn_color lhs, dmnsn_color rhs) { return dmnsn_new_color(lhs.R - rhs.R, lhs.G - rhs.G, lhs.B - rhs.B); } -/// Scale a color's intensity. +/** Scale a color's intensity. */ DMNSN_INLINE dmnsn_color dmnsn_color_mul(double n, dmnsn_color color) { return dmnsn_new_color(n*color.R, n*color.G, n*color.B); } -/// Return the color at \p n on a gradient from \p c1 at 0 to \p c2 at 1. +/** Return the color at \p n on a gradient from \p c1 at 0 to \p c2 at 1. */ DMNSN_INLINE dmnsn_color dmnsn_color_gradient(dmnsn_color c1, dmnsn_color c2, double n) { @@ -143,14 +147,14 @@ dmnsn_color_gradient(dmnsn_color c1, dmnsn_color c2, double n) ); } -/// Illuminate \p color with \p light. +/** Illuminate \p color with \p light. */ DMNSN_INLINE dmnsn_color dmnsn_color_illuminate(dmnsn_color light, dmnsn_color color) { return dmnsn_new_color(light.R*color.R, light.G*color.G, light.B*color.B); } -/// Saturate the color components to [0.0, 1.0]. +/** Saturate the color components to [0.0, 1.0]. */ DMNSN_INLINE dmnsn_color dmnsn_color_saturate(dmnsn_color color) { @@ -160,30 +164,30 @@ dmnsn_color_saturate(dmnsn_color color) return color; } -/// Return whether a color contains any NaN components. +/** Return whether a color contains any NaN components. */ DMNSN_INLINE bool dmnsn_color_isnan(dmnsn_color color) { - return isnan(color.R) || isnan(color.G) || isnan(color.B); + return dmnsn_isnan(color.R) || dmnsn_isnan(color.G) || dmnsn_isnan(color.B); } -// Standard colors +/* Standard colors */ -/// Black. +/** Black. */ #define dmnsn_black dmnsn_new_color(0.0, 0.0, 0.0) -/// White. +/** White. */ #define dmnsn_white dmnsn_new_color(1.0, 1.0, 1.0) -/// Red. +/** Red. */ #define dmnsn_red dmnsn_new_color(1.0, 0.0, 0.0) -/// Green. +/** Green. */ #define dmnsn_green dmnsn_new_color(0.0, 1.0, 0.0) -/// Blue. +/** Blue. */ #define dmnsn_blue dmnsn_new_color(0.0, 0.0, 1.0) -/// Magenta. +/** Magenta. */ #define dmnsn_magenta dmnsn_new_color(1.0, 0.0, 1.0) -/// Orange. +/** Orange. */ #define dmnsn_orange dmnsn_new_color(1.0, 0.21404114048223255, 0.0) -/// Yellow. +/** Yellow. */ #define dmnsn_yellow dmnsn_new_color(1.0, 1.0, 0.0) -/// Cyan. +/** Cyan. */ #define dmnsn_cyan dmnsn_new_color(0.0, 1.0, 1.0) diff --git a/libdimension/dimension/compiler.h b/libdimension/dimension/compiler.h index 952200b..3d392b5 100644 --- a/libdimension/dimension/compiler.h +++ b/libdimension/dimension/compiler.h @@ -30,23 +30,46 @@ */ #ifndef DMNSN_INLINE #ifdef __cplusplus - // C++ inline semantics + /* C++ inline semantics */ #define DMNSN_INLINE inline #elif __STDC_VERSION__ >= 199901L - // C99 inline semantics + /* C99 inline semantics */ #define DMNSN_INLINE inline #elif defined(__GNUC__) - // GCC inline semantics + /* GCC inline semantics */ #define DMNSN_INLINE __extension__ extern __inline__ #else - // Unknown C - mark functions static and hope the compiler is smart enough - // to inline them + /* Unknown C - mark functions static and hope the compiler is smart enough + to inline them */ #define DMNSN_INLINE static #endif #endif +/** + * @internal + * @def DMNSN_FUNC + * @brief Expands to the name of the current function + */ +#ifdef __GNUC__ + #define DMNSN_FUNC __PRETTY_FUNCTION__ +#elif __STDC_VERSION__ >= 199901L + #define DMNSN_FUNC __func__ +#else + #define DMNSN_FUNC "" +#endif + +/** + * @internal + * An unreachable statement. + */ #ifdef __GNUC__ #define DMNSN_UNREACHABLE() __builtin_unreachable() #else #define DMNSN_UNREACHABLE() ((void)0) #endif + +/** + * @internal + * Whether C99 features are supported. + */ +#define DMNSN_C99 (__STDC_VERSION__ >= 199901L || __cplusplus >= 201103L) diff --git a/libdimension/dimension/dictionary.h b/libdimension/dimension/dictionary.h index 15661de..887b171 100644 --- a/libdimension/dimension/dictionary.h +++ b/libdimension/dimension/dictionary.h @@ -23,7 +23,7 @@ * Simple associative arrays. */ -/// A string-object associative array. +/** A string-object associative array. */ typedef struct dmnsn_dictionary dmnsn_dictionary; /** diff --git a/libdimension/dimension/finish.h b/libdimension/dimension/finish.h index 5471897..d975877 100644 --- a/libdimension/dimension/finish.h +++ b/libdimension/dimension/finish.h @@ -23,17 +23,17 @@ * Object finishes. */ -// Ambient component +/* Ambient component */ -/// Ambient finish component. +/** Ambient finish component. */ typedef struct dmnsn_ambient { - dmnsn_color ambient; ///< Ambient light. + dmnsn_color ambient; /**< Ambient light. */ } dmnsn_ambient; -/// Allocate an ambient component. +/** Allocate an ambient component. */ dmnsn_ambient *dmnsn_new_ambient(dmnsn_pool *pool, dmnsn_color ambient); -// Diffuse component +/* Diffuse component */ typedef struct dmnsn_diffuse dmnsn_diffuse; @@ -50,17 +50,17 @@ typedef dmnsn_color dmnsn_diffuse_fn(const dmnsn_diffuse *diffuse, dmnsn_color light, dmnsn_color color, dmnsn_vector ray, dmnsn_vector normal); -/// Diffuse finish component. +/** Diffuse finish component. */ struct dmnsn_diffuse { - dmnsn_diffuse_fn *diffuse_fn; ///< Diffuse callback. + dmnsn_diffuse_fn *diffuse_fn; /**< Diffuse callback. */ }; -/// Allocate a dummy diffuse component. +/** Allocate a dummy diffuse component. */ dmnsn_diffuse *dmnsn_new_diffuse(dmnsn_pool *pool); -/// Initialize a dmnsn_diffuse field. +/** Initialize a dmnsn_diffuse field. */ void dmnsn_init_diffuse(dmnsn_diffuse *diffuse); -// Specular component +/* Specular component */ typedef struct dmnsn_specular dmnsn_specular; @@ -79,17 +79,17 @@ typedef dmnsn_color dmnsn_specular_fn(const dmnsn_specular *specular, dmnsn_vector ray, dmnsn_vector normal, dmnsn_vector viewer); -/// Specular finish component. +/** Specular finish component. */ struct dmnsn_specular { - dmnsn_specular_fn *specular_fn; ///< Specular callback. + dmnsn_specular_fn *specular_fn; /**< Specular callback. */ }; -/// Allocate a dummy specular component. +/** Allocate a dummy specular component. */ dmnsn_specular *dmnsn_new_specular(dmnsn_pool *pool); -/// Initialize a dmnsn_specular field. +/** Initialize a dmnsn_specular field. */ void dmnsn_init_specular(dmnsn_specular *specular); -// Reflection component +/* Reflection component */ typedef struct dmnsn_reflection dmnsn_reflection; @@ -106,24 +106,24 @@ typedef dmnsn_color dmnsn_reflection_fn(const dmnsn_reflection *reflection, dmnsn_color reflect, dmnsn_color color, dmnsn_vector ray, dmnsn_vector normal); -/// The reflection component. +/** The reflection component. */ struct dmnsn_reflection { - dmnsn_reflection_fn *reflection_fn; ///< Reflection callback. + dmnsn_reflection_fn *reflection_fn; /**< Reflection callback. */ }; -/// Allocate a dummy reflection component. +/** Allocate a dummy reflection component. */ dmnsn_reflection *dmnsn_new_reflection(dmnsn_pool *pool); -/// Initialize a dmnsn_reflection field. +/** Initialize a dmnsn_reflection field. */ void dmnsn_init_reflection(dmnsn_reflection *reflection); -// Entire finishes +/* Entire finishes */ -/// A finish. +/** A finish. */ typedef struct dmnsn_finish { - dmnsn_ambient *ambient; ///< Ambient component. - dmnsn_diffuse *diffuse; ///< Diffuse component. - dmnsn_specular *specular; ///< Specular component. - dmnsn_reflection *reflection; ///< Reflection component. + dmnsn_ambient *ambient; /**< Ambient component. */ + dmnsn_diffuse *diffuse; /**< Diffuse component. */ + dmnsn_specular *specular; /**< Specular component. */ + dmnsn_reflection *reflection; /**< Reflection component. */ } dmnsn_finish; /** diff --git a/libdimension/dimension/future.h b/libdimension/dimension/future.h index 263c647..9ba28b1 100644 --- a/libdimension/dimension/future.h +++ b/libdimension/dimension/future.h @@ -26,7 +26,7 @@ * is returned as an int from dmnsn_finish_progress(). */ -/// A future object. +/** A future object. */ typedef struct dmnsn_future dmnsn_future; /** diff --git a/libdimension/dimension/geometry.h b/libdimension/dimension/geometry.h index fd4a781..7b52a98 100644 --- a/libdimension/dimension/geometry.h +++ b/libdimension/dimension/geometry.h @@ -26,105 +26,115 @@ #include #include -/// A vector in 3 dimensions. +/** A vector in 3 dimensions. */ typedef struct dmnsn_vector { - double x; ///< The x component. - double y; ///< The y component. - double z; ///< The z component. + double x; /**< The x component. */ + double y; /**< The y component. */ + double z; /**< The z component. */ } dmnsn_vector; -/// A standard format string for vectors. +/** A standard format string for vectors. */ #define DMNSN_VECTOR_FORMAT "<%g, %g, %g>" -/// The appropriate arguements to printf() a vector. +/** The appropriate arguements to printf() a vector. */ #define DMNSN_VECTOR_PRINTF(v) (v).x, (v).y, (v).z -/// A 4x4 affine transformation matrix, with implied [0 0 0 1] bottom row. +/** A 4x4 affine transformation matrix, with implied [0 0 0 1] bottom row. */ typedef struct dmnsn_matrix { - double n[3][4]; ///< The matrix elements in row-major order. + double n[3][4]; /**< The matrix elements in row-major order. */ } dmnsn_matrix; -/// A standard format string for matricies. +/** A standard format string for matricies. */ #define DMNSN_MATRIX_FORMAT \ "[%g\t%g\t%g\t%g]\n" \ "[%g\t%g\t%g\t%g]\n" \ "[%g\t%g\t%g\t%g]\n" \ "[%g\t%g\t%g\t%g]" -/// The appropriate arguements to printf() a matrix. +/** The appropriate arguements to printf() a matrix. */ #define DMNSN_MATRIX_PRINTF(m) \ (m).n[0][0], (m).n[0][1], (m).n[0][2], (m).n[0][3], \ (m).n[1][0], (m).n[1][1], (m).n[1][2], (m).n[1][3], \ (m).n[2][0], (m).n[2][1], (m).n[2][2], (m).n[2][3], \ 0.0, 0.0, 0.0, 1.0 -/// A line, or ray. +/** A line, or ray. */ typedef struct dmnsn_line { - dmnsn_vector x0; ///< A point on the line. - dmnsn_vector n; ///< A normal vector; the direction of the line. + dmnsn_vector x0; /**< A point on the line. */ + dmnsn_vector n; /**< A normal vector; the direction of the line. */ } dmnsn_line; -/// A standard format string for lines. +/** A standard format string for lines. */ #define DMNSN_LINE_FORMAT "(<%g, %g, %g> + t*<%g, %g, %g>)" -/// The appropriate arguements to printf() a line. +/** The appropriate arguements to printf() a line. */ #define DMNSN_LINE_PRINTF(l) \ DMNSN_VECTOR_PRINTF((l).x0), DMNSN_VECTOR_PRINTF((l).n) -/// An axis-aligned bounding box (AABB). +/** An axis-aligned bounding box (AABB). */ typedef struct dmnsn_bounding_box { - dmnsn_vector min; ///< The coordinate-wise minimum extent of the box. - dmnsn_vector max; ///< The coordinate-wise maximum extent of the box. + dmnsn_vector min; /**< The coordinate-wise minimum extent of the box. */ + dmnsn_vector max; /**< The coordinate-wise maximum extent of the box. */ } dmnsn_bounding_box; -/// A standard format string for bounding boxes. +/** A standard format string for bounding boxes. */ #define DMNSN_BOUNDING_BOX_FORMAT "(<%g, %g, %g> ==> <%g, %g, %g>)" -/// The appropriate arguements to printf() a bounding box. +/** The appropriate arguements to printf() a bounding box. */ #define DMNSN_BOUNDING_BOX_PRINTF(box) \ DMNSN_VECTOR_PRINTF((box).min), DMNSN_VECTOR_PRINTF((box).max) -// Constants +/* Constants */ -/// The smallest value considered non-zero by some numerical algorithms. +/** The smallest value considered non-zero by some numerical algorithms. */ #define dmnsn_epsilon 1.0e-10 -/// The zero vector. +/** The zero vector. */ static const dmnsn_vector dmnsn_zero = { 0.0, 0.0, 0.0 }; -/// The x vector. +/** The x vector. */ static const dmnsn_vector dmnsn_x = { 1.0, 0.0, 0.0 }; -/// The y vector. +/** The y vector. */ static const dmnsn_vector dmnsn_y = { 0.0, 1.0, 0.0 }; -/// The z vector. +/** The z vector. */ static const dmnsn_vector dmnsn_z = { 0.0, 0.0, 1.0 }; -// Scalar functions +/** + * @def DMNSN_INFINITY + * Expands to floating-point infinity. + */ +#if defined(INFINITY) || DMNSN_C99 + #define DMNSN_INFINITY INFINITY +#else + #define DMNSN_INFINITY HUGE_VAL +#endif -/// Find the minimum of two scalars. +/* Scalar functions */ + +/** Find the minimum of two scalars. */ DMNSN_INLINE double dmnsn_min(double a, double b) { return a < b ? a : b; } -/// Find the maximum of two scalars. +/** Find the maximum of two scalars. */ DMNSN_INLINE double dmnsn_max(double a, double b) { return a > b ? a : b; } -/// Convert degrees to radians. +/** Convert degrees to radians. */ DMNSN_INLINE double dmnsn_radians(double degrees) { return degrees*atan(1.0)/45.0; } -/// Convert radians to degrees. +/** Convert radians to degrees. */ DMNSN_INLINE double dmnsn_degrees(double radians) { return radians*45.0/atan(1.0); } -/// Return the sign of a scalar. +/** Return the sign of a scalar. */ DMNSN_INLINE int dmnsn_sign(double n) { @@ -137,9 +147,9 @@ dmnsn_sign(double n) } } -// Shorthand for vector/matrix construction +/* Shorthand for vector/matrix construction */ -/// Construct a new vector. +/** Construct a new vector. */ DMNSN_INLINE dmnsn_vector dmnsn_new_vector(double x, double y, double z) { @@ -147,7 +157,7 @@ dmnsn_new_vector(double x, double y, double z) return v; } -/// Construct a new transformation matrix. +/** Construct a new transformation matrix. */ DMNSN_INLINE dmnsn_matrix dmnsn_new_matrix(double a0, double a1, double a2, double a3, double b0, double b1, double b2, double b3, @@ -159,7 +169,7 @@ dmnsn_new_matrix(double a0, double a1, double a2, double a3, return m; } -/// Construct a new transformation matrix from column vectors. +/** Construct a new transformation matrix from column vectors. */ DMNSN_INLINE dmnsn_matrix dmnsn_new_matrix4(dmnsn_vector a, dmnsn_vector b, dmnsn_vector c, dmnsn_vector d) @@ -170,14 +180,14 @@ dmnsn_new_matrix4(dmnsn_vector a, dmnsn_vector b, dmnsn_vector c, return m; } -/// Extract column vectors from a matrix. +/** Extract column vectors from a matrix. */ DMNSN_INLINE dmnsn_vector dmnsn_matrix_column(dmnsn_matrix M, unsigned int i) { return dmnsn_new_vector(M.n[0][i], M.n[1][i], M.n[2][i]); } -/// Return the identity matrix. +/** Return the identity matrix. */ dmnsn_matrix dmnsn_identity_matrix(void); /** @@ -238,119 +248,119 @@ dmnsn_new_bounding_box(dmnsn_vector min, dmnsn_vector max) return box; } -/// Return the bounding box which contains nothing. +/** Return the bounding box which contains nothing. */ DMNSN_INLINE dmnsn_bounding_box dmnsn_zero_bounding_box(void) { dmnsn_bounding_box box = { - { INFINITY, INFINITY, INFINITY }, - { -INFINITY, -INFINITY, -INFINITY } + { DMNSN_INFINITY, DMNSN_INFINITY, DMNSN_INFINITY }, + { -DMNSN_INFINITY, -DMNSN_INFINITY, -DMNSN_INFINITY } }; return box; } -/// Return the bounding box which contains everything. +/** Return the bounding box which contains everything. */ DMNSN_INLINE dmnsn_bounding_box dmnsn_infinite_bounding_box(void) { dmnsn_bounding_box box = { - { -INFINITY, -INFINITY, -INFINITY }, - { INFINITY, INFINITY, INFINITY } + { -DMNSN_INFINITY, -DMNSN_INFINITY, -DMNSN_INFINITY }, + { DMNSN_INFINITY, DMNSN_INFINITY, DMNSN_INFINITY } }; return box; } -// Vector and matrix arithmetic +/* Vector and matrix arithmetic */ -/// Negate a vector. +/** Negate a vector. */ DMNSN_INLINE dmnsn_vector dmnsn_vector_negate(dmnsn_vector rhs) { - // 3 negations + /* 3 negations */ dmnsn_vector v = { -rhs.x, -rhs.y, -rhs.z }; return v; } -/// Add two vectors. +/** Add two vectors. */ DMNSN_INLINE dmnsn_vector dmnsn_vector_add(dmnsn_vector lhs, dmnsn_vector rhs) { - // 3 additions + /* 3 additions */ dmnsn_vector v = { lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z }; return v; } -/// Subtract two vectors. +/** Subtract two vectors. */ DMNSN_INLINE dmnsn_vector dmnsn_vector_sub(dmnsn_vector lhs, dmnsn_vector rhs) { - // 3 additions + /* 3 additions */ dmnsn_vector v = { lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z }; return v; } -/// Multiply a vector by a scalar. +/** Multiply a vector by a scalar. */ DMNSN_INLINE dmnsn_vector dmnsn_vector_mul(double lhs, dmnsn_vector rhs) { - // 3 multiplications + /* 3 multiplications */ dmnsn_vector v = { lhs*rhs.x, lhs*rhs.y, lhs*rhs.z }; return v; } -/// Divide a vector by a scalar. +/** Divide a vector by a scalar. */ DMNSN_INLINE dmnsn_vector dmnsn_vector_div(dmnsn_vector lhs, double rhs) { - // 3 divisions + /* 3 divisions */ dmnsn_vector v = { lhs.x/rhs, lhs.y/rhs, lhs.z/rhs }; return v; } -/// Return the dot product of two vectors. +/** Return the dot product of two vectors. */ DMNSN_INLINE double dmnsn_vector_dot(dmnsn_vector lhs, dmnsn_vector rhs) { - // 3 multiplications, 2 additions + /* 3 multiplications, 2 additions */ return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z; } -/// Return the cross product of two vectors. +/** Return the cross product of two vectors. */ DMNSN_INLINE dmnsn_vector dmnsn_vector_cross(dmnsn_vector lhs, dmnsn_vector rhs) { - // 6 multiplications, 3 additions + /* 6 multiplications, 3 additions */ dmnsn_vector v = { lhs.y*rhs.z - lhs.z*rhs.y, lhs.z*rhs.x - lhs.x*rhs.z, lhs.x*rhs.y - lhs.y*rhs.x }; return v; } -/// Return the projection of \p u onto \p d. +/** Return the projection of \p u onto \p d. */ DMNSN_INLINE dmnsn_vector dmnsn_vector_proj(dmnsn_vector u, dmnsn_vector d) { - // 1 division, 9 multiplications, 4 additions + /* 1 division, 9 multiplications, 4 additions */ return dmnsn_vector_mul(dmnsn_vector_dot(u, d)/dmnsn_vector_dot(d, d), d); } -/// Return the magnitude of a vector. +/** Return the magnitude of a vector. */ DMNSN_INLINE double dmnsn_vector_norm(dmnsn_vector n) { - // 1 sqrt, 3 multiplications, 2 additions + /* 1 sqrt, 3 multiplications, 2 additions */ return sqrt(dmnsn_vector_dot(n, n)); } -/// Return the direction of a vector. +/** Return the direction of a vector. */ DMNSN_INLINE dmnsn_vector dmnsn_vector_normalized(dmnsn_vector n) { - // 1 sqrt, 3 divisions, 3 multiplications, 2 additions + /* 1 sqrt, 3 divisions, 3 multiplications, 2 additions */ return dmnsn_vector_div(n, dmnsn_vector_norm(n)); } -/// Return the component-wise minimum of two vectors. +/** Return the component-wise minimum of two vectors. */ DMNSN_INLINE dmnsn_vector dmnsn_vector_min(dmnsn_vector a, dmnsn_vector b) { @@ -361,7 +371,7 @@ dmnsn_vector_min(dmnsn_vector a, dmnsn_vector b) ); } -/// Return the component-wise maximum of two vectors. +/** Return the component-wise maximum of two vectors. */ DMNSN_INLINE dmnsn_vector dmnsn_vector_max(dmnsn_vector a, dmnsn_vector b) { @@ -372,17 +382,17 @@ dmnsn_vector_max(dmnsn_vector a, dmnsn_vector b) ); } -/// Invert a matrix. +/** Invert a matrix. */ dmnsn_matrix dmnsn_matrix_inverse(dmnsn_matrix A); -/// Multiply two matricies. +/** Multiply two matricies. */ dmnsn_matrix dmnsn_matrix_mul(dmnsn_matrix lhs, dmnsn_matrix rhs); -/// Transform a point by a matrix. +/** Transform a point by a matrix. */ DMNSN_INLINE dmnsn_vector dmnsn_transform_point(dmnsn_matrix T, dmnsn_vector v) { - // 9 multiplications, 9 additions + /* 9 multiplications, 9 additions */ dmnsn_vector r; r.x = T.n[0][0]*v.x + T.n[0][1]*v.y + T.n[0][2]*v.z + T.n[0][3]; r.y = T.n[1][0]*v.x + T.n[1][1]*v.y + T.n[1][2]*v.z + T.n[1][3]; @@ -390,11 +400,11 @@ dmnsn_transform_point(dmnsn_matrix T, dmnsn_vector v) return r; } -/// Transform a direction by a matrix. +/** Transform a direction by a matrix. */ DMNSN_INLINE dmnsn_vector dmnsn_transform_direction(dmnsn_matrix T, dmnsn_vector v) { - // 9 multiplications, 6 additions + /* 9 multiplications, 6 additions */ dmnsn_vector r; r.x = T.n[0][0]*v.x + T.n[0][1]*v.y + T.n[0][2]*v.z; r.y = T.n[1][0]*v.x + T.n[1][1]*v.y + T.n[1][2]*v.z; @@ -411,7 +421,8 @@ dmnsn_transform_direction(dmnsn_matrix T, dmnsn_vector v) DMNSN_INLINE dmnsn_vector dmnsn_transform_normal(dmnsn_matrix Tinv, dmnsn_vector v) { - // Multiply by the transpose of the inverse (9 multiplications, 6 additions) + /* Multiply by the transpose of the inverse + (9 multiplications, 6 additions) */ dmnsn_vector r; r.x = Tinv.n[0][0]*v.x + Tinv.n[1][0]*v.y + Tinv.n[2][0]*v.z; r.y = Tinv.n[0][1]*v.x + Tinv.n[1][1]*v.y + Tinv.n[2][1]*v.z; @@ -419,7 +430,7 @@ dmnsn_transform_normal(dmnsn_matrix Tinv, dmnsn_vector v) return r; } -/// Transform a bounding box by a matrix. +/** Transform a bounding box by a matrix. */ dmnsn_bounding_box dmnsn_transform_bounding_box(dmnsn_matrix T, dmnsn_bounding_box box); @@ -431,7 +442,7 @@ dmnsn_bounding_box dmnsn_transform_bounding_box(dmnsn_matrix T, DMNSN_INLINE dmnsn_line dmnsn_transform_line(dmnsn_matrix T, dmnsn_line l) { - // 18 multiplications, 24 additions + /* 18 multiplications, 24 additions */ dmnsn_line ret; ret.x0 = dmnsn_transform_point(T, l.x0); ret.n = dmnsn_transform_direction(T, l.n); @@ -448,7 +459,7 @@ dmnsn_line_point(dmnsn_line l, double t) return dmnsn_vector_add(l.x0, dmnsn_vector_mul(t, l.n)); } -/// Add epsilon*l.n to l.x0, to avoid self-intersections. +/** Add epsilon*l.n to l.x0, to avoid self-intersections. */ DMNSN_INLINE dmnsn_line dmnsn_line_add_epsilon(dmnsn_line l) { @@ -477,7 +488,7 @@ dmnsn_symmetric_bounding_box(dmnsn_vector r) return box; } -/// Return whether \p p is within the axis-aligned bounding box. +/** Return whether \p p is within the axis-aligned bounding box. */ DMNSN_INLINE bool dmnsn_bounding_box_contains(dmnsn_bounding_box box, dmnsn_vector p) { @@ -485,11 +496,11 @@ dmnsn_bounding_box_contains(dmnsn_bounding_box box, dmnsn_vector p) && (p.x <= box.max.x && p.y <= box.max.y && p.z <= box.max.z); } -/// Return whether a bounding box is infinite. +/** Return whether a bounding box is infinite. */ DMNSN_INLINE bool dmnsn_bounding_box_is_infinite(dmnsn_bounding_box box) { - return box.min.x == -INFINITY; + return box.min.x == -DMNSN_INFINITY; } /** @@ -508,21 +519,32 @@ dmnsn_bounding_box_swallow(dmnsn_bounding_box box, dmnsn_vector point) return ret; } -/// Return whether a vector contains any NaN components. +/** Return whether a scalar is NaN. */ +DMNSN_INLINE bool +dmnsn_isnan(double n) +{ +#if DMNSN_C99 + return isnan(n); +#else + return n != n; +#endif +} + +/** Return whether a vector contains any NaN components. */ DMNSN_INLINE bool dmnsn_vector_isnan(dmnsn_vector v) { - return isnan(v.x) || isnan(v.y) || isnan(v.z); + return dmnsn_isnan(v.x) || dmnsn_isnan(v.y) || dmnsn_isnan(v.z); } -/// Return whether a matrix contains any NaN components. +/** Return whether a matrix contains any NaN components. */ DMNSN_INLINE bool dmnsn_matrix_isnan(dmnsn_matrix m) { size_t i, j; for (i = 0; i < 3; ++i) { for (j = 0; j < 4; ++j) { - if (isnan(m.n[i][j])) { + if (dmnsn_isnan(m.n[i][j])) { return true; } } @@ -530,14 +552,14 @@ dmnsn_matrix_isnan(dmnsn_matrix m) return false; } -/// Return whether a line contains any NaN entries. +/** Return whether a line contains any NaN entries. */ DMNSN_INLINE bool dmnsn_line_isnan(dmnsn_line l) { return dmnsn_vector_isnan(l.x0) || dmnsn_vector_isnan(l.n); } -/// Return whether a bounding box has any NaN components. +/** Return whether a bounding box has any NaN components. */ DMNSN_INLINE bool dmnsn_bounding_box_isnan(dmnsn_bounding_box box) { diff --git a/libdimension/dimension/interior.h b/libdimension/dimension/interior.h index 006e88d..0ff697d 100644 --- a/libdimension/dimension/interior.h +++ b/libdimension/dimension/interior.h @@ -23,9 +23,9 @@ * Object interiors. */ -/// An interior. +/** An interior. */ typedef struct dmnsn_interior { - double ior; ///< Refractive index. + double ior; /**< Refractive index. */ } dmnsn_interior; /** diff --git a/libdimension/dimension/light.h b/libdimension/dimension/light.h index 82b72b4..218611d 100644 --- a/libdimension/dimension/light.h +++ b/libdimension/dimension/light.h @@ -25,7 +25,7 @@ #include -// Forward-declar dmnsn_light +/* Forward-declar dmnsn_light */ typedef struct dmnsn_light dmnsn_light; /** @@ -54,12 +54,12 @@ typedef dmnsn_color dmnsn_light_illumination_fn(const dmnsn_light *light, */ typedef bool dmnsn_light_shadow_fn(const dmnsn_light *light, double t); -/// A light. +/** A light. */ struct dmnsn_light { - // Callbacks - dmnsn_light_direction_fn *direction_fn; ///< Direction callback. - dmnsn_light_illumination_fn *illumination_fn; ///< Illumination callback. - dmnsn_light_shadow_fn *shadow_fn; ///< Shadow callback. + /* Callbacks */ + dmnsn_light_direction_fn *direction_fn; /**< Direction callback. */ + dmnsn_light_illumination_fn *illumination_fn; /**< Illumination callback. */ + dmnsn_light_shadow_fn *shadow_fn; /**< Shadow callback. */ }; /** diff --git a/libdimension/dimension/malloc.h b/libdimension/dimension/malloc.h index e7dcd4a..742e3a2 100644 --- a/libdimension/dimension/malloc.h +++ b/libdimension/dimension/malloc.h @@ -25,7 +25,7 @@ * fails, they instead call dmnsn_error(). */ -#include // For size_t +#include /* For size_t */ /** * Allocate some memory. Always use dmnsn_free() to free this memory, never diff --git a/libdimension/dimension/map.h b/libdimension/dimension/map.h index f5642b5..7229a24 100644 --- a/libdimension/dimension/map.h +++ b/libdimension/dimension/map.h @@ -23,7 +23,7 @@ * Generic maps (backend for pigment_maps, etc.). */ -/// A map. +/** A map. */ typedef struct dmnsn_map dmnsn_map; /** diff --git a/libdimension/dimension/object.h b/libdimension/dimension/object.h index 1887119..c8e9d86 100644 --- a/libdimension/dimension/object.h +++ b/libdimension/dimension/object.h @@ -25,18 +25,18 @@ #include -// Forward-declare dmnsn_object +/* Forward-declare dmnsn_object */ typedef struct dmnsn_object dmnsn_object; -/// A type to represent a ray-object intersection. +/** A type to represent a ray-object intersection. */ typedef struct dmnsn_intersection { - dmnsn_line ray; ///< The ray that intersected. - double t; ///< The line index that intersected. + dmnsn_line ray; /**< The ray that intersected. */ + double t; /**< The line index that intersected. */ - /// The surface normal at the intersection point. + /** The surface normal at the intersection point. */ dmnsn_vector normal; - /// The object of intersection. + /** The object of intersection. */ const dmnsn_object *object; } dmnsn_intersection; @@ -71,32 +71,32 @@ typedef dmnsn_bounding_box dmnsn_object_bounding_fn(const dmnsn_object *object, */ typedef void dmnsn_object_precompute_fn(dmnsn_object *object); -/// Object callbacks. +/** Object callbacks. */ typedef struct dmnsn_object_vtable { - dmnsn_object_intersection_fn *intersection_fn; ///< Intersection callback. - dmnsn_object_inside_fn *inside_fn; ///< Inside callback. - dmnsn_object_bounding_fn *bounding_fn; ///< Bounding callback. - dmnsn_object_precompute_fn *precompute_fn; ///< Precomputation callback. + dmnsn_object_intersection_fn *intersection_fn; /**< Intersection callback. */ + dmnsn_object_inside_fn *inside_fn; /**< Inside callback. */ + dmnsn_object_bounding_fn *bounding_fn; /**< Bounding callback. */ + dmnsn_object_precompute_fn *precompute_fn; /**< Precomputation callback. */ } dmnsn_object_vtable; -/// An object. +/** An object. */ struct dmnsn_object { - const dmnsn_object_vtable *vtable; ///< Callbacks. + const dmnsn_object_vtable *vtable; /**< Callbacks. */ - dmnsn_texture *texture; ///< Surface properties. - dmnsn_interior *interior; ///< Interior properties. + dmnsn_texture *texture; /**< Surface properties. */ + dmnsn_interior *interior; /**< Interior properties. */ - dmnsn_matrix trans; ///< Transformation matrix. - dmnsn_matrix intrinsic_trans; ///< Transformations intrinsic to the object. + dmnsn_matrix trans; /**< Transformation matrix. */ + dmnsn_matrix intrinsic_trans; /**< Transformations intrinsic to the object. */ - dmnsn_array *children; ///< Child objects. - bool split_children; ///< Whether the child objects can be split. + dmnsn_array *children; /**< Child objects. */ + bool split_children; /**< Whether the child objects can be split. */ - // Precomputed values - bool precomputed; ///< @internal Whether the object is precomputed yet. - dmnsn_matrix trans_inv; ///< Inverse of the transformation matrix. - dmnsn_matrix pigment_trans; ///< Inverse transformation for the texture. - dmnsn_bounding_box bounding_box; ///< Bounding box in world coordinates. + /* Precomputed values */ + bool precomputed; /**< @internal Whether the object is precomputed yet. */ + dmnsn_matrix trans_inv; /**< Inverse of the transformation matrix. */ + dmnsn_matrix pigment_trans; /**< Inverse transformation for the texture. */ + dmnsn_bounding_box bounding_box; /**< Bounding box in world coordinates. */ }; /** @@ -132,7 +132,7 @@ dmnsn_object_intersection(const dmnsn_object *object, dmnsn_line line, dmnsn_line line_trans = dmnsn_transform_line(object->trans_inv, line); intersection->object = NULL; if (object->vtable->intersection_fn(object, line_trans, intersection)) { - // Get us back into world coordinates + /* Get us back into world coordinates */ intersection->ray = line; intersection->normal = dmnsn_vector_normalized( dmnsn_transform_normal(object->trans_inv, intersection->normal) @@ -141,9 +141,8 @@ dmnsn_object_intersection(const dmnsn_object *object, dmnsn_line line, intersection->object = object; } - dmnsn_assert(!isnan(intersection->t), "Intersection point is NaN."); - dmnsn_assert(!dmnsn_vector_isnan(intersection->normal), - "Intersection normal is NaN."); + dmnsn_assert(!dmnsn_isnan(intersection->t), "Intersection point is NaN."); + dmnsn_assert(!dmnsn_vector_isnan(intersection->normal), "Intersection normal is NaN."); return true; } else { diff --git a/libdimension/dimension/pattern.h b/libdimension/dimension/pattern.h index f1276ec..2caed07 100644 --- a/libdimension/dimension/pattern.h +++ b/libdimension/dimension/pattern.h @@ -24,7 +24,7 @@ * used for pigments and normals. */ -// Forward-declare dmnsn_pattern +/* Forward-declare dmnsn_pattern */ typedef struct dmnsn_pattern dmnsn_pattern; /** @@ -35,9 +35,9 @@ typedef struct dmnsn_pattern dmnsn_pattern; */ typedef double dmnsn_pattern_fn(const dmnsn_pattern *pattern, dmnsn_vector v); -/// A pattern. +/** A pattern. */ struct dmnsn_pattern { - dmnsn_pattern_fn *pattern_fn; ///< The pattern callback. + dmnsn_pattern_fn *pattern_fn; /**< The pattern callback. */ }; /** diff --git a/libdimension/dimension/pigment.h b/libdimension/dimension/pigment.h index 05bc6f6..14d8bae 100644 --- a/libdimension/dimension/pigment.h +++ b/libdimension/dimension/pigment.h @@ -23,7 +23,7 @@ * Object pigments. */ -// Forward-declare dmnsn_pigment +/* Forward-declare dmnsn_pigment */ typedef struct dmnsn_pigment dmnsn_pigment; /** @@ -41,18 +41,18 @@ typedef dmnsn_tcolor dmnsn_pigment_fn(const dmnsn_pigment *pigment, */ typedef void dmnsn_pigment_initialize_fn(dmnsn_pigment *pigment); -/// A pigment. +/** A pigment. */ struct dmnsn_pigment { - dmnsn_pigment_fn *pigment_fn; ///< The pigment callback. - dmnsn_pigment_initialize_fn *initialize_fn; ///< The initializer callback. + dmnsn_pigment_fn *pigment_fn; /**< The pigment callback. */ + dmnsn_pigment_initialize_fn *initialize_fn; /**< The initializer callback. */ - dmnsn_matrix trans; ///< Transformation matrix. - dmnsn_matrix trans_inv; ///< The inverse of the transformation matrix. + dmnsn_matrix trans; /**< Transformation matrix. */ + dmnsn_matrix trans_inv; /**< The inverse of the transformation matrix. */ - /// Quick color -- used for low-quality renders. + /** Quick color -- used for low-quality renders. */ dmnsn_tcolor quick_color; - bool initialized; /// @internal Whether the pigment is initialized. + bool initialized; /** @internal Whether the pigment is initialized. */ }; /** diff --git a/libdimension/dimension/pigments.h b/libdimension/dimension/pigments.h index edaf2b4..100016d 100644 --- a/libdimension/dimension/pigments.h +++ b/libdimension/dimension/pigments.h @@ -44,8 +44,8 @@ dmnsn_pigment *dmnsn_new_canvas_pigment(dmnsn_pool *pool, dmnsn_canvas *canvas); * Pigment map flags. */ typedef enum dmnsn_pigment_map_flags { - DMNSN_PIGMENT_MAP_REGULAR, ///< Calculate linear color gradients. - DMNSN_PIGMENT_MAP_SRGB ///< Calculate sRGB color gradients. + DMNSN_PIGMENT_MAP_REGULAR, /**< Calculate linear color gradients. */ + DMNSN_PIGMENT_MAP_SRGB /**< Calculate sRGB color gradients. */ } dmnsn_pigment_map_flags; /** diff --git a/libdimension/dimension/pool.h b/libdimension/dimension/pool.h index a744398..164bbbc 100644 --- a/libdimension/dimension/pool.h +++ b/libdimension/dimension/pool.h @@ -25,9 +25,9 @@ * once once a scene is rendered (for example). */ -#include // For size_t +#include /* For size_t */ -// Forward-declare dmnsn_pool. +/* Forward-declare dmnsn_pool. */ typedef struct dmnsn_pool dmnsn_pool; /** diff --git a/libdimension/dimension/scene.h b/libdimension/dimension/scene.h index b9f8c36..dd0c1ba 100644 --- a/libdimension/dimension/scene.h +++ b/libdimension/dimension/scene.h @@ -23,62 +23,62 @@ * Entire scenes. */ -/// Render quality flags. +/** Render quality flags. */ enum { - DMNSN_RENDER_NONE = 0, ///< Render nothing. - DMNSN_RENDER_PIGMENT = 1 << 0, ///< Render pigments. - DMNSN_RENDER_LIGHTS = 1 << 1, ///< Render lights and shadows. - DMNSN_RENDER_FINISH = 1 << 2, ///< Render object finishes. - DMNSN_RENDER_TRANSPARENCY = 1 << 3, ///< Render transparency/refraction. - DMNSN_RENDER_REFLECTION = 1 << 4, ///< Render specular reflection. - DMNSN_RENDER_FULL = ~DMNSN_RENDER_NONE ///< Render everything. + DMNSN_RENDER_NONE = 0, /**< Render nothing. */ + DMNSN_RENDER_PIGMENT = 1 << 0, /**< Render pigments. */ + DMNSN_RENDER_LIGHTS = 1 << 1, /**< Render lights and shadows. */ + DMNSN_RENDER_FINISH = 1 << 2, /**< Render object finishes. */ + DMNSN_RENDER_TRANSPARENCY = 1 << 3, /**< Render transparency/refraction. */ + DMNSN_RENDER_REFLECTION = 1 << 4, /**< Render specular reflection. */ + DMNSN_RENDER_FULL = ~DMNSN_RENDER_NONE /**< Render everything. */ }; -/// Render quality. +/** Render quality. */ typedef unsigned int dmnsn_quality; -/// An entire scene. +/** An entire scene. */ typedef struct dmnsn_scene { - // World attributes - dmnsn_pigment *background; ///< Background pigment. - dmnsn_texture *default_texture; ///< Default object texture. - dmnsn_interior *default_interior; ///< Default object interior. + /* World attributes */ + dmnsn_pigment *background; /**< Background pigment. */ + dmnsn_texture *default_texture; /**< Default object texture. */ + dmnsn_interior *default_interior; /**< Default object interior. */ - /// Canvas. + /** Canvas. */ dmnsn_canvas *canvas; - // Support for rendering image subregions. - size_t region_x; ///< The x position of the canvas in the broader image. - size_t region_y; ///< The y position of the canvas in the broader image. - size_t outer_width; ///< Width of the broader image. - size_t outer_height; ///< Height of the broader image. + /* Support for rendering image subregions. */ + size_t region_x; /**< The x position of the canvas in the broader image. */ + size_t region_y; /**< The y position of the canvas in the broader image. */ + size_t outer_width; /**< Width of the broader image. */ + size_t outer_height; /**< Height of the broader image. */ - /// Objects. + /** Objects. */ dmnsn_array *objects; - /// Lights. + /** Lights. */ dmnsn_array *lights; - /// Camera. + /** Camera. */ dmnsn_camera *camera; - /// Render quality. + /** Render quality. */ dmnsn_quality quality; - /// Recursion limit. + /** Recursion limit. */ unsigned int reclimit; - /// Adaptive depth control bailout. + /** Adaptive depth control bailout. */ double adc_bailout; - /// Number of parallel threads. + /** Number of parallel threads. */ unsigned int nthreads; - /// Timers. + /** Timers. */ dmnsn_timer bounding_timer; dmnsn_timer render_timer; - bool initialized; ///< @internal Whether the scene is initialized. + bool initialized; /**< @internal Whether the scene is initialized. */ } dmnsn_scene; /** diff --git a/libdimension/dimension/tcolor.h b/libdimension/dimension/tcolor.h index b50178d..4432dd1 100644 --- a/libdimension/dimension/tcolor.h +++ b/libdimension/dimension/tcolor.h @@ -23,19 +23,19 @@ * Colors with transparency information. */ -/// A transparent color. +/** A transparent color. */ typedef struct dmnsn_tcolor { - dmnsn_color c; ///< Color. - double T; ///< Transparency. - double F; ///< Proportion of filtered transparency. + dmnsn_color c; /**< Color. */ + double T; /**< Transparency. */ + double F; /**< Proportion of filtered transparency. */ } dmnsn_tcolor; -/// A standard format string for colors. +/** A standard format string for colors. */ #define DMNSN_TCOLOR_FORMAT "TColor<%g, %g, %g, %g, %g>" -/// The appropriate arguements to printf() a color. +/** The appropriate arguements to printf() a color. */ #define DMNSN_TCOLOR_PRINTF(tc) (tc).c.R, (tc).c.G, (tc).c.B, (tc).T, (tc).F -/// Create a tcolor. +/** Create a tcolor. */ DMNSN_INLINE dmnsn_tcolor dmnsn_new_tcolor(dmnsn_color c, double T, double F) { @@ -43,10 +43,10 @@ dmnsn_new_tcolor(dmnsn_color c, double T, double F) return ret; } -/// Convert a dmnsn_color into a dmnsn_tcolor. +/** Convert a dmnsn_color into a dmnsn_tcolor. */ #define DMNSN_TCOLOR(c) dmnsn_new_tcolor(c, 0.0, 0.0) -/// Create a tcolor with individually-specified components. +/** Create a tcolor with individually-specified components. */ DMNSN_INLINE dmnsn_tcolor dmnsn_new_tcolor5(double R, double G, double B, double T, double F) { @@ -54,7 +54,7 @@ dmnsn_new_tcolor5(double R, double G, double B, double T, double F) return ret; } -/// Return the color at \p n on a gradient from \p c1 at 0 to \p c2 at 1. +/** Return the color at \p n on a gradient from \p c1 at 0 to \p c2 at 1. */ DMNSN_INLINE dmnsn_tcolor dmnsn_tcolor_gradient(dmnsn_tcolor c1, dmnsn_tcolor c2, double n) { @@ -65,7 +65,7 @@ dmnsn_tcolor_gradient(dmnsn_tcolor c1, dmnsn_tcolor c2, double n) ); } -/// Filter \p light through \p filter. +/** Filter \p light through \p filter. */ DMNSN_INLINE dmnsn_color dmnsn_tcolor_filter(dmnsn_color light, dmnsn_tcolor filter) { @@ -75,7 +75,7 @@ dmnsn_tcolor_filter(dmnsn_color light, dmnsn_tcolor filter) return dmnsn_color_add(filtered, transmitted); } -/// Remove the filtered component of a tcolor. +/** Remove the filtered component of a tcolor. */ DMNSN_INLINE dmnsn_tcolor dmnsn_tcolor_remove_filter(dmnsn_tcolor tcolor) { @@ -89,7 +89,7 @@ dmnsn_tcolor_remove_filter(dmnsn_tcolor tcolor) return tcolor; } -/// Saturate the tcolor components to [0.0, 1.0]. +/** Saturate the tcolor components to [0.0, 1.0]. */ DMNSN_INLINE dmnsn_tcolor dmnsn_tcolor_saturate(dmnsn_tcolor tcolor) { @@ -99,14 +99,14 @@ dmnsn_tcolor_saturate(dmnsn_tcolor tcolor) return tcolor; } -/// Return whether a tcolor contains any NaN components. +/** Return whether a tcolor contains any NaN components. */ DMNSN_INLINE bool dmnsn_tcolor_isnan(dmnsn_tcolor tcolor) { - return dmnsn_color_isnan(tcolor.c) || isnan(tcolor.T) || isnan(tcolor.F); + return dmnsn_color_isnan(tcolor.c) || dmnsn_isnan(tcolor.T) || dmnsn_isnan(tcolor.F); } -// Standard tcolors +/* Standard tcolors */ -/// Clear. +/** Clear. */ #define dmnsn_clear dmnsn_new_tcolor5(0.0, 0.0, 0.0, 1.0, 0.0) diff --git a/libdimension/dimension/texture.h b/libdimension/dimension/texture.h index 58f5a80..df08a4a 100644 --- a/libdimension/dimension/texture.h +++ b/libdimension/dimension/texture.h @@ -23,15 +23,15 @@ * Object textures. */ -/// A complete texture. +/** A complete texture. */ typedef struct { - dmnsn_pigment *pigment; ///< Pigment. - dmnsn_finish finish; ///< Finish. + dmnsn_pigment *pigment; /**< Pigment. */ + dmnsn_finish finish; /**< Finish. */ - dmnsn_matrix trans; ///< Transformation matrix. - dmnsn_matrix trans_inv; ///< The inverse of the transformation matrix. + dmnsn_matrix trans; /**< Transformation matrix. */ + dmnsn_matrix trans_inv; /**< The inverse of the transformation matrix. */ - bool initialized; ///< @internal Whether the texture is initialized yet. + bool initialized; /**< @internal Whether the texture is initialized yet. */ } dmnsn_texture; /** diff --git a/libdimension/dimension/timer.h b/libdimension/dimension/timer.h index be1f3c0..55d66ff 100644 --- a/libdimension/dimension/timer.h +++ b/libdimension/dimension/timer.h @@ -23,14 +23,14 @@ * A platform-agnostic timer abstraction. */ -/// A platform-agnotic timer. +/** A platform-agnotic timer. */ typedef struct dmnsn_timer { - double real; ///< Wall-clock time. - double user; ///< Time spent executing. - double system; ///< Time spent waiting for the system. + double real; /**< Wall-clock time. */ + double user; /**< Time spent executing. */ + double system; /**< Time spent waiting for the system. */ } dmnsn_timer; -/// A standard format string for timers. +/** A standard format string for timers. */ #define DMNSN_TIMER_FORMAT "%.2fs (user: %.2fs; system: %.2fs)" /** * The appropriate arguments to printf() a timer. For example: diff --git a/libdimension/tests/Makefile.am b/libdimension/tests/Makefile.am index a2d78ba..0349850 100644 --- a/libdimension/tests/Makefile.am +++ b/libdimension/tests/Makefile.am @@ -33,6 +33,7 @@ check_PROGRAMS = warning.test \ png.test \ gl.test \ render.test \ + c89.test \ c99.test \ cxx.test TESTS = $(check_PROGRAMS) @@ -96,6 +97,11 @@ gl_test_LDADD = libdimension-tests.la render_test_SOURCES = render.c render_test_LDADD = libdimension-tests.la +c89_test_SOURCES = c89.c +c89_test_LDADD = libdimension-tests.la + +c89.o: CFLAGS += -std=c89 -Wpedantic + c99_test_SOURCES = c99.c c99_test_LDADD = libdimension-tests.la diff --git a/libdimension/tests/c89.c b/libdimension/tests/c89.c new file mode 100644 index 0000000..9393184 --- /dev/null +++ b/libdimension/tests/c89.c @@ -0,0 +1,32 @@ +/************************************************************************* + * Copyright (C) 2014 Tavian Barnes * + * * + * This file is part of The Dimension Test Suite. * + * * + * The Dimension Test Suite is free software; you can redistribute it * + * and/or modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 3 of the * + * License, or (at your option) any later version. * + * * + * The Dimension Test Suite is distributed in the hope that it will be * + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +/** + * @file + * Check C89 compliance of headers. + */ + +#include "dimension.h" +#include + +int +main(void) +{ + return EXIT_SUCCESS; +} -- cgit v1.2.3