source: trunk/src/crtdll/crtdll_main.c@ 4667

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

Major move towards WINE CRTDLL, mixture between both code branches

File size: 25.2 KB
Line 
1/*
2 * The C RunTime DLL
3 *
4 * Implements C run-time functionality as known from UNIX.
5 *
6 * Copyright 1996,1998 Marcus Meissner
7 * Copyright 1996 Jukka Iivonen
8 * Copyright 1997,2000 Uwe Bonnes
9 * Copyright 2000 Jon Griffiths
10 */
11
12/*
13Unresolved issues Uwe Bonnes 970904:
14- tested with ftp://ftp.remcomp.com/pub/remcomp/lcc-win32.zip, a C-Compiler
15 for Win32, based on lcc, from Jacob Navia
16UB 000416:
17- probably not thread safe
18*/
19
20/* NOTE: This file also implements the wcs* functions. They _ARE_ in
21 * the newer Linux libcs, but use 4 byte wide characters, so are unusable,
22 * since we need 2 byte wide characters. - Marcus Meissner, 981031
23 */
24
25#include <string.h>
26#include <errno.h>
27
28#include <float.h>
29#include <libc\locale.h>
30#include <setjmp.h>
31#include "signal.h"
32
33
34#include "crtdll.h"
35#include <ctype.h>
36#define __USE_ISOC9X 1 /* for isfinite */
37#include <math.h>
38#include <errno.h>
39#include <stdlib.h>
40#include "ntddk.h"
41#include "wingdi.h"
42#include "winuser.h"
43
44
45DEFAULT_DEBUG_CHANNEL(crtdll);
46
47
48UINT CRTDLL_argc_dll; /* CRTDLL.23 */
49LPSTR *CRTDLL_argv_dll; /* CRTDLL.24 */
50LPSTR CRTDLL_acmdln_dll; /* CRTDLL.38 */
51UINT CRTDLL_basemajor_dll; /* CRTDLL.42 */
52UINT CRTDLL_baseminor_dll; /* CRTDLL.43 */
53UINT CRTDLL_baseversion_dll; /* CRTDLL.44 */
54UINT CRTDLL_commode_dll; /* CRTDLL.59 */
55LPSTR CRTDLL_environ_dll; /* CRTDLL.75 */
56UINT CRTDLL_fmode_dll; /* CRTDLL.104 */
57UINT CRTDLL_osmajor_dll; /* CRTDLL.241 */
58UINT CRTDLL_osminor_dll; /* CRTDLL.242 */
59UINT CRTDLL_osmode_dll; /* CRTDLL.243 */
60UINT CRTDLL_osver_dll; /* CRTDLL.244 */
61UINT CRTDLL_osversion_dll; /* CRTDLL.245 */
62UINT CRTDLL_winmajor_dll; /* CRTDLL.329 */
63UINT CRTDLL_winminor_dll; /* CRTDLL.330 */
64UINT CRTDLL_winver_dll; /* CRTDLL.331 */
65INT CRTDLL_doserrno = 0;
66INT CRTDLL_errno = 0;
67const INT CRTDLL__sys_nerr = 43;
68
69
70
71
72#define FS_OS2 unsigned short sel = RestoreOS2FS();
73#define FS_WIN32 SetFS(sel);
74
75
76/*********************************************************************
77 * CRTDLL_MainInit (CRTDLL.init)
78 */
79
80BOOL WINAPI CRTDLL_Init(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
81{
82 FS_OS2
83
84 // call i/o initializer in file.c
85 if (fdwReason == DLL_PROCESS_ATTACH)
86 {
87 __CRTDLL__init_io();
88 }
89
90 /*
91 PH 2000/11/21 this code doesn't look very useful
92
93 if (fdwReason == DLL_PROCESS_ATTACH) {
94 _fdopen(0,"r");
95 _fdopen(1,"w");
96 _fdopen(2,"w");
97 CRTDLL_hHeap = HeapCreate(0, 0x10000, 0);
98 }
99 else
100 if (fdwReason == DLL_PROCESS_DETACH) {
101 HeapDestroy(CRTDLL_hHeap);
102 CRTDLL_hHeap = 0;
103 }
104 */
105
106 FS_WIN32
107 return TRUE;
108}
109
110
111/* INTERNAL: Set the crt and dos errno's from the OS error given. */
112void __CRTDLL__set_errno(ULONG err)
113{
114 /* FIXME: not MT safe */
115 CRTDLL_doserrno = err;
116
117 switch(err)
118 {
119#define ERR_CASE(oserr) case oserr:
120#define ERR_MAPS(oserr,crterr) case oserr:CRTDLL_errno = crterr;break;
121 ERR_CASE(ERROR_ACCESS_DENIED)
122 ERR_CASE(ERROR_NETWORK_ACCESS_DENIED)
123 ERR_CASE(ERROR_CANNOT_MAKE)
124 ERR_CASE(ERROR_SEEK_ON_DEVICE)
125 ERR_CASE(ERROR_LOCK_FAILED)
126 ERR_CASE(ERROR_FAIL_I24)
127 ERR_CASE(ERROR_CURRENT_DIRECTORY)
128 ERR_CASE(ERROR_DRIVE_LOCKED)
129 ERR_CASE(ERROR_NOT_LOCKED)
130 ERR_CASE(ERROR_INVALID_ACCESS)
131 ERR_MAPS(ERROR_LOCK_VIOLATION, EACCES);
132 ERR_CASE(ERROR_FILE_NOT_FOUND)
133 ERR_CASE(ERROR_NO_MORE_FILES)
134 ERR_CASE(ERROR_BAD_PATHNAME)
135 ERR_CASE(ERROR_BAD_NETPATH)
136 ERR_CASE(ERROR_INVALID_DRIVE)
137 ERR_CASE(ERROR_BAD_NET_NAME)
138 ERR_CASE(ERROR_FILENAME_EXCED_RANGE)
139 ERR_MAPS(ERROR_PATH_NOT_FOUND, ENOENT);
140/* @@@PH ERR_MAPS(ERROR_IO_DEVICE, EIO); */
141 ERR_MAPS(ERROR_BAD_FORMAT, ENOEXEC);
142 ERR_MAPS(ERROR_INVALID_HANDLE, EBADF);
143 ERR_CASE(ERROR_OUTOFMEMORY)
144 ERR_CASE(ERROR_INVALID_BLOCK)
145 ERR_CASE(ERROR_NOT_ENOUGH_QUOTA);
146 ERR_MAPS(ERROR_ARENA_TRASHED, ENOMEM);
147/* @@@PH ERR_MAPS(ERROR_BUSY, EBUSY); */
148 ERR_CASE(ERROR_ALREADY_EXISTS)
149 ERR_MAPS(ERROR_FILE_EXISTS, EEXIST);
150/* @@@PH ERR_MAPS(ERROR_BAD_DEVICE, ENODEV); */
151 ERR_MAPS(ERROR_TOO_MANY_OPEN_FILES, EMFILE);
152 ERR_MAPS(ERROR_DISK_FULL, ENOSPC);
153/* @@@PH ERR_MAPS(ERROR_BROKEN_PIPE, EPIPE); */
154/* @@@PH ERR_MAPS(ERROR_POSSIBLE_DEADLOCK, EDEADLK); */
155/* @@@PH ERR_MAPS(ERROR_DIR_NOT_EMPTY, ENOTEMPTY); */
156 ERR_MAPS(ERROR_BAD_ENVIRONMENT, E2BIG);
157 ERR_CASE(ERROR_WAIT_NO_CHILDREN)
158 ERR_MAPS(ERROR_CHILD_NOT_COMPLETE, ECHILD);
159 ERR_CASE(ERROR_NO_PROC_SLOTS)
160 ERR_CASE(ERROR_MAX_THRDS_REACHED)
161 ERR_MAPS(ERROR_NESTING_NOT_ALLOWED, EAGAIN);
162 default:
163 /* Remaining cases map to EINVAL */
164 /* FIXME: may be missing some errors above */
165 CRTDLL_errno = EINVAL;
166 }
167}
168
169
170/*********************************************************************
171 * _GetMainArgs (CRTDLL.022)
172 */
173LPSTR * CDECL CRTDLL__GetMainArgs(LPDWORD argc,LPSTR **argv,
174 LPSTR *environ,DWORD flag)
175{
176 char *cmdline;
177 char **xargv;
178 int xargc,end,last_arg,afterlastspace;
179 DWORD version;
180
181 TRACE("(%p,%p,%p,%ld).\n",
182 argc,argv,environ,flag
183 );
184
185 if (CRTDLL_acmdln_dll != NULL)
186 HeapFree(GetProcessHeap(), 0, CRTDLL_acmdln_dll);
187
188 CRTDLL_acmdln_dll = cmdline = CRTDLL__strdup( GetCommandLineA() );
189 TRACE("got '%s'\n", cmdline);
190
191 version = GetVersion();
192 CRTDLL_osver_dll = version >> 16;
193 CRTDLL_winminor_dll = version & 0xFF;
194 CRTDLL_winmajor_dll = (version>>8) & 0xFF;
195 CRTDLL_baseversion_dll = version >> 16;
196 CRTDLL_winver_dll = ((version >> 8) & 0xFF) + ((version & 0xFF) << 8);
197 CRTDLL_baseminor_dll = (version >> 16) & 0xFF;
198 CRTDLL_basemajor_dll = (version >> 24) & 0xFF;
199 CRTDLL_osversion_dll = version & 0xFFFF;
200 CRTDLL_osminor_dll = version & 0xFF;
201 CRTDLL_osmajor_dll = (version>>8) & 0xFF;
202
203 /* missing threading init */
204
205 end=0;last_arg=0;xargv=NULL;xargc=0;afterlastspace=0;
206 while (1)
207 {
208 if ((cmdline[end]==' ') || (cmdline[end]=='\0'))
209 {
210 if (cmdline[end]=='\0')
211 last_arg=1;
212 else
213 cmdline[end]='\0';
214 /* alloc xargc + NULL entry */
215 xargv=(char**)HeapReAlloc( GetProcessHeap(), 0, xargv,
216 sizeof(char*)*(xargc+1));
217 if (strlen(cmdline+afterlastspace))
218 {
219 xargv[xargc] = CRTDLL__strdup(cmdline+afterlastspace);
220 xargc++;
221 if (!last_arg) /* need to seek to the next arg ? */
222 {
223 end++;
224 while (cmdline[end]==' ')
225 end++;
226 }
227 afterlastspace=end;
228 }
229 else
230 {
231 xargv[xargc] = NULL; /* the last entry is NULL */
232 break;
233 }
234 }
235 else
236 end++;
237 }
238 CRTDLL_argc_dll = xargc;
239 *argc = xargc;
240 CRTDLL_argv_dll = xargv;
241 *argv = xargv;
242
243 TRACE("found %d arguments\n",
244 CRTDLL_argc_dll);
245 CRTDLL_environ_dll = *environ = GetEnvironmentStringsA();
246 return environ;
247}
248
249
250/*********************************************************************
251 * _initterm (CRTDLL.135)
252 */
253DWORD CDECL CRTDLL__initterm(_INITTERMFUN *start,_INITTERMFUN *end)
254{
255 _INITTERMFUN *current;
256
257 TRACE("(%p,%p)\n",start,end);
258 current=start;
259 while (current<end) {
260 if (*current) (*current)();
261 current++;
262 }
263 return 0;
264}
265
266
267/*******************************************************************
268 * _global_unwind2 (CRTDLL.129)
269 */
270void CDECL CRTDLL__global_unwind2( PEXCEPTION_FRAME frame )
271{
272 RtlUnwind( frame, 0, NULL, 0 );
273}
274
275
276/*******************************************************************
277 * _local_unwind2 (CRTDLL.173)
278 */
279void CDECL CRTDLL__local_unwind2( PEXCEPTION_FRAME endframe, DWORD nr )
280{
281 dprintf2(("CRTDLL: _local_unwind2\n"));
282 TRACE("(%p,%ld)\n",endframe,nr);
283}
284
285
286/*********************************************************************
287 * _beep (CRTDLL.045)
288 *
289 * Output a tone using the PC speaker.
290 *
291 * PARAMS
292 * freq [in] Frequency of the tone
293 *
294 * duration [in] Length of time the tone should sound
295 *
296 * RETURNS
297 * None.
298 */
299void CDECL CRTDLL__beep( UINT freq, UINT duration)
300{
301 TRACE(":Freq %d, Duration %d\n",freq,duration);
302 Beep(freq, duration);
303}
304
305
306/*********************************************************************
307 * rand (CRTDLL.446)
308 */
309INT CDECL CRTDLL_rand()
310{
311 return (rand() & CRTDLL_RAND_MAX);
312}
313
314
315/*********************************************************************
316 * _rotl (CRTDLL.259)
317 */
318UINT CDECL CRTDLL__rotl(UINT x,INT shift)
319{
320 // return (_rotl(value, shift));
321
322 shift &= 31;
323 return (x << shift) | (x >> (32-shift));
324}
325
326
327/*********************************************************************
328 * _lrotl (CRTDLL.175)
329 */
330DWORD CDECL CRTDLL__lrotl(DWORD x,INT shift)
331{
332 // return (_lrotl(value, shift));
333
334 shift &= 31;
335 return (x << shift) | (x >> (32-shift));
336}
337
338
339/*********************************************************************
340 * _lrotr (CRTDLL.176)
341 */
342DWORD CDECL CRTDLL__lrotr(DWORD x,INT shift)
343{
344 // return (_lrotr(value, shift));
345
346 shift &= 0x1f;
347 return (x >> shift) | (x << (32-shift));
348}
349
350
351/*********************************************************************
352 * _rotr (CRTDLL.258)
353 */
354DWORD CDECL CRTDLL__rotr(UINT x,INT shift)
355{
356 // return (_rotr(value, shift));
357
358 shift &= 0x1f;
359 return (x >> shift) | (x << (32-shift));
360}
361
362
363/*********************************************************************
364 * vswprintf (CRTDLL.501)
365 */
366INT CDECL CRTDLL_vswprintf( LPWSTR buffer, LPCWSTR spec, va_list args )
367{
368 // return (vswprintf(s, t, format, arg));
369
370 return wvsprintfW( buffer, spec, args );
371}
372
373
374/*********************************************************************
375 * longjmp (CRTDLL.426)
376 */
377VOID CDECL CRTDLL_longjmp(jmp_buf env, int val)
378{
379 FIXME("CRTDLL_longjmp semistub, expect crash\n");
380 longjmp(env, val);
381}
382
383
384/*********************************************************************
385 * setlocale (CRTDLL.453)
386 */
387LPSTR CDECL CRTDLL_setlocale(INT category,LPCSTR locale)
388{
389 return (setlocale(category, locale));
390
391 /*
392 LPSTR categorystr;
393
394 switch (category) {
395 case CRTDLL_LC_ALL: categorystr="LC_ALL";break;
396 case CRTDLL_LC_COLLATE: categorystr="LC_COLLATE";break;
397 case CRTDLL_LC_CTYPE: categorystr="LC_CTYPE";break;
398 case CRTDLL_LC_MONETARY: categorystr="LC_MONETARY";break;
399 case CRTDLL_LC_NUMERIC: categorystr="LC_NUMERIC";break;
400 case CRTDLL_LC_TIME: categorystr="LC_TIME";break;
401 default: categorystr = "UNKNOWN?";break;
402 }
403 FIXME("(%s,%s),stub!\n",categorystr,locale);
404 return "C";
405 */
406}
407
408
409/*********************************************************************
410 * _isctype (CRTDLL.138)
411 */
412BOOL CDECL CRTDLL__isctype(CHAR x,CHAR type)
413{
414 if ((type & CRTDLL_SPACE) && isspace(x))
415 return TRUE;
416 if ((type & CRTDLL_PUNCT) && ispunct(x))
417 return TRUE;
418 if ((type & CRTDLL_LOWER) && islower(x))
419 return TRUE;
420 if ((type & CRTDLL_UPPER) && isupper(x))
421 return TRUE;
422 if ((type & CRTDLL_ALPHA) && isalpha(x))
423 return TRUE;
424 if ((type & CRTDLL_DIGIT) && isdigit(x))
425 return TRUE;
426 if ((type & CRTDLL_CONTROL) && iscntrl(x))
427 return TRUE;
428 /* check CRTDLL_LEADBYTE */
429 return FALSE;
430}
431
432
433/*********************************************************************
434 * _fullpath (CRTDLL.114)
435 */
436LPSTR CDECL CRTDLL__fullpath(LPSTR buf, LPCSTR name, INT size)
437{
438 // return (_fullpath(buf, path, size));
439
440 if (!buf)
441 {
442 size = 256;
443 if(!(buf = CRTDLL_malloc(size))) return NULL;
444 }
445 if (!GetFullPathNameA( name, size, buf, NULL )) return NULL;
446 TRACE("CRTDLL_fullpath got %s\n",buf);
447 return buf;
448}
449
450
451/*********************************************************************
452 * _splitpath (CRTDLL.279)
453 */
454VOID CDECL CRTDLL__splitpath(LPCSTR path, LPSTR drive, LPSTR directory, LPSTR filename, LPSTR extension )
455{
456 // _splitpath( path, drive, dir, fname, ext);
457
458 /* drive includes :
459 directory includes leading and trailing (forward and backward slashes)
460 filename without dot and slashes
461 extension with leading dot
462 */
463 char * drivechar,*dirchar,*namechar;
464
465 TRACE("CRTDLL__splitpath got %s\n",path);
466
467 drivechar = strchr(path,':');
468 dirchar = strrchr(path,'/');
469 namechar = strrchr(path,'\\');
470 dirchar = max(dirchar,namechar);
471 if (dirchar)
472 namechar = strrchr(dirchar,'.');
473 else
474 namechar = strrchr(path,'.');
475
476 if (drive)
477 {
478 *drive = 0x00;
479 if (drivechar)
480 {
481 strncat(drive,path,drivechar-path+1);
482 path = drivechar+1;
483 }
484 }
485 if (directory)
486 {
487 *directory = 0x00;
488 if (dirchar)
489 {
490 strncat(directory,path,dirchar-path+1);
491 path = dirchar+1;
492 }
493 }
494 if (filename)
495 {
496 *filename = 0x00;
497 if (namechar)
498 {
499 strncat(filename,path,namechar-path);
500 if (extension)
501 {
502 *extension = 0x00;
503 strcat(extension,namechar);
504 }
505 }
506 }
507
508 TRACE("CRTDLL__splitpath found %s %s %s %s\n",drive,directory,filename,extension);
509}
510
511
512/*********************************************************************
513 * _makepath (CRTDLL.182)
514 */
515
516VOID CDECL CRTDLL__makepath(LPSTR path, LPCSTR drive,
517 LPCSTR directory, LPCSTR filename,
518 LPCSTR extension )
519{
520 // _makepath(path, drive, dir, fname, ext);
521
522 char ch;
523 TRACE("CRTDLL__makepath got %s %s %s %s\n", drive, directory,
524 filename, extension);
525
526 if ( !path )
527 return;
528
529 path[0] = 0;
530 if (drive && drive[0])
531 {
532 path[0] = drive[0];
533 path[1] = ':';
534 path[2] = 0;
535 }
536 if (directory && directory[0])
537 {
538 strcat(path, directory);
539 ch = path[strlen(path)-1];
540 if (ch != '/' && ch != '\\')
541 strcat(path,"\\");
542 }
543 if (filename && filename[0])
544 {
545 strcat(path, filename);
546 if (extension && extension[0])
547 {
548 if ( extension[0] != '.' ) {
549 strcat(path,".");
550 }
551 strcat(path,extension);
552 }
553 }
554
555 TRACE("CRTDLL__makepath returns %s\n",path);
556}
557
558
559/*********************************************************************
560 * _errno (CRTDLL.52)
561 * Return the address of the CRT errno (Not the libc errno).
562 * @@@PH Note: veeeery strange ...
563 * BUGS
564 * Not MT safe.
565 */
566LPINT CDECL CRTDLL__errno( VOID )
567{
568 // return (_errno());
569
570 return &CRTDLL_errno;
571}
572
573
574/*********************************************************************
575 * __doserrno (CRTDLL.26)
576 *
577 * Return the address of the DOS errno (holding the last OS error).
578 * @@@PH Note: veeeery strange ...
579 * BUGS
580 * Not MT safe.
581 */
582LPINT CDECL CRTDLL___doserrno( VOID )
583{
584 // return (__doserrno());
585
586 return &CRTDLL_doserrno;
587}
588
589
590/**********************************************************************
591 * _strerror (CRTDLL.284)
592 *
593 * Return a formatted system error message.
594 *
595 * NOTES
596 * The caller does not own the string returned.
597 */
598extern int sprintf(char *str, const char *format, ...);
599
600LPSTR CDECL CRTDLL__strerror (LPCSTR err)
601{
602 // return (_strerror((char*)s));
603
604 static char strerrbuff[256];
605 sprintf(strerrbuff,"%s: %s\n",err,CRTDLL_strerror(CRTDLL_errno));
606 return strerrbuff;
607}
608
609
610/*********************************************************************
611 * perror (CRTDLL.435)
612 *
613 * Print a formatted system error message to stderr.
614 */
615VOID CDECL CRTDLL_perror (LPCSTR err)
616{
617 // perror( s );
618
619 char *err_str = CRTDLL_strerror(CRTDLL_errno);
620 CRTDLL_fprintf(CRTDLL_stderr,"%s: %s\n",err,err_str);
621 CRTDLL_free(err_str);
622}
623
624
625/*********************************************************************
626 * strerror (CRTDLL.465)
627 *
628 * Return the text of an error.
629 *
630 * NOTES
631 * The caller does not own the string returned.
632 */
633extern char *strerror(int errnum);
634
635LPSTR CDECL CRTDLL_strerror (INT err)
636{
637 return strerror(err);
638}
639
640
641/*********************************************************************
642 * signal (CRTDLL.455)
643 */
644LPVOID CDECL CRTDLL_signal(INT sig, sig_handler_type ptr)
645{
646 //return (signal(sig, ptr));
647
648 FIXME("(%d %p):stub.\n", sig, ptr);
649 return (void*)-1;
650}
651
652
653/*********************************************************************
654 * _sleep (CRTDLL.267)
655 */
656VOID CDECL CRTDLL__sleep(ULONG timeout)
657{
658 TRACE("CRTDLL__sleep for %ld milliseconds\n",timeout);
659 Sleep((timeout)?timeout:1);
660}
661
662
663/*********************************************************************
664 * getenv (CRTDLL.437)
665 */
666LPSTR CDECL CRTDLL_getenv(LPCSTR name)
667{
668 // return (getenv(name));
669
670 LPSTR environ = GetEnvironmentStringsA();
671 LPSTR pp,pos = NULL;
672 unsigned int length;
673
674 for (pp = environ; (*pp); pp = pp + strlen(pp) +1)
675 {
676 pos =strchr(pp,'=');
677 if (pos)
678 length = pos -pp;
679 else
680 length = strlen(pp);
681 if (!strncmp(pp,name,length)) break;
682 }
683 if ((pp)&& (pos))
684 {
685 pp = pos+1;
686 TRACE("got %s\n",pp);
687 }
688 FreeEnvironmentStringsA( environ );
689 return pp;
690}
691
692
693/*********************************************************************
694 * _except_handler2 (CRTDLL.78)
695 */
696INT CDECL CRTDLL__except_handler2 (
697 PEXCEPTION_RECORD rec,
698 PEXCEPTION_FRAME frame,
699 PCONTEXT context,
700 PEXCEPTION_FRAME *dispatcher)
701{
702 FIXME ("exception %lx flags=%lx at %p handler=%p %p %p stub\n",
703 rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress,
704 frame->Handler, context, dispatcher);
705 return ExceptionContinueSearch;
706}
707
708
709/*********************************************************************
710 * __isascii (CRTDLL.028)
711 *
712 */
713INT CDECL CRTDLL___isascii(INT c)
714{
715 return isascii(c);
716}
717
718
719/*********************************************************************
720 * __toascii (CRTDLL.035)
721 *
722 */
723INT CDECL CRTDLL___toascii(INT c)
724{
725 // return (_toascii(c));
726
727 return c & 0x7f;
728}
729
730
731/*********************************************************************
732 * iswascii (CRTDLL.404)
733 *
734 */
735INT CDECL CRTDLL_iswascii(LONG c)
736{
737 // return (!((c)&(~0x7f)));
738 return ((unsigned)c < 0x80);
739}
740
741
742/*********************************************************************
743 * __iscsym (CRTDLL.029)
744 *
745 * Is a character valid in a C identifier (a-Z,0-9,_).
746 *
747 * PARAMS
748 * c [I]: Character to check
749 *
750 * RETURNS
751 * Non zero if c is valid as t a C identifier.
752 */
753INT CDECL CRTDLL___iscsym(LONG c)
754{
755 // return (_iscsym(c));
756
757 return (isalnum(c) || c == '_');
758}
759
760
761/*********************************************************************
762 * __iscsymf (CRTDLL.030)
763 *
764 * Is a character valid as the first letter in a C identifier (a-Z,_).
765 *
766 * PARAMS
767 * c [in] Character to check
768 *
769 * RETURNS
770 * Non zero if c is valid as the first letter in a C identifier.
771 */
772INT CDECL CRTDLL___iscsymf(LONG c)
773{
774 // return (_iscsymf(c));
775
776 return (isalpha(c) || c == '_');
777}
778
779
780/*********************************************************************
781 * _loaddll (CRTDLL.171)
782 *
783 * Get a handle to a DLL in memory. The DLL is loaded if it is not already.
784 *
785 * PARAMS
786 * dll [in] Name of DLL to load.
787 *
788 * RETURNS
789 * Success: A handle to the loaded DLL.
790 *
791 * Failure: FIXME.
792 */
793INT CDECL CRTDLL__loaddll(LPSTR dllname)
794{
795 return LoadLibraryA(dllname);
796}
797
798
799/*********************************************************************
800 * _unloaddll (CRTDLL.313)
801 *
802 * Free reference to a DLL handle from loaddll().
803 *
804 * PARAMS
805 * dll [in] Handle to free.
806 *
807 * RETURNS
808 * Success: 0.
809 *
810 * Failure: Error number.
811 */
812INT CDECL CRTDLL__unloaddll(HANDLE dll)
813{
814 INT err;
815 if (FreeLibrary(dll))
816 return 0;
817 err = GetLastError();
818 __CRTDLL__set_errno(err);
819 return err;
820}
821
822
823/*********************************************************************
824 * _lsearch (CRTDLL.177)
825 *
826 * Linear search of an array of elements. Adds the item to the array if
827 * not found.
828 *
829 * PARAMS
830 * match [in] Pointer to element to match
831 * start [in] Pointer to start of search memory
832 * array_size [in] Length of search array (element count)
833 * elem_size [in] Size of each element in memory
834 * comp_func [in] Pointer to comparason function (like qsort()).
835 *
836 * RETURNS
837 * Pointer to the location where element was found or added.
838 */
839LPVOID CDECL CRTDLL__lsearch(LPVOID match,LPVOID start, LPUINT array_size,
840 UINT elem_size, comp_func cf)
841{
842 LPBYTE pStart = (LPBYTE)start;
843 UINT size = *array_size;
844 if (size)
845 do
846 {
847 if (cf((LPVOID*)match, (LPVOID*)pStart) == 0)
848 return pStart; /* found */
849 pStart += elem_size;
850 } while (--size);
851
852 /* not found, add to end */
853 memcpy(pStart, match, elem_size);
854 array_size[0]++;
855 return pStart;
856}
857
858
859/*********************************************************************
860 * _itow (CRTDLL.164)
861 *
862 * Convert an integer to a wide char string.
863 */
864/* @@@PH extern LPSTR CDECL _itoa( long , LPSTR , INT);*/ /* ntdll */
865
866WCHAR* CDECL CRTDLL__itow(INT value,WCHAR* out,INT base)
867{
868 char buff[64]; /* FIXME: Whats the maximum buffer size for INT_MAX? */
869
870 _itoa(value, buff, base);
871 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, buff, -1, out, 64);
872 return out;
873}
874
875
876/*********************************************************************
877 * _ltow (CRTDLL.??)
878 *
879 * Convert a long to a wide char string.
880 */
881/* @@@PH extern LPSTR CDECL _ltoa( long , LPSTR , INT); */ /* ntdll */
882
883WCHAR* CDECL CRTDLL__ltow(LONG value,WCHAR* out,INT base)
884{
885 char buff[64]; /* FIXME: Whats the maximum buffer size for LONG_MAX? */
886
887 _ltoa(value, buff, base);
888 MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, buff, -1, out, 64);
889 return out;
890}
891
892
893/*********************************************************************
894 * _ultow (CRTDLL.??)
895 *
896 * Convert an unsigned long to a wide char string.
897 */
898/* @@@PH extern LPSTR CDECL _ultoa( long , LPSTR , INT); */ /* ntdll */
899
900WCHAR* CDECL CRTDLL__ultow(ULONG value,WCHAR* out,INT base)
901{
902 char buff[64]; /* FIXME: Whats the maximum buffer size for ULONG_MAX? */
903
904 _ultoa(value, buff, base);
905 MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, buff, -1, out, 64);
906 return out;
907}
908
909
910/*********************************************************************
911 * _toupper (CRTDLL.489)
912 */
913CHAR CDECL CRTDLL__toupper(CHAR c)
914{
915 // return (_toupper(n));
916
917 return toupper(c);
918}
919
920
921/*********************************************************************
922 * _tolower (CRTDLL.490)
923 */
924CHAR CDECL CRTDLL__tolower(CHAR c)
925{
926 // return (_tolower(n));
927
928 return tolower(c);
929}
930
931
932/* FP functions */
933
934/*********************************************************************
935 * _cabs (CRTDLL.048)
936 *
937 * Return the absolue value of a complex number.
938 *
939 * PARAMS
940 * c [in] Structure containing real and imaginary parts of complex number.
941 *
942 * RETURNS
943 * Absolute value of complex number (always a positive real number).
944 */
945double CDECL CRTDLL__cabs(struct __CRTDLL_complex c)
946{
947 // return (_cabs(c));
948
949 return sqrt(c.real * c.real + c.imaginary * c.imaginary);
950}
951
952
953/*********************************************************************
954 * _chgsign (CRTDLL.053)
955 *
956 * Change the sign of an IEEE double.
957 *
958 * PARAMS
959 * d [in] Number to invert.
960 *
961 * RETURNS
962 * Number with sign inverted.
963 */
964double CDECL CRTDLL__chgsign(double d)
965{
966 /* FIXME: +-infinity,Nan not tested */
967 return -d;
968}
969
970
971/*********************************************************************
972 * _copysign (CRTDLL.062)
973 *
974 * Return the number x with the sign of y.
975 */
976double CDECL CRTDLL__copysign(double x, double y)
977{
978 /* FIXME: Behaviour for Nan/Inf etc? */
979 if (y < 0.0)
980 return x < 0.0 ? x : -x;
981
982 return x < 0.0 ? -x : x;
983}
984
985
986/*********************************************************************
987 * _finite (CRTDLL.101)
988 *
989 * Determine if an IEEE double is finite (i.e. not +/- Infinity).
990 *
991 * PARAMS
992 * d [in] Number to check.
993 *
994 * RETURNS
995 * Non zero if number is finite.
996 */
997INT CDECL CRTDLL__finite(double d)
998{
999 return 0;
1000 //@@@PH return (isfinite(d)?1:0); /* See comment for CRTDLL__isnan() */
1001}
1002
1003
1004/*********************************************************************
1005 * _fpreset (CRTDLL.107)
1006 *
1007 * Reset the state of the floating point processor.
1008 *
1009 * PARAMS
1010 * None.
1011 *
1012 * RETURNS
1013 * None.
1014 *
1015 * BUGS
1016 * Unimplemented.
1017 */
1018VOID CDECL CRTDLL__fpreset(void)
1019{
1020 //FIXME(":stub!\n");
1021 _fpreset();
1022}
1023
1024
1025/*********************************************************************
1026 * _isnan (CRTDLL.164)
1027 *
1028 * Determine if an IEEE double is unrepresentable (NaN).
1029 *
1030 * PARAMS
1031 * d [in] Number to check.
1032 *
1033 * RETURNS
1034 * Non zero if number is NaN.
1035 */
1036INT CDECL CRTDLL__isnan(double d)
1037{
1038 /* some implementations return -1 for true(glibc), crtdll returns 1.
1039 * Do the same, as the result may be used in calculations.
1040 */
1041 return 0;
1042 //@@@PH return isnan(d)?1:0;
1043}
Note: See TracBrowser for help on using the repository browser.