Remove unused dependencies

This commit is contained in:
AnErrupTion 2023-06-17 17:12:38 +02:00
parent 85600ee9b3
commit 13c9aa7c1b
19 changed files with 7 additions and 1393 deletions

View File

@ -1,2 +0,0 @@
bin
obj

View File

@ -1,2 +0,0 @@
obj
bin

View File

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

View File

@ -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?!)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,6 @@
const std = @import("std");
const c = @cImport({
pub const c = @cImport({
@cInclude("configator.h");
@cInclude("dragonfail.h");
@cInclude("termbox.h");
@ -17,11 +18,12 @@ const MAX_AUTH_FAILS = 10;
// Main allocator for Ly
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator();
pub const allocator = gpa.allocator();
// Ly general and language configuration
var config: c.struct_config = undefined;
var lang: c.struct_lang = undefined;
pub var config: c.struct_config = undefined;
pub var lang: c.struct_lang = undefined;
comptime {
@export(config, .{ .name = "config" });
@ -314,7 +316,7 @@ pub fn main() !void {
c.load(desktop, username);
// 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;
},