diff toys/posix/sed.c @ 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. The actual code should be the same afterward, this is just cosmetic refactoring.
author Rob Landley <rob@landley.net>
date Tue, 13 Nov 2012 17:14:08 -0600
parents 7e846e281e38
children
line wrap: on
line diff
--- a/toys/posix/sed.c	Tue Nov 13 16:13:45 2012 -0600
+++ b/toys/posix/sed.c	Tue Nov 13 17:14:08 2012 -0600
@@ -1,21 +1,24 @@
-/* vi: set sw=4 ts=4:
+/* sed.c - Stream editor.
  *
- * sed.c - Stream editor.
- *
- * Copyright 2008 Rob Landley <rob@landley.net>
+ * Copyright 2012 Rob Landley <rob@landley.net>
  *
  * See http://opengroup.org/onlinepubs/9699919799/utilities/sed.c
 
 USE_SED(NEWTOY(sed, "irne*", TOYFLAG_BIN))
 
 config SED
-	bool "sed"
-	default n
-	help
-	  usage: sed [-irn] {command | [-e command]...} [FILE...]
+  bool "sed"
+  default n
+  help
+    usage: sed [-irn] {command | [-e command]...} [FILE...]
 
-	  Stream EDitor, transforms text by appling commands to each line
-	  of input.
+    Stream EDitor, transforms text by appling script of command to each line
+    of input.
+
+    -e  Add expression to the command script (if no -e, use first argument)
+    -i	Modify file in place
+    -n  No default output (p commands only)
+    -r  Use extended regular expression syntex
 */
 
 #define FOR_sed
@@ -23,40 +26,106 @@
 #include "lib/xregcomp.h"
 
 GLOBALS(
-	struct arg_list *commands;
+  struct arg_list *scripts;
+  struct double_list *commands;
+
+  void *parsed;
 )
 
+// Digested version of what sed commands can actually tell use to do.
+
+
 struct sed_command {
-	// Doubly linked list of commands.
-	struct sed_command *next, *prev;
+  // double_list compatibility (easier to create in-order)
+  struct sed_command *next, *prev;
 
-	// Regexes for s/match/data/ and /match_begin/,/match_end/command
-	regex_t *match, *match_begin, *match_end;
+  // data string for (saicytb)
+  char c, *data;
+  // Regexes for s/match/data/ and /begin/,/end/command
+  regex_t *match, *begin, *end;
+  // For numeric ranges ala 10,20command
+  long lstart, lstop;
+  // Which match to replace, 0 for all. s and w commands can write to a file
+  int which, outfd;
+};
 
-	// For numeric ranges ala 10,20command
-	int first_line, last_line;
+//  Space. Space. Gotta get past space. Spaaaaaaaace! (But not newline.)
+void spaceorb(char **s)
+{
+  while (**s == ' ' || **s == '\t') *s++;
+}
 
-	// Which match to replace, 0 for all.
-	int which;
+void parse_scripts(void)
+{
+  struct sed_command *commands = 0;
+  struct arg_list *script;
+  int which = 0;
+  long l;
+
+  for (script = TT.scripts; *script; script = script->next) {
+    char *str = script->arg, *s;
+    struct sed_command *cmd;
+
+    which++;
+    for (i=1;;) {
+      if (!*str) break;
+
+      cmd = xzalloc(sizeof(struct sed_command));
 
-	// s and w commands can write to a file.  Slight optimization: we use 0
-	// instead of -1 to mean no file here, because even when there's no stdin
-	// our input file would take fd 0.
-	int outfd;
+      // Identify prefix
+      for (;;) {
+        long l;
+
+        spaceorb(&str);
+        if (*str == '$') {
+          l = -1;
+          str++;
+        } else if (isdigit(*str)) l = strtol(str, &str, 10);
+        else if (!cmd->lstart) break;
+        else goto parse_fail;
 
-	// Data string for (saicytb)
-	char *data;
+        spaceorb(&str);
+        if (!cmd->lstart) {
+          if (!l) goto parse_fail;
+          cmd->lstart = l;
+          if (*str != ',') break;
+          str++;
+          continue;
+        }
+        cmd->lstop = l;
+        break;
+      } else if (*str == '/') {
+        printf("regex\n");
+      }
+      l = stridx("{bcdDgGhHlnNpPstwxyrqia= \t#:}", *str);
+      if (l == -1) goto parse_fail;
 
-	// Which command letter is this?
-	char command;
-};
+
+    }
+  }
+
+  return;
+
+parse_fail:
+  error_exit("bad expression %d@%d: %s", which, i, script->arg+i);
+}
 
 void sed_main(void)
 {
-	struct arg_list *test;
+  char **files=toys.optargs;
+
+  // If no -e, use first argument
+  if (!TT.scripts) {
+    if (!*files) error_exit("Need script");
+    (TT.scripts=xzalloc(sizeof(struct arg_list)))->arg=*(files++);
+  }
+
 
-	for (test = TT.commands; test; test = test->next)
-		dprintf(2,"command=%s\n",test->arg);
+  {
+    struct arg_list *test;
 
-	printf("Hello world\n");
+    for (test = TT.commands; test; test = test->next)
+      dprintf(2,"command=%s\n",test->arg);
+    while (*files) dprintf(2,"file=%s\n", *(files++));
+  }
 }