From: Peter Johnson Date: Sat, 13 Feb 2010 08:42:27 +0000 (-0000) Subject: vsyasm: create intermediate output directories if necessary. X-Git-Tag: v1.0.0~24 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c699637602d24bc29413d12a4165eb47a1251769;p=yasm vsyasm: create intermediate output directories if necessary. This feature is apparently assumed by MSBUILD. Contributed (with minor modifications) by: Brian Gladman svn path=/trunk/yasm/; revision=2287 --- diff --git a/configure.ac b/configure.ac index 501b7525..638d654a 100644 --- a/configure.ac +++ b/configure.ac @@ -105,7 +105,7 @@ AM_WITH_DMALLOC # Checks for header files. # AC_HEADER_STDC -AC_CHECK_HEADERS([strings.h libgen.h unistd.h direct.h]) +AC_CHECK_HEADERS([strings.h libgen.h unistd.h direct.h sys/stat.h]) # REQUIRE standard C headers if test "$ac_cv_header_stdc" != yes; then diff --git a/frontends/vsyasm/vsyasm.c b/frontends/vsyasm/vsyasm.c index 43a478d8..5983a954 100644 --- a/frontends/vsyasm/vsyasm.c +++ b/frontends/vsyasm/vsyasm.c @@ -45,7 +45,8 @@ #include "license.c" /*@null@*/ /*@only@*/ static char *objdir_pathname = NULL; -/*@null@*/ /*@only@*/ static char *global_prefix = NULL, *global_suffix = NULL; +/*@null@*/ /*@only@*/ static char *global_prefix = NULL, *global_suffix = +NULL; /*@null@*/ /*@only@*/ static char *listdir_pathname = NULL; /*@null@*/ /*@only@*/ static char *mapdir_pathname = NULL; /*@null@*/ /*@only@*/ static char *machine_name = NULL; @@ -658,6 +659,20 @@ main(int argc, char *argv[]) /* If not already specified, output to the current directory. */ if (!objdir_pathname) objdir_pathname = yasm__xstrdup("./"); + else if((i = yasm__createpath(objdir_pathname)) > 0) { + objdir_pathname[i] = '/'; + objdir_pathname[i+1] = '\0'; + } + + /* Create other output directories if necessary */ + if (listdir_pathname && (i = yasm__createpath(listdir_pathname)) > 0) { + listdir_pathname[i] = '/'; + listdir_pathname[i+1] = '\0'; + } + if (mapdir_pathname && (i = yasm__createpath(mapdir_pathname)) > 0) { + mapdir_pathname[i] = '/'; + mapdir_pathname[i+1] = '\0'; + } /* Assemble each input file. Terminate on first error. */ STAILQ_FOREACH(infile, &input_files, link) @@ -927,7 +942,6 @@ opt_listdir_handler(/*@unused@*/ char *cmd, char *param, assert(param != NULL); listdir_pathname = yasm_xmalloc(strlen(param)+2); strcpy(listdir_pathname, param); - strcat(listdir_pathname, "/"); return 0; } @@ -945,7 +959,6 @@ opt_objdir_handler(/*@unused@*/ char *cmd, char *param, assert(param != NULL); objdir_pathname = yasm_xmalloc(strlen(param)+2); strcpy(objdir_pathname, param); - strcat(objdir_pathname, "/"); return 0; } @@ -963,7 +976,6 @@ opt_mapdir_handler(/*@unused@*/ char *cmd, char *param, assert(param != NULL); mapdir_pathname = yasm_xmalloc(strlen(param)+2); strcpy(mapdir_pathname, param); - strcat(mapdir_pathname, "/"); return 0; } diff --git a/libyasm/file.c b/libyasm/file.c index 128934a8..07609348 100644 --- a/libyasm/file.c +++ b/libyasm/file.c @@ -34,6 +34,14 @@ #include #endif +#ifdef _WIN32 +#include +#endif + +#ifdef HAVE_SYS_STAT_H +#include +#endif + #include #include @@ -450,6 +458,68 @@ yasm__combpath_win(const char *from, const char *to) return out; } +size_t +yasm__createpath_common(const char *path, int win) +{ + const char *pp = path, *pe; + char *ts, *tp; + size_t len, lth; + + lth = len = strlen(path); + ts = tp = (char *) malloc(len + 1); + pe = pp + len; + while (pe > pp) { + if ((win && *pe == '\\') || *pe == '/') + break; + --pe; + --lth; + } + + while (pp <= pe) { + if (pp == pe || (win && *pp == '\\') || *pp == '/') { +#ifdef _WIN32 + struct _finddata_t fi; + intptr_t h; +#elif defined(HAVE_SYS_STAT_H) + struct stat fi; +#endif + *tp = '\0'; + +#ifdef _WIN32 + h = _findfirst(ts, &fi); + if (h != -1) { + if (fi.attrib != _A_SUBDIR) { + _findclose(h); + break; + } + } else if (errno == ENOENT) { + if (_mkdir(ts) == -1) { + _findclose(h); + lth = -1; + break; + } + } + _findclose(h); +#elif defined(HAVE_SYS_STAT_H) + if (stat(ts, &fi) != -1) { + if (!S_ISDIR(fi.st_mode)) + break; + } else if (errno == ENOENT) { + if (mkdir(ts, 0755) == -1) { + lth = 0; + break; + } + } +#else + break; +#endif + } + *tp++ = *pp++; + } + free(ts); + return lth; +} + typedef struct incpath { STAILQ_ENTRY(incpath) link; /*@owned@*/ char *path; diff --git a/libyasm/file.h b/libyasm/file.h index a1de0339..d99785dd 100644 --- a/libyasm/file.h +++ b/libyasm/file.h @@ -179,6 +179,30 @@ char *yasm__combpath_win(const char *from, const char *to); # endif #endif +/** Recursively create tree of directories needed for pathname. + * \internal + * \param path pathname + * \param win handle windows paths + * \return Length of directory portion of pathname. + */ +YASM_LIB_DECL +size_t yasm__createpath_common(const char *path, int win); + +/** Recursively create tree of directories needed for pathname. + * Unless otherwise defined, defaults to yasm__createpath_unix(). + * \internal + * \param path pathname + * \return Length of directory portion of pathname. + */ +#ifndef yasm__createpath +# if defined (_WIN32) || defined (WIN32) || defined (__MSDOS__) || \ + defined (__DJGPP__) || defined (__OS2__) +# define yasm__createpath(path) yasm__createpath_common(path, 1) +# else +# define yasm__createpath(path) yasm__createpath_common(path, 0) +# endif +#endif + /** Try to find and open an include file, searching through include paths. * First iname is looked for relative to the directory containing "from", then * it's looked for relative to each of the include paths.