A regular expression is first compiled with compile(). You will want to preserve this. But in ed.c, compile() is called with a single character that indicates what character will terminate the regular expression (for example, '/'); compile() collects the regular expression into a buffer by reading one character at a time with getchr() until it finds a terminator. You should replace this mechanism with something that just compiles a regular expression passed in as a char* argument.
Similarly, execute(), which tests whether a single line matches the compiled regular expression, accesses the text of the line by calling getline(). You should replace this interface by calling execute with two arguments, the compiled regular expression and the line to test.
With these two changes, main() becomes rather similar to the grep program in TPOP.
advance() is much like the match() function that we examined in class; it's called by execute() to move to the next character of the text and the next piece of the RE.
The function getchr() is used to read the next character typed by the user of ed. You can replace it throughout compile() by something that fetches the next RE character and advances a pointer.
Don't use any of the I/O mechanisms in ed.c; they are too specialized to its file manipulations. Use stdio in the most straightforward way that you can, again lifted from grep in TPOP.
The file ed1.c is the same as ed.c, except that it has a few extra comments; compare the two versions with diff.