#include "tool_dirhie.h"
#include "tool_msgs.h"
-#ifdef _WIN32
+#ifdef UNITTESTS
+# define toolx_mkdir(x, y) create_dir_hierarchy_trace_mkdir(x)
+#elif defined(_WIN32)
# include <direct.h>
# define toolx_mkdir(x, y) _mkdir(x)
#elif defined(MSDOS) && !defined(__DJGPP__)
# define toolx_mkdir mkdir
#endif
+#ifdef UNITTESTS
+static struct dynbuf mkdir_results;
+
+UNITTEST struct dynbuf *create_dir_hierarchy_trace_dynres(void)
+{
+ return &mkdir_results;
+}
+
+static int create_dir_hierarchy_trace_mkdir(const char *dir)
+{
+ return !dir ||
+ curlx_dyn_add(&mkdir_results, dir) ||
+ curlx_dyn_add(&mkdir_results, "|") ? -1 : 0;
+}
+#endif
+
static void show_dir_errno(const char *name)
{
switch(errno) {
#if defined(_WIN32) || defined(MSDOS)
if(!curlx_dyn_len(&dirbuf)) {
- /* Skip creating a drive's current directory. It may seem as though that
- would harmlessly fail but it could be a corner case if X: did not
- exist, since we would be creating it erroneously. eg if outfile is
- X:\foo\bar\filename then do not mkdir X: This logic takes into
+ /* Skip creating a standalone Windows/MS-DOS drive letter 'X:', e.g.
+ if outfile is X:\foo\bar\filename. Do create drive-relative
+ directories e.g. in outfile X:foo\bar\filename. This logic takes into
account unsupported drives !:, 1:, etc. */
- if(len > 1 && (outfile[1] == ':'))
+ if(len == 2 && (outfile[1] == ':'))
skip = TRUE;
}
#endif
--- /dev/null
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+#include "unitcheck.h"
+#include "tool_dirhie.h"
+
+static CURLcode test_tool1720(const char *arg)
+{
+ UNITTEST_BEGIN_SIMPLE
+
+ static const char *check[] = {
+ "",
+ "(null)",
+ "filename",
+ "(null)",
+ "foo/bar/",
+ "foo|foo/bar|",
+ "foo/bar/filename",
+ "foo|foo/bar|",
+ "/foo/bar/filename",
+ "/foo|/foo/bar|",
+#if defined(_WIN32) || defined(MSDOS)
+ "C:/foo/bar/filename",
+ "C:/foo|C:/foo/bar|",
+ "C:foo/bar/filename",
+ "C:foo|C:foo/bar|",
+ "foo\\bar\\filename",
+ "foo|foo\\bar|",
+ "\\foo\\bar\\filename",
+ "\\foo|\\foo\\bar|",
+ "C:\\foo\\bar\\filename",
+ "C:\\foo|C:\\foo\\bar|",
+ "C:foo\\bar\\filename",
+ "C:foo|C:foo\\bar|",
+#endif
+ };
+
+ size_t i;
+ struct dynbuf *res = create_dir_hierarchy_trace_dynres();
+
+ curlx_dyn_init(res, 256);
+
+ for(i = 0; i < CURL_ARRAYSIZE(check); i += 2) {
+ const char *actual;
+ curlx_dyn_reset(res);
+ create_dir_hierarchy(check[i]);
+ actual = curlx_dyn_ptr(res);
+ if(!actual)
+ actual = "(null)";
+ if(strcmp(check[i + 1], actual)) {
+ curl_mprintf("Expected '%s' got '%s'\n", check[i + 1], actual);
+ unitfail++;
+ }
+ }
+
+ curlx_dyn_free(res);
+
+ UNITTEST_END_SIMPLE
+}