From 6311297c158d91459fad2b4269d9a070fabc5a5b Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 25 Jun 2024 11:33:46 +0200 Subject: [PATCH] tools: Add helper functions to get the standard directories. --- tools/tools.h | 82 ++++++++++++++++++++++++++++++++++++++- tools/widl/Makefile.in | 6 +-- tools/widl/widl.c | 24 +++++------- tools/winegcc/Makefile.in | 3 +- tools/winegcc/winegcc.c | 11 ++---- tools/wmc/Makefile.in | 4 +- tools/wmc/wmc.c | 15 ++----- tools/wrc/Makefile.in | 6 +-- tools/wrc/wrc.c | 17 +++----- 9 files changed, 106 insertions(+), 62 deletions(-) diff --git a/tools/tools.h b/tools/tools.h index 076f22d7dad..39441cb0ea6 100644 --- a/tools/tools.h +++ b/tools/tools.h @@ -326,6 +326,43 @@ static inline char *replace_extension( const char *name, const char *old_ext, co return strmake( "%.*s%s", name_len, name, new_ext ); } +/* build a path with the relative dir from 'from' to 'dest' appended to base */ +static inline char *build_relative_path( const char *base, const char *from, const char *dest ) +{ + const char *start; + char *ret; + unsigned int dotdots = 0; + + for (;;) + { + while (*from == '/') from++; + while (*dest == '/') dest++; + start = dest; /* save start of next path element */ + if (!*from) break; + + while (*from && *from != '/' && *from == *dest) { from++; dest++; } + if ((!*from || *from == '/') && (!*dest || *dest == '/')) continue; + + do /* count remaining elements in 'from' */ + { + dotdots++; + while (*from && *from != '/') from++; + while (*from == '/') from++; + } + while (*from); + break; + } + + ret = xmalloc( strlen(base) + 3 * dotdots + strlen(start) + 2 ); + strcpy( ret, base ); + while (dotdots--) strcat( ret, "/.." ); + + if (!start[0]) return ret; + strcat( ret, "/" ); + strcat( ret, start ); + return ret; +} + /* temp files management */ extern const char *temp_dir; @@ -651,7 +688,7 @@ static inline struct target init_argv0_target( const char *argv0 ) } -static inline char *get_argv0_dir( const char *argv0 ) +static inline char *get_bindir( const char *argv0 ) { #ifndef _WIN32 char *dir = NULL; @@ -673,6 +710,49 @@ static inline char *get_argv0_dir( const char *argv0 ) #endif } +#ifdef LIBDIR +static inline const char *get_libdir( const char *bindir ) +{ +#ifdef BINDIR + if (bindir) return build_relative_path( bindir, BINDIR, LIBDIR ); +#endif + return LIBDIR; +} +#endif + +#ifdef DATADIR +static inline const char *get_datadir( const char *bindir ) +{ +#ifdef BINDIR + if (bindir) return build_relative_path( bindir, BINDIR, DATADIR ); +#endif + return DATADIR; +} +#endif + +#ifdef INCLUDEDIR +static inline const char *get_includedir( const char *bindir ) +{ +#ifdef BINDIR + if (bindir) return build_relative_path( bindir, BINDIR, INCLUDEDIR ); +#endif + return INCLUDEDIR; +} +#endif + +static inline const char *get_nlsdir( const char *bindir, const char *srcdir ) +{ + if (bindir && strendswith( bindir, srcdir )) return strmake( "%s/../../nls", bindir ); +#ifdef DATADIR + else + { + const char *datadir = get_datadir( bindir ); + if (datadir) return strmake( "%s/wine/nls", datadir ); + } +#endif + return NULL; +} + /* output buffer management */ diff --git a/tools/widl/Makefile.in b/tools/widl/Makefile.in index fee965d49db..4caabd87ba7 100644 --- a/tools/widl/Makefile.in +++ b/tools/widl/Makefile.in @@ -24,10 +24,6 @@ SOURCES = \ write_msft.c \ write_sltg.c -widl_EXTRADEFS = \ - -DINCLUDEDIR="\"${includedir}\"" \ - -DDLLDIR="\"${libdir}/wine\"" \ - -DBIN_TO_INCLUDEDIR=\"`${MAKEDEP} -R ${bindir} ${includedir}`\" \ - -DBIN_TO_DLLDIR=\"`${MAKEDEP} -R ${bindir} ${libdir}/wine`\" +widl_EXTRADEFS = -DINCLUDEDIR="\"${includedir}\"" -DBINDIR="\"${bindir}\"" -DLIBDIR="\"${libdir}\"" INSTALL_DEV = $(PROGRAMS) diff --git a/tools/widl/widl.c b/tools/widl/widl.c index ef68259157b..6eb81d12860 100644 --- a/tools/widl/widl.c +++ b/tools/widl/widl.c @@ -134,8 +134,9 @@ struct strarray temp_files = { 0 }; const char *temp_dir = NULL; const char *prefix_client = ""; const char *prefix_server = ""; +static const char *bindir; +static const char *libdir; static const char *includedir; -static const char *dlldir; static struct strarray dlldirs; static char *output_name; static const char *sysroot = ""; @@ -469,15 +470,6 @@ void write_id_data(const statement_list_t *stmts) fclose(idfile); } -static void init_argv0_dir( const char *argv0 ) -{ - char *dir = get_argv0_dir( argv0 ); - - if (!dir) return; - includedir = strmake( "%s/%s", dir, BIN_TO_INCLUDEDIR ); - dlldir = strmake( "%s/%s", dir, BIN_TO_DLLDIR ); -} - static void option_callback( int optc, char *optarg ) { switch (optc) @@ -643,7 +635,7 @@ static void option_callback( int optc, char *optarg ) int open_typelib( const char *name ) { - static const char *default_dirs[] = { DLLDIR, "/usr/lib/wine", "/usr/local/lib/wine" }; + static const char *default_dirs[] = { LIBDIR "/wine", "/usr/lib/wine", "/usr/local/lib/wine" }; struct target win_target = { target.cpu, PLATFORM_WINDOWS }; const char *pe_dir = get_arch_dir( win_target ); int fd; @@ -672,10 +664,10 @@ int open_typelib( const char *name ) if (stdinc) { - if (dlldir) + if (libdir) { - TRYOPEN( strmake( "%s%s/%s", dlldir, pe_dir, name )); - TRYOPEN( strmake( "%s/%s", dlldir, name )); + TRYOPEN( strmake( "%s/wine%s/%s", libdir, pe_dir, name )); + TRYOPEN( strmake( "%s/wine/%s", libdir, name )); } for (i = 0; i < ARRAY_SIZE(default_dirs); i++) { @@ -694,7 +686,9 @@ int main(int argc,char *argv[]) struct strarray files; init_signals( exit_on_signal ); - init_argv0_dir( argv[0] ); + bindir = get_bindir( argv[0] ); + libdir = get_libdir( bindir ); + includedir = get_includedir( bindir ); target = init_argv0_target( argv[0] ); now = time(NULL); diff --git a/tools/winegcc/Makefile.in b/tools/winegcc/Makefile.in index 37749545807..9adf978b7aa 100644 --- a/tools/winegcc/Makefile.in +++ b/tools/winegcc/Makefile.in @@ -9,9 +9,8 @@ winegcc_SYMLINKS = winecpp wineg++ winegcc_EXTRADEFS = \ -DINCLUDEDIR="\"${includedir}\"" \ + -DBINDIR="\"${bindir}\"" \ -DLIBDIR="\"${libdir}\"" \ - -DBIN_TO_INCLUDEDIR=\"`${MAKEDEP} -R ${bindir} ${includedir}`\" \ - -DBIN_TO_LIBDIR=\"`${MAKEDEP} -R ${bindir} ${libdir}`\" \ -DCC="\"$(CC)\"" \ -DCPP="\"$(CPPBIN)\"" \ -DCXX="\"$(CXX)\"" \ diff --git a/tools/winegcc/winegcc.c b/tools/winegcc/winegcc.c index fb759063da9..a6b91a4edc6 100644 --- a/tools/winegcc/winegcc.c +++ b/tools/winegcc/winegcc.c @@ -611,13 +611,6 @@ static char *get_lib_dir( struct options *opts ) return strmake( "%s%s", root, LIBDIR ); } -static void init_argv0_dir( const char *argv0 ) -{ - if (!(bindir = get_argv0_dir( argv0 ))) return; - includedir = strmake( "%s/%s", bindir, BIN_TO_INCLUDEDIR ); - libdir = strmake( "%s/%s", bindir, BIN_TO_LIBDIR ); -} - static void compile(struct options* opts, const char* lang) { struct strarray comp_args = get_translator(opts); @@ -1489,7 +1482,9 @@ int main(int argc, char **argv) char* str; init_signals( exit_on_signal ); - init_argv0_dir( argv[0] ); + bindir = get_bindir( argv[0] ); + libdir = get_libdir( bindir ); + includedir = get_includedir( bindir ); /* setup tmp file removal at exit */ atexit(clean_temp_files); diff --git a/tools/wmc/Makefile.in b/tools/wmc/Makefile.in index 1c2c72360b7..6eda097f2a6 100644 --- a/tools/wmc/Makefile.in +++ b/tools/wmc/Makefile.in @@ -11,8 +11,6 @@ SOURCES = \ wmc.man.in \ write.c -wmc_EXTRADEFS = \ - -DNLSDIR="\"${datadir}/wine/nls\"" \ - -DBIN_TO_NLSDIR=\"`${MAKEDEP} -R ${bindir} ${datadir}/wine/nls`\" +wmc_EXTRADEFS = -DBINDIR="\"${bindir}\"" -DDATADIR="\"${datadir}\"" INSTALL_DEV = $(PROGRAMS) diff --git a/tools/wmc/wmc.c b/tools/wmc/wmc.c index e4f2377e772..51c0b9a4d30 100644 --- a/tools/wmc/wmc.c +++ b/tools/wmc/wmc.c @@ -94,7 +94,8 @@ char *output_name = NULL; /* The name given by the -o option */ const char *input_name = NULL; /* The name given on the command-line */ char *header_name = NULL; /* The name given by the -H option */ -const char *nlsdirs[3] = { NULL, NLSDIR, NULL }; +static const char *bindir; +const char *nlsdirs[3] = { NULL, DATADIR "/wine/nls", NULL }; int line_number = 1; /* The current line */ int char_number = 1; /* The current char pos within the line */ @@ -143,15 +144,6 @@ static void exit_on_signal( int sig ) exit(1); /* this will call the atexit functions */ } -static void init_argv0_dir( const char *argv0 ) -{ - char *dir = get_argv0_dir( argv0 ); - - if (!dir) return; - if (strendswith( dir, "/tools/wmc" )) nlsdirs[0] = strmake( "%s/../../nls", dir ); - else nlsdirs[0] = strmake( "%s/%s", dir, BIN_TO_NLSDIR ); -} - static void option_callback( int optc, char *optarg ) { switch(optc) @@ -221,7 +213,8 @@ int main(int argc,char *argv[]) atexit( cleanup_files ); init_signals( exit_on_signal ); - init_argv0_dir( argv[0] ); + bindir = get_bindir( argv[0] ); + nlsdirs[0] = get_nlsdir( bindir, "/tools/wmc" ); /* First rebuild the commandline to put in destination */ /* Could be done through env[], but not all OS-es support it */ diff --git a/tools/wrc/Makefile.in b/tools/wrc/Makefile.in index 54cde2e98fd..7e05fd74c24 100644 --- a/tools/wrc/Makefile.in +++ b/tools/wrc/Makefile.in @@ -14,10 +14,6 @@ SOURCES = \ wrc.c \ wrc.man.in -wrc_EXTRADEFS = \ - -DNLSDIR="\"${datadir}/wine/nls\"" \ - -DINCLUDEDIR="\"${includedir}\"" \ - -DBIN_TO_NLSDIR=\"`${MAKEDEP} -R ${bindir} ${datadir}/wine/nls`\" \ - -DBIN_TO_INCLUDEDIR=\"`${MAKEDEP} -R ${bindir} ${includedir}`\" +wrc_EXTRADEFS = -DBINDIR="\"${bindir}\"" -DDATADIR="\"${datadir}\"" -DINCLUDEDIR="\"${includedir}\"" INSTALL_DEV = $(PROGRAMS) diff --git a/tools/wrc/wrc.c b/tools/wrc/wrc.c index 48d5d2033d8..36f439ff88e 100644 --- a/tools/wrc/wrc.c +++ b/tools/wrc/wrc.c @@ -137,8 +137,9 @@ static int stdinc = 1; static int po_mode; static const char *po_dir; static const char *sysroot = ""; +static const char *bindir; static const char *includedir; -const char *nlsdirs[3] = { NULL, NLSDIR, NULL }; +const char *nlsdirs[3] = { NULL, DATADIR "/wine/nls", NULL }; int line_number = 1; /* The current line */ int char_number = 1; /* The current char pos within the line */ @@ -282,16 +283,6 @@ static int load_file( const char *input_name, const char *output_name ) return ret; } -static void init_argv0_dir( const char *argv0 ) -{ - char *dir = get_argv0_dir( argv0 ); - - if (!dir) return; - includedir = strmake( "%s/%s", dir, BIN_TO_INCLUDEDIR ); - if (strendswith( dir, "/tools/wrc" )) nlsdirs[0] = strmake( "%s/../../nls", dir ); - else nlsdirs[0] = strmake( "%s/%s", dir, BIN_TO_NLSDIR ); -} - static void option_callback( int optc, char *optarg ) { switch(optc) @@ -396,7 +387,9 @@ int main(int argc,char *argv[]) int i; init_signals( exit_on_signal ); - init_argv0_dir( argv[0] ); + bindir = get_bindir( argv[0] ); + includedir = get_includedir( bindir ); + nlsdirs[0] = get_nlsdir( bindir, "/tools/wrc" ); /* Set the default defined stuff */ set_version_defines();