Serenity Operating System
at master 95 lines 3.2 kB view raw
1/* 2 * Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include "SectionNode.h" 8#include "PageNode.h" 9#include "Path.h" 10#include "SubsectionNode.h" 11#include <AK/LexicalPath.h> 12#include <AK/QuickSort.h> 13#include <LibCore/DeprecatedFile.h> 14#include <LibCore/DirIterator.h> 15 16namespace Manual { 17 18ErrorOr<NonnullRefPtr<SectionNode>> SectionNode::try_create_from_number(StringView section) 19{ 20 auto maybe_section_number = section.to_uint<u32>(); 21 if (!maybe_section_number.has_value()) 22 return Error::from_string_literal("Section is not a number"); 23 auto section_number = maybe_section_number.release_value(); 24 if (section_number > number_of_sections) 25 return Error::from_string_literal("Section number too large"); 26 return sections[section_number - 1]; 27} 28 29ErrorOr<String> SectionNode::path() const 30{ 31 return String::formatted("{}/{}{}", manual_base_path, top_level_section_prefix, m_section); 32} 33 34ErrorOr<String> SectionNode::name() const 35{ 36 return String::formatted("{}. {}", m_section, m_name); 37} 38 39ErrorOr<void> SectionNode::reify_if_needed() const 40{ 41 if (m_reified) 42 return {}; 43 m_reified = true; 44 45 auto own_path = TRY(path()); 46 Core::DirIterator dir_iter { own_path.to_deprecated_string(), Core::DirIterator::Flags::SkipDots }; 47 48 struct Child { 49 NonnullRefPtr<Node const> node; 50 String name_for_sorting; 51 }; 52 Vector<Child> children; 53 54 while (dir_iter.has_next()) { 55 LexicalPath lexical_path(dir_iter.next_path()); 56 if (lexical_path.extension() != "md") { 57 if (Core::DeprecatedFile::is_directory(LexicalPath::absolute_path(own_path.to_deprecated_string(), lexical_path.string()))) { 58 dbgln("Found subsection {}", lexical_path); 59 children.append({ .node = TRY(try_make_ref_counted<SubsectionNode>(*this, lexical_path.title())), 60 .name_for_sorting = TRY(String::from_utf8(lexical_path.title())) }); 61 } 62 } else { 63 children.append({ .node = TRY(try_make_ref_counted<PageNode>(*this, TRY(String::from_utf8(lexical_path.title())))), 64 .name_for_sorting = TRY(String::from_utf8(lexical_path.title())) }); 65 } 66 } 67 68 quick_sort(children, [](auto const& a, auto const& b) { return a.name_for_sorting < b.name_for_sorting; }); 69 70 m_children.ensure_capacity(children.size()); 71 for (auto child : children) 72 m_children.unchecked_append(move(child.node)); 73 74 return {}; 75} 76 77void SectionNode::set_open(bool open) 78{ 79 if (m_open == open) 80 return; 81 m_open = open; 82} 83 84Array<NonnullRefPtr<SectionNode>, number_of_sections> const sections = { { 85 make_ref_counted<SectionNode>("1"sv, "User Programs"sv), 86 make_ref_counted<SectionNode>("2"sv, "System Calls"sv), 87 make_ref_counted<SectionNode>("3"sv, "Library Functions"sv), 88 make_ref_counted<SectionNode>("4"sv, "Special Files"sv), 89 make_ref_counted<SectionNode>("5"sv, "File Formats"sv), 90 make_ref_counted<SectionNode>("6"sv, "Games"sv), 91 make_ref_counted<SectionNode>("7"sv, "Miscellanea"sv), 92 make_ref_counted<SectionNode>("8"sv, "Sysadmin Tools"sv), 93} }; 94 95}