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 2422c34e11df..3055c16e980d 100644 --- a/scripts/dtc/util.c +++ b/scripts/dtc/util.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | 34 | ||
| 35 | #include "libfdt.h" | 35 | #include "libfdt.h" |
| 36 | #include "util.h" | 36 | #include "util.h" |
| 37 | #include "version_gen.h" | ||
| 37 | 38 | ||
| 38 | char *xstrdup(const char *s) | 39 | char *xstrdup(const char *s) |
| 39 | { | 40 | { |
| @@ -72,7 +73,7 @@ char *join_path(const char *path, const char *name) | |||
| 72 | int util_is_printable_string(const void *data, int len) | 73 | int util_is_printable_string(const void *data, int len) |
| 73 | { | 74 | { |
| 74 | const char *s = data; | 75 | const char *s = data; |
| 75 | const char *ss; | 76 | const char *ss, *se; |
| 76 | 77 | ||
| 77 | /* zero length is not */ | 78 | /* zero length is not */ |
| 78 | if (len == 0) | 79 | if (len == 0) |
| @@ -82,13 +83,19 @@ int util_is_printable_string(const void *data, int len) | |||
| 82 | if (s[len - 1] != '\0') | 83 | if (s[len - 1] != '\0') |
| 83 | return 0; | 84 | return 0; |
| 84 | 85 | ||
| 85 | ss = s; | 86 | se = s + len; |
| 86 | while (*s && isprint(*s)) | ||
| 87 | s++; | ||
| 88 | 87 | ||
| 89 | /* not zero, or not done yet */ | 88 | while (s < se) { |
| 90 | if (*s != '\0' || (s + 1 - ss) < len) | 89 | ss = s; |
| 91 | return 0; | 90 | while (s < se && *s && isprint(*s)) |
| 91 | s++; | ||
| 92 | |||
| 93 | /* not zero, or not done yet */ | ||
| 94 | if (*s != '\0' || s == ss) | ||
| 95 | return 0; | ||
| 96 | |||
| 97 | s++; | ||
| 98 | } | ||
| 92 | 99 | ||
| 93 | return 1; | 100 | return 1; |
| 94 | } | 101 | } |
| @@ -191,7 +198,7 @@ char get_escape_char(const char *s, int *i) | |||
| 191 | return val; | 198 | return val; |
| 192 | } | 199 | } |
| 193 | 200 | ||
| 194 | int utilfdt_read_err(const char *filename, char **buffp) | 201 | int utilfdt_read_err_len(const char *filename, char **buffp, off_t *len) |
| 195 | { | 202 | { |
| 196 | int fd = 0; /* assume stdin */ | 203 | int fd = 0; /* assume stdin */ |
| 197 | char *buf = NULL; | 204 | char *buf = NULL; |
| @@ -206,12 +213,12 @@ int utilfdt_read_err(const char *filename, char **buffp) | |||
| 206 | } | 213 | } |
| 207 | 214 | ||
| 208 | /* Loop until we have read everything */ | 215 | /* Loop until we have read everything */ |
| 209 | buf = malloc(bufsize); | 216 | buf = xmalloc(bufsize); |
| 210 | do { | 217 | do { |
| 211 | /* Expand the buffer to hold the next chunk */ | 218 | /* Expand the buffer to hold the next chunk */ |
| 212 | if (offset == bufsize) { | 219 | if (offset == bufsize) { |
| 213 | bufsize *= 2; | 220 | bufsize *= 2; |
| 214 | buf = realloc(buf, bufsize); | 221 | buf = xrealloc(buf, bufsize); |
| 215 | if (!buf) { | 222 | if (!buf) { |
| 216 | ret = ENOMEM; | 223 | ret = ENOMEM; |
| 217 | break; | 224 | break; |
| @@ -232,13 +239,20 @@ int utilfdt_read_err(const char *filename, char **buffp) | |||
| 232 | free(buf); | 239 | free(buf); |
| 233 | else | 240 | else |
| 234 | *buffp = buf; | 241 | *buffp = buf; |
| 242 | *len = bufsize; | ||
| 235 | return ret; | 243 | return ret; |
| 236 | } | 244 | } |
| 237 | 245 | ||
| 238 | char *utilfdt_read(const char *filename) | 246 | int utilfdt_read_err(const char *filename, char **buffp) |
| 247 | { | ||
| 248 | off_t len; | ||
| 249 | return utilfdt_read_err_len(filename, buffp, &len); | ||
| 250 | } | ||
| 251 | |||
| 252 | char *utilfdt_read_len(const char *filename, off_t *len) | ||
| 239 | { | 253 | { |
| 240 | char *buff; | 254 | char *buff; |
| 241 | int ret = utilfdt_read_err(filename, &buff); | 255 | int ret = utilfdt_read_err_len(filename, &buff, len); |
| 242 | 256 | ||
| 243 | if (ret) { | 257 | if (ret) { |
| 244 | fprintf(stderr, "Couldn't open blob from '%s': %s\n", filename, | 258 | fprintf(stderr, "Couldn't open blob from '%s': %s\n", filename, |
| @@ -249,6 +263,12 @@ char *utilfdt_read(const char *filename) | |||
| 249 | return buff; | 263 | return buff; |
| 250 | } | 264 | } |
| 251 | 265 | ||
| 266 | char *utilfdt_read(const char *filename) | ||
| 267 | { | ||
| 268 | off_t len; | ||
| 269 | return utilfdt_read_len(filename, &len); | ||
| 270 | } | ||
| 271 | |||
| 252 | int utilfdt_write_err(const char *filename, const void *blob) | 272 | int utilfdt_write_err(const char *filename, const void *blob) |
| 253 | { | 273 | { |
| 254 | int fd = 1; /* assume stdout */ | 274 | int fd = 1; /* assume stdout */ |
| @@ -329,3 +349,100 @@ int utilfdt_decode_type(const char *fmt, int *type, int *size) | |||
| 329 | return -1; | 349 | return -1; |
| 330 | return 0; | 350 | return 0; |
| 331 | } | 351 | } |
| 352 | |||
| 353 | void utilfdt_print_data(const char *data, int len) | ||
| 354 | { | ||
| 355 | int i; | ||
| 356 | const char *p = data; | ||
| 357 | const char *s; | ||
| 358 | |||
| 359 | /* no data, don't print */ | ||
| 360 | if (len == 0) | ||
| 361 | return; | ||
| 362 | |||
| 363 | if (util_is_printable_string(data, len)) { | ||
| 364 | printf(" = "); | ||
| 365 | |||
| 366 | s = data; | ||
| 367 | do { | ||
| 368 | printf("\"%s\"", s); | ||
| 369 | s += strlen(s) + 1; | ||
| 370 | if (s < data + len) | ||
| 371 | printf(", "); | ||
| 372 | } while (s < data + len); | ||
| 373 | |||
| 374 | } else if ((len % 4) == 0) { | ||
| 375 | const uint32_t *cell = (const uint32_t *)data; | ||
| 376 | |||
| 377 | printf(" = <"); | ||
| 378 | for (i = 0; i < len; i += 4) | ||
| 379 | printf("0x%08x%s", fdt32_to_cpu(cell[i]), | ||
| 380 | i < (len - 4) ? " " : ""); | ||
| 381 | printf(">"); | ||
| 382 | } else { | ||
| 383 | printf(" = ["); | ||
| 384 | for (i = 0; i < len; i++) | ||
| 385 | printf("%02x%s", *p++, i < len - 1 ? " " : ""); | ||
| 386 | printf("]"); | ||
| 387 | } | ||
| 388 | } | ||
| 389 | |||
| 390 | void util_version(void) | ||
| 391 | { | ||
| 392 | printf("Version: %s\n", DTC_VERSION); | ||
| 393 | exit(0); | ||
| 394 | } | ||
| 395 | |||
| 396 | void util_usage(const char *errmsg, const char *synopsis, | ||
| 397 | const char *short_opts, struct option const long_opts[], | ||
| 398 | const char * const opts_help[]) | ||
| 399 | { | ||
| 400 | FILE *fp = errmsg ? stderr : stdout; | ||
| 401 | const char a_arg[] = "<arg>"; | ||
| 402 | size_t a_arg_len = strlen(a_arg) + 1; | ||
| 403 | size_t i; | ||
| 404 | int optlen; | ||
| 405 | |||
| 406 | fprintf(fp, | ||
| 407 | "Usage: %s\n" | ||
| 408 | "\n" | ||
| 409 | "Options: -[%s]\n", synopsis, short_opts); | ||
| 410 | |||
| 411 | /* prescan the --long opt length to auto-align */ | ||
| 412 | optlen = 0; | ||
| 413 | for (i = 0; long_opts[i].name; ++i) { | ||
| 414 | /* +1 is for space between --opt and help text */ | ||
| 415 | int l = strlen(long_opts[i].name) + 1; | ||
| 416 | if (long_opts[i].has_arg == a_argument) | ||
| 417 | l += a_arg_len; | ||
| 418 | if (optlen < l) | ||
| 419 | optlen = l; | ||
| 420 | } | ||
| 421 | |||
| 422 | for (i = 0; long_opts[i].name; ++i) { | ||
| 423 | /* helps when adding new applets or options */ | ||
| 424 | assert(opts_help[i] != NULL); | ||
| 425 | |||
| 426 | /* first output the short flag if it has one */ | ||
| 427 | if (long_opts[i].val > '~') | ||
| 428 | fprintf(fp, " "); | ||
| 429 | else | ||
| 430 | fprintf(fp, " -%c, ", long_opts[i].val); | ||
| 431 | |||
| 432 | /* then the long flag */ | ||
| 433 | if (long_opts[i].has_arg == no_argument) | ||
| 434 | fprintf(fp, "--%-*s", optlen, long_opts[i].name); | ||
| 435 | else | ||
| 436 | fprintf(fp, "--%s %s%*s", long_opts[i].name, a_arg, | ||
| 437 | (int)(optlen - strlen(long_opts[i].name) - a_arg_len), ""); | ||
| 438 | |||
| 439 | /* finally the help text */ | ||
| 440 | fprintf(fp, "%s\n", opts_help[i]); | ||
| 441 | } | ||
| 442 | |||
| 443 | if (errmsg) { | ||
| 444 | fprintf(fp, "\nError: %s\n", errmsg); | ||
| 445 | exit(EXIT_FAILURE); | ||
| 446 | } else | ||
| 447 | exit(EXIT_SUCCESS); | ||
| 448 | } | ||
