diff options
Diffstat (limited to 'scripts/kconfig/confdata.c')
| -rw-r--r-- | scripts/kconfig/confdata.c | 61 | 
1 files changed, 59 insertions, 2 deletions
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 52577f052bc..13ddf1126c2 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -182,10 +182,66 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)  	return 0;  } +#define LINE_GROWTH 16 +static int add_byte(int c, char **lineptr, size_t slen, size_t *n) +{ +	char *nline; +	size_t new_size = slen + 1; +	if (new_size > *n) { +		new_size += LINE_GROWTH - 1; +		new_size *= 2; +		nline = realloc(*lineptr, new_size); +		if (!nline) +			return -1; + +		*lineptr = nline; +		*n = new_size; +	} + +	(*lineptr)[slen] = c; + +	return 0; +} + +static ssize_t compat_getline(char **lineptr, size_t *n, FILE *stream) +{ +	char *line = *lineptr; +	size_t slen = 0; + +	for (;;) { +		int c = getc(stream); + +		switch (c) { +		case '\n': +			if (add_byte(c, &line, slen, n) < 0) +				goto e_out; +			slen++; +			/* fall through */ +		case EOF: +			if (add_byte('\0', &line, slen, n) < 0) +				goto e_out; +			*lineptr = line; +			if (slen == 0) +				return -1; +			return slen; +		default: +			if (add_byte(c, &line, slen, n) < 0) +				goto e_out; +			slen++; +		} +	} + +e_out: +	line[slen-1] = '\0'; +	*lineptr = line; +	return -1; +} +  int conf_read_simple(const char *name, int def)  {  	FILE *in = NULL; -	char line[1024]; +	char   *line = NULL; +	size_t  line_asize = 0;  	char *p, *p2;  	struct symbol *sym;  	int i, def_flags; @@ -247,7 +303,7 @@ load:  		}  	} -	while (fgets(line, sizeof(line), in)) { +	while (compat_getline(&line, &line_asize, in) != -1) {  		conf_lineno++;  		sym = NULL;  		if (line[0] == '#') { @@ -335,6 +391,7 @@ setsym:  			cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri);  		}  	} +	free(line);  	fclose(in);  	if (modules_sym)  |