annotate toys/posix/expand.c @ 732:45dbb4a5a3bc

First guess at what internationalization support for expand would look like.
author Rob Landley <rob@landley.net>
date Sat, 01 Dec 2012 18:30:20 -0600
parents e7c14db739c1
children 6cc69be43c42
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++) {
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
47 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
48 char c;
45dbb4a5a3bc First guess at what internationalization support for expand would look like.
Rob Landley <rob@landley.net>
parents: 725
diff changeset
49
45dbb4a5a3bc First guess at what internationalization support for expand would look like.
Rob Landley <rob@landley.net>
parents: 725
diff changeset
50 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
51 wchar_t blah;
45dbb4a5a3bc First guess at what internationalization support for expand would look like.
Rob Landley <rob@landley.net>
parents: 725
diff changeset
52
45dbb4a5a3bc First guess at what internationalization support for expand would look like.
Rob Landley <rob@landley.net>
parents: 725
diff changeset
53 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
54 if (width > 1) {
45dbb4a5a3bc First guess at what internationalization support for expand would look like.
Rob Landley <rob@landley.net>
parents: 725
diff changeset
55 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
56 perror_exit("stdout");
45dbb4a5a3bc First guess at what internationalization support for expand would look like.
Rob Landley <rob@landley.net>
parents: 725
diff changeset
57 i += width-1;
45dbb4a5a3bc First guess at what internationalization support for expand would look like.
Rob Landley <rob@landley.net>
parents: 725
diff changeset
58 x++;
45dbb4a5a3bc First guess at what internationalization support for expand would look like.
Rob Landley <rob@landley.net>
parents: 725
diff changeset
59 continue;
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 == -2) break;
45dbb4a5a3bc First guess at what internationalization support for expand would look like.
Rob Landley <rob@landley.net>
parents: 725
diff changeset
61 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
62 }
45dbb4a5a3bc First guess at what internationalization support for expand would look like.
Rob Landley <rob@landley.net>
parents: 725
diff changeset
63 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
64
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 (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
66 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
67
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
68 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
69 if (c == '\n') {
722
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
70 x = stop = 0;
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
71 continue;
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
72 }
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
73 } else {
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
74 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
75 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
76 width -= x%width;
722
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
77 } 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
78 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
79 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
80 break;
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
81 } else stop++;
715
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
82 }
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
83 xprintf("%*c", width, ' ');
715
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
84 }
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
85 x += width;
715
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
86 }
722
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
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
90 // 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
91 // 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
92 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
93 {
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
94 struct arg_list *tabs;
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
95 int tabcount = 0;
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
96
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
97 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
98 char *s = tabs->arg;
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
99
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
100 while (*s) {
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
101 int count;
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
102 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
103
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
104 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
105 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
106 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
107 s += count;
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
108 if (*s==' ' || *s==',') s++;
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
109 else break;
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
110 }
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
111 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
112 }
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
113
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
114 return tabcount;
715
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
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
117 void expand_main(void)
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
118 {
722
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
119 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
120
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
121 // 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
122 if (TT.tabcount) {
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
123 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
124 parse_tablist(TT.tab);
08d538115f39 Largeish rewrite of expand, mostly described on the mailing list.
Rob Landley <rob@landley.net>
parents: 717
diff changeset
125 }
717
54294a48a09b First round of expand cleanups.
Rob Landley <rob@landley.net>
parents: 716
diff changeset
126
715
3417db95f24b Add expand command as described in POSIX-2008.
Jonathan Clairembault <jonathan@clairembault.fr>
parents:
diff changeset
127 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
128 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
129 }