mirror of
https://github.com/hyprwm/hyprlang.git
synced 2024-11-16 18:25:57 +01:00
move to hyprutils
This commit is contained in:
parent
87d5d98410
commit
28be0805b1
5 changed files with 49 additions and 230 deletions
57
.github/workflows/arch.yml
vendored
57
.github/workflows/arch.yml
vendored
|
@ -2,39 +2,6 @@ name: Build & Test (Arch)
|
|||
|
||||
on: [push, pull_request, workflow_dispatch]
|
||||
jobs:
|
||||
gcc:
|
||||
name: "gcc build / clang test"
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: archlinux
|
||||
steps:
|
||||
- name: Checkout repository actions
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
sparse-checkout: .github/actions
|
||||
|
||||
- name: Get required pkgs
|
||||
run: |
|
||||
sed -i 's/SigLevel = Required DatabaseOptional/SigLevel = Optional TrustAll/' /etc/pacman.conf
|
||||
pacman --noconfirm --noprogressbar -Syyu
|
||||
pacman --noconfirm --noprogressbar -Sy gcc base-devel cmake clang libc++
|
||||
|
||||
- name: Build hyprlang with gcc
|
||||
run: |
|
||||
CC="/usr/bin/gcc" CXX="/usr/bin/g++" cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -S . -B ./build
|
||||
CC="/usr/bin/gcc" CXX="/usr/bin/g++" cmake --build ./build --config Release --target hyprlang -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||
cmake --install ./build
|
||||
|
||||
- name: Build tests with clang
|
||||
run: |
|
||||
rm -rf ./build
|
||||
CC="/usr/bin/clang" CXX="/usr/bin/clang++" cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -DCMAKE_CXX_FLAGS="-stdlib=libc++" -S . -B ./build
|
||||
CC="/usr/bin/clang" CXX="/usr/bin/clang++" cmake --build ./build --config Release --target tests -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
cd ./build && ctest --output-on-failure
|
||||
|
||||
asan:
|
||||
name: "gcc build / ASan tests"
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -50,7 +17,11 @@ jobs:
|
|||
run: |
|
||||
sed -i 's/SigLevel = Required DatabaseOptional/SigLevel = Optional TrustAll/' /etc/pacman.conf
|
||||
pacman --noconfirm --noprogressbar -Syyu
|
||||
pacman --noconfirm --noprogressbar -Sy gcc base-devel cmake clang
|
||||
pacman --noconfirm --noprogressbar -Sy gcc base-devel cmake clang git
|
||||
|
||||
- name: Get hyprutils-git
|
||||
run: |
|
||||
git clone https://github.com/hyprwm/hyprutils && cd hyprutils && cmake -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -B build && cmake --build build --target hyprutils && cmake --install build
|
||||
|
||||
- name: Build with gcc
|
||||
run: |
|
||||
|
@ -77,7 +48,11 @@ jobs:
|
|||
run: |
|
||||
sed -i 's/SigLevel = Required DatabaseOptional/SigLevel = Optional TrustAll/' /etc/pacman.conf
|
||||
pacman --noconfirm --noprogressbar -Syyu
|
||||
pacman --noconfirm --noprogressbar -Sy gcc base-devel cmake clang
|
||||
pacman --noconfirm --noprogressbar -Sy gcc base-devel cmake clang git
|
||||
|
||||
- name: Get hyprutils-git
|
||||
run: |
|
||||
git clone https://github.com/hyprwm/hyprutils && cd hyprutils && cmake -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -B build && cmake --build build --target hyprutils && cmake --install build
|
||||
|
||||
- name: Build with gcc
|
||||
run: |
|
||||
|
@ -104,7 +79,11 @@ jobs:
|
|||
run: |
|
||||
sed -i 's/SigLevel = Required DatabaseOptional/SigLevel = Optional TrustAll/' /etc/pacman.conf
|
||||
pacman --noconfirm --noprogressbar -Syyu
|
||||
pacman --noconfirm --noprogressbar -Sy gcc base-devel cmake clang
|
||||
pacman --noconfirm --noprogressbar -Sy gcc base-devel cmake clang git
|
||||
|
||||
- name: Get hyprutils-git
|
||||
run: |
|
||||
git clone https://github.com/hyprwm/hyprutils && cd hyprutils && cmake -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -B build && cmake --build build --target hyprutils && cmake --install build
|
||||
|
||||
- name: Build with gcc
|
||||
run: |
|
||||
|
@ -131,7 +110,11 @@ jobs:
|
|||
run: |
|
||||
sed -i 's/SigLevel = Required DatabaseOptional/SigLevel = Optional TrustAll/' /etc/pacman.conf
|
||||
pacman --noconfirm --noprogressbar -Syyu
|
||||
pacman --noconfirm --noprogressbar -Sy gcc base-devel cmake clang libc++
|
||||
pacman --noconfirm --noprogressbar -Sy gcc base-devel cmake clang libc++ git
|
||||
|
||||
- name: Get hyprutils-git
|
||||
run: |
|
||||
git clone https://github.com/hyprwm/hyprutils && cd hyprutils && cmake -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -B build && cmake --build build --target hyprutils && cmake --install build
|
||||
|
||||
- name: Build hyprlang with clang
|
||||
run: |
|
||||
|
|
|
@ -28,6 +28,11 @@ add_compile_definitions(HYPRLANG_INTERNAL)
|
|||
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(deps REQUIRED IMPORTED_TARGET
|
||||
hyprutils>=0.1.1
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE SRCFILES CONFIGURE_DEPENDS "src/*.cpp" "include/hyprlang.hpp")
|
||||
|
||||
add_library(hyprlang SHARED ${SRCFILES})
|
||||
|
@ -40,6 +45,8 @@ set_target_properties(hyprlang PROPERTIES
|
|||
SOVERSION 2
|
||||
PUBLIC_HEADER include/hyprlang.hpp)
|
||||
|
||||
target_link_libraries(hyprlang PkgConfig::deps)
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
# for std::expected.
|
||||
# probably evil. Arch's clang is very outdated tho...
|
||||
|
@ -55,12 +62,12 @@ install(TARGETS hyprlang)
|
|||
add_custom_target(tests)
|
||||
|
||||
add_executable(hyprlang_test "tests/parse/main.cpp")
|
||||
target_link_libraries(hyprlang_test PRIVATE hyprlang)
|
||||
target_link_libraries(hyprlang_test PRIVATE hyprlang hyprutils)
|
||||
add_test(NAME "Parsing" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests COMMAND hyprlang_test "parse")
|
||||
add_dependencies(tests hyprlang_test)
|
||||
|
||||
add_executable(hyprlang_fuzz "tests/fuzz/main.cpp")
|
||||
target_link_libraries(hyprlang_fuzz PRIVATE hyprlang)
|
||||
target_link_libraries(hyprlang_fuzz PRIVATE hyprlang hyprutils)
|
||||
add_test(NAME "Fuzz" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests COMMAND hyprlang_fuzz "fuzz")
|
||||
add_dependencies(tests hyprlang_fuzz)
|
||||
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
#include "VarList.hpp"
|
||||
#include <ranges>
|
||||
#include <algorithm>
|
||||
|
||||
static std::string removeBeginEndSpacesTabs(std::string str) {
|
||||
if (str.empty())
|
||||
return str;
|
||||
|
||||
int countBefore = 0;
|
||||
while (str[countBefore] == ' ' || str[countBefore] == '\t') {
|
||||
countBefore++;
|
||||
}
|
||||
|
||||
int countAfter = 0;
|
||||
while ((int)str.length() - countAfter - 1 >= 0 && (str[str.length() - countAfter - 1] == ' ' || str[str.length() - 1 - countAfter] == '\t')) {
|
||||
countAfter++;
|
||||
}
|
||||
|
||||
str = str.substr(countBefore, str.length() - countBefore - countAfter);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
CVarList::CVarList(const std::string& in, const size_t lastArgNo, const char delim, const bool removeEmpty) {
|
||||
if (in.empty())
|
||||
m_vArgs.emplace_back("");
|
||||
|
||||
std::string args{in};
|
||||
size_t idx = 0;
|
||||
size_t pos = 0;
|
||||
std::ranges::replace_if(
|
||||
args, [&](const char& c) { return delim == 's' ? std::isspace(c) : c == delim; }, 0);
|
||||
|
||||
for (const auto& s : args | std::views::split(0)) {
|
||||
if (removeEmpty && s.empty())
|
||||
continue;
|
||||
if (++idx == lastArgNo) {
|
||||
m_vArgs.emplace_back(removeBeginEndSpacesTabs(in.substr(pos)));
|
||||
break;
|
||||
}
|
||||
pos += s.size() + 1;
|
||||
m_vArgs.emplace_back(removeBeginEndSpacesTabs(std::string_view{s}.data()));
|
||||
}
|
||||
}
|
||||
|
||||
std::string CVarList::join(const std::string& joiner, size_t from, size_t to) const {
|
||||
size_t last = to == 0 ? size() : to;
|
||||
|
||||
std::string rolling;
|
||||
for (size_t i = from; i < last; ++i) {
|
||||
rolling += m_vArgs[i] + (i + 1 < last ? joiner : "");
|
||||
}
|
||||
|
||||
return rolling;
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
#pragma once
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
class CVarList {
|
||||
public:
|
||||
/** Split string into arg list
|
||||
@param lastArgNo stop splitting after argv reaches maximum size, last arg will contain rest of unsplit args
|
||||
@param delim if delimiter is 's', use std::isspace
|
||||
@param removeEmpty remove empty args from argv
|
||||
*/
|
||||
CVarList(const std::string& in, const size_t maxSize = 0, const char delim = ',', const bool removeEmpty = false);
|
||||
|
||||
~CVarList() = default;
|
||||
|
||||
size_t size() const {
|
||||
return m_vArgs.size();
|
||||
}
|
||||
|
||||
std::string join(const std::string& joiner, size_t from = 0, size_t to = 0) const;
|
||||
|
||||
void map(std::function<void(std::string&)> func) {
|
||||
for (auto& s : m_vArgs)
|
||||
func(s);
|
||||
}
|
||||
|
||||
void append(const std::string arg) {
|
||||
m_vArgs.emplace_back(arg);
|
||||
}
|
||||
|
||||
std::string operator[](const size_t& idx) const {
|
||||
if (idx >= m_vArgs.size())
|
||||
return "";
|
||||
return m_vArgs[idx];
|
||||
}
|
||||
|
||||
// for range-based loops
|
||||
std::vector<std::string>::iterator begin() {
|
||||
return m_vArgs.begin();
|
||||
}
|
||||
std::vector<std::string>::const_iterator begin() const {
|
||||
return m_vArgs.begin();
|
||||
}
|
||||
std::vector<std::string>::iterator end() {
|
||||
return m_vArgs.end();
|
||||
}
|
||||
std::vector<std::string>::const_iterator end() const {
|
||||
return m_vArgs.end();
|
||||
}
|
||||
|
||||
bool contains(const std::string& el) {
|
||||
for (auto& a : m_vArgs) {
|
||||
if (a == el)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::string> m_vArgs;
|
||||
};
|
|
@ -8,10 +8,11 @@
|
|||
#include <expected>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
|
||||
#include "VarList.hpp"
|
||||
#include <hyprutils/string/VarList.hpp>
|
||||
#include <hyprutils/string/String.hpp>
|
||||
|
||||
using namespace Hyprlang;
|
||||
using namespace Hyprutils::String;
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <crt_externs.h>
|
||||
|
@ -33,25 +34,6 @@ static size_t seekABIStructSize(const void* begin, size_t startOffset, size_t ma
|
|||
return 0;
|
||||
}
|
||||
|
||||
static std::string removeBeginEndSpacesTabs(std::string str) {
|
||||
if (str.empty())
|
||||
return str;
|
||||
|
||||
int countBefore = 0;
|
||||
while (str[countBefore] == ' ' || str[countBefore] == '\t') {
|
||||
countBefore++;
|
||||
}
|
||||
|
||||
int countAfter = 0;
|
||||
while ((int)str.length() - countAfter - 1 >= 0 && (str[str.length() - countAfter - 1] == ' ' || str[str.length() - 1 - countAfter] == '\t')) {
|
||||
countAfter++;
|
||||
}
|
||||
|
||||
str = str.substr(countBefore, str.length() - countBefore - countAfter);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
CConfig::CConfig(const char* path, const Hyprlang::SConfigOptions& options_) {
|
||||
SConfigOptions options;
|
||||
std::memcpy(&options, &options_, seekABIStructSize(&options_, 16, sizeof(SConfigOptions)));
|
||||
|
@ -177,62 +159,27 @@ void CConfig::commence() {
|
|||
}
|
||||
}
|
||||
|
||||
static bool isNumber(const std::string& str, bool allowfloat) {
|
||||
|
||||
std::string copy = str;
|
||||
if (*copy.begin() == '-')
|
||||
copy = copy.substr(1);
|
||||
|
||||
if (copy.empty())
|
||||
return false;
|
||||
|
||||
bool point = !allowfloat;
|
||||
for (auto& c : copy) {
|
||||
if (c == '.') {
|
||||
if (point)
|
||||
return false;
|
||||
point = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!std::isdigit(c))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void replaceAll(std::string& str, const std::string& from, const std::string& to) {
|
||||
if (from.empty())
|
||||
return;
|
||||
size_t pos = 0;
|
||||
while ((pos = str.find(from, pos)) != std::string::npos) {
|
||||
str.replace(pos, from.length(), to);
|
||||
pos += to.length();
|
||||
}
|
||||
}
|
||||
|
||||
static std::expected<int64_t, std::string> configStringToInt(const std::string& VALUE) {
|
||||
if (VALUE.starts_with("0x")) {
|
||||
// Values with 0x are hex
|
||||
const auto VALUEWITHOUTHEX = VALUE.substr(2);
|
||||
return stoll(VALUEWITHOUTHEX, nullptr, 16);
|
||||
} else if (VALUE.starts_with("rgba(") && VALUE.ends_with(')')) {
|
||||
const auto VALUEWITHOUTFUNC = removeBeginEndSpacesTabs(VALUE.substr(5, VALUE.length() - 6));
|
||||
const auto VALUEWITHOUTFUNC = trim(VALUE.substr(5, VALUE.length() - 6));
|
||||
|
||||
// try doing it the comma way first
|
||||
if (std::count(VALUEWITHOUTFUNC.begin(), VALUEWITHOUTFUNC.end(), ',') == 3) {
|
||||
// cool
|
||||
std::string rolling = VALUEWITHOUTFUNC;
|
||||
auto r = configStringToInt(removeBeginEndSpacesTabs(rolling.substr(0, rolling.find(','))));
|
||||
auto r = configStringToInt(trim(rolling.substr(0, rolling.find(','))));
|
||||
rolling = rolling.substr(rolling.find(',') + 1);
|
||||
auto g = configStringToInt(removeBeginEndSpacesTabs(rolling.substr(0, rolling.find(','))));
|
||||
auto g = configStringToInt(trim(rolling.substr(0, rolling.find(','))));
|
||||
rolling = rolling.substr(rolling.find(',') + 1);
|
||||
auto b = configStringToInt(removeBeginEndSpacesTabs(rolling.substr(0, rolling.find(','))));
|
||||
auto b = configStringToInt(trim(rolling.substr(0, rolling.find(','))));
|
||||
rolling = rolling.substr(rolling.find(',') + 1);
|
||||
uint8_t a = 0;
|
||||
try {
|
||||
a = std::round(std::stof(removeBeginEndSpacesTabs(rolling.substr(0, rolling.find(',')))) * 255.f);
|
||||
a = std::round(std::stof(trim(rolling.substr(0, rolling.find(',')))) * 255.f);
|
||||
} catch (std::exception& e) { return std::unexpected("failed parsing " + VALUEWITHOUTFUNC); }
|
||||
|
||||
if (!r.has_value() || !g.has_value() || !b.has_value())
|
||||
|
@ -249,17 +196,17 @@ static std::expected<int64_t, std::string> configStringToInt(const std::string&
|
|||
return std::unexpected("rgba() expects length of 8 characters (4 bytes) or 4 comma separated values");
|
||||
|
||||
} else if (VALUE.starts_with("rgb(") && VALUE.ends_with(')')) {
|
||||
const auto VALUEWITHOUTFUNC = removeBeginEndSpacesTabs(VALUE.substr(4, VALUE.length() - 5));
|
||||
const auto VALUEWITHOUTFUNC = trim(VALUE.substr(4, VALUE.length() - 5));
|
||||
|
||||
// try doing it the comma way first
|
||||
if (std::count(VALUEWITHOUTFUNC.begin(), VALUEWITHOUTFUNC.end(), ',') == 2) {
|
||||
// cool
|
||||
std::string rolling = VALUEWITHOUTFUNC;
|
||||
auto r = configStringToInt(removeBeginEndSpacesTabs(rolling.substr(0, rolling.find(','))));
|
||||
auto r = configStringToInt(trim(rolling.substr(0, rolling.find(','))));
|
||||
rolling = rolling.substr(rolling.find(',') + 1);
|
||||
auto g = configStringToInt(removeBeginEndSpacesTabs(rolling.substr(0, rolling.find(','))));
|
||||
auto g = configStringToInt(trim(rolling.substr(0, rolling.find(','))));
|
||||
rolling = rolling.substr(rolling.find(',') + 1);
|
||||
auto b = configStringToInt(removeBeginEndSpacesTabs(rolling.substr(0, rolling.find(','))));
|
||||
auto b = configStringToInt(trim(rolling.substr(0, rolling.find(','))));
|
||||
|
||||
if (!r.has_value() || !g.has_value() || !b.has_value())
|
||||
return std::unexpected("failed parsing " + VALUEWITHOUTFUNC);
|
||||
|
@ -513,7 +460,7 @@ CParseResult CConfig::parseVariable(const std::string& lhs, const std::string& r
|
|||
}
|
||||
|
||||
void CConfigImpl::parseComment(const std::string& comment) {
|
||||
const auto COMMENT = removeBeginEndSpacesTabs(comment);
|
||||
const auto COMMENT = trim(comment);
|
||||
|
||||
if (!COMMENT.starts_with("hyprlang"))
|
||||
return;
|
||||
|
@ -527,7 +474,7 @@ void CConfigImpl::parseComment(const std::string& comment) {
|
|||
CParseResult CConfig::parseLine(std::string line, bool dynamic) {
|
||||
CParseResult result;
|
||||
|
||||
line = removeBeginEndSpacesTabs(line);
|
||||
line = trim(line);
|
||||
|
||||
auto commentPos = line.find('#');
|
||||
|
||||
|
@ -556,7 +503,7 @@ CParseResult CConfig::parseLine(std::string line, bool dynamic) {
|
|||
}
|
||||
}
|
||||
|
||||
line = removeBeginEndSpacesTabs(line);
|
||||
line = trim(line);
|
||||
|
||||
if (line.empty())
|
||||
return result;
|
||||
|
@ -572,8 +519,8 @@ CParseResult CConfig::parseLine(std::string line, bool dynamic) {
|
|||
if (equalsPos != std::string::npos) {
|
||||
// set value or call handler
|
||||
CParseResult ret;
|
||||
auto LHS = removeBeginEndSpacesTabs(line.substr(0, equalsPos));
|
||||
auto RHS = removeBeginEndSpacesTabs(line.substr(equalsPos + 1));
|
||||
auto LHS = trim(line.substr(0, equalsPos));
|
||||
auto RHS = trim(line.substr(equalsPos + 1));
|
||||
|
||||
if (LHS.empty()) {
|
||||
result.setError("Empty lhs.");
|
||||
|
@ -591,9 +538,9 @@ CParseResult CConfig::parseLine(std::string line, bool dynamic) {
|
|||
const auto RHSIT = RHS.find("$" + var.name);
|
||||
|
||||
if (LHSIT != std::string::npos)
|
||||
replaceAll(LHS, "$" + var.name, var.value);
|
||||
replaceInString(LHS, "$" + var.name, var.value);
|
||||
if (RHSIT != std::string::npos)
|
||||
replaceAll(RHS, "$" + var.name, var.value);
|
||||
replaceInString(RHS, "$" + var.name, var.value);
|
||||
|
||||
if (RHSIT == std::string::npos && LHSIT == std::string::npos)
|
||||
continue;
|
||||
|
@ -657,7 +604,7 @@ CParseResult CConfig::parseLine(std::string line, bool dynamic) {
|
|||
}
|
||||
|
||||
line.pop_back();
|
||||
line = removeBeginEndSpacesTabs(line);
|
||||
line = trim(line);
|
||||
impl->categories.push_back(line);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue