db3b9692f2371ab47b49630354f84d9bdd302c45
[platform/upstream/kbd.git] / src / getunimap.c
1 #include "config.h"
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <errno.h>
6 #include <ctype.h>
7 #include <unistd.h>
8 #include <sys/ioctl.h>
9 #include <linux/kd.h>
10 #include "getfd.h"
11 #include "xmalloc.h"
12 #include "kdmapop.h"
13 #include "nls.h"
14 #include "version.h"
15
16 #ifndef USE_LIBC
17 /* There is such function in libc5 but it doesn't work for me [libc 5.4.13] */
18 #include "wctomb.c"
19 #define wctomb our_wctomb
20 #endif
21
22 static int
23 ud_compar(const void *u1, const void *u2)
24 {
25         unsigned short fp1 = ((struct unipair *)u1)->fontpos;
26         unsigned short fp2 = ((struct unipair *)u2)->fontpos;
27         return (int)fp1 - (int)fp2;
28 }
29
30 static void __attribute__((noreturn))
31 usage(void)
32 {
33         fprintf(stderr, _("Usage:\n\t%s [-s] [-C console]\n"), progname);
34         exit(EXIT_FAILURE);
35 }
36
37 int main(int argc, char **argv)
38 {
39         int sortflag = 0;
40         char mb[]    = { 0, 0, 0, 0, 0, 0, 0, 0 };
41         unsigned mb_length;
42         int fd, c, i;
43         char *console = NULL;
44         struct unimapdesc ud;
45
46         set_progname(argv[0]);
47
48         setlocale(LC_ALL, "");
49         bindtextdomain(PACKAGE_NAME, LOCALEDIR);
50         textdomain(PACKAGE_NAME);
51
52         if (argc == 2 &&
53             (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version")))
54                 print_version_and_exit();
55
56         while ((c = getopt(argc, argv, "sC:")) != EOF) {
57                 switch (c) {
58                         case 's':
59                                 sortflag = 1;
60                                 break;
61                         case 'C':
62                                 console = optarg;
63                                 break;
64                         default:
65                                 usage();
66                 }
67         }
68
69         if (optind < argc)
70                 usage();
71
72         if ((fd = getfd(console)) < 0)
73                 kbd_error(EXIT_FAILURE, 0, _("Couldn't get a file descriptor referring to the console"));
74
75         if (getunimap(fd, &ud))
76                 return EXIT_FAILURE;
77
78         if (sortflag) {
79                 printf("# sorted kernel unimap - count=%d\n", ud.entry_ct);
80                 /* sort and merge entries */
81                 qsort(ud.entries, ud.entry_ct, sizeof(ud.entries[0]),
82                       ud_compar);
83                 for (i = 0; i < ud.entry_ct; i++) {
84                         int fp = ud.entries[i].fontpos;
85                         printf("0x%03x\tU+%04x", fp, ud.entries[i].unicode);
86                         while (i + 1 < ud.entry_ct &&
87                                ud.entries[i + 1].fontpos == fp)
88                                 printf(" U+%04x", ud.entries[++i].unicode);
89                         printf("\n");
90                 }
91         } else {
92                 printf("# kernel unimap - count=%d\n", ud.entry_ct);
93                 for (i = 0; i < ud.entry_ct; i++) {
94                         mb_length                           = wctomb(mb, ud.entries[i].unicode);
95                         mb[(mb_length > 6) ? 0 : mb_length] = 0;
96                         if (mb_length == 1 && !isprint(mb[0])) {
97                                 mb[2] = 0;
98                                 mb[1] = mb[0] + 0100;
99                                 mb[0] = '^';
100                         }
101                         printf("0x%03x\tU+%04x\t# %s \n",
102                                ud.entries[i].fontpos,
103                                ud.entries[i].unicode, mb);
104                 }
105         }
106
107         return EXIT_SUCCESS;
108 }