annotate toys/posix/sed.c @ 1653:58cb2d7bd461 draft

sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
author Rob Landley <rob@landley.net>
date Tue, 13 Jan 2015 03:35:37 -0600
parents 8e506e89bb8c
children c8be6e37a616
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"
1619
a7e4dc024bbb Promote sed to posix.
Rob Landley <rob@landley.net>
parents: 1618
diff changeset
14 default y
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
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
1618
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
86 l Print line, escaping \abfrtv (but not newline), octal escaping other
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
87 nonprintable characters, wrapping lines to terminal width with a
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
88 backslash, and appending $ to actual end of line.
1537
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;
1618
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
178 unsigned xx;
237
7cb15eae1664 Zap toylist.h, moving contents of global structures into DEFINE_GLOBALS()
Rob Landley <rob@landley.net>
parents: 234
diff changeset
179 )
7cb15eae1664 Zap toylist.h, moving contents of global structures into DEFINE_GLOBALS()
Rob Landley <rob@landley.net>
parents: 234
diff changeset
180
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
181 struct step {
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
182 struct step *next, *prev;
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
183
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
184 // 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
185 long lmatch[2];
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
186 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
187 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
188 char c; // action
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
189 };
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
190
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
191 // 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
192 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
193 {
1560
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
194 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
195
1532
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 (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
197 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
198 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
199 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
200 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
201 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
202 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
203 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
204
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
205 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
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
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
208 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
209 }
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
210
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
211 // 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
212 // 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
213 // (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
214 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
215 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
216 {
1559
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
217 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
218
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
219 for (;;) {
1559
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
220 long ll = 0;
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
221 int rc;
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
222
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
223 while (len && !*s) {
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
224 s++;
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
225 len--;
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
226 }
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
227 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
228
1559
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
229 rc = regexec(preg, s, nmatch, pmatch, eflags);
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
230 if (!rc) {
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
231 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
232 pmatch[rc].rm_so += s-string;
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
233 pmatch[rc].rm_eo += s-string;
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
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
236 return 0;
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
237 }
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
238 if (ll==len) return rc;
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
239
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
240 s += ll;
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
241 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
242 }
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
243 }
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
244
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
245 // 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
246
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
247 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
248 {
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
249 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
250 char *s;
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
251
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
252 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
253 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
254 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
255 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
256 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
257
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
258 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
259 }
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
260
1560
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
261 // 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
262 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
263 {
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
264 if (!offset) {
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
265 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
266 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
267 }
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
268
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
269 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
270 }
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
271
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
272 // 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
273 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
274 {
1550
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 {
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
276 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
277 int file;
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
278 char *str;
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
279 } *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
280 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
281 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
282 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
283 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
284
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
285 // 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
286 // 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
287 // 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
288 TT.nextline = 0;
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
289 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
290 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
291 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
292 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
293 *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
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
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) return;
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
297 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
298 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
299
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
300 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
301 TT.restart = 0;
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
302
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
303 while (logrus) {
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
304 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
305
1556
e7944f8fdcbb Debugging pass on sed: make the existing test suite pass.
Rob Landley <rob@landley.net>
parents: 1553
diff changeset
306 // 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
307 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
308 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
309 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
310
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
311 // 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
312 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
313 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
314 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
315 else {
1560
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
316 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
317
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
318 // 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
319 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
320 }
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
321 } 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
322
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
323 // 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
324 } else {
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
325 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
326 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
327
1560
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
328 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
329 } 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
330
2dcc165f6e21 Fix some sed bugs and improve error reporting.
Rob Landley <rob@landley.net>
parents: 1577
diff changeset
331 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
332 }
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
333
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
334 // Didn't match?
1601
2dcc165f6e21 Fix some sed bugs and improve error reporting.
Rob Landley <rob@landley.net>
parents: 1577
diff changeset
335 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
336
1601
2dcc165f6e21 Fix some sed bugs and improve error reporting.
Rob Landley <rob@landley.net>
parents: 1577
diff changeset
337 // Deferred disable from regex end match
2dcc165f6e21 Fix some sed bugs and improve error reporting.
Rob Landley <rob@landley.net>
parents: 1577
diff changeset
338 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
339
2dcc165f6e21 Fix some sed bugs and improve error reporting.
Rob Landley <rob@landley.net>
parents: 1577
diff changeset
340 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
341 // 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
342 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
343 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
344
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 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
346 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
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 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
349 }
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
350 }
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
351 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
352 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
353 }
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
354 }
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
355
1560
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
356 // 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
357 if (!line) {
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
358 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
359 continue;
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
360 }
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
361
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
362 // Process command
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
363
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
364 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
365 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
366 a->str = logrus->arg1+(char *)logrus;
1621
53bfe8ac762b sed 'r' didn't work right.
Rob Landley <rob@landley.net>
parents: 1620
diff changeset
367 a->file = c=='r';
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
368 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
369 } 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
370 int t = tea;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
371
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
372 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
373 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
374 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
375 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
376 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
377 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
378 break;
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
379 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
380 }
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
381 } 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
382 str = logrus->arg1+(char *)logrus;
1601
2dcc165f6e21 Fix some sed bugs and improve error reporting.
Rob Landley <rob@landley.net>
parents: 1577
diff changeset
383 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
384 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
385 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
386 continue;
1560
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
387 } 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
388 free(line);
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
389 line = 0;
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
390 continue;
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
391 } 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
392 // 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
393 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
394 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
395 len -= str - line;
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
396 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
397
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
398 // 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
399 // 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
400 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
401 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
402 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
403 } 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
404 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
405 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
406 }
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
407 continue;
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
408 } 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
409 free(line);
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
410 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
411 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
412 } 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
413 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
414 line[len++] = '\n';
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
415 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
416 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
417 } 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
418 free(TT.remember);
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
419 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
420 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
421 } 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
422 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
423 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
424 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
425 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
426 } 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
427 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
428 emit(str, strlen(str), 1);
1618
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
429 } else if (c=='l') {
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
430 int i, x, off;
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
431
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
432 if (!TT.xx) {
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
433 terminal_size(&TT.xx, 0);
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
434 if (!TT.xx) TT.xx = 80;
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
435 if (TT.xx > sizeof(toybuf)-10) TT.xx = sizeof(toybuf)-10;
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
436 if (TT.xx > 4) TT.xx -= 4;
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
437 }
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
438
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
439 for (i = off = 0; i<len; i++) {
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
440 if (off >= TT.xx) {
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
441 toybuf[off++] = '\\';
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
442 emit(toybuf, off, 1);
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
443 off = 0;
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
444 }
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
445 x = stridx("\\\a\b\f\r\t\v", line[i]);
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
446 if (x != -1) {
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
447 toybuf[off++] = '\\';
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
448 toybuf[off++] = "\\abfrtv"[x];
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
449 } else if (line[i] >= ' ') toybuf[off++] = line[i];
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
450 else off += sprintf(toybuf+off, "\\%03o", line[i]);
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
451 }
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
452 toybuf[off++] = '$';
01d44ee47503 sed: implement 'l'
Rob Landley <rob@landley.net>
parents: 1616
diff changeset
453 emit(toybuf, off, 1);
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
454 } 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
455 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
456
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
457 break;
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
458 } 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
459 // 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
460 // 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
461 if (pline) {
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
462 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
463 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
464 free(TT.nextline);
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
465 TT.nextline = line;
1558
47647eebc5f9 Fix sed 'b' with no label and 'N' in general.
Rob Landley <rob@landley.net>
parents: 1557
diff changeset
466 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
467 line = 0;
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
468 }
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
469
1558
47647eebc5f9 Fix sed 'b' with no label and 'N' in general.
Rob Landley <rob@landley.net>
parents: 1557
diff changeset
470 // 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
471 goto done;
1559
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
472 } else if (c=='p' || c=='P') {
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
473 char *l = (c=='P') ? strchr(line, '\n') : 0;
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
474
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
475 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
476 } else if (c=='q') {
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
477 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
478 free(TT.nextline);
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
479 TT.nextline = 0;
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
480 TT.nextlen = 0;
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
481
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
482 break;
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
483 } else if (c=='s') {
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
484 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
485 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
486 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
487 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
488
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
489 // 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
490 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
491 mflags = REG_NOTBOL;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
492
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
493 // 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
494 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
495 if (!mlen && !zmatch) {
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
496 if (!rlen--) break;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
497 rline++;
1556
e7944f8fdcbb Debugging pass on sed: make the existing test suite pass.
Rob Landley <rob@landley.net>
parents: 1553
diff changeset
498 zmatch++;
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
499 continue;
1556
e7944f8fdcbb Debugging pass on sed: make the existing test suite pass.
Rob Landley <rob@landley.net>
parents: 1553
diff changeset
500 } else zmatch = 0;
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
501
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
502 // 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
503 off = logrus->sflags>>3;
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
504 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
505 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
506 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
507
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
508 continue;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
509 }
1556
e7944f8fdcbb Debugging pass on sed: make the existing test suite pass.
Rob Landley <rob@landley.net>
parents: 1553
diff changeset
510 // 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
511 // 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
512 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
513
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
514 // 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
515 for (off = newlen = 0; new[off]; off++) {
1559
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
516 int cc = -1;
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
517
1559
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
518 if (new[off] == '&') cc = 0;
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
519 else if (new[off] == '\\') cc = new[++off] - '0';
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
520 if (cc < 0 || cc > 9) {
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
521 newlen++;
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
522 continue;
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
523 }
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
524 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
525 }
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
526
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
527 // 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
528 // 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
529 len += newlen-mlen;
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
530 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
531 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
532 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
533 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
534
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
535 // copy in new replacement text
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
536 for (off = mlen = 0; new[off]; off++) {
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
537 int cc = 0, ll;
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
538
1613
96aa7ec74936 Fix yet another sed bug.
Rob Landley <rob@landley.net>
parents: 1612
diff changeset
539 if (new[off] == '\\') {
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
540 cc = new[++off] - '0';
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
541 if (cc<0 || cc>9) {
1613
96aa7ec74936 Fix yet another sed bug.
Rob Landley <rob@landley.net>
parents: 1612
diff changeset
542 if (!(rswap[mlen++] = unescape(new[off])))
1559
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
543 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
544
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
545 continue;
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
546 } else if (match[cc].rm_so == -1) error_exit("no s//\\%d/", cc);
1613
96aa7ec74936 Fix yet another sed bug.
Rob Landley <rob@landley.net>
parents: 1612
diff changeset
547 } else if (new[off] != '&') {
96aa7ec74936 Fix yet another sed bug.
Rob Landley <rob@landley.net>
parents: 1612
diff changeset
548 rswap[mlen++] = new[off];
96aa7ec74936 Fix yet another sed bug.
Rob Landley <rob@landley.net>
parents: 1612
diff changeset
549
96aa7ec74936 Fix yet another sed bug.
Rob Landley <rob@landley.net>
parents: 1612
diff changeset
550 continue;
96aa7ec74936 Fix yet another sed bug.
Rob Landley <rob@landley.net>
parents: 1612
diff changeset
551 }
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
552
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
553 ll = match[cc].rm_eo-match[cc].rm_so;
1613
96aa7ec74936 Fix yet another sed bug.
Rob Landley <rob@landley.net>
parents: 1612
diff changeset
554 memcpy(rswap+mlen, rline+match[cc].rm_so, ll);
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
555 mlen += ll;
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
556 }
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
557
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
558 rline = rswap+newlen;
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
559 free(line);
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
560 line = swap;
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
561
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
562 // 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
563 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
564 }
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
565
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
566 if (mflags) {
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
567 // flag p
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
568 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
569
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
570 tea = 1;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
571 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
572 }
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
573 } else if (c=='w') {
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
574 int fd, noeol;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
575 char *name;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
576
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
577 writenow:
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
578 // Swap out emit() context
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
579 fd = TT.fdout;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
580 noeol = TT.noeol;
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 // 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
583 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
584 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
585 name += 4;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
586 TT.noeol = *(name++);
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
587
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
588 // 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
589 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
590 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
591 *(--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
592 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
593 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
594 } 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
595 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
596
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
597 str = TT.remember;
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
598 TT.remember = line;
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
599 line = str;
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
600 TT.rememberlen = len;
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
601 len = swap;
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
602 } else if (c=='y') {
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
603 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
604 int i, j;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
605
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
606 from = to+logrus->arg1;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
607 to += logrus->arg2;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
608
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
609 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
610 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
611 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
612 }
1562
b5968bffb65c More sed bugfixes.
Rob Landley <rob@landley.net>
parents: 1561
diff changeset
613 } else if (c=='=') {
b5968bffb65c More sed bugfixes.
Rob Landley <rob@landley.net>
parents: 1561
diff changeset
614 sprintf(toybuf, "%ld", TT.count);
b5968bffb65c More sed bugfixes.
Rob Landley <rob@landley.net>
parents: 1561
diff changeset
615 emit(toybuf, strlen(toybuf), 1);
1610
74e2642c35e8 Last sed bugfix broke 'b', fix it.
Rob Landley <rob@landley.net>
parents: 1602
diff changeset
616 }
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
617
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
618 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
619 }
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
620
1560
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
621 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
622
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
623 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
624 free(line);
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
625
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
626 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
627 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
628
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
629 if (append->file) {
1621
53bfe8ac762b sed 'r' didn't work right.
Rob Landley <rob@landley.net>
parents: 1620
diff changeset
630 int fd = open(append->str, O_RDONLY);
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
631
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
632 // Force newline if noeol pending
1621
53bfe8ac762b sed 'r' didn't work right.
Rob Landley <rob@landley.net>
parents: 1620
diff changeset
633 if (fd != -1) {
53bfe8ac762b sed 'r' didn't work right.
Rob Landley <rob@landley.net>
parents: 1620
diff changeset
634 if (TT.noeol) xwrite(TT.fdout, "\n", 1);
53bfe8ac762b sed 'r' didn't work right.
Rob Landley <rob@landley.net>
parents: 1620
diff changeset
635 TT.noeol = 0;
53bfe8ac762b sed 'r' didn't work right.
Rob Landley <rob@landley.net>
parents: 1620
diff changeset
636 xsendfile(fd, TT.fdout);
53bfe8ac762b sed 'r' didn't work right.
Rob Landley <rob@landley.net>
parents: 1620
diff changeset
637 close(fd);
53bfe8ac762b sed 'r' didn't work right.
Rob Landley <rob@landley.net>
parents: 1620
diff changeset
638 }
1550
2997847aa299 Implement another largeish chunk of sed. Untested, unfinished, do not use yet.
Rob Landley <rob@landley.net>
parents: 1545
diff changeset
639 } 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
640 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
641 append = a;
1545
b6ff5dc17763 Implement a few sed commands. Not done, and not tested yet.
Rob Landley <rob@landley.net>
parents: 1543
diff changeset
642 }
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
643 }
231
31dc682c18ad Very early stub of sed, does nothing yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
644
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
645 // 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
646
1561
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
647 // 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
648 // 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
649 // 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
650 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
651 {
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
652 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
653
1520
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
654 for (;;) {
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
655 char *line = 0;
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
656 ssize_t len;
231
31dc682c18ad Very early stub of sed, does nothing yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
657
1520
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
658 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
659 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
660 call(&line, len);
1561
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
661 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
662 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
663 } else break;
1520
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
664 }
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
665
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
666 if (fd) fclose(fp);
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
667 }
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
668
1520
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
669 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
670 {
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
671 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
672 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
673
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
674 if (i) {
1562
b5968bffb65c More sed bugfixes.
Rob Landley <rob@landley.net>
parents: 1561
diff changeset
675 struct step *primal;
b5968bffb65c More sed bugfixes.
Rob Landley <rob@landley.net>
parents: 1561
diff changeset
676
1560
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
677 if (!fd && *name=='-') {
1646
8e506e89bb8c Fix sed backslash parsing in square bracket pattern sections.
Rob Landley <rob@landley.net>
parents: 1621
diff changeset
678 error_msg("-i on stdin");
1560
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
679 return;
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
680 }
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
681 TT.fdout = copy_tempfile(fd, name, &tmp);
1562
b5968bffb65c More sed bugfixes.
Rob Landley <rob@landley.net>
parents: 1561
diff changeset
682 TT.count = 0;
b5968bffb65c More sed bugfixes.
Rob Landley <rob@landley.net>
parents: 1561
diff changeset
683 for (primal = (void *)TT.pattern; primal; primal = primal->next)
b5968bffb65c More sed bugfixes.
Rob Landley <rob@landley.net>
parents: 1561
diff changeset
684 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
685 }
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
686 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
687 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
688 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
689 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
690 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
691 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
692 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
693 }
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
694 }
231
31dc682c18ad Very early stub of sed, does nothing yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
695
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
696 // 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
697 // 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
698 // 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
699 // 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
700 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
701 {
1646
8e506e89bb8c Fix sed backslash parsing in square bracket pattern sections.
Rob Landley <rob@landley.net>
parents: 1621
diff changeset
702 char *to, *from, mode = 0, 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
703
1556
e7944f8fdcbb Debugging pass on sed: make the existing test suite pass.
Rob Landley <rob@landley.net>
parents: 1553
diff changeset
704 to = from = *pstr;
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
705 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
706 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
707 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
708 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
709 if (delim) *delim = d;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
710 } 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
711 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
712
1646
8e506e89bb8c Fix sed backslash parsing in square bracket pattern sections.
Rob Landley <rob@landley.net>
parents: 1621
diff changeset
713 while (mode || *from != d) {
1653
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
714 if (!*from) {
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
715 *to = 0;
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
716
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
717 return 0;
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
718 }
1557
6e720e1e833c More sed bugfixes. (Did you know s/[/]// is a valid sed expression?)
Rob Landley <rob@landley.net>
parents: 1556
diff changeset
719
6e720e1e833c More sed bugfixes. (Did you know s/[/]// is a valid sed expression?)
Rob Landley <rob@landley.net>
parents: 1556
diff changeset
720 // 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
721 if (*from == '[') {
1646
8e506e89bb8c Fix sed backslash parsing in square bracket pattern sections.
Rob Landley <rob@landley.net>
parents: 1621
diff changeset
722 mode = '[';
8e506e89bb8c Fix sed backslash parsing in square bracket pattern sections.
Rob Landley <rob@landley.net>
parents: 1621
diff changeset
723 if (from[1] == ']') *(to++) = *(from++);
8e506e89bb8c Fix sed backslash parsing in square bracket pattern sections.
Rob Landley <rob@landley.net>
parents: 1621
diff changeset
724 } else if (mode && *from == ']') mode = 0;
8e506e89bb8c Fix sed backslash parsing in square bracket pattern sections.
Rob Landley <rob@landley.net>
parents: 1621
diff changeset
725 else 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
726 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
727
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
728 // 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
729 if (from[1] == d) from++;
1616
7d60ceb548d7 More sed bugs.
Rob Landley <rob@landley.net>
parents: 1613
diff changeset
730 else if (from[1]=='\\') *(to++) = *(from++);
7d60ceb548d7 More sed bugs.
Rob Landley <rob@landley.net>
parents: 1613
diff changeset
731 else {
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
732 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
733
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
734 if (c) {
1556
e7944f8fdcbb Debugging pass on sed: make the existing test suite pass.
Rob Landley <rob@landley.net>
parents: 1553
diff changeset
735 *(to++) = c;
e7944f8fdcbb Debugging pass on sed: make the existing test suite pass.
Rob Landley <rob@landley.net>
parents: 1553
diff changeset
736 from+=2;
e7944f8fdcbb Debugging pass on sed: make the existing test suite pass.
Rob Landley <rob@landley.net>
parents: 1553
diff changeset
737 continue;
1646
8e506e89bb8c Fix sed backslash parsing in square bracket pattern sections.
Rob Landley <rob@landley.net>
parents: 1621
diff changeset
738 } else if (from[1]) *(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
739 }
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
740 }
1556
e7944f8fdcbb Debugging pass on sed: make the existing test suite pass.
Rob Landley <rob@landley.net>
parents: 1553
diff changeset
741 *(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
742 }
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
743 *to = 0;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
744 *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
745
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
746 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
747 }
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
748
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
749 // 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
750 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
751 {
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
752 struct step *corwin = (void *)TT.pattern;
1653
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
753 char *line, *reg, c, *errstart;
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
754 int i;
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
755
1653
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
756 line = errstart = pline ? *pline : "";
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
757
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
758 // Append additional line to pattern argument string?
1620
6f7ed6316d90 Another sed bug. (The e2fsprogs build uses multiple line continuations on the same command.)
Rob Landley <rob@landley.net>
parents: 1619
diff changeset
759 // We temporarily repurpose "hit" to indicate line continuations
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
760 if (corwin && corwin->prev->hit) {
1653
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
761 if (!*pline) error_exit("unfinished %c", corwin->prev->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
762 // 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
763 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
764 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
765 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
766 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
767 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
768
1653
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
769 // Resume parsing for 'a' or 's' command
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
770 if (corwin->hit < 256) goto resume_s;
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
771 else goto resume_a;
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
772 }
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
773
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
774 // 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
775
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
776 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
777 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
778 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
779
1653
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
780 for (;;) {
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
781 while (isspace(*line) || *line == ';') line++;
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
782 if (*line == '#') while (*line && *line != '\n') line++;
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
783 else break;
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
784 }
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
785 if (!*line) return;
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
786
1601
2dcc165f6e21 Fix some sed bugs and improve error reporting.
Rob Landley <rob@landley.net>
parents: 1577
diff changeset
787 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
788 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
789 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
790 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
791
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
792 // 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
793 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
794 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
795 else if (i) break;
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
796
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
797 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
798 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
799 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
800 line++;
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
801 } 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
802 char *s = line;
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
803
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
804 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
805 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
806 else {
5d140d08cc30 More sed corner cases. (Empty regex repeats previous regex, implement -i, etc.)
Rob Landley <rob@landley.net>
parents: 1559
diff changeset
807 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
808 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
809 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
810 }
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
811 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
812 } 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
813 }
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
814
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
815 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
816 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
817
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
818 while (*line == '!') {
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
819 corwin->not = 1;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
820 line++;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
821 }
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
822 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
823
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
824 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
825 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
826 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
827
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
828 // 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
829 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
830 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
831 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
832
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
833 // 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
834 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
835 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
836 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
837 } else if (c == 's') {
1653
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
838 char *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
839
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
840 // 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
841
1653
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
842 // line continuations use arg1, so we fill out arg2 first (since the
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
843 // regex part can't be multiple lines) and swap them back later.
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
844
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
845 // get pattern (just record, we parse it later)
1653
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
846 corwin->arg2 = reg - (char *)corwin;
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
847 if (!(TT.remember = unescape_delimited_string(&line, &delim, 1)))
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
848 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
849
1653
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
850 reg += sizeof(regex_t);
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
851 corwin->arg1 = reg-(char *)corwin;
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
852 corwin->hit = delim;
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
853 resume_s:
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
854 // 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
855 // 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
856 fiona = line;
1653
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
857 while (*fiona != corwin->hit) {
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
858 if (!*fiona) break;
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
859 if (*fiona++ == '\\') {
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
860 if (!*fiona || *fiona == '\n') {
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
861 fiona[-1] = '\n';
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
862 break;
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
863 }
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
864 fiona++;
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
865 }
1553
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
866 }
2423dd884182 sed: implement s & and \1 backrefs.
Rob Landley <rob@landley.net>
parents: 1552
diff changeset
867
1653
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
868 reg = extend_string((void *)&corwin, line, reg-(char *)corwin,fiona-line);
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
869 line = fiona;
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
870 // line continuation? (note: '\n' can't be a valid delim).
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
871 if (*line == corwin->hit) corwin->hit = 0;
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
872 else {
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
873 if (!*line) continue;
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
874 reg--;
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
875 line++;
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
876 goto resume_s;
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
877 }
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
878
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
879 // swap arg1/arg2 so they're back in order arguments occur.
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
880 i = corwin->arg1;
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
881 corwin->arg1 = corwin->arg2;
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
882 corwin->arg2 = i;
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
883
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
884 // get flags
1561
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
885 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
886 long l;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
887
1616
7d60ceb548d7 More sed bugs.
Rob Landley <rob@landley.net>
parents: 1613
diff changeset
888 if (isspace(*line) && *line != '\n') continue;
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
889
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
890 if (0 <= (l = stridx("igp", *line))) corwin->sflags |= 1<<l;
1562
b5968bffb65c More sed bugfixes.
Rob Landley <rob@landley.net>
parents: 1561
diff changeset
891 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
892 corwin->sflags |= l << 3;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
893 line--;
1561
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
894 } 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
895 }
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
896
1561
162c7cc868e5 sed: fix 'q', and { }, and } after s/// with no semicolon.
Rob Landley <rob@landley.net>
parents: 1560
diff changeset
897 // 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
898 // allocating the space was done by extend_string() above
1653
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
899 if (!*TT.remember) corwin->arg1 = 0;
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
900 else xregcomp((void *)(corwin->arg1 + (char *)corwin), TT.remember,
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
901 ((toys.optflags & FLAG_r)*REG_EXTENDED)|((corwin->sflags&1)*REG_ICASE));
1653
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
902 free(TT.remember);
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
903 TT.remember = 0;
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
904 if (*line == 'w') {
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
905 line++;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
906 goto writenow;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
907 }
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
908 } else if (c == 'w') {
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
909 int fd, delim;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
910 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
911
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
912 // 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
913 // 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
914 // 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
915 // 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
916
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
917 writenow:
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
918 while (isspace(*line)) line++;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
919 if (!*line) goto brand;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
920 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
921 delim = *cc;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
922 *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
923 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
924 *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
925
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
926 corwin->w = reg - (char *)corwin;
1559
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
927 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
928 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
929
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
930 memcpy(reg, &fd, 4);
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
931 reg += 4;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
932 *(reg++) = 0;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
933 memcpy(reg, line, delim);
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
934 reg += delim;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
935 *(reg++) = 0;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
936
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
937 line = cc;
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
938 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
939 } 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
940 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
941 int len;
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
942
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
943 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
944 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
945 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
946 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
947 free(s);
1552
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
948 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
949 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
950 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
951 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
952 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
953 } else if (strchr("abcirtTw:", c)) {
1620
6f7ed6316d90 Another sed bug. (The e2fsprogs build uses multiple line continuations on the same command.)
Rob Landley <rob@landley.net>
parents: 1619
diff changeset
954 int 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
955
1653
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
956 while (isspace(*line) && *line != '\n') 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
957
1653
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
958 // Resume logic differs from 's' case because we don't add a newline
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
959 // unless it's after something, so we add it on return instead.
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
960 resume_a:
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
961 corwin->hit = 0;
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
962
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
963 // Trim whitespace from "b ;" and ": blah " but only first space in "w x "
1620
6f7ed6316d90 Another sed bug. (The e2fsprogs build uses multiple line continuations on the same command.)
Rob Landley <rob@landley.net>
parents: 1619
diff changeset
964 if (!(end = strcspn(line, strchr("btT:", c) ? "; \t\r\n\v\f" : "\n"))) {
6f7ed6316d90 Another sed bug. (The e2fsprogs build uses multiple line continuations on the same command.)
Rob Landley <rob@landley.net>
parents: 1619
diff changeset
965 if (strchr("btT", c)) continue;
6f7ed6316d90 Another sed bug. (The e2fsprogs build uses multiple line continuations on the same command.)
Rob Landley <rob@landley.net>
parents: 1619
diff changeset
966 else if (!corwin->arg1) 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
967 }
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
968
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
969 // 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
970 // 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
971 // 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
972 if (!corwin->arg1) corwin->arg1 = reg - (char*)corwin;
1620
6f7ed6316d90 Another sed bug. (The e2fsprogs build uses multiple line continuations on the same command.)
Rob Landley <rob@landley.net>
parents: 1619
diff changeset
973 else if ((corwin+1) != (void *)reg) *(reg++) = '\n';
6f7ed6316d90 Another sed bug. (The e2fsprogs build uses multiple line continuations on the same command.)
Rob Landley <rob@landley.net>
parents: 1619
diff changeset
974 reg = extend_string((void *)&corwin, line, reg - (char *)corwin, end);
6f7ed6316d90 Another sed bug. (The e2fsprogs build uses multiple line continuations on the same command.)
Rob Landley <rob@landley.net>
parents: 1619
diff changeset
975
1556
e7944f8fdcbb Debugging pass on sed: make the existing test suite pass.
Rob Landley <rob@landley.net>
parents: 1553
diff changeset
976 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
977
1612
eec3b88f2d58 Make sed a\ line continuations work properly for different pattern input modes.
Rob Landley <rob@landley.net>
parents: 1611
diff changeset
978 // Line continuation? (Two slightly different input methods, -e with
eec3b88f2d58 Make sed a\ line continuations work properly for different pattern input modes.
Rob Landley <rob@landley.net>
parents: 1611
diff changeset
979 // embedded newline vs -f line by line. Must parse both correctly.)
1620
6f7ed6316d90 Another sed bug. (The e2fsprogs build uses multiple line continuations on the same command.)
Rob Landley <rob@landley.net>
parents: 1619
diff changeset
980 if (!strchr("btT:", c) && line[-1] == '\\') {
1653
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
981 // backslash only matters if we have an odd number of them
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
982 for (i = 0; i<end; i++) if (line[-i-1] != '\\') break;
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
983 if (i&1) {
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
984 // reg is next available space, so reg[-1] is the null terminator
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
985 reg[-2] = 0;
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
986 if (*line && line[1]) {
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
987 reg -= 2;
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
988 line++;
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
989 goto resume_a;
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
990 } else corwin->hit = 256;
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
991 }
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
992 }
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
993
8bc715741481 Next drop of sed infrastructure, mostly argument parsing, doesn't do anything interesting yet.
Rob Landley <rob@landley.net>
parents: 1537
diff changeset
994 // 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
995 } 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
996 }
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
997
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
998 brand:
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
999 // Reminisce about chestnut trees.
1601
2dcc165f6e21 Fix some sed bugs and improve error reporting.
Rob Landley <rob@landley.net>
parents: 1577
diff changeset
1000 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
1001 }
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
1002
231
31dc682c18ad Very early stub of sed, does nothing yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
1003 void sed_main(void)
31dc682c18ad Very early stub of sed, does nothing yet.
Rob Landley <rob@landley.net>
parents:
diff changeset
1004 {
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
1005 struct arg_list *dworkin;
1520
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
1006 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
1007
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
1008 // 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
1009 // 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
1010 // 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
1011 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
1012 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
1013 return;
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
1014 }
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
1015
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
1016 // 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
1017 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
1018 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
1019 (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
1020 }
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
1021
ad6b2f0e566b Next round of sed infrastructure, parses most commands now, doesn't implement them yet.
Rob Landley <rob@landley.net>
parents: 1538
diff changeset
1022 // 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
1023 // 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
1024
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
1025 for (dworkin = TT.e; dworkin; dworkin = dworkin->next)
1559
9b2402162464 Fix more sed bugs.
Rob Landley <rob@landley.net>
parents: 1558
diff changeset
1026 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
1027 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
1028 do_lines(xopen(dworkin->arg, O_RDONLY), dworkin->arg, jewel_of_judgement);
1653
58cb2d7bd461 sed s/// can have line continuations in the replacement part, with or without a \ escaping the newline.
Rob Landley <rob@landley.net>
parents: 1646
diff changeset
1029 jewel_of_judgement(0, 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
1030 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
1031 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
1032
1532
bf2c5216d726 Basic sed range support, enough for "sed -n 9,11p README" to work.
Rob Landley <rob@landley.net>
parents: 1530
diff changeset
1033 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
1034 TT.remember = xstrdup("");
1530
3eafa445c1a6 Random in-progress snapshot of sed, not finished yet.
Rob Landley <rob@landley.net>
parents: 1520
diff changeset
1035
1520
dfd6b3404c16 Started over on sed (by reading the posix spec).
Rob Landley <rob@landley.net>
parents: 1235
diff changeset
1036 // 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
1037 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
1038
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
1039 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
1040
57ee7711a0c9 Implement more sed plumbing, including s/// (without \1 or & yet).
Rob Landley <rob@landley.net>
parents: 1550
diff changeset
1041 // 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
1042 }