diff options
Diffstat (limited to 'scripts/dtc/util.c')
| -rw-r--r-- | scripts/dtc/util.c | 141 | 
1 files changed, 129 insertions, 12 deletions
diff --git a/scripts/dtc/util.c b/scripts/dtc/util.c index 2422c34e11d..3055c16e980 100644 --- a/scripts/dtc/util.c +++ b/scripts/dtc/util.c @@ -34,6 +34,7 @@  #include "libfdt.h"  #include "util.h" +#include "version_gen.h"  char *xstrdup(const char *s)  { @@ -72,7 +73,7 @@ char *join_path(const char *path, const char *name)  int util_is_printable_string(const void *data, int len)  {  	const char *s = data; -	const char *ss; +	const char *ss, *se;  	/* zero length is not */  	if (len == 0) @@ -82,13 +83,19 @@ int util_is_printable_string(const void *data, int len)  	if (s[len - 1] != '\0')  		return 0; -	ss = s; -	while (*s && isprint(*s)) -		s++; +	se = s + len; -	/* not zero, or not done yet */ -	if (*s != '\0' || (s + 1 - ss) < len) -		return 0; +	while (s < se) { +		ss = s; +		while (s < se && *s && isprint(*s)) +			s++; + +		/* not zero, or not done yet */ +		if (*s != '\0' || s == ss) +			return 0; + +		s++; +	}  	return 1;  } @@ -191,7 +198,7 @@ char get_escape_char(const char *s, int *i)  	return val;  } -int utilfdt_read_err(const char *filename, char **buffp) +int utilfdt_read_err_len(const char *filename, char **buffp, off_t *len)  {  	int fd = 0;	/* assume stdin */  	char *buf = NULL; @@ -206,12 +213,12 @@ int utilfdt_read_err(const char *filename, char **buffp)  	}  	/* Loop until we have read everything */ -	buf = malloc(bufsize); +	buf = xmalloc(bufsize);  	do {  		/* Expand the buffer to hold the next chunk */  		if (offset == bufsize) {  			bufsize *= 2; -			buf = realloc(buf, bufsize); +			buf = xrealloc(buf, bufsize);  			if (!buf) {  				ret = ENOMEM;  				break; @@ -232,13 +239,20 @@ int utilfdt_read_err(const char *filename, char **buffp)  		free(buf);  	else  		*buffp = buf; +	*len = bufsize;  	return ret;  } -char *utilfdt_read(const char *filename) +int utilfdt_read_err(const char *filename, char **buffp) +{ +	off_t len; +	return utilfdt_read_err_len(filename, buffp, &len); +} + +char *utilfdt_read_len(const char *filename, off_t *len)  {  	char *buff; -	int ret = utilfdt_read_err(filename, &buff); +	int ret = utilfdt_read_err_len(filename, &buff, len);  	if (ret) {  		fprintf(stderr, "Couldn't open blob from '%s': %s\n", filename, @@ -249,6 +263,12 @@ char *utilfdt_read(const char *filename)  	return buff;  } +char *utilfdt_read(const char *filename) +{ +	off_t len; +	return utilfdt_read_len(filename, &len); +} +  int utilfdt_write_err(const char *filename, const void *blob)  {  	int fd = 1;	/* assume stdout */ @@ -329,3 +349,100 @@ int utilfdt_decode_type(const char *fmt, int *type, int *size)  		return -1;  	return 0;  } + +void utilfdt_print_data(const char *data, int len) +{ +	int i; +	const char *p = data; +	const char *s; + +	/* no data, don't print */ +	if (len == 0) +		return; + +	if (util_is_printable_string(data, len)) { +		printf(" = "); + +		s = data; +		do { +			printf("\"%s\"", s); +			s += strlen(s) + 1; +			if (s < data + len) +				printf(", "); +		} while (s < data + len); + +	} else if ((len % 4) == 0) { +		const uint32_t *cell = (const uint32_t *)data; + +		printf(" = <"); +		for (i = 0; i < len; i += 4) +			printf("0x%08x%s", fdt32_to_cpu(cell[i]), +			       i < (len - 4) ? " " : ""); +		printf(">"); +	} else { +		printf(" = ["); +		for (i = 0; i < len; i++) +			printf("%02x%s", *p++, i < len - 1 ? " " : ""); +		printf("]"); +	} +} + +void util_version(void) +{ +	printf("Version: %s\n", DTC_VERSION); +	exit(0); +} + +void util_usage(const char *errmsg, const char *synopsis, +		const char *short_opts, struct option const long_opts[], +		const char * const opts_help[]) +{ +	FILE *fp = errmsg ? stderr : stdout; +	const char a_arg[] = "<arg>"; +	size_t a_arg_len = strlen(a_arg) + 1; +	size_t i; +	int optlen; + +	fprintf(fp, +		"Usage: %s\n" +		"\n" +		"Options: -[%s]\n", synopsis, short_opts); + +	/* prescan the --long opt length to auto-align */ +	optlen = 0; +	for (i = 0; long_opts[i].name; ++i) { +		/* +1 is for space between --opt and help text */ +		int l = strlen(long_opts[i].name) + 1; +		if (long_opts[i].has_arg == a_argument) +			l += a_arg_len; +		if (optlen < l) +			optlen = l; +	} + +	for (i = 0; long_opts[i].name; ++i) { +		/* helps when adding new applets or options */ +		assert(opts_help[i] != NULL); + +		/* first output the short flag if it has one */ +		if (long_opts[i].val > '~') +			fprintf(fp, "      "); +		else +			fprintf(fp, "  -%c, ", long_opts[i].val); + +		/* then the long flag */ +		if (long_opts[i].has_arg == no_argument) +			fprintf(fp, "--%-*s", optlen, long_opts[i].name); +		else +			fprintf(fp, "--%s %s%*s", long_opts[i].name, a_arg, +				(int)(optlen - strlen(long_opts[i].name) - a_arg_len), ""); + +		/* finally the help text */ +		fprintf(fp, "%s\n", opts_help[i]); +	} + +	if (errmsg) { +		fprintf(fp, "\nError: %s\n", errmsg); +		exit(EXIT_FAILURE); +	} else +		exit(EXIT_SUCCESS); +}  | 
