diff --git a/Makefile.in b/Makefile.in index 5df074e..e2b87f0 100644 --- a/Makefile.in +++ b/Makefile.in @@ -3,63 +3,132 @@ # # 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 # information. # # -# Compiler tools definitions... +# This is a POSIX makefile +# + +.POSIX: + + +# +# Mini-XML version... +# + +MXML_VERSION = @MXML_VERSION@ + + +# +# Programs... # AR = @AR@ -ARFLAGS = @ARFLAGS@ -ARCHFLAGS = @ARCHFLAGS@ CC = @CC@ -CFLAGS = $(OPTIM) $(ARCHFLAGS) @CFLAGS@ $(CPPFLAGS) $(WARNINGS) -CP = @CP@ -CPPFLAGS = @CPPFLAGS@ DSO = @DSO@ -DSOFLAGS = @DSOFLAGS@ -LDFLAGS = $(OPTIM) $(ARCHFLAGS) @LDFLAGS@ INSTALL = @INSTALL@ -LIBMXML = @LIBMXML@ -LIBS = @LIBS@ -LN = @LN@ -s -MKDIR = @MKDIR@ -OPTIM = @OPTIM@ +LN = @LN@ -sf +MKDIR = @MKDIR@ -p RANLIB = @RANLIB@ RM = @RM@ -f +RMDIR = @RMDIR@ 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@ # -# 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@ +datadir = @datadir@ datarootdir = @datarootdir@ +exec_prefix = @exec_prefix@ includedir = @includedir@ +infodir = @infodir@ libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ mandir = @mandir@ -docdir = @docdir@ -BUILDROOT = $(DSTROOT) - - -# -# Install commands... -# +oldincludedir = @oldincludedir@ +prefix = @prefix@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +top_srcdir = @top_srcdir@ -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 +BUILDROOT = $(DSTROOT)$(DESTDIR) # @@ -81,7 +150,7 @@ DOCFILES = doc/mxml.epub doc/mxml.html doc/mxml-cover.png \ CHANGES.md LICENSE NOTICE README.md 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 -LIBOBJS = $(PUBLIBOBJS) mxml-private.o mxml-string.o +LIBOBJS = $(PUBLIBOBJS) mxml-private.o OBJS = testmxml.o $(LIBOBJS) ALLTARGETS = $(LIBMXML) testmxml CROSSTARGETS = $(LIBMXML) @@ -102,13 +171,12 @@ all: $(TARGETS) clean: echo Cleaning build files... $(RM) $(OBJS) $(ALLTARGETS) - $(RM) mxml1.dll - $(RM) mxml1.lib + $(RM) mxml2.dll + $(RM) mxml2.lib $(RM) libmxml.a $(RM) libmxml.so - $(RM) libmxml.so.1 - $(RM) libmxml.so.1.6 - $(RM) libmxml.1.dylib + $(RM) libmxml.so.2 + $(RM) libmxml.2.dylib $(RM) libmxml.dylib @@ -132,7 +200,7 @@ distclean: clean # Install everything... # -install: $(TARGETS) install-$(LIBMXML) install-libmxml.a +install: $(TARGETS) install-$(LIBMXML) @INSTALL_STATIC@ echo Installing documentation in $(BUILDROOT)$(docdir)... $(INSTALL_DIR) $(BUILDROOT)$(docdir) for file in $(DOCFILES); do \ @@ -154,29 +222,27 @@ install-libmxml.a: libmxml.a $(INSTALL_LIB) libmxml.a $(BUILDROOT)$(libdir) $(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)... $(INSTALL_DIR) $(BUILDROOT)$(libdir) - $(INSTALL_LIB) libmxml.so.1.6 $(BUILDROOT)$(libdir) + $(INSTALL_LIB) libmxml.so.2 $(BUILDROOT)$(libdir) $(RM) $(BUILDROOT)$(libdir)/libmxml.so - $(LN) libmxml.so.1.6 $(BUILDROOT)$(libdir)/libmxml.so - $(RM) $(BUILDROOT)$(libdir)/libmxml.so.1 - $(LN) libmxml.so.1.6 $(BUILDROOT)$(libdir)/libmxml.so.1 + $(LN) libmxml.so.2 $(BUILDROOT)$(libdir)/libmxml.so $(LDCONFIG) -install-libmxml.1.dylib: libmxml.1.dylib +install-libmxml.2.dylib: libmxml.2.dylib echo Installing libmxml.dylib to $(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 - $(LN) libmxml.1.dylib $(BUILDROOT)$(libdir)/libmxml.dylib + $(LN) libmxml.2.dylib $(BUILDROOT)$(libdir)/libmxml.dylib # # Uninstall everything... # -uninstall: uninstall-$(LIBMXML) uninstall-libmxml.a +uninstall: uninstall-$(LIBMXML) @UNINSTALL_STATIC@ echo Uninstalling documentation from $(BUILDROOT)$(docdir)... $(RM) -r $(BUILDROOT)$(docdir) echo Uninstalling headers from $(BUILDROOT)$(includedir)... @@ -190,17 +256,16 @@ uninstall-libmxml.a: echo Uninstalling libmxml.a from $(BUILDROOT)$(libdir)... $(RM) $(BUILDROOT)$(libdir)/libmxml.a -uninstall-libmxml.so.1.6: +uninstall-libmxml.so.2: echo Uninstalling libmxml.so from $(BUILDROOT)$(libdir)... $(RM) $(BUILDROOT)$(libdir)/libmxml.so - $(RM) $(BUILDROOT)$(libdir)/libmxml.so.1 - $(RM) $(BUILDROOT)$(libdir)/libmxml.so.1.6 + $(RM) $(BUILDROOT)$(libdir)/libmxml.so.2 $(LDCONFIG) -uninstall-libmxml.1.dylib: +uninstall-libmxml.2.dylib: echo Uninstalling libmxml.dylib from $(BUILDROOT)$(libdir)... $(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) $(RANLIB) $@ -$(LIBOBJS): mxml.h -mxml-entity.o mxml-file.o mxml-private.o: mxml-private.h +$(LIBOBJS): mxml.h mxml-private.h # -# mxml1.dll +# libmxml2.dll # -mxml1.dll: $(LIBOBJS) +libmxml2.dll: $(LIBOBJS) 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 $@... - $(DSO) $(DSOFLAGS) $(LDFLAGS) -o libmxml.so.1.6 $(LIBOBJS) $(LIBS) - $(RM) libmxml.so libmxml.so.1 - $(LN) libmxml.so.1.6 libmxml.so - $(LN) libmxml.so.1.6 libmxml.so.1 + $(DSO) $(DSOFLAGS) -o libmxml.so.2 $(LIBOBJS) $(LIBS) + $(RM) libmxml.so + $(LN) libmxml.so.2 libmxml.so # -# libmxml.1.dylib +# libmxml.2.dylib # -libmxml.1.dylib: $(LIBOBJS) +libmxml.2.dylib: $(LIBOBJS) echo Creating $@... - $(DSO) $(DSOFLAGS) $(LDFLAGS) -o libmxml.1.dylib \ + $(DSO) $(DSOFLAGS) -o libmxml.2.dylib \ -install_name $(libdir)/libmxml.dylib \ - -current_version 1.6.0 \ - -compatibility_version 1.0.0 \ + -current_version 2.0.0 \ + -compatibility_version 2.0.0 \ $(LIBOBJS) $(LIBS) $(RM) libmxml.dylib - $(LN) libmxml.1.dylib libmxml.dylib + $(LN) libmxml.2.dylib libmxml.dylib # diff --git a/NOTICE b/NOTICE index e788dab..32928e8 100644 --- a/NOTICE +++ b/NOTICE @@ -1,6 +1,6 @@ Mini-XML -Copyright © 2003-2022 by Michael R Sweet +Copyright © 2003-2024 by Michael R Sweet (Optional) Exceptions to the Apache 2.0 License: diff --git a/README.md b/README.md index bb62ce8..a0ef367 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,12 @@ Mini-XML - Tiny XML Parsing Library ![Apache 2.0](https://img.shields.io/github/license/michaelrsweet/mxml) ![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) -[![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 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 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 ----------------- @@ -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. -## Installing Mini-XML +Installing Mini-XML +------------------- The `install` target will install Mini-XML in the lib and include directories: - make install + sudo make install Once you have installed it, use the `-lmxml` option to link your application against it. @@ -199,7 +200,7 @@ current version of this software, documentation, and Github issue tracking page. 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 *optional* exception to allow linking against GPL2/LGPL2-only software. See the diff --git a/config.guess b/config.guess index 1817bdc..cdfc439 100755 --- a/config.guess +++ b/config.guess @@ -1,10 +1,10 @@ #! /bin/sh # 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 -timestamp='2022-05-25' +timestamp='2023-08-22' # 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 @@ -47,7 +47,7 @@ me=`echo "$0" | sed -e 's,.*/,,'` usage="\ 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: -h, --help print this help, then exit @@ -60,13 +60,13 @@ version="\ GNU config.guess ($timestamp) 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 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" -Try \`$me --help' for more information." +Try '$me --help' for more information." # Parse command line while test $# -gt 0 ; do @@ -102,8 +102,8 @@ GUESS= # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. +# Historically, 'CC_FOR_BUILD' used to be named 'HOST_CC'. We still +# use 'HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. @@ -155,6 +155,9 @@ Linux|GNU|GNU/*) set_cc_for_build cat <<-EOF > "$dummy.c" + #if defined(__ANDROID__) + LIBC=android + #else #include #if defined(__UCLIBC__) LIBC=uclibc @@ -169,6 +172,7 @@ Linux|GNU|GNU/*) LIBC=musl #endif #endif + #endif EOF cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` eval "$cc_set_libc" @@ -459,7 +463,7 @@ case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in UNAME_RELEASE=`uname -v` ;; 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/-/_/'` GUESS=sparc-sun-sunos$SUN_REL ;; @@ -904,7 +908,7 @@ EOF fi ;; *:FreeBSD:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` + UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in amd64) UNAME_PROCESSOR=x86_64 ;; @@ -966,11 +970,37 @@ EOF GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` 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:*:*) GUESS=$UNAME_MACHINE-unknown-minix ;; 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:*:*) UNAME_MACHINE=aarch64_be @@ -1036,7 +1066,16 @@ EOF k1om:Linux:*:*) 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 ;; m32r*:Linux:*:*) @@ -1191,7 +1230,7 @@ EOF GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION ;; 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. GUESS=$UNAME_MACHINE-pc-os2-emx ;; @@ -1332,7 +1371,7 @@ EOF GUESS=ns32k-sni-sysv fi ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + PENTIUM:*:4.0*:*) # Unisys 'ClearPath HMP IX 4000' SVR4/MP effort # says GUESS=i586-unisys-sysv4 ;; diff --git a/config.h.in b/config.h.in index f9be47f..1f638a7 100644 --- a/config.h.in +++ b/config.h.in @@ -1,99 +1,49 @@ -/* - * Configuration file for Mini-XML, a small XML file parsing library. - * - * https://www.msweet.org/mxml - * - * Copyright © 2003-2020 by Michael R Sweet. - * - * Licensed under Apache License v2.0. See the file "LICENSE" for more - * information. - */ +// +// Configuration file for Mini-XML, a small XML file parsing library. +// +// https://www.msweet.org/mxml +// +// Copyright © 2003-2024 by Michael R Sweet. +// +// Licensed under Apache License v2.0. See the file "LICENSE" for more +// information. +// -/* - * Include necessary headers... - */ +#ifndef MXML_CONFIG_H +# define MXML_CONFIG_H +# include +# include +# include +# include +# include -#include -#include -#include -#include -#include +// +// 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 +// +// Have ? +// -/* - * Do we have the *printf() functions? - */ +# undef HAVE_PTHREAD_H -#undef HAVE_SNPRINTF -#undef HAVE_VASPRINTF -#undef HAVE_VSNPRINTF - -/* - * 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 */ +#endif // !MXML_CONFIG_H diff --git a/config.sub b/config.sub index dba16e8..defe52c 100755 --- a/config.sub +++ b/config.sub @@ -1,10 +1,10 @@ #! /bin/sh # 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 -timestamp='2022-01-03' +timestamp='2023-09-19' # 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 @@ -76,13 +76,13 @@ Report bugs and patches to ." version="\ 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 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" -Try \`$me --help' for more information." +Try '$me --help' for more information." # Parse command line while test $# -gt 0 ; do @@ -130,7 +130,7 @@ IFS=$saved_IFS # Separate into logical components for further validation case $1 in *-*-*-*-*) - echo Invalid configuration \`"$1"\': more than four components >&2 + echo "Invalid configuration '$1': more than four components" >&2 exit 1 ;; *-*-*-*) @@ -145,7 +145,8 @@ case $1 in nto-qnx* | linux-* | uclinux-uclibc* \ | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ - | storm-chaos* | os2-emx* | rtmk-nova*) + | storm-chaos* | os2-emx* | rtmk-nova* | managarm-* \ + | windows-* ) basic_machine=$field1 basic_os=$maybe_os ;; @@ -943,7 +944,7 @@ $basic_machine EOF IFS=$saved_IFS ;; - # We use `pc' rather than `unknown' + # We use 'pc' rather than 'unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) @@ -1075,7 +1076,7 @@ case $cpu-$vendor in pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) cpu=i586 ;; - pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*) + pentiumpro-* | p6-* | 6x86-* | athlon-* | athlon_*-*) cpu=i686 ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) @@ -1180,7 +1181,7 @@ case $cpu-$vendor in case $cpu in 1750a | 580 \ | a29k \ - | aarch64 | aarch64_be \ + | aarch64 | aarch64_be | aarch64c | arm64ec \ | abacus \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \ @@ -1199,45 +1200,23 @@ case $cpu-$vendor in | d10v | d30v | dlx | dsp16xx \ | e2k | elxsi | epiphany \ | f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \ + | javascript \ | h8300 | h8500 \ | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i*86 | i860 | i960 | ia16 | ia64 \ | ip2k | iq2000 \ | k1om \ + | kvx \ | le32 | le64 \ | lm32 \ - | loongarch32 | loongarch64 | loongarchx32 \ + | loongarch32 | loongarch64 \ | m32c | m32r | m32rle \ | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \ | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \ | m88110 | m88k | maxq | mb | mcore | mep | metag \ | microblaze | microblazeel \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | 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 \ + | mips* \ | mmix \ | mn10200 | mn10300 \ | 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 ;; esac @@ -1306,11 +1285,12 @@ esac # Decode manufacturer-specific aliases for certain operating systems. -if test x$basic_os != x +if test x"$basic_os" != x then # First recognize some ad-hoc cases, or perhaps split kernel-os, or else just # set os. +obj= case $basic_os in gnu/linux*) kernel=linux @@ -1341,6 +1321,10 @@ EOF kernel=linux os=`echo "$basic_os" | sed -e 's|linux|gnu|'` ;; + managarm*) + kernel=managarm + os=`echo "$basic_os" | sed -e 's|managarm|mlibc|'` + ;; *) kernel= os=$basic_os @@ -1506,10 +1490,16 @@ case $os in os=eabi ;; *) - os=elf + os= + obj=elf ;; 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. ;; @@ -1528,12 +1518,15 @@ else # system, and we'll never get to this point. kernel= +obj= case $cpu-$vendor in score-*) - os=elf + os= + obj=elf ;; spu-*) - os=elf + os= + obj=elf ;; *-acorn) os=riscix1.2 @@ -1543,28 +1536,35 @@ case $cpu-$vendor in os=gnu ;; arm*-semi) - os=aout + os= + obj=aout ;; c4x-* | tic4x-*) - os=coff + os= + obj=coff ;; c8051-*) - os=elf + os= + obj=elf ;; clipper-intergraph) os=clix ;; hexagon-*) - os=elf + os= + obj=elf ;; tic54x-*) - os=coff + os= + obj=coff ;; tic55x-*) - os=coff + os= + obj=coff ;; tic6x-*) - os=coff + os= + obj=coff ;; # This must come before the *-dec entry. pdp10-*) @@ -1586,19 +1586,24 @@ case $cpu-$vendor in os=sunos3 ;; m68*-cisco) - os=aout + os= + obj=aout ;; mep-*) - os=elf + os= + obj=elf ;; mips*-cisco) - os=elf + os= + obj=elf ;; mips*-*) - os=elf + os= + obj=elf ;; or32-*) - os=coff + os= + obj=coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=sysv3 @@ -1607,7 +1612,8 @@ case $cpu-$vendor in os=sunos4.1.1 ;; pru-*) - os=elf + os= + obj=elf ;; *-be) os=beos @@ -1688,10 +1694,12 @@ case $cpu-$vendor in os=uxpv ;; *-rom68k) - os=coff + os= + obj=coff ;; *-*bug) - os=coff + os= + obj=coff ;; *-apple) os=macos @@ -1709,7 +1717,8 @@ esac fi -# Now, validate our (potentially fixed-up) OS. +# Now, validate our (potentially fixed-up) individual pieces (OS, OBJ). + case $os in # Sometimes we do "kernel-libc", so those need to count as OSes. musl* | newlib* | relibc* | uclibc*) @@ -1720,6 +1729,9 @@ case $os in # VxWorks passes extra cpu info in the 4th filed. simlinux | simwindows | spe) ;; + # See `case $cpu-$os` validation below + ghcjs) + ;; # Now accept the basic system types. # The portable systems comes first. # 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* \ | sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \ | hiux* | abug | nacl* | netware* | windows* \ - | os9* | macos* | osx* | ios* \ + | os9* | macos* | osx* | ios* | tvos* | watchos* \ | mpw* | magic* | mmixware* | mon960* | lnews* \ | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ | aos* | aros* | cloudabi* | sortix* | twizzler* \ @@ -1737,11 +1749,11 @@ case $os in | mirbsd* | netbsd* | dicos* | openedition* | ose* \ | bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \ | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \ - | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ - | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ + | bosx* | nextstep* | cxux* | oabi* \ + | ptx* | ecoff* | winnt* | domain* | vsta* \ | udi* | lites* | ieee* | go32* | aux* | hcos* \ | chorusrdb* | cegcc* | glidix* | serenity* \ - | cygwin* | msys* | pe* | moss* | proelf* | rtems* \ + | cygwin* | msys* | moss* | proelf* | rtems* \ | midipix* | mingw32* | mingw64* | mint* \ | uxpv* | beos* | mpeix* | udk* | moxiebox* \ | interix* | uwin* | mks* | rhapsody* | darwin* \ @@ -1754,7 +1766,7 @@ case $os in | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \ - | fiwix* ) + | fiwix* | mlibc* | cos* | mbr* ) ;; # This one is extra strict with allowed versions sco3.2v2 | sco3.2v[4-9]* | sco5v6*) @@ -1762,41 +1774,99 @@ case $os in ;; 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 + exit 1 + ;; +esac + +case $obj in + aout* | coff* | elf* | pe*) + ;; + '') + # empty is fine + ;; *) - echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2 + 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 ;; esac # As a final step for OS-related things, validate the OS-kernel combination # (given a valid OS), if there is a kernel. -case $kernel-$os in - linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \ - | linux-musl* | linux-relibc* | linux-uclibc* ) +case $kernel-$os-$obj in + linux-gnu*- | linux-dietlibc*- | linux-android*- | linux-newlib*- \ + | linux-musl*- | linux-relibc*- | linux-uclibc*- | linux-mlibc*- ) + ;; + uclinux-uclibc*- ) ;; - uclinux-uclibc* ) + managarm-mlibc*- | managarm-kernel*- ) ;; - -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* ) + windows*-msvc*-) + ;; + -dietlibc*- | -newlib*- | -musl*- | -relibc*- | -uclibc*- | -mlibc*- ) # These are just libc implementations, not actual OSes, and thus # 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 ;; - 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. ;; - *-*) - 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 ;; esac @@ -1879,7 +1949,7 @@ case $vendor in ;; esac -echo "$cpu-$vendor-${kernel:+$kernel-}$os" +echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}" exit # Local variables: diff --git a/configure b/configure index 07a0cd1..2939faa 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for Mini-XML 3.3.1. +# Generated by GNU Autoconf 2.71 for Mini-XML 4.0b1. # # Report bugs to . # @@ -610,8 +610,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='Mini-XML' PACKAGE_TARNAME='mxml' -PACKAGE_VERSION='3.3.1' -PACKAGE_STRING='Mini-XML 3.3.1' +PACKAGE_VERSION='4.0b1' +PACKAGE_STRING='Mini-XML 4.0b1' PACKAGE_BUGREPORT='https://github.com/michaelrsweet/mxml/issues' PACKAGE_URL='https://www.msweet.org/mxml' @@ -649,28 +649,26 @@ ac_includes_default="\ ac_header_c_list= ac_subst_vars='LTLIBOBJS LIBOBJS -PC_LIBS -PC_CFLAGS +PKGCONFIG_LIBS +PKGCONFIG_CFLAGS TARGETS WARNINGS -PICFLAG +OPTIONS +CSFLAGS +UNINSTALL_STATIC +LIBMXML_STATIC LIBMXML -DSOFLAGS -DSO +INSTALL_STATIC ARFLAGS +LN +RMDIR RM MKDIR -LN LDCONFIG -CP +INSTALL +CODE_SIGN AR RANLIB -INSTALL_DATA -INSTALL_SCRIPT -INSTALL_PROGRAM -ac_ct_CXX -CXXFLAGS -CXX OBJEXT EXEEXT ac_ct_CC @@ -678,9 +676,9 @@ CPPFLAGS CFLAGS CC OPTIM -ARCHFLAGS LDFLAGS -VERSION +DSOFLAGS +DSO host_os host_vendor host_cpu @@ -689,6 +687,7 @@ build_os build_vendor build_cpu build +MXML_VERSION target_alias host_alias build_alias @@ -731,16 +730,15 @@ SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking -with_ansi -with_archflags -with_optim +enable_threads +enable_static +enable_shared enable_debug enable_maintainer -enable_sanitizer +with_sanitizer +with_dsoflags +with_ldflags with_docdir -with_vsnprintf -enable_threads -enable_shared ' ac_precious_vars='build_alias host_alias @@ -749,10 +747,7 @@ CC CFLAGS LDFLAGS LIBS -CPPFLAGS -CXX -CXXFLAGS -CCC' +CPPFLAGS' # Initialize some variables set by options. @@ -1301,7 +1296,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures Mini-XML 3.3.1 to adapt to many kinds of systems. +\`configure' configures Mini-XML 4.0b1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1367,7 +1362,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of Mini-XML 3.3.1:";; + short | recursive ) echo "Configuration of Mini-XML 4.0b1:";; esac cat <<\_ACEOF @@ -1375,21 +1370,21 @@ Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-threads disable multi-threading support, default=no + --disable-static do not install static library + --disable-shared do not install shared library --enable-debug turn on debugging, default=no --enable-maintainer turn on maintainer mode, default=no - --enable-sanitizer build with AddressSanitizer, default=no - --disable-threads disable multi-threading support, default=no - --disable-shared turn off shared libraries, default=no Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-ansi set full ANSI C mode, default=no - --with-archflags set additional architecture flags, default=none - --with-optim set additional optimization flags, default=none + --with-sanitizer build with address, leak, memory, thread, or + undefined sanitizer, default=no + --with-dsoflags=... Specify additional DSOFLAGS + --with-ldflags=... Specify additional LDFLAGS --with-docdir set directory for documentation, default=${prefix}/share/doc/mxml - --with-vsnprintf use vsnprintf emulation functions, default=auto Some influential environment variables: CC C compiler command @@ -1399,8 +1394,6 @@ Some influential environment variables: LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory - CXX C++ compiler command - CXXFLAGS C++ compiler flags Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. @@ -1470,7 +1463,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -Mini-XML configure 3.3.1 +Mini-XML configure 4.0b1 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -1523,45 +1516,6 @@ fi } # ac_fn_c_try_compile -# ac_fn_cxx_try_compile LINENO -# ---------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_cxx_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest.beam - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -printf "%s\n" "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext -then : - ac_retval=0 -else $as_nop - printf "%s\n" "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_cxx_try_compile - # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. @@ -1609,68 +1563,6 @@ fi } # ac_fn_c_try_link -# ac_fn_c_check_func LINENO FUNC VAR -# ---------------------------------- -# Tests whether FUNC exists, setting the cache variable VAR accordingly -ac_fn_c_check_func () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -printf %s "checking for $2... " >&6; } -if eval test \${$3+y} -then : - printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -/* Define $2 to an innocuous variant, in case declares $2. - For example, HP-UX 11i declares gettimeofday. */ -#define $2 innocuous_$2 - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $2 (); below. */ - -#include -#undef $2 - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $2 (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$2 || defined __stub___$2 -choke me -#endif - -int -main (void) -{ -return $2 (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - eval "$3=yes" -else $as_nop - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -fi -eval ac_res=\$$3 - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -printf "%s\n" "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_func - # ac_fn_c_try_run LINENO # ---------------------- # Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that @@ -1770,7 +1662,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by Mini-XML $as_me 3.3.1, which was +It was created by Mini-XML $as_me 4.0b1, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -2349,222 +2241,6 @@ main (int argc, char **argv) } " -# Test code for whether the C++ compiler supports C++98 (global declarations) -ac_cxx_conftest_cxx98_globals=' -// Does the compiler advertise C++98 conformance? -#if !defined __cplusplus || __cplusplus < 199711L -# error "Compiler does not advertise C++98 conformance" -#endif - -// These inclusions are to reject old compilers that -// lack the unsuffixed header files. -#include -#include - -// and are *not* freestanding headers in C++98. -extern void assert (int); -namespace std { - extern int strcmp (const char *, const char *); -} - -// Namespaces, exceptions, and templates were all added after "C++ 2.0". -using std::exception; -using std::strcmp; - -namespace { - -void test_exception_syntax() -{ - try { - throw "test"; - } catch (const char *s) { - // Extra parentheses suppress a warning when building autoconf itself, - // due to lint rules shared with more typical C programs. - assert (!(strcmp) (s, "test")); - } -} - -template struct test_template -{ - T const val; - explicit test_template(T t) : val(t) {} - template T add(U u) { return static_cast(u) + val; } -}; - -} // anonymous namespace -' - -# Test code for whether the C++ compiler supports C++98 (body of main) -ac_cxx_conftest_cxx98_main=' - assert (argc); - assert (! argv[0]); -{ - test_exception_syntax (); - test_template tt (2.0); - assert (tt.add (4) == 6.0); - assert (true && !false); -} -' - -# Test code for whether the C++ compiler supports C++11 (global declarations) -ac_cxx_conftest_cxx11_globals=' -// Does the compiler advertise C++ 2011 conformance? -#if !defined __cplusplus || __cplusplus < 201103L -# error "Compiler does not advertise C++11 conformance" -#endif - -namespace cxx11test -{ - constexpr int get_val() { return 20; } - - struct testinit - { - int i; - double d; - }; - - class delegate - { - public: - delegate(int n) : n(n) {} - delegate(): delegate(2354) {} - - virtual int getval() { return this->n; }; - protected: - int n; - }; - - class overridden : public delegate - { - public: - overridden(int n): delegate(n) {} - virtual int getval() override final { return this->n * 2; } - }; - - class nocopy - { - public: - nocopy(int i): i(i) {} - nocopy() = default; - nocopy(const nocopy&) = delete; - nocopy & operator=(const nocopy&) = delete; - private: - int i; - }; - - // for testing lambda expressions - template Ret eval(Fn f, Ret v) - { - return f(v); - } - - // for testing variadic templates and trailing return types - template auto sum(V first) -> V - { - return first; - } - template auto sum(V first, Args... rest) -> V - { - return first + sum(rest...); - } -} -' - -# Test code for whether the C++ compiler supports C++11 (body of main) -ac_cxx_conftest_cxx11_main=' -{ - // Test auto and decltype - auto a1 = 6538; - auto a2 = 48573953.4; - auto a3 = "String literal"; - - int total = 0; - for (auto i = a3; *i; ++i) { total += *i; } - - decltype(a2) a4 = 34895.034; -} -{ - // Test constexpr - short sa[cxx11test::get_val()] = { 0 }; -} -{ - // Test initializer lists - cxx11test::testinit il = { 4323, 435234.23544 }; -} -{ - // Test range-based for - int array[] = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, - 14, 19, 17, 8, 6, 20, 16, 2, 11, 1}; - for (auto &x : array) { x += 23; } -} -{ - // Test lambda expressions - using cxx11test::eval; - assert (eval ([](int x) { return x*2; }, 21) == 42); - double d = 2.0; - assert (eval ([&](double x) { return d += x; }, 3.0) == 5.0); - assert (d == 5.0); - assert (eval ([=](double x) mutable { return d += x; }, 4.0) == 9.0); - assert (d == 5.0); -} -{ - // Test use of variadic templates - using cxx11test::sum; - auto a = sum(1); - auto b = sum(1, 2); - auto c = sum(1.0, 2.0, 3.0); -} -{ - // Test constructor delegation - cxx11test::delegate d1; - cxx11test::delegate d2(); - cxx11test::delegate d3(45); -} -{ - // Test override and final - cxx11test::overridden o1(55464); -} -{ - // Test nullptr - char *c = nullptr; -} -{ - // Test template brackets - test_template<::test_template> v(test_template(12)); -} -{ - // Unicode literals - char const *utf8 = u8"UTF-8 string \u2500"; - char16_t const *utf16 = u"UTF-8 string \u2500"; - char32_t const *utf32 = U"UTF-32 string \u2500"; -} -' - -# Test code for whether the C compiler supports C++11 (complete). -ac_cxx_conftest_cxx11_program="${ac_cxx_conftest_cxx98_globals} -${ac_cxx_conftest_cxx11_globals} - -int -main (int argc, char **argv) -{ - int ok = 0; - ${ac_cxx_conftest_cxx98_main} - ${ac_cxx_conftest_cxx11_main} - return ok; -} -" - -# Test code for whether the C compiler supports C++98 (complete). -ac_cxx_conftest_cxx98_program="${ac_cxx_conftest_cxx98_globals} -int -main (int argc, char **argv) -{ - int ok = 0; - ${ac_cxx_conftest_cxx98_main} - return ok; -} -" - as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H" as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H" as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H" @@ -2576,7 +2252,7 @@ as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H" as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H" # Auxiliary files required by this configure script. -ac_aux_files="install-sh config.guess config.sub" +ac_aux_files="config.guess config.sub" # Locations in which to look for auxiliary files. ac_aux_dir_candidates="${srcdir}${PATH_SEPARATOR}${srcdir}/..${PATH_SEPARATOR}${srcdir}/../.." @@ -2741,6 +2417,13 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu +ac_config_headers="$ac_config_headers config.h" + + +MXML_VERSION="4.0b1" + + +printf "%s\n" "#define MXML_VERSION \"Mini-XML v$MXML_VERSION\"" >>confdefs.h @@ -2834,182 +2517,64 @@ then : fi -ac_config_headers="$ac_config_headers config.h" - - - -VERSION="3.3.1" - -printf "%s\n" "#define MXML_VERSION \"Mini-XML v$VERSION\"" >>confdefs.h - - - CFLAGS="${CFLAGS:=}" CPPFLAGS="${CPPFLAGS:=}" +DSO="" +DSOFLAGS="${DSOFLAGS:=}" LDFLAGS="${LDFLAGS:=}" - LIBS="${LIBS:=}" +OPTIM="${OPTIM:=}" -# Check whether --with-ansi was given. -if test ${with_ansi+y} -then : - withval=$with_ansi; - use_ansi="$withval" - -else $as_nop - - use_ansi="no" - -fi - - - -# Check whether --with-archflags was given. -if test ${with_archflags+y} -then : - withval=$with_archflags; - ARCHFLAGS="$withval" -else $as_nop - case "$host_os_name" in #( - darwin*) : - if test "$host_os_version" -ge 200 -a x$enable_debug != xyes -then : - # macOS 11.0 and higher support the Apple Silicon (arm64) CPUs - ARCHFLAGS="-mmacosx-version-min=10.14 -arch x86_64 -arch arm64" -elif test x$enable_debug != xyes -then : - ARCHFLAGS="-mmacosx-version-min=10.14 -arch x86_64" -fi - ;; #( - *) : - ARCHFLAGS="" - ;; #( - *) : - ;; -esac -fi -# Check whether --with-optim was given. -if test ${with_optim+y} +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} then : - withval=$with_optim; - OPTIM="$withval" - + printf %s "(cached) " >&6 else $as_nop - - OPTIM="" - -fi - - - -# Check whether --enable-debug was given. -if test ${enable_debug+y} -then : - enableval=$enable_debug; -fi - -# Check whether --enable-maintainer was given. -if test ${enable_maintainer+y} -then : - enableval=$enable_maintainer; -fi - -# Check whether --enable-sanitizer was given. -if test ${enable_sanitizer+y} -then : - enableval=$enable_sanitizer; -fi - - - -# Check whether --with-docdir was given. -if test ${with_docdir+y} -then : - withval=$with_docdir; - docdir="$withval" - -else $as_nop - - docdir="NONE" - -fi - - - - -# Check whether --with-vsnprintf was given. -if test ${with_vsnprintf+y} -then : - withval=$with_vsnprintf; - use_vsnprintf="$withval" - -else $as_nop - - use_vsnprintf="no" - -fi - - - - - - - - - - - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_CC+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS fi fi @@ -3961,487 +3526,6 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - - - - -ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -if test -z "$CXX"; then - if test -n "$CCC"; then - CXX=$CCC - else - if test -n "$ac_tool_prefix"; then - for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++ - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_CXX+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$CXX"; then - ac_cv_prog_CXX="$CXX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CXX=$ac_cv_prog_CXX -if test -n "$CXX"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 -printf "%s\n" "$CXX" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - - test -n "$CXX" && break - done -fi -if test -z "$CXX"; then - ac_ct_CXX=$CXX - for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++ -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_CXX+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_CXX"; then - ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CXX="$ac_prog" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CXX=$ac_cv_prog_ac_ct_CXX -if test -n "$ac_ct_CXX"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 -printf "%s\n" "$ac_ct_CXX" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - - test -n "$ac_ct_CXX" && break -done - - if test "x$ac_ct_CXX" = x; then - CXX="g++" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CXX=$ac_ct_CXX - fi -fi - - fi -fi -# Provide some information about the compiler. -printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -printf "%s\n" "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C++" >&5 -printf %s "checking whether the compiler supports GNU C++... " >&6; } -if test ${ac_cv_cxx_compiler_gnu+y} -then : - printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main (void) -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO" -then : - ac_compiler_gnu=yes -else $as_nop - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -ac_cv_cxx_compiler_gnu=$ac_compiler_gnu - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 -printf "%s\n" "$ac_cv_cxx_compiler_gnu" >&6; } -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - -if test $ac_compiler_gnu = yes; then - GXX=yes -else - GXX= -fi -ac_test_CXXFLAGS=${CXXFLAGS+y} -ac_save_CXXFLAGS=$CXXFLAGS -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 -printf %s "checking whether $CXX accepts -g... " >&6; } -if test ${ac_cv_prog_cxx_g+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_save_cxx_werror_flag=$ac_cxx_werror_flag - ac_cxx_werror_flag=yes - ac_cv_prog_cxx_g=no - CXXFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main (void) -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO" -then : - ac_cv_prog_cxx_g=yes -else $as_nop - CXXFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main (void) -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO" -then : - -else $as_nop - ac_cxx_werror_flag=$ac_save_cxx_werror_flag - CXXFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main (void) -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO" -then : - ac_cv_prog_cxx_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - ac_cxx_werror_flag=$ac_save_cxx_werror_flag -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 -printf "%s\n" "$ac_cv_prog_cxx_g" >&6; } -if test $ac_test_CXXFLAGS; then - CXXFLAGS=$ac_save_CXXFLAGS -elif test $ac_cv_prog_cxx_g = yes; then - if test "$GXX" = yes; then - CXXFLAGS="-g -O2" - else - CXXFLAGS="-g" - fi -else - if test "$GXX" = yes; then - CXXFLAGS="-O2" - else - CXXFLAGS= - fi -fi -ac_prog_cxx_stdcxx=no -if test x$ac_prog_cxx_stdcxx = xno -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++11 features" >&5 -printf %s "checking for $CXX option to enable C++11 features... " >&6; } -if test ${ac_cv_prog_cxx_11+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_cv_prog_cxx_11=no -ac_save_CXX=$CXX -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_cxx_conftest_cxx11_program -_ACEOF -for ac_arg in '' -std=gnu++11 -std=gnu++0x -std=c++11 -std=c++0x -qlanglvl=extended0x -AA -do - CXX="$ac_save_CXX $ac_arg" - if ac_fn_cxx_try_compile "$LINENO" -then : - ac_cv_prog_cxx_cxx11=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam - test "x$ac_cv_prog_cxx_cxx11" != "xno" && break -done -rm -f conftest.$ac_ext -CXX=$ac_save_CXX -fi - -if test "x$ac_cv_prog_cxx_cxx11" = xno -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -printf "%s\n" "unsupported" >&6; } -else $as_nop - if test "x$ac_cv_prog_cxx_cxx11" = x -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -printf "%s\n" "none needed" >&6; } -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx11" >&5 -printf "%s\n" "$ac_cv_prog_cxx_cxx11" >&6; } - CXX="$CXX $ac_cv_prog_cxx_cxx11" -fi - ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11 - ac_prog_cxx_stdcxx=cxx11 -fi -fi -if test x$ac_prog_cxx_stdcxx = xno -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++98 features" >&5 -printf %s "checking for $CXX option to enable C++98 features... " >&6; } -if test ${ac_cv_prog_cxx_98+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_cv_prog_cxx_98=no -ac_save_CXX=$CXX -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_cxx_conftest_cxx98_program -_ACEOF -for ac_arg in '' -std=gnu++98 -std=c++98 -qlanglvl=extended -AA -do - CXX="$ac_save_CXX $ac_arg" - if ac_fn_cxx_try_compile "$LINENO" -then : - ac_cv_prog_cxx_cxx98=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam - test "x$ac_cv_prog_cxx_cxx98" != "xno" && break -done -rm -f conftest.$ac_ext -CXX=$ac_save_CXX -fi - -if test "x$ac_cv_prog_cxx_cxx98" = xno -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -printf "%s\n" "unsupported" >&6; } -else $as_nop - if test "x$ac_cv_prog_cxx_cxx98" = x -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -printf "%s\n" "none needed" >&6; } -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx98" >&5 -printf "%s\n" "$ac_cv_prog_cxx_cxx98" >&6; } - CXX="$CXX $ac_cv_prog_cxx_cxx98" -fi - ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98 - ac_prog_cxx_stdcxx=cxx98 -fi -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - # Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -# Reject install programs that cannot install multiple files. -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 -printf %s "checking for a BSD-compatible install... " >&6; } -if test -z "$INSTALL"; then -if test ${ac_cv_path_install+y} -then : - printf %s "(cached) " >&6 -else $as_nop - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - # Account for fact that we put trailing slashes in our PATH walk. -case $as_dir in #(( - ./ | /[cC]/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext"; then - if test $ac_prog = install && - grep dspmsg "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - rm -rf conftest.one conftest.two conftest.dir - echo one > conftest.one - echo two > conftest.two - mkdir conftest.dir - if "$as_dir$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir/" && - test -s conftest.one && test -s conftest.two && - test -s conftest.dir/conftest.one && - test -s conftest.dir/conftest.two - then - ac_cv_path_install="$as_dir$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - fi - done - done - ;; -esac - - done -IFS=$as_save_IFS - -rm -rf conftest.one conftest.two conftest.dir - -fi - if test ${ac_cv_path_install+y}; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 -printf "%s\n" "$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -if test "$INSTALL" = "$ac_install_sh" -then : - - # Use full path to install-sh script... - INSTALL="`pwd`/install-sh -c" - -fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 @@ -4544,19 +3628,20 @@ else RANLIB="$ac_cv_prog_RANLIB" fi -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. -set dummy ${ac_tool_prefix}ar; ac_word=$2 +# Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_AR+y} +if test ${ac_cv_path_AR+y} then : printf %s "(cached) " >&6 else $as_nop - if test -n "$AR"; then - ac_cv_prog_AR="$AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR + case $AR in + [\\/]* | ?:[\\/]*) + ac_cv_path_AR="$AR" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS @@ -4567,7 +3652,7 @@ do esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_AR="${ac_tool_prefix}ar" + ac_cv_path_AR="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi @@ -4575,9 +3660,10 @@ done done IFS=$as_save_IFS + ;; +esac fi -fi -AR=$ac_cv_prog_AR +AR=$ac_cv_path_AR if test -n "$AR"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 printf "%s\n" "$AR" >&6; } @@ -4587,21 +3673,22 @@ printf "%s\n" "no" >&6; } fi -fi -if test -z "$ac_cv_prog_AR"; then - ac_ct_AR=$AR - # Extract the first word of "ar", so it can be a program name with args. -set dummy ar; ac_word=$2 +for ac_prog in codesign true +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_AR+y} +if test ${ac_cv_path_CODE_SIGN+y} then : printf %s "(cached) " >&6 else $as_nop - if test -n "$ac_ct_AR"; then - ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR + case $CODE_SIGN in + [\\/]* | ?:[\\/]*) + ac_cv_path_CODE_SIGN="$CODE_SIGN" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS @@ -4612,7 +3699,7 @@ do esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_AR="ar" + ac_cv_path_CODE_SIGN="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi @@ -4620,43 +3707,41 @@ done done IFS=$as_save_IFS + ;; +esac fi -fi -ac_ct_AR=$ac_cv_prog_ac_ct_AR -if test -n "$ac_ct_AR"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 -printf "%s\n" "$ac_ct_AR" >&6; } +CODE_SIGN=$ac_cv_path_CODE_SIGN +if test -n "$CODE_SIGN"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CODE_SIGN" >&5 +printf "%s\n" "$CODE_SIGN" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi - if test "x$ac_ct_AR" = x; then - AR="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - AR=$ac_ct_AR - fi -else - AR="$ac_cv_prog_AR" -fi -# Extract the first word of "cp", so it can be a program name with args. -set dummy cp; ac_word=$2 + test -n "$CODE_SIGN" && break +done + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for install-sh script" >&5 +printf %s "checking for install-sh script... " >&6; } +INSTALL="`pwd`/install-sh" + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: using $INSTALL" >&5 +printf "%s\n" "using $INSTALL" >&6; } +for ac_prog in ldconfig true +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_path_CP+y} +if test ${ac_cv_path_LDCONFIG+y} then : printf %s "(cached) " >&6 else $as_nop - case $CP in + case $LDCONFIG in [\\/]* | ?:[\\/]*) - ac_cv_path_CP="$CP" # Let the user override the test with a path. + ac_cv_path_LDCONFIG="$LDCONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -4670,7 +3755,7 @@ do esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_path_CP="$as_dir$ac_word$ac_exec_ext" + ac_cv_path_LDCONFIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi @@ -4681,29 +3766,30 @@ IFS=$as_save_IFS ;; esac fi -CP=$ac_cv_path_CP -if test -n "$CP"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CP" >&5 -printf "%s\n" "$CP" >&6; } +LDCONFIG=$ac_cv_path_LDCONFIG +if test -n "$LDCONFIG"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LDCONFIG" >&5 +printf "%s\n" "$LDCONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi -for ac_prog in ldconfig false -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 + test -n "$LDCONFIG" && break +done + +# Extract the first word of "mkdir", so it can be a program name with args. +set dummy mkdir; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_path_LDCONFIG+y} +if test ${ac_cv_path_MKDIR+y} then : printf %s "(cached) " >&6 else $as_nop - case $LDCONFIG in + case $MKDIR in [\\/]* | ?:[\\/]*) - ac_cv_path_LDCONFIG="$LDCONFIG" # Let the user override the test with a path. + ac_cv_path_MKDIR="$MKDIR" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -4717,7 +3803,7 @@ do esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_path_LDCONFIG="$as_dir$ac_word$ac_exec_ext" + ac_cv_path_MKDIR="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi @@ -4728,30 +3814,27 @@ IFS=$as_save_IFS ;; esac fi -LDCONFIG=$ac_cv_path_LDCONFIG -if test -n "$LDCONFIG"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LDCONFIG" >&5 -printf "%s\n" "$LDCONFIG" >&6; } +MKDIR=$ac_cv_path_MKDIR +if test -n "$MKDIR"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MKDIR" >&5 +printf "%s\n" "$MKDIR" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi - test -n "$LDCONFIG" && break -done - -# Extract the first word of "ln", so it can be a program name with args. -set dummy ln; ac_word=$2 +# Extract the first word of "rm", so it can be a program name with args. +set dummy rm; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_path_LN+y} +if test ${ac_cv_path_RM+y} then : printf %s "(cached) " >&6 else $as_nop - case $LN in + case $RM in [\\/]* | ?:[\\/]*) - ac_cv_path_LN="$LN" # Let the user override the test with a path. + ac_cv_path_RM="$RM" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -4765,7 +3848,7 @@ do esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_path_LN="$as_dir$ac_word$ac_exec_ext" + ac_cv_path_RM="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi @@ -4776,27 +3859,27 @@ IFS=$as_save_IFS ;; esac fi -LN=$ac_cv_path_LN -if test -n "$LN"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LN" >&5 -printf "%s\n" "$LN" >&6; } +RM=$ac_cv_path_RM +if test -n "$RM"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RM" >&5 +printf "%s\n" "$RM" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi -# Extract the first word of "mkdir", so it can be a program name with args. -set dummy mkdir; ac_word=$2 +# Extract the first word of "rmdir", so it can be a program name with args. +set dummy rmdir; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_path_MKDIR+y} +if test ${ac_cv_path_RMDIR+y} then : printf %s "(cached) " >&6 else $as_nop - case $MKDIR in + case $RMDIR in [\\/]* | ?:[\\/]*) - ac_cv_path_MKDIR="$MKDIR" # Let the user override the test with a path. + ac_cv_path_RMDIR="$RMDIR" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -4810,7 +3893,7 @@ do esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_path_MKDIR="$as_dir$ac_word$ac_exec_ext" + ac_cv_path_RMDIR="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi @@ -4821,27 +3904,27 @@ IFS=$as_save_IFS ;; esac fi -MKDIR=$ac_cv_path_MKDIR -if test -n "$MKDIR"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MKDIR" >&5 -printf "%s\n" "$MKDIR" >&6; } +RMDIR=$ac_cv_path_RMDIR +if test -n "$RMDIR"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RMDIR" >&5 +printf "%s\n" "$RMDIR" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi -# Extract the first word of "rm", so it can be a program name with args. -set dummy rm; ac_word=$2 +# Extract the first word of "ln", so it can be a program name with args. +set dummy ln; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_path_RM+y} +if test ${ac_cv_path_LN+y} then : printf %s "(cached) " >&6 else $as_nop - case $RM in + case $LN in [\\/]* | ?:[\\/]*) - ac_cv_path_RM="$RM" # Let the user override the test with a path. + ac_cv_path_LN="$LN" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -4855,7 +3938,7 @@ do esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_path_RM="$as_dir$ac_word$ac_exec_ext" + ac_cv_path_LN="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi @@ -4866,10 +3949,10 @@ IFS=$as_save_IFS ;; esac fi -RM=$ac_cv_path_RM -if test -n "$RM"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RM" >&5 -printf "%s\n" "$RM" >&6; } +LN=$ac_cv_path_LN +if test -n "$LN"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LN" >&5 +printf "%s\n" "$LN" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } @@ -4878,18 +3961,16 @@ fi -case "$host_os_name" in #( - darwin* | *bsd) : +if test "$ac_cv_prog_ranlib" = ":" +then : - ARFLAGS="-rcv" - ;; #( - *) : + ARFLAGS="crs" - ARFLAGS="crvs" - ;; #( - *) : - ;; -esac +else $as_nop + + ARFLAGS="cr" + +fi @@ -4940,57 +4021,6 @@ esac -if test "x$use_ansi" != xyes -then : - - ac_fn_c_check_func "$LINENO" "strdup" "ac_cv_func_strdup" -if test "x$ac_cv_func_strdup" = xyes -then : - printf "%s\n" "#define HAVE_STRDUP 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "strlcat" "ac_cv_func_strlcat" -if test "x$ac_cv_func_strlcat" = xyes -then : - printf "%s\n" "#define HAVE_STRLCAT 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "strlcpy" "ac_cv_func_strlcpy" -if test "x$ac_cv_func_strlcpy" = xyes -then : - printf "%s\n" "#define HAVE_STRLCPY 1" >>confdefs.h - -fi - - -fi - -if test "x$use_vsnprintf" != xyes -then : - - ac_fn_c_check_func "$LINENO" "snprintf" "ac_cv_func_snprintf" -if test "x$ac_cv_func_snprintf" = xyes -then : - printf "%s\n" "#define HAVE_SNPRINTF 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "vasprintf" "ac_cv_func_vasprintf" -if test "x$ac_cv_func_vasprintf" = xyes -then : - printf "%s\n" "#define HAVE_VASPRINTF 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "vsnprintf" "ac_cv_func_vsnprintf" -if test "x$ac_cv_func_vsnprintf" = xyes -then : - printf "%s\n" "#define HAVE_VSNPRINTF 1" >>confdefs.h - -fi - - -fi - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for unsigned long long int" >&5 printf %s "checking for unsigned long long int... " >&6; } @@ -5228,8 +4258,11 @@ fi fi -DSO="${DSO:=:}" -DSOFLAGS="${DSOFLAGS:=}" +# Check whether --enable-static was given. +if test ${enable_static+y} +then : + enableval=$enable_static; +fi # Check whether --enable-shared was given. if test ${enable_shared+y} @@ -5238,144 +4271,163 @@ then : fi +LIBMXML_STATIC="libmxml.a" if test x$enable_shared != xno then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shared library support" >&5 -printf %s "checking for shared library support... " >&6; } - PICFLAG=1 - case "$host_os_name" in #( - sunos | unix_s) : - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - LIBMXML="libmxml.so.1.6" - DSO="\$(CC)" - DSOFLAGS="$DSOFLAGS -Wl,-h,libmxml.so.1 -G -R\$(libdir) \$(OPTIM)" - LDFLAGS="$LDFLAGS -R\$(libdir)" - ;; #( - linux*) : + linux* | gnu*) : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - LIBMXML="libmxml.so.1.6" + LIBMXML="libmxml.so.2" DSO="\$(CC)" - DSOFLAGS="$DSOFLAGS -Wl,-soname,libmxml.so.1 -shared \$(OPTIM)" + DSOFLAGS="$DSOFLAGS -Wl,-soname,\`basename \$@\` -shared" ;; #( - osf | gnu) : + *bsd*) : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - LIBMXML="libmxml.so.1.6" + LIBMXML="libmxml.so.2" DSO="\$(CC)" - DSOFLAGS="$DSOFLAGS -Wl,-soname,libmxml.so.1,-rpath,\$(libdir) -shared \$(OPTIM)" - LDFLAGS="$LDFLAGS -Wl,-rpath,\$(libdir)" + DSOFLAGS="$DSOFLAGS -Wl,-soname,\`basename \$@\` -shared -lc" ;; #( - *bsd | haiku*) : + darwin*) : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - LIBMXML="libmxml.so.1.6" + LIBMXML="libmxml.2.dylib" DSO="\$(CC)" - DSOFLAGS="$DSOFLAGS -Wl,-soname,libmxml.so.1,-R\$(libdir) -shared \$(OPTIM)" - LDFLAGS="$LDFLAGS -Wl,-R\$(libdir)" + DSOFLAGS="$DSOFLAGS -Wl,-no_warn_inits -dynamiclib -lc" ;; #( - darwin) : + sunos*) : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - LIBMXML="libmxml.1.dylib" + LIBMXML="libmxml.so.2" DSO="\$(CC)" - DSOFLAGS="$DSOFLAGS \$(RC_CFLAGS) -dynamiclib -lc" + DSOFLAGS="$DSOFLAGS -Wl,-h,\`basename \$@\` -G" ;; #( mingw) : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - LIBMXML="mxml1.dll" + LIBMXML="libmxml2.dll" 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" ;; #( *) : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: shared libraries not supported on this platform." >&5 -printf "%s\n" "$as_me: WARNING: shared libraries not supported on this platform." >&2;} - PICFLAG=0 - LIBMXML="libmxml.a" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Warning: Shared libraries may not work, trying -shared option." >&5 +printf "%s\n" "$as_me: Warning: Shared libraries may not work, trying -shared option." >&6;} + LIBMXML="libmxml.so.2" + DSO="\$(CC)" + DSOFLAGS="$DSOFLAGS -Wl,-soname,\`basename \$@\` -shared" ;; #( *) : ;; esac + if test x$enable_static != xno +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Installing static libraries..." >&5 +printf "%s\n" "$as_me: Installing static libraries..." >&6;} + INSTALL_STATIC="install-libmxml.a" + UNINSTALL_STATIC="uninstall-libmxml.a" + else $as_nop - PICFLAG=0 - LIBMXML="libmxml.a" + INSTALL_STATIC="" + UNINSTALL_STATIC="" fi +else $as_nop + INSTALL_STATIC="" + LIBMXML="libmxml.a" + UNINSTALL_STATIC="" +fi -WARNINGS="" - -if test -n "$GCC" -then : - CFLAGS="-D_GNU_SOURCE $CFLAGS" - if test "x$OPTIM" = x +# Check whether --enable-debug was given. +if test ${enable_debug+y} then : + enableval=$enable_debug; +fi - if test x$enable_debug = xyes +# Check whether --enable-maintainer was given. +if test ${enable_maintainer+y} then : + enableval=$enable_maintainer; +fi - OPTIM="-g" +# Check whether --with-sanitizer was given. +if test ${with_sanitizer+y} +then : + withval=$with_sanitizer; else $as_nop + with_sanitizer=no +fi - OPTIM="-g -Os" +if test "x$with_sanitizer" = xyes +then : -fi + with_sanitizer="address" -elif test x$enable_debug = xyes +elif test "$with_sanitizer" != address -a "$with_sanitizer" != leak -a "$with_sanitizer" != memory -a "$with_sanitizer" != no -a "$with_sanitizer" != thread -a "$with_sanitizer" != undefined then : - OPTIM="$OPTIM -g" + as_fn_error $? "Unsupported --with-sanitizer value \"$with_sanitizer\" specified." "$LINENO" 5 fi - if test x$enable_sanitizer = xyes +if test x$enable_debug = xyes then : - # Use -fsanitize=address with debugging... - OPTIM="$OPTIM -fsanitize=address" + CSFLAGS="" + OPTIM="$OPTIM -g" + OPTIONS="-DDEBUG -DDEBUG_GUARDS" else $as_nop - # Otherwise use the Fortify enhancements to catch any unbounded - # string operations... - CPPFLAGS="$CPPFLAGS -D_FORTIFY_SOURCE=2" + CSFLAGS="-o runtime" + OPTIM="$OPTIM -g -Os" + OPTIONS="" fi - if test "x$use_ansi" = xyes + + + +WARNINGS="" + + +if test -n "$GCC" +then : + + if test x$with_sanitizer != xno +then : + + # Use -fsanitize=FOO with debugging... + OPTIM="$OPTIM -fsanitize=$with_sanitizer" + +elif echo "$CPPFLAGS $CFLAGS" | grep -q _FORTIFY_SOURCE then : - CFLAGS="-ansi -pedantic $CFLAGS" + # Don't add _FORTIFY_SOURCE if it is already there + +else $as_nop + + # Otherwise use the Fortify enhancements to catch any unbounded + # string operations... + CPPFLAGS="$CPPFLAGS -D_FORTIFY_SOURCE=3" fi WARNINGS="-Wall -Wunused" - 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -Wno-$warning" >&5 printf %s "checking whether compiler supports -Wno-$warning... " >&6; } @@ -5418,128 +4470,279 @@ then : fi - if test $PICFLAG = 1 -a "$host_os_name" != aix + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -fPIE" >&5 +printf %s "checking whether compiler supports -fPIE... " >&6; } + OLDCFLAGS="$CFLAGS" + case "$host_os_name" in #( + darwin*) : + + CFLAGS="$CFLAGS -fPIC -fPIE -Wl,-pie" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" then : - OPTIM="-fPIC $OPTIM" + OLDCFLAGS="-fPIC $OLDCFLAGS" + LDFLAGS="-fPIE -Wl,-pie $LDFLAGS" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +else $as_nop + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; #( + *) : -else $as_nop + CFLAGS="$CFLAGS -fPIC -fPIE -pie" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ - if test "x$OPTIM" = x -then : +int +main (void) +{ - if test x$enable_debug = xyes + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" then : - OPTIM="-g" + OLDCFLAGS="-fPIC $OLDCFLAGS" + LDFLAGS="-fPIE -pie $LDFLAGS" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } else $as_nop - OPTIM="-O" - -fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; #( + *) : + ;; +esac + CFLAGS="$OLDCFLAGS" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for OS-specific compiler options" >&5 +printf %s "checking for OS-specific compiler options... " >&6; } case "$host_os_name" in #( - hp-ux) : + linux*) : - CFLAGS="-Ae $CFLAGS" + # Make sure we get the full set of Linux APIs from the headers... + CPPFLAGS="$CPPFLAGS -D__USE_MISC -D_GNU_SOURCE" - OPTIM="+DAportable $OPTIM" + # Mark read-only sections as relocatable to random addresses... + LDFLAGS="$LDFLAGS -Wl,-z,relro,-z,now" + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: -D__USE_MISC -D_GNU_SOURCE -Wl,-z,relro,-z,now" >&5 +printf "%s\n" "-D__USE_MISC -D_GNU_SOURCE -Wl,-z,relro,-z,now" >&6; } + ;; #( + darwin*) : - if test $PICFLAG = 1 + # When not building for debug, target macOS 11 or later, "universal" + # binaries when possible... + if echo "$CPPFLAGS $CFLAGS $LDFLAGS $OPTIM" | grep -q "\\-arch " then : - OPTIM="+z $OPTIM" + # Don't add architecture/min-version flags if they are already present + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 +printf "%s\n" "none" >&6; } -fi - ;; #( - unix_svr | sunos) : +elif echo "$CPPFLAGS $CFLAGS $LDFLAGS $OPTIM" | grep -q "\\-mmacosx-version-" +then : - if test $PICFLAG = 1 + # Don't add architecture/min-version flags if they are already present + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 +printf "%s\n" "none" >&6; } + +elif test "$host_os_version" -ge 200 -a x$enable_debug != xyes then : - OPTIM="-KPIC $OPTIM" + # macOS 11.0 and higher support the Apple Silicon (arm64) CPUs + OPTIM="$OPTIM -mmacosx-version-min=11.0 -arch x86_64 -arch arm64" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: -mmacosx-version-min=11.0 -arch x86_64 -arch arm64" >&5 +printf "%s\n" "-mmacosx-version-min=11.0 -arch x86_64 -arch arm64" >&6; } + +else $as_nop + + # Don't add architecture/min-version flags if debug enabled + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 +printf "%s\n" "none" >&6; } fi ;; #( *) : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 +printf "%s\n" "none" >&6; } + ;; #( + *) : ;; esac fi -if test "$build" = "$host" + +# Check whether --with-dsoflags was given. +if test ${with_dsoflags+y} then : + withval=$with_dsoflags; + DSOFLAGS="$withval $DSOFLAGS" - TARGETS="ALLTARGETS" +fi -else $as_nop - TARGETS="CROSSTARGETS" +# Check whether --with-ldflags was given. +if test ${with_ldflags+y} +then : + withval=$with_ldflags; + LDFLAGS="$withval $LDFLAGS" fi -if test "$prefix" = "NONE" + +# Check whether --with-docdir was given. +if test ${with_docdir+y} then : + withval=$with_docdir; + docdir="$withval" + +else $as_nop - prefix="/usr/local" + docdir="NONE" fi -if test "$exec_prefix" = "NONE" -then : - exec_prefix="$prefix" -fi -if test "$docdir" = "NONE" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +if test "$build" = "$host" then : - docdir="$datadir/doc/mxml" + TARGETS="ALLTARGETS" + +else $as_nop + + TARGETS="CROSSTARGETS" fi -if test "$mandir" = "\${prefix}/man" -a "$prefix" = "/usr" + + +if test "$prefix" = NONE then : - mandir="/usr/share/man" + # Default prefix isn't bound until AC_OUTPUT... + realprefix="/usr/local" + +else $as_nop + + realprefix="$prefix" fi +if test "$datarootdir" = "\${prefix}/share" +then : -if test "$includedir" != /usr/include + if test "$prefix" = "/" then : - PC_CFLAGS="-I$includedir" + datarootdir="/usr/share" else $as_nop - PC_CFLAGS="" + datarootdir="$realprefix/share" + +fi fi +if test "$datadir" = "\${prefix}/share" +then : -if test "$libdir" != /usr/lib + if test "$prefix" = "/" then : - PC_LIBS="-L$libdir -lmxml" + datadir="/usr/share" else $as_nop - PC_LIBS="-lmxml" + datadir="$realprefix/share" + +fi + +elif test "$datadir" = "\${datarootdir}" +then : + + datadir="$datarootdir" + +fi + + +PKGCONFIG_CFLAGS="" +PKGCONFIG_LIBS="-lmxml" +if test "$realprefix" != "/usr" -a "$realprefix" != "/usr/local" +then : + + PKGCONFIG_CFLAGS="-I\${includedir}" + PKGCONFIG_LIBS="-L\${libdir} $PKGCONFIG_LIBS" fi + + ac_config_files="$ac_config_files Makefile mxml.pc" cat >confcache <<\_ACEOF @@ -6041,7 +5244,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by Mini-XML $as_me 3.3.1, which was +This file was extended by Mini-XML $as_me 4.0b1, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -6106,7 +5309,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -Mini-XML config.status 3.3.1 +Mini-XML config.status 4.0b1 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" @@ -6116,7 +5319,6 @@ gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' -INSTALL='$INSTALL' test -n "\$AWK" || AWK=awk _ACEOF @@ -6674,10 +5876,6 @@ ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix # CONFIG_FILE # - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; - esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 @@ -6731,7 +5929,6 @@ s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ diff --git a/configure.ac b/configure.ac index 5b7ec04..0ca1e9e 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ dnl Configuration script for Mini-XML, a small XML file parsing library. dnl dnl https://www.msweet.org/mxml dnl -dnl Copyright © 2003-2022 by Michael R Sweet. +dnl Copyright © 2003-2024 by Michael R Sweet. dnl dnl Licensed under Apache License v2.0. See the file "LICENSE" for more dnl information. @@ -14,8 +14,12 @@ AC_PREREQ([2.70]) 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 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... -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. +dnl Compiler options... CFLAGS="${CFLAGS:=}" CPPFLAGS="${CPPFLAGS:=}" +DSO="" +DSOFLAGS="${DSOFLAGS:=}" LDFLAGS="${LDFLAGS:=}" -AC_SUBST([LDFLAGS]) LIBS="${LIBS:=}" +OPTIM="${OPTIM:=}" - -dnl Options... -AC_ARG_WITH([ansi], AS_HELP_STRING([--with-ansi], [set full ANSI C mode, default=no]), [ - 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([DSO]) +AC_SUBST([DSOFLAGS]) +AC_SUBST([LDFLAGS]) 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]), [ - 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... +dnl Standard programs... 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_CHECK_TOOL(AR,ar) -AC_PATH_PROG(CP,cp) -AC_PATH_PROGS(LDCONFIG,ldconfig false) -AC_PATH_PROG(LN,ln) -AC_PATH_PROG(MKDIR,mkdir) -AC_PATH_PROG(RM,rm) - - -dnl Flags for "ar" command... -AS_CASE(["$host_os_name"], [darwin* | *bsd], [ - ARFLAGS="-rcv" -], [*], [ - ARFLAGS="crvs" +AC_PATH_PROG([AR], [ar]) +AC_PATH_PROGS([CODE_SIGN], [codesign true]) +AC_MSG_CHECKING([for install-sh script]) +INSTALL="`pwd`/install-sh" +AC_SUBST([INSTALL]) +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 Figure out the correct "ar" command flags... +AS_IF([test "$ac_cv_prog_ranlib" = ":"], [ + ARFLAGS="crs" +], [ + ARFLAGS="cr" ]) -AC_SUBST(ARFLAGS) +AC_SUBST([ARFLAGS]) dnl Inline functions... 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... AC_TYPE_LONG_LONG_INT @@ -180,111 +121,113 @@ AS_IF([test "x$enable_threads" != xno], [ ]) -dnl Shared library support... -DSO="${DSO:=:}" -DSOFLAGS="${DSOFLAGS:=}" - -AC_ARG_ENABLE([shared], AS_HELP_STRING([--disable-shared], [turn off shared libraries, default=no])) +dnl Library targets... +AC_ARG_ENABLE([static], AS_HELP_STRING([--disable-static], [do not install static library])) +AC_ARG_ENABLE([shared], AS_HELP_STRING([--disable-shared], [do not install shared library])) +LIBMXML_STATIC="libmxml.a" AS_IF([test x$enable_shared != xno], [ - AC_MSG_CHECKING([for shared library support]) - PICFLAG=1 - - AS_CASE(["$host_os_name"], [sunos | unix_s], [ - AC_MSG_RESULT([yes]) - LIBMXML="libmxml.so.1.6" + AS_CASE(["$host_os_name"], [linux* | gnu*], [ + LIBMXML="libmxml.so.2" DSO="\$(CC)" - DSOFLAGS="$DSOFLAGS -Wl,-h,libmxml.so.1 -G -R\$(libdir) \$(OPTIM)" - LDFLAGS="$LDFLAGS -R\$(libdir)" - ], [linux*], [ - AC_MSG_RESULT([yes]) - LIBMXML="libmxml.so.1.6" + DSOFLAGS="$DSOFLAGS -Wl,-soname,\`basename \$@\` -shared" + ], [*bsd*], [ + LIBMXML="libmxml.so.2" DSO="\$(CC)" - DSOFLAGS="$DSOFLAGS -Wl,-soname,libmxml.so.1 -shared \$(OPTIM)" - ], [osf | gnu], [ - AC_MSG_RESULT([yes]) - LIBMXML="libmxml.so.1.6" + DSOFLAGS="$DSOFLAGS -Wl,-soname,\`basename \$@\` -shared -lc" + ], [darwin*], [ + LIBMXML="libmxml.2.dylib" DSO="\$(CC)" - DSOFLAGS="$DSOFLAGS -Wl,-soname,libmxml.so.1,-rpath,\$(libdir) -shared \$(OPTIM)" - LDFLAGS="$LDFLAGS -Wl,-rpath,\$(libdir)" - ], [*bsd | haiku*], [ - AC_MSG_RESULT([yes]) - LIBMXML="libmxml.so.1.6" + DSOFLAGS="$DSOFLAGS -Wl,-no_warn_inits -dynamiclib -lc" + ], [sunos*], [ + LIBMXML="libmxml.so.2" DSO="\$(CC)" - DSOFLAGS="$DSOFLAGS -Wl,-soname,libmxml.so.1,-R\$(libdir) -shared \$(OPTIM)" - LDFLAGS="$LDFLAGS -Wl,-R\$(libdir)" - ], [darwin], [ - AC_MSG_RESULT([yes]) - LIBMXML="libmxml.1.dylib" - DSO="\$(CC)" - DSOFLAGS="$DSOFLAGS \$(RC_CFLAGS) -dynamiclib -lc" + DSOFLAGS="$DSOFLAGS -Wl,-h,\`basename \$@\` -G" ], [mingw], [ AC_MSG_RESULT([yes]) - LIBMXML="mxml1.dll" + LIBMXML="libmxml2.dll" 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_WARN([shared libraries not supported on this platform.]) - PICFLAG=0 - LIBMXML="libmxml.a" + AC_MSG_NOTICE([Warning: Shared libraries may not work, trying -shared option.]) + LIBMXML="libmxml.so.2" + DSO="\$(CC)" + 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" + UNINSTALL_STATIC="" ]) -AC_SUBST([DSO]) -AC_SUBST([DSOFLAGS]) +AC_SUBST([INSTALL_STATIC]) 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="" AC_SUBST([WARNINGS]) AS_IF([test -n "$GCC"], [ - CFLAGS="-D_GNU_SOURCE $CFLAGS" - - AS_IF([test "x$OPTIM" = x], [ - AS_IF([test x$enable_debug = xyes], [ - OPTIM="-g" - ], [ - 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" + AS_IF([test x$with_sanitizer != xno], [ + # Use -fsanitize=FOO with debugging... + OPTIM="$OPTIM -fsanitize=$with_sanitizer" + ], [echo "$CPPFLAGS $CFLAGS" | grep -q _FORTIFY_SOURCE], [ + # Don't add _FORTIFY_SOURCE if it is already there ], [ # Otherwise use the Fortify enhancements to catch any unbounded # string operations... - CPPFLAGS="$CPPFLAGS -D_FORTIFY_SOURCE=2" - ]) - - AS_IF([test "x$use_ansi" = xyes], [ - CFLAGS="-ansi -pedantic $CFLAGS" + CPPFLAGS="$CPPFLAGS -D_FORTIFY_SOURCE=3" ]) dnl Show all standard warnings + unused variables when compiling... WARNINGS="-Wall -Wunused" 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]) OLDCFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Wno-$warning -Werror" AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], [ - AC_MSG_RESULT(yes) + AC_MSG_RESULT([yes]) WARNINGS="$WARNINGS -Wno-$warning" ], [ - AC_MSG_RESULT(no) + AC_MSG_RESULT([no]) ]) CFLAGS="$OLDCFLAGS" @@ -295,32 +238,111 @@ AS_IF([test -n "$GCC"], [ WARNINGS="$WARNINGS -Werror" ]) - AS_IF([test $PICFLAG = 1 -a "$host_os_name" != aix], [ - OPTIM="-fPIC $OPTIM" + dnl See if PIE options are supported... + 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]) + ]) ]) -], [ - AS_IF([test "x$OPTIM" = x], [ - AS_IF([test x$enable_debug = xyes], [ - OPTIM="-g" + CFLAGS="$OLDCFLAGS" + + dnl OS-specific compiler options... + 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]) ]) + ], [*], [ + AC_MSG_RESULT([none]) ]) +]) - AS_CASE(["$host_os_name"], [hp-ux], [ - CFLAGS="-Ae $CFLAGS" - OPTIM="+DAportable $OPTIM" +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" +]) - AS_IF([test $PICFLAG = 1], [ - OPTIM="+z $OPTIM" - ]) - ], [unix_svr | sunos], [ - AS_IF([test $PICFLAG = 1], [ - OPTIM="-KPIC $OPTIM" - ]) - ]) + +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... @@ -333,39 +355,44 @@ AC_SUBST([TARGETS]) dnl Fix installation directories... -AS_IF([test "$prefix" = "NONE"], [ - prefix="/usr/local" -]) - -AS_IF([test "$exec_prefix" = "NONE"], [ - exec_prefix="$prefix" +AS_IF([test "$prefix" = NONE], [ + # Default prefix isn't bound until AC_OUTPUT... + realprefix="/usr/local" +], [ + realprefix="$prefix" ]) -AS_IF([test "$docdir" = "NONE"], [ - docdir="$datadir/doc/mxml" +AS_IF([test "$datarootdir" = "\${prefix}/share"], [ + AS_IF([test "$prefix" = "/"], [ + datarootdir="/usr/share" + ], [ + datarootdir="$realprefix/share" + ]) ]) -AS_IF([test "$mandir" = "\${prefix}/man" -a "$prefix" = "/usr"], [ - mandir="/usr/share/man" +AS_IF([test "$datadir" = "\${prefix}/share"], [ + AS_IF([test "$prefix" = "/"], [ + datadir="/usr/share" + ], [ + datadir="$realprefix/share" + ]) +], [test "$datadir" = "\${datarootdir}"], [ + datadir="$datarootdir" ]) -dnl pkg-config stuff... -AS_IF([test "$includedir" != /usr/include], [ - PC_CFLAGS="-I$includedir" -], [ - PC_CFLAGS="" +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([PC_CFLAGS]) -AS_IF([test "$libdir" != /usr/lib], [ - PC_LIBS="-L$libdir -lmxml" -], [ - PC_LIBS="-lmxml" -]) -AC_SUBST([PC_LIBS]) +AC_SUBST([PKGCONFIG_CFLAGS]) +AC_SUBST([PKGCONFIG_LIBS]) -dnl Output the makefile, etc... +dnl Output generated files... AC_CONFIG_FILES([Makefile mxml.pc]) AC_OUTPUT diff --git a/mxml-attr.c b/mxml-attr.c index 541396e..7707e3c 100644 --- a/mxml-attr.c +++ b/mxml-attr.c @@ -1,73 +1,50 @@ -/* - * Attribute support code for Mini-XML, a small XML file parsing library. - * - * https://www.msweet.org/mxml - * - * Copyright © 2003-2021 by Michael R Sweet. - * - * Licensed under Apache License v2.0. See the file "LICENSE" for more - * information. - */ - -/* - * Include necessary headers... - */ - -#include "config.h" +// +// Attribute support code for Mini-XML, a small XML file parsing library. +// +// https://www.msweet.org/mxml +// +// Copyright © 2003-2024 by Michael R Sweet. +// +// Licensed under Apache License v2.0. See the file "LICENSE" for more +// information. +// + #include "mxml-private.h" -/* - * Local functions... - */ +// +// Local functions... +// static int mxml_set_attr(mxml_node_t *node, const char *name, char *value); -/* - * 'mxmlElementDeleteAttr()' - Delete an attribute. - * - * @since Mini-XML 2.4@ - */ +// +// 'mxmlElementDeleteAttr()' - Delete an attribute. +// void -mxmlElementDeleteAttr(mxml_node_t *node,/* I - Element */ - const char *name)/* I - Attribute name */ +mxmlElementDeleteAttr(mxml_node_t *node,// I - Element + const char *name)// I - Attribute name { - int i; /* Looping var */ - _mxml_attr_t *attr; /* Cirrent attribute */ - + int i; // Looping var + _mxml_attr_t *attr; // Cirrent attribute -#ifdef DEBUG - fprintf(stderr, "mxmlElementDeleteAttr(node=%p, name=\"%s\")\n", - node, name ? name : "(null)"); -#endif /* DEBUG */ - /* - * Range check input... - */ + MXML_DEBUG("mxmlElementDeleteAttr(node=%p, name=\"%s\")\n", node, name ? name : "(null)"); - if (!node || node->type != MXML_ELEMENT || !name) + // Range check input... + if (!node || node->type != MXML_TYPE_ELEMENT || !name) return; - /* - * Look for the attribute... - */ - - for (i = node->value.element.num_attrs, attr = node->value.element.attrs; - i > 0; - i --, attr ++) + // Look for the attribute... + for (i = node->value.element.num_attrs, attr = node->value.element.attrs; i > 0; i --, attr ++) { -#ifdef DEBUG - printf(" %s=\"%s\"\n", attr->name, attr->value); -#endif /* DEBUG */ + MXML_DEBUG("mxmlElementDeleteAttr: %s=\"%s\"\n", attr->name, attr->value); if (!strcmp(attr->name, name)) { - /* - * Delete this attribute... - */ - + // Delete this attribute... free(attr->name); free(attr->value); @@ -85,82 +62,60 @@ mxmlElementDeleteAttr(mxml_node_t *node,/* I - Element */ } -/* - * 'mxmlElementGetAttr()' - Get an attribute. - * - * This function returns @code NULL@ if the node is not an element or the - * named attribute does not exist. - */ +// +// 'mxmlElementGetAttr()' - Get an attribute. +// +// This function returns @code NULL@ if the node is not an element or the +// named attribute does not exist. +// -const char * /* O - Attribute value or @code NULL@ */ -mxmlElementGetAttr(mxml_node_t *node, /* I - Element node */ - const char *name) /* I - Name of attribute */ +const char * // O - Attribute value or @code NULL@ +mxmlElementGetAttr(mxml_node_t *node, // I - Element node + const char *name) // I - Name of attribute { - int i; /* Looping var */ - _mxml_attr_t *attr; /* Cirrent attribute */ - + int i; // Looping var + _mxml_attr_t *attr; // Cirrent attribute -#ifdef DEBUG - fprintf(stderr, "mxmlElementGetAttr(node=%p, name=\"%s\")\n", - node, name ? name : "(null)"); -#endif /* DEBUG */ - /* - * Range check input... - */ + MXML_DEBUG("mxmlElementGetAttr(node=%p, name=\"%s\")\n", node, name ? name : "(null)"); - if (!node || node->type != MXML_ELEMENT || !name) + // Range check input... + if (!node || node->type != MXML_TYPE_ELEMENT || !name) return (NULL); - /* - * Look for the attribute... - */ - - for (i = node->value.element.num_attrs, attr = node->value.element.attrs; - i > 0; - i --, attr ++) + // Look for the attribute... + for (i = node->value.element.num_attrs, attr = node->value.element.attrs; i > 0; i --, attr ++) { -#ifdef DEBUG - printf(" %s=\"%s\"\n", attr->name, attr->value); -#endif /* DEBUG */ + MXML_DEBUG("mxmlElementGetAttr: %s=\"%s\"\n", attr->name, attr->value); if (!strcmp(attr->name, name)) { -#ifdef DEBUG - printf(" Returning \"%s\"!\n", attr->value); -#endif /* DEBUG */ + MXML_DEBUG("mxmlElementGetAttr: Returning \"%s\".\n", attr->value); return (attr->value); } } - /* - * Didn't find attribute, so return NULL... - */ - -#ifdef DEBUG - puts(" Returning NULL!\n"); -#endif /* DEBUG */ + // Didn't find attribute, so return NULL... + MXML_DEBUG("mxmlElementGetAttr: Returning NULL.\n"); return (NULL); } -/* - * 'mxmlElementGetAttrByIndex()' - Get an element attribute by index. - * - * The index ("idx") is 0-based. @code NULL@ is returned if the specified index - * is out of range. - * - * @since Mini-XML 2.11@ - */ +// +// 'mxmlElementGetAttrByIndex()' - Get an element attribute by index. +// +// The index ("idx") is 0-based. @code NULL@ is returned if the specified index +// is out of range. +// -const char * /* O - Attribute value */ +const char * // O - Attribute value mxmlElementGetAttrByIndex( - mxml_node_t *node, /* I - Node */ - int idx, /* I - Attribute index, starting at 0 */ - const char **name) /* O - Attribute name */ + mxml_node_t *node, // I - Node + int idx, // I - Attribute index, starting at 0 + 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); if (name) @@ -170,50 +125,42 @@ mxmlElementGetAttrByIndex( } -/* - * 'mxmlElementGetAttrCount()' - Get the number of element attributes. - * - * @since Mini-XML 2.11@ - */ +// +// 'mxmlElementGetAttrCount()' - Get the number of element attributes. +// -int /* O - Number of attributes */ +int // O - Number of attributes 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); else return (0); } -/* - * 'mxmlElementSetAttr()' - Set an attribute. - * - * If the named attribute already exists, the value of the attribute - * is replaced by the new string value. The string value is copied - * into the element node. This function does nothing if the node is - * not an element. - */ +// +// 'mxmlElementSetAttr()' - Set an attribute. +// +// If the named attribute already exists, the value of the attribute +// is replaced by the new string value. The string value is copied +// into the element node. This function does nothing if the node is +// not an element. +// void -mxmlElementSetAttr(mxml_node_t *node, /* I - Element node */ - const char *name, /* I - Name of attribute */ - const char *value) /* I - Attribute value */ +mxmlElementSetAttr(mxml_node_t *node, // I - Element node + const char *name, // I - Name of attribute + const char *value) // I - Attribute value { - char *valuec; /* Copy of value */ + char *valuec; // Copy of value -#ifdef DEBUG - fprintf(stderr, "mxmlElementSetAttr(node=%p, name=\"%s\", value=\"%s\")\n", - node, name ? name : "(null)", value ? value : "(null)"); -#endif /* DEBUG */ + MXML_DEBUG("mxmlElementSetAttr(node=%p, name=\"%s\", value=\"%s\")\n", node, name ? name : "(null)", value ? value : "(null)"); - /* - * Range check input... - */ - - if (!node || node->type != MXML_ELEMENT || !name) + // Range check input... + if (!node || node->type != MXML_TYPE_ELEMENT || !name) return; if (value) @@ -225,109 +172,85 @@ mxmlElementSetAttr(mxml_node_t *node, /* I - Element node */ } } else + { valuec = NULL; + } if (mxml_set_attr(node, name, valuec)) free(valuec); } -/* - * 'mxmlElementSetAttrf()' - Set an attribute with a formatted value. - * - * If the named attribute already exists, the value of the attribute - * is replaced by the new formatted string. The formatted string value is - * copied into the element node. This function does nothing if the node - * is not an element. - * - * @since Mini-XML 2.3@ - */ +// +// 'mxmlElementSetAttrf()' - Set an attribute with a formatted value. +// +// If the named attribute already exists, the value of the attribute +// is replaced by the new formatted string. The formatted string value is +// copied into the element node. This function does nothing if the node +// is not an element. +// void -mxmlElementSetAttrf(mxml_node_t *node, /* I - Element node */ - const char *name, /* I - Name of attribute */ - const char *format,/* I - Printf-style attribute value */ - ...) /* I - Additional arguments as needed */ +mxmlElementSetAttrf(mxml_node_t *node, // I - Element node + const char *name, // I - Name of attribute + const char *format,// I - Printf-style attribute value + ...) // I - Additional arguments as needed { - va_list ap; /* Argument pointer */ - char *value; /* Value */ - + va_list ap; // Argument pointer + char buffer[16384]; // Format buffer + char *value; // Value -#ifdef DEBUG - fprintf(stderr, - "mxmlElementSetAttrf(node=%p, name=\"%s\", format=\"%s\", ...)\n", - node, name ? name : "(null)", format ? format : "(null)"); -#endif /* DEBUG */ - /* - * Range check input... - */ + MXML_DEBUG("mxmlElementSetAttrf(node=%p, name=\"%s\", format=\"%s\", ...)\n", node, name ? name : "(null)", format ? format : "(null)"); - if (!node || node->type != MXML_ELEMENT || !name || !format) + // Range check input... + if (!node || node->type != MXML_TYPE_ELEMENT || !name || !format) return; - /* - * Format the value... - */ - + // Format the value... va_start(ap, format); - value = _mxml_vstrdupf(format, ap); + vsnprintf(buffer, sizeof(buffer), format, ap); va_end(ap); - if (!value) - mxml_error("Unable to allocate memory for attribute '%s' in element %s.", - name, node->value.element.name); + if ((value = strdup(buffer)) == NULL) + mxml_error("Unable to allocate memory for attribute '%s' in element %s.", name, node->value.element.name); else if (mxml_set_attr(node, name, 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 */ -mxml_set_attr(mxml_node_t *node, /* I - Element node */ - const char *name, /* I - Attribute name */ - char *value) /* I - Attribute value */ +static int // O - 0 on success, -1 on failure +mxml_set_attr(mxml_node_t *node, // I - Element node + const char *name, // I - Attribute name + char *value) // I - Attribute value { - int i; /* Looping var */ - _mxml_attr_t *attr; /* New attribute */ + int i; // Looping var + _mxml_attr_t *attr; // New attribute - /* - * Look for the attribute... - */ - - for (i = node->value.element.num_attrs, attr = node->value.element.attrs; - i > 0; - i --, attr ++) + // Look for the attribute... + for (i = node->value.element.num_attrs, attr = node->value.element.attrs; i > 0; i --, attr ++) + { if (!strcmp(attr->name, name)) { - /* - * Free the old value as needed... - */ - + // Free the old value as needed... free(attr->value); attr->value = value; return (0); } + } - /* - * Add a new attribute... - */ - - 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)); + // Add a new attribute... + attr = realloc(node->value.element.attrs, (node->value.element.num_attrs + 1) * sizeof(_mxml_attr_t)); if (!attr) { - mxml_error("Unable to allocate memory for attribute '%s' in element %s.", - name, node->value.element.name); + mxml_error("Unable to allocate memory for attribute '%s' in element %s.", name, node->value.element.name); return (-1); } @@ -336,8 +259,7 @@ mxml_set_attr(mxml_node_t *node, /* I - Element node */ if ((attr->name = strdup(name)) == NULL) { - mxml_error("Unable to allocate memory for attribute '%s' in element %s.", - name, node->value.element.name); + mxml_error("Unable to allocate memory for attribute '%s' in element %s.", name, node->value.element.name); return (-1); } diff --git a/mxml-entity.c b/mxml-entity.c index 3b17d1e..76fdd0b 100644 --- a/mxml-entity.c +++ b/mxml-entity.c @@ -1,31 +1,27 @@ -/* - * Character entity support code 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... - */ +// +// Character entity support code for Mini-XML, a small XML file parsing library. +// +// https://www.msweet.org/mxml +// +// Copyright © 2003-2024 by Michael R Sweet. +// +// Licensed under Apache License v2.0. See the file "LICENSE" for more +// information. +// #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( - 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(); - /* Global data */ + // Global data 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. - * - * If val does not need to be represented by a named entity, @code NULL@ is returned. - */ +// +// '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. +// -const char * /* O - Entity name or @code NULL@ */ -mxmlEntityGetName(int val) /* I - Character value */ +const char * // O - Entity name or @code NULL@ +mxmlEntityGetName(int val) // I - Character value { switch (val) { @@ -73,76 +69,76 @@ mxmlEntityGetName(int val) /* I - Character value */ } -/* - * 'mxmlEntityGetValue()' - Get the character corresponding to a named entity. - * - * The entity name can also be a numeric constant. -1 is returned if the - * name is not known. - */ +// +// 'mxmlEntityGetValue()' - Get the character corresponding to a named entity. +// +// The entity name can also be a numeric constant. -1 is returned if the +// name is not known. +// -int /* O - Character value or -1 on error */ -mxmlEntityGetValue(const char *name) /* I - Entity name */ +int // O - Character value or -1 on error +mxmlEntityGetValue(const char *name) // I - Entity name { - int i; /* Looping var */ - int ch; /* Character value */ + int i; // Looping var + int ch; // Character value _mxml_global_t *global = _mxml_global(); - /* Global data */ + // Global data for (i = 0; i < global->num_entity_cbs; i ++) + { if ((ch = (global->entity_cbs[i])(name)) >= 0) return (ch); + } return (-1); } -/* - * 'mxmlEntityRemoveCallback()' - Remove a callback. - */ +// +// 'mxmlEntityRemoveCallback()' - Remove a callback. +// void 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(); - /* Global data */ + // Global data for (i = 0; i < global->num_entity_cbs; i ++) + { if (cb == global->entity_cbs[i]) { - /* - * Remove the callback... - */ - + // Remove the callback... global->num_entity_cbs --; if (i < global->num_entity_cbs) - memmove(global->entity_cbs + i, global->entity_cbs + i + 1, - (global->num_entity_cbs - i) * sizeof(global->entity_cbs[0])); + memmove(global->entity_cbs + i, global->entity_cbs + i + 1, (global->num_entity_cbs - i) * sizeof(global->entity_cbs[0])); return; } + } } -/* - * '_mxml_entity_cb()' - Lookup standard (X)HTML entities. - */ +// +// '_mxml_entity_cb()' - Lookup standard (X)HTML entities. +// -int /* O - Unicode value or -1 */ -_mxml_entity_cb(const char *name) /* I - Entity name */ +int // O - Unicode value or -1 +_mxml_entity_cb(const char *name) // I - Entity name { - int diff, /* Difference between names */ - current, /* Current entity in search */ - first, /* First entity in search */ - last; /* Last entity in search */ + int diff, // Difference between names + current, // Current entity in search + first, // First entity in search + last; // Last entity in search static const struct { - const char *name; /* Entity name */ - int val; /* Character value */ + const char *name; // Entity name + int val; // Character value } entities[] = { { "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; last = (int)(sizeof(entities) / sizeof(entities[0]) - 1); @@ -424,11 +417,7 @@ _mxml_entity_cb(const char *name) /* I - Entity name */ 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)) return (entities[first].val); else if (!strcmp(name, entities[last].name)) diff --git a/mxml-file.c b/mxml-file.c index 07bdc24..10111e5 100644 --- a/mxml-file.c +++ b/mxml-file.c @@ -1,59 +1,55 @@ -/* - * File loading code for Mini-XML, a small XML file parsing library. - * - * https://www.msweet.org/mxml - * - * Copyright © 2003-2021 by Michael R Sweet. - * - * Licensed under Apache License v2.0. See the file "LICENSE" for more - * information. - */ - -/* - * Include necessary headers... - */ +// +// File loading code for Mini-XML, a small XML file parsing library. +// +// https://www.msweet.org/mxml +// +// Copyright © 2003-2024 by Michael R Sweet. +// +// Licensed under Apache License v2.0. See the file "LICENSE" for more +// information. +// #ifndef _WIN32 # include -#endif /* !_WIN32 */ +#endif // !_WIN32 #include "mxml-private.h" -/* - * Character encoding... - */ +// +// Character encoding... +// -#define ENCODE_UTF8 0 /* UTF-8 */ -#define ENCODE_UTF16BE 1 /* UTF-16 Big-Endian */ -#define ENCODE_UTF16LE 2 /* UTF-16 Little-Endian */ +#define ENCODE_UTF8 0 // UTF-8 +#define ENCODE_UTF16BE 1 // UTF-16 Big-Endian +#define ENCODE_UTF16LE 2 // UTF-16 Little-Endian -/* - * Macro to test for a bad XML character... - */ +// +// Macro to test for a bad XML character... +// #define mxml_bad_char(ch) ((ch) < ' ' && (ch) != '\n' && (ch) != '\r' && (ch) != '\t') -/* - * Types and structures... - */ +// +// Types and structures... +// typedef int (*_mxml_getc_cb_t)(void *, int *); typedef int (*_mxml_putc_cb_t)(int, void *); -typedef struct _mxml_fdbuf_s /**** File descriptor buffer ****/ +typedef struct _mxml_fdbuf_s // File descriptor buffer { - int fd; /* File descriptor */ - unsigned char *current, /* Current position in buffer */ - *end, /* End of buffer */ - buffer[8192]; /* Character buffer */ + int fd; // File descriptor + unsigned char *current, // Current position in buffer + *end, // End of buffer + buffer[8192]; // Character buffer } _mxml_fdbuf_t; -/* - * Local functions... - */ +// +// Local functions... +// static int mxml_add_char(int ch, char **ptr, char **buffer, int *bufsize); static int mxml_fd_getc(void *p, int *encoding); @@ -77,140 +73,124 @@ static int mxml_write_string(const char *s, void *p, _mxml_putc_cb_t putc_cb); static int mxml_write_ws(mxml_node_t *node, void *p, mxml_save_cb_t cb, int ws, int col, _mxml_putc_cb_t putc_cb); -/* - * 'mxmlLoadFd()' - Load a file descriptor into an XML node tree. - * - * The nodes in the specified file are added to the specified top node. - * If no top node is provided, the XML file MUST be well-formed with a - * single parent node like for the entire file. The callback - * function returns the value type that should be used for child nodes. - * The constants @code MXML_INTEGER_CALLBACK@, @code MXML_OPAQUE_CALLBACK@, - * @code MXML_REAL_CALLBACK@, and @code MXML_TEXT_CALLBACK@ are defined for - * loading child (data) nodes of the specified type. - * - * Note: The most common programming error when using the Mini-XML library is - * to load an XML file using the @code MXML_TEXT_CALLBACK@, which returns inline - * text as a series of whitespace-delimited words, instead of using the - * @code MXML_OPAQUE_CALLBACK@ which returns the inline text as a single string - * (including whitespace). - */ - -mxml_node_t * /* O - First node or @code NULL@ if the file could not be read. */ -mxmlLoadFd(mxml_node_t *top, /* I - Top node */ - int fd, /* I - File descriptor to read from */ - mxml_load_cb_t cb) /* I - Callback function or constant */ +// +// 'mxmlLoadFd()' - Load a file descriptor into an XML node tree. +// +// The nodes in the specified file are added to the specified top node. +// If no top node is provided, the XML file MUST be well-formed with a +// single parent node like for the entire file. The callback +// function returns the value type that should be used for child nodes. +// The constants `MXML_INTEGER_CALLBACK`, `MXML_TYPE_OPAQUE_CALLBACK`, +// `MXML_REAL_CALLBACK`, and `MXML_TYPE_TEXT_CALLBACK` are defined for +// loading child (data) nodes of the specified type. +// +// Note: The most common programming error when using the Mini-XML library is +// to load an XML file using the `MXML_TEXT_CALLBACK`, which returns inline +// text as a series of whitespace-delimited words, instead of using the +// `MXML_OPAQUE_CALLBACK` which returns the inline text as a single string +// (including whitespace). +// + +mxml_node_t * // O - First node or `NULL` if the file could not be read. +mxmlLoadFd(mxml_node_t *top, // I - Top node + int fd, // I - File descriptor to read from + mxml_load_cb_t cb) // I - Callback function or constant { - _mxml_fdbuf_t buf; /* File descriptor buffer */ + _mxml_fdbuf_t buf; // File descriptor buffer - /* - * Initialize the file descriptor buffer... - */ - + // Initialize the file descriptor buffer... buf.fd = fd; buf.current = buf.buffer; buf.end = buf.buffer; - /* - * Read the XML data... - */ - + // Read the XML data... return (mxml_load_data(top, &buf, cb, mxml_fd_getc, MXML_NO_CALLBACK, NULL)); } -/* - * 'mxmlLoadFile()' - Load a file into an XML node tree. - * - * The nodes in the specified file are added to the specified top node. - * If no top node is provided, the XML file MUST be well-formed with a - * single parent node like for the entire file. The callback - * function returns the value type that should be used for child nodes. - * The constants @code MXML_INTEGER_CALLBACK@, @code MXML_OPAQUE_CALLBACK@, - * @code MXML_REAL_CALLBACK@, and @code MXML_TEXT_CALLBACK@ are defined for - * loading child (data) nodes of the specified type. - * - * Note: The most common programming error when using the Mini-XML library is - * to load an XML file using the @code MXML_TEXT_CALLBACK@, which returns inline - * text as a series of whitespace-delimited words, instead of using the - * @code MXML_OPAQUE_CALLBACK@ which returns the inline text as a single string - * (including whitespace). - */ - -mxml_node_t * /* O - First node or @code NULL@ if the file could not be read. */ -mxmlLoadFile(mxml_node_t *top, /* I - Top node */ - FILE *fp, /* I - File to read from */ - mxml_load_cb_t cb) /* I - Callback function or constant */ +// +// 'mxmlLoadFile()' - Load a file into an XML node tree. +// +// The nodes in the specified file are added to the specified top node. +// If no top node is provided, the XML file MUST be well-formed with a +// single parent node like for the entire file. The callback +// function returns the value type that should be used for child nodes. +// The constants `MXML_INTEGER_CALLBACK`, `MXML_TYPE_OPAQUE_CALLBACK`, +// `MXML_REAL_CALLBACK`, and `MXML_TYPE_TEXT_CALLBACK` are defined for +// loading child (data) nodes of the specified type. +// +// Note: The most common programming error when using the Mini-XML library is +// to load an XML file using the `MXML_TEXT_CALLBACK`, which returns inline +// text as a series of whitespace-delimited words, instead of using the +// `MXML_OPAQUE_CALLBACK` which returns the inline text as a single string +// (including whitespace). +// + +mxml_node_t * // O - First node or `NULL` if the file could not be read. +mxmlLoadFile(mxml_node_t *top, // I - Top node + FILE *fp, // I - File to read from + mxml_load_cb_t cb) // I - Callback function or constant { - /* - * Read the XML data... - */ - + // Read the XML data... return (mxml_load_data(top, fp, cb, mxml_file_getc, MXML_NO_CALLBACK, NULL)); } -/* - * 'mxmlLoadString()' - Load a string into an XML node tree. - * - * The nodes in the specified string are added to the specified top node. - * If no top node is provided, the XML string MUST be well-formed with a - * single parent node like for the entire string. The callback - * function returns the value type that should be used for child nodes. - * The constants @code MXML_INTEGER_CALLBACK@, @code MXML_OPAQUE_CALLBACK@, - * @code MXML_REAL_CALLBACK@, and @code MXML_TEXT_CALLBACK@ are defined for - * loading child (data) nodes of the specified type. - * - * Note: The most common programming error when using the Mini-XML library is - * to load an XML file using the @code MXML_TEXT_CALLBACK@, which returns inline - * text as a series of whitespace-delimited words, instead of using the - * @code MXML_OPAQUE_CALLBACK@ which returns the inline text as a single string - * (including whitespace). - */ - -mxml_node_t * /* O - First node or @code NULL@ if the string has errors. */ -mxmlLoadString(mxml_node_t *top, /* I - Top node */ - const char *s, /* I - String to load */ - mxml_load_cb_t cb) /* I - Callback function or constant */ +// +// 'mxmlLoadString()' - Load a string into an XML node tree. +// +// The nodes in the specified string are added to the specified top node. +// If no top node is provided, the XML string MUST be well-formed with a +// single parent node like for the entire string. The callback +// function returns the value type that should be used for child nodes. +// The constants `MXML_INTEGER_CALLBACK`, `MXML_TYPE_OPAQUE_CALLBACK`, +// `MXML_REAL_CALLBACK`, and `MXML_TYPE_TEXT_CALLBACK` are defined for +// loading child (data) nodes of the specified type. +// +// Note: The most common programming error when using the Mini-XML library is +// to load an XML file using the `MXML_TEXT_CALLBACK`, which returns inline +// text as a series of whitespace-delimited words, instead of using the +// `MXML_OPAQUE_CALLBACK` which returns the inline text as a single string +// (including whitespace). +// + +mxml_node_t * // O - First node or `NULL` if the string has errors. +mxmlLoadString(mxml_node_t *top, // I - Top node + const char *s, // I - String to load + mxml_load_cb_t cb) // I - Callback function or constant { - /* - * Read the XML data... - */ - - return (mxml_load_data(top, (void *)&s, cb, mxml_string_getc, MXML_NO_CALLBACK, - NULL)); + // Read the XML data... + return (mxml_load_data(top, (void *)&s, cb, mxml_string_getc, MXML_NO_CALLBACK, NULL)); } -/* - * 'mxmlSaveAllocString()' - Save an XML tree to an allocated string. - * - * This function returns a pointer to a string containing the textual - * representation of the XML node tree. The string should be freed - * using `free()` when you are done with it. `NULL` is returned if the node - * would produce an empty string or if the string cannot be allocated. - * - * The callback argument specifies a function that returns a whitespace - * string or `NULL` before and after each element. If `MXML_NO_CALLBACK` - * is specified, whitespace will only be added before `MXML_TEXT` nodes - * with leading whitespace and before attribute names inside opening - * element tags. - */ - -char * /* O - Allocated string or @code NULL@ */ +// +// 'mxmlSaveAllocString()' - Save an XML tree to an allocated string. +// +// This function returns a pointer to a string containing the textual +// representation of the XML node tree. The string should be freed +// using `free()` when you are done with it. `NULL` is returned if the node +// would produce an empty string or if the string cannot be allocated. +// +// The callback argument specifies a function that returns a whitespace +// string or `NULL` before and after each element. If `MXML_NO_CALLBACK` +// is specified, whitespace will only be added before `MXML_TYPE_TEXT` nodes +// with leading whitespace and before attribute names inside opening +// element tags. +// + +char * // O - Allocated string or `NULL` mxmlSaveAllocString( - mxml_node_t *node, /* I - Node to write */ - mxml_save_cb_t cb) /* I - Whitespace callback or @code MXML_NO_CALLBACK@ */ + mxml_node_t *node, // I - Node to write + mxml_save_cb_t cb) // I - Whitespace callback or `MXML_NO_CALLBACK` { - int bytes; /* Required bytes */ - char buffer[8192]; /* Temporary buffer */ - char *s; /* Allocated string */ + int bytes; // Required bytes + char buffer[8192]; // Temporary buffer + char *s; // Allocated string - /* - * Write the node to the temporary buffer... - */ - + // Write the node to the temporary buffer... bytes = mxmlSaveString(node, buffer, sizeof(buffer), cb); if (bytes <= 0) @@ -218,149 +198,124 @@ mxmlSaveAllocString( if (bytes < (int)(sizeof(buffer) - 1)) { - /* - * Node fit inside the buffer, so just duplicate that string and - * return... - */ - + // Node fit inside the buffer, so just duplicate that string and return... return (strdup(buffer)); } - /* - * Allocate a buffer of the required size and save the node to the - * new buffer... - */ - + // Allocate a buffer of the required size and save the node to the new buffer... if ((s = malloc(bytes + 1)) == NULL) return (NULL); mxmlSaveString(node, s, bytes + 1, cb); - /* - * Return the allocated string... - */ - + // Return the allocated string... return (s); } -/* - * 'mxmlSaveFd()' - Save an XML tree to a file descriptor. - * - * The callback argument specifies a function that returns a whitespace - * string or NULL before and after each element. If @code MXML_NO_CALLBACK@ - * is specified, whitespace will only be added before @code MXML_TEXT@ nodes - * with leading whitespace and before attribute names inside opening - * element tags. - */ - -int /* O - 0 on success, -1 on error. */ -mxmlSaveFd(mxml_node_t *node, /* I - Node to write */ - int fd, /* I - File descriptor to write to */ - mxml_save_cb_t cb) /* I - Whitespace callback or @code MXML_NO_CALLBACK@ */ +// +// 'mxmlSaveFd()' - Save an XML tree to a file descriptor. +// +// The callback argument specifies a function that returns a whitespace +// string or NULL before and after each element. If `MXML_NO_CALLBACK` +// is specified, whitespace will only be added before `MXML_TYPE_TEXT` nodes +// with leading whitespace and before attribute names inside opening +// element tags. +// + +int // O - 0 on success, -1 on error. +mxmlSaveFd(mxml_node_t *node, // I - Node to write + int fd, // I - File descriptor to write to + mxml_save_cb_t cb) // I - Whitespace callback or `MXML_NO_CALLBACK` { - int col; /* Final column */ - _mxml_fdbuf_t buf; /* File descriptor buffer */ + int col; // Final column + _mxml_fdbuf_t buf; // File descriptor buffer _mxml_global_t *global = _mxml_global(); - /* Global data */ + // Global data - /* - * Initialize the file descriptor buffer... - */ - + // Initialize the file descriptor buffer... buf.fd = fd; buf.current = buf.buffer; buf.end = buf.buffer + sizeof(buf.buffer); - /* - * Write the node... - */ - + // Write the node... if ((col = mxml_write_node(node, &buf, cb, 0, mxml_fd_putc, global)) < 0) return (-1); if (col > 0) + { if (mxml_fd_putc('\n', &buf) < 0) return (-1); + } - /* - * Flush and return... - */ - + // Flush and return... return (mxml_fd_write(&buf)); } -/* - * 'mxmlSaveFile()' - Save an XML tree to a file. - * - * The callback argument specifies a function that returns a whitespace - * string or NULL before and after each element. If @code MXML_NO_CALLBACK@ - * is specified, whitespace will only be added before @code MXML_TEXT@ nodes - * with leading whitespace and before attribute names inside opening - * element tags. - */ - -int /* O - 0 on success, -1 on error. */ -mxmlSaveFile(mxml_node_t *node, /* I - Node to write */ - FILE *fp, /* I - File to write to */ - mxml_save_cb_t cb) /* I - Whitespace callback or @code MXML_NO_CALLBACK@ */ +// +// 'mxmlSaveFile()' - Save an XML tree to a file. +// +// The callback argument specifies a function that returns a whitespace +// string or NULL before and after each element. If `MXML_NO_CALLBACK` +// is specified, whitespace will only be added before `MXML_TYPE_TEXT` nodes +// with leading whitespace and before attribute names inside opening +// element tags. +// + +int // O - 0 on success, -1 on error. +mxmlSaveFile(mxml_node_t *node, // I - Node to write + FILE *fp, // I - File to write to + mxml_save_cb_t cb) // I - Whitespace callback or `MXML_NO_CALLBACK` { - int col; /* Final column */ + int col; // Final column _mxml_global_t *global = _mxml_global(); - /* Global data */ - + // Global data - /* - * Write the node... - */ + // Write the node... if ((col = mxml_write_node(node, fp, cb, 0, mxml_file_putc, global)) < 0) return (-1); if (col > 0) + { if (putc('\n', fp) < 0) return (-1); + } - /* - * Return 0 (success)... - */ - + // Return 0 (success)... return (0); } -/* - * 'mxmlSaveString()' - Save an XML node tree to a string. - * - * This function returns the total number of bytes that would be - * required for the string but only copies (bufsize - 1) characters - * into the specified buffer. - * - * The callback argument specifies a function that returns a whitespace - * string or NULL before and after each element. If @code MXML_NO_CALLBACK@ - * is specified, whitespace will only be added before @code MXML_TEXT@ nodes - * with leading whitespace and before attribute names inside opening - * element tags. - */ - -int /* O - Size of string */ -mxmlSaveString(mxml_node_t *node, /* I - Node to write */ - char *buffer, /* I - String buffer */ - int bufsize, /* I - Size of string buffer */ - mxml_save_cb_t cb) /* I - Whitespace callback or @code MXML_NO_CALLBACK@ */ +// +// 'mxmlSaveString()' - Save an XML node tree to a string. +// +// This function returns the total number of bytes that would be +// required for the string but only copies (bufsize - 1) characters +// into the specified buffer. +// +// The callback argument specifies a function that returns a whitespace +// string or NULL before and after each element. If `MXML_NO_CALLBACK` +// is specified, whitespace will only be added before `MXML_TYPE_TEXT` nodes +// with leading whitespace and before attribute names inside opening +// element tags. +// + +int // O - Size of string +mxmlSaveString(mxml_node_t *node, // I - Node to write + char *buffer, // I - String buffer + int bufsize, // I - Size of string buffer + mxml_save_cb_t cb) // I - Whitespace callback or `MXML_NO_CALLBACK` { - int col; /* Final column */ - char *ptr[2]; /* Pointers for putc_cb */ + int col; // Final column + char *ptr[2]; // Pointers for putc_cb _mxml_global_t *global = _mxml_global(); - /* Global data */ - + // Global data - /* - * Write the node... - */ + // Write the node... ptr[0] = buffer; ptr[1] = buffer + bufsize; @@ -370,159 +325,137 @@ mxmlSaveString(mxml_node_t *node, /* I - Node to write */ if (col > 0) mxml_string_putc('\n', ptr); - /* - * Nul-terminate the buffer... - */ - + // Nul-terminate the buffer... if (ptr[0] >= ptr[1]) { if (bufsize > 0) buffer[bufsize - 1] = '\0'; } else + { ptr[0][0] = '\0'; + } - /* - * Return the number of characters... - */ - + // Return the number of characters... return ((int)(ptr[0] - buffer)); } -/* - * 'mxmlSAXLoadFd()' - Load a file descriptor into an XML node tree - * using a SAX callback. - * - * The nodes in the specified file are added to the specified top node. - * If no top node is provided, the XML file MUST be well-formed with a - * single parent node like for the entire file. The callback - * function returns the value type that should be used for child nodes. - * The constants @code MXML_INTEGER_CALLBACK@, @code MXML_OPAQUE_CALLBACK@, - * @code MXML_REAL_CALLBACK@, and @code MXML_TEXT_CALLBACK@ are defined for - * loading child nodes of the specified type. - * - * The SAX callback must call @link mxmlRetain@ for any nodes that need to - * be kept for later use. Otherwise, nodes are deleted when the parent - * node is closed or after each data, comment, CDATA, or directive node. - * - * @since Mini-XML 2.3@ - */ - -mxml_node_t * /* O - First node or @code NULL@ if the file could not be read. */ -mxmlSAXLoadFd(mxml_node_t *top, /* I - Top node */ - int fd, /* I - File descriptor to read from */ - mxml_load_cb_t cb, /* I - Callback function or constant */ - mxml_sax_cb_t sax_cb, /* I - SAX callback or @code MXML_NO_CALLBACK@ */ - void *sax_data) /* I - SAX user data */ +// +// 'mxmlSAXLoadFd()' - Load a file descriptor into an XML node tree +// using a SAX callback. +// +// The nodes in the specified file are added to the specified top node. +// If no top node is provided, the XML file MUST be well-formed with a +// single parent node like for the entire file. The callback +// function returns the value type that should be used for child nodes. +// The constants `MXML_INTEGER_CALLBACK`, `MXML_TYPE_OPAQUE_CALLBACK`, +// `MXML_REAL_CALLBACK`, and `MXML_TYPE_TEXT_CALLBACK` are defined for +// loading child nodes of the specified type. +// +// The SAX callback must call @link mxmlRetain@ for any nodes that need to +// be kept for later use. Otherwise, nodes are deleted when the parent +// node is closed or after each data, comment, CDATA, or directive node. +// + +mxml_node_t * // O - First node or `NULL` if the file could not be read. +mxmlSAXLoadFd(mxml_node_t *top, // I - Top node + int fd, // I - File descriptor to read from + mxml_load_cb_t cb, // I - Callback function or constant + mxml_sax_cb_t sax_cb, // I - SAX callback or `MXML_NO_CALLBACK` + void *sax_data) // I - SAX user data { - _mxml_fdbuf_t buf; /* File descriptor buffer */ + _mxml_fdbuf_t buf; // File descriptor buffer - /* - * Initialize the file descriptor buffer... - */ - + // Initialize the file descriptor buffer... buf.fd = fd; buf.current = buf.buffer; buf.end = buf.buffer; - /* - * Read the XML data... - */ - + // Read the XML data... return (mxml_load_data(top, &buf, cb, mxml_fd_getc, sax_cb, sax_data)); } -/* - * 'mxmlSAXLoadFile()' - Load a file into an XML node tree - * using a SAX callback. - * - * The nodes in the specified file are added to the specified top node. - * If no top node is provided, the XML file MUST be well-formed with a - * single parent node like for the entire file. The callback - * function returns the value type that should be used for child nodes. - * The constants @code MXML_INTEGER_CALLBACK@, @code MXML_OPAQUE_CALLBACK@, - * @code MXML_REAL_CALLBACK@, and @code MXML_TEXT_CALLBACK@ are defined for - * loading child nodes of the specified type. - * - * The SAX callback must call @link mxmlRetain@ for any nodes that need to - * be kept for later use. Otherwise, nodes are deleted when the parent - * node is closed or after each data, comment, CDATA, or directive node. - * - * @since Mini-XML 2.3@ - */ - -mxml_node_t * /* O - First node or @code NULL@ if the file could not be read. */ +// +// 'mxmlSAXLoadFile()' - Load a file into an XML node tree +// using a SAX callback. +// +// The nodes in the specified file are added to the specified top node. +// If no top node is provided, the XML file MUST be well-formed with a +// single parent node like for the entire file. The callback +// function returns the value type that should be used for child nodes. +// The constants `MXML_INTEGER_CALLBACK`, `MXML_TYPE_OPAQUE_CALLBACK`, +// `MXML_REAL_CALLBACK`, and `MXML_TYPE_TEXT_CALLBACK` are defined for +// loading child nodes of the specified type. +// +// The SAX callback must call @link mxmlRetain@ for any nodes that need to +// be kept for later use. Otherwise, nodes are deleted when the parent +// node is closed or after each data, comment, CDATA, or directive node. +// + +mxml_node_t * // O - First node or `NULL` if the file could not be read. mxmlSAXLoadFile( - mxml_node_t *top, /* I - Top node */ - FILE *fp, /* I - File to read from */ - mxml_load_cb_t cb, /* I - Callback function or constant */ - mxml_sax_cb_t sax_cb, /* I - SAX callback or @code MXML_NO_CALLBACK@ */ - void *sax_data) /* I - SAX user data */ + mxml_node_t *top, // I - Top node + FILE *fp, // I - File to read from + mxml_load_cb_t cb, // I - Callback function or constant + mxml_sax_cb_t sax_cb, // I - SAX callback or `MXML_NO_CALLBACK` + void *sax_data) // I - SAX user data { - /* - * Read the XML data... - */ - + // Read the XML data... return (mxml_load_data(top, fp, cb, mxml_file_getc, sax_cb, sax_data)); } -/* - * 'mxmlSAXLoadString()' - Load a string into an XML node tree - * using a SAX callback. - * - * The nodes in the specified string are added to the specified top node. - * If no top node is provided, the XML string MUST be well-formed with a - * single parent node like for the entire string. The callback - * function returns the value type that should be used for child nodes. - * The constants @code MXML_INTEGER_CALLBACK@, @code MXML_OPAQUE_CALLBACK@, - * @code MXML_REAL_CALLBACK@, and @code MXML_TEXT_CALLBACK@ are defined for - * loading child nodes of the specified type. - * - * The SAX callback must call @link mxmlRetain@ for any nodes that need to - * be kept for later use. Otherwise, nodes are deleted when the parent - * node is closed or after each data, comment, CDATA, or directive node. - * - * @since Mini-XML 2.3@ - */ - -mxml_node_t * /* O - First node or @code NULL@ if the string has errors. */ +// +// 'mxmlSAXLoadString()' - Load a string into an XML node tree +// using a SAX callback. +// +// The nodes in the specified string are added to the specified top node. +// If no top node is provided, the XML string MUST be well-formed with a +// single parent node like for the entire string. The callback +// function returns the value type that should be used for child nodes. +// The constants `MXML_INTEGER_CALLBACK`, `MXML_TYPE_OPAQUE_CALLBACK`, +// `MXML_REAL_CALLBACK`, and `MXML_TYPE_TEXT_CALLBACK` are defined for +// loading child nodes of the specified type. +// +// The SAX callback must call @link mxmlRetain@ for any nodes that need to +// be kept for later use. Otherwise, nodes are deleted when the parent +// node is closed or after each data, comment, CDATA, or directive node. +// + +mxml_node_t * // O - First node or `NULL` if the string has errors. mxmlSAXLoadString( - mxml_node_t *top, /* I - Top node */ - const char *s, /* I - String to load */ - mxml_load_cb_t cb, /* I - Callback function or constant */ - mxml_sax_cb_t sax_cb, /* I - SAX callback or @code MXML_NO_CALLBACK@ */ - void *sax_data) /* I - SAX user data */ + mxml_node_t *top, // I - Top node + const char *s, // I - String to load + mxml_load_cb_t cb, // I - Callback function or constant + mxml_sax_cb_t sax_cb, // I - SAX callback or `MXML_NO_CALLBACK` + void *sax_data) // I - SAX user data { - /* - * Read the XML data... - */ - + // Read the XML data... return (mxml_load_data(top, (void *)&s, cb, mxml_string_getc, sax_cb, sax_data)); } -/* - * 'mxmlSetCustomHandlers()' - Set the handling functions for custom data. - * - * The load function accepts a node pointer and a data string and must - * return 0 on success and non-zero on error. - * - * The save function accepts a node pointer and must return a malloc'd - * string on success and @code NULL@ on error. - * - */ +// +// 'mxmlSetCustomHandlers()' - Set the handling functions for custom data. +// +// The load function accepts a node pointer and a data string and must +// return 0 on success and non-zero on error. +// +// The save function accepts a node pointer and must return a malloc'd +// string on success and `NULL` on error. +// +// void mxmlSetCustomHandlers( - mxml_custom_load_cb_t load, /* I - Load function */ - mxml_custom_save_cb_t save) /* I - Save function */ + mxml_custom_load_cb_t load, // I - Load function + mxml_custom_save_cb_t save) // I - Save function { _mxml_global_t *global = _mxml_global(); - /* Global data */ + // Global data global->custom_load_cb = load; @@ -530,59 +463,54 @@ mxmlSetCustomHandlers( } -/* - * 'mxmlSetErrorCallback()' - Set the error message callback. - */ +// +// 'mxmlSetErrorCallback()' - Set the error message callback. +// void -mxmlSetErrorCallback(mxml_error_cb_t cb)/* I - Error callback function */ +mxmlSetErrorCallback(mxml_error_cb_t cb)// I - Error callback function { _mxml_global_t *global = _mxml_global(); - /* Global data */ + // Global data global->error_cb = cb; } -/* - * 'mxmlSetWrapMargin()' - Set the wrap margin when saving XML data. - * - * Wrapping is disabled when "column" is 0. - * - * @since Mini-XML 2.3@ - */ +// +// 'mxmlSetWrapMargin()' - Set the wrap margin when saving XML data. +// +// Wrapping is disabled when "column" is 0. +// void -mxmlSetWrapMargin(int column) /* I - Column for wrapping, 0 to disable wrapping */ +mxmlSetWrapMargin(int column) // I - Column for wrapping, 0 to disable wrapping { _mxml_global_t *global = _mxml_global(); - /* Global data */ + // Global data global->wrap = column; } -/* - * 'mxml_add_char()' - Add a character to a buffer, expanding as needed. - */ +// +// 'mxml_add_char()' - Add a character to a buffer, expanding as needed. +// -static int /* O - 0 on success, -1 on error */ -mxml_add_char(int ch, /* I - Character to add */ - char **bufptr, /* IO - Current position in buffer */ - char **buffer, /* IO - Current buffer */ - int *bufsize) /* IO - Current buffer size */ +static int // O - 0 on success, -1 on error +mxml_add_char(int ch, // I - Character to add + char **bufptr, // IO - Current position in buffer + char **buffer, // IO - Current buffer + int *bufsize) // IO - Current buffer size { - char *newbuffer; /* New buffer value */ + char *newbuffer; // New buffer value if (*bufptr >= (*buffer + *bufsize - 4)) { - /* - * Increase the size of the buffer... - */ - + // Increase the size of the buffer... if (*bufsize < 1024) (*bufsize) *= 2; else @@ -601,37 +529,25 @@ mxml_add_char(int ch, /* I - Character to add */ if (ch < 0x80) { - /* - * Single byte ASCII... - */ - + // Single byte ASCII... *(*bufptr)++ = ch; } else if (ch < 0x800) { - /* - * Two-byte UTF-8... - */ - + // Two-byte UTF-8... *(*bufptr)++ = 0xc0 | (ch >> 6); *(*bufptr)++ = 0x80 | (ch & 0x3f); } else if (ch < 0x10000) { - /* - * Three-byte UTF-8... - */ - + // Three-byte UTF-8... *(*bufptr)++ = 0xe0 | (ch >> 12); *(*bufptr)++ = 0x80 | ((ch >> 6) & 0x3f); *(*bufptr)++ = 0x80 | (ch & 0x3f); } else { - /* - * Four-byte UTF-8... - */ - + // Four-byte UTF-8... *(*bufptr)++ = 0xf0 | (ch >> 18); *(*bufptr)++ = 0x80 | ((ch >> 12) & 0x3f); *(*bufptr)++ = 0x80 | ((ch >> 6) & 0x3f); @@ -642,48 +558,41 @@ mxml_add_char(int ch, /* I - Character to add */ } -/* - * 'mxml_fd_getc()' - Read a character from a file descriptor. - */ +// +// 'mxml_fd_getc()' - Read a character from a file descriptor. +// -static int /* O - Character or EOF */ -mxml_fd_getc(void *p, /* I - File descriptor buffer */ - int *encoding) /* IO - Encoding */ +static int // O - Character or EOF +mxml_fd_getc(void *p, // I - File descriptor buffer + int *encoding) // IO - Encoding { - _mxml_fdbuf_t *buf; /* File descriptor buffer */ - int ch, /* Current character */ - temp; /* Temporary character */ - + _mxml_fdbuf_t *buf; // File descriptor buffer + int ch, // Current character + temp; // Temporary character - /* - * Grab the next character in the buffer... - */ + // Grab the next character in the buffer... buf = (_mxml_fdbuf_t *)p; if (buf->current >= buf->end) + { if (mxml_fd_read(buf) < 0) return (EOF); + } ch = *(buf->current)++; switch (*encoding) { case ENCODE_UTF8 : - /* - * Got a UTF-8 character; convert UTF-8 to Unicode and return... - */ - + // Got a UTF-8 character; convert UTF-8 to Unicode and return... if (!(ch & 0x80)) { -#if DEBUG > 1 - printf("mxml_fd_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); -#endif /* DEBUG > 1 */ + MXML_DEBUG("mxml_fd_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); if (mxml_bad_char(ch)) { - mxml_error("Bad control character 0x%02x not allowed by XML standard.", - ch); + mxml_error("Bad control character 0x%02x not allowed by XML standard.", ch); return (EOF); } @@ -691,13 +600,12 @@ mxml_fd_getc(void *p, /* I - File descriptor buffer */ } else if (ch == 0xfe) { - /* - * UTF-16 big-endian BOM? - */ - + // UTF-16 big-endian BOM? if (buf->current >= buf->end) + { if (mxml_fd_read(buf) < 0) return (EOF); + } ch = *(buf->current)++; @@ -710,13 +618,12 @@ mxml_fd_getc(void *p, /* I - File descriptor buffer */ } else if (ch == 0xff) { - /* - * UTF-16 little-endian BOM? - */ - + // UTF-16 little-endian BOM? if (buf->current >= buf->end) + { if (mxml_fd_read(buf) < 0) return (EOF); + } ch = *(buf->current)++; @@ -729,13 +636,12 @@ mxml_fd_getc(void *p, /* I - File descriptor buffer */ } else if ((ch & 0xe0) == 0xc0) { - /* - * Two-byte value... - */ - + // Two-byte value... if (buf->current >= buf->end) + { if (mxml_fd_read(buf) < 0) return (EOF); + } temp = *(buf->current)++; @@ -752,13 +658,12 @@ mxml_fd_getc(void *p, /* I - File descriptor buffer */ } else if ((ch & 0xf0) == 0xe0) { - /* - * Three-byte value... - */ - + // Three-byte value... if (buf->current >= buf->end) + { if (mxml_fd_read(buf) < 0) return (EOF); + } temp = *(buf->current)++; @@ -768,8 +673,10 @@ mxml_fd_getc(void *p, /* I - File descriptor buffer */ ch = ((ch & 0x0f) << 6) | (temp & 0x3f); if (buf->current >= buf->end) + { if (mxml_fd_read(buf) < 0) return (EOF); + } temp = *(buf->current)++; @@ -784,22 +691,18 @@ mxml_fd_getc(void *p, /* I - File descriptor buffer */ return (EOF); } - /* - * Ignore (strip) Byte Order Mark (BOM)... - */ - + // Ignore (strip) Byte Order Mark (BOM)... if (ch == 0xfeff) return (mxml_fd_getc(p, encoding)); } else if ((ch & 0xf8) == 0xf0) { - /* - * Four-byte value... - */ - + // Four-byte value... if (buf->current >= buf->end) + { if (mxml_fd_read(buf) < 0) return (EOF); + } temp = *(buf->current)++; @@ -809,8 +712,10 @@ mxml_fd_getc(void *p, /* I - File descriptor buffer */ ch = ((ch & 0x07) << 6) | (temp & 0x3f); if (buf->current >= buf->end) + { if (mxml_fd_read(buf) < 0) return (EOF); + } temp = *(buf->current)++; @@ -820,8 +725,10 @@ mxml_fd_getc(void *p, /* I - File descriptor buffer */ ch = (ch << 6) | (temp & 0x3f); if (buf->current >= buf->end) + { if (mxml_fd_read(buf) < 0) return (EOF); + } temp = *(buf->current)++; @@ -837,17 +744,18 @@ mxml_fd_getc(void *p, /* I - File descriptor buffer */ } } else + { return (EOF); + } break; case ENCODE_UTF16BE : - /* - * Read UTF-16 big-endian char... - */ - + // Read UTF-16 big-endian char... if (buf->current >= buf->end) + { if (mxml_fd_read(buf) < 0) return (EOF); + } temp = *(buf->current)++; @@ -855,27 +763,27 @@ mxml_fd_getc(void *p, /* I - File descriptor buffer */ if (mxml_bad_char(ch)) { - mxml_error("Bad control character 0x%02x not allowed by XML standard.", - ch); + mxml_error("Bad control character 0x%02x not allowed by XML standard.", ch); return (EOF); } else if (ch >= 0xd800 && ch <= 0xdbff) { - /* - * Multi-word UTF-16 char... - */ - + // Multi-word UTF-16 char... int lch; if (buf->current >= buf->end) + { if (mxml_fd_read(buf) < 0) return (EOF); + } lch = *(buf->current)++; if (buf->current >= buf->end) + { if (mxml_fd_read(buf) < 0) return (EOF); + } temp = *(buf->current)++; @@ -889,13 +797,12 @@ mxml_fd_getc(void *p, /* I - File descriptor buffer */ break; case ENCODE_UTF16LE : - /* - * Read UTF-16 little-endian char... - */ - + // Read UTF-16 little-endian char... if (buf->current >= buf->end) + { if (mxml_fd_read(buf) < 0) return (EOF); + } temp = *(buf->current)++; @@ -903,27 +810,27 @@ mxml_fd_getc(void *p, /* I - File descriptor buffer */ if (mxml_bad_char(ch)) { - mxml_error("Bad control character 0x%02x not allowed by XML standard.", - ch); + mxml_error("Bad control character 0x%02x not allowed by XML standard.", ch); return (EOF); } else if (ch >= 0xd800 && ch <= 0xdbff) { - /* - * Multi-word UTF-16 char... - */ - + // Multi-word UTF-16 char... int lch; if (buf->current >= buf->end) + { if (mxml_fd_read(buf) < 0) return (EOF); + } lch = *(buf->current)++; if (buf->current >= buf->end) + { if (mxml_fd_read(buf) < 0) return (EOF); + } temp = *(buf->current)++; @@ -937,81 +844,68 @@ mxml_fd_getc(void *p, /* I - File descriptor buffer */ break; } -#if DEBUG > 1 - printf("mxml_fd_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); -#endif /* DEBUG > 1 */ + MXML_DEBUG("mxml_fd_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); return (ch); } -/* - * 'mxml_fd_putc()' - Write a character to a file descriptor. - */ +// +// 'mxml_fd_putc()' - Write a character to a file descriptor. +// -static int /* O - 0 on success, -1 on error */ -mxml_fd_putc(int ch, /* I - Character */ - void *p) /* I - File descriptor buffer */ +static int // O - 0 on success, -1 on error +mxml_fd_putc(int ch, // I - Character + void *p) // I - File descriptor buffer { - _mxml_fdbuf_t *buf; /* File descriptor buffer */ + _mxml_fdbuf_t *buf; // File descriptor buffer - /* - * Flush the write buffer as needed... - */ - + // Flush the write buffer as needed... buf = (_mxml_fdbuf_t *)p; if (buf->current >= buf->end) + { if (mxml_fd_write(buf) < 0) return (-1); + } *(buf->current)++ = ch; - /* - * Return successfully... - */ - + // Return successfully... return (0); } -/* - * 'mxml_fd_read()' - Read a buffer of data from a file descriptor. - */ +// +// 'mxml_fd_read()' - Read a buffer of data from a file descriptor. +// -static int /* O - 0 on success, -1 on error */ -mxml_fd_read(_mxml_fdbuf_t *buf) /* I - File descriptor buffer */ +static int // O - 0 on success, -1 on error +mxml_fd_read(_mxml_fdbuf_t *buf) // I - File descriptor buffer { - int bytes; /* Bytes read... */ + int bytes; // Bytes read... - /* - * Range check input... - */ - + // Range check input... if (!buf) return (-1); - /* - * Read from the file descriptor... - */ - + // Read from the file descriptor... while ((bytes = (int)read(buf->fd, buf->buffer, sizeof(buf->buffer))) < 0) + { #ifdef EINTR if (errno != EAGAIN && errno != EINTR) #else if (errno != EAGAIN) -#endif /* EINTR */ +#endif // EINTR return (-1); + } if (bytes == 0) return (-1); - /* - * Update the pointers and return success... - */ - + // Update the pointers and return success... buf->current = buf->buffer; buf->end = buf->buffer + bytes; @@ -1019,66 +913,53 @@ mxml_fd_read(_mxml_fdbuf_t *buf) /* I - File descriptor buffer */ } -/* - * 'mxml_fd_write()' - Write a buffer of data to a file descriptor. - */ +// +// 'mxml_fd_write()' - Write a buffer of data to a file descriptor. +// -static int /* O - 0 on success, -1 on error */ -mxml_fd_write(_mxml_fdbuf_t *buf) /* I - File descriptor buffer */ +static int // O - 0 on success, -1 on error +mxml_fd_write(_mxml_fdbuf_t *buf) // I - File descriptor buffer { - int bytes; /* Bytes written */ - unsigned char *ptr; /* Pointer into buffer */ - + int bytes; // Bytes written + unsigned char *ptr; // Pointer into buffer - /* - * Range check... - */ + // Range check... if (!buf) return (-1); - /* - * Return 0 if there is nothing to write... - */ - + // Return 0 if there is nothing to write... if (buf->current == buf->buffer) return (0); - /* - * Loop until we have written everything... - */ - + // Loop until we have written everything... for (ptr = buf->buffer; ptr < buf->current; ptr += bytes) + { if ((bytes = (int)write(buf->fd, ptr, buf->current - ptr)) < 0) return (-1); + } - /* - * All done, reset pointers and return success... - */ - + // All done, reset pointers and return success... buf->current = buf->buffer; return (0); } -/* - * 'mxml_file_getc()' - Get a character from a file. - */ +// +// 'mxml_file_getc()' - Get a character from a file. +// -static int /* O - Character or EOF */ -mxml_file_getc(void *p, /* I - Pointer to file */ - int *encoding) /* IO - Encoding */ +static int // O - Character or EOF +mxml_file_getc(void *p, // I - Pointer to file + int *encoding) // IO - Encoding { - int ch, /* Character from file */ - temp; /* Temporary character */ - FILE *fp; /* Pointer to file */ - + int ch, // Character from file + temp; // Temporary character + FILE *fp; // Pointer to file - /* - * Read a character from the file and see if it is EOF or ASCII... - */ + // Read a character from the file and see if it is EOF or ASCII... fp = (FILE *)p; ch = getc(fp); @@ -1088,31 +969,21 @@ mxml_file_getc(void *p, /* I - Pointer to file */ switch (*encoding) { case ENCODE_UTF8 : - /* - * Got a UTF-8 character; convert UTF-8 to Unicode and return... - */ - + // Got a UTF-8 character; convert UTF-8 to Unicode and return... if (!(ch & 0x80)) { if (mxml_bad_char(ch)) { - mxml_error("Bad control character 0x%02x not allowed by XML standard.", - ch); + mxml_error("Bad control character 0x%02x not allowed by XML standard.", ch); return (EOF); } -#if DEBUG > 1 - printf("mxml_file_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); -#endif /* DEBUG > 1 */ - + MXML_DEBUG("mxml_file_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); return (ch); } else if (ch == 0xfe) { - /* - * UTF-16 big-endian BOM? - */ - + // UTF-16 big-endian BOM? ch = getc(fp); if (ch != 0xff) return (EOF); @@ -1123,10 +994,7 @@ mxml_file_getc(void *p, /* I - Pointer to file */ } else if (ch == 0xff) { - /* - * UTF-16 little-endian BOM? - */ - + // UTF-16 little-endian BOM? ch = getc(fp); if (ch != 0xfe) return (EOF); @@ -1137,10 +1005,7 @@ mxml_file_getc(void *p, /* I - Pointer to file */ } else if ((ch & 0xe0) == 0xc0) { - /* - * Two-byte value... - */ - + // Two-byte value... if ((temp = getc(fp)) == EOF || (temp & 0xc0) != 0x80) return (EOF); @@ -1154,10 +1019,7 @@ mxml_file_getc(void *p, /* I - Pointer to file */ } else if ((ch & 0xf0) == 0xe0) { - /* - * Three-byte value... - */ - + // Three-byte value... if ((temp = getc(fp)) == EOF || (temp & 0xc0) != 0x80) return (EOF); @@ -1174,19 +1036,13 @@ mxml_file_getc(void *p, /* I - Pointer to file */ return (EOF); } - /* - * Ignore (strip) Byte Order Mark (BOM)... - */ - + // Ignore (strip) Byte Order Mark (BOM)... if (ch == 0xfeff) return (mxml_file_getc(p, encoding)); } else if ((ch & 0xf8) == 0xf0) { - /* - * Four-byte value... - */ - + // Four-byte value... if ((temp = getc(fp)) == EOF || (temp & 0xc0) != 0x80) return (EOF); @@ -1209,28 +1065,23 @@ mxml_file_getc(void *p, /* I - Pointer to file */ } } else + { return (EOF); + } break; case ENCODE_UTF16BE : - /* - * Read UTF-16 big-endian char... - */ - + // Read UTF-16 big-endian char... ch = (ch << 8) | getc(fp); if (mxml_bad_char(ch)) { - mxml_error("Bad control character 0x%02x not allowed by XML standard.", - ch); + mxml_error("Bad control character 0x%02x not allowed by XML standard.", ch); return (EOF); } else if (ch >= 0xd800 && ch <= 0xdbff) { - /* - * Multi-word UTF-16 char... - */ - + // Multi-word UTF-16 char... int lch = getc(fp); lch = (lch << 8) | getc(fp); @@ -1242,24 +1093,17 @@ mxml_file_getc(void *p, /* I - Pointer to file */ break; case ENCODE_UTF16LE : - /* - * Read UTF-16 little-endian char... - */ - + // Read UTF-16 little-endian char... ch |= (getc(fp) << 8); if (mxml_bad_char(ch)) { - mxml_error("Bad control character 0x%02x not allowed by XML standard.", - ch); + mxml_error("Bad control character 0x%02x not allowed by XML standard.", ch); return (EOF); } else if (ch >= 0xd800 && ch <= 0xdbff) { - /* - * Multi-word UTF-16 char... - */ - + // Multi-word UTF-16 char... int lch = getc(fp); lch |= (getc(fp) << 8); @@ -1271,41 +1115,39 @@ mxml_file_getc(void *p, /* I - Pointer to file */ break; } -#if DEBUG > 1 - printf("mxml_file_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); -#endif /* DEBUG > 1 */ + MXML_DEBUG("mxml_file_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); return (ch); } -/* - * 'mxml_file_putc()' - Write a character to a file. - */ +// +// 'mxml_file_putc()' - Write a character to a file. +// -static int /* O - 0 on success, -1 on failure */ -mxml_file_putc(int ch, /* I - Character to write */ - void *p) /* I - Pointer to file */ +static int // O - 0 on success, -1 on failure +mxml_file_putc(int ch, // I - Character to write + void *p) // I - Pointer to file { return (putc(ch, (FILE *)p) == EOF ? -1 : 0); } -/* - * 'mxml_get_entity()' - Get the character corresponding to an entity... - */ +// +// 'mxml_get_entity()' - Get the character corresponding to an entity... +// -static int /* O - Character value or EOF on error */ -mxml_get_entity(mxml_node_t *parent, /* I - Parent node */ - void *p, /* I - Pointer to source */ - int *encoding, /* IO - Character encoding */ +static int // O - Character value or EOF on error +mxml_get_entity(mxml_node_t *parent, // I - Parent node + void *p, // I - Pointer to source + int *encoding, // IO - Character encoding int (*getc_cb)(void *, int *), - /* I - Get character function */ - int *line) /* IO - Current line number */ + // I - Get character function + int *line) // IO - Current line number { - int ch; /* Current character */ - char entity[64], /* Entity string */ - *entptr; /* Pointer into entity */ + int ch; // Current character + char entity[64], // Entity string + *entptr; // Pointer into entity entptr = entity; @@ -1313,9 +1155,13 @@ mxml_get_entity(mxml_node_t *parent, /* I - Parent node */ while ((ch = (*getc_cb)(p, encoding)) != EOF) { if (ch > 126 || (!isalnum(ch) && ch != '#')) + { break; + } else if (entptr < (entity + sizeof(entity) - 1)) + { *entptr++ = ch; + } else { mxml_error("Entity name too long under parent <%s> on line %d.", parent ? parent->value.element.name : "null", *line); @@ -1343,7 +1189,9 @@ mxml_get_entity(mxml_node_t *parent, /* I - Parent node */ ch = (int)strtol(entity + 1, NULL, 10); } else if ((ch = mxmlEntityGetValue(entity)) < 0) + { mxml_error("Entity name '%s;' not supported under parent <%s> on line %d.", entity, parent ? parent->value.element.name : "null", *line); + } if (mxml_bad_char(ch)) { @@ -1355,47 +1203,44 @@ mxml_get_entity(mxml_node_t *parent, /* I - Parent node */ } -/* - * 'mxml_load_data()' - Load data into an XML node tree. - */ +// +// 'mxml_load_data()' - Load data into an XML node tree. +// -static mxml_node_t * /* O - First node or NULL if the file could not be read. */ +static mxml_node_t * // O - First node or NULL if the file could not be read. mxml_load_data( - mxml_node_t *top, /* I - Top node */ - void *p, /* I - Pointer to data */ - mxml_load_cb_t cb, /* I - Callback function or MXML_NO_CALLBACK */ - _mxml_getc_cb_t getc_cb, /* I - Read function */ - mxml_sax_cb_t sax_cb, /* I - SAX callback or MXML_NO_CALLBACK */ - void *sax_data) /* I - SAX user data */ + mxml_node_t *top, // I - Top node + void *p, // I - Pointer to data + mxml_load_cb_t cb, // I - Callback function or MXML_NO_CALLBACK + _mxml_getc_cb_t getc_cb, // I - Read function + mxml_sax_cb_t sax_cb, // I - SAX callback or MXML_NO_CALLBACK + void *sax_data) // I - SAX user data { - mxml_node_t *node = NULL, /* Current node */ - *first = NULL, /* First node added */ - *parent = NULL; /* Current parent node */ - int line = 1, /* Current line number */ - ch, /* Character from file */ - whitespace; /* Non-zero if whitespace seen */ - char *buffer, /* String buffer */ - *bufptr; /* Pointer into buffer */ - int bufsize; /* Size of buffer */ - mxml_type_t type; /* Current node type */ - int encoding; /* Character encoding */ + mxml_node_t *node = NULL, // Current node + *first = NULL, // First node added + *parent = NULL; // Current parent node + int line = 1, // Current line number + ch, // Character from file + whitespace; // Non-zero if whitespace seen + char *buffer, // String buffer + *bufptr; // Pointer into buffer + int bufsize; // Size of buffer + mxml_type_t type; // Current node type + int encoding; // Character encoding _mxml_global_t *global = _mxml_global(); - /* Global data */ - static const char * const types[] = /* Type strings... */ + // Global data + static const char * const types[] = // Type strings... { - "MXML_ELEMENT", /* XML element with attributes */ - "MXML_INTEGER", /* Integer value */ - "MXML_OPAQUE", /* Opaque string */ - "MXML_REAL", /* Real value */ - "MXML_TEXT", /* Text fragment */ - "MXML_CUSTOM" /* Custom data */ + "MXML_TYPE_ELEMENT", // XML element with attributes + "MXML_TYPE_INTEGER", // Integer value + "MXML_TYPE_OPAQUE", // Opaque string + "MXML_TYPE_REAL", // Real value + "MXML_TYPE_TEXT", // Text fragment + "MXML_TYPE_CUSTOM" // Custom data }; - /* - * Read elements and other nodes from the file... - */ - + // Read elements and other nodes from the file... if ((buffer = malloc(64)) == NULL) { mxml_error("Unable to allocate string buffer."); @@ -1412,9 +1257,9 @@ mxml_load_data( if (cb && parent) type = (*cb)(parent); else if (parent) - type = MXML_TEXT; + type = MXML_TYPE_TEXT; else - type = MXML_IGNORE; + type = MXML_TYPE_IGNORE; if ((ch = (*getc_cb)(p, &encoding)) == EOF) { @@ -1431,40 +1276,34 @@ mxml_load_data( do { if ((ch == '<' || - (mxml_isspace(ch) && type != MXML_OPAQUE && type != MXML_CUSTOM)) && + (mxml_isspace(ch) && type != MXML_TYPE_OPAQUE && type != MXML_TYPE_CUSTOM)) && bufptr > buffer) { - /* - * Add a new value node... - */ - + // Add a new value node... *bufptr = '\0'; switch (type) { - case MXML_INTEGER : + case MXML_TYPE_INTEGER : node = mxmlNewInteger(parent, (int)strtol(buffer, &bufptr, 0)); break; - case MXML_OPAQUE : + case MXML_TYPE_OPAQUE : node = mxmlNewOpaque(parent, buffer); break; - case MXML_REAL : + case MXML_TYPE_REAL : node = mxmlNewReal(parent, strtod(buffer, &bufptr)); break; - case MXML_TEXT : + case MXML_TYPE_TEXT : node = mxmlNewText(parent, whitespace, buffer); break; - case MXML_CUSTOM : + case MXML_TYPE_CUSTOM : if (global->custom_load_cb) { - /* - * Use the callback to fill in the custom data... - */ - + // Use the callback to fill in the custom data... node = mxmlNewCustom(parent, NULL, NULL); if ((*global->custom_load_cb)(node, buffer)) @@ -1476,37 +1315,31 @@ mxml_load_data( break; } - default : /* Ignore... */ + default : // Ignore... node = NULL; break; } if (*bufptr) { - /* - * Bad integer/real number value... - */ - - mxml_error("Bad %s value '%s' in parent <%s> on line %d.", type == MXML_INTEGER ? "integer" : "real", buffer, parent ? parent->value.element.name : "null", line); + // Bad integer/real number value... + mxml_error("Bad %s value '%s' in parent <%s> on line %d.", type == MXML_TYPE_INTEGER ? "integer" : "real", buffer, parent ? parent->value.element.name : "null", line); break; } bufptr = buffer; - whitespace = mxml_isspace(ch) && type == MXML_TEXT; + whitespace = mxml_isspace(ch) && type == MXML_TYPE_TEXT; - if (!node && type != MXML_IGNORE) + if (!node && type != MXML_TYPE_IGNORE) { - /* - * Print error and return... - */ - + // Print error and return... mxml_error("Unable to add value node of type %s to parent <%s> on line %d.", types[type], parent ? parent->value.element.name : "null", line); goto error; } if (sax_cb) { - (*sax_cb)(node, MXML_SAX_DATA, sax_data); + (*sax_cb)(node, MXML_SAX_EVENT_DATA, sax_data); if (!mxmlRelease(node)) node = NULL; @@ -1515,18 +1348,16 @@ mxml_load_data( if (!first && node) first = node; } - else if (mxml_isspace(ch) && type == MXML_TEXT) + else if (mxml_isspace(ch) && type == MXML_TYPE_TEXT) + { whitespace = 1; + } if (ch == '\n') line ++; - /* - * Add lone whitespace node if we have an element and existing - * whitespace... - */ - - if (ch == '<' && whitespace && type == MXML_TEXT) + // Add lone whitespace node if we have an element and existing whitespace... + if (ch == '<' && whitespace && type == MXML_TYPE_TEXT) { if (parent) { @@ -1534,7 +1365,7 @@ mxml_load_data( if (sax_cb) { - (*sax_cb)(node, MXML_SAX_DATA, sax_data); + (*sax_cb)(node, MXML_SAX_EVENT_DATA, sax_data); if (!mxmlRelease(node)) node = NULL; @@ -1549,16 +1380,15 @@ mxml_load_data( if (ch == '<') { - /* - * Start of open/close tag... - */ - + // Start of open/close tag... bufptr = buffer; while ((ch = (*getc_cb)(p, &encoding)) != EOF) { if (mxml_isspace(ch) || ch == '>' || (ch == '/' && bufptr > buffer)) + { break; + } else if (ch == '<') { mxml_error("Bare < in element."); @@ -1573,13 +1403,17 @@ mxml_load_data( goto error; } else if (ch < '0' && ch != '!' && ch != '-' && ch != '.' && ch != '/') + { goto error; + } else if (mxml_add_char(ch, &bufptr, &buffer, &bufsize)) + { goto error; - else if (((bufptr - buffer) == 1 && buffer[0] == '?') || - ((bufptr - buffer) == 3 && !strncmp(buffer, "!--", 3)) || - ((bufptr - buffer) == 8 && !strncmp(buffer, "![CDATA[", 8))) + } + else if (((bufptr - buffer) == 1 && buffer[0] == '?') || ((bufptr - buffer) == 3 && !strncmp(buffer, "!--", 3)) || ((bufptr - buffer) == 8 && !strncmp(buffer, "![CDATA[", 8))) + { break; + } if (ch == '\n') line ++; @@ -1589,14 +1423,10 @@ mxml_load_data( if (!strcmp(buffer, "!--")) { - /* - * Gather rest of comment... - */ - + // Gather rest of comment... while ((ch = (*getc_cb)(p, &encoding)) != EOF) { - if (ch == '>' && bufptr > (buffer + 4) && - bufptr[-3] != '-' && bufptr[-2] == '-' && bufptr[-1] == '-') + if (ch == '>' && bufptr > (buffer + 4) && bufptr[-3] != '-' && bufptr[-2] == '-' && bufptr[-1] == '-') break; else if (mxml_add_char(ch, &bufptr, &buffer, &bufsize)) goto error; @@ -1605,50 +1435,34 @@ mxml_load_data( line ++; } - /* - * Error out if we didn't get the whole comment... - */ - + // Error out if we didn't get the whole comment... if (ch != '>') { - /* - * Print error and return... - */ - + // Print error and return... mxml_error("Early EOF in comment node on line %d.", line); goto error; } - - /* - * Otherwise add this as an element under the current parent... - */ - + // Otherwise add this as an element under the current parent... *bufptr = '\0'; if (!parent && first) { - /* - * There can only be one root element! - */ - + // There can only be one root element! mxml_error("<%s> cannot be a second root node after <%s> on line %d.", buffer, first->value.element.name, line); goto error; } if ((node = mxmlNewElement(parent, buffer)) == NULL) { - /* - * Just print error for now... - */ - + // Just print error for now... mxml_error("Unable to add comment node to parent <%s> on line %d.", parent ? parent->value.element.name : "null", line); break; } if (sax_cb) { - (*sax_cb)(node, MXML_SAX_COMMENT, sax_data); + (*sax_cb)(node, MXML_SAX_EVENT_COMMENT, sax_data); if (!mxmlRelease(node)) node = NULL; @@ -1659,72 +1473,52 @@ mxml_load_data( } else if (!strcmp(buffer, "![CDATA[")) { - /* - * Gather CDATA section... - */ - + // Gather CDATA section... while ((ch = (*getc_cb)(p, &encoding)) != EOF) { if (ch == '>' && !strncmp(bufptr - 2, "]]", 2)) { - /* - * Drop terminator from CDATA string... - */ - + // Drop terminator from CDATA string... bufptr[-2] = '\0'; break; } else if (mxml_add_char(ch, &bufptr, &buffer, &bufsize)) + { goto error; + } if (ch == '\n') line ++; } - /* - * Error out if we didn't get the whole comment... - */ - + // Error out if we didn't get the whole comment... if (ch != '>') { - /* - * Print error and return... - */ - + // Print error and return... mxml_error("Early EOF in CDATA node on line %d.", line); goto error; } - - /* - * Otherwise add this as an element under the current parent... - */ - + // Otherwise add this as an element under the current parent... *bufptr = '\0'; if (!parent && first) { - /* - * There can only be one root element! - */ - + // There can only be one root element! mxml_error("<%s> cannot be a second root node after <%s> on line %d.", buffer, first->value.element.name, line); goto error; } if ((node = mxmlNewElement(parent, buffer)) == NULL) { - /* - * Print error and return... - */ - + // Print error and return... mxml_error("Unable to add CDATA node to parent <%s> on line %d.", parent ? parent->value.element.name : "null", line); goto error; } if (sax_cb) { - (*sax_cb)(node, MXML_SAX_CDATA, sax_data); + (*sax_cb)(node, MXML_SAX_EVENT_CDATA, sax_data); if (!mxmlRelease(node)) node = NULL; @@ -1735,10 +1529,7 @@ mxml_load_data( } else if (buffer[0] == '?') { - /* - * Gather rest of processing instruction... - */ - + // Gather rest of processing instruction... while ((ch = (*getc_cb)(p, &encoding)) != EOF) { if (ch == '>' && bufptr > buffer && bufptr[-1] == '?') @@ -1750,49 +1541,34 @@ mxml_load_data( line ++; } - /* - * Error out if we didn't get the whole processing instruction... - */ - + // Error out if we didn't get the whole processing instruction... if (ch != '>') { - /* - * Print error and return... - */ - + // Print error and return... mxml_error("Early EOF in processing instruction node on line %d.", line); goto error; } - /* - * Otherwise add this as an element under the current parent... - */ - + // Otherwise add this as an element under the current parent... *bufptr = '\0'; if (!parent && first) { - /* - * There can only be one root element! - */ - + // There can only be one root element! mxml_error("<%s> cannot be a second root node after <%s> on line %d.", buffer, first->value.element.name, line); goto error; } if ((node = mxmlNewElement(parent, buffer)) == NULL) { - /* - * Print error and return... - */ - + // Print error and return... mxml_error("Unable to add processing instruction node to parent <%s> on line %d.", parent ? parent->value.element.name : "null", line); goto error; } if (sax_cb) { - (*sax_cb)(node, MXML_SAX_DIRECTIVE, sax_data); + (*sax_cb)(node, MXML_SAX_EVENT_DIRECTIVE, sax_data); if (strncmp(node->value.element.name, "?xml ", 5) && !mxmlRelease(node)) node = NULL; @@ -1810,20 +1586,19 @@ mxml_load_data( if (cb) type = (*cb)(parent); else - type = MXML_TEXT; + type = MXML_TYPE_TEXT; } } } else if (buffer[0] == '!') { - /* - * Gather rest of declaration... - */ - + // Gather rest of declaration... do { if (ch == '>') + { break; + } else { if (ch == '&') @@ -1841,49 +1616,34 @@ mxml_load_data( } while ((ch = (*getc_cb)(p, &encoding)) != EOF); - /* - * Error out if we didn't get the whole declaration... - */ - + // Error out if we didn't get the whole declaration... if (ch != '>') { - /* - * Print error and return... - */ - + // Print error and return... mxml_error("Early EOF in declaration node on line %d.", line); goto error; } - /* - * Otherwise add this as an element under the current parent... - */ - + // Otherwise add this as an element under the current parent... *bufptr = '\0'; if (!parent && first) { - /* - * There can only be one root element! - */ - + // There can only be one root element! mxml_error("<%s> cannot be a second root node after <%s> on line %d.", buffer, first->value.element.name, line); goto error; } if ((node = mxmlNewElement(parent, buffer)) == NULL) { - /* - * Print error and return... - */ - + // Print error and return... mxml_error("Unable to add declaration node to parent <%s> on line %d.", parent ? parent->value.element.name : "null", line); goto error; } if (sax_cb) { - (*sax_cb)(node, MXML_SAX_DIRECTIVE, sax_data); + (*sax_cb)(node, MXML_SAX_EVENT_DIRECTIVE, sax_data); if (!mxmlRelease(node)) node = NULL; @@ -1901,30 +1661,21 @@ mxml_load_data( if (cb) type = (*cb)(parent); else - type = MXML_TEXT; + type = MXML_TYPE_TEXT; } } } else if (buffer[0] == '/') { - /* - * Handle close tag... - */ - + // Handle close tag... if (!parent || strcmp(buffer + 1, parent->value.element.name)) { - /* - * Close tag doesn't match tree; print an error for now... - */ - + // Close tag doesn't match tree; print an error for now... mxml_error("Mismatched close tag <%s> under parent <%s> on line %d.", buffer, parent ? parent->value.element.name : "(null)", line); goto error; } - /* - * Keep reading until we see >... - */ - + // Keep reading until we see >... while (ch != '>' && ch != EOF) ch = (*getc_cb)(p, &encoding); @@ -1933,7 +1684,7 @@ mxml_load_data( if (sax_cb) { - (*sax_cb)(node, MXML_SAX_ELEMENT_CLOSE, sax_data); + (*sax_cb)(node, MXML_SAX_EVENT_ELEMENT_CLOSE, sax_data); if (!mxmlRelease(node)) { @@ -1944,35 +1695,23 @@ mxml_load_data( } } - /* - * Ascend into the parent and set the value type as needed... - */ - + // Ascend into the parent and set the value type as needed... if (cb && parent) type = (*cb)(parent); } else { - /* - * Handle open tag... - */ - + // Handle open tag... if (!parent && first) { - /* - * There can only be one root element! - */ - + // There can only be one root element! mxml_error("<%s> cannot be a second root node after <%s> on line %d.", buffer, first->value.element.name, line); goto error; } if ((node = mxmlNewElement(parent, buffer)) == NULL) { - /* - * Just print error for now... - */ - + // Just print error for now... mxml_error("Unable to add element node to parent <%s> on line %d.", parent ? parent->value.element.name : "null", line); goto error; } @@ -1996,7 +1735,7 @@ mxml_load_data( } if (sax_cb) - (*sax_cb)(node, MXML_SAX_ELEMENT_OPEN, sax_data); + (*sax_cb)(node, MXML_SAX_EVENT_ELEMENT_OPEN, sax_data); if (!first) first = node; @@ -2006,20 +1745,17 @@ mxml_load_data( if (ch != '/') { - /* - * Descend into this node, setting the value type as needed... - */ - + // Descend into this node, setting the value type as needed... parent = node; if (cb && parent) type = (*cb)(parent); else - type = MXML_TEXT; + type = MXML_TYPE_TEXT; } else if (sax_cb) { - (*sax_cb)(node, MXML_SAX_ELEMENT_CLOSE, sax_data); + (*sax_cb)(node, MXML_SAX_EVENT_ELEMENT_CLOSE, sax_data); if (!mxmlRelease(node)) { @@ -2035,38 +1771,26 @@ mxml_load_data( } else if (ch == '&') { - /* - * Add character entity to current buffer... - */ - + // Add character entity to current buffer... if ((ch = mxml_get_entity(parent, p, &encoding, getc_cb, &line)) == EOF) goto error; if (mxml_add_char(ch, &bufptr, &buffer, &bufsize)) goto error; } - else if (type == MXML_OPAQUE || type == MXML_CUSTOM || !mxml_isspace(ch)) + else if (type == MXML_TYPE_OPAQUE || type == MXML_TYPE_CUSTOM || !mxml_isspace(ch)) { - /* - * Add character to current buffer... - */ - + // Add character to current buffer... if (mxml_add_char(ch, &bufptr, &buffer, &bufsize)) goto error; } } while ((ch = (*getc_cb)(p, &encoding)) != EOF); - /* - * Free the string buffer - we don't need it anymore... - */ - + // Free the string buffer - we don't need it anymore... free(buffer); - /* - * Find the top element and return it... - */ - + // Find the top element and return it... if (parent) { node = parent; @@ -2089,10 +1813,7 @@ mxml_load_data( else return (first); - /* - * Common error return... - */ - + // Common error return... error: mxmlDelete(first); @@ -2103,31 +1824,28 @@ mxml_load_data( } -/* - * 'mxml_parse_element()' - Parse an element for any attributes... - */ +// +// 'mxml_parse_element()' - Parse an element for any attributes... +// -static int /* O - Terminating character */ +static int // O - Terminating character mxml_parse_element( - mxml_node_t *node, /* I - Element node */ - void *p, /* I - Data to read from */ - int *encoding, /* IO - Encoding */ - _mxml_getc_cb_t getc_cb, /* I - Data callback */ - int *line) /* IO - Current line number */ + mxml_node_t *node, // I - Element node + void *p, // I - Data to read from + int *encoding, // IO - Encoding + _mxml_getc_cb_t getc_cb, // I - Data callback + int *line) // IO - Current line number { - int ch, /* Current character in file */ - quote; /* Quoting character */ - char *name, /* Attribute name */ - *value, /* Attribute value */ - *ptr; /* Pointer into name/value */ - int namesize, /* Size of name string */ - valsize; /* Size of value string */ + int ch, // Current character in file + quote; // Quoting character + char *name, // Attribute name + *value, // Attribute value + *ptr; // Pointer into name/value + int namesize, // Size of name string + valsize; // Size of value string - /* - * Initialize the name and value buffers... - */ - + // Initialize the name and value buffers... if ((name = malloc(64)) == NULL) { mxml_error("Unable to allocate memory for name."); @@ -2145,20 +1863,12 @@ mxml_parse_element( valsize = 64; - /* - * Loop until we hit a >, /, ?, or EOF... - */ - + // Loop until we hit a >, /, ?, or EOF... while ((ch = (*getc_cb)(p, encoding)) != EOF) { -#if DEBUG > 1 - fprintf(stderr, "parse_element: ch='%c'\n", ch); -#endif /* DEBUG > 1 */ - - /* - * Skip leading whitespace... - */ + MXML_DEBUG("parse_element: ch='%c'\n", ch); + // Skip leading whitespace... if (mxml_isspace(ch)) { if (ch == '\n') @@ -2167,16 +1877,10 @@ mxml_parse_element( continue; } - /* - * Stop at /, ?, or >... - */ - + // Stop at /, ?, or >... if (ch == '/' || ch == '?') { - /* - * Grab the > character and print an error if it isn't there... - */ - + // Grab the > character and print an error if it isn't there... quote = (*getc_cb)(p, encoding); if (quote != '>') @@ -2193,22 +1897,18 @@ mxml_parse_element( goto error; } else if (ch == '>') + { break; + } - /* - * Read the attribute name... - */ - + // Read the attribute name... ptr = name; if (mxml_add_char(ch, &ptr, &name, &namesize)) goto error; if (ch == '\"' || ch == '\'') { - /* - * Name is in quotes, so get a quoted string... - */ - + // Name is in quotes, so get a quoted string... quote = ch; while ((ch = (*getc_cb)(p, encoding)) != EOF) @@ -2219,7 +1919,9 @@ mxml_parse_element( goto error; } else if (ch == '\n') + { (*line)++; + } if (mxml_add_char(ch, &ptr, &name, &namesize)) goto error; @@ -2230,14 +1932,10 @@ mxml_parse_element( } else { - /* - * Grab an normal, non-quoted name... - */ - + // Grab an normal, non-quoted name... while ((ch = (*getc_cb)(p, encoding)) != EOF) { - if (mxml_isspace(ch) || ch == '=' || ch == '/' || ch == '>' || - ch == '?') + if (mxml_isspace(ch) || ch == '=' || ch == '/' || ch == '>' || ch == '?') { if (ch == '\n') (*line)++; @@ -2275,10 +1973,7 @@ mxml_parse_element( if (ch == '=') { - /* - * Read the attribute value... - */ - + // Read the attribute value... while ((ch = (*getc_cb)(p, encoding)) != EOF && mxml_isspace(ch)) { if (ch == '\n') @@ -2293,10 +1988,7 @@ mxml_parse_element( if (ch == '\'' || ch == '\"') { - /* - * Read quoted value... - */ - + // Read quoted value... quote = ch; ptr = value; @@ -2314,7 +2006,9 @@ mxml_parse_element( goto error; } else if (ch == '\n') + { (*line)++; + } if (mxml_add_char(ch, &ptr, &value, &valsize)) goto error; @@ -2325,10 +2019,7 @@ mxml_parse_element( } else { - /* - * Read unquoted value... - */ - + // Read unquoted value... ptr = value; if (mxml_add_char(ch, &ptr, &value, &valsize)) goto error; @@ -2358,10 +2049,7 @@ mxml_parse_element( *ptr = '\0'; } - /* - * Set the attribute with the given string value... - */ - + // Set the attribute with the given string value... mxmlElementSetAttr(node, name, value); } else @@ -2370,16 +2058,10 @@ mxml_parse_element( goto error; } - /* - * Check the end character... - */ - + // Check the end character... if (ch == '/' || ch == '?') { - /* - * Grab the > character and print an error if it isn't there... - */ - + // Grab the > character and print an error if it isn't there... quote = (*getc_cb)(p, encoding); if (quote != '>') @@ -2394,19 +2076,13 @@ mxml_parse_element( break; } - /* - * Free the name and value buffers and return... - */ - + // Free the name and value buffers and return... free(name); free(value); return (ch); - /* - * Common error return point... - */ - + // Common error return point... error: free(name); @@ -2416,26 +2092,23 @@ mxml_parse_element( } -/* - * 'mxml_string_getc()' - Get a character from a string. - */ +// +// 'mxml_string_getc()' - Get a character from a string. +// -static int /* O - Character or EOF */ -mxml_string_getc(void *p, /* I - Pointer to file */ - int *encoding) /* IO - Encoding */ +static int // O - Character or EOF +mxml_string_getc(void *p, // I - Pointer to file + int *encoding) // IO - Encoding { - int ch; /* Character */ - const char **s; /* Pointer to string pointer */ + int ch; // Character + const char **s; // Pointer to string pointer s = (const char **)p; if ((ch = (*s)[0] & 255) != 0 || *encoding == ENCODE_UTF16LE) { - /* - * Got character; convert UTF-8 to integer and return... - */ - + // Got character; convert UTF-8 to integer and return... (*s)++; switch (*encoding) @@ -2443,14 +2116,11 @@ mxml_string_getc(void *p, /* I - Pointer to file */ case ENCODE_UTF8 : if (!(ch & 0x80)) { -#if DEBUG > 1 - printf("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); -#endif /* DEBUG > 1 */ + MXML_DEBUG("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); if (mxml_bad_char(ch)) { - mxml_error("Bad control character 0x%02x not allowed by XML standard.", - ch); + mxml_error("Bad control character 0x%02x not allowed by XML standard.", ch); return (EOF); } @@ -2458,10 +2128,7 @@ mxml_string_getc(void *p, /* I - Pointer to file */ } else if (ch == 0xfe) { - /* - * UTF-16 big-endian BOM? - */ - + // UTF-16 big-endian BOM? if (((*s)[0] & 255) != 0xff) return (EOF); @@ -2472,10 +2139,7 @@ mxml_string_getc(void *p, /* I - Pointer to file */ } else if (ch == 0xff) { - /* - * UTF-16 little-endian BOM? - */ - + // UTF-16 little-endian BOM? if (((*s)[0] & 255) != 0xfe) return (EOF); @@ -2486,10 +2150,7 @@ mxml_string_getc(void *p, /* I - Pointer to file */ } else if ((ch & 0xe0) == 0xc0) { - /* - * Two-byte value... - */ - + // Two-byte value... if (((*s)[0] & 0xc0) != 0x80) return (EOF); @@ -2503,20 +2164,13 @@ mxml_string_getc(void *p, /* I - Pointer to file */ return (EOF); } -#if DEBUG > 1 - printf("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); -#endif /* DEBUG > 1 */ - + MXML_DEBUG("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); return (ch); } else if ((ch & 0xf0) == 0xe0) { - /* - * Three-byte value... - */ - - if (((*s)[0] & 0xc0) != 0x80 || - ((*s)[1] & 0xc0) != 0x80) + // Three-byte value... + if (((*s)[0] & 0xc0) != 0x80 || ((*s)[1] & 0xc0) != 0x80) return (EOF); ch = ((((ch & 0x0f) << 6) | ((*s)[0] & 0x3f)) << 6) | ((*s)[1] & 0x3f); @@ -2529,33 +2183,20 @@ mxml_string_getc(void *p, /* I - Pointer to file */ return (EOF); } - /* - * Ignore (strip) Byte Order Mark (BOM)... - */ - + // Ignore (strip) Byte Order Mark (BOM)... if (ch == 0xfeff) return (mxml_string_getc(p, encoding)); -#if DEBUG > 1 - printf("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); -#endif /* DEBUG > 1 */ - + MXML_DEBUG("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); return (ch); } else if ((ch & 0xf8) == 0xf0) { - /* - * Four-byte value... - */ - - if (((*s)[0] & 0xc0) != 0x80 || - ((*s)[1] & 0xc0) != 0x80 || - ((*s)[2] & 0xc0) != 0x80) + // Four-byte value... + if (((*s)[0] & 0xc0) != 0x80 || ((*s)[1] & 0xc0) != 0x80 || ((*s)[2] & 0xc0) != 0x80) return (EOF); - ch = ((((((ch & 0x07) << 6) | ((*s)[0] & 0x3f)) << 6) | - ((*s)[1] & 0x3f)) << 6) | ((*s)[2] & 0x3f); - + ch = ((((((ch & 0x07) << 6) | ((*s)[0] & 0x3f)) << 6) | ((*s)[1] & 0x3f)) << 6) | ((*s)[2] & 0x3f); (*s) += 3; if (ch < 0x10000) @@ -2564,37 +2205,28 @@ mxml_string_getc(void *p, /* I - Pointer to file */ return (EOF); } -#if DEBUG > 1 - printf("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); -#endif /* DEBUG > 1 */ - + MXML_DEBUG("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); return (ch); } else + { return (EOF); + } case ENCODE_UTF16BE : - /* - * Read UTF-16 big-endian char... - */ - + // Read UTF-16 big-endian char... ch = (ch << 8) | ((*s)[0] & 255); (*s) ++; if (mxml_bad_char(ch)) { - mxml_error("Bad control character 0x%02x not allowed by XML standard.", - ch); + mxml_error("Bad control character 0x%02x not allowed by XML standard.", ch); return (EOF); } else if (ch >= 0xd800 && ch <= 0xdbff) { - /* - * Multi-word UTF-16 char... - */ - - int lch; /* Lower word */ - + // Multi-word UTF-16 char... + int lch; // Lower word if (!(*s)[0]) return (EOF); @@ -2608,17 +2240,11 @@ mxml_string_getc(void *p, /* I - Pointer to file */ ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + 0x10000; } -#if DEBUG > 1 - printf("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); -#endif /* DEBUG > 1 */ - + MXML_DEBUG("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); return (ch); case ENCODE_UTF16LE : - /* - * Read UTF-16 little-endian char... - */ - + // Read UTF-16 little-endian char... ch = ch | (((*s)[0] & 255) << 8); if (!ch) @@ -2631,18 +2257,13 @@ mxml_string_getc(void *p, /* I - Pointer to file */ if (mxml_bad_char(ch)) { - mxml_error("Bad control character 0x%02x not allowed by XML standard.", - ch); + mxml_error("Bad control character 0x%02x not allowed by XML standard.", ch); return (EOF); } else if (ch >= 0xd800 && ch <= 0xdbff) { - /* - * Multi-word UTF-16 char... - */ - - int lch; /* Lower word */ - + // Multi-word UTF-16 char... + int lch; // Lower word if (!(*s)[1]) return (EOF); @@ -2656,10 +2277,7 @@ mxml_string_getc(void *p, /* I - Pointer to file */ ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + 0x10000; } -#if DEBUG > 1 - printf("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); -#endif /* DEBUG > 1 */ - + MXML_DEBUG("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); return (ch); } } @@ -2668,15 +2286,15 @@ mxml_string_getc(void *p, /* I - Pointer to file */ } -/* - * 'mxml_string_putc()' - Write a character to a string. - */ +// +// 'mxml_string_putc()' - Write a character to a string. +// -static int /* O - 0 on success, -1 on failure */ -mxml_string_putc(int ch, /* I - Character to write */ - void *p) /* I - Pointer to string pointers */ +static int // O - 0 on success, -1 on failure +mxml_string_putc(int ch, // I - Character to write + void *p) // I - Pointer to string pointers { - char **pp; /* Pointer to string pointers */ + char **pp; // Pointer to string pointers pp = (char **)p; @@ -2690,26 +2308,23 @@ mxml_string_putc(int ch, /* I - Character to write */ } -/* - * 'mxml_write_name()' - Write a name string. - */ +// +// 'mxml_write_name()' - Write a name string. +// -static int /* O - 0 on success, -1 on failure */ -mxml_write_name(const char *s, /* I - Name to write */ - void *p, /* I - Write pointer */ +static int // O - 0 on success, -1 on failure +mxml_write_name(const char *s, // I - Name to write + void *p, // I - Write pointer int (*putc_cb)(int, void *)) - /* I - Write callback */ + // I - Write callback { - char quote; /* Quote character */ - const char *name; /* Entity name */ + char quote; // Quote character + const char *name; // Entity name if (*s == '\"' || *s == '\'') { - /* - * Write a quoted name string... - */ - + // Write a quoted name string... if ((*putc_cb)(*s, p) < 0) return (-1); @@ -2734,24 +2349,20 @@ mxml_write_name(const char *s, /* I - Name to write */ return (-1); } else if ((*putc_cb)(*s, p) < 0) + { return (-1); + } s ++; } - /* - * Write the end quote... - */ - + // Write the end quote... if ((*putc_cb)(quote, p) < 0) return (-1); } else { - /* - * Write a non-quoted name string... - */ - + // Write a non-quoted name string... while (*s) { if ((*putc_cb)(*s, p) < 0) @@ -2765,52 +2376,41 @@ mxml_write_name(const char *s, /* I - Name to write */ } -/* - * 'mxml_write_node()' - Save an XML node to a file. - */ +// +// 'mxml_write_node()' - Save an XML node to a file. +// -static int /* O - Column or -1 on error */ -mxml_write_node(mxml_node_t *node, /* I - Node to write */ - void *p, /* I - File to write to */ - mxml_save_cb_t cb, /* I - Whitespace callback */ - int col, /* I - Current column */ - _mxml_putc_cb_t putc_cb,/* I - Output callback */ - _mxml_global_t *global)/* I - Global data */ +static int // O - Column or -1 on error +mxml_write_node(mxml_node_t *node, // I - Node to write + void *p, // I - File to write to + mxml_save_cb_t cb, // I - Whitespace callback + int col, // I - Current column + _mxml_putc_cb_t putc_cb,// I - Output callback + _mxml_global_t *global)// I - Global data { - mxml_node_t *current, /* Current node */ - *next; /* Next node */ - int i, /* Looping var */ - width; /* Width of attr + value */ - _mxml_attr_t *attr; /* Current attribute */ - char s[255]; /* Temporary string */ - + mxml_node_t *current, // Current node + *next; // Next node + int i, // Looping var + width; // Width of attr + value + _mxml_attr_t *attr; // Current attribute + char s[255]; // Temporary string - /* - * Loop through this node and all of its children... - */ + // Loop through this node and all of its children... for (current = node; current; current = next) { - /* - * Print the node value... - */ - + // Print the node value... switch (current->type) { - case MXML_ELEMENT : + case MXML_TYPE_ELEMENT : col = mxml_write_ws(current, p, cb, MXML_WS_BEFORE_OPEN, col, putc_cb); if ((*putc_cb)('<', p) < 0) return (-1); - if (current->value.element.name[0] == '?' || - !strncmp(current->value.element.name, "!--", 3)) + if (current->value.element.name[0] == '?' || !strncmp(current->value.element.name, "!--", 3)) { - /* - * Comments and processing instructions do not use character - * entities. - */ - - const char *ptr; /* Pointer into name */ + // Comments and processing instructions do not use character entities. + const char *ptr; // Pointer into name for (ptr = current->value.element.name; *ptr; ptr ++) if ((*putc_cb)(*ptr, p) < 0) @@ -2818,12 +2418,9 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */ } else if (!strncmp(current->value.element.name, "![CDATA[", 8)) { - /* - * CDATA elements do not use character entities, but also need the - * "]]" terminator added at the end. - */ - - const char *ptr; /* Pointer into name */ + // CDATA elements do not use character entities, but also need the + // "]]" terminator added at the end. + const char *ptr; // Pointer into name for (ptr = current->value.element.name; *ptr; ptr ++) if ((*putc_cb)(*ptr, p) < 0) @@ -2835,13 +2432,13 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */ return (-1); } else if (mxml_write_name(current->value.element.name, p, putc_cb) < 0) + { return (-1); + } col += strlen(current->value.element.name) + 1; - for (i = current->value.element.num_attrs, attr = current->value.element.attrs; - i > 0; - i --, attr ++) + for (i = current->value.element.num_attrs, attr = current->value.element.attrs; i > 0; i --, attr ++) { width = (int)strlen(attr->name); @@ -2883,10 +2480,7 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */ if (current->child) { - /* - * Write children... - */ - + // Write children... if ((*putc_cb)('>', p) < 0) return (-1); else @@ -2894,13 +2488,9 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */ col = mxml_write_ws(current, p, cb, MXML_WS_AFTER_OPEN, col, putc_cb); } - else if (current->value.element.name[0] == '!' || - current->value.element.name[0] == '?') + else if (current->value.element.name[0] == '!' || current->value.element.name[0] == '?') { - /* - * The ? and ! elements are special-cases... - */ - + // The ? and ! elements are special-cases... if ((*putc_cb)('>', p) < 0) return (-1); else @@ -2923,7 +2513,7 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */ } break; - case MXML_INTEGER : + case MXML_TYPE_INTEGER : if (current->prev) { if (global->wrap > 0 && col > global->wrap) @@ -2934,9 +2524,13 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */ col = 0; } else if ((*putc_cb)(' ', p) < 0) + { return (-1); + } else + { col ++; + } } snprintf(s, sizeof(s), "%d", current->value.integer); @@ -2946,14 +2540,14 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */ col += strlen(s); break; - case MXML_OPAQUE : + case MXML_TYPE_OPAQUE : if (mxml_write_string(current->value.opaque, p, putc_cb) < 0) return (-1); col += strlen(current->value.opaque); break; - case MXML_REAL : + case MXML_TYPE_REAL : if (current->prev) { if (global->wrap > 0 && col > global->wrap) @@ -2964,11 +2558,16 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */ col = 0; } else if ((*putc_cb)(' ', p) < 0) + { return (-1); + } else + { col ++; + } } + // TODO: Provide locale-neutral formatting/scanning code for REAL snprintf(s, sizeof(s), "%f", current->value.real); if (mxml_write_string(s, p, putc_cb) < 0) return (-1); @@ -2976,7 +2575,7 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */ col += strlen(s); break; - case MXML_TEXT : + case MXML_TYPE_TEXT : if (current->value.text.whitespace && col > 0) { if (global->wrap > 0 && col > global->wrap) @@ -2987,9 +2586,13 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */ col = 0; } else if ((*putc_cb)(' ', p) < 0) + { return (-1); + } else + { col ++; + } } if (mxml_write_string(current->value.text.string, p, putc_cb) < 0) @@ -2998,11 +2601,11 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */ col += strlen(current->value.text.string); break; - case MXML_CUSTOM : + case MXML_TYPE_CUSTOM : if (global->custom_save_cb) { - char *data; /* Custom data string */ - const char *newline; /* Last newline in string */ + char *data; // Custom data string + const char *newline; // Last newline in string if ((data = (*global->custom_save_cb)(current)) == NULL) @@ -3020,43 +2623,30 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */ break; } - default : /* Should never happen */ + default : // Should never happen return (-1); } - /* - * Figure out the next node... - */ - + // Figure out the next node... if ((next = current->child) == NULL) { if (current == node) { - /* - * Don't traverse to sibling node if we are at the "root" node... - */ - + // Don't traverse to sibling node if we are at the "root" node... next = NULL; } else { - /* - * Try the next sibling, and continue traversing upwards as needed... - */ - + // Try the next sibling, and continue traversing upwards as needed... while ((next = current->next) == NULL) { if (current == node || !current->parent) break; - /* - * The ? and ! elements are special-cases and have no end tags... - */ - + // The ? and ! elements are special-cases and have no end tags... current = current->parent; - if (current->value.element.name[0] != '!' && - current->value.element.name[0] != '?') + if (current->value.element.name[0] != '!' && current->value.element.name[0] != '?') { col = mxml_write_ws(current, p, cb, MXML_WS_BEFORE_CLOSE, col, putc_cb); @@ -3085,17 +2675,17 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */ } -/* - * 'mxml_write_string()' - Write a string, escaping & and < as needed. - */ +// +// 'mxml_write_string()' - Write a string, escaping & and < as needed. +// -static int /* O - 0 on success, -1 on failure */ +static int // O - 0 on success, -1 on failure mxml_write_string( - const char *s, /* I - String to write */ - void *p, /* I - Write pointer */ - _mxml_putc_cb_t putc_cb) /* I - Write callback */ + const char *s, // I - String to write + void *p, // I - Write pointer + _mxml_putc_cb_t putc_cb) // I - Write callback { - const char *name; /* Entity name, if any */ + const char *name; // Entity name, if any while (*s) @@ -3116,7 +2706,9 @@ mxml_write_string( return (-1); } else if ((*putc_cb)(*s, p) < 0) + { return (-1); + } s ++; } @@ -3125,19 +2717,19 @@ mxml_write_string( } -/* - * 'mxml_write_ws()' - Do whitespace callback... - */ +// +// 'mxml_write_ws()' - Do whitespace callback... +// -static int /* O - New column */ -mxml_write_ws(mxml_node_t *node, /* I - Current node */ - void *p, /* I - Write pointer */ - mxml_save_cb_t cb, /* I - Callback function */ - int ws, /* I - Where value */ - int col, /* I - Current column */ - _mxml_putc_cb_t putc_cb) /* I - Write callback */ +static int // O - New column +mxml_write_ws(mxml_node_t *node, // I - Current node + void *p, // I - Write pointer + mxml_save_cb_t cb, // I - Callback function + int ws, // I - Where value + int col, // I - Current column + _mxml_putc_cb_t putc_cb) // I - Write callback { - const char *s; /* Whitespace string */ + const char *s; // Whitespace string if (cb && (s = (*cb)(node, ws)) != NULL) @@ -3145,16 +2737,22 @@ mxml_write_ws(mxml_node_t *node, /* I - Current node */ while (*s) { if ((*putc_cb)(*s, p) < 0) + { return (-1); + } else if (*s == '\n') + { col = 0; + } else if (*s == '\t') { col += MXML_TAB; col = col - (col % MXML_TAB); } else + { col ++; + } s ++; } diff --git a/mxml-get.c b/mxml-get.c index e2ff2bd..95b197f 100644 --- a/mxml-get.c +++ b/mxml-get.c @@ -1,365 +1,258 @@ -/* - * Node get functions for Mini-XML, a small XML file parsing library. - * - * https://www.msweet.org/mxml - * - * Copyright © 2014-2019 by Michael R Sweet. - * - * Licensed under Apache License v2.0. See the file "LICENSE" for more - * information. - */ - -/* - * Include necessary headers... - */ - -#include "config.h" +// +// Node get functions for Mini-XML, a small XML file parsing library. +// +// https://www.msweet.org/mxml +// +// Copyright © 2014-2024 by Michael R Sweet. +// +// Licensed under Apache License v2.0. See the file "LICENSE" for more +// information. +// + #include "mxml-private.h" -/* - * 'mxmlGetCDATA()' - Get the value for a CDATA node. - * - * @code NULL@ is returned if the node is not a CDATA element. - * - * @since Mini-XML 2.7@ - */ +// +// 'mxmlGetCDATA()' - Get the value for a CDATA node. +// +// `NULL` is returned if the node is not a CDATA element. +// -const char * /* O - CDATA value or @code NULL@ */ -mxmlGetCDATA(mxml_node_t *node) /* I - Node to get */ +const char * // O - CDATA value or `NULL` +mxmlGetCDATA(mxml_node_t *node) // I - Node to get { - /* - * Range check input... - */ - - if (!node || node->type != MXML_ELEMENT || - strncmp(node->value.element.name, "![CDATA[", 8)) + // Range check input... + if (!node || node->type != MXML_TYPE_ELEMENT || strncmp(node->value.element.name, "![CDATA[", 8)) return (NULL); - /* - * Return the text following the CDATA declaration... - */ - + // Return the text following the CDATA declaration... return (node->value.element.name + 8); } -/* - * 'mxmlGetCustom()' - Get the value for a custom node. - * - * @code NULL@ is returned if the node (or its first child) is not a custom - * value node. - * - * @since Mini-XML 2.7@ - */ +// +// 'mxmlGetCustom()' - Get the value for a custom node. +// +// `NULL` is returned if the node (or its first child) is not a custom +// value node. +// -const void * /* O - Custom value or @code NULL@ */ -mxmlGetCustom(mxml_node_t *node) /* I - Node to get */ +const void * // O - Custom value or `NULL` +mxmlGetCustom(mxml_node_t *node) // I - Node to get { - /* - * Range check input... - */ - + // Range check input... if (!node) return (NULL); - /* - * Return the integer value... - */ - - if (node->type == MXML_CUSTOM) + // Return the custom value... + if (node->type == MXML_TYPE_CUSTOM) return (node->value.custom.data); - else if (node->type == MXML_ELEMENT && - node->child && - node->child->type == MXML_CUSTOM) + else if (node->type == MXML_TYPE_ELEMENT && node->child && node->child->type == MXML_TYPE_CUSTOM) return (node->child->value.custom.data); else return (NULL); } -/* - * 'mxmlGetElement()' - Get the name for an element node. - * - * @code NULL@ is returned if the node is not an element node. - * - * @since Mini-XML 2.7@ - */ +// +// 'mxmlGetElement()' - Get the name for an element node. +// +// `NULL` is returned if the node is not an element node. +// -const char * /* O - Element name or @code NULL@ */ -mxmlGetElement(mxml_node_t *node) /* I - Node to get */ +const char * // O - Element name or `NULL` +mxmlGetElement(mxml_node_t *node) // I - Node to get { - /* - * Range check input... - */ - - if (!node || node->type != MXML_ELEMENT) + // Range check input... + if (!node || node->type != MXML_TYPE_ELEMENT) return (NULL); - /* - * Return the element name... - */ - + // Return the element name... return (node->value.element.name); } -/* - * '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 - * has no children. - * - * @since Mini-XML 2.7@ - */ +// +// 'mxmlGetFirstChild()' - Get the first child of an element node. +// +// `NULL` is returned if the node is not an element node or if the node +// has no children. +// -mxml_node_t * /* O - First child or @code NULL@ */ -mxmlGetFirstChild(mxml_node_t *node) /* I - Node to get */ +mxml_node_t * // O - First child or `NULL` +mxmlGetFirstChild(mxml_node_t *node) // I - Node to get { - /* - * Range check input... - */ - - if (!node || node->type != MXML_ELEMENT) + // Range check input... + if (!node || node->type != MXML_TYPE_ELEMENT) return (NULL); - /* - * Return the first child node... - */ - + // Return the first child node... return (node->child); } -/* - * 'mxmlGetInteger()' - Get the integer value from the specified node or its - * first child. - * - * 0 is returned if the node (or its first child) is not an integer value node. - * - * @since Mini-XML 2.7@ - */ +// +// 'mxmlGetInteger()' - Get the integer value from the specified node or its +// first child. +// +// 0 is returned if the node (or its first child) is not an integer value node. +// -int /* O - Integer value or 0 */ -mxmlGetInteger(mxml_node_t *node) /* I - Node to get */ +int // O - Integer value or 0 +mxmlGetInteger(mxml_node_t *node) // I - Node to get { - /* - * Range check input... - */ - + // Range check input... if (!node) return (0); - /* - * Return the integer value... - */ - - if (node->type == MXML_INTEGER) + // Return the integer value... + if (node->type == MXML_TYPE_INTEGER) return (node->value.integer); - else if (node->type == MXML_ELEMENT && - node->child && - node->child->type == MXML_INTEGER) + else if (node->type == MXML_TYPE_ELEMENT && node->child && node->child->type == MXML_TYPE_INTEGER) return (node->child->value.integer); else return (0); } -/* - * '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 - * has no children. - * - * @since Mini-XML 2.7@ - */ +// +// 'mxmlGetLastChild()' - Get the last child of an element node. +// +// `NULL` is returned if the node is not an element node or if the node +// has no children. +// -mxml_node_t * /* O - Last child or @code NULL@ */ -mxmlGetLastChild(mxml_node_t *node) /* I - Node to get */ +mxml_node_t * // O - Last child or `NULL` +mxmlGetLastChild(mxml_node_t *node) // I - Node to get { - /* - * Range check input... - */ - - if (!node || node->type != MXML_ELEMENT) + // Range check input... + if (!node || node->type != MXML_TYPE_ELEMENT) return (NULL); - /* - * Return the node type... - */ - + // Return the last child node... return (node->last_child); } -/* - * 'mxmlGetNextSibling()' - Get the next node for the current parent. - * - * @code NULL@ is returned if this is the last child for the current parent. - * - * @since Mini-XML 2.7@ - */ +// +// 'mxmlGetNextSibling()' - Get the next node for the current parent. +// +// `NULL` is returned if this is the last child for the current parent. +// 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) return (NULL); - /* - * Return the node type... - */ - + // Return the next sibling node... return (node->next); } -/* - * '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 - * value node. - * - * @since Mini-XML 2.7@ - */ +// +// 'mxmlGetOpaque()' - Get an opaque string value for a node or its first child. +// +// `NULL` is returned if the node (or its first child) is not an opaque +// value node. +// -const char * /* O - Opaque string or @code NULL@ */ -mxmlGetOpaque(mxml_node_t *node) /* I - Node to get */ +const char * // O - Opaque string or `NULL` +mxmlGetOpaque(mxml_node_t *node) // I - Node to get { - /* - * Range check input... - */ - + // Range check input... if (!node) return (NULL); - /* - * Return the integer value... - */ - - if (node->type == MXML_OPAQUE) + // Return the opaque value... + if (node->type == MXML_TYPE_OPAQUE) return (node->value.opaque); - else if (node->type == MXML_ELEMENT && - node->child && - node->child->type == MXML_OPAQUE) + else if (node->type == MXML_TYPE_ELEMENT && node->child && node->child->type == MXML_TYPE_OPAQUE) return (node->child->value.opaque); else return (NULL); } -/* - * 'mxmlGetParent()' - Get the parent node. - * - * @code NULL@ is returned for a root node. - * - * @since Mini-XML 2.7@ - */ +// +// 'mxmlGetParent()' - Get the parent node. +// +// `NULL` is returned for a root node. +// -mxml_node_t * /* O - Parent node or @code NULL@ */ -mxmlGetParent(mxml_node_t *node) /* I - Node to get */ +mxml_node_t * // O - Parent node or `NULL` +mxmlGetParent(mxml_node_t *node) // I - Node to get { - /* - * Range check input... - */ - + // Range check input... if (!node) return (NULL); - /* - * Return the node type... - */ - + // Return the parent node... return (node->parent); } -/* - * 'mxmlGetPrevSibling()' - Get the previous node for the current parent. - * - * @code NULL@ is returned if this is the first child for the current parent. - * - * @since Mini-XML 2.7@ - */ +// +// 'mxmlGetPrevSibling()' - Get the previous node for the current parent. +// +// `NULL` is returned if this is the first child for the current parent. +// -mxml_node_t * /* O - Previous node or @code NULL@ */ -mxmlGetPrevSibling(mxml_node_t *node) /* I - Node to get */ +mxml_node_t * // O - Previous node or `NULL` +mxmlGetPrevSibling(mxml_node_t *node) // I - Node to get { - /* - * Range check input... - */ - + // Range check input... if (!node) return (NULL); - /* - * Return the node type... - */ - + // Return the previous sibling node... return (node->prev); } -/* - * '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. - * - * @since Mini-XML 2.7@ - */ +// +// '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. +// -double /* O - Real value or 0.0 */ -mxmlGetReal(mxml_node_t *node) /* I - Node to get */ +double // O - Real value or 0.0 +mxmlGetReal(mxml_node_t *node) // I - Node to get { - /* - * Range check input... - */ - + // Range check input... if (!node) return (0.0); - /* - * Return the integer value... - */ - - if (node->type == MXML_REAL) + // Return the real value... + if (node->type == MXML_TYPE_REAL) return (node->value.real); - else if (node->type == MXML_ELEMENT && - node->child && - node->child->type == MXML_REAL) + else if (node->type == MXML_TYPE_ELEMENT && node->child && node->child->type == MXML_TYPE_REAL) return (node->child->value.real); else return (0.0); } -/* - * '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. - * The "whitespace" argument can be @code NULL@. - * - * 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. - * 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 - * using the @link mxmlGetOpaque@ function instead. - * - * @since Mini-XML 2.7@ - */ - -const char * /* O - Text string or @code NULL@ */ -mxmlGetText(mxml_node_t *node, /* I - Node to get */ - int *whitespace) /* O - 1 if string is preceded by whitespace, 0 otherwise */ +// +// 'mxmlGetText()' - Get the text value for a node or its first child. +// +// `NULL` is returned if the node (or its first child) is not a text node. +// The "whitespace" argument can be `NULL`. +// +// Note: Text nodes consist of whitespace-delimited words. You will only get +// 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 +// the XML file with `MXML_TYPE_OPAQUE` nodes and get the resulting strings +// using the @link mxmlGetOpaque@ function instead. +// + +const char * // O - Text string or `NULL` +mxmlGetText(mxml_node_t *node, // I - Node to get + int *whitespace) // O - 1 if string is preceded by whitespace, 0 otherwise { - /* - * Range check input... - */ - + // Range check input... if (!node) { if (whitespace) @@ -368,20 +261,15 @@ mxmlGetText(mxml_node_t *node, /* I - Node to get */ return (NULL); } - /* - * Return the integer value... - */ - - if (node->type == MXML_TEXT) + // Return the integer value... + if (node->type == MXML_TYPE_TEXT) { if (whitespace) *whitespace = node->value.text.whitespace; return (node->value.text.string); } - else if (node->type == MXML_ELEMENT && - node->child && - node->child->type == MXML_TEXT) + else if (node->type == MXML_TYPE_ELEMENT && node->child && node->child->type == MXML_TYPE_TEXT) { if (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. - * - * @code MXML_IGNORE@ is returned if "node" is @code NULL@. - * - * @since Mini-XML 2.7@ - */ +// +// 'mxmlGetType()' - Get the node type. +// +// `MXML_TYPE_IGNORE` is returned if "node" is `NULL`. +// -mxml_type_t /* O - Type of node */ -mxmlGetType(mxml_node_t *node) /* I - Node to get */ +mxml_type_t // O - Type of node +mxmlGetType(mxml_node_t *node) // I - Node to get { - /* - * Range check input... - */ - + // Range check input... if (!node) - return (MXML_IGNORE); - - /* - * Return the node type... - */ + return (MXML_TYPE_IGNORE); + // Return the node type... return (node->type); } -/* - * 'mxmlGetUserData()' - Get the user data pointer for a node. - * - * @since Mini-XML 2.7@ - */ +// +// 'mxmlGetUserData()' - Get the user data pointer for a node. +// -void * /* O - User data pointer */ -mxmlGetUserData(mxml_node_t *node) /* I - Node to get */ +void * // O - User data pointer +mxmlGetUserData(mxml_node_t *node) // I - Node to get { - /* - * Range check input... - */ - + // Range check input... if (!node) return (NULL); - /* - * Return the user data pointer... - */ - + // Return the user data pointer... return (node->user_data); } diff --git a/mxml-index.c b/mxml-index.c index ca1ea7b..08762e3 100644 --- a/mxml-index.c +++ b/mxml-index.c @@ -1,79 +1,60 @@ -/* - * Index support code for Mini-XML, a small XML file parsing library. - * - * https://www.msweet.org/mxml - * - * Copyright © 2003-2021 by Michael R Sweet. - * - * Licensed under Apache License v2.0. See the file "LICENSE" for more - * information. - */ - -/* - * Include necessary headers... - */ - -#include "config.h" +// +// Index support code for Mini-XML, a small XML file parsing library. +// +// https://www.msweet.org/mxml +// +// Copyright © 2003-2024 by Michael R Sweet. +// +// Licensed under Apache License v2.0. See the file "LICENSE" for more +// information. +// + #include "mxml-private.h" -/* - * Sort functions... - */ +// +// Local functions... +// -static int index_compare(mxml_index_t *ind, mxml_node_t *first, - 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_compare(mxml_index_t *ind, mxml_node_t *first, mxml_node_t *second); +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); -/* - * 'mxmlIndexDelete()' - Delete an index. - */ +// +// 'mxmlIndexDelete()' - Delete an index. +// 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) return; - /* - * Free memory... - */ - + // Free memory... free(ind->attr); free(ind->nodes); free(ind); } -/* - * 'mxmlIndexEnum()' - Return the next node in the index. - * - * 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 - * index. - */ +// +// 'mxmlIndexEnum()' - Return the next node in the index. +// +// 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 +// index. +// -mxml_node_t * /* O - Next node or @code NULL@ if there is none */ -mxmlIndexEnum(mxml_index_t *ind) /* I - Index to enumerate */ +mxml_node_t * // O - Next node or `NULL` if there is none +mxmlIndexEnum(mxml_index_t *ind) // I - Index to enumerate { - /* - * Range check input... - */ - + // Range check input... if (!ind) return (NULL); - /* - * Return the next node... - */ - + // Return the next node... if (ind->cur_node < ind->num_nodes) return (ind->nodes[ind->cur_node ++]); else @@ -81,249 +62,164 @@ mxmlIndexEnum(mxml_index_t *ind) /* I - Index to enumerate */ } -/* - * 'mxmlIndexFind()' - Find the next matching node. - * - * You should call @link mxmlIndexReset@ prior to using this function for - * the first time with a particular set of "element" and "value" - * strings. Passing @code NULL@ for both "element" and "value" is equivalent - * to calling @link mxmlIndexEnum@. - */ +// +// 'mxmlIndexFind()' - Find the next matching node. +// +// You should call @link mxmlIndexReset@ prior to using this function for +// the first time with a particular set of "element" and "value" +// strings. Passing `NULL` for both "element" and "value" is equivalent +// to calling @link mxmlIndexEnum@. +// -mxml_node_t * /* O - Node or @code NULL@ if none found */ -mxmlIndexFind(mxml_index_t *ind, /* I - Index to search */ - const char *element, /* I - Element name to find, if any */ - const char *value) /* I - Attribute value, if any */ +mxml_node_t * // O - Node or `NULL` if none found +mxmlIndexFind(mxml_index_t *ind, // I - Index to search + const char *element, // I - Element name to find, if any + const char *value) // I - Attribute value, if any { - int diff, /* Difference between names */ - current, /* Current entity in search */ - first, /* First entity in search */ - last; /* Last entity in search */ + int diff, // Difference between names + current, // Current entity in search + first, // First entity in search + last; // Last entity in search -#ifdef DEBUG - printf("mxmlIndexFind(ind=%p, element=\"%s\", value=\"%s\")\n", - ind, element ? element : "(null)", value ? value : "(null)"); -#endif /* DEBUG */ - - /* - * Range check input... - */ + MXML_DEBUG("mxmlIndexFind(ind=%p, element=\"%s\", value=\"%s\")\n", ind, element ? element : "(null)", value ? value : "(null)"); + // Range check input... if (!ind || (!ind->attr && value)) { -#ifdef DEBUG - puts(" returning NULL..."); - if (ind) - printf(" ind->attr=\"%s\"\n", ind->attr ? ind->attr : "(null)"); -#endif /* DEBUG */ - + MXML_DEBUG("mxmlIndexFind: Returning NULL, ind->attr=\"%s\"...\n", ind && ind->attr ? ind->attr : "(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) 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) { -#ifdef DEBUG - puts(" returning NULL..."); - puts(" no nodes!"); -#endif /* DEBUG */ - + MXML_DEBUG("mxmlIndexFind: Returning NULL, no nodes...\n"); 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) { - /* - * Find the first node using a modified binary search algorithm... - */ - + // Find the first node using a modified binary search algorithm... first = 0; last = ind->num_nodes - 1; -#ifdef DEBUG - printf(" find first time, num_nodes=%d...\n", ind->num_nodes); -#endif /* DEBUG */ + MXML_DEBUG("mxmlIndexFind: Find first time, num_nodes=%d...\n", ind->num_nodes); while ((last - first) > 1) { current = (first + last) / 2; -#ifdef DEBUG - printf(" first=%d, last=%d, current=%d\n", first, last, current); -#endif /* DEBUG */ + MXML_DEBUG("mxmlIndexFind: first=%d, last=%d, current=%d\n", first, last, current); if ((diff = index_find(ind, element, value, ind->nodes[current])) == 0) { - /* - * Found a match, move back to find the first... - */ - -#ifdef DEBUG - puts(" match!"); -#endif /* DEBUG */ + // Found a match, move back to find the first... + MXML_DEBUG("mxmlIndexFind: match.\n"); - while (current > 0 && - !index_find(ind, element, value, ind->nodes[current - 1])) + while (current > 0 && !index_find(ind, element, value, ind->nodes[current - 1])) current --; -#ifdef DEBUG - printf(" returning first match=%d\n", current); -#endif /* DEBUG */ - - /* - * Return the first match and save the index to the next... - */ + MXML_DEBUG("mxmlIndexFind: Returning first match=%d\n", current); + // Return the first match and save the index to the next... ind->cur_node = current + 1; return (ind->nodes[current]); } else if (diff < 0) + { last = current; + } else + { first = current; + } -#ifdef DEBUG - printf(" diff=%d\n", diff); -#endif /* DEBUG */ + MXML_DEBUG("mxmlIndexFind: diff=%d\n", diff); } - /* - * 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 ++) + { if (!index_find(ind, element, value, ind->nodes[current])) { - /* - * Found exactly one (or possibly two) match... - */ - -#ifdef DEBUG - printf(" returning only match %d...\n", current); -#endif /* DEBUG */ - + // Found exactly one (or possibly two) match... + MXML_DEBUG("mxmlIndexFind: Returning only match %d...\n", current); ind->cur_node = current + 1; return (ind->nodes[current]); } + } - /* - * No matches... - */ - + // No matches... ind->cur_node = ind->num_nodes; - -#ifdef DEBUG - puts(" returning NULL..."); -#endif /* DEBUG */ - + MXML_DEBUG("mxmlIndexFind: Returning NULL...\n"); return (NULL); } - else if (ind->cur_node < ind->num_nodes && - !index_find(ind, element, value, ind->nodes[ind->cur_node])) + else if (ind->cur_node < ind->num_nodes && !index_find(ind, element, value, ind->nodes[ind->cur_node])) { - /* - * Return the next matching node... - */ - -#ifdef DEBUG - printf(" returning next match %d...\n", ind->cur_node); -#endif /* DEBUG */ - + // Return the next matching node... + MXML_DEBUG("mxmlIndexFind: Returning next match %d...\n", 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; -#ifdef DEBUG - puts(" returning NULL..."); -#endif /* DEBUG */ - + MXML_DEBUG("mxmlIndexFind: Returning NULL...\n"); return (NULL); } -/* - * 'mxmlIndexGetCount()' - Get the number of nodes in an index. - * - * @since Mini-XML 2.7@ - */ +// +// 'mxmlIndexGetCount()' - Get the number of nodes in an index. +// -int /* I - Number of nodes in index */ -mxmlIndexGetCount(mxml_index_t *ind) /* I - Index of nodes */ +int // I - Number of nodes in index +mxmlIndexGetCount(mxml_index_t *ind) // I - Index of nodes { - /* - * Range check input... - */ - + // Range check input... if (!ind) return (0); - /* - * Return the number of nodes in the index... - */ - + // Return the number of nodes in the index... return (ind->num_nodes); } -/* - * 'mxmlIndexNew()' - Create a new index. - * - * 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 - * 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" - * argument is not NULL. - */ - -mxml_index_t * /* O - New index */ -mxmlIndexNew(mxml_node_t *node, /* I - XML node tree */ - const char *element, /* I - Element to index or @code NULL@ for all */ - const char *attr) /* I - Attribute to index or @code NULL@ for none */ +// +// 'mxmlIndexNew()' - Create a new index. +// +// The index will contain all nodes that contain the named element and/or +// 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 +// sorted by element name and optionally by attribute value if the "attr" +// argument is not NULL. +// + +mxml_index_t * // O - New index +mxmlIndexNew(mxml_node_t *node, // I - XML node tree + const char *element, // I - Element to index or `NULL` for all + const char *attr) // I - Attribute to index or `NULL` for none { - mxml_index_t *ind; /* New index */ - mxml_node_t *current, /* Current node in index */ - **temp; /* Temporary node pointer array */ - + mxml_index_t *ind; // New index + mxml_node_t *current, // Current node in index + **temp; // Temporary node pointer array - /* - * Range check input... - */ -#ifdef DEBUG - printf("mxmlIndexNew(node=%p, element=\"%s\", attr=\"%s\")\n", - node, element ? element : "(null)", attr ? attr : "(null)"); -#endif /* DEBUG */ + // Range check input... + MXML_DEBUG("mxmlIndexNew(node=%p, element=\"%s\", attr=\"%s\")\n", node, element ? element : "(null)", attr ? attr : "(null)"); if (!node) return (NULL); - /* - * Create a new index... - */ - + // Create a new index... if ((ind = calloc(1, sizeof(mxml_index_t))) == NULL) { mxml_error("Unable to allocate memory for index."); @@ -356,10 +252,7 @@ mxmlIndexNew(mxml_node_t *node, /* I - XML node tree */ 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."); mxmlIndexDelete(ind); return (NULL); @@ -374,115 +267,36 @@ mxmlIndexNew(mxml_node_t *node, /* I - XML node tree */ current = mxmlFindElement(current, node, element, attr, NULL, MXML_DESCEND); } - /* - * 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 */ - + // Sort nodes based upon the search criteria... if (ind->num_nodes > 1) index_sort(ind, 0, ind->num_nodes - 1); -#ifdef DEBUG - { - 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 the new index... return (ind); } -/* - * 'mxmlIndexReset()' - Reset the enumeration/find pointer in the index and - * return the first node in the index. - * - * This function should be called prior to using @link mxmlIndexEnum@ or - * @link mxmlIndexFind@ for the first time. - */ +// +// 'mxmlIndexReset()' - Reset the enumeration/find pointer in the index and +// return the first node in the index. +// +// This function should be called prior to using @link mxmlIndexEnum@ or +// @link mxmlIndexFind@ for the first time. +// -mxml_node_t * /* O - First node or @code NULL@ if there is none */ -mxmlIndexReset(mxml_index_t *ind) /* I - Index to reset */ +mxml_node_t * // O - First node or `NULL` if there is none +mxmlIndexReset(mxml_index_t *ind) // I - Index to reset { -#ifdef DEBUG - printf("mxmlIndexReset(ind=%p)\n", ind); -#endif /* DEBUG */ - - /* - * Range check input... - */ + MXML_DEBUG("mxmlIndexReset(ind=%p)\n", ind); + // Range check input... if (!ind) return (NULL); - /* - * Set the index to the first element... - */ - + // Set the index to the first element... ind->cur_node = 0; - /* - * Return the first node... - */ - + // Return the first node... if (ind->num_nodes) return (ind->nodes[0]); 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 */ -index_compare(mxml_index_t *ind, /* I - Index */ - mxml_node_t *first, /* I - First node */ - mxml_node_t *second) /* I - Second node */ +static int // O - Result of comparison +index_compare(mxml_index_t *ind, // I - Index + mxml_node_t *first, // I - First node + mxml_node_t *second) // I - Second node { - int diff; /* Difference */ - + int diff; // Difference - /* - * Check the element name... - */ - if ((diff = strcmp(first->value.element.name, - second->value.element.name)) != 0) + // Check the element name... + if ((diff = strcmp(first->value.element.name, second->value.element.name)) != 0) return (diff); - /* - * Check the attribute value... - */ - + // Check the attribute value... if (ind->attr) { - if ((diff = strcmp(mxmlElementGetAttr(first, ind->attr), - mxmlElementGetAttr(second, ind->attr))) != 0) + if ((diff = strcmp(mxmlElementGetAttr(first, ind->attr), mxmlElementGetAttr(second, ind->attr))) != 0) return (diff); } - /* - * No difference, return 0... - */ - + // No difference, 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 */ -index_find(mxml_index_t *ind, /* I - Index */ - const char *element, /* I - Element name or @code NULL@ */ - const char *value, /* I - Attribute value or @code NULL@ */ - mxml_node_t *node) /* I - Node */ +static int // O - Result of comparison +index_find(mxml_index_t *ind, // I - Index + const char *element, // I - Element name or `NULL` + const char *value, // I - Attribute value or `NULL` + mxml_node_t *node) // I - Node { - int diff; /* Difference */ - + int diff; // Difference - /* - * Check the element name... - */ + // Check the element name... if (element) { if ((diff = strcmp(element, node->value.element.name)) != 0) return (diff); } - /* - * Check the attribute value... - */ - + // Check the attribute value... if (value) { if ((diff = strcmp(value, mxmlElementGetAttr(node, ind->attr))) != 0) return (diff); } - /* - * No difference, return 0... - */ - + // No difference, return 0... return (0); } -/* - * 'index_sort()' - Sort the nodes in the index... - * - * This function implements the classic quicksort algorithm... - */ +// +// 'index_sort()' - Sort the nodes in the index... +// +// This function implements the classic quicksort algorithm... +// static void -index_sort(mxml_index_t *ind, /* I - Index to sort */ - int left, /* I - Left node in partition */ - int right) /* I - Right node in partition */ +index_sort(mxml_index_t *ind, // I - Index to sort + int left, // I - Left node in partition + int right) // I - Right node in partition { - mxml_node_t *pivot, /* Pivot node */ - *temp; /* Swap node */ - int templ, /* Temporary left node */ - tempr; /* Temporary right node */ - + mxml_node_t *pivot, // Pivot node + *temp; // Swap node + int templ, // Temporary left 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 { - /* - * Sort the pivot in the current partition... - */ - + // Sort the pivot in the current partition... pivot = ind->nodes[left]; for (templ = left, tempr = right; templ < tempr;) { - /* - * Move left while left node <= pivot node... - */ - - while ((templ < right) && - index_compare(ind, ind->nodes[templ], pivot) <= 0) + // Move left while left node <= pivot node... + while ((templ < right) && index_compare(ind, ind->nodes[templ], pivot) <= 0) templ ++; - /* - * Move right while right node > pivot node... - */ - - while ((tempr > left) && - index_compare(ind, ind->nodes[tempr], pivot) > 0) + // Move right while right node > pivot node... + while ((tempr > left) && index_compare(ind, ind->nodes[tempr], pivot) > 0) tempr --; - /* - * Swap nodes if needed... - */ - + // Swap nodes if needed... if (templ < tempr) { 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) { ind->nodes[left] = ind->nodes[tempr]; ind->nodes[tempr] = pivot; } - /* - * Recursively sort the left partition as needed... - */ - + // Recursively sort the left partition as needed... if (left < (tempr - 1)) index_sort(ind, left, tempr - 1); } diff --git a/mxml-node.c b/mxml-node.c index 45b7071..a554706 100644 --- a/mxml-node.c +++ b/mxml-node.c @@ -1,81 +1,53 @@ -/* - * Node support code for Mini-XML, a small XML file parsing library. - * - * https://www.msweet.org/mxml - * - * Copyright © 2003-2021 by Michael R Sweet. - * - * Licensed under Apache License v2.0. See the file "LICENSE" for more - * information. - */ - -/* - * Include necessary headers... - */ - -#include "config.h" +// +// Node support code for Mini-XML, a small XML file parsing library. +// +// https://www.msweet.org/mxml +// +// Copyright © 2003-2024 by Michael R Sweet. +// +// Licensed under Apache License v2.0. See the file "LICENSE" for more +// information. +// + #include "mxml-private.h" -/* - * Local functions... - */ +// +// Local functions... +// static void mxml_free(mxml_node_t *node); static mxml_node_t *mxml_new(mxml_node_t *parent, mxml_type_t type); -/* - * 'mxmlAdd()' - Add a node to a tree. - * - * Adds the specified node to the parent. If the child argument is not - * @code NULL@, puts the new node before or after the specified child depending - * on the value of the where argument. If the child argument is @code NULL@, - * puts the new node at the beginning of the child list (@code MXML_ADD_BEFORE@) - * or at the end of the child list (@code MXML_ADD_AFTER@). The constant - * @code MXML_ADD_TO_PARENT@ can be used to specify a @code NULL@ child pointer. - */ +// +// 'mxmlAdd()' - Add a node to a tree. +// +// Adds the specified node to the parent. If the child argument is not +// `NULL`, puts the new node before or after the specified child depending +// on the value of the where argument. If the child argument is `NULL`, +// puts the new node at the beginning of the child list (`MXML_ADD_BEFORE`) +// or at the end of the child list (`MXML_ADD_AFTER`). The constant +// `MXML_ADD_TO_PARENT` can be used to specify a `NULL` child pointer. +// void -mxmlAdd(mxml_node_t *parent, /* I - Parent node */ - int where, /* I - Where to add, @code MXML_ADD_BEFORE@ or @code MXML_ADD_AFTER@ */ - mxml_node_t *child, /* I - Child node for where or @code MXML_ADD_TO_PARENT@ */ - mxml_node_t *node) /* I - Node to add */ +mxmlAdd(mxml_node_t *parent, // I - Parent node + int where, // I - Where to add, `MXML_ADD_BEFORE` or `MXML_ADD_AFTER` + mxml_node_t *child, // I - Child node for where or `MXML_ADD_TO_PARENT` + mxml_node_t *node) // I - Node to add { -#ifdef DEBUG - fprintf(stderr, "mxmlAdd(parent=%p, where=%d, child=%p, node=%p)\n", parent, - where, child, node); -#endif /* DEBUG */ - - /* - * Range check input... - */ + MXML_DEBUG("mxmlAdd(parent=%p, where=%d, child=%p, node=%p)\n", parent, where, child, node); + // Range check input... if (!parent || !node) return; -#if DEBUG > 1 - fprintf(stderr, " BEFORE: node->parent=%p\n", node->parent); - if (parent) - { - fprintf(stderr, " BEFORE: parent->child=%p\n", parent->child); - fprintf(stderr, " BEFORE: parent->last_child=%p\n", parent->last_child); - fprintf(stderr, " BEFORE: parent->prev=%p\n", parent->prev); - fprintf(stderr, " BEFORE: parent->next=%p\n", parent->next); - } -#endif /* DEBUG > 1 */ - - /* - * Remove the node from any existing parent... - */ - + // Remove the node from any existing parent... if (node->parent) mxmlRemove(node); - /* - * Reset pointers... - */ - + // Reset pointers... node->parent = parent; switch (where) @@ -83,10 +55,7 @@ mxmlAdd(mxml_node_t *parent, /* I - Parent node */ case MXML_ADD_BEFORE : if (!child || child == parent->child || child->parent != parent) { - /* - * Insert as first node under parent... - */ - + // Insert as first node under parent... node->next = parent->child; if (parent->child) @@ -98,10 +67,7 @@ mxmlAdd(mxml_node_t *parent, /* I - Parent node */ } else { - /* - * Insert node before this child... - */ - + // Insert node before this child... node->next = child; node->prev = child->prev; @@ -117,10 +83,7 @@ mxmlAdd(mxml_node_t *parent, /* I - Parent node */ case MXML_ADD_AFTER : if (!child || child == parent->last_child || child->parent != parent) { - /* - * Insert as last node under parent... - */ - + // Insert as last node under parent... node->parent = parent; node->prev = parent->last_child; @@ -133,10 +96,7 @@ mxmlAdd(mxml_node_t *parent, /* I - Parent node */ } else { - /* - * Insert node after this child... - */ - + // Insert node after this child... node->prev = child; node->next = child->next; @@ -149,196 +109,143 @@ mxmlAdd(mxml_node_t *parent, /* I - Parent node */ } break; } - -#if DEBUG > 1 - fprintf(stderr, " AFTER: node->parent=%p\n", node->parent); - if (parent) - { - fprintf(stderr, " AFTER: parent->child=%p\n", parent->child); - fprintf(stderr, " AFTER: parent->last_child=%p\n", parent->last_child); - fprintf(stderr, " AFTER: parent->prev=%p\n", parent->prev); - fprintf(stderr, " AFTER: parent->next=%p\n", parent->next); - } -#endif /* DEBUG > 1 */ } -/* - * 'mxmlDelete()' - Delete a node and all of its children. - * - * If the specified node has a parent, this function first removes the - * node from its parent using the @link mxmlRemove@ function. - */ +// +// 'mxmlDelete()' - Delete a node and all of its children. +// +// If the specified node has a parent, this function first removes the +// node from its parent using the @link mxmlRemove@ function. +// void -mxmlDelete(mxml_node_t *node) /* I - Node to delete */ +mxmlDelete(mxml_node_t *node) // I - Node to delete { - mxml_node_t *current, /* Current node */ - *next; /* Next node */ - + mxml_node_t *current, // Current node + *next; // Next node -#ifdef DEBUG - fprintf(stderr, "mxmlDelete(node=%p)\n", node); -#endif /* DEBUG */ - /* - * Range check input... - */ + MXML_DEBUG("mxmlDelete(node=%p)\n", node); + // Range check input... if (!node) return; - /* - * Remove the node from its parent, if any... - */ - + // Remove the node from its parent, if any... mxmlRemove(node); - /* - * Delete children... - */ - + // Delete children... for (current = node->child; current; current = next) { - /* - * Get the next node... - */ - + // Get the next node... if ((next = current->child) != NULL) { - /* - * Free parent nodes after child nodes have been freed... - */ - + // Free parent nodes after child nodes have been freed... current->child = NULL; continue; } if ((next = current->next) == NULL) { - /* - * Next node is the parent, which we'll free as needed... - */ - + // Next node is the parent, which we'll free as needed... if ((next = current->parent) == node) next = NULL; } - /* - * Free child... - */ - + // Free child... mxml_free(current); } - /* - * Then free the memory used by the parent node... - */ - + // Then free the memory used by the parent node... mxml_free(node); } -/* - * 'mxmlGetRefCount()' - Get the current reference (use) count for a node. - * - * The initial reference count of new nodes is 1. Use the @link mxmlRetain@ - * and @link mxmlRelease@ functions to increment and decrement a node's - * reference count. - * - * @since Mini-XML 2.7@. - */ +// +// 'mxmlGetRefCount()' - Get the current reference (use) count for a node. +// +// The initial reference count of new nodes is 1. Use the @link mxmlRetain@ +// and @link mxmlRelease@ functions to increment and decrement a node's +// reference count. +// -int /* O - Reference count */ -mxmlGetRefCount(mxml_node_t *node) /* I - Node */ +int // O - Reference count +mxmlGetRefCount(mxml_node_t *node) // I - Node { - /* - * Range check input... - */ - + // Range check input... if (!node) return (0); - /* - * Return the reference count... - */ - + // Return the reference count... return (node->ref_count); } -/* - * 'mxmlNewCDATA()' - Create a new CDATA node. - * - * The new CDATA node is added to the end of the specified parent's child - * list. The constant @code MXML_NO_PARENT@ can be used to specify that the new - * CDATA node has no parent. The data string must be nul-terminated and - * is copied into the new node. CDATA nodes currently use the - * @code MXML_ELEMENT@ type. - * - * @since Mini-XML 2.3@ - */ - -mxml_node_t * /* O - New node */ -mxmlNewCDATA(mxml_node_t *parent, /* I - Parent node or @code MXML_NO_PARENT@ */ - const char *data) /* I - Data string */ -{ - mxml_node_t *node; /* New node */ +// +// 'mxmlNewCDATA()' - Create a new CDATA node. +// +// The new CDATA node is added to the end of the specified parent's child +// list. The constant `MXML_NO_PARENT` can be used to specify that the new +// CDATA node has no parent. The data string must be nul-terminated and +// is copied into the new node. CDATA nodes currently use the +// `MXML_TYPE_ELEMENT` type. +// +mxml_node_t * // O - New node +mxmlNewCDATA(mxml_node_t *parent, // I - Parent node or `MXML_NO_PARENT` + const char *data) // I - Data string +{ + mxml_node_t *node; // New node -#ifdef DEBUG - fprintf(stderr, "mxmlNewCDATA(parent=%p, data=\"%s\")\n", - parent, data ? data : "(null)"); -#endif /* DEBUG */ - /* - * Range check input... - */ + MXML_DEBUG("mxmlNewCDATA(parent=%p, data=\"%s\")\n", parent, data ? data : "(null)"); + // Range check input... if (!data) return (NULL); - /* - * Create the node and set the name value... - */ + // Create the node and set the name value... + if ((node = mxml_new(parent, MXML_TYPE_ELEMENT)) != NULL) + { + size_t datalen = strlen(data); // Length of data - if ((node = mxml_new(parent, MXML_ELEMENT)) != NULL) - node->value.element.name = _mxml_strdupf("![CDATA[%s", data); + if ((node->value.element.name = malloc(datalen + 9)) == NULL) + { + mxml_error("Unable to allocate memory for CDATA."); + mxmlDelete(node); + return (NULL); + } + + snprintf(node->value.element.name, datalen + 9, "![CDATA[%s", data); + } return (node); } -/* - * 'mxmlNewCustom()' - Create a new custom data node. - * - * The new custom node is added to the end of the specified parent's child - * list. The constant @code MXML_NO_PARENT@ can be used to specify that the new - * element node has no parent. @code NULL@ can be passed when the data in the - * node is not dynamically allocated or is separately managed. - * - * @since Mini-XML 2.1@ - */ +// +// 'mxmlNewCustom()' - Create a new custom data node. +// +// The new custom node is added to the end of the specified parent's child +// list. The constant `MXML_NO_PARENT` can be used to specify that the new +// element node has no parent. `NULL` can be passed when the data in the +// node is not dynamically allocated or is separately managed. +// -mxml_node_t * /* O - New node */ +mxml_node_t * // O - New node mxmlNewCustom( - mxml_node_t *parent, /* I - Parent node or @code MXML_NO_PARENT@ */ - void *data, /* I - Pointer to data */ - mxml_custom_destroy_cb_t destroy) /* I - Function to destroy data */ + mxml_node_t *parent, // I - Parent node or `MXML_NO_PARENT` + void *data, // I - Pointer to data + mxml_custom_destroy_cb_t destroy) // I - Function to destroy data { - mxml_node_t *node; /* New node */ - + mxml_node_t *node; // New node -#ifdef DEBUG - fprintf(stderr, "mxmlNewCustom(parent=%p, data=%p, destroy=%p)\n", parent, - data, destroy); -#endif /* DEBUG */ - /* - * Create the node and set the value... - */ + MXML_DEBUG("mxmlNewCustom(parent=%p, data=%p, destroy=%p)\n", parent, data, destroy); - if ((node = mxml_new(parent, MXML_CUSTOM)) != NULL) + // Create the node and set the value... + if ((node = mxml_new(parent, MXML_TYPE_CUSTOM)) != NULL) { node->value.custom.data = data; node->value.custom.destroy = destroy; @@ -348,224 +255,180 @@ mxmlNewCustom( } -/* - * 'mxmlNewElement()' - Create a new element node. - * - * The new element node is added to the end of the specified parent's child - * list. The constant @code MXML_NO_PARENT@ can be used to specify that the new - * element node has no parent. - */ +// +// 'mxmlNewElement()' - Create a new element node. +// +// The new element node is added to the end of the specified parent's child +// list. The constant `MXML_NO_PARENT` can be used to specify that the new +// element node has no parent. +// -mxml_node_t * /* O - New node */ -mxmlNewElement(mxml_node_t *parent, /* I - Parent node or @code MXML_NO_PARENT@ */ - const char *name) /* I - Name of element */ +mxml_node_t * // O - New node +mxmlNewElement(mxml_node_t *parent, // I - Parent node or `MXML_NO_PARENT` + const char *name) // I - Name of element { - mxml_node_t *node; /* New node */ + mxml_node_t *node; // New node -#ifdef DEBUG - fprintf(stderr, "mxmlNewElement(parent=%p, name=\"%s\")\n", parent, - name ? name : "(null)"); -#endif /* DEBUG */ - - /* - * Range check input... - */ + MXML_DEBUG("mxmlNewElement(parent=%p, name=\"%s\")\n", parent, name ? name : "(null)"); + // Range check input... if (!name) return (NULL); - /* - * Create the node and set the element name... - */ - - if ((node = mxml_new(parent, MXML_ELEMENT)) != NULL) + // Create the node and set the element name... + if ((node = mxml_new(parent, MXML_TYPE_ELEMENT)) != NULL) node->value.element.name = strdup(name); return (node); } -/* - * 'mxmlNewInteger()' - Create a new integer node. - * - * The new integer node is added to the end of the specified parent's child - * list. The constant @code MXML_NO_PARENT@ can be used to specify that the new - * integer node has no parent. - */ +// +// 'mxmlNewInteger()' - Create a new integer node. +// +// The new integer node is added to the end of the specified parent's child +// list. The constant `MXML_NO_PARENT` can be used to specify that the new +// integer node has no parent. +// -mxml_node_t * /* O - New node */ -mxmlNewInteger(mxml_node_t *parent, /* I - Parent node or @code MXML_NO_PARENT@ */ - int integer) /* I - Integer value */ +mxml_node_t * // O - New node +mxmlNewInteger(mxml_node_t *parent, // I - Parent node or `MXML_NO_PARENT` + int integer) // I - Integer value { - mxml_node_t *node; /* New node */ + mxml_node_t *node; // New node -#ifdef DEBUG - fprintf(stderr, "mxmlNewInteger(parent=%p, integer=%d)\n", parent, integer); -#endif /* DEBUG */ + MXML_DEBUG("mxmlNewInteger(parent=%p, integer=%d)\n", parent, integer); - /* - * Create the node and set the element name... - */ - - if ((node = mxml_new(parent, MXML_INTEGER)) != NULL) + // Create the node and set the element name... + if ((node = mxml_new(parent, MXML_TYPE_INTEGER)) != NULL) node->value.integer = integer; return (node); } -/* - * 'mxmlNewOpaque()' - Create a new opaque string. - * - * The new opaque string node is added to the end of the specified parent's - * child list. The constant @code MXML_NO_PARENT@ can be used to specify that - * the new opaque string node has no parent. The opaque string must be nul- - * terminated and is copied into the new node. - */ +// +// 'mxmlNewOpaque()' - Create a new opaque string. +// +// The new opaque string node is added to the end of the specified parent's +// child list. The constant `MXML_NO_PARENT` can be used to specify that +// the new opaque string node has no parent. The opaque string must be nul- +// terminated and is copied into the new node. +// -mxml_node_t * /* O - New node */ -mxmlNewOpaque(mxml_node_t *parent, /* I - Parent node or @code MXML_NO_PARENT@ */ - const char *opaque) /* I - Opaque string */ +mxml_node_t * // O - New node +mxmlNewOpaque(mxml_node_t *parent, // I - Parent node or `MXML_NO_PARENT` + const char *opaque) // I - Opaque string { - mxml_node_t *node; /* New node */ - + mxml_node_t *node; // New node -#ifdef DEBUG - fprintf(stderr, "mxmlNewOpaque(parent=%p, opaque=\"%s\")\n", parent, - opaque ? opaque : "(null)"); -#endif /* DEBUG */ - /* - * Range check input... - */ + MXML_DEBUG("mxmlNewOpaque(parent=%p, opaque=\"%s\")\n", parent, opaque ? opaque : "(null)"); + // Range check input... if (!opaque) return (NULL); - /* - * Create the node and set the element name... - */ - - if ((node = mxml_new(parent, MXML_OPAQUE)) != NULL) + // Create the node and set the element name... + if ((node = mxml_new(parent, MXML_TYPE_OPAQUE)) != NULL) node->value.opaque = strdup(opaque); return (node); } -/* - * 'mxmlNewOpaquef()' - Create a new formatted opaque string node. - * - * The new opaque string node is added to the end of the specified parent's - * child list. The constant @code MXML_NO_PARENT@ can be used to specify that - * the new opaque string node has no parent. The format string must be - * nul-terminated and is formatted into the new node. - */ +// +// 'mxmlNewOpaquef()' - Create a new formatted opaque string node. +// +// The new opaque string node is added to the end of the specified parent's +// child list. The constant `MXML_NO_PARENT` can be used to specify that +// the new opaque string node has no parent. The format string must be +// nul-terminated and is formatted into the new node. +// -mxml_node_t * /* O - New node */ -mxmlNewOpaquef(mxml_node_t *parent, /* I - Parent node or @code MXML_NO_PARENT@ */ - const char *format, /* I - Printf-style format string */ - ...) /* I - Additional args as needed */ +mxml_node_t * // O - New node +mxmlNewOpaquef(mxml_node_t *parent, // I - Parent node or `MXML_NO_PARENT` + const char *format, // I - Printf-style format string + ...) // I - Additional args as needed { - mxml_node_t *node; /* New node */ - va_list ap; /* Pointer to arguments */ + mxml_node_t *node; // New node + va_list ap; // Pointer to arguments + char buffer[16384]; // Format buffer -#ifdef DEBUG - fprintf(stderr, "mxmlNewOpaquef(parent=%p, format=\"%s\", ...)\n", parent, format ? format : "(null)"); -#endif /* DEBUG */ - - /* - * Range check input... - */ + MXML_DEBUG("mxmlNewOpaquef(parent=%p, format=\"%s\", ...)\n", parent, format ? format : "(null)"); + // Range check input... if (!format) return (NULL); - /* - * Create the node and set the text value... - */ - - if ((node = mxml_new(parent, MXML_OPAQUE)) != NULL) + // Create the node and set the text value... + if ((node = mxml_new(parent, MXML_TYPE_OPAQUE)) != NULL) { va_start(ap, format); - - node->value.opaque = _mxml_vstrdupf(format, ap); - + vsnprintf(buffer, sizeof(buffer), format, ap); va_end(ap); + + node->value.opaque = strdup(buffer); } return (node); } -/* - * 'mxmlNewReal()' - Create a new real number node. - * - * The new real number node is added to the end of the specified parent's - * child list. The constant @code MXML_NO_PARENT@ can be used to specify that - * the new real number node has no parent. - */ +// +// 'mxmlNewReal()' - Create a new real number node. +// +// The new real number node is added to the end of the specified parent's +// child list. The constant `MXML_NO_PARENT` can be used to specify that +// the new real number node has no parent. +// -mxml_node_t * /* O - New node */ -mxmlNewReal(mxml_node_t *parent, /* I - Parent node or @code MXML_NO_PARENT@ */ - double real) /* I - Real number value */ +mxml_node_t * // O - New node +mxmlNewReal(mxml_node_t *parent, // I - Parent node or `MXML_NO_PARENT` + double real) // I - Real number value { - mxml_node_t *node; /* New node */ - + mxml_node_t *node; // New node -#ifdef DEBUG - fprintf(stderr, "mxmlNewReal(parent=%p, real=%g)\n", parent, real); -#endif /* DEBUG */ - /* - * Create the node and set the element name... - */ + MXML_DEBUG("mxmlNewReal(parent=%p, real=%g)\n", parent, real); - if ((node = mxml_new(parent, MXML_REAL)) != NULL) + // Create the node and set the element name... + if ((node = mxml_new(parent, MXML_TYPE_REAL)) != NULL) node->value.real = real; return (node); } -/* - * 'mxmlNewText()' - Create a new text fragment node. - * - * The new text node is added to the end of the specified parent's child - * list. The constant @code MXML_NO_PARENT@ can be used to specify that the new - * text node has no parent. The whitespace parameter is used to specify - * whether leading whitespace is present before the node. The text - * string must be nul-terminated and is copied into the new node. - */ - -mxml_node_t * /* O - New node */ -mxmlNewText(mxml_node_t *parent, /* I - Parent node or @code MXML_NO_PARENT@ */ - int whitespace, /* I - 1 = leading whitespace, 0 = no whitespace */ - const char *string) /* I - String */ +// +// 'mxmlNewText()' - Create a new text fragment node. +// +// The new text node is added to the end of the specified parent's child +// list. The constant `MXML_NO_PARENT` can be used to specify that the new +// text node has no parent. The whitespace parameter is used to specify +// whether leading whitespace is present before the node. The text +// string must be nul-terminated and is copied into the new node. +// + +mxml_node_t * // O - New node +mxmlNewText(mxml_node_t *parent, // I - Parent node or `MXML_NO_PARENT` + int whitespace, // I - 1 = leading whitespace, 0 = no whitespace + const char *string) // I - String { - mxml_node_t *node; /* New node */ + mxml_node_t *node; // New node -#ifdef DEBUG - fprintf(stderr, "mxmlNewText(parent=%p, whitespace=%d, string=\"%s\")\n", - parent, whitespace, string ? string : "(null)"); -#endif /* DEBUG */ - - /* - * Range check input... - */ + MXML_DEBUG("mxmlNewText(parent=%p, whitespace=%d, string=\"%s\")\n", parent, whitespace, string ? string : "(null)"); + // Range check input... if (!string) return (NULL); - /* - * Create the node and set the text value... - */ - - if ((node = mxml_new(parent, MXML_TEXT)) != NULL) + // Create the node and set the text value... + if ((node = mxml_new(parent, MXML_TYPE_TEXT)) != NULL) { node->value.text.whitespace = whitespace; node->value.text.string = strdup(string); @@ -575,94 +438,65 @@ mxmlNewText(mxml_node_t *parent, /* I - Parent node or @code MXML_NO_PARENT@ */ } -/* - * 'mxmlNewTextf()' - Create a new formatted text fragment node. - * - * The new text node is added to the end of the specified parent's child - * list. The constant @code MXML_NO_PARENT@ can be used to specify that the new - * text node has no parent. The whitespace parameter is used to specify - * whether leading whitespace is present before the node. The format - * string must be nul-terminated and is formatted into the new node. - */ - -mxml_node_t * /* O - New node */ -mxmlNewTextf(mxml_node_t *parent, /* I - Parent node or @code MXML_NO_PARENT@ */ - int whitespace, /* I - 1 = leading whitespace, 0 = no whitespace */ - const char *format, /* I - Printf-style format string */ - ...) /* I - Additional args as needed */ +// +// 'mxmlNewTextf()' - Create a new formatted text fragment node. +// +// The new text node is added to the end of the specified parent's child +// list. The constant `MXML_NO_PARENT` can be used to specify that the new +// text node has no parent. The whitespace parameter is used to specify +// whether leading whitespace is present before the node. The format +// string must be nul-terminated and is formatted into the new node. +// + +mxml_node_t * // O - New node +mxmlNewTextf(mxml_node_t *parent, // I - Parent node or `MXML_NO_PARENT` + int whitespace, // I - 1 = leading whitespace, 0 = no whitespace + const char *format, // I - Printf-style format string + ...) // I - Additional args as needed { - mxml_node_t *node; /* New node */ - va_list ap; /* Pointer to arguments */ - + mxml_node_t *node; // New node + va_list ap; // Pointer to arguments + char buffer[16384]; // Format buffer -#ifdef DEBUG - fprintf(stderr, "mxmlNewTextf(parent=%p, whitespace=%d, format=\"%s\", ...)\n", - parent, whitespace, format ? format : "(null)"); -#endif /* DEBUG */ - /* - * Range check input... - */ + MXML_DEBUG("mxmlNewTextf(parent=%p, whitespace=%d, format=\"%s\", ...)\n", parent, whitespace, format ? format : "(null)"); + // Range check input... if (!format) return (NULL); - /* - * Create the node and set the text value... - */ - - if ((node = mxml_new(parent, MXML_TEXT)) != NULL) + // Create the node and set the text value... + if ((node = mxml_new(parent, MXML_TYPE_TEXT)) != NULL) { va_start(ap, format); + vsnprintf(buffer, sizeof(buffer), format, ap); + va_end(ap); node->value.text.whitespace = whitespace; - node->value.text.string = _mxml_vstrdupf(format, ap); - - va_end(ap); + node->value.text.string = strdup(buffer); } return (node); } -/* - * 'mxmlRemove()' - Remove a node from its parent. - * - * This function does not free memory used by the node - use @link mxmlDelete@ - * for that. This function does nothing if the node has no parent. - */ +// +// 'mxmlRemove()' - Remove a node from its parent. +// +// This function does not free memory used by the node - use @link mxmlDelete@ +// for that. This function does nothing if the node has no parent. +// void -mxmlRemove(mxml_node_t *node) /* I - Node to remove */ +mxmlRemove(mxml_node_t *node) // I - Node to remove { -#ifdef DEBUG - fprintf(stderr, "mxmlRemove(node=%p)\n", node); -#endif /* DEBUG */ - - /* - * Range check input... - */ + MXML_DEBUG("mxmlRemove(node=%p)\n", node); + // Range check input... if (!node || !node->parent) return; - /* - * Remove from parent... - */ - -#if DEBUG > 1 - fprintf(stderr, " BEFORE: node->parent=%p\n", node->parent); - if (node->parent) - { - fprintf(stderr, " BEFORE: node->parent->child=%p\n", node->parent->child); - fprintf(stderr, " BEFORE: node->parent->last_child=%p\n", node->parent->last_child); - } - fprintf(stderr, " BEFORE: node->child=%p\n", node->child); - fprintf(stderr, " BEFORE: node->last_child=%p\n", node->last_child); - fprintf(stderr, " BEFORE: node->prev=%p\n", node->prev); - fprintf(stderr, " BEFORE: node->next=%p\n", node->next); -#endif /* DEBUG > 1 */ - + // Remove from parent... if (node->prev) node->prev->next = node->next; else @@ -676,55 +510,37 @@ mxmlRemove(mxml_node_t *node) /* I - Node to remove */ node->parent = NULL; node->prev = NULL; node->next = NULL; - -#if DEBUG > 1 - fprintf(stderr, " AFTER: node->parent=%p\n", node->parent); - if (node->parent) - { - fprintf(stderr, " AFTER: node->parent->child=%p\n", node->parent->child); - fprintf(stderr, " AFTER: node->parent->last_child=%p\n", node->parent->last_child); - } - fprintf(stderr, " AFTER: node->child=%p\n", node->child); - fprintf(stderr, " AFTER: node->last_child=%p\n", node->last_child); - fprintf(stderr, " AFTER: node->prev=%p\n", node->prev); - fprintf(stderr, " AFTER: node->next=%p\n", node->next); -#endif /* DEBUG > 1 */ } -/* - * 'mxmlNewXML()' - Create a new XML document tree. - * - * The "version" argument specifies the version number to put in the - * ?xml element node. If @code NULL@, version "1.0" is assumed. - * - * @since Mini-XML 2.3@ - */ +// +// 'mxmlNewXML()' - Create a new XML document tree. +// +// The "version" argument specifies the version number to put in the +// ?xml element node. If `NULL`, version "1.0" is assumed. +// -mxml_node_t * /* O - New ?xml node */ -mxmlNewXML(const char *version) /* I - Version number to use */ +mxml_node_t * // O - New ?xml node +mxmlNewXML(const char *version) // I - Version number to use { - char element[1024]; /* Element text */ + char element[1024]; // Element text - snprintf(element, sizeof(element), "?xml version=\"%s\" encoding=\"utf-8\"?", - version ? version : "1.0"); + snprintf(element, sizeof(element), "?xml version=\"%s\" encoding=\"utf-8\"?", version ? version : "1.0"); return (mxmlNewElement(NULL, element)); } -/* - * 'mxmlRelease()' - Release a node. - * - * When the reference count reaches zero, the node (and any children) - * is deleted via @link mxmlDelete@. - * - * @since Mini-XML 2.3@ - */ +// +// 'mxmlRelease()' - Release a node. +// +// When the reference count reaches zero, the node (and any children) +// is deleted via @link mxmlDelete@. +// -int /* O - New reference count */ -mxmlRelease(mxml_node_t *node) /* I - Node */ +int // O - New reference count +mxmlRelease(mxml_node_t *node) // I - Node { if (node) { @@ -734,21 +550,23 @@ mxmlRelease(mxml_node_t *node) /* I - Node */ return (0); } else + { return (node->ref_count); + } } else + { return (-1); + } } -/* - * 'mxmlRetain()' - Retain a node. - * - * @since Mini-XML 2.3@ - */ +// +// 'mxmlRetain()' - Retain a node. +// -int /* O - New reference count */ -mxmlRetain(mxml_node_t *node) /* I - Node */ +int // O - New reference count +mxmlRetain(mxml_node_t *node) // I - Node { if (node) return (++ node->ref_count); @@ -757,21 +575,21 @@ mxmlRetain(mxml_node_t *node) /* I - Node */ } -/* - * 'mxml_free()' - Free the memory used by a node. - * - * Note: Does not free child nodes, does not remove from parent. - */ +// +// 'mxml_free()' - Free the memory used by a node. +// +// Note: Does not free child nodes, does not remove from parent. +// static void -mxml_free(mxml_node_t *node) /* I - Node */ +mxml_free(mxml_node_t *node) // I - Node { - int i; /* Looping var */ + int i; // Looping var switch (node->type) { - case MXML_ELEMENT : + case MXML_TYPE_ELEMENT : free(node->value.element.name); if (node->value.element.num_attrs) @@ -785,84 +603,61 @@ mxml_free(mxml_node_t *node) /* I - Node */ free(node->value.element.attrs); } break; - case MXML_INTEGER : - /* Nothing to do */ + case MXML_TYPE_INTEGER : + // Nothing to do break; - case MXML_OPAQUE : + case MXML_TYPE_OPAQUE : free(node->value.opaque); break; - case MXML_REAL : - /* Nothing to do */ + case MXML_TYPE_REAL : + // Nothing to do break; - case MXML_TEXT : + case MXML_TYPE_TEXT : free(node->value.text.string); break; - case MXML_CUSTOM : - if (node->value.custom.data && - node->value.custom.destroy) + case MXML_TYPE_CUSTOM : + if (node->value.custom.data && node->value.custom.destroy) (*(node->value.custom.destroy))(node->value.custom.data); break; default : break; } - /* - * Free this node... - */ - + // Free this node... free(node); } -/* - * 'mxml_new()' - Create a new node. - */ +// +// 'mxml_new()' - Create a new node. +// -static mxml_node_t * /* O - New node */ -mxml_new(mxml_node_t *parent, /* I - Parent node */ - mxml_type_t type) /* I - Node type */ +static mxml_node_t * // O - New node +mxml_new(mxml_node_t *parent, // I - Parent node + mxml_type_t type) // I - Node type { - mxml_node_t *node; /* New node */ - + mxml_node_t *node; // New node -#if DEBUG > 1 - fprintf(stderr, "mxml_new(parent=%p, type=%d)\n", parent, type); -#endif /* DEBUG > 1 */ - /* - * Allocate memory for the node... - */ + MXML_DEBUG("mxml_new(parent=%p, type=%d)\n", parent, type); + // Allocate memory for the node... if ((node = calloc(1, sizeof(mxml_node_t))) == NULL) { -#if DEBUG > 1 - fputs(" returning NULL\n", stderr); -#endif /* DEBUG > 1 */ - + MXML_DEBUG("mxml_new: Returning NULL\n"); return (NULL); } -#if DEBUG > 1 - fprintf(stderr, " returning %p\n", node); -#endif /* DEBUG > 1 */ - - /* - * Set the node type... - */ + MXML_DEBUG("mxml_new: Returning %p\n", node); + // Set the node type... node->type = type; node->ref_count = 1; - /* - * Add to the parent if present... - */ - + // Add to the parent if present... if (parent) mxmlAdd(parent, MXML_ADD_AFTER, MXML_ADD_TO_PARENT, node); - /* - * Return the new node... - */ - + // Return the new node... return (node); } diff --git a/mxml-private.c b/mxml-private.c index ec4f0de..3f008bb 100644 --- a/mxml-private.c +++ b/mxml-private.c @@ -1,34 +1,30 @@ -/* - * Private functions for Mini-XML, a small XML file parsing library. - * - * https://www.msweet.org/mxml - * - * Copyright © 2003-2022 by Michael R Sweet. - * - * Licensed under Apache License v2.0. See the file "LICENSE" for more - * information. - */ - -/* - * Include necessary headers... - */ +// +// Private functions for Mini-XML, a small XML file parsing library. +// +// https://www.msweet.org/mxml +// +// Copyright © 2003-2024 by Michael R Sweet. +// +// Licensed under Apache License v2.0. See the file "LICENSE" for more +// information. +// #include "mxml-private.h" -/* - * 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 - * and bad things *will* happen. - * - * 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 - * 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. - * - * 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. - */ +// +// 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 +// and bad things *will* happen. +// +// 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 +// 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. +// +// 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. +// #if defined(__sun) || defined(_AIX) # pragma fini(_mxml_fini) @@ -36,133 +32,122 @@ #elif defined(__hpux) # pragma 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 #else # define _MXML_FINI _fini -#endif /* __sun */ +#endif // __sun -/* - * 'mxml_error()' - Display an error message. - */ +// +// 'mxml_error()' - Display an error message. +// void -mxml_error(const char *format, /* I - Printf-style format string */ - ...) /* I - Additional arguments as needed */ +mxml_error(const char *format, // I - Printf-style format string + ...) // I - Additional arguments as needed { - va_list ap; /* Pointer to arguments */ - char s[1024]; /* Message string */ + va_list ap; // Pointer to arguments + char s[1024]; // Message string _mxml_global_t *global = _mxml_global(); - /* Global data */ + // Global data - /* - * Range check input... - */ - + // Range check input... if (!format) return; - /* - * Format the error message string... - */ - + // Format the error message string... va_start(ap, format); - vsnprintf(s, sizeof(s), format, ap); - va_end(ap); - /* - * And then display the error message... - */ - + // And then display the error message... if (global->error_cb) (*global->error_cb)(s); 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_ignore_cb(mxml_node_t *node) /* I - Current node */ +mxml_type_t // O - Node type +mxml_ignore_cb(mxml_node_t *node) // I - Current 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_integer_cb(mxml_node_t *node) /* I - Current node */ +mxml_type_t // O - Node type +mxml_integer_cb(mxml_node_t *node) // I - Current 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_opaque_cb(mxml_node_t *node) /* I - Current node */ +mxml_type_t // O - Node type +mxml_opaque_cb(mxml_node_t *node) // I - Current 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_real_cb(mxml_node_t *node) /* I - Current node */ +mxml_type_t // O - Node type +mxml_real_cb(mxml_node_t *node) // I - Current node { (void)node; - return (MXML_REAL); + return (MXML_TYPE_REAL); } -#ifdef HAVE_PTHREAD_H /**** POSIX threading ****/ +#ifdef HAVE_PTHREAD_H // POSIX threading # include static int _mxml_initialized = 0; - /* Have we been initialized? */ -static pthread_key_t _mxml_key; /* Thread local storage key */ + // Have we been initialized? +static pthread_key_t _mxml_key; // Thread local storage key 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_destructor(void *g); -/* - * '_mxml_destructor()' - Free memory used for globals... - */ +// +// '_mxml_destructor()' - Free memory used for globals... +// static void -_mxml_destructor(void *g) /* I - Global data */ +_mxml_destructor(void *g) // I - Global data { free(g); } -/* - * '_mxml_fini()' - Clean up when unloaded. - */ +// +// '_mxml_fini()' - Clean up when unloaded. +// static 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_t *global; /* Global data */ + _mxml_global_t *global; // Global data 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 _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 -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 */ -DllMain(HINSTANCE hinst, /* I - DLL module handle */ - DWORD reason, /* I - Reason */ - LPVOID reserved) /* I - Unused */ +BOOL WINAPI // O - Success/failure +DllMain(HINSTANCE hinst, // I - DLL module handle + DWORD reason, // I - Reason + LPVOID reserved) // I - Unused { - _mxml_global_t *global; /* Global data */ + _mxml_global_t *global; // Global data (void)hinst; @@ -233,17 +218,17 @@ DllMain(HINSTANCE hinst, /* I - DLL module handle */ 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) return (FALSE); 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) free(global); 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) 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_t *global; /* Global data */ + _mxml_global_t *global; // Global data if ((global = (_mxml_global_t *)TlsGetValue(_mxml_tls_index)) == NULL) @@ -283,25 +268,25 @@ _mxml_global(void) } -#else /**** No threading ****/ -/* - * '_mxml_global()' - Get global data. - */ +#else // No threading +// +// '_mxml_global()' - Get global data. +// -_mxml_global_t * /* O - Global data */ +_mxml_global_t * // O - Global data _mxml_global(void) { - static _mxml_global_t global = /* Global data */ + static _mxml_global_t global = // Global data { - NULL, /* error_cb */ - 1, /* num_entity_cbs */ - { _mxml_entity_cb }, /* entity_cbs */ - 72, /* wrap */ - NULL, /* custom_load_cb */ - NULL /* custom_save_cb */ + NULL, // error_cb + 1, // num_entity_cbs + { _mxml_entity_cb }, // entity_cbs + 72, // wrap + NULL, // custom_load_cb + NULL // custom_save_cb }; return (&global); } -#endif /* HAVE_PTHREAD_H */ +#endif // HAVE_PTHREAD_H diff --git a/mxml-private.h b/mxml-private.h index 80fa28b..32d5a49 100644 --- a/mxml-private.h +++ b/mxml-private.h @@ -1,87 +1,93 @@ -/* - * Private definitions 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. - */ - -#ifndef _mxml_private_h_ -# define _mxml_private_h_ - -/* - * Include necessary headers... - */ - +// +// Private definitions for Mini-XML, a small XML file parsing library. +// +// https://www.msweet.org/mxml +// +// Copyright © 2003-2024 by Michael R Sweet. +// +// Licensed under Apache License v2.0. See the file "LICENSE" for more +// information. +// + +#ifndef MXML_PRIVATE_H +# define MXML_PRIVATE_H # include "config.h" # include "mxml.h" -/* - * Private structures... - */ +// +// Private macros... +// + +# ifdef DEBUG +# define MXML_DEBUG(...) fprintf(stderr, __VA_ARGS__) +# else +# define MXML_DEBUG(...) +# endif // DEBUG + -typedef struct _mxml_attr_s /**** An XML element attribute value. ****/ +// +// Private structures... +// + +typedef struct _mxml_attr_s // An XML element attribute value. { - char *name; /* Attribute name */ - char *value; /* Attribute value */ + char *name; // Attribute name + char *value; // Attribute value } _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 */ - int num_attrs; /* Number of attributes */ - _mxml_attr_t *attrs; /* Attributes */ + char *name; // Name of element + int num_attrs; // Number of attributes + _mxml_attr_t *attrs; // Attributes } _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? */ - char *string; /* Fragment string */ + int whitespace; // Leading whitespace? + char *string; // Fragment string } _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 */ - mxml_custom_destroy_cb_t destroy; /* Pointer to destructor function */ + void *data; // Pointer to (allocated) custom data + mxml_custom_destroy_cb_t destroy; // Pointer to destructor function } _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 */ - int integer; /* Integer number */ - char *opaque; /* Opaque string */ - double real; /* Real number */ - _mxml_text_t text; /* Text fragment */ - _mxml_custom_t custom; /* Custom data @since Mini-XML 2.1@ */ + _mxml_element_t element; // Element + int integer; // Integer number + char *opaque; // Opaque string + double real; // Real number + _mxml_text_t text; // Text fragment + _mxml_custom_t custom; // Custom data @since Mini-XML 2.1@ } _mxml_value_t; -struct _mxml_node_s /**** An XML node. ****/ +struct _mxml_node_s // An XML node. { - mxml_type_t type; /* Node type */ - struct _mxml_node_s *next; /* Next 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 *child; /* First child node */ - struct _mxml_node_s *last_child; /* Last child node */ - _mxml_value_t value; /* Node value */ - int ref_count; /* Use count */ - void *user_data; /* User data */ + mxml_type_t type; // Node type + struct _mxml_node_s *next; // Next 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 *child; // First child node + struct _mxml_node_s *last_child; // Last child node + _mxml_value_t value; // Node value + int ref_count; // Use count + 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 */ - int num_nodes; /* Number of nodes in index */ - int alloc_nodes; /* Allocated nodes in index */ - int cur_node; /* Current node */ - mxml_node_t **nodes; /* Node array */ + char *attr; // Attribute used for indexing or NULL + int num_nodes; // Number of nodes in index + int alloc_nodes; // Allocated nodes in index + int cur_node; // Current node + 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 *); @@ -93,11 +99,12 @@ typedef struct _mxml_global_s /**** Global, per-thread data ****/ } _mxml_global_t; -/* - * Functions... - */ +// +// Private functions... +// extern _mxml_global_t *_mxml_global(void); extern int _mxml_entity_cb(const char *name); -#endif /* !_mxml_private_h_ */ + +#endif // !MXML_PRIVATE_H diff --git a/mxml-search.c b/mxml-search.c index 8e2ef0a..ad3f66d 100644 --- a/mxml-search.c +++ b/mxml-search.c @@ -1,99 +1,68 @@ -/* - * Search/navigation 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" +// +// Search/navigation functions for Mini-XML, a small XML file parsing library. +// +// https://www.msweet.org/mxml +// +// Copyright © 2003-2024 by Michael R Sweet. +// +// Licensed under Apache License v2.0. See the file "LICENSE" for more +// information. +// + #include "mxml-private.h" -/* - * 'mxmlFindElement()' - Find the named element. - * - * 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 - * searches can be implemented by looking for all elements of a given name - * or all elements with a specific attribute. The descend argument determines - * whether the search descends into child nodes; normally you will use - * @code MXML_DESCEND_FIRST@ for the initial search and @code MXML_NO_DESCEND@ - * to find additional direct descendents of the node. The top node argument - * constrains the search to a particular node's children. - */ - -mxml_node_t * /* O - Element node or @code NULL@ */ -mxmlFindElement(mxml_node_t *node, /* I - Current node */ - mxml_node_t *top, /* I - Top node */ - const char *element, /* I - Element name or @code NULL@ for any */ - const char *attr, /* I - Attribute name, or @code NULL@ for none */ - const char *value, /* I - Attribute value, or @code NULL@ for any */ - int descend) /* I - Descend into tree - @code MXML_DESCEND@, @code MXML_NO_DESCEND@, or @code MXML_DESCEND_FIRST@ */ +// +// 'mxmlFindElement()' - Find the named element. +// +// The search is constrained by the name, attribute name, and value; any +// `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 +// or all elements with a specific attribute. The descend argument determines +// whether the search descends into child nodes; normally you will use +// `MXML_DESCEND_FIRST` for the initial search and `MXML_NO_DESCEND` +// to find additional direct descendents of the node. The top node argument +// constrains the search to a particular node's children. +// + +mxml_node_t * // O - Element node or `NULL` +mxmlFindElement(mxml_node_t *node, // I - Current node + mxml_node_t *top, // I - Top node + const char *element, // I - Element name or `NULL` for any + const char *attr, // I - Attribute name, or `NULL` for none + const char *value, // I - Attribute value, or `NULL` for any + 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)) return (NULL); - /* - * Start with the next node... - */ - + // Start with the next node... node = mxmlWalkNext(node, top, descend); - /* - * Loop until we find a matching element... - */ - + // Loop until we find a matching element... while (node != NULL) { - /* - * See if this node matches... - */ - - if (node->type == MXML_ELEMENT && - node->value.element.name && - (!element || !strcmp(node->value.element.name, element))) + // See if this node matches... + if (node->type == MXML_TYPE_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) - return (node); /* No attribute search, return it... */ - - /* - * Check for the attribute... - */ + return (node); // No attribute search, return it... + // Check for the attribute... 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)) - 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) node = mxmlWalkNext(node, top, MXML_DESCEND); else @@ -104,59 +73,47 @@ mxmlFindElement(mxml_node_t *node, /* I - Current node */ } -/* - * 'mxmlFindPath()' - Find a node with the given path. - * - * 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, - * "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 - * children and the first child is a value node. - * - * @since Mini-XML 2.7@ - */ - -mxml_node_t * /* O - Found node or @code NULL@ */ -mxmlFindPath(mxml_node_t *top, /* I - Top node */ - const char *path) /* I - Path to element */ +// +// 'mxmlFindPath()' - Find a node with the given path. +// +// 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, +// "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 +// children and the first child is a value node. +// + +mxml_node_t * // O - Found node or `NULL` +mxmlFindPath(mxml_node_t *top, // I - Top node + const char *path) // I - Path to element { - mxml_node_t *node; /* Current node */ - char element[256]; /* Current element name */ - const char *pathsep; /* Separator in path */ - int descend; /* mxmlFindElement option */ - + mxml_node_t *node; // Current node + char element[256]; // Current element name + const char *pathsep; // Separator in path + int descend; // mxmlFindElement option - /* - * Range check input... - */ + // Range check input... if (!top || !path || !*path) return (NULL); - /* - * Search each element in the path... - */ - + // Search each element in the path... node = top; while (*path) { - /* - * Handle wildcards... - */ - + // Handle wildcards... if (!strncmp(path, "*/", 2)) { path += 2; descend = MXML_DESCEND; } else + { descend = MXML_DESCEND_FIRST; + } - /* - * Get the next element in the path... - */ - + // Get the next element in the path... if ((pathsep = strchr(path, '/')) == NULL) pathsep = path + strlen(path); @@ -171,87 +128,91 @@ mxmlFindPath(mxml_node_t *top, /* I - Top node */ else path = pathsep; - /* - * Search for the element... - */ - - if ((node = mxmlFindElement(node, node, element, NULL, NULL, - descend)) == NULL) + // Search for the element... + if ((node = mxmlFindElement(node, node, element, NULL, NULL, descend)) == NULL) return (NULL); } - /* - * If we get this far, return the node or its first child... - */ - - if (node->child && node->child->type != MXML_ELEMENT) + // If we get this far, return the node or its first child... + if (node->child && node->child->type != MXML_TYPE_ELEMENT) return (node->child); else return (node); } -/* - * 'mxmlWalkNext()' - Walk to the next logical node in the tree. - * - * The descend argument controls whether the first child is considered - * to be the next node. The top node argument constrains the walk to - * the node's children. - */ +// +// 'mxmlWalkNext()' - Walk to the next logical node in the tree. +// +// The descend argument controls whether the first child is considered +// to be the next node. The top node argument constrains the walk to +// the node's children. +// -mxml_node_t * /* O - Next node or @code NULL@ */ -mxmlWalkNext(mxml_node_t *node, /* I - Current 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@ */ +mxml_node_t * // O - Next node or `NULL` +mxmlWalkNext(mxml_node_t *node, // I - Current node + mxml_node_t *top, // I - Top node + int descend) // I - Descend into tree - `MXML_DESCEND`, `MXML_NO_DESCEND`, or `MXML_DESCEND_FIRST` { if (!node) + { return (NULL); + } else if (node->child && descend) + { return (node->child); + } else if (node == top) + { return (NULL); + } else if (node->next) + { return (node->next); + } else if (node->parent && node->parent != top) { node = node->parent; while (!node->next) + { if (node->parent == top || !node->parent) return (NULL); else node = node->parent; + } return (node->next); } else + { return (NULL); + } } -/* - * 'mxmlWalkPrev()' - Walk to the previous logical node in the tree. - * - * The descend argument controls whether the previous node's last child - * is considered to be the previous node. The top node argument constrains - * the walk to the node's children. - */ +// +// 'mxmlWalkPrev()' - Walk to the previous logical node in the tree. +// +// The descend argument controls whether the previous node's last child +// is considered to be the previous node. The top node argument constrains +// the walk to the node's children. +// -mxml_node_t * /* O - Previous node or @code NULL@ */ -mxmlWalkPrev(mxml_node_t *node, /* I - Current 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@ */ +mxml_node_t * // O - Previous node or `NULL` +mxmlWalkPrev(mxml_node_t *node, // I - Current node + mxml_node_t *top, // I - Top node + int descend) // I - Descend into tree - `MXML_DESCEND`, `MXML_NO_DESCEND`, or `MXML_DESCEND_FIRST` { if (!node || node == top) + { return (NULL); + } else if (node->prev) { 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; while (node->last_child) @@ -260,10 +221,16 @@ mxmlWalkPrev(mxml_node_t *node, /* I - Current node */ return (node); } else + { return (node->prev); + } } else if (node->parent != top) + { return (node->parent); + } else + { return (NULL); + } } diff --git a/mxml-set.c b/mxml-set.c index 5f5423f..1ae56db 100644 --- a/mxml-set.c +++ b/mxml-set.c @@ -1,49 +1,36 @@ -/* - * Node set functions for Mini-XML, a small XML file parsing library. - * - * https://www.msweet.org/mxml - * - * Copyright © 2003-2021 by Michael R Sweet. - * - * Licensed under Apache License v2.0. See the file "LICENSE" for more - * information. - */ - -/* - * Include necessary headers... - */ - -#include "config.h" +// +// Node set functions for Mini-XML, a small XML file parsing library. +// +// https://www.msweet.org/mxml +// +// Copyright © 2003-2024 by Michael R Sweet. +// +// Licensed under Apache License v2.0. See the file "LICENSE" for more +// information. +// + #include "mxml-private.h" -/* - * '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. - * - * @since Mini-XML 2.3@ - */ +// +// '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. +// -int /* O - 0 on success, -1 on failure */ -mxmlSetCDATA(mxml_node_t *node, /* I - Node to set */ - const char *data) /* I - New data string */ +int // O - 0 on success, -1 on failure +mxmlSetCDATA(mxml_node_t *node, // I - Node to set + 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... - */ - 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)) + // 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)) node = node->child; - if (!node || node->type != MXML_ELEMENT || - strncmp(node->value.element.name, "![CDATA[", 8)) + if (!node || node->type != MXML_TYPE_ELEMENT || strncmp(node->value.element.name, "![CDATA[", 8)) { mxml_error("Wrong node type."); return (-1); @@ -56,18 +43,14 @@ mxmlSetCDATA(mxml_node_t *node, /* I - Node to set */ if (data == (node->value.element.name + 8)) { - /* - * Don't change the value... - */ - + // Don't change the value... 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."); return (-1); @@ -75,34 +58,29 @@ mxmlSetCDATA(mxml_node_t *node, /* I - Node to set */ free(node->value.element.name); node->value.element.name = s; + snprintf(node->value.element.name, datalen + 9, "![CDATA[%s", data); return (0); } -/* - * '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. - * - * @since Mini-XML 2.1@ - */ +// +// '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. +// -int /* O - 0 on success, -1 on failure */ +int // O - 0 on success, -1 on failure mxmlSetCustom( - mxml_node_t *node, /* I - Node to set */ - void *data, /* I - New data pointer */ - mxml_custom_destroy_cb_t destroy) /* I - New destructor function */ + mxml_node_t *node, // I - Node to set + void *data, // I - New data pointer + mxml_custom_destroy_cb_t destroy) // I - New destructor function { - /* - * Range check input... - */ - - if (node && node->type == MXML_ELEMENT && - node->child && node->child->type == MXML_CUSTOM) + // Range check input... + if (node && node->type == MXML_TYPE_ELEMENT && node->child && node->child->type == MXML_TYPE_CUSTOM) node = node->child; - if (!node || node->type != MXML_CUSTOM) + if (!node || node->type != MXML_TYPE_CUSTOM) { mxml_error("Wrong node type."); return (-1); @@ -114,10 +92,7 @@ mxmlSetCustom( 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) (*(node->value.custom.destroy))(node->value.custom.data); @@ -128,24 +103,21 @@ mxmlSetCustom( } -/* - * 'mxmlSetElement()' - Set the name of an element node. - * - * The node is not changed if it is not an element node. - */ +// +// 'mxmlSetElement()' - Set the name of an element node. +// +// The node is not changed if it is not an element node. +// -int /* O - 0 on success, -1 on failure */ -mxmlSetElement(mxml_node_t *node, /* I - Node to set */ - const char *name) /* I - New name string */ +int // O - 0 on success, -1 on failure +mxmlSetElement(mxml_node_t *node, // I - Node to set + const char *name) // I - New name string { - char *s; /* New name string */ + char *s; // New name string - /* - * Range check input... - */ - - if (!node || node->type != MXML_ELEMENT) + // Range check input... + if (!node || node->type != MXML_TYPE_ELEMENT) { mxml_error("Wrong node type."); return (-1); @@ -159,10 +131,7 @@ mxmlSetElement(mxml_node_t *node, /* I - Node to set */ if (name == node->value.element.name) 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) { 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. - * - * The node is not changed if it (or its first child) is not 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. +// -int /* O - 0 on success, -1 on failure */ -mxmlSetInteger(mxml_node_t *node, /* I - Node to set */ - int integer) /* I - Integer value */ +int // O - 0 on success, -1 on failure +mxmlSetInteger(mxml_node_t *node, // I - Node to set + int integer) // I - Integer value { - /* - * Range check input... - */ - - if (node && node->type == MXML_ELEMENT && - node->child && node->child->type == MXML_INTEGER) + // Range check input... + if (node && node->type == MXML_TYPE_ELEMENT && node->child && node->child->type == MXML_TYPE_INTEGER) node = node->child; - if (!node || node->type != MXML_INTEGER) + if (!node || node->type != MXML_TYPE_INTEGER) { mxml_error("Wrong node type."); return (-1); } - /* - * Set the new value and return... - */ - + // Set the new value and return... node->value.integer = integer; return (0); } -/* - * 'mxmlSetOpaque()' - Set the value of an opaque node. - * - * The node is not changed if it (or its first child) is not 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. +// -int /* O - 0 on success, -1 on failure */ -mxmlSetOpaque(mxml_node_t *node, /* I - Node to set */ - const char *opaque) /* I - Opaque string */ +int // O - 0 on success, -1 on failure +mxmlSetOpaque(mxml_node_t *node, // I - Node to set + const char *opaque) // I - Opaque string { - char *s; /* New opaque string */ + char *s; // New opaque string - /* - * Range check input... - */ - - if (node && node->type == MXML_ELEMENT && - node->child && node->child->type == MXML_OPAQUE) + // Range check input... + if (node && node->type == MXML_TYPE_ELEMENT && node->child && node->child->type == MXML_TYPE_OPAQUE) node = node->child; - if (!node || node->type != MXML_OPAQUE) + if (!node || node->type != MXML_TYPE_OPAQUE) { mxml_error("Wrong node type."); return (-1); @@ -245,10 +203,7 @@ mxmlSetOpaque(mxml_node_t *node, /* I - Node to set */ if (node->value.opaque == opaque) 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) { 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. - * - * The node is not changed if it (or its first child) is not an opaque node. - * - * @since Mini-XML 2.11@ - */ +// +// '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. +// -int /* O - 0 on success, -1 on failure */ -mxmlSetOpaquef(mxml_node_t *node, /* I - Node to set */ - const char *format, /* I - Printf-style format string */ - ...) /* I - Additional arguments as needed */ +int // O - 0 on success, -1 on failure +mxmlSetOpaquef(mxml_node_t *node, // I - Node to set + const char *format, // I - Printf-style format string + ...) // I - Additional arguments as needed { - va_list ap; /* Pointer to arguments */ - char *s; /* Temporary string */ - + va_list ap; // Pointer to arguments + char buffer[16384]; // Format buffer + char *s; // Temporary string - /* - * Range check input... - */ - if (node && node->type == MXML_ELEMENT && - node->child && node->child->type == MXML_OPAQUE) + // Range check input... + if (node && node->type == MXML_TYPE_ELEMENT && node->child && node->child->type == MXML_TYPE_OPAQUE) node = node->child; - if (!node || node->type != MXML_OPAQUE) + if (!node || node->type != MXML_TYPE_OPAQUE) { mxml_error("Wrong node type."); return (-1); @@ -298,15 +248,12 @@ mxmlSetOpaquef(mxml_node_t *node, /* I - Node to set */ 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); - s = _mxml_vstrdupf(format, ap); + vsnprintf(buffer, sizeof(buffer), format, ap); va_end(ap); - if (!s) + if ((s = strdup(buffer)) == NULL) { mxml_error("Unable to allocate memory for opaque string."); return (-1); @@ -319,63 +266,55 @@ mxmlSetOpaquef(mxml_node_t *node, /* I - Node to set */ } -/* - * '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. - */ +// +// '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. +// -int /* O - 0 on success, -1 on failure */ -mxmlSetReal(mxml_node_t *node, /* I - Node to set */ - double real) /* I - Real number value */ +int // O - 0 on success, -1 on failure +mxmlSetReal(mxml_node_t *node, // I - Node to set + double real) // I - Real number value { /* * Range check input... */ - if (node && node->type == MXML_ELEMENT && - node->child && node->child->type == MXML_REAL) + if (node && node->type == MXML_TYPE_ELEMENT && node->child && node->child->type == MXML_TYPE_REAL) node = node->child; - if (!node || node->type != MXML_REAL) + if (!node || node->type != MXML_TYPE_REAL) { mxml_error("Wrong node type."); return (-1); } - /* - * Set the new value and return... - */ - + // Set the new value and return... node->value.real = real; return (0); } -/* - * 'mxmlSetText()' - Set the value of a text node. - * - * The node is not changed if it (or its first child) is not 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. +// -int /* O - 0 on success, -1 on failure */ -mxmlSetText(mxml_node_t *node, /* I - Node to set */ - int whitespace, /* I - 1 = leading whitespace, 0 = no whitespace */ - const char *string) /* I - String */ +int // O - 0 on success, -1 on failure +mxmlSetText(mxml_node_t *node, // I - Node to set + int whitespace, // I - 1 = leading whitespace, 0 = no whitespace + const char *string) // I - String { - char *s; /* New string */ - + char *s; // New string - /* - * Range check input... - */ - if (node && node->type == MXML_ELEMENT && - node->child && node->child->type == MXML_TEXT) + // Range check input... + if (node && node->type == MXML_TYPE_ELEMENT && node->child && node->child->type == MXML_TYPE_TEXT) node = node->child; - if (!node || node->type != MXML_TEXT) + if (!node || node->type != MXML_TYPE_TEXT) { mxml_error("Wrong node type."); return (-1); @@ -392,10 +331,7 @@ mxmlSetText(mxml_node_t *node, /* I - Node to set */ 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) { 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. - * - * The node is not changed if it (or its first child) is not a text node. - */ +// +// '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. +// -int /* O - 0 on success, -1 on failure */ -mxmlSetTextf(mxml_node_t *node, /* I - Node to set */ - int whitespace, /* I - 1 = leading whitespace, 0 = no whitespace */ - const char *format, /* I - Printf-style format string */ - ...) /* I - Additional arguments as needed */ +int // O - 0 on success, -1 on failure +mxmlSetTextf(mxml_node_t *node, // I - Node to set + int whitespace, // I - 1 = leading whitespace, 0 = no whitespace + const char *format, // I - Printf-style format string + ...) // I - Additional arguments as needed { - va_list ap; /* Pointer to arguments */ - char *s; /* Temporary string */ - + va_list ap; // Pointer to arguments + char buffer[16384]; // Format buffer + char *s; // Temporary string - /* - * Range check input... - */ - if (node && node->type == MXML_ELEMENT && - node->child && node->child->type == MXML_TEXT) + // Range check input... + if (node && node->type == MXML_TYPE_ELEMENT && node->child && node->child->type == MXML_TYPE_TEXT) node = node->child; - if (!node || node->type != MXML_TEXT) + if (!node || node->type != MXML_TYPE_TEXT) { mxml_error("Wrong node type."); return (-1); @@ -451,10 +384,10 @@ mxmlSetTextf(mxml_node_t *node, /* I - Node to set */ */ va_start(ap, format); - s = _mxml_vstrdupf(format, ap); + vsnprintf(buffer, sizeof(buffer), format, ap); va_end(ap); - if (!s) + if ((s = strdup(buffer)) == NULL) { mxml_error("Unable to allocate memory for text string."); return (-1); @@ -469,27 +402,19 @@ mxmlSetTextf(mxml_node_t *node, /* I - Node to set */ } -/* - * 'mxmlSetUserData()' - Set the user data pointer for a node. - * - * @since Mini-XML 2.7@ - */ +// +// 'mxmlSetUserData()' - Set the user data pointer for a node. +// -int /* O - 0 on success, -1 on failure */ -mxmlSetUserData(mxml_node_t *node, /* I - Node to set */ - void *data) /* I - User data pointer */ +int // O - 0 on success, -1 on failure +mxmlSetUserData(mxml_node_t *node, // I - Node to set + void *data) // I - User data pointer { - /* - * Range check input... - */ - + // Range check input... if (!node) return (-1); - /* - * Set the user data pointer and return... - */ - + // Set the user data pointer and return... node->user_data = data; return (0); } diff --git a/mxml-string.c b/mxml-string.c deleted file mode 100644 index 5c05ff1..0000000 --- a/mxml-string.c +++ /dev/null @@ -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 */ -} diff --git a/mxml.h b/mxml.h index 01f2638..72b1180 100644 --- a/mxml.h +++ b/mxml.h @@ -1,158 +1,140 @@ -/* - * Header file for Mini-XML, a small XML file parsing library. - * - * https://www.msweet.org/mxml - * - * Copyright © 2003-2021 by Michael R Sweet. - * - * Licensed under Apache License v2.0. See the file "LICENSE" for more - * information. - */ - -/* - * Prevent multiple inclusion... - */ - -#ifndef _mxml_h_ -# define _mxml_h_ - -/* - * Include necessary headers... - */ - +// +// Header file for Mini-XML, a small XML file parsing library. +// +// https://www.msweet.org/mxml +// +// Copyright © 2003-2024 by Michael R Sweet. +// +// Licensed under Apache License v2.0. See the file "LICENSE" for more +// information. +// + +#ifndef MXML_H +# define MXML_H # include # include # include # include # include +# ifdef __cplusplus +extern "C" { +# endif // __cplusplus -/* - * Constants... - */ +// +// Constants... +// -# define MXML_MAJOR_VERSION 3 /* Major version number */ -# define MXML_MINOR_VERSION 2 /* Minor version number */ +# define MXML_MAJOR_VERSION 4 // Major 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 - /* Treat all data as integers */ + // Treat all data as integers # define MXML_OPAQUE_CALLBACK mxml_opaque_cb - /* Treat all data as opaque */ + // Treat all data as opaque # define MXML_REAL_CALLBACK mxml_real_cb - /* Treat all data as real numbers */ -# define MXML_TEXT_CALLBACK 0 /* Treat all data as text */ + // Treat all data as real numbers +# define MXML_TEXT_CALLBACK 0 // Treat all data as text # 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_NO_DESCEND 0 /* Don't descend when finding/walking */ -# define MXML_DESCEND_FIRST -1 /* Descend for first find */ +# define MXML_DESCEND 1 // 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_WS_BEFORE_OPEN 0 /* Callback for before 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_AFTER_CLOSE 3 /* Callback for after close 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_BEFORE_CLOSE 2 // Callback for before 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_AFTER 1 /* Add node after specified node */ -# define MXML_ADD_TO_PARENT NULL /* Add node relative to parent */ +# define MXML_ADD_BEFORE 0 // Add node before specified node +# define MXML_ADD_AFTER 1 // Add node after specified node +# 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_COMMENT, /* Comment node */ - MXML_SAX_DATA, /* Data node */ - MXML_SAX_DIRECTIVE, /* Processing directive node */ - MXML_SAX_ELEMENT_CLOSE, /* Element closed */ - MXML_SAX_ELEMENT_OPEN /* Element opened */ + MXML_SAX_EVENT_CDATA, // CDATA node + MXML_SAX_EVENT_COMMENT, // Comment node + MXML_SAX_EVENT_DATA, // Data node + MXML_SAX_EVENT_DIRECTIVE, // Processing directive node + MXML_SAX_EVENT_ELEMENT_CLOSE, // Element closed + MXML_SAX_EVENT_ELEMENT_OPEN // Element opened } 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_ELEMENT, /* XML element with attributes */ - MXML_INTEGER, /* Integer value */ - MXML_OPAQUE, /* Opaque string */ - MXML_REAL, /* Real value */ - MXML_TEXT, /* Text fragment */ - MXML_CUSTOM /* Custom data @since Mini-XML 2.1@ */ + MXML_TYPE_IGNORE = -1, // Ignore/throw away node + MXML_TYPE_ELEMENT, // XML element with attributes + MXML_TYPE_INTEGER, // Integer value + MXML_TYPE_OPAQUE, // Opaque string + MXML_TYPE_REAL, // Real value + MXML_TYPE_TEXT, // Text fragment + MXML_TYPE_CUSTOM // Custom data } mxml_type_t; typedef void (*mxml_custom_destroy_cb_t)(void *); - /**** Custom data destructor ****/ + // Custom data destructor 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; - /**** An XML node index. ****/ + // An XML node index. 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 *); - /**** Custom data save callback function ****/ + // Custom data save callback function 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 *); - /**** Load callback function ****/ + // Load callback function 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 *); - /**** SAX callback function ****/ + // SAX callback function -/* - * C++ support... - */ +// +// Prototypes... +// -# ifdef __cplusplus -extern "C" { -# endif /* __cplusplus */ - -/* - * Prototypes... - */ - -extern void mxmlAdd(mxml_node_t *parent, int where, - mxml_node_t *child, mxml_node_t *node); +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 mxmlElementDeleteAttr(mxml_node_t *node, - const char *name); +extern void mxmlElementDeleteAttr(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 int mxmlElementGetAttrCount(mxml_node_t *node); -extern void mxmlElementSetAttr(mxml_node_t *node, const char *name, - const char *value); -extern void mxmlElementSetAttrf(mxml_node_t *node, const char *name, - const char *format, ...) -# ifdef __GNUC__ -__attribute__ ((__format__ (__printf__, 3, 4))) -# endif /* __GNUC__ */ -; +extern void mxmlElementSetAttr(mxml_node_t *node, const char *name, const char *value); +extern void mxmlElementSetAttrf(mxml_node_t *node, const char *name, const char *format, ...) MXML_FORMAT(3,4); extern int mxmlEntityAddCallback(mxml_entity_cb_t cb); extern const char *mxmlEntityGetName(int val); extern int mxmlEntityGetValue(const char *name); extern void mxmlEntityRemoveCallback(mxml_entity_cb_t cb); -extern mxml_node_t *mxmlFindElement(mxml_node_t *node, mxml_node_t *top, - const char *element, const char *attr, - const char *value, int descend); +extern mxml_node_t *mxmlFindElement(mxml_node_t *node, mxml_node_t *top, const char *element, const char *attr, const char *value, int descend); extern mxml_node_t *mxmlFindPath(mxml_node_t *node, const char *path); extern const char *mxmlGetCDATA(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 mxmlIndexDelete(mxml_index_t *ind); extern mxml_node_t *mxmlIndexEnum(mxml_index_t *ind); -extern mxml_node_t *mxmlIndexFind(mxml_index_t *ind, - const char *element, - const char *value); +extern mxml_node_t *mxmlIndexFind(mxml_index_t *ind, const char *element, const char *value); extern int mxmlIndexGetCount(mxml_index_t *ind); -extern mxml_index_t *mxmlIndexNew(mxml_node_t *node, const char *element, - const char *attr); +extern mxml_index_t *mxmlIndexNew(mxml_node_t *node, const char *element, const char *attr); extern mxml_node_t *mxmlIndexReset(mxml_index_t *ind); -extern mxml_node_t *mxmlLoadFd(mxml_node_t *top, int fd, - mxml_type_t (*cb)(mxml_node_t *)); -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 *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); +extern mxml_node_t *mxmlLoadString(mxml_node_t *top, const char *s, mxml_load_cb_t cb); extern mxml_node_t *mxmlNewCDATA(mxml_node_t *parent, const char *string); -extern mxml_node_t *mxmlNewCustom(mxml_node_t *parent, void *data, - mxml_custom_destroy_cb_t destroy); +extern mxml_node_t *mxmlNewCustom(mxml_node_t *parent, void *data, mxml_custom_destroy_cb_t destroy); 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 *mxmlNewOpaque(mxml_node_t *parent, const char *opaque); -extern mxml_node_t *mxmlNewOpaquef(mxml_node_t *parent, const char *format, ...) -# ifdef __GNUC__ -__attribute__ ((__format__ (__printf__, 2, 3))) -# endif /* __GNUC__ */ -; +extern mxml_node_t *mxmlNewOpaquef(mxml_node_t *parent, const char *format, ...) MXML_FORMAT(2,3); 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 *mxmlNewTextf(mxml_node_t *parent, int whitespace, const char *format, ...) -# ifdef __GNUC__ -__attribute__ ((__format__ (__printf__, 3, 4))) -# endif /* __GNUC__ */ -; +extern mxml_node_t *mxmlNewTextf(mxml_node_t *parent, int whitespace, const char *format, ...) MXML_FORMAT(3,4); extern mxml_node_t *mxmlNewXML(const char *version); extern int mxmlRelease(mxml_node_t *node); extern void mxmlRemove(mxml_node_t *node); extern int mxmlRetain(mxml_node_t *node); -extern char *mxmlSaveAllocString(mxml_node_t *node, - mxml_save_cb_t cb); -extern int mxmlSaveFd(mxml_node_t *node, int fd, - mxml_save_cb_t cb); -extern int mxmlSaveFile(mxml_node_t *node, FILE *fp, - mxml_save_cb_t cb); -extern int mxmlSaveString(mxml_node_t *node, char *buffer, - 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 char *mxmlSaveAllocString(mxml_node_t *node, mxml_save_cb_t cb); +extern int mxmlSaveFd(mxml_node_t *node, int fd, mxml_save_cb_t cb); +extern int mxmlSaveFile(mxml_node_t *node, FILE *fp, mxml_save_cb_t cb); +extern int mxmlSaveString(mxml_node_t *node, char *buffer, int bufsize, mxml_save_cb_t cb); +extern mxml_node_t *mxmlSAXLoadFd(mxml_node_t *top, int fd, mxml_load_cb_t cb, mxml_sax_cb_t sax, void *sax_data); +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 mxml_node_t *mxmlSAXLoadString(mxml_node_t *top, const char *s, mxml_load_cb_t cb, mxml_sax_cb_t sax, void *sax_data); extern int mxmlSetCDATA(mxml_node_t *node, const char *data); -extern int mxmlSetCustom(mxml_node_t *node, void *data, - mxml_custom_destroy_cb_t destroy); -extern void mxmlSetCustomHandlers(mxml_custom_load_cb_t load, - mxml_custom_save_cb_t save); +extern int mxmlSetCustom(mxml_node_t *node, void *data, mxml_custom_destroy_cb_t destroy); +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 void mxmlSetErrorCallback(mxml_error_cb_t cb); extern int mxmlSetInteger(mxml_node_t *node, int integer); extern int mxmlSetOpaque(mxml_node_t *node, const char *opaque); -extern int mxmlSetOpaquef(mxml_node_t *node, const char *format, ...) -# ifdef __GNUC__ -__attribute__ ((__format__ (__printf__, 2, 3))) -# endif /* __GNUC__ */ -; +extern int mxmlSetOpaquef(mxml_node_t *node, const char *format, ...) MXML_FORMAT(2,3); extern int mxmlSetReal(mxml_node_t *node, double real); -extern int mxmlSetText(mxml_node_t *node, int whitespace, - const char *string); -extern int mxmlSetTextf(mxml_node_t *node, int whitespace, - const char *format, ...) -# ifdef __GNUC__ -__attribute__ ((__format__ (__printf__, 3, 4))) -# endif /* __GNUC__ */ -; +extern int mxmlSetText(mxml_node_t *node, int whitespace, const char *string); +extern int mxmlSetTextf(mxml_node_t *node, int whitespace, const char *format, ...) MXML_FORMAT(3,4); extern int mxmlSetUserData(mxml_node_t *node, void *data); extern void mxmlSetWrapMargin(int column); -extern mxml_node_t *mxmlWalkNext(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); +extern mxml_node_t *mxmlWalkNext(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, ...) -# ifdef __GNUC__ -__attribute__ ((__format__ (__printf__, 1, 2))) -# endif /* __GNUC__ */ -; +extern void mxml_error(const char *format, ...) MXML_FORMAT(1,2); 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_opaque_cb(mxml_node_t *node); extern mxml_type_t mxml_real_cb(mxml_node_t *node); -/* - * C++ support... - */ - # ifdef __cplusplus } -# endif /* __cplusplus */ -#endif /* !_mxml_h_ */ +# endif // __cplusplus +#endif // !MXML_H diff --git a/mxml.pc.in b/mxml.pc.in index 81f3bf5..0d4ab10 100644 --- a/mxml.pc.in +++ b/mxml.pc.in @@ -5,6 +5,6 @@ includedir=@includedir@ Name: Mini-XML Description: Lightweight XML support library -Version: @VERSION@ -Libs: @PC_LIBS@ -Cflags: @PC_CFLAGS@ +Version: @MXML_VERSION@ +Libs: @PKGCONFIG_LIBS@ +Cflags: @PKGCONFIG_CFLAGS@ diff --git a/testmxml.c b/testmxml.c index 271c6f1..5c8b9bf 100644 --- a/testmxml.c +++ b/testmxml.c @@ -1,90 +1,79 @@ -/* - * Test program for Mini-XML, a small XML file parsing library. - * - * Usage: - * - * ./testmxml input.xml [string-output.xml] >stdio-output.xml - * ./testmxml "stdio-output.xml - * - * 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" +// +// Test program for Mini-XML, a small XML file parsing library. +// +// Usage: +// +// ./testmxml input.xml [string-output.xml] >stdio-output.xml +// ./testmxml "stdio-output.xml +// +// https://www.msweet.org/mxml +// +// Copyright © 2003-2024 by Michael R Sweet. +// +// Licensed under Apache License v2.0. See the file "LICENSE" for more +// information. +// + #include "mxml-private.h" #ifndef _WIN32 # include -#endif /* !_WIN32 */ +#endif // !_WIN32 #include #ifndef O_BINARY # define O_BINARY 0 -#endif /* !O_BINARY */ +#endif // !O_BINARY -/* - * Globals... - */ +// +// Globals... +// int event_counts[6]; -/* - * Local functions... - */ +// +// Local functions... +// void sax_cb(mxml_node_t *node, mxml_sax_event_t event, void *data); mxml_type_t type_cb(mxml_node_t *node); 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 */ -main(int argc, /* I - Number of command-line args */ - char *argv[]) /* I - Command-line args */ +int // O - Exit status +main(int argc, // I - Number of command-line args + char *argv[]) // I - Command-line args { - int i; /* Looping var */ - FILE *fp; /* File to read */ - int fd; /* File descriptor */ - mxml_node_t *xml, /* node */ - *tree, /* Element tree */ - *node; /* Node which should be in test.xml */ - mxml_index_t *ind; /* XML index */ - char buffer[16384]; /* Save string */ - static const char *types[] = /* Strings for node types */ + int i; // Looping var + FILE *fp; // File to read + int fd; // File descriptor + mxml_node_t *xml, // node + *tree, // Element tree + *node; // Node which should be in test.xml + mxml_index_t *ind; // XML index + char buffer[16384]; // Save string + static const char *types[] = // Strings for node types { - "MXML_ELEMENT", - "MXML_INTEGER", - "MXML_OPAQUE", - "MXML_REAL", - "MXML_TEXT" + "MXML_TYPE_ELEMENT", + "MXML_TYPE_INTEGER", + "MXML_TYPE_OPAQUE", + "MXML_TYPE_REAL", + "MXML_TYPE_TEXT" }; - /* - * Check arguments... - */ - + // Check arguments... if (argc != 2 && argc != 3) { fputs("Usage: testmxml filename.xml [string-output.xml]\n", stderr); return (1); } - /* - * Test the basic functionality... - */ - + // Test the basic functionality... xml = mxmlNewXML("1.0"); tree = mxmlNewElement(xml, "element"); @@ -94,19 +83,16 @@ main(int argc, /* I - Number of command-line args */ 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", - tree->type < MXML_ELEMENT || tree->type > MXML_TEXT ? - "UNKNOWN" : types[tree->type], tree->type); + 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); mxmlDelete(tree); return (1); } if (strcmp(tree->value.element.name, "element")) { - fprintf(stderr, "ERROR: Parent value is \"%s\", expected \"element\".\n", - tree->value.element.name); + fprintf(stderr, "ERROR: Parent value is \"%s\", expected \"element\".\n", tree->value.element.name); mxmlDelete(tree); return (1); } @@ -116,18 +102,12 @@ main(int argc, /* I - Number of command-line args */ mxmlNewReal(tree, 123.4f); mxmlNewText(tree, 1, "text"); - mxmlLoadString(tree, "string string string", - MXML_NO_CALLBACK); - mxmlLoadString(tree, "1 2 3", - MXML_INTEGER_CALLBACK); - mxmlLoadString(tree, "1.0 2.0 3.0", - MXML_REAL_CALLBACK); - mxmlLoadString(tree, "opaque opaque opaque", - MXML_OPAQUE_CALLBACK); - mxmlLoadString(tree, "valuevalue2" - "", MXML_OPAQUE_CALLBACK); - mxmlNewCDATA(tree, - "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n"); + mxmlLoadString(tree, "string string string", MXML_NO_CALLBACK); + mxmlLoadString(tree, "1 2 3", MXML_INTEGER_CALLBACK); + mxmlLoadString(tree, "1.0 2.0 3.0", MXML_REAL_CALLBACK); + mxmlLoadString(tree, "opaque opaque opaque", MXML_OPAQUE_CALLBACK); + mxmlLoadString(tree, "valuevalue2", MXML_OPAQUE_CALLBACK); + mxmlNewCDATA(tree, "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n"); mxmlNewCDATA(tree, "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n" "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n" @@ -152,19 +132,16 @@ main(int argc, /* I - Number of command-line args */ 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", - node->type < MXML_ELEMENT || node->type > MXML_TEXT ? - "UNKNOWN" : types[node->type], node->type); + 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); mxmlDelete(tree); return (1); } if (node->value.integer != 123) { - fprintf(stderr, "ERROR: First child value is %d, expected 123.\n", - node->value.integer); + fprintf(stderr, "ERROR: First child value is %d, expected 123.\n", node->value.integer); mxmlDelete(tree); return (1); } @@ -178,19 +155,16 @@ main(int argc, /* I - Number of command-line args */ 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", - node->type < MXML_ELEMENT || node->type > MXML_TEXT ? - "UNKNOWN" : types[node->type], node->type); + 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); mxmlDelete(tree); return (1); } if (!node->value.opaque || strcmp(node->value.opaque, "opaque")) { - fprintf(stderr, "ERROR: Second child value is \"%s\", expected \"opaque\".\n", - node->value.opaque ? node->value.opaque : "(null)"); + fprintf(stderr, "ERROR: Second child value is \"%s\", expected \"opaque\".\n", node->value.opaque ? node->value.opaque : "(null)"); mxmlDelete(tree); return (1); } @@ -204,19 +178,16 @@ main(int argc, /* I - Number of command-line args */ 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", - node->type < MXML_ELEMENT || node->type > MXML_TEXT ? - "UNKNOWN" : types[node->type], node->type); + 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); mxmlDelete(tree); return (1); } if (node->value.real != 123.4f) { - fprintf(stderr, "ERROR: Third child value is %f, expected 123.4.\n", - node->value.real); + fprintf(stderr, "ERROR: Third child value is %f, expected 123.4.\n", node->value.real); mxmlDelete(tree); return (1); } @@ -230,21 +201,16 @@ main(int argc, /* I - Number of command-line args */ 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", - node->type < MXML_ELEMENT || node->type > MXML_TEXT ? - "UNKNOWN" : types[node->type], node->type); + 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); mxmlDelete(tree); return (1); } - if (!node->value.text.whitespace || - !node->value.text.string || strcmp(node->value.text.string, "text")) + if (!node->value.text.whitespace || !node->value.text.string || strcmp(node->value.text.string, "text")) { - 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)"); + 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)"); mxmlDelete(tree); return (1); } @@ -260,20 +226,15 @@ main(int argc, /* I - Number of command-line args */ 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", - i + 1, node->type < MXML_ELEMENT || node->type > MXML_TEXT ? - "UNKNOWN" : types[node->type], node->type); + 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); mxmlDelete(tree); return (1); } } - /* - * Test mxmlFindPath... - */ - + // Test mxmlFindPath... node = mxmlFindPath(tree, "*/two"); if (!node) { @@ -281,7 +242,7 @@ main(int argc, /* I - Number of command-line args */ mxmlDelete(tree); 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); mxmlDelete(tree); @@ -295,7 +256,7 @@ main(int argc, /* I - Number of command-line args */ mxmlDelete(tree); 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); mxmlDelete(tree); @@ -309,17 +270,14 @@ main(int argc, /* I - Number of command-line args */ mxmlDelete(tree); 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); mxmlDelete(tree); return (1); } - /* - * Test indices... - */ - + // Test indices... ind = mxmlIndexNew(tree, NULL, NULL); if (!ind) { @@ -330,8 +288,7 @@ main(int argc, /* I - Number of command-line args */ if (ind->num_nodes != 13) { - fprintf(stderr, "ERROR: Index of all nodes contains %d " - "nodes; expected 13.\n", ind->num_nodes); + fprintf(stderr, "ERROR: Index of all nodes contains %d nodes; expected 13.\n", ind->num_nodes); mxmlIndexDelete(ind); mxmlDelete(tree); return (1); @@ -358,8 +315,7 @@ main(int argc, /* I - Number of command-line args */ if (ind->num_nodes != 4) { - fprintf(stderr, "ERROR: Index of groups contains %d " - "nodes; expected 4.\n", ind->num_nodes); + fprintf(stderr, "ERROR: Index of groups contains %d nodes; expected 4.\n", ind->num_nodes); mxmlIndexDelete(ind); mxmlDelete(tree); return (1); @@ -386,8 +342,7 @@ main(int argc, /* I - Number of command-line args */ if (ind->num_nodes != 3) { - fprintf(stderr, "ERROR: Index of type attributes contains %d " - "nodes; expected 3.\n", ind->num_nodes); + fprintf(stderr, "ERROR: Index of type attributes contains %d nodes; expected 3.\n", ind->num_nodes); mxmlIndexDelete(ind); mxmlDelete(tree); return (1); @@ -414,8 +369,7 @@ main(int argc, /* I - Number of command-line args */ if (ind->num_nodes != 3) { - fprintf(stderr, "ERROR: Index of elements and attributes contains %d " - "nodes; expected 3.\n", ind->num_nodes); + fprintf(stderr, "ERROR: Index of elements and attributes contains %d nodes; expected 3.\n", ind->num_nodes); mxmlIndexDelete(ind); mxmlDelete(tree); return (1); @@ -432,18 +386,16 @@ main(int argc, /* I - Number of command-line args */ mxmlIndexDelete(ind); - /* - * Check the mxmlDelete() works properly... - */ - + // Check the mxmlDelete() works properly... for (i = 0; i < 12; i ++) { if (tree->child) + { mxmlDelete(tree->child); + } else { - fprintf(stderr, "ERROR: Child pointer prematurely NULL on child #%d\n", - i + 1); + fprintf(stderr, "ERROR: Child pointer prematurely NULL on child #%d\n", i + 1); mxmlDelete(tree); return (1); } @@ -463,12 +415,11 @@ main(int argc, /* I - Number of command-line args */ 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] == '<') + { xml = mxmlLoadString(NULL, argv[1], MXML_NO_CALLBACK); + } else if ((fp = fopen(argv[1], "rb")) == NULL) { perror(argv[1]); @@ -476,10 +427,7 @@ main(int argc, /* I - Number of command-line args */ } else { - /* - * Read the file... - */ - + // Read the file... xml = mxmlLoadFile(NULL, fp, MXML_NO_CALLBACK); fclose(fp); @@ -493,13 +441,9 @@ main(int argc, /* I - Number of command-line args */ if (!strcmp(argv[1], "test.xml")) { - const char *text; /* Text value */ - - /* - * Verify that mxmlFindElement() and indirectly mxmlWalkNext() work - * properly... - */ + const char *text; // Text value + // Verify that mxmlFindElement() and indirectly mxmlWalkNext() work properly... if ((node = mxmlFindPath(xml, "group/option/keyword")) == NULL) { 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); } - if (node->type != MXML_TEXT) + if (node->type != MXML_TYPE_TEXT) { fputs("No child node of group/option/keyword.\n", stderr); mxmlSaveFile(xml, stderr, MXML_NO_CALLBACK); @@ -525,12 +469,11 @@ main(int argc, /* I - Number of command-line args */ mxmlDelete(xml); - /* - * Open the file... - */ - + // Open the file... if (argv[1][0] == '<') + { xml = mxmlLoadString(NULL, argv[1], type_cb); + } else if ((fp = fopen(argv[1], "rb")) == NULL) { perror(argv[1]); @@ -538,10 +481,7 @@ main(int argc, /* I - Number of command-line args */ } else { - /* - * Read the file... - */ - + // Read the file... xml = mxmlLoadFile(NULL, fp, type_cb); fclose(fp); @@ -555,13 +495,8 @@ main(int argc, /* I - Number of command-line args */ if (!strcmp(argv[1], "test.xml")) { - /* - * Verify that mxmlFindElement() and indirectly mxmlWalkNext() work - * properly... - */ - - if ((node = mxmlFindElement(xml, xml, "choice", NULL, NULL, - MXML_DESCEND)) == NULL) + // Verify that mxmlFindElement() and indirectly mxmlWalkNext() work properly... + if ((node = mxmlFindElement(xml, xml, "choice", NULL, NULL, MXML_DESCEND)) == NULL) { fputs("Unable to find first element in XML tree.\n", stderr); 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); - /* - * 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 (argc == 3) @@ -596,40 +525,25 @@ main(int argc, /* I - Number of command-line args */ } } - /* - * Delete the tree... - */ - + // Delete the tree... mxmlDelete(xml); - /* - * Read from/write to file descriptors... - */ - + // Read from/write to file descriptors... if (argv[1][0] != '<') { - /* - * Open the file again... - */ - + // Open the file again... if ((fd = open(argv[1], O_RDONLY | O_BINARY)) < 0) { perror(argv[1]); return (1); } - /* - * Read the file... - */ - + // Read the file... xml = mxmlLoadFd(NULL, fd, type_cb); close(fd); - /* - * Create filename.xmlfd... - */ - + // Create filename.xmlfd... snprintf(buffer, sizeof(buffer), "%sfd", argv[1]); 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); } - /* - * Write the file... - */ - + // Write the file... mxmlSaveFd(xml, fd, whitespace_cb); close(fd); - /* - * Delete the tree... - */ - + // Delete the tree... mxmlDelete(xml); } - /* - * Test SAX methods... - */ - + // Test SAX methods... memset(event_counts, 0, sizeof(event_counts)); if (argv[1][0] == '<') + { mxmlRelease(mxmlSAXLoadString(NULL, argv[1], type_cb, sax_cb, NULL)); + } else if ((fp = fopen(argv[1], "rb")) == NULL) { perror(argv[1]); @@ -669,10 +576,7 @@ main(int argc, /* I - Number of command-line args */ } else { - /* - * Read the file... - */ - + // Read the file... mxmlRelease(mxmlSAXLoadFile(NULL, fp, type_cb, sax_cb, NULL)); fclose(fp); @@ -680,56 +584,48 @@ main(int argc, /* I - Number of command-line args */ 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", - event_counts[MXML_SAX_CDATA]); + fprintf(stderr, "MXML_SAX_EVENT_CDATA seen %d times, expected 1 times.\n", event_counts[MXML_SAX_EVENT_CDATA]); 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", - event_counts[MXML_SAX_COMMENT]); + fprintf(stderr, "MXML_SAX_EVENT_COMMENT seen %d times, expected 1 times.\n", event_counts[MXML_SAX_EVENT_COMMENT]); 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", - event_counts[MXML_SAX_DATA]); + fprintf(stderr, "MXML_SAX_EVENT_DATA seen %d times, expected 61 times.\n", event_counts[MXML_SAX_EVENT_DATA]); 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", - event_counts[MXML_SAX_DIRECTIVE]); + fprintf(stderr, "MXML_SAX_EVENT_DIRECTIVE seen %d times, expected 1 times.\n", event_counts[MXML_SAX_EVENT_DIRECTIVE]); 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", - event_counts[MXML_SAX_ELEMENT_CLOSE]); + fprintf(stderr, "MXML_SAX_EVENT_ELEMENT_CLOSE seen %d times, expected 20 times.\n", event_counts[MXML_SAX_EVENT_ELEMENT_CLOSE]); 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", - event_counts[MXML_SAX_ELEMENT_OPEN]); + fprintf(stderr, "MXML_SAX_EVENT_ELEMENT_OPEN seen %d times, expected 20 times.\n", event_counts[MXML_SAX_EVENT_ELEMENT_OPEN]); return (1); } } #ifndef _WIN32 - /* - * Debug hooks... - */ - + // Debug hooks... if (getenv("TEST_DELAY") != NULL) sleep(atoi(getenv("TEST_DELAY"))); + # ifdef __APPLE__ if (getenv("TEST_LEAKS") != NULL) { @@ -739,43 +635,37 @@ main(int argc, /* I - Number of command-line args */ if (system(command)) puts("Unable to check for leaks."); } -# endif /* __APPLE__ */ -#endif /* !_WIN32 */ - - /* - * Return... - */ +# endif // __APPLE__ +#endif // !_WIN32 + // Return... return (0); } -/* - * 'sax_cb()' - Process nodes via SAX. - */ +// +// 'sax_cb()' - Process nodes via SAX. +// void -sax_cb(mxml_node_t *node, /* I - Current node */ - mxml_sax_event_t event, /* I - SAX event */ - void *data) /* I - SAX user data */ +sax_cb(mxml_node_t *node, // I - Current node + mxml_sax_event_t event, // I - SAX event + void *data) // I - SAX user data { - static const char * const events[] = /* Events */ - { - "MXML_SAX_CDATA", /* CDATA node */ - "MXML_SAX_COMMENT", /* Comment node */ - "MXML_SAX_DATA", /* Data node */ - "MXML_SAX_DIRECTIVE", /* Processing directive node */ - "MXML_SAX_ELEMENT_CLOSE", /* Element closed */ - "MXML_SAX_ELEMENT_OPEN" /* Element opened */ + static const char * const events[] = // Events + { + "MXML_SAX_EVENT_CDATA", // CDATA node + "MXML_SAX_EVENT_COMMENT", // Comment node + "MXML_SAX_EVENT_DATA", // Data node + "MXML_SAX_EVENT_DIRECTIVE", // Processing directive node + "MXML_SAX_EVENT_ELEMENT_CLOSE", // Element closed + "MXML_SAX_EVENT_ELEMENT_OPEN" // Element opened }; (void)data; - /* - * This SAX callback just counts the different events. - */ - + // This SAX callback just counts the different events. if (!node) 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 */ -type_cb(mxml_node_t *node) /* I - Element node */ +mxml_type_t // O - Data type +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) type = node->value.element.name; if (!strcmp(type, "integer")) - return (MXML_INTEGER); + return (MXML_TYPE_INTEGER); else if (!strcmp(type, "opaque") || !strcmp(type, "pre")) - return (MXML_OPAQUE); + return (MXML_TYPE_OPAQUE); else if (!strcmp(type, "real")) - return (MXML_REAL); + return (MXML_TYPE_REAL); else - return (MXML_TEXT); + return (MXML_TYPE_TEXT); } -/* - * 'whitespace_cb()' - Let the mxmlSaveFile() function know when to insert - * newlines and tabs... - */ +// +// 'whitespace_cb()' - Let the mxmlSaveFile() function know when to insert +// newlines and tabs... +// -const char * /* O - Whitespace string or NULL */ -whitespace_cb(mxml_node_t *node, /* I - Element node */ - int where) /* I - Open or close tag? */ +const char * // O - Whitespace string or NULL +whitespace_cb(mxml_node_t *node, // I - Element node + int where) // I - Open or close tag? { - mxml_node_t *parent; /* Parent node */ - int level; /* Indentation level */ - const char *name; /* Name of element */ + mxml_node_t *parent; // Parent node + int level; // Indentation level + const char *name; // Name of element 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. - * These are just common HTML elements... - */ - + // We can conditionally break to a new line before or after any element. + // These are just common HTML elements... name = node->value.element.name; - 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")) + 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")) { - /* - * Newlines before open and after close... - */ - + // Newlines before open and after close... if (where == MXML_WS_BEFORE_OPEN || where == MXML_WS_AFTER_CLOSE) return ("\n"); } 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"); } else if (!strcmp(name, "dd") || !strcmp(name, "dt") || !strcmp(name, "li")) { - /* - * Put a tab before
  • 's,
    's, and
    's, and a newline after them... - */ - + // Put a tab before
  • 's,
    's, and
    's, and a newline after them... if (where == MXML_WS_BEFORE_OPEN) return ("\t"); else if (where == MXML_WS_AFTER_CLOSE) @@ -872,13 +744,9 @@ whitespace_cb(mxml_node_t *node, /* I - Element node */ else return (NULL); } - else if (where == MXML_WS_BEFORE_OPEN || - ((!strcmp(name, "choice") || !strcmp(name, "option")) && - where == MXML_WS_BEFORE_CLOSE)) + else if (where == MXML_WS_BEFORE_OPEN || ((!strcmp(name, "choice") || !strcmp(name, "option")) && where == MXML_WS_BEFORE_CLOSE)) { - for (level = -1, parent = node->parent; - parent; - level ++, parent = parent->parent); + for (level = -1, parent = node->parent; parent; level ++, parent = parent->parent); if (level > 8) level = 8; @@ -887,17 +755,11 @@ whitespace_cb(mxml_node_t *node, /* I - Element node */ return (tabs + 8 - level); } - else if (where == MXML_WS_AFTER_CLOSE || - ((!strcmp(name, "group") || !strcmp(name, "option") || - !strcmp(name, "choice")) && - where == MXML_WS_AFTER_OPEN)) + else if (where == MXML_WS_AFTER_CLOSE || ((!strcmp(name, "group") || !strcmp(name, "option") || !strcmp(name, "choice")) && where == MXML_WS_AFTER_OPEN)) return ("\n"); else if (where == MXML_WS_AFTER_OPEN && !node->child) return ("\n"); - /* - * Return NULL for no added whitespace... - */ - + // Return NULL for no added whitespace... return (NULL); }