aboutsummaryrefslogtreecommitdiff
path: root/editors/sed.c
diff options
context:
space:
mode:
Diffstat (limited to 'editors/sed.c')
-rw-r--r--editors/sed.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/editors/sed.c b/editors/sed.c
index 73034438a..374830f3f 100644
--- a/editors/sed.c
+++ b/editors/sed.c
@@ -100,6 +100,12 @@ enum {
100 OPT_in_place = 1 << 0, 100 OPT_in_place = 1 << 0,
101}; 101};
102 102
103struct sed_FILE {
104 struct sed_FILE *next; /* Next (linked list, NULL terminated) */
105 const char *fname;
106 FILE *fp;
107};
108
103/* Each sed command turns into one of these structures. */ 109/* Each sed command turns into one of these structures. */
104typedef struct sed_cmd_s { 110typedef struct sed_cmd_s {
105 /* Ordered by alignment requirements: currently 36 bytes on x86 */ 111 /* Ordered by alignment requirements: currently 36 bytes on x86 */
@@ -157,6 +163,11 @@ struct globals {
157 /* linked list of append lines */ 163 /* linked list of append lines */
158 llist_t *append_head; 164 llist_t *append_head;
159 165
166 /* linked list of FILEs opened for 'w' and s///w'.
167 * Needed to handle duplicate fnames: sed '/a/w F;/b/w F'
168 */
169 struct sed_FILE *FILE_head;
170
160 char *add_cmd_line; 171 char *add_cmd_line;
161 172
162 struct pipeline { 173 struct pipeline {
@@ -217,6 +228,22 @@ static void sed_free_and_close_stuff(void)
217void sed_free_and_close_stuff(void); 228void sed_free_and_close_stuff(void);
218#endif 229#endif
219 230
231static FILE *sed_xfopen_w(const char *fname)
232{
233 struct sed_FILE **pp = &G.FILE_head;
234 struct sed_FILE *cur;
235 while ((cur = *pp) != NULL) {
236 if (strcmp(cur->fname, fname) == 0)
237 return cur->fp;
238 pp = &cur->next;
239 }
240 *pp = cur = xzalloc(sizeof(*cur));
241 /*cur->next = NULL; - already is */
242 cur->fname = xstrdup(fname);
243 cur->fp = xfopen_for_write(fname);
244 return cur->fp;
245}
246
220/* If something bad happens during -i operation, delete temp file */ 247/* If something bad happens during -i operation, delete temp file */
221 248
222static void cleanup_outname(void) 249static void cleanup_outname(void)
@@ -452,7 +479,7 @@ static int parse_subst_cmd(sed_cmd_t *sed_cmd, const char *substr)
452 { 479 {
453 char *fname; 480 char *fname;
454 idx += parse_file_cmd(/*sed_cmd,*/ substr+idx+1, &fname); 481 idx += parse_file_cmd(/*sed_cmd,*/ substr+idx+1, &fname);
455 sed_cmd->sw_file = xfopen_for_write(fname); 482 sed_cmd->sw_file = sed_xfopen_w(fname);
456 sed_cmd->sw_last_char = '\n'; 483 sed_cmd->sw_last_char = '\n';
457 free(fname); 484 free(fname);
458 break; 485 break;
@@ -567,7 +594,7 @@ static const char *parse_cmd_args(sed_cmd_t *sed_cmd, const char *cmdstr)
567 } 594 }
568 cmdstr += parse_file_cmd(/*sed_cmd,*/ cmdstr, &sed_cmd->string); 595 cmdstr += parse_file_cmd(/*sed_cmd,*/ cmdstr, &sed_cmd->string);
569 if (sed_cmd->cmd == 'w') { 596 if (sed_cmd->cmd == 'w') {
570 sed_cmd->sw_file = xfopen_for_write(sed_cmd->string); 597 sed_cmd->sw_file = sed_xfopen_w(sed_cmd->string);
571 sed_cmd->sw_last_char = '\n'; 598 sed_cmd->sw_last_char = '\n';
572 } 599 }
573 } 600 }