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 2422c34..3055c16 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); +} |