]>
Commit | Line | Data |
---|---|---|
4c6ebd20 | 1 | diff -ur busybox-0.60.1/printf.c busybox-0.60.1.new/printf.c |
2 | --- busybox-0.60.1/printf.c Mon Mar 19 20:25:49 2001 | |
3 | +++ busybox-0.60.1.new/printf.c Thu May 31 16:41:31 2001 | |
82b23b53 MM |
4 | @@ -47,6 +47,9 @@ |
5 | ||
6 | // 19990508 Busy Boxed! Dave Cinege | |
7 | ||
8 | +// on by default | |
9 | +#define BB_FEATURE_PRINTF_GETTEXT | |
10 | + | |
11 | #include <unistd.h> | |
12 | #include <stdio.h> | |
13 | #include <sys/types.h> | |
14 | @@ -55,6 +58,11 @@ | |
15 | #include <stdlib.h> | |
16 | #include <fcntl.h> | |
17 | #include <ctype.h> | |
18 | +#include <string.h> | |
19 | +#include <unistd.h> | |
20 | +#include <stdio.h> | |
21 | +#include <sys/stat.h> | |
22 | +#include <sys/mman.h> | |
23 | #include "busybox.h" | |
24 | ||
25 | ||
26 | @@ -117,19 +125,140 @@ | |
27 | /* The value to return to the calling program. */ | |
28 | static int exit_status; | |
29 | ||
30 | + | |
31 | +/* | |
0cd3c5fc | 32 | + * Very pure gettext added by Michal Moskal <malekith@pld-linux.org> |
82b23b53 MM |
33 | + * This possibly could be converted into utility function |
34 | + * and used in other places as well. | |
35 | + */ | |
36 | + | |
37 | +#ifdef BB_FEATURE_PRINTF_GETTEXT | |
38 | +/* The magic number of the GNU message catalog format. */ | |
39 | +#define _MAGIC 0x950412de | |
40 | + | |
41 | +/* Header for binary .mo file format. */ | |
42 | +struct mo_file_header | |
43 | +{ | |
44 | + /* The magic number. */ | |
45 | + u_int32_t magic; | |
46 | + /* The revision number of the file format. */ | |
47 | + u_int32_t revision; | |
48 | + /* The number of strings pairs. */ | |
49 | + u_int32_t nstrings; | |
50 | + /* Offset of table with start offsets of original strings. */ | |
51 | + u_int32_t orig_tab_offset; | |
52 | + /* Offset of table with start offsets of translation strings. */ | |
53 | + u_int32_t trans_tab_offset; | |
54 | + /* Size of hashing table. */ | |
55 | + u_int32_t hash_tab_size; | |
56 | + /* Offset of first hashing entry. */ | |
57 | + u_int32_t hash_tab_offset; | |
58 | +}; | |
59 | + | |
60 | +struct string_desc | |
61 | +{ | |
62 | + /* Length of addressed string. */ | |
63 | + u_int32_t length; | |
64 | + /* Offset of string in file. */ | |
65 | + u_int32_t offset; | |
66 | +}; | |
67 | + | |
68 | +static u_int32_t swap(u_int32_t i) | |
69 | +{ | |
70 | + return (i << 24) | ((i & 0xff00) << 8) | | |
71 | + ((i >> 8) & 0xff00) | (i >> 24); | |
72 | +} | |
73 | + | |
74 | +#define swap_if(a) ((has_to_swap) ? swap(a) : (a)) | |
75 | + | |
76 | +static char *getmsg(const char *filename, const char *msgid) | |
77 | +{ | |
78 | + int fd; | |
79 | + struct mo_file_header *ptr; | |
80 | + struct stat st; | |
81 | + int has_to_swap; | |
82 | + size_t top, bottom; | |
83 | + struct string_desc *orig_tab, *trans_tab = NULL; | |
84 | + int act = -1; | |
85 | + char *ret = (char*)msgid; | |
86 | + | |
87 | + if (filename == NULL || stat(filename, &st)) | |
88 | + return ret; | |
89 | + | |
90 | + fd = open(filename, O_RDONLY); | |
91 | + if (fd == -1) | |
92 | + return ret; | |
93 | + | |
94 | + ptr = (struct mo_file_header *) mmap(NULL, st.st_size, PROT_READ, | |
95 | + MAP_PRIVATE, fd, 0); | |
96 | + close(fd); | |
97 | + | |
98 | + if (ptr == (void*)-1) | |
99 | + return ret; | |
100 | + | |
101 | + has_to_swap = ptr->magic != _MAGIC; | |
102 | + | |
103 | + if (swap_if(ptr->magic) != _MAGIC) | |
104 | + goto oops; | |
105 | + | |
106 | + /* FIXME: use hash table */ | |
107 | + | |
108 | + orig_tab = (struct string_desc *) | |
109 | + ((char *) ptr + swap_if(ptr->orig_tab_offset)); | |
110 | + trans_tab = (struct string_desc *) | |
111 | + ((char *) ptr + swap_if(ptr->trans_tab_offset)); | |
112 | + | |
113 | + bottom = 0; | |
114 | + top = swap_if(ptr->nstrings); | |
115 | + while (bottom < top) { | |
116 | + int cmp_val; | |
117 | + | |
118 | + act = (bottom + top) / 2; | |
119 | + cmp_val = | |
120 | + strcmp(msgid, | |
121 | + ((char *) ptr + swap_if(orig_tab[act].offset))); | |
122 | + if (cmp_val < 0) | |
123 | + top = act; | |
124 | + else if (cmp_val > 0) | |
125 | + bottom = act + 1; | |
126 | + else | |
127 | + break; | |
128 | + act = -1; | |
129 | + } | |
130 | + | |
131 | + oops: | |
132 | + if (act != -1) | |
133 | + ret = strdup(((char *) ptr + swap_if(trans_tab[act].offset))); | |
134 | + munmap(ptr, st.st_size); | |
135 | + return ret; | |
136 | +} | |
137 | +#else | |
138 | +# define getmsg(a,b) (b) | |
139 | +#endif | |
140 | + | |
141 | int printf_main(int argc, char **argv) | |
142 | { | |
143 | char *format; | |
144 | int args_used; | |
145 | + int opt; | |
146 | + const char *nls_file = NULL; | |
147 | ||
148 | exit_status = 0; | |
149 | - if (argc <= 1 || **(argv + 1) == '-') { | |
150 | - show_usage(); | |
151 | - } | |
152 | ||
153 | - format = argv[1]; | |
154 | - argc -= 2; | |
155 | - argv += 2; | |
156 | + while ((opt = getopt(argc, argv, "n:")) != -1) | |
157 | + switch (opt) { | |
158 | + case 'n': | |
159 | + nls_file = optarg; | |
160 | + break; | |
161 | + default: | |
162 | + show_usage(); | |
163 | + break; | |
164 | + } | |
165 | + | |
166 | + format = getmsg(nls_file, argv[optind++]); | |
167 | + | |
168 | + argc -= optind; | |
169 | + argv += optind; | |
170 | ||
171 | do { | |
172 | args_used = print_formatted(format, argc, argv); |