aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml39
-rw-r--r--.github/workflows/build.yml1
-rw-r--r--.gitlab-ci.yml65
-rw-r--r--MANIFEST.in12
-rw-r--r--Makefile70
-rw-r--r--checks.c2
-rw-r--r--data.c47
-rw-r--r--dtc-lexer.l15
-rw-r--r--dtc.h3
-rw-r--r--dtdiff2
-rw-r--r--fdtput.c38
-rw-r--r--libfdt/TODO1
-rw-r--r--libfdt/fdt.h4
-rw-r--r--libfdt/libfdt.h214
-rw-r--r--libfdt/meson.build35
-rw-r--r--livetree.c2
-rw-r--r--meson.build7
-rw-r--r--meson_options.txt2
-rw-r--r--pylibfdt/Makefile.pylibfdt30
-rw-r--r--pylibfdt/meson.build28
-rw-r--r--pyproject.toml33
-rwxr-xr-xscripts/install-deps.sh10
-rwxr-xr-xsetup.py97
-rw-r--r--srcpos.c33
-rw-r--r--srcpos.h1
-rwxr-xr-xtests/fdtget-runtest.sh2
-rw-r--r--tests/meson.build2
-rwxr-xr-xtests/run_tests.sh13
-rw-r--r--tests/testdata.h6
-rw-r--r--treesource.c52
30 files changed, 598 insertions, 268 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
new file mode 100644
index 0000000..825aeb7
--- /dev/null
+++ b/.cirrus.yml
@@ -0,0 +1,39 @@
+# FreeBSD build with multiple versions
+freebsd_versions_task:
+ name: FreeBSD $FREEBSD_VERSION make build
+ freebsd_instance:
+ image_family: $FREEBSD_IMAGE
+ matrix:
+ - env:
+ FREEBSD_VERSION: "13.5"
+ FREEBSD_IMAGE: freebsd-13-5
+ - env:
+ FREEBSD_VERSION: "14.3"
+ FREEBSD_IMAGE: freebsd-14-3
+ install_script:
+ - pkg install -y git gmake flex bison python3 py312-setuptools swig libyaml pkgconf
+ build_script:
+ - gmake
+ check_script:
+ - gmake check
+
+# FreeBSD meson builds with multiple versions
+freebsd_meson_versions_task:
+ name: FreeBSD $FREEBSD_VERSION meson build
+ freebsd_instance:
+ image_family: $FREEBSD_IMAGE
+ matrix:
+ - env:
+ FREEBSD_VERSION: "13.5"
+ FREEBSD_IMAGE: freebsd-13-5
+ - env:
+ FREEBSD_VERSION: "14.3"
+ FREEBSD_IMAGE: freebsd-14-3
+ install_script:
+ - pkg install -y git meson ninja flex bison python3 py312-setuptools swig libyaml pkgconf
+ setup_script:
+ - meson setup -D python=enabled -D yaml=enabled build
+ build_script:
+ - meson compile -C build
+ test_script:
+ - if ! meson test -C build; then cat build/meson-logs/testlog.txt; false; fi
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index a030ae6..b6e0a9c 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -4,6 +4,7 @@ name: Build test
push:
branches:
- main
+ - ci
pull_request:
branches:
- main
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..f5b1fb1
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,65 @@
+stages:
+ - build
+
+variables:
+ GIT_DEPTH: 1
+
+workflow:
+ rules:
+ - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "main"
+ - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "ci"
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
+
+# Linux builds with make
+.build-make-template: &build-make-template
+ stage: build
+ before_script:
+ - ./scripts/install-deps.sh
+ script:
+ - make
+ - make check
+ interruptible: true
+
+build-make-alpine:
+ <<: *build-make-template
+ image: alpine:latest
+
+build-make-archlinux:
+ <<: *build-make-template
+ image: archlinux:latest
+
+build-make-fedora:
+ <<: *build-make-template
+ image: fedora:latest
+
+build-make-ubuntu:
+ <<: *build-make-template
+ image: ubuntu:latest
+
+# Linux builds with meson
+.build-meson-template: &build-meson-template
+ stage: build
+ before_script:
+ - ./scripts/install-deps.sh
+ script:
+ - meson setup -D python=enabled -D yaml=enabled build
+ - meson compile -C build
+ - if ! meson test -C build; then cat build/meson-logs/testlog.txt; false; fi
+ interruptible: true
+
+build-meson-alpine:
+ <<: *build-meson-template
+ image: alpine:latest
+
+build-meson-archlinux:
+ <<: *build-meson-template
+ image: archlinux:latest
+
+build-meson-fedora:
+ <<: *build-meson-template
+ image: fedora:latest
+
+build-meson-ubuntu:
+ <<: *build-meson-template
+ image: ubuntu:latest
+
diff --git a/MANIFEST.in b/MANIFEST.in
deleted file mode 100644
index 904d124..0000000
--- a/MANIFEST.in
+++ /dev/null
@@ -1,12 +0,0 @@
-# SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
-
-global-exclude *
-include README.md
-include GPL
-include BSD-2-Clause
-include setup.py
-include pylibfdt/libfdt.i
-include libfdt/libfdt.h
-include libfdt/fdt.h
-include libfdt/libfdt_env.h
-include VERSION.txt
diff --git a/Makefile b/Makefile
index f1f0ab3..83d8220 100644
--- a/Makefile
+++ b/Makefile
@@ -3,6 +3,10 @@
# Device Tree Compiler
#
+$(warning WARNING: Building dtc using make is deprecated, in favour of using Meson (https://mesonbuild.com))
+$(warning )
+$(warning Use `meson setup builddir/ && meson compile -C builddir/` to build, `meson test -C builddir/` to test, or `meson configure` to see build options.)
+
#
# Version information will be constructed in this order:
# DTC_VERSION release version as MAJOR.MINOR.PATCH
@@ -20,14 +24,16 @@ ASSUME_MASK ?= 0
CPPFLAGS = -I libfdt -I . -DFDT_ASSUME_MASK=$(ASSUME_MASK)
WARNINGS = -Wall -Wpointer-arith -Wcast-qual -Wnested-externs -Wsign-compare \
-Wstrict-prototypes -Wmissing-prototypes -Wredundant-decls -Wshadow \
- -Wsuggest-attribute=format -Wwrite-strings
+ -Wwrite-strings
+ifeq ($(shell $(CC) --version | grep -q gcc && echo gcc),gcc)
+WARNINGS += -Wsuggest-attribute=format
+endif
CFLAGS = -g -Os $(SHAREDLIB_CFLAGS) -Werror $(WARNINGS) $(EXTRA_CFLAGS)
BISON = bison
LEX = flex
SWIG = swig
PKG_CONFIG ?= pkg-config
-PYTHON ?= python3
INSTALL = install
INSTALL_PROGRAM = $(INSTALL)
@@ -43,8 +49,6 @@ INCLUDEDIR = $(PREFIX)/include
HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
sed -e 's/\(cygwin\|msys\).*/\1/')
-NO_PYTHON ?= 0
-
NO_VALGRIND := $(shell $(PKG_CONFIG) --exists valgrind; echo $$?)
ifeq ($(NO_VALGRIND),1)
CPPFLAGS += -DNO_VALGRIND
@@ -64,6 +68,8 @@ else
CFLAGS += $(shell $(PKG_CONFIG) --cflags yaml-0.1)
endif
+HAS_VERSION_SCRIPT := $(shell echo 'int main(){}' | $(CC) -Wl,--version-script=/dev/null -x c - -o /dev/null 2>/dev/null && echo y)
+
ifeq ($(HOSTOS),darwin)
SHAREDLIB_EXT = dylib
SHAREDLIB_CFLAGS = -fPIC
@@ -71,11 +77,15 @@ SHAREDLIB_LDFLAGS = -fPIC -dynamiclib -Wl,-install_name -Wl,
else ifeq ($(HOSTOS),$(filter $(HOSTOS),msys cygwin))
SHAREDLIB_EXT = so
SHAREDLIB_CFLAGS =
-SHAREDLIB_LDFLAGS = -shared -Wl,--version-script=$(LIBFDT_version) -Wl,-soname,
+SHAREDLIB_LDFLAGS = -shared -Wl,-soname,
else
SHAREDLIB_EXT = so
SHAREDLIB_CFLAGS = -fPIC
-SHAREDLIB_LDFLAGS = -fPIC -shared -Wl,--version-script=$(LIBFDT_version) -Wl,-soname,
+SHAREDLIB_LDFLAGS = -fPIC -shared -Wl,-soname,
+endif
+
+ifeq ($(HAS_VERSION_SCRIPT),y)
+SHAREDLIB_LDFLAGS += -Wl,--version-script=$(LIBFDT_version)
endif
#
@@ -154,29 +164,6 @@ SCRIPTS = dtdiff
all: $(BIN) libfdt
-# We need both Python and swig to build/install pylibfdt.
-# This builds the given make ${target} if those deps are found.
-check_python_deps = \
- if $(PKG_CONFIG) --cflags $(PYTHON) >/dev/null 2>&1; then \
- if which swig >/dev/null 2>&1; then \
- can_build=yes; \
- fi; \
- fi; \
- if [ "$${can_build}" = "yes" ]; then \
- $(MAKE) $${target}; \
- else \
- echo "\#\# Skipping pylibfdt (install python dev and swig to build)"; \
- fi ;
-
-.PHONY: maybe_pylibfdt
-maybe_pylibfdt: FORCE
- target=pylibfdt; $(check_python_deps)
-
-ifeq ($(NO_PYTHON),0)
-all: maybe_pylibfdt
-endif
-
-
ifneq ($(DEPTARGETS),)
ifneq ($(MAKECMDGOALS),libfdt)
-include $(DTC_OBJS:%.o=%.d)
@@ -250,14 +237,6 @@ install-includes:
install: install-bin install-lib install-includes
-.PHONY: maybe_install_pylibfdt
-maybe_install_pylibfdt: FORCE
- target=install_pylibfdt; $(check_python_deps)
-
-ifeq ($(NO_PYTHON),0)
-install: maybe_install_pylibfdt
-endif
-
$(VERSION_FILE): Makefile FORCE
$(call filechk,version)
@@ -284,16 +263,6 @@ dist:
#
-# Rules for pylibfdt
-#
-PYLIBFDT_dir = pylibfdt
-
-include $(PYLIBFDT_dir)/Makefile.pylibfdt
-
-.PHONY: pylibfdt
-pylibfdt: $(PYLIBFDT_dir)/_libfdt.so
-
-#
# Release signing and uploading
# This is for maintainer convenience, don't try this at home.
#
@@ -326,9 +295,6 @@ TESTS_BIN += fdtput
TESTS_BIN += fdtget
TESTS_BIN += fdtdump
TESTS_BIN += fdtoverlay
-ifeq ($(NO_PYTHON),0)
-TESTS_PYLIBFDT += maybe_pylibfdt
-endif
ifneq ($(MAKECMDGOALS),libfdt)
include tests/Makefile.tests
@@ -340,7 +306,7 @@ endif
STD_CLEANFILES = *~ *.o *.$(SHAREDLIB_EXT) *.d *.a *.i *.s core a.out vgcore.* \
*.tab.[ch] *.lex.c *.output
-clean: libfdt_clean pylibfdt_clean tests_clean
+clean: libfdt_clean tests_clean
@$(VECHO) CLEAN
rm -f $(STD_CLEANFILES)
rm -f $(VERSION_FILE)
@@ -360,7 +326,7 @@ clean: libfdt_clean pylibfdt_clean tests_clean
%.o: %.S
@$(VECHO) AS $@
- $(CC) $(CPPFLAGS) $(AFLAGS) -D__ASSEMBLY__ -o $@ -c $<
+ $(CC) $(CPPFLAGS) $(AFLAGS) -o $@ -c $<
%.d: %.c
@$(VECHO) DEP $<
diff --git a/checks.c b/checks.c
index 123f2eb..7e3fed5 100644
--- a/checks.c
+++ b/checks.c
@@ -1024,7 +1024,7 @@ static void check_i2c_bus_bridge(struct check *c, struct dt_info *dti, struct no
} else if (strprefixeq(node->name, node->basenamelen, "i2c")) {
struct node *child;
for_each_child(node, child) {
- if (strprefixeq(child->name, node->basenamelen, "i2c-bus"))
+ if (strprefixeq(child->name, child->basenamelen, "i2c-bus"))
return;
}
node->bus = &i2c_bus;
diff --git a/data.c b/data.c
index 1473423..5b25aa0 100644
--- a/data.c
+++ b/data.c
@@ -228,11 +228,7 @@ struct data data_add_marker(struct data d, enum markertype type, char *ref)
{
struct marker *m;
- m = xmalloc(sizeof(*m));
- m->offset = d.len;
- m->type = type;
- m->ref = ref;
- m->next = NULL;
+ m = alloc_marker(d.len, type, ref);
return data_append_markers(d, m);
}
@@ -254,3 +250,44 @@ bool data_is_one_string(struct data d)
return true;
}
+
+struct data data_insert_data(struct data d, struct marker *m, struct data old)
+{
+ unsigned int offset = m->offset;
+ struct marker *next = m->next;
+ struct marker *marker;
+ struct data new_data;
+ char *ref;
+
+ new_data = data_insert_at_marker(d, m, old.val, old.len);
+
+ /* Copy all markers from old value */
+ marker = old.markers;
+ for_each_marker(marker) {
+ ref = NULL;
+
+ if (marker->ref)
+ ref = xstrdup(marker->ref);
+
+ m->next = alloc_marker(marker->offset + offset, marker->type,
+ ref);
+ m = m->next;
+ }
+ m->next = next;
+
+ return new_data;
+}
+
+struct marker *alloc_marker(unsigned int offset, enum markertype type,
+ char *ref)
+{
+ struct marker *m;
+
+ m = xmalloc(sizeof(*m));
+ m->offset = offset;
+ m->type = type;
+ m->ref = ref;
+ m->next = NULL;
+
+ return m;
+}
diff --git a/dtc-lexer.l b/dtc-lexer.l
index de60a70..15d585c 100644
--- a/dtc-lexer.l
+++ b/dtc-lexer.l
@@ -151,6 +151,21 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
return DT_LABEL;
}
+<V1>{LABEL} {
+ /* Missed includes or macro definitions while
+ * preprocessing can lead to unexpected identifiers in
+ * the input. Report a slightly more informative error
+ * in this case */
+
+ lexical_error("Unexpected '%s'", yytext);
+
+ /* Treat it as a literal which often generates further
+ * useful error messages */
+
+ yylval.integer = 0;
+ return DT_LITERAL;
+ }
+
<V1>([0-9]+|0[xX][0-9a-fA-F]+)(U|L|UL|LL|ULL)? {
char *e;
DPRINT("Integer Literal: '%s'\n", yytext);
diff --git a/dtc.h b/dtc.h
index 9acf071..3a220b9 100644
--- a/dtc.h
+++ b/dtc.h
@@ -182,7 +182,10 @@ struct data data_append_addr(struct data d, uint64_t addr);
struct data data_append_byte(struct data d, uint8_t byte);
struct data data_append_zeroes(struct data d, int len);
struct data data_append_align(struct data d, int align);
+struct data data_insert_data(struct data d, struct marker *m, struct data old);
+struct marker *alloc_marker(unsigned int offset, enum markertype type,
+ char *ref);
struct data data_add_marker(struct data d, enum markertype type, char *ref);
bool data_is_one_string(struct data d);
diff --git a/dtdiff b/dtdiff
index cdbf079..841b085 100644
--- a/dtdiff
+++ b/dtdiff
@@ -17,7 +17,7 @@ source_and_sort () {
*.dts)
IFORMAT=dts
;;
- *.dtb)
+ *.dtb|*.dtbo)
IFORMAT=dtb
;;
esac
diff --git a/fdtput.c b/fdtput.c
index c2fecf4..05f2b93 100644
--- a/fdtput.c
+++ b/fdtput.c
@@ -9,6 +9,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <errno.h>
#include <libfdt.h>
@@ -64,16 +65,12 @@ static int encode_value(struct display_info *disp, char **arg, int arg_count,
int len; /* length of this cell/string/byte */
int ival;
int upto; /* the number of bytes we have written to buf */
- char fmt[3];
upto = 0;
if (disp->verbose)
fprintf(stderr, "Decoding value:\n");
- fmt[0] = '%';
- fmt[1] = disp->type ? disp->type : 'd';
- fmt[2] = '\0';
for (; arg_count > 0; arg++, arg_count--, upto += len) {
/* assume integer unless told otherwise */
if (disp->type == 's')
@@ -94,7 +91,34 @@ static int encode_value(struct display_info *disp, char **arg, int arg_count,
fprintf(stderr, "\tstring: '%s'\n", ptr);
} else {
fdt32_t *iptr = (fdt32_t *)ptr;
- sscanf(*arg, fmt, &ival);
+ char *endptr;
+
+ errno = 0;
+ switch (disp->type) {
+ case 'x':
+ ival = strtoul(*arg, &endptr, 16);
+ break;
+ case 'o':
+ ival = strtoul(*arg, &endptr, 8);
+ break;
+ case 'i':
+ ival = strtol(*arg, &endptr, 0);
+ break;
+ case 'u':
+ ival = strtoul(*arg, &endptr, 0);
+ break;
+ default: /* 0 or 'd' */
+ ival = strtol(*arg, &endptr, 10);
+ }
+
+ if (*endptr != '\0' || errno) {
+ if (disp->verbose) {
+ fprintf(stderr,
+ "Couldn't parse \"%s\" as an integer\n",
+ *arg);
+ }
+ return -1;
+ }
if (len == 4)
*iptr = cpu_to_fdt32(ival);
else
@@ -389,8 +413,8 @@ static struct option const usage_long_opts[] = {
USAGE_COMMON_LONG_OPTS,
};
static const char * const usage_opts_help[] = {
- "Create nodes if they don't already exist",
- "Delete nodes (and any subnodes) if they already exist",
+ "Create nodes",
+ "Delete nodes (and any subnodes)",
"Delete properties if they already exist",
"Automatically create nodes as needed for the node path",
"Type of data",
diff --git a/libfdt/TODO b/libfdt/TODO
index 288437e..ea2ef92 100644
--- a/libfdt/TODO
+++ b/libfdt/TODO
@@ -1,3 +1,2 @@
- Tree traversal functions
- Graft function
-- Complete libfdt.h documenting comments
diff --git a/libfdt/fdt.h b/libfdt/fdt.h
index 0c91aa7..a07abfc 100644
--- a/libfdt/fdt.h
+++ b/libfdt/fdt.h
@@ -7,7 +7,7 @@
* Copyright 2012 Kim Phillips, Freescale Semiconductor.
*/
-#ifndef __ASSEMBLY__
+#ifndef __ASSEMBLER__
struct fdt_header {
fdt32_t magic; /* magic word FDT_MAGIC */
@@ -45,7 +45,7 @@ struct fdt_property {
char data[];
};
-#endif /* !__ASSEMBLY */
+#endif /* !__ASSEMBLER__ */
#define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */
#define FDT_TAGSIZE sizeof(fdt32_t)
diff --git a/libfdt/libfdt.h b/libfdt/libfdt.h
index b5e7200..7a10f66 100644
--- a/libfdt/libfdt.h
+++ b/libfdt/libfdt.h
@@ -116,6 +116,20 @@ extern "C" {
/* Low-level functions (you probably don't need these) */
/**********************************************************************/
+/**
+ * fdt_offset_ptr - safely get a byte range within the device tree blob
+ * @fdt: Pointer to the device tree blob
+ * @offset: Offset within the blob to the desired byte range
+ * @checklen: Required length of the byte range
+ *
+ * fdt_offset_ptr() returns a pointer to the byte range of length @checklen at
+ * the given @offset within the device tree blob, after verifying that the byte
+ * range fits entirely within the blob and does not overflow.
+ *
+ * returns:
+ * pointer to the byte range, on success
+ * NULL, if the requested range does not fit within the blob
+ */
#ifndef SWIG /* This function is not useful in Python */
const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen);
#endif
@@ -124,6 +138,20 @@ static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen);
}
+/**
+ * fdt_next_tag - get next tag in the device tree
+ * @fdt: Pointer to the device tree blob
+ * @offset: Offset within the blob to start searching
+ * @nextoffset: Pointer to variable to store the offset of the next tag
+ *
+ * fdt_next_tag() returns the tag type of the next tag in the device tree
+ * blob starting from the given @offset. If @nextoffset is non-NULL, it will
+ * be set to the offset immediately following the tag.
+ *
+ * returns:
+ * the tag type (FDT_BEGIN_NODE, FDT_END_NODE, FDT_PROP, FDT_NOP, FDT_END),
+ * FDT_END, if offset is out of bounds
+ */
uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
/*
@@ -334,6 +362,23 @@ int fdt_move(const void *fdt, void *buf, int bufsize);
/* Read-only functions */
/**********************************************************************/
+/**
+ * fdt_check_full - check device tree validity
+ * @fdt: pointer to the device tree blob
+ * @bufsize: size of the buffer containing the device tree
+ *
+ * fdt_check_full() checks that the given buffer contains a valid
+ * flattened device tree and that the tree structure is internally
+ * consistent. This is a more thorough check than fdt_check_header().
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
int fdt_check_full(const void *fdt, size_t bufsize);
/**
@@ -1540,10 +1585,90 @@ int fdt_create_with_flags(void *buf, int bufsize, uint32_t flags);
*/
int fdt_create(void *buf, int bufsize);
+/**
+ * fdt_resize - move and resize a device tree in sequential write state
+ * @fdt: Pointer to the device tree to resize
+ * @buf: Buffer where resized tree should be placed
+ * @bufsize: Size of the buffer at @buf
+ *
+ * fdt_resize() moves the device tree blob from @fdt to @buf and
+ * resizes it to fit in the new buffer size.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, if @bufsize is too small
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE, standard meanings
+ */
int fdt_resize(void *fdt, void *buf, int bufsize);
+
+/**
+ * fdt_add_reservemap_entry - add an entry to the memory reserve map
+ * @fdt: Pointer to the device tree blob
+ * @addr: Start address of the reserve map entry
+ * @size: Size of the reserved region
+ *
+ * fdt_add_reservemap_entry() adds a memory reserve map entry to the
+ * device tree blob during the sequential write process. This function
+ * can only be called after fdt_create() and before fdt_finish_reservemap().
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, if there is insufficient space in the blob
+ * -FDT_ERR_BADSTATE, if not in the correct sequential write state
+ */
int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
+
+/**
+ * fdt_finish_reservemap - complete the memory reserve map
+ * @fdt: Pointer to the device tree blob
+ *
+ * fdt_finish_reservemap() completes the memory reserve map section
+ * of the device tree blob during sequential write. After calling this
+ * function, no more reserve map entries can be added and the blob
+ * moves to the structure creation phase.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_BADSTATE, if not in the correct sequential write state
+ */
int fdt_finish_reservemap(void *fdt);
+
+/**
+ * fdt_begin_node - start creation of a new node
+ * @fdt: Pointer to the device tree blob
+ * @name: Name of the node to create
+ *
+ * fdt_begin_node() starts the creation of a new node with the given
+ * @name during sequential write. After calling this function, properties
+ * can be added with fdt_property() and subnodes can be created with
+ * additional fdt_begin_node() calls. The node must be completed with
+ * fdt_end_node().
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, if there is insufficient space in the blob
+ * -FDT_ERR_BADSTATE, if not in the correct sequential write state
+ */
int fdt_begin_node(void *fdt, const char *name);
+
+/**
+ * fdt_property - add a property to the current node
+ * @fdt: Pointer to the device tree blob
+ * @name: Name of the property to add
+ * @val: Pointer to the property value
+ * @len: Length of the property value in bytes
+ *
+ * fdt_property() adds a property with the given @name and value to
+ * the current node during sequential write. This function can only
+ * be called between fdt_begin_node() and fdt_end_node().
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, if there is insufficient space in the blob
+ * -FDT_ERR_BADSTATE, if not currently within a node
+ */
int fdt_property(void *fdt, const char *name, const void *val, int len);
static inline int fdt_property_u32(void *fdt, const char *name, uint32_t val)
{
@@ -1580,15 +1705,94 @@ int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp);
#define fdt_property_string(fdt, name, str) \
fdt_property(fdt, name, str, strlen(str)+1)
+
+/**
+ * fdt_end_node - complete the current node
+ * @fdt: Pointer to the device tree blob
+ *
+ * fdt_end_node() completes the current node during sequential write. This
+ * function must be called to close each node started with
+ * fdt_begin_node(). After calling this function, no more properties or subnodes
+ * can be added to the node.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_BADSTATE, if not currently within a node
+ */
int fdt_end_node(void *fdt);
+
+/**
+ * fdt_finish - complete device tree creation
+ * @fdt: Pointer to the device tree blob
+ *
+ * fdt_finish() completes the device tree creation process started with
+ * fdt_create(). This function finalizes the device tree blob and makes it ready
+ * for use. After calling this function, the blob is complete and can be used
+ * with libfdt read-only and read-write functions, but not with sequential write
+ * functions.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_BADSTATE, if the sequential write process is incomplete
+ */
int fdt_finish(void *fdt);
/**********************************************************************/
/* Read-write functions */
/**********************************************************************/
+/**
+ * fdt_create_empty_tree - create an empty device tree
+ * @buf: Buffer where the empty tree should be created
+ * @bufsize: Size of the buffer at @buf
+ *
+ * fdt_create_empty_tree() creates a minimal empty device tree blob
+ * in the given buffer. The tree contains only a root node with no
+ * properties or subnodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, if @bufsize is too small for even an empty tree
+ */
int fdt_create_empty_tree(void *buf, int bufsize);
+
+/**
+ * fdt_open_into - move a device tree into a new buffer and make editable
+ * @fdt: Pointer to the device tree to move
+ * @buf: Buffer where the editable tree should be placed
+ * @bufsize: Size of the buffer at @buf
+ *
+ * fdt_open_into() moves and reorganizes the device tree blob from @fdt
+ * into @buf, converting it to a format suitable for read-write operations.
+ * The new buffer should allow space for modifications.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, if @bufsize is too small
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
int fdt_open_into(const void *fdt, void *buf, int bufsize);
+
+/**
+ * fdt_pack - pack a device tree blob
+ * @fdt: Pointer to the device tree blob
+ *
+ * fdt_pack() reorganizes the device tree blob to eliminate any free space
+ * and pack it into the minimum possible size. This is useful after making
+ * modifications that might have left gaps in the blob.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT, standard meanings
+ */
int fdt_pack(void *fdt);
/**
@@ -2317,6 +2521,16 @@ int fdt_overlay_target_offset(const void *fdt, const void *fdto,
/* Debugging / informational functions */
/**********************************************************************/
+/**
+ * fdt_strerror - return string description of error code
+ * @errval: Error code returned by a libfdt function
+ *
+ * fdt_strerror() returns a string description of the error code passed
+ * in @errval.
+ *
+ * returns:
+ * pointer to a string describing the error code
+ */
const char *fdt_strerror(int errval);
#ifdef __cplusplus
diff --git a/libfdt/meson.build b/libfdt/meson.build
index c2f4bd6..68d4c1d 100644
--- a/libfdt/meson.build
+++ b/libfdt/meson.build
@@ -31,7 +31,7 @@ libfdt = library(
version: meson.project_version(),
link_args: link_args,
link_depends: 'version.lds',
- install: true,
+ install: get_option('default_library') != 'static' or not wheel_only,
)
libfdt_inc = include_directories('.')
@@ -40,21 +40,24 @@ libfdt_dep = declare_dependency(
include_directories: libfdt_inc,
link_with: libfdt,
)
-
-install_headers(
- files(
- 'fdt.h',
- 'libfdt.h',
- 'libfdt_env.h',
+meson.override_dependency('libfdt', libfdt_dep)
+
+if not wheel_only
+ install_headers(
+ files(
+ 'fdt.h',
+ 'libfdt.h',
+ 'libfdt_env.h',
+ )
)
-)
-pkgconfig = import('pkgconfig')
+ pkgconfig = import('pkgconfig')
-pkgconfig.generate(
- libraries: libfdt,
- version: meson.project_version(),
- filebase: 'libfdt',
- name: 'libfdt',
- description: 'Flat Device Tree manipulation',
-)
+ pkgconfig.generate(
+ libraries: libfdt,
+ version: meson.project_version(),
+ filebase: 'libfdt',
+ name: 'libfdt',
+ description: 'Flat Device Tree manipulation',
+ )
+endif
diff --git a/livetree.c b/livetree.c
index 93c77d9..d51d058 100644
--- a/livetree.c
+++ b/livetree.c
@@ -174,7 +174,7 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
old_prop->val = new_prop->val;
old_prop->deleted = 0;
- free(old_prop->srcpos);
+ srcpos_free(old_prop->srcpos);
old_prop->srcpos = new_prop->srcpos;
free(new_prop);
new_prop = NULL;
diff --git a/meson.build b/meson.build
index 3026f88..66b44e8 100644
--- a/meson.build
+++ b/meson.build
@@ -43,6 +43,7 @@ py = import('python')
py = py.find_installation(required: get_option('python'))
swig = find_program('swig', required: get_option('python'))
pylibfdt_enabled = not meson.is_cross_build() and py.found() and swig.found() ? true : false
+wheel_only = get_option('wheel-only')
version_gen_h = vcs_tag(
command: ['git', 'describe', '--dirty=+'],
@@ -59,7 +60,7 @@ util_dep = declare_dependency(
dependencies: libfdt_dep
)
-if get_option('tools')
+if get_option('tools') and not wheel_only
flex = find_program('flex', required: true)
bison = find_program('bison', required: true)
@@ -117,6 +118,10 @@ if get_option('tools')
)
endif
+foreach e: dtc_tools
+ meson.override_find_program(e.name(), e)
+endforeach
+
if pylibfdt_enabled
subdir('pylibfdt')
endif
diff --git a/meson_options.txt b/meson_options.txt
index 62b31b3..a866b17 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -10,3 +10,5 @@ option('python', type: 'feature', value: 'auto',
description: 'Build pylibfdt Python library')
option('tests', type: 'boolean', value: true,
description: 'Build tests')
+option('wheel-only', type: 'boolean', value: false,
+ description: 'building from meson-python')
diff --git a/pylibfdt/Makefile.pylibfdt b/pylibfdt/Makefile.pylibfdt
deleted file mode 100644
index 647203f..0000000
--- a/pylibfdt/Makefile.pylibfdt
+++ /dev/null
@@ -1,30 +0,0 @@
-# SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
-# Makefile.pylibfdt
-#
-
-PYLIBFDT_srcs = $(PYLIBFDT_dir)/libfdt.i
-PYMODULE = $(PYLIBFDT_dir)/_libfdt.so
-PYLIBFDT_CLEANFILES_L = libfdt_wrap.c libfdt.py *.pyc *.so
-PYLIBFDT_CLEANFILES = $(PYLIBFDT_CLEANFILES_L:%=$(PYLIBFDT_dir)/%)
-PYLIBFDT_CLEANDIRS_L = __pycache__ libfdt.egg-info
-PYLIBFDT_CLEANDIRS = build $(PYLIBFDT_CLEANDIRS_L:%=$(PYLIBFDT_dir)/%)
-
-SETUP = ./setup.py
-
-ifndef V
-SETUPFLAGS += --quiet
-endif
-
-$(PYMODULE): WARNINGS = # suppress warnings from generated code
-$(PYMODULE): $(PYLIBFDT_srcs) $(LIBFDT_archive) $(SETUP)
- @$(VECHO) PYMOD $@
- CFLAGS="$(CFLAGS) -Wno-error" $(PYTHON) $(SETUP) $(SETUPFLAGS) build_ext
-
-install_pylibfdt: $(PYMODULE)
- @$(VECHO) INSTALL-PYLIB
- $(PYTHON) $(SETUP) $(SETUPFLAGS) install --prefix=$(PREFIX)
-
-pylibfdt_clean:
- @$(VECHO) CLEAN "(pylibfdt)"
- rm -f $(PYLIBFDT_CLEANFILES)
- rm -rf $(PYLIBFDT_CLEANDIRS)
diff --git a/pylibfdt/meson.build b/pylibfdt/meson.build
index 6157f8d..b13d802 100644
--- a/pylibfdt/meson.build
+++ b/pylibfdt/meson.build
@@ -1,13 +1,21 @@
-setup_py = find_program('../setup.py')
-setup_py = [setup_py, '--quiet', '--top-builddir', meson.project_build_root()]
-
-pylibfdt = custom_target(
- 'pylibfdt',
+libfdt_c = custom_target(
+ 'swig',
input: 'libfdt.i',
- depends: libfdt,
- output: '_libfdt.so',
- command: [setup_py, 'build_ext'],
- build_by_default: true,
+ output: ['libfdt.c', 'libfdt.py'],
+ install: true,
+ install_dir: [false, py.get_install_dir(pure: false)],
+ command: [swig, '-python', '-I'+meson.current_source_dir() / '../libfdt', '-o', '@OUTPUT0@', '@INPUT@']
)
-meson.add_install_script(setup_py, 'install', '--prefix=' + get_option('prefix'), '--root=$DESTDIR')
+nowarn_gen = cc.get_supported_arguments(
+ '-Wno-cast-qual',
+ '-Wno-missing-prototypes',
+ '-Wno-redundant-decls',
+)
+pylibfdt = py.extension_module(
+ '_libfdt',
+ libfdt_c,
+ c_args: ['-DPY_SSIZE_T_CLEAN'] + nowarn_gen,
+ dependencies: [libfdt_dep, py.dependency()],
+ install: true,
+)
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..853d13e
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,33 @@
+[build-system]
+build-backend = 'mesonpy'
+requires = ['meson-python']
+
+[project]
+name = 'libfdt'
+authors = [
+ {name = 'Simon Glass', email = 'sjg@chromium.org'},
+]
+classifiers = [
+ 'Programming Language :: Python :: 3',
+ 'License :: OSI Approved :: BSD License',
+ 'License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)',
+ 'Operating System :: OS Independent',
+]
+description = 'Python binding for libfdt'
+readme = 'README.md'
+requires-python = '>=3.8'
+dynamic = ['version']
+
+[project.urls]
+'homepage' = 'https://git.kernel.org/pub/scm/utils/dtc/dtc.git'
+
+# These arguments are applied only when building a redistributable binary wheel
+# for uploading to PyPI. We don't want to install libraries (or headers /
+# pkgconfig files / executables) that clash with system C installs, so we
+# disable everything other than the python bindings themselves, and build the
+# python C-API extension using static linkage to avoid juggling "libdir" /
+# LD_LIBRARY_PATH / RPATH around. When building both the C library and the
+# python bindings for a distro, `meson setup` will still default to shared
+# libraries.
+[tool.meson-python.args]
+setup = ['-Ddefault_library=static', '-Dwheel-only=true']
diff --git a/scripts/install-deps.sh b/scripts/install-deps.sh
index 12507de..d243504 100755
--- a/scripts/install-deps.sh
+++ b/scripts/install-deps.sh
@@ -12,20 +12,20 @@ fi
if [ "$NAME" = "Arch Linux" ]
then
pacman -Syu --needed --noconfirm bison diffutils flex gcc git libyaml \
- make meson pkgconf python python-setuptools-scm swig valgrind which
+ make meson pkgconf python python-setuptools-scm swig
elif [ "$NAME" = "Alpine Linux" ]
then
- apk add build-base bison coreutils flex git yaml yaml-dev python3-dev \
- meson py3-setuptools_scm swig valgrind
+ apk add build-base bison flex git yaml yaml-dev python3-dev \
+ meson py3-setuptools_scm swig
elif [ "$NAME" = "Fedora Linux" ]
then
dnf install -y bison diffutils flex gcc git libyaml libyaml-devel \
- make meson python3-devel python3-setuptools swig valgrind which
+ make meson python3-devel python3-setuptools swig
elif [ "$NAME" = "Ubuntu" ]
then
apt update
apt install -yq build-essential bison flex git libyaml-dev pkg-config \
- meson python3-dev python3-setuptools python3-setuptools-scm swig valgrind
+ meson python3-dev python3-setuptools python3-setuptools-scm swig
else
echo "ERROR: OS name is not provided."
exit 1
diff --git a/setup.py b/setup.py
deleted file mode 100755
index 52844ce..0000000
--- a/setup.py
+++ /dev/null
@@ -1,97 +0,0 @@
-#!/usr/bin/env python3
-# SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
-
-"""
-setup.py file for SWIG libfdt
-Copyright (C) 2017 Google, Inc.
-Written by Simon Glass <sjg@chromium.org>
-"""
-
-import os
-import sys
-
-from setuptools import setup, Extension
-from setuptools.command.build_py import build_py as _build_py
-
-
-def scan_for_info(srcdir):
- """Scan for the version and long_description fields
-
- Args:
- srcdir (str): Source-directory path
-
- Returns: tuple
- str: Full description (contents of README.md)
- str: Version string
- """
- with open(os.path.join(srcdir, "VERSION.txt"), "r", encoding='utf-8') as fh:
- version = fh.readline().strip()
-
- with open(os.path.join(srcdir, "README.md"), "r", encoding='utf-8') as fh:
- long_description = fh.read()
-
- return version, long_description
-
-
-def get_top_builddir(srcdir):
- """Figure out the top-level directory containing the source code
-
- Args:
- srcdir (str): Source-directory path
-
- Returns:
- str: Directory to build in
- """
- if '--top-builddir' in sys.argv:
- index = sys.argv.index('--top-builddir')
- sys.argv.pop(index)
- return sys.argv.pop(index)
- return srcdir
-
-
-class BuildPy(_build_py):
- """Small class to run the build_ext command"""
- def run(self):
- self.run_command("build_ext")
- return super().run()
-
-
-srcdir = os.path.dirname(__file__)
-version, long_description = scan_for_info(srcdir)
-
-libfdt_module = Extension(
- '_libfdt',
- sources=[os.path.join(srcdir, 'pylibfdt/libfdt.i')],
- define_macros=[('PY_SSIZE_T_CLEAN', None)],
- include_dirs=[os.path.join(srcdir, 'libfdt')],
- libraries=['fdt'],
- library_dirs=[os.path.join(get_top_builddir(srcdir), 'libfdt')],
- swig_opts=['-I' + os.path.join(srcdir, 'libfdt')],
-)
-
-
-setup(
- name='libfdt',
- version=version,
- cmdclass = {'build_py' : BuildPy},
- author='Simon Glass',
- author_email='sjg@chromium.org',
- description='Python binding for libfdt',
- ext_modules=[libfdt_module],
- package_dir={'': os.path.join(srcdir, 'pylibfdt')},
- py_modules=['libfdt'],
- python_requires=">=3.8",
-
- long_description=long_description,
- long_description_content_type="text/plain",
- url="https://git.kernel.org/pub/scm/utils/dtc/dtc.git",
- license="BSD",
- license_files=["GPL", "BSD-2-Clause"],
-
- classifiers=[
- "Programming Language :: Python :: 3",
- "License :: OSI Approved :: BSD License",
- "License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)",
- "Operating System :: OS Independent",
- ],
-)
diff --git a/srcpos.c b/srcpos.c
index 5e2f7dd..fef892f 100644
--- a/srcpos.c
+++ b/srcpos.c
@@ -89,6 +89,26 @@ static char *shorten_to_initial_path(char *fname)
}
/**
+ * Returns true if the given path is an absolute one.
+ *
+ * On Windows, it either needs to begin with a forward slash or with a drive
+ * letter (e.g. "C:").
+ * On all other operating systems, it must begin with a forward slash to be
+ * considered an absolute path.
+ */
+static bool is_absolute_path(const char *path)
+{
+#ifdef WIN32
+ return (
+ path[0] == '/' ||
+ (((path[0] >= 'A' && path[0] <= 'Z') || (path[0] >= 'a' && path[0] <= 'z')) && path[1] == ':')
+ );
+#else
+ return (path[0] == '/');
+#endif
+}
+
+/**
* Try to open a file in a given directory.
*
* If the filename is an absolute path, then dirname is ignored. If it is a
@@ -103,7 +123,7 @@ static char *try_open(const char *dirname, const char *fname, FILE **fp)
{
char *fullname;
- if (!dirname || fname[0] == '/')
+ if (!dirname || is_absolute_path(fname))
fullname = xstrdup(fname);
else
fullname = join_path(dirname, fname);
@@ -287,6 +307,17 @@ struct srcpos *srcpos_extend(struct srcpos *pos, struct srcpos *newtail)
return pos;
}
+void srcpos_free(struct srcpos *pos)
+{
+ struct srcpos *p_next;
+
+ while (pos) {
+ p_next = pos->next;
+ free(pos);
+ pos = p_next;
+ }
+}
+
char *
srcpos_string(struct srcpos *pos)
{
diff --git a/srcpos.h b/srcpos.h
index 4318d7a..4d60b50 100644
--- a/srcpos.h
+++ b/srcpos.h
@@ -88,6 +88,7 @@ extern void srcpos_update(struct srcpos *pos, const char *text, int len);
extern struct srcpos *srcpos_copy(struct srcpos *pos);
extern struct srcpos *srcpos_extend(struct srcpos *new_srcpos,
struct srcpos *old_srcpos);
+extern void srcpos_free(struct srcpos *pos);
extern char *srcpos_string(struct srcpos *pos);
extern char *srcpos_string_first(struct srcpos *pos, int level);
extern char *srcpos_string_last(struct srcpos *pos, int level);
diff --git a/tests/fdtget-runtest.sh b/tests/fdtget-runtest.sh
index 18b7404..35fa5e1 100755
--- a/tests/fdtget-runtest.sh
+++ b/tests/fdtget-runtest.sh
@@ -9,7 +9,7 @@ rm -f $LOG $EXPECT
trap "rm -f $LOG $EXPECT" 0
expect="$1"
-printf '%b\n' "$expect" > $EXPECT
+printf "$expect\n" > $EXPECT
shift
verbose_run_log_check "$LOG" $VALGRIND $DTGET "$@"
diff --git a/tests/meson.build b/tests/meson.build
index 52d657e..37bfd47 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -1,4 +1,4 @@
-trees = static_library('trees', files('trees.S'), c_args: '-D__ASSEMBLY__',
+trees = static_library('trees', files('trees.S'),
build_by_default: false,
include_directories: libfdt_inc)
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
index fecfe7c..2e172d7 100755
--- a/tests/run_tests.sh
+++ b/tests/run_tests.sh
@@ -43,13 +43,14 @@ fi
# stat differs between platforms
if [ -z "$STATSZ" ]; then
- stat --version 2>/dev/null | grep -q 'GNU'
- GNUSTAT=$?
- if [ "$GNUSTAT" -ne 0 ]; then
- # Assume BSD stat if we can't detect as GNU stat
- STATSZ="stat -f %Uz"
- else
+ # First attempt GNU style, this is supported by both the
+ # actual GNU coreutils version, and the Rust re-implementation
+ # uutils, used in recent Ubuntu versions
+ if stat -c %s $0; then
STATSZ="stat -c %s"
+ else
+ # Otherwise assume BSD style stat
+ STATSZ="stat -f %Uz"
fi
fi
diff --git a/tests/testdata.h b/tests/testdata.h
index 4f9e3ba..fcebc2c 100644
--- a/tests/testdata.h
+++ b/tests/testdata.h
@@ -1,4 +1,4 @@
-#ifdef __ASSEMBLY__
+#ifdef __ASSEMBLER__
#define ASM_CONST_LL(x) (x)
#else
#define ASM_CONST_LL(x) (x##ULL)
@@ -46,7 +46,7 @@
#define TEST_MEMREGION_SIZE_HI 0x0fedcba900000000
#define TEST_MEMREGION_SIZE_INC 0x1000
-#ifndef __ASSEMBLY__
+#ifndef __ASSEMBLER__
extern struct fdt_header test_tree1;
extern struct fdt_header truncated_property;
extern struct fdt_header bad_node_char;
@@ -57,4 +57,4 @@ extern struct fdt_header truncated_string;
extern struct fdt_header truncated_memrsv;
extern struct fdt_header two_roots;
extern struct fdt_header named_root;
-#endif /* ! __ASSEMBLY */
+#endif /* ! __ASSEMBLER__ */
diff --git a/treesource.c b/treesource.c
index ae15839..d25f01f 100644
--- a/treesource.c
+++ b/treesource.c
@@ -139,26 +139,48 @@ static const char *delim_end[] = {
[TYPE_STRING] = "",
};
+/*
+ * The invariants in the marker list are:
+ * - offsets are non-strictly monotonically increasing
+ * - for a single offset there is at most one type marker
+ * - for a single offset that has both a type marker and non-type markers, the
+ * type marker appears before the others.
+ */
+static struct marker **add_marker(struct marker **mi,
+ enum markertype type, unsigned int offset, char *ref)
+{
+ struct marker *nm;
+
+ while (*mi && (*mi)->offset < offset)
+ mi = &(*mi)->next;
+
+ if (*mi && (*mi)->offset == offset && is_type_marker((*mi)->type)) {
+ if (is_type_marker(type))
+ return mi;
+ mi = &(*mi)->next;
+ }
+
+ if (*mi && (*mi)->offset == offset && type == (*mi)->type)
+ return mi;
+
+ nm = xmalloc(sizeof(*nm));
+ nm->type = type;
+ nm->offset = offset;
+ nm->ref = ref;
+ nm->next = *mi;
+ *mi = nm;
+
+ return &nm->next;
+}
+
static void add_string_markers(struct property *prop)
{
int l, len = prop->val.len;
const char *p = prop->val.val;
+ struct marker **mi = &prop->val.markers;
- for (l = strlen(p) + 1; l < len; l += strlen(p + l) + 1) {
- struct marker *m, **nextp;
-
- m = xmalloc(sizeof(*m));
- m->offset = l;
- m->type = TYPE_STRING;
- m->ref = NULL;
- m->next = NULL;
-
- /* Find the end of the markerlist */
- nextp = &prop->val.markers;
- while (*nextp)
- nextp = &((*nextp)->next);
- *nextp = m;
- }
+ for (l = strlen(p) + 1; l < len; l += strlen(p + l) + 1)
+ mi = add_marker(mi, TYPE_STRING, l, NULL);
}
static enum markertype guess_value_type(struct property *prop)