]>
Commit | Line | Data |
---|---|---|
c818a1f2 JB |
1 | --- busybox-1.3.1/coreutils/printf.c.orig 2006-12-27 05:54:50.000000000 +0100 |
2 | +++ busybox-1.3.1/coreutils/printf.c 2006-12-30 12:28:27.605589427 +0100 | |
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 | + | |
c818a1f2 JB |
10 | #include "busybox.h" |
11 | ||
12 | static int print_formatted(char *format, int argc, char **argv); | |
13 | @@ -109,18 +112,137 @@ | |
14 | } | |
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 | +{ | |
56 | + return (i << 24) | ((i & 0xff00) << 8) | | |
57 | + ((i >> 8) & 0xff00) | (i >> 24); | |
58 | +} | |
59 | + | |
60 | +#define swap_if(a) ((has_to_swap) ? swap(a) : (a)) | |
61 | + | |
62 | +static char *getmsg(const char *filename, const char *msgid) | |
63 | +{ | |
64 | + int fd; | |
65 | + struct mo_file_header *ptr; | |
66 | + struct stat st; | |
67 | + int has_to_swap; | |
68 | + size_t top, bottom; | |
69 | + struct string_desc *orig_tab, *trans_tab = NULL; | |
70 | + int act = -1; | |
71 | + char *ret = (char*)msgid; | |
72 | + | |
73 | + if (filename == NULL || stat(filename, &st)) | |
74 | + return ret; | |
75 | + | |
76 | + fd = open(filename, O_RDONLY); | |
77 | + if (fd == -1) | |
78 | + return ret; | |
79 | + | |
80 | + ptr = (struct mo_file_header *) mmap(NULL, st.st_size, PROT_READ, | |
81 | + MAP_PRIVATE, fd, 0); | |
82 | + close(fd); | |
83 | + | |
84 | + if (ptr == (void*)-1) | |
85 | + return ret; | |
86 | + | |
87 | + has_to_swap = ptr->magic != _MAGIC; | |
88 | + | |
89 | + if (swap_if(ptr->magic) != _MAGIC) | |
90 | + goto oops; | |
91 | + | |
92 | + /* FIXME: use hash table */ | |
93 | + | |
94 | + orig_tab = (struct string_desc *) | |
95 | + ((char *) ptr + swap_if(ptr->orig_tab_offset)); | |
96 | + trans_tab = (struct string_desc *) | |
97 | + ((char *) ptr + swap_if(ptr->trans_tab_offset)); | |
98 | + | |
99 | + bottom = 0; | |
100 | + top = swap_if(ptr->nstrings); | |
101 | + while (bottom < top) { | |
102 | + int cmp_val; | |
103 | + | |
104 | + act = (bottom + top) / 2; | |
105 | + cmp_val = | |
106 | + strcmp(msgid, | |
107 | + ((char *) ptr + swap_if(orig_tab[act].offset))); | |
108 | + if (cmp_val < 0) | |
109 | + top = act; | |
110 | + else if (cmp_val > 0) | |
111 | + bottom = act + 1; | |
112 | + else | |
113 | + break; | |
114 | + act = -1; | |
115 | + } | |
116 | + | |
117 | + oops: | |
118 | + if (act != -1) | |
119 | + ret = strdup(((char *) ptr + swap_if(trans_tab[act].offset))); | |
120 | + munmap(ptr, st.st_size); | |
121 | + return ret; | |
122 | +} | |
123 | +#else | |
124 | +# define getmsg(a,b) (b) | |
125 | +#endif | |
126 | + | |
127 | int printf_main(int argc, char **argv) | |
128 | { | |
129 | char *format; | |
130 | int args_used; | |
131 | + int opt; | |
132 | + const char *nls_file = NULL; | |
133 | ||
c818a1f2 | 134 | - if (argc <= 1 || argv[1][0] == '-') { |
3ca7065e | 135 | - bb_show_usage(); |
82b23b53 | 136 | - } |
82b23b53 MM |
137 | + while ((opt = getopt(argc, argv, "n:")) != -1) |
138 | + switch (opt) { | |
139 | + case 'n': | |
140 | + nls_file = optarg; | |
141 | + break; | |
142 | + default: | |
3ca7065e | 143 | + bb_show_usage(); |
82b23b53 MM |
144 | + break; |
145 | + } | |
146 | + | |
147 | + format = getmsg(nls_file, argv[optind++]); | |
281716a4 | 148 | |
149 | - format = argv[1]; | |
150 | - argc -= 2; | |
151 | - argv += 2; | |
82b23b53 MM |
152 | + argc -= optind; |
153 | + argv += optind; | |
154 | ||
155 | do { | |
156 | args_used = print_formatted(format, argc, argv); |