ReactOS  0.4.14-dev-297-g23e575c
stubgen.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <malloc.h>
3 #include <string.h>
4 #include <ctype.h>
5 
6 #ifdef _WIN32
7 #define popen _popen
8 #define snprintf _snprintf
9 #endif
10 
11 typedef struct _stub {
12  char *name;
13  char *origin;
14  struct _stub *next;
15 } stub;
16 
17 void usage( char *name ) {
18  fprintf( stderr,
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",
24  name );
25 }
26 
27 int main( int argc, char **argv ) {
28  char line[1024];
29  char *make = "make";
30  char *nm = "nm";
31  char *origin = "unknown.a";
32  stub *functions = NULL, *new_f, *imports = NULL, *search;
33  FILE *make_f, *nm_f;
34  int i, libstart = argc;
35  FILE *out = fopen("tests/stubs.tst","w");
36 
37  if( argc == 1 ) {
38  if( out ) fclose( out );
39  usage(argv[0]);
40  return 1;
41  }
42 
43  if( !out ) {
44  fprintf( stderr, "Could not write file tests/stubs.tst\n" );
45  return 1;
46  }
47 
48  fprintf( out, "# Automatically generated by stubgen\n" );
49 
50  for( i = 1; i < argc; i++ ) {
51  if( !strcmp( argv[i], "-m" ) ) {
52  make = argv[i+1];
53  i++;
54  } else if( !strcmp( argv[i], "-n" ) ) {
55  nm = argv[i+1];
56  i++;
57  } else { libstart = i; break; }
58  }
59 
60  snprintf( line, sizeof(line), "%s test 2>&1", make );
61  make_f = popen( line, "r" );
62 
63  if( !make_f ) {
64  fclose( out );
65  fprintf( stderr, "Could not run %s test\n", make );
66  return 1;
67  }
68 
69  while( fgets( line, sizeof(line), make_f ) ) {
70  char *end_of_location;
71  char *begin_q, *end_q;
72 
73  if( !strstr( line, "undefined reference to" ) ) continue;
74 
75  end_of_location = strrchr( line, ':' );
76 
77  if( !end_of_location ) continue;
78 
79  begin_q = strchr( end_of_location, '`' );
80  end_q = strchr( end_of_location, '\'' );
81 
82  if( !begin_q || !end_q ) continue;
83 
84  begin_q += 2; /* skip `_ */
85 
86  memmove( line, begin_q, end_q - begin_q );
87  line[end_q - begin_q] = 0;
88 
89  for( new_f = functions; new_f; new_f = new_f->next )
90  if( !strcmp( new_f->name, line ) ) break;
91 
92  if( new_f ) continue;
93 
94  new_f = (stub *)malloc( sizeof(stub) );
95  if( !new_f )
96  {
97  fprintf( stderr, "Out of memory\n" );
98  fclose( out );
99  pclose( make_f );
100  return 1;
101  }
102 
103  new_f->name = strdup( line );
104  new_f->next = functions;
105  functions = new_f;
106  }
107 
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" );
112 
113  for( origin = argv[i]; *argv[i]; argv[i]++ )
114  if( *argv[i] == '/' || *argv[i] == '\\' )
115  origin = argv[i] + 1;
116 
117 
118  if( !nm_f ) {
119  fprintf( stderr, "Could not run %s\n", line );
120  continue;
121  }
122 
123  while( fgets( line, sizeof(line), nm_f ) ) {
124  char *import_sign, *eol;
125 
126  if( !(import_sign = strstr( line, " I " )) ) continue;
127 
128  import_sign += 3;
129  while( *import_sign && isspace(*import_sign) ) import_sign++;
130 
131  /* Strip ws after name */
132  for( eol = import_sign; *eol && !isspace(*eol); eol++ );
133 
134  *eol = 0;
135 
136  for( new_f = imports; new_f; new_f = new_f->next )
137  if( !strcmp( new_f->name, import_sign ) ) break;
138 
139  if( new_f ) continue;
140 
141  new_f = (stub *)malloc( sizeof(stub) );
142  if( !new_f )
143  {
144  fprintf( stderr, "Out of memory\n" );
145  fclose( out );
146  pclose( make_f );
147  pclose( nm_f );
148  return 1;
149  }
150 
151  new_f->name = strdup( import_sign + 1 );
152  new_f->origin = origin;
153  new_f->next = imports;
154  imports = new_f;
155  }
156 
157  pclose( nm_f );
158  }
159 
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 );
166  continue;
167  }
168  }
169  }
170 
171  fclose( out );
172  pclose( make_f );
173  return 0;
174 }
static short search(int val, const short *table, int size)
Definition: msg711.c:255
static int argc
Definition: ServiceArgs.c:12
#define isspace(c)
Definition: acclib.h:69
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
Definition: stubgen.c:11
#define snprintf
Definition: wintirpc.h:48
voidpf uLong int origin
Definition: ioapi.h:142
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
#define argv
Definition: mplay32.c:18
struct _stub stub
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
_Check_return_ _CRTIMP char *__cdecl strdup(_In_opt_z_ const char *_Src)
smooth NULL
Definition: ftsmooth.c:416
Definition: parser.c:48
struct _stub * next
Definition: stubgen.c:14
static FILE * out
Definition: regtests2xml.c:44
char * origin
Definition: stubgen.c:13
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
#define pclose
Definition: syshdrs.h:73
_Check_return_opt_ _CRTIMP char *__cdecl fgets(_Out_writes_z_(_MaxCount) char *_Buf, _In_ int _MaxCount, _Inout_ FILE *_File)
struct imports * next
Definition: parser.yy.c:2647
#define popen
Definition: syshdrs.h:72
char * strchr(const char *String, int ch)
Definition: utclib.c:501
Definition: name.c:36
void usage(char *name)
Definition: stubgen.c:17
FILE * stderr
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define malloc
Definition: debug_ros.c:4
char * name
Definition: stubgen.c:12
int main(int argc, char **argv)
Definition: stubgen.c:27