ed: code shrink
function old new delta findString 117 115 -2 skip_blank 16 - -16 getNum 369 345 -24 doCommands 2448 2183 -265 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 0/3 up/down: 0/-307) Total: -307 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
5ea50697fd
commit
7d2f33dc1f
94
editors/ed.c
94
editors/ed.c
@ -78,13 +78,6 @@ static int bad_nums(int num1, int num2, const char *for_what)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *skip_blank(const char *cp)
|
|
||||||
{
|
|
||||||
while (isblank(*cp))
|
|
||||||
cp++;
|
|
||||||
return (char *)cp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return a pointer to the specified line number.
|
* Return a pointer to the specified line number.
|
||||||
*/
|
*/
|
||||||
@ -138,15 +131,13 @@ static int findString(const LINE *lp, const char *str, int len, int offset)
|
|||||||
const char *cp, *ncp;
|
const char *cp, *ncp;
|
||||||
|
|
||||||
cp = &lp->data[offset];
|
cp = &lp->data[offset];
|
||||||
left = lp->len - offset;
|
left = lp->len - offset - len;
|
||||||
|
|
||||||
while (left >= len) {
|
while (left >= 0) {
|
||||||
ncp = memchr(cp, *str, left);
|
ncp = memchr(cp, str[0], left + 1);
|
||||||
if (ncp == NULL)
|
if (ncp == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
left -= (ncp - cp);
|
left -= (ncp - cp);
|
||||||
if (left < len)
|
|
||||||
return -1;
|
|
||||||
cp = ncp;
|
cp = ncp;
|
||||||
if (memcmp(cp, str, len) == 0)
|
if (memcmp(cp, str, len) == 0)
|
||||||
return (cp - lp->data);
|
return (cp - lp->data);
|
||||||
@ -203,25 +194,23 @@ static NOINLINE int searchLines(const char *str, int num1, int num2)
|
|||||||
/*
|
/*
|
||||||
* Parse a line number argument if it is present. This is a sum
|
* Parse a line number argument if it is present. This is a sum
|
||||||
* or difference of numbers, '.', '$', 'x, or a search string.
|
* or difference of numbers, '.', '$', 'x, or a search string.
|
||||||
* Returns TRUE if successful (whether or not there was a number).
|
* Returns pointer which stopped the scan if successful (whether or not
|
||||||
* Returns FALSE if there was a parsing error, with a message output.
|
* 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.
|
* Whether there was a number is returned indirectly, as is the number.
|
||||||
* The character pointer which stopped the scan is also returned.
|
|
||||||
*/
|
*/
|
||||||
static int getNum(const char **retcp, smallint *retHaveNum, int *retNum)
|
static const char* getNum(const char *cp, smallint *retHaveNum, int *retNum)
|
||||||
{
|
{
|
||||||
const char *cp;
|
|
||||||
char *endStr, str[USERSIZE];
|
char *endStr, str[USERSIZE];
|
||||||
int value, num;
|
int value, num;
|
||||||
smallint haveNum, minus;
|
smallint haveNum, minus;
|
||||||
|
|
||||||
cp = *retcp;
|
|
||||||
value = 0;
|
value = 0;
|
||||||
haveNum = FALSE;
|
haveNum = FALSE;
|
||||||
minus = 0;
|
minus = 0;
|
||||||
|
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
cp = skip_blank(cp);
|
cp = skip_whitespace(cp);
|
||||||
|
|
||||||
switch (*cp) {
|
switch (*cp) {
|
||||||
case '.':
|
case '.':
|
||||||
@ -240,7 +229,7 @@ static int getNum(const char **retcp, smallint *retHaveNum, int *retNum)
|
|||||||
cp++;
|
cp++;
|
||||||
if ((*cp < 'a') || (*cp > 'z')) {
|
if ((*cp < 'a') || (*cp > 'z')) {
|
||||||
bb_error_msg("bad mark name");
|
bb_error_msg("bad mark name");
|
||||||
return FALSE;
|
return NULL;
|
||||||
}
|
}
|
||||||
haveNum = TRUE;
|
haveNum = TRUE;
|
||||||
num = marks[*cp++ - 'a'];
|
num = marks[*cp++ - 'a'];
|
||||||
@ -256,16 +245,15 @@ static int getNum(const char **retcp, smallint *retHaveNum, int *retNum)
|
|||||||
cp = "";
|
cp = "";
|
||||||
num = searchLines(str, curNum, lastNum);
|
num = searchLines(str, curNum, lastNum);
|
||||||
if (num == 0)
|
if (num == 0)
|
||||||
return FALSE;
|
return NULL;
|
||||||
haveNum = TRUE;
|
haveNum = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (!isdigit(*cp)) {
|
if (!isdigit(*cp)) {
|
||||||
*retcp = cp;
|
|
||||||
*retHaveNum = haveNum;
|
*retHaveNum = haveNum;
|
||||||
*retNum = value;
|
*retNum = value;
|
||||||
return TRUE;
|
return cp;
|
||||||
}
|
}
|
||||||
num = 0;
|
num = 0;
|
||||||
while (isdigit(*cp))
|
while (isdigit(*cp))
|
||||||
@ -276,7 +264,7 @@ static int getNum(const char **retcp, smallint *retHaveNum, int *retNum)
|
|||||||
|
|
||||||
value += (minus ? -num : num);
|
value += (minus ? -num : num);
|
||||||
|
|
||||||
cp = skip_blank(cp);
|
cp = skip_whitespace(cp);
|
||||||
|
|
||||||
switch (*cp) {
|
switch (*cp) {
|
||||||
case '-':
|
case '-':
|
||||||
@ -290,10 +278,9 @@ static int getNum(const char **retcp, smallint *retHaveNum, int *retNum)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
*retcp = cp;
|
|
||||||
*retHaveNum = haveNum;
|
*retHaveNum = haveNum;
|
||||||
*retNum = value;
|
*retNum = value;
|
||||||
return TRUE;
|
return cp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -789,12 +776,13 @@ static void subCommand(const char *cmd, int num1, int num2)
|
|||||||
*/
|
*/
|
||||||
static void doCommands(void)
|
static void doCommands(void)
|
||||||
{
|
{
|
||||||
const char *cp;
|
|
||||||
char *endbuf, buf[USERSIZE];
|
|
||||||
int len, num1, num2;
|
|
||||||
smallint have1, have2;
|
|
||||||
|
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
|
char buf[USERSIZE];
|
||||||
|
const char *cp;
|
||||||
|
int len;
|
||||||
|
int n, num1, num2;
|
||||||
|
smallint h, have1, have2;
|
||||||
|
|
||||||
/* Returns:
|
/* Returns:
|
||||||
* -1 on read errors or EOF, or on bare Ctrl-D.
|
* -1 on read errors or EOF, or on bare Ctrl-D.
|
||||||
* 0 on ctrl-C,
|
* 0 on ctrl-C,
|
||||||
@ -803,32 +791,36 @@ static void doCommands(void)
|
|||||||
len = read_line_input(NULL, ": ", buf, sizeof(buf), /*timeout*/ -1);
|
len = read_line_input(NULL, ": ", buf, sizeof(buf), /*timeout*/ -1);
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
return;
|
return;
|
||||||
endbuf = &buf[len - 1];
|
while (len && isblank(buf[--len]))
|
||||||
while ((endbuf > buf) && isblank(endbuf[-1]))
|
buf[len] = '\0';
|
||||||
endbuf--;
|
|
||||||
*endbuf = '\0';
|
|
||||||
|
|
||||||
cp = skip_blank(buf);
|
|
||||||
have1 = FALSE;
|
|
||||||
have2 = FALSE;
|
|
||||||
|
|
||||||
if ((curNum == 0) && (lastNum > 0)) {
|
if ((curNum == 0) && (lastNum > 0)) {
|
||||||
curNum = 1;
|
curNum = 1;
|
||||||
curLine = lines.next;
|
curLine = lines.next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getNum(&cp, &have1, &num1))
|
have1 = FALSE;
|
||||||
|
have2 = FALSE;
|
||||||
|
/* Don't pass &have1, &num1 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;
|
continue;
|
||||||
|
have1 = h;
|
||||||
|
num1 = n;
|
||||||
|
|
||||||
cp = skip_blank(cp);
|
cp = skip_whitespace(cp);
|
||||||
|
|
||||||
if (*cp == ',') {
|
if (*cp == ',') {
|
||||||
cp++;
|
cp = getNum(cp + 1, &h, &n);
|
||||||
if (!getNum(&cp, &have2, &num2))
|
if (!cp)
|
||||||
continue;
|
continue;
|
||||||
|
num2 = n;
|
||||||
if (!have1)
|
if (!have1)
|
||||||
num1 = 1;
|
num1 = 1;
|
||||||
if (!have2)
|
if (!h)
|
||||||
num2 = lastNum;
|
num2 = lastNum;
|
||||||
have1 = TRUE;
|
have1 = TRUE;
|
||||||
have2 = TRUE;
|
have2 = TRUE;
|
||||||
@ -857,7 +849,7 @@ static void doCommands(void)
|
|||||||
bb_error_msg("bad file command");
|
bb_error_msg("bad file command");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cp = skip_blank(cp);
|
cp = skip_whitespace(cp);
|
||||||
if (*cp == '\0') {
|
if (*cp == '\0') {
|
||||||
if (fileName)
|
if (fileName)
|
||||||
printf("\"%s\"\n", fileName);
|
printf("\"%s\"\n", fileName);
|
||||||
@ -874,7 +866,7 @@ static void doCommands(void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'k':
|
case 'k':
|
||||||
cp = skip_blank(cp);
|
cp = skip_whitespace(cp);
|
||||||
if ((*cp < 'a') || (*cp > 'z') || cp[1]) {
|
if ((*cp < 'a') || (*cp > 'z') || cp[1]) {
|
||||||
bb_error_msg("bad mark name");
|
bb_error_msg("bad mark name");
|
||||||
break;
|
break;
|
||||||
@ -891,7 +883,7 @@ static void doCommands(void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'q':
|
case 'q':
|
||||||
cp = skip_blank(cp);
|
cp = skip_whitespace(cp);
|
||||||
if (have1 || *cp) {
|
if (have1 || *cp) {
|
||||||
bb_error_msg("bad quit command");
|
bb_error_msg("bad quit command");
|
||||||
break;
|
break;
|
||||||
@ -902,7 +894,7 @@ static void doCommands(void)
|
|||||||
/* read error/EOF - no way to continue */
|
/* read error/EOF - no way to continue */
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
return;
|
return;
|
||||||
cp = skip_blank(buf);
|
cp = skip_whitespace(buf);
|
||||||
if ((*cp | 0x20) == 'y') /* Y or y */
|
if ((*cp | 0x20) == 'y') /* Y or y */
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
@ -912,7 +904,7 @@ static void doCommands(void)
|
|||||||
bb_error_msg("bad read command");
|
bb_error_msg("bad read command");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cp = skip_blank(cp);
|
cp = skip_whitespace(cp);
|
||||||
if (*cp == '\0') {
|
if (*cp == '\0') {
|
||||||
bb_error_msg("no file name");
|
bb_error_msg("no file name");
|
||||||
break;
|
break;
|
||||||
@ -934,7 +926,7 @@ static void doCommands(void)
|
|||||||
bb_error_msg("bad write command");
|
bb_error_msg("bad write command");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cp = skip_blank(cp);
|
cp = skip_whitespace(cp);
|
||||||
if (!have1) {
|
if (!have1) {
|
||||||
num1 = 1;
|
num1 = 1;
|
||||||
num2 = lastNum;
|
num2 = lastNum;
|
||||||
|
Loading…
Reference in New Issue
Block a user