8 #define snprintf _snprintf
11 typedef struct _stub
{
17 void usage( char *name
) {
19 "Usage: %s [-n nm] [-m make] libs...\n"
20 "nm -- The command used to run nm on reactos objects\n"
21 "make -- The command used to build reactos\n\n"
22 "libs are import libraries (.a files) typically from\n"
23 "dk/lib/nkm and dk/lib/w32\n",
27 int main( int argc
, char **argv
) {
31 char *origin
= "unknown.a";
32 stub
*functions
= NULL
, *new_f
, *imports
= NULL
, *search
;
34 int i
, libstart
= argc
;
35 FILE *out
= fopen("tests/stubs.tst","w");
37 if( argc
== 1 ) { usage(argv
[0]); return 1; }
40 fprintf( stderr
, "Could not write file tests/stubs.tst\n" );
44 fprintf( out
, "# Automatically generated by stubgen\n" );
46 for( i
= 1; i
< argc
; i
++ ) {
47 if( !strcmp( argv
[i
], "-m" ) ) {
50 } else if( !strcmp( argv
[i
], "-n" ) ) {
53 } else { libstart
= i
; break; }
56 snprintf( line
, sizeof(line
), "%s test 2>&1", make
);
57 make_f
= popen( line
, "r" );
61 fprintf( stderr
, "Could not run %s test\n", make
);
65 while( fgets( line
, sizeof(line
), make_f
) ) {
66 char *end_of_location
;
67 char *begin_q
, *end_q
;
69 if( !strstr( line
, "undefined reference to" ) ) continue;
71 end_of_location
= strrchr( line
, ':' );
73 if( !end_of_location
) continue;
75 begin_q
= strchr( end_of_location
, '`' );
76 end_q
= strchr( end_of_location
, '\'' );
78 if( !begin_q
|| !end_q
) continue;
80 begin_q
+= 2; /* skip `_ */
82 memmove( line
, begin_q
, end_q
- begin_q
);
83 line
[end_q
- begin_q
] = 0;
85 for( new_f
= functions
; new_f
; new_f
= new_f
->next
)
86 if( !strcmp( new_f
->name
, line
) ) break;
90 new_f
= (stub
*)malloc( sizeof(stub
) );
93 fprintf( stderr
, "Out of memory\n" );
99 new_f
->name
= strdup( line
);
100 new_f
->next
= functions
;
104 /* Scan libraries and collect available import sections */
105 for( i
= libstart
; i
< argc
; i
++ ) {
106 snprintf( line
, sizeof(line
), "%s %s", nm
, argv
[i
] );
107 nm_f
= popen( line
, "r" );
109 for( origin
= argv
[i
]; *argv
[i
]; argv
[i
]++ )
110 if( *argv
[i
] == '/' || *argv
[i
] == '\\' )
111 origin
= argv
[i
] + 1;
115 fprintf( stderr
, "Could not run %s\n", line
);
119 while( fgets( line
, sizeof(line
), nm_f
) ) {
120 char *import_sign
, *eol
;
122 if( !(import_sign
= strstr( line
, " I " )) ) continue;
125 while( *import_sign
&& isspace(*import_sign
) ) import_sign
++;
127 /* Strip ws after name */
128 for( eol
= import_sign
; *eol
&& !isspace(*eol
); eol
++ );
132 for( new_f
= imports
; new_f
; new_f
= new_f
->next
)
133 if( !strcmp( new_f
->name
, import_sign
) ) break;
135 if( new_f
) continue;
137 new_f
= (stub
*)malloc( sizeof(stub
) );
140 fprintf( stderr
, "Out of memory\n" );
147 new_f
->name
= strdup( import_sign
+ 1 );
148 new_f
->origin
= origin
;
149 new_f
->next
= imports
;
156 /* Now we have a list of unique functions and a list of imports,
157 lookup each function and output the entry from the import list. */
158 for( new_f
= functions
; new_f
; new_f
= new_f
->next
) {
159 for( search
= imports
; search
; search
= search
->next
) {
160 if( !strcmp( new_f
->name
, search
->name
) ) {
161 fprintf( out
, "%s %s\n", search
->origin
, search
->name
);