xlsxwriter 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Rakefile +40 -0
- data/ext/xlsxwriter/chart.c +105 -0
- data/ext/xlsxwriter/chart.h +27 -0
- data/ext/xlsxwriter/extconf.rb +14 -0
- data/ext/xlsxwriter/format.c +67 -0
- data/ext/xlsxwriter/format.h +9 -0
- data/ext/xlsxwriter/libxlsxwriter/LICENSE.txt +89 -0
- data/ext/xlsxwriter/libxlsxwriter/Makefile +141 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter.h +23 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/app.h +79 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/chart.h +1093 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/common.h +336 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/content_types.h +74 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/core.h +51 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/custom.h +52 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/drawing.h +111 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/format.h +1214 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/hash_table.h +76 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/packager.h +80 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/relationships.h +77 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/shared_strings.h +83 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/styles.h +77 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/theme.h +47 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/third_party/ioapi.h +215 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/third_party/queue.h +694 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/third_party/tmpfileplus.h +53 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/third_party/tree.h +801 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/third_party/zip.h +375 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/utility.h +166 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/workbook.h +751 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/worksheet.h +2641 -0
- data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/xmlwriter.h +178 -0
- data/ext/xlsxwriter/libxlsxwriter/lib/.gitignore +0 -0
- data/ext/xlsxwriter/libxlsxwriter/src/Makefile +125 -0
- data/ext/xlsxwriter/libxlsxwriter/src/app.c +439 -0
- data/ext/xlsxwriter/libxlsxwriter/src/chart.c +3420 -0
- data/ext/xlsxwriter/libxlsxwriter/src/content_types.c +341 -0
- data/ext/xlsxwriter/libxlsxwriter/src/core.c +293 -0
- data/ext/xlsxwriter/libxlsxwriter/src/custom.c +224 -0
- data/ext/xlsxwriter/libxlsxwriter/src/drawing.c +746 -0
- data/ext/xlsxwriter/libxlsxwriter/src/format.c +728 -0
- data/ext/xlsxwriter/libxlsxwriter/src/hash_table.c +223 -0
- data/ext/xlsxwriter/libxlsxwriter/src/packager.c +877 -0
- data/ext/xlsxwriter/libxlsxwriter/src/relationships.c +242 -0
- data/ext/xlsxwriter/libxlsxwriter/src/shared_strings.c +264 -0
- data/ext/xlsxwriter/libxlsxwriter/src/styles.c +1086 -0
- data/ext/xlsxwriter/libxlsxwriter/src/theme.c +348 -0
- data/ext/xlsxwriter/libxlsxwriter/src/utility.c +512 -0
- data/ext/xlsxwriter/libxlsxwriter/src/workbook.c +1895 -0
- data/ext/xlsxwriter/libxlsxwriter/src/worksheet.c +4992 -0
- data/ext/xlsxwriter/libxlsxwriter/src/xmlwriter.c +355 -0
- data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/Makefile +44 -0
- data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/crypt.h +131 -0
- data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/ioapi.c +247 -0
- data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/ioapi.h +209 -0
- data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/iowin32.c +456 -0
- data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/iowin32.h +28 -0
- data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/miniunz.c +660 -0
- data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/minizip.c +520 -0
- data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/mztools.c +291 -0
- data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/mztools.h +37 -0
- data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/unzip.c +2125 -0
- data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/unzip.h +437 -0
- data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/zip.c +2007 -0
- data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/zip.h +367 -0
- data/ext/xlsxwriter/libxlsxwriter/third_party/tmpfileplus/Makefile +42 -0
- data/ext/xlsxwriter/libxlsxwriter/third_party/tmpfileplus/tmpfileplus.c +342 -0
- data/ext/xlsxwriter/libxlsxwriter/third_party/tmpfileplus/tmpfileplus.h +53 -0
- data/ext/xlsxwriter/workbook.c +257 -0
- data/ext/xlsxwriter/workbook.h +42 -0
- data/ext/xlsxwriter/workbook_properties.c +103 -0
- data/ext/xlsxwriter/workbook_properties.h +10 -0
- data/ext/xlsxwriter/worksheet.c +1064 -0
- data/ext/xlsxwriter/worksheet.h +74 -0
- data/ext/xlsxwriter/xlsxwriter.c +239 -0
- data/lib/xlsxwriter.rb +6 -0
- data/lib/xlsxwriter/version.rb +3 -0
- data/lib/xlsxwriter/worksheet.rb +72 -0
- data/test/run-test.rb +11 -0
- data/test/support/xlsx_comparable.rb +109 -0
- data/test/test-array-formula.rb +33 -0
- data/test/test-autofilter.rb +70 -0
- data/test/test-chart-area.rb +25 -0
- data/test/test-data.rb +65 -0
- data/test/test-default-row.rb +25 -0
- data/test/test-defined-name.rb +46 -0
- data/test/test-escapes.rb +33 -0
- data/test/test-fit-to-pages.rb +21 -0
- data/test/test-formatting.rb +137 -0
- data/test/test-gridlines.rb +15 -0
- data/test/test-hyperlink.rb +67 -0
- data/test/test-image.rb +84 -0
- data/test/test-merge-range.rb +18 -0
- data/test/test-misc.rb +29 -0
- data/test/test-optimize.rb +32 -0
- data/test/test-page-breaks.rb +13 -0
- data/test/test-page-setup.rb +28 -0
- data/test/test-panes.rb +45 -0
- data/test/test-print-area.rb +19 -0
- data/test/test-print-options.rb +61 -0
- data/test/test-print-scale.rb +12 -0
- data/test/test-properties.rb +51 -0
- data/test/test-protect.rb +27 -0
- data/test/test-repeat.rb +23 -0
- data/test/test-row-col-format.rb +35 -0
- data/test/test-set-selection.rb +13 -0
- data/test/test-set-start-page.rb +13 -0
- data/test/test-simple.rb +62 -0
- data/test/test-types.rb +17 -0
- data/test/xlsx-func-testcase.rb +36 -0
- metadata +228 -0
@@ -0,0 +1,348 @@
|
|
1
|
+
/*****************************************************************************
|
2
|
+
* theme - A library for creating Excel XLSX theme files.
|
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 <string.h>
|
11
|
+
|
12
|
+
#include "xlsxwriter/xmlwriter.h"
|
13
|
+
#include "xlsxwriter/theme.h"
|
14
|
+
#include "xlsxwriter/utility.h"
|
15
|
+
|
16
|
+
const char *theme_strs[] = {
|
17
|
+
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n",
|
18
|
+
"<a:theme xmlns:a=\"http://schemas.openxmlformats.org/",
|
19
|
+
"drawingml/2006/main\" name=\"Office Theme\">",
|
20
|
+
"<a:themeElements>",
|
21
|
+
"<a:clrScheme name=\"Office\"><a:dk1>",
|
22
|
+
"<a:sysClr val=\"windowText\" lastClr=\"000000\"/>",
|
23
|
+
"</a:dk1><a:lt1>",
|
24
|
+
"<a:sysClr val=\"window\" lastClr=\"FFFFFF\"/></a:lt1><a:dk2>",
|
25
|
+
"<a:srgbClr val=\"1F497D\"/></a:dk2><a:lt2>",
|
26
|
+
"<a:srgbClr val=\"EEECE1\"/></a:lt2><a:accent1>",
|
27
|
+
"<a:srgbClr val=\"4F81BD\"/></a:accent1><a:accent2>",
|
28
|
+
"<a:srgbClr val=\"C0504D\"/></a:accent2><a:accent3>",
|
29
|
+
"<a:srgbClr val=\"9BBB59\"/></a:accent3><a:accent4>",
|
30
|
+
"<a:srgbClr val=\"8064A2\"/></a:accent4><a:accent5>",
|
31
|
+
"<a:srgbClr val=\"4BACC6\"/></a:accent5><a:accent6>",
|
32
|
+
"<a:srgbClr val=\"F79646\"/></a:accent6><a:hlink>",
|
33
|
+
"<a:srgbClr val=\"0000FF\"/></a:hlink><a:folHlink>",
|
34
|
+
"<a:srgbClr val=\"800080\"/></a:folHlink></a:clrScheme>",
|
35
|
+
"<a:fontScheme name=\"Office\"><a:majorFont>",
|
36
|
+
"<a:latin typeface=\"Cambria\"/><a:ea typeface=\"\"/>",
|
37
|
+
"<a:cs typeface=\"\"/>",
|
38
|
+
"<a:font script=\"Jpan\" typeface=\"MS Pゴシック\"/>",
|
39
|
+
"<a:font script=\"Hang\" typeface=\"맑은 고딕\"/>",
|
40
|
+
"<a:font script=\"Hans\" typeface=\"宋体\"/>",
|
41
|
+
"<a:font script=\"Hant\" typeface=\"新細明體\"/>",
|
42
|
+
"<a:font script=\"Arab\" typeface=\"Times New Roman\"/>",
|
43
|
+
"<a:font script=\"Hebr\" typeface=\"Times New Roman\"/>",
|
44
|
+
"<a:font script=\"Thai\" typeface=\"Tahoma\"/>",
|
45
|
+
"<a:font script=\"Ethi\" typeface=\"Nyala\"/>",
|
46
|
+
"<a:font script=\"Beng\" typeface=\"Vrinda\"/>",
|
47
|
+
"<a:font script=\"Gujr\" typeface=\"Shruti\"/>",
|
48
|
+
"<a:font script=\"Khmr\" typeface=\"MoolBoran\"/>",
|
49
|
+
"<a:font script=\"Knda\" typeface=\"Tunga\"/>",
|
50
|
+
"<a:font script=\"Guru\" typeface=\"Raavi\"/>",
|
51
|
+
"<a:font script=\"Cans\" typeface=\"Euphemia\"/>",
|
52
|
+
"<a:font script=\"Cher\" typeface=\"Plantagenet Cherokee\"/>",
|
53
|
+
"<a:font script=\"Yiii\" typeface=\"Microsoft Yi Baiti\"/>",
|
54
|
+
"<a:font script=\"Tibt\" typeface=\"Microsoft Himalaya\"/>",
|
55
|
+
"<a:font script=\"Thaa\" typeface=\"MV Boli\"/>",
|
56
|
+
"<a:font script=\"Deva\" typeface=\"Mangal\"/>",
|
57
|
+
"<a:font script=\"Telu\" typeface=\"Gautami\"/>",
|
58
|
+
"<a:font script=\"Taml\" typeface=\"Latha\"/>",
|
59
|
+
"<a:font script=\"Syrc\" typeface=\"Estrangelo Edessa\"/>",
|
60
|
+
"<a:font script=\"Orya\" typeface=\"Kalinga\"/>",
|
61
|
+
"<a:font script=\"Mlym\" typeface=\"Kartika\"/>",
|
62
|
+
"<a:font script=\"Laoo\" typeface=\"DokChampa\"/>",
|
63
|
+
"<a:font script=\"Sinh\" typeface=\"Iskoola Pota\"/>",
|
64
|
+
"<a:font script=\"Mong\" typeface=\"Mongolian Baiti\"/>",
|
65
|
+
"<a:font script=\"Viet\" typeface=\"Times New Roman\"/>",
|
66
|
+
"<a:font script=\"Uigh\" typeface=\"Microsoft Uighur\"/>",
|
67
|
+
"</a:majorFont>",
|
68
|
+
"<a:minorFont>",
|
69
|
+
"<a:latin typeface=\"Calibri\"/>",
|
70
|
+
"<a:ea typeface=\"\"/>",
|
71
|
+
"<a:cs typeface=\"\"/>",
|
72
|
+
"<a:font script=\"Jpan\" typeface=\"MS Pゴシック\"/>",
|
73
|
+
"<a:font script=\"Hang\" typeface=\"맑은 고딕\"/>",
|
74
|
+
"<a:font script=\"Hans\" typeface=\"宋体\"/>",
|
75
|
+
"<a:font script=\"Hant\" typeface=\"新細明體\"/>",
|
76
|
+
"<a:font script=\"Arab\" typeface=\"Arial\"/>",
|
77
|
+
"<a:font script=\"Hebr\" typeface=\"Arial\"/>",
|
78
|
+
"<a:font script=\"Thai\" typeface=\"Tahoma\"/>",
|
79
|
+
"<a:font script=\"Ethi\" typeface=\"Nyala\"/>",
|
80
|
+
"<a:font script=\"Beng\" typeface=\"Vrinda\"/>",
|
81
|
+
"<a:font script=\"Gujr\" typeface=\"Shruti\"/>",
|
82
|
+
"<a:font script=\"Khmr\" typeface=\"DaunPenh\"/>",
|
83
|
+
"<a:font script=\"Knda\" typeface=\"Tunga\"/>",
|
84
|
+
"<a:font script=\"Guru\" typeface=\"Raavi\"/>",
|
85
|
+
"<a:font script=\"Cans\" typeface=\"Euphemia\"/>",
|
86
|
+
"<a:font script=\"Cher\" typeface=\"Plantagenet Cherokee\"/>",
|
87
|
+
"<a:font script=\"Yiii\" typeface=\"Microsoft Yi Baiti\"/>",
|
88
|
+
"<a:font script=\"Tibt\" typeface=\"Microsoft Himalaya\"/>",
|
89
|
+
"<a:font script=\"Thaa\" typeface=\"MV Boli\"/>",
|
90
|
+
"<a:font script=\"Deva\" typeface=\"Mangal\"/>",
|
91
|
+
"<a:font script=\"Telu\" typeface=\"Gautami\"/>",
|
92
|
+
"<a:font script=\"Taml\" typeface=\"Latha\"/>",
|
93
|
+
"<a:font script=\"Syrc\" typeface=\"Estrangelo Edessa\"/>",
|
94
|
+
"<a:font script=\"Orya\" typeface=\"Kalinga\"/>",
|
95
|
+
"<a:font script=\"Mlym\" typeface=\"Kartika\"/>",
|
96
|
+
"<a:font script=\"Laoo\" typeface=\"DokChampa\"/>",
|
97
|
+
"<a:font script=\"Sinh\" typeface=\"Iskoola Pota\"/>",
|
98
|
+
"<a:font script=\"Mong\" typeface=\"Mongolian Baiti\"/>",
|
99
|
+
"<a:font script=\"Viet\" typeface=\"Arial\"/>",
|
100
|
+
"<a:font script=\"Uigh\" typeface=\"Microsoft Uighur\"/>",
|
101
|
+
"</a:minorFont>",
|
102
|
+
"</a:fontScheme><a:fmtScheme name=\"Office\">",
|
103
|
+
"<a:fillStyleLst>",
|
104
|
+
"<a:solidFill>",
|
105
|
+
"<a:schemeClr val=\"phClr\"/>",
|
106
|
+
"</a:solidFill>",
|
107
|
+
"<a:gradFill rotWithShape=\"1\">",
|
108
|
+
"<a:gsLst>",
|
109
|
+
"<a:gs pos=\"0\">",
|
110
|
+
"<a:schemeClr val=\"phClr\">",
|
111
|
+
"<a:tint val=\"50000\"/>",
|
112
|
+
"<a:satMod val=\"300000\"/>",
|
113
|
+
"</a:schemeClr>",
|
114
|
+
"</a:gs>",
|
115
|
+
"<a:gs pos=\"35000\">",
|
116
|
+
"<a:schemeClr val=\"phClr\">",
|
117
|
+
"<a:tint val=\"37000\"/>",
|
118
|
+
"<a:satMod val=\"300000\"/>",
|
119
|
+
"</a:schemeClr>",
|
120
|
+
"</a:gs>",
|
121
|
+
"<a:gs pos=\"100000\">",
|
122
|
+
"<a:schemeClr val=\"phClr\">",
|
123
|
+
"<a:tint val=\"15000\"/>",
|
124
|
+
"<a:satMod val=\"350000\"/>",
|
125
|
+
"</a:schemeClr>",
|
126
|
+
"</a:gs>",
|
127
|
+
"</a:gsLst>",
|
128
|
+
"<a:lin ang=\"16200000\" scaled=\"1\"/>",
|
129
|
+
"</a:gradFill>",
|
130
|
+
"<a:gradFill rotWithShape=\"1\">",
|
131
|
+
"<a:gsLst>",
|
132
|
+
"<a:gs pos=\"0\">",
|
133
|
+
"<a:schemeClr val=\"phClr\">",
|
134
|
+
"<a:shade val=\"51000\"/>",
|
135
|
+
"<a:satMod val=\"130000\"/>",
|
136
|
+
"</a:schemeClr>",
|
137
|
+
"</a:gs>",
|
138
|
+
"<a:gs pos=\"80000\">",
|
139
|
+
"<a:schemeClr val=\"phClr\">",
|
140
|
+
"<a:shade val=\"93000\"/>",
|
141
|
+
"<a:satMod val=\"130000\"/>",
|
142
|
+
"</a:schemeClr>",
|
143
|
+
"</a:gs>",
|
144
|
+
"<a:gs pos=\"100000\">",
|
145
|
+
"<a:schemeClr val=\"phClr\">",
|
146
|
+
"<a:shade val=\"94000\"/>",
|
147
|
+
"<a:satMod val=\"135000\"/>",
|
148
|
+
"</a:schemeClr>",
|
149
|
+
"</a:gs>",
|
150
|
+
"</a:gsLst>",
|
151
|
+
"<a:lin ang=\"16200000\" scaled=\"0\"/>",
|
152
|
+
"</a:gradFill>",
|
153
|
+
"</a:fillStyleLst>",
|
154
|
+
"<a:lnStyleLst>",
|
155
|
+
"<a:ln w=\"9525\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\">",
|
156
|
+
"<a:solidFill>",
|
157
|
+
"<a:schemeClr val=\"phClr\">",
|
158
|
+
"<a:shade val=\"95000\"/>",
|
159
|
+
"<a:satMod val=\"105000\"/>",
|
160
|
+
"</a:schemeClr>",
|
161
|
+
"</a:solidFill>",
|
162
|
+
"<a:prstDash val=\"solid\"/>",
|
163
|
+
"</a:ln>",
|
164
|
+
"<a:ln w=\"25400\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\">",
|
165
|
+
"<a:solidFill>",
|
166
|
+
"<a:schemeClr val=\"phClr\"/>",
|
167
|
+
"</a:solidFill>",
|
168
|
+
"<a:prstDash val=\"solid\"/>",
|
169
|
+
"</a:ln>",
|
170
|
+
"<a:ln w=\"38100\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\">",
|
171
|
+
"<a:solidFill>",
|
172
|
+
"<a:schemeClr val=\"phClr\"/>",
|
173
|
+
"</a:solidFill>",
|
174
|
+
"<a:prstDash val=\"solid\"/>",
|
175
|
+
"</a:ln>",
|
176
|
+
"</a:lnStyleLst>",
|
177
|
+
"<a:effectStyleLst>",
|
178
|
+
"<a:effectStyle>",
|
179
|
+
"<a:effectLst>",
|
180
|
+
"<a:outerShdw blurRad=\"40000\" dist=\"20000\" ",
|
181
|
+
"dir=\"5400000\" rotWithShape=\"0\">",
|
182
|
+
"<a:srgbClr val=\"000000\">",
|
183
|
+
"<a:alpha val=\"38000\"/>",
|
184
|
+
"</a:srgbClr>",
|
185
|
+
"</a:outerShdw>",
|
186
|
+
"</a:effectLst>",
|
187
|
+
"</a:effectStyle>",
|
188
|
+
"<a:effectStyle>",
|
189
|
+
"<a:effectLst>",
|
190
|
+
"<a:outerShdw blurRad=\"40000\" dist=\"23000\" ",
|
191
|
+
"dir=\"5400000\" rotWithShape=\"0\">",
|
192
|
+
"<a:srgbClr val=\"000000\">",
|
193
|
+
"<a:alpha val=\"35000\"/>",
|
194
|
+
"</a:srgbClr>",
|
195
|
+
"</a:outerShdw>",
|
196
|
+
"</a:effectLst>",
|
197
|
+
"</a:effectStyle>",
|
198
|
+
"<a:effectStyle>",
|
199
|
+
"<a:effectLst>",
|
200
|
+
"<a:outerShdw blurRad=\"40000\" dist=\"23000\" ",
|
201
|
+
"dir=\"5400000\" rotWithShape=\"0\">",
|
202
|
+
"<a:srgbClr val=\"000000\">",
|
203
|
+
"<a:alpha val=\"35000\"/>",
|
204
|
+
"</a:srgbClr>",
|
205
|
+
"</a:outerShdw>",
|
206
|
+
"</a:effectLst>",
|
207
|
+
"<a:scene3d>",
|
208
|
+
"<a:camera prst=\"orthographicFront\">",
|
209
|
+
"<a:rot lat=\"0\" lon=\"0\" rev=\"0\"/>",
|
210
|
+
"</a:camera>",
|
211
|
+
"<a:lightRig rig=\"threePt\" dir=\"t\">",
|
212
|
+
"<a:rot lat=\"0\" lon=\"0\" rev=\"1200000\"/>",
|
213
|
+
"</a:lightRig>",
|
214
|
+
"</a:scene3d>",
|
215
|
+
"<a:sp3d>",
|
216
|
+
"<a:bevelT w=\"63500\" h=\"25400\"/>",
|
217
|
+
"</a:sp3d>",
|
218
|
+
"</a:effectStyle>",
|
219
|
+
"</a:effectStyleLst>",
|
220
|
+
"<a:bgFillStyleLst>",
|
221
|
+
"<a:solidFill>",
|
222
|
+
"<a:schemeClr val=\"phClr\"/>",
|
223
|
+
"</a:solidFill>",
|
224
|
+
"<a:gradFill rotWithShape=\"1\">",
|
225
|
+
"<a:gsLst>",
|
226
|
+
"<a:gs pos=\"0\">",
|
227
|
+
"<a:schemeClr val=\"phClr\">",
|
228
|
+
"<a:tint val=\"40000\"/>",
|
229
|
+
"<a:satMod val=\"350000\"/>",
|
230
|
+
"</a:schemeClr>",
|
231
|
+
"</a:gs>",
|
232
|
+
"<a:gs pos=\"40000\">",
|
233
|
+
"<a:schemeClr val=\"phClr\">",
|
234
|
+
"<a:tint val=\"45000\"/>",
|
235
|
+
"<a:shade val=\"99000\"/>",
|
236
|
+
"<a:satMod val=\"350000\"/>",
|
237
|
+
"</a:schemeClr>",
|
238
|
+
"</a:gs>",
|
239
|
+
"<a:gs pos=\"100000\">",
|
240
|
+
"<a:schemeClr val=\"phClr\">",
|
241
|
+
"<a:shade val=\"20000\"/>",
|
242
|
+
"<a:satMod val=\"255000\"/>",
|
243
|
+
"</a:schemeClr>",
|
244
|
+
"</a:gs>",
|
245
|
+
"</a:gsLst>",
|
246
|
+
"<a:path path=\"circle\">",
|
247
|
+
"<a:fillToRect l=\"50000\" t=\"-80000\" r=\"50000\" b=\"180000\"/>",
|
248
|
+
"</a:path>",
|
249
|
+
"</a:gradFill>",
|
250
|
+
"<a:gradFill rotWithShape=\"1\">",
|
251
|
+
"<a:gsLst>",
|
252
|
+
"<a:gs pos=\"0\">",
|
253
|
+
"<a:schemeClr val=\"phClr\">",
|
254
|
+
"<a:tint val=\"80000\"/>",
|
255
|
+
"<a:satMod val=\"300000\"/>",
|
256
|
+
"</a:schemeClr>",
|
257
|
+
"</a:gs>",
|
258
|
+
"<a:gs pos=\"100000\">",
|
259
|
+
"<a:schemeClr val=\"phClr\">",
|
260
|
+
"<a:shade val=\"30000\"/>",
|
261
|
+
"<a:satMod val=\"200000\"/>",
|
262
|
+
"</a:schemeClr>",
|
263
|
+
"</a:gs>",
|
264
|
+
"</a:gsLst>",
|
265
|
+
"<a:path path=\"circle\">",
|
266
|
+
"<a:fillToRect l=\"50000\" t=\"50000\" r=\"50000\" b=\"50000\"/>",
|
267
|
+
"</a:path>",
|
268
|
+
"</a:gradFill>",
|
269
|
+
"</a:bgFillStyleLst>",
|
270
|
+
"</a:fmtScheme>",
|
271
|
+
"</a:themeElements>",
|
272
|
+
"<a:objectDefaults/>",
|
273
|
+
"<a:extraClrSchemeLst/>",
|
274
|
+
"</a:theme>\n",
|
275
|
+
""
|
276
|
+
};
|
277
|
+
|
278
|
+
/*
|
279
|
+
* Forward declarations.
|
280
|
+
*/
|
281
|
+
|
282
|
+
/*****************************************************************************
|
283
|
+
*
|
284
|
+
* Private functions.
|
285
|
+
*
|
286
|
+
****************************************************************************/
|
287
|
+
|
288
|
+
/*
|
289
|
+
* Create a new theme object.
|
290
|
+
*/
|
291
|
+
lxw_theme *
|
292
|
+
lxw_theme_new()
|
293
|
+
{
|
294
|
+
lxw_theme *theme = calloc(1, sizeof(lxw_theme));
|
295
|
+
GOTO_LABEL_ON_MEM_ERROR(theme, mem_error);
|
296
|
+
|
297
|
+
return theme;
|
298
|
+
|
299
|
+
mem_error:
|
300
|
+
lxw_theme_free(theme);
|
301
|
+
return NULL;
|
302
|
+
}
|
303
|
+
|
304
|
+
/*
|
305
|
+
* Free a theme object.
|
306
|
+
*/
|
307
|
+
void
|
308
|
+
lxw_theme_free(lxw_theme *theme)
|
309
|
+
{
|
310
|
+
if (!theme)
|
311
|
+
return;
|
312
|
+
|
313
|
+
free(theme);
|
314
|
+
}
|
315
|
+
|
316
|
+
/*****************************************************************************
|
317
|
+
*
|
318
|
+
* XML functions.
|
319
|
+
*
|
320
|
+
****************************************************************************/
|
321
|
+
|
322
|
+
/* This library isn't a xmlwriter. */
|
323
|
+
|
324
|
+
/*****************************************************************************
|
325
|
+
*
|
326
|
+
* XML file assembly functions.
|
327
|
+
*
|
328
|
+
****************************************************************************/
|
329
|
+
|
330
|
+
/*
|
331
|
+
* Assemble and write the XML file.
|
332
|
+
*/
|
333
|
+
void
|
334
|
+
lxw_theme_assemble_xml_file(lxw_theme *self)
|
335
|
+
{
|
336
|
+
int i = 0;
|
337
|
+
|
338
|
+
while (strlen(theme_strs[i])) {
|
339
|
+
fprintf(self->file, "%s", theme_strs[i]);
|
340
|
+
i++;
|
341
|
+
}
|
342
|
+
}
|
343
|
+
|
344
|
+
/*****************************************************************************
|
345
|
+
*
|
346
|
+
* Public functions.
|
347
|
+
*
|
348
|
+
****************************************************************************/
|
@@ -0,0 +1,512 @@
|
|
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
|
+
return row_num - 1;
|
247
|
+
}
|
248
|
+
|
249
|
+
/*
|
250
|
+
* Convert an Excel style A1 cell reference to a zero indexed column number.
|
251
|
+
*/
|
252
|
+
lxw_col_t
|
253
|
+
lxw_name_to_col(const char *col_str)
|
254
|
+
{
|
255
|
+
lxw_col_t col_num = 0;
|
256
|
+
const char *p = col_str;
|
257
|
+
|
258
|
+
/* Convert leading column letters of A1 cell. Ignore absolute $ marker. */
|
259
|
+
while (p && (isupper((unsigned char) *p) || *p == '$')) {
|
260
|
+
if (*p != '$')
|
261
|
+
col_num = (col_num * 26) + (*p - 'A' + 1);
|
262
|
+
p++;
|
263
|
+
}
|
264
|
+
|
265
|
+
return col_num - 1;
|
266
|
+
}
|
267
|
+
|
268
|
+
/*
|
269
|
+
* Convert the second row of an Excel range ref to a zero indexed number.
|
270
|
+
*/
|
271
|
+
uint32_t
|
272
|
+
lxw_name_to_row_2(const char *row_str)
|
273
|
+
{
|
274
|
+
const char *p = row_str;
|
275
|
+
|
276
|
+
/* Find the : separator in the range. */
|
277
|
+
while (p && *p != ':')
|
278
|
+
p++;
|
279
|
+
|
280
|
+
if (p)
|
281
|
+
return lxw_name_to_row(++p);
|
282
|
+
else
|
283
|
+
return -1;
|
284
|
+
}
|
285
|
+
|
286
|
+
/*
|
287
|
+
* Convert the second column of an Excel range ref to a zero indexed number.
|
288
|
+
*/
|
289
|
+
uint16_t
|
290
|
+
lxw_name_to_col_2(const char *col_str)
|
291
|
+
{
|
292
|
+
const char *p = col_str;
|
293
|
+
|
294
|
+
/* Find the : separator in the range. */
|
295
|
+
while (p && *p != ':')
|
296
|
+
p++;
|
297
|
+
|
298
|
+
if (p)
|
299
|
+
return lxw_name_to_col(++p);
|
300
|
+
else
|
301
|
+
return -1;
|
302
|
+
}
|
303
|
+
|
304
|
+
/*
|
305
|
+
* Convert a lxw_datetime struct to an Excel serial date.
|
306
|
+
*/
|
307
|
+
double
|
308
|
+
lxw_datetime_to_excel_date(lxw_datetime *datetime, uint8_t date_1904)
|
309
|
+
{
|
310
|
+
int year = datetime->year;
|
311
|
+
int month = datetime->month;
|
312
|
+
int day = datetime->day;
|
313
|
+
int hour = datetime->hour;
|
314
|
+
int min = datetime->min;
|
315
|
+
double sec = datetime->sec;
|
316
|
+
double seconds;
|
317
|
+
int epoch = date_1904 ? 1904 : 1900;
|
318
|
+
int offset = date_1904 ? 4 : 0;
|
319
|
+
int norm = 300;
|
320
|
+
int range;
|
321
|
+
/* Set month days and check for leap year. */
|
322
|
+
int mdays[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
323
|
+
int leap = 0;
|
324
|
+
int days = 0;
|
325
|
+
int i;
|
326
|
+
|
327
|
+
/* For times without dates set the default date for the epoch. */
|
328
|
+
if (!year) {
|
329
|
+
if (!date_1904) {
|
330
|
+
year = 1899;
|
331
|
+
month = 12;
|
332
|
+
day = 31;
|
333
|
+
}
|
334
|
+
else {
|
335
|
+
year = 1904;
|
336
|
+
month = 1;
|
337
|
+
day = 1;
|
338
|
+
}
|
339
|
+
}
|
340
|
+
|
341
|
+
/* Convert the Excel seconds to a fraction of the seconds in 24 hours. */
|
342
|
+
seconds = (hour * 60 * 60 + min * 60 + sec) / (24 * 60 * 60.0);
|
343
|
+
|
344
|
+
/* Special cases for Excel dates in the 1900 epoch. */
|
345
|
+
if (!date_1904) {
|
346
|
+
/* Excel 1900 epoch. */
|
347
|
+
if (year == 1899 && month == 12 && day == 31)
|
348
|
+
return seconds;
|
349
|
+
|
350
|
+
/* Excel 1900 epoch. */
|
351
|
+
if (year == 1900 && month == 1 && day == 0)
|
352
|
+
return seconds;
|
353
|
+
|
354
|
+
/* Excel false leapday */
|
355
|
+
if (year == 1900 && month == 2 && day == 29)
|
356
|
+
return 60 + seconds;
|
357
|
+
}
|
358
|
+
|
359
|
+
/* We calculate the date by calculating the number of days since the */
|
360
|
+
/* epoch and adjust for the number of leap days. We calculate the */
|
361
|
+
/* number of leap days by normalizing the year in relation to the */
|
362
|
+
/* epoch. Thus the year 2000 becomes 100 for 4-year and 100-year */
|
363
|
+
/* leapdays and 400 for 400-year leapdays. */
|
364
|
+
range = year - epoch;
|
365
|
+
|
366
|
+
if (year % 4 == 0 && (year % 100 > 0 || year % 400 == 0)) {
|
367
|
+
leap = 1;
|
368
|
+
mdays[2] = 29;
|
369
|
+
}
|
370
|
+
|
371
|
+
/*
|
372
|
+
* Calculate the serial date by accumulating the number of days
|
373
|
+
* since the epoch.
|
374
|
+
*/
|
375
|
+
|
376
|
+
/* Add days for previous months. */
|
377
|
+
for (i = 0; i < month; i++) {
|
378
|
+
days += mdays[i];
|
379
|
+
}
|
380
|
+
/* Add days for current month. */
|
381
|
+
days += day;
|
382
|
+
/* Add days for all previous years. */
|
383
|
+
days += range * 365;
|
384
|
+
/* Add 4 year leapdays. */
|
385
|
+
days += (range) / 4;
|
386
|
+
/* Remove 100 year leapdays. */
|
387
|
+
days -= (range + offset) / 100;
|
388
|
+
/* Add 400 year leapdays. */
|
389
|
+
days += (range + offset + norm) / 400;
|
390
|
+
/* Remove leap days already counted. */
|
391
|
+
days -= leap;
|
392
|
+
|
393
|
+
/* Adjust for Excel erroneously treating 1900 as a leap year. */
|
394
|
+
if (!date_1904 && days > 59)
|
395
|
+
days++;
|
396
|
+
|
397
|
+
return days + seconds;
|
398
|
+
}
|
399
|
+
|
400
|
+
/* Simple strdup() implementation since it isn't ANSI C. */
|
401
|
+
char *
|
402
|
+
lxw_strdup(const char *str)
|
403
|
+
{
|
404
|
+
size_t len;
|
405
|
+
char *copy;
|
406
|
+
|
407
|
+
if (!str)
|
408
|
+
return NULL;
|
409
|
+
|
410
|
+
len = strlen(str) + 1;
|
411
|
+
copy = malloc(len);
|
412
|
+
|
413
|
+
if (copy)
|
414
|
+
memcpy(copy, str, len);
|
415
|
+
|
416
|
+
return copy;
|
417
|
+
}
|
418
|
+
|
419
|
+
/* Simple strlen that counts UTF-8 characters. Assumes well formed UTF-8. */
|
420
|
+
size_t
|
421
|
+
lxw_utf8_strlen(const char *str)
|
422
|
+
{
|
423
|
+
size_t byte_count = 0;
|
424
|
+
size_t char_count = 0;
|
425
|
+
|
426
|
+
while (str[byte_count]) {
|
427
|
+
if ((str[byte_count] & 0xc0) != 0x80)
|
428
|
+
char_count++;
|
429
|
+
|
430
|
+
byte_count++;
|
431
|
+
}
|
432
|
+
|
433
|
+
return char_count;
|
434
|
+
}
|
435
|
+
|
436
|
+
/* Simple tolower() for strings. */
|
437
|
+
void
|
438
|
+
lxw_str_tolower(char *str)
|
439
|
+
{
|
440
|
+
int i;
|
441
|
+
|
442
|
+
for (i = 0; str[i]; i++)
|
443
|
+
str[i] = tolower(str[i]);
|
444
|
+
}
|
445
|
+
|
446
|
+
/* Create a quoted version of the worksheet name, or return an unmodified
|
447
|
+
* copy if it doesn't required quoting. */
|
448
|
+
char *
|
449
|
+
lxw_quote_sheetname(const char *str)
|
450
|
+
{
|
451
|
+
|
452
|
+
uint8_t needs_quoting = 0;
|
453
|
+
size_t number_of_quotes = 2;
|
454
|
+
size_t i, j;
|
455
|
+
size_t len = strlen(str);
|
456
|
+
|
457
|
+
/* Don't quote the sheetname if it is already quoted. */
|
458
|
+
if (str[0] == '\'')
|
459
|
+
return lxw_strdup(str);
|
460
|
+
|
461
|
+
/* Check if the sheetname contains any characters that require it
|
462
|
+
* to be quoted. Also check for single quotes within the string. */
|
463
|
+
for (i = 0; i < len; i++) {
|
464
|
+
if (!isalnum((unsigned char) str[i]) && str[i] != '_'
|
465
|
+
&& str[i] != '.')
|
466
|
+
needs_quoting = 1;
|
467
|
+
|
468
|
+
if (str[i] == '\'') {
|
469
|
+
needs_quoting = 1;
|
470
|
+
number_of_quotes++;
|
471
|
+
}
|
472
|
+
}
|
473
|
+
|
474
|
+
if (!needs_quoting) {
|
475
|
+
return lxw_strdup(str);
|
476
|
+
}
|
477
|
+
else {
|
478
|
+
/* Add single quotes to the start and end of the string. */
|
479
|
+
char *quoted_name = calloc(1, len + number_of_quotes + 1);
|
480
|
+
RETURN_ON_MEM_ERROR(quoted_name, NULL);
|
481
|
+
|
482
|
+
quoted_name[0] = '\'';
|
483
|
+
|
484
|
+
for (i = 0, j = 1; i < len; i++, j++) {
|
485
|
+
quoted_name[j] = str[i];
|
486
|
+
|
487
|
+
/* Double quote inline single quotes. */
|
488
|
+
if (str[i] == '\'') {
|
489
|
+
quoted_name[++j] = '\'';
|
490
|
+
}
|
491
|
+
}
|
492
|
+
quoted_name[j++] = '\'';
|
493
|
+
quoted_name[j++] = '\0';
|
494
|
+
|
495
|
+
return quoted_name;
|
496
|
+
}
|
497
|
+
}
|
498
|
+
|
499
|
+
/*
|
500
|
+
* Thin wrapper for tmpfile() so it can be over-ridden with a user defined
|
501
|
+
* version if required for safety or portability.
|
502
|
+
*/
|
503
|
+
FILE *
|
504
|
+
lxw_tmpfile(char *tmpdir)
|
505
|
+
{
|
506
|
+
#ifndef USE_STANDARD_TMPFILE
|
507
|
+
return tmpfileplus(tmpdir, NULL, NULL, 0);
|
508
|
+
#else
|
509
|
+
(void) tmpdir;
|
510
|
+
return tmpfile();
|
511
|
+
#endif
|
512
|
+
}
|