mirror of
https://github.com/michaelrsweet/mxml.git
synced 2024-11-24 03:15:30 +00:00
Start working on Mini-XML v4.0.
This commit is contained in:
parent
809204a305
commit
f9b9a40494
199
Makefile.in
199
Makefile.in
@ -3,63 +3,132 @@
|
|||||||
#
|
#
|
||||||
# https://www.msweet.org/mxml
|
# https://www.msweet.org/mxml
|
||||||
#
|
#
|
||||||
# Copyright © 2003-2021 by Michael R Sweet.
|
# Copyright © 2003-2024 by Michael R Sweet.
|
||||||
#
|
#
|
||||||
# Licensed under Apache License v2.0. See the file "LICENSE" for more
|
# Licensed under Apache License v2.0. See the file "LICENSE" for more
|
||||||
# information.
|
# information.
|
||||||
#
|
#
|
||||||
|
|
||||||
#
|
#
|
||||||
# Compiler tools definitions...
|
# This is a POSIX makefile
|
||||||
|
#
|
||||||
|
|
||||||
|
.POSIX:
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Mini-XML version...
|
||||||
|
#
|
||||||
|
|
||||||
|
MXML_VERSION = @MXML_VERSION@
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Programs...
|
||||||
#
|
#
|
||||||
|
|
||||||
AR = @AR@
|
AR = @AR@
|
||||||
ARFLAGS = @ARFLAGS@
|
|
||||||
ARCHFLAGS = @ARCHFLAGS@
|
|
||||||
CC = @CC@
|
CC = @CC@
|
||||||
CFLAGS = $(OPTIM) $(ARCHFLAGS) @CFLAGS@ $(CPPFLAGS) $(WARNINGS)
|
|
||||||
CP = @CP@
|
|
||||||
CPPFLAGS = @CPPFLAGS@
|
|
||||||
DSO = @DSO@
|
DSO = @DSO@
|
||||||
DSOFLAGS = @DSOFLAGS@
|
|
||||||
LDFLAGS = $(OPTIM) $(ARCHFLAGS) @LDFLAGS@
|
|
||||||
INSTALL = @INSTALL@
|
INSTALL = @INSTALL@
|
||||||
LIBMXML = @LIBMXML@
|
LN = @LN@ -sf
|
||||||
LIBS = @LIBS@
|
MKDIR = @MKDIR@ -p
|
||||||
LN = @LN@ -s
|
|
||||||
MKDIR = @MKDIR@
|
|
||||||
OPTIM = @OPTIM@
|
|
||||||
RANLIB = @RANLIB@
|
RANLIB = @RANLIB@
|
||||||
RM = @RM@ -f
|
RM = @RM@ -f
|
||||||
|
RMDIR = @RMDIR@
|
||||||
SHELL = /bin/sh
|
SHELL = /bin/sh
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Installation programs...
|
||||||
|
#
|
||||||
|
|
||||||
|
INSTALL_BIN = $(INSTALL) -c -m 755
|
||||||
|
INSTALL_DATA = $(INSTALL) -c -m 444
|
||||||
|
INSTALL_DIR = $(INSTALL) -d -m 755
|
||||||
|
INSTALL_LIB = $(INSTALL) -c -m 755
|
||||||
|
INSTALL_MAN = $(INSTALL) -c -m 444
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Libraries...
|
||||||
|
#
|
||||||
|
|
||||||
|
LIBMXML = @LIBMXML@
|
||||||
|
LIBMXML_STATIC = @LIBMXML_STATIC@
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Install static libraries?
|
||||||
|
#
|
||||||
|
|
||||||
|
INSTALL_STATIC = @INSTALL_STATIC@
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Code signing...
|
||||||
|
#
|
||||||
|
|
||||||
|
CODE_SIGN = @CODE_SIGN@
|
||||||
|
CODESIGN_IDENTITY = -
|
||||||
|
CSFLAGS = -s "$(CODESIGN_IDENTITY)" @CSFLAGS@ --timestamp
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Library archiver...
|
||||||
|
#
|
||||||
|
|
||||||
|
ARFLAGS = @ARFLAGS@
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# C compiler and preprocessor...
|
||||||
|
#
|
||||||
|
|
||||||
|
CFLAGS = @CFLAGS@
|
||||||
|
CPPFLAGS = @CPPFLAGS@
|
||||||
WARNINGS = @WARNINGS@
|
WARNINGS = @WARNINGS@
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Configured directories...
|
# Linker options...
|
||||||
|
#
|
||||||
|
|
||||||
|
DSOFLAGS = @DSOFLAGS@
|
||||||
|
LDFLAGS = @LDFLAGS@
|
||||||
|
LIBS = @LIBS@ -lm
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Optimization and architecture options for both the compiler and linker.
|
||||||
|
#
|
||||||
|
|
||||||
|
OPTIM = @OPTIM@
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Directories...
|
||||||
#
|
#
|
||||||
|
|
||||||
prefix = @prefix@
|
|
||||||
exec_prefix = @exec_prefix@
|
|
||||||
bindir = @bindir@
|
bindir = @bindir@
|
||||||
|
datadir = @datadir@
|
||||||
datarootdir = @datarootdir@
|
datarootdir = @datarootdir@
|
||||||
|
exec_prefix = @exec_prefix@
|
||||||
includedir = @includedir@
|
includedir = @includedir@
|
||||||
|
infodir = @infodir@
|
||||||
libdir = @libdir@
|
libdir = @libdir@
|
||||||
|
libexecdir = @libexecdir@
|
||||||
|
localstatedir = @localstatedir@
|
||||||
mandir = @mandir@
|
mandir = @mandir@
|
||||||
docdir = @docdir@
|
oldincludedir = @oldincludedir@
|
||||||
BUILDROOT = $(DSTROOT)
|
prefix = @prefix@
|
||||||
|
sbindir = @sbindir@
|
||||||
|
sharedstatedir = @sharedstatedir@
|
||||||
|
srcdir = @srcdir@
|
||||||
|
sysconfdir = @sysconfdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
|
||||||
|
BUILDROOT = $(DSTROOT)$(DESTDIR)
|
||||||
#
|
|
||||||
# Install commands...
|
|
||||||
#
|
|
||||||
|
|
||||||
INSTALL_BIN = $(INSTALL) -m 755
|
|
||||||
INSTALL_DATA = $(INSTALL) -m 644
|
|
||||||
INSTALL_DIR = $(INSTALL) -d
|
|
||||||
INSTALL_LIB = $(INSTALL) -m 755
|
|
||||||
INSTALL_MAN = $(INSTALL) -m 644
|
|
||||||
INSTALL_SCRIPT = $(INSTALL) -m 755
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -81,7 +150,7 @@ DOCFILES = doc/mxml.epub doc/mxml.html doc/mxml-cover.png \
|
|||||||
CHANGES.md LICENSE NOTICE README.md
|
CHANGES.md LICENSE NOTICE README.md
|
||||||
PUBLIBOBJS = mxml-attr.o mxml-entity.o mxml-file.o mxml-get.o \
|
PUBLIBOBJS = mxml-attr.o mxml-entity.o mxml-file.o mxml-get.o \
|
||||||
mxml-index.o mxml-node.o mxml-search.o mxml-set.o
|
mxml-index.o mxml-node.o mxml-search.o mxml-set.o
|
||||||
LIBOBJS = $(PUBLIBOBJS) mxml-private.o mxml-string.o
|
LIBOBJS = $(PUBLIBOBJS) mxml-private.o
|
||||||
OBJS = testmxml.o $(LIBOBJS)
|
OBJS = testmxml.o $(LIBOBJS)
|
||||||
ALLTARGETS = $(LIBMXML) testmxml
|
ALLTARGETS = $(LIBMXML) testmxml
|
||||||
CROSSTARGETS = $(LIBMXML)
|
CROSSTARGETS = $(LIBMXML)
|
||||||
@ -102,13 +171,12 @@ all: $(TARGETS)
|
|||||||
clean:
|
clean:
|
||||||
echo Cleaning build files...
|
echo Cleaning build files...
|
||||||
$(RM) $(OBJS) $(ALLTARGETS)
|
$(RM) $(OBJS) $(ALLTARGETS)
|
||||||
$(RM) mxml1.dll
|
$(RM) mxml2.dll
|
||||||
$(RM) mxml1.lib
|
$(RM) mxml2.lib
|
||||||
$(RM) libmxml.a
|
$(RM) libmxml.a
|
||||||
$(RM) libmxml.so
|
$(RM) libmxml.so
|
||||||
$(RM) libmxml.so.1
|
$(RM) libmxml.so.2
|
||||||
$(RM) libmxml.so.1.6
|
$(RM) libmxml.2.dylib
|
||||||
$(RM) libmxml.1.dylib
|
|
||||||
$(RM) libmxml.dylib
|
$(RM) libmxml.dylib
|
||||||
|
|
||||||
|
|
||||||
@ -132,7 +200,7 @@ distclean: clean
|
|||||||
# Install everything...
|
# Install everything...
|
||||||
#
|
#
|
||||||
|
|
||||||
install: $(TARGETS) install-$(LIBMXML) install-libmxml.a
|
install: $(TARGETS) install-$(LIBMXML) @INSTALL_STATIC@
|
||||||
echo Installing documentation in $(BUILDROOT)$(docdir)...
|
echo Installing documentation in $(BUILDROOT)$(docdir)...
|
||||||
$(INSTALL_DIR) $(BUILDROOT)$(docdir)
|
$(INSTALL_DIR) $(BUILDROOT)$(docdir)
|
||||||
for file in $(DOCFILES); do \
|
for file in $(DOCFILES); do \
|
||||||
@ -154,29 +222,27 @@ install-libmxml.a: libmxml.a
|
|||||||
$(INSTALL_LIB) libmxml.a $(BUILDROOT)$(libdir)
|
$(INSTALL_LIB) libmxml.a $(BUILDROOT)$(libdir)
|
||||||
$(RANLIB) $(BUILDROOT)$(libdir)/libmxml.a
|
$(RANLIB) $(BUILDROOT)$(libdir)/libmxml.a
|
||||||
|
|
||||||
install-libmxml.so.1.6: libmxml.so.1.6
|
install-libmxml.so.2: libmxml.so.2
|
||||||
echo Installing libmxml.so to $(BUILDROOT)$(libdir)...
|
echo Installing libmxml.so to $(BUILDROOT)$(libdir)...
|
||||||
$(INSTALL_DIR) $(BUILDROOT)$(libdir)
|
$(INSTALL_DIR) $(BUILDROOT)$(libdir)
|
||||||
$(INSTALL_LIB) libmxml.so.1.6 $(BUILDROOT)$(libdir)
|
$(INSTALL_LIB) libmxml.so.2 $(BUILDROOT)$(libdir)
|
||||||
$(RM) $(BUILDROOT)$(libdir)/libmxml.so
|
$(RM) $(BUILDROOT)$(libdir)/libmxml.so
|
||||||
$(LN) libmxml.so.1.6 $(BUILDROOT)$(libdir)/libmxml.so
|
$(LN) libmxml.so.2 $(BUILDROOT)$(libdir)/libmxml.so
|
||||||
$(RM) $(BUILDROOT)$(libdir)/libmxml.so.1
|
|
||||||
$(LN) libmxml.so.1.6 $(BUILDROOT)$(libdir)/libmxml.so.1
|
|
||||||
$(LDCONFIG)
|
$(LDCONFIG)
|
||||||
|
|
||||||
install-libmxml.1.dylib: libmxml.1.dylib
|
install-libmxml.2.dylib: libmxml.2.dylib
|
||||||
echo Installing libmxml.dylib to $(BUILDROOT)$(libdir)...
|
echo Installing libmxml.dylib to $(BUILDROOT)$(libdir)...
|
||||||
$(INSTALL_DIR) $(BUILDROOT)$(libdir)
|
$(INSTALL_DIR) $(BUILDROOT)$(libdir)
|
||||||
$(INSTALL_LIB) libmxml.1.dylib $(BUILDROOT)$(libdir)
|
$(INSTALL_LIB) libmxml.2.dylib $(BUILDROOT)$(libdir)
|
||||||
$(RM) $(BUILDROOT)$(libdir)/libmxml.dylib
|
$(RM) $(BUILDROOT)$(libdir)/libmxml.dylib
|
||||||
$(LN) libmxml.1.dylib $(BUILDROOT)$(libdir)/libmxml.dylib
|
$(LN) libmxml.2.dylib $(BUILDROOT)$(libdir)/libmxml.dylib
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Uninstall everything...
|
# Uninstall everything...
|
||||||
#
|
#
|
||||||
|
|
||||||
uninstall: uninstall-$(LIBMXML) uninstall-libmxml.a
|
uninstall: uninstall-$(LIBMXML) @UNINSTALL_STATIC@
|
||||||
echo Uninstalling documentation from $(BUILDROOT)$(docdir)...
|
echo Uninstalling documentation from $(BUILDROOT)$(docdir)...
|
||||||
$(RM) -r $(BUILDROOT)$(docdir)
|
$(RM) -r $(BUILDROOT)$(docdir)
|
||||||
echo Uninstalling headers from $(BUILDROOT)$(includedir)...
|
echo Uninstalling headers from $(BUILDROOT)$(includedir)...
|
||||||
@ -190,17 +256,16 @@ uninstall-libmxml.a:
|
|||||||
echo Uninstalling libmxml.a from $(BUILDROOT)$(libdir)...
|
echo Uninstalling libmxml.a from $(BUILDROOT)$(libdir)...
|
||||||
$(RM) $(BUILDROOT)$(libdir)/libmxml.a
|
$(RM) $(BUILDROOT)$(libdir)/libmxml.a
|
||||||
|
|
||||||
uninstall-libmxml.so.1.6:
|
uninstall-libmxml.so.2:
|
||||||
echo Uninstalling libmxml.so from $(BUILDROOT)$(libdir)...
|
echo Uninstalling libmxml.so from $(BUILDROOT)$(libdir)...
|
||||||
$(RM) $(BUILDROOT)$(libdir)/libmxml.so
|
$(RM) $(BUILDROOT)$(libdir)/libmxml.so
|
||||||
$(RM) $(BUILDROOT)$(libdir)/libmxml.so.1
|
$(RM) $(BUILDROOT)$(libdir)/libmxml.so.2
|
||||||
$(RM) $(BUILDROOT)$(libdir)/libmxml.so.1.6
|
|
||||||
$(LDCONFIG)
|
$(LDCONFIG)
|
||||||
|
|
||||||
uninstall-libmxml.1.dylib:
|
uninstall-libmxml.2.dylib:
|
||||||
echo Uninstalling libmxml.dylib from $(BUILDROOT)$(libdir)...
|
echo Uninstalling libmxml.dylib from $(BUILDROOT)$(libdir)...
|
||||||
$(RM) $(BUILDROOT)$(libdir)/libmxml.dylib
|
$(RM) $(BUILDROOT)$(libdir)/libmxml.dylib
|
||||||
$(RM) $(BUILDROOT)$(libdir)/libmxml.1.dylib
|
$(RM) $(BUILDROOT)$(libdir)/libmxml.2.dylib
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -253,44 +318,42 @@ libmxml.a: $(LIBOBJS)
|
|||||||
$(AR) $(ARFLAGS) $@ $(LIBOBJS)
|
$(AR) $(ARFLAGS) $@ $(LIBOBJS)
|
||||||
$(RANLIB) $@
|
$(RANLIB) $@
|
||||||
|
|
||||||
$(LIBOBJS): mxml.h
|
$(LIBOBJS): mxml.h mxml-private.h
|
||||||
mxml-entity.o mxml-file.o mxml-private.o: mxml-private.h
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# mxml1.dll
|
# libmxml2.dll
|
||||||
#
|
#
|
||||||
|
|
||||||
mxml1.dll: $(LIBOBJS)
|
libmxml2.dll: $(LIBOBJS)
|
||||||
echo Creating $@...
|
echo Creating $@...
|
||||||
$(DSO) $(DSOFLAGS) $(LDFLAGS) -o $@ $(LIBOBJS) $(LIBS)
|
$(DSO) $(DSOFLAGS) -o $@ $(LIBOBJS) $(LIBS)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# libmxml.so.1.6
|
# libmxml.so.2
|
||||||
#
|
#
|
||||||
|
|
||||||
libmxml.so.1.6: $(LIBOBJS)
|
libmxml.so.2: $(LIBOBJS)
|
||||||
echo Creating $@...
|
echo Creating $@...
|
||||||
$(DSO) $(DSOFLAGS) $(LDFLAGS) -o libmxml.so.1.6 $(LIBOBJS) $(LIBS)
|
$(DSO) $(DSOFLAGS) -o libmxml.so.2 $(LIBOBJS) $(LIBS)
|
||||||
$(RM) libmxml.so libmxml.so.1
|
$(RM) libmxml.so
|
||||||
$(LN) libmxml.so.1.6 libmxml.so
|
$(LN) libmxml.so.2 libmxml.so
|
||||||
$(LN) libmxml.so.1.6 libmxml.so.1
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# libmxml.1.dylib
|
# libmxml.2.dylib
|
||||||
#
|
#
|
||||||
|
|
||||||
libmxml.1.dylib: $(LIBOBJS)
|
libmxml.2.dylib: $(LIBOBJS)
|
||||||
echo Creating $@...
|
echo Creating $@...
|
||||||
$(DSO) $(DSOFLAGS) $(LDFLAGS) -o libmxml.1.dylib \
|
$(DSO) $(DSOFLAGS) -o libmxml.2.dylib \
|
||||||
-install_name $(libdir)/libmxml.dylib \
|
-install_name $(libdir)/libmxml.dylib \
|
||||||
-current_version 1.6.0 \
|
-current_version 2.0.0 \
|
||||||
-compatibility_version 1.0.0 \
|
-compatibility_version 2.0.0 \
|
||||||
$(LIBOBJS) $(LIBS)
|
$(LIBOBJS) $(LIBS)
|
||||||
$(RM) libmxml.dylib
|
$(RM) libmxml.dylib
|
||||||
$(LN) libmxml.1.dylib libmxml.dylib
|
$(LN) libmxml.2.dylib libmxml.dylib
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
2
NOTICE
2
NOTICE
@ -1,6 +1,6 @@
|
|||||||
Mini-XML
|
Mini-XML
|
||||||
|
|
||||||
Copyright © 2003-2022 by Michael R Sweet
|
Copyright © 2003-2024 by Michael R Sweet
|
||||||
|
|
||||||
|
|
||||||
(Optional) Exceptions to the Apache 2.0 License:
|
(Optional) Exceptions to the Apache 2.0 License:
|
||||||
|
19
README.md
19
README.md
@ -5,8 +5,12 @@ Mini-XML - Tiny XML Parsing Library
|
|||||||
![Apache 2.0](https://img.shields.io/github/license/michaelrsweet/mxml)
|
![Apache 2.0](https://img.shields.io/github/license/michaelrsweet/mxml)
|
||||||
![Build](https://github.com/michaelrsweet/mxml/workflows/Build/badge.svg)
|
![Build](https://github.com/michaelrsweet/mxml/workflows/Build/badge.svg)
|
||||||
[![Coverity Scan Status](https://img.shields.io/coverity/scan/23959.svg)](https://scan.coverity.com/projects/michaelrsweet-mxml)
|
[![Coverity Scan Status](https://img.shields.io/coverity/scan/23959.svg)](https://scan.coverity.com/projects/michaelrsweet-mxml)
|
||||||
[![LGTM Grade](https://img.shields.io/lgtm/grade/cpp/github/michaelrsweet/mxml)](https://lgtm.com/projects/g/michaelrsweet/mxml/context:cpp)
|
|
||||||
[![LGTM Alerts](https://img.shields.io/lgtm/alerts/github/michaelrsweet/mxml)](https://lgtm.com/projects/g/michaelrsweet/mxml/)
|
> Note: The master branch contains what will become Mini-XML v4.0. See the
|
||||||
|
> v3.x branch for the Mini-XML v3.x source code. Version 4.0 is not 100% source
|
||||||
|
> compatible with earlier versions of Mini-XML. Changes will be documented in
|
||||||
|
> the near future...
|
||||||
|
|
||||||
|
|
||||||
Mini-XML is a small XML parsing library that you can use to read XML data files
|
Mini-XML is a small XML parsing library that you can use to read XML data files
|
||||||
or strings in your application without requiring large non-standard libraries.
|
or strings in your application without requiring large non-standard libraries.
|
||||||
@ -29,10 +33,6 @@ Mini-XML provides the following functionality:
|
|||||||
Mini-XML doesn't do validation or other types of processing on the data
|
Mini-XML doesn't do validation or other types of processing on the data
|
||||||
based upon schema files or other sources of definition information.
|
based upon schema files or other sources of definition information.
|
||||||
|
|
||||||
> Note: Version 3.0 hides the definition of the `mxml_node_t` structure,
|
|
||||||
> requiring the use of the various accessor functions that were introduced in
|
|
||||||
> version 2.0.
|
|
||||||
|
|
||||||
|
|
||||||
Building Mini-XML
|
Building Mini-XML
|
||||||
-----------------
|
-----------------
|
||||||
@ -61,12 +61,13 @@ included project files in the `vcnet` subdirectory to build the library
|
|||||||
instead. Note: The static library on Windows is NOT thread-safe.
|
instead. Note: The static library on Windows is NOT thread-safe.
|
||||||
|
|
||||||
|
|
||||||
## Installing Mini-XML
|
Installing Mini-XML
|
||||||
|
-------------------
|
||||||
|
|
||||||
The `install` target will install Mini-XML in the lib and include
|
The `install` target will install Mini-XML in the lib and include
|
||||||
directories:
|
directories:
|
||||||
|
|
||||||
make install
|
sudo make install
|
||||||
|
|
||||||
Once you have installed it, use the `-lmxml` option to link your application
|
Once you have installed it, use the `-lmxml` option to link your application
|
||||||
against it.
|
against it.
|
||||||
@ -199,7 +200,7 @@ current version of this software, documentation, and Github issue tracking page.
|
|||||||
Legal Stuff
|
Legal Stuff
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
Copyright © 2003-2022 by Michael R Sweet
|
Copyright © 2003-2024 by Michael R Sweet
|
||||||
|
|
||||||
The Mini-XML library is licensed under the Apache License Version 2.0 with an
|
The Mini-XML library is licensed under the Apache License Version 2.0 with an
|
||||||
*optional* exception to allow linking against GPL2/LGPL2-only software. See the
|
*optional* exception to allow linking against GPL2/LGPL2-only software. See the
|
||||||
|
65
config.guess
vendored
65
config.guess
vendored
@ -1,10 +1,10 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Attempt to guess a canonical system name.
|
# Attempt to guess a canonical system name.
|
||||||
# Copyright 1992-2022 Free Software Foundation, Inc.
|
# Copyright 1992-2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
# shellcheck disable=SC2006,SC2268 # see below for rationale
|
# shellcheck disable=SC2006,SC2268 # see below for rationale
|
||||||
|
|
||||||
timestamp='2022-05-25'
|
timestamp='2023-08-22'
|
||||||
|
|
||||||
# This file is free software; you can redistribute it and/or modify it
|
# This file is free software; you can redistribute it and/or modify it
|
||||||
# under the terms of the GNU General Public License as published by
|
# under the terms of the GNU General Public License as published by
|
||||||
@ -47,7 +47,7 @@ me=`echo "$0" | sed -e 's,.*/,,'`
|
|||||||
usage="\
|
usage="\
|
||||||
Usage: $0 [OPTION]
|
Usage: $0 [OPTION]
|
||||||
|
|
||||||
Output the configuration name of the system \`$me' is run on.
|
Output the configuration name of the system '$me' is run on.
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
-h, --help print this help, then exit
|
-h, --help print this help, then exit
|
||||||
@ -60,13 +60,13 @@ version="\
|
|||||||
GNU config.guess ($timestamp)
|
GNU config.guess ($timestamp)
|
||||||
|
|
||||||
Originally written by Per Bothner.
|
Originally written by Per Bothner.
|
||||||
Copyright 1992-2022 Free Software Foundation, Inc.
|
Copyright 1992-2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This is free software; see the source for copying conditions. There is NO
|
This is free software; see the source for copying conditions. There is NO
|
||||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||||
|
|
||||||
help="
|
help="
|
||||||
Try \`$me --help' for more information."
|
Try '$me --help' for more information."
|
||||||
|
|
||||||
# Parse command line
|
# Parse command line
|
||||||
while test $# -gt 0 ; do
|
while test $# -gt 0 ; do
|
||||||
@ -102,8 +102,8 @@ GUESS=
|
|||||||
# temporary files to be created and, as you can see below, it is a
|
# temporary files to be created and, as you can see below, it is a
|
||||||
# headache to deal with in a portable fashion.
|
# headache to deal with in a portable fashion.
|
||||||
|
|
||||||
# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
|
# Historically, 'CC_FOR_BUILD' used to be named 'HOST_CC'. We still
|
||||||
# use `HOST_CC' if defined, but it is deprecated.
|
# use 'HOST_CC' if defined, but it is deprecated.
|
||||||
|
|
||||||
# Portable tmp directory creation inspired by the Autoconf team.
|
# Portable tmp directory creation inspired by the Autoconf team.
|
||||||
|
|
||||||
@ -155,6 +155,9 @@ Linux|GNU|GNU/*)
|
|||||||
|
|
||||||
set_cc_for_build
|
set_cc_for_build
|
||||||
cat <<-EOF > "$dummy.c"
|
cat <<-EOF > "$dummy.c"
|
||||||
|
#if defined(__ANDROID__)
|
||||||
|
LIBC=android
|
||||||
|
#else
|
||||||
#include <features.h>
|
#include <features.h>
|
||||||
#if defined(__UCLIBC__)
|
#if defined(__UCLIBC__)
|
||||||
LIBC=uclibc
|
LIBC=uclibc
|
||||||
@ -169,6 +172,7 @@ Linux|GNU|GNU/*)
|
|||||||
LIBC=musl
|
LIBC=musl
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
EOF
|
EOF
|
||||||
cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
|
cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
|
||||||
eval "$cc_set_libc"
|
eval "$cc_set_libc"
|
||||||
@ -459,7 +463,7 @@ case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in
|
|||||||
UNAME_RELEASE=`uname -v`
|
UNAME_RELEASE=`uname -v`
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
# Japanese Language versions have a version number like `4.1.3-JL'.
|
# Japanese Language versions have a version number like '4.1.3-JL'.
|
||||||
SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'`
|
SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'`
|
||||||
GUESS=sparc-sun-sunos$SUN_REL
|
GUESS=sparc-sun-sunos$SUN_REL
|
||||||
;;
|
;;
|
||||||
@ -904,7 +908,7 @@ EOF
|
|||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
*:FreeBSD:*:*)
|
*:FreeBSD:*:*)
|
||||||
UNAME_PROCESSOR=`/usr/bin/uname -p`
|
UNAME_PROCESSOR=`uname -p`
|
||||||
case $UNAME_PROCESSOR in
|
case $UNAME_PROCESSOR in
|
||||||
amd64)
|
amd64)
|
||||||
UNAME_PROCESSOR=x86_64 ;;
|
UNAME_PROCESSOR=x86_64 ;;
|
||||||
@ -966,11 +970,37 @@ EOF
|
|||||||
GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
|
GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
|
||||||
GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC
|
GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC
|
||||||
;;
|
;;
|
||||||
|
x86_64:[Mm]anagarm:*:*|i?86:[Mm]anagarm:*:*)
|
||||||
|
GUESS="$UNAME_MACHINE-pc-managarm-mlibc"
|
||||||
|
;;
|
||||||
|
*:[Mm]anagarm:*:*)
|
||||||
|
GUESS="$UNAME_MACHINE-unknown-managarm-mlibc"
|
||||||
|
;;
|
||||||
*:Minix:*:*)
|
*:Minix:*:*)
|
||||||
GUESS=$UNAME_MACHINE-unknown-minix
|
GUESS=$UNAME_MACHINE-unknown-minix
|
||||||
;;
|
;;
|
||||||
aarch64:Linux:*:*)
|
aarch64:Linux:*:*)
|
||||||
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
|
set_cc_for_build
|
||||||
|
CPU=$UNAME_MACHINE
|
||||||
|
LIBCABI=$LIBC
|
||||||
|
if test "$CC_FOR_BUILD" != no_compiler_found; then
|
||||||
|
ABI=64
|
||||||
|
sed 's/^ //' << EOF > "$dummy.c"
|
||||||
|
#ifdef __ARM_EABI__
|
||||||
|
#ifdef __ARM_PCS_VFP
|
||||||
|
ABI=eabihf
|
||||||
|
#else
|
||||||
|
ABI=eabi
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
EOF
|
||||||
|
cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'`
|
||||||
|
eval "$cc_set_abi"
|
||||||
|
case $ABI in
|
||||||
|
eabi | eabihf) CPU=armv8l; LIBCABI=$LIBC$ABI ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
GUESS=$CPU-unknown-linux-$LIBCABI
|
||||||
;;
|
;;
|
||||||
aarch64_be:Linux:*:*)
|
aarch64_be:Linux:*:*)
|
||||||
UNAME_MACHINE=aarch64_be
|
UNAME_MACHINE=aarch64_be
|
||||||
@ -1036,7 +1066,16 @@ EOF
|
|||||||
k1om:Linux:*:*)
|
k1om:Linux:*:*)
|
||||||
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
|
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
|
||||||
;;
|
;;
|
||||||
loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*)
|
kvx:Linux:*:*)
|
||||||
|
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
|
||||||
|
;;
|
||||||
|
kvx:cos:*:*)
|
||||||
|
GUESS=$UNAME_MACHINE-unknown-cos
|
||||||
|
;;
|
||||||
|
kvx:mbr:*:*)
|
||||||
|
GUESS=$UNAME_MACHINE-unknown-mbr
|
||||||
|
;;
|
||||||
|
loongarch32:Linux:*:* | loongarch64:Linux:*:*)
|
||||||
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
|
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
|
||||||
;;
|
;;
|
||||||
m32r*:Linux:*:*)
|
m32r*:Linux:*:*)
|
||||||
@ -1191,7 +1230,7 @@ EOF
|
|||||||
GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION
|
GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION
|
||||||
;;
|
;;
|
||||||
i*86:OS/2:*:*)
|
i*86:OS/2:*:*)
|
||||||
# If we were able to find `uname', then EMX Unix compatibility
|
# If we were able to find 'uname', then EMX Unix compatibility
|
||||||
# is probably installed.
|
# is probably installed.
|
||||||
GUESS=$UNAME_MACHINE-pc-os2-emx
|
GUESS=$UNAME_MACHINE-pc-os2-emx
|
||||||
;;
|
;;
|
||||||
@ -1332,7 +1371,7 @@ EOF
|
|||||||
GUESS=ns32k-sni-sysv
|
GUESS=ns32k-sni-sysv
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
|
PENTIUM:*:4.0*:*) # Unisys 'ClearPath HMP IX 4000' SVR4/MP effort
|
||||||
# says <Richard.M.Bartel@ccMail.Census.GOV>
|
# says <Richard.M.Bartel@ccMail.Census.GOV>
|
||||||
GUESS=i586-unisys-sysv4
|
GUESS=i586-unisys-sysv4
|
||||||
;;
|
;;
|
||||||
|
118
config.h.in
118
config.h.in
@ -1,99 +1,49 @@
|
|||||||
/*
|
//
|
||||||
* Configuration file for Mini-XML, a small XML file parsing library.
|
// Configuration file for Mini-XML, a small XML file parsing library.
|
||||||
*
|
//
|
||||||
* https://www.msweet.org/mxml
|
// https://www.msweet.org/mxml
|
||||||
*
|
//
|
||||||
* Copyright © 2003-2020 by Michael R Sweet.
|
// Copyright © 2003-2024 by Michael R Sweet.
|
||||||
*
|
//
|
||||||
* Licensed under Apache License v2.0. See the file "LICENSE" for more
|
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
||||||
* information.
|
// information.
|
||||||
*/
|
//
|
||||||
|
|
||||||
/*
|
#ifndef MXML_CONFIG_H
|
||||||
* Include necessary headers...
|
# define MXML_CONFIG_H
|
||||||
*/
|
# include <stdio.h>
|
||||||
|
# include <stdlib.h>
|
||||||
#include <stdio.h>
|
# include <string.h>
|
||||||
#include <stdlib.h>
|
# include <stdarg.h>
|
||||||
#include <string.h>
|
# include <ctype.h>
|
||||||
#include <stdarg.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Version number...
|
// Version number
|
||||||
*/
|
//
|
||||||
|
|
||||||
#define MXML_VERSION ""
|
# define MXML_VERSION ""
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Inline function support...
|
// Inline function support
|
||||||
*/
|
//
|
||||||
|
|
||||||
#define inline
|
# define inline
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Long long support...
|
// Long long support
|
||||||
*/
|
//
|
||||||
|
|
||||||
#undef HAVE_LONG_LONG_INT
|
# undef HAVE_LONG_LONG_INT
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Do we have the *printf() functions?
|
// Have <pthread.h>?
|
||||||
*/
|
//
|
||||||
|
|
||||||
#undef HAVE_SNPRINTF
|
# undef HAVE_PTHREAD_H
|
||||||
#undef HAVE_VASPRINTF
|
|
||||||
#undef HAVE_VSNPRINTF
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
#endif // !MXML_CONFIG_H
|
||||||
* Do we have the strXXX() functions?
|
|
||||||
*/
|
|
||||||
|
|
||||||
#undef HAVE_STRDUP
|
|
||||||
#undef HAVE_STRLCAT
|
|
||||||
#undef HAVE_STRLCPY
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Do we have threading support?
|
|
||||||
*/
|
|
||||||
|
|
||||||
#undef HAVE_PTHREAD_H
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Define prototypes for string functions as needed...
|
|
||||||
*/
|
|
||||||
|
|
||||||
# ifndef HAVE_STRDUP
|
|
||||||
extern char *_mxml_strdup(const char *);
|
|
||||||
# define strdup _mxml_strdup
|
|
||||||
# endif /* !HAVE_STRDUP */
|
|
||||||
|
|
||||||
# ifndef HAVE_STRLCAT
|
|
||||||
extern size_t _mxml_strlcat(char *, const char *, size_t);
|
|
||||||
# define strlcat _mxml_strlcat
|
|
||||||
# endif /* !HAVE_STRLCAT */
|
|
||||||
|
|
||||||
# ifndef HAVE_STRLCPY
|
|
||||||
extern size_t _mxml_strlcpy(char *, const char *, size_t);
|
|
||||||
# define strlcpy _mxml_strlcpy
|
|
||||||
# endif /* !HAVE_STRLCPY */
|
|
||||||
|
|
||||||
extern char *_mxml_strdupf(const char *, ...);
|
|
||||||
extern char *_mxml_vstrdupf(const char *, va_list);
|
|
||||||
|
|
||||||
# ifndef HAVE_SNPRINTF
|
|
||||||
extern int _mxml_snprintf(char *, size_t, const char *, ...);
|
|
||||||
# define snprintf _mxml_snprintf
|
|
||||||
# endif /* !HAVE_SNPRINTF */
|
|
||||||
|
|
||||||
# ifndef HAVE_VSNPRINTF
|
|
||||||
extern int _mxml_vsnprintf(char *, size_t, const char *, va_list);
|
|
||||||
# define vsnprintf _mxml_vsnprintf
|
|
||||||
# endif /* !HAVE_VSNPRINTF */
|
|
||||||
|
224
config.sub
vendored
224
config.sub
vendored
@ -1,10 +1,10 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Configuration validation subroutine script.
|
# Configuration validation subroutine script.
|
||||||
# Copyright 1992-2022 Free Software Foundation, Inc.
|
# Copyright 1992-2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
# shellcheck disable=SC2006,SC2268 # see below for rationale
|
# shellcheck disable=SC2006,SC2268 # see below for rationale
|
||||||
|
|
||||||
timestamp='2022-01-03'
|
timestamp='2023-09-19'
|
||||||
|
|
||||||
# This file is free software; you can redistribute it and/or modify it
|
# This file is free software; you can redistribute it and/or modify it
|
||||||
# under the terms of the GNU General Public License as published by
|
# under the terms of the GNU General Public License as published by
|
||||||
@ -76,13 +76,13 @@ Report bugs and patches to <config-patches@gnu.org>."
|
|||||||
version="\
|
version="\
|
||||||
GNU config.sub ($timestamp)
|
GNU config.sub ($timestamp)
|
||||||
|
|
||||||
Copyright 1992-2022 Free Software Foundation, Inc.
|
Copyright 1992-2023 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This is free software; see the source for copying conditions. There is NO
|
This is free software; see the source for copying conditions. There is NO
|
||||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||||
|
|
||||||
help="
|
help="
|
||||||
Try \`$me --help' for more information."
|
Try '$me --help' for more information."
|
||||||
|
|
||||||
# Parse command line
|
# Parse command line
|
||||||
while test $# -gt 0 ; do
|
while test $# -gt 0 ; do
|
||||||
@ -130,7 +130,7 @@ IFS=$saved_IFS
|
|||||||
# Separate into logical components for further validation
|
# Separate into logical components for further validation
|
||||||
case $1 in
|
case $1 in
|
||||||
*-*-*-*-*)
|
*-*-*-*-*)
|
||||||
echo Invalid configuration \`"$1"\': more than four components >&2
|
echo "Invalid configuration '$1': more than four components" >&2
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
*-*-*-*)
|
*-*-*-*)
|
||||||
@ -145,7 +145,8 @@ case $1 in
|
|||||||
nto-qnx* | linux-* | uclinux-uclibc* \
|
nto-qnx* | linux-* | uclinux-uclibc* \
|
||||||
| uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \
|
| uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \
|
||||||
| netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \
|
| netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \
|
||||||
| storm-chaos* | os2-emx* | rtmk-nova*)
|
| storm-chaos* | os2-emx* | rtmk-nova* | managarm-* \
|
||||||
|
| windows-* )
|
||||||
basic_machine=$field1
|
basic_machine=$field1
|
||||||
basic_os=$maybe_os
|
basic_os=$maybe_os
|
||||||
;;
|
;;
|
||||||
@ -943,7 +944,7 @@ $basic_machine
|
|||||||
EOF
|
EOF
|
||||||
IFS=$saved_IFS
|
IFS=$saved_IFS
|
||||||
;;
|
;;
|
||||||
# We use `pc' rather than `unknown'
|
# We use 'pc' rather than 'unknown'
|
||||||
# because (1) that's what they normally are, and
|
# because (1) that's what they normally are, and
|
||||||
# (2) the word "unknown" tends to confuse beginning users.
|
# (2) the word "unknown" tends to confuse beginning users.
|
||||||
i*86 | x86_64)
|
i*86 | x86_64)
|
||||||
@ -1075,7 +1076,7 @@ case $cpu-$vendor in
|
|||||||
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
|
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
|
||||||
cpu=i586
|
cpu=i586
|
||||||
;;
|
;;
|
||||||
pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*)
|
pentiumpro-* | p6-* | 6x86-* | athlon-* | athlon_*-*)
|
||||||
cpu=i686
|
cpu=i686
|
||||||
;;
|
;;
|
||||||
pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
|
pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
|
||||||
@ -1180,7 +1181,7 @@ case $cpu-$vendor in
|
|||||||
case $cpu in
|
case $cpu in
|
||||||
1750a | 580 \
|
1750a | 580 \
|
||||||
| a29k \
|
| a29k \
|
||||||
| aarch64 | aarch64_be \
|
| aarch64 | aarch64_be | aarch64c | arm64ec \
|
||||||
| abacus \
|
| abacus \
|
||||||
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \
|
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \
|
||||||
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \
|
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \
|
||||||
@ -1199,45 +1200,23 @@ case $cpu-$vendor in
|
|||||||
| d10v | d30v | dlx | dsp16xx \
|
| d10v | d30v | dlx | dsp16xx \
|
||||||
| e2k | elxsi | epiphany \
|
| e2k | elxsi | epiphany \
|
||||||
| f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \
|
| f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \
|
||||||
|
| javascript \
|
||||||
| h8300 | h8500 \
|
| h8300 | h8500 \
|
||||||
| hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
| hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
||||||
| hexagon \
|
| hexagon \
|
||||||
| i370 | i*86 | i860 | i960 | ia16 | ia64 \
|
| i370 | i*86 | i860 | i960 | ia16 | ia64 \
|
||||||
| ip2k | iq2000 \
|
| ip2k | iq2000 \
|
||||||
| k1om \
|
| k1om \
|
||||||
|
| kvx \
|
||||||
| le32 | le64 \
|
| le32 | le64 \
|
||||||
| lm32 \
|
| lm32 \
|
||||||
| loongarch32 | loongarch64 | loongarchx32 \
|
| loongarch32 | loongarch64 \
|
||||||
| m32c | m32r | m32rle \
|
| m32c | m32r | m32rle \
|
||||||
| m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \
|
| m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \
|
||||||
| m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \
|
| m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \
|
||||||
| m88110 | m88k | maxq | mb | mcore | mep | metag \
|
| m88110 | m88k | maxq | mb | mcore | mep | metag \
|
||||||
| microblaze | microblazeel \
|
| microblaze | microblazeel \
|
||||||
| mips | mipsbe | mipseb | mipsel | mipsle \
|
| mips* \
|
||||||
| mips16 \
|
|
||||||
| mips64 | mips64eb | mips64el \
|
|
||||||
| mips64octeon | mips64octeonel \
|
|
||||||
| mips64orion | mips64orionel \
|
|
||||||
| mips64r5900 | mips64r5900el \
|
|
||||||
| mips64vr | mips64vrel \
|
|
||||||
| mips64vr4100 | mips64vr4100el \
|
|
||||||
| mips64vr4300 | mips64vr4300el \
|
|
||||||
| mips64vr5000 | mips64vr5000el \
|
|
||||||
| mips64vr5900 | mips64vr5900el \
|
|
||||||
| mipsisa32 | mipsisa32el \
|
|
||||||
| mipsisa32r2 | mipsisa32r2el \
|
|
||||||
| mipsisa32r3 | mipsisa32r3el \
|
|
||||||
| mipsisa32r5 | mipsisa32r5el \
|
|
||||||
| mipsisa32r6 | mipsisa32r6el \
|
|
||||||
| mipsisa64 | mipsisa64el \
|
|
||||||
| mipsisa64r2 | mipsisa64r2el \
|
|
||||||
| mipsisa64r3 | mipsisa64r3el \
|
|
||||||
| mipsisa64r5 | mipsisa64r5el \
|
|
||||||
| mipsisa64r6 | mipsisa64r6el \
|
|
||||||
| mipsisa64sb1 | mipsisa64sb1el \
|
|
||||||
| mipsisa64sr71k | mipsisa64sr71kel \
|
|
||||||
| mipsr5900 | mipsr5900el \
|
|
||||||
| mipstx39 | mipstx39el \
|
|
||||||
| mmix \
|
| mmix \
|
||||||
| mn10200 | mn10300 \
|
| mn10200 | mn10300 \
|
||||||
| moxie \
|
| moxie \
|
||||||
@ -1285,7 +1264,7 @@ case $cpu-$vendor in
|
|||||||
;;
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2
|
echo "Invalid configuration '$1': machine '$cpu-$vendor' not recognized" 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@ -1306,11 +1285,12 @@ esac
|
|||||||
|
|
||||||
# Decode manufacturer-specific aliases for certain operating systems.
|
# Decode manufacturer-specific aliases for certain operating systems.
|
||||||
|
|
||||||
if test x$basic_os != x
|
if test x"$basic_os" != x
|
||||||
then
|
then
|
||||||
|
|
||||||
# First recognize some ad-hoc cases, or perhaps split kernel-os, or else just
|
# First recognize some ad-hoc cases, or perhaps split kernel-os, or else just
|
||||||
# set os.
|
# set os.
|
||||||
|
obj=
|
||||||
case $basic_os in
|
case $basic_os in
|
||||||
gnu/linux*)
|
gnu/linux*)
|
||||||
kernel=linux
|
kernel=linux
|
||||||
@ -1341,6 +1321,10 @@ EOF
|
|||||||
kernel=linux
|
kernel=linux
|
||||||
os=`echo "$basic_os" | sed -e 's|linux|gnu|'`
|
os=`echo "$basic_os" | sed -e 's|linux|gnu|'`
|
||||||
;;
|
;;
|
||||||
|
managarm*)
|
||||||
|
kernel=managarm
|
||||||
|
os=`echo "$basic_os" | sed -e 's|managarm|mlibc|'`
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
kernel=
|
kernel=
|
||||||
os=$basic_os
|
os=$basic_os
|
||||||
@ -1506,10 +1490,16 @@ case $os in
|
|||||||
os=eabi
|
os=eabi
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
os=elf
|
os=
|
||||||
|
obj=elf
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
|
aout* | coff* | elf* | pe*)
|
||||||
|
# These are machine code file formats, not OSes
|
||||||
|
obj=$os
|
||||||
|
os=
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
# No normalization, but not necessarily accepted, that comes below.
|
# No normalization, but not necessarily accepted, that comes below.
|
||||||
;;
|
;;
|
||||||
@ -1528,12 +1518,15 @@ else
|
|||||||
# system, and we'll never get to this point.
|
# system, and we'll never get to this point.
|
||||||
|
|
||||||
kernel=
|
kernel=
|
||||||
|
obj=
|
||||||
case $cpu-$vendor in
|
case $cpu-$vendor in
|
||||||
score-*)
|
score-*)
|
||||||
os=elf
|
os=
|
||||||
|
obj=elf
|
||||||
;;
|
;;
|
||||||
spu-*)
|
spu-*)
|
||||||
os=elf
|
os=
|
||||||
|
obj=elf
|
||||||
;;
|
;;
|
||||||
*-acorn)
|
*-acorn)
|
||||||
os=riscix1.2
|
os=riscix1.2
|
||||||
@ -1543,28 +1536,35 @@ case $cpu-$vendor in
|
|||||||
os=gnu
|
os=gnu
|
||||||
;;
|
;;
|
||||||
arm*-semi)
|
arm*-semi)
|
||||||
os=aout
|
os=
|
||||||
|
obj=aout
|
||||||
;;
|
;;
|
||||||
c4x-* | tic4x-*)
|
c4x-* | tic4x-*)
|
||||||
os=coff
|
os=
|
||||||
|
obj=coff
|
||||||
;;
|
;;
|
||||||
c8051-*)
|
c8051-*)
|
||||||
os=elf
|
os=
|
||||||
|
obj=elf
|
||||||
;;
|
;;
|
||||||
clipper-intergraph)
|
clipper-intergraph)
|
||||||
os=clix
|
os=clix
|
||||||
;;
|
;;
|
||||||
hexagon-*)
|
hexagon-*)
|
||||||
os=elf
|
os=
|
||||||
|
obj=elf
|
||||||
;;
|
;;
|
||||||
tic54x-*)
|
tic54x-*)
|
||||||
os=coff
|
os=
|
||||||
|
obj=coff
|
||||||
;;
|
;;
|
||||||
tic55x-*)
|
tic55x-*)
|
||||||
os=coff
|
os=
|
||||||
|
obj=coff
|
||||||
;;
|
;;
|
||||||
tic6x-*)
|
tic6x-*)
|
||||||
os=coff
|
os=
|
||||||
|
obj=coff
|
||||||
;;
|
;;
|
||||||
# This must come before the *-dec entry.
|
# This must come before the *-dec entry.
|
||||||
pdp10-*)
|
pdp10-*)
|
||||||
@ -1586,19 +1586,24 @@ case $cpu-$vendor in
|
|||||||
os=sunos3
|
os=sunos3
|
||||||
;;
|
;;
|
||||||
m68*-cisco)
|
m68*-cisco)
|
||||||
os=aout
|
os=
|
||||||
|
obj=aout
|
||||||
;;
|
;;
|
||||||
mep-*)
|
mep-*)
|
||||||
os=elf
|
os=
|
||||||
|
obj=elf
|
||||||
;;
|
;;
|
||||||
mips*-cisco)
|
mips*-cisco)
|
||||||
os=elf
|
os=
|
||||||
|
obj=elf
|
||||||
;;
|
;;
|
||||||
mips*-*)
|
mips*-*)
|
||||||
os=elf
|
os=
|
||||||
|
obj=elf
|
||||||
;;
|
;;
|
||||||
or32-*)
|
or32-*)
|
||||||
os=coff
|
os=
|
||||||
|
obj=coff
|
||||||
;;
|
;;
|
||||||
*-tti) # must be before sparc entry or we get the wrong os.
|
*-tti) # must be before sparc entry or we get the wrong os.
|
||||||
os=sysv3
|
os=sysv3
|
||||||
@ -1607,7 +1612,8 @@ case $cpu-$vendor in
|
|||||||
os=sunos4.1.1
|
os=sunos4.1.1
|
||||||
;;
|
;;
|
||||||
pru-*)
|
pru-*)
|
||||||
os=elf
|
os=
|
||||||
|
obj=elf
|
||||||
;;
|
;;
|
||||||
*-be)
|
*-be)
|
||||||
os=beos
|
os=beos
|
||||||
@ -1688,10 +1694,12 @@ case $cpu-$vendor in
|
|||||||
os=uxpv
|
os=uxpv
|
||||||
;;
|
;;
|
||||||
*-rom68k)
|
*-rom68k)
|
||||||
os=coff
|
os=
|
||||||
|
obj=coff
|
||||||
;;
|
;;
|
||||||
*-*bug)
|
*-*bug)
|
||||||
os=coff
|
os=
|
||||||
|
obj=coff
|
||||||
;;
|
;;
|
||||||
*-apple)
|
*-apple)
|
||||||
os=macos
|
os=macos
|
||||||
@ -1709,7 +1717,8 @@ esac
|
|||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Now, validate our (potentially fixed-up) OS.
|
# Now, validate our (potentially fixed-up) individual pieces (OS, OBJ).
|
||||||
|
|
||||||
case $os in
|
case $os in
|
||||||
# Sometimes we do "kernel-libc", so those need to count as OSes.
|
# Sometimes we do "kernel-libc", so those need to count as OSes.
|
||||||
musl* | newlib* | relibc* | uclibc*)
|
musl* | newlib* | relibc* | uclibc*)
|
||||||
@ -1720,6 +1729,9 @@ case $os in
|
|||||||
# VxWorks passes extra cpu info in the 4th filed.
|
# VxWorks passes extra cpu info in the 4th filed.
|
||||||
simlinux | simwindows | spe)
|
simlinux | simwindows | spe)
|
||||||
;;
|
;;
|
||||||
|
# See `case $cpu-$os` validation below
|
||||||
|
ghcjs)
|
||||||
|
;;
|
||||||
# Now accept the basic system types.
|
# Now accept the basic system types.
|
||||||
# The portable systems comes first.
|
# The portable systems comes first.
|
||||||
# Each alternative MUST end in a * to match a version number.
|
# Each alternative MUST end in a * to match a version number.
|
||||||
@ -1728,7 +1740,7 @@ case $os in
|
|||||||
| hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \
|
| hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \
|
||||||
| sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \
|
| sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \
|
||||||
| hiux* | abug | nacl* | netware* | windows* \
|
| hiux* | abug | nacl* | netware* | windows* \
|
||||||
| os9* | macos* | osx* | ios* \
|
| os9* | macos* | osx* | ios* | tvos* | watchos* \
|
||||||
| mpw* | magic* | mmixware* | mon960* | lnews* \
|
| mpw* | magic* | mmixware* | mon960* | lnews* \
|
||||||
| amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \
|
| amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \
|
||||||
| aos* | aros* | cloudabi* | sortix* | twizzler* \
|
| aos* | aros* | cloudabi* | sortix* | twizzler* \
|
||||||
@ -1737,11 +1749,11 @@ case $os in
|
|||||||
| mirbsd* | netbsd* | dicos* | openedition* | ose* \
|
| mirbsd* | netbsd* | dicos* | openedition* | ose* \
|
||||||
| bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \
|
| bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \
|
||||||
| ekkobsd* | freebsd* | riscix* | lynxos* | os400* \
|
| ekkobsd* | freebsd* | riscix* | lynxos* | os400* \
|
||||||
| bosx* | nextstep* | cxux* | aout* | elf* | oabi* \
|
| bosx* | nextstep* | cxux* | oabi* \
|
||||||
| ptx* | coff* | ecoff* | winnt* | domain* | vsta* \
|
| ptx* | ecoff* | winnt* | domain* | vsta* \
|
||||||
| udi* | lites* | ieee* | go32* | aux* | hcos* \
|
| udi* | lites* | ieee* | go32* | aux* | hcos* \
|
||||||
| chorusrdb* | cegcc* | glidix* | serenity* \
|
| chorusrdb* | cegcc* | glidix* | serenity* \
|
||||||
| cygwin* | msys* | pe* | moss* | proelf* | rtems* \
|
| cygwin* | msys* | moss* | proelf* | rtems* \
|
||||||
| midipix* | mingw32* | mingw64* | mint* \
|
| midipix* | mingw32* | mingw64* | mint* \
|
||||||
| uxpv* | beos* | mpeix* | udk* | moxiebox* \
|
| uxpv* | beos* | mpeix* | udk* | moxiebox* \
|
||||||
| interix* | uwin* | mks* | rhapsody* | darwin* \
|
| interix* | uwin* | mks* | rhapsody* | darwin* \
|
||||||
@ -1754,7 +1766,7 @@ case $os in
|
|||||||
| onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
|
| onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
|
||||||
| midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
|
| midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
|
||||||
| nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \
|
| nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \
|
||||||
| fiwix* )
|
| fiwix* | mlibc* | cos* | mbr* )
|
||||||
;;
|
;;
|
||||||
# This one is extra strict with allowed versions
|
# This one is extra strict with allowed versions
|
||||||
sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
|
sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
|
||||||
@ -1762,41 +1774,99 @@ case $os in
|
|||||||
;;
|
;;
|
||||||
none)
|
none)
|
||||||
;;
|
;;
|
||||||
|
kernel* | msvc* )
|
||||||
|
# Restricted further below
|
||||||
|
;;
|
||||||
|
'')
|
||||||
|
if test x"$obj" = x
|
||||||
|
then
|
||||||
|
echo "Invalid configuration '$1': Blank OS only allowed with explicit machine code file format" 1>&2
|
||||||
|
fi
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2
|
echo "Invalid configuration '$1': OS '$os' not recognized" 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case $obj in
|
||||||
|
aout* | coff* | elf* | pe*)
|
||||||
|
;;
|
||||||
|
'')
|
||||||
|
# empty is fine
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Invalid configuration '$1': Machine code format '$obj' not recognized" 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Here we handle the constraint that a (synthetic) cpu and os are
|
||||||
|
# valid only in combination with each other and nowhere else.
|
||||||
|
case $cpu-$os in
|
||||||
|
# The "javascript-unknown-ghcjs" triple is used by GHC; we
|
||||||
|
# accept it here in order to tolerate that, but reject any
|
||||||
|
# variations.
|
||||||
|
javascript-ghcjs)
|
||||||
|
;;
|
||||||
|
javascript-* | *-ghcjs)
|
||||||
|
echo "Invalid configuration '$1': cpu '$cpu' is not valid with os '$os$obj'" 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# As a final step for OS-related things, validate the OS-kernel combination
|
# As a final step for OS-related things, validate the OS-kernel combination
|
||||||
# (given a valid OS), if there is a kernel.
|
# (given a valid OS), if there is a kernel.
|
||||||
case $kernel-$os in
|
case $kernel-$os-$obj in
|
||||||
linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \
|
linux-gnu*- | linux-dietlibc*- | linux-android*- | linux-newlib*- \
|
||||||
| linux-musl* | linux-relibc* | linux-uclibc* )
|
| linux-musl*- | linux-relibc*- | linux-uclibc*- | linux-mlibc*- )
|
||||||
;;
|
;;
|
||||||
uclinux-uclibc* )
|
uclinux-uclibc*- )
|
||||||
;;
|
;;
|
||||||
-dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* )
|
managarm-mlibc*- | managarm-kernel*- )
|
||||||
|
;;
|
||||||
|
windows*-msvc*-)
|
||||||
|
;;
|
||||||
|
-dietlibc*- | -newlib*- | -musl*- | -relibc*- | -uclibc*- | -mlibc*- )
|
||||||
# These are just libc implementations, not actual OSes, and thus
|
# These are just libc implementations, not actual OSes, and thus
|
||||||
# require a kernel.
|
# require a kernel.
|
||||||
echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2
|
echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
kfreebsd*-gnu* | kopensolaris*-gnu*)
|
-kernel*- )
|
||||||
|
echo "Invalid configuration '$1': '$os' needs explicit kernel." 1>&2
|
||||||
|
exit 1
|
||||||
;;
|
;;
|
||||||
vxworks-simlinux | vxworks-simwindows | vxworks-spe)
|
*-kernel*- )
|
||||||
|
echo "Invalid configuration '$1': '$kernel' does not support '$os'." 1>&2
|
||||||
|
exit 1
|
||||||
;;
|
;;
|
||||||
nto-qnx*)
|
*-msvc*- )
|
||||||
|
echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2
|
||||||
|
exit 1
|
||||||
;;
|
;;
|
||||||
os2-emx)
|
kfreebsd*-gnu*- | kopensolaris*-gnu*-)
|
||||||
;;
|
;;
|
||||||
*-eabi* | *-gnueabi*)
|
vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-)
|
||||||
;;
|
;;
|
||||||
-*)
|
nto-qnx*-)
|
||||||
|
;;
|
||||||
|
os2-emx-)
|
||||||
|
;;
|
||||||
|
*-eabi*- | *-gnueabi*-)
|
||||||
|
;;
|
||||||
|
none--*)
|
||||||
|
# None (no kernel, i.e. freestanding / bare metal),
|
||||||
|
# can be paired with an machine code file format
|
||||||
|
;;
|
||||||
|
-*-)
|
||||||
# Blank kernel with real OS is always fine.
|
# Blank kernel with real OS is always fine.
|
||||||
;;
|
;;
|
||||||
*-*)
|
--*)
|
||||||
echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2
|
# Blank kernel and OS with real machine code file format is always fine.
|
||||||
|
;;
|
||||||
|
*-*-*)
|
||||||
|
echo "Invalid configuration '$1': Kernel '$kernel' not known to work with OS '$os'." 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@ -1879,7 +1949,7 @@ case $vendor in
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
echo "$cpu-$vendor-${kernel:+$kernel-}$os"
|
echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}"
|
||||||
exit
|
exit
|
||||||
|
|
||||||
# Local variables:
|
# Local variables:
|
||||||
|
437
configure.ac
437
configure.ac
@ -3,7 +3,7 @@ dnl Configuration script for Mini-XML, a small XML file parsing library.
|
|||||||
dnl
|
dnl
|
||||||
dnl https://www.msweet.org/mxml
|
dnl https://www.msweet.org/mxml
|
||||||
dnl
|
dnl
|
||||||
dnl Copyright © 2003-2022 by Michael R Sweet.
|
dnl Copyright © 2003-2024 by Michael R Sweet.
|
||||||
dnl
|
dnl
|
||||||
dnl Licensed under Apache License v2.0. See the file "LICENSE" for more
|
dnl Licensed under Apache License v2.0. See the file "LICENSE" for more
|
||||||
dnl information.
|
dnl information.
|
||||||
@ -14,8 +14,12 @@ AC_PREREQ([2.70])
|
|||||||
|
|
||||||
|
|
||||||
dnl Package name and version...
|
dnl Package name and version...
|
||||||
AC_INIT([Mini-XML], [3.3.1], [https://github.com/michaelrsweet/mxml/issues], [mxml], [https://www.msweet.org/mxml])
|
AC_INIT([Mini-XML], [4.0b1], [https://github.com/michaelrsweet/mxml/issues], [mxml], [https://www.msweet.org/mxml])
|
||||||
|
AC_CONFIG_HEADERS([config.h])
|
||||||
|
|
||||||
|
MXML_VERSION="AC_PACKAGE_VERSION"
|
||||||
|
AC_SUBST([MXML_VERSION])
|
||||||
|
AC_DEFINE_UNQUOTED([MXML_VERSION], "Mini-XML v$MXML_VERSION", [Version number])
|
||||||
|
|
||||||
dnl This line is provided to ensure that you don't run the autoheader program
|
dnl This line is provided to ensure that you don't run the autoheader program
|
||||||
dnl against this project. Doing so is completely unsupported and WILL cause
|
dnl against this project. Doing so is completely unsupported and WILL cause
|
||||||
@ -35,113 +39,50 @@ AS_IF([test "x$host_os_version" = x], [
|
|||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
dnl Set the name of the config header file...
|
dnl Compiler options...
|
||||||
AC_CONFIG_HEADERS([config.h])
|
|
||||||
|
|
||||||
|
|
||||||
dnl Version number...
|
|
||||||
VERSION="AC_PACKAGE_VERSION"
|
|
||||||
AC_SUBST(VERSION)
|
|
||||||
AC_DEFINE_UNQUOTED(MXML_VERSION, "Mini-XML v$VERSION")
|
|
||||||
|
|
||||||
|
|
||||||
dnl Clear default debugging options and set normal optimization by
|
|
||||||
dnl default unless the user asks for debugging specifically.
|
|
||||||
CFLAGS="${CFLAGS:=}"
|
CFLAGS="${CFLAGS:=}"
|
||||||
CPPFLAGS="${CPPFLAGS:=}"
|
CPPFLAGS="${CPPFLAGS:=}"
|
||||||
|
DSO=""
|
||||||
|
DSOFLAGS="${DSOFLAGS:=}"
|
||||||
LDFLAGS="${LDFLAGS:=}"
|
LDFLAGS="${LDFLAGS:=}"
|
||||||
AC_SUBST([LDFLAGS])
|
|
||||||
LIBS="${LIBS:=}"
|
LIBS="${LIBS:=}"
|
||||||
|
OPTIM="${OPTIM:=}"
|
||||||
|
|
||||||
|
AC_SUBST([DSO])
|
||||||
dnl Options...
|
AC_SUBST([DSOFLAGS])
|
||||||
AC_ARG_WITH([ansi], AS_HELP_STRING([--with-ansi], [set full ANSI C mode, default=no]), [
|
AC_SUBST([LDFLAGS])
|
||||||
use_ansi="$withval"
|
|
||||||
], [
|
|
||||||
use_ansi="no"
|
|
||||||
])
|
|
||||||
|
|
||||||
AC_ARG_WITH([archflags], AS_HELP_STRING([--with-archflags], [set additional architecture flags, default=none]), [
|
|
||||||
ARCHFLAGS="$withval"
|
|
||||||
], [
|
|
||||||
AS_CASE(["$host_os_name"], [darwin*], [
|
|
||||||
AS_IF([test "$host_os_version" -ge 200 -a x$enable_debug != xyes], [
|
|
||||||
# macOS 11.0 and higher support the Apple Silicon (arm64) CPUs
|
|
||||||
ARCHFLAGS="-mmacosx-version-min=10.14 -arch x86_64 -arch arm64"
|
|
||||||
], [test x$enable_debug != xyes], [
|
|
||||||
ARCHFLAGS="-mmacosx-version-min=10.14 -arch x86_64"
|
|
||||||
])
|
|
||||||
], [*], [
|
|
||||||
ARCHFLAGS=""
|
|
||||||
])
|
|
||||||
])
|
|
||||||
AC_SUBST([ARCHFLAGS])
|
|
||||||
|
|
||||||
AC_ARG_WITH([optim], AS_HELP_STRING([--with-optim], [set additional optimization flags, default=none]), [
|
|
||||||
OPTIM="$withval"
|
|
||||||
], [
|
|
||||||
OPTIM=""
|
|
||||||
])
|
|
||||||
AC_SUBST([OPTIM])
|
AC_SUBST([OPTIM])
|
||||||
|
|
||||||
AC_ARG_ENABLE([debug], AS_HELP_STRING([--enable-debug], [turn on debugging, default=no]))
|
|
||||||
AC_ARG_ENABLE([maintainer], AS_HELP_STRING([--enable-maintainer], [turn on maintainer mode, default=no]))
|
|
||||||
AC_ARG_ENABLE([sanitizer], AS_HELP_STRING([--enable-sanitizer], [build with AddressSanitizer, default=no]))
|
|
||||||
|
|
||||||
AC_ARG_WITH([docdir], AS_HELP_STRING([--with-docdir], [set directory for documentation, default=${prefix}/share/doc/mxml]), [
|
dnl Standard programs...
|
||||||
docdir="$withval"
|
|
||||||
], [
|
|
||||||
docdir="NONE"
|
|
||||||
])
|
|
||||||
AC_SUBST(docdir)
|
|
||||||
|
|
||||||
AC_ARG_WITH([vsnprintf], AS_HELP_STRING([--with-vsnprintf], [use vsnprintf emulation functions, default=auto]), [
|
|
||||||
use_vsnprintf="$withval"
|
|
||||||
], [
|
|
||||||
use_vsnprintf="no"
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
||||||
dnl Checks for programs...
|
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
AC_PROG_CXX
|
|
||||||
AC_PROG_INSTALL
|
|
||||||
AS_IF([test "$INSTALL" = "$ac_install_sh"], [
|
|
||||||
# Use full path to install-sh script...
|
|
||||||
INSTALL="`pwd`/install-sh -c"
|
|
||||||
])
|
|
||||||
AC_PROG_RANLIB
|
AC_PROG_RANLIB
|
||||||
AC_CHECK_TOOL(AR,ar)
|
AC_PATH_PROG([AR], [ar])
|
||||||
AC_PATH_PROG(CP,cp)
|
AC_PATH_PROGS([CODE_SIGN], [codesign true])
|
||||||
AC_PATH_PROGS(LDCONFIG,ldconfig false)
|
AC_MSG_CHECKING([for install-sh script])
|
||||||
AC_PATH_PROG(LN,ln)
|
INSTALL="`pwd`/install-sh"
|
||||||
AC_PATH_PROG(MKDIR,mkdir)
|
AC_SUBST([INSTALL])
|
||||||
AC_PATH_PROG(RM,rm)
|
AC_MSG_RESULT([using $INSTALL])
|
||||||
|
AC_PATH_PROGS([LDCONFIG],ldconfig true)
|
||||||
|
AC_PATH_PROG([MKDIR], [mkdir])
|
||||||
|
AC_PATH_PROG([RM], [rm])
|
||||||
|
AC_PATH_PROG([RMDIR], [rmdir])
|
||||||
|
AC_PATH_PROG([LN], [ln])
|
||||||
|
|
||||||
|
|
||||||
dnl Flags for "ar" command...
|
dnl Figure out the correct "ar" command flags...
|
||||||
AS_CASE(["$host_os_name"], [darwin* | *bsd], [
|
AS_IF([test "$ac_cv_prog_ranlib" = ":"], [
|
||||||
ARFLAGS="-rcv"
|
ARFLAGS="crs"
|
||||||
], [*], [
|
], [
|
||||||
ARFLAGS="crvs"
|
ARFLAGS="cr"
|
||||||
])
|
])
|
||||||
AC_SUBST(ARFLAGS)
|
AC_SUBST([ARFLAGS])
|
||||||
|
|
||||||
|
|
||||||
dnl Inline functions...
|
dnl Inline functions...
|
||||||
AC_C_INLINE
|
AC_C_INLINE
|
||||||
|
|
||||||
|
|
||||||
dnl Checks for string functions.
|
|
||||||
AS_IF([test "x$use_ansi" != xyes], [
|
|
||||||
AC_CHECK_FUNCS([strdup strlcat strlcpy])
|
|
||||||
])
|
|
||||||
|
|
||||||
AS_IF([test "x$use_vsnprintf" != xyes], [
|
|
||||||
AC_CHECK_FUNCS([snprintf vasprintf vsnprintf])
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
||||||
dnl Check for "long long" support...
|
dnl Check for "long long" support...
|
||||||
AC_TYPE_LONG_LONG_INT
|
AC_TYPE_LONG_LONG_INT
|
||||||
|
|
||||||
@ -180,111 +121,113 @@ AS_IF([test "x$enable_threads" != xno], [
|
|||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
dnl Shared library support...
|
dnl Library targets...
|
||||||
DSO="${DSO:=:}"
|
AC_ARG_ENABLE([static], AS_HELP_STRING([--disable-static], [do not install static library]))
|
||||||
DSOFLAGS="${DSOFLAGS:=}"
|
AC_ARG_ENABLE([shared], AS_HELP_STRING([--disable-shared], [do not install shared library]))
|
||||||
|
|
||||||
AC_ARG_ENABLE([shared], AS_HELP_STRING([--disable-shared], [turn off shared libraries, default=no]))
|
|
||||||
|
|
||||||
|
LIBMXML_STATIC="libmxml.a"
|
||||||
AS_IF([test x$enable_shared != xno], [
|
AS_IF([test x$enable_shared != xno], [
|
||||||
AC_MSG_CHECKING([for shared library support])
|
AS_CASE(["$host_os_name"], [linux* | gnu*], [
|
||||||
PICFLAG=1
|
LIBMXML="libmxml.so.2"
|
||||||
|
|
||||||
AS_CASE(["$host_os_name"], [sunos | unix_s], [
|
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
LIBMXML="libmxml.so.1.6"
|
|
||||||
DSO="\$(CC)"
|
DSO="\$(CC)"
|
||||||
DSOFLAGS="$DSOFLAGS -Wl,-h,libmxml.so.1 -G -R\$(libdir) \$(OPTIM)"
|
DSOFLAGS="$DSOFLAGS -Wl,-soname,\`basename \$@\` -shared"
|
||||||
LDFLAGS="$LDFLAGS -R\$(libdir)"
|
], [*bsd*], [
|
||||||
], [linux*], [
|
LIBMXML="libmxml.so.2"
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
LIBMXML="libmxml.so.1.6"
|
|
||||||
DSO="\$(CC)"
|
DSO="\$(CC)"
|
||||||
DSOFLAGS="$DSOFLAGS -Wl,-soname,libmxml.so.1 -shared \$(OPTIM)"
|
DSOFLAGS="$DSOFLAGS -Wl,-soname,\`basename \$@\` -shared -lc"
|
||||||
], [osf | gnu], [
|
], [darwin*], [
|
||||||
AC_MSG_RESULT([yes])
|
LIBMXML="libmxml.2.dylib"
|
||||||
LIBMXML="libmxml.so.1.6"
|
|
||||||
DSO="\$(CC)"
|
DSO="\$(CC)"
|
||||||
DSOFLAGS="$DSOFLAGS -Wl,-soname,libmxml.so.1,-rpath,\$(libdir) -shared \$(OPTIM)"
|
DSOFLAGS="$DSOFLAGS -Wl,-no_warn_inits -dynamiclib -lc"
|
||||||
LDFLAGS="$LDFLAGS -Wl,-rpath,\$(libdir)"
|
], [sunos*], [
|
||||||
], [*bsd | haiku*], [
|
LIBMXML="libmxml.so.2"
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
LIBMXML="libmxml.so.1.6"
|
|
||||||
DSO="\$(CC)"
|
DSO="\$(CC)"
|
||||||
DSOFLAGS="$DSOFLAGS -Wl,-soname,libmxml.so.1,-R\$(libdir) -shared \$(OPTIM)"
|
DSOFLAGS="$DSOFLAGS -Wl,-h,\`basename \$@\` -G"
|
||||||
LDFLAGS="$LDFLAGS -Wl,-R\$(libdir)"
|
|
||||||
], [darwin], [
|
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
LIBMXML="libmxml.1.dylib"
|
|
||||||
DSO="\$(CC)"
|
|
||||||
DSOFLAGS="$DSOFLAGS \$(RC_CFLAGS) -dynamiclib -lc"
|
|
||||||
], [mingw], [
|
], [mingw], [
|
||||||
AC_MSG_RESULT([yes])
|
AC_MSG_RESULT([yes])
|
||||||
LIBMXML="mxml1.dll"
|
LIBMXML="libmxml2.dll"
|
||||||
DSO="\$(CC)"
|
DSO="\$(CC)"
|
||||||
DSOFLAGS="$DSOFLAGS -shared -Wl,--out-implib,libmxml1.a,--no-undefined,--enable-runtime-pseudo-reloc"
|
DSOFLAGS="$DSOFLAGS -shared -Wl,--out-implib,libmxml2.a,--no-undefined,--enable-runtime-pseudo-reloc"
|
||||||
], [*], [
|
], [*], [
|
||||||
AC_MSG_RESULT([no])
|
AC_MSG_NOTICE([Warning: Shared libraries may not work, trying -shared option.])
|
||||||
AC_MSG_WARN([shared libraries not supported on this platform.])
|
LIBMXML="libmxml.so.2"
|
||||||
PICFLAG=0
|
DSO="\$(CC)"
|
||||||
LIBMXML="libmxml.a"
|
DSOFLAGS="$DSOFLAGS -Wl,-soname,\`basename \$@\` -shared"
|
||||||
|
])
|
||||||
|
|
||||||
|
AS_IF([test x$enable_static != xno], [
|
||||||
|
AC_MSG_NOTICE([Installing static libraries...])
|
||||||
|
INSTALL_STATIC="install-libmxml.a"
|
||||||
|
UNINSTALL_STATIC="uninstall-libmxml.a"
|
||||||
|
], [
|
||||||
|
INSTALL_STATIC=""
|
||||||
|
UNINSTALL_STATIC=""
|
||||||
])
|
])
|
||||||
], [
|
], [
|
||||||
PICFLAG=0
|
INSTALL_STATIC=""
|
||||||
LIBMXML="libmxml.a"
|
LIBMXML="libmxml.a"
|
||||||
|
UNINSTALL_STATIC=""
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_SUBST([DSO])
|
AC_SUBST([INSTALL_STATIC])
|
||||||
AC_SUBST([DSOFLAGS])
|
|
||||||
AC_SUBST([LIBMXML])
|
AC_SUBST([LIBMXML])
|
||||||
AC_SUBST([PICFLAG])
|
AC_SUBST([LIBMXML_STATIC])
|
||||||
|
AC_SUBST([UNINSTALL_STATIC])
|
||||||
|
|
||||||
|
|
||||||
dnl Compiler options...
|
dnl Extra compiler options...
|
||||||
|
AC_ARG_ENABLE([debug], AS_HELP_STRING([--enable-debug], [turn on debugging, default=no]))
|
||||||
|
AC_ARG_ENABLE([maintainer], AS_HELP_STRING([--enable-maintainer], [turn on maintainer mode, default=no]))
|
||||||
|
AC_ARG_WITH([sanitizer], AS_HELP_STRING([--with-sanitizer], [build with address, leak, memory, thread, or undefined sanitizer, default=no]), [], [with_sanitizer=no])
|
||||||
|
AS_IF([test "x$with_sanitizer" = xyes], [
|
||||||
|
with_sanitizer="address"
|
||||||
|
], [test "$with_sanitizer" != address -a "$with_sanitizer" != leak -a "$with_sanitizer" != memory -a "$with_sanitizer" != no -a "$with_sanitizer" != thread -a "$with_sanitizer" != undefined], [
|
||||||
|
AC_MSG_ERROR([Unsupported --with-sanitizer value "$with_sanitizer" specified.])
|
||||||
|
])
|
||||||
|
|
||||||
|
AS_IF([test x$enable_debug = xyes], [
|
||||||
|
CSFLAGS=""
|
||||||
|
OPTIM="$OPTIM -g"
|
||||||
|
OPTIONS="-DDEBUG -DDEBUG_GUARDS"
|
||||||
|
], [
|
||||||
|
CSFLAGS="-o runtime"
|
||||||
|
OPTIM="$OPTIM -g -Os"
|
||||||
|
OPTIONS=""
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_SUBST([CSFLAGS])
|
||||||
|
AC_SUBST([OPTIONS])
|
||||||
|
|
||||||
WARNINGS=""
|
WARNINGS=""
|
||||||
AC_SUBST([WARNINGS])
|
AC_SUBST([WARNINGS])
|
||||||
|
|
||||||
AS_IF([test -n "$GCC"], [
|
AS_IF([test -n "$GCC"], [
|
||||||
CFLAGS="-D_GNU_SOURCE $CFLAGS"
|
AS_IF([test x$with_sanitizer != xno], [
|
||||||
|
# Use -fsanitize=FOO with debugging...
|
||||||
AS_IF([test "x$OPTIM" = x], [
|
OPTIM="$OPTIM -fsanitize=$with_sanitizer"
|
||||||
AS_IF([test x$enable_debug = xyes], [
|
], [echo "$CPPFLAGS $CFLAGS" | grep -q _FORTIFY_SOURCE], [
|
||||||
OPTIM="-g"
|
# Don't add _FORTIFY_SOURCE if it is already there
|
||||||
], [
|
|
||||||
OPTIM="-g -Os"
|
|
||||||
])
|
|
||||||
], [test x$enable_debug = xyes], [
|
|
||||||
OPTIM="$OPTIM -g"
|
|
||||||
])
|
|
||||||
|
|
||||||
AS_IF([test x$enable_sanitizer = xyes], [
|
|
||||||
# Use -fsanitize=address with debugging...
|
|
||||||
OPTIM="$OPTIM -fsanitize=address"
|
|
||||||
], [
|
], [
|
||||||
# Otherwise use the Fortify enhancements to catch any unbounded
|
# Otherwise use the Fortify enhancements to catch any unbounded
|
||||||
# string operations...
|
# string operations...
|
||||||
CPPFLAGS="$CPPFLAGS -D_FORTIFY_SOURCE=2"
|
CPPFLAGS="$CPPFLAGS -D_FORTIFY_SOURCE=3"
|
||||||
])
|
|
||||||
|
|
||||||
AS_IF([test "x$use_ansi" = xyes], [
|
|
||||||
CFLAGS="-ansi -pedantic $CFLAGS"
|
|
||||||
])
|
])
|
||||||
|
|
||||||
dnl Show all standard warnings + unused variables when compiling...
|
dnl Show all standard warnings + unused variables when compiling...
|
||||||
WARNINGS="-Wall -Wunused"
|
WARNINGS="-Wall -Wunused"
|
||||||
|
|
||||||
dnl Drop some not-useful/unreliable warnings...
|
dnl Drop some not-useful/unreliable warnings...
|
||||||
for warning in char-subscripts format-truncation format-y2k switch unused-result; do
|
for warning in char-subscripts deprecated-declarations format-truncation format-y2k switch unused-result; do
|
||||||
AC_MSG_CHECKING([whether compiler supports -Wno-$warning])
|
AC_MSG_CHECKING([whether compiler supports -Wno-$warning])
|
||||||
|
|
||||||
OLDCFLAGS="$CFLAGS"
|
OLDCFLAGS="$CFLAGS"
|
||||||
CFLAGS="$CFLAGS -Wno-$warning -Werror"
|
CFLAGS="$CFLAGS -Wno-$warning -Werror"
|
||||||
|
|
||||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], [
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT([yes])
|
||||||
WARNINGS="$WARNINGS -Wno-$warning"
|
WARNINGS="$WARNINGS -Wno-$warning"
|
||||||
], [
|
], [
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT([no])
|
||||||
])
|
])
|
||||||
|
|
||||||
CFLAGS="$OLDCFLAGS"
|
CFLAGS="$OLDCFLAGS"
|
||||||
@ -295,32 +238,111 @@ AS_IF([test -n "$GCC"], [
|
|||||||
WARNINGS="$WARNINGS -Werror"
|
WARNINGS="$WARNINGS -Werror"
|
||||||
])
|
])
|
||||||
|
|
||||||
AS_IF([test $PICFLAG = 1 -a "$host_os_name" != aix], [
|
dnl See if PIE options are supported...
|
||||||
OPTIM="-fPIC $OPTIM"
|
AC_MSG_CHECKING(whether compiler supports -fPIE)
|
||||||
|
OLDCFLAGS="$CFLAGS"
|
||||||
|
AS_CASE(["$host_os_name"],
|
||||||
|
[darwin*], [
|
||||||
|
CFLAGS="$CFLAGS -fPIC -fPIE -Wl,-pie"
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[
|
||||||
|
OLDCFLAGS="-fPIC $OLDCFLAGS"
|
||||||
|
LDFLAGS="-fPIE -Wl,-pie $LDFLAGS"
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
])
|
||||||
|
], [*], [
|
||||||
|
CFLAGS="$CFLAGS -fPIC -fPIE -pie"
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[
|
||||||
|
OLDCFLAGS="-fPIC $OLDCFLAGS"
|
||||||
|
LDFLAGS="-fPIE -pie $LDFLAGS"
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
])
|
||||||
])
|
])
|
||||||
], [
|
CFLAGS="$OLDCFLAGS"
|
||||||
AS_IF([test "x$OPTIM" = x], [
|
|
||||||
AS_IF([test x$enable_debug = xyes], [
|
dnl OS-specific compiler options...
|
||||||
OPTIM="-g"
|
AC_MSG_CHECKING([for OS-specific compiler options])
|
||||||
|
AS_CASE(["$host_os_name"], [linux*], [
|
||||||
|
# Make sure we get the full set of Linux APIs from the headers...
|
||||||
|
CPPFLAGS="$CPPFLAGS -D__USE_MISC -D_GNU_SOURCE"
|
||||||
|
|
||||||
|
# Mark read-only sections as relocatable to random addresses...
|
||||||
|
LDFLAGS="$LDFLAGS -Wl,-z,relro,-z,now"
|
||||||
|
|
||||||
|
AC_MSG_RESULT([-D__USE_MISC -D_GNU_SOURCE -Wl,-z,relro,-z,now])
|
||||||
|
], [darwin*], [
|
||||||
|
# When not building for debug, target macOS 11 or later, "universal"
|
||||||
|
# binaries when possible...
|
||||||
|
AS_IF([echo "$CPPFLAGS $CFLAGS $LDFLAGS $OPTIM" | grep -q "\\-arch "], [
|
||||||
|
# Don't add architecture/min-version flags if they are already present
|
||||||
|
AC_MSG_RESULT([none])
|
||||||
|
], [echo "$CPPFLAGS $CFLAGS $LDFLAGS $OPTIM" | grep -q "\\-mmacosx-version-"], [
|
||||||
|
# Don't add architecture/min-version flags if they are already present
|
||||||
|
AC_MSG_RESULT([none])
|
||||||
|
], [test "$host_os_version" -ge 200 -a x$enable_debug != xyes], [
|
||||||
|
# macOS 11.0 and higher support the Apple Silicon (arm64) CPUs
|
||||||
|
OPTIM="$OPTIM -mmacosx-version-min=11.0 -arch x86_64 -arch arm64"
|
||||||
|
AC_MSG_RESULT([-mmacosx-version-min=11.0 -arch x86_64 -arch arm64])
|
||||||
], [
|
], [
|
||||||
OPTIM="-O"
|
# Don't add architecture/min-version flags if debug enabled
|
||||||
])
|
AC_MSG_RESULT([none])
|
||||||
])
|
|
||||||
|
|
||||||
AS_CASE(["$host_os_name"], [hp-ux], [
|
|
||||||
CFLAGS="-Ae $CFLAGS"
|
|
||||||
|
|
||||||
OPTIM="+DAportable $OPTIM"
|
|
||||||
|
|
||||||
AS_IF([test $PICFLAG = 1], [
|
|
||||||
OPTIM="+z $OPTIM"
|
|
||||||
])
|
|
||||||
], [unix_svr | sunos], [
|
|
||||||
AS_IF([test $PICFLAG = 1], [
|
|
||||||
OPTIM="-KPIC $OPTIM"
|
|
||||||
])
|
])
|
||||||
|
], [*], [
|
||||||
|
AC_MSG_RESULT([none])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl Extra linker options...
|
||||||
|
AC_ARG_WITH([dsoflags], AS_HELP_STRING([--with-dsoflags=...], [Specify additional DSOFLAGS]), [
|
||||||
|
DSOFLAGS="$withval $DSOFLAGS"
|
||||||
|
])
|
||||||
|
AC_ARG_WITH([ldflags], AS_HELP_STRING([--with-ldflags=...], [Specify additional LDFLAGS]), [
|
||||||
|
LDFLAGS="$withval $LDFLAGS"
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl Directories...
|
||||||
|
AC_ARG_WITH([docdir], AS_HELP_STRING([--with-docdir], [set directory for documentation, default=${prefix}/share/doc/mxml]), [
|
||||||
|
docdir="$withval"
|
||||||
|
], [
|
||||||
|
docdir="NONE"
|
||||||
|
])
|
||||||
|
AC_SUBST(docdir)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dnl Determine whether we are cross-compiling...
|
dnl Determine whether we are cross-compiling...
|
||||||
@ -333,39 +355,44 @@ AC_SUBST([TARGETS])
|
|||||||
|
|
||||||
|
|
||||||
dnl Fix installation directories...
|
dnl Fix installation directories...
|
||||||
AS_IF([test "$prefix" = "NONE"], [
|
AS_IF([test "$prefix" = NONE], [
|
||||||
prefix="/usr/local"
|
# Default prefix isn't bound until AC_OUTPUT...
|
||||||
])
|
realprefix="/usr/local"
|
||||||
|
|
||||||
AS_IF([test "$exec_prefix" = "NONE"], [
|
|
||||||
exec_prefix="$prefix"
|
|
||||||
])
|
|
||||||
|
|
||||||
AS_IF([test "$docdir" = "NONE"], [
|
|
||||||
docdir="$datadir/doc/mxml"
|
|
||||||
])
|
|
||||||
|
|
||||||
AS_IF([test "$mandir" = "\${prefix}/man" -a "$prefix" = "/usr"], [
|
|
||||||
mandir="/usr/share/man"
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
||||||
dnl pkg-config stuff...
|
|
||||||
AS_IF([test "$includedir" != /usr/include], [
|
|
||||||
PC_CFLAGS="-I$includedir"
|
|
||||||
], [
|
], [
|
||||||
PC_CFLAGS=""
|
realprefix="$prefix"
|
||||||
])
|
])
|
||||||
AC_SUBST([PC_CFLAGS])
|
|
||||||
|
|
||||||
AS_IF([test "$libdir" != /usr/lib], [
|
AS_IF([test "$datarootdir" = "\${prefix}/share"], [
|
||||||
PC_LIBS="-L$libdir -lmxml"
|
AS_IF([test "$prefix" = "/"], [
|
||||||
], [
|
datarootdir="/usr/share"
|
||||||
PC_LIBS="-lmxml"
|
], [
|
||||||
|
datarootdir="$realprefix/share"
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
|
AS_IF([test "$datadir" = "\${prefix}/share"], [
|
||||||
|
AS_IF([test "$prefix" = "/"], [
|
||||||
|
datadir="/usr/share"
|
||||||
|
], [
|
||||||
|
datadir="$realprefix/share"
|
||||||
|
])
|
||||||
|
], [test "$datadir" = "\${datarootdir}"], [
|
||||||
|
datadir="$datarootdir"
|
||||||
])
|
])
|
||||||
AC_SUBST([PC_LIBS])
|
|
||||||
|
|
||||||
|
|
||||||
dnl Output the makefile, etc...
|
dnl pkg-config flags...
|
||||||
|
PKGCONFIG_CFLAGS=""
|
||||||
|
PKGCONFIG_LIBS="-lmxml"
|
||||||
|
AS_IF([test "$realprefix" != "/usr" -a "$realprefix" != "/usr/local"], [
|
||||||
|
PKGCONFIG_CFLAGS="-I\${includedir}"
|
||||||
|
PKGCONFIG_LIBS="-L\${libdir} $PKGCONFIG_LIBS"
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_SUBST([PKGCONFIG_CFLAGS])
|
||||||
|
AC_SUBST([PKGCONFIG_LIBS])
|
||||||
|
|
||||||
|
|
||||||
|
dnl Output generated files...
|
||||||
AC_CONFIG_FILES([Makefile mxml.pc])
|
AC_CONFIG_FILES([Makefile mxml.pc])
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
320
mxml-attr.c
320
mxml-attr.c
@ -1,73 +1,50 @@
|
|||||||
/*
|
//
|
||||||
* Attribute support code for Mini-XML, a small XML file parsing library.
|
// Attribute support code for Mini-XML, a small XML file parsing library.
|
||||||
*
|
//
|
||||||
* https://www.msweet.org/mxml
|
// https://www.msweet.org/mxml
|
||||||
*
|
//
|
||||||
* Copyright © 2003-2021 by Michael R Sweet.
|
// Copyright © 2003-2024 by Michael R Sweet.
|
||||||
*
|
//
|
||||||
* Licensed under Apache License v2.0. See the file "LICENSE" for more
|
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
||||||
* information.
|
// information.
|
||||||
*/
|
//
|
||||||
|
|
||||||
/*
|
|
||||||
* Include necessary headers...
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "mxml-private.h"
|
#include "mxml-private.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Local functions...
|
// Local functions...
|
||||||
*/
|
//
|
||||||
|
|
||||||
static int mxml_set_attr(mxml_node_t *node, const char *name, char *value);
|
static int mxml_set_attr(mxml_node_t *node, const char *name, char *value);
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlElementDeleteAttr()' - Delete an attribute.
|
// 'mxmlElementDeleteAttr()' - Delete an attribute.
|
||||||
*
|
//
|
||||||
* @since Mini-XML 2.4@
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
void
|
||||||
mxmlElementDeleteAttr(mxml_node_t *node,/* I - Element */
|
mxmlElementDeleteAttr(mxml_node_t *node,// I - Element
|
||||||
const char *name)/* I - Attribute name */
|
const char *name)// I - Attribute name
|
||||||
{
|
{
|
||||||
int i; /* Looping var */
|
int i; // Looping var
|
||||||
_mxml_attr_t *attr; /* Cirrent attribute */
|
_mxml_attr_t *attr; // Cirrent attribute
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
MXML_DEBUG("mxmlElementDeleteAttr(node=%p, name=\"%s\")\n", node, name ? name : "(null)");
|
||||||
fprintf(stderr, "mxmlElementDeleteAttr(node=%p, name=\"%s\")\n",
|
|
||||||
node, name ? name : "(null)");
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
if (!node || node->type != MXML_TYPE_ELEMENT || !name)
|
||||||
*/
|
|
||||||
|
|
||||||
if (!node || node->type != MXML_ELEMENT || !name)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
// Look for the attribute...
|
||||||
* Look for the attribute...
|
for (i = node->value.element.num_attrs, attr = node->value.element.attrs; i > 0; i --, attr ++)
|
||||||
*/
|
|
||||||
|
|
||||||
for (i = node->value.element.num_attrs, attr = node->value.element.attrs;
|
|
||||||
i > 0;
|
|
||||||
i --, attr ++)
|
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
MXML_DEBUG("mxmlElementDeleteAttr: %s=\"%s\"\n", attr->name, attr->value);
|
||||||
printf(" %s=\"%s\"\n", attr->name, attr->value);
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
if (!strcmp(attr->name, name))
|
if (!strcmp(attr->name, name))
|
||||||
{
|
{
|
||||||
/*
|
// Delete this attribute...
|
||||||
* Delete this attribute...
|
|
||||||
*/
|
|
||||||
|
|
||||||
free(attr->name);
|
free(attr->name);
|
||||||
free(attr->value);
|
free(attr->value);
|
||||||
|
|
||||||
@ -85,82 +62,60 @@ mxmlElementDeleteAttr(mxml_node_t *node,/* I - Element */
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlElementGetAttr()' - Get an attribute.
|
// 'mxmlElementGetAttr()' - Get an attribute.
|
||||||
*
|
//
|
||||||
* This function returns @code NULL@ if the node is not an element or the
|
// This function returns @code NULL@ if the node is not an element or the
|
||||||
* named attribute does not exist.
|
// named attribute does not exist.
|
||||||
*/
|
//
|
||||||
|
|
||||||
const char * /* O - Attribute value or @code NULL@ */
|
const char * // O - Attribute value or @code NULL@
|
||||||
mxmlElementGetAttr(mxml_node_t *node, /* I - Element node */
|
mxmlElementGetAttr(mxml_node_t *node, // I - Element node
|
||||||
const char *name) /* I - Name of attribute */
|
const char *name) // I - Name of attribute
|
||||||
{
|
{
|
||||||
int i; /* Looping var */
|
int i; // Looping var
|
||||||
_mxml_attr_t *attr; /* Cirrent attribute */
|
_mxml_attr_t *attr; // Cirrent attribute
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
MXML_DEBUG("mxmlElementGetAttr(node=%p, name=\"%s\")\n", node, name ? name : "(null)");
|
||||||
fprintf(stderr, "mxmlElementGetAttr(node=%p, name=\"%s\")\n",
|
|
||||||
node, name ? name : "(null)");
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
if (!node || node->type != MXML_TYPE_ELEMENT || !name)
|
||||||
*/
|
|
||||||
|
|
||||||
if (!node || node->type != MXML_ELEMENT || !name)
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
/*
|
// Look for the attribute...
|
||||||
* Look for the attribute...
|
for (i = node->value.element.num_attrs, attr = node->value.element.attrs; i > 0; i --, attr ++)
|
||||||
*/
|
|
||||||
|
|
||||||
for (i = node->value.element.num_attrs, attr = node->value.element.attrs;
|
|
||||||
i > 0;
|
|
||||||
i --, attr ++)
|
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
MXML_DEBUG("mxmlElementGetAttr: %s=\"%s\"\n", attr->name, attr->value);
|
||||||
printf(" %s=\"%s\"\n", attr->name, attr->value);
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
if (!strcmp(attr->name, name))
|
if (!strcmp(attr->name, name))
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
MXML_DEBUG("mxmlElementGetAttr: Returning \"%s\".\n", attr->value);
|
||||||
printf(" Returning \"%s\"!\n", attr->value);
|
|
||||||
#endif /* DEBUG */
|
|
||||||
return (attr->value);
|
return (attr->value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Didn't find attribute, so return NULL...
|
||||||
* Didn't find attribute, so return NULL...
|
MXML_DEBUG("mxmlElementGetAttr: Returning NULL.\n");
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
puts(" Returning NULL!\n");
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlElementGetAttrByIndex()' - Get an element attribute by index.
|
// 'mxmlElementGetAttrByIndex()' - Get an element attribute by index.
|
||||||
*
|
//
|
||||||
* The index ("idx") is 0-based. @code NULL@ is returned if the specified index
|
// The index ("idx") is 0-based. @code NULL@ is returned if the specified index
|
||||||
* is out of range.
|
// is out of range.
|
||||||
*
|
//
|
||||||
* @since Mini-XML 2.11@
|
|
||||||
*/
|
|
||||||
|
|
||||||
const char * /* O - Attribute value */
|
const char * // O - Attribute value
|
||||||
mxmlElementGetAttrByIndex(
|
mxmlElementGetAttrByIndex(
|
||||||
mxml_node_t *node, /* I - Node */
|
mxml_node_t *node, // I - Node
|
||||||
int idx, /* I - Attribute index, starting at 0 */
|
int idx, // I - Attribute index, starting at 0
|
||||||
const char **name) /* O - Attribute name */
|
const char **name) // O - Attribute name
|
||||||
{
|
{
|
||||||
if (!node || node->type != MXML_ELEMENT || idx < 0 || idx >= node->value.element.num_attrs)
|
if (!node || node->type != MXML_TYPE_ELEMENT || idx < 0 || idx >= node->value.element.num_attrs)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
if (name)
|
if (name)
|
||||||
@ -170,50 +125,42 @@ mxmlElementGetAttrByIndex(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlElementGetAttrCount()' - Get the number of element attributes.
|
// 'mxmlElementGetAttrCount()' - Get the number of element attributes.
|
||||||
*
|
//
|
||||||
* @since Mini-XML 2.11@
|
|
||||||
*/
|
|
||||||
|
|
||||||
int /* O - Number of attributes */
|
int // O - Number of attributes
|
||||||
mxmlElementGetAttrCount(
|
mxmlElementGetAttrCount(
|
||||||
mxml_node_t *node) /* I - Node */
|
mxml_node_t *node) // I - Node
|
||||||
{
|
{
|
||||||
if (node && node->type == MXML_ELEMENT)
|
if (node && node->type == MXML_TYPE_ELEMENT)
|
||||||
return (node->value.element.num_attrs);
|
return (node->value.element.num_attrs);
|
||||||
else
|
else
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlElementSetAttr()' - Set an attribute.
|
// 'mxmlElementSetAttr()' - Set an attribute.
|
||||||
*
|
//
|
||||||
* If the named attribute already exists, the value of the attribute
|
// If the named attribute already exists, the value of the attribute
|
||||||
* is replaced by the new string value. The string value is copied
|
// is replaced by the new string value. The string value is copied
|
||||||
* into the element node. This function does nothing if the node is
|
// into the element node. This function does nothing if the node is
|
||||||
* not an element.
|
// not an element.
|
||||||
*/
|
//
|
||||||
|
|
||||||
void
|
void
|
||||||
mxmlElementSetAttr(mxml_node_t *node, /* I - Element node */
|
mxmlElementSetAttr(mxml_node_t *node, // I - Element node
|
||||||
const char *name, /* I - Name of attribute */
|
const char *name, // I - Name of attribute
|
||||||
const char *value) /* I - Attribute value */
|
const char *value) // I - Attribute value
|
||||||
{
|
{
|
||||||
char *valuec; /* Copy of value */
|
char *valuec; // Copy of value
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
MXML_DEBUG("mxmlElementSetAttr(node=%p, name=\"%s\", value=\"%s\")\n", node, name ? name : "(null)", value ? value : "(null)");
|
||||||
fprintf(stderr, "mxmlElementSetAttr(node=%p, name=\"%s\", value=\"%s\")\n",
|
|
||||||
node, name ? name : "(null)", value ? value : "(null)");
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
if (!node || node->type != MXML_TYPE_ELEMENT || !name)
|
||||||
*/
|
|
||||||
|
|
||||||
if (!node || node->type != MXML_ELEMENT || !name)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (value)
|
if (value)
|
||||||
@ -225,109 +172,85 @@ mxmlElementSetAttr(mxml_node_t *node, /* I - Element node */
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
valuec = NULL;
|
valuec = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (mxml_set_attr(node, name, valuec))
|
if (mxml_set_attr(node, name, valuec))
|
||||||
free(valuec);
|
free(valuec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlElementSetAttrf()' - Set an attribute with a formatted value.
|
// 'mxmlElementSetAttrf()' - Set an attribute with a formatted value.
|
||||||
*
|
//
|
||||||
* If the named attribute already exists, the value of the attribute
|
// If the named attribute already exists, the value of the attribute
|
||||||
* is replaced by the new formatted string. The formatted string value is
|
// is replaced by the new formatted string. The formatted string value is
|
||||||
* copied into the element node. This function does nothing if the node
|
// copied into the element node. This function does nothing if the node
|
||||||
* is not an element.
|
// is not an element.
|
||||||
*
|
//
|
||||||
* @since Mini-XML 2.3@
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
void
|
||||||
mxmlElementSetAttrf(mxml_node_t *node, /* I - Element node */
|
mxmlElementSetAttrf(mxml_node_t *node, // I - Element node
|
||||||
const char *name, /* I - Name of attribute */
|
const char *name, // I - Name of attribute
|
||||||
const char *format,/* I - Printf-style attribute value */
|
const char *format,// I - Printf-style attribute value
|
||||||
...) /* I - Additional arguments as needed */
|
...) // I - Additional arguments as needed
|
||||||
{
|
{
|
||||||
va_list ap; /* Argument pointer */
|
va_list ap; // Argument pointer
|
||||||
char *value; /* Value */
|
char buffer[16384]; // Format buffer
|
||||||
|
char *value; // Value
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
MXML_DEBUG("mxmlElementSetAttrf(node=%p, name=\"%s\", format=\"%s\", ...)\n", node, name ? name : "(null)", format ? format : "(null)");
|
||||||
fprintf(stderr,
|
|
||||||
"mxmlElementSetAttrf(node=%p, name=\"%s\", format=\"%s\", ...)\n",
|
|
||||||
node, name ? name : "(null)", format ? format : "(null)");
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
if (!node || node->type != MXML_TYPE_ELEMENT || !name || !format)
|
||||||
*/
|
|
||||||
|
|
||||||
if (!node || node->type != MXML_ELEMENT || !name || !format)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
// Format the value...
|
||||||
* Format the value...
|
|
||||||
*/
|
|
||||||
|
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
value = _mxml_vstrdupf(format, ap);
|
vsnprintf(buffer, sizeof(buffer), format, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
if (!value)
|
if ((value = strdup(buffer)) == NULL)
|
||||||
mxml_error("Unable to allocate memory for attribute '%s' in element %s.",
|
mxml_error("Unable to allocate memory for attribute '%s' in element %s.", name, node->value.element.name);
|
||||||
name, node->value.element.name);
|
|
||||||
else if (mxml_set_attr(node, name, value))
|
else if (mxml_set_attr(node, name, value))
|
||||||
free(value);
|
free(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxml_set_attr()' - Set or add an attribute name/value pair.
|
// 'mxml_set_attr()' - Set or add an attribute name/value pair.
|
||||||
*/
|
//
|
||||||
|
|
||||||
static int /* O - 0 on success, -1 on failure */
|
static int // O - 0 on success, -1 on failure
|
||||||
mxml_set_attr(mxml_node_t *node, /* I - Element node */
|
mxml_set_attr(mxml_node_t *node, // I - Element node
|
||||||
const char *name, /* I - Attribute name */
|
const char *name, // I - Attribute name
|
||||||
char *value) /* I - Attribute value */
|
char *value) // I - Attribute value
|
||||||
{
|
{
|
||||||
int i; /* Looping var */
|
int i; // Looping var
|
||||||
_mxml_attr_t *attr; /* New attribute */
|
_mxml_attr_t *attr; // New attribute
|
||||||
|
|
||||||
|
|
||||||
/*
|
// Look for the attribute...
|
||||||
* Look for the attribute...
|
for (i = node->value.element.num_attrs, attr = node->value.element.attrs; i > 0; i --, attr ++)
|
||||||
*/
|
{
|
||||||
|
|
||||||
for (i = node->value.element.num_attrs, attr = node->value.element.attrs;
|
|
||||||
i > 0;
|
|
||||||
i --, attr ++)
|
|
||||||
if (!strcmp(attr->name, name))
|
if (!strcmp(attr->name, name))
|
||||||
{
|
{
|
||||||
/*
|
// Free the old value as needed...
|
||||||
* Free the old value as needed...
|
|
||||||
*/
|
|
||||||
|
|
||||||
free(attr->value);
|
free(attr->value);
|
||||||
attr->value = value;
|
attr->value = value;
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
// Add a new attribute...
|
||||||
* Add a new attribute...
|
attr = realloc(node->value.element.attrs, (node->value.element.num_attrs + 1) * sizeof(_mxml_attr_t));
|
||||||
*/
|
|
||||||
|
|
||||||
if (node->value.element.num_attrs == 0)
|
|
||||||
attr = malloc(sizeof(_mxml_attr_t));
|
|
||||||
else
|
|
||||||
attr = realloc(node->value.element.attrs,
|
|
||||||
(node->value.element.num_attrs + 1) * sizeof(_mxml_attr_t));
|
|
||||||
|
|
||||||
if (!attr)
|
if (!attr)
|
||||||
{
|
{
|
||||||
mxml_error("Unable to allocate memory for attribute '%s' in element %s.",
|
mxml_error("Unable to allocate memory for attribute '%s' in element %s.", name, node->value.element.name);
|
||||||
name, node->value.element.name);
|
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,8 +259,7 @@ mxml_set_attr(mxml_node_t *node, /* I - Element node */
|
|||||||
|
|
||||||
if ((attr->name = strdup(name)) == NULL)
|
if ((attr->name = strdup(name)) == NULL)
|
||||||
{
|
{
|
||||||
mxml_error("Unable to allocate memory for attribute '%s' in element %s.",
|
mxml_error("Unable to allocate memory for attribute '%s' in element %s.", name, node->value.element.name);
|
||||||
name, node->value.element.name);
|
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
129
mxml-entity.c
129
mxml-entity.c
@ -1,31 +1,27 @@
|
|||||||
/*
|
//
|
||||||
* Character entity support code for Mini-XML, a small XML file parsing library.
|
// Character entity support code for Mini-XML, a small XML file parsing library.
|
||||||
*
|
//
|
||||||
* https://www.msweet.org/mxml
|
// https://www.msweet.org/mxml
|
||||||
*
|
//
|
||||||
* Copyright © 2003-2019 by Michael R Sweet.
|
// Copyright © 2003-2024 by Michael R Sweet.
|
||||||
*
|
//
|
||||||
* Licensed under Apache License v2.0. See the file "LICENSE" for more
|
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
||||||
* information.
|
// information.
|
||||||
*/
|
//
|
||||||
|
|
||||||
/*
|
|
||||||
* Include necessary headers...
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "mxml-private.h"
|
#include "mxml-private.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlEntityAddCallback()' - Add a callback to convert entities to Unicode.
|
// 'mxmlEntityAddCallback()' - Add a callback to convert entities to Unicode.
|
||||||
*/
|
//
|
||||||
|
|
||||||
int /* O - 0 on success, -1 on failure */
|
int // O - 0 on success, -1 on failure
|
||||||
mxmlEntityAddCallback(
|
mxmlEntityAddCallback(
|
||||||
mxml_entity_cb_t cb) /* I - Callback function to add */
|
mxml_entity_cb_t cb) // I - Callback function to add
|
||||||
{
|
{
|
||||||
_mxml_global_t *global = _mxml_global();
|
_mxml_global_t *global = _mxml_global();
|
||||||
/* Global data */
|
// Global data
|
||||||
|
|
||||||
|
|
||||||
if (global->num_entity_cbs < (int)(sizeof(global->entity_cbs) / sizeof(global->entity_cbs[0])))
|
if (global->num_entity_cbs < (int)(sizeof(global->entity_cbs) / sizeof(global->entity_cbs[0])))
|
||||||
@ -44,14 +40,14 @@ mxmlEntityAddCallback(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlEntityGetName()' - Get the name that corresponds to the character value.
|
// 'mxmlEntityGetName()' - Get the name that corresponds to the character value.
|
||||||
*
|
//
|
||||||
* If val does not need to be represented by a named entity, @code NULL@ is returned.
|
// If val does not need to be represented by a named entity, @code NULL@ is returned.
|
||||||
*/
|
//
|
||||||
|
|
||||||
const char * /* O - Entity name or @code NULL@ */
|
const char * // O - Entity name or @code NULL@
|
||||||
mxmlEntityGetName(int val) /* I - Character value */
|
mxmlEntityGetName(int val) // I - Character value
|
||||||
{
|
{
|
||||||
switch (val)
|
switch (val)
|
||||||
{
|
{
|
||||||
@ -73,76 +69,76 @@ mxmlEntityGetName(int val) /* I - Character value */
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlEntityGetValue()' - Get the character corresponding to a named entity.
|
// 'mxmlEntityGetValue()' - Get the character corresponding to a named entity.
|
||||||
*
|
//
|
||||||
* The entity name can also be a numeric constant. -1 is returned if the
|
// The entity name can also be a numeric constant. -1 is returned if the
|
||||||
* name is not known.
|
// name is not known.
|
||||||
*/
|
//
|
||||||
|
|
||||||
int /* O - Character value or -1 on error */
|
int // O - Character value or -1 on error
|
||||||
mxmlEntityGetValue(const char *name) /* I - Entity name */
|
mxmlEntityGetValue(const char *name) // I - Entity name
|
||||||
{
|
{
|
||||||
int i; /* Looping var */
|
int i; // Looping var
|
||||||
int ch; /* Character value */
|
int ch; // Character value
|
||||||
_mxml_global_t *global = _mxml_global();
|
_mxml_global_t *global = _mxml_global();
|
||||||
/* Global data */
|
// Global data
|
||||||
|
|
||||||
|
|
||||||
for (i = 0; i < global->num_entity_cbs; i ++)
|
for (i = 0; i < global->num_entity_cbs; i ++)
|
||||||
|
{
|
||||||
if ((ch = (global->entity_cbs[i])(name)) >= 0)
|
if ((ch = (global->entity_cbs[i])(name)) >= 0)
|
||||||
return (ch);
|
return (ch);
|
||||||
|
}
|
||||||
|
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlEntityRemoveCallback()' - Remove a callback.
|
// 'mxmlEntityRemoveCallback()' - Remove a callback.
|
||||||
*/
|
//
|
||||||
|
|
||||||
void
|
void
|
||||||
mxmlEntityRemoveCallback(
|
mxmlEntityRemoveCallback(
|
||||||
mxml_entity_cb_t cb) /* I - Callback function to remove */
|
mxml_entity_cb_t cb) // I - Callback function to remove
|
||||||
{
|
{
|
||||||
int i; /* Looping var */
|
int i; // Looping var
|
||||||
_mxml_global_t *global = _mxml_global();
|
_mxml_global_t *global = _mxml_global();
|
||||||
/* Global data */
|
// Global data
|
||||||
|
|
||||||
|
|
||||||
for (i = 0; i < global->num_entity_cbs; i ++)
|
for (i = 0; i < global->num_entity_cbs; i ++)
|
||||||
|
{
|
||||||
if (cb == global->entity_cbs[i])
|
if (cb == global->entity_cbs[i])
|
||||||
{
|
{
|
||||||
/*
|
// Remove the callback...
|
||||||
* Remove the callback...
|
|
||||||
*/
|
|
||||||
|
|
||||||
global->num_entity_cbs --;
|
global->num_entity_cbs --;
|
||||||
|
|
||||||
if (i < global->num_entity_cbs)
|
if (i < global->num_entity_cbs)
|
||||||
memmove(global->entity_cbs + i, global->entity_cbs + i + 1,
|
memmove(global->entity_cbs + i, global->entity_cbs + i + 1, (global->num_entity_cbs - i) * sizeof(global->entity_cbs[0]));
|
||||||
(global->num_entity_cbs - i) * sizeof(global->entity_cbs[0]));
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* '_mxml_entity_cb()' - Lookup standard (X)HTML entities.
|
// '_mxml_entity_cb()' - Lookup standard (X)HTML entities.
|
||||||
*/
|
//
|
||||||
|
|
||||||
int /* O - Unicode value or -1 */
|
int // O - Unicode value or -1
|
||||||
_mxml_entity_cb(const char *name) /* I - Entity name */
|
_mxml_entity_cb(const char *name) // I - Entity name
|
||||||
{
|
{
|
||||||
int diff, /* Difference between names */
|
int diff, // Difference between names
|
||||||
current, /* Current entity in search */
|
current, // Current entity in search
|
||||||
first, /* First entity in search */
|
first, // First entity in search
|
||||||
last; /* Last entity in search */
|
last; // Last entity in search
|
||||||
static const struct
|
static const struct
|
||||||
{
|
{
|
||||||
const char *name; /* Entity name */
|
const char *name; // Entity name
|
||||||
int val; /* Character value */
|
int val; // Character value
|
||||||
} entities[] =
|
} entities[] =
|
||||||
{
|
{
|
||||||
{ "AElig", 198 },
|
{ "AElig", 198 },
|
||||||
@ -405,10 +401,7 @@ _mxml_entity_cb(const char *name) /* I - Entity name */
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
// Do a binary search for the named entity...
|
||||||
* Do a binary search for the named entity...
|
|
||||||
*/
|
|
||||||
|
|
||||||
first = 0;
|
first = 0;
|
||||||
last = (int)(sizeof(entities) / sizeof(entities[0]) - 1);
|
last = (int)(sizeof(entities) / sizeof(entities[0]) - 1);
|
||||||
|
|
||||||
@ -424,11 +417,7 @@ _mxml_entity_cb(const char *name) /* I - Entity name */
|
|||||||
first = current;
|
first = current;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If we get here, there is a small chance that there is still a match; check first and last...
|
||||||
* If we get here, there is a small chance that there is still
|
|
||||||
* a match; check first and last...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!strcmp(name, entities[first].name))
|
if (!strcmp(name, entities[first].name))
|
||||||
return (entities[first].val);
|
return (entities[first].val);
|
||||||
else if (!strcmp(name, entities[last].name))
|
else if (!strcmp(name, entities[last].name))
|
||||||
|
1888
mxml-file.c
1888
mxml-file.c
File diff suppressed because it is too large
Load Diff
450
mxml-get.c
450
mxml-get.c
@ -1,365 +1,258 @@
|
|||||||
/*
|
//
|
||||||
* Node get functions for Mini-XML, a small XML file parsing library.
|
// Node get functions for Mini-XML, a small XML file parsing library.
|
||||||
*
|
//
|
||||||
* https://www.msweet.org/mxml
|
// https://www.msweet.org/mxml
|
||||||
*
|
//
|
||||||
* Copyright © 2014-2019 by Michael R Sweet.
|
// Copyright © 2014-2024 by Michael R Sweet.
|
||||||
*
|
//
|
||||||
* Licensed under Apache License v2.0. See the file "LICENSE" for more
|
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
||||||
* information.
|
// information.
|
||||||
*/
|
//
|
||||||
|
|
||||||
/*
|
|
||||||
* Include necessary headers...
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "mxml-private.h"
|
#include "mxml-private.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlGetCDATA()' - Get the value for a CDATA node.
|
// 'mxmlGetCDATA()' - Get the value for a CDATA node.
|
||||||
*
|
//
|
||||||
* @code NULL@ is returned if the node is not a CDATA element.
|
// `NULL` is returned if the node is not a CDATA element.
|
||||||
*
|
//
|
||||||
* @since Mini-XML 2.7@
|
|
||||||
*/
|
|
||||||
|
|
||||||
const char * /* O - CDATA value or @code NULL@ */
|
const char * // O - CDATA value or `NULL`
|
||||||
mxmlGetCDATA(mxml_node_t *node) /* I - Node to get */
|
mxmlGetCDATA(mxml_node_t *node) // I - Node to get
|
||||||
{
|
{
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
if (!node || node->type != MXML_TYPE_ELEMENT || strncmp(node->value.element.name, "![CDATA[", 8))
|
||||||
*/
|
|
||||||
|
|
||||||
if (!node || node->type != MXML_ELEMENT ||
|
|
||||||
strncmp(node->value.element.name, "![CDATA[", 8))
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
/*
|
// Return the text following the CDATA declaration...
|
||||||
* Return the text following the CDATA declaration...
|
|
||||||
*/
|
|
||||||
|
|
||||||
return (node->value.element.name + 8);
|
return (node->value.element.name + 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlGetCustom()' - Get the value for a custom node.
|
// 'mxmlGetCustom()' - Get the value for a custom node.
|
||||||
*
|
//
|
||||||
* @code NULL@ is returned if the node (or its first child) is not a custom
|
// `NULL` is returned if the node (or its first child) is not a custom
|
||||||
* value node.
|
// value node.
|
||||||
*
|
//
|
||||||
* @since Mini-XML 2.7@
|
|
||||||
*/
|
|
||||||
|
|
||||||
const void * /* O - Custom value or @code NULL@ */
|
const void * // O - Custom value or `NULL`
|
||||||
mxmlGetCustom(mxml_node_t *node) /* I - Node to get */
|
mxmlGetCustom(mxml_node_t *node) // I - Node to get
|
||||||
{
|
{
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!node)
|
if (!node)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
/*
|
// Return the custom value...
|
||||||
* Return the integer value...
|
if (node->type == MXML_TYPE_CUSTOM)
|
||||||
*/
|
|
||||||
|
|
||||||
if (node->type == MXML_CUSTOM)
|
|
||||||
return (node->value.custom.data);
|
return (node->value.custom.data);
|
||||||
else if (node->type == MXML_ELEMENT &&
|
else if (node->type == MXML_TYPE_ELEMENT && node->child && node->child->type == MXML_TYPE_CUSTOM)
|
||||||
node->child &&
|
|
||||||
node->child->type == MXML_CUSTOM)
|
|
||||||
return (node->child->value.custom.data);
|
return (node->child->value.custom.data);
|
||||||
else
|
else
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlGetElement()' - Get the name for an element node.
|
// 'mxmlGetElement()' - Get the name for an element node.
|
||||||
*
|
//
|
||||||
* @code NULL@ is returned if the node is not an element node.
|
// `NULL` is returned if the node is not an element node.
|
||||||
*
|
//
|
||||||
* @since Mini-XML 2.7@
|
|
||||||
*/
|
|
||||||
|
|
||||||
const char * /* O - Element name or @code NULL@ */
|
const char * // O - Element name or `NULL`
|
||||||
mxmlGetElement(mxml_node_t *node) /* I - Node to get */
|
mxmlGetElement(mxml_node_t *node) // I - Node to get
|
||||||
{
|
{
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
if (!node || node->type != MXML_TYPE_ELEMENT)
|
||||||
*/
|
|
||||||
|
|
||||||
if (!node || node->type != MXML_ELEMENT)
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
/*
|
// Return the element name...
|
||||||
* Return the element name...
|
|
||||||
*/
|
|
||||||
|
|
||||||
return (node->value.element.name);
|
return (node->value.element.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlGetFirstChild()' - Get the first child of an element node.
|
// 'mxmlGetFirstChild()' - Get the first child of an element node.
|
||||||
*
|
//
|
||||||
* @code NULL@ is returned if the node is not an element node or if the node
|
// `NULL` is returned if the node is not an element node or if the node
|
||||||
* has no children.
|
// has no children.
|
||||||
*
|
//
|
||||||
* @since Mini-XML 2.7@
|
|
||||||
*/
|
|
||||||
|
|
||||||
mxml_node_t * /* O - First child or @code NULL@ */
|
mxml_node_t * // O - First child or `NULL`
|
||||||
mxmlGetFirstChild(mxml_node_t *node) /* I - Node to get */
|
mxmlGetFirstChild(mxml_node_t *node) // I - Node to get
|
||||||
{
|
{
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
if (!node || node->type != MXML_TYPE_ELEMENT)
|
||||||
*/
|
|
||||||
|
|
||||||
if (!node || node->type != MXML_ELEMENT)
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
/*
|
// Return the first child node...
|
||||||
* Return the first child node...
|
|
||||||
*/
|
|
||||||
|
|
||||||
return (node->child);
|
return (node->child);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlGetInteger()' - Get the integer value from the specified node or its
|
// 'mxmlGetInteger()' - Get the integer value from the specified node or its
|
||||||
* first child.
|
// first child.
|
||||||
*
|
//
|
||||||
* 0 is returned if the node (or its first child) is not an integer value node.
|
// 0 is returned if the node (or its first child) is not an integer value node.
|
||||||
*
|
//
|
||||||
* @since Mini-XML 2.7@
|
|
||||||
*/
|
|
||||||
|
|
||||||
int /* O - Integer value or 0 */
|
int // O - Integer value or 0
|
||||||
mxmlGetInteger(mxml_node_t *node) /* I - Node to get */
|
mxmlGetInteger(mxml_node_t *node) // I - Node to get
|
||||||
{
|
{
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!node)
|
if (!node)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
/*
|
// Return the integer value...
|
||||||
* Return the integer value...
|
if (node->type == MXML_TYPE_INTEGER)
|
||||||
*/
|
|
||||||
|
|
||||||
if (node->type == MXML_INTEGER)
|
|
||||||
return (node->value.integer);
|
return (node->value.integer);
|
||||||
else if (node->type == MXML_ELEMENT &&
|
else if (node->type == MXML_TYPE_ELEMENT && node->child && node->child->type == MXML_TYPE_INTEGER)
|
||||||
node->child &&
|
|
||||||
node->child->type == MXML_INTEGER)
|
|
||||||
return (node->child->value.integer);
|
return (node->child->value.integer);
|
||||||
else
|
else
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlGetLastChild()' - Get the last child of an element node.
|
// 'mxmlGetLastChild()' - Get the last child of an element node.
|
||||||
*
|
//
|
||||||
* @code NULL@ is returned if the node is not an element node or if the node
|
// `NULL` is returned if the node is not an element node or if the node
|
||||||
* has no children.
|
// has no children.
|
||||||
*
|
//
|
||||||
* @since Mini-XML 2.7@
|
|
||||||
*/
|
|
||||||
|
|
||||||
mxml_node_t * /* O - Last child or @code NULL@ */
|
mxml_node_t * // O - Last child or `NULL`
|
||||||
mxmlGetLastChild(mxml_node_t *node) /* I - Node to get */
|
mxmlGetLastChild(mxml_node_t *node) // I - Node to get
|
||||||
{
|
{
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
if (!node || node->type != MXML_TYPE_ELEMENT)
|
||||||
*/
|
|
||||||
|
|
||||||
if (!node || node->type != MXML_ELEMENT)
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
/*
|
// Return the last child node...
|
||||||
* Return the node type...
|
|
||||||
*/
|
|
||||||
|
|
||||||
return (node->last_child);
|
return (node->last_child);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlGetNextSibling()' - Get the next node for the current parent.
|
// 'mxmlGetNextSibling()' - Get the next node for the current parent.
|
||||||
*
|
//
|
||||||
* @code NULL@ is returned if this is the last child for the current parent.
|
// `NULL` is returned if this is the last child for the current parent.
|
||||||
*
|
//
|
||||||
* @since Mini-XML 2.7@
|
|
||||||
*/
|
|
||||||
|
|
||||||
mxml_node_t *
|
mxml_node_t *
|
||||||
mxmlGetNextSibling(mxml_node_t *node) /* I - Node to get */
|
mxmlGetNextSibling(mxml_node_t *node) // I - Node to get
|
||||||
{
|
{
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!node)
|
if (!node)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
/*
|
// Return the next sibling node...
|
||||||
* Return the node type...
|
|
||||||
*/
|
|
||||||
|
|
||||||
return (node->next);
|
return (node->next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlGetOpaque()' - Get an opaque string value for a node or its first child.
|
// 'mxmlGetOpaque()' - Get an opaque string value for a node or its first child.
|
||||||
*
|
//
|
||||||
* @code NULL@ is returned if the node (or its first child) is not an opaque
|
// `NULL` is returned if the node (or its first child) is not an opaque
|
||||||
* value node.
|
// value node.
|
||||||
*
|
//
|
||||||
* @since Mini-XML 2.7@
|
|
||||||
*/
|
|
||||||
|
|
||||||
const char * /* O - Opaque string or @code NULL@ */
|
const char * // O - Opaque string or `NULL`
|
||||||
mxmlGetOpaque(mxml_node_t *node) /* I - Node to get */
|
mxmlGetOpaque(mxml_node_t *node) // I - Node to get
|
||||||
{
|
{
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!node)
|
if (!node)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
/*
|
// Return the opaque value...
|
||||||
* Return the integer value...
|
if (node->type == MXML_TYPE_OPAQUE)
|
||||||
*/
|
|
||||||
|
|
||||||
if (node->type == MXML_OPAQUE)
|
|
||||||
return (node->value.opaque);
|
return (node->value.opaque);
|
||||||
else if (node->type == MXML_ELEMENT &&
|
else if (node->type == MXML_TYPE_ELEMENT && node->child && node->child->type == MXML_TYPE_OPAQUE)
|
||||||
node->child &&
|
|
||||||
node->child->type == MXML_OPAQUE)
|
|
||||||
return (node->child->value.opaque);
|
return (node->child->value.opaque);
|
||||||
else
|
else
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlGetParent()' - Get the parent node.
|
// 'mxmlGetParent()' - Get the parent node.
|
||||||
*
|
//
|
||||||
* @code NULL@ is returned for a root node.
|
// `NULL` is returned for a root node.
|
||||||
*
|
//
|
||||||
* @since Mini-XML 2.7@
|
|
||||||
*/
|
|
||||||
|
|
||||||
mxml_node_t * /* O - Parent node or @code NULL@ */
|
mxml_node_t * // O - Parent node or `NULL`
|
||||||
mxmlGetParent(mxml_node_t *node) /* I - Node to get */
|
mxmlGetParent(mxml_node_t *node) // I - Node to get
|
||||||
{
|
{
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!node)
|
if (!node)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
/*
|
// Return the parent node...
|
||||||
* Return the node type...
|
|
||||||
*/
|
|
||||||
|
|
||||||
return (node->parent);
|
return (node->parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlGetPrevSibling()' - Get the previous node for the current parent.
|
// 'mxmlGetPrevSibling()' - Get the previous node for the current parent.
|
||||||
*
|
//
|
||||||
* @code NULL@ is returned if this is the first child for the current parent.
|
// `NULL` is returned if this is the first child for the current parent.
|
||||||
*
|
//
|
||||||
* @since Mini-XML 2.7@
|
|
||||||
*/
|
|
||||||
|
|
||||||
mxml_node_t * /* O - Previous node or @code NULL@ */
|
mxml_node_t * // O - Previous node or `NULL`
|
||||||
mxmlGetPrevSibling(mxml_node_t *node) /* I - Node to get */
|
mxmlGetPrevSibling(mxml_node_t *node) // I - Node to get
|
||||||
{
|
{
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!node)
|
if (!node)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
/*
|
// Return the previous sibling node...
|
||||||
* Return the node type...
|
|
||||||
*/
|
|
||||||
|
|
||||||
return (node->prev);
|
return (node->prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlGetReal()' - Get the real value for a node or its first child.
|
// 'mxmlGetReal()' - Get the real value for a node or its first child.
|
||||||
*
|
//
|
||||||
* 0.0 is returned if the node (or its first child) is not a real value node.
|
// 0.0 is returned if the node (or its first child) is not a real value node.
|
||||||
*
|
//
|
||||||
* @since Mini-XML 2.7@
|
|
||||||
*/
|
|
||||||
|
|
||||||
double /* O - Real value or 0.0 */
|
double // O - Real value or 0.0
|
||||||
mxmlGetReal(mxml_node_t *node) /* I - Node to get */
|
mxmlGetReal(mxml_node_t *node) // I - Node to get
|
||||||
{
|
{
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!node)
|
if (!node)
|
||||||
return (0.0);
|
return (0.0);
|
||||||
|
|
||||||
/*
|
// Return the real value...
|
||||||
* Return the integer value...
|
if (node->type == MXML_TYPE_REAL)
|
||||||
*/
|
|
||||||
|
|
||||||
if (node->type == MXML_REAL)
|
|
||||||
return (node->value.real);
|
return (node->value.real);
|
||||||
else if (node->type == MXML_ELEMENT &&
|
else if (node->type == MXML_TYPE_ELEMENT && node->child && node->child->type == MXML_TYPE_REAL)
|
||||||
node->child &&
|
|
||||||
node->child->type == MXML_REAL)
|
|
||||||
return (node->child->value.real);
|
return (node->child->value.real);
|
||||||
else
|
else
|
||||||
return (0.0);
|
return (0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlGetText()' - Get the text value for a node or its first child.
|
// 'mxmlGetText()' - Get the text value for a node or its first child.
|
||||||
*
|
//
|
||||||
* @code NULL@ is returned if the node (or its first child) is not a text node.
|
// `NULL` is returned if the node (or its first child) is not a text node.
|
||||||
* The "whitespace" argument can be @code NULL@.
|
// The "whitespace" argument can be `NULL`.
|
||||||
*
|
//
|
||||||
* Note: Text nodes consist of whitespace-delimited words. You will only get
|
// Note: Text nodes consist of whitespace-delimited words. You will only get
|
||||||
* single words of text when reading an XML file with @code MXML_TEXT@ nodes.
|
// single words of text when reading an XML file with `MXML_TYPE_TEXT` nodes.
|
||||||
* If you want the entire string between elements in the XML file, you MUST read
|
// If you want the entire string between elements in the XML file, you MUST read
|
||||||
* the XML file with @code MXML_OPAQUE@ nodes and get the resulting strings
|
// the XML file with `MXML_TYPE_OPAQUE` nodes and get the resulting strings
|
||||||
* using the @link mxmlGetOpaque@ function instead.
|
// using the @link mxmlGetOpaque@ function instead.
|
||||||
*
|
//
|
||||||
* @since Mini-XML 2.7@
|
|
||||||
*/
|
|
||||||
|
|
||||||
const char * /* O - Text string or @code NULL@ */
|
const char * // O - Text string or `NULL`
|
||||||
mxmlGetText(mxml_node_t *node, /* I - Node to get */
|
mxmlGetText(mxml_node_t *node, // I - Node to get
|
||||||
int *whitespace) /* O - 1 if string is preceded by whitespace, 0 otherwise */
|
int *whitespace) // O - 1 if string is preceded by whitespace, 0 otherwise
|
||||||
{
|
{
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!node)
|
if (!node)
|
||||||
{
|
{
|
||||||
if (whitespace)
|
if (whitespace)
|
||||||
@ -368,20 +261,15 @@ mxmlGetText(mxml_node_t *node, /* I - Node to get */
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Return the integer value...
|
||||||
* Return the integer value...
|
if (node->type == MXML_TYPE_TEXT)
|
||||||
*/
|
|
||||||
|
|
||||||
if (node->type == MXML_TEXT)
|
|
||||||
{
|
{
|
||||||
if (whitespace)
|
if (whitespace)
|
||||||
*whitespace = node->value.text.whitespace;
|
*whitespace = node->value.text.whitespace;
|
||||||
|
|
||||||
return (node->value.text.string);
|
return (node->value.text.string);
|
||||||
}
|
}
|
||||||
else if (node->type == MXML_ELEMENT &&
|
else if (node->type == MXML_TYPE_ELEMENT && node->child && node->child->type == MXML_TYPE_TEXT)
|
||||||
node->child &&
|
|
||||||
node->child->type == MXML_TEXT)
|
|
||||||
{
|
{
|
||||||
if (whitespace)
|
if (whitespace)
|
||||||
*whitespace = node->child->value.text.whitespace;
|
*whitespace = node->child->value.text.whitespace;
|
||||||
@ -398,51 +286,35 @@ mxmlGetText(mxml_node_t *node, /* I - Node to get */
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlGetType()' - Get the node type.
|
// 'mxmlGetType()' - Get the node type.
|
||||||
*
|
//
|
||||||
* @code MXML_IGNORE@ is returned if "node" is @code NULL@.
|
// `MXML_TYPE_IGNORE` is returned if "node" is `NULL`.
|
||||||
*
|
//
|
||||||
* @since Mini-XML 2.7@
|
|
||||||
*/
|
|
||||||
|
|
||||||
mxml_type_t /* O - Type of node */
|
mxml_type_t // O - Type of node
|
||||||
mxmlGetType(mxml_node_t *node) /* I - Node to get */
|
mxmlGetType(mxml_node_t *node) // I - Node to get
|
||||||
{
|
{
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!node)
|
if (!node)
|
||||||
return (MXML_IGNORE);
|
return (MXML_TYPE_IGNORE);
|
||||||
|
|
||||||
/*
|
|
||||||
* Return the node type...
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
// Return the node type...
|
||||||
return (node->type);
|
return (node->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlGetUserData()' - Get the user data pointer for a node.
|
// 'mxmlGetUserData()' - Get the user data pointer for a node.
|
||||||
*
|
//
|
||||||
* @since Mini-XML 2.7@
|
|
||||||
*/
|
|
||||||
|
|
||||||
void * /* O - User data pointer */
|
void * // O - User data pointer
|
||||||
mxmlGetUserData(mxml_node_t *node) /* I - Node to get */
|
mxmlGetUserData(mxml_node_t *node) // I - Node to get
|
||||||
{
|
{
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!node)
|
if (!node)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
/*
|
// Return the user data pointer...
|
||||||
* Return the user data pointer...
|
|
||||||
*/
|
|
||||||
|
|
||||||
return (node->user_data);
|
return (node->user_data);
|
||||||
}
|
}
|
||||||
|
566
mxml-index.c
566
mxml-index.c
@ -1,79 +1,60 @@
|
|||||||
/*
|
//
|
||||||
* Index support code for Mini-XML, a small XML file parsing library.
|
// Index support code for Mini-XML, a small XML file parsing library.
|
||||||
*
|
//
|
||||||
* https://www.msweet.org/mxml
|
// https://www.msweet.org/mxml
|
||||||
*
|
//
|
||||||
* Copyright © 2003-2021 by Michael R Sweet.
|
// Copyright © 2003-2024 by Michael R Sweet.
|
||||||
*
|
//
|
||||||
* Licensed under Apache License v2.0. See the file "LICENSE" for more
|
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
||||||
* information.
|
// information.
|
||||||
*/
|
//
|
||||||
|
|
||||||
/*
|
|
||||||
* Include necessary headers...
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "mxml-private.h"
|
#include "mxml-private.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Sort functions...
|
// Local functions...
|
||||||
*/
|
//
|
||||||
|
|
||||||
static int index_compare(mxml_index_t *ind, mxml_node_t *first,
|
static int index_compare(mxml_index_t *ind, mxml_node_t *first, mxml_node_t *second);
|
||||||
mxml_node_t *second);
|
static int index_find(mxml_index_t *ind, const char *element, const char *value, mxml_node_t *node);
|
||||||
static int index_find(mxml_index_t *ind, const char *element,
|
|
||||||
const char *value, mxml_node_t *node);
|
|
||||||
static void index_sort(mxml_index_t *ind, int left, int right);
|
static void index_sort(mxml_index_t *ind, int left, int right);
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlIndexDelete()' - Delete an index.
|
// 'mxmlIndexDelete()' - Delete an index.
|
||||||
*/
|
//
|
||||||
|
|
||||||
void
|
void
|
||||||
mxmlIndexDelete(mxml_index_t *ind) /* I - Index to delete */
|
mxmlIndexDelete(mxml_index_t *ind) // I - Index to delete
|
||||||
{
|
{
|
||||||
/*
|
// Range check input..
|
||||||
* Range check input..
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!ind)
|
if (!ind)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
// Free memory...
|
||||||
* Free memory...
|
|
||||||
*/
|
|
||||||
|
|
||||||
free(ind->attr);
|
free(ind->attr);
|
||||||
free(ind->nodes);
|
free(ind->nodes);
|
||||||
free(ind);
|
free(ind);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlIndexEnum()' - Return the next node in the index.
|
// 'mxmlIndexEnum()' - Return the next node in the index.
|
||||||
*
|
//
|
||||||
* You should call @link mxmlIndexReset@ prior to using this function to get
|
// You should call @link mxmlIndexReset@ prior to using this function to get
|
||||||
* the first node in the index. Nodes are returned in the sorted order of the
|
// the first node in the index. Nodes are returned in the sorted order of the
|
||||||
* index.
|
// index.
|
||||||
*/
|
//
|
||||||
|
|
||||||
mxml_node_t * /* O - Next node or @code NULL@ if there is none */
|
mxml_node_t * // O - Next node or `NULL` if there is none
|
||||||
mxmlIndexEnum(mxml_index_t *ind) /* I - Index to enumerate */
|
mxmlIndexEnum(mxml_index_t *ind) // I - Index to enumerate
|
||||||
{
|
{
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!ind)
|
if (!ind)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
/*
|
// Return the next node...
|
||||||
* Return the next node...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (ind->cur_node < ind->num_nodes)
|
if (ind->cur_node < ind->num_nodes)
|
||||||
return (ind->nodes[ind->cur_node ++]);
|
return (ind->nodes[ind->cur_node ++]);
|
||||||
else
|
else
|
||||||
@ -81,249 +62,164 @@ mxmlIndexEnum(mxml_index_t *ind) /* I - Index to enumerate */
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlIndexFind()' - Find the next matching node.
|
// 'mxmlIndexFind()' - Find the next matching node.
|
||||||
*
|
//
|
||||||
* You should call @link mxmlIndexReset@ prior to using this function for
|
// You should call @link mxmlIndexReset@ prior to using this function for
|
||||||
* the first time with a particular set of "element" and "value"
|
// the first time with a particular set of "element" and "value"
|
||||||
* strings. Passing @code NULL@ for both "element" and "value" is equivalent
|
// strings. Passing `NULL` for both "element" and "value" is equivalent
|
||||||
* to calling @link mxmlIndexEnum@.
|
// to calling @link mxmlIndexEnum@.
|
||||||
*/
|
//
|
||||||
|
|
||||||
mxml_node_t * /* O - Node or @code NULL@ if none found */
|
mxml_node_t * // O - Node or `NULL` if none found
|
||||||
mxmlIndexFind(mxml_index_t *ind, /* I - Index to search */
|
mxmlIndexFind(mxml_index_t *ind, // I - Index to search
|
||||||
const char *element, /* I - Element name to find, if any */
|
const char *element, // I - Element name to find, if any
|
||||||
const char *value) /* I - Attribute value, if any */
|
const char *value) // I - Attribute value, if any
|
||||||
{
|
{
|
||||||
int diff, /* Difference between names */
|
int diff, // Difference between names
|
||||||
current, /* Current entity in search */
|
current, // Current entity in search
|
||||||
first, /* First entity in search */
|
first, // First entity in search
|
||||||
last; /* Last entity in search */
|
last; // Last entity in search
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
MXML_DEBUG("mxmlIndexFind(ind=%p, element=\"%s\", value=\"%s\")\n", ind, element ? element : "(null)", value ? value : "(null)");
|
||||||
printf("mxmlIndexFind(ind=%p, element=\"%s\", value=\"%s\")\n",
|
|
||||||
ind, element ? element : "(null)", value ? value : "(null)");
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Range check input...
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
// Range check input...
|
||||||
if (!ind || (!ind->attr && value))
|
if (!ind || (!ind->attr && value))
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
MXML_DEBUG("mxmlIndexFind: Returning NULL, ind->attr=\"%s\"...\n", ind && ind->attr ? ind->attr : "(null)");
|
||||||
puts(" returning NULL...");
|
|
||||||
if (ind)
|
|
||||||
printf(" ind->attr=\"%s\"\n", ind->attr ? ind->attr : "(null)");
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If both element and value are NULL, just enumerate the nodes in the index...
|
||||||
* If both element and value are NULL, just enumerate the nodes in the
|
|
||||||
* index...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!element && !value)
|
if (!element && !value)
|
||||||
return (mxmlIndexEnum(ind));
|
return (mxmlIndexEnum(ind));
|
||||||
|
|
||||||
/*
|
// If there are no nodes in the index, return NULL...
|
||||||
* If there are no nodes in the index, return NULL...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!ind->num_nodes)
|
if (!ind->num_nodes)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
MXML_DEBUG("mxmlIndexFind: Returning NULL, no nodes...\n");
|
||||||
puts(" returning NULL...");
|
|
||||||
puts(" no nodes!");
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If cur_node == 0, then find the first matching node...
|
||||||
* If cur_node == 0, then find the first matching node...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (ind->cur_node == 0)
|
if (ind->cur_node == 0)
|
||||||
{
|
{
|
||||||
/*
|
// Find the first node using a modified binary search algorithm...
|
||||||
* Find the first node using a modified binary search algorithm...
|
|
||||||
*/
|
|
||||||
|
|
||||||
first = 0;
|
first = 0;
|
||||||
last = ind->num_nodes - 1;
|
last = ind->num_nodes - 1;
|
||||||
|
|
||||||
#ifdef DEBUG
|
MXML_DEBUG("mxmlIndexFind: Find first time, num_nodes=%d...\n", ind->num_nodes);
|
||||||
printf(" find first time, num_nodes=%d...\n", ind->num_nodes);
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
while ((last - first) > 1)
|
while ((last - first) > 1)
|
||||||
{
|
{
|
||||||
current = (first + last) / 2;
|
current = (first + last) / 2;
|
||||||
|
|
||||||
#ifdef DEBUG
|
MXML_DEBUG("mxmlIndexFind: first=%d, last=%d, current=%d\n", first, last, current);
|
||||||
printf(" first=%d, last=%d, current=%d\n", first, last, current);
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
if ((diff = index_find(ind, element, value, ind->nodes[current])) == 0)
|
if ((diff = index_find(ind, element, value, ind->nodes[current])) == 0)
|
||||||
{
|
{
|
||||||
/*
|
// Found a match, move back to find the first...
|
||||||
* Found a match, move back to find the first...
|
MXML_DEBUG("mxmlIndexFind: match.\n");
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
while (current > 0 && !index_find(ind, element, value, ind->nodes[current - 1]))
|
||||||
puts(" match!");
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
while (current > 0 &&
|
|
||||||
!index_find(ind, element, value, ind->nodes[current - 1]))
|
|
||||||
current --;
|
current --;
|
||||||
|
|
||||||
#ifdef DEBUG
|
MXML_DEBUG("mxmlIndexFind: Returning first match=%d\n", current);
|
||||||
printf(" returning first match=%d\n", current);
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return the first match and save the index to the next...
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
// Return the first match and save the index to the next...
|
||||||
ind->cur_node = current + 1;
|
ind->cur_node = current + 1;
|
||||||
|
|
||||||
return (ind->nodes[current]);
|
return (ind->nodes[current]);
|
||||||
}
|
}
|
||||||
else if (diff < 0)
|
else if (diff < 0)
|
||||||
|
{
|
||||||
last = current;
|
last = current;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
first = current;
|
first = current;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
MXML_DEBUG("mxmlIndexFind: diff=%d\n", diff);
|
||||||
printf(" diff=%d\n", diff);
|
|
||||||
#endif /* DEBUG */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If we get this far, then we found exactly 0 or 1 matches...
|
||||||
* If we get this far, then we found exactly 0 or 1 matches...
|
|
||||||
*/
|
|
||||||
|
|
||||||
for (current = first; current <= last; current ++)
|
for (current = first; current <= last; current ++)
|
||||||
|
{
|
||||||
if (!index_find(ind, element, value, ind->nodes[current]))
|
if (!index_find(ind, element, value, ind->nodes[current]))
|
||||||
{
|
{
|
||||||
/*
|
// Found exactly one (or possibly two) match...
|
||||||
* Found exactly one (or possibly two) match...
|
MXML_DEBUG("mxmlIndexFind: Returning only match %d...\n", current);
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf(" returning only match %d...\n", current);
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
ind->cur_node = current + 1;
|
ind->cur_node = current + 1;
|
||||||
|
|
||||||
return (ind->nodes[current]);
|
return (ind->nodes[current]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
// No matches...
|
||||||
* No matches...
|
|
||||||
*/
|
|
||||||
|
|
||||||
ind->cur_node = ind->num_nodes;
|
ind->cur_node = ind->num_nodes;
|
||||||
|
MXML_DEBUG("mxmlIndexFind: Returning NULL...\n");
|
||||||
#ifdef DEBUG
|
|
||||||
puts(" returning NULL...");
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
else if (ind->cur_node < ind->num_nodes &&
|
else if (ind->cur_node < ind->num_nodes && !index_find(ind, element, value, ind->nodes[ind->cur_node]))
|
||||||
!index_find(ind, element, value, ind->nodes[ind->cur_node]))
|
|
||||||
{
|
{
|
||||||
/*
|
// Return the next matching node...
|
||||||
* Return the next matching node...
|
MXML_DEBUG("mxmlIndexFind: Returning next match %d...\n", ind->cur_node);
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf(" returning next match %d...\n", ind->cur_node);
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
return (ind->nodes[ind->cur_node ++]);
|
return (ind->nodes[ind->cur_node ++]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If we get this far, then we have no matches...
|
||||||
* If we get this far, then we have no matches...
|
|
||||||
*/
|
|
||||||
|
|
||||||
ind->cur_node = ind->num_nodes;
|
ind->cur_node = ind->num_nodes;
|
||||||
|
|
||||||
#ifdef DEBUG
|
MXML_DEBUG("mxmlIndexFind: Returning NULL...\n");
|
||||||
puts(" returning NULL...");
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlIndexGetCount()' - Get the number of nodes in an index.
|
// 'mxmlIndexGetCount()' - Get the number of nodes in an index.
|
||||||
*
|
//
|
||||||
* @since Mini-XML 2.7@
|
|
||||||
*/
|
|
||||||
|
|
||||||
int /* I - Number of nodes in index */
|
int // I - Number of nodes in index
|
||||||
mxmlIndexGetCount(mxml_index_t *ind) /* I - Index of nodes */
|
mxmlIndexGetCount(mxml_index_t *ind) // I - Index of nodes
|
||||||
{
|
{
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!ind)
|
if (!ind)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
/*
|
// Return the number of nodes in the index...
|
||||||
* Return the number of nodes in the index...
|
|
||||||
*/
|
|
||||||
|
|
||||||
return (ind->num_nodes);
|
return (ind->num_nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlIndexNew()' - Create a new index.
|
// 'mxmlIndexNew()' - Create a new index.
|
||||||
*
|
//
|
||||||
* The index will contain all nodes that contain the named element and/or
|
// The index will contain all nodes that contain the named element and/or
|
||||||
* attribute. If both "element" and "attr" are @code NULL@, then the index will
|
// attribute. If both "element" and "attr" are `NULL`, then the index will
|
||||||
* contain a sorted list of the elements in the node tree. Nodes are
|
// contain a sorted list of the elements in the node tree. Nodes are
|
||||||
* sorted by element name and optionally by attribute value if the "attr"
|
// sorted by element name and optionally by attribute value if the "attr"
|
||||||
* argument is not NULL.
|
// argument is not NULL.
|
||||||
*/
|
//
|
||||||
|
|
||||||
mxml_index_t * /* O - New index */
|
mxml_index_t * // O - New index
|
||||||
mxmlIndexNew(mxml_node_t *node, /* I - XML node tree */
|
mxmlIndexNew(mxml_node_t *node, // I - XML node tree
|
||||||
const char *element, /* I - Element to index or @code NULL@ for all */
|
const char *element, // I - Element to index or `NULL` for all
|
||||||
const char *attr) /* I - Attribute to index or @code NULL@ for none */
|
const char *attr) // I - Attribute to index or `NULL` for none
|
||||||
{
|
{
|
||||||
mxml_index_t *ind; /* New index */
|
mxml_index_t *ind; // New index
|
||||||
mxml_node_t *current, /* Current node in index */
|
mxml_node_t *current, // Current node in index
|
||||||
**temp; /* Temporary node pointer array */
|
**temp; // Temporary node pointer array
|
||||||
|
|
||||||
|
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
MXML_DEBUG("mxmlIndexNew(node=%p, element=\"%s\", attr=\"%s\")\n", node, element ? element : "(null)", attr ? attr : "(null)");
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf("mxmlIndexNew(node=%p, element=\"%s\", attr=\"%s\")\n",
|
|
||||||
node, element ? element : "(null)", attr ? attr : "(null)");
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
if (!node)
|
if (!node)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
/*
|
// Create a new index...
|
||||||
* Create a new index...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ((ind = calloc(1, sizeof(mxml_index_t))) == NULL)
|
if ((ind = calloc(1, sizeof(mxml_index_t))) == NULL)
|
||||||
{
|
{
|
||||||
mxml_error("Unable to allocate memory for index.");
|
mxml_error("Unable to allocate memory for index.");
|
||||||
@ -356,10 +252,7 @@ mxmlIndexNew(mxml_node_t *node, /* I - XML node tree */
|
|||||||
|
|
||||||
if (!temp)
|
if (!temp)
|
||||||
{
|
{
|
||||||
/*
|
// Unable to allocate memory for the index, so abort...
|
||||||
* Unable to allocate memory for the index, so abort...
|
|
||||||
*/
|
|
||||||
|
|
||||||
mxml_error("Unable to allocate memory for index nodes.");
|
mxml_error("Unable to allocate memory for index nodes.");
|
||||||
mxmlIndexDelete(ind);
|
mxmlIndexDelete(ind);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
@ -374,115 +267,36 @@ mxmlIndexNew(mxml_node_t *node, /* I - XML node tree */
|
|||||||
current = mxmlFindElement(current, node, element, attr, NULL, MXML_DESCEND);
|
current = mxmlFindElement(current, node, element, attr, NULL, MXML_DESCEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Sort nodes based upon the search criteria...
|
||||||
* Sort nodes based upon the search criteria...
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
{
|
|
||||||
int i; /* Looping var */
|
|
||||||
|
|
||||||
|
|
||||||
printf("%d node(s) in index.\n\n", ind->num_nodes);
|
|
||||||
|
|
||||||
if (attr)
|
|
||||||
{
|
|
||||||
printf("Node Address Element %s\n", attr);
|
|
||||||
puts("-------- -------- -------------- ------------------------------");
|
|
||||||
|
|
||||||
for (i = 0; i < ind->num_nodes; i ++)
|
|
||||||
printf("%8d %-8p %-14.14s %s\n", i, ind->nodes[i],
|
|
||||||
ind->nodes[i]->value.element.name,
|
|
||||||
mxmlElementGetAttr(ind->nodes[i], attr));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
puts("Node Address Element");
|
|
||||||
puts("-------- -------- --------------");
|
|
||||||
|
|
||||||
for (i = 0; i < ind->num_nodes; i ++)
|
|
||||||
printf("%8d %-8p %s\n", i, ind->nodes[i],
|
|
||||||
ind->nodes[i]->value.element.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
putchar('\n');
|
|
||||||
}
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
if (ind->num_nodes > 1)
|
if (ind->num_nodes > 1)
|
||||||
index_sort(ind, 0, ind->num_nodes - 1);
|
index_sort(ind, 0, ind->num_nodes - 1);
|
||||||
|
|
||||||
#ifdef DEBUG
|
// Return the new index...
|
||||||
{
|
|
||||||
int i; /* Looping var */
|
|
||||||
|
|
||||||
|
|
||||||
puts("After sorting:\n");
|
|
||||||
|
|
||||||
if (attr)
|
|
||||||
{
|
|
||||||
printf("Node Address Element %s\n", attr);
|
|
||||||
puts("-------- -------- -------------- ------------------------------");
|
|
||||||
|
|
||||||
for (i = 0; i < ind->num_nodes; i ++)
|
|
||||||
printf("%8d %-8p %-14.14s %s\n", i, ind->nodes[i],
|
|
||||||
ind->nodes[i]->value.element.name,
|
|
||||||
mxmlElementGetAttr(ind->nodes[i], attr));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
puts("Node Address Element");
|
|
||||||
puts("-------- -------- --------------");
|
|
||||||
|
|
||||||
for (i = 0; i < ind->num_nodes; i ++)
|
|
||||||
printf("%8d %-8p %s\n", i, ind->nodes[i],
|
|
||||||
ind->nodes[i]->value.element.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
putchar('\n');
|
|
||||||
}
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return the new index...
|
|
||||||
*/
|
|
||||||
|
|
||||||
return (ind);
|
return (ind);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlIndexReset()' - Reset the enumeration/find pointer in the index and
|
// 'mxmlIndexReset()' - Reset the enumeration/find pointer in the index and
|
||||||
* return the first node in the index.
|
// return the first node in the index.
|
||||||
*
|
//
|
||||||
* This function should be called prior to using @link mxmlIndexEnum@ or
|
// This function should be called prior to using @link mxmlIndexEnum@ or
|
||||||
* @link mxmlIndexFind@ for the first time.
|
// @link mxmlIndexFind@ for the first time.
|
||||||
*/
|
//
|
||||||
|
|
||||||
mxml_node_t * /* O - First node or @code NULL@ if there is none */
|
mxml_node_t * // O - First node or `NULL` if there is none
|
||||||
mxmlIndexReset(mxml_index_t *ind) /* I - Index to reset */
|
mxmlIndexReset(mxml_index_t *ind) // I - Index to reset
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
MXML_DEBUG("mxmlIndexReset(ind=%p)\n", ind);
|
||||||
printf("mxmlIndexReset(ind=%p)\n", ind);
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Range check input...
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
// Range check input...
|
||||||
if (!ind)
|
if (!ind)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
/*
|
// Set the index to the first element...
|
||||||
* Set the index to the first element...
|
|
||||||
*/
|
|
||||||
|
|
||||||
ind->cur_node = 0;
|
ind->cur_node = 0;
|
||||||
|
|
||||||
/*
|
// Return the first node...
|
||||||
* Return the first node...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (ind->num_nodes)
|
if (ind->num_nodes)
|
||||||
return (ind->nodes[0]);
|
return (ind->nodes[0]);
|
||||||
else
|
else
|
||||||
@ -490,137 +304,100 @@ mxmlIndexReset(mxml_index_t *ind) /* I - Index to reset */
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'index_compare()' - Compare two nodes.
|
// 'index_compare()' - Compare two nodes.
|
||||||
*/
|
//
|
||||||
|
|
||||||
static int /* O - Result of comparison */
|
static int // O - Result of comparison
|
||||||
index_compare(mxml_index_t *ind, /* I - Index */
|
index_compare(mxml_index_t *ind, // I - Index
|
||||||
mxml_node_t *first, /* I - First node */
|
mxml_node_t *first, // I - First node
|
||||||
mxml_node_t *second) /* I - Second node */
|
mxml_node_t *second) // I - Second node
|
||||||
{
|
{
|
||||||
int diff; /* Difference */
|
int diff; // Difference
|
||||||
|
|
||||||
|
|
||||||
/*
|
// Check the element name...
|
||||||
* Check the element name...
|
if ((diff = strcmp(first->value.element.name, second->value.element.name)) != 0)
|
||||||
*/
|
|
||||||
|
|
||||||
if ((diff = strcmp(first->value.element.name,
|
|
||||||
second->value.element.name)) != 0)
|
|
||||||
return (diff);
|
return (diff);
|
||||||
|
|
||||||
/*
|
// Check the attribute value...
|
||||||
* Check the attribute value...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (ind->attr)
|
if (ind->attr)
|
||||||
{
|
{
|
||||||
if ((diff = strcmp(mxmlElementGetAttr(first, ind->attr),
|
if ((diff = strcmp(mxmlElementGetAttr(first, ind->attr), mxmlElementGetAttr(second, ind->attr))) != 0)
|
||||||
mxmlElementGetAttr(second, ind->attr))) != 0)
|
|
||||||
return (diff);
|
return (diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// No difference, return 0...
|
||||||
* No difference, return 0...
|
|
||||||
*/
|
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'index_find()' - Compare a node with index values.
|
// 'index_find()' - Compare a node with index values.
|
||||||
*/
|
//
|
||||||
|
|
||||||
static int /* O - Result of comparison */
|
static int // O - Result of comparison
|
||||||
index_find(mxml_index_t *ind, /* I - Index */
|
index_find(mxml_index_t *ind, // I - Index
|
||||||
const char *element, /* I - Element name or @code NULL@ */
|
const char *element, // I - Element name or `NULL`
|
||||||
const char *value, /* I - Attribute value or @code NULL@ */
|
const char *value, // I - Attribute value or `NULL`
|
||||||
mxml_node_t *node) /* I - Node */
|
mxml_node_t *node) // I - Node
|
||||||
{
|
{
|
||||||
int diff; /* Difference */
|
int diff; // Difference
|
||||||
|
|
||||||
|
|
||||||
/*
|
// Check the element name...
|
||||||
* Check the element name...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (element)
|
if (element)
|
||||||
{
|
{
|
||||||
if ((diff = strcmp(element, node->value.element.name)) != 0)
|
if ((diff = strcmp(element, node->value.element.name)) != 0)
|
||||||
return (diff);
|
return (diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Check the attribute value...
|
||||||
* Check the attribute value...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (value)
|
if (value)
|
||||||
{
|
{
|
||||||
if ((diff = strcmp(value, mxmlElementGetAttr(node, ind->attr))) != 0)
|
if ((diff = strcmp(value, mxmlElementGetAttr(node, ind->attr))) != 0)
|
||||||
return (diff);
|
return (diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// No difference, return 0...
|
||||||
* No difference, return 0...
|
|
||||||
*/
|
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'index_sort()' - Sort the nodes in the index...
|
// 'index_sort()' - Sort the nodes in the index...
|
||||||
*
|
//
|
||||||
* This function implements the classic quicksort algorithm...
|
// This function implements the classic quicksort algorithm...
|
||||||
*/
|
//
|
||||||
|
|
||||||
static void
|
static void
|
||||||
index_sort(mxml_index_t *ind, /* I - Index to sort */
|
index_sort(mxml_index_t *ind, // I - Index to sort
|
||||||
int left, /* I - Left node in partition */
|
int left, // I - Left node in partition
|
||||||
int right) /* I - Right node in partition */
|
int right) // I - Right node in partition
|
||||||
{
|
{
|
||||||
mxml_node_t *pivot, /* Pivot node */
|
mxml_node_t *pivot, // Pivot node
|
||||||
*temp; /* Swap node */
|
*temp; // Swap node
|
||||||
int templ, /* Temporary left node */
|
int templ, // Temporary left node
|
||||||
tempr; /* Temporary right node */
|
tempr; // Temporary right node
|
||||||
|
|
||||||
|
|
||||||
/*
|
// Loop until we have sorted all the way to the right...
|
||||||
* Loop until we have sorted all the way to the right...
|
|
||||||
*/
|
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
/*
|
// Sort the pivot in the current partition...
|
||||||
* Sort the pivot in the current partition...
|
|
||||||
*/
|
|
||||||
|
|
||||||
pivot = ind->nodes[left];
|
pivot = ind->nodes[left];
|
||||||
|
|
||||||
for (templ = left, tempr = right; templ < tempr;)
|
for (templ = left, tempr = right; templ < tempr;)
|
||||||
{
|
{
|
||||||
/*
|
// Move left while left node <= pivot node...
|
||||||
* Move left while left node <= pivot node...
|
while ((templ < right) && index_compare(ind, ind->nodes[templ], pivot) <= 0)
|
||||||
*/
|
|
||||||
|
|
||||||
while ((templ < right) &&
|
|
||||||
index_compare(ind, ind->nodes[templ], pivot) <= 0)
|
|
||||||
templ ++;
|
templ ++;
|
||||||
|
|
||||||
/*
|
// Move right while right node > pivot node...
|
||||||
* Move right while right node > pivot node...
|
while ((tempr > left) && index_compare(ind, ind->nodes[tempr], pivot) > 0)
|
||||||
*/
|
|
||||||
|
|
||||||
while ((tempr > left) &&
|
|
||||||
index_compare(ind, ind->nodes[tempr], pivot) > 0)
|
|
||||||
tempr --;
|
tempr --;
|
||||||
|
|
||||||
/*
|
// Swap nodes if needed...
|
||||||
* Swap nodes if needed...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (templ < tempr)
|
if (templ < tempr)
|
||||||
{
|
{
|
||||||
temp = ind->nodes[templ];
|
temp = ind->nodes[templ];
|
||||||
@ -629,21 +406,14 @@ index_sort(mxml_index_t *ind, /* I - Index to sort */
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// When we get here, the right (tempr) node is the new position for the pivot node...
|
||||||
* When we get here, the right (tempr) node is the new position for the
|
|
||||||
* pivot node...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (index_compare(ind, pivot, ind->nodes[tempr]) > 0)
|
if (index_compare(ind, pivot, ind->nodes[tempr]) > 0)
|
||||||
{
|
{
|
||||||
ind->nodes[left] = ind->nodes[tempr];
|
ind->nodes[left] = ind->nodes[tempr];
|
||||||
ind->nodes[tempr] = pivot;
|
ind->nodes[tempr] = pivot;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Recursively sort the left partition as needed...
|
||||||
* Recursively sort the left partition as needed...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (left < (tempr - 1))
|
if (left < (tempr - 1))
|
||||||
index_sort(ind, left, tempr - 1);
|
index_sort(ind, left, tempr - 1);
|
||||||
}
|
}
|
||||||
|
803
mxml-node.c
803
mxml-node.c
File diff suppressed because it is too large
Load Diff
237
mxml-private.c
237
mxml-private.c
@ -1,34 +1,30 @@
|
|||||||
/*
|
//
|
||||||
* Private functions for Mini-XML, a small XML file parsing library.
|
// Private functions for Mini-XML, a small XML file parsing library.
|
||||||
*
|
//
|
||||||
* https://www.msweet.org/mxml
|
// https://www.msweet.org/mxml
|
||||||
*
|
//
|
||||||
* Copyright © 2003-2022 by Michael R Sweet.
|
// Copyright © 2003-2024 by Michael R Sweet.
|
||||||
*
|
//
|
||||||
* Licensed under Apache License v2.0. See the file "LICENSE" for more
|
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
||||||
* information.
|
// information.
|
||||||
*/
|
//
|
||||||
|
|
||||||
/*
|
|
||||||
* Include necessary headers...
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "mxml-private.h"
|
#include "mxml-private.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Some crazy people think that unloading a shared object is a good or safe
|
// Some crazy people think that unloading a shared object is a good or safe
|
||||||
* thing to do. Unfortunately, most objects are simply *not* safe to unload
|
// thing to do. Unfortunately, most objects are simply *not* safe to unload
|
||||||
* and bad things *will* happen.
|
// and bad things *will* happen.
|
||||||
*
|
//
|
||||||
* The following mess of conditional code allows us to provide a destructor
|
// The following mess of conditional code allows us to provide a destructor
|
||||||
* function in Mini-XML for our thread-global storage so that it can possibly
|
// function in Mini-XML for our thread-global storage so that it can possibly
|
||||||
* be unloaded safely, although since there is no standard way to do so I
|
// be unloaded safely, although since there is no standard way to do so I
|
||||||
* can't even provide any guarantees that you can do it safely on all platforms.
|
// can't even provide any guarantees that you can do it safely on all platforms.
|
||||||
*
|
//
|
||||||
* This code currently supports AIX, HP-UX, Linux, macOS, Solaris, and
|
// This code currently supports AIX, HP-UX, Linux, macOS, Solaris, and
|
||||||
* Windows. It might work on the BSDs and IRIX, but I haven't tested that.
|
// Windows. It might work on the BSDs and IRIX, but I haven't tested that.
|
||||||
*/
|
//
|
||||||
|
|
||||||
#if defined(__sun) || defined(_AIX)
|
#if defined(__sun) || defined(_AIX)
|
||||||
# pragma fini(_mxml_fini)
|
# pragma fini(_mxml_fini)
|
||||||
@ -36,133 +32,122 @@
|
|||||||
#elif defined(__hpux)
|
#elif defined(__hpux)
|
||||||
# pragma FINI _mxml_fini
|
# pragma FINI _mxml_fini
|
||||||
# define _MXML_FINI _mxml_fini
|
# define _MXML_FINI _mxml_fini
|
||||||
#elif defined(__GNUC__) /* Linux and macOS */
|
#elif defined(__GNUC__) // Linux and macOS
|
||||||
# define _MXML_FINI __attribute((destructor)) _mxml_fini
|
# define _MXML_FINI __attribute((destructor)) _mxml_fini
|
||||||
#else
|
#else
|
||||||
# define _MXML_FINI _fini
|
# define _MXML_FINI _fini
|
||||||
#endif /* __sun */
|
#endif // __sun
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxml_error()' - Display an error message.
|
// 'mxml_error()' - Display an error message.
|
||||||
*/
|
//
|
||||||
|
|
||||||
void
|
void
|
||||||
mxml_error(const char *format, /* I - Printf-style format string */
|
mxml_error(const char *format, // I - Printf-style format string
|
||||||
...) /* I - Additional arguments as needed */
|
...) // I - Additional arguments as needed
|
||||||
{
|
{
|
||||||
va_list ap; /* Pointer to arguments */
|
va_list ap; // Pointer to arguments
|
||||||
char s[1024]; /* Message string */
|
char s[1024]; // Message string
|
||||||
_mxml_global_t *global = _mxml_global();
|
_mxml_global_t *global = _mxml_global();
|
||||||
/* Global data */
|
// Global data
|
||||||
|
|
||||||
|
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!format)
|
if (!format)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
// Format the error message string...
|
||||||
* Format the error message string...
|
|
||||||
*/
|
|
||||||
|
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
|
|
||||||
vsnprintf(s, sizeof(s), format, ap);
|
vsnprintf(s, sizeof(s), format, ap);
|
||||||
|
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
/*
|
// And then display the error message...
|
||||||
* And then display the error message...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (global->error_cb)
|
if (global->error_cb)
|
||||||
(*global->error_cb)(s);
|
(*global->error_cb)(s);
|
||||||
else
|
else
|
||||||
fprintf(stderr, "mxml: %s\n", s);
|
fprintf(stderr, "%s\n", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxml_ignore_cb()' - Default callback for ignored values.
|
// 'mxml_ignore_cb()' - Default callback for ignored values.
|
||||||
*/
|
//
|
||||||
|
|
||||||
mxml_type_t /* O - Node type */
|
mxml_type_t // O - Node type
|
||||||
mxml_ignore_cb(mxml_node_t *node) /* I - Current node */
|
mxml_ignore_cb(mxml_node_t *node) // I - Current node
|
||||||
{
|
{
|
||||||
(void)node;
|
(void)node;
|
||||||
|
|
||||||
return (MXML_IGNORE);
|
return (MXML_TYPE_IGNORE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxml_integer_cb()' - Default callback for integer values.
|
// 'mxml_integer_cb()' - Default callback for integer values.
|
||||||
*/
|
//
|
||||||
|
|
||||||
mxml_type_t /* O - Node type */
|
mxml_type_t // O - Node type
|
||||||
mxml_integer_cb(mxml_node_t *node) /* I - Current node */
|
mxml_integer_cb(mxml_node_t *node) // I - Current node
|
||||||
{
|
{
|
||||||
(void)node;
|
(void)node;
|
||||||
|
|
||||||
return (MXML_INTEGER);
|
return (MXML_TYPE_INTEGER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxml_opaque_cb()' - Default callback for opaque values.
|
// 'mxml_opaque_cb()' - Default callback for opaque values.
|
||||||
*/
|
//
|
||||||
|
|
||||||
mxml_type_t /* O - Node type */
|
mxml_type_t // O - Node type
|
||||||
mxml_opaque_cb(mxml_node_t *node) /* I - Current node */
|
mxml_opaque_cb(mxml_node_t *node) // I - Current node
|
||||||
{
|
{
|
||||||
(void)node;
|
(void)node;
|
||||||
|
|
||||||
return (MXML_OPAQUE);
|
return (MXML_TYPE_OPAQUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxml_real_cb()' - Default callback for real number values.
|
// 'mxml_real_cb()' - Default callback for real number values.
|
||||||
*/
|
//
|
||||||
|
|
||||||
mxml_type_t /* O - Node type */
|
mxml_type_t // O - Node type
|
||||||
mxml_real_cb(mxml_node_t *node) /* I - Current node */
|
mxml_real_cb(mxml_node_t *node) // I - Current node
|
||||||
{
|
{
|
||||||
(void)node;
|
(void)node;
|
||||||
|
|
||||||
return (MXML_REAL);
|
return (MXML_TYPE_REAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_PTHREAD_H /**** POSIX threading ****/
|
#ifdef HAVE_PTHREAD_H // POSIX threading
|
||||||
# include <pthread.h>
|
# include <pthread.h>
|
||||||
|
|
||||||
static int _mxml_initialized = 0;
|
static int _mxml_initialized = 0;
|
||||||
/* Have we been initialized? */
|
// Have we been initialized?
|
||||||
static pthread_key_t _mxml_key; /* Thread local storage key */
|
static pthread_key_t _mxml_key; // Thread local storage key
|
||||||
static pthread_once_t _mxml_key_once = PTHREAD_ONCE_INIT;
|
static pthread_once_t _mxml_key_once = PTHREAD_ONCE_INIT;
|
||||||
/* One-time initialization object */
|
// One-time initialization object
|
||||||
static void _mxml_init(void);
|
static void _mxml_init(void);
|
||||||
static void _mxml_destructor(void *g);
|
static void _mxml_destructor(void *g);
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* '_mxml_destructor()' - Free memory used for globals...
|
// '_mxml_destructor()' - Free memory used for globals...
|
||||||
*/
|
//
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_mxml_destructor(void *g) /* I - Global data */
|
_mxml_destructor(void *g) // I - Global data
|
||||||
{
|
{
|
||||||
free(g);
|
free(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* '_mxml_fini()' - Clean up when unloaded.
|
// '_mxml_fini()' - Clean up when unloaded.
|
||||||
*/
|
//
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_MXML_FINI(void)
|
_MXML_FINI(void)
|
||||||
@ -172,14 +157,14 @@ _MXML_FINI(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* '_mxml_global()' - Get global data.
|
// '_mxml_global()' - Get global data.
|
||||||
*/
|
//
|
||||||
|
|
||||||
_mxml_global_t * /* O - Global data */
|
_mxml_global_t * // O - Global data
|
||||||
_mxml_global(void)
|
_mxml_global(void)
|
||||||
{
|
{
|
||||||
_mxml_global_t *global; /* Global data */
|
_mxml_global_t *global; // Global data
|
||||||
|
|
||||||
|
|
||||||
pthread_once(&_mxml_key_once, _mxml_init);
|
pthread_once(&_mxml_key_once, _mxml_init);
|
||||||
@ -198,9 +183,9 @@ _mxml_global(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* '_mxml_init()' - Initialize global data...
|
// '_mxml_init()' - Initialize global data...
|
||||||
*/
|
//
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_mxml_init(void)
|
_mxml_init(void)
|
||||||
@ -210,22 +195,22 @@ _mxml_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#elif defined(_WIN32) && defined(MXML1_EXPORTS) /**** WIN32 threading ****/
|
#elif defined(_WIN32) && defined(MXML1_EXPORTS) // WIN32 threading
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
|
|
||||||
static DWORD _mxml_tls_index; /* Index for global storage */
|
static DWORD _mxml_tls_index; // Index for global storage
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'DllMain()' - Main entry for library.
|
// 'DllMain()' - Main entry for library.
|
||||||
*/
|
//
|
||||||
|
|
||||||
BOOL WINAPI /* O - Success/failure */
|
BOOL WINAPI // O - Success/failure
|
||||||
DllMain(HINSTANCE hinst, /* I - DLL module handle */
|
DllMain(HINSTANCE hinst, // I - DLL module handle
|
||||||
DWORD reason, /* I - Reason */
|
DWORD reason, // I - Reason
|
||||||
LPVOID reserved) /* I - Unused */
|
LPVOID reserved) // I - Unused
|
||||||
{
|
{
|
||||||
_mxml_global_t *global; /* Global data */
|
_mxml_global_t *global; // Global data
|
||||||
|
|
||||||
|
|
||||||
(void)hinst;
|
(void)hinst;
|
||||||
@ -233,17 +218,17 @@ DllMain(HINSTANCE hinst, /* I - DLL module handle */
|
|||||||
|
|
||||||
switch (reason)
|
switch (reason)
|
||||||
{
|
{
|
||||||
case DLL_PROCESS_ATTACH : /* Called on library initialization */
|
case DLL_PROCESS_ATTACH : // Called on library initialization
|
||||||
if ((_mxml_tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES)
|
if ((_mxml_tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES)
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DLL_THREAD_DETACH : /* Called when a thread terminates */
|
case DLL_THREAD_DETACH : // Called when a thread terminates
|
||||||
if ((global = (_mxml_global_t *)TlsGetValue(_mxml_tls_index)) != NULL)
|
if ((global = (_mxml_global_t *)TlsGetValue(_mxml_tls_index)) != NULL)
|
||||||
free(global);
|
free(global);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DLL_PROCESS_DETACH : /* Called when library is unloaded */
|
case DLL_PROCESS_DETACH : // Called when library is unloaded
|
||||||
if ((global = (_mxml_global_t *)TlsGetValue(_mxml_tls_index)) != NULL)
|
if ((global = (_mxml_global_t *)TlsGetValue(_mxml_tls_index)) != NULL)
|
||||||
free(global);
|
free(global);
|
||||||
|
|
||||||
@ -258,14 +243,14 @@ DllMain(HINSTANCE hinst, /* I - DLL module handle */
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* '_mxml_global()' - Get global data.
|
// '_mxml_global()' - Get global data.
|
||||||
*/
|
//
|
||||||
|
|
||||||
_mxml_global_t * /* O - Global data */
|
_mxml_global_t * // O - Global data
|
||||||
_mxml_global(void)
|
_mxml_global(void)
|
||||||
{
|
{
|
||||||
_mxml_global_t *global; /* Global data */
|
_mxml_global_t *global; // Global data
|
||||||
|
|
||||||
|
|
||||||
if ((global = (_mxml_global_t *)TlsGetValue(_mxml_tls_index)) == NULL)
|
if ((global = (_mxml_global_t *)TlsGetValue(_mxml_tls_index)) == NULL)
|
||||||
@ -283,25 +268,25 @@ _mxml_global(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#else /**** No threading ****/
|
#else // No threading
|
||||||
/*
|
//
|
||||||
* '_mxml_global()' - Get global data.
|
// '_mxml_global()' - Get global data.
|
||||||
*/
|
//
|
||||||
|
|
||||||
_mxml_global_t * /* O - Global data */
|
_mxml_global_t * // O - Global data
|
||||||
_mxml_global(void)
|
_mxml_global(void)
|
||||||
{
|
{
|
||||||
static _mxml_global_t global = /* Global data */
|
static _mxml_global_t global = // Global data
|
||||||
{
|
{
|
||||||
NULL, /* error_cb */
|
NULL, // error_cb
|
||||||
1, /* num_entity_cbs */
|
1, // num_entity_cbs
|
||||||
{ _mxml_entity_cb }, /* entity_cbs */
|
{ _mxml_entity_cb }, // entity_cbs
|
||||||
72, /* wrap */
|
72, // wrap
|
||||||
NULL, /* custom_load_cb */
|
NULL, // custom_load_cb
|
||||||
NULL /* custom_save_cb */
|
NULL // custom_save_cb
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
return (&global);
|
return (&global);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_PTHREAD_H */
|
#endif // HAVE_PTHREAD_H
|
||||||
|
129
mxml-private.h
129
mxml-private.h
@ -1,87 +1,93 @@
|
|||||||
/*
|
//
|
||||||
* Private definitions for Mini-XML, a small XML file parsing library.
|
// Private definitions for Mini-XML, a small XML file parsing library.
|
||||||
*
|
//
|
||||||
* https://www.msweet.org/mxml
|
// https://www.msweet.org/mxml
|
||||||
*
|
//
|
||||||
* Copyright © 2003-2019 by Michael R Sweet.
|
// Copyright © 2003-2024 by Michael R Sweet.
|
||||||
*
|
//
|
||||||
* Licensed under Apache License v2.0. See the file "LICENSE" for more
|
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
||||||
* information.
|
// information.
|
||||||
*/
|
//
|
||||||
|
|
||||||
#ifndef _mxml_private_h_
|
|
||||||
# define _mxml_private_h_
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Include necessary headers...
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
#ifndef MXML_PRIVATE_H
|
||||||
|
# define MXML_PRIVATE_H
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
# include "mxml.h"
|
# include "mxml.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Private structures...
|
// Private macros...
|
||||||
*/
|
//
|
||||||
|
|
||||||
typedef struct _mxml_attr_s /**** An XML element attribute value. ****/
|
# ifdef DEBUG
|
||||||
|
# define MXML_DEBUG(...) fprintf(stderr, __VA_ARGS__)
|
||||||
|
# else
|
||||||
|
# define MXML_DEBUG(...)
|
||||||
|
# endif // DEBUG
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Private structures...
|
||||||
|
//
|
||||||
|
|
||||||
|
typedef struct _mxml_attr_s // An XML element attribute value.
|
||||||
{
|
{
|
||||||
char *name; /* Attribute name */
|
char *name; // Attribute name
|
||||||
char *value; /* Attribute value */
|
char *value; // Attribute value
|
||||||
} _mxml_attr_t;
|
} _mxml_attr_t;
|
||||||
|
|
||||||
typedef struct _mxml_element_s /**** An XML element value. ****/
|
typedef struct _mxml_element_s // An XML element value.
|
||||||
{
|
{
|
||||||
char *name; /* Name of element */
|
char *name; // Name of element
|
||||||
int num_attrs; /* Number of attributes */
|
int num_attrs; // Number of attributes
|
||||||
_mxml_attr_t *attrs; /* Attributes */
|
_mxml_attr_t *attrs; // Attributes
|
||||||
} _mxml_element_t;
|
} _mxml_element_t;
|
||||||
|
|
||||||
typedef struct _mxml_text_s /**** An XML text value. ****/
|
typedef struct _mxml_text_s // An XML text value.
|
||||||
{
|
{
|
||||||
int whitespace; /* Leading whitespace? */
|
int whitespace; // Leading whitespace?
|
||||||
char *string; /* Fragment string */
|
char *string; // Fragment string
|
||||||
} _mxml_text_t;
|
} _mxml_text_t;
|
||||||
|
|
||||||
typedef struct _mxml_custom_s /**** An XML custom value. ****/
|
typedef struct _mxml_custom_s // An XML custom value.
|
||||||
{
|
{
|
||||||
void *data; /* Pointer to (allocated) custom data */
|
void *data; // Pointer to (allocated) custom data
|
||||||
mxml_custom_destroy_cb_t destroy; /* Pointer to destructor function */
|
mxml_custom_destroy_cb_t destroy; // Pointer to destructor function
|
||||||
} _mxml_custom_t;
|
} _mxml_custom_t;
|
||||||
|
|
||||||
typedef union _mxml_value_u /**** An XML node value. ****/
|
typedef union _mxml_value_u // An XML node value.
|
||||||
{
|
{
|
||||||
_mxml_element_t element; /* Element */
|
_mxml_element_t element; // Element
|
||||||
int integer; /* Integer number */
|
int integer; // Integer number
|
||||||
char *opaque; /* Opaque string */
|
char *opaque; // Opaque string
|
||||||
double real; /* Real number */
|
double real; // Real number
|
||||||
_mxml_text_t text; /* Text fragment */
|
_mxml_text_t text; // Text fragment
|
||||||
_mxml_custom_t custom; /* Custom data @since Mini-XML 2.1@ */
|
_mxml_custom_t custom; // Custom data @since Mini-XML 2.1@
|
||||||
} _mxml_value_t;
|
} _mxml_value_t;
|
||||||
|
|
||||||
struct _mxml_node_s /**** An XML node. ****/
|
struct _mxml_node_s // An XML node.
|
||||||
{
|
{
|
||||||
mxml_type_t type; /* Node type */
|
mxml_type_t type; // Node type
|
||||||
struct _mxml_node_s *next; /* Next node under same parent */
|
struct _mxml_node_s *next; // Next node under same parent
|
||||||
struct _mxml_node_s *prev; /* Previous node under same parent */
|
struct _mxml_node_s *prev; // Previous node under same parent
|
||||||
struct _mxml_node_s *parent; /* Parent node */
|
struct _mxml_node_s *parent; // Parent node
|
||||||
struct _mxml_node_s *child; /* First child node */
|
struct _mxml_node_s *child; // First child node
|
||||||
struct _mxml_node_s *last_child; /* Last child node */
|
struct _mxml_node_s *last_child; // Last child node
|
||||||
_mxml_value_t value; /* Node value */
|
_mxml_value_t value; // Node value
|
||||||
int ref_count; /* Use count */
|
int ref_count; // Use count
|
||||||
void *user_data; /* User data */
|
void *user_data; // User data
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _mxml_index_s /**** An XML node index. ****/
|
struct _mxml_index_s // An XML node index.
|
||||||
{
|
{
|
||||||
char *attr; /* Attribute used for indexing or NULL */
|
char *attr; // Attribute used for indexing or NULL
|
||||||
int num_nodes; /* Number of nodes in index */
|
int num_nodes; // Number of nodes in index
|
||||||
int alloc_nodes; /* Allocated nodes in index */
|
int alloc_nodes; // Allocated nodes in index
|
||||||
int cur_node; /* Current node */
|
int cur_node; // Current node
|
||||||
mxml_node_t **nodes; /* Node array */
|
mxml_node_t **nodes; // Node array
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _mxml_global_s /**** Global, per-thread data ****/
|
typedef struct _mxml_global_s // Global, per-thread data
|
||||||
|
|
||||||
{
|
{
|
||||||
void (*error_cb)(const char *);
|
void (*error_cb)(const char *);
|
||||||
@ -93,11 +99,12 @@ typedef struct _mxml_global_s /**** Global, per-thread data ****/
|
|||||||
} _mxml_global_t;
|
} _mxml_global_t;
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Functions...
|
// Private functions...
|
||||||
*/
|
//
|
||||||
|
|
||||||
extern _mxml_global_t *_mxml_global(void);
|
extern _mxml_global_t *_mxml_global(void);
|
||||||
extern int _mxml_entity_cb(const char *name);
|
extern int _mxml_entity_cb(const char *name);
|
||||||
|
|
||||||
#endif /* !_mxml_private_h_ */
|
|
||||||
|
#endif // !MXML_PRIVATE_H
|
||||||
|
255
mxml-search.c
255
mxml-search.c
@ -1,99 +1,68 @@
|
|||||||
/*
|
//
|
||||||
* Search/navigation functions for Mini-XML, a small XML file parsing library.
|
// Search/navigation functions for Mini-XML, a small XML file parsing library.
|
||||||
*
|
//
|
||||||
* https://www.msweet.org/mxml
|
// https://www.msweet.org/mxml
|
||||||
*
|
//
|
||||||
* Copyright © 2003-2019 by Michael R Sweet.
|
// Copyright © 2003-2024 by Michael R Sweet.
|
||||||
*
|
//
|
||||||
* Licensed under Apache License v2.0. See the file "LICENSE" for more
|
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
||||||
* information.
|
// information.
|
||||||
*/
|
//
|
||||||
|
|
||||||
/*
|
|
||||||
* Include necessary headers...
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "mxml-private.h"
|
#include "mxml-private.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlFindElement()' - Find the named element.
|
// 'mxmlFindElement()' - Find the named element.
|
||||||
*
|
//
|
||||||
* The search is constrained by the name, attribute name, and value; any
|
// The search is constrained by the name, attribute name, and value; any
|
||||||
* @code NULL@ names or values are treated as wildcards, so different kinds of
|
// `NULL` names or values are treated as wildcards, so different kinds of
|
||||||
* searches can be implemented by looking for all elements of a given name
|
// searches can be implemented by looking for all elements of a given name
|
||||||
* or all elements with a specific attribute. The descend argument determines
|
// or all elements with a specific attribute. The descend argument determines
|
||||||
* whether the search descends into child nodes; normally you will use
|
// whether the search descends into child nodes; normally you will use
|
||||||
* @code MXML_DESCEND_FIRST@ for the initial search and @code MXML_NO_DESCEND@
|
// `MXML_DESCEND_FIRST` for the initial search and `MXML_NO_DESCEND`
|
||||||
* to find additional direct descendents of the node. The top node argument
|
// to find additional direct descendents of the node. The top node argument
|
||||||
* constrains the search to a particular node's children.
|
// constrains the search to a particular node's children.
|
||||||
*/
|
//
|
||||||
|
|
||||||
mxml_node_t * /* O - Element node or @code NULL@ */
|
mxml_node_t * // O - Element node or `NULL`
|
||||||
mxmlFindElement(mxml_node_t *node, /* I - Current node */
|
mxmlFindElement(mxml_node_t *node, // I - Current node
|
||||||
mxml_node_t *top, /* I - Top node */
|
mxml_node_t *top, // I - Top node
|
||||||
const char *element, /* I - Element name or @code NULL@ for any */
|
const char *element, // I - Element name or `NULL` for any
|
||||||
const char *attr, /* I - Attribute name, or @code NULL@ for none */
|
const char *attr, // I - Attribute name, or `NULL` for none
|
||||||
const char *value, /* I - Attribute value, or @code NULL@ for any */
|
const char *value, // I - Attribute value, or `NULL` for any
|
||||||
int descend) /* I - Descend into tree - @code MXML_DESCEND@, @code MXML_NO_DESCEND@, or @code MXML_DESCEND_FIRST@ */
|
int descend) // I - Descend into tree - `MXML_DESCEND`, `MXML_NO_DESCEND`, or `MXML_DESCEND_FIRST`
|
||||||
{
|
{
|
||||||
const char *temp; /* Current attribute value */
|
const char *temp; // Current attribute value
|
||||||
|
|
||||||
|
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!node || !top || (!attr && value))
|
if (!node || !top || (!attr && value))
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
/*
|
// Start with the next node...
|
||||||
* Start with the next node...
|
|
||||||
*/
|
|
||||||
|
|
||||||
node = mxmlWalkNext(node, top, descend);
|
node = mxmlWalkNext(node, top, descend);
|
||||||
|
|
||||||
/*
|
// Loop until we find a matching element...
|
||||||
* Loop until we find a matching element...
|
|
||||||
*/
|
|
||||||
|
|
||||||
while (node != NULL)
|
while (node != NULL)
|
||||||
{
|
{
|
||||||
/*
|
// See if this node matches...
|
||||||
* See if this node matches...
|
if (node->type == MXML_TYPE_ELEMENT && node->value.element.name && (!element || !strcmp(node->value.element.name, element)))
|
||||||
*/
|
|
||||||
|
|
||||||
if (node->type == MXML_ELEMENT &&
|
|
||||||
node->value.element.name &&
|
|
||||||
(!element || !strcmp(node->value.element.name, element)))
|
|
||||||
{
|
{
|
||||||
/*
|
// See if we need to check for an attribute...
|
||||||
* See if we need to check for an attribute...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!attr)
|
if (!attr)
|
||||||
return (node); /* No attribute search, return it... */
|
return (node); // No attribute search, return it...
|
||||||
|
|
||||||
/*
|
|
||||||
* Check for the attribute...
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
// Check for the attribute...
|
||||||
if ((temp = mxmlElementGetAttr(node, attr)) != NULL)
|
if ((temp = mxmlElementGetAttr(node, attr)) != NULL)
|
||||||
{
|
{
|
||||||
/*
|
// OK, we have the attribute, does it match?
|
||||||
* OK, we have the attribute, does it match?
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!value || !strcmp(value, temp))
|
if (!value || !strcmp(value, temp))
|
||||||
return (node); /* Yes, return it... */
|
return (node); // Yes, return it...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// No match, move on to the next node...
|
||||||
* No match, move on to the next node...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (descend == MXML_DESCEND)
|
if (descend == MXML_DESCEND)
|
||||||
node = mxmlWalkNext(node, top, MXML_DESCEND);
|
node = mxmlWalkNext(node, top, MXML_DESCEND);
|
||||||
else
|
else
|
||||||
@ -104,59 +73,47 @@ mxmlFindElement(mxml_node_t *node, /* I - Current node */
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlFindPath()' - Find a node with the given path.
|
// 'mxmlFindPath()' - Find a node with the given path.
|
||||||
*
|
//
|
||||||
* The "path" is a slash-separated list of element names. The name "*" is
|
// The "path" is a slash-separated list of element names. The name "*" is
|
||||||
* considered a wildcard for one or more levels of elements. For example,
|
// considered a wildcard for one or more levels of elements. For example,
|
||||||
* "foo/one/two", "bar/two/one", "*\/one", and so forth.
|
// "foo/one/two", "bar/two/one", "*\/one", and so forth.
|
||||||
*
|
//
|
||||||
* The first child node of the found node is returned if the given node has
|
// The first child node of the found node is returned if the given node has
|
||||||
* children and the first child is a value node.
|
// children and the first child is a value node.
|
||||||
*
|
//
|
||||||
* @since Mini-XML 2.7@
|
|
||||||
*/
|
|
||||||
|
|
||||||
mxml_node_t * /* O - Found node or @code NULL@ */
|
mxml_node_t * // O - Found node or `NULL`
|
||||||
mxmlFindPath(mxml_node_t *top, /* I - Top node */
|
mxmlFindPath(mxml_node_t *top, // I - Top node
|
||||||
const char *path) /* I - Path to element */
|
const char *path) // I - Path to element
|
||||||
{
|
{
|
||||||
mxml_node_t *node; /* Current node */
|
mxml_node_t *node; // Current node
|
||||||
char element[256]; /* Current element name */
|
char element[256]; // Current element name
|
||||||
const char *pathsep; /* Separator in path */
|
const char *pathsep; // Separator in path
|
||||||
int descend; /* mxmlFindElement option */
|
int descend; // mxmlFindElement option
|
||||||
|
|
||||||
|
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!top || !path || !*path)
|
if (!top || !path || !*path)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
/*
|
// Search each element in the path...
|
||||||
* Search each element in the path...
|
|
||||||
*/
|
|
||||||
|
|
||||||
node = top;
|
node = top;
|
||||||
while (*path)
|
while (*path)
|
||||||
{
|
{
|
||||||
/*
|
// Handle wildcards...
|
||||||
* Handle wildcards...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!strncmp(path, "*/", 2))
|
if (!strncmp(path, "*/", 2))
|
||||||
{
|
{
|
||||||
path += 2;
|
path += 2;
|
||||||
descend = MXML_DESCEND;
|
descend = MXML_DESCEND;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
descend = MXML_DESCEND_FIRST;
|
descend = MXML_DESCEND_FIRST;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
// Get the next element in the path...
|
||||||
* Get the next element in the path...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ((pathsep = strchr(path, '/')) == NULL)
|
if ((pathsep = strchr(path, '/')) == NULL)
|
||||||
pathsep = path + strlen(path);
|
pathsep = path + strlen(path);
|
||||||
|
|
||||||
@ -171,87 +128,91 @@ mxmlFindPath(mxml_node_t *top, /* I - Top node */
|
|||||||
else
|
else
|
||||||
path = pathsep;
|
path = pathsep;
|
||||||
|
|
||||||
/*
|
// Search for the element...
|
||||||
* Search for the element...
|
if ((node = mxmlFindElement(node, node, element, NULL, NULL, descend)) == NULL)
|
||||||
*/
|
|
||||||
|
|
||||||
if ((node = mxmlFindElement(node, node, element, NULL, NULL,
|
|
||||||
descend)) == NULL)
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// If we get this far, return the node or its first child...
|
||||||
* If we get this far, return the node or its first child...
|
if (node->child && node->child->type != MXML_TYPE_ELEMENT)
|
||||||
*/
|
|
||||||
|
|
||||||
if (node->child && node->child->type != MXML_ELEMENT)
|
|
||||||
return (node->child);
|
return (node->child);
|
||||||
else
|
else
|
||||||
return (node);
|
return (node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlWalkNext()' - Walk to the next logical node in the tree.
|
// 'mxmlWalkNext()' - Walk to the next logical node in the tree.
|
||||||
*
|
//
|
||||||
* The descend argument controls whether the first child is considered
|
// The descend argument controls whether the first child is considered
|
||||||
* to be the next node. The top node argument constrains the walk to
|
// to be the next node. The top node argument constrains the walk to
|
||||||
* the node's children.
|
// the node's children.
|
||||||
*/
|
//
|
||||||
|
|
||||||
mxml_node_t * /* O - Next node or @code NULL@ */
|
mxml_node_t * // O - Next node or `NULL`
|
||||||
mxmlWalkNext(mxml_node_t *node, /* I - Current node */
|
mxmlWalkNext(mxml_node_t *node, // I - Current node
|
||||||
mxml_node_t *top, /* I - Top node */
|
mxml_node_t *top, // I - Top node
|
||||||
int descend) /* I - Descend into tree - @code MXML_DESCEND@, @code MXML_NO_DESCEND@, or @code MXML_DESCEND_FIRST@ */
|
int descend) // I - Descend into tree - `MXML_DESCEND`, `MXML_NO_DESCEND`, or `MXML_DESCEND_FIRST`
|
||||||
{
|
{
|
||||||
if (!node)
|
if (!node)
|
||||||
|
{
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
}
|
||||||
else if (node->child && descend)
|
else if (node->child && descend)
|
||||||
|
{
|
||||||
return (node->child);
|
return (node->child);
|
||||||
|
}
|
||||||
else if (node == top)
|
else if (node == top)
|
||||||
|
{
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
}
|
||||||
else if (node->next)
|
else if (node->next)
|
||||||
|
{
|
||||||
return (node->next);
|
return (node->next);
|
||||||
|
}
|
||||||
else if (node->parent && node->parent != top)
|
else if (node->parent && node->parent != top)
|
||||||
{
|
{
|
||||||
node = node->parent;
|
node = node->parent;
|
||||||
|
|
||||||
while (!node->next)
|
while (!node->next)
|
||||||
|
{
|
||||||
if (node->parent == top || !node->parent)
|
if (node->parent == top || !node->parent)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
else
|
else
|
||||||
node = node->parent;
|
node = node->parent;
|
||||||
|
}
|
||||||
|
|
||||||
return (node->next);
|
return (node->next);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlWalkPrev()' - Walk to the previous logical node in the tree.
|
// 'mxmlWalkPrev()' - Walk to the previous logical node in the tree.
|
||||||
*
|
//
|
||||||
* The descend argument controls whether the previous node's last child
|
// The descend argument controls whether the previous node's last child
|
||||||
* is considered to be the previous node. The top node argument constrains
|
// is considered to be the previous node. The top node argument constrains
|
||||||
* the walk to the node's children.
|
// the walk to the node's children.
|
||||||
*/
|
//
|
||||||
|
|
||||||
mxml_node_t * /* O - Previous node or @code NULL@ */
|
mxml_node_t * // O - Previous node or `NULL`
|
||||||
mxmlWalkPrev(mxml_node_t *node, /* I - Current node */
|
mxmlWalkPrev(mxml_node_t *node, // I - Current node
|
||||||
mxml_node_t *top, /* I - Top node */
|
mxml_node_t *top, // I - Top node
|
||||||
int descend) /* I - Descend into tree - @code MXML_DESCEND@, @code MXML_NO_DESCEND@, or @code MXML_DESCEND_FIRST@ */
|
int descend) // I - Descend into tree - `MXML_DESCEND`, `MXML_NO_DESCEND`, or `MXML_DESCEND_FIRST`
|
||||||
{
|
{
|
||||||
if (!node || node == top)
|
if (!node || node == top)
|
||||||
|
{
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
}
|
||||||
else if (node->prev)
|
else if (node->prev)
|
||||||
{
|
{
|
||||||
if (node->prev->last_child && descend)
|
if (node->prev->last_child && descend)
|
||||||
{
|
{
|
||||||
/*
|
// Find the last child under the previous node...
|
||||||
* Find the last child under the previous node...
|
|
||||||
*/
|
|
||||||
|
|
||||||
node = node->prev->last_child;
|
node = node->prev->last_child;
|
||||||
|
|
||||||
while (node->last_child)
|
while (node->last_child)
|
||||||
@ -260,10 +221,16 @@ mxmlWalkPrev(mxml_node_t *node, /* I - Current node */
|
|||||||
return (node);
|
return (node);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
return (node->prev);
|
return (node->prev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (node->parent != top)
|
else if (node->parent != top)
|
||||||
|
{
|
||||||
return (node->parent);
|
return (node->parent);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
369
mxml-set.c
369
mxml-set.c
@ -1,49 +1,36 @@
|
|||||||
/*
|
//
|
||||||
* Node set functions for Mini-XML, a small XML file parsing library.
|
// Node set functions for Mini-XML, a small XML file parsing library.
|
||||||
*
|
//
|
||||||
* https://www.msweet.org/mxml
|
// https://www.msweet.org/mxml
|
||||||
*
|
//
|
||||||
* Copyright © 2003-2021 by Michael R Sweet.
|
// Copyright © 2003-2024 by Michael R Sweet.
|
||||||
*
|
//
|
||||||
* Licensed under Apache License v2.0. See the file "LICENSE" for more
|
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
||||||
* information.
|
// information.
|
||||||
*/
|
//
|
||||||
|
|
||||||
/*
|
|
||||||
* Include necessary headers...
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "mxml-private.h"
|
#include "mxml-private.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlSetCDATA()' - Set the element name of a CDATA node.
|
// 'mxmlSetCDATA()' - Set the element name of a CDATA node.
|
||||||
*
|
//
|
||||||
* The node is not changed if it (or its first child) is not a CDATA element node.
|
// The node is not changed if it (or its first child) is not a CDATA element node.
|
||||||
*
|
//
|
||||||
* @since Mini-XML 2.3@
|
|
||||||
*/
|
|
||||||
|
|
||||||
int /* O - 0 on success, -1 on failure */
|
int // O - 0 on success, -1 on failure
|
||||||
mxmlSetCDATA(mxml_node_t *node, /* I - Node to set */
|
mxmlSetCDATA(mxml_node_t *node, // I - Node to set
|
||||||
const char *data) /* I - New data string */
|
const char *data) // I - New data string
|
||||||
{
|
{
|
||||||
char *s; /* New element name */
|
size_t datalen; // Length of data string
|
||||||
|
char *s; // New element name
|
||||||
|
|
||||||
|
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
if (node && node->type == MXML_TYPE_ELEMENT && strncmp(node->value.element.name, "![CDATA[", 8) && node->child && node->child->type == MXML_TYPE_ELEMENT && !strncmp(node->child->value.element.name, "![CDATA[", 8))
|
||||||
*/
|
|
||||||
|
|
||||||
if (node && node->type == MXML_ELEMENT &&
|
|
||||||
strncmp(node->value.element.name, "![CDATA[", 8) &&
|
|
||||||
node->child && node->child->type == MXML_ELEMENT &&
|
|
||||||
!strncmp(node->child->value.element.name, "![CDATA[", 8))
|
|
||||||
node = node->child;
|
node = node->child;
|
||||||
|
|
||||||
if (!node || node->type != MXML_ELEMENT ||
|
if (!node || node->type != MXML_TYPE_ELEMENT || strncmp(node->value.element.name, "![CDATA[", 8))
|
||||||
strncmp(node->value.element.name, "![CDATA[", 8))
|
|
||||||
{
|
{
|
||||||
mxml_error("Wrong node type.");
|
mxml_error("Wrong node type.");
|
||||||
return (-1);
|
return (-1);
|
||||||
@ -56,18 +43,14 @@ mxmlSetCDATA(mxml_node_t *node, /* I - Node to set */
|
|||||||
|
|
||||||
if (data == (node->value.element.name + 8))
|
if (data == (node->value.element.name + 8))
|
||||||
{
|
{
|
||||||
/*
|
// Don't change the value...
|
||||||
* Don't change the value...
|
|
||||||
*/
|
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Allocate the new value, free any old element value, and set the new value...
|
||||||
* Allocate the new value, free any old element value, and set the new value...
|
datalen = strlen(data);
|
||||||
*/
|
|
||||||
|
|
||||||
if ((s = _mxml_strdupf("![CDATA[%s", data)) == NULL)
|
if ((s = malloc(datalen + 9)) == NULL)
|
||||||
{
|
{
|
||||||
mxml_error("Unable to allocate memory for CDATA.");
|
mxml_error("Unable to allocate memory for CDATA.");
|
||||||
return (-1);
|
return (-1);
|
||||||
@ -75,34 +58,29 @@ mxmlSetCDATA(mxml_node_t *node, /* I - Node to set */
|
|||||||
|
|
||||||
free(node->value.element.name);
|
free(node->value.element.name);
|
||||||
node->value.element.name = s;
|
node->value.element.name = s;
|
||||||
|
snprintf(node->value.element.name, datalen + 9, "![CDATA[%s", data);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlSetCustom()' - Set the data and destructor of a custom data node.
|
// 'mxmlSetCustom()' - Set the data and destructor of a custom data node.
|
||||||
*
|
//
|
||||||
* The node is not changed if it (or its first child) is not a custom node.
|
// The node is not changed if it (or its first child) is not a custom node.
|
||||||
*
|
//
|
||||||
* @since Mini-XML 2.1@
|
|
||||||
*/
|
|
||||||
|
|
||||||
int /* O - 0 on success, -1 on failure */
|
int // O - 0 on success, -1 on failure
|
||||||
mxmlSetCustom(
|
mxmlSetCustom(
|
||||||
mxml_node_t *node, /* I - Node to set */
|
mxml_node_t *node, // I - Node to set
|
||||||
void *data, /* I - New data pointer */
|
void *data, // I - New data pointer
|
||||||
mxml_custom_destroy_cb_t destroy) /* I - New destructor function */
|
mxml_custom_destroy_cb_t destroy) // I - New destructor function
|
||||||
{
|
{
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
if (node && node->type == MXML_TYPE_ELEMENT && node->child && node->child->type == MXML_TYPE_CUSTOM)
|
||||||
*/
|
|
||||||
|
|
||||||
if (node && node->type == MXML_ELEMENT &&
|
|
||||||
node->child && node->child->type == MXML_CUSTOM)
|
|
||||||
node = node->child;
|
node = node->child;
|
||||||
|
|
||||||
if (!node || node->type != MXML_CUSTOM)
|
if (!node || node->type != MXML_TYPE_CUSTOM)
|
||||||
{
|
{
|
||||||
mxml_error("Wrong node type.");
|
mxml_error("Wrong node type.");
|
||||||
return (-1);
|
return (-1);
|
||||||
@ -114,10 +92,7 @@ mxmlSetCustom(
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Free any old element value and set the new value...
|
||||||
* Free any old element value and set the new value...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (node->value.custom.data && node->value.custom.destroy)
|
if (node->value.custom.data && node->value.custom.destroy)
|
||||||
(*(node->value.custom.destroy))(node->value.custom.data);
|
(*(node->value.custom.destroy))(node->value.custom.data);
|
||||||
|
|
||||||
@ -128,24 +103,21 @@ mxmlSetCustom(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlSetElement()' - Set the name of an element node.
|
// 'mxmlSetElement()' - Set the name of an element node.
|
||||||
*
|
//
|
||||||
* The node is not changed if it is not an element node.
|
// The node is not changed if it is not an element node.
|
||||||
*/
|
//
|
||||||
|
|
||||||
int /* O - 0 on success, -1 on failure */
|
int // O - 0 on success, -1 on failure
|
||||||
mxmlSetElement(mxml_node_t *node, /* I - Node to set */
|
mxmlSetElement(mxml_node_t *node, // I - Node to set
|
||||||
const char *name) /* I - New name string */
|
const char *name) // I - New name string
|
||||||
{
|
{
|
||||||
char *s; /* New name string */
|
char *s; // New name string
|
||||||
|
|
||||||
|
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
if (!node || node->type != MXML_TYPE_ELEMENT)
|
||||||
*/
|
|
||||||
|
|
||||||
if (!node || node->type != MXML_ELEMENT)
|
|
||||||
{
|
{
|
||||||
mxml_error("Wrong node type.");
|
mxml_error("Wrong node type.");
|
||||||
return (-1);
|
return (-1);
|
||||||
@ -159,10 +131,7 @@ mxmlSetElement(mxml_node_t *node, /* I - Node to set */
|
|||||||
if (name == node->value.element.name)
|
if (name == node->value.element.name)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
/*
|
// Free any old element value and set the new value...
|
||||||
* Free any old element value and set the new value...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ((s = strdup(name)) == NULL)
|
if ((s = strdup(name)) == NULL)
|
||||||
{
|
{
|
||||||
mxml_error("Unable to allocate memory for element name.");
|
mxml_error("Unable to allocate memory for element name.");
|
||||||
@ -176,62 +145,51 @@ mxmlSetElement(mxml_node_t *node, /* I - Node to set */
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlSetInteger()' - Set the value of an integer node.
|
// 'mxmlSetInteger()' - Set the value of an integer node.
|
||||||
*
|
//
|
||||||
* The node is not changed if it (or its first child) is not an integer node.
|
// The node is not changed if it (or its first child) is not an integer node.
|
||||||
*/
|
//
|
||||||
|
|
||||||
int /* O - 0 on success, -1 on failure */
|
int // O - 0 on success, -1 on failure
|
||||||
mxmlSetInteger(mxml_node_t *node, /* I - Node to set */
|
mxmlSetInteger(mxml_node_t *node, // I - Node to set
|
||||||
int integer) /* I - Integer value */
|
int integer) // I - Integer value
|
||||||
{
|
{
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
if (node && node->type == MXML_TYPE_ELEMENT && node->child && node->child->type == MXML_TYPE_INTEGER)
|
||||||
*/
|
|
||||||
|
|
||||||
if (node && node->type == MXML_ELEMENT &&
|
|
||||||
node->child && node->child->type == MXML_INTEGER)
|
|
||||||
node = node->child;
|
node = node->child;
|
||||||
|
|
||||||
if (!node || node->type != MXML_INTEGER)
|
if (!node || node->type != MXML_TYPE_INTEGER)
|
||||||
{
|
{
|
||||||
mxml_error("Wrong node type.");
|
mxml_error("Wrong node type.");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Set the new value and return...
|
||||||
* Set the new value and return...
|
|
||||||
*/
|
|
||||||
|
|
||||||
node->value.integer = integer;
|
node->value.integer = integer;
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlSetOpaque()' - Set the value of an opaque node.
|
// 'mxmlSetOpaque()' - Set the value of an opaque node.
|
||||||
*
|
//
|
||||||
* The node is not changed if it (or its first child) is not an opaque node.
|
// The node is not changed if it (or its first child) is not an opaque node.
|
||||||
*/
|
//
|
||||||
|
|
||||||
int /* O - 0 on success, -1 on failure */
|
int // O - 0 on success, -1 on failure
|
||||||
mxmlSetOpaque(mxml_node_t *node, /* I - Node to set */
|
mxmlSetOpaque(mxml_node_t *node, // I - Node to set
|
||||||
const char *opaque) /* I - Opaque string */
|
const char *opaque) // I - Opaque string
|
||||||
{
|
{
|
||||||
char *s; /* New opaque string */
|
char *s; // New opaque string
|
||||||
|
|
||||||
|
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
if (node && node->type == MXML_TYPE_ELEMENT && node->child && node->child->type == MXML_TYPE_OPAQUE)
|
||||||
*/
|
|
||||||
|
|
||||||
if (node && node->type == MXML_ELEMENT &&
|
|
||||||
node->child && node->child->type == MXML_OPAQUE)
|
|
||||||
node = node->child;
|
node = node->child;
|
||||||
|
|
||||||
if (!node || node->type != MXML_OPAQUE)
|
if (!node || node->type != MXML_TYPE_OPAQUE)
|
||||||
{
|
{
|
||||||
mxml_error("Wrong node type.");
|
mxml_error("Wrong node type.");
|
||||||
return (-1);
|
return (-1);
|
||||||
@ -245,10 +203,7 @@ mxmlSetOpaque(mxml_node_t *node, /* I - Node to set */
|
|||||||
if (node->value.opaque == opaque)
|
if (node->value.opaque == opaque)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
/*
|
// Free any old opaque value and set the new value...
|
||||||
* Free any old opaque value and set the new value...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ((s = strdup(opaque)) == NULL)
|
if ((s = strdup(opaque)) == NULL)
|
||||||
{
|
{
|
||||||
mxml_error("Unable to allocate memory for opaque string.");
|
mxml_error("Unable to allocate memory for opaque string.");
|
||||||
@ -262,32 +217,27 @@ mxmlSetOpaque(mxml_node_t *node, /* I - Node to set */
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlSetOpaquef()' - Set the value of an opaque string node to a formatted string.
|
// 'mxmlSetOpaquef()' - Set the value of an opaque string node to a formatted string.
|
||||||
*
|
//
|
||||||
* The node is not changed if it (or its first child) is not an opaque node.
|
// The node is not changed if it (or its first child) is not an opaque node.
|
||||||
*
|
//
|
||||||
* @since Mini-XML 2.11@
|
|
||||||
*/
|
|
||||||
|
|
||||||
int /* O - 0 on success, -1 on failure */
|
int // O - 0 on success, -1 on failure
|
||||||
mxmlSetOpaquef(mxml_node_t *node, /* I - Node to set */
|
mxmlSetOpaquef(mxml_node_t *node, // I - Node to set
|
||||||
const char *format, /* I - Printf-style format string */
|
const char *format, // I - Printf-style format string
|
||||||
...) /* I - Additional arguments as needed */
|
...) // I - Additional arguments as needed
|
||||||
{
|
{
|
||||||
va_list ap; /* Pointer to arguments */
|
va_list ap; // Pointer to arguments
|
||||||
char *s; /* Temporary string */
|
char buffer[16384]; // Format buffer
|
||||||
|
char *s; // Temporary string
|
||||||
|
|
||||||
|
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
if (node && node->type == MXML_TYPE_ELEMENT && node->child && node->child->type == MXML_TYPE_OPAQUE)
|
||||||
*/
|
|
||||||
|
|
||||||
if (node && node->type == MXML_ELEMENT &&
|
|
||||||
node->child && node->child->type == MXML_OPAQUE)
|
|
||||||
node = node->child;
|
node = node->child;
|
||||||
|
|
||||||
if (!node || node->type != MXML_OPAQUE)
|
if (!node || node->type != MXML_TYPE_OPAQUE)
|
||||||
{
|
{
|
||||||
mxml_error("Wrong node type.");
|
mxml_error("Wrong node type.");
|
||||||
return (-1);
|
return (-1);
|
||||||
@ -298,15 +248,12 @@ mxmlSetOpaquef(mxml_node_t *node, /* I - Node to set */
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Format the new string, free any old string value, and set the new value...
|
||||||
* Format the new string, free any old string value, and set the new value...
|
|
||||||
*/
|
|
||||||
|
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
s = _mxml_vstrdupf(format, ap);
|
vsnprintf(buffer, sizeof(buffer), format, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
if (!s)
|
if ((s = strdup(buffer)) == NULL)
|
||||||
{
|
{
|
||||||
mxml_error("Unable to allocate memory for opaque string.");
|
mxml_error("Unable to allocate memory for opaque string.");
|
||||||
return (-1);
|
return (-1);
|
||||||
@ -319,63 +266,55 @@ mxmlSetOpaquef(mxml_node_t *node, /* I - Node to set */
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlSetReal()' - Set the value of a real number node.
|
// 'mxmlSetReal()' - Set the value of a real number node.
|
||||||
*
|
//
|
||||||
* The node is not changed if it (or its first child) is not a real number node.
|
// The node is not changed if it (or its first child) is not a real number node.
|
||||||
*/
|
//
|
||||||
|
|
||||||
int /* O - 0 on success, -1 on failure */
|
int // O - 0 on success, -1 on failure
|
||||||
mxmlSetReal(mxml_node_t *node, /* I - Node to set */
|
mxmlSetReal(mxml_node_t *node, // I - Node to set
|
||||||
double real) /* I - Real number value */
|
double real) // I - Real number value
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Range check input...
|
* Range check input...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (node && node->type == MXML_ELEMENT &&
|
if (node && node->type == MXML_TYPE_ELEMENT && node->child && node->child->type == MXML_TYPE_REAL)
|
||||||
node->child && node->child->type == MXML_REAL)
|
|
||||||
node = node->child;
|
node = node->child;
|
||||||
|
|
||||||
if (!node || node->type != MXML_REAL)
|
if (!node || node->type != MXML_TYPE_REAL)
|
||||||
{
|
{
|
||||||
mxml_error("Wrong node type.");
|
mxml_error("Wrong node type.");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Set the new value and return...
|
||||||
* Set the new value and return...
|
|
||||||
*/
|
|
||||||
|
|
||||||
node->value.real = real;
|
node->value.real = real;
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlSetText()' - Set the value of a text node.
|
// 'mxmlSetText()' - Set the value of a text node.
|
||||||
*
|
//
|
||||||
* The node is not changed if it (or its first child) is not a text node.
|
// The node is not changed if it (or its first child) is not a text node.
|
||||||
*/
|
//
|
||||||
|
|
||||||
int /* O - 0 on success, -1 on failure */
|
int // O - 0 on success, -1 on failure
|
||||||
mxmlSetText(mxml_node_t *node, /* I - Node to set */
|
mxmlSetText(mxml_node_t *node, // I - Node to set
|
||||||
int whitespace, /* I - 1 = leading whitespace, 0 = no whitespace */
|
int whitespace, // I - 1 = leading whitespace, 0 = no whitespace
|
||||||
const char *string) /* I - String */
|
const char *string) // I - String
|
||||||
{
|
{
|
||||||
char *s; /* New string */
|
char *s; // New string
|
||||||
|
|
||||||
|
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
if (node && node->type == MXML_TYPE_ELEMENT && node->child && node->child->type == MXML_TYPE_TEXT)
|
||||||
*/
|
|
||||||
|
|
||||||
if (node && node->type == MXML_ELEMENT &&
|
|
||||||
node->child && node->child->type == MXML_TEXT)
|
|
||||||
node = node->child;
|
node = node->child;
|
||||||
|
|
||||||
if (!node || node->type != MXML_TEXT)
|
if (!node || node->type != MXML_TYPE_TEXT)
|
||||||
{
|
{
|
||||||
mxml_error("Wrong node type.");
|
mxml_error("Wrong node type.");
|
||||||
return (-1);
|
return (-1);
|
||||||
@ -392,10 +331,7 @@ mxmlSetText(mxml_node_t *node, /* I - Node to set */
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Free any old string value and set the new value...
|
||||||
* Free any old string value and set the new value...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ((s = strdup(string)) == NULL)
|
if ((s = strdup(string)) == NULL)
|
||||||
{
|
{
|
||||||
mxml_error("Unable to allocate memory for text string.");
|
mxml_error("Unable to allocate memory for text string.");
|
||||||
@ -411,31 +347,28 @@ mxmlSetText(mxml_node_t *node, /* I - Node to set */
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlSetTextf()' - Set the value of a text node to a formatted string.
|
// 'mxmlSetTextf()' - Set the value of a text node to a formatted string.
|
||||||
*
|
//
|
||||||
* The node is not changed if it (or its first child) is not a text node.
|
// The node is not changed if it (or its first child) is not a text node.
|
||||||
*/
|
//
|
||||||
|
|
||||||
int /* O - 0 on success, -1 on failure */
|
int // O - 0 on success, -1 on failure
|
||||||
mxmlSetTextf(mxml_node_t *node, /* I - Node to set */
|
mxmlSetTextf(mxml_node_t *node, // I - Node to set
|
||||||
int whitespace, /* I - 1 = leading whitespace, 0 = no whitespace */
|
int whitespace, // I - 1 = leading whitespace, 0 = no whitespace
|
||||||
const char *format, /* I - Printf-style format string */
|
const char *format, // I - Printf-style format string
|
||||||
...) /* I - Additional arguments as needed */
|
...) // I - Additional arguments as needed
|
||||||
{
|
{
|
||||||
va_list ap; /* Pointer to arguments */
|
va_list ap; // Pointer to arguments
|
||||||
char *s; /* Temporary string */
|
char buffer[16384]; // Format buffer
|
||||||
|
char *s; // Temporary string
|
||||||
|
|
||||||
|
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
if (node && node->type == MXML_TYPE_ELEMENT && node->child && node->child->type == MXML_TYPE_TEXT)
|
||||||
*/
|
|
||||||
|
|
||||||
if (node && node->type == MXML_ELEMENT &&
|
|
||||||
node->child && node->child->type == MXML_TEXT)
|
|
||||||
node = node->child;
|
node = node->child;
|
||||||
|
|
||||||
if (!node || node->type != MXML_TEXT)
|
if (!node || node->type != MXML_TYPE_TEXT)
|
||||||
{
|
{
|
||||||
mxml_error("Wrong node type.");
|
mxml_error("Wrong node type.");
|
||||||
return (-1);
|
return (-1);
|
||||||
@ -451,10 +384,10 @@ mxmlSetTextf(mxml_node_t *node, /* I - Node to set */
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
s = _mxml_vstrdupf(format, ap);
|
vsnprintf(buffer, sizeof(buffer), format, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
if (!s)
|
if ((s = strdup(buffer)) == NULL)
|
||||||
{
|
{
|
||||||
mxml_error("Unable to allocate memory for text string.");
|
mxml_error("Unable to allocate memory for text string.");
|
||||||
return (-1);
|
return (-1);
|
||||||
@ -469,27 +402,19 @@ mxmlSetTextf(mxml_node_t *node, /* I - Node to set */
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'mxmlSetUserData()' - Set the user data pointer for a node.
|
// 'mxmlSetUserData()' - Set the user data pointer for a node.
|
||||||
*
|
//
|
||||||
* @since Mini-XML 2.7@
|
|
||||||
*/
|
|
||||||
|
|
||||||
int /* O - 0 on success, -1 on failure */
|
int // O - 0 on success, -1 on failure
|
||||||
mxmlSetUserData(mxml_node_t *node, /* I - Node to set */
|
mxmlSetUserData(mxml_node_t *node, // I - Node to set
|
||||||
void *data) /* I - User data pointer */
|
void *data) // I - User data pointer
|
||||||
{
|
{
|
||||||
/*
|
// Range check input...
|
||||||
* Range check input...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!node)
|
if (!node)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
/*
|
// Set the user data pointer and return...
|
||||||
* Set the user data pointer and return...
|
|
||||||
*/
|
|
||||||
|
|
||||||
node->user_data = data;
|
node->user_data = data;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
561
mxml-string.c
561
mxml-string.c
@ -1,561 +0,0 @@
|
|||||||
/*
|
|
||||||
* String functions for Mini-XML, a small XML file parsing library.
|
|
||||||
*
|
|
||||||
* https://www.msweet.org/mxml
|
|
||||||
*
|
|
||||||
* Copyright © 2003-2019 by Michael R Sweet.
|
|
||||||
*
|
|
||||||
* Licensed under Apache License v2.0. See the file "LICENSE" for more
|
|
||||||
* information.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Include necessary headers...
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The va_copy macro is part of C99, but many compilers don't implement it.
|
|
||||||
* Provide a "direct assignment" implmentation when va_copy isn't defined...
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef va_copy
|
|
||||||
# ifdef __va_copy
|
|
||||||
# define va_copy(dst,src) __va_copy(dst,src)
|
|
||||||
# else
|
|
||||||
# define va_copy(dst,src) memcpy(&dst, &src, sizeof(va_list))
|
|
||||||
# endif /* __va_copy */
|
|
||||||
#endif /* va_copy */
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef HAVE_SNPRINTF
|
|
||||||
/*
|
|
||||||
* '_mxml_snprintf()' - Format a string.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int /* O - Number of bytes formatted */
|
|
||||||
_mxml_snprintf(char *buffer, /* I - Output buffer */
|
|
||||||
size_t bufsize, /* I - Size of output buffer */
|
|
||||||
const char *format, /* I - Printf-style format string */
|
|
||||||
...) /* I - Additional arguments as needed */
|
|
||||||
{
|
|
||||||
va_list ap; /* Argument list */
|
|
||||||
int bytes; /* Number of bytes formatted */
|
|
||||||
|
|
||||||
|
|
||||||
va_start(ap, format);
|
|
||||||
bytes = vsnprintf(buffer, bufsize, format, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
return (bytes);
|
|
||||||
}
|
|
||||||
#endif /* !HAVE_SNPRINTF */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* '_mxml_strdup()' - Duplicate a string.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef HAVE_STRDUP
|
|
||||||
char * /* O - New string pointer */
|
|
||||||
_mxml_strdup(const char *s) /* I - String to duplicate */
|
|
||||||
{
|
|
||||||
char *t; /* New string pointer */
|
|
||||||
|
|
||||||
|
|
||||||
if (s == NULL)
|
|
||||||
return (NULL);
|
|
||||||
|
|
||||||
if ((t = malloc(strlen(s) + 1)) == NULL)
|
|
||||||
return (NULL);
|
|
||||||
|
|
||||||
return (strcpy(t, s));
|
|
||||||
}
|
|
||||||
#endif /* !HAVE_STRDUP */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* '_mxml_strdupf()' - Format and duplicate a string.
|
|
||||||
*/
|
|
||||||
|
|
||||||
char * /* O - New string pointer */
|
|
||||||
_mxml_strdupf(const char *format, /* I - Printf-style format string */
|
|
||||||
...) /* I - Additional arguments as needed */
|
|
||||||
{
|
|
||||||
va_list ap; /* Pointer to additional arguments */
|
|
||||||
char *s; /* Pointer to formatted string */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get a pointer to the additional arguments, format the string,
|
|
||||||
* and return it...
|
|
||||||
*/
|
|
||||||
|
|
||||||
va_start(ap, format);
|
|
||||||
#ifdef HAVE_VASPRINTF
|
|
||||||
if (vasprintf(&s, format, ap) < 0)
|
|
||||||
s = NULL;
|
|
||||||
#else
|
|
||||||
s = _mxml_vstrdupf(format, ap);
|
|
||||||
#endif /* HAVE_VASPRINTF */
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
return (s);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef HAVE_STRLCAT
|
|
||||||
/*
|
|
||||||
* '_mxml_strlcat()' - Safely concatenate a string.
|
|
||||||
*/
|
|
||||||
|
|
||||||
size_t /* O - Number of bytes copied */
|
|
||||||
_mxml_strlcat(char *dst, /* I - Destination buffer */
|
|
||||||
const char *src, /* I - Source string */
|
|
||||||
size_t dstsize) /* I - Size of destination buffer */
|
|
||||||
{
|
|
||||||
size_t srclen; /* Length of source string */
|
|
||||||
size_t dstlen; /* Length of destination string */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Figure out how much room is left...
|
|
||||||
*/
|
|
||||||
|
|
||||||
dstlen = strlen(dst);
|
|
||||||
|
|
||||||
if (dstsize <= (dstlen + 1))
|
|
||||||
return (dstlen); /* No room, return immediately... */
|
|
||||||
|
|
||||||
dstsize -= dstlen + 1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Figure out how much room is needed...
|
|
||||||
*/
|
|
||||||
|
|
||||||
srclen = strlen(src);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copy the appropriate amount...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (srclen > dstsize)
|
|
||||||
srclen = dstsize;
|
|
||||||
|
|
||||||
memmove(dst + dstlen, src, srclen);
|
|
||||||
dst[dstlen + srclen] = '\0';
|
|
||||||
|
|
||||||
return (dstlen + srclen);
|
|
||||||
}
|
|
||||||
#endif /* !HAVE_STRLCAT */
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef HAVE_STRLCPY
|
|
||||||
/*
|
|
||||||
* '_mxml_strlcpy()' - Safely copy a string.
|
|
||||||
*/
|
|
||||||
|
|
||||||
size_t /* O - Number of bytes copied */
|
|
||||||
_mxml_strlcpy(char *dst, /* I - Destination buffer */
|
|
||||||
const char *src, /* I - Source string */
|
|
||||||
size_t dstsize) /* I - Size of destination buffer */
|
|
||||||
{
|
|
||||||
size_t srclen; /* Length of source string */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Figure out how much room is needed...
|
|
||||||
*/
|
|
||||||
|
|
||||||
dstsize --;
|
|
||||||
|
|
||||||
srclen = strlen(src);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copy the appropriate amount...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (srclen > dstsize)
|
|
||||||
srclen = dstsize;
|
|
||||||
|
|
||||||
memmove(dst, src, srclen);
|
|
||||||
dst[srclen] = '\0';
|
|
||||||
|
|
||||||
return (srclen);
|
|
||||||
}
|
|
||||||
#endif /* !HAVE_STRLCPY */
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef HAVE_VSNPRINTF
|
|
||||||
/*
|
|
||||||
* '_mxml_vsnprintf()' - Format a string into a fixed size buffer.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int /* O - Number of bytes formatted */
|
|
||||||
_mxml_vsnprintf(char *buffer, /* O - Output buffer */
|
|
||||||
size_t bufsize, /* O - Size of output buffer */
|
|
||||||
const char *format, /* I - Printf-style format string */
|
|
||||||
va_list ap) /* I - Pointer to additional arguments */
|
|
||||||
{
|
|
||||||
char *bufptr, /* Pointer to position in buffer */
|
|
||||||
*bufend, /* Pointer to end of buffer */
|
|
||||||
sign, /* Sign of format width */
|
|
||||||
size, /* Size character (h, l, L) */
|
|
||||||
type; /* Format type character */
|
|
||||||
int width, /* Width of field */
|
|
||||||
prec; /* Number of characters of precision */
|
|
||||||
char tformat[100], /* Temporary format string for sprintf() */
|
|
||||||
*tptr, /* Pointer into temporary format */
|
|
||||||
temp[1024]; /* Buffer for formatted numbers */
|
|
||||||
char *s; /* Pointer to string */
|
|
||||||
int slen; /* Length of string */
|
|
||||||
int bytes; /* Total number of bytes needed */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Loop through the format string, formatting as needed...
|
|
||||||
*/
|
|
||||||
|
|
||||||
bufptr = buffer;
|
|
||||||
bufend = buffer + bufsize - 1;
|
|
||||||
bytes = 0;
|
|
||||||
|
|
||||||
while (*format)
|
|
||||||
{
|
|
||||||
if (*format == '%')
|
|
||||||
{
|
|
||||||
tptr = tformat;
|
|
||||||
*tptr++ = *format++;
|
|
||||||
|
|
||||||
if (*format == '%')
|
|
||||||
{
|
|
||||||
if (bufptr && bufptr < bufend)
|
|
||||||
*bufptr++ = *format;
|
|
||||||
bytes ++;
|
|
||||||
format ++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (strchr(" -+#\'", *format))
|
|
||||||
{
|
|
||||||
*tptr++ = *format;
|
|
||||||
sign = *format++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sign = 0;
|
|
||||||
|
|
||||||
if (*format == '*')
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Get width from argument...
|
|
||||||
*/
|
|
||||||
|
|
||||||
format ++;
|
|
||||||
width = va_arg(ap, int);
|
|
||||||
|
|
||||||
snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", width);
|
|
||||||
tptr += strlen(tptr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
width = 0;
|
|
||||||
|
|
||||||
while (isdigit(*format & 255))
|
|
||||||
{
|
|
||||||
if (tptr < (tformat + sizeof(tformat) - 1))
|
|
||||||
*tptr++ = *format;
|
|
||||||
|
|
||||||
width = width * 10 + *format++ - '0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*format == '.')
|
|
||||||
{
|
|
||||||
if (tptr < (tformat + sizeof(tformat) - 1))
|
|
||||||
*tptr++ = *format;
|
|
||||||
|
|
||||||
format ++;
|
|
||||||
|
|
||||||
if (*format == '*')
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Get precision from argument...
|
|
||||||
*/
|
|
||||||
|
|
||||||
format ++;
|
|
||||||
prec = va_arg(ap, int);
|
|
||||||
|
|
||||||
snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", prec);
|
|
||||||
tptr += strlen(tptr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
prec = 0;
|
|
||||||
|
|
||||||
while (isdigit(*format & 255))
|
|
||||||
{
|
|
||||||
if (tptr < (tformat + sizeof(tformat) - 1))
|
|
||||||
*tptr++ = *format;
|
|
||||||
|
|
||||||
prec = prec * 10 + *format++ - '0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
prec = -1;
|
|
||||||
|
|
||||||
if (*format == 'l' && format[1] == 'l')
|
|
||||||
{
|
|
||||||
size = 'L';
|
|
||||||
|
|
||||||
if (tptr < (tformat + sizeof(tformat) - 2))
|
|
||||||
{
|
|
||||||
*tptr++ = 'l';
|
|
||||||
*tptr++ = 'l';
|
|
||||||
}
|
|
||||||
|
|
||||||
format += 2;
|
|
||||||
}
|
|
||||||
else if (*format == 'h' || *format == 'l' || *format == 'L')
|
|
||||||
{
|
|
||||||
if (tptr < (tformat + sizeof(tformat) - 1))
|
|
||||||
*tptr++ = *format;
|
|
||||||
|
|
||||||
size = *format++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!*format)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (tptr < (tformat + sizeof(tformat) - 1))
|
|
||||||
*tptr++ = *format;
|
|
||||||
|
|
||||||
type = *format++;
|
|
||||||
*tptr = '\0';
|
|
||||||
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case 'E' : /* Floating point formats */
|
|
||||||
case 'G' :
|
|
||||||
case 'e' :
|
|
||||||
case 'f' :
|
|
||||||
case 'g' :
|
|
||||||
if ((width + 2) > sizeof(temp))
|
|
||||||
break;
|
|
||||||
|
|
||||||
sprintf(temp, tformat, va_arg(ap, double));
|
|
||||||
|
|
||||||
bytes += strlen(temp);
|
|
||||||
|
|
||||||
if (bufptr)
|
|
||||||
{
|
|
||||||
if ((bufptr + strlen(temp)) > bufend)
|
|
||||||
{
|
|
||||||
strncpy(bufptr, temp, (size_t)(bufend - bufptr));
|
|
||||||
bufptr = bufend;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
strcpy(bufptr, temp);
|
|
||||||
bufptr += strlen(temp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'B' : /* Integer formats */
|
|
||||||
case 'X' :
|
|
||||||
case 'b' :
|
|
||||||
case 'd' :
|
|
||||||
case 'i' :
|
|
||||||
case 'o' :
|
|
||||||
case 'u' :
|
|
||||||
case 'x' :
|
|
||||||
if ((width + 2) > sizeof(temp))
|
|
||||||
break;
|
|
||||||
|
|
||||||
#ifdef HAVE_LONG_LONG_INT
|
|
||||||
if (size == 'L')
|
|
||||||
sprintf(temp, tformat, va_arg(ap, long long));
|
|
||||||
else
|
|
||||||
#endif /* HAVE_LONG_LONG_INT */
|
|
||||||
sprintf(temp, tformat, va_arg(ap, int));
|
|
||||||
|
|
||||||
bytes += strlen(temp);
|
|
||||||
|
|
||||||
if (bufptr)
|
|
||||||
{
|
|
||||||
if ((bufptr + strlen(temp)) > bufend)
|
|
||||||
{
|
|
||||||
strncpy(bufptr, temp, (size_t)(bufend - bufptr));
|
|
||||||
bufptr = bufend;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
strcpy(bufptr, temp);
|
|
||||||
bufptr += strlen(temp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'p' : /* Pointer value */
|
|
||||||
if ((width + 2) > sizeof(temp))
|
|
||||||
break;
|
|
||||||
|
|
||||||
sprintf(temp, tformat, va_arg(ap, void *));
|
|
||||||
|
|
||||||
bytes += strlen(temp);
|
|
||||||
|
|
||||||
if (bufptr)
|
|
||||||
{
|
|
||||||
if ((bufptr + strlen(temp)) > bufend)
|
|
||||||
{
|
|
||||||
strncpy(bufptr, temp, (size_t)(bufend - bufptr));
|
|
||||||
bufptr = bufend;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
strcpy(bufptr, temp);
|
|
||||||
bufptr += strlen(temp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'c' : /* Character or character array */
|
|
||||||
bytes += width;
|
|
||||||
|
|
||||||
if (bufptr)
|
|
||||||
{
|
|
||||||
if (width <= 1)
|
|
||||||
*bufptr++ = va_arg(ap, int);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((bufptr + width) > bufend)
|
|
||||||
width = bufend - bufptr;
|
|
||||||
|
|
||||||
memcpy(bufptr, va_arg(ap, char *), (size_t)width);
|
|
||||||
bufptr += width;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 's' : /* String */
|
|
||||||
if ((s = va_arg(ap, char *)) == NULL)
|
|
||||||
s = "(null)";
|
|
||||||
|
|
||||||
slen = strlen(s);
|
|
||||||
if (slen > width && prec != width)
|
|
||||||
width = slen;
|
|
||||||
|
|
||||||
bytes += width;
|
|
||||||
|
|
||||||
if (bufptr)
|
|
||||||
{
|
|
||||||
if ((bufptr + width) > bufend)
|
|
||||||
width = bufend - bufptr;
|
|
||||||
|
|
||||||
if (slen > width)
|
|
||||||
slen = width;
|
|
||||||
|
|
||||||
if (sign == '-')
|
|
||||||
{
|
|
||||||
strncpy(bufptr, s, (size_t)slen);
|
|
||||||
memset(bufptr + slen, ' ', (size_t)(width - slen));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memset(bufptr, ' ', (size_t)(width - slen));
|
|
||||||
strncpy(bufptr + width - slen, s, (size_t)slen);
|
|
||||||
}
|
|
||||||
|
|
||||||
bufptr += width;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'n' : /* Output number of chars so far */
|
|
||||||
*(va_arg(ap, int *)) = bytes;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bytes ++;
|
|
||||||
|
|
||||||
if (bufptr && bufptr < bufend)
|
|
||||||
*bufptr++ = *format;
|
|
||||||
|
|
||||||
format ++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Nul-terminate the string and return the number of characters needed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
*bufptr = '\0';
|
|
||||||
|
|
||||||
return (bytes);
|
|
||||||
}
|
|
||||||
#endif /* !HAVE_VSNPRINTF */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* '_mxml_vstrdupf()' - Format and duplicate a string.
|
|
||||||
*/
|
|
||||||
|
|
||||||
char * /* O - New string pointer */
|
|
||||||
_mxml_vstrdupf(const char *format, /* I - Printf-style format string */
|
|
||||||
va_list ap) /* I - Pointer to additional arguments */
|
|
||||||
{
|
|
||||||
#ifdef HAVE_VASPRINTF
|
|
||||||
char *s; /* String */
|
|
||||||
|
|
||||||
if (vasprintf(&s, format, ap) < 0)
|
|
||||||
s = NULL;
|
|
||||||
|
|
||||||
return (s);
|
|
||||||
|
|
||||||
#else
|
|
||||||
int bytes; /* Number of bytes required */
|
|
||||||
char *buffer; /* String buffer */
|
|
||||||
# ifndef _WIN32
|
|
||||||
char temp[256]; /* Small buffer for first vsnprintf */
|
|
||||||
# endif /* !_WIN32 */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* First format with a tiny buffer; this will tell us how many bytes are
|
|
||||||
* needed...
|
|
||||||
*/
|
|
||||||
|
|
||||||
# ifdef _WIN32
|
|
||||||
bytes = _vscprintf(format, ap);
|
|
||||||
|
|
||||||
# else
|
|
||||||
va_list apcopy; /* Copy of argument list */
|
|
||||||
|
|
||||||
va_copy(apcopy, ap);
|
|
||||||
if ((bytes = vsnprintf(temp, sizeof(temp), format, apcopy)) < sizeof(temp))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Hey, the formatted string fits in the tiny buffer, so just dup that...
|
|
||||||
*/
|
|
||||||
|
|
||||||
return (strdup(temp));
|
|
||||||
}
|
|
||||||
# endif /* _WIN32 */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Allocate memory for the whole thing and reformat to the new buffer...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ((buffer = calloc(1, bytes + 1)) != NULL)
|
|
||||||
vsnprintf(buffer, bytes + 1, format, ap);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return the new string...
|
|
||||||
*/
|
|
||||||
|
|
||||||
return (buffer);
|
|
||||||
#endif /* HAVE_VASPRINTF */
|
|
||||||
}
|
|
280
mxml.h
280
mxml.h
@ -1,158 +1,140 @@
|
|||||||
/*
|
//
|
||||||
* Header file for Mini-XML, a small XML file parsing library.
|
// Header file for Mini-XML, a small XML file parsing library.
|
||||||
*
|
//
|
||||||
* https://www.msweet.org/mxml
|
// https://www.msweet.org/mxml
|
||||||
*
|
//
|
||||||
* Copyright © 2003-2021 by Michael R Sweet.
|
// Copyright © 2003-2024 by Michael R Sweet.
|
||||||
*
|
//
|
||||||
* Licensed under Apache License v2.0. See the file "LICENSE" for more
|
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
||||||
* information.
|
// information.
|
||||||
*/
|
//
|
||||||
|
|
||||||
/*
|
|
||||||
* Prevent multiple inclusion...
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _mxml_h_
|
|
||||||
# define _mxml_h_
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Include necessary headers...
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
#ifndef MXML_H
|
||||||
|
# define MXML_H
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
# include <string.h>
|
# include <string.h>
|
||||||
# include <ctype.h>
|
# include <ctype.h>
|
||||||
# include <errno.h>
|
# include <errno.h>
|
||||||
|
# ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
# endif // __cplusplus
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Constants...
|
// Constants...
|
||||||
*/
|
//
|
||||||
|
|
||||||
# define MXML_MAJOR_VERSION 3 /* Major version number */
|
# define MXML_MAJOR_VERSION 4 // Major version number
|
||||||
# define MXML_MINOR_VERSION 2 /* Minor version number */
|
# define MXML_MINOR_VERSION 0 // Minor version number
|
||||||
|
|
||||||
# define MXML_TAB 8 /* Tabs every N columns */
|
# ifdef __GNUC__
|
||||||
|
# define MXML_FORMAT(a,b) __attribute__ ((__format__ (__printf__, a, b)))
|
||||||
|
# else
|
||||||
|
# define MXML_FORMAT(a,b)
|
||||||
|
# endif // __GNUC__
|
||||||
|
|
||||||
# define MXML_NO_CALLBACK 0 /* Don't use a type callback */
|
# define MXML_TAB 8 // Tabs every N columns
|
||||||
|
|
||||||
|
# define MXML_NO_CALLBACK 0 // Don't use a type callback
|
||||||
# define MXML_INTEGER_CALLBACK mxml_integer_cb
|
# define MXML_INTEGER_CALLBACK mxml_integer_cb
|
||||||
/* Treat all data as integers */
|
// Treat all data as integers
|
||||||
# define MXML_OPAQUE_CALLBACK mxml_opaque_cb
|
# define MXML_OPAQUE_CALLBACK mxml_opaque_cb
|
||||||
/* Treat all data as opaque */
|
// Treat all data as opaque
|
||||||
# define MXML_REAL_CALLBACK mxml_real_cb
|
# define MXML_REAL_CALLBACK mxml_real_cb
|
||||||
/* Treat all data as real numbers */
|
// Treat all data as real numbers
|
||||||
# define MXML_TEXT_CALLBACK 0 /* Treat all data as text */
|
# define MXML_TEXT_CALLBACK 0 // Treat all data as text
|
||||||
# define MXML_IGNORE_CALLBACK mxml_ignore_cb
|
# define MXML_IGNORE_CALLBACK mxml_ignore_cb
|
||||||
/* Ignore all non-element content */
|
// Ignore all non-element content
|
||||||
|
|
||||||
# define MXML_NO_PARENT 0 /* No parent for the node */
|
# define MXML_NO_PARENT 0 // No parent for the node
|
||||||
|
|
||||||
# define MXML_DESCEND 1 /* Descend when finding/walking */
|
# define MXML_DESCEND 1 // Descend when finding/walking
|
||||||
# define MXML_NO_DESCEND 0 /* Don't descend when finding/walking */
|
# define MXML_NO_DESCEND 0 // Don't descend when finding/walking
|
||||||
# define MXML_DESCEND_FIRST -1 /* Descend for first find */
|
# define MXML_DESCEND_FIRST -1 // Descend for first find
|
||||||
|
|
||||||
# define MXML_WS_BEFORE_OPEN 0 /* Callback for before open tag */
|
# define MXML_WS_BEFORE_OPEN 0 // Callback for before open tag
|
||||||
# define MXML_WS_AFTER_OPEN 1 /* Callback for after open tag */
|
# define MXML_WS_AFTER_OPEN 1 // Callback for after open tag
|
||||||
# define MXML_WS_BEFORE_CLOSE 2 /* Callback for before close tag */
|
# define MXML_WS_BEFORE_CLOSE 2 // Callback for before close tag
|
||||||
# define MXML_WS_AFTER_CLOSE 3 /* Callback for after close tag */
|
# define MXML_WS_AFTER_CLOSE 3 // Callback for after close tag
|
||||||
|
|
||||||
# define MXML_ADD_BEFORE 0 /* Add node before specified node */
|
# define MXML_ADD_BEFORE 0 // Add node before specified node
|
||||||
# define MXML_ADD_AFTER 1 /* Add node after specified node */
|
# define MXML_ADD_AFTER 1 // Add node after specified node
|
||||||
# define MXML_ADD_TO_PARENT NULL /* Add node relative to parent */
|
# define MXML_ADD_TO_PARENT NULL // Add node relative to parent
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Data types...
|
// Data types...
|
||||||
*/
|
//
|
||||||
|
|
||||||
typedef enum mxml_sax_event_e /**** SAX event type. ****/
|
typedef enum mxml_sax_event_e // SAX event type.
|
||||||
{
|
{
|
||||||
MXML_SAX_CDATA, /* CDATA node */
|
MXML_SAX_EVENT_CDATA, // CDATA node
|
||||||
MXML_SAX_COMMENT, /* Comment node */
|
MXML_SAX_EVENT_COMMENT, // Comment node
|
||||||
MXML_SAX_DATA, /* Data node */
|
MXML_SAX_EVENT_DATA, // Data node
|
||||||
MXML_SAX_DIRECTIVE, /* Processing directive node */
|
MXML_SAX_EVENT_DIRECTIVE, // Processing directive node
|
||||||
MXML_SAX_ELEMENT_CLOSE, /* Element closed */
|
MXML_SAX_EVENT_ELEMENT_CLOSE, // Element closed
|
||||||
MXML_SAX_ELEMENT_OPEN /* Element opened */
|
MXML_SAX_EVENT_ELEMENT_OPEN // Element opened
|
||||||
} mxml_sax_event_t;
|
} mxml_sax_event_t;
|
||||||
|
|
||||||
typedef enum mxml_type_e /**** The XML node type. ****/
|
typedef enum mxml_type_e // The XML node type.
|
||||||
{
|
{
|
||||||
MXML_IGNORE = -1, /* Ignore/throw away node @since Mini-XML 2.3@ */
|
MXML_TYPE_IGNORE = -1, // Ignore/throw away node
|
||||||
MXML_ELEMENT, /* XML element with attributes */
|
MXML_TYPE_ELEMENT, // XML element with attributes
|
||||||
MXML_INTEGER, /* Integer value */
|
MXML_TYPE_INTEGER, // Integer value
|
||||||
MXML_OPAQUE, /* Opaque string */
|
MXML_TYPE_OPAQUE, // Opaque string
|
||||||
MXML_REAL, /* Real value */
|
MXML_TYPE_REAL, // Real value
|
||||||
MXML_TEXT, /* Text fragment */
|
MXML_TYPE_TEXT, // Text fragment
|
||||||
MXML_CUSTOM /* Custom data @since Mini-XML 2.1@ */
|
MXML_TYPE_CUSTOM // Custom data
|
||||||
} mxml_type_t;
|
} mxml_type_t;
|
||||||
|
|
||||||
typedef void (*mxml_custom_destroy_cb_t)(void *);
|
typedef void (*mxml_custom_destroy_cb_t)(void *);
|
||||||
/**** Custom data destructor ****/
|
// Custom data destructor
|
||||||
|
|
||||||
typedef void (*mxml_error_cb_t)(const char *);
|
typedef void (*mxml_error_cb_t)(const char *);
|
||||||
/**** Error callback function ****/
|
// Error callback function
|
||||||
|
|
||||||
typedef struct _mxml_node_s mxml_node_t; /**** An XML node. ****/
|
typedef struct _mxml_node_s mxml_node_t;// An XML node.
|
||||||
|
|
||||||
typedef struct _mxml_index_s mxml_index_t;
|
typedef struct _mxml_index_s mxml_index_t;
|
||||||
/**** An XML node index. ****/
|
// An XML node index.
|
||||||
|
|
||||||
typedef int (*mxml_custom_load_cb_t)(mxml_node_t *, const char *);
|
typedef int (*mxml_custom_load_cb_t)(mxml_node_t *, const char *);
|
||||||
/**** Custom data load callback function ****/
|
// Custom data load callback function
|
||||||
|
|
||||||
typedef char *(*mxml_custom_save_cb_t)(mxml_node_t *);
|
typedef char *(*mxml_custom_save_cb_t)(mxml_node_t *);
|
||||||
/**** Custom data save callback function ****/
|
// Custom data save callback function
|
||||||
|
|
||||||
typedef int (*mxml_entity_cb_t)(const char *);
|
typedef int (*mxml_entity_cb_t)(const char *);
|
||||||
/**** Entity callback function */
|
// Entity callback function
|
||||||
|
|
||||||
typedef mxml_type_t (*mxml_load_cb_t)(mxml_node_t *);
|
typedef mxml_type_t (*mxml_load_cb_t)(mxml_node_t *);
|
||||||
/**** Load callback function ****/
|
// Load callback function
|
||||||
|
|
||||||
typedef const char *(*mxml_save_cb_t)(mxml_node_t *, int);
|
typedef const char *(*mxml_save_cb_t)(mxml_node_t *, int);
|
||||||
/**** Save callback function ****/
|
// Save callback function
|
||||||
|
|
||||||
typedef void (*mxml_sax_cb_t)(mxml_node_t *, mxml_sax_event_t, void *);
|
typedef void (*mxml_sax_cb_t)(mxml_node_t *, mxml_sax_event_t, void *);
|
||||||
/**** SAX callback function ****/
|
// SAX callback function
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* C++ support...
|
// Prototypes...
|
||||||
*/
|
//
|
||||||
|
|
||||||
# ifdef __cplusplus
|
extern void mxmlAdd(mxml_node_t *parent, int where, mxml_node_t *child, mxml_node_t *node);
|
||||||
extern "C" {
|
|
||||||
# endif /* __cplusplus */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Prototypes...
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern void mxmlAdd(mxml_node_t *parent, int where,
|
|
||||||
mxml_node_t *child, mxml_node_t *node);
|
|
||||||
extern void mxmlDelete(mxml_node_t *node);
|
extern void mxmlDelete(mxml_node_t *node);
|
||||||
extern void mxmlElementDeleteAttr(mxml_node_t *node,
|
extern void mxmlElementDeleteAttr(mxml_node_t *node, const char *name);
|
||||||
const char *name);
|
|
||||||
extern const char *mxmlElementGetAttr(mxml_node_t *node, const char *name);
|
extern const char *mxmlElementGetAttr(mxml_node_t *node, const char *name);
|
||||||
extern const char *mxmlElementGetAttrByIndex(mxml_node_t *node, int idx, const char **name);
|
extern const char *mxmlElementGetAttrByIndex(mxml_node_t *node, int idx, const char **name);
|
||||||
extern int mxmlElementGetAttrCount(mxml_node_t *node);
|
extern int mxmlElementGetAttrCount(mxml_node_t *node);
|
||||||
extern void mxmlElementSetAttr(mxml_node_t *node, const char *name,
|
extern void mxmlElementSetAttr(mxml_node_t *node, const char *name, const char *value);
|
||||||
const char *value);
|
extern void mxmlElementSetAttrf(mxml_node_t *node, const char *name, const char *format, ...) MXML_FORMAT(3,4);
|
||||||
extern void mxmlElementSetAttrf(mxml_node_t *node, const char *name,
|
|
||||||
const char *format, ...)
|
|
||||||
# ifdef __GNUC__
|
|
||||||
__attribute__ ((__format__ (__printf__, 3, 4)))
|
|
||||||
# endif /* __GNUC__ */
|
|
||||||
;
|
|
||||||
extern int mxmlEntityAddCallback(mxml_entity_cb_t cb);
|
extern int mxmlEntityAddCallback(mxml_entity_cb_t cb);
|
||||||
extern const char *mxmlEntityGetName(int val);
|
extern const char *mxmlEntityGetName(int val);
|
||||||
extern int mxmlEntityGetValue(const char *name);
|
extern int mxmlEntityGetValue(const char *name);
|
||||||
extern void mxmlEntityRemoveCallback(mxml_entity_cb_t cb);
|
extern void mxmlEntityRemoveCallback(mxml_entity_cb_t cb);
|
||||||
extern mxml_node_t *mxmlFindElement(mxml_node_t *node, mxml_node_t *top,
|
extern mxml_node_t *mxmlFindElement(mxml_node_t *node, mxml_node_t *top, const char *element, const char *attr, const char *value, int descend);
|
||||||
const char *element, const char *attr,
|
|
||||||
const char *value, int descend);
|
|
||||||
extern mxml_node_t *mxmlFindPath(mxml_node_t *node, const char *path);
|
extern mxml_node_t *mxmlFindPath(mxml_node_t *node, const char *path);
|
||||||
extern const char *mxmlGetCDATA(mxml_node_t *node);
|
extern const char *mxmlGetCDATA(mxml_node_t *node);
|
||||||
extern const void *mxmlGetCustom(mxml_node_t *node);
|
extern const void *mxmlGetCustom(mxml_node_t *node);
|
||||||
@ -171,109 +153,61 @@ extern mxml_type_t mxmlGetType(mxml_node_t *node);
|
|||||||
extern void *mxmlGetUserData(mxml_node_t *node);
|
extern void *mxmlGetUserData(mxml_node_t *node);
|
||||||
extern void mxmlIndexDelete(mxml_index_t *ind);
|
extern void mxmlIndexDelete(mxml_index_t *ind);
|
||||||
extern mxml_node_t *mxmlIndexEnum(mxml_index_t *ind);
|
extern mxml_node_t *mxmlIndexEnum(mxml_index_t *ind);
|
||||||
extern mxml_node_t *mxmlIndexFind(mxml_index_t *ind,
|
extern mxml_node_t *mxmlIndexFind(mxml_index_t *ind, const char *element, const char *value);
|
||||||
const char *element,
|
|
||||||
const char *value);
|
|
||||||
extern int mxmlIndexGetCount(mxml_index_t *ind);
|
extern int mxmlIndexGetCount(mxml_index_t *ind);
|
||||||
extern mxml_index_t *mxmlIndexNew(mxml_node_t *node, const char *element,
|
extern mxml_index_t *mxmlIndexNew(mxml_node_t *node, const char *element, const char *attr);
|
||||||
const char *attr);
|
|
||||||
extern mxml_node_t *mxmlIndexReset(mxml_index_t *ind);
|
extern mxml_node_t *mxmlIndexReset(mxml_index_t *ind);
|
||||||
extern mxml_node_t *mxmlLoadFd(mxml_node_t *top, int fd,
|
extern mxml_node_t *mxmlLoadFd(mxml_node_t *top, int fd, mxml_load_cb_t cb); extern mxml_node_t *mxmlLoadFile(mxml_node_t *top, FILE *fp, mxml_load_cb_t cb);
|
||||||
mxml_type_t (*cb)(mxml_node_t *));
|
extern mxml_node_t *mxmlLoadString(mxml_node_t *top, const char *s, mxml_load_cb_t cb);
|
||||||
extern mxml_node_t *mxmlLoadFile(mxml_node_t *top, FILE *fp,
|
|
||||||
mxml_type_t (*cb)(mxml_node_t *));
|
|
||||||
extern mxml_node_t *mxmlLoadString(mxml_node_t *top, const char *s,
|
|
||||||
mxml_type_t (*cb)(mxml_node_t *));
|
|
||||||
extern mxml_node_t *mxmlNewCDATA(mxml_node_t *parent, const char *string);
|
extern mxml_node_t *mxmlNewCDATA(mxml_node_t *parent, const char *string);
|
||||||
extern mxml_node_t *mxmlNewCustom(mxml_node_t *parent, void *data,
|
extern mxml_node_t *mxmlNewCustom(mxml_node_t *parent, void *data, mxml_custom_destroy_cb_t destroy);
|
||||||
mxml_custom_destroy_cb_t destroy);
|
|
||||||
extern mxml_node_t *mxmlNewElement(mxml_node_t *parent, const char *name);
|
extern mxml_node_t *mxmlNewElement(mxml_node_t *parent, const char *name);
|
||||||
extern mxml_node_t *mxmlNewInteger(mxml_node_t *parent, int integer);
|
extern mxml_node_t *mxmlNewInteger(mxml_node_t *parent, int integer);
|
||||||
extern mxml_node_t *mxmlNewOpaque(mxml_node_t *parent, const char *opaque);
|
extern mxml_node_t *mxmlNewOpaque(mxml_node_t *parent, const char *opaque);
|
||||||
extern mxml_node_t *mxmlNewOpaquef(mxml_node_t *parent, const char *format, ...)
|
extern mxml_node_t *mxmlNewOpaquef(mxml_node_t *parent, const char *format, ...) MXML_FORMAT(2,3);
|
||||||
# ifdef __GNUC__
|
|
||||||
__attribute__ ((__format__ (__printf__, 2, 3)))
|
|
||||||
# endif /* __GNUC__ */
|
|
||||||
;
|
|
||||||
extern mxml_node_t *mxmlNewReal(mxml_node_t *parent, double real);
|
extern mxml_node_t *mxmlNewReal(mxml_node_t *parent, double real);
|
||||||
extern mxml_node_t *mxmlNewText(mxml_node_t *parent, int whitespace, const char *string);
|
extern mxml_node_t *mxmlNewText(mxml_node_t *parent, int whitespace, const char *string);
|
||||||
extern mxml_node_t *mxmlNewTextf(mxml_node_t *parent, int whitespace, const char *format, ...)
|
extern mxml_node_t *mxmlNewTextf(mxml_node_t *parent, int whitespace, const char *format, ...) MXML_FORMAT(3,4);
|
||||||
# ifdef __GNUC__
|
|
||||||
__attribute__ ((__format__ (__printf__, 3, 4)))
|
|
||||||
# endif /* __GNUC__ */
|
|
||||||
;
|
|
||||||
extern mxml_node_t *mxmlNewXML(const char *version);
|
extern mxml_node_t *mxmlNewXML(const char *version);
|
||||||
extern int mxmlRelease(mxml_node_t *node);
|
extern int mxmlRelease(mxml_node_t *node);
|
||||||
extern void mxmlRemove(mxml_node_t *node);
|
extern void mxmlRemove(mxml_node_t *node);
|
||||||
extern int mxmlRetain(mxml_node_t *node);
|
extern int mxmlRetain(mxml_node_t *node);
|
||||||
extern char *mxmlSaveAllocString(mxml_node_t *node,
|
extern char *mxmlSaveAllocString(mxml_node_t *node, mxml_save_cb_t cb);
|
||||||
mxml_save_cb_t cb);
|
extern int mxmlSaveFd(mxml_node_t *node, int fd, mxml_save_cb_t cb);
|
||||||
extern int mxmlSaveFd(mxml_node_t *node, int fd,
|
extern int mxmlSaveFile(mxml_node_t *node, FILE *fp, mxml_save_cb_t cb);
|
||||||
mxml_save_cb_t cb);
|
extern int mxmlSaveString(mxml_node_t *node, char *buffer, int bufsize, mxml_save_cb_t cb);
|
||||||
extern int mxmlSaveFile(mxml_node_t *node, FILE *fp,
|
extern mxml_node_t *mxmlSAXLoadFd(mxml_node_t *top, int fd, mxml_load_cb_t cb, mxml_sax_cb_t sax, void *sax_data);
|
||||||
mxml_save_cb_t cb);
|
extern mxml_node_t *mxmlSAXLoadFile(mxml_node_t *top, FILE *fp, mxml_load_cb_t cb, mxml_sax_cb_t sax, void *sax_data);
|
||||||
extern int mxmlSaveString(mxml_node_t *node, char *buffer,
|
extern mxml_node_t *mxmlSAXLoadString(mxml_node_t *top, const char *s, mxml_load_cb_t cb, mxml_sax_cb_t sax, void *sax_data);
|
||||||
int bufsize, mxml_save_cb_t cb);
|
|
||||||
extern mxml_node_t *mxmlSAXLoadFd(mxml_node_t *top, int fd,
|
|
||||||
mxml_type_t (*cb)(mxml_node_t *),
|
|
||||||
mxml_sax_cb_t sax, void *sax_data);
|
|
||||||
extern mxml_node_t *mxmlSAXLoadFile(mxml_node_t *top, FILE *fp,
|
|
||||||
mxml_type_t (*cb)(mxml_node_t *),
|
|
||||||
mxml_sax_cb_t sax, void *sax_data);
|
|
||||||
extern mxml_node_t *mxmlSAXLoadString(mxml_node_t *top, const char *s,
|
|
||||||
mxml_type_t (*cb)(mxml_node_t *),
|
|
||||||
mxml_sax_cb_t sax, void *sax_data);
|
|
||||||
extern int mxmlSetCDATA(mxml_node_t *node, const char *data);
|
extern int mxmlSetCDATA(mxml_node_t *node, const char *data);
|
||||||
extern int mxmlSetCustom(mxml_node_t *node, void *data,
|
extern int mxmlSetCustom(mxml_node_t *node, void *data, mxml_custom_destroy_cb_t destroy);
|
||||||
mxml_custom_destroy_cb_t destroy);
|
extern void mxmlSetCustomHandlers(mxml_custom_load_cb_t load, mxml_custom_save_cb_t save);
|
||||||
extern void mxmlSetCustomHandlers(mxml_custom_load_cb_t load,
|
|
||||||
mxml_custom_save_cb_t save);
|
|
||||||
extern int mxmlSetElement(mxml_node_t *node, const char *name);
|
extern int mxmlSetElement(mxml_node_t *node, const char *name);
|
||||||
extern void mxmlSetErrorCallback(mxml_error_cb_t cb);
|
extern void mxmlSetErrorCallback(mxml_error_cb_t cb);
|
||||||
extern int mxmlSetInteger(mxml_node_t *node, int integer);
|
extern int mxmlSetInteger(mxml_node_t *node, int integer);
|
||||||
extern int mxmlSetOpaque(mxml_node_t *node, const char *opaque);
|
extern int mxmlSetOpaque(mxml_node_t *node, const char *opaque);
|
||||||
extern int mxmlSetOpaquef(mxml_node_t *node, const char *format, ...)
|
extern int mxmlSetOpaquef(mxml_node_t *node, const char *format, ...) MXML_FORMAT(2,3);
|
||||||
# ifdef __GNUC__
|
|
||||||
__attribute__ ((__format__ (__printf__, 2, 3)))
|
|
||||||
# endif /* __GNUC__ */
|
|
||||||
;
|
|
||||||
extern int mxmlSetReal(mxml_node_t *node, double real);
|
extern int mxmlSetReal(mxml_node_t *node, double real);
|
||||||
extern int mxmlSetText(mxml_node_t *node, int whitespace,
|
extern int mxmlSetText(mxml_node_t *node, int whitespace, const char *string);
|
||||||
const char *string);
|
extern int mxmlSetTextf(mxml_node_t *node, int whitespace, const char *format, ...) MXML_FORMAT(3,4);
|
||||||
extern int mxmlSetTextf(mxml_node_t *node, int whitespace,
|
|
||||||
const char *format, ...)
|
|
||||||
# ifdef __GNUC__
|
|
||||||
__attribute__ ((__format__ (__printf__, 3, 4)))
|
|
||||||
# endif /* __GNUC__ */
|
|
||||||
;
|
|
||||||
extern int mxmlSetUserData(mxml_node_t *node, void *data);
|
extern int mxmlSetUserData(mxml_node_t *node, void *data);
|
||||||
extern void mxmlSetWrapMargin(int column);
|
extern void mxmlSetWrapMargin(int column);
|
||||||
extern mxml_node_t *mxmlWalkNext(mxml_node_t *node, mxml_node_t *top,
|
extern mxml_node_t *mxmlWalkNext(mxml_node_t *node, mxml_node_t *top, int descend);
|
||||||
int descend);
|
extern mxml_node_t *mxmlWalkPrev(mxml_node_t *node, mxml_node_t *top, int descend);
|
||||||
extern mxml_node_t *mxmlWalkPrev(mxml_node_t *node, mxml_node_t *top,
|
|
||||||
int descend);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Semi-private functions...
|
// Semi-private functions...
|
||||||
*/
|
//
|
||||||
|
|
||||||
extern void mxml_error(const char *format, ...)
|
extern void mxml_error(const char *format, ...) MXML_FORMAT(1,2);
|
||||||
# ifdef __GNUC__
|
|
||||||
__attribute__ ((__format__ (__printf__, 1, 2)))
|
|
||||||
# endif /* __GNUC__ */
|
|
||||||
;
|
|
||||||
extern mxml_type_t mxml_ignore_cb(mxml_node_t *node);
|
extern mxml_type_t mxml_ignore_cb(mxml_node_t *node);
|
||||||
extern mxml_type_t mxml_integer_cb(mxml_node_t *node);
|
extern mxml_type_t mxml_integer_cb(mxml_node_t *node);
|
||||||
extern mxml_type_t mxml_opaque_cb(mxml_node_t *node);
|
extern mxml_type_t mxml_opaque_cb(mxml_node_t *node);
|
||||||
extern mxml_type_t mxml_real_cb(mxml_node_t *node);
|
extern mxml_type_t mxml_real_cb(mxml_node_t *node);
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* C++ support...
|
|
||||||
*/
|
|
||||||
|
|
||||||
# ifdef __cplusplus
|
# ifdef __cplusplus
|
||||||
}
|
}
|
||||||
# endif /* __cplusplus */
|
# endif // __cplusplus
|
||||||
#endif /* !_mxml_h_ */
|
#endif // !MXML_H
|
||||||
|
@ -5,6 +5,6 @@ includedir=@includedir@
|
|||||||
|
|
||||||
Name: Mini-XML
|
Name: Mini-XML
|
||||||
Description: Lightweight XML support library
|
Description: Lightweight XML support library
|
||||||
Version: @VERSION@
|
Version: @MXML_VERSION@
|
||||||
Libs: @PC_LIBS@
|
Libs: @PKGCONFIG_LIBS@
|
||||||
Cflags: @PC_CFLAGS@
|
Cflags: @PKGCONFIG_CFLAGS@
|
||||||
|
480
testmxml.c
480
testmxml.c
@ -1,90 +1,79 @@
|
|||||||
/*
|
//
|
||||||
* Test program for Mini-XML, a small XML file parsing library.
|
// Test program for Mini-XML, a small XML file parsing library.
|
||||||
*
|
//
|
||||||
* Usage:
|
// Usage:
|
||||||
*
|
//
|
||||||
* ./testmxml input.xml [string-output.xml] >stdio-output.xml
|
// ./testmxml input.xml [string-output.xml] >stdio-output.xml
|
||||||
* ./testmxml "<?xml ..." [string-output.xml] >stdio-output.xml
|
// ./testmxml "<?xml ..." [string-output.xml] >stdio-output.xml
|
||||||
*
|
//
|
||||||
* https://www.msweet.org/mxml
|
// https://www.msweet.org/mxml
|
||||||
*
|
//
|
||||||
* Copyright © 2003-2019 by Michael R Sweet.
|
// Copyright © 2003-2024 by Michael R Sweet.
|
||||||
*
|
//
|
||||||
* Licensed under Apache License v2.0. See the file "LICENSE" for more
|
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
||||||
* information.
|
// information.
|
||||||
*/
|
//
|
||||||
|
|
||||||
/*
|
|
||||||
* Include necessary headers...
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "mxml-private.h"
|
#include "mxml-private.h"
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif /* !_WIN32 */
|
#endif // !_WIN32
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#ifndef O_BINARY
|
#ifndef O_BINARY
|
||||||
# define O_BINARY 0
|
# define O_BINARY 0
|
||||||
#endif /* !O_BINARY */
|
#endif // !O_BINARY
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Globals...
|
// Globals...
|
||||||
*/
|
//
|
||||||
|
|
||||||
int event_counts[6];
|
int event_counts[6];
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* Local functions...
|
// Local functions...
|
||||||
*/
|
//
|
||||||
|
|
||||||
void sax_cb(mxml_node_t *node, mxml_sax_event_t event, void *data);
|
void sax_cb(mxml_node_t *node, mxml_sax_event_t event, void *data);
|
||||||
mxml_type_t type_cb(mxml_node_t *node);
|
mxml_type_t type_cb(mxml_node_t *node);
|
||||||
const char *whitespace_cb(mxml_node_t *node, int where);
|
const char *whitespace_cb(mxml_node_t *node, int where);
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'main()' - Main entry for test program.
|
// 'main()' - Main entry for test program.
|
||||||
*/
|
//
|
||||||
|
|
||||||
int /* O - Exit status */
|
int // O - Exit status
|
||||||
main(int argc, /* I - Number of command-line args */
|
main(int argc, // I - Number of command-line args
|
||||||
char *argv[]) /* I - Command-line args */
|
char *argv[]) // I - Command-line args
|
||||||
{
|
{
|
||||||
int i; /* Looping var */
|
int i; // Looping var
|
||||||
FILE *fp; /* File to read */
|
FILE *fp; // File to read
|
||||||
int fd; /* File descriptor */
|
int fd; // File descriptor
|
||||||
mxml_node_t *xml, /* <?xml ...?> node */
|
mxml_node_t *xml, // <?xml ...?> node
|
||||||
*tree, /* Element tree */
|
*tree, // Element tree
|
||||||
*node; /* Node which should be in test.xml */
|
*node; // Node which should be in test.xml
|
||||||
mxml_index_t *ind; /* XML index */
|
mxml_index_t *ind; // XML index
|
||||||
char buffer[16384]; /* Save string */
|
char buffer[16384]; // Save string
|
||||||
static const char *types[] = /* Strings for node types */
|
static const char *types[] = // Strings for node types
|
||||||
{
|
{
|
||||||
"MXML_ELEMENT",
|
"MXML_TYPE_ELEMENT",
|
||||||
"MXML_INTEGER",
|
"MXML_TYPE_INTEGER",
|
||||||
"MXML_OPAQUE",
|
"MXML_TYPE_OPAQUE",
|
||||||
"MXML_REAL",
|
"MXML_TYPE_REAL",
|
||||||
"MXML_TEXT"
|
"MXML_TYPE_TEXT"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
// Check arguments...
|
||||||
* Check arguments...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (argc != 2 && argc != 3)
|
if (argc != 2 && argc != 3)
|
||||||
{
|
{
|
||||||
fputs("Usage: testmxml filename.xml [string-output.xml]\n", stderr);
|
fputs("Usage: testmxml filename.xml [string-output.xml]\n", stderr);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Test the basic functionality...
|
||||||
* Test the basic functionality...
|
|
||||||
*/
|
|
||||||
|
|
||||||
xml = mxmlNewXML("1.0");
|
xml = mxmlNewXML("1.0");
|
||||||
tree = mxmlNewElement(xml, "element");
|
tree = mxmlNewElement(xml, "element");
|
||||||
|
|
||||||
@ -94,19 +83,16 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tree->type != MXML_ELEMENT)
|
if (tree->type != MXML_TYPE_ELEMENT)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "ERROR: Parent has type %s (%d), expected MXML_ELEMENT.\n",
|
fprintf(stderr, "ERROR: Parent has type %s (%d), expected MXML_TYPE_ELEMENT.\n", tree->type < MXML_TYPE_ELEMENT || tree->type > MXML_TYPE_TEXT ? "UNKNOWN" : types[tree->type], tree->type);
|
||||||
tree->type < MXML_ELEMENT || tree->type > MXML_TEXT ?
|
|
||||||
"UNKNOWN" : types[tree->type], tree->type);
|
|
||||||
mxmlDelete(tree);
|
mxmlDelete(tree);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(tree->value.element.name, "element"))
|
if (strcmp(tree->value.element.name, "element"))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "ERROR: Parent value is \"%s\", expected \"element\".\n",
|
fprintf(stderr, "ERROR: Parent value is \"%s\", expected \"element\".\n", tree->value.element.name);
|
||||||
tree->value.element.name);
|
|
||||||
mxmlDelete(tree);
|
mxmlDelete(tree);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
@ -116,18 +102,12 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
mxmlNewReal(tree, 123.4f);
|
mxmlNewReal(tree, 123.4f);
|
||||||
mxmlNewText(tree, 1, "text");
|
mxmlNewText(tree, 1, "text");
|
||||||
|
|
||||||
mxmlLoadString(tree, "<group type='string'>string string string</group>",
|
mxmlLoadString(tree, "<group type='string'>string string string</group>", MXML_NO_CALLBACK);
|
||||||
MXML_NO_CALLBACK);
|
mxmlLoadString(tree, "<group type='integer'>1 2 3</group>", MXML_INTEGER_CALLBACK);
|
||||||
mxmlLoadString(tree, "<group type='integer'>1 2 3</group>",
|
mxmlLoadString(tree, "<group type='real'>1.0 2.0 3.0</group>", MXML_REAL_CALLBACK);
|
||||||
MXML_INTEGER_CALLBACK);
|
mxmlLoadString(tree, "<group>opaque opaque opaque</group>", MXML_OPAQUE_CALLBACK);
|
||||||
mxmlLoadString(tree, "<group type='real'>1.0 2.0 3.0</group>",
|
mxmlLoadString(tree, "<foo><bar><one><two>value<two>value2</two></two></one></bar></foo>", MXML_OPAQUE_CALLBACK);
|
||||||
MXML_REAL_CALLBACK);
|
mxmlNewCDATA(tree, "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n");
|
||||||
mxmlLoadString(tree, "<group>opaque opaque opaque</group>",
|
|
||||||
MXML_OPAQUE_CALLBACK);
|
|
||||||
mxmlLoadString(tree, "<foo><bar><one><two>value<two>value2</two></two></one>"
|
|
||||||
"</bar></foo>", MXML_OPAQUE_CALLBACK);
|
|
||||||
mxmlNewCDATA(tree,
|
|
||||||
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n");
|
|
||||||
mxmlNewCDATA(tree,
|
mxmlNewCDATA(tree,
|
||||||
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n"
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n"
|
||||||
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n"
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n"
|
||||||
@ -152,19 +132,16 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->type != MXML_INTEGER)
|
if (node->type != MXML_TYPE_INTEGER)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "ERROR: First child has type %s (%d), expected MXML_INTEGER.\n",
|
fprintf(stderr, "ERROR: First child has type %s (%d), expected MXML_TYPE_INTEGER.\n", node->type < MXML_TYPE_ELEMENT || node->type > MXML_TYPE_TEXT ? "UNKNOWN" : types[node->type], node->type);
|
||||||
node->type < MXML_ELEMENT || node->type > MXML_TEXT ?
|
|
||||||
"UNKNOWN" : types[node->type], node->type);
|
|
||||||
mxmlDelete(tree);
|
mxmlDelete(tree);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->value.integer != 123)
|
if (node->value.integer != 123)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "ERROR: First child value is %d, expected 123.\n",
|
fprintf(stderr, "ERROR: First child value is %d, expected 123.\n", node->value.integer);
|
||||||
node->value.integer);
|
|
||||||
mxmlDelete(tree);
|
mxmlDelete(tree);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
@ -178,19 +155,16 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->type != MXML_OPAQUE)
|
if (node->type != MXML_TYPE_OPAQUE)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "ERROR: Second child has type %s (%d), expected MXML_OPAQUE.\n",
|
fprintf(stderr, "ERROR: Second child has type %s (%d), expected MXML_TYPE_OPAQUE.\n", node->type < MXML_TYPE_ELEMENT || node->type > MXML_TYPE_TEXT ? "UNKNOWN" : types[node->type], node->type);
|
||||||
node->type < MXML_ELEMENT || node->type > MXML_TEXT ?
|
|
||||||
"UNKNOWN" : types[node->type], node->type);
|
|
||||||
mxmlDelete(tree);
|
mxmlDelete(tree);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!node->value.opaque || strcmp(node->value.opaque, "opaque"))
|
if (!node->value.opaque || strcmp(node->value.opaque, "opaque"))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "ERROR: Second child value is \"%s\", expected \"opaque\".\n",
|
fprintf(stderr, "ERROR: Second child value is \"%s\", expected \"opaque\".\n", node->value.opaque ? node->value.opaque : "(null)");
|
||||||
node->value.opaque ? node->value.opaque : "(null)");
|
|
||||||
mxmlDelete(tree);
|
mxmlDelete(tree);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
@ -204,19 +178,16 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->type != MXML_REAL)
|
if (node->type != MXML_TYPE_REAL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "ERROR: Third child has type %s (%d), expected MXML_REAL.\n",
|
fprintf(stderr, "ERROR: Third child has type %s (%d), expected MXML_TYPE_REAL.\n", node->type < MXML_TYPE_ELEMENT || node->type > MXML_TYPE_TEXT ? "UNKNOWN" : types[node->type], node->type);
|
||||||
node->type < MXML_ELEMENT || node->type > MXML_TEXT ?
|
|
||||||
"UNKNOWN" : types[node->type], node->type);
|
|
||||||
mxmlDelete(tree);
|
mxmlDelete(tree);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->value.real != 123.4f)
|
if (node->value.real != 123.4f)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "ERROR: Third child value is %f, expected 123.4.\n",
|
fprintf(stderr, "ERROR: Third child value is %f, expected 123.4.\n", node->value.real);
|
||||||
node->value.real);
|
|
||||||
mxmlDelete(tree);
|
mxmlDelete(tree);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
@ -230,21 +201,16 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->type != MXML_TEXT)
|
if (node->type != MXML_TYPE_TEXT)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "ERROR: Fourth child has type %s (%d), expected MXML_TEXT.\n",
|
fprintf(stderr, "ERROR: Fourth child has type %s (%d), expected MXML_TYPE_TEXT.\n", node->type < MXML_TYPE_ELEMENT || node->type > MXML_TYPE_TEXT ? "UNKNOWN" : types[node->type], node->type);
|
||||||
node->type < MXML_ELEMENT || node->type > MXML_TEXT ?
|
|
||||||
"UNKNOWN" : types[node->type], node->type);
|
|
||||||
mxmlDelete(tree);
|
mxmlDelete(tree);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!node->value.text.whitespace ||
|
if (!node->value.text.whitespace || !node->value.text.string || strcmp(node->value.text.string, "text"))
|
||||||
!node->value.text.string || strcmp(node->value.text.string, "text"))
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "ERROR: Fourth child value is %d,\"%s\", expected 1,\"text\".\n",
|
fprintf(stderr, "ERROR: Fourth child value is %d,\"%s\", expected 1,\"text\".\n", node->value.text.whitespace, node->value.text.string ? node->value.text.string : "(null)");
|
||||||
node->value.text.whitespace,
|
|
||||||
node->value.text.string ? node->value.text.string : "(null)");
|
|
||||||
mxmlDelete(tree);
|
mxmlDelete(tree);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
@ -260,20 +226,15 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->type != MXML_ELEMENT)
|
if (node->type != MXML_TYPE_ELEMENT)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "ERROR: Group child #%d has type %s (%d), expected MXML_ELEMENT.\n",
|
fprintf(stderr, "ERROR: Group child #%d has type %s (%d), expected MXML_TYPE_ELEMENT.\n", i + 1, node->type < MXML_TYPE_ELEMENT || node->type > MXML_TYPE_TEXT ? "UNKNOWN" : types[node->type], node->type);
|
||||||
i + 1, node->type < MXML_ELEMENT || node->type > MXML_TEXT ?
|
|
||||||
"UNKNOWN" : types[node->type], node->type);
|
|
||||||
mxmlDelete(tree);
|
mxmlDelete(tree);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Test mxmlFindPath...
|
||||||
* Test mxmlFindPath...
|
|
||||||
*/
|
|
||||||
|
|
||||||
node = mxmlFindPath(tree, "*/two");
|
node = mxmlFindPath(tree, "*/two");
|
||||||
if (!node)
|
if (!node)
|
||||||
{
|
{
|
||||||
@ -281,7 +242,7 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
mxmlDelete(tree);
|
mxmlDelete(tree);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
else if (node->type != MXML_OPAQUE || strcmp(node->value.opaque, "value"))
|
else if (node->type != MXML_TYPE_OPAQUE || strcmp(node->value.opaque, "value"))
|
||||||
{
|
{
|
||||||
fputs("ERROR: Bad value for \"*/two\".\n", stderr);
|
fputs("ERROR: Bad value for \"*/two\".\n", stderr);
|
||||||
mxmlDelete(tree);
|
mxmlDelete(tree);
|
||||||
@ -295,7 +256,7 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
mxmlDelete(tree);
|
mxmlDelete(tree);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
else if (node->type != MXML_OPAQUE || strcmp(node->value.opaque, "value"))
|
else if (node->type != MXML_TYPE_OPAQUE || strcmp(node->value.opaque, "value"))
|
||||||
{
|
{
|
||||||
fputs("ERROR: Bad value for \"foo/*/two\".\n", stderr);
|
fputs("ERROR: Bad value for \"foo/*/two\".\n", stderr);
|
||||||
mxmlDelete(tree);
|
mxmlDelete(tree);
|
||||||
@ -309,17 +270,14 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
mxmlDelete(tree);
|
mxmlDelete(tree);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
else if (node->type != MXML_OPAQUE || strcmp(node->value.opaque, "value"))
|
else if (node->type != MXML_TYPE_OPAQUE || strcmp(node->value.opaque, "value"))
|
||||||
{
|
{
|
||||||
fputs("ERROR: Bad value for \"foo/bar/one/two\".\n", stderr);
|
fputs("ERROR: Bad value for \"foo/bar/one/two\".\n", stderr);
|
||||||
mxmlDelete(tree);
|
mxmlDelete(tree);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Test indices...
|
||||||
* Test indices...
|
|
||||||
*/
|
|
||||||
|
|
||||||
ind = mxmlIndexNew(tree, NULL, NULL);
|
ind = mxmlIndexNew(tree, NULL, NULL);
|
||||||
if (!ind)
|
if (!ind)
|
||||||
{
|
{
|
||||||
@ -330,8 +288,7 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
|
|
||||||
if (ind->num_nodes != 13)
|
if (ind->num_nodes != 13)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "ERROR: Index of all nodes contains %d "
|
fprintf(stderr, "ERROR: Index of all nodes contains %d nodes; expected 13.\n", ind->num_nodes);
|
||||||
"nodes; expected 13.\n", ind->num_nodes);
|
|
||||||
mxmlIndexDelete(ind);
|
mxmlIndexDelete(ind);
|
||||||
mxmlDelete(tree);
|
mxmlDelete(tree);
|
||||||
return (1);
|
return (1);
|
||||||
@ -358,8 +315,7 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
|
|
||||||
if (ind->num_nodes != 4)
|
if (ind->num_nodes != 4)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "ERROR: Index of groups contains %d "
|
fprintf(stderr, "ERROR: Index of groups contains %d nodes; expected 4.\n", ind->num_nodes);
|
||||||
"nodes; expected 4.\n", ind->num_nodes);
|
|
||||||
mxmlIndexDelete(ind);
|
mxmlIndexDelete(ind);
|
||||||
mxmlDelete(tree);
|
mxmlDelete(tree);
|
||||||
return (1);
|
return (1);
|
||||||
@ -386,8 +342,7 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
|
|
||||||
if (ind->num_nodes != 3)
|
if (ind->num_nodes != 3)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "ERROR: Index of type attributes contains %d "
|
fprintf(stderr, "ERROR: Index of type attributes contains %d nodes; expected 3.\n", ind->num_nodes);
|
||||||
"nodes; expected 3.\n", ind->num_nodes);
|
|
||||||
mxmlIndexDelete(ind);
|
mxmlIndexDelete(ind);
|
||||||
mxmlDelete(tree);
|
mxmlDelete(tree);
|
||||||
return (1);
|
return (1);
|
||||||
@ -414,8 +369,7 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
|
|
||||||
if (ind->num_nodes != 3)
|
if (ind->num_nodes != 3)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "ERROR: Index of elements and attributes contains %d "
|
fprintf(stderr, "ERROR: Index of elements and attributes contains %d nodes; expected 3.\n", ind->num_nodes);
|
||||||
"nodes; expected 3.\n", ind->num_nodes);
|
|
||||||
mxmlIndexDelete(ind);
|
mxmlIndexDelete(ind);
|
||||||
mxmlDelete(tree);
|
mxmlDelete(tree);
|
||||||
return (1);
|
return (1);
|
||||||
@ -432,18 +386,16 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
|
|
||||||
mxmlIndexDelete(ind);
|
mxmlIndexDelete(ind);
|
||||||
|
|
||||||
/*
|
// Check the mxmlDelete() works properly...
|
||||||
* Check the mxmlDelete() works properly...
|
|
||||||
*/
|
|
||||||
|
|
||||||
for (i = 0; i < 12; i ++)
|
for (i = 0; i < 12; i ++)
|
||||||
{
|
{
|
||||||
if (tree->child)
|
if (tree->child)
|
||||||
|
{
|
||||||
mxmlDelete(tree->child);
|
mxmlDelete(tree->child);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(stderr, "ERROR: Child pointer prematurely NULL on child #%d\n",
|
fprintf(stderr, "ERROR: Child pointer prematurely NULL on child #%d\n", i + 1);
|
||||||
i + 1);
|
|
||||||
mxmlDelete(tree);
|
mxmlDelete(tree);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
@ -463,12 +415,11 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
|
|
||||||
mxmlDelete(xml);
|
mxmlDelete(xml);
|
||||||
|
|
||||||
/*
|
// Open the file/string using the default (MXML_NO_CALLBACK) callback...
|
||||||
* Open the file/string using the default (MXML_NO_CALLBACK) callback...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (argv[1][0] == '<')
|
if (argv[1][0] == '<')
|
||||||
|
{
|
||||||
xml = mxmlLoadString(NULL, argv[1], MXML_NO_CALLBACK);
|
xml = mxmlLoadString(NULL, argv[1], MXML_NO_CALLBACK);
|
||||||
|
}
|
||||||
else if ((fp = fopen(argv[1], "rb")) == NULL)
|
else if ((fp = fopen(argv[1], "rb")) == NULL)
|
||||||
{
|
{
|
||||||
perror(argv[1]);
|
perror(argv[1]);
|
||||||
@ -476,10 +427,7 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
// Read the file...
|
||||||
* Read the file...
|
|
||||||
*/
|
|
||||||
|
|
||||||
xml = mxmlLoadFile(NULL, fp, MXML_NO_CALLBACK);
|
xml = mxmlLoadFile(NULL, fp, MXML_NO_CALLBACK);
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
@ -493,13 +441,9 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
|
|
||||||
if (!strcmp(argv[1], "test.xml"))
|
if (!strcmp(argv[1], "test.xml"))
|
||||||
{
|
{
|
||||||
const char *text; /* Text value */
|
const char *text; // Text value
|
||||||
|
|
||||||
/*
|
|
||||||
* Verify that mxmlFindElement() and indirectly mxmlWalkNext() work
|
|
||||||
* properly...
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
// Verify that mxmlFindElement() and indirectly mxmlWalkNext() work properly...
|
||||||
if ((node = mxmlFindPath(xml, "group/option/keyword")) == NULL)
|
if ((node = mxmlFindPath(xml, "group/option/keyword")) == NULL)
|
||||||
{
|
{
|
||||||
fputs("Unable to find group/option/keyword element in XML tree.\n", stderr);
|
fputs("Unable to find group/option/keyword element in XML tree.\n", stderr);
|
||||||
@ -507,7 +451,7 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->type != MXML_TEXT)
|
if (node->type != MXML_TYPE_TEXT)
|
||||||
{
|
{
|
||||||
fputs("No child node of group/option/keyword.\n", stderr);
|
fputs("No child node of group/option/keyword.\n", stderr);
|
||||||
mxmlSaveFile(xml, stderr, MXML_NO_CALLBACK);
|
mxmlSaveFile(xml, stderr, MXML_NO_CALLBACK);
|
||||||
@ -525,12 +469,11 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
|
|
||||||
mxmlDelete(xml);
|
mxmlDelete(xml);
|
||||||
|
|
||||||
/*
|
// Open the file...
|
||||||
* Open the file...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (argv[1][0] == '<')
|
if (argv[1][0] == '<')
|
||||||
|
{
|
||||||
xml = mxmlLoadString(NULL, argv[1], type_cb);
|
xml = mxmlLoadString(NULL, argv[1], type_cb);
|
||||||
|
}
|
||||||
else if ((fp = fopen(argv[1], "rb")) == NULL)
|
else if ((fp = fopen(argv[1], "rb")) == NULL)
|
||||||
{
|
{
|
||||||
perror(argv[1]);
|
perror(argv[1]);
|
||||||
@ -538,10 +481,7 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
// Read the file...
|
||||||
* Read the file...
|
|
||||||
*/
|
|
||||||
|
|
||||||
xml = mxmlLoadFile(NULL, fp, type_cb);
|
xml = mxmlLoadFile(NULL, fp, type_cb);
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
@ -555,13 +495,8 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
|
|
||||||
if (!strcmp(argv[1], "test.xml"))
|
if (!strcmp(argv[1], "test.xml"))
|
||||||
{
|
{
|
||||||
/*
|
// Verify that mxmlFindElement() and indirectly mxmlWalkNext() work properly...
|
||||||
* Verify that mxmlFindElement() and indirectly mxmlWalkNext() work
|
if ((node = mxmlFindElement(xml, xml, "choice", NULL, NULL, MXML_DESCEND)) == NULL)
|
||||||
* properly...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ((node = mxmlFindElement(xml, xml, "choice", NULL, NULL,
|
|
||||||
MXML_DESCEND)) == NULL)
|
|
||||||
{
|
{
|
||||||
fputs("Unable to find first <choice> element in XML tree.\n", stderr);
|
fputs("Unable to find first <choice> element in XML tree.\n", stderr);
|
||||||
mxmlDelete(tree);
|
mxmlDelete(tree);
|
||||||
@ -576,16 +511,10 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Print the XML tree...
|
||||||
* Print the XML tree...
|
|
||||||
*/
|
|
||||||
|
|
||||||
mxmlSaveFile(xml, stdout, whitespace_cb);
|
mxmlSaveFile(xml, stdout, whitespace_cb);
|
||||||
|
|
||||||
/*
|
// Save the XML tree to a string and print it...
|
||||||
* Save the XML tree to a string and print it...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (mxmlSaveString(xml, buffer, sizeof(buffer), whitespace_cb) > 0)
|
if (mxmlSaveString(xml, buffer, sizeof(buffer), whitespace_cb) > 0)
|
||||||
{
|
{
|
||||||
if (argc == 3)
|
if (argc == 3)
|
||||||
@ -596,40 +525,25 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Delete the tree...
|
||||||
* Delete the tree...
|
|
||||||
*/
|
|
||||||
|
|
||||||
mxmlDelete(xml);
|
mxmlDelete(xml);
|
||||||
|
|
||||||
/*
|
// Read from/write to file descriptors...
|
||||||
* Read from/write to file descriptors...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (argv[1][0] != '<')
|
if (argv[1][0] != '<')
|
||||||
{
|
{
|
||||||
/*
|
// Open the file again...
|
||||||
* Open the file again...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ((fd = open(argv[1], O_RDONLY | O_BINARY)) < 0)
|
if ((fd = open(argv[1], O_RDONLY | O_BINARY)) < 0)
|
||||||
{
|
{
|
||||||
perror(argv[1]);
|
perror(argv[1]);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Read the file...
|
||||||
* Read the file...
|
|
||||||
*/
|
|
||||||
|
|
||||||
xml = mxmlLoadFd(NULL, fd, type_cb);
|
xml = mxmlLoadFd(NULL, fd, type_cb);
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
/*
|
// Create filename.xmlfd...
|
||||||
* Create filename.xmlfd...
|
|
||||||
*/
|
|
||||||
|
|
||||||
snprintf(buffer, sizeof(buffer), "%sfd", argv[1]);
|
snprintf(buffer, sizeof(buffer), "%sfd", argv[1]);
|
||||||
|
|
||||||
if ((fd = open(buffer, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666)) < 0)
|
if ((fd = open(buffer, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666)) < 0)
|
||||||
@ -639,29 +553,22 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Write the file...
|
||||||
* Write the file...
|
|
||||||
*/
|
|
||||||
|
|
||||||
mxmlSaveFd(xml, fd, whitespace_cb);
|
mxmlSaveFd(xml, fd, whitespace_cb);
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
/*
|
// Delete the tree...
|
||||||
* Delete the tree...
|
|
||||||
*/
|
|
||||||
|
|
||||||
mxmlDelete(xml);
|
mxmlDelete(xml);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Test SAX methods...
|
||||||
* Test SAX methods...
|
|
||||||
*/
|
|
||||||
|
|
||||||
memset(event_counts, 0, sizeof(event_counts));
|
memset(event_counts, 0, sizeof(event_counts));
|
||||||
|
|
||||||
if (argv[1][0] == '<')
|
if (argv[1][0] == '<')
|
||||||
|
{
|
||||||
mxmlRelease(mxmlSAXLoadString(NULL, argv[1], type_cb, sax_cb, NULL));
|
mxmlRelease(mxmlSAXLoadString(NULL, argv[1], type_cb, sax_cb, NULL));
|
||||||
|
}
|
||||||
else if ((fp = fopen(argv[1], "rb")) == NULL)
|
else if ((fp = fopen(argv[1], "rb")) == NULL)
|
||||||
{
|
{
|
||||||
perror(argv[1]);
|
perror(argv[1]);
|
||||||
@ -669,10 +576,7 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
// Read the file...
|
||||||
* Read the file...
|
|
||||||
*/
|
|
||||||
|
|
||||||
mxmlRelease(mxmlSAXLoadFile(NULL, fp, type_cb, sax_cb, NULL));
|
mxmlRelease(mxmlSAXLoadFile(NULL, fp, type_cb, sax_cb, NULL));
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
@ -680,56 +584,48 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
|
|
||||||
if (!strcmp(argv[1], "test.xml"))
|
if (!strcmp(argv[1], "test.xml"))
|
||||||
{
|
{
|
||||||
if (event_counts[MXML_SAX_CDATA] != 1)
|
if (event_counts[MXML_SAX_EVENT_CDATA] != 1)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "MXML_SAX_CDATA seen %d times, expected 1 times.\n",
|
fprintf(stderr, "MXML_SAX_EVENT_CDATA seen %d times, expected 1 times.\n", event_counts[MXML_SAX_EVENT_CDATA]);
|
||||||
event_counts[MXML_SAX_CDATA]);
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event_counts[MXML_SAX_COMMENT] != 1)
|
if (event_counts[MXML_SAX_EVENT_COMMENT] != 1)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "MXML_SAX_COMMENT seen %d times, expected 1 times.\n",
|
fprintf(stderr, "MXML_SAX_EVENT_COMMENT seen %d times, expected 1 times.\n", event_counts[MXML_SAX_EVENT_COMMENT]);
|
||||||
event_counts[MXML_SAX_COMMENT]);
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event_counts[MXML_SAX_DATA] != 61)
|
if (event_counts[MXML_SAX_EVENT_DATA] != 61)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "MXML_SAX_DATA seen %d times, expected 61 times.\n",
|
fprintf(stderr, "MXML_SAX_EVENT_DATA seen %d times, expected 61 times.\n", event_counts[MXML_SAX_EVENT_DATA]);
|
||||||
event_counts[MXML_SAX_DATA]);
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event_counts[MXML_SAX_DIRECTIVE] != 1)
|
if (event_counts[MXML_SAX_EVENT_DIRECTIVE] != 1)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "MXML_SAX_DIRECTIVE seen %d times, expected 1 times.\n",
|
fprintf(stderr, "MXML_SAX_EVENT_DIRECTIVE seen %d times, expected 1 times.\n", event_counts[MXML_SAX_EVENT_DIRECTIVE]);
|
||||||
event_counts[MXML_SAX_DIRECTIVE]);
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event_counts[MXML_SAX_ELEMENT_CLOSE] != 20)
|
if (event_counts[MXML_SAX_EVENT_ELEMENT_CLOSE] != 20)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "MXML_SAX_ELEMENT_CLOSE seen %d times, expected 20 times.\n",
|
fprintf(stderr, "MXML_SAX_EVENT_ELEMENT_CLOSE seen %d times, expected 20 times.\n", event_counts[MXML_SAX_EVENT_ELEMENT_CLOSE]);
|
||||||
event_counts[MXML_SAX_ELEMENT_CLOSE]);
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event_counts[MXML_SAX_ELEMENT_OPEN] != 20)
|
if (event_counts[MXML_SAX_EVENT_ELEMENT_OPEN] != 20)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "MXML_SAX_ELEMENT_OPEN seen %d times, expected 20 times.\n",
|
fprintf(stderr, "MXML_SAX_EVENT_ELEMENT_OPEN seen %d times, expected 20 times.\n", event_counts[MXML_SAX_EVENT_ELEMENT_OPEN]);
|
||||||
event_counts[MXML_SAX_ELEMENT_OPEN]);
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
/*
|
// Debug hooks...
|
||||||
* Debug hooks...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (getenv("TEST_DELAY") != NULL)
|
if (getenv("TEST_DELAY") != NULL)
|
||||||
sleep(atoi(getenv("TEST_DELAY")));
|
sleep(atoi(getenv("TEST_DELAY")));
|
||||||
|
|
||||||
# ifdef __APPLE__
|
# ifdef __APPLE__
|
||||||
if (getenv("TEST_LEAKS") != NULL)
|
if (getenv("TEST_LEAKS") != NULL)
|
||||||
{
|
{
|
||||||
@ -739,43 +635,37 @@ main(int argc, /* I - Number of command-line args */
|
|||||||
if (system(command))
|
if (system(command))
|
||||||
puts("Unable to check for leaks.");
|
puts("Unable to check for leaks.");
|
||||||
}
|
}
|
||||||
# endif /* __APPLE__ */
|
# endif // __APPLE__
|
||||||
#endif /* !_WIN32 */
|
#endif // !_WIN32
|
||||||
|
|
||||||
/*
|
|
||||||
* Return...
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
// Return...
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'sax_cb()' - Process nodes via SAX.
|
// 'sax_cb()' - Process nodes via SAX.
|
||||||
*/
|
//
|
||||||
|
|
||||||
void
|
void
|
||||||
sax_cb(mxml_node_t *node, /* I - Current node */
|
sax_cb(mxml_node_t *node, // I - Current node
|
||||||
mxml_sax_event_t event, /* I - SAX event */
|
mxml_sax_event_t event, // I - SAX event
|
||||||
void *data) /* I - SAX user data */
|
void *data) // I - SAX user data
|
||||||
{
|
{
|
||||||
static const char * const events[] = /* Events */
|
static const char * const events[] = // Events
|
||||||
{
|
{
|
||||||
"MXML_SAX_CDATA", /* CDATA node */
|
"MXML_SAX_EVENT_CDATA", // CDATA node
|
||||||
"MXML_SAX_COMMENT", /* Comment node */
|
"MXML_SAX_EVENT_COMMENT", // Comment node
|
||||||
"MXML_SAX_DATA", /* Data node */
|
"MXML_SAX_EVENT_DATA", // Data node
|
||||||
"MXML_SAX_DIRECTIVE", /* Processing directive node */
|
"MXML_SAX_EVENT_DIRECTIVE", // Processing directive node
|
||||||
"MXML_SAX_ELEMENT_CLOSE", /* Element closed */
|
"MXML_SAX_EVENT_ELEMENT_CLOSE", // Element closed
|
||||||
"MXML_SAX_ELEMENT_OPEN" /* Element opened */
|
"MXML_SAX_EVENT_ELEMENT_OPEN" // Element opened
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
(void)data;
|
(void)data;
|
||||||
|
|
||||||
/*
|
// This SAX callback just counts the different events.
|
||||||
* This SAX callback just counts the different events.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!node)
|
if (!node)
|
||||||
fprintf(stderr, "ERROR: SAX callback for event %s has NULL node.\n", events[event]);
|
fprintf(stderr, "ERROR: SAX callback for event %s has NULL node.\n", events[event]);
|
||||||
|
|
||||||
@ -783,83 +673,65 @@ sax_cb(mxml_node_t *node, /* I - Current node */
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'type_cb()' - XML data type callback for mxmlLoadFile()...
|
// 'type_cb()' - XML data type callback for mxmlLoadFile()...
|
||||||
*/
|
//
|
||||||
|
|
||||||
mxml_type_t /* O - Data type */
|
mxml_type_t // O - Data type
|
||||||
type_cb(mxml_node_t *node) /* I - Element node */
|
type_cb(mxml_node_t *node) // I - Element node
|
||||||
{
|
{
|
||||||
const char *type; /* Type string */
|
const char *type; // Type string
|
||||||
|
|
||||||
|
|
||||||
/*
|
// You can lookup attributes and/or use the element name, hierarchy, etc...
|
||||||
* You can lookup attributes and/or use the element name, hierarchy, etc...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ((type = mxmlElementGetAttr(node, "type")) == NULL)
|
if ((type = mxmlElementGetAttr(node, "type")) == NULL)
|
||||||
type = node->value.element.name;
|
type = node->value.element.name;
|
||||||
|
|
||||||
if (!strcmp(type, "integer"))
|
if (!strcmp(type, "integer"))
|
||||||
return (MXML_INTEGER);
|
return (MXML_TYPE_INTEGER);
|
||||||
else if (!strcmp(type, "opaque") || !strcmp(type, "pre"))
|
else if (!strcmp(type, "opaque") || !strcmp(type, "pre"))
|
||||||
return (MXML_OPAQUE);
|
return (MXML_TYPE_OPAQUE);
|
||||||
else if (!strcmp(type, "real"))
|
else if (!strcmp(type, "real"))
|
||||||
return (MXML_REAL);
|
return (MXML_TYPE_REAL);
|
||||||
else
|
else
|
||||||
return (MXML_TEXT);
|
return (MXML_TYPE_TEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//
|
||||||
* 'whitespace_cb()' - Let the mxmlSaveFile() function know when to insert
|
// 'whitespace_cb()' - Let the mxmlSaveFile() function know when to insert
|
||||||
* newlines and tabs...
|
// newlines and tabs...
|
||||||
*/
|
//
|
||||||
|
|
||||||
const char * /* O - Whitespace string or NULL */
|
const char * // O - Whitespace string or NULL
|
||||||
whitespace_cb(mxml_node_t *node, /* I - Element node */
|
whitespace_cb(mxml_node_t *node, // I - Element node
|
||||||
int where) /* I - Open or close tag? */
|
int where) // I - Open or close tag?
|
||||||
{
|
{
|
||||||
mxml_node_t *parent; /* Parent node */
|
mxml_node_t *parent; // Parent node
|
||||||
int level; /* Indentation level */
|
int level; // Indentation level
|
||||||
const char *name; /* Name of element */
|
const char *name; // Name of element
|
||||||
static const char *tabs = "\t\t\t\t\t\t\t\t";
|
static const char *tabs = "\t\t\t\t\t\t\t\t";
|
||||||
/* Tabs for indentation */
|
// Tabs for indentation
|
||||||
|
|
||||||
|
|
||||||
/*
|
// We can conditionally break to a new line before or after any element.
|
||||||
* We can conditionally break to a new line before or after any element.
|
// These are just common HTML elements...
|
||||||
* These are just common HTML elements...
|
|
||||||
*/
|
|
||||||
|
|
||||||
name = node->value.element.name;
|
name = node->value.element.name;
|
||||||
|
|
||||||
if (!strcmp(name, "html") || !strcmp(name, "head") || !strcmp(name, "body") ||
|
if (!strcmp(name, "html") || !strcmp(name, "head") || !strcmp(name, "body") || !strcmp(name, "pre") || !strcmp(name, "p") || !strcmp(name, "h1") || !strcmp(name, "h2") || !strcmp(name, "h3") || !strcmp(name, "h4") || !strcmp(name, "h5") || !strcmp(name, "h6"))
|
||||||
!strcmp(name, "pre") || !strcmp(name, "p") ||
|
|
||||||
!strcmp(name, "h1") || !strcmp(name, "h2") || !strcmp(name, "h3") ||
|
|
||||||
!strcmp(name, "h4") || !strcmp(name, "h5") || !strcmp(name, "h6"))
|
|
||||||
{
|
{
|
||||||
/*
|
// Newlines before open and after close...
|
||||||
* Newlines before open and after close...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (where == MXML_WS_BEFORE_OPEN || where == MXML_WS_AFTER_CLOSE)
|
if (where == MXML_WS_BEFORE_OPEN || where == MXML_WS_AFTER_CLOSE)
|
||||||
return ("\n");
|
return ("\n");
|
||||||
}
|
}
|
||||||
else if (!strcmp(name, "dl") || !strcmp(name, "ol") || !strcmp(name, "ul"))
|
else if (!strcmp(name, "dl") || !strcmp(name, "ol") || !strcmp(name, "ul"))
|
||||||
{
|
{
|
||||||
/*
|
// Put a newline before and after list elements...
|
||||||
* Put a newline before and after list elements...
|
|
||||||
*/
|
|
||||||
|
|
||||||
return ("\n");
|
return ("\n");
|
||||||
}
|
}
|
||||||
else if (!strcmp(name, "dd") || !strcmp(name, "dt") || !strcmp(name, "li"))
|
else if (!strcmp(name, "dd") || !strcmp(name, "dt") || !strcmp(name, "li"))
|
||||||
{
|
{
|
||||||
/*
|
// Put a tab before <li>'s, <dd>'s, and <dt>'s, and a newline after them...
|
||||||
* Put a tab before <li>'s, <dd>'s, and <dt>'s, and a newline after them...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (where == MXML_WS_BEFORE_OPEN)
|
if (where == MXML_WS_BEFORE_OPEN)
|
||||||
return ("\t");
|
return ("\t");
|
||||||
else if (where == MXML_WS_AFTER_CLOSE)
|
else if (where == MXML_WS_AFTER_CLOSE)
|
||||||
@ -872,13 +744,9 @@ whitespace_cb(mxml_node_t *node, /* I - Element node */
|
|||||||
else
|
else
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
else if (where == MXML_WS_BEFORE_OPEN ||
|
else if (where == MXML_WS_BEFORE_OPEN || ((!strcmp(name, "choice") || !strcmp(name, "option")) && where == MXML_WS_BEFORE_CLOSE))
|
||||||
((!strcmp(name, "choice") || !strcmp(name, "option")) &&
|
|
||||||
where == MXML_WS_BEFORE_CLOSE))
|
|
||||||
{
|
{
|
||||||
for (level = -1, parent = node->parent;
|
for (level = -1, parent = node->parent; parent; level ++, parent = parent->parent);
|
||||||
parent;
|
|
||||||
level ++, parent = parent->parent);
|
|
||||||
|
|
||||||
if (level > 8)
|
if (level > 8)
|
||||||
level = 8;
|
level = 8;
|
||||||
@ -887,17 +755,11 @@ whitespace_cb(mxml_node_t *node, /* I - Element node */
|
|||||||
|
|
||||||
return (tabs + 8 - level);
|
return (tabs + 8 - level);
|
||||||
}
|
}
|
||||||
else if (where == MXML_WS_AFTER_CLOSE ||
|
else if (where == MXML_WS_AFTER_CLOSE || ((!strcmp(name, "group") || !strcmp(name, "option") || !strcmp(name, "choice")) && where == MXML_WS_AFTER_OPEN))
|
||||||
((!strcmp(name, "group") || !strcmp(name, "option") ||
|
|
||||||
!strcmp(name, "choice")) &&
|
|
||||||
where == MXML_WS_AFTER_OPEN))
|
|
||||||
return ("\n");
|
return ("\n");
|
||||||
else if (where == MXML_WS_AFTER_OPEN && !node->child)
|
else if (where == MXML_WS_AFTER_OPEN && !node->child)
|
||||||
return ("\n");
|
return ("\n");
|
||||||
|
|
||||||
/*
|
// Return NULL for no added whitespace...
|
||||||
* Return NULL for no added whitespace...
|
|
||||||
*/
|
|
||||||
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user