Mercurial > hg > toybox
annotate toys/posix/expand.c @ 722:08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
author | Rob Landley <rob@landley.net> |
---|---|
date | Fri, 30 Nov 2012 02:41:52 -0600 |
parents | 54294a48a09b |
children | 2818724bb8be |
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 |
722
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
7 USE_EXPAND(NEWTOY(expand, "t*", TOYFLAG_USR|TOYFLAG_BIN)) |
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 |
3417db95f24b
Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff
changeset
|
13 usage: expand [-t tablist] [file...] |
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 |
717
54294a48a09b
First round of expand cleanups.
Rob Landley <rob@landley.net>
parents:
716
diff
changeset
|
17 -t tablist |
715
3417db95f24b
Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff
changeset
|
18 |
717
54294a48a09b
First round of expand cleanups.
Rob Landley <rob@landley.net>
parents:
716
diff
changeset
|
19 Specify tab stops, either a single number instead of the default 8, |
722
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
20 or a comma separated list of increasing numbers representing tabstop |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
21 positions (absolute, not increments) with each additional tab beyound |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
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 |
3417db95f24b
Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff
changeset
|
34 static void expand_file(int fd, char *name) |
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 (;;) { |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
39 len = read(fd, toybuf, sizeof(toybuf)); |
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 toys.exitval = 1; |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
43 return; |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
44 } |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
45 if (!len) break; |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
46 for (i=0; i<len; i++) { |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
47 int len = 1; |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
48 if (toybuf[i] != '\t') { |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
49 if (EOF == putc(toybuf[i], stdout)) perror_exit(0); |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
50 if (toybuf[i] == '\n') { |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
51 x = stop = 0; |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
52 continue; |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
53 } |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
54 } else { |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
55 if (TT.tabcount < 2) { |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
56 len = TT.tabcount ? *TT.tab : 8; |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
57 len -= x%len; |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
58 } 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
|
59 if (TT.tab[stop] > x) { |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
60 len = TT.tab[stop] - x; |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
61 break; |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
62 } else stop++; |
715
3417db95f24b
Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff
changeset
|
63 } |
722
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
64 xprintf("%*c", len, ' '); |
715
3417db95f24b
Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff
changeset
|
65 } |
722
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
66 x += len; |
715
3417db95f24b
Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff
changeset
|
67 } |
722
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
68 } |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
69 } |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
70 |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
71 // 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
|
72 // 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
|
73 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
|
74 { |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
75 struct arg_list *tabs; |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
76 int tabcount = 0; |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
77 |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
78 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
|
79 char *s = tabs->arg; |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
80 |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
81 while (*s) { |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
82 int count; |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
83 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
|
84 |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
85 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
|
86 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
|
87 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
|
88 s += count; |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
89 if (*s==' ' || *s==',') s++; |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
90 else break; |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
91 } |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
92 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
|
93 } |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
94 |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
95 return tabcount; |
715
3417db95f24b
Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff
changeset
|
96 } |
3417db95f24b
Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff
changeset
|
97 |
3417db95f24b
Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff
changeset
|
98 void expand_main(void) |
3417db95f24b
Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff
changeset
|
99 { |
722
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
100 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
|
101 |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
102 // 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
|
103 if (TT.tabcount) { |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
104 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
|
105 parse_tablist(TT.tab); |
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
106 } |
717
54294a48a09b
First round of expand cleanups.
Rob Landley <rob@landley.net>
parents:
716
diff
changeset
|
107 |
715
3417db95f24b
Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff
changeset
|
108 loopfiles(toys.optargs, expand_file); |
722
08d538115f39
Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents:
717
diff
changeset
|
109 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
|
110 } |