fast_excel 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -2
  3. data/Makefile +14 -0
  4. data/README.md +7 -2
  5. data/Rakefile +10 -0
  6. data/extconf.rb +0 -0
  7. data/fast_excel.gemspec +3 -1
  8. data/lib/fast_excel/binding.rb +3 -7
  9. data/lib/rubygems_plugin.rb +3 -0
  10. data/libxlsxwriter/.gitignore +49 -0
  11. data/libxlsxwriter/.indent.pro +125 -0
  12. data/libxlsxwriter/.travis.yml +25 -0
  13. data/libxlsxwriter/CONTRIBUTING.md +226 -0
  14. data/libxlsxwriter/Changes.txt +557 -0
  15. data/libxlsxwriter/LICENSE.txt +89 -0
  16. data/libxlsxwriter/Makefile +156 -0
  17. data/libxlsxwriter/Readme.md +78 -0
  18. data/libxlsxwriter/cocoapods/libxlsxwriter-umbrella.h +30 -0
  19. data/libxlsxwriter/cocoapods/libxlsxwriter.modulemap +7 -0
  20. data/libxlsxwriter/include/xlsxwriter/app.h +79 -0
  21. data/libxlsxwriter/include/xlsxwriter/chart.h +3476 -0
  22. data/libxlsxwriter/include/xlsxwriter/common.h +372 -0
  23. data/libxlsxwriter/include/xlsxwriter/content_types.h +74 -0
  24. data/libxlsxwriter/include/xlsxwriter/core.h +51 -0
  25. data/libxlsxwriter/include/xlsxwriter/custom.h +52 -0
  26. data/libxlsxwriter/include/xlsxwriter/drawing.h +111 -0
  27. data/libxlsxwriter/include/xlsxwriter/format.h +1214 -0
  28. data/libxlsxwriter/include/xlsxwriter/hash_table.h +76 -0
  29. data/libxlsxwriter/include/xlsxwriter/packager.h +80 -0
  30. data/libxlsxwriter/include/xlsxwriter/relationships.h +77 -0
  31. data/libxlsxwriter/include/xlsxwriter/shared_strings.h +83 -0
  32. data/libxlsxwriter/include/xlsxwriter/styles.h +77 -0
  33. data/libxlsxwriter/include/xlsxwriter/theme.h +47 -0
  34. data/libxlsxwriter/include/xlsxwriter/third_party/ioapi.h +214 -0
  35. data/libxlsxwriter/include/xlsxwriter/third_party/queue.h +694 -0
  36. data/libxlsxwriter/include/xlsxwriter/third_party/tmpfileplus.h +53 -0
  37. data/libxlsxwriter/include/xlsxwriter/third_party/tree.h +801 -0
  38. data/libxlsxwriter/include/xlsxwriter/third_party/zip.h +375 -0
  39. data/libxlsxwriter/include/xlsxwriter/utility.h +166 -0
  40. data/libxlsxwriter/include/xlsxwriter/workbook.h +757 -0
  41. data/libxlsxwriter/include/xlsxwriter/worksheet.h +2641 -0
  42. data/libxlsxwriter/include/xlsxwriter/xmlwriter.h +178 -0
  43. data/libxlsxwriter/include/xlsxwriter.h +23 -0
  44. data/libxlsxwriter/lib/.gitignore +0 -0
  45. data/libxlsxwriter/libxlsxwriter.podspec +47 -0
  46. data/libxlsxwriter/src/Makefile +130 -0
  47. data/libxlsxwriter/src/app.c +443 -0
  48. data/libxlsxwriter/src/chart.c +6346 -0
  49. data/libxlsxwriter/src/content_types.c +345 -0
  50. data/libxlsxwriter/src/core.c +293 -0
  51. data/libxlsxwriter/src/custom.c +224 -0
  52. data/libxlsxwriter/src/drawing.c +746 -0
  53. data/libxlsxwriter/src/format.c +729 -0
  54. data/libxlsxwriter/src/hash_table.c +223 -0
  55. data/libxlsxwriter/src/packager.c +948 -0
  56. data/libxlsxwriter/src/relationships.c +245 -0
  57. data/libxlsxwriter/src/shared_strings.c +266 -0
  58. data/libxlsxwriter/src/styles.c +1088 -0
  59. data/libxlsxwriter/src/theme.c +348 -0
  60. data/libxlsxwriter/src/utility.c +515 -0
  61. data/libxlsxwriter/src/workbook.c +1930 -0
  62. data/libxlsxwriter/src/worksheet.c +5022 -0
  63. data/libxlsxwriter/src/xmlwriter.c +355 -0
  64. data/libxlsxwriter/third_party/minizip/Makefile +44 -0
  65. data/libxlsxwriter/third_party/minizip/Makefile.am +45 -0
  66. data/libxlsxwriter/third_party/minizip/Makefile.orig +25 -0
  67. data/libxlsxwriter/third_party/minizip/MiniZip64_Changes.txt +6 -0
  68. data/libxlsxwriter/third_party/minizip/MiniZip64_info.txt +74 -0
  69. data/libxlsxwriter/third_party/minizip/README.txt +5 -0
  70. data/libxlsxwriter/third_party/minizip/configure.ac +32 -0
  71. data/libxlsxwriter/third_party/minizip/crypt.h +131 -0
  72. data/libxlsxwriter/third_party/minizip/ioapi.c +247 -0
  73. data/libxlsxwriter/third_party/minizip/ioapi.h +208 -0
  74. data/libxlsxwriter/third_party/minizip/iowin32.c +456 -0
  75. data/libxlsxwriter/third_party/minizip/iowin32.h +28 -0
  76. data/libxlsxwriter/third_party/minizip/make_vms.com +25 -0
  77. data/libxlsxwriter/third_party/minizip/miniunz.c +660 -0
  78. data/libxlsxwriter/third_party/minizip/miniunzip.1 +63 -0
  79. data/libxlsxwriter/third_party/minizip/minizip.1 +46 -0
  80. data/libxlsxwriter/third_party/minizip/minizip.c +520 -0
  81. data/libxlsxwriter/third_party/minizip/minizip.pc.in +12 -0
  82. data/libxlsxwriter/third_party/minizip/mztools.c +291 -0
  83. data/libxlsxwriter/third_party/minizip/mztools.h +37 -0
  84. data/libxlsxwriter/third_party/minizip/unzip.c +2125 -0
  85. data/libxlsxwriter/third_party/minizip/unzip.h +437 -0
  86. data/libxlsxwriter/third_party/minizip/zip.c +2007 -0
  87. data/libxlsxwriter/third_party/minizip/zip.h +367 -0
  88. data/libxlsxwriter/third_party/tmpfileplus/Makefile +42 -0
  89. data/libxlsxwriter/third_party/tmpfileplus/tmpfileplus.c +342 -0
  90. data/libxlsxwriter/third_party/tmpfileplus/tmpfileplus.h +53 -0
  91. data/libxlsxwriter/version.txt +1 -0
  92. metadata +89 -6
  93. data/binaries/libxlsxwriter-alpine.so +0 -0
  94. data/binaries/libxlsxwriter-darwin.dylib +0 -0
  95. data/binaries/libxlsxwriter-glibc.so +0 -0
@@ -0,0 +1,515 @@
1
+ /*****************************************************************************
2
+ * utility - Utility functions for libxlsxwriter.
3
+ *
4
+ * Used in conjunction with the libxlsxwriter library.
5
+ *
6
+ * Copyright 2014-2017, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
7
+ *
8
+ */
9
+
10
+ #include <ctype.h>
11
+ #include <stdio.h>
12
+ #include <string.h>
13
+ #include <stdint.h>
14
+ #include <stdlib.h>
15
+ #include "xlsxwriter/utility.h"
16
+ #include "xlsxwriter/third_party/tmpfileplus.h"
17
+
18
+ char *error_strings[LXW_MAX_ERRNO + 1] = {
19
+ "No error.",
20
+ "Memory error, failed to malloc() required memory.",
21
+ "Error creating output xlsx file. Usually a permissions error.",
22
+ "Error encountered when creating a tmpfile during file assembly.",
23
+ "Zlib error with a file operation while creating xlsx file.",
24
+ "Zlib error when adding sub file to xlsx file.",
25
+ "Zlib error when closing xlsx file.",
26
+ "NULL function parameter ignored.",
27
+ "Function parameter validation error.",
28
+ "Worksheet name exceeds Excel's limit of 31 characters.",
29
+ "Worksheet name contains invalid Excel character: '[]:*?/\\'",
30
+ "Worksheet name is already in use.",
31
+ "Parameter exceeds Excel's limit of 128 characters.",
32
+ "Parameter exceeds Excel's limit of 255 characters.",
33
+ "String exceeds Excel's limit of 32,767 characters.",
34
+ "Error finding internal string index.",
35
+ "Worksheet row or column index out of range.",
36
+ "Maximum number of worksheet URLs (65530) exceeded.",
37
+ "Couldn't read image dimensions or DPI.",
38
+ "Unknown error number."
39
+ };
40
+
41
+ char *
42
+ lxw_strerror(lxw_error error_num)
43
+ {
44
+ if (error_num > LXW_MAX_ERRNO)
45
+ error_num = LXW_MAX_ERRNO;
46
+
47
+ return error_strings[error_num];
48
+ }
49
+
50
+ /*
51
+ * Convert Excel A-XFD style column name to zero based number.
52
+ */
53
+ void
54
+ lxw_col_to_name(char *col_name, lxw_col_t col_num, uint8_t absolute)
55
+ {
56
+ uint8_t pos = 0;
57
+ size_t len;
58
+ uint8_t i;
59
+
60
+ /* Change from 0 index to 1 index. */
61
+ col_num++;
62
+
63
+ /* Convert the column number to a string in reverse order. */
64
+ while (col_num) {
65
+
66
+ /* Get the remainder in base 26. */
67
+ int remainder = col_num % 26;
68
+
69
+ if (remainder == 0)
70
+ remainder = 26;
71
+
72
+ /* Convert the remainder value to a character. */
73
+ col_name[pos++] = 'A' + remainder - 1;
74
+ col_name[pos] = '\0';
75
+
76
+ /* Get the next order of magnitude. */
77
+ col_num = (col_num - 1) / 26;
78
+ }
79
+
80
+ if (absolute) {
81
+ col_name[pos] = '$';
82
+ col_name[pos + 1] = '\0';
83
+ }
84
+
85
+ /* Reverse the column name string. */
86
+ len = strlen(col_name);
87
+ for (i = 0; i < (len / 2); i++) {
88
+ char tmp = col_name[i];
89
+ col_name[i] = col_name[len - i - 1];
90
+ col_name[len - i - 1] = tmp;
91
+ }
92
+ }
93
+
94
+ /*
95
+ * Convert zero indexed row and column to an Excel style A1 cell reference.
96
+ */
97
+ void
98
+ lxw_rowcol_to_cell(char *cell_name, lxw_row_t row, lxw_col_t col)
99
+ {
100
+ size_t pos;
101
+
102
+ /* Add the column to the cell. */
103
+ lxw_col_to_name(cell_name, col, 0);
104
+
105
+ /* Get the end of the cell. */
106
+ pos = strlen(cell_name);
107
+
108
+ /* Add the row to the cell. */
109
+ lxw_snprintf(&cell_name[pos], LXW_MAX_ROW_NAME_LENGTH, "%d", ++row);
110
+ }
111
+
112
+ /*
113
+ * Convert zero indexed row and column to an Excel style $A$1 cell with
114
+ * an absolute reference.
115
+ */
116
+ void
117
+ lxw_rowcol_to_cell_abs(char *cell_name, lxw_row_t row, lxw_col_t col,
118
+ uint8_t abs_row, uint8_t abs_col)
119
+ {
120
+ size_t pos;
121
+
122
+ /* Add the column to the cell. */
123
+ lxw_col_to_name(cell_name, col, abs_col);
124
+
125
+ /* Get the end of the cell. */
126
+ pos = strlen(cell_name);
127
+
128
+ if (abs_row)
129
+ cell_name[pos++] = '$';
130
+
131
+ /* Add the row to the cell. */
132
+ lxw_snprintf(&cell_name[pos], LXW_MAX_ROW_NAME_LENGTH, "%d", ++row);
133
+ }
134
+
135
+ /*
136
+ * Convert zero indexed row and column pair to an Excel style A1:C5
137
+ * range reference.
138
+ */
139
+ void
140
+ lxw_rowcol_to_range(char *range,
141
+ lxw_row_t first_row, lxw_col_t first_col,
142
+ lxw_row_t last_row, lxw_col_t last_col)
143
+ {
144
+ size_t pos;
145
+
146
+ /* Add the first cell to the range. */
147
+ lxw_rowcol_to_cell(range, first_row, first_col);
148
+
149
+ /* If the start and end cells are the same just return a single cell. */
150
+ if (first_row == last_row && first_col == last_col)
151
+ return;
152
+
153
+ /* Get the end of the cell. */
154
+ pos = strlen(range);
155
+
156
+ /* Add the range separator. */
157
+ range[pos++] = ':';
158
+
159
+ /* Add the first cell to the range. */
160
+ lxw_rowcol_to_cell(&range[pos], last_row, last_col);
161
+ }
162
+
163
+ /*
164
+ * Convert zero indexed row and column pairs to an Excel style $A$1:$C$5
165
+ * range reference with absolute values.
166
+ */
167
+ void
168
+ lxw_rowcol_to_range_abs(char *range,
169
+ lxw_row_t first_row, lxw_col_t first_col,
170
+ lxw_row_t last_row, lxw_col_t last_col)
171
+ {
172
+ size_t pos;
173
+
174
+ /* Add the first cell to the range. */
175
+ lxw_rowcol_to_cell_abs(range, first_row, first_col, 1, 1);
176
+
177
+ /* If the start and end cells are the same just return a single cell. */
178
+ if (first_row == last_row && first_col == last_col)
179
+ return;
180
+
181
+ /* Get the end of the cell. */
182
+ pos = strlen(range);
183
+
184
+ /* Add the range separator. */
185
+ range[pos++] = ':';
186
+
187
+ /* Add the first cell to the range. */
188
+ lxw_rowcol_to_cell_abs(&range[pos], last_row, last_col, 1, 1);
189
+ }
190
+
191
+ /*
192
+ * Convert sheetname and zero indexed row and column pairs to an Excel style
193
+ * Sheet1!$A$1:$C$5 formula reference with absolute values.
194
+ */
195
+ void
196
+ lxw_rowcol_to_formula_abs(char *formula, const char *sheetname,
197
+ lxw_row_t first_row, lxw_col_t first_col,
198
+ lxw_row_t last_row, lxw_col_t last_col)
199
+ {
200
+ size_t pos;
201
+ char *quoted_name = lxw_quote_sheetname(sheetname);
202
+
203
+ strncpy(formula, quoted_name, LXW_MAX_FORMULA_RANGE_LENGTH - 1);
204
+ free(quoted_name);
205
+
206
+ /* Get the end of the sheetname. */
207
+ pos = strlen(formula);
208
+
209
+ /* Add the range separator. */
210
+ formula[pos++] = '!';
211
+
212
+ /* Add the first cell to the range. */
213
+ lxw_rowcol_to_cell_abs(&formula[pos], first_row, first_col, 1, 1);
214
+
215
+ /* If the start and end cells are the same just return a single cell. */
216
+ if (first_row == last_row && first_col == last_col)
217
+ return;
218
+
219
+ /* Get the end of the cell. */
220
+ pos = strlen(formula);
221
+
222
+ /* Add the range separator. */
223
+ formula[pos++] = ':';
224
+
225
+ /* Add the first cell to the range. */
226
+ lxw_rowcol_to_cell_abs(&formula[pos], last_row, last_col, 1, 1);
227
+ }
228
+
229
+ /*
230
+ * Convert an Excel style A1 cell reference to a zero indexed row number.
231
+ */
232
+ lxw_row_t
233
+ lxw_name_to_row(const char *row_str)
234
+ {
235
+ lxw_row_t row_num = 0;
236
+ const char *p = row_str;
237
+
238
+ /* Skip the column letters and absolute symbol of the A1 cell. */
239
+ while (p && !isdigit((unsigned char) *p))
240
+ p++;
241
+
242
+ /* Convert the row part of the A1 cell to a number. */
243
+ if (p)
244
+ row_num = atoi(p);
245
+
246
+ if (row_num)
247
+ return row_num - 1;
248
+ else
249
+ return 0;
250
+ }
251
+
252
+ /*
253
+ * Convert an Excel style A1 cell reference to a zero indexed column number.
254
+ */
255
+ lxw_col_t
256
+ lxw_name_to_col(const char *col_str)
257
+ {
258
+ lxw_col_t col_num = 0;
259
+ const char *p = col_str;
260
+
261
+ /* Convert leading column letters of A1 cell. Ignore absolute $ marker. */
262
+ while (p && (isupper((unsigned char) *p) || *p == '$')) {
263
+ if (*p != '$')
264
+ col_num = (col_num * 26) + (*p - 'A' + 1);
265
+ p++;
266
+ }
267
+
268
+ return col_num - 1;
269
+ }
270
+
271
+ /*
272
+ * Convert the second row of an Excel range ref to a zero indexed number.
273
+ */
274
+ uint32_t
275
+ lxw_name_to_row_2(const char *row_str)
276
+ {
277
+ const char *p = row_str;
278
+
279
+ /* Find the : separator in the range. */
280
+ while (p && *p != ':')
281
+ p++;
282
+
283
+ if (p)
284
+ return lxw_name_to_row(++p);
285
+ else
286
+ return -1;
287
+ }
288
+
289
+ /*
290
+ * Convert the second column of an Excel range ref to a zero indexed number.
291
+ */
292
+ uint16_t
293
+ lxw_name_to_col_2(const char *col_str)
294
+ {
295
+ const char *p = col_str;
296
+
297
+ /* Find the : separator in the range. */
298
+ while (p && *p != ':')
299
+ p++;
300
+
301
+ if (p)
302
+ return lxw_name_to_col(++p);
303
+ else
304
+ return -1;
305
+ }
306
+
307
+ /*
308
+ * Convert a lxw_datetime struct to an Excel serial date.
309
+ */
310
+ double
311
+ lxw_datetime_to_excel_date(lxw_datetime *datetime, uint8_t date_1904)
312
+ {
313
+ int year = datetime->year;
314
+ int month = datetime->month;
315
+ int day = datetime->day;
316
+ int hour = datetime->hour;
317
+ int min = datetime->min;
318
+ double sec = datetime->sec;
319
+ double seconds;
320
+ int epoch = date_1904 ? 1904 : 1900;
321
+ int offset = date_1904 ? 4 : 0;
322
+ int norm = 300;
323
+ int range;
324
+ /* Set month days and check for leap year. */
325
+ int mdays[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
326
+ int leap = 0;
327
+ int days = 0;
328
+ int i;
329
+
330
+ /* For times without dates set the default date for the epoch. */
331
+ if (!year) {
332
+ if (!date_1904) {
333
+ year = 1899;
334
+ month = 12;
335
+ day = 31;
336
+ }
337
+ else {
338
+ year = 1904;
339
+ month = 1;
340
+ day = 1;
341
+ }
342
+ }
343
+
344
+ /* Convert the Excel seconds to a fraction of the seconds in 24 hours. */
345
+ seconds = (hour * 60 * 60 + min * 60 + sec) / (24 * 60 * 60.0);
346
+
347
+ /* Special cases for Excel dates in the 1900 epoch. */
348
+ if (!date_1904) {
349
+ /* Excel 1900 epoch. */
350
+ if (year == 1899 && month == 12 && day == 31)
351
+ return seconds;
352
+
353
+ /* Excel 1900 epoch. */
354
+ if (year == 1900 && month == 1 && day == 0)
355
+ return seconds;
356
+
357
+ /* Excel false leapday */
358
+ if (year == 1900 && month == 2 && day == 29)
359
+ return 60 + seconds;
360
+ }
361
+
362
+ /* We calculate the date by calculating the number of days since the */
363
+ /* epoch and adjust for the number of leap days. We calculate the */
364
+ /* number of leap days by normalizing the year in relation to the */
365
+ /* epoch. Thus the year 2000 becomes 100 for 4-year and 100-year */
366
+ /* leapdays and 400 for 400-year leapdays. */
367
+ range = year - epoch;
368
+
369
+ if (year % 4 == 0 && (year % 100 > 0 || year % 400 == 0)) {
370
+ leap = 1;
371
+ mdays[2] = 29;
372
+ }
373
+
374
+ /*
375
+ * Calculate the serial date by accumulating the number of days
376
+ * since the epoch.
377
+ */
378
+
379
+ /* Add days for previous months. */
380
+ for (i = 0; i < month; i++) {
381
+ days += mdays[i];
382
+ }
383
+ /* Add days for current month. */
384
+ days += day;
385
+ /* Add days for all previous years. */
386
+ days += range * 365;
387
+ /* Add 4 year leapdays. */
388
+ days += (range) / 4;
389
+ /* Remove 100 year leapdays. */
390
+ days -= (range + offset) / 100;
391
+ /* Add 400 year leapdays. */
392
+ days += (range + offset + norm) / 400;
393
+ /* Remove leap days already counted. */
394
+ days -= leap;
395
+
396
+ /* Adjust for Excel erroneously treating 1900 as a leap year. */
397
+ if (!date_1904 && days > 59)
398
+ days++;
399
+
400
+ return days + seconds;
401
+ }
402
+
403
+ /* Simple strdup() implementation since it isn't ANSI C. */
404
+ char *
405
+ lxw_strdup(const char *str)
406
+ {
407
+ size_t len;
408
+ char *copy;
409
+
410
+ if (!str)
411
+ return NULL;
412
+
413
+ len = strlen(str) + 1;
414
+ copy = malloc(len);
415
+
416
+ if (copy)
417
+ memcpy(copy, str, len);
418
+
419
+ return copy;
420
+ }
421
+
422
+ /* Simple strlen that counts UTF-8 characters. Assumes well formed UTF-8. */
423
+ size_t
424
+ lxw_utf8_strlen(const char *str)
425
+ {
426
+ size_t byte_count = 0;
427
+ size_t char_count = 0;
428
+
429
+ while (str[byte_count]) {
430
+ if ((str[byte_count] & 0xc0) != 0x80)
431
+ char_count++;
432
+
433
+ byte_count++;
434
+ }
435
+
436
+ return char_count;
437
+ }
438
+
439
+ /* Simple tolower() for strings. */
440
+ void
441
+ lxw_str_tolower(char *str)
442
+ {
443
+ int i;
444
+
445
+ for (i = 0; str[i]; i++)
446
+ str[i] = tolower(str[i]);
447
+ }
448
+
449
+ /* Create a quoted version of the worksheet name, or return an unmodified
450
+ * copy if it doesn't required quoting. */
451
+ char *
452
+ lxw_quote_sheetname(const char *str)
453
+ {
454
+
455
+ uint8_t needs_quoting = 0;
456
+ size_t number_of_quotes = 2;
457
+ size_t i, j;
458
+ size_t len = strlen(str);
459
+
460
+ /* Don't quote the sheetname if it is already quoted. */
461
+ if (str[0] == '\'')
462
+ return lxw_strdup(str);
463
+
464
+ /* Check if the sheetname contains any characters that require it
465
+ * to be quoted. Also check for single quotes within the string. */
466
+ for (i = 0; i < len; i++) {
467
+ if (!isalnum((unsigned char) str[i]) && str[i] != '_'
468
+ && str[i] != '.')
469
+ needs_quoting = 1;
470
+
471
+ if (str[i] == '\'') {
472
+ needs_quoting = 1;
473
+ number_of_quotes++;
474
+ }
475
+ }
476
+
477
+ if (!needs_quoting) {
478
+ return lxw_strdup(str);
479
+ }
480
+ else {
481
+ /* Add single quotes to the start and end of the string. */
482
+ char *quoted_name = calloc(1, len + number_of_quotes + 1);
483
+ RETURN_ON_MEM_ERROR(quoted_name, NULL);
484
+
485
+ quoted_name[0] = '\'';
486
+
487
+ for (i = 0, j = 1; i < len; i++, j++) {
488
+ quoted_name[j] = str[i];
489
+
490
+ /* Double quote inline single quotes. */
491
+ if (str[i] == '\'') {
492
+ quoted_name[++j] = '\'';
493
+ }
494
+ }
495
+ quoted_name[j++] = '\'';
496
+ quoted_name[j++] = '\0';
497
+
498
+ return quoted_name;
499
+ }
500
+ }
501
+
502
+ /*
503
+ * Thin wrapper for tmpfile() so it can be over-ridden with a user defined
504
+ * version if required for safety or portability.
505
+ */
506
+ FILE *
507
+ lxw_tmpfile(char *tmpdir)
508
+ {
509
+ #ifndef USE_STANDARD_TMPFILE
510
+ return tmpfileplus(tmpdir, NULL, NULL, 0);
511
+ #else
512
+ (void) tmpdir;
513
+ return tmpfile();
514
+ #endif
515
+ }