Author | Jamozed <[email protected]> |
Date | 2020-06-26 02:06:57 |
Commit | ca86cbe4d4875260ed5b9f0550312f8245628cc0 |
meta: Add base project files
Diffstat
A | .gitignore | | | 8 | ++++++++ |
A | CMakeLists.txt | | | 11 | +++++++++++ |
A | LICENCE | | | 27 | +++++++++++++++++++++++++++ |
A | README.md | | | 32 | ++++++++++++++++++++++++++++++++ |
A | build/buildUNIX.sh | | | 4 | ++++ |
A | ext/error.h | | | 48 | ++++++++++++++++++++++++++++++++++++++++++++++++ |
A | ext/optget.h | | | 169 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
7 files changed, 299 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..99dc2fa --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +.clangd/ +bin/ +build/* +!build/buildUNIX.sh +!build/buildWIN32.bat +!build/buildWIN64.bat +compile_commands.json +lib/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..1000e7e --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,11 @@ +# CMakeLists.txt +# CMakeLists file for OMKOV coreutils + +CMAKE_MINIMUM_REQUIRED(VERSION 3.9) +PROJECT(coreutils C) + +SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib) +SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib) +SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/ext) diff --git a/LICENCE b/LICENCE new file mode 100644 index 0000000..a3b99cd --- /dev/null +++ b/LICENCE @@ -0,0 +1,27 @@ +OMKOV Permissive Licence, version 1.0 + +Copyright (C) 2020, Jakob Wakeling +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal with +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: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimers. +* Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimers in the documentation and/or + other materials provided with the distribution. +* Neither the names of the copyright holders, nor the names of its contributors + may be used to endorse or promote products derived from this Software without + specific prior written permission. + +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 COPYRIGHT +HOLDERS OR CONTRIBUTORS 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 WITH THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..c6b9f75 --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ +# OMKOV Core Utilities + +> OMKOV implementations of core software utilities + +OMKOV Core Utilities (coreutils) implements many basic software utilities +commonly found on UNIX-like systems. + +## Utilities + +| Utility | Description | Standard | +| ---------------- | ---------------------------------------- | -------- | + +## Build Instructions + +OMKOV coreutils uses CMake to build. +Binaries will be located in the `bin` directory. + +### UNIX Build + +Run `buildUNIX.sh` in the `build` directory, or + +```sh +cd build +cmake ../ +make +``` + +## Meta + +Copyright (C) 2020, Jakob Wakeling +All rights reserved. +[OMKOV Permissive Licence](https://www.omkov.net/OLPE) diff --git a/build/buildUNIX.sh b/build/buildUNIX.sh new file mode 100755 index 0000000..d7d509f --- /dev/null +++ b/build/buildUNIX.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh +dir="$(dirname $(realpath "$0"))" +cd "$dir" && cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXPORT_COMPILE_COMMANDS=1 ../ && make +mv -f "compile_commands.json" "../compile_commands.json" diff --git a/ext/error.h b/ext/error.h new file mode 100644 index 0000000..91c0796 --- /dev/null +++ b/ext/error.h @@ -0,0 +1,48 @@ +// error.h, version 1.0.0 +// OMKOV error library +// Copyright (C) 2020, Jakob Wakeling +// All rights reserved. + +/* +OMKOV Public Domain Licence, version 1.0 + +Permission is hereby granted to deal with this software and its associated +documentation files without restriction. + +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 COPYRIGHT +HOLDERS OR CONTRIBUTORS 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 WITH THE SOFTWARE. +*/ + +#ifndef OMKOV_ERROR_H_38W06M3W +#define OMKOV_ERROR_H_38W06M3W + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> + +#define serrno strerror(errno) + +static void error(int status, const char *format, ...) { + va_list ap; va_start(ap, format); fflush(stdout); + vfprintf(stderr, format, ap); fputc('\n', stderr); + va_end(ap); exit(status); +} + +static void warn(const char *format, ...) { + va_list ap; va_start(ap, format); fflush(stdout); + vfprintf(stderr, format, ap); fputc('\n', stderr); + va_end(ap); return; +} + +#ifdef __cplusplus +} +#endif // __cplusplus +#endif // OMKOV_ERROR_H_38W06M3W diff --git a/ext/optget.h b/ext/optget.h new file mode 100644 index 0000000..cc9ed90 --- /dev/null +++ b/ext/optget.h @@ -0,0 +1,169 @@ +// optget.h, version 1.5.1 +// OMKOV optget library +// Copyright (C) 2020, Jakob Wakeling +// All rights reserved. + +/* +OMKOV Permissive Licence, version 1.0 + +Copyright (C) 2020, Jakob Wakeling +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal with +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: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimers. +* Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimers in the documentation and/or + other materials provided with the distribution. +* Neither the names of the copyright holders, nor the names of its contributors + may be used to endorse or promote products derived from this Software without + specific prior written permission. + +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 COPYRIGHT +HOLDERS OR CONTRIBUTORS 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 WITH THE SOFTWARE. +*/ + +#ifndef OMKOV_OPTGET_H_W3LIZK1S +#define OMKOV_OPTGET_H_W3LIZK1S + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#include <stdio.h> +#include <string.h> + +#define ARG_NUL 0 +#define ARG_REQ 1 +#define ARG_OPT 2 + +typedef struct { + char *str; + int arg, val; +} lop_t; + +typedef struct { + int ind, opt, pos, nop; + char *arg, *lop, *str; + lop_t *lops; +} opt_t; + +static const opt_t OPTGET_INIT = { 1, 0, 1, 0, NULL, NULL, NULL, NULL }; + +static inline void _permute(char *argv[], int ind, int n); + +#define cur argv[opt->ind] + +/* + Parse the next command line argument +*/ +static inline int optget(opt_t *opt, char *argv[], int flags) { + if (flags & 1) { + for (; cur && (cur[0] != '-' || cur[1] == 0); ++opt->ind, ++opt->nop); + if (!cur) { opt->ind -= opt->nop; opt->nop = 0; return -1; } + } + else if (!cur || (cur[0] != '-' || cur[1] == 0)) { return -1; } + + int optind = opt->ind, optret; + + if (cur[1] == '-') { + if (cur[2] == 0) { if (opt->nop) { + _permute(argv, opt->ind++, opt->nop); + opt->ind -= opt->nop; opt->nop = 0; + } else { ++opt->ind; } return -1; + } + + int optend, lop; optret = '?'; opt->opt = 0; opt->lop = cur; + if (!opt->lops) { goto nol; } + for (optend = 2; cur[optend] != '=' && cur[optend] != 0; ++optend) {} + + for (lop = 0; opt->lops[lop].str; ++lop) { + if (strncmp(&cur[2], opt->lops[lop].str, (size_t)optend - 2) == 0) { + if (!opt->lops[lop].str[optend - 2]) { + optret = opt->opt = opt->lops[lop].val; + break; + } + } + } + + if (opt->lops[lop].arg > ARG_NUL) { + if (cur[optend]) { opt->arg = &cur[optend + 1]; } + else if (argv[opt->ind + 1]) { opt->arg = argv[++opt->ind]; } + else { + if (opt->lops[lop].arg == ARG_REQ) { optret = ':'; } + opt->arg = NULL; + } + } + else { opt->arg = NULL; } + +nol: opt->pos = 0; + } + else { + optret = opt->opt = cur[opt->pos++]; opt->lop = NULL; + const char *optchr = strchr(opt->str, opt->opt); + + if (!optchr) { optret = '?'; } + else if (optchr[1] == ':') { + if (cur[opt->pos]) { opt->arg = &cur[opt->pos]; } + else if (argv[opt->ind + 1]) { opt->arg = argv[++opt->ind]; } + else { opt->arg = NULL; optret = ':'; } + opt->pos = 0; + } + else { opt->arg = NULL; } + } + + if (!opt->pos || !cur[opt->pos]) { + ++opt->ind; opt->pos = 1; + if (opt->nop) for (; optind < opt->ind; ++optind) { + _permute(argv, optind, opt->nop); + } + } + + if (optret == '?' && opt->str[0] != ':') { + if (opt->opt) { + fprintf(stderr, "%s: invalid option -- '%c'\n", argv[0], opt->opt); + } + else if (opt->lop) { + fprintf(stderr, "%s: invalid option '%s'\n", argv[0], opt->lop); + } + } + if (optret == ':' && opt->str[0] != ':') { + if (opt->opt) { + fprintf(stderr, "%s: option requires argument -- '%c'\n", argv[0], + opt->opt); + } + else if (opt->lop) { + fprintf(stderr, "%s: option requires argument '%s'\n", argv[0], + opt->lop); + } + } + + return optret; +} + +/* + Permute arguments +*/ +static inline void _permute(char *argv[], int ind, int n) { + char *arg = argv[ind]; + for (int i = ind; i > ind - n; --i) { argv[i] = argv[i - 1]; } + argv[ind - n] = arg; + return; +} + +#undef cur // argv[opt->ind] + +#ifdef __cplusplus +} +#endif // __cplusplus +#endif // OMKOV_OPTGET_H_W3LIZK1S