annotate toys/pending/sed.c @ 1611:50dc30893f9d draft

Fix bug in sed y/// where bytes in target but not in source were replaced by zeroes (nul terminator overwritten).
author Rob Landley <rob@landley.net>
date Sat, 13 Dec 2014 18:35:11 -0600
parents 74e2642c35e8
children eec3b88f2d58
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1537
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
1 /* sed.c - stream editor. Thing that does s/// and other stuff.
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
1558
47647eebc5f9 Fix sed 'b' with no label and 'N' in general.
Rob Landley <rob@landley.net>
parents: 1557
diff changeset
6 *
47647eebc5f9 Fix sed 'b' with no label and 'N' in general.
Rob Landley <rob@landley.net>
parents: 1557
diff changeset
7 * TODO: lines > 2G could signed int wrap length counters. Not just getline()
47647eebc5f9 Fix sed 'b' with no label and 'N' in general.
Rob Landley <rob@landley.net>
parents: 1557
diff changeset
8 * but N and s///
233
d4176f3f3835 Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents: 231
diff changeset
9
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
10 USE_SED(NEWTOY(sed, "(version)e*f*inr", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
234
163498bf547b Move NEWTOY() list from end of toylist.h to generated/newtoys.h.
Rob Landley <rob@landley.net>
parents: 233
diff changeset
11
233
d4176f3f3835 Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents: 231
diff changeset
12 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
13 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
14 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
15 help
1520
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
16 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
17
1537
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
18 Stream editor. Apply one or more editing SCRIPTs to each line of input
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
19 (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
20
1520
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
21 -e add SCRIPT to list
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
22 -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
23 -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
24 -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
25 -r Use extended regular expression syntax.
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
26 -s Treat input files separately (implied by -i)
1520
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
27
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
28 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
29 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
30 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
31 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
32
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
33 Each COMMAND may be preceded by an address which limits the command to
1537
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
34 apply only to the specified line(s). Commands without an address apply to
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
35 every line. Addresses are of the form:
1520
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
36
1537
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
37 [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
38
1520
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
39 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
40 expression/ within a pair of forward slashes, or the character "$" which
1537
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
41 matches the last line of input. (In -s or -i mode this matches the last
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
42 line of each file, otherwise just the last line of the last file.) A single
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
43 address matches one line, a pair of comma separated addresses match
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
44 everything from the first address to the second address (inclusive). If
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
45 both addresses are regular expressions, more than one range of lines in
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
46 each file can match.
1520
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
47
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
48 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
49 (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
50 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
51 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
52 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
53 (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
54 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
55
1537
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
56 Sed mostly operates on individual lines one at a time. It reads each line,
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
57 processes it, and either writes it to the output or discards it before
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
58 reading the next line. Sed can remember one additional line in a separate
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
59 buffer (using the h, H, g, G, and x commands), and can read the next line
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
60 of input early (using the n and N command), but other than that command
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
61 scripts operate on individual lines of text.
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
62
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
63 Each COMMAND starts with a single character. The following commands take
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
64 no arguments:
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
65
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
66 { Start a new command block, continuing until a corresponding "}".
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
67 Command blocks may nest. If the block has an address, commands within
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
68 the block are only run for lines within the block's address range.
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
69
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
70 } End command block (this command cannot have an address)
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
71
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
72 d Delete this line and move on to the next one
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
73 (ignores remaining COMMANDs)
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
74
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
75 D Delete one line of input and restart command SCRIPT (same as "d"
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
76 unless you've glued lines together with "N" or similar)
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
77
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
78 g Get remembered line (overwriting current line)
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
79
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
80 G Get remembered line (appending to current line)
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
81
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
82 h Remember this line (overwriting remembered line)
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
83
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
84 H Remember this line (appending to remembered line, if any)
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
85
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
86 l Print this line, escaping \abfrtv (but leaving \n as a newline),
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
87 using octal escapes for other nonprintable characters, and
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
88 wrapping lines to terminal width with a backslash and newline
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
89
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
90 n Print default output and read next line, replacing current line
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
91 (If no next line available, quit processing script)
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
92
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
93 N Append next line of input to this line, separated by a newline
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
94 (This advances the line counter for address matching and "=", if no
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
95 next line available quit processing script without default output)
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
96
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
97 p Print this line
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
98
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
99 P Print this line up to first newline (from "N")
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
100
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
101 q Quit (print default output, no more commands processed or lines read)
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
102
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
103 x Exchange this line with remembered line (overwrite in both directions)
1520
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
104
1537
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
105 = Print the current line number (followed by a newline)
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
106
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
107 The following commands (may) take an argument. The "text" arguments (to
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
108 the "a", "b", and "c" commands) may end with an unescaped "\" to append
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
109 the next line (for which leading whitespace is not skipped), and also
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
110 treat ";" as a literal character (use "\;" instead).
1537
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
111
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
112 a [text] Append text to output before attempting to read next line
1537
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
113
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
114 b [label] Branch, jumps to :label (or with no label, to end of SCRIPT)
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
115
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
116 c [text] Delete line, output text at end of matching address range
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
117 (ignores remaining COMMANDs)
1537
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
118
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
119 i [text] Print text
1537
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
120
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
121 r [file] Append contents of file to output before attempting to read
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
122 next line.
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
123
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
124 s/S/R/F Search for regex S, replace matched text with R using flags F.
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
125 The first character after the "s" (anything but newline or
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
126 backslash) is the delimiter, escape with \ to use normally.
1520
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
127
1537
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
128 The replacement text may contain "&" to substitute the matched
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
129 text (escape it with backslash for a literal &), or \1 through
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
130 \9 to substitute a parenthetical subexpression in the regex.
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
131 You can also use the normal backslash escapes such as \n and
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
132 a backslash at the end of the line appends the next line.
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
133
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
134 The flags are:
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
135
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
136 [0-9] A number, substitute only that occurrence of pattern
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
137 g Global, substitute all occurrences of pattern
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
138 i Ignore case when matching
1537
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
139 p Print the line if match was found and replaced
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
140 w [file] Write (append) line to file if match replaced
1520
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
141
1537
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
142 t [label] Test, jump to :label only if an "s" command found a match in
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
143 this line since last test (replacing with same text counts)
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
144
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
145 T [label] Test false, jump only if "s" hasn't found a match.
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
146
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
147 w [file] Write (append) line to file
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
148
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
149 y/old/new/ Change each character in 'old' to corresponding character
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
150 in 'new' (with standard backslash escapes, delimiter can be
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
151 any repeated character except \ or \n)
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
152
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
153 : [label] Labeled target for jump commands
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
154
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
155 # Comment, ignore rest of this line of SCRIPT
1520
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
156
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
157 Deviations from posix: allow extended regular expressions with -r,
1537
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
158 editing in place with -i, separate with -s, printf escapes in text, line
a6ef79b31829 Fill out rest of help text for sed.
Rob Landley <rob@landley.net>
parents: 1532
diff changeset
159 continuations, semicolons after all commands, 2-address anywhere an
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
160 address is allowed, "T" command, multiline continuations for [abc],
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
161 \; to end [abc] argument before end of line.
233
d4176f3f3835 Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents: 231
diff changeset
162 */
231
31dc682c18ad Very early stub of sed, does nothing yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
163
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
164 #define FOR_sed
231
31dc682c18ad Very early stub of sed, does nothing yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
165 #include "toys.h"
31dc682c18ad Very early stub of sed, does nothing yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
166
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
167 GLOBALS(
1520
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
168 struct arg_list *f;
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
169 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
170
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
171 // processed pattern list
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
172 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
173
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
174 char *nextline, *remember;
1560
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
175 void *restart, *lastregex;
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
176 long nextlen, rememberlen, count;
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
177 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
178 )
7cb15eae1664 Zap toylist.h, moving contents of global structures into DEFINE_GLOBALS()
Rob Landley <rob@landley.net>
parents: 234
diff changeset
179
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
180 struct step {
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
181 struct step *next, *prev;
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
182
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
183 // 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
184 long lmatch[2];
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
185 int rmatch[2], arg1, arg2, w; // offsets because remalloc()
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
186 unsigned not, hit, sflags;
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
187 char c; // action
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
188 };
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
189
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
190 // 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
191 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
192 {
1560
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
193 int l, old = line[len];
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
194
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
195 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
196 if (eol) line[len++] = '\n';
1560
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
197 if (!len) return 0;
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
198 TT.noeol = len && !eol;
1560
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
199 l = writeall(TT.fdout, line, len);
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
200 if (eol) line[len-1] = old;
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
201 if (l != len) {
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
202 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
203
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
204 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
205 }
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
206
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
207 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
208 }
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
209
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
210 // Do regex matching handling embedded NUL bytes in string. Note that
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
211 // neither the pattern nor the match can currently include NUL bytes
1559
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
212 // (even with wildcards) and string must be null terminated.
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
213 static int ghostwheel(regex_t *preg, char *string, long len, int nmatch,
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
214 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
215 {
1559
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
216 char *s = string;
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
217
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
218 for (;;) {
1559
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
219 long ll = 0;
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
220 int rc;
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
221
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
222 while (len && !*s) {
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
223 s++;
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
224 len--;
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
225 }
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
226 while (s[ll] && ll<len) ll++;
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
227
1559
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
228 rc = regexec(preg, s, nmatch, pmatch, eflags);
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
229 if (!rc) {
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
230 for (rc = 0; rc<nmatch && pmatch[rc].rm_so!=-1; rc++) {
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
231 pmatch[rc].rm_so += s-string;
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
232 pmatch[rc].rm_eo += s-string;
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
233 }
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
234
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
235 return 0;
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
236 }
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
237 if (ll==len) return rc;
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
238
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
239 s += ll;
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
240 len -= ll;
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
241 }
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
242 }
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
243
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
244 // Extend allocation to include new string, with newline between if newlen<0
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
245
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
246 static char *extend_string(char **old, char *new, int oldlen, int newlen)
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
247 {
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
248 int newline = newlen < 0;
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
249 char *s;
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
250
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
251 if (newline) newlen = -newlen;
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
252 s = *old = xrealloc(*old, oldlen+newlen+newline+1);
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
253 if (newline) s[oldlen++] = '\n';
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
254 memcpy(s+oldlen, new, newlen);
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
255 s[oldlen+newlen] = 0;
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
256
1611
50dc30893f9d Fix bug in sed y/// where bytes in target but not in source were replaced by zeroes (nul terminator overwritten).
Rob Landley <rob@landley.net>
parents: 1610
diff changeset
257 return s+oldlen+newlen+1;
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
258 }
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
259
1560
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
260 // An empty regex repeats the previous one
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
261 void *get_regex(void *trump, int offset)
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
262 {
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
263 if (!offset) {
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
264 if (!TT.lastregex) error_exit("no previous regex");
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
265 return TT.lastregex;
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
266 }
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
267
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
268 return TT.lastregex = offset+(char *)trump;
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
269 }
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
270
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
271 // Apply pattern to line from input file
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
272 static void walk_pattern(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
273 {
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
274 struct append {
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
275 struct append *next, *prev;
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
276 int file;
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
277 char *str;
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
278 } *append = 0;
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
279 char *line = TT.nextline;
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
280 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
281 struct step *logrus;
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
282 int eol = 0, tea = 0;
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
283
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
284 // Grab next line for deferred processing (EOF detection: we get a NULL
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
285 // 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
286 // file matches $ (unless we're doing -i).
1561
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
287 TT.nextline = 0;
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
288 TT.nextlen = 0;
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 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
290 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
291 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
292 *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
293 }
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
294
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
295 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
296 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
297 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
298
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
299 logrus = TT.restart ? TT.restart : (void *)TT.pattern;
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
300 TT.restart = 0;
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
301
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
302 while (logrus) {
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
303 char *str, c = logrus->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
304
1556
e7944f8fdcbb Debugging pass on sed: make the existing test suite pass.
Rob Landley <rob@landley.net>
parents: 1553
diff changeset
305 // Have we got a line or regex matching range for this rule?
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
306 if (*logrus->lmatch || *logrus->rmatch) {
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
307 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
308 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
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 // 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
311 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
312 if (!(lm = logrus->lmatch[1])) {
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
313 if (!logrus->rmatch[1]) logrus->hit = 0;
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
314 else {
1560
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
315 void *rm = get_regex(logrus, logrus->rmatch[1]);
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
316
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
317 // regex match end includes matching line, so defer deactivation
1560
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
318 if (line && !ghostwheel(rm, line, len, 0, 0, 0)) miss = 1;
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
319 }
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
320 } 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
321
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
322 // 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
323 } else {
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
324 if (!(lm = *logrus->lmatch)) {
1560
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
325 void *rm = get_regex(logrus, *logrus->rmatch);
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
326
1560
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
327 if (line && !ghostwheel(rm, line, len, 0, 0, 0)) logrus->hit++;
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
328 } else if (lm == TT.count || (lm == -1 && !pline)) logrus->hit++;
1601
2dcc165f6e21 Fix some sed bugs and improve error reporting.
Rob Landley <rob@landley.net>
parents: 1577
diff changeset
329
2dcc165f6e21 Fix some sed bugs and improve error reporting.
Rob Landley <rob@landley.net>
parents: 1577
diff changeset
330 if (!logrus->lmatch[1] && !logrus->rmatch[1]) miss = 1;
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
331 }
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
332
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
333 // Didn't match?
1601
2dcc165f6e21 Fix some sed bugs and improve error reporting.
Rob Landley <rob@landley.net>
parents: 1577
diff changeset
334 lm = !(logrus->hit ^ logrus->not);
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
335
1601
2dcc165f6e21 Fix some sed bugs and improve error reporting.
Rob Landley <rob@landley.net>
parents: 1577
diff changeset
336 // Deferred disable from regex end match
2dcc165f6e21 Fix some sed bugs and improve error reporting.
Rob Landley <rob@landley.net>
parents: 1577
diff changeset
337 if (miss || logrus->lmatch[1] == TT.count) logrus->hit = 0;
2dcc165f6e21 Fix some sed bugs and improve error reporting.
Rob Landley <rob@landley.net>
parents: 1577
diff changeset
338
2dcc165f6e21 Fix some sed bugs and improve error reporting.
Rob Landley <rob@landley.net>
parents: 1577
diff changeset
339 if (lm) {
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
340 // Handle skipping curly bracket command group
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
341 if (c == '{') {
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
342 int curly = 1;
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
343
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
344 while (curly) {
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
345 logrus = logrus->next;
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
346 if (logrus->c == '{') curly++;
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
347 if (logrus->c == '}') curly--;
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
348 }
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
349 }
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
350 logrus = logrus->next;
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
351 continue;
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
352 }
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
353 }
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
354
1560
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
355 // A deleted line can still update line match state for later commands
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
356 if (!line) {
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
357 logrus = logrus->next;
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
358 continue;
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
359 }
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
360
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
361 // Process command
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
362
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
363 if (c=='a' || c=='r') {
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
364 struct append *a = xzalloc(sizeof(struct append));
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
365 a->str = logrus->arg1+(char *)logrus;
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
366 a->file = c== 'r';
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
367 dlist_add_nomalloc((void *)&append, (void *)a);
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
368 } else if (c=='b' || c=='t' || c=='T') {
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
369 int t = tea;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
370
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
371 if (c != 'b') tea = 0;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
372 if (c=='b' || t^(c=='T')) {
1558
47647eebc5f9 Fix sed 'b' with no label and 'N' in general.
Rob Landley <rob@landley.net>
parents: 1557
diff changeset
373 if (!logrus->arg1) break;
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
374 str = logrus->arg1+(char *)logrus;
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
375 for (logrus = (void *)TT.pattern; logrus; logrus = logrus->next)
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
376 if (logrus->c == ':' && !strcmp(logrus->arg1+(char *)logrus, str))
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
377 break;
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
378 if (!logrus) error_exit("no :%s", str);
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
379 }
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
380 } else if (c=='c') {
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
381 str = logrus->arg1+(char *)logrus;
1601
2dcc165f6e21 Fix some sed bugs and improve error reporting.
Rob Landley <rob@landley.net>
parents: 1577
diff changeset
382 if (!logrus->hit) emit(str, strlen(str), 1);
1577
ac84a209cb05 sed: c needs to trigger range logic like d, D works like d when there isn't anything left in the line, and more tests.
Rob Landley <rob@landley.net>
parents: 1562
diff changeset
383 free(line);
ac84a209cb05 sed: c needs to trigger range logic like d, D works like d when there isn't anything left in the line, and more tests.
Rob Landley <rob@landley.net>
parents: 1562
diff changeset
384 line = 0;
ac84a209cb05 sed: c needs to trigger range logic like d, D works like d when there isn't anything left in the line, and more tests.
Rob Landley <rob@landley.net>
parents: 1562
diff changeset
385 continue;
1560
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
386 } else if (c=='d') {
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
387 free(line);
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
388 line = 0;
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
389 continue;
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
390 } else if (c=='D') {
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
391 // Delete up to \n or end of buffer
1577
ac84a209cb05 sed: c needs to trigger range logic like d, D works like d when there isn't anything left in the line, and more tests.
Rob Landley <rob@landley.net>
parents: 1562
diff changeset
392 str = line;
ac84a209cb05 sed: c needs to trigger range logic like d, D works like d when there isn't anything left in the line, and more tests.
Rob Landley <rob@landley.net>
parents: 1562
diff changeset
393 while ((str-line)<len) if (*(str++) == '\n') break;
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
394 len -= str - line;
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
395 memmove(line, str, len);
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
396
1577
ac84a209cb05 sed: c needs to trigger range logic like d, D works like d when there isn't anything left in the line, and more tests.
Rob Landley <rob@landley.net>
parents: 1562
diff changeset
397 // if "delete" blanks line, disable further processing
ac84a209cb05 sed: c needs to trigger range logic like d, D works like d when there isn't anything left in the line, and more tests.
Rob Landley <rob@landley.net>
parents: 1562
diff changeset
398 // otherwise trim and restart script
ac84a209cb05 sed: c needs to trigger range logic like d, D works like d when there isn't anything left in the line, and more tests.
Rob Landley <rob@landley.net>
parents: 1562
diff changeset
399 if (!len) {
ac84a209cb05 sed: c needs to trigger range logic like d, D works like d when there isn't anything left in the line, and more tests.
Rob Landley <rob@landley.net>
parents: 1562
diff changeset
400 free(line);
ac84a209cb05 sed: c needs to trigger range logic like d, D works like d when there isn't anything left in the line, and more tests.
Rob Landley <rob@landley.net>
parents: 1562
diff changeset
401 line = 0;
ac84a209cb05 sed: c needs to trigger range logic like d, D works like d when there isn't anything left in the line, and more tests.
Rob Landley <rob@landley.net>
parents: 1562
diff changeset
402 } else {
ac84a209cb05 sed: c needs to trigger range logic like d, D works like d when there isn't anything left in the line, and more tests.
Rob Landley <rob@landley.net>
parents: 1562
diff changeset
403 line[len] = 0;
ac84a209cb05 sed: c needs to trigger range logic like d, D works like d when there isn't anything left in the line, and more tests.
Rob Landley <rob@landley.net>
parents: 1562
diff changeset
404 logrus = (void *)TT.pattern;
ac84a209cb05 sed: c needs to trigger range logic like d, D works like d when there isn't anything left in the line, and more tests.
Rob Landley <rob@landley.net>
parents: 1562
diff changeset
405 }
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
406 continue;
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
407 } else if (c=='g') {
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
408 free(line);
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
409 line = xstrdup(TT.remember);
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
410 len = TT.rememberlen;
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
411 } else if (c=='G') {
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
412 line = xrealloc(line, len+TT.rememberlen+2);
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
413 line[len++] = '\n';
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
414 memcpy(line+len, TT.remember, TT.rememberlen);
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
415 line[len += TT.rememberlen] = 0;
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
416 } else if (c=='h') {
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
417 free(TT.remember);
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
418 TT.remember = xstrdup(line);
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
419 TT.rememberlen = len;
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
420 } else if (c=='H') {
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
421 TT.remember = xrealloc(TT.remember, TT.rememberlen+len+2);
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
422 TT.remember[TT.rememberlen++] = '\n';
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
423 memcpy(TT.remember+TT.rememberlen, line, len);
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
424 TT.remember[TT.rememberlen += len] = 0;
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
425 } else if (c=='i') {
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
426 str = logrus->arg1+(char *)logrus;
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
427 emit(str, strlen(str), 1);
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
428 // } else if (c=='l') {
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
429 // error_exit("todo: l");
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
430 } else if (c=='n') {
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
431 TT.restart = logrus->next;
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
432
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
433 break;
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
434 } else if (c=='N') {
1558
47647eebc5f9 Fix sed 'b' with no label and 'N' in general.
Rob Landley <rob@landley.net>
parents: 1557
diff changeset
435 // Can't just grab next line because we could have multiple N and
47647eebc5f9 Fix sed 'b' with no label and 'N' in general.
Rob Landley <rob@landley.net>
parents: 1557
diff changeset
436 // we need to actually read ahead to get N;$p EOF detection right.
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
437 if (pline) {
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
438 TT.restart = logrus->next;
1558
47647eebc5f9 Fix sed 'b' with no label and 'N' in general.
Rob Landley <rob@landley.net>
parents: 1557
diff changeset
439 extend_string(&line, TT.nextline, len, -TT.nextlen);
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
440 free(TT.nextline);
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
441 TT.nextline = line;
1558
47647eebc5f9 Fix sed 'b' with no label and 'N' in general.
Rob Landley <rob@landley.net>
parents: 1557
diff changeset
442 TT.nextlen += len + 1;
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
443 line = 0;
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
444 }
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
445
1558
47647eebc5f9 Fix sed 'b' with no label and 'N' in general.
Rob Landley <rob@landley.net>
parents: 1557
diff changeset
446 // Pending append goes out right after N
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
447 goto done;
1559
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
448 } else if (c=='p' || c=='P') {
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
449 char *l = (c=='P') ? strchr(line, '\n') : 0;
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
450
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
451 if (emit(line, l ? l-line : len, eol)) break;
1561
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
452 } else if (c=='q') {
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
453 if (pline) *pline = (void *)1;
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
454 free(TT.nextline);
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
455 TT.nextline = 0;
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
456 TT.nextlen = 0;
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
457
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
458 break;
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
459 } else if (c=='s') {
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
460 char *rline = line, *new = logrus->arg2 + (char *)logrus, *swap, *rswap;
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
461 regmatch_t *match = (void *)toybuf;
1560
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
462 regex_t *reg = get_regex(logrus, logrus->arg1);
1556
e7944f8fdcbb Debugging pass on sed: make the existing test suite pass.
Rob Landley <rob@landley.net>
parents: 1553
diff changeset
463 int mflags = 0, count = 0, zmatch = 1, rlen = len, mlen, off, newlen;
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
464
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
465 // Find match in remaining line (up to remaining len)
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
466 while (!ghostwheel(reg, rline, rlen, 10, match, mflags)) {
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
467 mflags = REG_NOTBOL;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
468
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
469 // Zero length matches don't count immediately after a previous match
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
470 mlen = match[0].rm_eo-match[0].rm_so;
1556
e7944f8fdcbb Debugging pass on sed: make the existing test suite pass.
Rob Landley <rob@landley.net>
parents: 1553
diff changeset
471 if (!mlen && !zmatch) {
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
472 if (!rlen--) break;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
473 rline++;
1556
e7944f8fdcbb Debugging pass on sed: make the existing test suite pass.
Rob Landley <rob@landley.net>
parents: 1553
diff changeset
474 zmatch++;
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
475 continue;
1556
e7944f8fdcbb Debugging pass on sed: make the existing test suite pass.
Rob Landley <rob@landley.net>
parents: 1553
diff changeset
476 } else zmatch = 0;
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
477
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
478 // If we're replacing only a specific match, skip if this isn't it
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
479 off = logrus->sflags>>3;
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
480 if (off && off != ++count) {
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
481 rline += match[0].rm_eo;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
482 rlen -= match[0].rm_eo;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
483
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
484 continue;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
485 }
1556
e7944f8fdcbb Debugging pass on sed: make the existing test suite pass.
Rob Landley <rob@landley.net>
parents: 1553
diff changeset
486 // The fact getline() can allocate unbounded amounts of memory is
e7944f8fdcbb Debugging pass on sed: make the existing test suite pass.
Rob Landley <rob@landley.net>
parents: 1553
diff changeset
487 // a bigger issue, but while we're here check for integer overflow
e7944f8fdcbb Debugging pass on sed: make the existing test suite pass.
Rob Landley <rob@landley.net>
parents: 1553
diff changeset
488 if (match[0].rm_eo > INT_MAX) perror_exit(0);
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
489
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
490 // newlen = strlen(new) but with \1 and & and printf escapes
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
491 for (off = newlen = 0; new[off]; off++) {
1559
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
492 int cc = -1;
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
493
1559
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
494 if (new[off] == '&') cc = 0;
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
495 else if (new[off] == '\\') cc = new[++off] - '0';
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
496 if (cc < 0 || cc > 9) {
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
497 newlen++;
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
498 continue;
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
499 }
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
500 newlen += match[cc].rm_eo-match[cc].rm_so;
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
501 }
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
502
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
503 // Allocate new size, copy start/end around match. (Can't extend in
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
504 // place because backrefs may refer to text after it's overwritten.)
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
505 len += newlen-mlen;
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
506 swap = xmalloc(len+1);
1611
50dc30893f9d Fix bug in sed y/// where bytes in target but not in source were replaced by zeroes (nul terminator overwritten).
Rob Landley <rob@landley.net>
parents: 1610
diff changeset
507 rswap = swap+(rline-line)+match[0].rm_so;
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
508 memcpy(swap, line, (rline-line)+match[0].rm_so);
1611
50dc30893f9d Fix bug in sed y/// where bytes in target but not in source were replaced by zeroes (nul terminator overwritten).
Rob Landley <rob@landley.net>
parents: 1610
diff changeset
509 memcpy(rswap+newlen, rline+match[0].rm_eo, (rlen -= match[0].rm_eo)+1);
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
510
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
511 // copy in new replacement text
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
512 for (off = mlen = 0; new[off]; off++) {
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
513 int cc = 0, ll;
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
514
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
515 if ((rswap[mlen++] = new[off]) == '\\') {
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
516 cc = new[++off] - '0';
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
517 if (cc<0 || cc>9) {
1559
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
518 if (!(rswap[mlen-1] = unescape(new[off])))
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
519 rswap[mlen-1] = new[off];
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
520
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
521 continue;
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
522 } else if (match[cc].rm_so == -1) error_exit("no s//\\%d/", cc);
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
523 } else if (new[off] != '&') continue;
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
524
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
525 ll = match[cc].rm_eo-match[cc].rm_so;
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
526 memcpy(rswap+(--mlen), rline+match[cc].rm_so, ll);
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
527 mlen += ll;
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
528 }
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
529
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
530 rline = rswap+newlen;
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
531 free(line);
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
532 line = swap;
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
533 len = rlen+(rline-line);
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
534
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
535 // Stop after first substitution unless we have flag g
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
536 if (!(logrus->sflags & 2)) break;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
537 }
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
538
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
539 if (mflags) {
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
540 // flag p
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
541 if (logrus->sflags & 4) emit(line, len, eol);
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
542
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
543 tea = 1;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
544 if (logrus->w) goto writenow;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
545 }
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
546 } else if (c=='w') {
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
547 int fd, noeol;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
548 char *name;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
549
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
550 writenow:
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
551 // Swap out emit() context
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
552 fd = TT.fdout;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
553 noeol = TT.noeol;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
554
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
555 // We save filehandle and newline status before filename
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
556 name = logrus->w + (char *)logrus;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
557 memcpy(&TT.fdout, name, 4);
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
558 name += 4;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
559 TT.noeol = *(name++);
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
560
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
561 // write, then save/restore context
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
562 if (emit(line, len, eol))
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
563 perror_exit("w '%s'", logrus->arg1+(char *)logrus);
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
564 *(--name) = TT.noeol;
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
565 TT.noeol = noeol;
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
566 TT.fdout = fd;
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
567 } else if (c=='x') {
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
568 long swap = TT.rememberlen;
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
569
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
570 str = TT.remember;
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
571 TT.remember = line;
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
572 line = str;
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
573 TT.rememberlen = len;
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
574 len = swap;
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
575 } else if (c=='y') {
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
576 char *from, *to = (char *)logrus;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
577 int i, j;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
578
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
579 from = to+logrus->arg1;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
580 to += logrus->arg2;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
581
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
582 for (i = 0; i < len; i++) {
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
583 j = stridx(from, line[i]);
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
584 if (j != -1) line[i] = to[j];
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
585 }
1562
b5968bffb65c More sed bugfixes.
Rob Landley <rob@landley.net>
parents: 1561
diff changeset
586 } else if (c=='=') {
b5968bffb65c More sed bugfixes.
Rob Landley <rob@landley.net>
parents: 1561
diff changeset
587 sprintf(toybuf, "%ld", TT.count);
b5968bffb65c More sed bugfixes.
Rob Landley <rob@landley.net>
parents: 1561
diff changeset
588 emit(toybuf, strlen(toybuf), 1);
1610
74e2642c35e8 Last sed bugfix broke 'b', fix it.
Rob Landley <rob@landley.net>
parents: 1602
diff changeset
589 }
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
590
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
591 logrus = logrus->next;
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
592 }
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
593
1560
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
594 if (line && !(toys.optflags & FLAG_n)) emit(line, len, eol);
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
595
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
596 done:
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
597 free(line);
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
598
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
599 if (dlist_terminate(append)) while (append) {
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
600 struct append *a = append->next;
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
601
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
602 if (append->file) {
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
603 int fd = xopen(append->str, O_RDONLY);
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
604
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
605 // Force newline if noeol pending
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
606 emit(0, 0, 0);
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
607 xsendfile(fd, TT.fdout);
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
608 close(fd);
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
609 } else emit(append->str, strlen(append->str), 1);
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
610 free(append);
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
611 append = a;
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
612 }
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
613 }
231
31dc682c18ad Very early stub of sed, does nothing yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
614
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
615 // 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
616
1561
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
617 // Iterate over lines in file, calling function. Function can write 0 to
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
618 // the line pointer if they want to keep it, or 1 to terminate processing,
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
619 // otherwise line is freed. Passed file descriptor is closed at the end.
1520
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
620 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
621 {
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
622 FILE *fp = fd ? xfdopen(fd, "r") : stdin;
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
623
1520
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
624 for (;;) {
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
625 char *line = 0;
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
626 ssize_t len;
231
31dc682c18ad Very early stub of sed, does nothing yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
627
1520
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
628 len = getline(&line, (void *)&len, fp);
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
629 if (len > 0) {
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
630 call(&line, len);
1561
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
631 if (line == (void *)1) break;
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
632 free(line);
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
633 } else break;
1520
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
634 }
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
635
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
636 if (fd) fclose(fp);
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
637 }
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
638
1520
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
639 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
640 {
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
641 int i = toys.optflags & FLAG_i;
1560
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
642 char *tmp;
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
643
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
644 if (i) {
1562
b5968bffb65c More sed bugfixes.
Rob Landley <rob@landley.net>
parents: 1561
diff changeset
645 struct step *primal;
b5968bffb65c More sed bugfixes.
Rob Landley <rob@landley.net>
parents: 1561
diff changeset
646
1560
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
647 if (!fd && *name=='-') {
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
648 error_msg("no -i on stdin");
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
649 return;
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
650 }
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
651 TT.fdout = copy_tempfile(fd, name, &tmp);
1562
b5968bffb65c More sed bugfixes.
Rob Landley <rob@landley.net>
parents: 1561
diff changeset
652 TT.count = 0;
b5968bffb65c More sed bugfixes.
Rob Landley <rob@landley.net>
parents: 1561
diff changeset
653 for (primal = (void *)TT.pattern; primal; primal = primal->next)
b5968bffb65c More sed bugfixes.
Rob Landley <rob@landley.net>
parents: 1561
diff changeset
654 primal->hit = 0;
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
655 }
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
656 do_lines(fd, name, walk_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
657 if (i) {
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
658 walk_pattern(0, 0);
1560
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
659 replace_tempfile(-1, TT.fdout, &tmp);
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
660 TT.fdout = 1;
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
661 TT.nextline = 0;
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
662 TT.nextlen = TT.noeol = 0;
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
663 }
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
664 }
231
31dc682c18ad Very early stub of sed, does nothing yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
665
1602
ea86581a9e36 Make unescape_delimited_string() copy the string so error reporting isn't so messed up.
Rob Landley <rob@landley.net>
parents: 1601
diff changeset
666 // Copy chunk of string between two delimiters, converting printf escapes.
ea86581a9e36 Make unescape_delimited_string() copy the string so error reporting isn't so messed up.
Rob Landley <rob@landley.net>
parents: 1601
diff changeset
667 // returns processed copy of string (0 if error), *pstr advances to next
ea86581a9e36 Make unescape_delimited_string() copy the string so error reporting isn't so messed up.
Rob Landley <rob@landley.net>
parents: 1601
diff changeset
668 // unused char. if delim (or *delim) is 0 uses/saves starting char as delimiter
ea86581a9e36 Make unescape_delimited_string() copy the string so error reporting isn't so messed up.
Rob Landley <rob@landley.net>
parents: 1601
diff changeset
669 // if regxex, ignore delimiter in [ranges]
ea86581a9e36 Make unescape_delimited_string() copy the string so error reporting isn't so messed up.
Rob Landley <rob@landley.net>
parents: 1601
diff changeset
670 static char *unescape_delimited_string(char **pstr, char *delim, int regex)
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
671 {
1556
e7944f8fdcbb Debugging pass on sed: make the existing test suite pass.
Rob Landley <rob@landley.net>
parents: 1553
diff changeset
672 char *to, *from, d;
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
673
1556
e7944f8fdcbb Debugging pass on sed: make the existing test suite pass.
Rob Landley <rob@landley.net>
parents: 1553
diff changeset
674 to = from = *pstr;
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
675 if (!delim || !*delim) {
1602
ea86581a9e36 Make unescape_delimited_string() copy the string so error reporting isn't so messed up.
Rob Landley <rob@landley.net>
parents: 1601
diff changeset
676 if (!(d = *(from++))) return 0;
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
677 if (d == '\\') d = *(from++);
1602
ea86581a9e36 Make unescape_delimited_string() copy the string so error reporting isn't so messed up.
Rob Landley <rob@landley.net>
parents: 1601
diff changeset
678 if (!d || d == '\\') return 0;
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
679 if (delim) *delim = d;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
680 } else d = *delim;
1602
ea86581a9e36 Make unescape_delimited_string() copy the string so error reporting isn't so messed up.
Rob Landley <rob@landley.net>
parents: 1601
diff changeset
681 to = delim = xmalloc(strlen(*pstr)+1);
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
682
1556
e7944f8fdcbb Debugging pass on sed: make the existing test suite pass.
Rob Landley <rob@landley.net>
parents: 1553
diff changeset
683 while (*from != d) {
1602
ea86581a9e36 Make unescape_delimited_string() copy the string so error reporting isn't so messed up.
Rob Landley <rob@landley.net>
parents: 1601
diff changeset
684 if (!*from) return 0;
1557
6e720e1e833c More sed bugfixes. (Did you know s/[/]// is a valid sed expression?)
Rob Landley <rob@landley.net>
parents: 1556
diff changeset
685
6e720e1e833c More sed bugfixes. (Did you know s/[/]// is a valid sed expression?)
Rob Landley <rob@landley.net>
parents: 1556
diff changeset
686 // delimiter in regex character range doesn't count
6e720e1e833c More sed bugfixes. (Did you know s/[/]// is a valid sed expression?)
Rob Landley <rob@landley.net>
parents: 1556
diff changeset
687 if (*from == '[') {
6e720e1e833c More sed bugfixes. (Did you know s/[/]// is a valid sed expression?)
Rob Landley <rob@landley.net>
parents: 1556
diff changeset
688 int len = 1;
6e720e1e833c More sed bugfixes. (Did you know s/[/]// is a valid sed expression?)
Rob Landley <rob@landley.net>
parents: 1556
diff changeset
689
6e720e1e833c More sed bugfixes. (Did you know s/[/]// is a valid sed expression?)
Rob Landley <rob@landley.net>
parents: 1556
diff changeset
690 if (from[len] == ']') len++;
1602
ea86581a9e36 Make unescape_delimited_string() copy the string so error reporting isn't so messed up.
Rob Landley <rob@landley.net>
parents: 1601
diff changeset
691 while (from[len] != ']') if (!from[len++]) return 0;
1557
6e720e1e833c More sed bugfixes. (Did you know s/[/]// is a valid sed expression?)
Rob Landley <rob@landley.net>
parents: 1556
diff changeset
692 memmove(to, from, ++len);
6e720e1e833c More sed bugfixes. (Did you know s/[/]// is a valid sed expression?)
Rob Landley <rob@landley.net>
parents: 1556
diff changeset
693 to += len;
6e720e1e833c More sed bugfixes. (Did you know s/[/]// is a valid sed expression?)
Rob Landley <rob@landley.net>
parents: 1556
diff changeset
694 from += len;
6e720e1e833c More sed bugfixes. (Did you know s/[/]// is a valid sed expression?)
Rob Landley <rob@landley.net>
parents: 1556
diff changeset
695 continue;
6e720e1e833c More sed bugfixes. (Did you know s/[/]// is a valid sed expression?)
Rob Landley <rob@landley.net>
parents: 1556
diff changeset
696 }
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
697 if (*from == '\\') {
1602
ea86581a9e36 Make unescape_delimited_string() copy the string so error reporting isn't so messed up.
Rob Landley <rob@landley.net>
parents: 1601
diff changeset
698 if (!from[1]) return 0;
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
699
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
700 // Check escaped end delimiter before printf style escapes.
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
701 if (from[1] == d) from++;
1562
b5968bffb65c More sed bugfixes.
Rob Landley <rob@landley.net>
parents: 1561
diff changeset
702 else if (from[1]!='\\') {
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
703 char c = unescape(from[1]);
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
704
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
705 if (c) {
1556
e7944f8fdcbb Debugging pass on sed: make the existing test suite pass.
Rob Landley <rob@landley.net>
parents: 1553
diff changeset
706 *(to++) = c;
e7944f8fdcbb Debugging pass on sed: make the existing test suite pass.
Rob Landley <rob@landley.net>
parents: 1553
diff changeset
707 from+=2;
e7944f8fdcbb Debugging pass on sed: make the existing test suite pass.
Rob Landley <rob@landley.net>
parents: 1553
diff changeset
708 continue;
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
709 }
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
710 }
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
711 }
1556
e7944f8fdcbb Debugging pass on sed: make the existing test suite pass.
Rob Landley <rob@landley.net>
parents: 1553
diff changeset
712 *(to++) = *(from++);
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
713 }
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
714 *to = 0;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
715 *pstr = from+1;
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
716
1602
ea86581a9e36 Make unescape_delimited_string() copy the string so error reporting isn't so messed up.
Rob Landley <rob@landley.net>
parents: 1601
diff changeset
717 return delim;
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
718 }
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
719
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
720 // 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
721 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
722 {
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
723 struct step *corwin = (void *)TT.pattern;
1601
2dcc165f6e21 Fix some sed bugs and improve error reporting.
Rob Landley <rob@landley.net>
parents: 1577
diff changeset
724 char *line = *pline, *reg, c, *errstart = *pline;
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
725 int i;
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
726
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
727 // Append additional line to pattern argument string?
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
728 if (corwin && corwin->prev->hit) {
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
729 // Remove half-finished entry from list so remalloc() doesn't confuse it
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
730 TT.pattern = TT.pattern->prev;
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
731 corwin = dlist_pop(&TT.pattern);
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
732 corwin->hit = 0;
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
733 c = corwin->c;
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
734 reg = (char *)corwin;
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
735 reg += corwin->arg1 + strlen(reg + corwin->arg1);
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
736
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
737 // Resume parsing
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
738 goto append;
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
739 }
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
740
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
741 // Loop through commands in line
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
742
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
743 corwin = 0;
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
744 for (;;) {
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
745 if (corwin) dlist_add_nomalloc(&TT.pattern, (void *)corwin);
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
746
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
747 while (isspace(*line) || *line == ';') line++;
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
748 if (!*line || *line == '#') return;
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
749
1601
2dcc165f6e21 Fix some sed bugs and improve error reporting.
Rob Landley <rob@landley.net>
parents: 1577
diff changeset
750 errstart = 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
751 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
752 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
753 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
754
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
755 // 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
756 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
757 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
758 else if (i) break;
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
759
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
760 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
761 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
762 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
763 line++;
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
764 } else if (*line == '/' || *line == '\\') {
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
765 char *s = line;
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
766
1602
ea86581a9e36 Make unescape_delimited_string() copy the string so error reporting isn't so messed up.
Rob Landley <rob@landley.net>
parents: 1601
diff changeset
767 if (!(s = unescape_delimited_string(&line, 0, 1))) goto brand;
1560
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
768 if (!*s) corwin->rmatch[i] = 0;
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
769 else {
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
770 xregcomp((void *)reg, s, (toys.optflags & FLAG_r)*REG_EXTENDED);
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
771 corwin->rmatch[i] = reg-toybuf;
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
772 reg += sizeof(regex_t);
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
773 }
1602
ea86581a9e36 Make unescape_delimited_string() copy the string so error reporting isn't so messed up.
Rob Landley <rob@landley.net>
parents: 1601
diff changeset
774 free(s);
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
775 } 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
776 }
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
777
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
778 while (isspace(*line)) line++;
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
779 if (!*line) break;
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
780
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
781 while (*line == '!') {
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
782 corwin->not = 1;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
783 line++;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
784 }
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
785 while (isspace(*line)) line++;
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
786
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
787 c = corwin->c = *(line++);
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
788 if (strchr("}:", c) && i) break;
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
789 if (strchr("aiqr=", c) && i>1) break;
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
790
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
791 // 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
792 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
793 memcpy(corwin, toybuf, reg-toybuf);
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
794 reg = (reg-toybuf) + (char *)corwin;
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
795
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
796 // Parse arguments by command type
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
797 if (c == '{') TT.nextlen++;
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
798 else if (c == '}') {
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
799 if (!TT.nextlen--) break;
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
800 } else if (c == 's') {
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
801 char *merlin, *fiona, delim = 0;
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
802
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
803 // s/pattern/replacement/flags
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
804
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
805 // get pattern (just record, we parse it later)
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
806 corwin->arg1 = reg - (char *)corwin;
1602
ea86581a9e36 Make unescape_delimited_string() copy the string so error reporting isn't so messed up.
Rob Landley <rob@landley.net>
parents: 1601
diff changeset
807 if (!(merlin = unescape_delimited_string(&line, &delim, 1))) goto brand;
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
808
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
809 // get replacement - don't replace escapes because \1 and \& need
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
810 // processing later, after we replace \\ with \ we can't tell \\1 from \1
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
811 fiona = line;
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
812 while (*line != delim) {
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
813 if (!*line) goto brand;
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
814 if (*line == '\\') {
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
815 if (!line[1]) goto brand;
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
816 line += 2;
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
817 } else line++;
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
818 }
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
819
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
820 corwin->arg2 = corwin->arg1 + sizeof(regex_t);
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
821 reg = extend_string((void *)&corwin, fiona, corwin->arg2, line-fiona)+1;
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
822
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
823 // get flags
1561
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
824 for (line++; *line; line++) {
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
825 long l;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
826
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
827 if (isspace(*line)) continue;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
828
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
829 if (0 <= (l = stridx("igp", *line))) corwin->sflags |= 1<<l;
1562
b5968bffb65c More sed bugfixes.
Rob Landley <rob@landley.net>
parents: 1561
diff changeset
830 else if (!(corwin->sflags>>3) && 0<(l = strtol(line, &line, 10))) {
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
831 corwin->sflags |= l << 3;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
832 line--;
1561
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
833 } else break;
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
834 }
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
835
1561
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
836 // We deferred actually parsing the regex until we had the s///i flag
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
837 // allocating the space was done by extend_string() above
1560
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
838 if (!*merlin) corwin->arg1 = 0;
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
839 else xregcomp((void *)(corwin->arg1 + (char *)corwin), merlin,
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
840 ((toys.optflags & FLAG_r)*REG_EXTENDED)|((corwin->sflags&1)*REG_ICASE));
1602
ea86581a9e36 Make unescape_delimited_string() copy the string so error reporting isn't so messed up.
Rob Landley <rob@landley.net>
parents: 1601
diff changeset
841 free(merlin);
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
842 if (*line == 'w') {
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
843 line++;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
844 goto writenow;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
845 }
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
846 } else if (c == 'w') {
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
847 int fd, delim;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
848 char *cc;
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
849
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
850 // Since s/// uses arg1 and arg2, and w needs a persistent filehandle and
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
851 // eol status, and to retain the filename for error messages, we'd need
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
852 // to go up to arg5 just for this. Compromise: dynamically allocate the
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
853 // filehandle and eol status.
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
854
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
855 writenow:
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
856 while (isspace(*line)) line++;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
857 if (!*line) goto brand;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
858 for (cc = line; *cc; cc++) if (*cc == '\\' && cc[1] == ';') break;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
859 delim = *cc;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
860 *cc = 0;
1557
6e720e1e833c More sed bugfixes. (Did you know s/[/]// is a valid sed expression?)
Rob Landley <rob@landley.net>
parents: 1556
diff changeset
861 fd = xcreate(line, O_WRONLY|O_CREAT|O_TRUNC, 0644);
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
862 *cc = delim;
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
863
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
864 corwin->w = reg - (char *)corwin;
1559
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
865 corwin = xrealloc(corwin, corwin->w+(cc-line)+6);
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
866 reg = corwin->w + (char *)corwin;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
867
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
868 memcpy(reg, &fd, 4);
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
869 reg += 4;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
870 *(reg++) = 0;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
871 memcpy(reg, line, delim);
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
872 reg += delim;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
873 *(reg++) = 0;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
874
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
875 line = cc;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
876 if (delim) line += 2;
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
877 } else if (c == 'y') {
1602
ea86581a9e36 Make unescape_delimited_string() copy the string so error reporting isn't so messed up.
Rob Landley <rob@landley.net>
parents: 1601
diff changeset
878 char *s, delim = 0;
ea86581a9e36 Make unescape_delimited_string() copy the string so error reporting isn't so messed up.
Rob Landley <rob@landley.net>
parents: 1601
diff changeset
879 int len;
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
880
1602
ea86581a9e36 Make unescape_delimited_string() copy the string so error reporting isn't so messed up.
Rob Landley <rob@landley.net>
parents: 1601
diff changeset
881 if (!(s = unescape_delimited_string(&line, &delim, 0))) goto brand;
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
882 corwin->arg1 = reg-(char *)corwin;
1602
ea86581a9e36 Make unescape_delimited_string() copy the string so error reporting isn't so messed up.
Rob Landley <rob@landley.net>
parents: 1601
diff changeset
883 len = strlen(s);
ea86581a9e36 Make unescape_delimited_string() copy the string so error reporting isn't so messed up.
Rob Landley <rob@landley.net>
parents: 1601
diff changeset
884 reg = extend_string((void *)&corwin, s, reg-(char *)corwin, len);
ea86581a9e36 Make unescape_delimited_string() copy the string so error reporting isn't so messed up.
Rob Landley <rob@landley.net>
parents: 1601
diff changeset
885 free(s);
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
886 corwin->arg2 = reg-(char *)corwin;
1602
ea86581a9e36 Make unescape_delimited_string() copy the string so error reporting isn't so messed up.
Rob Landley <rob@landley.net>
parents: 1601
diff changeset
887 if (!(s = unescape_delimited_string(&line, &delim, 0))) goto brand;
ea86581a9e36 Make unescape_delimited_string() copy the string so error reporting isn't so messed up.
Rob Landley <rob@landley.net>
parents: 1601
diff changeset
888 if (len != strlen(s)) goto brand;
ea86581a9e36 Make unescape_delimited_string() copy the string so error reporting isn't so messed up.
Rob Landley <rob@landley.net>
parents: 1601
diff changeset
889 reg = extend_string((void *)&corwin, s, reg-(char*)corwin, len);
ea86581a9e36 Make unescape_delimited_string() copy the string so error reporting isn't so messed up.
Rob Landley <rob@landley.net>
parents: 1601
diff changeset
890 free(s);
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
891 } else if (strchr("abcirtTw:", c)) {
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
892 int end, class;
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
893
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
894 // Trim whitespace from "b ;" and ": blah " but only first space in "w x "
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
895
1610
74e2642c35e8 Last sed bugfix broke 'b', fix it.
Rob Landley <rob@landley.net>
parents: 1602
diff changeset
896 while (isspace(*line)) {
74e2642c35e8 Last sed bugfix broke 'b', fix it.
Rob Landley <rob@landley.net>
parents: 1602
diff changeset
897 if (!strchr("btT", c) || *line != '\n') line++;
74e2642c35e8 Last sed bugfix broke 'b', fix it.
Rob Landley <rob@landley.net>
parents: 1602
diff changeset
898 else break;
74e2642c35e8 Last sed bugfix broke 'b', fix it.
Rob Landley <rob@landley.net>
parents: 1602
diff changeset
899 }
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
900 append:
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
901 class = !strchr("btT:", c);
1559
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
902 end = strcspn(line, class ? "\n" : "; \t\r\n\v\f");
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
903
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
904 if (!end) {
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
905 if (!strchr("btT", c)) break;
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
906 continue;
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
907 }
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
908
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
909 // Extend allocation to include new string. We use offsets instead of
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
910 // pointers so realloc() moving stuff doesn't break things. Do it
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
911 // here instead of toybuf so there's no maximum size.
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
912 if (!corwin->arg1) corwin->arg1 = reg - (char*)corwin;
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
913 reg = extend_string((void *)&corwin, line, reg - (char *)corwin, end);
1556
e7944f8fdcbb Debugging pass on sed: make the existing test suite pass.
Rob Landley <rob@landley.net>
parents: 1553
diff changeset
914 line += end;
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
915
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
916 // Line continuation?
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
917 if (class && reg[-1] == '\\') {
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
918 reg[-1] = 0;
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
919 corwin->hit++;
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
920 }
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
921
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
922 // Commands that take no arguments
1557
6e720e1e833c More sed bugfixes. (Did you know s/[/]// is a valid sed expression?)
Rob Landley <rob@landley.net>
parents: 1556
diff changeset
923 } else if (!strchr("{dDgGhHlnNpPqx=", c)) break;
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
924 }
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
925
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
926 brand:
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
927 // Reminisce about chestnut trees.
1601
2dcc165f6e21 Fix some sed bugs and improve error reporting.
Rob Landley <rob@landley.net>
parents: 1577
diff changeset
928 error_exit("bad pattern '%s'@%ld (%c)", errstart, line-errstart+1, *line);
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
929 }
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
930
231
31dc682c18ad Very early stub of sed, does nothing yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
931 void sed_main(void)
31dc682c18ad Very early stub of sed, does nothing yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
932 {
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
933 struct arg_list *dworkin;
1520
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
934 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
935
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
936 // 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
937 // 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
938 // 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
939 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
940 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
941 return;
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
942 }
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
943
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
944 // 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
945 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
946 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
947 (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
948 }
1543
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
949
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
950 // Option parsing infrastructure can't interlace "-e blah -f blah -e blah"
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
951 // so handle all -e, then all -f. (At least the behavior's consistent.)
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
952
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
953 for (dworkin = TT.e; dworkin; dworkin = dworkin->next)
1559
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
954 jewel_of_judgement(&dworkin->arg, strlen(dworkin->arg));
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
955 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
956 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
957 dlist_terminate(TT.pattern);
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
958 if (TT.nextlen) error_exit("no }");
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
959
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
960 TT.fdout = 1;
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
961 TT.remember = xstrdup("");
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
962
1520
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
963 // 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
964 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
965
1538
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
966 if (!(toys.optflags & FLAG_i)) walk_pattern(0, 0);
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
967
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
968 // todo: need to close fd when done for TOYBOX_FREE?
231
31dc682c18ad Very early stub of sed, does nothing yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
969 }