+// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2013, Google Inc.
*
- * SPDX-License-Identifier: GPL-2.0+
- *
* Perform a grep of an FDT either displaying the source subset or producing
* a new .dtb subset which can be used as required.
*/
#include <assert.h>
#include <ctype.h>
+#include <errno.h>
#include <getopt.h>
+#include <fcntl.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <fdt_region.h>
-#include <../include/libfdt.h>
-#include <libfdt_internal.h>
+#include "fdt_host.h"
+#include "libfdt_internal.h"
/* Define DEBUG to get some debugging output on stderr */
#ifdef DEBUG
}
str = strdup(str);
+ if (!str)
+ goto err_mem;
node = malloc(sizeof(*node));
- if (!str || !node) {
- fprintf(stderr, "Out of memory\n");
- return -1;
- }
+ if (!node)
+ goto err_mem;
node->next = *headp;
node->type = type;
node->include = include;
*headp = node;
return 0;
+err_mem:
+ fprintf(stderr, "Out of memory\n");
+ return -1;
}
static bool util_is_printable_string(const void *data, int len)
* return 1 at the first match. For exclusive conditions, we must
* check that there are no matches.
*/
- for (val = disp->value_head; val; val = val->next) {
- if (!(type & val->type))
- continue;
- match = fdt_stringlist_contains(data, size, val->string);
- debug(" - val->type=%x, str='%s', match=%d\n",
- val->type, val->string, match);
- if (match && val->include) {
- debug(" - match inc %s\n", val->string);
- return 1;
+ if (data) {
+ for (val = disp->value_head; val; val = val->next) {
+ if (!(type & val->type))
+ continue;
+ match = fdt_stringlist_contains(data, size,
+ val->string);
+ debug(" - val->type=%x, str='%s', match=%d\n",
+ val->type, val->string, match);
+ if (match && val->include) {
+ debug(" - match inc %s\n", val->string);
+ return 1;
+ }
+ if (match)
+ none_match &= ~val->type;
}
- if (match)
- none_match &= ~val->type;
}
/*
*/
static int do_fdtgrep(struct display_info *disp, const char *filename)
{
- struct fdt_region *region;
+ struct fdt_region *region = NULL;
int max_regions;
int count = 100;
char path[1024];
* The first pass will count the regions, but if it is too many,
* we do another pass to actually record them.
*/
- for (i = 0; i < 3; i++) {
- region = malloc(count * sizeof(struct fdt_region));
+ for (i = 0; i < 2; i++) {
+ region = realloc(region, count * sizeof(struct fdt_region));
if (!region) {
fprintf(stderr, "Out of memory for %d regions\n",
count);
disp->flags);
if (count < 0) {
report_error("fdt_find_regions", count);
+ free(region);
return -1;
}
if (count <= max_regions)
break;
+ }
+ if (count > max_regions) {
free(region);
+ fprintf(stderr, "Internal error with fdtgrep_find_region()\n");
+ return -1;
}
/* Optionally print a list of regions */
/* Helper for getopt case statements */
#define case_USAGE_COMMON_FLAGS \
case 'h': usage(NULL); \
+ /* fallthrough */ \
case 'V': util_version(); \
+ /* fallthrough */ \
case '?': usage("unknown option");
static const char usage_short_opts[] =
switch (opt) {
case_USAGE_COMMON_FLAGS
+ /* fallthrough */
case 'a':
disp->show_addr = 1;
break;
break;
case 'C':
inc = 0;
- /* no break */
+ /* fallthrough */
case 'c':
type = FDT_IS_COMPAT;
break;
break;
case 'G':
inc = 0;
- /* no break */
+ /* fallthrough */
case 'g':
type = FDT_ANY_GLOBAL;
break;
break;
case 'N':
inc = 0;
- /* no break */
+ /* fallthrough */
case 'n':
type = FDT_IS_NODE;
break;
break;
case 'P':
inc = 0;
- /* no break */
+ /* fallthrough */
case 'p':
type = FDT_IS_PROP;
break;