#include #include #include #include "config.h" #include "log.h" 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++) (*(p->funcs[i]))(); free(p); } } static void init_defaults(void) { Gconfig.framebuffer_device = "/dev/fb1"; Gconfig.button_debounce = 100; Gconfig.sys_mq_length = 64; } 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(parsed->framebuffer_device); 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) { 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(); 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; }