diff options
author | Grant Likely <grant.likely@linaro.org> | 2014-01-21 07:54:49 -0500 |
---|---|---|
committer | Grant Likely <grant.likely@linaro.org> | 2014-01-21 08:35:11 -0500 |
commit | 73ab39b14cdf6b83da6817166f6c8a9dcc25e392 (patch) | |
tree | db578fb9a2335ed044161b40971e8a2846e11b1b /scripts/dtc | |
parent | a878b91019809b1f2276bebefd6c96567431c316 (diff) |
scripts/dtc: Update to upstream version v1.4.0
Update to the latest version of dtc with the following notable
enhancements and bug fixes:
* fdtput: expand fdt if value does not fit
* dtc/fdt{get, put}/convert-dtsv0-lexer: convert to new usage helpers
* libfdt: Add fdt_next_subnode() to permit easy subnode iteration
* utilfdt_read: pass back up the length of data read
* util_version: new helper for displaying version info
* die: constify format string arg
* utilfdt_read_err: use xmalloc funcs
* Export fdt_stringlist_contains()
* dtc: Drop the '-S is deprecated' warning
* dtc/libfdt: sparse fixes
* dtc/libfdt: introduce fdt types for annotation by endian checkers
* Fix util_is_printable_string
* dtc: srcpos_verror() should print to stderr
* libfdt: Added missing functions to shared library
Shipped bison/flex generated files were built on an Ubuntu 13.10 system.
Signed-off-by: Grant Likely <grant.likely@linaro.org>
Diffstat (limited to 'scripts/dtc')
-rw-r--r-- | scripts/dtc/dtc.c | 119 | ||||
-rw-r--r-- | scripts/dtc/dtc.h | 1 | ||||
-rw-r--r-- | scripts/dtc/srcpos.c | 6 | ||||
-rw-r--r-- | scripts/dtc/util.c | 141 | ||||
-rw-r--r-- | scripts/dtc/util.h | 107 | ||||
-rw-r--r-- | scripts/dtc/version_gen.h | 2 |
6 files changed, 294 insertions, 82 deletions
diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c index a375683c1534..e3c96536fd9d 100644 --- a/scripts/dtc/dtc.c +++ b/scripts/dtc/dtc.c | |||
@@ -21,8 +21,6 @@ | |||
21 | #include "dtc.h" | 21 | #include "dtc.h" |
22 | #include "srcpos.h" | 22 | #include "srcpos.h" |
23 | 23 | ||
24 | #include "version_gen.h" | ||
25 | |||
26 | /* | 24 | /* |
27 | * Command line options | 25 | * Command line options |
28 | */ | 26 | */ |
@@ -49,55 +47,60 @@ static void fill_fullpaths(struct node *tree, const char *prefix) | |||
49 | fill_fullpaths(child, tree->fullpath); | 47 | fill_fullpaths(child, tree->fullpath); |
50 | } | 48 | } |
51 | 49 | ||
52 | static void __attribute__ ((noreturn)) usage(void) | 50 | /* Usage related data. */ |
53 | { | 51 | static const char usage_synopsis[] = "dtc [options] <input file>"; |
54 | fprintf(stderr, "Usage:\n"); | 52 | static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv"; |
55 | fprintf(stderr, "\tdtc [options] <input file>\n"); | 53 | static struct option const usage_long_opts[] = { |
56 | fprintf(stderr, "\nOptions:\n"); | 54 | {"quiet", no_argument, NULL, 'q'}, |
57 | fprintf(stderr, "\t-h\n"); | 55 | {"in-format", a_argument, NULL, 'I'}, |
58 | fprintf(stderr, "\t\tThis help text\n"); | 56 | {"out", a_argument, NULL, 'o'}, |
59 | fprintf(stderr, "\t-q\n"); | 57 | {"out-format", a_argument, NULL, 'O'}, |
60 | fprintf(stderr, "\t\tQuiet: -q suppress warnings, -qq errors, -qqq all\n"); | 58 | {"out-version", a_argument, NULL, 'V'}, |
61 | fprintf(stderr, "\t-I <input format>\n"); | 59 | {"out-dependency", a_argument, NULL, 'd'}, |
62 | fprintf(stderr, "\t\tInput formats are:\n"); | 60 | {"reserve", a_argument, NULL, 'R'}, |
63 | fprintf(stderr, "\t\t\tdts - device tree source text\n"); | 61 | {"space", a_argument, NULL, 'S'}, |
64 | fprintf(stderr, "\t\t\tdtb - device tree blob\n"); | 62 | {"pad", a_argument, NULL, 'p'}, |
65 | fprintf(stderr, "\t\t\tfs - /proc/device-tree style directory\n"); | 63 | {"boot-cpu", a_argument, NULL, 'b'}, |
66 | fprintf(stderr, "\t-o <output file>\n"); | 64 | {"force", no_argument, NULL, 'f'}, |
67 | fprintf(stderr, "\t-O <output format>\n"); | 65 | {"include", a_argument, NULL, 'i'}, |
68 | fprintf(stderr, "\t\tOutput formats are:\n"); | 66 | {"sort", no_argument, NULL, 's'}, |
69 | fprintf(stderr, "\t\t\tdts - device tree source text\n"); | 67 | {"phandle", a_argument, NULL, 'H'}, |
70 | fprintf(stderr, "\t\t\tdtb - device tree blob\n"); | 68 | {"warning", a_argument, NULL, 'W'}, |
71 | fprintf(stderr, "\t\t\tasm - assembler source\n"); | 69 | {"error", a_argument, NULL, 'E'}, |
72 | fprintf(stderr, "\t-V <output version>\n"); | 70 | {"help", no_argument, NULL, 'h'}, |
73 | fprintf(stderr, "\t\tBlob version to produce, defaults to %d (relevant for dtb\n\t\tand asm output only)\n", DEFAULT_FDT_VERSION); | 71 | {"version", no_argument, NULL, 'v'}, |
74 | fprintf(stderr, "\t-d <output dependency file>\n"); | 72 | {NULL, no_argument, NULL, 0x0}, |
75 | fprintf(stderr, "\t-R <number>\n"); | 73 | }; |
76 | fprintf(stderr, "\t\tMake space for <number> reserve map entries (relevant for \n\t\tdtb and asm output only)\n"); | 74 | static const char * const usage_opts_help[] = { |
77 | fprintf(stderr, "\t-S <bytes>\n"); | 75 | "\n\tQuiet: -q suppress warnings, -qq errors, -qqq all", |
78 | fprintf(stderr, "\t\tMake the blob at least <bytes> long (extra space)\n"); | 76 | "\n\tInput formats are:\n" |
79 | fprintf(stderr, "\t-p <bytes>\n"); | 77 | "\t\tdts - device tree source text\n" |
80 | fprintf(stderr, "\t\tAdd padding to the blob of <bytes> long (extra space)\n"); | 78 | "\t\tdtb - device tree blob\n" |
81 | fprintf(stderr, "\t-b <number>\n"); | 79 | "\t\tfs - /proc/device-tree style directory", |
82 | fprintf(stderr, "\t\tSet the physical boot cpu\n"); | 80 | "\n\tOutput file", |
83 | fprintf(stderr, "\t-f\n"); | 81 | "\n\tOutput formats are:\n" |
84 | fprintf(stderr, "\t\tForce - try to produce output even if the input tree has errors\n"); | 82 | "\t\tdts - device tree source text\n" |
85 | fprintf(stderr, "\t-i\n"); | 83 | "\t\tdtb - device tree blob\n" |
86 | fprintf(stderr, "\t\tAdd a path to search for include files\n"); | 84 | "\t\tasm - assembler source", |
87 | fprintf(stderr, "\t-s\n"); | 85 | "\n\tBlob version to produce, defaults to %d (for dtb and asm output)", //, DEFAULT_FDT_VERSION); |
88 | fprintf(stderr, "\t\tSort nodes and properties before outputting (only useful for\n\t\tcomparing trees)\n"); | 86 | "\n\tOutput dependency file", |
89 | fprintf(stderr, "\t-v\n"); | 87 | "\n\ttMake space for <number> reserve map entries (for dtb and asm output)", |
90 | fprintf(stderr, "\t\tPrint DTC version and exit\n"); | 88 | "\n\tMake the blob at least <bytes> long (extra space)", |
91 | fprintf(stderr, "\t-H <phandle format>\n"); | 89 | "\n\tAdd padding to the blob of <bytes> long (extra space)", |
92 | fprintf(stderr, "\t\tphandle formats are:\n"); | 90 | "\n\tSet the physical boot cpu", |
93 | fprintf(stderr, "\t\t\tlegacy - \"linux,phandle\" properties only\n"); | 91 | "\n\tTry to produce output even if the input tree has errors", |
94 | fprintf(stderr, "\t\t\tepapr - \"phandle\" properties only\n"); | 92 | "\n\tAdd a path to search for include files", |
95 | fprintf(stderr, "\t\t\tboth - Both \"linux,phandle\" and \"phandle\" properties\n"); | 93 | "\n\tSort nodes and properties before outputting (useful for comparing trees)", |
96 | fprintf(stderr, "\t-W [no-]<checkname>\n"); | 94 | "\n\tValid phandle formats are:\n" |
97 | fprintf(stderr, "\t-E [no-]<checkname>\n"); | 95 | "\t\tlegacy - \"linux,phandle\" properties only\n" |
98 | fprintf(stderr, "\t\t\tenable or disable warnings and errors\n"); | 96 | "\t\tepapr - \"phandle\" properties only\n" |
99 | exit(3); | 97 | "\t\tboth - Both \"linux,phandle\" and \"phandle\" properties", |
100 | } | 98 | "\n\tEnable/disable warnings (prefix with \"no-\")", |
99 | "\n\tEnable/disable errors (prefix with \"no-\")", | ||
100 | "\n\tPrint this help and exit", | ||
101 | "\n\tPrint version and exit", | ||
102 | NULL, | ||
103 | }; | ||
101 | 104 | ||
102 | int main(int argc, char *argv[]) | 105 | int main(int argc, char *argv[]) |
103 | { | 106 | { |
@@ -118,8 +121,7 @@ int main(int argc, char *argv[]) | |||
118 | minsize = 0; | 121 | minsize = 0; |
119 | padsize = 0; | 122 | padsize = 0; |
120 | 123 | ||
121 | while ((opt = getopt(argc, argv, "hI:O:o:V:d:R:S:p:fqb:i:vH:sW:E:")) | 124 | while ((opt = util_getopt_long()) != EOF) { |
122 | != EOF) { | ||
123 | switch (opt) { | 125 | switch (opt) { |
124 | case 'I': | 126 | case 'I': |
125 | inform = optarg; | 127 | inform = optarg; |
@@ -158,8 +160,7 @@ int main(int argc, char *argv[]) | |||
158 | srcfile_add_search_path(optarg); | 160 | srcfile_add_search_path(optarg); |
159 | break; | 161 | break; |
160 | case 'v': | 162 | case 'v': |
161 | printf("Version: %s\n", DTC_VERSION); | 163 | util_version(); |
162 | exit(0); | ||
163 | case 'H': | 164 | case 'H': |
164 | if (streq(optarg, "legacy")) | 165 | if (streq(optarg, "legacy")) |
165 | phandle_format = PHANDLE_LEGACY; | 166 | phandle_format = PHANDLE_LEGACY; |
@@ -185,13 +186,14 @@ int main(int argc, char *argv[]) | |||
185 | break; | 186 | break; |
186 | 187 | ||
187 | case 'h': | 188 | case 'h': |
189 | usage(NULL); | ||
188 | default: | 190 | default: |
189 | usage(); | 191 | usage("unknown option"); |
190 | } | 192 | } |
191 | } | 193 | } |
192 | 194 | ||
193 | if (argc > (optind+1)) | 195 | if (argc > (optind+1)) |
194 | usage(); | 196 | usage("missing files"); |
195 | else if (argc < (optind+1)) | 197 | else if (argc < (optind+1)) |
196 | arg = "-"; | 198 | arg = "-"; |
197 | else | 199 | else |
@@ -201,9 +203,6 @@ int main(int argc, char *argv[]) | |||
201 | if (minsize && padsize) | 203 | if (minsize && padsize) |
202 | die("Can't set both -p and -S\n"); | 204 | die("Can't set both -p and -S\n"); |
203 | 205 | ||
204 | if (minsize) | ||
205 | fprintf(stderr, "DTC: Use of \"-S\" is deprecated; it will be removed soon, use \"-p\" instead\n"); | ||
206 | |||
207 | if (depname) { | 206 | if (depname) { |
208 | depfile = fopen(depname, "w"); | 207 | depfile = fopen(depname, "w"); |
209 | if (!depfile) | 208 | if (!depfile) |
diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h index 3e42a071070e..264a20cf66a8 100644 --- a/scripts/dtc/dtc.h +++ b/scripts/dtc/dtc.h | |||
@@ -66,7 +66,6 @@ typedef uint32_t cell_t; | |||
66 | #define strneq(a, b, n) (strncmp((a), (b), (n)) == 0) | 66 | #define strneq(a, b, n) (strncmp((a), (b), (n)) == 0) |
67 | 67 | ||
68 | #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) | 68 | #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) |
69 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) | ||
70 | 69 | ||
71 | /* Data blobs */ | 70 | /* Data blobs */ |
72 | enum markertype { | 71 | enum markertype { |
diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c index 246ab4bc0d9d..c20bc5315bc1 100644 --- a/scripts/dtc/srcpos.c +++ b/scripts/dtc/srcpos.c | |||
@@ -297,9 +297,9 @@ srcpos_verror(struct srcpos *pos, char const *fmt, va_list va) | |||
297 | 297 | ||
298 | srcstr = srcpos_string(pos); | 298 | srcstr = srcpos_string(pos); |
299 | 299 | ||
300 | fprintf(stdout, "Error: %s ", srcstr); | 300 | fprintf(stderr, "Error: %s ", srcstr); |
301 | vfprintf(stdout, fmt, va); | 301 | vfprintf(stderr, fmt, va); |
302 | fprintf(stdout, "\n"); | 302 | fprintf(stderr, "\n"); |
303 | } | 303 | } |
304 | 304 | ||
305 | void | 305 | void |
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 | } | ||
diff --git a/scripts/dtc/util.h b/scripts/dtc/util.h index c8eb45d9f04b..8f40b4499359 100644 --- a/scripts/dtc/util.h +++ b/scripts/dtc/util.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define _UTIL_H | 2 | #define _UTIL_H |
3 | 3 | ||
4 | #include <stdarg.h> | 4 | #include <stdarg.h> |
5 | #include <getopt.h> | ||
5 | 6 | ||
6 | /* | 7 | /* |
7 | * Copyright 2011 The Chromium Authors, All Rights Reserved. | 8 | * Copyright 2011 The Chromium Authors, All Rights Reserved. |
@@ -23,7 +24,9 @@ | |||
23 | * USA | 24 | * USA |
24 | */ | 25 | */ |
25 | 26 | ||
26 | static inline void __attribute__((noreturn)) die(char * str, ...) | 27 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) |
28 | |||
29 | static inline void __attribute__((noreturn)) die(const char *str, ...) | ||
27 | { | 30 | { |
28 | va_list ap; | 31 | va_list ap; |
29 | 32 | ||
@@ -57,12 +60,14 @@ extern char *xstrdup(const char *s); | |||
57 | extern char *join_path(const char *path, const char *name); | 60 | extern char *join_path(const char *path, const char *name); |
58 | 61 | ||
59 | /** | 62 | /** |
60 | * Check a string of a given length to see if it is all printable and | 63 | * Check a property of a given length to see if it is all printable and |
61 | * has a valid terminator. | 64 | * has a valid terminator. The property can contain either a single string, |
65 | * or multiple strings each of non-zero length. | ||
62 | * | 66 | * |
63 | * @param data The string to check | 67 | * @param data The string to check |
64 | * @param len The string length including terminator | 68 | * @param len The string length including terminator |
65 | * @return 1 if a valid printable string, 0 if not */ | 69 | * @return 1 if a valid printable string, 0 if not |
70 | */ | ||
66 | int util_is_printable_string(const void *data, int len); | 71 | int util_is_printable_string(const void *data, int len); |
67 | 72 | ||
68 | /* | 73 | /* |
@@ -83,6 +88,13 @@ char get_escape_char(const char *s, int *i); | |||
83 | char *utilfdt_read(const char *filename); | 88 | char *utilfdt_read(const char *filename); |
84 | 89 | ||
85 | /** | 90 | /** |
91 | * Like utilfdt_read(), but also passes back the size of the file read. | ||
92 | * | ||
93 | * @param len If non-NULL, the amount of data we managed to read | ||
94 | */ | ||
95 | char *utilfdt_read_len(const char *filename, off_t *len); | ||
96 | |||
97 | /** | ||
86 | * Read a device tree file into a buffer. Does not report errors, but only | 98 | * Read a device tree file into a buffer. Does not report errors, but only |
87 | * returns them. The value returned can be passed to strerror() to obtain | 99 | * returns them. The value returned can be passed to strerror() to obtain |
88 | * an error message for the user. | 100 | * an error message for the user. |
@@ -93,6 +105,12 @@ char *utilfdt_read(const char *filename); | |||
93 | */ | 105 | */ |
94 | int utilfdt_read_err(const char *filename, char **buffp); | 106 | int utilfdt_read_err(const char *filename, char **buffp); |
95 | 107 | ||
108 | /** | ||
109 | * Like utilfdt_read_err(), but also passes back the size of the file read. | ||
110 | * | ||
111 | * @param len If non-NULL, the amount of data we managed to read | ||
112 | */ | ||
113 | int utilfdt_read_err_len(const char *filename, char **buffp, off_t *len); | ||
96 | 114 | ||
97 | /** | 115 | /** |
98 | * Write a device tree buffer to a file. This will report any errors on | 116 | * Write a device tree buffer to a file. This will report any errors on |
@@ -148,6 +166,85 @@ int utilfdt_decode_type(const char *fmt, int *type, int *size); | |||
148 | #define USAGE_TYPE_MSG \ | 166 | #define USAGE_TYPE_MSG \ |
149 | "<type>\ts=string, i=int, u=unsigned, x=hex\n" \ | 167 | "<type>\ts=string, i=int, u=unsigned, x=hex\n" \ |
150 | "\tOptional modifier prefix:\n" \ | 168 | "\tOptional modifier prefix:\n" \ |
151 | "\t\thh or b=byte, h=2 byte, l=4 byte (default)\n"; | 169 | "\t\thh or b=byte, h=2 byte, l=4 byte (default)"; |
170 | |||
171 | /** | ||
172 | * Print property data in a readable format to stdout | ||
173 | * | ||
174 | * Properties that look like strings will be printed as strings. Otherwise | ||
175 | * the data will be displayed either as cells (if len is a multiple of 4 | ||
176 | * bytes) or bytes. | ||
177 | * | ||
178 | * If len is 0 then this function does nothing. | ||
179 | * | ||
180 | * @param data Pointers to property data | ||
181 | * @param len Length of property data | ||
182 | */ | ||
183 | void utilfdt_print_data(const char *data, int len); | ||
184 | |||
185 | /** | ||
186 | * Show source version and exit | ||
187 | */ | ||
188 | void util_version(void) __attribute__((noreturn)); | ||
189 | |||
190 | /** | ||
191 | * Show usage and exit | ||
192 | * | ||
193 | * This helps standardize the output of various utils. You most likely want | ||
194 | * to use the usage() helper below rather than call this. | ||
195 | * | ||
196 | * @param errmsg If non-NULL, an error message to display | ||
197 | * @param synopsis The initial example usage text (and possible examples) | ||
198 | * @param short_opts The string of short options | ||
199 | * @param long_opts The structure of long options | ||
200 | * @param opts_help An array of help strings (should align with long_opts) | ||
201 | */ | ||
202 | void util_usage(const char *errmsg, const char *synopsis, | ||
203 | const char *short_opts, struct option const long_opts[], | ||
204 | const char * const opts_help[]) __attribute__((noreturn)); | ||
205 | |||
206 | /** | ||
207 | * Show usage and exit | ||
208 | * | ||
209 | * If you name all your usage variables with usage_xxx, then you can call this | ||
210 | * help macro rather than expanding all arguments yourself. | ||
211 | * | ||
212 | * @param errmsg If non-NULL, an error message to display | ||
213 | */ | ||
214 | #define usage(errmsg) \ | ||
215 | util_usage(errmsg, usage_synopsis, usage_short_opts, \ | ||
216 | usage_long_opts, usage_opts_help) | ||
217 | |||
218 | /** | ||
219 | * Call getopt_long() with standard options | ||
220 | * | ||
221 | * Since all util code runs getopt in the same way, provide a helper. | ||
222 | */ | ||
223 | #define util_getopt_long() getopt_long(argc, argv, usage_short_opts, \ | ||
224 | usage_long_opts, NULL) | ||
225 | |||
226 | /* Helper for aligning long_opts array */ | ||
227 | #define a_argument required_argument | ||
228 | |||
229 | /* Helper for usage_short_opts string constant */ | ||
230 | #define USAGE_COMMON_SHORT_OPTS "hV" | ||
231 | |||
232 | /* Helper for usage_long_opts option array */ | ||
233 | #define USAGE_COMMON_LONG_OPTS \ | ||
234 | {"help", no_argument, NULL, 'h'}, \ | ||
235 | {"version", no_argument, NULL, 'V'}, \ | ||
236 | {NULL, no_argument, NULL, 0x0} | ||
237 | |||
238 | /* Helper for usage_opts_help array */ | ||
239 | #define USAGE_COMMON_OPTS_HELP \ | ||
240 | "Print this help and exit", \ | ||
241 | "Print version and exit", \ | ||
242 | NULL | ||
243 | |||
244 | /* Helper for getopt case statements */ | ||
245 | #define case_USAGE_COMMON_FLAGS \ | ||
246 | case 'h': usage(NULL); \ | ||
247 | case 'V': util_version(); \ | ||
248 | case '?': usage("unknown option"); | ||
152 | 249 | ||
153 | #endif /* _UTIL_H */ | 250 | #endif /* _UTIL_H */ |
diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h index 6158b867df99..e0b82fe8e7de 100644 --- a/scripts/dtc/version_gen.h +++ b/scripts/dtc/version_gen.h | |||
@@ -1 +1 @@ | |||
#define DTC_VERSION "DTC 1.2.0-g37c0b6a0" | #define DTC_VERSION "DTC 1.4.0" | ||