upiwin/src/config.c

149 lines
3.0 KiB
C
Raw Normal View History

#include <stdio.h>
#include <stdlib.h>
2019-12-06 22:37:20 -07:00
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include "config.h"
#include "scode.h"
#include "log.h"
2019-12-06 22:37:20 -07:00
static const struct option long_options[] = {
{"framebuffer", required_argument, 0, 'F'},
{"help", no_argument, 0, 'h'},
{ NULL, 0, 0, 0 }
};
static const char *short_options = "F:h";
static const char *helptext =
"UPIWIN - Micro Pi Windows server program\n\n"
"Usage: upiwin [options] scriptname [scriptargs]\n\n"
"Available options:\n"
" -F,--framebuffer [devname] - Specifies the framebuffer device name\n"
" -h,--help - Displays this help message.\n"
"";
#define EXITFUNCBLOCK_FUNCCOUNT 64
typedef struct tagEXITFUNCBLOCK
{
struct tagEXITFUNCBLOCK *next;
int num_funcs;
PEXITFUNC funcs[EXITFUNCBLOCK_FUNCCOUNT];
} EXITFUNCBLOCK, *PEXITFUNCBLOCK;
/* The global configuration data */
GLOBAL_CONFIG Gconfig;
static PEXITFUNCBLOCK exitfuncs = NULL;
static void run_exit_funcs(void)
{
int i;
PEXITFUNCBLOCK p;
while (exitfuncs)
{
p = exitfuncs;
exitfuncs = p->next;
for (i = p->num_funcs - 1; i >= 0; i--)
if (p->funcs[i])
(*(p->funcs[i]))();
free(p);
}
}
static void init_defaults(void)
{
Gconfig.framebuffer_device = "/dev/fb1";
Gconfig.button_debounce = 100;
Gconfig.sys_mq_length = 64;
}
2019-12-06 22:37:20 -07:00
static HRESULT parse_cmdline(int argc, char *argv[], GLOBAL_CONFIG *parsed)
{
int c;
PSTR pstr;
BOOL help = FALSE;
memset(parsed, 0, sizeof(GLOBAL_CONFIG));
for (;;)
{
c = getopt_long(argc, argv, short_options, long_options, NULL);
if (c==-1)
break;
switch (c)
{
case 'F':
pstr = strdup(optarg);
if (!pstr)
{
Log(LERROR, "Out of memory in parse_cmdline");
return E_OUTOFMEMORY;
}
if (parsed->framebuffer_device)
free((PVOID)(parsed->framebuffer_device));
2019-12-06 22:37:20 -07:00
parsed->framebuffer_device = pstr;
break;
case 'h':
help = TRUE;
break;
default:
fprintf(stderr, "%s: unexpected option -%c\n", argv[0], c);
return E_UNEXPECTED;
}
}
if (help)
{
fputs(helptext, stdout);
return S_FALSE;
}
return S_OK;
}
static void overlay_config(GLOBAL_CONFIG *p)
{
2019-12-06 22:37:20 -07:00
if (p->framebuffer_device)
Gconfig.framebuffer_device = p->framebuffer_device;
}
HRESULT Config_setup(int argc, char *argv[])
{
HRESULT hr;
GLOBAL_CONFIG from_commandline;
if (atexit(run_exit_funcs))
{
Log(LFATAL, "Unable to set up exit function mechanism");
return E_FAIL;
}
init_defaults();
2019-12-06 22:37:20 -07:00
hr = parse_cmdline(argc, argv, &from_commandline);
if (hr != S_OK)
return hr;
overlay_config(&from_commandline);
return S_OK;
}
HRESULT Config_exitfunc(PEXITFUNC pfn)
{
PEXITFUNCBLOCK p;
if (!exitfuncs || (exitfuncs->num_funcs == EXITFUNCBLOCK_FUNCCOUNT))
{
p = (PEXITFUNCBLOCK)malloc(sizeof(EXITFUNCBLOCK));
if (!p)
{
Log(LERROR, "unable to allocate another exit function block");
return E_OUTOFMEMORY;
}
p->next = exitfuncs;
p->num_funcs = 0;
exitfuncs = p;
}
exitfuncs->funcs[exitfuncs->num_funcs++] = pfn;
return S_OK;
}