Update the changelog
[opencv] / apps / cvenv / filelist.cpp
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 //  By downloading, copying, installing or using the software you agree to this license.
6 //  If you do not agree to this license, do not download, install,
7 //  copy or use the software.
8 //
9 //
10 //                        Intel License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 //   * Redistribution's of source code must retain the above copyright notice,
20 //     this list of conditions and the following disclaimer.
21 //
22 //   * Redistribution's in binary form must reproduce the above copyright notice,
23 //     this list of conditions and the following disclaimer in the documentation
24 //     and/or other materials provided with the distribution.
25 //
26 //   * The name of Intel Corporation may not be used to endorse or promote products
27 //     derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/
41
42 /* this file contains platform-depended code (parse dll, */
43 /* getting file list e.t.c.)                             */
44
45
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <string.h>
49 #include "eic.h"
50 #include "filelist.h"
51
52 #undef malloc
53 #undef realloc
54 #undef free
55
56 #ifdef WIN32
57 #include <windows.h>
58 #else
59 #include <dlfcn.h>
60 #endif
61
62 char* GetPathFromModuleName( char* modulename )
63 {
64     int i;
65     if( !modulename )
66         return 0;
67 #ifndef WIN32
68     /* if module is link find real path */
69     int  len;
70     char real[1000];
71     strcpy( real, modulename );
72     while( (len = readlink( real, real, 1000 )) > 0 )
73         real[len] = 0;
74     char* path = (char*)malloc( strlen( real ) + 10 );
75     strcpy( path, real );
76 #else
77     char* path = (char*)malloc( strlen( modulename ) + 10 );
78     strcpy( path, modulename );
79 #endif
80
81     for( i = strlen( path ) - 1;
82          i > 0 && path[i] != '\\' && path[i] != '/';
83          i-- );
84
85     if( i <= 0 )
86     {
87         path[0] = '.';
88         i = 1;
89     }
90
91     path[i] = '/';
92     path[i + 1] = 0;
93
94 #ifdef WIN32
95     for( i = 0; i < (int)strlen( path ); i++ )
96         if( path[i] == '\\' )
97             path[i] = '/';
98 #endif
99
100     return path;
101 }
102
103
104 /* path - path to module (in)       */
105 /* headers - array of headers (out) */
106 /* libs - array of libs (out)       */
107 int GetFileList( char* path, char*** headers,  int* header_num,
108                              char*** headpath, int* headpath_num,
109                              char*** libs,     int* lib_num )
110 {
111     if( !path )
112         return -1;
113
114     if( libs )
115         *libs = 0;
116     if( lib_num )
117         *lib_num = 0;
118     if( headpath_num )
119         *headpath_num = 0;
120
121     char init[1000];
122     char root[1000];
123     strcpy( init, path );
124
125     /* adding last '/' if needed */
126     int len = strlen( init );
127     if( len )
128     {
129         if( len && init[len - 1] != '\\' && init[len - 1] != '/' )
130             strcat( init, "/" );
131     }
132     else
133         strcpy( init, "/" );
134     strcpy( root, init );
135
136 #ifdef WIN32
137     strcat( init, "plugins.cfg" );
138 #else
139     strcat( init, "plugins.conf" );
140 #endif
141
142     int    nlp = 0;
143     int    nip = 0;
144     int    nl  = 0;
145     int    ni  = 0;
146
147     /* open config file */
148     FILE* cfg = fopen( init, "rb" );
149     if( cfg )
150     {
151         /* reading */
152         fseek( cfg, 0, SEEK_END );
153         int size = ftell( cfg );
154         fseek( cfg, 0, SEEK_SET );
155
156         char* buffer = (char*)malloc( size + 2 );
157         fread( buffer, 1, size, cfg );
158         buffer[size] = 0;
159
160         /* parsing */
161         char** lpath = (char**)malloc( 1 );
162         char** ipath = (char**)malloc( 1 );
163         char** incl  = (char**)malloc( 1 );
164         char** lib   = (char**)malloc( 1 );
165         char   what[100];
166         char   where[1000];
167
168         int    i;
169         for( i = 0; i < size; )
170         {
171             /* get string */
172             int j;
173             for( j = i; buffer[j] <= ' ' && j < size; j++ );
174             i = j;
175             if( i >= size )
176                 break;
177             for( j = i; buffer[j] != 0xa && buffer[j] != 0xd && j < size; j++ );
178             buffer[j] = 0;
179
180             if( buffer[i] == '#' )
181             {
182                 i = j;
183                 continue;
184             }
185
186             what[0] = 0;
187             where[0] = 0;
188             sscanf( buffer + i, "%s %s", what, where );
189             if( !strcmp( what, "include" ) )
190             {
191                 incl = (char**)realloc( incl, sizeof( *incl ) * (ni + 1) );
192                 incl[ni] = (char*)malloc( strlen( where ) + 1 );
193                 strcpy( incl[ni], where );
194                 ni++;
195             }
196             else if( !strcmp( what, "incpath" ) )
197             {
198                 ipath = (char**)realloc( ipath, sizeof( *ipath ) * (nip + 1) );
199                 ipath[nip] = (char*)malloc( strlen( root ) + strlen( where ) + 1 );
200                 ipath[nip][0] = 0;
201     #ifdef WIN32
202                 if( where[1] != ':' )
203     #else
204                 if( where[0] != '/' )
205     #endif
206                     strcpy( ipath[nip], root );
207                 strcat( ipath[nip], where );
208                 nip++;
209             }
210             else if( !strcmp( what, "libpath" ) )
211             {
212                 lpath = (char**)realloc( lpath, sizeof( *lpath ) * (nlp + 1) );
213                 lpath[nlp] = (char*)malloc( strlen( root ) + strlen( where ) + 1 );
214                 lpath[nlp][0] = 0;
215     #ifdef WIN32
216                 if( where[1] != ':' )
217     #else
218                 if( where[0] != '/' )
219     #endif
220                     strcpy( lpath[nlp], root );
221                 strcat( lpath[nlp], where );
222                 nlp++;
223             }
224             else if( !strcmp( what, "library" ) )
225             {
226                 int found = 0;
227     #ifdef WIN32
228                 if( where[1] != ':' )
229     #else
230                 if( where[0] != '/' )
231     #endif
232                     for( int i = 0; i < nlp; i++ )
233                     {
234                         char findlib[1000];
235                         strcpy( findlib, lpath[i] );
236                         strcat( findlib, "/" );
237                         strcat( findlib, where );
238                         FILE* lb = fopen( findlib, "rb" );
239                         if( lb )
240                         {
241                             lib = (char**)realloc( lib, sizeof( *lib ) * (nl + 1) );
242                             lib[nl] = (char*)malloc( strlen( findlib ) + 1 );
243                             strcpy( lib[nl], findlib );
244                             nl++;
245                             fclose( lb );
246                             found = 1;
247                             break;
248                         }
249                     }
250                 else
251                 {
252                     FILE* lb = fopen( where, "rb" );
253                     if( lb )
254                     {
255                         lib = (char**)realloc( lib, sizeof( *lib ) * (nl + 1) );
256                         lib[nl] = (char*)malloc( strlen( where ) + 1 );
257                         strcpy( lib[nl], where );
258                         nl++;
259                         fclose( lb );
260                         found = 1;
261                         break;
262                     }
263                 }
264                 if( !found )
265                 {
266                     char tmp[1000];
267                     sprintf( tmp, "Library %s hasn't been found\n", where );
268                     ErrorOutput( tmp );
269                 }
270             }
271
272             i = j;
273         }
274
275         if( headers && ni )
276             *headers = incl;
277         else
278         {
279             for( int i = 0; i < nip; i++ )
280                 free( incl[i] );
281             free( incl );
282         }
283
284         if( libs && nl )
285             *libs = lib;
286         else
287         {
288             for( int i = 0; i < nl; i++ )
289                 free( lib[i] );
290             free( lib );
291         }
292
293         if( headpath && nip )
294             *headpath = ipath;
295         else
296         {
297             for( int i = 0; i < nip; i++ )
298                 free( ipath[i] );
299             free( ipath );
300         }
301
302         for( i = 0; i < nlp; i++ )
303             free( lpath[i] );
304         free( lpath );
305
306         fclose( cfg );
307         free( buffer );
308     }
309     if( header_num )
310         *header_num = ni;
311     if( headpath_num )
312         *headpath_num = nip;
313     if( lib_num )
314         *lib_num = nl;
315
316     return 0;
317 }
318
319
320 #define MakePtr(cast,ptr,addValue) (cast)((DWORD)(ptr)+(DWORD)(addValue))
321
322 static int GetExportList( char* filename, char*** names )
323 {
324 #ifdef WIN32
325     HANDLE file = CreateFile( filename,
326                               GENERIC_READ,
327                               FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
328                               0,
329                               OPEN_EXISTING,
330                               0,
331                               0 );
332
333     if( file == INVALID_HANDLE_VALUE )
334         return 0;
335
336     unsigned long filesize;
337     unsigned long read;
338     char* buffer = (char*)malloc( filesize = SetFilePointer( file, 0, 0, FILE_END ) );
339     SetFilePointer( file, 0, 0, FILE_BEGIN );
340     BOOL res = ReadFile( file, buffer, filesize, &read, 0 );
341     CloseHandle( file );
342     if( !res )
343     {
344         free( buffer );
345         return 0;
346     }
347
348     PIMAGE_EXPORT_DIRECTORY exportDir;
349     PIMAGE_SECTION_HEADER header;
350     PIMAGE_NT_HEADERS pNTHeader;
351     PIMAGE_DOS_HEADER pDosHdr;
352     int delta;
353     int i;
354     char** name;
355     unsigned int exportsStartRVA, exportsEndRVA;
356     unsigned int base;
357     char* pfile;
358     int num;
359
360     pfile = buffer;
361
362     pDosHdr = (PIMAGE_DOS_HEADER)pfile;
363     base = (DWORD)pfile;
364
365     pNTHeader = MakePtr(PIMAGE_NT_HEADERS,
366                         pfile,pDosHdr->e_lfanew);
367
368     exportsStartRVA =
369         pNTHeader->OptionalHeader.DataDirectory
370         [IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
371
372
373     exportsEndRVA = exportsStartRVA + pNTHeader->OptionalHeader.DataDirectory
374         [IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
375
376     // Get the IMAGE_SECTION_HEADER that contains the exports.  This is
377     // usually the .edata section, but doesn't have to be.
378     
379     PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(pNTHeader);
380     
381     header = 0;
382     
383     for ( i=0; i < pNTHeader->FileHeader.NumberOfSections; i++, section++ )
384     {
385         // Is the RVA within this section?
386         if ( (exportsStartRVA >= section->VirtualAddress) &&
387             (exportsStartRVA < (section->VirtualAddress + section->Misc.VirtualSize)))
388             header =  section;
389     }
390     
391     if ( !header )
392     {
393         printf( "No Exports Table Found\n" );
394         free( buffer );
395         return 0;
396     }
397     
398     delta = (INT)(header->VirtualAddress - header->PointerToRawData);
399     exportDir = MakePtr(PIMAGE_EXPORT_DIRECTORY, base,
400         exportsStartRVA - delta);
401     
402     name = (PSTR *)((DWORD)exportDir->AddressOfNames - delta + base);
403     
404     exportDir = MakePtr(PIMAGE_EXPORT_DIRECTORY, base,
405         exportsStartRVA - delta);
406     
407     *names = (char**)malloc( (exportDir->NumberOfNames + 1) * sizeof(char*) );
408     
409     for ( unsigned int j = 0; j < exportDir->NumberOfNames; j++ )
410     {
411         (*names)[j] = (char*)malloc( strlen( name[j] - delta + base ) + 1 );
412         strcpy( (*names)[j], name[j] - delta + base );
413     }
414     
415     num = exportDir->NumberOfNames;
416     free( buffer );
417     
418     return num;
419 #else
420     char* command = (char*)malloc( strlen( filename ) + 100 );
421     strcat( strcat( strcpy( command, "nm " ), filename ), " | grep \" T \"" );
422     FILE* exp = popen( command, "r" );
423     int r;
424     int size = 0;
425     char buffer[1000];
426     char* file = (char*)malloc( 1 );
427     while( (r = fread( buffer, 1, 1000, exp ) ) > 0 )
428     {
429         file = (char*)realloc( file, size + r );
430         memcpy( file + size, buffer, r );
431         size += r;
432     }
433     pclose( exp );
434
435     (*names) = (char**)malloc( 1 );
436     int num = 0;
437         
438     for( int i = 0; i < size; )
439     {
440         /* get string */
441         int j;
442         for( j = i; file[j] <= ' ' && j < size; j++ );
443         i = j;
444         if( i >= size )
445             break;
446         for( j = i; file[j] != 0xa && file[j] != 0xd && j < size; j++ );
447         file[j] = 0;
448
449         char entry[1000];
450         char type[1000];
451         char name[1000];
452
453         sscanf( file + i, "%s %s %s", entry, type, name );
454         (*names) = (char**)realloc( *names, sizeof(**names) * (num + 1) );
455         (*names)[num] = (char*)malloc( strlen( name ) + 1 );
456         strcpy( (*names)[num], name );
457 //        printf( "%s\n", (*names)[num] );
458         num++;
459         i = j;
460     }
461     free( file );
462     return num;
463 #endif
464 }
465
466 int AddLibrary( char* path )
467 {
468 #ifdef WIN32
469     HMODULE lib;
470 #else
471     void*   lib;
472 #endif
473     int funcs;
474     char** exports;
475
476     if( (funcs = GetExportList( path, &exports )) == 0 )
477     {
478         return -1;
479     }
480
481 #ifdef WIN32
482     if( (lib = LoadLibrary( path )) == 0 )
483 #else
484     if( (lib = dlopen( path, RTLD_LAZY )) == 0 )
485 #endif
486         return -1;
487
488     for( int i = 0; i < funcs; i++ )
489     {
490 #ifdef WIN32
491         void* func = GetProcAddress( lib, exports[i] );
492 #else
493         void* func = dlsym( lib, exports[i] );
494 #endif
495         if( func )
496             AddExternFunction( func, exports[i] );
497         free( exports[i] );
498     }
499
500     //AddWrappers();
501
502     free( exports );
503
504     return 0;
505 }
506
507 //-----------------------------------------------------------------------------
508
509 extern "C" int _eicUprintf(int (*output)(...), char **arg, char *fmt, arg_list ap);
510 extern "C" int _eicUscanf (int (*input)(...) , int (*uget)(...) ,
511                            char **arg, const char *fmt, arg_list ap);
512 extern "C" int charout_(int c, char *buf);
513 extern "C" int charin_(char *buf);
514 extern "C" int charback_(int ch, char **buf);
515 typedef int(*put_t)(...);
516 //typedef int(*put0_t)();
517 #ifdef WIN32
518 static HANDLE g_hWritePipe = 0;
519 static HANDLE g_hErrorPipe = 0;
520 static HANDLE g_hInputPipe = 0;
521 #else
522 static int g_hWritePipe = 0;
523 static int g_hErrorPipe = 0;
524 static int g_hInputPipe = 0;
525 #endif
526
527 static VaL output_printf( )
528 {
529     VaL val;
530     val_t v;
531     unsigned long num;
532     arg_list ag = getargs();
533
534     char* g_pchBuf = (char*) malloc( 0xF000 );
535     memset( g_pchBuf, 0, 0xF000 );
536     char* fmt = (char*) nextarg(ag,ptr_t).p;
537
538     v.ival = val.ival = _eicUprintf((put_t)charout_, &g_pchBuf, fmt, ag);
539
540     
541     //console outout//v.ival = val.ival = _eicUprintf((put_t)fputc,stdout,fmt,ag);
542     
543     if( g_hWritePipe )
544 #ifdef WIN32
545         WriteFile(g_hWritePipe,
546                   (LPCVOID) g_pchBuf,
547                   val.ival,
548                   &num,
549                   NULL);
550 #else
551     write( g_hWritePipe, g_pchBuf, val.ival );
552 #endif
553     else
554         printf( "%s", g_pchBuf );
555
556     free( g_pchBuf );
557     return val;
558 }
559
560 static VaL input_scanf()
561 {
562     VaL val;
563     val_t v;
564     unsigned long num;
565     arg_list ag = getargs();
566
567     char* g_pchBuf = (char*)malloc( 0xF000 );
568     char* _pchBuf = g_pchBuf;
569     memset( g_pchBuf, 0, 0xF000 );
570
571     if( g_hInputPipe )
572 #ifdef WIN32
573     {
574         ReadFile(g_hInputPipe,
575                   (LPVOID) g_pchBuf,
576                   255,
577                   &num,
578                   NULL);
579     
580         g_pchBuf[num] = '\n';
581     
582         WriteFile(g_hWritePipe,
583                   (LPVOID) g_pchBuf,
584                   num+1,
585                   &num,
586                   NULL);
587     }
588 #else
589     num = read( g_hInputPipe, g_pchBuf, 255 );
590 #endif
591     else
592         scanf( "%s%n", g_pchBuf, &num );
593
594     char* fmt = (char*) nextarg(ag,ptr_t).p;
595     v.ival = val.ival = _eicUscanf ((put_t)charin_ ,
596                                    (put_t)charback_, &g_pchBuf, fmt, ag);
597     //console input//v.ival = _eicUscanf((put_t)fgetc,(put_t)ungetc,stdin,fmt,ag);
598     
599     free( _pchBuf );
600     return val;
601 }
602
603 void ErrorOutput(char *msg)
604 {
605     unsigned long num;
606     unsigned long size = strlen( msg );
607
608     if( g_hErrorPipe )
609 #ifdef WIN32
610     {
611         if( g_hWritePipe )
612             WriteFile(g_hWritePipe,
613                       (LPCVOID) msg,
614                       size,
615                       &num,
616                       NULL);
617         else
618             printf( msg );
619
620         WriteFile(g_hErrorPipe,
621                   (LPCVOID) msg,
622                   size,
623                   &num,
624                   NULL);
625     }
626 #else
627     {
628         if( g_hWritePipe )
629             write( g_hWritePipe, msg, size );
630         else
631             printf( msg );
632         write( g_hErrorPipe, msg, size );
633     }
634 #endif
635     else
636         printf( "%s", msg );
637
638 }
639
640 void _printf(char *msg)
641 {
642     printf(msg);
643 }
644
645 void InitIO( char* output, char* errors, char* input )
646 {
647     if( input )
648         sscanf( input, "%d", &g_hInputPipe );
649     else
650         g_hInputPipe = 0;
651     EiC_add_builtinfunc( "scanf", input_scanf );
652
653     if( output )
654         sscanf( output, "%d", &g_hWritePipe );
655     else
656         g_hWritePipe = 0;
657     EiC_add_builtinfunc( "printf", output_printf );
658
659     if( errors ) {
660         sscanf( errors, "%d", &g_hErrorPipe );
661         EiC_setMessageDisplay(ErrorOutput);
662     }
663     else
664     {
665         EiC_setMessageDisplay(_printf);
666         g_hErrorPipe = 0;
667     }
668 }