Mercurial > hg > toybox
annotate toys/pending/sed.c @ 1532:bf2c5216d726 draft
Basic sed range support, enough for "sed -n 9,11p README" to work.
author | Rob Landley <rob@landley.net> |
---|---|
date | Fri, 24 Oct 2014 18:16:32 -0500 |
parents | 3eafa445c1a6 |
children | a6ef79b31829 |
rev | line source |
---|---|
1520
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
1 /* sed.c - stream editor |
233
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
231
diff
changeset
|
2 * |
1520
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
3 * Copyright 2014 Rob Landley <rob@landley.net> |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
4 * |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
5 * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sed.html |
233
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
231
diff
changeset
|
6 * |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
7 * todo "-e blah -f blah -e blah" what order? (All -e, then all -f.) |
1520
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
8 * What happens when first address matched, then EOF? How about ",42" or "1," |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
9 * Does $ match last line of file or last line of input |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
10 * If file doesn't end with newline |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
11 * command preceded by whitespace. whitespace before rw or s///w file |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
12 * space before address |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
13 * numerical addresses that cross, select one line |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
14 * test backslash escapes in regex; share code with printf? |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
15 * address counts lines cumulatively across files |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
16 * Why can't I start an address with \\ (posix says no, but _why_?) |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
17 * Fun with \nblah\nn vs \tblah\tt |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
18 * |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
19 * echo -e "one\ntwo\nthree" | sed -n '$,$p' |
233
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
231
diff
changeset
|
20 |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
21 USE_SED(NEWTOY(sed, "(version)e*f*inr", TOYFLAG_USR|TOYFLAG_BIN)) |
234
163498bf547b
Move NEWTOY() list from end of toylist.h to generated/newtoys.h.
Rob Landley <rob@landley.net>
parents:
233
diff
changeset
|
22 |
233
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
231
diff
changeset
|
23 config SED |
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.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
24 bool "sed" |
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.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
25 default n |
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.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
26 help |
1520
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
27 usage: sed [-inr] [-e SCRIPT]...|SCRIPT [-f SCRIPT_FILE]... [FILE...] |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
28 |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
29 Stream editor. Apply one or more editing SCRIPTs to each line of each line |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
30 of input (from FILE or stdin) producing output (by default to stdout). |
233
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
231
diff
changeset
|
31 |
1520
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
32 -e add SCRIPT to list |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
33 -f add contents of SCRIPT_FILE to list |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
34 -i Edit each file in place. |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
35 -n No default output. (Use the p command to output matched lines.) |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
36 -r Use extended regular expression syntax. |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
37 |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
38 A SCRIPT is a series of one or more COMMANDs separated by newlines or |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
39 semicolons. All -e SCRIPTs are concatenated together as if separated |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
40 by newlines, followed by all lines from -f SCRIPT_FILEs, in order. |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
41 If no -e or -f SCRIPTs are specified, the first argument is the SCRIPT. |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
42 |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
43 Each COMMAND may be preceded by an address which limits the command to |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
44 run only on the specified lines: |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
45 |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
46 [ADDRESS[,ADDRESS]]COMMAND |
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.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
47 |
1520
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
48 The ADDRESS may be a decimal line number (starting at 1), a /regular |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
49 expression/ within a pair of forward slashes, or the character "$" which |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
50 matches the last line of input. A single address matches one line, a pair |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
51 of comma separated addresses match everything from the first address to |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
52 the second address (inclusive). If both addresses are regular expressions, |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
53 more than one range of lines in each file can match. |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
54 |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
55 REGULAR EXPRESSIONS in sed are started and ended by the same character |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
56 (traditionally / but anything except a backslash or a newline works). |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
57 Backslashes may be used to escape the delimiter if it occurs in the |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
58 regex, and for the usual printf escapes (\abcefnrtv and octal, hex, |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
59 and unicode). An empty regex repeats the previous one. ADDRESS regexes |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
60 (above) require the first delimeter to be escaped with a backslash when |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
61 it isn't a forward slash (to distinguish it from the COMMANDs below). |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
62 |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
63 Each COMMAND starts with a single character, which may be followed by |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
64 additional data depending on the COMMAND: |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
65 |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
66 rwbrstwy:{ |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
67 |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
68 s search and replace |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
69 |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
70 The search and replace syntax |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
71 |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
72 Deviations from posix: we allow extended regular expressions with -r, |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
73 editing in place with -i, printf escapes in text, semicolons after. |
233
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
231
diff
changeset
|
74 */ |
231
31dc682c18ad
Very early stub of sed, does nothing yet.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
75 |
674
7e846e281e38
New build infrastructure to generate FLAG_ macros and TT alias, #define FOR_commandname before #including toys.h to trigger it. Rename DEFINE_GLOBALS() to just GLOBALS() (because I could never remember if it was DECLARE_GLOBALS). Convert existing commands to use new infrastructure, and replace optflag constants with FLAG_ macros where appropriate.
Rob Landley <rob@landley.net>
parents:
656
diff
changeset
|
76 #define FOR_sed |
231
31dc682c18ad
Very early stub of sed, does nothing yet.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
77 #include "toys.h" |
31dc682c18ad
Very early stub of sed, does nothing yet.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
78 |
674
7e846e281e38
New build infrastructure to generate FLAG_ macros and TT alias, #define FOR_commandname before #including toys.h to trigger it. Rename DEFINE_GLOBALS() to just GLOBALS() (because I could never remember if it was DECLARE_GLOBALS). Convert existing commands to use new infrastructure, and replace optflag constants with FLAG_ macros where appropriate.
Rob Landley <rob@landley.net>
parents:
656
diff
changeset
|
79 GLOBALS( |
1520
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
80 struct arg_list *f; |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
81 struct arg_list *e; |
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.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
82 |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
83 // processed pattern list |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
84 struct double_list *pattern; |
1532
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
85 |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
86 char *nextline; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
87 long nextlen, count; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
88 int fdout, noeol; |
237
7cb15eae1664
Zap toylist.h, moving contents of global structures into DEFINE_GLOBALS()
Rob Landley <rob@landley.net>
parents:
234
diff
changeset
|
89 ) |
7cb15eae1664
Zap toylist.h, moving contents of global structures into DEFINE_GLOBALS()
Rob Landley <rob@landley.net>
parents:
234
diff
changeset
|
90 |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
91 struct step { |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
92 struct step *next, *prev; |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
93 |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
94 // Begin and end of each match |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
95 long lmatch[2]; |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
96 regex_t *rmatch[2]; |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
97 |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
98 // Action |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
99 char c; |
1532
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
100 |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
101 int hit; |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
102 }; |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
103 |
1532
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
104 // Write out line with potential embedded NUL, handling eol/noeol |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
105 static int emit(char *line, long len, int eol) |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
106 { |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
107 if (TT.noeol && !writeall(TT.fdout, "\n", 1)) return 1; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
108 if (eol) line[len++] = '\n'; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
109 TT.noeol = !eol; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
110 if (len != writeall(TT.fdout, line, len)) { |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
111 perror_msg("short write"); |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
112 |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
113 return 1; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
114 } |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
115 |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
116 return 0; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
117 } |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
118 |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
119 // Do regex matching handling embedded NUL bytes in string. |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
120 static int ghostwheel(regex_t *preg, char *string, int nmatch, |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
121 regmatch_t pmatch[], int eflags) |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
122 { |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
123 // todo: this |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
124 return regexec(preg, string, nmatch, pmatch, eflags); |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
125 } |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
126 |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
127 // Apply pattern to line from input file |
1532
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
128 static void sed_line(char **pline, long plen) |
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.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
129 { |
1532
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
130 char *line = TT.nextline; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
131 long len = TT.nextlen; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
132 struct step *logrus; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
133 int eol = 0; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
134 |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
135 // Grab next line for deferred processing (EOF detection, we get a NULL |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
136 // pline at EOF to flush last line). Note that only end of _last_ input |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
137 // file matches $ (unless we're doing -i). |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
138 if (pline) { |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
139 TT.nextline = *pline; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
140 TT.nextlen = plen; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
141 *pline = 0; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
142 } |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
143 |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
144 if (!line || !len) return; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
145 |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
146 if (line[len-1] == '\n') line[--len] = eol++; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
147 TT.count++; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
148 |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
149 for (logrus = (void *)TT.pattern; logrus; logrus = logrus->next) { |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
150 char c = logrus->c; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
151 |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
152 // Have we got a matching range for this rule? |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
153 if (logrus->lmatch || *logrus->rmatch) { |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
154 int miss = 0; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
155 long lm; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
156 regex_t *rm; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
157 |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
158 // In a match that might end? |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
159 if (logrus->hit) { |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
160 if (!(lm = logrus->lmatch[1])) { |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
161 if (!(rm = logrus->rmatch[1])) logrus->hit = 0; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
162 else { |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
163 // regex match end includes matching line, so defer deactivation |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
164 if (!ghostwheel(rm, line, 0, 0, 0)) miss = 1; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
165 } |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
166 } else if (lm > 0 && lm < TT.count) logrus->hit = 0; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
167 |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
168 // Start a new match? |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
169 } else { |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
170 if (!(lm = *logrus->lmatch)) { |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
171 if (!ghostwheel(*logrus->rmatch, line, 0, 0, 0)) logrus->hit++; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
172 } else if (lm == TT.count) logrus->hit++; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
173 } |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
174 |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
175 if (!logrus->hit) continue; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
176 if (miss) logrus->hit = 0; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
177 } |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
178 |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
179 // Process like the wind, bullseye! |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
180 |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
181 // todo: embedded NUL, eol |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
182 if (c == 'p') { |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
183 if (emit(line, len, eol)) break; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
184 } else error_exit("what?"); |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
185 } |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
186 |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
187 if (!(toys.optflags & FLAG_n)) emit(line, len, eol); |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
188 |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
189 free(line); |
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.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
190 } |
231
31dc682c18ad
Very early stub of sed, does nothing yet.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
191 |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
192 // Genericish function, can probably get moved to lib.c |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
193 |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
194 // Iterate over lines in file, calling function. Function can write NULL to |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
195 // the line pointer if they want to keep it, otherwise line is freed. |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
196 // Passed file descriptor is closed at the end of processing. |
1520
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
197 static void do_lines(int fd, char *name, void (*call)(char **pline, long len)) |
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.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
198 { |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
199 FILE *fp = xfdopen(fd, "r"); |
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.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
200 |
1520
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
201 for (;;) { |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
202 char *line = 0; |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
203 ssize_t len; |
231
31dc682c18ad
Very early stub of sed, does nothing yet.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
204 |
1520
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
205 len = getline(&line, (void *)&len, fp); |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
206 call(&line, len); |
1520
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
207 free(line); |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
208 if (len < 1) break; |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
209 } |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
210 fclose(fp); |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
211 } |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
212 |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
213 // Iterate over newline delimited data blob (potentially with embedded NUL), |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
214 // call function on each line. |
1532
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
215 static void chop_lines(char *data, long len, void (*call)(char **p, long l)) |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
216 { |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
217 long ll; |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
218 |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
219 for (ll = 0; ll < len; ll++) { |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
220 if (data[ll] == '\n') { |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
221 char *c = data; |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
222 |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
223 data[ll] = 0; |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
224 call(&c, len); |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
225 data[ll++] = '\n'; |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
226 data += ll; |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
227 len -= ll; |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
228 ll = -1; |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
229 } |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
230 } |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
231 if (len) call(&data, len); |
1520
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
232 } |
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.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
233 |
1520
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
234 static void do_sed(int fd, char *name) |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
235 { |
1532
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
236 int i = toys.optflags & FLAG_i; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
237 |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
238 if (i) { |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
239 // todo: rename dance |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
240 } |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
241 do_lines(fd, name, sed_line); |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
242 if (i) { |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
243 sed_line(0, 0); |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
244 |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
245 // todo: rename dance |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
246 } |
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.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
247 } |
231
31dc682c18ad
Very early stub of sed, does nothing yet.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
248 |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
249 // Translate primal pattern into walkable form. |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
250 static void jewel_of_judgement(char **pline, long len) |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
251 { |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
252 struct step *corwin; |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
253 char *line = *pline, *reg; |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
254 int i; |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
255 |
1532
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
256 for (line = *pline;;line++) { |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
257 while (isspace(*line)) line++; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
258 if (*line == '#') return; |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
259 |
1532
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
260 memset(toybuf, 0, sizeof(struct step)); |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
261 corwin = (void *)toybuf; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
262 reg = toybuf + sizeof(struct step); |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
263 |
1532
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
264 // Parse address range (if any) |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
265 for (i = 0; i < 2; i++) { |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
266 if (*line == ',') line++; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
267 else if (i) break; |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
268 |
1532
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
269 if (isdigit(*line)) corwin->lmatch[i] = strtol(line, &line, 0); |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
270 else if (*line == '$') { |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
271 corwin->lmatch[i] = -1; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
272 line++; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
273 } else if (*line == '/' || *line == '\\') { |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
274 char delim = *(line++), slash = 0, *to, *from; |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
275 |
1532
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
276 if (delim == '\\') { |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
277 if (!*line) goto brand; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
278 slash = delim = *(line++); |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
279 } |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
280 |
1532
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
281 // Removing backslash escapes edits the source string, which could |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
282 // be from the environment space via -e, which could screw up what |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
283 // "ps" sees, and I'm ok with that. |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
284 for (to = from = line; *from != delim; *(to++) = *(from++)) { |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
285 if (!*from) goto brand; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
286 if (*from == '\\') { |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
287 if (!from[1]) goto brand; |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
288 |
1532
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
289 // Check escaped end delimiter before printf style escapes. |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
290 if (from[1] == slash) from++; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
291 else { |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
292 char c = unescape(from[1]); |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
293 |
1532
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
294 if (c) { |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
295 *to = c; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
296 from++; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
297 } |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
298 } |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
299 } |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
300 } |
1532
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
301 slash = *to; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
302 *to = 0; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
303 xregcomp(corwin->rmatch[i] = (void *)reg, line, |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
304 ((toys.optflags & FLAG_r)*REG_EXTENDED)|REG_NOSUB); |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
305 *to = slash; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
306 reg += sizeof(regex_t); |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
307 line = from + 1; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
308 } else break; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
309 } |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
310 |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
311 while (isspace(*line)) line++; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
312 |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
313 if (!*line || !strchr("p", *line)) break; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
314 corwin->c = *(line++); |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
315 |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
316 // Add step to pattern |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
317 corwin = xmalloc(reg-toybuf); |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
318 memcpy(corwin, toybuf, reg-toybuf); |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
319 dlist_add_nomalloc(&TT.pattern, (void *)corwin); |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
320 |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
321 while (isspace(*line)) line++; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
322 if (!*line) return; |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
323 if (*line != ';') break; |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
324 } |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
325 |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
326 brand: |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
327 // Reminisce about chestnut trees. |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
328 error_exit("bad pattern '%s'@%ld (%c)", *pline, line-*pline, *line); |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
329 } |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
330 |
231
31dc682c18ad
Very early stub of sed, does nothing yet.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
331 void sed_main(void) |
31dc682c18ad
Very early stub of sed, does nothing yet.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
332 { |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
333 struct arg_list *dworkin; |
1520
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
334 char **args = toys.optargs; |
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.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
335 |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
336 // Lie to autoconf when it asks stupid questions, so configure regexes |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
337 // that look for "GNU sed version %f" greater than some old buggy number |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
338 // don't fail us for not matching their narrow expectations. |
1532
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
339 if (toys.optflags & FLAG_version) { |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
340 xprintf("This is not GNU sed version 9.0\n"); |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
341 return; |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
342 } |
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
343 |
1532
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
344 // Need a pattern. If no unicorns about, fight serpent and take its eye. |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
345 if (!TT.e && !TT.f) { |
1520
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
346 if (!*toys.optargs) error_exit("no pattern"); |
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
347 (TT.e = xzalloc(sizeof(struct arg_list)))->arg = *(args++); |
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.
Rob Landley <rob@landley.net>
parents:
674
diff
changeset
|
348 } |
1532
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
349 for (dworkin = TT.e; dworkin; dworkin = dworkin->next) |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
350 chop_lines(dworkin->arg, strlen(dworkin->arg), jewel_of_judgement); |
1532
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
351 for (dworkin = TT.f; dworkin; dworkin = dworkin->next) |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
352 do_lines(xopen(dworkin->arg, O_RDONLY), dworkin->arg, jewel_of_judgement); |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
353 dlist_terminate(TT.pattern); |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
354 |
1532
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
355 TT.fdout = 1; |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
356 |
1520
dfd6b3404c16
Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents:
1235
diff
changeset
|
357 // Inflict pattern upon input files |
1530
3eafa445c1a6
Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents:
1520
diff
changeset
|
358 loopfiles_rw(args, O_RDONLY, 0, 0, do_sed); |
1532
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
359 |
bf2c5216d726
Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents:
1530
diff
changeset
|
360 if (!(toys.optflags & FLAG_i)) sed_line(0, 0); |
231
31dc682c18ad
Very early stub of sed, does nothing yet.
Rob Landley <rob@landley.net>
parents:
diff
changeset
|
361 } |