tuxpaint-pencil-sharpener/src/parse.gperf
William Kendrick e6365974f6 * --joystick-buttons-ignore option can be used to ignore joystick buttons
(rather than all non-command-assigned buttons being used asi
  left-mouse-click)
 * Updated docs re: joysticks a bit.
2014-03-31 05:54:32 +00:00

279 lines
8.9 KiB
Text

%struct-type
%language=ANSI-C
%7bit
%readonly-tables
%define initializer-suffix ,0
%{
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <stdint.h>
#include "../src/parse.h"
#include "../src/debug.h"
const char PARSE_YES[] = "yes";
const char PARSE_NO[] = "no";
const char PARSE_CLOBBER[] = ":-("; // for painful lang/locale priority situation
struct cfg
{
const char *name;
void (*val)(void);
};
#define MULTIVAL 0x00000000
#define POS 0x00000001
#define NEG 0x00000002
#define BOOLMASK (POS|NEG)
#define BITS 2 // if this grows past 2, must shift the offset
#define FLAGMASK ((1<<BITS)-1)
#define MULTI(x) (void*)(offsetof(struct cfginfo,x)|MULTIVAL)
#define POSBOOL(x) (void*)(offsetof(struct cfginfo,x)|POS)
#define NEGBOOL(x) (void*)(offsetof(struct cfginfo,x)|NEG)
#define IMM(x) imm_##x
static void imm_version(void)
{
show_version(0);
}
static void imm_verbose_version(void)
{
show_version(1);
}
static void imm_usage(void)
{
show_usage(0);
}
static void imm_help(void)
{
show_version(0);
show_usage(0);
}
static void imm_copying(void)
{
show_version(0);
printf("\n"
"This program is free software; you can redistribute it\n"
"and/or modify it under the terms of the GNU General Public\n"
"License as published by the Free Software Foundation;\n"
"either version 2 of the License, or (at your option) any\n"
"later version.\n"
"\n"
"This program is distributed in the hope that it will be\n"
"useful and entertaining, but WITHOUT ANY WARRANTY; without\n"
"even the implied warranty of MERCHANTABILITY or FITNESS\n"
"FOR A PARTICULAR PURPOSE. See the GNU General Public\n"
"License for more details.\n"
"\n"
"You should have received a copy of the GNU General Public\n"
"License along with this program; if not, write to the Free\n"
"Software Foundation, Inc., 59 Temple Place, Suite 330,\n"
"Boston, MA 02111-1307 USA\n" "\n");
}
// We get this from gperf:
//__inline static unsigned int hash (register const char *str, register unsigned int len)
//__inline __attribute__((__gnu_inline__)) const struct cfg *in_word_set (register const char *str, register unsigned int len);
//
// We use sed (see Makefile) to make those functions static.
%}
struct cfg
%%
alllocalefonts, POSBOOL(all_locale_fonts)
allowscreensaver, NEGBOOL(disable_screensaver)
altprint, MULTI(alt_print_command_default)
altprintalways, MULTI(alt_print_command_default)
altprintcommand, MULTI(altprintcommand)
altprintmod, MULTI(alt_print_command_default)
altprintnever, MULTI(alt_print_command_default)
autosave, POSBOOL(autosave_on_quit)
buttondistinction, NEGBOOL(no_button_distinction)
colorfile, MULTI(colorfile)
complexshapes, NEGBOOL(simple_shapes)
copying, IMM(copying)
currentlocalefont, NEGBOOL(all_locale_fonts)
datadir, MULTI(datadir)
disablescreensaver, POSBOOL(disable_screensaver)
dontgrab, NEGBOOL(grab_input)
dontmirrorstamps, NEGBOOL(mirrorstamps)
fancycursors, NEGBOOL(no_fancy_cursors)
fullscreen, MULTI(parsertmp_fullscreen_native)
grab, POSBOOL(grab_input)
help, IMM(help)
hidecursor, POSBOOL(hide_cursor)
keyboard, POSBOOL(keymouse)
label, NEGBOOL(disable_label)
lang, MULTI(parsertmp_lang)
locale, MULTI(parsertmp_locale)
lockfile, POSBOOL(ok_to_use_lockfile)
magiccontrols, NEGBOOL(disable_magic_controls)
mirrorstamps, POSBOOL(mirrorstamps)
mixedcase, NEGBOOL(only_uppercase)
mouse, NEGBOOL(keymouse)
native, POSBOOL(native_screensize)
orient, MULTI(rotate_orientation)
outlines, NEGBOOL(dont_do_xor)
papersize, MULTI(papersize)
print, NEGBOOL(disable_print)
printcfg, POSBOOL(use_print_config)
printcommand, MULTI(printcommand)
printdelay, MULTI(print_delay)
quit, NEGBOOL(disable_quit)
save, NEGBOOL(disable_save)
savedir, MULTI(savedir)
saveover, POSBOOL(_promptless_save_over)
saveoverask, POSBOOL(_promptless_save_over_ask)
saveovernew, POSBOOL(_promptless_save_over_new)
shortcuts, NEGBOOL(noshortcuts)
showcursor, NEGBOOL(hide_cursor)
simpleshapes, POSBOOL(simple_shapes)
sound, POSBOOL(use_sound)
stampcontrols, NEGBOOL(disable_stamp_controls)
stamps, NEGBOOL(dont_load_stamps)
stampsize, MULTI(stamp_size_override)
startblank, POSBOOL(start_blank)
startlast, NEGBOOL(start_blank)
sysconfig, POSBOOL(parsertmp_sysconfig)
sysfonts, NEGBOOL(no_system_fonts)
uppercase, POSBOOL(only_uppercase)
usage, IMM(usage)
verbose-version, IMM(verbose_version)
version, IMM(version)
wheelmouse, POSBOOL(wheely)
windowed, NEGBOOL(fullscreen)
windowsize, MULTI(parsertmp_windowsize)
mouse-accessibility, POSBOOL(mouseaccessibility)
onscreen-keyboard, POSBOOL(onscreen_keyboard)
onscreen-keyboard-layout, MULTI(onscreen_keyboard_layout)
onscreen-keyboard-disable-change, POSBOOL(onscreen_keyboard_disable_change)
joystick-dev, MULTI(joystick_dev)
joystick-slowness, MULTI(joystick_slowness)
joystick-threshold, MULTI(joystick_lowthreshold)
joystick-maxsteps, MULTI(joystick_maxsteps)
joystick-hat-slowness, MULTI(joystick_hat_slowness)
joystick-hat-timeout, MULTI(joystick_hat_timeout)
joystick-btn-escape, MULTI(joystick_button_escape)
joystick-btn-brush, MULTI(joystick_button_selectbrushtool)
joystick-btn-stamp, MULTI(joystick_button_selectstamptool)
joystick-btn-lines, MULTI(joystick_button_selectlinestool)
joystick-btn-shapes, MULTI(joystick_button_selectshapestool)
joystick-btn-text, MULTI(joystick_button_selecttexttool)
joystick-btn-label, MULTI(joystick_button_selectlabeltool)
joystick-btn-magic, MULTI(joystick_button_selectmagictool)
joystick-btn-undo, MULTI(joystick_button_undo)
joystick-btn-redo, MULTI(joystick_button_redo)
joystick-btn-eraser, MULTI(joystick_button_selecterasertool)
joystick-btn-new, MULTI(joystick_button_new)
joystick-btn-open, MULTI(joystick_button_open)
joystick-btn-save, MULTI(joystick_button_save)
joystick-btn-pgsetup, MULTI(joystick_button_pagesetup)
joystick-btn-print, MULTI(joystick_button_print)
joystick-buttons-ignore, MULTI(joystick_buttons_ignore)
%%
void parse_one_option(struct cfginfo *restrict tmpcfg, const char *str, const char *opt, const char *restrict src)
{
int noflag;
uintptr_t uintptr;
unsigned flags;
unsigned offset;
char *dupecheck;
const struct cfg *cfg;
#ifdef DEBUG
printf("parsing %s: <%s> <%s>\n", src, str, opt);
#endif
if(isdigit(*str))
{
if(opt && !strcmp(opt,"no"))
str = "640x480";
opt = str;
str = "windowsize";
}
noflag = 2*(str[0]=='n' && str[1]=='o' && str[2]);
cfg = in_word_set(str+noflag, strlen(str+noflag));
uintptr = cfg ? (uintptr_t)cfg->val : 0;
flags = (uintptr<CFGINFO_MAXOFFSET) ? (uintptr & FLAGMASK) : 0;
if(!cfg || (!(flags & BOOLMASK) && noflag) )
{
if(src)
printf("Unknown option '%s' in config file '%s'\n",str,src);
else
printf("Unknown command line option '--%s'\n",str);
exit(47);
}
if(unlikely(uintptr >= CFGINFO_MAXOFFSET))
{
if(src)
{
// immediate options are only for the command line
printf("Unknown option '%s' in config file '%s'\n",str,src);
exit(49);
}
if(opt)
{
printf("Command line option '--%s' doesn't take a value.\n",str);
exit(50);
}
cfg->val();
exit(0);
}
if(flags & BOOLMASK)
{
int flip = !!noflag ^ !!(flags & NEG);
if(!opt)
opt = flip ? PARSE_NO : PARSE_YES;
else if(!strcmp("yes",opt))
opt = flip ? PARSE_NO : PARSE_YES;
else if(!strcmp("no",opt))
opt = flip ? PARSE_YES : PARSE_NO;
else
{
if(src)
printf("Option '%s' in config file '%s' is yes/no only, but got '%s'\n",str,src,opt);
else
printf("Command line option '--%s' is yes/no only, but got '%s'\n",str,opt);
exit(51);
}
}
else if(!opt || !*opt)
{
if(src)
printf("Option '%s' in config file '%s' needs a value\n",str,src);
else
printf("Command line option '--%s' needs a value\n",str);
exit(52);
}
offset = uintptr &~ FLAGMASK;
memcpy(&dupecheck, offset+(char*)tmpcfg, sizeof(char*));
if(dupecheck)
{
if(src)
printf("Option '%s' in config file '%s' sets '%s' again.\n",str,src,cfg->name);
else
printf("Command line option '--%s' sets '%s' again.\n",str,cfg->name);
exit(53);
}
memcpy(offset+(char*)tmpcfg, &opt, sizeof(char*));
}