1#include "include/pw.h"
 2#include "include/pwlib/file.h"
 3#include "include/pwlib/path.h"
 4
 5[[nodiscard]] bool pw_mkdir(PwValuePtr path)
 6{
 7    PwValue path_str = PW_NULL;
 8    if (!pw_path_as_string(path, &path_str)) {
 9        return false;
10    }
11    PW_CSTRING(c_path, &path_str);
12    if (mkdir(c_path, 0777)) {
13        pw_set_status(PwErrno(errno));
14        return false;
15    }
16    return true;
17}
18
19[[nodiscard]] bool pw_makedirs(PwValuePtr path)
20{
21    PwValue parts = PW_NULL;
22    if (!pw_path_as_array(path, &parts)) {
23        return false;
24    }
25    unsigned n = pw_array_length(&parts);
26    unsigned path_len = 0;
27    uint8_t path_char_size = 1;
28    for (unsigned i = 0; i < n; i++) {
29        PwValue part = PW_NULL;
30        if (!pw_array_item(&parts, i, &part)) {
31            return false;
32        }
33        path_len += pw_strlen(&part) + 1;
34        if (path_char_size < part.str_params.char_size) {
35            path_char_size = part.str_params.char_size;
36        }
37    }
38    PwValue created_path = PW_NULL;
39    if (!pw_create_empty_string(path_len, path_char_size, &created_path)) {
40        return false;
41    }
42    for (unsigned i = 0; i < n; i++) {
43        PwValue part = PW_NULL;
44        if (!pw_array_item(&parts, i, &part)) {
45            return false;
46        }
47        if (!pw_string_append(&created_path, &part)) {
48            return false;
49        }
50        if (i == 0 && pw_equal(&part, "/")) {
51            continue;
52        }
53        if (!pw_mkdir(&created_path)) {
54            PwValue status = pw_get_status();
55            if (!pw_is_errno(&status, EEXIST)) {
56                // double check
57                bool exists;
58                if (!pw_file_exists(&created_path, &exists)) {
59                    return false;
60                }
61                if (!exists) {
62                    pw_set_status(&status);
63                    return false;
64                }
65            }
66        }
67        if (!pw_string_append(&created_path, '/')) {
68            return false;
69        }
70    }
71    return true;
72}
73
74[[nodiscard]] bool pw_makedirs_for_file(PwValuePtr path)
75{
76    PwValue parts = PW_NULL;
77    if (!pw_path_as_array(path, &parts)) {
78        return false;
79    }
80    PwValue dir_parts = PW_NULL;
81    if (!pw_array_slice(&parts, 0, pw_array_length(&parts) - 1, &dir_parts)) {
82        return false;
83    }
84    return pw_makedirs(&dir_parts);
85}