]> granicus.if.org Git - file/commitdiff
wide char strlen support. from debian
authorChristos Zoulas <christos@zoulas.com>
Mon, 22 Mar 2004 19:12:15 +0000 (19:12 +0000)
committerChristos Zoulas <christos@zoulas.com>
Mon, 22 Mar 2004 19:12:15 +0000 (19:12 +0000)
src/file.c
src/file.h

index ca259b94ee30e02c304bb8d199fabba619fabb46..0c61439281ef8c87577d3df1de948f58e1f82797 100644 (file)
@@ -62,6 +62,9 @@
 #ifdef HAVE_LOCALE_H
 #include <locale.h>
 #endif
+#ifdef HAVE_WCHAR_T
+#include <wchar.h>
+#endif
 
 #ifdef HAVE_GETOPT_H
 #include <getopt.h>    /* for long options (is this portable?)*/
@@ -74,7 +77,7 @@
 #include "patchlevel.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$Id: file.c,v 1.90 2004/03/03 17:24:28 christos Exp $")
+FILE_RCSID("@(#)$Id: file.c,v 1.91 2004/03/22 19:12:15 christos Exp $")
 #endif /* lint */
 
 
@@ -304,7 +307,7 @@ main(int argc, char *argv[])
        else {
                int i, wid, nw;
                for (wid = 0, i = optind; i < argc; i++) {
-                       nw = strlen(argv[i]);
+                       nw = file_mbswidth(argv[i]);
                        if (nw > wid)
                                wid = nw;
                }
@@ -354,7 +357,7 @@ unwrap(char *fn)
                }
 
                while (fgets(buf, MAXPATHLEN, f) != NULL) {
-                       cwid = strlen(buf) - 1;
+                       cwid = file_mbswidth(buf) - 1;
                        if (cwid > wid)
                                wid = cwid;
                }
@@ -363,7 +366,7 @@ unwrap(char *fn)
        }
 
        while (fgets(buf, MAXPATHLEN, f) != NULL) {
-               buf[strlen(buf)-1] = '\0';
+               buf[file_mbswidth(buf)-1] = '\0';
                process(buf, wid);
                if(nobuffer)
                        (void) fflush(stdout);
@@ -380,7 +383,7 @@ process(const char *inname, int wid)
 
        if (wid > 0 && !bflag)
                (void) printf("%s%s%*s ", std_in ? "/dev/stdin" : inname,
-                   separator, (int) (nopad ? 0 : (wid - strlen(inname))), "");
+                   separator, (int) (nopad ? 0 : (wid - file_mbswidth(inname))), "");
 
        type = magic_file(magic, std_in ? NULL : inname);
        if (type == NULL)
@@ -447,6 +450,40 @@ byteconv2(int from, int same, int big_endian)
 }
 #endif
 
+size_t
+file_mbswidth(const char *s)
+{
+#ifdef HAVE_WCHAR_H
+       size_t bytesconsumed, old_n, n, width = 0;
+       mbstate_t state;
+       wchar_t nextchar;
+       (void)memset(&state, 0, sizeof(mbstate_t));
+       old_n = n = strlen(s);
+
+       while (n > 0) {
+               bytesconsumed = mbrtowc(&nextchar, s, n, &state);
+               if (bytesconsumed == (size_t)(-1) ||
+                   bytesconsumed == (size_t)(-2)) {
+                       /* Something went wrong, return something reasonable */
+                       return old_n;
+               }
+               if (s[0] == '\n') {
+                       /*
+                        * do what strlen() would do, so that caller
+                        * is always right
+                        */
+                       width++;
+               } else
+                       width += wcwidth(nextchar);
+
+               s += bytesconsumed, n -= bytesconsumed;
+       }
+       return width;
+#else
+       return strlen(s);
+#endif
+}
+
 private void
 usage(void)
 {
index 86344f53a1e0e98be5487693fa4c4f8f3f5a03a5..abdbdd9f600e9858823a31ac83769132c061face 100644 (file)
@@ -32,7 +32,7 @@
  */
 /*
  * file.h - definitions for file(1) program
- * @(#)$Id: file.h,v 1.59 2003/10/14 19:17:17 christos Exp $
+ * @(#)$Id: file.h,v 1.60 2004/03/22 19:12:15 christos Exp $
  */
 
 #ifndef __file_h__
@@ -214,6 +214,7 @@ protected void file_error(struct magic_set *, int, const char *, ...);
 protected void file_magwarn(const char *, ...);
 protected void file_mdump(struct magic *);
 protected void file_showstr(FILE *, const char *, size_t);
+protected size_t file_mbswidth(const char *);
 protected const char *file_getbuffer(struct magic_set *);
 
 #ifndef HAVE_STRERROR