2026-01-13 18:01:27 +01:00
|
|
|
#define _POSIX_C_SOURCE 200809L
|
|
|
|
|
|
2026-01-08 14:40:37 +01:00
|
|
|
#include "io_backend.h"
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
2026-01-08 16:15:29 +01:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
// === Static variables
|
2026-01-08 14:40:37 +01:00
|
|
|
|
2026-01-20 22:16:46 +01:00
|
|
|
#include "../utils/args/args.h"
|
2026-01-12 22:27:26 +01:00
|
|
|
|
2026-01-08 14:40:37 +01:00
|
|
|
static struct iob_context context;
|
2026-01-08 16:15:29 +01:00
|
|
|
static FILE *input = NULL;
|
|
|
|
|
static char *stream_buf = NULL;
|
|
|
|
|
static size_t stream_buf_size = 0;
|
|
|
|
|
static enum iob_state state = IOB_STATE_NOT_INITIALIZED;
|
|
|
|
|
|
|
|
|
|
// === Functions
|
2026-01-08 14:40:37 +01:00
|
|
|
|
|
|
|
|
int iob_init(struct iob_context *ctx)
|
|
|
|
|
{
|
2026-01-08 16:15:29 +01:00
|
|
|
if (state != IOB_STATE_NOT_INITIALIZED)
|
2026-01-08 16:59:37 +01:00
|
|
|
return IOB_ERROR_MODULE_ALREADY_INITIALIZED;
|
2026-01-08 16:15:29 +01:00
|
|
|
|
2026-01-08 14:40:37 +01:00
|
|
|
context = *ctx;
|
|
|
|
|
|
|
|
|
|
switch (context.mode)
|
|
|
|
|
{
|
2026-01-08 16:15:29 +01:00
|
|
|
case IOB_MODE_STDIN:
|
2026-01-08 14:40:37 +01:00
|
|
|
input = stdin;
|
2026-01-08 16:15:29 +01:00
|
|
|
state = IOB_STATE_READY;
|
2026-01-08 14:40:37 +01:00
|
|
|
return 0;
|
|
|
|
|
|
2026-01-08 16:15:29 +01:00
|
|
|
case IOB_MODE_SCRIPT:
|
2026-01-08 14:40:37 +01:00
|
|
|
if (context.args == NULL)
|
2026-01-08 16:15:29 +01:00
|
|
|
return IOB_ERROR_BAD_ARG;
|
2026-01-08 14:40:37 +01:00
|
|
|
input = fopen(context.args, "r");
|
|
|
|
|
if (input == NULL)
|
2026-01-08 16:15:29 +01:00
|
|
|
return IOB_ERROR_CANNOT_OPEN_FILE;
|
|
|
|
|
state = IOB_STATE_READY;
|
|
|
|
|
return 0;
|
2026-01-08 14:40:37 +01:00
|
|
|
|
2026-01-08 16:15:29 +01:00
|
|
|
case IOB_MODE_CMD:
|
2026-01-15 18:49:42 +01:00
|
|
|
if (context.args == NULL)
|
2026-01-08 16:15:29 +01:00
|
|
|
return IOB_ERROR_BAD_ARG;
|
|
|
|
|
state = IOB_STATE_READY;
|
|
|
|
|
return 0;
|
2026-01-08 14:40:37 +01:00
|
|
|
|
|
|
|
|
default:
|
2026-01-08 16:15:29 +01:00
|
|
|
return IOB_ERROR_BAD_ARG;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void iob_close(void)
|
|
|
|
|
{
|
|
|
|
|
fclose(input);
|
|
|
|
|
if ((context.mode == IOB_MODE_STDIN || context.mode == IOB_MODE_SCRIPT)
|
|
|
|
|
&& stream_buf != NULL)
|
|
|
|
|
{
|
|
|
|
|
free(stream_buf);
|
|
|
|
|
stream_buf_size = 0;
|
|
|
|
|
}
|
|
|
|
|
state = IOB_STATE_NOT_INITIALIZED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ssize_t stream_read(char **stream)
|
|
|
|
|
{
|
|
|
|
|
// Check args
|
|
|
|
|
if (stream == NULL)
|
|
|
|
|
return IOB_ERROR_BAD_ARG;
|
|
|
|
|
|
|
|
|
|
// Check env
|
|
|
|
|
if (state == IOB_STATE_NOT_INITIALIZED)
|
|
|
|
|
return IOB_ERROR_MODULE_NOT_INITIALIZED;
|
|
|
|
|
if (state == IOB_STATE_FINISHED)
|
|
|
|
|
return 0;
|
|
|
|
|
if (state == IOB_STATE_ERROR)
|
|
|
|
|
return IOB_ERROR_GENERIC;
|
|
|
|
|
|
|
|
|
|
// Use input
|
|
|
|
|
if (context.mode == IOB_MODE_STDIN || context.mode == IOB_MODE_SCRIPT)
|
|
|
|
|
{
|
|
|
|
|
ssize_t nread = getline(&stream_buf, &stream_buf_size, input);
|
|
|
|
|
if (nread == -1)
|
|
|
|
|
{
|
|
|
|
|
state = IOB_STATE_FINISHED;
|
2026-01-22 14:05:49 +01:00
|
|
|
// MAGNIFICO
|
|
|
|
|
// malloc(1);
|
|
|
|
|
*stream_buf = EOF;
|
|
|
|
|
*stream = stream_buf;
|
|
|
|
|
return 1;
|
2026-01-08 16:15:29 +01:00
|
|
|
}
|
|
|
|
|
else if (nread < 0)
|
|
|
|
|
state = IOB_STATE_ERROR;
|
|
|
|
|
|
2026-01-21 18:59:53 +01:00
|
|
|
*stream = stream_buf;
|
2026-01-08 16:15:29 +01:00
|
|
|
return nread;
|
|
|
|
|
}
|
|
|
|
|
// Use args
|
|
|
|
|
else if (context.mode == IOB_MODE_CMD)
|
|
|
|
|
{
|
|
|
|
|
*stream = context.args;
|
2026-01-15 20:42:28 +01:00
|
|
|
size_t len = strlen(context.args);
|
|
|
|
|
context.args[len] = EOF;
|
2026-01-21 20:00:48 +01:00
|
|
|
return len + 1;
|
2026-01-08 16:15:29 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
*stream = NULL;
|
|
|
|
|
return IOB_ERROR_GENERIC;
|
2026-01-08 14:40:37 +01:00
|
|
|
}
|
|
|
|
|
}
|
2026-01-12 22:27:26 +01:00
|
|
|
|
|
|
|
|
int iob_config_from_args(struct args_options *args, struct iob_context *ctx)
|
|
|
|
|
{
|
|
|
|
|
switch (args->type)
|
|
|
|
|
{
|
|
|
|
|
case INPUT_STDIN:
|
|
|
|
|
ctx->mode = IOB_MODE_STDIN;
|
|
|
|
|
ctx->args = NULL;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case INPUT_FILE:
|
|
|
|
|
ctx->mode = IOB_MODE_SCRIPT;
|
|
|
|
|
ctx->args = (char *)args->input_source;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case INPUT_CMD:
|
|
|
|
|
ctx->mode = IOB_MODE_CMD;
|
2026-01-15 18:49:42 +01:00
|
|
|
ctx->args = (char *)args->input_source;
|
2026-01-12 22:27:26 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
2026-01-13 22:24:43 +01:00
|
|
|
return IOB_ERROR_GENERIC;
|
2026-01-12 22:27:26 +01:00
|
|
|
}
|
|
|
|
|
return 0;
|
2026-01-13 22:24:43 +01:00
|
|
|
}
|