aboutsummaryrefslogtreecommitdiff
path: root/bin/ls/print.c
diff options
context:
space:
mode:
Diffstat (limited to 'bin/ls/print.c')
-rw-r--r--bin/ls/print.c169
1 files changed, 107 insertions, 62 deletions
diff --git a/bin/ls/print.c b/bin/ls/print.c
index 930d6eaeeb70..c96fe7cace41 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,6 @@ printcol(const DISPLAY *dp)
if (dp->entries > lastentries) {
if ((narray =
realloc(array, dp->entries * sizeof(FTSENT *))) == NULL) {
- warn(NULL);
printscol(dp);
return;
}
@@ -283,17 +318,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 +343,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 +369,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 +394,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 +424,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 +436,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 +444,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 +472,7 @@ printtype(u_int mode)
static int
putch(int c)
{
- (void)putchar(c);
+ xo_emit("{D:/%c}", c);
return 0;
}
@@ -539,7 +581,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 +594,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 +626,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 +648,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 +699,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 +708,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 +717,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)