From 8149aae9e3468b13452b8f45440e6704a8ad5807 Mon Sep 17 00:00:00 2001 From: Alexey Gladkov Date: Wed, 5 Sep 2012 17:53:51 +0400 Subject: [PATCH] Split loadkeys utility and parser Signed-off-by: Alexey Gladkov --- .gitignore | 4 +- src/Makefile.am | 4 +- src/loadkeys.analyze.l | 9 +- src/loadkeys.c | 258 +++++++++++++++++++++++++++++++++++ src/loadkeys.keymap.h | 18 +++ src/{loadkeys.y => loadkeys.parse.y} | 258 +++-------------------------------- 6 files changed, 301 insertions(+), 250 deletions(-) create mode 100644 src/loadkeys.c rename src/{loadkeys.y => loadkeys.parse.y} (82%) diff --git a/.gitignore b/.gitignore index 5912b74..e9fc35f 100644 --- a/.gitignore +++ b/.gitignore @@ -51,5 +51,5 @@ src/spawn_console src/spawn_login src/loadkeys.analyze.c src/loadkeys.analyze.h -src/loadkeys.c -src/loadkeys.h +src/loadkeys.parse.c +src/loadkeys.parse.h diff --git a/src/Makefile.am b/src/Makefile.am index 629f2f7..bf2053d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -87,8 +87,8 @@ mapscrn_CFLAGS = -DMAIN loadunimap_CFLAGS = -DMAIN AM_LFLAGS = --header-file=$(CURDIR)/loadkeys.analyze.h -BUILT_SOURCES = loadkeys.c loadkeys.analyze.c loadkeys.h loadkeys.analyze.h -loadkeys_SOURCES = loadkeys.y loadkeys.analyze.l $(KSYMS_S) +BUILT_SOURCES = loadkeys.parse.c loadkeys.analyze.c loadkeys.parse.h loadkeys.analyze.h +loadkeys_SOURCES = loadkeys.c loadkeys.parse.y loadkeys.analyze.l $(KSYMS_S) install-exec-hook: for i in psfaddtable psfgettable psfstriptable; do \ diff --git a/src/loadkeys.analyze.l b/src/loadkeys.analyze.l index 9acd91f..3356ae1 100644 --- a/src/loadkeys.analyze.l +++ b/src/loadkeys.analyze.l @@ -8,7 +8,7 @@ #include "paths.h" #include "findfile.h" -#include "loadkeys.h" +#include "loadkeys.parse.h" #include "loadkeys.keymap.h" %} @@ -24,11 +24,8 @@ %option extra-type="struct keymap *" %{ -int stack_push(struct keymap *kmap, lkfile_t *fp, yyscan_t scanner); -int stack_pop(struct keymap *kmap, yyscan_t scanner); - int -stack_push(struct keymap *kmap, lkfile_t *fp, yyscan_t scanner) +stack_push(struct keymap *kmap, lkfile_t *fp, void *scanner) { int i = 0; @@ -55,7 +52,7 @@ stack_push(struct keymap *kmap, lkfile_t *fp, yyscan_t scanner) } int -stack_pop(struct keymap *kmap, yyscan_t scanner) +stack_pop(struct keymap *kmap, void *scanner) { int i = 0; diff --git a/src/loadkeys.c b/src/loadkeys.c new file mode 100644 index 0000000..e253a8b --- /dev/null +++ b/src/loadkeys.c @@ -0,0 +1,258 @@ +/* loadkeys.c + * + * This file is part of kbd project. + * Copyright (C) 1993 Risto Kankkunen. + * Copyright (C) 1993 Eugene G. Crosser. + * Copyright (C) 1994-2007 Andries E. Brouwer. + * Copyright (C) 2007-2012 Alexey Gladkov + * + * This file is covered by the GNU General Public License, + * which should be included with kbd as the file COPYING. + */ + +#include +#include +#include +#include +#include +#include + +#include "../config.h" +#include "nls.h" +#include "kbd.h" +#include "paths.h" +#include "getfd.h" +#include "findfile.h" + +#include "loadkeys.keymap.h" + +const char *progname; + +char **dirpath; +char *dirpath1[] = { "", DATADIR "/" KEYMAPDIR "/**", KERNDIR "/", 0 }; +char *dirpath2[] = { 0, 0 }; +char *suffixes[] = { "", ".kmap", ".map", 0 }; + +static void attr_noreturn +usage(void) +{ + fprintf(stderr, _("loadkeys version %s\n" + "\n" + "Usage: %s [option...] [mapfile...]\n" + "\n" + "Valid options are:\n" + "\n" + " -a --ascii force conversion to ASCII\n" + " -b --bkeymap output a binary keymap to stdout\n" + " -c --clearcompose clear kernel compose table\n" + " -C --console=file\n" + " the console device to be used\n" + " -d --default load \"%s\"\n" + " -h --help display this help text\n" + " -m --mktable output a \"defkeymap.c\" to stdout\n" + " -q --quiet suppress all normal output\n" + " -s --clearstrings clear kernel string table\n" + " -u --unicode force conversion to Unicode\n" + " -v --verbose report the changes\n"), + PACKAGE_VERSION, progname, DEFMAP); + exit(EXIT_FAILURE); +} + +static inline const char * +set_progname(const char *name) +{ + char *p; + p = strrchr(name, '/'); + return (p && p + 1 ? p + 1 : name); +} + +int +main(int argc, char *argv[]) +{ + const char *short_opts = "abcC:dhmsuqvV"; + const struct option long_opts[] = { + { "console", required_argument, NULL, 'C'}, + { "ascii", no_argument, NULL, 'a' }, + { "bkeymap", no_argument, NULL, 'b' }, + { "clearcompose", no_argument, NULL, 'c' }, + { "default", no_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, + { "mktable", no_argument, NULL, 'm' }, + { "clearstrings", no_argument, NULL, 's' }, + { "unicode", no_argument, NULL, 'u' }, + { "quiet", no_argument, NULL, 'q' }, + { "verbose", no_argument, NULL, 'v' }, + { "version", no_argument, NULL, 'V' }, + { NULL, 0, NULL, 0 } + }; + + enum options { + OPT_A = (1 << 1), + OPT_B = (1 << 2), + OPT_D = (1 << 3), + OPT_M = (1 << 4), + OPT_U = (1 << 5) + }; + int options = 0; + + struct keymap kmap; + + int c, i, rc = -1; + int fd; + int kbd_mode; + int kd_mode; + char *console = NULL; + char *ev; + lkfile_t f; + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE_NAME, LOCALEDIR); + textdomain(PACKAGE_NAME); + + progname = set_progname(argv[0]); + + keymap_init(&kmap); + + while ((c = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) { + switch (c) { + case 'a': + options |= OPT_A; + break; + case 'b': + options |= OPT_B; + break; + case 'c': + kmap.flags |= LKFLAG_CLEAR_COMPOSE; + break; + case 'C': + console = optarg; + break; + case 'd': + options |= OPT_D; + break; + case 'm': + options |= OPT_M; + break; + case 's': + kmap.flags |= LKFLAG_CLEAR_STRINGS; + break; + case 'u': + options |= OPT_U; + kmap.flags |= LKFLAG_UNICODE_MODE; + kmap.prefer_unicode = 1; + break; + case 'q': + kmap.verbose = LOG_QUIET; + break; + case 'v': + if (kmap.verbose < LOG_MAXVALUE) + kmap.verbose++; + break; + case 'V': + fprintf(stdout, _("%s from %s\n"), progname, PACKAGE_STRING); + exit(0); + case 'h': + case '?': + usage(); + } + } + + if ((options & OPT_U) && (options & OPT_A)) { + fprintf(stderr, + _("%s: Options --unicode and --ascii are mutually exclusive\n"), + progname); + exit(EXIT_FAILURE); + } + + /* get console */ + fd = getfd(console); + + if (!(options & OPT_M) && !(options & OPT_B)) { + /* check whether the keyboard is in Unicode mode */ + if (ioctl(fd, KDGKBMODE, &kbd_mode) || + ioctl(fd, KDGETMODE, &kd_mode)) { + fprintf(stderr, _("%s: error reading keyboard mode: %m\n"), + progname); + exit(EXIT_FAILURE); + } + + if (kbd_mode == K_UNICODE) { + if (options & OPT_A) { + fprintf(stderr, + _("%s: warning: loading non-Unicode keymap on Unicode console\n" + " (perhaps you want to do `kbd_mode -a'?)\n"), + progname); + } else { + kmap.prefer_unicode = 1; + } + + /* reset -u option if keyboard is in K_UNICODE anyway */ + kmap.flags ^= LKFLAG_UNICODE_MODE; + + } else if (options & OPT_U && kd_mode != KD_GRAPHICS) { + fprintf(stderr, + _("%s: warning: loading Unicode keymap on non-Unicode console\n" + " (perhaps you want to do `kbd_mode -u'?)\n"), + progname); + } + } + + dirpath = dirpath1; + if ((ev = getenv("LOADKEYS_KEYMAP_PATH")) != NULL) { + dirpath2[0] = ev; + dirpath = dirpath2; + } + + if (options & OPT_D) { + /* first read default map - search starts in . */ + + if (findfile(DEFMAP, dirpath, suffixes, &f)) { + fprintf(stderr, _("Cannot find %s\n"), DEFMAP); + exit(EXIT_FAILURE); + } + + if ((rc = parse_keymap(&kmap, &f)) == -1) + goto fail; + + + } else if (optind == argc) { + f.fd = stdin; + strcpy(f.pathname, ""); + + if ((rc = parse_keymap(&kmap, &f)) == -1) + goto fail; + } + + for (i = optind; argv[i]; i++) { + if (!strcmp(argv[i], "-")) { + f.fd = stdin; + strcpy(f.pathname, ""); + + } else if (findfile(argv[i], dirpath, suffixes, &f)) { + fprintf(stderr, _("cannot open file %s\n"), argv[i]); + goto fail; + } + + if ((rc = parse_keymap(&kmap, &f)) == -1) + goto fail; + } + + if ((rc = do_constant(&kmap)) == -1) + goto fail; + + if (options & OPT_B) { + rc = bkeymap(&kmap); + } else if (options & OPT_M) { + rc = mktable(&kmap, stdout); + } else { + rc = loadkeys(&kmap, fd, kbd_mode); + } + + fail: keymap_free(&kmap); + close(fd); + + if (rc < 0) + exit(EXIT_FAILURE); + + exit(EXIT_SUCCESS); +} diff --git a/src/loadkeys.keymap.h b/src/loadkeys.keymap.h index 574af17..0aaead4 100644 --- a/src/loadkeys.keymap.h +++ b/src/loadkeys.keymap.h @@ -87,4 +87,22 @@ struct strdata { unsigned char data[MAX_PARSER_STRING]; }; +#include + +/* Public */ +int keymap_init(struct keymap *km); +void keymap_free(struct keymap *kmap); +int parse_keymap(struct keymap *kmap, lkfile_t *f); + +int do_constant(struct keymap *kmap); + +int loadkeys(struct keymap *kmap, int fd, int kbd_mode); +int bkeymap(struct keymap *kmap); +int mktable(struct keymap *kmap, FILE *fd); + +/* Private */ +int stack_push(struct keymap *kmap, lkfile_t *fp, void *scanner); +int stack_pop(struct keymap *kmap, void *scanner); + + #endif /* LK_KEYMAP_H */ diff --git a/src/loadkeys.y b/src/loadkeys.parse.y similarity index 82% rename from src/loadkeys.y rename to src/loadkeys.parse.y index 49b1ce5..0a75fd9 100644 --- a/src/loadkeys.y +++ b/src/loadkeys.parse.y @@ -1,38 +1,38 @@ -/* - * loadkeys.y +/* loadkeys.parse.y + * + * This file is part of kbd project. + * Copyright (C) 1993 Risto Kankkunen. + * Copyright (C) 1993 Eugene G. Crosser. + * Copyright (C) 1994-2007 Andries E. Brouwer. + * Copyright (C) 2007-2012 Alexey Gladkov * - * For history, see older versions. + * This file is covered by the GNU General Public License, + * which should be included with kbd as the file COPYING. */ %{ #define YY_HEADER_EXPORT_START_CONDITIONS 1 #include #include -#include #include #include -#include -#include #include -#include #include #include #include #include #include "paths.h" -#include "getfd.h" -#include "findfile.h" #include "ksyms.h" #include "modifiers.h" #include "nls.h" -#include "version.h" +#include "kbd.h" #ifdef COMPAT_HEADERS #include "compat/linux-keyboard.h" #endif -#include "loadkeys.h" +#include "loadkeys.parse.h" #include "loadkeys.analyze.h" %} @@ -79,42 +79,8 @@ int yyerror(yyscan_t scanner, struct keymap *kmap, const char *s); -int keymap_init(struct keymap *km); - -extern int stack_push(struct keymap *kmap, lkfile_t *fp, yyscan_t scanner); -extern int stack_pop(struct keymap *kmap, yyscan_t scanner); - #include "ksyms.h" -static void attr_noreturn usage(void) -{ - fprintf(stderr, _("loadkeys version %s\n" - "\n" - "Usage: loadkeys [option...] [mapfile...]\n" - "\n" - "Valid options are:\n" - "\n" - " -a --ascii force conversion to ASCII\n" - " -b --bkeymap output a binary keymap to stdout\n" - " -c --clearcompose clear kernel compose table\n" - " -C --console=file\n" - " the console device to be used\n" - " -d --default load \"%s\"\n" - " -h --help display this help text\n" - " -m --mktable output a \"defkeymap.c\" to stdout\n" - " -q --quiet suppress all normal output\n" - " -s --clearstrings clear kernel string table\n" - " -u --unicode force conversion to Unicode\n" - " -v --verbose report the changes\n"), - PACKAGE_VERSION, DEFMAP); - exit(EXIT_FAILURE); -} - -char **dirpath; -char *dirpath1[] = { "", DATADIR "/" KEYMAPDIR "/**", KERNDIR "/", 0 }; -char *dirpath2[] = { 0, 0 }; -char *suffixes[] = { "", ".kmap", ".map", 0 }; - static void __attribute__ ((format (printf, 4, 5))) lkmessage(const char *file, int line, const char *fn, const char *fmt, ...) { @@ -420,7 +386,8 @@ static int defkeys(struct keymap *kmap, int fd, int kbd_mode) fail: return -1; } -static void freekeys(struct keymap *kmap) +void +keymap_free(struct keymap *kmap) { int i; for (i = 0; i < MAX_NR_KEYMAPS; i++) { @@ -599,7 +566,7 @@ do_constant_key(struct keymap *kmap, int i, u_short key) return 0; } -static int +int do_constant(struct keymap *kmap) { int i, r0 = 0; @@ -626,7 +593,7 @@ do_constant(struct keymap *kmap) return 0; } -static int +int loadkeys(struct keymap *kmap, int fd, int kbd_mode) { int keyct, funcct, diacct; @@ -779,7 +746,7 @@ outchar(FILE *fd, unsigned char c, int comma) fprintf(fd, comma ? "', " : "'"); } -static int +int mktable(struct keymap *kmap, FILE *fd) { int j; @@ -906,7 +873,7 @@ mktable(struct keymap *kmap, FILE *fd) return 0; } -static int +int bkeymap(struct keymap *kmap) { int i, j; @@ -1146,7 +1113,7 @@ rvalue : NUMBER { $$ = convert_code(kmap->prefer_unicode, $1, TO_AUTO); } ; %% -static int +int parse_keymap(struct keymap *kmap, lkfile_t *f) { yyscan_t scanner; @@ -1170,192 +1137,3 @@ parse_keymap(struct keymap *kmap, lkfile_t *f) fail: yylex_destroy(scanner); return rc; } - -int main(int argc, char *argv[]) -{ - const char *short_opts = "abcC:dhmsuqvV"; - const struct option long_opts[] = { - { "console", required_argument, NULL, 'C'}, - { "ascii", no_argument, NULL, 'a' }, - { "bkeymap", no_argument, NULL, 'b' }, - { "clearcompose", no_argument, NULL, 'c' }, - { "default", no_argument, NULL, 'd' }, - { "help", no_argument, NULL, 'h' }, - { "mktable", no_argument, NULL, 'm' }, - { "clearstrings", no_argument, NULL, 's' }, - { "unicode", no_argument, NULL, 'u' }, - { "quiet", no_argument, NULL, 'q' }, - { "verbose", no_argument, NULL, 'v' }, - { "version", no_argument, NULL, 'V' }, - { NULL, 0, NULL, 0 } - }; - - enum options { - OPT_A = (1 << 1), - OPT_B = (1 << 2), - OPT_D = (1 << 3), - OPT_M = (1 << 4), - OPT_U = (1 << 5) - }; - int options = 0; - - struct keymap kmap; - - int c, i, rc = -1; - int fd; - int kbd_mode; - int kd_mode; - char *console = NULL; - char *ev; - lkfile_t f; - - set_progname(argv[0]); - - setlocale(LC_ALL, ""); - bindtextdomain(PACKAGE_NAME, LOCALEDIR); - textdomain(PACKAGE_NAME); - - keymap_init(&kmap); - - while ((c = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) { - switch (c) { - case 'a': - options |= OPT_A; - break; - case 'b': - options |= OPT_B; - break; - case 'c': - kmap.flags |= LKFLAG_CLEAR_COMPOSE; - break; - case 'C': - console = optarg; - break; - case 'd': - options |= OPT_D; - break; - case 'm': - options |= OPT_M; - break; - case 's': - kmap.flags |= LKFLAG_CLEAR_STRINGS; - break; - case 'u': - options |= OPT_U; - kmap.flags |= LKFLAG_UNICODE_MODE; - kmap.prefer_unicode = 1; - break; - case 'q': - kmap.verbose = LOG_QUIET; - break; - case 'v': - if (kmap.verbose < LOG_MAXVALUE) - kmap.verbose++; - break; - case 'V': - print_version_and_exit(); - case 'h': - case '?': - usage(); - } - } - - if ((options & OPT_U) && (options & OPT_A)) { - fprintf(stderr, - _("%s: Options --unicode and --ascii are mutually exclusive\n"), - progname); - exit(EXIT_FAILURE); - } - - /* get console */ - fd = getfd(console); - - if (!(options & OPT_M) && !(options & OPT_B)) { - /* check whether the keyboard is in Unicode mode */ - if (ioctl(fd, KDGKBMODE, &kbd_mode) || - ioctl(fd, KDGETMODE, &kd_mode)) { - fprintf(stderr, _("%s: error reading keyboard mode: %m\n"), - progname); - exit(EXIT_FAILURE); - } - - if (kbd_mode == K_UNICODE) { - if (options & OPT_A) { - fprintf(stderr, - _("%s: warning: loading non-Unicode keymap on Unicode console\n" - " (perhaps you want to do `kbd_mode -a'?)\n"), - progname); - } else { - kmap.prefer_unicode = 1; - } - - /* reset -u option if keyboard is in K_UNICODE anyway */ - kmap.flags ^= LKFLAG_UNICODE_MODE; - - } else if (options & OPT_U && kd_mode != KD_GRAPHICS) { - fprintf(stderr, - _("%s: warning: loading Unicode keymap on non-Unicode console\n" - " (perhaps you want to do `kbd_mode -u'?)\n"), - progname); - } - } - - dirpath = dirpath1; - if ((ev = getenv("LOADKEYS_KEYMAP_PATH")) != NULL) { - dirpath2[0] = ev; - dirpath = dirpath2; - } - - if (options & OPT_D) { - /* first read default map - search starts in . */ - - if (findfile(DEFMAP, dirpath, suffixes, &f)) { - fprintf(stderr, _("Cannot find %s\n"), DEFMAP); - exit(EXIT_FAILURE); - } - - if ((rc = parse_keymap(&kmap, &f)) == -1) - goto fail; - - - } else if (optind == argc) { - f.fd = stdin; - strcpy(f.pathname, ""); - - if ((rc = parse_keymap(&kmap, &f)) == -1) - goto fail; - } - - for (i = optind; argv[i]; i++) { - if (!strcmp(argv[i], "-")) { - f.fd = stdin; - strcpy(f.pathname, ""); - - } else if (findfile(argv[i], dirpath, suffixes, &f)) { - fprintf(stderr, _("cannot open file %s\n"), argv[i]); - goto fail; - } - - if ((rc = parse_keymap(&kmap, &f)) == -1) - goto fail; - } - - if ((rc = do_constant(&kmap)) == -1) - goto fail; - - if (options & OPT_B) { - rc = bkeymap(&kmap); - } else if (options & OPT_M) { - rc = mktable(&kmap, stdout); - } else { - rc = loadkeys(&kmap, fd, kbd_mode); - } - - fail: freekeys(&kmap); - close(fd); - - if (rc < 0) - exit(EXIT_FAILURE); - - exit(EXIT_SUCCESS); -} -- 2.7.4