=================================================================== ChangeSet@xxx, 2004-08-10 00:52:50-05:00, dtor_core@xxxxxxxxxxxxx Split option parsing (-o text) into separate file suitable for use outside of mice.c. Also implement the following changes in option parsing: - make arguments for string and integer options mandatory; - warn user if option is present twice in the option string; - provide means to check whether an option is present or not. Makefile.in | 4 gpm.c | 53 ----------- headers/gpmInt.h | 3 headers/message.h | 3 headers/optparser.h | 50 +++++++++++ mice.c | 234 +++++++++++++--------------------------------------- optparser.c | 155 ++++++++++++++++++++++++++++++++++ prog/mouse-test.c | 8 - 8 files changed, 276 insertions(+), 234 deletions(-) =================================================================== diff -Nru a/src/Makefile.in b/src/Makefile.in --- a/src/Makefile.in 2004-08-10 01:17:58 -05:00 +++ b/src/Makefile.in 2004-08-10 01:17:58 -05:00 @@ -14,7 +14,7 @@ # Main portion: regular build rules GSRC = main.c gpm.c gpn.c mice.c special.c twiddler.c synaptics.c \ - startup.c server_tools.c console.c client.c + startup.c server_tools.c console.c client.c optparser.c GOBJ = $(GSRC:.c=.o) report.o tools.o @@ -153,7 +153,7 @@ $(CC) -I. @CPPFLAGS@ $(CPPFLAGS) @CFLAGS@ $(CFLAGS) -c -o $@.o $< $(CC) @LDFLAGS@ $(LDFLAGS) -o $@ $@.o @LIBS@ $(LIBS) lib/libgpm.a -prog/mouse-test: mice.o twiddler.o synaptics.o console.o +prog/mouse-test: mice.o twiddler.o synaptics.o console.o optparser.o $(PROG): @SHLIB@ lib/libgpm.a diff -Nru a/src/gpm.c b/src/gpm.c --- a/src/gpm.c 2004-08-10 01:17:58 -05:00 +++ b/src/gpm.c 2004-08-10 01:17:58 -05:00 @@ -86,50 +86,6 @@ int clicks; } state; -/* BRAINDEAD..ok not really, but got to leave anyway... FIXME */ -/* argc and argv for mice initialization */ -static int mouse_argc[3]; /* 0 for default (unused) and two mice */ -static char **mouse_argv[3]; /* 0 for default (unused) and two mice */ - -/*===================================================================*/ -/* - * first, all the stuff that used to be in gpn.c (i.e., not main-loop) - */ -/*-------------------------------------------------------------------*/ - -/* build_argv is used for mouse initialization routines */ -static char **build_argv(char *argv0, char *str, int *argcptr, char sep) -{ - int argc = 1; - char **argv; - char *s; - - /* argv0 is never NULL, but the extra string may well be */ - if (str) - for (s=str; sep && (s = strchr(s, sep)); argc++) s++; - - argv = calloc(argc+2, sizeof(char **)); - if (!argv) gpm_report(GPM_PR_OOPS,GPM_MESS_ALLOC_FAILED); - argv[0] = argv0; - - if (!str) { - *argcptr = argc; /* 1 */ - return argv; - } - /* else, add arguments */ - s = argv[1] = strdup(str); - argc = 2; /* first to fill */ - - /* ok, now split: the first one is in place, and s is the whole string */ - for ( ; sep && (s = strchr(s, sep)) ; argc++) { - *s = '\0'; - s++; - argv[argc] = s; - } - *argcptr = argc; - return argv; -} - /*------------------------------------------------------------------- * fetch the actual device data from the mouse device, dependent on * what Gpm_Type is being passed. @@ -497,13 +453,9 @@ /* and then reset the flag */ fcntl(fd,F_SETFL,fcntl(fd,F_GETFL) & ~O_NDELAY); - /* create argc and argv for this device */ - mouse_argv[i] = build_argv(opt_type, opt_options, &mouse_argc[i], ','); - /* init the device, and use the return value as new mouse type */ if (m_type->init) - m_type=(m_type->init)(fd, m_type->flags, m_type, mouse_argc[i], - mouse_argv[i]); + m_type=(m_type->init)(fd, m_type->flags, m_type); if (!m_type) gpm_report(GPM_PR_OOPS,GPM_MESS_MOUSE_INIT); which_mouse->fd=fd; @@ -581,8 +533,7 @@ if ((mouse_table[i].fd = open(opt_dev, O_RDWR)) < 0) gpm_report(GPM_PR_OOPS, GPM_MESS_OPEN,opt_dev); if (m_type->init) - m_type->init(mouse_table[i].fd, m_type->flags, m_type, - mouse_argc[1], mouse_argv[1]); + m_type->init(mouse_table[i].fd, m_type->flags, m_type); maxfd = max(maxfd, mouse_table[1].fd); readySet = connSet; FD_SET(mouse_table[1].fd, &readySet); diff -Nru a/src/headers/gpmInt.h b/src/headers/gpmInt.h --- a/src/headers/gpmInt.h 2004-08-10 01:17:58 -05:00 +++ b/src/headers/gpmInt.h 2004-08-10 01:17:58 -05:00 @@ -115,8 +115,7 @@ char *desc; /* a descriptive line */ char *synonyms; /* extra names (the XFree name etc) as a list */ int (*fun)(Gpm_Event *state, unsigned char *data); - struct Gpm_Type *(*init)(int fd, unsigned short flags, - struct Gpm_Type *type, int argc, char **argv); + struct Gpm_Type *(*init)(int fd, unsigned short flags, struct Gpm_Type *type); unsigned short flags; unsigned char proto[4]; int packetlen; diff -Nru a/src/headers/message.h b/src/headers/message.h --- a/src/headers/message.h 2004-08-10 01:17:58 -05:00 +++ b/src/headers/message.h 2004-08-10 01:17:58 -05:00 @@ -168,7 +168,8 @@ #define GPM_MESS_SELECT_TIMES "selected %i times" #define GPM_MESS_OPTION_NO_ARG "%s: Option \"%s\" takes no argument: ignoring \"%s\"" -#define GPM_MESS_INVALID_ARG "%s: Invalid arg. \"%s\" to \"%s\"" +#define GPM_MESS_INVALID_ARG "%s: Invalid argument \"%s\" for option \"%s\"" +#define GPM_MESS_MISSING_ARG "%s: Option \"%s\" requires an argument" #define GPM_MESS_CONT_WITH_ERR "%s: Continuing despite errors in option parsing" #define GPM_MESS_TOO_MANY_OPTS "%s: Too many options for \"-t %s\"" diff -Nru a/src/headers/optparser.h b/src/headers/optparser.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/src/headers/optparser.h 2004-08-10 01:17:58 -05:00 @@ -0,0 +1,50 @@ +/* + * optparser.h - GPM mouse options parser + * + * Copyright (C) 1993 Andrew Haylett <ajh@xxxxxxxxxxxxx> + * Copyright (C) 1994-2000 Alessandro Rubini <rubini@xxxxxxxx> + * Copyright (C) 1998,1999 Ian Zimmerman <itz@xxxxxxxxx> + * Copyright (C) 2001,2002 Nico Schottelius <nico-gpm@xxxxxxxxxxxxxxx> + * Copyright (C) 2003 Dmitry Torokhov <dtor@xxxxxxx> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + ********/ +#ifndef __GPM_OPTPARSER_H_ +#define __GPM_OPTPARSER_H_ + +enum option_type { + OPT_BOOL = 1, + OPT_INT, /* "%i" */ + OPT_DEC, /* "%d" */ + OPT_STRING, + /* other types must be added */ + OPT_END = 0 +}; + +struct option_helper { + char *name; + enum option_type type; + union u { + int *iptr; /* used for int and bool arguments */ + char **sptr; /* used for string arguments, by strdup()ing the value */ + } u; + int value; /* used for boolean arguments */ + int present; +}; + +int parse_options(const char *who, const char *opt, char sep, struct option_helper *info); +int check_no_options(const char *proto, const char *opts, char sep); +int is_option_present(struct option_helper *info, const char *name); +#endif diff -Nru a/src/mice.c b/src/mice.c --- a/src/mice.c 2004-08-10 01:17:58 -05:00 +++ b/src/mice.c 2004-08-10 01:17:58 -05:00 @@ -76,132 +76,36 @@ #include "headers/twiddler.h" #include "headers/synaptics.h" #include "headers/message.h" - -/*========================================================================*/ -/* Parsing argv: helper dats struct function (should they get elsewhere?) */ -/*========================================================================*/ - -enum argv_type { - ARGV_BOOL = 1, - ARGV_INT, /* "%i" */ - ARGV_DEC, /* "%d" */ - ARGV_STRING, - /* other types must be added */ - ARGV_END = 0 -}; - -typedef struct argv_helper { - char *name; - enum argv_type type; - union u { - int *iptr; /* used for int and bool arguments */ - char **sptr; /* used for string arguments, by strdup()ing the value */ - } u; - int value; /* used for boolean arguments */ -} argv_helper; - -static int parse_argv(argv_helper *info, int argc, char **argv) -{ - int i, j = 0, errors = 0; - long l; - argv_helper *p; - char *s, *t; - int base = 0; /* for strtol */ - - - for (i=1; i<argc; i++) { - for (p = info; p->type != ARGV_END; p++) { - j = strlen(p->name); - if (strncmp(p->name, argv[i], j)) - continue; - if (isalnum(argv[i][j])) - continue; - break; - } - if (p->type == ARGV_END) { /* not found */ - fprintf(stderr, "%s: Uknown option \"%s\" for pointer \"%s\"\n", - option.progname, argv[i], argv[0]); - errors++; - continue; - } - /* Found. Look for trailing stuff, if any */ - s = argv[i]+j; - while (*s && isspace(*s)) s++; /* skip spaces */ - if (*s == '=') s++; /* skip equal */ - while (*s && isspace(*s)) s++; /* skip other spaces */ - - /* Now parse what s is */ - switch(p->type) { - case ARGV_BOOL: - if (*s) { - gpm_report(GPM_PR_ERR,GPM_MESS_OPTION_NO_ARG,option.progname,p->name,s); - errors++; - } - *(p->u.iptr) = p->value; - break; - - case ARGV_DEC: - base = 10; /* and fall through */ - case ARGV_INT: - l = strtol(s, &t, base); - if (*t) { - gpm_report(GPM_PR_ERR,GPM_MESS_INVALID_ARG, option.progname, s, p->name); - errors++; - break; - } - *(p->u.iptr) = (int)l; - break; - - case ARGV_STRING: - *(p->u.sptr) = strdup(s); - break; - - case ARGV_END: /* let's please "-Wall" */ - break; - } - } /* for i in argc */ - if (errors) gpm_report(GPM_PR_ERR,GPM_MESS_CONT_WITH_ERR, option.progname); - return errors; -} - -/*========================================================================*/ -/* Provide a common error engine by parsing with an empty option-set */ -/*========================================================================*/ -static volatile int check_no_argv(int argc, char **argv) -{ - static argv_helper optioninfo[] = { - {"", ARGV_END} - }; - return parse_argv(optioninfo, argc, argv); -} +#include "headers/optparser.h" /*========================================================================*/ /* Parse the "old" -o options */ /*========================================================================*/ -static int option_modem_lines(int fd, int argc, char **argv) +static int option_modem_lines(int fd, char *proto, char *opts) { - static unsigned int err, lines, reallines; + static unsigned int lines, reallines; + static struct option_helper optioninfo[] = { + {"dtr", OPT_BOOL, u: {iptr: &lines}, value: TIOCM_DTR}, + {"rts", OPT_BOOL, u: {iptr: &lines}, value: TIOCM_RTS}, + {"both", OPT_BOOL, u: {iptr: &lines}, value: TIOCM_DTR | TIOCM_RTS}, + {"", OPT_END} + }; - static argv_helper optioninfo[] = { - {"dtr", ARGV_BOOL, u: {iptr: &lines}, value: TIOCM_DTR}, - {"rts", ARGV_BOOL, u: {iptr: &lines}, value: TIOCM_RTS}, - {"both", ARGV_BOOL, u: {iptr: &lines}, value: TIOCM_DTR | TIOCM_RTS}, - {"", ARGV_END} - }; + int rslt = parse_options(proto, opts, ',', optioninfo); - if (argc<2) return 0; - if (argc > 2) { - gpm_report(GPM_PR_ERR,GPM_MESS_TOO_MANY_OPTS,option.progname, argv[0]); + if (rslt < 0) { + errno = EINVAL; + return -1; + } else if (rslt > 1) { + gpm_report(GPM_PR_ERR, GPM_MESS_TOO_MANY_OPTS, option.progname, proto); errno = EINVAL; /* used by gpm_oops(), if the caller reports failure */ return -1; + } else if (rslt == 1) { + /* ok, move the lines */ + ioctl(fd, TIOCMGET, &reallines); + reallines &= ~lines; + ioctl(fd, TIOCMSET, &reallines); } - err = parse_argv(optioninfo, argc, argv); - if(err) return 0; /* a message has been printed, but go on as good */ - - /* ok, move the lines */ - ioctl(fd, TIOCMGET, &reallines); - reallines &= ~lines; - ioctl(fd, TIOCMSET, &reallines); return 0; } @@ -709,8 +613,7 @@ } /* standard ps2 */ -static Gpm_Type *I_ps2(int fd, unsigned short flags, - struct Gpm_Type *type, int argc, char **argv) +static Gpm_Type *I_ps2(int fd, unsigned short flags, struct Gpm_Type *type) { static unsigned char s[] = { 246, 230, 244, 243, 100, 232, 3, }; write (fd, s, sizeof (s)); @@ -719,13 +622,12 @@ return type; } -static Gpm_Type *I_netmouse(int fd, unsigned short flags, - struct Gpm_Type *type, int argc, char **argv) +static Gpm_Type *I_netmouse(int fd, unsigned short flags, struct Gpm_Type *type) { unsigned char magic[6] = { 0xe8, 0x03, 0xe6, 0xe6, 0xe6, 0xe9 }; int i; - if (check_no_argv(argc, argv)) return NULL; + if (!check_no_options(type->name, opt_options, ',')) return NULL; for (i=0; i<6; i++) { unsigned char c = 0; write( fd, magic+i, 1 ); @@ -1478,11 +1380,9 @@ /*========================================================================*/ /* Then, mice should be initialized */ -static Gpm_Type* I_empty(int fd, unsigned short flags, - struct Gpm_Type *type, int argc, char **argv) +static Gpm_Type* I_empty(int fd, unsigned short flags, struct Gpm_Type *type) { - if (check_no_argv(argc, argv)) return NULL; - return type; + return check_no_options(type->name, opt_options, ',') ? type : NULL; } static int setspeed(int fd,int old,int new,int needtowrite,unsigned short flags) @@ -1539,14 +1439,13 @@ {125,"Q"}, {1E9,"N"}, }; -static Gpm_Type* I_serial(int fd, unsigned short flags, - struct Gpm_Type *type, int argc, char **argv) +static Gpm_Type* I_serial(int fd, unsigned short flags, struct Gpm_Type *type) { int i; unsigned char c; fd_set set; struct timeval timeout={0,0}; /* used when not debugging */ /* accept "-o dtr", "-o rts" and "-o both" */ - if (option_modem_lines(fd, argc, argv)) return NULL; + if (option_modem_lines(fd, type->name, opt_options)) return NULL; #ifndef DEBUG /* flush any pending input (thanks, Miguel) */ @@ -1615,14 +1514,13 @@ return type; } -static Gpm_Type* I_logi(int fd, unsigned short flags, - struct Gpm_Type *type, int argc, char **argv) +static Gpm_Type* I_logi(int fd, unsigned short flags, struct Gpm_Type *type) { int i; struct stat buf; int busmouse; - if (check_no_argv(argc, argv)) return NULL; + if (!check_no_options(type->name, opt_options, ',')) return NULL; /* is this a serial- or a bus- mouse? */ if(fstat(fd,&buf)==-1) gpm_report(GPM_PR_OOPS,GPM_MESS_FSTAT); @@ -1651,8 +1549,7 @@ return type; } -static Gpm_Type *I_wacom(int fd, unsigned short flags, - struct Gpm_Type *type, int argc, char **argv) +static Gpm_Type *I_wacom(int fd, unsigned short flags, struct Gpm_Type *type) { /* wacom graphire tablet */ #define UD_RESETBAUD "\r$" /* reset baud rate to default (wacom V) */ @@ -1731,12 +1628,13 @@ */ /* accept boolean options absolute and relative */ - static argv_helper optioninfo[] = { - {"absolute", ARGV_BOOL, u: {iptr: &WacomAbsoluteWanted}, value: !0}, - {"relative", ARGV_BOOL, u: {iptr: &WacomAbsoluteWanted}, value: 0}, - {"", ARGV_END} + static struct option_helper optioninfo[] = { + {"absolute", OPT_BOOL, u: {iptr: &WacomAbsoluteWanted}, value: !0}, + {"relative", OPT_BOOL, u: {iptr: &WacomAbsoluteWanted}, value: 0}, + {"", OPT_END} }; - parse_argv(optioninfo, argc, argv); + + parse_options(type->name, opt_options, ',', optioninfo); type->absolute = WacomAbsoluteWanted; reset_wacom(); @@ -1775,13 +1673,12 @@ return type; } -static Gpm_Type *I_pnp(int fd, unsigned short flags, - struct Gpm_Type *type, int argc, char **argv) +static Gpm_Type *I_pnp(int fd, unsigned short flags, struct Gpm_Type *type) { struct termios tty; /* accept "-o dtr", "-o rts" and "-o both" */ - if (option_modem_lines(fd, argc, argv)) return NULL; + if (option_modem_lines(fd, type->name, opt_options)) return NULL; /* * Just put the device to 1200 baud. Thanks to Francois Chastrette @@ -1851,8 +1748,7 @@ /* intellimouse, ps2 version: Ben Pfaff and Colin Plumb */ /* Autodetect: Steve Bennett */ -static Gpm_Type *I_imps2(int fd, unsigned short flags, struct Gpm_Type *type, - int argc, char **argv) +static Gpm_Type *I_imps2(int fd, unsigned short flags, struct Gpm_Type *type) { int id; static unsigned char basic_init[] = { GPM_AUX_ENABLE_DEV, GPM_AUX_SET_SAMPLE, 100 }; @@ -1907,12 +1803,11 @@ * This works with Dexxa Optical Mouse, but because in X same initstring * is named ExplorerPS/2 so I named it in the same way. */ -static Gpm_Type *I_exps2(int fd, unsigned short flags, - struct Gpm_Type *type, int argc, char **argv) +static Gpm_Type *I_exps2(int fd, unsigned short flags, struct Gpm_Type *type) { static unsigned char s1[] = { 243, 200, 243, 200, 243, 80, }; - if (check_no_argv(argc, argv)) return NULL; + if (!check_no_options(type->name, opt_options, ',')) return NULL; write (fd, s1, sizeof (s1)); usleep (30000); @@ -1920,42 +1815,38 @@ return type; } -static Gpm_Type *I_twid(int fd, unsigned short flags, - struct Gpm_Type *type, int argc, char **argv) +static Gpm_Type *I_twid(int fd, unsigned short flags, struct Gpm_Type *type) { - if (check_no_argv(argc, argv)) return NULL; + if (!check_no_options(type->name, opt_options, ',')) return NULL; if (twiddler_key_init() != 0) return NULL; /* * the twiddler is a serial mouse: just drop dtr * and run at 2400 (unless specified differently) */ - if(opt_baud==DEF_BAUD) opt_baud = 2400; - argv[1] = "dtr"; /* argv[1] is guaranteed to be NULL (this is dirty) */ - return I_serial(fd, flags, type, argc, argv); + if (opt_baud == DEF_BAUD) opt_baud = 2400; + opt_options = "dtr"; + return I_serial(fd, flags, type); } -static Gpm_Type *I_calus(int fd, unsigned short flags, - struct Gpm_Type *type, int argc, char **argv) +static Gpm_Type *I_calus(int fd, unsigned short flags, struct Gpm_Type *type) { - if (check_no_argv(argc, argv)) return NULL; + if (!check_no_options(type->name, opt_options, ',')) return NULL; - if (opt_baud == 1200) opt_baud=9600; /* default to 9600 */ - return I_serial(fd, flags, type, argc, argv); + if (opt_baud == 1200) opt_baud = 9600; /* default to 9600 */ + return I_serial(fd, flags, type); } /* synaptics touchpad, ps2 version: Henry Davies */ -static Gpm_Type *I_synps2(int fd, unsigned short flags, - struct Gpm_Type *type, int argc, char **argv) +static Gpm_Type *I_synps2(int fd, unsigned short flags, struct Gpm_Type *type) { syn_ps2_init (fd); return type; } -static Gpm_Type *I_summa(int fd, unsigned short flags, - struct Gpm_Type *type, int argc, char **argv) +static Gpm_Type *I_summa(int fd, unsigned short flags, struct Gpm_Type *type) { void resetsumma() { @@ -2044,8 +1935,7 @@ return type; } -static Gpm_Type *I_mtouch(int fd, unsigned short flags, - struct Gpm_Type *type, int argc, char **argv) +static Gpm_Type *I_mtouch(int fd, unsigned short flags, struct Gpm_Type *type) { struct termios tty; @@ -2068,8 +1958,7 @@ } /* simple initialization for the gunze touchscreen */ -static Gpm_Type *I_gunze(int fd, unsigned short flags, - struct Gpm_Type *type, int argc, char **argv) +static Gpm_Type *I_gunze(int fd, unsigned short flags, struct Gpm_Type *type) { struct termios tty; FILE *f; @@ -2078,18 +1967,18 @@ #define GUNZE_CALIBRATION_FILE SYSCONFDIR "/gpm-calibration" /* accept a few options */ - static argv_helper optioninfo[] = { - {"smooth", ARGV_INT, u: {iptr: &gunze_avg}}, - {"debounce", ARGV_INT, u: {iptr: &gunze_debounce}}, + static struct option_helper optioninfo[] = { + {"smooth", OPT_INT, u: {iptr: &gunze_avg}}, + {"debounce", OPT_INT, u: {iptr: &gunze_debounce}}, /* FIXME: add corner tapping */ - {"", ARGV_END} + {"", OPT_END} }; - parse_argv(optioninfo, argc, argv); + parse_options(type->name, opt_options, ',', optioninfo); /* check that the baud rate is valid */ if (opt_baud == DEF_BAUD) opt_baud = 19200; /* force 19200 as default */ if (opt_baud != 9600 && opt_baud != 19200) { - gpm_report(GPM_PR_ERR,GPM_MESS_GUNZE_WRONG_BAUD,option.progname, argv[0]); + gpm_report(GPM_PR_ERR, GPM_MESS_GUNZE_WRONG_BAUD, option.progname, type->name); opt_baud = 19200; } tcgetattr(fd, &tty); @@ -2127,8 +2016,7 @@ } /* Genius Wizardpad tablet -- Matt Kimball (mkimball@xxxxxxxxxxxx) */ -static Gpm_Type *I_wp(int fd, unsigned short flags, - struct Gpm_Type *type, int argc, char **argv) +static Gpm_Type *I_wp(int fd, unsigned short flags, struct Gpm_Type *type) { struct termios tty; char tablet_info[256]; diff -Nru a/src/optparser.c b/src/optparser.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/src/optparser.c 2004-08-10 01:17:58 -05:00 @@ -0,0 +1,155 @@ +/* + * optparser.c - GPM mouse options parser + * + * Copyright (C) 1993 Andrew Haylett <ajh@xxxxxxxxxxxxx> + * Copyright (C) 1994-2000 Alessandro Rubini <rubini@xxxxxxxx> + * Copyright (C) 1998,1999 Ian Zimmerman <itz@xxxxxxxxx> + * Copyright (C) 2001,2002 Nico Schottelius <nico-gpm@xxxxxxxxxxxxxxx> + * Copyright (C) 2003 Dmitry Torokhov <dtor@xxxxxxx> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + ********/ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <ctype.h> + +#include "headers/gpmInt.h" +#include "headers/message.h" +#include "headers/optparser.h" + +int parse_options(const char *proto, const char *opts, char sep, struct option_helper *info) +{ + int len, n, n_opts = 0, errors = 0; + long l; + struct option_helper *p; + char *s, *t, *str; + int base; /* for strtol */ + + for (p = info; p->type != OPT_END; p++) + p->present = 0; + + if (!opts) + return 0; + + if (!(str = strdup(opts))) + gpm_report(GPM_PR_OOPS, GPM_MESS_ALLOC_FAILED); + + /* split input string */ + for (s = str, n = 1; sep && (s = strchr(s, sep)); s++, n++) + *s = '\0'; + + for (s = str; n; s += strlen(s) + 1, n--) { + if (strlen(s) == 0) + continue; + + for (p = info; p->type != OPT_END; p++) { + len = strlen(p->name); + if (!strncmp(p->name, s, len) && !isalnum(s[len])) + break; + } + if (p->type == OPT_END) { /* not found */ + gpm_report(GPM_PR_ERR, "%s: Uknown option \"%s\" for protocol \"%s\"\n", + option.progname, s, proto); + errors++; + continue; + } + if (p->present) { + gpm_report(GPM_PR_ERR, "%s: option \"%s\" has already been seen, ignored (\"%s\")\n", + option.progname, s, proto); + continue; + } + p->present = 1; + n_opts++; + /* Found. Look for trailing stuff, if any */ + s += strlen(p->name); + while (*s && isspace(*s)) s++; /* skip spaces */ + if (*s == '=') s++; /* skip equal */ + while (*s && isspace(*s)) s++; /* skip other spaces */ + + /* Now parse what s is */ + base = 0; + switch(p->type) { + case OPT_BOOL: + if (*s) { + gpm_report(GPM_PR_ERR, GPM_MESS_OPTION_NO_ARG, option.progname, p->name, s); + errors++; + } + *(p->u.iptr) = p->value; + break; + + case OPT_DEC: + base = 10; /* and fall through */ + + case OPT_INT: + if (*s == '\0') { + gpm_report(GPM_PR_ERR, GPM_MESS_MISSING_ARG, option.progname, p->name); + } else { + l = strtol(s, &t, base); + if (*t) { + gpm_report(GPM_PR_ERR, GPM_MESS_INVALID_ARG, option.progname, s, p->name); + errors++; + break; + } + *(p->u.iptr) = (int)l; + } + break; + + case OPT_STRING: + if (*s == '\0') + gpm_report(GPM_PR_ERR, GPM_MESS_MISSING_ARG, option.progname, p->name); + else + *(p->u.sptr) = strdup(s); + break; + + case OPT_END: /* let's please "-Wall" */ + break; + } + } + + free(str); + + if (errors) { + gpm_report(GPM_PR_ERR,GPM_MESS_CONT_WITH_ERR, option.progname); + return -errors; + } + return n_opts; +} + +int check_no_options(const char *proto, const char *opts, char sep) +{ + static struct option_helper info[] = { + { "", OPT_END } + }; + + return parse_options(proto, opts, sep, info) == 0; +} + +int is_option_present(struct option_helper *info, const char *name) +{ + struct option_helper *p; + int len; + + for (p = info; p->type != OPT_END; p++) { + len = strlen(p->name); + if (!strncmp(p->name, name, len) && !isalnum(name[len])) + return p->present; + } + + gpm_report(GPM_PR_ERR, "%s: Uknown option \"%s\"\n", option.progname, name); + return 0; +} + diff -Nru a/src/prog/mouse-test.c b/src/prog/mouse-test.c --- a/src/prog/mouse-test.c 2004-08-10 01:17:58 -05:00 +++ b/src/prog/mouse-test.c 2004-08-10 01:17:58 -05:00 @@ -172,8 +172,7 @@ return &((*current)->next); } -Gpm_Type *(*I_serial)(int fd, unsigned short flags, struct Gpm_Type *type, - int argc, char **argv); +Gpm_Type *(*I_serial)(int fd, unsigned short flags, struct Gpm_Type *type); /*----------------------------------------------------------------------------- @@ -187,7 +186,7 @@ usleep(100000); fd=open(name,O_RDWR); if (fd < 0) gpm_report(GPM_PR_OOPS,name); - (*I_serial)(fd,type->flags,type,1,&type->name); /* ms initialization */ + (*I_serial)(fd,type->flags,type); /* ms initialization */ return fd; } @@ -356,8 +355,7 @@ printf("\t%s\r\n", (*nextdev)->name); FD_SET((*nextdev)->fd,&devSet); maxfd=max((*nextdev)->fd,maxfd); - (*I_serial)((*nextdev)->fd,(mice+1)->flags,mice+1, - 1, &(mice+1)->name); /* try ms mode */ + (*I_serial)((*nextdev)->fd,(mice+1)->flags,mice+1); /* try ms mode */ } savSet=devSet; _______________________________________________ gpm mailing list gpm@xxxxxxxxxxxxxx http://lists.linux.it/listinfo/gpm