common.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. /*
  2. * libxlsxwriter
  3. *
  4. * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
  5. */
  6. /**
  7. * @file common.h
  8. *
  9. * @brief Common functions and defines for the libxlsxwriter library.
  10. *
  11. * <!-- Copyright 2014-2018, John McNamara, [email protected] -->
  12. *
  13. */
  14. #ifndef __LXW_COMMON_H__
  15. #define __LXW_COMMON_H__
  16. #include <time.h>
  17. #include "third_party/queue.h"
  18. #include "third_party/tree.h"
  19. #ifndef TESTING
  20. #define STATIC static
  21. #else
  22. #define STATIC
  23. #endif
  24. /** Integer data type to represent a row value. Equivalent to `uint32_t`.
  25. *
  26. * The maximum row in Excel is 1,048,576.
  27. */
  28. typedef uint32_t lxw_row_t;
  29. /** Integer data type to represent a column value. Equivalent to `uint16_t`.
  30. *
  31. * The maximum column in Excel is 16,384.
  32. */
  33. typedef uint16_t lxw_col_t;
  34. /** Boolean values used in libxlsxwriter. */
  35. enum lxw_boolean {
  36. /** False value. */
  37. LXW_FALSE,
  38. /** True value. */
  39. LXW_TRUE
  40. };
  41. /**
  42. * @brief Error codes from libxlsxwriter functions.
  43. *
  44. * See the `lxw_strerror()` function for an example of how to convert the
  45. * enum number to a descriptive error message string.
  46. */
  47. typedef enum lxw_error {
  48. /** No error. */
  49. LXW_NO_ERROR = 0,
  50. /** Memory error, failed to malloc() required memory. */
  51. LXW_ERROR_MEMORY_MALLOC_FAILED,
  52. /** Error creating output xlsx file. Usually a permissions error. */
  53. LXW_ERROR_CREATING_XLSX_FILE,
  54. /** Error encountered when creating a tmpfile during file assembly. */
  55. LXW_ERROR_CREATING_TMPFILE,
  56. /** Zlib error with a file operation while creating xlsx file. */
  57. LXW_ERROR_ZIP_FILE_OPERATION,
  58. /** Zlib error when adding sub file to xlsx file. */
  59. LXW_ERROR_ZIP_FILE_ADD,
  60. /** Zlib error when closing xlsx file. */
  61. LXW_ERROR_ZIP_CLOSE,
  62. /** NULL function parameter ignored. */
  63. LXW_ERROR_NULL_PARAMETER_IGNORED,
  64. /** Function parameter validation error. */
  65. LXW_ERROR_PARAMETER_VALIDATION,
  66. /** Worksheet name exceeds Excel's limit of 31 characters. */
  67. LXW_ERROR_SHEETNAME_LENGTH_EXCEEDED,
  68. /** Worksheet name contains invalid Excel character: '[]:*?/\\' */
  69. LXW_ERROR_INVALID_SHEETNAME_CHARACTER,
  70. /** Worksheet name is already in use. */
  71. LXW_ERROR_SHEETNAME_ALREADY_USED,
  72. /** Parameter exceeds Excel's limit of 32 characters. */
  73. LXW_ERROR_32_STRING_LENGTH_EXCEEDED,
  74. /** Parameter exceeds Excel's limit of 128 characters. */
  75. LXW_ERROR_128_STRING_LENGTH_EXCEEDED,
  76. /** Parameter exceeds Excel's limit of 255 characters. */
  77. LXW_ERROR_255_STRING_LENGTH_EXCEEDED,
  78. /** String exceeds Excel's limit of 32,767 characters. */
  79. LXW_ERROR_MAX_STRING_LENGTH_EXCEEDED,
  80. /** Error finding internal string index. */
  81. LXW_ERROR_SHARED_STRING_INDEX_NOT_FOUND,
  82. /** Worksheet row or column index out of range. */
  83. LXW_ERROR_WORKSHEET_INDEX_OUT_OF_RANGE,
  84. /** Maximum number of worksheet URLs (65530) exceeded. */
  85. LXW_ERROR_WORKSHEET_MAX_NUMBER_URLS_EXCEEDED,
  86. /** Couldn't read image dimensions or DPI. */
  87. LXW_ERROR_IMAGE_DIMENSIONS,
  88. LXW_MAX_ERRNO
  89. } lxw_error;
  90. /** @brief Struct to represent a date and time in Excel.
  91. *
  92. * Struct to represent a date and time in Excel. See @ref working_with_dates.
  93. */
  94. typedef struct lxw_datetime {
  95. /** Year : 1900 - 9999 */
  96. int year;
  97. /** Month : 1 - 12 */
  98. int month;
  99. /** Day : 1 - 31 */
  100. int day;
  101. /** Hour : 0 - 23 */
  102. int hour;
  103. /** Minute : 0 - 59 */
  104. int min;
  105. /** Seconds : 0 - 59.999 */
  106. double sec;
  107. } lxw_datetime;
  108. enum lxw_custom_property_types {
  109. LXW_CUSTOM_NONE,
  110. LXW_CUSTOM_STRING,
  111. LXW_CUSTOM_DOUBLE,
  112. LXW_CUSTOM_INTEGER,
  113. LXW_CUSTOM_BOOLEAN,
  114. LXW_CUSTOM_DATETIME
  115. };
  116. /* Excel sheetname max of 31 chars. */
  117. #define LXW_SHEETNAME_MAX 31
  118. /* Max with all worksheet chars 4xUTF-8 bytes + start and end quotes + \0. */
  119. #define LXW_MAX_SHEETNAME_LENGTH ((LXW_SHEETNAME_MAX * 4) + 2 + 1)
  120. /* Max col string length. */
  121. #define LXW_MAX_COL_NAME_LENGTH sizeof("$XFD")
  122. /* Max row string length. */
  123. #define LXW_MAX_ROW_NAME_LENGTH sizeof("$1048576")
  124. /* Max cell string length. */
  125. #define LXW_MAX_CELL_NAME_LENGTH sizeof("$XFWD$1048576")
  126. /* Max range: $XFWD$1048576:$XFWD$1048576\0 */
  127. #define LXW_MAX_CELL_RANGE_LENGTH (LXW_MAX_CELL_NAME_LENGTH * 2)
  128. /* Max range formula Sheet1!$A$1:$C$5$ style. */
  129. #define LXW_MAX_FORMULA_RANGE_LENGTH (LXW_MAX_SHEETNAME_LENGTH + LXW_MAX_CELL_RANGE_LENGTH)
  130. /* Datetime string length. */
  131. #define LXW_DATETIME_LENGTH sizeof("2016-12-12T23:00:00Z")
  132. #define LXW_EPOCH_1900 0
  133. #define LXW_EPOCH_1904 1
  134. #define LXW_UINT32_T_LENGTH sizeof("4294967296")
  135. #define LXW_FILENAME_LENGTH 128
  136. #define LXW_IGNORE 1
  137. #define LXW_SCHEMA_MS "http://schemas.microsoft.com/office/2006/relationships"
  138. #define LXW_SCHEMA_ROOT "http://schemas.openxmlformats.org"
  139. #define LXW_SCHEMA_DRAWING LXW_SCHEMA_ROOT "/drawingml/2006"
  140. #define LXW_SCHEMA_OFFICEDOC LXW_SCHEMA_ROOT "/officeDocument/2006"
  141. #define LXW_SCHEMA_PACKAGE LXW_SCHEMA_ROOT "/package/2006/relationships"
  142. #define LXW_SCHEMA_DOCUMENT LXW_SCHEMA_ROOT "/officeDocument/2006/relationships"
  143. #define LXW_SCHEMA_CONTENT LXW_SCHEMA_ROOT "/package/2006/content-types"
  144. #define LXW_ERROR(message) \
  145. fprintf(stderr, "[ERROR][%s:%d]: " message "\n", __FILE__, __LINE__)
  146. #define LXW_MEM_ERROR() \
  147. LXW_ERROR("Memory allocation failed.")
  148. #define GOTO_LABEL_ON_MEM_ERROR(pointer, label) \
  149. if (!pointer) { \
  150. LXW_MEM_ERROR(); \
  151. goto label; \
  152. }
  153. #define RETURN_ON_MEM_ERROR(pointer, error) \
  154. if (!pointer) { \
  155. LXW_MEM_ERROR(); \
  156. return error; \
  157. }
  158. #define RETURN_VOID_ON_MEM_ERROR(pointer) \
  159. if (!pointer) { \
  160. LXW_MEM_ERROR(); \
  161. return; \
  162. }
  163. #define RETURN_ON_ERROR(error) \
  164. if (error) \
  165. return error;
  166. #define LXW_WARN(message) \
  167. fprintf(stderr, "[WARNING]: " message "\n")
  168. /* We can't use variadic macros here since we support ANSI C. */
  169. #define LXW_WARN_FORMAT(message) \
  170. fprintf(stderr, "[WARNING]: " message "\n")
  171. #define LXW_WARN_FORMAT1(message, var) \
  172. fprintf(stderr, "[WARNING]: " message "\n", var)
  173. #define LXW_WARN_FORMAT2(message, var1, var2) \
  174. fprintf(stderr, "[WARNING]: " message "\n", var1, var2)
  175. /* Chart axis type checks. */
  176. #define LXW_WARN_CAT_AXIS_ONLY(function) \
  177. if (!axis->is_category) { \
  178. fprintf(stderr, "[WARNING]: " \
  179. function "() is only valid for category axes\n"); \
  180. return; \
  181. }
  182. #define LXW_WARN_VALUE_AXIS_ONLY(function) \
  183. if (!axis->is_value) { \
  184. fprintf(stderr, "[WARNING]: " \
  185. function "() is only valid for value axes\n"); \
  186. return; \
  187. }
  188. #define LXW_WARN_DATE_AXIS_ONLY(function) \
  189. if (!axis->is_date) { \
  190. fprintf(stderr, "[WARNING]: " \
  191. function "() is only valid for date axes\n"); \
  192. return; \
  193. }
  194. #define LXW_WARN_CAT_AND_DATE_AXIS_ONLY(function) \
  195. if (!axis->is_category && !axis->is_date) { \
  196. fprintf(stderr, "[WARNING]: " \
  197. function "() is only valid for category and date axes\n"); \
  198. return; \
  199. }
  200. #define LXW_WARN_VALUE_AND_DATE_AXIS_ONLY(function) \
  201. if (!axis->is_value && !axis->is_date) { \
  202. fprintf(stderr, "[WARNING]: " \
  203. function "() is only valid for value and date axes\n"); \
  204. return; \
  205. }
  206. #ifndef LXW_BIG_ENDIAN
  207. #define LXW_UINT32_NETWORK(n) ((((n) & 0xFF) << 24) | \
  208. (((n) & 0xFF00) << 8) | \
  209. (((n) & 0xFF0000) >> 8) | \
  210. (((n) & 0xFF000000) >> 24))
  211. #define LXW_UINT16_NETWORK(n) ((((n) & 0x00FF) << 8) | (((n) & 0xFF00) >> 8))
  212. #define LXW_UINT32_HOST(n) (n)
  213. #else
  214. #define LXW_UINT32_NETWORK(n) (n)
  215. #define LXW_UINT16_NETWORK(n) (n)
  216. #define LXW_UINT32_HOST(n) ((((n) & 0xFF) << 24) | \
  217. (((n) & 0xFF00) << 8) | \
  218. (((n) & 0xFF0000) >> 8) | \
  219. (((n) & 0xFF000000) >> 24))
  220. #endif
  221. /* *INDENT-OFF* */
  222. #ifdef __cplusplus
  223. extern "C" {
  224. #endif
  225. /* *INDENT-ON* */
  226. /* Compilers that have a native snprintf() can use it directly. */
  227. #ifdef _MSC_VER
  228. #define LXW_HAS_SNPRINTF
  229. #endif
  230. #ifdef LXW_HAS_SNPRINTF
  231. #define lxw_snprintf snprintf
  232. #else
  233. #define lxw_snprintf __builtin_snprintf
  234. #endif
  235. /* Define a snprintf for MSVC 2010. */
  236. #if defined(_MSC_VER) && _MSC_VER < 1900
  237. #include <stdarg.h>
  238. #define snprintf msvc2010_snprintf
  239. #define vsnprintf msvc2010_vsnprintf
  240. __inline int
  241. msvc2010_vsnprintf(char *str, size_t size, const char *format, va_list ap)
  242. {
  243. int count = -1;
  244. if (size != 0)
  245. count = _vsnprintf_s(str, size, _TRUNCATE, format, ap);
  246. if (count == -1)
  247. count = _vscprintf(format, ap);
  248. return count;
  249. }
  250. __inline int
  251. msvc2010_snprintf(char *str, size_t size, const char *format, ...)
  252. {
  253. int count;
  254. va_list ap;
  255. va_start(ap, format);
  256. count = msvc2010_vsnprintf(str, size, format, ap);
  257. va_end(ap);
  258. return count;
  259. }
  260. #endif
  261. /* Safer strcpy for fixed width char arrays. */
  262. #define lxw_strcpy(dest, src) \
  263. lxw_snprintf(dest, sizeof(dest), "%s", src)
  264. /* Define the queue.h structs for the formats list. */
  265. STAILQ_HEAD(lxw_formats, lxw_format);
  266. /* Define the queue.h structs for the generic data structs. */
  267. STAILQ_HEAD(lxw_tuples, lxw_tuple);
  268. STAILQ_HEAD(lxw_custom_properties, lxw_custom_property);
  269. typedef struct lxw_tuple {
  270. char *key;
  271. char *value;
  272. STAILQ_ENTRY (lxw_tuple) list_pointers;
  273. } lxw_tuple;
  274. /* Define custom property used in workbook.c and custom.c. */
  275. typedef struct lxw_custom_property {
  276. enum lxw_custom_property_types type;
  277. char *name;
  278. union {
  279. char *string;
  280. double number;
  281. int32_t integer;
  282. uint8_t boolean;
  283. lxw_datetime datetime;
  284. } u;
  285. STAILQ_ENTRY (lxw_custom_property) list_pointers;
  286. } lxw_custom_property;
  287. /* Declarations required for unit testing. */
  288. #ifdef TESTING
  289. #endif /* TESTING */
  290. /* *INDENT-OFF* */
  291. #ifdef __cplusplus
  292. }
  293. #endif
  294. /* *INDENT-ON* */
  295. #endif /* __LXW_COMMON_H__ */