1 /************************************************************************/
2 /* */
3 /* Unit types and conversions between units. */
4 /* */
5 /************************************************************************/
6
7 # include "appUtilConfig.h"
8
9 # include <string.h>
10 # include <time.h>
11
12 # include "appUnit.h"
13 # include <appDebugon.h>
14
appUnitTypeInt(const char * unitTypeString)15 int appUnitTypeInt( const char * unitTypeString )
16 {
17 if ( ! strcmp( unitTypeString, "cm" ) )
18 { return UNITtyCM; }
19
20 if ( ! strcmp( unitTypeString, "inch" ) ||
21 ! strcmp( unitTypeString, "\"" ) )
22 { return UNITtyINCH; }
23
24 if ( ! strcmp( unitTypeString, "points" ) ||
25 ! strcmp( unitTypeString, "pt" ) )
26 { return UNITtyPOINTS; }
27
28 if ( ! strcmp( unitTypeString, "picas" ) ||
29 ! strcmp( unitTypeString, "pi" ) )
30 { return UNITtyPICAS; }
31
32 if ( ! strcmp( unitTypeString, "mm" ) )
33 { return UNITtyMM; }
34
35 return -1;
36 }
37
appUnitTypeString(int unitTypeInt)38 const char * appUnitTypeString( int unitTypeInt )
39 {
40 switch( unitTypeInt )
41 {
42 case UNITtyCM: return "cm";
43 case UNITtyINCH: return "\"";
44 case UNITtyPOINTS: return "pt";
45 case UNITtyPICAS: return "pi";
46 case UNITtyMM: return "mm";
47 default:
48 LDEB(unitTypeInt); return "?";
49 }
50 }
51
appUnitFromTwips(int twips,int unitTypeInt)52 double appUnitFromTwips( int twips,
53 int unitTypeInt )
54 {
55 switch( unitTypeInt )
56 {
57 case UNITtyCM: return ( 2.54* twips )/ ( 20.0* 72 );
58 case UNITtyINCH: return twips/ ( 20.0* 72 );
59 case UNITtyPOINTS: return twips/ 20.0;
60 case UNITtyPICAS: return twips/ ( 20.0* 12 );
61 case UNITtyMM: return ( 25.4* twips )/ ( 20.0* 72 );
62 default:
63 LDEB(unitTypeInt); return -1;
64 }
65 }
66
appUnitToTwips(double units,int unitTypeInt)67 double appUnitToTwips( double units,
68 int unitTypeInt )
69 {
70 switch( unitTypeInt )
71 {
72 case UNITtyCM: return ( 20.0* 72* units )/ 2.54;
73 case UNITtyINCH: return 20.0* 72* units;
74 case UNITtyPOINTS: return 20.0* units;
75 case UNITtyPICAS: return 20.0* 12* units;
76 case UNITtyMM: return ( 20.0* 72* units )/ 25.4;
77 default:
78 LDEB(unitTypeInt); return -1;
79 }
80 }
81
82 /************************************************************************/
83 /* */
84 /* Format a date according to an 'MS-Word' datetime picture */
85 /* */
86 /* "sequence" (sequence value) values are not supported here.. They */
87 /* are supposed to be inserted and properly escaped beforehand or to */
88 /* be replaced later on. */
89 /* */
90 /* It is the responsibility of the caller to cope with the */
91 /* interference between the output of the strftime() substitutions and */
92 /* the 'sequence' substitutins in the order in which they are applied. */
93 /* */
94 /************************************************************************/
95
appWordFormatDate(char * to,int maxlen,const struct tm * tm,const char * wordPicture)96 int appWordFormatDate( char * to,
97 int maxlen,
98 const struct tm * tm,
99 const char * wordPicture )
100 {
101 int l;
102 const char * from= wordPicture;
103 const char * frm;
104
105 while( *from )
106 {
107 switch( *from )
108 {
109 int count;
110
111 case 'M':
112 count= 1;
113 from++;
114 while( count < 4 && from[0] == from[-1] )
115 { from++; count++; }
116 switch( count )
117 {
118 case 1:
119 l= strftime( to, maxlen+ 1, "%m", tm );
120 if ( l < 1 )
121 { LDEB(l); return -1; }
122 if ( to[0] == '0' )
123 { memmove( to, to+ 1, l+ 1 ); }
124 to += l; maxlen -= l;
125 continue;
126
127 case 2:
128 l= strftime( to, maxlen+ 1, "%m", tm );
129 if ( l < 1 )
130 { LDEB(l); return -1; }
131 to += l; maxlen -= l;
132 continue;
133
134 case 3:
135 l= strftime( to, maxlen+ 1, "%b", tm );
136 if ( l < 1 )
137 { LDEB(l); return -1; }
138 to += l; maxlen -= l;
139 continue;
140
141 case 4:
142 l= strftime( to, maxlen+ 1, "%B", tm );
143 if ( l < 1 )
144 { LDEB(l); return -1; }
145 to += l; maxlen -= l;
146 continue;
147
148 default:
149 LDEB(count); return -1;
150 }
151
152 case 'd': case 'D':
153 count= 1;
154 from++;
155 while( count < 4 &&
156 tolower( from[0] ) == tolower( from[-1] ) )
157 { from++; count++; }
158 switch( count )
159 {
160 case 1:
161 l= strftime( to, maxlen+ 1, "%d", tm );
162 if ( l < 1 )
163 { LDEB(l); return -1; }
164 if ( to[0] == '0' )
165 { memmove( to, to+ 1, l+ 1 ); }
166 to += l; maxlen -= l;
167 continue;
168
169 case 2:
170 l= strftime( to, maxlen+ 1, "%d", tm );
171 if ( l < 1 )
172 { LDEB(l); return -1; }
173 to += l; maxlen -= l;
174 continue;
175
176 case 3:
177 l= strftime( to, maxlen+ 1, "%a", tm );
178 if ( l < 1 )
179 { LDEB(l); return -1; }
180 to += l; maxlen -= l;
181 continue;
182
183 case 4:
184 l= strftime( to, maxlen+ 1, "%A", tm );
185 if ( l < 1 )
186 { LDEB(l); return -1; }
187 to += l; maxlen -= l;
188 continue;
189
190 default:
191 LDEB(count); return -1;
192 }
193
194 case 'y': case 'Y':
195 count= 1;
196 from++;
197 while( count < 4 &&
198 tolower( from[0] ) == tolower( from[-1] ) )
199 { from++; count++; }
200 switch( count )
201 {
202 case 2:
203 /* GCC: Shut Up! */
204 frm= "%y";
205 l= strftime( to, maxlen+ 1, frm, tm );
206 if ( l < 1 )
207 { LDEB(l); return -1; }
208 to += l; maxlen -= l;
209 continue;
210
211 case 4:
212 l= strftime( to, maxlen+ 1, "%Y", tm );
213 if ( l < 1 )
214 { LDEB(l); return -1; }
215 to += l; maxlen -= l;
216 continue;
217
218 default:
219 LDEB(count); return -1;
220 }
221
222 case 'H':
223 count= 1;
224 from++;
225 while( count < 2 && from[0] == from[-1] )
226 { from++; count++; }
227 switch( count )
228 {
229 case 1:
230 l= strftime( to, maxlen+ 1, "%H", tm );
231 if ( l < 1 )
232 { LDEB(l); return -1; }
233 if ( to[0] == '0' )
234 { memmove( to, to+ 1, l+ 1 ); }
235 to += l; maxlen -= l;
236 continue;
237
238 case 2:
239 l= strftime( to, maxlen+ 1, "%H", tm );
240 if ( l < 1 )
241 { LDEB(l); return -1; }
242 to += l; maxlen -= l;
243 continue;
244
245 default:
246 LDEB(count); return -1;
247 }
248
249 case 'h':
250 count= 1;
251 from++;
252 while( count < 2 && from[0] == from[-1] )
253 { from++; count++; }
254 switch( count )
255 {
256 case 1:
257 l= strftime( to, maxlen+ 1, "%I", tm );
258 if ( l < 1 )
259 { LDEB(l); return -1; }
260 if ( to[0] == '0' )
261 { memmove( to, to+ 1, l+ 1 ); }
262 to += l; maxlen -= l;
263 continue;
264
265 case 2:
266 l= strftime( to, maxlen+ 1, "%I", tm );
267 if ( l < 1 )
268 { LDEB(l); return -1; }
269 to += l; maxlen -= l;
270 continue;
271
272 default:
273 LDEB(count); return -1;
274 }
275
276 case 'm':
277 count= 1;
278 from++;
279 while( count < 2 && from[0] == from[-1] )
280 { from++; count++; }
281 switch( count )
282 {
283 case 1:
284 l= strftime( to, maxlen+ 1, "%M", tm );
285 if ( l < 1 )
286 { LDEB(l); return -1; }
287 if ( to[0] == '0' )
288 { memmove( to, to+ 1, l+ 1 ); }
289 to += l; maxlen -= l;
290 continue;
291
292 case 2:
293 l= strftime( to, maxlen+ 1, "%M", tm );
294 if ( l < 1 )
295 { LDEB(l); return -1; }
296 to += l; maxlen -= l;
297 continue;
298
299 default:
300 LDEB(count); return -1;
301 }
302
303 case 'A': case 'a':
304 if ( ! strcmp( from, "AM/PM" ) ||
305 ! strcmp( from, "am/pm" ) )
306 {
307 l= strftime( to, maxlen+ 1, "%p", tm );
308 if ( l < 1 )
309 { LDEB(l); return -1; }
310 to += l; maxlen -= l; from += 5;
311 continue;
312 }
313
314 if ( ! strcmp( from, "A/P" ) ||
315 ! strcmp( from, "a/p" ) )
316 {
317 l= strftime( to, maxlen+ 1, "%p", tm );
318 if ( l < 1 )
319 { LDEB(l); return -1; }
320 to += l; maxlen -= l; from += 3;
321 continue;
322 }
323
324 goto defaultCase;
325
326 case '\'':
327 from++;
328 while( *from != '\'' )
329 {
330 if ( ! *from )
331 { LDEB(1); return -1; }
332
333 if ( maxlen < 1 )
334 { LDEB(maxlen); return -1; }
335 *(to++)= *(from++); maxlen--;
336 }
337
338 from++; /* '\'' */
339 continue;
340
341 case '`':
342 if ( maxlen < 1 )
343 { LDEB(maxlen); return -1; }
344 *(to++)= *(from++);
345 while( *from != '\'' )
346 {
347 if ( ! *from )
348 { LDEB(1); return -1; }
349
350 if ( maxlen < 1 )
351 { LDEB(maxlen); return -1; }
352 *(to++)= *(from++); maxlen--;
353 }
354
355 if ( maxlen < 1 )
356 { LDEB(maxlen); return -1; }
357 *(to++)= *(from++);
358 continue;
359
360 default: defaultCase:
361 if ( maxlen < 1 )
362 { LDEB(maxlen); return -1; }
363 *(to++)= *(from++); maxlen--;
364 continue;
365 }
366 }
367
368 *to= '\0';
369
370 return 0;
371 }
372
373 /************************************************************************/
374 /* */
375 /* Invalidate/Initialize a 'struct tm'. */
376 /* */
377 /************************************************************************/
378
utilInvalidateTime(struct tm * tm)379 void utilInvalidateTime( struct tm * tm )
380 {
381 const time_t t= 0;
382
383 *tm= *localtime( &t );
384
385 tm->tm_mday= 0;
386
387 return;
388 }
389
390