compiler, ecere: Moved references to stdin/stdout to instance.c to work around issues...
[sdk] / ecere / src / com / instance.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdarg.h>
4 #include <ctype.h>
5 #include <string.h>
6
7 #if defined(__GNUC__) || defined(__WATCOMC__) || defined(__WIN32__)
8 #include <time.h>
9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #include <fcntl.h>
12 #endif
13
14 #if defined(__unix__) || defined(__APPLE__)
15 #define bool _bool
16 #include <utime.h>
17 #include <dlfcn.h>
18 #undef bool
19 #endif
20
21 #if defined(__WIN32__)
22 #define WIN32_LEAN_AND_MEAN
23 #define UNICODE
24 #include <windows.h>
25 #include <io.h>
26
27 #else
28 #include <unistd.h>
29 #endif
30
31 typedef int bool;
32 typedef unsigned char byte;
33 typedef unsigned short uint16;
34 typedef unsigned int uint;
35 typedef unsigned int FileSize;
36 typedef unsigned long long uint64;
37
38 #define false 0
39 #define true 1
40
41 #define null ((void *)0)
42
43 #define MAX_LOCATION 797
44 #define MAX_FILENAME 274
45 #define MAX_EXTENSION 17
46
47 FILE *eC_stdin(void)  { return stdin; }
48 FILE *eC_stdout(void) { return stdout; }
49 FILE *eC_stderr(void) { return stderr; }
50
51 void __ecereNameSpace__ecere__com__eSystem_Delete(void * memory);
52 void * __ecereNameSpace__ecere__com__eSystem_New0(unsigned int size);
53 void * __ecereNameSpace__ecere__com__eSystem_Renew(void * memory, unsigned int size);
54 void * __ecereNameSpace__ecere__com__eSystem_Renew0(void * memory, unsigned int size);
55 unsigned short * __ecereNameSpace__ecere__sys__UTF8toUTF16(char * source, int * wordCount);
56 unsigned short * __ecereNameSpace__ecere__sys__UTF8toUTF16Buffer(char * source, uint16 * dest, int max);
57 char * __ecereNameSpace__ecere__sys__UTF16toUTF8(uint16 * source);
58 char * __ecereNameSpace__ecere__sys__UTF16toUTF8Buffer(uint16 * source, byte * dest, int max);
59
60 #define eSystem_Delete     __ecereNameSpace__ecere__com__eSystem_Delete
61 #define eSystem_New0       __ecereNameSpace__ecere__com__eSystem_New0
62 #define eSystem_Renew      __ecereNameSpace__ecere__com__eSystem_Renew
63 #define eSystem_Renew0     __ecereNameSpace__ecere__com__eSystem_Renew0
64 #define UTF8toUTF16        __ecereNameSpace__ecere__sys__UTF8toUTF16
65 #define UTF8toUTF16Buffer  __ecereNameSpace__ecere__sys__UTF8toUTF16Buffer
66 #define UTF16toUTF8        __ecereNameSpace__ecere__sys__UTF16toUTF8
67 #define UTF16toUTF8Buffer  __ecereNameSpace__ecere__sys__UTF16toUTF8Buffer
68
69 #if defined(__unix__)
70 static char exeLocation[MAX_LOCATION];
71 #endif
72
73 int __ecereNameSpace__ecere__sys__Tokenize(char * string, int maxTokens, char* tokens[], bool escapeBackSlashes);
74 char * __ecereNameSpace__ecere__sys__RSearchString(char * buffer, char * subStr, int maxLen, bool matchCase, bool matchWord);
75 char * __ecereNameSpace__ecere__sys__GetLastDirectory(char * string, char * output);
76 char * __ecereNameSpace__ecere__sys__PathCat(char * string, char * addedPath);
77 char * __ecereNameSpace__ecere__sys__GetExtension(char * string, char * output);
78
79 #define Tokenize           __ecereNameSpace__ecere__sys__Tokenize
80 #define RSearchString      __ecereNameSpace__ecere__sys__RSearchString
81 #define GetLastDirectory   __ecereNameSpace__ecere__sys__GetLastDirectory
82 #define PathCat            __ecereNameSpace__ecere__sys__PathCat
83 #define GetExtension       __ecereNameSpace__ecere__sys__GetExtension
84
85 extern struct __ecereNameSpace__ecere__com__Instance * __thisModule;
86
87 typedef enum { unknown, win32, tux, apple } Platform;
88
89 #if defined(__WIN32__)
90 Platform runtimePlatform = win32;
91 #elif defined(__APPLE__)
92 Platform runtimePlatform = apple;
93 #elif defined(__linux__)
94 Platform runtimePlatform = tux;
95 #else
96 Platform runtimePlatform = unknown;
97 #endif
98
99 bool Instance_LocateModule(char * name, char * fileName)
100 {
101 #if defined(__WIN32__)
102    HMODULE hModule = null;
103    if(name && name[0])
104    {
105       uint16 _wmoduleName[MAX_LOCATION];
106       UTF8toUTF16Buffer(name, _wmoduleName, MAX_LOCATION);
107       hModule = GetModuleHandle(_wmoduleName);
108       if(!hModule)
109       {
110          wcscat(_wmoduleName, L".exe");
111          hModule = GetModuleHandle(_wmoduleName);
112       }
113       if(hModule)
114       {
115          uint16 _wfileName[MAX_LOCATION];
116          GetModuleFileNameW(hModule, _wfileName, MAX_LOCATION);
117          UTF16toUTF8Buffer(_wfileName, (byte *)fileName, MAX_LOCATION);
118          return true;
119       }
120    }
121    else
122    {
123       uint16 _wfileName[MAX_LOCATION];
124       GetModuleFileNameW(null, _wfileName, MAX_LOCATION);
125       UTF16toUTF8Buffer(_wfileName, (byte *)fileName, MAX_LOCATION);
126       return true;
127    }
128 #elif defined(__APPLE__)
129    if(name && name[0])
130    {
131       int imageCount = _dyld_image_count();
132       int c;
133       int nameLen = strlen(name);
134       for(c = 0; c<imageCount; c++)
135       {
136          struct mach_header * header = _dyld_get_image_header(c);
137          char * path = _dyld_get_image_name(c);
138          int pathLen = strlen(path);
139          char * subStr = RSearchString(path, name, pathLen, false, false);
140          if(subStr)
141          {
142             if(( *(subStr-1) == '/' || !strncmp(subStr - 4, "/lib", 4)) &&
143                (!subStr[nameLen] || !strncmp(subStr + nameLen, ".dylib", 6)))
144             {
145                strcpy(fileName, path);
146                return true;
147             }
148          }
149       }
150    }
151    else
152    {
153       int size = MAX_LOCATION;
154       _NSGetExecutablePath(fileName, &size);
155       return true;
156    }
157 #elif defined(__unix__)
158    //File f = FileOpen("/proc/self/maps", read);
159    FILE * f;
160    char exeName[MAX_FILENAME];
161    exeName[0] = 0;
162 #if defined(__linux__)
163    f = fopen("/proc/self/status", "r");
164 #else
165    f = fopen("/proc/curproc/status", "r");
166 #endif
167    if(f)
168    {
169       char line[1025];
170       while(fgets(line, sizeof(line), f))
171       {
172          char * name = strstr(line, "Name:\t");
173          if(name)
174          {
175             int nameLen;
176             name += 6;
177             nameLen = strlen(name);
178             name[--nameLen] = 0;
179             strcpy(exeName, name);
180             break;
181          }
182       }
183       fclose(f);
184   }
185 #if defined(__linux__)
186    f = fopen("/proc/self/maps", "r");
187 #else
188    f = fopen("/proc/curproc/map", "r");
189 #endif
190    if(f)
191    {
192       char line[1025];
193       //while(f.GetLine(line, sizeof(line)))
194       while(fgets(line, sizeof(line), f))
195       {
196          char * path = strstr(line, "/");
197          if(path)
198          {
199             int pathLen = strlen(path);
200             path[--pathLen] = 0;
201             if(name && name[0])
202             {
203                int nameLen = strlen(name);
204                char * subStr;
205                subStr = RSearchString(path, name, pathLen, false, false);
206                if(subStr)
207                {
208                   if(( *(subStr-1) == '/' || !strncmp(subStr - 4, "/lib", 4)) &&
209                      (!subStr[nameLen] || !strncmp(subStr + nameLen, ".so", 3)))
210                   {
211                      char * space = strchr(path, ' ');
212                      if(space) *space = 0;
213                      strcpy(fileName, path);
214                      fclose(f);
215                      return true;
216                   }
217                }
218             }
219             else
220             {
221                char name[MAX_FILENAME];
222                GetLastDirectory(path, name);
223                if(!exeName[0] || !strcmp(name, exeName))
224                {
225                   char * space = strchr(path, ' ');
226                   if(space) *space = 0;
227                   strcpy(fileName, path);
228                   fclose(f);
229                   return true;
230                }
231             }
232          }
233       }
234       fclose(f);
235    }
236    if(!name || !name[0])
237    {
238       strcpy(fileName, exeLocation);
239       return true;
240    }
241 #endif
242    return false;
243 }
244
245 void Instance_COM_Initialize(int argc, char ** argv, char ** parsedCommand, int * argcPtr, char *** argvPtr)
246 {
247 #if !defined(__WIN32__) && !defined(ECERE_BOOTSTRAP)
248    // Disable stdout buffering on Unix
249    setvbuf(stdout, null, _IONBF, 0);
250 #endif
251 #if defined(__WIN32__)
252    *parsedCommand = UTF16toUTF8(GetCommandLineW());
253    *argvPtr = eSystem_New0(sizeof(char *) * 512);
254    *argcPtr = Tokenize(*parsedCommand, 512,(void*)(char **)(*argvPtr), false);
255 #else
256    *argcPtr = argc;
257    *argvPtr = argv;
258 #endif
259 #if defined(__unix__)
260    if(!__thisModule && argv)
261    {
262       getcwd(exeLocation, MAX_LOCATION);
263       PathCat(exeLocation, argv[0]);
264    }
265 #endif
266 }
267
268 void * Instance_Module_Load(char * name, void ** Load, void ** Unload)
269 {
270    char fileName[MAX_LOCATION];
271    char extension[MAX_EXTENSION];
272    void * library = null;
273
274    *Load = null;
275    *Unload = null;
276
277 #if defined(__WIN32__)
278    strcpy(fileName, name);
279    GetExtension(fileName, extension);
280    if(!extension[0])
281       strcat(fileName, ".dll");
282
283    {
284       uint16 _wfileName[MAX_LOCATION];
285       UTF8toUTF16Buffer(fileName, _wfileName, MAX_LOCATION);
286       library = LoadLibraryW(_wfileName);
287    }
288    if(library)
289    {
290 #ifdef _WIN64
291       *Load = (void *)GetProcAddress(library, "__ecereDll_Load");
292       *Unload = (void *)GetProcAddress(library, "__ecereDll_Unload");
293 #else
294       *Load = (void *)GetProcAddress(library, "__ecereDll_Load@4");
295       *Unload = (void *)GetProcAddress(library, "__ecereDll_Unload@4");
296 #endif
297       if(!*Load)
298          FreeLibrary(library);
299    }
300 #elif defined(__unix__) || defined(__APPLE__)
301 #if defined(__ANDROID__)
302    sprintf(fileName, "/data/data/com.ecere.%s/lib/lib", name);
303 #else
304    strcpy(fileName, "lib");
305 #endif
306    strcat(fileName, name);
307    GetExtension(fileName, extension);
308    if(!extension[0])
309 #if defined(__APPLE__)
310       strcat(fileName, ".dylib");
311 #else
312       strcat(fileName, ".so");
313 #endif
314
315    library = dlopen(fileName, RTLD_LAZY);
316    if(!library)
317    {
318 #ifdef DEB_HOST_MULTIARCH
319       strcpy(fileName, DEB_HOST_MULTIARCH);
320       strcat(fileName, "/ec/lib");
321 #else
322       strcpy(fileName, "/usr/lib/ec/lib");
323 #endif
324       strcat(fileName, name);
325       GetExtension(fileName, extension);
326       if(!extension[0])
327 #if defined(__APPLE__)
328          strcat(fileName, ".dylib");
329 #else
330          strcat(fileName, ".so");
331 #endif
332       library = dlopen(fileName, RTLD_LAZY);
333    }
334
335    if(library)
336    {
337       *Load = dlsym(library, "__ecereDll_Load");
338       *Unload = dlsym(library, "__ecereDll_Unload");
339       if(!*Load)
340          dlclose(library);
341    }
342 #elif defined(__APPLE__)
343    strcpy(fileName, "lib");
344    strcat(fileName, name);
345    GetExtension(fileName, extension);
346    if(!extension[0])
347       strcat(fileName, ".dylib");
348    {
349       NSObjectFileImage *fileImage;
350       NSObjectFileImageReturnCode returnCode = NSCreateObjectFileImageFromFile(fileName, &fileImage);
351
352       if(returnCode == NSObjectFileImageSuccess)
353       {
354          printf("NSObjectFileImageSuccess!\n");
355          library = NSLinkModule(fileImage,fileName, 
356               NSLINKMODULE_OPTION_RETURN_ON_ERROR
357             | NSLINKMODULE_OPTION_PRIVATE);
358          // NSDestroyObjectFileImage(fileImage);
359          if(library)
360          {
361             *Load = NSAddressOfSymbol(NSLookupSymbolInModule(library, "__ecereDll_Load")); 
362             *Unload = NSAddressOfSymbol(NSLookupSymbolInModule(library, "__ecereDll_Unload"));
363             if(!*Load)
364             {
365                NSUnLinkModule(library, 0);
366             }
367             else
368                printf("Found Load!\n");
369          }
370       }
371       else
372          printf("No Success :(\n");
373    }
374 #endif
375    return library;
376 }
377
378 void Instance_Module_Free(void * library)
379 {
380 #if defined(__WIN32__)
381    if(library)
382       FreeLibrary(library);
383 #elif defined(__unix__) || defined(__APPLE__)
384    if(library)
385       dlclose(library);
386 #endif
387 }