source: trunk/src/kernel32/time.cpp@ 4197

Last change on this file since 4197 was 4174, checked in by phaller, 25 years ago

WINE NLS sync

File size: 19.5 KB
Line 
1/* $Id: time.cpp,v 1.9 2000-09-03 18:04:56 phaller Exp $ */
2
3/*
4 * Win32 time/date API functions
5 *
6 * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
7 * Copyright 1999 Christoph Bratschi (cbratschi@datacomm.ch)
8 *
9 * Copyright 1996 Alexandre Julliard
10 * Copyright 1995 Martin von Loewis
11 * Copyright 1998 David Lee Lambert
12
13 *
14 * Project Odin Software License can be found in LICENSE.TXT
15 */
16#include <os2win.h>
17#include <winnls.h>
18#include "winuser.h"
19#include <stdlib.h>
20#include <string.h>
21#include <stdio.h>
22#include "unicode.h"
23
24#define DBG_LOCALLOG DBG_time
25#include "dbglocal.h"
26
27#define lstrcpynAtoW(unicode,ascii,asciilen) AsciiToUnicodeN(ascii,unicode,asciilen);
28
29#define WPRINTF_LEFTALIGN 0x0001 /* Align output on the left ('-' prefix) */
30#define WPRINTF_PREFIX_HEX 0x0002 /* Prefix hex with 0x ('#' prefix) */
31#define WPRINTF_ZEROPAD 0x0004 /* Pad with zeros ('0' prefix) */
32#define WPRINTF_LONG 0x0008 /* Long arg ('l' prefix) */
33#define WPRINTF_SHORT 0x0010 /* Short arg ('h' prefix) */
34#define WPRINTF_UPPER_HEX 0x0020 /* Upper-case hex ('X' specifier) */
35#define WPRINTF_WIDE 0x0040 /* Wide arg ('w' prefix) */
36
37typedef enum
38{
39 WPR_UNKNOWN,
40 WPR_CHAR,
41 WPR_WCHAR,
42 WPR_STRING,
43 WPR_WSTRING,
44 WPR_SIGNED,
45 WPR_UNSIGNED,
46 WPR_HEXA
47} WPRINTF_TYPE;
48
49typedef struct
50{
51 UINT flags;
52 UINT width;
53 UINT precision;
54 WPRINTF_TYPE type;
55} WPRINTF_FORMAT;
56
57typedef union {
58 WCHAR wchar_view;
59 CHAR char_view;
60 LPCSTR lpcstr_view;
61 LPCWSTR lpcwstr_view;
62 INT int_view;
63} WPRINTF_DATA;
64
65static const CHAR null_stringA[] = "(null)";
66static const WCHAR null_stringW[] = { '(', 'n', 'u', 'l', 'l', ')', 0 };
67
68//******************************************************************************
69//******************************************************************************
70VOID WIN32API GetLocalTime( LPSYSTEMTIME arg1)
71{
72/// dprintf(("KERNEL32: GetLocalTime\n"));
73 O32_GetLocalTime(arg1);
74}
75//******************************************************************************
76//******************************************************************************
77BOOL WIN32API SetLocalTime( const SYSTEMTIME * arg1)
78{
79 dprintf(("KERNEL32: SetLocalTime\n"));
80 return O32_SetLocalTime(arg1);
81}
82//******************************************************************************
83//******************************************************************************
84BOOL WIN32API FileTimeToDosDateTime(const FILETIME * arg1, LPWORD arg2, LPWORD arg3)
85{
86 dprintf(("KERNEL32: FileTimeToDosDateTime\n"));
87 return O32_FileTimeToDosDateTime(arg1, arg2, arg3);
88}
89//******************************************************************************
90//******************************************************************************
91BOOL WIN32API FileTimeToLocalFileTime(const FILETIME * arg1, LPFILETIME arg2)
92{
93 dprintf(("KERNEL32: FileTimeToLocalFileTime\n"));
94 return O32_FileTimeToLocalFileTime(arg1, arg2);
95}
96//******************************************************************************
97//******************************************************************************
98BOOL WIN32API LocalFileTimeToFileTime(const FILETIME * arg1, LPFILETIME arg2)
99{
100 dprintf(("KERNEL32: LocalFileTimeToFileTime\n"));
101 return O32_LocalFileTimeToFileTime(arg1, arg2);
102}
103//******************************************************************************
104//******************************************************************************
105BOOL WIN32API FileTimeToSystemTime(const FILETIME * arg1, LPSYSTEMTIME arg2)
106{
107 dprintf(("KERNEL32: FileTimeToSystemTime"));
108 return O32_FileTimeToSystemTime(arg1, arg2);
109}
110//******************************************************************************
111//******************************************************************************
112BOOL WIN32API DosDateTimeToFileTime( WORD arg1, WORD arg2, LPFILETIME arg3)
113{
114 dprintf(("KERNEL32: DosDateTimeToFileTime\n"));
115 return O32_DosDateTimeToFileTime(arg1, arg2, arg3);
116}
117//******************************************************************************
118//******************************************************************************
119DWORD WIN32API GetTimeZoneInformation( LPTIME_ZONE_INFORMATION arg1)
120{
121 dprintf(("KERNEL32: GetTimeZoneInformation\n"));
122 return O32_GetTimeZoneInformation(arg1);
123}
124//******************************************************************************
125//******************************************************************************
126DWORD WIN32API GetTickCount(void)
127{
128//// dprintf(("KERNEL32: GetTickCount\n"));
129 return O32_GetTickCount();
130}
131//******************************************************************************
132//******************************************************************************
133VOID WIN32API GetSystemTime( LPSYSTEMTIME arg1)
134{
135 dprintf(("KERNEL32: OS2GetSystemTime\n"));
136 O32_GetSystemTime(arg1);
137}
138//******************************************************************************
139//******************************************************************************
140BOOL WIN32API SystemTimeToFileTime( const SYSTEMTIME * arg1, LPFILETIME arg2)
141{
142 dprintf(("KERNEL32: OS2SystemTimeToFileTime\n"));
143 return O32_SystemTimeToFileTime(arg1, arg2);
144}
145//******************************************************************************
146//******************************************************************************
147BOOL WIN32API SystemTimeToTzSpecificLocalTime( LPTIME_ZONE_INFORMATION arg1, LPSYSTEMTIME arg2, LPSYSTEMTIME arg3)
148{
149 dprintf(("KERNEL32: OS2SystemTimeToTzSpecificLocalTime\n"));
150 return O32_SystemTimeToTzSpecificLocalTime(arg1, arg2, arg3);
151}
152//******************************************************************************
153//******************************************************************************
154BOOL WIN32API SetTimeZoneInformation( const LPTIME_ZONE_INFORMATION arg1)
155{
156 dprintf(("KERNEL32: OS2SetTimeZoneInformation\n"));
157 return O32_SetTimeZoneInformation(arg1);
158}
159//******************************************************************************
160//******************************************************************************
161BOOL WIN32API SetSystemTime(const SYSTEMTIME * arg1)
162{
163 dprintf(("KERNEL32: OS2SetSystemTime\n"));
164 return O32_SetSystemTime(arg1);
165}
166
167/***********************************************************************
168 * WPRINTF_ParseFormatA
169 *
170 * Parse a format specification. A format specification has the form:
171 *
172 * [-][#][0][width][.precision]type
173 *
174 * Return value is the length of the format specification in characters.
175 */
176static INT WPRINTF_ParseFormatA( LPCSTR format, WPRINTF_FORMAT *res )
177{
178 LPCSTR p = format;
179
180 res->flags = 0;
181 res->width = 0;
182 res->precision = 0;
183 if (*p == '-') { res->flags |= WPRINTF_LEFTALIGN; p++; }
184 if (*p == '#') { res->flags |= WPRINTF_PREFIX_HEX; p++; }
185 if (*p == '0') { res->flags |= WPRINTF_ZEROPAD; p++; }
186 while ((*p >= '0') && (*p <= '9')) /* width field */
187 {
188 res->width = res->width * 10 + *p - '0';
189 p++;
190 }
191 if (*p == '.') /* precision field */
192 {
193 p++;
194 while ((*p >= '0') && (*p <= '9'))
195 {
196 res->precision = res->precision * 10 + *p - '0';
197 p++;
198 }
199 }
200 if (*p == 'l') { res->flags |= WPRINTF_LONG; p++; }
201 else if (*p == 'h') { res->flags |= WPRINTF_SHORT; p++; }
202 else if (*p == 'w') { res->flags |= WPRINTF_WIDE; p++; }
203 switch(*p)
204 {
205 case 'c':
206 res->type = (res->flags & WPRINTF_LONG) ? WPR_WCHAR : WPR_CHAR;
207 break;
208 case 'C':
209 res->type = (res->flags & WPRINTF_SHORT) ? WPR_CHAR : WPR_WCHAR;
210 break;
211 case 'd':
212 case 'i':
213 res->type = WPR_SIGNED;
214 break;
215 case 's':
216 res->type = (res->flags & (WPRINTF_LONG |WPRINTF_WIDE))
217 ? WPR_WSTRING : WPR_STRING;
218 break;
219 case 'S':
220 res->type = (res->flags & (WPRINTF_SHORT|WPRINTF_WIDE))
221 ? WPR_STRING : WPR_WSTRING;
222 break;
223 case 'u':
224 res->type = WPR_UNSIGNED;
225 break;
226 case 'X':
227 res->flags |= WPRINTF_UPPER_HEX;
228 /* fall through */
229 case 'x':
230 res->type = WPR_HEXA;
231 break;
232 default: /* unknown format char */
233 res->type = WPR_UNKNOWN;
234 p--; /* print format as normal char */
235 break;
236 }
237 return (INT)(p - format) + 1;
238}
239
240
241/***********************************************************************
242 * WPRINTF_ParseFormatW
243 *
244 * Parse a format specification. A format specification has the form:
245 *
246 * [-][#][0][width][.precision]type
247 *
248 * Return value is the length of the format specification in characters.
249 */
250static INT WPRINTF_ParseFormatW( LPCWSTR format, WPRINTF_FORMAT *res )
251{
252 LPCWSTR p = format;
253
254 res->flags = 0;
255 res->width = 0;
256 res->precision = 0;
257 if (*p == '-') { res->flags |= WPRINTF_LEFTALIGN; p++; }
258 if (*p == '#') { res->flags |= WPRINTF_PREFIX_HEX; p++; }
259 if (*p == '0') { res->flags |= WPRINTF_ZEROPAD; p++; }
260 while ((*p >= '0') && (*p <= '9')) /* width field */
261 {
262 res->width = res->width * 10 + *p - '0';
263 p++;
264 }
265 if (*p == '.') /* precision field */
266 {
267 p++;
268 while ((*p >= '0') && (*p <= '9'))
269 {
270 res->precision = res->precision * 10 + *p - '0';
271 p++;
272 }
273 }
274 if (*p == 'l') { res->flags |= WPRINTF_LONG; p++; }
275 else if (*p == 'h') { res->flags |= WPRINTF_SHORT; p++; }
276 else if (*p == 'w') { res->flags |= WPRINTF_WIDE; p++; }
277 switch((CHAR)*p)
278 {
279 case 'c':
280 res->type = (res->flags & WPRINTF_SHORT) ? WPR_CHAR : WPR_WCHAR;
281 break;
282 case 'C':
283 res->type = (res->flags & WPRINTF_LONG) ? WPR_WCHAR : WPR_CHAR;
284 break;
285 case 'd':
286 case 'i':
287 res->type = WPR_SIGNED;
288 break;
289 case 's':
290 res->type = ((res->flags & WPRINTF_SHORT) && !(res->flags & WPRINTF_WIDE)) ? WPR_STRING : WPR_WSTRING;
291 break;
292 case 'S':
293 res->type = (res->flags & (WPRINTF_LONG|WPRINTF_WIDE)) ? WPR_WSTRING : WPR_STRING;
294 break;
295 case 'u':
296 res->type = WPR_UNSIGNED;
297 break;
298 case 'X':
299 res->flags |= WPRINTF_UPPER_HEX;
300 /* fall through */
301 case 'x':
302 res->type = WPR_HEXA;
303 break;
304 default:
305 res->type = WPR_UNKNOWN;
306 p--; /* print format as normal char */
307 break;
308 }
309 return (INT)(p - format) + 1;
310}
311
312
313/***********************************************************************
314 * WPRINTF_GetLen
315 */
316static UINT WPRINTF_GetLen( WPRINTF_FORMAT *format, WPRINTF_DATA *arg,
317 LPSTR number, UINT maxlen )
318{
319 UINT len;
320
321 if (format->flags & WPRINTF_LEFTALIGN) format->flags &= ~WPRINTF_ZEROPAD;
322 if (format->width > maxlen) format->width = maxlen;
323 switch(format->type)
324 {
325 case WPR_CHAR:
326 case WPR_WCHAR:
327 return (format->precision = 1);
328 case WPR_STRING:
329 if (!arg->lpcstr_view) arg->lpcstr_view = null_stringA;
330 for (len = 0; !format->precision || (len < format->precision); len++)
331 if (!*(arg->lpcstr_view + len)) break;
332 if (len > maxlen) len = maxlen;
333 return (format->precision = len);
334 case WPR_WSTRING:
335 if (!arg->lpcwstr_view) arg->lpcwstr_view = null_stringW;
336 for (len = 0; !format->precision || (len < format->precision); len++)
337 if (!*(arg->lpcwstr_view + len)) break;
338 if (len > maxlen) len = maxlen;
339 return (format->precision = len);
340 case WPR_SIGNED:
341 len = sprintf( number, "%d", arg->int_view );
342 break;
343 case WPR_UNSIGNED:
344 len = sprintf( number, "%u", (UINT)arg->int_view );
345 break;
346 case WPR_HEXA:
347 len = sprintf( number,
348 (format->flags & WPRINTF_UPPER_HEX) ? "%X" : "%x",
349 (UINT)arg->int_view);
350 if (format->flags & WPRINTF_PREFIX_HEX) len += 2;
351 break;
352 default:
353 return 0;
354 }
355 if (len > maxlen) len = maxlen;
356 if (format->precision < len) format->precision = len;
357 if (format->precision > maxlen) format->precision = maxlen;
358 if ((format->flags & WPRINTF_ZEROPAD) && (format->width > format->precision))
359 format->precision = format->width;
360 return len;
361}
362
363/***********************************************************************
364 * WPRINTF_ExtractVAPtr (Not a Windows API)
365 */
366static WPRINTF_DATA WPRINTF_ExtractVAPtr( WPRINTF_FORMAT *format, va_list* args )
367{
368 WPRINTF_DATA result;
369 switch(format->type)
370 {
371 case WPR_WCHAR:
372 result.wchar_view = va_arg( *args, WCHAR ); break;
373 case WPR_CHAR:
374 result.char_view = va_arg( *args, CHAR ); break;
375 case WPR_STRING:
376 result.lpcstr_view = va_arg( *args, LPCSTR); break;
377 case WPR_WSTRING:
378 result.lpcwstr_view = va_arg( *args, LPCWSTR); break;
379 case WPR_HEXA:
380 case WPR_SIGNED:
381 case WPR_UNSIGNED:
382 result.int_view = va_arg( *args, INT ); break;
383 default:
384 result.wchar_view = 0; break;
385 }
386 return result;
387}
388
389/***********************************************************************
390 * wvsnprintfA (Not a Windows API)
391 */
392INT WINAPI wvsnprintfA( LPSTR buffer, UINT maxlen, LPCSTR spec,
393 va_list args )
394{
395 WPRINTF_FORMAT format;
396 LPSTR p = buffer;
397 UINT i, len;
398 CHAR number[20];
399 WPRINTF_DATA argData;
400
401 while (*spec && (maxlen > 1))
402 {
403 if (*spec != '%') { *p++ = *spec++; maxlen--; continue; }
404 spec++;
405 if (*spec == '%') { *p++ = *spec++; maxlen--; continue; }
406 spec += WPRINTF_ParseFormatA( spec, &format );
407 argData = WPRINTF_ExtractVAPtr( &format, &args );
408 len = WPRINTF_GetLen( &format, &argData, number, maxlen - 1 );
409 if (!(format.flags & WPRINTF_LEFTALIGN))
410 for (i = format.precision; i < format.width; i++, maxlen--)
411 *p++ = ' ';
412 switch(format.type)
413 {
414 case WPR_WCHAR:
415 *p = argData.wchar_view;
416 if (*p != '\0') p++;
417 else if (format.width > 1) *p++ = ' ';
418 else len = 0;
419 break;
420 case WPR_CHAR:
421 *p = argData.char_view;
422 if (*p != '\0') p++;
423 else if (format.width > 1) *p++ = ' ';
424 else len = 0;
425 break;
426 case WPR_STRING:
427 memcpy( p, argData.lpcstr_view, len );
428 p += len;
429 break;
430 case WPR_WSTRING:
431 {
432 LPCWSTR ptr = argData.lpcwstr_view;
433 for (i = 0; i < len; i++) *p++ = (CHAR)*ptr++;
434 }
435 break;
436 case WPR_HEXA:
437 if ((format.flags & WPRINTF_PREFIX_HEX) && (maxlen > 3))
438 {
439 *p++ = '0';
440 *p++ = (format.flags & WPRINTF_UPPER_HEX) ? 'X' : 'x';
441 maxlen -= 2;
442 len -= 2;
443 format.precision -= 2;
444 format.width -= 2;
445 }
446 /* fall through */
447 case WPR_SIGNED:
448 case WPR_UNSIGNED:
449 for (i = len; i < format.precision; i++, maxlen--) *p++ = '0';
450 memcpy( p, number, len );
451 p += len;
452 /* Go to the next arg */
453 break;
454 case WPR_UNKNOWN:
455 continue;
456 }
457 if (format.flags & WPRINTF_LEFTALIGN)
458 for (i = format.precision; i < format.width; i++, maxlen--)
459 *p++ = ' ';
460 maxlen -= len;
461 }
462 *p = 0;
463 //TRACE("%s\n",buffer);
464 return (maxlen > 1) ? (INT)(p - buffer) : -1;
465}
466
467
468/***********************************************************************
469 * wvsnprintfW (Not a Windows API)
470 */
471INT WINAPI wvsnprintfW( LPWSTR buffer, UINT maxlen, LPCWSTR spec,
472 va_list args )
473{
474 WPRINTF_FORMAT format;
475 LPWSTR p = buffer;
476 UINT i, len;
477 CHAR number[20];
478
479 while (*spec && (maxlen > 1))
480 {
481 if (*spec != '%') { *p++ = *spec++; maxlen--; continue; }
482 spec++;
483 if (*spec == '%') { *p++ = *spec++; maxlen--; continue; }
484 spec += WPRINTF_ParseFormatW( spec, &format );
485 len = WPRINTF_GetLen( &format, (WPRINTF_DATA*)args, number, maxlen - 1 );
486 if (!(format.flags & WPRINTF_LEFTALIGN))
487 for (i = format.precision; i < format.width; i++, maxlen--)
488 *p++ = ' ';
489 switch(format.type)
490 {
491 case WPR_WCHAR:
492 *p = va_arg( args, WCHAR );
493 if (*p != '\0') p++;
494 else if (format.width > 1) *p++ = ' ';
495 else len = 0;
496 break;
497 case WPR_CHAR:
498 *p = (WCHAR)va_arg( args, CHAR );
499 if (*p != '\0') p++;
500 else if (format.width > 1) *p++ = ' ';
501 else len = 0;
502 break;
503 case WPR_STRING:
504 {
505 LPCSTR ptr = va_arg( args, LPCSTR );
506 for (i = 0; i < len; i++) *p++ = (WCHAR)*ptr++;
507 }
508 break;
509 case WPR_WSTRING:
510 if (len) memcpy( p, va_arg( args, LPCWSTR ), len * sizeof(WCHAR) );
511 p += len;
512 break;
513 case WPR_HEXA:
514 if ((format.flags & WPRINTF_PREFIX_HEX) && (maxlen > 3))
515 {
516 *p++ = '0';
517 *p++ = (format.flags & WPRINTF_UPPER_HEX) ? 'X' : 'x';
518 maxlen -= 2;
519 len -= 2;
520 format.precision -= 2;
521 format.width -= 2;
522 }
523 /* fall through */
524 case WPR_SIGNED:
525 case WPR_UNSIGNED:
526 for (i = len; i < format.precision; i++, maxlen--) *p++ = '0';
527 for (i = 0; i < len; i++) *p++ = (WCHAR)number[i];
528 (void)va_arg( args, INT ); /* Go to the next arg */
529 break;
530 case WPR_UNKNOWN:
531 continue;
532 }
533 if (format.flags & WPRINTF_LEFTALIGN)
534 for (i = format.precision; i < format.width; i++, maxlen--)
535 *p++ = ' ';
536 maxlen -= len;
537 }
538 *p = 0;
539 return (maxlen > 1) ? (INT)(p - buffer) : -1;
540}
541
542/***********************************************************************
543 * wsnprintfA (Not a Windows API)
544 */
545INT WINAPIV wsnprintfA( LPSTR buffer, UINT maxlen, LPCSTR spec, ... )
546{
547 va_list valist;
548 INT res;
549
550 va_start( valist, spec );
551 res = wvsnprintfA( buffer, maxlen, spec, valist );
552 va_end( valist );
553 return res;
554}
555
556/***********************************************************************
557 * wsnprintfW (Not a Windows API)
558 */
559INT WINAPIV wsnprintfW( LPWSTR buffer, UINT maxlen, LPCWSTR spec, ... )
560{
561 va_list valist;
562 INT res;
563
564 va_start( valist, spec );
565 res = wvsnprintfW( buffer, maxlen, spec, valist );
566 va_end( valist );
567 return res;
568}
569
570
571/*****************************************************************************
572 * Name : DWORD GetSystemTimeAsFileTime
573 * Purpose : The GetSystemTimeAsFileTime function obtains the current system
574 * date and time. The information is in Coordinated Universal Time (UTC) format.
575 * Parameters: LLPFILETIME lLPSYSTEMTIMEAsFileTime
576 * Variables :
577 * Result :
578 * Remark :
579 * Status : UNTESTED
580 *
581 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
582 *****************************************************************************/
583
584VOID WIN32API GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime)
585{
586 FILETIME ft; /* code sequence from WIN32.HLP */
587 SYSTEMTIME st;
588
589 dprintf(("KERNEL32: GetSystemTimeAsFileTime(%08xh)\n", lpSystemTimeAsFileTime));
590
591 GetSystemTime(&st);
592 SystemTimeToFileTime(&st, &ft);
593}
Note: See TracBrowser for help on using the repository browser.