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