1 /* expand.c - expands tabs to space
3 * Copyright 2012 Jonathan Clairembault <jonathan at clairembault dot fr>
5 * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/expand.html
7 USE_EXPAND(NEWTOY(expand, "t*", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
13 usage: expand [-t TABLIST] [FILE...]
15 Expand tabs to spaces according to tabstops.
19 Specify tab stops, either a single number instead of the default 8,
20 or a comma separated list of increasing numbers representing tabstop
21 positions (absolute, not increments) with each additional tab beyound
22 that becoming one space.
29 struct arg_list *tabs;
31 unsigned tabcount, *tab;
34 static void do_expand(int fd, char *name)
36 int i, len, x=0, stop = 0;
39 len = readall(fd, toybuf, sizeof(toybuf));
45 for (i=0; i<len; i++) {
49 if (CFG_TOYBOX_I18N) {
52 width = mbrtowc(&blah, toybuf+i, len-i, 0);
54 if (width != fwrite(toybuf+i, width, 1, stdout))
55 perror_exit("stdout");
59 } else if (width == -2) break;
60 else if (width == -1) continue;
65 if (EOF == putc(c, stdout)) perror_exit(0);
67 if (c == '\b' && x) width = -1;
73 if (TT.tabcount < 2) {
74 width = TT.tabcount ? *TT.tab : 8;
76 } else while (stop < TT.tabcount) {
77 if (TT.tab[stop] > x) {
78 width = TT.tab[stop] - x;
82 xprintf("%*c", width, ' ');
89 // Parse -t options to fill out unsigned array in tablist (if not NULL)
90 // return number of entries in tablist
91 static int parse_tablist(unsigned *tablist)
93 struct arg_list *tabs;
96 for (tabs = TT.tabs; tabs; tabs = tabs->next) {
101 unsigned x, *t = tablist ? tablist+tabcount : &x;
103 if (tabcount >= sizeof(toybuf)/sizeof(unsigned)) break;
104 if (sscanf(s, "%u%n", t, &count) != 1) break;
105 if (tabcount++ && tablist && *(t-1) >= *t) break;
107 if (*s==' ' || *s==',') s++;
110 if (*s) error_exit("bad tablist");
116 void expand_main(void)
118 TT.tabcount = parse_tablist(NULL);
120 // Determine size of tablist, allocate memory, fill out tablist
122 TT.tab = xmalloc(sizeof(unsigned)*TT.tabcount);
123 parse_tablist(TT.tab);
126 loopfiles(toys.optargs, do_expand);
127 if (CFG_TOYBOX_FREE) free(TT.tab);