ifupdown: save some 100+ bytes of code in addstr()

This commit is contained in:
Denis Vlasenko 2006-11-23 15:07:38 +00:00
parent 4e4662cc73
commit 93ad1c2385

View File

@ -125,6 +125,7 @@ static int count_netmask_bits(char *dotted_quad)
/* Found a netmask... Check if it is dotted quad */ /* Found a netmask... Check if it is dotted quad */
if (sscanf(dotted_quad, "%u.%u.%u.%u", &a, &b, &c, &d) != 4) if (sscanf(dotted_quad, "%u.%u.%u.%u", &a, &b, &c, &d) != 4)
return -1; return -1;
// FIXME: will be confused by e.g. 255.0.255.0
result = count_bits(a); result = count_bits(a);
result += count_bits(b); result += count_bits(b);
result += count_bits(c); result += count_bits(c);
@ -133,32 +134,27 @@ static int count_netmask_bits(char *dotted_quad)
} }
#endif #endif
static void addstr(char **buf, size_t *len, size_t *pos, const char *str, size_t str_length) static void addstr(char **bufp, const char *str, size_t str_length)
{ {
if (*pos + str_length >= *len) { /* xasprintf trick will be smaller, but we are often
char *newbuf; * called with str_length == 1 - don't want to have
* THAT much of malloc/freeing! */
newbuf = xrealloc(*buf, *len * 2 + str_length + 1); char *buf = *bufp;
*buf = newbuf; int len = (buf ? strlen(buf) : 0);
*len = *len * 2 + str_length + 1; str_length++;
} buf = xrealloc(buf, len + str_length);
/* copies at most str_length-1 chars! */
while (str_length-- >= 1) { safe_strncpy(buf + len, str, str_length);
(*buf)[(*pos)++] = *str; *bufp = buf;
str++;
}
(*buf)[*pos] = '\0';
} }
static int strncmpz(const char *l, const char *r, size_t llen) static int strncmpz(const char *l, const char *r, size_t llen)
{ {
int i = strncmp(l, r, llen); int i = strncmp(l, r, llen);
if (i == 0) { if (i == 0)
return -r[llen]; return -r[llen];
} else {
return i; return i;
}
} }
static char *get_var(const char *id, size_t idlen, struct interface_defn_t *ifd) static char *get_var(const char *id, size_t idlen, struct interface_defn_t *ifd)
@ -168,31 +164,27 @@ static char *get_var(const char *id, size_t idlen, struct interface_defn_t *ifd)
if (strncmpz(id, "iface", idlen) == 0) { if (strncmpz(id, "iface", idlen) == 0) {
char *result; char *result;
static char label_buf[20]; static char label_buf[20];
strncpy(label_buf, ifd->iface, 19); safe_strncpy(label_buf, ifd->iface, sizeof(label_buf));
label_buf[19]=0;
result = strchr(label_buf, ':'); result = strchr(label_buf, ':');
if (result) { if (result) {
*result=0; *result = '\0';
} }
return label_buf; return label_buf;
} else if (strncmpz(id, "label", idlen) == 0) { }
if (strncmpz(id, "label", idlen) == 0) {
return ifd->iface; return ifd->iface;
} else { }
for (i = 0; i < ifd->n_options; i++) { for (i = 0; i < ifd->n_options; i++) {
if (strncmpz(id, ifd->option[i].name, idlen) == 0) { if (strncmpz(id, ifd->option[i].name, idlen) == 0) {
return ifd->option[i].value; return ifd->option[i].value;
} }
} }
}
return NULL; return NULL;
} }
static char *parse(const char *command, struct interface_defn_t *ifd) static char *parse(const char *command, struct interface_defn_t *ifd)
{ {
char *result = NULL; char *result = NULL;
size_t pos = 0, len = 0;
size_t old_pos[MAX_OPT_DEPTH] = { 0 }; size_t old_pos[MAX_OPT_DEPTH] = { 0 };
int okay[MAX_OPT_DEPTH] = { 1 }; int okay[MAX_OPT_DEPTH] = { 1 };
int opt_depth = 1; int opt_depth = 1;
@ -200,26 +192,26 @@ static char *parse(const char *command, struct interface_defn_t *ifd)
while (*command) { while (*command) {
switch (*command) { switch (*command) {
default: default:
addstr(&result, &len, &pos, command, 1); addstr(&result, command, 1);
command++; command++;
break; break;
case '\\': case '\\':
if (command[1]) { if (command[1]) {
addstr(&result, &len, &pos, command + 1, 1); addstr(&result, command + 1, 1);
command += 2; command += 2;
} else { } else {
addstr(&result, &len, &pos, command, 1); addstr(&result, command, 1);
command++; command++;
} }
break; break;
case '[': case '[':
if (command[1] == '[' && opt_depth < MAX_OPT_DEPTH) { if (command[1] == '[' && opt_depth < MAX_OPT_DEPTH) {
old_pos[opt_depth] = pos; old_pos[opt_depth] = strlen(result);
okay[opt_depth] = 1; okay[opt_depth] = 1;
opt_depth++; opt_depth++;
command += 2; command += 2;
} else { } else {
addstr(&result, &len, &pos, "[", 1); addstr(&result, "[", 1);
command++; command++;
} }
break; break;
@ -227,12 +219,11 @@ static char *parse(const char *command, struct interface_defn_t *ifd)
if (command[1] == ']' && opt_depth > 1) { if (command[1] == ']' && opt_depth > 1) {
opt_depth--; opt_depth--;
if (!okay[opt_depth]) { if (!okay[opt_depth]) {
pos = old_pos[opt_depth]; result[old_pos[opt_depth]] = '\0';
result[pos] = '\0';
} }
command += 2; command += 2;
} else { } else {
addstr(&result, &len, &pos, "]", 1); addstr(&result, "]", 1);
command++; command++;
} }
break; break;
@ -252,18 +243,17 @@ static char *parse(const char *command, struct interface_defn_t *ifd)
varvalue = get_var(command, nextpercent - command, ifd); varvalue = get_var(command, nextpercent - command, ifd);
if (varvalue) { if (varvalue) {
addstr(&result, &len, &pos, varvalue, strlen(varvalue)); addstr(&result, varvalue, strlen(varvalue));
} else { } else {
#ifdef CONFIG_FEATURE_IFUPDOWN_IP #ifdef CONFIG_FEATURE_IFUPDOWN_IP
/* Sigh... Add a special case for 'ip' to convert from /* Sigh... Add a special case for 'ip' to convert from
* dotted quad to bit count style netmasks. */ * dotted quad to bit count style netmasks. */
if (strncmp(command, "bnmask", 6)==0) { if (strncmp(command, "bnmask", 6)==0) {
int res; unsigned res;
varvalue = get_var("netmask", 7, ifd); varvalue = get_var("netmask", 7, ifd);
if (varvalue && (res=count_netmask_bits(varvalue)) > 0) { if (varvalue && (res = count_netmask_bits(varvalue)) > 0) {
char argument[255]; const char *argument = utoa(res);
sprintf(argument, "%d", res); addstr(&result, argument, strlen(argument));
addstr(&result, &len, &pos, argument, strlen(argument));
command = nextpercent + 1; command = nextpercent + 1;
break; break;
} }
@ -567,7 +557,7 @@ static char *next_word(char **buf)
unsigned short length; unsigned short length;
char *word; char *word;
if ((buf == NULL) || (*buf == NULL) || (**buf == '\0')) { if (!buf || !*buf || !**buf) {
return NULL; return NULL;
} }