Forgot this.
[oweals/busybox.git] / sed.c
diff --git a/sed.c b/sed.c
index 4dd552a2d7d336bdd3831ffc8f0c814b4ce7a52d..4dfc0246c9e87a9b54033a587ad842dbb99ea8b9 100644 (file)
--- a/sed.c
+++ b/sed.c
 #include <ctype.h>
 
 static const char sed_usage[] = 
-"sed [-n] [-e script] [file...]\n"
-"Allowed scripts come in two forms:\n"
-"'/regexp/[gp]'\n"
-"\tattempt to match regexp against the pattern space\n"
-"'s/regexp/replacement/[gp]'\n"
-"\tattempt to match regexp against the pattern space\n"
-"\tand if successful replaces the matched portion with replacement."
+"sed [-n] [-e script] [file...]\n\n"
+"Allowed sed scripts come in the following form:\n"
+"\t's/regexp/replacement/[gp]'\n"
+"which attempt to match regexp against the pattern space\n"
+"and if successful replaces the matched portion with replacement.\n\n"
 "Options:\n"
 "-e\tadd the script to the commands to be executed\n"
 "-n\tsuppress automatic printing of pattern space\n\n"
 #if defined BB_REGEXP
-"This version of sed matches full regexps.\n";
+"This version of sed matches full regular expresions.\n";
 #else
-"This version of sed matches strings (not full regexps).\n";
+"This version of sed matches strings (not full regular expresions).\n";
 #endif
+    
 
+static void do_sed(FILE *fp, char *needle, char *newNeedle, int ignoreCase, int printFlag, int quietFlag)
+{
+    int foundOne=FALSE;
+    char haystack[1024];
 
-static int replaceFlag = FALSE;
-static int noprintFlag = FALSE;
-
+    while (fgets (haystack, 1023, fp)) {
+       foundOne = replace_match(haystack, needle, newNeedle, ignoreCase);
+       if (foundOne==TRUE && printFlag==TRUE) {
+           fprintf(stdout, haystack);
+       }
+       if (quietFlag==FALSE) {
+           fprintf(stdout, haystack);
+       }
+    }
+}
 
 extern int sed_main (int argc, char **argv)
 {
     FILE *fp;
-    const char *needle;
-    const char *name;
-    const char *cp;
-    int tellName=TRUE;
+    char *needle=NULL, *newNeedle=NULL;
+    char *name;
+    char *cp;
     int ignoreCase=FALSE;
-    int tellLine=FALSE;
-    long line;
-    char haystack[BUF_SIZE];
-
-    ignoreCase = FALSE;
-    tellLine = FALSE;
+    int printFlag=FALSE;
+    int quietFlag=FALSE;
+    int stopNow;
 
     argc--;
     argv++;
     if (argc < 1) {
-       usage(grep_usage);
+       usage(sed_usage);
     }
 
     if (**argv == '-') {
        argc--;
        cp = *argv++;
+       stopNow=FALSE;
 
-       while (*++cp)
+       while (*++cp && stopNow==FALSE) {
            switch (*cp) {
            case 'n':
-               noprintFlag = TRUE;
+               quietFlag = TRUE;
                break;
            case 'e':
-               if (*(*argv)+1 != '\'' && **argv != '\"') {
-                   if (--argc == 0)
-                       usage( mkdir_usage);
-                   ++argv;
-                   if (*(*argv)+1 != '\'' && **argv != '\"') {
-                       usage( mkdir_usage);
+               if (*(cp+1)==0 && --argc < 0) {
+                   usage( sed_usage);
                }
-               /* Find the specified modes */
-               mode = 0;
-               if ( parse_mode(*(++argv), &mode) == FALSE ) {
-                   fprintf(stderr, "Unknown mode: %s\n", *argv);
-                   exit( FALSE);
+               if ( *++cp != 's')
+                   cp = *argv++;
+               while( *cp ) {
+                   if (*cp == 's' && strlen(cp) > 3 && *(cp+1) == '/') {
+                       char* pos=needle=cp+2;
+                       for(;;) {
+                           pos = strchr(pos, '/');
+                           if (pos==NULL) {
+                               usage( sed_usage);
+                           }
+                           if (*(pos-1) == '\\') {
+                               pos++;
+                               continue;
+                           }
+                           break;
+                       }
+                       *pos=0;
+                       newNeedle=++pos;
+                       for(;;) {
+                           pos = strchr(pos, '/');
+                           if (pos==NULL) {
+                               usage( sed_usage);
+                           }
+                           if (*(pos-1) == '\\') {
+                               pos++;
+                               continue;
+                           }
+                           break;
+                       }
+                       *pos=0;
+                       if (pos+2 != 0) {
+                           while (*++pos) {
+                               switch (*pos) {
+                                   case 'i':
+                                       ignoreCase=TRUE;
+                                       break;
+                                   case 'p':
+                                       printFlag=TRUE;
+                                       break;
+                                   case 'g':
+                                       break;
+                                   default:
+                                       usage( sed_usage);
+                               }
+                           }
+                       }
+                   }
+                   cp++;
                }
+               //fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle);
+               stopNow=TRUE;
                break;
 
            default:
-               usage(grep_usage);
+               usage(sed_usage);
            }
-    }
-
-    needle = *argv++;
-    argc--;
-
-    while (argc-- > 0) {
-       name = *argv++;
-
-       fp = fopen (name, "r");
-       if (fp == NULL) {
-           perror (name);
-           continue;
        }
+    }
 
-       line = 0;
-
-       while (fgets (haystack, sizeof (haystack), fp)) {
-           line++;
-           cp = &haystack[strlen (haystack) - 1];
+    if (argc==0) {
+       do_sed( stdin, needle, newNeedle, ignoreCase, printFlag, quietFlag);
+    } else {
+       while (argc-- > 0) {
+           name = *argv++;
 
-           if (*cp != '\n')
-               fprintf (stderr, "%s: Line too long\n", name);
+           fp = fopen (name, "r");
+           if (fp == NULL) {
+               perror (name);
+               continue;
+           }
 
-           if (find_match(haystack, needle, ignoreCase) == TRUE) {
-               if (tellName==TRUE)
-                   printf ("%s: ", name);
+           do_sed( fp, needle, newNeedle, ignoreCase, printFlag, quietFlag);
 
-               if (tellLine==TRUE)
-                   printf ("%ld: ", line);
+           if (ferror (fp))
+               perror (name);
 
-               fputs (haystack, stdout);
-           }
+           fclose (fp);
        }
-
-       if (ferror (fp))
-           perror (name);
-
-       fclose (fp);
     }
     exit( TRUE);
 }