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