]> git.pld-linux.org Git - packages/busybox.git/blob - busybox-printf-gettext.patch
dynamic configuration needs libtirpc-devel
[packages/busybox.git] / busybox-printf-gettext.patch
1 diff -urNp -x '*.orig' busybox-1.31.1.org/coreutils/printf.c busybox-1.31.1/coreutils/printf.c
2 --- busybox-1.31.1.org/coreutils/printf.c       2019-06-10 12:50:53.000000000 +0200
3 +++ busybox-1.31.1/coreutils/printf.c   2021-10-21 10:28:37.833148938 +0200
4 @@ -59,6 +59,9 @@
5  //usage:       "$ printf \"Val=%d\\n\" 5\n"
6  //usage:       "Val=5\n"
7  
8 +// on by default
9 +#define BB_FEATURE_PRINTF_GETTEXT
10 +
11  #include "libbb.h"
12  
13  /* A note on bad input: neither bash 3.2 nor coreutils 6.10 stop on it.
14 @@ -400,11 +403,132 @@ static char **print_formatted(char *f, c
15         return argv;
16  }
17  
18 +/*
19 + * Very pure gettext added by Michal Moskal <malekith@pld-linux.org>
20 + * This possibly could be converted into utility function
21 + * and used in other places as well.
22 + */
23 +
24 +#ifdef BB_FEATURE_PRINTF_GETTEXT
25 +/* The magic number of the GNU message catalog format.  */
26 +#define _MAGIC 0x950412de
27 +
28 +/* Header for binary .mo file format.  */
29 +struct mo_file_header
30 +{
31 +       /* The magic number.  */
32 +       u_int32_t magic;
33 +       /* The revision number of the file format.  */
34 +       u_int32_t revision;
35 +       /* The number of strings pairs.  */
36 +       u_int32_t nstrings;
37 +       /* Offset of table with start offsets of original strings.  */
38 +       u_int32_t orig_tab_offset;
39 +       /* Offset of table with start offsets of translation strings.  */
40 +       u_int32_t trans_tab_offset;
41 +       /* Size of hashing table.  */
42 +       u_int32_t hash_tab_size;
43 +       /* Offset of first hashing entry.  */
44 +       u_int32_t hash_tab_offset;
45 +};
46 +
47 +struct string_desc
48 +{
49 +       /* Length of addressed string.  */
50 +       u_int32_t length;
51 +       /* Offset of string in file.  */
52 +       u_int32_t offset;
53 +};
54 +
55 +static u_int32_t swap(u_int32_t i)
56 +{
57 +       return (i << 24) | ((i & 0xff00) << 8) |
58 +               ((i >> 8) & 0xff00) | (i >> 24);
59 +}
60 +#define swap_if(a) ((has_to_swap) ? swap(a) : (a))
61 +static char *getmsg(const char *filename, const char *msgid)
62 +{
63 +       int fd;
64 +       struct mo_file_header *ptr;
65 +       struct stat st;
66 +       int has_to_swap;
67 +       size_t top, bottom;
68 +       struct string_desc *orig_tab, *trans_tab = NULL;
69 +       int act = -1;
70 +       char *ret = (char*)msgid;
71 +
72 +       if (filename == NULL || stat(filename, &st))
73 +               return ret;
74 +
75 +       fd = open(filename, O_RDONLY);
76 +       if (fd == -1)
77 +               return ret;
78 +
79 +       ptr = (struct mo_file_header *) mmap(NULL, st.st_size, PROT_READ,
80 +                       MAP_PRIVATE, fd, 0);
81 +       close(fd);
82 +
83 +       if (ptr == (void*)-1)
84 +               return ret;
85 +
86 +       has_to_swap = ptr->magic != _MAGIC;
87 +
88 +       if (swap_if(ptr->magic) != _MAGIC)
89 +               goto oops;
90 +
91 +       /* FIXME: use hash table */
92 +
93 +       orig_tab = (struct string_desc *)
94 +               ((char *) ptr + swap_if(ptr->orig_tab_offset));
95 +       trans_tab = (struct string_desc *)
96 +               ((char *) ptr + swap_if(ptr->trans_tab_offset));
97 +
98 +       bottom = 0;
99 +       top = swap_if(ptr->nstrings);
100 +       while (bottom < top) {
101 +               int cmp_val;
102 +               act = (bottom + top) / 2;
103 +               cmp_val =
104 +                       strcmp(msgid,
105 +                                       ((char *) ptr + swap_if(orig_tab[act].offset)));
106 +               if (cmp_val < 0)
107 +                       top = act;
108 +               else if (cmp_val > 0)
109 +                       bottom = act + 1;
110 +               else
111 +                       break;
112 +               act = -1;
113 +       }
114 +
115 +oops:
116 +       if (act != -1)
117 +               ret = strdup(((char *) ptr + swap_if(trans_tab[act].offset)));
118 +       munmap(ptr, st.st_size);
119 +       return ret;
120 +}
121 +#else
122 +# define getmsg(a,b) (b)
123 +#endif
124 +
125  int printf_main(int argc UNUSED_PARAM, char **argv)
126  {
127         int conv_err;
128         char *format;
129         char **argv2;
130 +       int opt;
131 +       const char *nls_file = NULL;
132 +
133 +       while ((opt = getopt(argc, argv, "n:")) != -1)
134 +               switch (opt) {
135 +                       case 'n':
136 +                               nls_file = optarg;
137 +                               break;
138 +                       default:
139 +                               bb_show_usage();
140 +                               break;
141 +               }
142 +
143 +       format = getmsg(nls_file, argv[optind++]);
144  
145         /* We must check that stdout is not closed.
146          * The reason for this is highly non-obvious.
147 @@ -436,8 +560,8 @@ int printf_main(int argc UNUSED_PARAM, c
148                 bb_show_usage();
149         }
150  
151 -       format = argv[1];
152 -       argv2 = argv + 2;
153 +    argv += optind;
154 +       argv2 = argv;
155  
156         conv_err = 0;
157         do {
This page took 0.054685 seconds and 3 git commands to generate.