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

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

.

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