diff --git a/regexis024_build_system.h b/regexis024_build_system.h index 16737e9..43f49b1 100644 --- a/regexis024_build_system.h +++ b/regexis024_build_system.h @@ -150,23 +150,8 @@ struct path_t { me.parts.push_back(el); return me; } - - void operator/=(const path_t& other) { - if (other.is_relative) { - for (auto& el: other.parts) - parts.push_back(el); - } else { - *this = other; - } - } }; -mode_t get_umask(){ - mode_t old = umask(0); - umask(old); - return old; -} - void createDir(const path_t& path) { std::string cur_pref = std::string(path.is_relative ? "" : "/"); for (size_t i = 0; i < path.parts.size(); i++) { @@ -190,105 +175,9 @@ void createDir(const path_t& path) { } } -struct fsDetourFrame { - std::string path; - bool has_expanded = false; - - explicit fsDetourFrame(const std::string &path) : path(path) {} -}; - template using uptr = std::unique_ptr; -void deleteEntity(const std::string& path) { - int ret; - static constexpr size_t mem_limit = 10000; - std::vector> cs; - cs.emplace_back(new fsDetourFrame(path)); - while (!cs.empty()) { - fsDetourFrame& cur = *cs.back(); - if (cur.has_expanded) { - ret = rmdir(cur.path.c_str()); - ASSERT_on_iret(ret, "rmdir(\"" + cur.path + "\")"); - /* cur invalidated */ - cs.pop_back(); - } else { - struct stat info; - ret = stat(cur.path.c_str(), &info); - ASSERT_on_iret(ret, "stat(\"" + cur.path + "\")"); - if (S_ISDIR(info.st_mode)) { - DIR* D = opendir(cur.path.c_str()); - ASSERT(D != NULL, prettyprint_errno("opendir(\"" + cur.path +"\")")); - while (true) { - errno = 0; - struct dirent* Dent = readdir(D); - if (Dent == NULL) { - if (closedir(D) != 0) - throw std::runtime_error("closedir"); - if (errno == 0) - break; - THROW_on_errno("dirent in \"" + cur.path + "\""); - } - std::string child_entry = Dent->d_name; - if (child_entry != "." && child_entry != "..") { - if (cs.size() >= mem_limit) { - THROW("deleteEntity is deleting a very big entity"); - } - cs.emplace_back(new fsDetourFrame(cur.path + "/" + child_entry)); - } - } - cur.has_expanded = true; - } else if (S_ISREG(info.st_mode)) { - ret = unlink(cur.path.c_str()); - ASSERT_on_iret(ret, "unlink(\"" + cur.path + "\")"); - /* cur invalidated */ - cs.pop_back(); - } else { - THROW("unknown filetype of file \"" + cur.path + "\""); - } - } - } -} - -/* Recursively delete a directory `path` and nothing else. If `path` leads nowhere, task - * is considered successfully done. If `path` is not a directory, error arises */ -void ensureDirDeletion(const std::string& path) { - errno = 0; - struct stat info; - int ret = stat(path.c_str(), &info); - if (errno == ENOENT) - return; - ASSERT_on_iret(ret, "stat(\"" + path + "\")"); - ASSERT(S_ISDIR(info.st_mode), "Not a directory"); - deleteEntity(path); -} - -/* Delete empty directory `path` and nothing else. If `path` leads nowhere, task - * is considered successfully done. If `path` is not an empty directory, error arises */ -void enusreEmptyDirDeletion(const std::string& path) { - errno = 0; - int ret = rmdir(path.c_str()); - if (ret < 0) { - if (errno == ENOENT) - return; - THROW_on_errno("rmdir(\"" + path + "\")"); - } -} - -/* Delete a file `path` and nothing else. If `path` leads nowhere, task - * is considered successfully done. If `path` is not a file, error arises */ -void ensureFileDeletion(const std::string& path) { - errno = 0; - struct stat info; - int ret = stat(path.c_str(), &info); - if (errno == ENOENT) - return; - ASSERT_on_iret(ret, "stat(\"" + path + "\")"); - ASSERT(S_ISREG(info.st_mode), "Not a regular file"); - ret = unlink(path.c_str()); - ASSERT_on_iret(ret, "unlink(\"" + path + "\")"); -} - void checkFoldernessOfDir(const std::string& path) { struct stat info; int ret = stat(path.c_str(), &info); @@ -322,8 +211,7 @@ void readFile(const std::string& path, std::string& result) { close(fd); } -/* write(fd, text); close(fd); Argument description is for error handling */ - +/* write(fd, text); close(fd); */ void writeToFileDescriptor(int fd, const std::string& text, const std::string& description = "") { size_t n = text.size(); size_t i = 0; @@ -555,14 +443,10 @@ struct BuildUnit { /* Build unit dependencies are identidied by their index in array */ std::vector bu_dependencies; - BuildUnit(const std::string &type, const std::vector &all_fs_dependencies, - const std::vector &all_fs_results, const std::vector &bu_dependencies) - : type(type), - all_fs_dependencies(all_fs_dependencies), - all_fs_results(all_fs_results), - bu_dependencies(bu_dependencies) { - } - + BuildUnit(std::string type_, std::vector all_fs_deps_, std::vector all_fs_results_, + std::vector bu_deps_): type(std::move(type_)), all_fs_dependencies(std::move(all_fs_deps_)), + all_fs_results(std::move(all_fs_results_)), bu_dependencies(std::move(bu_deps_)){} + BuildUnit(): type("blank"){} virtual void execute() const { } @@ -576,7 +460,7 @@ struct MkdirBuildUnit: public BuildUnit { path_t dir_path; MkdirBuildUnit(const path_t &dir_path) - : BuildUnit("mkdir", {}, {ExpectedFSEntityState((std::string)dir_path, S_IFDIR)}, {}), dir_path(dir_path) {} + : BuildUnit{"mkdir", {}, {ExpectedFSEntityState((std::string)dir_path, S_IFDIR)}, {}}, dir_path(dir_path) {} void execute() const override { createDir(dir_path); @@ -593,7 +477,7 @@ struct SubprocessedBuildUnit: public BuildUnit { SubprocessedBuildUnit(const std::string &type, const std::vector &all_fs_dependencies, const std::vector &all_fs_results, const std::vector &bu_dependencies, const std::vector &build_command) - : BuildUnit(type, all_fs_dependencies, all_fs_results, bu_dependencies), + : BuildUnit{type, all_fs_dependencies, all_fs_results, bu_dependencies}, build_command(build_command) { } @@ -616,9 +500,9 @@ struct FileWriteBuildUnit: public BuildUnit { std::string text; FileWriteBuildUnit(const path_t &filepath, const std::string &text) : - BuildUnit("touch", {}, + BuildUnit{"touch", {}, {ExpectedFSEntityState(filepath, S_IFREG)}, - {}), + {}}, filepath(filepath),text(text) { } @@ -640,9 +524,8 @@ struct FileInstallBuildUnit: public BuildUnit { path_t destination; FileInstallBuildUnit(const path_t& source, const path_t& destination): source(source), destination(destination), - BuildUnit("file-install", {ExpectedFSEntityState(source, S_IFREG)}, - {ExpectedFSEntityState(destination, S_IFREG)}, {}) { - } + BuildUnit{"file-install", {ExpectedFSEntityState(source, S_IFREG)}, + {ExpectedFSEntityState(destination, S_IFREG)}, {}} {} void execute() const override { ASSERT(!destination.parts.empty(), "Bad installation destination"); @@ -756,93 +639,11 @@ void topsort(std::vector& result, std::vector& circular_dependen /* Now this array is structured like this: [0] requires [1], which requires [2] ... and [-1] requires [0] */ } -int _utf8_retrieve_size(uint8_t firstByte) { - if (!(firstByte & 0b10000000)) - return 1; - uint8_t a = 0b11000000; - uint8_t b = 0b00100000; - for (int i = 2; i <= 4; i++){ - if ((firstByte & (a | b)) == a) - return i; - a |= b; - b >>= 1; - } - return -1; -} - -int32_t _utf8_retrieve_character(int sz, size_t pos, const uint8_t *string) { - if (sz == 1) - return string[pos]; - uint32_t v = string[pos] & (0b01111111 >> sz); - pos++; - for (int i = 1; i < sz; i++){ - uint32_t th = string[pos]; - if ((th & 0b11000000) != 0b10000000) - return -1; - v <<= 6; - v |= (th & 0b00111111); - pos++; - } - assert(v <= INT32_MAX); - return static_cast(v); -} - -void utf8_string_iterat(int32_t &cp, size_t &adj, size_t pos, const uint8_t *string, size_t string_size) { - if (pos >= string_size) {cp = -1; return;} - adj = _utf8_retrieve_size(string[pos]); - if (adj < 0 || pos + adj > string_size) {cp = -1; return;} - if ((cp = _utf8_retrieve_character(adj, pos, string)) < 0) {cp = -1; return;} -} - -size_t text_line_width(const std::string& str) { - size_t pos = 0; - size_t sz = 0; - while (pos < str.size()) { - int32_t code; size_t adj; - utf8_string_iterat(code, adj, pos, reinterpret_cast(str.data()), str.size()); - if (code < 0) - return 0; - sz++; - pos += adj; - } - return sz; -} - -std::string strMul(size_t n, const char* str) { - std::string res; - for (size_t i = 0; i < n; i++) - res += str; - return res; -} - std::string prettyprint_cyclic_dependency(const std::vector& lines) { - static const char* arrow_right_to_down = "\u2B10"; - static const char* line_corner_top_right = "\u2510"; - static const char* line_corner_bottom_right = "\u2518"; - static const char* line_vertical = "\u2502"; - static const char* line_horizontal = "\u2500"; - - if (lines.empty()) - return ""; - if (lines.size() == 1) { - return lines[0] + " requires itself\n"; - } - size_t max_line = 0; - size_t n = lines.size(); - std::vector new_lines(n + 1); - for (size_t i = 0; i < n; i++) { - new_lines[i + 1] += lines[i]; - new_lines[i + 1] += i == 0 ? " requires" : ", which requires"; - max_line = std::max(max_line, text_line_width(new_lines[i + 1])); - } - new_lines[0] = arrow_right_to_down + strMul(max_line, line_horizontal) + line_corner_top_right; - for (size_t i = 1; i + 1 < n + 1; i++) { - new_lines[i] += strMul(max_line - text_line_width(new_lines[i]) + 1, " ") + line_vertical; - } - new_lines[n] += " " + strMul(max_line - text_line_width(new_lines[n]), line_horizontal) + line_corner_bottom_right; - std::string res; - for (auto& line: new_lines) - res += line + "\n"; + std::string res = "Брэ! ТУТ ЧЁ-ТО НЕ ТАК!\n"; + for (auto& el: lines) + res += el; res += '\n'; + res += "Lmao, you have a cyclic build unit dependency in your scipt.\n"; return res; } @@ -888,21 +689,13 @@ struct CTargetDependenceOnLibraryFPass { }; struct CTargetDependenceOnProjectsLibrary { - CTargetDependenceOnLibraryFPass passing_flags; std::string project_library_target; - - explicit CTargetDependenceOnProjectsLibrary(const std::string& target_lib): project_library_target(target_lib){} - explicit CTargetDependenceOnProjectsLibrary (const std::string& target_lib, bool pass_comp_flags, bool pass_lib_flags): - project_library_target(target_lib), passing_flags{pass_comp_flags, pass_lib_flags} {} + CTargetDependenceOnLibraryFPass passing_flags; }; struct CTargetDependenceOnExternalLibrary { - CTargetDependenceOnLibraryFPass passing_flags; std::string external_library_name; - - explicit CTargetDependenceOnExternalLibrary(const std::string &ext_lib): external_library_name(ext_lib) {} - explicit CTargetDependenceOnExternalLibrary(const std::string &ext_lib, bool pass_comp_flags, bool pass_lib_flags): - external_library_name(ext_lib), passing_flags{pass_comp_flags, pass_lib_flags} {} + CTargetDependenceOnLibraryFPass passing_flags; }; struct ExternalLibraryData { @@ -936,10 +729,7 @@ struct CTarget { std::string installation_dir; /* If empty, no .pc file will be created. Otherwise, must include filename */ std::string pc_output_path; - std::string description; std::string version = "0.1"; - - CTarget(const std::string& name, const std::string& type): name(name), type(type){} }; void check_is_good_name_1(const std::string& name) { @@ -1130,7 +920,7 @@ void load_ctargets_on_building_and_installing( size_t blank_ibu_for_tg_FINAL; /* bon_install_root is either install_lib_dir_pth or intall_bin_dir_path */ auto gen_ibus_for_this_th = [&](const std::string& bin_install_root, const std::string& resuting_bin_extension) { - BuildUnit* podveska = new BuildUnit(); + BuildUnit* podveska = new BuildUnit{}; /* Time to initialize corresponding build units in "install" runlevel */ size_t my_ibu_for_final_binary_installation = add_ibu(new FileInstallBuildUnit( path_t(proj_compiled_dir_path) / tg.name / (tg.name + resuting_bin_extension), @@ -1204,7 +994,7 @@ void load_ctargets_on_building_and_installing( size_t pkg_conf_install_ibu = add_ibu(new FileWriteBuildUnit( path_t(install_pkgconfig_dir_path) / tg.pc_output_path, "Name: " + tg.name + "\n" + - "Description: " + tg.description + "\n" + + "Description: \n" + "Version: " + tg.version + "\n" + "Cflags: " + join_string_arr(s.emitted_compilation_flags_PASSED_FORWARD, " ") + "\n" + "Libs: " + join_string_arr(s.emitted_linkage_flags_PASSED_FORWARD, " ") + "\n")); @@ -1222,7 +1012,7 @@ void load_ctargets_on_building_and_installing( struct NormalCBuildSystemCommandMeaning { std::string project_root; std::string installation_root; - bool allowed_symlink_install = false; + bool local = false; bool need_to_build = false; bool need_to_install = false; }; @@ -1293,43 +1083,4 @@ void regular_ctargets_to_2bus_conversion( ); } -std::string text_formatting_break_spaces(const std::string& text) { - std::string out; - return out; -} - -void draw_bu_arr_in_dot(const BuildUnitsArray& taskSet, std::string& output) { - size_t N = taskSet.size(); - output += "digraph BUs { \n" - "graph [rankdir=LR]" - "node [fontcolor = black color = black fillcolor = white margin = \"0.2,0.2\"" - " shape=rect ]\n"; - for (size_t i = 0; i < N; i++) { - const BuildUnit& bu = *(taskSet[i]); - output += std::string("N_") + std::to_string(i) + " [ label = " - + escape_with_doublequoting("[" + std::to_string(i) + "] " + prettyprint_build_unit(bu)) - + "]\n"; - for (size_t j: bu.bu_dependencies) { - output += "N_" + std::to_string(i) + " -> N_" + std::to_string(j) + "\n"; - } - } - output += "}\n"; -} - -void show_build_units_array_with_image_viewer(const BuildUnitsArray& taskSet, const std::string& image_viewer = "sxiv") -{ - std::string dot_input; - draw_bu_arr_in_dot(taskSet, dot_input); - std::string dot_output; - std::string dot_error; - printf("Look at that\n%s\n", dot_input.c_str()); - CommandReturnCode rc = executeCommand_imulating_whole_input_and_save_output({"dot", "-T", "svg"}, dot_input, dot_output, dot_error); - if (!rc.isOk()) { - printf("Dot error output:\n%s", dot_error.c_str()); - } - ASSERT_pl(rc.isOk()); - writeFile("taskSet.svg", dot_output); - ASSERT(executeCommand({image_viewer, "taskSet.svg"}).isOk(), "imageviewer error"); -} - #endif //REGEXIS024_BUILD_SYSTEM_H