ReactOS 0.4.16-dev-1946-g52006dd
tools.h
Go to the documentation of this file.
1/*
2 * Helper functions for the Wine tools
3 *
4 * Copyright 2021 Alexandre Julliard
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#ifndef __WINE_TOOLS_H
22#define __WINE_TOOLS_H
23
24#ifndef __WINE_CONFIG_H
25# error You must include config.h to use this header
26#endif
27
28#include <limits.h>
29#include <stdarg.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
33#include <sys/types.h>
34#include <sys/stat.h>
35#include <signal.h>
36#include <fcntl.h>
37#include <time.h>
38#include <errno.h>
39#ifdef HAVE_SYS_SYSCTL_H
40# include <sys/sysctl.h>
41#endif
42
43#ifdef _WIN32
44# include <direct.h>
45# include <io.h>
46# include <process.h>
47# define mkdir(path,mode) mkdir(path)
48# ifndef S_ISREG
49# define S_ISREG(mod) (((mod) & _S_IFMT) == _S_IFREG)
50# endif
51# ifdef _MSC_VER
52# define popen _popen
53# define pclose _pclose
54# define strtoll _strtoi64
55# define strtoull _strtoui64
56# define strncasecmp _strnicmp
57# define strcasecmp _stricmp
58# endif
59#ifdef __REACTOS__
60#define MAX_PATH 260
61#define ARRAYSIZE(x) (sizeof(x) / sizeof((x)[0]))
62#else
63# include <windef.h>
64# include <winbase.h>
65#endif
66#else
67extern char **environ;
68# include <spawn.h>
69# include <sys/wait.h>
70# include <unistd.h>
71# ifndef O_BINARY
72# define O_BINARY 0
73# endif
74# ifndef __int64
75# if defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__)
76# define __int64 long
77# else
78# define __int64 long long
79# endif
80# endif
81#endif
82
83#if !defined(__GNUC__) && !defined(__attribute__)
84#define __attribute__(x)
85#endif
86
87#ifndef max
88#define max(a,b) (((a) > (b)) ? (a) : (b))
89#endif
90#ifndef min
91#define min(a,b) (((a) < (b)) ? (a) : (b))
92#endif
93
94#ifndef ARRAY_SIZE
95#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
96#endif
97
98struct target
99{
101
102 enum
103 {
114};
115
116static inline void *xmalloc( size_t size )
117{
118 void *res = malloc( size ? size : 1 );
119
120 if (res == NULL)
121 {
122 fprintf( stderr, "Virtual memory exhausted.\n" );
123 exit(1);
124 }
125 return res;
126}
127
128static inline void *xrealloc (void *ptr, size_t size)
129{
130 void *res = realloc( ptr, size );
131
132 if (size && res == NULL)
133 {
134 fprintf( stderr, "Virtual memory exhausted.\n" );
135 exit(1);
136 }
137 return res;
138}
139
140static inline char *xstrdup( const char *str )
141{
142 return strcpy( xmalloc( strlen(str)+1 ), str );
143}
144
145static inline int strendswith( const char *str, const char *end )
146{
147 int l = strlen( str );
148 int m = strlen( end );
149 return l >= m && !strcmp( str + l - m, end );
150}
151
152static char *strmake( const char* fmt, ... ) __attribute__ ((__format__ (__printf__, 1, 2)));
153static inline char *strmake( const char* fmt, ... )
154{
155 int n;
156 size_t size = 100;
157 va_list ap;
158
159 for (;;)
160 {
161 char *p = xmalloc( size );
162 va_start( ap, fmt );
163 n = vsnprintf( p, size, fmt, ap );
164 va_end( ap );
165 if (n == -1) size *= 2;
166 else if ((size_t)n >= size) size = n + 1;
167 else return p;
168 free( p );
169 }
170}
171
172/* string array functions */
173
175{
176 unsigned int count; /* strings in use */
177 unsigned int size; /* total allocated size */
178 const char **str;
179};
180
181static const struct strarray empty_strarray;
182
183static inline void strarray_add( struct strarray *array, const char *str )
184{
185 if (array->count == array->size)
186 {
187 if (array->size) array->size *= 2;
188 else array->size = 16;
189 array->str = xrealloc( array->str, sizeof(array->str[0]) * array->size );
190 }
191 array->str[array->count++] = str;
192}
193
194static inline void strarray_addall( struct strarray *array, struct strarray added )
195{
196 unsigned int i;
197
198 for (i = 0; i < added.count; i++) strarray_add( array, added.str[i] );
199}
200
201static inline int strarray_exists( const struct strarray *array, const char *str )
202{
203 unsigned int i;
204
205 for (i = 0; i < array->count; i++) if (!strcmp( array->str[i], str )) return 1;
206 return 0;
207}
208
209static inline void strarray_add_uniq( struct strarray *array, const char *str )
210{
212}
213
214static inline void strarray_addall_uniq( struct strarray *array, struct strarray added )
215{
216 unsigned int i;
217
218 for (i = 0; i < added.count; i++) strarray_add_uniq( array, added.str[i] );
219}
220
221static inline struct strarray strarray_fromstring( const char *str, const char *delim )
222{
224 char *buf = xstrdup( str );
225 const char *tok;
226
227 for (tok = strtok( buf, delim ); tok; tok = strtok( NULL, delim ))
228 strarray_add( &array, xstrdup( tok ));
229 free( buf );
230 return array;
231}
232
233static inline struct strarray strarray_frompath( const char *path )
234{
235 if (!path) return empty_strarray;
236#ifdef _WIN32
237 return strarray_fromstring( path, ";" );
238#else
239 return strarray_fromstring( path, ":" );
240#endif
241}
242
243static inline char *strarray_tostring( struct strarray array, const char *sep )
244{
245 char *str;
246 unsigned int i, len = 1 + (array.count - 1) * strlen(sep);
247
248 if (!array.count) return xstrdup("");
249 for (i = 0; i < array.count; i++) len += strlen( array.str[i] );
250 str = xmalloc( len );
251 strcpy( str, array.str[0] );
252 for (i = 1; i < array.count; i++)
253 {
254 strcat( str, sep );
255 strcat( str, array.str[i] );
256 }
257 return str;
258}
259
260static inline void strarray_qsort( struct strarray *array, int (*func)(const char **, const char **) )
261{
262 if (array->count) qsort( array->str, array->count, sizeof(*array->str), (void *)func );
263}
264
265static inline const char *strarray_bsearch( const struct strarray *array, const char *str,
266 int (*func)(const char **, const char **) )
267{
268 char **res = NULL;
269
270 if (array->count) res = bsearch( &str, array->str, array->count, sizeof(*array->str), (void *)func );
271 return res ? *res : NULL;
272}
273
274static inline void strarray_trace( struct strarray args )
275{
276 unsigned int i;
277
278 for (i = 0; i < args.count; i++)
279 {
280 if (strpbrk( args.str[i], " \t\n\r")) printf( "\"%s\"", args.str[i] );
281 else printf( "%s", args.str[i] );
282 putchar( i < args.count - 1 ? ' ' : '\n' );
283 }
284}
285
286static inline int strarray_spawn( struct strarray args )
287{
288#ifdef _WIN32
290 return _spawnvp( _P_WAIT, args.str[0], args.str );
291#else
292 pid_t pid, wret;
293 int status;
294
296 if (posix_spawnp( &pid, args.str[0], NULL, NULL, (char **)args.str, environ ))
297 return -1;
298
299 while (pid != (wret = waitpid( pid, &status, 0 )))
300 if (wret == -1 && errno != EINTR) break;
301
302 if (pid == wret && WIFEXITED(status)) return WEXITSTATUS(status);
303 return 255; /* abnormal exit with an abort or an interrupt */
304#endif
305}
306
307static inline char *get_basename( const char *file )
308{
309 const char *ret = strrchr( file, '/' );
310 return xstrdup( ret ? ret + 1 : file );
311}
312
313static inline char *get_basename_noext( const char *file )
314{
315 char *ext, *ret = get_basename( file );
316 if ((ext = strrchr( ret, '.' ))) *ext = 0;
317 return ret;
318}
319
320static inline char *get_dirname( const char *file )
321{
322 const char *end = strrchr( file, '/' );
323 if (!end) return xstrdup( "." );
324 if (end == file) end++;
325 return strmake( "%.*s", (int)(end - file), file );
326}
327
328static inline char *replace_extension( const char *name, const char *old_ext, const char *new_ext )
329{
330 int name_len = strlen( name );
331
332 if (strendswith( name, old_ext )) name_len -= strlen( old_ext );
333 return strmake( "%.*s%s", name_len, name, new_ext );
334}
335
336/* build a path with the relative dir from 'from' to 'dest' appended to base */
337static inline char *build_relative_path( const char *base, const char *from, const char *dest )
338{
339 const char *start;
340 char *ret;
341 unsigned int dotdots = 0;
342
343 for (;;)
344 {
345 while (*from == '/') from++;
346 while (*dest == '/') dest++;
347 start = dest; /* save start of next path element */
348 if (!*from) break;
349
350 while (*from && *from != '/' && *from == *dest) { from++; dest++; }
351 if ((!*from || *from == '/') && (!*dest || *dest == '/')) continue;
352
353 do /* count remaining elements in 'from' */
354 {
355 dotdots++;
356 while (*from && *from != '/') from++;
357 while (*from == '/') from++;
358 }
359 while (*from);
360 break;
361 }
362
363 ret = xmalloc( strlen(base) + 3 * dotdots + strlen(start) + 2 );
364 strcpy( ret, base );
365 while (dotdots--) strcat( ret, "/.." );
366
367 if (!start[0]) return ret;
368 strcat( ret, "/" );
369 strcat( ret, start );
370 return ret;
371}
372
373/* temp files management */
374
375extern const char *temp_dir;
376extern struct strarray temp_files;
377
378static inline char *make_temp_dir(void)
379{
380 unsigned int value = time(NULL) + getpid();
381 int count;
382 char *name;
383 const char *tmpdir = NULL;
384
385 for (count = 0; count < 0x8000; count++)
386 {
387 if (tmpdir)
388 name = strmake( "%s/tmp%08x", tmpdir, value );
389 else
390 name = strmake( "tmp%08x", value );
391 if (!mkdir( name, 0700 )) return name;
392 value += 7777;
393 if (errno == EACCES && !tmpdir)
394 {
395#if defined(__REACTOS__) && defined(_WIN32)
396 if (!(tmpdir = getenv("TEMP"))) tmpdir = "temp";
397#else
398 if (!(tmpdir = getenv("TMPDIR"))) tmpdir = "/tmp";
399#endif
400 }
401 free( name );
402 }
403 fprintf( stderr, "failed to create directory for temp files\n" );
404 exit(1);
405}
406
407static inline char *make_temp_file( const char *prefix, const char *suffix )
408{
409 static unsigned int value;
410 int fd, count;
411 char *name;
412
414 if (!suffix) suffix = "";
415 if (!prefix) prefix = "tmp";
417
418 for (count = 0; count < 0x8000; count++)
419 {
420 name = strmake( "%s/%s-%08x%s", temp_dir, prefix, value++, suffix );
421 fd = open( name, O_RDWR | O_CREAT | O_EXCL, 0600 );
422 if (fd >= 0)
423 {
424#ifdef HAVE_SIGPROCMASK /* block signals while manipulating the temp files list */
425 sigset_t mask_set, old_set;
426
427 sigemptyset( &mask_set );
428 sigaddset( &mask_set, SIGHUP );
429 sigaddset( &mask_set, SIGTERM );
430 sigaddset( &mask_set, SIGINT );
431 sigprocmask( SIG_BLOCK, &mask_set, &old_set );
433 sigprocmask( SIG_SETMASK, &old_set, NULL );
434#else
436#endif
437 close( fd );
438 return name;
439 }
440 free( name );
441 }
442 fprintf( stderr, "failed to create temp file for %s%s in %s\n", prefix, suffix, temp_dir );
443 exit(1);
444}
445
446static inline void remove_temp_files(void)
447{
448 unsigned int i;
449
450 for (i = 0; i < temp_files.count; i++) if (temp_files.str[i]) unlink( temp_files.str[i] );
451 if (temp_dir) rmdir( temp_dir );
452}
453
454
455static inline void init_signals( void (*cleanup)(int) )
456{
459#ifdef SIGHUP
461#endif
462}
463
464
465static inline void *read_file( const char *name, size_t *size )
466{
467 struct stat st;
468 int res, fd;
469 void *data;
470
471 if ((fd = open( name, O_RDONLY | O_BINARY )) == -1) return NULL;
472 fstat( fd, &st );
473 data = xmalloc( st.st_size );
474 res = read( fd, data, st.st_size );
475 if (res == -1)
476 {
477 free( data );
478 data = NULL;
479 *size = 0;
480 }
481 else *size = res;
482 close( fd );
483 return data;
484}
485
486
487static inline struct target get_default_target(void)
488{
489 struct target target;
490#ifdef __i386__
492#elif defined(__x86_64__)
494#elif defined(__arm__)
496#elif defined(__aarch64__)
498#else
499#error Unsupported CPU
500#endif
501
502#ifdef __APPLE__
504#elif defined(__ANDROID__)
506#elif defined(__linux__)
508#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
510#elif defined(__sun)
512#elif defined(__CYGWIN__)
514#elif defined(_WIN32)
516#else
518#endif
519
520 return target;
521}
522
523
524static inline unsigned int get_target_ptr_size( struct target target )
525{
526 static const unsigned int sizes[] =
527 {
528 [CPU_i386] = 4,
529 [CPU_x86_64] = 8,
530 [CPU_ARM] = 4,
531 [CPU_ARM64] = 8,
532 [CPU_ARM64EC] = 8,
533 };
534 return sizes[target.cpu];
535}
536
537
538static inline void set_target_ptr_size( struct target *target, unsigned int size )
539{
540 switch (target->cpu)
541 {
542 case CPU_i386:
543 if (size == 8) target->cpu = CPU_x86_64;
544 break;
545 case CPU_x86_64:
546 if (size == 4) target->cpu = CPU_i386;
547 break;
548 case CPU_ARM:
549 if (size == 8) target->cpu = CPU_ARM64;
550 break;
551 case CPU_ARM64:
552 case CPU_ARM64EC:
553 if (size == 4) target->cpu = CPU_ARM;
554 break;
555 }
556}
557
558
559static inline int get_cpu_from_name( const char *name )
560{
561 static const struct
562 {
563 const char *name;
564 int cpu;
565 } cpu_names[] =
566 {
567 { "i386", CPU_i386 },
568 { "i486", CPU_i386 },
569 { "i586", CPU_i386 },
570 { "i686", CPU_i386 },
571 { "i786", CPU_i386 },
572 { "x86_64", CPU_x86_64 },
573 { "amd64", CPU_x86_64 },
574 { "aarch64", CPU_ARM64 },
575 { "arm64ec", CPU_ARM64EC },
576 { "arm64", CPU_ARM64 },
577 { "arm", CPU_ARM },
578 };
579 unsigned int i;
580
581 for (i = 0; i < ARRAY_SIZE(cpu_names); i++)
582 if (!strncmp( cpu_names[i].name, name, strlen(cpu_names[i].name) )) return cpu_names[i].cpu;
583 return -1;
584}
585
586
587static inline int get_platform_from_name( const char *name )
588{
589 static const struct
590 {
591 const char *name;
592 int platform;
593 } platform_names[] =
594 {
595 { "macos", PLATFORM_APPLE },
596 { "darwin", PLATFORM_APPLE },
597 { "android", PLATFORM_ANDROID },
598 { "linux", PLATFORM_LINUX },
599 { "freebsd", PLATFORM_FREEBSD },
600 { "solaris", PLATFORM_SOLARIS },
601 { "mingw32", PLATFORM_MINGW },
602 { "windows-gnu", PLATFORM_MINGW },
603 { "winnt", PLATFORM_MINGW },
604 { "windows", PLATFORM_WINDOWS },
605 { "cygwin", PLATFORM_CYGWIN },
606 };
607 unsigned int i;
608
609 for (i = 0; i < ARRAY_SIZE(platform_names); i++)
610 if (!strncmp( platform_names[i].name, name, strlen(platform_names[i].name) ))
611 return platform_names[i].platform;
612 return -1;
613};
614
615
616static inline const char *get_arch_dir( struct target target )
617{
618 static const char *cpu_names[] =
619 {
620 [CPU_i386] = "i386",
621 [CPU_x86_64] = "x86_64",
622 [CPU_ARM] = "arm",
623 [CPU_ARM64] = "aarch64",
624 [CPU_ARM64EC] = "aarch64",
625 };
626
627 if (!cpu_names[target.cpu]) return "";
628
629 switch (target.platform)
630 {
631 case PLATFORM_WINDOWS:
632 case PLATFORM_CYGWIN:
633 case PLATFORM_MINGW:
634 return strmake( "/%s-windows", cpu_names[target.cpu] );
635 default:
636 return strmake( "/%s-unix", cpu_names[target.cpu] );
637 }
638}
639
640static inline int parse_target( const char *name, struct target *target )
641{
642 int res;
643 char *p, *spec = xstrdup( name );
644
645 /* target specification is in the form CPU-MANUFACTURER-OS or CPU-MANUFACTURER-KERNEL-OS */
646
647 /* get the CPU part */
648
649 if ((p = strchr( spec, '-' )))
650 {
651 *p++ = 0;
652 if ((res = get_cpu_from_name( spec )) == -1)
653 {
654 free( spec );
655 return 0;
656 }
657 target->cpu = res;
658 }
659 else if (!strcmp( spec, "mingw32" ))
660 {
662 p = spec;
663 }
664 else
665 {
666 free( spec );
667 return 0;
668 }
669
670 /* get the OS part */
671
672 target->platform = PLATFORM_UNSPECIFIED; /* default value */
673 for (;;)
674 {
675 if ((res = get_platform_from_name( p )) != -1)
676 {
678 break;
679 }
680 if (!(p = strchr( p, '-' ))) break;
681 p++;
682 }
683
684 free( spec );
685 return 1;
686}
687
688
689static inline struct target init_argv0_target( const char *argv0 )
690{
691 char *name = get_basename( argv0 );
692 struct target target;
693
694 if (!strchr( name, '-' ) || !parse_target( name, &target ))
696
697 free( name );
698 return target;
699}
700
701
702static inline char *get_bindir( const char *argv0 )
703{
704#ifdef __REACTOS__
705 return NULL;
706#else
707#ifndef _WIN32
708 char *dir = NULL;
709
710#if defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) \
711 || defined(__CYGWIN__) || defined(__MSYS__)
712 dir = realpath( "/proc/self/exe", NULL );
713#elif defined (__FreeBSD__) || defined(__DragonFly__)
714 static int pathname[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
715 size_t path_size = PATH_MAX;
716 char *path = xmalloc( path_size );
717 if (!sysctl( pathname, ARRAY_SIZE(pathname), path, &path_size, NULL, 0 ))
718 dir = realpath( path, NULL );
719 free( path );
720#endif
721 if (!dir && !(dir = realpath( argv0, NULL ))) return NULL;
722 return get_dirname( dir );
723#else
724 char path[MAX_PATH], *p;
726 for (p = path; *p; p++) if (*p == '\\') *p = '/';
727 return get_dirname( path );
728#endif
729#endif
730}
731
732#ifdef LIBDIR
733static inline const char *get_libdir( const char *bindir )
734{
735#ifdef BINDIR
736 if (bindir) return build_relative_path( bindir, BINDIR, LIBDIR );
737#endif
738 return LIBDIR;
739}
740#endif
741
742#ifdef DATADIR
743static inline const char *get_datadir( const char *bindir )
744{
745#ifdef BINDIR
746 if (bindir) return build_relative_path( bindir, BINDIR, DATADIR );
747#endif
748 return DATADIR;
749}
750#endif
751
752#ifdef INCLUDEDIR
753static inline const char *get_includedir( const char *bindir )
754{
755#ifdef BINDIR
756 if (bindir) return build_relative_path( bindir, BINDIR, INCLUDEDIR );
757#endif
758 return INCLUDEDIR;
759}
760#endif
761
762static inline const char *get_nlsdir( const char *bindir, const char *srcdir )
763{
764 if (bindir && strendswith( bindir, srcdir )) return strmake( "%s/../../nls", bindir );
765#ifdef DATADIR
766 else
767 {
768 const char *datadir = get_datadir( bindir );
769 if (datadir) return strmake( "%s/wine/nls", datadir );
770 }
771#endif
772 return NULL;
773}
774
775
776/* output buffer management */
777
778extern unsigned char *output_buffer;
779extern size_t output_buffer_pos;
780extern size_t output_buffer_size;
781
782static inline void check_output_buffer_space( size_t size )
783{
785 {
788 }
789}
790
791static inline void init_output_buffer(void)
792{
793 output_buffer_size = 1024;
796}
797
798static inline void put_data( const void *data, size_t size )
799{
803}
804
805static inline void put_byte( unsigned char val )
806{
809}
810
811static inline void put_word( unsigned short val )
812{
816}
817
818static inline void put_dword( unsigned int val )
819{
825}
826
827static inline void put_qword( unsigned int val )
828{
829 put_dword( val );
830 put_dword( 0 );
831}
832
833static inline void align_output( unsigned int align )
834{
835 size_t size = align - (output_buffer_pos % align);
836
837 if (size == align) return;
841}
842
843static inline void flush_output_buffer( const char *name )
844{
845 int fd = open( name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666 );
846
848 {
849 perror( name );
850 exit(1);
851 }
852 close( fd );
854}
855
856/* command-line option parsing */
857/* partly based on the Glibc getopt() implementation */
858
860{
861 const char *name;
863 int val;
864};
865
866static inline struct strarray parse_options( int argc, char **argv, const char *short_opts,
867 const struct long_option *long_opts, int long_only,
868 void (*callback)( int, char* ) )
869{
870 struct strarray ret = empty_strarray;
871 const char *flag;
872 char *start, *end;
873 int i;
874
875#define OPT_ERR(fmt) { callback( '?', strmake( fmt, argv[i] )); continue; }
876
877 for (i = 1; i < argc; i++)
878 {
879 if (argv[i][0] != '-' || !argv[i][1]) /* not an option */
880 {
881 strarray_add( &ret, argv[i] );
882 continue;
883 }
884 if (!strcmp( argv[i], "--" ))
885 {
886 /* add remaining args */
887 while (++i < argc) strarray_add( &ret, argv[i] );
888 break;
889 }
890 start = argv[i] + 1 + (argv[i][1] == '-');
891
892 if (argv[i][1] == '-' || (long_only && (argv[i][2] || !strchr( short_opts, argv[i][1] ))))
893 {
894 /* handle long option */
895 const struct long_option *opt, *found = NULL;
896 int count = 0;
897
898 if (!(end = strchr( start, '=' ))) end = start + strlen(start);
899 for (opt = long_opts; opt && opt->name; opt++)
900 {
901 if (strncmp( opt->name, start, end - start )) continue;
902 if (!opt->name[end - start]) /* exact match */
903 {
904 found = opt;
905 count = 1;
906 break;
907 }
908 if (!found)
909 {
910 found = opt;
911 count++;
912 }
913 else if (long_only || found->has_arg != opt->has_arg || found->val != opt->val)
914 {
915 count++;
916 }
917 }
918
919 if (count > 1) OPT_ERR( "option '%s' is ambiguous" );
920
921 if (found)
922 {
923 if (*end)
924 {
925 if (!found->has_arg) OPT_ERR( "argument not allowed in '%s'" );
926 end++; /* skip '=' */
927 }
928 else if (found->has_arg == 1)
929 {
930 if (i == argc - 1) OPT_ERR( "option '%s' requires an argument" );
931 end = argv[++i];
932 }
933 else end = NULL;
934
935 callback( found->val, end );
936 continue;
937 }
938 if (argv[i][1] == '-' || !long_only || !strchr( short_opts, argv[i][1] ))
939 OPT_ERR( "unrecognized option '%s'" );
940 }
941
942 /* handle short option */
943 for ( ; *start; start++)
944 {
945 if (!(flag = strchr( short_opts, *start ))) OPT_ERR( "invalid option '%s'" );
946 if (flag[1] == ':')
947 {
948 end = start + 1;
949 if (!*end) end = NULL;
950 if (flag[2] != ':' && !end)
951 {
952 if (i == argc - 1) OPT_ERR( "option '%s' requires an argument" );
953 end = argv[++i];
954 }
955 callback( *start, end );
956 break;
957 }
958 callback( *start, NULL );
959 }
960 }
961 return ret;
962#undef OPT_ERR
963}
964
965#endif /* __WINE_TOOLS_H */
static int argc
Definition: ServiceArgs.c:12
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define EINTR
Definition: acclib.h:80
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
#define EACCES
Definition: acclib.h:85
char * strtok(char *String, const char *Delimiters)
Definition: utclib.c:338
char * strchr(const char *String, int ch)
Definition: utclib.c:501
char * strpbrk(const char *String, const char *Delimiters)
Definition: utclib.c:302
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
#define O_WRONLY
Definition: acwin.h:111
#define O_CREAT
Definition: acwin.h:110
#define mkdir
Definition: acwin.h:101
#define read
Definition: acwin.h:96
#define O_RDONLY
Definition: acwin.h:108
#define open
Definition: acwin.h:95
#define close
Definition: acwin.h:98
#define fstat
Definition: acwin.h:100
#define write
Definition: acwin.h:97
#define O_TRUNC
Definition: acwin.h:112
unsigned int dir
Definition: maze.c:112
#define PATH_MAX
Definition: types.h:280
r l[0]
Definition: byte_order.h:168
#define LIBDIR
Definition: create_nls.c:23
void __cdecl qsort(_Inout_updates_bytes_(_NumOfElements *_SizeOfElements) void *_Base, _In_ size_t _NumOfElements, _In_ size_t _SizeOfElements, _In_ int(__cdecl *_PtFuncCompare)(const void *, const void *))
#define SIGHUP
Definition: signal.h:22
#define SIGINT
Definition: signal.h:23
#define SIGTERM
Definition: signal.h:39
int putchar(int c)
Definition: crtsupp.c:12
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define put_byte(s, c)
Definition: deflate.h:276
#define NULL
Definition: types.h:112
DWORD pid_t
Definition: types.h:91
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define MAX_PATH
Definition: compat.h:34
static const WCHAR *const ext[]
Definition: module.c:53
static void cleanup(void)
Definition: main.c:1335
DWORD WINAPI GetModuleFileNameA(HINSTANCE hModule, LPSTR lpFilename, DWORD nSize)
Definition: loader.c:539
unsigned char
Definition: typeof.h:29
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
return ret
Definition: mutex.c:146
int align(int length, int align)
Definition: dsound8.c:36
#define printf
Definition: freeldr.h:97
GLuint start
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLenum func
Definition: glext.h:6028
GLdouble n
Definition: glext.h:7729
GLuint res
Definition: glext.h:9613
GLsizeiptr size
Definition: glext.h:5919
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint GLfloat * val
Definition: glext.h:7180
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
const GLfloat * m
Definition: glext.h:10848
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 flag
Definition: glfuncs.h:52
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
#define O_EXCL
Definition: fcntl.h:40
#define O_RDWR
Definition: fcntl.h:36
_CRTIMP void __cdecl perror(_In_opt_z_ const char *_ErrMsg)
#define stderr
Definition: stdio.h:100
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define unlink
Definition: syshdrs.h:54
__u16 time
Definition: mkdosfs.c:8
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
char pathname[512]
Definition: util.h:13
static PVOID ptr
Definition: dispmode.c:27
static IPrintDialogCallback callback
Definition: printdlg.c:326
static char * dest
Definition: rtl.c:135
#define _P_WAIT
Definition: port.h:370
static const struct @594 sizes[]
#define argv
Definition: mplay32.c:18
platform
Definition: msipriv.h:364
#define rmdir
Definition: syshdrs.h:70
const WCHAR * str
#define errno
Definition: errno.h:18
_CRTIMP intptr_t __cdecl _spawnvp(_In_ int _Mode, _In_z_ const char *_Filename, _In_z_ const char *const *_ArgList)
_Check_return_ char *__cdecl getenv(_In_z_ const char *_VarName)
_CRT_RESTORE_GCC_WARNINGS _CRT_DISABLE_GCC_WARNINGS _Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
#define inline
Definition: compat.h:23
strcat
Definition: string.h:92
strcpy
Definition: string.h:131
#define exit(n)
Definition: config.h:202
int signal
Definition: except.c:84
static int fd
Definition: io.c:51
#define memset(x, y, z)
Definition: compat.h:39
static void strarray_qsort(struct strarray *array, int(*func)(const char **, const char **))
Definition: tools.h:260
static void strarray_add(struct strarray *array, const char *str)
Definition: tools.h:183
static char * make_temp_dir(void)
Definition: tools.h:378
static char * get_bindir(const char *argv0)
Definition: tools.h:702
static char * strmake(const char *fmt,...) __attribute__((__format__(__printf__
Definition: tools.h:153
static void * xrealloc(void *ptr, size_t size)
Definition: tools.h:128
static char * strarray_tostring(struct strarray array, const char *sep)
Definition: tools.h:243
#define O_BINARY
Definition: tools.h:72
size_t output_buffer_pos
Definition: utils.c:164
static int get_cpu_from_name(const char *name)
Definition: tools.h:559
size_t output_buffer_size
Definition: utils.c:165
static int strendswith(const char *str, const char *end)
Definition: tools.h:145
static char * xstrdup(const char *str)
Definition: tools.h:140
static char * get_basename(const char *file)
Definition: tools.h:307
static struct strarray strarray_frompath(const char *path)
Definition: tools.h:233
static void align_output(unsigned int align)
Definition: tools.h:833
const char * temp_dir
Definition: widl.c:134
static void init_output_buffer(void)
Definition: tools.h:791
static void strarray_addall(struct strarray *array, struct strarray added)
Definition: tools.h:194
static void set_target_ptr_size(struct target *target, unsigned int size)
Definition: tools.h:538
static void put_data(const void *data, size_t size)
Definition: tools.h:798
static const struct strarray empty_strarray
Definition: tools.h:181
static const char * get_arch_dir(struct target target)
Definition: tools.h:616
#define ARRAY_SIZE(x)
Definition: tools.h:95
static void flush_output_buffer(const char *name)
Definition: tools.h:843
static void strarray_trace(struct strarray args)
Definition: tools.h:274
static struct strarray parse_options(int argc, char **argv, const char *short_opts, const struct long_option *long_opts, int long_only, void(*callback)(int, char *))
Definition: tools.h:866
static const char * get_nlsdir(const char *bindir, const char *srcdir)
Definition: tools.h:762
static char * make_temp_file(const char *prefix, const char *suffix)
Definition: tools.h:407
static int parse_target(const char *name, struct target *target)
Definition: tools.h:640
static int get_platform_from_name(const char *name)
Definition: tools.h:587
static struct target get_default_target(void)
Definition: tools.h:487
static void remove_temp_files(void)
Definition: tools.h:446
#define OPT_ERR(fmt)
static void init_signals(void(*cleanup)(int))
Definition: tools.h:455
static char * get_dirname(const char *file)
Definition: tools.h:320
static void put_dword(unsigned int val)
Definition: tools.h:818
static void put_qword(unsigned int val)
Definition: tools.h:827
char ** environ
static unsigned int get_target_ptr_size(struct target target)
Definition: tools.h:524
struct strarray temp_files
Definition: widl.c:133
static char * build_relative_path(const char *base, const char *from, const char *dest)
Definition: tools.h:337
static char * get_basename_noext(const char *file)
Definition: tools.h:313
static char * replace_extension(const char *name, const char *old_ext, const char *new_ext)
Definition: tools.h:328
static const char * strarray_bsearch(const struct strarray *array, const char *str, int(*func)(const char **, const char **))
Definition: tools.h:265
static void check_output_buffer_space(size_t size)
Definition: tools.h:782
static int strarray_exists(const struct strarray *array, const char *str)
Definition: tools.h:201
static struct strarray strarray_fromstring(const char *str, const char *delim)
Definition: tools.h:221
static void put_word(unsigned short val)
Definition: tools.h:811
unsigned char * output_buffer
Definition: utils.c:163
static void strarray_addall_uniq(struct strarray *array, struct strarray added)
Definition: tools.h:214
static int strarray_spawn(struct strarray args)
Definition: tools.h:286
static void * read_file(const char *name, size_t *size)
Definition: tools.h:465
static void * xmalloc(size_t size)
Definition: tools.h:116
static void strarray_add_uniq(struct strarray *array, const char *str)
Definition: tools.h:209
static struct target init_argv0_target(const char *argv0)
Definition: tools.h:689
#define max(a, b)
Definition: tools.h:88
static char tmpdir[MAX_PATH]
Definition: shlexec.c:52
static char argv0[MAX_PATH]
Definition: shlexec.c:49
CardRegion * from
Definition: spigame.cpp:19
Definition: match.c:390
Definition: fci.c:127
Definition: dsound.c:943
int val
Definition: tools.h:863
const char * name
Definition: tools.h:861
int has_arg
Definition: tools.h:862
Definition: name.c:39
Definition: stat.h:55
_off_t st_size
Definition: stat.h:63
Definition: ps.c:97
unsigned int count
Definition: tools.h:176
unsigned int size
Definition: tools.h:177
const char ** str
Definition: tools.h:178
Definition: tools.h:99
@ CPU_ARM64EC
Definition: tools.h:100
@ CPU_x86_64
Definition: tools.h:100
@ CPU_ARM
Definition: tools.h:100
@ CPU_ARM64
Definition: tools.h:100
@ CPU_i386
Definition: tools.h:100
enum target::@5353 platform
@ PLATFORM_APPLE
Definition: tools.h:105
@ PLATFORM_LINUX
Definition: tools.h:107
@ PLATFORM_SOLARIS
Definition: tools.h:109
@ PLATFORM_MINGW
Definition: tools.h:111
@ PLATFORM_FREEBSD
Definition: tools.h:108
@ PLATFORM_WINDOWS
Definition: tools.h:110
@ PLATFORM_UNSPECIFIED
Definition: tools.h:104
@ PLATFORM_CYGWIN
Definition: tools.h:112
@ PLATFORM_ANDROID
Definition: tools.h:106
enum target::@5352 cpu
Character const *const prefix
Definition: tempnam.cpp:195
#define bsearch
#define vsnprintf
Definition: tif_win32.c:406
Definition: pdh_main.c:96
static const char * bindir
Definition: widl.c:137
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3837
void int int ULONGLONG int va_list * ap
Definition: winesup.h:36
#define getpid
Definition: wintirpc.h:52
#define const
Definition: zconf.h:233