]>
Commit | Line | Data |
---|---|---|
72a55260 AM |
1 | diff -urN busybox-1.6.0.org/coreutils/printf.c busybox-1.6.0/coreutils/printf.c |
2 | --- busybox-1.6.0.org/coreutils/printf.c 2007-06-01 13:48:34.000000000 +0200 | |
3 | +++ busybox-1.6.0/coreutils/printf.c 2007-06-03 20:27:45.511646939 +0200 | |
c818a1f2 | 4 | @@ -38,6 +38,9 @@ |
82b23b53 MM |
5 | |
6 | // 19990508 Busy Boxed! Dave Cinege | |
7 | ||
8 | +// on by default | |
9 | +#define BB_FEATURE_PRINTF_GETTEXT | |
10 | + | |
72a55260 | 11 | #include "libbb.h" |
c818a1f2 | 12 | |
72a55260 AM |
13 | typedef void (*converter)(const char *arg, void *result); |
14 | @@ -285,19 +288,137 @@ | |
316ae9e2 | 15 | return save_argc - argc; |
c818a1f2 | 16 | } |
82b23b53 | 17 | |
82b23b53 | 18 | +/* |
0cd3c5fc | 19 | + * Very pure gettext added by Michal Moskal <malekith@pld-linux.org> |
82b23b53 MM |
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 | +{ | |
316ae9e2 AM |
57 | + return (i << 24) | ((i & 0xff00) << 8) | |
58 | + ((i >> 8) & 0xff00) | (i >> 24); | |
82b23b53 | 59 | +} |
82b23b53 | 60 | +#define swap_if(a) ((has_to_swap) ? swap(a) : (a)) |
82b23b53 MM |
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; | |
316ae9e2 | 71 | + |
82b23b53 MM |
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, | |
316ae9e2 | 80 | + MAP_PRIVATE, fd, 0); |
82b23b53 MM |
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 *) | |
316ae9e2 | 94 | + ((char *) ptr + swap_if(ptr->orig_tab_offset)); |
82b23b53 | 95 | + trans_tab = (struct string_desc *) |
316ae9e2 | 96 | + ((char *) ptr + swap_if(ptr->trans_tab_offset)); |
82b23b53 MM |
97 | + |
98 | + bottom = 0; | |
99 | + top = swap_if(ptr->nstrings); | |
100 | + while (bottom < top) { | |
101 | + int cmp_val; | |
82b23b53 MM |
102 | + act = (bottom + top) / 2; |
103 | + cmp_val = | |
316ae9e2 AM |
104 | + strcmp(msgid, |
105 | + ((char *) ptr + swap_if(orig_tab[act].offset))); | |
82b23b53 MM |
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 | + | |
316ae9e2 | 115 | +oops: |
82b23b53 MM |
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 | + | |
316ae9e2 | 125 | int printf_main(int argc, char **argv); |
82b23b53 MM |
126 | int printf_main(int argc, char **argv) |
127 | { | |
128 | char *format; | |
316ae9e2 AM |
129 | - int args_used; |
130 | + int args_used, opt; | |
82b23b53 | 131 | + const char *nls_file = NULL; |
72a55260 | 132 | + |
82b23b53 MM |
133 | + while ((opt = getopt(argc, argv, "n:")) != -1) |
134 | + switch (opt) { | |
316ae9e2 AM |
135 | + case 'n': |
136 | + nls_file = optarg; | |
137 | + break; | |
138 | + default: | |
139 | + bb_show_usage(); | |
140 | + break; | |
82b23b53 | 141 | + } |
82b23b53 | 142 | + format = getmsg(nls_file, argv[optind++]); |
281716a4 | 143 | |
72a55260 AM |
144 | if (argc <= 1 || argv[1][0] == '-') { |
145 | bb_show_usage(); | |
146 | } | |
147 | ||
281716a4 | 148 | - format = argv[1]; |
149 | - argc -= 2; | |
150 | - argv += 2; | |
82b23b53 MM |
151 | + argc -= optind; |
152 | + argv += optind; | |
153 | ||
154 | do { | |
155 | args_used = print_formatted(format, argc, argv); |