Browse Source

Move libman parsing into a new directory/namespace

default_compile_flags
vector-of-bool 5 years ago
parent
commit
07a7e4bd97
11 changed files with 91 additions and 66 deletions
  1. +14
    -0
      src/dds/archive.hpp
  2. +4
    -4
      src/dds/build.cpp
  3. +1
    -1
      src/dds/ddslim.main.cpp
  4. +7
    -3
      src/dds/manifest.cpp
  5. +2
    -0
      src/dds/manifest.hpp
  6. +9
    -3
      src/dds/toolchain.cpp
  7. +2
    -0
      src/dds/util.hpp
  8. +3
    -3
      src/dds/util.test.hpp
  9. +9
    -9
      src/libman/parse.cpp
  10. +27
    -30
      src/libman/parse.hpp
  11. +13
    -13
      src/libman/parse.test.cpp

+ 14
- 0
src/dds/archive.hpp View File

#pragma once

#include <dds/util.hpp>

#include <vector>

namespace dds {

struct archive_rules {
std::vector<fs::path> objects;
fs::path out;
};

} // namespace dds

+ 4
- 4
src/dds/build.cpp View File

#include <dds/proc.hpp> #include <dds/proc.hpp>
#include <dds/source.hpp> #include <dds/source.hpp>
#include <dds/toolchain.hpp> #include <dds/toolchain.hpp>
#include <dds/lm_parse.hpp>
#include <libman/parse.hpp>


#include <algorithm> #include <algorithm>
#include <chrono> #include <chrono>
copy_headers(header_root, header_dest, sources); copy_headers(header_root, header_dest, sources);
} }


std::vector<lm_pair> lm_pairs;
std::vector<lm::pair> lm_pairs;
lm_pairs.emplace_back("Type", "Package"); lm_pairs.emplace_back("Type", "Package");
lm_pairs.emplace_back("Name", params.export_name); lm_pairs.emplace_back("Name", params.export_name);
lm_pairs.emplace_back("Namespace", params.export_name); lm_pairs.emplace_back("Namespace", params.export_name);
lm_pairs.emplace_back("Library", "lib.lml"); lm_pairs.emplace_back("Library", "lib.lml");
lm_write_pairs(export_root / "package.lmp", lm_pairs);
lm::write_pairs(export_root / "package.lmp", lm_pairs);


lm_pairs.clear(); lm_pairs.clear();
lm_pairs.emplace_back("Type", "Library"); lm_pairs.emplace_back("Type", "Library");
lm_pairs.emplace_back("Name", params.export_name); lm_pairs.emplace_back("Name", params.export_name);
lm_pairs.emplace_back("Path", fs::relative(archive_dest, export_root).string()); lm_pairs.emplace_back("Path", fs::relative(archive_dest, export_root).string());
lm_pairs.emplace_back("Include-Path", fs::relative(header_dest, export_root).string()); lm_pairs.emplace_back("Include-Path", fs::relative(header_dest, export_root).string());
lm_write_pairs(export_root / "lib.lml", lm_pairs);
lm::write_pairs(export_root / "lib.lml", lm_pairs);
} }


fs::path fs::path

+ 1
- 1
src/dds/ddslim.main.cpp View File

#include <dds/build.hpp> #include <dds/build.hpp>
#include <dds/lm_parse.hpp>
#include <libman/parse.hpp>
#include <dds/logging.hpp> #include <dds/logging.hpp>
#include <dds/util.hpp> #include <dds/util.hpp>



+ 7
- 3
src/dds/manifest.cpp View File

#include "./manifest.hpp" #include "./manifest.hpp"


#include <dds/lm_parse.hpp>
#include <libman/parse.hpp>


#include <spdlog/fmt/fmt.h> #include <spdlog/fmt/fmt.h>


using namespace dds; using namespace dds;


library_manifest library_manifest::load_from_file(const fs::path& fpath) { library_manifest library_manifest::load_from_file(const fs::path& fpath) {
auto kvs = lm_parse_file(fpath);
auto kvs = lm::parse_file(fpath);
library_manifest ret; library_manifest ret;
for (auto& pair : kvs.items()) { for (auto& pair : kvs.items()) {
if (pair.key() == "Private-Include") { if (pair.key() == "Private-Include") {
ret.private_includes.emplace_back(pair.value()); ret.private_includes.emplace_back(pair.value());
} else if (pair.key() == "Private-Define") { } else if (pair.key() == "Private-Define") {
ret.private_defines.emplace_back(pair.value()); ret.private_defines.emplace_back(pair.value());
} else if (pair.key() == "Uses") {
ret.uses.emplace_back(pair.value());
} else if (pair.key() == "Links") {
ret.uses.emplace_back(pair.value());
} else { } else {
throw std::runtime_error( throw std::runtime_error(
fmt::format("Unknown key in file '{}': {}", fpath.string(), pair.key())); fmt::format("Unknown key in file '{}': {}", fpath.string(), pair.key()));
} }
} }
return ret; return ret;
}
}

+ 2
- 0
src/dds/manifest.hpp View File

struct library_manifest { struct library_manifest {
std::vector<fs::path> private_includes; std::vector<fs::path> private_includes;
std::vector<std::string> private_defines; std::vector<std::string> private_defines;
std::vector<std::string> uses;
std::vector<std::string> links;


static library_manifest load_from_file(const fs::path&); static library_manifest load_from_file(const fs::path&);
}; };

+ 9
- 3
src/dds/toolchain.cpp View File

#include "./toolchain.hpp" #include "./toolchain.hpp"


#include <dds/lm_parse.hpp>
#include <libman/parse.hpp>


#include <spdlog/fmt/fmt.h> #include <spdlog/fmt/fmt.h>


} }
}; };


auto kvs = lm_parse_file(p);
auto kvs = lm::parse_file(p);
for (auto&& pair : kvs.items()) { for (auto&& pair : kvs.items()) {
auto& key = pair.key(); auto& key = pair.key();
auto& value = pair.value(); auto& value = pair.value();
std::optional<toolchain> toolchain::get_builtin(std::string_view s) noexcept { std::optional<toolchain> toolchain::get_builtin(std::string_view s) noexcept {
toolchain ret; toolchain ret;


using namespace std::string_literals;
using namespace std::literals;

if (starts_with(s, "ccache:")) {
s = s.substr("ccache:"sv.length());
ret._c_compile.push_back("ccache");
ret._cxx_compile.push_back("ccache");
}


if (starts_with(s, "gcc") || starts_with(s, "clang")) { if (starts_with(s, "gcc") || starts_with(s, "clang")) {
ret._inc_template = {"-isystem", "<PATH>"}; ret._inc_template = {"-isystem", "<PATH>"};

+ 2
- 0
src/dds/util.hpp View File



namespace fs = std::filesystem; namespace fs = std::filesystem;


using path_ref = const fs::path&;

std::fstream open(const fs::path& filepath, std::ios::openmode mode, std::error_code& ec); std::fstream open(const fs::path& filepath, std::ios::openmode mode, std::error_code& ec);
std::string slurp_file(const fs::path& path, std::error_code& ec); std::string slurp_file(const fs::path& path, std::error_code& ec);



+ 3
- 3
src/dds/util.test.hpp View File

++::dds::S_failed_checks; \ ++::dds::S_failed_checks; \
std::cerr << "Check failed at " << __FILE__ << ':' << __LINE__ << ": " << #__VA_ARGS__ \ std::cerr << "Check failed at " << __FILE__ << ':' << __LINE__ << ": " << #__VA_ARGS__ \
<< "\n"; \ << "\n"; \
throw requirement_failed(); \
throw ::dds::requirement_failed(); \
} \ } \
} while (0) } while (0)


int main() { \ int main() { \
try { \ try { \
run_tests(); \ run_tests(); \
} catch (const requirement_failed&) { \
return S_failed_checks; \
} catch (const ::dds::requirement_failed&) { \
return ::dds::S_failed_checks; \
} catch (const std::exception& e) { \ } catch (const std::exception& e) { \
std::cerr << "An unhandled exception occured: " << e.what() << '\n'; \ std::cerr << "An unhandled exception occured: " << e.what() << '\n'; \
return 2; \ return 2; \

src/dds/lm_parse.cpp → src/libman/parse.cpp View File

#include "./lm_parse.hpp"
#include "./parse.hpp"


#include <dds/util.hpp> #include <dds/util.hpp>




using namespace std::literals; using namespace std::literals;


using namespace dds;
using namespace lm;


namespace { namespace {


return sview(iter, new_end); return sview(iter, new_end);
} }


void parse_line(std::vector<lm_pair>& pairs, const std::string_view whole_line) {
void parse_line(std::vector<pair>& pairs, const std::string_view whole_line) {
const auto line = trim(whole_line); const auto line = trim(whole_line);
if (line.empty() || line[0] == '#') { if (line.empty() || line[0] == '#') {
return; return;


} // namespace } // namespace


dds::lm_kv_pairs dds::lm_parse_string(std::string_view s) {
std::vector<lm_pair> pairs;
pair_list lm::parse_string(std::string_view s) {
std::vector<pair> pairs;


auto line_begin = s.begin(); auto line_begin = s.begin();
auto iter = line_begin; auto iter = line_begin;
if (line_begin != end) { if (line_begin != end) {
parse_line(pairs, sview(line_begin, end)); parse_line(pairs, sview(line_begin, end));
} }
return lm_kv_pairs(std::move(pairs));
return pair_list(std::move(pairs));
} }


dds::lm_kv_pairs dds::lm_parse_file(fs::path fpath) { return lm_parse_string(slurp_file(fpath)); }
lm::pair_list lm::parse_file(fs::path fpath) { return parse_string(dds::slurp_file(fpath)); }


void dds::lm_write_pairs(fs::path fpath, const std::vector<lm_pair>& pairs) {
auto fstream = open(fpath, std::ios::out | std::ios::binary);
void lm::write_pairs(fs::path fpath, const std::vector<pair>& pairs) {
auto fstream = dds::open(fpath, std::ios::out | std::ios::binary);
for (auto& pair : pairs) { for (auto& pair : pairs) {
fstream << pair.key() << ": " << pair.value() << '\n'; fstream << pair.key() << ": " << pair.value() << '\n';
} }

src/dds/lm_parse.hpp → src/libman/parse.hpp View File

#ifndef DDS_LM_PARSE_HPP_INCLUDED
#define DDS_LM_PARSE_HPP_INCLUDED
#pragma once


#include <cassert> #include <cassert>
#include <filesystem> #include <filesystem>
#include <utility> #include <utility>
#include <vector> #include <vector>


namespace dds {
namespace lm {


class lm_pair {
class pair {
std::string _key; std::string _key;
std::string _value; std::string _value;


public: public:
lm_pair(std::string_view k, std::string_view v)
pair(std::string_view k, std::string_view v)
: _key(k) : _key(k)
, _value(v) {} , _value(v) {}


auto& value() const noexcept { return _value; } auto& value() const noexcept { return _value; }
}; };


struct kv_pair_iterator {
using vec_type = std::vector<lm_pair>;
class pair_iterator {
using vec_type = std::vector<pair>;
using base_iter = vec_type::const_iterator; using base_iter = vec_type::const_iterator;
base_iter _iter; base_iter _iter;
base_iter _end; base_iter _end;
using pointer = vec_type::pointer; using pointer = vec_type::pointer;
using reference = vec_type::reference; using reference = vec_type::reference;


inline kv_pair_iterator(base_iter, base_iter, std::string_view k);
inline pair_iterator(base_iter, base_iter, std::string_view k);


kv_pair_iterator& operator++() & noexcept {
pair_iterator& operator++() & noexcept {
assert(_iter != _end); assert(_iter != _end);
++_iter; ++_iter;
while (_iter != _end && _iter->key() != _key) { while (_iter != _end && _iter->key() != _key) {
return *this; return *this;
} }


const lm_pair* operator->() const noexcept {
const pair* operator->() const noexcept {
assert(_iter != _end); assert(_iter != _end);
return _iter.operator->(); return _iter.operator->();
} }


const lm_pair& operator*() const noexcept {
const pair& operator*() const noexcept {
assert(_iter != _end); assert(_iter != _end);
return *_iter; return *_iter;
} }


inline bool operator!=(const kv_pair_iterator& o) const noexcept { return _iter != o._iter; }
inline bool operator!=(const pair_iterator& o) const noexcept { return _iter != o._iter; }


auto begin() const noexcept { return *this; } auto begin() const noexcept { return *this; }
auto end() const noexcept { return kv_pair_iterator(_end, _end, _key); }
auto end() const noexcept { return pair_iterator(_end, _end, _key); }


explicit operator bool() const noexcept { return *this != end(); } explicit operator bool() const noexcept { return *this != end(); }
}; };


class lm_kv_pairs {
std::vector<lm_pair> _kvs;
class pair_list {
std::vector<pair> _kvs;


public: public:
explicit lm_kv_pairs(std::vector<lm_pair> kvs)
explicit pair_list(std::vector<pair> kvs)
: _kvs(kvs) {} : _kvs(kvs) {}


auto& items() const noexcept { return _kvs; } auto& items() const noexcept { return _kvs; }


const lm_pair* find(const std::string_view& key) const noexcept {
const pair* find(const std::string_view& key) const noexcept {
for (auto&& item : items()) { for (auto&& item : items()) {
if (item.key() == key) { if (item.key() == key) {
return &item; return &item;
return nullptr; return nullptr;
} }


kv_pair_iterator iter(std::string_view key) const noexcept {
pair_iterator iter(std::string_view key) const noexcept {
auto iter = items().begin(); auto iter = items().begin();
const auto end = items().end(); const auto end = items().end();
while (iter != end && iter->key() != key) { while (iter != end && iter->key() != key) {
++iter; ++iter;
} }
return kv_pair_iterator{iter, end, key};
return pair_iterator{iter, end, key};
} }


std::vector<lm_pair> all_of(std::string_view key) const noexcept {
std::vector<pair> all_of(std::string_view key) const noexcept {
auto iter = this->iter(key); auto iter = this->iter(key);
return std::vector<lm_pair>(iter, iter.end());
return std::vector<pair>(iter, iter.end());
} }


auto size() const noexcept { return _kvs.size(); } auto size() const noexcept { return _kvs.size(); }
}; };


inline kv_pair_iterator::kv_pair_iterator(base_iter it, base_iter end, std::string_view k)
inline pair_iterator::pair_iterator(base_iter it, base_iter end, std::string_view k)
: _iter{it} : _iter{it}
, _end{end} , _end{end}
, _key{k} {} , _key{k} {}


lm_kv_pairs lm_parse_string(std::string_view);
lm_kv_pairs lm_parse_file(std::filesystem::path);
void lm_write_pairs(std::filesystem::path, const std::vector<lm_pair>&);
pair_list parse_string(std::string_view);
pair_list parse_file(std::filesystem::path);
void write_pairs(std::filesystem::path, const std::vector<pair>&);


inline void lm_write_pairs(const std::filesystem::path& fpath, const lm_kv_pairs& pairs) {
lm_write_pairs(fpath, pairs.items());
inline void write_pairs(const std::filesystem::path& fpath, const pair_list& pairs) {
write_pairs(fpath, pairs.items());
} }


} // namespace dds

#endif // DDS_LM_PARSE_HPP_INCLUDED
} // namespace lm

src/dds/lm_parse.test.cpp → src/libman/parse.test.cpp View File

#include <dds/lm_parse.hpp>
#include <dds/util.test.hpp> #include <dds/util.test.hpp>
#include <libman/parse.hpp>


#include <iostream> #include <iostream>


using namespace dds;
using namespace lm;


void test_simple() { void test_simple() {
auto lm_src = ""; auto lm_src = "";
auto kvs = lm_parse_string(lm_src);
auto kvs = parse_string(lm_src);
CHECK(kvs.size() == 0); CHECK(kvs.size() == 0);


lm_src = "foo: bar"; lm_src = "foo: bar";
kvs = lm_parse_string(lm_src);
kvs = parse_string(lm_src);
CHECK(kvs.size() == 1); CHECK(kvs.size() == 1);
REQUIRE(kvs.find("foo")); REQUIRE(kvs.find("foo"));
CHECK(kvs.find("foo")->value() == "bar"); CHECK(kvs.find("foo")->value() == "bar");


lm_src = "foo:bar: baz"; lm_src = "foo:bar: baz";
kvs = lm_parse_string(lm_src);
kvs = parse_string(lm_src);
CHECK(kvs.size() == 1); CHECK(kvs.size() == 1);
REQUIRE(kvs.find("foo:bar")); REQUIRE(kvs.find("foo:bar"));
CHECK(kvs.find("foo:bar")->value() == "baz"); CHECK(kvs.find("foo:bar")->value() == "baz");


CHECK(lm_parse_string("#comment").size() == 0);
CHECK(lm_parse_string("\n\n").size() == 0);
CHECK(lm_parse_string("\n#comment").size() == 0);
CHECK(lm_parse_string("#comment\n\n").size() == 0);
CHECK(parse_string("#comment").size() == 0);
CHECK(parse_string("\n\n").size() == 0);
CHECK(parse_string("\n#comment").size() == 0);
CHECK(parse_string("#comment\n\n").size() == 0);


std::vector<std::string_view> empty_foos = { std::vector<std::string_view> empty_foos = {
"Foo:", "Foo:",
"Foo :\n", "Foo :\n",
}; };
for (auto s : empty_foos) { for (auto s : empty_foos) {
kvs = lm_parse_string(s);
kvs = parse_string(s);
CHECK(kvs.size() == 1); CHECK(kvs.size() == 1);
REQUIRE(kvs.find("Foo")); REQUIRE(kvs.find("Foo"));
CHECK(kvs.find("Foo")->value() == ""); CHECK(kvs.find("Foo")->value() == "");
} }


kvs = lm_parse_string("foo: # Not a comment");
kvs = parse_string("foo: # Not a comment");
CHECK(kvs.size() == 1); CHECK(kvs.size() == 1);
REQUIRE(kvs.find("foo")); REQUIRE(kvs.find("foo"));
CHECK(kvs.find("foo")->value() == "# Not a comment"); CHECK(kvs.find("foo")->value() == "# Not a comment");
} }


void test_multi() { void test_multi() {
auto kvs = lm_parse_string("Foo: bar\nbaz: qux");
auto kvs = parse_string("Foo: bar\nbaz: qux");
CHECK(kvs.size() == 2); CHECK(kvs.size() == 2);
REQUIRE(kvs.find("Foo")); REQUIRE(kvs.find("Foo"));
CHECK(kvs.find("Foo")->value() == "bar"); CHECK(kvs.find("Foo")->value() == "bar");
REQUIRE(kvs.find("baz")); REQUIRE(kvs.find("baz"));
CHECK(kvs.find("baz")->value() == "qux"); CHECK(kvs.find("baz")->value() == "qux");


kvs = lm_parse_string("foo: first\nfoo: second\n");
kvs = parse_string("foo: first\nfoo: second\n");
CHECK(kvs.size() == 2); CHECK(kvs.size() == 2);
auto iter = kvs.iter("foo"); auto iter = kvs.iter("foo");
REQUIRE(iter); REQUIRE(iter);

Loading…
Cancel
Save