fast_excel 0.6.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +1 -1
  3. data/CHANGELOG.md +3 -1
  4. data/Rakefile +4 -1
  5. data/fast_excel.gemspec +1 -1
  6. data/lib/fast_excel/binding/workbook.rb +9 -0
  7. data/lib/fast_excel/binding/worksheet.rb +2 -2
  8. data/lib/fast_excel/binding.rb +16 -13
  9. data/libxlsxwriter/.cirrus.yml +9 -0
  10. data/libxlsxwriter/.github/workflows/cmake_actions.yml +10 -6
  11. data/libxlsxwriter/.github/workflows/code_style.yml +2 -0
  12. data/libxlsxwriter/.github/workflows/make_32_actions.yml +43 -0
  13. data/libxlsxwriter/.github/workflows/windows_build.yml +7 -6
  14. data/libxlsxwriter/.github/workflows/zig_build.yml +1 -3
  15. data/libxlsxwriter/.gitignore +9 -7
  16. data/libxlsxwriter/.indent.pro +6 -0
  17. data/libxlsxwriter/CMakeLists.txt +377 -238
  18. data/libxlsxwriter/Changes.txt +189 -0
  19. data/libxlsxwriter/LICENSE.txt +1 -1
  20. data/libxlsxwriter/Makefile +36 -4
  21. data/libxlsxwriter/Readme.md +1 -1
  22. data/libxlsxwriter/build.zig +181 -92
  23. data/libxlsxwriter/build.zig.zon +15 -4
  24. data/libxlsxwriter/cocoapods/libxlsxwriter-umbrella.h +4 -0
  25. data/libxlsxwriter/include/xlsxwriter/app.h +2 -1
  26. data/libxlsxwriter/include/xlsxwriter/chart.h +134 -1
  27. data/libxlsxwriter/include/xlsxwriter/chartsheet.h +2 -1
  28. data/libxlsxwriter/include/xlsxwriter/comment.h +2 -1
  29. data/libxlsxwriter/include/xlsxwriter/common.h +12 -8
  30. data/libxlsxwriter/include/xlsxwriter/content_types.h +3 -1
  31. data/libxlsxwriter/include/xlsxwriter/core.h +2 -1
  32. data/libxlsxwriter/include/xlsxwriter/custom.h +2 -1
  33. data/libxlsxwriter/include/xlsxwriter/drawing.h +2 -1
  34. data/libxlsxwriter/include/xlsxwriter/format.h +34 -3
  35. data/libxlsxwriter/include/xlsxwriter/hash_table.h +2 -1
  36. data/libxlsxwriter/include/xlsxwriter/metadata.h +5 -1
  37. data/libxlsxwriter/include/xlsxwriter/packager.h +6 -1
  38. data/libxlsxwriter/include/xlsxwriter/relationships.h +3 -1
  39. data/libxlsxwriter/include/xlsxwriter/rich_value.h +51 -0
  40. data/libxlsxwriter/include/xlsxwriter/rich_value_rel.h +50 -0
  41. data/libxlsxwriter/include/xlsxwriter/rich_value_structure.h +53 -0
  42. data/libxlsxwriter/include/xlsxwriter/rich_value_types.h +49 -0
  43. data/libxlsxwriter/include/xlsxwriter/shared_strings.h +2 -1
  44. data/libxlsxwriter/include/xlsxwriter/styles.h +2 -1
  45. data/libxlsxwriter/include/xlsxwriter/table.h +2 -1
  46. data/libxlsxwriter/include/xlsxwriter/theme.h +2 -1
  47. data/libxlsxwriter/include/xlsxwriter/third_party/ioapi.h +4 -4
  48. data/libxlsxwriter/include/xlsxwriter/third_party/zip.h +3 -3
  49. data/libxlsxwriter/include/xlsxwriter/utility.h +58 -7
  50. data/libxlsxwriter/include/xlsxwriter/vml.h +2 -1
  51. data/libxlsxwriter/include/xlsxwriter/workbook.h +59 -2
  52. data/libxlsxwriter/include/xlsxwriter/worksheet.h +159 -13
  53. data/libxlsxwriter/include/xlsxwriter/xmlwriter.h +11 -10
  54. data/libxlsxwriter/include/xlsxwriter.h +5 -4
  55. data/libxlsxwriter/libxlsxwriter.podspec +6 -6
  56. data/libxlsxwriter/src/Makefile +2 -1
  57. data/libxlsxwriter/src/app.c +2 -1
  58. data/libxlsxwriter/src/chart.c +360 -63
  59. data/libxlsxwriter/src/chartsheet.c +2 -1
  60. data/libxlsxwriter/src/comment.c +2 -1
  61. data/libxlsxwriter/src/content_types.c +22 -1
  62. data/libxlsxwriter/src/core.c +2 -1
  63. data/libxlsxwriter/src/custom.c +2 -1
  64. data/libxlsxwriter/src/drawing.c +7 -3
  65. data/libxlsxwriter/src/format.c +21 -1
  66. data/libxlsxwriter/src/hash_table.c +2 -1
  67. data/libxlsxwriter/src/metadata.c +176 -20
  68. data/libxlsxwriter/src/packager.c +306 -6
  69. data/libxlsxwriter/src/relationships.c +25 -1
  70. data/libxlsxwriter/src/rich_value.c +191 -0
  71. data/libxlsxwriter/src/rich_value_rel.c +142 -0
  72. data/libxlsxwriter/src/rich_value_structure.c +162 -0
  73. data/libxlsxwriter/src/rich_value_types.c +199 -0
  74. data/libxlsxwriter/src/shared_strings.c +2 -1
  75. data/libxlsxwriter/src/styles.c +31 -7
  76. data/libxlsxwriter/src/table.c +2 -1
  77. data/libxlsxwriter/src/theme.c +2 -1
  78. data/libxlsxwriter/src/utility.c +136 -46
  79. data/libxlsxwriter/src/vml.c +2 -1
  80. data/libxlsxwriter/src/workbook.c +191 -10
  81. data/libxlsxwriter/src/worksheet.c +514 -34
  82. data/libxlsxwriter/src/xmlwriter.c +17 -22
  83. data/libxlsxwriter/third_party/minizip/Makefile.orig +1 -1
  84. data/libxlsxwriter/third_party/minizip/configure.ac +1 -1
  85. data/libxlsxwriter/third_party/minizip/ioapi.h +6 -6
  86. data/libxlsxwriter/third_party/minizip/miniunz.c +16 -2
  87. data/libxlsxwriter/third_party/minizip/unzip.c +4 -4
  88. data/libxlsxwriter/third_party/minizip/unzip.h +1 -1
  89. data/libxlsxwriter/third_party/minizip/zip.c +5 -5
  90. data/libxlsxwriter/third_party/minizip/zip.h +3 -3
  91. data/libxlsxwriter/version.txt +1 -1
  92. data/test/validations_test.rb +3 -3
  93. data/test/worksheet_test.rb +10 -2
  94. metadata +11 -4
  95. data/libxlsxwriter/cmake/FindMINIZIP.cmake +0 -121
  96. data/libxlsxwriter/cmake/FindPackage.cmake +0 -183
  97. data/libxlsxwriter/cmake/i686-toolchain.cmake +0 -7
@@ -3,7 +3,8 @@
3
3
  *
4
4
  * Used in conjunction with the libxlsxwriter library.
5
5
  *
6
- * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
6
+ * SPDX-License-Identifier: BSD-2-Clause
7
+ * Copyright 2014-2026, John McNamara, jmcnamara@cpan.org.
7
8
  *
8
9
  */
9
10
 
@@ -39,6 +40,8 @@ char *error_strings[LXW_MAX_ERRNO + 1] = {
39
40
  "Feature is not currently supported in this configuration.",
40
41
  "NULL function parameter ignored.",
41
42
  "Function parameter validation error.",
43
+ "Function string parameter is empty.",
44
+ "Datetime struct parameter has an invalid field value.",
42
45
  "Worksheet name exceeds Excel's limit of 31 characters.",
43
46
  "Worksheet name cannot contain invalid characters: '[ ] : * ? / \\'",
44
47
  "Worksheet name cannot start or end with an apostrophe.",
@@ -250,18 +253,39 @@ lxw_row_t
250
253
  lxw_name_to_row(const char *row_str)
251
254
  {
252
255
  lxw_row_t row_num = 0;
253
- const char *p = row_str;
256
+
257
+ if (!row_str)
258
+ return row_num;
254
259
 
255
260
  /* Skip the column letters and absolute symbol of the A1 cell. */
256
- while (p && !isdigit((unsigned char) *p))
257
- p++;
261
+ while (*row_str && !isdigit((unsigned char) *row_str))
262
+ row_str++;
258
263
 
259
264
  /* Convert the row part of the A1 cell to a number. */
260
- if (p)
261
- row_num = atoi(p);
265
+ if (*row_str)
266
+ row_num = atoi(row_str);
262
267
 
263
268
  if (row_num)
264
- return row_num - 1;
269
+ row_num--;
270
+
271
+ return row_num;
272
+ }
273
+
274
+ /*
275
+ * Convert the second row of an Excel range ref to a zero indexed number.
276
+ */
277
+ uint32_t
278
+ lxw_name_to_row_2(const char *row_str)
279
+ {
280
+ if (!row_str)
281
+ return 0;
282
+
283
+ /* Find the : separator in the range. */
284
+ while (*row_str && *row_str != ':')
285
+ row_str++;
286
+
287
+ if (*row_str)
288
+ return lxw_name_to_row(++row_str);
265
289
  else
266
290
  return 0;
267
291
  }
@@ -273,52 +297,103 @@ lxw_col_t
273
297
  lxw_name_to_col(const char *col_str)
274
298
  {
275
299
  lxw_col_t col_num = 0;
276
- const char *p = col_str;
300
+
301
+ if (!col_str)
302
+ return col_num;
277
303
 
278
304
  /* Convert leading column letters of A1 cell. Ignore absolute $ marker. */
279
- while (p && (isupper((unsigned char) *p) || *p == '$')) {
280
- if (*p != '$')
281
- col_num = (col_num * 26) + (*p - 'A' + 1);
282
- p++;
305
+ while (*col_str && (isupper((unsigned char) *col_str) || *col_str == '$')) {
306
+ if (*col_str != '$')
307
+ col_num = (col_num * 26) + (*col_str - 'A' + 1);
308
+ col_str++;
283
309
  }
284
310
 
285
- return col_num - 1;
311
+ if (col_num)
312
+ col_num--;
313
+
314
+ return col_num;
286
315
  }
287
316
 
288
317
  /*
289
- * Convert the second row of an Excel range ref to a zero indexed number.
318
+ * Convert the second column of an Excel range ref to a zero indexed number.
290
319
  */
291
- uint32_t
292
- lxw_name_to_row_2(const char *row_str)
320
+ uint16_t
321
+ lxw_name_to_col_2(const char *col_str)
293
322
  {
294
- const char *p = row_str;
323
+ if (!col_str)
324
+ return 0;
295
325
 
296
326
  /* Find the : separator in the range. */
297
- while (p && *p != ':')
298
- p++;
327
+ while (*col_str && *col_str != ':')
328
+ col_str++;
299
329
 
300
- if (p)
301
- return lxw_name_to_row(++p);
330
+ if (*col_str)
331
+ return lxw_name_to_col(++col_str);
302
332
  else
303
- return -1;
333
+ return 0;
304
334
  }
305
335
 
306
- /*
307
- * Convert the second column of an Excel range ref to a zero indexed number.
308
- */
309
- uint16_t
310
- lxw_name_to_col_2(const char *col_str)
336
+ lxw_error
337
+ lxw_datetime_validate(lxw_datetime *datetime)
311
338
  {
312
- const char *p = col_str;
339
+ if (!datetime)
340
+ return LXW_ERROR_DATETIME_VALIDATION;
313
341
 
314
- /* Find the : separator in the range. */
315
- while (p && *p != ':')
316
- p++;
342
+ /*
343
+ * Excel uses the year 1900 as the default epoch but it uses 1899-12-31 as
344
+ * the 0 date and internally we use the 0-0-0 date for time only values.
345
+ */
346
+ if (datetime->year < 1900 &&
347
+ !(datetime->year == 0 &&
348
+ datetime->month == 0 && datetime->day == 0) &&
349
+ !(datetime->year == 1899 &&
350
+ datetime->month == 12 && datetime->day == 31)) {
317
351
 
318
- if (p)
319
- return lxw_name_to_col(++p);
320
- else
321
- return -1;
352
+ LXW_WARN_FORMAT1("lxw_datetime_validate(): invalid year: %d. "
353
+ "Valid range is 1900-9999.", datetime->year);
354
+
355
+ return LXW_ERROR_DATETIME_VALIDATION;
356
+ }
357
+
358
+ if (datetime->year > 9999) {
359
+ LXW_WARN_FORMAT1("lxw_datetime_validate(): invalid year: %d. "
360
+ "Valid range is 1900-9999.", datetime->year);
361
+ return LXW_ERROR_DATETIME_VALIDATION;
362
+ }
363
+
364
+ if (datetime->year != 0) {
365
+ if (datetime->month < 1 || datetime->month > 12) {
366
+ LXW_WARN_FORMAT1("lxw_datetime_validate(): invalid month: %d. "
367
+ "Valid range is 1-12.", datetime->month);
368
+ return LXW_ERROR_DATETIME_VALIDATION;
369
+ }
370
+
371
+ if (datetime->day < 1 || datetime->day > 31) {
372
+ LXW_WARN_FORMAT1("lxw_datetime_validate(): invalid day: %d. "
373
+ "Valid range is 1-31.", datetime->day);
374
+ return LXW_ERROR_DATETIME_VALIDATION;
375
+ }
376
+ }
377
+
378
+ if (datetime->hour < 0 || datetime->hour > 23) {
379
+ LXW_WARN_FORMAT1("lxw_datetime_validate(): invalid hour: %d. "
380
+ "Valid range is 0-23.", datetime->hour);
381
+ return LXW_ERROR_DATETIME_VALIDATION;
382
+ }
383
+
384
+ if (datetime->min < 0 || datetime->min > 59) {
385
+ LXW_WARN_FORMAT1("lxw_datetime_validate(): invalid minute: %d. "
386
+ "Valid range is 0-59.", datetime->min);
387
+ return LXW_ERROR_DATETIME_VALIDATION;
388
+ }
389
+
390
+ if (datetime->sec < 0.0 || datetime->sec >= 60.0) {
391
+ LXW_WARN_FORMAT1("lxw_datetime_validate(): invalid seconds: %.3f. "
392
+ "Valid range is 0.0-59.999.", datetime->sec);
393
+ return LXW_ERROR_DATETIME_VALIDATION;
394
+ }
395
+
396
+ return LXW_NO_ERROR;
322
397
  }
323
398
 
324
399
  /*
@@ -326,7 +401,8 @@ lxw_name_to_col_2(const char *col_str)
326
401
  * or 1904 epoch.
327
402
  */
328
403
  double
329
- lxw_datetime_to_excel_date_epoch(lxw_datetime *datetime, uint8_t date_1904)
404
+ lxw_datetime_to_excel_date_with_epoch(lxw_datetime *datetime,
405
+ uint8_t use_1904_epoch)
330
406
  {
331
407
  int year = datetime->year;
332
408
  int month = datetime->month;
@@ -335,8 +411,8 @@ lxw_datetime_to_excel_date_epoch(lxw_datetime *datetime, uint8_t date_1904)
335
411
  int min = datetime->min;
336
412
  double sec = datetime->sec;
337
413
  double seconds;
338
- int epoch = date_1904 ? 1904 : 1900;
339
- int offset = date_1904 ? 4 : 0;
414
+ int epoch = use_1904_epoch ? 1904 : 1900;
415
+ int offset = use_1904_epoch ? 4 : 0;
340
416
  int norm = 300;
341
417
  int range;
342
418
  /* Set month days and check for leap year. */
@@ -345,9 +421,12 @@ lxw_datetime_to_excel_date_epoch(lxw_datetime *datetime, uint8_t date_1904)
345
421
  int days = 0;
346
422
  int i;
347
423
 
424
+ if (lxw_datetime_validate(datetime) != LXW_NO_ERROR)
425
+ return 0.0;
426
+
348
427
  /* For times without dates set the default date for the epoch. */
349
428
  if (!year) {
350
- if (!date_1904) {
429
+ if (!use_1904_epoch) {
351
430
  year = 1899;
352
431
  month = 12;
353
432
  day = 31;
@@ -363,7 +442,7 @@ lxw_datetime_to_excel_date_epoch(lxw_datetime *datetime, uint8_t date_1904)
363
442
  seconds = (hour * 60 * 60 + min * 60 + sec) / (24 * 60 * 60.0);
364
443
 
365
444
  /* Special cases for Excel dates in the 1900 epoch. */
366
- if (!date_1904) {
445
+ if (!use_1904_epoch) {
367
446
  /* Excel 1900 epoch. */
368
447
  if (year == 1899 && month == 12 && day == 31)
369
448
  return seconds;
@@ -412,7 +491,7 @@ lxw_datetime_to_excel_date_epoch(lxw_datetime *datetime, uint8_t date_1904)
412
491
  days -= leap;
413
492
 
414
493
  /* Adjust for Excel erroneously treating 1900 as a leap year. */
415
- if (!date_1904 && days > 59)
494
+ if (!use_1904_epoch && days > 59)
416
495
  days++;
417
496
 
418
497
  return days + seconds;
@@ -424,7 +503,7 @@ lxw_datetime_to_excel_date_epoch(lxw_datetime *datetime, uint8_t date_1904)
424
503
  double
425
504
  lxw_datetime_to_excel_datetime(lxw_datetime *datetime)
426
505
  {
427
- return lxw_datetime_to_excel_date_epoch(datetime, LXW_FALSE);
506
+ return lxw_datetime_to_excel_date_with_epoch(datetime, LXW_FALSE);
428
507
  }
429
508
 
430
509
  /*
@@ -434,7 +513,7 @@ lxw_datetime_to_excel_datetime(lxw_datetime *datetime)
434
513
  double
435
514
  lxw_unixtime_to_excel_date(int64_t unixtime)
436
515
  {
437
- return lxw_unixtime_to_excel_date_epoch(unixtime, LXW_FALSE);
516
+ return lxw_unixtime_to_excel_date_with_epoch(unixtime, LXW_FALSE);
438
517
  }
439
518
 
440
519
  /*
@@ -442,14 +521,15 @@ lxw_unixtime_to_excel_date(int64_t unixtime)
442
521
  * 1900 or 1904 epoch.
443
522
  */
444
523
  double
445
- lxw_unixtime_to_excel_date_epoch(int64_t unixtime, uint8_t date_1904)
524
+ lxw_unixtime_to_excel_date_with_epoch(int64_t unixtime,
525
+ uint8_t use_1904_epoch)
446
526
  {
447
527
  double excel_datetime = 0.0;
448
- double epoch = date_1904 ? 24107.0 : 25568.0;
528
+ double epoch = use_1904_epoch ? 24107.0 : 25568.0;
449
529
 
450
530
  excel_datetime = epoch + (unixtime / (24 * 60 * 60.0));
451
531
 
452
- if (!date_1904 && excel_datetime >= 60.0)
532
+ if (!use_1904_epoch && excel_datetime >= 60.0)
453
533
  excel_datetime = excel_datetime + 1.0;
454
534
 
455
535
  return excel_datetime;
@@ -514,6 +594,16 @@ lxw_str_tolower(char *str)
514
594
  str[i] = tolower(str[i]);
515
595
  }
516
596
 
597
+ /* Simple check for empty strings. */
598
+ uint8_t
599
+ lxw_str_is_empty(const char *str)
600
+ {
601
+ if (str[0] == '\0')
602
+ return 1;
603
+ else
604
+ return 0;
605
+ }
606
+
517
607
  /* Create a quoted version of the worksheet name, or return an unmodified
518
608
  * copy if it doesn't required quoting. */
519
609
  char *
@@ -3,7 +3,8 @@
3
3
  *
4
4
  * Used in conjunction with the libxlsxwriter library.
5
5
  *
6
- * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
6
+ * SPDX-License-Identifier: BSD-2-Clause
7
+ * Copyright 2014-2026, John McNamara, jmcnamara@cpan.org.
7
8
  *
8
9
  */
9
10