Release 970120
[wine] / misc / crtdll.c
1 /*
2  * The C RunTime DLL
3  * 
4  * Implements C run-time functionality as known from UNIX.
5  *
6  * Copyright 1996 Marcus Meissner
7  * Copyright 1996 Jukka Iivonen
8  */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <unistd.h>
14 #include <time.h>
15 #include <ctype.h>
16 #include <math.h>
17 #include "win.h"
18 #include "windows.h"
19 #include "stddebug.h"
20 #include "debug.h"
21 #include "module.h"
22 #include "xmalloc.h"
23 #include "heap.h"
24 #include "crtdll.h"
25
26 UINT32 CRTDLL_argc_dll;         /* CRTDLL.23 */
27 LPSTR *CRTDLL_argv_dll;         /* CRTDLL.24 */
28 LPSTR  CRTDLL_acmdln_dll;       /* CRTDLL.38 */
29 UINT32 CRTDLL_basemajor_dll;    /* CRTDLL.42 */
30 UINT32 CRTDLL_baseminor_dll;    /* CRTDLL.43 */
31 UINT32 CRTDLL_baseversion_dll;  /* CRTDLL.44 */
32 LPSTR  CRTDLL_environ_dll;      /* CRTDLL.75 */
33 UINT32 CRTDLL_osmajor_dll;      /* CRTDLL.241 */
34 UINT32 CRTDLL_osminor_dll;      /* CRTDLL.242 */
35 UINT32 CRTDLL_osver_dll;        /* CRTDLL.244 */
36 UINT32 CRTDLL_osversion_dll;    /* CRTDLL.245 */
37 UINT32 CRTDLL_winmajor_dll;     /* CRTDLL.329 */
38 UINT32 CRTDLL_winminor_dll;     /* CRTDLL.330 */
39 UINT32 CRTDLL_winver_dll;       /* CRTDLL.331 */
40
41 typedef VOID (*new_handler_type)(VOID);
42
43 static new_handler_type new_handler;
44
45 /*********************************************************************
46  *                  _GetMainArgs  (CRTDLL.022)
47  */
48 DWORD
49 CRTDLL__GetMainArgs(LPDWORD argc,LPSTR **argv,LPSTR *environ,DWORD flag)
50 {
51         char *cmdline;
52         char  **xargv;
53         int     xargc,i,afterlastspace;
54         DWORD   version;
55
56         dprintf_crtdll(stderr,"__GetMainArgs(%p,%p,%p,%ld).\n",
57                 argc,argv,environ,flag
58         );
59         CRTDLL_acmdln_dll = cmdline = xstrdup( GetCommandLine32A() );
60
61         version = GetVersion32();
62         CRTDLL_osver_dll       = version >> 16;
63         CRTDLL_winminor_dll    = version & 0xFF;
64         CRTDLL_winmajor_dll    = (version>>8) & 0xFF;
65         CRTDLL_baseversion_dll = version >> 16;
66         CRTDLL_winver_dll      = ((version >> 8) & 0xFF) + ((version & 0xFF) << 8);
67         CRTDLL_baseminor_dll   = (version >> 16) & 0xFF;
68         CRTDLL_basemajor_dll   = (version >> 24) & 0xFF;
69         CRTDLL_osversion_dll   = version & 0xFFFF;
70         CRTDLL_osminor_dll     = version & 0xFF;
71         CRTDLL_osmajor_dll     = (version>>8) & 0xFF;
72
73         /* missing threading init */
74
75         i=0;xargv=NULL;xargc=0;afterlastspace=0;
76         while (cmdline[i]) {
77                 if (cmdline[i]==' ') {
78                         xargv=(char**)xrealloc(xargv,sizeof(char*)*(++xargc));
79                         cmdline[i]='\0';
80                         xargv[xargc-1] = xstrdup(cmdline+afterlastspace);
81                         i++;
82                         while (cmdline[i]==' ')
83                                 i++;
84                         if (cmdline[i])
85                                 afterlastspace=i;
86                 } else
87                         i++;
88         }
89         xargv=(char**)xrealloc(xargv,sizeof(char*)*(++xargc));
90         cmdline[i]='\0';
91         xargv[xargc-1] = xstrdup(cmdline+afterlastspace);
92         CRTDLL_argc_dll = xargc;
93         *argc           = xargc;
94         CRTDLL_argv_dll = xargv;
95         *argv           = xargv;
96
97         /* FIXME ... use real environment */
98         *environ        = xmalloc(sizeof(LPSTR));
99         CRTDLL_environ_dll = *environ;
100         (*environ)[0] = NULL;
101         return 0;
102 }
103
104 typedef void (*_INITTERMFUN)();
105
106 /*********************************************************************
107  *                  _initterm     (CRTDLL.135)
108  */
109 DWORD CRTDLL__initterm(_INITTERMFUN *start,_INITTERMFUN *end)
110 {
111         _INITTERMFUN    *current;
112
113         dprintf_crtdll(stddeb,"_initterm(%p,%p)\n",start,end);
114         current=start;
115         while (current<end) {
116                 if (*current) (*current)();
117                 current++;
118         }
119         return 0;
120 }
121
122 /*********************************************************************
123  *                  srand         (CRTDLL.460)
124  */
125 void CRTDLL_srand(DWORD seed)
126 {
127         /* FIXME: should of course be thread? process? local */
128         srand(seed);
129 }
130
131 /*********************************************************************
132  *                  fprintf       (CRTDLL.373)
133  */
134 int CRTDLL_fprintf(DWORD *args)
135 {
136         /* FIXME: use args[0] */
137         return vfprintf(stderr,(LPSTR)(args[1]),args+2);
138 }
139
140 /*********************************************************************
141  *                  printf        (CRTDLL.440)
142  */
143 int CRTDLL_printf(DWORD *args)
144 {
145         return vfprintf(stdout,(LPSTR)(args[0]),args+1);
146 }
147
148 /*********************************************************************
149  *                  sprintf        (CRTDLL.458)
150  */
151 int CRTDLL_sprintf(DWORD *args)
152 {
153         return vsprintf((LPSTR)(args[0]),(LPSTR)(args[1]),args+2);
154 }
155
156 /*********************************************************************
157  *                  time          (CRTDLL.488)
158  */
159 time_t CRTDLL_time(time_t *timeptr)
160 {
161         time_t  curtime = time(NULL);
162
163         if (timeptr)
164                 *timeptr = curtime;
165         return curtime;
166 }
167
168 /*********************************************************************
169  *                  _isatty       (CRTDLL.137)
170  */
171 BOOL32 CRTDLL__isatty(DWORD x)
172 {
173         dprintf_crtdll(stderr,"CRTDLL__isatty(%ld)\n",x);
174         return TRUE;
175 }
176
177 /*********************************************************************
178  *                  _write        (CRTDLL.332)
179  */
180 INT32 CRTDLL__write(DWORD x,LPVOID buf,DWORD len)
181 {
182         if (x<=2)
183                 return write(x,buf,len);
184         /* hmm ... */
185         dprintf_crtdll(stderr,"CRTDLL__write(%ld,%p,%ld)\n",x,buf,len);
186         return len;
187 }
188
189
190 /*********************************************************************
191  *                  exit          (CRTDLL.359)
192  */
193 void CRTDLL_exit(DWORD ret)
194 {
195         dprintf_crtdll(stderr,"CRTDLL_exit(%ld)\n",ret);
196         ExitProcess(ret);
197 }
198
199
200 /*********************************************************************
201  *                  fflush        (CRTDLL.365)
202  */
203 void CRTDLL_fflush(DWORD x)
204 {
205     dprintf_crtdll(stderr,"CRTDLL_fflush(%ld)\n",x);
206 }
207
208
209 /*********************************************************************
210  *                  gets          (CRTDLL.391)
211  */
212 LPSTR CRTDLL_gets(LPSTR buf)
213 {
214   /* BAD, for the whole WINE process blocks... just done this way to test
215    * windows95's ftp.exe.
216    */
217     return gets(buf);
218 }
219
220
221 /*********************************************************************
222  *                  abs           (CRTDLL.339)
223  */
224 INT32 CRTDLL_abs(INT32 x)
225 {
226     return abs(x);
227 }
228
229
230 /*********************************************************************
231  *                  acos          (CRTDLL.340)
232  */
233 float CRTDLL_acos(float x)
234 {
235     return acos(x);
236 }
237
238
239 /*********************************************************************
240  *                  asin          (CRTDLL.342)
241  */
242 float CRTDLL_asin(float x)
243 {
244     return asin(x);
245 }
246
247
248 /*********************************************************************
249  *                  atan          (CRTDLL.343)
250  */
251 float CRTDLL_atan(float x)
252 {
253     return atan(x);
254 }
255
256
257 /*********************************************************************
258  *                  atan2         (CRTDLL.344)
259  */
260 float CRTDLL_atan2(float x, float y)
261 {
262     return atan2(x,y);
263 }
264
265
266 /*********************************************************************
267  *                  atof          (CRTDLL.346)
268  */
269 float CRTDLL_atof(LPCSTR x)
270 {
271     return atof(x);
272 }
273
274
275 /*********************************************************************
276  *                  atoi          (CRTDLL.347)
277  */
278 INT32 CRTDLL_atoi(LPCSTR x)
279 {
280     return atoi(x);
281 }
282
283
284 /*********************************************************************
285  *                  atol          (CRTDLL.348)
286  */
287 LONG CRTDLL_atol(LPCSTR x)
288 {
289     return atol(x);
290 }
291
292
293 /*********************************************************************
294  *                  cos           (CRTDLL.354)
295  */
296 float CRTDLL_cos(float x)
297 {
298     return cos(x);
299 }
300
301
302 /*********************************************************************
303  *                  cosh          (CRTDLL.355)
304  */
305 float CRTDLL_cosh(float x)
306 {
307     return cosh(x);
308 }
309
310
311 /*********************************************************************
312  *                  exp           (CRTDLL.360)
313  */
314 float CRTDLL_exp(float x)
315 {
316     return exp(x);
317 }
318
319
320 /*********************************************************************
321  *                  fabs          (CRTDLL.361)
322  */
323 float CRTDLL_fabs(float x)
324 {
325     return fabs(x);
326 }
327
328
329 /*********************************************************************
330  *                  isalnum       (CRTDLL.394)
331  */
332 CHAR CRTDLL_isalnum(CHAR x)
333 {
334     return isalnum(x);
335 }
336
337
338 /*********************************************************************
339  *                  isalpha       (CRTDLL.395)
340  */
341 CHAR CRTDLL_isalpha(CHAR x)
342 {
343     return isalpha(x);
344 }
345
346
347 /*********************************************************************
348  *                  iscntrl       (CRTDLL.396)
349  */
350 CHAR CRTDLL_iscntrl(CHAR x)
351 {
352     return iscntrl(x);
353 }
354
355
356 /*********************************************************************
357  *                  isdigit       (CRTDLL.397)
358  */
359 CHAR CRTDLL_isdigit(CHAR x)
360 {
361     return isdigit(x);
362 }
363
364
365 /*********************************************************************
366  *                  isgraph       (CRTDLL.398)
367  */
368 CHAR CRTDLL_isgraph(CHAR x)
369 {
370     return isgraph(x);
371 }
372
373
374 /*********************************************************************
375  *                  islower       (CRTDLL.400)
376  */
377 CHAR CRTDLL_islower(CHAR x)
378 {
379     return islower(x);
380 }
381
382
383 /*********************************************************************
384  *                  isprint       (CRTDLL.401)
385  */
386 CHAR CRTDLL_isprint(CHAR x)
387 {
388     return isprint(x);
389 }
390
391
392 /*********************************************************************
393  *                  ispunct       (CRTDLL.402)
394  */
395 CHAR CRTDLL_ispunct(CHAR x)
396 {
397     return ispunct(x);
398 }
399
400
401 /*********************************************************************
402  *                  isspace       (CRTDLL.403)
403  */
404 CHAR CRTDLL_isspace(CHAR x)
405 {
406     return isspace(x);
407 }
408
409
410 /*********************************************************************
411  *                  isupper       (CRTDLL.404)
412  */
413 CHAR CRTDLL_isupper(CHAR x)
414 {
415     return isupper(x);
416 }
417
418
419 /*********************************************************************
420  *                  isxdigit      (CRTDLL.418)
421  */
422 CHAR CRTDLL_isxdigit(CHAR x)
423 {
424     return isxdigit(x);
425 }
426
427
428 /*********************************************************************
429  *                  labs          (CRTDLL.419)
430  */
431 LONG CRTDLL_labs(LONG x)
432 {
433     return labs(x);
434 }
435
436
437 /*********************************************************************
438  *                  log           (CRTDLL.424)
439  */
440 float CRTDLL_log(float x)
441 {
442     return log(x);
443 }
444
445
446 /*********************************************************************
447  *                  log10         (CRTDLL.425)
448  */
449 float CRTDLL_log10(float x)
450 {
451     return log10(x);
452 }
453
454
455 /*********************************************************************
456  *                  pow           (CRTDLL.439)
457  */
458 float CRTDLL_pow(float x, float y)
459 {
460     return pow(x,y);
461 }
462
463
464 /*********************************************************************
465  *                  rand          (CRTDLL.446)
466  */
467 INT32 CRTDLL_rand()
468 {
469     return rand();
470 }
471
472
473 /*********************************************************************
474  *                  sin           (CRTDLL.456)
475  */
476 float CRTDLL_sin(float x)
477 {
478     return sin(x);
479 }
480
481
482 /*********************************************************************
483  *                  sinh          (CRTDLL.457)
484  */
485 float CRTDLL_sinh(float x)
486 {
487     return sinh(x);
488 }
489
490
491 /*********************************************************************
492  *                  sqrt          (CRTDLL.459)
493  */
494 float CRTDLL_sqrt(float x)
495 {
496     return sqrt(x);
497 }
498
499
500 /*********************************************************************
501  *                  tan           (CRTDLL.486)
502  */
503 float CRTDLL_tan(float x)
504 {
505     return tan(x);
506 }
507
508
509 /*********************************************************************
510  *                  tanh          (CRTDLL.487)
511  */
512 float CRTDLL_tanh(float x)
513 {
514     return tanh(x);
515 }
516
517
518 /*********************************************************************
519  *                  tolower       (CRTDLL.491)
520  */
521 CHAR CRTDLL_tolower(CHAR x)
522 {
523     return tolower(x);
524 }
525
526
527 /*********************************************************************
528  *                  toupper       (CRTDLL.492)
529  */
530 CHAR CRTDLL_toupper(CHAR x)
531 {
532     return toupper(x);
533 }
534
535
536 /*********************************************************************
537  *                  putchar       (CRTDLL.442)
538  */
539 void CRTDLL_putchar(INT32 x)
540 {
541     putchar(x);
542 }
543
544
545 /*********************************************************************
546  *                  _mbsicmp      (CRTDLL.204)
547  */
548 int CRTDLL__mbsicmp(unsigned char *x,unsigned char *y)
549 {
550     do {
551         if (!*x)
552             return !!*y;
553         if (!*y)
554             return !!*x;
555         /* FIXME: MBCS handling... */
556         if (*x!=*y)
557             return 1;
558         x++;
559         y++;
560     } while (1);
561 }
562
563
564 /*********************************************************************
565  *                  _mbsinc       (CRTDLL.205)
566  */
567 unsigned char* CRTDLL__mbsinc(unsigned char *x)
568 {
569     /* FIXME: mbcs */
570     return x++;
571 }
572
573
574 /*********************************************************************
575  *                  vsprintf      (CRTDLL.500)
576  */
577 int CRTDLL_vsprintf(DWORD *args)
578 {
579     return vsprintf((char *)args[0],(char *)args[1],args+2);
580 }
581
582 /*********************************************************************
583  *                  vsprintf      (CRTDLL.500) (NTDLL.913)
584  */
585 int CRTDLL_sscanf(DWORD *args)
586 {
587     return vsscanf((char *)args[0],(char *)args[1],args+2);
588 }
589
590
591 /*********************************************************************
592  *                  _mbscpy       (CRTDLL.200)
593  */
594 unsigned char* CRTDLL__mbscpy(unsigned char *x,unsigned char *y)
595 {
596     return strcpy(x,y);
597 }
598
599
600 /*********************************************************************
601  *                  _mbscat       (CRTDLL.197)
602  */
603 unsigned char* CRTDLL__mbscat(unsigned char *x,unsigned char *y)
604 {
605     return strcat(x,y);
606 }
607
608 /*********************************************************************
609  *                  _strupr       (CRTDLL.300)
610  */
611 LPSTR CRTDLL__strupr(LPSTR x)
612 {
613         LPSTR   y=x;
614
615         while (*y) {
616                 *y=toupper(*y);
617                 y++;
618         }
619         return x;
620 }
621
622 /*********************************************************************
623  *                  _wcsupr       (CRTDLL.328)
624  */
625 LPWSTR CRTDLL__wcsupr(LPWSTR x)
626 {
627         LPWSTR  y=x;
628
629         while (*y) {
630                 *y=toupper(*y);
631                 y++;
632         }
633         return x;
634 }
635
636 /*********************************************************************
637  *                  _wcslwr       (CRTDLL.323)
638  */
639 LPWSTR CRTDLL__wcslwr(LPWSTR x)
640 {
641         LPWSTR  y=x;
642
643         while (*y) {
644                 *y=tolower(*y);
645                 y++;
646         }
647         return x;
648 }
649
650
651 /*********************************************************************
652  *                  malloc        (CRTDLL.427)
653  */
654 VOID* CRTDLL_malloc(DWORD size)
655 {
656     return HeapAlloc(GetProcessHeap(),0,size);
657 }
658
659 /*********************************************************************
660  *                  new           (CRTDLL.001)
661  */
662 VOID* CRTDLL_new(DWORD size)
663 {
664     VOID* result;
665     if(!(result = HeapAlloc(GetProcessHeap(),0,size)) && new_handler)
666         (*new_handler)();
667     return result;
668 }
669
670 /*********************************************************************
671  *                  set_new_handler(CRTDLL.003)
672  */
673 new_handler_type CRTDLL_set_new_handler(new_handler_type func)
674 {
675     new_handler_type old_handler = new_handler;
676     new_handler = func;
677     return old_handler;
678 }
679
680 /*********************************************************************
681  *                  calloc        (CRTDLL.350)
682  */
683 VOID* CRTDLL_calloc(DWORD size, DWORD count)
684 {
685     return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size * count );
686 }
687
688 /*********************************************************************
689  *                  realloc        (CRTDLL.447)
690  */
691 VOID* CRTDLL_realloc( VOID *ptr, DWORD size )
692 {
693     return HeapReAlloc( GetProcessHeap(), 0, ptr, size );
694 }
695
696 /*********************************************************************
697  *                  free          (CRTDLL.427)
698  */
699 VOID CRTDLL_free(LPVOID ptr)
700 {
701     HeapFree(GetProcessHeap(),0,ptr);
702 }
703
704 /*********************************************************************
705  *                  delete       (CRTDLL.002)
706  */
707 VOID CRTDLL_delete(VOID* ptr)
708 {
709     HeapFree(GetProcessHeap(),0,ptr);
710 }
711
712 /*********************************************************************
713  *                  _strdup          (CRTDLL.285)
714  */
715 LPSTR CRTDLL__strdup(LPSTR ptr)
716 {
717     return HEAP_strdupA(GetProcessHeap(),0,ptr);
718 }
719
720 /*********************************************************************
721  *                  fclose           (CRTDLL.362)
722  */
723 DWORD CRTDLL_fclose(LPVOID x)
724 {
725     dprintf_crtdll(stdnimp,"fclose(%p)\n",x);
726     return 0;
727 }
728
729 /*********************************************************************
730  *                  setlocale           (CRTDLL.453)
731  */
732 LPSTR CRTDLL_setlocale(INT32 category,LPCSTR locale)
733 {
734         LPSTR categorystr;
735
736         switch (category) {
737         case CRTDLL_LC_ALL: categorystr="LC_ALL";break;
738         case CRTDLL_LC_COLLATE: categorystr="LC_COLLATE";break;
739         case CRTDLL_LC_CTYPE: categorystr="LC_CTYPE";break;
740         case CRTDLL_LC_MONETARY: categorystr="LC_MONETARY";break;
741         case CRTDLL_LC_NUMERIC: categorystr="LC_NUMERIC";break;
742         case CRTDLL_LC_TIME: categorystr="LC_TIME";break;
743         default: categorystr = "UNKNOWN?";break;
744         }
745         fprintf(stderr,"CRTDLL.setlocale(%s,%s),stub!\n",categorystr,locale);
746         return "C";
747 }
748
749 /*********************************************************************
750  *                  wcsspn           (CRTDLL.516)
751  */
752 INT32 CRTDLL_wcsspn(LPWSTR str,LPWSTR accept)
753 {
754         LPWSTR  s,t;
755
756         s=str;
757         do {
758                 t=accept;
759                 while (*t) { if (*t==*s) break;t++;}
760                 if (!*t) break;
761                 s++;
762         } while (*s);
763         return s-str; /* nr of wchars */
764 }
765
766 /*********************************************************************
767  *                  wcschr           (CRTDLL.504)
768  */
769 LPWSTR CRTDLL_wcschr(LPWSTR str,WCHAR xchar)
770 {
771         LPWSTR  s;
772
773         s=str;
774         do {
775                 if (*s==xchar)
776                         return s;
777         } while (*s++);
778         return NULL;
779 }
780
781 /*********************************************************************
782  *                  towupper           (CRTDLL.494)
783  */
784 WCHAR CRTDLL_towupper(WCHAR x)
785 {
786     return (WCHAR)toupper((CHAR)x);
787 }
788
789 /*********************************************************************
790  *                  swprintf           (CRTDLL.483)
791  */
792 DWORD CRTDLL_swprintf(DWORD *args)
793 {
794     return WIN32_wsprintf32W(args);
795 }
796
797 /*********************************************************************
798  *                  _wcsicoll           (CRTDLL.322)
799  */
800 DWORD CRTDLL__wcsicoll(LPWSTR a1,LPWSTR a2)
801 {
802     /* FIXME: handle collates */
803     return lstrcmpi32W(a1,a2);
804 }
805
806 /*********************************************************************
807  *                  wcscoll           (CRTDLL.506)
808  */
809 DWORD CRTDLL_wcscoll(LPWSTR a1,LPWSTR a2)
810 {
811     /* FIXME: handle collates */
812     return lstrcmp32W(a1,a2);
813 }
814
815 /*********************************************************************
816  *                  wcsstr           (CRTDLL.517)
817  */
818 LPWSTR CRTDLL_wcsstr(LPWSTR s,LPWSTR b)
819 {
820         LPWSTR  x,y,c;
821
822         x=s;
823         while (*x) {
824                 if (*x==*b) {
825                         y=x;c=b;
826                         while (*y && *c && *y==*c) { c++;y++; }
827                         if (!*c)
828                                 return x;
829                 }
830                 x++;
831         }
832         return NULL;
833 }
834
835 /*********************************************************************
836  *                  wcsrchr           (CRTDLL.515)
837  */
838 LPWSTR CRTDLL_wcsrchr(LPWSTR str,WCHAR xchar)
839 {
840         LPWSTR  s;
841
842         s=str+lstrlen32W(str);
843         do {
844                 if (*s==xchar)
845                         return s;
846                 s--;
847         } while (s>=str);
848         return NULL;
849 }
850
851 /*********************************************************************
852  *                  _setmode           (CRTDLL.265)
853  * FIXME: dunno what this is.
854  */
855 DWORD
856 CRTDLL__setmode(LPVOID x,INT32 y) {
857         /* FIXME */
858         fprintf(stdnimp,"CRTDLL._setmode(%p,%d), STUB.\n",x,y);
859         return 0;
860 }
861
862 /*********************************************************************
863  *                  atexit           (CRTDLL.345)
864  */
865 INT32
866 CRTDLL_atexit(LPVOID x) {
867         /* FIXME */
868         fprintf(stdnimp,"CRTDLL.atexit(%p), STUB.\n",x);
869         return 0; /* successful */
870 }