This commit is contained in:
herbglitch 2022-10-27 15:16:54 -06:00
commit db1adbb838
35 changed files with 4408 additions and 0 deletions

533
.gitignore vendored Normal file
View file

@ -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

84
CMakeLists.txt Normal file
View file

@ -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}
)

29
Doxyfile Normal file
View file

@ -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

View file

@ -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@")

View file

@ -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 }}

View file

@ -0,0 +1,3 @@
docs/html
.DS_Store
.idea

View file

@ -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.

View file

@ -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;
}
}

View file

@ -0,0 +1,30 @@
<!-- HTML footer for doxygen 1.9.1-->
<!-- start footer part -->
<!--BEGIN GENERATE_TREEVIEW-->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
$navpath
<li class="footer">$generatedby <a href="https://www.doxygen.org/index.html"><img class="footer" src="$relpath^doxygen.svg" width="104" height="31" alt="doxygen"/></a> $doxygenversion </li>
</ul>
</div>
<!--END GENERATE_TREEVIEW-->
<!--BEGIN !GENERATE_TREEVIEW-->
<hr class="footer"/><address class="footer"><small>
$generatedby&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="$relpath^doxygen.svg" width="104" height="31" alt="doxygen"/></a> $doxygenversion
</small></address>
<!--END !GENERATE_TREEVIEW-->
<script type="text/javascript">
$(function() {
toggleButton = document.createElement('doxygen-awesome-dark-mode-toggle')
toggleButton.title = "Toggle Light/Dark Mode"
$(document).ready(function(){
document.getElementById("MSearchBox").parentNode.appendChild(toggleButton)
})
$(window).resize(function(){
document.getElementById("MSearchBox").parentNode.appendChild(toggleButton)
})
})
</script>
</body>
</html>

View file

@ -0,0 +1,78 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen $doxygenversion"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<!-- BEGIN opengraph metadata -->
<meta property="og:title" content="Doxygen Awesome" />
<meta property="og:image" content="https://repository-images.githubusercontent.com/348492097/4f16df80-88fb-11eb-9d31-4015ff22c452" />
<meta property="og:description" content="Custom CSS theme for doxygen html-documentation with lots of customization parameters." />
<meta property="og:url" content="https://jothepro.github.io/doxygen-awesome-css/" />
<!-- END opengraph metadata -->
<!-- BEGIN twitter metadata -->
<meta name="twitter:image:src" content="https://repository-images.githubusercontent.com/348492097/4f16df80-88fb-11eb-9d31-4015ff22c452" />
<meta name="twitter:title" content="Doxygen Awesome" />
<meta name="twitter:description" content="Custom CSS theme for doxygen html-documentation with lots of customization parameters." />
<!-- END twitter metadata -->
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
<link rel="icon" type="image/svg+xml" href="logo.drawio.svg"/>
<script type="text/javascript" src="$relpath^jquery.js"></script>
<script type="text/javascript" src="$relpath^dynsections.js"></script>
<script type="text/javascript" src="$relpath^doxygen-awesome-darkmode-toggle.js"></script>
$treeview
$search
$mathjax
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
$extrastylesheet
</head>
<body>
<!-- https://tholman.com/github-corners/ -->
<a href="https://github.com/jothepro/doxygen-awesome-css" class="github-corner" title="View source on GitHub">
<svg viewBox="0 0 250 250" style="position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true">
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<!--BEGIN TITLEAREA-->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<!--BEGIN PROJECT_LOGO-->
<td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"/></td>
<!--END PROJECT_LOGO-->
<!--BEGIN PROJECT_NAME-->
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">$projectname
<!--BEGIN PROJECT_NUMBER-->&#160;<span id="projectnumber">$projectnumber</span><!--END PROJECT_NUMBER-->
</div>
<!--BEGIN PROJECT_BRIEF--><div id="projectbrief">$projectbrief</div><!--END PROJECT_BRIEF-->
</td>
<!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME-->
<!--BEGIN PROJECT_BRIEF-->
<td style="padding-left: 0.5em;">
<div id="projectbrief">$projectbrief</div>
</td>
<!--END PROJECT_BRIEF-->
<!--END !PROJECT_NAME-->
<!--BEGIN DISABLE_INDEX-->
<!--BEGIN SEARCHENGINE-->
<td>$searchbox</td>
<!--END SEARCHENGINE-->
<!--END DISABLE_INDEX-->
</tr>
</tbody>
</table>
</div>
<!--END TITLEAREA-->
<!-- end header part -->

View file

@ -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.
*/

View file

@ -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);

View file

@ -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));
}
}

View file

@ -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;
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,26 @@
<!-- HTML footer for doxygen 1.9.2-->
<!-- start footer part -->
<!--BEGIN GENERATE_TREEVIEW-->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>$navpath</ul>
</div>
<!--END GENERATE_TREEVIEW-->
<!--BEGIN !GENERATE_TREEVIEW-->
<hr class="footer"/><address class="footer"><small></small></address>
<!--END !GENERATE_TREEVIEW-->
<script type="text/javascript">
// script for doxygen 1.9.1
$(function() {
toggleButton = document.createElement('doxygen-awesome-dark-mode-toggle')
toggleButton.title = "Toggle Light/Dark Mode"
$(document).ready(function(){
document.getElementById("MSearchBox").parentNode.appendChild(toggleButton)
})
$(window).resize(function(){
document.getElementById("MSearchBox").parentNode.appendChild(toggleButton)
})
})
</script>
</body>
</html>

View file

@ -0,0 +1,74 @@
<!-- HTML header for doxygen 1.9.2-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen $doxygenversion"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
<!--BEGIN DISABLE_INDEX-->
<!--BEGIN FULL_SIDEBAR-->
<script type="text/javascript">var page_layout=1;</script>
<!--END FULL_SIDEBAR-->
<!--END DISABLE_INDEX-->
<script type="text/javascript" src="$relpath^jquery.js"></script>
<script type="text/javascript" src="$relpath^dynsections.js"></script>
$treeview
$search
$mathjax
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
$extrastylesheet
<script type="text/javascript" src="$relpath^doxygen-awesome-darkmode-toggle.js"></script>
</head>
<body>
<!--BEGIN DISABLE_INDEX-->
<!--BEGIN FULL_SIDEBAR-->
<div id="side-nav" class="ui-resizable side-nav-resizable"><!-- do not remove this div, it is closed by doxygen! -->
<!--END FULL_SIDEBAR-->
<!--END DISABLE_INDEX-->
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<!--BEGIN TITLEAREA-->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<!--BEGIN PROJECT_LOGO-->
<td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"/></td>
<!--END PROJECT_LOGO-->
<!--BEGIN PROJECT_NAME-->
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">$projectname<!--BEGIN PROJECT_NUMBER--><span id="projectnumber">&#160;$projectnumber</span><!--END PROJECT_NUMBER-->
</div>
<!--BEGIN PROJECT_BRIEF--><div id="projectbrief">$projectbrief</div><!--END PROJECT_BRIEF-->
</td>
<!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME-->
<!--BEGIN PROJECT_BRIEF-->
<td style="padding-left: 0.5em;">
<div id="projectbrief">$projectbrief</div>
</td>
<!--END PROJECT_BRIEF-->
<!--END !PROJECT_NAME-->
<!--BEGIN DISABLE_INDEX-->
<!--BEGIN SEARCHENGINE-->
<!--BEGIN !FULL_SIDEBAR-->
<td>$searchbox</td>
<!--END !FULL_SIDEBAR-->
<!--END SEARCHENGINE-->
<!--END DISABLE_INDEX-->
</tr>
<!--BEGIN SEARCHENGINE-->
<!--BEGIN FULL_SIDEBAR-->
<tr><td colspan="2">$searchbox</td></tr>
<!--END FULL_SIDEBAR-->
<!--END SEARCHENGINE-->
</tbody>
</table>
</div>
<!--END TITLEAREA-->
<!-- end header part -->

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -0,0 +1,5 @@
#ifndef ARC_GRAPHICS_DATA_H_
#define ARC_GRAPHICS_DATA_H_
#endif //ARC_GRAPHICS_DATA_H_

141
include/arc/std/config.h Normal file
View file

@ -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 <stdint.h>
#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 <group>:: 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

View file

@ -0,0 +1,48 @@
#ifdef ARC_DEFAULT_CONFIG
#ifndef ARC_DEFAULTS_CONFIG_H_
#define ARC_DEFAULTS_CONFIG_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#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

36
include/arc/std/errno.h Normal file
View file

@ -0,0 +1,36 @@
#ifndef ARC_STD_ERRNO_H_
#define ARC_STD_ERRNO_H_
#include <stdint.h>
#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 <stdio.h>
# 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_

110
include/arc/std/handler.h Normal file
View file

@ -0,0 +1,110 @@
#ifndef ARC_STD_HANDLER_H_
#define ARC_STD_HANDLER_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/**
* @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_

121
include/arc/std/hashtable.h Normal file
View file

@ -0,0 +1,121 @@
#ifndef ARC_STD_HASHTABLE_H_
#define ARC_STD_HASHTABLE_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stddef.h>
/**
* @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_

26
include/arc/std/io.h Normal file
View file

@ -0,0 +1,26 @@
#ifndef ARC_STD_IO_H_
#define ARC_STD_IO_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/**
* @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_

104
include/arc/std/string.h Normal file
View file

@ -0,0 +1,104 @@
#ifndef ARC_STD_STRING_H_
#define ARC_STD_STRING_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/**
* @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_

82
include/arc/std/vector.h Normal file
View file

@ -0,0 +1,82 @@
#ifndef ARC_STD_VECTOR_H_
#define ARC_STD_VECTOR_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/**
* @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_

417
src/std/config.c Normal file
View file

@ -0,0 +1,417 @@
#include "arc/std/config.h"
#include "arc/std/errno.h"
#include "arc/std/io.h"
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
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;
}

116
src/std/defaults/config.c Normal file
View file

@ -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 <stdio.h>
#include <stdlib.h>
#include <string.h>
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

68
src/std/handler.c Normal file
View file

@ -0,0 +1,68 @@
#include "arc/std/handler.h"
#include "arc/std/errno.h"
#include "arc/std/vector.h"
#include <stdlib.h>
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);
}

167
src/std/hashtable.c Normal file
View file

@ -0,0 +1,167 @@
#include "arc/std/hashtable.h"
#include "arc/std/errno.h"
#include <stdlib.h>
#include <stdio.h>
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;
}

28
src/std/io.c Normal file
View file

@ -0,0 +1,28 @@
#include "arc/std/io.h"
#include "arc/std/errno.h"
#include <stdio.h>
#include <stdlib.h>
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;
}

115
src/std/string.c Normal file
View file

@ -0,0 +1,115 @@
#include "arc/std/string.h"
#include "arc/std/errno.h"
#include <string.h>
#include <stdlib.h>
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;
}

109
src/std/vector.c Normal file
View file

@ -0,0 +1,109 @@
#include "arc/std/vector.h"
#include "arc/std/errno.h"
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
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)); }