MFH
Sponsored by: The FreeBSD Foundation
This commit is contained in:
commit
0edd2576c0
6
Makefile
6
Makefile
@ -125,7 +125,7 @@ TGTS= all all-man buildenv buildenvvars buildkernel buildworld \
|
||||
obj objlink rerelease showconfig tags toolchain update \
|
||||
_worldtmp _legacy _bootstrap-tools _cleanobj _obj \
|
||||
_build-tools _cross-tools _includes _libraries \
|
||||
build32 distribute32 install32 build32 distribute32 install32 \
|
||||
build32 distribute32 install32 buildsoft distributesoft installsoft \
|
||||
builddtb xdev xdev-build xdev-install \
|
||||
xdev-links native-xtools stageworld stagekernel stage-packages \
|
||||
create-world-packages create-kernel-packages create-packages \
|
||||
@ -408,7 +408,7 @@ MAKEFAIL=cat
|
||||
|
||||
universe_prologue: upgrade_checks
|
||||
universe: universe_prologue
|
||||
universe_prologue:
|
||||
universe_prologue: .PHONY
|
||||
@echo "--------------------------------------------------------------"
|
||||
@echo ">>> make universe started on ${STARTTIME}"
|
||||
@echo "--------------------------------------------------------------"
|
||||
@ -494,7 +494,7 @@ universe_kernconf_${TARGET}_${kernel}: .MAKE
|
||||
"check _.${TARGET}.${kernel} for details"| ${MAKEFAIL}))
|
||||
.endfor
|
||||
universe: universe_epilogue
|
||||
universe_epilogue:
|
||||
universe_epilogue: .PHONY
|
||||
@echo "--------------------------------------------------------------"
|
||||
@echo ">>> make universe completed on `LC_ALL=C date`"
|
||||
@echo " (started ${STARTTIME})"
|
||||
|
@ -144,6 +144,15 @@ CLEANDIR= clean cleandepend
|
||||
CLEANDIR= cleandir
|
||||
.endif
|
||||
|
||||
.if ${MK_META_MODE} == "yes"
|
||||
# If filemon is used then we can rely on the build being incremental-safe.
|
||||
# The .meta files will also track the build command and rebuild should
|
||||
# it change.
|
||||
.if empty(.MAKE.MODE:Mnofilemon)
|
||||
NO_CLEAN= t
|
||||
.endif
|
||||
.endif
|
||||
|
||||
LOCAL_TOOL_DIRS?=
|
||||
PACKAGEDIR?= ${DESTDIR}/${DISTDIR}
|
||||
|
||||
@ -316,6 +325,10 @@ CROSSENV+= MAKEOBJDIRPREFIX=${OBJTREE} \
|
||||
MACHINE_ARCH=${TARGET_ARCH} \
|
||||
MACHINE=${TARGET} \
|
||||
CPUTYPE=${TARGET_CPUTYPE}
|
||||
.if ${MK_META_MODE} != "no"
|
||||
# Don't rebuild build-tools targets during normal build.
|
||||
CROSSENV+= BUILD_TOOLS_META=.NOMETA_CMP
|
||||
.endif
|
||||
.if ${MK_GROFF} != "no"
|
||||
CROSSENV+= GROFF_BIN_PATH=${WORLDTMP}/legacy/usr/bin \
|
||||
GROFF_FONT_PATH=${WORLDTMP}/legacy/usr/share/groff_font \
|
||||
@ -327,6 +340,7 @@ CROSSENV+= ${TARGET_CFLAGS}
|
||||
|
||||
# bootstrap-tools stage
|
||||
BMAKEENV= INSTALL="sh ${.CURDIR}/tools/install.sh" \
|
||||
TOOLS_PREFIX=${WORLDTMP} \
|
||||
PATH=${BPATH}:${PATH} \
|
||||
WORLDTMP=${WORLDTMP} \
|
||||
MAKEFLAGS="-m ${.CURDIR}/tools/build/mk ${.MAKEFLAGS}"
|
||||
@ -672,12 +686,12 @@ WMAKE_TGTS+= build${libcompat}
|
||||
buildworld: buildworld_prologue ${WMAKE_TGTS} buildworld_epilogue
|
||||
.ORDER: buildworld_prologue ${WMAKE_TGTS} buildworld_epilogue
|
||||
|
||||
buildworld_prologue:
|
||||
buildworld_prologue: .PHONY
|
||||
@echo "--------------------------------------------------------------"
|
||||
@echo ">>> World build started on `LC_ALL=C date`"
|
||||
@echo "--------------------------------------------------------------"
|
||||
|
||||
buildworld_epilogue:
|
||||
buildworld_epilogue: .PHONY
|
||||
@echo
|
||||
@echo "--------------------------------------------------------------"
|
||||
@echo ">>> World build completed on `LC_ALL=C date`"
|
||||
@ -1897,7 +1911,7 @@ _prebuild_libs= ${_kerberos5_lib_libasn1} \
|
||||
lib/libkiconv lib/libkvm lib/liblzma lib/libmd lib/libnv \
|
||||
${_lib_casper} \
|
||||
lib/ncurses/ncurses lib/ncurses/ncursesw \
|
||||
lib/libopie lib/libpam ${_lib_libthr} \
|
||||
lib/libopie lib/libpam/libpam ${_lib_libthr} \
|
||||
${_lib_libradius} lib/libsbuf lib/libtacplus \
|
||||
lib/libgeom \
|
||||
${_cddl_lib_libumem} ${_cddl_lib_libnvpair} \
|
||||
@ -1909,6 +1923,7 @@ _prebuild_libs= ${_kerberos5_lib_libasn1} \
|
||||
${_secure_lib_libcrypto} ${_lib_libldns} \
|
||||
${_secure_lib_libssh} ${_secure_lib_libssl} \
|
||||
gnu/lib/libdialog
|
||||
|
||||
.if ${MK_GNUCXX} != "no"
|
||||
_prebuild_libs+= gnu/lib/libstdc++ gnu/lib/libsupc++
|
||||
gnu/lib/libstdc++__L: lib/msun__L
|
||||
@ -2076,7 +2091,7 @@ ${_lib}__PL: .PHONY .MAKE
|
||||
.endif
|
||||
.endfor
|
||||
|
||||
.for _lib in ${_startup_libs} ${_prebuild_libs:Nlib/libpam} ${_generic_libs}
|
||||
.for _lib in ${_startup_libs} ${_prebuild_libs} ${_generic_libs}
|
||||
${_lib}__L: .PHONY .MAKE
|
||||
.if exists(${.CURDIR}/${_lib})
|
||||
${_+_}@${ECHODIR} "===> ${_lib} (obj,all,install)"; \
|
||||
@ -2087,18 +2102,6 @@ ${_lib}__L: .PHONY .MAKE
|
||||
.endif
|
||||
.endfor
|
||||
|
||||
# libpam is special: we need to build static PAM modules before
|
||||
# static PAM library, and dynamic PAM library before dynamic PAM
|
||||
# modules.
|
||||
lib/libpam__L: .PHONY .MAKE
|
||||
${_+_}@${ECHODIR} "===> lib/libpam (obj,all,install)"; \
|
||||
cd ${.CURDIR}/lib/libpam; \
|
||||
${MAKE} MK_TESTS=no DIRPRFX=lib/libpam/ obj; \
|
||||
${MAKE} MK_TESTS=no DIRPRFX=lib/libpam/ \
|
||||
-D_NO_LIBPAM_SO_YET all; \
|
||||
${MAKE} MK_TESTS=no DIRPRFX=lib/libpam/ \
|
||||
-D_NO_LIBPAM_SO_YET install
|
||||
|
||||
_prereq_libs: ${_prereq_libs:S/$/__PL/}
|
||||
_startup_libs: ${_startup_libs:S/$/__L/}
|
||||
_prebuild_libs: ${_prebuild_libs:S/$/__L/}
|
||||
|
@ -88,8 +88,13 @@ LIBCOMPATWMAKEENV+= MAKEOBJDIRPREFIX=${LIBCOMPAT_OBJTREE} \
|
||||
LIBDIR=/usr/lib${libcompat} \
|
||||
SHLIBDIR=/usr/lib${libcompat} \
|
||||
DTRACE="${LIB$COMPATDTRACE:U${DTRACE}}"
|
||||
.if ${MK_META_MODE} != "no"
|
||||
# Don't rebuild build-tools targets during normal build.
|
||||
LIBCOMPATWMAKEENV+= BUILD_TOOLS_META=.NOMETA_CMP
|
||||
.endif
|
||||
LIBCOMPATWMAKEFLAGS+= CC="${XCC} ${LIBCOMPATCFLAGS}" \
|
||||
CXX="${XCXX} ${LIBCOMPATCFLAGS} ${LIBCOMPATCXXFLAGS}" \
|
||||
CPP="${XCPP} ${LIBCOMPATCFLAGS}" \
|
||||
DESTDIR=${LIBCOMPATTMP} \
|
||||
-DNO_CPU_CFLAGS \
|
||||
MK_CTF=no \
|
||||
|
@ -1732,7 +1732,6 @@ OLD_FILES+=usr/share/man/man4/lindev.4.gz
|
||||
# 20140425
|
||||
OLD_FILES+=usr/lib/libssp_p.a
|
||||
OLD_FILES+=usr/lib/libstand_p.a
|
||||
OLD_FILES+=usr/lib32/libc_pic.a
|
||||
OLD_FILES+=usr/lib32/libssp_p.a
|
||||
OLD_FILES+=usr/lib32/libstand_p.a
|
||||
# 20140314: AppleTalk
|
||||
|
27
UPDATING
27
UPDATING
@ -31,6 +31,33 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW:
|
||||
disable the most expensive debugging functionality run
|
||||
"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
|
||||
|
||||
20160414:
|
||||
The CAM I/O scheduler has been committed to the kernel. There should be
|
||||
no user visible impact. This does enable NCQ Trim on ada SSDs. While the
|
||||
list of known rogues that claim support for this but actually corrupt
|
||||
data is believed to be complete, be on the lookout for data
|
||||
corruption. The known rogue list is believed to be complete:
|
||||
|
||||
o Crucial MX100, M550 drives with MU01 firmware.
|
||||
o Micron M510 and M550 drives with MU01 firmware.
|
||||
o Micron M500 prior to MU07 firmware
|
||||
o Samsung 830, 840, and 850 all firmwares
|
||||
o FCCT M500 all firmwares
|
||||
|
||||
Crucial has firmware http://www.crucial.com/usa/en/support-ssd-firmware
|
||||
with working NCQ TRIM. For Micron branded drives, see your sales rep for
|
||||
updated firmware. Black listed drives will work correctly because these
|
||||
drives work correctly so long as no NCQ TRIMs are sent to them. Given
|
||||
this list is the same as found in Linux, it's believed there are no
|
||||
other rogues in the market place. All other models from the above
|
||||
vendors work.
|
||||
|
||||
To be safe, if you are at all concerned, you can quirk each of your
|
||||
drives to prevent NCQ from being sent by setting:
|
||||
kern.cam.ada.X.quirks="0x2"
|
||||
in loader.conf. If the drive requires the 4k sector quirk, set the
|
||||
quirks entry to 0x3.
|
||||
|
||||
20160330:
|
||||
The FAST_DEPEND build option has been removed and its functionality is
|
||||
now the one true way. The old mkdep(1) style of 'make depend' has
|
||||
|
@ -110,7 +110,7 @@ csh.1: tcsh.man
|
||||
|
||||
build-tools: gethost
|
||||
|
||||
gethost: gethost.c sh.err.h tc.const.h sh.h
|
||||
gethost: gethost.c sh.err.h tc.const.h sh.h ${BUILD_TOOLS_META}
|
||||
@rm -f ${.TARGET}
|
||||
${CC} -o gethost ${LDFLAGS} ${CFLAGS:C/-DHAVE_ICONV//} \
|
||||
${TCSHDIR}/gethost.c
|
||||
|
@ -45,10 +45,10 @@ builtins.c builtins.h: mkbuiltins builtins.def
|
||||
# XXX this is just to stop the default .c rule being used, so that the
|
||||
# intermediate object has a fixed name.
|
||||
# XXX we have a default .c rule, but no default .o rule.
|
||||
.o:
|
||||
mknodes.o mksyntax.o: ${BUILD_TOOLS_META}
|
||||
${CC} ${CFLAGS} ${LDFLAGS} ${.IMPSRC} ${LDLIBS} -o ${.TARGET}
|
||||
mknodes: mknodes.o
|
||||
mksyntax: mksyntax.o
|
||||
mknodes: mknodes.o ${BUILD_TOOLS_META}
|
||||
mksyntax: mksyntax.o ${BUILD_TOOLS_META}
|
||||
|
||||
.ORDER: nodes.c nodes.h
|
||||
nodes.c nodes.h: mknodes nodetypes nodes.c.pat
|
||||
|
@ -1616,7 +1616,6 @@ parsesub: {
|
||||
int flags;
|
||||
char *p;
|
||||
static const char types[] = "}-+?=";
|
||||
int bracketed_name = 0; /* used to handle ${[0-9]*} variables */
|
||||
int linno;
|
||||
int length;
|
||||
int c1;
|
||||
@ -1640,7 +1639,6 @@ parsesub: {
|
||||
subtype = VSNORMAL;
|
||||
flags = 0;
|
||||
if (c == '{') {
|
||||
bracketed_name = 1;
|
||||
c = pgetc_linecont();
|
||||
subtype = 0;
|
||||
}
|
||||
@ -1665,7 +1663,7 @@ parsesub: {
|
||||
flags |= VSLINENO;
|
||||
}
|
||||
} else if (is_digit(c)) {
|
||||
if (bracketed_name) {
|
||||
if (subtype != VSNORMAL) {
|
||||
do {
|
||||
STPUTC(c, out);
|
||||
c = pgetc_linecont();
|
||||
|
@ -108,16 +108,16 @@ typedef struct tcpsinfo {
|
||||
uint32_t tcps_snxt; /* next sequence # to send */
|
||||
uint32_t tcps_rack; /* sequence # we have acked */
|
||||
uint32_t tcps_rnxt; /* next sequence # expected */
|
||||
uint32_t tcps_swnd; /* send window size */
|
||||
u_long tcps_swnd; /* send window size */
|
||||
int32_t tcps_snd_ws; /* send window scaling */
|
||||
uint32_t tcps_swl1; /* window update seg seq number */
|
||||
uint32_t tcps_swl2; /* window update seg ack number */
|
||||
uint32_t tcps_rup; /* receive urgent pointer */
|
||||
uint32_t tcps_radv; /* advertised window */
|
||||
uint32_t tcps_rwnd; /* receive window size */
|
||||
u_long tcps_rwnd; /* receive window size */
|
||||
int32_t tcps_rcv_ws; /* receive window scaling */
|
||||
uint32_t tcps_cwnd; /* congestion window */
|
||||
uint32_t tcps_cwnd_ssthresh; /* threshold for congestion avoidance */
|
||||
u_long tcps_cwnd; /* congestion window */
|
||||
u_long tcps_cwnd_ssthresh; /* threshold for congestion avoidance */
|
||||
uint32_t tcps_srecover; /* for use in NewReno Fast Recovery */
|
||||
uint32_t tcps_sack_fack; /* SACK sequence # we have acked */
|
||||
uint32_t tcps_sack_snxt; /* next SACK seq # for retransmission */
|
||||
|
@ -343,7 +343,7 @@ create_scn(struct elfcopy *ecp)
|
||||
GElf_Shdr ish;
|
||||
size_t indx;
|
||||
uint64_t oldndx, newndx;
|
||||
int elferr, sec_flags;
|
||||
int elferr, sec_flags, reorder;
|
||||
|
||||
/*
|
||||
* Insert a pseudo section that contains the ELF header
|
||||
@ -367,6 +367,7 @@ create_scn(struct elfcopy *ecp)
|
||||
errx(EXIT_FAILURE, "elf_getshstrndx failed: %s",
|
||||
elf_errmsg(-1));
|
||||
|
||||
reorder = 0;
|
||||
is = NULL;
|
||||
while ((is = elf_nextscn(ecp->ein, is)) != NULL) {
|
||||
if (gelf_getshdr(is, &ish) == NULL)
|
||||
@ -482,8 +483,20 @@ create_scn(struct elfcopy *ecp)
|
||||
/* create section header based on input object. */
|
||||
if (strcmp(name, ".symtab") != 0 &&
|
||||
strcmp(name, ".strtab") != 0 &&
|
||||
strcmp(name, ".shstrtab") != 0)
|
||||
strcmp(name, ".shstrtab") != 0) {
|
||||
copy_shdr(ecp, s, NULL, 0, sec_flags);
|
||||
/*
|
||||
* elfcopy puts .symtab, .strtab and .shstrtab
|
||||
* sections in the end of the output object.
|
||||
* If the input objects have more sections
|
||||
* after any of these 3 sections, the section
|
||||
* table will be reordered. section symbols
|
||||
* should be regenerated for relocations.
|
||||
*/
|
||||
if (reorder)
|
||||
ecp->flags &= ~SYMTAB_INTACT;
|
||||
} else
|
||||
reorder = 1;
|
||||
|
||||
if (strcmp(name, ".symtab") == 0) {
|
||||
ecp->flags |= SYMTAB_EXIST;
|
||||
|
@ -132,7 +132,7 @@ m_xword(m, k, err)
|
||||
return EXTRACT_LONG(cp);
|
||||
}
|
||||
m0 = m->m_next;
|
||||
if (m0 == 0 || M_LEN(m0) + len - k < 4)
|
||||
if (m0 == NULL || M_LEN(m0) + len - k < 4)
|
||||
goto bad;
|
||||
*err = 0;
|
||||
np = MTOD(m0, u_char *);
|
||||
@ -168,7 +168,7 @@ m_xhalf(m, k, err)
|
||||
return EXTRACT_SHORT(cp);
|
||||
}
|
||||
m0 = m->m_next;
|
||||
if (m0 == 0)
|
||||
if (m0 == NULL)
|
||||
goto bad;
|
||||
*err = 0;
|
||||
return (cp[0] << 8) | MTOD(m0, u_char *)[0];
|
||||
@ -205,7 +205,7 @@ bpf_filter(pc, p, wirelen, buflen)
|
||||
} else
|
||||
m = NULL;
|
||||
|
||||
if (pc == 0)
|
||||
if (pc == NULL)
|
||||
/*
|
||||
* No filter means accept all.
|
||||
*/
|
||||
|
@ -64,9 +64,9 @@ ipfrwlock_t ipf_global, ipf_mutex, ipf_ipidfrag, ipf_frcache, ipf_tokens;
|
||||
int (*ipf_checkp) __P((struct ip *, int, void *, int, mb_t **));
|
||||
|
||||
#ifdef IPFILTER_LKM
|
||||
static int *ipff_addr = 0;
|
||||
static int *ipff_addr;
|
||||
static int ipff_value;
|
||||
static __psunsigned_t *ipfk_addr = 0;
|
||||
static __psunsigned_t *ipfk_addr;
|
||||
static __psunsigned_t ipfk_code[4];
|
||||
#endif
|
||||
static void nifattach();
|
||||
@ -85,7 +85,7 @@ typedef struct nif {
|
||||
int nf_unit;
|
||||
} nif_t;
|
||||
|
||||
static nif_t *nif_head = 0;
|
||||
static nif_t *nif_head;
|
||||
static int nif_interfaces = 0;
|
||||
extern int in_interfaces;
|
||||
#if IRIX >= 60500
|
||||
|
@ -57,10 +57,11 @@ snf_pcap_stats(pcap_t *p, struct pcap_stat *ps)
|
||||
static void
|
||||
snf_platform_cleanup(pcap_t *p)
|
||||
{
|
||||
struct pcap_snf *ps = p->priv;
|
||||
struct pcap_snf *ps;
|
||||
|
||||
if (p == NULL)
|
||||
return;
|
||||
ps = p->priv;
|
||||
|
||||
snf_ring_close(ps->snf_ring);
|
||||
snf_close(ps->snf_handle);
|
||||
|
@ -77,6 +77,7 @@ GH_PAGES_PACKAGE_DIR = ${GH_PAGES_DIR}/${GH_PACKAGING_DIR}
|
||||
packages:
|
||||
@-[ -d ${GH_PAGES_DIR} ] && set -x \
|
||||
&& echo "Updating packages on gh-pages ..." \
|
||||
&& mkdir -p ${GH_PAGES_DIR}/${GH_PACKAGING_DIR} \
|
||||
&& SHA1="`openssl sha1 ${PACKAGE_FILE} | awk '{print $$2}'`" \
|
||||
&& SHA256="`openssl sha256 ${PACKAGE_FILE} | awk '{print $$2}'`" \
|
||||
&& SIZE="`ls -l ${PACKAGE_FILE} | awk '{print $$5}'`" \
|
||||
|
@ -12,7 +12,7 @@
|
||||
#
|
||||
|
||||
AC_PREREQ(2.2)
|
||||
AC_INIT([libxo], [0.4.6], [phil@juniper.net])
|
||||
AC_INIT([libxo], [0.6.1], [phil@juniper.net])
|
||||
AM_INIT_AUTOMAKE([-Wall -Werror foreign -Wno-portability])
|
||||
|
||||
# Support silent build rules. Requires at least automake-1.11.
|
||||
@ -74,6 +74,7 @@ AC_CHECK_HEADERS([ctype.h errno.h stdio.h stdlib.h])
|
||||
AC_CHECK_HEADERS([string.h sys/param.h unistd.h ])
|
||||
AC_CHECK_HEADERS([sys/sysctl.h])
|
||||
AC_CHECK_HEADERS([threads.h])
|
||||
AC_CHECK_HEADERS([monitor.h])
|
||||
|
||||
dnl humanize_number(3) is a great function, but it's not standard.
|
||||
dnl Note Macosx has the function in libutil.a but doesn't ship the
|
||||
@ -148,10 +149,18 @@ fi
|
||||
AC_SUBST(GETTEXT_CFLAGS)
|
||||
AC_SUBST(GETTEXT_LIBS)
|
||||
|
||||
GETTEXT_BINDIR=${GETTEXT_PREFIX}/bin
|
||||
AC_SUBST(GETTEXT_BINDIR)
|
||||
GETTEXT_LIBDIR=${GETTEXT_PREFIX}/lib
|
||||
AC_SUBST(GETTEXT_LIBDIR)
|
||||
if test -x ${GETTEXT_PREFIX}/bin/msgfmt ; then
|
||||
GETTEXT_BINDIR=${GETTEXT_PREFIX}/bin
|
||||
elif test -x ${GETTEXT_PREFIX}/local/bin/msgfmt ; then
|
||||
GETTEXT_BINDIR=${GETTEXT_PREFIX}/local/bin
|
||||
else
|
||||
AC_MSG_NOTICE("could not find msgfmt tool")
|
||||
# Use a (bad) fall back value
|
||||
GETTEXT_BINDIR=${GETTEXT_PREFIX}/bin
|
||||
fi
|
||||
AC_SUBST(GETTEXT_BINDIR)
|
||||
|
||||
AM_CONDITIONAL([HAVE_GETTEXT], [test "$HAVE_GETTEXT" = "yes"])
|
||||
|
||||
@ -287,6 +296,18 @@ if test "${LIBXO_WCWIDTH}" != "no"; then
|
||||
AC_DEFINE([LIBXO_WCWIDTH], [1], [Enable local wcwidth implementation])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([retain hash bucket size])
|
||||
AC_ARG_WITH(retain-size,
|
||||
[ --with-retain-size=[DIR] Specify retain hash bucket size (in bits)],
|
||||
[XO_RETAIN_SIZE=$withval],
|
||||
[XO_RETAIN_SIZE=default]
|
||||
)
|
||||
|
||||
AC_MSG_RESULT([$XO_RETAIN_SIZE])
|
||||
if test "${XO_RETAIN_SIZE}" != "default"; then
|
||||
AC_DEFINE_UNQUOTED([XO_RETAIN_SIZE], ${XO_RETAIN_SIZE}, [Retain hash bucket size])
|
||||
fi
|
||||
|
||||
AC_CHECK_LIB([m], [lrint])
|
||||
AM_CONDITIONAL([HAVE_LIBM], [test "$HAVE_LIBM" != "no"])
|
||||
|
||||
@ -347,12 +368,15 @@ XO_SRCDIR=${srcdir}
|
||||
XO_LIBDIR=${libdir}
|
||||
XO_BINDIR=${bindir}
|
||||
XO_INCLUDEDIR=${includedir}
|
||||
XO_CFLAGS="${CFLAGS}"
|
||||
|
||||
AC_SUBST(XO_LIBS)
|
||||
AC_SUBST(XO_SRCDIR)
|
||||
AC_SUBST(XO_LIBDIR)
|
||||
AC_SUBST(XO_BINDIR)
|
||||
AC_SUBST(XO_INCLUDEDIR)
|
||||
AC_SUBST(XO_LIBEXT)
|
||||
AC_SUBST(XO_CFLAGS)
|
||||
|
||||
AC_ARG_WITH(encoder-dir,
|
||||
[ --with-encoder-dir=[DIR] Specify location of encoder libraries],
|
||||
@ -449,4 +473,5 @@ AC_MSG_NOTICE([summary of build options:
|
||||
isthreaded: ${HAVE_ISTHREADED:-no}
|
||||
thread-local: ${THREAD_LOCAL:-no}
|
||||
local wcwidth: ${LIBXO_WCWIDTH:-no}
|
||||
retain size: ${XO_RETAIN_SIZE:-no}
|
||||
])
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -699,9 +699,10 @@ XOF_WARN is set, a warning will be generated.
|
||||
Field modifiers are flags which modify the way content emitted for
|
||||
particular output styles:
|
||||
|
||||
|---+---------------+-------------------------------------------------|
|
||||
|---+---------------+--------------------------------------------------|
|
||||
| M | Name | Description |
|
||||
|---+---------------+-------------------------------------------------|
|
||||
|---+---------------+--------------------------------------------------|
|
||||
| a | argument | The content appears as a 'const char *' argument |
|
||||
| c | colon | A colon (":") is appended after the label |
|
||||
| d | display | Only emit field for display styles (text/HTML) |
|
||||
| e | encoding | Only emit for encoding styles (XML/JSON) |
|
||||
@ -717,7 +718,7 @@ particular output styles:
|
||||
| q | quotes | Quote the field when using JSON style |
|
||||
| t | trim | Trim leading and trailing whitespace |
|
||||
| w | white | A blank (" ") is appended after the label |
|
||||
|---+---------------+-------------------------------------------------|
|
||||
|---+---------------+--------------------------------------------------|
|
||||
|
||||
Roles and modifiers can also use more verbose names, when preceeded by
|
||||
a comma. For example, the modifier string "Lwc" (or "L,white,colon")
|
||||
@ -727,6 +728,27 @@ modifier string "Vkq" (or ":key,quote") means the field has a value
|
||||
role (the default role), that it is a key for the current instance,
|
||||
and that the value should be quoted when encoded for JSON.
|
||||
|
||||
**** The Argument Modifier ({a:})
|
||||
|
||||
The argument modifier indicates that the content of the field
|
||||
descriptor will be placed as a UTF-8 string (const char *) argument
|
||||
within the xo_emit parameters.
|
||||
|
||||
EXAMPLE:
|
||||
xo_emit("{La:} {a:}\n", "Label text", "label", "value");
|
||||
TEXT:
|
||||
Label text value
|
||||
JSON:
|
||||
"label": "value"
|
||||
XML:
|
||||
<label>value</label>
|
||||
|
||||
The argument modifier allows field names for value fields to be passed
|
||||
on the stack, avoiding the need to build a field descriptor using
|
||||
snprintf. For many field roles, the argument modifier is not needed,
|
||||
since those roles have specific mechanisms for arguments, such as
|
||||
"{C:fg-%s}".
|
||||
|
||||
**** The Colon Modifier ({c:})
|
||||
|
||||
The colon modifier appends a single colon to the data value:
|
||||
@ -907,6 +929,21 @@ needed, but often this needs to be controlled by the caller.
|
||||
JSON:
|
||||
"year": "2014"
|
||||
|
||||
The heuristic is based on the format; if the format uses any of the
|
||||
following conversion specifiers, then no quotes are used:
|
||||
|
||||
d i o u x X D O U e E f F g G a A c C p
|
||||
|
||||
**** The Trim Modifier ({t:})
|
||||
|
||||
The trim modifier removes any leading or trailing whitespace from
|
||||
the value.
|
||||
|
||||
EXAMPLE:
|
||||
xo_emit("{t:description}", " some input ");
|
||||
JSON:
|
||||
"description": "some input"
|
||||
|
||||
**** The White Space Modifier ({w:})
|
||||
|
||||
The white space modifier appends a single space to the data value:
|
||||
@ -1029,6 +1066,24 @@ LANG, or LC_ALL environment varibles. The first of this list of
|
||||
variables is used and if none of the variables are set, the locale
|
||||
defaults to "UTF-8".
|
||||
|
||||
libxo will convert these arguments as needed to either UTF-8 (for XML,
|
||||
JSON, and HTML styles) or locale-based strings for display in text
|
||||
style.
|
||||
|
||||
xo_emit("Alll strings are utf-8 content {:tag/%ls}",
|
||||
L"except for wide strings");
|
||||
|
||||
"%S" is equivalent to "%ls".
|
||||
|
||||
|--------+-----------------+-------------------------------|
|
||||
| Format | Argument Type | Argument Contents |
|
||||
|--------+-----------------+-------------------------------|
|
||||
| %s | const char * | UTF-8 string |
|
||||
| %S | const char * | UTF-8 string (alias for '%s') |
|
||||
| %ls | const wchar_t * | Wide character UNICODE string |
|
||||
| %hs | const char * | locale-based string |
|
||||
|--------+-----------------+-------------------------------|
|
||||
|
||||
For example, a function is passed a locale-base name, a hat size,
|
||||
and a time value. The hat size is formatted in a UTF-8 (ASCII)
|
||||
string, and the time value is formatted into a wchar_t string.
|
||||
@ -1163,6 +1218,53 @@ variants might be wise.
|
||||
| xo_emit_errc | xo_emit_errc_p |
|
||||
|------------------+------------------------|
|
||||
|
||||
*** Retaining Parsed Format Information @retain@
|
||||
|
||||
libxo can retain the parsed internal information related to the given
|
||||
format string, allowing subsequent xo_emit calls, the retained
|
||||
information is used, avoiding repetitive parsing of the format string.
|
||||
|
||||
SYNTAX:
|
||||
int xo_emit_f(xo_emit_flags_t flags, const char fmt, ...);
|
||||
EXAMPLE:
|
||||
xo_emit_f(XOEF_RETAIN, "{:some/%02d}{:thing/%-6s}{:fancy}\n",
|
||||
some, thing, fancy);
|
||||
|
||||
To retain parsed format information, use the XOEF_RETAIN flag to the
|
||||
xo_emit_f() function. A complete set of xo_emit_f functions exist to
|
||||
match all the xo_emit function signatures (with handles, varadic
|
||||
argument, and printf-like flags):
|
||||
|
||||
|------------------+------------------------|
|
||||
| Function | Flags Equivalent |
|
||||
|------------------+------------------------|
|
||||
| xo_emit_hv | xo_emit_hvf |
|
||||
| xo_emit_h | xo_emit_hf |
|
||||
| xo_emit | xo_emit_f |
|
||||
| xo_emit_hvp | xo_emit_hvfp |
|
||||
| xo_emit_hp | xo_emit_hfp |
|
||||
| xo_emit_p | xo_emit_fp |
|
||||
|------------------+------------------------|
|
||||
|
||||
The format string must be immutable across multiple calls to xo_emit_f(),
|
||||
since the library retains the string. Typically this is done by using
|
||||
static constant strings, such as string literals. If the string is not
|
||||
immutable, the XOEF_RETAIN flag must not be used.
|
||||
|
||||
The functions xo_retain_clear() and xo_retain_clear_all() release
|
||||
internal information on either a single format string or all format
|
||||
strings, respectively. Neither is required, but the library will
|
||||
retain this information until it is cleared or the process exits.
|
||||
|
||||
const char *fmt = "{:name} {:count/%d}\n";
|
||||
for (i = 0; i < 1000; i++) {
|
||||
xo_open_instance("item");
|
||||
xo_emit_f(XOEF_RETAIN, fmt, name[i], count[i]);
|
||||
}
|
||||
xo_retain_clear(fmt);
|
||||
|
||||
The retained information is kept as thread-specific data.
|
||||
|
||||
*** Example
|
||||
|
||||
In this example, the value for the number of items in stock is emitted:
|
||||
@ -1196,46 +1298,6 @@ penultimate line to:
|
||||
data-type="number"
|
||||
data-help="Number of items in stock">144</div>
|
||||
|
||||
** Command-line Arguments
|
||||
|
||||
libxo uses command line options to trigger rendering behavior. The
|
||||
following options are recognised:
|
||||
|
||||
- --libxo <options>
|
||||
- --libxo=<options>
|
||||
- --libxo:<brief-options>
|
||||
|
||||
Options is a comma-separated list of tokens that correspond to output
|
||||
styles, flags, or features:
|
||||
|
||||
|-------------+-------------------------------------------------------|
|
||||
| Token | Action |
|
||||
|-------------+-------------------------------------------------------|
|
||||
| color | Enable colors/effects for display styles (TEXT, HTML) |
|
||||
| dtrt | Enable "Do The Right Thing" mode |
|
||||
| html | Emit HTML output |
|
||||
| indent=xx | Set the indentation level |
|
||||
| info | Add info attributes (HTML) |
|
||||
| json | Emit JSON output |
|
||||
| keys | Emit the key attribute for keys (XML) |
|
||||
| log-gettext | Log (via stderr) each gettext(3) string lookup |
|
||||
| log-syslog | Log (via stderr) each syslog message (via xo_syslog) |
|
||||
| no-humanize | Ignore the {h:} modifier (TEXT, HTML) |
|
||||
| no-locale | Do not initialize the locale setting |
|
||||
| no-top | Do not emit a top set of braces (JSON) |
|
||||
| not-first | Pretend the 1st output item was not 1st (JSON) |
|
||||
| pretty | Emit pretty-printed output |
|
||||
| text | Emit TEXT output |
|
||||
| underscores | Replace XML-friendly "-"s with JSON friendly "_"s e |
|
||||
| units | Add the 'units' (XML) or 'data-units (HTML) attribute |
|
||||
| warn | Emit warnings when libxo detects bad calls |
|
||||
| warn-xml | Emit warnings in XML |
|
||||
| xml | Emit XML output |
|
||||
| xpath | Add XPath expressions (HTML) |
|
||||
|-------------+-------------------------------------------------------|
|
||||
|
||||
The brief options are detailed in ^LIBXO_OPTIONS^.
|
||||
|
||||
** Representing Hierarchy
|
||||
|
||||
For XML and JSON, individual fields appear inside hierarchies which
|
||||
@ -1382,20 +1444,81 @@ properly.
|
||||
xo_close_marker("fish-guts");
|
||||
}
|
||||
|
||||
** Command-line Arguments
|
||||
|
||||
libxo uses command line options to trigger rendering behavior. The
|
||||
following options are recognised:
|
||||
|
||||
- --libxo <options>
|
||||
- --libxo=<options>
|
||||
- --libxo:<brief-options>
|
||||
|
||||
Programs using libxo are expecting to call the xo_parse_args function
|
||||
to parse these arguments. See ^xo_parse_args^ for details.
|
||||
|
||||
Options is a comma-separated list of tokens that correspond to output
|
||||
styles, flags, or features:
|
||||
|
||||
|-------------+-------------------------------------------------------|
|
||||
| Token | Action |
|
||||
|-------------+-------------------------------------------------------|
|
||||
| color | Enable colors/effects for display styles (TEXT, HTML) |
|
||||
| dtrt | Enable "Do The Right Thing" mode |
|
||||
| html | Emit HTML output |
|
||||
| indent=xx | Set the indentation level |
|
||||
| info | Add info attributes (HTML) |
|
||||
| json | Emit JSON output |
|
||||
| keys | Emit the key attribute for keys (XML) |
|
||||
| log-gettext | Log (via stderr) each gettext(3) string lookup |
|
||||
| log-syslog | Log (via stderr) each syslog message (via xo_syslog) |
|
||||
| no-humanize | Ignore the {h:} modifier (TEXT, HTML) |
|
||||
| no-locale | Do not initialize the locale setting |
|
||||
| no-retain | Prevent retaining formatting information |
|
||||
| no-top | Do not emit a top set of braces (JSON) |
|
||||
| not-first | Pretend the 1st output item was not 1st (JSON) |
|
||||
| pretty | Emit pretty-printed output |
|
||||
| retain | Force retaining formatting information |
|
||||
| text | Emit TEXT output |
|
||||
| underscores | Replace XML-friendly "-"s with JSON friendly "_"s e |
|
||||
| units | Add the 'units' (XML) or 'data-units (HTML) attribute |
|
||||
| warn | Emit warnings when libxo detects bad calls |
|
||||
| warn-xml | Emit warnings in XML |
|
||||
| xml | Emit XML output |
|
||||
| xpath | Add XPath expressions (HTML) |
|
||||
|-------------+-------------------------------------------------------|
|
||||
|
||||
The brief options are detailed in ^LIBXO_OPTIONS^.
|
||||
|
||||
* The libxo API
|
||||
|
||||
This section gives details about the functions in libxo, how to call
|
||||
them, and the actions they perform.
|
||||
|
||||
** Handles @handles@
|
||||
|
||||
libxo uses "handles" to control its rendering functionality. The
|
||||
handle contains state and buffered data, as well as callback functions
|
||||
to process data.
|
||||
|
||||
A default handle is used when a NULL is passed to functions accepting
|
||||
a handle. This handle is initialized to write its data to stdout
|
||||
using the default style of text (XO_STYLE_TEXT).
|
||||
Handles give an abstraction for libxo that encapsulates the state of a
|
||||
stream of output. Handles have the data type "xo_handle_t" and are
|
||||
opaque to the caller.
|
||||
|
||||
For the convenience of callers, the libxo library includes handle-less
|
||||
functions that implicitly use the default handle. Any function that
|
||||
takes a handle will use the default handle is a value of NULL is
|
||||
passed in place of a valid handle.
|
||||
The library has a default handle that is automatically initialized.
|
||||
By default, this handle will send text style output (XO_STYLE_TEXT) to
|
||||
standard output. The xo_set_style and xo_set_flags functions can be
|
||||
used to change this behavior.
|
||||
|
||||
For the typical command that is generating output on standard output,
|
||||
there is no need to create an explicit handle, but they are available
|
||||
when needed, e.g., for daemons that generate multiple streams of
|
||||
output.
|
||||
|
||||
Many libxo functions take a handle as their first parameter; most that
|
||||
do not use the default handle. Any function taking a handle can be
|
||||
passed NULL to access the default handle. For the convenience of
|
||||
callers, the libxo library includes handle-less functions that
|
||||
implicitly use the default handle.
|
||||
|
||||
For example, the following are equivalent:
|
||||
|
||||
@ -1404,46 +1527,6 @@ For example, the following are equivalent:
|
||||
|
||||
Handles are created using xo_create() and destroy using xo_destroy().
|
||||
|
||||
** UTF-8
|
||||
|
||||
All strings for libxo must be UTF-8. libxo will handle turning them
|
||||
into locale-based strings for display to the user.
|
||||
|
||||
The only exception is argument formatted using the "%ls" format, which
|
||||
require a wide character string (wchar_t *) as input. libxo will
|
||||
convert these arguments as needed to either UTF-8 (for XML, JSON, and
|
||||
HTML styles) or locale-based strings for display in text style.
|
||||
|
||||
xo_emit("Alll strings are utf-8 content {:tag/%ls}",
|
||||
L"except for wide strings");
|
||||
|
||||
"%S" is equivalent to "%ls".
|
||||
|
||||
* The libxo API
|
||||
|
||||
This section gives details about the functions in libxo, how to call
|
||||
them, and the actions they perform.
|
||||
|
||||
** Handles
|
||||
|
||||
Handles give an abstraction for libxo that encapsulates the state of a
|
||||
stream of output. Handles have the data type "xo_handle_t" and are
|
||||
opaque to the caller.
|
||||
|
||||
The library has a default handle that is automatically initialized.
|
||||
By default, this handle will send text style output to standard output.
|
||||
The xo_set_style and xo_set_flags functions can be used to change this
|
||||
behavior.
|
||||
|
||||
Many libxo functions take a handle as their first parameter; most that
|
||||
do not use the default handle. Any function taking a handle can
|
||||
be passed NULL to access the default handle.
|
||||
|
||||
For the typical command that is generating output on standard output,
|
||||
there is no need to create an explicit handle, but they are available
|
||||
when needed, e.g., for daemons that generate multiple streams of
|
||||
output.
|
||||
|
||||
*** xo_create
|
||||
|
||||
A handle can be allocated using the xo_create() function:
|
||||
@ -1653,11 +1736,34 @@ string, since an inappropriate cast can ruin your day. The vap
|
||||
argument to xo_emit_hv() points to a variable argument list that can
|
||||
be used to retrieve arguments via va_arg().
|
||||
|
||||
*** Single Field Emitting Functions (xo_emit_field) @xo_emit_field@
|
||||
|
||||
The following functions can also make output, but only make a single
|
||||
field at a time:
|
||||
|
||||
int xo_emit_field_hv (xo_handle_t *xop, const char *rolmod,
|
||||
const char *contents, const char *fmt,
|
||||
const char *efmt, va_list vap);
|
||||
|
||||
int xo_emit_field_h (xo_handle_t *xop, const char *rolmod,
|
||||
const char *contents, const char *fmt,
|
||||
const char *efmt, ...);
|
||||
|
||||
int xo_emit_field (const char *rolmod, const char *contents,
|
||||
const char *fmt, const char *efmt, ...);
|
||||
|
||||
These functions are intended to avoid the scenario where one
|
||||
would otherwise need to compose a format descriptors using
|
||||
snprintf(). The individual parts of the format descriptor are
|
||||
passed in distinctly.
|
||||
|
||||
xo_emit("T", "Host name is ", NULL, NULL);
|
||||
xo_emit("V", "host-name", NULL, NULL, host-name);
|
||||
|
||||
*** Attributes (xo_attr) @xo_attr@
|
||||
|
||||
The xo_attr() function emits attributes for the XML output style.
|
||||
|
||||
|
||||
int xo_attr (const char *name, const char *fmt, ...);
|
||||
int xo_attr_h (xo_handle_t *xop, const char *name,
|
||||
const char *fmt, ...);
|
||||
@ -2555,23 +2661,23 @@ In 2001, we added an XML API to the JUNOS operating system, which is
|
||||
built on top of FreeBSD. Eventually this API became standardized as
|
||||
the NETCONF API (RFC 6241). As part of this effort, we modified many
|
||||
FreeBSD utilities to emit XML, typically via a "-X" switch. The
|
||||
results were mixed. The cost of maintaining this code, updating it
|
||||
results were mixed. The cost of maintaining this code, updating it,
|
||||
and carrying it were non-trivial, and contributed to our expense (and
|
||||
the associated delay) with upgrading the version of FreeBSD on which
|
||||
each release of JUNOS is based.
|
||||
|
||||
A recent (2014) effort within JUNOS aims at removing our modifications
|
||||
to the underlying FreeBSD code as a means of reducing the expense and
|
||||
delay. JUNOS is structured to have system components generate XML
|
||||
that is rendered by the CLI (think: login shell) into human-readable
|
||||
text. This allows the API to use the same plumbing as the CLI, and
|
||||
ensures that all components emit XML, and that it is emitted with
|
||||
knowledge of the consumer of that XML, yielding an API that have no
|
||||
incremental cost or feature delay.
|
||||
delay in tracking HEAD. JUNOS is structured to have system components
|
||||
generate XML that is rendered by the CLI (think: login shell) into
|
||||
human-readable text. This allows the API to use the same plumbing as
|
||||
the CLI, and ensures that all components emit XML, and that it is
|
||||
emitted with knowledge of the consumer of that XML, yielding an API
|
||||
that have no incremental cost or feature delay.
|
||||
|
||||
libxo is an effort to mix the best aspects of the JUNOS strategy into
|
||||
FreeBSD in a seemless way, allowing commands to make printf-like
|
||||
output calls without needing to care how the output is rendered.
|
||||
output calls with a single code path.
|
||||
|
||||
*** Did the complex semantics of format strings evolve over time?
|
||||
|
||||
|
@ -135,7 +135,7 @@ cbor_encode_uint (xo_buffer_t *xbp, uint64_t minor, unsigned limit)
|
||||
char *bp = xbp->xb_curp;
|
||||
int i, m;
|
||||
|
||||
if (minor > (1UL<<32)) {
|
||||
if (minor > (1ULL << 32)) {
|
||||
*bp++ |= CBOR_LEN64;
|
||||
m = 64;
|
||||
|
||||
|
@ -77,34 +77,34 @@ while test $# -gt 0; do
|
||||
;;
|
||||
|
||||
--cflags)
|
||||
echo -I@LIBXO_INCLUDEDIR@ @LIBXO_CFLAGS@
|
||||
echo -I@XO_INCLUDEDIR@ @XO_CFLAGS@
|
||||
;;
|
||||
|
||||
|
||||
--share)
|
||||
echo @LIBXO_SHAREDIR@
|
||||
echo @XO_SHAREDIR@
|
||||
;;
|
||||
|
||||
--bindir)
|
||||
echo @LIBXO_BINDIR@
|
||||
echo @XO_BINDIR@
|
||||
;;
|
||||
|
||||
--libdir)
|
||||
echo @LIBXO_LIBDIR@
|
||||
echo @XO_LIBDIR@
|
||||
;;
|
||||
|
||||
|
||||
--libs)
|
||||
if [ "`uname`" = "Linux" ]
|
||||
then
|
||||
if [ "@LIBXO_LIBDIR@" = "-L/usr/lib" -o "@LIBXO_LIBDIR@" = "-L/usr/lib64" ]
|
||||
if [ "@XO_LIBDIR@" = "-L/usr/lib" -o "@XO_LIBDIR@" = "-L/usr/lib64" ]
|
||||
then
|
||||
echo @LIBXO_LIBS@
|
||||
echo @XO_LIBS@
|
||||
else
|
||||
echo -L@LIBXO_LIBDIR@ @LIBXO_LIBS@
|
||||
echo -L@XO_LIBDIR@ @XO_LIBS@
|
||||
fi
|
||||
else
|
||||
echo -L@LIBXO_LIBDIR@ @LIBXO_LIBS@ @WIN32_EXTRA_LIBADD@
|
||||
echo -L@XO_LIBDIR@ @XO_LIBS@
|
||||
fi
|
||||
;;
|
||||
|
||||
|
@ -19,7 +19,8 @@
|
||||
* http://juniper.github.io/libxo/libxo-manual.html
|
||||
*
|
||||
* For first time readers, the core bits of code to start looking at are:
|
||||
* - xo_do_emit() -- the central function of the library
|
||||
* - xo_do_emit() -- parse and emit a set of fields
|
||||
* - xo_do_emit_fields -- the central function of the library
|
||||
* - xo_do_format_field() -- handles formatting a single field
|
||||
* - xo_transiton() -- the state machine that keeps things sane
|
||||
* and of course the "xo_handle_t" data structure, which carries all
|
||||
@ -120,6 +121,7 @@
|
||||
|
||||
const char xo_version[] = LIBXO_VERSION;
|
||||
const char xo_version_extra[] = LIBXO_VERSION_EXTRA;
|
||||
static const char xo_default_format[] = "%s";
|
||||
|
||||
#ifndef UNUSED
|
||||
#define UNUSED __attribute__ ((__unused__))
|
||||
@ -338,6 +340,7 @@ typedef unsigned long xo_xff_flags_t;
|
||||
#define XFF_GT_FIELD (1<<19) /* Call gettext() on a field */
|
||||
|
||||
#define XFF_GT_PLURAL (1<<20) /* Call dngettext to find plural form */
|
||||
#define XFF_ARGUMENT (1<<21) /* Content provided via argument */
|
||||
|
||||
/* Flags to turn off when we don't want i18n processing */
|
||||
#define XFF_GT_FLAGS (XFF_GT_FIELD | XFF_GT_PLURAL)
|
||||
@ -1046,7 +1049,7 @@ xo_is_utf8 (char ch)
|
||||
return (ch & 0x80);
|
||||
}
|
||||
|
||||
static int
|
||||
static inline int
|
||||
xo_utf8_to_wc_len (const char *buf)
|
||||
{
|
||||
unsigned b = (unsigned char) *buf;
|
||||
@ -1105,9 +1108,13 @@ xo_buf_utf8_len (xo_handle_t *xop, const char *buf, int bufsiz)
|
||||
* bits we pull off the first character is dependent on the length,
|
||||
* but we put 6 bits off all other bytes.
|
||||
*/
|
||||
static wchar_t
|
||||
static inline wchar_t
|
||||
xo_utf8_char (const char *buf, int len)
|
||||
{
|
||||
/* Most common case: singleton byte */
|
||||
if (len == 1)
|
||||
return (unsigned char) buf[0];
|
||||
|
||||
int i;
|
||||
wchar_t wc;
|
||||
const unsigned char *cp = (const unsigned char *) buf;
|
||||
@ -1281,6 +1288,195 @@ xo_data_escape (xo_handle_t *xop, const char *str, int len)
|
||||
xo_buf_escape(xop, &xop->xo_data, str, len, 0);
|
||||
}
|
||||
|
||||
#ifdef LIBXO_NO_RETAIN
|
||||
/*
|
||||
* Empty implementations of the retain logic
|
||||
*/
|
||||
|
||||
void
|
||||
xo_retain_clear_all (void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
xo_retain_clear (const char *fmt UNUSED)
|
||||
{
|
||||
return;
|
||||
}
|
||||
static void
|
||||
xo_retain_add (const char *fmt UNUSED, xo_field_info_t *fields UNUSED,
|
||||
unsigned num_fields UNUSED)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
xo_retain_find (const char *fmt UNUSED, xo_field_info_t **valp UNUSED,
|
||||
unsigned *nump UNUSED)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#else /* !LIBXO_NO_RETAIN */
|
||||
/*
|
||||
* Retain: We retain parsed field definitions to enhance performance,
|
||||
* especially inside loops. We depend on the caller treating the format
|
||||
* strings as immutable, so that we can retain pointers into them. We
|
||||
* hold the pointers in a hash table, so allow quick access. Retained
|
||||
* information is retained until xo_retain_clear is called.
|
||||
*/
|
||||
|
||||
/*
|
||||
* xo_retain_entry_t holds information about one retained set of
|
||||
* parsed fields.
|
||||
*/
|
||||
typedef struct xo_retain_entry_s {
|
||||
struct xo_retain_entry_s *xre_next; /* Pointer to next (older) entry */
|
||||
unsigned long xre_hits; /* Number of times we've hit */
|
||||
const char *xre_format; /* Pointer to format string */
|
||||
unsigned xre_num_fields; /* Number of fields saved */
|
||||
xo_field_info_t *xre_fields; /* Pointer to fields */
|
||||
} xo_retain_entry_t;
|
||||
|
||||
/*
|
||||
* xo_retain_t holds a complete set of parsed fields as a hash table.
|
||||
*/
|
||||
#ifndef XO_RETAIN_SIZE
|
||||
#define XO_RETAIN_SIZE 6
|
||||
#endif /* XO_RETAIN_SIZE */
|
||||
#define RETAIN_HASH_SIZE (1<<XO_RETAIN_SIZE)
|
||||
|
||||
typedef struct xo_retain_s {
|
||||
xo_retain_entry_t *xr_bucket[RETAIN_HASH_SIZE];
|
||||
} xo_retain_t;
|
||||
|
||||
static THREAD_LOCAL(xo_retain_t) xo_retain;
|
||||
static THREAD_LOCAL(unsigned) xo_retain_count;
|
||||
|
||||
/*
|
||||
* Simple hash function based on Thomas Wang's paper. The original is
|
||||
* gone, but an archive is available on the Way Back Machine:
|
||||
*
|
||||
* http://web.archive.org/web/20071223173210/\
|
||||
* http://www.concentric.net/~Ttwang/tech/inthash.htm
|
||||
*
|
||||
* For our purposes, we can assume the low four bits are uninteresting
|
||||
* since any string less that 16 bytes wouldn't be worthy of
|
||||
* retaining. We toss the high bits also, since these bits are likely
|
||||
* to be common among constant format strings. We then run Wang's
|
||||
* algorithm, and cap the result at RETAIN_HASH_SIZE.
|
||||
*/
|
||||
static unsigned
|
||||
xo_retain_hash (const char *fmt)
|
||||
{
|
||||
volatile uintptr_t iptr = (uintptr_t) (const void *) fmt;
|
||||
|
||||
/* Discard low four bits and high bits; they aren't interesting */
|
||||
uint32_t val = (uint32_t) ((iptr >> 4) & (((1 << 24) - 1)));
|
||||
|
||||
val = (val ^ 61) ^ (val >> 16);
|
||||
val = val + (val << 3);
|
||||
val = val ^ (val >> 4);
|
||||
val = val * 0x3a8f05c5; /* My large prime number */
|
||||
val = val ^ (val >> 15);
|
||||
val &= RETAIN_HASH_SIZE - 1;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Walk all buckets, clearing all retained entries
|
||||
*/
|
||||
void
|
||||
xo_retain_clear_all (void)
|
||||
{
|
||||
int i;
|
||||
xo_retain_entry_t *xrep, *next;
|
||||
|
||||
for (i = 0; i < RETAIN_HASH_SIZE; i++) {
|
||||
for (xrep = xo_retain.xr_bucket[i]; xrep; xrep = next) {
|
||||
next = xrep->xre_next;
|
||||
xo_free(xrep);
|
||||
}
|
||||
xo_retain.xr_bucket[i] = NULL;
|
||||
}
|
||||
xo_retain_count = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Walk all buckets, clearing all retained entries
|
||||
*/
|
||||
void
|
||||
xo_retain_clear (const char *fmt)
|
||||
{
|
||||
xo_retain_entry_t **xrepp;
|
||||
unsigned hash = xo_retain_hash(fmt);
|
||||
|
||||
for (xrepp = &xo_retain.xr_bucket[hash]; *xrepp;
|
||||
xrepp = &(*xrepp)->xre_next) {
|
||||
if ((*xrepp)->xre_format == fmt) {
|
||||
*xrepp = (*xrepp)->xre_next;
|
||||
xo_retain_count -= 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Search the hash for an entry matching 'fmt'; return it's fields.
|
||||
*/
|
||||
static int
|
||||
xo_retain_find (const char *fmt, xo_field_info_t **valp, unsigned *nump)
|
||||
{
|
||||
if (xo_retain_count == 0)
|
||||
return -1;
|
||||
|
||||
unsigned hash = xo_retain_hash(fmt);
|
||||
xo_retain_entry_t *xrep;
|
||||
|
||||
for (xrep = xo_retain.xr_bucket[hash]; xrep != NULL;
|
||||
xrep = xrep->xre_next) {
|
||||
if (xrep->xre_format == fmt) {
|
||||
*valp = xrep->xre_fields;
|
||||
*nump = xrep->xre_num_fields;
|
||||
xrep->xre_hits += 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
xo_retain_add (const char *fmt, xo_field_info_t *fields, unsigned num_fields)
|
||||
{
|
||||
unsigned hash = xo_retain_hash(fmt);
|
||||
xo_retain_entry_t *xrep;
|
||||
unsigned sz = sizeof(*xrep) + (num_fields + 1) * sizeof(*fields);
|
||||
xo_field_info_t *xfip;
|
||||
|
||||
xrep = xo_realloc(NULL, sz);
|
||||
if (xrep == NULL)
|
||||
return;
|
||||
|
||||
xfip = (xo_field_info_t *) &xrep[1];
|
||||
memcpy(xfip, fields, num_fields * sizeof(*fields));
|
||||
|
||||
bzero(xrep, sizeof(*xrep));
|
||||
|
||||
xrep->xre_format = fmt;
|
||||
xrep->xre_fields = xfip;
|
||||
xrep->xre_num_fields = num_fields;
|
||||
|
||||
/* Record the field info in the retain bucket */
|
||||
xrep->xre_next = xo_retain.xr_bucket[hash];
|
||||
xo_retain.xr_bucket[hash] = xrep;
|
||||
xo_retain_count += 1;
|
||||
}
|
||||
|
||||
#endif /* !LIBXO_NO_RETAIN */
|
||||
|
||||
/*
|
||||
* Generate a warning. Normally, this is a text message written to
|
||||
* standard error. If the XOF_WARN_XML flag is set, then we generate
|
||||
@ -1574,6 +1770,19 @@ xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap)
|
||||
break;
|
||||
}
|
||||
|
||||
switch (xo_style(xop)) {
|
||||
case XO_STYLE_HTML:
|
||||
if (XOIF_ISSET(xop, XOIF_DIV_OPEN)) {
|
||||
static char div_close[] = "</div>";
|
||||
XOIF_CLEAR(xop, XOIF_DIV_OPEN);
|
||||
xo_data_append(xop, div_close, sizeof(div_close) - 1);
|
||||
|
||||
if (XOF_ISSET(xop, XOF_PRETTY))
|
||||
xo_data_append(xop, "\n", 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
(void) xo_flush_h(xop);
|
||||
}
|
||||
|
||||
@ -1679,6 +1888,39 @@ xo_create_to_file (FILE *fp, xo_style_t style, xo_xof_flags_t flags)
|
||||
return xop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default handler to output to a file.
|
||||
* @xop libxo handle
|
||||
* @fp FILE pointer to use
|
||||
*/
|
||||
int
|
||||
xo_set_file_h (xo_handle_t *xop, FILE *fp)
|
||||
{
|
||||
xop = xo_default(xop);
|
||||
|
||||
if (fp == NULL) {
|
||||
xo_failure(xop, "xo_set_file: NULL fp");
|
||||
return -1;
|
||||
}
|
||||
|
||||
xop->xo_opaque = fp;
|
||||
xop->xo_write = xo_write_to_file;
|
||||
xop->xo_close = xo_close_file;
|
||||
xop->xo_flush = xo_flush_file;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default handler to output to a file.
|
||||
* @fp FILE pointer to use
|
||||
*/
|
||||
int
|
||||
xo_set_file (FILE *fp)
|
||||
{
|
||||
return xo_set_file_h(NULL, fp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Release any resources held by the handle.
|
||||
* @xop XO handle to alter (or NULL for default handle)
|
||||
@ -1824,9 +2066,11 @@ static xo_mapping_t xo_xof_names[] = {
|
||||
{ XOF_LOG_SYSLOG, "log-syslog" },
|
||||
{ XOF_NO_HUMANIZE, "no-humanize" },
|
||||
{ XOF_NO_LOCALE, "no-locale" },
|
||||
{ XOF_RETAIN_NONE, "no-retain" },
|
||||
{ XOF_NO_TOP, "no-top" },
|
||||
{ XOF_NOT_FIRST, "not-first" },
|
||||
{ XOF_PRETTY, "pretty" },
|
||||
{ XOF_RETAIN_ALL, "retain" },
|
||||
{ XOF_UNDERSCORES, "underscores" },
|
||||
{ XOF_UNITS, "units" },
|
||||
{ XOF_WARN, "warn" },
|
||||
@ -3374,6 +3618,15 @@ xo_buf_append_div (xo_handle_t *xop, const char *class, xo_xff_flags_t flags,
|
||||
static char div_end[] = "\">";
|
||||
static char div_close[] = "</div>";
|
||||
|
||||
/* The encoding format defaults to the normal format */
|
||||
if (encoding == NULL) {
|
||||
char *enc = alloca(vlen + 1);
|
||||
memcpy(enc, value, vlen);
|
||||
enc[vlen] = '\0';
|
||||
encoding = xo_fix_encoding(xop, enc);
|
||||
elen = strlen(encoding);
|
||||
}
|
||||
|
||||
/*
|
||||
* To build our XPath predicate, we need to save the va_list before
|
||||
* we format our data, and then restore it before we format the
|
||||
@ -3406,15 +3659,6 @@ xo_buf_append_div (xo_handle_t *xop, const char *class, xo_xff_flags_t flags,
|
||||
else
|
||||
xo_buf_append(pbp, "='", 2);
|
||||
|
||||
/* The encoding format defaults to the normal format */
|
||||
if (encoding == NULL) {
|
||||
char *enc = alloca(vlen + 1);
|
||||
memcpy(enc, value, vlen);
|
||||
enc[vlen] = '\0';
|
||||
encoding = xo_fix_encoding(xop, enc);
|
||||
elen = strlen(encoding);
|
||||
}
|
||||
|
||||
xo_xff_flags_t pflags = flags | XFF_XML | XFF_ATTR;
|
||||
pflags &= ~(XFF_NO_OUTPUT | XFF_ENCODE_ONLY);
|
||||
xo_do_format_field(xop, pbp, encoding, elen, pflags);
|
||||
@ -3613,10 +3857,9 @@ xo_format_text (xo_handle_t *xop, const char *str, int len)
|
||||
}
|
||||
|
||||
static void
|
||||
xo_format_title (xo_handle_t *xop, xo_field_info_t *xfip)
|
||||
xo_format_title (xo_handle_t *xop, xo_field_info_t *xfip,
|
||||
const char *str, unsigned len)
|
||||
{
|
||||
const char *str = xfip->xfi_content;
|
||||
unsigned len = xfip->xfi_clen;
|
||||
const char *fmt = xfip->xfi_format;
|
||||
unsigned flen = xfip->xfi_flen;
|
||||
xo_xff_flags_t flags = xfip->xfi_flags;
|
||||
@ -4083,10 +4326,9 @@ xo_format_value (xo_handle_t *xop, const char *name, int nlen,
|
||||
}
|
||||
|
||||
static void
|
||||
xo_set_gettext_domain (xo_handle_t *xop, xo_field_info_t *xfip)
|
||||
xo_set_gettext_domain (xo_handle_t *xop, xo_field_info_t *xfip,
|
||||
const char *str, unsigned len)
|
||||
{
|
||||
const char *str = xfip->xfi_content;
|
||||
unsigned len = xfip->xfi_clen;
|
||||
const char *fmt = xfip->xfi_format;
|
||||
unsigned flen = xfip->xfi_flen;
|
||||
|
||||
@ -4335,13 +4577,13 @@ xo_colors_enabled (xo_handle_t *xop UNUSED)
|
||||
}
|
||||
|
||||
static void
|
||||
xo_colors_handle_text (xo_handle_t *xop UNUSED, xo_colors_t *newp)
|
||||
xo_colors_handle_text (xo_handle_t *xop, xo_colors_t *newp)
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
char *cp = buf, *ep = buf + sizeof(buf);
|
||||
unsigned i, bit;
|
||||
xo_colors_t *oldp = &xop->xo_colors;
|
||||
const char *code;
|
||||
const char *code = NULL;
|
||||
|
||||
/*
|
||||
* Start the buffer with an escape. We don't want to add the '['
|
||||
@ -4460,10 +4702,9 @@ xo_colors_handle_html (xo_handle_t *xop, xo_colors_t *newp)
|
||||
}
|
||||
|
||||
static void
|
||||
xo_format_colors (xo_handle_t *xop, xo_field_info_t *xfip)
|
||||
xo_format_colors (xo_handle_t *xop, xo_field_info_t *xfip,
|
||||
const char *str, unsigned len)
|
||||
{
|
||||
const char *str = xfip->xfi_content;
|
||||
unsigned len = xfip->xfi_clen;
|
||||
const char *fmt = xfip->xfi_format;
|
||||
unsigned flen = xfip->xfi_flen;
|
||||
|
||||
@ -4534,10 +4775,9 @@ xo_format_colors (xo_handle_t *xop, xo_field_info_t *xfip)
|
||||
}
|
||||
|
||||
static void
|
||||
xo_format_units (xo_handle_t *xop, xo_field_info_t *xfip)
|
||||
xo_format_units (xo_handle_t *xop, xo_field_info_t *xfip,
|
||||
const char *str, unsigned len)
|
||||
{
|
||||
const char *str = xfip->xfi_content;
|
||||
unsigned len = xfip->xfi_clen;
|
||||
const char *fmt = xfip->xfi_format;
|
||||
unsigned flen = xfip->xfi_flen;
|
||||
xo_xff_flags_t flags = xfip->xfi_flags;
|
||||
@ -4589,10 +4829,9 @@ xo_format_units (xo_handle_t *xop, xo_field_info_t *xfip)
|
||||
}
|
||||
|
||||
static int
|
||||
xo_find_width (xo_handle_t *xop, xo_field_info_t *xfip)
|
||||
xo_find_width (xo_handle_t *xop, xo_field_info_t *xfip,
|
||||
const char *str, unsigned len)
|
||||
{
|
||||
const char *str = xfip->xfi_content;
|
||||
unsigned len = xfip->xfi_clen;
|
||||
const char *fmt = xfip->xfi_format;
|
||||
unsigned flen = xfip->xfi_flen;
|
||||
|
||||
@ -4639,7 +4878,8 @@ xo_anchor_clear (xo_handle_t *xop)
|
||||
* format it when the end anchor tag is seen.
|
||||
*/
|
||||
static void
|
||||
xo_anchor_start (xo_handle_t *xop, xo_field_info_t *xfip)
|
||||
xo_anchor_start (xo_handle_t *xop, xo_field_info_t *xfip,
|
||||
const char *str, unsigned len)
|
||||
{
|
||||
if (xo_style(xop) != XO_STYLE_TEXT && xo_style(xop) != XO_STYLE_HTML)
|
||||
return;
|
||||
@ -4656,11 +4896,12 @@ xo_anchor_start (xo_handle_t *xop, xo_field_info_t *xfip)
|
||||
* Now we find the width, if possible. If it's not there,
|
||||
* we'll get it on the end anchor.
|
||||
*/
|
||||
xop->xo_anchor_min_width = xo_find_width(xop, xfip);
|
||||
xop->xo_anchor_min_width = xo_find_width(xop, xfip, str, len);
|
||||
}
|
||||
|
||||
static void
|
||||
xo_anchor_stop (xo_handle_t *xop, xo_field_info_t *xfip)
|
||||
xo_anchor_stop (xo_handle_t *xop, xo_field_info_t *xfip,
|
||||
const char *str, unsigned len)
|
||||
{
|
||||
if (xo_style(xop) != XO_STYLE_TEXT && xo_style(xop) != XO_STYLE_HTML)
|
||||
return;
|
||||
@ -4672,7 +4913,7 @@ xo_anchor_stop (xo_handle_t *xop, xo_field_info_t *xfip)
|
||||
|
||||
XOIF_CLEAR(xop, XOIF_UNITS_PENDING);
|
||||
|
||||
int width = xo_find_width(xop, xfip);
|
||||
int width = xo_find_width(xop, xfip, str, len);
|
||||
if (width == 0)
|
||||
width = xop->xo_anchor_min_width;
|
||||
|
||||
@ -4787,6 +5028,7 @@ static xo_mapping_t xo_role_names[] = {
|
||||
#define XO_ROLE_NEWLINE '\n'
|
||||
|
||||
static xo_mapping_t xo_modifier_names[] = {
|
||||
{ XFF_ARGUMENT, "argument" },
|
||||
{ XFF_COLON, "colon" },
|
||||
{ XFF_COMMA, "comma" },
|
||||
{ XFF_DISPLAY_ONLY, "display" },
|
||||
@ -4858,6 +5100,7 @@ xo_count_fields (xo_handle_t *xop UNUSED, const char *fmt)
|
||||
* '[': start a section of anchored text
|
||||
* ']': end a section of anchored text
|
||||
* The following modifiers are also supported:
|
||||
* 'a': content is provided via argument (const char *), not descriptor
|
||||
* 'c': flag: emit a colon after the label
|
||||
* 'd': field is only emitted for display styles (text and html)
|
||||
* 'e': field is only emitted for encoding styles (xml and json)
|
||||
@ -4884,7 +5127,7 @@ xo_parse_roles (xo_handle_t *xop, const char *fmt,
|
||||
xo_xff_flags_t flags = 0;
|
||||
uint8_t fnum = 0;
|
||||
|
||||
for (sp = basep; sp; sp++) {
|
||||
for (sp = basep; sp && *sp; sp++) {
|
||||
if (*sp == ':' || *sp == '/' || *sp == '}')
|
||||
break;
|
||||
|
||||
@ -4961,6 +5204,10 @@ xo_parse_roles (xo_handle_t *xop, const char *fmt,
|
||||
fnum = (fnum * 10) + (*sp - '0');
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
flags |= XFF_ARGUMENT;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
flags |= XFF_COLON;
|
||||
break;
|
||||
@ -5133,7 +5380,6 @@ static int
|
||||
xo_parse_fields (xo_handle_t *xop, xo_field_info_t *fields,
|
||||
unsigned num_fields, const char *fmt)
|
||||
{
|
||||
static const char default_format[] = "%s";
|
||||
const char *cp, *sp, *ep, *basep;
|
||||
unsigned field = 0;
|
||||
xo_field_info_t *xfip = fields;
|
||||
@ -5267,12 +5513,12 @@ xo_parse_fields (xo_handle_t *xop, xo_field_info_t *fields,
|
||||
xfip->xfi_next = ++sp;
|
||||
|
||||
/* If we have content, then we have a default format */
|
||||
if (xfip->xfi_clen || format) {
|
||||
if (xfip->xfi_clen || format || (xfip->xfi_flags & XFF_ARGUMENT)) {
|
||||
if (format) {
|
||||
xfip->xfi_format = format;
|
||||
xfip->xfi_flen = flen;
|
||||
} else if (xo_role_wants_default_format(xfip->xfi_ftype)) {
|
||||
xfip->xfi_format = default_format;
|
||||
xfip->xfi_format = xo_default_format;
|
||||
xfip->xfi_flen = 2;
|
||||
}
|
||||
}
|
||||
@ -5568,9 +5814,8 @@ xo_gettext_combine_formats (xo_handle_t *xop, const char *fmt UNUSED,
|
||||
* Summary: i18n aighn't cheap.
|
||||
*/
|
||||
static const char *
|
||||
xo_gettext_build_format (xo_handle_t *xop UNUSED,
|
||||
xo_field_info_t *fields UNUSED,
|
||||
int this_field UNUSED,
|
||||
xo_gettext_build_format (xo_handle_t *xop,
|
||||
xo_field_info_t *fields, int this_field,
|
||||
const char *fmt, char **new_fmtp)
|
||||
{
|
||||
if (xo_style_is_encoding(xop))
|
||||
@ -5686,17 +5931,22 @@ xo_gettext_rebuild_content (xo_handle_t *xop UNUSED,
|
||||
#endif /* HAVE_GETTEXT */
|
||||
|
||||
/*
|
||||
* The central function for emitting libxo output.
|
||||
* Emit a set of fields. This is really the core of libxo.
|
||||
*/
|
||||
static int
|
||||
xo_do_emit (xo_handle_t *xop, const char *fmt)
|
||||
xo_do_emit_fields (xo_handle_t *xop, xo_field_info_t *fields,
|
||||
unsigned max_fields, const char *fmt)
|
||||
{
|
||||
int gettext_inuse = 0;
|
||||
int gettext_changed = 0;
|
||||
int gettext_reordered = 0;
|
||||
unsigned ftype;
|
||||
xo_xff_flags_t flags;
|
||||
xo_field_info_t *new_fields = NULL;
|
||||
|
||||
xo_field_info_t *xfip;
|
||||
unsigned field;
|
||||
int rc = 0;
|
||||
|
||||
int flush = XOF_ISSET(xop, XOF_FLUSH);
|
||||
int flush_line = XOF_ISSET(xop, XOF_FLUSH_LINE);
|
||||
char *new_fmt = NULL;
|
||||
@ -5704,20 +5954,6 @@ xo_do_emit (xo_handle_t *xop, const char *fmt)
|
||||
if (XOIF_ISSET(xop, XOIF_REORDER) || xo_style(xop) == XO_STYLE_ENCODER)
|
||||
flush_line = 0;
|
||||
|
||||
xop->xo_columns = 0; /* Always reset it */
|
||||
xop->xo_errno = errno; /* Save for "%m" */
|
||||
|
||||
unsigned max_fields = xo_count_fields(xop, fmt), field;
|
||||
xo_field_info_t fields[max_fields], *xfip;
|
||||
|
||||
bzero(fields, max_fields * sizeof(fields[0]));
|
||||
|
||||
if (xo_parse_fields(xop, fields, max_fields, fmt))
|
||||
return -1; /* Warning already displayed */
|
||||
|
||||
unsigned ftype;
|
||||
xo_xff_flags_t flags;
|
||||
|
||||
/*
|
||||
* Some overhead for gettext; if the fields in the msgstr returned
|
||||
* by gettext are reordered, then we need to record start and end
|
||||
@ -5745,6 +5981,18 @@ xo_do_emit (xo_handle_t *xop, const char *fmt)
|
||||
min_fstart = field;
|
||||
}
|
||||
|
||||
const char *content = xfip->xfi_content;
|
||||
int clen = xfip->xfi_clen;
|
||||
|
||||
if (flags & XFF_ARGUMENT) {
|
||||
/*
|
||||
* Argument flag means the content isn't given in the descriptor,
|
||||
* but as a UTF-8 string ('const char *') argument in xo_vap.
|
||||
*/
|
||||
content = va_arg(xop->xo_vap, char *);
|
||||
clen = content ? strlen(content) : 0;
|
||||
}
|
||||
|
||||
if (ftype == XO_ROLE_NEWLINE) {
|
||||
xo_line_close(xop);
|
||||
if (flush_line && xo_flush_h(xop) < 0)
|
||||
@ -5773,15 +6021,15 @@ xo_do_emit (xo_handle_t *xop, const char *fmt)
|
||||
}
|
||||
|
||||
if (ftype == 'V')
|
||||
xo_format_value(xop, xfip->xfi_content, xfip->xfi_clen,
|
||||
xo_format_value(xop, content, clen,
|
||||
xfip->xfi_format, xfip->xfi_flen,
|
||||
xfip->xfi_encoding, xfip->xfi_elen, flags);
|
||||
else if (ftype == '[')
|
||||
xo_anchor_start(xop, xfip);
|
||||
xo_anchor_start(xop, xfip, content, clen);
|
||||
else if (ftype == ']')
|
||||
xo_anchor_stop(xop, xfip);
|
||||
xo_anchor_stop(xop, xfip, content, clen);
|
||||
else if (ftype == 'C')
|
||||
xo_format_colors(xop, xfip);
|
||||
xo_format_colors(xop, xfip, content, clen);
|
||||
|
||||
else if (ftype == 'G') {
|
||||
/*
|
||||
@ -5792,7 +6040,7 @@ xo_do_emit (xo_handle_t *xop, const char *fmt)
|
||||
* Since gettext returns strings in a static buffer, we make
|
||||
* a copy in new_fmt.
|
||||
*/
|
||||
xo_set_gettext_domain(xop, xfip);
|
||||
xo_set_gettext_domain(xop, xfip, content, clen);
|
||||
|
||||
if (!gettext_inuse) { /* Only translate once */
|
||||
gettext_inuse = 1;
|
||||
@ -5843,17 +6091,17 @@ xo_do_emit (xo_handle_t *xop, const char *fmt)
|
||||
}
|
||||
continue;
|
||||
|
||||
} else if (xfip->xfi_clen || xfip->xfi_format) {
|
||||
} else if (clen || xfip->xfi_format) {
|
||||
|
||||
const char *class_name = xo_class_name(ftype);
|
||||
if (class_name)
|
||||
xo_format_content(xop, class_name, xo_tag_name(ftype),
|
||||
xfip->xfi_content, xfip->xfi_clen,
|
||||
content, clen,
|
||||
xfip->xfi_format, xfip->xfi_flen, flags);
|
||||
else if (ftype == 'T')
|
||||
xo_format_title(xop, xfip);
|
||||
xo_format_title(xop, xfip, content, clen);
|
||||
else if (ftype == 'U')
|
||||
xo_format_units(xop, xfip);
|
||||
xo_format_units(xop, xfip, content, clen);
|
||||
else
|
||||
xo_failure(xop, "unknown field type: '%c'", ftype);
|
||||
}
|
||||
@ -5884,7 +6132,7 @@ xo_do_emit (xo_handle_t *xop, const char *fmt)
|
||||
if (flush && !XOIF_ISSET(xop, XOIF_ANCHOR)) {
|
||||
if (xo_write(xop) < 0)
|
||||
rc = -1; /* Report failure */
|
||||
else if (xop->xo_flush && xop->xo_flush(xop->xo_opaque) < 0)
|
||||
else if (xo_flush_h(xop) < 0)
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
@ -5904,6 +6152,53 @@ xo_do_emit (xo_handle_t *xop, const char *fmt)
|
||||
return (rc < 0) ? rc : (int) xop->xo_columns;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse and emit a set of fields
|
||||
*/
|
||||
static int
|
||||
xo_do_emit (xo_handle_t *xop, xo_emit_flags_t flags, const char *fmt)
|
||||
{
|
||||
xop->xo_columns = 0; /* Always reset it */
|
||||
xop->xo_errno = errno; /* Save for "%m" */
|
||||
|
||||
if (fmt == NULL)
|
||||
return 0;
|
||||
|
||||
unsigned max_fields;
|
||||
xo_field_info_t *fields = NULL;
|
||||
|
||||
/* Adjust XOEF_RETAIN based on global flags */
|
||||
if (XOF_ISSET(xop, XOF_RETAIN_ALL))
|
||||
flags |= XOEF_RETAIN;
|
||||
if (XOF_ISSET(xop, XOF_RETAIN_NONE))
|
||||
flags &= ~XOEF_RETAIN;
|
||||
|
||||
/*
|
||||
* Check for 'retain' flag, telling us to retain the field
|
||||
* information. If we've already saved it, then we can avoid
|
||||
* re-parsing the format string.
|
||||
*/
|
||||
if (!(flags & XOEF_RETAIN)
|
||||
|| xo_retain_find(fmt, &fields, &max_fields) != 0
|
||||
|| fields == NULL) {
|
||||
|
||||
/* Nothing retained; parse the format string */
|
||||
max_fields = xo_count_fields(xop, fmt);
|
||||
fields = alloca(max_fields * sizeof(fields[0]));
|
||||
bzero(fields, max_fields * sizeof(fields[0]));
|
||||
|
||||
if (xo_parse_fields(xop, fields, max_fields, fmt))
|
||||
return -1; /* Warning already displayed */
|
||||
|
||||
if (flags & XOEF_RETAIN) {
|
||||
/* Retain the info */
|
||||
xo_retain_add(fmt, fields, max_fields);
|
||||
}
|
||||
}
|
||||
|
||||
return xo_do_emit_fields(xop, fields, max_fields, fmt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Rebuild a format string in a gettext-friendly format. This function
|
||||
* is exposed to tools can perform this function. See xo(1).
|
||||
@ -5944,7 +6239,7 @@ xo_emit_hv (xo_handle_t *xop, const char *fmt, va_list vap)
|
||||
|
||||
xop = xo_default(xop);
|
||||
va_copy(xop->xo_vap, vap);
|
||||
rc = xo_do_emit(xop, fmt);
|
||||
rc = xo_do_emit(xop, 0, fmt);
|
||||
va_end(xop->xo_vap);
|
||||
bzero(&xop->xo_vap, sizeof(xop->xo_vap));
|
||||
|
||||
@ -5958,7 +6253,7 @@ xo_emit_h (xo_handle_t *xop, const char *fmt, ...)
|
||||
|
||||
xop = xo_default(xop);
|
||||
va_start(xop->xo_vap, fmt);
|
||||
rc = xo_do_emit(xop, fmt);
|
||||
rc = xo_do_emit(xop, 0, fmt);
|
||||
va_end(xop->xo_vap);
|
||||
bzero(&xop->xo_vap, sizeof(xop->xo_vap));
|
||||
|
||||
@ -5972,13 +6267,137 @@ xo_emit (const char *fmt, ...)
|
||||
int rc;
|
||||
|
||||
va_start(xop->xo_vap, fmt);
|
||||
rc = xo_do_emit(xop, fmt);
|
||||
rc = xo_do_emit(xop, 0, fmt);
|
||||
va_end(xop->xo_vap);
|
||||
bzero(&xop->xo_vap, sizeof(xop->xo_vap));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
xo_emit_hvf (xo_handle_t *xop, xo_emit_flags_t flags,
|
||||
const char *fmt, va_list vap)
|
||||
{
|
||||
int rc;
|
||||
|
||||
xop = xo_default(xop);
|
||||
va_copy(xop->xo_vap, vap);
|
||||
rc = xo_do_emit(xop, flags, fmt);
|
||||
va_end(xop->xo_vap);
|
||||
bzero(&xop->xo_vap, sizeof(xop->xo_vap));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
xo_emit_hf (xo_handle_t *xop, xo_emit_flags_t flags, const char *fmt, ...)
|
||||
{
|
||||
int rc;
|
||||
|
||||
xop = xo_default(xop);
|
||||
va_start(xop->xo_vap, fmt);
|
||||
rc = xo_do_emit(xop, flags, fmt);
|
||||
va_end(xop->xo_vap);
|
||||
bzero(&xop->xo_vap, sizeof(xop->xo_vap));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
xo_emit_f (xo_emit_flags_t flags, const char *fmt, ...)
|
||||
{
|
||||
xo_handle_t *xop = xo_default(NULL);
|
||||
int rc;
|
||||
|
||||
va_start(xop->xo_vap, fmt);
|
||||
rc = xo_do_emit(xop, flags, fmt);
|
||||
va_end(xop->xo_vap);
|
||||
bzero(&xop->xo_vap, sizeof(xop->xo_vap));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Emit a single field by providing the info information typically provided
|
||||
* inside the field description (role, modifiers, and formats). This is
|
||||
* a convenience function to avoid callers using snprintf to build field
|
||||
* descriptions.
|
||||
*/
|
||||
int
|
||||
xo_emit_field_hv (xo_handle_t *xop, const char *rolmod, const char *contents,
|
||||
const char *fmt, const char *efmt,
|
||||
va_list vap)
|
||||
{
|
||||
int rc;
|
||||
|
||||
xop = xo_default(xop);
|
||||
|
||||
if (rolmod == NULL)
|
||||
rolmod = "V";
|
||||
|
||||
xo_field_info_t xfi;
|
||||
|
||||
bzero(&xfi, sizeof(xfi));
|
||||
|
||||
const char *cp;
|
||||
cp = xo_parse_roles(xop, rolmod, rolmod, &xfi);
|
||||
if (cp == NULL)
|
||||
return -1;
|
||||
|
||||
xfi.xfi_start = fmt;
|
||||
xfi.xfi_content = contents;
|
||||
xfi.xfi_format = fmt;
|
||||
xfi.xfi_encoding = efmt;
|
||||
xfi.xfi_clen = contents ? strlen(contents) : 0;
|
||||
xfi.xfi_flen = fmt ? strlen(fmt) : 0;
|
||||
xfi.xfi_elen = efmt ? strlen(efmt) : 0;
|
||||
|
||||
/* If we have content, then we have a default format */
|
||||
if (contents && fmt == NULL
|
||||
&& xo_role_wants_default_format(xfi.xfi_ftype)) {
|
||||
xfi.xfi_format = xo_default_format;
|
||||
xfi.xfi_flen = 2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
va_copy(xop->xo_vap, vap);
|
||||
|
||||
rc = xo_do_emit_fields(xop, &xfi, 1, fmt ?: contents ?: "field");
|
||||
|
||||
va_end(xop->xo_vap);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
xo_emit_field_h (xo_handle_t *xop, const char *rolmod, const char *contents,
|
||||
const char *fmt, const char *efmt, ...)
|
||||
{
|
||||
int rc;
|
||||
va_list vap;
|
||||
|
||||
va_start(vap, efmt);
|
||||
rc = xo_emit_field_hv(xop, rolmod, contents, fmt, efmt, vap);
|
||||
va_end(vap);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
xo_emit_field (const char *rolmod, const char *contents,
|
||||
const char *fmt, const char *efmt, ...)
|
||||
{
|
||||
int rc;
|
||||
va_list vap;
|
||||
|
||||
va_start(vap, efmt);
|
||||
rc = xo_emit_field_hv(NULL, rolmod, contents, fmt, efmt, vap);
|
||||
va_end(vap);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
xo_attr_hv (xo_handle_t *xop, const char *name, const char *fmt, va_list vap)
|
||||
{
|
||||
@ -6392,7 +6811,7 @@ xo_open_list_hf (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name)
|
||||
}
|
||||
|
||||
int
|
||||
xo_open_list_h (xo_handle_t *xop, const char *name UNUSED)
|
||||
xo_open_list_h (xo_handle_t *xop, const char *name)
|
||||
{
|
||||
return xo_open_list_hf(xop, 0, name);
|
||||
}
|
||||
@ -6404,7 +6823,7 @@ xo_open_list (const char *name)
|
||||
}
|
||||
|
||||
int
|
||||
xo_open_list_hd (xo_handle_t *xop, const char *name UNUSED)
|
||||
xo_open_list_hd (xo_handle_t *xop, const char *name)
|
||||
{
|
||||
return xo_open_list_hf(xop, XOF_DTRT, name);
|
||||
}
|
||||
@ -7113,6 +7532,11 @@ xo_transition (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name,
|
||||
xsp->xs_state, new_state);
|
||||
}
|
||||
|
||||
/* Handle the flush flag */
|
||||
if (rc >= 0 && XOF_ISSET(xop, XOF_FLUSH))
|
||||
if (xo_flush_h(xop))
|
||||
rc = -1;
|
||||
|
||||
return rc;
|
||||
|
||||
marker_prevents_close:
|
||||
@ -7179,22 +7603,11 @@ xo_set_allocator (xo_realloc_func_t realloc_func, xo_free_func_t free_func)
|
||||
int
|
||||
xo_flush_h (xo_handle_t *xop)
|
||||
{
|
||||
static char div_close[] = "</div>";
|
||||
int rc;
|
||||
|
||||
xop = xo_default(xop);
|
||||
|
||||
switch (xo_style(xop)) {
|
||||
case XO_STYLE_HTML:
|
||||
if (XOIF_ISSET(xop, XOIF_DIV_OPEN)) {
|
||||
XOIF_CLEAR(xop, XOIF_DIV_OPEN);
|
||||
xo_data_append(xop, div_close, sizeof(div_close) - 1);
|
||||
|
||||
if (XOF_ISSET(xop, XOF_PRETTY))
|
||||
xo_data_append(xop, "\n", 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case XO_STYLE_ENCODER:
|
||||
xo_encoder_handle(xop, XO_OP_FLUSH, NULL, NULL);
|
||||
}
|
||||
@ -7435,7 +7848,7 @@ xo_set_program (const char *name)
|
||||
}
|
||||
|
||||
void
|
||||
xo_set_version_h (xo_handle_t *xop, const char *version UNUSED)
|
||||
xo_set_version_h (xo_handle_t *xop, const char *version)
|
||||
{
|
||||
xop = xo_default(xop);
|
||||
|
||||
|
@ -94,6 +94,11 @@ typedef unsigned long long xo_xof_flags_t;
|
||||
|
||||
#define XOF_LOG_GETTEXT XOF_BIT(28) /** Log (stderr) gettext lookup strings */
|
||||
#define XOF_UTF8 XOF_BIT(29) /** Force text output to be UTF8 */
|
||||
#define XOF_RETAIN_ALL XOF_BIT(30) /** Force use of XOEF_RETAIN */
|
||||
#define XOF_RETAIN_NONE XOF_BIT(31) /** Prevent use of XOEF_RETAIN */
|
||||
|
||||
typedef unsigned xo_emit_flags_t; /* Flags to xo_emit() and friends */
|
||||
#define XOEF_RETAIN (1<<0) /* Retain parsed formatting information */
|
||||
|
||||
/*
|
||||
* The xo_info_t structure provides a mapping between names and
|
||||
@ -162,6 +167,12 @@ xo_set_flags (xo_handle_t *xop, xo_xof_flags_t flags);
|
||||
void
|
||||
xo_clear_flags (xo_handle_t *xop, xo_xof_flags_t flags);
|
||||
|
||||
int
|
||||
xo_set_file_h (xo_handle_t *xop, FILE *fp);
|
||||
|
||||
int
|
||||
xo_set_file (FILE *fp);
|
||||
|
||||
void
|
||||
xo_set_info (xo_handle_t *xop, xo_info_t *infop, int count);
|
||||
|
||||
@ -180,6 +191,16 @@ xo_emit_h (xo_handle_t *xop, const char *fmt, ...);
|
||||
int
|
||||
xo_emit (const char *fmt, ...);
|
||||
|
||||
int
|
||||
xo_emit_hvf (xo_handle_t *xop, xo_emit_flags_t flags,
|
||||
const char *fmt, va_list vap);
|
||||
|
||||
int
|
||||
xo_emit_hf (xo_handle_t *xop, xo_emit_flags_t flags, const char *fmt, ...);
|
||||
|
||||
int
|
||||
xo_emit_f (xo_emit_flags_t flags, const char *fmt, ...);
|
||||
|
||||
PRINTFLIKE(2, 0)
|
||||
static inline int
|
||||
xo_emit_hvp (xo_handle_t *xop, const char *fmt, va_list vap)
|
||||
@ -209,6 +230,36 @@ xo_emit_p (const char *fmt, ...)
|
||||
return rc;
|
||||
}
|
||||
|
||||
PRINTFLIKE(3, 0)
|
||||
static inline int
|
||||
xo_emit_hvfp (xo_handle_t *xop, xo_emit_flags_t flags,
|
||||
const char *fmt, va_list vap)
|
||||
{
|
||||
return xo_emit_hvf(xop, flags, fmt, vap);
|
||||
}
|
||||
|
||||
PRINTFLIKE(3, 4)
|
||||
static inline int
|
||||
xo_emit_hfp (xo_handle_t *xop, xo_emit_flags_t flags, const char *fmt, ...)
|
||||
{
|
||||
va_list vap;
|
||||
va_start(vap, fmt);
|
||||
int rc = xo_emit_hvf(xop, flags, fmt, vap);
|
||||
va_end(vap);
|
||||
return rc;
|
||||
}
|
||||
|
||||
PRINTFLIKE(2, 3)
|
||||
static inline int
|
||||
xo_emit_fp (xo_emit_flags_t flags, const char *fmt, ...)
|
||||
{
|
||||
va_list vap;
|
||||
va_start(vap, fmt);
|
||||
int rc = xo_emit_hvf(NULL, flags, fmt, vap);
|
||||
va_end(vap);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
xo_open_container_h (xo_handle_t *xop, const char *name);
|
||||
|
||||
@ -593,4 +644,23 @@ char *
|
||||
xo_simplify_format (xo_handle_t *xop, const char *fmt, int with_numbers,
|
||||
xo_simplify_field_func_t field_cb);
|
||||
|
||||
int
|
||||
xo_emit_field_hv (xo_handle_t *xop, const char *rolmod, const char *contents,
|
||||
const char *fmt, const char *efmt,
|
||||
va_list vap);
|
||||
|
||||
int
|
||||
xo_emit_field_h (xo_handle_t *xop, const char *rolmod, const char *contents,
|
||||
const char *fmt, const char *efmt, ...);
|
||||
|
||||
int
|
||||
xo_emit_field (const char *rolmod, const char *contents,
|
||||
const char *fmt, const char *efmt, ...);
|
||||
|
||||
void
|
||||
xo_retain_clear_all (void);
|
||||
|
||||
void
|
||||
xo_retain_clear (const char *fmt);
|
||||
|
||||
#endif /* INCLUDE_XO_H */
|
||||
|
@ -1,246 +0,0 @@
|
||||
/* libxo/xo_config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
|
||||
systems. This function is required for `alloca.c' support on those systems.
|
||||
*/
|
||||
#undef CRAY_STACKSEG_END
|
||||
|
||||
/* Define to 1 if using `alloca.c'. */
|
||||
#undef C_ALLOCA
|
||||
|
||||
/* Define to 1 if you have `alloca', as a function or macro. */
|
||||
#undef HAVE_ALLOCA
|
||||
|
||||
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
|
||||
*/
|
||||
#undef HAVE_ALLOCA_H
|
||||
|
||||
/* Define to 1 if you have the `asprintf' function. */
|
||||
#undef HAVE_ASPRINTF
|
||||
|
||||
/* Define to 1 if you have the `bzero' function. */
|
||||
#undef HAVE_BZERO
|
||||
|
||||
/* Define to 1 if you have the `ctime' function. */
|
||||
#undef HAVE_CTIME
|
||||
|
||||
/* Define to 1 if you have the <ctype.h> header file. */
|
||||
#undef HAVE_CTYPE_H
|
||||
|
||||
/* Define to 1 if you have the declaration of `__isthreaded', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL___ISTHREADED
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define to 1 if you have the `dlfunc' function. */
|
||||
#undef HAVE_DLFUNC
|
||||
|
||||
/* Define to 1 if you have the <errno.h> header file. */
|
||||
#undef HAVE_ERRNO_H
|
||||
|
||||
/* Define to 1 if you have the `fdopen' function. */
|
||||
#undef HAVE_FDOPEN
|
||||
|
||||
/* Define to 1 if you have the `flock' function. */
|
||||
#undef HAVE_FLOCK
|
||||
|
||||
/* Define to 1 if you have the `getpass' function. */
|
||||
#undef HAVE_GETPASS
|
||||
|
||||
/* Define to 1 if you have the `getprogname' function. */
|
||||
#undef HAVE_GETPROGNAME
|
||||
|
||||
/* Define to 1 if you have the `getrusage' function. */
|
||||
#undef HAVE_GETRUSAGE
|
||||
|
||||
/* gettext(3) */
|
||||
#undef HAVE_GETTEXT
|
||||
|
||||
/* Define to 1 if you have the `gettimeofday' function. */
|
||||
#undef HAVE_GETTIMEOFDAY
|
||||
|
||||
/* humanize_number(3) */
|
||||
#undef HAVE_HUMANIZE_NUMBER
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the `crypto' library (-lcrypto). */
|
||||
#undef HAVE_LIBCRYPTO
|
||||
|
||||
/* Define to 1 if you have the `m' library (-lm). */
|
||||
#undef HAVE_LIBM
|
||||
|
||||
/* Define to 1 if you have the <libutil.h> header file. */
|
||||
#undef HAVE_LIBUTIL_H
|
||||
|
||||
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
|
||||
to 0 otherwise. */
|
||||
#undef HAVE_MALLOC
|
||||
|
||||
/* Define to 1 if you have the `memmove' function. */
|
||||
#undef HAVE_MEMMOVE
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Support printflike */
|
||||
#undef HAVE_PRINTFLIKE
|
||||
|
||||
/* Define to 1 if your system has a GNU libc compatible `realloc' function,
|
||||
and to 0 otherwise. */
|
||||
#undef HAVE_REALLOC
|
||||
|
||||
/* Define to 1 if you have the `srand' function. */
|
||||
#undef HAVE_SRAND
|
||||
|
||||
/* Define to 1 if you have the `sranddev' function. */
|
||||
#undef HAVE_SRANDDEV
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdio_ext.h> header file. */
|
||||
#undef HAVE_STDIO_EXT_H
|
||||
|
||||
/* Define to 1 if you have the <stdio.h> header file. */
|
||||
#undef HAVE_STDIO_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the <stdtime/tzfile.h> header file. */
|
||||
#undef HAVE_STDTIME_TZFILE_H
|
||||
|
||||
/* Define to 1 if you have the `strchr' function. */
|
||||
#undef HAVE_STRCHR
|
||||
|
||||
/* Define to 1 if you have the `strcspn' function. */
|
||||
#undef HAVE_STRCSPN
|
||||
|
||||
/* Define to 1 if you have the `strerror' function. */
|
||||
#undef HAVE_STRERROR
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the `strlcpy' function. */
|
||||
#undef HAVE_STRLCPY
|
||||
|
||||
/* Define to 1 if you have the `strspn' function. */
|
||||
#undef HAVE_STRSPN
|
||||
|
||||
/* Have struct sockaddr_un.sun_len */
|
||||
#undef HAVE_SUN_LEN
|
||||
|
||||
/* Define to 1 if you have the `sysctlbyname' function. */
|
||||
#undef HAVE_SYSCTLBYNAME
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/sysctl.h> header file. */
|
||||
#undef HAVE_SYS_SYSCTL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#undef HAVE_SYS_TIME_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <threads.h> header file. */
|
||||
#undef HAVE_THREADS_H
|
||||
|
||||
/* thread-local setting */
|
||||
#undef HAVE_THREAD_LOCAL
|
||||
|
||||
/* Define to 1 if you have the <tzfile.h> header file. */
|
||||
#undef HAVE_TZFILE_H
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to 1 if you have the `__flbf' function. */
|
||||
#undef HAVE___FLBF
|
||||
|
||||
/* Enable debugging */
|
||||
#undef LIBXO_DEBUG
|
||||
|
||||
/* Enable text-only rendering */
|
||||
#undef LIBXO_TEXT_ONLY
|
||||
|
||||
/* Version number as dotted value */
|
||||
#undef LIBXO_VERSION
|
||||
|
||||
/* Version number extra information */
|
||||
#undef LIBXO_VERSION_EXTRA
|
||||
|
||||
/* Version number as a number */
|
||||
#undef LIBXO_VERSION_NUMBER
|
||||
|
||||
/* Version number as string */
|
||||
#undef LIBXO_VERSION_STRING
|
||||
|
||||
/* Enable local wcwidth implementation */
|
||||
#undef LIBXO_WCWIDTH
|
||||
|
||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||
#undef LT_OBJDIR
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#undef PACKAGE_URL
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* If using the C implementation of alloca, define if you know the
|
||||
direction of stack growth for your system; otherwise it will be
|
||||
automatically deduced at runtime.
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||
#undef STACK_DIRECTION
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
#undef inline
|
||||
#endif
|
||||
|
||||
/* Define to rpl_malloc if the replacement function should be used. */
|
||||
#undef malloc
|
||||
|
||||
/* Define to rpl_realloc if the replacement function should be used. */
|
||||
#undef realloc
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
#undef size_t
|
111
contrib/libxo/libxo/xo_emit_f.3
Normal file
111
contrib/libxo/libxo/xo_emit_f.3
Normal file
@ -0,0 +1,111 @@
|
||||
.\" #
|
||||
.\" # Copyright (c) 2016, Juniper Networks, Inc.
|
||||
.\" # All rights reserved.
|
||||
.\" # This SOFTWARE is licensed under the LICENSE provided in the
|
||||
.\" # ../Copyright file. By downloading, installing, copying, or
|
||||
.\" # using the SOFTWARE, you agree to be bound by the terms of that
|
||||
.\" # LICENSE.
|
||||
.\" # Phil Shafer, April 2016
|
||||
.\"
|
||||
.Dd April 15, 2016
|
||||
.Dt LIBXO 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm xo_emit_f , xo_emit_hf , xo_emit_hvf
|
||||
.Nd emit formatted output based on format string and arguments
|
||||
.Sh LIBRARY
|
||||
.Lb libxo
|
||||
.Sh SYNOPSIS
|
||||
.In libxo/xo.h
|
||||
.Ft int
|
||||
.Fn xo_emit_f "xo_emit_flags_t flags" "const char *fmt" "..."
|
||||
.Ft int
|
||||
.Fn xo_emit_hf "xo_handle_t *xop" "xo_emit_flags_t flags" "const char *fmt" "..."
|
||||
.Ft int
|
||||
.Fn xo_emit_hvf "xo_handle_t *xop" "xo_emit_flags_t flags" "const char *fmt" "va_list vap"
|
||||
.Ft void
|
||||
.Fn xo_retain_clear_all "void"
|
||||
.Ft void
|
||||
.Fn xo_retain_clear "const char *fmt"
|
||||
.Sh DESCRIPTION
|
||||
These functions allow callers to pass a set of flags to
|
||||
.Nm
|
||||
emitting functions. These processing of arguments, except for
|
||||
.Fa flags ,
|
||||
is identical to the base functions.
|
||||
See
|
||||
.Xr xo_emit 3
|
||||
for additional information.
|
||||
.Pp
|
||||
The only currently defined flag is
|
||||
.Dv XOEF_RETAIN .
|
||||
.Nm
|
||||
can retain the parsed internal information related to the given
|
||||
format string, allowing subsequent
|
||||
.Xr xo_emit 3
|
||||
calls, the retained
|
||||
information is used, avoiding repetitive parsing of the format string.
|
||||
To retain parsed format information, use the
|
||||
.Dv XOEF_RETAIN
|
||||
flag to the
|
||||
.Fn xo_emit_f
|
||||
function.
|
||||
.Pp
|
||||
The format string must be immutable across multiple calls to
|
||||
.Xn xo_emit_f ,
|
||||
since the library retains the string.
|
||||
Typically this is done by using
|
||||
static constant strings, such as string literals. If the string is not
|
||||
immutable, the
|
||||
.Dv XOEF_RETAIN
|
||||
flag must not be used.
|
||||
.Pp
|
||||
The functions
|
||||
.Fn xo_retain_clear
|
||||
and
|
||||
.Fn xo_retain_clear_all
|
||||
release internal information on either a single format string or all
|
||||
format strings, respectively.
|
||||
Neither is required, but the library will
|
||||
retain this information until it is cleared or the process exits.
|
||||
.Pp
|
||||
The retained information is kept as thread-specific data.
|
||||
.Pp
|
||||
Use
|
||||
.Fn xo_retain_clear
|
||||
and
|
||||
.Fn xo_retain_clear_all
|
||||
to clear the retained information, clearing the retained information
|
||||
for either a specific format string or all format strings, respectively.
|
||||
These functions are only needed when the calling application wants to
|
||||
clear this information; they are not generally needed.
|
||||
.Sh EXAMPLES
|
||||
.Pp
|
||||
.Bd -literal -offset indent
|
||||
for (i = 0; i < 1000; i++) {
|
||||
xo_open_instance("item");
|
||||
xo_emit_f(XOEF_RETAIN, "{:name} {:count/%d}\n",
|
||||
name[i], count[i]);
|
||||
}
|
||||
.Ed
|
||||
.Pp
|
||||
In this example, the caller desires to clear the retained information.
|
||||
.Bd -literal -offset indent
|
||||
const char *fmt = "{:name} {:count/%d}\n";
|
||||
for (i = 0; i < 1000; i++) {
|
||||
xo_open_instance("item");
|
||||
xo_emit_f(XOEF_RETAIN, fmt, name[i], count[i]);
|
||||
}
|
||||
xo_retain_clear(fmt);
|
||||
.Ed
|
||||
.Sh RETURN CODE
|
||||
The return values for these functions is identical to those of their
|
||||
traditional counterparts. See
|
||||
.Xr xo_emit 3
|
||||
for details.
|
||||
.Sh SEE ALSO
|
||||
.Xr xo_emit 3 ,
|
||||
.Xr xo_open_container 3 ,
|
||||
.Xr xo_open_list 3 ,
|
||||
.Xr xo_format 5 ,
|
||||
.Xr libxo 3
|
@ -51,14 +51,14 @@ field descriptions within the format string.
|
||||
.Pp
|
||||
The field description is given as follows:
|
||||
.Bd -literal -offset indent
|
||||
'{' [ role | modifier ]* [',' long-names ]* ':' [ content ]
|
||||
[ '/' field-format [ '/' encoding-format ]] '}'
|
||||
\(aq{\(aq [ role | modifier ]* [\(aq,\(aq long\-names ]* \(aq:\(aq [ content ]
|
||||
[ \(aq/\(aq field\-format [ \(aq/\(aq encoding\-format ]] \(aq}\(aq
|
||||
.Ed
|
||||
.Pp
|
||||
The role describes the function of the field, while the modifiers
|
||||
enable optional behaviors.
|
||||
The contents, field-format, and
|
||||
encoding-format are used in varying ways, based on the role.
|
||||
The contents, field\-format, and
|
||||
encoding\-format are used in varying ways, based on the role.
|
||||
These are described in the following sections.
|
||||
.Pp
|
||||
Braces can be escaped by using double braces, similar to "%%" in
|
||||
@ -68,26 +68,26 @@ The format string "{{braces}}" would emit "{braces}".
|
||||
In the following example, three field descriptors appear.
|
||||
The first
|
||||
is a padding field containing three spaces of padding, the second is a
|
||||
label ("In stock"), and the third is a value field ("in-stock").
|
||||
The in-stock field has a "%u" format that will parse the next argument
|
||||
label ("In stock"), and the third is a value field ("in\-stock").
|
||||
The in\-stock field has a "%u" format that will parse the next argument
|
||||
passed to the
|
||||
.Xr xo_emit 3 ,
|
||||
function as an unsigned integer.
|
||||
.Bd -literal -offset indent
|
||||
xo_emit("{P: }{Lwc:In stock}{:in-stock/%u}\\n", 65);
|
||||
xo_emit("{P: }{Lwc:In stock}{:in\-stock/%u}\\n", 65);
|
||||
.Ed
|
||||
.Pp
|
||||
This single line of code can generate text ("In stock: 65\\n"), XML
|
||||
("<in-stock>65</in-stock>"), JSON ('"in-stock": 65'), or HTML (too
|
||||
("<in\-stock>65</in\-stock>"), JSON (\(aq"in\-stock": 65\(aq), or HTML (too
|
||||
lengthy to be listed here).
|
||||
.Pp
|
||||
While roles and modifiers typically use single character for brevity,
|
||||
there are alternative names for each which allow more verbose
|
||||
formatting strings.
|
||||
These names must be preceded by a comma, and may follow any
|
||||
single-character values:
|
||||
single\-character values:
|
||||
.Bd -literal -offset indent
|
||||
xo_emit("{L,white,colon:In stock}{,key:in-stock/%u}\n", 65);
|
||||
xo_emit("{L,white,colon:In stock}{,key:in\-stock/%u}\\n", 65);
|
||||
.Ed
|
||||
.Ss "Field Roles"
|
||||
Field roles are optional, and indicate the role and formatting of the
|
||||
@ -96,7 +96,7 @@ The roles are listed below; only one role is permitted:
|
||||
.Bl -column "M" "Name12341234"
|
||||
.It Sy "M" "Name " "Description"
|
||||
.It C "color " "Field is a color or effect"
|
||||
.It D "decoration " "Field is non-text (e.g. colon, comma)"
|
||||
.It D "decoration " "Field is non\-text (e.g. colon, comma)"
|
||||
.It E "error " "Field is an error message"
|
||||
.It L "label " "Field is text that prefixes a value"
|
||||
.It N "note " "Field is text that follows a value"
|
||||
@ -105,12 +105,12 @@ The roles are listed below; only one role is permitted:
|
||||
.It U "units " "Field is the units for the previous value field"
|
||||
.It V "value " "Field is the name of field (the default)"
|
||||
.It W "warning " "Field is a warning message"
|
||||
.It \&[ "start-anchor" "Begin a section of anchored variable-width text"
|
||||
.It \&] "stop-anchor " "End a section of anchored variable-width text"
|
||||
.It \&[ "start\-anchor" "Begin a section of anchored variable\-width text"
|
||||
.It \&] "stop\-anchor " "End a section of anchored variable\-width text"
|
||||
.El
|
||||
.Bd -literal -offset indent
|
||||
EXAMPLE:
|
||||
xo_emit("{L:Free}{D::}{P: }{:free/%u} {U:Blocks}\n",
|
||||
xo_emit("{L:Free}{D::}{P: }{:free/%u} {U:Blocks}\\n",
|
||||
free_blocks);
|
||||
.Ed
|
||||
.Pp
|
||||
@ -121,50 +121,50 @@ a comma:
|
||||
.Bd -literal -offset indent
|
||||
EXAMPLE:
|
||||
xo_emit("{,label:Free}{,decoration::}{,padding: }"
|
||||
"{,value:free/%u} {,units:Blocks}\n",
|
||||
"{,value:free/%u} {,units:Blocks}\\n",
|
||||
free_blocks);
|
||||
.Ed
|
||||
.Ss "The Color Role ({C:})"
|
||||
Colors and effects control how text values are displayed; they are
|
||||
used for display styles (TEXT and HTML).
|
||||
.Bd -literal -offset indent
|
||||
xo_emit("{C:bold}{:value}{C:no-bold}\n", value);
|
||||
xo_emit("{C:bold}{:value}{C:no\-bold}\\n", value);
|
||||
.Ed
|
||||
.Pp
|
||||
Colors and effects remain in effect until modified by other "C"-role
|
||||
Colors and effects remain in effect until modified by other "C"\-role
|
||||
fields.
|
||||
.Bd -literal -offset indent
|
||||
xo_emit("{C:bold}{C:inverse}both{C:no-bold}only inverse\n");
|
||||
xo_emit("{C:bold}{C:inverse}both{C:no\-bold}only inverse\\n");
|
||||
.Ed
|
||||
.Pp
|
||||
If the content is empty, the "reset" action is performed.
|
||||
.Bd -literal -offset indent
|
||||
xo_emit("{C:both,underline}{:value}{C:}\n", value);
|
||||
xo_emit("{C:both,underline}{:value}{C:}\\n", value);
|
||||
.Ed
|
||||
.Pp
|
||||
The content should be a comma-separated list of zero or more colors or
|
||||
The content should be a comma\-separated list of zero or more colors or
|
||||
display effects.
|
||||
.Bd -literal -offset indent
|
||||
xo_emit("{C:bold,underline,inverse}All three{C:no-bold,no-inverse}\n");
|
||||
xo_emit("{C:bold,underline,inverse}All three{C:no\-bold,no\-inverse}\\n");
|
||||
.Ed
|
||||
.Pp
|
||||
The color content can be either static, when placed directly within
|
||||
the field descriptor, or a printf-style format descriptor can be used,
|
||||
the field descriptor, or a printf\-style format descriptor can be used,
|
||||
if preceded by a slash ("/"):
|
||||
.Bd -literal -offset indent
|
||||
xo_emit("{C:/%s%s}{:value}{C:}", need_bold ? "bold" : "",
|
||||
need_underline ? "underline" : "", value);
|
||||
.Ed
|
||||
.Pp
|
||||
Color names are prefixed with either "fg-" or "bg-" to change the
|
||||
Color names are prefixed with either "fg\-" or "bg\-" to change the
|
||||
foreground and background colors, respectively.
|
||||
.Bd -literal -offset indent
|
||||
xo_emit("{C:/fg-%s,bg-%s}{Lwc:Cost}{:cost/%u}{C:reset}\n",
|
||||
xo_emit("{C:/fg\-%s,bg\-%s}{Lwc:Cost}{:cost/%u}{C:reset}\\n",
|
||||
fg_color, bg_color, cost);
|
||||
.Ed
|
||||
.Pp
|
||||
The following table lists the supported effects:
|
||||
.Bl -column "no-underline"
|
||||
.Bl -column "no\-underline"
|
||||
.It Sy "Name " "Description"
|
||||
.It "bg\-xxxxx " "Change background color"
|
||||
.It "bold " "Start bold text effect"
|
||||
@ -179,7 +179,7 @@ The following table lists the supported effects:
|
||||
.El
|
||||
.Pp
|
||||
The following color names are supported:
|
||||
.Bl -column "no-underline"
|
||||
.Bl -column "no\-underline"
|
||||
.It Sy "Name"
|
||||
.It black
|
||||
.It blue
|
||||
@ -193,7 +193,7 @@ The following color names are supported:
|
||||
.El
|
||||
.Ss "The Decoration Role ({D:})"
|
||||
Decorations are typically punctuation marks such as colons,
|
||||
semi-colons, and commas used to decorate the text and make it simpler
|
||||
semi\-colons, and commas used to decorate the text and make it simpler
|
||||
for human readers.
|
||||
By marking these distinctly, HTML usage scenarios
|
||||
can use CSS to direct their display parameters.
|
||||
@ -219,22 +219,23 @@ change such as changing "/%06d" to "/%08d" should not force hand
|
||||
inspection of all .po files.
|
||||
.Pp
|
||||
The simplified version can be generated for a single message using the
|
||||
"xopo -s <text>" command, or an entire .pot can be translated using
|
||||
the "xopo -f <input> -o <output>" command.
|
||||
"xopo \-s <text>" command, or an entire .pot can be translated using
|
||||
the "xopo \-f <input> \-o <output>" command.
|
||||
.Bd -literal -offset indent
|
||||
xo_emit("{G:}Invalid token\n");
|
||||
xo_emit("{G:}Invalid token\\n");
|
||||
.Ed
|
||||
.Pp
|
||||
The {G:} role allows a domain name to be set.
|
||||
.Fn gettext
|
||||
calls will
|
||||
continue to use that domain name until the current format string
|
||||
processing is complete, enabling a library function to emit strings
|
||||
using it's own catalog.
|
||||
using it\(aqs own catalog.
|
||||
The domain name can be either static as the
|
||||
content of the field, or a format can be used to get the domain name
|
||||
from the arguments.
|
||||
.Bd -literal -offset indent
|
||||
xo_emit("{G:libc}Service unavailable in restricted mode\n");
|
||||
xo_emit("{G:libc}Service unavailable in restricted mode\\n");
|
||||
.Ed
|
||||
.Ss "The Label Role ({L:})"
|
||||
Labels are text that appears before a value.
|
||||
@ -249,7 +250,7 @@ Notes are text that appears after a value.
|
||||
.Ss "The Padding Role ({P:})"
|
||||
Padding represents whitespace used before and between fields.
|
||||
The padding content can be either static, when placed directly within
|
||||
the field descriptor, or a printf-style format descriptor can be used,
|
||||
the field descriptor, or a printf\-style format descriptor can be used,
|
||||
if preceded by a slash ("/"):
|
||||
.Bd -literal -offset indent
|
||||
xo_emit("{P: }{Lwc:Cost}{:cost/%u}\\n", cost);
|
||||
@ -259,7 +260,7 @@ if preceded by a slash ("/"):
|
||||
Titles are heading or column headers that are meant to be displayed to
|
||||
the user.
|
||||
The title can be either static, when placed directly within
|
||||
the field descriptor, or a printf-style format descriptor can be used,
|
||||
the field descriptor, or a printf\-style format descriptor can be used,
|
||||
if preceded by a slash ("/"):
|
||||
.Bd -literal -offset indent
|
||||
xo_emit("{T:Interface Statistics}\\n");
|
||||
@ -274,7 +275,7 @@ for the previous value field.
|
||||
xo_emit("{Lwc:Distance}{:distance/%u}{Uw:miles}\\n", miles);
|
||||
.Ed
|
||||
.Pp
|
||||
Note that the sense of the 'w' modifier is reversed for units;
|
||||
Note that the sense of the \(aqw\(aq modifier is reversed for units;
|
||||
a blank is added before the contents, rather than after it.
|
||||
.Pp
|
||||
When the
|
||||
@ -286,14 +287,14 @@ attribute:
|
||||
<distance units="miles">50</distance>
|
||||
.Ed
|
||||
.Pp
|
||||
Units can also be rendered in HTML as the "data-units" attribute:
|
||||
Units can also be rendered in HTML as the "data\-units" attribute:
|
||||
.Bd -literal -offset indent
|
||||
<div class="data" data-tag="distance" data-units="miles"
|
||||
data-xpath="/top/data/distance">50</div>
|
||||
<div class="data" data\-tag="distance" data\-units="miles"
|
||||
data\-xpath="/top/data/distance">50</div>
|
||||
.Ed
|
||||
.Ss "The Value Role ({V:} and {:})"
|
||||
The value role is used to represent the a data value that is
|
||||
interesting for the non-display output styles (XML and JSON).
|
||||
interesting for the non\-display output styles (XML and JSON).
|
||||
Value
|
||||
is the default role; if no other role designation is given, the field
|
||||
is a value.
|
||||
@ -356,16 +357,17 @@ Field modifiers are flags which modify the way content emitted for
|
||||
particular output styles:
|
||||
.Bl -column M "Name123456789"
|
||||
.It Sy M "Name " "Description"
|
||||
.It a "argument " "The content appears as a ""const char *"" argument"
|
||||
.It c "colon " "A colon ("":"") is appended after the label"
|
||||
.It d "display " "Only emit field for display styles (text/HTML)"
|
||||
.It e "encoding " "Only emit for encoding styles (XML/JSON)"
|
||||
.It h "humanize (hn) " "Format large numbers in human-readable style"
|
||||
.It " " "hn-space " "Humanize: Place space between numeric and unit"
|
||||
.It " " "hn-decimal " "Humanize: Add a decimal digit, if number < 10"
|
||||
.It " " "hn-1000 " "Humanize: Use 1000 as divisor instead of 1024"
|
||||
.It h "humanize (hn) " "Format large numbers in human\-readable style"
|
||||
.It " " "hn\-space " "Humanize: Place space between numeric and unit"
|
||||
.It " " "hn\-decimal " "Humanize: Add a decimal digit, if number < 10"
|
||||
.It " " "hn\-1000 " "Humanize: Use 1000 as divisor instead of 1024"
|
||||
.It k "key " "Field is a key, suitable for XPath predicates"
|
||||
.It l "leaf-list " "Field is a leaf-list, a list of leaf values"
|
||||
.It n "no-quotes " "Do not quote the field when using JSON style"
|
||||
.It l "leaf\-list " "Field is a leaf\-list, a list of leaf values"
|
||||
.It n "no\-quotes " "Do not quote the field when using JSON style"
|
||||
.It q "quotes " "Quote the field when using JSON style"
|
||||
.It t "trim " "Trim leading and trailing whitespace"
|
||||
.It w "white space " "A blank ("" "") is appended after the label"
|
||||
@ -373,7 +375,7 @@ particular output styles:
|
||||
.Pp
|
||||
For example, the modifier string "Lwc" means the field has a label
|
||||
role (text that describes the next field) and should be followed by a
|
||||
colon ('c') and a space ('w').
|
||||
colon (\(aqc\(aq) and a space (\(aqw\(aq).
|
||||
The modifier string "Vkq" means the
|
||||
field has a value role, that it is a key for the current instance, and
|
||||
that the value should be quoted when encoded for JSON.
|
||||
@ -382,10 +384,31 @@ Roles and modifiers can also use more verbose names, when preceeded by
|
||||
a comma.
|
||||
For example, the modifier string "Lwc" (or "L,white,colon")
|
||||
means the field has a label role (text that describes the next field)
|
||||
and should be followed by a colon ('c') and a space ('w').
|
||||
and should be followed by a colon (\(aqc\(aq) and a space (\(aqw\(aq).
|
||||
The modifier string "Vkq" (or ":key,quote") means the field has a value
|
||||
role (the default role), that it is a key for the current instance,
|
||||
and that the value should be quoted when encoded for JSON.
|
||||
.Ss "The Argument Modifier ({a:})"
|
||||
The argument modifier indicates that the content of the field
|
||||
descriptor will be placed as a UTF\-8 string (const char *) argument
|
||||
within the xo_emit parameters.
|
||||
.Bd -literal -offset indent
|
||||
EXAMPLE:
|
||||
xo_emit("{La:} {a:}\\n", "Label text", "label", "value");
|
||||
TEXT:
|
||||
Label text value
|
||||
JSON:
|
||||
"label": "value"
|
||||
XML:
|
||||
<label>value</label>
|
||||
.Ed
|
||||
.Pp
|
||||
The argument modifier allows field names for value fields to be passed
|
||||
on the stack, avoiding the need to build a field descriptor using
|
||||
.Xr snprintf 1 .
|
||||
For many field roles, the argument modifier is not needed,
|
||||
since those roles have specific mechanisms for arguments,
|
||||
such as "{C:fg\-%s}".
|
||||
.Ss "The Colon Modifier ({c:})"
|
||||
The colon modifier appends a single colon to the data value:
|
||||
.Bd -literal -offset indent
|
||||
@ -397,7 +420,7 @@ The colon modifier appends a single colon to the data value:
|
||||
.Pp
|
||||
The colon modifier is only used for the TEXT and HTML output
|
||||
styles.
|
||||
It is commonly combined with the space modifier ('{w:}').
|
||||
It is commonly combined with the space modifier (\(aq{w:}\(aq).
|
||||
It is purely a convenience feature.
|
||||
.Ss "The Display Modifier ({d:})"
|
||||
The display modifier indicated the field should only be generated for
|
||||
@ -429,39 +452,39 @@ The encoding modifier is the opposite of the display modifier, and
|
||||
they are often used to give to distinct views of the underlying data.
|
||||
.Ss "The Humanize Modifier ({h:})"
|
||||
The humanize modifier is used to render large numbers as in a
|
||||
human-readable format.
|
||||
human\-readable format.
|
||||
While numbers like "44470272" are completely readable to computers and
|
||||
savants, humans will generally find "44M" more meaningful.
|
||||
.Pp
|
||||
"hn" can be used as an alias for "humanize".
|
||||
.Pp
|
||||
The humanize modifier only affects display styles (TEXT and HMTL).
|
||||
The "no-humanize" option will block the function of the humanize modifier.
|
||||
The "no\-humanize" option will block the function of the humanize modifier.
|
||||
.Pp
|
||||
There are a number of modifiers that affect details of humanization.
|
||||
These are only available in as full names, not single characters.
|
||||
The "hn-space" modifier places a space between the number and any
|
||||
The "hn\-space" modifier places a space between the number and any
|
||||
multiplier symbol, such as "M" or "K" (ex: "44 K").
|
||||
The "hn-decimal" modifier will add a decimal point and a single tenths digit
|
||||
The "hn\-decimal" modifier will add a decimal point and a single tenths digit
|
||||
when the number is less than 10 (ex: "4.4K").
|
||||
The "hn-1000" modifier will use 1000 as divisor instead of 1024, following the
|
||||
JEDEC-standard instead of the more natural binary powers-of-two
|
||||
The "hn\-1000" modifier will use 1000 as divisor instead of 1024, following the
|
||||
JEDEC\-standard instead of the more natural binary powers\-of\-two
|
||||
tradition.
|
||||
.Bd -literal -offset indent
|
||||
EXAMPLE:
|
||||
xo_emit("{h:input/%u}, {h,hn-space:output/%u}, "
|
||||
"{h,hn-decimal:errors/%u}, {h,hn-1000:capacity/%u}, "
|
||||
"{h,hn-decimal:remaining/%u}\n",
|
||||
xo_emit("{h:input/%u}, {h,hn\-space:output/%u}, "
|
||||
"{h,hn\-decimal:errors/%u}, {h,hn\-1000:capacity/%u}, "
|
||||
"{h,hn\-decimal:remaining/%u}\\n",
|
||||
input, output, errors, capacity, remaining);
|
||||
TEXT:
|
||||
21, 57 K, 96M, 44M, 1.2G
|
||||
.Ed
|
||||
.Pp
|
||||
In the HTML style, the original numeric value is rendered in the
|
||||
"data-number" attribute on the <div> element:
|
||||
"data\-number" attribute on the <div> element:
|
||||
.Bd -literal -offset indent
|
||||
<div class="data" data-tag="errors"
|
||||
data-number="100663296">96M</div>
|
||||
<div class="data" data\-tag="errors"
|
||||
data\-number="100663296">96M</div>
|
||||
.Ed
|
||||
.Ss "The Gettext Modifier ({g:})"
|
||||
The gettext modifier is used to translate individual fields using the
|
||||
@ -476,9 +499,9 @@ translation.
|
||||
In the following example, the strings "State" and "full" are passed
|
||||
to
|
||||
.Fn gettext
|
||||
to find locale-based translated strings.
|
||||
to find locale\-based translated strings.
|
||||
.Bd -literal -offset indent
|
||||
xo_emit("{Lgwc:State}{g:state}\n", "full");
|
||||
xo_emit("{Lgwc:State}{g:state}\\n", "full");
|
||||
.Ed
|
||||
.Ss "The Key Modifier ({k:})"
|
||||
The key modifier is used to indicate that a particular field helps
|
||||
@ -499,15 +522,15 @@ Currently the key modifier is only used when generating XPath values
|
||||
for the HTML output style when
|
||||
.Dv XOF_XPATH
|
||||
is set, but other uses are likely in the near future.
|
||||
.Ss "The Leaf-List Modifier ({l:})"
|
||||
The leaf-list modifier is used to distinguish lists where each
|
||||
.Ss "The Leaf\-List Modifier ({l:})"
|
||||
The leaf\-list modifier is used to distinguish lists where each
|
||||
instance consists of only a single value. In XML, these are
|
||||
rendered as single elements, where JSON renders them as arrays.
|
||||
.Bd -literal -offset indent
|
||||
EXAMPLE:
|
||||
xo_open_list("user");
|
||||
for (i = 0; i < num_users; i++) {
|
||||
xo_emit("Member {l:name}\n", user[i].u_name);
|
||||
xo_emit("Member {l:name}\\n", user[i].u_name);
|
||||
}
|
||||
xo_close_list("user");
|
||||
XML:
|
||||
@ -516,8 +539,8 @@ rendered as single elements, where JSON renders them as arrays.
|
||||
JSON:
|
||||
"user": [ "phil", "pallavi" ]
|
||||
.Ed
|
||||
.Ss "The No-Quotes Modifier ({n:})"
|
||||
The no-quotes modifier (and its twin, the 'quotes' modifier) affect
|
||||
.Ss "The No\-Quotes Modifier ({n:})"
|
||||
The no\-quotes modifier (and its twin, the \(aqquotes\(aq modifier) affect
|
||||
the quoting of values in the JSON output style.
|
||||
JSON uses quotes for
|
||||
string values, but no quotes for numeric, boolean, and null data.
|
||||
@ -538,8 +561,9 @@ language settings.
|
||||
The contents of the field should be the singular
|
||||
and plural English values, separated by a comma:
|
||||
.Bd -literal -offset indent
|
||||
xo_emit("{:bytes} {Ngp:byte,bytes}\n", bytes);
|
||||
xo_emit("{:bytes} {Ngp:byte,bytes}\\n", bytes);
|
||||
.Ed
|
||||
.Pp
|
||||
The plural modifier is meant to work with the gettext modifier ({g:})
|
||||
but can work independently.
|
||||
.Pp
|
||||
@ -554,7 +578,7 @@ function is
|
||||
called to handle the heavy lifting, using the message catalog to
|
||||
convert the singular and plural forms into the native language.
|
||||
.Ss "The Quotes Modifier ({q:})"
|
||||
The quotes modifier (and its twin, the 'no-quotes' modifier) affect
|
||||
The quotes modifier (and its twin, the \(aqno-quotes\(aq modifier) affect
|
||||
the quoting of values in the JSON output style.
|
||||
JSON uses quotes for
|
||||
string values, but no quotes for numeric, boolean, and null data.
|
||||
@ -578,23 +602,23 @@ The white space modifier appends a single space to the data value:
|
||||
.Pp
|
||||
The white space modifier is only used for the TEXT and HTML output
|
||||
styles.
|
||||
It is commonly combined with the colon modifier ('{c:}').
|
||||
It is commonly combined with the colon modifier (\(aq{c:}\(aq).
|
||||
It is purely a convenience feature.
|
||||
.Pp
|
||||
Note that the sense of the 'w' modifier is reversed for the units role
|
||||
Note that the sense of the \(aqw\(aq modifier is reversed for the units role
|
||||
({Uw:}); a blank is added before the contents, rather than after it.
|
||||
.Ss "Field Formatting"
|
||||
The field format is similar to the format string for
|
||||
.Xr printf 3 .
|
||||
Its use varies based on the role of the field, but generally is used to
|
||||
format the field's contents.
|
||||
format the field\(aqs contents.
|
||||
.Pp
|
||||
If the format string is not provided for a value field, it defaults
|
||||
to "%s".
|
||||
.Pp
|
||||
Note a field definition can contain zero or more printf-style
|
||||
Note a field definition can contain zero or more printf\-style
|
||||
.Dq directives ,
|
||||
which are sequences that start with a '%' and end with
|
||||
which are sequences that start with a \(aq%\(aq and end with
|
||||
one of following characters: "diouxXDOUeEfFgGaAcCsSp".
|
||||
Each directive
|
||||
is matched by one of more arguments to the
|
||||
@ -603,54 +627,54 @@ function.
|
||||
.Pp
|
||||
The format string has the form:
|
||||
.Bd -literal -offset indent
|
||||
'%' format-modifier * format-character
|
||||
\(aq%\(aq format\-modifier * format\-character
|
||||
.Ed
|
||||
.Pp
|
||||
The format- modifier can be:
|
||||
The format\- modifier can be:
|
||||
.Bl -bullet
|
||||
.It
|
||||
a '#' character, indicating the output value should be prefixed with
|
||||
a \(aq#\(aq character, indicating the output value should be prefixed with
|
||||
"0x", typically to indicate a base 16 (hex) value.
|
||||
.It
|
||||
a minus sign ('-'), indicating the output value should be padded on
|
||||
a minus sign (\(aq\-\(aq), indicating the output value should be padded on
|
||||
the right instead of the left.
|
||||
.It
|
||||
a leading zero ('0') indicating the output value should be padded on the
|
||||
left with zeroes instead of spaces (' ').
|
||||
a leading zero (\(aq0\(aq) indicating the output value should be padded on the
|
||||
left with zeroes instead of spaces (\(aq \(aq).
|
||||
.It
|
||||
one or more digits ('0' - '9') indicating the minimum width of the
|
||||
one or more digits (\(aq0\(aq \- \(aq9\(aq) indicating the minimum width of the
|
||||
argument.
|
||||
If the width in columns of the output value is less than
|
||||
the minimum width, the value will be padded to reach the minimum.
|
||||
.It
|
||||
a period followed by one or more digits indicating the maximum
|
||||
number of bytes which will be examined for a string argument, or the maximum
|
||||
width for a non-string argument.
|
||||
width for a non\-string argument.
|
||||
When handling ASCII strings this
|
||||
functions as the field width but for multi-byte characters, a single
|
||||
functions as the field width but for multi\-byte characters, a single
|
||||
character may be composed of multiple bytes.
|
||||
.Xr xo_emit 3
|
||||
will never dereference memory beyond the given number of bytes.
|
||||
.It
|
||||
a second period followed by one or more digits indicating the maximum
|
||||
width for a string argument.
|
||||
This modifier cannot be given for non-string arguments.
|
||||
This modifier cannot be given for non\-string arguments.
|
||||
.It
|
||||
one or more 'h' characters, indicating shorter input data.
|
||||
one or more \(aqh\(aq characters, indicating shorter input data.
|
||||
.It
|
||||
one or more 'l' characters, indicating longer input data.
|
||||
one or more \(aql\(aq characters, indicating longer input data.
|
||||
.It
|
||||
a 'z' character, indicating a 'size_t' argument.
|
||||
a \(aqz\(aq character, indicating a \(aqsize_t\(aq argument.
|
||||
.It
|
||||
a 't' character, indicating a 'ptrdiff_t' argument.
|
||||
a \(aqt\(aq character, indicating a \(aqptrdiff_t\(aq argument.
|
||||
.It
|
||||
a ' ' character, indicating a space should be emitted before
|
||||
a \(aq \(aq character, indicating a space should be emitted before
|
||||
positive numbers.
|
||||
.It
|
||||
a '+' character, indicating sign should emitted before any number.
|
||||
a \(aq+\(aq character, indicating sign should emitted before any number.
|
||||
.El
|
||||
.Pp
|
||||
Note that 'q', 'D', 'O', and 'U' are considered deprecated and will be
|
||||
Note that \(aqq\(aq, \(aqD\(aq, \(aqO\(aq, and \(aqU\(aq are considered deprecated and will be
|
||||
removed eventually.
|
||||
.Pp
|
||||
The format character is described in the following table:
|
||||
@ -665,22 +689,22 @@ The format character is described in the following table:
|
||||
.It D "long " "base 10 (decimal)"
|
||||
.It O "unsigned long " "base 8 (octal)"
|
||||
.It U "unsigned long " "base 10 (decimal)"
|
||||
.It e "double " "[-]d.ddde+-dd"
|
||||
.It E "double " "[-]d.dddE+-dd"
|
||||
.It f "double " "[-]ddd.ddd"
|
||||
.It F "double " "[-]ddd.ddd"
|
||||
.It g "double " "as 'e' or 'f'"
|
||||
.It G "double " "as 'E' or 'F'"
|
||||
.It a "double " "[-]0xh.hhhp[+-]d"
|
||||
.It A "double " "[-]0Xh.hhhp[+-]d"
|
||||
.It e "double " "[\-]d.ddde+\-dd"
|
||||
.It E "double " "[\-]d.dddE+\-dd"
|
||||
.It f "double " "[\-]ddd.ddd"
|
||||
.It F "double " "[\-]ddd.ddd"
|
||||
.It g "double " "as \(aqe\(aq or \(aqf\(aq"
|
||||
.It G "double " "as \(aqE\(aq or \(aqF\(aq"
|
||||
.It a "double " "[\-]0xh.hhhp[+\-]d"
|
||||
.It A "double " "[\-]0Xh.hhhp[+\-]d"
|
||||
.It c "unsigned char " "a character"
|
||||
.It C "wint_t " "a character"
|
||||
.It s "char * " "a UTF-8 string"
|
||||
.It s "char * " "a UTF\-8 string"
|
||||
.It S "wchar_t * " "a unicode/WCS string"
|
||||
.It p "void * " "'%#lx'"
|
||||
.It p "void * " "\(aq%#lx\(aq"
|
||||
.El
|
||||
.Pp
|
||||
The 'h' and 'l' modifiers affect the size and treatment of the
|
||||
The \(aqh\(aq and \(aql\(aq modifiers affect the size and treatment of the
|
||||
argument:
|
||||
.Bl -column "Mod" "d, i " "o, u, x, X "
|
||||
.It Sy "Mod" "d, i " "o, u, x, X"
|
||||
@ -693,27 +717,27 @@ argument:
|
||||
.It "z " "size_t " "size_t"
|
||||
.It "q " "quad_t " "u_quad_t"
|
||||
.El
|
||||
.Ss "UTF-8 and Locale Strings"
|
||||
.Ss "UTF\-8 and Locale Strings"
|
||||
All strings for
|
||||
.Nm libxo
|
||||
must be UTF-8.
|
||||
must be UTF\-8.
|
||||
.Nm libxo
|
||||
will handle turning them
|
||||
into locale-based strings for display to the user.
|
||||
into locale\-based strings for display to the user.
|
||||
.Pp
|
||||
For strings, the 'h' and 'l' modifiers affect the interpretation of
|
||||
For strings, the \(aqh\(aq and \(aql\(aq modifiers affect the interpretation of
|
||||
the bytes pointed to argument.
|
||||
The default '%s' string is a 'char *'
|
||||
pointer to a string encoded as UTF-8.
|
||||
Since UTF-8 is compatible with
|
||||
The default \(aq%s\(aq string is a \(aqchar *\(aq
|
||||
pointer to a string encoded as UTF\-8.
|
||||
Since UTF\-8 is compatible with
|
||||
.Em ASCII
|
||||
data, a normal 7-bit
|
||||
data, a normal 7\-bit
|
||||
.Em ASCII
|
||||
string can be used.
|
||||
"%ls" expects a
|
||||
"wchar_t *" pointer to a wide-character string, encoded as 32-bit
|
||||
"wchar_t *" pointer to a wide\-character string, encoded as 32\-bit
|
||||
Unicode values.
|
||||
"%hs" expects a "char *" pointer to a multi-byte
|
||||
"%hs" expects a "char *" pointer to a multi\-byte
|
||||
string encoded with the current locale, as given by the
|
||||
.Ev LC_CTYPE ,
|
||||
.Ev LANG ,
|
||||
@ -722,22 +746,22 @@ or
|
||||
environment variables.
|
||||
The first of this list of
|
||||
variables is used and if none of the variables are set, the locale defaults to
|
||||
.Em UTF-8 .
|
||||
.Em UTF\-8 .
|
||||
.Pp
|
||||
.Nm libxo
|
||||
will
|
||||
convert these arguments as needed to either UTF-8 (for XML, JSON, and
|
||||
HTML styles) or locale-based strings for display in text style.
|
||||
convert these arguments as needed to either UTF\-8 (for XML, JSON, and
|
||||
HTML styles) or locale\-based strings for display in text style.
|
||||
.Bd -literal -offset indent
|
||||
xo_emit("All strings are utf-8 content {:tag/%ls}",
|
||||
xo_emit("All strings are utf\-8 content {:tag/%ls}",
|
||||
L"except for wide strings");
|
||||
.Ed
|
||||
.Pp
|
||||
"%S" is equivalent to "%ls".
|
||||
.Pp
|
||||
For example, a function is passed a locale-base name, a hat size,
|
||||
For example, a function is passed a locale\-base name, a hat size,
|
||||
and a time value.
|
||||
The hat size is formatted in a UTF-8 (ASCII)
|
||||
The hat size is formatted in a UTF\-8 (ASCII)
|
||||
string, and the time value is formatted into a wchar_t string.
|
||||
.Bd -literal -offset indent
|
||||
void print_order (const char *name, int size,
|
||||
@ -755,7 +779,7 @@ string, and the time value is formatted into a wchar_t string.
|
||||
|
||||
xo_emit("The hat for {:name/%hs} is {:size/%s}.\\n",
|
||||
name, size_val);
|
||||
xo_emit("It was ordered on {:order-time/%ls}.\\n",
|
||||
xo_emit("It was ordered on {:order\-time/%ls}.\\n",
|
||||
when);
|
||||
}
|
||||
.Ed
|
||||
@ -766,11 +790,11 @@ will perform the conversion
|
||||
required to make appropriate output.
|
||||
Text style output uses the
|
||||
current locale (as described above), while XML, JSON, and HTML use
|
||||
UTF-8.
|
||||
UTF\-8.
|
||||
.Pp
|
||||
UTF-8 and locale-encoded strings can use multiple bytes to encode one
|
||||
UTF\-8 and locale\-encoded strings can use multiple bytes to encode one
|
||||
column of data.
|
||||
The traditional "precision'" (aka "max-width") value
|
||||
The traditional "precision" (aka "max\-width") value
|
||||
for "%s" printf formatting becomes overloaded since it specifies both
|
||||
the number of bytes that can be safely referenced and the maximum
|
||||
number of columns to emit.
|
||||
@ -800,12 +824,12 @@ For HTML, these characters are placed in a <div> with class "text".
|
||||
"size": "extra small"
|
||||
HTML:
|
||||
<div class="text">The hat is </div>
|
||||
<div class="data" data-tag="size">extra small</div>
|
||||
<div class="data" data\-tag="size">extra small</div>
|
||||
<div class="text">.</div>
|
||||
.Ed
|
||||
.Ss "'%n' is Not Supported"
|
||||
.Ss "\(aq%n\(aq is Not Supported"
|
||||
.Nm libxo
|
||||
does not support the '%n' directive.
|
||||
does not support the \(aq%n\(aq directive.
|
||||
It is a bad idea and we
|
||||
just do not do it.
|
||||
.Ss "The Encoding Format (eformat)"
|
||||
@ -817,7 +841,7 @@ If the primary is not given, both default to "%s".
|
||||
.Sh EXAMPLE
|
||||
In this example, the value for the number of items in stock is emitted:
|
||||
.Bd -literal -offset indent
|
||||
xo_emit("{P: }{Lwc:In stock}{:in-stock/%u}\\n",
|
||||
xo_emit("{P: }{Lwc:In stock}{:in\-stock/%u}\\n",
|
||||
instock);
|
||||
.Ed
|
||||
.Pp
|
||||
@ -826,16 +850,16 @@ This call will generate the following output:
|
||||
TEXT:
|
||||
In stock: 144
|
||||
XML:
|
||||
<in-stock>144</in-stock>
|
||||
<in\-stock>144</in\-stock>
|
||||
JSON:
|
||||
"in-stock": 144,
|
||||
"in\-stock": 144,
|
||||
HTML:
|
||||
<div class="line">
|
||||
<div class="padding"> </div>
|
||||
<div class="label">In stock</div>
|
||||
<div class="decoration">:</div>
|
||||
<div class="padding"> </div>
|
||||
<div class="data" data-tag="in-stock">144</div>
|
||||
<div class="data" data\-tag="in\-stock">144</div>
|
||||
</div>
|
||||
.Ed
|
||||
.Pp
|
||||
@ -846,10 +870,10 @@ or
|
||||
.Dv XOF_INFO
|
||||
data, which would expand the penultimate line to:
|
||||
.Bd -literal -offset indent
|
||||
<div class="data" data-tag="in-stock"
|
||||
data-xpath="/top/data/item/in-stock"
|
||||
data-type="number"
|
||||
data-help="Number of items in stock">144</div>
|
||||
<div class="data" data\-tag="in\-stock"
|
||||
data\-xpath="/top/data/item/in\-stock"
|
||||
data\-type="number"
|
||||
data\-help="Number of items in stock">144</div>
|
||||
.Ed
|
||||
.Sh WHAT MAKES A GOOD FIELD NAME?
|
||||
To make useful, consistent field names, follow these guidelines:
|
||||
@ -867,23 +891,23 @@ But the raw field name should use hyphens.
|
||||
.Ss "Use full words"
|
||||
Do not abbreviate especially when the abbreviation is not obvious or
|
||||
not widely used.
|
||||
Use "data-size", not "dsz" or "dsize".
|
||||
Use "data\-size", not "dsz" or "dsize".
|
||||
Use
|
||||
"interface" instead of "ifname", "if-name", "iface", "if", or "intf".
|
||||
.Ss "Use <verb>-<units>"
|
||||
Using the form <verb>-<units> or <verb>-<classifier>-<units> helps in
|
||||
"interface" instead of "ifname", "if\-name", "iface", "if", or "intf".
|
||||
.Ss "Use <verb>\-<units>"
|
||||
Using the form <verb>\-<units> or <verb>\-<classifier>\-<units> helps in
|
||||
making consistent, useful names, avoiding the situation where one app
|
||||
uses "sent-packet" and another "packets-sent" and another
|
||||
"packets-we-have-sent".
|
||||
uses "sent\-packet" and another "packets\-sent" and another
|
||||
"packets\-we\-have\-sent".
|
||||
The <units> can be dropped when it is
|
||||
obvious, as can obvious words in the classification.
|
||||
Use "receive-after-window-packets" instead of
|
||||
"received-packets-of-data-after-window".
|
||||
Use "receive\-after\-window\-packets" instead of
|
||||
"received\-packets\-of\-data\-after\-window".
|
||||
.Ss "Reuse existing field names"
|
||||
Nothing is worse than writing expressions like:
|
||||
.Bd -literal -offset indent
|
||||
if ($src1/process[pid == $pid]/name ==
|
||||
$src2/proc-table/proc/p[process-id == $pid]/proc-name) {
|
||||
$src2/proc\-table/proc/p[process\-id == $pid]/proc\-name) {
|
||||
...
|
||||
}
|
||||
.Ed
|
||||
@ -903,7 +927,7 @@ calls or "{e:}" fields to make the data useful.
|
||||
.Ss "Do not use an arbitrary number postfix"
|
||||
What does "errors2" mean?
|
||||
No one will know.
|
||||
"errors-after-restart" would be a better choice.
|
||||
"errors\-after\-restart" would be a better choice.
|
||||
Think of your users, and think of the future.
|
||||
If you make "errors2", the next guy will happily make
|
||||
"errors3" and before you know it, someone will be asking what is the
|
||||
@ -913,7 +937,7 @@ Think of your field vocabulary as an API.
|
||||
You want it useful,
|
||||
expressive, meaningful, direct, and obvious.
|
||||
You want the client
|
||||
application's programmer to move between without the need to
|
||||
application\(aqs programmer to move between without the need to
|
||||
understand a variety of opinions on how fields are named.
|
||||
They should
|
||||
see the system as a single cohesive whole, not a sack of cats.
|
||||
@ -925,12 +949,12 @@ By choosing wise names now, you are making their lives better.
|
||||
After using
|
||||
.Xr xolint 1
|
||||
to find errors in your field descriptors, use
|
||||
.Dq "xolint -V"
|
||||
.Dq "xolint \-V"
|
||||
to spell check your field names and to detect different
|
||||
names for the same data.
|
||||
.Dq dropped-short
|
||||
.Dq dropped\-short
|
||||
and
|
||||
.Dq dropped-too-short
|
||||
.Dq dropped\-too\-short
|
||||
are both reasonable names, but using them both will lead users to ask the
|
||||
difference between the two fields.
|
||||
If there is no difference,
|
||||
|
@ -83,12 +83,16 @@ Log (via stderr) each syslog message (via
|
||||
Ignore the {h:} modifier (TEXT, HTML)
|
||||
.It Dv no-locale
|
||||
Do not initialize the locale setting
|
||||
.It Dv no-retain
|
||||
Prevent retaining formatting information
|
||||
.It Dv no-top
|
||||
Do not emit a top set of braces (JSON)
|
||||
.It Dv not-first
|
||||
Pretend the 1st output item was not 1st (JSON)
|
||||
.It Dv pretty
|
||||
Emit pretty-printed output
|
||||
.It Dv retain
|
||||
Force retaining formatting information
|
||||
.It Dv text
|
||||
Emit TEXT output
|
||||
.If Dv underscores
|
||||
|
@ -5,7 +5,7 @@ includedir=@includedir@
|
||||
|
||||
|
||||
Name: libxo
|
||||
Version: @VERSION@
|
||||
Version: @LIBXO_VERSION@
|
||||
Description: The XML Output Library
|
||||
Libs: @LIBXO_LIBDIR@ @LIBXO_LIBS@
|
||||
Cflags: @LIBXO_INCLUDEDIR@
|
||||
Libs: -L@XO_LIBDIR@ @XO_LIBS@
|
||||
Cflags: -I@XO_INCLUDEDIR@
|
||||
|
@ -6,15 +6,15 @@
|
||||
require 'formula'
|
||||
|
||||
class Libxo < Formula
|
||||
homepage 'https://github.com/Juniper/@PACKAGE-NAME@'
|
||||
url 'https://github.com/Juniper/@PACKAGE_NAME@/releases/@PACKAGE_VERSION@/@PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz'
|
||||
homepage 'https://github.com/Juniper/@PACKAGE_NAME@'
|
||||
url 'https://github.com/Juniper/@PACKAGE_NAME@/releases/download/@PACKAGE_VERSION@/@PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz'
|
||||
sha1 '__SHA1__'
|
||||
|
||||
depends_on 'libtool' => :build
|
||||
|
||||
def install
|
||||
system "./configure", "--disable-dependency-tracking",
|
||||
system "./configure", "--disable-dependency-tracking", "--disable-silent-rules",
|
||||
"--prefix=#{prefix}"
|
||||
system "make install"
|
||||
system "make", "install"
|
||||
end
|
||||
end
|
||||
|
@ -22,7 +22,8 @@ test_07.c \
|
||||
test_08.c \
|
||||
test_09.c \
|
||||
test_10.c \
|
||||
test_11.c
|
||||
test_11.c \
|
||||
test_12.c
|
||||
|
||||
test_01_test_SOURCES = test_01.c
|
||||
test_02_test_SOURCES = test_02.c
|
||||
@ -35,6 +36,7 @@ test_08_test_SOURCES = test_08.c
|
||||
test_09_test_SOURCES = test_09.c
|
||||
test_10_test_SOURCES = test_10.c
|
||||
test_11_test_SOURCES = test_11.c
|
||||
test_12_test_SOURCES = test_12.c
|
||||
|
||||
# TEST_CASES := $(shell cd ${srcdir} ; echo *.c )
|
||||
|
||||
|
@ -2,6 +2,14 @@ op create: [] []
|
||||
op open_container: [top] []
|
||||
op string: [host] [my-box]
|
||||
op string: [domain] [example.com]
|
||||
op string: [host] [my-box]
|
||||
op string: [domain] [example.com]
|
||||
op string: [label] [value]
|
||||
op string: [max-chaos] [very]
|
||||
op content: [min-chaos] [42]
|
||||
op string: [some-chaos] [[42]]
|
||||
op string: [host] [my-box]
|
||||
op string: [domain] [example.com]
|
||||
op attr: [test] [value]
|
||||
op open_container: [data] []
|
||||
op open_list: [item] []
|
||||
@ -114,6 +122,16 @@ op close_list: [item] []
|
||||
op close_container: [data4] []
|
||||
op content: [cost] [425]
|
||||
op content: [cost] [455]
|
||||
op string: [mode] [mode]
|
||||
op string: [mode_octal] [octal]
|
||||
op string: [links] [links]
|
||||
op string: [user] [user]
|
||||
op string: [group] [group]
|
||||
op string: [mode] [/some/file]
|
||||
op content: [mode_octal] [640]
|
||||
op content: [links] [1]
|
||||
op string: [user] [user]
|
||||
op string: [group] [group]
|
||||
op close_container: [top] []
|
||||
op finish: [] []
|
||||
op flush: [] []
|
||||
|
File diff suppressed because one or more lines are too long
@ -1,4 +1,26 @@
|
||||
<div class="line">
|
||||
<div class="text">testing argument modifier </div>
|
||||
<div class="data" data-tag="host" data-xpath="/top/host">my-box</div>
|
||||
<div class="text">.</div>
|
||||
<div class="data" data-tag="domain" data-xpath="/top/domain">example.com</div>
|
||||
<div class="text">...</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">testing argument modifier with encoding to </div>
|
||||
<div class="text">.</div>
|
||||
<div class="data" data-tag="domain" data-xpath="/top/domain">example.com</div>
|
||||
<div class="text">...</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="label">Label text</div>
|
||||
<div class="text"> </div>
|
||||
<div class="data" data-tag="label" data-xpath="/top/label">value</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="data" data-tag="max-chaos" data-xpath="/top/max-chaos"> very </div>
|
||||
<div class="data" data-tag="min-chaos" data-xpath="/top/min-chaos">42</div>
|
||||
<div class="data" data-tag="some-chaos" data-xpath="/top/some-chaos">42
|
||||
</div>
|
||||
<div class="text">Connecting to </div>
|
||||
<div class="data" data-tag="host" data-xpath="/top/host">my-box</div>
|
||||
<div class="text">.</div>
|
||||
@ -301,3 +323,22 @@
|
||||
<div class="padding"> </div>
|
||||
<div class="data" data-tag="cost" data-xpath="/top/cost">455</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text"> </div>
|
||||
<div class="data" data-tag="links" data-xpath="/top/links">links</div>
|
||||
<div class="text"> </div>
|
||||
<div class="data" data-tag="user" data-xpath="/top/user">user</div>
|
||||
<div class="text"> </div>
|
||||
<div class="data" data-tag="group" data-xpath="/top/group">group</div>
|
||||
<div class="text"> </div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="data" data-tag="mode" data-xpath="/top/mode">/some/file</div>
|
||||
<div class="text"> </div>
|
||||
<div class="data" data-tag="links" data-xpath="/top/links"> 1</div>
|
||||
<div class="text"> </div>
|
||||
<div class="data" data-tag="user" data-xpath="/top/user">user </div>
|
||||
<div class="text"> </div>
|
||||
<div class="data" data-tag="group" data-xpath="/top/group">group </div>
|
||||
<div class="text"> </div>
|
||||
</div>
|
||||
|
@ -1,4 +1,26 @@
|
||||
<div class="line">
|
||||
<div class="text">testing argument modifier </div>
|
||||
<div class="data" data-tag="host">my-box</div>
|
||||
<div class="text">.</div>
|
||||
<div class="data" data-tag="domain">example.com</div>
|
||||
<div class="text">...</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">testing argument modifier with encoding to </div>
|
||||
<div class="text">.</div>
|
||||
<div class="data" data-tag="domain">example.com</div>
|
||||
<div class="text">...</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="label">Label text</div>
|
||||
<div class="text"> </div>
|
||||
<div class="data" data-tag="label">value</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="data" data-tag="max-chaos"> very </div>
|
||||
<div class="data" data-tag="min-chaos">42</div>
|
||||
<div class="data" data-tag="some-chaos">42
|
||||
</div>
|
||||
<div class="text">Connecting to </div>
|
||||
<div class="data" data-tag="host">my-box</div>
|
||||
<div class="text">.</div>
|
||||
@ -301,3 +323,22 @@
|
||||
<div class="padding"> </div>
|
||||
<div class="data" data-tag="cost">455</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text"> </div>
|
||||
<div class="data" data-tag="links">links</div>
|
||||
<div class="text"> </div>
|
||||
<div class="data" data-tag="user">user</div>
|
||||
<div class="text"> </div>
|
||||
<div class="data" data-tag="group">group</div>
|
||||
<div class="text"> </div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="data" data-tag="mode">/some/file</div>
|
||||
<div class="text"> </div>
|
||||
<div class="data" data-tag="links"> 1</div>
|
||||
<div class="text"> </div>
|
||||
<div class="data" data-tag="user">user </div>
|
||||
<div class="text"> </div>
|
||||
<div class="data" data-tag="group">group </div>
|
||||
<div class="text"> </div>
|
||||
</div>
|
||||
|
@ -1,2 +1,2 @@
|
||||
{"top": {"host":"my-box","domain":"example.com", "data": {"item": [{"sku":"GRO-000-415","name":"gum","sold":1412,"in-stock":54,"on-order":10}, {"sku":"HRD-000-212","name":"rope","sold":85,"in-stock":4,"on-order":2}, {"sku":"HRD-000-517","name":"ladder","sold":0,"in-stock":2,"on-order":1}, {"sku":"HRD-000-632","name":"bolt","sold":4123,"in-stock":144,"on-order":42}, {"sku":"GRO-000-2331","name":"water","sold":17,"in-stock":14,"on-order":2}]}, "data2": {"item": [{"sku":"GRO-000-415","name":"gum","sold":1412.0,"in-stock":54,"on-order":10}, {"sku":"HRD-000-212","name":"rope","sold":85.0,"in-stock":4,"on-order":2}, {"sku":"HRD-000-517","name":"ladder","sold":0,"in-stock":2,"on-order":1}, {"sku":"HRD-000-632","name":"bolt","sold":4123.0,"in-stock":144,"on-order":42}, {"sku":"GRO-000-2331","name":"water","sold":17.0,"in-stock":14,"on-order":2}]}, "data3": {"item": [{"sku":"GRO-000-533","name":"fish","sold":1321.0,"in-stock":45,"on-order":1}]}, "data4": {"item": ["gum","rope","ladder","bolt","water"]},"cost":425,"cost":455}
|
||||
{"top": {"host":"my-box","domain":"example.com","host":"my-box","domain":"example.com","label":"value","max-chaos":"very","min-chaos":42,"some-chaos":"[42]","host":"my-box","domain":"example.com", "data": {"item": [{"sku":"GRO-000-415","name":"gum","sold":1412,"in-stock":54,"on-order":10}, {"sku":"HRD-000-212","name":"rope","sold":85,"in-stock":4,"on-order":2}, {"sku":"HRD-000-517","name":"ladder","sold":0,"in-stock":2,"on-order":1}, {"sku":"HRD-000-632","name":"bolt","sold":4123,"in-stock":144,"on-order":42}, {"sku":"GRO-000-2331","name":"water","sold":17,"in-stock":14,"on-order":2}]}, "data2": {"item": [{"sku":"GRO-000-415","name":"gum","sold":1412.0,"in-stock":54,"on-order":10}, {"sku":"HRD-000-212","name":"rope","sold":85.0,"in-stock":4,"on-order":2}, {"sku":"HRD-000-517","name":"ladder","sold":0,"in-stock":2,"on-order":1}, {"sku":"HRD-000-632","name":"bolt","sold":4123.0,"in-stock":144,"on-order":42}, {"sku":"GRO-000-2331","name":"water","sold":17.0,"in-stock":14,"on-order":2}]}, "data3": {"item": [{"sku":"GRO-000-533","name":"fish","sold":1321.0,"in-stock":45,"on-order":1}]}, "data4": {"item": ["gum","rope","ladder","bolt","water"]},"cost":425,"cost":455,"mode":"mode","mode_octal":"octal","links":"links","user":"user","group":"group","mode":"/some/file","mode_octal":640,"links":1,"user":"user","group":"group"}
|
||||
}
|
||||
|
@ -1,5 +1,13 @@
|
||||
{
|
||||
"top": {
|
||||
"host": "my-box",
|
||||
"domain": "example.com",
|
||||
"host": "my-box",
|
||||
"domain": "example.com",
|
||||
"label": "value",
|
||||
"max-chaos": "very",
|
||||
"min-chaos": 42,
|
||||
"some-chaos": "[42]",
|
||||
"host": "my-box",
|
||||
"domain": "example.com",
|
||||
"data": {
|
||||
@ -101,6 +109,16 @@
|
||||
]
|
||||
},
|
||||
"cost": 425,
|
||||
"cost": 455
|
||||
"cost": 455,
|
||||
"mode": "mode",
|
||||
"mode_octal": "octal",
|
||||
"links": "links",
|
||||
"user": "user",
|
||||
"group": "group",
|
||||
"mode": "/some/file",
|
||||
"mode_octal": 640,
|
||||
"links": 1,
|
||||
"user": "user",
|
||||
"group": "group"
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,7 @@
|
||||
testing argument modifier my-box.example.com...
|
||||
testing argument modifier with encoding to .example.com...
|
||||
Label text value
|
||||
very 4242
|
||||
Connecting to my-box.example.com...
|
||||
Item Total Sold In Stock On Order SKU
|
||||
gum 1412 54 10 GRO-000-415
|
||||
@ -45,3 +49,5 @@ Item: water
|
||||
XXXXXXXX
|
||||
X XCost: 425
|
||||
X XCost: 455
|
||||
links user group
|
||||
/some/file 1 user group
|
||||
|
@ -1 +1 @@
|
||||
<top><host>my-box</host><domain>example.com</domain><data test="value"><item test2="value2"><sku test3="value3" key="key">GRO-000-415</sku><name key="key">gum</name><sold>1412</sold><in-stock>54</in-stock><on-order>10</on-order></item><item><sku test3="value3" key="key">HRD-000-212</sku><name key="key">rope</name><sold>85</sold><in-stock>4</in-stock><on-order>2</on-order></item><item><sku test3="value3" key="key">HRD-000-517</sku><name key="key">ladder</name><sold>0</sold><in-stock>2</in-stock><on-order>1</on-order></item><item><sku test3="value3" key="key">HRD-000-632</sku><name key="key">bolt</name><sold>4123</sold><in-stock>144</in-stock><on-order>42</on-order></item><item><sku test3="value3" key="key">GRO-000-2331</sku><name key="key">water</name><sold>17</sold><in-stock>14</in-stock><on-order>2</on-order></item></data><data2><item><sku key="key">GRO-000-415</sku><name key="key">gum</name><sold>1412.0</sold><in-stock>54</in-stock><on-order>10</on-order></item><item><sku key="key">HRD-000-212</sku><name key="key">rope</name><sold>85.0</sold><in-stock>4</in-stock><on-order>2</on-order></item><item><sku key="key">HRD-000-517</sku><name key="key">ladder</name><sold>0</sold><in-stock>2</in-stock><on-order>1</on-order></item><item><sku key="key">HRD-000-632</sku><name key="key">bolt</name><sold>4123.0</sold><in-stock>144</in-stock><on-order>42</on-order></item><item><sku key="key">GRO-000-2331</sku><name key="key">water</name><sold>17.0</sold><in-stock>14</in-stock><on-order>2</on-order></item></data2><data3><item><sku key="key">GRO-000-533</sku><name key="key">fish</name><sold>1321.0</sold><in-stock>45</in-stock><on-order>1</on-order></item></data3><data4><item test4="value4">gum</item><item test4="value4">rope</item><item test4="value4">ladder</item><item test4="value4">bolt</item><item test4="value4">water</item></data4><cost>425</cost><cost>455</cost></top>
|
||||
<top><host>my-box</host><domain>example.com</domain><host>my-box</host><domain>example.com</domain><label>value</label><max-chaos>very</max-chaos><min-chaos>42</min-chaos><some-chaos>[42]</some-chaos><host>my-box</host><domain>example.com</domain><data test="value"><item test2="value2"><sku test3="value3" key="key">GRO-000-415</sku><name key="key">gum</name><sold>1412</sold><in-stock>54</in-stock><on-order>10</on-order></item><item><sku test3="value3" key="key">HRD-000-212</sku><name key="key">rope</name><sold>85</sold><in-stock>4</in-stock><on-order>2</on-order></item><item><sku test3="value3" key="key">HRD-000-517</sku><name key="key">ladder</name><sold>0</sold><in-stock>2</in-stock><on-order>1</on-order></item><item><sku test3="value3" key="key">HRD-000-632</sku><name key="key">bolt</name><sold>4123</sold><in-stock>144</in-stock><on-order>42</on-order></item><item><sku test3="value3" key="key">GRO-000-2331</sku><name key="key">water</name><sold>17</sold><in-stock>14</in-stock><on-order>2</on-order></item></data><data2><item><sku key="key">GRO-000-415</sku><name key="key">gum</name><sold>1412.0</sold><in-stock>54</in-stock><on-order>10</on-order></item><item><sku key="key">HRD-000-212</sku><name key="key">rope</name><sold>85.0</sold><in-stock>4</in-stock><on-order>2</on-order></item><item><sku key="key">HRD-000-517</sku><name key="key">ladder</name><sold>0</sold><in-stock>2</in-stock><on-order>1</on-order></item><item><sku key="key">HRD-000-632</sku><name key="key">bolt</name><sold>4123.0</sold><in-stock>144</in-stock><on-order>42</on-order></item><item><sku key="key">GRO-000-2331</sku><name key="key">water</name><sold>17.0</sold><in-stock>14</in-stock><on-order>2</on-order></item></data2><data3><item><sku key="key">GRO-000-533</sku><name key="key">fish</name><sold>1321.0</sold><in-stock>45</in-stock><on-order>1</on-order></item></data3><data4><item test4="value4">gum</item><item test4="value4">rope</item><item test4="value4">ladder</item><item test4="value4">bolt</item><item test4="value4">water</item></data4><cost>425</cost><cost>455</cost><mode>mode</mode><mode_octal>octal</mode_octal><links>links</links><user>user</user><group>group</group><mode>/some/file</mode><mode_octal>640</mode_octal><links>1</links><user>user</user><group>group</group></top>
|
@ -1,4 +1,12 @@
|
||||
<top>
|
||||
<host>my-box</host>
|
||||
<domain>example.com</domain>
|
||||
<host>my-box</host>
|
||||
<domain>example.com</domain>
|
||||
<label>value</label>
|
||||
<max-chaos>very</max-chaos>
|
||||
<min-chaos>42</min-chaos>
|
||||
<some-chaos>[42]</some-chaos>
|
||||
<host>my-box</host>
|
||||
<domain>example.com</domain>
|
||||
<data test="value">
|
||||
@ -93,4 +101,14 @@
|
||||
</data4>
|
||||
<cost>425</cost>
|
||||
<cost>455</cost>
|
||||
<mode>mode</mode>
|
||||
<mode_octal>octal</mode_octal>
|
||||
<links>links</links>
|
||||
<user>user</user>
|
||||
<group>group</group>
|
||||
<mode>/some/file</mode>
|
||||
<mode_octal>640</mode_octal>
|
||||
<links>1</links>
|
||||
<user>user</user>
|
||||
<group>group</group>
|
||||
</top>
|
||||
|
0
contrib/libxo/tests/core/saved/test_12.E.err
Normal file
0
contrib/libxo/tests/core/saved/test_12.E.err
Normal file
89
contrib/libxo/tests/core/saved/test_12.E.out
Normal file
89
contrib/libxo/tests/core/saved/test_12.E.out
Normal file
@ -0,0 +1,89 @@
|
||||
op create: [] []
|
||||
op open_container: [top] []
|
||||
op open_container: [data] []
|
||||
op open_list: [thing] []
|
||||
op open_instance: [thing] []
|
||||
op string: [name] [thing]
|
||||
op string: [color] [green]
|
||||
op content: [time] [2:15]
|
||||
op string: [hand] [left]
|
||||
op string: [color] [blue]
|
||||
op content: [time] [3:45]
|
||||
op close_instance: [thing] []
|
||||
op open_instance: [thing] []
|
||||
op string: [name] [thing]
|
||||
op string: [color] [green]
|
||||
op content: [time] [2:15]
|
||||
op string: [hand] [left]
|
||||
op string: [color] [blue]
|
||||
op content: [time] [3:45]
|
||||
op close_instance: [thing] []
|
||||
op open_instance: [thing] []
|
||||
op string: [name] [thing]
|
||||
op string: [color] [green]
|
||||
op content: [time] [2:15]
|
||||
op string: [hand] [left]
|
||||
op string: [color] [blue]
|
||||
op content: [time] [3:45]
|
||||
op close_instance: [thing] []
|
||||
op open_instance: [thing] []
|
||||
op string: [name] [thing]
|
||||
op string: [color] [green]
|
||||
op content: [time] [2:15]
|
||||
op string: [hand] [left]
|
||||
op string: [color] [blue]
|
||||
op content: [time] [3:45]
|
||||
op close_instance: [thing] []
|
||||
op open_instance: [thing] []
|
||||
op string: [name] [thing]
|
||||
op string: [color] [green]
|
||||
op content: [time] [2:15]
|
||||
op string: [hand] [left]
|
||||
op string: [color] [blue]
|
||||
op content: [time] [3:45]
|
||||
op close_instance: [thing] []
|
||||
op open_instance: [thing] []
|
||||
op string: [name] [thing]
|
||||
op string: [color] [green]
|
||||
op content: [time] [2:15]
|
||||
op string: [hand] [left]
|
||||
op string: [color] [blue]
|
||||
op content: [time] [3:45]
|
||||
op close_instance: [thing] []
|
||||
op open_instance: [thing] []
|
||||
op string: [name] [thing]
|
||||
op string: [color] [green]
|
||||
op content: [time] [2:15]
|
||||
op string: [hand] [left]
|
||||
op string: [color] [blue]
|
||||
op content: [time] [3:45]
|
||||
op close_instance: [thing] []
|
||||
op open_instance: [thing] []
|
||||
op string: [name] [thing]
|
||||
op string: [color] [green]
|
||||
op content: [time] [2:15]
|
||||
op string: [hand] [left]
|
||||
op string: [color] [blue]
|
||||
op content: [time] [3:45]
|
||||
op close_instance: [thing] []
|
||||
op open_instance: [thing] []
|
||||
op string: [name] [thing]
|
||||
op string: [color] [green]
|
||||
op content: [time] [2:15]
|
||||
op string: [hand] [left]
|
||||
op string: [color] [blue]
|
||||
op content: [time] [3:45]
|
||||
op close_instance: [thing] []
|
||||
op open_instance: [thing] []
|
||||
op string: [name] [thing]
|
||||
op string: [color] [green]
|
||||
op content: [time] [2:15]
|
||||
op string: [hand] [left]
|
||||
op string: [color] [blue]
|
||||
op content: [time] [3:45]
|
||||
op close_instance: [thing] []
|
||||
op close_list: [thing] []
|
||||
op close_container: [data] []
|
||||
op close_container: [top] []
|
||||
op finish: [] []
|
||||
op flush: [] []
|
0
contrib/libxo/tests/core/saved/test_12.H.err
Normal file
0
contrib/libxo/tests/core/saved/test_12.H.err
Normal file
1
contrib/libxo/tests/core/saved/test_12.H.out
Normal file
1
contrib/libxo/tests/core/saved/test_12.H.out
Normal file
@ -0,0 +1 @@
|
||||
<div class="line"><div class="text">The </div><div class="data" data-tag="name">thing</div><div class="text"> is </div><div class="data" data-tag="color">green</div><div class="text"> til </div><div class="data" data-tag="time">02:15</div></div><div class="line"><div class="text">My </div><div class="data" data-tag="hand">left</div><div class="text"> hand is </div><div class="data" data-tag="color">blue</div><div class="text"> til </div><div class="data" data-tag="time">03:45</div></div><div class="line"><div class="text">The </div><div class="data" data-tag="name">thing</div><div class="text"> is </div><div class="data" data-tag="color">green</div><div class="text"> til </div><div class="data" data-tag="time">02:15</div></div><div class="line"><div class="text">My </div><div class="data" data-tag="hand">left</div><div class="text"> hand is </div><div class="data" data-tag="color">blue</div><div class="text"> til </div><div class="data" data-tag="time">03:45</div></div><div class="line"><div class="text">The </div><div class="data" data-tag="name">thing</div><div class="text"> is </div><div class="data" data-tag="color">green</div><div class="text"> til </div><div class="data" data-tag="time">02:15</div></div><div class="line"><div class="text">My </div><div class="data" data-tag="hand">left</div><div class="text"> hand is </div><div class="data" data-tag="color">blue</div><div class="text"> til </div><div class="data" data-tag="time">03:45</div></div><div class="line"><div class="text">The </div><div class="data" data-tag="name">thing</div><div class="text"> is </div><div class="data" data-tag="color">green</div><div class="text"> til </div><div class="data" data-tag="time">02:15</div></div><div class="line"><div class="text">My </div><div class="data" data-tag="hand">left</div><div class="text"> hand is </div><div class="data" data-tag="color">blue</div><div class="text"> til </div><div class="data" data-tag="time">03:45</div></div><div class="line"><div class="text">The </div><div class="data" data-tag="name">thing</div><div class="text"> is </div><div class="data" data-tag="color">green</div><div class="text"> til </div><div class="data" data-tag="time">02:15</div></div><div class="line"><div class="text">My </div><div class="data" data-tag="hand">left</div><div class="text"> hand is </div><div class="data" data-tag="color">blue</div><div class="text"> til </div><div class="data" data-tag="time">03:45</div></div><div class="line"><div class="text">The </div><div class="data" data-tag="name">thing</div><div class="text"> is </div><div class="data" data-tag="color">green</div><div class="text"> til </div><div class="data" data-tag="time">02:15</div></div><div class="line"><div class="text">My </div><div class="data" data-tag="hand">left</div><div class="text"> hand is </div><div class="data" data-tag="color">blue</div><div class="text"> til </div><div class="data" data-tag="time">03:45</div></div><div class="line"><div class="text">The </div><div class="data" data-tag="name">thing</div><div class="text"> is </div><div class="data" data-tag="color">green</div><div class="text"> til </div><div class="data" data-tag="time">02:15</div></div><div class="line"><div class="text">My </div><div class="data" data-tag="hand">left</div><div class="text"> hand is </div><div class="data" data-tag="color">blue</div><div class="text"> til </div><div class="data" data-tag="time">03:45</div></div><div class="line"><div class="text">The </div><div class="data" data-tag="name">thing</div><div class="text"> is </div><div class="data" data-tag="color">green</div><div class="text"> til </div><div class="data" data-tag="time">02:15</div></div><div class="line"><div class="text">My </div><div class="data" data-tag="hand">left</div><div class="text"> hand is </div><div class="data" data-tag="color">blue</div><div class="text"> til </div><div class="data" data-tag="time">03:45</div></div><div class="line"><div class="text">The </div><div class="data" data-tag="name">thing</div><div class="text"> is </div><div class="data" data-tag="color">green</div><div class="text"> til </div><div class="data" data-tag="time">02:15</div></div><div class="line"><div class="text">My </div><div class="data" data-tag="hand">left</div><div class="text"> hand is </div><div class="data" data-tag="color">blue</div><div class="text"> til </div><div class="data" data-tag="time">03:45</div></div><div class="line"><div class="text">The </div><div class="data" data-tag="name">thing</div><div class="text"> is </div><div class="data" data-tag="color">green</div><div class="text"> til </div><div class="data" data-tag="time">02:15</div></div><div class="line"><div class="text">My </div><div class="data" data-tag="hand">left</div><div class="text"> hand is </div><div class="data" data-tag="color">blue</div><div class="text"> til </div><div class="data" data-tag="time">03:45</div></div>
|
0
contrib/libxo/tests/core/saved/test_12.HIPx.err
Normal file
0
contrib/libxo/tests/core/saved/test_12.HIPx.err
Normal file
160
contrib/libxo/tests/core/saved/test_12.HIPx.out
Normal file
160
contrib/libxo/tests/core/saved/test_12.HIPx.out
Normal file
@ -0,0 +1,160 @@
|
||||
<div class="line">
|
||||
<div class="text">The </div>
|
||||
<div class="data" data-tag="name" data-xpath="/top/data/thing/name">thing</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="color" data-xpath="/top/data/thing[name = 'thing']/color">green</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time" data-xpath="/top/data/thing[name = 'thing']/time">02:15</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">My </div>
|
||||
<div class="data" data-tag="hand" data-xpath="/top/data/thing[name = 'thing']/hand">left</div>
|
||||
<div class="text"> hand is </div>
|
||||
<div class="data" data-tag="color" data-xpath="/top/data/thing[name = 'thing']/color">blue</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time" data-xpath="/top/data/thing[name = 'thing']/time">03:45</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The </div>
|
||||
<div class="data" data-tag="name" data-xpath="/top/data/thing/name">thing</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="color" data-xpath="/top/data/thing[name = 'thing']/color">green</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time" data-xpath="/top/data/thing[name = 'thing']/time">02:15</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">My </div>
|
||||
<div class="data" data-tag="hand" data-xpath="/top/data/thing[name = 'thing']/hand">left</div>
|
||||
<div class="text"> hand is </div>
|
||||
<div class="data" data-tag="color" data-xpath="/top/data/thing[name = 'thing']/color">blue</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time" data-xpath="/top/data/thing[name = 'thing']/time">03:45</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The </div>
|
||||
<div class="data" data-tag="name" data-xpath="/top/data/thing/name">thing</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="color" data-xpath="/top/data/thing[name = 'thing']/color">green</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time" data-xpath="/top/data/thing[name = 'thing']/time">02:15</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">My </div>
|
||||
<div class="data" data-tag="hand" data-xpath="/top/data/thing[name = 'thing']/hand">left</div>
|
||||
<div class="text"> hand is </div>
|
||||
<div class="data" data-tag="color" data-xpath="/top/data/thing[name = 'thing']/color">blue</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time" data-xpath="/top/data/thing[name = 'thing']/time">03:45</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The </div>
|
||||
<div class="data" data-tag="name" data-xpath="/top/data/thing/name">thing</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="color" data-xpath="/top/data/thing[name = 'thing']/color">green</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time" data-xpath="/top/data/thing[name = 'thing']/time">02:15</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">My </div>
|
||||
<div class="data" data-tag="hand" data-xpath="/top/data/thing[name = 'thing']/hand">left</div>
|
||||
<div class="text"> hand is </div>
|
||||
<div class="data" data-tag="color" data-xpath="/top/data/thing[name = 'thing']/color">blue</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time" data-xpath="/top/data/thing[name = 'thing']/time">03:45</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The </div>
|
||||
<div class="data" data-tag="name" data-xpath="/top/data/thing/name">thing</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="color" data-xpath="/top/data/thing[name = 'thing']/color">green</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time" data-xpath="/top/data/thing[name = 'thing']/time">02:15</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">My </div>
|
||||
<div class="data" data-tag="hand" data-xpath="/top/data/thing[name = 'thing']/hand">left</div>
|
||||
<div class="text"> hand is </div>
|
||||
<div class="data" data-tag="color" data-xpath="/top/data/thing[name = 'thing']/color">blue</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time" data-xpath="/top/data/thing[name = 'thing']/time">03:45</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The </div>
|
||||
<div class="data" data-tag="name" data-xpath="/top/data/thing/name">thing</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="color" data-xpath="/top/data/thing[name = 'thing']/color">green</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time" data-xpath="/top/data/thing[name = 'thing']/time">02:15</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">My </div>
|
||||
<div class="data" data-tag="hand" data-xpath="/top/data/thing[name = 'thing']/hand">left</div>
|
||||
<div class="text"> hand is </div>
|
||||
<div class="data" data-tag="color" data-xpath="/top/data/thing[name = 'thing']/color">blue</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time" data-xpath="/top/data/thing[name = 'thing']/time">03:45</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The </div>
|
||||
<div class="data" data-tag="name" data-xpath="/top/data/thing/name">thing</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="color" data-xpath="/top/data/thing[name = 'thing']/color">green</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time" data-xpath="/top/data/thing[name = 'thing']/time">02:15</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">My </div>
|
||||
<div class="data" data-tag="hand" data-xpath="/top/data/thing[name = 'thing']/hand">left</div>
|
||||
<div class="text"> hand is </div>
|
||||
<div class="data" data-tag="color" data-xpath="/top/data/thing[name = 'thing']/color">blue</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time" data-xpath="/top/data/thing[name = 'thing']/time">03:45</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The </div>
|
||||
<div class="data" data-tag="name" data-xpath="/top/data/thing/name">thing</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="color" data-xpath="/top/data/thing[name = 'thing']/color">green</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time" data-xpath="/top/data/thing[name = 'thing']/time">02:15</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">My </div>
|
||||
<div class="data" data-tag="hand" data-xpath="/top/data/thing[name = 'thing']/hand">left</div>
|
||||
<div class="text"> hand is </div>
|
||||
<div class="data" data-tag="color" data-xpath="/top/data/thing[name = 'thing']/color">blue</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time" data-xpath="/top/data/thing[name = 'thing']/time">03:45</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The </div>
|
||||
<div class="data" data-tag="name" data-xpath="/top/data/thing/name">thing</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="color" data-xpath="/top/data/thing[name = 'thing']/color">green</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time" data-xpath="/top/data/thing[name = 'thing']/time">02:15</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">My </div>
|
||||
<div class="data" data-tag="hand" data-xpath="/top/data/thing[name = 'thing']/hand">left</div>
|
||||
<div class="text"> hand is </div>
|
||||
<div class="data" data-tag="color" data-xpath="/top/data/thing[name = 'thing']/color">blue</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time" data-xpath="/top/data/thing[name = 'thing']/time">03:45</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The </div>
|
||||
<div class="data" data-tag="name" data-xpath="/top/data/thing/name">thing</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="color" data-xpath="/top/data/thing[name = 'thing']/color">green</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time" data-xpath="/top/data/thing[name = 'thing']/time">02:15</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">My </div>
|
||||
<div class="data" data-tag="hand" data-xpath="/top/data/thing[name = 'thing']/hand">left</div>
|
||||
<div class="text"> hand is </div>
|
||||
<div class="data" data-tag="color" data-xpath="/top/data/thing[name = 'thing']/color">blue</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time" data-xpath="/top/data/thing[name = 'thing']/time">03:45</div>
|
||||
</div>
|
0
contrib/libxo/tests/core/saved/test_12.HP.err
Normal file
0
contrib/libxo/tests/core/saved/test_12.HP.err
Normal file
160
contrib/libxo/tests/core/saved/test_12.HP.out
Normal file
160
contrib/libxo/tests/core/saved/test_12.HP.out
Normal file
@ -0,0 +1,160 @@
|
||||
<div class="line">
|
||||
<div class="text">The </div>
|
||||
<div class="data" data-tag="name">thing</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="color">green</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time">02:15</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">My </div>
|
||||
<div class="data" data-tag="hand">left</div>
|
||||
<div class="text"> hand is </div>
|
||||
<div class="data" data-tag="color">blue</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time">03:45</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The </div>
|
||||
<div class="data" data-tag="name">thing</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="color">green</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time">02:15</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">My </div>
|
||||
<div class="data" data-tag="hand">left</div>
|
||||
<div class="text"> hand is </div>
|
||||
<div class="data" data-tag="color">blue</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time">03:45</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The </div>
|
||||
<div class="data" data-tag="name">thing</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="color">green</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time">02:15</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">My </div>
|
||||
<div class="data" data-tag="hand">left</div>
|
||||
<div class="text"> hand is </div>
|
||||
<div class="data" data-tag="color">blue</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time">03:45</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The </div>
|
||||
<div class="data" data-tag="name">thing</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="color">green</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time">02:15</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">My </div>
|
||||
<div class="data" data-tag="hand">left</div>
|
||||
<div class="text"> hand is </div>
|
||||
<div class="data" data-tag="color">blue</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time">03:45</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The </div>
|
||||
<div class="data" data-tag="name">thing</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="color">green</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time">02:15</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">My </div>
|
||||
<div class="data" data-tag="hand">left</div>
|
||||
<div class="text"> hand is </div>
|
||||
<div class="data" data-tag="color">blue</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time">03:45</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The </div>
|
||||
<div class="data" data-tag="name">thing</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="color">green</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time">02:15</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">My </div>
|
||||
<div class="data" data-tag="hand">left</div>
|
||||
<div class="text"> hand is </div>
|
||||
<div class="data" data-tag="color">blue</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time">03:45</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The </div>
|
||||
<div class="data" data-tag="name">thing</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="color">green</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time">02:15</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">My </div>
|
||||
<div class="data" data-tag="hand">left</div>
|
||||
<div class="text"> hand is </div>
|
||||
<div class="data" data-tag="color">blue</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time">03:45</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The </div>
|
||||
<div class="data" data-tag="name">thing</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="color">green</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time">02:15</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">My </div>
|
||||
<div class="data" data-tag="hand">left</div>
|
||||
<div class="text"> hand is </div>
|
||||
<div class="data" data-tag="color">blue</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time">03:45</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The </div>
|
||||
<div class="data" data-tag="name">thing</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="color">green</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time">02:15</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">My </div>
|
||||
<div class="data" data-tag="hand">left</div>
|
||||
<div class="text"> hand is </div>
|
||||
<div class="data" data-tag="color">blue</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time">03:45</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">The </div>
|
||||
<div class="data" data-tag="name">thing</div>
|
||||
<div class="text"> is </div>
|
||||
<div class="data" data-tag="color">green</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time">02:15</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="text">My </div>
|
||||
<div class="data" data-tag="hand">left</div>
|
||||
<div class="text"> hand is </div>
|
||||
<div class="data" data-tag="color">blue</div>
|
||||
<div class="text"> til </div>
|
||||
<div class="data" data-tag="time">03:45</div>
|
||||
</div>
|
0
contrib/libxo/tests/core/saved/test_12.J.err
Normal file
0
contrib/libxo/tests/core/saved/test_12.J.err
Normal file
2
contrib/libxo/tests/core/saved/test_12.J.out
Normal file
2
contrib/libxo/tests/core/saved/test_12.J.out
Normal file
@ -0,0 +1,2 @@
|
||||
{"top": {"data": {"thing": [{"name":"thing","color":"green","time":2:15,"hand":"left","color":"blue","time":3:45}, {"name":"thing","color":"green","time":2:15,"hand":"left","color":"blue","time":3:45}, {"name":"thing","color":"green","time":2:15,"hand":"left","color":"blue","time":3:45}, {"name":"thing","color":"green","time":2:15,"hand":"left","color":"blue","time":3:45}, {"name":"thing","color":"green","time":2:15,"hand":"left","color":"blue","time":3:45}, {"name":"thing","color":"green","time":2:15,"hand":"left","color":"blue","time":3:45}, {"name":"thing","color":"green","time":2:15,"hand":"left","color":"blue","time":3:45}, {"name":"thing","color":"green","time":2:15,"hand":"left","color":"blue","time":3:45}, {"name":"thing","color":"green","time":2:15,"hand":"left","color":"blue","time":3:45}, {"name":"thing","color":"green","time":2:15,"hand":"left","color":"blue","time":3:45}]}}
|
||||
}
|
0
contrib/libxo/tests/core/saved/test_12.JP.err
Normal file
0
contrib/libxo/tests/core/saved/test_12.JP.err
Normal file
88
contrib/libxo/tests/core/saved/test_12.JP.out
Normal file
88
contrib/libxo/tests/core/saved/test_12.JP.out
Normal file
@ -0,0 +1,88 @@
|
||||
{
|
||||
"top": {
|
||||
"data": {
|
||||
"thing": [
|
||||
{
|
||||
"name": "thing",
|
||||
"color": "green",
|
||||
"time": 2:15,
|
||||
"hand": "left",
|
||||
"color": "blue",
|
||||
"time": 3:45
|
||||
},
|
||||
{
|
||||
"name": "thing",
|
||||
"color": "green",
|
||||
"time": 2:15,
|
||||
"hand": "left",
|
||||
"color": "blue",
|
||||
"time": 3:45
|
||||
},
|
||||
{
|
||||
"name": "thing",
|
||||
"color": "green",
|
||||
"time": 2:15,
|
||||
"hand": "left",
|
||||
"color": "blue",
|
||||
"time": 3:45
|
||||
},
|
||||
{
|
||||
"name": "thing",
|
||||
"color": "green",
|
||||
"time": 2:15,
|
||||
"hand": "left",
|
||||
"color": "blue",
|
||||
"time": 3:45
|
||||
},
|
||||
{
|
||||
"name": "thing",
|
||||
"color": "green",
|
||||
"time": 2:15,
|
||||
"hand": "left",
|
||||
"color": "blue",
|
||||
"time": 3:45
|
||||
},
|
||||
{
|
||||
"name": "thing",
|
||||
"color": "green",
|
||||
"time": 2:15,
|
||||
"hand": "left",
|
||||
"color": "blue",
|
||||
"time": 3:45
|
||||
},
|
||||
{
|
||||
"name": "thing",
|
||||
"color": "green",
|
||||
"time": 2:15,
|
||||
"hand": "left",
|
||||
"color": "blue",
|
||||
"time": 3:45
|
||||
},
|
||||
{
|
||||
"name": "thing",
|
||||
"color": "green",
|
||||
"time": 2:15,
|
||||
"hand": "left",
|
||||
"color": "blue",
|
||||
"time": 3:45
|
||||
},
|
||||
{
|
||||
"name": "thing",
|
||||
"color": "green",
|
||||
"time": 2:15,
|
||||
"hand": "left",
|
||||
"color": "blue",
|
||||
"time": 3:45
|
||||
},
|
||||
{
|
||||
"name": "thing",
|
||||
"color": "green",
|
||||
"time": 2:15,
|
||||
"hand": "left",
|
||||
"color": "blue",
|
||||
"time": 3:45
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
0
contrib/libxo/tests/core/saved/test_12.T.err
Normal file
0
contrib/libxo/tests/core/saved/test_12.T.err
Normal file
20
contrib/libxo/tests/core/saved/test_12.T.out
Normal file
20
contrib/libxo/tests/core/saved/test_12.T.out
Normal file
@ -0,0 +1,20 @@
|
||||
The thing is green til 02:15
|
||||
My left hand is blue til 03:45
|
||||
The thing is green til 02:15
|
||||
My left hand is blue til 03:45
|
||||
The thing is green til 02:15
|
||||
My left hand is blue til 03:45
|
||||
The thing is green til 02:15
|
||||
My left hand is blue til 03:45
|
||||
The thing is green til 02:15
|
||||
My left hand is blue til 03:45
|
||||
The thing is green til 02:15
|
||||
My left hand is blue til 03:45
|
||||
The thing is green til 02:15
|
||||
My left hand is blue til 03:45
|
||||
The thing is green til 02:15
|
||||
My left hand is blue til 03:45
|
||||
The thing is green til 02:15
|
||||
My left hand is blue til 03:45
|
||||
The thing is green til 02:15
|
||||
My left hand is blue til 03:45
|
0
contrib/libxo/tests/core/saved/test_12.X.err
Normal file
0
contrib/libxo/tests/core/saved/test_12.X.err
Normal file
1
contrib/libxo/tests/core/saved/test_12.X.out
Normal file
1
contrib/libxo/tests/core/saved/test_12.X.out
Normal file
@ -0,0 +1 @@
|
||||
<top><data><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing><thing><name>thing</name><color>green</color><time>2:15</time><hand>left</hand><color>blue</color><time>3:45</time></thing></data></top>
|
0
contrib/libxo/tests/core/saved/test_12.XP.err
Normal file
0
contrib/libxo/tests/core/saved/test_12.XP.err
Normal file
84
contrib/libxo/tests/core/saved/test_12.XP.out
Normal file
84
contrib/libxo/tests/core/saved/test_12.XP.out
Normal file
@ -0,0 +1,84 @@
|
||||
<top>
|
||||
<data>
|
||||
<thing>
|
||||
<name>thing</name>
|
||||
<color>green</color>
|
||||
<time>2:15</time>
|
||||
<hand>left</hand>
|
||||
<color>blue</color>
|
||||
<time>3:45</time>
|
||||
</thing>
|
||||
<thing>
|
||||
<name>thing</name>
|
||||
<color>green</color>
|
||||
<time>2:15</time>
|
||||
<hand>left</hand>
|
||||
<color>blue</color>
|
||||
<time>3:45</time>
|
||||
</thing>
|
||||
<thing>
|
||||
<name>thing</name>
|
||||
<color>green</color>
|
||||
<time>2:15</time>
|
||||
<hand>left</hand>
|
||||
<color>blue</color>
|
||||
<time>3:45</time>
|
||||
</thing>
|
||||
<thing>
|
||||
<name>thing</name>
|
||||
<color>green</color>
|
||||
<time>2:15</time>
|
||||
<hand>left</hand>
|
||||
<color>blue</color>
|
||||
<time>3:45</time>
|
||||
</thing>
|
||||
<thing>
|
||||
<name>thing</name>
|
||||
<color>green</color>
|
||||
<time>2:15</time>
|
||||
<hand>left</hand>
|
||||
<color>blue</color>
|
||||
<time>3:45</time>
|
||||
</thing>
|
||||
<thing>
|
||||
<name>thing</name>
|
||||
<color>green</color>
|
||||
<time>2:15</time>
|
||||
<hand>left</hand>
|
||||
<color>blue</color>
|
||||
<time>3:45</time>
|
||||
</thing>
|
||||
<thing>
|
||||
<name>thing</name>
|
||||
<color>green</color>
|
||||
<time>2:15</time>
|
||||
<hand>left</hand>
|
||||
<color>blue</color>
|
||||
<time>3:45</time>
|
||||
</thing>
|
||||
<thing>
|
||||
<name>thing</name>
|
||||
<color>green</color>
|
||||
<time>2:15</time>
|
||||
<hand>left</hand>
|
||||
<color>blue</color>
|
||||
<time>3:45</time>
|
||||
</thing>
|
||||
<thing>
|
||||
<name>thing</name>
|
||||
<color>green</color>
|
||||
<time>2:15</time>
|
||||
<hand>left</hand>
|
||||
<color>blue</color>
|
||||
<time>3:45</time>
|
||||
</thing>
|
||||
<thing>
|
||||
<name>thing</name>
|
||||
<color>green</color>
|
||||
<time>2:15</time>
|
||||
<hand>left</hand>
|
||||
<color>blue</color>
|
||||
<time>3:45</time>
|
||||
</thing>
|
||||
</data>
|
||||
</top>
|
@ -79,6 +79,18 @@ main (int argc, char **argv)
|
||||
|
||||
xo_open_container_h(NULL, "top");
|
||||
|
||||
xo_emit("testing argument modifier {a:}.{a:}...\n",
|
||||
"host", "my-box", "domain", "example.com");
|
||||
|
||||
xo_emit("testing argument modifier with encoding to {ea:}.{a:}...\n",
|
||||
"host", "my-box", "domain", "example.com");
|
||||
|
||||
xo_emit("{La:} {a:}\n", "Label text", "label", "value");
|
||||
|
||||
xo_emit_field("Vt", "max-chaos", NULL, NULL, " very ");
|
||||
xo_emit_field("V", "min-chaos", "%d", NULL, 42);
|
||||
xo_emit_field("V", "some-chaos", "%d\n", "[%d]", 42);
|
||||
|
||||
xo_emit("Connecting to {:host}.{:domain}...\n", "my-box", "example.com");
|
||||
|
||||
xo_attr("test", "value");
|
||||
@ -169,6 +181,16 @@ main (int argc, char **argv)
|
||||
xo_emit("X{P: }X{Lwc:Cost}{:cost/%u}\n", 425);
|
||||
xo_emit("X{P:/%30s}X{Lwc:Cost}{:cost/%u}\n", "", 455);
|
||||
|
||||
xo_emit("{e:mode/%s}{e:mode_octal/%s} {t:links/%s} "
|
||||
"{t:user/%s} {t:group/%s} \n",
|
||||
"mode", "octal", "links",
|
||||
"user", "group", "extra1", "extra2", "extra3");
|
||||
|
||||
xo_emit("{t:mode/%s}{e:mode_octal/%03o} {t:links/%*u} "
|
||||
"{t:user/%-*s} {t:group/%-*s} \n",
|
||||
"/some/file", (int) 0640, 8, 1,
|
||||
10, "user", 12, "group");
|
||||
|
||||
xo_close_container_h(NULL, "top");
|
||||
|
||||
xo_finish();
|
||||
|
@ -42,6 +42,7 @@ main (int argc, char **argv)
|
||||
}
|
||||
|
||||
xo_set_flags(NULL, XOF_UNITS); /* Always test w/ this */
|
||||
xo_set_file(stdout);
|
||||
|
||||
xo_open_container_h(NULL, "top");
|
||||
|
||||
|
76
contrib/libxo/tests/core/test_12.c
Normal file
76
contrib/libxo/tests/core/test_12.c
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Juniper Networks, Inc.
|
||||
* All rights reserved.
|
||||
* This SOFTWARE is licensed under the LICENSE provided in the
|
||||
* ../Copyright file. By downloading, installing, copying, or otherwise
|
||||
* using the SOFTWARE, you agree to be bound by the terms of that
|
||||
* LICENSE.
|
||||
* Phil Shafer, July 2014
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "xo_config.h"
|
||||
#include "xo.h"
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int i, count = 10;
|
||||
int mon = 0;
|
||||
xo_emit_flags_t flags = XOEF_RETAIN;
|
||||
|
||||
argc = xo_parse_args(argc, argv);
|
||||
if (argc < 0)
|
||||
return 1;
|
||||
|
||||
for (argc = 1; argv[argc]; argc++) {
|
||||
if (strcmp(argv[argc], "xml") == 0)
|
||||
xo_set_style(NULL, XO_STYLE_XML);
|
||||
else if (strcmp(argv[argc], "json") == 0)
|
||||
xo_set_style(NULL, XO_STYLE_JSON);
|
||||
else if (strcmp(argv[argc], "text") == 0)
|
||||
xo_set_style(NULL, XO_STYLE_TEXT);
|
||||
else if (strcmp(argv[argc], "html") == 0)
|
||||
xo_set_style(NULL, XO_STYLE_HTML);
|
||||
else if (strcmp(argv[argc], "pretty") == 0)
|
||||
xo_set_flags(NULL, XOF_PRETTY);
|
||||
else if (strcmp(argv[argc], "xpath") == 0)
|
||||
xo_set_flags(NULL, XOF_XPATH);
|
||||
else if (strcmp(argv[argc], "info") == 0)
|
||||
xo_set_flags(NULL, XOF_INFO);
|
||||
else if (strcmp(argv[argc], "no-retain") == 0)
|
||||
flags &= ~XOEF_RETAIN;
|
||||
else if (strcmp(argv[argc], "big") == 0) {
|
||||
if (argv[argc + 1])
|
||||
count = atoi(argv[++argc]);
|
||||
}
|
||||
}
|
||||
|
||||
xo_set_flags(NULL, XOF_UNITS); /* Always test w/ this */
|
||||
xo_set_file(stdout);
|
||||
|
||||
xo_open_container("top");
|
||||
xo_open_container("data");
|
||||
|
||||
const char *fmt1 = "The {C:fg-red}{k:name}{C:reset} is "
|
||||
"{C:/fg-%s}{:color}{C:reset} til {:time/%02d:%02d}\n";
|
||||
const char *fmt2 = "My {C:fg-red}{:hand}{C:reset} hand is "
|
||||
"{C:/fg-%s}{:color}{C:reset} til {:time/%02d:%02d}\n";
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
xo_open_instance("thing");
|
||||
xo_emit_f(flags, fmt1, "thing", "green", "green", 2, 15);
|
||||
xo_emit_f(flags, fmt2, "left", "blue", "blue", 3, 45);
|
||||
}
|
||||
|
||||
xo_close_container("data");
|
||||
xo_close_container_h(NULL, "top");
|
||||
|
||||
xo_finish();
|
||||
|
||||
return 0;
|
||||
}
|
@ -26,7 +26,7 @@ int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
static char domainname[] = "gt_01";
|
||||
char path[MAXPATHLEN];
|
||||
static char path[MAXPATHLEN];
|
||||
const char *tzone = "EST";
|
||||
const char *lang = "pig_latin";
|
||||
|
||||
|
@ -133,13 +133,8 @@ _MARCHS+= x86
|
||||
META_TARGETS+= compat copies symlinks
|
||||
stage_includes: ${SHARED}
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
installincludes: ${SHARED}
|
||||
${SHARED}: compat
|
||||
|
||||
# Take care of stale directory-level symlinks.
|
||||
compat: ${META_DEPS}
|
||||
compat:
|
||||
.for i in ${LDIRS} ${LSUBDIRS} machine ${_MARCHS} crypto
|
||||
if [ -L ${DESTDIR}${INCLUDEDIR}/$i ]; then \
|
||||
rm -f ${DESTDIR}${INCLUDEDIR}/$i; \
|
||||
@ -149,7 +144,7 @@ compat: ${META_DEPS}
|
||||
-f ${.CURDIR}/../etc/mtree/BSD.include.dist \
|
||||
-p ${DESTDIR}${INCLUDEDIR} > /dev/null
|
||||
|
||||
copies: ${META_DEPS}
|
||||
copies:
|
||||
.for i in ${LDIRS} ${LSUBDIRS} ${LSUBSUBDIRS} crypto machine machine/pc \
|
||||
${_MARCHS}
|
||||
if [ -d ${DESTDIR}${INCLUDEDIR}/$i ]; then \
|
||||
@ -235,7 +230,7 @@ copies: ${META_DEPS}
|
||||
${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 teken.h \
|
||||
${DESTDIR}${INCLUDEDIR}/teken
|
||||
|
||||
symlinks: ${META_DEPS}
|
||||
symlinks:
|
||||
@${ECHO} "Setting up symlinks to kernel source tree..."
|
||||
.for i in ${LDIRS}
|
||||
cd ${.CURDIR}/../sys/$i; \
|
||||
@ -349,6 +344,11 @@ symlinks: ${META_DEPS}
|
||||
${DESTDIR}${INCLUDEDIR}/rpc; \
|
||||
done
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
installincludes: ${SHARED}
|
||||
${SHARED}: compat
|
||||
|
||||
.if ${MACHINE} == "host" && !defined(_SKIP_BUILD)
|
||||
# we're here because we are building a sysroot...
|
||||
# we need MACHINE et al set correctly
|
||||
|
@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
|
||||
.data
|
||||
.align 3
|
||||
.globl _C_LABEL(minbrk)
|
||||
.hidden _C_LABEL(minbrk)
|
||||
.type _C_LABEL(minbrk),#object
|
||||
_C_LABEL(minbrk):
|
||||
.quad _C_LABEL(_end)
|
||||
|
@ -29,6 +29,7 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
ENTRY(cerror)
|
||||
.hidden cerror
|
||||
sub sp, sp, #16
|
||||
stp x0, lr, [sp]
|
||||
bl _C_LABEL(__error)
|
||||
|
@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
|
||||
.data
|
||||
.align 3
|
||||
.global _C_LABEL(curbrk)
|
||||
.hidden _C_LABEL(curbrk)
|
||||
.type _C_LABEL(curbrk),#object
|
||||
_C_LABEL(curbrk):
|
||||
.quad _C_LABEL(_end)
|
||||
|
@ -632,6 +632,7 @@ dns_getaddrinfo(const nvlist_t *limits, const nvlist_t *nvlin, nvlist_t *nvlout)
|
||||
hints.ai_addrlen = 0;
|
||||
hints.ai_addr = NULL;
|
||||
hints.ai_canonname = NULL;
|
||||
hints.ai_next = NULL;
|
||||
hintsp = &hints;
|
||||
family = hints.ai_family;
|
||||
} else {
|
||||
|
@ -121,7 +121,7 @@ gss_add_cred(OM_uint32 *minor_status,
|
||||
* gss_add_cred for that mechanism, otherwise we copy the mc
|
||||
* to new_cred.
|
||||
*/
|
||||
target_mc = 0;
|
||||
target_mc = NULL;
|
||||
if (cred) {
|
||||
SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
|
||||
if (gss_oid_equal(mc->gmc_mech_oid, desired_mech)) {
|
||||
@ -151,7 +151,7 @@ gss_add_cred(OM_uint32 *minor_status,
|
||||
return (major_status);
|
||||
}
|
||||
} else {
|
||||
mn = 0;
|
||||
mn = NULL;
|
||||
}
|
||||
|
||||
m = _gss_find_mech_switch(desired_mech);
|
||||
|
@ -47,7 +47,7 @@ gss_encapsulate_token(const gss_buffer_t input_token, gss_OID oid,
|
||||
* First time around, we calculate the size, second time, we
|
||||
* encode the token.
|
||||
*/
|
||||
p = 0;
|
||||
p = NULL;
|
||||
for (i = 0; i < 2; i++) {
|
||||
len = 0;
|
||||
|
||||
|
@ -40,13 +40,14 @@ gss_get_mic(OM_uint32 *minor_status,
|
||||
gss_buffer_t message_token)
|
||||
{
|
||||
struct _gss_context *ctx = (struct _gss_context *) context_handle;
|
||||
struct _gss_mech_switch *m = ctx->gc_mech;
|
||||
struct _gss_mech_switch *m;
|
||||
|
||||
_gss_buffer_zero(message_token);
|
||||
if (ctx == NULL) {
|
||||
*minor_status = 0;
|
||||
return (GSS_S_NO_CONTEXT);
|
||||
}
|
||||
m = ctx->gc_mech;
|
||||
|
||||
return (m->gm_get_mic(minor_status, ctx->gc_ctx, qop_req,
|
||||
message_buffer, message_token));
|
||||
|
@ -99,7 +99,7 @@ gss_inquire_context(OM_uint32 *minor_status,
|
||||
if (src_name)
|
||||
gss_release_name(minor_status, src_name);
|
||||
m->gm_release_name(minor_status, &src_mn);
|
||||
minor_status = 0;
|
||||
minor_status = NULL;
|
||||
return (GSS_S_FAILURE);
|
||||
}
|
||||
*targ_name = (gss_name_t) name;
|
||||
|
@ -83,7 +83,7 @@ _gss_string_to_oid(const char* s, gss_OID oid)
|
||||
* out the size. Second time around, we actually encode the
|
||||
* number.
|
||||
*/
|
||||
res = 0;
|
||||
res = NULL;
|
||||
for (i = 0; i < 2; i++) {
|
||||
byte_count = 0;
|
||||
for (p = s, j = 0; p; p = q, j++) {
|
||||
|
@ -48,7 +48,7 @@ gss_pseudo_random(OM_uint32 *minor_status,
|
||||
gss_buffer_t prf_out)
|
||||
{
|
||||
struct _gss_context *ctx = (struct _gss_context *) context;
|
||||
struct _gss_mech_switch *m = ctx->gc_mech;
|
||||
struct _gss_mech_switch *m;
|
||||
OM_uint32 major_status;
|
||||
|
||||
_gss_buffer_zero(prf_out);
|
||||
@ -58,6 +58,7 @@ gss_pseudo_random(OM_uint32 *minor_status,
|
||||
*minor_status = 0;
|
||||
return GSS_S_NO_CONTEXT;
|
||||
}
|
||||
m = ctx->gc_mech;
|
||||
|
||||
if (m->gm_pseudo_random == NULL)
|
||||
return GSS_S_UNAVAILABLE;
|
||||
|
@ -39,7 +39,7 @@ gss_verify_mic(OM_uint32 *minor_status,
|
||||
gss_qop_t *qop_state)
|
||||
{
|
||||
struct _gss_context *ctx = (struct _gss_context *) context_handle;
|
||||
struct _gss_mech_switch *m = ctx->gc_mech;
|
||||
struct _gss_mech_switch *m;
|
||||
|
||||
if (qop_state)
|
||||
*qop_state = 0;
|
||||
@ -47,6 +47,7 @@ gss_verify_mic(OM_uint32 *minor_status,
|
||||
*minor_status = 0;
|
||||
return (GSS_S_NO_CONTEXT);
|
||||
}
|
||||
m = ctx->gc_mech;
|
||||
|
||||
return (m->gm_verify_mic(minor_status, ctx->gc_ctx,
|
||||
message_buffer, token_buffer, qop_state));
|
||||
|
@ -42,7 +42,7 @@ gss_wrap(OM_uint32 *minor_status,
|
||||
gss_buffer_t output_message_buffer)
|
||||
{
|
||||
struct _gss_context *ctx = (struct _gss_context *) context_handle;
|
||||
struct _gss_mech_switch *m = ctx->gc_mech;
|
||||
struct _gss_mech_switch *m;
|
||||
|
||||
if (conf_state)
|
||||
*conf_state = 0;
|
||||
@ -51,6 +51,7 @@ gss_wrap(OM_uint32 *minor_status,
|
||||
*minor_status = 0;
|
||||
return (GSS_S_NO_CONTEXT);
|
||||
}
|
||||
m = ctx->gc_mech;
|
||||
|
||||
return (m->gm_wrap(minor_status, ctx->gc_ctx,
|
||||
conf_req_flag, qop_req, input_message_buffer,
|
||||
|
@ -40,13 +40,14 @@ gss_wrap_size_limit(OM_uint32 *minor_status,
|
||||
OM_uint32 *max_input_size)
|
||||
{
|
||||
struct _gss_context *ctx = (struct _gss_context *) context_handle;
|
||||
struct _gss_mech_switch *m = ctx->gc_mech;
|
||||
struct _gss_mech_switch *m;
|
||||
|
||||
*max_input_size = 0;
|
||||
if (ctx == NULL) {
|
||||
*minor_status = 0;
|
||||
return (GSS_S_NO_CONTEXT);
|
||||
}
|
||||
m = ctx->gc_mech;
|
||||
|
||||
return (m->gm_wrap_size_limit(minor_status, ctx->gc_ctx,
|
||||
conf_req_flag, qop_req, req_output_size, max_input_size));
|
||||
|
@ -40,7 +40,7 @@ magic.mgc: mkmagic magic
|
||||
|
||||
CLEANFILES+= mkmagic
|
||||
build-tools: mkmagic
|
||||
mkmagic: apprentice.c cdf_time.c encoding.c funcs.c magic.c print.c
|
||||
mkmagic: apprentice.c cdf_time.c encoding.c funcs.c magic.c print.c ${BUILD_TOOLS_META}
|
||||
${CC} ${CFLAGS} -DCOMPILE_ONLY ${LDFLAGS} -o ${.TARGET} ${.ALLSRC} \
|
||||
${LDADD}
|
||||
|
||||
|
@ -24,8 +24,11 @@
|
||||
#
|
||||
# $FreeBSD$
|
||||
|
||||
# The modules must be built first, because they are built into the
|
||||
# static version of libpam.
|
||||
SUBDIR+= modules libpam static_modules
|
||||
# The modules link in libpam. They build the static modules as well.
|
||||
SUBDIR+= libpam modules
|
||||
SUBDIR_DEPEND_modules= libpam
|
||||
SUBDIR+= static_libpam
|
||||
SUBDIR_DEPEND_static_libpam= modules
|
||||
SUBDIR_PARALLEL=
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
|
@ -39,7 +39,11 @@ PACKAGE=lib${LIB}
|
||||
OPENPAM= ${.CURDIR}/../../../contrib/openpam
|
||||
.PATH: ${OPENPAM}/include ${OPENPAM}/lib/libpam ${OPENPAM}/doc/man
|
||||
|
||||
LIB= pam
|
||||
# static_libpam will build libpam.a
|
||||
.if !defined(LIB)
|
||||
SHLIB= pam
|
||||
.endif
|
||||
|
||||
MK_PROFILE=no
|
||||
|
||||
SRCS= openpam_asprintf.c \
|
||||
@ -99,7 +103,7 @@ SRCS= openpam_asprintf.c \
|
||||
# Local additions
|
||||
SRCS+= pam_debug_log.c
|
||||
|
||||
MAN= openpam.3 \
|
||||
MAN?= openpam.3 \
|
||||
openpam_borrow_cred.3 \
|
||||
openpam_free_data.3 \
|
||||
openpam_free_envlist.3 \
|
||||
@ -151,10 +155,10 @@ MAN= openpam.3 \
|
||||
pam_vprompt.3 \
|
||||
pam.conf.5
|
||||
|
||||
MLINKS= pam.conf.5 pam.d.5
|
||||
MLINKS?= pam.conf.5 pam.d.5
|
||||
|
||||
CSTD?= c99
|
||||
CFLAGS+= -I${.CURDIR} -I${OPENPAM}/include
|
||||
CFLAGS+= -I${OPENPAM}/include
|
||||
CFLAGS+= -DLIB_MAJ=${SHLIB_MAJOR}
|
||||
CFLAGS+= -DHAVE_DLFUNC=1
|
||||
CFLAGS+= -DHAVE_FDLOPEN=1
|
||||
@ -173,7 +177,7 @@ HEADERS= security/openpam.h \
|
||||
ADD_HEADERS= security/pam_mod_misc.h
|
||||
|
||||
# Headers
|
||||
INCS= ${HEADERS} ${ADD_HEADERS}
|
||||
INCS?= ${HEADERS} ${ADD_HEADERS}
|
||||
INCSDIR= ${INCLUDEDIR}/security
|
||||
|
||||
.include <src.opts.mk>
|
||||
|
@ -27,5 +27,6 @@
|
||||
.include "modules.inc"
|
||||
|
||||
SUBDIR= ${MODULES}
|
||||
SUBDIR_PARALLEL=
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
|
@ -7,14 +7,7 @@ MK_PROFILE= no
|
||||
|
||||
CFLAGS+= -I${PAMDIR}/include -I${.CURDIR}/../../libpam
|
||||
|
||||
# This is nasty.
|
||||
# For the static case, libpam.a depends on the modules.
|
||||
# For the dynamic case, the modules depend on libpam.so.N
|
||||
.if defined(_NO_LIBPAM_SO_YET)
|
||||
NO_PIC=
|
||||
.else
|
||||
SHLIB_NAME?= ${LIB}.so.${SHLIB_MAJOR}
|
||||
LIBADD+= pam
|
||||
.endif
|
||||
|
||||
.include "../Makefile.inc"
|
||||
|
@ -35,15 +35,17 @@
|
||||
#
|
||||
# $FreeBSD$
|
||||
|
||||
OPENPAM= ${.CURDIR:H:H:H}/contrib/openpam
|
||||
.PATH: ${OPENPAM}/lib
|
||||
.PATH: ${OPENPAM}/lib/libpam
|
||||
.PATH: ${.CURDIR}/../libpam
|
||||
|
||||
all:
|
||||
|
||||
SRCS = openpam_static.c
|
||||
# Only build the static library.
|
||||
LIB= pam
|
||||
NO_PIC=
|
||||
|
||||
# Avoid redundancy with the master Makefile.
|
||||
MAN=
|
||||
INCS=
|
||||
MLINKS=
|
||||
MK_TESTS= no
|
||||
|
||||
#
|
||||
# Static modules
|
||||
@ -61,11 +63,7 @@ STATICOBJS+= openpam_static_modules.o
|
||||
CLEANFILES+= openpam_static.o \
|
||||
openpam_static_modules.o
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
.if empty(_SKIP_BUILD)
|
||||
openpam_static_modules.o: openpam_static.o ${STATIC_MODULES}
|
||||
${LD} -o ${.TARGET} -r --whole-archive ${.ALLSRC}
|
||||
|
||||
all: ${STATICOBJS}
|
||||
.endif
|
||||
.include "${.CURDIR}/../libpam/Makefile"
|
@ -46,7 +46,7 @@
|
||||
|
||||
#define CPU_SPINWAIT
|
||||
#define DTV_OFFSET offsetof(struct tcb, tcb_dtv)
|
||||
#define TP_OFFSET 0x10
|
||||
#define TP_OFFSET sizeof(struct tcb)
|
||||
|
||||
/*
|
||||
* Variant I tcb. The structure layout is fixed, don't blindly
|
||||
|
@ -3,10 +3,10 @@
|
||||
.Fx
|
||||
uses
|
||||
.Nm libxo
|
||||
version 0.4.6.
|
||||
version 0.6.1.
|
||||
Complete documentation can be found on github:
|
||||
.Bd -literal -offset indent
|
||||
http://juniper.github.io/libxo/0.4.6/libxo\-manual.html
|
||||
http://juniper.github.io/libxo/0.6.1/libxo\-manual.html
|
||||
.Ed
|
||||
.Pp
|
||||
.Nm libxo
|
||||
|
@ -88,6 +88,9 @@
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the <monitor.h> header file. */
|
||||
/* #undef HAVE_MONITOR_H */
|
||||
|
||||
/* Support printflike */
|
||||
/* #undef HAVE_PRINTFLIKE */
|
||||
|
||||
@ -180,16 +183,16 @@
|
||||
/* #undef LIBXO_TEXT_ONLY */
|
||||
|
||||
/* Version number as dotted value */
|
||||
#define LIBXO_VERSION "0.4.6"
|
||||
#define LIBXO_VERSION "0.6.1"
|
||||
|
||||
/* Version number extra information */
|
||||
#define LIBXO_VERSION_EXTRA ""
|
||||
|
||||
/* Version number as a number */
|
||||
#define LIBXO_VERSION_NUMBER 4006
|
||||
#define LIBXO_VERSION_NUMBER 6001
|
||||
|
||||
/* Version number as string */
|
||||
#define LIBXO_VERSION_STRING "4006"
|
||||
#define LIBXO_VERSION_STRING "6001"
|
||||
|
||||
/* Enable local wcwidth implementation */
|
||||
#define LIBXO_WCWIDTH 1
|
||||
@ -207,7 +210,7 @@
|
||||
#define PACKAGE_NAME "libxo"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "libxo 0.4.6"
|
||||
#define PACKAGE_STRING "libxo 0.6.1"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "libxo"
|
||||
@ -216,7 +219,7 @@
|
||||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "0.4.6"
|
||||
#define PACKAGE_VERSION "0.6.1"
|
||||
|
||||
/* If using the C implementation of alloca, define if you know the
|
||||
direction of stack growth for your system; otherwise it will be
|
||||
@ -230,7 +233,10 @@
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "0.4.6"
|
||||
#define VERSION "0.6.1"
|
||||
|
||||
/* Retain hash bucket size */
|
||||
/* #undef XO_RETAIN_SIZE */
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
|
@ -65,7 +65,7 @@ int
|
||||
ypclnt_havepasswdd(ypclnt_t *ypclnt)
|
||||
{
|
||||
struct netconfig *nc = NULL;
|
||||
void *localhandle = 0;
|
||||
void *localhandle = NULL;
|
||||
CLIENT *clnt = NULL;
|
||||
int ret;
|
||||
|
||||
@ -139,7 +139,7 @@ yppasswd_local(ypclnt_t *ypclnt, const struct passwd *pwd)
|
||||
struct master_yppasswd yppwd;
|
||||
struct rpc_err rpcerr;
|
||||
struct netconfig *nc = NULL;
|
||||
void *localhandle = 0;
|
||||
void *localhandle = NULL;
|
||||
CLIENT *clnt = NULL;
|
||||
int ret, *result;
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
PACKAGE=tests
|
||||
FILESGROUPS= TESTS
|
||||
TESTSPACKAGE= ${PACKAGE}
|
||||
@ -50,7 +52,10 @@ TAP_TESTS_C+= ctrig_test
|
||||
TAP_TESTS_C+= exponential_test
|
||||
TAP_TESTS_C+= fenv_test
|
||||
TAP_TESTS_C+= fma_test
|
||||
# clang 3.8.0 fails always fails this test. See: bug 208703
|
||||
.if ! (${COMPILER_TYPE} == "clang" && ${COMPILER_VERSION} == 30800)
|
||||
TAP_TESTS_C+= fmaxmin_test
|
||||
.endif
|
||||
TAP_TESTS_C+= ilogb_test
|
||||
TAP_TESTS_C+= invtrig_test
|
||||
TAP_TESTS_C+= invctrig_test
|
||||
|
@ -390,10 +390,10 @@ keys.list: MKkeys_list.sh Caps
|
||||
# Build tools
|
||||
build-tools: make_hash make_keys
|
||||
|
||||
make_keys: make_keys.c names.c ncurses_def.h ${HEADERS}
|
||||
make_keys: make_keys.c names.c ncurses_def.h ${HEADERS} ${BUILD_TOOLS_META}
|
||||
${CC} -o $@ ${CFLAGS} ${NCURSES_DIR}/ncurses/tinfo/make_keys.c
|
||||
|
||||
make_hash: make_hash.c hashsize.h ncurses_def.h ${HEADERS}
|
||||
make_hash: make_hash.c hashsize.h ncurses_def.h ${HEADERS} ${BUILD_TOOLS_META}
|
||||
${CC} -o $@ ${CFLAGS} -DMAIN_PROGRAM \
|
||||
${NCURSES_DIR}/ncurses/tinfo/make_hash.c
|
||||
|
||||
|
@ -200,7 +200,7 @@ bootonly: packagesystem
|
||||
MK_GAMES=no MK_GROFF=no \
|
||||
MK_INSTALLLIB=no MK_LIB32=no MK_MAIL=no \
|
||||
MK_NCP=no MK_TOOLCHAIN=no MK_PROFILE=no \
|
||||
MK_INSTALLIB=no MK_RESCUE=no MK_DICT=no \
|
||||
MK_RESCUE=no MK_DICT=no \
|
||||
MK_KERNEL_SYMBOLS=no MK_TESTS=no MK_DEBUG_FILES=no
|
||||
# Copy manifest only (no distfiles) to get checksums
|
||||
mkdir -p ${.TARGET}/usr/freebsd-dist
|
||||
|
@ -41,7 +41,7 @@
|
||||
.\" ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
.\" SOFTWARE.
|
||||
.\"
|
||||
.Dd March 28, 2016
|
||||
.Dd April 14, 2016
|
||||
.Dt DEVD.CONF 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -501,6 +501,23 @@ Information about the state of the system.
|
||||
Notification that the system has woken from the suspended state.
|
||||
.El
|
||||
.El
|
||||
.Pp
|
||||
.It Li CAM
|
||||
Events related to the
|
||||
.Xr cam 4
|
||||
system.
|
||||
.Bl -tag -width ".Sy Subsystem" -compact
|
||||
.It Sy Subsystem
|
||||
.It Li periph
|
||||
Events related to peripheral devices.
|
||||
.Bl -tag -width ".li timeout" -compact
|
||||
.It Sy Type
|
||||
.It Li error
|
||||
Generic errors.
|
||||
.It Li timeout
|
||||
Command timeouts.
|
||||
.El
|
||||
.El
|
||||
.El
|
||||
.Pp
|
||||
A link state change to UP on the interface
|
||||
@ -630,4 +647,5 @@ has many additional examples.
|
||||
.Xr coretemp 4 ,
|
||||
.Xr devfs 5 ,
|
||||
.Xr re_format 7 ,
|
||||
.Xr devd 8
|
||||
.Xr devd 8 ,
|
||||
.Xr cam 4
|
||||
|
@ -403,7 +403,7 @@ lastdump(int arg) /* w ==> just what to do; W ==> most recent dumps */
|
||||
dumpme = tnow > (dtwalk->dd_ddate - (tlast->tm_hour * 3600)
|
||||
- (tlast->tm_min * 60) - tlast->tm_sec
|
||||
+ (dt->fs_freq * 86400));
|
||||
};
|
||||
}
|
||||
if (arg != 'w' || dumpme)
|
||||
(void) printf(
|
||||
"%c %8s\t(%6s) Last dump: Level %d, Date %s\n",
|
||||
|
@ -118,7 +118,7 @@ fsckinit(void)
|
||||
bzero(totalreadcnt, sizeof(long) * BT_NUMBUFTYPES);
|
||||
bzero(readtime, sizeof(struct timespec) * BT_NUMBUFTYPES);
|
||||
bzero(totalreadtime, sizeof(struct timespec) * BT_NUMBUFTYPES);
|
||||
bzero(&startprog, sizeof(struct timespec));;
|
||||
bzero(&startprog, sizeof(struct timespec));
|
||||
bzero(&sblk, sizeof(struct bufarea));
|
||||
pdirbp = NULL;
|
||||
pbp = NULL;
|
||||
|
@ -911,6 +911,6 @@ sfp_status(int s, struct ifreq *ifr, int verbose)
|
||||
break;
|
||||
default:
|
||||
print_sfp_status(&ii, verbose);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -234,6 +234,9 @@ static struct _s_x ether_types[] = {
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static struct _s_x rule_eactions[] = {
|
||||
{ NULL, 0 } /* terminator */
|
||||
};
|
||||
|
||||
static struct _s_x rule_actions[] = {
|
||||
{ "accept", TOK_ACCEPT },
|
||||
@ -265,6 +268,7 @@ static struct _s_x rule_actions[] = {
|
||||
{ "setdscp", TOK_SETDSCP },
|
||||
{ "call", TOK_CALL },
|
||||
{ "return", TOK_RETURN },
|
||||
{ "eaction", TOK_EACTION },
|
||||
{ NULL, 0 } /* terminator */
|
||||
};
|
||||
|
||||
@ -381,6 +385,8 @@ static uint16_t pack_table(struct tidx *tstate, char *name);
|
||||
|
||||
static char *table_search_ctlv(ipfw_obj_ctlv *ctlv, uint16_t idx);
|
||||
static void object_sort_ctlv(ipfw_obj_ctlv *ctlv);
|
||||
static char *object_search_ctlv(ipfw_obj_ctlv *ctlv, uint16_t idx,
|
||||
uint16_t type);
|
||||
|
||||
/*
|
||||
* Simple string buffer API.
|
||||
@ -634,7 +640,7 @@ do_get3(int optname, ip_fw3_opheader *op3, size_t *optlen)
|
||||
* with the string (-1 in case of failure).
|
||||
*/
|
||||
int
|
||||
match_token(struct _s_x *table, char *string)
|
||||
match_token(struct _s_x *table, const char *string)
|
||||
{
|
||||
struct _s_x *pt;
|
||||
uint i = strlen(string);
|
||||
@ -646,7 +652,7 @@ match_token(struct _s_x *table, char *string)
|
||||
}
|
||||
|
||||
/**
|
||||
* match_token takes a table and a string, returns the value associated
|
||||
* match_token_relaxed takes a table and a string, returns the value associated
|
||||
* with the string for the best match.
|
||||
*
|
||||
* Returns:
|
||||
@ -655,7 +661,7 @@ match_token(struct _s_x *table, char *string)
|
||||
* -2 if more than one records match @string.
|
||||
*/
|
||||
int
|
||||
match_token_relaxed(struct _s_x *table, char *string)
|
||||
match_token_relaxed(struct _s_x *table, const char *string)
|
||||
{
|
||||
struct _s_x *pt, *m;
|
||||
int i, c;
|
||||
@ -676,6 +682,18 @@ match_token_relaxed(struct _s_x *table, char *string)
|
||||
return (c > 0 ? -2: -1);
|
||||
}
|
||||
|
||||
int
|
||||
get_token(struct _s_x *table, const char *string, const char *errbase)
|
||||
{
|
||||
int tcmd;
|
||||
|
||||
if ((tcmd = match_token_relaxed(table, string)) < 0)
|
||||
errx(EX_USAGE, "%s %s %s",
|
||||
(tcmd == 0) ? "invalid" : "ambiguous", errbase, string);
|
||||
|
||||
return (tcmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* match_value takes a table and a value, returns the string associated
|
||||
* with the value (NULL in case of failure).
|
||||
@ -1383,7 +1401,7 @@ show_static_rule(struct cmdline_opts *co, struct format_opts *fo,
|
||||
{
|
||||
static int twidth = 0;
|
||||
int l;
|
||||
ipfw_insn *cmd, *tagptr = NULL;
|
||||
ipfw_insn *cmd, *has_eaction = NULL, *tagptr = NULL;
|
||||
const char *comment = NULL; /* ptr to comment if we have one */
|
||||
int proto = 0; /* default */
|
||||
int flags = 0; /* prerequisites */
|
||||
@ -1484,7 +1502,7 @@ show_static_rule(struct cmdline_opts *co, struct format_opts *fo,
|
||||
if (cmd->arg1 == ICMP6_UNREACH_RST)
|
||||
bprintf(bp, "reset6");
|
||||
else
|
||||
print_unreach6_code(cmd->arg1);
|
||||
print_unreach6_code(bp, cmd->arg1);
|
||||
break;
|
||||
|
||||
case O_SKIPTO:
|
||||
@ -1567,6 +1585,52 @@ show_static_rule(struct cmdline_opts *co, struct format_opts *fo,
|
||||
bprint_uint_arg(bp, "setfib ", cmd->arg1 & 0x7FFF);
|
||||
break;
|
||||
|
||||
case O_EXTERNAL_ACTION: {
|
||||
const char *ename;
|
||||
|
||||
/*
|
||||
* The external action can consists of two following
|
||||
* each other opcodes - O_EXTERNAL_ACTION and
|
||||
* O_EXTERNAL_INSTANCE. The first contains the ID of
|
||||
* name of external action. The second contains the ID
|
||||
* of name of external action instance.
|
||||
* NOTE: in case when external action has no named
|
||||
* instances support, the second opcode isn't needed.
|
||||
*/
|
||||
has_eaction = cmd;
|
||||
ename = object_search_ctlv(fo->tstate, cmd->arg1,
|
||||
IPFW_TLV_EACTION);
|
||||
if (match_token(rule_eactions, ename) != -1)
|
||||
bprintf(bp, "%s", ename);
|
||||
else
|
||||
bprintf(bp, "eaction %s", ename);
|
||||
break;
|
||||
}
|
||||
|
||||
case O_EXTERNAL_INSTANCE: {
|
||||
const char *ename;
|
||||
|
||||
if (has_eaction == NULL)
|
||||
break;
|
||||
/*
|
||||
* XXX: we need to teach ipfw(9) to rewrite opcodes
|
||||
* in the user buffer on rule addition. When we add
|
||||
* the rule, we specify zero TLV type for
|
||||
* O_EXTERNAL_INSTANCE object. To show correct
|
||||
* rule after `ipfw add` we need to search instance
|
||||
* name with zero type. But when we do `ipfw show`
|
||||
* we calculate TLV type using IPFW_TLV_EACTION_NAME()
|
||||
* macro.
|
||||
*/
|
||||
ename = object_search_ctlv(fo->tstate, cmd->arg1, 0);
|
||||
if (ename == NULL)
|
||||
ename = object_search_ctlv(fo->tstate,
|
||||
cmd->arg1,
|
||||
IPFW_TLV_EACTION_NAME(has_eaction->arg1));
|
||||
bprintf(bp, " %s", ename);
|
||||
break;
|
||||
}
|
||||
|
||||
case O_SETDSCP:
|
||||
{
|
||||
const char *code;
|
||||
@ -2730,6 +2794,42 @@ struct tidx {
|
||||
uint8_t set;
|
||||
};
|
||||
|
||||
int
|
||||
ipfw_check_object_name(const char *name)
|
||||
{
|
||||
int c, i, l;
|
||||
|
||||
/*
|
||||
* Check that name is null-terminated and contains
|
||||
* valid symbols only. Valid mask is:
|
||||
* [a-zA-Z0-9\-_\.]{1,63}
|
||||
*/
|
||||
l = strlen(name);
|
||||
if (l == 0 || l >= 64)
|
||||
return (EINVAL);
|
||||
for (i = 0; i < l; i++) {
|
||||
c = name[i];
|
||||
if (isalpha(c) || isdigit(c) || c == '_' ||
|
||||
c == '-' || c == '.')
|
||||
continue;
|
||||
return (EINVAL);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
eaction_check_name(const char *name)
|
||||
{
|
||||
|
||||
if (ipfw_check_object_name(name) != 0)
|
||||
return (EINVAL);
|
||||
/* Restrict some 'special' names */
|
||||
if (match_token(rule_actions, name) != -1 &&
|
||||
match_token(rule_action_params, name) != -1)
|
||||
return (EINVAL);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
pack_object(struct tidx *tstate, char *name, int otype)
|
||||
{
|
||||
@ -3833,7 +3933,46 @@ compile_rule(char *av[], uint32_t *rbuf, int *rbufsize, struct tidx *tstate)
|
||||
break;
|
||||
|
||||
default:
|
||||
errx(EX_DATAERR, "invalid action %s\n", av[-1]);
|
||||
av--;
|
||||
if (match_token(rule_eactions, *av) == -1)
|
||||
errx(EX_DATAERR, "invalid action %s\n", *av);
|
||||
/*
|
||||
* External actions support.
|
||||
* XXX: we support only syntax with instance name.
|
||||
* For known external actions (from rule_eactions list)
|
||||
* we can handle syntax directly. But with `eaction'
|
||||
* keyword we can use only `eaction <name> <instance>'
|
||||
* syntax.
|
||||
*/
|
||||
case TOK_EACTION: {
|
||||
uint16_t idx;
|
||||
|
||||
NEED1("Missing eaction name");
|
||||
if (eaction_check_name(*av) != 0)
|
||||
errx(EX_DATAERR, "Invalid eaction name %s", *av);
|
||||
idx = pack_object(tstate, *av, IPFW_TLV_EACTION);
|
||||
if (idx == 0)
|
||||
errx(EX_DATAERR, "pack_object failed");
|
||||
fill_cmd(action, O_EXTERNAL_ACTION, 0, idx);
|
||||
av++;
|
||||
NEED1("Missing eaction instance name");
|
||||
action = next_cmd(action, &ablen);
|
||||
action->len = 1;
|
||||
CHECK_ACTLEN;
|
||||
if (eaction_check_name(*av) != 0)
|
||||
errx(EX_DATAERR, "Invalid eaction instance name %s",
|
||||
*av);
|
||||
/*
|
||||
* External action instance object has TLV type depended
|
||||
* from the external action name object index. Since we
|
||||
* currently don't know this index, use zero as TLV type.
|
||||
*/
|
||||
idx = pack_object(tstate, *av, 0);
|
||||
if (idx == 0)
|
||||
errx(EX_DATAERR, "pack_object failed");
|
||||
fill_cmd(action, O_EXTERNAL_INSTANCE, 0, idx);
|
||||
av++;
|
||||
}
|
||||
}
|
||||
action = next_cmd(action, &ablen);
|
||||
|
||||
@ -4758,7 +4897,7 @@ object_search_ctlv(ipfw_obj_ctlv *ctlv, uint16_t idx, uint16_t type)
|
||||
ntlv = bsearch(&key, (ctlv + 1), ctlv->count, ctlv->objsize,
|
||||
compare_object_kntlv);
|
||||
|
||||
if (ntlv != 0)
|
||||
if (ntlv != NULL)
|
||||
return (ntlv->name);
|
||||
|
||||
return (NULL);
|
||||
@ -5019,7 +5158,7 @@ ipfw_list_objects(int ac, char *av[])
|
||||
printf("There are no objects\n");
|
||||
ntlv = (ipfw_obj_ntlv *)(olh + 1);
|
||||
for (i = 0; i < olh->count; i++) {
|
||||
printf(" kidx: %4d\ttype: %2d\tname: %s\n", ntlv->idx,
|
||||
printf(" kidx: %4d\ttype: %6d\tname: %s\n", ntlv->idx,
|
||||
ntlv->head.type, ntlv->name);
|
||||
ntlv++;
|
||||
}
|
||||
|
@ -83,6 +83,7 @@ enum tokens {
|
||||
|
||||
TOK_ACCEPT,
|
||||
TOK_COUNT,
|
||||
TOK_EACTION,
|
||||
TOK_PIPE,
|
||||
TOK_LINK,
|
||||
TOK_QUEUE,
|
||||
@ -261,8 +262,9 @@ int _substrcmp2(const char *str1, const char* str2, const char* str3);
|
||||
int stringnum_cmp(const char *a, const char *b);
|
||||
|
||||
/* utility functions */
|
||||
int match_token(struct _s_x *table, char *string);
|
||||
int match_token_relaxed(struct _s_x *table, char *string);
|
||||
int match_token(struct _s_x *table, const char *string);
|
||||
int match_token_relaxed(struct _s_x *table, const char *string);
|
||||
int get_token(struct _s_x *table, const char *string, const char *errbase);
|
||||
char const *match_value(struct _s_x *p, int value);
|
||||
size_t concat_tokens(char *buf, size_t bufsize, struct _s_x *table,
|
||||
char *delimiter);
|
||||
@ -313,6 +315,7 @@ void ipfw_flush(int force);
|
||||
void ipfw_zero(int ac, char *av[], int optname);
|
||||
void ipfw_list(int ac, char *av[], int show_counters);
|
||||
void ipfw_internal_handler(int ac, char *av[]);
|
||||
int ipfw_check_object_name(const char *name);
|
||||
|
||||
#ifdef PF
|
||||
/* altq.c */
|
||||
@ -329,7 +332,7 @@ void dummynet_flush(void);
|
||||
int ipfw_delete_pipe(int pipe_or_queue, int n);
|
||||
|
||||
/* ipv6.c */
|
||||
void print_unreach6_code(uint16_t code);
|
||||
void print_unreach6_code(struct buf_pr *bp, uint16_t code);
|
||||
void print_ip6(struct buf_pr *bp, struct _ipfw_insn_ip6 *cmd, char const *s);
|
||||
void print_flow6id(struct buf_pr *bp, struct _ipfw_insn_u32 *cmd);
|
||||
void print_icmp6types(struct buf_pr *bp, struct _ipfw_insn_u32 *cmd);
|
||||
@ -345,7 +348,7 @@ int fill_ext6hdr(struct _ipfw_insn *cmd, char *av);
|
||||
|
||||
/* tables.c */
|
||||
struct _ipfw_obj_ctlv;
|
||||
int table_check_name(char *tablename);
|
||||
int table_check_name(const char *tablename);
|
||||
void ipfw_list_ta(int ac, char *av[]);
|
||||
void ipfw_list_values(int ac, char *av[]);
|
||||
|
||||
|
@ -71,14 +71,14 @@ fill_unreach6_code(u_short *codep, char *str)
|
||||
}
|
||||
|
||||
void
|
||||
print_unreach6_code(uint16_t code)
|
||||
print_unreach6_code(struct buf_pr *bp, uint16_t code)
|
||||
{
|
||||
char const *s = match_value(icmp6codes, code);
|
||||
|
||||
if (s != NULL)
|
||||
printf("unreach6 %s", s);
|
||||
bprintf(bp, "unreach6 %s", s);
|
||||
else
|
||||
printf("unreach6 %u", code);
|
||||
bprintf(bp, "unreach6 %u", code);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -53,8 +53,8 @@ static void table_lock(ipfw_obj_header *oh, int lock);
|
||||
static int table_swap(ipfw_obj_header *oh, char *second);
|
||||
static int table_get_info(ipfw_obj_header *oh, ipfw_xtable_info *i);
|
||||
static int table_show_info(ipfw_xtable_info *i, void *arg);
|
||||
static void table_fill_ntlv(ipfw_obj_ntlv *ntlv, char *name, uint32_t set,
|
||||
uint16_t uidx);
|
||||
static void table_fill_ntlv(ipfw_obj_ntlv *ntlv, const char *name,
|
||||
uint32_t set, uint16_t uidx);
|
||||
|
||||
static int table_flush_one(ipfw_xtable_info *i, void *arg);
|
||||
static int table_show_one(ipfw_xtable_info *i, void *arg);
|
||||
@ -130,18 +130,6 @@ lookup_host (char *host, struct in_addr *ipaddr)
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
get_token(struct _s_x *table, char *string, char *errbase)
|
||||
{
|
||||
int tcmd;
|
||||
|
||||
if ((tcmd = match_token_relaxed(table, string)) < 0)
|
||||
errx(EX_USAGE, "%s %s %s",
|
||||
(tcmd == 0) ? "invalid" : "ambiguous", errbase, string);
|
||||
|
||||
return (tcmd);
|
||||
}
|
||||
|
||||
/*
|
||||
* This one handles all table-related commands
|
||||
* ipfw table NAME create ...
|
||||
@ -293,7 +281,8 @@ ipfw_table_handler(int ac, char *av[])
|
||||
}
|
||||
|
||||
static void
|
||||
table_fill_ntlv(ipfw_obj_ntlv *ntlv, char *name, uint32_t set, uint16_t uidx)
|
||||
table_fill_ntlv(ipfw_obj_ntlv *ntlv, const char *name, uint32_t set,
|
||||
uint16_t uidx)
|
||||
{
|
||||
|
||||
ntlv->head.type = IPFW_TLV_TBL_NAME;
|
||||
@ -1994,30 +1983,14 @@ ipfw_list_values(int ac, char *av[])
|
||||
}
|
||||
|
||||
int
|
||||
table_check_name(char *tablename)
|
||||
table_check_name(const char *tablename)
|
||||
{
|
||||
int c, i, l;
|
||||
|
||||
/*
|
||||
* Check if tablename is null-terminated and contains
|
||||
* valid symbols only. Valid mask is:
|
||||
* [a-zA-Z0-9\-_\.]{1,63}
|
||||
*/
|
||||
l = strlen(tablename);
|
||||
if (l == 0 || l >= 64)
|
||||
if (ipfw_check_object_name(tablename) != 0)
|
||||
return (EINVAL);
|
||||
for (i = 0; i < l; i++) {
|
||||
c = tablename[i];
|
||||
if (isalpha(c) || isdigit(c) || c == '_' ||
|
||||
c == '-' || c == '.')
|
||||
continue;
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/* Restrict some 'special' names */
|
||||
if (strcmp(tablename, "all") == 0)
|
||||
return (EINVAL);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -1027,7 +1027,7 @@ xdr_fh(XDR *xdrsp, struct nfhret *np)
|
||||
if (!authfnd && (authcnt > 0 || np->auth != AUTH_SYS))
|
||||
np->stat = EAUTH;
|
||||
return (1);
|
||||
};
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -1605,13 +1605,22 @@ bandwidth : STRING {
|
||||
|
||||
bps = strtod($1, &cp);
|
||||
if (cp != NULL) {
|
||||
if (strlen(cp) > 1) {
|
||||
char *cu = cp + 1;
|
||||
if (!strcmp(cu, "Bit") ||
|
||||
!strcmp(cu, "B") ||
|
||||
!strcmp(cu, "bit") ||
|
||||
!strcmp(cu, "b")) {
|
||||
*cu = 0;
|
||||
}
|
||||
}
|
||||
if (!strcmp(cp, "b"))
|
||||
; /* nothing */
|
||||
else if (!strcmp(cp, "Kb"))
|
||||
else if (!strcmp(cp, "K"))
|
||||
bps *= 1000;
|
||||
else if (!strcmp(cp, "Mb"))
|
||||
else if (!strcmp(cp, "M"))
|
||||
bps *= 1000 * 1000;
|
||||
else if (!strcmp(cp, "Gb"))
|
||||
else if (!strcmp(cp, "G"))
|
||||
bps *= 1000 * 1000 * 1000;
|
||||
else if (!strcmp(cp, "%")) {
|
||||
if (bps < 0 || bps > 100) {
|
||||
|
@ -32,9 +32,8 @@
|
||||
.Nd "specify an alternate kernel and boot flags for the next reboot"
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl a
|
||||
.Op Fl af
|
||||
.Op Fl e Ar variable=value
|
||||
.Op Fl f
|
||||
.Op Fl k Ar kernel
|
||||
.Op Fl o Ar options
|
||||
.Nm
|
||||
|
@ -50,7 +50,7 @@ add_kenv()
|
||||
|
||||
display_usage() {
|
||||
cat <<-EOF
|
||||
Usage: nextboot [-e variable=value] [-f] [-k kernel] [-o options]
|
||||
Usage: nextboot [-af] [-e variable=value] [-k kernel] [-o options]
|
||||
nextboot -D
|
||||
EOF
|
||||
}
|
||||
|
@ -436,7 +436,7 @@ DoFile(const char *savedir, const char *device)
|
||||
{
|
||||
xo_handle_t *xostdout, *xoinfo;
|
||||
static char infoname[PATH_MAX], corename[PATH_MAX], linkname[PATH_MAX];
|
||||
static char *buf = NULL;
|
||||
static char *buf = NULL, *temp = NULL;
|
||||
struct kerneldumpheader kdhf, kdhl;
|
||||
off_t mediasize, dumpsize, firsthd, lasthd;
|
||||
FILE *info, *fp;
|
||||
@ -490,14 +490,29 @@ DoFile(const char *savedir, const char *device)
|
||||
printf("sectorsize = %u\n", sectorsize);
|
||||
}
|
||||
|
||||
if (sectorsize < sizeof(kdhl)) {
|
||||
syslog(LOG_ERR,
|
||||
"Sector size is less the kernel dump header %zu",
|
||||
sizeof(kdhl));
|
||||
goto closefd;
|
||||
}
|
||||
|
||||
lasthd = mediasize - sectorsize;
|
||||
if (temp == NULL) {
|
||||
temp = malloc(sectorsize);
|
||||
if (temp == NULL) {
|
||||
syslog(LOG_ERR, "%m");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (lseek(fd, lasthd, SEEK_SET) != lasthd ||
|
||||
read(fd, &kdhl, sizeof(kdhl)) != sizeof(kdhl)) {
|
||||
read(fd, temp, sectorsize) != (ssize_t)sectorsize) {
|
||||
syslog(LOG_ERR,
|
||||
"error reading last dump header at offset %lld in %s: %m",
|
||||
(long long)lasthd, device);
|
||||
goto closefd;
|
||||
}
|
||||
memcpy(&kdhl, temp, sizeof(kdhl));
|
||||
istextdump = 0;
|
||||
if (strncmp(kdhl.magic, TEXTDUMPMAGIC, sizeof kdhl) == 0) {
|
||||
if (verbose)
|
||||
@ -567,15 +582,16 @@ DoFile(const char *savedir, const char *device)
|
||||
goto closefd;
|
||||
}
|
||||
dumpsize = dtoh64(kdhl.dumplength);
|
||||
firsthd = lasthd - dumpsize - sizeof kdhf;
|
||||
firsthd = lasthd - dumpsize - sectorsize;
|
||||
if (lseek(fd, firsthd, SEEK_SET) != firsthd ||
|
||||
read(fd, &kdhf, sizeof(kdhf)) != sizeof(kdhf)) {
|
||||
read(fd, temp, sectorsize) != (ssize_t)sectorsize) {
|
||||
syslog(LOG_ERR,
|
||||
"error reading first dump header at offset %lld in %s: %m",
|
||||
(long long)firsthd, device);
|
||||
nerr++;
|
||||
goto closefd;
|
||||
}
|
||||
memcpy(&kdhf, temp, sizeof(kdhf));
|
||||
|
||||
if (verbose >= 2) {
|
||||
printf("First dump headers:\n");
|
||||
@ -586,7 +602,7 @@ DoFile(const char *savedir, const char *device)
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (memcmp(&kdhl, &kdhf, sizeof kdhl)) {
|
||||
if (memcmp(&kdhl, &kdhf, sizeof(kdhl))) {
|
||||
syslog(LOG_ERR,
|
||||
"first and last dump headers disagree on %s", device);
|
||||
nerr++;
|
||||
@ -603,7 +619,7 @@ DoFile(const char *savedir, const char *device)
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (kdhl.panicstring[0])
|
||||
if (kdhl.panicstring[0] != '\0')
|
||||
syslog(LOG_ALERT, "reboot after panic: %*s",
|
||||
(int)sizeof(kdhl.panicstring), kdhl.panicstring);
|
||||
else
|
||||
@ -724,9 +740,10 @@ DoFile(const char *savedir, const char *device)
|
||||
if (!keep) {
|
||||
if (verbose)
|
||||
printf("clearing dump header\n");
|
||||
memcpy(kdhl.magic, KERNELDUMPMAGIC_CLEARED, sizeof kdhl.magic);
|
||||
memcpy(kdhl.magic, KERNELDUMPMAGIC_CLEARED, sizeof(kdhl.magic));
|
||||
memcpy(temp, &kdhl, sizeof(kdhl));
|
||||
if (lseek(fd, lasthd, SEEK_SET) != lasthd ||
|
||||
write(fd, &kdhl, sizeof(kdhl)) != sizeof(kdhl))
|
||||
write(fd, temp, sectorsize) != (ssize_t)sectorsize)
|
||||
syslog(LOG_ERR,
|
||||
"error while clearing the dump header: %m");
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user