mirror of https://github.com/fairyglade/ly.git
Remove unused dependencies
This commit is contained in:
parent
85600ee9b3
commit
13c9aa7c1b
|
|
@ -1,2 +0,0 @@
|
||||||
bin
|
|
||||||
obj
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
obj
|
|
||||||
bin
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
|
||||||
Version 2, December 2004
|
|
||||||
|
|
||||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
|
||||||
|
|
||||||
Everyone is permitted to copy and distribute verbatim or modified
|
|
||||||
copies of this license document, and changing it is allowed as long
|
|
||||||
as the name is changed.
|
|
||||||
|
|
||||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
|
||||||
|
|
||||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
|
||||||
|
|
@ -1,79 +0,0 @@
|
||||||
# Testoasterror
|
|
||||||
Testoasterror is a minimalistic testing library. It is written in C99
|
|
||||||
and does not use dynamic memory allocations by default.
|
|
||||||
|
|
||||||
# Testing
|
|
||||||
Run `make` and `make run`. This will execute the example in the `tests` folder.
|
|
||||||
|
|
||||||
# Using
|
|
||||||
## TL;DR
|
|
||||||
Check out the `tests` folder
|
|
||||||
|
|
||||||
## Details
|
|
||||||
Include `testoasterror.h` and compile `testoasterror.c` with your testing `main()`.
|
|
||||||
|
|
||||||
Declare an array of `bool` to hold the results of each tested expression.
|
|
||||||
Its size determines the maximum number of expression checks for the same test.
|
|
||||||
If one outreaches that limit, testoasterror will print a "fail overflow" message.
|
|
||||||
The limit is 255, the maximum for a `uint8_t`.
|
|
||||||
```
|
|
||||||
bool results[255];
|
|
||||||
```
|
|
||||||
|
|
||||||
Also declare an array of function pointers to hold your tests
|
|
||||||
```
|
|
||||||
void (*funcs[3])(struct testoasterror*) =
|
|
||||||
{
|
|
||||||
test1,
|
|
||||||
test2,
|
|
||||||
test3
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Then, initialize a testoasterror context, giving:
|
|
||||||
- a pointer to the context to initialize
|
|
||||||
- the expression results buffer
|
|
||||||
- its length
|
|
||||||
- the testing functions array
|
|
||||||
- its length
|
|
||||||
```
|
|
||||||
struct testoasterror test;
|
|
||||||
testoasterror_init(&test, results, 255, funcs, 3);
|
|
||||||
```
|
|
||||||
|
|
||||||
Run the tests and you're good to go!
|
|
||||||
```
|
|
||||||
testoasterror_run(&test);
|
|
||||||
```
|
|
||||||
|
|
||||||
You can now write your tests in other C files, using the same function prototype
|
|
||||||
```
|
|
||||||
#ifndef C_TESTS
|
|
||||||
#define C_TESTS
|
|
||||||
|
|
||||||
#include "testoasterror.h"
|
|
||||||
|
|
||||||
// a test
|
|
||||||
void test1(struct testoasterror* test)
|
|
||||||
{
|
|
||||||
// an expression check
|
|
||||||
testoasterror(test, 1 > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
```
|
|
||||||
|
|
||||||
It is, in my opinion, a good idea to include them directly with the `main()`.
|
|
||||||
This way, the function pointers will resolve without the need for a header
|
|
||||||
(hence the include guards in the C file example above)
|
|
||||||
```
|
|
||||||
#include "tests.c"
|
|
||||||
```
|
|
||||||
|
|
||||||
Extra: to abort, call the fail function *and return*
|
|
||||||
```
|
|
||||||
testoasterror_fail(test);
|
|
||||||
```
|
|
||||||
|
|
||||||
# Greetings
|
|
||||||
nnorm for ninja-starring this repo (how can you be *this* fast?!)
|
|
||||||
|
|
@ -1,155 +0,0 @@
|
||||||
#include "testoasterror.h"
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
void testoasterror_init(
|
|
||||||
struct testoasterror* test,
|
|
||||||
bool* results,
|
|
||||||
uint8_t max,
|
|
||||||
void (**funcs)(struct testoasterror*),
|
|
||||||
uint16_t count)
|
|
||||||
{
|
|
||||||
test->testing = false;
|
|
||||||
test->results = results;
|
|
||||||
test->results_end = results + max;
|
|
||||||
|
|
||||||
test->funcs = funcs;
|
|
||||||
test->funcs_count = count;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool testoasterror_log(struct testoasterror* test)
|
|
||||||
{
|
|
||||||
bool* results = test->results;
|
|
||||||
uint8_t max = test->results_cur - results;
|
|
||||||
uint8_t passed_expr = 0;
|
|
||||||
|
|
||||||
// checks the saved status of all processed expressions
|
|
||||||
for (uint8_t i = 0; i < max; ++i)
|
|
||||||
{
|
|
||||||
if (results[i])
|
|
||||||
{
|
|
||||||
++passed_expr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// first fail
|
|
||||||
if (passed_expr == i)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "failed expression ids:");
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stderr, " %u", i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// newline if we printed any failed expression id
|
|
||||||
if (passed_expr != max)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (test->failexec)
|
|
||||||
{
|
|
||||||
fprintf(
|
|
||||||
stderr,
|
|
||||||
"aborted before expression: %u\n",
|
|
||||||
max);
|
|
||||||
}
|
|
||||||
|
|
||||||
// expressions summary
|
|
||||||
fprintf(
|
|
||||||
stderr,
|
|
||||||
"expressions: %u passed, %u failed\n",
|
|
||||||
passed_expr,
|
|
||||||
max - passed_expr);
|
|
||||||
|
|
||||||
return (passed_expr == max);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool testoasterror_run(struct testoasterror* test)
|
|
||||||
{
|
|
||||||
// don't run tests in tests...
|
|
||||||
if (test->testing == true)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* result;
|
|
||||||
bool func_passed;
|
|
||||||
uint16_t tests_passed = 0;
|
|
||||||
|
|
||||||
fprintf(
|
|
||||||
stderr,
|
|
||||||
"running %u tests with %u expr slots\n\n",
|
|
||||||
test->funcs_count,
|
|
||||||
(uint8_t) (test->results_end - test->results));
|
|
||||||
|
|
||||||
// runs the test functions from the given function pointers
|
|
||||||
for (uint16_t i = 0; i < test->funcs_count; ++i)
|
|
||||||
{
|
|
||||||
// resets the expr results
|
|
||||||
test->results_cur = test->results;
|
|
||||||
test->failoverflow = false;
|
|
||||||
test->failexec = false;
|
|
||||||
|
|
||||||
// runs the test
|
|
||||||
test->funcs_index = i;
|
|
||||||
test->funcs[i](test);
|
|
||||||
|
|
||||||
// outputs info (a fail overflow is considered a fail)
|
|
||||||
func_passed = testoasterror_log(test)
|
|
||||||
&& !test->failoverflow
|
|
||||||
&& !test->failexec;
|
|
||||||
tests_passed += func_passed;
|
|
||||||
|
|
||||||
// generates a message describing the test results
|
|
||||||
if (test->failoverflow == true)
|
|
||||||
{
|
|
||||||
result = "encountered a fail overflow";
|
|
||||||
}
|
|
||||||
else if (test->failexec == true)
|
|
||||||
{
|
|
||||||
result = "aborted";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = func_passed ? "passed" : "failed";
|
|
||||||
}
|
|
||||||
|
|
||||||
// test status
|
|
||||||
fprintf(stderr, "test #%u %s\n\n", i, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
// tests summary
|
|
||||||
fprintf(
|
|
||||||
stderr,
|
|
||||||
"tests: %u passed, %u failed\n",
|
|
||||||
tests_passed,
|
|
||||||
test->funcs_count - tests_passed);
|
|
||||||
|
|
||||||
return (test->funcs_count == tests_passed);
|
|
||||||
}
|
|
||||||
|
|
||||||
// save a test status
|
|
||||||
bool testoasterror(struct testoasterror* test, bool expr)
|
|
||||||
{
|
|
||||||
if (test->results_cur < test->results_end)
|
|
||||||
{
|
|
||||||
*(test->results_cur) = expr;
|
|
||||||
++(test->results_cur);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
test->failoverflow = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return expr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// handles set execution fails
|
|
||||||
void testoasterror_fail(struct testoasterror* test)
|
|
||||||
{
|
|
||||||
test->failexec = true;
|
|
||||||
}
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
#ifndef H_TESTOASTERROR
|
|
||||||
#define H_TESTOASTERROR
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
// main structure
|
|
||||||
struct testoasterror
|
|
||||||
{
|
|
||||||
// this is a test library so we handle all weird cases
|
|
||||||
bool testing;
|
|
||||||
|
|
||||||
// test results for one function
|
|
||||||
bool* results;
|
|
||||||
bool* results_cur;
|
|
||||||
bool* results_end;
|
|
||||||
|
|
||||||
// whether the function made too much tests for the results array
|
|
||||||
bool failoverflow; // <3
|
|
||||||
// execution fail
|
|
||||||
bool failexec;
|
|
||||||
|
|
||||||
// test functions
|
|
||||||
void (**funcs)(struct testoasterror*);
|
|
||||||
uint16_t funcs_index;
|
|
||||||
uint16_t funcs_count;
|
|
||||||
};
|
|
||||||
|
|
||||||
// testoasterror can be static if you want it to (:
|
|
||||||
void testoasterror_init(
|
|
||||||
struct testoasterror* test,
|
|
||||||
bool* results,
|
|
||||||
uint8_t max,
|
|
||||||
void (**funcs)(struct testoasterror*),
|
|
||||||
uint16_t count);
|
|
||||||
bool testoasterror_run(struct testoasterror* test);
|
|
||||||
bool testoasterror(struct testoasterror* test, bool expr);
|
|
||||||
void testoasterror_count(struct testoasterror* test, uint16_t count);
|
|
||||||
void testoasterror_fail(struct testoasterror* test);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
#include "testoasterror.h"
|
|
||||||
|
|
||||||
// source include
|
|
||||||
#include "tests.c"
|
|
||||||
|
|
||||||
#define COUNT_RESULTS 2
|
|
||||||
#define COUNT_FUNCS 3
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
bool results[COUNT_RESULTS];
|
|
||||||
void (*funcs[COUNT_FUNCS])(struct testoasterror*) =
|
|
||||||
{
|
|
||||||
test1,
|
|
||||||
test2,
|
|
||||||
test3
|
|
||||||
};
|
|
||||||
|
|
||||||
struct testoasterror test;
|
|
||||||
testoasterror_init(&test, results, COUNT_RESULTS, funcs, COUNT_FUNCS);
|
|
||||||
testoasterror_run(&test);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
#ifndef C_TESTS
|
|
||||||
#define C_TESTS
|
|
||||||
|
|
||||||
#include "testoasterror.h"
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
void test1(struct testoasterror* test)
|
|
||||||
{
|
|
||||||
testoasterror(test, 1 == 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void test2(struct testoasterror* test)
|
|
||||||
{
|
|
||||||
testoasterror(test, 0 == 0);
|
|
||||||
testoasterror(test, 1 == 1);
|
|
||||||
testoasterror(test, 2 == 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void test3(struct testoasterror* test)
|
|
||||||
{
|
|
||||||
bool res;
|
|
||||||
|
|
||||||
res = testoasterror(test, strcmp("fuck", "shit") == 0);
|
|
||||||
|
|
||||||
if (!res)
|
|
||||||
{
|
|
||||||
testoasterror_fail(test);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
testoasterror(test, 0 == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
|
||||||
Version 2, December 2004
|
|
||||||
|
|
||||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
|
||||||
|
|
||||||
Everyone is permitted to copy and distribute verbatim or modified
|
|
||||||
copies of this license document, and changing it is allowed as long
|
|
||||||
as the name is changed.
|
|
||||||
|
|
||||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
|
||||||
|
|
||||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
|
||||||
|
|
@ -1,129 +0,0 @@
|
||||||
# Argoat
|
|
||||||
Argoat is a lightweight library for command-line options parsing.
|
|
||||||
This was created because most of the existing solutions rely heavily on macros,
|
|
||||||
and all of them expect you to write a giant switch to handle the given options.
|
|
||||||
|
|
||||||
Argoat allows you to deal with arguments using function pointers.
|
|
||||||
It does not use any macro, switch, or dynamic memory allocation.
|
|
||||||
|
|
||||||
Argoat supports the following syntaxes:
|
|
||||||
- simple options `test -a -b`
|
|
||||||
- compound options `test -ab`
|
|
||||||
- assigned options `test -c=4 -d 2`
|
|
||||||
- long options `test --code 4 --den 2`
|
|
||||||
- lone dash `test --oki - --den 2`
|
|
||||||
- lone double-dash `test --oki -- --doki`
|
|
||||||
- unflagged options `test 0 -c=4 1 -d=2 3`
|
|
||||||
- limited params `test 0 -c 4 1 -d 2 3`
|
|
||||||
|
|
||||||
Argoat does not support the following syntaxes *on purpose*:
|
|
||||||
- simple neighbours `test -a4`
|
|
||||||
- custom symbols `test +a 4`
|
|
||||||
|
|
||||||
All of that in around 200 lines of code (getopt has approximately 700).
|
|
||||||
Don't be shy, sneak a goat in your code.
|
|
||||||
|
|
||||||
## Cloning
|
|
||||||
Clone with `--recurse-submodules` to get the required submodules.
|
|
||||||
|
|
||||||
## Testing
|
|
||||||
Run `make` to compile the testing suite, and `make run` to perform the tests.
|
|
||||||
|
|
||||||
## Using
|
|
||||||
### TL;DR
|
|
||||||
```
|
|
||||||
#include "argoat.h"
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
void handle_main(void* data, char** pars, const int pars_count)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void handle_bool(void* data, char** pars, const int pars_count)
|
|
||||||
{
|
|
||||||
*((bool*) data) = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
bool data1 = false;
|
|
||||||
char* unflagged[23];
|
|
||||||
|
|
||||||
const struct argoat_sprig sprigs[2] =
|
|
||||||
{
|
|
||||||
{NULL, 0, NULL, handle_main},
|
|
||||||
{"t", 0, (void*) &data1, handle_bool}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct argoat args = {sprigs, 2, unflagged, 0, 23};
|
|
||||||
argoat_graze(&args, argc, argv);
|
|
||||||
printf("%c\n", data1 ? '1' : '0');
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Details
|
|
||||||
Include `argoat.h` and compile `argoat.c` with your code.
|
|
||||||
|
|
||||||
Write the functions that will handle your parameters.
|
|
||||||
They will be called during the parsing process, in the order given by the user
|
|
||||||
```
|
|
||||||
void handle_main(void* data, char** pars, const int pars_count)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void handle_bool(void* data, char** pars, const int pars_count)
|
|
||||||
{
|
|
||||||
*((bool*) data) = true;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
In your `int main(int argc, char** argv)`, declare the variables to configure.
|
|
||||||
They will be passed to the corresponding functions as `void* data`
|
|
||||||
```
|
|
||||||
bool data1 = false;
|
|
||||||
```
|
|
||||||
|
|
||||||
Also declare an array of strings to store the unflagged arguments.
|
|
||||||
Just choose a size corresponding to the maximum number of unflagged arguments
|
|
||||||
your program supports, or create a null pointer if it does not use them.
|
|
||||||
```
|
|
||||||
char* unflagged[UNFLAGGED_MAX];
|
|
||||||
```
|
|
||||||
|
|
||||||
Then, declare an array of flag structures.
|
|
||||||
The first entry only has to contain the unflagged-arguments handling function.
|
|
||||||
The others must specify:
|
|
||||||
- the name of the flag (one char for '-' prefix, multiple chars for '--')
|
|
||||||
- the maximum number of arguments supported by this flag
|
|
||||||
- a pointer to the data that has to be configured by the handling function
|
|
||||||
- a pointer to the handling function
|
|
||||||
```
|
|
||||||
const struct argoat_sprig sprigs[2] =
|
|
||||||
{
|
|
||||||
{NULL, 0, NULL, handle_main},
|
|
||||||
{"t", 0, (void*) &data1, handle_bool}
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
Then, create the main argoat structure given:
|
|
||||||
- the flags array
|
|
||||||
- its size,
|
|
||||||
- the unflagged string buffer
|
|
||||||
- the initial number of unflagged arguments
|
|
||||||
- the maximum possible
|
|
||||||
```
|
|
||||||
struct argoat args = {sprigs, 2, unflagged, 0, UNFLAGGED_MAX};
|
|
||||||
```
|
|
||||||
|
|
||||||
All that remains to do is calling the parsing function
|
|
||||||
```
|
|
||||||
argoat_graze(&args, argc, argv);
|
|
||||||
```
|
|
||||||
|
|
||||||
And using the configured data
|
|
||||||
```
|
|
||||||
printf("%c\n", data1 ? '1' : '0');
|
|
||||||
```
|
|
||||||
|
|
@ -1,234 +0,0 @@
|
||||||
#include "argoat.h"
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
// executes the function for unflagged pars
|
|
||||||
void argoat_unflagged_sacrifice(const struct argoat* args)
|
|
||||||
{
|
|
||||||
args->sprigs[0].func(args->sprigs[0].data,
|
|
||||||
args->unflagged,
|
|
||||||
args->unflagged_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns 1 to increment the pars counter if the one given is flagged
|
|
||||||
// otherwise we store the unflagged par in the buffer and return 0
|
|
||||||
int argoat_increment_pars(struct argoat* args, char* flag, char* pars)
|
|
||||||
{
|
|
||||||
// unflagged pars
|
|
||||||
if (flag == NULL)
|
|
||||||
{
|
|
||||||
// tests bounds and saves
|
|
||||||
int count = args->unflagged_count;
|
|
||||||
|
|
||||||
if (count < args->unflagged_max)
|
|
||||||
{
|
|
||||||
args->unflagged[count] = pars;
|
|
||||||
++args->unflagged_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// flagged pars
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// function execution
|
|
||||||
void argoat_sacrifice(struct argoat* args,
|
|
||||||
char* flag,
|
|
||||||
char** pars,
|
|
||||||
int pars_count)
|
|
||||||
{
|
|
||||||
// first flag found or tag compound passed
|
|
||||||
if (flag == NULL)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// handles flags with '='
|
|
||||||
int flag_len;
|
|
||||||
char* eq = strchr(flag, '=');
|
|
||||||
|
|
||||||
if (eq != NULL)
|
|
||||||
{
|
|
||||||
flag_len = eq - flag;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
flag_len = strlen(flag); // safe
|
|
||||||
}
|
|
||||||
|
|
||||||
// searches the tag in the argoat structure
|
|
||||||
// we initialize i to 1 to skip the programm execution command
|
|
||||||
int i = 1;
|
|
||||||
int len = args->sprigs_count;
|
|
||||||
|
|
||||||
while(i < len)
|
|
||||||
{
|
|
||||||
// as we use strncmp we must test the sizes to avoid collisions
|
|
||||||
if ((strncmp(args->sprigs[i].flag, flag, flag_len) == 0)
|
|
||||||
&& (((int) strlen(args->sprigs[i].flag)) == flag_len)) // safe
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
|
|
||||||
// the flag was not registered
|
|
||||||
if (i == len)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// handles flags with '='
|
|
||||||
// maximum number of pars passed to the function
|
|
||||||
int max;
|
|
||||||
|
|
||||||
if (eq != NULL)
|
|
||||||
{
|
|
||||||
// moves past the '=' char
|
|
||||||
++eq;
|
|
||||||
// moves the pars pointer to the flag
|
|
||||||
--pars;
|
|
||||||
|
|
||||||
// flag with '=' means we wave an additionnal parameter
|
|
||||||
++pars_count;
|
|
||||||
// which will be the only one (the others are left unflagged)
|
|
||||||
max = 1;
|
|
||||||
|
|
||||||
// copies the par following '=' at the beginning of the flag
|
|
||||||
memcpy(pars[0], eq, strlen(eq) + 1); // safe
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
max = args->sprigs[i].pars_max;
|
|
||||||
}
|
|
||||||
|
|
||||||
// saves pars exceeding the limit
|
|
||||||
if (pars_count > max)
|
|
||||||
{
|
|
||||||
for(int k = max; k < pars_count; ++k)
|
|
||||||
{
|
|
||||||
// leverages the pars incrementation side-effects
|
|
||||||
argoat_increment_pars(args, NULL, pars[k]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// fixes the number of pars given to the function
|
|
||||||
pars_count = max;
|
|
||||||
}
|
|
||||||
|
|
||||||
// calls the approriate function
|
|
||||||
args->sprigs[i].func(args->sprigs[i].data, pars, pars_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
// executes functions without pars for compound tags
|
|
||||||
void argoat_compound(struct argoat* args, char** pars)
|
|
||||||
{
|
|
||||||
// currently processed char/flag
|
|
||||||
int scroll = 1;
|
|
||||||
char flag[2]; // safe
|
|
||||||
|
|
||||||
flag[1] = '\0';
|
|
||||||
|
|
||||||
// if this function is excuted this means there is at least one flag
|
|
||||||
// therefore it is safe to test the condition for the next char only
|
|
||||||
do
|
|
||||||
{
|
|
||||||
flag[0] = pars[0][scroll];
|
|
||||||
argoat_sacrifice(args, flag, pars, 0);
|
|
||||||
++scroll;
|
|
||||||
}
|
|
||||||
while(pars[0][scroll] != '\0');
|
|
||||||
}
|
|
||||||
|
|
||||||
// executes functions with pars for each flag
|
|
||||||
void argoat_graze(struct argoat* args, int argc, char** argv)
|
|
||||||
{
|
|
||||||
int pars_count = 0;
|
|
||||||
char** pars = NULL;
|
|
||||||
char* flag = NULL;
|
|
||||||
char dash;
|
|
||||||
|
|
||||||
// skips the program execution command
|
|
||||||
++argv;
|
|
||||||
--argc;
|
|
||||||
|
|
||||||
// identifies every element in argv and executes the right
|
|
||||||
// handling functions during the process
|
|
||||||
for (int i = 0; i < argc; ++i)
|
|
||||||
{
|
|
||||||
// will be tested to identify lone dashes and long flags
|
|
||||||
dash = argv[i][1];
|
|
||||||
|
|
||||||
// pars
|
|
||||||
if (argv[i][0] != '-')
|
|
||||||
{
|
|
||||||
pars_count += argoat_increment_pars(args,
|
|
||||||
flag,
|
|
||||||
argv[i]);
|
|
||||||
}
|
|
||||||
// lone dash pars
|
|
||||||
else if (dash == '\0')
|
|
||||||
{
|
|
||||||
pars_count += argoat_increment_pars(args,
|
|
||||||
flag,
|
|
||||||
argv[i]);
|
|
||||||
}
|
|
||||||
// very probably long flags
|
|
||||||
else if (dash == '-')
|
|
||||||
{
|
|
||||||
// lone double-dash pars
|
|
||||||
if (argv[i][2] == '\0')
|
|
||||||
{
|
|
||||||
pars_count += argoat_increment_pars(args,
|
|
||||||
flag,
|
|
||||||
argv[i]);
|
|
||||||
}
|
|
||||||
// long flags
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// executes for previous flag
|
|
||||||
argoat_sacrifice(args, flag, pars, pars_count);
|
|
||||||
// starts a new flag scope
|
|
||||||
flag = argv[i] + 2;
|
|
||||||
pars = argv + i + 1;
|
|
||||||
pars_count = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// flags
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// executes for previous flag
|
|
||||||
argoat_sacrifice(args, flag, pars, pars_count);
|
|
||||||
|
|
||||||
// compound flags (eg "-xvzf") directly executes
|
|
||||||
if ((argv[i][2] != '=') && (argv[i][2] != '\0'))
|
|
||||||
{
|
|
||||||
// to get rid of the dash
|
|
||||||
argoat_compound(args, argv + i);
|
|
||||||
flag = NULL;
|
|
||||||
pars = NULL;
|
|
||||||
}
|
|
||||||
// simple flags
|
|
||||||
else
|
|
||||||
{
|
|
||||||
flag = argv[i] + 1;
|
|
||||||
pars = argv + i + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pars_count = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// we call the function corresponding to the last flag
|
|
||||||
argoat_sacrifice(args, flag, pars, pars_count);
|
|
||||||
// we call the function handling unflagged pars
|
|
||||||
if (args->unflagged_max > 0)
|
|
||||||
{
|
|
||||||
argoat_unflagged_sacrifice(args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
#ifndef H_ARGOAT
|
|
||||||
#define H_ARGOAT
|
|
||||||
|
|
||||||
// flag-processor
|
|
||||||
struct argoat_sprig
|
|
||||||
{
|
|
||||||
// dash-prefixed option
|
|
||||||
const char* flag;
|
|
||||||
// maximum pars
|
|
||||||
const int pars_max;
|
|
||||||
// pre-loaded data for the function
|
|
||||||
void* data;
|
|
||||||
// function executed upon detection
|
|
||||||
void (* const func)(void* data, char** pars, const int pars_count);
|
|
||||||
};
|
|
||||||
|
|
||||||
// main structure
|
|
||||||
struct argoat
|
|
||||||
{
|
|
||||||
// the flags-processor list, with handling functions etc.
|
|
||||||
const struct argoat_sprig* sprigs;
|
|
||||||
// size of the list above
|
|
||||||
const int sprigs_count;
|
|
||||||
// unflagged tags buffer
|
|
||||||
char** unflagged;
|
|
||||||
int unflagged_count;
|
|
||||||
int unflagged_max;
|
|
||||||
};
|
|
||||||
|
|
||||||
void argoat_unflagged_sacrifice(const struct argoat* args);
|
|
||||||
int argoat_increment_pars(struct argoat* args, char* flag, char* pars);
|
|
||||||
void argoat_sacrifice(struct argoat* args, char* flag, char** pars, int pars_count);
|
|
||||||
void argoat_compound(struct argoat* args, char** pars);
|
|
||||||
void argoat_graze(struct argoat* args, int argc, char** argv);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
#include "argoat.h"
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
void handle_bool(void* data, char** pars, const int pars_count)
|
|
||||||
{
|
|
||||||
*((bool*) data) = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void handle_main(void* data, char** pars, const int pars_count)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
bool data1 = false;
|
|
||||||
bool data2 = false;
|
|
||||||
bool data3 = false;
|
|
||||||
char** unflagged = NULL;
|
|
||||||
|
|
||||||
const struct argoat_sprig sprigs[4] =
|
|
||||||
{
|
|
||||||
{NULL, 0, NULL, handle_main},
|
|
||||||
{"l", 0, (void*) &data1, handle_bool},
|
|
||||||
{"m", 0, (void*) &data2, handle_bool},
|
|
||||||
{"o", 0, (void*) &data3, handle_bool},
|
|
||||||
};
|
|
||||||
|
|
||||||
struct argoat args = {sprigs, 4, unflagged, 0, 0};
|
|
||||||
|
|
||||||
argoat_graze(&args, argc, argv);
|
|
||||||
|
|
||||||
printf("t%c%c%c\n",
|
|
||||||
data1 ? 'l' : ' ',
|
|
||||||
data2 ? 'm' : ' ',
|
|
||||||
data3 ? 'o' : ' ');
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
#include "argoat.h"
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#define UNFLAGGED_MAX 4
|
|
||||||
|
|
||||||
void handle_bool(void* data, char** pars, const int pars_count)
|
|
||||||
{
|
|
||||||
*((bool*) data) = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void handle_main(void* data, char** pars, const int pars_count)
|
|
||||||
{
|
|
||||||
if (pars_count > UNFLAGGED_MAX)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < pars_count; ++i)
|
|
||||||
{
|
|
||||||
printf("%s", pars[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
bool data1 = false;
|
|
||||||
bool data2 = false;
|
|
||||||
bool data3 = false;
|
|
||||||
char* unflagged[UNFLAGGED_MAX];
|
|
||||||
|
|
||||||
const struct argoat_sprig sprigs[4] =
|
|
||||||
{
|
|
||||||
{NULL, 0, NULL, handle_main},
|
|
||||||
{"long", 0, (void*) &data1, handle_bool},
|
|
||||||
{"mighty", 0, (void*) &data2, handle_bool},
|
|
||||||
{"options", 0, (void*) &data3, handle_bool},
|
|
||||||
};
|
|
||||||
|
|
||||||
struct argoat args = {sprigs, 4, unflagged, 0, UNFLAGGED_MAX};
|
|
||||||
|
|
||||||
argoat_graze(&args, argc, argv);
|
|
||||||
|
|
||||||
printf("t%c%c%c\n",
|
|
||||||
data1 ? 'l' : ' ',
|
|
||||||
data2 ? 'm' : ' ',
|
|
||||||
data3 ? 'o' : ' ');
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
#include "argoat.h"
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#define UNFLAGGED_MAX 4
|
|
||||||
|
|
||||||
void handle_bool(void* data, char** pars, const int pars_count)
|
|
||||||
{
|
|
||||||
*((bool*) data) = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void handle_add(void* data, char** pars, const int pars_count)
|
|
||||||
{
|
|
||||||
if (pars_count < 2)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
*((int*) data) = atoi(pars[0]) + atoi(pars[1]); // safe for testing
|
|
||||||
}
|
|
||||||
|
|
||||||
void handle_string(void* data, char** pars, const int pars_count)
|
|
||||||
{
|
|
||||||
if (pars_count < 1)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
*((char**) data) = pars[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
void handle_main(void* data, char** pars, const int pars_count)
|
|
||||||
{
|
|
||||||
if (pars_count > UNFLAGGED_MAX)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < pars_count; ++i)
|
|
||||||
{
|
|
||||||
printf("%s", pars[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
bool data1 = false;
|
|
||||||
int data2 = 0;
|
|
||||||
char* data3 = "";
|
|
||||||
|
|
||||||
char* unflagged[UNFLAGGED_MAX];
|
|
||||||
|
|
||||||
const struct argoat_sprig sprigs[4] =
|
|
||||||
{
|
|
||||||
{NULL, 0, NULL, handle_main},
|
|
||||||
{"tau", 2, (void*) &data2, handle_add},
|
|
||||||
{"t", 0, (void*) &data1, handle_bool},
|
|
||||||
{"text", 1, (void*) &data3, handle_string},
|
|
||||||
};
|
|
||||||
|
|
||||||
struct argoat args = {sprigs, 4, unflagged, 0, UNFLAGGED_MAX};
|
|
||||||
|
|
||||||
argoat_graze(&args, argc, argv);
|
|
||||||
|
|
||||||
printf("t%c%d%s\n", data1 ? 'l' : ' ', data2, data3);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
#define _POSIX_C_SOURCE 200809L
|
|
||||||
#include "testoasterror.h"
|
|
||||||
|
|
||||||
// source include
|
|
||||||
#include "tests.c"
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
bool results[32];
|
|
||||||
void (*funcs[3])(struct testoasterror*) =
|
|
||||||
{
|
|
||||||
test1,
|
|
||||||
test2,
|
|
||||||
test3
|
|
||||||
};
|
|
||||||
|
|
||||||
struct testoasterror test;
|
|
||||||
testoasterror_init(&test, results, 32, funcs, 3);
|
|
||||||
testoasterror_run(&test);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,80 +0,0 @@
|
||||||
#ifndef C_TESTS
|
|
||||||
#define C_TESTS
|
|
||||||
|
|
||||||
#include "testoasterror.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
void test_tool(struct testoasterror* test, uint8_t id, char* args, char* cmp)
|
|
||||||
{
|
|
||||||
char* ret;
|
|
||||||
char buf[32];
|
|
||||||
char cmd[128];
|
|
||||||
char cmp_ln[16];
|
|
||||||
|
|
||||||
snprintf(cmd, 128, "./argoat_sample_%u %s 2>&1", id, args);
|
|
||||||
snprintf(cmp_ln, 16, "%s\n", cmp);
|
|
||||||
|
|
||||||
FILE* fp = popen(cmd, "r");
|
|
||||||
testoasterror(test, fp != NULL);
|
|
||||||
|
|
||||||
ret = fgets(buf, 32, fp);
|
|
||||||
testoasterror(test, (ret != NULL) && (strcmp(buf, cmp_ln) == 0));
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void test1(struct testoasterror* test)
|
|
||||||
{
|
|
||||||
test_tool(test, 1, "", "t ");
|
|
||||||
|
|
||||||
test_tool(test, 1, "-l", "tl ");
|
|
||||||
test_tool(test, 1, "-m", "t m ");
|
|
||||||
test_tool(test, 1, "-o", "t o");
|
|
||||||
|
|
||||||
test_tool(test, 1, "--l", "tl ");
|
|
||||||
test_tool(test, 1, "--long", "t ");
|
|
||||||
|
|
||||||
test_tool(test, 1, "-lmo", "tlmo");
|
|
||||||
test_tool(test, 1, "-lm -o", "tlmo");
|
|
||||||
test_tool(test, 1, "-l -m -o", "tlmo");
|
|
||||||
|
|
||||||
test_tool(test, 1, "-l 1 -m 2 -o 3", "tlmo");
|
|
||||||
|
|
||||||
test_tool(test, 1, "-l - -m", "tlm ");
|
|
||||||
test_tool(test, 1, "-l --m 3", "tlm ");
|
|
||||||
test_tool(test, 1, "-l --m=3", "tlm ");
|
|
||||||
}
|
|
||||||
|
|
||||||
void test2(struct testoasterror* test)
|
|
||||||
{
|
|
||||||
test_tool(test, 2, "--long", "tl ");
|
|
||||||
test_tool(test, 2, "--mighty", "t m ");
|
|
||||||
test_tool(test, 2, "--options", "t o");
|
|
||||||
|
|
||||||
test_tool(test, 2, "-l", "t ");
|
|
||||||
test_tool(test, 2, "-long", "t ");
|
|
||||||
|
|
||||||
test_tool(test, 2, "--long --mighty --options", "tlmo");
|
|
||||||
test_tool(test, 2, "0 --long 1 --mighty 2 --options 3", "0123tlmo");
|
|
||||||
test_tool(test, 2, "0 --long=1 --mighty 2 --options 3", "023tlmo");
|
|
||||||
test_tool(test, 2, "0 --long=1 4 --mighty 2 --options 3", "0423tlmo");
|
|
||||||
|
|
||||||
test_tool(test, 2, "0 --long - --mighty -- --options 3", "0---3tlmo");
|
|
||||||
}
|
|
||||||
|
|
||||||
void test3(struct testoasterror* test)
|
|
||||||
{
|
|
||||||
test_tool(test, 3, "-t", "tl0");
|
|
||||||
test_tool(test, 3, "--tau", "t 0");
|
|
||||||
test_tool(test, 3, "--text", "t 0");
|
|
||||||
|
|
||||||
test_tool(test, 3, "-t --tau 3 4 5", "5tl7");
|
|
||||||
test_tool(test, 3, "--tau=3 4 5", "45t 0");
|
|
||||||
test_tool(test, 3, "--text one two", "twot 0one");
|
|
||||||
|
|
||||||
test_tool(test, 3, "--text= one two", "onetwot 0");
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
356
src/main.c
356
src/main.c
|
|
@ -1,356 +0,0 @@
|
||||||
#include "argoat.h"
|
|
||||||
#include "configator.h"
|
|
||||||
#include "dragonfail.h"
|
|
||||||
#include "termbox.h"
|
|
||||||
|
|
||||||
#include "draw.h"
|
|
||||||
#include "inputs.h"
|
|
||||||
#include "login.h"
|
|
||||||
#include "utils.h"
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#define ARG_COUNT 7
|
|
||||||
|
|
||||||
#ifndef LY_VERSION
|
|
||||||
#define LY_VERSION "0.7.0"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// global
|
|
||||||
struct lang lang;
|
|
||||||
struct config config;
|
|
||||||
|
|
||||||
// args handles
|
|
||||||
void arg_help(void* data, char** pars, const int pars_count)
|
|
||||||
{
|
|
||||||
printf("If you want to configure Ly, please check the config file, usually located at /etc/ly/config.ini.\n");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void arg_version(void* data, char** pars, const int pars_count)
|
|
||||||
{
|
|
||||||
printf("Ly version %s\n", LY_VERSION);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// low-level error messages
|
|
||||||
void log_init(char** log)
|
|
||||||
{
|
|
||||||
log[DGN_OK] = lang.err_dgn_oob;
|
|
||||||
log[DGN_NULL] = lang.err_null;
|
|
||||||
log[DGN_ALLOC] = lang.err_alloc;
|
|
||||||
log[DGN_BOUNDS] = lang.err_bounds;
|
|
||||||
log[DGN_DOMAIN] = lang.err_domain;
|
|
||||||
log[DGN_MLOCK] = lang.err_mlock;
|
|
||||||
log[DGN_XSESSIONS_DIR] = lang.err_xsessions_dir;
|
|
||||||
log[DGN_XSESSIONS_OPEN] = lang.err_xsessions_open;
|
|
||||||
log[DGN_PATH] = lang.err_path;
|
|
||||||
log[DGN_CHDIR] = lang.err_chdir;
|
|
||||||
log[DGN_PWNAM] = lang.err_pwnam;
|
|
||||||
log[DGN_USER_INIT] = lang.err_user_init;
|
|
||||||
log[DGN_USER_GID] = lang.err_user_gid;
|
|
||||||
log[DGN_USER_UID] = lang.err_user_uid;
|
|
||||||
log[DGN_PAM] = lang.err_pam;
|
|
||||||
log[DGN_HOSTNAME] = lang.err_hostname;
|
|
||||||
}
|
|
||||||
|
|
||||||
void arg_config(void* data, char** pars, const int pars_count)
|
|
||||||
{
|
|
||||||
*((char **)data) = *pars;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ly!
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
// init error lib
|
|
||||||
log_init(dgn_init());
|
|
||||||
|
|
||||||
// load config
|
|
||||||
config_defaults();
|
|
||||||
lang_defaults();
|
|
||||||
|
|
||||||
char *config_path = NULL;
|
|
||||||
// parse args
|
|
||||||
const struct argoat_sprig sprigs[ARG_COUNT] =
|
|
||||||
{
|
|
||||||
{NULL, 0, NULL, NULL},
|
|
||||||
{"config", 0, &config_path, arg_config},
|
|
||||||
{"c", 0, &config_path, arg_config},
|
|
||||||
{"help", 0, NULL, arg_help},
|
|
||||||
{"h", 0, NULL, arg_help},
|
|
||||||
{"version", 0, NULL, arg_version},
|
|
||||||
{"v", 0, NULL, arg_version},
|
|
||||||
};
|
|
||||||
|
|
||||||
struct argoat args = {sprigs, ARG_COUNT, NULL, 0, 0};
|
|
||||||
argoat_graze(&args, argc, argv);
|
|
||||||
|
|
||||||
// init inputs
|
|
||||||
struct desktop desktop;
|
|
||||||
struct text login;
|
|
||||||
struct text password;
|
|
||||||
input_desktop(&desktop);
|
|
||||||
input_text(&login, config.max_login_len);
|
|
||||||
input_text(&password, config.max_password_len);
|
|
||||||
|
|
||||||
if (dgn_catch())
|
|
||||||
{
|
|
||||||
config_free();
|
|
||||||
lang_free();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
config_load(config_path);
|
|
||||||
lang_load();
|
|
||||||
|
|
||||||
void* input_structs[3] =
|
|
||||||
{
|
|
||||||
(void*) &desktop,
|
|
||||||
(void*) &login,
|
|
||||||
(void*) &password,
|
|
||||||
};
|
|
||||||
|
|
||||||
void (*input_handles[3]) (void*, struct tb_event*) =
|
|
||||||
{
|
|
||||||
handle_desktop,
|
|
||||||
handle_text,
|
|
||||||
handle_text,
|
|
||||||
};
|
|
||||||
|
|
||||||
desktop_load(&desktop);
|
|
||||||
load(&desktop, &login);
|
|
||||||
|
|
||||||
// start termbox
|
|
||||||
tb_init();
|
|
||||||
tb_select_output_mode(TB_OUTPUT_NORMAL);
|
|
||||||
tb_clear();
|
|
||||||
|
|
||||||
// init visible elements
|
|
||||||
struct tb_event event;
|
|
||||||
struct term_buf buf;
|
|
||||||
|
|
||||||
//Place the curser on the login field if there is no saved username, if there is, place the curser on the password field
|
|
||||||
uint8_t active_input;
|
|
||||||
if (config.default_input == LOGIN_INPUT && login.text != login.end){
|
|
||||||
active_input = PASSWORD_INPUT;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
active_input = config.default_input;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// init drawing stuff
|
|
||||||
draw_init(&buf);
|
|
||||||
|
|
||||||
// draw_box and position_input are called because they need to be
|
|
||||||
// called before *input_handles[active_input] for the cursor to be
|
|
||||||
// positioned correctly
|
|
||||||
draw_box(&buf);
|
|
||||||
position_input(&buf, &desktop, &login, &password);
|
|
||||||
(*input_handles[active_input])(input_structs[active_input], NULL);
|
|
||||||
|
|
||||||
if (config.animate)
|
|
||||||
{
|
|
||||||
animate_init(&buf);
|
|
||||||
|
|
||||||
if (dgn_catch())
|
|
||||||
{
|
|
||||||
config.animate = false;
|
|
||||||
dgn_reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// init state info
|
|
||||||
int error;
|
|
||||||
bool run = true;
|
|
||||||
bool update = true;
|
|
||||||
bool reboot = false;
|
|
||||||
bool shutdown = false;
|
|
||||||
uint8_t auth_fails = 0;
|
|
||||||
|
|
||||||
switch_tty(&buf);
|
|
||||||
|
|
||||||
// main loop
|
|
||||||
while (run)
|
|
||||||
{
|
|
||||||
if (update)
|
|
||||||
{
|
|
||||||
if (auth_fails < 10)
|
|
||||||
{
|
|
||||||
(*input_handles[active_input])(input_structs[active_input], NULL);
|
|
||||||
tb_clear();
|
|
||||||
animate(&buf);
|
|
||||||
draw_bigclock(&buf);
|
|
||||||
draw_box(&buf);
|
|
||||||
draw_clock(&buf);
|
|
||||||
draw_labels(&buf);
|
|
||||||
if(!config.hide_f1_commands)
|
|
||||||
draw_f_commands();
|
|
||||||
draw_lock_state(&buf);
|
|
||||||
position_input(&buf, &desktop, &login, &password);
|
|
||||||
draw_desktop(&desktop);
|
|
||||||
draw_input(&login);
|
|
||||||
draw_input_mask(&password);
|
|
||||||
update = config.animate;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
usleep(10000);
|
|
||||||
update = cascade(&buf, &auth_fails);
|
|
||||||
}
|
|
||||||
|
|
||||||
tb_present();
|
|
||||||
}
|
|
||||||
|
|
||||||
int timeout = -1;
|
|
||||||
|
|
||||||
if (config.animate)
|
|
||||||
{
|
|
||||||
timeout = config.min_refresh_delta;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
struct timeval tv;
|
|
||||||
gettimeofday(&tv, NULL);
|
|
||||||
if (config.bigclock)
|
|
||||||
timeout = (60 - tv.tv_sec % 60) * 1000 - tv.tv_usec / 1000 + 1;
|
|
||||||
if (config.clock)
|
|
||||||
timeout = 1000 - tv.tv_usec / 1000 + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (timeout == -1)
|
|
||||||
{
|
|
||||||
error = tb_poll_event(&event);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
error = tb_peek_event(&event, timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error < 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.type == TB_EVENT_KEY)
|
|
||||||
{
|
|
||||||
switch (event.key)
|
|
||||||
{
|
|
||||||
case TB_KEY_F1:
|
|
||||||
shutdown = true;
|
|
||||||
run = false;
|
|
||||||
break;
|
|
||||||
case TB_KEY_F2:
|
|
||||||
reboot = true;
|
|
||||||
run = false;
|
|
||||||
break;
|
|
||||||
case TB_KEY_CTRL_C:
|
|
||||||
run = false;
|
|
||||||
break;
|
|
||||||
case TB_KEY_CTRL_U:
|
|
||||||
if (active_input > 0)
|
|
||||||
{
|
|
||||||
input_text_clear(input_structs[active_input]);
|
|
||||||
update = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TB_KEY_CTRL_K:
|
|
||||||
case TB_KEY_ARROW_UP:
|
|
||||||
if (active_input > 0)
|
|
||||||
{
|
|
||||||
--active_input;
|
|
||||||
update = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TB_KEY_CTRL_J:
|
|
||||||
case TB_KEY_ARROW_DOWN:
|
|
||||||
if (active_input < 2)
|
|
||||||
{
|
|
||||||
++active_input;
|
|
||||||
update = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TB_KEY_TAB:
|
|
||||||
++active_input;
|
|
||||||
|
|
||||||
if (active_input > 2)
|
|
||||||
{
|
|
||||||
active_input = SESSION_SWITCH;
|
|
||||||
}
|
|
||||||
update = true;
|
|
||||||
break;
|
|
||||||
case TB_KEY_ENTER:
|
|
||||||
save(&desktop, &login);
|
|
||||||
auth(&desktop, &login, &password, &buf);
|
|
||||||
update = true;
|
|
||||||
|
|
||||||
if (dgn_catch())
|
|
||||||
{
|
|
||||||
++auth_fails;
|
|
||||||
// move focus back to password input
|
|
||||||
active_input = PASSWORD_INPUT;
|
|
||||||
|
|
||||||
if (dgn_output_code() != DGN_PAM)
|
|
||||||
{
|
|
||||||
buf.info_line = dgn_output_log();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.blank_password)
|
|
||||||
{
|
|
||||||
input_text_clear(&password);
|
|
||||||
}
|
|
||||||
|
|
||||||
dgn_reset();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
buf.info_line = lang.logout;
|
|
||||||
}
|
|
||||||
|
|
||||||
load(&desktop, &login);
|
|
||||||
system("tput cnorm");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
(*input_handles[active_input])(
|
|
||||||
input_structs[active_input],
|
|
||||||
&event);
|
|
||||||
update = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// stop termbox
|
|
||||||
tb_shutdown();
|
|
||||||
|
|
||||||
// free inputs
|
|
||||||
input_desktop_free(&desktop);
|
|
||||||
input_text_free(&login);
|
|
||||||
input_text_free(&password);
|
|
||||||
free_hostname();
|
|
||||||
|
|
||||||
// unload config
|
|
||||||
draw_free(&buf);
|
|
||||||
lang_free();
|
|
||||||
|
|
||||||
if (shutdown)
|
|
||||||
{
|
|
||||||
execl("/bin/sh", "sh", "-c", config.shutdown_cmd, NULL);
|
|
||||||
}
|
|
||||||
else if (reboot)
|
|
||||||
{
|
|
||||||
execl("/bin/sh", "sh", "-c", config.restart_cmd, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
config_free();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
12
src/main.zig
12
src/main.zig
|
|
@ -1,5 +1,6 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const c = @cImport({
|
|
||||||
|
pub const c = @cImport({
|
||||||
@cInclude("configator.h");
|
@cInclude("configator.h");
|
||||||
@cInclude("dragonfail.h");
|
@cInclude("dragonfail.h");
|
||||||
@cInclude("termbox.h");
|
@cInclude("termbox.h");
|
||||||
|
|
@ -17,11 +18,12 @@ const MAX_AUTH_FAILS = 10;
|
||||||
|
|
||||||
// Main allocator for Ly
|
// Main allocator for Ly
|
||||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
const allocator = gpa.allocator();
|
|
||||||
|
pub const allocator = gpa.allocator();
|
||||||
|
|
||||||
// Ly general and language configuration
|
// Ly general and language configuration
|
||||||
var config: c.struct_config = undefined;
|
pub var config: c.struct_config = undefined;
|
||||||
var lang: c.struct_lang = undefined;
|
pub var lang: c.struct_lang = undefined;
|
||||||
|
|
||||||
comptime {
|
comptime {
|
||||||
@export(config, .{ .name = "config" });
|
@export(config, .{ .name = "config" });
|
||||||
|
|
@ -314,7 +316,7 @@ pub fn main() !void {
|
||||||
c.load(desktop, username);
|
c.load(desktop, username);
|
||||||
|
|
||||||
// Reset cursor to its normal state
|
// Reset cursor to its normal state
|
||||||
_ = std.ChildProcess.exec(.{ .argv = &[_][]const u8{ "/sbin/tput", "cnorm" }, .allocator = allocator }) catch return;
|
_ = std.ChildProcess.exec(.{ .argv = &[_][]const u8{ "/usr/bin/tput", "cnorm" }, .allocator = allocator }) catch return;
|
||||||
|
|
||||||
update = true;
|
update = true;
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue