Mercurial > hg > toybox
comparison toys/posix/sed.c @ 694:786841fdb1e0
Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
The actual code should be the same afterward, this is just cosmetic refactoring.
author | Rob Landley <rob@landley.net> |
---|---|
date | Tue, 13 Nov 2012 17:14:08 -0600 |
parents | 7e846e281e38 |
children |
comparison
equal
deleted
inserted
replaced
693:4a5a250e0633 | 694:786841fdb1e0 |
---|---|
1 /* vi: set sw=4 ts=4: | 1 /* sed.c - Stream editor. |
2 * | 2 * |
3 * sed.c - Stream editor. | 3 * Copyright 2012 Rob Landley <rob@landley.net> |
4 * | |
5 * Copyright 2008 Rob Landley <rob@landley.net> | |
6 * | 4 * |
7 * See http://opengroup.org/onlinepubs/9699919799/utilities/sed.c | 5 * See http://opengroup.org/onlinepubs/9699919799/utilities/sed.c |
8 | 6 |
9 USE_SED(NEWTOY(sed, "irne*", TOYFLAG_BIN)) | 7 USE_SED(NEWTOY(sed, "irne*", TOYFLAG_BIN)) |
10 | 8 |
11 config SED | 9 config SED |
12 bool "sed" | 10 bool "sed" |
13 default n | 11 default n |
14 help | 12 help |
15 usage: sed [-irn] {command | [-e command]...} [FILE...] | 13 usage: sed [-irn] {command | [-e command]...} [FILE...] |
16 | 14 |
17 Stream EDitor, transforms text by appling commands to each line | 15 Stream EDitor, transforms text by appling script of command to each line |
18 of input. | 16 of input. |
17 | |
18 -e Add expression to the command script (if no -e, use first argument) | |
19 -i Modify file in place | |
20 -n No default output (p commands only) | |
21 -r Use extended regular expression syntex | |
19 */ | 22 */ |
20 | 23 |
21 #define FOR_sed | 24 #define FOR_sed |
22 #include "toys.h" | 25 #include "toys.h" |
23 #include "lib/xregcomp.h" | 26 #include "lib/xregcomp.h" |
24 | 27 |
25 GLOBALS( | 28 GLOBALS( |
26 struct arg_list *commands; | 29 struct arg_list *scripts; |
30 struct double_list *commands; | |
31 | |
32 void *parsed; | |
27 ) | 33 ) |
28 | 34 |
35 // Digested version of what sed commands can actually tell use to do. | |
36 | |
37 | |
29 struct sed_command { | 38 struct sed_command { |
30 // Doubly linked list of commands. | 39 // double_list compatibility (easier to create in-order) |
31 struct sed_command *next, *prev; | 40 struct sed_command *next, *prev; |
32 | 41 |
33 // Regexes for s/match/data/ and /match_begin/,/match_end/command | 42 // data string for (saicytb) |
34 regex_t *match, *match_begin, *match_end; | 43 char c, *data; |
44 // Regexes for s/match/data/ and /begin/,/end/command | |
45 regex_t *match, *begin, *end; | |
46 // For numeric ranges ala 10,20command | |
47 long lstart, lstop; | |
48 // Which match to replace, 0 for all. s and w commands can write to a file | |
49 int which, outfd; | |
50 }; | |
35 | 51 |
36 // For numeric ranges ala 10,20command | 52 // Space. Space. Gotta get past space. Spaaaaaaaace! (But not newline.) |
37 int first_line, last_line; | 53 void spaceorb(char **s) |
54 { | |
55 while (**s == ' ' || **s == '\t') *s++; | |
56 } | |
38 | 57 |
39 // Which match to replace, 0 for all. | 58 void parse_scripts(void) |
40 int which; | 59 { |
60 struct sed_command *commands = 0; | |
61 struct arg_list *script; | |
62 int which = 0; | |
63 long l; | |
41 | 64 |
42 // s and w commands can write to a file. Slight optimization: we use 0 | 65 for (script = TT.scripts; *script; script = script->next) { |
43 // instead of -1 to mean no file here, because even when there's no stdin | 66 char *str = script->arg, *s; |
44 // our input file would take fd 0. | 67 struct sed_command *cmd; |
45 int outfd; | |
46 | 68 |
47 // Data string for (saicytb) | 69 which++; |
48 char *data; | 70 for (i=1;;) { |
71 if (!*str) break; | |
49 | 72 |
50 // Which command letter is this? | 73 cmd = xzalloc(sizeof(struct sed_command)); |
51 char command; | 74 |
52 }; | 75 // Identify prefix |
76 for (;;) { | |
77 long l; | |
78 | |
79 spaceorb(&str); | |
80 if (*str == '$') { | |
81 l = -1; | |
82 str++; | |
83 } else if (isdigit(*str)) l = strtol(str, &str, 10); | |
84 else if (!cmd->lstart) break; | |
85 else goto parse_fail; | |
86 | |
87 spaceorb(&str); | |
88 if (!cmd->lstart) { | |
89 if (!l) goto parse_fail; | |
90 cmd->lstart = l; | |
91 if (*str != ',') break; | |
92 str++; | |
93 continue; | |
94 } | |
95 cmd->lstop = l; | |
96 break; | |
97 } else if (*str == '/') { | |
98 printf("regex\n"); | |
99 } | |
100 l = stridx("{bcdDgGhHlnNpPstwxyrqia= \t#:}", *str); | |
101 if (l == -1) goto parse_fail; | |
102 | |
103 | |
104 } | |
105 } | |
106 | |
107 return; | |
108 | |
109 parse_fail: | |
110 error_exit("bad expression %d@%d: %s", which, i, script->arg+i); | |
111 } | |
53 | 112 |
54 void sed_main(void) | 113 void sed_main(void) |
55 { | 114 { |
56 struct arg_list *test; | 115 char **files=toys.optargs; |
57 | 116 |
58 for (test = TT.commands; test; test = test->next) | 117 // If no -e, use first argument |
59 dprintf(2,"command=%s\n",test->arg); | 118 if (!TT.scripts) { |
119 if (!*files) error_exit("Need script"); | |
120 (TT.scripts=xzalloc(sizeof(struct arg_list)))->arg=*(files++); | |
121 } | |
60 | 122 |
61 printf("Hello world\n"); | 123 |
124 { | |
125 struct arg_list *test; | |
126 | |
127 for (test = TT.commands; test; test = test->next) | |
128 dprintf(2,"command=%s\n",test->arg); | |
129 while (*files) dprintf(2,"file=%s\n", *(files++)); | |
130 } | |
62 } | 131 } |