aboutsummaryrefslogtreecommitdiff
path: root/editors
diff options
context:
space:
mode:
Diffstat (limited to 'editors')
-rw-r--r--editors/ed.c15
-rw-r--r--editors/sed.c31
2 files changed, 40 insertions, 6 deletions
diff --git a/editors/ed.c b/editors/ed.c
index dfe0f1a77..209ce9942 100644
--- a/editors/ed.c
+++ b/editors/ed.c
@@ -18,7 +18,7 @@
18 18
19//applet:IF_ED(APPLET(ed, BB_DIR_BIN, BB_SUID_DROP)) 19//applet:IF_ED(APPLET(ed, BB_DIR_BIN, BB_SUID_DROP))
20 20
21//usage:#define ed_trivial_usage "[-p PROMPT] [FILE]" 21//usage:#define ed_trivial_usage "[-p PROMPT] [-s] [FILE]"
22//usage:#define ed_full_usage "" 22//usage:#define ed_full_usage ""
23 23
24#include "libbb.h" 24#include "libbb.h"
@@ -71,6 +71,11 @@ struct globals {
71 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 71 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
72} while (0) 72} while (0)
73 73
74#define OPTION_STR "sp:"
75enum {
76 OPT_s = (1 << 0),
77};
78
74static int bad_nums(int num1, int num2, const char *for_what) 79static int bad_nums(int num1, int num2, const char *for_what)
75{ 80{
76 if ((num1 < 1) || (num2 > lastNum) || (num1 > num2)) { 81 if ((num1 < 1) || (num2 > lastNum) || (num1 > num2)) {
@@ -458,7 +463,8 @@ static int readLines(const char *file, int num)
458 * in the following format: 463 * in the following format:
459 * "%d\n", <number of bytes read> 464 * "%d\n", <number of bytes read>
460 */ 465 */
461 printf("%u\n", charCount); 466 if (!(option_mask32 & OPT_s))
467 printf("%u\n", charCount);
462 return TRUE; 468 return TRUE;
463} 469}
464 470
@@ -510,7 +516,8 @@ static int writeLines(const char *file, int num1, int num2)
510 * unless the -s option was specified, in the following format: 516 * unless the -s option was specified, in the following format:
511 * "%d\n", <number of bytes written> 517 * "%d\n", <number of bytes written>
512 */ 518 */
513 printf("%u\n", charCount); 519 if (!(option_mask32 & OPT_s))
520 printf("%u\n", charCount);
514 return TRUE; 521 return TRUE;
515} 522}
516 523
@@ -1005,7 +1012,7 @@ int ed_main(int argc UNUSED_PARAM, char **argv)
1005 lines.prev = &lines; 1012 lines.prev = &lines;
1006 1013
1007 prompt = ""; /* no prompt by default */ 1014 prompt = ""; /* no prompt by default */
1008 getopt32(argv, "p:", &prompt); 1015 getopt32(argv, OPTION_STR, &prompt);
1009 argv += optind; 1016 argv += optind;
1010 1017
1011 if (argv[0]) { 1018 if (argv[0]) {
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 }