1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright 2011 The Chromium Authors, All Rights Reserved.
4 * Copyright 2008 Jon Loeliger, Freescale Semiconductor, Inc.
6 * util_is_printable_string contributed by
7 * Pantelis Antoniou <pantelis.antoniou AT gmail.com>
23 #include "version_gen.h"
25 char *xstrdup(const char *s
)
27 int len
= strlen(s
) + 1;
28 char *d
= xmalloc(len
);
35 int xavsprintf_append(char **strp
, const char *fmt
, va_list ap
)
37 int n
, size
= 0; /* start with 128 bytes */
46 n
= vsnprintf(NULL
, 0, fmt
, ap_copy
) + 1;
49 p
= xrealloc(p
, size
+ n
);
51 n
= vsnprintf(p
+ size
, n
, fmt
, ap
);
57 int xasprintf_append(char **strp
, const char *fmt
, ...)
63 n
= xavsprintf_append(strp
, fmt
, ap
);
69 int xasprintf(char **strp
, const char *fmt
, ...)
77 n
= xavsprintf_append(strp
, fmt
, ap
);
83 char *join_path(const char *path
, const char *name
)
85 int lenp
= strlen(path
);
86 int lenn
= strlen(name
);
91 len
= lenp
+ lenn
+ 2;
92 if ((lenp
> 0) && (path
[lenp
-1] == '/')) {
98 memcpy(str
, path
, lenp
);
103 memcpy(str
+lenp
, name
, lenn
+1);
107 bool util_is_printable_string(const void *data
, int len
)
109 const char *s
= data
;
112 /* zero length is not */
116 /* must terminate with zero */
117 if (s
[len
- 1] != '\0')
124 while (s
< se
&& *s
&& isprint((unsigned char)*s
))
127 /* not zero, or not done yet */
128 if (*s
!= '\0' || s
== ss
)
138 * Parse a octal encoded character starting at index i in string s. The
139 * resulting character will be returned and the index i will be updated to
140 * point at the character directly after the end of the encoding, this may be
141 * the '\0' terminator of the string.
143 static char get_oct_char(const char *s
, int *i
)
150 strncpy(x
, s
+ *i
, 3);
152 val
= strtol(x
, &endx
, 8);
161 * Parse a hexadecimal encoded character starting at index i in string s. The
162 * resulting character will be returned and the index i will be updated to
163 * point at the character directly after the end of the encoding, this may be
164 * the '\0' terminator of the string.
166 static char get_hex_char(const char *s
, int *i
)
173 strncpy(x
, s
+ *i
, 2);
175 val
= strtol(x
, &endx
, 16);
177 die("\\x used with no following hex digits\n");
183 char get_escape_char(const char *s
, int *i
)
219 j
--; /* need to re-read the first digit as
220 * part of the octal value */
221 val
= get_oct_char(s
, &j
);
224 val
= get_hex_char(s
, &j
);
234 int utilfdt_read_err(const char *filename
, char **buffp
, size_t *len
)
236 int fd
= 0; /* assume stdin */
238 size_t bufsize
= 1024, offset
= 0;
242 if (strcmp(filename
, "-") != 0) {
243 fd
= open(filename
, O_RDONLY
);
248 /* Loop until we have read everything */
249 buf
= xmalloc(bufsize
);
251 /* Expand the buffer to hold the next chunk */
252 if (offset
== bufsize
) {
254 buf
= xrealloc(buf
, bufsize
);
257 ret
= read(fd
, &buf
[offset
], bufsize
- offset
);
265 /* Clean up, including closing stdin; return errno on error */
276 char *utilfdt_read(const char *filename
, size_t *len
)
279 int ret
= utilfdt_read_err(filename
, &buff
, len
);
282 fprintf(stderr
, "Couldn't open blob from '%s': %s\n", filename
,
286 /* Successful read */
290 int utilfdt_write_err(const char *filename
, const void *blob
)
292 int fd
= 1; /* assume stdout */
296 const char *ptr
= blob
;
298 if (strcmp(filename
, "-") != 0) {
299 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
, 0666);
304 totalsize
= fdt_totalsize(blob
);
307 while (offset
< totalsize
) {
308 ret
= write(fd
, ptr
+ offset
, totalsize
- offset
);
315 /* Close the file/stdin; return errno on error */
318 return ret
< 0 ? -ret
: 0;
322 int utilfdt_write(const char *filename
, const void *blob
)
324 int ret
= utilfdt_write_err(filename
, blob
);
327 fprintf(stderr
, "Couldn't write blob to '%s': %s\n", filename
,
333 int utilfdt_decode_type(const char *fmt
, int *type
, int *size
)
340 /* get the conversion qualifier */
342 if (strchr("hlLb", *fmt
)) {
344 if (qualifier
== *fmt
) {
346 /* TODO: case 'l': qualifier = 'L'; break;*/
354 /* we should now have a type */
355 if ((*fmt
== '\0') || !strchr("iuxs", *fmt
))
358 /* convert qualifier (bhL) to byte size */
360 *size
= qualifier
== 'b' ? 1 :
361 qualifier
== 'h' ? 2 :
362 qualifier
== 'l' ? 4 : -1;
365 /* that should be it! */
371 void utilfdt_print_data(const char *data
, int len
)
376 /* no data, don't print */
380 if (util_is_printable_string(data
, len
)) {
389 } while (s
< data
+ len
);
391 } else if ((len
% 4) == 0) {
392 const fdt32_t
*cell
= (const fdt32_t
*)data
;
395 for (i
= 0, len
/= 4; i
< len
; i
++)
396 printf("0x%08x%s", fdt32_to_cpu(cell
[i
]),
397 i
< (len
- 1) ? " " : "");
400 const unsigned char *p
= (const unsigned char *)data
;
402 for (i
= 0; i
< len
; i
++)
403 printf("%02x%s", *p
++, i
< len
- 1 ? " " : "");
408 void NORETURN
util_version(void)
410 printf("Version: %s\n", DTC_VERSION
);
414 void NORETURN
util_usage(const char *errmsg
, const char *synopsis
,
415 const char *short_opts
,
416 struct option
const long_opts
[],
417 const char * const opts_help
[])
419 FILE *fp
= errmsg
? stderr
: stdout
;
420 const char a_arg
[] = "<arg>";
421 size_t a_arg_len
= strlen(a_arg
) + 1;
428 "Options: -[%s]\n", synopsis
, short_opts
);
430 /* prescan the --long opt length to auto-align */
432 for (i
= 0; long_opts
[i
].name
; ++i
) {
433 /* +1 is for space between --opt and help text */
434 int l
= strlen(long_opts
[i
].name
) + 1;
435 if (long_opts
[i
].has_arg
== a_argument
)
441 for (i
= 0; long_opts
[i
].name
; ++i
) {
442 /* helps when adding new applets or options */
443 assert(opts_help
[i
] != NULL
);
445 /* first output the short flag if it has one */
446 if (long_opts
[i
].val
> '~')
449 fprintf(fp
, " -%c, ", long_opts
[i
].val
);
451 /* then the long flag */
452 if (long_opts
[i
].has_arg
== no_argument
)
453 fprintf(fp
, "--%-*s", optlen
, long_opts
[i
].name
);
455 fprintf(fp
, "--%s %s%*s", long_opts
[i
].name
, a_arg
,
456 (int)(optlen
- strlen(long_opts
[i
].name
) - a_arg_len
), "");
458 /* finally the help text */
459 fprintf(fp
, "%s\n", opts_help
[i
]);
463 fprintf(fp
, "\nError: %s\n", errmsg
);