diff options
Diffstat (limited to 'bin/ls/print.c')
-rw-r--r-- | bin/ls/print.c | 169 |
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) |