sed: code shrink
function old new delta get_next_line 246 250 +4 sed_main 671 662 -9 add_input_file 47 - -47 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 1/1 up/down: 4/-56) Total: -52 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
259b3c047a
commit
deb0769b26
@ -23,9 +23,6 @@
|
|||||||
* resulting sed_cmd_t structures are appended to a linked list
|
* resulting sed_cmd_t structures are appended to a linked list
|
||||||
* (G.sed_cmd_head/G.sed_cmd_tail).
|
* (G.sed_cmd_head/G.sed_cmd_tail).
|
||||||
*
|
*
|
||||||
* add_input_file() adds a char* to the list of input files. We need to
|
|
||||||
* know all input sources ahead of time to find the last line for the $ match.
|
|
||||||
*
|
|
||||||
* process_files() does actual sedding, reading data lines from each input FILE*
|
* process_files() does actual sedding, reading data lines from each input FILE*
|
||||||
* (which could be stdin) and applying the sed command list (sed_cmd_head) to
|
* (which could be stdin) and applying the sed command list (sed_cmd_head) to
|
||||||
* each of the resulting lines.
|
* each of the resulting lines.
|
||||||
@ -141,8 +138,8 @@ struct globals {
|
|||||||
smallint exitcode;
|
smallint exitcode;
|
||||||
|
|
||||||
/* list of input files */
|
/* list of input files */
|
||||||
int input_file_count, current_input_file;
|
int current_input_file, last_input_file;
|
||||||
const char **input_file_list;
|
char **input_file_list;
|
||||||
FILE *current_fp;
|
FILE *current_fp;
|
||||||
|
|
||||||
regmatch_t regmatch[10];
|
regmatch_t regmatch[10];
|
||||||
@ -942,7 +939,7 @@ static char *get_next_line(char *gets_char, char *last_puts_char, char last_gets
|
|||||||
/* will be returned if last line in the file
|
/* will be returned if last line in the file
|
||||||
* doesn't end with either '\n' or '\0' */
|
* doesn't end with either '\n' or '\0' */
|
||||||
gc = NO_EOL_CHAR;
|
gc = NO_EOL_CHAR;
|
||||||
for (; G.input_file_list[G.current_input_file]; G.current_input_file++) {
|
for (; G.current_input_file <= G.last_input_file; G.current_input_file++) {
|
||||||
FILE *fp = G.current_fp;
|
FILE *fp = G.current_fp;
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
const char *path = G.input_file_list[G.current_input_file];
|
const char *path = G.input_file_list[G.current_input_file];
|
||||||
@ -1414,12 +1411,6 @@ static void add_cmd_block(char *cmdstr)
|
|||||||
free(sv);
|
free(sv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_input_file(const char *file)
|
|
||||||
{
|
|
||||||
G.input_file_list = xrealloc_vector(G.input_file_list, 2, G.input_file_count);
|
|
||||||
G.input_file_list[G.input_file_count++] = file;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sed_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
int sed_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||||
int sed_main(int argc UNUSED_PARAM, char **argv)
|
int sed_main(int argc UNUSED_PARAM, char **argv)
|
||||||
{
|
{
|
||||||
@ -1501,36 +1492,38 @@ int sed_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
/* argv[0..(argc-1)] should be names of file to process. If no
|
/* argv[0..(argc-1)] should be names of file to process. If no
|
||||||
* files were specified or '-' was specified, take input from stdin.
|
* files were specified or '-' was specified, take input from stdin.
|
||||||
* Otherwise, we process all the files specified. */
|
* Otherwise, we process all the files specified. */
|
||||||
if (argv[0] == NULL) {
|
G.input_file_list = argv;
|
||||||
|
if (!argv[0]) {
|
||||||
if (opt & OPT_in_place)
|
if (opt & OPT_in_place)
|
||||||
bb_error_msg_and_die(bb_msg_requires_arg, "-i");
|
bb_error_msg_and_die(bb_msg_requires_arg, "-i");
|
||||||
add_input_file(bb_msg_standard_input);
|
argv[0] = (char*)bb_msg_standard_input;
|
||||||
|
/* G.last_input_file = 0; - already is */
|
||||||
} else {
|
} else {
|
||||||
int i;
|
goto start;
|
||||||
|
|
||||||
for (i = 0; argv[i]; i++) {
|
for (; *argv; argv++) {
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
int nonstdoutfd;
|
int nonstdoutfd;
|
||||||
sed_cmd_t *sed_cmd;
|
sed_cmd_t *sed_cmd;
|
||||||
|
|
||||||
if (LONE_DASH(argv[i]) && !(opt & OPT_in_place)) {
|
G.last_input_file++;
|
||||||
add_input_file(bb_msg_standard_input);
|
start:
|
||||||
process_files();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
add_input_file(argv[i]);
|
|
||||||
if (!(opt & OPT_in_place)) {
|
if (!(opt & OPT_in_place)) {
|
||||||
|
if (LONE_DASH(*argv)) {
|
||||||
|
*argv = (char*)bb_msg_standard_input;
|
||||||
|
process_files();
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -i: process each FILE separately: */
|
/* -i: process each FILE separately: */
|
||||||
|
|
||||||
G.outname = xasprintf("%sXXXXXX", argv[i]);
|
G.outname = xasprintf("%sXXXXXX", *argv);
|
||||||
nonstdoutfd = xmkstemp(G.outname);
|
nonstdoutfd = xmkstemp(G.outname);
|
||||||
G.nonstdout = xfdopen_for_write(nonstdoutfd);
|
G.nonstdout = xfdopen_for_write(nonstdoutfd);
|
||||||
|
|
||||||
/* Set permissions/owner of output file */
|
/* Set permissions/owner of output file */
|
||||||
stat(argv[i], &statbuf);
|
stat(*argv, &statbuf);
|
||||||
/* chmod'ing AFTER chown would preserve suid/sgid bits,
|
/* chmod'ing AFTER chown would preserve suid/sgid bits,
|
||||||
* but GNU sed 4.2.1 does not preserve them either */
|
* but GNU sed 4.2.1 does not preserve them either */
|
||||||
fchmod(nonstdoutfd, statbuf.st_mode);
|
fchmod(nonstdoutfd, statbuf.st_mode);
|
||||||
@ -1541,12 +1534,12 @@ int sed_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
G.nonstdout = stdout;
|
G.nonstdout = stdout;
|
||||||
|
|
||||||
if (opt_i) {
|
if (opt_i) {
|
||||||
char *backupname = xasprintf("%s%s", argv[i], opt_i);
|
char *backupname = xasprintf("%s%s", *argv, opt_i);
|
||||||
xrename(argv[i], backupname);
|
xrename(*argv, backupname);
|
||||||
free(backupname);
|
free(backupname);
|
||||||
}
|
}
|
||||||
/* else unlink(argv[i]); - rename below does this */
|
/* else unlink(*argv); - rename below does this */
|
||||||
xrename(G.outname, argv[i]); //TODO: rollback backup on error?
|
xrename(G.outname, *argv); //TODO: rollback backup on error?
|
||||||
free(G.outname);
|
free(G.outname);
|
||||||
G.outname = NULL;
|
G.outname = NULL;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user