diff options
Diffstat (limited to 'sed.c')
-rw-r--r-- | sed.c | 110 |
1 files changed, 62 insertions, 48 deletions
@@ -33,12 +33,10 @@ | |||
33 | 33 | ||
34 | static const char sed_usage[] = | 34 | static const char sed_usage[] = |
35 | "sed [-n] [-e script] [file...]\n" | 35 | "sed [-n] [-e script] [file...]\n" |
36 | "Allowed scripts come in two forms:\n" | 36 | "Allowed scripts come in the following form:\n\n" |
37 | "'/regexp/[gp]'\n" | ||
38 | "\tattempt to match regexp against the pattern space\n" | ||
39 | "'s/regexp/replacement/[gp]'\n" | 37 | "'s/regexp/replacement/[gp]'\n" |
40 | "\tattempt to match regexp against the pattern space\n" | 38 | "\tattempt to match regexp against the pattern space\n" |
41 | "\tand if successful replaces the matched portion with replacement." | 39 | "\tand if successful replaces the matched portion with replacement.\n\n" |
42 | "Options:\n" | 40 | "Options:\n" |
43 | "-e\tadd the script to the commands to be executed\n" | 41 | "-e\tadd the script to the commands to be executed\n" |
44 | "-n\tsuppress automatic printing of pattern space\n\n" | 42 | "-n\tsuppress automatic printing of pattern space\n\n" |
@@ -49,64 +47,86 @@ static const char sed_usage[] = | |||
49 | #endif | 47 | #endif |
50 | 48 | ||
51 | 49 | ||
52 | static int replaceFlag = FALSE; | ||
53 | static int noprintFlag = FALSE; | ||
54 | 50 | ||
55 | 51 | ||
56 | extern int sed_main (int argc, char **argv) | 52 | extern int sed_main (int argc, char **argv) |
57 | { | 53 | { |
58 | FILE *fp; | 54 | FILE *fp; |
59 | const char *needle; | 55 | char *needle=NULL, *newNeedle=NULL; |
60 | const char *name; | 56 | char *name; |
61 | const char *cp; | 57 | char *cp; |
62 | int tellName=TRUE; | ||
63 | int ignoreCase=FALSE; | 58 | int ignoreCase=FALSE; |
64 | int tellLine=FALSE; | 59 | int foundOne=FALSE; |
65 | long line; | 60 | int noprintFlag=FALSE; |
66 | char haystack[BUF_SIZE]; | 61 | int stopNow; |
67 | 62 | char *haystack; | |
68 | ignoreCase = FALSE; | ||
69 | tellLine = FALSE; | ||
70 | 63 | ||
71 | argc--; | 64 | argc--; |
72 | argv++; | 65 | argv++; |
73 | if (argc < 1) { | 66 | if (argc < 1) { |
74 | usage(grep_usage); | 67 | usage(sed_usage); |
75 | } | 68 | } |
76 | 69 | ||
77 | if (**argv == '-') { | 70 | if (**argv == '-') { |
78 | argc--; | 71 | argc--; |
79 | cp = *argv++; | 72 | cp = *argv++; |
73 | stopNow=FALSE; | ||
80 | 74 | ||
81 | while (*++cp) | 75 | while (*++cp && stopNow==FALSE) |
82 | switch (*cp) { | 76 | switch (*cp) { |
83 | case 'n': | 77 | case 'n': |
84 | noprintFlag = TRUE; | 78 | noprintFlag = TRUE; |
85 | break; | 79 | break; |
86 | case 'e': | 80 | case 'e': |
87 | if (*(*argv)+1 != '\'' && **argv != '\"') { | 81 | if (*(cp+1)==0 && --argc < 0) { |
88 | if (--argc == 0) | 82 | fprintf(stderr, "A\n"); |
89 | usage( mkdir_usage); | 83 | usage( sed_usage); |
90 | ++argv; | ||
91 | if (*(*argv)+1 != '\'' && **argv != '\"') { | ||
92 | usage( mkdir_usage); | ||
93 | } | 84 | } |
94 | /* Find the specified modes */ | 85 | cp = *argv++; |
95 | mode = 0; | 86 | while( *cp ) { |
96 | if ( parse_mode(*(++argv), &mode) == FALSE ) { | 87 | if (*cp == 's' && strlen(cp) > 3 && *(cp+1) == '/') { |
97 | fprintf(stderr, "Unknown mode: %s\n", *argv); | 88 | char* pos=needle=cp+2; |
98 | exit( FALSE); | 89 | for(;;) { |
90 | pos = strchr(pos, '/'); | ||
91 | if (pos==NULL) { | ||
92 | fprintf(stderr, "B\n"); | ||
93 | usage( sed_usage); | ||
94 | } | ||
95 | if (*(pos-1) == '\\') { | ||
96 | pos++; | ||
97 | continue; | ||
98 | } | ||
99 | break; | ||
100 | } | ||
101 | *pos=0; | ||
102 | newNeedle=++pos; | ||
103 | for(;;) { | ||
104 | pos = strchr(pos, '/'); | ||
105 | if (pos==NULL) { | ||
106 | fprintf(stderr, "C\n"); | ||
107 | usage( sed_usage); | ||
108 | } | ||
109 | if (*(pos-1) == '\\') { | ||
110 | pos++; | ||
111 | continue; | ||
112 | } | ||
113 | break; | ||
114 | } | ||
115 | *pos=0; | ||
116 | } | ||
117 | cp++; | ||
99 | } | 118 | } |
119 | fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); | ||
120 | stopNow=TRUE; | ||
100 | break; | 121 | break; |
101 | 122 | ||
102 | default: | 123 | default: |
103 | usage(grep_usage); | 124 | fprintf(stderr, "D\n"); |
125 | usage(sed_usage); | ||
104 | } | 126 | } |
105 | } | 127 | } |
106 | 128 | ||
107 | needle = *argv++; | 129 | fprintf(stderr, "argc=%d\n", argc); |
108 | argc--; | ||
109 | |||
110 | while (argc-- > 0) { | 130 | while (argc-- > 0) { |
111 | name = *argv++; | 131 | name = *argv++; |
112 | 132 | ||
@@ -115,25 +135,19 @@ extern int sed_main (int argc, char **argv) | |||
115 | perror (name); | 135 | perror (name); |
116 | continue; | 136 | continue; |
117 | } | 137 | } |
138 | fprintf(stderr, "filename is '%s'\n", name); | ||
118 | 139 | ||
119 | line = 0; | 140 | haystack = (char*)malloc( 80); |
120 | |||
121 | while (fgets (haystack, sizeof (haystack), fp)) { | 141 | while (fgets (haystack, sizeof (haystack), fp)) { |
122 | line++; | ||
123 | cp = &haystack[strlen (haystack) - 1]; | ||
124 | |||
125 | if (*cp != '\n') | ||
126 | fprintf (stderr, "%s: Line too long\n", name); | ||
127 | |||
128 | if (find_match(haystack, needle, ignoreCase) == TRUE) { | ||
129 | if (tellName==TRUE) | ||
130 | printf ("%s: ", name); | ||
131 | |||
132 | if (tellLine==TRUE) | ||
133 | printf ("%ld: ", line); | ||
134 | 142 | ||
143 | foundOne = replace_match(haystack, needle, newNeedle, ignoreCase); | ||
144 | if (noprintFlag==TRUE && foundOne==TRUE) | ||
135 | fputs (haystack, stdout); | 145 | fputs (haystack, stdout); |
136 | } | 146 | else |
147 | fputs (haystack, stdout); | ||
148 | /* Avoid any mem leaks */ | ||
149 | free(haystack); | ||
150 | haystack = (char*)malloc( BUF_SIZE); | ||
137 | } | 151 | } |
138 | 152 | ||
139 | if (ferror (fp)) | 153 | if (ferror (fp)) |