Makefiles: Force building 32 or 64 bit by setting ARCH=32 or 64
[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(const char * libLocation, const char * name, void ** Load, void ** Unload)
269 {
270    char fileName[MAX_LOCATION];
271    char extension[MAX_EXTENSION];
272    void * library = null;
273 #if defined(__unix__) || defined(__APPLE__)
274    int attempts = 0;
275    char * paths[] = { null, "/usr/lib/ec/lib", "/usr/lib32/ec/lib" };
276 #endif
277
278    *Load = null;
279    *Unload = null;
280
281 #if defined(__WIN32__)
282    strcpy(fileName, name);
283    GetExtension(fileName, extension);
284    if(!extension[0])
285       strcat(fileName, ".dll");
286
287    {
288       uint16 _wfileName[MAX_LOCATION];
289       UTF8toUTF16Buffer(fileName, _wfileName, MAX_LOCATION);
290       library = LoadLibraryW(_wfileName);
291    }
292    if(library)
293    {
294 #ifdef _WIN64
295       *Load = (void *)GetProcAddress(library, "__ecereDll_Load");
296       *Unload = (void *)GetProcAddress(library, "__ecereDll_Unload");
297 #else
298       *Load = (void *)GetProcAddress(library, "__ecereDll_Load@4");
299       *Unload = (void *)GetProcAddress(library, "__ecereDll_Unload@4");
300 #endif
301       if(!*Load)
302          FreeLibrary(library);
303    }
304 #elif defined(__unix__) || defined(__APPLE__)
305    if(libLocation)
306       strcpy(fileName, libLocation);
307    else
308       strcpy(fileName, "lib");
309    strcat(fileName, name);
310    GetExtension(fileName, extension);
311    if(!extension[0])
312 #if defined(__APPLE__)
313       strcat(fileName, ".dylib");
314 #else
315       strcat(fileName, ".so");
316 #endif
317
318    library = dlopen(fileName, RTLD_LAZY);
319    while(!library && attempts < sizeof(paths)/sizeof(paths[0]))
320    {
321       if(paths[attempts])
322          strcpy(fileName, paths[attempts++]);
323       else
324       {
325          attempts++;
326 #ifdef DEB_HOST_MULTIARCH
327          strcpy(fileName, DEB_HOST_MULTIARCH);
328          strcat(fileName, "/ec/lib");
329 #else
330          continue;
331 #endif
332       }
333       strcat(fileName, name);
334       GetExtension(fileName, extension);
335       if(!extension[0])
336 #if defined(__APPLE__)
337          strcat(fileName, ".dylib");
338 #else
339          strcat(fileName, ".so");
340 #endif
341       library = dlopen(fileName, RTLD_LAZY);
342    }
343
344    if(library)
345    {
346       *Load = dlsym(library, "__ecereDll_Load");
347       *Unload = dlsym(library, "__ecereDll_Unload");
348       if(!*Load)
349          dlclose(library);
350    }
351 #elif defined(__APPLE__)
352    strcpy(fileName, "lib");
353    strcat(fileName, name);
354    GetExtension(fileName, extension);
355    if(!extension[0])
356       strcat(fileName, ".dylib");
357    {
358       NSObjectFileImage *fileImage;
359       NSObjectFileImageReturnCode returnCode = NSCreateObjectFileImageFromFile(fileName, &fileImage);
360
361       if(returnCode == NSObjectFileImageSuccess)
362       {
363          printf("NSObjectFileImageSuccess!\n");
364          library = NSLinkModule(fileImage,fileName, 
365               NSLINKMODULE_OPTION_RETURN_ON_ERROR
366             | NSLINKMODULE_OPTION_PRIVATE);
367          // NSDestroyObjectFileImage(fileImage);
368          if(library)
369          {
370             *Load = NSAddressOfSymbol(NSLookupSymbolInModule(library, "__ecereDll_Load")); 
371             *Unload = NSAddressOfSymbol(NSLookupSymbolInModule(library, "__ecereDll_Unload"));
372             if(!*Load)
373             {
374                NSUnLinkModule(library, 0);
375             }
376             else
377                printf("Found Load!\n");
378          }
379       }
380       else
381          printf("No Success :(\n");
382    }
383 #endif
384    return library;
385 }
386
387 void Instance_Module_Free(void * library)
388 {
389 #if defined(__WIN32__)
390    if(library)
391       FreeLibrary(library);
392 #elif defined(__unix__) || defined(__APPLE__)
393    if(library)
394       dlclose(library);
395 #endif
396 }