aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MANIFEST.in12
-rw-r--r--Makefile55
-rw-r--r--checks.c2
-rw-r--r--data.c47
-rw-r--r--dtc.h3
-rw-r--r--dtdiff2
-rw-r--r--fdtput.c4
-rw-r--r--libfdt/fdt.h4
-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-xsetup.py97
-rw-r--r--srcpos.c11
-rw-r--r--srcpos.h1
-rw-r--r--tests/meson.build2
-rw-r--r--tests/testdata.h6
-rw-r--r--treesource.c52
21 files changed, 189 insertions, 246 deletions
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..b1815c3 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
@@ -27,7 +31,6 @@ BISON = bison
LEX = flex
SWIG = swig
PKG_CONFIG ?= pkg-config
-PYTHON ?= python3
INSTALL = install
INSTALL_PROGRAM = $(INSTALL)
@@ -43,8 +46,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
@@ -154,29 +155,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 +228,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 +254,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 +286,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 +297,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 +317,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.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..825640c 100644
--- a/fdtput.c
+++ b/fdtput.c
@@ -389,8 +389,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/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/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/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..5bb57bf 100644
--- a/srcpos.c
+++ b/srcpos.c
@@ -287,6 +287,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/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/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)