busybox/editors/ed.c

1017 lines
19 KiB
C
Raw Normal View History

/* vi: set sw=4 ts=4: */
/*
* Copyright (c) 2002 by David I. Bell
* Permission is granted to use, distribute, or modify this source,
* provided that this copyright notice remains intact.
*
* The "ed" built-in command (much simplified)
*/
//config:config ED
//config: bool "ed (21 kb)"
//config: default y
//config: help
//config: The original 1970's Unix text editor, from the days of teletypes.
//config: Small, simple, evil. Part of SUSv3. If you're not already using
//config: this, you don't need it.
//kbuild:lib-$(CONFIG_ED) += ed.o
//applet:IF_ED(APPLET(ed, BB_DIR_BIN, BB_SUID_DROP))
//usage:#define ed_trivial_usage "[FILE]"
//usage:#define ed_full_usage ""
#include "libbb.h"
#include "common_bufsiz.h"
typedef struct LINE {
struct LINE *next;
struct LINE *prev;
int len;
char data[1];
} LINE;
#define searchString bb_common_bufsiz1
enum {
USERSIZE = COMMON_BUFSIZE > 1024 ? 1024
: COMMON_BUFSIZE - 1, /* max line length typed in by user */
INITBUF_SIZE = 1024, /* initial buffer size */
};
struct globals {
int curNum;
int lastNum;
int bufUsed;
int bufSize;
LINE *curLine;
char *bufBase;
char *bufPtr;
char *fileName;
LINE lines;
smallint dirty;
int marks[26];
};
#define G (*ptr_to_globals)
#define curLine (G.curLine )
#define bufBase (G.bufBase )
#define bufPtr (G.bufPtr )
#define fileName (G.fileName )
#define curNum (G.curNum )
#define lastNum (G.lastNum )
#define bufUsed (G.bufUsed )
#define bufSize (G.bufSize )
#define dirty (G.dirty )
#define lines (G.lines )
#define marks (G.marks )
#define INIT_G() do { \
setup_common_bufsiz(); \
SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
} while (0)
static int bad_nums(int num1, int num2, const char *for_what)
{
if ((num1 < 1) || (num2 > lastNum) || (num1 > num2)) {
bb_error_msg("bad line range for %s", for_what);
return 1;
}
return 0;
}
/*
* Return a pointer to the specified line number.
*/
static LINE *findLine(int num)
{
LINE *lp;
int lnum;
if ((num < 1) || (num > lastNum)) {
bb_error_msg("line number %d does not exist", num);
return NULL;
}
if (curNum <= 0) {
curNum = 1;
curLine = lines.next;
}
if (num == curNum)
return curLine;
lp = curLine;
lnum = curNum;
if (num < (curNum / 2)) {
lp = lines.next;
lnum = 1;
} else if (num > ((curNum + lastNum) / 2)) {
lp = lines.prev;
lnum = lastNum;
}
while (lnum < num) {
lp = lp->next;
lnum++;
}
while (lnum > num) {
lp = lp->prev;
lnum--;
}
return lp;
}
/*
* Search a line for the specified string starting at the specified
* offset in the line. Returns the offset of the found string, or -1.
*/
static int findString(const LINE *lp, const char *str, int len, int offset)
{
int left;
const char *cp, *ncp;
cp = &lp->data[offset];
left = lp->len - offset - len;
while (left >= 0) {
ncp = memchr(cp, str[0], left + 1);
if (ncp == NULL)
return -1;
left -= (ncp - cp);
cp = ncp;
if (memcmp(cp, str, len) == 0)
return (cp - lp->data);
cp++;
left--;
}
return -1;
}
/*
* Search for a line which contains the specified string.
* If the string is "", then the previously searched for string
* is used. The currently searched for string is saved for future use.
* Returns the line number which matches, or 0 if there was no match
* with an error printed.
*/
static NOINLINE int searchLines(const char *str, int num1, int num2)
{
const LINE *lp;
int len;
if (bad_nums(num1, num2, "search"))
return 0;
if (*str == '\0') {
if (searchString[0] == '\0') {
libbb: reduce the overhead of single parameter bb_error_msg() calls Back in 2007, commit 0c97c9d43707 ("'simple' error message functions by Loic Grenie") introduced bb_simple_perror_msg() to allow for a lower overhead call to bb_perror_msg() when only a string was being printed with no parameters. This saves space for some CPU architectures because it avoids the overhead of a call to a variadic function. However there has never been a simple version of bb_error_msg(), and since 2007 many new calls to bb_perror_msg() have been added that only take a single parameter and so could have been using bb_simple_perror_message(). This changeset introduces 'simple' versions of bb_info_msg(), bb_error_msg(), bb_error_msg_and_die(), bb_herror_msg() and bb_herror_msg_and_die(), and replaces all calls that only take a single parameter, or use something like ("%s", arg), with calls to the corresponding 'simple' version. Since it is likely that single parameter calls to the variadic functions may be accidentally reintroduced in the future a new debugging config option WARN_SIMPLE_MSG has been introduced. This uses some macro magic which will cause any such calls to generate a warning, but this is turned off by default to avoid use of the unpleasant macros in normal circumstances. This is a large changeset due to the number of calls that have been replaced. The only files that contain changes other than simple substitution of function calls are libbb.h, libbb/herror_msg.c, libbb/verror_msg.c and libbb/xfuncs_printf.c. In miscutils/devfsd.c, networking/udhcp/common.h and util-linux/mdev.c additonal macros have been added for logging so that single parameter and multiple parameter logging variants exist. The amount of space saved varies considerably by architecture, and was found to be as follows (for 'defconfig' using GCC 7.4): Arm: -92 bytes MIPS: -52 bytes PPC: -1836 bytes x86_64: -938 bytes Note that for the MIPS architecture only an exception had to be made disabling the 'simple' calls for 'udhcp' (in networking/udhcp/common.h) because it made these files larger on MIPS. Signed-off-by: James Byrne <james.byrne@origamienergy.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-07-02 17:35:03 +08:00
bb_simple_error_msg("no previous search string");
return 0;
}
str = searchString;
}
if (str != searchString)
strcpy(searchString, str);
2008-03-28 10:24:59 +08:00
len = strlen(str);
2008-03-28 10:24:59 +08:00
lp = findLine(num1);
if (lp == NULL)
return 0;
2008-03-28 10:24:59 +08:00
while (num1 <= num2) {
if (findString(lp, str, len, 0) >= 0)
return num1;
num1++;
lp = lp->next;
}
2008-03-28 10:24:59 +08:00
bb_error_msg("can't find string \"%s\"", str);
return 0;
}
2008-03-28 10:24:59 +08:00
/*
* Parse a line number argument if it is present. This is a sum
* or difference of numbers, ".", "$", "'c", or a search string.
* Returns pointer which stopped the scan if successful
* (whether or not there was a number).
* Returns NULL if there was a parsing error, with a message output.
* Whether there was a number is returned indirectly, as is the number.
*/
static const char* getNum(const char *cp, smallint *retHaveNum, int *retNum)
{
char *endStr, str[USERSIZE];
int value, num;
smallint haveNum, minus;
2008-03-28 10:24:59 +08:00
value = 0;
haveNum = FALSE;
minus = 0;
2008-03-28 10:24:59 +08:00
while (TRUE) {
cp = skip_whitespace(cp);
2008-03-28 10:24:59 +08:00
switch (*cp) {
case '.':
haveNum = TRUE;
num = curNum;
cp++;
break;
2008-03-28 10:24:59 +08:00
case '$':
haveNum = TRUE;
num = lastNum;
cp++;
break;
case '\'':
cp++;
if ((unsigned)(*cp - 'a') >= 26) {
libbb: reduce the overhead of single parameter bb_error_msg() calls Back in 2007, commit 0c97c9d43707 ("'simple' error message functions by Loic Grenie") introduced bb_simple_perror_msg() to allow for a lower overhead call to bb_perror_msg() when only a string was being printed with no parameters. This saves space for some CPU architectures because it avoids the overhead of a call to a variadic function. However there has never been a simple version of bb_error_msg(), and since 2007 many new calls to bb_perror_msg() have been added that only take a single parameter and so could have been using bb_simple_perror_message(). This changeset introduces 'simple' versions of bb_info_msg(), bb_error_msg(), bb_error_msg_and_die(), bb_herror_msg() and bb_herror_msg_and_die(), and replaces all calls that only take a single parameter, or use something like ("%s", arg), with calls to the corresponding 'simple' version. Since it is likely that single parameter calls to the variadic functions may be accidentally reintroduced in the future a new debugging config option WARN_SIMPLE_MSG has been introduced. This uses some macro magic which will cause any such calls to generate a warning, but this is turned off by default to avoid use of the unpleasant macros in normal circumstances. This is a large changeset due to the number of calls that have been replaced. The only files that contain changes other than simple substitution of function calls are libbb.h, libbb/herror_msg.c, libbb/verror_msg.c and libbb/xfuncs_printf.c. In miscutils/devfsd.c, networking/udhcp/common.h and util-linux/mdev.c additonal macros have been added for logging so that single parameter and multiple parameter logging variants exist. The amount of space saved varies considerably by architecture, and was found to be as follows (for 'defconfig' using GCC 7.4): Arm: -92 bytes MIPS: -52 bytes PPC: -1836 bytes x86_64: -938 bytes Note that for the MIPS architecture only an exception had to be made disabling the 'simple' calls for 'udhcp' (in networking/udhcp/common.h) because it made these files larger on MIPS. Signed-off-by: James Byrne <james.byrne@origamienergy.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-07-02 17:35:03 +08:00
bb_simple_error_msg("bad mark name");
return NULL;
}
haveNum = TRUE;
num = marks[(unsigned)(*cp - 'a')];
cp++;
break;
case '/':
strcpy(str, ++cp);
endStr = strchr(str, '/');
if (endStr) {
*endStr++ = '\0';
cp += (endStr - str);
} else
cp = "";
num = searchLines(str, curNum, lastNum);
if (num == 0)
return NULL;
haveNum = TRUE;
break;
2008-03-28 10:24:59 +08:00
default:
if (!isdigit(*cp)) {
*retHaveNum = haveNum;
*retNum = value;
return cp;
}
num = 0;
while (isdigit(*cp))
num = num * 10 + *cp++ - '0';
haveNum = TRUE;
break;
}
value += (minus ? -num : num);
cp = skip_whitespace(cp);
2008-03-28 10:24:59 +08:00
switch (*cp) {
case '-':
minus = 1;
cp++;
break;
2008-03-28 10:24:59 +08:00
case '+':
minus = 0;
cp++;
break;
default:
*retHaveNum = haveNum;
*retNum = value;
return cp;
}
}
}
/*
* Set the current line number.
* Returns TRUE if successful.
*/
static int setCurNum(int num)
{
LINE *lp;
lp = findLine(num);
if (lp == NULL)
return FALSE;
curNum = num;
curLine = lp;
return TRUE;
}
/*
* Insert a new line with the specified text.
* The line is inserted so as to become the specified line,
* thus pushing any existing and further lines down one.
* The inserted line is also set to become the current line.
* Returns TRUE if successful.
*/
static int insertLine(int num, const char *data, int len)
{
LINE *newLp, *lp;
if ((num < 1) || (num > lastNum + 1)) {
libbb: reduce the overhead of single parameter bb_error_msg() calls Back in 2007, commit 0c97c9d43707 ("'simple' error message functions by Loic Grenie") introduced bb_simple_perror_msg() to allow for a lower overhead call to bb_perror_msg() when only a string was being printed with no parameters. This saves space for some CPU architectures because it avoids the overhead of a call to a variadic function. However there has never been a simple version of bb_error_msg(), and since 2007 many new calls to bb_perror_msg() have been added that only take a single parameter and so could have been using bb_simple_perror_message(). This changeset introduces 'simple' versions of bb_info_msg(), bb_error_msg(), bb_error_msg_and_die(), bb_herror_msg() and bb_herror_msg_and_die(), and replaces all calls that only take a single parameter, or use something like ("%s", arg), with calls to the corresponding 'simple' version. Since it is likely that single parameter calls to the variadic functions may be accidentally reintroduced in the future a new debugging config option WARN_SIMPLE_MSG has been introduced. This uses some macro magic which will cause any such calls to generate a warning, but this is turned off by default to avoid use of the unpleasant macros in normal circumstances. This is a large changeset due to the number of calls that have been replaced. The only files that contain changes other than simple substitution of function calls are libbb.h, libbb/herror_msg.c, libbb/verror_msg.c and libbb/xfuncs_printf.c. In miscutils/devfsd.c, networking/udhcp/common.h and util-linux/mdev.c additonal macros have been added for logging so that single parameter and multiple parameter logging variants exist. The amount of space saved varies considerably by architecture, and was found to be as follows (for 'defconfig' using GCC 7.4): Arm: -92 bytes MIPS: -52 bytes PPC: -1836 bytes x86_64: -938 bytes Note that for the MIPS architecture only an exception had to be made disabling the 'simple' calls for 'udhcp' (in networking/udhcp/common.h) because it made these files larger on MIPS. Signed-off-by: James Byrne <james.byrne@origamienergy.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-07-02 17:35:03 +08:00
bb_simple_error_msg("inserting at bad line number");
return FALSE;
}
newLp = xmalloc(sizeof(LINE) + len - 1);
memcpy(newLp->data, data, len);
newLp->len = len;
if (num > lastNum)
lp = &lines;
else {
lp = findLine(num);
if (lp == NULL) {
free((char *) newLp);
return FALSE;
}
}
newLp->next = lp;
newLp->prev = lp->prev;
lp->prev->next = newLp;
lp->prev = newLp;
lastNum++;
dirty = TRUE;
return setCurNum(num);
}
/*
* Add lines which are typed in by the user.
* The lines are inserted just before the specified line number.
* The lines are terminated by a line containing a single dot (ugly!),
* or by an end of file.
*/
static void addLines(int num)
{
int len;
char buf[USERSIZE + 1];
while (1) {
/* Returns:
* -1 on read errors or EOF, or on bare Ctrl-D.
* 0 on ctrl-C,
* >0 length of input string, including terminating '\n'
*/
len = read_line_input(NULL, "", buf, sizeof(buf));
if (len <= 0) {
/* Previously, ctrl-C was exiting to shell.
* Now we exit to ed prompt. Is in important? */
return;
}
if (buf[0] == '.' && buf[1] == '\n' && buf[2] == '\0')
return;
if (!insertLine(num++, buf, len))
return;
}
}
/*
* Read lines from a file at the specified line number.
* Returns TRUE if the file was successfully read.
*/
static int readLines(const char *file, int num)
{
int fd, cc;
int len, lineCount, charCount;
char *cp;
if ((num < 1) || (num > lastNum + 1)) {
libbb: reduce the overhead of single parameter bb_error_msg() calls Back in 2007, commit 0c97c9d43707 ("'simple' error message functions by Loic Grenie") introduced bb_simple_perror_msg() to allow for a lower overhead call to bb_perror_msg() when only a string was being printed with no parameters. This saves space for some CPU architectures because it avoids the overhead of a call to a variadic function. However there has never been a simple version of bb_error_msg(), and since 2007 many new calls to bb_perror_msg() have been added that only take a single parameter and so could have been using bb_simple_perror_message(). This changeset introduces 'simple' versions of bb_info_msg(), bb_error_msg(), bb_error_msg_and_die(), bb_herror_msg() and bb_herror_msg_and_die(), and replaces all calls that only take a single parameter, or use something like ("%s", arg), with calls to the corresponding 'simple' version. Since it is likely that single parameter calls to the variadic functions may be accidentally reintroduced in the future a new debugging config option WARN_SIMPLE_MSG has been introduced. This uses some macro magic which will cause any such calls to generate a warning, but this is turned off by default to avoid use of the unpleasant macros in normal circumstances. This is a large changeset due to the number of calls that have been replaced. The only files that contain changes other than simple substitution of function calls are libbb.h, libbb/herror_msg.c, libbb/verror_msg.c and libbb/xfuncs_printf.c. In miscutils/devfsd.c, networking/udhcp/common.h and util-linux/mdev.c additonal macros have been added for logging so that single parameter and multiple parameter logging variants exist. The amount of space saved varies considerably by architecture, and was found to be as follows (for 'defconfig' using GCC 7.4): Arm: -92 bytes MIPS: -52 bytes PPC: -1836 bytes x86_64: -938 bytes Note that for the MIPS architecture only an exception had to be made disabling the 'simple' calls for 'udhcp' (in networking/udhcp/common.h) because it made these files larger on MIPS. Signed-off-by: James Byrne <james.byrne@origamienergy.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-07-02 17:35:03 +08:00
bb_simple_error_msg("bad line for read");
return FALSE;
}
fd = open(file, 0);
if (fd < 0) {
bb_simple_perror_msg(file);
return FALSE;
}
bufPtr = bufBase;
bufUsed = 0;
lineCount = 0;
charCount = 0;
cc = 0;
printf("\"%s\", ", file);
fflush_all();
do {
cp = memchr(bufPtr, '\n', bufUsed);
if (cp) {
len = (cp - bufPtr) + 1;
if (!insertLine(num, bufPtr, len)) {
close(fd);
return FALSE;
}
bufPtr += len;
bufUsed -= len;
charCount += len;
lineCount++;
num++;
continue;
}
if (bufPtr != bufBase) {
memcpy(bufBase, bufPtr, bufUsed);
bufPtr = bufBase + bufUsed;
}
if (bufUsed >= bufSize) {
len = (bufSize * 3) / 2;
cp = xrealloc(bufBase, len);
bufBase = cp;
bufPtr = bufBase + bufUsed;
bufSize = len;
}
cc = safe_read(fd, bufPtr, bufSize - bufUsed);
bufUsed += cc;
bufPtr = bufBase;
} while (cc > 0);
if (cc < 0) {
bb_simple_perror_msg(file);
close(fd);
return FALSE;
}
if (bufUsed) {
if (!insertLine(num, bufPtr, bufUsed)) {
close(fd);
return -1;
}
lineCount++;
charCount += bufUsed;
}
close(fd);
printf("%d lines%s, %d chars\n", lineCount,
(bufUsed ? " (incomplete)" : ""), charCount);
return TRUE;
}
/*
* Write the specified lines out to the specified file.
* Returns TRUE if successful, or FALSE on an error with a message output.
*/
static int writeLines(const char *file, int num1, int num2)
{
LINE *lp;
int fd, lineCount, charCount;
if (bad_nums(num1, num2, "write"))
return FALSE;
lineCount = 0;
charCount = 0;
fd = creat(file, 0666);
if (fd < 0) {
bb_simple_perror_msg(file);
return FALSE;
}
printf("\"%s\", ", file);
fflush_all();
lp = findLine(num1);
if (lp == NULL) {
close(fd);
return FALSE;
}
while (num1++ <= num2) {
if (full_write(fd, lp->data, lp->len) != lp->len) {
bb_simple_perror_msg(file);
close(fd);
return FALSE;
}
charCount += lp->len;
lineCount++;
lp = lp->next;
}
if (close(fd) < 0) {
bb_simple_perror_msg(file);
return FALSE;
}
printf("%d lines, %d chars\n", lineCount, charCount);
return TRUE;
}
/*
* Print lines in a specified range.
* The last line printed becomes the current line.
* If expandFlag is TRUE, then the line is printed specially to
* show magic characters.
*/
static int printLines(int num1, int num2, int expandFlag)
{
const LINE *lp;
const char *cp;
int ch, count;
if (bad_nums(num1, num2, "print"))
return FALSE;
lp = findLine(num1);
if (lp == NULL)
return FALSE;
while (num1 <= num2) {
if (!expandFlag) {
write(STDOUT_FILENO, lp->data, lp->len);
setCurNum(num1++);
lp = lp->next;
continue;
}
/*
* Show control characters and characters with the
* high bit set specially.
*/
cp = lp->data;
count = lp->len;
if ((count > 0) && (cp[count - 1] == '\n'))
count--;
while (count-- > 0) {
ch = (unsigned char) *cp++;
fputc_printable(ch | PRINTABLE_META, stdout);
}
fputs("$\n", stdout);
setCurNum(num1++);
lp = lp->next;
}
return TRUE;
}
/*
* Delete lines from the given range.
*/
static void deleteLines(int num1, int num2)
{
LINE *lp, *nlp, *plp;
int count;
if (bad_nums(num1, num2, "delete"))
return;
lp = findLine(num1);
if (lp == NULL)
return;
if ((curNum >= num1) && (curNum <= num2)) {
if (num2 < lastNum)
setCurNum(num2 + 1);
else if (num1 > 1)
setCurNum(num1 - 1);
else
curNum = 0;
}
count = num2 - num1 + 1;
if (curNum > num2)
curNum -= count;
lastNum -= count;
while (count-- > 0) {
nlp = lp->next;
plp = lp->prev;
plp->next = nlp;
nlp->prev = plp;
free(lp);
lp = nlp;
}
dirty = TRUE;
}
/*
* Do the substitute command.
* The current line is set to the last substitution done.
*/
static void subCommand(const char *cmd, int num1, int num2)
{
char *cp, *oldStr, *newStr, buf[USERSIZE];
int delim, oldLen, newLen, deltaLen, offset;
LINE *lp, *nlp;
int globalFlag, printFlag, didSub, needPrint;
if (bad_nums(num1, num2, "substitute"))
return;
globalFlag = FALSE;
printFlag = FALSE;
didSub = FALSE;
needPrint = FALSE;
/*
* Copy the command so we can modify it.
*/
strcpy(buf, cmd);
cp = buf;
if (isblank(*cp) || (*cp == '\0')) {
libbb: reduce the overhead of single parameter bb_error_msg() calls Back in 2007, commit 0c97c9d43707 ("'simple' error message functions by Loic Grenie") introduced bb_simple_perror_msg() to allow for a lower overhead call to bb_perror_msg() when only a string was being printed with no parameters. This saves space for some CPU architectures because it avoids the overhead of a call to a variadic function. However there has never been a simple version of bb_error_msg(), and since 2007 many new calls to bb_perror_msg() have been added that only take a single parameter and so could have been using bb_simple_perror_message(). This changeset introduces 'simple' versions of bb_info_msg(), bb_error_msg(), bb_error_msg_and_die(), bb_herror_msg() and bb_herror_msg_and_die(), and replaces all calls that only take a single parameter, or use something like ("%s", arg), with calls to the corresponding 'simple' version. Since it is likely that single parameter calls to the variadic functions may be accidentally reintroduced in the future a new debugging config option WARN_SIMPLE_MSG has been introduced. This uses some macro magic which will cause any such calls to generate a warning, but this is turned off by default to avoid use of the unpleasant macros in normal circumstances. This is a large changeset due to the number of calls that have been replaced. The only files that contain changes other than simple substitution of function calls are libbb.h, libbb/herror_msg.c, libbb/verror_msg.c and libbb/xfuncs_printf.c. In miscutils/devfsd.c, networking/udhcp/common.h and util-linux/mdev.c additonal macros have been added for logging so that single parameter and multiple parameter logging variants exist. The amount of space saved varies considerably by architecture, and was found to be as follows (for 'defconfig' using GCC 7.4): Arm: -92 bytes MIPS: -52 bytes PPC: -1836 bytes x86_64: -938 bytes Note that for the MIPS architecture only an exception had to be made disabling the 'simple' calls for 'udhcp' (in networking/udhcp/common.h) because it made these files larger on MIPS. Signed-off-by: James Byrne <james.byrne@origamienergy.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-07-02 17:35:03 +08:00
bb_simple_error_msg("bad delimiter for substitute");
return;
}
delim = *cp++;
oldStr = cp;
cp = strchr(cp, delim);
if (cp == NULL) {
libbb: reduce the overhead of single parameter bb_error_msg() calls Back in 2007, commit 0c97c9d43707 ("'simple' error message functions by Loic Grenie") introduced bb_simple_perror_msg() to allow for a lower overhead call to bb_perror_msg() when only a string was being printed with no parameters. This saves space for some CPU architectures because it avoids the overhead of a call to a variadic function. However there has never been a simple version of bb_error_msg(), and since 2007 many new calls to bb_perror_msg() have been added that only take a single parameter and so could have been using bb_simple_perror_message(). This changeset introduces 'simple' versions of bb_info_msg(), bb_error_msg(), bb_error_msg_and_die(), bb_herror_msg() and bb_herror_msg_and_die(), and replaces all calls that only take a single parameter, or use something like ("%s", arg), with calls to the corresponding 'simple' version. Since it is likely that single parameter calls to the variadic functions may be accidentally reintroduced in the future a new debugging config option WARN_SIMPLE_MSG has been introduced. This uses some macro magic which will cause any such calls to generate a warning, but this is turned off by default to avoid use of the unpleasant macros in normal circumstances. This is a large changeset due to the number of calls that have been replaced. The only files that contain changes other than simple substitution of function calls are libbb.h, libbb/herror_msg.c, libbb/verror_msg.c and libbb/xfuncs_printf.c. In miscutils/devfsd.c, networking/udhcp/common.h and util-linux/mdev.c additonal macros have been added for logging so that single parameter and multiple parameter logging variants exist. The amount of space saved varies considerably by architecture, and was found to be as follows (for 'defconfig' using GCC 7.4): Arm: -92 bytes MIPS: -52 bytes PPC: -1836 bytes x86_64: -938 bytes Note that for the MIPS architecture only an exception had to be made disabling the 'simple' calls for 'udhcp' (in networking/udhcp/common.h) because it made these files larger on MIPS. Signed-off-by: James Byrne <james.byrne@origamienergy.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-07-02 17:35:03 +08:00
bb_simple_error_msg("missing 2nd delimiter for substitute");
return;
}
*cp++ = '\0';
newStr = cp;
cp = strchr(cp, delim);
if (cp)
*cp++ = '\0';
else
cp = (char*)"";
while (*cp) switch (*cp++) {
case 'g':
globalFlag = TRUE;
break;
case 'p':
printFlag = TRUE;
break;
default:
libbb: reduce the overhead of single parameter bb_error_msg() calls Back in 2007, commit 0c97c9d43707 ("'simple' error message functions by Loic Grenie") introduced bb_simple_perror_msg() to allow for a lower overhead call to bb_perror_msg() when only a string was being printed with no parameters. This saves space for some CPU architectures because it avoids the overhead of a call to a variadic function. However there has never been a simple version of bb_error_msg(), and since 2007 many new calls to bb_perror_msg() have been added that only take a single parameter and so could have been using bb_simple_perror_message(). This changeset introduces 'simple' versions of bb_info_msg(), bb_error_msg(), bb_error_msg_and_die(), bb_herror_msg() and bb_herror_msg_and_die(), and replaces all calls that only take a single parameter, or use something like ("%s", arg), with calls to the corresponding 'simple' version. Since it is likely that single parameter calls to the variadic functions may be accidentally reintroduced in the future a new debugging config option WARN_SIMPLE_MSG has been introduced. This uses some macro magic which will cause any such calls to generate a warning, but this is turned off by default to avoid use of the unpleasant macros in normal circumstances. This is a large changeset due to the number of calls that have been replaced. The only files that contain changes other than simple substitution of function calls are libbb.h, libbb/herror_msg.c, libbb/verror_msg.c and libbb/xfuncs_printf.c. In miscutils/devfsd.c, networking/udhcp/common.h and util-linux/mdev.c additonal macros have been added for logging so that single parameter and multiple parameter logging variants exist. The amount of space saved varies considerably by architecture, and was found to be as follows (for 'defconfig' using GCC 7.4): Arm: -92 bytes MIPS: -52 bytes PPC: -1836 bytes x86_64: -938 bytes Note that for the MIPS architecture only an exception had to be made disabling the 'simple' calls for 'udhcp' (in networking/udhcp/common.h) because it made these files larger on MIPS. Signed-off-by: James Byrne <james.byrne@origamienergy.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-07-02 17:35:03 +08:00
bb_simple_error_msg("unknown option for substitute");
return;
}
if (*oldStr == '\0') {
if (searchString[0] == '\0') {
libbb: reduce the overhead of single parameter bb_error_msg() calls Back in 2007, commit 0c97c9d43707 ("'simple' error message functions by Loic Grenie") introduced bb_simple_perror_msg() to allow for a lower overhead call to bb_perror_msg() when only a string was being printed with no parameters. This saves space for some CPU architectures because it avoids the overhead of a call to a variadic function. However there has never been a simple version of bb_error_msg(), and since 2007 many new calls to bb_perror_msg() have been added that only take a single parameter and so could have been using bb_simple_perror_message(). This changeset introduces 'simple' versions of bb_info_msg(), bb_error_msg(), bb_error_msg_and_die(), bb_herror_msg() and bb_herror_msg_and_die(), and replaces all calls that only take a single parameter, or use something like ("%s", arg), with calls to the corresponding 'simple' version. Since it is likely that single parameter calls to the variadic functions may be accidentally reintroduced in the future a new debugging config option WARN_SIMPLE_MSG has been introduced. This uses some macro magic which will cause any such calls to generate a warning, but this is turned off by default to avoid use of the unpleasant macros in normal circumstances. This is a large changeset due to the number of calls that have been replaced. The only files that contain changes other than simple substitution of function calls are libbb.h, libbb/herror_msg.c, libbb/verror_msg.c and libbb/xfuncs_printf.c. In miscutils/devfsd.c, networking/udhcp/common.h and util-linux/mdev.c additonal macros have been added for logging so that single parameter and multiple parameter logging variants exist. The amount of space saved varies considerably by architecture, and was found to be as follows (for 'defconfig' using GCC 7.4): Arm: -92 bytes MIPS: -52 bytes PPC: -1836 bytes x86_64: -938 bytes Note that for the MIPS architecture only an exception had to be made disabling the 'simple' calls for 'udhcp' (in networking/udhcp/common.h) because it made these files larger on MIPS. Signed-off-by: James Byrne <james.byrne@origamienergy.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-07-02 17:35:03 +08:00
bb_simple_error_msg("no previous search string");
return;
}
oldStr = searchString;
}
if (oldStr != searchString)
strcpy(searchString, oldStr);
lp = findLine(num1);
if (lp == NULL)
return;
oldLen = strlen(oldStr);
newLen = strlen(newStr);
deltaLen = newLen - oldLen;
offset = 0;
nlp = NULL;
while (num1 <= num2) {
offset = findString(lp, oldStr, oldLen, offset);
if (offset < 0) {
if (needPrint) {
printLines(num1, num1, FALSE);
needPrint = FALSE;
}
offset = 0;
lp = lp->next;
num1++;
continue;
}
needPrint = printFlag;
didSub = TRUE;
dirty = TRUE;
/*
* If the replacement string is the same size or shorter
* than the old string, then the substitution is easy.
*/
if (deltaLen <= 0) {
memcpy(&lp->data[offset], newStr, newLen);
if (deltaLen) {
memcpy(&lp->data[offset + newLen],
&lp->data[offset + oldLen],
lp->len - offset - oldLen);
lp->len += deltaLen;
}
offset += newLen;
if (globalFlag)
continue;
if (needPrint) {
printLines(num1, num1, FALSE);
needPrint = FALSE;
}
lp = lp->next;
num1++;
continue;
}
/*
* The new string is larger, so allocate a new line
* structure and use that. Link it in place of
* the old line structure.
*/
nlp = xmalloc(sizeof(LINE) + lp->len + deltaLen);
nlp->len = lp->len + deltaLen;
memcpy(nlp->data, lp->data, offset);
memcpy(&nlp->data[offset], newStr, newLen);
memcpy(&nlp->data[offset + newLen],
&lp->data[offset + oldLen],
lp->len - offset - oldLen);
nlp->next = lp->next;
nlp->prev = lp->prev;
nlp->prev->next = nlp;
nlp->next->prev = nlp;
if (curLine == lp)
curLine = nlp;
free(lp);
lp = nlp;
offset += newLen;
if (globalFlag)
continue;
if (needPrint) {
printLines(num1, num1, FALSE);
needPrint = FALSE;
}
lp = lp->next;
num1++;
}
if (!didSub)
bb_error_msg("no substitutions found for \"%s\"", oldStr);
}
/*
* Read commands until we are told to stop.
*/
static void doCommands(void)
{
while (TRUE) {
char buf[USERSIZE];
const char *cp;
int len;
int n, num1, num2;
smallint h, have1, have2;
/* Returns:
* -1 on read errors or EOF, or on bare Ctrl-D.
* 0 on ctrl-C,
* >0 length of input string, including terminating '\n'
*/
len = read_line_input(NULL, ": ", buf, sizeof(buf));
if (len <= 0)
return;
while (len && isspace(buf[--len]))
buf[len] = '\0';
if ((curNum == 0) && (lastNum > 0)) {
curNum = 1;
curLine = lines.next;
}
have1 = FALSE;
have2 = FALSE;
/* Don't pass &haveN, &numN to getNum() since this forces
* compiler to keep them on stack, not in registers,
* which is usually quite suboptimal.
* Using intermediate variables shrinks code by ~150 bytes.
*/
cp = getNum(skip_whitespace(buf), &h, &n);
if (!cp)
continue;
have1 = h;
num1 = n;
cp = skip_whitespace(cp);
if (*cp == ',') {
cp = getNum(cp + 1, &h, &n);
if (!cp)
continue;
num2 = n;
if (!have1)
num1 = 1;
if (!h)
num2 = lastNum;
have1 = TRUE;
have2 = TRUE;
}
if (!have1)
num1 = curNum;
if (!have2)
num2 = num1;
switch (*cp++) {
case 'a':
addLines(num1 + 1);
break;
case 'c':
deleteLines(num1, num2);
addLines(num1);
break;
case 'd':
deleteLines(num1, num2);
break;
case 'f':
if (*cp != '\0' && *cp != ' ') {
libbb: reduce the overhead of single parameter bb_error_msg() calls Back in 2007, commit 0c97c9d43707 ("'simple' error message functions by Loic Grenie") introduced bb_simple_perror_msg() to allow for a lower overhead call to bb_perror_msg() when only a string was being printed with no parameters. This saves space for some CPU architectures because it avoids the overhead of a call to a variadic function. However there has never been a simple version of bb_error_msg(), and since 2007 many new calls to bb_perror_msg() have been added that only take a single parameter and so could have been using bb_simple_perror_message(). This changeset introduces 'simple' versions of bb_info_msg(), bb_error_msg(), bb_error_msg_and_die(), bb_herror_msg() and bb_herror_msg_and_die(), and replaces all calls that only take a single parameter, or use something like ("%s", arg), with calls to the corresponding 'simple' version. Since it is likely that single parameter calls to the variadic functions may be accidentally reintroduced in the future a new debugging config option WARN_SIMPLE_MSG has been introduced. This uses some macro magic which will cause any such calls to generate a warning, but this is turned off by default to avoid use of the unpleasant macros in normal circumstances. This is a large changeset due to the number of calls that have been replaced. The only files that contain changes other than simple substitution of function calls are libbb.h, libbb/herror_msg.c, libbb/verror_msg.c and libbb/xfuncs_printf.c. In miscutils/devfsd.c, networking/udhcp/common.h and util-linux/mdev.c additonal macros have been added for logging so that single parameter and multiple parameter logging variants exist. The amount of space saved varies considerably by architecture, and was found to be as follows (for 'defconfig' using GCC 7.4): Arm: -92 bytes MIPS: -52 bytes PPC: -1836 bytes x86_64: -938 bytes Note that for the MIPS architecture only an exception had to be made disabling the 'simple' calls for 'udhcp' (in networking/udhcp/common.h) because it made these files larger on MIPS. Signed-off-by: James Byrne <james.byrne@origamienergy.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-07-02 17:35:03 +08:00
bb_simple_error_msg("bad file command");
break;
}
cp = skip_whitespace(cp);
if (*cp == '\0') {
if (fileName)
printf("\"%s\"\n", fileName);
else
puts("No file name");
break;
}
free(fileName);
fileName = xstrdup(cp);
break;
case 'i':
if (!have1 && lastNum == 0)
num1 = 1;
addLines(num1);
break;
case 'k':
cp = skip_whitespace(cp);
if ((unsigned)(*cp - 'a') >= 26 || cp[1]) {
libbb: reduce the overhead of single parameter bb_error_msg() calls Back in 2007, commit 0c97c9d43707 ("'simple' error message functions by Loic Grenie") introduced bb_simple_perror_msg() to allow for a lower overhead call to bb_perror_msg() when only a string was being printed with no parameters. This saves space for some CPU architectures because it avoids the overhead of a call to a variadic function. However there has never been a simple version of bb_error_msg(), and since 2007 many new calls to bb_perror_msg() have been added that only take a single parameter and so could have been using bb_simple_perror_message(). This changeset introduces 'simple' versions of bb_info_msg(), bb_error_msg(), bb_error_msg_and_die(), bb_herror_msg() and bb_herror_msg_and_die(), and replaces all calls that only take a single parameter, or use something like ("%s", arg), with calls to the corresponding 'simple' version. Since it is likely that single parameter calls to the variadic functions may be accidentally reintroduced in the future a new debugging config option WARN_SIMPLE_MSG has been introduced. This uses some macro magic which will cause any such calls to generate a warning, but this is turned off by default to avoid use of the unpleasant macros in normal circumstances. This is a large changeset due to the number of calls that have been replaced. The only files that contain changes other than simple substitution of function calls are libbb.h, libbb/herror_msg.c, libbb/verror_msg.c and libbb/xfuncs_printf.c. In miscutils/devfsd.c, networking/udhcp/common.h and util-linux/mdev.c additonal macros have been added for logging so that single parameter and multiple parameter logging variants exist. The amount of space saved varies considerably by architecture, and was found to be as follows (for 'defconfig' using GCC 7.4): Arm: -92 bytes MIPS: -52 bytes PPC: -1836 bytes x86_64: -938 bytes Note that for the MIPS architecture only an exception had to be made disabling the 'simple' calls for 'udhcp' (in networking/udhcp/common.h) because it made these files larger on MIPS. Signed-off-by: James Byrne <james.byrne@origamienergy.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-07-02 17:35:03 +08:00
bb_simple_error_msg("bad mark name");
break;
}
marks[(unsigned)(*cp - 'a')] = num2;
break;
case 'l':
printLines(num1, num2, TRUE);
break;
case 'p':
printLines(num1, num2, FALSE);
break;
case 'q':
cp = skip_whitespace(cp);
if (have1 || *cp) {
libbb: reduce the overhead of single parameter bb_error_msg() calls Back in 2007, commit 0c97c9d43707 ("'simple' error message functions by Loic Grenie") introduced bb_simple_perror_msg() to allow for a lower overhead call to bb_perror_msg() when only a string was being printed with no parameters. This saves space for some CPU architectures because it avoids the overhead of a call to a variadic function. However there has never been a simple version of bb_error_msg(), and since 2007 many new calls to bb_perror_msg() have been added that only take a single parameter and so could have been using bb_simple_perror_message(). This changeset introduces 'simple' versions of bb_info_msg(), bb_error_msg(), bb_error_msg_and_die(), bb_herror_msg() and bb_herror_msg_and_die(), and replaces all calls that only take a single parameter, or use something like ("%s", arg), with calls to the corresponding 'simple' version. Since it is likely that single parameter calls to the variadic functions may be accidentally reintroduced in the future a new debugging config option WARN_SIMPLE_MSG has been introduced. This uses some macro magic which will cause any such calls to generate a warning, but this is turned off by default to avoid use of the unpleasant macros in normal circumstances. This is a large changeset due to the number of calls that have been replaced. The only files that contain changes other than simple substitution of function calls are libbb.h, libbb/herror_msg.c, libbb/verror_msg.c and libbb/xfuncs_printf.c. In miscutils/devfsd.c, networking/udhcp/common.h and util-linux/mdev.c additonal macros have been added for logging so that single parameter and multiple parameter logging variants exist. The amount of space saved varies considerably by architecture, and was found to be as follows (for 'defconfig' using GCC 7.4): Arm: -92 bytes MIPS: -52 bytes PPC: -1836 bytes x86_64: -938 bytes Note that for the MIPS architecture only an exception had to be made disabling the 'simple' calls for 'udhcp' (in networking/udhcp/common.h) because it made these files larger on MIPS. Signed-off-by: James Byrne <james.byrne@origamienergy.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-07-02 17:35:03 +08:00
bb_simple_error_msg("bad quit command");
break;
}
if (!dirty)
return;
len = read_line_input(NULL, "Really quit? ", buf, 16);
/* read error/EOF - no way to continue */
if (len < 0)
return;
cp = skip_whitespace(buf);
if ((*cp | 0x20) == 'y') /* Y or y */
return;
break;
case 'r':
if (*cp != '\0' && *cp != ' ') {
libbb: reduce the overhead of single parameter bb_error_msg() calls Back in 2007, commit 0c97c9d43707 ("'simple' error message functions by Loic Grenie") introduced bb_simple_perror_msg() to allow for a lower overhead call to bb_perror_msg() when only a string was being printed with no parameters. This saves space for some CPU architectures because it avoids the overhead of a call to a variadic function. However there has never been a simple version of bb_error_msg(), and since 2007 many new calls to bb_perror_msg() have been added that only take a single parameter and so could have been using bb_simple_perror_message(). This changeset introduces 'simple' versions of bb_info_msg(), bb_error_msg(), bb_error_msg_and_die(), bb_herror_msg() and bb_herror_msg_and_die(), and replaces all calls that only take a single parameter, or use something like ("%s", arg), with calls to the corresponding 'simple' version. Since it is likely that single parameter calls to the variadic functions may be accidentally reintroduced in the future a new debugging config option WARN_SIMPLE_MSG has been introduced. This uses some macro magic which will cause any such calls to generate a warning, but this is turned off by default to avoid use of the unpleasant macros in normal circumstances. This is a large changeset due to the number of calls that have been replaced. The only files that contain changes other than simple substitution of function calls are libbb.h, libbb/herror_msg.c, libbb/verror_msg.c and libbb/xfuncs_printf.c. In miscutils/devfsd.c, networking/udhcp/common.h and util-linux/mdev.c additonal macros have been added for logging so that single parameter and multiple parameter logging variants exist. The amount of space saved varies considerably by architecture, and was found to be as follows (for 'defconfig' using GCC 7.4): Arm: -92 bytes MIPS: -52 bytes PPC: -1836 bytes x86_64: -938 bytes Note that for the MIPS architecture only an exception had to be made disabling the 'simple' calls for 'udhcp' (in networking/udhcp/common.h) because it made these files larger on MIPS. Signed-off-by: James Byrne <james.byrne@origamienergy.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-07-02 17:35:03 +08:00
bb_simple_error_msg("bad read command");
break;
}
cp = skip_whitespace(cp);
if (*cp == '\0') {
libbb: reduce the overhead of single parameter bb_error_msg() calls Back in 2007, commit 0c97c9d43707 ("'simple' error message functions by Loic Grenie") introduced bb_simple_perror_msg() to allow for a lower overhead call to bb_perror_msg() when only a string was being printed with no parameters. This saves space for some CPU architectures because it avoids the overhead of a call to a variadic function. However there has never been a simple version of bb_error_msg(), and since 2007 many new calls to bb_perror_msg() have been added that only take a single parameter and so could have been using bb_simple_perror_message(). This changeset introduces 'simple' versions of bb_info_msg(), bb_error_msg(), bb_error_msg_and_die(), bb_herror_msg() and bb_herror_msg_and_die(), and replaces all calls that only take a single parameter, or use something like ("%s", arg), with calls to the corresponding 'simple' version. Since it is likely that single parameter calls to the variadic functions may be accidentally reintroduced in the future a new debugging config option WARN_SIMPLE_MSG has been introduced. This uses some macro magic which will cause any such calls to generate a warning, but this is turned off by default to avoid use of the unpleasant macros in normal circumstances. This is a large changeset due to the number of calls that have been replaced. The only files that contain changes other than simple substitution of function calls are libbb.h, libbb/herror_msg.c, libbb/verror_msg.c and libbb/xfuncs_printf.c. In miscutils/devfsd.c, networking/udhcp/common.h and util-linux/mdev.c additonal macros have been added for logging so that single parameter and multiple parameter logging variants exist. The amount of space saved varies considerably by architecture, and was found to be as follows (for 'defconfig' using GCC 7.4): Arm: -92 bytes MIPS: -52 bytes PPC: -1836 bytes x86_64: -938 bytes Note that for the MIPS architecture only an exception had to be made disabling the 'simple' calls for 'udhcp' (in networking/udhcp/common.h) because it made these files larger on MIPS. Signed-off-by: James Byrne <james.byrne@origamienergy.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-07-02 17:35:03 +08:00
bb_simple_error_msg("no file name");
break;
}
if (!have1)
num1 = lastNum;
if (readLines(cp, num1 + 1))
break;
if (fileName == NULL)
fileName = xstrdup(cp);
break;
case 's':
subCommand(cp, num1, num2);
break;
case 'w':
if (*cp != '\0' && *cp != ' ') {
libbb: reduce the overhead of single parameter bb_error_msg() calls Back in 2007, commit 0c97c9d43707 ("'simple' error message functions by Loic Grenie") introduced bb_simple_perror_msg() to allow for a lower overhead call to bb_perror_msg() when only a string was being printed with no parameters. This saves space for some CPU architectures because it avoids the overhead of a call to a variadic function. However there has never been a simple version of bb_error_msg(), and since 2007 many new calls to bb_perror_msg() have been added that only take a single parameter and so could have been using bb_simple_perror_message(). This changeset introduces 'simple' versions of bb_info_msg(), bb_error_msg(), bb_error_msg_and_die(), bb_herror_msg() and bb_herror_msg_and_die(), and replaces all calls that only take a single parameter, or use something like ("%s", arg), with calls to the corresponding 'simple' version. Since it is likely that single parameter calls to the variadic functions may be accidentally reintroduced in the future a new debugging config option WARN_SIMPLE_MSG has been introduced. This uses some macro magic which will cause any such calls to generate a warning, but this is turned off by default to avoid use of the unpleasant macros in normal circumstances. This is a large changeset due to the number of calls that have been replaced. The only files that contain changes other than simple substitution of function calls are libbb.h, libbb/herror_msg.c, libbb/verror_msg.c and libbb/xfuncs_printf.c. In miscutils/devfsd.c, networking/udhcp/common.h and util-linux/mdev.c additonal macros have been added for logging so that single parameter and multiple parameter logging variants exist. The amount of space saved varies considerably by architecture, and was found to be as follows (for 'defconfig' using GCC 7.4): Arm: -92 bytes MIPS: -52 bytes PPC: -1836 bytes x86_64: -938 bytes Note that for the MIPS architecture only an exception had to be made disabling the 'simple' calls for 'udhcp' (in networking/udhcp/common.h) because it made these files larger on MIPS. Signed-off-by: James Byrne <james.byrne@origamienergy.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-07-02 17:35:03 +08:00
bb_simple_error_msg("bad write command");
break;
}
cp = skip_whitespace(cp);
if (*cp == '\0') {
cp = fileName;
if (!cp) {
libbb: reduce the overhead of single parameter bb_error_msg() calls Back in 2007, commit 0c97c9d43707 ("'simple' error message functions by Loic Grenie") introduced bb_simple_perror_msg() to allow for a lower overhead call to bb_perror_msg() when only a string was being printed with no parameters. This saves space for some CPU architectures because it avoids the overhead of a call to a variadic function. However there has never been a simple version of bb_error_msg(), and since 2007 many new calls to bb_perror_msg() have been added that only take a single parameter and so could have been using bb_simple_perror_message(). This changeset introduces 'simple' versions of bb_info_msg(), bb_error_msg(), bb_error_msg_and_die(), bb_herror_msg() and bb_herror_msg_and_die(), and replaces all calls that only take a single parameter, or use something like ("%s", arg), with calls to the corresponding 'simple' version. Since it is likely that single parameter calls to the variadic functions may be accidentally reintroduced in the future a new debugging config option WARN_SIMPLE_MSG has been introduced. This uses some macro magic which will cause any such calls to generate a warning, but this is turned off by default to avoid use of the unpleasant macros in normal circumstances. This is a large changeset due to the number of calls that have been replaced. The only files that contain changes other than simple substitution of function calls are libbb.h, libbb/herror_msg.c, libbb/verror_msg.c and libbb/xfuncs_printf.c. In miscutils/devfsd.c, networking/udhcp/common.h and util-linux/mdev.c additonal macros have been added for logging so that single parameter and multiple parameter logging variants exist. The amount of space saved varies considerably by architecture, and was found to be as follows (for 'defconfig' using GCC 7.4): Arm: -92 bytes MIPS: -52 bytes PPC: -1836 bytes x86_64: -938 bytes Note that for the MIPS architecture only an exception had to be made disabling the 'simple' calls for 'udhcp' (in networking/udhcp/common.h) because it made these files larger on MIPS. Signed-off-by: James Byrne <james.byrne@origamienergy.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-07-02 17:35:03 +08:00
bb_simple_error_msg("no file name specified");
break;
}
}
if (!have1) {
num1 = 1;
num2 = lastNum;
dirty = FALSE;
}
writeLines(cp, num1, num2);
break;
case 'z':
switch (*cp) {
case '-':
printLines(curNum - 21, curNum, FALSE);
break;
case '.':
printLines(curNum - 11, curNum + 10, FALSE);
break;
default:
printLines(curNum, curNum + 21, FALSE);
break;
}
break;
case '.':
if (have1) {
libbb: reduce the overhead of single parameter bb_error_msg() calls Back in 2007, commit 0c97c9d43707 ("'simple' error message functions by Loic Grenie") introduced bb_simple_perror_msg() to allow for a lower overhead call to bb_perror_msg() when only a string was being printed with no parameters. This saves space for some CPU architectures because it avoids the overhead of a call to a variadic function. However there has never been a simple version of bb_error_msg(), and since 2007 many new calls to bb_perror_msg() have been added that only take a single parameter and so could have been using bb_simple_perror_message(). This changeset introduces 'simple' versions of bb_info_msg(), bb_error_msg(), bb_error_msg_and_die(), bb_herror_msg() and bb_herror_msg_and_die(), and replaces all calls that only take a single parameter, or use something like ("%s", arg), with calls to the corresponding 'simple' version. Since it is likely that single parameter calls to the variadic functions may be accidentally reintroduced in the future a new debugging config option WARN_SIMPLE_MSG has been introduced. This uses some macro magic which will cause any such calls to generate a warning, but this is turned off by default to avoid use of the unpleasant macros in normal circumstances. This is a large changeset due to the number of calls that have been replaced. The only files that contain changes other than simple substitution of function calls are libbb.h, libbb/herror_msg.c, libbb/verror_msg.c and libbb/xfuncs_printf.c. In miscutils/devfsd.c, networking/udhcp/common.h and util-linux/mdev.c additonal macros have been added for logging so that single parameter and multiple parameter logging variants exist. The amount of space saved varies considerably by architecture, and was found to be as follows (for 'defconfig' using GCC 7.4): Arm: -92 bytes MIPS: -52 bytes PPC: -1836 bytes x86_64: -938 bytes Note that for the MIPS architecture only an exception had to be made disabling the 'simple' calls for 'udhcp' (in networking/udhcp/common.h) because it made these files larger on MIPS. Signed-off-by: James Byrne <james.byrne@origamienergy.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-07-02 17:35:03 +08:00
bb_simple_error_msg("no arguments allowed");
break;
}
printLines(curNum, curNum, FALSE);
break;
case '-':
if (setCurNum(curNum - 1))
printLines(curNum, curNum, FALSE);
break;
case '=':
printf("%d\n", num1);
break;
case '\0':
if (have1) {
printLines(num2, num2, FALSE);
break;
}
if (setCurNum(curNum + 1))
printLines(curNum, curNum, FALSE);
break;
default:
libbb: reduce the overhead of single parameter bb_error_msg() calls Back in 2007, commit 0c97c9d43707 ("'simple' error message functions by Loic Grenie") introduced bb_simple_perror_msg() to allow for a lower overhead call to bb_perror_msg() when only a string was being printed with no parameters. This saves space for some CPU architectures because it avoids the overhead of a call to a variadic function. However there has never been a simple version of bb_error_msg(), and since 2007 many new calls to bb_perror_msg() have been added that only take a single parameter and so could have been using bb_simple_perror_message(). This changeset introduces 'simple' versions of bb_info_msg(), bb_error_msg(), bb_error_msg_and_die(), bb_herror_msg() and bb_herror_msg_and_die(), and replaces all calls that only take a single parameter, or use something like ("%s", arg), with calls to the corresponding 'simple' version. Since it is likely that single parameter calls to the variadic functions may be accidentally reintroduced in the future a new debugging config option WARN_SIMPLE_MSG has been introduced. This uses some macro magic which will cause any such calls to generate a warning, but this is turned off by default to avoid use of the unpleasant macros in normal circumstances. This is a large changeset due to the number of calls that have been replaced. The only files that contain changes other than simple substitution of function calls are libbb.h, libbb/herror_msg.c, libbb/verror_msg.c and libbb/xfuncs_printf.c. In miscutils/devfsd.c, networking/udhcp/common.h and util-linux/mdev.c additonal macros have been added for logging so that single parameter and multiple parameter logging variants exist. The amount of space saved varies considerably by architecture, and was found to be as follows (for 'defconfig' using GCC 7.4): Arm: -92 bytes MIPS: -52 bytes PPC: -1836 bytes x86_64: -938 bytes Note that for the MIPS architecture only an exception had to be made disabling the 'simple' calls for 'udhcp' (in networking/udhcp/common.h) because it made these files larger on MIPS. Signed-off-by: James Byrne <james.byrne@origamienergy.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-07-02 17:35:03 +08:00
bb_simple_error_msg("unimplemented command");
break;
}
}
}
int ed_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int ed_main(int argc UNUSED_PARAM, char **argv)
{
INIT_G();
bufSize = INITBUF_SIZE;
bufBase = xmalloc(bufSize);
bufPtr = bufBase;
lines.next = &lines;
lines.prev = &lines;
if (argv[1]) {
fileName = xstrdup(argv[1]);
if (!readLines(fileName, 1)) {
return EXIT_SUCCESS;
}
if (lastNum)
setCurNum(1);
dirty = FALSE;
}
doCommands();
return EXIT_SUCCESS;
}