xlsxwriter 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +40 -0
  3. data/ext/xlsxwriter/chart.c +105 -0
  4. data/ext/xlsxwriter/chart.h +27 -0
  5. data/ext/xlsxwriter/extconf.rb +14 -0
  6. data/ext/xlsxwriter/format.c +67 -0
  7. data/ext/xlsxwriter/format.h +9 -0
  8. data/ext/xlsxwriter/libxlsxwriter/LICENSE.txt +89 -0
  9. data/ext/xlsxwriter/libxlsxwriter/Makefile +141 -0
  10. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter.h +23 -0
  11. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/app.h +79 -0
  12. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/chart.h +1093 -0
  13. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/common.h +336 -0
  14. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/content_types.h +74 -0
  15. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/core.h +51 -0
  16. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/custom.h +52 -0
  17. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/drawing.h +111 -0
  18. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/format.h +1214 -0
  19. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/hash_table.h +76 -0
  20. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/packager.h +80 -0
  21. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/relationships.h +77 -0
  22. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/shared_strings.h +83 -0
  23. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/styles.h +77 -0
  24. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/theme.h +47 -0
  25. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/third_party/ioapi.h +215 -0
  26. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/third_party/queue.h +694 -0
  27. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/third_party/tmpfileplus.h +53 -0
  28. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/third_party/tree.h +801 -0
  29. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/third_party/zip.h +375 -0
  30. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/utility.h +166 -0
  31. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/workbook.h +751 -0
  32. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/worksheet.h +2641 -0
  33. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/xmlwriter.h +178 -0
  34. data/ext/xlsxwriter/libxlsxwriter/lib/.gitignore +0 -0
  35. data/ext/xlsxwriter/libxlsxwriter/src/Makefile +125 -0
  36. data/ext/xlsxwriter/libxlsxwriter/src/app.c +439 -0
  37. data/ext/xlsxwriter/libxlsxwriter/src/chart.c +3420 -0
  38. data/ext/xlsxwriter/libxlsxwriter/src/content_types.c +341 -0
  39. data/ext/xlsxwriter/libxlsxwriter/src/core.c +293 -0
  40. data/ext/xlsxwriter/libxlsxwriter/src/custom.c +224 -0
  41. data/ext/xlsxwriter/libxlsxwriter/src/drawing.c +746 -0
  42. data/ext/xlsxwriter/libxlsxwriter/src/format.c +728 -0
  43. data/ext/xlsxwriter/libxlsxwriter/src/hash_table.c +223 -0
  44. data/ext/xlsxwriter/libxlsxwriter/src/packager.c +877 -0
  45. data/ext/xlsxwriter/libxlsxwriter/src/relationships.c +242 -0
  46. data/ext/xlsxwriter/libxlsxwriter/src/shared_strings.c +264 -0
  47. data/ext/xlsxwriter/libxlsxwriter/src/styles.c +1086 -0
  48. data/ext/xlsxwriter/libxlsxwriter/src/theme.c +348 -0
  49. data/ext/xlsxwriter/libxlsxwriter/src/utility.c +512 -0
  50. data/ext/xlsxwriter/libxlsxwriter/src/workbook.c +1895 -0
  51. data/ext/xlsxwriter/libxlsxwriter/src/worksheet.c +4992 -0
  52. data/ext/xlsxwriter/libxlsxwriter/src/xmlwriter.c +355 -0
  53. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/Makefile +44 -0
  54. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/crypt.h +131 -0
  55. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/ioapi.c +247 -0
  56. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/ioapi.h +209 -0
  57. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/iowin32.c +456 -0
  58. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/iowin32.h +28 -0
  59. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/miniunz.c +660 -0
  60. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/minizip.c +520 -0
  61. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/mztools.c +291 -0
  62. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/mztools.h +37 -0
  63. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/unzip.c +2125 -0
  64. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/unzip.h +437 -0
  65. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/zip.c +2007 -0
  66. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/zip.h +367 -0
  67. data/ext/xlsxwriter/libxlsxwriter/third_party/tmpfileplus/Makefile +42 -0
  68. data/ext/xlsxwriter/libxlsxwriter/third_party/tmpfileplus/tmpfileplus.c +342 -0
  69. data/ext/xlsxwriter/libxlsxwriter/third_party/tmpfileplus/tmpfileplus.h +53 -0
  70. data/ext/xlsxwriter/workbook.c +257 -0
  71. data/ext/xlsxwriter/workbook.h +42 -0
  72. data/ext/xlsxwriter/workbook_properties.c +103 -0
  73. data/ext/xlsxwriter/workbook_properties.h +10 -0
  74. data/ext/xlsxwriter/worksheet.c +1064 -0
  75. data/ext/xlsxwriter/worksheet.h +74 -0
  76. data/ext/xlsxwriter/xlsxwriter.c +239 -0
  77. data/lib/xlsxwriter.rb +6 -0
  78. data/lib/xlsxwriter/version.rb +3 -0
  79. data/lib/xlsxwriter/worksheet.rb +72 -0
  80. data/test/run-test.rb +11 -0
  81. data/test/support/xlsx_comparable.rb +109 -0
  82. data/test/test-array-formula.rb +33 -0
  83. data/test/test-autofilter.rb +70 -0
  84. data/test/test-chart-area.rb +25 -0
  85. data/test/test-data.rb +65 -0
  86. data/test/test-default-row.rb +25 -0
  87. data/test/test-defined-name.rb +46 -0
  88. data/test/test-escapes.rb +33 -0
  89. data/test/test-fit-to-pages.rb +21 -0
  90. data/test/test-formatting.rb +137 -0
  91. data/test/test-gridlines.rb +15 -0
  92. data/test/test-hyperlink.rb +67 -0
  93. data/test/test-image.rb +84 -0
  94. data/test/test-merge-range.rb +18 -0
  95. data/test/test-misc.rb +29 -0
  96. data/test/test-optimize.rb +32 -0
  97. data/test/test-page-breaks.rb +13 -0
  98. data/test/test-page-setup.rb +28 -0
  99. data/test/test-panes.rb +45 -0
  100. data/test/test-print-area.rb +19 -0
  101. data/test/test-print-options.rb +61 -0
  102. data/test/test-print-scale.rb +12 -0
  103. data/test/test-properties.rb +51 -0
  104. data/test/test-protect.rb +27 -0
  105. data/test/test-repeat.rb +23 -0
  106. data/test/test-row-col-format.rb +35 -0
  107. data/test/test-set-selection.rb +13 -0
  108. data/test/test-set-start-page.rb +13 -0
  109. data/test/test-simple.rb +62 -0
  110. data/test/test-types.rb +17 -0
  111. data/test/xlsx-func-testcase.rb +36 -0
  112. metadata +228 -0
@@ -0,0 +1,53 @@
1
+ /* $Id: tmpfileplus.h $ */
2
+ /*
3
+ * $Date: 2016-06-01 03:31Z $
4
+ * $Revision: 2.0.0 $
5
+ * $Author: dai $
6
+ */
7
+
8
+ /*
9
+ * This Source Code Form is subject to the terms of the Mozilla Public
10
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
11
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12
+ *
13
+ * Copyright (c) 2012-16 David Ireland, DI Management Services Pty Ltd
14
+ * <http://www.di-mgt.com.au/contact/>.
15
+ */
16
+
17
+ #if _MSC_VER > 1000
18
+ #pragma once
19
+ #endif
20
+
21
+ #ifndef TMPFILEPLUS_H_
22
+ #define TMPFILEPLUS_H_
23
+
24
+ #include <stdio.h>
25
+
26
+ /** Create a unique temporary file.
27
+ @param dir (optional) directory to create file. If NULL use default TMP directory.
28
+ @param prefix (optional) prefix for file name. If NULL use "tmp.".
29
+ @param pathname (optional) pointer to a buffer to receive the temp filename.
30
+ Allocated using `malloc()`; user to free. Ignored if NULL.
31
+ @param keep If `keep` is nonzero and `pathname` is not NULL, then keep the file after closing.
32
+ Otherwise file is automatically deleted when closed.
33
+ @return Pointer to stream opened in binary read/write (w+b) mode, or a null pointer on error.
34
+ @exception ENOMEM Not enough memory to allocate filename.
35
+ */
36
+ FILE *tmpfileplus(const char *dir, const char *prefix, char **pathname, int keep);
37
+
38
+
39
+ /** Create a unique temporary file with filename stored in a fixed-length buffer.
40
+ @param dir (optional) directory to create file. If NULL use default directory.
41
+ @param prefix (optional) prefix for file name. If NULL use "tmp.".
42
+ @param pathnamebuf (optional) buffer to receive full pathname of temporary file. Ignored if NULL.
43
+ @param pathsize Size of buffer to receive filename and its terminating null character.
44
+ @param keep If `keep` is nonzero and `pathname` is not NULL, then keep the file after closing.
45
+ Otherwise file is automatically deleted when closed.
46
+ @return Pointer to stream opened in binary read/write (w+b) mode, or a null pointer on error.
47
+ @exception E2BIG Resulting filename is too big for the buffer `pathnamebuf`.
48
+ */
49
+ FILE *tmpfileplus_f(const char *dir, const char *prefix, char *pathnamebuf, size_t pathsize, int keep);
50
+
51
+ #define TMPFILE_KEEP 1
52
+
53
+ #endif /* end TMPFILEPLUS_H_ */
@@ -0,0 +1,257 @@
1
+ #include <string.h>
2
+ #include "xlsxwriter.h"
3
+ #include "format.h"
4
+ #include "workbook.h"
5
+
6
+ VALUE
7
+ workbook_alloc(VALUE klass)
8
+ {
9
+ VALUE obj;
10
+ struct workbook *ptr;
11
+
12
+ obj = Data_Make_Struct(klass, struct workbook, NULL, workbook_free, ptr);
13
+
14
+ ptr->path = NULL;
15
+ ptr->workbook = NULL;
16
+ ptr->formats = NULL;
17
+ ptr->properties = NULL;
18
+
19
+ return obj;
20
+ }
21
+
22
+ VALUE
23
+ workbook_new_(int argc, VALUE *argv, VALUE self) {
24
+ VALUE workbook = rb_call_super(argc, argv);
25
+ if (rb_block_given_p()) {
26
+ rb_yield(workbook);
27
+ workbook_release(workbook);
28
+ return Qnil;
29
+ }
30
+ return workbook;
31
+ }
32
+
33
+ VALUE
34
+ workbook_init(int argc, VALUE *argv, VALUE self) {
35
+ struct workbook *ptr;
36
+ lxw_workbook_options options = {
37
+ .constant_memory = 0,
38
+ .tmpdir = NULL
39
+ };
40
+
41
+ if (argc < 1 || argc > 2) {
42
+ rb_raise(rb_eArgError, "wrong number of arguments");
43
+ return self;
44
+ } else if (argc == 2) {
45
+ VALUE const_mem = rb_hash_aref(argv[1], ID2SYM(rb_intern("constant_memory")));
46
+ if (!NIL_P(const_mem) && const_mem) {
47
+ options.constant_memory = 1;
48
+ VALUE tmpdir = rb_hash_aref(argv[1], ID2SYM(rb_intern("tmpdir")));
49
+ if (!NIL_P(tmpdir))
50
+ options.tmpdir = RSTRING_PTR(tmpdir);
51
+ }
52
+ }
53
+
54
+ Data_Get_Struct(self, struct workbook, ptr);
55
+
56
+ size_t len = RSTRING_LEN(argv[0]);
57
+ ptr->path = malloc(len + 1);
58
+ strncpy(ptr->path, RSTRING_PTR(argv[0]), len + 1);
59
+ if (options.constant_memory) {
60
+ ptr->workbook = workbook_new_opt(ptr->path, &options);
61
+ } else {
62
+ ptr->workbook = workbook_new(ptr->path);
63
+ }
64
+ ptr->properties = NULL;
65
+ rb_iv_set(self, "@font_sizes", rb_hash_new());
66
+
67
+ return self;
68
+ }
69
+
70
+ VALUE
71
+ workbook_release(VALUE self) {
72
+ struct workbook *ptr;
73
+ Data_Get_Struct(self, struct workbook, ptr);
74
+
75
+ workbook_free(ptr);
76
+ return self;
77
+ }
78
+
79
+ void
80
+ workbook_free(void *p) {
81
+ struct workbook *ptr = p;
82
+
83
+ if (ptr->workbook) {
84
+ if (ptr->properties) {
85
+ workbook_set_properties(ptr->workbook, ptr->properties);
86
+ }
87
+ workbook_close(ptr->workbook);
88
+ ptr->workbook = NULL;
89
+ }
90
+ if (ptr->path) {
91
+ free(ptr->path);
92
+ ptr->path = NULL;
93
+ }
94
+ if (ptr->formats) {
95
+ st_free_table(ptr->formats);
96
+ ptr->formats = NULL;
97
+ };
98
+
99
+ if (ptr->properties) {
100
+ #define FREE_PROP(prop) { \
101
+ if (ptr->properties->prop) { \
102
+ xfree(ptr->properties->prop); \
103
+ ptr->properties->prop = NULL; \
104
+ } \
105
+ }
106
+ FREE_PROP(title);
107
+ FREE_PROP(subject);
108
+ FREE_PROP(author);
109
+ FREE_PROP(manager);
110
+ FREE_PROP(company);
111
+ FREE_PROP(category);
112
+ FREE_PROP(keywords);
113
+ FREE_PROP(comments);
114
+ FREE_PROP(status);
115
+ FREE_PROP(hyperlink_base);
116
+ #undef FREE_PROP
117
+ free(ptr->properties);
118
+ ptr->properties = NULL;
119
+ }
120
+ }
121
+
122
+ VALUE
123
+ workbook_add_worksheet_(int argc, VALUE *argv, VALUE self) {
124
+ VALUE worksheet = Qnil;
125
+
126
+ if (argc > 1) {
127
+ rb_raise(rb_eArgError, "wrong number of arguments");
128
+ return Qnil;
129
+ }
130
+
131
+ struct workbook *ptr;
132
+ Data_Get_Struct(self, struct workbook, ptr);
133
+ if (ptr->workbook) {
134
+ VALUE mXlsxWriter = rb_const_get(rb_cObject, rb_intern("XlsxWriter"));
135
+ VALUE cWorksheet = rb_const_get(mXlsxWriter, rb_intern("Worksheet"));
136
+ worksheet = rb_funcall(cWorksheet, rb_intern("new"), argc + 1, self, argv[0]);
137
+ }
138
+
139
+ if (rb_block_given_p()) {
140
+ VALUE res = rb_yield(worksheet);
141
+ return res;
142
+ }
143
+
144
+ return worksheet;
145
+ }
146
+
147
+ VALUE
148
+ workbook_add_format_(VALUE self, VALUE key, VALUE opts) {
149
+ struct workbook *ptr;
150
+ lxw_format *format;
151
+ Data_Get_Struct(self, struct workbook, ptr);
152
+
153
+ if (!ptr->formats) {
154
+ ptr->formats = st_init_numtable();
155
+ }
156
+
157
+ format = workbook_add_format(ptr->workbook);
158
+ st_insert(ptr->formats, rb_to_id(key), (st_data_t)format);
159
+ format_apply_opts(format, opts);
160
+
161
+ VALUE font_size = rb_hash_aref(opts, ID2SYM(rb_intern("font_size")));
162
+ if (!NIL_P(font_size)) {
163
+ VALUE bold = rb_hash_aref(opts, ID2SYM(rb_intern("bold")));
164
+ if (!NIL_P(bold) && bold) {
165
+ rb_hash_aset(rb_iv_get(self, "@font_sizes"), key, rb_float_new(NUM2DBL(font_size) * 1.5));
166
+ } else {
167
+ rb_hash_aset(rb_iv_get(self, "@font_sizes"), key, font_size);
168
+ }
169
+ }
170
+
171
+ return self;
172
+ }
173
+
174
+ VALUE
175
+ workbook_add_chart_(VALUE self, VALUE type) {
176
+ VALUE chart = rb_funcall(cChart, rb_intern("new"), 2, self, type);
177
+ if (rb_block_given_p()) {
178
+ VALUE res = rb_yield(chart);
179
+ return res;
180
+ }
181
+ return chart;
182
+ }
183
+
184
+ VALUE
185
+ workbook_set_default_xf_indices_(VALUE self) {
186
+ struct workbook *ptr;
187
+ Data_Get_Struct(self, struct workbook, ptr);
188
+ lxw_workbook_set_default_xf_indices(ptr->workbook);
189
+ return self;
190
+ }
191
+
192
+ VALUE
193
+ workbook_properties_(VALUE self) {
194
+ VALUE props = rb_obj_alloc(cWorkbookProperties);
195
+ rb_obj_call_init(props, 1, &self);
196
+ return props;
197
+ }
198
+
199
+ VALUE
200
+ workbook_define_name_(VALUE self, VALUE name, VALUE formula) {
201
+ struct workbook *ptr;
202
+ Data_Get_Struct(self, struct workbook, ptr);
203
+ workbook_define_name(ptr->workbook, StringValueCStr(name), StringValueCStr(formula));
204
+ return self;
205
+ }
206
+
207
+ VALUE
208
+ workbook_validate_worksheet_name_(VALUE self, VALUE name) {
209
+ struct workbook *ptr;
210
+ lxw_error err;
211
+ Data_Get_Struct(self, struct workbook, ptr);
212
+ err = workbook_validate_worksheet_name(ptr->workbook, StringValueCStr(name));
213
+ handle_lxw_error(err);
214
+ return Qtrue;
215
+ }
216
+
217
+
218
+ lxw_format *
219
+ workbook_get_format(VALUE self, VALUE key) {
220
+ struct workbook *ptr;
221
+ lxw_format *format = NULL;
222
+
223
+ if (NIL_P(key))
224
+ return NULL;
225
+
226
+ Data_Get_Struct(self, struct workbook, ptr);
227
+
228
+ if (!ptr->formats)
229
+ return NULL;
230
+
231
+ st_lookup(ptr->formats, rb_to_id(key), (st_data_t *) &format);
232
+
233
+ return format;
234
+ }
235
+
236
+ lxw_datetime
237
+ value_to_lxw_datetime(VALUE val) {
238
+ const ID i_to_time = rb_intern("to_time");
239
+ if (rb_respond_to(val, i_to_time)) {
240
+ val = rb_funcall(val, i_to_time, 0);
241
+ }
242
+ lxw_datetime res = {
243
+ .year = NUM2INT(rb_funcall(val, rb_intern("year"), 0)),
244
+ .month = NUM2INT(rb_funcall(val, rb_intern("month"), 0)),
245
+ .day = NUM2INT(rb_funcall(val, rb_intern("day"), 0)),
246
+ .hour = NUM2INT(rb_funcall(val, rb_intern("hour"), 0)),
247
+ .min = NUM2INT(rb_funcall(val, rb_intern("min"), 0)),
248
+ .sec = NUM2DBL(rb_funcall(val, rb_intern("sec"), 0)) +
249
+ NUM2DBL(rb_funcall(val, rb_intern("subsec"), 0))
250
+ };
251
+ return res;
252
+ }
253
+
254
+ void
255
+ handle_lxw_error(lxw_error err) {
256
+ return;
257
+ }
@@ -0,0 +1,42 @@
1
+ #include <ruby.h>
2
+
3
+ #ifndef __WORKBOOK__
4
+ #define __WORKBOOK__
5
+
6
+ struct workbook {
7
+ char *path;
8
+ lxw_workbook *workbook;
9
+ lxw_doc_properties *properties;
10
+ st_table *formats;
11
+ };
12
+
13
+
14
+ VALUE workbook_alloc(VALUE klass);
15
+ VALUE workbook_new_(int argc, VALUE *argv, VALUE self);
16
+ VALUE workbook_init(int argc, VALUE *argv, VALUE self);
17
+ VALUE workbook_release(VALUE self);
18
+ void workbook_free(void *);
19
+
20
+ VALUE workbook_add_worksheet_(int argc, VALUE *argv, VALUE self);
21
+ VALUE workbook_add_format_(VALUE self, VALUE key, VALUE opts);
22
+ VALUE workbook_add_chart_(VALUE self, VALUE type);
23
+ VALUE workbook_set_default_xf_indices_(VALUE self);
24
+ VALUE workbook_properties_(VALUE self);
25
+ VALUE workbook_define_name_(VALUE self, VALUE name, VALUE formula);
26
+ VALUE workbook_validate_worksheet_name_(VALUE self, VALUE name);
27
+
28
+
29
+ lxw_format *workbook_get_format(VALUE self, VALUE key);
30
+ lxw_datetime value_to_lxw_datetime(VALUE val);
31
+ void handle_lxw_error(lxw_error err);
32
+
33
+ extern VALUE mXlsxWriter;
34
+ extern VALUE cWorkbook;
35
+ extern VALUE cWorksheet;
36
+ extern VALUE mXlsxFormat;
37
+ extern VALUE cWorkbookProperties;
38
+ extern VALUE cChart;
39
+ extern VALUE cChartSeries;
40
+ extern VALUE cChartAxis;
41
+
42
+ #endif // __WORKBOOK__
@@ -0,0 +1,103 @@
1
+ #include <string.h>
2
+ #include <ruby/util.h>
3
+ #include "xlsxwriter.h"
4
+ #include "workbook.h"
5
+ #include "workbook_properties.h"
6
+
7
+ VALUE
8
+ workbook_properties_init_(VALUE self, VALUE workbook) {
9
+ struct workbook *wb_ptr;
10
+ rb_iv_set(self, "@workbook", workbook);
11
+ Data_Get_Struct(workbook, struct workbook, wb_ptr);
12
+ if (!wb_ptr->properties) {
13
+ wb_ptr->properties = calloc(1, sizeof(lxw_doc_properties));
14
+ }
15
+ if (rb_block_given_p()) {
16
+ rb_yield(self);
17
+ }
18
+ return self;
19
+ }
20
+
21
+ VALUE
22
+ workbook_properties_set_dir_(VALUE self, VALUE value) {
23
+ VALUE key = rb_id2str(rb_frame_callee());
24
+ char *key_str = ruby_strdup(RSTRING_PTR(key));
25
+ size_t last_pos = RSTRING_LEN(key) - 1;
26
+ if (last_pos > 0 && key_str[last_pos] == '=') {
27
+ key_str[last_pos] = '\0';
28
+ }
29
+ key = rb_str_new_cstr(key_str);
30
+ workbook_properties_set_(self, key, value);
31
+ xfree(key_str);
32
+ return value;
33
+ }
34
+
35
+ VALUE
36
+ workbook_properties_set_(VALUE self, VALUE key, VALUE value) {
37
+ char *key_cstr = NULL;
38
+ switch (TYPE(key)) {
39
+ case T_STRING:
40
+ key_cstr = StringValueCStr(key);
41
+ break;
42
+ case T_SYMBOL:
43
+ key = rb_sym2str(key);
44
+ key_cstr = StringValueCStr(key);
45
+ break;
46
+ default:
47
+ rb_raise(rb_eArgError, "Wrong type of key: %"PRIsVALUE, rb_obj_class(key));
48
+ }
49
+
50
+ struct workbook *wb_ptr;
51
+ Data_Get_Struct(rb_iv_get(self, "@workbook"), struct workbook, wb_ptr);
52
+ lxw_doc_properties *props = wb_ptr->properties;
53
+ if (!props) {
54
+ rb_raise(rb_eRuntimeError, "Workbook properties are already freed.");
55
+ }
56
+
57
+ #define HANDLE_PROP(prop) { \
58
+ if (!strcmp(#prop, key_cstr)) { \
59
+ props->prop = ruby_strdup(StringValueCStr(value)); \
60
+ return value; \
61
+ } \
62
+ }
63
+ HANDLE_PROP(title);
64
+ HANDLE_PROP(subject);
65
+ HANDLE_PROP(author);
66
+ HANDLE_PROP(manager);
67
+ HANDLE_PROP(company);
68
+ HANDLE_PROP(category);
69
+ HANDLE_PROP(keywords);
70
+ HANDLE_PROP(comments);
71
+ HANDLE_PROP(status);
72
+ HANDLE_PROP(hyperlink_base);
73
+ #undef HANDLE_PROP
74
+
75
+ // Not a standard property.
76
+ switch (TYPE(value)) {
77
+ case T_NIL:
78
+ break;
79
+ case T_STRING:
80
+ workbook_set_custom_property_string(wb_ptr->workbook, key_cstr, StringValueCStr(value));
81
+ break;
82
+ case T_FLOAT: case T_RATIONAL:
83
+ workbook_set_custom_property_number(wb_ptr->workbook, key_cstr, NUM2DBL(value));
84
+ break;
85
+ case T_FIXNUM: case T_BIGNUM:
86
+ workbook_set_custom_property_integer(wb_ptr->workbook, key_cstr, NUM2INT(value));
87
+ break;
88
+ case T_TRUE: case T_FALSE:
89
+ workbook_set_custom_property_boolean(wb_ptr->workbook, key_cstr, value != Qfalse);
90
+ break;
91
+ case T_DATA:
92
+ if (rb_obj_class(value) == rb_cTime) {
93
+ lxw_datetime datetime = value_to_lxw_datetime(value);
94
+ workbook_set_custom_property_datetime(wb_ptr->workbook, key_cstr, &datetime);
95
+ } else {
96
+ rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE
97
+ " (must be string, numeric, true, false, nil or time)",
98
+ rb_obj_class(value));
99
+ }
100
+ break;
101
+ }
102
+ return value;
103
+ }