commit db1adbb838250307595f0b41528f9c93e9546f77 Author: herbglitch Date: Thu Oct 27 15:16:54 2022 -0600 first diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e7bcb40 --- /dev/null +++ b/.gitignore @@ -0,0 +1,533 @@ +# Created by https://www.toptal.com/developers/gitignore/api/c,c++,visualstudiocode,visualstudio,vim,cmake +# Edit at https://www.toptal.com/developers/gitignore?templates=c,c++,visualstudiocode,visualstudio,vim,cmake + +### C ### +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf + +### C++ ### +# Prerequisites + +# Compiled Object files +*.slo + +# Precompiled Headers + +# Compiled Dynamic libraries + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai + +# Executables + +### CMake ### +CMakeLists.txt.user +CMakeCache.txt +CMakeFiles +CMakeScripts +Testing +Makefile +cmake_install.cmake +install_manifest.txt +compile_commands.json +CTestTestfile.cmake +_deps + +### CMake Patch ### +# External projects +*-prefix/ + +### Vim ### +# Swap +[._]*.s[a-v][a-z] +!*.svg # comment out if you don't need vector files +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +# Session +Session.vim +Sessionx.vim + +# Temporary +.netrwhist +*~ +# Auto-generated tag files +tags +# Persistent undo +[._]*.un~ + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets + +# Local History for Visual Studio Code +.history/ + +# Built Visual Studio Code Extensions +*.vsix + +### VisualStudioCode Patch ### +# Ignore all local history of files +.history +.ionide + +# Support for Project snippet scope +.vscode/*.code-snippets + +# Ignore code-workspaces +*.code-workspace + +### VisualStudio ### +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.meta +*.iobj +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.tlog +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio 6 auto-generated project file (contains which files were open etc.) +*.vbp + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) +*.dsw +*.dsp + +# Visual Studio 6 technical files + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# Visual Studio History (VSHistory) files +.vshistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +# VS Code files for those working on multiple tools + +# Local History for Visual Studio Code + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp + +# JetBrains Rider +*.sln.iml + +### VisualStudio Patch ### +# Additional files built by Visual Studio + +# End of https://www.toptal.com/developers/gitignore/api/c,c++,visualstudiocode,visualstudio,vim,cmake + +doxygen/html +[Bb][Uu][Ii][Ll][Dd] +.ccls \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..8a7c993 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,84 @@ +cmake_minimum_required(VERSION 3.10) + +set(ARCHEUS_STD_VERSION 0.0.0) +project(archeus_std LANGUAGES C VERSION ${ARCHEUS_STD_VERSION} DESCRIPTION "libarcheus_std standard archeus c library") + +include(GNUInstallDirs) + +function(print var) + message("${var} = ${${var}}") +endfunction() + +option(ARCHEUS_STD_DEBUG "Build in debug mode" ON) +option(ARCHEUS_STD_DEFAULT_CONFIG "Build with default config keys" ON) + +set(ARCHEUS_STD_FLAGS "") + +if(ARCHEUS_STD_DEBUG) + string(APPEND ARCHEUS_STD_FLAGS "-Wall -Werror -g ") +endif() + +if(ARCHEUS_STD_DEFAULT_CONFIG) + string(APPEND ARCHEUS_STD_FLAGS "-DARC_DEFAULT_CONFIG ") +endif() + +set(CMAKE_C_FLAGS ${ARCHEUS_STD_FLAGS}) + +add_library(archeus_std SHARED) + +target_sources(archeus_std PRIVATE + src/std/config.c +# src/arc_ecs.c + src/std/hashtable.c + src/std/io.c + src/std/string.c + src/std/vector.c + src/std/handler.c + + src/std/defaults/config.c +) + +target_include_directories(archeus_std PRIVATE + include +) + +install(TARGETS archeus_std EXPORT archeus_std_Exports + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) + +install(EXPORT archeus_std_Exports + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/archeus_std-${PROJECT_VERSION} +) + +install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/include/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + FILES_MATCHING + PATTERN *.h +) + +include(CMakePackageConfigHelpers) +set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}) +set(LIBRARY_INSTALL_BIN ${CMAKE_INSTALL_LIBDIR}) + +configure_package_config_file( + "${PROJECT_SOURCE_DIR}/cmake/archeus_std-config.cmake.in" + "${PROJECT_BINARY_DIR}/archeus_std-config.cmake" + + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/archeus_std-${PROJECT_VERSION} + PATH_VARS INCLUDE_INSTALL_DIR LIBRARY_INSTALL_BIN +) + +write_basic_package_version_file( + "archeus_std-ConfigVersion.cmake" + VERSION {PROJECT_VERSION} + COMPATIBILITY SameMajorVersion +) + +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/archeus_std-config.cmake + ${CMAKE_CURRENT_BINARY_DIR}/archeus_std-ConfigVersion.cmake +DESTINATION + ${CMAKE_INSTALL_LIBDIR}/cmake/archeus_std-${PROJECT_VERSION} +) diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 0000000..340951c --- /dev/null +++ b/Doxyfile @@ -0,0 +1,29 @@ +PROJECT_NAME = ge_lib +PROJECT_NUMBER = 0.0.0 +OUTPUT_DIRECTORY = ./doxygen/ +OPTIMIZE_OUTPUT_FOR_C = YES +EXTRACT_ALL = YES +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES +EXTRACT_ANON_NSPACES = YES +RECURSIVE = YES +SOURCE_BROWSER = YES +INLINE_SOURCES = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +USE_MATHJAX = NO +GENERATE_LATEX = NO +INPUT = ./src/ + +# Include the required Javascript +HTML_EXTRA_FILES = doxygen/doxygen-awesome-css/doxygen-awesome-darkmode-toggle.js + +# Add the additional CSS. This is ONLY required for the sidebar-only theme variant! +HTML_EXTRA_STYLESHEET = doxygen/doxygen-awesome-css/doxygen-awesome.css \ + doxygen/doxygen-awesome-css/doxygen-awesome-sidebar-only.css \ + doxygen/doxygen-awesome-css/doxygen-awesome-sidebar-only-darkmode-toggle.css + +# set custom header & footer files generated in previous step +HTML_HEADER = doxygen/doxygen-awesome-css/header.html +HTML_FOOTER = doxygen/doxygen-awesome-css/footer.html + diff --git a/cmake/archeus_std-config.cmake.in b/cmake/archeus_std-config.cmake.in new file mode 100644 index 0000000..c1ff713 --- /dev/null +++ b/cmake/archeus_std-config.cmake.in @@ -0,0 +1,9 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@_Exports.cmake") + +set_and_check(ARCHEUS_STD_INCLUDE_DIRS "@PACKAGE_INCLUDE_INSTALL_DIR@") +set_and_check(ARCHEUS_STD_LINK_DIRS "@PACKAGE_LIBRARY_INSTALL_BIN@") +set(ARCHEUS_STD_LIBRARIES "@PROJECT_NAME@") + +check_required_components("@PROJECT_NAME@") diff --git a/doxygen/doxygen-awesome-css/.github/workflows/publish.yaml b/doxygen/doxygen-awesome-css/.github/workflows/publish.yaml new file mode 100644 index 0000000..d415af3 --- /dev/null +++ b/doxygen/doxygen-awesome-css/.github/workflows/publish.yaml @@ -0,0 +1,29 @@ +name: publish +on: + release: + types: [published] +jobs: + deploy: + runs-on: ubuntu-20.04 + steps: + - name: Checkout repository + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: install Doxygen 1.9.2 + run: | + sudo apt-get update + sudo apt-get install -y graphviz libclang-cpp1-9 libclang1-9 + wget https://www.doxygen.nl/files/doxygen-1.9.2.linux.bin.tar.gz + tar -xvzf doxygen-1.9.2.linux.bin.tar.gz + ln -s doxygen-1.9.2/bin/doxygen doxygen + - name: set version + run: echo "PROJECT_NUMBER = `git describe --tags`" >> Doxyfile + - name: Generate Documentation + run: ./doxygen Doxyfile + - name: Publish generated content to GitHub Pages + uses: tsunematsu21/actions-publish-gh-pages@v1.0.1 + with: + dir: docs/html + branch: gh-pages + token: ${{ secrets.ACCESS_TOKEN }} \ No newline at end of file diff --git a/doxygen/doxygen-awesome-css/.gitignore b/doxygen/doxygen-awesome-css/.gitignore new file mode 100644 index 0000000..5c40af7 --- /dev/null +++ b/doxygen/doxygen-awesome-css/.gitignore @@ -0,0 +1,3 @@ +docs/html +.DS_Store +.idea \ No newline at end of file diff --git a/doxygen/doxygen-awesome-css/LICENSE b/doxygen/doxygen-awesome-css/LICENSE new file mode 100644 index 0000000..1d8b99a --- /dev/null +++ b/doxygen/doxygen-awesome-css/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 jothepro + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/doxygen/doxygen-awesome-css/docs/doxygen-custom/custom.css b/doxygen/doxygen-awesome-css/docs/doxygen-custom/custom.css new file mode 100644 index 0000000..73bedc4 --- /dev/null +++ b/doxygen/doxygen-awesome-css/docs/doxygen-custom/custom.css @@ -0,0 +1,16 @@ +.github-corner svg { + fill: var(--primary-light-color); + color: var(--page-background-color); + width: 72px; + height: 72px; +} + +@media screen and (max-width: 767px) { + .github-corner svg { + width: 55px; + height: 55px; + } + #projectnumber { + margin-right: 22px; + } +} diff --git a/doxygen/doxygen-awesome-css/docs/doxygen-custom/footer.html b/doxygen/doxygen-awesome-css/docs/doxygen-custom/footer.html new file mode 100644 index 0000000..d4a0439 --- /dev/null +++ b/doxygen/doxygen-awesome-css/docs/doxygen-custom/footer.html @@ -0,0 +1,30 @@ + + + + + + + + + + + diff --git a/doxygen/doxygen-awesome-css/docs/doxygen-custom/header.html b/doxygen/doxygen-awesome-css/docs/doxygen-custom/header.html new file mode 100644 index 0000000..0e9d120 --- /dev/null +++ b/doxygen/doxygen-awesome-css/docs/doxygen-custom/header.html @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + +$projectname: $title +$title + + + + + +$treeview +$search +$mathjax + +$extrastylesheet + + + + + + + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + +
+
$projectname +  $projectnumber +
+
$projectbrief
+
+
$projectbrief
+
$searchbox
+
+ + diff --git a/doxygen/doxygen-awesome-css/docs/page.dox b/doxygen/doxygen-awesome-css/docs/page.dox new file mode 100644 index 0000000..ab82ae9 --- /dev/null +++ b/doxygen/doxygen-awesome-css/docs/page.dox @@ -0,0 +1,15 @@ +/*! + +\page page1 Example Page +\tableofcontents +Leading text. +\section sec An example section +This page contains the subsections \ref subsection1 and \ref subsection2. +\subsection subsection1 The first subsection +Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. +\subsection subsection2 The second subsection +Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. + +\note Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. + +*/ \ No newline at end of file diff --git a/doxygen/doxygen-awesome-css/doxygen-awesome-darkmode-toggle.js b/doxygen/doxygen-awesome-css/doxygen-awesome-darkmode-toggle.js new file mode 100644 index 0000000..ae72bf7 --- /dev/null +++ b/doxygen/doxygen-awesome-css/doxygen-awesome-darkmode-toggle.js @@ -0,0 +1,115 @@ +/** + +Doxygen Awesome +https://github.com/jothepro/doxygen-awesome-css + +MIT License + +Copyright (c) 2021 jothepro + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + +class DoxygenAwesomeDarkModeToggle extends HTMLElement { + static prefersLightModeInDarkModeKey = "prefers-light-mode-in-dark-mode" + static prefersDarkModeInLightModeKey = "prefers-dark-mode-in-light-mode" + + static _staticConstructor = function() { + DoxygenAwesomeDarkModeToggle.darkModeEnabled = DoxygenAwesomeDarkModeToggle.userPreference + DoxygenAwesomeDarkModeToggle.enableDarkMode(DoxygenAwesomeDarkModeToggle.darkModeEnabled) + // Update the color scheme when the browsers preference changes + // without user interaction on the website. + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => { + DoxygenAwesomeDarkModeToggle.onSystemPreferenceChanged() + }) + // Update the color scheme when the tab is made visible again. + // It is possible that the appearance was changed in another tab + // while this tab was in the background. + document.addEventListener("visibilitychange", visibilityState => { + if (document.visibilityState === 'visible') { + DoxygenAwesomeDarkModeToggle.onSystemPreferenceChanged() + } + }); + }() + + constructor() { + super(); + this.onclick=this.toggleDarkMode + } + + /** + * @returns `true` for dark-mode, `false` for light-mode system preference + */ + static get systemPreference() { + return window.matchMedia('(prefers-color-scheme: dark)').matches + } + + /** + * @returns `true` for dark-mode, `false` for light-mode user preference + */ + static get userPreference() { + return (!DoxygenAwesomeDarkModeToggle.systemPreference && localStorage.getItem(DoxygenAwesomeDarkModeToggle.prefersDarkModeInLightModeKey)) || + (DoxygenAwesomeDarkModeToggle.systemPreference && !localStorage.getItem(DoxygenAwesomeDarkModeToggle.prefersLightModeInDarkModeKey)) + } + + static set userPreference(userPreference) { + DoxygenAwesomeDarkModeToggle.darkModeEnabled = userPreference + if(!userPreference) { + if(DoxygenAwesomeDarkModeToggle.systemPreference) { + localStorage.setItem(DoxygenAwesomeDarkModeToggle.prefersLightModeInDarkModeKey, true) + } else { + localStorage.removeItem(DoxygenAwesomeDarkModeToggle.prefersDarkModeInLightModeKey) + } + } else { + if(!DoxygenAwesomeDarkModeToggle.systemPreference) { + localStorage.setItem(DoxygenAwesomeDarkModeToggle.prefersDarkModeInLightModeKey, true) + } else { + localStorage.removeItem(DoxygenAwesomeDarkModeToggle.prefersLightModeInDarkModeKey) + } + } + DoxygenAwesomeDarkModeToggle.onUserPreferenceChanged() + } + + static enableDarkMode(enable) { + let head = document.getElementsByTagName('head')[0] + if(enable) { + document.documentElement.classList.add("dark-mode") + document.documentElement.classList.remove("light-mode") + } else { + document.documentElement.classList.remove("dark-mode") + document.documentElement.classList.add("light-mode") + } + } + + static onSystemPreferenceChanged() { + DoxygenAwesomeDarkModeToggle.darkModeEnabled = DoxygenAwesomeDarkModeToggle.userPreference + DoxygenAwesomeDarkModeToggle.enableDarkMode(DoxygenAwesomeDarkModeToggle.darkModeEnabled) + } + + static onUserPreferenceChanged() { + DoxygenAwesomeDarkModeToggle.enableDarkMode(DoxygenAwesomeDarkModeToggle.darkModeEnabled) + } + + toggleDarkMode() { + DoxygenAwesomeDarkModeToggle.userPreference = !DoxygenAwesomeDarkModeToggle.userPreference + } +} + +customElements.define("doxygen-awesome-dark-mode-toggle", DoxygenAwesomeDarkModeToggle); diff --git a/doxygen/doxygen-awesome-css/doxygen-awesome-sidebar-only-darkmode-toggle.css b/doxygen/doxygen-awesome-css/doxygen-awesome-sidebar-only-darkmode-toggle.css new file mode 100644 index 0000000..b988b6f --- /dev/null +++ b/doxygen/doxygen-awesome-css/doxygen-awesome-sidebar-only-darkmode-toggle.css @@ -0,0 +1,40 @@ + +/** + +Doxygen Awesome +https://github.com/jothepro/doxygen-awesome-css + +MIT License + +Copyright (c) 2021 jothepro + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + +@media screen and (min-width: 768px) { + + #MSearchBox { + width: calc(var(--side-nav-fixed-width) - calc(2 * var(--spacing-medium)) - var(--searchbar-height) - 1px); + } + + #MSearchField { + width: calc(var(--side-nav-fixed-width) - calc(2 * var(--spacing-medium)) - 66px - var(--searchbar-height)); + } +} diff --git a/doxygen/doxygen-awesome-css/doxygen-awesome-sidebar-only.css b/doxygen/doxygen-awesome-css/doxygen-awesome-sidebar-only.css new file mode 100644 index 0000000..655a90c --- /dev/null +++ b/doxygen/doxygen-awesome-css/doxygen-awesome-sidebar-only.css @@ -0,0 +1,108 @@ +/** + +Doxygen Awesome +https://github.com/jothepro/doxygen-awesome-css + +MIT License + +Copyright (c) 2021 jothepro + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + */ + +html { + /* side nav width. MUST be = `TREEVIEW_WIDTH`. + * Make sure it is wide enought to contain the page title (logo + title + version) + */ + --side-nav-fixed-width: 340px; + --menu-display: none; + + --top-height: 120px; +} + + +@media screen and (min-width: 768px) { + html { + --searchbar-background: var(--page-background-color); + } + + #side-nav { + min-width: var(--side-nav-fixed-width); + max-width: var(--side-nav-fixed-width); + top: var(--top-height); + overflow: visible; + } + + #nav-tree, #side-nav { + height: calc(100vh - var(--top-height)) !important; + } + + #nav-tree { + padding: 0; + } + + #top { + display: block; + border-bottom: none; + height: var(--top-height); + margin-bottom: calc(0px - var(--top-height)); + max-width: var(--side-nav-fixed-width); + background: var(--side-nav-background); + } + #main-nav { + float: left; + padding-right: 0; + } + + .ui-resizable-handle { + cursor: default; + width: 1px !important; + box-shadow: 0 calc(-2 * var(--top-height)) 0 0 var(--separator-color); + } + + #nav-path { + position: fixed; + right: 0; + left: var(--side-nav-fixed-width); + bottom: 0; + width: auto; + } + + #doc-content { + height: calc(100vh - 31px) !important; + padding-bottom: calc(3 * var(--spacing-large)); + padding-top: calc(var(--top-height) - 80px); + box-sizing: border-box; + margin-left: var(--side-nav-fixed-width) !important; + } + + #MSearchBox { + width: calc(var(--side-nav-fixed-width) - calc(2 * var(--spacing-medium))); + } + + #MSearchField { + width: calc(var(--side-nav-fixed-width) - calc(2 * var(--spacing-medium)) - 65px); + } + + #MSearchResultsWindow { + left: var(--spacing-medium) !important; + right: auto; + } +} diff --git a/doxygen/doxygen-awesome-css/doxygen-awesome.css b/doxygen/doxygen-awesome-css/doxygen-awesome.css new file mode 100644 index 0000000..549c139 --- /dev/null +++ b/doxygen/doxygen-awesome-css/doxygen-awesome.css @@ -0,0 +1,1504 @@ +/** + +Doxygen Awesome +https://github.com/jothepro/doxygen-awesome-css + +MIT License + +Copyright (c) 2021 jothepro + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + +html { + /* primary theme color. This will affect the entire websites color scheme: links, arrows, labels, ... */ + --primary-color: #1779c4; + --primary-dark-color: #00559f; + --primary-light-color: #7aabd6; + --primary-lighter-color: #cae1f1; + --primary-lightest-color: #e9f1f8; + + /* page base colors */ + --page-background-color: white; + --page-foreground-color: #2c3e50; + --page-secondary-foreground-color: #67727e; + + /* color for all separators on the website: hr, borders, ... */ + --separator-color: #dedede; + + /* border radius for all rounded components. Will affect many components, like dropdowns, memitems, codeblocks, ... */ + --border-radius-large: 8px; + --border-radius-small: 4px; + --border-radius-medium: 6px; + + /* default spacings. Most compontest reference these values for spacing, to provide uniform spacing on the page. */ + --spacing-small: 5px; + --spacing-medium: 10px; + --spacing-large: 16px; + + /* default box shadow used for raising an element above the normal content. Used in dropdowns, Searchresult, ... */ + --box-shadow: 0 2px 10px 0 rgba(0,0,0,.1); + + --odd-color: rgba(0,0,0,.03); + + /* font-families. will affect all text on the website + * font-family: the normal font for text, headlines, menus + * font-family-monospace: used for preformatted text in memtitle, code, fragments + */ + --font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif; + --font-family-monospace: source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace; + + /* font sizes */ + --page-font-size: 15.6px; + --navigation-font-size: 14.4px; + --code-font-size: 14.4px; /* affects code, fragment */ + --title-font-size: 22px; + + /* content text properties. These only affect the page content, not the navigation or any other ui elements */ + --content-line-height: 27px; + /* The content is centered and constraint in it's width. To make the content fill the whole page, set the variable to auto.*/ + --content-maxwidth: 1000px; + + /* colors for various content boxes: @warning, @note, @deprecated @bug */ + --warning-color: #fca49b; + --warning-color-dark: #b61825; + --warning-color-darker: #75070f; + --note-color: rgba(255,229,100,.3); + --note-color-dark: #c39900; + --note-color-darker: #8d7400; + --deprecated-color: rgb(214, 216, 224); + --deprecated-color-dark: #5b6269; + --deprecated-color-darker: #43454a; + --bug-color: rgb(246, 208, 178); + --bug-color-dark: #a53a00; + --bug-color-darker: #5b1d00; + --invariant-color: #b7f8d0; + --invariant-color-dark: #00ba44; + --invariant-color-darker: #008622; + + /* blockquote colors */ + --blockquote-background: #f5f5f5; + --blockquote-foreground: #727272; + + /* table colors */ + --tablehead-background: #f1f1f1; + --tablehead-foreground: var(--page-foreground-color); + + /* menu-display: block | none + * Visibility of the top navigation on screens >= 768px. On smaller screen the menu is always visible. + * `GENERATE_TREEVIEW` MUST be enabled! + */ + --menu-display: block; + + --menu-focus-foreground: var(--page-background-color); + --menu-focus-background: var(--primary-color); + --menu-selected-background: rgba(0,0,0,.05); + + + --header-background: var(--page-background-color); + --header-foreground: var(--page-foreground-color); + + /* searchbar colors */ + --searchbar-background: var(--side-nav-background); + --searchbar-foreground: var(--page-foreground-color); + + /* searchbar size + * (`searchbar-width` is only applied on screens >= 768px. + * on smaller screens the searchbar will always fill the entire screen width) */ + --searchbar-height: 33px; + --searchbar-width: 210px; + + /* code block colors */ + --code-background: #f5f5f5; + --code-foreground: var(--page-foreground-color); + + /* fragment colors */ + --fragment-background: #282c34; + --fragment-foreground: #ffffff; + --fragment-keyword: #cc99cd; + --fragment-keywordtype: #ab99cd; + --fragment-keywordflow: #e08000; + --fragment-token: #7ec699; + --fragment-comment: #999999; + --fragment-link: #98c0e3; + --fragment-preprocessor: #65cabe; + --fragment-linenumber-color: #cccccc; + --fragment-linenumber-background: #35393c; + --fragment-linenumber-border: #1f1f1f; + --fragment-lineheight: 20px; + + /* sidebar navigation (treeview) colors */ + --side-nav-background: #fbfbfb; + --side-nav-foreground: var(--page-foreground-color); + --side-nav-arrow-opacity: 0; + --side-nav-arrow-hover-opacity: 0.9; + + /* height of an item in any tree / collapsable table */ + --tree-item-height: 30px; + + --darkmode-toggle-button-icon: '☀️' +} + +@media screen and (max-width: 767px) { + html { + --page-font-size: 16px; + --navigation-font-size: 16px; + --code-font-size: 15px; /* affects code, fragment */ + --title-font-size: 22px; + } +} + +@media (prefers-color-scheme: dark) { + html:not(.light-mode) { + color-scheme: dark; + + --primary-color: #1982d2; + --primary-dark-color: #5ca8e2; + --primary-light-color: #4779ac; + --primary-lighter-color: #191e21; + --primary-lightest-color: #191a1c; + + --box-shadow: 0 2px 10px 0 rgba(0,0,0,.35); + + --odd-color: rgba(0,0,0,.1); + + --menu-selected-background: rgba(0,0,0,.4); + + --page-background-color: #1C1D1F; + --page-foreground-color: #d2dbde; + --page-secondary-foreground-color: #859399; + --separator-color: #000000; + --side-nav-background: #252628; + + --code-background: #2a2c2f; + + --tablehead-background: #2a2c2f; + + --blockquote-background: #1f2022; + --blockquote-foreground: #77848a; + + --warning-color: #b61825; + --warning-color-dark: #510a02; + --warning-color-darker: #f5b1aa; + --note-color: rgb(255, 183, 0); + --note-color-dark: #9f7300; + --note-color-darker: #645b39; + --deprecated-color: rgb(88, 90, 96); + --deprecated-color-dark: #262e37; + --deprecated-color-darker: #a0a5b0; + --bug-color: rgb(248, 113, 0); + --bug-color-dark: #812a00; + --bug-color-darker: #ffd3be; + + --darkmode-toggle-button-icon: '🌛'; + } +} + +/* dark mode variables are defined twice, to support both the dark-mode without and with doxygen-awesome-darkmode-toggle.js */ +html.dark-mode { + color-scheme: dark; + + --primary-color: #1982d2; + --primary-dark-color: #5ca8e2; + --primary-light-color: #4779ac; + --primary-lighter-color: #191e21; + --primary-lightest-color: #191a1c; + + --box-shadow: 0 2px 10px 0 rgba(0,0,0,.35); + + --odd-color: rgba(0,0,0,.1); + + --menu-selected-background: rgba(0,0,0,.4); + + --page-background-color: #1C1D1F; + --page-foreground-color: #d2dbde; + --page-secondary-foreground-color: #859399; + --separator-color: #000000; + --side-nav-background: #252628; + + --code-background: #2a2c2f; + + --tablehead-background: #2a2c2f; + + --blockquote-background: #1f2022; + --blockquote-foreground: #77848a; + + --warning-color: #b61825; + --warning-color-dark: #510a02; + --warning-color-darker: #f5b1aa; + --note-color: rgb(255, 183, 0); + --note-color-dark: #9f7300; + --note-color-darker: #645b39; + --deprecated-color: rgb(88, 90, 96); + --deprecated-color-dark: #262e37; + --deprecated-color-darker: #a0a5b0; + --bug-color: rgb(248, 113, 0); + --bug-color-dark: #812a00; + --bug-color-darker: #ffd3be; + + --darkmode-toggle-button-icon: '🌛'; +} + +body { + color: var(--page-foreground-color); + background-color: var(--page-background-color); + font-size: var(--page-font-size); +} + +body, table, div, p, dl, #nav-tree .label, .title, .sm-dox a, .sm-dox a:hover, .sm-dox a:focus, #projectname, .SelectItem, #MSearchField, .navpath li.navelem a, .navpath li.navelem a:hover { + font-family: var(--font-family); +} + +h1, h2, h3, h4, h5 { + margin-top: .9em; + font-weight: 600; + line-height: initial; +} + +p, div, table, dl { + font-size: var(--page-font-size); +} + +a:link, a:visited, a:hover, a:focus, a:active { + color: var(--primary-color) !important; + font-weight: 500; +} + +/* + Title and top navigation + */ + +#top { + background: var(--header-background); + border-bottom: 1px solid var(--separator-color); +} + +@media screen and (min-width: 768px) { + #top { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + align-items: center; + } +} + +#main-nav { + flex-grow: 5; + padding: var(--spacing-small) var(--spacing-medium); +} + +#titlearea { + width: auto; + padding: var(--spacing-medium) var(--spacing-large); + background: none; + color: var(--header-foreground); + border-bottom: none; +} + +@media screen and (max-width: 767px) { + #titlearea { + padding-bottom: var(--spacing-small); + } +} + +#titlearea table tbody tr { + height: auto !important; +} + +#projectname { + font-size: var(--title-font-size); + font-weight: 600; +} + +#projectnumber { + font-family: inherit; + font-size: 60%; +} + +#projectbrief { + font-family: inherit; + font-size: 80%; +} + +#projectlogo { + vertical-align: middle; +} + +#projectlogo img { + max-height: calc(var(--title-font-size) * 2); + margin-right: var(--spacing-small); +} + +.sm-dox, .tabs, .tabs2, .tabs3 { + background: none; + padding: 0; +} + +.tabs, .tabs2, .tabs3 { + border-bottom: 1px solid var(--separator-color); + margin-bottom: -1px; +} + +@media screen and (max-width: 767px) { + .sm-dox a span.sub-arrow { + background: var(--code-background); + } +} + +@media screen and (min-width: 768px) { + .sm-dox li, .tablist li { + display: var(--menu-display); + } + + .sm-dox a span.sub-arrow { + border-color: var(--header-foreground) transparent transparent transparent; + } + + .sm-dox a:hover span.sub-arrow { + border-color: var(--menu-focus-foreground) transparent transparent transparent; + } + + .sm-dox ul a span.sub-arrow { + border-color: transparent transparent transparent var(--page-foreground-color); + } + + .sm-dox ul a:hover span.sub-arrow { + border-color: transparent transparent transparent var(--menu-focus-foreground); + } +} + +.sm-dox ul { + background: var(--page-background-color); + box-shadow: var(--box-shadow); + border: 1px solid var(--separator-color); + border-radius: var(--border-radius-medium) !important; + padding: var(--spacing-small); + animation: ease-out 150ms slideInMenu; +} + +@keyframes slideInMenu { + from { + opacity: 0; + transform: translate(0px, -2px); + } + + to { + opacity: 1; + transform: translate(0px, 0px); + } +} + +.sm-dox ul a { + color: var(--page-foreground-color) !important; + background: var(--page-background-color); + font-size: var(--navigation-font-size); +} + +.sm-dox>li>ul:after { + border-bottom-color: var(--page-background-color) !important; +} + +.sm-dox>li>ul:before { + border-bottom-color: var(--separator-color) !important; +} + +.sm-dox ul a:hover, .sm-dox ul a:active, .sm-dox ul a:focus { + font-size: var(--navigation-font-size) !important; + color: var(--menu-focus-foreground) !important; + text-shadow: none; + background-color: var(--menu-focus-background); + border-radius: var(--border-radius-small) !important; +} + +.sm-dox a, .sm-dox a:focus, .tablist li, .tablist li a, .tablist li.current a { + text-shadow: none; + background: transparent; + background-image: none !important; + color: var(--header-foreground) !important; + font-weight: normal; + font-size: var(--navigation-font-size); +} + +.sm-dox a:focus { + outline: auto; +} + +.sm-dox a:hover, .sm-dox a:active, .tablist li a:hover { + text-shadow: none; + font-weight: normal; + background: var(--menu-focus-background); + color: var(--menu-focus-foreground) !important; + border-radius: var(--border-radius-small) !important; + font-size: var(--navigation-font-size); +} + +.tablist li.current { + border-radius: var(--border-radius-small); + background: var(--menu-selected-background); +} + +.tablist li { + margin: var(--spacing-small) 0 var(--spacing-small) var(--spacing-small); +} + +.tablist a { + padding: 0 var(--spacing-large); +} + + +/* + Search box + */ + +#MSearchBox { + height: var(--searchbar-height); + background: var(--searchbar-background); + border-radius: var(--searchbar-height); + border: 1px solid var(--separator-color); + overflow: hidden; + width: var(--searchbar-width); + position: relative; + box-shadow: none; + display: block; + margin-top: 0; +} + +.left #MSearchSelect { + left: 0; +} + +.tabs .left #MSearchSelect { + padding-left: 0; +} + +.tabs #MSearchBox { + position: absolute; + right: var(--spacing-medium); +} + +@media screen and (max-width: 767px) { + .tabs #MSearchBox { + position: relative; + right: 0; + margin-left: var(--spacing-medium); + margin-top: 0; + } +} + +#MSearchSelectWindow, #MSearchResultsWindow { + z-index: 9999; +} + +#MSearchBox.MSearchBoxActive { + border-color: var(--primary-color); + box-shadow: inset 0 0 0 1px var(--primary-color); +} + +#main-menu > li:last-child { + margin-right: 0; +} + +@media screen and (max-width: 767px) { + #main-menu > li:last-child { + height: 50px; + } +} + +#MSearchField { + font-size: var(--navigation-font-size); + height: calc(var(--searchbar-height) - 2px); + background: transparent; + width: calc(var(--searchbar-width) - 64px); +} + +.MSearchBoxActive #MSearchField { + color: var(--searchbar-foreground); +} + +#MSearchSelect { + top: calc(calc(var(--searchbar-height) / 2) - 11px); +} + +.left #MSearchSelect { + padding-left: 8px; +} + +#MSearchBox span.left, #MSearchBox span.right { + background: none; +} + +#MSearchBox span.right { + padding-top: calc(calc(var(--searchbar-height) / 2) - 12px); + position: absolute; + right: var(--spacing-small); +} + +.tabs #MSearchBox span.right { + top: calc(calc(var(--searchbar-height) / 2) - 12px); +} + +@keyframes slideInSearchResults { + from { + opacity: 0; + transform: translate(0, 15px); + } + + to { + opacity: 1; + transform: translate(0, 20px); + } +} + +#MSearchResultsWindow { + left: auto !important; + right: var(--spacing-medium); + border-radius: var(--border-radius-large); + border: 1px solid var(--separator-color); + transform: translate(0, 20px); + box-shadow: var(--box-shadow); + animation: ease-out 280ms slideInSearchResults; + background: var(--page-background-color); +} + +iframe#MSearchResults { + margin: 4px; +} + +iframe { + color-scheme: normal; +} + +@media (prefers-color-scheme: dark) { + html:not(.light-mode) iframe#MSearchResults { + filter: invert() hue-rotate(180deg); + } +} + +html.dark-mode iframe#MSearchResults { + filter: invert() hue-rotate(180deg); +} + +#MSearchSelectWindow { + border: 1px solid var(--separator-color); + border-radius: var(--border-radius-medium); + box-shadow: var(--box-shadow); + background: var(--page-background-color); +} + +#MSearchSelectWindow a.SelectItem { + font-size: var(--navigation-font-size); + line-height: var(--content-line-height); + margin: 0 var(--spacing-small); + border-radius: var(--border-radius-small); + color: var(--page-foreground-color) !important; + font-weight: normal; +} + +#MSearchSelectWindow a.SelectItem:hover { + background: var(--menu-focus-background); + color: var(--menu-focus-foreground) !important; +} + +@media screen and (max-width: 767px) { + #MSearchBox { + margin-top: var(--spacing-medium); + margin-bottom: var(--spacing-medium); + width: calc(100vw - 30px); + } + + #main-menu > li:last-child { + float: none !important; + } + + #MSearchField { + width: calc(100vw - 110px); + } + + @keyframes slideInSearchResultsMobile { + from { + opacity: 0; + transform: translate(0, 15px); + } + + to { + opacity: 1; + transform: translate(0, 20px); + } + } + + #MSearchResultsWindow { + left: var(--spacing-medium) !important; + right: var(--spacing-medium); + overflow: auto; + transform: translate(0, 20px); + animation: ease-out 280ms slideInSearchResultsMobile; + } + + /* + * Overwrites for fixing the searchbox on mobile in doxygen 1.9.2 + */ + label.main-menu-btn ~ #searchBoxPos1 { + top: 3px !important; + right: 6px !important; + left: 45px; + display: flex; + } + + label.main-menu-btn ~ #searchBoxPos1 > #MSearchBox { + margin-top: 0; + margin-bottom: 0; + flex-grow: 2; + float: left; + } +} + +/* + Tree view + */ + +#side-nav { + padding: 0 !important; + background: var(--side-nav-background); +} + +@media screen and (max-width: 767px) { + #side-nav { + display: none; + } + + #doc-content { + margin-left: 0 !important; + height: auto !important; + padding-bottom: calc(2 * var(--spacing-large)); + } +} + +#nav-tree { + background: transparent; +} + +#nav-tree .label { + font-size: var(--navigation-font-size); +} + +#nav-tree .item { + height: var(--tree-item-height); + line-height: var(--tree-item-height); +} + +#nav-sync { + top: 12px !important; + right: 12px; +} + +#nav-tree .selected { + text-shadow: none; + background-image: none; + background-color: transparent; + box-shadow: inset 4px 0 0 0 var(--primary-color); +} + +#nav-tree a { + color: var(--side-nav-foreground) !important; + font-weight: normal; +} + +#nav-tree a:focus { + outline-style: auto; +} + +#nav-tree .arrow { + opacity: var(--side-nav-arrow-opacity); +} + +.arrow { + color: inherit; + cursor: pointer; + font-size: 45%; + vertical-align: middle; + margin-right: 2px; + font-family: serif; + height: auto; + text-align: right; +} + +#nav-tree div.item:hover .arrow, #nav-tree a:focus .arrow { + opacity: var(--side-nav-arrow-hover-opacity); +} + +#nav-tree .selected a { + color: var(--primary-color) !important; + font-weight: bolder; + font-weight: 600; +} + +.ui-resizable-e { + background: var(--separator-color); + width: 1px; +} + +/* + Contents + */ + +div.header { + border-bottom: 1px solid var(--separator-color); + background-color: var(--page-background-color); + background-image: none; +} + +div.contents, div.header .title, div.header .summary { + max-width: var(--content-maxwidth); +} + +div.contents, div.header .title { + line-height: initial; + margin: calc(var(--spacing-medium) + .2em) auto var(--spacing-medium) auto; +} + +div.header .summary { + margin: var(--spacing-medium) auto 0 auto; +} + +div.headertitle { + padding: 0; +} + +div.header .title { + font-weight: 600; + font-size: 210%; + padding: var(--spacing-medium) var(--spacing-large); + word-break: break-word; +} + +div.header .summary { + width: auto; + display: block; + float: none; + padding: 0 var(--spacing-large); +} + +td.memSeparator { + border-color: var(--separator-color); +} + +.mdescLeft, .mdescRight, .memItemLeft, .memItemRight, .memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background: var(--code-background); +} + +.mdescRight { + color: var(--page-secondary-foreground-color); +} + +span.mlabel { + background: var(--primary-color); + border: none; + padding: 4px 9px; + border-radius: 12px; + margin-right: var(--spacing-medium); +} + +span.mlabel:last-of-type { + margin-right: 2px; +} + +div.contents { + padding: 0 var(--spacing-large); +} + +div.contents p, div.contents li { + line-height: var(--content-line-height); +} + +div.contents div.dyncontent { + margin: var(--spacing-medium) 0; +} + +@media (prefers-color-scheme: dark) { + html:not(.light-mode) div.contents div.dyncontent img, + html:not(.light-mode) div.contents center img, + html:not(.light-mode) div.contents table img, + html:not(.light-mode) div.contents div.dyncontent iframe, + html:not(.light-mode) div.contents center iframe, + html:not(.light-mode) div.contents table iframe { + filter: hue-rotate(180deg) invert(); + } +} + +html.dark-mode div.contents div.dyncontent img, +html.dark-mode div.contents center img, +html.dark-mode div.contents table img, +html.dark-mode div.contents div.dyncontent iframe, +html.dark-mode div.contents center iframe, +html.dark-mode div.contents table iframe { + filter: hue-rotate(180deg) invert(); +} + +h2.groupheader { + border-bottom: 1px solid var(--separator-color); + color: var(--page-foreground-color); +} + +blockquote { + padding: var(--spacing-small) var(--spacing-medium); + background: var(--blockquote-background); + color: var(--blockquote-foreground); + border-left: 2px solid var(--blockquote-foreground); + margin: 0; +} + +blockquote p { + margin: var(--spacing-small) 0 var(--spacing-medium) 0; +} +.paramname { + font-weight: 600; + color: var(--primary-dark-color); +} + +.glow { + text-shadow: 0 0 15px var(--primary-light-color) !important; +} + +.alphachar a { + color: var(--page-foreground-color); +} + +/* + Table of Contents + */ + +div.toc { + background-color: var(--side-nav-background); + border: 1px solid var(--separator-color); + border-radius: var(--border-radius-medium); + box-shadow: var(--box-shadow); + padding: 0 var(--spacing-large); + margin: 0 0 var(--spacing-medium) var(--spacing-medium); +} + +div.toc h3 { + color: var(--side-nav-foreground); + font-size: var(--navigation-font-size); + margin: var(--spacing-large) 0; +} + +div.toc li { + font-size: var(--navigation-font-size); + padding: 0; + background: none; +} + +div.toc li:before { + content: '↓'; + font-weight: 800; + font-family: var(--font-family); + margin-right: var(--spacing-small); + color: var(--side-nav-foreground); + opacity: .4; +} + +div.toc ul li.level1 { + margin: 0; +} + +div.toc ul li.level2, div.toc ul li.level3 { + margin-top: 0; +} + + +@media screen and (max-width: 767px) { + div.toc { + float: none; + width: auto; + margin: 0 0 var(--spacing-medium) 0; + } +} + +/* + Code & Fragments + */ + +code, div.fragment, pre.fragment { + border-radius: var(--border-radius-small); + border: none; + overflow: hidden; +} + +code { + display: inline; + background: var(--code-background); + color: var(--code-foreground); + padding: 2px 6px; + word-break: break-word; +} + +div.fragment, pre.fragment { + margin: var(--spacing-medium) 0; + padding: 14px 16px; + background: var(--fragment-background); + color: var(--fragment-foreground); + overflow-x: auto; +} + +@media screen and (max-width: 767px) { + div.fragment, pre.fragment { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + + .contents > div.fragment, .textblock > div.fragment, .textblock > pre.fragment { + margin: var(--spacing-medium) calc(0px - var(--spacing-large)); + border-radius: 0; + } + + .textblock li > .fragment { + margin: var(--spacing-medium) calc(0px - var(--spacing-large)); + } + + .memdoc li > .fragment { + margin: var(--spacing-medium) calc(0px - var(--spacing-medium)); + } + + .memdoc > div.fragment, .memdoc > pre.fragment, dl dd > div.fragment, dl dd pre.fragment { + margin: var(--spacing-medium) calc(0px - var(--spacing-medium)); + border-radius: 0; + } +} + +code, code a, pre.fragment, div.fragment, div.fragment .line, div.fragment span, div.fragment .line a, div.fragment .line span { + font-family: var(--font-family-monospace); + font-size: var(--code-font-size) !important; +} + +div.line:after { + margin-right: var(--spacing-medium); +} + +div.fragment .line, pre.fragment { + white-space: pre; + word-wrap: initial; + line-height: var(--fragment-lineheight); +} + +div.fragment span.keyword { + color: var(--fragment-keyword); +} + +div.fragment span.keywordtype { + color: var(--fragment-keywordtype); +} + +div.fragment span.keywordflow { + color: var(--fragment-keywordflow); +} + +div.fragment span.stringliteral { + color: var(--fragment-token) +} + +div.fragment span.comment { + color: var(--fragment-comment); +} + +div.fragment a.code { + color: var(--fragment-link) !important; +} + +div.fragment span.preprocessor { + color: var(--fragment-preprocessor); +} + +div.fragment span.lineno { + display: inline-block; + width: 27px; + border-right: none; + background: var(--fragment-linenumber-background); + color: var(--fragment-linenumber-color); +} + +div.fragment span.lineno a { + background: none; + color: var(--fragment-link) !important; +} + +div.fragment .line:first-child .lineno { + box-shadow: -999999px 0px 0 999999px var(--fragment-linenumber-background), -999998px 0px 0 999999px var(--fragment-linenumber-border); +} + +/* + dl warning, attention, note, deprecated, bug, ... + */ + +dl.warning, dl.attention, dl.note, dl.deprecated, dl.bug, dl.invariant, dl.pre { + padding: var(--spacing-medium); + margin: var(--spacing-medium) 0; + color: var(--page-background-color); + overflow: hidden; + margin-left: 0; + border-radius: var(--border-radius-small); +} + +dl.section dd { + margin-bottom: 2px; +} + +dl.warning, dl.attention { + background: var(--warning-color); + border-left: 8px solid var(--warning-color-dark); + color: var(--warning-color-darker); +} + +dl.warning dt, dl.attention dt { + color: var(--warning-color-dark); +} + +dl.note { + background: var(--note-color); + border-left: 8px solid var(--note-color-dark); + color: var(--note-color-darker); +} + +dl.note dt { + color: var(--note-color-dark); +} + +dl.bug { + background: var(--bug-color); + border-left: 8px solid var(--bug-color-dark); + color: var(--bug-color-darker); +} + +dl.bug dt a { + color: var(--bug-color-dark) !important; +} + +dl.deprecated { + background: var(--deprecated-color); + border-left: 8px solid var(--deprecated-color-dark); + color: var(--deprecated-color-darker); +} + +dl.deprecated dt a { + color: var(--deprecated-color-dark) !important; +} + +dl.section dd, dl.bug dd, dl.deprecated dd { + margin-inline-start: 0px; +} + +dl.invariant, dl.pre { + background: var(--invariant-color); + border-left: 8px solid var(--invariant-color-dark); + color: var(--invariant-color-darker); +} + +/* + memitem + */ + +div.memdoc, div.memproto, h2.memtitle { + box-shadow: none; + background-image: none; + border: none; +} + +div.memdoc { + padding: 0 var(--spacing-medium); + background: var(--page-background-color); +} + +h2.memtitle, div.memitem { + border: 1px solid var(--separator-color); +} + +div.memproto, h2.memtitle { + background: var(--code-background); + text-shadow: none; +} + +h2.memtitle { + font-weight: 500; + font-family: monospace, fixed; + border-bottom: none; + border-top-left-radius: var(--border-radius-medium); + border-top-right-radius: var(--border-radius-medium); + word-break: break-all; +} + +a:target + h2.memtitle, a:target + h2.memtitle + div.memitem { + border-color: var(--primary-light-color); +} + +a:target + h2.memtitle { + box-shadow: -3px -3px 3px 0 var(--primary-lightest-color), 3px -3px 3px 0 var(--primary-lightest-color); +} + +a:target + h2.memtitle + div.memitem { + box-shadow: 0 0 10px 0 var(--primary-lighter-color); +} + +div.memitem { + border-top-right-radius: var(--border-radius-medium); + border-bottom-right-radius: var(--border-radius-medium); + border-bottom-left-radius: var(--border-radius-medium); + overflow: hidden; + display: block !important; +} + +div.memdoc { + border-radius: 0; +} + +div.memproto { + border-radius: 0 var(--border-radius-small) 0 0; + overflow: auto; + border-bottom: 1px solid var(--separator-color); + padding: var(--spacing-medium); + margin-bottom: -1px; +} + +div.memtitle { + border-top-right-radius: var(--border-radius-medium); + border-top-left-radius: var(--border-radius-medium); +} + +div.memproto table.memname { + font-family: monospace, fixed; + color: var(--page-foreground-color); +} + +table.mlabels, table.mlabels > tbody { + display: block; +} + +td.mlabels-left { + width: auto; +} + +table.mlabels > tbody > tr:first-child { + display: flex; + justify-content: space-between; + flex-wrap: wrap; +} + +.memname, .memitem span.mlabels { + margin: 0 +} + +/* + reflist + */ + +dl.reflist { + box-shadow: var(--box-shadow); + border-radius: var(--border-radius-medium); + border: 1px solid var(--separator-color); + overflow: hidden; + padding: 0; +} + + +dl.reflist dt, dl.reflist dd { + box-shadow: none; + text-shadow: none; + background-image: none; + border: none; + padding: 12px; +} + + +dl.reflist dt { + font-weight: 500; + border-radius: 0; + background: var(--code-background); + border-bottom: 1px solid var(--separator-color); + color: var(--page-foreground-color) +} + + +dl.reflist dd { + background: none; +} + +/* + Table + */ + +table.markdownTable, table.fieldtable { + width: 100%; + border: 1px solid var(--separator-color); + margin: var(--spacing-medium) 0; +} + +table.fieldtable { + box-shadow: none; + border-radius: var(--border-radius-small); +} + +th.markdownTableHeadLeft, th.markdownTableHeadRight, th.markdownTableHeadCenter, th.markdownTableHeadNone { + background: var(--tablehead-background); + color: var(--tablehead-foreground); + font-weight: 600; + font-size: var(--page-font-size); +} + +table.markdownTable td, table.markdownTable th, table.fieldtable dt { + border: 1px solid var(--separator-color); + padding: var(--spacing-small) var(--spacing-medium); +} + +table.fieldtable th { + font-size: var(--page-font-size); + font-weight: 600; + background-image: none; + background-color: var(--tablehead-background); + color: var(--tablehead-foreground); + border-bottom: 1px solid var(--separator-color); +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + border-bottom: 1px solid var(--separator-color); + border-right: 1px solid var(--separator-color); +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid var(--separator-color); +} + +.memberdecls td.glow, .fieldtable tr.glow { + background-color: var(--primary-light-color); + box-shadow: 0 0 15px var(--primary-lighter-color); +} + +table.memberdecls { + display: block; + overflow-x: auto; + overflow-y: hidden; +} + + +/* + Horizontal Rule + */ + +hr { + margin-top: var(--spacing-large); + margin-bottom: var(--spacing-large); + border-top:1px solid var(--separator-color); +} + +.contents hr { + box-shadow: var(--content-maxwidth) 0 0 0 var(--separator-color), calc(0px - var(--content-maxwidth)) 0 0 0 var(--separator-color); +} + +.contents img { + max-width: 100%; +} + +/* + Directories + */ +div.directory { + border-top: 1px solid var(--separator-color); + border-bottom: 1px solid var(--separator-color); + width: auto; +} + +table.directory { + font-family: var(--font-family); + font-size: var(--page-font-size); + font-weight: normal; +} + +.directory td.entry { + padding: var(--spacing-small); + display: flex; + align-items: center; +} + +.directory tr.even { + background-color: var(--odd-color); +} + +.icona { + width: auto; + height: auto; + margin: 0 var(--spacing-small); +} + +.icon { + background: var(--primary-color); + width: 18px; + height: 18px; + line-height: 18px; +} + +.iconfopen, .icondoc, .iconfclosed { + background-position: center; + margin-bottom: 0; +} + +.icondoc { + filter: saturate(0.2); +} + +@media screen and (max-width: 767px) { + div.directory { + margin-left: calc(0px - var(--spacing-medium)); + margin-right: calc(0px - var(--spacing-medium)); + } +} + +@media (prefers-color-scheme: dark) { + html:not(.light-mode) .iconfopen, html:not(.light-mode) .iconfclosed { + filter: hue-rotate(180deg) invert(); + } +} + +html.dark-mode .iconfopen, html.dark-mode .iconfclosed { + filter: hue-rotate(180deg) invert(); +} + +/* + Class list + */ + +.classindex dl.odd { + background: var(--odd-color); + border-radius: var(--border-radius-small); +} + +@media screen and (max-width: 767px) { + .classindex { + margin: 0 calc(0px - var(--spacing-small)); + } +} + +/* + Footer and nav-path + */ + +#nav-path { + margin-bottom: -1px; + width: 100%; +} + +#nav-path ul { + background-image: none; + background: var(--page-background-color); + border: none; + border-top: 1px solid var(--separator-color); + border-bottom: 1px solid var(--separator-color); + font-size: var(--navigation-font-size); +} + +img.footer { + width: 60px; +} + +.navpath li.footer { + color: var(--page-secondary-foreground-color); +} + +address.footer { + margin-bottom: var(--spacing-large); +} + +#nav-path li.navelem { + background-image: none; + display: flex; + align-items: center; +} + +.navpath li.navelem a { + text-shadow: none; + display: inline-block; + color: var(--primary-color) !important; +} + +.navpath li.navelem b { + color: var(--primary-dark-color); + font-weight: 500; +} + +li.navelem { + padding: 0; + margin-left: -8px; +} + +li.navelem:first-child { + margin-left: var(--spacing-large); +} + +li.navelem:first-child:before { + display: none; +} + +#nav-path li.navelem:after { + content: ''; + border: 5px solid var(--page-background-color); + border-bottom-color: transparent; + border-right-color: transparent; + border-top-color: transparent; + transform: scaleY(4.2); + z-index: 10; + margin-left: 6px; +} + +#nav-path li.navelem:before { + content: ''; + border: 5px solid var(--separator-color); + border-bottom-color: transparent; + border-right-color: transparent; + border-top-color: transparent; + transform: scaleY(3.2); + margin-right: var(--spacing-small); +} + +.navpath li.navelem a:hover { + color: var(--primary-color); +} + +/* + Optional Dark mode toggle button +*/ + +doxygen-awesome-dark-mode-toggle { + display: inline-block; + margin: 0 0 0 var(--spacing-small); + padding: 0; + width: var(--searchbar-height); + height: var(--searchbar-height); + background: none; + border: none; + font-size: 23px; + border-radius: var(--border-radius-medium); + vertical-align: middle; + text-align: center; + line-height: var(--searchbar-height); +} + +doxygen-awesome-dark-mode-toggle:hover { + background: var(--separator-color); +} + +doxygen-awesome-dark-mode-toggle:after { + content: var(--darkmode-toggle-button-icon) +} diff --git a/doxygen/doxygen-awesome-css/footer.html b/doxygen/doxygen-awesome-css/footer.html new file mode 100644 index 0000000..b667e73 --- /dev/null +++ b/doxygen/doxygen-awesome-css/footer.html @@ -0,0 +1,26 @@ + + + + + + + + + + + diff --git a/doxygen/doxygen-awesome-css/header.html b/doxygen/doxygen-awesome-css/header.html new file mode 100644 index 0000000..cd6634f --- /dev/null +++ b/doxygen/doxygen-awesome-css/header.html @@ -0,0 +1,74 @@ + + + + + + + + +$projectname: $title +$title + + + + + + + + +$treeview +$search +$mathjax + +$extrastylesheet + + + + + +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
$projectname $projectnumber +
+
$projectbrief
+
+
$projectbrief
+
$searchbox
$searchbox
+
+ + diff --git a/doxygen/doxygen-awesome-css/img/screenshot.png b/doxygen/doxygen-awesome-css/img/screenshot.png new file mode 100644 index 0000000..c65033f Binary files /dev/null and b/doxygen/doxygen-awesome-css/img/screenshot.png differ diff --git a/doxygen/doxygen-awesome-css/img/theme-variations.drawio.svg b/doxygen/doxygen-awesome-css/img/theme-variations.drawio.svg new file mode 100644 index 0000000..c6b395f --- /dev/null +++ b/doxygen/doxygen-awesome-css/img/theme-variations.drawio.svg @@ -0,0 +1 @@ +
1. Base Theme
1. Base Theme
Content
Content
Titlebar (Navigation + Search)
Titlebar (Navigation + Search)
Sidebar (Navigation)
Sidebar (Navigation)
Footer (Breadcrumbs)
Footer (Breadcrumbs)
Search
Search
Title
Tit...
Content
Content
Sidebar
(Title + Navigation)
Sidebar...
Footer (Breadcrumbs)
Footer (Breadcrumbs)
Search
Search
Title
Tit...
2. Sidebar-Only Theme
2. Sidebar-Only Theme
Viewer does not support full SVG 1.1
diff --git a/include/arc/graphics/data.h b/include/arc/graphics/data.h new file mode 100644 index 0000000..b04c3c3 --- /dev/null +++ b/include/arc/graphics/data.h @@ -0,0 +1,5 @@ + +#ifndef ARC_GRAPHICS_DATA_H_ +#define ARC_GRAPHICS_DATA_H_ + +#endif //ARC_GRAPHICS_DATA_H_ \ No newline at end of file diff --git a/include/arc/std/config.h b/include/arc/std/config.h new file mode 100644 index 0000000..c05e9e4 --- /dev/null +++ b/include/arc/std/config.h @@ -0,0 +1,141 @@ +#ifndef ARC_STD_CONFIG_H_ +#define ARC_STD_CONFIG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "arc/std/hashtable.h" +#include "arc/std/string.h" +#include + +#ifndef ARC_HOME_PATH +#define ARC_HOME_PATH "./res/" +#endif //ARC_HOME_PATH + +#define ARC_KEY_BUCKET_SIZE 0x20 +#define ARC_GROUP_BUCKET_SIZE 0x20 +#define ARC_GROUP_DATA_BUCKET_SIZE 0x20 + +/** + * @brief a type that keeps permanice of data for when loading and unloading config files + */ +typedef struct ARC_Config ARC_Config; + +/** + * @brief a function to read a key from string to a ARC_ConfigTypeTemplate + * + * @param config ARC_Config to store data to + * @param data string of what is to be read in + * @param subdata location of stubstring in data for what is to be read in + * @param value value of read in variable + */ +typedef int32_t (* ARC_ConfigKeyRead)(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); + +/** + * @brief a function to delete a value from a key in ARC_Config + * + * @param config ARC_Config that can be used to check for references in data + * @param data string of what is going to be deleted (used to check if value is a reference) + * @param subdata location of substring in data for what is going to be deleted (used to check if value is a reference) + * @param value pointer of data to be deleted + */ +typedef int32_t (* ARC_ConfigKeyDelete)(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); + +/** + * @brief adds a usable key to ARC_Config + * + * @param config ARC_Config we are adding keys to + * @param type string of key type + * @param keyRead function for reading/creating key from string + * @param keyDelete function for deleting stored key + * + * @return 0 on sucess, ARC_ERRNO_ on fail + */ +int32_t ARC_ConfigKey_Add(ARC_Config *config, char *type, ARC_ConfigKeyRead keyRead, ARC_ConfigKeyDelete keyDelete); + +/** + * @brief external callback to add keys to config + */ +typedef int32_t (* ARC_ConfigKey_AddFunc)(ARC_Config *config); + +/** + * @brief creates ARC_Config type + * + * @param config ARC_Config we are initializing + * @param keysAdd callback to add ConfigKeys to config->keys, can be NULL + * + * @return 0 on sucess, ARC_ERRNO_ on fail + */ +int32_t ARC_Config_Create(ARC_Config **config, ARC_ConfigKey_AddFunc keysAdd); + +/** + * @brief destroys ARC_Config type + * + * @return 0 on sucess, ARC_ERRNO_ on fail + */ +int32_t ARC_Config_Destroy(ARC_Config *config); + +/** + * @brief commands that can be used in ARC_Config_FileIO + */ +#define ARC_CONFIG_FILE_IO_LOAD 0x00 +#define ARC_CONFIG_FILE_IO_UNLOAD 0x01 + +/** + * @brief handles file io for ARC_Config Type + * + * @param config ARC_Config where io operations will take place + * @param path file path for io + * + * @return 0 on sucess, ARC_ERRNO_ on fail + */ +int32_t ARC_Config_FileIO(ARC_Config *config, const char *path, uint8_t command); + +/** + * @brief sets current group in config + * + * @note ARC_Config_Get will use this set group + * + * @param config ARC_Config we are setting current group in + * @param groupname name of group that will be set + * + * @return 0 on sucess, ARC_ERRNO_ on fail + */ +int32_t ARC_Config_SetGroup(ARC_Config *config, char *groupname); + +/** + * @brief get a value from a given keyname + * + * @note name may be prefaced with :: to specify group + * + * @param config ARC_Config to get value from + * @param keyname name of key to get from config + * @param value data retrieved from config + * + * @return 0 on sucess, ARC_ERRNO_ on fail + */ +int32_t ARC_Config_Get(ARC_Config *config, char *keyname, void **value); + +/** + * @brief get a reference value from a given substring + * + * @note this function is meant to help with creation and deletion functions for types + * + * @param config ARC_Config to get value from + * @param data string that holds the substring that will be used + * @param subdata location of stubstring in data for what is to be read in + * + * @return a valid pointer on sucess, NULL on fail + */ +void *ARC_Config_GetReference(ARC_Config *config, char *data, ARC_StringSubstr *subdata); + +#ifdef __cplusplus +} +#endif + +#endif //ARC_STD_CONFIG_H_ + +#ifdef ARC_DEFAULT_CONFIG +#include "defaults/config.h" +#endif //ARC_DEFAULT_CONFIG \ No newline at end of file diff --git a/include/arc/std/defaults/config.h b/include/arc/std/defaults/config.h new file mode 100644 index 0000000..bfca04c --- /dev/null +++ b/include/arc/std/defaults/config.h @@ -0,0 +1,48 @@ +#ifdef ARC_DEFAULT_CONFIG + +#ifndef ARC_DEFAULTS_CONFIG_H_ +#define ARC_DEFAULTS_CONFIG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "arc/std/string.h" + +typedef struct ARC_Config ARC_Config; +int32_t ARC_Defaults_ConfigKey_Create(ARC_Config *config); + +int32_t ARC_ConfigKey_Read_Uint8_t (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); +int32_t ARC_ConfigKey_Read_Int8_t (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); +//int32_t ARC_ConfigKey_Read_Char (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); +int32_t ARC_ConfigKey_Read_Uint16_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); +int32_t ARC_ConfigKey_Read_Int16_t (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); +int32_t ARC_ConfigKey_Read_Uint32_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); +int32_t ARC_ConfigKey_Read_Int32_t (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); +int32_t ARC_ConfigKey_Read_Int (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); +int32_t ARC_ConfigKey_Read_Uint64_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); +int32_t ARC_ConfigKey_Read_Int64_t (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); +int32_t ARC_ConfigKey_Read_Long (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); +int32_t ARC_ConfigKey_Read_String (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); + +int32_t ARC_ConfigKey_Delete_Uint8_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); +int32_t ARC_ConfigKey_Delete_Int8_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); +int32_t ARC_ConfigKey_Delete_Char (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); +int32_t ARC_ConfigKey_Delete_Uint16_t(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); +int32_t ARC_ConfigKey_Delete_Int16_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); +int32_t ARC_ConfigKey_Delete_Uint32_t(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); +int32_t ARC_ConfigKey_Delete_Int32_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); +int32_t ARC_ConfigKey_Delete_Int (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); +int32_t ARC_ConfigKey_Delete_Uint64_t(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); +int32_t ARC_ConfigKey_Delete_Int64_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); +int32_t ARC_ConfigKey_Delete_Long (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); +int32_t ARC_ConfigKey_Delete_String (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); + +#ifdef __cplusplus +} +#endif + +#endif //ARC_DEFAULTS_CONFIG_H_ + +#endif //ARC_DEFAULT_CONFIG diff --git a/include/arc/std/errno.h b/include/arc/std/errno.h new file mode 100644 index 0000000..90e3612 --- /dev/null +++ b/include/arc/std/errno.h @@ -0,0 +1,36 @@ +#ifndef ARC_STD_ERRNO_H_ +#define ARC_STD_ERRNO_H_ + +#include + +#define ARC_ERRNO_NULL -0x01 +#define ARC_ERRNO_DATA -0x02 +#define ARC_ERRNO_COPY -0x03 +#define ARC_ERRNO_EXISTS -0x04 +#define ARC_ERRNO_OVERFLOW -0x05 + + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-variable" +static int32_t arc_errno = 0; +// #pragma GCC diagnostic pop + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#ifdef ARC_DEBUG +# include +# define ARC_DEBUG_LOG(ERR, STR, ...) printf("[ERROR %d] " STR "\n", ERR, __VA_ARGS__) +#else +# define ARC_DEBUG_LOG(ERR, STR, ...) +#endif + +#define ARC_ERR_CHECK(FUNC) FUNC; if(arc_errno){ ARC_DEBUG_LOG(arc_errno, "%s", #FUNC); return; } + +#endif //ARC_STD_ERRNO_H_ \ No newline at end of file diff --git a/include/arc/std/handler.h b/include/arc/std/handler.h new file mode 100644 index 0000000..ef67966 --- /dev/null +++ b/include/arc/std/handler.h @@ -0,0 +1,110 @@ +#ifndef ARC_STD_HANDLER_H_ +#define ARC_STD_HANDLER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + * @brief a handler type + */ +typedef struct ARC_Handler ARC_Handler; + +/** + * @brief a function that will take iterated data + * + * @param data iterated data from ARC_Handler_Iterate + */ +typedef void (* ARC_Handler_DataFn)(void *data); + +/** + * @brief a function that will be used during destruction of trash vector + * + * @param data data that is being destroyed from trash + */ +typedef void (* ARC_Handler_CleanDataFn)(void *data); + +/** + * @brief creates ARC_Handler type + * + * @param config ARC_Handler to initialize + */ +void ARC_Handler_Create(ARC_Handler **handler); + +/** + * @brief destroyes ARC_Handler type + */ +void ARC_Handler_Destroy(ARC_Handler *handler, ARC_Handler_CleanDataFn cleanfn); + +/** + * @brief adds data to handler + * + * @param handler ARC_Handler to add to + * @param data data that is being added + */ +void ARC_Handler_Add(ARC_Handler *handler, void *data); + +/** + * @brief remove from handler + * + * @note the data that is removed is stored in a trash vector + * the ARC_Handler_Clean function must be called clean the trash vector + * the trash vector is to make sure a state is not deleted while being run + * + * @param handler ARC_Handler to remove from + * @param data data that is being removed + */ +void ARC_Handler_Remove(ARC_Handler *handler, void *data); + +/** + * @brief remove from handler + * + * @note the data that is removed is stored in a trash vector + * the ARC_Handler_Clean function must be called clean the trash vector + * the trash vector is to make sure a state is not deleted while being run + * + * @param handler ARC_Handler to remove from + * @param index index of data that is being removed + */ +void ARC_Handler_RemoveIndex(ARC_Handler *handler, uint32_t *index); + +/** + * @brief calls provided function on each element in handler + * + * @param handler ARC_Handler to iterate through + * @param datafn function that will be called on each element of data + */ +void ARC_Handler_Iterate(ARC_Handler *handler, ARC_Handler_DataFn datafn); + +/** + * @brief clears all data from handler and puts it in trash vector + * + * @param handler ARC_Handler to clear data from + */ +void ARC_Handler_Clear(ARC_Handler *handler); + +/** + * @brief clears trash from handler + * + * @note cleanfn's main purpose is to help manage memory + * + * @param handler ARC_Handler to remove trash from + * @param cleanfn user provided function to run on trash before clearing from trash vector + * can be null + */ +void ARC_Handler_Clean(ARC_Handler *handler, ARC_Handler_CleanDataFn cleanfn); + +/** + * @brief gets size of vector + * + * @param handler ARC_handler to get size from + */ +uint32_t *ARC_Handler_Size(ARC_Handler *handler); + +#ifdef __cplusplus +} +#endif + +#endif //ARC_STD_HANDLER_H_ \ No newline at end of file diff --git a/include/arc/std/hashtable.h b/include/arc/std/hashtable.h new file mode 100644 index 0000000..41c7ab3 --- /dev/null +++ b/include/arc/std/hashtable.h @@ -0,0 +1,121 @@ +#ifndef ARC_STD_HASHTABLE_H_ +#define ARC_STD_HASHTABLE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** + * @brief the arc hashtable data type +*/ +typedef struct ARC_Hashtable ARC_Hashtable; + +/** + * @brief a node that contains a key-value reference along with a linked list like node +*/ +typedef struct ARC_HashtableNode ARC_HashtableNode; +struct ARC_HashtableNode { + void *key; + size_t keysize; + + void *data; + ARC_HashtableNode *node; +}; + +/** + * @brief a hashing function ptr + * + * @param key value to hash + * @param keysize should be sizeof(key) before key is a void ptr + * @param hashval value of hash, does not need to be within range of buckets + * + * @return 0 on sucess, ARC_ERRNO_ on fail +*/ +typedef int32_t (* ARC_Hashtable_Hash)(void *key, size_t *keysize, uint32_t *hashval); + +/** + * @brief key comparison function ptr + * + * @param key1 first key + * @param key2 second key + * + * @return 0 on sucess +*/ +typedef int32_t (* ARC_Hashtable_KeyCompare)(void *key1, size_t *key1size, void *key2, size_t *key2size); + +/** + * @brief callback to allow memory freeing of nodes + * + * @param node node to be destroyed + * @param userdata any data the user wants to access in the callback + * + * @return 0 on sucess, ARC_ERRNO_ on fail +*/ +typedef int32_t (* ARC_HashtableNode_DestroyExternal)(ARC_HashtableNode *node, void *userdata); + +/** + * @brief cteates ARC_Hashtable type + * + * @param htable where to store data + * @param bucketsize num of nodes to create in inital table + * @param hash hashing function to be used, if set to NULL, CRC32 will be used + * @param compare comparison functon for checking keys, if set to NULL, addresses will be compared +*/ +void ARC_Hashtable_Create(ARC_Hashtable **htable, uint32_t bucketsize, ARC_Hashtable_Hash hash, ARC_Hashtable_KeyCompare compare); + +/** + * @brief destroys ARC_Hashtable type + * + * @param htable htable that will be destroyed + * @param external function to allow external freeing of nodes, can be NULL + * @param userdata any data the user wants access to in the callback + * + * @return 0 on sucess, ARC_ERRNO_ on fail +*/ +int32_t ARC_Hashtable_Destroy(ARC_Hashtable *htable, ARC_HashtableNode_DestroyExternal external, void *userdata); + +/** + * @brief adds value to hastable + * + * @param htable ARC_Hashtable to add to + * @param key key for node that is being added + * @param keysize sizeof key before it is passed into a void * + * @param data data for node that is being added + * + * @return 0 on sucess, ARC_ERRNO_ on fail +*/ +int32_t ARC_Hashtable_Add(ARC_Hashtable *htable, void *key, size_t keysize, void *data); + +/** + * @brief gets value from hashtable by key + * + * @param htable table to get value from + * @param key key to get value from table + * @param keysize sizeof key before it is passed into a void * + * @param data data retrieved from table + * + * @return 0 on sucess, ARC_ERRNO_ on fail +*/ +int32_t ARC_Hashtable_Get(ARC_Hashtable *htable, void *key, size_t keysize, void **data); + +/** + * @brief removes value from hashtable + * + * @param htable ARC_Hashtable to remove from + * @param key key of data to remove from hash table + * @param keysize sizeof key before it is passed into a void * + * @param external function to allow external freeing of data, can be NULL + * @param userdata any data the user wants access to in the callback +* + * @return 0 on sucess, ARC_ERRNO_ on fail +*/ +int32_t ARC_Hashtable_Remove(ARC_Hashtable *htable, void *key, size_t keysize, ARC_HashtableNode_DestroyExternal external, void *userdata); + +#ifdef __cplusplus +} +#endif + +#endif //ARC_STD_HASHTABLE_H_ \ No newline at end of file diff --git a/include/arc/std/io.h b/include/arc/std/io.h new file mode 100644 index 0000000..fec28dc --- /dev/null +++ b/include/arc/std/io.h @@ -0,0 +1,26 @@ +#ifndef ARC_STD_IO_H_ +#define ARC_STD_IO_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + * @brief get string and size from file + * + * @param path a string to path of target file + * @param data pointer to where string will be created + * this will need to be freed once done using it + * @param size size of string + * + * @return int 0 on success, ARC_ERRNO_ on fail +*/ +int32_t ARC_IO_FileToStr(const char *path, char **data, uint64_t *size); + +#ifdef __cplusplus +} +#endif + +#endif //ARC_STD_IO_H_ \ No newline at end of file diff --git a/include/arc/std/string.h b/include/arc/std/string.h new file mode 100644 index 0000000..86db75c --- /dev/null +++ b/include/arc/std/string.h @@ -0,0 +1,104 @@ +#ifndef ARC_STD_STRING_H_ +#define ARC_STD_STRING_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + * @brief substring position within a string +*/ +typedef struct ARC_StringSubstr { + uint64_t index; + uint64_t length; +} ARC_StringSubstr; + +/** + * @brief substring position within a string, stored as 4 bytes +*/ +typedef struct ARC_StringSubstr32_t { + uint32_t index; + uint32_t length; +} ARC_StringSubstr32_t; + +/** + * @brief substring position within a string, stored as 1 byte +*/ +typedef struct ARC_StringSubstr8_t { + uint8_t index; + uint8_t length; +} ARC_StringSubstr8_t; + +/** + * @brief checks if string is alphabetic + * + * @param val string to check + * @param length length of string to check + * + * @return 1 if alphabetic, 0 if not alphabetic + */ +uint8_t ARC_String_Alpha(char *val, uint64_t length); + +/** + * @brief converst substring from string to uint64_t + * + * @param data string to get substring from + * @param substr substring to convert to long + * + * @return uint64_t converted number +*/ +uint64_t ARC_String_ToUint64_t(const char *data, ARC_StringSubstr *substr); + +/** + * @brief takes a given string, and assigns index and length for position of first matching substring + * + * @param data the string to find substring in + * @param substr the string to find + * @param index the index of substring within the string will be ~uint64_t if not found + * + * @return int ARC_ERRNO_ error code + */ +int32_t ARC_String_Find(char *data, char *substr, uint64_t *index); + +/** + * @brief takes a given string, and assigns index and length for position of last matching substring + * + * @param data the string to find substring in + * @param substr the string to find + * @param index the index of substring within the string will be ~uint64_t if not found + * + * @return int ARC_ERRNO_ error code + */ +int32_t ARC_String_FindBack(char *data, char *substr, uint64_t *index); + +/** + * @brief strips the ends based on a given substing + * + * @param data the string to find the substring in + * @param substr the substring to strip ends by, defaults to " " if NULL + * @param subdata the substring of data, will use given substring data, or strlen if length == 0 + * also will hold the return values + * + * @return int ARC_ERRNO_ error code +*/ +int32_t ARC_StringSubstr_StripEnds(char *data, char *substr, ARC_StringSubstr *subdata); + +/** + * @brief strips the ends based on a given substing + * + * @param data the string to find the substring in + * @param substr the substring to strip ends by, defaults to " " if NULL + * @param subdata the substring of data, will use given substring data, or strlen if length == 0 + * also will hold the return values + * + * @return int ARC_ERRNO_ error code +*/ +int32_t ARC_StringSubstr_StripWhitespaceEnds(char *data, ARC_StringSubstr *subdata); + +#ifdef __cplusplus +} +#endif + +#endif //ARC_STD_STRING_H_ \ No newline at end of file diff --git a/include/arc/std/vector.h b/include/arc/std/vector.h new file mode 100644 index 0000000..ca34029 --- /dev/null +++ b/include/arc/std/vector.h @@ -0,0 +1,82 @@ +#ifndef ARC_STD_VECTOR_H_ +#define ARC_STD_VECTOR_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + * @brief a dynamic array type + */ +typedef struct ARC_Vector ARC_Vector; + +/** + * @brief data comparison function ptr + * + * @param a first data struct + * @param b second data struct + * + * @return 0 when a == b +*/ +typedef int8_t (* ARC_Vector_CompareDataFn)(void *a, void *b); + +/** + * @brief creates ARC_Vector type + * + * @param config ARC_Vector to initialize + */ +void ARC_Vector_Create(ARC_Vector **vector, uint32_t dataSize); + +/** + * @brief destroyes ARC_Vector type + */ +void ARC_Vector_Destroy(ARC_Vector *vector); + +/** + * @brief adds value to vector + * + * @param vector ARC_Vector to add to + * @param data data that is being added + */ +void ARC_Vector_Add(ARC_Vector *vector, void *data); + +/** + * @brief remove from ARC_Vector + * + * @param vector ARC_Vector to remove from + * @param data data that is being removed + */ +void ARC_Vector_Remove(ARC_Vector *vector, void *data, ARC_Vector_CompareDataFn compare); + +/** + * @brief remove from ARC_Vector + * + * @param vector ARC_Vector to remove from + * @param index index of data that is being removed + */ +void ARC_Vector_RemoveIndex(ARC_Vector *vector, uint32_t *index); + +/** + * @brief gets size of vector + * + * @param vector ARC_Vector to get size from + */ +uint32_t *ARC_Vector_Size(ARC_Vector *vector); + +/** + * @brief gets data from ARC_Vector at position index + * + * @param vector ARC_Vector to get data from + * @param index position of data in ARC_Vector + * + * @return pointer to data on success, NULL on fail + */ +void *ARC_Vector_Get(ARC_Vector *vector, uint32_t *index); + +#ifdef __cplusplus +} +#endif + +#endif //ARC_STD_VECTOR_H_ \ No newline at end of file diff --git a/src/std/config.c b/src/std/config.c new file mode 100644 index 0000000..678c81e --- /dev/null +++ b/src/std/config.c @@ -0,0 +1,417 @@ +#include "arc/std/config.h" + +#include "arc/std/errno.h" +#include "arc/std/io.h" +#include +#include +#include +#include + +struct ARC_Config { + ARC_Hashtable *currgroup; + + ARC_Hashtable *groups; + ARC_Hashtable *keys; +}; + +typedef struct ARC_ConfigKey { + ARC_ConfigKeyRead Read; + ARC_ConfigKeyDelete Delete; +} ARC_ConfigKey; + +typedef struct ARC_ConfigTypeTemplate { + ARC_ConfigKey *key; + + void *data; +} ARC_ConfigTypeTemplate; + +typedef struct ARC_DeleteUserData { + ARC_Config *config; + + const char* data; + ARC_StringSubstr *subdata; +} ARC_DeleteUserData; + +int32_t ARC_Config_KeyComp(void *key1, size_t *key1size, void *key2, size_t *key2size){ + if(*key1size - *key2size){ return -1; } + return strncmp((const char *)key1, (const char *)key2, *key1size); +} + +int32_t ARC_ConfigKey_Add(ARC_Config *config, char *type, ARC_ConfigKeyRead keyRead, ARC_ConfigKeyDelete keyDelete){ + ARC_ConfigKey *temp = (ARC_ConfigKey *)malloc(sizeof(ARC_ConfigKey)); + temp->Read = keyRead; + temp->Delete = keyDelete; + return ARC_Hashtable_Add(config->keys, (void *)type, strlen(type), (void *)temp); +} + +int32_t ARC_ConfigKey_Destroy(ARC_HashtableNode *node, void *userdata){ + if(!node->data){ return ARC_ERRNO_NULL; } + free((ARC_ConfigKey *)node->data); + return 0; +} + +int32_t ARC_ConfigGroup_Create(ARC_Config *config, const char *name){ + ARC_Hashtable *data; + ARC_Hashtable_Create(&data, ARC_GROUP_DATA_BUCKET_SIZE, NULL, ARC_Config_KeyComp); + + char *group = (char *) malloc(sizeof(char) * strlen(name)); + strncpy(group, name, strlen(name)); + + return ARC_Hashtable_Add(config->groups, (void *)group, strlen(name), (void *)data); +} + +int32_t ARC_ConfigGroupNode_Destroy(ARC_HashtableNode *node, void *userdata){ + free((char *)node->key); + + ARC_ConfigTypeTemplate *temp = (ARC_ConfigTypeTemplate *)node->data; + if(temp->key){ + ARC_DeleteUserData *deldata = (ARC_DeleteUserData *)userdata; + temp->key->Delete(deldata->config, deldata->data, deldata->subdata, temp->data); + } + + free(temp); + return 0; +} + +int32_t ARC_ConfigGroup_Destroy(ARC_HashtableNode *group, void *userdata){ + free((char *)group->key); + return ARC_Hashtable_Destroy((ARC_Hashtable *)group->data, ARC_ConfigGroupNode_Destroy, userdata); +} + +int32_t ARC_Config_Create(ARC_Config **config, ARC_ConfigKey_AddFunc keysAdd){ + *config = (ARC_Config *) malloc(sizeof(ARC_Config)); + (*config)->currgroup = NULL; + + ARC_Hashtable *groups; + ARC_Hashtable_Create(&groups, ARC_GROUP_BUCKET_SIZE, NULL, ARC_Config_KeyComp); + (*config)->groups = groups; + ARC_ConfigGroup_Create(*config, ""); + + ARC_Hashtable *keys; + ARC_Hashtable_Create(&keys, ARC_KEY_BUCKET_SIZE, NULL, ARC_Config_KeyComp); + (*config)->keys = keys; + +#ifdef ARC_DEFAULT_CONFIG + ARC_Defaults_ConfigKey_Create(*config); +#endif + + if(keysAdd){ keysAdd(*config); } + + return 0; +} + +int32_t ARC_Config_Destroy(ARC_Config *config){ + ARC_DeleteUserData deldata = { .config = config, .data = NULL, .subdata = NULL }; + int32_t err = ARC_Hashtable_Destroy(config->groups, ARC_ConfigGroup_Destroy, (void *)&deldata); + if(err){ return err; } + + err = ARC_Hashtable_Destroy(config->keys, ARC_ConfigKey_Destroy, NULL); + if(err){ return err; } + + free(config); + return 0; +} + +int32_t ARC_Config_Get(ARC_Config *config, char *keyname, void **value){ + uint64_t len = 0; + ARC_ConfigTypeTemplate *temp; + + int32_t err = ARC_String_Find(keyname, (char *)"::", &len); + if(err){ return err; } + + if(len != ~((uint64_t)0)){ + char group[len + 1]; + strncpy(group, keyname, len); + group[len] = '\0'; + + ARC_Hashtable *currgroup = config->currgroup; + err = ARC_Config_SetGroup(config, group); + if(err){ return err; } + + char *namestr = (len + 2) + keyname; + char name[strlen(namestr)]; + strcpy(name, namestr); + + err = ARC_Hashtable_Get(config->currgroup, (void *)name, strlen(name), (void **)&temp); + if(err){ return err; } + + config->currgroup = currgroup; + *value = temp->data; + return 0; + } + + err = ARC_Hashtable_Get(config->currgroup, (void *)keyname, strlen(keyname), (void **)&temp); + if(err){ return err; } + + *value = temp->data; + return 0; +} + +int32_t ARC_Config_Remove(ARC_Config *config, const char *keyname, const char* data, ARC_StringSubstr *subdata){ + ARC_DeleteUserData deldata = { .config = config, .data = data, .subdata = subdata }; + printf("data: %s\n\n", data); + return ARC_Hashtable_Remove(config->currgroup, (void *)keyname, strlen(keyname), ARC_ConfigGroupNode_Destroy, (void *)&deldata); +} + +int32_t ARC_Config_SetGroup(ARC_Config *config, char *groupstr){ + int err = ARC_Hashtable_Get(config->groups, groupstr, strlen(groupstr), (void **)&(config->currgroup)); + if(err && err != ARC_ERRNO_NULL){ return err; } + + if(!(config->currgroup)){ + err = ARC_ConfigGroup_Create(config, groupstr); + if(err){ return err; } + + err = ARC_Hashtable_Get(config->groups, groupstr, strlen(groupstr), (void **)&(config->currgroup)); + if(err){ return err; } + } + + return 0; +} + +void ARC_ConfigPath_Create(char *data, ARC_StringSubstr *subpath, char **path){ + if(*(data + subpath->index) == '~'){ + *path = (char *) malloc(sizeof(char) * (subpath->length + strlen(ARC_HOME_PATH) + 1)); + strcpy(*path, ARC_HOME_PATH); + strncpy((*path) + strlen(ARC_HOME_PATH) - 1, data + subpath->index, subpath->length); + (*path)[subpath->length + strlen(ARC_HOME_PATH)] = '\0'; + return; + } + + *path = (char *) malloc(sizeof(char) * (subpath->length + 1)); + strncpy(*path, data + subpath->index, subpath->length); + (*path)[subpath->length] = '\0'; +} + +void ARC_ConfigPath_Destroy(char *url){ + free(url); +} + +int32_t ARC_Config_Recurse(ARC_Config *config, char *data, uint64_t *size, char *groupstr, ARC_StringSubstr *subkey, uint8_t *command); + +int32_t ARC_ConfigKey_Command(ARC_Config *config, char *data, uint64_t *size, ARC_StringSubstr *subkey){ + ARC_StringSubstr subcommand = { subkey->index + 1, 0 }; + int32_t err = ARC_String_Find(data + subcommand.index, " ", &(subcommand.length)); + if(err){ return err; } + if(subcommand.length == ~((uint64_t)0)){ return ARC_ERRNO_DATA; } + subkey->index += subcommand.length + 1; + + ARC_StringSubstr_StripEnds(data, NULL, &subcommand); + if(strncmp("load", data + subcommand.index, strlen("load")) && strncmp("unload", data + subcommand.index, strlen("unload"))){ return ARC_ERRNO_DATA; } + + ARC_StringSubstr subpath = { subkey->index, 0 }; + err = ARC_String_Find(data + subpath.index, (char *)"\"", &(subpath.index)); + if(err){ return err; } + if(subpath.length == ~((uint64_t)0)){ return ARC_ERRNO_DATA; } + subkey->index += subpath.length + 2; //we want to skip over the first \" that is why it is 2 not 1 + + subpath = (ARC_StringSubstr) { subkey->index, 0 }; + err = ARC_String_Find(data + subpath.index, (char *)"\"", &(subpath.length)); + if(err){ return err; } + if(subpath.length == ~((uint64_t)0)){ return ARC_ERRNO_DATA; } + subkey->index += subpath.length + 1; + + char *path; + ARC_ConfigPath_Create(data, &subpath, &path); + + if (!strncmp( "load", data + subcommand.index, strlen( "load"))){ err = ARC_Config_FileIO(config, path, ARC_CONFIG_FILE_IO_LOAD ); } + else if(!strncmp("unload", data + subcommand.index, strlen("unload"))){ err = ARC_Config_FileIO(config, path, ARC_CONFIG_FILE_IO_UNLOAD); } + else { return ARC_ERRNO_DATA; } + + ARC_ConfigPath_Destroy(path); + return err; +} + +int32_t ARC_ConfigKey_Comment(ARC_Config *config, char *data, uint64_t *size, ARC_StringSubstr *subkey){ + uint64_t commentlen = 0; + if(data[subkey->index + 1] == '*'){ + int32_t err = ARC_String_Find(data + subkey->index, (char *)"*/", &commentlen); + if(err){ return err; } + + subkey->index += commentlen + 1; + return 0; + } + + int32_t err = ARC_String_Find(data + subkey->index, (char *)"\n", &commentlen); + if(err){ return err; } + + subkey->index += commentlen + 1; + return 0; +} + +int32_t ARC_ConfigKey_Group(ARC_Config *config, char *data, uint64_t *size, ARC_StringSubstr *subkey, uint8_t *command){ + ARC_StringSubstr subgroup = { subkey->index, 0 }; + int32_t err = ARC_String_Find(data + subgroup.index, "{", &(subgroup.length)); + if(err){ return err; } + if(subgroup.length == ~((uint64_t)0)){ return ARC_ERRNO_DATA; } + subkey->index += subgroup.length + 1; + + ARC_StringSubstr_StripEnds(data, NULL, &subgroup); + + char groupstr[subgroup.length + 1]; + strncpy(groupstr, data + subgroup.index, subgroup.length); + groupstr[subgroup.length] = '\0'; + + return ARC_Config_Recurse(config, data, size, groupstr, subkey, command); +} + +int32_t ARC_ConfigKey_Load(ARC_Config *config, char *data, uint64_t *size, char *keyname, ARC_StringSubstr *subkey){ + ARC_ConfigKey *key; + int32_t err = ARC_Hashtable_Get(config->keys, (void *)keyname, strlen(keyname), (void **)&key); + if(err){ return err; } + + ARC_StringSubstr subname = { subkey->index, 0 }; + err = ARC_String_Find(data + subname.index, (char *)"=", &(subname.length)); + if(err){ return err; } + if(subname.length == ~((uint64_t)0)){ return ARC_ERRNO_DATA; } + subkey->index += subname.length + 1; + + ARC_StringSubstr_StripEnds(data, NULL, &subname); + + ARC_StringSubstr subvalue = { subkey->index, 0 }; + err = ARC_String_Find(data + subvalue.index, (char *)";", &(subvalue.length)); + if(err){ return err; } + if(subvalue.length == ~((uint64_t)0)){ return ARC_ERRNO_DATA; } + subkey->index += subvalue.length + 1; + + ARC_StringSubstr_StripEnds(data, NULL, &subvalue); + ARC_ConfigTypeTemplate *templateVal = NULL; + + char *name = malloc(sizeof(char) * subname.length + 1); + strncpy(name, data + subname.index, sizeof(char) * subname.length); + name[subname.length] = '\0'; + + templateVal = (ARC_ConfigTypeTemplate *) malloc(sizeof(ARC_ConfigTypeTemplate)); + templateVal->key = NULL; + templateVal->data = ARC_Config_GetReference(config, data, &subvalue); + + if(!templateVal->data){ + err = key->Read(config, data, &subvalue, &(templateVal->data)); + if(err){ return err; } + templateVal->key = key; + } + + return ARC_Hashtable_Add(config->currgroup, (void *)name, strlen(name), (void *)templateVal); +} + +int32_t ARC_ConfigKey_Unload(ARC_Config *config, char *data, uint64_t *size, char *keyname, ARC_StringSubstr *subkey){ + ARC_StringSubstr subname = { subkey->index, 0 }; + int32_t err = ARC_String_Find(data + subname.index, (char *)"=", &(subname.length)); + if(err){ return err; } + if(subname.length == ~((uint64_t)0)){ return ARC_ERRNO_DATA; } + subkey->index += subname.length + 1; + + ARC_StringSubstr_StripEnds(data, NULL, &subname); + char name[subname.length + 1]; + strncpy(name, data + subname.index, subname.length); + name[subname.length] = '\0'; + + subname = (ARC_StringSubstr){ subkey->index, 0 }; + err = ARC_String_Find(data + subname.index, (char *)";", &(subname.length)); + if(err){ return err; } + if(subname.length == ~((uint64_t)0)){ return ARC_ERRNO_DATA; } + subkey->index += subname.length + 1; + + return ARC_Config_Remove(config, name, data, &subname); +} + +int32_t ARC_Config_Recurse(ARC_Config *config, char *data, uint64_t *size, char *groupstr, ARC_StringSubstr *subkey, uint8_t *command){ + int32_t err = ARC_Config_SetGroup(config, groupstr); + if(err){ return err; } + ARC_Hashtable *group = config->currgroup; + + while(subkey->index < *size){ + if(data[subkey->index] == ' ' || data[subkey->index] == '\n' || data[subkey->index] == '\t' || data[subkey->index] == '\r'){ + subkey->index++; + continue; + } + + if(data[subkey->index] == '}'){ + config->currgroup = NULL; + subkey->index++; + return 0; + } + + if(data[subkey->index] == '#'){ + err = ARC_ConfigKey_Command(config, data, size, subkey); + if(err){ return err; } + continue; + } + + if(data[subkey->index] == '/'){ + err = ARC_ConfigKey_Comment(config, data, size, subkey); + if(err){ return err; } + continue; + } + + err = ARC_String_Find(data + subkey->index, (char *)" ", &(subkey->length)); + if(err){ return err; } + if(subkey->length == ~((uint64_t)0)){ return 0; } + + if(!(config->currgroup)){ + config->currgroup = group; + } + + char keyname[subkey->length + 1]; + strncpy(keyname, data + subkey->index, subkey->length); + keyname[subkey->length] = '\0'; + subkey->index += subkey->length + 1; + + if(subkey->length == strlen("group") && !strcmp(keyname, "group")){ + err = ARC_ConfigKey_Group(config, data, size, subkey, command); + if(err){ return err; } + continue; + } + + if(*command == ARC_CONFIG_FILE_IO_LOAD){ + err = ARC_ConfigKey_Load(config, data, size, keyname, subkey); + if(err){ return err; } + continue; + } + + if(*command == ARC_CONFIG_FILE_IO_UNLOAD){ + err = ARC_ConfigKey_Unload(config, data, size, keyname, subkey); + if(err){ return err;} + continue; + } + + return ARC_ERRNO_DATA; + } + + config->currgroup = group; + return 0; +} + +int32_t ARC_Config_FileIO(ARC_Config *config, const char *pathstr, uint8_t command){ + char *path, *data; + uint64_t size; + ARC_StringSubstr subpath = { 0, strlen(pathstr) }; + ARC_ConfigPath_Create((char *)pathstr, &subpath, &path); + + int32_t err = ARC_IO_FileToStr(path, &data, &size); + if(err){ + ARC_DEBUG_LOG(err, "ARC_IO_FileToStr(%s, &data, &size);\n", path); + ARC_ConfigPath_Destroy(path); + return err; + } + + ARC_ConfigPath_Destroy(path); + + ARC_StringSubstr subkey = { 0, 0 }; + err = ARC_Config_Recurse(config, data, &size, "", &subkey, &command); + if(err){ return err; } + + free(data); + return 0; +} + +void *ARC_Config_GetReference(ARC_Config *config, char *data, ARC_StringSubstr *subdata){ + if(ARC_String_Alpha(data + subdata->index, 1) && *(data + subdata->index) != ':'){ return NULL; } + + char refname[subdata->length + 1]; + strncpy(refname, data + subdata->index, subdata->length); + refname[subdata->length] = 0; + + void *value; + int32_t err = ARC_Config_Get(config, refname, &value); + return (err)? NULL : value; +} diff --git a/src/std/defaults/config.c b/src/std/defaults/config.c new file mode 100644 index 0000000..3842690 --- /dev/null +++ b/src/std/defaults/config.c @@ -0,0 +1,116 @@ +#ifdef ARC_DEFAULT_CONFIG + +#include "arc/std/defaults/config.h" + +#include "arc/std/config.h" +#include "arc/std/errno.h" +#include +#include +#include + +int32_t ARC_Defaults_ConfigKey_Create(ARC_Config *config){ + ARC_ConfigKey_Add(config, "uint8_t" , ARC_ConfigKey_Read_Uint8_t , ARC_ConfigKey_Delete_Uint8_t ); + ARC_ConfigKey_Add(config, "int8_t" , ARC_ConfigKey_Read_Int8_t , ARC_ConfigKey_Delete_Int8_t ); +// ARC_ConfigKey_Add(config, "char" , ARC_ConfigKey_Read_Char , ARC_ConfigKey_Delete_Char ); + ARC_ConfigKey_Add(config, "uint16_t", ARC_ConfigKey_Read_Uint16_t, ARC_ConfigKey_Delete_Uint16_t); + ARC_ConfigKey_Add(config, "int16_t" , ARC_ConfigKey_Read_Int16_t , ARC_ConfigKey_Delete_Int16_t ); + ARC_ConfigKey_Add(config, "uint32_t", ARC_ConfigKey_Read_Uint32_t, ARC_ConfigKey_Delete_Uint32_t); + ARC_ConfigKey_Add(config, "int32_t" , ARC_ConfigKey_Read_Int32_t , ARC_ConfigKey_Delete_Int32_t ); + ARC_ConfigKey_Add(config, "int" , ARC_ConfigKey_Read_Int , ARC_ConfigKey_Delete_Int ); + ARC_ConfigKey_Add(config, "uint64_t", ARC_ConfigKey_Read_Uint64_t, ARC_ConfigKey_Delete_Uint64_t); + ARC_ConfigKey_Add(config, "int64_t" , ARC_ConfigKey_Read_Int64_t , ARC_ConfigKey_Delete_Int64_t ); + ARC_ConfigKey_Add(config, "long" , ARC_ConfigKey_Read_Long , ARC_ConfigKey_Delete_Long ); + ARC_ConfigKey_Add(config, "string" , ARC_ConfigKey_Read_String , ARC_ConfigKey_Delete_String ); + return 0; +} + +int32_t ARC_ConfigKey_Read_Uint8_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ + *value = (uint8_t *) malloc(sizeof(uint8_t)); + *((uint8_t *)(*value)) = (uint8_t) ARC_String_ToUint64_t(data, subdata); + return 0; +} + +int32_t ARC_ConfigKey_Read_Int8_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ + *value = (int8_t *) malloc(sizeof(int8_t)); + *((int8_t *)(*value)) = (int8_t) ARC_String_ToUint64_t(data, subdata); + return 0; +} + +int32_t ARC_ConfigKey_Read_Char(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ + *value = (char *) malloc(sizeof(char)); + *((char *)(* value)) = (char) *(data + subdata->index); + return 0; +} + +int32_t ARC_ConfigKey_Read_Uint16_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ + *value = (uint16_t *) malloc(sizeof(uint16_t)); + *((uint16_t *)(*value)) = (uint16_t) ARC_String_ToUint64_t(data, subdata); + return 0; +} + +int32_t ARC_ConfigKey_Read_Int16_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ + *value = (int16_t *) malloc(sizeof(int16_t)); + *((int16_t *)(*value)) = (int16_t) ARC_String_ToUint64_t(data, subdata); + return 0; +} + +int32_t ARC_ConfigKey_Read_Uint32_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ + *value = (uint32_t *) malloc(sizeof(uint32_t)); + *((uint32_t *)(*value)) = (uint32_t) ARC_String_ToUint64_t(data, subdata); + return 0; +} + +int32_t ARC_ConfigKey_Read_Int32_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ + *value = (int32_t *) malloc(sizeof(int32_t)); + *((int32_t *)(*value)) = (int32_t) ARC_String_ToUint64_t(data, subdata); + return 0; +} + +int32_t ARC_ConfigKey_Read_Int(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ + *value = (int *) malloc(sizeof(int)); + *((int *)(*value)) = (int) ARC_String_ToUint64_t(data, subdata); + return 0; +} + +int32_t ARC_ConfigKey_Read_Uint64_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ + *value = (uint64_t *) malloc(sizeof(uint64_t)); + *((uint64_t *)(*value)) = ARC_String_ToUint64_t(data, subdata); + return 0; +} + +int32_t ARC_ConfigKey_Read_Int64_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ + *value = (int64_t *) malloc(sizeof(int64_t)); + *((int64_t *)(*value)) = (int64_t) ARC_String_ToUint64_t(data, subdata); + return 0; +} + +int32_t ARC_ConfigKey_Read_Long(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ + *value = (long *) malloc(sizeof(long)); + *((long *)(*value)) = (long) ARC_String_ToUint64_t(data, subdata); + return 0; +} + +int32_t ARC_ConfigKey_Read_String(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ + ARC_StringSubstr_StripWhitespaceEnds((char *)data, subdata); + if(data[subdata->index] != '"' || data[subdata->index + subdata->length] != '"'){ return ARC_ERRNO_DATA; } + ARC_StringSubstr_StripEnds((char *)data, (char *)"\"", subdata); + *value = (char *) malloc(sizeof(char) * (subdata->length + 1)); + strncpy((char *)(*value), data + subdata->index, subdata->length); + ((char *)(*value))[subdata->length] = '\0'; + return 0; +} + +int32_t ARC_ConfigKey_Delete_Uint8_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((uint8_t *)value){ free((uint8_t *)value); } return 0; } +int32_t ARC_ConfigKey_Delete_Int8_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((int8_t *)value){ free((int8_t *)value); } return 0; } +int32_t ARC_ConfigKey_Delete_Char (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((char *)value){ free((char *)value); } return 0; } +int32_t ARC_ConfigKey_Delete_Uint16_t(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((uint16_t *)value){ free((uint16_t *)value); } return 0; } +int32_t ARC_ConfigKey_Delete_Int16_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((int16_t *)value){ free((int16_t *)value); } return 0; } +int32_t ARC_ConfigKey_Delete_Uint32_t(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((uint32_t *)value){ free((uint32_t *)value); } return 0; } +int32_t ARC_ConfigKey_Delete_Int32_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((int32_t *)value){ free((int32_t *)value); } return 0; } +int32_t ARC_ConfigKey_Delete_Int (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((int *)value){ free((int *)value); } return 0; } +int32_t ARC_ConfigKey_Delete_Uint64_t(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((uint64_t *)value){ free((uint64_t *)value); } return 0; } +int32_t ARC_ConfigKey_Delete_Int64_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((int64_t *)value){ free((int64_t *)value); } return 0; } +int32_t ARC_ConfigKey_Delete_Long (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((long *)value){ free((long *)value); } return 0; } +int32_t ARC_ConfigKey_Delete_String (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((char *)value){ free((char *)value); } return 0; } + +#endif //ARC_DEFAULT_CONFIG diff --git a/src/std/handler.c b/src/std/handler.c new file mode 100644 index 0000000..0f4ae1c --- /dev/null +++ b/src/std/handler.c @@ -0,0 +1,68 @@ +#include "arc/std/handler.h" + +#include "arc/std/errno.h" +#include "arc/std/vector.h" +#include + +struct ARC_Handler { + ARC_Vector *data; + ARC_Vector *trash; +}; + +void ARC_Handler_Create(ARC_Handler **handler){ + *handler = (ARC_Handler *) malloc(sizeof(ARC_Handler)); + ARC_Vector_Create(&((*handler)->data), sizeof(void *)); + ARC_Vector_Create(&((*handler)->trash), sizeof(void *)); +} + +void ARC_Handler_Destroy(ARC_Handler *handler, ARC_Handler_CleanDataFn cleanfn){ + ARC_Handler_Clear(handler); + ARC_Handler_Clean(handler, cleanfn); + + ARC_Vector_Destroy(handler->data); + ARC_Vector_Destroy(handler->trash); + + free(handler); +} + +void ARC_Handler_Add(ARC_Handler *handler, void *data){ + ARC_Vector_Add(handler->data, data); +} + +int8_t ARC_Handler_RemoveCompareFn(void *a, void *b){ return a == b; } + +void ARC_Handler_Remove(ARC_Handler *handler, void *data){ + ARC_Vector_Remove(handler->data, data, ARC_Handler_RemoveCompareFn); + ARC_Vector_Add(handler->trash, data); +} + +void ARC_Handler_RemoveIndex(ARC_Handler *handler, uint32_t *index){ + void *data = ARC_Vector_Get(handler->data, index); + ARC_Vector_RemoveIndex(handler->data, index); + ARC_Vector_Add(handler->trash, data); +} + +void ARC_Handler_Iterate(ARC_Handler *handler, ARC_Handler_DataFn datafn){ + for(uint32_t i = 0; i < *ARC_Vector_Size(handler->data); i++){ + datafn(ARC_Vector_Get(handler->data, &i)); + } +} + +void ARC_Handler_Clear(ARC_Handler *handler){ + while(*ARC_Vector_Size(handler->data)){ + ARC_Handler_Remove(handler, 0); + } +} + +void ARC_Handler_Clean(ARC_Handler *handler, ARC_Handler_CleanDataFn cleanfn){ + uint32_t i = 0; + while(*ARC_Vector_Size(handler->trash)){ + void *data = ARC_Vector_Get(handler->trash, &i); + cleanfn(data); + ARC_Vector_RemoveIndex(handler->trash, &i); + } +} + +uint32_t *ARC_Handler_Size(ARC_Handler *handler){ + return ARC_Vector_Size(handler->data); +} diff --git a/src/std/hashtable.c b/src/std/hashtable.c new file mode 100644 index 0000000..d7a511d --- /dev/null +++ b/src/std/hashtable.c @@ -0,0 +1,167 @@ +#include "arc/std/hashtable.h" + +#include "arc/std/errno.h" +#include +#include + +struct ARC_Hashtable { + uint32_t size; + ARC_HashtableNode **nodes; + ARC_Hashtable_Hash hash; + ARC_Hashtable_KeyCompare compare; +}; + +int32_t CRC32(void *key, size_t *keysize, uint32_t *hashval){ + *hashval = 0xffffffff; + + for(size_t i = 0; i < *keysize; i++){ + uint8_t value = *(((uint8_t *)key) + i); + for(uint8_t j = 0; j < 8; j++){ + uint8_t flag = (uint8_t)((value ^ *hashval) & 1); + *hashval >>= 1; + if(flag){ *hashval ^= 0xEDB888320; } + value >>= 1; + } + } + + *hashval = ~*hashval; + return 0; +} + +int32_t ARC_Default_Key_Compare(void *key1, size_t *key1size, void *key2, size_t *key2size){ + return key1 - key2; +} + +void ARC_HashtableNode_Create(ARC_HashtableNode **node, void *key, size_t *keysize, void *data){ + *node = (ARC_HashtableNode *) malloc(sizeof(ARC_HashtableNode)); + (*node)->key = key; + (*node)->keysize = *keysize; + (*node)->data = data; + (*node)->node = NULL; +} + +int32_t ARC_HashtableNode_Destroy(ARC_HashtableNode *node, ARC_HashtableNode_DestroyExternal external, void *userdata){ + if(node == NULL){ return 0; } + ARC_HashtableNode_Destroy(node->node, external, userdata); + + if(external){ + int32_t err = external(node, userdata); + if(err){ return err; } + } + + free(node); + return 0; +} + +void ARC_Hashtable_Create(ARC_Hashtable **htable, uint32_t bucketsize, ARC_Hashtable_Hash hash, ARC_Hashtable_KeyCompare compare){ + *htable = (ARC_Hashtable *) malloc(sizeof(ARC_Hashtable)); + (*htable)->size = bucketsize; + (*htable)->nodes = (ARC_HashtableNode **) calloc(bucketsize, sizeof(ARC_HashtableNode *)); + (*htable)->hash = (hash)? hash : CRC32; + (*htable)->compare = (compare)? compare : ARC_Default_Key_Compare; +} + +int32_t ARC_Hashtable_Destroy(ARC_Hashtable *htable, ARC_HashtableNode_DestroyExternal external, void *userdata){ + for(uint32_t i = 0; i < htable->size; i++){ + if(htable->nodes[i]){ + int32_t err = ARC_HashtableNode_Destroy(htable->nodes[i], external, userdata); + if(err){ return err; } + } + } + + free(htable->nodes); + free(htable); + + return 0; +} + +int32_t ARC_Hashtable_Add(ARC_Hashtable *htable, void *key, size_t keysize, void *data){ + uint32_t size = 0; + int32_t err = htable->hash(key, &keysize, &size); + if(err){ return err; } + + ARC_HashtableNode *bucket = htable->nodes[size % htable->size]; + if(!bucket){ + ARC_HashtableNode_Create(&bucket, key, &keysize, data); + htable->nodes[size % htable->size] = bucket; + return 0; + } + + if(!htable->compare(bucket->key, &bucket->keysize, key, &keysize)){ return ARC_ERRNO_EXISTS; } + + while(bucket->node){ + if(!htable->compare(bucket->node->key, &bucket->node->keysize, key, &keysize)){ return ARC_ERRNO_EXISTS; } + bucket = bucket->node; + } + + ARC_HashtableNode_Create(&(bucket->node), key, &keysize, data); + return 0; +} + +int32_t ARC_Hashtable_Get(ARC_Hashtable *htable, void *key, size_t keysize, void **data){ + uint32_t size = 0; + int32_t err = htable->hash(key, &keysize, &size); + if(err){ return err; } + + ARC_HashtableNode *bucket = htable->nodes[size % htable->size]; + if(!bucket){ + *data = NULL; + return ARC_ERRNO_NULL; + } + + if(!htable->compare(bucket->key, &bucket->keysize, key, &keysize)){ + *data = bucket->data; + return 0; + } + + while(bucket->node){ + if(!htable->compare(bucket->node->key, &bucket->node->keysize, key, &keysize)){ + *data = bucket->node->data; + return 0; + } + bucket = bucket->node; + } + + return ARC_ERRNO_NULL; +} + +int32_t ARC_Hashtable_Remove(ARC_Hashtable *htable, void *key, size_t keysize, ARC_HashtableNode_DestroyExternal external, void *userdata){ + uint32_t size = 0; + int32_t err = htable->hash(key, &keysize, &size); + if(err){ return err; } + + ARC_HashtableNode *bucket = htable->nodes[size % htable->size]; + if(!bucket){ return ARC_ERRNO_NULL; } + + if(!htable->compare(bucket->key, &bucket->keysize, key, &keysize)){ + ARC_HashtableNode *temp = bucket; + htable->nodes[size % htable->size] = bucket->node; + + if(external){ + err = external(temp, userdata); + if(err){ return err; } + } + + free(temp); + return 0; + } + + while(bucket->node){ + if(!htable->compare(bucket->node->key, &bucket->node->keysize, key, &keysize)){ + ARC_HashtableNode *temp = bucket->node; + bucket->node = bucket->node->node; + + if(external){ + err = external(temp, userdata); + if(err){ return err; } + } + + free(temp); + return 0; + } + + bucket = bucket->node; + } + + return ARC_ERRNO_NULL; +} diff --git a/src/std/io.c b/src/std/io.c new file mode 100644 index 0000000..16b57a2 --- /dev/null +++ b/src/std/io.c @@ -0,0 +1,28 @@ +#include "arc/std/io.h" + +#include "arc/std/errno.h" +#include +#include + +int32_t ARC_IO_FileToStr(const char *path, char **data, uint64_t *size){ + FILE *file = fopen(path, "rb"); + if(!file){ return ARC_ERRNO_NULL; } + + fseek(file, 0L, SEEK_END); + *size = ftell(file); + rewind(file); + + *data = (char *) calloc(1, *size + 1); + if(!*data){ + fclose(file); + return ARC_ERRNO_NULL; + } + + if(1 != fread(*data, *size, 1, file)){ + fclose(file); + return ARC_ERRNO_COPY; + } + + fclose(file); + return 0; +} diff --git a/src/std/string.c b/src/std/string.c new file mode 100644 index 0000000..1bab3e6 --- /dev/null +++ b/src/std/string.c @@ -0,0 +1,115 @@ +#include "arc/std/string.h" + +#include "arc/std/errno.h" +#include +#include + +uint8_t ARC_String_Alpha(char *val, uint64_t length){ + for(; length; length--){ + if(val[length - 1] >= 'a' && val[length - 1] <= 'z'){ continue; } + if(val[length - 1] >= 'A' && val[length - 1] <= 'Z'){ continue; } + return 1; + } + return 0; +} + +uint64_t ARC_String_ToUint64_t(const char *data, ARC_StringSubstr *substr){ + char temp[substr->length + 1]; + strncpy(temp, data + substr->index, substr->length); + temp[substr->length] = '\0'; + + return (uint64_t) strtoul(temp, NULL, 10); +} + +int32_t ARC_String_Find(char *data, char *substr, uint64_t *index){ + if(!data || !substr){ return ARC_ERRNO_NULL; } + + uint64_t max = strlen(data); + uint64_t sub = strlen(substr); + if(!max || !sub || sub > max){ return ARC_ERRNO_DATA; } + + max -= sub - 1; + for(uint64_t i = 0; max; i++, max--){ + if(!strncmp(data + i, substr, sub)){ + *index = i; + return 0; + } + } + + *index = ~((uint64_t)0); + return 0; +} + +int32_t ARC_String_FindBack(char *data, char *substr, uint64_t *index){ + if(!data || !substr){ return ARC_ERRNO_NULL; } + + uint64_t max = strlen(data); + uint64_t sub = strlen(substr); + if(!max || !sub || sub > max){ return ARC_ERRNO_DATA; } + + max -= sub - 1; + for(; max; max--){ + if(!strncmp(data + (max - 1), substr, sub)){ + *index = max; + return 0; + } + } + + *index = ~((uint64_t)0); + return 0; +} + +int32_t ARC_StringSubstr_StripEnds(char *data, char *substr, ARC_StringSubstr *subdata){ + if(!subdata){ return ARC_ERRNO_NULL; } + if(!substr){ substr = (char *)" "; } + + subdata->length = (subdata->length)? subdata->length : strlen(data); + uint64_t max = subdata->length; + uint64_t sub = strlen(substr); + if(!max || !sub || sub > max){ return ARC_ERRNO_DATA; } + + max -= sub - 1; + for(; max; max--){ + if(strncmp(data + subdata->index + (max - 1), substr, sub)){ + subdata->length = max; + break; + } + } + + max = subdata->length - (sub - 1); + for(uint64_t i = 0; max; i++, max--){ + if(strncmp(data + subdata->index + i, substr, sub)){ + subdata->index += i; + subdata->length -= i; + return 0; + } + } + + return 0; +} + +int32_t ARC_StringSubstr_StripWhitespaceEnds(char *data, ARC_StringSubstr *subdata){ + if(!subdata){ return ARC_ERRNO_NULL; } + + subdata->length = (subdata->length)? subdata->length : strlen(data); + uint64_t max = subdata->length; + if(!max){ return ARC_ERRNO_DATA; } + + for(; max; max--){ + if(data[subdata->index + (max - 1)] != ' ' && data[subdata->index + (max - 1)] != '\n' && data[subdata->index + (max - 1)] != '\t' && data[subdata->index + (max - 1)] != '\r'){ + subdata->length = max; + break; + } + } + + max = subdata->length; + for(uint64_t i = 0; max; i++, max--){ + if(data[subdata->index + i] != ' ' && data[subdata->index + i] != '\n' && data[subdata->index + i] != '\t' && data[subdata->index + i] != '\r'){ + subdata->index += i; + subdata->length -= i; + return 0; + } + } + + return 0; +} diff --git a/src/std/vector.c b/src/std/vector.c new file mode 100644 index 0000000..b02d03f --- /dev/null +++ b/src/std/vector.c @@ -0,0 +1,109 @@ +#include "arc/std/vector.h" + +#include "arc/std/errno.h" +#include +#include +#include + +struct ARC_Vector { + uint32_t *currentSize, *capacity; + uint32_t *dataSize; + void *data; +}; + +void ARC_Vector_Create(ARC_Vector **vector, uint32_t dataSize){ + *vector = (ARC_Vector *) malloc(sizeof(ARC_Vector)); + (*vector)->currentSize = (uint32_t *) malloc(sizeof(uint32_t)); + (*vector)->capacity = (uint32_t *) malloc(sizeof(uint32_t)); + (*vector)->dataSize = (uint32_t *) malloc(sizeof(uint32_t)); + (*vector)->data = (void *) malloc(dataSize); + + *((*vector)->currentSize) = 0; + *((*vector)->capacity) = 1; + *((*vector)->dataSize) = dataSize; +} + +void ARC_Vector_Destroy(ARC_Vector *vector){ + free(vector->currentSize); + free(vector->capacity); + free(vector->data); + free(vector->dataSize); + free(vector); +} + +void ARC_Vector_Add(ARC_Vector *vector, void *data){ + if(*(vector->currentSize) == ~((uint32_t)0)){ + arc_errno = ARC_ERRNO_OVERFLOW; + return; + } + + if(*(vector->currentSize) == *(vector->capacity)){ + *(vector->capacity) <<= 1; + + vector->data = (void *) realloc(vector->data, *(vector->dataSize) * *(vector->capacity)); + } + + memcpy(vector->data + (*(vector->currentSize) * *(vector->dataSize)), data, *(vector->dataSize)); + ++*(vector->currentSize); +} + +void ARC_Vector_Remove(ARC_Vector *vector, void *data, ARC_Vector_CompareDataFn compare){ + if(!*(vector->currentSize)){ + arc_errno = ARC_ERRNO_DATA; + return; + } + + --*(vector->currentSize); + + if(*(vector->currentSize) != *(vector->capacity) >> 1){ + for(uint32_t i = 0; i <= *(vector->currentSize); i++){ + if(!compare(data, vector->data + (i * *(vector->dataSize)))){ + memcpy(vector->data + (i * *(vector->dataSize)), vector->data + ((i + 1) * *(vector->dataSize)), *(vector->currentSize - i) * *(vector->dataSize)); + return; + } + } + + arc_errno = ARC_ERRNO_DATA; + return; + } + + *(vector->capacity) >>= 1; + void *temp = (void *) malloc(*(vector->dataSize) * *(vector->capacity)); + + for(uint32_t i = 0; i <= *(vector->currentSize); i++){ + if(compare(data, vector->data + (i * *(vector->dataSize)))){ + memcpy(temp, vector->data, i * *(vector->dataSize)); + memcpy(temp + (i * *(vector->dataSize)), vector->data + ((i + 1) * *(vector->dataSize)), *(vector->currentSize - i) * *(vector->dataSize)); + free(vector->data); + vector->data = temp; + return; + } + } + + arc_errno = ARC_ERRNO_DATA; +} + +void ARC_Vector_RemoveIndex(ARC_Vector *vector, uint32_t *index){ + if(!*(vector->currentSize) || *index >= *(vector->currentSize)){ + arc_errno = ARC_ERRNO_DATA; + return; + } + + --*(vector->currentSize); + if(*(vector->currentSize) != *(vector->capacity) >> 1){ + memcpy(vector->data + (*index * *(vector->dataSize)), vector->data + ((*index + 1) * *(vector->dataSize)), *(vector->currentSize - *index) * *(vector->dataSize)); + return; + } + + *(vector->capacity) >>= 1; + void **temp = (void **) malloc(sizeof(void *) * (*(vector->capacity))); + memcpy(temp, vector->data, *index * *(vector->dataSize)); + memcpy(temp + (*index * *(vector->dataSize)), vector->data + ((*index + 1) * *(vector->dataSize)), *(vector->currentSize - *index) * *(vector->dataSize)); + + free(vector->data); + vector->data = temp; +} + +uint32_t *ARC_Vector_Size(ARC_Vector *vector){ return vector->currentSize; } + +void *ARC_Vector_Get(ARC_Vector *vector, uint32_t *index){ return (void *)(uint8_t (*)[*(vector->dataSize)]) vector->data + (*index * *(vector->dataSize)); }