Sponsored by:	The FreeBSD Foundation
This commit is contained in:
Glen Barber 2016-04-16 02:32:12 +00:00
commit 0edd2576c0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/release-pkg/; revision=298092
451 changed files with 9427 additions and 2778 deletions

View File

@ -125,7 +125,7 @@ TGTS= all all-man buildenv buildenvvars buildkernel buildworld \
obj objlink rerelease showconfig tags toolchain update \ obj objlink rerelease showconfig tags toolchain update \
_worldtmp _legacy _bootstrap-tools _cleanobj _obj \ _worldtmp _legacy _bootstrap-tools _cleanobj _obj \
_build-tools _cross-tools _includes _libraries \ _build-tools _cross-tools _includes _libraries \
build32 distribute32 install32 build32 distribute32 install32 \ build32 distribute32 install32 buildsoft distributesoft installsoft \
builddtb xdev xdev-build xdev-install \ builddtb xdev xdev-build xdev-install \
xdev-links native-xtools stageworld stagekernel stage-packages \ xdev-links native-xtools stageworld stagekernel stage-packages \
create-world-packages create-kernel-packages create-packages \ create-world-packages create-kernel-packages create-packages \
@ -408,7 +408,7 @@ MAKEFAIL=cat
universe_prologue: upgrade_checks universe_prologue: upgrade_checks
universe: universe_prologue universe: universe_prologue
universe_prologue: universe_prologue: .PHONY
@echo "--------------------------------------------------------------" @echo "--------------------------------------------------------------"
@echo ">>> make universe started on ${STARTTIME}" @echo ">>> make universe started on ${STARTTIME}"
@echo "--------------------------------------------------------------" @echo "--------------------------------------------------------------"
@ -494,7 +494,7 @@ universe_kernconf_${TARGET}_${kernel}: .MAKE
"check _.${TARGET}.${kernel} for details"| ${MAKEFAIL})) "check _.${TARGET}.${kernel} for details"| ${MAKEFAIL}))
.endfor .endfor
universe: universe_epilogue universe: universe_epilogue
universe_epilogue: universe_epilogue: .PHONY
@echo "--------------------------------------------------------------" @echo "--------------------------------------------------------------"
@echo ">>> make universe completed on `LC_ALL=C date`" @echo ">>> make universe completed on `LC_ALL=C date`"
@echo " (started ${STARTTIME})" @echo " (started ${STARTTIME})"

View File

@ -144,6 +144,15 @@ CLEANDIR= clean cleandepend
CLEANDIR= cleandir CLEANDIR= cleandir
.endif .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?= LOCAL_TOOL_DIRS?=
PACKAGEDIR?= ${DESTDIR}/${DISTDIR} PACKAGEDIR?= ${DESTDIR}/${DISTDIR}
@ -316,6 +325,10 @@ CROSSENV+= MAKEOBJDIRPREFIX=${OBJTREE} \
MACHINE_ARCH=${TARGET_ARCH} \ MACHINE_ARCH=${TARGET_ARCH} \
MACHINE=${TARGET} \ MACHINE=${TARGET} \
CPUTYPE=${TARGET_CPUTYPE} 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" .if ${MK_GROFF} != "no"
CROSSENV+= GROFF_BIN_PATH=${WORLDTMP}/legacy/usr/bin \ CROSSENV+= GROFF_BIN_PATH=${WORLDTMP}/legacy/usr/bin \
GROFF_FONT_PATH=${WORLDTMP}/legacy/usr/share/groff_font \ GROFF_FONT_PATH=${WORLDTMP}/legacy/usr/share/groff_font \
@ -327,6 +340,7 @@ CROSSENV+= ${TARGET_CFLAGS}
# bootstrap-tools stage # bootstrap-tools stage
BMAKEENV= INSTALL="sh ${.CURDIR}/tools/install.sh" \ BMAKEENV= INSTALL="sh ${.CURDIR}/tools/install.sh" \
TOOLS_PREFIX=${WORLDTMP} \
PATH=${BPATH}:${PATH} \ PATH=${BPATH}:${PATH} \
WORLDTMP=${WORLDTMP} \ WORLDTMP=${WORLDTMP} \
MAKEFLAGS="-m ${.CURDIR}/tools/build/mk ${.MAKEFLAGS}" MAKEFLAGS="-m ${.CURDIR}/tools/build/mk ${.MAKEFLAGS}"
@ -672,12 +686,12 @@ WMAKE_TGTS+= build${libcompat}
buildworld: buildworld_prologue ${WMAKE_TGTS} buildworld_epilogue buildworld: buildworld_prologue ${WMAKE_TGTS} buildworld_epilogue
.ORDER: buildworld_prologue ${WMAKE_TGTS} buildworld_epilogue .ORDER: buildworld_prologue ${WMAKE_TGTS} buildworld_epilogue
buildworld_prologue: buildworld_prologue: .PHONY
@echo "--------------------------------------------------------------" @echo "--------------------------------------------------------------"
@echo ">>> World build started on `LC_ALL=C date`" @echo ">>> World build started on `LC_ALL=C date`"
@echo "--------------------------------------------------------------" @echo "--------------------------------------------------------------"
buildworld_epilogue: buildworld_epilogue: .PHONY
@echo @echo
@echo "--------------------------------------------------------------" @echo "--------------------------------------------------------------"
@echo ">>> World build completed on `LC_ALL=C date`" @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/libkiconv lib/libkvm lib/liblzma lib/libmd lib/libnv \
${_lib_casper} \ ${_lib_casper} \
lib/ncurses/ncurses lib/ncurses/ncursesw \ 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_libradius} lib/libsbuf lib/libtacplus \
lib/libgeom \ lib/libgeom \
${_cddl_lib_libumem} ${_cddl_lib_libnvpair} \ ${_cddl_lib_libumem} ${_cddl_lib_libnvpair} \
@ -1909,6 +1923,7 @@ _prebuild_libs= ${_kerberos5_lib_libasn1} \
${_secure_lib_libcrypto} ${_lib_libldns} \ ${_secure_lib_libcrypto} ${_lib_libldns} \
${_secure_lib_libssh} ${_secure_lib_libssl} \ ${_secure_lib_libssh} ${_secure_lib_libssl} \
gnu/lib/libdialog gnu/lib/libdialog
.if ${MK_GNUCXX} != "no" .if ${MK_GNUCXX} != "no"
_prebuild_libs+= gnu/lib/libstdc++ gnu/lib/libsupc++ _prebuild_libs+= gnu/lib/libstdc++ gnu/lib/libsupc++
gnu/lib/libstdc++__L: lib/msun__L gnu/lib/libstdc++__L: lib/msun__L
@ -2076,7 +2091,7 @@ ${_lib}__PL: .PHONY .MAKE
.endif .endif
.endfor .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 ${_lib}__L: .PHONY .MAKE
.if exists(${.CURDIR}/${_lib}) .if exists(${.CURDIR}/${_lib})
${_+_}@${ECHODIR} "===> ${_lib} (obj,all,install)"; \ ${_+_}@${ECHODIR} "===> ${_lib} (obj,all,install)"; \
@ -2087,18 +2102,6 @@ ${_lib}__L: .PHONY .MAKE
.endif .endif
.endfor .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/} _prereq_libs: ${_prereq_libs:S/$/__PL/}
_startup_libs: ${_startup_libs:S/$/__L/} _startup_libs: ${_startup_libs:S/$/__L/}
_prebuild_libs: ${_prebuild_libs:S/$/__L/} _prebuild_libs: ${_prebuild_libs:S/$/__L/}

View File

@ -88,8 +88,13 @@ LIBCOMPATWMAKEENV+= MAKEOBJDIRPREFIX=${LIBCOMPAT_OBJTREE} \
LIBDIR=/usr/lib${libcompat} \ LIBDIR=/usr/lib${libcompat} \
SHLIBDIR=/usr/lib${libcompat} \ SHLIBDIR=/usr/lib${libcompat} \
DTRACE="${LIB$COMPATDTRACE:U${DTRACE}}" 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}" \ LIBCOMPATWMAKEFLAGS+= CC="${XCC} ${LIBCOMPATCFLAGS}" \
CXX="${XCXX} ${LIBCOMPATCFLAGS} ${LIBCOMPATCXXFLAGS}" \ CXX="${XCXX} ${LIBCOMPATCFLAGS} ${LIBCOMPATCXXFLAGS}" \
CPP="${XCPP} ${LIBCOMPATCFLAGS}" \
DESTDIR=${LIBCOMPATTMP} \ DESTDIR=${LIBCOMPATTMP} \
-DNO_CPU_CFLAGS \ -DNO_CPU_CFLAGS \
MK_CTF=no \ MK_CTF=no \

View File

@ -1732,7 +1732,6 @@ OLD_FILES+=usr/share/man/man4/lindev.4.gz
# 20140425 # 20140425
OLD_FILES+=usr/lib/libssp_p.a OLD_FILES+=usr/lib/libssp_p.a
OLD_FILES+=usr/lib/libstand_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/libssp_p.a
OLD_FILES+=usr/lib32/libstand_p.a OLD_FILES+=usr/lib32/libstand_p.a
# 20140314: AppleTalk # 20140314: AppleTalk

View File

@ -31,6 +31,33 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW:
disable the most expensive debugging functionality run disable the most expensive debugging functionality run
"ln -s 'abort:false,junk:false' /etc/malloc.conf".) "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: 20160330:
The FAST_DEPEND build option has been removed and its functionality is 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 now the one true way. The old mkdep(1) style of 'make depend' has

View File

@ -110,7 +110,7 @@ csh.1: tcsh.man
build-tools: gethost 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} @rm -f ${.TARGET}
${CC} -o gethost ${LDFLAGS} ${CFLAGS:C/-DHAVE_ICONV//} \ ${CC} -o gethost ${LDFLAGS} ${CFLAGS:C/-DHAVE_ICONV//} \
${TCSHDIR}/gethost.c ${TCSHDIR}/gethost.c

View File

@ -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 # XXX this is just to stop the default .c rule being used, so that the
# intermediate object has a fixed name. # intermediate object has a fixed name.
# XXX we have a default .c rule, but no default .o rule. # 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} ${CC} ${CFLAGS} ${LDFLAGS} ${.IMPSRC} ${LDLIBS} -o ${.TARGET}
mknodes: mknodes.o mknodes: mknodes.o ${BUILD_TOOLS_META}
mksyntax: mksyntax.o mksyntax: mksyntax.o ${BUILD_TOOLS_META}
.ORDER: nodes.c nodes.h .ORDER: nodes.c nodes.h
nodes.c nodes.h: mknodes nodetypes nodes.c.pat nodes.c nodes.h: mknodes nodetypes nodes.c.pat

View File

@ -1616,7 +1616,6 @@ parsesub: {
int flags; int flags;
char *p; char *p;
static const char types[] = "}-+?="; static const char types[] = "}-+?=";
int bracketed_name = 0; /* used to handle ${[0-9]*} variables */
int linno; int linno;
int length; int length;
int c1; int c1;
@ -1640,7 +1639,6 @@ parsesub: {
subtype = VSNORMAL; subtype = VSNORMAL;
flags = 0; flags = 0;
if (c == '{') { if (c == '{') {
bracketed_name = 1;
c = pgetc_linecont(); c = pgetc_linecont();
subtype = 0; subtype = 0;
} }
@ -1665,7 +1663,7 @@ parsesub: {
flags |= VSLINENO; flags |= VSLINENO;
} }
} else if (is_digit(c)) { } else if (is_digit(c)) {
if (bracketed_name) { if (subtype != VSNORMAL) {
do { do {
STPUTC(c, out); STPUTC(c, out);
c = pgetc_linecont(); c = pgetc_linecont();

View File

@ -108,16 +108,16 @@ typedef struct tcpsinfo {
uint32_t tcps_snxt; /* next sequence # to send */ uint32_t tcps_snxt; /* next sequence # to send */
uint32_t tcps_rack; /* sequence # we have acked */ uint32_t tcps_rack; /* sequence # we have acked */
uint32_t tcps_rnxt; /* next sequence # expected */ 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 */ int32_t tcps_snd_ws; /* send window scaling */
uint32_t tcps_swl1; /* window update seg seq number */ uint32_t tcps_swl1; /* window update seg seq number */
uint32_t tcps_swl2; /* window update seg ack number */ uint32_t tcps_swl2; /* window update seg ack number */
uint32_t tcps_rup; /* receive urgent pointer */ uint32_t tcps_rup; /* receive urgent pointer */
uint32_t tcps_radv; /* advertised window */ 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 */ int32_t tcps_rcv_ws; /* receive window scaling */
uint32_t tcps_cwnd; /* congestion window */ u_long tcps_cwnd; /* congestion window */
uint32_t tcps_cwnd_ssthresh; /* threshold for congestion avoidance */ u_long tcps_cwnd_ssthresh; /* threshold for congestion avoidance */
uint32_t tcps_srecover; /* for use in NewReno Fast Recovery */ uint32_t tcps_srecover; /* for use in NewReno Fast Recovery */
uint32_t tcps_sack_fack; /* SACK sequence # we have acked */ uint32_t tcps_sack_fack; /* SACK sequence # we have acked */
uint32_t tcps_sack_snxt; /* next SACK seq # for retransmission */ uint32_t tcps_sack_snxt; /* next SACK seq # for retransmission */

View File

@ -343,7 +343,7 @@ create_scn(struct elfcopy *ecp)
GElf_Shdr ish; GElf_Shdr ish;
size_t indx; size_t indx;
uint64_t oldndx, newndx; uint64_t oldndx, newndx;
int elferr, sec_flags; int elferr, sec_flags, reorder;
/* /*
* Insert a pseudo section that contains the ELF header * 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", errx(EXIT_FAILURE, "elf_getshstrndx failed: %s",
elf_errmsg(-1)); elf_errmsg(-1));
reorder = 0;
is = NULL; is = NULL;
while ((is = elf_nextscn(ecp->ein, is)) != NULL) { while ((is = elf_nextscn(ecp->ein, is)) != NULL) {
if (gelf_getshdr(is, &ish) == NULL) if (gelf_getshdr(is, &ish) == NULL)
@ -482,8 +483,20 @@ create_scn(struct elfcopy *ecp)
/* create section header based on input object. */ /* create section header based on input object. */
if (strcmp(name, ".symtab") != 0 && if (strcmp(name, ".symtab") != 0 &&
strcmp(name, ".strtab") != 0 && strcmp(name, ".strtab") != 0 &&
strcmp(name, ".shstrtab") != 0) strcmp(name, ".shstrtab") != 0) {
copy_shdr(ecp, s, NULL, 0, sec_flags); 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) { if (strcmp(name, ".symtab") == 0) {
ecp->flags |= SYMTAB_EXIST; ecp->flags |= SYMTAB_EXIST;

View File

@ -132,7 +132,7 @@ m_xword(m, k, err)
return EXTRACT_LONG(cp); return EXTRACT_LONG(cp);
} }
m0 = m->m_next; m0 = m->m_next;
if (m0 == 0 || M_LEN(m0) + len - k < 4) if (m0 == NULL || M_LEN(m0) + len - k < 4)
goto bad; goto bad;
*err = 0; *err = 0;
np = MTOD(m0, u_char *); np = MTOD(m0, u_char *);
@ -168,7 +168,7 @@ m_xhalf(m, k, err)
return EXTRACT_SHORT(cp); return EXTRACT_SHORT(cp);
} }
m0 = m->m_next; m0 = m->m_next;
if (m0 == 0) if (m0 == NULL)
goto bad; goto bad;
*err = 0; *err = 0;
return (cp[0] << 8) | MTOD(m0, u_char *)[0]; return (cp[0] << 8) | MTOD(m0, u_char *)[0];
@ -205,7 +205,7 @@ bpf_filter(pc, p, wirelen, buflen)
} else } else
m = NULL; m = NULL;
if (pc == 0) if (pc == NULL)
/* /*
* No filter means accept all. * No filter means accept all.
*/ */

View File

@ -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 **)); int (*ipf_checkp) __P((struct ip *, int, void *, int, mb_t **));
#ifdef IPFILTER_LKM #ifdef IPFILTER_LKM
static int *ipff_addr = 0; static int *ipff_addr;
static int ipff_value; static int ipff_value;
static __psunsigned_t *ipfk_addr = 0; static __psunsigned_t *ipfk_addr;
static __psunsigned_t ipfk_code[4]; static __psunsigned_t ipfk_code[4];
#endif #endif
static void nifattach(); static void nifattach();
@ -85,7 +85,7 @@ typedef struct nif {
int nf_unit; int nf_unit;
} nif_t; } nif_t;
static nif_t *nif_head = 0; static nif_t *nif_head;
static int nif_interfaces = 0; static int nif_interfaces = 0;
extern int in_interfaces; extern int in_interfaces;
#if IRIX >= 60500 #if IRIX >= 60500

View File

@ -57,10 +57,11 @@ snf_pcap_stats(pcap_t *p, struct pcap_stat *ps)
static void static void
snf_platform_cleanup(pcap_t *p) snf_platform_cleanup(pcap_t *p)
{ {
struct pcap_snf *ps = p->priv; struct pcap_snf *ps;
if (p == NULL) if (p == NULL)
return; return;
ps = p->priv;
snf_ring_close(ps->snf_ring); snf_ring_close(ps->snf_ring);
snf_close(ps->snf_handle); snf_close(ps->snf_handle);

View File

@ -77,6 +77,7 @@ GH_PAGES_PACKAGE_DIR = ${GH_PAGES_DIR}/${GH_PACKAGING_DIR}
packages: packages:
@-[ -d ${GH_PAGES_DIR} ] && set -x \ @-[ -d ${GH_PAGES_DIR} ] && set -x \
&& echo "Updating packages on gh-pages ..." \ && echo "Updating packages on gh-pages ..." \
&& mkdir -p ${GH_PAGES_DIR}/${GH_PACKAGING_DIR} \
&& SHA1="`openssl sha1 ${PACKAGE_FILE} | awk '{print $$2}'`" \ && SHA1="`openssl sha1 ${PACKAGE_FILE} | awk '{print $$2}'`" \
&& SHA256="`openssl sha256 ${PACKAGE_FILE} | awk '{print $$2}'`" \ && SHA256="`openssl sha256 ${PACKAGE_FILE} | awk '{print $$2}'`" \
&& SIZE="`ls -l ${PACKAGE_FILE} | awk '{print $$5}'`" \ && SIZE="`ls -l ${PACKAGE_FILE} | awk '{print $$5}'`" \

View File

@ -12,7 +12,7 @@
# #
AC_PREREQ(2.2) 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]) AM_INIT_AUTOMAKE([-Wall -Werror foreign -Wno-portability])
# Support silent build rules. Requires at least automake-1.11. # 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([string.h sys/param.h unistd.h ])
AC_CHECK_HEADERS([sys/sysctl.h]) AC_CHECK_HEADERS([sys/sysctl.h])
AC_CHECK_HEADERS([threads.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 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 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_CFLAGS)
AC_SUBST(GETTEXT_LIBS) AC_SUBST(GETTEXT_LIBS)
GETTEXT_BINDIR=${GETTEXT_PREFIX}/bin
AC_SUBST(GETTEXT_BINDIR)
GETTEXT_LIBDIR=${GETTEXT_PREFIX}/lib GETTEXT_LIBDIR=${GETTEXT_PREFIX}/lib
AC_SUBST(GETTEXT_LIBDIR) 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"]) 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]) AC_DEFINE([LIBXO_WCWIDTH], [1], [Enable local wcwidth implementation])
fi 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]) AC_CHECK_LIB([m], [lrint])
AM_CONDITIONAL([HAVE_LIBM], [test "$HAVE_LIBM" != "no"]) AM_CONDITIONAL([HAVE_LIBM], [test "$HAVE_LIBM" != "no"])
@ -347,12 +368,15 @@ XO_SRCDIR=${srcdir}
XO_LIBDIR=${libdir} XO_LIBDIR=${libdir}
XO_BINDIR=${bindir} XO_BINDIR=${bindir}
XO_INCLUDEDIR=${includedir} XO_INCLUDEDIR=${includedir}
XO_CFLAGS="${CFLAGS}"
AC_SUBST(XO_LIBS)
AC_SUBST(XO_SRCDIR) AC_SUBST(XO_SRCDIR)
AC_SUBST(XO_LIBDIR) AC_SUBST(XO_LIBDIR)
AC_SUBST(XO_BINDIR) AC_SUBST(XO_BINDIR)
AC_SUBST(XO_INCLUDEDIR) AC_SUBST(XO_INCLUDEDIR)
AC_SUBST(XO_LIBEXT) AC_SUBST(XO_LIBEXT)
AC_SUBST(XO_CFLAGS)
AC_ARG_WITH(encoder-dir, AC_ARG_WITH(encoder-dir,
[ --with-encoder-dir=[DIR] Specify location of encoder libraries], [ --with-encoder-dir=[DIR] Specify location of encoder libraries],
@ -449,4 +473,5 @@ AC_MSG_NOTICE([summary of build options:
isthreaded: ${HAVE_ISTHREADED:-no} isthreaded: ${HAVE_ISTHREADED:-no}
thread-local: ${THREAD_LOCAL:-no} thread-local: ${THREAD_LOCAL:-no}
local wcwidth: ${LIBXO_WCWIDTH:-no} local wcwidth: ${LIBXO_WCWIDTH:-no}
retain size: ${XO_RETAIN_SIZE:-no}
]) ])

File diff suppressed because it is too large Load Diff

View File

@ -699,25 +699,26 @@ XOF_WARN is set, a warning will be generated.
Field modifiers are flags which modify the way content emitted for Field modifiers are flags which modify the way content emitted for
particular output styles: particular output styles:
|---+---------------+-------------------------------------------------| |---+---------------+--------------------------------------------------|
| M | Name | Description | | M | Name | Description |
|---+---------------+-------------------------------------------------| |---+---------------+--------------------------------------------------|
| c | colon | A colon (":") is appended after the label | | a | argument | The content appears as a 'const char *' argument |
| d | display | Only emit field for display styles (text/HTML) | | c | colon | A colon (":") is appended after the label |
| e | encoding | Only emit for encoding styles (XML/JSON) | | d | display | Only emit field for display styles (text/HTML) |
| g | gettext | Call gettext on field's render content | | e | encoding | Only emit for encoding styles (XML/JSON) |
| h | humanize (hn) | Format large numbers in human-readable style | | g | gettext | Call gettext on field's render content |
| | hn-space | Humanize: Place space between numeric and unit | | h | humanize (hn) | Format large numbers in human-readable style |
| | hn-decimal | Humanize: Add a decimal digit, if number < 10 | | | hn-space | Humanize: Place space between numeric and unit |
| | hn-1000 | Humanize: Use 1000 as divisor instead of 1024 | | | hn-decimal | Humanize: Add a decimal digit, if number < 10 |
| k | key | Field is a key, suitable for XPath predicates | | | hn-1000 | Humanize: Use 1000 as divisor instead of 1024 |
| l | leaf-list | Field is a leaf-list | | k | key | Field is a key, suitable for XPath predicates |
| n | no-quotes | Do not quote the field when using JSON style | | l | leaf-list | Field is a leaf-list |
| p | plural | Gettext: Use comma-separated plural form | | n | no-quotes | Do not quote the field when using JSON style |
| q | quotes | Quote the field when using JSON style | | p | plural | Gettext: Use comma-separated plural form |
| t | trim | Trim leading and trailing whitespace | | q | quotes | Quote the field when using JSON style |
| w | white | A blank (" ") is appended after the label | | 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 Roles and modifiers can also use more verbose names, when preceeded by
a comma. For example, the modifier string "Lwc" (or "L,white,colon") 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, role (the default role), that it is a key for the current instance,
and that the value should be quoted when encoded for JSON. 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 ({c:})
The colon modifier appends a single colon to the data value: 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: JSON:
"year": "2014" "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 ({w:})
The white space modifier appends a single space to the data value: 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 variables is used and if none of the variables are set, the locale
defaults to "UTF-8". 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, 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) 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. 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 | | 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 *** Example
In this example, the value for the number of items in stock is emitted: 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-type="number"
data-help="Number of items in stock">144</div> 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 ** Representing Hierarchy
For XML and JSON, individual fields appear inside hierarchies which For XML and JSON, individual fields appear inside hierarchies which
@ -1382,20 +1444,81 @@ properly.
xo_close_marker("fish-guts"); 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@ ** Handles @handles@
libxo uses "handles" to control its rendering functionality. The libxo uses "handles" to control its rendering functionality. The
handle contains state and buffered data, as well as callback functions handle contains state and buffered data, as well as callback functions
to process data. to process data.
A default handle is used when a NULL is passed to functions accepting Handles give an abstraction for libxo that encapsulates the state of a
a handle. This handle is initialized to write its data to stdout stream of output. Handles have the data type "xo_handle_t" and are
using the default style of text (XO_STYLE_TEXT). opaque to the caller.
For the convenience of callers, the libxo library includes handle-less The library has a default handle that is automatically initialized.
functions that implicitly use the default handle. Any function that By default, this handle will send text style output (XO_STYLE_TEXT) to
takes a handle will use the default handle is a value of NULL is standard output. The xo_set_style and xo_set_flags functions can be
passed in place of a valid handle. 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: 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(). 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 *** xo_create
A handle can be allocated using the xo_create() function: 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 argument to xo_emit_hv() points to a variable argument list that can
be used to retrieve arguments via va_arg(). 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@ *** Attributes (xo_attr) @xo_attr@
The xo_attr() function emits attributes for the XML output style. The xo_attr() function emits attributes for the XML output style.
int xo_attr (const char *name, const char *fmt, ...); int xo_attr (const char *name, const char *fmt, ...);
int xo_attr_h (xo_handle_t *xop, const char *name, int xo_attr_h (xo_handle_t *xop, const char *name,
const char *fmt, ...); 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 built on top of FreeBSD. Eventually this API became standardized as
the NETCONF API (RFC 6241). As part of this effort, we modified many the NETCONF API (RFC 6241). As part of this effort, we modified many
FreeBSD utilities to emit XML, typically via a "-X" switch. The 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 and carrying it were non-trivial, and contributed to our expense (and
the associated delay) with upgrading the version of FreeBSD on which the associated delay) with upgrading the version of FreeBSD on which
each release of JUNOS is based. each release of JUNOS is based.
A recent (2014) effort within JUNOS aims at removing our modifications A recent (2014) effort within JUNOS aims at removing our modifications
to the underlying FreeBSD code as a means of reducing the expense and to the underlying FreeBSD code as a means of reducing the expense and
delay. JUNOS is structured to have system components generate XML delay in tracking HEAD. JUNOS is structured to have system components
that is rendered by the CLI (think: login shell) into human-readable generate XML that is rendered by the CLI (think: login shell) into
text. This allows the API to use the same plumbing as the CLI, and human-readable text. This allows the API to use the same plumbing as
ensures that all components emit XML, and that it is emitted with the CLI, and ensures that all components emit XML, and that it is
knowledge of the consumer of that XML, yielding an API that have no emitted with knowledge of the consumer of that XML, yielding an API
incremental cost or feature delay. that have no incremental cost or feature delay.
libxo is an effort to mix the best aspects of the JUNOS strategy into 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 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? *** Did the complex semantics of format strings evolve over time?

View File

@ -135,7 +135,7 @@ cbor_encode_uint (xo_buffer_t *xbp, uint64_t minor, unsigned limit)
char *bp = xbp->xb_curp; char *bp = xbp->xb_curp;
int i, m; int i, m;
if (minor > (1UL<<32)) { if (minor > (1ULL << 32)) {
*bp++ |= CBOR_LEN64; *bp++ |= CBOR_LEN64;
m = 64; m = 64;

View File

@ -77,34 +77,34 @@ while test $# -gt 0; do
;; ;;
--cflags) --cflags)
echo -I@LIBXO_INCLUDEDIR@ @LIBXO_CFLAGS@ echo -I@XO_INCLUDEDIR@ @XO_CFLAGS@
;; ;;
--share) --share)
echo @LIBXO_SHAREDIR@ echo @XO_SHAREDIR@
;; ;;
--bindir) --bindir)
echo @LIBXO_BINDIR@ echo @XO_BINDIR@
;; ;;
--libdir) --libdir)
echo @LIBXO_LIBDIR@ echo @XO_LIBDIR@
;; ;;
--libs) --libs)
if [ "`uname`" = "Linux" ] if [ "`uname`" = "Linux" ]
then 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 then
echo @LIBXO_LIBS@ echo @XO_LIBS@
else else
echo -L@LIBXO_LIBDIR@ @LIBXO_LIBS@ echo -L@XO_LIBDIR@ @XO_LIBS@
fi fi
else else
echo -L@LIBXO_LIBDIR@ @LIBXO_LIBS@ @WIN32_EXTRA_LIBADD@ echo -L@XO_LIBDIR@ @XO_LIBS@
fi fi
;; ;;

View File

@ -19,7 +19,8 @@
* http://juniper.github.io/libxo/libxo-manual.html * http://juniper.github.io/libxo/libxo-manual.html
* *
* For first time readers, the core bits of code to start looking at are: * 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_do_format_field() -- handles formatting a single field
* - xo_transiton() -- the state machine that keeps things sane * - xo_transiton() -- the state machine that keeps things sane
* and of course the "xo_handle_t" data structure, which carries all * 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[] = LIBXO_VERSION;
const char xo_version_extra[] = LIBXO_VERSION_EXTRA; const char xo_version_extra[] = LIBXO_VERSION_EXTRA;
static const char xo_default_format[] = "%s";
#ifndef UNUSED #ifndef UNUSED
#define UNUSED __attribute__ ((__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_FIELD (1<<19) /* Call gettext() on a field */
#define XFF_GT_PLURAL (1<<20) /* Call dngettext to find plural form */ #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 */ /* Flags to turn off when we don't want i18n processing */
#define XFF_GT_FLAGS (XFF_GT_FIELD | XFF_GT_PLURAL) #define XFF_GT_FLAGS (XFF_GT_FIELD | XFF_GT_PLURAL)
@ -1046,7 +1049,7 @@ xo_is_utf8 (char ch)
return (ch & 0x80); return (ch & 0x80);
} }
static int static inline int
xo_utf8_to_wc_len (const char *buf) xo_utf8_to_wc_len (const char *buf)
{ {
unsigned b = (unsigned 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, * bits we pull off the first character is dependent on the length,
* but we put 6 bits off all other bytes. * but we put 6 bits off all other bytes.
*/ */
static wchar_t static inline wchar_t
xo_utf8_char (const char *buf, int len) xo_utf8_char (const char *buf, int len)
{ {
/* Most common case: singleton byte */
if (len == 1)
return (unsigned char) buf[0];
int i; int i;
wchar_t wc; wchar_t wc;
const unsigned char *cp = (const unsigned char *) buf; 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); 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 * Generate a warning. Normally, this is a text message written to
* standard error. If the XOF_WARN_XML flag is set, then we generate * 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; 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); (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; 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. * Release any resources held by the handle.
* @xop XO handle to alter (or NULL for default 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_LOG_SYSLOG, "log-syslog" },
{ XOF_NO_HUMANIZE, "no-humanize" }, { XOF_NO_HUMANIZE, "no-humanize" },
{ XOF_NO_LOCALE, "no-locale" }, { XOF_NO_LOCALE, "no-locale" },
{ XOF_RETAIN_NONE, "no-retain" },
{ XOF_NO_TOP, "no-top" }, { XOF_NO_TOP, "no-top" },
{ XOF_NOT_FIRST, "not-first" }, { XOF_NOT_FIRST, "not-first" },
{ XOF_PRETTY, "pretty" }, { XOF_PRETTY, "pretty" },
{ XOF_RETAIN_ALL, "retain" },
{ XOF_UNDERSCORES, "underscores" }, { XOF_UNDERSCORES, "underscores" },
{ XOF_UNITS, "units" }, { XOF_UNITS, "units" },
{ XOF_WARN, "warn" }, { 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_end[] = "\">";
static char div_close[] = "</div>"; 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 * 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 * 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 else
xo_buf_append(pbp, "='", 2); 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; xo_xff_flags_t pflags = flags | XFF_XML | XFF_ATTR;
pflags &= ~(XFF_NO_OUTPUT | XFF_ENCODE_ONLY); pflags &= ~(XFF_NO_OUTPUT | XFF_ENCODE_ONLY);
xo_do_format_field(xop, pbp, encoding, elen, pflags); 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 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; const char *fmt = xfip->xfi_format;
unsigned flen = xfip->xfi_flen; unsigned flen = xfip->xfi_flen;
xo_xff_flags_t flags = xfip->xfi_flags; 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 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; const char *fmt = xfip->xfi_format;
unsigned flen = xfip->xfi_flen; unsigned flen = xfip->xfi_flen;
@ -4335,13 +4577,13 @@ xo_colors_enabled (xo_handle_t *xop UNUSED)
} }
static void 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 buf[BUFSIZ];
char *cp = buf, *ep = buf + sizeof(buf); char *cp = buf, *ep = buf + sizeof(buf);
unsigned i, bit; unsigned i, bit;
xo_colors_t *oldp = &xop->xo_colors; 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 '[' * 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 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; const char *fmt = xfip->xfi_format;
unsigned flen = xfip->xfi_flen; unsigned flen = xfip->xfi_flen;
@ -4534,10 +4775,9 @@ xo_format_colors (xo_handle_t *xop, xo_field_info_t *xfip)
} }
static void 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; const char *fmt = xfip->xfi_format;
unsigned flen = xfip->xfi_flen; unsigned flen = xfip->xfi_flen;
xo_xff_flags_t flags = xfip->xfi_flags; 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 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; const char *fmt = xfip->xfi_format;
unsigned flen = xfip->xfi_flen; 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. * format it when the end anchor tag is seen.
*/ */
static void 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) if (xo_style(xop) != XO_STYLE_TEXT && xo_style(xop) != XO_STYLE_HTML)
return; 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, * Now we find the width, if possible. If it's not there,
* we'll get it on the end anchor. * 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 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) if (xo_style(xop) != XO_STYLE_TEXT && xo_style(xop) != XO_STYLE_HTML)
return; return;
@ -4672,7 +4913,7 @@ xo_anchor_stop (xo_handle_t *xop, xo_field_info_t *xfip)
XOIF_CLEAR(xop, XOIF_UNITS_PENDING); 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) if (width == 0)
width = xop->xo_anchor_min_width; width = xop->xo_anchor_min_width;
@ -4787,6 +5028,7 @@ static xo_mapping_t xo_role_names[] = {
#define XO_ROLE_NEWLINE '\n' #define XO_ROLE_NEWLINE '\n'
static xo_mapping_t xo_modifier_names[] = { static xo_mapping_t xo_modifier_names[] = {
{ XFF_ARGUMENT, "argument" },
{ XFF_COLON, "colon" }, { XFF_COLON, "colon" },
{ XFF_COMMA, "comma" }, { XFF_COMMA, "comma" },
{ XFF_DISPLAY_ONLY, "display" }, { 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 * '[': start a section of anchored text
* ']': end a section of anchored text * ']': end a section of anchored text
* The following modifiers are also supported: * The following modifiers are also supported:
* 'a': content is provided via argument (const char *), not descriptor
* 'c': flag: emit a colon after the label * 'c': flag: emit a colon after the label
* 'd': field is only emitted for display styles (text and html) * 'd': field is only emitted for display styles (text and html)
* 'e': field is only emitted for encoding styles (xml and json) * '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; xo_xff_flags_t flags = 0;
uint8_t fnum = 0; uint8_t fnum = 0;
for (sp = basep; sp; sp++) { for (sp = basep; sp && *sp; sp++) {
if (*sp == ':' || *sp == '/' || *sp == '}') if (*sp == ':' || *sp == '/' || *sp == '}')
break; break;
@ -4961,6 +5204,10 @@ xo_parse_roles (xo_handle_t *xop, const char *fmt,
fnum = (fnum * 10) + (*sp - '0'); fnum = (fnum * 10) + (*sp - '0');
break; break;
case 'a':
flags |= XFF_ARGUMENT;
break;
case 'c': case 'c':
flags |= XFF_COLON; flags |= XFF_COLON;
break; break;
@ -5133,7 +5380,6 @@ static int
xo_parse_fields (xo_handle_t *xop, xo_field_info_t *fields, xo_parse_fields (xo_handle_t *xop, xo_field_info_t *fields,
unsigned num_fields, const char *fmt) unsigned num_fields, const char *fmt)
{ {
static const char default_format[] = "%s";
const char *cp, *sp, *ep, *basep; const char *cp, *sp, *ep, *basep;
unsigned field = 0; unsigned field = 0;
xo_field_info_t *xfip = fields; 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; xfip->xfi_next = ++sp;
/* If we have content, then we have a default format */ /* 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) { if (format) {
xfip->xfi_format = format; xfip->xfi_format = format;
xfip->xfi_flen = flen; xfip->xfi_flen = flen;
} else if (xo_role_wants_default_format(xfip->xfi_ftype)) { } 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; 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. * Summary: i18n aighn't cheap.
*/ */
static const char * static const char *
xo_gettext_build_format (xo_handle_t *xop UNUSED, xo_gettext_build_format (xo_handle_t *xop,
xo_field_info_t *fields UNUSED, xo_field_info_t *fields, int this_field,
int this_field UNUSED,
const char *fmt, char **new_fmtp) const char *fmt, char **new_fmtp)
{ {
if (xo_style_is_encoding(xop)) if (xo_style_is_encoding(xop))
@ -5686,17 +5931,22 @@ xo_gettext_rebuild_content (xo_handle_t *xop UNUSED,
#endif /* HAVE_GETTEXT */ #endif /* HAVE_GETTEXT */
/* /*
* The central function for emitting libxo output. * Emit a set of fields. This is really the core of libxo.
*/ */
static int 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_inuse = 0;
int gettext_changed = 0; int gettext_changed = 0;
int gettext_reordered = 0; int gettext_reordered = 0;
unsigned ftype;
xo_xff_flags_t flags;
xo_field_info_t *new_fields = NULL; xo_field_info_t *new_fields = NULL;
xo_field_info_t *xfip;
unsigned field;
int rc = 0; int rc = 0;
int flush = XOF_ISSET(xop, XOF_FLUSH); int flush = XOF_ISSET(xop, XOF_FLUSH);
int flush_line = XOF_ISSET(xop, XOF_FLUSH_LINE); int flush_line = XOF_ISSET(xop, XOF_FLUSH_LINE);
char *new_fmt = NULL; 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) if (XOIF_ISSET(xop, XOIF_REORDER) || xo_style(xop) == XO_STYLE_ENCODER)
flush_line = 0; 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 * Some overhead for gettext; if the fields in the msgstr returned
* by gettext are reordered, then we need to record start and end * 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; 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) { if (ftype == XO_ROLE_NEWLINE) {
xo_line_close(xop); xo_line_close(xop);
if (flush_line && xo_flush_h(xop) < 0) 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') 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_format, xfip->xfi_flen,
xfip->xfi_encoding, xfip->xfi_elen, flags); xfip->xfi_encoding, xfip->xfi_elen, flags);
else if (ftype == '[') else if (ftype == '[')
xo_anchor_start(xop, xfip); xo_anchor_start(xop, xfip, content, clen);
else if (ftype == ']') else if (ftype == ']')
xo_anchor_stop(xop, xfip); xo_anchor_stop(xop, xfip, content, clen);
else if (ftype == 'C') else if (ftype == 'C')
xo_format_colors(xop, xfip); xo_format_colors(xop, xfip, content, clen);
else if (ftype == 'G') { 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 * Since gettext returns strings in a static buffer, we make
* a copy in new_fmt. * 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 */ if (!gettext_inuse) { /* Only translate once */
gettext_inuse = 1; gettext_inuse = 1;
@ -5843,17 +6091,17 @@ xo_do_emit (xo_handle_t *xop, const char *fmt)
} }
continue; continue;
} else if (xfip->xfi_clen || xfip->xfi_format) { } else if (clen || xfip->xfi_format) {
const char *class_name = xo_class_name(ftype); const char *class_name = xo_class_name(ftype);
if (class_name) if (class_name)
xo_format_content(xop, class_name, xo_tag_name(ftype), 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); xfip->xfi_format, xfip->xfi_flen, flags);
else if (ftype == 'T') else if (ftype == 'T')
xo_format_title(xop, xfip); xo_format_title(xop, xfip, content, clen);
else if (ftype == 'U') else if (ftype == 'U')
xo_format_units(xop, xfip); xo_format_units(xop, xfip, content, clen);
else else
xo_failure(xop, "unknown field type: '%c'", ftype); 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 (flush && !XOIF_ISSET(xop, XOIF_ANCHOR)) {
if (xo_write(xop) < 0) if (xo_write(xop) < 0)
rc = -1; /* Report failure */ 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; rc = -1;
} }
@ -5904,6 +6152,53 @@ xo_do_emit (xo_handle_t *xop, const char *fmt)
return (rc < 0) ? rc : (int) xop->xo_columns; 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 * Rebuild a format string in a gettext-friendly format. This function
* is exposed to tools can perform this function. See xo(1). * 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); xop = xo_default(xop);
va_copy(xop->xo_vap, vap); va_copy(xop->xo_vap, vap);
rc = xo_do_emit(xop, fmt); rc = xo_do_emit(xop, 0, fmt);
va_end(xop->xo_vap); va_end(xop->xo_vap);
bzero(&xop->xo_vap, sizeof(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); xop = xo_default(xop);
va_start(xop->xo_vap, fmt); va_start(xop->xo_vap, fmt);
rc = xo_do_emit(xop, fmt); rc = xo_do_emit(xop, 0, fmt);
va_end(xop->xo_vap); va_end(xop->xo_vap);
bzero(&xop->xo_vap, sizeof(xop->xo_vap)); bzero(&xop->xo_vap, sizeof(xop->xo_vap));
@ -5972,13 +6267,137 @@ xo_emit (const char *fmt, ...)
int rc; int rc;
va_start(xop->xo_vap, fmt); va_start(xop->xo_vap, fmt);
rc = xo_do_emit(xop, fmt); rc = xo_do_emit(xop, 0, fmt);
va_end(xop->xo_vap); va_end(xop->xo_vap);
bzero(&xop->xo_vap, sizeof(xop->xo_vap)); bzero(&xop->xo_vap, sizeof(xop->xo_vap));
return rc; 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 int
xo_attr_hv (xo_handle_t *xop, const char *name, const char *fmt, va_list vap) 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 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); return xo_open_list_hf(xop, 0, name);
} }
@ -6404,7 +6823,7 @@ xo_open_list (const char *name)
} }
int 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); 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); 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; return rc;
marker_prevents_close: marker_prevents_close:
@ -7179,22 +7603,11 @@ xo_set_allocator (xo_realloc_func_t realloc_func, xo_free_func_t free_func)
int int
xo_flush_h (xo_handle_t *xop) xo_flush_h (xo_handle_t *xop)
{ {
static char div_close[] = "</div>";
int rc; int rc;
xop = xo_default(xop); xop = xo_default(xop);
switch (xo_style(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: case XO_STYLE_ENCODER:
xo_encoder_handle(xop, XO_OP_FLUSH, NULL, NULL); xo_encoder_handle(xop, XO_OP_FLUSH, NULL, NULL);
} }
@ -7435,7 +7848,7 @@ xo_set_program (const char *name)
} }
void 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); xop = xo_default(xop);

View File

@ -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_LOG_GETTEXT XOF_BIT(28) /** Log (stderr) gettext lookup strings */
#define XOF_UTF8 XOF_BIT(29) /** Force text output to be UTF8 */ #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 * 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 void
xo_clear_flags (xo_handle_t *xop, xo_xof_flags_t flags); 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 void
xo_set_info (xo_handle_t *xop, xo_info_t *infop, int count); 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 int
xo_emit (const char *fmt, ...); 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) PRINTFLIKE(2, 0)
static inline int static inline int
xo_emit_hvp (xo_handle_t *xop, const char *fmt, va_list vap) 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; 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 int
xo_open_container_h (xo_handle_t *xop, const char *name); 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_format (xo_handle_t *xop, const char *fmt, int with_numbers,
xo_simplify_field_func_t field_cb); 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 */ #endif /* INCLUDE_XO_H */

View File

@ -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

View 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

View File

@ -51,14 +51,14 @@ field descriptions within the format string.
.Pp .Pp
The field description is given as follows: The field description is given as follows:
.Bd -literal -offset indent .Bd -literal -offset indent
'{' [ role | modifier ]* [',' long-names ]* ':' [ content ] \(aq{\(aq [ role | modifier ]* [\(aq,\(aq long\-names ]* \(aq:\(aq [ content ]
[ '/' field-format [ '/' encoding-format ]] '}' [ \(aq/\(aq field\-format [ \(aq/\(aq encoding\-format ]] \(aq}\(aq
.Ed .Ed
.Pp .Pp
The role describes the function of the field, while the modifiers The role describes the function of the field, while the modifiers
enable optional behaviors. enable optional behaviors.
The contents, field-format, and The contents, field\-format, and
encoding-format are used in varying ways, based on the role. encoding\-format are used in varying ways, based on the role.
These are described in the following sections. These are described in the following sections.
.Pp .Pp
Braces can be escaped by using double braces, similar to "%%" in 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. In the following example, three field descriptors appear.
The first The first
is a padding field containing three spaces of padding, the second is a 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"). 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 The in\-stock field has a "%u" format that will parse the next argument
passed to the passed to the
.Xr xo_emit 3 , .Xr xo_emit 3 ,
function as an unsigned integer. function as an unsigned integer.
.Bd -literal -offset indent .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 .Ed
.Pp .Pp
This single line of code can generate text ("In stock: 65\\n"), XML 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). lengthy to be listed here).
.Pp .Pp
While roles and modifiers typically use single character for brevity, While roles and modifiers typically use single character for brevity,
there are alternative names for each which allow more verbose there are alternative names for each which allow more verbose
formatting strings. formatting strings.
These names must be preceded by a comma, and may follow any These names must be preceded by a comma, and may follow any
single-character values: single\-character values:
.Bd -literal -offset indent .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 .Ed
.Ss "Field Roles" .Ss "Field Roles"
Field roles are optional, and indicate the role and formatting of the 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" .Bl -column "M" "Name12341234"
.It Sy "M" "Name " "Description" .It Sy "M" "Name " "Description"
.It C "color " "Field is a color or effect" .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 E "error " "Field is an error message"
.It L "label " "Field is text that prefixes a value" .It L "label " "Field is text that prefixes a value"
.It N "note " "Field is text that follows 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 U "units " "Field is the units for the previous value field"
.It V "value " "Field is the name of field (the default)" .It V "value " "Field is the name of field (the default)"
.It W "warning " "Field is a warning message" .It W "warning " "Field is a warning message"
.It \&[ "start-anchor" "Begin 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" .It \&] "stop\-anchor " "End a section of anchored variable\-width text"
.El .El
.Bd -literal -offset indent .Bd -literal -offset indent
EXAMPLE: 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); free_blocks);
.Ed .Ed
.Pp .Pp
@ -121,50 +121,50 @@ a comma:
.Bd -literal -offset indent .Bd -literal -offset indent
EXAMPLE: EXAMPLE:
xo_emit("{,label:Free}{,decoration::}{,padding: }" xo_emit("{,label:Free}{,decoration::}{,padding: }"
"{,value:free/%u} {,units:Blocks}\n", "{,value:free/%u} {,units:Blocks}\\n",
free_blocks); free_blocks);
.Ed .Ed
.Ss "The Color Role ({C:})" .Ss "The Color Role ({C:})"
Colors and effects control how text values are displayed; they are Colors and effects control how text values are displayed; they are
used for display styles (TEXT and HTML). used for display styles (TEXT and HTML).
.Bd -literal -offset indent .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 .Ed
.Pp .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. fields.
.Bd -literal -offset indent .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 .Ed
.Pp .Pp
If the content is empty, the "reset" action is performed. If the content is empty, the "reset" action is performed.
.Bd -literal -offset indent .Bd -literal -offset indent
xo_emit("{C:both,underline}{:value}{C:}\n", value); xo_emit("{C:both,underline}{:value}{C:}\\n", value);
.Ed .Ed
.Pp .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. display effects.
.Bd -literal -offset indent .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 .Ed
.Pp .Pp
The color content can be either static, when placed directly within 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 ("/"): if preceded by a slash ("/"):
.Bd -literal -offset indent .Bd -literal -offset indent
xo_emit("{C:/%s%s}{:value}{C:}", need_bold ? "bold" : "", xo_emit("{C:/%s%s}{:value}{C:}", need_bold ? "bold" : "",
need_underline ? "underline" : "", value); need_underline ? "underline" : "", value);
.Ed .Ed
.Pp .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. foreground and background colors, respectively.
.Bd -literal -offset indent .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); fg_color, bg_color, cost);
.Ed .Ed
.Pp .Pp
The following table lists the supported effects: The following table lists the supported effects:
.Bl -column "no-underline" .Bl -column "no\-underline"
.It Sy "Name " "Description" .It Sy "Name " "Description"
.It "bg\-xxxxx " "Change background color" .It "bg\-xxxxx " "Change background color"
.It "bold " "Start bold text effect" .It "bold " "Start bold text effect"
@ -179,7 +179,7 @@ The following table lists the supported effects:
.El .El
.Pp .Pp
The following color names are supported: The following color names are supported:
.Bl -column "no-underline" .Bl -column "no\-underline"
.It Sy "Name" .It Sy "Name"
.It black .It black
.It blue .It blue
@ -193,7 +193,7 @@ The following color names are supported:
.El .El
.Ss "The Decoration Role ({D:})" .Ss "The Decoration Role ({D:})"
Decorations are typically punctuation marks such as colons, 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. for human readers.
By marking these distinctly, HTML usage scenarios By marking these distinctly, HTML usage scenarios
can use CSS to direct their display parameters. 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. inspection of all .po files.
.Pp .Pp
The simplified version can be generated for a single message using the The simplified version can be generated for a single message using the
"xopo -s <text>" command, or an entire .pot can be translated using "xopo \-s <text>" command, or an entire .pot can be translated using
the "xopo -f <input> -o <output>" command. the "xopo \-f <input> \-o <output>" command.
.Bd -literal -offset indent .Bd -literal -offset indent
xo_emit("{G:}Invalid token\n"); xo_emit("{G:}Invalid token\\n");
.Ed .Ed
.Pp
The {G:} role allows a domain name to be set. The {G:} role allows a domain name to be set.
.Fn gettext .Fn gettext
calls will calls will
continue to use that domain name until the current format string continue to use that domain name until the current format string
processing is complete, enabling a library function to emit strings 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 The domain name can be either static as the
content of the field, or a format can be used to get the domain name content of the field, or a format can be used to get the domain name
from the arguments. from the arguments.
.Bd -literal -offset indent .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 .Ed
.Ss "The Label Role ({L:})" .Ss "The Label Role ({L:})"
Labels are text that appears before a value. 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:})" .Ss "The Padding Role ({P:})"
Padding represents whitespace used before and between fields. Padding represents whitespace used before and between fields.
The padding content can be either static, when placed directly within 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 ("/"): if preceded by a slash ("/"):
.Bd -literal -offset indent .Bd -literal -offset indent
xo_emit("{P: }{Lwc:Cost}{:cost/%u}\\n", cost); 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 Titles are heading or column headers that are meant to be displayed to
the user. the user.
The title can be either static, when placed directly within 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 ("/"): if preceded by a slash ("/"):
.Bd -literal -offset indent .Bd -literal -offset indent
xo_emit("{T:Interface Statistics}\\n"); 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); xo_emit("{Lwc:Distance}{:distance/%u}{Uw:miles}\\n", miles);
.Ed .Ed
.Pp .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. a blank is added before the contents, rather than after it.
.Pp .Pp
When the When the
@ -286,14 +287,14 @@ attribute:
<distance units="miles">50</distance> <distance units="miles">50</distance>
.Ed .Ed
.Pp .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 .Bd -literal -offset indent
<div class="data" data-tag="distance" data-units="miles" <div class="data" data\-tag="distance" data\-units="miles"
data-xpath="/top/data/distance">50</div> data\-xpath="/top/data/distance">50</div>
.Ed .Ed
.Ss "The Value Role ({V:} and {:})" .Ss "The Value Role ({V:} and {:})"
The value role is used to represent the a data value that is 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 Value
is the default role; if no other role designation is given, the field is the default role; if no other role designation is given, the field
is a value. is a value.
@ -356,16 +357,17 @@ Field modifiers are flags which modify the way content emitted for
particular output styles: particular output styles:
.Bl -column M "Name123456789" .Bl -column M "Name123456789"
.It Sy M "Name " "Description" .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 c "colon " "A colon ("":"") is appended after the label"
.It d "display " "Only emit field for display styles (text/HTML)" .It d "display " "Only emit field for display styles (text/HTML)"
.It e "encoding " "Only emit for encoding styles (XML/JSON)" .It e "encoding " "Only emit for encoding styles (XML/JSON)"
.It h "humanize (hn) " "Format large numbers in human-readable style" .It h "humanize (hn) " "Format large numbers in human\-readable style"
.It " " "hn-space " "Humanize: Place space between numeric and unit" .It " " "hn\-space " "Humanize: Place space between numeric and unit"
.It " " "hn-decimal " "Humanize: Add a decimal digit, if number < 10" .It " " "hn\-decimal " "Humanize: Add a decimal digit, if number < 10"
.It " " "hn-1000 " "Humanize: Use 1000 as divisor instead of 1024" .It " " "hn\-1000 " "Humanize: Use 1000 as divisor instead of 1024"
.It k "key " "Field is a key, suitable for XPath predicates" .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 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 n "no\-quotes " "Do not quote the field when using JSON style"
.It q "quotes " "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 t "trim " "Trim leading and trailing whitespace"
.It w "white space " "A blank ("" "") is appended after the label" .It w "white space " "A blank ("" "") is appended after the label"
@ -373,7 +375,7 @@ particular output styles:
.Pp .Pp
For example, the modifier string "Lwc" means the field has a label 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 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 The modifier string "Vkq" means the
field has a value role, that it is a key for the current instance, and 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. 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. a comma.
For example, the modifier string "Lwc" (or "L,white,colon") For example, the modifier string "Lwc" (or "L,white,colon")
means the field has a label role (text that describes the next field) 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 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, role (the default role), that it is a key for the current instance,
and that the value should be quoted when encoded for JSON. 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:})" .Ss "The Colon Modifier ({c:})"
The colon modifier appends a single colon to the data value: The colon modifier appends a single colon to the data value:
.Bd -literal -offset indent .Bd -literal -offset indent
@ -397,7 +420,7 @@ The colon modifier appends a single colon to the data value:
.Pp .Pp
The colon modifier is only used for the TEXT and HTML output The colon modifier is only used for the TEXT and HTML output
styles. 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. It is purely a convenience feature.
.Ss "The Display Modifier ({d:})" .Ss "The Display Modifier ({d:})"
The display modifier indicated the field should only be generated for 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. they are often used to give to distinct views of the underlying data.
.Ss "The Humanize Modifier ({h:})" .Ss "The Humanize Modifier ({h:})"
The humanize modifier is used to render large numbers as in a 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 While numbers like "44470272" are completely readable to computers and
savants, humans will generally find "44M" more meaningful. savants, humans will generally find "44M" more meaningful.
.Pp .Pp
"hn" can be used as an alias for "humanize". "hn" can be used as an alias for "humanize".
.Pp .Pp
The humanize modifier only affects display styles (TEXT and HMTL). 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 .Pp
There are a number of modifiers that affect details of humanization. There are a number of modifiers that affect details of humanization.
These are only available in as full names, not single characters. 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"). 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"). when the number is less than 10 (ex: "4.4K").
The "hn-1000" modifier will use 1000 as divisor instead of 1024, following the 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 JEDEC\-standard instead of the more natural binary powers\-of\-two
tradition. tradition.
.Bd -literal -offset indent .Bd -literal -offset indent
EXAMPLE: EXAMPLE:
xo_emit("{h:input/%u}, {h,hn-space:output/%u}, " xo_emit("{h:input/%u}, {h,hn\-space:output/%u}, "
"{h,hn-decimal:errors/%u}, {h,hn-1000:capacity/%u}, " "{h,hn\-decimal:errors/%u}, {h,hn\-1000:capacity/%u}, "
"{h,hn-decimal:remaining/%u}\n", "{h,hn\-decimal:remaining/%u}\\n",
input, output, errors, capacity, remaining); input, output, errors, capacity, remaining);
TEXT: TEXT:
21, 57 K, 96M, 44M, 1.2G 21, 57 K, 96M, 44M, 1.2G
.Ed .Ed
.Pp .Pp
In the HTML style, the original numeric value is rendered in the 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 .Bd -literal -offset indent
<div class="data" data-tag="errors" <div class="data" data\-tag="errors"
data-number="100663296">96M</div> data\-number="100663296">96M</div>
.Ed .Ed
.Ss "The Gettext Modifier ({g:})" .Ss "The Gettext Modifier ({g:})"
The gettext modifier is used to translate individual fields using the 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 In the following example, the strings "State" and "full" are passed
to to
.Fn gettext .Fn gettext
to find locale-based translated strings. to find locale\-based translated strings.
.Bd -literal -offset indent .Bd -literal -offset indent
xo_emit("{Lgwc:State}{g:state}\n", "full"); xo_emit("{Lgwc:State}{g:state}\\n", "full");
.Ed .Ed
.Ss "The Key Modifier ({k:})" .Ss "The Key Modifier ({k:})"
The key modifier is used to indicate that a particular field helps 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 for the HTML output style when
.Dv XOF_XPATH .Dv XOF_XPATH
is set, but other uses are likely in the near future. is set, but other uses are likely in the near future.
.Ss "The Leaf-List Modifier ({l:})" .Ss "The Leaf\-List Modifier ({l:})"
The leaf-list modifier is used to distinguish lists where each The leaf\-list modifier is used to distinguish lists where each
instance consists of only a single value. In XML, these are instance consists of only a single value. In XML, these are
rendered as single elements, where JSON renders them as arrays. rendered as single elements, where JSON renders them as arrays.
.Bd -literal -offset indent .Bd -literal -offset indent
EXAMPLE: EXAMPLE:
xo_open_list("user"); xo_open_list("user");
for (i = 0; i < num_users; i++) { 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"); xo_close_list("user");
XML: XML:
@ -516,8 +539,8 @@ rendered as single elements, where JSON renders them as arrays.
JSON: JSON:
"user": [ "phil", "pallavi" ] "user": [ "phil", "pallavi" ]
.Ed .Ed
.Ss "The No-Quotes Modifier ({n:})" .Ss "The No\-Quotes Modifier ({n:})"
The no-quotes modifier (and its twin, the 'quotes' modifier) affect The no\-quotes modifier (and its twin, the \(aqquotes\(aq modifier) affect
the quoting of values in the JSON output style. the quoting of values in the JSON output style.
JSON uses quotes for JSON uses quotes for
string values, but no quotes for numeric, boolean, and null data. 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 The contents of the field should be the singular
and plural English values, separated by a comma: and plural English values, separated by a comma:
.Bd -literal -offset indent .Bd -literal -offset indent
xo_emit("{:bytes} {Ngp:byte,bytes}\n", bytes); xo_emit("{:bytes} {Ngp:byte,bytes}\\n", bytes);
.Ed .Ed
.Pp
The plural modifier is meant to work with the gettext modifier ({g:}) The plural modifier is meant to work with the gettext modifier ({g:})
but can work independently. but can work independently.
.Pp .Pp
@ -554,7 +578,7 @@ function is
called to handle the heavy lifting, using the message catalog to called to handle the heavy lifting, using the message catalog to
convert the singular and plural forms into the native language. convert the singular and plural forms into the native language.
.Ss "The Quotes Modifier ({q:})" .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. the quoting of values in the JSON output style.
JSON uses quotes for JSON uses quotes for
string values, but no quotes for numeric, boolean, and null data. 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 .Pp
The white space modifier is only used for the TEXT and HTML output The white space modifier is only used for the TEXT and HTML output
styles. 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. It is purely a convenience feature.
.Pp .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. ({Uw:}); a blank is added before the contents, rather than after it.
.Ss "Field Formatting" .Ss "Field Formatting"
The field format is similar to the format string for The field format is similar to the format string for
.Xr printf 3 . .Xr printf 3 .
Its use varies based on the role of the field, but generally is used to 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 .Pp
If the format string is not provided for a value field, it defaults If the format string is not provided for a value field, it defaults
to "%s". to "%s".
.Pp .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 , .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". one of following characters: "diouxXDOUeEfFgGaAcCsSp".
Each directive Each directive
is matched by one of more arguments to the is matched by one of more arguments to the
@ -603,54 +627,54 @@ function.
.Pp .Pp
The format string has the form: The format string has the form:
.Bd -literal -offset indent .Bd -literal -offset indent
'%' format-modifier * format-character \(aq%\(aq format\-modifier * format\-character
.Ed .Ed
.Pp .Pp
The format- modifier can be: The format\- modifier can be:
.Bl -bullet .Bl -bullet
.It .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. "0x", typically to indicate a base 16 (hex) value.
.It .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. the right instead of the left.
.It .It
a leading zero ('0') indicating the output value should be padded on the a leading zero (\(aq0\(aq) indicating the output value should be padded on the
left with zeroes instead of spaces (' '). left with zeroes instead of spaces (\(aq \(aq).
.It .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. argument.
If the width in columns of the output value is less than If the width in columns of the output value is less than
the minimum width, the value will be padded to reach the minimum. the minimum width, the value will be padded to reach the minimum.
.It .It
a period followed by one or more digits indicating the maximum 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 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 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. character may be composed of multiple bytes.
.Xr xo_emit 3 .Xr xo_emit 3
will never dereference memory beyond the given number of bytes. will never dereference memory beyond the given number of bytes.
.It .It
a second period followed by one or more digits indicating the maximum a second period followed by one or more digits indicating the maximum
width for a string argument. width for a string argument.
This modifier cannot be given for non-string arguments. This modifier cannot be given for non\-string arguments.
.It .It
one or more 'h' characters, indicating shorter input data. one or more \(aqh\(aq characters, indicating shorter input data.
.It .It
one or more 'l' characters, indicating longer input data. one or more \(aql\(aq characters, indicating longer input data.
.It .It
a 'z' character, indicating a 'size_t' argument. a \(aqz\(aq character, indicating a \(aqsize_t\(aq argument.
.It .It
a 't' character, indicating a 'ptrdiff_t' argument. a \(aqt\(aq character, indicating a \(aqptrdiff_t\(aq argument.
.It .It
a ' ' character, indicating a space should be emitted before a \(aq \(aq character, indicating a space should be emitted before
positive numbers. positive numbers.
.It .It
a '+' character, indicating sign should emitted before any number. a \(aq+\(aq character, indicating sign should emitted before any number.
.El .El
.Pp .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. removed eventually.
.Pp .Pp
The format character is described in the following table: 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 D "long " "base 10 (decimal)"
.It O "unsigned long " "base 8 (octal)" .It O "unsigned long " "base 8 (octal)"
.It U "unsigned long " "base 10 (decimal)" .It U "unsigned long " "base 10 (decimal)"
.It e "double " "[-]d.ddde+-dd" .It e "double " "[\-]d.ddde+\-dd"
.It E "double " "[-]d.dddE+-dd" .It E "double " "[\-]d.dddE+\-dd"
.It f "double " "[-]ddd.ddd" .It f "double " "[\-]ddd.ddd"
.It F "double " "[-]ddd.ddd" .It F "double " "[\-]ddd.ddd"
.It g "double " "as 'e' or 'f'" .It g "double " "as \(aqe\(aq or \(aqf\(aq"
.It G "double " "as 'E' or 'F'" .It G "double " "as \(aqE\(aq or \(aqF\(aq"
.It a "double " "[-]0xh.hhhp[+-]d" .It a "double " "[\-]0xh.hhhp[+\-]d"
.It A "double " "[-]0Xh.hhhp[+-]d" .It A "double " "[\-]0Xh.hhhp[+\-]d"
.It c "unsigned char " "a character" .It c "unsigned char " "a character"
.It C "wint_t " "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 S "wchar_t * " "a unicode/WCS string"
.It p "void * " "'%#lx'" .It p "void * " "\(aq%#lx\(aq"
.El .El
.Pp .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: argument:
.Bl -column "Mod" "d, i " "o, u, x, X " .Bl -column "Mod" "d, i " "o, u, x, X "
.It Sy "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 "z " "size_t " "size_t"
.It "q " "quad_t " "u_quad_t" .It "q " "quad_t " "u_quad_t"
.El .El
.Ss "UTF-8 and Locale Strings" .Ss "UTF\-8 and Locale Strings"
All strings for All strings for
.Nm libxo .Nm libxo
must be UTF-8. must be UTF\-8.
.Nm libxo .Nm libxo
will handle turning them will handle turning them
into locale-based strings for display to the user. into locale\-based strings for display to the user.
.Pp .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 bytes pointed to argument.
The default '%s' string is a 'char *' The default \(aq%s\(aq string is a \(aqchar *\(aq
pointer to a string encoded as UTF-8. pointer to a string encoded as UTF\-8.
Since UTF-8 is compatible with Since UTF\-8 is compatible with
.Em ASCII .Em ASCII
data, a normal 7-bit data, a normal 7\-bit
.Em ASCII .Em ASCII
string can be used. string can be used.
"%ls" expects a "%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. 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 string encoded with the current locale, as given by the
.Ev LC_CTYPE , .Ev LC_CTYPE ,
.Ev LANG , .Ev LANG ,
@ -722,22 +746,22 @@ or
environment variables. environment variables.
The first of this list of The first of this list of
variables is used and if none of the variables are set, the locale defaults to variables is used and if none of the variables are set, the locale defaults to
.Em UTF-8 . .Em UTF\-8 .
.Pp .Pp
.Nm libxo .Nm libxo
will will
convert these arguments as needed to either UTF-8 (for XML, JSON, and convert these arguments as needed to either UTF\-8 (for XML, JSON, and
HTML styles) or locale-based strings for display in text style. HTML styles) or locale\-based strings for display in text style.
.Bd -literal -offset indent .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"); L"except for wide strings");
.Ed .Ed
.Pp .Pp
"%S" is equivalent to "%ls". "%S" is equivalent to "%ls".
.Pp .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. 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. string, and the time value is formatted into a wchar_t string.
.Bd -literal -offset indent .Bd -literal -offset indent
void print_order (const char *name, int size, 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", xo_emit("The hat for {:name/%hs} is {:size/%s}.\\n",
name, size_val); name, size_val);
xo_emit("It was ordered on {:order-time/%ls}.\\n", xo_emit("It was ordered on {:order\-time/%ls}.\\n",
when); when);
} }
.Ed .Ed
@ -766,11 +790,11 @@ will perform the conversion
required to make appropriate output. required to make appropriate output.
Text style output uses the Text style output uses the
current locale (as described above), while XML, JSON, and HTML use current locale (as described above), while XML, JSON, and HTML use
UTF-8. UTF\-8.
.Pp .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. 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 for "%s" printf formatting becomes overloaded since it specifies both
the number of bytes that can be safely referenced and the maximum the number of bytes that can be safely referenced and the maximum
number of columns to emit. number of columns to emit.
@ -800,12 +824,12 @@ For HTML, these characters are placed in a <div> with class "text".
"size": "extra small" "size": "extra small"
HTML: HTML:
<div class="text">The hat is </div> <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> <div class="text">.</div>
.Ed .Ed
.Ss "'%n' is Not Supported" .Ss "\(aq%n\(aq is Not Supported"
.Nm libxo .Nm libxo
does not support the '%n' directive. does not support the \(aq%n\(aq directive.
It is a bad idea and we It is a bad idea and we
just do not do it. just do not do it.
.Ss "The Encoding Format (eformat)" .Ss "The Encoding Format (eformat)"
@ -817,7 +841,7 @@ If the primary is not given, both default to "%s".
.Sh EXAMPLE .Sh EXAMPLE
In this example, the value for the number of items in stock is emitted: In this example, the value for the number of items in stock is emitted:
.Bd -literal -offset indent .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); instock);
.Ed .Ed
.Pp .Pp
@ -826,16 +850,16 @@ This call will generate the following output:
TEXT: TEXT:
In stock: 144 In stock: 144
XML: XML:
<in-stock>144</in-stock> <in\-stock>144</in\-stock>
JSON: JSON:
"in-stock": 144, "in\-stock": 144,
HTML: HTML:
<div class="line"> <div class="line">
<div class="padding"> </div> <div class="padding"> </div>
<div class="label">In stock</div> <div class="label">In stock</div>
<div class="decoration">:</div> <div class="decoration">:</div>
<div class="padding"> </div> <div class="padding"> </div>
<div class="data" data-tag="in-stock">144</div> <div class="data" data\-tag="in\-stock">144</div>
</div> </div>
.Ed .Ed
.Pp .Pp
@ -846,10 +870,10 @@ or
.Dv XOF_INFO .Dv XOF_INFO
data, which would expand the penultimate line to: data, which would expand the penultimate line to:
.Bd -literal -offset indent .Bd -literal -offset indent
<div class="data" data-tag="in-stock" <div class="data" data\-tag="in\-stock"
data-xpath="/top/data/item/in-stock" data\-xpath="/top/data/item/in\-stock"
data-type="number" data\-type="number"
data-help="Number of items in stock">144</div> data\-help="Number of items in stock">144</div>
.Ed .Ed
.Sh WHAT MAKES A GOOD FIELD NAME? .Sh WHAT MAKES A GOOD FIELD NAME?
To make useful, consistent field names, follow these guidelines: 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" .Ss "Use full words"
Do not abbreviate especially when the abbreviation is not obvious or Do not abbreviate especially when the abbreviation is not obvious or
not widely used. not widely used.
Use "data-size", not "dsz" or "dsize". Use "data\-size", not "dsz" or "dsize".
Use Use
"interface" instead of "ifname", "if-name", "iface", "if", or "intf". "interface" instead of "ifname", "if\-name", "iface", "if", or "intf".
.Ss "Use <verb>-<units>" .Ss "Use <verb>\-<units>"
Using the form <verb>-<units> or <verb>-<classifier>-<units> helps in Using the form <verb>\-<units> or <verb>\-<classifier>\-<units> helps in
making consistent, useful names, avoiding the situation where one app making consistent, useful names, avoiding the situation where one app
uses "sent-packet" and another "packets-sent" and another uses "sent\-packet" and another "packets\-sent" and another
"packets-we-have-sent". "packets\-we\-have\-sent".
The <units> can be dropped when it is The <units> can be dropped when it is
obvious, as can obvious words in the classification. obvious, as can obvious words in the classification.
Use "receive-after-window-packets" instead of Use "receive\-after\-window\-packets" instead of
"received-packets-of-data-after-window". "received\-packets\-of\-data\-after\-window".
.Ss "Reuse existing field names" .Ss "Reuse existing field names"
Nothing is worse than writing expressions like: Nothing is worse than writing expressions like:
.Bd -literal -offset indent .Bd -literal -offset indent
if ($src1/process[pid == $pid]/name == 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 .Ed
@ -903,7 +927,7 @@ calls or "{e:}" fields to make the data useful.
.Ss "Do not use an arbitrary number postfix" .Ss "Do not use an arbitrary number postfix"
What does "errors2" mean? What does "errors2" mean?
No one will know. 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. Think of your users, and think of the future.
If you make "errors2", the next guy will happily make If you make "errors2", the next guy will happily make
"errors3" and before you know it, someone will be asking what is the "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, You want it useful,
expressive, meaningful, direct, and obvious. expressive, meaningful, direct, and obvious.
You want the client 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. understand a variety of opinions on how fields are named.
They should They should
see the system as a single cohesive whole, not a sack of cats. 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 After using
.Xr xolint 1 .Xr xolint 1
to find errors in your field descriptors, use to find errors in your field descriptors, use
.Dq "xolint -V" .Dq "xolint \-V"
to spell check your field names and to detect different to spell check your field names and to detect different
names for the same data. names for the same data.
.Dq dropped-short .Dq dropped\-short
and and
.Dq dropped-too-short .Dq dropped\-too\-short
are both reasonable names, but using them both will lead users to ask the are both reasonable names, but using them both will lead users to ask the
difference between the two fields. difference between the two fields.
If there is no difference, If there is no difference,

View File

@ -83,12 +83,16 @@ Log (via stderr) each syslog message (via
Ignore the {h:} modifier (TEXT, HTML) Ignore the {h:} modifier (TEXT, HTML)
.It Dv no-locale .It Dv no-locale
Do not initialize the locale setting Do not initialize the locale setting
.It Dv no-retain
Prevent retaining formatting information
.It Dv no-top .It Dv no-top
Do not emit a top set of braces (JSON) Do not emit a top set of braces (JSON)
.It Dv not-first .It Dv not-first
Pretend the 1st output item was not 1st (JSON) Pretend the 1st output item was not 1st (JSON)
.It Dv pretty .It Dv pretty
Emit pretty-printed output Emit pretty-printed output
.It Dv retain
Force retaining formatting information
.It Dv text .It Dv text
Emit TEXT output Emit TEXT output
.If Dv underscores .If Dv underscores

View File

@ -5,7 +5,7 @@ includedir=@includedir@
Name: libxo Name: libxo
Version: @VERSION@ Version: @LIBXO_VERSION@
Description: The XML Output Library Description: The XML Output Library
Libs: @LIBXO_LIBDIR@ @LIBXO_LIBS@ Libs: -L@XO_LIBDIR@ @XO_LIBS@
Cflags: @LIBXO_INCLUDEDIR@ Cflags: -I@XO_INCLUDEDIR@

View File

@ -6,15 +6,15 @@
require 'formula' require 'formula'
class Libxo < Formula class Libxo < Formula
homepage 'https://github.com/Juniper/@PACKAGE-NAME@' homepage 'https://github.com/Juniper/@PACKAGE_NAME@'
url 'https://github.com/Juniper/@PACKAGE_NAME@/releases/@PACKAGE_VERSION@/@PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz' url 'https://github.com/Juniper/@PACKAGE_NAME@/releases/download/@PACKAGE_VERSION@/@PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz'
sha1 '__SHA1__' sha1 '__SHA1__'
depends_on 'libtool' => :build depends_on 'libtool' => :build
def install def install
system "./configure", "--disable-dependency-tracking", system "./configure", "--disable-dependency-tracking", "--disable-silent-rules",
"--prefix=#{prefix}" "--prefix=#{prefix}"
system "make install" system "make", "install"
end end
end end

View File

@ -22,7 +22,8 @@ test_07.c \
test_08.c \ test_08.c \
test_09.c \ test_09.c \
test_10.c \ test_10.c \
test_11.c test_11.c \
test_12.c
test_01_test_SOURCES = test_01.c test_01_test_SOURCES = test_01.c
test_02_test_SOURCES = test_02.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_09_test_SOURCES = test_09.c
test_10_test_SOURCES = test_10.c test_10_test_SOURCES = test_10.c
test_11_test_SOURCES = test_11.c test_11_test_SOURCES = test_11.c
test_12_test_SOURCES = test_12.c
# TEST_CASES := $(shell cd ${srcdir} ; echo *.c ) # TEST_CASES := $(shell cd ${srcdir} ; echo *.c )

View File

@ -2,6 +2,14 @@ op create: [] []
op open_container: [top] [] op open_container: [top] []
op string: [host] [my-box] op string: [host] [my-box]
op string: [domain] [example.com] 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 attr: [test] [value]
op open_container: [data] [] op open_container: [data] []
op open_list: [item] [] op open_list: [item] []
@ -114,6 +122,16 @@ op close_list: [item] []
op close_container: [data4] [] op close_container: [data4] []
op content: [cost] [425] op content: [cost] [425]
op content: [cost] [455] 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 close_container: [top] []
op finish: [] [] op finish: [] []
op flush: [] [] op flush: [] []

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,26 @@
<div class="line"> <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="text">Connecting to </div>
<div class="data" data-tag="host" data-xpath="/top/host">my-box</div> <div class="data" data-tag="host" data-xpath="/top/host">my-box</div>
<div class="text">.</div> <div class="text">.</div>
@ -301,3 +323,22 @@
<div class="padding"> </div> <div class="padding"> </div>
<div class="data" data-tag="cost" data-xpath="/top/cost">455</div> <div class="data" data-tag="cost" data-xpath="/top/cost">455</div>
</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>

View File

@ -1,4 +1,26 @@
<div class="line"> <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="text">Connecting to </div>
<div class="data" data-tag="host">my-box</div> <div class="data" data-tag="host">my-box</div>
<div class="text">.</div> <div class="text">.</div>
@ -301,3 +323,22 @@
<div class="padding"> </div> <div class="padding"> </div>
<div class="data" data-tag="cost">455</div> <div class="data" data-tag="cost">455</div>
</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>

View File

@ -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"}
} }

View File

@ -1,5 +1,13 @@
{ {
"top": { "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", "host": "my-box",
"domain": "example.com", "domain": "example.com",
"data": { "data": {
@ -101,6 +109,16 @@
] ]
}, },
"cost": 425, "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"
} }
} }

View File

@ -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... Connecting to my-box.example.com...
Item Total Sold In Stock On Order SKU Item Total Sold In Stock On Order SKU
gum 1412 54 10 GRO-000-415 gum 1412 54 10 GRO-000-415
@ -45,3 +49,5 @@ Item: water
XXXXXXXX XXXXXXXX
X XCost: 425 X XCost: 425
X XCost: 455 X XCost: 455
links user group
/some/file 1 user group

View File

@ -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>

View File

@ -1,4 +1,12 @@
<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> <host>my-box</host>
<domain>example.com</domain> <domain>example.com</domain>
<data test="value"> <data test="value">
@ -93,4 +101,14 @@
</data4> </data4>
<cost>425</cost> <cost>425</cost>
<cost>455</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> </top>

View 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: [] []

View 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>

View 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>

View 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>

View 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}]}}
}

View 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
}
]
}
}
}

View 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

View 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>

View 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>

View File

@ -79,6 +79,18 @@ main (int argc, char **argv)
xo_open_container_h(NULL, "top"); 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_emit("Connecting to {:host}.{:domain}...\n", "my-box", "example.com");
xo_attr("test", "value"); 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: }X{Lwc:Cost}{:cost/%u}\n", 425);
xo_emit("X{P:/%30s}X{Lwc:Cost}{:cost/%u}\n", "", 455); 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_close_container_h(NULL, "top");
xo_finish(); xo_finish();

View File

@ -42,6 +42,7 @@ main (int argc, char **argv)
} }
xo_set_flags(NULL, XOF_UNITS); /* Always test w/ this */ xo_set_flags(NULL, XOF_UNITS); /* Always test w/ this */
xo_set_file(stdout);
xo_open_container_h(NULL, "top"); xo_open_container_h(NULL, "top");

View 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;
}

View File

@ -26,7 +26,7 @@ int
main (int argc, char **argv) main (int argc, char **argv)
{ {
static char domainname[] = "gt_01"; static char domainname[] = "gt_01";
char path[MAXPATHLEN]; static char path[MAXPATHLEN];
const char *tzone = "EST"; const char *tzone = "EST";
const char *lang = "pig_latin"; const char *lang = "pig_latin";

View File

@ -133,13 +133,8 @@ _MARCHS+= x86
META_TARGETS+= compat copies symlinks META_TARGETS+= compat copies symlinks
stage_includes: ${SHARED} stage_includes: ${SHARED}
.include <bsd.prog.mk>
installincludes: ${SHARED}
${SHARED}: compat
# Take care of stale directory-level symlinks. # Take care of stale directory-level symlinks.
compat: ${META_DEPS} compat:
.for i in ${LDIRS} ${LSUBDIRS} machine ${_MARCHS} crypto .for i in ${LDIRS} ${LSUBDIRS} machine ${_MARCHS} crypto
if [ -L ${DESTDIR}${INCLUDEDIR}/$i ]; then \ if [ -L ${DESTDIR}${INCLUDEDIR}/$i ]; then \
rm -f ${DESTDIR}${INCLUDEDIR}/$i; \ rm -f ${DESTDIR}${INCLUDEDIR}/$i; \
@ -149,7 +144,7 @@ compat: ${META_DEPS}
-f ${.CURDIR}/../etc/mtree/BSD.include.dist \ -f ${.CURDIR}/../etc/mtree/BSD.include.dist \
-p ${DESTDIR}${INCLUDEDIR} > /dev/null -p ${DESTDIR}${INCLUDEDIR} > /dev/null
copies: ${META_DEPS} copies:
.for i in ${LDIRS} ${LSUBDIRS} ${LSUBSUBDIRS} crypto machine machine/pc \ .for i in ${LDIRS} ${LSUBDIRS} ${LSUBSUBDIRS} crypto machine machine/pc \
${_MARCHS} ${_MARCHS}
if [ -d ${DESTDIR}${INCLUDEDIR}/$i ]; then \ 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 \ ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 teken.h \
${DESTDIR}${INCLUDEDIR}/teken ${DESTDIR}${INCLUDEDIR}/teken
symlinks: ${META_DEPS} symlinks:
@${ECHO} "Setting up symlinks to kernel source tree..." @${ECHO} "Setting up symlinks to kernel source tree..."
.for i in ${LDIRS} .for i in ${LDIRS}
cd ${.CURDIR}/../sys/$i; \ cd ${.CURDIR}/../sys/$i; \
@ -349,6 +344,11 @@ symlinks: ${META_DEPS}
${DESTDIR}${INCLUDEDIR}/rpc; \ ${DESTDIR}${INCLUDEDIR}/rpc; \
done done
.include <bsd.prog.mk>
installincludes: ${SHARED}
${SHARED}: compat
.if ${MACHINE} == "host" && !defined(_SKIP_BUILD) .if ${MACHINE} == "host" && !defined(_SKIP_BUILD)
# we're here because we are building a sysroot... # we're here because we are building a sysroot...
# we need MACHINE et al set correctly # we need MACHINE et al set correctly

View File

@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
.data .data
.align 3 .align 3
.globl _C_LABEL(minbrk) .globl _C_LABEL(minbrk)
.hidden _C_LABEL(minbrk)
.type _C_LABEL(minbrk),#object .type _C_LABEL(minbrk),#object
_C_LABEL(minbrk): _C_LABEL(minbrk):
.quad _C_LABEL(_end) .quad _C_LABEL(_end)

View File

@ -29,6 +29,7 @@
__FBSDID("$FreeBSD$"); __FBSDID("$FreeBSD$");
ENTRY(cerror) ENTRY(cerror)
.hidden cerror
sub sp, sp, #16 sub sp, sp, #16
stp x0, lr, [sp] stp x0, lr, [sp]
bl _C_LABEL(__error) bl _C_LABEL(__error)

View File

@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
.data .data
.align 3 .align 3
.global _C_LABEL(curbrk) .global _C_LABEL(curbrk)
.hidden _C_LABEL(curbrk)
.type _C_LABEL(curbrk),#object .type _C_LABEL(curbrk),#object
_C_LABEL(curbrk): _C_LABEL(curbrk):
.quad _C_LABEL(_end) .quad _C_LABEL(_end)

View File

@ -102,7 +102,7 @@ cam_freeccb(union ccb *ccb)
* /dev/foo0 * /dev/foo0
* foo0 * foo0
* nfoo0 * nfoo0
* *
* Some peripheral drivers create separate device nodes with 'n' prefix for * Some peripheral drivers create separate device nodes with 'n' prefix for
* non-rewind operations. Currently only sa(4) tape driver has this feature. * non-rewind operations. Currently only sa(4) tape driver has this feature.
* We extract pure peripheral name as device name for this special case. * We extract pure peripheral name as device name for this special case.
@ -194,7 +194,7 @@ cam_get_device(const char *path, char *dev_name, int devnamelen, int *unit)
/* /*
* At this point, if the last character of the string isn't a * At this point, if the last character of the string isn't a
* number, we know the user either didn't give us a device number, * number, we know the user either didn't give us a device number,
* or he gave us a device name/number format we don't recognize. * or he gave us a device name/number format we don't recognize.
*/ */
if (!isdigit(tmpstr[strlen(tmpstr) - 1])) { if (!isdigit(tmpstr[strlen(tmpstr) - 1])) {
@ -275,7 +275,7 @@ cam_open_btl(path_id_t path_id, target_id_t target_id, lun_id_t target_lun,
int fd, bufsize; int fd, bufsize;
if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) { if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
snprintf(cam_errbuf, CAM_ERRBUF_SIZE, snprintf(cam_errbuf, CAM_ERRBUF_SIZE,
"%s: couldn't open %s\n%s: %s", func_name, XPT_DEVICE, "%s: couldn't open %s\n%s: %s", func_name, XPT_DEVICE,
func_name, strerror(errno)); func_name, strerror(errno));
return(NULL); return(NULL);
@ -292,7 +292,7 @@ cam_open_btl(path_id_t path_id, target_id_t target_id, lun_id_t target_lun,
ccb.cdm.match_buf_len = bufsize; ccb.cdm.match_buf_len = bufsize;
ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize); ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
if (ccb.cdm.matches == NULL) { if (ccb.cdm.matches == NULL) {
snprintf(cam_errbuf, CAM_ERRBUF_SIZE, snprintf(cam_errbuf, CAM_ERRBUF_SIZE,
"%s: couldn't malloc match buffer", func_name); "%s: couldn't malloc match buffer", func_name);
close(fd); close(fd);
return(NULL); return(NULL);
@ -305,14 +305,14 @@ cam_open_btl(path_id_t path_id, target_id_t target_id, lun_id_t target_lun,
ccb.cdm.patterns = (struct dev_match_pattern *)malloc( ccb.cdm.patterns = (struct dev_match_pattern *)malloc(
sizeof(struct dev_match_pattern)); sizeof(struct dev_match_pattern));
if (ccb.cdm.patterns == NULL) { if (ccb.cdm.patterns == NULL) {
snprintf(cam_errbuf, CAM_ERRBUF_SIZE, snprintf(cam_errbuf, CAM_ERRBUF_SIZE,
"%s: couldn't malloc pattern buffer", func_name); "%s: couldn't malloc pattern buffer", func_name);
free(ccb.cdm.matches); free(ccb.cdm.matches);
close(fd); close(fd);
return(NULL); return(NULL);
} }
ccb.cdm.patterns[0].type = DEV_MATCH_PERIPH; ccb.cdm.patterns[0].type = DEV_MATCH_PERIPH;
match_pat = &ccb.cdm.patterns[0].pattern.periph_pattern; match_pat = &ccb.cdm.patterns[0].pattern.periph_pattern;
/* /*
* We're looking for the passthrough device associated with this * We're looking for the passthrough device associated with this
@ -421,7 +421,7 @@ cam_lookup_pass(const char *dev_name, int unit, int flags,
* passthrough device. * passthrough device.
*/ */
if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) { if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
snprintf(cam_errbuf, CAM_ERRBUF_SIZE, snprintf(cam_errbuf, CAM_ERRBUF_SIZE,
"%s: couldn't open %s\n%s: %s", func_name, XPT_DEVICE, "%s: couldn't open %s\n%s: %s", func_name, XPT_DEVICE,
func_name, strerror(errno)); func_name, strerror(errno));
return(NULL); return(NULL);
@ -435,7 +435,7 @@ cam_lookup_pass(const char *dev_name, int unit, int flags,
ccb.cgdl.unit_number = unit; ccb.cgdl.unit_number = unit;
/* /*
* Attempt to get the passthrough device. This ioctl will fail if * Attempt to get the passthrough device. This ioctl will fail if
* the device name is null, if the device doesn't exist, or if the * the device name is null, if the device doesn't exist, or if the
* passthrough driver isn't in the kernel. * passthrough driver isn't in the kernel.
*/ */
@ -512,7 +512,7 @@ cam_real_open_device(const char *path, int flags, struct cam_device *device,
} }
device->fd = -1; device->fd = -1;
malloced_device = 1; malloced_device = 1;
} }
/* /*
* If the user passed in a path, save it for him. * If the user passed in a path, save it for him.
@ -551,7 +551,7 @@ cam_real_open_device(const char *path, int flags, struct cam_device *device,
* we don't have to set any fields. * we don't have to set any fields.
*/ */
ccb.ccb_h.func_code = XPT_GDEVLIST; ccb.ccb_h.func_code = XPT_GDEVLIST;
/* /*
* We're only doing this to get some information on the device in * We're only doing this to get some information on the device in
* question. Otherwise, we'd have to pass in yet another * question. Otherwise, we'd have to pass in yet another
@ -611,7 +611,7 @@ cam_real_open_device(const char *path, int flags, struct cam_device *device,
goto crod_bailout; goto crod_bailout;
} }
device->pd_type = SID_TYPE(&ccb.cgd.inq_data); device->pd_type = SID_TYPE(&ccb.cgd.inq_data);
bcopy(&ccb.cgd.inq_data, &device->inq_data, bcopy(&ccb.cgd.inq_data, &device->inq_data,
sizeof(struct scsi_inquiry_data)); sizeof(struct scsi_inquiry_data));
device->serial_num_len = ccb.cgd.serial_num_len; device->serial_num_len = ccb.cgd.serial_num_len;
bcopy(&ccb.cgd.serial_num, &device->serial_num, device->serial_num_len); bcopy(&ccb.cgd.serial_num, &device->serial_num, device->serial_num_len);
@ -719,7 +719,7 @@ cam_device_dup(struct cam_device *device)
newdev = malloc(sizeof(struct cam_device)); newdev = malloc(sizeof(struct cam_device));
if (newdev == NULL) { if (newdev == NULL) {
snprintf(cam_errbuf, CAM_ERRBUF_SIZE, snprintf(cam_errbuf, CAM_ERRBUF_SIZE,
"%s: couldn't malloc CAM device structure", func_name); "%s: couldn't malloc CAM device structure", func_name);
return(NULL); return(NULL);
} }

View File

@ -83,7 +83,7 @@ extern char cam_errbuf[];
struct cam_device { struct cam_device {
char device_path[MAXPATHLEN];/* char device_path[MAXPATHLEN];/*
* Pathname of the device * Pathname of the device
* given by the user. This * given by the user. This
* may be null if the * may be null if the
* user states the device * user states the device
@ -98,15 +98,15 @@ struct cam_device {
* Unit number given by * Unit number given by
* the user. * the user.
*/ */
char device_name[DEV_IDLEN+1];/* char device_name[DEV_IDLEN+1];/*
* Name of the device, * Name of the device,
* e.g. 'pass' * e.g. 'pass'
*/ */
u_int32_t dev_unit_num; /* Unit number of the passthrough u_int32_t dev_unit_num; /* Unit number of the passthrough
* device associated with this * device associated with this
* particular device. * particular device.
*/ */
char sim_name[SIM_IDLEN+1]; /* Controller name, e.g. 'ahc' */ char sim_name[SIM_IDLEN+1]; /* Controller name, e.g. 'ahc' */
u_int32_t sim_unit_number; /* Controller unit number */ u_int32_t sim_unit_number; /* Controller unit number */
u_int32_t bus_id; /* Controller bus number */ u_int32_t bus_id; /* Controller bus number */
@ -142,7 +142,7 @@ int cam_send_ccb(struct cam_device *device, union ccb *ccb);
char * cam_path_string(struct cam_device *dev, char *str, char * cam_path_string(struct cam_device *dev, char *str,
int len); int len);
struct cam_device * cam_device_dup(struct cam_device *device); struct cam_device * cam_device_dup(struct cam_device *device);
void cam_device_copy(struct cam_device *src, void cam_device_copy(struct cam_device *src,
struct cam_device *dst); struct cam_device *dst);
int cam_get_device(const char *path, char *dev_name, int cam_get_device(const char *path, char *dev_name,
int devnamelen, int *unit); int devnamelen, int *unit);

View File

@ -632,6 +632,7 @@ dns_getaddrinfo(const nvlist_t *limits, const nvlist_t *nvlin, nvlist_t *nvlout)
hints.ai_addrlen = 0; hints.ai_addrlen = 0;
hints.ai_addr = NULL; hints.ai_addr = NULL;
hints.ai_canonname = NULL; hints.ai_canonname = NULL;
hints.ai_next = NULL;
hintsp = &hints; hintsp = &hints;
family = hints.ai_family; family = hints.ai_family;
} else { } else {

View File

@ -121,7 +121,7 @@ gss_add_cred(OM_uint32 *minor_status,
* gss_add_cred for that mechanism, otherwise we copy the mc * gss_add_cred for that mechanism, otherwise we copy the mc
* to new_cred. * to new_cred.
*/ */
target_mc = 0; target_mc = NULL;
if (cred) { if (cred) {
SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) { SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
if (gss_oid_equal(mc->gmc_mech_oid, desired_mech)) { if (gss_oid_equal(mc->gmc_mech_oid, desired_mech)) {
@ -151,7 +151,7 @@ gss_add_cred(OM_uint32 *minor_status,
return (major_status); return (major_status);
} }
} else { } else {
mn = 0; mn = NULL;
} }
m = _gss_find_mech_switch(desired_mech); m = _gss_find_mech_switch(desired_mech);

View File

@ -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 * First time around, we calculate the size, second time, we
* encode the token. * encode the token.
*/ */
p = 0; p = NULL;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
len = 0; len = 0;

View File

@ -40,13 +40,14 @@ gss_get_mic(OM_uint32 *minor_status,
gss_buffer_t message_token) gss_buffer_t message_token)
{ {
struct _gss_context *ctx = (struct _gss_context *) context_handle; 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); _gss_buffer_zero(message_token);
if (ctx == NULL) { if (ctx == NULL) {
*minor_status = 0; *minor_status = 0;
return (GSS_S_NO_CONTEXT); return (GSS_S_NO_CONTEXT);
} }
m = ctx->gc_mech;
return (m->gm_get_mic(minor_status, ctx->gc_ctx, qop_req, return (m->gm_get_mic(minor_status, ctx->gc_ctx, qop_req,
message_buffer, message_token)); message_buffer, message_token));

View File

@ -99,7 +99,7 @@ gss_inquire_context(OM_uint32 *minor_status,
if (src_name) if (src_name)
gss_release_name(minor_status, src_name); gss_release_name(minor_status, src_name);
m->gm_release_name(minor_status, &src_mn); m->gm_release_name(minor_status, &src_mn);
minor_status = 0; minor_status = NULL;
return (GSS_S_FAILURE); return (GSS_S_FAILURE);
} }
*targ_name = (gss_name_t) name; *targ_name = (gss_name_t) name;

View File

@ -83,7 +83,7 @@ _gss_string_to_oid(const char* s, gss_OID oid)
* out the size. Second time around, we actually encode the * out the size. Second time around, we actually encode the
* number. * number.
*/ */
res = 0; res = NULL;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
byte_count = 0; byte_count = 0;
for (p = s, j = 0; p; p = q, j++) { for (p = s, j = 0; p; p = q, j++) {

View File

@ -48,7 +48,7 @@ gss_pseudo_random(OM_uint32 *minor_status,
gss_buffer_t prf_out) gss_buffer_t prf_out)
{ {
struct _gss_context *ctx = (struct _gss_context *) context; 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; OM_uint32 major_status;
_gss_buffer_zero(prf_out); _gss_buffer_zero(prf_out);
@ -58,6 +58,7 @@ gss_pseudo_random(OM_uint32 *minor_status,
*minor_status = 0; *minor_status = 0;
return GSS_S_NO_CONTEXT; return GSS_S_NO_CONTEXT;
} }
m = ctx->gc_mech;
if (m->gm_pseudo_random == NULL) if (m->gm_pseudo_random == NULL)
return GSS_S_UNAVAILABLE; return GSS_S_UNAVAILABLE;

View File

@ -39,7 +39,7 @@ gss_verify_mic(OM_uint32 *minor_status,
gss_qop_t *qop_state) gss_qop_t *qop_state)
{ {
struct _gss_context *ctx = (struct _gss_context *) context_handle; 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) if (qop_state)
*qop_state = 0; *qop_state = 0;
@ -47,6 +47,7 @@ gss_verify_mic(OM_uint32 *minor_status,
*minor_status = 0; *minor_status = 0;
return (GSS_S_NO_CONTEXT); return (GSS_S_NO_CONTEXT);
} }
m = ctx->gc_mech;
return (m->gm_verify_mic(minor_status, ctx->gc_ctx, return (m->gm_verify_mic(minor_status, ctx->gc_ctx,
message_buffer, token_buffer, qop_state)); message_buffer, token_buffer, qop_state));

View File

@ -42,7 +42,7 @@ gss_wrap(OM_uint32 *minor_status,
gss_buffer_t output_message_buffer) gss_buffer_t output_message_buffer)
{ {
struct _gss_context *ctx = (struct _gss_context *) context_handle; 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) if (conf_state)
*conf_state = 0; *conf_state = 0;
@ -51,6 +51,7 @@ gss_wrap(OM_uint32 *minor_status,
*minor_status = 0; *minor_status = 0;
return (GSS_S_NO_CONTEXT); return (GSS_S_NO_CONTEXT);
} }
m = ctx->gc_mech;
return (m->gm_wrap(minor_status, ctx->gc_ctx, return (m->gm_wrap(minor_status, ctx->gc_ctx,
conf_req_flag, qop_req, input_message_buffer, conf_req_flag, qop_req, input_message_buffer,

View File

@ -40,13 +40,14 @@ gss_wrap_size_limit(OM_uint32 *minor_status,
OM_uint32 *max_input_size) OM_uint32 *max_input_size)
{ {
struct _gss_context *ctx = (struct _gss_context *) context_handle; 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; *max_input_size = 0;
if (ctx == NULL) { if (ctx == NULL) {
*minor_status = 0; *minor_status = 0;
return (GSS_S_NO_CONTEXT); return (GSS_S_NO_CONTEXT);
} }
m = ctx->gc_mech;
return (m->gm_wrap_size_limit(minor_status, ctx->gc_ctx, return (m->gm_wrap_size_limit(minor_status, ctx->gc_ctx,
conf_req_flag, qop_req, req_output_size, max_input_size)); conf_req_flag, qop_req, req_output_size, max_input_size));

View File

@ -40,7 +40,7 @@ magic.mgc: mkmagic magic
CLEANFILES+= mkmagic CLEANFILES+= mkmagic
build-tools: 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} \ ${CC} ${CFLAGS} -DCOMPILE_ONLY ${LDFLAGS} -o ${.TARGET} ${.ALLSRC} \
${LDADD} ${LDADD}

View File

@ -24,8 +24,11 @@
# #
# $FreeBSD$ # $FreeBSD$
# The modules must be built first, because they are built into the # The modules link in libpam. They build the static modules as well.
# static version of libpam. SUBDIR+= libpam modules
SUBDIR+= modules libpam static_modules SUBDIR_DEPEND_modules= libpam
SUBDIR+= static_libpam
SUBDIR_DEPEND_static_libpam= modules
SUBDIR_PARALLEL=
.include <bsd.subdir.mk> .include <bsd.subdir.mk>

View File

@ -39,7 +39,11 @@ PACKAGE=lib${LIB}
OPENPAM= ${.CURDIR}/../../../contrib/openpam OPENPAM= ${.CURDIR}/../../../contrib/openpam
.PATH: ${OPENPAM}/include ${OPENPAM}/lib/libpam ${OPENPAM}/doc/man .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 MK_PROFILE=no
SRCS= openpam_asprintf.c \ SRCS= openpam_asprintf.c \
@ -99,7 +103,7 @@ SRCS= openpam_asprintf.c \
# Local additions # Local additions
SRCS+= pam_debug_log.c SRCS+= pam_debug_log.c
MAN= openpam.3 \ MAN?= openpam.3 \
openpam_borrow_cred.3 \ openpam_borrow_cred.3 \
openpam_free_data.3 \ openpam_free_data.3 \
openpam_free_envlist.3 \ openpam_free_envlist.3 \
@ -151,10 +155,10 @@ MAN= openpam.3 \
pam_vprompt.3 \ pam_vprompt.3 \
pam.conf.5 pam.conf.5
MLINKS= pam.conf.5 pam.d.5 MLINKS?= pam.conf.5 pam.d.5
CSTD?= c99 CSTD?= c99
CFLAGS+= -I${.CURDIR} -I${OPENPAM}/include CFLAGS+= -I${OPENPAM}/include
CFLAGS+= -DLIB_MAJ=${SHLIB_MAJOR} CFLAGS+= -DLIB_MAJ=${SHLIB_MAJOR}
CFLAGS+= -DHAVE_DLFUNC=1 CFLAGS+= -DHAVE_DLFUNC=1
CFLAGS+= -DHAVE_FDLOPEN=1 CFLAGS+= -DHAVE_FDLOPEN=1
@ -173,7 +177,7 @@ HEADERS= security/openpam.h \
ADD_HEADERS= security/pam_mod_misc.h ADD_HEADERS= security/pam_mod_misc.h
# Headers # Headers
INCS= ${HEADERS} ${ADD_HEADERS} INCS?= ${HEADERS} ${ADD_HEADERS}
INCSDIR= ${INCLUDEDIR}/security INCSDIR= ${INCLUDEDIR}/security
.include <src.opts.mk> .include <src.opts.mk>

View File

@ -27,5 +27,6 @@
.include "modules.inc" .include "modules.inc"
SUBDIR= ${MODULES} SUBDIR= ${MODULES}
SUBDIR_PARALLEL=
.include <bsd.subdir.mk> .include <bsd.subdir.mk>

View File

@ -7,14 +7,7 @@ MK_PROFILE= no
CFLAGS+= -I${PAMDIR}/include -I${.CURDIR}/../../libpam 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} SHLIB_NAME?= ${LIB}.so.${SHLIB_MAJOR}
LIBADD+= pam LIBADD+= pam
.endif
.include "../Makefile.inc" .include "../Makefile.inc"

View File

@ -35,15 +35,17 @@
# #
# $FreeBSD$ # $FreeBSD$
OPENPAM= ${.CURDIR:H:H:H}/contrib/openpam .PATH: ${.CURDIR}/../libpam
.PATH: ${OPENPAM}/lib
.PATH: ${OPENPAM}/lib/libpam
all: # Only build the static library.
LIB= pam
SRCS = openpam_static.c NO_PIC=
# Avoid redundancy with the master Makefile.
MAN= MAN=
INCS=
MLINKS=
MK_TESTS= no
# #
# Static modules # Static modules
@ -61,11 +63,7 @@ STATICOBJS+= openpam_static_modules.o
CLEANFILES+= openpam_static.o \ CLEANFILES+= openpam_static.o \
openpam_static_modules.o openpam_static_modules.o
.include <bsd.prog.mk>
.if empty(_SKIP_BUILD)
openpam_static_modules.o: openpam_static.o ${STATIC_MODULES} openpam_static_modules.o: openpam_static.o ${STATIC_MODULES}
${LD} -o ${.TARGET} -r --whole-archive ${.ALLSRC} ${LD} -o ${.TARGET} -r --whole-archive ${.ALLSRC}
all: ${STATICOBJS} .include "${.CURDIR}/../libpam/Makefile"
.endif

View File

@ -46,7 +46,7 @@
#define CPU_SPINWAIT #define CPU_SPINWAIT
#define DTV_OFFSET offsetof(struct tcb, tcb_dtv) #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 * Variant I tcb. The structure layout is fixed, don't blindly

View File

@ -3,10 +3,10 @@
.Fx .Fx
uses uses
.Nm libxo .Nm libxo
version 0.4.6. version 0.6.1.
Complete documentation can be found on github: Complete documentation can be found on github:
.Bd -literal -offset indent .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 .Ed
.Pp .Pp
.Nm libxo .Nm libxo

View File

@ -88,6 +88,9 @@
/* Define to 1 if you have the <memory.h> header file. */ /* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1 #define HAVE_MEMORY_H 1
/* Define to 1 if you have the <monitor.h> header file. */
/* #undef HAVE_MONITOR_H */
/* Support printflike */ /* Support printflike */
/* #undef HAVE_PRINTFLIKE */ /* #undef HAVE_PRINTFLIKE */
@ -180,16 +183,16 @@
/* #undef LIBXO_TEXT_ONLY */ /* #undef LIBXO_TEXT_ONLY */
/* Version number as dotted value */ /* Version number as dotted value */
#define LIBXO_VERSION "0.4.6" #define LIBXO_VERSION "0.6.1"
/* Version number extra information */ /* Version number extra information */
#define LIBXO_VERSION_EXTRA "" #define LIBXO_VERSION_EXTRA ""
/* Version number as a number */ /* Version number as a number */
#define LIBXO_VERSION_NUMBER 4006 #define LIBXO_VERSION_NUMBER 6001
/* Version number as string */ /* Version number as string */
#define LIBXO_VERSION_STRING "4006" #define LIBXO_VERSION_STRING "6001"
/* Enable local wcwidth implementation */ /* Enable local wcwidth implementation */
#define LIBXO_WCWIDTH 1 #define LIBXO_WCWIDTH 1
@ -207,7 +210,7 @@
#define PACKAGE_NAME "libxo" #define PACKAGE_NAME "libxo"
/* Define to the full name and version of this package. */ /* 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 to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libxo" #define PACKAGE_TARNAME "libxo"
@ -216,7 +219,7 @@
#define PACKAGE_URL "" #define PACKAGE_URL ""
/* Define to the version of this package. */ /* 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 /* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be direction of stack growth for your system; otherwise it will be
@ -230,7 +233,10 @@
#define STDC_HEADERS 1 #define STDC_HEADERS 1
/* Version number of package */ /* 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 /* 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. */ calls it, or to nothing if 'inline' is not supported under any name. */

View File

@ -65,7 +65,7 @@ int
ypclnt_havepasswdd(ypclnt_t *ypclnt) ypclnt_havepasswdd(ypclnt_t *ypclnt)
{ {
struct netconfig *nc = NULL; struct netconfig *nc = NULL;
void *localhandle = 0; void *localhandle = NULL;
CLIENT *clnt = NULL; CLIENT *clnt = NULL;
int ret; int ret;
@ -139,7 +139,7 @@ yppasswd_local(ypclnt_t *ypclnt, const struct passwd *pwd)
struct master_yppasswd yppwd; struct master_yppasswd yppwd;
struct rpc_err rpcerr; struct rpc_err rpcerr;
struct netconfig *nc = NULL; struct netconfig *nc = NULL;
void *localhandle = 0; void *localhandle = NULL;
CLIENT *clnt = NULL; CLIENT *clnt = NULL;
int ret, *result; int ret, *result;

View File

@ -1,5 +1,7 @@
# $FreeBSD$ # $FreeBSD$
.include <bsd.own.mk>
PACKAGE=tests PACKAGE=tests
FILESGROUPS= TESTS FILESGROUPS= TESTS
TESTSPACKAGE= ${PACKAGE} TESTSPACKAGE= ${PACKAGE}
@ -50,7 +52,10 @@ TAP_TESTS_C+= ctrig_test
TAP_TESTS_C+= exponential_test TAP_TESTS_C+= exponential_test
TAP_TESTS_C+= fenv_test TAP_TESTS_C+= fenv_test
TAP_TESTS_C+= fma_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 TAP_TESTS_C+= fmaxmin_test
.endif
TAP_TESTS_C+= ilogb_test TAP_TESTS_C+= ilogb_test
TAP_TESTS_C+= invtrig_test TAP_TESTS_C+= invtrig_test
TAP_TESTS_C+= invctrig_test TAP_TESTS_C+= invctrig_test

View File

@ -390,10 +390,10 @@ keys.list: MKkeys_list.sh Caps
# Build tools # Build tools
build-tools: make_hash make_keys 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 ${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 \ ${CC} -o $@ ${CFLAGS} -DMAIN_PROGRAM \
${NCURSES_DIR}/ncurses/tinfo/make_hash.c ${NCURSES_DIR}/ncurses/tinfo/make_hash.c

View File

@ -200,7 +200,7 @@ bootonly: packagesystem
MK_GAMES=no MK_GROFF=no \ MK_GAMES=no MK_GROFF=no \
MK_INSTALLLIB=no MK_LIB32=no MK_MAIL=no \ MK_INSTALLLIB=no MK_LIB32=no MK_MAIL=no \
MK_NCP=no MK_TOOLCHAIN=no MK_PROFILE=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 MK_KERNEL_SYMBOLS=no MK_TESTS=no MK_DEBUG_FILES=no
# Copy manifest only (no distfiles) to get checksums # Copy manifest only (no distfiles) to get checksums
mkdir -p ${.TARGET}/usr/freebsd-dist mkdir -p ${.TARGET}/usr/freebsd-dist

View File

@ -41,7 +41,7 @@
.\" ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS .\" ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
.\" SOFTWARE. .\" SOFTWARE.
.\" .\"
.Dd March 28, 2016 .Dd April 14, 2016
.Dt DEVD.CONF 5 .Dt DEVD.CONF 5
.Os .Os
.Sh NAME .Sh NAME
@ -501,6 +501,23 @@ Information about the state of the system.
Notification that the system has woken from the suspended state. Notification that the system has woken from the suspended state.
.El .El
.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 .El
.Pp .Pp
A link state change to UP on the interface A link state change to UP on the interface
@ -630,4 +647,5 @@ has many additional examples.
.Xr coretemp 4 , .Xr coretemp 4 ,
.Xr devfs 5 , .Xr devfs 5 ,
.Xr re_format 7 , .Xr re_format 7 ,
.Xr devd 8 .Xr devd 8 ,
.Xr cam 4

View File

@ -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) dumpme = tnow > (dtwalk->dd_ddate - (tlast->tm_hour * 3600)
- (tlast->tm_min * 60) - tlast->tm_sec - (tlast->tm_min * 60) - tlast->tm_sec
+ (dt->fs_freq * 86400)); + (dt->fs_freq * 86400));
}; }
if (arg != 'w' || dumpme) if (arg != 'w' || dumpme)
(void) printf( (void) printf(
"%c %8s\t(%6s) Last dump: Level %d, Date %s\n", "%c %8s\t(%6s) Last dump: Level %d, Date %s\n",

View File

@ -118,7 +118,7 @@ fsckinit(void)
bzero(totalreadcnt, sizeof(long) * BT_NUMBUFTYPES); bzero(totalreadcnt, sizeof(long) * BT_NUMBUFTYPES);
bzero(readtime, sizeof(struct timespec) * BT_NUMBUFTYPES); bzero(readtime, sizeof(struct timespec) * BT_NUMBUFTYPES);
bzero(totalreadtime, 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)); bzero(&sblk, sizeof(struct bufarea));
pdirbp = NULL; pdirbp = NULL;
pbp = NULL; pbp = NULL;

View File

@ -911,6 +911,6 @@ sfp_status(int s, struct ifreq *ifr, int verbose)
break; break;
default: default:
print_sfp_status(&ii, verbose); print_sfp_status(&ii, verbose);
}; }
} }

View File

@ -234,6 +234,9 @@ static struct _s_x ether_types[] = {
{ NULL, 0 } { NULL, 0 }
}; };
static struct _s_x rule_eactions[] = {
{ NULL, 0 } /* terminator */
};
static struct _s_x rule_actions[] = { static struct _s_x rule_actions[] = {
{ "accept", TOK_ACCEPT }, { "accept", TOK_ACCEPT },
@ -265,6 +268,7 @@ static struct _s_x rule_actions[] = {
{ "setdscp", TOK_SETDSCP }, { "setdscp", TOK_SETDSCP },
{ "call", TOK_CALL }, { "call", TOK_CALL },
{ "return", TOK_RETURN }, { "return", TOK_RETURN },
{ "eaction", TOK_EACTION },
{ NULL, 0 } /* terminator */ { 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 char *table_search_ctlv(ipfw_obj_ctlv *ctlv, uint16_t idx);
static void object_sort_ctlv(ipfw_obj_ctlv *ctlv); 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. * 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). * with the string (-1 in case of failure).
*/ */
int int
match_token(struct _s_x *table, char *string) match_token(struct _s_x *table, const char *string)
{ {
struct _s_x *pt; struct _s_x *pt;
uint i = strlen(string); 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. * with the string for the best match.
* *
* Returns: * Returns:
@ -655,7 +661,7 @@ match_token(struct _s_x *table, char *string)
* -2 if more than one records match @string. * -2 if more than one records match @string.
*/ */
int 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; struct _s_x *pt, *m;
int i, c; int i, c;
@ -676,6 +682,18 @@ match_token_relaxed(struct _s_x *table, char *string)
return (c > 0 ? -2: -1); 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 * match_value takes a table and a value, returns the string associated
* with the value (NULL in case of failure). * 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; static int twidth = 0;
int l; 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 */ const char *comment = NULL; /* ptr to comment if we have one */
int proto = 0; /* default */ int proto = 0; /* default */
int flags = 0; /* prerequisites */ 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) if (cmd->arg1 == ICMP6_UNREACH_RST)
bprintf(bp, "reset6"); bprintf(bp, "reset6");
else else
print_unreach6_code(cmd->arg1); print_unreach6_code(bp, cmd->arg1);
break; break;
case O_SKIPTO: 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); bprint_uint_arg(bp, "setfib ", cmd->arg1 & 0x7FFF);
break; 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: case O_SETDSCP:
{ {
const char *code; const char *code;
@ -2730,6 +2794,42 @@ struct tidx {
uint8_t set; 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 static uint16_t
pack_object(struct tidx *tstate, char *name, int otype) 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; break;
default: 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); 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, ntlv = bsearch(&key, (ctlv + 1), ctlv->count, ctlv->objsize,
compare_object_kntlv); compare_object_kntlv);
if (ntlv != 0) if (ntlv != NULL)
return (ntlv->name); return (ntlv->name);
return (NULL); return (NULL);
@ -5019,7 +5158,7 @@ ipfw_list_objects(int ac, char *av[])
printf("There are no objects\n"); printf("There are no objects\n");
ntlv = (ipfw_obj_ntlv *)(olh + 1); ntlv = (ipfw_obj_ntlv *)(olh + 1);
for (i = 0; i < olh->count; i++) { 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->head.type, ntlv->name);
ntlv++; ntlv++;
} }

View File

@ -83,6 +83,7 @@ enum tokens {
TOK_ACCEPT, TOK_ACCEPT,
TOK_COUNT, TOK_COUNT,
TOK_EACTION,
TOK_PIPE, TOK_PIPE,
TOK_LINK, TOK_LINK,
TOK_QUEUE, 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); int stringnum_cmp(const char *a, const char *b);
/* utility functions */ /* utility functions */
int match_token(struct _s_x *table, char *string); int match_token(struct _s_x *table, const char *string);
int match_token_relaxed(struct _s_x *table, 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); char const *match_value(struct _s_x *p, int value);
size_t concat_tokens(char *buf, size_t bufsize, struct _s_x *table, size_t concat_tokens(char *buf, size_t bufsize, struct _s_x *table,
char *delimiter); char *delimiter);
@ -313,6 +315,7 @@ void ipfw_flush(int force);
void ipfw_zero(int ac, char *av[], int optname); void ipfw_zero(int ac, char *av[], int optname);
void ipfw_list(int ac, char *av[], int show_counters); void ipfw_list(int ac, char *av[], int show_counters);
void ipfw_internal_handler(int ac, char *av[]); void ipfw_internal_handler(int ac, char *av[]);
int ipfw_check_object_name(const char *name);
#ifdef PF #ifdef PF
/* altq.c */ /* altq.c */
@ -329,7 +332,7 @@ void dummynet_flush(void);
int ipfw_delete_pipe(int pipe_or_queue, int n); int ipfw_delete_pipe(int pipe_or_queue, int n);
/* ipv6.c */ /* 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_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_flow6id(struct buf_pr *bp, struct _ipfw_insn_u32 *cmd);
void print_icmp6types(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 */ /* tables.c */
struct _ipfw_obj_ctlv; 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_ta(int ac, char *av[]);
void ipfw_list_values(int ac, char *av[]); void ipfw_list_values(int ac, char *av[]);

View File

@ -71,14 +71,14 @@ fill_unreach6_code(u_short *codep, char *str)
} }
void void
print_unreach6_code(uint16_t code) print_unreach6_code(struct buf_pr *bp, uint16_t code)
{ {
char const *s = match_value(icmp6codes, code); char const *s = match_value(icmp6codes, code);
if (s != NULL) if (s != NULL)
printf("unreach6 %s", s); bprintf(bp, "unreach6 %s", s);
else else
printf("unreach6 %u", code); bprintf(bp, "unreach6 %u", code);
} }
/* /*

View File

@ -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_swap(ipfw_obj_header *oh, char *second);
static int table_get_info(ipfw_obj_header *oh, ipfw_xtable_info *i); 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 int table_show_info(ipfw_xtable_info *i, void *arg);
static void table_fill_ntlv(ipfw_obj_ntlv *ntlv, char *name, uint32_t set, static void table_fill_ntlv(ipfw_obj_ntlv *ntlv, const char *name,
uint16_t uidx); uint32_t set, uint16_t uidx);
static int table_flush_one(ipfw_xtable_info *i, void *arg); static int table_flush_one(ipfw_xtable_info *i, void *arg);
static int table_show_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); 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 * This one handles all table-related commands
* ipfw table NAME create ... * ipfw table NAME create ...
@ -293,7 +281,8 @@ ipfw_table_handler(int ac, char *av[])
} }
static void 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; ntlv->head.type = IPFW_TLV_TBL_NAME;
@ -1994,30 +1983,14 @@ ipfw_list_values(int ac, char *av[])
} }
int int
table_check_name(char *tablename) table_check_name(const char *tablename)
{ {
int c, i, l;
/* if (ipfw_check_object_name(tablename) != 0)
* 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)
return (EINVAL); 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 */ /* Restrict some 'special' names */
if (strcmp(tablename, "all") == 0) if (strcmp(tablename, "all") == 0)
return (EINVAL); return (EINVAL);
return (0); return (0);
} }

View File

@ -1027,7 +1027,7 @@ xdr_fh(XDR *xdrsp, struct nfhret *np)
if (!authfnd && (authcnt > 0 || np->auth != AUTH_SYS)) if (!authfnd && (authcnt > 0 || np->auth != AUTH_SYS))
np->stat = EAUTH; np->stat = EAUTH;
return (1); return (1);
}; }
return (0); return (0);
} }

View File

@ -1605,13 +1605,22 @@ bandwidth : STRING {
bps = strtod($1, &cp); bps = strtod($1, &cp);
if (cp != NULL) { 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")) if (!strcmp(cp, "b"))
; /* nothing */ ; /* nothing */
else if (!strcmp(cp, "Kb")) else if (!strcmp(cp, "K"))
bps *= 1000; bps *= 1000;
else if (!strcmp(cp, "Mb")) else if (!strcmp(cp, "M"))
bps *= 1000 * 1000; bps *= 1000 * 1000;
else if (!strcmp(cp, "Gb")) else if (!strcmp(cp, "G"))
bps *= 1000 * 1000 * 1000; bps *= 1000 * 1000 * 1000;
else if (!strcmp(cp, "%")) { else if (!strcmp(cp, "%")) {
if (bps < 0 || bps > 100) { if (bps < 0 || bps > 100) {

View File

@ -32,9 +32,8 @@
.Nd "specify an alternate kernel and boot flags for the next reboot" .Nd "specify an alternate kernel and boot flags for the next reboot"
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm .Nm
.Op Fl a .Op Fl af
.Op Fl e Ar variable=value .Op Fl e Ar variable=value
.Op Fl f
.Op Fl k Ar kernel .Op Fl k Ar kernel
.Op Fl o Ar options .Op Fl o Ar options
.Nm .Nm

Some files were not shown because too many files have changed in this diff Show More