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
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
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 }