aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
Diffstat (limited to 'libbb')
-rw-r--r--libbb/lineedit.c9
-rw-r--r--libbb/read.c53
-rw-r--r--libbb/unicode.c17
3 files changed, 56 insertions, 23 deletions
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index f7faf4639..ab418c0ab 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -1000,7 +1000,7 @@ static void showfiles(void)
1000 1000
1001 /* find the longest file name - use that as the column width */ 1001 /* find the longest file name - use that as the column width */
1002 for (row = 0; row < nrows; row++) { 1002 for (row = 0; row < nrows; row++) {
1003 l = unicode_strlen(matches[row]); 1003 l = unicode_strwidth(matches[row]);
1004 if (column_width < l) 1004 if (column_width < l)
1005 column_width = l; 1005 column_width = l;
1006 } 1006 }
@@ -1020,10 +1020,13 @@ static void showfiles(void)
1020 1020
1021 for (nc = 1; nc < ncols && n+nrows < nfiles; n += nrows, nc++) { 1021 for (nc = 1; nc < ncols && n+nrows < nfiles; n += nrows, nc++) {
1022 printf("%s%-*s", matches[n], 1022 printf("%s%-*s", matches[n],
1023 (int)(column_width - unicode_strlen(matches[n])), "" 1023 (int)(column_width - unicode_strwidth(matches[n])), ""
1024 ); 1024 );
1025 } 1025 }
1026 puts(matches[n]); 1026 if (ENABLE_UNICODE_SUPPORT)
1027 puts(printable_string(NULL, matches[n]));
1028 else
1029 puts(matches[n]);
1027 } 1030 }
1028} 1031}
1029 1032
diff --git a/libbb/read.c b/libbb/read.c
index f3af144f0..cd6bbeb13 100644
--- a/libbb/read.c
+++ b/libbb/read.c
@@ -305,22 +305,26 @@ void* FAST_FUNC xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p)
305 return buf; 305 return buf;
306} 306}
307 307
308/* Used by e.g. rpm which gives us a fd without filename,
309 * thus we can't guess the format from filename's extension.
310 */
308#if ZIPPED 311#if ZIPPED
309int FAST_FUNC setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/) 312void FAST_FUNC setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/)
310{ 313{
311 const int fail_if_not_detected = 1; 314 const int fail_if_not_detected = 1;
312 unsigned char magic[2]; 315 unsigned char magic[8];
313#if BB_MMU 316 int offset = -2;
317# if BB_MMU
314 IF_DESKTOP(long long) int FAST_FUNC (*xformer)(int src_fd, int dst_fd); 318 IF_DESKTOP(long long) int FAST_FUNC (*xformer)(int src_fd, int dst_fd);
315 enum { xformer_prog = 0 }; 319 enum { xformer_prog = 0 };
316#else 320# else
317 enum { xformer = 0 }; 321 enum { xformer = 0 };
318 const char *xformer_prog; 322 const char *xformer_prog;
319#endif 323# endif
320 324
321 /* .gz and .bz2 both have 2-byte signature, and their 325 /* .gz and .bz2 both have 2-byte signature, and their
322 * unpack_XXX_stream wants this header skipped. */ 326 * unpack_XXX_stream wants this header skipped. */
323 xread(fd, &magic, 2); 327 xread(fd, magic, 2);
324 if (ENABLE_FEATURE_SEAMLESS_GZ 328 if (ENABLE_FEATURE_SEAMLESS_GZ
325 && magic[0] == 0x1f && magic[1] == 0x8b 329 && magic[0] == 0x1f && magic[1] == 0x8b
326 ) { 330 ) {
@@ -341,28 +345,41 @@ int FAST_FUNC setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/)
341# endif 345# endif
342 goto found_magic; 346 goto found_magic;
343 } 347 }
344// TODO: xz format support. rpm adopted it, "rpm -i FILE.rpm" badly needs this. 348 if (ENABLE_FEATURE_SEAMLESS_XZ
345// Signature: 0xFD, '7', 'z', 'X', 'Z', 0x00 349 && magic[0] == 0xfd && magic[1] == '7'
346// More info at: http://tukaani.org/xz/xz-file-format.txt 350 ) {
351 /* .xz signature: 0xfd, '7', 'z', 'X', 'Z', 0x00 */
352 /* More info at: http://tukaani.org/xz/xz-file-format.txt */
353 offset = -6;
354 xread(fd, magic + 2, 4);
355 if (strcmp((char*)magic + 2, "zXZ") == 0) {
356# if BB_MMU
357 xformer = unpack_xz_stream;
358# else
359 xformer_prog = "unxz";
360# endif
361 xlseek(fd, offset, SEEK_CUR);
362 goto found_magic;
363 }
364 }
347 365
348 /* No known magic seen */ 366 /* No known magic seen */
349 if (fail_if_not_detected) 367 if (fail_if_not_detected)
350 bb_error_msg_and_die("no gzip" 368 bb_error_msg_and_die("no gzip"
351 IF_FEATURE_SEAMLESS_BZ2("/bzip2") 369 IF_FEATURE_SEAMLESS_BZ2("/bzip2")
370 IF_FEATURE_SEAMLESS_XZ("/xz")
352 " magic"); 371 " magic");
353 xlseek(fd, -2, SEEK_CUR); 372 xlseek(fd, offset, SEEK_CUR);
354 return fd; 373 return;
355 374
356 found_magic: 375 found_magic:
357# if !BB_MMU 376# if !BB_MMU
358 /* NOMMU version of open_transformer execs 377 /* NOMMU version of open_transformer execs
359 * an external unzipper that wants 378 * an external unzipper that wants
360 * file position at the start of the file */ 379 * file position at the start of the file */
361 xlseek(fd, -2, SEEK_CUR); 380 xlseek(fd, offset, SEEK_CUR);
362# endif 381# endif
363 open_transformer(fd, xformer, xformer_prog); 382 open_transformer(fd, xformer, xformer_prog);
364
365 return fd;
366} 383}
367#endif /* ZIPPED */ 384#endif /* ZIPPED */
368 385
@@ -380,12 +397,14 @@ int FAST_FUNC open_zipped(const char *fname)
380 397
381 sfx = strrchr(fname, '.'); 398 sfx = strrchr(fname, '.');
382 if (sfx) { 399 if (sfx) {
383 if (ENABLE_FEATURE_SEAMLESS_LZMA && strcmp(sfx, ".lzma") == 0) 400 sfx++;
401 if (ENABLE_FEATURE_SEAMLESS_LZMA && strcmp(sfx, "lzma") == 0)
384 /* .lzma has no header/signature, just trust it */ 402 /* .lzma has no header/signature, just trust it */
385 open_transformer(fd, unpack_lzma_stream, "unlzma"); 403 open_transformer(fd, unpack_lzma_stream, "unlzma");
386 else 404 else
387 if ((ENABLE_FEATURE_SEAMLESS_GZ && strcmp(sfx, ".gz") == 0) 405 if ((ENABLE_FEATURE_SEAMLESS_GZ && strcmp(sfx, "gz") == 0)
388 || (ENABLE_FEATURE_SEAMLESS_BZ2 && strcmp(sfx, ".bz2") == 0) 406 || (ENABLE_FEATURE_SEAMLESS_BZ2 && strcmp(sfx, "bz2") == 0)
407 || (ENABLE_FEATURE_SEAMLESS_XZ && strcmp(sfx, "xz") == 0)
389 ) { 408 ) {
390 setup_unzip_on_fd(fd /*, fail_if_not_detected: 1*/); 409 setup_unzip_on_fd(fd /*, fail_if_not_detected: 1*/);
391 } 410 }
diff --git a/libbb/unicode.c b/libbb/unicode.c
index b2c28239b..d6fcf7a43 100644
--- a/libbb/unicode.c
+++ b/libbb/unicode.c
@@ -25,13 +25,15 @@ uint8_t unicode_status;
25 25
26void FAST_FUNC init_unicode(void) 26void FAST_FUNC init_unicode(void)
27{ 27{
28 /* In unicode, this is a one character string */
29 static const char unicode_0x394[] = { 0xce, 0x94, 0 }; 28 static const char unicode_0x394[] = { 0xce, 0x94, 0 };
29 size_t width;
30 30
31 if (unicode_status != UNICODE_UNKNOWN) 31 if (unicode_status != UNICODE_UNKNOWN)
32 return; 32 return;
33 33 /* In unicode, this is a one character string */
34 unicode_status = unicode_strlen(unicode_0x394) == 1 ? UNICODE_ON : UNICODE_OFF; 34// can use unicode_strlen(string) too, but otherwise unicode_strlen() is unused
35 width = mbstowcs(NULL, unicode_0x394, INT_MAX);
36 unicode_status = (width == 1 ? UNICODE_ON : UNICODE_OFF);
35} 37}
36 38
37#else 39#else
@@ -954,6 +956,7 @@ int FAST_FUNC unicode_bidi_is_neutral_wchar(wint_t wc)
954 956
955/* The rest is mostly same for libc and for "homegrown" support */ 957/* The rest is mostly same for libc and for "homegrown" support */
956 958
959#if 0 // UNUSED
957size_t FAST_FUNC unicode_strlen(const char *string) 960size_t FAST_FUNC unicode_strlen(const char *string)
958{ 961{
959 size_t width = mbstowcs(NULL, string, INT_MAX); 962 size_t width = mbstowcs(NULL, string, INT_MAX);
@@ -961,6 +964,14 @@ size_t FAST_FUNC unicode_strlen(const char *string)
961 return strlen(string); 964 return strlen(string);
962 return width; 965 return width;
963} 966}
967#endif
968
969size_t FAST_FUNC unicode_strwidth(const char *string)
970{
971 uni_stat_t uni_stat;
972 printable_string(&uni_stat, string);
973 return uni_stat.unicode_width;
974}
964 975
965static char* FAST_FUNC unicode_conv_to_printable2(uni_stat_t *stats, const char *src, unsigned width, int flags) 976static char* FAST_FUNC unicode_conv_to_printable2(uni_stat_t *stats, const char *src, unsigned width, int flags)
966{ 977{