Release 970509
[wine/multimedia.git] / misc / crtdll.c
blobf9ab8c0cecf241abeda20a48e02b3a11e469a3cd
1 /*
2 * The C RunTime DLL
3 *
4 * Implements C run-time functionality as known from UNIX.
6 * Copyright 1996 Marcus Meissner
7 * Copyright 1996 Jukka Iivonen
8 */
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <stdarg.h>
13 #include <string.h>
14 #include <unistd.h>
15 #include <time.h>
16 #include <ctype.h>
17 #include <math.h>
18 #include "win.h"
19 #include "windows.h"
20 #include "stddebug.h"
21 #include "debug.h"
22 #include "module.h"
23 #include "xmalloc.h"
24 #include "heap.h"
25 #include "crtdll.h"
26 #include "drive.h"
28 UINT32 CRTDLL_argc_dll; /* CRTDLL.23 */
29 LPSTR *CRTDLL_argv_dll; /* CRTDLL.24 */
30 LPSTR CRTDLL_acmdln_dll; /* CRTDLL.38 */
31 UINT32 CRTDLL_basemajor_dll; /* CRTDLL.42 */
32 UINT32 CRTDLL_baseminor_dll; /* CRTDLL.43 */
33 UINT32 CRTDLL_baseversion_dll; /* CRTDLL.44 */
34 LPSTR CRTDLL_environ_dll; /* CRTDLL.75 */
35 UINT32 CRTDLL_osmajor_dll; /* CRTDLL.241 */
36 UINT32 CRTDLL_osminor_dll; /* CRTDLL.242 */
37 UINT32 CRTDLL_osver_dll; /* CRTDLL.244 */
38 UINT32 CRTDLL_osversion_dll; /* CRTDLL.245 */
39 UINT32 CRTDLL_winmajor_dll; /* CRTDLL.329 */
40 UINT32 CRTDLL_winminor_dll; /* CRTDLL.330 */
41 UINT32 CRTDLL_winver_dll; /* CRTDLL.331 */
43 typedef VOID (*new_handler_type)(VOID);
45 static new_handler_type new_handler;
47 /*********************************************************************
48 * _GetMainArgs (CRTDLL.022)
50 DWORD
51 CRTDLL__GetMainArgs(LPDWORD argc,LPSTR **argv,LPSTR *environ,DWORD flag)
53 char *cmdline;
54 char **xargv;
55 int xargc,i,afterlastspace;
56 DWORD version;
58 dprintf_crtdll(stderr,"__GetMainArgs(%p,%p,%p,%ld).\n",
59 argc,argv,environ,flag
61 CRTDLL_acmdln_dll = cmdline = xstrdup( GetCommandLine32A() );
63 version = GetVersion32();
64 CRTDLL_osver_dll = version >> 16;
65 CRTDLL_winminor_dll = version & 0xFF;
66 CRTDLL_winmajor_dll = (version>>8) & 0xFF;
67 CRTDLL_baseversion_dll = version >> 16;
68 CRTDLL_winver_dll = ((version >> 8) & 0xFF) + ((version & 0xFF) << 8);
69 CRTDLL_baseminor_dll = (version >> 16) & 0xFF;
70 CRTDLL_basemajor_dll = (version >> 24) & 0xFF;
71 CRTDLL_osversion_dll = version & 0xFFFF;
72 CRTDLL_osminor_dll = version & 0xFF;
73 CRTDLL_osmajor_dll = (version>>8) & 0xFF;
75 /* missing threading init */
77 i=0;xargv=NULL;xargc=0;afterlastspace=0;
78 while (cmdline[i]) {
79 if (cmdline[i]==' ') {
80 xargv=(char**)xrealloc(xargv,sizeof(char*)*(++xargc));
81 cmdline[i]='\0';
82 xargv[xargc-1] = xstrdup(cmdline+afterlastspace);
83 i++;
84 while (cmdline[i]==' ')
85 i++;
86 if (cmdline[i])
87 afterlastspace=i;
88 } else
89 i++;
91 xargv=(char**)xrealloc(xargv,sizeof(char*)*(++xargc));
92 cmdline[i]='\0';
93 xargv[xargc-1] = xstrdup(cmdline+afterlastspace);
94 CRTDLL_argc_dll = xargc;
95 *argc = xargc;
96 CRTDLL_argv_dll = xargv;
97 *argv = xargv;
99 /* FIXME ... use real environment */
100 *environ = xmalloc(sizeof(LPSTR));
101 CRTDLL_environ_dll = *environ;
102 (*environ)[0] = NULL;
103 return 0;
106 typedef void (*_INITTERMFUN)();
108 /*********************************************************************
109 * _initterm (CRTDLL.135)
111 DWORD CRTDLL__initterm(_INITTERMFUN *start,_INITTERMFUN *end)
113 _INITTERMFUN *current;
115 dprintf_crtdll(stddeb,"_initterm(%p,%p)\n",start,end);
116 current=start;
117 while (current<end) {
118 if (*current) (*current)();
119 current++;
121 return 0;
124 /*********************************************************************
125 * srand (CRTDLL.460)
127 void CRTDLL_srand(DWORD seed)
129 /* FIXME: should of course be thread? process? local */
130 srand(seed);
133 /*********************************************************************
134 * fprintf (CRTDLL.373)
136 int CRTDLL_fprintf(DWORD *args)
138 /* FIXME: use args[0] */
139 /* CMF - This makes a BIG assumption about va_list */
140 return vfprintf(stderr, (LPSTR) args[1], (va_list) &args[2]);
143 /*********************************************************************
144 * printf (CRTDLL.440)
146 int CRTDLL_printf(DWORD *args)
148 /* CMF - This makes a BIG assumption about va_list */
149 return vfprintf(stdout, (LPSTR) args[0], (va_list) &args[1]);
152 /*********************************************************************
153 * sprintf (CRTDLL.458)
155 int CRTDLL_sprintf(DWORD *args)
157 /* CMF - This makes a BIG assumption about va_list */
158 return vsprintf((LPSTR) args[0], (LPSTR) args[1], (va_list) &args[2]);
161 /*********************************************************************
162 * time (CRTDLL.488)
164 time_t CRTDLL_time(time_t *timeptr)
166 time_t curtime = time(NULL);
168 if (timeptr)
169 *timeptr = curtime;
170 return curtime;
173 /*********************************************************************
174 * _isatty (CRTDLL.137)
176 BOOL32 CRTDLL__isatty(DWORD x)
178 dprintf_crtdll(stderr,"CRTDLL__isatty(%ld)\n",x);
179 return TRUE;
182 /*********************************************************************
183 * _write (CRTDLL.332)
185 INT32 CRTDLL__write(DWORD x,LPVOID buf,DWORD len)
187 if (x<=2)
188 return write(x,buf,len);
189 /* hmm ... */
190 dprintf_crtdll(stderr,"CRTDLL__write(%ld,%p,%ld)\n",x,buf,len);
191 return len;
195 /*********************************************************************
196 * exit (CRTDLL.359)
198 void CRTDLL_exit(DWORD ret)
200 dprintf_crtdll(stderr,"CRTDLL_exit(%ld)\n",ret);
201 ExitProcess(ret);
205 /*********************************************************************
206 * fflush (CRTDLL.365)
208 void CRTDLL_fflush(DWORD x)
210 dprintf_crtdll(stderr,"CRTDLL_fflush(%ld)\n",x);
214 /*********************************************************************
215 * gets (CRTDLL.391)
217 LPSTR CRTDLL_gets(LPSTR buf)
219 /* BAD, for the whole WINE process blocks... just done this way to test
220 * windows95's ftp.exe.
222 return gets(buf);
226 /*********************************************************************
227 * abs (CRTDLL.339)
229 INT32 CRTDLL_abs(INT32 x)
231 return abs(x);
235 /*********************************************************************
236 * acos (CRTDLL.340)
238 float CRTDLL_acos(float x)
240 return acos(x);
244 /*********************************************************************
245 * asin (CRTDLL.342)
247 float CRTDLL_asin(float x)
249 return asin(x);
253 /*********************************************************************
254 * atan (CRTDLL.343)
256 float CRTDLL_atan(float x)
258 return atan(x);
262 /*********************************************************************
263 * atan2 (CRTDLL.344)
265 float CRTDLL_atan2(float x, float y)
267 return atan2(x,y);
271 /*********************************************************************
272 * atof (CRTDLL.346)
274 float CRTDLL_atof(LPCSTR x)
276 return atof(x);
280 /*********************************************************************
281 * atoi (CRTDLL.347)
283 INT32 CRTDLL_atoi(LPCSTR x)
285 return atoi(x);
289 /*********************************************************************
290 * atol (CRTDLL.348)
292 LONG CRTDLL_atol(LPCSTR x)
294 return atol(x);
298 /*********************************************************************
299 * cos (CRTDLL.354)
301 float CRTDLL_cos(float x)
303 return cos(x);
307 /*********************************************************************
308 * cosh (CRTDLL.355)
310 float CRTDLL_cosh(float x)
312 return cosh(x);
316 /*********************************************************************
317 * exp (CRTDLL.360)
319 float CRTDLL_exp(float x)
321 return exp(x);
325 /*********************************************************************
326 * fabs (CRTDLL.361)
328 float CRTDLL_fabs(float x)
330 return fabs(x);
334 /*********************************************************************
335 * isalnum (CRTDLL.394)
337 CHAR CRTDLL_isalnum(CHAR x)
339 return isalnum(x);
343 /*********************************************************************
344 * isalpha (CRTDLL.395)
346 CHAR CRTDLL_isalpha(CHAR x)
348 return isalpha(x);
352 /*********************************************************************
353 * iscntrl (CRTDLL.396)
355 CHAR CRTDLL_iscntrl(CHAR x)
357 return iscntrl(x);
361 /*********************************************************************
362 * isdigit (CRTDLL.397)
364 CHAR CRTDLL_isdigit(CHAR x)
366 return isdigit(x);
370 /*********************************************************************
371 * isgraph (CRTDLL.398)
373 CHAR CRTDLL_isgraph(CHAR x)
375 return isgraph(x);
379 /*********************************************************************
380 * islower (CRTDLL.400)
382 CHAR CRTDLL_islower(CHAR x)
384 return islower(x);
388 /*********************************************************************
389 * isprint (CRTDLL.401)
391 CHAR CRTDLL_isprint(CHAR x)
393 return isprint(x);
397 /*********************************************************************
398 * ispunct (CRTDLL.402)
400 CHAR CRTDLL_ispunct(CHAR x)
402 return ispunct(x);
406 /*********************************************************************
407 * isspace (CRTDLL.403)
409 CHAR CRTDLL_isspace(CHAR x)
411 return isspace(x);
415 /*********************************************************************
416 * isupper (CRTDLL.404)
418 CHAR CRTDLL_isupper(CHAR x)
420 return isupper(x);
424 /*********************************************************************
425 * isxdigit (CRTDLL.418)
427 CHAR CRTDLL_isxdigit(CHAR x)
429 return isxdigit(x);
433 /*********************************************************************
434 * labs (CRTDLL.419)
436 LONG CRTDLL_labs(LONG x)
438 return labs(x);
442 /*********************************************************************
443 * log (CRTDLL.424)
445 float CRTDLL_log(float x)
447 return log(x);
451 /*********************************************************************
452 * log10 (CRTDLL.425)
454 float CRTDLL_log10(float x)
456 return log10(x);
460 /*********************************************************************
461 * pow (CRTDLL.439)
463 float CRTDLL_pow(float x, float y)
465 return pow(x,y);
469 /*********************************************************************
470 * rand (CRTDLL.446)
472 INT32 CRTDLL_rand()
474 return rand();
478 /*********************************************************************
479 * sin (CRTDLL.456)
481 float CRTDLL_sin(float x)
483 return sin(x);
487 /*********************************************************************
488 * sinh (CRTDLL.457)
490 float CRTDLL_sinh(float x)
492 return sinh(x);
496 /*********************************************************************
497 * sqrt (CRTDLL.459)
499 float CRTDLL_sqrt(float x)
501 return sqrt(x);
505 /*********************************************************************
506 * tan (CRTDLL.486)
508 float CRTDLL_tan(float x)
510 return tan(x);
514 /*********************************************************************
515 * tanh (CRTDLL.487)
517 float CRTDLL_tanh(float x)
519 return tanh(x);
523 /*********************************************************************
524 * tolower (CRTDLL.491)
526 CHAR CRTDLL_tolower(CHAR x)
528 return tolower(x);
532 /*********************************************************************
533 * toupper (CRTDLL.492)
535 CHAR CRTDLL_toupper(CHAR x)
537 return toupper(x);
541 /*********************************************************************
542 * putchar (CRTDLL.442)
544 void CRTDLL_putchar(INT32 x)
546 putchar(x);
550 /*********************************************************************
551 * _mbsicmp (CRTDLL.204)
553 int CRTDLL__mbsicmp(unsigned char *x,unsigned char *y)
555 do {
556 if (!*x)
557 return !!*y;
558 if (!*y)
559 return !!*x;
560 /* FIXME: MBCS handling... */
561 if (*x!=*y)
562 return 1;
563 x++;
564 y++;
565 } while (1);
569 /*********************************************************************
570 * _mbsinc (CRTDLL.205)
572 unsigned char* CRTDLL__mbsinc(unsigned char *x)
574 /* FIXME: mbcs */
575 return x++;
579 /*********************************************************************
580 * vsprintf (CRTDLL.500)
582 int CRTDLL_vsprintf(DWORD *args)
584 /* CMF - This makes a BIG assumption about va_list */
585 return vsprintf((char *) args[0], (char *) args[1], (va_list) &args[2]);
588 /*********************************************************************
589 * vsprintf (CRTDLL.500) (NTDLL.913)
591 int CRTDLL_sscanf(DWORD *args)
593 /* CMF - This makes a BIG assumption about va_list */
594 return vsscanf((char *) args[0], (char *) args[1], (va_list) &args[2]);
598 /*********************************************************************
599 * _mbscpy (CRTDLL.200)
601 unsigned char* CRTDLL__mbscpy(unsigned char *x,unsigned char *y)
603 return strcpy(x,y);
607 /*********************************************************************
608 * _mbscat (CRTDLL.197)
610 unsigned char* CRTDLL__mbscat(unsigned char *x,unsigned char *y)
612 return strcat(x,y);
615 /*********************************************************************
616 * _strupr (CRTDLL.300)
618 LPSTR CRTDLL__strupr(LPSTR x)
620 LPSTR y=x;
622 while (*y) {
623 *y=toupper(*y);
624 y++;
626 return x;
629 /*********************************************************************
630 * _wcsupr (CRTDLL.328)
632 LPWSTR CRTDLL__wcsupr(LPWSTR x)
634 LPWSTR y=x;
636 while (*y) {
637 *y=toupper(*y);
638 y++;
640 return x;
643 /*********************************************************************
644 * _wcslwr (CRTDLL.323)
646 LPWSTR CRTDLL__wcslwr(LPWSTR x)
648 LPWSTR y=x;
650 while (*y) {
651 *y=tolower(*y);
652 y++;
654 return x;
658 /*********************************************************************
659 * malloc (CRTDLL.427)
661 VOID* CRTDLL_malloc(DWORD size)
663 return HeapAlloc(GetProcessHeap(),0,size);
666 /*********************************************************************
667 * new (CRTDLL.001)
669 VOID* CRTDLL_new(DWORD size)
671 VOID* result;
672 if(!(result = HeapAlloc(GetProcessHeap(),0,size)) && new_handler)
673 (*new_handler)();
674 return result;
677 /*********************************************************************
678 * set_new_handler(CRTDLL.003)
680 new_handler_type CRTDLL_set_new_handler(new_handler_type func)
682 new_handler_type old_handler = new_handler;
683 new_handler = func;
684 return old_handler;
687 /*********************************************************************
688 * calloc (CRTDLL.350)
690 VOID* CRTDLL_calloc(DWORD size, DWORD count)
692 return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size * count );
695 /*********************************************************************
696 * realloc (CRTDLL.447)
698 VOID* CRTDLL_realloc( VOID *ptr, DWORD size )
700 return HeapReAlloc( GetProcessHeap(), 0, ptr, size );
703 /*********************************************************************
704 * free (CRTDLL.427)
706 VOID CRTDLL_free(LPVOID ptr)
708 HeapFree(GetProcessHeap(),0,ptr);
711 /*********************************************************************
712 * delete (CRTDLL.002)
714 VOID CRTDLL_delete(VOID* ptr)
716 HeapFree(GetProcessHeap(),0,ptr);
719 /*********************************************************************
720 * _strdup (CRTDLL.285)
722 LPSTR CRTDLL__strdup(LPSTR ptr)
724 return HEAP_strdupA(GetProcessHeap(),0,ptr);
727 /*********************************************************************
728 * fclose (CRTDLL.362)
730 DWORD CRTDLL_fclose(LPVOID x)
732 dprintf_crtdll(stdnimp,"fclose(%p)\n",x);
733 return 0;
736 /*********************************************************************
737 * setlocale (CRTDLL.453)
739 LPSTR CRTDLL_setlocale(INT32 category,LPCSTR locale)
741 LPSTR categorystr;
743 switch (category) {
744 case CRTDLL_LC_ALL: categorystr="LC_ALL";break;
745 case CRTDLL_LC_COLLATE: categorystr="LC_COLLATE";break;
746 case CRTDLL_LC_CTYPE: categorystr="LC_CTYPE";break;
747 case CRTDLL_LC_MONETARY: categorystr="LC_MONETARY";break;
748 case CRTDLL_LC_NUMERIC: categorystr="LC_NUMERIC";break;
749 case CRTDLL_LC_TIME: categorystr="LC_TIME";break;
750 default: categorystr = "UNKNOWN?";break;
752 fprintf(stderr,"CRTDLL.setlocale(%s,%s),stub!\n",categorystr,locale);
753 return "C";
756 /*********************************************************************
757 * wcsspn (CRTDLL.516)
759 INT32 CRTDLL_wcsspn(LPWSTR str,LPWSTR accept)
761 LPWSTR s,t;
763 s=str;
764 do {
765 t=accept;
766 while (*t) { if (*t==*s) break;t++;}
767 if (!*t) break;
768 s++;
769 } while (*s);
770 return s-str; /* nr of wchars */
773 /*********************************************************************
774 * wcscspn (CRTDLL.508)
776 INT32 CRTDLL_wcscspn(LPWSTR str,LPWSTR reject)
778 LPWSTR s,t;
780 s=str;
781 do {
782 t=reject;
783 while (*t) { if (*t==*s) break;t++;}
784 if (*t) break;
785 s++;
786 } while (*s);
787 return s-str; /* nr of wchars */
790 /*********************************************************************
791 * wcschr (CRTDLL.504)
793 LPWSTR CRTDLL_wcschr(LPWSTR str,WCHAR xchar)
795 LPWSTR s;
797 s=str;
798 do {
799 if (*s==xchar)
800 return s;
801 } while (*s++);
802 return NULL;
805 /*********************************************************************
806 * towupper (CRTDLL.494)
808 WCHAR CRTDLL_towupper(WCHAR x)
810 return (WCHAR)toupper((CHAR)x);
813 /*********************************************************************
814 * swprintf (CRTDLL.483)
816 DWORD CRTDLL_swprintf(DWORD *args)
818 return WIN32_wsprintf32W(args);
821 /*********************************************************************
822 * _wcsicoll (CRTDLL.322)
824 DWORD CRTDLL__wcsicoll(LPWSTR a1,LPWSTR a2)
826 /* FIXME: handle collates */
827 return lstrcmpi32W(a1,a2);
830 /*********************************************************************
831 * wcscoll (CRTDLL.506)
833 DWORD CRTDLL_wcscoll(LPWSTR a1,LPWSTR a2)
835 /* FIXME: handle collates */
836 return lstrcmp32W(a1,a2);
839 /*********************************************************************
840 * _wcsrev (CRTDLL.326)
842 VOID CRTDLL__wcsrev(LPWSTR s) {
843 LPWSTR e;
845 e=s;
846 while (*e)
847 e++;
848 while (s<e) {
849 WCHAR a;
851 a=*s;*s=*e;*e=a;
852 s++;e--;
856 /*********************************************************************
857 * wcsstr (CRTDLL.517)
859 LPWSTR CRTDLL_wcsstr(LPWSTR s,LPWSTR b)
861 LPWSTR x,y,c;
863 x=s;
864 while (*x) {
865 if (*x==*b) {
866 y=x;c=b;
867 while (*y && *c && *y==*c) { c++;y++; }
868 if (!*c)
869 return x;
871 x++;
873 return NULL;
876 /*********************************************************************
877 * wcsrchr (CRTDLL.515)
879 LPWSTR CRTDLL_wcsrchr(LPWSTR str,WCHAR xchar)
881 LPWSTR s;
883 s=str+lstrlen32W(str);
884 do {
885 if (*s==xchar)
886 return s;
887 s--;
888 } while (s>=str);
889 return NULL;
892 /*********************************************************************
893 * _setmode (CRTDLL.265)
894 * FIXME: dunno what this is.
896 DWORD
897 CRTDLL__setmode(LPVOID x,INT32 y) {
898 /* FIXME */
899 fprintf(stdnimp,"CRTDLL._setmode(%p,%d), STUB.\n",x,y);
900 return 0;
903 /*********************************************************************
904 * atexit (CRTDLL.345)
906 INT32
907 CRTDLL_atexit(LPVOID x) {
908 /* FIXME */
909 fprintf(stdnimp,"CRTDLL.atexit(%p), STUB.\n",x);
910 return 0; /* successful */
913 /*********************************************************************
914 * mbtowc (CRTDLL.430)
915 * FIXME: check multibyte support
917 WCHAR
918 CRTDLL_mbtowc(CHAR a) {
919 return a;
922 /*********************************************************************
923 * _isctype (CRTDLL.138)
925 BOOL32
926 CRTDLL__isctype(CHAR x,CHAR type) {
927 if ((type & CRTDLL_SPACE) && isspace(x))
928 return TRUE;
929 if ((type & CRTDLL_PUNCT) && ispunct(x))
930 return TRUE;
931 if ((type & CRTDLL_LOWER) && islower(x))
932 return TRUE;
933 if ((type & CRTDLL_UPPER) && isupper(x))
934 return TRUE;
935 if ((type & CRTDLL_ALPHA) && isalpha(x))
936 return TRUE;
937 if ((type & CRTDLL_DIGIT) && isdigit(x))
938 return TRUE;
939 if ((type & CRTDLL_CONTROL) && iscntrl(x))
940 return TRUE;
941 /* check CRTDLL_LEADBYTE */
942 return FALSE;
945 /*********************************************************************
946 * _chdrive (CRTDLL.52)
948 BOOL32
949 CRTDLL__chdrive(INT32 newdrive) {
950 /* FIXME: generates errnos */
951 return DRIVE_SetCurrentDrive(newdrive);
954 /*********************************************************************
955 * _chdir (CRTDLL.51)
957 INT32
958 CRTDLL__chdir(LPCSTR newdir) {
959 if (!SetCurrentDirectory32A(newdir))
960 return -1;
961 return 0;
964 /*********************************************************************
965 * _mkdir (CRTDLL.234)
967 INT32
968 CRTDLL__mkdir(LPCSTR newdir) {
969 if (!CreateDirectory32A(newdir,NULL))
970 return -1;
971 return 0;
974 /*********************************************************************
975 * _errno (CRTDLL.52)
976 * Yes, this is a function.
978 LPINT32
979 CRTDLL__errno() {
980 static int crtdllerrno;
981 extern int LastErrorToErrno(DWORD);
983 /* FIXME: we should set the error at the failing function call time */
984 crtdllerrno = LastErrorToErrno(GetLastError());
985 return &crtdllerrno;