Mercurial > hg > toybox
view toys/posix/expand.c @ 1061:ed2694ccf2ae draft
Minor cosmetic tweaks to expand.
Working my way through the to-review list that predates the "pending"
directory. This gets expand off my to-review list. (Proof that "need to
review" doesn't mean it's in bad shape, this command was fine. Changed
capitalization in the help text because I'm trying to have "user supplies
this value" be all caps, switched a read() to readall() although I'm not
sure modern kernels actually allow -EINTR to generate zero length reads
anymore, and since most of the loopfiles() target functions are called
do_commandname() changed the name to that just so it's regular. None of
the changes are actually important. :)
author | Rob Landley <rob@landley.net> |
---|---|
date | Mon, 09 Sep 2013 05:52:49 -0500 |
parents | 6cc69be43c42 |
children | 3b85d2ce34aa |
line wrap: on
line source
/* expand.c - expands tabs to space * * Copyright 2012 Jonathan Clairembault <jonathan at clairembault dot fr> * * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/expand.html USE_EXPAND(NEWTOY(expand, "t*", TOYFLAG_USR|TOYFLAG_BIN)) config EXPAND bool "expand" default y help usage: expand [-t TABLIST] [FILE...] Expand tabs to spaces according to tabstops. -t TABLIST Specify tab stops, either a single number instead of the default 8, or a comma separated list of increasing numbers representing tabstop positions (absolute, not increments) with each additional tab beyound that becoming one space. */ #define FOR_expand #include "toys.h" GLOBALS( struct arg_list *tabs; unsigned tabcount, *tab; ) static void do_expand(int fd, char *name) { int i, len, x=0, stop = 0; for (;;) { len = readall(fd, toybuf, sizeof(toybuf)); if (len<0) { perror_msg("%s", name); return; } if (!len) break; for (i=0; i<len; i++) { int width = 1; char c; if (CFG_TOYBOX_I18N) { wchar_t blah; width = mbrtowc(&blah, toybuf+i, len-i, 0); if (width > 1) { if (width != fwrite(toybuf+i, width, 1, stdout)) perror_exit("stdout"); i += width-1; x++; continue; } else if (width == -2) break; else if (width == -1) continue; } c = toybuf[i]; if (c != '\t') { if (EOF == putc(c, stdout)) perror_exit(0); if (c == '\b' && x) width = -1; if (c == '\n') { x = stop = 0; continue; } } else { if (TT.tabcount < 2) { width = TT.tabcount ? *TT.tab : 8; width -= x%width; } else while (stop < TT.tabcount) { if (TT.tab[stop] > x) { width = TT.tab[stop] - x; break; } else stop++; } xprintf("%*c", width, ' '); } x += width; } } } // Parse -t options to fill out unsigned array in tablist (if not NULL) // return number of entries in tablist static int parse_tablist(unsigned *tablist) { struct arg_list *tabs; int tabcount = 0; for (tabs = TT.tabs; tabs; tabs = tabs->next) { char *s = tabs->arg; while (*s) { int count; unsigned x, *t = tablist ? tablist+tabcount : &x; if (tabcount >= sizeof(toybuf)/sizeof(unsigned)) break; if (sscanf(s, "%u%n", t, &count) != 1) break; if (tabcount++ && tablist && *(t-1) >= *t) break; s += count; if (*s==' ' || *s==',') s++; else break; } if (*s) error_exit("bad tablist"); } return tabcount; } void expand_main(void) { TT.tabcount = parse_tablist(NULL); // Determine size of tablist, allocate memory, fill out tablist if (TT.tabcount) { TT.tab = xmalloc(sizeof(unsigned)*TT.tabcount); parse_tablist(TT.tab); } loopfiles(toys.optargs, do_expand); if (CFG_TOYBOX_FREE) free(TT.tab); }