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