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");
38 if( out
) fclose( out
);
44 fprintf( stderr
, "Could not write file tests/stubs.tst\n" );
48 fprintf( out
, "# Automatically generated by stubgen\n" );
50 for( i
= 1; i
< argc
; i
++ ) {
51 if( !strcmp( argv
[i
], "-m" ) ) {
54 } else if( !strcmp( argv
[i
], "-n" ) ) {
57 } else { libstart
= i
; break; }
60 snprintf( line
, sizeof(line
), "%s test 2>&1", make
);
61 make_f
= popen( line
, "r" );
65 fprintf( stderr
, "Could not run %s test\n", make
);
69 while( fgets( line
, sizeof(line
), make_f
) ) {
70 char *end_of_location
;
71 char *begin_q
, *end_q
;
73 if( !strstr( line
, "undefined reference to" ) ) continue;
75 end_of_location
= strrchr( line
, ':' );
77 if( !end_of_location
) continue;
79 begin_q
= strchr( end_of_location
, '`' );
80 end_q
= strchr( end_of_location
, '\'' );
82 if( !begin_q
|| !end_q
) continue;
84 begin_q
+= 2; /* skip `_ */
86 memmove( line
, begin_q
, end_q
- begin_q
);
87 line
[end_q
- begin_q
] = 0;
89 for( new_f
= functions
; new_f
; new_f
= new_f
->next
)
90 if( !strcmp( new_f
->name
, line
) ) break;
94 new_f
= (stub
*)malloc( sizeof(stub
) );
97 fprintf( stderr
, "Out of memory\n" );
103 new_f
->name
= strdup( line
);
104 new_f
->next
= functions
;
108 /* Scan libraries and collect available import sections */
109 for( i
= libstart
; i
< argc
; i
++ ) {
110 snprintf( line
, sizeof(line
), "%s %s", nm
, argv
[i
] );
111 nm_f
= popen( line
, "r" );
113 for( origin
= argv
[i
]; *argv
[i
]; argv
[i
]++ )
114 if( *argv
[i
] == '/' || *argv
[i
] == '\\' )
115 origin
= argv
[i
] + 1;
119 fprintf( stderr
, "Could not run %s\n", line
);
123 while( fgets( line
, sizeof(line
), nm_f
) ) {
124 char *import_sign
, *eol
;
126 if( !(import_sign
= strstr( line
, " I " )) ) continue;
129 while( *import_sign
&& isspace(*import_sign
) ) import_sign
++;
131 /* Strip ws after name */
132 for( eol
= import_sign
; *eol
&& !isspace(*eol
); eol
++ );
136 for( new_f
= imports
; new_f
; new_f
= new_f
->next
)
137 if( !strcmp( new_f
->name
, import_sign
) ) break;
139 if( new_f
) continue;
141 new_f
= (stub
*)malloc( sizeof(stub
) );
144 fprintf( stderr
, "Out of memory\n" );
151 new_f
->name
= strdup( import_sign
+ 1 );
152 new_f
->origin
= origin
;
153 new_f
->next
= imports
;
160 /* Now we have a list of unique functions and a list of imports,
161 lookup each function and output the entry from the import list. */
162 for( new_f
= functions
; new_f
; new_f
= new_f
->next
) {
163 for( search
= imports
; search
; search
= search
->next
) {
164 if( !strcmp( new_f
->name
, search
->name
) ) {
165 fprintf( out
, "%s %s\n", search
->origin
, search
->name
);