Make GetTickCount not use the whole Unix epoch (since 1970) any more,
[wine] / misc / main.c
1 /*
2  * Main function.
3  *
4  * Copyright 1994 Alexandre Julliard
5  */
6
7 #include "config.h"
8
9 #include <locale.h>
10 #include <ctype.h>
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <unistd.h>
15 #ifdef MALLOC_DEBUGGING
16 # include <malloc.h>
17 #endif
18
19 #include "windef.h"
20 #include "winbase.h"
21 #include "ntddk.h"
22 #include "winnls.h"
23 #include "winerror.h"
24
25 #include "winsock.h"
26 #include "heap.h"
27 #include "msdos.h"
28 #include "options.h"
29 #include "debugtools.h"
30 #include "debugdefs.h"
31 #include "module.h"
32 #include "tweak.h"
33
34
35 /***********************************************************************
36  *          MAIN_ParseDebugOptions
37  *
38  *  Turns specific debug messages on or off, according to "options".
39  */
40 void MAIN_ParseDebugOptions( const char *arg )
41 {
42   /* defined in relay32/relay386.c */
43   extern char **debug_relay_includelist;
44   extern char **debug_relay_excludelist;
45   /* defined in relay32/snoop.c */
46   extern char **debug_snoop_includelist;
47   extern char **debug_snoop_excludelist;
48
49   int i;
50   int l, cls;
51
52   char *options = strdup(arg);
53
54   l = strlen(options);
55   if (l<2) goto error;
56
57   if (options[l-1]=='\n') options[l-1]='\0';
58   do
59   {
60     if ((*options!='+')&&(*options!='-')){
61       int j;
62
63       for(j=0; j<DEBUG_CLASS_COUNT; j++)
64         if(!lstrncmpiA(options, debug_cl_name[j], strlen(debug_cl_name[j])))
65           break;
66       if(j==DEBUG_CLASS_COUNT)
67         goto error;
68       options += strlen(debug_cl_name[j]);
69       if ((*options!='+')&&(*options!='-'))
70         goto error;
71       cls = j;
72     }
73     else
74       cls = -1; /* all classes */
75
76     if (strchr(options,','))
77       l=strchr(options,',')-options;
78     else
79       l=strlen(options);
80
81     if (!lstrncmpiA(options+1,"all",l-1))
82       {
83         int i, j;
84         for (i=0; i<DEBUG_CHANNEL_COUNT; i++)
85           for(j=0; j<DEBUG_CLASS_COUNT; j++)
86             if(cls == -1 || cls == j)
87                 __SET_DEBUGGING( j, debug_channels[i], (*options=='+') );
88       }
89     else if (!lstrncmpiA(options+1, "relay=", 6) ||
90              !lstrncmpiA(options+1, "snoop=", 6))
91       {
92         int i, j;
93         char *s, *s2, ***output, c;
94
95         for (i=0; i<DEBUG_CHANNEL_COUNT; i++)
96           if (!strncasecmp( debug_channels[i] + 1, options + 1, 5))
97           {
98             for(j=0; j<DEBUG_CLASS_COUNT; j++)
99               if(cls == -1 || cls == j)
100                   __SET_DEBUGGING( j, debug_channels[i], 1 );
101             break;
102           }
103         /* should never happen, maybe assert(i!=DEBUG_CHANNEL_COUNT)? */
104         if (i==DEBUG_CHANNEL_COUNT)
105           goto error;
106         output = (*options == '+') ?
107                         ((*(options+1) == 'r') ?
108                                 &debug_relay_includelist :
109                                 &debug_snoop_includelist) :
110                         ((*(options+1) == 'r') ?
111                                 &debug_relay_excludelist :
112                                 &debug_snoop_excludelist);
113         s = options + 7;
114         /* if there are n ':', there are n+1 modules, and we need n+2 slots
115          * last one being for the sentinel (NULL) */
116         i = 2;  
117         while((s = strchr(s, ':'))) i++, s++;
118         *output = malloc(sizeof(char **) * i);
119         i = 0;
120         s = options + 7;
121         while((s2 = strchr(s, ':'))) {
122           c = *s2;
123           *s2 = '\0';
124           *((*output)+i) = _strupr(strdup(s));
125           *s2 = c;
126           s = s2 + 1;
127           i++;
128         }
129         c = *(options + l);
130         *(options + l) = '\0';
131         *((*output)+i) = _strupr(strdup(s));
132         *(options + l) = c;
133         *((*output)+i+1) = NULL;
134       }
135     else
136       {
137         int i, j;
138         for (i=0; i<DEBUG_CHANNEL_COUNT; i++)
139           if (!strncasecmp( debug_channels[i] + 1, options + 1, l - 1) && !debug_channels[i][l])
140           {
141             for(j=0; j<DEBUG_CLASS_COUNT; j++)
142               if(cls == -1 || cls == j)
143                   __SET_DEBUGGING( j, debug_channels[i], (*options=='+') );
144             break;
145           }
146         if (i==DEBUG_CHANNEL_COUNT)
147           goto error;
148       }
149     options+=l;
150   }
151   while((*options==',')&&(*(++options)));
152
153   if (!*options) return;
154
155  error:  
156   MESSAGE("%s: Syntax: --debugmsg [class]+xxx,...  or "
157       "-debugmsg [class]-xxx,...\n",argv0);
158   MESSAGE("Example: --debugmsg +all,warn-heap\n"
159       "  turn on all messages except warning heap messages\n");
160   MESSAGE("Special case: --debugmsg +relay=DLL:DLL.###:FuncName\n"
161       "  turn on -debugmsg +relay only as specified\n"
162       "Special case: --debugmsg -relay=DLL:DLL.###:FuncName\n"
163       "  turn on --debugmsg +relay except as specified\n"
164       "Also permitted, +snoop=..., -snoop=... as with relay.\n\n");
165   
166   MESSAGE("Available message classes:\n");
167   for(i=0;i<DEBUG_CLASS_COUNT;i++)
168     MESSAGE( "%-9s", debug_cl_name[i]);
169   MESSAGE("\n\n");
170   
171   MESSAGE("Available message types:\n");
172   MESSAGE("%-9s ","all");
173   for(i=0;i<DEBUG_CHANNEL_COUNT;i++)
174       MESSAGE("%-9s%c",debug_channels[i] + 1,
175           (((i+2)%8==0)?'\n':' '));
176   MESSAGE("\n\n");
177   ExitProcess(1);
178 }
179
180 /***********************************************************************
181  *           MAIN_WineInit
182  *
183  * Wine initialisation
184  */
185 void MAIN_WineInit(void)
186 {
187 #ifdef MALLOC_DEBUGGING
188     char *trace;
189
190     mcheck(NULL);
191     if (!(trace = getenv("MALLOC_TRACE")))
192     {       
193         MESSAGE( "MALLOC_TRACE not set. No trace generated\n" );
194     }
195     else
196     {
197         MESSAGE( "malloc trace goes to %s\n", trace );
198         mtrace();
199     }
200 #endif
201
202     setbuf(stdout,NULL);
203     setbuf(stderr,NULL);
204     setlocale(LC_CTYPE,"");
205 }
206
207 /***********************************************************************
208  *           Beep   (KERNEL32.11)
209  */
210 BOOL WINAPI Beep( DWORD dwFreq, DWORD dwDur )
211 {
212     static char beep = '\a';
213     /* dwFreq and dwDur are ignored by Win95 */
214     if (isatty(2)) write( 2, &beep, 1 );
215     return TRUE;
216 }
217
218
219 /***********************************************************************
220 *       FileCDR (KERNEL.130)
221 */
222 FARPROC16 WINAPI FileCDR16(FARPROC16 x)
223 {
224         FIXME_(file)("(0x%8x): stub\n", (int) x);
225         return (FARPROC16)TRUE;
226 }
227
228 /***********************************************************************
229  *           GetTickCount   (USER.13) (KERNEL32.299)
230  *
231  * Returns the number of milliseconds, modulo 2^32, since the start
232  * of the wineserver.
233  */
234 DWORD WINAPI GetTickCount(void)
235 {
236     struct timeval t;
237     gettimeofday( &t, NULL );
238     return ((t.tv_sec * 1000) + (t.tv_usec / 1000)) - server_startticks;
239 }