Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 22 Sep 2016 16:47:00 +0000 (UTC)
From:      "Andrey A. Chernov" <ache@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r306200 - stable/10/bin/cat
Message-ID:  <201609221647.u8MGl0bN095772@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ache
Date: Thu Sep 22 16:46:59 2016
New Revision: 306200
URL: https://svnweb.freebsd.org/changeset/base/306200

Log:
  MFC r305841
  
  Implement multibyte encoding support for -v with fallback

Modified:
  stable/10/bin/cat/cat.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/bin/cat/cat.c
==============================================================================
--- stable/10/bin/cat/cat.c	Thu Sep 22 16:05:19 2016	(r306199)
+++ stable/10/bin/cat/cat.c	Thu Sep 22 16:46:59 2016	(r306200)
@@ -63,6 +63,8 @@ __FBSDID("$FreeBSD$");
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <wchar.h>
+#include <wctype.h>
 
 static int bflag, eflag, lflag, nflag, sflag, tflag, vflag;
 static int rval;
@@ -205,6 +207,7 @@ static void
 cook_cat(FILE *fp)
 {
 	int ch, gobble, line, prev;
+	wint_t wch;
 
 	/* Reset EOF condition on stdin. */
 	if (fp == stdin && feof(stdin))
@@ -237,18 +240,40 @@ cook_cat(FILE *fp)
 				continue;
 			}
 		} else if (vflag) {
-			if (!isascii(ch) && !isprint(ch)) {
+			(void)ungetc(ch, fp);
+			/*
+			 * Our getwc(3) doesn't change file position
+			 * on error.
+			 */
+			if ((wch = getwc(fp)) == WEOF) {
+				if (ferror(fp) && errno == EILSEQ) {
+					clearerr(fp);
+					/* Resync attempt. */
+					memset(&fp->_mbstate, 0, sizeof(mbstate_t));
+					if ((ch = getc(fp)) == EOF)
+						break;
+					wch = ch;
+					goto ilseq;
+				} else
+					break;
+			}
+			if (!iswascii(wch) && !iswprint(wch)) {
+ilseq:
 				if (putchar('M') == EOF || putchar('-') == EOF)
 					break;
-				ch = toascii(ch);
+				wch = toascii(wch);
 			}
-			if (iscntrl(ch)) {
-				if (putchar('^') == EOF ||
-				    putchar(ch == '\177' ? '?' :
-				    ch | 0100) == EOF)
+			if (iswcntrl(wch)) {
+				ch = toascii(wch);
+				ch = (ch == '\177') ? '?' : (ch | 0100);
+				if (putchar('^') == EOF || putchar(ch) == EOF)
 					break;
 				continue;
 			}
+			if (putwchar(wch) == WEOF)
+				break;
+			ch = -1;
+			continue;
 		}
 		if (putchar(ch) == EOF)
 			break;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201609221647.u8MGl0bN095772>