+/* Flags & variables */
+
+typedef enum { f_none, f_replace, f_append } sed_function;
+
+#define NO_LINE -2
+#define LAST_LINE -1
+static int addr_line = NO_LINE;
+static char *addr_pattern = NULL;
+static int negated = 0;
+
+#define SKIPSPACES(p) do { while (isspace(*(p))) (p)++; } while (0)
+
+#define BUFSIZE 1024
+
+static inline int at_last(FILE * fp)
+{
+ int res = 0;
+
+ if (feof(fp))
+ return 1;
+ else {
+ char ch;
+ if ((ch = fgetc(fp)) == EOF)
+ res++;
+ ungetc(ch, fp);
+ }
+ return res;
+}
+
+static void do_sed_repl(FILE * fp, char *needle, char *newNeedle,
+ int ignoreCase, int printFlag, int quietFlag)
+{
+ int foundOne = FALSE;
+ char haystack[BUFSIZE];
+ int line = 1, doit;
+
+ while (fgets(haystack, BUFSIZE - 1, fp)) {
+ doit = 0;
+ if (addr_pattern) {
+ doit = !find_match(haystack, addr_pattern, FALSE);
+ } else if (addr_line == NO_LINE)
+ doit = 1;
+ else if (addr_line == LAST_LINE) {
+ if (at_last(fp))
+ doit = 1;
+ } else {
+ if (line == addr_line)
+ doit = 1;
+ }
+ if (negated)
+ doit = 1 - doit;
+ if (doit) {
+ foundOne =
+ replace_match(haystack, needle, newNeedle, ignoreCase);
+
+ if (foundOne == TRUE && printFlag == TRUE) {
+ fprintf(stdout, haystack);
+ }
+ }
+
+ if (quietFlag == FALSE) {
+ fprintf(stdout, haystack);
+ }
+
+ line++;
+ }
+}
+
+static void do_sed_append(FILE * fp, char *appendline, int quietFlag)
+{
+ char buffer[BUFSIZE];
+ int line = 1, doit;