Skip to content

Commit

Permalink
PR/362: ro-ee: fix wide char printing
Browse files Browse the repository at this point in the history
  • Loading branch information
zoulasc committed Jul 4, 2022
1 parent 642895b commit c80065f
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 23 deletions.
88 changes: 69 additions & 19 deletions src/file.c
Expand Up @@ -32,7 +32,7 @@
#include "file.h"

#ifndef lint
FILE_RCSID("@(#)$File: file.c,v 1.196 2022/07/04 17:00:51 christos Exp $")
FILE_RCSID("@(#)$File: file.c,v 1.197 2022/07/04 19:44:35 christos Exp $")
#endif /* lint */

#include "magic.h"
Expand Down Expand Up @@ -60,6 +60,12 @@ FILE_RCSID("@(#)$File: file.c,v 1.196 2022/07/04 17:00:51 christos Exp $")
#ifdef HAVE_WCTYPE_H
#include <wctype.h>
#endif
#if defined(HAVE_WCHAR_H) && defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH) && \
defined(HAVE_WCTYPE_H)
#define FILE_WIDE_SUPPORT
#else
#include <ctype.h>
#endif

#if defined(HAVE_GETOPT_H) && defined(HAVE_STRUCT_OPTION)
# include <getopt.h>
Expand Down Expand Up @@ -550,6 +556,55 @@ out: file_err(EXIT_FAILURE, "Cannot allocate memory for file list");
return e;
}

private void
file_octal(unsigned char c)
{
putc('\\', stdout);
putc(((c >> 6) & 7) + '0', stdout);
putc(((c >> 3) & 7) + '0', stdout);
putc(((c >> 0) & 7) + '0', stdout);
}

private void
fname_print(const char *inname)
{
size_t n = strlen(inname);
#ifdef FILE_WIDE_SUPPORT
mbstate_t state;
wchar_t nextchar;
size_t bytesconsumed;


(void)mbrlen(NULL, 0, &state);
while (n > 0) {
bytesconsumed = mbrtowc(&nextchar, inname, n, &state);
if (bytesconsumed == CAST(size_t, -1) ||
bytesconsumed == CAST(size_t, -2)) {
nextchar = *inname;
bytesconsumed = 1;
}
inname += bytesconsumed;
n -= bytesconsumed;
if (iswprint(nextchar)) {
putwc(nextchar, stdout);
continue;
}
/* XXX: What if it is > 255? */
file_octal(CAST(unsigned char, nextchar));
}
#else
size_t i;
for (i = 0; i < n; i++) {
unsigned char c = CAST(unsigned char, inname[i]);
if (isprint(c)) {
putc(c);
continue;
}
file_octal(c);
}
#endif
}

/*
* Called for each input file on the command line (or in a list of files)
*/
Expand All @@ -559,15 +614,13 @@ process(struct magic_set *ms, const char *inname, int wid)
const char *type, c = nulsep > 1 ? '\0' : '\n';
int std_in = strcmp(inname, "-") == 0;
int haderror = 0;
size_t plen = 4 * wid + 1;
char *pbuf, *pname;

if ((pbuf = CAST(char *, malloc(plen))) == NULL)
file_err(EXIT_FAILURE, "Can't allocate %zu bytes", plen);

if (wid > 0 && !bflag) {
pname = file_printable(ms, pbuf, plen, inname, wid);
(void)printf("%s", std_in ? "/dev/stdin" : pname);
const char *pname = std_in ? "/dev/stdin" : inname;
if ((ms->flags & MAGIC_RAW) == 0)
fname_print(pname);
else
(void)printf("%s", pname);
if (nulsep)
(void)putc('\0', stdout);
if (nulsep < 2) {
Expand All @@ -586,43 +639,40 @@ process(struct magic_set *ms, const char *inname, int wid)
}
if (nobuffer)
haderror |= fflush(stdout) != 0;
free(pbuf);
return haderror || type == NULL;
}

protected size_t
file_mbswidth(struct magic_set *ms, const char *s)
{
size_t width = 0;
#if defined(HAVE_WCHAR_H) && defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH) && \
defined(HAVE_WCTYPE_H)
size_t bytesconsumed, old_n, n;
#ifdef FILE_WIDE_SUPPORT
size_t bytesconsumed, n;
mbstate_t state;
wchar_t nextchar;
(void)memset(&state, 0, sizeof(mbstate_t));
old_n = n = strlen(s);

(void)mbrlen(NULL, 0, &state);
n = strlen(s);

while (n > 0) {
bytesconsumed = mbrtowc(&nextchar, s, n, &state);
if (bytesconsumed == CAST(size_t, -1) ||
bytesconsumed == CAST(size_t, -2)) {
/* Something went wrong, return something reasonable */
return old_n;
nextchar = *s;
bytesconsumed = 1;
}
width += ((ms->flags & MAGIC_RAW) != 0
|| iswprint(nextchar)) ? wcwidth(nextchar) : 4;

s += bytesconsumed, n -= bytesconsumed;
}
return width;
#else
while (*s) {
width += (ms->flags & MAGIC_RAW) != 0
|| isprint(CAST(unsigned char, *s)) ? 1 : 4;
}

return strlen(s);
#endif
return width;
}

private void
Expand Down
4 changes: 2 additions & 2 deletions src/file.h
Expand Up @@ -27,7 +27,7 @@
*/
/*
* file.h - definitions for file(1) program
* @(#)$File: file.h,v 1.234 2022/05/28 20:24:09 christos Exp $
* @(#)$File: file.h,v 1.235 2022/07/04 19:44:35 christos Exp $
*/

#ifndef __file_h__
Expand Down Expand Up @@ -575,7 +575,7 @@ protected size_t file_pstring_length_size(struct magic_set *,
const struct magic *);
protected size_t file_pstring_get_length(struct magic_set *,
const struct magic *, const char *);
public char * file_printable(struct magic_set *, char *, size_t,
protected char * file_printable(struct magic_set *, char *, size_t,
const char *, size_t);
#ifdef __EMX__
protected int file_os2_apptype(struct magic_set *, const char *, const void *,
Expand Down
4 changes: 2 additions & 2 deletions src/funcs.c
Expand Up @@ -27,7 +27,7 @@
#include "file.h"

#ifndef lint
FILE_RCSID("@(#)$File: funcs.c,v 1.129 2022/05/28 20:24:09 christos Exp $")
FILE_RCSID("@(#)$File: funcs.c,v 1.130 2022/07/04 19:44:35 christos Exp $")
#endif /* lint */

#include "magic.h"
Expand Down Expand Up @@ -763,7 +763,7 @@ file_pop_buffer(struct magic_set *ms, file_pushbuf_t *pb)
/*
* convert string to ascii printable format.
*/
public char *
protected char *
file_printable(struct magic_set *ms, char *buf, size_t bufsiz,
const char *str, size_t slen)
{
Expand Down

0 comments on commit c80065f

Please sign in to comment.