diff options
author | Erik Andersen <andersen@codepoet.org> | 1999-12-29 03:34:00 +0000 |
---|---|---|
committer | Erik Andersen <andersen@codepoet.org> | 1999-12-29 03:34:00 +0000 |
commit | a89910829c73c5ed4f30eecb181d7b3087ca4f74 (patch) | |
tree | 9467006b9e64b9051ec48c6fcccd30e50c587f84 | |
parent | f664c004db12cdb3e379c1745351e225c7b92de7 (diff) | |
download | busybox-w32-a89910829c73c5ed4f30eecb181d7b3087ca4f74.tar.gz busybox-w32-a89910829c73c5ed4f30eecb181d7b3087ca4f74.tar.bz2 busybox-w32-a89910829c73c5ed4f30eecb181d7b3087ca4f74.zip |
Add the beginings of some regression testing. Add in the recently
contributed loadacm utility (for dealing with unicode fonts)
-Erik
-rw-r--r-- | Changelog | 2 | ||||
-rw-r--r-- | applets/busybox.c | 3 | ||||
-rw-r--r-- | busybox.c | 3 | ||||
-rw-r--r-- | busybox.def.h | 1 | ||||
-rw-r--r-- | console-tools/loadacm.c | 441 | ||||
-rw-r--r-- | internal.h | 1 | ||||
-rw-r--r-- | loadacm.c | 441 | ||||
-rwxr-xr-x | reg_test.sh | 136 | ||||
-rw-r--r-- | utility.c | 2 |
9 files changed, 1029 insertions, 1 deletions
@@ -15,6 +15,8 @@ | |||
15 | special files. | 15 | special files. |
16 | * cp and mv were quite broken when moving directories. I have rewritten | 16 | * cp and mv were quite broken when moving directories. I have rewritten |
17 | them so they should now work as expected. | 17 | them so they should now work as expected. |
18 | * New app: loadacm contributed by Peter Novodvorsky <petya@logic.ru> | ||
19 | for loading application character maps for working with Unicode fonts. | ||
18 | 20 | ||
19 | 21 | ||
20 | -Erik Andersen | 22 | -Erik Andersen |
diff --git a/applets/busybox.c b/applets/busybox.c index cd4ab8fcd..403b14008 100644 --- a/applets/busybox.c +++ b/applets/busybox.c | |||
@@ -232,6 +232,9 @@ static const struct Applet applets[] = { | |||
232 | #ifdef BB_GZIP //bin | 232 | #ifdef BB_GZIP //bin |
233 | {"gzip", gzip_main}, | 233 | {"gzip", gzip_main}, |
234 | #endif | 234 | #endif |
235 | #ifdef BB_LOADACM //usr/bin | ||
236 | {"loadacm", loadacm_main}, | ||
237 | #endif | ||
235 | {0} | 238 | {0} |
236 | }; | 239 | }; |
237 | 240 | ||
@@ -232,6 +232,9 @@ static const struct Applet applets[] = { | |||
232 | #ifdef BB_GZIP //bin | 232 | #ifdef BB_GZIP //bin |
233 | {"gzip", gzip_main}, | 233 | {"gzip", gzip_main}, |
234 | #endif | 234 | #endif |
235 | #ifdef BB_LOADACM //usr/bin | ||
236 | {"loadacm", loadacm_main}, | ||
237 | #endif | ||
235 | {0} | 238 | {0} |
236 | }; | 239 | }; |
237 | 240 | ||
diff --git a/busybox.def.h b/busybox.def.h index 3c290f7a4..3982a1c83 100644 --- a/busybox.def.h +++ b/busybox.def.h | |||
@@ -33,6 +33,7 @@ | |||
33 | #define BB_KLOGD | 33 | #define BB_KLOGD |
34 | //#define BB_LENGTH | 34 | //#define BB_LENGTH |
35 | #define BB_LN | 35 | #define BB_LN |
36 | //#define BB_LOADACM | ||
36 | //#define BB_LOADFONT | 37 | //#define BB_LOADFONT |
37 | //#define BB_LOADKMAP | 38 | //#define BB_LOADKMAP |
38 | #define BB_LOGGER | 39 | #define BB_LOGGER |
diff --git a/console-tools/loadacm.c b/console-tools/loadacm.c new file mode 100644 index 000000000..491bc5ce8 --- /dev/null +++ b/console-tools/loadacm.c | |||
@@ -0,0 +1,441 @@ | |||
1 | /* | ||
2 | * Derived from | ||
3 | * mapscrn.c - version 0.92 | ||
4 | * | ||
5 | * Was taken from console-tools and adapted by | ||
6 | * Peter Novodvorsky <petya@logic.ru> | ||
7 | */ | ||
8 | |||
9 | #include <stdio.h> | ||
10 | #include <stdlib.h> | ||
11 | #include <memory.h> | ||
12 | #include <string.h> | ||
13 | #include <unistd.h> | ||
14 | #include <fcntl.h> | ||
15 | #include <assert.h> | ||
16 | #include <errno.h> | ||
17 | #include <signal.h> | ||
18 | #include <sys/types.h> | ||
19 | #include <sys/stat.h> | ||
20 | #include <sys/ioctl.h> | ||
21 | #include <sys/kd.h> | ||
22 | |||
23 | typedef unsigned short unicode; | ||
24 | |||
25 | static long int ctoi(unsigned char *s, int *is_unicode); | ||
26 | int old_screen_map_read_ascii(FILE *fp, unsigned char buf[]); | ||
27 | int uni_screen_map_read_ascii(FILE *fp, unicode buf[], int* is_unicode); | ||
28 | unicode utf8_to_ucs2 (char* buf); | ||
29 | int screen_map_load(int fd, FILE *fp); | ||
30 | |||
31 | int loadacm_main(int argc, char **argv) | ||
32 | { | ||
33 | int fd; | ||
34 | |||
35 | fd = open("/dev/tty", O_RDWR); | ||
36 | if (fd < 0) { | ||
37 | fprintf(stderr, "Error opening /dev/tty1: %s\n", strerror(errno)); | ||
38 | return 1; | ||
39 | } | ||
40 | |||
41 | if (screen_map_load(fd, stdin)) | ||
42 | { | ||
43 | fprintf(stderr, "Error loading acm: %s\n", strerror(errno)); | ||
44 | return 1; | ||
45 | } | ||
46 | |||
47 | write(fd, "\033(K", 3); | ||
48 | |||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | int screen_map_load(int fd, FILE *fp) | ||
53 | { | ||
54 | struct stat stbuf; | ||
55 | unicode wbuf[E_TABSZ]; | ||
56 | unsigned char buf[E_TABSZ]; | ||
57 | int parse_failed = 0; | ||
58 | int is_unicode; | ||
59 | |||
60 | if (fstat(fp->_fileno, &stbuf)) | ||
61 | perror("Cannot stat map file"), exit(1); | ||
62 | |||
63 | /* first try a UTF screen-map: either ASCII (no restriction) or binary (regular file) */ | ||
64 | if (!(parse_failed = (-1 == uni_screen_map_read_ascii(fp,wbuf,&is_unicode))) || | ||
65 | (S_ISREG(stbuf.st_mode) && | ||
66 | (stbuf.st_size == (sizeof(unicode) * E_TABSZ)))) /* test for binary UTF map by size */ | ||
67 | { | ||
68 | if (parse_failed) | ||
69 | { | ||
70 | if (-1 == fseek (fp, 0, SEEK_SET)) | ||
71 | { | ||
72 | if (errno == ESPIPE) | ||
73 | fprintf (stderr, "16bit screen-map MUST be a regular file.\n"), exit (1); | ||
74 | else | ||
75 | perror ("fseek failed reading binary 16bit screen-map"), exit (1); | ||
76 | } | ||
77 | |||
78 | if (fread(wbuf, sizeof(unicode) * E_TABSZ, 1, fp) != 1) | ||
79 | perror("Cannot read [new] map from file"), exit(1); | ||
80 | #if 0 | ||
81 | else | ||
82 | fprintf(stderr, "Input screen-map is binary.\n"); | ||
83 | #endif | ||
84 | } | ||
85 | |||
86 | /* if it was effectively a 16-bit ASCII, OK, else try to read as 8-bit map */ | ||
87 | /* same if it was binary, ie. if parse_failed */ | ||
88 | if (parse_failed || is_unicode) | ||
89 | { | ||
90 | if (ioctl(fd,PIO_UNISCRNMAP,wbuf)) | ||
91 | perror("PIO_UNISCRNMAP ioctl"), exit(1); | ||
92 | else | ||
93 | return 0; | ||
94 | } | ||
95 | } | ||
96 | |||
97 | /* rewind... */ | ||
98 | if (-1 == fseek (fp, 0, SEEK_SET)) | ||
99 | { | ||
100 | if (errno == ESPIPE) | ||
101 | fprintf (stderr, "Assuming 8bit screen-map - MUST be a regular file.\n"), exit (1); | ||
102 | else | ||
103 | perror ("fseek failed assuming 8bit screen-map"), exit (1); | ||
104 | } | ||
105 | |||
106 | /* ... and try an old 8-bit screen-map */ | ||
107 | if (!(parse_failed = (-1 == old_screen_map_read_ascii(fp,buf))) || | ||
108 | (S_ISREG(stbuf.st_mode) && | ||
109 | (stbuf.st_size == E_TABSZ))) /* test for binary old 8-bit map by size */ | ||
110 | { | ||
111 | if (parse_failed) | ||
112 | { | ||
113 | if (-1 == fseek (fp, 0, SEEK_SET)) | ||
114 | { | ||
115 | if (errno == ESPIPE) | ||
116 | /* should not - it succedeed above */ | ||
117 | fprintf (stderr, "fseek() returned ESPIPE !\n"), exit (1); | ||
118 | else | ||
119 | perror ("fseek for binary 8bit screen-map"), exit (1); | ||
120 | } | ||
121 | |||
122 | if (fread(buf,E_TABSZ,1,fp) != 1) | ||
123 | perror("Cannot read [old] map from file"), exit(1); | ||
124 | #if 0 | ||
125 | else | ||
126 | fprintf(stderr, "Input screen-map is binary.\n"); | ||
127 | #endif | ||
128 | } | ||
129 | |||
130 | if (ioctl(fd,PIO_SCRNMAP,buf)) | ||
131 | perror("PIO_SCRNMAP ioctl"), exit(1); | ||
132 | else | ||
133 | return 0; | ||
134 | } | ||
135 | else | ||
136 | { | ||
137 | fprintf(stderr, "Error parsing symbolic map\n"); | ||
138 | exit(1); | ||
139 | } | ||
140 | } | ||
141 | |||
142 | |||
143 | /* | ||
144 | * - reads `fp' as a 16-bit ASCII SFM file. | ||
145 | * - returns -1 on error. | ||
146 | * - returns it in `unicode' in an E_TABSZ-elements array. | ||
147 | * - sets `*is_unicode' flagiff there were any non-8-bit | ||
148 | * (ie. real 16-bit) mapping. | ||
149 | * | ||
150 | * FIXME: ignores everything after second word | ||
151 | */ | ||
152 | int uni_screen_map_read_ascii(FILE *fp, unicode buf[], int *is_unicode) | ||
153 | { | ||
154 | char buffer[256]; /* line buffer reading file */ | ||
155 | char *p, *q; /* 1st + 2nd words in line */ | ||
156 | int in, on; /* the same, as numbers */ | ||
157 | int tmp_is_unicode; /* tmp for is_unicode calculation */ | ||
158 | int i; /* loop index - result holder */ | ||
159 | int ret_code = 0; /* return code */ | ||
160 | sigset_t sigset, old_sigset; | ||
161 | |||
162 | assert (is_unicode); | ||
163 | |||
164 | *is_unicode = 0; | ||
165 | |||
166 | /* first 128 codes defaults to ASCII */ | ||
167 | for (i=0; i<128; i++) buf[i] = i; | ||
168 | /* remaining defaults to replacement char (usually E_TABSZ = 256) */ | ||
169 | for ( ; i<E_TABSZ; i++) buf[i] = 0xfffd; | ||
170 | |||
171 | /* block SIGCHLD */ | ||
172 | sigemptyset (&sigset); | ||
173 | sigaddset (&sigset, SIGCHLD); | ||
174 | sigprocmask (SIG_BLOCK, &sigset, &old_sigset); | ||
175 | |||
176 | do | ||
177 | { | ||
178 | if (NULL == fgets(buffer, sizeof(buffer),fp)) | ||
179 | { | ||
180 | if (feof (fp)) | ||
181 | break; | ||
182 | else | ||
183 | { | ||
184 | perror ("uni_screen_map_read_ascii() can't read line"); | ||
185 | exit (2); | ||
186 | } | ||
187 | } | ||
188 | |||
189 | /* get "charset-relative charcode", stripping leading spaces */ | ||
190 | p = strtok(buffer," \t\n"); | ||
191 | |||
192 | /* skip empty lines and comments */ | ||
193 | if (!p || *p == '#') | ||
194 | continue; | ||
195 | |||
196 | /* get unicode mapping */ | ||
197 | q = strtok(NULL," \t\n"); | ||
198 | if (q) | ||
199 | { | ||
200 | in = ctoi(p, NULL); | ||
201 | if (in < 0 || in > 255) | ||
202 | { | ||
203 | ret_code = -1; | ||
204 | break; | ||
205 | } | ||
206 | |||
207 | on = ctoi(q, &tmp_is_unicode); | ||
208 | if (in < 0 && on > 65535) | ||
209 | { | ||
210 | ret_code = -1; | ||
211 | break; | ||
212 | } | ||
213 | |||
214 | *is_unicode |= tmp_is_unicode; | ||
215 | buf[in] = on; | ||
216 | } | ||
217 | else | ||
218 | { | ||
219 | ret_code = -1; | ||
220 | break; | ||
221 | } | ||
222 | } | ||
223 | while (1); /* terminated by break on feof() */ | ||
224 | |||
225 | /* restore sig mask */ | ||
226 | sigprocmask (SIG_SETMASK, &old_sigset, NULL); | ||
227 | |||
228 | return ret_code; | ||
229 | } | ||
230 | |||
231 | |||
232 | int old_screen_map_read_ascii(FILE *fp, unsigned char buf[]) | ||
233 | { | ||
234 | char buffer[256]; | ||
235 | int in, on; | ||
236 | char *p, *q; | ||
237 | |||
238 | for (in=0; in<256; in++) buf[in]=in; | ||
239 | |||
240 | while (fgets(buffer,sizeof(buffer)-1,fp)) | ||
241 | { | ||
242 | p = strtok(buffer," \t\n"); | ||
243 | |||
244 | if (!p || *p == '#') | ||
245 | continue; | ||
246 | |||
247 | q = strtok(NULL," \t\n#"); | ||
248 | if (q) | ||
249 | { | ||
250 | in = ctoi(p, NULL); | ||
251 | if (in < 0 || in > 255) return -1; | ||
252 | |||
253 | on = ctoi(q, NULL); | ||
254 | if (in < 0 && on > 255) return -1; | ||
255 | |||
256 | buf[in] = on; | ||
257 | } | ||
258 | else return -1; | ||
259 | } | ||
260 | |||
261 | return(0); | ||
262 | } | ||
263 | |||
264 | |||
265 | /* | ||
266 | * - converts a string into an int. | ||
267 | * - supports dec and hex bytes, hex UCS2, single-quoted byte and UTF8 chars. | ||
268 | * - returns the converted value | ||
269 | * - if `is_unicode != NULL', use it to tell whether it was unicode | ||
270 | * | ||
271 | * CAVEAT: will report valid UTF mappings using only 1 byte as 8-bit ones. | ||
272 | */ | ||
273 | long int ctoi(unsigned char *s, int *is_unicode) | ||
274 | { | ||
275 | int i; | ||
276 | size_t ls; | ||
277 | |||
278 | ls = strlen(s); | ||
279 | if (is_unicode) *is_unicode = 0; | ||
280 | |||
281 | /* hex-specified UCS2 */ | ||
282 | if ((strncmp(s,"U+",2) == 0) && | ||
283 | (strspn(s+2,"0123456789abcdefABCDEF") == ls-2)) | ||
284 | { | ||
285 | sscanf(s+2,"%x",&i); | ||
286 | if (is_unicode) *is_unicode = 1; | ||
287 | } | ||
288 | |||
289 | /* hex-specified byte */ | ||
290 | else if ((ls <= 4) && (strncmp(s,"0x",2) == 0) && | ||
291 | (strspn(s+2,"0123456789abcdefABCDEF") == ls-2)) | ||
292 | sscanf(s+2,"%x",&i); | ||
293 | |||
294 | /* oct-specified number (byte) */ | ||
295 | else if ((*s == '0') && | ||
296 | (strspn(s,"01234567") == ls)) | ||
297 | sscanf(s,"%o",&i); | ||
298 | |||
299 | /* dec-specified number (byte) */ | ||
300 | else if (strspn(s,"0123456789") == ls) | ||
301 | sscanf(s,"%d",&i); | ||
302 | |||
303 | /* single-byte quoted char */ | ||
304 | else if ((strlen(s) == 3) && (s[0] == '\'') && (s[2] == '\'')) | ||
305 | i=s[1]; | ||
306 | |||
307 | /* multi-byte UTF8 quoted char */ | ||
308 | else if ((s[0] == '\'') && (s[ls-1] == '\'')) | ||
309 | { | ||
310 | s[ls-1] = 0; /* ensure we'll not "parse UTF too far" */ | ||
311 | i = utf8_to_ucs2(s+1); | ||
312 | if (is_unicode) *is_unicode = 1; | ||
313 | } | ||
314 | else | ||
315 | return(-1); | ||
316 | |||
317 | return(i); | ||
318 | } | ||
319 | |||
320 | |||
321 | void saveoldmap(int fd, char *omfil) | ||
322 | { | ||
323 | FILE *fp; | ||
324 | char buf[E_TABSZ]; | ||
325 | #ifdef GIO_UNISCRNMAP | ||
326 | unicode xbuf[E_TABSZ]; | ||
327 | int is_old_map = 0; | ||
328 | |||
329 | if (ioctl(fd,GIO_UNISCRNMAP,xbuf)) | ||
330 | { | ||
331 | perror("GIO_UNISCRNMAP ioctl error"); | ||
332 | #endif | ||
333 | if (ioctl(fd,GIO_SCRNMAP,buf)) | ||
334 | { | ||
335 | perror("GIO_SCRNMAP ioctl error"); | ||
336 | exit(1); | ||
337 | } | ||
338 | else | ||
339 | is_old_map = 1; | ||
340 | #ifdef GIO_UNISCRNMAP | ||
341 | } | ||
342 | #endif | ||
343 | |||
344 | if ((fp = fopen(omfil, "w")) == NULL) | ||
345 | { | ||
346 | perror(omfil); | ||
347 | exit(1); | ||
348 | } | ||
349 | |||
350 | #ifdef GIO_UNISCRNMAP | ||
351 | if (is_old_map) | ||
352 | { | ||
353 | #endif | ||
354 | if (fwrite(buf,E_TABSZ,1,fp) != 1) | ||
355 | { | ||
356 | perror("Error writing map to file"); | ||
357 | exit(1); | ||
358 | } | ||
359 | #ifdef GIO_UNISCRNMAP | ||
360 | } | ||
361 | else | ||
362 | if (fwrite(xbuf, sizeof(unicode) * E_TABSZ,1,fp) != 1) | ||
363 | { | ||
364 | perror("Error writing map to file"); | ||
365 | exit(1); | ||
366 | } | ||
367 | #endif | ||
368 | |||
369 | fclose(fp); | ||
370 | } | ||
371 | |||
372 | unicode utf8_to_ucs2 (char* buf) | ||
373 | { | ||
374 | int utf_count = 0; | ||
375 | long utf_char; | ||
376 | unicode tc; | ||
377 | unsigned char c; | ||
378 | |||
379 | do | ||
380 | { | ||
381 | c = *buf; | ||
382 | buf++; | ||
383 | |||
384 | /* if byte should be part of multi-byte sequence */ | ||
385 | if(c & 0x80) | ||
386 | { | ||
387 | /* if we have already started to parse a UTF8 sequence */ | ||
388 | if (utf_count > 0 && (c & 0xc0) == 0x80) | ||
389 | { | ||
390 | utf_char = (utf_char << 6) | (c & 0x3f); | ||
391 | utf_count--; | ||
392 | if (utf_count == 0) | ||
393 | tc = utf_char; | ||
394 | else | ||
395 | continue; | ||
396 | } | ||
397 | else /* Possibly 1st char of a UTF8 sequence */ | ||
398 | { | ||
399 | if ((c & 0xe0) == 0xc0) | ||
400 | { | ||
401 | utf_count = 1; | ||
402 | utf_char = (c & 0x1f); | ||
403 | } | ||
404 | else if ((c & 0xf0) == 0xe0) | ||
405 | { | ||
406 | utf_count = 2; | ||
407 | utf_char = (c & 0x0f); | ||
408 | } | ||
409 | else if ((c & 0xf8) == 0xf0) | ||
410 | { | ||
411 | utf_count = 3; | ||
412 | utf_char = (c & 0x07); | ||
413 | } | ||
414 | else if ((c & 0xfc) == 0xf8) | ||
415 | { | ||
416 | utf_count = 4; | ||
417 | utf_char = (c & 0x03); | ||
418 | } | ||
419 | else if ((c & 0xfe) == 0xfc) | ||
420 | { | ||
421 | utf_count = 5; | ||
422 | utf_char = (c & 0x01); | ||
423 | } | ||
424 | else | ||
425 | utf_count = 0; | ||
426 | continue; | ||
427 | } | ||
428 | } | ||
429 | else /* not part of multi-byte sequence - treat as ASCII | ||
430 | * this makes incomplete sequences to be ignored | ||
431 | */ | ||
432 | { | ||
433 | tc = c; | ||
434 | utf_count = 0; | ||
435 | } | ||
436 | } | ||
437 | while (utf_count); | ||
438 | |||
439 | return tc; | ||
440 | } | ||
441 | |||
diff --git a/internal.h b/internal.h index 05e3904e6..1e42982d3 100644 --- a/internal.h +++ b/internal.h | |||
@@ -130,6 +130,7 @@ extern int update_main(int argc, char** argv); | |||
130 | extern int uname_main(int argc, char** argv); | 130 | extern int uname_main(int argc, char** argv); |
131 | extern int gunzip_main (int argc, char** argv); | 131 | extern int gunzip_main (int argc, char** argv); |
132 | extern int gzip_main(int argc, char** argv); | 132 | extern int gzip_main(int argc, char** argv); |
133 | extern int loadacm_main(int argc, char** argv); | ||
133 | 134 | ||
134 | 135 | ||
135 | const char *modeString(int mode); | 136 | const char *modeString(int mode); |
diff --git a/loadacm.c b/loadacm.c new file mode 100644 index 000000000..491bc5ce8 --- /dev/null +++ b/loadacm.c | |||
@@ -0,0 +1,441 @@ | |||
1 | /* | ||
2 | * Derived from | ||
3 | * mapscrn.c - version 0.92 | ||
4 | * | ||
5 | * Was taken from console-tools and adapted by | ||
6 | * Peter Novodvorsky <petya@logic.ru> | ||
7 | */ | ||
8 | |||
9 | #include <stdio.h> | ||
10 | #include <stdlib.h> | ||
11 | #include <memory.h> | ||
12 | #include <string.h> | ||
13 | #include <unistd.h> | ||
14 | #include <fcntl.h> | ||
15 | #include <assert.h> | ||
16 | #include <errno.h> | ||
17 | #include <signal.h> | ||
18 | #include <sys/types.h> | ||
19 | #include <sys/stat.h> | ||
20 | #include <sys/ioctl.h> | ||
21 | #include <sys/kd.h> | ||
22 | |||
23 | typedef unsigned short unicode; | ||
24 | |||
25 | static long int ctoi(unsigned char *s, int *is_unicode); | ||
26 | int old_screen_map_read_ascii(FILE *fp, unsigned char buf[]); | ||
27 | int uni_screen_map_read_ascii(FILE *fp, unicode buf[], int* is_unicode); | ||
28 | unicode utf8_to_ucs2 (char* buf); | ||
29 | int screen_map_load(int fd, FILE *fp); | ||
30 | |||
31 | int loadacm_main(int argc, char **argv) | ||
32 | { | ||
33 | int fd; | ||
34 | |||
35 | fd = open("/dev/tty", O_RDWR); | ||
36 | if (fd < 0) { | ||
37 | fprintf(stderr, "Error opening /dev/tty1: %s\n", strerror(errno)); | ||
38 | return 1; | ||
39 | } | ||
40 | |||
41 | if (screen_map_load(fd, stdin)) | ||
42 | { | ||
43 | fprintf(stderr, "Error loading acm: %s\n", strerror(errno)); | ||
44 | return 1; | ||
45 | } | ||
46 | |||
47 | write(fd, "\033(K", 3); | ||
48 | |||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | int screen_map_load(int fd, FILE *fp) | ||
53 | { | ||
54 | struct stat stbuf; | ||
55 | unicode wbuf[E_TABSZ]; | ||
56 | unsigned char buf[E_TABSZ]; | ||
57 | int parse_failed = 0; | ||
58 | int is_unicode; | ||
59 | |||
60 | if (fstat(fp->_fileno, &stbuf)) | ||
61 | perror("Cannot stat map file"), exit(1); | ||
62 | |||
63 | /* first try a UTF screen-map: either ASCII (no restriction) or binary (regular file) */ | ||
64 | if (!(parse_failed = (-1 == uni_screen_map_read_ascii(fp,wbuf,&is_unicode))) || | ||
65 | (S_ISREG(stbuf.st_mode) && | ||
66 | (stbuf.st_size == (sizeof(unicode) * E_TABSZ)))) /* test for binary UTF map by size */ | ||
67 | { | ||
68 | if (parse_failed) | ||
69 | { | ||
70 | if (-1 == fseek (fp, 0, SEEK_SET)) | ||
71 | { | ||
72 | if (errno == ESPIPE) | ||
73 | fprintf (stderr, "16bit screen-map MUST be a regular file.\n"), exit (1); | ||
74 | else | ||
75 | perror ("fseek failed reading binary 16bit screen-map"), exit (1); | ||
76 | } | ||
77 | |||
78 | if (fread(wbuf, sizeof(unicode) * E_TABSZ, 1, fp) != 1) | ||
79 | perror("Cannot read [new] map from file"), exit(1); | ||
80 | #if 0 | ||
81 | else | ||
82 | fprintf(stderr, "Input screen-map is binary.\n"); | ||
83 | #endif | ||
84 | } | ||
85 | |||
86 | /* if it was effectively a 16-bit ASCII, OK, else try to read as 8-bit map */ | ||
87 | /* same if it was binary, ie. if parse_failed */ | ||
88 | if (parse_failed || is_unicode) | ||
89 | { | ||
90 | if (ioctl(fd,PIO_UNISCRNMAP,wbuf)) | ||
91 | perror("PIO_UNISCRNMAP ioctl"), exit(1); | ||
92 | else | ||
93 | return 0; | ||
94 | } | ||
95 | } | ||
96 | |||
97 | /* rewind... */ | ||
98 | if (-1 == fseek (fp, 0, SEEK_SET)) | ||
99 | { | ||
100 | if (errno == ESPIPE) | ||
101 | fprintf (stderr, "Assuming 8bit screen-map - MUST be a regular file.\n"), exit (1); | ||
102 | else | ||
103 | perror ("fseek failed assuming 8bit screen-map"), exit (1); | ||
104 | } | ||
105 | |||
106 | /* ... and try an old 8-bit screen-map */ | ||
107 | if (!(parse_failed = (-1 == old_screen_map_read_ascii(fp,buf))) || | ||
108 | (S_ISREG(stbuf.st_mode) && | ||
109 | (stbuf.st_size == E_TABSZ))) /* test for binary old 8-bit map by size */ | ||
110 | { | ||
111 | if (parse_failed) | ||
112 | { | ||
113 | if (-1 == fseek (fp, 0, SEEK_SET)) | ||
114 | { | ||
115 | if (errno == ESPIPE) | ||
116 | /* should not - it succedeed above */ | ||
117 | fprintf (stderr, "fseek() returned ESPIPE !\n"), exit (1); | ||
118 | else | ||
119 | perror ("fseek for binary 8bit screen-map"), exit (1); | ||
120 | } | ||
121 | |||
122 | if (fread(buf,E_TABSZ,1,fp) != 1) | ||
123 | perror("Cannot read [old] map from file"), exit(1); | ||
124 | #if 0 | ||
125 | else | ||
126 | fprintf(stderr, "Input screen-map is binary.\n"); | ||
127 | #endif | ||
128 | } | ||
129 | |||
130 | if (ioctl(fd,PIO_SCRNMAP,buf)) | ||
131 | perror("PIO_SCRNMAP ioctl"), exit(1); | ||
132 | else | ||
133 | return 0; | ||
134 | } | ||
135 | else | ||
136 | { | ||
137 | fprintf(stderr, "Error parsing symbolic map\n"); | ||
138 | exit(1); | ||
139 | } | ||
140 | } | ||
141 | |||
142 | |||
143 | /* | ||
144 | * - reads `fp' as a 16-bit ASCII SFM file. | ||
145 | * - returns -1 on error. | ||
146 | * - returns it in `unicode' in an E_TABSZ-elements array. | ||
147 | * - sets `*is_unicode' flagiff there were any non-8-bit | ||
148 | * (ie. real 16-bit) mapping. | ||
149 | * | ||
150 | * FIXME: ignores everything after second word | ||
151 | */ | ||
152 | int uni_screen_map_read_ascii(FILE *fp, unicode buf[], int *is_unicode) | ||
153 | { | ||
154 | char buffer[256]; /* line buffer reading file */ | ||
155 | char *p, *q; /* 1st + 2nd words in line */ | ||
156 | int in, on; /* the same, as numbers */ | ||
157 | int tmp_is_unicode; /* tmp for is_unicode calculation */ | ||
158 | int i; /* loop index - result holder */ | ||
159 | int ret_code = 0; /* return code */ | ||
160 | sigset_t sigset, old_sigset; | ||
161 | |||
162 | assert (is_unicode); | ||
163 | |||
164 | *is_unicode = 0; | ||
165 | |||
166 | /* first 128 codes defaults to ASCII */ | ||
167 | for (i=0; i<128; i++) buf[i] = i; | ||
168 | /* remaining defaults to replacement char (usually E_TABSZ = 256) */ | ||
169 | for ( ; i<E_TABSZ; i++) buf[i] = 0xfffd; | ||
170 | |||
171 | /* block SIGCHLD */ | ||
172 | sigemptyset (&sigset); | ||
173 | sigaddset (&sigset, SIGCHLD); | ||
174 | sigprocmask (SIG_BLOCK, &sigset, &old_sigset); | ||
175 | |||
176 | do | ||
177 | { | ||
178 | if (NULL == fgets(buffer, sizeof(buffer),fp)) | ||
179 | { | ||
180 | if (feof (fp)) | ||
181 | break; | ||
182 | else | ||
183 | { | ||
184 | perror ("uni_screen_map_read_ascii() can't read line"); | ||
185 | exit (2); | ||
186 | } | ||
187 | } | ||
188 | |||
189 | /* get "charset-relative charcode", stripping leading spaces */ | ||
190 | p = strtok(buffer," \t\n"); | ||
191 | |||
192 | /* skip empty lines and comments */ | ||
193 | if (!p || *p == '#') | ||
194 | continue; | ||
195 | |||
196 | /* get unicode mapping */ | ||
197 | q = strtok(NULL," \t\n"); | ||
198 | if (q) | ||
199 | { | ||
200 | in = ctoi(p, NULL); | ||
201 | if (in < 0 || in > 255) | ||
202 | { | ||
203 | ret_code = -1; | ||
204 | break; | ||
205 | } | ||
206 | |||
207 | on = ctoi(q, &tmp_is_unicode); | ||
208 | if (in < 0 && on > 65535) | ||
209 | { | ||
210 | ret_code = -1; | ||
211 | break; | ||
212 | } | ||
213 | |||
214 | *is_unicode |= tmp_is_unicode; | ||
215 | buf[in] = on; | ||
216 | } | ||
217 | else | ||
218 | { | ||
219 | ret_code = -1; | ||
220 | break; | ||
221 | } | ||
222 | } | ||
223 | while (1); /* terminated by break on feof() */ | ||
224 | |||
225 | /* restore sig mask */ | ||
226 | sigprocmask (SIG_SETMASK, &old_sigset, NULL); | ||
227 | |||
228 | return ret_code; | ||
229 | } | ||
230 | |||
231 | |||
232 | int old_screen_map_read_ascii(FILE *fp, unsigned char buf[]) | ||
233 | { | ||
234 | char buffer[256]; | ||
235 | int in, on; | ||
236 | char *p, *q; | ||
237 | |||
238 | for (in=0; in<256; in++) buf[in]=in; | ||
239 | |||
240 | while (fgets(buffer,sizeof(buffer)-1,fp)) | ||
241 | { | ||
242 | p = strtok(buffer," \t\n"); | ||
243 | |||
244 | if (!p || *p == '#') | ||
245 | continue; | ||
246 | |||
247 | q = strtok(NULL," \t\n#"); | ||
248 | if (q) | ||
249 | { | ||
250 | in = ctoi(p, NULL); | ||
251 | if (in < 0 || in > 255) return -1; | ||
252 | |||
253 | on = ctoi(q, NULL); | ||
254 | if (in < 0 && on > 255) return -1; | ||
255 | |||
256 | buf[in] = on; | ||
257 | } | ||
258 | else return -1; | ||
259 | } | ||
260 | |||
261 | return(0); | ||
262 | } | ||
263 | |||
264 | |||
265 | /* | ||
266 | * - converts a string into an int. | ||
267 | * - supports dec and hex bytes, hex UCS2, single-quoted byte and UTF8 chars. | ||
268 | * - returns the converted value | ||
269 | * - if `is_unicode != NULL', use it to tell whether it was unicode | ||
270 | * | ||
271 | * CAVEAT: will report valid UTF mappings using only 1 byte as 8-bit ones. | ||
272 | */ | ||
273 | long int ctoi(unsigned char *s, int *is_unicode) | ||
274 | { | ||
275 | int i; | ||
276 | size_t ls; | ||
277 | |||
278 | ls = strlen(s); | ||
279 | if (is_unicode) *is_unicode = 0; | ||
280 | |||
281 | /* hex-specified UCS2 */ | ||
282 | if ((strncmp(s,"U+",2) == 0) && | ||
283 | (strspn(s+2,"0123456789abcdefABCDEF") == ls-2)) | ||
284 | { | ||
285 | sscanf(s+2,"%x",&i); | ||
286 | if (is_unicode) *is_unicode = 1; | ||
287 | } | ||
288 | |||
289 | /* hex-specified byte */ | ||
290 | else if ((ls <= 4) && (strncmp(s,"0x",2) == 0) && | ||
291 | (strspn(s+2,"0123456789abcdefABCDEF") == ls-2)) | ||
292 | sscanf(s+2,"%x",&i); | ||
293 | |||
294 | /* oct-specified number (byte) */ | ||
295 | else if ((*s == '0') && | ||
296 | (strspn(s,"01234567") == ls)) | ||
297 | sscanf(s,"%o",&i); | ||
298 | |||
299 | /* dec-specified number (byte) */ | ||
300 | else if (strspn(s,"0123456789") == ls) | ||
301 | sscanf(s,"%d",&i); | ||
302 | |||
303 | /* single-byte quoted char */ | ||
304 | else if ((strlen(s) == 3) && (s[0] == '\'') && (s[2] == '\'')) | ||
305 | i=s[1]; | ||
306 | |||
307 | /* multi-byte UTF8 quoted char */ | ||
308 | else if ((s[0] == '\'') && (s[ls-1] == '\'')) | ||
309 | { | ||
310 | s[ls-1] = 0; /* ensure we'll not "parse UTF too far" */ | ||
311 | i = utf8_to_ucs2(s+1); | ||
312 | if (is_unicode) *is_unicode = 1; | ||
313 | } | ||
314 | else | ||
315 | return(-1); | ||
316 | |||
317 | return(i); | ||
318 | } | ||
319 | |||
320 | |||
321 | void saveoldmap(int fd, char *omfil) | ||
322 | { | ||
323 | FILE *fp; | ||
324 | char buf[E_TABSZ]; | ||
325 | #ifdef GIO_UNISCRNMAP | ||
326 | unicode xbuf[E_TABSZ]; | ||
327 | int is_old_map = 0; | ||
328 | |||
329 | if (ioctl(fd,GIO_UNISCRNMAP,xbuf)) | ||
330 | { | ||
331 | perror("GIO_UNISCRNMAP ioctl error"); | ||
332 | #endif | ||
333 | if (ioctl(fd,GIO_SCRNMAP,buf)) | ||
334 | { | ||
335 | perror("GIO_SCRNMAP ioctl error"); | ||
336 | exit(1); | ||
337 | } | ||
338 | else | ||
339 | is_old_map = 1; | ||
340 | #ifdef GIO_UNISCRNMAP | ||
341 | } | ||
342 | #endif | ||
343 | |||
344 | if ((fp = fopen(omfil, "w")) == NULL) | ||
345 | { | ||
346 | perror(omfil); | ||
347 | exit(1); | ||
348 | } | ||
349 | |||
350 | #ifdef GIO_UNISCRNMAP | ||
351 | if (is_old_map) | ||
352 | { | ||
353 | #endif | ||
354 | if (fwrite(buf,E_TABSZ,1,fp) != 1) | ||
355 | { | ||
356 | perror("Error writing map to file"); | ||
357 | exit(1); | ||
358 | } | ||
359 | #ifdef GIO_UNISCRNMAP | ||
360 | } | ||
361 | else | ||
362 | if (fwrite(xbuf, sizeof(unicode) * E_TABSZ,1,fp) != 1) | ||
363 | { | ||
364 | perror("Error writing map to file"); | ||
365 | exit(1); | ||
366 | } | ||
367 | #endif | ||
368 | |||
369 | fclose(fp); | ||
370 | } | ||
371 | |||
372 | unicode utf8_to_ucs2 (char* buf) | ||
373 | { | ||
374 | int utf_count = 0; | ||
375 | long utf_char; | ||
376 | unicode tc; | ||
377 | unsigned char c; | ||
378 | |||
379 | do | ||
380 | { | ||
381 | c = *buf; | ||
382 | buf++; | ||
383 | |||
384 | /* if byte should be part of multi-byte sequence */ | ||
385 | if(c & 0x80) | ||
386 | { | ||
387 | /* if we have already started to parse a UTF8 sequence */ | ||
388 | if (utf_count > 0 && (c & 0xc0) == 0x80) | ||
389 | { | ||
390 | utf_char = (utf_char << 6) | (c & 0x3f); | ||
391 | utf_count--; | ||
392 | if (utf_count == 0) | ||
393 | tc = utf_char; | ||
394 | else | ||
395 | continue; | ||
396 | } | ||
397 | else /* Possibly 1st char of a UTF8 sequence */ | ||
398 | { | ||
399 | if ((c & 0xe0) == 0xc0) | ||
400 | { | ||
401 | utf_count = 1; | ||
402 | utf_char = (c & 0x1f); | ||
403 | } | ||
404 | else if ((c & 0xf0) == 0xe0) | ||
405 | { | ||
406 | utf_count = 2; | ||
407 | utf_char = (c & 0x0f); | ||
408 | } | ||
409 | else if ((c & 0xf8) == 0xf0) | ||
410 | { | ||
411 | utf_count = 3; | ||
412 | utf_char = (c & 0x07); | ||
413 | } | ||
414 | else if ((c & 0xfc) == 0xf8) | ||
415 | { | ||
416 | utf_count = 4; | ||
417 | utf_char = (c & 0x03); | ||
418 | } | ||
419 | else if ((c & 0xfe) == 0xfc) | ||
420 | { | ||
421 | utf_count = 5; | ||
422 | utf_char = (c & 0x01); | ||
423 | } | ||
424 | else | ||
425 | utf_count = 0; | ||
426 | continue; | ||
427 | } | ||
428 | } | ||
429 | else /* not part of multi-byte sequence - treat as ASCII | ||
430 | * this makes incomplete sequences to be ignored | ||
431 | */ | ||
432 | { | ||
433 | tc = c; | ||
434 | utf_count = 0; | ||
435 | } | ||
436 | } | ||
437 | while (utf_count); | ||
438 | |||
439 | return tc; | ||
440 | } | ||
441 | |||
diff --git a/reg_test.sh b/reg_test.sh new file mode 100755 index 000000000..0a30ae305 --- /dev/null +++ b/reg_test.sh | |||
@@ -0,0 +1,136 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | |||
4 | |||
5 | rm -rf testdir | ||
6 | ./busybox cp tar.c testdir | ||
7 | |||
8 | if ! eval diff -u tar.c testdir ; then | ||
9 | echo " " | ||
10 | echo "Bummer. File copy failed." | ||
11 | exit 0 | ||
12 | else | ||
13 | echo "Cool. File copy is ok." | ||
14 | fi | ||
15 | echo " " | ||
16 | |||
17 | rm -rf testdir | ||
18 | mkdir -p testdir/foo | ||
19 | ./busybox cp tar.c testdir/foo | ||
20 | |||
21 | if ! eval diff -u tar.c testdir/foo/tar.c ; then | ||
22 | echo " " | ||
23 | echo "Bummer. File copy to a directory failed." | ||
24 | exit 0 | ||
25 | else | ||
26 | echo "Cool. File copy to a directory is ok." | ||
27 | fi | ||
28 | echo " " | ||
29 | |||
30 | |||
31 | rm -rf testdir | ||
32 | mkdir -p testdir/foo | ||
33 | ./busybox cp tar.c testdir/foo/ | ||
34 | |||
35 | if ! eval diff -u tar.c testdir/foo/tar.c ; then | ||
36 | echo " " | ||
37 | echo "Bummer. File copy to a directory w/ a '/' failed." | ||
38 | exit 0 | ||
39 | else | ||
40 | echo "Cool. File copy to a directory w/ a '/' is ok." | ||
41 | fi | ||
42 | echo " " | ||
43 | |||
44 | |||
45 | rm -rf testdir X11 | ||
46 | cp -a /etc/X11 . | ||
47 | ./busybox cp -a X11 testdir | ||
48 | |||
49 | if ! eval diff -ur X11 testdir ; then | ||
50 | echo " " | ||
51 | echo "Bummer. Local dir copy failed." | ||
52 | exit 0 | ||
53 | else | ||
54 | echo "Cool. Local dir copy is ok." | ||
55 | fi | ||
56 | echo " " | ||
57 | |||
58 | rm -rf testdir X11 | ||
59 | cp -a /etc/X11 . | ||
60 | ./busybox cp -a X11 testdir/ | ||
61 | |||
62 | if ! eval diff -ur X11 testdir ; then | ||
63 | echo " " | ||
64 | echo "Bummer. Local dir copy w/ a '/' failed." | ||
65 | exit 0 | ||
66 | else | ||
67 | echo "Cool. Local dir copy w/ a '/' is ok." | ||
68 | fi | ||
69 | echo " " | ||
70 | |||
71 | rm -rf testdir X11 | ||
72 | cp -a /etc/X11 . | ||
73 | ./busybox cp -a X11/ testdir | ||
74 | |||
75 | if ! eval diff -ur X11 testdir ; then | ||
76 | echo " " | ||
77 | echo "Bummer. Local dir copy w/ a src '/' failed." | ||
78 | exit 0 | ||
79 | else | ||
80 | echo "Cool. Local dir copy w/ a src '/' is ok." | ||
81 | fi | ||
82 | echo " " | ||
83 | |||
84 | rm -rf testdir X11 | ||
85 | cp -a /etc/X11 . | ||
86 | ./busybox cp -a X11/ testdir/ | ||
87 | |||
88 | if ! eval diff -ur X11 testdir ; then | ||
89 | echo " " | ||
90 | echo "Bummer. Local dir copy w/ 2x '/'s failed." | ||
91 | exit 0 | ||
92 | else | ||
93 | echo "Cool. Local dir copy w/ 2x '/'s is ok." | ||
94 | fi | ||
95 | echo " " | ||
96 | |||
97 | rm -rf testdir X11 | ||
98 | ./busybox cp -a /etc/X11 testdir | ||
99 | if ! eval diff -ur /etc/X11 testdir ; then | ||
100 | echo " " | ||
101 | echo "Bummer. Remote dir copy failed." | ||
102 | exit 0 | ||
103 | else | ||
104 | echo "Cool. Remote dir copy is ok." | ||
105 | fi | ||
106 | echo " " | ||
107 | |||
108 | |||
109 | rm -rf testdir X11 | ||
110 | mkdir -p testdir/foo | ||
111 | |||
112 | ./busybox cp -a /etc/X11 testdir/foo | ||
113 | if ! eval diff -ur /etc/X11 testdir/foo ; then | ||
114 | echo " " | ||
115 | echo "Bummer. Remote dir copy to a directory failed." | ||
116 | exit 0 | ||
117 | else | ||
118 | echo "Cool. Remote dir copy to a directory is ok." | ||
119 | fi | ||
120 | echo " " | ||
121 | |||
122 | |||
123 | rm -rf testdir X11 | ||
124 | mkdir -p testdir/foo | ||
125 | |||
126 | ./busybox cp -a /etc/X11 testdir/foo/ | ||
127 | if ! eval diff -ur /etc/X11 testdir/foo ; then | ||
128 | echo " " | ||
129 | echo "Bummer. Remote dir copy to a directory w/ a '/' failed." | ||
130 | exit 0 | ||
131 | else | ||
132 | echo "Cool. Remote dir copy to a directory w/ a '/' is ok." | ||
133 | fi | ||
134 | |||
135 | rm -rf testdir | ||
136 | |||
@@ -479,7 +479,7 @@ recursiveAction(const char *fileName, int recurse, int followLinks, int depthFir | |||
479 | 479 | ||
480 | 480 | ||
481 | 481 | ||
482 | #if defined (BB_TAR) || defined (BB_MKDIR) || defined (BB_CP) | 482 | #if defined (BB_TAR) || defined (BB_MKDIR) |
483 | /* | 483 | /* |
484 | * Attempt to create the directories along the specified path, except for | 484 | * Attempt to create the directories along the specified path, except for |
485 | * the final component. The mode is given for the final directory only, | 485 | * the final component. The mode is given for the final directory only, |