- grouped commands: {cmd1;cmd2}
- transliteration (y/source-chars/dest-chars/)
- pattern space hold space storing / swapping (g, h, x)
- - labels / branching (: label, b, t)
+ - labels / branching (: label, b, t, T)
(Note: Specifying an address (range) to match is *optional*; commands
default to the whole pattern space if no specific address match was
Unsupported features:
- - GNU extensions
+ - most GNU extensions
- and more.
Todo:
#include <stdio.h>
#include <unistd.h> /* for getopt() */
-#include <regex.h>
#include <string.h> /* for strdup() */
#include <errno.h>
#include <ctype.h> /* for isspace() */
#include <stdlib.h>
#include "busybox.h"
+#include "xregex.h"
typedef struct sed_cmd_s {
/* Ordered by alignment requirements: currently 36 bytes on x86 */
static sed_cmd_t *sed_cmd_tail = &sed_cmd_head;
/* Linked list of append lines */
-static struct append_list {
+struct append_list {
char *string;
struct append_list *next;
};
if(sed_cmd->cmd=='w')
sed_cmd->file=bb_xfopen(sed_cmd->string,"w");
/* handle branch commands */
- } else if (strchr(":bt", sed_cmd->cmd)) {
+ } else if (strchr(":btT", sed_cmd->cmd)) {
int length;
while(isspace(*cmdstr)) cmdstr++;
break;
}
- /* Test if substition worked, branch if so. */
+ /* Test/branch if substitution occurred */
case 't':
- if (!substituted) break;
+ if(!substituted) break;
substituted=0;
- /* Fall through */
+ /* Fall through */
+ /* Test/branch if substitution didn't occur */
+ case 'T':
+ if (substituted) break;
+ /* Fall through */
/* Branch to label */
case 'b':
if (!sed_cmd->string) goto discard_commands;
for (j = 0; sed_cmd->string[j]; j += 2) {
if (pattern_space[i] == sed_cmd->string[j]) {
pattern_space[i] = sed_cmd->string[j + 1];
+ break;
}
}
}
* files were specified or '-' was specified, take input from stdin.
* Otherwise, we process all the files specified. */
if (argv[optind] == NULL) {
- if(in_place) {
- fprintf(stderr,"sed: Filename required for -i\n");
- exit(1);
- }
+ if(in_place) bb_error_msg_and_die("Filename required for -i");
add_input_file(stdin);
process_files();
} else {
if (file) {
if(in_place) {
struct stat statbuf;
+ int nonstdoutfd;
+
outname=bb_xstrndup(argv[i],strlen(argv[i])+6);
strcat(outname,"XXXXXX");
- mkstemp(outname);
- nonstdout=bb_wfopen(outname,"w");
+ if(-1==(nonstdoutfd=mkstemp(outname)))
+ bb_error_msg_and_die("no temp file");
+ nonstdout=fdopen(nonstdoutfd,"w");
/* Set permissions of output file */
fstat(fileno(file),&statbuf);
- fchmod(fileno(nonstdout),statbuf.st_mode);
- atexit(cleanup_outname);
+ fchmod(nonstdoutfd,statbuf.st_mode);
add_input_file(file);
process_files();
fclose(nonstdout);