annotate toys/posix/expand.c @ 1776:7bf68329eb3b draft default tip

Repository switched to git at https://github.com/landley/toybox
author Rob Landley <rob@landley.net>
date Thu, 09 Apr 2015 02:28:32 -0500
parents 3b85d2ce34aa
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
715
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
1 /* expand.c - expands tabs to space
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
2 *
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
3 * Copyright 2012 Jonathan Clairembault <jonathan at clairembault dot fr>
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
4 *
717
54294a48a09b First round of expand cleanups.
Rob Landley <rob@landley.net>
parents: 716
diff changeset
5 * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/expand.html
715
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
6
1342
3b85d2ce34aa When locale is enabled, sprintf("%.123s", str) is counting characters, not bytes, so we can't globally enable locale without opening stack/heap smashing vulnerabilities. Make commands individually request setlocale() using TOYFLAGS instead.
Rob Landley <rob@landley.net>
parents: 1061
diff changeset
7 USE_EXPAND(NEWTOY(expand, "t*", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
715
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
8
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
9 config EXPAND
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
10 bool "expand"
717
54294a48a09b First round of expand cleanups.
Rob Landley <rob@landley.net>
parents: 716
diff changeset
11 default y
715
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
12 help
1061
ed2694ccf2ae Minor cosmetic tweaks to expand.
Rob Landley <rob@landley.net>
parents: 780
diff changeset
13 usage: expand [-t TABLIST] [FILE...]
715
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
14
717
54294a48a09b First round of expand cleanups.
Rob Landley <rob@landley.net>
parents: 716
diff changeset
15 Expand tabs to spaces according to tabstops.
715
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
16
1061
ed2694ccf2ae Minor cosmetic tweaks to expand.
Rob Landley <rob@landley.net>
parents: 780
diff changeset
17 -t TABLIST
715
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
18
1061
ed2694ccf2ae Minor cosmetic tweaks to expand.
Rob Landley <rob@landley.net>
parents: 780
diff changeset
19 Specify tab stops, either a single number instead of the default 8,
ed2694ccf2ae Minor cosmetic tweaks to expand.
Rob Landley <rob@landley.net>
parents: 780
diff changeset
20 or a comma separated list of increasing numbers representing tabstop
ed2694ccf2ae Minor cosmetic tweaks to expand.
Rob Landley <rob@landley.net>
parents: 780
diff changeset
21 positions (absolute, not increments) with each additional tab beyound
ed2694ccf2ae Minor cosmetic tweaks to expand.
Rob Landley <rob@landley.net>
parents: 780
diff changeset
22 that becoming one space.
715
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
23 */
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
24
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
25 #define FOR_expand
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
26 #include "toys.h"
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
27
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
28 GLOBALS(
722
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
29 struct arg_list *tabs;
715
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
30
722
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
31 unsigned tabcount, *tab;
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
32 )
715
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
33
1061
ed2694ccf2ae Minor cosmetic tweaks to expand.
Rob Landley <rob@landley.net>
parents: 780
diff changeset
34 static void do_expand(int fd, char *name)
715
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
35 {
722
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
36 int i, len, x=0, stop = 0;
715
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
37
722
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
38 for (;;) {
1061
ed2694ccf2ae Minor cosmetic tweaks to expand.
Rob Landley <rob@landley.net>
parents: 780
diff changeset
39 len = readall(fd, toybuf, sizeof(toybuf));
722
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
40 if (len<0) {
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
41 perror_msg("%s", name);
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
42 return;
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
43 }
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
44 if (!len) break;
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
45 for (i=0; i<len; i++) {
725
e7c14db739c1 Would the compiler like to warn me about declaring two variables with the same name in the same function? No? Carry on then...
Rob Landley <rob@landley.net>
parents: 723
diff changeset
46 int width = 1;
732
45dbb4a5a3bc First guess at what internationalization support for expand would look like.
Rob Landley <rob@landley.net>
parents: 725
diff changeset
47 char c;
45dbb4a5a3bc First guess at what internationalization support for expand would look like.
Rob Landley <rob@landley.net>
parents: 725
diff changeset
48
45dbb4a5a3bc First guess at what internationalization support for expand would look like.
Rob Landley <rob@landley.net>
parents: 725
diff changeset
49 if (CFG_TOYBOX_I18N) {
45dbb4a5a3bc First guess at what internationalization support for expand would look like.
Rob Landley <rob@landley.net>
parents: 725
diff changeset
50 wchar_t blah;
45dbb4a5a3bc First guess at what internationalization support for expand would look like.
Rob Landley <rob@landley.net>
parents: 725
diff changeset
51
45dbb4a5a3bc First guess at what internationalization support for expand would look like.
Rob Landley <rob@landley.net>
parents: 725
diff changeset
52 width = mbrtowc(&blah, toybuf+i, len-i, 0);
45dbb4a5a3bc First guess at what internationalization support for expand would look like.
Rob Landley <rob@landley.net>
parents: 725
diff changeset
53 if (width > 1) {
45dbb4a5a3bc First guess at what internationalization support for expand would look like.
Rob Landley <rob@landley.net>
parents: 725
diff changeset
54 if (width != fwrite(toybuf+i, width, 1, stdout))
45dbb4a5a3bc First guess at what internationalization support for expand would look like.
Rob Landley <rob@landley.net>
parents: 725
diff changeset
55 perror_exit("stdout");
45dbb4a5a3bc First guess at what internationalization support for expand would look like.
Rob Landley <rob@landley.net>
parents: 725
diff changeset
56 i += width-1;
45dbb4a5a3bc First guess at what internationalization support for expand would look like.
Rob Landley <rob@landley.net>
parents: 725
diff changeset
57 x++;
45dbb4a5a3bc First guess at what internationalization support for expand would look like.
Rob Landley <rob@landley.net>
parents: 725
diff changeset
58 continue;
45dbb4a5a3bc First guess at what internationalization support for expand would look like.
Rob Landley <rob@landley.net>
parents: 725
diff changeset
59 } else if (width == -2) break;
45dbb4a5a3bc First guess at what internationalization support for expand would look like.
Rob Landley <rob@landley.net>
parents: 725
diff changeset
60 else if (width == -1) continue;
45dbb4a5a3bc First guess at what internationalization support for expand would look like.
Rob Landley <rob@landley.net>
parents: 725
diff changeset
61 }
45dbb4a5a3bc First guess at what internationalization support for expand would look like.
Rob Landley <rob@landley.net>
parents: 725
diff changeset
62 c = toybuf[i];
723
2818724bb8be Re-add backspace support to expand (oops) and fix test to expect data plus backspace characters rather than the chracters cancelling each other out before output.
Rob Landley <rob@landley.net>
parents: 722
diff changeset
63
2818724bb8be Re-add backspace support to expand (oops) and fix test to expect data plus backspace characters rather than the chracters cancelling each other out before output.
Rob Landley <rob@landley.net>
parents: 722
diff changeset
64 if (c != '\t') {
2818724bb8be Re-add backspace support to expand (oops) and fix test to expect data plus backspace characters rather than the chracters cancelling each other out before output.
Rob Landley <rob@landley.net>
parents: 722
diff changeset
65 if (EOF == putc(c, stdout)) perror_exit(0);
2818724bb8be Re-add backspace support to expand (oops) and fix test to expect data plus backspace characters rather than the chracters cancelling each other out before output.
Rob Landley <rob@landley.net>
parents: 722
diff changeset
66
725
e7c14db739c1 Would the compiler like to warn me about declaring two variables with the same name in the same function? No? Carry on then...
Rob Landley <rob@landley.net>
parents: 723
diff changeset
67 if (c == '\b' && x) width = -1;
723
2818724bb8be Re-add backspace support to expand (oops) and fix test to expect data plus backspace characters rather than the chracters cancelling each other out before output.
Rob Landley <rob@landley.net>
parents: 722
diff changeset
68 if (c == '\n') {
722
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
69 x = stop = 0;
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
70 continue;
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
71 }
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
72 } else {
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
73 if (TT.tabcount < 2) {
725
e7c14db739c1 Would the compiler like to warn me about declaring two variables with the same name in the same function? No? Carry on then...
Rob Landley <rob@landley.net>
parents: 723
diff changeset
74 width = TT.tabcount ? *TT.tab : 8;
e7c14db739c1 Would the compiler like to warn me about declaring two variables with the same name in the same function? No? Carry on then...
Rob Landley <rob@landley.net>
parents: 723
diff changeset
75 width -= x%width;
722
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
76 } else while (stop < TT.tabcount) {
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
77 if (TT.tab[stop] > x) {
725
e7c14db739c1 Would the compiler like to warn me about declaring two variables with the same name in the same function? No? Carry on then...
Rob Landley <rob@landley.net>
parents: 723
diff changeset
78 width = TT.tab[stop] - x;
722
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
79 break;
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
80 } else stop++;
715
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
81 }
725
e7c14db739c1 Would the compiler like to warn me about declaring two variables with the same name in the same function? No? Carry on then...
Rob Landley <rob@landley.net>
parents: 723
diff changeset
82 xprintf("%*c", width, ' ');
715
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
83 }
725
e7c14db739c1 Would the compiler like to warn me about declaring two variables with the same name in the same function? No? Carry on then...
Rob Landley <rob@landley.net>
parents: 723
diff changeset
84 x += width;
715
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
85 }
722
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
86 }
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
87 }
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
88
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
89 // Parse -t options to fill out unsigned array in tablist (if not NULL)
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
90 // return number of entries in tablist
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
91 static int parse_tablist(unsigned *tablist)
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
92 {
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
93 struct arg_list *tabs;
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
94 int tabcount = 0;
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
95
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
96 for (tabs = TT.tabs; tabs; tabs = tabs->next) {
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
97 char *s = tabs->arg;
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
98
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
99 while (*s) {
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
100 int count;
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
101 unsigned x, *t = tablist ? tablist+tabcount : &x;
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
102
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
103 if (tabcount >= sizeof(toybuf)/sizeof(unsigned)) break;
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
104 if (sscanf(s, "%u%n", t, &count) != 1) break;
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
105 if (tabcount++ && tablist && *(t-1) >= *t) break;
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
106 s += count;
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
107 if (*s==' ' || *s==',') s++;
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
108 else break;
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
109 }
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
110 if (*s) error_exit("bad tablist");
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
111 }
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
112
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
113 return tabcount;
715
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
114 }
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
115
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
116 void expand_main(void)
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
117 {
722
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
118 TT.tabcount = parse_tablist(NULL);
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
119
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
120 // Determine size of tablist, allocate memory, fill out tablist
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
121 if (TT.tabcount) {
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
122 TT.tab = xmalloc(sizeof(unsigned)*TT.tabcount);
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
123 parse_tablist(TT.tab);
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
124 }
717
54294a48a09b First round of expand cleanups.
Rob Landley <rob@landley.net>
parents: 716
diff changeset
125
1061
ed2694ccf2ae Minor cosmetic tweaks to expand.
Rob Landley <rob@landley.net>
parents: 780
diff changeset
126 loopfiles(toys.optargs, do_expand);
722
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
127 if (CFG_TOYBOX_FREE) free(TT.tab);
715
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
128 }