summaryrefslogtreecommitdiffstats
path: root/bin/ls
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2015-06-10 01:27:38 +0000
committermarcel <marcel@FreeBSD.org>2015-06-10 01:27:38 +0000
commitd404130e6a5621f7c5a8fbde7c83f5b8f6645dea (patch)
tree041dc508d6d48aab9392307a5db18596fac84fd6 /bin/ls
parentf92ed4607337cadd40fda365acfe1e1194f38b73 (diff)
downloadFreeBSD-src-d404130e6a5621f7c5a8fbde7c83f5b8f6645dea.zip
FreeBSD-src-d404130e6a5621f7c5a8fbde7c83f5b8f6645dea.tar.gz
Convert ls(1) to use libxo(3).
Obtained from: Phil Shafer <phil@juniper.net> Sponsored by: Juniper Networks, Inc.
Diffstat (limited to 'bin/ls')
-rw-r--r--bin/ls/Makefile2
-rw-r--r--bin/ls/extern.h11
-rw-r--r--bin/ls/ls.15
-rw-r--r--bin/ls/ls.c54
-rw-r--r--bin/ls/print.c170
-rw-r--r--bin/ls/util.c52
6 files changed, 190 insertions, 104 deletions
diff --git a/bin/ls/Makefile b/bin/ls/Makefile
index 58206e0..3349b7a 100644
--- a/bin/ls/Makefile
+++ b/bin/ls/Makefile
@@ -10,7 +10,7 @@ LIBADD= util
.if !defined(RELEASE_CRUNCH) && \
${MK_LS_COLORS} != no
CFLAGS+= -DCOLORLS
-LIBADD+= termcapw
+LIBADD+= termcapw xo
.endif
.include <bsd.prog.mk>
diff --git a/bin/ls/extern.h b/bin/ls/extern.h
index 90a20a8..e4b5059 100644
--- a/bin/ls/extern.h
+++ b/bin/ls/extern.h
@@ -45,14 +45,17 @@ int revsizecmp(const FTSENT *, const FTSENT *);
void printcol(const DISPLAY *);
void printlong(const DISPLAY *);
-int printname(const char *);
+int printname(const char *, const char *);
void printscol(const DISPLAY *);
void printstream(const DISPLAY *);
void usage(void);
-int prn_normal(const char *);
+int prn_normal(const char *, const char *);
+char * getname(const char *);
size_t len_octal(const char *, int);
-int prn_octal(const char *);
-int prn_printable(const char *);
+int prn_octal(const char *, const char *);
+char * get_octal(const char *);
+int prn_printable(const char *, const char *);
+char * get_printable(const char *);
#ifdef COLORLS
void parsecolors(const char *cs);
void colorquit(int);
diff --git a/bin/ls/ls.1 b/bin/ls/ls.1
index ee8e4ff..3e02229 100644
--- a/bin/ls/ls.1
+++ b/bin/ls/ls.1
@@ -32,7 +32,7 @@
.\" @(#)ls.1 8.7 (Berkeley) 7/29/94
.\" $FreeBSD$
.\"
-.Dd April 4, 2014
+.Dd June 8, 2015
.Dt LS 1
.Os
.Sh NAME
@@ -40,6 +40,7 @@
.Nd list directory contents
.Sh SYNOPSIS
.Nm
+.Op Fl -libxo
.Op Fl ABCFGHILPRSTUWZabcdfghiklmnopqrstuwxy1,
.Op Fl D Ar format
.Op Ar
@@ -797,9 +798,11 @@ specification.
.Xr getfacl 1 ,
.Xr sort 1 ,
.Xr xterm 1 ,
+.Xr libxo 3 ,
.Xr localeconv 3 ,
.Xr strftime 3 ,
.Xr strmode 3 ,
+.Xr xo_parse_args 3 ,
.Xr termcap 5 ,
.Xr maclabel 7 ,
.Xr sticky 7 ,
diff --git a/bin/ls/ls.c b/bin/ls/ls.c
index 74276c1..926d2bc 100644
--- a/bin/ls/ls.c
+++ b/bin/ls/ls.c
@@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$");
#include <termcap.h>
#include <signal.h>
#endif
+#include <libxo/xo.h>
#include "ls.h"
#include "extern.h"
@@ -185,6 +186,12 @@ main(int argc, char *argv[])
fts_options = FTS_PHYSICAL;
if (getenv("LS_SAMESORT"))
f_samesort = 1;
+
+ argc = xo_parse_args(argc, argv);
+ if (argc < 0)
+ return (1);
+ xo_set_flags(NULL, XOF_COLUMNS);
+
while ((ch = getopt(argc, argv,
"1ABCD:FGHILPRSTUWXZabcdfghiklmnopqrstuwxy,")) != -1) {
switch (ch) {
@@ -381,7 +388,7 @@ main(int argc, char *argv[])
f_color = 1;
}
#else
- warnx("color support not compiled in");
+ xo_warnx("color support not compiled in");
#endif /*COLORLS*/
#ifdef COLORLS
@@ -479,10 +486,13 @@ main(int argc, char *argv[])
else
printfcn = printcol;
+ xo_open_container("file-information");
if (argc)
traverse(argc, argv, fts_options);
else
traverse(1, dotav, fts_options);
+ xo_close_container("file-information");
+ xo_finish();
exit(rval);
}
@@ -500,10 +510,11 @@ traverse(int argc, char *argv[], int options)
FTS *ftsp;
FTSENT *p, *chp;
int ch_options;
+ int first = 1;
if ((ftsp =
fts_open(argv, options, f_nosort ? NULL : mastercmp)) == NULL)
- err(1, "fts_open");
+ xo_err(1, "fts_open");
/*
* We ignore errors from fts_children here since they will be
@@ -525,11 +536,11 @@ traverse(int argc, char *argv[], int options)
while ((p = fts_read(ftsp)) != NULL)
switch (p->fts_info) {
case FTS_DC:
- warnx("%s: directory causes a cycle", p->fts_name);
+ xo_warnx("%s: directory causes a cycle", p->fts_name);
break;
case FTS_DNR:
case FTS_ERR:
- warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
+ xo_warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
rval = 1;
break;
case FTS_D:
@@ -537,31 +548,40 @@ traverse(int argc, char *argv[], int options)
p->fts_name[0] == '.' && !f_listdot)
break;
+ if (first) {
+ first = 0;
+ xo_open_list("directory");
+ }
+ xo_open_instance("directory");
+
/*
* If already output something, put out a newline as
* a separator. If multiple arguments, precede each
* directory with its name.
*/
if (output) {
- putchar('\n');
- (void)printname(p->fts_path);
- puts(":");
+ xo_emit("\n");
+ (void)printname("path", p->fts_path);
+ xo_emit(":\n");
} else if (argc > 1) {
- (void)printname(p->fts_path);
- puts(":");
+ (void)printname("path", p->fts_path);
+ xo_emit(":\n");
output = 1;
}
chp = fts_children(ftsp, ch_options);
display(p, chp, options);
+ xo_close_instance("directory");
if (!f_recursive && chp != NULL)
(void)fts_set(ftsp, p, FTS_SKIP);
break;
default:
break;
}
+ if (!first)
+ xo_close_list("directory");
if (errno)
- err(1, "fts_read");
+ xo_err(1, "fts_read");
}
/*
@@ -608,7 +628,7 @@ display(const FTSENT *p, FTSENT *list, int options)
/* Fill-in "::" as "0:0:0" for the sake of scanf. */
jinitmax = malloc(strlen(initmax) * 2 + 2);
if (jinitmax == NULL)
- err(1, "malloc");
+ xo_err(1, "malloc");
initmax2 = jinitmax;
if (*initmax == ':')
strcpy(initmax2, "0:"), initmax2 += 2;
@@ -679,7 +699,7 @@ display(const FTSENT *p, FTSENT *list, int options)
flags = NULL;
for (cur = list, entries = 0; cur; cur = cur->fts_link) {
if (cur->fts_info == FTS_ERR || cur->fts_info == FTS_NS) {
- warnx("%s: %s",
+ xo_warnx("%s: %s",
cur->fts_name, strerror(cur->fts_errno));
cur->fts_number = NO_PRINT;
rval = 1;
@@ -745,7 +765,7 @@ display(const FTSENT *p, FTSENT *list, int options)
flags = strdup("-");
}
if (flags == NULL)
- err(1, "fflagstostr");
+ xo_err(1, "fflagstostr");
flen = strlen(flags);
if (flen > (size_t)maxflags)
maxflags = flen;
@@ -759,7 +779,7 @@ display(const FTSENT *p, FTSENT *list, int options)
error = mac_prepare_file_label(&label);
if (error == -1) {
- warn("MAC label for %s/%s",
+ xo_warn("MAC label for %s/%s",
cur->fts_parent->fts_path,
cur->fts_name);
goto label_out;
@@ -780,7 +800,7 @@ display(const FTSENT *p, FTSENT *list, int options)
error = mac_get_link(name,
label);
if (error == -1) {
- warn("MAC label for %s/%s",
+ xo_warn("MAC label for %s/%s",
cur->fts_parent->fts_path,
cur->fts_name);
mac_free(label);
@@ -790,7 +810,7 @@ display(const FTSENT *p, FTSENT *list, int options)
error = mac_to_text(label,
&labelstr);
if (error == -1) {
- warn("MAC label for %s/%s",
+ xo_warn("MAC label for %s/%s",
cur->fts_parent->fts_path,
cur->fts_name);
mac_free(label);
@@ -808,7 +828,7 @@ label_out:
if ((np = malloc(sizeof(NAMES) + labelstrlen +
ulen + glen + flen + 4)) == NULL)
- err(1, "malloc");
+ xo_err(1, "malloc");
np->user = &np->data[0];
(void)strcpy(np->user, user);
diff --git a/bin/ls/print.c b/bin/ls/print.c
index 930d6ea..20c980e 100644
--- a/bin/ls/print.c
+++ b/bin/ls/print.c
@@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$");
#include <termcap.h>
#include <signal.h>
#endif
+#include <libxo/xo.h>
#include "ls.h"
#include "extern.h"
@@ -65,9 +66,9 @@ __FBSDID("$FreeBSD$");
static int printaname(const FTSENT *, u_long, u_long);
static void printdev(size_t, dev_t);
static void printlink(const FTSENT *);
-static void printtime(time_t);
+static void printtime(const char *, time_t);
static int printtype(u_int);
-static void printsize(size_t, off_t);
+static void printsize(const char *, size_t, off_t);
#ifdef COLORLS
static void endcolor(int);
static int colortype(mode_t);
@@ -109,26 +110,46 @@ printscol(const DISPLAY *dp)
{
FTSENT *p;
+ xo_open_list("entry");
for (p = dp->list; p; p = p->fts_link) {
if (IS_NOPRINT(p))
continue;
+ xo_open_instance("entry");
(void)printaname(p, dp->s_inode, dp->s_block);
- (void)putchar('\n');
+ xo_close_instance("entry");
+ xo_emit("\n");
}
+ xo_close_list("entry");
}
/*
* print name in current style
*/
int
-printname(const char *name)
+printname(const char *field, const char *name)
+{
+ char fmt[BUFSIZ];
+ char *s = getname(name);
+ int rc;
+
+ snprintf(fmt, sizeof(fmt), "{:%s/%%hs}", field);
+ rc = xo_emit(fmt, s);
+ free(s);
+ return rc;
+}
+
+/*
+ * print name in current style
+ */
+char *
+getname(const char *name)
{
if (f_octal || f_octal_escape)
- return prn_octal(name);
+ return get_octal(name);
else if (f_nonprint)
- return prn_printable(name);
+ return get_printable(name);
else
- return prn_normal(name);
+ return strdup(name);
}
void
@@ -144,46 +165,59 @@ printlong(const DISPLAY *dp)
if ((dp->list == NULL || dp->list->fts_level != FTS_ROOTLEVEL) &&
(f_longform || f_size)) {
- (void)printf("total %lu\n", howmany(dp->btotal, blocksize));
+ xo_emit("{L:total} {:total-blocks/%lu}\n",
+ howmany(dp->btotal, blocksize));
}
+ xo_open_list("entry");
for (p = dp->list; p; p = p->fts_link) {
+ char *name;
if (IS_NOPRINT(p))
continue;
+ xo_open_instance("entry");
sp = p->fts_statp;
+ name = getname(p->fts_name);
+ if (name)
+ xo_emit("{ke:name}", name);
if (f_inode)
- (void)printf("%*ju ",
+ xo_emit("{:inode/%*ju} ",
dp->s_inode, (uintmax_t)sp->st_ino);
if (f_size)
- (void)printf("%*jd ",
+ xo_emit("{:blocks/%*jd} ",
dp->s_block, howmany(sp->st_blocks, blocksize));
strmode(sp->st_mode, buf);
aclmode(buf, p);
np = p->fts_pointer;
- (void)printf("%s %*u %-*s %-*s ", buf, dp->s_nlink,
- sp->st_nlink, dp->s_user, np->user, dp->s_group,
- np->group);
+ xo_attr("value", "%03o", (int) sp->st_mode & ALLPERMS);
+ xo_emit("{t:mode/%s} {:links/%*u} {:user/%-*s} {:group/%-*s} ",
+ buf, dp->s_nlink, sp->st_nlink,
+ dp->s_user, np->user, dp->s_group, np->group);
if (f_flags)
- (void)printf("%-*s ", dp->s_flags, np->flags);
+ xo_emit("{:flags/%-*s} ", dp->s_flags, np->flags);
if (f_label)
- (void)printf("%-*s ", dp->s_label, np->label);
+ xo_emit("{:label/%-*s} ", dp->s_label, np->label);
if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode))
printdev(dp->s_size, sp->st_rdev);
else
- printsize(dp->s_size, sp->st_size);
+ printsize("size", dp->s_size, sp->st_size);
if (f_accesstime)
- printtime(sp->st_atime);
+ printtime("access-time", sp->st_atime);
else if (f_birthtime)
- printtime(sp->st_birthtime);
+ printtime("birth-time", sp->st_birthtime);
else if (f_statustime)
- printtime(sp->st_ctime);
+ printtime("change-time", sp->st_ctime);
else
- printtime(sp->st_mtime);
+ printtime("modify-time", sp->st_mtime);
#ifdef COLORLS
if (f_color)
color_printed = colortype(sp->st_mode);
#endif
- (void)printname(p->fts_name);
+
+ if (name) {
+ xo_emit("{dk:name}", name);
+ free(name);
+ }
+
#ifdef COLORLS
if (f_color && color_printed)
endcolor(0);
@@ -192,8 +226,10 @@ printlong(const DISPLAY *dp)
(void)printtype(sp->st_mode);
if (S_ISLNK(sp->st_mode))
printlink(p);
- (void)putchar('\n');
+ xo_close_instance("entry");
+ xo_emit("\n");
}
+ xo_close_list("entry");
}
void
@@ -208,17 +244,17 @@ printstream(const DISPLAY *dp)
/* XXX strlen does not take octal escapes into account. */
if (strlen(p->fts_name) + chcnt +
(p->fts_link ? 2 : 0) >= (unsigned)termwidth) {
- putchar('\n');
+ xo_emit("\n");
chcnt = 0;
}
chcnt += printaname(p, dp->s_inode, dp->s_block);
if (p->fts_link) {
- printf(", ");
+ xo_emit(", ");
chcnt += 2;
}
}
if (chcnt)
- putchar('\n');
+ xo_emit("\n");
}
void
@@ -252,7 +288,7 @@ printcol(const DISPLAY *dp)
if (dp->entries > lastentries) {
if ((narray =
realloc(array, dp->entries * sizeof(FTSENT *))) == NULL) {
- warn(NULL);
+ xo_warn(NULL);
printscol(dp);
return;
}
@@ -283,17 +319,21 @@ printcol(const DISPLAY *dp)
if ((dp->list == NULL || dp->list->fts_level != FTS_ROOTLEVEL) &&
(f_longform || f_size)) {
- (void)printf("total %lu\n", howmany(dp->btotal, blocksize));
+ xo_emit("{L:total} {:total-blocks/%lu}\n",
+ howmany(dp->btotal, blocksize));
}
+ xo_open_list("entry");
base = 0;
for (row = 0; row < numrows; ++row) {
endcol = colwidth;
if (!f_sortacross)
base = row;
for (col = 0, chcnt = 0; col < numcols; ++col) {
+ xo_open_instance("entry");
chcnt += printaname(array[base], dp->s_inode,
dp->s_block);
+ xo_close_instance("entry");
if (f_sortacross)
base++;
else
@@ -304,13 +344,14 @@ printcol(const DISPLAY *dp)
<= endcol) {
if (f_sortacross && col + 1 >= numcols)
break;
- (void)putchar(f_notabs ? ' ' : '\t');
+ xo_emit(f_notabs ? " " : "\t");
chcnt = cnt;
}
endcol += colwidth;
}
- (void)putchar('\n');
+ xo_emit("\n");
}
+ xo_close_list("entry");
}
/*
@@ -329,16 +370,16 @@ printaname(const FTSENT *p, u_long inodefield, u_long sizefield)
sp = p->fts_statp;
chcnt = 0;
if (f_inode)
- chcnt += printf("%*ju ",
+ chcnt += xo_emit("{:inode/%*ju} ",
(int)inodefield, (uintmax_t)sp->st_ino);
if (f_size)
- chcnt += printf("%*jd ",
+ chcnt += xo_emit("{:size/%*jd} ",
(int)sizefield, howmany(sp->st_blocks, blocksize));
#ifdef COLORLS
if (f_color)
color_printed = colortype(sp->st_mode);
#endif
- chcnt += printname(p->fts_name);
+ chcnt += printname("name", p->fts_name);
#ifdef COLORLS
if (f_color && color_printed)
endcolor(0);
@@ -354,14 +395,14 @@ printaname(const FTSENT *p, u_long inodefield, u_long sizefield)
static void
printdev(size_t width, dev_t dev)
{
-
- (void)printf("%#*jx ", (u_int)width, (uintmax_t)dev);
+ xo_emit("{:device/%#*jx} ", (u_int)width, (uintmax_t)dev);
}
static void
-printtime(time_t ftime)
+printtime(const char *field, time_t ftime)
{
char longstring[80];
+ char fmt[BUFSIZ];
static time_t now = 0;
const char *format;
static int d_first = -1;
@@ -384,8 +425,10 @@ printtime(time_t ftime)
/* mmm dd yyyy || dd mmm yyyy */
format = d_first ? "%e %b %Y" : "%b %e %Y";
strftime(longstring, sizeof(longstring), format, localtime(&ftime));
- fputs(longstring, stdout);
- fputc(' ', stdout);
+
+ snprintf(fmt, sizeof(fmt), "{:%s/%%s} ", field);
+ xo_attr("value", "%ld", (long) ftime);
+ xo_emit(fmt, longstring);
}
static int
@@ -394,7 +437,7 @@ printtype(u_int mode)
if (f_slash) {
if ((mode & S_IFMT) == S_IFDIR) {
- (void)putchar('/');
+ xo_emit("{D:\\/}{e:type/directory}");
return (1);
}
return (0);
@@ -402,25 +445,25 @@ printtype(u_int mode)
switch (mode & S_IFMT) {
case S_IFDIR:
- (void)putchar('/');
+ xo_emit("{D:/\\/}{e:type/directory}");
return (1);
case S_IFIFO:
- (void)putchar('|');
+ xo_emit("{D:|}{e:type/fifo}");
return (1);
case S_IFLNK:
- (void)putchar('@');
+ xo_emit("{D:@}{e:type/link}");
return (1);
case S_IFSOCK:
- (void)putchar('=');
+ xo_emit("{D:=}{e:type/socket}");
return (1);
case S_IFWHT:
- (void)putchar('%');
+ xo_emit("{D:%}{e:type/whiteout}");
return (1);
default:
break;
}
if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
- (void)putchar('*');
+ xo_emit("{D:*}{e:executable/}");
return (1);
}
return (0);
@@ -430,7 +473,7 @@ printtype(u_int mode)
static int
putch(int c)
{
- (void)putchar(c);
+ xo_emit("{D:/%c}", c);
return 0;
}
@@ -539,7 +582,7 @@ parsecolors(const char *cs)
if (c[j] >= '0' && c[j] <= '7') {
colors[i].num[j] = c[j] - '0';
if (!legacy_warn) {
- warnx("LSCOLORS should use "
+ xo_warnx("LSCOLORS should use "
"characters a-h instead of 0-9 ("
"see the manual page)");
}
@@ -552,7 +595,7 @@ parsecolors(const char *cs)
} else if (tolower((unsigned char)c[j]) == 'x')
colors[i].num[j] = -1;
else {
- warnx("invalid character '%c' in LSCOLORS"
+ xo_warnx("invalid character '%c' in LSCOLORS"
" env var", c[j]);
colors[i].num[j] = -1;
}
@@ -584,18 +627,19 @@ printlink(const FTSENT *p)
(void)snprintf(name, sizeof(name),
"%s/%s", p->fts_parent->fts_accpath, p->fts_name);
if ((lnklen = readlink(name, path, sizeof(path) - 1)) == -1) {
- (void)fprintf(stderr, "\nls: %s: %s\n", name, strerror(errno));
+ xo_error("\nls: %s: %s\n", name, strerror(errno));
return;
}
path[lnklen] = '\0';
- (void)printf(" -> ");
- (void)printname(path);
+ xo_emit(" -> ");
+ (void)printname("target", path);
}
static void
-printsize(size_t width, off_t bytes)
+printsize(const char *field, size_t width, off_t bytes)
{
-
+ char fmt[BUFSIZ];
+
if (f_humanval) {
/*
* Reserve one space before the size and allocate room for
@@ -605,13 +649,15 @@ printsize(size_t width, off_t bytes)
humanize_number(buf, sizeof(buf), (int64_t)bytes, "",
HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
- (void)printf("%*s ", (u_int)width, buf);
- } else if (f_thousands) { /* with commas */
+ snprintf(fmt, sizeof(fmt), "{:%s/%%%ds} ", field, (int) width);
+ xo_attr("value", "%jd", (intmax_t) bytes);
+ xo_emit(fmt, buf);
+ } else { /* with commas */
/* This format assignment needed to work round gcc bug. */
- const char *format = "%*j'd ";
- (void)printf(format, (u_int)width, bytes);
- } else
- (void)printf("%*jd ", (u_int)width, bytes);
+ snprintf(fmt, sizeof(fmt), "{:%s/%%%dj%sd} ",
+ field, (int) width, f_thousands ? "'" : "");
+ xo_emit(fmt, (intmax_t) bytes);
+ }
}
/*
@@ -654,7 +700,7 @@ aclmode(char *buf, const FTSENT *p)
type = ACL_TYPE_NFS4;
supports_acls = 1;
} else if (ret < 0 && errno != EINVAL) {
- warn("%s", name);
+ xo_warn("%s", name);
return;
}
if (supports_acls == 0) {
@@ -663,7 +709,7 @@ aclmode(char *buf, const FTSENT *p)
type = ACL_TYPE_ACCESS;
supports_acls = 1;
} else if (ret < 0 && errno != EINVAL) {
- warn("%s", name);
+ xo_warn("%s", name);
return;
}
}
@@ -672,12 +718,12 @@ aclmode(char *buf, const FTSENT *p)
return;
facl = acl_get_link_np(name, type);
if (facl == NULL) {
- warn("%s", name);
+ xo_warn("%s", name);
return;
}
if (acl_is_trivial_np(facl, &trivial)) {
acl_free(facl);
- warn("%s", name);
+ xo_warn("%s", name);
return;
}
if (!trivial)
diff --git a/bin/ls/util.c b/bin/ls/util.c
index f8466cd..b75cbec 100644
--- a/bin/ls/util.c
+++ b/bin/ls/util.c
@@ -50,13 +50,19 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include <wchar.h>
#include <wctype.h>
+#include <libxo/xo.h>
#include "ls.h"
#include "extern.h"
int
-prn_normal(const char *s)
+prn_normal(const char *field, const char *s)
{
+ char fmt[_POSIX2_LINE_MAX];
+
+ snprintf(fmt, sizeof(fmt), "{:%s/%%hs}", field);
+ return xo_emit(fmt, s);
+#if 0
mbstate_t mbs;
wchar_t wc;
int i, n;
@@ -83,43 +89,47 @@ prn_normal(const char *s)
n += wcwidth(wc);
}
return (n);
+#endif
}
-int
-prn_printable(const char *s)
+char *
+get_printable(const char *s)
{
mbstate_t mbs;
wchar_t wc;
int i, n;
size_t clen;
+ int slen = strlen(s);
+ char *buf = alloca(slen + 1), *bp = buf;
memset(&mbs, 0, sizeof(mbs));
n = 0;
while ((clen = mbrtowc(&wc, s, MB_LEN_MAX, &mbs)) != 0) {
if (clen == (size_t)-1) {
- putchar('?');
+ *bp++ = '?';
s++;
n++;
memset(&mbs, 0, sizeof(mbs));
continue;
}
if (clen == (size_t)-2) {
- putchar('?');
+ *bp++ = '?';
n++;
break;
}
if (!iswprint(wc)) {
- putchar('?');
+ *bp++ = '?';
s += clen;
n++;
continue;
}
for (i = 0; i < (int)clen; i++)
- putchar((unsigned char)s[i]);
+ *bp++ = (unsigned char)s[i];
s += clen;
n += wcwidth(wc);
}
- return (n);
+ *bp = '\0';
+ return strdup(buf);
}
/*
@@ -165,8 +175,8 @@ len_octal(const char *s, int len)
return (r);
}
-int
-prn_octal(const char *s)
+char *
+get_octal(const char *s)
{
static const char esc[] = "\\\\\"\"\aa\bb\ff\nn\rr\tt\vv";
const char *p;
@@ -175,6 +185,8 @@ prn_octal(const char *s)
size_t clen;
unsigned char ch;
int goodchar, i, len, prtlen;
+ int slen = strlen(s);
+ char *buf = alloca(slen * 4 + 1), *bp = buf;
memset(&mbs, 0, sizeof(mbs));
len = 0;
@@ -182,7 +194,7 @@ prn_octal(const char *s)
goodchar = clen != (size_t)-1 && clen != (size_t)-2;
if (goodchar && iswprint(wc) && wc != L'\"' && wc != L'\\') {
for (i = 0; i < (int)clen; i++)
- putchar((unsigned char)s[i]);
+ *bp++ = (unsigned char)s[i];
len += wcwidth(wc);
} else if (goodchar && f_octal_escape &&
#if WCHAR_MIN < 0
@@ -190,8 +202,8 @@ prn_octal(const char *s)
#endif
wc <= (wchar_t)UCHAR_MAX &&
(p = strchr(esc, (char)wc)) != NULL) {
- putchar('\\');
- putchar(p[1]);
+ *bp ++ = '\\';
+ *bp++ = p[1];
len += 2;
} else {
if (goodchar)
@@ -202,10 +214,10 @@ prn_octal(const char *s)
prtlen = strlen(s);
for (i = 0; i < prtlen; i++) {
ch = (unsigned char)s[i];
- putchar('\\');
- putchar('0' + (ch >> 6));
- putchar('0' + ((ch >> 3) & 7));
- putchar('0' + (ch & 7));
+ *bp++ = '\\';
+ *bp++ = '0' + (ch >> 6);
+ *bp++ = '0' + ((ch >> 3) & 7);
+ *bp++ = '0' + (ch & 7);
len += 4;
}
}
@@ -217,13 +229,15 @@ prn_octal(const char *s)
} else
s += clen;
}
- return (len);
+
+ *bp = '\0';
+ return strdup(buf);
}
void
usage(void)
{
- (void)fprintf(stderr,
+ xo_error(
#ifdef COLORLS
"usage: ls [-ABCFGHILPRSTUWZabcdfghiklmnopqrstuwxy1,] [-D format]"
#else
OpenPOWER on IntegriCloud