2 * Useful functions for winegcc/winewrap
4 * Copyright 2000 Francois Gouget
5 * Copyright 2002 Dimitrie O. Paun
6 * Copyright 2003 Richard Cohen
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "wine/port.h"
34 # define min(x,y) (((x) < (y)) ? (x) : (y))
39 void error(const char* s
, ...)
44 fprintf(stderr
, "winegcc: ");
45 vfprintf(stderr
, s
, ap
);
46 fprintf(stderr
, "\n");
51 void* xmalloc(size_t size
)
55 if ((p
= malloc (size
)) == NULL
)
56 error("Could not malloc %d bytes.", size
);
61 void *xrealloc(void* p
, size_t size
)
63 void* p2
= realloc (p
, size
);
65 error("Could not realloc %d bytes.", size
);
70 int strendswith(const char* str
, const char* end
)
75 return l
>= m
&& strcmp(str
+ l
- m
, end
) == 0;
78 char* strmake(const char* fmt
, ...)
86 char *p
= xmalloc (size
);
88 n
= vsnprintf (p
, size
, fmt
, ap
);
90 if (n
== -1) size
*= 2;
91 else if ((size_t)n
>= size
) size
= n
+ 1;
97 strarray
* strarray_alloc(void)
99 strarray
* arr
= xmalloc(sizeof(*arr
));
100 arr
->maximum
= arr
->size
= 0;
105 void strarray_free(strarray
* arr
)
111 void strarray_add(strarray
* arr
, const char* str
)
113 if (arr
->size
== arr
->maximum
)
116 arr
->base
= xrealloc(arr
->base
, sizeof(*(arr
->base
)) * arr
->maximum
);
118 arr
->base
[arr
->size
++] = str
;
121 void strarray_del(strarray
* arr
, int i
)
123 if (i
< 0 || i
>= arr
->size
) error("Invalid index i=%d", i
);
124 memmove(&arr
->base
[i
], &arr
->base
[i
+ 1], (arr
->size
- i
- 1) * sizeof(arr
->base
[0]));
128 void strarray_addall(strarray
* arr
, const strarray
* from
)
132 for (i
= 0; i
< from
->size
; i
++)
133 strarray_add(arr
, from
->base
[i
]);
136 strarray
* strarray_dup(const strarray
* arr
)
138 strarray
* dup
= strarray_alloc();
141 for (i
= 0; i
< arr
->size
; i
++)
142 strarray_add(dup
, arr
->base
[i
]);
147 strarray
* strarray_fromstring(const char* str
, const char* delim
)
149 strarray
* arr
= strarray_alloc();
150 char* buf
= strdup(str
);
153 for(tok
= strtok(buf
, delim
); tok
; tok
= strtok(0, delim
))
154 strarray_add(arr
, strdup(tok
));
160 char* strarray_tostring(const strarray
* arr
, const char* sep
)
165 str
= strmake("%s", arr
->base
[0]);
166 for (i
= 1; i
< arr
->size
; i
++)
168 newstr
= strmake("%s%s%s", str
, sep
, arr
->base
[i
]);
176 char* get_basename(const char* file
)
181 if ((name
= strrchr(file
, '/'))) name
++;
184 base_name
= strdup(name
);
185 if ((p
= strrchr(base_name
, '.'))) *p
= 0;
190 void create_file(const char* name
, int mode
, const char* fmt
, ...)
195 if (verbose
) printf("Creating file %s\n", name
);
197 if ( !(file
= fopen(name
, "w")) )
198 error("Unable to open %s for writing.", name
);
199 vfprintf(file
, fmt
, ap
);
205 file_type
get_file_type(const char* filename
)
207 /* see tools/winebuild/res32.c: check_header for details */
208 static const char res_sig
[] = { 0,0,0,0, 32,0,0,0, 0xff,0xff, 0,0, 0xff,0xff, 0,0, 0,0,0,0, 0,0, 0,0, 0,0,0,0, 0,0,0,0 };
209 char buf
[sizeof(res_sig
)];
212 fd
= open( filename
, O_RDONLY
);
213 if (fd
== -1) return file_na
;
214 cnt
= read(fd
, buf
, sizeof(buf
));
216 if (cnt
== -1) return file_na
;
218 if (cnt
== sizeof(res_sig
) && !memcmp(buf
, res_sig
, sizeof(res_sig
))) return file_res
;
219 if (strendswith(filename
, ".o")) return file_obj
;
220 if (strendswith(filename
, ".a")) return file_arh
;
221 if (strendswith(filename
, ".res")) return file_res
;
222 if (strendswith(filename
, ".so")) return file_so
;
223 if (strendswith(filename
, ".dylib")) return file_so
;
224 if (strendswith(filename
, ".def")) return file_def
;
225 if (strendswith(filename
, ".spec")) return file_spec
;
226 if (strendswith(filename
, ".rc")) return file_rc
;
231 static char* try_lib_path(const char* dir
, const char* pre
,
232 const char* library
, const char* ext
,
233 file_type expected_type
)
238 /* first try a subdir named from the library we are looking for */
239 fullname
= strmake("%s/%s/%s%s%s", dir
, library
, pre
, library
, ext
);
240 if (verbose
> 1) fprintf(stderr
, "Try %s...", fullname
);
241 type
= get_file_type(fullname
);
242 if (verbose
> 1) fprintf(stderr
, type
== expected_type
? "FOUND!\n" : "no\n");
243 if (type
== expected_type
) return fullname
;
246 fullname
= strmake("%s/%s%s%s", dir
, pre
, library
, ext
);
247 if (verbose
> 1) fprintf(stderr
, "Try %s...", fullname
);
248 type
= get_file_type(fullname
);
249 if (verbose
> 1) fprintf(stderr
, type
== expected_type
? "FOUND!\n" : "no\n");
250 if (type
== expected_type
) return fullname
;
255 static file_type
guess_lib_type(const char* dir
, const char* library
, char** file
)
257 /* Unix shared object */
258 if ((*file
= try_lib_path(dir
, "lib", library
, ".so", file_so
)))
261 /* Mach-O (Darwin/Mac OS X) Dynamic Library behaves mostly like .so */
262 if ((*file
= try_lib_path(dir
, "lib", library
, ".dylib", file_so
)))
266 if ((*file
= try_lib_path(dir
, "lib", library
, ".def", file_def
)))
268 if ((*file
= try_lib_path(dir
, "", library
, ".def", file_def
)))
271 /* Unix static archives */
272 if ((*file
= try_lib_path(dir
, "lib", library
, ".a", file_arh
)))
278 file_type
get_lib_type(strarray
* path
, const char* library
, char** file
)
282 for (i
= 0; i
< path
->size
; i
++)
284 file_type type
= guess_lib_type(path
->base
[i
], library
, file
);
285 if (type
!= file_na
) return type
;
290 void spawn(const strarray
* prefix
, const strarray
* args
, int ignore_errors
)
293 strarray
* arr
= strarray_dup(args
);
297 strarray_add(arr
, NULL
);
302 for (i
= 0; i
< prefix
->size
; i
++)
307 if (!(p
= strrchr(argv
[0], '/'))) p
= argv
[0];
309 prog
= strmake("%s/%s", prefix
->base
[i
], p
);
310 if (stat(prog
, &st
) == 0)
312 if ((st
.st_mode
& S_IFREG
) && (st
.st_mode
& (S_IXUSR
| S_IXGRP
| S_IXOTH
)))
323 for(i
= 0; argv
[i
]; i
++) printf("%s ", argv
[i
]);
327 if ((status
= spawnvp( _P_WAIT
, argv
[0], argv
)) && !ignore_errors
)
329 if (status
> 0) error("%s failed.", argv
[0]);
330 else perror("winegcc");