diff options
Diffstat (limited to 'lib')
645 files changed, 38848 insertions, 23234 deletions
diff --git a/lib/Makefile b/lib/Makefile index 7e52d6e32e..37e8ce06d7 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -48,7 +48,7 @@ else diameter \ cosTransactions cosEvent cosTime cosNotification cosProperty \ cosFileTransfer cosEventDomain et megaco webtool \ - xmerl edoc eunit ssh inviso typer docbuilder erl_docgen \ + xmerl edoc eunit ssh inviso typer erl_docgen \ common_test percept dialyzer # dialyzer OTHER_SUB_DIRECTORIES += hipe @@ -60,7 +60,7 @@ else diameter \ cosTransactions cosEvent cosTime cosNotification \ cosProperty cosFileTransfer cosEventDomain et megaco webtool \ - xmerl edoc eunit ssh inviso typer docbuilder erl_docgen \ + xmerl edoc eunit ssh inviso typer erl_docgen \ common_test percept dialyzer # dialyzer OTHER_SUB_DIRECTORIES += hipe $(TSP_APP) diff --git a/lib/asn1/src/asn1ct_constructed_ber.erl b/lib/asn1/src/asn1ct_constructed_ber.erl index 77b78dcac7..edeefe1f43 100644 --- a/lib/asn1/src/asn1ct_constructed_ber.erl +++ b/lib/asn1/src/asn1ct_constructed_ber.erl @@ -1542,7 +1542,7 @@ mkfunname(Erule,TopType,Cname,WhatKind,DecOrEnc,Arity) -> F = lists:concat(["fun '",DecOrEnc,"_",EType,"'/",Arity]), {F, "?MODULE", F}; #'Externaltypereference'{module=Mod,type=EType} -> - {lists:concat(["{'",Mod,"','",DecOrEnc,"_",EType,"'}"]),Mod, + {lists:concat(["fun '",Mod,"':'",DecOrEnc,"_",EType,"'/",Arity]),Mod, lists:concat(["'",DecOrEnc,"_",EType,"'"])}; {constructed,bif} -> F = diff --git a/lib/common_test/doc/src/ct_hooks.xml b/lib/common_test/doc/src/ct_hooks.xml index f9fc1858d0..b98c04a850 100644 --- a/lib/common_test/doc/src/ct_hooks.xml +++ b/lib/common_test/doc/src/ct_hooks.xml @@ -37,12 +37,6 @@ <description> - <warning><p>This feature is in alpha release right now. This means that the - interface may change in the future and that there may be bugs. We - encourage you to use this feature, but be prepared - that there might be bugs and that the interface might change - inbetween releases.</p></warning> - <p>The <em>Common Test Hook</em> (henceforth called CTH) framework allows extensions of the default behaviour of Common Test by means of callbacks before and after all test suite calls. It is meant for advanced users of diff --git a/lib/common_test/doc/src/ct_hooks_chapter.xml b/lib/common_test/doc/src/ct_hooks_chapter.xml index 3b9620d0f2..8505ee8469 100644 --- a/lib/common_test/doc/src/ct_hooks_chapter.xml +++ b/lib/common_test/doc/src/ct_hooks_chapter.xml @@ -32,11 +32,6 @@ <marker id="general"></marker> <section> <title>General</title> - <warning><p>This feature is in alpha release right now. This means that the - interface may change in the future and that there may be bugs. We - encourage you to use this feature, but be prepared - that there might be bugs and that the interface might change - inbetween releases.</p></warning> <p> The <em>Common Test Hook</em> (henceforth called CTH) framework allows extensions of the default behaviour of Common Test by means of hooks @@ -113,9 +108,10 @@ </section> <section> - <title>CTH Priority</title> + <title>CTH Execution order</title> <p>By default each CTH installed will be executed in the order which - they are installed. This is not always wanted so common_test allows + they are installed for init calls, and then reversed for end calls. + This is not always wanted so common_test allows the user to specify a priority for each hook. The priority can either be specified in the CTH <seealso marker="ct_hooks#Module:init-2">init/2 </seealso> function or when installing the hook. The priority given at diff --git a/lib/common_test/priv/Makefile.in b/lib/common_test/priv/Makefile.in index f4a0c181f9..d9033f6ef1 100644 --- a/lib/common_test/priv/Makefile.in +++ b/lib/common_test/priv/Makefile.in @@ -59,6 +59,7 @@ ifneq ($(findstring win32,$(TARGET)),win32) FILES = vts.tool SCRIPTS = IMAGES = tile1.jpg +CSS = ct_default.css # # Rules @@ -85,11 +86,11 @@ include $(ERL_TOP)/make/otp_release_targets.mk ifeq ($(XNIX),true) release_spec: opt $(INSTALL_DIR) $(RELSYSDIR)/priv - $(INSTALL_DATA) $(FILES) $(IMAGES) $(RELSYSDIR)/priv + $(INSTALL_DATA) $(FILES) $(IMAGES) $(CSS) $(RELSYSDIR)/priv else release_spec: opt $(INSTALL_DIR) $(RELSYSDIR)/priv - $(INSTALL_DATA) $(FILES) $(IMAGES) $(RELSYSDIR)/priv + $(INSTALL_DATA) $(FILES) $(IMAGES) $(CSS) $(RELSYSDIR)/priv endif release_docs_spec: @@ -105,6 +106,7 @@ else # FILES = vts.tool IMAGES = tile1.jpg +CSS = ct_default.css # # Rules @@ -124,7 +126,7 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt $(INSTALL_DIR) $(RELSYSDIR)/priv - $(INSTALL_DATA) $(FILES) $(IMAGES) $(RELSYSDIR)/priv + $(INSTALL_DATA) $(FILES) $(IMAGES) $(CSS) $(RELSYSDIR)/priv release_docs_spec: diff --git a/lib/common_test/priv/auxdir/config.guess b/lib/common_test/priv/auxdir/config.guess index fefabd7dd0..38a833903b 120000..100755 --- a/lib/common_test/priv/auxdir/config.guess +++ b/lib/common_test/priv/auxdir/config.guess @@ -1 +1,1519 @@ -../../../../erts/autoconf/config.guess
\ No newline at end of file +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, +# Inc. + +timestamp='2007-05-17' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner <[email protected]>. +# Please send patches to <[email protected]>. Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <[email protected]>." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# ([email protected] 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # [email protected] (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:SunOS:5.*:* | ix86xen:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include <stdio.h> /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <sys/systemcfg.h> + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include <stdlib.h> + #include <unistd.h> + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <unistd.h> + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:[3456]*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + EM64T | authenticamd) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + tile:Linux:*:*) + echo tile-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + xtensa:Linux:*:*) + echo xtensa-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <features.h> + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^LIBC/{ + s: ::g + p + }'`" + test x"${LIBC}" != x && { + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit + } + test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` + echo ${UNAME_MACHINE}-pc-isc$UNAME_REL + elif /bin/uname -X 2>/dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says <[email protected]> + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes <[email protected]>. + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From [email protected]. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From [email protected]. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From [email protected]. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c <<EOF +#ifdef _SEQUENT_ +# include <sys/types.h> +# include <sys/utsname.h> +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include <sys/param.h> + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include <sys/param.h> +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 <<EOF +$0: unable to guess system type + +This script, last modified $timestamp, has failed to recognize +the operating system you are using. It is advised that you +download the most up to date version of the config scripts from + + http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess +and + http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub + +If the version you run ($0) is already up to date, please +send the following data and any information you think might be +pertinent to <[email protected]> in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/lib/common_test/priv/auxdir/config.sub b/lib/common_test/priv/auxdir/config.sub index 90979e8924..f43233b104 120000..100755 --- a/lib/common_test/priv/auxdir/config.sub +++ b/lib/common_test/priv/auxdir/config.sub @@ -1 +1,1630 @@ -../../../../erts/autoconf/config.sub
\ No newline at end of file +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, +# Inc. + +timestamp='2007-04-29' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to <[email protected]>. Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <[email protected]>." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | mt \ + | msp430 \ + | nios | nios2 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | score \ + | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16c) + basic_machine=cr16c-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + tile*) + basic_machine=tile-tilera + os=-linux-gnu + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/lib/common_test/priv/auxdir/install-sh b/lib/common_test/priv/auxdir/install-sh index 9422c370df..a5897de6ea 120000..100755 --- a/lib/common_test/priv/auxdir/install-sh +++ b/lib/common_test/priv/auxdir/install-sh @@ -1 +1,519 @@ -../../../../erts/autoconf/install-sh
\ No newline at end of file +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2006-12-25.00 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + trap '(exit $?); exit' 1 2 13 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dst_arg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + -*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test -z "$d" && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/lib/common_test/priv/ct_default.css b/lib/common_test/priv/ct_default.css new file mode 100644 index 0000000000..75f8d5db8a --- /dev/null +++ b/lib/common_test/priv/ct_default.css @@ -0,0 +1,186 @@ +/* Stylesheet for Common Test */ + +body { + padding: 10px; margin: 10px; + -webkit-font-smoothing: antialiased; + background-color: #FBFFFC; +} + +a:link { + color: #2B507D; +} + +a:visited { + color: #85ABD5 +} + +h1 { + font-family: verdana, arial, sans-serif; font-size: 200%; + letter-spacing: -2px; word-spacing: 2px; font-weight: bold; + color: #3F3F3F; +} + +h2 { + font-family: verdana, arial, sans-serif; font-size: 175%; + letter-spacing: -2px; word-spacing: 2px; font-weight: normal; + color: #3F3F3F; +} + +h3 { + font-family: verdana, arial, sans-serif; font-size: 140%; + letter-spacing: -2px; word-spacing: 2px; font-weight: bold; + color: #3F3F3F; +} + +h4 { + font-family: verdana, arial, sans-serif; font-size: 120%; + letter-spacing: -2px; word-spacing: 2px; font-weight: normal; + color: #3F3F3F; +} + +p { + font-family: "Trebuchet MS", "Lucida Sans Unicode", verdana, arial, sans-serif; + font-size: .9em; color: #000000; +} + +ul { + list-style-type: none; + padding: 0em; + margin: 1em; +} +li { + font-size: 0.95em; color: #000000; + margin: .3em 0; +} + +pre { + color: black; + font-family: "Monaco", "Andale Mono", "Consolas", monospace; + font-size: .8em; + } + +code { + color: black; + font-family: "Monaco", "Andale Mono", "Consolas", monospace; + font-size: .8em; +} + +div.mono_sm { + font-family: "Courier New", monospace; font-size: .75em; + word-spacing: 1px; color: #000000; +} + +div.mono_la { + font-family: "Courier New", monospace; font-size: .8em; + color: #000000; +} + +div.copyright { + padding: 20px 0px 0px 0px; + font-family: "Courier New", monospace; font-size: .7em; + color: #000000; +} + +div.ct_internal { + background: lightgrey; color: black; + font-family: "Monaco", "Andale Mono", "Consolas", monospace; + font-size: .95em; + margin: .2em 0 0 0; +} + +div.default { + background: lightgreen; color: black; + font-family: "Monaco", "Andale Mono", "Consolas", monospace; + font-size: 1.05em; + margin: .2em 0 0 0; +} + +div.label { + font-family: verdana, arial, sans-serif; font-size: 200%; + letter-spacing: -2.5px; word-spacing: 2px; + font-weight: bold; color: #2B507D; +} + +table { + border-collapse: collapse; border: 6px solid #3F3F3F; + background: #FFFFFF; + font: .8em/1.2em "Lucida Sans Unicode", verdana, arial, sans-serif; + color: #222; +} + +caption { + font-size: 1.3em; font-weight: bold; + text-align: center; padding: 1em 4px; +} + +td, th { + padding: .5em 7px .5em 7px; line-height: 1.3em; + border-bottom: 3px solid #F5C4C1; + border-left: 2px dashed #809FFF; +} + +th { + background: #3F3F3F; color: #fff; + font-family: arial, sans-serif; font-size: 120%; + letter-spacing: -0.5px; + font-weight: bold; text-align: center; + padding-right: .5em; vertical-align: top; +} + +thead th { + background: #2C5755; text-align: center; +} + +.odd td { + background: #F3F3F3; +} +.odd th { + background: #F3F3F3; +} + +td a, td a:link { + color: #2B507D; +} + +td a:visited { + color: #85ABD5; +} + +tr:hover th[scope=row], tr:hover td { + background-color: #D1D1D1; + color: #fff; +} + +td a:hover, td a:focus { + color: #85ABD5; +} + +th a, td a:active { + color: #85ABD5; +} + +tfoot th, tfoot td { + background: #3F3F3F; color: #fff; +} + +th + td { + padding-left: .5em; +} + +#button_holder { + display: block; float: center; + font-family: arial, verdana, sans-serif; + font-size: 12px; text-shadow: 1px 1px lightgray; +} + +.btn a { + padding: 6px 12px; float: center; + text-decoration: none; color: #3F3F3F; + font-weight: bold; border: 3px outset #3F3F3F; + background-color: #F3F3F3; +} + +.btn a:hover { + color: #fff; + background-color: #809FFF; +} diff --git a/lib/common_test/src/ct.erl b/lib/common_test/src/ct.erl index 69e15fa246..d72b8bc0e1 100644 --- a/lib/common_test/src/ct.erl +++ b/lib/common_test/src/ct.erl @@ -63,7 +63,7 @@ log/1, log/2, log/3, print/1, print/2, print/3, pal/1, pal/2, pal/3, - fail/1, comment/1, + fail/1, fail/2, comment/1, comment/2, testcases/2, userdata/2, userdata/3, timetrap/1, sleep/1]). @@ -108,7 +108,7 @@ install(Opts) -> %%% Cases = atom() | [atom()] %%% Result = [TestResult] | {error,Reason} %%% -%%% @doc Run the given testcase(s). +%%% @doc Run the given test case(s). %%% %%% <p>Requires that <code>ct:install/1</code> has been run first.</p> %%% @@ -121,7 +121,7 @@ run(TestDir,Suite,Cases) -> %%%----------------------------------------------------------------- %%% @spec run(TestDir,Suite) -> Result %%% -%%% @doc Run all testcases in the given suite. +%%% @doc Run all test cases in the given suite. %%% @see run/3. run(TestDir,Suite) -> ct_run:run(TestDir,Suite). @@ -130,7 +130,7 @@ run(TestDir,Suite) -> %%% @spec run(TestDirs) -> Result %%% TestDirs = TestDir | [TestDir] %%% -%%% @doc Run all testcases in all suites in the given directories. +%%% @doc Run all test cases in all suites in the given directories. %%% @see run/3. run(TestDirs) -> ct_run:run(TestDirs). @@ -440,11 +440,10 @@ log(X1,X2) -> %%% Format = string() %%% Args = list() %%% -%%% @doc Printout from a testcase to the log. +%%% @doc Printout from a test case to the log file. %%% -%%% <p>This function is meant for printing stuff directly from a -%%% testcase (i.e. not from within the CT framework) in the test -%%% log.</p> +%%% <p>This function is meant for printing a string directly from a +%%% test case to the test case log file.</p> %%% %%% <p>Default <code>Category</code> is <code>default</code> and %%% default <code>Args</code> is <code>[]</code>.</p> @@ -473,10 +472,10 @@ print(X1,X2) -> %%% Format = string() %%% Args = list() %%% -%%% @doc Printout from a testcase to the console. +%%% @doc Printout from a test case to the console. %%% -%%% <p>This function is meant for printing stuff from a testcase on -%%% the console.</p> +%%% <p>This function is meant for printing a string from a test case +%%% to the console.</p> %%% %%% <p>Default <code>Category</code> is <code>default</code> and %%% default <code>Args</code> is <code>[]</code>.</p> @@ -508,10 +507,10 @@ pal(X1,X2) -> %%% Format = string() %%% Args = list() %%% -%%% @doc Print and log from a testcase. +%%% @doc Print and log from a test case. %%% -%%% <p>This function is meant for printing stuff from a testcase both -%%% in the log and on the console.</p> +%%% <p>This function is meant for printing a string from a test case, +%%% both to the test case log file and to the console.</p> %%% %%% <p>Default <code>Category</code> is <code>default</code> and %%% default <code>Args</code> is <code>[]</code>.</p> @@ -528,18 +527,35 @@ pal(Category,Format,Args) -> fail(Reason) -> exit({test_case_failed,Reason}). + +%%%----------------------------------------------------------------- +%%% @spec fail(Format, Args) -> void() +%%% Format = string() +%%% Args = list() +%%% +%%% @doc Terminate a test case with an error message specified +%%% by a format string and a list of values (used as arguments to +%%% <code>io_lib:format/2</code>). +fail(Format, Args) -> + try io_lib:format(Format, Args) of + Str -> + exit({test_case_failed,lists:flatten(Str)}) + catch + _:BadArgs -> + exit({BadArgs,{?MODULE,fail,[Format,Args]}}) + end. + + %%%----------------------------------------------------------------- %%% @spec comment(Comment) -> void() %%% Comment = term() %%% -%%% @doc Print the given <code>Comment</code> in the comment field of +%%% @doc Print the given <code>Comment</code> in the comment field in %%% the table on the test suite result page. %%% %%% <p>If called several times, only the last comment is printed. -%%% <code>comment/1</code> is also overwritten by the return value -%%% <code>{comment,Comment}</code> or by the function -%%% <code>fail/1</code> (which prints <code>Reason</code> as a -%%% comment).</p> +%%% The test case return value <code>{comment,Comment}</code> +%%% overwrites the string set by this function.</p> comment(Comment) when is_list(Comment) -> Formatted = case (catch io_lib:format("~s",[Comment])) of @@ -553,6 +569,29 @@ comment(Comment) -> Formatted = io_lib:format("~p",[Comment]), send_html_comment(lists:flatten(Formatted)). +%%%----------------------------------------------------------------- +%%% @spec comment(Format, Args) -> void() +%%% Format = string() +%%% Args = list() +%%% +%%% @doc Print the formatted string in the comment field in +%%% the table on the test suite result page. +%%% +%%% <p>The <code>Format</code> and <code>Args</code> arguments are +%%% used in call to <code>io_lib:format/2</code> in order to create +%%% the comment string. The behaviour of <code>comment/2</code> is +%%% otherwise the same as the <code>comment/1</code> function (see +%%% above for details).</p> +comment(Format, Args) when is_list(Format), is_list(Args) -> + Formatted = + case (catch io_lib:format(Format, Args)) of + {'EXIT',Reason} -> % bad args + exit({Reason,{?MODULE,comment,[Format,Args]}}); + String -> + lists:flatten(String) + end, + send_html_comment(Formatted). + send_html_comment(Comment) -> Html = "<font color=\"green\">" ++ Comment ++ "</font>", ct_util:set_testdata({comment,Html}), @@ -606,7 +645,7 @@ listenv(Telnet) -> %%% Testcases = list() %%% Reason = term() %%% -%%% @doc Returns all testcases in the specified suite. +%%% @doc Returns all test cases in the specified suite. testcases(TestDir, Suite) -> case make_and_load(TestDir, Suite) of E = {error,_} -> diff --git a/lib/common_test/src/ct_framework.erl b/lib/common_test/src/ct_framework.erl index 482c5242ce..ee0162c5e3 100644 --- a/lib/common_test/src/ct_framework.erl +++ b/lib/common_test/src/ct_framework.erl @@ -27,7 +27,7 @@ -export([init_tc/3, end_tc/3, end_tc/4, get_suite/2, get_all_cases/1]). -export([report/2, warn/1, error_notification/4]). --export([get_logopts/0, format_comment/1, overview_html_header/1]). +-export([get_logopts/0, format_comment/1, get_html_wrapper/3]). -export([error_in_suite/1, ct_init_per_group/2, ct_end_per_group/2]). @@ -1274,6 +1274,10 @@ report(What,Data) -> tests_done -> ok; tc_start -> + %% Data = {{Suite,Func},LogFileName} + ct_event:sync_notify(#event{name=tc_logfile, + node=node(), + data=Data}), ok; tc_done -> {_Suite,Case,Result} = Data, @@ -1411,30 +1415,6 @@ format_comment(Comment) -> "<font color=\"green\">" ++ Comment ++ "</font>". %%%----------------------------------------------------------------- -%%% @spec overview_html_header(TestName) -> Header -overview_html_header(TestName) -> - TestName1 = lists:flatten(io_lib:format("~p", [TestName])), - Label = case application:get_env(common_test, test_label) of - {ok,Lbl} when Lbl =/= undefined -> - "<H1><FONT color=\"green\">" ++ Lbl ++ "</FONT></H1>\n"; - _ -> - "" - end, - Bgr = case ct_logs:basic_html() of - true -> - ""; - false -> - CTPath = code:lib_dir(common_test), - TileFile = filename:join(filename:join(CTPath,"priv"),"tile1.jpg"), - " background=\"" ++ TileFile ++ "\"" - end, - - ["<html>\n", - "<head><title>Test ", TestName1, " results</title>\n", - "<meta http-equiv=\"cache-control\" content=\"no-cache\">\n", - "</head>\n", - "<body", Bgr, " bgcolor=\"white\" text=\"black\" ", - "link=\"blue\" vlink=\"purple\" alink=\"red\">\n", - Label, - "<H2>Results from test ", TestName1, "</H2>\n"]. - +%%% @spec get_html_wrapper(TestName, PrintLabel, Cwd) -> Header +get_html_wrapper(TestName, PrintLabel, Cwd) -> + ct_logs:get_ts_html_wrapper(TestName, PrintLabel, Cwd). diff --git a/lib/common_test/src/ct_hooks.erl b/lib/common_test/src/ct_hooks.erl index ffafc582cf..c42adbbdd9 100644 --- a/lib/common_test/src/ct_hooks.erl +++ b/lib/common_test/src/ct_hooks.erl @@ -178,8 +178,9 @@ call_generic(#ct_hook_config{ module = Mod, state = State} = Hook, call(Fun, Config, Meta) -> maybe_lock(), Hooks = get_hooks(), - Res = call(get_new_hooks(Config, Fun) ++ - [{HookId,Fun} || #ct_hook_config{id = HookId} <- Hooks], + Calls = get_new_hooks(Config, Fun) ++ + [{HookId,Fun} || #ct_hook_config{id = HookId} <- Hooks], + Res = call(resort(Calls,Hooks,Meta), remove(?config_name,Config), Meta, Hooks), maybe_unlock(), Res. @@ -205,7 +206,7 @@ call([{Hook, call_id, NextFun} | Rest], Config, Meta, Hooks) -> {Hooks ++ [NewHook], [{NewId, call_init}, {NewId,NextFun} | Rest]} end, - call(resort(NewRest,NewHooks), Config, Meta, NewHooks) + call(resort(NewRest,NewHooks,Meta), Config, Meta, NewHooks) catch Error:Reason -> Trace = erlang:get_stacktrace(), ct_logs:log("Suite Hook","Failed to start a CTH: ~p:~p", @@ -221,7 +222,7 @@ call([{HookId, Fun} | Rest], Config, Meta, Hooks) -> {NewConf, NewHook} = Fun(Hook, Config, Meta), NewCalls = get_new_hooks(NewConf, Fun), NewHooks = lists:keyreplace(HookId, #ct_hook_config.id, Hooks, NewHook), - call(resort(NewCalls ++ Rest,NewHooks), %% Resort if call_init changed prio + call(resort(NewCalls ++ Rest,NewHooks,Meta), %% Resort if call_init changed prio remove(?config_name, NewConf), Meta, terminate_if_scope_ends(HookId, Meta, NewHooks)) catch throw:{error_in_cth_call,Reason} -> @@ -308,6 +309,18 @@ get_hooks() -> %% call_id < call_init < ctfirst < Priority 1 < .. < Priority N < ctlast %% If Hook Priority is equal, check when it has been installed and %% sort on that instead. +%% If we are doing a cleanup call i.e. {post,pre}_end_per_*, all priorities +%% are reversed. Probably want to make this sorting algorithm pluginable +%% as some point... +resort(Calls,Hooks,[F|_R]) when F == post_end_per_testcase; + F == pre_end_per_group; + F == post_end_per_group; + F == pre_end_per_suite; + F == post_end_per_suite -> + lists:reverse(resort(Calls,Hooks)); +resort(Calls,Hooks,_Meta) -> + resort(Calls,Hooks). + resort(Calls, Hooks) -> lists:sort( fun({_,_,_},_) -> diff --git a/lib/common_test/src/ct_logs.erl b/lib/common_test/src/ct_logs.erl index c1523509a5..19ad7b26d8 100644 --- a/lib/common_test/src/ct_logs.erl +++ b/lib/common_test/src/ct_logs.erl @@ -29,11 +29,13 @@ -module(ct_logs). -export([init/1,close/2,init_tc/1,end_tc/1]). --export([get_log_dir/0,log/3,start_log/1,cont_log/2,end_log/0]). +-export([get_log_dir/0,get_log_dir/1]). +-export([log/3,start_log/1,cont_log/2,end_log/0]). -export([set_stylesheet/2,clear_stylesheet/1]). -export([add_external_logs/1,add_link/3]). -export([make_last_run_index/0]). -export([make_all_suites_index/1,make_all_runs_index/1]). +-export([get_ts_html_wrapper/3]). %% Logging stuff directly from testcase -export([tc_log/3,tc_print/3,tc_pal/3,ct_log/3, @@ -53,6 +55,7 @@ -define(all_runs_name, "all_runs.html"). -define(index_name, "index.html"). -define(totals_name, "totals.info"). +-define(css_default, "ct_default.css"). -define(table_color1,"#ADD8E6"). -define(table_color2,"#E4F0FE"). @@ -162,7 +165,12 @@ clear_stylesheet(TC) -> %%%----------------------------------------------------------------- %%% @spec get_log_dir() -> {ok,Dir} | {error,Reason} get_log_dir() -> - call(get_log_dir). + call({get_log_dir,false}). + +%%%----------------------------------------------------------------- +%%% @spec get_log_dir(ReturnAbsName) -> {ok,Dir} | {error,Reason} +get_log_dir(ReturnAbsName) -> + call({get_log_dir,ReturnAbsName}). %%%----------------------------------------------------------------- %%% make_last_run_index() -> ok @@ -205,6 +213,7 @@ cast(Msg) -> %%% <p>This function is called by ct_framework:init_tc/3</p> init_tc(RefreshLog) -> call({init_tc,self(),group_leader(),RefreshLog}), + io:format(xhtml("", "<br />")), ok. %%%----------------------------------------------------------------- @@ -448,7 +457,6 @@ logger(Parent,Mode) -> timer:sleep(1000), Time1 = calendar:local_time(), Dir1 = make_dirname(Time1), - {Time1,Dir1}; false -> {Time0,Dir0} @@ -456,8 +464,44 @@ logger(Parent,Mode) -> %%! <--- file:make_dir(Dir), + AbsDir = ?abs(Dir), + put(ct_run_dir, AbsDir), + + case basic_html() of + true -> + put(basic_html, true); + BasicHtml -> + put(basic_html, BasicHtml), + %% copy stylesheet to log dir (both top dir and test run + %% dir) so logs are independent of Common Test installation + {ok,Cwd} = file:get_cwd(), + CTPath = code:lib_dir(common_test), + CSSFileSrc = filename:join(filename:join(CTPath, "priv"), + ?css_default), + CSSFileDestTop = filename:join(Cwd, ?css_default), + CSSFileDestRun = filename:join(AbsDir, ?css_default), + case file:copy(CSSFileSrc, CSSFileDestTop) of + {error,Reason0} -> + io:format(user, "ERROR! "++ + "CSS file ~p could not be copied to ~p. "++ + "Reason: ~p~n", + [CSSFileSrc,CSSFileDestTop,Reason0]), + exit({css_file_error,CSSFileDestTop}); + _ -> + case file:copy(CSSFileSrc, CSSFileDestRun) of + {error,Reason1} -> + io:format(user, "ERROR! "++ + "CSS file ~p could not be copied to ~p. "++ + "Reason: ~p~n", + [CSSFileSrc,CSSFileDestRun,Reason1]), + exit({css_file_error,CSSFileDestRun}); + _ -> + ok + end + end + end, ct_event:notify(#event{name=start_logging,node=node(), - data=?abs(Dir)}), + data=AbsDir}), make_all_runs_index(start), make_all_suites_index(start), case Mode of @@ -472,7 +516,7 @@ logger(Parent,Mode) -> Parent ! {started,self(),{Time,filename:absname("")}}, set_evmgr_gl(CtLogFd), logger_loop(#logger_state{parent=Parent, - log_dir=Dir, + log_dir=AbsDir, start_time=Time, orig_GL=group_leader(), ct_log_fd=CtLogFd, @@ -536,12 +580,15 @@ logger_loop(State) -> set_evmgr_gl(State#logger_state.ct_log_fd), return(From,ok), logger_loop(State#logger_state{tc_groupleaders=rm_tc_gl(TCPid,State)}); - {get_log_dir,From} -> + {{get_log_dir,true},From} -> return(From,{ok,State#logger_state.log_dir}), logger_loop(State); + {{get_log_dir,false},From} -> + return(From,{ok,filename:basename(State#logger_state.log_dir)}), + logger_loop(State); {make_last_run_index,From} -> make_last_run_index(State#logger_state.start_time), - return(From,State#logger_state.log_dir), + return(From,filename:basename(State#logger_state.log_dir)), logger_loop(State); {set_stylesheet,_,SSFile} when State#logger_state.stylesheet == SSFile -> logger_loop(State); @@ -657,7 +704,7 @@ set_evmgr_gl(GL) -> open_ctlog() -> {ok,Fd} = file:open(?ct_log_name,[write]), - io:format(Fd,header("Common Test Framework"),[]), + io:format(Fd, header("Common Test Framework Log"), []), case file:consult(ct_run:variables_file_name("../")) of {ok,Vars} -> io:format(Fd, config_table(Vars), []); @@ -672,17 +719,22 @@ open_ctlog() -> end, print_style(Fd,undefined), io:format(Fd, - "<br><br><h2>Progress Log</h2>\n" - "<pre>\n",[]), + xhtml("<br><br><h2>Progress Log</h2>\n<pre>\n", + "<br /><br /><h4>PROGRESS LOG</h4>\n<pre>\n"), []), Fd. print_style(Fd,undefined) -> - io:format(Fd, - "<style>\n" - "div.ct_internal { background:lightgrey; color:black }\n" - "div.default { background:lightgreen; color:black }\n" - "</style>\n", - []); + case basic_html() of + true -> + io:format(Fd, + "<style>\n" + "div.ct_internal { background:lightgrey; color:black; }\n" + "div.default { background:lightgreen; color:black; }\n" + "</style>\n", + []); + _ -> + ok + end; print_style(Fd,StyleSheet) -> case file:read_file(StyleSheet) of @@ -692,20 +744,19 @@ print_style(Fd,StyleSheet) -> 0 -> string:str(Str,"<STYLE>"); N0 -> N0 end, - case Pos0 of - 0 -> print_style_error(Fd,StyleSheet,missing_style_tag); - _ -> - Pos1 = case string:str(Str,"</style>") of - 0 -> string:str(Str,"</STYLE>"); - N1 -> N1 - end, - case Pos1 of - 0 -> - print_style_error(Fd,StyleSheet,missing_style_end_tag); - _ -> - Style = string:sub_string(Str,Pos0,Pos1+7), - io:format(Fd,"~s\n",[Style]) - end + Pos1 = case string:str(Str,"</style>") of + 0 -> string:str(Str,"</STYLE>"); + N1 -> N1 + end, + if (Pos0 == 0) and (Pos1 /= 0) -> + print_style_error(Fd,StyleSheet,missing_style_start_tag); + (Pos0 /= 0) and (Pos1 == 0) -> + print_style_error(Fd,StyleSheet,missing_style_end_tag); + Pos0 /= 0 -> + Style = string:sub_string(Str,Pos0,Pos1+7), + io:format(Fd,"~s\n",[Style]); + Pos0 == 0 -> + io:format(Fd,"<style>~s</style>\n",[Str]) end; {error,Reason} -> print_style_error(Fd,StyleSheet,Reason) @@ -723,7 +774,7 @@ print_style_error(Fd,StyleSheet,Reason) -> print_style(Fd,undefined). close_ctlog(Fd) -> - io:format(Fd,"</pre>",[]), + io:format(Fd,"\n</pre>\n",[]), io:format(Fd,footer(),[]), file:close(Fd). @@ -854,8 +905,8 @@ make_one_index_entry1(SuiteName, Link, Label, Success, Fail, UserSkip, AutoSkip, CrashDumpName = SuiteName ++ "_erl_crash.dump", case filelib:is_file(CrashDumpName) of true -> - [" <A HREF=\"", CrashDumpName, - "\">(CrashDump)</A>"]; + [" <a href=\"", CrashDumpName, + "\">(CrashDump)</a>"]; false -> "" end @@ -869,32 +920,41 @@ make_one_index_entry1(SuiteName, Link, Label, Success, Fail, UserSkip, AutoSkip, 0 -> "-"; _ -> NodeOrDate end, - N = ["<TD ALIGN=right><FONT SIZE=-1>",Node1,"</FONT></TD>\n"], - L = ["<TD ALIGN=center><FONT SIZE=-1><B>",Label,"</FONT></B></TD>\n"], - T = ["<TD><FONT SIZE=-1>",timestamp(CtRunDir),"</FONT></TD>\n"], + TS = timestamp(CtRunDir), + N = xhtml(["<td align=right><font size=\"-1\">",Node1, + "</font></td>\n"], + ["<td align=right>",Node1,"</td>\n"]), + L = xhtml(["<td align=center><font size=\"-1\"><b>",Label, + "</font></b></td>\n"], + ["<td align=center><b>",Label,"</b></td>\n"]), + T = xhtml(["<td><font size=\"-1\">",TS,"</font></td>\n"], + ["<td>",TS,"</td>\n"]), CtLogFile = filename:join(CtRunDir,?ct_log_name), OldRunsLink = case OldRuns of [] -> "none"; - _ -> "<A HREF=\""++?all_runs_name++"\">Old Runs</A>" + _ -> "<a href=\""++?all_runs_name++"\">Old Runs</a>" end, - A=["<TD><FONT SIZE=-1><A HREF=\"",CtLogFile,"\">CT Log</A></FONT></TD>\n", - "<TD><FONT SIZE=-1>",OldRunsLink,"</FONT></TD>\n"], + A = xhtml(["<td><font size=\"-1\"><a href=\"",CtLogFile, + "\">CT Log</a></font></td>\n", + "<td><font size=\"-1\">",OldRunsLink,"</font></td>\n"], + ["<td><a href=\"",CtLogFile,"\">CT Log</a></td>\n", + "<td>",OldRunsLink,"</td>\n"]), {L,T,N,A}; false -> {"","","",""} end, NotBuiltStr = if NotBuilt == 0 -> - ["<TD ALIGN=right>",integer_to_list(NotBuilt),"</TD>\n"]; + ["<td align=right>",integer_to_list(NotBuilt),"</td>\n"]; true -> - ["<TD ALIGN=right><A HREF=\"",filename:join(CtRunDir,?ct_log_name),"\">", - integer_to_list(NotBuilt),"</A></TD>\n"] + ["<td align=right><a href=\"",filename:join(CtRunDir,?ct_log_name),"\">", + integer_to_list(NotBuilt),"</a></td>\n"] end, FailStr = if Fail > 0 -> - ["<FONT color=\"red\">", - integer_to_list(Fail),"</FONT>"]; + ["<font color=\"red\">", + integer_to_list(Fail),"</font>"]; true -> integer_to_list(Fail) end, @@ -902,31 +962,33 @@ make_one_index_entry1(SuiteName, Link, Label, Success, Fail, UserSkip, AutoSkip, if AutoSkip == undefined -> {UserSkip,"?","?"}; true -> ASStr = if AutoSkip > 0 -> - ["<FONT color=\"brown\">", - integer_to_list(AutoSkip),"</FONT>"]; + ["<font color=\"brown\">", + integer_to_list(AutoSkip),"</font>"]; true -> integer_to_list(AutoSkip) end, {UserSkip+AutoSkip,integer_to_list(UserSkip),ASStr} end, - ["<TR valign=top>\n", - "<TD><FONT SIZE=-1><A HREF=\"",LogFile,"\">",SuiteName,"</A>",CrashDumpLink,"</FONT></TD>\n", - Lbl, - Timestamp, - "<TD ALIGN=right>",integer_to_list(Success),"</TD>\n", - "<TD ALIGN=right>",FailStr,"</TD>\n", - "<TD ALIGN=right>",integer_to_list(AllSkip), - " (",UserSkipStr,"/",AutoSkipStr,")</TD>\n", - NotBuiltStr, - Node, - AllInfo, - "</TR>\n"]. + [xhtml("<tr valign=top>\n", + ["<tr class=\"",odd_or_even(),"\">\n"]), + xhtml("<td><font size=\"-1\"><a href=\"", "<td><a href=\""), + LogFile,"\">",SuiteName,"</a>", CrashDumpLink, + xhtml("</font></td>\n", "</td>\n"), + Lbl, Timestamp, + "<td align=right>",integer_to_list(Success),"</td>\n", + "<td align=right>",FailStr,"</td>\n", + "<td align=right>",integer_to_list(AllSkip), + " (",UserSkipStr,"/",AutoSkipStr,")</td>\n", + NotBuiltStr, Node, AllInfo, "</tr>\n"]. + total_row(Success, Fail, UserSkip, AutoSkip, NotBuilt, All) -> {Label,TimestampCell,AllInfo} = case All of true -> - {"<TD> </TD>\n", - "<TD> </TD>\n", - "<TD> </TD>\n<TD> </TD>\n"}; + {"<td> </td>\n", + "<td> </td>\n", + "<td> </td>\n" + "<td> </td>\n" + "<td> </td>\n"}; false -> {"","",""} end, @@ -936,17 +998,15 @@ total_row(Success, Fail, UserSkip, AutoSkip, NotBuilt, All) -> true -> {UserSkip+AutoSkip, integer_to_list(UserSkip),integer_to_list(AutoSkip)} end, - ["<TR valign=top>\n", - "<TD><B>Total</B></TD>", - Label, - TimestampCell, - "<TD ALIGN=right><B>",integer_to_list(Success),"<B></TD>\n", - "<TD ALIGN=right><B>",integer_to_list(Fail),"<B></TD>\n", - "<TD ALIGN=right>",integer_to_list(AllSkip), - " (",UserSkipStr,"/",AutoSkipStr,")</TD>\n", - "<TD ALIGN=right><B>",integer_to_list(NotBuilt),"<B></TD>\n", - AllInfo, - "</TR>\n"]. + [xhtml("<tr valign=top>\n", + ["<tr class=\"",odd_or_even(),"\">\n"]), + "<td><b>Total</b></td>\n", Label, TimestampCell, + "<td align=right><b>",integer_to_list(Success),"<b></td>\n", + "<td align=right><b>",integer_to_list(Fail),"<b></td>\n", + "<td align=right>",integer_to_list(AllSkip), + " (",UserSkipStr,"/",AutoSkipStr,")</td>\n", + "<td align=right><b>",integer_to_list(NotBuilt),"<b></td>\n", + AllInfo, "</tr>\n"]. not_built(_BaseName,_LogDir,_All,[]) -> 0; @@ -1005,41 +1065,52 @@ index_header(Label, StartTime) -> undefined -> header("Test Results", format_time(StartTime)); _ -> - header("Test Results for \"" ++ Label ++ "\"", + header("Test Results for '" ++ Label ++ "'", format_time(StartTime)) end, [Head | - ["<CENTER>\n", - "<P><A HREF=\"",?ct_log_name,"\">Common Test Framework Log</A></P>", - "<TABLE border=\"3\" cellpadding=\"5\" " - "BGCOLOR=\"",?table_color3,"\">\n" - "<th><B>Test Name</B></th>\n", - "<th><font color=\"",?table_color3,"\">_</font>Ok" - "<font color=\"",?table_color3,"\">_</font></th>\n" + ["<center>\n", + xhtml(["<p><a href=\"",?ct_log_name, + "\">Common Test Framework Log</a></p>"], + ["<br />" + "<div id=\"button_holder\" class=\"btn\">\n" + "<a href=\"",?ct_log_name, + "\">COMMON TEST FRAMEWORK LOG</a>\n</div>"]), + xhtml("<br>\n", "<br /><br /><br />\n"), + xhtml(["<table border=\"3\" cellpadding=\"5\" " + "bgcolor=\"",?table_color3,"\">\n"], "<table>\n"), + "<th><b>Test Name</b></th>\n", + xhtml(["<th><font color=\"",?table_color3,"\">_</font>Ok" + "<font color=\"",?table_color3,"\">_</font></th>\n"], + "<th>Ok</th>\n"), "<th>Failed</th>\n", - "<th>Skipped<br>(User/Auto)</th>\n" - "<th>Missing<br>Suites</th>\n" + "<th>Skipped", xhtml("<br>", "<br />"), "(User/Auto)</th>\n" + "<th>Missing", xhtml("<br>", "<br />"), "Suites</th>\n" "\n"]]. - all_suites_index_header() -> {ok,Cwd} = file:get_cwd(), all_suites_index_header(Cwd). all_suites_index_header(IndexDir) -> LogDir = filename:basename(IndexDir), - AllRuns = "All test runs in \"" ++ LogDir ++ "\"", + AllRuns = xhtml(["All test runs in \"" ++ LogDir ++ "\""], + "ALL RUNS"), + AllRunsLink = xhtml(["<a href=\"",?all_runs_name,"\">",AllRuns,"</a>\n"], + ["<div id=\"button_holder\" class=\"btn\">\n" + "<a href=\"",?all_runs_name,"\">",AllRuns,"</a>\n</div>"]), [header("Test Results") | - ["<CENTER>\n", - "<A HREF=\"",?all_runs_name,"\">",AllRuns,"</A>\n", - "<br><br>\n", - "<TABLE border=\"3\" cellpadding=\"5\" " - "BGCOLOR=\"",?table_color2,"\">\n" + ["<center>\n", + AllRunsLink, + xhtml("<br><br>\n", "<br /><br />\n"), + xhtml(["<table border=\"3\" cellpadding=\"5\" " + "bgcolor=\"",?table_color2,"\">\n"], "<table>\n"), "<th>Test Name</th>\n", "<th>Label</th>\n", "<th>Test Run Started</th>\n", - "<th><font color=\"",?table_color2,"\">_</font>Ok" - "<font color=\"",?table_color2,"\">_</font></th>\n" + xhtml(["<th><font color=\"",?table_color2,"\">_</font>Ok" + "<font color=\"",?table_color2,"\">_</font></th>\n"], + "<th>Ok</th>\n"), "<th>Failed</th>\n", "<th>Skipped<br>(User/Auto)</th>\n" "<th>Missing<br>Suites</th>\n" @@ -1052,17 +1123,25 @@ all_runs_header() -> {ok,Cwd} = file:get_cwd(), LogDir = filename:basename(Cwd), Title = "All test runs in \"" ++ LogDir ++ "\"", + IxLink = [xhtml(["<p><a href=\"",?index_name, + "\">Test Index Page</a></p>"], + ["<div id=\"button_holder\" class=\"btn\">\n" + "<a href=\"",?index_name, + "\">TEST INDEX PAGE</a>\n</div>"]), + xhtml("<br>\n", "<br /><br />\n")], [header(Title) | - ["<CENTER><TABLE border=\"3\" cellpadding=\"5\" " - "BGCOLOR=\"",?table_color1,"\">\n" - "<th><B>History</B></th>\n" - "<th><B>Node</B></th>\n" - "<th><B>Label</B></th>\n" + ["<center>\n", IxLink, + xhtml(["<table border=\"3\" cellpadding=\"5\" " + "bgcolor=\"",?table_color1,"\">\n"], "<table>\n"), + "<th><b>History</b></th>\n" + "<th><b>Node</b></th>\n" + "<th><b>Label</b></th>\n" "<th>Tests</th>\n" - "<th><B>Test Names</B></th>\n" - "<th>Total</th>\n" - "<th><font color=\"",?table_color1,"\">_</font>Ok" - "<font color=\"",?table_color1,"\">_</font></th>\n" + "<th><b>Test Names</b></th>\n" + "<th>Total</th>\n", + xhtml(["<th><font color=\"",?table_color1,"\">_</font>Ok" + "<font color=\"",?table_color1,"\">_</font></th>\n"], + "<th>Ok</th>\n"), "<th>Failed</th>\n" "<th>Skipped<br>(User/Auto)</th>\n" "<th>Missing<br>Suites</th>\n" @@ -1075,60 +1154,56 @@ header(Title, SubTitle) -> header1(Title, SubTitle) -> SubTitleHTML = if SubTitle =/= "" -> - ["<CENTER>\n", - "<H2>" ++ SubTitle ++ "</H2>\n", - "</CENTER>\n<BR>\n"]; - true -> "<BR>\n" + ["<center>\n", + "<h3>" ++ SubTitle ++ "</h3>\n", + xhtml("</center>\n<br>\n", "</center>\n<br />\n")]; + true -> xhtml("<br>\n", "<br />\n") end, - ["<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n" - "<!-- autogenerated by '"++atom_to_list(?MODULE)++"'. -->\n" - "<HTML>\n", - "<HEAD>\n", - - "<TITLE>" ++ Title ++ " " ++ SubTitle ++ "</TITLE>\n", - "<META HTTP-EQUIV=\"CACHE-CONTROL\" CONTENT=\"NO-CACHE\">\n", - - "</HEAD>\n", - - body_tag(), - - "<!-- ---- DOCUMENT TITLE ---- -->\n", - - "<CENTER>\n", - "<H1>" ++ Title ++ "</H1>\n", - "</CENTER>\n", - SubTitleHTML, - - "<!-- ---- CONTENT ---- -->\n"]. + CSSFile = xhtml(fun() -> "" end, + fun() -> make_relative(locate_default_css_file()) end), + [xhtml(["<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n", + "<html>\n"], + ["<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n", + "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n", + "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n"]), + "<!-- autogenerated by '"++atom_to_list(?MODULE)++"' -->\n", + "<head>\n", + "<title>" ++ Title ++ " " ++ SubTitle ++ "</title>\n", + "<meta http-equiv=\"cache-control\" content=\"no-cache\">\n", + xhtml("", + ["<link rel=\"stylesheet\" href=\"",CSSFile,"\" type=\"text/css\">"]), + "</head>\n", + body_tag(), + "<center>\n", + "<h1>" ++ Title ++ "</h1>\n", + "</center>\n", + SubTitleHTML,"\n"]. index_footer() -> - ["</TABLE>\n" - "</CENTER>\n" | footer()]. + ["</table>\n" + "</center>\n" | footer()]. footer() -> - ["<P><CENTER>\n" - "<BR><BR>\n" - "<HR>\n" - "<P><FONT SIZE=-1>\n" + ["<center>\n", + xhtml("<br><br>\n<hr>\n", "<br /><br />\n"), + xhtml("<p><font size=\"-1\">\n", "<div class=\"copyright\">"), "Copyright © ", year(), - " <A HREF=\"http://erlang.ericsson.se\">Open Telecom Platform</A><BR>\n" - "Updated: <!date>", current_time(), "<!/date><BR>\n" - "</FONT>\n" - "</CENTER>\n" + " <a href=\"http://www.erlang.org\">Open Telecom Platform</a>", + xhtml("<br>\n", "<br />\n"), + "Updated: <!date>", current_time(), "<!/date>", + xhtml("<br>\n", "<br />\n"), + xhtml("</font></p>\n", "</div>\n"), + "</center>\n" "</body>\n"]. body_tag() -> - case basic_html() of - true -> - "<body bgcolor=\"#FFFFFF\" text=\"#000000\" link=\"#0000FF\" " - "vlink=\"#800080\" alink=\"#FF0000\">\n"; - false -> - CTPath = code:lib_dir(common_test), - TileFile = filename:join(filename:join(CTPath,"priv"),"tile1.jpg"), - "<body background=\"" ++ TileFile ++ "\" bgcolor=\"#FFFFFF\" text=\"#000000\" link=\"#0000FF\" " - "vlink=\"#800080\" alink=\"#FF0000\">\n" - end. + CTPath = code:lib_dir(common_test), + TileFile = filename:join(filename:join(CTPath,"priv"),"tile1.jpg"), + xhtml("<body background=\"" ++ TileFile ++ + "\" bgcolor=\"#FFFFFF\" text=\"#000000\" link=\"#0000FF\" " + "vlink=\"#800080\" alink=\"#FF0000\">\n", + "<body>\n"). current_time() -> format_time(calendar:local_time()). @@ -1258,20 +1333,25 @@ config_table(Vars) -> [config_table_header()|config_table1(Vars)]. config_table_header() -> - ["<h2>Configuration</h2>\n", - "<table border=\"3\" cellpadding=\"5\" bgcolor=\"",?table_color1, - "\"\n", + [ + xhtml(["<h2>Configuration</h2>\n" + "<table border=\"3\" cellpadding=\"5\" bgcolor=\"",?table_color1,"\"\n"], + "<h4>CONFIGURATION</h4>\n<table>\n"), "<tr><th>Key</th><th>Value</th></tr>\n"]. config_table1([{Key,Value}|Vars]) -> - ["<tr><td>", atom_to_list(Key), "</td>\n", - "<td><pre>",io_lib:format("~p",[Value]),"</pre></td></tr>\n" | + [xhtml(["<tr><td>", atom_to_list(Key), "</td>\n", + "<td><pre>",io_lib:format("~p",[Value]),"</pre></td></tr>\n"], + ["<tr class=\"", odd_or_even(), "\">\n", + "<td>", atom_to_list(Key), "</td>\n", + "<td>", io_lib:format("~p",[Value]), "</td>\n</tr>\n"]) | config_table1(Vars)]; config_table1([]) -> ["</table>\n"]. make_all_runs_index(When) -> + put(basic_html, basic_html()), AbsName = ?abs(?all_runs_name), notify_and_lock_file(AbsName), if When == start -> ok; @@ -1280,8 +1360,7 @@ make_all_runs_index(When) -> Dirs = filelib:wildcard(logdir_prefix()++"*.*"), DirsSorted = (catch sort_all_runs(Dirs)), Header = all_runs_header(), - BasicHtml = basic_html(), - Index = [runentry(Dir, BasicHtml) || Dir <- DirsSorted], + Index = [runentry(Dir) || Dir <- DirsSorted], Result = file:write_file(AbsName,Header++Index++index_footer()), if When == start -> ok; true -> io:put_chars("done\n") @@ -1309,22 +1388,22 @@ sort_all_runs(Dirs) -> interactive_link() -> [Dir|_] = lists:reverse(filelib:wildcard(logdir_prefix()++"*.*")), CtLog = filename:join(Dir,"ctlog.html"), - Body = ["Log from last interactive run: <A HREF=\"",CtLog,"\">", - timestamp(Dir),"</A>"], + Body = ["Log from last interactive run: <a href=\"",CtLog,"\">", + timestamp(Dir),"</a>"], file:write_file("last_interactive.html",Body), io:format("~n~nUpdated ~s\n" "Any CT activities will be logged here\n", [?abs("last_interactive.html")]). -runentry(Dir, BasicHtml) -> +runentry(Dir) -> TotalsFile = filename:join(Dir,?totals_name), TotalsStr = case read_totals_file(TotalsFile) of {Node,Label,Logs,{TotSucc,TotFail,UserSkip,AutoSkip,NotBuilt}} -> TotFailStr = if TotFail > 0 -> - ["<FONT color=\"red\">", - integer_to_list(TotFail),"</FONT>"]; + ["<font color=\"red\">", + integer_to_list(TotFail),"</font>"]; true -> integer_to_list(TotFail) end, @@ -1332,8 +1411,8 @@ runentry(Dir, BasicHtml) -> if AutoSkip == undefined -> {UserSkip,"?","?"}; true -> ASStr = if AutoSkip > 0 -> - ["<FONT color=\"brown\">", - integer_to_list(AutoSkip),"</FONT>"]; + ["<font color=\"brown\">", + integer_to_list(AutoSkip),"</font>"]; true -> integer_to_list(AutoSkip) end, {UserSkip+AutoSkip,integer_to_list(UserSkip),ASStr} @@ -1365,30 +1444,49 @@ runentry(Dir, BasicHtml) -> lists:flatten(io_lib:format("~s...",[Trunc])) end, Total = TotSucc+TotFail+AllSkip, - A = ["<TD ALIGN=center><FONT SIZE=-1>",Node,"</FONT></TD>\n", - "<TD ALIGN=center><FONT SIZE=-1><B>",Label,"</B></FONT></TD>\n", - "<TD ALIGN=right>",NoOfTests,"</TD>\n"], - B = if BasicHtml -> - ["<TD ALIGN=center><FONT SIZE=-1>",TestNamesTrunc,"</FONT></TD>\n"]; - true -> - ["<TD ALIGN=center TITLE='",TestNames,"'><FONT SIZE=-1> ", - TestNamesTrunc,"</FONT></TD>\n"] - end, - C = ["<TD ALIGN=right>",integer_to_list(Total),"</TD>\n", - "<TD ALIGN=right>",integer_to_list(TotSucc),"</TD>\n", - "<TD ALIGN=right>",TotFailStr,"</TD>\n", - "<TD ALIGN=right>",integer_to_list(AllSkip), - " (",UserSkipStr,"/",AutoSkipStr,")</TD>\n", - "<TD ALIGN=right>",integer_to_list(NotBuilt),"</TD>\n"], + A = xhtml(["<td align=center><font size=\"-1\">",Node, + "</font></td>\n", + "<td align=center><font size=\"-1\"><b>",Label, + "</b></font></td>\n", + "<td align=right>",NoOfTests,"</td>\n"], + ["<td align=center>",Node,"</td>\n", + "<td align=center><b>",Label,"</b></td>\n", + "<td align=right>",NoOfTests,"</td>\n"]), + B = xhtml(["<td align=center title='",TestNames,"'><font size=\"-1\"> ", + TestNamesTrunc,"</font></td>\n"], + ["<td align=center title='",TestNames,"'> ", + TestNamesTrunc,"</td>\n"]), + C = ["<td align=right>",integer_to_list(Total),"</td>\n", + "<td align=right>",integer_to_list(TotSucc),"</td>\n", + "<td align=right>",TotFailStr,"</td>\n", + "<td align=right>",integer_to_list(AllSkip), + " (",UserSkipStr,"/",AutoSkipStr,")</td>\n", + "<td align=right>",integer_to_list(NotBuilt),"</td>\n"], A++B++C; _ -> - ["<TD ALIGN=center><FONT size=-1 color=\"red\">", - "Test data missing or corrupt","</FONT></TD>\n"] + A = xhtml(["<td align=center><font size=\"-1\" color=\"red\">" + "Test data missing or corrupt</font></td>\n", + "<td align=center><font size=\"-1\">?</font></td>\n", + "<td align=right>?</td>\n"], + ["<td align=center><font color=\"red\">" + "Test data missing or corrupt</font></td>\n", + "<td align=center>?</td>\n", + "<td align=right>?</td>\n"]), + B = xhtml(["<td align=center><font size=\"-1\">?</font></td>\n"], + ["<td align=center>?</td>\n"]), + C = ["<td align=right>?</td>\n", + "<td align=right>?</td>\n", + "<td align=right>?</td>\n", + "<td align=right>?</td>\n", + "<td align=right>?</td>\n"], + A++B++C end, Index = filename:join(Dir,?index_name), - ["<TR>\n" - "<TD><FONT SIZE=-1><A HREF=\"",Index,"\">",timestamp(Dir),"</A>",TotalsStr,"</FONT></TD>\n" - "</TR>\n"]. + [xhtml("<tr>\n", ["<tr class=\"",odd_or_even(),"\">\n"]), + xhtml(["<td><font size=\"-1\"><a href=\"",Index,"\">",timestamp(Dir),"</a>", + TotalsStr,"</font></td>\n"], + ["<td><a href=\"",Index,"\">",timestamp(Dir),"</a>",TotalsStr,"</td>\n"]), + "</tr>\n"]. write_totals_file(Name,Label,Logs,Totals) -> AbsName = ?abs(Name), @@ -1482,6 +1580,7 @@ timestamp(Dir) -> %% Creates the top level index file. When == start | refresh. %% A copy of the dir tree under logdir is cached as a result. make_all_suites_index(When) when is_atom(When) -> + put(basic_html, basic_html()), AbsIndexName = ?abs(?index_name), notify_and_lock_file(AbsIndexName), LogDirs = filelib:wildcard(logdir_prefix()++".*/*"++?logdir_ext), @@ -1493,6 +1592,7 @@ make_all_suites_index(When) when is_atom(When) -> %% This updates the top level index file using cached data from %% the initial index file creation. make_all_suites_index(NewTestData = {_TestName,DirName}) -> + put(basic_html, basic_html()), %% AllLogDirs = [{TestName,Label,Missing,{LastLogDir,Summary},OldDirs}|...] {AbsIndexName,LogDirData} = ct_util:get_testdata(test_index), @@ -1850,6 +1950,38 @@ last_test([], Latest) -> Latest. %%%----------------------------------------------------------------- +%%% @spec xhtml(HTML, XHTML) -> HTML | XHTML +%%% +%%% @doc +%%% +xhtml(HTML, XHTML) when is_function(HTML), + is_function(XHTML) -> + case get(basic_html) of + true -> HTML(); + _ -> XHTML() + end; +xhtml(HTML, XHTML) -> + case get(basic_html) of + true -> HTML; + _ -> XHTML + end. + +%%%----------------------------------------------------------------- +%%% @spec odd_or_even() -> "odd" | "even" +%%% +%%% @doc +%%% +odd_or_even() -> + case get(odd_or_even) of + even -> + put(odd_or_even, odd), + "even"; + _ -> + put(odd_or_even, even), + "odd" + end. + +%%%----------------------------------------------------------------- %%% @spec basic_html() -> true | false %%% %%% @doc @@ -1861,3 +1993,149 @@ basic_html() -> _ -> false end. + +%%%----------------------------------------------------------------- +%%% @spec locate_default_css_file() -> CSSFile +%%% +%%% @doc +%%% +locate_default_css_file() -> + {ok,CWD} = file:get_cwd(), + CSSFileInCwd = filename:join(CWD, ?css_default), + case filelib:is_file(CSSFileInCwd) of + true -> + CSSFileInCwd; + false -> + CSSResultFile = + case {whereis(?MODULE),self()} of + {Self,Self} -> + %% executed on the ct_logs process + filename:join(get(ct_run_dir), ?css_default); + _ -> + %% executed on other process than ct_logs + {ok,RunDir} = get_log_dir(true), + filename:join(RunDir, ?css_default) + end, + case filelib:is_file(CSSResultFile) of + true -> + CSSResultFile; + false -> + %% last resort, try use css file in CT installation + CTPath = code:lib_dir(common_test), + filename:join(filename:join(CTPath, "priv"), ?css_default) + end + end. + +%%%----------------------------------------------------------------- +%%% @spec make_relative(AbsDir, Cwd) -> RelDir +%%% +%%% @doc Return directory path to File (last element of AbsDir), which +%%% is the path relative to Cwd. Examples when Cwd == "/ldisk/test/logs": +%%% make_relative("/ldisk/test/logs/run/trace.log") -> "run/trace.log" +%%% make_relative("/ldisk/test/trace.log") -> "../trace.log" +%%% make_relative("/ldisk/test/logs/trace.log") -> "trace.log" +make_relative(AbsDir) -> + {ok,Cwd} = file:get_cwd(), + make_relative(AbsDir, Cwd). + +make_relative(AbsDir, Cwd) -> + DirTokens = filename:split(AbsDir), + CwdTokens = filename:split(Cwd), + filename:join(make_relative1(DirTokens, CwdTokens)). + +make_relative1([T | DirTs], [T | CwdTs]) -> + make_relative1(DirTs, CwdTs); +make_relative1(Last = [_File], []) -> + Last; +make_relative1(Last = [_File], CwdTs) -> + Ups = ["../" || _ <- CwdTs], + Ups ++ Last; +make_relative1(DirTs, []) -> + DirTs; +make_relative1(DirTs, CwdTs) -> + Ups = ["../" || _ <- CwdTs], + Ups ++ DirTs. + +%%%----------------------------------------------------------------- +%%% @spec get_ts_html_wrapper(TestName, PrintLabel, Cwd) -> {Mode,Header,Footer} +%%% +%%% @doc +%%% +get_ts_html_wrapper(TestName, PrintLabel, Cwd) -> + TestName1 = if is_list(TestName) -> + lists:flatten(TestName); + true -> + lists:flatten(io_lib:format("~p", [TestName])) + end, + Basic = basic_html(), + LabelStr = + if not PrintLabel -> + ""; + true -> + case {Basic,application:get_env(common_test, test_label)} of + {true,{ok,Lbl}} when Lbl =/= undefined -> + "<h1><font color=\"green\">" ++ Lbl ++ "</font></h1>\n"; + {_,{ok,Lbl}} when Lbl =/= undefined -> + "<div class=\"label\">'" ++ Lbl ++ "'</div>\n"; + _ -> + "" + end + end, + CTPath = code:lib_dir(common_test), + {ok,CtLogdir} = get_log_dir(true), + AllRuns = make_relative(filename:join(filename:dirname(CtLogdir), + ?all_runs_name), Cwd), + TestIndex = make_relative(filename:join(filename:dirname(CtLogdir), + ?index_name), Cwd), + case Basic of + true -> + TileFile = filename:join(filename:join(CTPath,"priv"),"tile1.jpg"), + Bgr = " background=\"" ++ TileFile ++ "\"", + Copyright = + ["<p><font size=\"-1\">\n", + "Copyright © ", year(), + " <a href=\"http://www.erlang.org\">", + "Open Telecom Platform</a><br>\n", + "Updated: <!date>", current_time(), "<!/date>", + "<br>\n</font></p>\n"], + {basic_html, + ["<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n", + "<html>\n", + "<head><title>", TestName1, "</title>\n", + "<meta http-equiv=\"cache-control\" content=\"no-cache\">\n", + "</head>\n", + "<body", Bgr, " bgcolor=\"white\" text=\"black\" ", + "link=\"blue\" vlink=\"purple\" alink=\"red\">\n", + LabelStr, "\n"], + ["<center>\n<br><hr><p>\n", + "<a href=\"", AllRuns, + "\">Test run history\n</a> | ", + "<a href=\"", TestIndex, + "\">Top level test index\n</a>\n</p>\n", + Copyright,"</center>\n</body>\n</html>\n"]}; + _ -> + Copyright = + ["<div class=\"copyright\">", + "Copyright © ", year(), + " <a href=\"http://www.erlang.org\">", + "Open Telecom Platform</a><br />\n", + "Updated: <!date>", current_time(), "<!/date>", + "<br />\n</div>\n"], + CSSFile = xhtml(fun() -> "" end, + fun() -> make_relative(locate_default_css_file(), Cwd) end), + {xhtml, + ["<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n", + "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n", + "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n", + "<head>\n<title>", TestName1, "</title>\n", + "<meta http-equiv=\"cache-control\" content=\"no-cache\">\n", + "<link rel=\"stylesheet\" href=\"", CSSFile, "\" type=\"text/css\">", + "</head>\n","<body>\n", + LabelStr, "\n"], + ["<center>\n<br /><hr /><p>\n", + "<a href=\"", AllRuns, + "\">Test run history\n</a> | ", + "<a href=\"", TestIndex, + "\">Top level test index\n</a>\n</p>\n", + Copyright,"</center>\n</body>\n</html>\n"]} + end. diff --git a/lib/common_test/test/ct_hooks_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE.erl index 5c99f0f9f7..2c519f08b5 100644 --- a/lib/common_test/test/ct_hooks_SUITE.erl +++ b/lib/common_test/test/ct_hooks_SUITE.erl @@ -1046,29 +1046,34 @@ test_events(prio_cth) -> [900],[900,900],[500,900],[1000],[1200,1050], [1100],[1200]]) ++ GenPost(post_end_per_testcase, - [[1100,100],[600,200],[600,600],[600],[700],[800], - [900],[900,900],[500,900],[1000],[1200,1050], - [1100],[1200]]) ++ + lists:reverse( + [[1100,100],[600,200],[600,600],[600],[700],[800], + [900],[900,900],[500,900],[1000],[1200,1050], + [1100],[1200]])) ++ [{?eh,tc_done,{ct_cth_prio_SUITE,test_case,ok}}, {?eh,tc_start,{ct_cth_prio_SUITE,{end_per_group,'_',[]}}}] ++ GenPre(pre_end_per_group, - [[1100,100],[600,200],[600,600],[600],[700],[800], - [900],[900,900],[500,900],[1000],[1200,1050], - [1100],[1200]]) ++ + lists:reverse( + [[1100,100],[600,200],[600,600],[600],[700],[800], + [900],[900,900],[500,900],[1000],[1200,1050], + [1100],[1200]])) ++ GenPost(post_end_per_group, - [[1100,100],[600,200],[600,600],[600],[700],[800], - [900],[900,900],[500,900],[1000],[1200,1050], - [1100],[1200]]) ++ + lists:reverse( + [[1100,100],[600,200],[600,600],[600],[700],[800], + [900],[900,900],[500,900],[1000],[1200,1050], + [1100],[1200]])) ++ [{?eh,tc_done,{ct_cth_prio_SUITE,{end_per_group,'_',[]},ok}}], {?eh,tc_start,{ct_cth_prio_SUITE,end_per_suite}}] ++ GenPre(pre_end_per_suite, - [[1100,100],[600,200],[600,600],[700],[800],[900],[1000], - [1200,1050],[1100],[1200]]) ++ + lists:reverse( + [[1100,100],[600,200],[600,600],[700],[800],[900],[1000], + [1200,1050],[1100],[1200]])) ++ GenPost(post_end_per_suite, - [[1100,100],[600,200],[600,600],[700],[800],[900],[1000], - [1200,1050],[1100],[1200]]) ++ + lists:reverse( + [[1100,100],[600,200],[600,600],[700],[800],[900],[1000], + [1200,1050],[1100],[1200]])) ++ [{?eh,tc_done,{ct_cth_prio_SUITE,end_per_suite,ok}}, {?eh,test_done,{'DEF','STOP_TIME'}}, {?eh,stop_logging,[]}]; diff --git a/lib/compiler/src/Makefile b/lib/compiler/src/Makefile index 1238d113e1..7a237608ad 100644 --- a/lib/compiler/src/Makefile +++ b/lib/compiler/src/Makefile @@ -59,6 +59,7 @@ MODULES = \ beam_opcodes \ beam_peep \ beam_receive \ + beam_split \ beam_trim \ beam_type \ beam_utils \ diff --git a/lib/compiler/src/beam_dead.erl b/lib/compiler/src/beam_dead.erl index 9f81a6ab43..5f12a98f09 100644 --- a/lib/compiler/src/beam_dead.erl +++ b/lib/compiler/src/beam_dead.erl @@ -131,10 +131,9 @@ -import(lists, [mapfoldl/3,reverse/1]). module({Mod,Exp,Attr,Fs0,_}, _Opts) -> - Fs1 = [split_blocks(F) || F <- Fs0], - {Fs2,Lc1} = beam_clean:clean_labels(Fs1), - {Fs,Lc} = mapfoldl(fun function/2, Lc1, Fs2), - %%{Fs,Lc} = {Fs2,Lc1}, + {Fs1,Lc1} = beam_clean:clean_labels(Fs0), + {Fs,Lc} = mapfoldl(fun function/2, Lc1, Fs1), + %%{Fs,Lc} = {Fs1,Lc1}, {ok,{Mod,Exp,Attr,Fs,Lc}}. function({function,Name,Arity,CLabel,Is0}, Lc0) -> @@ -160,64 +159,6 @@ function({function,Name,Arity,CLabel,Is0}, Lc0) -> erlang:raise(Class, Error, Stack) end. -%% We must split the basic block when we encounter instructions with labels, -%% such as catches and BIFs. All labels must be visible outside the blocks. - -split_blocks({function,Name,Arity,CLabel,Is0}) -> - Is = split_blocks(Is0, []), - {function,Name,Arity,CLabel,Is}. - -split_blocks([{block,Bl}|Is], Acc0) -> - Acc = split_block(Bl, [], Acc0), - split_blocks(Is, Acc); -split_blocks([I|Is], Acc) -> - split_blocks(Is, [I|Acc]); -split_blocks([], Acc) -> reverse(Acc). - -split_block([{set,[R],[_,_,_]=As,{bif,is_record,{f,Lbl}}}|Is], Bl, Acc) -> - %% is_record/3 must be translated by beam_clean; therefore, - %% it must be outside of any block. - split_block(Is, [], [{bif,is_record,{f,Lbl},As,R}|make_block(Bl, Acc)]); -split_block([{set,[R],As,{bif,N,{f,Lbl}=Fail}}|Is], Bl, Acc) when Lbl =/= 0 -> - split_block(Is, [], [{bif,N,Fail,As,R}|make_block(Bl, Acc)]); -split_block([{set,[R],As,{alloc,Live,{gc_bif,N,{f,Lbl}=Fail}}}|Is], Bl, Acc) - when Lbl =/= 0 -> - split_block(Is, [], [{gc_bif,N,Fail,Live,As,R}|make_block(Bl, Acc)]); -split_block([{set,[R],[],{'catch',L}}|Is], Bl, Acc) -> - split_block(Is, [], [{'catch',R,L}|make_block(Bl, Acc)]); -split_block([{set,[],[],{line,_}=Line}|Is], Bl, Acc) -> - split_block(Is, [], [Line|make_block(Bl, Acc)]); -split_block([I|Is], Bl, Acc) -> - split_block(Is, [I|Bl], Acc); -split_block([], Bl, Acc) -> make_block(Bl, Acc). - -make_block([], Acc) -> Acc; -make_block([{set,[D],Ss,{bif,Op,Fail}}|Bl]=Bl0, Acc) -> - %% If the last instruction in the block is a comparison or boolean operator - %% (such as '=:='), move it out of the block to facilitate further - %% optimizations. - Arity = length(Ss), - case erl_internal:comp_op(Op, Arity) orelse - erl_internal:new_type_test(Op, Arity) orelse - erl_internal:bool_op(Op, Arity) of - false -> - [{block,reverse(Bl0)}|Acc]; - true -> - I = {bif,Op,Fail,Ss,D}, - case Bl =:= [] of - true -> [I|Acc]; - false -> [I,{block,reverse(Bl)}|Acc] - end - end; -make_block([{set,[Dst],[Src],move}|Bl], Acc) -> - %% Make optimization of {move,Src,Dst}, {jump,...} possible. - I = {move,Src,Dst}, - case Bl =:= [] of - true -> [I|Acc]; - false -> [I,{block,reverse(Bl)}|Acc] - end; -make_block(Bl, Acc) -> [{block,reverse(Bl)}|Acc]. - %% 'move' instructions outside of blocks may thwart the jump optimizer. %% Move them back into the block. diff --git a/lib/compiler/src/beam_split.erl b/lib/compiler/src/beam_split.erl new file mode 100644 index 0000000000..cacaaebffe --- /dev/null +++ b/lib/compiler/src/beam_split.erl @@ -0,0 +1,85 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2011. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +-module(beam_split). +-export([module/2]). + +-import(lists, [reverse/1]). + +module({Mod,Exp,Attr,Fs0,Lc}, _Opts) -> + Fs = [split_blocks(F) || F <- Fs0], + {ok,{Mod,Exp,Attr,Fs,Lc}}. + +%% We must split the basic block when we encounter instructions with labels, +%% such as catches and BIFs. All labels must be visible outside the blocks. + +split_blocks({function,Name,Arity,CLabel,Is0}) -> + Is = split_blocks(Is0, []), + {function,Name,Arity,CLabel,Is}. + +split_blocks([{block,Bl}|Is], Acc0) -> + Acc = split_block(Bl, [], Acc0), + split_blocks(Is, Acc); +split_blocks([I|Is], Acc) -> + split_blocks(Is, [I|Acc]); +split_blocks([], Acc) -> reverse(Acc). + +split_block([{set,[R],[_,_,_]=As,{bif,is_record,{f,Lbl}}}|Is], Bl, Acc) -> + %% is_record/3 must be translated by beam_clean; therefore, + %% it must be outside of any block. + split_block(Is, [], [{bif,is_record,{f,Lbl},As,R}|make_block(Bl, Acc)]); +split_block([{set,[R],As,{bif,N,{f,Lbl}=Fail}}|Is], Bl, Acc) when Lbl =/= 0 -> + split_block(Is, [], [{bif,N,Fail,As,R}|make_block(Bl, Acc)]); +split_block([{set,[R],As,{alloc,Live,{gc_bif,N,{f,Lbl}=Fail}}}|Is], Bl, Acc) + when Lbl =/= 0 -> + split_block(Is, [], [{gc_bif,N,Fail,Live,As,R}|make_block(Bl, Acc)]); +split_block([{set,[R],[],{'catch',L}}|Is], Bl, Acc) -> + split_block(Is, [], [{'catch',R,L}|make_block(Bl, Acc)]); +split_block([{set,[],[],{line,_}=Line}|Is], Bl, Acc) -> + split_block(Is, [], [Line|make_block(Bl, Acc)]); +split_block([I|Is], Bl, Acc) -> + split_block(Is, [I|Bl], Acc); +split_block([], Bl, Acc) -> make_block(Bl, Acc). + +make_block([], Acc) -> Acc; +make_block([{set,[D],Ss,{bif,Op,Fail}}|Bl]=Bl0, Acc) -> + %% If the last instruction in the block is a comparison or boolean operator + %% (such as '=:='), move it out of the block to facilitate further + %% optimizations. + Arity = length(Ss), + case erl_internal:comp_op(Op, Arity) orelse + erl_internal:new_type_test(Op, Arity) orelse + erl_internal:bool_op(Op, Arity) of + false -> + [{block,reverse(Bl0)}|Acc]; + true -> + I = {bif,Op,Fail,Ss,D}, + case Bl =:= [] of + true -> [I|Acc]; + false -> [I,{block,reverse(Bl)}|Acc] + end + end; +make_block([{set,[Dst],[Src],move}|Bl], Acc) -> + %% Make optimization of {move,Src,Dst}, {jump,...} possible. + I = {move,Src,Dst}, + case Bl =:= [] of + true -> [I|Acc]; + false -> [I,{block,reverse(Bl)}|Acc] + end; +make_block(Bl, Acc) -> [{block,reverse(Bl)}|Acc]. diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl index fe3b1680d9..95f12df40d 100644 --- a/lib/compiler/src/beam_validator.erl +++ b/lib/compiler/src/beam_validator.erl @@ -670,10 +670,20 @@ valfun_4({get_tuple_element,Src,I,Dst}, Vst) -> valfun_4({test,bs_start_match2,{f,Fail},Live,[Ctx,NeedSlots],Ctx}, Vst0) -> %% If source and destination registers are the same, match state %% is OK as input. - _ = get_move_term_type(Ctx, Vst0), + CtxType = get_move_term_type(Ctx, Vst0), verify_live(Live, Vst0), Vst1 = prune_x_regs(Live, Vst0), - Vst = branch_state(Fail, Vst1), + BranchVst = case CtxType of + {match_context,_,_} -> + %% The failure branch will never be taken when Ctx + %% is a match context. Therefore, the type for Ctx + %% at the failure label must not be match_context + %% (or we could reject legal code). + set_type_reg(term, Ctx, Vst1); + _ -> + Vst1 + end, + Vst = branch_state(Fail, BranchVst), set_type_reg(bsm_match_state(NeedSlots), Ctx, Vst); valfun_4({test,bs_start_match2,{f,Fail},Live,[Src,Slots],Dst}, Vst0) -> assert_term(Src, Vst0), diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl index bfa7c6cedd..a17a10046e 100644 --- a/lib/compiler/src/compile.erl +++ b/lib/compiler/src/compile.erl @@ -175,6 +175,8 @@ expand_opt(r12, Os) -> [no_recv_opt,no_line_info|Os]; expand_opt(r13, Os) -> [no_recv_opt,no_line_info|Os]; +expand_opt(r14, Os) -> + [no_line_info|Os]; expand_opt({debug_info_key,_}=O, Os) -> [encrypt_debug_info,O|Os]; expand_opt(no_float_opt, Os) -> @@ -235,7 +237,8 @@ format_error({module_name,Mod,Filename}) -> code=[], core_code=[], abstract_code=[], %Abstract code for debugger. - options=[] :: [option()], + options=[] :: [option()], %Options for compilation + mod_options=[] :: [option()], %Options for module_info errors=[], warnings=[]}). @@ -246,10 +249,11 @@ internal(Master, Input, Opts) -> internal({forms,Forms}, Opts) -> {_,Ps} = passes(forms, Opts), - internal_comp(Ps, "", "", #compile{code=Forms,options=Opts}); + internal_comp(Ps, "", "", #compile{code=Forms,options=Opts, + mod_options=Opts}); internal({file,File}, Opts) -> {Ext,Ps} = passes(file, Opts), - Compile = #compile{options=Opts}, + Compile = #compile{options=Opts,mod_options=Opts}, internal_comp(Ps, File, Ext, Compile). internal_comp(Passes, File, Suffix, St0) -> @@ -629,7 +633,9 @@ asm_passes() -> {iff,dbool,{listing,"bool"}}, {unless,no_topt,{pass,beam_type}}, {iff,dtype,{listing,"type"}}, - {pass,beam_dead}, %Must always run since it splits blocks. + {pass,beam_split}, + {iff,dsplit,{listing,"split"}}, + {unless,no_dead,{pass,beam_dead}}, {iff,ddead,{listing,"dead"}}, {unless,no_jopt,{pass,beam_jump}}, {iff,djmp,{listing,"jump"}}, @@ -1228,12 +1234,13 @@ beam_unused_labels(#compile{code=Code0}=St) -> Code = beam_jump:module_labels(Code0), {ok,St#compile{code=Code}}. -beam_asm(#compile{ifile=File,code=Code0,abstract_code=Abst,options=Opts0}=St) -> +beam_asm(#compile{ifile=File,code=Code0, + abstract_code=Abst,mod_options=Opts0}=St) -> Source = filename:absname(File), Opts1 = lists:map(fun({debug_info_key,_}) -> {debug_info_key,'********'}; (Other) -> Other end, Opts0), - Opts2 = [O || O <- Opts1, is_informative_option(O)], + Opts2 = [O || O <- Opts1, effects_code_generation(O)], case beam_asm:module(Code0, Abst, Source, Opts2) of {ok,Code} -> {ok,St#compile{code=Code,abstract_code=[]}} end. @@ -1303,15 +1310,23 @@ embed_native_code(St, {Architecture,NativeCode}) -> {ok, BeamPlusNative} = beam_lib:build_module(Chunks), St#compile{code=BeamPlusNative}. -%% Returns true if the option is informative and therefore should be included -%% in the option list of the compiled module. - -is_informative_option(beam) -> false; -is_informative_option(report_warnings) -> false; -is_informative_option(report_errors) -> false; -is_informative_option(binary) -> false; -is_informative_option(verbose) -> false; -is_informative_option(_) -> true. +%% effects_code_generation(Option) -> true|false. +%% Determine whether the option could have any effect on the +%% generated code in the BEAM file (as opposed to how +%% errors will be reported). + +effects_code_generation(Option) -> + case Option of + beam -> false; + report_warnings -> false; + report_errors -> false; + return_errors-> false; + return_warnings-> false; + binary -> false; + verbose -> false; + {cwd,_} -> false; + _ -> true + end. save_binary(#compile{code=none}=St) -> {ok,St}; save_binary(#compile{module=Mod,ofile=Outfile, diff --git a/lib/compiler/src/compiler.app.src b/lib/compiler/src/compiler.app.src index 4ac879c9a4..efa25fe039 100644 --- a/lib/compiler/src/compiler.app.src +++ b/lib/compiler/src/compiler.app.src @@ -34,6 +34,7 @@ beam_opcodes, beam_peep, beam_receive, + beam_split, beam_trim, beam_type, beam_utils, diff --git a/lib/compiler/src/erl_bifs.erl b/lib/compiler/src/erl_bifs.erl index 2514c06360..f82a798ceb 100644 --- a/lib/compiler/src/erl_bifs.erl +++ b/lib/compiler/src/erl_bifs.erl @@ -136,6 +136,7 @@ is_pure(math, sinh, 1) -> true; is_pure(math, sqrt, 1) -> true; is_pure(math, tan, 1) -> true; is_pure(math, tanh, 1) -> true; +is_pure(math, pi, 0) -> true; is_pure(_, _, _) -> false. diff --git a/lib/compiler/src/sys_expand_pmod.erl b/lib/compiler/src/sys_expand_pmod.erl index 4fee26f2a6..4576dfbf12 100644 --- a/lib/compiler/src/sys_expand_pmod.erl +++ b/lib/compiler/src/sys_expand_pmod.erl @@ -317,6 +317,8 @@ expr({'try',Line,Es0,Scs0,Ccs0,As0},St) -> Ccs1 = icr_clauses(Ccs0,St), As1 = exprs(As0,St), {'try',Line,Es1,Scs1,Ccs1,As1}; +expr({'fun',_,{function,_,_,_}}=ExtFun,_St) -> + ExtFun; expr({'fun',Line,Body,Info},St) -> case Body of {clauses,Cs0} -> diff --git a/lib/compiler/test/compile_SUITE.erl b/lib/compiler/test/compile_SUITE.erl index 8c6a623dfb..fedbd98f71 100644 --- a/lib/compiler/test/compile_SUITE.erl +++ b/lib/compiler/test/compile_SUITE.erl @@ -77,12 +77,22 @@ file_1(Config) when is_list(Config) -> ?line {Simple, Target} = files(Config, "file_1"), ?line {ok, Cwd} = file:get_cwd(), ?line ok = file:set_cwd(filename:dirname(Target)), - ?line {ok,simple} = compile:file(Simple), %Smoke test only. + + %% Native from BEAM without compilation info. ?line {ok,simple} = compile:file(Simple, [slim]), %Smoke test only. - ?line {ok,simple} = compile:file(Simple, [native,report]), %Smoke test. ?line {ok,simple} = compile:file(Target, [native,from_beam]), %Smoke test. - ?line {ok,simple} = compile:file(Simple, [debug_info]), + + %% Native from BEAM with compilation info. + ?line {ok,simple} = compile:file(Simple), %Smoke test only. + ?line {ok,simple} = compile:file(Target, [native,from_beam]), %Smoke test. + + ?line {ok,simple} = compile:file(Simple, [native,report]), %Smoke test. + + ?line compile_and_verify(Simple, Target, []), + ?line compile_and_verify(Simple, Target, [native]), + ?line compile_and_verify(Simple, Target, [debug_info]), ?line {ok,simple} = compile:file(Simple, [no_line_info]), %Coverage + ?line ok = file:set_cwd(Cwd), ?line true = exists(Target), ?line passed = run(Target, test, []), @@ -113,10 +123,9 @@ big_file(Config) when is_list(Config) -> ?line Big = filename:join(DataDir, "big.erl"), ?line Target = filename:join(PrivDir, "big.beam"), ?line ok = file:set_cwd(PrivDir), - ?line {ok,big} = compile:file(Big, []), - ?line {ok,big} = compile:file(Big, [r9,debug_info]), - ?line {ok,big} = compile:file(Big, [no_postopt]), - ?line true = exists(Target), + ?line compile_and_verify(Big, Target, []), + ?line compile_and_verify(Big, Target, [debug_info]), + ?line compile_and_verify(Big, Target, [no_postopt]), %% Cleanup. ?line ok = file:delete(Target), @@ -775,3 +784,15 @@ do_asm(Beam, Outdir) -> [M,Class,Error,erlang:get_stacktrace()]), error end. + +%%% +%%% Utilities. +%%% + +compile_and_verify(Name, Target, Opts) -> + Mod = list_to_atom(filename:basename(Name, ".erl")), + {ok,Mod} = compile:file(Name, Opts), + {ok,{Mod,[{compile_info,CInfo}]}} = + beam_lib:chunks(Target, [compile_info]), + {options,BeamOpts} = lists:keyfind(options, 1, CInfo), + Opts = BeamOpts. diff --git a/lib/compiler/test/inline_SUITE.erl b/lib/compiler/test/inline_SUITE.erl index 086fba2649..2e17d3fde6 100644 --- a/lib/compiler/test/inline_SUITE.erl +++ b/lib/compiler/test/inline_SUITE.erl @@ -33,7 +33,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> test_lib:recompile(?MODULE), [attribute, bsdecode, bsdes, barnes2, decode1, smith, - itracer, pseudoknot, lists, really_inlined, otp_7223, + itracer, pseudoknot, comma_splitter, lists, really_inlined, otp_7223, coverage]. groups() -> @@ -78,6 +78,7 @@ attribute(Config) when is_list(Config) -> ?comp(smith). ?comp(itracer). ?comp(pseudoknot). +?comp(comma_splitter). try_inline(Mod, Config) -> ?line Src = filename:join(?config(data_dir, Config), atom_to_list(Mod)), diff --git a/lib/compiler/test/inline_SUITE_data/comma_splitter.erl b/lib/compiler/test/inline_SUITE_data/comma_splitter.erl new file mode 100644 index 0000000000..eaa89e0edc --- /dev/null +++ b/lib/compiler/test/inline_SUITE_data/comma_splitter.erl @@ -0,0 +1,18 @@ +-module(comma_splitter). +-export([?MODULE/0]). + +?MODULE() -> + {<<"def">>,<<"cba">>} = split_at_comma(<<"abc, def">>, <<>>), + ok. + +strip_leading_ws(<<N, Rest/binary>>) when N =< $\s -> + strip_leading_ws(Rest); +strip_leading_ws(B) -> + B. + +split_at_comma(<<>>, Accu) -> + {<<>>, Accu}; +split_at_comma(<<$,, Rest/binary>>, Accu) -> + {strip_leading_ws(Rest), Accu}; +split_at_comma(<<C, Rest/binary>>, Accu) -> + split_at_comma(Rest, <<C, Accu/binary>>). diff --git a/lib/compiler/test/pmod_SUITE.erl b/lib/compiler/test/pmod_SUITE.erl index 3d02adaf52..5dd09a7245 100644 --- a/lib/compiler/test/pmod_SUITE.erl +++ b/lib/compiler/test/pmod_SUITE.erl @@ -100,6 +100,7 @@ basic_1(Config, Opts) -> Fun = fun(Arg) -> Prop4:bar(Arg) end, ?line ok = Fun({s,0}), + [{y,[1,2]},{x,[5,19]}] = Prop4:collapse([{y,[2,1]},{x,[19,5]}]), ok. otp_8447(Config) when is_list(Config) -> diff --git a/lib/compiler/test/pmod_SUITE_data/pmod_basic.erl b/lib/compiler/test/pmod_SUITE_data/pmod_basic.erl index 0d46cffe00..c6aa2d4655 100644 --- a/lib/compiler/test/pmod_SUITE_data/pmod_basic.erl +++ b/lib/compiler/test/pmod_SUITE_data/pmod_basic.erl @@ -21,6 +21,7 @@ -export([lookup/1,or_props/1,prepend/1,append/1,stupid_sum/0]). -export([bar/1,bar_bar/1]). -export([bc1/0, bc2/0]). +-export([collapse/1]). lookup(Key) -> proplists:lookup(Key, Props). @@ -77,3 +78,6 @@ bc1() -> bc2() -> << <<A:1>> || A <- [1,0,1,0] >>. + +collapse(L) -> + lists:keymap(fun lists:sort/1, 2, L). diff --git a/lib/configure.in.src b/lib/configure.in.src index 792a7f932a..609bb62308 100644 --- a/lib/configure.in.src +++ b/lib/configure.in.src @@ -17,7 +17,7 @@ dnl dnl %CopyrightEnd% dnl -dnl Turn of caching +dnl Turn off caching define([AC_CACHE_LOAD], )dnl define([AC_CACHE_SAVE], )dnl diff --git a/lib/cosFileTransfer/test/fileTransfer_SUITE.erl b/lib/cosFileTransfer/test/fileTransfer_SUITE.erl index e94c307ef8..79a234bd28 100644 --- a/lib/cosFileTransfer/test/fileTransfer_SUITE.erl +++ b/lib/cosFileTransfer/test/fileTransfer_SUITE.erl @@ -131,10 +131,10 @@ end_per_testcase(_Case, Config) -> ok. init_per_suite(Config) -> - case code:which(crypto) of - Res when is_atom(Res) -> + case crypto_works() of + false -> {skip,"Could not start crypto!"}; - _Else -> + true -> orber:jump_start(), cosProperty:install(), cosProperty:start(), @@ -165,6 +165,15 @@ init_per_suite(Config) -> end end. +crypto_works() -> + try crypto:start() of + {error,{already_started,crypto}} -> true; + ok -> true + catch + error:_ -> + false + end. + end_per_suite(Config) -> ssl:stop(), crypto:stop(), diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c index 802c1991de..4dc62421d2 100644 --- a/lib/crypto/c_src/crypto.c +++ b/lib/crypto/c_src/crypto.c @@ -53,6 +53,17 @@ #include <openssl/evp.h> #include <openssl/hmac.h> +#if OPENSSL_VERSION_NUMBER >= 0x00908000L && !defined(OPENSSL_NO_SHA256) && defined(NID_sha256) +# define HAVE_SHA256 +#endif +#if OPENSSL_VERSION_NUMBER >= 0x00908000L && !defined(OPENSSL_NO_SHA384) && defined(NID_sha384)\ + && !defined(OPENSSL_NO_SHA512) /* disabled like this in my sha.h (?) */ +# define HAVE_SHA384 +#endif +#if OPENSSL_VERSION_NUMBER >= 0x00908000L && !defined(OPENSSL_NO_SHA512) && defined(NID_sha512) +# define HAVE_SHA512 +#endif + #ifdef VALGRIND # include <valgrind/memcheck.h> @@ -124,6 +135,14 @@ static ERL_NIF_TERM sha(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM sha_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM sha_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM sha_final(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM sha256_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM sha256_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM sha256_update_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM sha256_final_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM sha512_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM sha512_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM sha512_update_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM sha512_final_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM md4(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM md4_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM md4_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); @@ -148,7 +167,7 @@ static ERL_NIF_TERM strong_rand_mpint_nif(ErlNifEnv* env, int argc, const ERL_NI static ERL_NIF_TERM rand_uniform_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM mod_exp_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM dss_verify(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); -static ERL_NIF_TERM rsa_verify(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM rsa_verify_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM aes_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM exor(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM rc4_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); @@ -201,6 +220,14 @@ static ErlNifFunc nif_funcs[] = { {"sha_init", 0, sha_init}, {"sha_update", 2, sha_update}, {"sha_final", 1, sha_final}, + {"sha256_nif", 1, sha256_nif}, + {"sha256_init_nif", 0, sha256_init_nif}, + {"sha256_update_nif", 2, sha256_update_nif}, + {"sha256_final_nif", 1, sha256_final_nif}, + {"sha512_nif", 1, sha512_nif}, + {"sha512_init_nif", 0, sha512_init_nif}, + {"sha512_update_nif", 2, sha512_update_nif}, + {"sha512_final_nif", 1, sha512_final_nif}, {"md4", 1, md4}, {"md4_init", 0, md4_init}, {"md4_update", 2, md4_update}, @@ -228,7 +255,7 @@ static ErlNifFunc nif_funcs[] = { {"rand_uniform_nif", 2, rand_uniform_nif}, {"mod_exp_nif", 3, mod_exp_nif}, {"dss_verify", 4, dss_verify}, - {"rsa_verify", 4, rsa_verify}, + {"rsa_verify_nif", 4, rsa_verify_nif}, {"aes_cbc_crypt", 4, aes_cbc_crypt}, {"exor", 2, exor}, {"rc4_encrypt", 2, rc4_encrypt}, @@ -260,6 +287,9 @@ ERL_NIF_INIT(crypto,nif_funcs,load,reload,upgrade,unload) #define SHA_CTX_LEN (sizeof(SHA_CTX)) #define SHA_LEN 20 #define SHA_LEN_96 12 +#define SHA256_LEN (256/8) +#define SHA384_LEN (384/8) +#define SHA512_LEN (512/8) #define HMAC_INT_LEN 64 #define HMAC_IPAD 0x36 @@ -270,6 +300,9 @@ static ErlNifRWLock** lock_vec = NULL; /* Static locks used by openssl */ static ERL_NIF_TERM atom_true; static ERL_NIF_TERM atom_false; static ERL_NIF_TERM atom_sha; +static ERL_NIF_TERM atom_sha256; +static ERL_NIF_TERM atom_sha384; +static ERL_NIF_TERM atom_sha512; static ERL_NIF_TERM atom_md5; static ERL_NIF_TERM atom_ripemd160; static ERL_NIF_TERM atom_error; @@ -286,6 +319,7 @@ static ERL_NIF_TERM atom_not_suitable_generator; static ERL_NIF_TERM atom_check_failed; static ERL_NIF_TERM atom_unknown; static ERL_NIF_TERM atom_none; +static ERL_NIF_TERM atom_notsup; static int is_ok_load_info(ErlNifEnv* env, ERL_NIF_TERM load_info) @@ -340,6 +374,9 @@ static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) atom_true = enif_make_atom(env,"true"); atom_false = enif_make_atom(env,"false"); atom_sha = enif_make_atom(env,"sha"); + atom_sha256 = enif_make_atom(env,"sha256"); + atom_sha384 = enif_make_atom(env,"sha384"); + atom_sha512 = enif_make_atom(env,"sha512"); atom_md5 = enif_make_atom(env,"md5"); atom_ripemd160 = enif_make_atom(env,"ripemd160"); atom_error = enif_make_atom(env,"error"); @@ -355,6 +392,7 @@ static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) atom_check_failed = enif_make_atom(env,"check_failed"); atom_unknown = enif_make_atom(env,"unknown"); atom_none = enif_make_atom(env,"none"); + atom_notsup = enif_make_atom(env,"notsup"); *priv_data = NULL; library_refc++; @@ -519,6 +557,129 @@ static ERL_NIF_TERM sha_final(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[ return ret; } +static ERL_NIF_TERM sha256_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Data) */ +#ifdef HAVE_SHA256 + ErlNifBinary ibin; + ERL_NIF_TERM ret; + + if (!enif_inspect_iolist_as_binary(env, argv[0], &ibin)) { + return enif_make_badarg(env); + } + SHA256((unsigned char *) ibin.data, ibin.size, + enif_make_new_binary(env,SHA256_LEN, &ret)); + return ret; +#else + return atom_notsup; +#endif +} +static ERL_NIF_TERM sha256_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* () */ +#ifdef HAVE_SHA256 + ERL_NIF_TERM ret; + SHA256_Init((SHA256_CTX *) enif_make_new_binary(env, sizeof(SHA256_CTX), &ret)); + return ret; +#else + return atom_notsup; +#endif +} +static ERL_NIF_TERM sha256_update_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Context, Data) */ +#ifdef HAVE_SHA256 + SHA256_CTX* new_ctx; + ErlNifBinary ctx_bin, data_bin; + ERL_NIF_TERM ret; + if (!enif_inspect_binary(env, argv[0], &ctx_bin) || ctx_bin.size != sizeof(SHA256_CTX) + || !enif_inspect_iolist_as_binary(env, argv[1], &data_bin)) { + return enif_make_badarg(env); + } + new_ctx = (SHA256_CTX*) enif_make_new_binary(env,sizeof(SHA256_CTX), &ret); + memcpy(new_ctx, ctx_bin.data, sizeof(SHA256_CTX)); + SHA256_Update(new_ctx, data_bin.data, data_bin.size); + return ret; +#else + return atom_notsup; +#endif +} +static ERL_NIF_TERM sha256_final_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Context) */ +#ifdef HAVE_SHA256 + ErlNifBinary ctx_bin; + SHA256_CTX ctx_clone; + ERL_NIF_TERM ret; + if (!enif_inspect_binary(env, argv[0], &ctx_bin) || ctx_bin.size != sizeof(SHA256_CTX)) { + return enif_make_badarg(env); + } + memcpy(&ctx_clone, ctx_bin.data, sizeof(SHA256_CTX)); /* writable */ + SHA256_Final(enif_make_new_binary(env, SHA256_LEN, &ret), &ctx_clone); + return ret; +#else + return atom_notsup; +#endif +} + +static ERL_NIF_TERM sha512_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Data) */ +#ifdef HAVE_SHA512 + ErlNifBinary ibin; + ERL_NIF_TERM ret; + + if (!enif_inspect_iolist_as_binary(env, argv[0], &ibin)) { + return enif_make_badarg(env); + } + SHA512((unsigned char *) ibin.data, ibin.size, + enif_make_new_binary(env,SHA512_LEN, &ret)); + return ret; +#else + return atom_notsup; +#endif +} +static ERL_NIF_TERM sha512_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* () */ +#ifdef HAVE_SHA512 + ERL_NIF_TERM ret; + SHA512_Init((SHA512_CTX *) enif_make_new_binary(env, sizeof(SHA512_CTX), &ret)); + return ret; +#else + return atom_notsup; +#endif +} +static ERL_NIF_TERM sha512_update_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Context, Data) */ +#ifdef HAVE_SHA512 + SHA512_CTX* new_ctx; + ErlNifBinary ctx_bin, data_bin; + ERL_NIF_TERM ret; + if (!enif_inspect_binary(env, argv[0], &ctx_bin) || ctx_bin.size != sizeof(SHA512_CTX) + || !enif_inspect_iolist_as_binary(env, argv[1], &data_bin)) { + return enif_make_badarg(env); + } + new_ctx = (SHA512_CTX*) enif_make_new_binary(env,sizeof(SHA512_CTX), &ret); + memcpy(new_ctx, ctx_bin.data, sizeof(SHA512_CTX)); + SHA512_Update(new_ctx, data_bin.data, data_bin.size); + return ret; +#else + return atom_notsup; +#endif +} +static ERL_NIF_TERM sha512_final_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Context) */ +#ifdef HAVE_SHA512 + ErlNifBinary ctx_bin; + SHA512_CTX ctx_clone; + ERL_NIF_TERM ret; + if (!enif_inspect_binary(env, argv[0], &ctx_bin) || ctx_bin.size != sizeof(SHA512_CTX)) { + return enif_make_badarg(env); + } + memcpy(&ctx_clone, ctx_bin.data, sizeof(SHA512_CTX)); /* writable */ + SHA512_Final(enif_make_new_binary(env, SHA512_LEN, &ret), &ctx_clone); + return ret; +#else + return atom_notsup; +#endif +} + + static ERL_NIF_TERM md4(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {/* (Data) */ ErlNifBinary ibin; @@ -1095,17 +1256,14 @@ static ERL_NIF_TERM dss_verify(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv return(i > 0) ? atom_true : atom_false; } -static ERL_NIF_TERM rsa_verify(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +static ERL_NIF_TERM rsa_verify_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {/* (Type, Data, Signature, Key=[E,N]) */ ErlNifBinary data_bin, sign_bin; - unsigned char hmacbuf[SHA_DIGEST_LENGTH]; + unsigned char hmacbuf[SHA512_LEN]; ERL_NIF_TERM head, tail, ret; - int i, is_sha; + int i; RSA* rsa = RSA_new(); - - if (argv[0] == atom_sha) is_sha = 1; - else if (argv[0] == atom_md5) is_sha = 0; - else goto badarg; + const ERL_NIF_TERM type = argv[0]; if (!inspect_mpint(env, argv[1], &data_bin) || !inspect_mpint(env, argv[2], &sign_bin) @@ -1114,22 +1272,57 @@ static ERL_NIF_TERM rsa_verify(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv || !enif_get_list_cell(env, tail, &head, &tail) || !get_bn_from_mpint(env, head, &rsa->n) || !enif_is_empty_list(env, tail)) { - badarg: + ret = enif_make_badarg(env); } else { - if (is_sha) { + if (type == atom_sha) { SHA1(data_bin.data+4, data_bin.size-4, hmacbuf); i = RSA_verify(NID_sha1, hmacbuf, SHA_DIGEST_LENGTH, sign_bin.data+4, sign_bin.size-4, rsa); } - else { + else if (type == atom_sha256) { + #ifdef HAVE_SHA256 + SHA256(data_bin.data+4, data_bin.size-4, hmacbuf); + i = RSA_verify(NID_sha256, hmacbuf, SHA256_LEN, + sign_bin.data+4, sign_bin.size-4, rsa); + #else + ret = atom_notsup; + goto done; + #endif + } + else if (type == atom_sha384) { + #ifdef HAVE_SHA384 + SHA384(data_bin.data+4, data_bin.size-4, hmacbuf); + i = RSA_verify(NID_sha384, hmacbuf, SHA384_LEN, + sign_bin.data+4, sign_bin.size-4, rsa); + #else + ret = atom_notsup; + goto done; + #endif + } + else if (type == atom_sha512) { + #ifdef HAVE_SHA512 + SHA512(data_bin.data+4, data_bin.size-4, hmacbuf); + i = RSA_verify(NID_sha512, hmacbuf, SHA512_LEN, + sign_bin.data+4, sign_bin.size-4, rsa); + #else + ret = atom_notsup; + goto done; + #endif + } + else if (type == atom_md5) { MD5(data_bin.data+4, data_bin.size-4, hmacbuf); i = RSA_verify(NID_md5, hmacbuf, MD5_DIGEST_LENGTH, sign_bin.data+4, sign_bin.size-4, rsa); } + else { + ret = enif_make_badarg(env); + goto done; + } ret = (i==1 ? atom_true : atom_false); - } + } +done: RSA_free(rsa); return ret; } diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml index 48243fd693..8cb893cd1c 100644 --- a/lib/crypto/doc/src/crypto.xml +++ b/lib/crypto/doc/src/crypto.xml @@ -896,7 +896,7 @@ Mpint() = <![CDATA[<<ByteLen:32/integer-big, Bytes:ByteLen/binary>>]]> <v>Key = [E, N]</v> <v>E, N = Mpint</v> <d>Where <c>E</c> is the public exponent and <c>N</c> is public modulus.</d> - <v>DigestType = md5 | sha</v> + <v>DigestType = md5 | sha | sha256 | sha384 | sha512</v> <d> The default <c>DigestType</c> is sha.</d> <v>Mpint = binary()</v> </type> @@ -905,6 +905,8 @@ Mpint() = <![CDATA[<<ByteLen:32/integer-big, Bytes:ByteLen/binary>>]]> and verifies that the digest matches the RSA signature using the signer's public key <c>Key</c>. </p> + <p>May throw exception <c>notsup</c> in case the chosen <c>DigestType</c> + is not supported by the underlying OpenSSL implementation.</p> </desc> </func> diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 0714cb686d..d7aac27825 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -25,8 +25,8 @@ -export([md4/1, md4_init/0, md4_update/2, md4_final/1]). -export([md5/1, md5_init/0, md5_update/2, md5_final/1]). -export([sha/1, sha_init/0, sha_update/2, sha_final/1]). -%-export([sha256/1, sha256_init/0, sha256_update/2, sha256_final/1]). -%-export([sha512/1, sha512_init/0, sha512_update/2, sha512_final/1]). +-export([sha256/1, sha256_init/0, sha256_update/2, sha256_final/1]). +-export([sha512/1, sha512_init/0, sha512_update/2, sha512_final/1]). -export([md5_mac/2, md5_mac_96/2, sha_mac/2, sha_mac/3, sha_mac_96/2]). -export([hmac_init/2, hmac_update/2, hmac_final/1, hmac_final_n/2]). -export([des_cbc_encrypt/3, des_cbc_decrypt/3, des_cbc_ivec/1]). @@ -64,8 +64,8 @@ -define(FUNC_LIST, [md4, md4_init, md4_update, md4_final, md5, md5_init, md5_update, md5_final, sha, sha_init, sha_update, sha_final, -%% sha256, sha256_init, sha256_update, sha256_final, -%% sha512, sha512_init, sha512_update, sha512_final, + sha256, sha256_init, sha256_update, sha256_final, + sha512, sha512_init, sha512_update, sha512_final, md5_mac, md5_mac_96, sha_mac, sha_mac_96, sha_mac_init, sha_mac_update, sha_mac_final, @@ -95,7 +95,7 @@ aes_ctr_stream_init, aes_ctr_stream_encrypt, aes_ctr_stream_decrypt, info_lib]). --type rsa_digest_type() :: 'md5' | 'sha'. +-type rsa_digest_type() :: 'md5' | 'sha' | 'sha256' | 'sha384' | 'sha512'. -type dss_digest_type() :: 'none' | 'sha'. -type crypto_integer() :: binary() | integer(). @@ -219,6 +219,73 @@ sha_init() -> ?nif_stub. sha_update(_Context, _Data) -> ?nif_stub. sha_final(_Context) -> ?nif_stub. +% +%% SHA256 +%% +-spec sha256(iodata()) -> binary(). +-spec sha256_init() -> binary(). +-spec sha256_update(binary(), iodata()) -> binary(). +-spec sha256_final(binary()) -> binary(). + +sha256(Data) -> + case sha256_nif(Data) of + notsup -> erlang:error(notsup); + Bin -> Bin + end. +sha256_init() -> + case sha256_init_nif() of + notsup -> erlang:error(notsup); + Bin -> Bin + end. +sha256_update(Context, Data) -> + case sha256_update_nif(Context, Data) of + notsup -> erlang:error(notsup); + Bin -> Bin + end. +sha256_final(Context) -> + case sha256_final_nif(Context) of + notsup -> erlang:error(notsup); + Bin -> Bin + end. + +sha256_nif(_Data) -> ?nif_stub. +sha256_init_nif() -> ?nif_stub. +sha256_update_nif(_Context, _Data) -> ?nif_stub. +sha256_final_nif(_Context) -> ?nif_stub. + +% +%% SHA512 +%% +-spec sha512(iodata()) -> binary(). +-spec sha512_init() -> binary(). +-spec sha512_update(binary(), iodata()) -> binary(). +-spec sha512_final(binary()) -> binary(). + +sha512(Data) -> + case sha512_nif(Data) of + notsup -> erlang:error(notsup); + Bin -> Bin + end. +sha512_init() -> + case sha512_init_nif() of + notsup -> erlang:error(notsup); + Bin -> Bin + end. +sha512_update(Context, Data) -> + case sha512_update_nif(Context, Data) of + notsup -> erlang:error(notsup); + Bin -> Bin + end. +sha512_final(Context) -> + case sha512_final_nif(Context) of + notsup -> erlang:error(notsup); + Bin -> Bin + end. + +sha512_nif(_Data) -> ?nif_stub. +sha512_init_nif() -> ?nif_stub. +sha512_update_nif(_Context, _Data) -> ?nif_stub. +sha512_final_nif(_Context) -> ?nif_stub. %% %% MESSAGE AUTHENTICATION CODES @@ -522,8 +589,14 @@ dss_verify(_Type,_Data,_Signature,_Key) -> ?nif_stub. % Key = [E,N] E=PublicExponent N=PublicModulus rsa_verify(Data,Signature,Key) -> - rsa_verify(sha, Data,Signature,Key). -rsa_verify(_Type,_Data,_Signature,_Key) -> ?nif_stub. + rsa_verify_nif(sha, Data,Signature,Key). +rsa_verify(Type, Data, Signature, Key) -> + case rsa_verify_nif(Type, Data, Signature, Key) of + notsup -> erlang:error(notsup); + Bool -> Bool + end. + +rsa_verify_nif(_Type, _Data, _Signature, _Key) -> ?nif_stub. %% diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl index 86acdc27df..627c966dfb 100644 --- a/lib/crypto/test/crypto_SUITE.erl +++ b/lib/crypto/test/crypto_SUITE.erl @@ -68,30 +68,29 @@ rc4_test/1, rc4_stream_test/1, blowfish_cfb64/1, - smp/1, - cleanup/1]). + smp/1]). -export([hexstr2bin/1]). suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> - [link_test, md5, md5_update, md4, md4_update, md5_mac, - md5_mac_io, sha, sha_update, - hmac_update_sha, hmac_update_sha_n, hmac_update_md5_n, hmac_update_md5_io, hmac_update_md5, - %% sha256, sha256_update, sha512,sha512_update, - des_cbc, des_cfb, des3_cbc, des3_cfb, rc2_cbc, aes_cfb, aes_cbc, - aes_cbc_iter, aes_ctr, aes_ctr_stream, des_cbc_iter, des_cfb_iter, des_ecb, - des_cbc, rc2_cbc, aes_cfb, aes_cbc, - aes_cbc_iter, aes_ctr, aes_ctr_stream, des_cbc_iter, des_ecb, - rand_uniform_test, strong_rand_test, - rsa_verify_test, dsa_verify_test, rsa_sign_test, - dsa_sign_test, rsa_encrypt_decrypt, dh, exor_test, - rc4_test, rc4_stream_test, mod_exp_test, blowfish_cfb64, - smp]. - -groups() -> - []. + [link_test, {group, info}]. + +groups() -> + [{info, [sequence],[info, {group, rest}]}, + {rest, [], + [md5, md5_update, md4, md4_update, md5_mac, + md5_mac_io, sha, sha_update, + hmac_update_sha, hmac_update_sha_n, hmac_update_md5_n, + hmac_update_md5_io, hmac_update_md5, + des_cbc, aes_cfb, aes_cbc, + aes_cbc_iter, aes_ctr, aes_ctr_stream, des_cbc_iter, des_ecb, + rand_uniform_test, strong_rand_test, + rsa_verify_test, dsa_verify_test, rsa_sign_test, + dsa_sign_test, rsa_encrypt_decrypt, dh, exor_test, + rc4_test, rc4_stream_test, mod_exp_test, blowfish_cfb64, + smp]}]. init_per_suite(Config) -> Config. @@ -105,11 +104,15 @@ init_per_group(_GroupName, Config) -> end_per_group(_GroupName, Config) -> Config. +init_per_testcase(info, Config) -> + Config; init_per_testcase(_Name,Config) -> io:format("init_per_testcase\n"), ?line crypto:start(), Config. +end_per_testcase(info, Config) -> + Config; end_per_testcase(_Name,Config) -> io:format("end_per_testcase\n"), ?line crypto:stop(), @@ -197,13 +200,6 @@ info(Config) when is_list(Config) -> ?line crypto:stop() end. -cleanup(doc) -> - ["Cleanup (dummy)."]; -cleanup(suite) -> - []; -cleanup(Config) when is_list(Config) -> - Config. - %% %% md5(doc) -> diff --git a/lib/dialyzer/src/dialyzer.erl b/lib/dialyzer/src/dialyzer.erl index 5014a4244c..3e3c12405f 100644 --- a/lib/dialyzer/src/dialyzer.erl +++ b/lib/dialyzer/src/dialyzer.erl @@ -442,23 +442,29 @@ message_to_string({opaque_type_test, [Fun, Opaque]}) -> message_to_string({race_condition, [M, F, Args, Reason]}) -> io_lib:format("The call ~w:~w~s ~s\n", [M, F, Args, Reason]); %%----- Warnings for behaviour errors -------------------- -message_to_string({callback_type_mismatch, [B, F, A, O]}) -> - io_lib:format("The inferred return type of the ~w/~w callback includes the" - " type ~s which is not a valid return for the ~w behaviour\n", - [F, A, erl_types:t_to_string(O), B]); -message_to_string({callback_arg_type_mismatch, [B, F, A, N, O]}) -> - io_lib:format("The inferred type of the ~s argument of ~w/~w callback" - " includes the type ~s which is not valid for the ~w behaviour" - "\n", [ordinal(N), F, A, erl_types:t_to_string(O), B]); +message_to_string({callback_type_mismatch, [B, F, A, ST, CT]}) -> + io_lib:format("The inferred return type of ~w/~w (~s) has nothing in common" + " with ~s, which is the expected return type for the callback of" + " ~w behaviour\n", [F, A, ST, CT, B]); +message_to_string({callback_arg_type_mismatch, [B, F, A, N, ST, CT]}) -> + io_lib:format("The inferred type for the ~s argument of ~w/~w (~s) is" + " not a supertype of ~s, which is expected type for this" + " argument in the callback of the ~w behaviour\n", + [ordinal(N), F, A, ST, CT, B]); +message_to_string({callback_spec_type_mismatch, [B, F, A, ST, CT]}) -> + io_lib:format("The return type ~s in the specification of ~w/~w is not a" + " subtype of ~s, which is the expected return type for the" + " callback of ~w behaviour\n", [ST, F, A, CT, B]); +message_to_string({callback_spec_arg_type_mismatch, [B, F, A, N, ST, CT]}) -> + io_lib:format("The specified type for the ~s argument of ~w/~w (~s) is" + " not a supertype of ~s, which is expected type for this" + " argument in the callback of the ~w behaviour\n", + [ordinal(N), F, A, ST, CT, B]); message_to_string({callback_missing, [B, F, A]}) -> io_lib:format("Undefined callback function ~w/~w (behaviour '~w')\n", [F, A, B]); -message_to_string({invalid_spec, [B, F, A, R]}) -> - io_lib:format("The spec for the ~w:~w/~w callback is not correct: ~s\n", - [B, F, A, R]); -message_to_string({spec_missing, [B, F, A]}) -> - io_lib:format("Type info about ~w:~w/~w callback is not available\n", - [B, F, A]). +message_to_string({callback_info_missing, [B]}) -> + io_lib:format("Callback info about the ~w behaviour is not available\n", [B]). %%----------------------------------------------------------------------------- %% Auxiliary functions below diff --git a/lib/dialyzer/src/dialyzer.hrl b/lib/dialyzer/src/dialyzer.hrl index 9d2e554981..5e089d1773 100644 --- a/lib/dialyzer/src/dialyzer.hrl +++ b/lib/dialyzer/src/dialyzer.hrl @@ -57,6 +57,7 @@ -define(WARN_UNMATCHED_RETURN, warn_umatched_return). -define(WARN_RACE_CONDITION, warn_race_condition). -define(WARN_BEHAVIOUR, warn_behaviour). +-define(WARN_UNDEFINED_CALLBACK, warn_undefined_callbacks). %% %% The following type has double role: @@ -71,7 +72,8 @@ | ?WARN_CONTRACT_NOT_EQUAL | ?WARN_CONTRACT_SUBTYPE | ?WARN_CONTRACT_SUPERTYPE | ?WARN_CALLGRAPH | ?WARN_UNMATCHED_RETURN | ?WARN_RACE_CONDITION - | ?WARN_BEHAVIOUR | ?WARN_CONTRACT_RANGE. + | ?WARN_BEHAVIOUR | ?WARN_CONTRACT_RANGE + | ?WARN_UNDEFINED_CALLBACK. %% %% This is the representation of each warning as they will be returned diff --git a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl index abad1f3a75..62153fa176 100644 --- a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl +++ b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl @@ -43,8 +43,7 @@ parent :: pid(), plt :: dialyzer_plt:plt(), start_from = byte_code :: start_from(), - use_contracts = true :: boolean(), - behaviours = {false,[]} :: {boolean(),[atom()]} + use_contracts = true :: boolean() }). -record(server_state, {parent :: pid(), legal_warnings :: [dial_warn_tag()]}). @@ -57,9 +56,7 @@ start(Parent, LegalWarnings, Analysis) -> RacesOn = ordsets:is_element(?WARN_RACE_CONDITION, LegalWarnings), - BehavOn = ordsets:is_element(?WARN_BEHAVIOUR, LegalWarnings), - Analysis0 = Analysis#analysis{race_detection = RacesOn, - behaviours_chk = BehavOn}, + Analysis0 = Analysis#analysis{race_detection = RacesOn}, Analysis1 = expand_files(Analysis0), Analysis2 = run_analysis(Analysis1), State = #server_state{parent = Parent, legal_warnings = LegalWarnings}, @@ -125,8 +122,7 @@ analysis_start(Parent, Analysis) -> plt = Plt, parent = Parent, start_from = Analysis#analysis.start_from, - use_contracts = Analysis#analysis.use_contracts, - behaviours = {Analysis#analysis.behaviours_chk, []} + use_contracts = Analysis#analysis.use_contracts }, Files = ordsets:from_list(Analysis#analysis.files), {Callgraph, NoWarn, TmpCServer0} = compile_and_store(Files, State), @@ -180,8 +176,8 @@ analysis_start(Parent, Analysis) -> send_analysis_done(Parent, Plt4, State3#analysis_state.doc_plt). analyze_callgraph(Callgraph, State) -> - Plt = State#analysis_state.plt, Codeserver = State#analysis_state.codeserver, + Plt = dialyzer_plt:insert_callbacks(State#analysis_state.plt, Codeserver), Parent = State#analysis_state.parent, case State#analysis_state.analysis_type of plt_build -> @@ -192,13 +188,11 @@ analyze_callgraph(Callgraph, State) -> State#analysis_state{plt = NewPlt}; succ_typings -> NoWarn = State#analysis_state.no_warn_unused, - {BehavioursChk, _Known} = State#analysis_state.behaviours, DocPlt = State#analysis_state.doc_plt, Callgraph1 = dialyzer_callgraph:finalize(Callgraph), {Warnings, NewPlt, NewDocPlt} = dialyzer_succ_typings:get_warnings(Callgraph1, Plt, DocPlt, - Codeserver, NoWarn, Parent, - BehavioursChk), + Codeserver, NoWarn, Parent), dialyzer_callgraph:delete(Callgraph1), send_warnings(State#analysis_state.parent, Warnings), State#analysis_state{plt = NewPlt, doc_plt = NewDocPlt} @@ -213,8 +207,7 @@ compile_and_store(Files, #analysis_state{codeserver = CServer, include_dirs = Dirs, parent = Parent, use_contracts = UseContracts, - start_from = StartFrom, - behaviours = {BehChk, _} + start_from = StartFrom } = State) -> send_log(Parent, "Reading files and computing callgraph... "), {T1, _} = statistics(runtime), @@ -263,37 +256,26 @@ compile_and_store(Files, #analysis_state{codeserver = CServer, {T2, _} = statistics(runtime), Msg1 = io_lib:format("done in ~.2f secs\nRemoving edges... ", [(T2-T1)/1000]), send_log(Parent, Msg1), - {KnownBehaviours, UnknownBehaviours} = - dialyzer_behaviours:get_behaviours(Modules, NewCServer), - if UnknownBehaviours =:= [] -> ok; - true -> send_unknown_behaviours(Parent, UnknownBehaviours) - end, - State1 = State#analysis_state{behaviours = {BehChk, KnownBehaviours}}, - NewCallgraph2 = cleanup_callgraph(State1, NewCServer, NewCallgraph1, Modules), + NewCallgraph2 = cleanup_callgraph(State, NewCServer, NewCallgraph1, Modules), {T3, _} = statistics(runtime), Msg2 = io_lib:format("done in ~.2f secs\n", [(T3-T2)/1000]), send_log(Parent, Msg2), {NewCallgraph2, sets:from_list(NoWarn), NewCServer}. cleanup_callgraph(#analysis_state{plt = InitPlt, parent = Parent, - codeserver = CodeServer, - behaviours = {BehChk, KnownBehaviours} + codeserver = CodeServer }, CServer, Callgraph, Modules) -> ModuleDeps = dialyzer_callgraph:module_deps(Callgraph), send_mod_deps(Parent, ModuleDeps), {Callgraph1, ExtCalls} = dialyzer_callgraph:remove_external(Callgraph), - if BehChk -> - RelevantAPICalls = - dialyzer_behaviours:get_behaviour_apis(KnownBehaviours), - BehaviourAPICalls = [Call || {_From, To} = Call <- ExtCalls, - lists:member(To, RelevantAPICalls)], - Callgraph2 = - dialyzer_callgraph:put_behaviour_api_calls(BehaviourAPICalls, - Callgraph1); - true -> - Callgraph2 = Callgraph1 - end, + RelevantAPICalls = + dialyzer_behaviours:get_behaviour_apis([gen_server]), + BehaviourAPICalls = [Call || {_From, To} = Call <- ExtCalls, + lists:member(To, RelevantAPICalls)], + Callgraph2 = + dialyzer_callgraph:put_behaviour_api_calls(BehaviourAPICalls, + Callgraph1), ExtCalls1 = [Call || Call = {_From, To} <- ExtCalls, not dialyzer_plt:contains_mfa(InitPlt, To)], {BadCalls1, RealExtCalls} = @@ -325,63 +307,42 @@ compile_src(File, Includes, Defines, Callgraph, CServer, UseContracts) -> case dialyzer_utils:get_abstract_code_from_src(File, CompOpts) of {error, _Msg} = Error -> Error; {ok, AbstrCode} -> - case dialyzer_utils:get_core_from_abstract_code(AbstrCode, CompOpts) of - error -> {error, " Could not find abstract code for: " ++ File}; - {ok, Core} -> - Mod = cerl:concrete(cerl:module_name(Core)), - NoWarn = abs_get_nowarn(AbstrCode, Mod), - case dialyzer_utils:get_record_and_type_info(AbstrCode) of - {error, _} = Error -> Error; - {ok, RecInfo} -> - CServer2 = - dialyzer_codeserver:store_temp_records(Mod, RecInfo, CServer), - case UseContracts of - true -> - case dialyzer_utils:get_spec_info(Mod, AbstrCode, RecInfo) of - {error, _} = Error -> Error; - {ok, SpecInfo} -> - CServer3 = - dialyzer_codeserver:store_temp_contracts(Mod, - SpecInfo, - CServer2), - store_core(Mod, Core, NoWarn, Callgraph, CServer3) - end; - false -> - store_core(Mod, Core, NoWarn, Callgraph, CServer2) - end - end - end + compile_common(File, AbstrCode, CompOpts, Callgraph, CServer, UseContracts) end. compile_byte(File, Callgraph, CServer, UseContracts) -> case dialyzer_utils:get_abstract_code_from_beam(File) of error -> {error, " Could not get abstract code for: " ++ File ++ "\n" ++ - " Recompile with +debug_info or analyze starting from source code"}; + " Recompile with +debug_info or analyze starting from source code"}; {ok, AbstrCode} -> - case dialyzer_utils:get_core_from_abstract_code(AbstrCode) of - error -> {error, " Could not get core for: "++File}; - {ok, Core} -> - Mod = cerl:concrete(cerl:module_name(Core)), - NoWarn = abs_get_nowarn(AbstrCode, Mod), - case dialyzer_utils:get_record_and_type_info(AbstrCode) of - {error, _} = Error -> Error; - {ok, RecInfo} -> - CServer1 = - dialyzer_codeserver:store_temp_records(Mod, RecInfo, CServer), - case UseContracts of - true -> - case dialyzer_utils:get_spec_info(Mod, AbstrCode, RecInfo) of - {error, _} = Error -> Error; - {ok, SpecInfo} -> - CServer2 = - dialyzer_codeserver:store_temp_contracts(Mod, SpecInfo, - CServer1), - store_core(Mod, Core, NoWarn, Callgraph, CServer2) - end; - false -> - store_core(Mod, Core, NoWarn, Callgraph, CServer1) - end + compile_common(File, AbstrCode, [], Callgraph, CServer, UseContracts) + end. + +compile_common(File, AbstrCode, CompOpts, Callgraph, CServer, UseContracts) -> + case dialyzer_utils:get_core_from_abstract_code(AbstrCode, CompOpts) of + error -> {error, " Could not get core Erlang code for: " ++ File}; + {ok, Core} -> + Mod = cerl:concrete(cerl:module_name(Core)), + NoWarn = abs_get_nowarn(AbstrCode, Mod), + case dialyzer_utils:get_record_and_type_info(AbstrCode) of + {error, _} = Error -> Error; + {ok, RecInfo} -> + CServer1 = + dialyzer_codeserver:store_temp_records(Mod, RecInfo, CServer), + case UseContracts of + true -> + case dialyzer_utils:get_spec_info(Mod, AbstrCode, RecInfo) of + {error, _} = Error -> Error; + {ok, SpecInfo, CallbackInfo} -> + CServer2 = + dialyzer_codeserver:store_temp_contracts(Mod, SpecInfo, + CallbackInfo, + CServer1), + store_core(Mod, Core, NoWarn, Callgraph, CServer2) + end; + false -> + store_core(Mod, Core, NoWarn, Callgraph, CServer1) end end end. diff --git a/lib/dialyzer/src/dialyzer_behaviours.erl b/lib/dialyzer/src/dialyzer_behaviours.erl index 47ce9ba6eb..900ddf28c5 100644 --- a/lib/dialyzer/src/dialyzer_behaviours.erl +++ b/lib/dialyzer/src/dialyzer_behaviours.erl @@ -30,7 +30,7 @@ -module(dialyzer_behaviours). --export([check_callbacks/4, get_behaviours/2, get_behaviour_apis/1, +-export([check_callbacks/4, get_behaviour_apis/1, translate_behaviour_api_call/5, translatable_behaviours/1, translate_callgraph/3]). @@ -51,12 +51,6 @@ %%-------------------------------------------------------------------- --spec get_behaviours([module()], dialyzer_codeserver:codeserver()) -> - {[behaviour()], [behaviour()]}. - -get_behaviours(Modules, Codeserver) -> - get_behaviours(Modules, Codeserver, [], []). - -spec check_callbacks(module(), [{cerl:cerl(), cerl:cerl()}], dialyzer_plt:plt(), dialyzer_codeserver:codeserver()) -> [dial_warning()]. @@ -69,12 +63,170 @@ check_callbacks(Module, Attrs, Plt, Codeserver) -> MFA = {Module,module_info,0}, {_Var,Code} = dialyzer_codeserver:lookup_mfa_code(MFA, Codeserver), File = get_file(cerl:get_ann(Code)), - State = #state{plt = Plt, codeserver = Codeserver, filename = File, - behlines = BehLines}, + State = #state{plt = Plt, filename = File, behlines = BehLines, + codeserver = Codeserver}, Warnings = get_warnings(Module, Behaviours, State), [add_tag_file_line(Module, W, State) || W <- Warnings] end. +%%-------------------------------------------------------------------- + +get_behaviours(Attrs) -> + BehaviourListsAndLine = [{cerl:concrete(L2), hd(cerl:get_ann(L2))} || + {L1, L2} <- Attrs, cerl:is_literal(L1), + cerl:is_literal(L2), cerl:concrete(L1) =:= 'behaviour'], + Behaviours = lists:append([Behs || {Behs,_} <- BehaviourListsAndLine]), + BehLines = [{B,L} || {L1,L} <- BehaviourListsAndLine, B <- L1], + {Behaviours, BehLines}. + +get_warnings(Module, Behaviours, State) -> + get_warnings(Module, Behaviours, State, []). + +get_warnings(_, [], _, Acc) -> + Acc; +get_warnings(Module, [Behaviour|Rest], State, Acc) -> + NewAcc = check_behaviour(Module, Behaviour, State, Acc), + get_warnings(Module, Rest, State, NewAcc). + +check_behaviour(Module, Behaviour, #state{plt = Plt} = State, Acc) -> + case dialyzer_plt:lookup_callbacks(Plt, Behaviour) of + [] -> [{callback_info_missing, [Behaviour]}|Acc]; + Callbacks -> check_all_callbacks(Module, Behaviour, Callbacks, State, Acc) + end. + +check_all_callbacks(_Module, _Behaviour, [], _State, Acc) -> + Acc; +check_all_callbacks(Module, Behaviour, [Cb|Rest], + #state{plt = Plt, codeserver = Codeserver} = State, Acc) -> + {{Behaviour, Function, Arity}, + {{_BehFile, _BehLine}, Callback}} = Cb, + CbMFA = {Module, Function, Arity}, + CbReturnType = dialyzer_contracts:get_contract_return(Callback), + CbArgTypes = dialyzer_contracts:get_contract_args(Callback), + Records = + case dict:find(Module, dialyzer_codeserver:get_records(Codeserver)) of + {ok, V} -> V; + error -> dict:new() + end, + Acc0 = Acc, + Acc1 = + case dialyzer_plt:lookup(Plt, CbMFA) of + 'none' -> [{callback_missing, [Behaviour, Function, Arity]}|Acc0]; + {'value', RetArgTypes} -> + Acc00 = Acc0, + {ReturnType, ArgTypes} = RetArgTypes, + Acc01 = + case erl_types:t_is_subtype(ReturnType, CbReturnType) of + true -> Acc00; + false -> + case erl_types:t_is_none( + erl_types:t_inf(ReturnType, CbReturnType)) of + false -> Acc00; + true -> + [{callback_type_mismatch, + [Behaviour, Function, Arity, + erl_types:t_to_string(ReturnType, Records), + erl_types:t_to_string(CbReturnType, Records)]}|Acc00] + end + end, + Acc02 = + case erl_types:any_none( + erl_types:t_inf_lists(ArgTypes, CbArgTypes)) of + false -> Acc01; + true -> + find_mismatching_args(type, ArgTypes, CbArgTypes, Behaviour, + Function, Arity, Records, 1, Acc01) + end, + Acc02 + end, + Acc2 = + case dialyzer_codeserver:lookup_mfa_contract(CbMFA, Codeserver) of + 'error' -> Acc1; + {ok, {{File, Line}, Contract}} -> + Acc10 = Acc1, + SpecReturnType0 = dialyzer_contracts:get_contract_return(Contract), + SpecArgTypes0 = dialyzer_contracts:get_contract_args(Contract), + SpecReturnType = erl_types:subst_all_vars_to_any(SpecReturnType0), + SpecArgTypes = + [erl_types:subst_all_vars_to_any(ArgT0) || ArgT0 <- SpecArgTypes0], + Acc11 = + case erl_types:t_is_subtype(SpecReturnType, CbReturnType) of + true -> Acc10; + false -> + ExtraType = erl_types:t_subtract(SpecReturnType, CbReturnType), + [{callback_spec_type_mismatch, + [File, Line, Behaviour, Function, Arity, + erl_types:t_to_string(ExtraType, Records), + erl_types:t_to_string(CbReturnType, Records)]}|Acc10] + end, + Acc12 = + case erl_types:any_none( + erl_types:t_inf_lists(SpecArgTypes, CbArgTypes)) of + false -> Acc11; + true -> + find_mismatching_args({spec, File, Line}, SpecArgTypes, + CbArgTypes, Behaviour, Function, + Arity, Records, 1, Acc11) + end, + Acc12 + end, + NewAcc = Acc2, + check_all_callbacks(Module, Behaviour, Rest, State, NewAcc). + +find_mismatching_args(_, [], [], _Beh, _Function, _Arity, _Records, _N, Acc) -> + Acc; +find_mismatching_args(Kind, [Type|Rest], [CbType|CbRest], Behaviour, + Function, Arity, Records, N, Acc) -> + case erl_types:t_is_none(erl_types:t_inf(Type, CbType)) of + false -> + find_mismatching_args(Kind, Rest, CbRest, Behaviour, Function, + Arity, Records, N+1, Acc); + true -> + Info = + [Behaviour, Function, Arity, N, + erl_types:t_to_string(Type, Records), + erl_types:t_to_string(CbType, Records)], + NewAcc = + [case Kind of + type -> {callback_arg_type_mismatch, Info}; + {spec, File, Line} -> + {callback_spec_arg_type_mismatch, [File, Line | Info]} + end | Acc], + find_mismatching_args(Kind, Rest, CbRest, Behaviour, Function, + Arity, Records, N+1, NewAcc) + end. + +add_tag_file_line(_Module, {Tag, [B|_R]} = Warn, State) + when Tag =:= callback_missing; + Tag =:= callback_info_missing -> + {B, Line} = lists:keyfind(B, 1, State#state.behlines), + Category = + case Tag of + callback_missing -> ?WARN_BEHAVIOUR; + callback_info_missing -> ?WARN_UNDEFINED_CALLBACK + end, + {Category, {State#state.filename, Line}, Warn}; +add_tag_file_line(_Module, {Tag, [File, Line|R]}, _State) + when Tag =:= callback_spec_type_mismatch; + Tag =:= callback_spec_arg_type_mismatch -> + {?WARN_BEHAVIOUR, {File, Line}, {Tag, R}}; +add_tag_file_line(Module, {_Tag, [_B, Fun, Arity|_R]} = Warn, State) -> + {_A, FunCode} = + dialyzer_codeserver:lookup_mfa_code({Module, Fun, Arity}, + State#state.codeserver), + Anns = cerl:get_ann(FunCode), + FileLine = {get_file(Anns), get_line(Anns)}, + {?WARN_BEHAVIOUR, FileLine, Warn}. + +get_line([Line|_]) when is_integer(Line) -> Line; +get_line([_|Tail]) -> get_line(Tail); +get_line([]) -> -1. + +get_file([{file, File}|_]) -> File; +get_file([_|Tail]) -> get_file(Tail). + +%%----------------------------------------------------------------------------- + -spec translatable_behaviours(cerl:c_module()) -> behaviour_api_dict(). translatable_behaviours(Tree) -> @@ -133,182 +285,6 @@ translate_callgraph([{Behaviour,_}|Behaviours], Module, Callgraph) -> translate_callgraph([], _Module, Callgraph) -> Callgraph. -%%-------------------------------------------------------------------- - -get_behaviours(Attrs) -> - BehaviourListsAndLine = [{cerl:concrete(L2), hd(cerl:get_ann(L2))} || - {L1, L2} <- Attrs, cerl:is_literal(L1), - cerl:is_literal(L2), cerl:concrete(L1) =:= 'behaviour'], - Behaviours = lists:append([Behs || {Behs,_} <- BehaviourListsAndLine]), - BehLines = [{B,L} || {L1,L} <- BehaviourListsAndLine, B <- L1], - {Behaviours, BehLines}. - -get_warnings(Module, Behaviours, State) -> - get_warnings(Module, Behaviours, State, []). - -get_warnings(_, [], _, Acc) -> - Acc; -get_warnings(Module, [Behaviour|Rest], State, Acc) -> - Warnings = check_behaviour(Module, Behaviour, State), - get_warnings(Module, Rest, State, Warnings ++ Acc). - -check_behaviour(Module, Behaviour, State) -> - try - Callbacks = Behaviour:behaviour_info(callbacks), - Fun = fun({_,_,_}) -> true; - (_) -> false - end, - case lists:any(Fun, Callbacks) of - true -> check_all_callbacks(Module, Behaviour, Callbacks, State); - false -> [] - end - catch - _:_ -> [] - end. - -check_all_callbacks(Module, Behaviour, Callbacks, State) -> - check_all_callbacks(Module, Behaviour, Callbacks, State, []). - -check_all_callbacks(_Module, _Behaviour, [], _State, Acc) -> - Acc; -check_all_callbacks(Module, Behaviour, [{Fun, Arity, Spec}|Rest], - #state{codeserver = CServer} = State, Acc) -> - Records = dialyzer_codeserver:get_records(CServer), - ExpTypes = dialyzer_codeserver:get_exported_types(CServer), - case parse_spec(Spec, ExpTypes, Records) of - {ok, Fun, Type} -> - RetType = erl_types:t_fun_range(Type), - ArgTypes = erl_types:t_fun_args(Type), - Warns = check_callback(Module, Behaviour, Fun, Arity, RetType, - ArgTypes, State#state.plt); - Else -> - Warns = [{invalid_spec, [Behaviour, Fun, Arity, reason_spec_error(Else)]}] - end, - check_all_callbacks(Module, Behaviour, Rest, State, Warns ++ Acc); -check_all_callbacks(Module, Behaviour, [{Fun, Arity}|Rest], State, Acc) -> - Warns = {spec_missing, [Behaviour, Fun, Arity]}, - check_all_callbacks(Module, Behaviour, Rest, State, [Warns|Acc]). - -parse_spec(String, ExpTypes, Records) -> - case erl_scan:string(String) of - {ok, Tokens, _} -> - case erl_parse:parse(Tokens) of - {ok, Form} -> - case Form of - {attribute, _, 'spec', {{Fun, _}, [TypeForm|_Constraint]}} -> - MaybeRemoteType = erl_types:t_from_form(TypeForm), - try - Type = erl_types:t_solve_remote(MaybeRemoteType, ExpTypes, - Records), - {ok, Fun, Type} - catch - throw:{error,Msg} -> {spec_remote_error, Msg} - end; - _Other -> not_a_spec - end; - {error, {Line, _, Msg}} -> {spec_parser_error, Line, Msg} - end; - _Other -> - lexer_error - end. - -reason_spec_error({spec_remote_error, Msg}) -> - io_lib:format("Remote type solver error: ~s. Make sure the behaviour source is included in the analysis or the plt",[Msg]); -reason_spec_error(not_a_spec) -> - "This is not a spec"; -reason_spec_error({spec_parser_error, Line, Msg}) -> - io_lib:format("~s line of the spec: ~s", [ordinal(Line),Msg]); -reason_spec_error(lexer_error) -> - "Lexical error". - -ordinal(1) -> "1st"; -ordinal(2) -> "2nd"; -ordinal(3) -> "3rd"; -ordinal(N) when is_integer(N) -> io_lib:format("~wth",[N]). - -check_callback(Module, Behaviour, Fun, Arity, XRetType, XArgTypes, Plt) -> - LookupType = dialyzer_plt:lookup(Plt, {Module, Fun, Arity}), - case LookupType of - {value, {Type,Args}} -> - Warn1 = case unifiable(Type, XRetType) of - [] -> []; - Offenders -> - [{callback_type_mismatch, - [Behaviour, Fun, Arity, erl_types:t_sup(Offenders)]}] - end, - ZipArgs = lists:zip3(lists:seq(1, Arity), Args, XArgTypes), - Warn2 = [{callback_arg_type_mismatch, - [Behaviour, Fun, Arity, N, - erl_types:t_sup(Offenders)]} || - {Offenders, N} <- [check_callback_1(V) || V <- ZipArgs], - Offenders =/= []], - Warn1 ++ Warn2; - _ -> [{callback_missing, [Behaviour, Fun, Arity]}] - end. - -check_callback_1({N, T1, T2}) -> - {unifiable(T1, T2), N}. - -unifiable(Type1, Type2) -> - List1 = erl_types:t_elements(Type1), - List2 = erl_types:t_elements(Type2), - [T || T <- List1, - lists:all(fun(T1) -> - erl_types:t_is_none(erl_types:t_inf(T, T1, opaque)) - end, List2)]. - -add_tag_file_line(_Module, {Tag, [B|_R]} = Warn, State) - when Tag =:= spec_missing; - Tag =:= invalid_spec; - Tag =:= callback_missing -> - {B, Line} = lists:keyfind(B, 1, State#state.behlines), - {?WARN_BEHAVIOUR, {State#state.filename, Line}, Warn}; -add_tag_file_line(Module, {_Tag, [_B, Fun, Arity|_R]} = Warn, State) -> - {_A, FunCode} = - dialyzer_codeserver:lookup_mfa_code({Module, Fun, Arity}, - State#state.codeserver), - Anns = cerl:get_ann(FunCode), - FileLine = {get_file(Anns), get_line(Anns)}, - {?WARN_BEHAVIOUR, FileLine, Warn}. - -get_line([Line|_]) when is_integer(Line) -> Line; -get_line([_|Tail]) -> get_line(Tail); -get_line([]) -> -1. - -get_file([{file, File}|_]) -> File; -get_file([_|Tail]) -> get_file(Tail). - -%%----------------------------------------------------------------------------- - -get_behaviours([], _Codeserver, KnownAcc, UnknownAcc) -> - {KnownAcc, UnknownAcc}; -get_behaviours([M|Rest], Codeserver, KnownAcc, UnknownAcc) -> - Tree = dialyzer_codeserver:lookup_mod_code(M, Codeserver), - Attrs = cerl:module_attrs(Tree), - {Behaviours, _BehLines} = get_behaviours(Attrs), - {Known, Unknown} = call_behaviours(Behaviours), - get_behaviours(Rest, Codeserver, Known ++ KnownAcc, Unknown ++ UnknownAcc). - -call_behaviours(Behaviours) -> - call_behaviours(Behaviours, [], []). -call_behaviours([], KnownAcc, UnknownAcc) -> - {lists:reverse(KnownAcc), lists:reverse(UnknownAcc)}; -call_behaviours([Behaviour|Rest], KnownAcc, UnknownAcc) -> - try - Callbacks = Behaviour:behaviour_info(callbacks), - Fun = fun({_,_,_}) -> true; - (_) -> false - end, - case lists:any(Fun, Callbacks) of - false -> call_behaviours(Rest, KnownAcc, [Behaviour | UnknownAcc]); - true -> call_behaviours(Rest, [Behaviour | KnownAcc], UnknownAcc) - end - catch - _:_ -> call_behaviours(Rest, KnownAcc, [Behaviour | UnknownAcc]) - end. - -%------------------------------------------------------------------------------ - get_behaviour_apis([], Acc) -> Acc; get_behaviour_apis([Behaviour | Rest], Acc) -> diff --git a/lib/dialyzer/src/dialyzer_cl.erl b/lib/dialyzer/src/dialyzer_cl.erl index 8d61216b7a..04a0db890f 100644 --- a/lib/dialyzer/src/dialyzer_cl.erl +++ b/lib/dialyzer/src/dialyzer_cl.erl @@ -29,10 +29,6 @@ -module(dialyzer_cl). -%% Avoid warning for local function error/1 clashing with autoimported BIF. --compile({no_auto_import,[error/1]}). -%% Avoid warning for local function error/2 clashing with autoimported BIF. --compile({no_auto_import,[error/2]}). -export([start/1]). -include("dialyzer.hrl"). @@ -88,7 +84,7 @@ init_opts_for_build(Opts) -> Plts -> Msg = io_lib:format("Could not build multiple PLT files: ~s\n", [format_plts(Plts)]), - error(Msg) + cl_error(Msg) end; false -> Opts#options{init_plts = []} end. @@ -110,7 +106,7 @@ init_opts_for_add(Opts) -> Plts -> Msg = io_lib:format("Could not add to multiple PLT files: ~s\n", [format_plts(Plts)]), - error(Msg) + cl_error(Msg) end; false -> case Opts#options.init_plts =:= [] of @@ -134,11 +130,12 @@ check_plt_aux([_] = Plt, Opts) -> report_check(Opts2), plt_common(Opts2, [], []); check_plt_aux([Plt|Plts], Opts) -> - Opts1 = Opts#options{init_plts = [Plt]}, - Opts2 = init_opts_for_check(Opts1), - report_check(Opts2), - plt_common(Opts2, [], []), - check_plt_aux(Plts, Opts). + case check_plt_aux([Plt], Opts) of + {?RET_NOTHING_SUSPICIOUS, []} -> check_plt_aux(Plts, Opts); + {?RET_DISCREPANCIES, Warns} -> + {_RET, MoreWarns} = check_plt_aux(Plts, Opts), + {?RET_DISCREPANCIES, Warns ++ MoreWarns} + end. init_opts_for_check(Opts) -> InitPlt = @@ -175,7 +172,7 @@ init_opts_for_remove(Opts) -> Plts -> Msg = io_lib:format("Could not remove from multiple PLT files: ~s\n", [format_plts(Plts)]), - error(Msg) + cl_error(Msg) end; false -> case Opts#options.init_plts =:= [] of @@ -193,7 +190,7 @@ plt_common(#options{init_plts = [InitPlt]} = Opts, RemoveFiles, AddFiles) -> none -> ok; OutPlt -> {ok, Binary} = file:read_file(InitPlt), - file:write_file(OutPlt, Binary) + ok = file:write_file(OutPlt, Binary) end, case Opts#options.report_mode of quiet -> ok; @@ -221,19 +218,19 @@ plt_common(#options{init_plts = [InitPlt]} = Opts, RemoveFiles, AddFiles) -> {error, no_such_file} -> Msg = io_lib:format("Could not find the PLT: ~s\n~s", [InitPlt, default_plt_error_msg()]), - error(Msg); + cl_error(Msg); {error, not_valid} -> Msg = io_lib:format("The file: ~s is not a valid PLT file\n~s", [InitPlt, default_plt_error_msg()]), - error(Msg); + cl_error(Msg); {error, read_error} -> Msg = io_lib:format("Could not read the PLT: ~s\n~s", [InitPlt, default_plt_error_msg()]), - error(Msg); + cl_error(Msg); {error, {no_file_to_remove, F}} -> Msg = io_lib:format("Could not remove the file ~s from the PLT: ~s\n", [F, InitPlt]), - error(Msg) + cl_error(Msg) end. default_plt_error_msg() -> @@ -426,7 +423,7 @@ assert_writable(PltFile) -> true -> ok; false -> Msg = io_lib:format(" The PLT file ~s is not writable", [PltFile]), - error(Msg) + cl_error(Msg) end. check_if_writable(PltFile) -> @@ -525,10 +522,7 @@ native_compile(Mods) -> end. hc(Mod) -> - case code:ensure_loaded(Mod) of - {module, Mod} -> ok; - {error, sticky_directory} -> ok - end, + {module, Mod} = code:ensure_loaded(Mod), case code:is_module_native(Mod) of true -> ok; false -> @@ -553,7 +547,7 @@ init_output(State0, #options{output_file = OutFile, {error, Reason} -> Msg = io_lib:format("Could not open output file ~p, Reason: ~p\n", [OutFile, Reason]), - error(State, lists:flatten(Msg)) + cl_error(State, lists:flatten(Msg)) end end. @@ -599,10 +593,10 @@ cl_loop(State, LogCache) -> cl_loop(NewState, LogCache); {'EXIT', BackendPid, {error, Reason}} -> Msg = failed_anal_msg(Reason, LogCache), - error(State, Msg); + cl_error(State, Msg); {'EXIT', BackendPid, Reason} when Reason =/= 'normal' -> Msg = failed_anal_msg(io_lib:format("~P", [Reason, 12]), LogCache), - error(State, Msg); + cl_error(State, Msg); _Other -> %% io:format("Received ~p\n", [_Other]), cl_loop(State, LogCache) @@ -611,7 +605,7 @@ cl_loop(State, LogCache) -> -spec failed_anal_msg(string(), [_]) -> nonempty_string(). failed_anal_msg(Reason, LogCache) -> - Msg = "Analysis failed with error: " ++ Reason ++ "\n", + Msg = "Analysis failed with error:\n" ++ Reason ++ "\n", case LogCache =:= [] of true -> Msg; false -> @@ -635,14 +629,14 @@ store_warnings(#cl_state{stored_warnings = StoredWarnings} = St, Warnings) -> store_unknown_behaviours(#cl_state{unknown_behaviours = Behs} = St, Beh) -> St#cl_state{unknown_behaviours = Beh ++ Behs}. --spec error(string()) -> no_return(). +-spec cl_error(string()) -> no_return(). -error(Msg) -> +cl_error(Msg) -> throw({dialyzer_error, Msg}). --spec error(#cl_state{}, string()) -> no_return(). +-spec cl_error(#cl_state{}, string()) -> no_return(). -error(State, Msg) -> +cl_error(State, Msg) -> case State#cl_state.output of standard_io -> ok; Outfile -> io:format(Outfile, "\n~s\n", [Msg]) @@ -754,15 +748,13 @@ print_unknown_behaviours(#cl_state{output = Output, true -> io:nl(Output); %% Need to do a newline first false -> ok end, - case Format of - formatted -> - io:put_chars(Output, "Unknown behaviours (behaviour_info(callbacks)" - " does not return any specs):\n"), - do_print_unknown_behaviours(Output, Behaviours, " "); - raw -> - io:put_chars(Output, "%% Unknown behaviours:\n"), - do_print_unknown_behaviours(Output, Behaviours, "%% ") - end + {Prompt, Prefix} = + case Format of + formatted -> {"Unknown behaviours:\n"," "}; + raw -> {"%% Unknown behaviours:\n","%% "} + end, + io:put_chars(Output, Prompt), + do_print_unknown_behaviours(Output, Behaviours, Prefix) end. do_print_unknown_behaviours(Output, [B|T], Before) -> diff --git a/lib/dialyzer/src/dialyzer_cl_parse.erl b/lib/dialyzer/src/dialyzer_cl_parse.erl index f80eb81ac6..ff8fc39a5e 100644 --- a/lib/dialyzer/src/dialyzer_cl_parse.erl +++ b/lib/dialyzer/src/dialyzer_cl_parse.erl @@ -491,6 +491,12 @@ warning_options_msg() -> Suppress warnings for patterns that are unused or cannot match. -Wno_opaque Suppress warnings for violations of opaqueness of data types. + -Wno_behaviours + Suppress warnings about behaviour callbacks which drift from the published + recommended interfaces. + -Wno_undefined_callbacks + Suppress warnings about behaviours that have no -callback attributes for + their callbacks. -Wunmatched_returns *** Include warnings for function calls which ignore a structured return value or do not match against one of many possible return value(s). @@ -498,9 +504,6 @@ warning_options_msg() -> Include warnings for functions that only return by means of an exception. -Wrace_conditions *** Include warnings for possible race conditions. - -Wbehaviours *** - Include warnings about behaviour callbacks which drift from the published - recommended interfaces. -Wunderspecs *** Warn about underspecified functions (those whose -spec is strictly more allowing than the success typing). diff --git a/lib/dialyzer/src/dialyzer_codeserver.erl b/lib/dialyzer/src/dialyzer_codeserver.erl index b2097f7e53..c34a9f0b7d 100644 --- a/lib/dialyzer/src/dialyzer_codeserver.erl +++ b/lib/dialyzer/src/dialyzer_codeserver.erl @@ -28,10 +28,11 @@ -module(dialyzer_codeserver). -export([delete/1, - finalize_contracts/2, + finalize_contracts/3, finalize_exported_types/2, finalize_records/2, get_contracts/1, + get_callbacks/1, get_exported_types/1, get_exports/1, get_records/1, @@ -54,7 +55,7 @@ store_records/3, store_temp_records/3, store_contracts/3, - store_temp_contracts/3]). + store_temp_contracts/4]). -export_type([codeserver/0]). @@ -70,7 +71,10 @@ records = dict:new() :: dict(), temp_records = dict:new() :: dict(), contracts = dict:new() :: dict(), - temp_contracts = dict:new() :: dict()}). + callbacks = dict:new() :: dict(), + temp_contracts = dict:new() :: dict(), + temp_callbacks = dict:new() :: dict() + }). -opaque codeserver() :: #codeserver{}. @@ -227,24 +231,42 @@ lookup_mfa_contract({M,_F,_A} = MFA, #codeserver{contracts = ContDict}) -> get_contracts(#codeserver{contracts = ContDict}) -> ContDict. --spec store_temp_contracts(atom(), dict(), codeserver()) -> codeserver(). +-spec get_callbacks(codeserver()) -> dict(). -store_temp_contracts(Mod, Dict, #codeserver{temp_contracts = C} = CS) +get_callbacks(#codeserver{callbacks = CallbDict}) -> + CallbDict. + +-spec store_temp_contracts(atom(), dict(), dict(), codeserver()) -> + codeserver(). + +store_temp_contracts(Mod, SpecDict, CallbackDict, + #codeserver{temp_contracts = Cn, + temp_callbacks = Cb} = CS) when is_atom(Mod) -> - case dict:size(Dict) =:= 0 of - true -> CS; - false -> CS#codeserver{temp_contracts = dict:store(Mod, Dict, C)} + CS1 = + case dict:size(SpecDict) =:= 0 of + true -> CS; + false -> CS#codeserver{temp_contracts = dict:store(Mod, SpecDict, Cn)} + end, + case dict:size(CallbackDict) =:= 0 of + true -> CS1; + false -> CS1#codeserver{temp_callbacks = dict:store(Mod, CallbackDict, Cb)} end. --spec get_temp_contracts(codeserver()) -> dict(). +-spec get_temp_contracts(codeserver()) -> {dict(), dict()}. -get_temp_contracts(#codeserver{temp_contracts = TempContDict}) -> - TempContDict. +get_temp_contracts(#codeserver{temp_contracts = TempContDict, + temp_callbacks = TempCallDict}) -> + {TempContDict, TempCallDict}. --spec finalize_contracts(dict(), codeserver()) -> codeserver(). +-spec finalize_contracts(dict(), dict(), codeserver()) -> codeserver(). -finalize_contracts(Dict, CS) -> - CS#codeserver{contracts = Dict, temp_contracts = dict:new()}. +finalize_contracts(CnDict, CbDict, CS) -> + CS#codeserver{contracts = CnDict, + callbacks = CbDict, + temp_contracts = dict:new(), + temp_callbacks = dict:new() + }. table__new() -> spawn_link(fun() -> table__loop(none, dict:new()) end). diff --git a/lib/dialyzer/src/dialyzer_contracts.erl b/lib/dialyzer/src/dialyzer_contracts.erl index 84b926a17a..8b43740e34 100644 --- a/lib/dialyzer/src/dialyzer_contracts.erl +++ b/lib/dialyzer/src/dialyzer_contracts.erl @@ -141,7 +141,8 @@ sequence([H|T], Delimiter) -> H ++ Delimiter ++ sequence(T, Delimiter). dialyzer_codeserver:codeserver(). process_contract_remote_types(CodeServer) -> - TmpContractDict = dialyzer_codeserver:get_temp_contracts(CodeServer), + {TmpContractDict, TmpCallbackDict} = + dialyzer_codeserver:get_temp_contracts(CodeServer), ExpTypes = dialyzer_codeserver:get_exported_types(CodeServer), RecordDict = dialyzer_codeserver:get_records(CodeServer), ContractFun = @@ -155,7 +156,9 @@ process_contract_remote_types(CodeServer) -> dict:map(ContractFun, ContractDict) end, NewContractDict = dict:map(ModuleFun, TmpContractDict), - dialyzer_codeserver:finalize_contracts(NewContractDict, CodeServer). + NewCallbackDict = dict:map(ModuleFun, TmpCallbackDict), + dialyzer_codeserver:finalize_contracts(NewContractDict, NewCallbackDict, + CodeServer). -spec check_contracts([{mfa(), file_contract()}], dialyzer_callgraph:callgraph(), dict()) -> plt_contracts(). @@ -253,7 +256,7 @@ check_extraneous([C|Cs], SuccType) -> check_extraneous_1(Contract, SuccType) -> CRngs = erl_types:t_elements(erl_types:t_fun_range(Contract)), STRng = erl_types:t_fun_range(SuccType), - %% io:format("CR = ~p\nSR = ~p\n", [CRngs, STRng]), + ?debug("CR = ~p\nSR = ~p\n", [CRngs, STRng]), case [CR || CR <- CRngs, erl_types:t_is_none(erl_types:t_inf(CR, STRng, opaque))] of [] -> ok; CRs -> {error, {extra_range, erl_types:t_sup(CRs), STRng}} @@ -349,28 +352,37 @@ insert_constraints([], Dict) -> Dict. store_tmp_contract(MFA, FileLine, TypeSpec, SpecDict, RecordsDict) -> %% io:format("contract from form: ~p\n", [TypeSpec]), - TmpContract = contract_from_form(TypeSpec, RecordsDict), + TmpContract = contract_from_form(TypeSpec, RecordsDict, FileLine), %% io:format("contract: ~p\n", [Contract]), dict:store(MFA, {FileLine, TmpContract}, SpecDict). -contract_from_form(Forms, RecDict) -> - {CFuns, Forms1} = contract_from_form(Forms, RecDict, [], []), +contract_from_form(Forms, RecDict, FileLine) -> + {CFuns, Forms1} = contract_from_form(Forms, RecDict, FileLine, [], []), #tmp_contract{contract_funs = CFuns, forms = Forms1}. contract_from_form([{type, _, 'fun', [_, _]} = Form | Left], RecDict, - TypeAcc, FormAcc) -> + FileLine, TypeAcc, FormAcc) -> TypeFun = fun(ExpTypes, AllRecords) -> - Type = erl_types:t_from_form(Form, RecDict), + Type = + try + erl_types:t_from_form(Form, RecDict) + catch + throw:{error, Msg} -> + {File, Line} = FileLine, + NewMsg = io_lib:format("~s:~p: ~s", [filename:basename(File), + Line, Msg]), + throw({error, NewMsg}) + end, NewType = erl_types:t_solve_remote(Type, ExpTypes, AllRecords), {NewType, []} end, NewTypeAcc = [TypeFun | TypeAcc], NewFormAcc = [{Form, []} | FormAcc], - contract_from_form(Left, RecDict, NewTypeAcc, NewFormAcc); + contract_from_form(Left, RecDict, FileLine, NewTypeAcc, NewFormAcc); contract_from_form([{type, _L1, bounded_fun, [{type, _L2, 'fun', [_, _]} = Form, Constr]}| Left], - RecDict, TypeAcc, FormAcc) -> + RecDict, FileLine, TypeAcc, FormAcc) -> TypeFun = fun(ExpTypes, AllRecords) -> Constr1 = [constraint_from_form(C, RecDict, ExpTypes, AllRecords) @@ -382,8 +394,8 @@ contract_from_form([{type, _L1, bounded_fun, end, NewTypeAcc = [TypeFun | TypeAcc], NewFormAcc = [{Form, Constr} | FormAcc], - contract_from_form(Left, RecDict, NewTypeAcc, NewFormAcc); -contract_from_form([], _RecDict, TypeAcc, FormAcc) -> + contract_from_form(Left, RecDict, FileLine, NewTypeAcc, NewFormAcc); +contract_from_form([], _RecDict, _FileLine, TypeAcc, FormAcc) -> {lists:reverse(TypeAcc), lists:reverse(FormAcc)}. constraint_from_form({type, _, constraint, [{atom, _, is_subtype}, @@ -441,7 +453,21 @@ get_invalid_contract_warnings_funs([{MFA, {FileLine, Contract}}|Left], {error, invalid_contract} -> [invalid_contract_warning(MFA, FileLine, Sig, RecDict)|Acc]; {error, {extra_range, ExtraRanges, STRange}} -> - [extra_range_warning(MFA, FileLine, ExtraRanges, STRange)|Acc]; + Warn = + case t_from_forms_without_remote(Contract#contract.forms, + RecDict) of + {ok, NoRemoteType} -> + CRet = erl_types:t_fun_range(NoRemoteType), + erl_types:t_is_subtype(ExtraRanges, CRet); + unsupported -> + true + end, + case Warn of + true -> + [extra_range_warning(MFA, FileLine, ExtraRanges, STRange)|Acc]; + false -> + Acc + end; {error, Msg} -> [{?WARN_CONTRACT_SYNTAX, FileLine, Msg}|Acc]; ok -> @@ -504,26 +530,92 @@ picky_contract_check(CSig0, Sig0, MFA, FileLine, Contract, RecDict, Acc) -> extra_contract_warning({M, F, A}, FileLine, Contract, CSig, Sig, RecDict) -> SigString = lists:flatten(dialyzer_utils:format_sig(Sig, RecDict)), ContractString0 = lists:flatten(dialyzer_utils:format_sig(CSig, RecDict)), - case SigString =:= ContractString0 of + %% The only difference is in record fields containing 'undefined' or not. + IsUndefRecordFieldsRelated = SigString =:= ContractString0, + {IsRemoteTypesRelated, SubtypeRelation} = + is_remote_types_related(Contract, CSig, Sig, RecDict), + case IsUndefRecordFieldsRelated orelse IsRemoteTypesRelated of true -> - %% The only difference is in record fields containing 'undefined' or not. no_warning; false -> ContractString = contract_to_string(Contract), {Tag, Msg} = - case erl_types:t_is_subtype(CSig, Sig) of - true -> + case SubtypeRelation of + contract_is_subtype -> {?WARN_CONTRACT_SUBTYPE, {contract_subtype, [M, F, A, ContractString, SigString]}}; - false -> - case erl_types:t_is_subtype(Sig, CSig) of - true -> - {?WARN_CONTRACT_SUPERTYPE, - {contract_supertype, [M, F, A, ContractString, SigString]}}; - false -> - {?WARN_CONTRACT_NOT_EQUAL, - {contract_diff, [M, F, A, ContractString, SigString]}} - end + contract_is_supertype -> + {?WARN_CONTRACT_SUPERTYPE, + {contract_supertype, [M, F, A, ContractString, SigString]}}; + neither -> + {?WARN_CONTRACT_NOT_EQUAL, + {contract_diff, [M, F, A, ContractString, SigString]}} end, {warning, {Tag, FileLine, Msg}} end. + +is_remote_types_related(Contract, CSig, Sig, RecDict) -> + case erl_types:t_is_subtype(CSig, Sig) of + true -> + {false, contract_is_subtype}; + false -> + case erl_types:t_is_subtype(Sig, CSig) of + true -> + case t_from_forms_without_remote(Contract#contract.forms, RecDict) of + {ok, NoRemoteTypeSig} -> + case blame_remote(CSig, NoRemoteTypeSig, Sig) of + true -> + {true, neither}; + false -> + {false, contract_is_supertype} + end; + unsupported -> + {false, contract_is_supertype} + end; + false -> + {false, neither} + end + end. + +t_from_forms_without_remote([{FType, []}], RecDict) -> + Type0 = erl_types:t_from_form(FType, RecDict), + Map = + fun(Type) -> + case erl_types:t_is_remote(Type) of + true -> erl_types:t_none(); + false -> Type + end + end, + {ok, erl_types:t_map(Map, Type0)}; +t_from_forms_without_remote([{_FType, _Constrs}], _RecDict) -> + %% 'When' constraints + unsupported; +t_from_forms_without_remote(_Forms, _RecDict) -> + %% Lots of forms + unsupported. + +blame_remote(ContractSig, NoRemoteContractSig, Sig) -> + CArgs = erl_types:t_fun_args(ContractSig), + CRange = erl_types:t_fun_range(ContractSig), + NRArgs = erl_types:t_fun_args(NoRemoteContractSig), + NRRange = erl_types:t_fun_range(NoRemoteContractSig), + SArgs = erl_types:t_fun_args(Sig), + SRange = erl_types:t_fun_range(Sig), + blame_remote_list([CRange|CArgs], [NRRange|NRArgs], [SRange|SArgs]). + +blame_remote_list([], [], []) -> + true; +blame_remote_list([CArg|CArgs], [NRArg|NRArgs], [SArg|SArgs]) -> + case erl_types:t_is_equal(CArg, NRArg) of + true -> + case not erl_types:t_is_equal(CArg, SArg) of + true -> false; + false -> blame_remote_list(CArgs, NRArgs, SArgs) + end; + false -> + case erl_types:t_is_subtype(SArg, NRArg) + andalso not erl_types:t_is_subtype(NRArg, SArg) of + true -> false; + false -> blame_remote_list(CArgs, NRArgs, SArgs) + end + end. diff --git a/lib/dialyzer/src/dialyzer_options.erl b/lib/dialyzer/src/dialyzer_options.erl index b2a67de8bd..866650a0b2 100644 --- a/lib/dialyzer/src/dialyzer_options.erl +++ b/lib/dialyzer/src/dialyzer_options.erl @@ -49,7 +49,9 @@ build(Opts) -> ?WARN_CALLGRAPH, ?WARN_CONTRACT_RANGE, ?WARN_CONTRACT_TYPES, - ?WARN_CONTRACT_SYNTAX], + ?WARN_CONTRACT_SYNTAX, + ?WARN_BEHAVIOUR, + ?WARN_UNDEFINED_CALLBACK], DefaultWarns1 = ordsets:from_list(DefaultWarns), InitPlt = dialyzer_plt:get_default_plt(), DefaultOpts = #options{}, @@ -275,14 +277,16 @@ build_warnings([Opt|Opts], Warnings) -> no_contracts -> Warnings1 = ordsets:del_element(?WARN_CONTRACT_SYNTAX, Warnings), ordsets:del_element(?WARN_CONTRACT_TYPES, Warnings1); + no_behaviours -> + ordsets:del_element(?WARN_BEHAVIOUR, Warnings); + no_undefined_callbacks -> + ordsets:del_element(?WARN_UNDEFINED_CALLBACK, Warnings); unmatched_returns -> ordsets:add_element(?WARN_UNMATCHED_RETURN, Warnings); error_handling -> ordsets:add_element(?WARN_RETURN_ONLY_EXIT, Warnings); race_conditions -> ordsets:add_element(?WARN_RACE_CONDITION, Warnings); - behaviours -> - ordsets:add_element(?WARN_BEHAVIOUR, Warnings); specdiffs -> S = ordsets:from_list([?WARN_CONTRACT_SUBTYPE, ?WARN_CONTRACT_SUPERTYPE, diff --git a/lib/dialyzer/src/dialyzer_plt.erl b/lib/dialyzer/src/dialyzer_plt.erl index 6033d7f17c..206c43e4e2 100644 --- a/lib/dialyzer/src/dialyzer_plt.erl +++ b/lib/dialyzer/src/dialyzer_plt.erl @@ -43,10 +43,12 @@ %% insert/3, insert_list/2, insert_contract_list/2, + insert_callbacks/2, insert_types/2, insert_exported_types/2, lookup/2, lookup_contract/2, + lookup_callbacks/2, lookup_module/2, merge_plts/1, merge_plts_or_report_conflicts/2, @@ -79,6 +81,7 @@ -record(plt, {info = table_new() :: dict(), types = table_new() :: dict(), contracts = table_new() :: dict(), + callbacks = table_new() :: dict(), exported_types = sets:new() :: set()}). -opaque plt() :: #plt{}. @@ -91,6 +94,7 @@ file_md5_list = [] :: [file_md5()], info = dict:new() :: dict(), contracts = dict:new() :: dict(), + callbacks = dict:new() :: dict(), types = dict:new() :: dict(), exported_types = sets:new() :: set(), mod_deps :: mod_deps(), @@ -105,20 +109,26 @@ new() -> -spec delete_module(plt(), atom()) -> plt(). -delete_module(#plt{info = Info, types = Types, contracts = Contracts, +delete_module(#plt{info = Info, types = Types, + contracts = Contracts, + callbacks = Callbacks, exported_types = ExpTypes}, Mod) -> #plt{info = table_delete_module(Info, Mod), types = table_delete_module2(Types, Mod), contracts = table_delete_module(Contracts, Mod), + callbacks = table_delete_module(Callbacks, Mod), exported_types = table_delete_module1(ExpTypes, Mod)}. -spec delete_list(plt(), [mfa() | integer()]) -> plt(). -delete_list(#plt{info = Info, types = Types, contracts = Contracts, +delete_list(#plt{info = Info, types = Types, + contracts = Contracts, + callbacks = Callbacks, exported_types = ExpTypes}, List) -> #plt{info = table_delete_list(Info, List), types = Types, contracts = table_delete_list(Contracts, List), + callbacks = table_delete_list(Callbacks, List), exported_types = ExpTypes}. -spec insert_contract_list(plt(), dialyzer_contracts:plt_contracts()) -> plt(). @@ -126,16 +136,42 @@ delete_list(#plt{info = Info, types = Types, contracts = Contracts, insert_contract_list(#plt{contracts = Contracts} = PLT, List) -> PLT#plt{contracts = table_insert_list(Contracts, List)}. +-spec insert_callbacks(plt(), dialyzer_codeserver:codeserver()) -> plt(). + +insert_callbacks(#plt{callbacks = Callbacks} = Plt, Codeserver) -> + FunPreferNew = fun(_Key, _Val1, Val2) -> Val2 end, + FunDictMerger = + fun(_Key, Value, AccIn) -> dict:merge(FunPreferNew, Value, AccIn) end, + MergedCallbacks = dict:fold(FunDictMerger, dict:new(), + dialyzer_codeserver:get_callbacks(Codeserver)), + List = dict:to_list(MergedCallbacks), + Plt#plt{callbacks = table_insert_list(Callbacks, List)}. + -spec lookup_contract(plt(), mfa_patt()) -> 'none' | {'value', #contract{}}. lookup_contract(#plt{contracts = Contracts}, {M, F, _} = MFA) when is_atom(M), is_atom(F) -> table_lookup(Contracts, MFA). +-spec lookup_callbacks(plt(), module()) -> [{mfa(), + {{Filename::string(), + Line::pos_integer()}, + #contract{}}}]. + +lookup_callbacks(#plt{callbacks = Callbacks}, Mod) when is_atom(Mod) -> + FunModFilter = + fun({M, _F, _A}, _Val) -> M =:= Mod; + ( _Key, _Val) -> false + end, + ModCallbacks = dict:filter(FunModFilter, Callbacks), + dict:to_list(ModCallbacks). + -spec delete_contract_list(plt(), [mfa()]) -> plt(). -delete_contract_list(#plt{contracts = Contracts} = PLT, List) -> - PLT#plt{contracts = table_delete_list(Contracts, List)}. +delete_contract_list(#plt{contracts = Contracts, + callbacks = Callbacks} = PLT, List) -> + PLT#plt{contracts = table_delete_list(Contracts, List), + callbacks = table_delete_list(Callbacks, List)}. %% -spec insert(plt(), mfa() | integer(), {_, _}) -> plt(). %% @@ -230,6 +266,7 @@ from_file(FileName, ReturnInfo) -> Plt = #plt{info = Rec#file_plt.info, types = Rec#file_plt.types, contracts = Rec#file_plt.contracts, + callbacks = Rec#file_plt.callbacks, exported_types = Rec#file_plt.exported_types}, case ReturnInfo of false -> Plt; @@ -284,26 +321,34 @@ get_record_from_file(FileName) -> -spec merge_plts([plt()]) -> plt(). merge_plts(List) -> - InfoList = [Info || #plt{info = Info} <- List], - TypesList = [Types || #plt{types = Types} <- List], - ExpTypesList = [ExpTypes || #plt{exported_types = ExpTypes} <- List], - ContractsList = [Contracts || #plt{contracts = Contracts} <- List], + {InfoList, TypesList, ExpTypesList, ContractsList, CallbacksList} = + group_fields(List), #plt{info = table_merge(InfoList), types = table_merge(TypesList), exported_types = sets_merge(ExpTypesList), - contracts = table_merge(ContractsList)}. + contracts = table_merge(ContractsList), + callbacks = table_merge(CallbacksList) + }. -spec merge_disj_plts([plt()]) -> plt(). merge_disj_plts(List) -> + {InfoList, TypesList, ExpTypesList, ContractsList, CallbacksList} = + group_fields(List), + #plt{info = table_disj_merge(InfoList), + types = table_disj_merge(TypesList), + exported_types = sets_disj_merge(ExpTypesList), + contracts = table_disj_merge(ContractsList), + callbacks = table_disj_merge(CallbacksList) + }. + +group_fields(List) -> InfoList = [Info || #plt{info = Info} <- List], TypesList = [Types || #plt{types = Types} <- List], ExpTypesList = [ExpTypes || #plt{exported_types = ExpTypes} <- List], ContractsList = [Contracts || #plt{contracts = Contracts} <- List], - #plt{info = table_disj_merge(InfoList), - types = table_disj_merge(TypesList), - exported_types = sets_disj_merge(ExpTypesList), - contracts = table_disj_merge(ContractsList)}. + CallbacksList = [Callbacks || #plt{callbacks = Callbacks} <- List], + {InfoList, TypesList, ExpTypesList, ContractsList, CallbacksList}. -spec merge_plts_or_report_conflicts([file:filename()], [plt()]) -> plt(). @@ -329,7 +374,7 @@ find_duplicates(List) -> to_file(FileName, #plt{info = Info, types = Types, contracts = Contracts, - exported_types = ExpTypes}, + callbacks = Callbacks, exported_types = ExpTypes}, ModDeps, {MD5, OldModDeps}) -> NewModDeps = dict:merge(fun(_Key, OldVal, NewVal) -> ordsets:union(OldVal, NewVal) @@ -340,6 +385,7 @@ to_file(FileName, file_md5_list = MD5, info = Info, contracts = Contracts, + callbacks = Callbacks, types = Types, exported_types = ExpTypes, mod_deps = NewModDeps, diff --git a/lib/dialyzer/src/dialyzer_succ_typings.erl b/lib/dialyzer/src/dialyzer_succ_typings.erl index dc5a3fed37..4d86bb34a7 100644 --- a/lib/dialyzer/src/dialyzer_succ_typings.erl +++ b/lib/dialyzer/src/dialyzer_succ_typings.erl @@ -29,7 +29,7 @@ -export([analyze_callgraph/3, analyze_callgraph/4, - get_warnings/7]). + get_warnings/6]). %% These are only intended as debug functions. -export([doit/1, @@ -106,21 +106,19 @@ get_refined_success_typings(State) -> -type doc_plt() :: 'undefined' | dialyzer_plt:plt(). -spec get_warnings(dialyzer_callgraph:callgraph(), dialyzer_plt:plt(), doc_plt(), dialyzer_codeserver:codeserver(), set(), - pid(), boolean()) -> + pid()) -> {[dial_warning()], dialyzer_plt:plt(), doc_plt()}. -get_warnings(Callgraph, Plt, DocPlt, Codeserver, - NoWarnUnused, Parent, BehavioursChk) -> +get_warnings(Callgraph, Plt, DocPlt, Codeserver, NoWarnUnused, Parent) -> InitState = #st{callgraph = Callgraph, codeserver = Codeserver, no_warn_unused = NoWarnUnused, parent = Parent, plt = Plt}, NewState = get_refined_success_typings(InitState), Mods = dialyzer_callgraph:modules(NewState#st.callgraph), CWarns = dialyzer_contracts:get_invalid_contract_warnings(Mods, Codeserver, NewState#st.plt), - get_warnings_from_modules(Mods, NewState, DocPlt, BehavioursChk, CWarns). + get_warnings_from_modules(Mods, NewState, DocPlt, CWarns). -get_warnings_from_modules([M|Ms], State, DocPlt, - BehavioursChk, Acc) when is_atom(M) -> +get_warnings_from_modules([M|Ms], State, DocPlt, Acc) when is_atom(M) -> send_log(State#st.parent, io_lib:format("Getting warnings for ~w\n", [M])), #st{callgraph = Callgraph, codeserver = Codeserver, no_warn_unused = NoWarnUnused, plt = Plt} = State, @@ -135,19 +133,15 @@ get_warnings_from_modules([M|Ms], State, DocPlt, dialyzer_dataflow:get_warnings(ModCode, Plt, Callgraph, Records, NoWarnUnused), {NewAcc, Warnings2} = postprocess_dataflow_warns(RawWarnings2, State, Acc), Attrs = cerl:module_attrs(ModCode), - Warnings3 = if BehavioursChk -> - dialyzer_behaviours:check_callbacks(M, Attrs, - Plt, Codeserver); - true -> [] - end, + Warnings3 = dialyzer_behaviours:check_callbacks(M, Attrs, Plt, Codeserver), NewDocPlt = insert_into_doc_plt(FunTypes, Callgraph, DocPlt), NewCallgraph = dialyzer_callgraph:renew_race_info(Callgraph, RaceCode, PublicTables, NamedTables), State1 = st__renew_state_calls(NewCallgraph, State), - get_warnings_from_modules(Ms, State1, NewDocPlt, BehavioursChk, + get_warnings_from_modules(Ms, State1, NewDocPlt, [Warnings1, Warnings2, Warnings3|NewAcc]); -get_warnings_from_modules([], #st{plt = Plt}, DocPlt, _, Acc) -> +get_warnings_from_modules([], #st{plt = Plt}, DocPlt, Acc) -> {lists:flatten(Acc), Plt, DocPlt}. postprocess_dataflow_warns(RawWarnings, State, WarnAcc) -> @@ -476,7 +470,7 @@ doit(Module) -> {ok, Code} = dialyzer_utils:get_core_from_abstract_code(AbstrCode), {ok, Records} = dialyzer_utils:get_record_and_type_info(AbstrCode), %% contract typing info in dictionary format - {ok, Contracts} = + {ok, Contracts, _Callbacks} = dialyzer_utils:get_spec_info(cerl:concrete(cerl:module_name(Code)), AbstrCode, Records), Sigs0 = get_top_level_signatures(Code, Records, Contracts), diff --git a/lib/dialyzer/src/dialyzer_typesig.erl b/lib/dialyzer/src/dialyzer_typesig.erl index 92868b6878..4268814859 100644 --- a/lib/dialyzer/src/dialyzer_typesig.erl +++ b/lib/dialyzer/src/dialyzer_typesig.erl @@ -2046,8 +2046,7 @@ lookup_type(Key, Map) -> %% case cerl:is_literal(Key) of %% true -> t_from_term(cerl:concrete(Key)); %% false -> - Subst = t_subst(Key, Map), - t_sup(Subst, Subst). + t_subst(Key, Map). %% end. mk_var(Var) -> diff --git a/lib/dialyzer/src/dialyzer_utils.erl b/lib/dialyzer/src/dialyzer_utils.erl index 12f8dec67e..2a248fb028 100644 --- a/lib/dialyzer/src/dialyzer_utils.erl +++ b/lib/dialyzer/src/dialyzer_utils.erl @@ -311,11 +311,15 @@ merge_records(NewRecords, OldRecords) -> %% %% ============================================================================ +-type spec_dict() :: dict(). +-type callback_dict() :: dict(). + -spec get_spec_info(atom(), abstract_code(), dict()) -> - {'ok', dict()} | {'error', string()}. + {'ok', spec_dict(), callback_dict()} | {'error', string()}. get_spec_info(ModName, AbstractCode, RecordsDict) -> - get_spec_info(AbstractCode, dict:new(), RecordsDict, ModName, "nofile"). + get_spec_info(AbstractCode, dict:new(), dict:new(), + RecordsDict, ModName, "nofile"). %% TypeSpec is a list of conditional contracts for a function. %% Each contract is of the form {[Argument], Range, [Constraint]} where @@ -323,21 +327,34 @@ get_spec_info(ModName, AbstractCode, RecordsDict) -> %% - Constraint is of the form {subtype, T1, T2} where T1 and T2 %% are erl_types:erl_type() -get_spec_info([{attribute, Ln, spec, {Id, TypeSpec}}|Left], - SpecDict, RecordsDict, ModName, File) when is_list(TypeSpec) -> +get_spec_info([{attribute, Ln, Contract, {Id, TypeSpec}}|Left], + SpecDict, CallbackDict, RecordsDict, ModName, File) + when ((Contract =:= 'spec') or (Contract =:= 'callback')), + is_list(TypeSpec) -> MFA = case Id of {_, _, _} = T -> T; {F, A} -> {ModName, F, A} end, - try dict:find(MFA, SpecDict) of + ActiveDict = + case Contract of + spec -> SpecDict; + callback -> CallbackDict + end, + try dict:find(MFA, ActiveDict) of error -> - NewSpecDict = + NewActiveDict = dialyzer_contracts:store_tmp_contract(MFA, {File, Ln}, TypeSpec, - SpecDict, RecordsDict), - get_spec_info(Left, NewSpecDict, RecordsDict, ModName, File); + ActiveDict, RecordsDict), + {NewSpecDict, NewCallbackDict} = + case Contract of + spec -> {NewActiveDict, CallbackDict}; + callback -> {SpecDict, NewActiveDict} + end, + get_spec_info(Left, NewSpecDict, NewCallbackDict, + RecordsDict, ModName,File); {ok, {{OtherFile, L},_C}} -> {Mod, Fun, Arity} = MFA, - Msg = flat_format(" Contract for function ~w:~w/~w " + Msg = flat_format(" Contract/callback for function ~w:~w/~w " "already defined in ~s:~w\n", [Mod, Fun, Arity, OtherFile, L]), throw({error, Msg}) @@ -347,12 +364,14 @@ get_spec_info([{attribute, Ln, spec, {Id, TypeSpec}}|Left], [Ln, Error])} end; get_spec_info([{attribute, _, file, {IncludeFile, _}}|Left], - SpecDict, RecordsDict, ModName, _File) -> - get_spec_info(Left, SpecDict, RecordsDict, ModName, IncludeFile); -get_spec_info([_Other|Left], SpecDict, RecordsDict, ModName, File) -> - get_spec_info(Left, SpecDict, RecordsDict, ModName, File); -get_spec_info([], SpecDict, _RecordsDict, _ModName, _File) -> - {ok, SpecDict}. + SpecDict, CallbackDict, RecordsDict, ModName, _File) -> + get_spec_info(Left, SpecDict, CallbackDict, + RecordsDict, ModName, IncludeFile); +get_spec_info([_Other|Left], SpecDict, CallbackDict, + RecordsDict, ModName, File) -> + get_spec_info(Left, SpecDict, CallbackDict, RecordsDict, ModName, File); +get_spec_info([], SpecDict, CallbackDict, _RecordsDict, _ModName, _File) -> + {ok, SpecDict, CallbackDict}. %% ============================================================================ %% diff --git a/lib/dialyzer/test/behaviour_SUITE_data/dialyzer_options b/lib/dialyzer/test/behaviour_SUITE_data/dialyzer_options new file mode 100644 index 0000000000..50991c9bc5 --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/dialyzer_options @@ -0,0 +1 @@ +{dialyzer_options, []}. diff --git a/lib/dialyzer/test/behaviour_SUITE_data/results/callbacks_and_specs b/lib/dialyzer/test/behaviour_SUITE_data/results/callbacks_and_specs new file mode 100644 index 0000000000..33d135048e --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/results/callbacks_and_specs @@ -0,0 +1,5 @@ + +my_callbacks_wrong.erl:26: The return type #state{parent::'undefined' | pid(),status::'closed' | 'init' | 'open',subscribe::[{pid(),integer()}],counter::integer()} in the specification of callback_init/1 is not a subtype of {'ok',_}, which is the expected return type for the callback of my_behaviour behaviour +my_callbacks_wrong.erl:28: The inferred return type of callback_init/1 (#state{parent::'undefined' | pid(),status::'init',subscribe::[],counter::1}) has nothing in common with {'ok',_}, which is the expected return type for the callback of my_behaviour behaviour +my_callbacks_wrong.erl:30: The return type {'reply',#state{parent::'undefined' | pid(),status::'closed' | 'init' | 'open',subscribe::[{pid(),integer()}],counter::integer()}} in the specification of callback_cast/3 is not a subtype of {'noreply',_}, which is the expected return type for the callback of my_behaviour behaviour +my_callbacks_wrong.erl:39: The specified type for the 2nd argument of callback_call/3 (atom()) is not a supertype of pid(), which is expected type for this argument in the callback of the my_behaviour behaviour diff --git a/lib/dialyzer/test/behaviour_SUITE_data/results/gen_event_incorrect_return b/lib/dialyzer/test/behaviour_SUITE_data/results/gen_event_incorrect_return new file mode 100644 index 0000000000..e646eea383 --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/results/gen_event_incorrect_return @@ -0,0 +1,2 @@ + +gen_event_incorrect_return.erl:16: The inferred return type of init/1 ('error') has nothing in common with {'error',_} | {'ok',_} | {'ok',_,'hibernate'}, which is the expected return type for the callback of gen_event behaviour diff --git a/lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_incorrect_args b/lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_incorrect_args new file mode 100644 index 0000000000..3e98da785f --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_incorrect_args @@ -0,0 +1,8 @@ + +gen_server_incorrect_args.erl:3: Undefined callback function code_change/3 (behaviour 'gen_server') +gen_server_incorrect_args.erl:3: Undefined callback function handle_cast/2 (behaviour 'gen_server') +gen_server_incorrect_args.erl:3: Undefined callback function handle_info/2 (behaviour 'gen_server') +gen_server_incorrect_args.erl:3: Undefined callback function init/1 (behaviour 'gen_server') +gen_server_incorrect_args.erl:3: Undefined callback function terminate/2 (behaviour 'gen_server') +gen_server_incorrect_args.erl:7: The inferred return type of handle_call/3 ({'no'} | {'ok'}) has nothing in common with {'noreply',_} | {'noreply',_,'hibernate' | 'infinity' | non_neg_integer()} | {'reply',_,_} | {'stop',_,_} | {'reply',_,_,'hibernate' | 'infinity' | non_neg_integer()} | {'stop',_,_,_}, which is the expected return type for the callback of gen_server behaviour +gen_server_incorrect_args.erl:7: The inferred type for the 2nd argument of handle_call/3 ('boo' | 'foo') is not a supertype of {pid(),_}, which is expected type for this argument in the callback of the gen_server behaviour diff --git a/lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_missing_callbacks b/lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_missing_callbacks new file mode 100644 index 0000000000..5e0ed5fd27 --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_missing_callbacks @@ -0,0 +1,3 @@ + +gen_server_missing_callbacks.erl:3: Undefined callback function handle_cast/2 (behaviour 'gen_server') +gen_server_missing_callbacks.erl:3: Undefined callback function handle_info/2 (behaviour 'gen_server') diff --git a/lib/dialyzer/test/behaviour_SUITE_data/results/sample_behaviour b/lib/dialyzer/test/behaviour_SUITE_data/results/sample_behaviour new file mode 100644 index 0000000000..a38e662ccf --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/results/sample_behaviour @@ -0,0 +1,9 @@ + +sample_callback_wrong.erl:15: The inferred return type of sample_callback_2/0 (42) has nothing in common with atom(), which is the expected return type for the callback of sample_behaviour behaviour +sample_callback_wrong.erl:16: The inferred return type of sample_callback_3/0 ('fair') has nothing in common with 'fail' | {'ok',1..255}, which is the expected return type for the callback of sample_behaviour behaviour +sample_callback_wrong.erl:17: The inferred return type of sample_callback_4/1 ('fail') has nothing in common with 'ok', which is the expected return type for the callback of sample_behaviour behaviour +sample_callback_wrong.erl:19: The inferred return type of sample_callback_5/1 (string()) has nothing in common with 'fail' | 'ok', which is the expected return type for the callback of sample_behaviour behaviour +sample_callback_wrong.erl:19: The inferred type for the 1st argument of sample_callback_5/1 (atom()) is not a supertype of 1..255, which is expected type for this argument in the callback of the sample_behaviour behaviour +sample_callback_wrong.erl:21: The inferred return type of sample_callback_6/3 ({'okk',number()}) has nothing in common with 'fail' | {'ok',1..255}, which is the expected return type for the callback of sample_behaviour behaviour +sample_callback_wrong.erl:21: The inferred type for the 3rd argument of sample_callback_6/3 (atom()) is not a supertype of string(), which is expected type for this argument in the callback of the sample_behaviour behaviour +sample_callback_wrong.erl:3: Undefined callback function sample_callback_1/0 (behaviour 'sample_behaviour') diff --git a/lib/dialyzer/test/behaviour_SUITE_data/results/sample_behaviour_old b/lib/dialyzer/test/behaviour_SUITE_data/results/sample_behaviour_old new file mode 100644 index 0000000000..f0181bb59c --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/results/sample_behaviour_old @@ -0,0 +1,4 @@ + +incorrect_args_callback.erl:12: The inferred type for the 2nd argument of bar/2 ('yes') is not a supertype of [any()], which is expected type for this argument in the callback of the correct_behaviour behaviour +incorrect_return_callback.erl:9: The inferred return type of foo/0 ('error') has nothing in common with 'no' | 'yes', which is the expected return type for the callback of correct_behaviour behaviour +missing_callback.erl:5: Undefined callback function foo/0 (behaviour 'correct_behaviour') diff --git a/lib/dialyzer/test/behaviour_SUITE_data/results/supervisor_incorrect_return b/lib/dialyzer/test/behaviour_SUITE_data/results/supervisor_incorrect_return new file mode 100644 index 0000000000..e89caf3cf7 --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/results/supervisor_incorrect_return @@ -0,0 +1,2 @@ + +supervisor_incorrect_return.erl:14: The inferred return type of init/1 ({'ok',{{'one_against_one',0,1},[{_,_,_,_,_,_},...]}}) has nothing in common with 'ignore' | {'ok',{{'one_for_all',non_neg_integer(),non_neg_integer()} | {'one_for_one',non_neg_integer(),non_neg_integer()} | {'rest_for_one',non_neg_integer(),non_neg_integer()} | {'simple_one_for_one',non_neg_integer(),non_neg_integer()},[{_,{atom() | tuple(),atom(),'undefined' | [any()]},'permanent' | 'temporary' | 'transient','brutal_kill' | 'infinity' | non_neg_integer(),'supervisor' | 'worker','dynamic' | [atom() | tuple()]}]}}, which is the expected return type for the callback of supervisor behaviour diff --git a/lib/dialyzer/test/behaviour_SUITE_data/results/undefined_callbacks b/lib/dialyzer/test/behaviour_SUITE_data/results/undefined_callbacks new file mode 100644 index 0000000000..7147ffc750 --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/results/undefined_callbacks @@ -0,0 +1,2 @@ + +undefined_beh_callback.erl:5: Callback info about the undefined_behaviour behaviour is not available diff --git a/lib/dialyzer/test/behaviour_SUITE_data/results/vars_in_beh_spec b/lib/dialyzer/test/behaviour_SUITE_data/results/vars_in_beh_spec new file mode 100644 index 0000000000..5284e412f0 --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/results/vars_in_beh_spec @@ -0,0 +1,6 @@ + +vars_in_beh_spec.erl:3: Undefined callback function handle_call/3 (behaviour 'gen_server') +vars_in_beh_spec.erl:3: Undefined callback function handle_cast/2 (behaviour 'gen_server') +vars_in_beh_spec.erl:3: Undefined callback function handle_info/2 (behaviour 'gen_server') +vars_in_beh_spec.erl:3: Undefined callback function init/1 (behaviour 'gen_server') +vars_in_beh_spec.erl:3: Undefined callback function terminate/2 (behaviour 'gen_server') diff --git a/lib/dialyzer/test/behaviour_SUITE_data/src/callbacks_and_specs/my_behaviour.erl b/lib/dialyzer/test/behaviour_SUITE_data/src/callbacks_and_specs/my_behaviour.erl new file mode 100644 index 0000000000..c4e5203448 --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/src/callbacks_and_specs/my_behaviour.erl @@ -0,0 +1,11 @@ +-module(my_behaviour). + +-callback callback_init(Parent :: pid()) -> {'ok', State::term()}. + +-callback callback_cast(State::term(), From::pid(), Msg::term()) -> + {'noreply', NewState::term()}. + +-callback callback_call(State::term(), From::pid(), Msg::term()) -> + {'reply', NewState::term(), Reply::term()}. + +-callback callback_exit(State::term()) -> 'ok'. diff --git a/lib/dialyzer/test/behaviour_SUITE_data/src/callbacks_and_specs/my_callbacks_correct.erl b/lib/dialyzer/test/behaviour_SUITE_data/src/callbacks_and_specs/my_callbacks_correct.erl new file mode 100644 index 0000000000..041b4ac56c --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/src/callbacks_and_specs/my_callbacks_correct.erl @@ -0,0 +1,59 @@ +-module(my_callbacks_correct). + +-export([ + callback_init/1 + , callback_call/3 + , callback_cast/3 + , callback_exit/1 + ]). + +-record(state, { + parent :: pid(), + status = init :: 'init' | 'open' | 'closed', + subscribe = [] :: list({pid(), integer()}), + counter = 1 :: integer() + }). + +-type state() :: #state{}. + +-type cast_message() :: 'open' | 'closed'. + +-type call_message() :: 'subscribe' | 'unsubscribe'. +-type call_reply() :: 'accepted' | 'rejected'. + +-spec callback_init(Parent::pid()) -> {'ok', state()}. + +callback_init(Parent) -> + {ok, #state{parent = Parent}}. + +-spec callback_cast(state(), pid(), cast_message()) -> {'noreply', state()}. + +callback_cast(#state{parent = Pid} = State, Pid, Message) + when Message =:= 'open'; Message =:= 'close' -> + {noreply, State#state{status = Message}}; +callback_cast(State, _Pid, _Message) -> + {noreply, State}. + +-spec callback_call(state(), pid(), call_message()) -> + {'reply', state(), call_reply()}. + +callback_call(#state{status = open, subscribe = Subscribers} = State, + Pid, Message) + when Message =:= 'subscribe'; + Message =:= 'unsubscribe' -> + NewState = + case Message of + subscribe -> + N = State#state.counter, + State#state{subscribe = [{Pid, N}|Subscribers], counter = N+1}; + unsubscribe -> + State#state{subscribe = lists:keydelete(Pid, 1, Subscribers)} + end, + {reply, NewState, accepted}; +callback_call(State, _Pid, _Message) -> + {reply, State, rejected}. + +-spec callback_exit(state()) -> 'ok'. + +callback_exit(_State) -> + ok. diff --git a/lib/dialyzer/test/behaviour_SUITE_data/src/callbacks_and_specs/my_callbacks_wrong.erl b/lib/dialyzer/test/behaviour_SUITE_data/src/callbacks_and_specs/my_callbacks_wrong.erl new file mode 100644 index 0000000000..0459622dc1 --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/src/callbacks_and_specs/my_callbacks_wrong.erl @@ -0,0 +1,61 @@ +-module(my_callbacks_wrong). + +-export([ + callback_init/1 + , callback_call/3 + , callback_cast/3 + , callback_exit/1 + ]). + +-behaviour(my_behaviour). + +-record(state, { + parent :: pid(), + status = init :: 'init' | 'open' | 'closed', + subscribe = [] :: list({pid(), integer()}), + counter = 1 :: integer() + }). + +-type state() :: #state{}. + +-type cast_message() :: 'open' | 'closed'. + +-type call_message() :: 'subscribe' | 'unsubscribe'. +-type call_reply() :: 'accepted' | 'rejected'. + +-spec callback_init(Parent::pid()) -> state(). %% Wrong return spec + +callback_init(Parent) -> #state{parent = Parent}. %% Wrong return + +-spec callback_cast(state(), pid() | atom(), cast_message()) -> + {'noreply' | 'reply', state()}. %% More generic spec + +callback_cast(#state{parent = Pid} = State, Pid, Message) + when Message =:= 'open'; Message =:= 'close' -> + {noreply, State#state{status = Message}}; +callback_cast(State, _Pid, _Message) -> + {noreply, State}. + +-spec callback_call(state(), atom(), call_message()) -> %% Wrong arg spec + {'reply', state(), call_reply()}. + +callback_call(#state{status = open, subscribe = Subscribers} = State, + Pid, Message) + when Message =:= 'subscribe'; + Message =:= 'unsubscribe' -> + NewState = + case Message of + subscribe -> + N = State#state.counter, + State#state{subscribe = [{Pid, N}|Subscribers], counter = N+1}; + unsubscribe -> + State#state{subscribe = lists:keydelete(Pid, 1, Subscribers)} + end, + {reply, NewState, accepted}; +callback_call(State, _Pid, _Message) -> + {reply, State, rejected}. + +-spec callback_exit(state()) -> ok. + +callback_exit(_State) -> + ok. diff --git a/lib/dialyzer/test/behaviour_SUITE_data/src/gen_event_incorrect_return.erl b/lib/dialyzer/test/behaviour_SUITE_data/src/gen_event_incorrect_return.erl new file mode 100644 index 0000000000..f5ccf7f8c4 --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/src/gen_event_incorrect_return.erl @@ -0,0 +1,33 @@ +-module(gen_event_incorrect_return). + +-behaviour(gen_event). + +-export([start_link/0, add_handler/0]). + +-export([init/1, handle_event/2, handle_call/2, + handle_info/2, terminate/2, code_change/3]). + +start_link() -> + gen_event:start_link({local, myserver}). + +add_handler() -> + gen_event:add_handler(myserver, ?MODULE, []). + +init([]) -> + error. + +handle_event(_Event, State) -> + {ok, State}. + +handle_call(_Request, State) -> + Reply = ok, + {ok, Reply, State}. + +handle_info(_Info, State) -> + {ok, State}. + +terminate(_Reason, _State) -> + ok. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. diff --git a/lib/dialyzer/test/behaviour_SUITE_data/src/gen_server_incorrect_args.erl b/lib/dialyzer/test/behaviour_SUITE_data/src/gen_server_incorrect_args.erl new file mode 100644 index 0000000000..df04dff80d --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/src/gen_server_incorrect_args.erl @@ -0,0 +1,11 @@ +-module(gen_server_incorrect_args). + +-behaviour(gen_server). + +-export([handle_call/3]). + +handle_call(_Request, From, _State) -> + case From of + 'boo' -> {'ok'}; + 'foo' -> {'no'} + end. diff --git a/lib/dialyzer/test/behaviour_SUITE_data/src/gen_server_missing_callbacks.erl b/lib/dialyzer/test/behaviour_SUITE_data/src/gen_server_missing_callbacks.erl new file mode 100644 index 0000000000..760466fdac --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/src/gen_server_missing_callbacks.erl @@ -0,0 +1,23 @@ +-module(gen_server_missing_callbacks). + +-behaviour(gen_server). + +-export([start_link/0]). + +-export([init/1, handle_call/3, terminate/2, code_change/3]). + +start_link() -> + gen_server:start_link({local, myserver}, ?MODULE, [], []). + +init([]) -> + ignore. + +handle_call(_Request, _From, State) -> + Reply = ok, + {reply, Reply, State}. + +terminate(_Reason, _State) -> + ok. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. diff --git a/lib/dialyzer/test/behaviour_SUITE_data/src/sample_behaviour/sample_behaviour.erl b/lib/dialyzer/test/behaviour_SUITE_data/src/sample_behaviour/sample_behaviour.erl new file mode 100644 index 0000000000..116980986b --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/src/sample_behaviour/sample_behaviour.erl @@ -0,0 +1,13 @@ +-module(sample_behaviour). + +-type custom() :: 1..42. + +-callback sample_callback_1() -> term(). +-callback sample_callback_2() -> atom(). +-callback sample_callback_3() -> {'ok', custom()} | 'fail'. + +-callback sample_callback_4(term()) -> 'ok'. +-callback sample_callback_5(custom()) -> 'ok' | 'fail'. + +-callback sample_callback_6(custom(), custom(), string()) -> + {'ok', custom()} | 'fail'. diff --git a/lib/dialyzer/test/behaviour_SUITE_data/src/sample_behaviour/sample_callback_correct.erl b/lib/dialyzer/test/behaviour_SUITE_data/src/sample_behaviour/sample_callback_correct.erl new file mode 100644 index 0000000000..ab0378e6f0 --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/src/sample_behaviour/sample_callback_correct.erl @@ -0,0 +1,32 @@ +-module(sample_callback_correct). + +-behaviour(sample_behaviour). + +-export([ + sample_callback_1/0, + sample_callback_2/0, + sample_callback_3/0, + sample_callback_4/1, + sample_callback_5/1, + sample_callback_6/3 + ]). + +sample_callback_1() -> 42. % This is a valid return. +sample_callback_2() -> foo. % This is a valid return. +sample_callback_3() -> {ok, 17}. % This is a valid return. +sample_callback_4(Input) -> + put(mine, Input+1), % This is valid handling of the input + ok. % This is a valid return. +sample_callback_5(Input) -> + case Input - 1 < 22 of % This is valid handling of the input + true -> ok; % This is a valid return. + false -> fail % This is a valid return. + end. +sample_callback_6(OldNr, NewNr, Reason) -> + Diff = NewNr - OldNr, % This is valid handling of the input + Msg = string:join(["Reason: ", Reason], ","), % This is valid handling of the input + case Diff > 0 of + true -> put(mine, {NewNr, Msg}), + {ok, NewNr}; % This is a valid return. + false -> fail % This is a valid return. + end. diff --git a/lib/dialyzer/test/behaviour_SUITE_data/src/sample_behaviour/sample_callback_correct_2.erl b/lib/dialyzer/test/behaviour_SUITE_data/src/sample_behaviour/sample_callback_correct_2.erl new file mode 100644 index 0000000000..c218174e58 --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/src/sample_behaviour/sample_callback_correct_2.erl @@ -0,0 +1,38 @@ +-module(sample_callback_correct_2). + +-behaviour(sample_behaviour). + +-export([ + sample_callback_1/0, + sample_callback_2/0, + sample_callback_3/0, + sample_callback_4/1, + sample_callback_5/1, + sample_callback_6/3, + common_infrastructure/1 + ]). + +sample_callback_1() -> 42. % This is a valid return. +sample_callback_2() -> halt(). % Crashes are also allowed. +sample_callback_3() -> {ok, 17}. % This is a valid return. +sample_callback_4(Input) -> + case Input of + 1 -> common_infrastructure(Input); % This is 'correct' input for + _ -> ok % common_infrastructure. + end. +sample_callback_5(Input) -> + case get(Input) of % This is valid handling of a more generic input + true -> ok; % This is a valid return. + false -> fail % This is a valid return. + end. +sample_callback_6(OldNr, NewNr, Reason) -> + Diff = NewNr - OldNr, % This is valid handling of the input + Msg = string:join(["Reason: ", Reason], ","), % This is valid handling of the input + case Diff > 0 of + true -> put(mine, {NewNr, Msg}), + {ok, NewNr}; % This is a valid return. + false -> fail % This is a valid return. + end. + +common_infrastructure( 1) -> 'ok'; +common_infrastructure(42) -> 'fail'. diff --git a/lib/dialyzer/test/behaviour_SUITE_data/src/sample_behaviour/sample_callback_wrong.erl b/lib/dialyzer/test/behaviour_SUITE_data/src/sample_behaviour/sample_callback_wrong.erl new file mode 100644 index 0000000000..02a063fab7 --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/src/sample_behaviour/sample_callback_wrong.erl @@ -0,0 +1,25 @@ +-module(sample_callback_wrong). + +-behaviour(sample_behaviour). + +-export([ +% sample_callback_1/0, + sample_callback_2/0, + sample_callback_3/0, + sample_callback_4/1, + sample_callback_5/1, + sample_callback_6/3 + ]). + +% sample_callback_1() -> 41. % We can't really break this contract so: missing! +sample_callback_2() -> 42. % This is not an atom(). +sample_callback_3() -> fair. % This is probably a typo. +sample_callback_4(_) -> % We cannot break the input. + fail. % We can definitely return a wrong value however. :) +sample_callback_5(Input) -> % Input is treated as an atom, result is a list. + atom_to_list(Input). % Both violate the contract. +sample_callback_6(OldNr, NewNr, Reason) -> + Diff = NewNr - OldNr, % This is valid handling of the input + %% Reason should have been treated as a string. + Msg = string:join(["Reason: ", atom_to_list(Reason)], ","), + {okk, NewNr}. %% This, too, is a typo. diff --git a/lib/dialyzer/test/behaviour_SUITE_data/src/sample_behaviour_old/correct_behaviour.erl b/lib/dialyzer/test/behaviour_SUITE_data/src/sample_behaviour_old/correct_behaviour.erl new file mode 100644 index 0000000000..90ce590997 --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/src/sample_behaviour_old/correct_behaviour.erl @@ -0,0 +1,6 @@ +%%% This is a behaviour with info about its calllbacks. + +-module(correct_behaviour). + +-callback foo() -> yes | no. +-callback bar({atom(),_},[_]) -> term(). diff --git a/lib/dialyzer/test/behaviour_SUITE_data/src/sample_behaviour_old/correct_callback.erl b/lib/dialyzer/test/behaviour_SUITE_data/src/sample_behaviour_old/correct_callback.erl new file mode 100644 index 0000000000..8f254520ab --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/src/sample_behaviour_old/correct_callback.erl @@ -0,0 +1,15 @@ +%%% This is a correct callback module for the correct_behaviour. + +-module(correct_callback). + +-behaviour(correct_behaviour). + +-export([foo/0, bar/2]). + +foo() -> + yes. + +bar({'query', 'boo'}, _Any) -> + no; +bar({'reply', [_R]}, [1,2,3]) -> + yes. diff --git a/lib/dialyzer/test/behaviour_SUITE_data/src/sample_behaviour_old/incorrect_args_callback.erl b/lib/dialyzer/test/behaviour_SUITE_data/src/sample_behaviour_old/incorrect_args_callback.erl new file mode 100644 index 0000000000..68fc60d418 --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/src/sample_behaviour_old/incorrect_args_callback.erl @@ -0,0 +1,13 @@ +%%% This is a correct callback module for the correct_behaviour. + +-module(incorrect_args_callback). + +-behaviour(correct_behaviour). + +-export([foo/0, bar/2]). + +foo() -> + yes. + +bar({'reply', _Any}, yes) -> %% Should be a tuple and a list. + yes. diff --git a/lib/dialyzer/test/behaviour_SUITE_data/src/sample_behaviour_old/incorrect_return_callback.erl b/lib/dialyzer/test/behaviour_SUITE_data/src/sample_behaviour_old/incorrect_return_callback.erl new file mode 100644 index 0000000000..9ff920cdd0 --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/src/sample_behaviour_old/incorrect_return_callback.erl @@ -0,0 +1,15 @@ +%%% This is a correct callback module for the correct_behaviour. + +-module(incorrect_return_callback). + +-behaviour(correct_behaviour). + +-export([foo/0, bar/2]). + +foo() -> + error. %% Should be 'yes' or 'no'. + +bar({'query', 'boo'}, _Any) -> + no; +bar({'reply', [_R]}, [1,2,3]) -> + yes. diff --git a/lib/dialyzer/test/behaviour_SUITE_data/src/sample_behaviour_old/missing_callback.erl b/lib/dialyzer/test/behaviour_SUITE_data/src/sample_behaviour_old/missing_callback.erl new file mode 100644 index 0000000000..e6c5306839 --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/src/sample_behaviour_old/missing_callback.erl @@ -0,0 +1,10 @@ +%%% This is a correct callback module for the correct_behaviour. + +-module(missing_callback). + +-behaviour(correct_behaviour). + +-export([bar/2]). + +bar({'reply', _Any}, []) -> + yes. diff --git a/lib/dialyzer/test/behaviour_SUITE_data/src/supervisor_incorrect_return.erl b/lib/dialyzer/test/behaviour_SUITE_data/src/supervisor_incorrect_return.erl new file mode 100644 index 0000000000..616a9073ae --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/src/supervisor_incorrect_return.erl @@ -0,0 +1,17 @@ +-module(supervisor_incorrect_return). + +-behaviour(supervisor). + +-export([start_link/0]). + +-export([init/1]). + +-define(SERVER, ?MODULE). + +start_link() -> + supervisor:start_link({local, ?SERVER}, ?MODULE, []). + +init([]) -> + AChild = {'AName',{'AModule',start_link,[]}, + permanent,2000,worker,['AModule']}, + {ok,{{one_against_one,0,1}, [AChild]}}. diff --git a/lib/dialyzer/test/behaviour_SUITE_data/src/undefined_callbacks/undefined_beh_callback.erl b/lib/dialyzer/test/behaviour_SUITE_data/src/undefined_callbacks/undefined_beh_callback.erl new file mode 100644 index 0000000000..8223225b4b --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/src/undefined_callbacks/undefined_beh_callback.erl @@ -0,0 +1,13 @@ +%%% This is a correct callback module for the correct_behaviour. + +-module(undefined_beh_callback). + +-behaviour(undefined_behaviour). + +-export([foo/0, bar/2]). + +foo() -> + yes. + +bar({'reply', _Any}, yes) -> + yes. diff --git a/lib/dialyzer/test/behaviour_SUITE_data/src/undefined_callbacks/undefined_behaviour.erl b/lib/dialyzer/test/behaviour_SUITE_data/src/undefined_callbacks/undefined_behaviour.erl new file mode 100644 index 0000000000..fb3d4c5e03 --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/src/undefined_callbacks/undefined_behaviour.erl @@ -0,0 +1,10 @@ +%%% This is a behaviour with undefined info about its calllbacks. + +-module(undefined_behaviour). + +-export([behaviour_info/1]). + +behaviour_info(callbacks) -> + [{foo, 0}, {bar, 2}]; +behaviour_info(_Other) -> + undefined. diff --git a/lib/dialyzer/test/behaviour_SUITE_data/src/vars_in_beh_spec.erl b/lib/dialyzer/test/behaviour_SUITE_data/src/vars_in_beh_spec.erl new file mode 100644 index 0000000000..dc75b30d0e --- /dev/null +++ b/lib/dialyzer/test/behaviour_SUITE_data/src/vars_in_beh_spec.erl @@ -0,0 +1,10 @@ +-module(vars_in_beh_spec). + +-behaviour(gen_server). + +-export([code_change/3]). + +-spec code_change(_, State, _) -> {ok, State}. + +code_change(_, State, _) -> + {ok, State}. diff --git a/lib/dialyzer/test/r9c_SUITE_data/results/inets b/lib/dialyzer/test/r9c_SUITE_data/results/inets index 0177dcc88c..24cb39e52b 100644 --- a/lib/dialyzer/test/r9c_SUITE_data/results/inets +++ b/lib/dialyzer/test/r9c_SUITE_data/results/inets @@ -3,21 +3,15 @@ ftp.erl:1243: The pattern {'ok', {N, Bytes}} can never match the type 'eof' | {' ftp.erl:640: The pattern {'closed', _Why} can never match the type 'perm_fname_not_allowed' | 'perm_neg_compl' | 'perm_no_space' | 'pos_compl' | 'pos_interm' | 'pos_interm_acct' | 'trans_neg_compl' | 'trans_no_space' | {'error' | 'perm_fname_not_allowed' | 'perm_neg_compl' | 'perm_no_space' | 'pos_compl' | 'pos_interm' | 'pos_interm_acct' | 'pos_prel' | 'trans_neg_compl' | 'trans_no_space',atom() | [any()] | {'invalid_server_response',[any(),...]}} http.erl:117: The pattern {'error', Reason} can never match the type #req_headers{connection::[45 | 97 | 101 | 105 | 107 | 108 | 112 | 118,...],content_length::[48,...],other::[{_,_}]} http.erl:138: Function close_session/2 will never be called -http_lib.erl:286: The call http_lib:close('ip_comm' | {'ssl',_},port() | {'sslsocket',_,_}) will never return since it differs in the 1st argument from the success typing arguments: ('http' | 'https',port() | {'sslsocket',_,pid() | {_,{'config',_,_,_,_,{_,_,_,_}}} | {'sslsocket',_,pid() | {'sslsocket',_,pid() | {_,_,_}}}}) -http_lib.erl:415: The pattern 61 can never match the type 'http_eoh' | binary() | maybe_improper_list(any(),binary() | []) | {'http_error',binary() | string()} | #http_request{method::'DELETE' | 'GET' | 'HEAD' | 'OPTIONS' | 'POST' | 'PUT' | 'TRACE' | binary() | string(),path::'*' | binary() | string() | {'abs_path',binary() | string()} | {'scheme',binary() | string(),binary() | string()} | {'absoluteURI','http' | 'https',binary() | string(),'undefined' | non_neg_integer(),binary() | string()},version::{non_neg_integer(),non_neg_integer()}} | #http_response{version::{non_neg_integer(),non_neg_integer()},status::integer(),phrase::binary() | string()} | {'http_header',integer(),atom() | binary() | string(),_,binary() | string()} -http_lib.erl:417: The pattern 59 can never match the type 'http_eoh' | binary() | maybe_improper_list(any(),binary() | []) | {'http_error',binary() | string()} | #http_request{method::'DELETE' | 'GET' | 'HEAD' | 'OPTIONS' | 'POST' | 'PUT' | 'TRACE' | binary() | string(),path::'*' | binary() | string() | {'abs_path',binary() | string()} | {'scheme',binary() | string(),binary() | string()} | {'absoluteURI','http' | 'https',binary() | string(),'undefined' | non_neg_integer(),binary() | string()},version::{non_neg_integer(),non_neg_integer()}} | #http_response{version::{non_neg_integer(),non_neg_integer()},status::integer(),phrase::binary() | string()} | {'http_header',integer(),atom() | binary() | string(),_,binary() | string()} -http_lib.erl:420: The pattern 13 can never match the type 'http_eoh' | binary() | maybe_improper_list(any(),binary() | []) | {'http_error',binary() | string()} | #http_request{method::'DELETE' | 'GET' | 'HEAD' | 'OPTIONS' | 'POST' | 'PUT' | 'TRACE' | binary() | string(),path::'*' | binary() | string() | {'abs_path',binary() | string()} | {'scheme',binary() | string(),binary() | string()} | {'absoluteURI','http' | 'https',binary() | string(),'undefined' | non_neg_integer(),binary() | string()},version::{non_neg_integer(),non_neg_integer()}} | #http_response{version::{non_neg_integer(),non_neg_integer()},status::integer(),phrase::binary() | string()} | {'http_header',integer(),atom() | binary() | string(),_,binary() | string()} -http_lib.erl:424: The variable _ can never match since previous clauses completely covered the type 'http_eoh' | binary() | maybe_improper_list(any(),binary() | []) | {'http_error',binary() | string()} | #http_request{method::'DELETE' | 'GET' | 'HEAD' | 'OPTIONS' | 'POST' | 'PUT' | 'TRACE' | binary() | string(),path::'*' | binary() | string() | {'abs_path',binary() | string()} | {'scheme',binary() | string(),binary() | string()} | {'absoluteURI','http' | 'https',binary() | string(),'undefined' | non_neg_integer(),binary() | string()},version::{non_neg_integer(),non_neg_integer()}} | #http_response{version::{non_neg_integer(),non_neg_integer()},status::integer(),phrase::binary() | string()} | {'http_header',integer(),atom() | binary() | string(),_,binary() | string()} -http_lib.erl:428: Function read_chunk_ext_val/6 will never be called -http_lib.erl:444: The pattern 10 can never match the type 'http_eoh' | binary() | maybe_improper_list(any(),binary() | []) | {'http_error',binary() | string()} | #http_request{method::'DELETE' | 'GET' | 'HEAD' | 'OPTIONS' | 'POST' | 'PUT' | 'TRACE' | binary() | string(),path::'*' | binary() | string() | {'abs_path',binary() | string()} | {'scheme',binary() | string(),binary() | string()} | {'absoluteURI','http' | 'https',binary() | string(),'undefined' | non_neg_integer(),binary() | string()},version::{non_neg_integer(),non_neg_integer()}} | #http_response{version::{non_neg_integer(),non_neg_integer()},status::integer(),phrase::binary() | string()} | {'http_header',integer(),atom() | binary() | string(),_,binary() | string()} -http_lib.erl:552: Call to missing or unexported function ssl:accept/2 +http_lib.erl:286: The call http_lib:close('ip_comm' | {'ssl',_},any()) will never return since it differs in the 1st argument from the success typing arguments: ('http' | 'https',any()) +http_lib.erl:424: The variable _ can never match since previous clauses completely covered the type any() +http_lib.erl:438: The variable _ can never match since previous clauses completely covered the type any() http_lib.erl:99: Function getHeaderValue/2 will never be called httpc_handler.erl:660: Function exit_session_ok/2 has no local return httpc_manager.erl:145: The pattern {ErrorReply, State2} can never match the type {{'ok',number()},number(),#state{reqid::number()}} httpc_manager.erl:160: The pattern {ErrorReply, State2} can never match the type {{'ok',number()},number(),#state{reqid::number()}} httpc_manager.erl:478: The pattern {'error', Reason} can never match the type 'ok' | {number(),#session{clientclose::boolean(),pipeline::[],quelength::1}} httpc_manager.erl:490: The pattern {'error', Reason} can never match the type 'ok' | {number(),#session{clientclose::boolean(),pipeline::[],quelength::1}} -httpd.erl:583: The pattern <{'error', Reason}, _Fd, SoFar> can never match the type <[any()],pid(),[[any(),...]]> httpd_acceptor.erl:105: The pattern {'error', Reason} can never match the type {'ok',pid()} httpd_acceptor.erl:110: Function handle_connection_err/4 will never be called httpd_acceptor.erl:168: Function report_error/2 will never be called @@ -26,14 +20,10 @@ httpd_manager.erl:885: The pattern {'EXIT', Reason} can never match since previo httpd_manager.erl:919: Function auth_status/1 will never be called httpd_manager.erl:926: Function sec_status/1 will never be called httpd_manager.erl:933: Function acceptor_status/1 will never be called -httpd_request_handler.erl:374: The call httpd_response:send_status(Info::#mod{parsed_header::maybe_improper_list()},417,[32 | 66 | 98 | 100 | 103 | 105 | 111 | 116 | 121,...]) will never return since it differs in the 2nd argument from the success typing arguments: (#mod{socket_type::'ip_comm' | {'ssl',_},socket::port() | {'sslsocket',_,_}},100 | 301 | 304 | 400 | 401 | 403 | 404 | 412 | 414 | 416 | 500 | 501 | 503,any()) -httpd_request_handler.erl:378: The call httpd_response:send_status(Info::#mod{parsed_header::maybe_improper_list()},417,[32 | 77 | 97 | 100 | 101 | 104 | 108 | 110 | 111 | 116 | 119,...]) will never return since it differs in the 2nd argument from the success typing arguments: (#mod{socket_type::'ip_comm' | {'ssl',_},socket::port() | {'sslsocket',_,_}},100 | 301 | 304 | 400 | 401 | 403 | 404 | 412 | 414 | 416 | 500 | 501 | 503,any()) -httpd_request_handler.erl:401: The call httpd_response:send_status(Info::#mod{parsed_header::maybe_improper_list()},417,[32 | 77 | 97 | 100 | 101 | 104 | 108 | 110 | 111 | 116 | 119,...]) will never return since it differs in the 2nd argument from the success typing arguments: (#mod{socket_type::'ip_comm' | {'ssl',_},socket::port() | {'sslsocket',_,_}},100 | 301 | 304 | 400 | 401 | 403 | 404 | 412 | 414 | 416 | 500 | 501 | 503,any()) -httpd_request_handler.erl:489: The variable Other can never match since previous clauses completely covered the type {'error',_} | {'ok','http_eoh' | binary() | maybe_improper_list(any(),binary() | []) | {'http_error',binary() | string()} | {'http_request','DELETE' | 'GET' | 'HEAD' | 'OPTIONS' | 'POST' | 'PUT' | 'TRACE' | binary() | string(),'*' | binary() | string() | {'abs_path',binary() | [any()]} | {'scheme',binary() | [any()],binary() | [any()]} | {'absoluteURI','http' | 'https',binary() | [any()],'undefined' | non_neg_integer(),binary() | [any()]},{non_neg_integer(),non_neg_integer()}} | {'http_response',{non_neg_integer(),non_neg_integer()},integer(),binary() | string()} | {'http_header',integer(),atom() | binary() | string(),_,binary() | string()}} -httpd_request_handler.erl:644: The call lists:reverse(Fields0::{'error',_} | {'ok',_}) will never return since it differs in the 1st argument from the success typing arguments: ([any()]) -httpd_request_handler.erl:645: Function will never be called -httpd_socket.erl:129: Call to missing or unexported function ssl:accept/2 -httpd_socket.erl:49: The pattern {'ok', _} can never match the type {'error',_} +httpd_request_handler.erl:374: The call httpd_response:send_status(Info::#mod{parsed_header::maybe_improper_list()},417,[32 | 66 | 98 | 100 | 103 | 105 | 111 | 116 | 121,...]) will never return since it differs in the 2nd argument from the success typing arguments: (#mod{socket_type::'ip_comm' | {'ssl',_}},100 | 301 | 304 | 400 | 401 | 403 | 404 | 412 | 414 | 416 | 500 | 501 | 503,any()) +httpd_request_handler.erl:378: The call httpd_response:send_status(Info::#mod{parsed_header::maybe_improper_list()},417,[32 | 77 | 97 | 100 | 101 | 104 | 108 | 110 | 111 | 116 | 119,...]) will never return since it differs in the 2nd argument from the success typing arguments: (#mod{socket_type::'ip_comm' | {'ssl',_}},100 | 301 | 304 | 400 | 401 | 403 | 404 | 412 | 414 | 416 | 500 | 501 | 503,any()) +httpd_request_handler.erl:401: The call httpd_response:send_status(Info::#mod{parsed_header::maybe_improper_list()},417,[32 | 77 | 97 | 100 | 101 | 104 | 108 | 110 | 111 | 116 | 119,...]) will never return since it differs in the 2nd argument from the success typing arguments: (#mod{socket_type::'ip_comm' | {'ssl',_}},100 | 301 | 304 | 400 | 401 | 403 | 404 | 412 | 414 | 416 | 500 | 501 | 503,any()) +httpd_request_handler.erl:649: Guard test [{_,_}] =:= Trailers::nonempty_string() can never succeed httpd_sup.erl:63: The variable Else can never match since previous clauses completely covered the type {'error',_} | {'ok',[any()],_,_} httpd_sup.erl:88: The pattern {'error', Reason} can never match the type {'ok',_,_} httpd_sup.erl:92: The variable Else can never match since previous clauses completely covered the type {'ok',_,_} @@ -48,10 +38,10 @@ mod_dir.erl:72: The pattern {'error', Reason} can never match the type {'ok',[[[ mod_get.erl:135: The pattern <{'enfile', _}, _Info, Path> can never match the type <atom(),#mod{},atom() | binary() | [atom() | [any()] | char()]> mod_head.erl:80: The pattern <{'enfile', _}, _Info, Path> can never match the type <atom(),#mod{},atom() | binary() | [atom() | [any()] | char()]> mod_htaccess.erl:460: The pattern {'error', BadData} can never match the type {'ok',_} -mod_include.erl:193: The pattern {_, Name, {[], []}} can never match the type {[any()],[any()],string()} -mod_include.erl:195: The pattern {_, Name, {PathInfo, []}} can never match the type {[any()],[any()],string()} -mod_include.erl:197: The pattern {_, Name, {PathInfo, QueryString}} can never match the type {[any()],[any()],string()} -mod_include.erl:201: The variable Gurka can never match since previous clauses completely covered the type {[any()],[any()],string()} +mod_include.erl:193: The pattern {_, Name, {[], []}} can never match the type {[any()],[any()],maybe_improper_list()} +mod_include.erl:195: The pattern {_, Name, {PathInfo, []}} can never match the type {[any()],[any()],maybe_improper_list()} +mod_include.erl:197: The pattern {_, Name, {PathInfo, QueryString}} can never match the type {[any()],[any()],maybe_improper_list()} +mod_include.erl:201: The variable Gurka can never match since previous clauses completely covered the type {[any()],[any()],maybe_improper_list()} mod_include.erl:692: The pattern <{'read', Reason}, Info, Path> can never match the type <{'open',atom()},#mod{},atom() | binary() | [atom() | [any()] | char()]> mod_include.erl:706: The pattern <{'enfile', _}, _Info, Path> can never match the type <atom(),#mod{},atom() | binary() | [atom() | [any()] | char()]> mod_include.erl:716: Function read_error/3 will never be called diff --git a/lib/dialyzer/test/r9c_SUITE_data/results/mnesia b/lib/dialyzer/test/r9c_SUITE_data/results/mnesia index 2be71ac7d7..b397d37523 100644 --- a/lib/dialyzer/test/r9c_SUITE_data/results/mnesia +++ b/lib/dialyzer/test/r9c_SUITE_data/results/mnesia @@ -2,6 +2,7 @@ mnesia.erl:1319: Guard test size(Spec::[{_,_,_},...]) can never succeed mnesia.erl:1498: The call mnesia:bad_info_reply(Tab::atom(),Item::'type') will never return since it differs in the 2nd argument from the success typing arguments: (atom(),'memory' | 'size') mnesia.erl:331: Function mod2abs/1 has no local return +mnesia_backup.erl:49: Callback info about the mnesia_backup behaviour is not available mnesia_bup.erl:111: The created fun has no local return mnesia_bup.erl:574: Function fallback_receiver/2 has no local return mnesia_bup.erl:967: Function uninstall_fallback_master/2 has no local return @@ -12,9 +13,12 @@ mnesia_controller.erl:1679: The pattern {'stop', Reason, Reply, State2} can neve mnesia_controller.erl:1685: The pattern {'noreply', State2, _Timeout} can never match the type {'reply',_,_} mnesia_event.erl:77: The pattern 'remove_handler' can never match the type {'ok',_} mnesia_event.erl:79: The pattern {'swap_handler', Args1, State1, Mod2, Args2} can never match the type {'ok',_} +mnesia_frag.erl:26: Callback info about the mnesia_access behaviour is not available mnesia_frag.erl:294: The call mnesia_frag:remote_collect(Ref::reference(),{'error',_},[],OldSelectFun::fun(() -> [any()])) will never return since it differs in the 2nd argument from the success typing arguments: (reference(),'ok',[any()],fun(() -> [any()])) mnesia_frag.erl:304: The call mnesia_frag:remote_collect(Ref::reference(),{'error',{'node_not_running',_}},[],OldSelectFun::fun(() -> [any()])) will never return since it differs in the 2nd argument from the success typing arguments: (reference(),'ok',[any()],fun(() -> [any()])) mnesia_frag.erl:312: The call mnesia_frag:remote_collect(Ref::reference(),LocalRes::{'error',_},[],OldSelectFun::fun(() -> [any()])) will never return since it differs in the 2nd argument from the success typing arguments: (reference(),'ok',[any()],fun(() -> [any()])) +mnesia_frag_hash.erl:24: Callback info about the mnesia_frag_hash behaviour is not available +mnesia_frag_old_hash.erl:23: Callback info about the mnesia_frag_hash behaviour is not available mnesia_index.erl:52: The call mnesia_lib:other_val(Var::{_,'commit_work' | 'index' | 'setorbag' | 'storage_type' | {'index',_}},_ReASoN_::any()) will never return since it differs in the 1st argument from the success typing arguments: ({_,'active_replicas' | 'where_to_read' | 'where_to_write'},any()) mnesia_lib.erl:1028: The pattern {'EXIT', Reason} can never match the type [any()] | {'error',_} mnesia_lib.erl:957: The pattern {'ok', {0, _}} can never match the type 'eof' | {'error',atom()} | {'ok',binary() | string()} diff --git a/lib/dialyzer/test/small_SUITE_data/src/maybe_improper.erl b/lib/dialyzer/test/small_SUITE_data/src/maybe_improper.erl new file mode 100644 index 0000000000..1743d81493 --- /dev/null +++ b/lib/dialyzer/test/small_SUITE_data/src/maybe_improper.erl @@ -0,0 +1,7 @@ +-module(maybe_improper). + +-export([s/1]). + +-spec s(maybe_improper_list(X,Y)) -> {[X], maybe_improper_list(X,Y)}. +s(A) -> + lists:split(2,A). diff --git a/lib/dialyzer/test/underspecs_SUITE_data/dialyzer_options b/lib/dialyzer/test/underspecs_SUITE_data/dialyzer_options new file mode 100644 index 0000000000..f7197ac30f --- /dev/null +++ b/lib/dialyzer/test/underspecs_SUITE_data/dialyzer_options @@ -0,0 +1 @@ +{dialyzer_options, [{warnings, [underspecs]}]}. diff --git a/lib/dialyzer/test/underspecs_SUITE_data/results/remote b/lib/dialyzer/test/underspecs_SUITE_data/results/remote new file mode 100644 index 0000000000..1e0cda3bde --- /dev/null +++ b/lib/dialyzer/test/underspecs_SUITE_data/results/remote @@ -0,0 +1,9 @@ + +remotes1.erl:17: The specification for remotes1:foo5/1 states that the function might also return 'ko' but the inferred return is 'ok' +remotes1.erl:20: Type specification remotes1:foo6('ok' | 'ko') -> 'ok' is a supertype of the success typing: remotes1:foo6('ok') -> 'ok' +remotes1.erl:25: The specification for remotes1:foo7/1 states that the function might also return 'ko' but the inferred return is 'ok' +remotes1.erl:28: Type specification remotes1:foo8(local_type_42()) -> 'ok' is a supertype of the success typing: remotes1:foo8('ok') -> 'ok' +remotes1.erl:33: The specification for remotes1:foo9/1 states that the function might also return 'ko' but the inferred return is 'ok' +remotes1.erl:36: Type specification remotes1:foo10(local_and_known_remote_type_42()) -> 'ok' is a supertype of the success typing: remotes1:foo10('ok') -> 'ok' +remotes1.erl:49: Type specification remotes1:foo13('ok') -> local_and_unknown_remote_type_42() is a supertype of the success typing: remotes1:foo13('ok') -> 'ok' +remotes1.erl:52: Type specification remotes1:foo14(local_and_unknown_remote_type_42()) -> 'ok' is a supertype of the success typing: remotes1:foo14('ok') -> 'ok' diff --git a/lib/dialyzer/test/underspecs_SUITE_data/src/remote/remotes1.erl b/lib/dialyzer/test/underspecs_SUITE_data/src/remote/remotes1.erl new file mode 100644 index 0000000000..b722495095 --- /dev/null +++ b/lib/dialyzer/test/underspecs_SUITE_data/src/remote/remotes1.erl @@ -0,0 +1,61 @@ +-module(remotes1). + +-compile(export_all). + +-spec foo1(some_unknown_remote:type42()) -> ok. +foo1(ok) -> ok. + +-spec foo2(ok) -> some_unknown_remote:type42(). +foo2(ok) -> ok. + +-spec foo3(some_known_remote:type42()) -> ok. +foo3(ok) -> ok. + +-spec foo4(ok) -> some_known_remote:type42(). +foo4(ok) -> ok. + +-spec foo5(ok|ko) -> ok|ko. +foo5(ok) -> ok. + +-spec foo6(ok|ko) -> ok. +foo6(ok) -> ok. + +-type local_type_42() :: ok | ko. + +-spec foo7(ok) -> local_type_42(). +foo7(ok) -> ok. + +-spec foo8(local_type_42()) -> ok. +foo8(ok) -> ok. + +-type local_and_known_remote_type_42() :: some_known_remote:type42() | ok | ko. + +-spec foo9(ok) -> local_and_known_remote_type_42(). +foo9(ok) -> ok. + +-spec foo10(local_and_known_remote_type_42()) -> ok. +foo10(ok) -> ok. + +-type local_and_ok_known_remote_type_42() :: some_known_remote:type42() | ok. + +-spec foo11(ok) -> local_and_ok_known_remote_type_42(). +foo11(ok) -> ok. + +-spec foo12(local_and_ok_known_remote_type_42()) -> ok. +foo12(ok) -> ok. + +-type local_and_unknown_remote_type_42() :: some_unknown_remote:type42() | ok | ko. + +-spec foo13(ok) -> local_and_unknown_remote_type_42(). +foo13(ok) -> ok. + +-spec foo14(local_and_unknown_remote_type_42()) -> ok. +foo14(ok) -> ok. + +-type local_and_ok_unknown_remote_type_42() :: some_unknown_remote:type42() | ok. + +-spec foo15(ok) -> local_and_ok_unknown_remote_type_42(). +foo15(ok) -> ok. + +-spec foo16(local_and_ok_unknown_remote_type_42()) -> ok. +foo16(ok) -> ok. diff --git a/lib/dialyzer/test/underspecs_SUITE_data/src/remote/some_known_remote.erl b/lib/dialyzer/test/underspecs_SUITE_data/src/remote/some_known_remote.erl new file mode 100644 index 0000000000..437f1e7826 --- /dev/null +++ b/lib/dialyzer/test/underspecs_SUITE_data/src/remote/some_known_remote.erl @@ -0,0 +1,5 @@ +-module(some_known_remote). + +-export_type([type42/0]). + +-type type42() :: ok | ko. diff --git a/lib/diameter/src/base/diameter_service.erl b/lib/diameter/src/base/diameter_service.erl index b36160148b..0893956f97 100644 --- a/lib/diameter/src/base/diameter_service.erl +++ b/lib/diameter/src/base/diameter_service.erl @@ -646,11 +646,6 @@ mod_state(Alias) -> mod_state(Alias, ModS) -> put({?MODULE, mod_state, Alias}, ModS). -%% have_transport/2 - -have_transport(SvcName, Ref) -> - [] /= diameter_config:have_transport(SvcName, Ref). - %%% --------------------------------------------------------------------------- %%% # shutdown/2 %%% --------------------------------------------------------------------------- @@ -1130,7 +1125,7 @@ start_tc(Tc, T, _) -> %% tc_timeout/2 tc_timeout({Ref, _Type, _Opts} = T, #state{service_name = SvcName} = S) -> - tc(have_transport(SvcName, Ref), T, S). + tc(diameter_config:have_transport(SvcName, Ref), T, S). tc(true, {Ref, Type, Opts}, #state{service_name = SvcName} = S) -> @@ -1158,7 +1153,7 @@ close(Pid, #state{service_name = SvcName, options = Opts} = fetch(PeerT, Pid), - c(Pid, have_transport(SvcName, Ref), Opts). + c(Pid, diameter_config:have_transport(SvcName, Ref), Opts). %% Tell watchdog to (maybe) die later ... c(Pid, true, Opts) -> diff --git a/lib/diameter/vsn.mk b/lib/diameter/vsn.mk index b1d3ba2241..0c240798cc 100644 --- a/lib/diameter/vsn.mk +++ b/lib/diameter/vsn.mk @@ -18,7 +18,7 @@ # %CopyrightEnd% APPLICATION = diameter -DIAMETER_VSN = 0.11 +DIAMETER_VSN = 1.0 PRE_VSN = APP_VSN = "$(APPLICATION)-$(DIAMETER_VSN)$(PRE_VSN)" diff --git a/lib/docbuilder/AUTHORS b/lib/docbuilder/AUTHORS deleted file mode 100644 index 4f2a8e9361..0000000000 --- a/lib/docbuilder/AUTHORS +++ /dev/null @@ -1,10 +0,0 @@ -Docbuilder is a rewrite of the Old docbuilder -and takes XML as input instead of SGML. -Docbuilder makes use of xmerl for parsing XML -and produces HTML. Everything is written in Erlang -and there are no dependencies to external tools. - -Original Authors: -Gunilla Arendt - -Contributors: diff --git a/lib/docbuilder/Makefile b/lib/docbuilder/Makefile deleted file mode 100644 index 21f42421d6..0000000000 --- a/lib/docbuilder/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -# ``The contents of this file are subject to the Erlang Public License, -# Version 1.1, (the "License"); you may not use this file except in -# compliance with the License. You should have received a copy of the -# Erlang Public License along with this software. If not, it can be -# retrieved via the world wide web at http://www.erlang.org/. -# -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -# the License for the specific language governing rights and limitations -# under the License. -# -# The Initial Developer of the Original Code is Ericsson Utvecklings AB. -# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings -# AB. All Rights Reserved.'' -# -# $Id$ -# -include $(ERL_TOP)/make/target.mk -include $(ERL_TOP)/make/$(TARGET)/otp.mk - -# -# Macros -# - -SUB_DIRECTORIES = src dtd etc doc/src - -include vsn.mk -VSN = $(DOCB_VSN) - -SPECIAL_TARGETS = - -# -# Default Subdir Targets -# -include $(ERL_TOP)/make/otp_subdir.mk - - diff --git a/lib/docbuilder/doc/pdf/.gitignore b/lib/docbuilder/doc/pdf/.gitignore deleted file mode 100644 index e69de29bb2..0000000000 --- a/lib/docbuilder/doc/pdf/.gitignore +++ /dev/null diff --git a/lib/docbuilder/doc/src/book.xml b/lib/docbuilder/doc/src/book.xml deleted file mode 100644 index a13d56dd8a..0000000000 --- a/lib/docbuilder/doc/src/book.xml +++ /dev/null @@ -1,50 +0,0 @@ -<?xml version="1.0" encoding="latin1" ?> -<!DOCTYPE book SYSTEM "book.dtd"> - -<book xmlns:xi="http://www.w3.org/2001/XInclude"> - <header titlestyle="normal"> - <copyright> - <year>1997</year><year>2009</year> - <holder>Ericsson AB. All Rights Reserved.</holder> - </copyright> - <legalnotice> - The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved online at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - the License for the specific language governing rights and limitations - under the License. - - </legalnotice> - - <title>DocBuilder</title> - <prepared></prepared> - <docno></docno> - <date></date> - <rev></rev> - </header> - <insidecover> - </insidecover> - <pagetext>Docbuilder</pagetext> - <preamble> - <contents level="2"></contents> - </preamble> - <parts lift="no"> - <xi:include href="part.xml"/> - </parts> - <applications> - <xi:include href="ref_man.xml"/> - </applications> - <releasenotes> - <xi:include href="notes.xml"/> - </releasenotes> - <listoffigures></listoffigures> - <listoftables></listoftables> - <listofterms></listofterms> - <index></index> -</book> - diff --git a/lib/docbuilder/doc/src/docb_gen.xml b/lib/docbuilder/doc/src/docb_gen.xml deleted file mode 100644 index d4ebfd0f84..0000000000 --- a/lib/docbuilder/doc/src/docb_gen.xml +++ /dev/null @@ -1,213 +0,0 @@ -<?xml version="1.0" encoding="iso-8859-1" ?> -<!DOCTYPE erlref SYSTEM "erlref.dtd"> - -<erlref> - <header> - <copyright> - <year>1999</year> - <year>2011</year> - <holder>Ericsson AB, All Rights Reserved</holder> - </copyright> - <legalnotice> - The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved online at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - the License for the specific language governing rights and limitations - under the License. - - The Initial Developer of the Original Code is Ericsson AB. - </legalnotice> - <title>docb_gen</title> - <prepared></prepared> - <docno></docno> - <date></date> - <rev></rev> - </header> - <module>docb_gen</module> - <modulesummary>Generate XML from EDoc comments in Erlang source code. - </modulesummary> - - <description> - <p><c>docb_gen</c> contains functions for generating XML - documentation source code according to the <c>erlref</c> or - <c>chapter</c> DTD from - <seealso marker="edoc:chapter">EDoc</seealso> comments in Erlang - source code or an <c>overview.edoc</c> file, using EDoc.</p> - </description> - - <funcs> - <func> - <name>module(File) -> ok | {error, Reason}</name> - <name>module(File, Options) -> ok | {error, Reason}</name> - <fsummary>Generate XML from EDoc comments in Erlang source code. - </fsummary> - <type> - <v>File = string()</v> - <v>Options = [Opt]</v> - <v>Opt = {def,Defs} | {includes,Dirs} | {preprocess,Bool} - | {sort_functions,Bool}</v> - <v>Defs = [{atom(),string()}]</v> - <v>Dirs = [string()]</v> - <v>Bool = bool()</v> - <v>Reason = badfile | {badopt,term()} | term()</v> - </type> - <desc> - <p>Generates XML documentation source code according to - the <c>erlref</c> DTD from EDoc comments <c>File</c>, using - the EDoc application.</p> - - <p><c>File</c> is an Erlang source file, given with or without - the <c>.erl</c> extension as <c>Name.erl</c> or <c>Name</c>. - The resulting XML file is created in the current working - directory and named <c>Name.xml</c>.</p> - - <p><c>Options</c> is a list of options, see below.</p> - - <p>Returns <c>ok</c> if successful, and an error tuple - otherwise.</p> - </desc> - </func> - - <func> - <name>users_guide(File) -> ok | {error, Reason}</name> - <name>users_guide(File, Options) -> ok | {error, Reason}</name> - <fsummary>Generate XML from EDoc comments in Erlang source code - </fsummary> - <type> - <v>File -- see module/1,2</v> - <v>Options -- see module/1,2</v> - <v>Reason -- see module/1,2</v> - </type> - <desc> - <p>Like <c>module/1,2</c> but generates XML source code - according to the <c>chapter</c> DTD from an - <c>overview.edoc</c> or similar file.</p> - - <p>The resulting file is named <c>chapter.xml</c>.</p> - </desc> - </func> - </funcs> - - <section> - <title>Options</title> - <taglist> - <tag><c>{def, [{Name,Text}]}</c></tag> - <item>Specifies EDoc macro definitions. See - <seealso marker="edoc:edoc">edoc:get_doc/2</seealso>.</item> - - <tag><c>{includes, [Dir]}</c></tag> - <item>Specifies directories where EDoc should search for include - files. See - <seealso marker="edoc:edoc">edoc:read_source/2</seealso>.</item> - - <tag><c>{preprocess, true|false}</c></tag> - <item>Specifies if EDoc should read the source file via the Erlang - preprocessor. Default is <c>false</c>. See - <seealso marker="edoc:edoc">edoc:read_source/2</seealso>.</item> - - <tag><c>{sort_functions, true|false}</c></tag> - <item>Specifies if the functions in the resulting XML file should - be sorted alphabetically. Default is <c>true</c>.</item> - </taglist> - </section> - - <section> - <title>Limitations</title> - <p>The mapping from the EDoc XHTML output to valid Erlang/OTP XML - is not complete. An attempt has been made to cover the most - commonly used XHTML constructs, but there will still be cases - where XML generation fails or where the resulting XML is - inadequate. This is especially true for <c>users_guide/1,2</c>. - </p> - - <p>Known limitations for some XHTML tags:</p> - <taglist> - <tag><c><![CDATA[<a>]]></c></tag> - <item> - <p>All attributes except the first <c>href</c> or <c>name</c> - attribute are ignored.</p> - <p>A <c>href</c> attribute means the <c><![CDATA[<a>]]></c> tag - will be transformed to a <c><![CDATA[<seealso>]]></c> or - <c><![CDATA[<url>]]></c> tag and an attempt is made to - resolve the reference if necessary.</p> - - <p>A <c>name</c> attribute means the <c><![CDATA[<a>]]></c> tag - will be transformed to a <c><![CDATA[<marker>]]></c> tag.</p> - </item> - - <tag><c><![CDATA[<b>, <em>, <pre>]]></c></tag> - <item>Cannot contain other tags in Erlang/OTP XML, content is - converted to plain text. - </item> - - <tag><c><![CDATA[<center>]]></c></tag> - <item>No corresponding Erlang/OTP XML tag, converted to plain - text. - </item> - - <tag><c><![CDATA[<font>]]></c></tag> - <item>No corresponding Erlang/OTP XML tag, converted to plain - text. - </item> - - <tag><c><![CDATA[<h1>, <h2>, ...]]></c></tag> - <item>There is no tag corresponding to a header in Erlang/OTP XML, - so these are converted to plain text instead, with - the exception of <c><![CDATA[<h3>]]></c> and - <c><![CDATA[<h4>]]></c> tags within <c>overview.edoc</c>, see - part about "<c>chapter</c> DTD" below. - </item> - - <tag><c><![CDATA[<sup>]]></c></tag> - <item>There is no tag corresponding to superscript in Erlang/OTP - XML, so this is converted to plain text within brackets "(..)". - </item> - - <tag>References</tag> - <item>The markers automatically inserted by EDoc at each heading - and function will override the markers automatically inserted - by DocBuilder, with the unfortunate result that the links in - the left-hand frame of the User's Guide will not work, and - also that cross referencing a function in a module the usual - Erlang/OTP way - "<c><![CDATA[<seealso marker="edoc:edoc#run/3...>]]></c>" does - not work. (But - "<c><![CDATA[<seealso marker="edoc:edoc#run-3...>]]></c>" does.) - </item> - </taglist> - - <p><em>erlref DTD</em></p> - <taglist> - <tag>Tables</tag> - <item>Tables are not allowed. The contents of a table is - converted to text instead, each row corresponding to one line - of text. - </item> - </taglist> - - <p><em>chapter DTD</em></p> - <taglist> - <tag>Sections</tag> - <item>Only two levels of sections. <c><![CDATA[<h3>]]></c> - (equivalent to EDoc headings "<c>== Heading ==</c>") is - interpreted as start of top-level section, or if there is no - <c><![CDATA[<h3>]]></c> tag, the entire document is made into - one top-level section. <c><![CDATA[<h4>]]></c> (equivalent to - EDoc sub-headings ("<c><![CDATA[=== Sub-heading ===]]></c>") is - interpreted as start of second-level section. - </item> - - <tag>Tables</tag> - <item>Tables without borders are converted to text in the same - manner as for the <c>erlref</c> DTD. - </item> - </taglist> - </section> - -</erlref> - diff --git a/lib/docbuilder/doc/src/docb_transform.xml b/lib/docbuilder/doc/src/docb_transform.xml deleted file mode 100644 index 06a04c8c02..0000000000 --- a/lib/docbuilder/doc/src/docb_transform.xml +++ /dev/null @@ -1,224 +0,0 @@ -<?xml version="1.0" encoding="latin1" ?> -<!DOCTYPE erlref SYSTEM "erlref.dtd"> - -<erlref> - <header> - <copyright> - <year>2001</year> - <year>2011</year> - <holder>Ericsson AB, All Rights Reserved</holder> - </copyright> - <legalnotice> - The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved online at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - the License for the specific language governing rights and limitations - under the License. - - The Initial Developer of the Original Code is Ericsson AB. - </legalnotice> - - <title>docb_transform</title> - <prepared></prepared> - <docno></docno> - <date></date> - <rev></rev> - </header> - <module>docb_transform</module> - <modulesummary>Transform XML to HTML</modulesummary> - <description> - <p><c>docb_transform</c> contains functions for transforming XML - documentation source code to HTML.</p> - </description> - - <funcs> - <func> - <name>file(File) -> ok | {error, Reason}</name> - <name>file(File, Options) -> ok | {error, Reason}</name> - <fsummary>Transform XML to HTML</fsummary> - <type> - <v>File = string()</v> - <v>Options = [Opt]</v> - <v>Opt -- see below</v> - </type> - <desc> - <p>Transforms XML documentation source code to HTML.</p> - - <p><c>File</c> is a documentation source file, given with or - without the <c>.xml</c> extension as <c>Name.xml</c> or - <c>Name</c>.</p> - - <p>If <c>File</c> contains XML code according to a basic DTD - (<c>chapter</c>, <c>erlref</c>, ...), the resulting HTML - file is named <c>Name.html</c>.</p> - - <p>If <c>File</c> contains XML code according to a compound DTD - (<c>application</c> or <c>part</c>), several files are - created:</p> - <list> - <item>A cover page for the application with two frames, - <c>Name_frame.html</c>.</item> - <item>The contents of the left frame and a front page, - <c>Name.html</c> and <c>Name_first.html</c>.</item> - <item>A bibliography and a glossary, <c>Name_cite.html</c> - and <c>Name_term.html</c>.</item> - <item>In the case of an <c>application</c> DTD an index - is created, <c>Name.kwc</c> and <c>Name_index.html</c>. - </item> - <item>One HTML file for each file included from <c>File</c>. - </item> - <item>Also, if there exists a <c>fascicules.xml</c> file where - the value of the <c>entry</c> attribute for <c>File</c> is - <c>"yes"</c>, the cover page is copied to <c>index.html</c>. - </item> - </list> - </desc> - </func> - </funcs> - - <section> - <title>Options</title> - <taglist> - <tag><c>{html_mod, Module}, Module=atom()</c></tag> - <item> - <p>A callback module can be used for specifying HTML snippets - that should be included in the generated HTML files, see - below.</p> - </item> - - <tag><c>{outdir, Dir}, Dir=string()</c></tag> - <item> - <p>Destination for generated files. Default is current working - directory.</p> - </item> - - <tag><c>{number, Number}, Number=int()</c></tag> - <item> - <p>First chapter number when transforming a <c>chapter</c> - file. Default is 1.</p> - </item> - - <tag><c>{ptype, unix|windows}</c></tag> - <item> - <p>For <c>path</c> elements, the specified file path should be - presented.</p> - </item> - - <tag><c>silent</c></tag> - <item> - <p>Silent - no warnings, only error information is printed.</p> - </item> - - <tag><c>{top, Index}, Index=string()</c></tag> - <item> - <p>Specifies the value of "Top" in the left frame of a front - page, which normally should be some kind of top index file - for the documentation.</p> - </item> - - <tag><c>{vsn, Vsn}, Vsn=string()</c></tag> - <item> - <p>Application version number. Overrides a version number - defined in the XML document. Visible in the left frame and - on the front page.</p> - </item> - - <tag><c>{term_defs, File}, File=string()</c></tag> - <item> - <p>Use the global glossary definitions in <c>File</c>, which - should contain a list of tuples <c>{Id, Name, Definition, - Owner}</c>. See the section - <seealso marker="inline_tags#termTAG"><term>, - <termdef> - Glossary</seealso> in the User's Guide. - </p> - </item> - - <tag><c>{cite_defs, File}, File=string()</c></tag> - <item> - <p>Use the global bibliography definitions in <c>File</c>, which - should contain a list of tuples <c>{Id, Title, Info, - Owner}</c>. See the section - <seealso marker="inline_tags#citeTAG"><cite>, - <citedef> - Bibliography</seealso> in the User's - Guide.</p> - </item> - </taglist> - </section> - - <section> - <title>Callback Module</title> - - <p>A <c>html_mod</c> callback module can include the functions - specified below. Note that there is no check that the resulting - HTML code is valid. All functions are optional.</p> - </section> - - <funcs> - <func> - <name>Module:head() -> string()</name> - <fsummary>Snippet to be included in head of a document.</fsummary> - <desc> - <p>Defines a HTML snippet to be included in the head of - a document, after the <c><HEAD></c> start tag and - <c><TITLE></c> tag:</p> - <pre> -<HTML> -<HEAD> - <TITLE>...</TITLE> - - snippet is included here - - ... -</HEAD> -... -</HTML> - </pre> - </desc> - </func> - - <func> - <name>Module:top() -> string()</name> - <fsummary>Snippet to be included at the top of a document. - </fsummary> - <desc> - <p>Defines a HTML snippet to be included at the top of a - document, after the <c><BODY></c> start tag.</p> - </desc> - </func> - - <func> - <name>Module:bottom() -> string()</name> - <fsummary>Snippet to be included at the bottom of a document. - </fsummary> - <desc> - <p>Defines a HTML snippet to be included at the bottom of a - document, before the <c></BODY></c> end tag.</p> - </desc> - </func> - - <func> - <name>Module:seealso(SeeAlso) -> Href</name> - <fsummary></fsummary> - <type> - <v>SeeAlso = Href = string()</v> - </type> - <desc> - <p>When referring to another part of the document, or another - document, the XML tag <c><seealso></c> is used: - <c><![CDATA[<seealso marker="File#Marker">...text...</seealso>]]></c>. - By default, this is translated to - <c><![CDATA[<A HREF="File.html#Marker>...text...</A>]]></c>.</p> - - <p>This function makes it possible to specify an alternative - translation <c>Href</c> of the <c>marker</c> attribute value - <c>SeeAlso</c>. For example, in OTP this is used to resolve - cross references between applications.</p> - </desc> - </func> - </funcs> - -</erlref> - diff --git a/lib/docbuilder/doc/src/docbuilder_app.xml b/lib/docbuilder/doc/src/docbuilder_app.xml deleted file mode 100644 index 58b8daf598..0000000000 --- a/lib/docbuilder/doc/src/docbuilder_app.xml +++ /dev/null @@ -1,57 +0,0 @@ -<?xml version="1.0" encoding="latin1" ?> -<!DOCTYPE appref SYSTEM "appref.dtd"> - -<appref> - <header> - <copyright> - <year>2007</year> - <year>2011</year> - <holder>Ericsson AB, All Rights Reserved</holder> - </copyright> - <legalnotice> - The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved online at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - the License for the specific language governing rights and limitations - under the License. - - The Initial Developer of the Original Code is Ericsson AB. - </legalnotice> - - <title>docbuilder</title> - <prepared></prepared> - <docno></docno> - <date></date> - <rev></rev> - </header> - <app>docbuilder</app> - <appsummary>The DocBuilder Application</appsummary> - <description> - <p>DocBuilder provides functionality for generating HTML - documentation for Erlang modules and Erlang/OTP applications - from XML source code and/or EDoc comments in Erlang source code. - </p> - </description> - - <section> - <title>Limitations</title> - <p>DocBuilder is primarily intended for generating documentation - for Erlang/OTP itself. That is, no attempt has been made to create - a tool suitable for generating documentation in general.</p> - </section> - - <section> - <title>See Also</title> - <p>DocBuilder User's Guide, - <seealso marker="docb_gen">docb_gen(3)</seealso>, - <seealso marker="docb_transform">docb_transform(3)</seealso> - <seealso marker="docb_xml_check"></seealso></p> - </section> - -</appref> - diff --git a/lib/docbuilder/doc/src/make.dep b/lib/docbuilder/doc/src/make.dep deleted file mode 100644 index d9b075e114..0000000000 --- a/lib/docbuilder/doc/src/make.dep +++ /dev/null @@ -1,33 +0,0 @@ -# ---------------------------------------------------- -# >>>> Do not edit this file <<<< -# This file was automaticly generated by -# /home/otp/bin/docdepend -# ---------------------------------------------------- - - -# ---------------------------------------------------- -# TeX files that the DVI file depend on -# ---------------------------------------------------- - -book.dvi: block_tags.tex book.tex character_entities.tex \ - docb_gen.tex docb_transform.tex docb_xml_check.tex \ - docbuilder_app.tex fasc_dtds.tex header_tags.tex \ - inline_tags.tex overview.tex part.tex ref_man.tex \ - refman_dtds.tex user_guide_dtds.tex - -# ---------------------------------------------------- -# Source inlined when transforming from source to LaTeX -# ---------------------------------------------------- - -block_tags.tex: gazonk - -book.tex: ref_man.xml - -inline_tags.tex: ../../../../system/doc/definitions/term.defs - -# ---------------------------------------------------- -# Pictures that the DVI file depend on -# ---------------------------------------------------- - -book.dvi: man.ps - diff --git a/lib/docbuilder/doc/src/man.ps b/lib/docbuilder/doc/src/man.ps deleted file mode 100644 index b4d7ef7636..0000000000 --- a/lib/docbuilder/doc/src/man.ps +++ /dev/null @@ -1,750 +0,0 @@ -%!PS-Adobe-2.0 EPSF-2.0 -%%Title: /clearcase/otp/internal_tools/sgml/test/man.ps -%%Creator: XV Version 3.10a Rev: 12/29/94 - by John Bradley -%%BoundingBox: 243 308 369 484 -%%Pages: 1 -%%DocumentFonts: -%%EndComments -%%EndProlog - -%%Page: 1 1 - -% remember original state -/origstate save def - -% build a temporary dictionary -20 dict begin - -% define string to hold a scanline's worth of data -/pix 126 string def - -% define space for color conversions -/grays 126 string def % space for gray scale line -/npixls 0 def -/rgbindx 0 def - -% lower left corner -243 308 translate - -% size of image (on paper, in 1/72inch coords) -126.00000 175.96800 scale - -126 176 8 % dimensions of data -[126 0 0 -176 0 176] % mapping matrix -{currentfile pix readhexstring pop} -image - -110000110011111111111100111111110011110011111111111100111111112222222222 -33445544446655665555665566666655666666888888778899888899aabbaabbbbbbaabb -bbaaaaaaaabbbbbbaabbccddbbaaaaccccccddddccddddccbbccccccbbccccaabbaaaaaa -9999aaaa8899887777554455666655555544 -000000110011110000001100112222111111001111111100001111111111112222112233 -55334444446666775544555555775577777766888888889988889999aaccbbaabb99aaaa -bbbbaaaaaaaabbbbccccccccccccbbccccccccddccddddccbbaaccddccbbaaccbbbbaaaa -999999889977667755554455666655444444 -110011000011000000111111111100111100112211111111110011111111112222222233 -3344444455446677665555667777667788888888667788aa88999999aabbaabbaa889999 -aabbbbbbaaaaaabbddccccccbbccccccbbaaccccccccccccbbccccccccbbbbbbbbaaaa99 -9999aa888877666655555555555544333344 -110000110011110000001111111111000011001122110011111111002211222211224433 -3333444444556677666655667777667777888877666688998899aa99aabbaaaaaaaabbaa -99aabbaabbbbbbbbbbccbbddaabbccbbaa99ccddccccccbbccccccddccbbbbaaccaa9988 -889988887766665566665544443344554444 -000000000000110011000000110000110000001111000000111100221111111133222222 -33444433444455667777555555776666778888667777778888aa998888bbaa99aaaaaabb -bbbbbbaabbccbbbbbbccbbbbbbccccaabbbbbbccccccbbbbbbbbccbbbbbbbbbbbbaa7788 -aa9988889966666655666655553355556644 -110011111111111100111100110011000000001100002211111122221122111122222222 -33443333334455776666776666667766778855668866777788448899889988889999bbaa -aaaabbaaaabbbbaabbbbbbbbbbbbaa99bbaabbccddccccccbbccbbbbaabbbbaaaa777788 -aa9999aa9988776677777755555544556655 -110000001111111122111111000000001111110011111111110022111111111133222233 -223322445555445544667777667777667777887788887799883377999999998899aaaaaa -99aabbbbccbbbbbbbbbbaaaaaabb99aaaabbbbbbccccccbbccccbbbbaabbaaccaa886688 -9999aaaa9988888866667744555544445544 -110000111122111111221100111111110011111111111100111111222222221122333333 -22222244556655445555667788778888aaaa88aa889999aabbaaaa998888998899aa99aa -bbaabbccbbbbaaaabbbbbbbbbbbbaabbaaaaccccccbbccddccbbaabbaabbaabb99888888 -99aa99aa9988888866446655554444444444 -110000001111111111110011110000111100221111001111000011222222222222333344 -223322444466664455667766777788777755556666333344557788aa9999888888aa88aa -aabbbbaabbaaccbbaaaaaaccbbccaa99bbccccccccbbccccccbbbbbbbbaabbaaaa99aa88 -999988999988887766664455445555555544 -110011111100001111111111110000000011111111110011111122111111112233222222 -443333555544444455777788775522000000000000000000000000447799aaaa99888899 -aaaabbaaaaccbbaaaabbbbbbbbaa7788bbddccccbbbbbbbbccbbbbaabbaaaaaaaaaa9999 -aa999988aa99887766666655444455445544 -000000110011110000110000110011001100001111110000111122112211112211222222 -5544444455443333446677772200000000000000000000000000000000337799999999aa -9999aabbbbbbaaaa88aaaabbbb889988ccccccbbccbbbbaaaa9999bb8855889999999988 -998888998888886655667755554455554433 -110011001111001100001100111111000000001100111100111111222211113333222211 -44555544444433445555550000000000000000000000000011000000000000003377aa99 -888899aa99aa9999aaaabbaabb99aabbaabbbbccaabbaaaabb88aaaa995588aaaaaa8888 -8888aa998888887755777766554444332222 -111111110011111111001111001111110000000011000011001111111122332222223322 -334466554444444455441100000000000000000000000000000000001155220000113366 -998888aa99998899bbbbaabbbbaaaaaabbbbbbbbbbaabbaaaa99aaaa8888aa9999889988 -7799aa888888665566666655554433334422 -221111110011000011111111110000000000110011110000111111001111333311223333 -443344443344554488440011553300000000000000000000000000227788883300000011 -4444559999887799aaaaaaccbbaaaa9988ccccbbaabbbbaaaa99aa9988aa999988888888 -776688888877667766554455444444444433 -221111110011111100110011000011000000000000110000110011001111112222221122 -2222333333111111448899ccffddbb77442222221111000000000044bbddccaa33000000 -00000000558888998899bbaabbaabbaa99bbaabbaaaabbaa99aa99999988778888777777 -663355778877776666665544444433333322 -221100222211001111112200111111000011000000000011001100111111112211112211 -332244220011000055ddffeeeeeeeeeeddddddeeddcc88330000000044ddddcc55000000 -000000000077aaaa999999aaaabbbbbbaa99aabbbbaaaabbaaaaaa999999888888557755 -664466666677666655667755443333223322 -221111222211221111111100000011110000110000001100111111110011111122112222 -3322000000000044ddffffeeffeeeeeeeeeeeeeeffeeffdd885511000033aaddaa330011 -2211000000339988889999aaaaaabbaabbbbbbbbbbaaaaaabb99aa8899aa999988665577 -665577777766555544443366443344333322 -221111111122221111001111111100000000000000001111111111111111111111223344 -22000000000077ddeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeffeebb440000005588661100 -11000000001188888888aa9999aabbbbbbaaaabbaabbbbbbaa8899888899888888776666 -556666776666443366555555445533333333 -112211111122221111221100111100110000000000001111001100000000111122112211 -000000000088eeeeeeeeeeeeffeeeeffffeeeeeeffeeeeeeeeeeffee8811000000118866 -0000000000118899888899aaaabbbbbbbbbbbb99aabbaaaaaa9988888877888877555566 -555555666655446655556655444444443344 -221111111100111111110011111111110011001100110000111100110011111111000000 -0000000088ffeeddeeeeeeeeeeeeeeeeeeeeffeeeeffffeeeeeeeeffffbb775566aaeeee -aa332233000088aa88888899bbaaaa99aabbaaaabbaabbbbaaaa88888877888877555555 -445577666655554455555566665544665533 -110000111111110011111111111111110000000000001100111111000011111111110000 -00000088ddddddddddffeeffeeeeeeeeeeeeffeeeeeeeeffeeeeeeeeeeffffffffffeedd -eecc441111002288997788aa99aaaa99aa99aabbbbaabbaaaa9977778888777777776655 -555577776666666666666677775555555555 -001111110011001100111111112211111100110000000011110011111111001111000000 -000022aaddccddddeeeeeeeeeeeeeeeeeeeeeeeeeeffeeffeeeeeeffeeffeeeeeeeeeeee -eeffdd3311110044998899999999aaaaaaaaaabbaabbbbaaaa8888778877888866776677 -665566667755556644665555554444666666 -110011110011111111001100002211111100110011111100111100111111111100000000 -000022bbcccccccceeeeeeeeeeeeeeeeeeeeffeeffeeffffffeeeeffeeffeeffeeeeeeee -eeddeebb6644000088998899bbbbbbaabbbbbbaabbbbbbcc999988888877888877667777 -557777777766665544555555555555665566 -110011221111111111111111111111221100001100110011111111221100221100000000 -00001199aabbccccddeeeeeeeeeeeeeeeeeeeeeeffffeeffeeffeeeeffeeffeeeeeeeeee -eeddeeeebb88110066aa99aabbccbbaabbbbbbaabbbbbbbbbb99aaaa9988777766667777 -666677777777665544665566555566664455 -221111222222111111111111221111111111111111001111111100221122221100000000 -000022aabbbbaaccddeeeeeeeeddeeeeeeffeeeeeeeeffeeffeeffeeffffeeeeeeeeeeee -eeeeeeeeeecc220066aaaaaaaabbbbbbccaabbaaaabbccbbaaaaaa998888886677887777 -777777888866776655667755665566666655 -222211222222111122111122111111000000001111111111111122111122220000000000 -00002299bbaaaabbddeeeeeeddeeffeeeeeeeeeeffeeeeeeeeffeeeeffffffeeeeeeeeee -eeeeeeeeeecc330044aaaabbaabbbbbbaaaabb99aabbbbbbbbaaaa889988888877888888 -887777778888776644777777666677667766 -222222332233222211221111221111110000111111222222222211222222221100000000 -00001188cc99aabbddddddeeeeeeeeeeeeeeffeeeeeeeeeeffeeeeffeeffeeeeeeeeeeee -eeeeeeeeeeee440044bbaabbbbaabbbb9999aaaabbaabbbbbb9999998888887788888899 -887777778888887755776677667755667755 -221122442222222222332211222222111111001111222222221133112222220000000000 -00001177bbaaaaaaeeddeeddeeeeddeeeeeeeeeeeeeeeeeeffeeffffeeeeeeffeeeeeedd -eeeeffeeddffaa0022aabbbbbbbbbbaaaa99bbbbaabbaabbaa9988888888998888887777 -888866777788888888888877666655445566 -331133442233333333332222332211111111111111112222222233221122220000000000 -0000115599aabbccddddeeddeeeeeeeeeeeeeeeeffeeeeffeeffeeffffffeeffeeffddee -eeeeeeeeeeffdd110088bbbbbbccbbaa99bbaabbaaaabbbbbbbb99888888888888666677 -777777778888666677888877775544444455 -332222332222334422222233222233110011222222112233223322222211221100000000 -000000228899aabbddddeeddeeeeeeeeeeeeeeeeffeeeeeeffeeffeeeeffeeffeeeeeedd -eeffeeeeeeeecc220066bbaabbbbbbaaaa999999aaaaaaaa9999aaaa9988888877776688 -888877778888776677887777666666665544 -333311332233333333222222222233331111113322222222223322332222220000000000 -000000225577aabbccddddddeeeeeeeeeeeeeeeeeeeeeeffffffffeeffffeeeeeeeeeeee -eeeeeeeeeeeedd110044bbaaaabbaabb99999999aabbaa999999aa999999998888777788 -888855888888886677777788777777555555 -222211222222224444111122222211222233221133443344332233333322551100000000 -00000022557788aaccddeeddddeeddeeeeeeeeeeffffeeffeeeeffeeeeeeeeffeeffeedd -eeeeeeeeeeeedd33003399aaaabbbbaaaa88999999aaaaaa99aaaabbaaaaaa9999778888 -887766888888885577776666777766556644 -222211222222222233334422222222112233222233554444332222222222440000000000 -0000001144779988bbccddddddffddeeeeeeffeeeeeeeeffffffeeeeeeffeeffffeeeedd -eeeeeeeeeeeedd2200228899aaaaaa88888899999999bbaa99aabbbbbbaa999988888888 -887777778877665566886666666677775566 -443322111133331111222233332222332222332233223333333333332233331100000000 -000000115555668899ddddddddeeeeeeeeffeeffffffeeffeeeeffeeeeeeeeeeeeeeeedd -eeeeeeeeeeeedd2200339999aabbaa889999aaaa99aabbaaaa99bbbbaaaa998899998888 -888888997777775577777777777777666666 -332211223322222222221122223333221122112233333333332244333333330000000000 -0000000033444466aaccccddddeeeeeeeeeeeeffeeeeeeffeeeeeeeeeeffeeeeffffeedd -eeeeeeeeeeeecc2200228899aaaa9988aaaaaaaa99aa99bbaabbaaaa99999988aa999988 -888888887777776677666666776666556644 -332222222233222233332222333333331133332233224433333344554444331100000000 -000000110044777788aaeeeeddeeeeddddddeeeeeeeeeeffeeffeeeeeeeeeeeeeeeedddd -ddeeddeeeeeedd220011aa9999aa999999bbbbbb99bbbbbbbbbbbbaaaaaa999999888899 -998888888888666677556677666655555555 -332222222222333333443333333322443333443344334433444455553333330000000000 -000000002233557788ccccccccaa775555446688ccddcceeeeeeeeeeddeeeeeeeeeedddd -eeddeeeeeeeedd44003399aa88aaaa99aaaaaaaa99bbbbbbbbbbbbbbbbbbaa999999aa88 -888866887788775577667755556655555544 -331122332222444433333333223333333344444444554433445555664444441100000000 -00000000332244889999777788330000000000116688aaddccddddccddddaa88aa99aadd -ddddeeeeeeddee660022aa99999999bb99bbbbaaaabbbbbbbbccbbbbbbbbaa99aaaa8888 -888877776677667755777755445555556655 -331122333333335544554433333322443344555555554433334433556655441100000000 -000000000000225544221100110000000000001111557799ccbb88778877110011003388 -bbddeeeeeeddee55002299aa999999aaaabbaabbaabbbbbbaaaaaabbaaaabbaa99998888 -887777667788666666666666555555554444 -333333333322444444555555444444444455556666555544334455336666551100000000 -000000001111001100000000000000000000000011224455889966111111000000000011 -66aaddeeeeeeee550033aa99aa999999bb99bbccaabbbbaaaaaaaabbaaaabbaabb888888 -667777777777775577554455553344444444 -223344332233555544556666665533335544556655555533446655555555661100000000 -00001100111100000000000011000000000000000011449999bb77000000000000004433 -225588cceeeeff660044aaaa888899aa9999aaaa99aabbaaaaaa99bbbb9999aaaa998888 -886677777777667766555555443355554455 -443344332233556655666655666633555544555555555555555566555555662200000000 -0000001111110000000000001100000000000000000066ddeeee990000000000000066bb -bb88bbcceeeeee880066aaaa9999bb9999aa99998899aa999999aaaabbaaaaaa99889988 -778888776677666655444455665555554433 -443333442233445577665566666655444444666655667766666666666644443300000000 -0000001133220000000000000000000000000000000055eeeeeebb110000000000000022 -bbffddddeeeeff88007799999999aabbaa9999999988aa99999999bbaaaa888877888888 -887777777766666655664455554455443344 -444422335566557766776666555544444455556666555555556666668899aa5500000000 -0000002233220000000000000044110011110000000055ffeeffcc110000000000000000 -0077ddddddddeebb118899999999aaaaaa8888aa88aaaaaa9999aabbaaaa997755889988 -887766777766775555665555444444443344 -555544333344556666556666445566556666555555665566665555335566999922000000 -0000002244332200000000001177663366330000000088eeeeffdd110000001100112200 -000066cceeeeeebb66ccbbaa9999aaaa998899aaaabbbbaa9988aaaabb99998888888877 -777755776666666655555555554444444444 -445555554444555555557766445544666677665566666666776611000000002233000000 -00000022445544112233442255442211110000000033bbeeeeeeee880000002255999966 -330033ddeeeeeeddddeeeeffccaa99998899aaaabbbbaaaa999999999999999988888877 -777766665566666655665544444444553333 -444444556666445555776666555566667777775566666655665500000000000000000000 -00000000334433337799999988775533112244225599ccddeeeeffee885533111166bbcc -bb6666ddffeeeeeeeeeeaa66aa99aa889999bbbbbbbb99aa999999999999998888888877 -667766555555555555444433444444333322 -334444445577665555556666665566665577666644444466664400000000000000000000 -000000002255667788bbbbbbaabb998866556688aabbddeeeeeeeeeedd8888bbaaccddee -eeeeddeeeeeeddeebb22000066aa88aabbaaccbbaa99aa99889988999999889999888877 -777766666666665544334455443333333333 -333355444466557766776655555555556666664455446666665500000000000000000000 -0000000011335577aaccddddddccbb998899ccddddccddeeffeeeeeeeedd8899ddeeeeee -eeddffeeeeeedddd3322220066aaaaaabb99bbbb99aaaa88888899888888888877887777 -556688553355665533444433334433333344 -444444225555445566888866666666777777776666556666664400000000000000000000 -0000000011224477aaddddeeddddddddddddddddddddeeeeeeffeeeeeeeecc88aaddeeee -eeeeeeeeeeeeeecc66dd8800779988bbbbaabbbbaaaa9988888888999977776677776666 -557766553355556644443333333344221133 -77bbccbb9988774455667777667788888877886666667777666611000000000000000000 -0000001111335577bbccddddeeeeeeddeeeeddddccddeeeeffeeeeeeeeeeffddddddeeee -eeeeffeeeeeeddccddeedd22999988aa99aaaa8899aa9988888888888888776677777766 -776666665555555544444444332222112211 -bbeeffffffeeeedd88444455668899998866776666666677775533000000000000000000 -0011114433446688bbccccccddddeeeeddddbbddeeddeeeeffffeeffeeffeeffffffeeee -ffeeeeffeeeeeebb77eeee88cc889999aaaa99aa99998888778888888888668888997777 -777777667766665533334433332222222222 -77ddeeffeeffeeeeee995555557788888888776677775577776655221100000000001100 -1122225555665588aabbbbccddddddeeccaabbeeddccddeeeeeeffeeffeeeeeeffeeeeee -eeffeeffeeeeffcc33bbeeeebbaaaaaa99aaaa9999888877889999999988777788887777 -888866556677665533334433112211222222 -4499bbbbeeeeeeeeeeee6633667799889988778877667788777777332200110000001100 -444477888866667799aabbccccddddddbb8888aa7755779999bbddeeffffeeeeeeffeeee -eeddeeeeffeeeedd44bbeeeebbaaaa99aaaaaa99889999888888aa99aa88776677888877 -887777666666554433554422222222222211 -003322446677cceeeeeeaa66777788888888888877667788887788662211113300002222 -66887777665566667799aabbccccccaa88443322000011223344446677ccffeeeeeeeeff -eebbeeeeeecceeeeaacceeeebbbbaaaaaabbaabbaa999988778899998888888888778888 -777766776677665555442222222233222222 -00220000000066ccffeeffaa776677887777887777777788888877773311005566115533 -7788996666445566667799bbccbbaaaa9933000000000000000000000066ffeeeeffeeee -eeddeeffeeffeeffeeddeeddbbaaaa99aaaaaabbccaaaa88889988999988888877888877 -888877667766666644332244442222223322 -1111000000000044aaeeffdd777755777788778877777788888888776611221122888844 -88aa77776655445555778899aa7788aaaa44000000000000000000000077ffeeeeddeeee -eeeeeeeeeeeeeeeeeeeeffccaaaaaa9999aaaaaabbaaaa9999888899bb99888866778888 -777777665555554444333322222222221122 -22000000001111001177dddd999999886666888877887788778888888844115544aa8888 -9988888866555555446666666666bbcc99330000000000000000000055eeffeeeeccddee -eeeeeeeeffeeffeeeeeeeeccaaaabbbbaaaabbbbaaaaaa88889999aa8899886688777766 -778888775566554433332233333322331111 -4400000000443300000033bbffeeffeebb666677888888888888777766663333bbbb88bb -aa998888885555554444221144aaccbb330000000000000000000033ccffeeeeffddcccc -cceeeeeeeeffeeeeeeffeebbbbbbbbbbbbaaaaaaaabbaa8899aa99889999888877888877 -667777668888998844332244442244332222 -770000000077ccbb996677eeeeeeeeeeeebb5566777788889988777777777755ccbbaacc -bbaa9988775577664400000055bb6633110000000000000000000077bbddeeeeeeffddaa -bbddddddddddffeeffeeeebbbbccccbbbbbbaaaaaaaa8888888888998899888888888888 -776677aaddeeeedd77223344443344333311 -dd77000011aa99aaddeecccceeeeeeeeeeeebbaa6677888899887788778888cceeccbbbb -ccaa998888888855110000337733000000000000000000000000005599ddccddeeeeeedd -aa99ccddaacceeffeeeeeeeebbaaccbbbbaa99aa99998888887799998899998877888888 -8888cceeeeeeeeddbb553344333333333322 -eeee88000077220033998866aaeeeeeeeeeeeeeeaa777788aa8899997788aaddccbbcccc -ccbbaaaabb9977440000335522000000000000000000000000000000227788aaeeeeeeee -bb8899ccddaaaaeeeeeeeeffcc99aaaa99999999aaaa8888888888777777888877777788 -88cceeeeeeeeddeeeeaa3344444433443333 -eeeedd55004488000011110077ffeeeeeeeeeeeeffbb8877889988999999ddddddddddcc -ddccccbb8866332200113300000000000000000000000000000000000000334488cceeee -ddccaa88bbbb6655bbffeeeeeeccaa9999aaaa99998899997777889999aa998888888866 -3388ddddddddcc88ccdd9944334433443322 -eeeeee88110066110000000088eeeeeeeeeeffeeeeeecc9977889999aacceeddeeeedddd -ddddaa88663300000000000000000000000000000000000000000011000000000022aadd -eeddccbb99aa88111188eeffeeffddaa99aaaaaa88998888888888aaeeeeeebbbbddddaa -1155ccaa55443311aaeedd88222222332211 -ddccdd88440000000000000077ddeeeeeeeeeeffeeeeffeebb99aaaaccddeeeeeeeeeeee -ddbb777777442200000000000000000000000000001188ccbb9999bb8833000000002222 -77ddddddccbb8844000044ddffffffeeaa88aa9999998888888888cceeddeeddeeeeeedd -2288bb991100000066bbddcc551122222222 -cc666622221100000000000055ddeeeeeeeeeeeeeeeeeeeeee9999ccddeeeeffeeeeeeee -eeddccaa884422331100000000000000000000001177eeeeeeeedddddd99550000001133 -1155ddeeddddcc8855000033aaeeeeffdd9999aa9999aa88995555cceeeeddeeeeeeeebb -00559999440000000055bbddbb3322223322 -ffdd4400001100000000000044ddeeeeeeeeeeeeeeeeeeeeeeccbbeeffeeeeeeeeffeeee -eeddeeccbb8866772200000000000000000000001144668899aabbddddccbb66110044bb -bbbbcccceeeeddddcc8877332277cceeeeeebb88999999aadd7799eeeeeeeeeeeeddddaa -4444775577220000000044bbee7711222211 -eeeecc33000000000000000033cceeeeeeeeeeeeeeeeeeffeeffeeffeeeeffeeffeeffff -eeffeeddeeccbb884411000000000000000011000000000000000088ccddddaa6644bbee -ddffeeddeeeeeeeeeeffffeeddbbddeeffeeeeddaa88aaccddbbeeddeeddddeeeeee8844 -7711221100000000001177ccddbb44112211 -eeeeffaa000000000000000066eeeeeeddddeeeeffeeeeeeffeeeeeeffeeeeffeeeeffff -eeeeeeeeeeeeeecc66110000000000000022666655334433446688bbeeddeeddbbccddee -eeeeeeeeeeddeeeeffffeeeeffffffeeeeeeeeffdd99cceeddbbddeeddddeeddeecc2200 -22000000000000003399ccccdddd88111122 -eeeeeeee550000000000000088eeddddddccddddeeeeddeeeeeeeeeeffeeffeeeeffffee -ffffeeeeffeeeeee99220000000011336688bbddddddddeeeeffeeeeeeeeeeeeeeeeeeee -ffeeffeeeeeeeeffeeeeeeffeeffeeeeffeeeeeeffddddeedd99ccddddddeeeedd660000 -00000000000000001166ccddddeeaa222222 -eeeeeeee880000000000000099eecc888888ddccccaa88ccddeeeeeeeeeeffeeffeeffee -ffeeeeffeeeeeeddbb3300001122336688aaddeeeeddeeeeeeeeeeffffeeeeffeeeeeeee -eeffeeffeeeeeeeeeeffeeeeffeeeeeeeeeeeeeeeeccccddcc5588aacceeddeecc220000 -0000000000000000004499bbccddcc331111 -eeeeeeee990000000000000088ddccdd6622bbddbb4455ddbbaaeeeeffeeffeeeeeeffff -eeffeeeeeeeeddcc996633335522335588aaccddeeeeeeeeeeeeeeeeeeffeeffffeeeeff -ffeeeeffffeeeeeeeeffeeeeeeffeeeeeeeeeeeeff99779988003377ccddeeee99000000 -000000000000000000000055bbddcc441122 -ffeeeeeedd3300000000000077cceeee880044aabb55ccffddccddffeeeeffeeeeeeeeff -eeffeeeeeeddccbb776644442211223377aaccddeeeeeeeeeeeeffffffeeffeeeeeeffee -ffeeeeeeeeeeeeffffeeeeffeeeeffffeeffeeffff8811333300001199ddeeee66000000 -0000000000000000001155ccddccdd551111 -eeeeeeeedd991100000000000077ccdd555577111133ddffeeddddffffffeeffffffeeee -ffffeeeeffddccbb7733110000000011336688bbcccceeeeeeeeeeffeeeeffffffeeeeee -ffeeffeeffeeffeeeeffeeffeeffffeeffeeffeeff99000000000066ddddeecc22000000 -00000000000000004499ccdddddddd771122 -eeeeeeeeeedd6600000000000000226677ddee66000088bbcc8866777799ccbbaabbbbcc -ddeeffffffeeeeeebb6644110000000000113355668899bbbbddddddeeeeeeddeeeeeeff -eeeeeeeeeeeeeeffffeeffffeeeeddddccddddddee990000000000aaffeeeeaa00000000 -00000000000000005588bbccccdddd880011 -eeeeffeeeeeebb99220000000000000055bbaa3300000011220000003399aa9988886666 -66888888bbddeeeeeeddcc9933000000000000000011224466778888aabbddddeeeeeeee -ffffeeffffeeeeeeccbbbbaaaa777777774411222211000000000055aaaaaa6622000000 -00000000000000004499bbccddddee991111 -eeeeeeffeeddddcc4422220000000000001133000000000000000000669999aaaa99aa99 -999911000011445588aacccc88110000000000000000222222223322336699bbddeeffee -ffeeeeddccccccaaaaaaaabbbbaabbbbbb66000000220000000000001111110000000000 -000000000000001155aabbddccddddbb2211 -ffeeffeeeeeecccc99aa55000000000000000000000000000000001188888899aaaaaaaa -99770000000000000000113333000000000000000000000011000000002277cceeeeddaa -8888ccccccccccccbbbbccddbbbbbbbbcc88000000000000000000000000000000000000 -00000000000000116699ccddddddeecc2211 -eeeeeeeeeeeeddccddccbb661100000000000000000000000000227788778877889999aa -660000000000000000000000000000000000000000111100000000000011445544331100 -0088ccccccccccccccbbbbccccbbbbbbaa99110000000000000000000000000000000000 -000000000000002266aaccddddddddcc3300 -eeeeeeeeeeeeddddbbccccccaa88887788aa440000000000004488778888887788779977 -110000000000000000000000000000000000001111111111001111000000000000000000 -55ccccbbccccbbccccbbbbbbbbbbbb999999772200000000000000000000000000000000 -000000000000002277aaddddccccdddd5511 -eeeeeeffffddddddddddeeddddeeddeeddcc773311000000337766777777667766776611 -000000000000000000000000000000000000000000000000000000000000000000000055 -ccbbbbccbbccccbbbbbbbbbbbbaaaaaaaa99997711000000000000000000000000000000 -000000000000001166aabbccccdddddd7711 -eeeeffeeeeeeeeeeeeddeeddeeddddddccbb996611001144777777776677776666771100 -0000110000000000000000000000000000000000000000000000000000000000000022dd -8844ccbbbbaabbaabbbbaabbaaaaaa99aa99aa7766110000000000000000000011557777 -66330000000000003388aaccdddddddd9911 -ddeeddeeeeeeeeeeddeeddddeeddddccbbaa883300004466667777666655666688440000 -0000001111000000000000000000000000000000000000000000000000000000000099ff -aa0077bb99aabbbbbbbb99aaaa99999999aa887766440000000000000000003388bbccbb -cc773300110000002277bbbbccccddddaa22 -ddeeddeeeeeeddeeeeddddddddddddbb9988330000336655886688776655556688220000 -00000011222211000000000000000000000000000000000000000000000000000077eeff -bb001199ccbbaaaaaaaaaa889988999999997777777733000000000000001166aaccccdd -ccbb770066550000336699ccddccdddddd55 -99aabbddddeeddeeddddddcceeddcc887755110011556666667777776677775522000000 -000011224455441100000000000000000000000000000000000000000000000066eeeeee -cc0000338899bb999999999988888888aa998888777755000000000000002277bbccccdd -ddcc991177882200336699bbddccddddddaa -22333366ccddddddddccddbbaa9977333311001144666655666688889966330000000000 -0000115555777777551100000000000000000000000000000000000000000044ddeeeeee -ee220000002277aabbaaaaaa99888899aa99aa88777766220000000000000055aaccddcc -ddcc991133885522113388ccccddddccccdd -0000000088aa888888887733221100000000115566776677777799994411000000000000 -00001155777788998877773300000000000000110000000000000000000077cceeeeeeee -ee2200000000003377aabbbbaaaa9988aaaaaa999977665500000000000000117799aabb -ccbb883311443311112266bbccccdddddddd -000000002233001122111100000000002244667766668866888899220000000000000000 -000000777799aaaa99aaaa99550000000000000000000000000000003388ddeeeeeeffee -ee33000000001100003388ccbbaa99999999999988775566330000000000000011558899 -aa9977220011000011335588ccddddeeddee -00000000000000000000000000001144667766667788aa99aa8811000000000000000000 -0000003377aabb99bbbbccaa77663300000000000000000000000055cceeeeeeeeeeeeff -ee3300000000001100000055aaccaaaa9988778888887755553300000000000000115566 -776622000000000000113377bbddccdddddd -00000000000000000000000000336677777788777788aa99661100000000000000000000 -000000117799aaccccccccbbbbaa99440000000000000000002288ddeeeeeeeeffeeeeee -dd22000000000000110000002288aaaaaa99778888778877776644000000000000002222 -22110000000000000000003388aaccddddee -000000000000000000000022667777887788777799884411000000000000000000000000 -0000000077aabbccddddccccddccddbb88442200000000000088ffeeeeeeeeffeeeeeeff -dd1100000000000000110000000044aabbaa999999888888665566440000000000000000 -0000000000000000000000001155bbccdddd -000000000000000022556688776688888877887733000000000000000000000000000000 -0000000055bbccddccddddddddeeeedddddd8800000011110000bbffeeeeeeeeffeeeeff -dd1100000000000000001100000000224444667777778888887766555500000000000000 -00000000000000000000000000003388ccdd -000000001133558899998888887788998899660000000000000000000000000000000000 -0000000022aaccddddddeeeeeeeeeeeeeedd330000117766447733ddeeeeffeeeeeeeeff -aa0000000000000000000000000000000000000000113344667788887766110000000000 -000000000000000000000000000000117799 -0000446688aabb88aa999988998888999977000000000000000000000000000000000000 -0000000000aaccddeeeeeeeeeeeeeeeeffaa00000044dd7788ee77aaeeffeeeeffeeffff -880000000000000000000000000000000000000000000000001122222233441100000000 -000000000000000000000000000000000033 -777788aa9988888888888899aa8899886600000000000000000000000000000000000000 -000000000088ddeeeeeeeeeeeeeeeeffeeaa550066bbdd99cceeccaaffeeeeeeeeffeeff -550000000000000000000000000000000000000000000000000000000000113322000000 -000000000000000000000000000000000000 -884422331100000000000022331100000000000000000000000000000000000000000000 -000000000077ddeeeeeeffeeffffffffbbaa6611aaddeecceeeeeebbeeffeeffffeeffee -440000000000000000000000000000000000000000000000000000000000000022110000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000077ddeeeeeeeeffeeeeffcc1111113399bbee88cceeee99aaffffeeffeeeeee -330000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000044ddeeeeeeeeffeeeeff66002266001166ee66aaeeee6666ffeeeeeeeeffdd -110000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000022ddeeeeeeeeeeffffcc11001155003388eeddddeebb2211ddffeeffeeffcc -110000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000aaffeeeeffeeeeff8800000088221155cceebbbb55000088ffeeeeeeffcc -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000077eeeeeeeeeeeeee3300000088660055ccdd554411000044ffffffeeffbb -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000022ddffeeffffff990055330055990077dddd221111330011ccffeeffff88 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000bbffeeeeeeee442299770022aa0077dddd442266bb9944aaffeeffff88 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000066ffeeeeff882288ddaa000077331188993399eeeeffcc99eeeeeeff77 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000011ddffeeffaa99ddeecc11001111001199bbeeeeeeeeeebbddffeecc11 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000066ffeeeeffeeeeeeee2200000066bbddeeeeeeeeeeffddcceebb5500 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000055ddeeeeeeeeffee550055aaaacceeccddffffeeeeeeeeeeffcc00 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000aaffeeffeeeeee66337788bbeeeeeeeeffeeffeeeeeeeeffcc00 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000033cceeeeeeeeeeee440066ddeeeeeeeeeeeeeeeeffeeffeeffbb00 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000055eeeeffeeffeeee88aacceeddeeeeeeeeeeeeffeeeeffeeff8800 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000011ddeeeeeeeeeeeeddddddeeeeeeeeffeeeeffeeffffeeffff6600 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000088ffeeffeeeeeeeeeeddeeeeeeffeeeeeeeeffeeeeffeeff4400 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000033eeeeeeffeeeeeeeeeeffeeeeeeeeeeddeeeeeeeeffeeee3300 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000011bbffeeeeffeeddeeddddbbaaaaddddcceeffeeffeeffee2200 -000000000000000000000000000000000000000000000000000000002200220000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000088ffeeeeeeddddcc9999aaaaddeeeeeeffeeffeeeeffcc0000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000044eeffeeffccddddccddeeeeeeeeeeeeeeeeeeffffffaa0000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000099ffcc5544cceeddddeeddccddeeddddeeeeeeeeff990000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000044ff9911004499aabbccccccccddbbaabbccddffff660000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000011ccbb996655bbbbaaccbbbbddddaaaaccddcceeee550000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000006688000066ddcccceeeeeeeeffeeddccaabbeeff330000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000001144000066eeeeeeddccbbbbbb7722220022bbee110000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000022665599aaccbbaabb775588778899cc000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000002211001177bbddbbaabbaa99ddeedd8844000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000110077bbddddeeffeeeeffeeffaa00000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000088aaeeffeeddccbbcc776655996600000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000778877555533445588113355882200000000 -441100000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000007799ccccddbbddeeee3300000000 -331100000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000001155bbeeeeeeeeffeeeeeeff5500000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000004488ddeeeeeeeeeeeeeeeedd2200000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000033bbddeeeeeeffeeeeffaa0000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000088ccddeeeeeeeeeeff880000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000044aaeeeeffeeeeeeff550000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000001188ddccccddbb9988000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000022222233774422000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000116699aaccddbb44000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000002288888888992200000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000002255661100000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000011000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000113355882200000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000011778899771100000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000002244110000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000110000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000001100 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000001100 -000000000000000000000000000000000000000000000000000000000033110000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000022440000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000011220000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000001100000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000001100000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000001100000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000110000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000001100000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000 -001100110011001100110011001100110000000000000000000000000000000000000000 -000000000000000000000000000000000000000000221100000000000000000000001111 -110000001100001100110000110000000000000000000000000000000000000000001100 -001100000000000000000000110000001100 - -showpage - -% stop using temporary dictionary -end - -% restore original state -origstate restore - -%%Trailer diff --git a/lib/docbuilder/doc/src/notes.xml b/lib/docbuilder/doc/src/notes.xml deleted file mode 100644 index 95f24ea9ca..0000000000 --- a/lib/docbuilder/doc/src/notes.xml +++ /dev/null @@ -1,256 +0,0 @@ -<?xml version="1.0" encoding="latin1" ?> -<!DOCTYPE chapter SYSTEM "chapter.dtd"> - -<chapter> - <header> - <copyright> - <year>2007</year><year>2011</year> - <holder>Ericsson AB. All Rights Reserved.</holder> - </copyright> - <legalnotice> - The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved online at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - the License for the specific language governing rights and limitations - under the License. - - </legalnotice> - - <title>DocBuilder Release Notes</title> - <prepared>otp_appnotes</prepared> - <docno>nil</docno> - <date>nil</date> - <rev>nil</rev> - <file>notes.xml</file> - </header> - <p>This document describes the changes made to the DocBuilder - application.</p> - -<section><title>Docbuilder 0.9.8.11</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - The docbuilder application has been deprecated and will - be removed in the R15 release.</p> - <p> - Own Id: OTP-9509</p> - </item> - </list> - </section> - -</section> - -<section><title>Docbuilder 0.9.8.10</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> fop 1.0 crashed when building the docbuilder pdf with - the following message - "java.lang.IllegalArgumentException: factor < 0; was: - -1". <br/> This is a known bug in fop 1.0 (fop bug id: - Bug 50524) when there is a word that consist of a single - soft hyphen (&shy;). this has been fixed in fop - source archive but not it's not in a release yet. It's - fixed in our documentation by removing the soft hyphens - where this is a problem. </p> - <p> - Own Id: OTP-9143</p> - </item> - </list> - </section> - -</section> - -<section><title>Docbuilder 0.9.8.9</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> Fix compatibility issues with docbuilder for R11 - documentation patches. </p> - <p> - Own Id: OTP-8946</p> - </item> - </list> - </section> - -</section> - -<section><title>Docbuilder 0.9.8.8</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> Fixed problem with a centered table that was - transformed into an xml document which then produced - mis-formatted html. </p> - <p> - Own Id: OTP-8784</p> - </item> - </list> - </section> - -</section> - -<section><title>Docbuilder 0.9.8.7</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p>The documentation is now possible to build in an open - source environment after a number of bugs are fixed and - some features are added in the documentation build - process. </p> - <p>- The arity calculation is updated.</p> - <p>- The module prefix used in the function names for - bif's are removed in the generated links so the links - will look like - "http://www.erlang.org/doc/man/erlang.html#append_element-2" - instead of - "http://www.erlang.org/doc/man/erlang.html#erlang:append_element-2".</p> - <p>- Enhanced the menu positioning in the html - documentation when a new page is loaded.</p> - <p>- A number of corrections in the generation of man - pages (thanks to Sergei Golovan)</p> - <p>- The legal notice is taken from the xml book file so - OTP's build process can be used for non OTP - applications.</p> - <p> - Own Id: OTP-8343</p> - </item> - </list> - </section> - -</section> - -<section><title>Docbuilder 0.9.8.6</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - The documentation is now built with open source tools - (xsltproc and fop) that exists on most platforms. One - visible change is that the frames are removed.</p> - <p> - Own Id: OTP-8201</p> - </item> - </list> - </section> - -</section> - -<section><title>Docbuilder 0.9.8.5</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p>The copyright notices have been updated.</p> - <p> - Own Id: OTP-7851</p> - </item> - </list> - </section> - -</section> - -<section><title>Docbuilder 0.9.8.4</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> - The element "code" with multiple CDATA or CDATA plus - other data now works as expected, previously it caused a - crash.</p> - <p> - Own Id: OTP-7236</p> - </item> - </list> - </section> - -</section> - -<section><title>Docbuilder 0.9.8</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - The generated html should now be valid xhtml (with a few - exceptions to be fixed in next version).</p> - <p> - Own Id: OTP-7027</p> - </item> - </list> - </section> - -</section> - - <section><title>Docbuilder 0.9.7</title> - - <section><title>Improvements and New Features</title> - <list> - <item> - <p> - New fonts and new CSS style included in generated html documents. - </p> - </item> - <item> - <p> - Updated DTD's with new header elements copyright and legalnotice. - Element authors changed to optional instead of mandatory. - - </p> - </item> - </list> - </section> - </section> - - <section><title>Docbuilder 0.9.1</title> - - <section><title>Fixed Bugs and Malfunctions</title> - <list> - <item> - <p> - Line breaks within <c>pre</c> are now always preserved.</p> - <p> - The definition of <c>name</c> in the cref DTD is now - correctly handled.</p> - <p> - <c>docb_transform</c>: The HTML snippet returned by the - <c>Module:head()</c> callback function is now placed - below the title in the HTML file (as specified in the - documentation), not on the same line.</p> - <p> - <c>docb_gen</c>: Added option <c>sort_functions</c>.</p> - <p> - Fixed bugs in cites and terms DTD, and also in book, - bookinsidecover and report DTDs which are not officially - supported (yet).</p> - <p> - License info added to all DTD files.</p> - <p> - Corrections and clarifications made to the User's Guide.</p> - <p> - Own Id: OTP-6775</p> - </item> - </list> - </section> - </section> - - <section> - <title>DocBuilder 0.9</title> - <p>First version of DocBuilder released as part of Erlang/OTP. - Previously it has been used as an internal tool only.</p> - </section> -</chapter> - diff --git a/lib/docbuilder/doc/src/overview.xml b/lib/docbuilder/doc/src/overview.xml deleted file mode 100644 index ca13c5d436..0000000000 --- a/lib/docbuilder/doc/src/overview.xml +++ /dev/null @@ -1,185 +0,0 @@ -<?xml version="1.0" encoding="latin1" ?> -<!DOCTYPE chapter SYSTEM "chapter.dtd"> - -<chapter> - <header> - <copyright> - <year>1997</year><year>2009</year> - <holder>Ericsson AB. All Rights Reserved.</holder> - </copyright> - <legalnotice> - The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved online at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - the License for the specific language governing rights and limitations - under the License. - - </legalnotice> - <title>Overview</title> - <prepared></prepared> - <docno></docno> - <date></date> - <rev></rev> - <file>overview.xml</file> - </header> - - <section> - <title>Background</title> - - <p>DocBuilder has been used within the OTP project to generate - documentation for Erlang/OTP itself for more than ten years. - It has now been released as a regular Erlang/OTP application.</p> - - <p>The intention with DocBuilder is that it should be as easy to - use and maintain as possible and generate adequate documentation - for OTP's needs. It uses frames, which can probably be regarded as - old-fashioned today. Hopefully, this should be improved in - the future.</p> - - <p>Originally, DocBuilder input was SGML files and external tools - was used for parsing. The internal version used in the OTP - project can generate not only HTML code but also LaTeX (for PDF - and PostScript) and nroff (for UNIX man pages). (Again, using - external tools). Because of this, the parsed source code is - transformed into a tree structure before being transformed again - into the desired format.</p> - </section> - - <section> - <title>DTD Suite</title> - - <p>Input is written as XML according to one of the DTDs and output - is corresponding HTML. Documentation for an Erlang/OTP application - is usually organized as follows:</p> - <taglist> - <tag><em>User's Guide</em></tag> - <item> - <p>(DTD: - <seealso marker="user_guide_dtds#partDTD">part</seealso>) - A collection of chapters - (<seealso marker="user_guide_dtds#chapterDTD">chapter</seealso>). - </p> - </item> - - <tag><em>Reference Manual</em></tag> - <item> - <p>(DTD: - <seealso marker="refman_dtds#applicationDTD">application</seealso> - A collection of manual pages for modules - (<seealso marker="refman_dtds#erlrefDTD">erlref</seealso>), - applications - (<seealso marker="refman_dtds#apprefDTD">appref</seealso>), - commands - (<seealso marker="refman_dtds#comrefDTD">comref</seealso>), - C libraries - (<seealso marker="refman_dtds#crefDTD">cref</seealso>) and - files - (<seealso marker="refman_dtds#filerefDTD">fileref</seealso>). - </p> - </item> - - <tag><em>Release Notes</em></tag> - <item> - <p>Same structure as the User's Guide.</p> - </item> - </taglist> - - <p>In some cases, one or more of the User's Guide, Reference Manual - and Release Notes are omitted. Also, it is possible to use either - the <c>application</c> or <c>part</c> DTD to write other types - of documentation for the application.</p> - - <p>A special kind of DTD, - <seealso marker="fasc_dtds">fascicules</seealso>, can be used to - specify the different parts of the documentation, and which one - of those should be shown as default.</p> - </section> - - <section> - <title>Structure of Generated HTML</title> - - <p>The generated HTML corresponding to a <c>part</c> or - <c>application</c> document is split into a left frame and a right - frame. The left frame contains information about the document - and links to the included files, that is chapters or manual pages. - The right frame is used to display either the front page for - the document, or the selected chapter/manual page.</p> - - <p>The left frame also contains links to a bibliography and a - glossary, which are automatically generated.</p> - - <p>In the case of an <c>application</c> document, the left frame - also contains a link to an automatically generated index.</p> - </section> - - <section> - <title>Basic Tags</title> - - <p>All DTDs in the DocBuilder DTD suite share a basic set of tags. - An author can easily switch from one DTD to another and still use - the same basic tags. It is furthermore easy to copy pieces of - information from one document to another, even though they do not - use the same DTD.</p> - - <p>The basic set of tags are divided into two categories: - <seealso marker="block_tags">block tags</seealso> and - <seealso marker="inline_tags">inline tags</seealso>. Block tags - typically define a separate block of information, like a - paragraph or a list. Inline tags are typically used within block - tags, for example a highlighted word within a paragraph.</p> - </section> - - <section> - <title>About This Document</title> - - <p>In this User's Guide, the structure of the different documents - and the meaning of the tags are explained. There are numerous - examples of documentation source code.</p> - - <p>For readability and simplicity, the examples have been kept as - short as possible. For an example of what the generated HTML - will look like, it is recommended to look at the DocBuilder - documentation itself:</p> - <list> - <item>This User's Guide is written using the <c>part</c> and - <c>chapter</c> DTDs.</item> - - <item>The Reference Manual is written using - the <c>application</c>, <c>appref</c> and <c>erlref</c> DTDs. - </item> - </list> - </section> - - <section> - <title>Usage</title> - - <list type="ordered"> - <item> - <p>Create the relevant XML files.</p> - - <p>If there are EDoc comments in a module, the function - <seealso marker="docb_gen#module/1">docb_gen:module/1,2</seealso> - can be used to generate an XML file according to - the <c>erlref</c> DTD for this module.</p> - </item> - - <item> - <p>The XML files can be validated using - <seealso marker="docb_xml_check#validate/1">docb_xml_check:validate/1</seealso>. - </p> - </item> - - <item> - <p>Generate HTML files by using - <seealso marker="docb_transform#file/1">docb_transform:file/1,2</seealso>. - </p> - </item> - </list> - </section> -</chapter> - diff --git a/lib/docbuilder/doc/src/part_notes.xml b/lib/docbuilder/doc/src/part_notes.xml deleted file mode 100644 index 2f824630fb..0000000000 --- a/lib/docbuilder/doc/src/part_notes.xml +++ /dev/null @@ -1,37 +0,0 @@ -<?xml version="1.0" encoding="latin1" ?> -<!DOCTYPE part SYSTEM "part.dtd"> - -<part xmlns:xi="http://www.w3.org/2001/XInclude"> - <header> - <copyright> - <year>2007</year><year>2009</year> - <holder>Ericsson AB. All Rights Reserved.</holder> - </copyright> - <legalnotice> - The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved online at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - the License for the specific language governing rights and limitations - under the License. - - </legalnotice> - - <title>DocBuilder Release Notes</title> - <prepared></prepared> - <docno></docno> - <date></date> - <rev></rev> - </header> - <description> - <p><em>Docbuilder</em> provides functionality for generating HTML - documentation for Erlang modules and Erlang/OTP applications - from XML source code and/or EDoc comments in Erlang source code.</p> - </description> - <xi:include href="notes.xml"/> -</part> - diff --git a/lib/docbuilder/dtd/Makefile b/lib/docbuilder/dtd/Makefile deleted file mode 100644 index 05c656f3fc..0000000000 --- a/lib/docbuilder/dtd/Makefile +++ /dev/null @@ -1,91 +0,0 @@ -# ``The contents of this file are subject to the Erlang Public License, -# Version 1.1, (the "License"); you may not use this file except in -# compliance with the License. You should have received a copy of the -# Erlang Public License along with this software. If not, it can be -# retrieved via the world wide web at http://www.erlang.org/. -# -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -# the License for the specific language governing rights and limitations -# under the License. -# -# The Initial Developer of the Original Code is Ericsson Utvecklings AB. -# Portions created by Ericsson are Copyright 1999-2000, Ericsson -# Utvecklings AB. All Rights Reserved.'' -# -# $Id$ -# - -include $(ERL_TOP)/make/target.mk -include $(ERL_TOP)/make/$(TARGET)/otp.mk - -# ---------------------------------------------------- -# Application version -# ---------------------------------------------------- -include ../vsn.mk -VSN=$(DOCB_VSN) - -# ---------------------------------------------------- -# Release directory specification -# ---------------------------------------------------- -RELSYSDIR = $(RELEASE_PATH)/lib/docbuilder-$(VSN) - -# ---------------------------------------------------- -# Common Macros -# ---------------------------------------------------- - -DTD_FILES = \ - application.dtd \ - appref.dtd \ - book.dtd \ - bookinsidecover.dtd \ - chapter.dtd \ - cites.dtd \ - common.dtd \ - common.entities.dtd \ - common.header.dtd \ - common.image.dtd \ - common.refs.dtd \ - common.table.dtd \ - comref.dtd \ - cref.dtd \ - erlref.dtd \ - fascicules.dtd \ - fileref.dtd \ - part.dtd \ - report.dtd \ - terms.dtd \ - xhtml-lat1.ent \ - xhtml-special.ent \ - xhtml-symbol.ent \ - xhtml1-frameset.dtd \ - xhtml1-strict.dtd \ - xhtml1-transitional.dtd - -# ---------------------------------------------------- -# Targets -# ---------------------------------------------------- - -debug opt: - -clean: - -docs: - -# ---------------------------------------------------- -# Release Target -# ---------------------------------------------------- -include $(ERL_TOP)/make/otp_release_targets.mk - -release_spec: - $(INSTALL_DIR) $(RELSYSDIR)/dtd - $(INSTALL_DATA) $(DTD_FILES) $(RELSYSDIR)/dtd - -release_docs_spec: - - - - - - - diff --git a/lib/docbuilder/dtd/common.dtd b/lib/docbuilder/dtd/common.dtd deleted file mode 100644 index 2c4ad51ab1..0000000000 --- a/lib/docbuilder/dtd/common.dtd +++ /dev/null @@ -1,87 +0,0 @@ -<!-- - ``The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved via the world wide web at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See - the License for the specific language governing rights and limitations - under the License. - - The Initial Developer of the Original Code is Ericsson AB. - Portions created by Ericsson are Copyright 1999-2007, Ericsson AB. - All Rights Reserved.'' - - $Id$ ---> -<!-- This file contains common stuff for all dtds. --> - -<!ENTITY % common.entities SYSTEM "common.entities.dtd" > -%common.entities; - -<!ENTITY % block "p|pre|code|list|taglist|codeinclude| - erleval" > -<!ENTITY % inline "#PCDATA|c|em|term|cite|br|path|seealso| - url|marker" > -<!-- XXX --> -<!ELEMENT p (%inline;)* > -<!ELEMENT pre (#PCDATA|seealso|url|input)* > -<!ELEMENT input (#PCDATA|seealso|url)* > -<!ELEMENT code (#PCDATA) > -<!ATTLIST code type (erl|c|none) "none" > -<!ELEMENT quote (p)* > -<!ELEMENT warning (%block;|quote|br|marker)* > -<!ELEMENT note (%block;|quote|br|marker)* > -<!ELEMENT c (#PCDATA) > -<!ELEMENT em (#PCDATA|c)* > - -<!-- XXX --> -<!ELEMENT term (termdef?) > -<!ATTLIST term id CDATA #REQUIRED > -<!ELEMENT termdef (#PCDATA) > -<!ELEMENT cite (citedef?) > -<!ATTLIST cite id CDATA #REQUIRED > -<!ELEMENT citedef (ctitle,cauthor,chowpublished) > -<!ELEMENT ctitle (#PCDATA) > -<!ELEMENT cauthor (#PCDATA) > -<!ELEMENT chowpublished (#PCDATA) > - -<!-- XXX --> -<!ELEMENT br EMPTY > - -<!-- Path --> - -<!ELEMENT path (#PCDATA) > -<!ATTLIST path unix CDATA "" - windows CDATA "" > - -<!-- List --> - -<!ELEMENT list (item+) > -<!ATTLIST list type (ordered|bulleted) "bulleted" > -<!ELEMENT taglist (tag,item)+ > -<!ELEMENT tag (#PCDATA|c|em|seealso|url)* > -<!ELEMENT item (%inline;|%block;)* > - -<!-- References --> - -<!ELEMENT seealso (#PCDATA) > -<!ATTLIST seealso marker CDATA #REQUIRED > -<!ELEMENT url (#PCDATA) > -<!ATTLIST url href CDATA #REQUIRED > -<!ELEMENT marker EMPTY > -<!ATTLIST marker id CDATA #REQUIRED > - -<!-- CodeInclude --> - -<!ELEMENT codeinclude EMPTY > -<!ATTLIST codeinclude file CDATA #REQUIRED - tag CDATA "" - type (erl|c|none) "none" > - -<!-- ErlEval --> - -<!ELEMENT erleval EMPTY > -<!ATTLIST erleval expr CDATA #REQUIRED > diff --git a/lib/docbuilder/dtd/common.refs.dtd b/lib/docbuilder/dtd/common.refs.dtd deleted file mode 100644 index 7b9974fbda..0000000000 --- a/lib/docbuilder/dtd/common.refs.dtd +++ /dev/null @@ -1,40 +0,0 @@ -<!-- - ``The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved via the world wide web at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See - the License for the specific language governing rights and limitations - under the License. - - The Initial Developer of the Original Code is Ericsson AB. - Portions created by Ericsson are Copyright 1999-2007, Ericsson AB. - All Rights Reserved.'' - - $Id$ ---> -<!-- This file contains common stuff for the *ref.dtd files. - Note that `name' is defined in each *ref.dtd. --> - -<!ENTITY % common SYSTEM "common.dtd" > -%common; -<!ENTITY % common.header SYSTEM "common.header.dtd" > -%common.header; - -<!ELEMENT description (%block;|quote|br|marker|warning|note)* > -<!ELEMENT funcs (func)+ > -<!ELEMENT func (name+,fsummary,type?,desc?) > -<!-- ELEMENT name is defined in each ref dtd --> -<!ELEMENT fsummary (#PCDATA|c|em)* > -<!ELEMENT type (v,d?)+ > -<!ELEMENT v (#PCDATA) > -<!ELEMENT d (#PCDATA|c|em)* > -<!ELEMENT desc (%block;|quote|br|marker|warning|note)* > -<!ELEMENT authors (aname,email)+ > -<!ELEMENT aname (#PCDATA) > -<!ELEMENT email (#PCDATA) > -<!ELEMENT section (marker*,title,(%block;|quote|br|marker| - warning|note)*) > diff --git a/lib/docbuilder/dtd/erlref.dtd b/lib/docbuilder/dtd/erlref.dtd deleted file mode 100644 index 21656a1446..0000000000 --- a/lib/docbuilder/dtd/erlref.dtd +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<!-- - ``The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved via the world wide web at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See - the License for the specific language governing rights and limitations - under the License. - - The Initial Developer of the Original Code is Ericsson AB. - Portions created by Ericsson are Copyright 1999-2007, Ericsson AB. - All Rights Reserved.'' - - $Id$ ---> - -<!ENTITY % common.refs SYSTEM "common.refs.dtd" > -%common.refs; - -<!ELEMENT erlref (header,module,modulesummary,description, - (section|funcs)*,authors?) > -<!ELEMENT module (#PCDATA) > -<!ELEMENT modulesummary (#PCDATA) > - -<!-- `name' is used in common.refs.dtd and must therefore - be defined in each *ref. dtd --> -<!ELEMENT name (#PCDATA) > diff --git a/lib/docbuilder/dtd/xhtml-lat1.ent b/lib/docbuilder/dtd/xhtml-lat1.ent deleted file mode 100644 index aaae738cfc..0000000000 --- a/lib/docbuilder/dtd/xhtml-lat1.ent +++ /dev/null @@ -1,196 +0,0 @@ -<!-- Portions (C) International Organization for Standardization 1986 - Permission to copy in any form is granted for use with - conforming SGML systems and applications as defined in - ISO 8879, provided this notice is included in all copies. ---> -<!-- Character entity set. Typical invocation: - <!ENTITY % HTMLlat1 PUBLIC - "-//W3C//ENTITIES Latin 1 for XHTML//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent"> - %HTMLlat1; ---> - -<!ENTITY nbsp " "> <!-- no-break space = non-breaking space, - U+00A0 ISOnum --> -<!ENTITY iexcl "¡"> <!-- inverted exclamation mark, U+00A1 ISOnum --> -<!ENTITY cent "¢"> <!-- cent sign, U+00A2 ISOnum --> -<!ENTITY pound "£"> <!-- pound sign, U+00A3 ISOnum --> -<!ENTITY curren "¤"> <!-- currency sign, U+00A4 ISOnum --> -<!ENTITY yen "¥"> <!-- yen sign = yuan sign, U+00A5 ISOnum --> -<!ENTITY brvbar "¦"> <!-- broken bar = broken vertical bar, - U+00A6 ISOnum --> -<!ENTITY sect "§"> <!-- section sign, U+00A7 ISOnum --> -<!ENTITY uml "¨"> <!-- diaeresis = spacing diaeresis, - U+00A8 ISOdia --> -<!ENTITY copy "©"> <!-- copyright sign, U+00A9 ISOnum --> -<!ENTITY ordf "ª"> <!-- feminine ordinal indicator, U+00AA ISOnum --> -<!ENTITY laquo "«"> <!-- left-pointing double angle quotation mark - = left pointing guillemet, U+00AB ISOnum --> -<!ENTITY not "¬"> <!-- not sign = discretionary hyphen, - U+00AC ISOnum --> -<!ENTITY shy "­"> <!-- soft hyphen = discretionary hyphen, - U+00AD ISOnum --> -<!ENTITY reg "®"> <!-- registered sign = registered trade mark sign, - U+00AE ISOnum --> -<!ENTITY macr "¯"> <!-- macron = spacing macron = overline - = APL overbar, U+00AF ISOdia --> -<!ENTITY deg "°"> <!-- degree sign, U+00B0 ISOnum --> -<!ENTITY plusmn "±"> <!-- plus-minus sign = plus-or-minus sign, - U+00B1 ISOnum --> -<!ENTITY sup2 "²"> <!-- superscript two = superscript digit two - = squared, U+00B2 ISOnum --> -<!ENTITY sup3 "³"> <!-- superscript three = superscript digit three - = cubed, U+00B3 ISOnum --> -<!ENTITY acute "´"> <!-- acute accent = spacing acute, - U+00B4 ISOdia --> -<!ENTITY micro "µ"> <!-- micro sign, U+00B5 ISOnum --> -<!ENTITY para "¶"> <!-- pilcrow sign = paragraph sign, - U+00B6 ISOnum --> -<!ENTITY middot "·"> <!-- middle dot = Georgian comma - = Greek middle dot, U+00B7 ISOnum --> -<!ENTITY cedil "¸"> <!-- cedilla = spacing cedilla, U+00B8 ISOdia --> -<!ENTITY sup1 "¹"> <!-- superscript one = superscript digit one, - U+00B9 ISOnum --> -<!ENTITY ordm "º"> <!-- masculine ordinal indicator, - U+00BA ISOnum --> -<!ENTITY raquo "»"> <!-- right-pointing double angle quotation mark - = right pointing guillemet, U+00BB ISOnum --> -<!ENTITY frac14 "¼"> <!-- vulgar fraction one quarter - = fraction one quarter, U+00BC ISOnum --> -<!ENTITY frac12 "½"> <!-- vulgar fraction one half - = fraction one half, U+00BD ISOnum --> -<!ENTITY frac34 "¾"> <!-- vulgar fraction three quarters - = fraction three quarters, U+00BE ISOnum --> -<!ENTITY iquest "¿"> <!-- inverted question mark - = turned question mark, U+00BF ISOnum --> -<!ENTITY Agrave "À"> <!-- latin capital letter A with grave - = latin capital letter A grave, - U+00C0 ISOlat1 --> -<!ENTITY Aacute "Á"> <!-- latin capital letter A with acute, - U+00C1 ISOlat1 --> -<!ENTITY Acirc "Â"> <!-- latin capital letter A with circumflex, - U+00C2 ISOlat1 --> -<!ENTITY Atilde "Ã"> <!-- latin capital letter A with tilde, - U+00C3 ISOlat1 --> -<!ENTITY Auml "Ä"> <!-- latin capital letter A with diaeresis, - U+00C4 ISOlat1 --> -<!ENTITY Aring "Å"> <!-- latin capital letter A with ring above - = latin capital letter A ring, - U+00C5 ISOlat1 --> -<!ENTITY AElig "Æ"> <!-- latin capital letter AE - = latin capital ligature AE, - U+00C6 ISOlat1 --> -<!ENTITY Ccedil "Ç"> <!-- latin capital letter C with cedilla, - U+00C7 ISOlat1 --> -<!ENTITY Egrave "È"> <!-- latin capital letter E with grave, - U+00C8 ISOlat1 --> -<!ENTITY Eacute "É"> <!-- latin capital letter E with acute, - U+00C9 ISOlat1 --> -<!ENTITY Ecirc "Ê"> <!-- latin capital letter E with circumflex, - U+00CA ISOlat1 --> -<!ENTITY Euml "Ë"> <!-- latin capital letter E with diaeresis, - U+00CB ISOlat1 --> -<!ENTITY Igrave "Ì"> <!-- latin capital letter I with grave, - U+00CC ISOlat1 --> -<!ENTITY Iacute "Í"> <!-- latin capital letter I with acute, - U+00CD ISOlat1 --> -<!ENTITY Icirc "Î"> <!-- latin capital letter I with circumflex, - U+00CE ISOlat1 --> -<!ENTITY Iuml "Ï"> <!-- latin capital letter I with diaeresis, - U+00CF ISOlat1 --> -<!ENTITY ETH "Ð"> <!-- latin capital letter ETH, U+00D0 ISOlat1 --> -<!ENTITY Ntilde "Ñ"> <!-- latin capital letter N with tilde, - U+00D1 ISOlat1 --> -<!ENTITY Ograve "Ò"> <!-- latin capital letter O with grave, - U+00D2 ISOlat1 --> -<!ENTITY Oacute "Ó"> <!-- latin capital letter O with acute, - U+00D3 ISOlat1 --> -<!ENTITY Ocirc "Ô"> <!-- latin capital letter O with circumflex, - U+00D4 ISOlat1 --> -<!ENTITY Otilde "Õ"> <!-- latin capital letter O with tilde, - U+00D5 ISOlat1 --> -<!ENTITY Ouml "Ö"> <!-- latin capital letter O with diaeresis, - U+00D6 ISOlat1 --> -<!ENTITY times "×"> <!-- multiplication sign, U+00D7 ISOnum --> -<!ENTITY Oslash "Ø"> <!-- latin capital letter O with stroke - = latin capital letter O slash, - U+00D8 ISOlat1 --> -<!ENTITY Ugrave "Ù"> <!-- latin capital letter U with grave, - U+00D9 ISOlat1 --> -<!ENTITY Uacute "Ú"> <!-- latin capital letter U with acute, - U+00DA ISOlat1 --> -<!ENTITY Ucirc "Û"> <!-- latin capital letter U with circumflex, - U+00DB ISOlat1 --> -<!ENTITY Uuml "Ü"> <!-- latin capital letter U with diaeresis, - U+00DC ISOlat1 --> -<!ENTITY Yacute "Ý"> <!-- latin capital letter Y with acute, - U+00DD ISOlat1 --> -<!ENTITY THORN "Þ"> <!-- latin capital letter THORN, - U+00DE ISOlat1 --> -<!ENTITY szlig "ß"> <!-- latin small letter sharp s = ess-zed, - U+00DF ISOlat1 --> -<!ENTITY agrave "à"> <!-- latin small letter a with grave - = latin small letter a grave, - U+00E0 ISOlat1 --> -<!ENTITY aacute "á"> <!-- latin small letter a with acute, - U+00E1 ISOlat1 --> -<!ENTITY acirc "â"> <!-- latin small letter a with circumflex, - U+00E2 ISOlat1 --> -<!ENTITY atilde "ã"> <!-- latin small letter a with tilde, - U+00E3 ISOlat1 --> -<!ENTITY auml "ä"> <!-- latin small letter a with diaeresis, - U+00E4 ISOlat1 --> -<!ENTITY aring "å"> <!-- latin small letter a with ring above - = latin small letter a ring, - U+00E5 ISOlat1 --> -<!ENTITY aelig "æ"> <!-- latin small letter ae - = latin small ligature ae, U+00E6 ISOlat1 --> -<!ENTITY ccedil "ç"> <!-- latin small letter c with cedilla, - U+00E7 ISOlat1 --> -<!ENTITY egrave "è"> <!-- latin small letter e with grave, - U+00E8 ISOlat1 --> -<!ENTITY eacute "é"> <!-- latin small letter e with acute, - U+00E9 ISOlat1 --> -<!ENTITY ecirc "ê"> <!-- latin small letter e with circumflex, - U+00EA ISOlat1 --> -<!ENTITY euml "ë"> <!-- latin small letter e with diaeresis, - U+00EB ISOlat1 --> -<!ENTITY igrave "ì"> <!-- latin small letter i with grave, - U+00EC ISOlat1 --> -<!ENTITY iacute "í"> <!-- latin small letter i with acute, - U+00ED ISOlat1 --> -<!ENTITY icirc "î"> <!-- latin small letter i with circumflex, - U+00EE ISOlat1 --> -<!ENTITY iuml "ï"> <!-- latin small letter i with diaeresis, - U+00EF ISOlat1 --> -<!ENTITY eth "ð"> <!-- latin small letter eth, U+00F0 ISOlat1 --> -<!ENTITY ntilde "ñ"> <!-- latin small letter n with tilde, - U+00F1 ISOlat1 --> -<!ENTITY ograve "ò"> <!-- latin small letter o with grave, - U+00F2 ISOlat1 --> -<!ENTITY oacute "ó"> <!-- latin small letter o with acute, - U+00F3 ISOlat1 --> -<!ENTITY ocirc "ô"> <!-- latin small letter o with circumflex, - U+00F4 ISOlat1 --> -<!ENTITY otilde "õ"> <!-- latin small letter o with tilde, - U+00F5 ISOlat1 --> -<!ENTITY ouml "ö"> <!-- latin small letter o with diaeresis, - U+00F6 ISOlat1 --> -<!ENTITY divide "÷"> <!-- division sign, U+00F7 ISOnum --> -<!ENTITY oslash "ø"> <!-- latin small letter o with stroke, - = latin small letter o slash, - U+00F8 ISOlat1 --> -<!ENTITY ugrave "ù"> <!-- latin small letter u with grave, - U+00F9 ISOlat1 --> -<!ENTITY uacute "ú"> <!-- latin small letter u with acute, - U+00FA ISOlat1 --> -<!ENTITY ucirc "û"> <!-- latin small letter u with circumflex, - U+00FB ISOlat1 --> -<!ENTITY uuml "ü"> <!-- latin small letter u with diaeresis, - U+00FC ISOlat1 --> -<!ENTITY yacute "ý"> <!-- latin small letter y with acute, - U+00FD ISOlat1 --> -<!ENTITY thorn "þ"> <!-- latin small letter thorn with, - U+00FE ISOlat1 --> -<!ENTITY yuml "ÿ"> <!-- latin small letter y with diaeresis, - U+00FF ISOlat1 --> diff --git a/lib/docbuilder/ebin/.gitignore b/lib/docbuilder/ebin/.gitignore deleted file mode 100644 index e69de29bb2..0000000000 --- a/lib/docbuilder/ebin/.gitignore +++ /dev/null diff --git a/lib/docbuilder/etc/Makefile b/lib/docbuilder/etc/Makefile deleted file mode 100644 index a2f669d749..0000000000 --- a/lib/docbuilder/etc/Makefile +++ /dev/null @@ -1,67 +0,0 @@ -# ``The contents of this file are subject to the Erlang Public License, -# Version 1.1, (the "License"); you may not use this file except in -# compliance with the License. You should have received a copy of the -# Erlang Public License along with this software. If not, it can be -# retrieved via the world wide web at http://www.erlang.org/. -# -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -# the License for the specific language governing rights and limitations -# under the License. -# -# The Initial Developer of the Original Code is Ericsson Utvecklings AB. -# Portions created by Ericsson are Copyright 1999-2000, Ericsson -# Utvecklings AB. All Rights Reserved.'' -# -# $Id$ -# - -include $(ERL_TOP)/make/target.mk -include $(ERL_TOP)/make/$(TARGET)/otp.mk - -# ---------------------------------------------------- -# Application version -# ---------------------------------------------------- -include ../vsn.mk -VSN=$(DOCB_VSN) - -# ---------------------------------------------------- -# Release directory specification -# ---------------------------------------------------- -RELSYSDIR = $(RELEASE_PATH)/lib/docbuilder-$(VSN) - -# ---------------------------------------------------- -# Common Macros -# ---------------------------------------------------- - -VAR_FILES = \ - note.gif \ - warning.gif - -# ---------------------------------------------------- -# Targets -# ---------------------------------------------------- - -debug opt: - -clean: - -docs: - -# ---------------------------------------------------- -# Release Target -# ---------------------------------------------------- -include $(ERL_TOP)/make/otp_release_targets.mk - -release_spec: - $(INSTALL_DIR) $(RELSYSDIR)/etc - $(INSTALL_DATA) $(VAR_FILES) $(RELSYSDIR)/etc - -release_docs_spec: - - - - - - - diff --git a/lib/docbuilder/etc/note.gif b/lib/docbuilder/etc/note.gif Binary files differdeleted file mode 100644 index 6fffe30419..0000000000 --- a/lib/docbuilder/etc/note.gif +++ /dev/null diff --git a/lib/docbuilder/etc/warning.gif b/lib/docbuilder/etc/warning.gif Binary files differdeleted file mode 100644 index 96af52360e..0000000000 --- a/lib/docbuilder/etc/warning.gif +++ /dev/null diff --git a/lib/docbuilder/info b/lib/docbuilder/info deleted file mode 100644 index 60daa212c8..0000000000 --- a/lib/docbuilder/info +++ /dev/null @@ -1,2 +0,0 @@ -group: doc -short: Tool for generating HTML documentation for applications. diff --git a/lib/docbuilder/src/Makefile b/lib/docbuilder/src/Makefile deleted file mode 100644 index e8a07a54e8..0000000000 --- a/lib/docbuilder/src/Makefile +++ /dev/null @@ -1,121 +0,0 @@ -# ``The contents of this file are subject to the Erlang Public License, -# Version 1.1, (the "License"); you may not use this file except in -# compliance with the License. You should have received a copy of the -# Erlang Public License along with this software. If not, it can be -# retrieved via the world wide web at http://www.erlang.org/. -# -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -# the License for the specific language governing rights and limitations -# under the License. -# -# The Initial Developer of the Original Code is Ericsson Utvecklings AB. -# Portions created by Ericsson are Copyright 1999-2000, Ericsson -# Utvecklings AB. All Rights Reserved.'' -# -# $Id$ -# - -include $(ERL_TOP)/make/target.mk -include $(ERL_TOP)/make/$(TARGET)/otp.mk - -# ---------------------------------------------------- -# Application version -# ---------------------------------------------------- -include ../vsn.mk -VSN=$(DOCB_VSN) - -# ---------------------------------------------------- -# Release directory specification -# ---------------------------------------------------- -RELSYSDIR = $(RELEASE_PATH)/lib/docbuilder-$(VSN) - -# ---------------------------------------------------- -# Common Macros -# ---------------------------------------------------- - -MODULES= \ - docb_edoc_xml_cb \ - docb_gen \ - docb_html \ - docb_html_layout \ - docb_html_ref \ - docb_html_util \ - docb_html_util_iso \ - docb_main \ - docb_pretty_format \ - docb_tr_application2html \ - docb_tr_appref2html \ - docb_tr_chapter2html \ - docb_tr_cite2html \ - docb_tr_comref2html \ - docb_tr_cref2html \ - docb_tr_erlref2html \ - docb_tr_fileref2html \ - docb_tr_first2html \ - docb_tr_index2html \ - docb_tr_part2html \ - docb_tr_refs2kwic \ - docb_tr_report2html \ - docb_tr_term2html \ - docb_transform \ - docb_util \ - docb_xmerl_tree_cb \ - docb_xmerl_xml_cb \ - docb_xml_check - -HRL_FILES= \ - docb_util.hrl - -ERL_FILES= $(MODULES:%=%.erl) - -TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) - -APP_FILE= docbuilder.app -APPUP_FILE= docbuilder.appup -APP_SRC= $(APP_FILE).src -APPUP_SRC= $(APPUP_FILE).src -APP_TARGET= $(EBIN)/$(APP_FILE) -APPUP_TARGET= $(EBIN)/$(APPUP_FILE) - -# ---------------------------------------------------- -# FLAGS -# ---------------------------------------------------- -ERL_FLAGS += -XMERL = ../../xmerl -ERL_COMPILE_FLAGS += -I$(XMERL)/include - -# ---------------------------------------------------- -# Targets -# ---------------------------------------------------- - -debug opt: $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) - -clean: - rm -f $(TARGET_FILES) $(APP_TARGET) - rm -f errs core *~ - -$(APP_TARGET): $(APP_SRC) ../vsn.mk - sed -e 's;%VSN%;$(VSN);' $< > $@ -$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk - sed -e 's;%VSN%;$(VSN);' $< > $@ - -docs: - -# ---------------------------------------------------- -# Release Target -# ---------------------------------------------------- -include $(ERL_TOP)/make/otp_release_targets.mk - -release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) $(RELSYSDIR)/ebin - -release_docs_spec: - - - - - diff --git a/lib/docbuilder/src/docb_gen.erl b/lib/docbuilder/src/docb_gen.erl deleted file mode 100644 index 75494314f1..0000000000 --- a/lib/docbuilder/src/docb_gen.erl +++ /dev/null @@ -1,142 +0,0 @@ -%% ``The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. -%% Portions created by Ericsson are Copyright 1999-2000, Ericsson -%% Utvecklings AB. All Rights Reserved.'' -%% -%% $Id$ -%% --module(docb_gen). - --export([module/1, module/2, users_guide/1, users_guide/2]). --deprecated([{module,1,next_major_release}, - {module,2,next_major_release}, - {users_guide,1,next_major_release}, - {users_guide,2,next_major_release}]). - --record(args, {suffix=".xml", - layout=docb_edoc_xml_cb, - def=[], - includes=[], - preprocess=false, - sort_functions=true}). - -%% module(File) -> ok | {error, Reason} -%% module(File, Opts) -> ok | {error, Reason} -%% File = string(), file name with or without ".erl" extension -%% Opts -- see code -%% Reason = badfile | {badopt, Term} -module(File0) -> - module(File0, []). -module(File0, RawOpts) -> - File = case filename:extension(File0) of - ".erl" -> File0; - _ -> File0++".erl" - end, - case filelib:is_regular(File) of - true -> - case parse(RawOpts, #args{}) of - {ok, Args} -> - Opts = [{def, Args#args.def}, - {includes, Args#args.includes}, - {preprocess, Args#args.preprocess}, - {sort_functions, Args#args.sort_functions}, - - {app_default, "OTPROOT"}, - {file_suffix, Args#args.suffix}, - {dir, "."}, - {layout, Args#args.layout}], - edoc:file(File, Opts); - Error -> - Error - end; - false -> - {error, badfile} - end. - -%% users_guide(File) -> ok | {error, Reason} -%% users_guide(File, Opts) -> ok | {error, Reason} -%% File = string() -%% Opts -- see code -%% Reason = badfile | {badopt, Opt} -users_guide(File) -> - users_guide(File, []). -users_guide(File, RawOpts) -> - case filelib:is_regular(File) of - true -> - case parse(RawOpts, #args{}) of - {ok, Args} -> - Opts = [{def, Args#args.def}, - {app_default, "OTPROOT"}, - {file_suffix, Args#args.suffix}, - {layout, Args#args.layout}], - - Env = edoc_lib:get_doc_env(Opts), - - {ok, Tags} = - edoc_extract:file(File, overview, Env, Opts), - Data = - edoc_data:overview("Overview", Tags, Env, Opts), - F = fun(M) -> M:overview(Data, Opts) end, - Text = edoc_lib:run_layout(F, Opts), - - OutFile = "chapter" ++ Args#args.suffix, - edoc_lib:write_file(Text, ".", OutFile); - Error -> - Error - end; - false -> - {error, badfile} - end. - -parse([{output,xml} | RawOpts], Args) -> - parse(RawOpts, Args); % default, no update of record necessary -parse([{output,sgml} | RawOpts], Args) -> - parse(RawOpts, Args#args{suffix=".sgml", layout=docb_edoc_sgml_cb}); -parse([{def,Defs} | RawOpts], Args) -> - case parse_defs(Defs) of - true -> - Args2 = Args#args{def=Args#args.def++Defs}, - parse(RawOpts, Args2); - false -> - {error, {badopt, {def,Defs}}} - end; -parse([{includes,Dirs} | RawOpts], Args) -> - case parse_includes(Dirs) of - true -> - Args2 = Args#args{includes=Args#args.includes++Dirs}, - parse(RawOpts, Args2); - false -> - {error, {badopt, {includes,Dirs}}} - end; -parse([{preprocess,Bool} | RawOpts], Args) when Bool==true; - Bool==false -> - parse(RawOpts, Args#args{preprocess=Bool}); -parse([{sort_functions,Bool} | RawOpts], Args) when Bool==true; - Bool==false -> - parse(RawOpts, Args#args{sort_functions=Bool}); -parse([], Args) -> - {ok, Args}; -parse([Opt | _RawOpts], _Args) -> - {error, {badopt, Opt}}. - -parse_defs(Defs) -> - lists:all(fun({Key,Val}) when is_atom(Key), is_list(Val) -> true; - (_) -> false - end, - Defs). - -parse_includes(Dirs) -> - lists:all(fun(Dir) when is_list(Dir) -> true; - (_) -> false - end, - Dirs). diff --git a/lib/docbuilder/src/docb_html.erl b/lib/docbuilder/src/docb_html.erl deleted file mode 100644 index bdfc5ea876..0000000000 --- a/lib/docbuilder/src/docb_html.erl +++ /dev/null @@ -1,393 +0,0 @@ -%% ``The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. -%% Portions created by Ericsson are Copyright 1999-2000, Ericsson -%% Utvecklings AB. All Rights Reserved.'' -%% -%% $Id$ -%% --module(docb_html). - --export([rule/2, rule/3]). - -rule([p, item, list|_], {_, _, _}) -> - {"", "<br />\n"}; -rule([p, item, taglist|_], {_, _, _}) -> - {"", "<br />\n"}; -rule([p|_], _) -> - {"\n<p>", "\n</p>"}; - -rule([pre|_], _) -> - {"\n<div class=\"example\"><pre>\n", "\n</pre></div>\n"}; - -rule([input|_], _) -> - {"<strong>", "</strong>"}; - -rule([quote|_], _) -> - {"\n<blockquote>\n", "\n</blockquote>\n"}; - -rule([i|_], _) -> - {"<em>", "</em>"}; - -rule([b|_], _) -> - {"<strong>", "</strong>"}; - -rule([c|_], _) -> - {"<span class=\"code\">", "</span>"}; - -rule([em|_], _) -> - {"<strong>", "</strong>"}; - -rule([sub|_], _) -> - {"<sub>", "</sub>"}; - -rule([sup|_], _) -> - {"<sup>", "</sup>"}; - -rule([termdef|_], _) -> - {drop, ""}; - -rule([citedef|_], _) -> - {drop, ""}; - -rule([br|_], _) -> - {"<br />\n", ""}; - -rule([digression|_], _) -> - {"<table>\n" - " <tr>\n" - " <td width=\"23\"></td>\n" - " <td>\n" - " <font size=\"-1\">\n", - " </font>\n" - " </td>\n" - " </tr>\n" - "</table>\n"}; - -rule([list, item, list|_], {_, ["ORDERED"], _}) -> - {"\n<ol>\n", "\n</ol>\n"}; -rule([list, item, taglist|_], {_, ["ORDERED"], _}) -> - {"\n<ol>\n", "\n</ol>\n"}; -rule([list|_], {_, ["ORDERED"], _}) -> - {"\n<ol>\n", "\n</ol>\n"}; -rule([list, item, list|_], {_, ["BULLETED"], _}) -> - {"\n<ul>\n", "\n</ul>\n"}; -rule([list, item, taglist|_], {_, ["BULLETED"], _}) -> - {"\n<ul>\n", "\n</ul>\n"}; -rule([list|_], {_, ["BULLETED"], _}) -> - {"\n<ul>\n", "\n</ul>\n"}; - -rule([taglist, item, taglist|_], _) -> - {"\n<dl>\n", "\n</dl>\n"}; -rule([taglist, item, list|_], _) -> - {"\n<dl>\n", "\n</dl>\n"}; -rule([taglist|_], _) -> - {"\n<dl>\n", "\n</dl>\n"}; - -rule([tag|_], _) -> - {"\n<dt>\n", "\n</dt>\n"}; - -rule([item, list|_], _) -> - {"\n<li>\n", "\n</li>\n\n"}; -rule([item, taglist|_], _) -> - {"\n<dd>\n", "\n</dd>\n"}; - -rule([image|_], {_, [File], _}) -> - File2 = - case filename:extension(File) of - [] -> File ++ ".gif"; - _ -> File - end, - {["\n<center>\n", "<img alt=\"", File2, "\" src=\"", File2, - "\"/><br/>\n"], - "\n</center>\n"}; - -rule([icaption|_], _) -> - {"<em>", "</em>\n"}; - -rule([url|_], {_, [HREF], _}) -> - URI = docb_html_util:make_uri(HREF), - {io_lib:format("<a target=\"_top\" href=\"~s\">", [URI]), "</a>"}; - -rule([marker|_], {_, [ID], _}) -> - %% remove all chars before first # including the # - {ok, NewID, _} = regexp:sub(ID, "^[^#]*#", ""), - %% replace "/" with "-" because "/" xhtml does not - %% allow "/" in the name attribute of element <a> - %% so we have to do the same as for marker i.e - %% Function/Arity is translated to an anchor in xhtml - %% like this : <a name="Function-Arity"/> - NewID2 = [case X of $/ -> $-;_->X end||X <- NewID], - {drop, ["<a name=\"", NewID2, "\"><!-- Empty --></a>"]}; - -rule([table|_], {_, ["", ""], Ts}) -> - {newargs, - "\n<center>\n" - "<table cellspacing=\"0\" cellpadding=\"2\" border=\"1\">\n", - reorder_table(Ts), - "\n</table>\n" - "</center>\n"}; -rule([table|_], {_, [Width, ""], Ts}) -> - {newargs, - ["\n<center>\n" - "<table cellspacing=\"0\" cellpadding=\"2\" border=\"1\" ", - "width=\"", Width, "%\">\n"], - reorder_table(Ts), - "\n</table>\n" - "</center>\n"}; - -%% The clauses above are for the report DTD. This one is for the other -%% DTDs. -rule([table|_], {_, ["LEFT"], Ts}) -> - {newargs, - "\n" - "<table cellspacing=\"0\" cellpadding=\"2\" border=\"1\">\n", - reorder_table(Ts), - "\n</table>\n"}; - -rule([table|_], {_, _, Ts}) -> - {newargs, - "\n<center>\n" - "<table cellspacing=\"0\" cellpadding=\"2\" border=\"1\">\n", - reorder_table(Ts), - "\n</table>\n" - "</center>\n"}; - -rule([row|_], _) -> - {" <tr>\n", "\n </tr>\n"}; - -rule([cell|_], {_, ["", ""], _}) -> - {" <td>\n", "\n </td>\n"}; -rule([cell|_], {_, [Align, ""], _}) -> - {[" <td align=\"", string:to_lower(Align), "\">\n"], "\n </td>\n"}; -rule([cell|_], {_, ["", VAlign], _}) -> - {[" <td valign=\"", string:to_lower(VAlign), "\">\n"], "\n </td>\n"}; -rule([cell|_], {_, [Align, VAlign], _}) -> - {[" <td align=\"", string:to_lower(Align), "\" valign=\"", string:to_lower(VAlign), "\">\n"], - "\n </td>\n"}; - -rule([tcaption|_], _) -> - {" <caption align=\"bottom\"><em>", "</em></caption>\n"}; - -rule([codeinclude|_], {_, [File, Tag, _Type], _}) -> -%% Type can be "ERL", "C" or "NONE" - {ok,Data} = docb_html_util:code_include(File, Tag), - {drop, ["\n<div class=\"example\"><pre>\n", Data, - "\n</pre></div>\n"]}; - -rule([erleval|_], {_, [Expr], _}) -> - docb_html_util:erl_eval(Expr); - -rule([pcdata, pre|_], {_, _, Data}) -> - %% Do not remove leading spaces. - {drop, docb_html_util:pcdata_to_html(Data, false)}; - -rule([pcdata|_], {_, _, Data}) -> - {drop, docb_html_util:pcdata_to_html(Data)}. - -rule([seealso|_], {_, [Marker], _}, Opts) -> - Href = - case docb_util:html_snippet(seealso, Marker, Opts) of - "" -> - %% DocBuilder default behavior: - %% Marker is of format "Path#Fragment", both optional. - %% Translated to <A HREF="Path.html#Fragment"> - case string:chr(Marker, $#) of - 0 -> % No Fragment - Marker++".html"; - 1 -> % No Path - %% replace "/" with "-" because "/" xhtml does not - %% allow "/" in the name attribute of element <a> - %% so we have to do the same as for marker i.e - %% Function/Arity is translated to an anchor in xhtml - %% like this : <a name="Function-Arity"/> - [case X of $/ -> $-;_->X end||X <- Marker]; - _ -> - Marker1 = [case X of $/ -> $-;_->X end||X <- Marker], - case string:tokens(Marker1, "#") of - [Path] -> % # at end, remove it - Path++".html"; - [Path | Frag0] -> - Path++".html#"++ - docb_util:join(Frag0, "#") - end - end; - Href0 -> - %% User defined behavior, use result as-is - Href0 - end, - {{["<a href=\"", Href, "\">"], "</a>"}, Opts}; - -rule([warning|_], _, Opts) -> - docb_html_util:copy_pics("warning.gif", "warning.gif", Opts), - {{"\n<div class=\"warning\">\n" - "<div class=\"label\">Warning</div>\n" - "<div class=\"content\">\n", - "\n</div>" - "\n</div>\n"}, Opts}; - -rule([note|_], _, Opts) -> - docb_html_util:copy_pics("note.gif", "note.gif", Opts), - {{"\n<div class=\"note\">\n" - "<div class=\"label\">Note</div>\n" - "<div class=\"content\">", - "\n</div>" - "\n</div>\n"}, Opts}; - -rule([path|_], {_, [UNIX, Windows], [{pcdata, _, Text}]}, Opts) -> - UnixPart = - docb_util:an_option({ptype,"unix"}, Opts) and (UNIX/=""), - WinPart = - docb_util:an_option({ptype,"windows"}, Opts) and (Windows/=""), - if - UnixPart, WinPart -> - {{drop, [docb_html_util:pcdata_to_html(Text), - " <font size=\"-2\">(<code>UNIX: ", - docb_html_util:attribute_cdata_to_html(UNIX), - ", ", - "Windows: ", - docb_html_util:attribute_cdata_to_html(Windows), - "</code>)</font>"]}, - Opts}; - UnixPart -> - {{drop, [docb_html_util:pcdata_to_html(Text), - " <font size=\"-1\">(<code>UNIX: ", - docb_html_util:attribute_cdata_to_html(UNIX), - "</code>)</font>"]}, - Opts}; - WinPart -> - {{drop, [docb_html_util:pcdata_to_html(Text), - " <font size=\"-1\">(<code>Windows: ", - docb_html_util:attribute_cdata_to_html(Windows), - "</code>)</font>"]}, - Opts}; - true -> - {{drop, docb_html_util:pcdata_to_html(Text)}, Opts} - end; - -rule([term|_], {_, [ID], _}, Opts) -> - case docb_util:an_option(dict, Opts) of - false -> - case docb_util:lookup_option({defs, term}, Opts) of - false -> - {{drop, ["<em><strong>", - ID, - "</strong></em> "]}, Opts}; - TermList -> - case lists:keyfind(ID, 1, TermList) of - false -> - {{drop, ["<em><strong>", ID, - "</strong></em> "]}, - Opts}; - {ID, Name, _Description, _Resp} -> - {{drop, ["<em><strong>", Name, - "</strong></em> "]}, - Opts}; - {ID, Name, _Description} -> - {{drop, [ "<em><strong>", Name, - "</strong></em> "]}, - Opts} - end - end; - true -> - case docb_util:lookup_option({defs, term}, Opts) of - false -> - {{drop, ["<em><strong>", ID, - "</strong></em> "]}, Opts}; - TermList -> - PartApplication = - docb_util:lookup_option(part_application, Opts), - case lists:keyfind(ID, 1, TermList) of - false -> - {{drop, ["<a href=\"", PartApplication, - "_term.html#", ID, "\">", ID, - "</a> "]}, Opts}; - {ID, Name, _Description, _Resp} -> - {{drop, ["<a href=\"", PartApplication, - "_term.html#", ID, "\">", Name, - "</a> "]}, Opts}; - {ID, Name, _Description} -> - {{drop, ["<a href=\"", PartApplication, - "_term.html#", ID, "\">", Name, - "</a> "]}, Opts} - end - end - end; - -rule([cite|_], {_, [ID], _}, Opts) -> - case docb_util:an_option(dict, Opts) of - false -> - case docb_util:lookup_option({defs, cite}, Opts) of - false -> - {{drop, ["<em><strong>", ID, "</strong></em> "]}, - Opts}; - CiteList -> - case lists:keyfind(ID, 1, CiteList) of - false -> - {{drop, - ["<em><strong>", ID, "</strong></em> "]}, - Opts}; - {ID, Name, _Description, _Resp} -> - {{drop, ["<em><strong>", Name, - "</strong></em> "]}, - Opts}; - {ID, Name, _Description} -> - {{drop, ["<em><strong>", Name, - "</strong></em> "]}, - Opts} - end - end; - true -> - case docb_util:lookup_option({defs, cite}, Opts) of - false -> - {{drop, ["<em><strong>", ID, "</strong></em> "]}, - Opts}; - CiteList -> - PartApp = - docb_util:lookup_option(part_application, Opts), - case lists:keyfind(ID, 1, CiteList) of - false -> - {{drop, ["<a href=\"", PartApp, - "_cite.html#", ID, "\">", ID, - "</a> "]}, - Opts}; - {ID, Name, _Description, _Resp} -> - {{drop, ["<a href=\"", PartApp, - "_cite.html#", ID, "\">", Name, - "</a> "]}, - Opts}; - {ID, Name, _Description} -> - {{drop, ["<a href=\"", PartApp, - "_cite.html#", ID, "\">", Name, - "</a> "]}, - Opts} - end - end - end; - -rule([code|_], {_, [Type], [{pcdata, _, Code}]}, Opts) -> - case lists:member(Type, ["ERL","C","NONE"]) of - true -> - {{drop, ["\n<div class=\"example\"><pre>\n", docb_html_util:element_cdata_to_html(Code), - "\n</pre></div>\n"]}, Opts}; - false -> - exit({error,"unknown type of <code>"}) - end. - -reorder_table(TableContent) -> - reorder_table(TableContent, [], []). -reorder_table([], Caption, NewTableContent) -> - Caption ++ lists:reverse(NewTableContent); -reorder_table([{tcaption,_,_} = Caption | TableContent], _, NewTableContent) -> - reorder_table(TableContent, [Caption], NewTableContent); -reorder_table([Row | TableContent], Caption, NewTableContent) -> - reorder_table(TableContent, Caption, [Row | NewTableContent]). diff --git a/lib/docbuilder/src/docb_html_layout.erl b/lib/docbuilder/src/docb_html_layout.erl deleted file mode 100644 index dca80ac58e..0000000000 --- a/lib/docbuilder/src/docb_html_layout.erl +++ /dev/null @@ -1,380 +0,0 @@ -%% ``The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. -%% Portions created by Ericsson are Copyright 1999-2000, Ericsson -%% Utvecklings AB. All Rights Reserved.'' -%% -%% $Id$ -%% --module(docb_html_layout). - --export([report_top/2, report_bot/1, - first_top/2, first_bot/1, - ref_top/2, ref_bot/1, - chapter_top/2, chapter_bot/1, - application_toc_top/3, application_toc_top/4, - part_toc_top/3, part_toc_top/4, part_toc_bot/0, - index_top/1, index_bot/0]). - -%% Report - -report_top(Data, Opts) -> - [Title, Prepared, _Responsible, DocNo, _Approved, _Checked, _Date, - Vsn0, _File] = Data, - html_header(Title, Opts) ++ - docb_util:html_snippet(top, Opts) ++ -"<center> -<h1>" ++ Title ++ "</h1> -<big> - " ++ DocNo ++ version(Opts, Vsn0) ++ "<br /> - " ++ Prepared ++ "<br /> -</big> -</center> -". - -report_bot(Opts) -> - docb_util:html_snippet(bottom, Opts) ++ -"</body> -</html> -". - -%% First - -first_top(Data, Opts) -> - [Title, _Prepared, _Responsible, DocNo, _Approved, _Checked, _Date, - Vsn0, _File] = Data, - html_header(Title, Opts) ++ - docb_util:html_snippet(top, Opts) ++ -"<center> -<h1>" ++ Title ++ "</h1> -<big>" ++ DocNo ++ version(Opts, Vsn0) ++ "<br /> -</big> -</center> -". - -first_bot(Opts) -> - report_bot(Opts). - -%% Reference - -ref_top(Data, Opts) -> - [Title, _Prepared, _Responsible, _DocNo, _Approved, _Checked, - _Date, _Rev, _File] = Data, - ref_html_header(Title, Opts) ++ -"<!-- refpage -->\n" ++ - docb_util:html_snippet(top, Opts) ++ -"<center> -<h1>" ++ Title ++ "</h1> -</center>". - -ref_bot(Opts) -> - docb_util:html_snippet(bottom, Opts) ++ -"</body> -</html> -". - -%% Chapter - -chapter_top(Data, Opts) -> - [Title, _Prepared, _Responsible, _DocNo, _Approved, _Checked, - _Date, _Rev, _File] = Data, - html_header(Title, Opts) ++ - docb_util:html_snippet(top, Opts). - -chapter_bot(Opts) -> - report_bot(Opts). - -%% Application ToC - -application_toc_top(Data, DocName, Opts) -> - [Title, _Prepared, _Responsible, DocNo, _Approved, _Checked, - _Date, Vsn0, _File] = Data, - html_header(Title, []) ++ -"<center> -<strong>" ++ Title ++ "</strong> -<p> -<small> - " ++ DocNo ++ version(Opts, Vsn0) ++ " -</small> -</p> -<p> -<small> - <a target=\"document\" href=\"" ++ DocName ++ "_cite.html\">Bibliography</a> | - <a target=\"document\" href=\"" ++ DocName ++ "_term.html\">Glossary</a> | - <a target=\"document\" href=\"" ++ DocName ++ "_index.html\">Index</a> | - <a target=\"document\" href=\"" ++ DocName ++ "_first.html\">Cover</a>" ++ top_index(Opts) ++ -"</small> -</p> -</center> -<p> -<small> -<strong>Table of Contents</strong> -</small> -</p> -". - -application_toc_top(Data, DocName, Opts, HRefTexts) -> - [Title, _Prepared, _Responsible, DocNo, _Approved, _Checked, - _Date, Vsn0, _File] = Data, - html_header(Title, []) ++ -"<center> -<small> -" ++ - docb_util:join( - lists:map( - fun({HRef, Text}) -> - "<a target=\"_top\" href=\"" ++ HRef ++ "\">" ++ - Text ++ "</a>" - end, - HRefTexts), " | ") ++ top_index(Opts) ++ -"</small> -<p> -<strong>" ++ Title ++ "</strong> -</p> -<p> -<small>" ++ DocNo ++ version(Opts, Vsn0) ++ "<br /> -</small> -</p> -<p> -<small> - <a target=\"document\" href=\"" ++ DocName ++ "_cite.html\">Bibliography</a> | - <a target=\"document\" href=\"" ++ DocName ++ "_term.html\">Glossary</a> | - <a target=\"document\" href=\"" ++ DocName ++ "_index.html\">Index</a> | - <a target=\"document\" href=\"" ++ DocName ++ "_first.html\">Cover</a> -</small> -</p> -</center> -<p> -<small> -<strong>Table of Contents</strong> -</small> -</p> -". - -%% Part ToC - -part_toc_top(Data, DocName, Opts) -> - [Title, _Prepared, _Responsible, DocNo, _Approved, _Checked, - _Date, Vsn0, _File] = Data, - html_header(Title, []) ++ -"<center> -<p> -<strong>" ++ Title ++ "</strong> -</p> -<p> -<small>" ++ DocNo ++ version(Opts, Vsn0) ++ "<br /> -</small> -</p> -<p> -<small> - <a target=\"document\" href=\"" ++ DocName ++ "_cite.html\">Bibliography</a> | - <a target=\"document\" href=\"" ++ DocName ++ "_term.html\">Glossary</a> | - <a target=\"document\" href=\"" ++ DocName ++ "_first.html\">Cover</a>" ++ - top_index(Opts) ++ -"</small> -</p> -</center> -<p> -<small> -<strong>Table of Contents</strong> -</small> -</p> -". - -part_toc_top(Data, DocName, Opts, HRefTexts) -> - [Title, _Prepared, _Responsible, DocNo, _Approved, _Checked, - _Date, Vsn0, _File] = Data, - html_header(Title, []) ++ -"<center> -<p> -<small> -" ++ - docb_util:join( - lists:map( - fun({HRef, Text}) -> - "<a target=\"_top\" href=\"" ++ HRef ++ "\">" ++ - Text ++ "</a>" - end, - HRefTexts), " | ") ++ top_index(Opts) ++ -"</small> -</p> -<p> -<strong>" ++ Title ++ "</strong> -</p> -<p> -<small> - " ++ DocNo ++ version(Opts, Vsn0) ++ "<br /> -</small> -</p> -<p> -<small> - <a target=\"document\" href=\"" ++ DocName ++ "_cite.html\">Bibliography</a> | - <a target=\"document\" href=\"" ++ DocName ++ "_term.html\">Glossary</a> | - <a target=\"document\" href=\"" ++ DocName ++ "_first.html\">Cover</a> -</small> -</p> -</center> -<p> -<small> -<strong>Table of Contents</strong> -</small> -</p> -". - -part_toc_bot() -> -"</body > -</html> -". - -%% Index - -index_top(_Data) -> - ref_html_header("INDEX", []) ++ -"<h1>INDEX</h1> -<p><em>Emphasized</em> index entries refer to <em>modules</em> -and <code>Courier</code> ditos to <code>functions</code>.\n</p>\n". - -index_bot() -> - part_toc_bot(). - -%% Internal functions - -html_header(Title, Opts) -> - Vsn = docb_util:version(), -%%"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"> -"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" - \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"> -<!-- This document was generated using DocBuilder-" ++ Vsn ++ " --> -<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\"> -<head> - <title>" ++ Title ++ "</title> - <meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\"/> - " ++ docb_util:html_snippet(head, Opts) ++ " - <style type=\"text/css\"> -<!-- - body { font-family: Verdana, Arial, Helvetica, sans-serif } - span.bold_code { font-family: courier;font-weight: bold} - span.code { font-family: courier;font-weight: normal} - -.note, .warning { - border: solid black 1px; - margin: 1em 3em; -} - -.note .label { - background: #30d42a; - color: white; - font-weight: bold; - padding: 5px 10px; -} -.note .content { - background: #eafeea; - color: black; - line-height: 120%; - font-size: 90%; - padding: 5px 10px; -} -.warning .label { - background: #C00; - color: white; - font-weight: bold; - padding: 5px 10px; -} -.warning .content { - background: #FFF0F0; - color: black; - line-height: 120%; - font-size: 90%; - padding: 5px 10px; -} - - .example { background-color:#eeeeff } - pre { font-family: courier; font-weight: normal } - .REFBODY { margin-left: 13mm } - .REFTYPES { margin-left: 8mm } ---> - </style> -</head> -<body bgcolor=\"#FFFFFF\" text=\"#000000\" link=\"#0000FF\" vlink=\"#FF00FF\" alink=\"#FF0000\"> -". - -ref_html_header(Title, Opts) -> - Vsn = docb_util:version(), -%%"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"> -"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" - \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"> -<!-- This document was generated using DocBuilder-" ++ Vsn ++ " --> -<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\"> -<head> - <title>" ++ Title ++ "</title> - <meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\"/> - " ++ docb_util:html_snippet(head, Opts) ++ " - <style type=\"text/css\"> -<!-- - body { font-family: Verdana, Arial, Helvetica, sans-serif } - span.bold_code { font-family: courier;font-weight: bold} - span.code { font-family: courier;font-weight: normal} - -.note, .warning { - border: solid black 1px; - margin: 1em 3em; -} - -.note .label { - background: #30d42a; - color: white; - font-weight: bold; - padding: 5px 10px; -} -.note .content { - background: #eafeea; - color: black; - line-height: 120%; - font-size: 90%; - padding: 5px 10px; -} -.warning .label { - background: #C00; - color: white; - font-weight: bold; - padding: 5px 10px; -} -.warning .content { - background: #FFF0F0; - color: black; - line-height: 120%; - font-size: 90%; - padding: 5px 10px; -} - - .example { background-color:#eeeeff } - pre { font-family: courier; font-weight: normal } - .REFBODY { margin-left: 13mm } - .REFTYPES { margin-left: 8mm } ---> - </style> -</head> -<body bgcolor=\"#FFFFFF\" text=\"#000000\" link=\"#0000FF\" vlink=\"#FF00FF\" alink=\"#FF0000\"> -". - -version(Opts, Vsn0) -> - case docb_util:lookup_option(vsn, Opts, Vsn0) of - "" -> ""; - Vsn -> " Version " ++ Vsn - end. - -top_index(Opts) -> - case docb_util:lookup_option(top, Opts) of - false -> ""; - TIFile -> - " | <a target=\"_top\" href=\"" ++ TIFile ++ "\">Top</a>" - end. diff --git a/lib/docbuilder/src/docb_html_ref.erl b/lib/docbuilder/src/docb_html_ref.erl deleted file mode 100644 index c5c166f1ae..0000000000 --- a/lib/docbuilder/src/docb_html_ref.erl +++ /dev/null @@ -1,79 +0,0 @@ -%% ``The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. -%% Portions created by Ericsson are Copyright 1999-2000, Ericsson -%% Utvecklings AB. All Rights Reserved.'' -%% -%% $Id$ -%% --module(docb_html_ref). - --export([rule/2, rule/3]). - -rule([description|_],_) -> - {"\n<h3>DESCRIPTION</h3>\n<div class=\"REFBODY\">\n","\n</div>\n"}; - -rule([funcs|_],_) -> - {"\n<h3>EXPORTS</h3>\n",""}; - -rule([func|_],_) -> - {"\n<p>",""}; - -rule([name, func, funcs, RefType|_], {_,_,[{pcdata,[],Name0}]}) -> - Name1 = docb_html_util:make_anchor_name_short(Name0, RefType), - {"<a name=\"" ++ Name1 ++ "\"><span class=\"bold_code\">", - "</span></a><br/>\n"}; - -rule([fsummary|_],_) -> - {drop, "\n</p>\n"}; - -rule([type|_], _) -> - {"\n<div class=\"REFBODY\"><p>Types:</p>\n <div class=\"REFTYPES\">\n<p>\n", - "\n </p> </div>\n</div>\n"}; - -rule([v|_], _) -> - {"<span class=\"bold_code\">","</span><br/>\n"}; - -rule([d|_], _) -> - {"\n<div class=\"REFBODY\">\n","\n</div>\n"}; - -rule([desc|_], _) -> - {"\n<div class=\"REFBODY\">\n","\n</div>\n"}; - -rule([authors|_], _) -> - {"\n<h3>AUTHORS</h3>\n<div class=\"REFBODY\">\n","\n</div>\n"}; - -rule([aname|_], _) -> - {"", " - "}; - -rule([section|_], {1,_,_}) -> - {"", ""}; -rule([section|_], {_N,_,_}) -> - {"", "\n</div>\n"}; - -rule([title|_], _) -> - {"\n<h3>", "</h3>\n<div class=\"REFBODY\">\n"}; - -rule(TagHistory, TagBody) -> - docb_html:rule(TagHistory, TagBody). - -rule([email|_], _, Opts) -> - case docb_util:html_snippet(email, Opts) of - "" -> - {{"","<br/>\n"}, Opts}; - Email -> - {{drop, Email++"<br/>\n"}, Opts} - end; - -rule(TagHistory, TagBody, Opts) -> - docb_html:rule(TagHistory, TagBody, Opts). - diff --git a/lib/docbuilder/src/docb_html_util.erl b/lib/docbuilder/src/docb_html_util.erl deleted file mode 100644 index 02ce8b52a7..0000000000 --- a/lib/docbuilder/src/docb_html_util.erl +++ /dev/null @@ -1,542 +0,0 @@ -%% ``The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. -%% Portions created by Ericsson are Copyright 1999-2000, Ericsson -%% Utvecklings AB. All Rights Reserved.'' -%% -%% $Id$ -%% --module(docb_html_util). - --export([attribute_cdata_to_html/1, - element_cdata_to_html/1, - pcdata_to_html/1, pcdata_to_html/2]). --export([copy_pics/3]). --export([extract_header_data/2, all_header_data/1]). --export([make_uri/1, - make_anchor_href/1, make_anchor_href_short/3, - make_anchor_name_short/2, - make_funcdef_short/2]). --export([erl_include/2, code_include/2, erl_eval/1]). --export([number/3, count_sections/1]). --export([format_toc/1]). --export([html_latin1_sort_order/1]). - -%%--Handle CDATA and PCDATA--------------------------------------------- - -%% NB: Functions for transforming sgmls/XMerL data output to html. -%% Do not use these for included text files (cf code_include and -%% erl_include). - -attribute_cdata_to_html(Data) -> - data2html(Data, false). - -element_cdata_to_html(Data) -> - data2html(Data, false). - -pcdata_to_html(Data) -> - data2html(Data, true). - -pcdata_to_html(Data, RmSp) -> - data2html(Data, RmSp). - -%% PCDATA, CDATA: Replace entities, and optionally delete -%% leading and multiple spaces. CDATA never contains entities to -%% replace. - -%% data2html(Cs, RmSpace) -data2html([246| Cs], RmSp) -> - [$&, $#, $2, $4, $6, $;| data2html(Cs, RmSp)]; -data2html([$>| Cs], RmSp) -> - [$&, $#, $6, $2, $;| data2html(Cs, RmSp)]; -data2html([$<| Cs], RmSp) -> - [$&, $#, $6, $0, $;| data2html(Cs, RmSp)]; -data2html([$&| Cs], RmSp) -> - [$&, $#, $3, $8, $;| data2html(Cs, RmSp)]; -data2html([$\"| Cs], RmSp) -> - [$&, $#, $3, $4, $;| data2html(Cs, RmSp)]; -data2html([$\n| Cs], RmSp) -> - data2html(Cs, RmSp); -data2html([$\\, $n| Cs], false) -> - [$\n| data2html(Cs, false)]; -data2html([$\\, $n| Cs], true) -> - [$\n| data2html(delete_leading_space(Cs), true)]; -data2html([$ , $ | Cs], true) -> % delete multiple space - [$ | data2html(delete_leading_space(Cs), true)]; -data2html([$\\, $|| Cs0], RmSp) -> - {Ent, Cs1} = collect_entity(Cs0), - [entity_to_html(Ent)| data2html(Cs1, RmSp)]; -data2html([$\\, $0, $1, $2| Cs], RmSp) -> - data2html(Cs, RmSp); -data2html([$\\, $\\, $n| Cs], RmSp) -> - [$\\, $n| data2html(Cs, RmSp)]; -data2html([$\\, O1, O2, O3| Cs], RmSp) - when O1 >= $0, O1 =< $7, O2 >= $0, O2 =< $7, O3 >= $0, O3 =< $7 -> - case octal2dec(O1, O2, O3) of - 173 -> % soft hyphen - data2html(Cs, RmSp); - C when C > 31, C < 256 -> - Ent = io_lib:format("&#~w;", [C]), - [Ent| data2html(Cs, RmSp)]; - C -> - [C| data2html(Cs, RmSp)] - end; -data2html([$\\, $\\| Cs], RmSp) -> - [$\\| data2html(Cs, RmSp)]; -data2html([C| Cs], RmSp) -> - [C| data2html(Cs, RmSp)]; -data2html([], _) -> - []. - -delete_leading_space([$ | Cs]) -> - delete_leading_space(Cs); -delete_leading_space(Cs) -> - Cs. - -collect_entity(Data) -> - collect_entity(Data, []). - -collect_entity([$\\, $|| Cs], Rs) -> - {lists:reverse(Rs), Cs}; -collect_entity([C| Cs], Rs) -> - collect_entity(Cs, [C| Rs]); -collect_entity([], Rs) -> - {[], lists:reverse(Rs)}. - -entity_to_html("&") -> "&"; -entity_to_html("\"") -> """; -entity_to_html("<") -> "<"; -entity_to_html(">") -> ">"; -entity_to_html([$\\, O1, O2, O3]) - when O1 >= $0, O1 =< $7, O2 >= $0, O2 =< $7, O3 >= $0, O3 =< $7 -> - case octal2dec(O1, O2, O3) of - 173 -> % soft hyphen - ""; - Value -> - io_lib:format("&#~w;", [Value]) - end; -entity_to_html(Other) -> - docb_html_util_iso:entity_to_html(Other). - -octal2dec(O1, O2, O3) -> - (O1*8+O2)*8+O3-73*$0. - -%%--Copy images--------------------------------------------------------- - -copy_pics(Src, Dest, Opts) -> - Dir = code:lib_dir(docbuilder), - InFile = filename:join([Dir, "etc", Src]), - OutFile = docb_util:outfile(Dest, "", Opts), - case filelib:last_modified(OutFile) of - 0 -> % File doesn't exist - file:copy(InFile, OutFile); - - OutMod2 -> - InMod1s = calendar:datetime_to_gregorian_seconds( - filelib:last_modified(InFile)), - OutMod2s = calendar:datetime_to_gregorian_seconds(OutMod2), - if - InMod1s > OutMod2s -> % InFile is newer than OutFile - file:copy(InFile, OutFile); - true -> - ok - end - end. - -%%--Resolve header data------------------------------------------------- - -extract_header_data(Key, {header, [], List}) -> - case lists:keyfind(Key, 1, List) of - {Key, [], []} -> - ""; - {Key, [], [{pcdata, [], Value}]} -> - pcdata_to_html(Value); - false -> - "" - end. - -all_header_data(Header) -> - all_header_data(Header, - [title, prepared, responsible, docno, approved, - checked, date, rev, file]). - -all_header_data(_Header, []) -> - []; -all_header_data(Header, [Key| Rest]) -> - [extract_header_data(Key, Header) | all_header_data(Header, Rest)]. - -%%--Resolve hypertext references---------------------------------------- - -%% URI regular expression (RFC 2396): -%% "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?" -%% We split it in five parts: -%% scheme: "^(([^:/?#]+):)?" (includes trailing `:') -%% authority: "^(//([^/?#]*))?" (includes leading `//') -%% path: "^([^?#]*)" -%% query: "^(\\?([^#]*))?" (includes leading `?') -%% fragment: "^(#(.*))?" (includes leading `#') - -make_uri(Cs) -> - lists:flatmap( - fun({path, S}) -> - case regexp:match(S, "\.xml?\$") of - {match, _, _} -> - {ok, NS, _} = regexp:sub(S, "\.xml?\$", ".html"), - NS; - _ -> - S - end; - ({_, S}) -> - S - end, - split_uri(Cs)). - -split_uri(URI) -> - split_uri(URI, [{scheme, "^(([^:/?#]+):)?"}, - {authority, "^(//([^/?#]*))?"}, - {path, "^([^?#]*)"}, - {'query', "^(\\?([^#]*))?"}, - {fragment, "^(#(.*))?"}]). - -split_uri("", [{Tag, _R}| T]) -> - [{Tag, ""}| split_uri("", T)]; -split_uri(Cs0, [{Tag, R}| T]) -> - {match, 1, N} = regexp:match(Cs0, R), - Cs1 = string:substr(Cs0, 1, N), - Cs2 = strip_and_escape_uri_component(Tag, Cs1), - [{Tag, Cs2}| split_uri(string:substr(Cs0, N+1), T)]; -split_uri(_, []) -> - []. - -strip_and_escape_uri_component(authority, "//" ++ Cs) -> - "//" ++ escape_uri(string:strip(Cs)); -strip_and_escape_uri_component(path, Cs) -> - escape_uri(string:strip(Cs)); -strip_and_escape_uri_component('query', "?" ++ Cs) -> - "?" ++ escape_uri(string:strip(Cs)); -strip_and_escape_uri_component(fragment, "#" ++ Cs) -> - "#" ++ escape_uri(string:strip(Cs)); -strip_and_escape_uri_component(_, "") -> - ""; -strip_and_escape_uri_component(_, Cs) -> - escape_uri(string:strip(Cs)). - -escape_uri([C|Cs]) when C =< 32; - C == $<; C == $<; C == $#; C == $%; C == $"; - C == $?; - C == ${; C == $}; C ==$|; C == $\\; C == $^; - C == $[; C == $]; C ==$'; - C >= 127 -> - [$%, mk_hex(C div 16), mk_hex(C rem 16)| escape_uri(Cs)]; -escape_uri([C|Cs]) -> - [C|escape_uri(Cs)]; -escape_uri([]) -> - []. - -mk_hex(C) when C<10 -> - C + $0; -mk_hex(C) -> - C - 10 + $a. - -make_anchor_href(HRef) -> - case regexp:split(HRef, "#") of - {ok, [HRef]} -> - %% No `#' in HRef, i.e. only path - make_anchor_href(HRef, ""); - {ok, [Path, Fragment]} -> - make_anchor_href(Path, Fragment) - end. - -make_anchor_href(Path0, Frag0) -> - Frag1 = string:strip(Frag0), - Path1 = case Path0 of - "" -> - ""; - _ -> - case regexp:match(Path0, "\.xml?\$") of - nomatch -> - Path0 ++ ".html"; - _ -> - {ok, NewPath, _} = regexp:sub(Path0, - "\.xml?\$", - ".html"), - NewPath - end - end, - case Frag1 of - "" -> - attribute_cdata_to_html(Path1); - _ -> - attribute_cdata_to_html(Path1) ++ - "#" ++ - attribute_cdata_to_html([case Ch of $/ -> $-; _ -> Ch end|| - Ch <-Frag1]) - end. - -make_anchor_href_short(Path, Frag, RefType) -> - ShortFrag = make_funcdef_short(Frag, RefType,"-"), - make_anchor_href(Path, ShortFrag). - -make_anchor_name_short(FuncName0, RefType) -> - FuncName1 = make_funcdef_short(FuncName0, RefType,"-"), - attribute_cdata_to_html(FuncName1). - -make_funcdef_short(FuncDef0, RefType) -> - make_funcdef_short(FuncDef0, RefType, "/"). - -make_funcdef_short(FuncDef0, RefType,Delimiter) -> - FuncDef1 = docb_util:trim(FuncDef0), - Any0 = case lists:member(RefType, [cref, erlref]) of - true -> - case catch docb_util:fknidx(FuncDef1, Delimiter) of - {'EXIT', _} -> - false; - Any1 -> - Any1 - end; - false -> - false - end, - case Any0 of - false -> - case string:tokens(FuncDef1, " ") of - [Any2| _] -> - Any2; - _ -> - FuncDef1 - end; - _ -> - Any0 - end. - -%%--Include tags-------------------------------------------------------- - -%% Only used in report DTD -erl_include(File, Tag) -> - case docb_main:include_file(File, Tag) of - {ok, Cs} -> - {drop, "\n<pre>\n" ++ text_to_html(Cs) ++ "\n</pre>\n"}; - error -> - {drop, ""} - end. - -code_include(File, Tag) -> - case docb_main:include(File, Tag, Tag) of - {ok, Cs} -> - {ok,text_to_html(Cs)}; - error -> - {error, {codeinclude,File}} - end. - -erl_eval(Expr) -> - Cs = docb_main:eval_str(Expr), - {drop, "\n<pre>\n" ++ text_to_html(Cs) ++ "\n</pre>\n"}. - -%% Only replaces certain characters. Spaces and new lines etc are kept. -%% Used for plain text (e.g. inclusions of code). -text_to_html([$>| Cs]) -> - [$&, $#, $6, $2, $;| text_to_html(Cs)]; -text_to_html([$<| Cs]) -> - [$&, $#, $6, $0, $;| text_to_html(Cs)]; -text_to_html([$&| Cs]) -> - [$&, $#, $3, $8, $;| text_to_html(Cs)]; -text_to_html([$\"| Cs]) -> - [$&, $#, $3, $4, $;| text_to_html(Cs)]; -text_to_html([C| Cs]) -> - [C| text_to_html(Cs)]; -text_to_html([]) -> - []. - -%%--Number sections----------------------------------------------------- - -number({Tag, Attrs, More}, none, File) -> - {Tag, Attrs, do_number(More, [1], File)}; -number({Tag, Attrs, More}, Prefix, File) -> - {Tag, Attrs, do_number(More, [list_to_integer(Prefix)], File)}. - -do_number([], _, _) -> - []; -do_number([{header, Attrs, More}| Rest], NN, File) -> - [{header, Attrs, More}| do_number(Rest, NN, File)]; -do_number([{section, Attrs, More}| Rest], [N| NN], File) -> - [{section, Attrs, do_number(More, [1, N| NN], File)}| - do_number(Rest, [N+1| NN], File)]; -do_number([{title, _, [{pcdata, _, Title}]}| More], [N| NN], File) -> - Format = make_format(length(NN)), - Number = lists:flatten(io_lib:format(Format, lists:reverse(NN))), - [{marker, [{"ID", "CDATA", Number}], []}, - {title, [{"NUMBER", "CDATA", Number}, - {"FILE", "CDATA", File}], - [{pcdata, [], Title}]}| do_number(More, [N| NN], File)]; -do_number([{pcdata, Attrs, More}| Rest], NN, File) -> - [{pcdata, Attrs, More}| do_number(Rest, NN, File)]; -do_number([{Tag, Attrs, More}| Rest], NN, File) -> - [{Tag, Attrs, do_number(More, NN, File)}|do_number(Rest, NN, File)]. - -make_format(1) -> - "~w"; -make_format(N) -> - "~w." ++ make_format(N-1). - -count_sections([section| Rest]) -> - 1 + count_sections(Rest); -count_sections([_| Rest]) -> - count_sections(Rest); -count_sections([]) -> - 0. - -%%--Make a ToC---------------------------------------------------------- - -format_toc(Toc) -> - [format_toc1(T) || T <- Toc]. - -format_toc1({Number, Title}) -> - [Number, " <a href = \"#", Number, "\">", Title, "</a><br/>\n"]. - -%%--Convert HTML ISO Latin 1 characters to ordinary characters---------- - -%% To be used for sorting. Cs must be flat. -html_latin1_sort_order(Cs) -> - hlso(Cs). - -hlso([]) -> - []; -hlso([$&, $#, C2, C1, C0, $;| Cs]) - when $0 =< C2, C2 =< $9, $0 =< C1, C1 =< $9, $0 =< C0, C0 =< $9 -> - C = ((C2-$0)*10 + (C1-$0))*10 + C0-$0, - hlso0(C, Cs); -hlso([$&, $#, C1, C0, $;| Cs]) - when $0 =< C1, C1 =< $9, $0 =< C0, C0 =< $9 -> - C = (C1-$0)*10 + C0-$0, - hlso0(C, Cs); -hlso([C| Cs]) -> - [C| hlso(Cs)]. - -hlso0(C, Cs) when 0 =< C, C =< 159 -> - [C| hlso(Cs)]; -hlso0(160, Cs) -> %% no-break space - hlso(Cs); % Remove it. -hlso0(161, Cs) -> %% inverted exclamation mark - [$? |hlso(Cs)]; -hlso0(162, Cs) -> %% cent sign - [$$|hlso(Cs)]; -hlso0(163, Cs) -> %% pound sterling sign - [$$|hlso(Cs)]; -hlso0(164, Cs) -> %% general currency sign - [$$|hlso(Cs)]; -hlso0(165, Cs) -> %% yen sign - [$$|hlso(Cs)]; -hlso0(166, Cs) -> %% broken (vertical) bar - [$| |hlso(Cs)]; -hlso0(167, Cs) -> %% section sign - [$$|hlso(Cs)]; -hlso0(168, Cs) -> %% umlaut (dieresis) - [$: |hlso(Cs)]; -hlso0(169, Cs) -> %% copyright sign - [$c |hlso(Cs)]; -hlso0(170, Cs) -> %% ordinal indicator, feminine - [$f |hlso(Cs)]; -hlso0(171, Cs) -> %% angle quotation mark, left - [$" |hlso(Cs)]; -hlso0(172, Cs) -> %% not sign - [$- |hlso(Cs)]; -hlso0(173, Cs) -> %% soft hyphen - [$- |hlso(Cs)]; -hlso0(174, Cs) -> %% registered sign - [$r |hlso(Cs)]; -hlso0(175, Cs) -> %% macron - [$- |hlso(Cs)]; -hlso0(176, Cs) -> %% degree sign - [$d |hlso(Cs)]; -hlso0(177, Cs) -> %% plus-or-minus sign - [$+ |hlso(Cs)]; -hlso0(178, Cs) -> %% superscript two - [$2 |hlso(Cs)]; -hlso0(179, Cs) -> %% superscript three - [$3 |hlso(Cs)]; -hlso0(180, Cs) -> %% acute accent - [$' |hlso(Cs)]; -hlso0(181, Cs) -> %% micro sign - [$' |hlso(Cs)]; -hlso0(182, Cs) -> %% pilcrow (paragraph sign) - [$$|hlso(Cs)]; -hlso0(183, Cs) -> %% middle dot - [$. |hlso(Cs)]; -hlso0(184, Cs) -> %% cedilla - [$c |hlso(Cs)]; -hlso0(185, Cs) -> %% superscript one - [$1 |hlso(Cs)]; -hlso0(186, Cs) -> %% ordinal indicator, masculine - [$m |hlso(Cs)]; -hlso0(187, Cs) -> %% angle quotation mark, right - [$" |hlso(Cs)]; -hlso0(188, Cs) -> %% fraction one-quarter - [$4 |hlso(Cs)]; -hlso0(189, Cs) -> %% fraction one-half - [$2 |hlso(Cs)]; -hlso0(190, Cs) -> %% fraction three-quarters - [$3 |hlso(Cs)]; -hlso0(191, Cs) -> %% inverted question mark - [$? |hlso(Cs)]; - -hlso0(C, Cs) when 192 =< C, C =< 198 -> %% capital A - [$A |hlso(Cs)]; -hlso0(199, Cs) -> %% capital C, cedilla - [$C |hlso(Cs)]; -hlso0(C, Cs) when 200 =< C, C =< 203 -> %% capital E - [$E |hlso(Cs)]; -hlso0(C, Cs) when 204 =< C, C =< 207 -> %% capital I - [$I |hlso(Cs)]; -hlso0(208, Cs) -> %% capital Eth, Icelandic - [$D |hlso(Cs)]; -hlso0(209, Cs) -> %% capital N, tilde - [$N |hlso(Cs)]; -hlso0(C, Cs) when 210 =< C, C =< 214 -> %% capital O - [$O |hlso(Cs)]; -hlso0(215, Cs) -> %% multiply sign - [$x |hlso(Cs)]; -hlso0(216, Cs) -> %% capital O, slash - [$O |hlso(Cs)]; -hlso0(C, Cs) when 217 =< C, C =< 220 -> %% capital U - [$U |hlso(Cs)]; -hlso0(221, Cs) -> %% capital Y, acute accent - [$Y |hlso(Cs)]; -hlso0(222, Cs) -> %% capital THORN, Icelandic - [$T |hlso(Cs)]; -hlso0(223, Cs) -> %% small sharp s, German (sz - [$s |hlso(Cs)]; -hlso0(C, Cs) when 224 =< C, C =< 230-> %% small a - [$a |hlso(Cs)]; -hlso0(231, Cs) -> %% small c, cedilla - [$c |hlso(Cs)]; -hlso0(C, Cs) when 232 =< C, C =< 235 -> %% small e - [$e |hlso(Cs)]; -hlso0(C, Cs) when 236 =< C, C =< 239 -> %% small i - [$i |hlso(Cs)]; -hlso0(240, Cs) -> %% small eth, Icelandic - [$d |hlso(Cs)]; -hlso0(241, Cs) -> %% small n, tilde - [$n |hlso(Cs)]; -hlso0(C, Cs) when 242 =< C, C =< 246 -> %% small o - [$o |hlso(Cs)]; -hlso0(247, Cs) -> %% divide sign - [$/ |hlso(Cs)]; -hlso0(248, Cs) -> %% small o, slash - [$o |hlso(Cs)]; -hlso0(C, Cs) when 249 =< C, C =< 252 -> %% small u - [$u |hlso(Cs)]; -hlso0(253, Cs) -> %% small y, acute accent - [$y |hlso(Cs)]; -hlso0(254, Cs) -> %% small thorn, Icelandic - [$t |hlso(Cs)]; -hlso0(255, Cs) -> %% small y, dieresis or umlaut - [$y |hlso(Cs)]. diff --git a/lib/docbuilder/src/docb_html_util_iso.erl b/lib/docbuilder/src/docb_html_util_iso.erl deleted file mode 100644 index c836805cd2..0000000000 --- a/lib/docbuilder/src/docb_html_util_iso.erl +++ /dev/null @@ -1,204 +0,0 @@ -%% ``The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. -%% Portions created by Ericsson are Copyright 1999-2000, Ericsson -%% Utvecklings AB. All Rights Reserved.'' -%% -%% $Id$ -%% --module(docb_html_util_iso). --export([entity_to_html/1]). - -%% Encodes ISOtech, ISOnum and ISOgrk3. -%% -%% All entities are of the form "[abcdef]". -%% -entity_to_html(Entity) when is_list(Entity), hd(Entity) =/= $[ -> - Entity; -entity_to_html(Entity) -> - case (catch enc(Entity)) of - {'EXIT', _} -> - Entity; - Enc -> - "<font face=symbol>" ++ Enc ++ "</font>" - end. - -enc("[Delta ]") -> "D"; -%% enc("[Dot ]") -> "�"; -%% enc("[DotDot]") -> "�"; -enc("[Gamma ]") -> "G"; -enc("[Lambda]") -> "L"; -enc("[Omega ]") -> "W"; -enc("[Phi ]") -> "F"; -enc("[Pi ]") -> "P"; -enc("[Prime ]") -> "²"; -enc("[Psi ]") -> "Y"; -enc("[Sigma ]") -> "S"; -enc("[Theta ]") -> "Q"; -enc("[Upsi ]") -> "¡"; -%% enc("[Verbar]") -> "�"; -enc("[Xi ]") -> "X"; - -enc("[aleph ]") -> "À"; -enc("[alpha ]") -> "a"; -enc("[amp ]") -> "&"; -enc("[and ]") -> "Ù"; -enc("[ang ]") -> "Ð"; -%% enc("[ang90 ]") -> "�"; -%% enc("[angsph]") -> "�"; -%% enc("[angst ]") -> "�"; -enc("[ap ]") -> "»"; - -%% enc("[becaus]") -> "�"; -%% enc("[bernou]") -> "�"; -enc("[bepsi ]") -> "'"; -enc("[beta ]") -> "b"; -enc("[bottom]") -> "^"; -enc("[bull ]") -> "·"; - -enc("[cap ]") -> "Ç"; -enc("[chi ]") -> "c"; -enc("[clubs ]") -> "§"; -%% enc("[compfn]") -> "�"; -enc("[cong ]") -> "@"; -enc("[copy ]") -> "Ó"; -%% enc("[conint]") -> "�"; -enc("[cup ]") -> "È"; - -enc("[dArr ]") -> "ß"; -enc("[darr ]") -> "¯"; -enc("[deg ]") -> "°"; -enc("[delta ]") -> "d"; -enc("[diam ]") -> "à"; -enc("[diams ]") -> "¨"; -enc("[divide]") -> "¸"; - -enc("[empty ]") -> "Æ"; -%% enc("[epsi ]") -> "�"; -%% enc("[epsis ]") -> "�"; -enc("[epsiv ]") -> "e"; -enc("[equiv ]") -> "º"; -enc("[eta ]") -> "h"; -enc("[exist ]") -> "$"; - -enc("[fnof ]") -> "¦"; -enc("[forall]") -> """; - -enc("[gamma ]") -> "g"; -%% enc("[gammad]") -> "�"; -enc("[ge ]") -> "³"; -enc("[gt ]") -> ">"; - -%% enc("[hamilt]") -> "�"; -enc("[hArr ]") -> "Û"; -enc("[harr ]") -> "«"; -enc("[hearts]") -> "©"; -enc("[horbar]") -> "¾"; - -enc("[iff ]") -> "Û"; -enc("[image ]") -> "Á"; -enc("[infin ]") -> "¥"; -enc("[int ]") -> "ò"; -enc("[iota ]") -> "i"; -enc("[isin ]") -> "Î"; - -enc("[kappa ]") -> "k"; -%%enc("[kappav]") -> "�"; - -enc("[lArr ]") -> "Ü"; -%% enc("[lagran]") -> "�"; -enc("[lambda]") -> "l"; -enc("[lang ]") -> "á"; -enc("[larr ]") -> "¬"; -enc("[le ]") -> "£"; -%% enc("[lowast]") -> "�"; -enc("[lowbar]") -> "_"; -enc("[lt ]") -> "<"; - -enc("[middot]") -> "×"; -enc("[minus ]") -> "-"; -%% enc("[mnplus]") -> "�"; -enc("[mu ]") -> "m"; - -enc("[nabla ]") -> "Ñ"; -enc("[ne ]") -> "¹"; -enc("[ni ]") -> "'"; -enc("[nsub ]") -> "Ë"; -enc("[not ]") -> "Ø"; -enc("[notin ]") -> "Ï"; -enc("[nu ]") -> "n"; - -enc("[omega ]") -> "w"; -enc("[or ]") -> "Ú"; -%% enc("[order ]") -> "�"; -enc("[oplus ]") -> "Å"; -enc("[otimes]") -> "Ä"; - -%% enc("[par ]") -> "�"; -enc("[part ]") -> "¶"; -%% enc("[permil]") -> "�"; -enc("[perp ]") -> "^"; % bottom -enc("[phis ]") -> "f"; -enc("[phiv ]") -> "j"; -%% enc("[phmmat]") -> "�"; -enc("[pi ]") -> "p"; -enc("[piv ]") -> "v"; -enc("[plus ]") -> "+"; -enc("[plusmn]") -> "±"; -enc("[prime ]") -> "¢"; -enc("[prod ]") -> "Õ"; -enc("[prop ]") -> "µ"; -enc("[psi ]") -> "y"; - -enc("[radic ]") -> "Ö"; -enc("[rang ]") -> "ñ"; -enc("[rArr ]") -> "Þ"; -enc("[rarr ]") -> "®"; -enc("[real ]") -> "Â"; -enc("[reg ]") -> "Ò"; -enc("[rho ]") -> "r"; -%% enc("[rhov ]") -> "�"; - -enc("[sigma ]") -> "s"; -enc("[sigmav]") -> "V"; -enc("[sim ]") -> "~"; -%% enc("[sime ]") -> "�"; -%% enc("[square]") -> "�"; -enc("[sol ]") -> "¤"; -enc("[spades]") -> "ª"; -enc("[sub ]") -> "Ì"; -enc("[sube ]") -> "Í"; -enc("[sup ]") -> "É"; -enc("[supe ]") -> "Ê"; -enc("[sum ]") -> "å"; - -enc("[tau ]") -> "t"; -enc("[tdot ]") -> "¼"; -enc("[there4]") -> "\"; -enc("[thetas]") -> "q"; -enc("[thetav]") -> "J"; -enc("[times ]") -> "´"; -%% enc("[tprime]") -> "�"; -enc("[trade ]") -> "Ô"; - -enc("[uArr ]") -> "Ý"; -enc("[uarr ]") -> "­"; -enc("[upsi ]") -> "u"; - -enc("[verbar]") -> "½"; - -%% enc("[wedgeq]") -> "�"; -enc("[weierp]") -> "Ã"; - -enc("[xi ]") -> "x"; - -enc("[zeta ]") -> "z". diff --git a/lib/docbuilder/src/docb_main.erl b/lib/docbuilder/src/docb_main.erl deleted file mode 100644 index c20cfc8e67..0000000000 --- a/lib/docbuilder/src/docb_main.erl +++ /dev/null @@ -1,657 +0,0 @@ -%% ``The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. -%% Portions created by Ericsson are Copyright 1999-2000, Ericsson -%% Utvecklings AB. All Rights Reserved.'' -%% -%% $Id$ -%% --module(docb_main). - --export([process/2, - parse/2, parse1/2, - pp/2, - insert_after/3, - transform/5, pp/5, - include_file/2, include/3, - eval_str/1, - validate_html/1 - ]). --export([do_parse_sgmls/1]). - -%%---------------------------------------------------------------------- - -%% process(File, Opts) -> errors | ok -%% Parses the source file File and transforms the result to html, -%% latex and/or man page format. -process(File, Opts) -> - - SrcType = docb_util:lookup_option(src_type, Opts), - - File1 = - case SrcType of - ".xml" -> - FileTmp = File ++ ".tmpconv", - os:cmd("sed -e 's/xi:include[ \t]*href/include file/g' -e 's/xmlns:xi=\"http:\\/\\/www.w3.org\\/2001\\/XInclude\"//g' < " ++ - File ++ ".xml > " ++ FileTmp ++ ".xml"), - FileTmp; - ".sgml" -> - File - end, - - case parse1(File1, Opts) of - errors -> - delete_tmp_file(SrcType, File1), - errors; - {ok, Tree} -> - From = element(1, Tree), - Tos0 = - lists:foldl( - fun(latex, Acc) -> [latex|Acc]; - (html, Acc) -> [html|Acc]; - ({man, _Section}, Acc) -> [man|Acc]; - (_, Acc) -> Acc - end, [], Opts), - - %% If no target format is specified, assume HTML: - Tos = if - Tos0 =:= [] -> [html]; - true -> Tos0 - end, - - Result = [transform(From, To, Opts, File, Tree)||To <- Tos], - case lists:member(transformation_error,Result) of - true -> - delete_tmp_file(SrcType, File1), - errors; - _ -> - delete_tmp_file(SrcType, File1), - ok - end - - end. - - -delete_tmp_file(".xml", File) -> - file:delete(File ++ ".xml"); -delete_tmp_file(_, _) -> - ok. - -%%---------------------------------------------------------------------- - -%% parse(File, Opts) -> {ok, Tree} | errors -%% Parses the source file File, resulting in a tree structure. -parse(File, Opts) -> - case docb_util:lookup_option(src_type, Opts) of - ".xml" -> - parse_xml(File++".xml", Opts); - ".sgml" -> - parse_sgml(File, Opts) - end. - -%% parse1(File, Opts) -> {ok, Tree} | errors -%% Like parse/2, but in the SGML case also prints the parse errors -%% (in File.html.sgmls_errs) information to stdout. -parse1(File, Opts) -> - parse(File, [{print_parse_errs, true}|Opts]). - - -validate_html(InFile) -> - ScanOpts = [{validation,true}, {fetch_fun, fun fetch_dtd/2}], - case xmerl_scan:file(InFile, ScanOpts) of - {_XMLTuple,[]} -> % ok - {InFile,ok}; - {'EXIT',Reason} -> - {InFile,Reason} - end. - -fetch_dtd({public,_,"http://www.w3.org/TR/xhtml1/DTD/"++ Rest},GlobalState) -> - Filename = filename:join(docb_util:dtd_dir(),Rest), - {ok,{file,Filename},GlobalState}; -fetch_dtd({public,_,Str},GlobalState) -> - {ok,{file,filename:join(docb_util:dtd_dir(),Str)},GlobalState}. - - - -parse_xml(InFile, Opts) -> - DtdDir = docb_util:dtd_dir(), - ScanOpts = [{validation,true}, {fetch_path, [DtdDir]}], - PrintP = docb_util:lookup_option(print_parse_errs, Opts), - case catch xmerl_scan:file(InFile, ScanOpts) of - {'EXIT', Error} when PrintP -> - docb_util:message(error, - "XML validation error:~n~p", [Error]), - errors; - {'EXIT', _Error} -> - errors; - {error, Reason} -> % probably file error - docb_util:message(error, "XML scan error: ~p", [Reason]), - errors; - {Doc, []} -> - case catch xmerl:export([Doc], docb_xmerl_tree_cb) of - [Tree] -> - verify(Tree), - {ok, Tree}; - {'EXIT', Error} -> - docb_util:message(error, - "XML export error:~n~p", [Error]), - errors - end - end. - -parse_sgml(InFile, Opts) -> - - Pfx = tmp_file_prefix(InFile, Opts), - OutFile = Pfx ++ "sgmls_output", - ErrFile = Pfx ++ "sgmls_errs", - - EntVals = lists:usort(docb_util:lookup_options(ent, Opts)), - Ents = lists:flatten([" -ent " ++ Val || Val <- EntVals]), - Cmd = docb_util:old_docb_dir() ++ "/bin/docb_sgmls_run " ++ - Ents ++ " " ++ InFile ++ ".sgml " ++ OutFile ++ " " ++ ErrFile, - - case os:cmd(Cmd) of - [] -> - PrintP = docb_util:lookup_option(print_parse_errs, Opts), - case filelib:file_size(ErrFile) of - 0 -> % implies no errors - parse_sgmls(InFile, OutFile); - _ when PrintP -> - cat(ErrFile), - errors; - _ -> - errors - end; - Msg -> - docb_util:message(error, "~p", [Msg]), - errors - end. - -tmp_file_prefix(File, Opts) -> - lists:concat( - [File, "." | lists:foldl( - fun(latex, Acc) -> ["latex."|Acc]; - (html, Acc) -> ["html."|Acc]; - ({man, Section}, Acc) -> ["man", Section, "."|Acc]; - (_, Acc) -> Acc - end, [], Opts)]). - -parse_sgmls(InFile, SgmlsFile) -> - case file:open(SgmlsFile, [read]) of - {ok, Fd} -> - Res = case (catch do_parse_sgmls(Fd)) of - {ok, Tree} -> - {ok, Tree}; - {'EXIT', Reason} -> - docb_util:message( - error, - "Cannot parse sgmls output file " - "~s, obtained from parsing ~s, " - "reason: ~w", - [SgmlsFile, InFile, Reason]), - errors; - {error, Reason} -> - docb_util:message( - error, - "Cannot parse sgmls output file " - "~s, obtained from parsing ~s, " - "reason: ~w", - [SgmlsFile, InFile, Reason]), - errors - end, - file:close(Fd), - case Res of - {ok, Tree0} -> - verify(Tree0), - {ok, Tree0}; - _Other -> - errors - end; - {error, Reason} -> - docb_util:message(error, - "Cannot open sgmls output file ~s, " - "obtained from parsing ~s, reason: ~w", - [SgmlsFile, InFile, Reason]), - errors - end. - -do_parse_sgmls(Fd) -> - do_parse_sgmls(Fd, []). - -do_parse_sgmls(Fd, Attrs) -> - case get_line(Fd) of - {attrs, A} -> - do_parse_sgmls(Fd, [A|Attrs]); - {startTag, Tag} -> - {ok, {Tag, Attrs, get_args(Fd)}}; - Other -> - {error, Other} - end. - -get_args(Fd) -> - case get_line(Fd) of - {startTag, Tag} -> - H = {Tag, [], get_args(Fd)}, - [H|get_args(Fd)]; - {dataTag, Str} -> - [{pcdata, [], Str}|get_args(Fd)]; - {attrs, A} -> - get_args_attr(Fd, [A]); - close -> - []; - ok -> - [] - end. - -get_args_attr(Fd, Attrs) -> - case get_line(Fd) of - {startTag, Tag} -> - H = {Tag, lists:reverse(Attrs), get_args(Fd)}, - [H|get_args(Fd)]; - {dataTag, Str} -> - [{pcdata, lists:reverse(Attrs), Str}|get_args(Fd)]; - {attrs, A} -> - get_args_attr(Fd, [A|Attrs]); - close -> - []; - ok -> - [] - end. - -get_line(Fd) -> - Str = io:get_line(Fd, ''), - case Str of - [$(|T] -> - {startTag, tag_name(T)}; - [$-|T] -> - {dataTag, T}; - [$)|_T] -> - close; - [$A|T] -> - {attrs, attrs(remove_nl(T))}; - [$?|_T] -> - get_line(Fd); - [$C|_] -> - ok - end. - -remove_nl([$\n|_]) -> []; -remove_nl([H|T]) -> [H|remove_nl(T)]; -remove_nl([]) -> []. - -%% attrs -%% splits a string like -%% AAAAA BBBBB ...... -%% into {"AAA", "BBB", Rest} - -attrs(T) -> - {X, T1} = get_item(T), - {Y, T2} = get_item(T1), - T3 = skip_blanks(T2), - {X, Y, T3}. - -get_item(T) -> get_item(skip_blanks(T), []). - -get_item([$ |T], L) -> {lists:reverse(L), [$ |T]}; -get_item([H|T], L) -> get_item(T, [H|L]); -get_item([], L) -> {lists:reverse(L), []}. - -skip_blanks([$ |T]) -> skip_blanks(T); -skip_blanks(T) -> T. - -tag_name(Str) -> tag_name(Str, []). - -tag_name([H|T], L) when $A =< H, H =< $Z -> - tag_name(T, [H-$A+$a|L]); -tag_name([$\n], L) -> - list_to_atom(lists:reverse(L)); -tag_name([H|T], L) -> - tag_name(T, [H|L]). - -cat(File) -> - case file:open(File, [read]) of - {ok, Fd} -> - cat1(Fd), - file:close(Fd); - Other -> - Other - end. - -cat1(Fd) -> - case io:get_line(Fd, '') of - eof -> - eof; - Str -> - io:format("~s", [Str]), - cat1(Fd) - end. - -%%---------------------------------------------------------------------- - -verify(Tree) -> verify(Tree, [], 1). - -verify({pcdata, Optional, _}, Path, Level) -> - verify_optional(Optional, Path, Level); -verify({Tag, Optional, Args}, Path, Level) when is_list(Args) -> - verify_optional(Optional, Path, Level) - andalso verify_list(Args, [Tag|Path], Level); -verify(Other, Path, Level) -> - verify_error(Other, Path, Level). - -verify_error(X, Path, Level) -> - docb_util:message(error, "Invalid object found at: ~p level:~w~n~s", - [Path, Level, docb_pretty_format:term(X)]), - false. - -verify_list([H|T], Path, Level) -> - verify(H, Path, Level) andalso verify_list(T, Path, Level + 1); -verify_list([], _, _) -> - true. - -verify_optional([{_, _, _}|T], Path, Level) -> - verify_optional(T, Path, Level); -verify_optional([], _Path, _Level) -> - true; -verify_optional(X, Path, Level) -> - verify_error(X, Path, Level). - -%%---------------------------------------------------------------------- - -%% pp(File, Opts) -> {ok, OutFile} | errors -%% Parses the source file and, if successful, prints the resulting tree -%% structure to a file with the extension ".pp". -pp(File, Opts) -> - case parse(File, Opts) of - {ok, Tree} -> - OutFile = File ++ ".pp", - dump(OutFile, Tree), - {ok, OutFile}; - errors -> - errors - end. - -dump(File, Struct) -> - {ok, Stream} = file:open(File, [write]), - io:format("Info: Dump on ~p ...", [File]), - io:format(Stream, "~n~s~n", [docb_pretty_format:term(Struct)]), - io:format(" done.\n"), - file:close(Stream). - -%%---------------------------------------------------------------------- - -%% insert_after(Tag, Tree, Obj) -> Tree | {'EXIT', Reason} -%% Insert an element in a tree structure -insert_after(Tag, Tree, Obj) -> - edit(Tag, Tree, {insert_after, Obj}). - -%% edit Op = delete, insert_before, insert_after -edit(Tag, Tree, Op) -> - case catch edit1(Tag, Tree, Op) of - error -> - docb_util:message(error, "Cannot do ~p to ~w", [Op, Tag]), - Tree; - Other -> - Other - end. - -edit1(Tag, {Tag, _O, _A}, _Op) -> - throw(error); -edit1(Tag, {Tag1, O, A}, Op) -> - {Tag1, O, edit1_list(Tag, A, Op)}; -edit1(_, _, _) -> - throw(error). - -edit1_list(Tag, [{pcdata, Str}|T], Op) -> - [{pcdata, Str}|edit1_list(Tag, T, Op)]; -edit1_list(Tag, [{Tag, O, A}|T], {insert_after, Obj}) -> - [{Tag, O, A}, Obj|T]; -edit1_list(Tag, [H|T], Op) -> - [H|edit1_list(Tag, T, Op)]; -edit1_list(_Tag, [], _Op) -> - []. - -%%______________________________________________________________________ - -%% transform(From, To, Opts, File, Tree) -> void() -%% Actual transformation of tree structure to desired format. -transform(From, To, Opts, File, Tree) -> - Filter = if - To =:= html; To =:= kwic -> - list_to_atom("docb_tr_" ++ atom_to_list(From) ++ - [$2|atom_to_list(To)]); - true -> - list_to_atom("sgml_tr_" ++ atom_to_list(From) ++ - [$2|atom_to_list(To)]) - end, - - case catch Filter:transform(File, Tree, Opts) of - - %% R5C - {'EXIT', {undef, [{Filter, transform, [File, Tree, Opts],_}|_]}}-> - %% No transformation defined - finish_transform(Tree, File, Opts, Filter); - - {'EXIT', {undef, {Filter, transform, [File, Tree, Opts],_}}} -> - %% No transformation defined - finish_transform(Tree, File, Opts, Filter); - - {'EXIT', What} -> - docb_util:message(error, - "Transformation trouble in ~P", [What, 9]), - transformation_error; - - {error, Reason} -> - docb_util:message(error, Reason), - transformation_error; - - {Tree1, Opts1} -> - %% transformation returning both new parse and new options - finish_transform(Tree1, File, Opts1, Filter); - - Tree1 -> - %% transformation returning only new parse - finish_transform(Tree1, File, Opts, Filter) - end. - -finish_transform(Tree, File, Opts, Filter) -> - {Str, NewOpts} = pp(Tree, [], 1, Filter, Opts), - Extension = - case catch Filter:extension(NewOpts) of - {'EXIT', _} -> - Filter:extension(); - Others -> - Others - end, - {ok, Out} = - file:open(docb_util:outfile(File, Extension, NewOpts), [write]), - put_chars(Out, Str), - file:close(Out). - -put_chars(Out, Str) -> put_chars(Out, Str, 0). - -put_chars(Out, [$\n|Cs], _Pos) -> - io:put_chars(Out, [$\n]), - put_chars(Out, Cs, 0); - -put_chars(Out, [$\011|Cs], Pos) -> % tab - TabbedPos = 8*((Pos div 8)+1), - Nblanks = TabbedPos - Pos, - io:put_chars(Out, lists:duplicate(Nblanks, $ )), - put_chars(Out, Cs, Pos+Nblanks); - -put_chars(Out, [C|Cs], Pos) when is_integer(C) -> - io:put_chars(Out, [C]), - put_chars(Out, Cs, Pos+1); - -put_chars(Out, [L|Cs], Pos) when is_list(L) -> - put_chars(Out, Cs, put_chars(Out, L, Pos)); - -put_chars(_Out, [], Pos) -> - Pos. - -pp({Tag, Optional, Args}, TagPath, Level, Filter, Opts) -> - TagPath1 = [Tag|TagPath], - Optional1 = reduce_optional(Optional), - - %% First try Filter:rule/3. It returns {Return, NewOpts} - %% where Return is as from rule/2: - Rule_3_result = - case catch Filter:rule(TagPath1, {Level,Optional1,Args},Opts) of - %% R5C - {'EXIT', {undef, [{_, rule, _, _}|_]}} -> % No rule/3 defined - failed; - - {'EXIT', {undef, {_, rule, _, _}}} -> % No rule/3 defined - failed; - %% R5C - {'EXIT', {function_clause, [{_, rule, _, _}|_]}} -> % No MATCHING rule/3 - failed; - - {'EXIT', {function_clause, {_, rule, _, _}}} -> % No MATCHING rule/3 - failed; - - {'EXIT', What} -> - docb_util:message(error, - "Serious Error: ~P", [What, 9]); - Others -> - Others - end, - handle_rule_call_result({r3, Rule_3_result}, Filter, TagPath1, Tag, - Level, Optional1, Args, Opts). - -handle_rule_call_result({r3, failed}, Filter, TagPath1, Tag, Level, Optional1, - Args, Opts) -> - %% Hmmm, try Filter:rule/2 - Rule_2_result = (catch Filter:rule(TagPath1, {Level, Optional1, Args})), - handle_rule_call_result({r2, Rule_2_result}, Filter, TagPath1, Tag, - Level, Optional1, Args, Opts); -handle_rule_call_result({r3, {Result, NewOpts}}, Filter, TagPath1, Tag, Level, - Optional1, Args, _Opts) -> - handle_rule_call_result({r2, Result}, Filter, TagPath1, Tag, Level, - Optional1, Args, NewOpts); -handle_rule_call_result({_, {func, F}}, _Filter, _TagPath1, _Tag, _Level, - _Optional1, Args, Opts) -> - {F(Args), Opts}; -handle_rule_call_result({_, {'EXIT', Why}}, _Filter, TagPath1, _Tag, Level, - Optional1, Args, Opts) -> - report_error(TagPath1, Why, {Level, Optional1, Args}), - {[], Opts}; -handle_rule_call_result({_, {drop, Str}}, _Filter, _TagPath1, _Tag, _Level, - _Optional1, _Args, Opts) -> - {[Str], Opts}; -handle_rule_call_result({_, {newargs, NewArgs}}, Filter, TagPath1, _Tag, _Level, - _Optional1, _Args, Opts) -> - {List, NewOpts} = pp_list(NewArgs, TagPath1, 1, Filter, Opts), - {[List], NewOpts}; -handle_rule_call_result({_, {newargs, Before, NewArgs, After}}, Filter, TagPath1, _Tag, _Level, - _Optional1, _Args, Opts) -> - {List, NewOpts} = pp_list(NewArgs, TagPath1, 1, Filter, Opts), - {[Before, List, After], NewOpts}; -handle_rule_call_result({_, {Before, After}}, Filter, TagPath1, _Tag, _Level, - _Optional1, Args, Opts) when is_list(Before) -> - {List, NewOpts} = pp_list(Args, TagPath1, 1, Filter, Opts), - {[Before, List, After], NewOpts}. - -pp_list([H|T], TagPath, Level, Rules, Opts) -> - {Hpp, Hopts} = pp(H, TagPath, Level, Rules, Opts), - {Tpp, Tops} = pp_list(T, TagPath, Level + 1, Rules, Hopts), - {[Hpp|Tpp], Tops}; -pp_list([], _, _, _, Opts) -> - {[], Opts}. - -reduce_optional([{_, _, H}|T]) -> [H|reduce_optional(T)]; -reduce_optional([]) -> []. - -report_error(Arg1, Cause, Arg2) -> - [Tag|_] = Arg1, - docb_util:message(error, - "Formatting trouble in ~p: ~p", [Tag, Cause]), - docb_util:message(error, "Failure in rule(~p, ~p)", [Arg1, Arg2]). - -%%---------------------------------------------------------------------- - -%% include_file(File, Tag) -> {ok, String} | error -include_file(File, Tag) -> - include(File, "%S" ++ Tag, "%E" ++ Tag). - -%% include(File, StartTag, StopTag) -> {ok, String} | error -include(File, "", "") -> - case file:open(File, [read]) of - {ok, Fd} -> - String = include_all(Fd), - file:close(Fd), - {ok, String}; - _ -> - docb_util:message(error, - "Include file ~s not found", [File]), - error - end; -include(File, StartTag, StopTag) -> - case file:open(File, [read]) of - {ok, Fd} -> - String = extract(File, Fd, StartTag, StopTag, searching), - file:close(Fd), - {ok, lists:flatten(String)}; - _ -> - docb_util:message(error, - "Include file ~s not found", [File]), - error - end. - -include_all(Fd) -> - case io:get_line(Fd, '') of - eof -> - []; - ListOfChars -> - ListOfChars ++ include_all(Fd) - end. - -extract(File, Fd, StartTag, StopTag, State) -> - Line=io:get_line(Fd, ''), - extract(File, Fd, StartTag, StopTag, State, Line). - -extract(File, _, _, _, _, eof) -> - docb_util:message(error, - "Premature end of file in include file ~p", - [File]), - []; -extract(File, Fd, StartTag, StopTag, searching, Line) -> - case regexp:match(Line, "^" ++ StartTag) of - {match, _Start, _Length} -> - extract(File, Fd, StartTag, StopTag, copying); - nomatch -> - extract(File, Fd, StartTag, StopTag, searching); - {error, _Error} -> - docb_util:message(error, "Bad syntax in ~s", [File]), - [] - end; -extract(File, Fd, StartTag, StopTag, copying, Line) -> - case regexp:match(Line, "^" ++ StopTag) of - {match, _Start, _Length} -> - []; - nomatch -> - [Line|extract(File, Fd, StartTag, StopTag, copying)]; - {error, _Error} -> - docb_util:message(error, "Bad syntax in ~s", [File]), - [] - end. - -%%---------------------------------------------------------------------- - -eval_str(Str) -> - case lib:eval_str(Str) of - {error, Report} -> - docb_util:message(error, - "ErlEval failed: ~s (~s)", [Str, Report]); - {ok, S} -> - io_lib:format("~p~n", [S]) - end. diff --git a/lib/docbuilder/src/docb_pretty_format.erl b/lib/docbuilder/src/docb_pretty_format.erl deleted file mode 100644 index 25dcd8987b..0000000000 --- a/lib/docbuilder/src/docb_pretty_format.erl +++ /dev/null @@ -1,177 +0,0 @@ -%% ``The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. -%% Portions created by Ericsson are Copyright 1999-2000, Ericsson -%% Utvecklings AB. All Rights Reserved.'' -%% -%% $Id$ -%% --module(docb_pretty_format). - --export([term/1]). - -%% pretty_format:term(Term) -> PNF list of characters -%% -%% Note: this is usually used in expressions like: -%% io:format('~s\n', [pretty_format:term(Term)]). -%% -%% Uses the following simple heuristics: -%% -%% 1) Simple tuples are printed across the page. -%% (Simple means *all* the elements are "flat") -%% 2) The complex tuple {Arg1, Arg2, Arg3,....} is printed thus: -%% {Arg1, -%% Arg2, -%% Arg3, -%% ...} -%% 3) Lists are treated as for tuples. -%% 4) Lists of printable characters are treated as strings. -%% -%% This method seems to work reasonable well for {Tag, ...} type -%% data structures. -term(Term) -> - element(2, term(Term, 0)). - -%% pretty_format:term(Term, Indent} -> {Indent', Chars} -%% Format <Term> -- use <Indent> to indent the *next* line. -%% Note: Indent' is a new indentaion level (sometimes printing <Term> -%% the next line to need an "extra" indent!). -term([], Indent) -> - {Indent, [$[,$]]}; -term(L, Indent) when is_list(L) -> - case is_string(L) of - true -> - {Indent, io_lib:write_string(L)}; - false -> - case complex_list(L) of - true -> - write_complex_list(L, Indent); - false -> - write_simple_list(L, Indent) - end - end; -term(T, Indent) when is_tuple(T) -> - case complex_tuple(T) of - true -> - write_complex_tuple(T, Indent); - false -> - write_simple_tuple(T, Indent) - end; -term(A, Indent) -> - {Indent, io_lib:write(A)}. - -%% write_simple_list([H|T], Indent) -> {Indent', Chars} -write_simple_list([H|T], Indent) -> - {_, S1} = term(H, Indent), - {_, S2} = write_simple_list_tail(T, Indent), - {Indent, [$[,S1|S2]}. - -write_simple_list_tail([H|T], Indent) -> - {_, S1} = term(H, Indent), - {_, S2} = write_simple_list_tail(T, Indent), - {Indent, [$,,S1| S2]}; -write_simple_list_tail([], Indent) -> - {Indent, "]"}; -write_simple_list_tail(Other, Indent) -> - {_, S} = term(Other, Indent), - {Indent, [$|,S,$]]}. - -%% write_complex_list([H|T], Indent) -> {Indent', Chars} -write_complex_list([H|T], Indent) -> - {I1, S1} = term(H, Indent+1), - {_, S2} = write_complex_list_tail(T, I1), - {Indent, [$[,S1|S2]}. - -write_complex_list_tail([H|T], Indent) -> - {I1, S1} = term(H, Indent), - {_, S2} = write_complex_list_tail(T, I1), - {Indent, [$,,nl_indent(Indent),S1,S2]}; -write_complex_list_tail([], Indent) -> - {Indent, "]"}; -write_complex_list_tail(Other, Indent) -> - {_, S} = term(Other, Indent), - {Indent, [$|,S,$]]}. - -%% complex_list(List) -> true | false -%% Returns true if the list is complex otherwise false. -complex_list([]) -> - false; -complex_list([H|T]) when is_list(H) -> - case is_string(H) of - true -> - complex_list(T); - false -> - true - end; -complex_list([H|_]) when is_tuple(H) -> true; -complex_list(_) -> false. - -%% complex_tuple(Tuple) -> true | false -%% Returns true if the tuple is complex otherwise false. -complex_tuple(T) -> - complex_list(tuple_to_list(T)). - -%% write_simple_tuple(Tuple, Indent} -> {Indent', Chars} -write_simple_tuple({}, Indent) -> - {Indent, "{}"}; -write_simple_tuple(Tuple, Indent) -> - {_, S} = write_simple_tuple_args(tuple_to_list(Tuple), Indent), - {Indent, [${, S, $}]}. - -write_simple_tuple_args([X], Indent) -> - term(X, Indent); -write_simple_tuple_args([H|T], Indent) -> - {_, SH} = term(H, Indent), - {_, ST} = write_simple_tuple_args(T, Indent), - {Indent, [SH, $,, ST]}. - -%% write_complex_tuple(Tuple, Indent} -> {Indent', Chars} -write_complex_tuple(Tuple, Indent) -> - [H|T] = tuple_to_list(Tuple), - {I1, SH} = term(H, Indent+2), - {_, ST} = write_complex_tuple_args(T, I1), - {Indent, [${, SH, ST, $}]}. - -write_complex_tuple_args([X], Indent) -> - {_, S} = term(X, Indent), - {Indent, [$,, nl_indent(Indent), S]}; -write_complex_tuple_args([H|T], Indent) -> - {I1, SH} = term(H, Indent), - {_, ST} = write_complex_tuple_args(T, I1), - {Indent, [$,, nl_indent(Indent) , SH, ST]}; -write_complex_tuple_args([], Indent) -> - {Indent, []}. - -%% utilities - -nl_indent(I) when I >= 0 -> - ["\n"|indent(I)]; -nl_indent(_I) -> - [$ ]. - -indent(I) when I >= 8 -> - [$\t|indent(I-8)]; -indent(I) when I > 0 -> - [$ |indent(I-1)]; -indent(_) -> - []. - -is_string([9|T]) -> - is_string(T); -is_string([10|T]) -> - is_string(T); -is_string([H|T]) when H >31, H < 127 -> - is_string(T); -is_string([]) -> - true; -is_string(_) -> - false. diff --git a/lib/docbuilder/src/docb_tr_application2html.erl b/lib/docbuilder/src/docb_tr_application2html.erl deleted file mode 100644 index d8cb214d0a..0000000000 --- a/lib/docbuilder/src/docb_tr_application2html.erl +++ /dev/null @@ -1,286 +0,0 @@ -%% ``The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. -%% Portions created by Ericsson are Copyright 1999-2000, Ericsson -%% Utvecklings AB. All Rights Reserved.'' -%% -%% $Id$ -%% --module(docb_tr_application2html). - --export([extension/0, transform/3, rule/2, rule/3]). - -extension() -> - ".html". - -transform(File, {application, _Attrs, [Header|Rest]}, Opts0) -> - - %% Extract header data - Title = docb_html_util:extract_header_data(title, Header), - - case docb_util:an_option(kwicindex_only, Opts0) of - false -> - - %% Create the framing HTML document - OutFile = docb_util:outfile(File++"_frame", ".html", Opts0), - case file:open(OutFile, [write]) of - {ok, Fd} -> - io:format(Fd, -"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" -\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\"> -<!-- This document was generated using DocBuilder-" ++ docb_util:version() ++ " --> -<html> -<head> - <title>~s</title> - " ++ docb_util:html_snippet(head, Opts0) ++ " -</head> -<frameset cols=\"150, *\"> - <frame src=\"~s\" name=\"toc\"> - <frame src=\"~s\" name=\"document\"> - <noframes> - <body bgcolor=\"#FFFFFF\" text=\"#000000\" link=\"#0000FF\" - vlink=\"#FF00FF\" alink=\"#FF0000\"> - <p>This documentation requires a browser that can handle frames</p> - </body> - </noframes> -</frameset> -</html> -", - [Title, - File++".html", File++"_first.html"]), - file:close(Fd) - end, - - %% Create the front HTML document - docb_main:transform(first, html, Opts0, File ++ "_first", - {first, [], [Header|Rest]}); - - true -> - ok - end, - - %% Extract files to include - Files = case Rest of - [{description, _, _}|NewRest] -> - lists:map(fun({include, [{_, _, F}], _}) ->filename:rootname(F) end, - NewRest); - [{include, _, _}|_NewRest] -> - lists:map(fun({include, [{_, _, F}], _}) -> filename:rootname(F) end, - Rest) - end, - - %% Concat all reference manuals into a *big* parse tree - ConcatTree = concat_files(Files, Opts0), - - %% Create the kwic index src file to be put in outdir - docb_main:transform(refs, kwic, Opts0, File, {refs,[],ConcatTree}), - - case docb_util:an_option(kwicindex_only, Opts0) of - false -> - - %% Create an index - docb_main:transform(index, html, Opts0, File ++ "_index", - {index, [], [Header|ConcatTree]}), - %% Create a cite dictionary - docb_main:transform(cite, html, Opts0, File ++ "_cite", - {cite, [], [Header|ConcatTree]}), - - %% Create a term dictionary - docb_main:transform(term, html, Opts0, File ++ "_term", - {term, [], [Header|ConcatTree]}), - - %% Transform each reference page - case docb_util:an_option(framework_only, Opts0) of - true -> - ok; - false -> - transform_refs(Files, - [dict,{part_application,File}|Opts0]) - end; - true -> - ok - end, - - %% Find all fascicules to be put in the top menu of the table of - %% contents - Ext = docb_util:lookup_option(src_type, Opts0), - Opts2 = - case filelib:is_regular("fascicules"++Ext) of - true -> - case docb_main:parse1("fascicules", Opts0) of - {ok, Parse} -> - FascData = get_fasc_data(Parse), - case lists:keyfind(File, 1, FascData) of - {_, _, "YES", _} -> - OrigFile = - docb_util:outfile(File++"_frame", - ".html", Opts0), - EntryFile = - docb_util:outfile("index", - ".html",Opts0), - docb_util:message(info, - "Copying ~s to ~s", - [OrigFile,EntryFile]), - file:copy(OrigFile, EntryFile); - _ -> - ok - end, - [{fascdata, FascData}| Opts0]; - errors -> - %% Do not bother - docb_util:message( - warning, - "fascicules~s could not be parsed," - " no index.html created", - [Ext]), - Opts0 - end; - false -> - %% do not bother - docb_util:message(warning, - "fascicules~s not found, " - "no index.html created", - [Ext]), - Opts0 - end, - - %% Create ToC parse tree - {{toc, [{"FILE", "CDATA", File}], [Header|make_toc(ConcatTree)]}, - Opts2}. - -concat_files(Files, Opts) -> - concat_files(Files, [], Opts). - -concat_files([File|Rest], Body, Opts) -> - case docb_main:parse1(File, Opts) of - {ok, Parse} -> - NewParse=expand([Parse], File), - %% Remove the reference manual header - [{Ref, [], [_Hdr| NewBody]}] = NewParse, - RefParse = [{Ref, [], NewBody}], - Body ++ concat_files(Rest, RefParse, Opts); - errors -> - errors - end; -concat_files([], Body, _Opts) -> - Body. - -expand([], _) -> - []; -expand([{pcdata, Attrs, More}|Rest], File) -> - [{pcdata, Attrs, More}|expand(Rest, File)]; -expand([{name, Attrs, More}|Rest], File) -> - [{name, [{"FILE", "CDATA", File}|Attrs], More}|expand(Rest, File)]; -expand([{module, Attrs, More}|Rest], File) -> - [{module, [{"FILE", "CDATA", File}|Attrs], More}|expand(Rest,File)]; -expand([{file, Attrs, More}|Rest], File) -> - [{file, [{"FILE", "CDATA", File}|Attrs], More}|expand(Rest, File)]; -expand([{app, Attrs, More}|Rest], File) -> - [{app, [{"FILE", "CDATA", File}|Attrs], More}|expand(Rest, File)]; -expand([{lib, Attrs, More}|Rest], File) -> - [{lib, [{"FILE", "CDATA", File}|Attrs], More}|expand(Rest, File)]; -expand([{com, Attrs, More}|Rest], File) -> - [{com, [{"FILE", "CDATA", File}|Attrs], More}|expand(Rest, File)]; -expand([{Tag, Attrs, More}|Rest], File) -> - [{Tag, Attrs, expand(More, File)}|expand(Rest, File)]. - -transform_refs([], _) -> - ok; -transform_refs([File|Rest], Opts) -> - Ext = docb_util:lookup_option(src_type, Opts), - docb_util:message(info, "Processing \"~s~s\"", [File, Ext]), - docb_main:process(File, Opts), - transform_refs(Rest, Opts). - -make_toc([]) -> - []; -make_toc([{pcdata, _Attrs, _More}|Rest]) -> - make_toc(Rest); -make_toc([{module, Attrs, More}|Rest]) -> - [{module, Attrs, More}|make_toc(Rest)]; -make_toc([{file, Attrs, More}|Rest]) -> - [{file, Attrs, More}|make_toc(Rest)]; -make_toc([{app, Attrs, More}|Rest]) -> - [{app, Attrs, More}|make_toc(Rest)]; -make_toc([{lib, Attrs, More}|Rest]) -> - [{lib, Attrs, More}|make_toc(Rest)]; -make_toc([{com, Attrs, More}|Rest]) -> - [{com, Attrs, More}|make_toc(Rest)]; -make_toc([{_Tag, _Attrs, More}|Rest]) -> - make_toc(More) ++ make_toc(Rest). - -rule([module|_], {_, [File], _}) -> - {"<small><a target=\"document\" href=\"" ++ - docb_html_util:make_anchor_href(File) ++ "\">", - "</a></small><br/>\n"}; - -rule([file|_], {_, [File], _}) -> - {"<small><a target=\"document\" href=\"" ++ - docb_html_util:make_anchor_href(File) ++ "\">", - "</a></small><br/>\n"}; - -rule([app|_], {_, [File], _}) -> - {"<small><a target=\"document\" href=\"" ++ - docb_html_util:make_anchor_href(File) ++ "\">", - "</a></small><br/>\n"}; - -rule([lib|_], {_, [File], _}) -> - {"<small><a target=\"document\" href=\"" ++ - docb_html_util:make_anchor_href(File) ++ "\">", - "</a></small><br/>\n"}; - -rule([com|_], {_, [File], _}) -> - {"<small><a target=\"document\" href=\"" ++ - docb_html_util:make_anchor_href(File) ++ "\">", - "</a></small><br/>\n"}; - -rule([pcdata|_], {_, _, Data}) -> - {drop, docb_html_util:pcdata_to_html(Data)}; - -rule(_, _) -> - {drop, ""}. - -rule([toc|_], {_Depth, [File], [Header|_]}, Opts) -> - case docb_util:lookup_option(fascdata, Opts) of - false -> - {{docb_html_layout:application_toc_top( - docb_html_util:all_header_data(Header), - File, Opts), - docb_html_layout:part_toc_bot()}, Opts}; - FascData -> - HRefTexts = - lists:map( - fun({_File, HRef, _Entry, PCText}) -> - {HRef, docb_html_util:pcdata_to_html(PCText)} - end, - FascData), - {{docb_html_layout:application_toc_top( - docb_html_util:all_header_data(Header), - File, Opts, HRefTexts) ++ "\n", - docb_html_layout:part_toc_bot()}, Opts} - end. - -%% Returns: [{File, HRef, Entry, Text}]. -get_fasc_data({fascicules, _, Fascs}) -> - lists:map( - fun({fascicule, Atts, Trees}) -> - AVals = get_avals(Atts), - PCText = get_pc_text(Trees), - list_to_tuple(lists:append([AVals, [PCText]])) - end, - Fascs). - -get_avals(Atts) -> - [element(3, Tuple) || Tuple <- Atts]. - -get_pc_text([{pcdata, _, Text}]) -> - Text. diff --git a/lib/docbuilder/src/docb_tr_appref2html.erl b/lib/docbuilder/src/docb_tr_appref2html.erl deleted file mode 100644 index 6b4cc0f815..0000000000 --- a/lib/docbuilder/src/docb_tr_appref2html.erl +++ /dev/null @@ -1,48 +0,0 @@ -%% ``The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. -%% Portions created by Ericsson are Copyright 1999-2000, Ericsson -%% Utvecklings AB. All Rights Reserved.'' -%% -%% $Id$ -%% --module(docb_tr_appref2html). - --export([extension/0, transform/3, rule/2, rule/3]). - -extension() -> - ".html". - -%% Transform the parse tree. Header data is stored in an extra -%% argument to make life easier later on. -transform(_File, {appref,_,[Header|Rest]}, _Opts) -> - Data = [{[], [], docb_html_util:all_header_data(Header)}], - {appref, Data, [{header,[],[]}|Rest]}. - -rule([header|_],_) -> - {drop, ""}; - -rule([app|_],_) -> - {"\n<h3>APPLICATION</h3>\n<div class=\"REFBODY\">\n","\n</div>\n"}; - -rule([appsummary|_],_) -> - {"\n<h3>APPLICATION SUMMARY</h3>\n<div class=\"REFBODY\">\n","\n</div>\n"}; - -rule(TagHistory, TagBody) -> - docb_html_ref:rule(TagHistory,TagBody). - -rule([appref|_], {_,[Data],_}, Opts) -> - {{docb_html_layout:ref_top(Data, Opts), - docb_html_layout:ref_bot(Opts)}, Opts}; - -rule(TagHistory, TagBody, Opts) -> - docb_html_ref:rule(TagHistory, TagBody, Opts). diff --git a/lib/docbuilder/src/docb_tr_chapter2html.erl b/lib/docbuilder/src/docb_tr_chapter2html.erl deleted file mode 100644 index 185cdc7cc3..0000000000 --- a/lib/docbuilder/src/docb_tr_chapter2html.erl +++ /dev/null @@ -1,59 +0,0 @@ -%% ``The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. -%% Portions created by Ericsson are Copyright 1999-2000, Ericsson -%% Utvecklings AB. All Rights Reserved.'' -%% -%% $Id$ -%% --module(docb_tr_chapter2html). - --export([extension/0, transform/3, rule/2, rule/3]). - -extension() -> - ".html". - -transform(File, {chapter,_,[Header|Rest]}, Opts) -> - Data = [{[], [], docb_html_util:all_header_data(Header)}], - Tree = {chapter, Data, [{header,[],[]}|Rest]}, - ChapterLevel = - case docb_util:lookup_option(number, Opts) of - false -> none; - Value -> Value - end, - docb_html_util:number(Tree, ChapterLevel, File). - -rule([header|_], _) -> - {drop, ""}; - -rule([toc|_], {_,_,ToC}) -> - {drop, - "\n<h3>Table of Contents</h3>\n" ++ - docb_html_util:format_toc(ToC) ++ "\n"}; - -rule([section|_], _) -> - {"", ""}; - -rule([title|Rest], {_,[Number,_File], [{pcdata,_,Title}]}) -> - N = integer_to_list(docb_html_util:count_sections(Rest)+1), - {drop,"\n<h" ++ N ++ ">" ++ Number ++ " " ++ - docb_html_util:pcdata_to_html(Title) ++ "</h" ++ N ++ ">\n"}; - -rule(TagHistory, TagBody) -> - docb_html:rule(TagHistory, TagBody). - -rule([chapter|_], {_,[Data],_}, Opts) -> - {{docb_html_layout:chapter_top(Data, Opts), - docb_html_layout:chapter_bot(Opts)}, Opts}; - -rule(TagHistory, TagBody, Opts) -> - docb_html:rule(TagHistory, TagBody, Opts). diff --git a/lib/docbuilder/src/docb_tr_cite2html.erl b/lib/docbuilder/src/docb_tr_cite2html.erl deleted file mode 100644 index 77f1c4e636..0000000000 --- a/lib/docbuilder/src/docb_tr_cite2html.erl +++ /dev/null @@ -1,134 +0,0 @@ -%% ``The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. -%% Portions created by Ericsson are Copyright 1999-2000, Ericsson -%% Utvecklings AB. All Rights Reserved.'' -%% -%% $Id$ -%% --module(docb_tr_cite2html). - --export([extension/0, transform/3, rule/2, rule/3]). - -extension() -> - ".html". - -transform(_File, Tree, Opts) -> - purge(Tree, Opts). - -purge({Tag, Attrs, [Header|Body]}, Opts) -> - CiteList = case docb_util:lookup_option({defs,cite}, Opts) of - false -> []; - Value -> Value - end, - B1 = purge_body(Body, CiteList), - B2 = lists:ukeysort(2, B1), - {Tag, Attrs, [Header|B2]}. - -purge_body([], _) -> - []; -purge_body([{pcdata,_Attrs,_More}|Rest], CiteList) -> - purge_body(Rest, CiteList); -purge_body([{cite,[{"ID","CDATA",ID}],More}|Rest], CiteList) -> - case lists:keyfind(ID, 1, CiteList) of - false -> - [{cite, [{"NAME","CDATA",ID}, {"ID","CDATA",ID}], More}| - purge_body(Rest, CiteList)]; - {ID, Name, _Description, _Responsible} -> - [{cite, [{"NAME","CDATA",Name}, {"ID","CDATA",ID}], More}| - purge_body(Rest, CiteList)]; - {ID, Name, _Description} -> - [{cite, [{"NAME","CDATA",Name}, {"ID","CDATA",ID}], More}| - purge_body(Rest, CiteList)] - end; -purge_body([{_Tag,_Attrs,More}|Rest], CiteList) -> - purge_body(More, CiteList) ++ purge_body(Rest, CiteList). - -rule([header|_], _) -> - {drop, ""}; -rule(_, _) -> - {drop, ""}. - -rule([cite|_], {_,[],[Header]}, Opts) -> - HeaderData = docb_html_util:all_header_data(Header), - {{docb_html_layout:chapter_top(HeaderData, Opts) ++ - "\n<center><h1>Bibliography</h1></center>\n", - docb_html_layout:chapter_bot(Opts)}, Opts}; - -rule([cite|_], {_,[],[Header|_]}, Opts) -> - HeaderData = docb_html_util:all_header_data(Header), - {{docb_html_layout:chapter_top(HeaderData, Opts) ++ - "\n<center><h1>Bibliography</h1></center>\n<dl>\n", - "\n</dl>\n" ++ docb_html_layout:chapter_bot(Opts)}, Opts}; - -rule([cite|_], {_,[Data],_}, Opts) -> - {{docb_html_layout:chapter_top(Data, Opts) ++ - "\n<center><h1>Bibliography</h1></center>\n<dl>\n", - "\n</dl>\n" ++ docb_html_layout:chapter_bot(Opts)}, Opts}; - -rule([cite|T], {A, B, [{citedef,C, - [{ctitle, [], [{pcdata,[],CTitle}]}, - {cauthor, [], [{pcdata,[],CAuthor}]}, - {chowpublished, [], - [{pcdata,[],Chowpublished}]}]}]}, Opts) -> - CiteDef = CTitle ++ " " ++ CAuthor ++ " " ++ Chowpublished, - rule([cite|T], {A,B,[{citedef,C,[{pcdata,[],CiteDef}]}]}, Opts); - -rule([cite|_], {_,[Name,ID], [{citedef,[],[{pcdata,[],Def}]}]}, Opts) -> - CiteList = - case docb_util:lookup_option({defs,cite}, Opts) of - false -> []; - Value -> Value - end, - case lists:keyfind(ID, 1, CiteList) of - false -> - {{drop,"\n<dt><a name=\"" ++ ID ++ "\">" ++ - "<strong>" ++ ID ++ "</strong></a></dt>\n<dd>" ++ - docb_html_util:pcdata_to_html(Def) ++ "\n</dd>\n"}, Opts}; - {ID, Name, Description, _Responsible} -> - docb_util:message(warning, - "Global cite ~s overriding local", [ID]), - {{drop,"\n<dt><a name=\"" ++ ID ++ "\">" ++ - "<strong>" ++ Name ++ "</strong></a></dt>\n<dd>" ++ - docb_html_util:pcdata_to_html(Description) ++ "\n</dd>\n"}, - Opts}; - {ID, Name, Description} -> - docb_util:message(warning, - "Global cite ~s overriding local", [ID]), - {{drop,"\n<dt><a name=\"" ++ ID ++ "\">" ++ - "<strong>" ++ Name ++ "</strong></a></dt>\n<dd>" ++ - docb_html_util:pcdata_to_html(Description) ++ "\n</dd>\n"}, Opts} - end; - -rule([cite|_], {_,[Name,ID],_}, Opts) -> - CiteList = - case docb_util:lookup_option({defs,cite}, Opts) of - false -> []; - Value -> Value - end, - case lists:keyfind(ID, 1, CiteList) of - false -> - docb_util:message(error, - "The cite ~s has no definition", [ID]), - {{drop,"\n<dt><a name=\"" ++ ID ++ "\">" ++ - "<strong>" ++ ID ++ "</strong></a></dt>\n<dd>" ++ - "??" ++ "\n</dd>\n"}, Opts}; - {ID, Name, Description, _Responsible} -> - {{drop,"\n<dt><a name=\"" ++ ID ++ "\">" ++ - "<strong>" ++ Name ++ "</strong></a></dt>\n<dd>" ++ - docb_html_util:pcdata_to_html(Description) ++ "\n</dd>\n"}, - Opts}; - {ID, Name, Description} -> - {{drop,"\n<dt><a name=\"" ++ ID ++ "\">" ++ - "<strong>" ++ Name ++ "</strong></a></dt>\n<dd>" ++ - docb_html_util:pcdata_to_html(Description) ++ "\n</dd>\n"}, Opts} - end. diff --git a/lib/docbuilder/src/docb_tr_comref2html.erl b/lib/docbuilder/src/docb_tr_comref2html.erl deleted file mode 100644 index 25207dccb4..0000000000 --- a/lib/docbuilder/src/docb_tr_comref2html.erl +++ /dev/null @@ -1,46 +0,0 @@ -%% ``The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. -%% Portions created by Ericsson are Copyright 1999-2000, Ericsson -%% Utvecklings AB. All Rights Reserved.'' -%% -%% $Id$ -%% --module(docb_tr_comref2html). - --export([extension/0, transform/3, rule/2, rule/3]). - -extension() -> - ".html". - -transform(_File, {comref,_,[Header|Rest]}, _Opts) -> - Data = [{[], [], docb_html_util:all_header_data(Header)}], - {comref, Data, [{header,[],[]}|Rest]}. - -rule([header|_],_) -> - {drop,""}; - -rule([com|_],_) -> - {"\n<h3>COMMAND</h3>\n<div class=\"REFBODY\">\n","\n</div>\n"}; - -rule([comsummary|_],_) -> - {"\n<h3>COMMAND SUMMARY</h3>\n<div class=\"REFBODY\">\n","\n</div>\n"}; - -rule(TagHistory, TagBody) -> - docb_html_ref:rule(TagHistory, TagBody). - -rule([comref|_], {_,[Data],_}, Opts) -> - {{docb_html_layout:ref_top(Data, Opts), - docb_html_layout:ref_bot(Opts)}, Opts}; - -rule(TagHistory, TagBody, Opts) -> - docb_html_ref:rule(TagHistory, TagBody, Opts). diff --git a/lib/docbuilder/src/docb_tr_cref2html.erl b/lib/docbuilder/src/docb_tr_cref2html.erl deleted file mode 100644 index 06748b8c57..0000000000 --- a/lib/docbuilder/src/docb_tr_cref2html.erl +++ /dev/null @@ -1,61 +0,0 @@ -%% ``The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. -%% Portions created by Ericsson are Copyright 1999-2000, Ericsson -%% Utvecklings AB. All Rights Reserved.'' -%% -%% $Id$ -%% --module(docb_tr_cref2html). - --export([extension/0, transform/3, rule/2, rule/3]). - -extension() -> - ".html". - -transform(_File, {cref,_,[Header|Rest]}, _Opts) -> - Data = [{[], [], docb_html_util:all_header_data(Header)}], - {cref, Data, [{header,[],[]}|Rest]}. - -rule([header|_],_) -> - {drop, ""}; - -rule([ret|_],_) -> - {"",""}; - -rule([nametext|_],_) -> - {" ",""}; - -rule([name|_], {_,_,[_Ret,{nametext,[],[{pcdata,[],Name}]}]}) -> - FName = lists:flatten(docb_html_util:pcdata_to_html(Name)), - TName = docb_util:trim(FName), - CAnchor = docb_util:fknidx(TName, "/"), - {"<A NAME=\"" ++ CAnchor ++ "\"><STRONG><CODE>", - "</CODE></STRONG></A><BR>\n"}; -rule([name|T], {I,As,[Ret,{pcdata,[],Name}]}) -> % For SGML DTD - rule([name|T], {I,As,[Ret,{nametext,[],[{pcdata,[],Name}]}]}); - -rule([lib|_],_) -> - {"\n<H3>C LIBRARY</H3>\n<DIV CLASS=REFBODY>\n","\n</DIV>\n"}; - -rule([libsummary|_],_) -> - {"\n<H3>C LIBRARY SUMMARY</H3>\n<DIV CLASS=REFBODY>\n","\n</DIV>\n"}; - -rule(TagHistory, TagBody) -> - docb_html_ref:rule(TagHistory, TagBody). - -rule([cref|_], {_,[Data],_}, Opts) -> - {{docb_html_layout:ref_top(Data, Opts), - docb_html_layout:ref_bot(Opts)}, Opts}; - -rule(TagHistory, TagBody, Opts) -> - docb_html_ref:rule(TagHistory, TagBody, Opts). diff --git a/lib/docbuilder/src/docb_tr_erlref2html.erl b/lib/docbuilder/src/docb_tr_erlref2html.erl deleted file mode 100644 index b264c46bce..0000000000 --- a/lib/docbuilder/src/docb_tr_erlref2html.erl +++ /dev/null @@ -1,46 +0,0 @@ -%% ``The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. -%% Portions created by Ericsson are Copyright 1999-2000, Ericsson -%% Utvecklings AB. All Rights Reserved.'' -%% -%% $Id$ -%% --module(docb_tr_erlref2html). - --export([extension/0, transform/3, rule/2, rule/3]). - -extension() -> - ".html". - -transform(_File, {erlref,_,[Header|Rest]}, _Opts) -> - Data = [{[], [], docb_html_util:all_header_data(Header)}], - {erlref, Data, [{header,[],[]}|Rest]}. - -rule([header|_],_) -> - {drop, ""}; - -rule([module|_],_) -> - {"\n<h3>MODULE</h3>\n<div class=\"REFBODY\">\n","\n</div>\n"}; - -rule([modulesummary|_],_) -> - {"\n<h3>MODULE SUMMARY</h3>\n<div class=\"REFBODY\">\n","\n</div>\n"}; - -rule(TagHistory, TagBody) -> - docb_html_ref:rule(TagHistory, TagBody). - -rule([erlref|_], {_,[Data],_}, Opts) -> - {{docb_html_layout:ref_top(Data, Opts), - docb_html_layout:ref_bot(Opts)}, Opts}; - -rule(TagHistory, TagBody, Opts) -> - docb_html_ref:rule(TagHistory, TagBody, Opts). diff --git a/lib/docbuilder/src/docb_tr_fileref2html.erl b/lib/docbuilder/src/docb_tr_fileref2html.erl deleted file mode 100644 index 60280543a8..0000000000 --- a/lib/docbuilder/src/docb_tr_fileref2html.erl +++ /dev/null @@ -1,46 +0,0 @@ -%% ``The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. -%% Portions created by Ericsson are Copyright 1999-2000, Ericsson -%% Utvecklings AB. All Rights Reserved.'' -%% -%% $Id$ -%% --module(docb_tr_fileref2html). - --export([extension/0, transform/3, rule/2, rule/3]). - -extension() -> - ".html". - -transform(_File, {fileref,_,[Header|Rest]}, _Opts) -> - Data = [{[], [], docb_html_util:all_header_data(Header)}], - {fileref, Data, [{header,[],[]}|Rest]}. - -rule([header|_],_) -> - {drop, ""}; - -rule([file|_],_) -> - {"\n<h3>FILE</h3>\n<div class=\"REFBODY\">\n","\n</div>\n"}; - -rule([filesummary|_],_) -> - {"\n<h3>FILE SUMMARY</h3>\n<div class=\"REFBODY\">\n","\n</div>\n"}; - -rule(TagHistory, TagBody) -> - docb_html_ref:rule(TagHistory, TagBody). - -rule([fileref|_], {_,[Data],_}, Opts) -> - {{docb_html_layout:ref_top(Data, Opts), - docb_html_layout:ref_bot(Opts)}, Opts}; - -rule(TagHistory, TagBody, Opts) -> - docb_html_ref:rule(TagHistory, TagBody, Opts). diff --git a/lib/docbuilder/src/docb_tr_first2html.erl b/lib/docbuilder/src/docb_tr_first2html.erl deleted file mode 100644 index e9ecbe73cb..0000000000 --- a/lib/docbuilder/src/docb_tr_first2html.erl +++ /dev/null @@ -1,46 +0,0 @@ -%% ``The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. -%% Portions created by Ericsson are Copyright 1999-2000, Ericsson -%% Utvecklings AB. All Rights Reserved.'' -%% -%% $Id$ -%% --module(docb_tr_first2html). - --export([extension/0, transform/3, rule/2, rule/3]). - -extension() -> - ".html". - -transform(_File, Tree, _Opts) -> - Tree. - -rule([header|_], _) -> - {drop, ""}; - -rule([description|_], _) -> - {"", ""}; - -rule([include|_], _) -> - {drop, ""}; - -rule(TagHistory, TagBody) -> - docb_html:rule(TagHistory, TagBody). - -rule([first|_], {_,[],[Header|_]}, Opts) -> - HeaderData = docb_html_util:all_header_data(Header), - {{docb_html_layout:first_top(HeaderData, Opts), - docb_html_layout:first_bot(Opts)}, Opts}; - -rule(TagHistory, TagBody, Opts) -> - docb_html:rule(TagHistory, TagBody, Opts). diff --git a/lib/docbuilder/src/docb_tr_index2html.erl b/lib/docbuilder/src/docb_tr_index2html.erl deleted file mode 100644 index 312342add2..0000000000 --- a/lib/docbuilder/src/docb_tr_index2html.erl +++ /dev/null @@ -1,195 +0,0 @@ -%% ``The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. -%% Portions created by Ericsson are Copyright 1999-2000, Ericsson -%% Utvecklings AB. All Rights Reserved.'' -%% -%% $Id$ -%% --module(docb_tr_index2html). - --export([extension/0, transform/3, rule/2]). - -extension() -> - ".html". - -transform(_File0, {index, Attrs, [Header| Trees0]}, _Opts) -> - Trees1 = prune_flat(Trees0, false), - %% - %% Now each element of Trees1 is a tree with tag `name' and - %% attribute `File', and with one `pcdata' subtree containing the - %% name `Func' of the function. We extract `File' and `Func', and - %% create new trees. - %% - %% `File' is attribute CDATA (from an <include file=...>), and - %% `Func' is PCDATA. - %% - FileFuncs = - [{File, RefType, Func} || - {name, [{_, _, File}, {_, _, RefType}|_], - [{pcdata, [], Func}]} - <- Trees1], - Trees2 = new_trees(FileFuncs), - {index, Attrs, [Header| Trees2]}. - -%% Remove all elements except those with tag equal to `name'. -%% Within `name' remove all elements except those equal to `pcdata'. -%% Add attribute `filetype' to `name'. -%% -%% Refs: appref, comref, cref, erlref, fileref -prune_flat([{appref, _Attrs, More}| Rest], _) -> - RefType = appref, - lists:append(prune_flat(More, RefType), prune_flat(Rest, RefType)); -prune_flat([{comref, _Attrs, More}| Rest], _) -> - RefType = comref, - lists:append(prune_flat(More, RefType), prune_flat(Rest, RefType)); -prune_flat([{cref, _Attrs, More}| Rest], _) -> - RefType = cref, - lists:append(prune_flat(More, RefType), prune_flat(Rest, RefType)); -prune_flat([{erlref, _Attrs, More}| Rest], _) -> - RefType = erlref, - lists:append(prune_flat(More, RefType), prune_flat(Rest, RefType)); -prune_flat([{fileref, _Attrs, More}| Rest], _) -> - RefType = fileref, - lists:append(prune_flat(More, RefType), prune_flat(Rest, RefType)); -prune_flat([{name, [Attr0|Attrs0], More}| Rest], RefType) -> - Attrs = [Attr0, {"FILETYPE", "CDATA", RefType} | - Attrs0], - [{name, Attrs, keep_pcdata(More)}| prune_flat(Rest, RefType)]; -prune_flat([{pcdata, _, _}| Rest], RefType) -> % special case - prune_flat(Rest, RefType); -prune_flat([{_Tag, _Attrs, More}| Rest], RefType) -> - lists:append(prune_flat(More, RefType), prune_flat(Rest, RefType)); -prune_flat([], _) -> - []. - -keep_pcdata(Trees) -> - [T || T = {pcdata, _, _} <- Trees]. - -new_trees(FileFuncs) -> - Files0 = [{File, RefType} || {File, RefType, _} <- FileFuncs], - Files1 = lists:usort(Files0), - FileEntries = [{reffile, File, RefType, - [Fu || {Fi, _, Fu} <- FileFuncs, Fi == File]} - || {File, RefType} <- Files1], - FuncEntries = [{func, Func, RefType, [File]} - || {File, RefType, Func} <- FileFuncs], - Entries = FileEntries ++ FuncEntries, - SortedEntries = sort_entries(Entries), - %% - %% We create a tree according to the following "dtd": - %% - %% element index (reffile | funcdef)* - %% element reffile (funcdef2)* - %% attribute reffile filename CDATA - %% attribute reffile filetype CDATA - %% element funcdef2 PCDATA - %% attribute funcdef2 filename CDATA - %% attribute funcdef2 filetype CDATA - %% element funcdef PCDATA - %% attribute funcdef filename CDATA - %% attribute funcdef filetype CDATA - %% - %% For example: - %% <index> - %% <reffile filename="mymod" filetype="erlref"> - %% <funcdef2 filename="mymod" filetype="erlref">myfunca(A)</> - %% <funcdef2 filename="mymod" filetype="erlref">myfuncb(A, B)</> - %% </> - %% <funcdef filename="mymod" filetype="erlref">myfunca(A)</> - %% <funcdef filename="mymod" filetype="erlref">myfuncb(A, B)</> - %% </> - lists:flatmap( - fun({reffile, File, RefType, Funcs}) -> - %% A reffile tree - [{reffile, [{"FILENAME", "CDATA", File}, - {"FILETYPE", "CDATA", RefType}], - [{funcdef2, [{"FILENAME", "CDATA", File}, - {"FILETYPE", "CDATA", RefType}], - [{pcdata, [], Func}]} || Func <- Funcs]}]; - ({func, Func, RefType, [File]}) -> - %% A func tree - [{funcdef, [{"FILENAME", "CDATA", File}, - {"FILETYPE", "CDATA", RefType}], - [{pcdata, [], Func}]}] - end, SortedEntries). - -%% Sorting of entries -%% -%% The sorting is based on how names of files and functions are -%% presented (in a browser). -%% Requires conversion to "function/2" etc. -%% -sort_entries(Entries) -> - ExpEntries = - lists:map( - fun({reffile, File, RefType, Funcs}) -> - HFile = filename_sort_order(File), - HFuncs = [{funcdef_sort_order(Fu, RefType), Fu} || Fu <- Funcs], - {reffile, HFile, File, RefType, lists:sort(HFuncs)}; - ({func, Func, RefType, [File]}) -> - HFunc = funcdef_sort_order(Func, RefType), - HFile = filename_sort_order(File), - {func, HFunc, Func, RefType, [{HFile, File}]} - end, Entries), - SortedExpEntries = lists:keysort(2, ExpEntries), - lists:map( - fun({Tag, _HName, Name, RefType, Vals}) -> - NVals = lists:map(fun({_HVal, Val}) -> Val end, Vals), - {Tag, Name, RefType, NVals} - end, SortedExpEntries). - -rule([index| _], _) -> - {docb_html_layout:index_top("") ++ - "<dl>\n", - "</dl>\n" ++ docb_html_layout:index_bot()}; - -rule([header| _], _) -> - {drop, ""}; - -rule([reffile| _], {_, [File, _RefType|_], _}) -> - CFile = docb_html_util:attribute_cdata_to_html(File), - {"<dt><em>" ++ CFile ++ "</em></dt>\n", ""}; - -rule([funcdef2| _], {_, [File, RefType|_], [{pcdata, [], FuncDef}]}) -> - FFuncDef = lists:flatten(docb_html_util:pcdata_to_html(FuncDef)), - TFuncDef = docb_util:trim(FFuncDef), - ShortFuncDef = docb_html_util:make_funcdef_short(TFuncDef, RefType), - HRef = - docb_html_util:make_anchor_href_short(File, TFuncDef, RefType), - {drop, - "<dd><a href=\"" ++ HRef ++ "\"><code>" ++ - ShortFuncDef ++ "</code></a></dd>\n"}; - -rule([funcdef| _], {_, [File, RefType|_], [{pcdata, [], FuncDef}]}) -> - FFuncDef = lists:flatten(docb_html_util:pcdata_to_html(FuncDef)), - TFuncDef = docb_util:trim(FFuncDef), - ShortFuncDef = docb_html_util:make_funcdef_short(TFuncDef, RefType), - HRef = - docb_html_util:make_anchor_href_short(File, TFuncDef, RefType), - CFile = docb_html_util:attribute_cdata_to_html(File), - {drop, - "<dt><code>" ++ ShortFuncDef ++ "</code></dt>\n" - "<dd><a href=\"" ++ HRef ++ "\"><em>" ++ - CFile ++ "</em></a></dd>\n"}; - -rule(_, _) -> - {drop, ""}. - -filename_sort_order(File) -> - docb_html_util:html_latin1_sort_order( - lists:flatten( - docb_html_util:attribute_cdata_to_html(string:strip(File)))). - -funcdef_sort_order(FuncDef, RefType) -> - docb_html_util:html_latin1_sort_order( - docb_html_util:make_anchor_name_short(FuncDef, RefType)). diff --git a/lib/docbuilder/src/docb_tr_part2html.erl b/lib/docbuilder/src/docb_tr_part2html.erl deleted file mode 100644 index 30befe8432..0000000000 --- a/lib/docbuilder/src/docb_tr_part2html.erl +++ /dev/null @@ -1,237 +0,0 @@ -%% ``The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. -%% Portions created by Ericsson are Copyright 1999-2000, Ericsson -%% Utvecklings AB. All Rights Reserved.'' -%% -%% $Id$ -%% --module(docb_tr_part2html). - --export([extension/0, transform/3, rule/2, rule/3]). - -extension() -> - ".html". - -transform(File, {part, _Attrs, [Header| Rest]}, Opts0) -> - - %% Extract header data - Title = docb_html_util:extract_header_data(title, Header), - - %% Create the framing HTML document - OutFile = docb_util:outfile(File ++ "_frame", ".html", Opts0), - case file:open(OutFile, [write]) of - {ok, Frame} -> - io:format(Frame, -"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" - \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\"> -<!-- This document was generated using DocBuilder-" ++ docb_util:version() ++ " --> -<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\"> -<head> - <title>~s</title> - " ++ docb_util:html_snippet(head, Opts0) ++ " -</head> -<frameset cols=\"200, *\"> - <frame src=\"~s\" name=\"toc\"/> - <frame src=\"~s\" name=\"document\"/> - <noframes> - <body bgcolor=\"#FFFFFF\" text=\"#000000\" link=\"#0000FF\" - vlink=\"#FF00FF\" alink=\"#FF0000\"> - <p>This documentation requires a browser that can handle frames</p> - </body> - </noframes> -</frameset> -</html> -", - [Title, File ++ ".html", File ++ "_first.html"]), - file:close(Frame) - end, - - %% Create the front HTML document - docb_main:transform(first, html, Opts0, File ++ "_first", - {first, [], [Header| Rest]}), - - %% Extract files to include - Files = - case Rest of - [{description, _, _}| NewRest] -> - lists:map(fun({include, [{_, _, F}], _}) -> filename:rootname(F) end, - NewRest); - [{include, _, _}| _NewRest] -> - lists:map(fun({include, [{_, _, F}], _}) -> filename:rootname(F) end, Rest) - end, - - %% Concat all chapters into a *big* parse tree - %% Also transform them to HTML - TransformP = not docb_util:an_option(framework_only, Opts0), - TOpts = [dict, {part_application,File}], - ConcatTree = concat_files(Files, Opts0, TransformP, TOpts), - - %% Create a cites dictionary - docb_main:transform(cite, html, Opts0, File ++ "_cite", - {cite, [], [Header| ConcatTree]}), - - %% Create a terms dictionary - docb_main:transform(term, html, Opts0, File ++ "_term", - {term, [], [Header| ConcatTree]}), - - %% Find all fascicules to be put in the top menu of the table of - %% contents - Ext = docb_util:lookup_option(src_type, Opts0), - Opts2 = - case filelib:is_regular("fascicules"++Ext) of - true -> - case docb_main:parse1("fascicules", Opts0) of - {ok, Parse} -> - FascData = get_fasc_data(Parse), - case lists:keyfind(File, 1, FascData) of - {_, _, "YES", _} -> - OrigFile = - docb_util:outfile(File++"_frame", - ".html", Opts0), - EntryFile = - docb_util:outfile("index", - ".html", Opts0), - docb_util:message(info, - "Copying ~s to ~s", - [OrigFile,EntryFile]), - file:copy(OrigFile, EntryFile); - _ -> - ok - end, - [{fascdata, FascData}| Opts0]; - errors -> - %% do not bother - docb_util:message( - warning, - "fascicules~s could not be parsed," - " no index.html created~n", [Ext]), - Opts0 - end; - _ -> - %% do not bother - docb_util:message(warning, - "fascicules~s not found, " - "no index.html created~n", - [Ext]), - Opts0 - end, - - %% Create ToC parse tree - {{toc, [{"FILE", "CDATA", File}], [Header| ConcatTree]}, Opts2}. - -concat_files(Files, Opts, TransformP, TOpts) -> - Ext = docb_util:lookup_option(src_type, Opts), - concat_files(Files, [], 1, Opts, TransformP, TOpts, Ext). - -concat_files([File | Rest], Body, ChLevel, Opts, TP, TOpts, Ext) -> - case docb_main:parse1(File, Opts) of - {ok, Parse} -> - {TopTag, Attrs, [Header = {header, _, HeaderContents} | More]} = Parse, - {title,_,Title} = lists:keyfind(title,1,HeaderContents), - NewMore = [{section, [], [{title, [], Title}| More]}], - NewParse = {TopTag, Attrs, [Header| NewMore]}, - if - TP -> - docb_util:message(info, - "Processing \"~s~s\"", - [File, Ext]), - Opts2 = - [html, {number,integer_to_list(ChLevel)}] ++ - TOpts ++ Opts, - docb_main:transform(TopTag, html, Opts2, File, - NewParse); - true -> ignore - end, - NumberTree = - docb_html_util:number(NewParse, - integer_to_list(ChLevel), File), - {_, [], [_| NewBody]} = NumberTree, - Body ++ concat_files(Rest, NewBody, ChLevel+1, Opts, - TP, TOpts, Ext); - errors -> - throw({error,"Parse error when building chapter "++File}) - end; -concat_files([], Body, _ChLevel, _Opts, _TP, _TOpts, _Ext) -> - Body. - -rule([section| _], _) -> - {"", ""}; - -rule(_, _) -> - {drop, ""}. - -rule([toc| _], {_Depth, [File], [Header| _]}, Opts) -> - case docb_util:lookup_option(fascdata, Opts) of - false -> - {{docb_html_layout:part_toc_top( - docb_html_util:all_header_data(Header), File, Opts), - docb_html_layout:part_toc_bot()}, Opts}; - FascData -> - HRefTexts = - lists:map( - fun({_File, HRef, _Entry, PCText}) -> - {HRef, docb_html_util:pcdata_to_html(PCText)} - end, - FascData), - {{docb_html_layout:part_toc_top( - docb_html_util:all_header_data(Header), - File, Opts, HRefTexts), - docb_html_layout:part_toc_bot()}, Opts} - end; - -rule([title| Rest], {_, [Number, File], [{pcdata, _, Title}]}, Opts) -> - N = docb_html_util:count_sections(Rest), - OutFile = docb_html_util:make_anchor_href(File), - if - N == 1 -> - {{drop, - "<hr/>\n<small>" ++ - Number ++ - " <a target=\"document\" href=\"" ++ OutFile ++ "#" ++ - Number ++ "\">" ++ - docb_html_util:pcdata_to_html(Title) ++ - "</a></small><br/>\n"}, - Opts}; - N < 3 -> - {{drop, - "<small>" ++ - Number ++ - " <a target=\"document\" href=\"" ++ OutFile ++ "#" ++ - Number ++ "\">" ++ - docb_html_util:pcdata_to_html(Title) ++ - "</a></small><br/>\n"}, - Opts}; - true -> - {{drop, ""}, Opts} - end. - -%% Parsed fascicules: -%% {fascicules,[], -%% [{fascicule, [{"FILE","CDATA","refman"}, -%% {"HREF","CDATA","refman_frame.html"}, -%% {"ENTRY","TOKEN","YES"}], -%% [{pcdata, [], "" Reference Manual\\n \n"}]}, -%% Returns: [{File, HRef, Entry, Text}]. -get_fasc_data({fascicules, _, Fascs}) -> - lists:map( - fun({fascicule, Atts, Trees}) -> - AVals = get_avals(Atts), - PCText = get_pc_text(Trees), - list_to_tuple(lists:append([AVals, [PCText]])) end, - Fascs). - -get_avals(Atts) -> - [element(3, Tuple) || Tuple <- Atts]. - -get_pc_text([{pcdata, _, Text}]) -> - Text. diff --git a/lib/docbuilder/src/docb_tr_refs2kwic.erl b/lib/docbuilder/src/docb_tr_refs2kwic.erl deleted file mode 100644 index dc60c329fc..0000000000 --- a/lib/docbuilder/src/docb_tr_refs2kwic.erl +++ /dev/null @@ -1,156 +0,0 @@ -%% ``The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. -%% Portions created by Ericsson are Copyright 1999-2000, Ericsson -%% Utvecklings AB. All Rights Reserved.'' -%% -%% $Id$ -%% --module(docb_tr_refs2kwic). - --export([extension/0, transform/3, rule/2]). - -%% Output parts of a parsetree that contains a series of reference -%% manual pages. The tags considered are: module, file, app, com and lib -%% (and their corresponding *summary tags), and name, fsummary, c, em, -%% ret and pcdata. - -extension() -> - ".kwc". - -transform(File, Tree, Opts) -> - {refs, [], Trees} = Tree, - FileTree = {srcfile, [], [{pcdata, [], File}]}, - AppName = docb_util:lookup_option(name, Opts, "unknown"), - AppTree = {appname, [], [{pcdata, [], AppName}]}, - Vsn = docb_util:lookup_option(vsn, Opts, "unknown"), - VsnTree = {appvsn, [], [{pcdata, [], Vsn}]}, - NewTree = {refs, [], [FileTree, AppTree, VsnTree| Trees]}, - {NewTree, Opts}. - -rule([refs|_],_) -> - {"%% Automatically generated. Do not edit.\n", ""}; - -rule([srcfile| _], _) -> - {"{srcfile, \"", "\"}.\n"}; - -rule([appname| _], _) -> - {"{appname, \"", "\"}.\n"}; - -rule([appvsn| _], _) -> - {"{appvsn, \"", "\"}.\n"}; - -rule([erlref|_ ], _) -> - {"", ""}; - -rule([fileref|_ ], _) -> - {"", ""}; - -rule([appref|_ ], _) -> - {"", ""}; - -rule([comref|_ ], _) -> - {"", ""}; - -rule([cref|_ ], _) -> - {"", ""}; - -rule([module| _], {_, [File], _}) -> - {drop, "{module, \"" ++ File ++ "\"}.\n"}; - -rule([file|_], {_, [File], _}) -> - {drop, "{file, \"" ++ File ++ "\"}.\n"}; - -rule([app|_], {_, [File], _}) -> - {drop, "{app, \"" ++ File ++ "\"}.\n"}; - -rule([com|_], {_, [File], _}) -> - {drop, "{com, \"" ++ File ++ "\"}.\n"}; - -rule([lib|_], {_, [File], _}) -> - {drop, "{lib, \"" ++ File ++ "\"}.\n"}; - -rule([modulesummary|_], _) -> - {"{modulesummary, \"", "\"}.\n"}; - -rule([filesummary|_], _) -> - {"{filesummary, \"", "\"}.\n"}; - -rule([appsummary|_], _) -> - {"{appsummary, \"", "\"}.\n"}; - -rule([comsummary|_], _) -> - {"{comsummary, \"", "\"}.\n"}; - -rule([libsummary|_], _) -> - {"{libsummary, \"", "\"}.\n"}; - -rule([funcs|_ ], _) -> - {"", ""}; - -rule([func|_ ], _) -> - {"", ""}; - -rule([name,func,funcs,cref|_], {_,[_File], [_Ret,{pcdata,[],Name}]}) -> - FName = lists:flatten(docb_html_util:pcdata_to_html(Name)), - TName = docb_util:trim(FName), - case catch docb_util:fknidx(TName, "/") of - {'EXIT',_} -> - {drop, ["{name, \"", escq(TName), "\"}.\n"]}; - FuncName -> - {drop, ["{name, \"", escq(FuncName), "\"}.\n"]} - end; - -rule([name,func,funcs,erlref|_], {_,[_File], [{pcdata,[],Name}]}) -> - FName = lists:flatten(docb_html_util:pcdata_to_html(Name)), - TName = docb_util:trim(FName), - case catch docb_util:fknidx(TName, "/") of - {'EXIT',_} -> - {drop, ["{name, \"", escq(TName), "\"}.\n"]}; - FuncName -> - {drop, ["{name, \"", escq(FuncName), "\"}.\n"]} - end; - -rule([name, func| _], {_, [_File], [{pcdata, [], Name}]}) -> - FName = lists:flatten(docb_html_util:pcdata_to_html(Name)), - TName = docb_util:trim(FName), - Cmd = case string:tokens(TName, " ") of - [Cmd0| _] -> - Cmd0; - _ -> - TName - end, - {drop, ["{name, \"", escq(Cmd), "\"}.\n"]}; - -rule([fsummary| _], _) -> - {"{fsummary, \"", "\"}.\n"}; - -rule([c, fsummary|_], _) -> - {"", ""}; - -rule([em, fsummary|_], _) -> - {"", ""}; - -rule([pcdata| _], {_, _, Data}) -> - FData = lists:flatten(docb_html_util:pcdata_to_html(Data)), - Out = lists:map(fun($\n) -> $ ; (C) -> C end, FData), - {drop, escq(Out)}; - -rule(_, _) -> - {drop, ""}. - -escq(Cs) -> - lists:flatmap(fun($") -> - "\\\""; - (C) -> [C] - end, - Cs). diff --git a/lib/docbuilder/src/docb_tr_report2html.erl b/lib/docbuilder/src/docb_tr_report2html.erl deleted file mode 100644 index 3386ed972a..0000000000 --- a/lib/docbuilder/src/docb_tr_report2html.erl +++ /dev/null @@ -1,70 +0,0 @@ -%% ``The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. -%% Portions created by Ericsson are Copyright 1999-2000, Ericsson -%% Utvecklings AB. All Rights Reserved.'' -%% -%% $Id$ -%% --module(docb_tr_report2html). - --export([extension/0, transform/3, rule/2, rule/3]). - -%% -%% File extension -%% - -extension() -> - ".html". - -transform(File, {report,_,[Header|Rest]}, Opts) -> - Data = [{[], [], docb_html_util:all_header_data(Header)}], - Tree = {report, Data, [{header,[],[]}|Rest]}, - ChapterLevel = case docb_util:lookup_option(number, Opts) of - false -> none; - Value -> Value - end, - NumberTree = docb_html_util:number(Tree, ChapterLevel, File), - options(NumberTree, Opts). - -options(Tree, []) -> - Tree; -options(Tree, [_|Rest]) -> - options(Tree, Rest). - -rule([header|_], _) -> - {drop, ""}; - -rule([toc|_], {_,_,ToC}) -> - {drop, "\n<h3>Table of Contents</h3>\n" ++ - docb_html_util:format_toc(ToC) ++ "\n"}; - -rule([section|_], _) -> - {"", ""}; - -rule([title|Rest], {_,[Number,_File], [{pcdata,_,Title}]}) -> - N = integer_to_list(docb_html_util:count_sections(Rest)+1), - {drop, "\n<h" ++ N ++ ">" ++ Number ++ " " ++ - docb_html_util:pcdata_to_html(Title) ++ "</h" ++ N ++ ">\n"}; - -rule([erlinclude|_], {_,[File,Tag],_}) -> - docb_html_util:erl_include(File, Tag); - -rule(TagHistory, TagBody) -> - docb_html:rule(TagHistory, TagBody). - -rule([report|_], {_,[Data],_}, Opts) -> - {{docb_html_layout:report_top(Data, Opts), - docb_html_layout:report_bot(Opts)}, Opts}; - -rule(TagHistory, TagBody, Opts) -> - docb_html:rule(TagHistory, TagBody, Opts). diff --git a/lib/docbuilder/src/docb_tr_term2html.erl b/lib/docbuilder/src/docb_tr_term2html.erl deleted file mode 100644 index a3c4a5312a..0000000000 --- a/lib/docbuilder/src/docb_tr_term2html.erl +++ /dev/null @@ -1,124 +0,0 @@ -%% ``The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. -%% Portions created by Ericsson are Copyright 1999-2000, Ericsson -%% Utvecklings AB. All Rights Reserved.'' -%% -%% $Id$ -%% --module(docb_tr_term2html). - --export([extension/0, transform/3, rule/2, rule/3]). - -extension() -> - ".html". - -transform(_File, Tree, Opts) -> - purge(Tree, Opts). - -purge({Tag, Attrs, [Header|Body]}, Opts) -> - TermList = case docb_util:lookup_option({defs,term}, Opts) of - false -> []; - Value -> Value - end, - B1 = purge_body(Body, TermList), - B2 = lists:ukeysort(2, B1), - {Tag, Attrs, [Header|B2]}. - -purge_body([], _) -> - []; -purge_body([{pcdata,_Attrs,_More}|Rest], TermList) -> - purge_body(Rest, TermList); -purge_body([{term,[{"ID","CDATA",ID}],More}|Rest], TermList) -> - case lists:keyfind(ID, 1, TermList) of - false -> - [{term,[{"NAME","CDATA",ID},{"ID","CDATA",ID}],More}| - purge_body(Rest, TermList)]; - {ID, Name, _Description, _Responsible} -> - [{term,[{"NAME","CDATA",Name},{"ID","CDATA",ID}],More}| - purge_body(Rest, TermList)]; - {ID, Name, _Description} -> - [{term,[{"NAME","CDATA",Name},{"ID","CDATA",ID}],More}| - purge_body(Rest, TermList)] - end; -purge_body([{_Tag,_Attrs,More}|Rest], TermList) -> - purge_body(More, TermList) ++ purge_body(Rest, TermList). - -rule([header|_], _) -> - {drop, ""}; -rule(_, _) -> - {drop, ""}. - -rule([term|_], {_,[],[Header]}, Opts) -> - {{docb_html_layout:chapter_top( - docb_html_util:all_header_data(Header), Opts) ++ - "\n<center><h1>Glossary</h1></center>\n", - docb_html_layout:chapter_bot(Opts)}, Opts}; - -rule([term|_], {_,[],[Header|_]},Opts) -> - {{docb_html_layout:chapter_top( - docb_html_util:all_header_data(Header), Opts) ++ - "\n<center><h1>Glossary</h1></center>\n<dl>\n", - "\n</dl>\n" ++ docb_html_layout:chapter_bot(Opts)}, Opts}; - -rule([term|_], {_,[Data],_}, Opts) -> - {{docb_html_layout:chapter_top(Data, Opts) ++ - "\n<center><h1>Bibliography</h1></center>\n<dl>\n", - "\n</dl>\n" ++ docb_html_layout:chapter_bot(Opts)}, Opts}; - -rule([term|_], {_,[Name,ID],[{termdef,[],[{pcdata,[],Def}]}]}, Opts) -> - TermList = case docb_util:lookup_option({defs,term}, Opts) of - false -> []; - Value -> Value - end, - case lists:keyfind(ID, 1, TermList) of - false -> - {{drop,"\n<dt><a name=\"" ++ ID ++ "\">" ++ - "<strong>" ++ ID ++ "</strong></a>\n</dt>\n<dd>" ++ - docb_html_util:pcdata_to_html(Def) ++ "\n</dd>\n"}, Opts}; - {ID, Name, Description, _Responsible} -> - docb_util:message(warning, - "Global term ~s overriding local", [ID]), - {{drop,"\n<dt><a name=\"" ++ ID ++ "\">" ++ - "<strong>" ++ Name ++ "</strong></a></dt>\n<dd>" ++ - docb_html_util:pcdata_to_html(Description) ++ "\n</dd>\n"}, - Opts}; - {ID, Name, Description} -> - docb_util:message(warning, - "Global term ~s overriding local", [ID]), - {{drop, "\n<dt><a name=\"" ++ ID ++ "\">" ++ - "<strong>" ++ Name ++ "</strong></a></dt>\n<dd>" ++ - docb_html_util:pcdata_to_html(Description) ++ "\n</dd>\n"}, Opts} - end; - -rule([term|_], {_,[Name,ID],_}, Opts) -> - TermList = case docb_util:lookup_option({defs,term}, Opts) of - false -> []; - Value -> Value - end, - case lists:keyfind(ID, 1, TermList) of - false -> - docb_util:message(error, - "The term ~s has no definition", [ID]), - {{drop, "\n<dt><a name=\"" ++ ID ++ "\">" ++ - "<strong>" ++ ID ++ "</strong></a></dt>\n<dd>" ++ - "??" ++ "\n</dd>\n"}, Opts}; - {ID, Name, Description, _Responsible} -> - {{drop, "\n<dt><a name=\"" ++ ID ++ "\">" ++ - "<strong>" ++ Name ++ "</strong></a></dt>\n<dd>" ++ - docb_html_util:pcdata_to_html(Description) ++ "\n</dd>\n"}, - Opts}; - {ID, Name, Description} -> - {{drop, "\n<dt><a name=\"" ++ ID ++ "\">" ++ - "<strong>" ++ Name ++ "</strong></a></dt>\n<dd>" ++ - docb_html_util:pcdata_to_html(Description) ++ "\n</dd>\n"}, Opts} - end. diff --git a/lib/docbuilder/src/docb_transform.erl b/lib/docbuilder/src/docb_transform.erl deleted file mode 100644 index 736ac92274..0000000000 --- a/lib/docbuilder/src/docb_transform.erl +++ /dev/null @@ -1,163 +0,0 @@ -%% ``The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. -%% Portions created by Ericsson are Copyright 1999-2000, Ericsson -%% Utvecklings AB. All Rights Reserved.'' -%% -%% $Id$ -%% --module(docb_transform). - --export([file/1, file/2]). --deprecated([{file,1,next_major_release}, - {file,2,next_major_release}]). - -%% file(File) -> ok | {error, Reason} -%% file(File, Opts) -> ok | {error, Reason} -%% File = string(), file name with or without ".xml" extension -%% Opts = [Opt] -%% Reason = badfile | {badopt, Term} -file(File0) -> - file(File0, []). -file(File0, RawOpts) -> - File = filename:rootname(File0), % without extension - Ext = case filename:extension(File0) of - ".xml" -> ".xml"; - ".sgml" -> ".sgml"; - "" -> - %% If the file is given without extension, we try to - %% infer if the source file is XML or SGML. - %% SGML is supported *internally within OTP* for - %% backwards compatibility reasons. - case filelib:is_regular(File++".xml") of - true -> ".xml"; - false -> ".sgml" - end; - _Ext0 -> % this is probably an error... - ".xml" - end, - case filelib:is_regular(File++Ext) of - true -> - case parse(RawOpts) of - {ok, Opts0} -> - {ok, Cwd} = file:get_cwd(), - Opts = [{src_type,Ext}, - {src_dir,Cwd}, - {src_file,File}, - {{local_defs,term},[]}, - {{local_defs,cite},[]} | Opts0], - case docb_main:process(File, Opts) of - errors -> error; - ok -> ok - end; - Error -> % {error, {badopt,Term}} - Error - end; - false -> - {error, badfile} - end. - -parse(RawOpts) -> - parse(RawOpts, []). - -%% Officially supported options - -parse([{html_mod,Module} | RawOpts], Opts) when is_atom(Module) -> - parse(RawOpts, [{html_mod,Module} | Opts]); -parse([{outdir,Dir} | RawOpts], Opts) when is_list(Dir) -> - parse(RawOpts, [{outdir,Dir} | Opts]); -parse([{number,N} | RawOpts], Opts) when is_integer(N) -> - parse(RawOpts, [{number,integer_to_list(N)} | Opts]); -parse([{number,Nstr} | RawOpts], Opts) -> % list when called from script - parse(RawOpts, [{number,Nstr} | Opts]); -parse([{ptype,Type} | RawOpts], Opts) when Type==unix; - Type==windows -> - parse(RawOpts, [{ptype,atom_to_list(Type)} | Opts]); -parse([{ptype,Type} | RawOpts], Opts) -> % list when called from script - parse(RawOpts, [{ptype,Type} | Opts]); -parse([silent | RawOpts], Opts) -> - put(option_silent, true), - parse(RawOpts, [silent | Opts]); -parse([{top,Index} | RawOpts], Opts) when is_list(Index) -> - parse(RawOpts, [{top,Index} | Opts]); -parse([{vsn,Vsn} | RawOpts], Opts) when is_list(Vsn) -> - parse(RawOpts, [{vsn,Vsn} | Opts]); - -parse([{term_defs,File} | RawOpts], Opts) when is_list(File) -> - Opts2 = get_defs(term, File, Opts), - parse(RawOpts, Opts2); -parse([{cite_defs,File} | RawOpts], Opts) when is_list(File) -> - Opts2 = get_defs(cite, File, Opts), - parse(RawOpts, Opts2); - -%% OTP internal options (SGML and PDF support etc.) - -parse([html | RawOpts], Opts) -> - parse(RawOpts, [html | Opts]); -parse([latex | RawOpts], Opts) -> - parse(RawOpts, [latex | Opts]); -parse([{man,Level} | RawOpts], Opts) -> % Level = 1..9 - parse(RawOpts, [{man,Level} | Opts]); - -parse([{booksty,StyFile} | RawOpts], Opts) -> % "otpA4" | "otpBOOK" - parse(RawOpts, [{booksty,StyFile} | Opts]); -parse([{includepath,Dir} | RawOpts], Opts) -> - parse(RawOpts, [{includepath,Dir} | Opts]); -parse([showpaths | RawOpts], Opts) -> - parse(RawOpts, [showpaths | Opts]); -parse([straight | RawOpts], Opts) -> - parse(RawOpts, [straight | Opts]); -parse([{ent,Ent} | RawOpts], Opts) -> - parse(RawOpts, [{ent,Ent} | Opts]); - -%% Undocumented options - -parse([{name, Name} | RawOpts], Opts) -> - parse(RawOpts, [{name, Name} | Opts]); -parse([framework_only | RawOpts], Opts) -> - parse(RawOpts, [framework_only | Opts]); -parse([kwicindex_only | RawOpts], Opts) -> - parse(RawOpts, [kwicindex_only | Opts]); - -parse([], Opts) -> - {ok, Opts}; -parse([Opt | _RawOpts], _Opts) -> - {error, {badopt, Opt}}. - -%% Type = term | cite -get_defs(Type, File, Opts) -> - Key = {defs,Type}, - {PrevDefs, Opts2} = - case lists:keyfind(Key, 1, Opts) of - {_, Defs0} -> - {Defs0, lists:keydelete(Key, 1, Opts)}; - false -> - {[], Opts} - end, - NewDefs = case file:consult(File) of - {ok, [DefL]} when is_list(DefL) -> - DefL; - {ok, _Terms} -> - docb_util:message(error, - "Skipping defs file ~s, does " - "not contain one list", [File]), - []; - {error, Error} -> - Expl = lists:flatten(file:format_error(Error)), - docb_util:message(error, - "Skipping defs file ~s, ~s", - [File, Expl]), - [] - end, - [{Key,PrevDefs++NewDefs} | Opts2]. - - diff --git a/lib/docbuilder/src/docb_util.erl b/lib/docbuilder/src/docb_util.erl deleted file mode 100644 index 9b2eec7733..0000000000 --- a/lib/docbuilder/src/docb_util.erl +++ /dev/null @@ -1,237 +0,0 @@ -%% ``The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. -%% Portions created by Ericsson are Copyright 1999-2000, Ericsson -%% Utvecklings AB. All Rights Reserved.'' -%% -%% $Id$ -%% --module(docb_util). - --export([version/0, old_docb_dir/0, dtd_dir/0]). --export([html_snippet/2, html_snippet/3]). --export([lookup_option/2, lookup_option/3, lookup_options/2, - an_option/2]). --export([outfile/3, full_file_name/4]). --export([message/2, message/3]). --export([ltrim/1, rtrim/1, trim/1]). --export([join/2]). --export([fknidx/2]). - --include("docb_util.hrl"). - -%%--DocBuilder info----------------------------------------------------- - -%% version() -> string() -%% Returns the DocBuilder application version. -version() -> - DocbDir = code:lib_dir(docbuilder), - case string:tokens(filename:basename(DocbDir), "-") of - [_, Vsn] -> Vsn; - _ -> "unknown" - end. - -%% old_docb_dir() -> string() -%% Returns the root directory of Old_DocBuilder (OTP internal). -old_docb_dir() -> - "/home/otp/sgml/docb". - -%% dtd_dir() -> string() -%% Returns the directory where the XML DTDs are located. -dtd_dir() -> - DocbDir = code:lib_dir(docbuilder), - filename:join(DocbDir, "dtd"). - -%%--User defined HTML snippets------------------------------------------ - -%% html_snippet(What, Opts) -> HTML -%% html_snippet(What, Arg, Opts) -> HTML -%% What = head | seealso -%% HTML = string() -html_snippet(What, Opts) -> - case lookup_option(html_mod, Opts) of - false -> ""; - Module -> - case catch Module:What() of - HTML when is_list(HTML) -> - HTML; - {'EXIT', {undef, _}} -> - ""; - {'EXIT', Reason} -> - message(warning, - "Callback function ~p:~p() => ~p", - [Module, What, Reason]), - ""; - Other -> - message(warning, - "Callback function ~p:~p() => ~p", - [Module, What, Other]), - "" - end - end. -html_snippet(What, Arg, Opts) -> - case lookup_option(html_mod, Opts) of - false -> ""; - Module -> - case catch Module:What(Arg) of - HTML when is_list(HTML) -> - HTML; - {'EXIT', {undef, _}} -> - ""; - {'EXIT', Reason} -> - message(warning, - "Callback function ~p:~p(~p) => ~p", - [Module, What, Arg, Reason]), - ""; - Other -> - message(warning, - "Callback function ~p:~p(~p) => ~p", - [Module, What, Arg, Other]), - "" - end - end. - -%%--Option utilities---------------------------------------------------- - -%% Opts = [{Opt,Value} | Opt] - -%% lookup_option(Opt, Opts) -> Value | false -lookup_option(Opt, Opts) -> - case lists:keyfind(Opt, 1, Opts) of - {Opt,Value} -> Value; - false -> false - end. - -%% lookup_option(Opt, Opts, DefaultValue) -> Value | DefaultValue -lookup_option(Opt, Opts, DefaultValue) -> - case lookup_option(Opt,Opts) of - false -> DefaultValue; - Value -> Value - end. - -%% lookup_options(Opt, Opts) -> [Value] -%% Used when the same option can be defined several times and returns -%% the (possibly empty) list of values. -lookup_options(Opt, Opts) -> - [V || {O, V} <- Opts, O == Opt]. - -%% an_option(Opt, Opts) -> bool() -an_option(Opt, Opts) -> - lists:member(Opt, Opts). - -%%--File handling------------------------------------------------------- - -%% outfile(File0, Extension, Opts) -> File -%% Build the full filename for where to place a resulting file. -outfile(File0, Extension, Opts) -> - File = - case regexp:match(File0, "[^/]*\$") of - {match,Start,Length} -> - string:substr(File0, Start, Length); - _ -> - File0 - end, - full_file_name(File, Extension, outdir, Opts). - -%% full_file_name(File, Extension, What, Opts) -> File' -%% File = string() -%% What = outdir | includepath -%% Prepend the full path name. -full_file_name(File, Extension, What, Opts) -> - Path = lookup_option(What, Opts, ""), - full_file_name(File, Extension, Path). - -full_file_name(File0, Extension, Path) -> - File = case filename:extension(File0) of - Extension -> File0; - _ -> File0++Extension - end, - - case File of - [$/|_] -> File; - [$~|_] -> File; - _ when Path=/="" -> filename:join(Path, File); - _ -> File - end. - -%%--Messages to the user------------------------------------------------ - -%% message(Class, Format) -%% message(Class, Format, Values) -> ok -%% Class = info | warning | error -%% Format, Values -- as in io:format/2 -%% Prints a warning or error message. -%% Call as util:message(warning, "~w is undefined", [foo]). -message(Class, Format) -> - message(Class, Format, []). -message(Class, Format, Values) -> - Prefix = case Class of - info -> ""; - warning -> "*** Warning: "; - error -> "*** Error: " - end, - case get(option_silent) of - true when Class==warning -> - ok; - _ -> - io:format(Prefix, []), - io:format(Format, Values), - io:nl() - end. - -%%--String handling----------------------------------------------------- - -%% ltrim(Str) -> Str' -%% rtrim(Str) -> Str' -%% trim(Str) -> Str' -%% Strips whitespace from left, right or both. -ltrim(Str) -> - lists:dropwhile(fun white_space/1, Str). -rtrim(Str) -> - lists:reverse(ltrim(lists:reverse(Str))). -trim(Str) -> - rtrim(ltrim(Str)). - -white_space($ ) -> true; -white_space(C) when C<$ -> true; -white_space($\n) -> true; -white_space($\t) -> true; -white_space(_) -> false. - -%% join(Strings, With) -> string() -join([H1, H2| T], S) -> - H1 ++ S ++ join([H2| T], S); -join([H], _) -> - H; -join([], _) -> - []. - -%%--Other--------------------------------------------------------------- - -%% fknidx(FNdef0, Fn_arity_sep) -> string() -%% Get me the function name and arity. -fknidx(FNdef0, Fn_arity_sep) -> - FNdef = string:strip(FNdef0), - case string:tokens(FNdef,"(") of - [FNdef] -> - %% No parentheses, assume variable: remove nl:s at end, - %% and strip blanks. - string:strip(string:strip(FNdef, right, $\n)); - [Name0|Args0] -> - [Args1|_] = string:tokens(string:strip(hd(Args0)), "-"), - Arity = case Args1 of - [$)|_] -> 0; - _ -> - length(string:tokens(Args1, ",")) - end, - string:strip(Name0)++Fn_arity_sep++integer_to_list(Arity) - end. diff --git a/lib/docbuilder/src/docb_util.hrl b/lib/docbuilder/src/docb_util.hrl deleted file mode 100644 index 01ef3f7fca..0000000000 --- a/lib/docbuilder/src/docb_util.hrl +++ /dev/null @@ -1,34 +0,0 @@ -%% ``The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. -%% Portions created by Ericsson are Copyright 1999-2000, Ericsson -%% Utvecklings AB. All Rights Reserved.'' -%% -%% $Id$ -%% - -%%% For character conversion - --record(in_opts, {expand_entities=false, - encode_filter = fun(X) -> X end}). --record(out_opts, {escape_chars=false, - remove_nl=false, - delete_trailing_whitespace=false, - delete_trailing_nl=false, - compress_white_space=false, - escape_filter = fun(X) -> X end}). - - --define(pcdata_IN, #in_opts{expand_entities=true}). --define(rcdata_IN, #in_opts{expand_entities=true}). --define(cdata_IN, #in_opts{}). - diff --git a/lib/docbuilder/src/docb_xmerl_tree_cb.erl b/lib/docbuilder/src/docb_xmerl_tree_cb.erl deleted file mode 100644 index bc62069230..0000000000 --- a/lib/docbuilder/src/docb_xmerl_tree_cb.erl +++ /dev/null @@ -1,343 +0,0 @@ -%% ``The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See -%% the Licence for the specific language governing rights and limitations -%% under the License. -%% -%% The Initial Developer of the Original Code is Ericsson AB. -%% Portions created by Ericsson are Copyright 1999-2006, Ericsson AB. -%% All Rights Reserved.�� -%% -%% $Id$ -%% --module(docb_xmerl_tree_cb). - -%% This is the XMerL callback module for exporting XML to the internal -%% tree format used by DocBuilder. -%% {Doc, _Misc} = xmerl_scan:file("file.xml", [{validation,true}]) -%% Tree = xmerl:export([Doc], docb_xmerl_tree_cb) - --export(['#xml-inheritance#'/0]). - --export(['#root#'/4, - '#text#'/1, - '#element#'/5]). --include("xmerl.hrl"). - -%%--Functions used by xmerl--------------------------------------------- - -'#xml-inheritance#'() -> - []. - -'#root#'(Data, _Attrs, [], _E) -> - Data. - -'#text#'(Text) -> - Text2 = strip_leading_blanks(Text), -%% before -%% case Text2 of -%% [$\n|T] -> -%% case is_empty(T) of -%% true -> []; -%% false -> {pcdata, [], nl(Text2)} -%% end; -%% -%% _ -> -%% {pcdata, [], nl(Text2)} -%% end. -%% after - {pcdata, [], nl(Text2)}. - -'#element#'(Tag, Data, Attrs, Parents, _E) when Tag==pre; Tag==code -> - [H|T] = reinsert_nl(Data), - NewData = [strip_nl(H)|T], - NewData2 = case Tag of - code -> - fix_single_pcdata(NewData); - pre -> - NewData - end, - {Tag, attrs(get_dtd(Parents), Tag, Attrs), NewData2}; -'#element#'(Tag, Data, Attrs, Parents, _E) -> - NewData = case tag_content(Tag) of - no_pcdata -> % remove all pcdata - [Dat|| - Dat <- Data, - begin - Fun = fun({pcdata,_,_}) -> false; - (_) -> true end, - Fun(Dat) - end]; - single_pcdata when length(Data)>1 -> - %% merge several pcdata's into one single pcdata - fix_single_pcdata(Data); - _ -> - lists:flatten(Data) - end, - {Tag, attrs(get_dtd(Parents), Tag, Attrs), NewData}. - -%%--Internal functions-------------------------------------------------- - -%% is_empty(Str) -> bool() -%% Returns true if the string Str only contains blanks, tabs and -%% newlines, false otherwise. -%% is_empty("\n" ++ Text) -> -%% is_empty(Text); -%% is_empty("\t" ++ Text) -> -%% is_empty(Text); -%% is_empty(" " ++ Text) -> -%% is_empty(Text); -%% is_empty("") -> -%% true; -%% is_empty(_) -> -%% false. - -%% reinsert_nl(L1) -> L2 -%% Workaround for <pre>: Normally empty lines are ignored. However, -%% Xmerl splits lines whenever it encounters an entity. In the case of -%% <pre>, this may lead to that we ignores what we think is an empty -%% line but is actually a line break that should be kept, for example -%% in this case: -%% <pre> -%% <input>some command</input> <-- this line break is lost! -%% <some result> -%% </pre> -%% This function reinserts line breaks where necessary. -reinsert_nl([[]|T]) -> - [{pcdata,[],"\\n"} | reinsert_nl(T)]; -reinsert_nl([H|T]) -> - [H | reinsert_nl(T)]; -reinsert_nl([]) -> - []. - -%% sgmls treats line breaks in a way that DocBuilder relies on and -%% which must be imitated here. Replace all "\n" with "\\n" and add -%% "\n" to the end of each text element. -nl("") -> - "\n"; -nl("\n"++Text) -> - "\\n"++nl(Text); -nl([Ch|Text]) -> - [Ch|nl(Text)]. - - -%% strip_leading_blanks(Str) -> Str -%% Leading spaces and tabs before a newline are always redundant -%% and are therefore stripped of here -%% If no newline is found the original string is returned unchanged - -strip_leading_blanks(Str) -> - strip_leading_blanks(Str,Str). - -strip_leading_blanks([],Str) -> - Str; -strip_leading_blanks([$\s|T],Str) -> - strip_leading_blanks(T,Str); -strip_leading_blanks([$\t|T],Str) -> - strip_leading_blanks(T,Str); -strip_leading_blanks(Rest=[$\n|_],_) -> - Rest; -strip_leading_blanks(_,Str) -> - Str. - -%% strip_nl(Str) -> Str -%% The XMerL scan will often result in the contents of <pre> or <code> -%% starting with a newline, as the format is normally: -%% <pre> -%% ..contents.. -%% </pre> -%% However, this newline must be removed, or the resulting HTML will be -%% <pre> -%% -%% ..content.. -%% </pre> -strip_nl({pcdata,[],"\\n"++Str}) -> {pcdata,[],Str}; -strip_nl(E) -> E. - -get_dtd([]) -> - none; -get_dtd(Parents) -> - {DTD, _} = lists:last(Parents), - DTD. - -%% attrs(DTD, Tag, GivenAttrs) -> AllAttrs -%% DTD = Tag = atom() DTD and tag name -%% GivenAttrs = [#xmlAttribute{}] -%% AllAttrs = [{Name, Type, Val}] -%% Name = string() (uppercase) Example: "VALIGN" -%% Type = "CDATA" | "TOKEN" -%% Val = string() (uppercase if type is "TOKEN", as-is otherwise) -%% The XMerL scanning of <file>.xml renders only the given attributes. -%% However, DocBuilder needs also the optional attributes (which not -%% necessarily have been given), so we add them here, using the default -%% values according to the DTDs. -%% NOTE: Uses the information from the DTDs. That is, if some change is -%% done to the DTDs, also this file must be updated. Ideally, the DTDs -%% should be parsed automatically in some way. -%% It can also be noted that this check is superfluous in the case where -%% all attributes are required (except that the attributes are sorted -%% in the same order as in the DTD) and where an optional attribute has -%% type "CDATA" as no sensible default value can be specified in this -%% case. -attrs(DTD, Tag, GivenAttrs) -> - merge_attrs(Tag, default_attrs(DTD, Tag), GivenAttrs). - -merge_attrs(Tag, [{NameA, Type, DefVal}|Default], GivenAttrs) -> - Val = case lists:keyfind(NameA, #xmlAttribute.name, GivenAttrs) of - #xmlAttribute{value=Val0} -> Val0; - false -> DefVal - end, - Attr = {attr_name(NameA), Type, attr_val(Type, Val)}, - [Attr | merge_attrs(Tag, Default, GivenAttrs)]; -merge_attrs(_Tag, [], _GivenAttrs) -> - []. - -attr_name(Atom) -> - string:to_upper(atom_to_list(Atom)). - -attr_val("CDATA", Val) -> Val; -attr_val("TOKEN", Val) -> string:to_upper(Val). - -%% Given the DTD and element tag, return a list [{Name, Value}] where -%% Name (atom) is the name of each possible attribute and -%% Value (lowercase string) its default value. -default_attrs(_, cell) -> - [{align, "TOKEN", "left"}, - {valign, "TOKEN", "middle"}]; -default_attrs(_, cite) -> - [{id, "CDATA", ""}]; % required -default_attrs(_, code) -> - [{type, "TOKEN", "none"}]; -default_attrs(_, codeinclude) -> - [{file, "CDATA", ""}, % required - {tag, "CDATA", ""}, - {type, "TOKEN", "none"}]; -default_attrs(book, contents) -> - [{level, "TOKEN", "2"}]; -default_attrs(_, erleval) -> - [{expr, "CDATA", ""}]; % required -default_attrs(report, erlinclude) -> - [{file, "CDATA", ""}, % required - {tag, "CDATA", ""}]; % required -default_attrs(_, fascicule) -> - [{file, "CDATA", ""}, % required - {href, "CDATA", ""}, % required - {entry, "TOKEN", "no"}]; -default_attrs(book, header) -> - [{titlestyle, "TOKEN", "normal"}]; -default_attrs(_, image) -> - [{file, "CDATA", ""}]; % required -default_attrs(_, include) -> - [{file, "CDATA", ""}]; % required -default_attrs(report, index) -> - [{txt, "CDATA", ""}]; % required -default_attrs(_, list) -> - [{type, "TOKEN", "bulleted"}]; -default_attrs(_, marker) -> - [{id, "CDATA", ""}]; % required -default_attrs(book, onepart) -> - [{lift, "TOKEN", "no"}]; -default_attrs(book, parts) -> - [{lift, "TOKEN", "no"}]; -default_attrs(_, path) -> - [{unix, "CDATA", ""}, - {windows, "CDATA", ""}]; -default_attrs(_, seealso) -> - [{marker, "CDATA", ""}]; % required -default_attrs(report, table) -> - [{width, "CDATA", "0"}, - {colspec, "CDATA", ""}]; -default_attrs(_, table) -> - [{align, "TOKEN", "center"}]; -default_attrs(_, term) -> - [{id, "CDATA", ""}]; % required -default_attrs(book, theheader) -> - [{tag, "TOKEN", "none"}]; -default_attrs(bookinsidecover, theheader) -> - [{tag, "TOKEN", "none"}]; -default_attrs(_, url) -> - [{href, "CDATA", ""}]; % required -default_attrs(_, _) -> []. - -%%--Single PCDATA broken into several fix------------------------------- - -%% When text contains an entity, then XMERL splits it into two -%% PCDATA elements, the second starting with the entity. -%% -%% Example: -%% Magnus Fr�berg => [{pcdata,[],"Magnus Fr\n"},{pcdata,[],"�berg\n"}] -%% -%% This is not handled by DocBuilder which expects many tags, for -%% example title and aname, to contain a single PCDATA element. (That -%% is also what nsgmls returned.) - -fix_single_pcdata([{pcdata,[],Str1}, {pcdata,[],Str2}|T]) -> - fix_single_pcdata([{pcdata,[],Str1++Str2}|T]); -fix_single_pcdata(FixedData) -> - FixedData. - -tag_content(aname) -> single_pcdata; -tag_content(app) -> single_pcdata; -tag_content(approved) -> single_pcdata; -tag_content(appsummary) -> single_pcdata; -tag_content(b) -> single_pcdata; -tag_content(c) -> single_pcdata; -tag_content(cauthor) -> single_pcdata; -tag_content(cell) -> mixed_content; -tag_content(checked) -> single_pcdata; -tag_content(chowpublished) -> single_pcdata; -tag_content(code) -> single_pcdata; % mixed? -tag_content(com) -> single_pcdata; -tag_content(comsummary) -> single_pcdata; -tag_content(copyright) -> mixed_content; -tag_content(ctitle) -> single_pcdata; -tag_content(d) -> mixed_content; -tag_content(date) -> single_pcdata; -tag_content(docno) -> single_pcdata; -tag_content(em) -> mixed_content; -tag_content(email) -> single_pcdata; -tag_content(fascicule) -> single_pcdata; -tag_content(file) -> single_pcdata; -tag_content(filesummary) -> single_pcdata; -tag_content(fsummary) -> mixed_content; -tag_content(headline) -> single_pcdata; -tag_content(holder) -> single_pcdata; -tag_content(i) -> single_pcdata; -tag_content(icaption) -> single_pcdata; -tag_content(id) -> single_pcdata; -tag_content(input) -> mixed_content; -tag_content(item) -> mixed_content; -tag_content(legalnotice) -> single_pcdata; -tag_content(lib) -> single_pcdata; -tag_content(libsummary) -> single_pcdata; -tag_content(module) -> single_pcdata; -tag_content(modulesummary) -> single_pcdata; -tag_content(name) -> single_pcdata; -tag_content(nametext) -> single_pcdata; -tag_content(p) -> mixed_content; -tag_content(pagetext) -> single_pcdata; -tag_content(path) -> single_pcdata; % mixed? -tag_content(pre) -> mixed_content; -tag_content(prepared) -> single_pcdata; -tag_content(resp) -> single_pcdata; -tag_content(responsible) -> single_pcdata; -tag_content(ret) -> single_pcdata; -tag_content(rev) -> single_pcdata; -tag_content(seealso) -> single_pcdata; % mixed? -tag_content(shortdef) -> single_pcdata; -tag_content(shorttitle) -> single_pcdata; -tag_content(tag) -> mixed_content; -tag_content(tcaption) -> single_pcdata; -tag_content(termdef) -> single_pcdata; -tag_content(title) -> single_pcdata; -tag_content(url) -> single_pcdata; % mixed -tag_content(v) -> single_pcdata; -tag_content(year) -> single_pcdata; -tag_content(_) -> no_pcdata. - - diff --git a/lib/docbuilder/src/docbuilder.app.src b/lib/docbuilder/src/docbuilder.app.src deleted file mode 100644 index 64c4770964..0000000000 --- a/lib/docbuilder/src/docbuilder.app.src +++ /dev/null @@ -1,37 +0,0 @@ -{application, docbuilder, - [{description, "Tool for building HTML documentation"}, - {vsn, "%VSN%"}, - {modules, [docb_edoc_xml_cb, - docb_gen, - docb_html, - docb_html_layout, - docb_html_ref, - docb_html_util, - docb_html_util_iso, - docb_main, - docb_pretty_format, - docb_tr_application2html, - docb_tr_appref2html, - docb_tr_chapter2html, - docb_tr_cite2html, - docb_tr_comref2html, - docb_tr_cref2html, - docb_tr_erlref2html, - docb_tr_fileref2html, - docb_tr_first2html, - docb_tr_index2html, - docb_tr_part2html, - docb_tr_refs2kwic, - docb_tr_report2html, - docb_tr_term2html, - docb_transform, - docb_util, - docb_xmerl_tree_cb, - docb_xmerl_xml_cb, - docb_xml_check - ]}, - {registered, []}, - {applications, [kernel, stdlib]}, - {env, []}]}. - - diff --git a/lib/docbuilder/src/docbuilder.appup.src b/lib/docbuilder/src/docbuilder.appup.src deleted file mode 100644 index 54a63833e6..0000000000 --- a/lib/docbuilder/src/docbuilder.appup.src +++ /dev/null @@ -1 +0,0 @@ -{"%VSN%",[],[]}. diff --git a/lib/docbuilder/test/Makefile b/lib/docbuilder/test/Makefile deleted file mode 100644 index 53dff193dc..0000000000 --- a/lib/docbuilder/test/Makefile +++ /dev/null @@ -1,80 +0,0 @@ -# ``The contents of this file are subject to the Erlang Public License, -# Version 1.1, (the "License"); you may not use this file except in -# compliance with the License. You should have received a copy of the -# Erlang Public License along with this software. If not, it can be -# retrieved via the world wide web at http://www.erlang.org/. -# -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -# the License for the specific language governing rights and limitations -# under the License. -# -# The Initial Developer of the Original Code is Ericsson Utvecklings AB. -# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings -# AB. All Rights Reserved.'' -# -# $Id$ -# -include $(ERL_TOP)/make/target.mk -include $(ERL_TOP)/make/$(TARGET)/otp.mk - -MODULES = \ - docb_SUITE - -ERL_FILES= $(MODULES:%=%.erl) - -TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) -INSTALL_PROGS= $(TARGET_FILES) - -EMAKEFILE=Emakefile - -SPEC_FILES= - -# ---------------------------------------------------- -# Release directory specification -# ---------------------------------------------------- -RELSYSDIR = $(RELEASE_PATH)/docb_test - -# ---------------------------------------------------- -# FLAGS -# ---------------------------------------------------- -ERL_MAKE_FLAGS += -ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include - -EBIN = . - -# ---------------------------------------------------- -# Targets -# ---------------------------------------------------- -.PHONY: make_emakefile - -make_emakefile: - $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES)\ - > $(EMAKEFILE) - -tests debug opt: make_emakefile - erl $(ERL_MAKE_FLAGS) -make - -clean: - rm -f $(EMAKEFILE) - rm -f $(TARGET_FILES) - rm -f core - -docs: - -# ---------------------------------------------------- -# Release Target -# ---------------------------------------------------- -include $(ERL_TOP)/make/otp_release_targets.mk - -release_spec: opt - -release_tests_spec: make_emakefile - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) $(SPEC_FILES) docb.cover $(EMAKEFILE) $(ERL_FILES) $(RELSYSDIR) - chmod -R u+w $(RELSYSDIR) - @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) - -release_docs_spec: - - diff --git a/lib/docbuilder/test/docb.cover b/lib/docbuilder/test/docb.cover deleted file mode 100644 index 80bab6eba7..0000000000 --- a/lib/docbuilder/test/docb.cover +++ /dev/null @@ -1,2 +0,0 @@ -{incl_app,docbuilder,details} - diff --git a/lib/docbuilder/test/docb_SUITE_data/cdata_problem.xml b/lib/docbuilder/test/docb_SUITE_data/cdata_problem.xml deleted file mode 100644 index b7f6f5376e..0000000000 --- a/lib/docbuilder/test/docb_SUITE_data/cdata_problem.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="latin1" ?> -<!DOCTYPE chapter SYSTEM "chapter.dtd"> -<chapter> - <header> - <title>�Docbookö bug</title> - <prepared>Matthias Lang</prepared> -<docno></docno> -<date>2008-03-31</date> - <rev>1.0</rev> - </header> - -<section><title>This is a title</title> - <code><![CDATA[ - This works - ]]></code> - - <code><![CDATA[ - This does not - ]]> </code> -</section> -</chapter> - diff --git a/lib/docbuilder/vsn.mk b/lib/docbuilder/vsn.mk deleted file mode 100644 index 6df438a537..0000000000 --- a/lib/docbuilder/vsn.mk +++ /dev/null @@ -1 +0,0 @@ -DOCB_VSN = 0.9.8.11 diff --git a/lib/docbuilder/xsd/application.xsd b/lib/docbuilder/xsd/application.xsd deleted file mode 100644 index eb666cb6c7..0000000000 --- a/lib/docbuilder/xsd/application.xsd +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
- <xs:include schemaLocation="common.xsd"/>
- <xs:include schemaLocation="common.header.xsd"/>
- <xs:element name="application">
- <xs:complexType>
- <xs:sequence>
- <xs:element ref="header"/>
- <xs:element minOccurs="0" ref="description"/>
- <xs:element maxOccurs="unbounded" ref="include"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="description">
- <xs:complexType>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="block"/>
- <xs:element ref="quote"/>
- <xs:element ref="br"/>
- <xs:element ref="marker"/>
- <xs:element ref="warning"/>
- <xs:element ref="note"/>
- </xs:choice>
- </xs:complexType>
- </xs:element>
- <xs:element name="include">
- <xs:complexType>
- <xs:attribute name="file" use="required"/>
- </xs:complexType>
- </xs:element>
-</xs:schema>
diff --git a/lib/docbuilder/xsd/appref.xsd b/lib/docbuilder/xsd/appref.xsd deleted file mode 100644 index b63839e494..0000000000 --- a/lib/docbuilder/xsd/appref.xsd +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
- <xs:include schemaLocation="common.refs.xsd"/>
- <!-- Structure -->
- <xs:element name="appref">
- <xs:complexType>
- <xs:sequence>
- <xs:element ref="header"/>
- <xs:element ref="app"/>
- <xs:element ref="appsummary"/>
- <xs:element ref="description"/>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="section"/>
- <xs:element ref="funcs"/>
- </xs:choice>
- <xs:element ref="authors"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="app" type="xs:string"/>
- <xs:element name="appsummary" type="xs:string"/>
- <!--
- `name' is used in common.refs.dtd and must therefore
- be defined in each *ref. dtd
- -->
- <xs:element name="name" type="xs:string"/>
-</xs:schema>
diff --git a/lib/docbuilder/xsd/book.xsd b/lib/docbuilder/xsd/book.xsd deleted file mode 100644 index b47962263a..0000000000 --- a/lib/docbuilder/xsd/book.xsd +++ /dev/null @@ -1,292 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
- <xs:include schemaLocation="common.xsd"/>
- <xs:include schemaLocation="common.table.xsd"/>
- <xs:element name="book">
- <xs:complexType>
- <xs:sequence>
- <xs:element ref="header"/>
- <xs:element minOccurs="0" ref="insidecover"/>
- <xs:element ref="pagetext"/>
- <xs:element ref="preamble"/>
- <xs:choice maxOccurs="unbounded">
- <xs:element ref="applications"/>
- <xs:element ref="parts"/>
- <xs:element ref="headline"/>
- <xs:element ref="pagetext"/>
- </xs:choice>
- <xs:sequence>
- <xs:element minOccurs="0" ref="listoffigures"/>
- <xs:element minOccurs="0" ref="listoftables"/>
- <xs:element minOccurs="0" ref="listofterms"/>
- <xs:element minOccurs="0" ref="bibliography"/>
- <xs:element minOccurs="0" ref="index"/>
- </xs:sequence>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="header">
- <xs:complexType>
- <xs:sequence>
- <xs:element ref="title"/>
- <xs:element ref="prepared"/>
- <xs:element minOccurs="0" ref="responsible"/>
- <xs:element ref="docno"/>
- <xs:element minOccurs="0" ref="approved"/>
- <xs:element minOccurs="0" ref="checked"/>
- <xs:element ref="date"/>
- <xs:element ref="rev"/>
- <xs:element minOccurs="0" ref="file"/>
- <xs:element minOccurs="0" ref="abbreviation"/>
- </xs:sequence>
- <xs:attribute name="titlestyle" default="normal">
- <xs:simpleType>
- <xs:restriction base="xs:token">
- <xs:enumeration value="special"/>
- <xs:enumeration value="normal"/>
- </xs:restriction>
- </xs:simpleType>
- </xs:attribute>
- </xs:complexType>
- </xs:element>
- <xs:element name="title">
- <xs:complexType mixed="true">
- <xs:sequence>
- <xs:element minOccurs="0" maxOccurs="unbounded" ref="br"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="prepared">
- <xs:complexType mixed="true">
- <xs:sequence>
- <xs:element minOccurs="0" maxOccurs="unbounded" ref="br"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="responsible">
- <xs:complexType mixed="true">
- <xs:sequence>
- <xs:element minOccurs="0" maxOccurs="unbounded" ref="br"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="docno">
- <xs:complexType mixed="true">
- <xs:sequence>
- <xs:element minOccurs="0" maxOccurs="unbounded" ref="br"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="approved">
- <xs:complexType mixed="true">
- <xs:sequence>
- <xs:element minOccurs="0" maxOccurs="unbounded" ref="br"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="checked">
- <xs:complexType mixed="true">
- <xs:sequence>
- <xs:element minOccurs="0" maxOccurs="unbounded" ref="br"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="date">
- <xs:complexType mixed="true">
- <xs:sequence>
- <xs:element minOccurs="0" maxOccurs="unbounded" ref="br"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="rev">
- <xs:complexType mixed="true">
- <xs:sequence>
- <xs:element minOccurs="0" maxOccurs="unbounded" ref="br"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="file">
- <xs:complexType mixed="true">
- <xs:sequence>
- <xs:element minOccurs="0" maxOccurs="unbounded" ref="br"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="abbreviation">
- <xs:complexType mixed="true">
- <xs:sequence>
- <xs:element minOccurs="0" maxOccurs="unbounded" ref="br"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="pagetext" type="xs:string"/>
- <xs:element name="preamble">
- <xs:complexType>
- <xs:sequence>
- <xs:element minOccurs="0" ref="preface"/>
- <xs:element minOccurs="0" ref="contents"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="preface">
- <xs:complexType>
- <xs:sequence>
- <xs:element minOccurs="0" ref="title"/>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="block"/>
- <xs:element ref="quote"/>
- <xs:element ref="br"/>
- <xs:element ref="marker"/>
- <xs:element ref="warning"/>
- <xs:element ref="note"/>
- <xs:element ref="table"/>
- </xs:choice>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="insidecover">
- <xs:complexType mixed="true">
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="br"/>
- <xs:element ref="theheader"/>
- <xs:element ref="vfill"/>
- <xs:element ref="tt"/>
- <xs:element ref="bold"/>
- <xs:element ref="include"/>
- </xs:choice>
- </xs:complexType>
- </xs:element>
- <xs:element name="tt">
- <xs:complexType mixed="true">
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="br"/>
- <xs:element ref="theheader"/>
- <xs:element ref="vfill"/>
- </xs:choice>
- </xs:complexType>
- </xs:element>
- <xs:element name="bold">
- <xs:complexType mixed="true">
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="br"/>
- <xs:element ref="theheader"/>
- <xs:element ref="vfill"/>
- </xs:choice>
- </xs:complexType>
- </xs:element>
- <xs:element name="vfill">
- <xs:complexType/>
- </xs:element>
- <xs:element name="theheader">
- <xs:complexType>
- <xs:attribute name="tag" default="none">
- <xs:simpleType>
- <xs:restriction base="xs:token">
- <xs:enumeration value="title"/>
- <xs:enumeration value="prepared"/>
- <xs:enumeration value="responsible"/>
- <xs:enumeration value="docno"/>
- <xs:enumeration value="approved"/>
- <xs:enumeration value="checked"/>
- <xs:enumeration value="date"/>
- <xs:enumeration value="rev"/>
- <xs:enumeration value="file"/>
- <xs:enumeration value="abbreviation"/>
- <xs:enumeration value="none"/>
- </xs:restriction>
- </xs:simpleType>
- </xs:attribute>
- </xs:complexType>
- </xs:element>
- <xs:element name="applications">
- <xs:complexType>
- <xs:sequence>
- <xs:element minOccurs="0" maxOccurs="unbounded" ref="include"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="parts">
- <xs:complexType>
- <xs:sequence>
- <xs:element minOccurs="0" ref="title"/>
- <xs:element minOccurs="0" ref="description"/>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="include"/>
- <xs:element ref="onepart"/>
- </xs:choice>
- </xs:sequence>
- <xs:attribute name="lift" default="no">
- <xs:simpleType>
- <xs:restriction base="xs:token">
- <xs:enumeration value="yes"/>
- <xs:enumeration value="no"/>
- </xs:restriction>
- </xs:simpleType>
- </xs:attribute>
- </xs:complexType>
- </xs:element>
- <xs:element name="headline" type="xs:string"/>
- <xs:element name="index">
- <xs:complexType/>
- </xs:element>
- <xs:element name="listoffigures">
- <xs:complexType/>
- </xs:element>
- <xs:element name="listoftables">
- <xs:complexType/>
- </xs:element>
- <xs:element name="listofterms">
- <xs:complexType/>
- </xs:element>
- <xs:element name="bibliography">
- <xs:complexType/>
- </xs:element>
- <xs:element name="contents">
- <xs:complexType>
- <xs:attribute name="level" default="2">
- <xs:simpleType>
- <xs:restriction base="xs:token">
- <xs:enumeration value="0"/>
- <xs:enumeration value="1"/>
- <xs:enumeration value="2"/>
- <xs:enumeration value="3"/>
- </xs:restriction>
- </xs:simpleType>
- </xs:attribute>
- </xs:complexType>
- </xs:element>
- <xs:element name="onepart">
- <xs:complexType>
- <xs:sequence>
- <xs:element minOccurs="0" ref="title"/>
- <xs:element minOccurs="0" ref="description"/>
- <xs:element maxOccurs="unbounded" ref="include"/>
- </xs:sequence>
- <xs:attribute name="lift" default="no">
- <xs:simpleType>
- <xs:restriction base="xs:token">
- <xs:enumeration value="yes"/>
- <xs:enumeration value="no"/>
- </xs:restriction>
- </xs:simpleType>
- </xs:attribute>
- </xs:complexType>
- </xs:element>
- <xs:element name="description">
- <xs:complexType>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="block"/>
- <xs:element ref="quote"/>
- <xs:element ref="br"/>
- <xs:element ref="marker"/>
- <xs:element ref="warning"/>
- <xs:element ref="note"/>
- </xs:choice>
- </xs:complexType>
- </xs:element>
- <xs:element name="include">
- <xs:complexType>
- <xs:attribute name="file" use="required"/>
- </xs:complexType>
- </xs:element>
-</xs:schema>
diff --git a/lib/docbuilder/xsd/chapter.xsd b/lib/docbuilder/xsd/chapter.xsd deleted file mode 100644 index 4d89baa988..0000000000 --- a/lib/docbuilder/xsd/chapter.xsd +++ /dev/null @@ -1,45 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
- <xs:include schemaLocation="common.xsd"/>
- <xs:include schemaLocation="common.header.xsd"/>
- <xs:include schemaLocation="common.table.xsd"/>
- <xs:include schemaLocation="common.image.xsd"/>
- <!-- Structure -->
- <xs:element name="chapter">
- <xs:complexType>
- <xs:sequence>
- <xs:element ref="header"/>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="block"/>
- <xs:element ref="quote"/>
- <xs:element ref="warning"/>
- <xs:element ref="note"/>
- <xs:element ref="br"/>
- <xs:element ref="image"/>
- <xs:element ref="marker"/>
- <xs:element ref="table"/>
- </xs:choice>
- <xs:element maxOccurs="unbounded" ref="section"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="section">
- <xs:complexType>
- <xs:sequence>
- <xs:element minOccurs="0" maxOccurs="unbounded" ref="marker"/>
- <xs:element ref="title"/>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="block"/>
- <xs:element ref="quote"/>
- <xs:element ref="warning"/>
- <xs:element ref="note"/>
- <xs:element ref="br"/>
- <xs:element ref="image"/>
- <xs:element ref="marker"/>
- <xs:element ref="table"/>
- <xs:element ref="section"/>
- </xs:choice>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
-</xs:schema>
diff --git a/lib/docbuilder/xsd/common.entities.xsd b/lib/docbuilder/xsd/common.entities.xsd deleted file mode 100644 index 52a5d35179..0000000000 --- a/lib/docbuilder/xsd/common.entities.xsd +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"/>
diff --git a/lib/docbuilder/xsd/common.header.xsd b/lib/docbuilder/xsd/common.header.xsd deleted file mode 100644 index bfee4b8bb4..0000000000 --- a/lib/docbuilder/xsd/common.header.xsd +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
- <xs:element name="header">
- <xs:complexType>
- <xs:sequence>
- <xs:element ref="title"/>
- <xs:element minOccurs="0" ref="shorttitle"/>
- <xs:element ref="prepared"/>
- <xs:element minOccurs="0" ref="responsible"/>
- <xs:element ref="docno"/>
- <xs:element minOccurs="0" ref="approved"/>
- <xs:element minOccurs="0" ref="checked"/>
- <xs:element ref="date"/>
- <xs:element ref="rev"/>
- <xs:element minOccurs="0" ref="file"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="title" type="xs:string"/>
- <xs:element name="shorttitle" type="xs:string"/>
- <xs:element name="prepared" type="xs:string"/>
- <xs:element name="responsible" type="xs:string"/>
- <xs:element name="docno" type="xs:string"/>
- <xs:element name="approved" type="xs:string"/>
- <xs:element name="checked" type="xs:string"/>
- <xs:element name="date" type="xs:string"/>
- <xs:element name="rev" type="xs:string"/>
- <xs:element name="file" type="xs:string"/>
-</xs:schema>
diff --git a/lib/docbuilder/xsd/common.image.xsd b/lib/docbuilder/xsd/common.image.xsd deleted file mode 100644 index 17054eb23c..0000000000 --- a/lib/docbuilder/xsd/common.image.xsd +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
- <xs:element name="image">
- <xs:complexType>
- <xs:complexContent>
- <xs:extension base="icaption">
- <xs:attribute name="file" use="required"/>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
- </xs:element>
- <xs:complexType name="icaption">
- <xs:sequence>
- <xs:element ref="icaption"/>
- </xs:sequence>
- </xs:complexType>
- <xs:element name="icaption" type="xs:string"/>
-</xs:schema>
diff --git a/lib/docbuilder/xsd/common.refs.xsd b/lib/docbuilder/xsd/common.refs.xsd deleted file mode 100644 index 58b450669d..0000000000 --- a/lib/docbuilder/xsd/common.refs.xsd +++ /dev/null @@ -1,102 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<!--
- This file contains common stuff for the *ref.dtd files.
- Note that `name' is defined in each *ref.dtd.
--->
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
- <xs:include schemaLocation="common.xsd"/>
- <xs:include schemaLocation="common.header.xsd"/>
- <xs:element name="description">
- <xs:complexType>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="block"/>
- <xs:element ref="quote"/>
- <xs:element ref="br"/>
- <xs:element ref="marker"/>
- <xs:element ref="warning"/>
- <xs:element ref="note"/>
- </xs:choice>
- </xs:complexType>
- </xs:element>
- <xs:element name="funcs">
- <xs:complexType>
- <xs:sequence>
- <xs:element maxOccurs="unbounded" ref="func"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="func">
- <xs:complexType>
- <xs:sequence>
- <xs:element maxOccurs="unbounded" ref="name"/>
- <xs:element ref="fsummary"/>
- <xs:element minOccurs="0" ref="type"/>
- <xs:element minOccurs="0" ref="desc"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <!-- ELEMENT name is defined in each ref dtd -->
- <xs:element name="fsummary">
- <xs:complexType mixed="true">
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="c"/>
- <xs:element ref="em"/>
- </xs:choice>
- </xs:complexType>
- </xs:element>
- <xs:element name="type">
- <xs:complexType>
- <xs:sequence maxOccurs="unbounded">
- <xs:element ref="v"/>
- <xs:element minOccurs="0" ref="d"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="v" type="xs:string"/>
- <xs:element name="d">
- <xs:complexType mixed="true">
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="c"/>
- <xs:element ref="em"/>
- </xs:choice>
- </xs:complexType>
- </xs:element>
- <xs:element name="desc">
- <xs:complexType>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="block"/>
- <xs:element ref="quote"/>
- <xs:element ref="br"/>
- <xs:element ref="marker"/>
- <xs:element ref="warning"/>
- <xs:element ref="note"/>
- </xs:choice>
- </xs:complexType>
- </xs:element>
- <xs:element name="authors">
- <xs:complexType>
- <xs:sequence maxOccurs="unbounded">
- <xs:element ref="aname"/>
- <xs:element ref="email"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="aname" type="xs:string"/>
- <xs:element name="email" type="xs:string"/>
- <xs:element name="section">
- <xs:complexType>
- <xs:sequence>
- <xs:element minOccurs="0" maxOccurs="unbounded" ref="marker"/>
- <xs:element ref="title"/>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="block"/>
- <xs:element ref="quote"/>
- <xs:element ref="br"/>
- <xs:element ref="marker"/>
- <xs:element ref="warning"/>
- <xs:element ref="note"/>
- </xs:choice>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
-</xs:schema>
diff --git a/lib/docbuilder/xsd/common.table.xsd b/lib/docbuilder/xsd/common.table.xsd deleted file mode 100644 index cf63df4317..0000000000 --- a/lib/docbuilder/xsd/common.table.xsd +++ /dev/null @@ -1,42 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
- <xs:element name="table">
- <xs:complexType>
- <xs:sequence>
- <xs:element maxOccurs="unbounded" ref="row"/>
- <xs:element ref="tcaption"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="row">
- <xs:complexType>
- <xs:sequence>
- <xs:element maxOccurs="unbounded" ref="cell"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="cell">
- <xs:complexType mixed="true">
- <xs:group minOccurs="0" maxOccurs="unbounded" ref="inline"/>
- <xs:attribute name="align" default="left">
- <xs:simpleType>
- <xs:restriction base="xs:token">
- <xs:enumeration value="left"/>
- <xs:enumeration value="center"/>
- <xs:enumeration value="right"/>
- </xs:restriction>
- </xs:simpleType>
- </xs:attribute>
- <xs:attribute name="valign" default="middle">
- <xs:simpleType>
- <xs:restriction base="xs:token">
- <xs:enumeration value="top"/>
- <xs:enumeration value="middle"/>
- <xs:enumeration value="bottom"/>
- </xs:restriction>
- </xs:simpleType>
- </xs:attribute>
- </xs:complexType>
- </xs:element>
- <xs:element name="tcaption" type="xs:string"/>
-</xs:schema>
diff --git a/lib/docbuilder/xsd/common.xsd b/lib/docbuilder/xsd/common.xsd deleted file mode 100644 index 3d43390bd8..0000000000 --- a/lib/docbuilder/xsd/common.xsd +++ /dev/null @@ -1,212 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<!-- This file contains common stuff for all dtds. -->
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
- <xs:element name="block" abstract="true"/>
- <xs:group name="inline">
- <xs:sequence>
- <xs:choice minOccurs="0">
- <xs:element ref="c"/>
- <xs:element ref="em"/>
- <xs:element ref="term"/>
- <xs:element ref="cite"/>
- <xs:element ref="br"/>
- <xs:element ref="path"/>
- <xs:element ref="seealso"/>
- <xs:element ref="url"/>
- <xs:element ref="marker"/>
- </xs:choice>
- </xs:sequence>
- </xs:group>
- <!-- XXX -->
- <xs:element name="p" substitutionGroup="block">
- <xs:complexType mixed="true">
- <xs:group minOccurs="0" maxOccurs="unbounded" ref="inline"/>
- </xs:complexType>
- </xs:element>
- <xs:element name="pre" substitutionGroup="block">
- <xs:complexType mixed="true">
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="seealso"/>
- <xs:element ref="url"/>
- <xs:element ref="input"/>
- </xs:choice>
- </xs:complexType>
- </xs:element>
- <xs:element name="input">
- <xs:complexType mixed="true">
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="seealso"/>
- <xs:element ref="url"/>
- </xs:choice>
- </xs:complexType>
- </xs:element>
- <xs:element name="code" substitutionGroup="block">
- <xs:complexType mixed="true">
- <xs:attribute name="type" default="none">
- <xs:simpleType>
- <xs:restriction base="xs:token">
- <xs:enumeration value="erl"/>
- <xs:enumeration value="c"/>
- <xs:enumeration value="none"/>
- </xs:restriction>
- </xs:simpleType>
- </xs:attribute>
- </xs:complexType>
- </xs:element>
- <xs:element name="quote">
- <xs:complexType>
- <xs:sequence>
- <xs:element minOccurs="0" maxOccurs="unbounded" ref="p"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="warning">
- <xs:complexType>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="block"/>
- <xs:element ref="quote"/>
- <xs:element ref="br"/>
- <xs:element ref="marker"/>
- </xs:choice>
- </xs:complexType>
- </xs:element>
- <xs:element name="note">
- <xs:complexType>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="block"/>
- <xs:element ref="quote"/>
- <xs:element ref="br"/>
- <xs:element ref="marker"/>
- </xs:choice>
- </xs:complexType>
- </xs:element>
- <xs:element name="c" type="xs:string"/>
- <xs:element name="em">
- <xs:complexType mixed="true">
- <xs:sequence>
- <xs:element minOccurs="0" maxOccurs="unbounded" ref="c"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <!-- XXX -->
- <xs:element name="term">
- <xs:complexType>
- <xs:sequence>
- <xs:element minOccurs="0" ref="termdef"/>
- </xs:sequence>
- <xs:attribute name="id" use="required"/>
- </xs:complexType>
- </xs:element>
- <xs:element name="termdef" type="xs:string"/>
- <xs:element name="cite">
- <xs:complexType>
- <xs:sequence>
- <xs:element minOccurs="0" ref="citedef"/>
- </xs:sequence>
- <xs:attribute name="id" use="required"/>
- </xs:complexType>
- </xs:element>
- <xs:element name="citedef">
- <xs:complexType>
- <xs:sequence>
- <xs:element ref="ctitle"/>
- <xs:element ref="cauthor"/>
- <xs:element ref="chowpublished"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="ctitle" type="xs:string"/>
- <xs:element name="cauthor" type="xs:string"/>
- <xs:element name="chowpublished" type="xs:string"/>
- <!-- XXX -->
- <xs:element name="br">
- <xs:complexType/>
- </xs:element>
- <!-- Path -->
- <xs:element name="path">
- <xs:complexType mixed="true">
- <xs:attribute name="unix" default=""/>
- <xs:attribute name="windows" default=""/>
- </xs:complexType>
- </xs:element>
- <!-- List -->
- <xs:element name="list" substitutionGroup="block">
- <xs:complexType>
- <xs:sequence>
- <xs:element maxOccurs="unbounded" ref="item"/>
- </xs:sequence>
- <xs:attribute name="type" default="bulleted">
- <xs:simpleType>
- <xs:restriction base="xs:token">
- <xs:enumeration value="ordered"/>
- <xs:enumeration value="bulleted"/>
- </xs:restriction>
- </xs:simpleType>
- </xs:attribute>
- </xs:complexType>
- </xs:element>
- <xs:element name="taglist" substitutionGroup="block">
- <xs:complexType>
- <xs:sequence maxOccurs="unbounded">
- <xs:element ref="tag"/>
- <xs:element ref="item"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="tag">
- <xs:complexType mixed="true">
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="c"/>
- <xs:element ref="em"/>
- <xs:element ref="seealso"/>
- <xs:element ref="url"/>
- </xs:choice>
- </xs:complexType>
- </xs:element>
- <xs:element name="item">
- <xs:complexType mixed="true">
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:group ref="inline"/>
- <xs:element ref="block"/>
- </xs:choice>
- </xs:complexType>
- </xs:element>
- <!-- References -->
- <xs:element name="seealso">
- <xs:complexType mixed="true">
- <xs:attribute name="marker" use="required"/>
- </xs:complexType>
- </xs:element>
- <xs:element name="url">
- <xs:complexType mixed="true">
- <xs:attribute name="href" use="required"/>
- </xs:complexType>
- </xs:element>
- <xs:element name="marker">
- <xs:complexType>
- <xs:attribute name="id" use="required"/>
- </xs:complexType>
- </xs:element>
- <!-- CodeInclude -->
- <xs:element name="codeinclude" substitutionGroup="block">
- <xs:complexType>
- <xs:attribute name="file" use="required"/>
- <xs:attribute name="tag" default=""/>
- <xs:attribute name="type" default="none">
- <xs:simpleType>
- <xs:restriction base="xs:token">
- <xs:enumeration value="erl"/>
- <xs:enumeration value="c"/>
- <xs:enumeration value="none"/>
- </xs:restriction>
- </xs:simpleType>
- </xs:attribute>
- </xs:complexType>
- </xs:element>
- <!-- ErlEval -->
- <xs:element name="erleval" substitutionGroup="block">
- <xs:complexType>
- <xs:attribute name="expr" use="required"/>
- </xs:complexType>
- </xs:element>
-</xs:schema>
diff --git a/lib/docbuilder/xsd/comref.xsd b/lib/docbuilder/xsd/comref.xsd deleted file mode 100644 index 61df4dd848..0000000000 --- a/lib/docbuilder/xsd/comref.xsd +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
- <xs:include schemaLocation="common.refs.xsd"/>
- <xs:element name="comref">
- <xs:complexType>
- <xs:sequence>
- <xs:element ref="header"/>
- <xs:element ref="com"/>
- <xs:element ref="comsummary"/>
- <xs:element ref="description"/>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="section"/>
- <xs:element ref="funcs"/>
- </xs:choice>
- <xs:element ref="authors"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="com" type="xs:string"/>
- <xs:element name="comsummary" type="xs:string"/>
- <!--
- `name' is used in common.refs.dtd and must therefore
- be defined in each *ref. dtd
- -->
- <xs:element name="name" type="xs:string"/>
-</xs:schema>
diff --git a/lib/docbuilder/xsd/cref.xsd b/lib/docbuilder/xsd/cref.xsd deleted file mode 100644 index f1cbeddfff..0000000000 --- a/lib/docbuilder/xsd/cref.xsd +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
- <xs:include schemaLocation="common.refs.xsd"/>
- <xs:element name="cref">
- <xs:complexType>
- <xs:sequence>
- <xs:element ref="header"/>
- <xs:element ref="lib"/>
- <xs:element ref="libsummary"/>
- <xs:element ref="description"/>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="section"/>
- <xs:element ref="funcs"/>
- </xs:choice>
- <xs:element ref="authors"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="lib" type="xs:string"/>
- <xs:element name="libsummary" type="xs:string"/>
- <!--
- `name' is used in common.refs.dtd and must therefore
- be defined in each *ref. dtd
- -->
- <xs:element name="name">
- <xs:complexType>
- <xs:sequence>
- <xs:element ref="ret"/>
- <xs:element ref="nametext"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="ret" type="xs:string"/>
- <xs:element name="nametext" type="xs:string"/>
-</xs:schema>
diff --git a/lib/docbuilder/xsd/erlref.xsd b/lib/docbuilder/xsd/erlref.xsd deleted file mode 100644 index f6011b7bea..0000000000 --- a/lib/docbuilder/xsd/erlref.xsd +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
- <xs:include schemaLocation="common.refs.xsd"/>
- <xs:element name="erlref">
- <xs:complexType>
- <xs:sequence>
- <xs:element ref="header"/>
- <xs:element ref="module"/>
- <xs:element ref="modulesummary"/>
- <xs:element ref="description"/>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="section"/>
- <xs:element ref="funcs"/>
- </xs:choice>
- <xs:element ref="authors"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="module" type="xs:string"/>
- <xs:element name="modulesummary" type="xs:string"/>
- <!--
- `name' is used in common.refs.dtd and must therefore
- be defined in each *ref. dtd
- -->
- <xs:element name="name" type="xs:string"/>
-</xs:schema>
diff --git a/lib/docbuilder/xsd/fascicules.xsd b/lib/docbuilder/xsd/fascicules.xsd deleted file mode 100644 index bfdb5bd604..0000000000 --- a/lib/docbuilder/xsd/fascicules.xsd +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?>
-<!-- Structure -->
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
- <xs:element name="fascicules">
- <xs:complexType>
- <xs:sequence>
- <xs:element maxOccurs="unbounded" ref="fascicule"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="fascicule">
- <xs:complexType mixed="true">
- <xs:attribute name="file" use="required"/>
- <xs:attribute name="href" use="required"/>
- <xs:attribute name="entry" default="no">
- <xs:simpleType>
- <xs:restriction base="xs:token">
- <xs:enumeration value="yes"/>
- <xs:enumeration value="no"/>
- </xs:restriction>
- </xs:simpleType>
- </xs:attribute>
- </xs:complexType>
- </xs:element>
-</xs:schema>
diff --git a/lib/docbuilder/xsd/fileref.xsd b/lib/docbuilder/xsd/fileref.xsd deleted file mode 100644 index 8038f2115f..0000000000 --- a/lib/docbuilder/xsd/fileref.xsd +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
- <xs:include schemaLocation="common.refs.xsd"/>
- <xs:element name="fileref">
- <xs:complexType>
- <xs:sequence>
- <xs:element ref="header"/>
- <xs:element ref="file"/>
- <xs:element ref="filesummary"/>
- <xs:element ref="description"/>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="section"/>
- <xs:element ref="funcs"/>
- </xs:choice>
- <xs:element ref="authors"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <!-- Note: ELEMENT file is already defined -->
- <xs:element name="filesummary" type="xs:string"/>
- <!--
- `name' is used in common.refs.dtd and must therefore
- be defined in each *ref. dtd
- -->
- <xs:element name="name" type="xs:string"/>
-</xs:schema>
diff --git a/lib/docbuilder/xsd/part.xsd b/lib/docbuilder/xsd/part.xsd deleted file mode 100644 index 30d6ec0120..0000000000 --- a/lib/docbuilder/xsd/part.xsd +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
- <xs:include schemaLocation="common.xsd"/>
- <xs:include schemaLocation="common.header.xsd"/>
- <xs:element name="part">
- <xs:complexType>
- <xs:sequence>
- <xs:element ref="header"/>
- <xs:element minOccurs="0" ref="description"/>
- <xs:element maxOccurs="unbounded" ref="include"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="description">
- <xs:complexType>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="block"/>
- <xs:element ref="quote"/>
- <xs:element ref="br"/>
- <xs:element ref="marker"/>
- <xs:element ref="warning"/>
- <xs:element ref="note"/>
- </xs:choice>
- </xs:complexType>
- </xs:element>
- <xs:element name="include">
- <xs:complexType>
- <xs:attribute name="file" use="required"/>
- </xs:complexType>
- </xs:element>
-</xs:schema>
diff --git a/lib/erl_docgen/Makefile b/lib/erl_docgen/Makefile index 93a6353cac..68b41a1ff2 100644 --- a/lib/erl_docgen/Makefile +++ b/lib/erl_docgen/Makefile @@ -23,8 +23,7 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk # Macros # -SUB_DIRECTORIES = src priv -#doc/src +SUB_DIRECTORIES = src priv doc/src include vsn.mk VSN = $(ERL_DOCGEN_VSN) diff --git a/lib/docbuilder/doc/html/.gitignore b/lib/erl_docgen/doc/html/.gitignore index e69de29bb2..e69de29bb2 100644 --- a/lib/docbuilder/doc/html/.gitignore +++ b/lib/erl_docgen/doc/html/.gitignore diff --git a/lib/docbuilder/doc/man3/.gitignore b/lib/erl_docgen/doc/man6/.gitignore index e69de29bb2..e69de29bb2 100644 --- a/lib/docbuilder/doc/man3/.gitignore +++ b/lib/erl_docgen/doc/man6/.gitignore diff --git a/lib/docbuilder/doc/man6/.gitignore b/lib/erl_docgen/doc/pdf/.gitignore index e69de29bb2..e69de29bb2 100644 --- a/lib/docbuilder/doc/man6/.gitignore +++ b/lib/erl_docgen/doc/pdf/.gitignore diff --git a/lib/docbuilder/doc/src/Makefile b/lib/erl_docgen/doc/src/Makefile index ae34266844..ff50c12895 100644 --- a/lib/docbuilder/doc/src/Makefile +++ b/lib/erl_docgen/doc/src/Makefile @@ -1,21 +1,22 @@ # # %CopyrightBegin% -# -# Copyright Ericsson AB 1997-2009. All Rights Reserved. -# +# +# Copyright Ericsson AB 2011-2011. All Rights Reserved. +# # The contents of this file are subject to the Erlang Public License, # Version 1.1, (the "License"); you may not use this file except in # compliance with the License. You should have received a copy of the # Erlang Public License along with this software. If not, it can be # retrieved online at http://www.erlang.org/. -# +# # Software distributed under the License is distributed on an "AS IS" # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See # the License for the specific language governing rights and limitations # under the License. -# +# # %CopyrightEnd% # +# include $(ERL_TOP)/make/target.mk include $(ERL_TOP)/make/$(TARGET)/otp.mk @@ -23,8 +24,8 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk # Application version # ---------------------------------------------------- include ../../vsn.mk -VSN=$(DOCB_VSN) -APPLICATION=docbuilder +VSN=$(ERL_DOCGEN_VSN) +APPLICATION=erl_docgen # ---------------------------------------------------- # Release directory specification @@ -35,45 +36,44 @@ RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN) # Target Specs # ---------------------------------------------------- XML_APPLICATION_FILES = ref_man.xml -XML_REF3_FILES = \ - docb_gen.xml \ - docb_transform.xml \ - docb_xml_check.xml XML_REF6_FILES = \ - docbuilder_app.xml + erl_docgen_app.xml + +XML_PART_FILES = \ + part.xml -XML_PART_FILES = part.xml part_notes.xml XML_CHAPTER_FILES = \ overview.xml \ + doc-build.xml \ user_guide_dtds.xml \ refman_dtds.xml \ - fasc_dtds.xml \ - header_tags.xml \ - block_tags.xml \ + notes.xml \ inline_tags.xml \ + header_tags.xml \ character_entities.xml \ - notes.xml + block_tags.xml BOOK_FILES = book.xml -GIF_FILES = \ - man.gif +XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF6_FILES) \ + $(XML_PART_FILES) $(XML_CHAPTER_FILES) + +TECHNICAL_DESCR_FILES = +EXAMPLE_FILES = \ + example.txt -XML_FILES = \ - $(BOOK_FILES) $(XML_CHAPTER_FILES) \ - $(XML_PART_FILES) $(XML_REF3_FILES) $(XML_REF6_FILES) \ - $(XML_APPLICATION_FILES) +GIF_FILES = \ + man.gif # ---------------------------------------------------- -HTML_FILES = \ - $(XML_APPLICATION_FILES:%.xml=$(HTMLDIR)/%.html) \ +HTML_FILES = $(XML_APPLICATION_FILES:%.xml=$(HTMLDIR)/%.html) \ + $(XML_CHAPTER_FILES:%.xml=$(HTMLDIR)/%.html) \ $(XML_PART_FILES:%.xml=$(HTMLDIR)/%.html) INFO_FILE = ../../info -MAN3_FILES = $(XML_REF3_FILES:%.xml=$(MAN3DIR)/%.3) MAN6_FILES = $(XML_REF6_FILES:%_app.xml=$(MAN6DIR)/%.6) HTML_REF_MAN_FILE = $(HTMLDIR)/index.html @@ -83,34 +83,40 @@ TOP_PDF_FILE = $(PDFDIR)/$(APPLICATION)-$(VSN).pdf # ---------------------------------------------------- # FLAGS # ---------------------------------------------------- +XML_FLAGS += DVIPS_FLAGS += # ---------------------------------------------------- # Targets # ---------------------------------------------------- +docs: pdf html man + $(HTMLDIR)/%.gif: %.gif $(INSTALL_DATA) $< $@ -docs: pdf html man +$(HTMLDIR)/example.txt: example.txt + $(INSTALL_DATA) $< $@ $(TOP_PDF_FILE): $(XML_FILES) pdf: $(TOP_PDF_FILE) -html: gifs $(HTML_REF_MAN_FILE) - -man: $(MAN3_FILES) $(MAN6_FILES) - -gifs: $(GIF_FILES:%=$(HTMLDIR)/%) - -debug opt: +html: gifs examples $(HTML_REF_MAN_FILE) clean clean_docs: rm -rf $(HTMLDIR)/* - rm -f $(MAN3DIR)/* rm -f $(MAN6DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) - rm -f errs core *~ + rm -f errs core *~ + rm -f $(JD_HTML) $(JD_PACK) + +man: $(MAN6_FILES) + +gifs: $(GIF_FILES:%=$(HTMLDIR)/%) + +examples: $(GIF_FILES:%=$(HTMLDIR)/%) + +debug opt: # ---------------------------------------------------- # Release Target @@ -124,9 +130,7 @@ release_docs_spec: docs $(INSTALL_DATA) $(HTMLDIR)/* \ $(RELSYSDIR)/doc/html $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 $(INSTALL_DIR) $(RELEASE_PATH)/man/man6 - $(INSTALL_DATA) $(MAN6_FILES) $(RELEASE_PATH)/man/man6 + $(INSTALL_DATA) $(MAN6DIR)/* $(RELEASE_PATH)/man/man6 release_spec: diff --git a/lib/docbuilder/doc/src/block_tags.xml b/lib/erl_docgen/doc/src/block_tags.xml index f5ba083f38..0900d7f008 100644 --- a/lib/docbuilder/doc/src/block_tags.xml +++ b/lib/erl_docgen/doc/src/block_tags.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>1997</year><year>2009</year> + <year>1997</year><year>2011</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -33,7 +33,7 @@ as a paragraph or a list.</p> <p>The following subset of block tags are common for all DTDs in - the DocBuilder DTD suite: + the OTP DTD suite: <marker id="block_subset"></marker> <seealso marker="#pTAG"><p></seealso>, <seealso marker="#preTAG"><pre></seealso>, @@ -81,7 +81,7 @@ sum([]) -> </code> <p>There is an attribute <c>type = "erl" | "c" | "none"</c>, but - currently this attribute is ignored by DocBuilder. Default value + currently this attribute is ignored. Default value is <c>"none"</c></p> <note> @@ -99,18 +99,18 @@ sum([]) -> gives the file name and <c>tag</c> defines a string which delimits the code snippet. Example:</p> <pre> -<codeinclude file="gazonk" tag="%% Erlang example"/> +<codeinclude file="example.txt" tag="%% Erlang example"/> </pre> <p>results in:</p> - <codeinclude file="gazonk" tag="%% Erlang example"/> + <codeinclude file="example.txt" tag="%% Erlang example"/> - <p>provided there is a file named <c>gazonk</c> looking like this: + <p>provided there is a file named <c>examples.txt</c> looking like this: </p> <code> ... %% Erlang example --module(gazonk). +-module(example). start() -> {error,"Pid required!"}. @@ -125,7 +125,7 @@ start(Pid) -> included.</p> <p>There is also an attribute <c>type = "erl" | "c" | "none"</c>, but - currently this attribute is ignored by DocBuilder. Default value + currently this attribute is ignored. Default value is <c>"none"</c></p> </section> diff --git a/lib/erl_docgen/doc/src/book.xml b/lib/erl_docgen/doc/src/book.xml index 9df5c39271..73bfb7916d 100644 --- a/lib/erl_docgen/doc/src/book.xml +++ b/lib/erl_docgen/doc/src/book.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE book SYSTEM "book.dtd"> <book xmlns:xi="http://www.w3.org/2001/XInclude"> <header titlestyle="normal"> <copyright> - <year>2004</year><year>2009</year> + <year>2004</year><year>2011</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -21,27 +21,26 @@ </legalnotice> - <title>erl_docgen</title> + <title>Erl_Docgen</title> <prepared>Lars Thorsen</prepared> <docno></docno> - <date>2009-11-10</date> - <rev>0.1</rev> + <date>2011-11-10</date> + <rev>0.3</rev> <file>book.xml</file> </header> - <insidecover> - </insidecover> <pagetext>erl_docgen</pagetext> <preamble> <contents level="2"></contents> </preamble> <parts lift="no"> + <xi:include href="part.xml"/> </parts> <applications> + <xi:include href="ref_man.xml"/> </applications> <releasenotes> <xi:include href="notes.xml"/> </releasenotes> - <listofterms></listofterms> <index></index> </book> diff --git a/lib/docbuilder/doc/src/character_entities.xml b/lib/erl_docgen/doc/src/character_entities.xml index 0a4ae17fb5..9f55b68d18 100644 --- a/lib/docbuilder/doc/src/character_entities.xml +++ b/lib/erl_docgen/doc/src/character_entities.xml @@ -32,7 +32,7 @@ <section> <title>Added Latin 1</title> - <p>The DocBuilder DTD suite uses the same character entities as + <p>The OTP DTD suite uses the same character entities as defined in HTML 3.2 (<c>ISO 8879-1986//ENTITIES Added Latin 1//EN//HTML</c>). That is: for an & (ampersand), use the entity: <c>&amp;</c>, for diff --git a/lib/erl_docgen/doc/src/convert.howto b/lib/erl_docgen/doc/src/convert.howto deleted file mode 100644 index 2c72de8c4c..0000000000 --- a/lib/erl_docgen/doc/src/convert.howto +++ /dev/null @@ -1,13 +0,0 @@ - -- add xmlns:xi="http://www.w3.org/2001/XInclude" on top tag - in files whith include directives - -- change <include file="notes"></include> <xi:include href="notes.xml"/> - -- change <image file="a"/> to <image file="a.gif"/> - -- remove chapers directly in the book and put them in the part instead - --change title to just the application name - -- fix codeinclude : xml --> xmlsrc
\ No newline at end of file diff --git a/lib/erl_docgen/doc/src/doc-build.xml b/lib/erl_docgen/doc/src/doc-build.xml new file mode 100644 index 0000000000..08410a1539 --- /dev/null +++ b/lib/erl_docgen/doc/src/doc-build.xml @@ -0,0 +1,188 @@ +<?xml version="1.0" encoding="iso-8859-1" ?> +<!DOCTYPE chapter SYSTEM "chapter.dtd"> + +<chapter> + <header> + <copyright> + <year>1997</year><year>2011</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + <title>How to Build OTP like documentation</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + <file>doc-build.xml</file> + </header> + + <section> + <title>Utilities to prepare XML files</title> + <section> + <title>Create XML files from code</title> + <p> + If there are EDoc comments in a module, the escript <c>xml_from_edoc.escript</c> + can be used to generate an XML file according to the <c>erlref</c> DTD + for this module. + </p> + <p> + Example: + </p> + <code> + + 1> escript $(ERL_TOP)/lib/erl_docgen/priv/bin/xml_from_edoc.escript ex1.erl + </code> + </section> + <section> + <title>Include code in XML</title> + <p>If there are OTP DTD <i>codeinclude</i> tags in the source XML file, the escript + <c>codeline_preprocessing.escript</c> can be used to include the code and produce + an XML file according to the OTP DTDs. + </p> + <p> + Example: + </p> + <code> + + 1> escript $(ERL_TOP)/lib/erl_docgen/priv/bin/codeline_preprocessing.escript ex1.xmlsrc ex1.xml + </code> + </section> + </section> + + <section> + <title>Use xsltproc to generate different output formats</title> + + <section> + <title>Parameters used in all the the XSL transformations</title> + <p> + These parameters to <c>xsltproc</c> are used for all the supported output formats. + </p> + <taglist> + <tag><c>docgen</c></tag> + <item> + Path to erl_docgen's top directory. + </item> + <tag><c>gendate</c></tag> + <item> + The date string that will be used in the documentation. + </item> + <tag><c>appname</c></tag> + <item> + The name of the application.> + </item> + <tag><c>appver</c></tag> + <item> + The version of the application. + </item> + </taglist> + </section> + + <section> + <title>Generate HTML output</title> + <p> + When generating HTML one also needs these three pramaters to <c>xsltproc</c>. + </p> + <taglist> + <tag><c>outdir</c></tag> + <item> + Output directory for the produced html files. + </item> + <tag><c>topdocdir</c></tag> + <item> + If one builds a standalone documentation for an application this should be set to ".". + </item> + <tag><c>pdfdir</c></tag> + <item> + Relative path from the html directory to where the pdf file are placed. + </item> + </taglist> + <p> + Example: + </p> + <code> + + 1> xsltproc --noout --stringparam outdir /tmp/myhtmldoc \ + --stringparam docgen $(ERL_TOP)/lib/erl_docgen \ + --stringparam topdocdir . \ + --stringparam pdfdir "$(PDFDIR)" \ + --xinclude \ + --stringparam gendate "December 5 2011" \ + --stringparam appname MyApp \ + --stringparam appver 0.1 \ + -path $ERL_TOP/lib/erl_docgen/priv/dtd \ + -path $ERL_TOP/lib/erl_docgen/priv/dtd_html_entities \ + $ERL_TOP/lib/erl_docgen/priv/xsl/db_html.xsl mybook.xml + </code> + </section> + + <section> + <title>Generate PDF</title> + <p> + The generation of the PDF file is done in two steps. First is <c>xsltproc</c> used to generate a <c>.fo</c> file + which is used as input to the <c>fop</c> command to produce th PDF file. + </p> + <p> + Example: + </p> + <code> + + 1> xsltproc --output MyApp.fo \ + --stringparam docgen $ERL_TOP/lib/erl_docgen \ + --stringparam gendate "December 5 2011" \ + --stringparam appname MyApp \ + --stringparam appver 0.1 \ + --xinclude \ + -path $ERL_TOP/lib/erl_docgen/priv/dtd \ + -path $ERL_TOP/lib/erl_docgen/priv/dtd_html_entities \ + $ERL_TOP/lib/erl_docgen/priv/xsl/db_pdf.xsl mybook.xml + + + 2> fop -fo MyApp.fo -pdf MyApp.pdf + </code> + </section> + + <section> + <title>Generate man pages</title> + <p> + Unix man pages can be generated with <c>xsltproc</c> from XML files written according to + the different OTP ref type DTDs. + </p> + <p> + Example: + </p> + <code> + + 1> xsltproc --output my_module.3\ + --stringparam docgen $ERL_TOP/lib/erl_docgen \ + --stringparam gendate "December 5 2011" \ + --stringparam appname MyApp \ + --stringparam appver 0.1 \ + --xinclude -path $ERL_TOP/lib/erl_docgen/priv/dtd \ + -path $ERL_TOP/lib/erl_docgen/priv/dtd_man_entities \ + $ERL_TOP/lib/erl_docgen/priv/xsl/db_man.xsl my_refpage.xml + </code> + </section> + + <section> + <title>Upcomming changes</title> + <p> + The output from the <c>erl_docgen</c> documentation build process is now just the OTP style. + But in a near future we will for example add the possibility to change logo, color in the PDF and + style sheet for the HTML. + </p> + </section> + + </section> +</chapter> diff --git a/lib/docbuilder/doc/src/docb_xml_check.xml b/lib/erl_docgen/doc/src/docgen_xml_check.xml index eff4fc4342..58cf069d81 100644 --- a/lib/docbuilder/doc/src/docb_xml_check.xml +++ b/lib/erl_docgen/doc/src/docgen_xml_check.xml @@ -23,16 +23,16 @@ The Initial Developer of the Original Code is Ericsson AB. </legalnotice> - <title>docb_xml_check</title> + <title>docgen_xml_check</title> <prepared></prepared> <docno></docno> <date></date> <rev></rev> </header> - <module>docb_xml_check</module> + <module>docgen_xml_check</module> <modulesummary>Validate XML documentation source code</modulesummary> <description> - <p><c>docb_xml_check</c> contains functions for validating XML + <p><c>docgen_xml_check</c> contains functions for validating XML documentation source code.</p> </description> diff --git a/lib/erl_docgen/doc/src/erl_docgen.txt b/lib/erl_docgen/doc/src/erl_docgen.txt deleted file mode 100644 index 14a4dc8e10..0000000000 --- a/lib/erl_docgen/doc/src/erl_docgen.txt +++ /dev/null @@ -1,6 +0,0 @@ - - - -/home/otptest/bin/otp_wrap_ssh boddington /home/otptest/bin/otp_build_doc -rel r13b02 -view otptest_r13_daily_doc2 -csfile /usr/local/otp/config-specs/r13_dev.cs -insdir /ldisk/daily_build -_ -
\ No newline at end of file diff --git a/lib/erl_docgen/doc/src/erl_docgen_app.xml b/lib/erl_docgen/doc/src/erl_docgen_app.xml new file mode 100644 index 0000000000..25c473bb7e --- /dev/null +++ b/lib/erl_docgen/doc/src/erl_docgen_app.xml @@ -0,0 +1,64 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE appref SYSTEM "appref.dtd"> + +<appref> + <header> + <copyright> + <year>2011</year><year>2011</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>erl_docgen</title> + <file>erl_docgen_app.xml</file> + </header> + <app>erl_docgen</app> + <appsummary> + The erl_docgen application is used to produce the OTP documentation. + </appsummary> + + <description> + <p> + The application consists of the following parts + <taglist> + <tag>XSL</tag> + <item> + <p> + A number of XSL files that is used to transform the xml files to html, pdf or man pages. + </p> + </item> + <tag>DTDs</tag> + <item> + <p> + The DTDs used for the OTP documentation. + </p> + </item> + <tag>escripts</tag> + <item> + <p> + Some scripts that is used to produce xml files according to OTP DTDs from some different input. + </p> + </item> + <tag>misc</tag> + <item> + <p> + Erlang logo, javascripts and css stylesheets used in the documentation. + </p> + </item> + </taglist> + </p> + </description> + +</appref> diff --git a/lib/docbuilder/doc/src/gazonk b/lib/erl_docgen/doc/src/example.txt index 1cf0b8f7bc..ad86165391 100644 --- a/lib/docbuilder/doc/src/gazonk +++ b/lib/erl_docgen/doc/src/example.txt @@ -1,7 +1,7 @@ This example code is used in block_tags.xml. %% Erlang example --module(gazonk). +-module(example). start() -> {error,"Pid required!"}. diff --git a/lib/docbuilder/doc/src/fasc_dtds.xml b/lib/erl_docgen/doc/src/fasc_dtds.xml index dec8189b55..dec8189b55 100644 --- a/lib/docbuilder/doc/src/fasc_dtds.xml +++ b/lib/erl_docgen/doc/src/fasc_dtds.xml diff --git a/lib/docbuilder/doc/src/fascicules.xml b/lib/erl_docgen/doc/src/fascicules.xml index 1b9d6bc94d..1b9d6bc94d 100644 --- a/lib/docbuilder/doc/src/fascicules.xml +++ b/lib/erl_docgen/doc/src/fascicules.xml diff --git a/lib/docbuilder/doc/src/header_tags.xml b/lib/erl_docgen/doc/src/header_tags.xml index b1456d679a..902bce4f68 100644 --- a/lib/docbuilder/doc/src/header_tags.xml +++ b/lib/erl_docgen/doc/src/header_tags.xml @@ -104,7 +104,7 @@ <section> <title><shorttitle></title> - <p>This optional tag is ignored by DocBuilder. It will likely be + <p>This optional tag is ignored. It will likely be removed in the future.</p> </section> @@ -112,8 +112,7 @@ <marker id="preparedTAG"></marker> <title><prepared></title> - <p>This tag is intended for administrative use and is ignored by - DocBuilder.</p> + <p>This tag is intended for administrative use and is ignored.</p> </section> <section> @@ -121,7 +120,7 @@ <title><responsible></title> <p>This optional tag is intended for administrative use and is - ignored by DocBuilder.</p> + ignored.</p> </section> <section> @@ -141,7 +140,7 @@ <title><approved></title> <p>This optional tag is intended for administrative use and is - ignored by DocBuilder.</p> + ignored.</p> </section> <section> @@ -149,15 +148,14 @@ <title><checked></title> <p>This optional tag is intended for administrative use and is - ignored by DocBuilder.</p> + ignored.</p> </section> <section> <marker id="dateTAG"></marker> <title><date></title> - <p>This tag is intended for administrative use and is ignored by - DocBuilder.</p> + <p>This tag is intended for administrative use and is ignored.</p> </section> <section> @@ -177,7 +175,7 @@ <title><file></title> <p>This optional tag is intended for administrative use and is - ignored by DocBuilder.</p> + ignored.</p> </section> </chapter> diff --git a/lib/docbuilder/doc/src/inline_tags.xml b/lib/erl_docgen/doc/src/inline_tags.xml index 5bcca54c05..9b27da659b 100644 --- a/lib/docbuilder/doc/src/inline_tags.xml +++ b/lib/erl_docgen/doc/src/inline_tags.xml @@ -92,7 +92,7 @@ inline tag.</p> </section> - <section> + <!-- section> <marker id="pathTAG"></marker> <title><path> - Path</title> @@ -115,7 +115,7 @@ in:</p> <p>"Look at the <path unix=".profile" windows="win.ini">start-up file</path> if you intend to alter the initial behavior."</p> - </section> + </section --> <section> <marker id="seealsoTAG"></marker> @@ -150,16 +150,10 @@ <p>Note the use of "#" before the name of the marker. Note also that the filename extension <c>.html</c> is omitted. This is - because the default behavior of DocBuilder is to translate + because the default behavior is to translate <c><![CDATA[<seealso marker="File#Marker">text</seealso>]]></c> to <c><![CDATA[<A HREF="File.html#Marker">text</A>]]></c>.</p> - <p>The default behaviour can be modified by using the callback - module option to <c>docb_transform:file/1,2</c> and defining a - callback function - <seealso marker="docb_transform#Module:seealso-1">Module:seealso/1</seealso>. - This possibility is for example used in OTP to resolve cross - references between applications.</p> </section> <section> @@ -192,28 +186,6 @@ <term id="HTML"><termdef>Hyper-Text Markup Language</termdef></term> ]]></pre> - <p>For a globally defined term, the tag is empty. Example:</p> - <pre><![CDATA[ -<term id="HTML"/> - ]]></pre> - - <p>Global definitions are given to DocBuilder in a file, using the - <seealso marker="docb_transform#file/1">docb_transform:file/1,2</seealso> - option <c>term_defs</c>. The file should contain a list of tuples, - one for each term definition, on the format - <c>{Id,Name,Definition,Owner}</c>. The <c>Owner</c> part is just - for administration, if there are several people contributing to a - term definition file. Example:</p> - <pre> -[..., - {"HTML", "HTML", "Hyper-Text Markup Language", "Gunilla"}, - ...]. - </pre> - - <p>DocBuilder will collect both local and global definitions in a - glossary, which can be reached from a link in the left frame of - the HTML documentation.</p> - <p>In the generated HTML, it is the term name which will be visible. For locally defined terms, the id and the name are the same. The name has a hypertext link to the definition in the glossary. @@ -237,21 +209,6 @@ <c><termdef></c>, but for a bibliography list rather than a glossary.</p> - <p>A global bibliography list is given to DocBuilder in a file, - using the <seealso marker="docb_transform#file/1">docb_transform:file/1,2</seealso> - option <c>cite_defs</c>. The file should contain a list of tuples, - one for each cite, on the format - <c>{Id,Title,Info,Owner}</c>. The <c>Owner</c> part is just - for administration, if there are several people contributing to a - bibliography file. Example:</p> - <pre> -[..., - {"erlbook", - "Concurrent Programming in ERLANG","J. Armstrong, R. Virding, C. Wikström, " - "M. Williams, Concurrent Programming in ERLANG, Prentice Hall, 1996, ISBN 0-13-508301-X", - "jocke"}, - ...]. - </pre> </section> </chapter> diff --git a/lib/docbuilder/doc/src/man.gif b/lib/erl_docgen/doc/src/man.gif Binary files differindex 8656c7443d..8656c7443d 100644 --- a/lib/docbuilder/doc/src/man.gif +++ b/lib/erl_docgen/doc/src/man.gif diff --git a/lib/erl_docgen/doc/src/notes.xml b/lib/erl_docgen/doc/src/notes.xml index 6a0eece56d..9591b363f7 100644 --- a/lib/erl_docgen/doc/src/notes.xml +++ b/lib/erl_docgen/doc/src/notes.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE chapter SYSTEM "chapter.dtd"> <chapter> @@ -21,14 +21,14 @@ </legalnotice> - <title>erl_docgen Release Notes</title> + <title>Erl_Docgen Release Notes</title> <prepared>otp_appnotes</prepared> <docno>nil</docno> <date>nil</date> <rev>nil</rev> <file>notes.xml</file> </header> - <p>This document describes the changes made to the erl_docgen application.</p> + <p>This document describes the changes made to the <em>erl_docgen</em> application.</p> <section><title>Erl_Docgen 0.2.6</title> diff --git a/lib/erl_docgen/doc/src/overview.xml b/lib/erl_docgen/doc/src/overview.xml new file mode 100644 index 0000000000..2a420c53d9 --- /dev/null +++ b/lib/erl_docgen/doc/src/overview.xml @@ -0,0 +1,105 @@ +<?xml version="1.0" encoding="iso-8859-1" ?> +<!DOCTYPE chapter SYSTEM "chapter.dtd"> + +<chapter> + <header> + <copyright> + <year>1997</year><year>2011</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + <title>Overview OTP DTDs</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + <file>overview.xml</file> + </header> + + <section> + <title>DTD Suite</title> + + <p>Input is written as XML according to one of the DTDs and output + is corresponding HTML. Documentation for an Erlang/OTP application + is usually organized as follows:</p> + <taglist> + <tag><em>User's Guide</em></tag> + <item> + <p>(DTD: + <seealso marker="user_guide_dtds#partDTD">part</seealso>) + A collection of chapters + (<seealso marker="user_guide_dtds#chapterDTD">chapter</seealso>). + </p> + </item> + + <tag><em>Reference Manual</em></tag> + <item> + <p>(DTD: + <seealso marker="refman_dtds#applicationDTD">application</seealso> + A collection of manual pages for modules + (<seealso marker="refman_dtds#erlrefDTD">erlref</seealso>), + applications + (<seealso marker="refman_dtds#apprefDTD">appref</seealso>), + commands + (<seealso marker="refman_dtds#comrefDTD">comref</seealso>), + C libraries + (<seealso marker="refman_dtds#crefDTD">cref</seealso>) and + files + (<seealso marker="refman_dtds#filerefDTD">fileref</seealso>). + </p> + </item> + + <tag><em>Release Notes</em></tag> + <item> + <p>Same structure as the User's Guide.</p> + </item> + </taglist> + + <p>In some cases, one or more of the User's Guide, Reference Manual + and Release Notes are omitted. Also, it is possible to use either + the <c>application</c> or <c>part</c> DTD to write other types + of documentation for the application.</p> + + + <p>The structure of the different documents and the meaning of the + tags are explained. There are numerous examples of documentation + source code.</p> + + <p>For readability and simplicity, the examples have been kept as + short as possible. For an example of what the generated HTML + will look like, it is recommended to look at the documentation of + an OTP application.</p> + + </section> + + <section> + <title>Basic Tags</title> + + <p>All DTDs in the OTP DTD suite share a basic set of tags. + An author can easily switch from one DTD to another and still use + the same basic tags. It is furthermore easy to copy pieces of + information from one document to another, even though they do not + use the same DTD.</p> + + <p>The basic set of tags are divided into two categories: + <seealso marker="block_tags">block tags</seealso> and + <seealso marker="inline_tags">inline tags</seealso>. Block tags + typically define a separate block of information, like a + paragraph or a list. Inline tags are typically used within block + tags, for example a highlighted word within a paragraph.</p> + </section> + +</chapter> + diff --git a/lib/docbuilder/doc/src/part.xml b/lib/erl_docgen/doc/src/part.xml index 546c6c612e..26d660df08 100644 --- a/lib/docbuilder/doc/src/part.xml +++ b/lib/erl_docgen/doc/src/part.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE part SYSTEM "part.dtd"> <part xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>2007</year><year>2009</year> + <year>2011</year><year>2011</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -20,21 +20,21 @@ under the License. </legalnotice> - <title>DocBuilder User's Guide</title> + <title>Erl_Docgen User's Guide</title> <prepared></prepared> <docno></docno> <date></date> <rev></rev> </header> <description> - <p><em>Docbuilder</em> provides functionality for generating HTML + <p><em>Erl_Docgen</em> provides functionality for generating HTML/PDF/man documentation for Erlang modules and Erlang/OTP applications from XML source code and/or EDoc comments in Erlang source code.</p> </description> + <xi:include href="doc-build.xml"/> <xi:include href="overview.xml"/> <xi:include href="user_guide_dtds.xml"/> <xi:include href="refman_dtds.xml"/> - <xi:include href="fasc_dtds.xml"/> <xi:include href="header_tags.xml"/> <xi:include href="block_tags.xml"/> <xi:include href="inline_tags.xml"/> diff --git a/lib/docbuilder/doc/src/ref_man.xml b/lib/erl_docgen/doc/src/ref_man.xml index 7be8ace32f..a2bc1a10a0 100644 --- a/lib/docbuilder/doc/src/ref_man.xml +++ b/lib/erl_docgen/doc/src/ref_man.xml @@ -4,7 +4,7 @@ <application xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>2007</year><year>2009</year> + <year>2011</year><year>2011</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -21,20 +21,16 @@ </legalnotice> - <title>DocBuilder Reference Manual</title> - <prepared></prepared> + <title>Erl_Docgen Reference Manual</title> + <prepared>OTP Team</prepared> <docno></docno> - <date></date> - <rev></rev> + <date>2011-11-10</date> + <rev>0.3</rev> + <file>ref_man.xml</file> </header> <description> - <p><em>DocBuilder</em> provides functionality for generating HTML - documentation for Erlang modules and Erlang/OTP applications - from XML source code and/or EDoc comments in Erlang source code.</p> + <p>The <em>erl_docgen</em> supports the OTP documentation build.</p> </description> - <xi:include href="docbuilder_app.xml"/> - <xi:include href="docb_gen.xml"/> - <xi:include href="docb_transform.xml"/> - <xi:include href="docb_xml_check.xml"/> + <xi:include href="erl_docgen_app.xml"/> </application> diff --git a/lib/docbuilder/doc/src/refman_dtds.xml b/lib/erl_docgen/doc/src/refman_dtds.xml index a7beaed708..7b01c57db4 100644 --- a/lib/docbuilder/doc/src/refman_dtds.xml +++ b/lib/erl_docgen/doc/src/refman_dtds.xml @@ -573,8 +573,8 @@ a <c><![CDATA[<nametext>]]></c> (function name and arguments, plain text).</p> - <p>In the case of an <c>erlref</c> DTD, DocBuilder will - automatically try to add a + <p>In the case of an <c>erlref</c> DTD, it will + automatically be added a <seealso marker="inline_tags#markerTAG">marker</seealso>, <c><![CDATA[<marker id="Name/Arity">]]></c> or <c><![CDATA[<marker id="Name">]]></c>, based on the contents of @@ -585,7 +585,7 @@ <name>foo(Arg1, Arg2) -> ok | {error, Reason}</name> ]]></pre> - <p>DocBuilder will create a marker + <p>Then a marker like this will be added <c><![CDATA[<marker id="foo/2">]]></c> before the function definition in the generated HTML. That is, referring to the function using diff --git a/lib/docbuilder/doc/src/user_guide_dtds.xml b/lib/erl_docgen/doc/src/user_guide_dtds.xml index a2db44f830..a2db44f830 100644 --- a/lib/docbuilder/doc/src/user_guide_dtds.xml +++ b/lib/erl_docgen/doc/src/user_guide_dtds.xml diff --git a/lib/erl_docgen/info b/lib/erl_docgen/info new file mode 100644 index 0000000000..31c7eb911a --- /dev/null +++ b/lib/erl_docgen/info @@ -0,0 +1,2 @@ +group: doc Documentation Applications +short: A utility used to produce the OTP documentation. diff --git a/lib/erl_docgen/priv/Makefile b/lib/erl_docgen/priv/Makefile index f50350bef2..18cf7b90dd 100644 --- a/lib/erl_docgen/priv/Makefile +++ b/lib/erl_docgen/priv/Makefile @@ -22,7 +22,7 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk # Macros # -SUB_DIRECTORIES = bin css docbuilder_dtd dtd_html_entities dtd_man_entities images js/flipmenu xsl +SUB_DIRECTORIES = bin css dtd dtd_html_entities dtd_man_entities images js/flipmenu xsl SPECIAL_TARGETS = diff --git a/lib/erl_docgen/priv/bin/specs_gen.escript b/lib/erl_docgen/priv/bin/specs_gen.escript index 982afece7f..156311565c 100644 --- a/lib/erl_docgen/priv/bin/specs_gen.escript +++ b/lib/erl_docgen/priv/bin/specs_gen.escript @@ -19,7 +19,7 @@ %%% <script> [-I<dir>]... [-o<dir>] [-module Module] [File] %%% -%%% Use EDoc and the layout module 'otp_specs' to create an XML file +%%% Use EDoc and the layout module 'docgen_otp_specs' to create an XML file %%% containing Dialyzer types and specifications (-type, -spec). %%% %%% Options: @@ -69,7 +69,7 @@ usage() -> call_edoc(FileSpec, InclFs, Dir) -> ReadOpts = [{includes, InclFs}, {preprocess, true}], ExtractOpts = [{report_missing_type, false}], - LayoutOpts = [{pretty_printer, erl_pp}, {layout, otp_specs}], + LayoutOpts = [{pretty_printer, erl_pp}, {layout, docgen_otp_specs}], File = case FileSpec of {file, File0} -> File0; {module, Module0} -> Module0 diff --git a/lib/erl_docgen/priv/bin/xml_from_edoc.escript b/lib/erl_docgen/priv/bin/xml_from_edoc.escript index ee79e82c3a..9a96a3c25a 100755 --- a/lib/erl_docgen/priv/bin/xml_from_edoc.escript +++ b/lib/erl_docgen/priv/bin/xml_from_edoc.escript @@ -27,7 +27,7 @@ %% Records %%====================================================================== -record(args, {suffix=".xml", - layout=docb_edoc_xml_cb, + layout=docgen_edoc_xml_cb, def=[], includes=[], preprocess=false, @@ -126,7 +126,7 @@ users_guide(File, Args) -> parse(["-xml" |RawOpts], Type, Args) -> parse(RawOpts, Type, Args); % default, no update of record necessary parse(["-sgml" |RawOpts], Type, Args) -> - parse(RawOpts, Type, Args#args{suffix=".sgml", layout=docb_edoc_sgml_cb}); + parse(RawOpts, Type, Args#args{suffix=".sgml", layout=docgen_edoc_sgml_cb}); parse(["-chapter" |RawOpts], _Type, Args) -> parse(RawOpts, chapter, Args); parse(["-def", Key, Val |RawOpts], Type, Args) -> diff --git a/lib/erl_docgen/priv/docbuilder_dtd/application.dtd b/lib/erl_docgen/priv/docbuilder_dtd/application.dtd deleted file mode 100644 index 8a1e8832ec..0000000000 --- a/lib/erl_docgen/priv/docbuilder_dtd/application.dtd +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<!-- - ``The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved via the world wide web at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See - the License for the specific language governing rights and limitations - under the License. - - The Initial Developer of the Original Code is Ericsson AB. - Portions created by Ericsson are Copyright 1999-2007, Ericsson AB. - All Rights Reserved.'' - - $Id$ ---> - -<!ENTITY % common SYSTEM "common.dtd" > -%common; -<!ENTITY % common.header SYSTEM "common.header.dtd" > -%common.header; - -<!ELEMENT application (header,description?,include+) > -<!ELEMENT description (%block;|quote|br|marker|warning|note)* > -<!ELEMENT include EMPTY > -<!ATTLIST include file CDATA #REQUIRED> diff --git a/lib/erl_docgen/priv/docbuilder_dtd/appref.dtd b/lib/erl_docgen/priv/docbuilder_dtd/appref.dtd deleted file mode 100644 index 70a5ff37af..0000000000 --- a/lib/erl_docgen/priv/docbuilder_dtd/appref.dtd +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<!-- - ``The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved via the world wide web at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See - the License for the specific language governing rights and limitations - under the License. - - The Initial Developer of the Original Code is Ericsson AB. - Portions created by Ericsson are Copyright 1999-2007, Ericsson AB. - All Rights Reserved.'' - - $Id$ ---> - -<!ENTITY % common.refs SYSTEM "common.refs.dtd" > -%common.refs; - -<!-- Structure --> - -<!ELEMENT appref (header,app,appsummary,description, - (section|funcs)*,authors?) > -<!ELEMENT app (#PCDATA) > -<!ELEMENT appsummary (#PCDATA) > - -<!-- `name' is used in common.refs.dtd and must therefore - be defined in each *ref. dtd --> -<!ELEMENT name (#PCDATA) > diff --git a/lib/erl_docgen/priv/docbuilder_dtd/book.dtd b/lib/erl_docgen/priv/docbuilder_dtd/book.dtd deleted file mode 100644 index bb89a6d255..0000000000 --- a/lib/erl_docgen/priv/docbuilder_dtd/book.dtd +++ /dev/null @@ -1,73 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<!-- - ``The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved via the world wide web at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See - the License for the specific language governing rights and limitations - under the License. - - The Initial Developer of the Original Code is Ericsson AB. - Portions created by Ericsson are Copyright 1999-2007, Ericsson AB. - All Rights Reserved.'' - - $Id$ ---> - -<!ENTITY % common SYSTEM "common.dtd" > -%common; -<!ENTITY % common.header SYSTEM "common.header.dtd" > -%common.header; -<!ENTITY % common.table SYSTEM "common.table.dtd" > -%common.table; - -<!ELEMENT book (header, - insidecover?, - pagetext, - preamble, - (applications|parts|headline|pagetext)+, - (listoffigures?, - listoftables?, - listofterms?, - bibliography?, - index?)) > - -<!ELEMENT pagetext (#PCDATA) > -<!ELEMENT preamble (contents?,preface?) > -<!ELEMENT preface (title?,(%block;|quote|br|marker|warning|note|table)*) > - -<!ELEMENT insidecover (#PCDATA|br|theheader|vfill|vspace|tt|bold| - include)* > -<!ELEMENT tt (#PCDATA|br|theheader|vfill)* > -<!ELEMENT bold (#PCDATA|br|theheader|vfill)* > -<!ELEMENT vfill EMPTY > -<!ELEMENT theheader EMPTY > -<!ATTLIST theheader tag (title|prepared|responsible|docno| - approved|checked|date|rev|file| - abbreviation| - none) "none" > - - -<!ELEMENT applications (include)* > -<!ELEMENT parts (title?,description?,(include|onepart)*) > -<!ATTLIST parts lift (yes|no) "no" > -<!ELEMENT headline (#PCDATA) > -<!ELEMENT index EMPTY > -<!ELEMENT listoffigures EMPTY > -<!ELEMENT listoftables EMPTY > -<!ELEMENT listofterms EMPTY > -<!ELEMENT bibliography EMPTY > -<!ELEMENT contents EMPTY > -<!ATTLIST contents level (0|1|2|3) "2"> - -<!ELEMENT onepart (title?,description?,include+) > -<!ATTLIST onepart lift (yes|no) "no" > - -<!ELEMENT description (%block;|quote|br|marker|warning|note)* > - -<!ELEMENT include EMPTY > -<!ATTLIST include file CDATA #REQUIRED> diff --git a/lib/erl_docgen/priv/docbuilder_dtd/bookinsidecover.dtd b/lib/erl_docgen/priv/docbuilder_dtd/bookinsidecover.dtd deleted file mode 100644 index d6efbef6a4..0000000000 --- a/lib/erl_docgen/priv/docbuilder_dtd/bookinsidecover.dtd +++ /dev/null @@ -1,36 +0,0 @@ -<!-- - ``The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved via the world wide web at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See - the License for the specific language governing rights and limitations - under the License. - - The Initial Developer of the Original Code is Ericsson AB. - Portions created by Ericsson are Copyright 1999-2007, Ericsson AB. - All Rights Reserved.'' - - $Id$ ---> -<!ENTITY % ISOlat1 SYSTEM "xhtml-lat1.ent" > -%ISOlat1; - -<!ENTITY amp "&" > -<!ENTITY gt ">" > -<!ENTITY lt "<" > - -<!ELEMENT bookinsidecover (#PCDATA|br|theheader|vfill|tt|bold)* > - -<!ELEMENT tt (#PCDATA|br|theheader|vfill)* > -<!ELEMENT bold (#PCDATA|br|theheader|vfill)* > -<!ELEMENT vfill EMPTY > -<!ELEMENT theheader EMPTY > -<!ATTLIST theheader tag (title|prepared|responsible|docno| - approved|checked|date|rev|file| - none) "none" > - -<!ELEMENT br EMPTY > diff --git a/lib/erl_docgen/priv/docbuilder_dtd/chapter.dtd b/lib/erl_docgen/priv/docbuilder_dtd/chapter.dtd deleted file mode 100644 index eb2c96b04f..0000000000 --- a/lib/erl_docgen/priv/docbuilder_dtd/chapter.dtd +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<!-- - ``The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved via the world wide web at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See - the License for the specific language governing rights and limitations - under the License. - - The Initial Developer of the Original Code is Ericsson AB. - Portions created by Ericsson are Copyright 1999-2007, Ericsson AB. - All Rights Reserved.'' - - $Id$ ---> - -<!ENTITY % common SYSTEM "common.dtd" > -%common; -<!ENTITY % common.header SYSTEM "common.header.dtd" > -%common.header; -<!ENTITY % common.table SYSTEM "common.table.dtd" > -%common.table; -<!ENTITY % common.image SYSTEM "common.image.dtd" > -%common.image; - -<!-- Structure --> - -<!ELEMENT chapter (header,(%block;|quote|warning|note|br| - image|marker|table)*,section+) > -<!ELEMENT section (marker*,title, - (%block;|quote|warning|note|br|image|marker| - table|section)*) > diff --git a/lib/erl_docgen/priv/docbuilder_dtd/cites.dtd b/lib/erl_docgen/priv/docbuilder_dtd/cites.dtd deleted file mode 100644 index 334574bff9..0000000000 --- a/lib/erl_docgen/priv/docbuilder_dtd/cites.dtd +++ /dev/null @@ -1,35 +0,0 @@ -<!-- - ``The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved via the world wide web at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See - the License for the specific language governing rights and limitations - under the License. - - The Initial Developer of the Original Code is Ericsson AB. - Portions created by Ericsson are Copyright 1999-2007, Ericsson AB. - All Rights Reserved.'' - - $Id$ ---> -<!ENTITY % ISOlat1 SYSTEM "xhtml-lat1.ent" > -%ISOlat1; - -<!ENTITY amp "&" > -<!ENTITY gt ">" > -<!ENTITY lt "<" > - -<!-- Structure --> - -<!ELEMENT cites (cite)* > -<!ELEMENT cite (id, shortdef, def, resp?) > -<!ELEMENT id (#PCDATA) > -<!ELEMENT shortdef (#PCDATA) > -<!ELEMENT def (#PCDATA|c|em)* > -<!ELEMENT resp (#PCDATA) > -<!ELEMENT c (#PCDATA) > -<!ELEMENT em (#PCDATA|c)* > diff --git a/lib/erl_docgen/priv/docbuilder_dtd/common.entities.dtd b/lib/erl_docgen/priv/docbuilder_dtd/common.entities.dtd deleted file mode 100644 index f893ecd070..0000000000 --- a/lib/erl_docgen/priv/docbuilder_dtd/common.entities.dtd +++ /dev/null @@ -1,24 +0,0 @@ -<!-- - ``The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved via the world wide web at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See - the License for the specific language governing rights and limitations - under the License. - - The Initial Developer of the Original Code is Ericsson AB. - Portions created by Ericsson are Copyright 1999-2007, Ericsson AB. - All Rights Reserved.'' - - $Id$ ---> -<!ENTITY % ISOlat1 SYSTEM "xhtml-lat1.ent" > -%ISOlat1; - -<!ENTITY amp "&" > -<!ENTITY gt ">" > -<!ENTITY lt "<" > diff --git a/lib/erl_docgen/priv/docbuilder_dtd/common.header.dtd b/lib/erl_docgen/priv/docbuilder_dtd/common.header.dtd deleted file mode 100644 index d422a89693..0000000000 --- a/lib/erl_docgen/priv/docbuilder_dtd/common.header.dtd +++ /dev/null @@ -1,42 +0,0 @@ -<!-- - ``The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved via the world wide web at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See - the License for the specific language governing rights and limitations - under the License. - - The Initial Developer of the Original Code is Ericsson AB. - Portions created by Ericsson are Copyright 1999-2007, Ericsson AB. - All Rights Reserved.'' - - $Id$ ---> -<!ELEMENT header (copyright?,legalnotice?,title,shorttitle?, - prepared,responsible?,docno,approved?, - checked?,date,rev,file?) > - -<!-- -The titlestyle attribute is only defined to make all the book.xml files -go through the validation. The attribute is not used for anything ---> -<!ATTLIST header titlestyle (special|normal) "normal"> - -<!ELEMENT title (#PCDATA) > -<!ELEMENT shorttitle (#PCDATA) > -<!ELEMENT prepared (#PCDATA) > -<!ELEMENT responsible (#PCDATA) > -<!ELEMENT docno (#PCDATA) > -<!ELEMENT approved (#PCDATA) > -<!ELEMENT checked (#PCDATA) > -<!ELEMENT copyright (year+,holder*) > -<!ELEMENT legalnotice (#PCDATA) > -<!ELEMENT date (#PCDATA) > -<!ELEMENT rev (#PCDATA) > -<!ELEMENT file (#PCDATA) > -<!ELEMENT year (#PCDATA) > -<!ELEMENT holder (#PCDATA) > diff --git a/lib/erl_docgen/priv/docbuilder_dtd/common.image.dtd b/lib/erl_docgen/priv/docbuilder_dtd/common.image.dtd deleted file mode 100644 index fc95a669dd..0000000000 --- a/lib/erl_docgen/priv/docbuilder_dtd/common.image.dtd +++ /dev/null @@ -1,21 +0,0 @@ -<!-- - ``The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved via the world wide web at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See - the License for the specific language governing rights and limitations - under the License. - - The Initial Developer of the Original Code is Ericsson AB. - Portions created by Ericsson are Copyright 1999-2007, Ericsson AB. - All Rights Reserved.'' - - $Id$ ---> -<!ELEMENT image (icaption) > -<!ATTLIST image file CDATA #REQUIRED > -<!ELEMENT icaption (#PCDATA) > diff --git a/lib/erl_docgen/priv/docbuilder_dtd/common.table.dtd b/lib/erl_docgen/priv/docbuilder_dtd/common.table.dtd deleted file mode 100644 index 7741da1018..0000000000 --- a/lib/erl_docgen/priv/docbuilder_dtd/common.table.dtd +++ /dev/null @@ -1,25 +0,0 @@ -<!-- - ``The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved via the world wide web at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See - the License for the specific language governing rights and limitations - under the License. - - The Initial Developer of the Original Code is Ericsson AB. - Portions created by Ericsson are Copyright 1999-2007, Ericsson AB. - All Rights Reserved.'' - - $Id$ ---> -<!ELEMENT table (row+,tcaption) > -<!ATTLIST table align (left|center|right) "center" > -<!ELEMENT row (cell+) > -<!ELEMENT cell (%inline;)* > -<!ATTLIST cell align (left|center|right) "left" - valign (top|middle|bottom) "middle" > -<!ELEMENT tcaption (#PCDATA) > diff --git a/lib/erl_docgen/priv/docbuilder_dtd/comref.dtd b/lib/erl_docgen/priv/docbuilder_dtd/comref.dtd deleted file mode 100644 index fcdea625d5..0000000000 --- a/lib/erl_docgen/priv/docbuilder_dtd/comref.dtd +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<!-- - ``The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved via the world wide web at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See - the License for the specific language governing rights and limitations - under the License. - - The Initial Developer of the Original Code is Ericsson AB. - Portions created by Ericsson are Copyright 1999-2007, Ericsson AB. - All Rights Reserved.'' - - $Id$ ---> - -<!ENTITY % common.refs SYSTEM "common.refs.dtd" > -%common.refs; - -<!ELEMENT comref (header,com,comsummary,description, - (section|funcs)*,authors?) > -<!ELEMENT com (#PCDATA) > -<!ELEMENT comsummary (#PCDATA) > - -<!-- `name' is used in common.refs.dtd and must therefore - be defined in each *ref. dtd --> -<!ELEMENT name (#PCDATA) > diff --git a/lib/erl_docgen/priv/docbuilder_dtd/cref.dtd b/lib/erl_docgen/priv/docbuilder_dtd/cref.dtd deleted file mode 100644 index e43bb2bf51..0000000000 --- a/lib/erl_docgen/priv/docbuilder_dtd/cref.dtd +++ /dev/null @@ -1,34 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<!-- - ``The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved via the world wide web at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See - the License for the specific language governing rights and limitations - under the License. - - The Initial Developer of the Original Code is Ericsson AB. - Portions created by Ericsson are Copyright 1999-2007, Ericsson AB. - All Rights Reserved.'' - - $Id$ ---> - -<!ENTITY % common.refs SYSTEM "common.refs.dtd" > -%common.refs; - -<!ELEMENT cref (header,lib,libsummary,description, - (section|funcs)*,authors?) > -<!ELEMENT lib (#PCDATA) > -<!ELEMENT libsummary (#PCDATA) > - -<!-- `name' is used in common.refs.dtd and must therefore - be defined in each *ref. dtd --> -<!ELEMENT name (ret,nametext) > -<!ELEMENT ret (#PCDATA) > -<!ELEMENT nametext (#PCDATA) > - diff --git a/lib/erl_docgen/priv/docbuilder_dtd/fascicules.dtd b/lib/erl_docgen/priv/docbuilder_dtd/fascicules.dtd deleted file mode 100644 index b14276a2c0..0000000000 --- a/lib/erl_docgen/priv/docbuilder_dtd/fascicules.dtd +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<!-- - ``The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved via the world wide web at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See - the License for the specific language governing rights and limitations - under the License. - - The Initial Developer of the Original Code is Ericsson AB. - Portions created by Ericsson are Copyright 1999-2007, Ericsson AB. - All Rights Reserved.'' - - $Id$ ---> - -<!ENTITY % ISOlat1 SYSTEM "xhtml-lat1.ent" > -%ISOlat1; - -<!ENTITY amp "&" > -<!ENTITY gt ">" > -<!ENTITY lt "<" > - -<!-- Structure --> - -<!ELEMENT fascicules (fascicule)+ > -<!ELEMENT fascicule (#PCDATA) > -<!ATTLIST fascicule file CDATA #REQUIRED - href CDATA #REQUIRED - entry (yes|no) "no" > - diff --git a/lib/erl_docgen/priv/docbuilder_dtd/fileref.dtd b/lib/erl_docgen/priv/docbuilder_dtd/fileref.dtd deleted file mode 100644 index 5a1cc54afe..0000000000 --- a/lib/erl_docgen/priv/docbuilder_dtd/fileref.dtd +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<!-- - ``The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved via the world wide web at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See - the License for the specific language governing rights and limitations - under the License. - - The Initial Developer of the Original Code is Ericsson AB. - Portions created by Ericsson are Copyright 1999-2007, Ericsson AB. - All Rights Reserved.'' - - $Id$ ---> - -<!ENTITY % common.refs SYSTEM "common.refs.dtd" > -%common.refs; - -<!ELEMENT fileref (header,file,filesummary,description, - (section|funcs)*,authors?) > -<!-- Note: ELEMENT file is already defined --> -<!ELEMENT filesummary (#PCDATA) > - -<!-- `name' is used in common.refs.dtd and must therefore - be defined in each *ref. dtd --> -<!ELEMENT name (#PCDATA) > diff --git a/lib/erl_docgen/priv/docbuilder_dtd/part.dtd b/lib/erl_docgen/priv/docbuilder_dtd/part.dtd deleted file mode 100644 index 3f97199042..0000000000 --- a/lib/erl_docgen/priv/docbuilder_dtd/part.dtd +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<!-- - ``The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved via the world wide web at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See - the License for the specific language governing rights and limitations - under the License. - - The Initial Developer of the Original Code is Ericsson AB. - Portions created by Ericsson are Copyright 1999-2007, Ericsson AB. - All Rights Reserved.'' - - $Id$ ---> - -<!ENTITY % common SYSTEM "common.dtd" > -%common; -<!ENTITY % common.header SYSTEM "common.header.dtd" > -%common.header; - -<!ELEMENT part (header,description?,include+) > -<!ELEMENT description (%block;|quote|br|marker|warning|note)* > -<!ELEMENT include EMPTY > -<!ATTLIST include file CDATA #REQUIRED> diff --git a/lib/erl_docgen/priv/docbuilder_dtd/report.dtd b/lib/erl_docgen/priv/docbuilder_dtd/report.dtd deleted file mode 100644 index 3d07e6e5a7..0000000000 --- a/lib/erl_docgen/priv/docbuilder_dtd/report.dtd +++ /dev/null @@ -1,138 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<!-- - ``The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved via the world wide web at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See - the License for the specific language governing rights and limitations - under the License. - - The Initial Developer of the Original Code is Ericsson AB. - Portions created by Ericsson are Copyright 1999-2007, Ericsson AB. - All Rights Reserved.'' - - $Id$ ---> - -<!ENTITY % ISOlat1 SYSTEM "xhtml-lat1.ent" > -%ISOlat1; - -<!ENTITY amp "&" > -<!ENTITY gt ">" > -<!ENTITY lt "<" > - -<!ENTITY % header "title,prepared,responsible,docno,approved, - checked,date,rev,file" > -<!ENTITY % block "p|pre|code|list|taglist|erlinclude| - codeinclude|erleval" > -<!ENTITY % inline "#PCDATA|i|b|c|em|term|cite|br|path|seealso| - url|marker" > - -<!-- Structure --> - -<!ELEMENT report (header,section+) > -<!ELEMENT header (title,prepared,responsible?,docno,approved?, - checked?,date,rev,file?) > -<!ELEMENT title (#PCDATA) > -<!ELEMENT prepared (#PCDATA) > -<!ELEMENT responsible (#PCDATA) > -<!ELEMENT docno (#PCDATA) > -<!ELEMENT approved (#PCDATA) > -<!ELEMENT checked (#PCDATA) > -<!ELEMENT date (#PCDATA) > -<!ELEMENT rev (#PCDATA) > -<!ELEMENT file (#PCDATA) > - -<!ELEMENT section (marker*,title, - (%block;|quote|warning|note|br|image|marker| - table|section)*) > -<!ELEMENT p (%inline;|index)* > -<!ELEMENT pre (#PCDATA|seealso|url|input)* > -<!ELEMENT input (#PCDATA|seealso|url)* > -<!ELEMENT code (#PCDATA) > -<!ATTLIST code type (erl|c|none) "none" > -<!ELEMENT quote (p)* > -<!ELEMENT warning (%block;|quote|br|image|marker|table)* > -<!ELEMENT note (%block;|quote|br|image|marker|table)* > -<!ELEMENT i (#PCDATA|b|c|em)* > -<!ELEMENT b (#PCDATA|i|c|em)* > -<!ELEMENT c (#PCDATA) > -<!ELEMENT em (#PCDATA|i|b|c)* > -<!ELEMENT term (termdef?) > -<!ATTLIST term id CDATA #REQUIRED > -<!ELEMENT termdef (#PCDATA) > -<!ELEMENT cite (citedef?) > -<!ATTLIST cite id CDATA #REQUIRED > -<!ELEMENT citedef (ctitle,cauthor,chowpublished) > -<!ELEMENT ctitle (#PCDATA) > -<!ELEMENT cauthor (#PCDATA) > -<!ELEMENT chowpublished (#PCDATA) > -<!ELEMENT br EMPTY > - -<!-- Path --> - -<!ELEMENT path (#PCDATA) > -<!ATTLIST path unix CDATA "" - windows CDATA "" > - -<!-- List --> - -<!ELEMENT list (item+) > -<!ATTLIST list type (ordered|bulleted) "bulleted" > -<!ELEMENT taglist (tag,item)+ > -<!ELEMENT tag (#PCDATA|i|b|c|em|seealso|url)* > -<!ELEMENT item (%inline;|%block;)* > - -<!-- Image --> - -<!ELEMENT image (icaption?) > -<!ATTLIST image file CDATA #REQUIRED > -<!ELEMENT icaption (#PCDATA) > - -<!-- References --> - -<!ELEMENT seealso (#PCDATA) > -<!ATTLIST seealso marker CDATA #REQUIRED > -<!ELEMENT url (#PCDATA) > -<!ATTLIST url href CDATA #REQUIRED > -<!ELEMENT marker EMPTY > -<!ATTLIST marker id CDATA #REQUIRED > - -<!-- Table --> - -<!ELEMENT table (row+,tcaption?) > -<!ATTLIST table width CDATA "0" - colspec CDATA "" > -<!ELEMENT row (cell+) > -<!ELEMENT cell (%inline;)* > -<!ATTLIST cell align (left|center|right) "left" - valign (top|middle|bottom) "middle" > -<!ELEMENT tcaption (#PCDATA) > - -<!-- ErlInclude --> - -<!ELEMENT erlinclude EMPTY > -<!ATTLIST erlinclude file CDATA #REQUIRED - tag CDATA #REQUIRED > - -<!-- CodeInclude --> - -<!ELEMENT codeinclude EMPTY > -<!ATTLIST codeinclude file CDATA #REQUIRED - tag CDATA "" - type (erl|c|none) "none" > - -<!-- ErlEval --> - -<!ELEMENT erleval EMPTY > -<!ATTLIST erleval expr CDATA #REQUIRED > - -<!-- Index FOR COMPATIBILITY --> - -<!ELEMENT index EMPTY > -<!ATTLIST index txt CDATA #REQUIRED > - diff --git a/lib/erl_docgen/priv/docbuilder_dtd/terms.dtd b/lib/erl_docgen/priv/docbuilder_dtd/terms.dtd deleted file mode 100644 index 6105ec593e..0000000000 --- a/lib/erl_docgen/priv/docbuilder_dtd/terms.dtd +++ /dev/null @@ -1,36 +0,0 @@ -<!-- - ``The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved via the world wide web at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See - the License for the specific language governing rights and limitations - under the License. - - The Initial Developer of the Original Code is Ericsson AB. - Portions created by Ericsson are Copyright 1999-2007, Ericsson AB. - All Rights Reserved.'' - - $Id$ ---> -<!ENTITY % ISOlat1 SYSTEM "xhtml-lat1.ent" > -%ISOlat1; - -<!ENTITY amp "&" > -<!ENTITY gt ">" > -<!ENTITY lt "<" > - -<!-- Structure --> - -<!ELEMENT terms (term)* > -<!ELEMENT term (id, shortdef, def, resp?) > -<!ELEMENT id (#PCDATA) > -<!ELEMENT shortdef (#PCDATA) > -<!ELEMENT def (#PCDATA|c|em)* > -<!ELEMENT resp (#PCDATA) > -<!ELEMENT c (#PCDATA) > -<!ELEMENT em (#PCDATA|c)* > - diff --git a/lib/erl_docgen/priv/docbuilder_dtd/xhtml1-frameset.dtd b/lib/erl_docgen/priv/docbuilder_dtd/xhtml1-frameset.dtd deleted file mode 100644 index d128f2eb7c..0000000000 --- a/lib/erl_docgen/priv/docbuilder_dtd/xhtml1-frameset.dtd +++ /dev/null @@ -1,1235 +0,0 @@ -<!-- - Extensible HTML version 1.0 Frameset DTD - - This is the same as HTML 4 Frameset except for - changes due to the differences between XML and SGML. - - Namespace = http://www.w3.org/1999/xhtml - - For further information, see: http://www.w3.org/TR/xhtml1 - - Copyright (c) 1998-2002 W3C (MIT, INRIA, Keio), - All Rights Reserved. - - This DTD module is identified by the PUBLIC and SYSTEM identifiers: - - PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" - SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd" - - $Revision: 1.2 $ - $Date: 2002/08/01 18:37:55 $ - ---> - -<!--================ Character mnemonic entities =========================--> - -<!ENTITY % HTMLlat1 PUBLIC - "-//W3C//ENTITIES Latin 1 for XHTML//EN" - "xhtml-lat1.ent"> -%HTMLlat1; - -<!ENTITY % HTMLsymbol PUBLIC - "-//W3C//ENTITIES Symbols for XHTML//EN" - "xhtml-symbol.ent"> -%HTMLsymbol; - -<!ENTITY % HTMLspecial PUBLIC - "-//W3C//ENTITIES Special for XHTML//EN" - "xhtml-special.ent"> -%HTMLspecial; - -<!--================== Imported Names ====================================--> - -<!ENTITY % ContentType "CDATA"> - <!-- media type, as per [RFC2045] --> - -<!ENTITY % ContentTypes "CDATA"> - <!-- comma-separated list of media types, as per [RFC2045] --> - -<!ENTITY % Charset "CDATA"> - <!-- a character encoding, as per [RFC2045] --> - -<!ENTITY % Charsets "CDATA"> - <!-- a space separated list of character encodings, as per [RFC2045] --> - -<!ENTITY % LanguageCode "NMTOKEN"> - <!-- a language code, as per [RFC3066] --> - -<!ENTITY % Character "CDATA"> - <!-- a single character, as per section 2.2 of [XML] --> - -<!ENTITY % Number "CDATA"> - <!-- one or more digits --> - -<!ENTITY % LinkTypes "CDATA"> - <!-- space-separated list of link types --> - -<!ENTITY % MediaDesc "CDATA"> - <!-- single or comma-separated list of media descriptors --> - -<!ENTITY % URI "CDATA"> - <!-- a Uniform Resource Identifier, see [RFC2396] --> - -<!ENTITY % UriList "CDATA"> - <!-- a space separated list of Uniform Resource Identifiers --> - -<!ENTITY % Datetime "CDATA"> - <!-- date and time information. ISO date format --> - -<!ENTITY % Script "CDATA"> - <!-- script expression --> - -<!ENTITY % StyleSheet "CDATA"> - <!-- style sheet data --> - -<!ENTITY % Text "CDATA"> - <!-- used for titles etc. --> - -<!ENTITY % FrameTarget "NMTOKEN"> - <!-- render in this frame --> - -<!ENTITY % Length "CDATA"> - <!-- nn for pixels or nn% for percentage length --> - -<!ENTITY % MultiLength "CDATA"> - <!-- pixel, percentage, or relative --> - -<!ENTITY % MultiLengths "CDATA"> - <!-- comma-separated list of MultiLength --> - -<!ENTITY % Pixels "CDATA"> - <!-- integer representing length in pixels --> - -<!-- these are used for image maps --> - -<!ENTITY % Shape "(rect|circle|poly|default)"> - -<!ENTITY % Coords "CDATA"> - <!-- comma separated list of lengths --> - -<!-- used for object, applet, img, input and iframe --> -<!ENTITY % ImgAlign "(top|middle|bottom|left|right)"> - -<!-- a color using sRGB: #RRGGBB as Hex values --> -<!ENTITY % Color "CDATA"> - -<!-- There are also 16 widely known color names with their sRGB values: - - Black = #000000 Green = #008000 - Silver = #C0C0C0 Lime = #00FF00 - Gray = #808080 Olive = #808000 - White = #FFFFFF Yellow = #FFFF00 - Maroon = #800000 Navy = #000080 - Red = #FF0000 Blue = #0000FF - Purple = #800080 Teal = #008080 - Fuchsia= #FF00FF Aqua = #00FFFF ---> - -<!--=================== Generic Attributes ===============================--> - -<!-- core attributes common to most elements - id document-wide unique id - class space separated list of classes - style associated style info - title advisory title/amplification ---> -<!ENTITY % coreattrs - "id ID #IMPLIED - class CDATA #IMPLIED - style %StyleSheet; #IMPLIED - title %Text; #IMPLIED" - > - -<!-- internationalization attributes - lang language code (backwards compatible) - xml:lang language code (as per XML 1.0 spec) - dir direction for weak/neutral text ---> -<!ENTITY % i18n - "lang %LanguageCode; #IMPLIED - xml:lang %LanguageCode; #IMPLIED - dir (ltr|rtl) #IMPLIED" - > - -<!-- attributes for common UI events - onclick a pointer button was clicked - ondblclick a pointer button was double clicked - onmousedown a pointer button was pressed down - onmouseup a pointer button was released - onmousemove a pointer was moved onto the element - onmouseout a pointer was moved away from the element - onkeypress a key was pressed and released - onkeydown a key was pressed down - onkeyup a key was released ---> -<!ENTITY % events - "onclick %Script; #IMPLIED - ondblclick %Script; #IMPLIED - onmousedown %Script; #IMPLIED - onmouseup %Script; #IMPLIED - onmouseover %Script; #IMPLIED - onmousemove %Script; #IMPLIED - onmouseout %Script; #IMPLIED - onkeypress %Script; #IMPLIED - onkeydown %Script; #IMPLIED - onkeyup %Script; #IMPLIED" - > - -<!-- attributes for elements that can get the focus - accesskey accessibility key character - tabindex position in tabbing order - onfocus the element got the focus - onblur the element lost the focus ---> -<!ENTITY % focus - "accesskey %Character; #IMPLIED - tabindex %Number; #IMPLIED - onfocus %Script; #IMPLIED - onblur %Script; #IMPLIED" - > - -<!ENTITY % attrs "%coreattrs; %i18n; %events;"> - -<!-- text alignment for p, div, h1-h6. The default is - align="left" for ltr headings, "right" for rtl --> - -<!ENTITY % TextAlign "align (left|center|right|justify) #IMPLIED"> - -<!--=================== Text Elements ====================================--> - -<!ENTITY % special.extra - "object | applet | img | map | iframe"> - -<!ENTITY % special.basic - "br | span | bdo"> - -<!ENTITY % special - "%special.basic; | %special.extra;"> - -<!ENTITY % fontstyle.extra "big | small | font | basefont"> - -<!ENTITY % fontstyle.basic "tt | i | b | u - | s | strike "> - -<!ENTITY % fontstyle "%fontstyle.basic; | %fontstyle.extra;"> - -<!ENTITY % phrase.extra "sub | sup"> -<!ENTITY % phrase.basic "em | strong | dfn | code | q | - samp | kbd | var | cite | abbr | acronym"> - -<!ENTITY % phrase "%phrase.basic; | %phrase.extra;"> - -<!ENTITY % inline.forms "input | select | textarea | label | button"> - -<!-- these can occur at block or inline level --> -<!ENTITY % misc.inline "ins | del | script"> - -<!-- these can only occur at block level --> -<!ENTITY % misc "noscript | %misc.inline;"> - - -<!ENTITY % inline "a | %special; | %fontstyle; | %phrase; | %inline.forms;"> - -<!-- %Inline; covers inline or "text-level" elements --> -<!ENTITY % Inline "(#PCDATA | %inline; | %misc.inline;)*"> - -<!--================== Block level elements ==============================--> - -<!ENTITY % heading "h1|h2|h3|h4|h5|h6"> -<!ENTITY % lists "ul | ol | dl | menu | dir"> -<!ENTITY % blocktext "pre | hr | blockquote | address | center"> - -<!ENTITY % block - "p | %heading; | div | %lists; | %blocktext; | isindex | fieldset | table"> - -<!-- %Flow; mixes block and inline and is used for list items etc. --> -<!ENTITY % Flow "(#PCDATA | %block; | form | %inline; | %misc;)*"> - -<!--================== Content models for exclusions =====================--> - -<!-- a elements use %Inline; excluding a --> - -<!ENTITY % a.content - "(#PCDATA | %special; | %fontstyle; | %phrase; | %inline.forms; | %misc.inline;)*"> - -<!-- pre uses %Inline excluding img, object, applet, big, small, - sub, sup, font, or basefont --> - -<!ENTITY % pre.content - "(#PCDATA | a | %special.basic; | %fontstyle.basic; | %phrase.basic; | - %inline.forms; | %misc.inline;)*"> - - -<!-- form uses %Flow; excluding form --> - -<!ENTITY % form.content "(#PCDATA | %block; | %inline; | %misc;)*"> - -<!-- button uses %Flow; but excludes a, form, form controls, iframe --> - -<!ENTITY % button.content - "(#PCDATA | p | %heading; | div | %lists; | %blocktext; | - table | br | span | bdo | object | applet | img | map | - %fontstyle; | %phrase; | %misc;)*"> - -<!--================ Document Structure ==================================--> - -<!-- the namespace URI designates the document profile --> - -<!ELEMENT html (head, frameset)> -<!ATTLIST html - %i18n; - id ID #IMPLIED - xmlns %URI; #FIXED 'http://www.w3.org/1999/xhtml' - > - -<!--================ Document Head =======================================--> - -<!ENTITY % head.misc "(script|style|meta|link|object|isindex)*"> - -<!-- content model is %head.misc; combined with a single - title and an optional base element in any order --> - -<!ELEMENT head (%head.misc;, - ((title, %head.misc;, (base, %head.misc;)?) | - (base, %head.misc;, (title, %head.misc;))))> - -<!ATTLIST head - %i18n; - id ID #IMPLIED - profile %URI; #IMPLIED - > - -<!-- The title element is not considered part of the flow of text. - It should be displayed, for example as the page header or - window title. Exactly one title is required per document. - --> -<!ELEMENT title (#PCDATA)> -<!ATTLIST title - %i18n; - id ID #IMPLIED - > - -<!-- document base URI --> - -<!ELEMENT base EMPTY> -<!ATTLIST base - id ID #IMPLIED - href %URI; #IMPLIED - target %FrameTarget; #IMPLIED - > - -<!-- generic metainformation --> -<!ELEMENT meta EMPTY> -<!ATTLIST meta - %i18n; - id ID #IMPLIED - http-equiv CDATA #IMPLIED - name CDATA #IMPLIED - content CDATA #REQUIRED - scheme CDATA #IMPLIED - > - -<!-- - Relationship values can be used in principle: - - a) for document specific toolbars/menus when used - with the link element in document head e.g. - start, contents, previous, next, index, end, help - b) to link to a separate style sheet (rel="stylesheet") - c) to make a link to a script (rel="script") - d) by stylesheets to control how collections of - html nodes are rendered into printed documents - e) to make a link to a printable version of this document - e.g. a PostScript or PDF version (rel="alternate" media="print") ---> - -<!ELEMENT link EMPTY> -<!ATTLIST link - %attrs; - charset %Charset; #IMPLIED - href %URI; #IMPLIED - hreflang %LanguageCode; #IMPLIED - type %ContentType; #IMPLIED - rel %LinkTypes; #IMPLIED - rev %LinkTypes; #IMPLIED - media %MediaDesc; #IMPLIED - target %FrameTarget; #IMPLIED - > - -<!-- style info, which may include CDATA sections --> -<!ELEMENT style (#PCDATA)> -<!ATTLIST style - %i18n; - id ID #IMPLIED - type %ContentType; #REQUIRED - media %MediaDesc; #IMPLIED - title %Text; #IMPLIED - xml:space (preserve) #FIXED 'preserve' - > - -<!-- script statements, which may include CDATA sections --> -<!ELEMENT script (#PCDATA)> -<!ATTLIST script - id ID #IMPLIED - charset %Charset; #IMPLIED - type %ContentType; #REQUIRED - language CDATA #IMPLIED - src %URI; #IMPLIED - defer (defer) #IMPLIED - xml:space (preserve) #FIXED 'preserve' - > - -<!-- alternate content container for non script-based rendering --> - -<!ELEMENT noscript %Flow;> -<!ATTLIST noscript - %attrs; - > - -<!--======================= Frames =======================================--> - -<!-- only one noframes element permitted per document --> - -<!ELEMENT frameset (frameset|frame|noframes)*> -<!ATTLIST frameset - %coreattrs; - rows %MultiLengths; #IMPLIED - cols %MultiLengths; #IMPLIED - onload %Script; #IMPLIED - onunload %Script; #IMPLIED - > - -<!-- reserved frame names start with "_" otherwise starts with letter --> - -<!-- tiled window within frameset --> - -<!ELEMENT frame EMPTY> -<!ATTLIST frame - %coreattrs; - longdesc %URI; #IMPLIED - name NMTOKEN #IMPLIED - src %URI; #IMPLIED - frameborder (1|0) "1" - marginwidth %Pixels; #IMPLIED - marginheight %Pixels; #IMPLIED - noresize (noresize) #IMPLIED - scrolling (yes|no|auto) "auto" - > - -<!-- inline subwindow --> - -<!ELEMENT iframe %Flow;> -<!ATTLIST iframe - %coreattrs; - longdesc %URI; #IMPLIED - name NMTOKEN #IMPLIED - src %URI; #IMPLIED - frameborder (1|0) "1" - marginwidth %Pixels; #IMPLIED - marginheight %Pixels; #IMPLIED - scrolling (yes|no|auto) "auto" - align %ImgAlign; #IMPLIED - height %Length; #IMPLIED - width %Length; #IMPLIED - > - -<!-- alternate content container for non frame-based rendering --> - -<!ELEMENT noframes (body)> -<!ATTLIST noframes - %attrs; - > - -<!--=================== Document Body ====================================--> - -<!ELEMENT body %Flow;> -<!ATTLIST body - %attrs; - onload %Script; #IMPLIED - onunload %Script; #IMPLIED - background %URI; #IMPLIED - bgcolor %Color; #IMPLIED - text %Color; #IMPLIED - link %Color; #IMPLIED - vlink %Color; #IMPLIED - alink %Color; #IMPLIED - > - -<!ELEMENT div %Flow;> <!-- generic language/style container --> -<!ATTLIST div - %attrs; - %TextAlign; - > - -<!--=================== Paragraphs =======================================--> - -<!ELEMENT p %Inline;> -<!ATTLIST p - %attrs; - %TextAlign; - > - -<!--=================== Headings =========================================--> - -<!-- - There are six levels of headings from h1 (the most important) - to h6 (the least important). ---> - -<!ELEMENT h1 %Inline;> -<!ATTLIST h1 - %attrs; - %TextAlign; - > - -<!ELEMENT h2 %Inline;> -<!ATTLIST h2 - %attrs; - %TextAlign; - > - -<!ELEMENT h3 %Inline;> -<!ATTLIST h3 - %attrs; - %TextAlign; - > - -<!ELEMENT h4 %Inline;> -<!ATTLIST h4 - %attrs; - %TextAlign; - > - -<!ELEMENT h5 %Inline;> -<!ATTLIST h5 - %attrs; - %TextAlign; - > - -<!ELEMENT h6 %Inline;> -<!ATTLIST h6 - %attrs; - %TextAlign; - > - -<!--=================== Lists ============================================--> - -<!-- Unordered list bullet styles --> - -<!ENTITY % ULStyle "(disc|square|circle)"> - -<!-- Unordered list --> - -<!ELEMENT ul (li)+> -<!ATTLIST ul - %attrs; - type %ULStyle; #IMPLIED - compact (compact) #IMPLIED - > - -<!-- Ordered list numbering style - - 1 arabic numbers 1, 2, 3, ... - a lower alpha a, b, c, ... - A upper alpha A, B, C, ... - i lower roman i, ii, iii, ... - I upper roman I, II, III, ... - - The style is applied to the sequence number which by default - is reset to 1 for the first list item in an ordered list. ---> -<!ENTITY % OLStyle "CDATA"> - -<!-- Ordered (numbered) list --> - -<!ELEMENT ol (li)+> -<!ATTLIST ol - %attrs; - type %OLStyle; #IMPLIED - compact (compact) #IMPLIED - start %Number; #IMPLIED - > - -<!-- single column list (DEPRECATED) --> -<!ELEMENT menu (li)+> -<!ATTLIST menu - %attrs; - compact (compact) #IMPLIED - > - -<!-- multiple column list (DEPRECATED) --> -<!ELEMENT dir (li)+> -<!ATTLIST dir - %attrs; - compact (compact) #IMPLIED - > - -<!-- LIStyle is constrained to: "(%ULStyle;|%OLStyle;)" --> -<!ENTITY % LIStyle "CDATA"> - -<!-- list item --> - -<!ELEMENT li %Flow;> -<!ATTLIST li - %attrs; - type %LIStyle; #IMPLIED - value %Number; #IMPLIED - > - -<!-- definition lists - dt for term, dd for its definition --> - -<!ELEMENT dl (dt|dd)+> -<!ATTLIST dl - %attrs; - compact (compact) #IMPLIED - > - -<!ELEMENT dt %Inline;> -<!ATTLIST dt - %attrs; - > - -<!ELEMENT dd %Flow;> -<!ATTLIST dd - %attrs; - > - -<!--=================== Address ==========================================--> - -<!-- information on author --> - -<!ELEMENT address (#PCDATA | %inline; | %misc.inline; | p)*> -<!ATTLIST address - %attrs; - > - -<!--=================== Horizontal Rule ==================================--> - -<!ELEMENT hr EMPTY> -<!ATTLIST hr - %attrs; - align (left|center|right) #IMPLIED - noshade (noshade) #IMPLIED - size %Pixels; #IMPLIED - width %Length; #IMPLIED - > - -<!--=================== Preformatted Text ================================--> - -<!-- content is %Inline; excluding - "img|object|applet|big|small|sub|sup|font|basefont" --> - -<!ELEMENT pre %pre.content;> -<!ATTLIST pre - %attrs; - width %Number; #IMPLIED - xml:space (preserve) #FIXED 'preserve' - > - -<!--=================== Block-like Quotes ================================--> - -<!ELEMENT blockquote %Flow;> -<!ATTLIST blockquote - %attrs; - cite %URI; #IMPLIED - > - -<!--=================== Text alignment ===================================--> - -<!-- center content --> -<!ELEMENT center %Flow;> -<!ATTLIST center - %attrs; - > - -<!--=================== Inserted/Deleted Text ============================--> - - -<!-- - ins/del are allowed in block and inline content, but its - inappropriate to include block content within an ins element - occurring in inline content. ---> -<!ELEMENT ins %Flow;> -<!ATTLIST ins - %attrs; - cite %URI; #IMPLIED - datetime %Datetime; #IMPLIED - > - -<!ELEMENT del %Flow;> -<!ATTLIST del - %attrs; - cite %URI; #IMPLIED - datetime %Datetime; #IMPLIED - > - -<!--================== The Anchor Element ================================--> - -<!-- content is %Inline; except that anchors shouldn't be nested --> - -<!ELEMENT a %a.content;> -<!ATTLIST a - %attrs; - %focus; - charset %Charset; #IMPLIED - type %ContentType; #IMPLIED - name NMTOKEN #IMPLIED - href %URI; #IMPLIED - hreflang %LanguageCode; #IMPLIED - rel %LinkTypes; #IMPLIED - rev %LinkTypes; #IMPLIED - shape %Shape; "rect" - coords %Coords; #IMPLIED - target %FrameTarget; #IMPLIED - > - -<!--===================== Inline Elements ================================--> - -<!ELEMENT span %Inline;> <!-- generic language/style container --> -<!ATTLIST span - %attrs; - > - -<!ELEMENT bdo %Inline;> <!-- I18N BiDi over-ride --> -<!ATTLIST bdo - %coreattrs; - %events; - lang %LanguageCode; #IMPLIED - xml:lang %LanguageCode; #IMPLIED - dir (ltr|rtl) #REQUIRED - > - -<!ELEMENT br EMPTY> <!-- forced line break --> -<!ATTLIST br - %coreattrs; - clear (left|all|right|none) "none" - > - -<!ELEMENT em %Inline;> <!-- emphasis --> -<!ATTLIST em %attrs;> - -<!ELEMENT strong %Inline;> <!-- strong emphasis --> -<!ATTLIST strong %attrs;> - -<!ELEMENT dfn %Inline;> <!-- definitional --> -<!ATTLIST dfn %attrs;> - -<!ELEMENT code %Inline;> <!-- program code --> -<!ATTLIST code %attrs;> - -<!ELEMENT samp %Inline;> <!-- sample --> -<!ATTLIST samp %attrs;> - -<!ELEMENT kbd %Inline;> <!-- something user would type --> -<!ATTLIST kbd %attrs;> - -<!ELEMENT var %Inline;> <!-- variable --> -<!ATTLIST var %attrs;> - -<!ELEMENT cite %Inline;> <!-- citation --> -<!ATTLIST cite %attrs;> - -<!ELEMENT abbr %Inline;> <!-- abbreviation --> -<!ATTLIST abbr %attrs;> - -<!ELEMENT acronym %Inline;> <!-- acronym --> -<!ATTLIST acronym %attrs;> - -<!ELEMENT q %Inline;> <!-- inlined quote --> -<!ATTLIST q - %attrs; - cite %URI; #IMPLIED - > - -<!ELEMENT sub %Inline;> <!-- subscript --> -<!ATTLIST sub %attrs;> - -<!ELEMENT sup %Inline;> <!-- superscript --> -<!ATTLIST sup %attrs;> - -<!ELEMENT tt %Inline;> <!-- fixed pitch font --> -<!ATTLIST tt %attrs;> - -<!ELEMENT i %Inline;> <!-- italic font --> -<!ATTLIST i %attrs;> - -<!ELEMENT b %Inline;> <!-- bold font --> -<!ATTLIST b %attrs;> - -<!ELEMENT big %Inline;> <!-- bigger font --> -<!ATTLIST big %attrs;> - -<!ELEMENT small %Inline;> <!-- smaller font --> -<!ATTLIST small %attrs;> - -<!ELEMENT u %Inline;> <!-- underline --> -<!ATTLIST u %attrs;> - -<!ELEMENT s %Inline;> <!-- strike-through --> -<!ATTLIST s %attrs;> - -<!ELEMENT strike %Inline;> <!-- strike-through --> -<!ATTLIST strike %attrs;> - -<!ELEMENT basefont EMPTY> <!-- base font size --> -<!ATTLIST basefont - id ID #IMPLIED - size CDATA #REQUIRED - color %Color; #IMPLIED - face CDATA #IMPLIED - > - -<!ELEMENT font %Inline;> <!-- local change to font --> -<!ATTLIST font - %coreattrs; - %i18n; - size CDATA #IMPLIED - color %Color; #IMPLIED - face CDATA #IMPLIED - > - -<!--==================== Object ======================================--> -<!-- - object is used to embed objects as part of HTML pages. - param elements should precede other content. Parameters - can also be expressed as attribute/value pairs on the - object element itself when brevity is desired. ---> - -<!ELEMENT object (#PCDATA | param | %block; | form |%inline; | %misc;)*> -<!ATTLIST object - %attrs; - declare (declare) #IMPLIED - classid %URI; #IMPLIED - codebase %URI; #IMPLIED - data %URI; #IMPLIED - type %ContentType; #IMPLIED - codetype %ContentType; #IMPLIED - archive %UriList; #IMPLIED - standby %Text; #IMPLIED - height %Length; #IMPLIED - width %Length; #IMPLIED - usemap %URI; #IMPLIED - name NMTOKEN #IMPLIED - tabindex %Number; #IMPLIED - align %ImgAlign; #IMPLIED - border %Pixels; #IMPLIED - hspace %Pixels; #IMPLIED - vspace %Pixels; #IMPLIED - > - -<!-- - param is used to supply a named property value. - In XML it would seem natural to follow RDF and support an - abbreviated syntax where the param elements are replaced - by attribute value pairs on the object start tag. ---> -<!ELEMENT param EMPTY> -<!ATTLIST param - id ID #IMPLIED - name CDATA #REQUIRED - value CDATA #IMPLIED - valuetype (data|ref|object) "data" - type %ContentType; #IMPLIED - > - -<!--=================== Java applet ==================================--> -<!-- - One of code or object attributes must be present. - Place param elements before other content. ---> -<!ELEMENT applet (#PCDATA | param | %block; | form | %inline; | %misc;)*> -<!ATTLIST applet - %coreattrs; - codebase %URI; #IMPLIED - archive CDATA #IMPLIED - code CDATA #IMPLIED - object CDATA #IMPLIED - alt %Text; #IMPLIED - name NMTOKEN #IMPLIED - width %Length; #REQUIRED - height %Length; #REQUIRED - align %ImgAlign; #IMPLIED - hspace %Pixels; #IMPLIED - vspace %Pixels; #IMPLIED - > - -<!--=================== Images ===========================================--> - -<!-- - To avoid accessibility problems for people who aren't - able to see the image, you should provide a text - description using the alt and longdesc attributes. - In addition, avoid the use of server-side image maps. ---> - -<!ELEMENT img EMPTY> -<!ATTLIST img - %attrs; - src %URI; #REQUIRED - alt %Text; #REQUIRED - name NMTOKEN #IMPLIED - longdesc %URI; #IMPLIED - height %Length; #IMPLIED - width %Length; #IMPLIED - usemap %URI; #IMPLIED - ismap (ismap) #IMPLIED - align %ImgAlign; #IMPLIED - border %Pixels; #IMPLIED - hspace %Pixels; #IMPLIED - vspace %Pixels; #IMPLIED - > - -<!-- usemap points to a map element which may be in this document - or an external document, although the latter is not widely supported --> - -<!--================== Client-side image maps ============================--> - -<!-- These can be placed in the same document or grouped in a - separate document although this isn't yet widely supported --> - -<!ELEMENT map ((%block; | form | %misc;)+ | area+)> -<!ATTLIST map - %i18n; - %events; - id ID #REQUIRED - class CDATA #IMPLIED - style %StyleSheet; #IMPLIED - title %Text; #IMPLIED - name NMTOKEN #IMPLIED - > - -<!ELEMENT area EMPTY> -<!ATTLIST area - %attrs; - %focus; - shape %Shape; "rect" - coords %Coords; #IMPLIED - href %URI; #IMPLIED - nohref (nohref) #IMPLIED - alt %Text; #REQUIRED - target %FrameTarget; #IMPLIED - > - -<!--================ Forms ===============================================--> - -<!ELEMENT form %form.content;> <!-- forms shouldn't be nested --> - -<!ATTLIST form - %attrs; - action %URI; #REQUIRED - method (get|post) "get" - name NMTOKEN #IMPLIED - enctype %ContentType; "application/x-www-form-urlencoded" - onsubmit %Script; #IMPLIED - onreset %Script; #IMPLIED - accept %ContentTypes; #IMPLIED - accept-charset %Charsets; #IMPLIED - target %FrameTarget; #IMPLIED - > - -<!-- - Each label must not contain more than ONE field - Label elements shouldn't be nested. ---> -<!ELEMENT label %Inline;> -<!ATTLIST label - %attrs; - for IDREF #IMPLIED - accesskey %Character; #IMPLIED - onfocus %Script; #IMPLIED - onblur %Script; #IMPLIED - > - -<!ENTITY % InputType - "(text | password | checkbox | - radio | submit | reset | - file | hidden | image | button)" - > - -<!-- the name attribute is required for all but submit & reset --> - -<!ELEMENT input EMPTY> <!-- form control --> -<!ATTLIST input - %attrs; - %focus; - type %InputType; "text" - name CDATA #IMPLIED - value CDATA #IMPLIED - checked (checked) #IMPLIED - disabled (disabled) #IMPLIED - readonly (readonly) #IMPLIED - size CDATA #IMPLIED - maxlength %Number; #IMPLIED - src %URI; #IMPLIED - alt CDATA #IMPLIED - usemap %URI; #IMPLIED - onselect %Script; #IMPLIED - onchange %Script; #IMPLIED - accept %ContentTypes; #IMPLIED - align %ImgAlign; #IMPLIED - > - -<!ELEMENT select (optgroup|option)+> <!-- option selector --> -<!ATTLIST select - %attrs; - name CDATA #IMPLIED - size %Number; #IMPLIED - multiple (multiple) #IMPLIED - disabled (disabled) #IMPLIED - tabindex %Number; #IMPLIED - onfocus %Script; #IMPLIED - onblur %Script; #IMPLIED - onchange %Script; #IMPLIED - > - -<!ELEMENT optgroup (option)+> <!-- option group --> -<!ATTLIST optgroup - %attrs; - disabled (disabled) #IMPLIED - label %Text; #REQUIRED - > - -<!ELEMENT option (#PCDATA)> <!-- selectable choice --> -<!ATTLIST option - %attrs; - selected (selected) #IMPLIED - disabled (disabled) #IMPLIED - label %Text; #IMPLIED - value CDATA #IMPLIED - > - -<!ELEMENT textarea (#PCDATA)> <!-- multi-line text field --> -<!ATTLIST textarea - %attrs; - %focus; - name CDATA #IMPLIED - rows %Number; #REQUIRED - cols %Number; #REQUIRED - disabled (disabled) #IMPLIED - readonly (readonly) #IMPLIED - onselect %Script; #IMPLIED - onchange %Script; #IMPLIED - > - -<!-- - The fieldset element is used to group form fields. - Only one legend element should occur in the content - and if present should only be preceded by whitespace. ---> -<!ELEMENT fieldset (#PCDATA | legend | %block; | form | %inline; | %misc;)*> -<!ATTLIST fieldset - %attrs; - > - -<!ENTITY % LAlign "(top|bottom|left|right)"> - -<!ELEMENT legend %Inline;> <!-- fieldset label --> -<!ATTLIST legend - %attrs; - accesskey %Character; #IMPLIED - align %LAlign; #IMPLIED - > - -<!-- - Content is %Flow; excluding a, form, form controls, iframe ---> -<!ELEMENT button %button.content;> <!-- push button --> -<!ATTLIST button - %attrs; - %focus; - name CDATA #IMPLIED - value CDATA #IMPLIED - type (button|submit|reset) "submit" - disabled (disabled) #IMPLIED - > - -<!-- single-line text input control (DEPRECATED) --> -<!ELEMENT isindex EMPTY> -<!ATTLIST isindex - %coreattrs; - %i18n; - prompt %Text; #IMPLIED - > - -<!--======================= Tables =======================================--> - -<!-- Derived from IETF HTML table standard, see [RFC1942] --> - -<!-- - The border attribute sets the thickness of the frame around the - table. The default units are screen pixels. - - The frame attribute specifies which parts of the frame around - the table should be rendered. The values are not the same as - CALS to avoid a name clash with the valign attribute. ---> -<!ENTITY % TFrame "(void|above|below|hsides|lhs|rhs|vsides|box|border)"> - -<!-- - The rules attribute defines which rules to draw between cells: - - If rules is absent then assume: - "none" if border is absent or border="0" otherwise "all" ---> - -<!ENTITY % TRules "(none | groups | rows | cols | all)"> - -<!-- horizontal placement of table relative to document --> -<!ENTITY % TAlign "(left|center|right)"> - -<!-- horizontal alignment attributes for cell contents - - char alignment char, e.g. char=":" - charoff offset for alignment char ---> -<!ENTITY % cellhalign - "align (left|center|right|justify|char) #IMPLIED - char %Character; #IMPLIED - charoff %Length; #IMPLIED" - > - -<!-- vertical alignment attributes for cell contents --> -<!ENTITY % cellvalign - "valign (top|middle|bottom|baseline) #IMPLIED" - > - -<!ELEMENT table - (caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))> -<!ELEMENT caption %Inline;> -<!ELEMENT thead (tr)+> -<!ELEMENT tfoot (tr)+> -<!ELEMENT tbody (tr)+> -<!ELEMENT colgroup (col)*> -<!ELEMENT col EMPTY> -<!ELEMENT tr (th|td)+> -<!ELEMENT th %Flow;> -<!ELEMENT td %Flow;> - -<!ATTLIST table - %attrs; - summary %Text; #IMPLIED - width %Length; #IMPLIED - border %Pixels; #IMPLIED - frame %TFrame; #IMPLIED - rules %TRules; #IMPLIED - cellspacing %Length; #IMPLIED - cellpadding %Length; #IMPLIED - align %TAlign; #IMPLIED - bgcolor %Color; #IMPLIED - > - -<!ENTITY % CAlign "(top|bottom|left|right)"> - -<!ATTLIST caption - %attrs; - align %CAlign; #IMPLIED - > - -<!-- -colgroup groups a set of col elements. It allows you to group -several semantically related columns together. ---> -<!ATTLIST colgroup - %attrs; - span %Number; "1" - width %MultiLength; #IMPLIED - %cellhalign; - %cellvalign; - > - -<!-- - col elements define the alignment properties for cells in - one or more columns. - - The width attribute specifies the width of the columns, e.g. - - width=64 width in screen pixels - width=0.5* relative width of 0.5 - - The span attribute causes the attributes of one - col element to apply to more than one column. ---> -<!ATTLIST col - %attrs; - span %Number; "1" - width %MultiLength; #IMPLIED - %cellhalign; - %cellvalign; - > - -<!-- - Use thead to duplicate headers when breaking table - across page boundaries, or for static headers when - tbody sections are rendered in scrolling panel. - - Use tfoot to duplicate footers when breaking table - across page boundaries, or for static footers when - tbody sections are rendered in scrolling panel. - - Use multiple tbody sections when rules are needed - between groups of table rows. ---> -<!ATTLIST thead - %attrs; - %cellhalign; - %cellvalign; - > - -<!ATTLIST tfoot - %attrs; - %cellhalign; - %cellvalign; - > - -<!ATTLIST tbody - %attrs; - %cellhalign; - %cellvalign; - > - -<!ATTLIST tr - %attrs; - %cellhalign; - %cellvalign; - bgcolor %Color; #IMPLIED - > - -<!-- Scope is simpler than headers attribute for common tables --> -<!ENTITY % Scope "(row|col|rowgroup|colgroup)"> - -<!-- th is for headers, td for data and for cells acting as both --> - -<!ATTLIST th - %attrs; - abbr %Text; #IMPLIED - axis CDATA #IMPLIED - headers IDREFS #IMPLIED - scope %Scope; #IMPLIED - rowspan %Number; "1" - colspan %Number; "1" - %cellhalign; - %cellvalign; - nowrap (nowrap) #IMPLIED - bgcolor %Color; #IMPLIED - width %Pixels; #IMPLIED - height %Pixels; #IMPLIED - > - -<!ATTLIST td - %attrs; - abbr %Text; #IMPLIED - axis CDATA #IMPLIED - headers IDREFS #IMPLIED - scope %Scope; #IMPLIED - rowspan %Number; "1" - colspan %Number; "1" - %cellhalign; - %cellvalign; - nowrap (nowrap) #IMPLIED - bgcolor %Color; #IMPLIED - width %Pixels; #IMPLIED - height %Pixels; #IMPLIED - > - diff --git a/lib/erl_docgen/priv/docbuilder_dtd/xhtml1-strict.dtd b/lib/erl_docgen/priv/docbuilder_dtd/xhtml1-strict.dtd deleted file mode 100644 index 2927b9ece7..0000000000 --- a/lib/erl_docgen/priv/docbuilder_dtd/xhtml1-strict.dtd +++ /dev/null @@ -1,978 +0,0 @@ -<!-- - Extensible HTML version 1.0 Strict DTD - - This is the same as HTML 4 Strict except for - changes due to the differences between XML and SGML. - - Namespace = http://www.w3.org/1999/xhtml - - For further information, see: http://www.w3.org/TR/xhtml1 - - Copyright (c) 1998-2002 W3C (MIT, INRIA, Keio), - All Rights Reserved. - - This DTD module is identified by the PUBLIC and SYSTEM identifiers: - - PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" - SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" - - $Revision: 1.1 $ - $Date: 2002/08/01 13:56:03 $ - ---> - -<!--================ Character mnemonic entities =========================--> - -<!ENTITY % HTMLlat1 PUBLIC - "-//W3C//ENTITIES Latin 1 for XHTML//EN" - "xhtml-lat1.ent"> -%HTMLlat1; - -<!ENTITY % HTMLsymbol PUBLIC - "-//W3C//ENTITIES Symbols for XHTML//EN" - "xhtml-symbol.ent"> -%HTMLsymbol; - -<!ENTITY % HTMLspecial PUBLIC - "-//W3C//ENTITIES Special for XHTML//EN" - "xhtml-special.ent"> -%HTMLspecial; - -<!--================== Imported Names ====================================--> - -<!ENTITY % ContentType "CDATA"> - <!-- media type, as per [RFC2045] --> - -<!ENTITY % ContentTypes "CDATA"> - <!-- comma-separated list of media types, as per [RFC2045] --> - -<!ENTITY % Charset "CDATA"> - <!-- a character encoding, as per [RFC2045] --> - -<!ENTITY % Charsets "CDATA"> - <!-- a space separated list of character encodings, as per [RFC2045] --> - -<!ENTITY % LanguageCode "NMTOKEN"> - <!-- a language code, as per [RFC3066] --> - -<!ENTITY % Character "CDATA"> - <!-- a single character, as per section 2.2 of [XML] --> - -<!ENTITY % Number "CDATA"> - <!-- one or more digits --> - -<!ENTITY % LinkTypes "CDATA"> - <!-- space-separated list of link types --> - -<!ENTITY % MediaDesc "CDATA"> - <!-- single or comma-separated list of media descriptors --> - -<!ENTITY % URI "CDATA"> - <!-- a Uniform Resource Identifier, see [RFC2396] --> - -<!ENTITY % UriList "CDATA"> - <!-- a space separated list of Uniform Resource Identifiers --> - -<!ENTITY % Datetime "CDATA"> - <!-- date and time information. ISO date format --> - -<!ENTITY % Script "CDATA"> - <!-- script expression --> - -<!ENTITY % StyleSheet "CDATA"> - <!-- style sheet data --> - -<!ENTITY % Text "CDATA"> - <!-- used for titles etc. --> - -<!ENTITY % Length "CDATA"> - <!-- nn for pixels or nn% for percentage length --> - -<!ENTITY % MultiLength "CDATA"> - <!-- pixel, percentage, or relative --> - -<!ENTITY % Pixels "CDATA"> - <!-- integer representing length in pixels --> - -<!-- these are used for image maps --> - -<!ENTITY % Shape "(rect|circle|poly|default)"> - -<!ENTITY % Coords "CDATA"> - <!-- comma separated list of lengths --> - -<!--=================== Generic Attributes ===============================--> - -<!-- core attributes common to most elements - id document-wide unique id - class space separated list of classes - style associated style info - title advisory title/amplification ---> -<!ENTITY % coreattrs - "id ID #IMPLIED - class CDATA #IMPLIED - style %StyleSheet; #IMPLIED - title %Text; #IMPLIED" - > - -<!-- internationalization attributes - lang language code (backwards compatible) - xml:lang language code (as per XML 1.0 spec) - dir direction for weak/neutral text ---> -<!ENTITY % i18n - "lang %LanguageCode; #IMPLIED - xml:lang %LanguageCode; #IMPLIED - dir (ltr|rtl) #IMPLIED" - > - -<!-- attributes for common UI events - onclick a pointer button was clicked - ondblclick a pointer button was double clicked - onmousedown a pointer button was pressed down - onmouseup a pointer button was released - onmousemove a pointer was moved onto the element - onmouseout a pointer was moved away from the element - onkeypress a key was pressed and released - onkeydown a key was pressed down - onkeyup a key was released ---> -<!ENTITY % events - "onclick %Script; #IMPLIED - ondblclick %Script; #IMPLIED - onmousedown %Script; #IMPLIED - onmouseup %Script; #IMPLIED - onmouseover %Script; #IMPLIED - onmousemove %Script; #IMPLIED - onmouseout %Script; #IMPLIED - onkeypress %Script; #IMPLIED - onkeydown %Script; #IMPLIED - onkeyup %Script; #IMPLIED" - > - -<!-- attributes for elements that can get the focus - accesskey accessibility key character - tabindex position in tabbing order - onfocus the element got the focus - onblur the element lost the focus ---> -<!ENTITY % focus - "accesskey %Character; #IMPLIED - tabindex %Number; #IMPLIED - onfocus %Script; #IMPLIED - onblur %Script; #IMPLIED" - > - -<!ENTITY % attrs "%coreattrs; %i18n; %events;"> - -<!--=================== Text Elements ====================================--> - -<!ENTITY % special.pre - "br | span | bdo | map"> - - -<!ENTITY % special - "%special.pre; | object | img "> - -<!ENTITY % fontstyle "tt | i | b | big | small "> - -<!ENTITY % phrase "em | strong | dfn | code | q | - samp | kbd | var | cite | abbr | acronym | sub | sup "> - -<!ENTITY % inline.forms "input | select | textarea | label | button"> - -<!-- these can occur at block or inline level --> -<!ENTITY % misc.inline "ins | del | script"> - -<!-- these can only occur at block level --> -<!ENTITY % misc "noscript | %misc.inline;"> - -<!ENTITY % inline "a | %special; | %fontstyle; | %phrase; | %inline.forms;"> - -<!-- %Inline; covers inline or "text-level" elements --> -<!ENTITY % Inline "(#PCDATA | %inline; | %misc.inline;)*"> - -<!--================== Block level elements ==============================--> - -<!ENTITY % heading "h1|h2|h3|h4|h5|h6"> -<!ENTITY % lists "ul | ol | dl"> -<!ENTITY % blocktext "pre | hr | blockquote | address"> - -<!ENTITY % block - "p | %heading; | div | %lists; | %blocktext; | fieldset | table"> - -<!ENTITY % Block "(%block; | form | %misc;)*"> - -<!-- %Flow; mixes block and inline and is used for list items etc. --> -<!ENTITY % Flow "(#PCDATA | %block; | form | %inline; | %misc;)*"> - -<!--================== Content models for exclusions =====================--> - -<!-- a elements use %Inline; excluding a --> - -<!ENTITY % a.content - "(#PCDATA | %special; | %fontstyle; | %phrase; | %inline.forms; | %misc.inline;)*"> - -<!-- pre uses %Inline excluding big, small, sup or sup --> - -<!ENTITY % pre.content - "(#PCDATA | a | %fontstyle; | %phrase; | %special.pre; | %misc.inline; - | %inline.forms;)*"> - -<!-- form uses %Block; excluding form --> - -<!ENTITY % form.content "(%block; | %misc;)*"> - -<!-- button uses %Flow; but excludes a, form and form controls --> - -<!ENTITY % button.content - "(#PCDATA | p | %heading; | div | %lists; | %blocktext; | - table | %special; | %fontstyle; | %phrase; | %misc;)*"> - -<!--================ Document Structure ==================================--> - -<!-- the namespace URI designates the document profile --> - -<!ELEMENT html (head, body)> -<!ATTLIST html - %i18n; - id ID #IMPLIED - xmlns %URI; #FIXED 'http://www.w3.org/1999/xhtml' - > - -<!--================ Document Head =======================================--> - -<!ENTITY % head.misc "(script|style|meta|link|object)*"> - -<!-- content model is %head.misc; combined with a single - title and an optional base element in any order --> - -<!ELEMENT head (%head.misc;, - ((title, %head.misc;, (base, %head.misc;)?) | - (base, %head.misc;, (title, %head.misc;))))> - -<!ATTLIST head - %i18n; - id ID #IMPLIED - profile %URI; #IMPLIED - > - -<!-- The title element is not considered part of the flow of text. - It should be displayed, for example as the page header or - window title. Exactly one title is required per document. - --> -<!ELEMENT title (#PCDATA)> -<!ATTLIST title - %i18n; - id ID #IMPLIED - > - -<!-- document base URI --> - -<!ELEMENT base EMPTY> -<!ATTLIST base - href %URI; #REQUIRED - id ID #IMPLIED - > - -<!-- generic metainformation --> -<!ELEMENT meta EMPTY> -<!ATTLIST meta - %i18n; - id ID #IMPLIED - http-equiv CDATA #IMPLIED - name CDATA #IMPLIED - content CDATA #REQUIRED - scheme CDATA #IMPLIED - > - -<!-- - Relationship values can be used in principle: - - a) for document specific toolbars/menus when used - with the link element in document head e.g. - start, contents, previous, next, index, end, help - b) to link to a separate style sheet (rel="stylesheet") - c) to make a link to a script (rel="script") - d) by stylesheets to control how collections of - html nodes are rendered into printed documents - e) to make a link to a printable version of this document - e.g. a PostScript or PDF version (rel="alternate" media="print") ---> - -<!ELEMENT link EMPTY> -<!ATTLIST link - %attrs; - charset %Charset; #IMPLIED - href %URI; #IMPLIED - hreflang %LanguageCode; #IMPLIED - type %ContentType; #IMPLIED - rel %LinkTypes; #IMPLIED - rev %LinkTypes; #IMPLIED - media %MediaDesc; #IMPLIED - > - -<!-- style info, which may include CDATA sections --> -<!ELEMENT style (#PCDATA)> -<!ATTLIST style - %i18n; - id ID #IMPLIED - type %ContentType; #REQUIRED - media %MediaDesc; #IMPLIED - title %Text; #IMPLIED - xml:space (preserve) #FIXED 'preserve' - > - -<!-- script statements, which may include CDATA sections --> -<!ELEMENT script (#PCDATA)> -<!ATTLIST script - id ID #IMPLIED - charset %Charset; #IMPLIED - type %ContentType; #REQUIRED - src %URI; #IMPLIED - defer (defer) #IMPLIED - xml:space (preserve) #FIXED 'preserve' - > - -<!-- alternate content container for non script-based rendering --> - -<!ELEMENT noscript %Block;> -<!ATTLIST noscript - %attrs; - > - -<!--=================== Document Body ====================================--> - -<!ELEMENT body %Block;> -<!ATTLIST body - %attrs; - onload %Script; #IMPLIED - onunload %Script; #IMPLIED - > - -<!ELEMENT div %Flow;> <!-- generic language/style container --> -<!ATTLIST div - %attrs; - > - -<!--=================== Paragraphs =======================================--> - -<!ELEMENT p %Inline;> -<!ATTLIST p - %attrs; - > - -<!--=================== Headings =========================================--> - -<!-- - There are six levels of headings from h1 (the most important) - to h6 (the least important). ---> - -<!ELEMENT h1 %Inline;> -<!ATTLIST h1 - %attrs; - > - -<!ELEMENT h2 %Inline;> -<!ATTLIST h2 - %attrs; - > - -<!ELEMENT h3 %Inline;> -<!ATTLIST h3 - %attrs; - > - -<!ELEMENT h4 %Inline;> -<!ATTLIST h4 - %attrs; - > - -<!ELEMENT h5 %Inline;> -<!ATTLIST h5 - %attrs; - > - -<!ELEMENT h6 %Inline;> -<!ATTLIST h6 - %attrs; - > - -<!--=================== Lists ============================================--> - -<!-- Unordered list --> - -<!ELEMENT ul (li)+> -<!ATTLIST ul - %attrs; - > - -<!-- Ordered (numbered) list --> - -<!ELEMENT ol (li)+> -<!ATTLIST ol - %attrs; - > - -<!-- list item --> - -<!ELEMENT li %Flow;> -<!ATTLIST li - %attrs; - > - -<!-- definition lists - dt for term, dd for its definition --> - -<!ELEMENT dl (dt|dd)+> -<!ATTLIST dl - %attrs; - > - -<!ELEMENT dt %Inline;> -<!ATTLIST dt - %attrs; - > - -<!ELEMENT dd %Flow;> -<!ATTLIST dd - %attrs; - > - -<!--=================== Address ==========================================--> - -<!-- information on author --> - -<!ELEMENT address %Inline;> -<!ATTLIST address - %attrs; - > - -<!--=================== Horizontal Rule ==================================--> - -<!ELEMENT hr EMPTY> -<!ATTLIST hr - %attrs; - > - -<!--=================== Preformatted Text ================================--> - -<!-- content is %Inline; excluding "img|object|big|small|sub|sup" --> - -<!ELEMENT pre %pre.content;> -<!ATTLIST pre - %attrs; - xml:space (preserve) #FIXED 'preserve' - > - -<!--=================== Block-like Quotes ================================--> - -<!ELEMENT blockquote %Block;> -<!ATTLIST blockquote - %attrs; - cite %URI; #IMPLIED - > - -<!--=================== Inserted/Deleted Text ============================--> - -<!-- - ins/del are allowed in block and inline content, but its - inappropriate to include block content within an ins element - occurring in inline content. ---> -<!ELEMENT ins %Flow;> -<!ATTLIST ins - %attrs; - cite %URI; #IMPLIED - datetime %Datetime; #IMPLIED - > - -<!ELEMENT del %Flow;> -<!ATTLIST del - %attrs; - cite %URI; #IMPLIED - datetime %Datetime; #IMPLIED - > - -<!--================== The Anchor Element ================================--> - -<!-- content is %Inline; except that anchors shouldn't be nested --> - -<!ELEMENT a %a.content;> -<!ATTLIST a - %attrs; - %focus; - charset %Charset; #IMPLIED - type %ContentType; #IMPLIED - name NMTOKEN #IMPLIED - href %URI; #IMPLIED - hreflang %LanguageCode; #IMPLIED - rel %LinkTypes; #IMPLIED - rev %LinkTypes; #IMPLIED - shape %Shape; "rect" - coords %Coords; #IMPLIED - > - -<!--===================== Inline Elements ================================--> - -<!ELEMENT span %Inline;> <!-- generic language/style container --> -<!ATTLIST span - %attrs; - > - -<!ELEMENT bdo %Inline;> <!-- I18N BiDi over-ride --> -<!ATTLIST bdo - %coreattrs; - %events; - lang %LanguageCode; #IMPLIED - xml:lang %LanguageCode; #IMPLIED - dir (ltr|rtl) #REQUIRED - > - -<!ELEMENT br EMPTY> <!-- forced line break --> -<!ATTLIST br - %coreattrs; - > - -<!ELEMENT em %Inline;> <!-- emphasis --> -<!ATTLIST em %attrs;> - -<!ELEMENT strong %Inline;> <!-- strong emphasis --> -<!ATTLIST strong %attrs;> - -<!ELEMENT dfn %Inline;> <!-- definitional --> -<!ATTLIST dfn %attrs;> - -<!ELEMENT code %Inline;> <!-- program code --> -<!ATTLIST code %attrs;> - -<!ELEMENT samp %Inline;> <!-- sample --> -<!ATTLIST samp %attrs;> - -<!ELEMENT kbd %Inline;> <!-- something user would type --> -<!ATTLIST kbd %attrs;> - -<!ELEMENT var %Inline;> <!-- variable --> -<!ATTLIST var %attrs;> - -<!ELEMENT cite %Inline;> <!-- citation --> -<!ATTLIST cite %attrs;> - -<!ELEMENT abbr %Inline;> <!-- abbreviation --> -<!ATTLIST abbr %attrs;> - -<!ELEMENT acronym %Inline;> <!-- acronym --> -<!ATTLIST acronym %attrs;> - -<!ELEMENT q %Inline;> <!-- inlined quote --> -<!ATTLIST q - %attrs; - cite %URI; #IMPLIED - > - -<!ELEMENT sub %Inline;> <!-- subscript --> -<!ATTLIST sub %attrs;> - -<!ELEMENT sup %Inline;> <!-- superscript --> -<!ATTLIST sup %attrs;> - -<!ELEMENT tt %Inline;> <!-- fixed pitch font --> -<!ATTLIST tt %attrs;> - -<!ELEMENT i %Inline;> <!-- italic font --> -<!ATTLIST i %attrs;> - -<!ELEMENT b %Inline;> <!-- bold font --> -<!ATTLIST b %attrs;> - -<!ELEMENT big %Inline;> <!-- bigger font --> -<!ATTLIST big %attrs;> - -<!ELEMENT small %Inline;> <!-- smaller font --> -<!ATTLIST small %attrs;> - -<!--==================== Object ======================================--> -<!-- - object is used to embed objects as part of HTML pages. - param elements should precede other content. Parameters - can also be expressed as attribute/value pairs on the - object element itself when brevity is desired. ---> - -<!ELEMENT object (#PCDATA | param | %block; | form | %inline; | %misc;)*> -<!ATTLIST object - %attrs; - declare (declare) #IMPLIED - classid %URI; #IMPLIED - codebase %URI; #IMPLIED - data %URI; #IMPLIED - type %ContentType; #IMPLIED - codetype %ContentType; #IMPLIED - archive %UriList; #IMPLIED - standby %Text; #IMPLIED - height %Length; #IMPLIED - width %Length; #IMPLIED - usemap %URI; #IMPLIED - name NMTOKEN #IMPLIED - tabindex %Number; #IMPLIED - > - -<!-- - param is used to supply a named property value. - In XML it would seem natural to follow RDF and support an - abbreviated syntax where the param elements are replaced - by attribute value pairs on the object start tag. ---> -<!ELEMENT param EMPTY> -<!ATTLIST param - id ID #IMPLIED - name CDATA #IMPLIED - value CDATA #IMPLIED - valuetype (data|ref|object) "data" - type %ContentType; #IMPLIED - > - -<!--=================== Images ===========================================--> - -<!-- - To avoid accessibility problems for people who aren't - able to see the image, you should provide a text - description using the alt and longdesc attributes. - In addition, avoid the use of server-side image maps. - Note that in this DTD there is no name attribute. That - is only available in the transitional and frameset DTD. ---> - -<!ELEMENT img EMPTY> -<!ATTLIST img - %attrs; - src %URI; #REQUIRED - alt %Text; #REQUIRED - longdesc %URI; #IMPLIED - height %Length; #IMPLIED - width %Length; #IMPLIED - usemap %URI; #IMPLIED - ismap (ismap) #IMPLIED - > - -<!-- usemap points to a map element which may be in this document - or an external document, although the latter is not widely supported --> - -<!--================== Client-side image maps ============================--> - -<!-- These can be placed in the same document or grouped in a - separate document although this isn't yet widely supported --> - -<!ELEMENT map ((%block; | form | %misc;)+ | area+)> -<!ATTLIST map - %i18n; - %events; - id ID #REQUIRED - class CDATA #IMPLIED - style %StyleSheet; #IMPLIED - title %Text; #IMPLIED - name NMTOKEN #IMPLIED - > - -<!ELEMENT area EMPTY> -<!ATTLIST area - %attrs; - %focus; - shape %Shape; "rect" - coords %Coords; #IMPLIED - href %URI; #IMPLIED - nohref (nohref) #IMPLIED - alt %Text; #REQUIRED - > - -<!--================ Forms ===============================================--> -<!ELEMENT form %form.content;> <!-- forms shouldn't be nested --> - -<!ATTLIST form - %attrs; - action %URI; #REQUIRED - method (get|post) "get" - enctype %ContentType; "application/x-www-form-urlencoded" - onsubmit %Script; #IMPLIED - onreset %Script; #IMPLIED - accept %ContentTypes; #IMPLIED - accept-charset %Charsets; #IMPLIED - > - -<!-- - Each label must not contain more than ONE field - Label elements shouldn't be nested. ---> -<!ELEMENT label %Inline;> -<!ATTLIST label - %attrs; - for IDREF #IMPLIED - accesskey %Character; #IMPLIED - onfocus %Script; #IMPLIED - onblur %Script; #IMPLIED - > - -<!ENTITY % InputType - "(text | password | checkbox | - radio | submit | reset | - file | hidden | image | button)" - > - -<!-- the name attribute is required for all but submit & reset --> - -<!ELEMENT input EMPTY> <!-- form control --> -<!ATTLIST input - %attrs; - %focus; - type %InputType; "text" - name CDATA #IMPLIED - value CDATA #IMPLIED - checked (checked) #IMPLIED - disabled (disabled) #IMPLIED - readonly (readonly) #IMPLIED - size CDATA #IMPLIED - maxlength %Number; #IMPLIED - src %URI; #IMPLIED - alt CDATA #IMPLIED - usemap %URI; #IMPLIED - onselect %Script; #IMPLIED - onchange %Script; #IMPLIED - accept %ContentTypes; #IMPLIED - > - -<!ELEMENT select (optgroup|option)+> <!-- option selector --> -<!ATTLIST select - %attrs; - name CDATA #IMPLIED - size %Number; #IMPLIED - multiple (multiple) #IMPLIED - disabled (disabled) #IMPLIED - tabindex %Number; #IMPLIED - onfocus %Script; #IMPLIED - onblur %Script; #IMPLIED - onchange %Script; #IMPLIED - > - -<!ELEMENT optgroup (option)+> <!-- option group --> -<!ATTLIST optgroup - %attrs; - disabled (disabled) #IMPLIED - label %Text; #REQUIRED - > - -<!ELEMENT option (#PCDATA)> <!-- selectable choice --> -<!ATTLIST option - %attrs; - selected (selected) #IMPLIED - disabled (disabled) #IMPLIED - label %Text; #IMPLIED - value CDATA #IMPLIED - > - -<!ELEMENT textarea (#PCDATA)> <!-- multi-line text field --> -<!ATTLIST textarea - %attrs; - %focus; - name CDATA #IMPLIED - rows %Number; #REQUIRED - cols %Number; #REQUIRED - disabled (disabled) #IMPLIED - readonly (readonly) #IMPLIED - onselect %Script; #IMPLIED - onchange %Script; #IMPLIED - > - -<!-- - The fieldset element is used to group form fields. - Only one legend element should occur in the content - and if present should only be preceded by whitespace. ---> -<!ELEMENT fieldset (#PCDATA | legend | %block; | form | %inline; | %misc;)*> -<!ATTLIST fieldset - %attrs; - > - -<!ELEMENT legend %Inline;> <!-- fieldset label --> -<!ATTLIST legend - %attrs; - accesskey %Character; #IMPLIED - > - -<!-- - Content is %Flow; excluding a, form and form controls ---> -<!ELEMENT button %button.content;> <!-- push button --> -<!ATTLIST button - %attrs; - %focus; - name CDATA #IMPLIED - value CDATA #IMPLIED - type (button|submit|reset) "submit" - disabled (disabled) #IMPLIED - > - -<!--======================= Tables =======================================--> - -<!-- Derived from IETF HTML table standard, see [RFC1942] --> - -<!-- - The border attribute sets the thickness of the frame around the - table. The default units are screen pixels. - - The frame attribute specifies which parts of the frame around - the table should be rendered. The values are not the same as - CALS to avoid a name clash with the valign attribute. ---> -<!ENTITY % TFrame "(void|above|below|hsides|lhs|rhs|vsides|box|border)"> - -<!-- - The rules attribute defines which rules to draw between cells: - - If rules is absent then assume: - "none" if border is absent or border="0" otherwise "all" ---> - -<!ENTITY % TRules "(none | groups | rows | cols | all)"> - -<!-- horizontal alignment attributes for cell contents - - char alignment char, e.g. char=':' - charoff offset for alignment char ---> -<!ENTITY % cellhalign - "align (left|center|right|justify|char) #IMPLIED - char %Character; #IMPLIED - charoff %Length; #IMPLIED" - > - -<!-- vertical alignment attributes for cell contents --> -<!ENTITY % cellvalign - "valign (top|middle|bottom|baseline) #IMPLIED" - > - -<!ELEMENT table - (caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))> -<!ELEMENT caption %Inline;> -<!ELEMENT thead (tr)+> -<!ELEMENT tfoot (tr)+> -<!ELEMENT tbody (tr)+> -<!ELEMENT colgroup (col)*> -<!ELEMENT col EMPTY> -<!ELEMENT tr (th|td)+> -<!ELEMENT th %Flow;> -<!ELEMENT td %Flow;> - -<!ATTLIST table - %attrs; - summary %Text; #IMPLIED - width %Length; #IMPLIED - border %Pixels; #IMPLIED - frame %TFrame; #IMPLIED - rules %TRules; #IMPLIED - cellspacing %Length; #IMPLIED - cellpadding %Length; #IMPLIED - > - -<!ATTLIST caption - %attrs; - > - -<!-- -colgroup groups a set of col elements. It allows you to group -several semantically related columns together. ---> -<!ATTLIST colgroup - %attrs; - span %Number; "1" - width %MultiLength; #IMPLIED - %cellhalign; - %cellvalign; - > - -<!-- - col elements define the alignment properties for cells in - one or more columns. - - The width attribute specifies the width of the columns, e.g. - - width=64 width in screen pixels - width=0.5* relative width of 0.5 - - The span attribute causes the attributes of one - col element to apply to more than one column. ---> -<!ATTLIST col - %attrs; - span %Number; "1" - width %MultiLength; #IMPLIED - %cellhalign; - %cellvalign; - > - -<!-- - Use thead to duplicate headers when breaking table - across page boundaries, or for static headers when - tbody sections are rendered in scrolling panel. - - Use tfoot to duplicate footers when breaking table - across page boundaries, or for static footers when - tbody sections are rendered in scrolling panel. - - Use multiple tbody sections when rules are needed - between groups of table rows. ---> -<!ATTLIST thead - %attrs; - %cellhalign; - %cellvalign; - > - -<!ATTLIST tfoot - %attrs; - %cellhalign; - %cellvalign; - > - -<!ATTLIST tbody - %attrs; - %cellhalign; - %cellvalign; - > - -<!ATTLIST tr - %attrs; - %cellhalign; - %cellvalign; - > - - -<!-- Scope is simpler than headers attribute for common tables --> -<!ENTITY % Scope "(row|col|rowgroup|colgroup)"> - -<!-- th is for headers, td for data and for cells acting as both --> - -<!ATTLIST th - %attrs; - abbr %Text; #IMPLIED - axis CDATA #IMPLIED - headers IDREFS #IMPLIED - scope %Scope; #IMPLIED - rowspan %Number; "1" - colspan %Number; "1" - %cellhalign; - %cellvalign; - > - -<!ATTLIST td - %attrs; - abbr %Text; #IMPLIED - axis CDATA #IMPLIED - headers IDREFS #IMPLIED - scope %Scope; #IMPLIED - rowspan %Number; "1" - colspan %Number; "1" - %cellhalign; - %cellvalign; - > - diff --git a/lib/erl_docgen/priv/docbuilder_dtd/xhtml1-transitional.dtd b/lib/erl_docgen/priv/docbuilder_dtd/xhtml1-transitional.dtd deleted file mode 100644 index 628f27ac50..0000000000 --- a/lib/erl_docgen/priv/docbuilder_dtd/xhtml1-transitional.dtd +++ /dev/null @@ -1,1201 +0,0 @@ -<!-- - Extensible HTML version 1.0 Transitional DTD - - This is the same as HTML 4 Transitional except for - changes due to the differences between XML and SGML. - - Namespace = http://www.w3.org/1999/xhtml - - For further information, see: http://www.w3.org/TR/xhtml1 - - Copyright (c) 1998-2002 W3C (MIT, INRIA, Keio), - All Rights Reserved. - - This DTD module is identified by the PUBLIC and SYSTEM identifiers: - - PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" - - $Revision: 1.2 $ - $Date: 2002/08/01 18:37:55 $ - ---> - -<!--================ Character mnemonic entities =========================--> - -<!ENTITY % HTMLlat1 PUBLIC - "-//W3C//ENTITIES Latin 1 for XHTML//EN" - "xhtml-lat1.ent"> -%HTMLlat1; - -<!ENTITY % HTMLsymbol PUBLIC - "-//W3C//ENTITIES Symbols for XHTML//EN" - "xhtml-symbol.ent"> -%HTMLsymbol; - -<!ENTITY % HTMLspecial PUBLIC - "-//W3C//ENTITIES Special for XHTML//EN" - "xhtml-special.ent"> -%HTMLspecial; - -<!--================== Imported Names ====================================--> - -<!ENTITY % ContentType "CDATA"> - <!-- media type, as per [RFC2045] --> - -<!ENTITY % ContentTypes "CDATA"> - <!-- comma-separated list of media types, as per [RFC2045] --> - -<!ENTITY % Charset "CDATA"> - <!-- a character encoding, as per [RFC2045] --> - -<!ENTITY % Charsets "CDATA"> - <!-- a space separated list of character encodings, as per [RFC2045] --> - -<!ENTITY % LanguageCode "NMTOKEN"> - <!-- a language code, as per [RFC3066] --> - -<!ENTITY % Character "CDATA"> - <!-- a single character, as per section 2.2 of [XML] --> - -<!ENTITY % Number "CDATA"> - <!-- one or more digits --> - -<!ENTITY % LinkTypes "CDATA"> - <!-- space-separated list of link types --> - -<!ENTITY % MediaDesc "CDATA"> - <!-- single or comma-separated list of media descriptors --> - -<!ENTITY % URI "CDATA"> - <!-- a Uniform Resource Identifier, see [RFC2396] --> - -<!ENTITY % UriList "CDATA"> - <!-- a space separated list of Uniform Resource Identifiers --> - -<!ENTITY % Datetime "CDATA"> - <!-- date and time information. ISO date format --> - -<!ENTITY % Script "CDATA"> - <!-- script expression --> - -<!ENTITY % StyleSheet "CDATA"> - <!-- style sheet data --> - -<!ENTITY % Text "CDATA"> - <!-- used for titles etc. --> - -<!ENTITY % FrameTarget "NMTOKEN"> - <!-- render in this frame --> - -<!ENTITY % Length "CDATA"> - <!-- nn for pixels or nn% for percentage length --> - -<!ENTITY % MultiLength "CDATA"> - <!-- pixel, percentage, or relative --> - -<!ENTITY % Pixels "CDATA"> - <!-- integer representing length in pixels --> - -<!-- these are used for image maps --> - -<!ENTITY % Shape "(rect|circle|poly|default)"> - -<!ENTITY % Coords "CDATA"> - <!-- comma separated list of lengths --> - -<!-- used for object, applet, img, input and iframe --> -<!ENTITY % ImgAlign "(top|middle|bottom|left|right)"> - -<!-- a color using sRGB: #RRGGBB as Hex values --> -<!ENTITY % Color "CDATA"> - -<!-- There are also 16 widely known color names with their sRGB values: - - Black = #000000 Green = #008000 - Silver = #C0C0C0 Lime = #00FF00 - Gray = #808080 Olive = #808000 - White = #FFFFFF Yellow = #FFFF00 - Maroon = #800000 Navy = #000080 - Red = #FF0000 Blue = #0000FF - Purple = #800080 Teal = #008080 - Fuchsia= #FF00FF Aqua = #00FFFF ---> - -<!--=================== Generic Attributes ===============================--> - -<!-- core attributes common to most elements - id document-wide unique id - class space separated list of classes - style associated style info - title advisory title/amplification ---> -<!ENTITY % coreattrs - "id ID #IMPLIED - class CDATA #IMPLIED - style %StyleSheet; #IMPLIED - title %Text; #IMPLIED" - > - -<!-- internationalization attributes - lang language code (backwards compatible) - xml:lang language code (as per XML 1.0 spec) - dir direction for weak/neutral text ---> -<!ENTITY % i18n - "lang %LanguageCode; #IMPLIED - xml:lang %LanguageCode; #IMPLIED - dir (ltr|rtl) #IMPLIED" - > - -<!-- attributes for common UI events - onclick a pointer button was clicked - ondblclick a pointer button was double clicked - onmousedown a pointer button was pressed down - onmouseup a pointer button was released - onmousemove a pointer was moved onto the element - onmouseout a pointer was moved away from the element - onkeypress a key was pressed and released - onkeydown a key was pressed down - onkeyup a key was released ---> -<!ENTITY % events - "onclick %Script; #IMPLIED - ondblclick %Script; #IMPLIED - onmousedown %Script; #IMPLIED - onmouseup %Script; #IMPLIED - onmouseover %Script; #IMPLIED - onmousemove %Script; #IMPLIED - onmouseout %Script; #IMPLIED - onkeypress %Script; #IMPLIED - onkeydown %Script; #IMPLIED - onkeyup %Script; #IMPLIED" - > - -<!-- attributes for elements that can get the focus - accesskey accessibility key character - tabindex position in tabbing order - onfocus the element got the focus - onblur the element lost the focus ---> -<!ENTITY % focus - "accesskey %Character; #IMPLIED - tabindex %Number; #IMPLIED - onfocus %Script; #IMPLIED - onblur %Script; #IMPLIED" - > - -<!ENTITY % attrs "%coreattrs; %i18n; %events;"> - -<!-- text alignment for p, div, h1-h6. The default is - align="left" for ltr headings, "right" for rtl --> - -<!ENTITY % TextAlign "align (left|center|right|justify) #IMPLIED"> - -<!--=================== Text Elements ====================================--> - -<!ENTITY % special.extra - "object | applet | img | map | iframe"> - -<!ENTITY % special.basic - "br | span | bdo"> - -<!ENTITY % special - "%special.basic; | %special.extra;"> - -<!ENTITY % fontstyle.extra "big | small | font | basefont"> - -<!ENTITY % fontstyle.basic "tt | i | b | u - | s | strike "> - -<!ENTITY % fontstyle "%fontstyle.basic; | %fontstyle.extra;"> - -<!ENTITY % phrase.extra "sub | sup"> -<!ENTITY % phrase.basic "em | strong | dfn | code | q | - samp | kbd | var | cite | abbr | acronym"> - -<!ENTITY % phrase "%phrase.basic; | %phrase.extra;"> - -<!ENTITY % inline.forms "input | select | textarea | label | button"> - -<!-- these can occur at block or inline level --> -<!ENTITY % misc.inline "ins | del | script"> - -<!-- these can only occur at block level --> -<!ENTITY % misc "noscript | %misc.inline;"> - -<!ENTITY % inline "a | %special; | %fontstyle; | %phrase; | %inline.forms;"> - -<!-- %Inline; covers inline or "text-level" elements --> -<!ENTITY % Inline "(#PCDATA | %inline; | %misc.inline;)*"> - -<!--================== Block level elements ==============================--> - -<!ENTITY % heading "h1|h2|h3|h4|h5|h6"> -<!ENTITY % lists "ul | ol | dl | menu | dir"> -<!ENTITY % blocktext "pre | hr | blockquote | address | center | noframes"> - -<!ENTITY % block - "p | %heading; | div | %lists; | %blocktext; | isindex |fieldset | table"> - -<!-- %Flow; mixes block and inline and is used for list items etc. --> -<!ENTITY % Flow "(#PCDATA | %block; | form | %inline; | %misc;)*"> - -<!--================== Content models for exclusions =====================--> - -<!-- a elements use %Inline; excluding a --> - -<!ENTITY % a.content - "(#PCDATA | %special; | %fontstyle; | %phrase; | %inline.forms; | %misc.inline;)*"> - -<!-- pre uses %Inline excluding img, object, applet, big, small, - font, or basefont --> - -<!ENTITY % pre.content - "(#PCDATA | a | %special.basic; | %fontstyle.basic; | %phrase.basic; | - %inline.forms; | %misc.inline;)*"> - -<!-- form uses %Flow; excluding form --> - -<!ENTITY % form.content "(#PCDATA | %block; | %inline; | %misc;)*"> - -<!-- button uses %Flow; but excludes a, form, form controls, iframe --> - -<!ENTITY % button.content - "(#PCDATA | p | %heading; | div | %lists; | %blocktext; | - table | br | span | bdo | object | applet | img | map | - %fontstyle; | %phrase; | %misc;)*"> - -<!--================ Document Structure ==================================--> - -<!-- the namespace URI designates the document profile --> - -<!ELEMENT html (head, body)> -<!ATTLIST html - %i18n; - id ID #IMPLIED - xmlns %URI; #FIXED 'http://www.w3.org/1999/xhtml' - > - -<!--================ Document Head =======================================--> - -<!ENTITY % head.misc "(script|style|meta|link|object|isindex)*"> - -<!-- content model is %head.misc; combined with a single - title and an optional base element in any order --> - -<!ELEMENT head (%head.misc;, - ((title, %head.misc;, (base, %head.misc;)?) | - (base, %head.misc;, (title, %head.misc;))))> - -<!ATTLIST head - %i18n; - id ID #IMPLIED - profile %URI; #IMPLIED - > - -<!-- The title element is not considered part of the flow of text. - It should be displayed, for example as the page header or - window title. Exactly one title is required per document. - --> -<!ELEMENT title (#PCDATA)> -<!ATTLIST title - %i18n; - id ID #IMPLIED - > - -<!-- document base URI --> - -<!ELEMENT base EMPTY> -<!ATTLIST base - id ID #IMPLIED - href %URI; #IMPLIED - target %FrameTarget; #IMPLIED - > - -<!-- generic metainformation --> -<!ELEMENT meta EMPTY> -<!ATTLIST meta - %i18n; - id ID #IMPLIED - http-equiv CDATA #IMPLIED - name CDATA #IMPLIED - content CDATA #REQUIRED - scheme CDATA #IMPLIED - > - -<!-- - Relationship values can be used in principle: - - a) for document specific toolbars/menus when used - with the link element in document head e.g. - start, contents, previous, next, index, end, help - b) to link to a separate style sheet (rel="stylesheet") - c) to make a link to a script (rel="script") - d) by stylesheets to control how collections of - html nodes are rendered into printed documents - e) to make a link to a printable version of this document - e.g. a PostScript or PDF version (rel="alternate" media="print") ---> - -<!ELEMENT link EMPTY> -<!ATTLIST link - %attrs; - charset %Charset; #IMPLIED - href %URI; #IMPLIED - hreflang %LanguageCode; #IMPLIED - type %ContentType; #IMPLIED - rel %LinkTypes; #IMPLIED - rev %LinkTypes; #IMPLIED - media %MediaDesc; #IMPLIED - target %FrameTarget; #IMPLIED - > - -<!-- style info, which may include CDATA sections --> -<!ELEMENT style (#PCDATA)> -<!ATTLIST style - %i18n; - id ID #IMPLIED - type %ContentType; #REQUIRED - media %MediaDesc; #IMPLIED - title %Text; #IMPLIED - xml:space (preserve) #FIXED 'preserve' - > - -<!-- script statements, which may include CDATA sections --> -<!ELEMENT script (#PCDATA)> -<!ATTLIST script - id ID #IMPLIED - charset %Charset; #IMPLIED - type %ContentType; #REQUIRED - language CDATA #IMPLIED - src %URI; #IMPLIED - defer (defer) #IMPLIED - xml:space (preserve) #FIXED 'preserve' - > - -<!-- alternate content container for non script-based rendering --> - -<!ELEMENT noscript %Flow;> -<!ATTLIST noscript - %attrs; - > - -<!--======================= Frames =======================================--> - -<!-- inline subwindow --> - -<!ELEMENT iframe %Flow;> -<!ATTLIST iframe - %coreattrs; - longdesc %URI; #IMPLIED - name NMTOKEN #IMPLIED - src %URI; #IMPLIED - frameborder (1|0) "1" - marginwidth %Pixels; #IMPLIED - marginheight %Pixels; #IMPLIED - scrolling (yes|no|auto) "auto" - align %ImgAlign; #IMPLIED - height %Length; #IMPLIED - width %Length; #IMPLIED - > - -<!-- alternate content container for non frame-based rendering --> - -<!ELEMENT noframes %Flow;> -<!ATTLIST noframes - %attrs; - > - -<!--=================== Document Body ====================================--> - -<!ELEMENT body %Flow;> -<!ATTLIST body - %attrs; - onload %Script; #IMPLIED - onunload %Script; #IMPLIED - background %URI; #IMPLIED - bgcolor %Color; #IMPLIED - text %Color; #IMPLIED - link %Color; #IMPLIED - vlink %Color; #IMPLIED - alink %Color; #IMPLIED - > - -<!ELEMENT div %Flow;> <!-- generic language/style container --> -<!ATTLIST div - %attrs; - %TextAlign; - > - -<!--=================== Paragraphs =======================================--> - -<!ELEMENT p %Inline;> -<!ATTLIST p - %attrs; - %TextAlign; - > - -<!--=================== Headings =========================================--> - -<!-- - There are six levels of headings from h1 (the most important) - to h6 (the least important). ---> - -<!ELEMENT h1 %Inline;> -<!ATTLIST h1 - %attrs; - %TextAlign; - > - -<!ELEMENT h2 %Inline;> -<!ATTLIST h2 - %attrs; - %TextAlign; - > - -<!ELEMENT h3 %Inline;> -<!ATTLIST h3 - %attrs; - %TextAlign; - > - -<!ELEMENT h4 %Inline;> -<!ATTLIST h4 - %attrs; - %TextAlign; - > - -<!ELEMENT h5 %Inline;> -<!ATTLIST h5 - %attrs; - %TextAlign; - > - -<!ELEMENT h6 %Inline;> -<!ATTLIST h6 - %attrs; - %TextAlign; - > - -<!--=================== Lists ============================================--> - -<!-- Unordered list bullet styles --> - -<!ENTITY % ULStyle "(disc|square|circle)"> - -<!-- Unordered list --> - -<!ELEMENT ul (li)+> -<!ATTLIST ul - %attrs; - type %ULStyle; #IMPLIED - compact (compact) #IMPLIED - > - -<!-- Ordered list numbering style - - 1 arabic numbers 1, 2, 3, ... - a lower alpha a, b, c, ... - A upper alpha A, B, C, ... - i lower roman i, ii, iii, ... - I upper roman I, II, III, ... - - The style is applied to the sequence number which by default - is reset to 1 for the first list item in an ordered list. ---> -<!ENTITY % OLStyle "CDATA"> - -<!-- Ordered (numbered) list --> - -<!ELEMENT ol (li)+> -<!ATTLIST ol - %attrs; - type %OLStyle; #IMPLIED - compact (compact) #IMPLIED - start %Number; #IMPLIED - > - -<!-- single column list (DEPRECATED) --> -<!ELEMENT menu (li)+> -<!ATTLIST menu - %attrs; - compact (compact) #IMPLIED - > - -<!-- multiple column list (DEPRECATED) --> -<!ELEMENT dir (li)+> -<!ATTLIST dir - %attrs; - compact (compact) #IMPLIED - > - -<!-- LIStyle is constrained to: "(%ULStyle;|%OLStyle;)" --> -<!ENTITY % LIStyle "CDATA"> - -<!-- list item --> - -<!ELEMENT li %Flow;> -<!ATTLIST li - %attrs; - type %LIStyle; #IMPLIED - value %Number; #IMPLIED - > - -<!-- definition lists - dt for term, dd for its definition --> - -<!ELEMENT dl (dt|dd)+> -<!ATTLIST dl - %attrs; - compact (compact) #IMPLIED - > - -<!ELEMENT dt %Inline;> -<!ATTLIST dt - %attrs; - > - -<!ELEMENT dd %Flow;> -<!ATTLIST dd - %attrs; - > - -<!--=================== Address ==========================================--> - -<!-- information on author --> - -<!ELEMENT address (#PCDATA | %inline; | %misc.inline; | p)*> -<!ATTLIST address - %attrs; - > - -<!--=================== Horizontal Rule ==================================--> - -<!ELEMENT hr EMPTY> -<!ATTLIST hr - %attrs; - align (left|center|right) #IMPLIED - noshade (noshade) #IMPLIED - size %Pixels; #IMPLIED - width %Length; #IMPLIED - > - -<!--=================== Preformatted Text ================================--> - -<!-- content is %Inline; excluding - "img|object|applet|big|small|sub|sup|font|basefont" --> - -<!ELEMENT pre %pre.content;> -<!ATTLIST pre - %attrs; - width %Number; #IMPLIED - xml:space (preserve) #FIXED 'preserve' - > - -<!--=================== Block-like Quotes ================================--> - -<!ELEMENT blockquote %Flow;> -<!ATTLIST blockquote - %attrs; - cite %URI; #IMPLIED - > - -<!--=================== Text alignment ===================================--> - -<!-- center content --> -<!ELEMENT center %Flow;> -<!ATTLIST center - %attrs; - > - -<!--=================== Inserted/Deleted Text ============================--> - -<!-- - ins/del are allowed in block and inline content, but its - inappropriate to include block content within an ins element - occurring in inline content. ---> -<!ELEMENT ins %Flow;> -<!ATTLIST ins - %attrs; - cite %URI; #IMPLIED - datetime %Datetime; #IMPLIED - > - -<!ELEMENT del %Flow;> -<!ATTLIST del - %attrs; - cite %URI; #IMPLIED - datetime %Datetime; #IMPLIED - > - -<!--================== The Anchor Element ================================--> - -<!-- content is %Inline; except that anchors shouldn't be nested --> - -<!ELEMENT a %a.content;> -<!ATTLIST a - %attrs; - %focus; - charset %Charset; #IMPLIED - type %ContentType; #IMPLIED - name NMTOKEN #IMPLIED - href %URI; #IMPLIED - hreflang %LanguageCode; #IMPLIED - rel %LinkTypes; #IMPLIED - rev %LinkTypes; #IMPLIED - shape %Shape; "rect" - coords %Coords; #IMPLIED - target %FrameTarget; #IMPLIED - > - -<!--===================== Inline Elements ================================--> - -<!ELEMENT span %Inline;> <!-- generic language/style container --> -<!ATTLIST span - %attrs; - > - -<!ELEMENT bdo %Inline;> <!-- I18N BiDi over-ride --> -<!ATTLIST bdo - %coreattrs; - %events; - lang %LanguageCode; #IMPLIED - xml:lang %LanguageCode; #IMPLIED - dir (ltr|rtl) #REQUIRED - > - -<!ELEMENT br EMPTY> <!-- forced line break --> -<!ATTLIST br - %coreattrs; - clear (left|all|right|none) "none" - > - -<!ELEMENT em %Inline;> <!-- emphasis --> -<!ATTLIST em %attrs;> - -<!ELEMENT strong %Inline;> <!-- strong emphasis --> -<!ATTLIST strong %attrs;> - -<!ELEMENT dfn %Inline;> <!-- definitional --> -<!ATTLIST dfn %attrs;> - -<!ELEMENT code %Inline;> <!-- program code --> -<!ATTLIST code %attrs;> - -<!ELEMENT samp %Inline;> <!-- sample --> -<!ATTLIST samp %attrs;> - -<!ELEMENT kbd %Inline;> <!-- something user would type --> -<!ATTLIST kbd %attrs;> - -<!ELEMENT var %Inline;> <!-- variable --> -<!ATTLIST var %attrs;> - -<!ELEMENT cite %Inline;> <!-- citation --> -<!ATTLIST cite %attrs;> - -<!ELEMENT abbr %Inline;> <!-- abbreviation --> -<!ATTLIST abbr %attrs;> - -<!ELEMENT acronym %Inline;> <!-- acronym --> -<!ATTLIST acronym %attrs;> - -<!ELEMENT q %Inline;> <!-- inlined quote --> -<!ATTLIST q - %attrs; - cite %URI; #IMPLIED - > - -<!ELEMENT sub %Inline;> <!-- subscript --> -<!ATTLIST sub %attrs;> - -<!ELEMENT sup %Inline;> <!-- superscript --> -<!ATTLIST sup %attrs;> - -<!ELEMENT tt %Inline;> <!-- fixed pitch font --> -<!ATTLIST tt %attrs;> - -<!ELEMENT i %Inline;> <!-- italic font --> -<!ATTLIST i %attrs;> - -<!ELEMENT b %Inline;> <!-- bold font --> -<!ATTLIST b %attrs;> - -<!ELEMENT big %Inline;> <!-- bigger font --> -<!ATTLIST big %attrs;> - -<!ELEMENT small %Inline;> <!-- smaller font --> -<!ATTLIST small %attrs;> - -<!ELEMENT u %Inline;> <!-- underline --> -<!ATTLIST u %attrs;> - -<!ELEMENT s %Inline;> <!-- strike-through --> -<!ATTLIST s %attrs;> - -<!ELEMENT strike %Inline;> <!-- strike-through --> -<!ATTLIST strike %attrs;> - -<!ELEMENT basefont EMPTY> <!-- base font size --> -<!ATTLIST basefont - id ID #IMPLIED - size CDATA #REQUIRED - color %Color; #IMPLIED - face CDATA #IMPLIED - > - -<!ELEMENT font %Inline;> <!-- local change to font --> -<!ATTLIST font - %coreattrs; - %i18n; - size CDATA #IMPLIED - color %Color; #IMPLIED - face CDATA #IMPLIED - > - -<!--==================== Object ======================================--> -<!-- - object is used to embed objects as part of HTML pages. - param elements should precede other content. Parameters - can also be expressed as attribute/value pairs on the - object element itself when brevity is desired. ---> - -<!ELEMENT object (#PCDATA | param | %block; | form | %inline; | %misc;)*> -<!ATTLIST object - %attrs; - declare (declare) #IMPLIED - classid %URI; #IMPLIED - codebase %URI; #IMPLIED - data %URI; #IMPLIED - type %ContentType; #IMPLIED - codetype %ContentType; #IMPLIED - archive %UriList; #IMPLIED - standby %Text; #IMPLIED - height %Length; #IMPLIED - width %Length; #IMPLIED - usemap %URI; #IMPLIED - name NMTOKEN #IMPLIED - tabindex %Number; #IMPLIED - align %ImgAlign; #IMPLIED - border %Pixels; #IMPLIED - hspace %Pixels; #IMPLIED - vspace %Pixels; #IMPLIED - > - -<!-- - param is used to supply a named property value. - In XML it would seem natural to follow RDF and support an - abbreviated syntax where the param elements are replaced - by attribute value pairs on the object start tag. ---> -<!ELEMENT param EMPTY> -<!ATTLIST param - id ID #IMPLIED - name CDATA #REQUIRED - value CDATA #IMPLIED - valuetype (data|ref|object) "data" - type %ContentType; #IMPLIED - > - -<!--=================== Java applet ==================================--> -<!-- - One of code or object attributes must be present. - Place param elements before other content. ---> -<!ELEMENT applet (#PCDATA | param | %block; | form | %inline; | %misc;)*> -<!ATTLIST applet - %coreattrs; - codebase %URI; #IMPLIED - archive CDATA #IMPLIED - code CDATA #IMPLIED - object CDATA #IMPLIED - alt %Text; #IMPLIED - name NMTOKEN #IMPLIED - width %Length; #REQUIRED - height %Length; #REQUIRED - align %ImgAlign; #IMPLIED - hspace %Pixels; #IMPLIED - vspace %Pixels; #IMPLIED - > - -<!--=================== Images ===========================================--> - -<!-- - To avoid accessibility problems for people who aren't - able to see the image, you should provide a text - description using the alt and longdesc attributes. - In addition, avoid the use of server-side image maps. ---> - -<!ELEMENT img EMPTY> -<!ATTLIST img - %attrs; - src %URI; #REQUIRED - alt %Text; #REQUIRED - name NMTOKEN #IMPLIED - longdesc %URI; #IMPLIED - height %Length; #IMPLIED - width %Length; #IMPLIED - usemap %URI; #IMPLIED - ismap (ismap) #IMPLIED - align %ImgAlign; #IMPLIED - border %Length; #IMPLIED - hspace %Pixels; #IMPLIED - vspace %Pixels; #IMPLIED - > - -<!-- usemap points to a map element which may be in this document - or an external document, although the latter is not widely supported --> - -<!--================== Client-side image maps ============================--> - -<!-- These can be placed in the same document or grouped in a - separate document although this isn't yet widely supported --> - -<!ELEMENT map ((%block; | form | %misc;)+ | area+)> -<!ATTLIST map - %i18n; - %events; - id ID #REQUIRED - class CDATA #IMPLIED - style %StyleSheet; #IMPLIED - title %Text; #IMPLIED - name CDATA #IMPLIED - > - -<!ELEMENT area EMPTY> -<!ATTLIST area - %attrs; - %focus; - shape %Shape; "rect" - coords %Coords; #IMPLIED - href %URI; #IMPLIED - nohref (nohref) #IMPLIED - alt %Text; #REQUIRED - target %FrameTarget; #IMPLIED - > - -<!--================ Forms ===============================================--> - -<!ELEMENT form %form.content;> <!-- forms shouldn't be nested --> - -<!ATTLIST form - %attrs; - action %URI; #REQUIRED - method (get|post) "get" - name NMTOKEN #IMPLIED - enctype %ContentType; "application/x-www-form-urlencoded" - onsubmit %Script; #IMPLIED - onreset %Script; #IMPLIED - accept %ContentTypes; #IMPLIED - accept-charset %Charsets; #IMPLIED - target %FrameTarget; #IMPLIED - > - -<!-- - Each label must not contain more than ONE field - Label elements shouldn't be nested. ---> -<!ELEMENT label %Inline;> -<!ATTLIST label - %attrs; - for IDREF #IMPLIED - accesskey %Character; #IMPLIED - onfocus %Script; #IMPLIED - onblur %Script; #IMPLIED - > - -<!ENTITY % InputType - "(text | password | checkbox | - radio | submit | reset | - file | hidden | image | button)" - > - -<!-- the name attribute is required for all but submit & reset --> - -<!ELEMENT input EMPTY> <!-- form control --> -<!ATTLIST input - %attrs; - %focus; - type %InputType; "text" - name CDATA #IMPLIED - value CDATA #IMPLIED - checked (checked) #IMPLIED - disabled (disabled) #IMPLIED - readonly (readonly) #IMPLIED - size CDATA #IMPLIED - maxlength %Number; #IMPLIED - src %URI; #IMPLIED - alt CDATA #IMPLIED - usemap %URI; #IMPLIED - onselect %Script; #IMPLIED - onchange %Script; #IMPLIED - accept %ContentTypes; #IMPLIED - align %ImgAlign; #IMPLIED - > - -<!ELEMENT select (optgroup|option)+> <!-- option selector --> -<!ATTLIST select - %attrs; - name CDATA #IMPLIED - size %Number; #IMPLIED - multiple (multiple) #IMPLIED - disabled (disabled) #IMPLIED - tabindex %Number; #IMPLIED - onfocus %Script; #IMPLIED - onblur %Script; #IMPLIED - onchange %Script; #IMPLIED - > - -<!ELEMENT optgroup (option)+> <!-- option group --> -<!ATTLIST optgroup - %attrs; - disabled (disabled) #IMPLIED - label %Text; #REQUIRED - > - -<!ELEMENT option (#PCDATA)> <!-- selectable choice --> -<!ATTLIST option - %attrs; - selected (selected) #IMPLIED - disabled (disabled) #IMPLIED - label %Text; #IMPLIED - value CDATA #IMPLIED - > - -<!ELEMENT textarea (#PCDATA)> <!-- multi-line text field --> -<!ATTLIST textarea - %attrs; - %focus; - name CDATA #IMPLIED - rows %Number; #REQUIRED - cols %Number; #REQUIRED - disabled (disabled) #IMPLIED - readonly (readonly) #IMPLIED - onselect %Script; #IMPLIED - onchange %Script; #IMPLIED - > - -<!-- - The fieldset element is used to group form fields. - Only one legend element should occur in the content - and if present should only be preceded by whitespace. ---> -<!ELEMENT fieldset (#PCDATA | legend | %block; | form | %inline; | %misc;)*> -<!ATTLIST fieldset - %attrs; - > - -<!ENTITY % LAlign "(top|bottom|left|right)"> - -<!ELEMENT legend %Inline;> <!-- fieldset label --> -<!ATTLIST legend - %attrs; - accesskey %Character; #IMPLIED - align %LAlign; #IMPLIED - > - -<!-- - Content is %Flow; excluding a, form, form controls, iframe ---> -<!ELEMENT button %button.content;> <!-- push button --> -<!ATTLIST button - %attrs; - %focus; - name CDATA #IMPLIED - value CDATA #IMPLIED - type (button|submit|reset) "submit" - disabled (disabled) #IMPLIED - > - -<!-- single-line text input control (DEPRECATED) --> -<!ELEMENT isindex EMPTY> -<!ATTLIST isindex - %coreattrs; - %i18n; - prompt %Text; #IMPLIED - > - -<!--======================= Tables =======================================--> - -<!-- Derived from IETF HTML table standard, see [RFC1942] --> - -<!-- - The border attribute sets the thickness of the frame around the - table. The default units are screen pixels. - - The frame attribute specifies which parts of the frame around - the table should be rendered. The values are not the same as - CALS to avoid a name clash with the valign attribute. ---> -<!ENTITY % TFrame "(void|above|below|hsides|lhs|rhs|vsides|box|border)"> - -<!-- - The rules attribute defines which rules to draw between cells: - - If rules is absent then assume: - "none" if border is absent or border="0" otherwise "all" ---> - -<!ENTITY % TRules "(none | groups | rows | cols | all)"> - -<!-- horizontal placement of table relative to document --> -<!ENTITY % TAlign "(left|center|right)"> - -<!-- horizontal alignment attributes for cell contents - - char alignment char, e.g. char=':' - charoff offset for alignment char ---> -<!ENTITY % cellhalign - "align (left|center|right|justify|char) #IMPLIED - char %Character; #IMPLIED - charoff %Length; #IMPLIED" - > - -<!-- vertical alignment attributes for cell contents --> -<!ENTITY % cellvalign - "valign (top|middle|bottom|baseline) #IMPLIED" - > - -<!ELEMENT table - (caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))> -<!ELEMENT caption %Inline;> -<!ELEMENT thead (tr)+> -<!ELEMENT tfoot (tr)+> -<!ELEMENT tbody (tr)+> -<!ELEMENT colgroup (col)*> -<!ELEMENT col EMPTY> -<!ELEMENT tr (th|td)+> -<!ELEMENT th %Flow;> -<!ELEMENT td %Flow;> - -<!ATTLIST table - %attrs; - summary %Text; #IMPLIED - width %Length; #IMPLIED - border %Pixels; #IMPLIED - frame %TFrame; #IMPLIED - rules %TRules; #IMPLIED - cellspacing %Length; #IMPLIED - cellpadding %Length; #IMPLIED - align %TAlign; #IMPLIED - bgcolor %Color; #IMPLIED - > - -<!ENTITY % CAlign "(top|bottom|left|right)"> - -<!ATTLIST caption - %attrs; - align %CAlign; #IMPLIED - > - -<!-- -colgroup groups a set of col elements. It allows you to group -several semantically related columns together. ---> -<!ATTLIST colgroup - %attrs; - span %Number; "1" - width %MultiLength; #IMPLIED - %cellhalign; - %cellvalign; - > - -<!-- - col elements define the alignment properties for cells in - one or more columns. - - The width attribute specifies the width of the columns, e.g. - - width=64 width in screen pixels - width=0.5* relative width of 0.5 - - The span attribute causes the attributes of one - col element to apply to more than one column. ---> -<!ATTLIST col - %attrs; - span %Number; "1" - width %MultiLength; #IMPLIED - %cellhalign; - %cellvalign; - > - -<!-- - Use thead to duplicate headers when breaking table - across page boundaries, or for static headers when - tbody sections are rendered in scrolling panel. - - Use tfoot to duplicate footers when breaking table - across page boundaries, or for static footers when - tbody sections are rendered in scrolling panel. - - Use multiple tbody sections when rules are needed - between groups of table rows. ---> -<!ATTLIST thead - %attrs; - %cellhalign; - %cellvalign; - > - -<!ATTLIST tfoot - %attrs; - %cellhalign; - %cellvalign; - > - -<!ATTLIST tbody - %attrs; - %cellhalign; - %cellvalign; - > - -<!ATTLIST tr - %attrs; - %cellhalign; - %cellvalign; - bgcolor %Color; #IMPLIED - > - -<!-- Scope is simpler than headers attribute for common tables --> -<!ENTITY % Scope "(row|col|rowgroup|colgroup)"> - -<!-- th is for headers, td for data and for cells acting as both --> - -<!ATTLIST th - %attrs; - abbr %Text; #IMPLIED - axis CDATA #IMPLIED - headers IDREFS #IMPLIED - scope %Scope; #IMPLIED - rowspan %Number; "1" - colspan %Number; "1" - %cellhalign; - %cellvalign; - nowrap (nowrap) #IMPLIED - bgcolor %Color; #IMPLIED - width %Length; #IMPLIED - height %Length; #IMPLIED - > - -<!ATTLIST td - %attrs; - abbr %Text; #IMPLIED - axis CDATA #IMPLIED - headers IDREFS #IMPLIED - scope %Scope; #IMPLIED - rowspan %Number; "1" - colspan %Number; "1" - %cellhalign; - %cellvalign; - nowrap (nowrap) #IMPLIED - bgcolor %Color; #IMPLIED - width %Length; #IMPLIED - height %Length; #IMPLIED - > - diff --git a/lib/erl_docgen/priv/docbuilder_dtd/Makefile b/lib/erl_docgen/priv/dtd/Makefile index e2214107cb..9454147258 100644 --- a/lib/erl_docgen/priv/docbuilder_dtd/Makefile +++ b/lib/erl_docgen/priv/dtd/Makefile @@ -62,7 +62,9 @@ DTD_FILES = \ fascicules.dtd \ terms.dtd - +ENT_FILES = \ + xhtml-special.ent \ + xhtml-symbol.ent # ---------------------------------------------------- # FLAGS @@ -87,8 +89,8 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv/docbuilder_dtd - $(INSTALL_DATA) $(DTD_FILES) $(RELSYSDIR)/priv/docbuilder_dtd + $(INSTALL_DIR) $(RELSYSDIR)/priv/dtd + $(INSTALL_DATA) $(DTD_FILES) $(ENT_FILES) $(RELSYSDIR)/priv/dtd release_docs_spec: diff --git a/lib/docbuilder/dtd/application.dtd b/lib/erl_docgen/priv/dtd/application.dtd index 8a1e8832ec..8a1e8832ec 100644 --- a/lib/docbuilder/dtd/application.dtd +++ b/lib/erl_docgen/priv/dtd/application.dtd diff --git a/lib/docbuilder/dtd/appref.dtd b/lib/erl_docgen/priv/dtd/appref.dtd index 70a5ff37af..70a5ff37af 100644 --- a/lib/docbuilder/dtd/appref.dtd +++ b/lib/erl_docgen/priv/dtd/appref.dtd diff --git a/lib/docbuilder/dtd/book.dtd b/lib/erl_docgen/priv/dtd/book.dtd index bb89a6d255..bb89a6d255 100644 --- a/lib/docbuilder/dtd/book.dtd +++ b/lib/erl_docgen/priv/dtd/book.dtd diff --git a/lib/docbuilder/dtd/bookinsidecover.dtd b/lib/erl_docgen/priv/dtd/bookinsidecover.dtd index d6efbef6a4..d6efbef6a4 100644 --- a/lib/docbuilder/dtd/bookinsidecover.dtd +++ b/lib/erl_docgen/priv/dtd/bookinsidecover.dtd diff --git a/lib/docbuilder/dtd/chapter.dtd b/lib/erl_docgen/priv/dtd/chapter.dtd index eb2c96b04f..eb2c96b04f 100644 --- a/lib/docbuilder/dtd/chapter.dtd +++ b/lib/erl_docgen/priv/dtd/chapter.dtd diff --git a/lib/docbuilder/dtd/cites.dtd b/lib/erl_docgen/priv/dtd/cites.dtd index 334574bff9..334574bff9 100644 --- a/lib/docbuilder/dtd/cites.dtd +++ b/lib/erl_docgen/priv/dtd/cites.dtd diff --git a/lib/erl_docgen/priv/docbuilder_dtd/common.dtd b/lib/erl_docgen/priv/dtd/common.dtd index fdc02c55a1..fdc02c55a1 100644 --- a/lib/erl_docgen/priv/docbuilder_dtd/common.dtd +++ b/lib/erl_docgen/priv/dtd/common.dtd diff --git a/lib/docbuilder/dtd/common.entities.dtd b/lib/erl_docgen/priv/dtd/common.entities.dtd index f893ecd070..f893ecd070 100644 --- a/lib/docbuilder/dtd/common.entities.dtd +++ b/lib/erl_docgen/priv/dtd/common.entities.dtd diff --git a/lib/docbuilder/dtd/common.header.dtd b/lib/erl_docgen/priv/dtd/common.header.dtd index d422a89693..d422a89693 100644 --- a/lib/docbuilder/dtd/common.header.dtd +++ b/lib/erl_docgen/priv/dtd/common.header.dtd diff --git a/lib/docbuilder/dtd/common.image.dtd b/lib/erl_docgen/priv/dtd/common.image.dtd index fc95a669dd..fc95a669dd 100644 --- a/lib/docbuilder/dtd/common.image.dtd +++ b/lib/erl_docgen/priv/dtd/common.image.dtd diff --git a/lib/erl_docgen/priv/docbuilder_dtd/common.refs.dtd b/lib/erl_docgen/priv/dtd/common.refs.dtd index c1237766e1..c1237766e1 100644 --- a/lib/erl_docgen/priv/docbuilder_dtd/common.refs.dtd +++ b/lib/erl_docgen/priv/dtd/common.refs.dtd diff --git a/lib/docbuilder/dtd/common.table.dtd b/lib/erl_docgen/priv/dtd/common.table.dtd index 7741da1018..7741da1018 100644 --- a/lib/docbuilder/dtd/common.table.dtd +++ b/lib/erl_docgen/priv/dtd/common.table.dtd diff --git a/lib/docbuilder/dtd/comref.dtd b/lib/erl_docgen/priv/dtd/comref.dtd index fcdea625d5..fcdea625d5 100644 --- a/lib/docbuilder/dtd/comref.dtd +++ b/lib/erl_docgen/priv/dtd/comref.dtd diff --git a/lib/docbuilder/dtd/cref.dtd b/lib/erl_docgen/priv/dtd/cref.dtd index e43bb2bf51..e43bb2bf51 100644 --- a/lib/docbuilder/dtd/cref.dtd +++ b/lib/erl_docgen/priv/dtd/cref.dtd diff --git a/lib/erl_docgen/priv/docbuilder_dtd/erlref.dtd b/lib/erl_docgen/priv/dtd/erlref.dtd index 9905086ff4..9905086ff4 100644 --- a/lib/erl_docgen/priv/docbuilder_dtd/erlref.dtd +++ b/lib/erl_docgen/priv/dtd/erlref.dtd diff --git a/lib/docbuilder/dtd/fascicules.dtd b/lib/erl_docgen/priv/dtd/fascicules.dtd index b14276a2c0..b14276a2c0 100644 --- a/lib/docbuilder/dtd/fascicules.dtd +++ b/lib/erl_docgen/priv/dtd/fascicules.dtd diff --git a/lib/docbuilder/dtd/fileref.dtd b/lib/erl_docgen/priv/dtd/fileref.dtd index 5a1cc54afe..5a1cc54afe 100644 --- a/lib/docbuilder/dtd/fileref.dtd +++ b/lib/erl_docgen/priv/dtd/fileref.dtd diff --git a/lib/docbuilder/dtd/part.dtd b/lib/erl_docgen/priv/dtd/part.dtd index 3f97199042..3f97199042 100644 --- a/lib/docbuilder/dtd/part.dtd +++ b/lib/erl_docgen/priv/dtd/part.dtd diff --git a/lib/docbuilder/dtd/report.dtd b/lib/erl_docgen/priv/dtd/report.dtd index 3d07e6e5a7..3d07e6e5a7 100644 --- a/lib/docbuilder/dtd/report.dtd +++ b/lib/erl_docgen/priv/dtd/report.dtd diff --git a/lib/docbuilder/dtd/terms.dtd b/lib/erl_docgen/priv/dtd/terms.dtd index 6105ec593e..6105ec593e 100644 --- a/lib/docbuilder/dtd/terms.dtd +++ b/lib/erl_docgen/priv/dtd/terms.dtd diff --git a/lib/docbuilder/dtd/xhtml-special.ent b/lib/erl_docgen/priv/dtd/xhtml-special.ent index ca358b2fec..ca358b2fec 100644 --- a/lib/docbuilder/dtd/xhtml-special.ent +++ b/lib/erl_docgen/priv/dtd/xhtml-special.ent diff --git a/lib/docbuilder/dtd/xhtml-symbol.ent b/lib/erl_docgen/priv/dtd/xhtml-symbol.ent index 63c2abfa6f..63c2abfa6f 100644 --- a/lib/docbuilder/dtd/xhtml-symbol.ent +++ b/lib/erl_docgen/priv/dtd/xhtml-symbol.ent diff --git a/lib/docbuilder/dtd/xhtml1-frameset.dtd b/lib/erl_docgen/priv/dtd/xhtml1-frameset.dtd index d128f2eb7c..d128f2eb7c 100644 --- a/lib/docbuilder/dtd/xhtml1-frameset.dtd +++ b/lib/erl_docgen/priv/dtd/xhtml1-frameset.dtd diff --git a/lib/docbuilder/dtd/xhtml1-strict.dtd b/lib/erl_docgen/priv/dtd/xhtml1-strict.dtd index 2927b9ece7..2927b9ece7 100644 --- a/lib/docbuilder/dtd/xhtml1-strict.dtd +++ b/lib/erl_docgen/priv/dtd/xhtml1-strict.dtd diff --git a/lib/docbuilder/dtd/xhtml1-transitional.dtd b/lib/erl_docgen/priv/dtd/xhtml1-transitional.dtd index 628f27ac50..628f27ac50 100644 --- a/lib/docbuilder/dtd/xhtml1-transitional.dtd +++ b/lib/erl_docgen/priv/dtd/xhtml1-transitional.dtd diff --git a/lib/erl_docgen/priv/xsl/db_eix.xsl b/lib/erl_docgen/priv/xsl/db_eix.xsl index 7a648ddfd7..249e6950f7 100644 --- a/lib/erl_docgen/priv/xsl/db_eix.xsl +++ b/lib/erl_docgen/priv/xsl/db_eix.xsl @@ -106,10 +106,14 @@ <xsl:choose> <!-- @arity is mandatory when referring to a specification --> <xsl:when test="string-length(@arity) > 0"> - <xsl:call-template name="spec_name"/> + <xsl:call-template name="spec_name"> + <xsl:with-param name="lastfuncsblock" select="$lastfuncsblock"/> + </xsl:call-template> </xsl:when> <xsl:otherwise> - <xsl:call-template name="name"/> + <xsl:call-template name="name"> + <xsl:with-param name="lastfuncsblock" select="$lastfuncsblock"/> + </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> @@ -324,7 +328,7 @@ <xsl:choose> <xsl:when test="string-length($tmp1) > 0 or starts-with($string, $start)"> <xsl:variable name="tmp2"> - <xsl:value-of select="substring-after($string, $end)"/> + <xsl:value-of select="substring-after(substring-after($string, $start), $end)"/> </xsl:variable> <xsl:variable name="retstring"> <xsl:call-template name="remove-paren"> diff --git a/lib/erl_docgen/priv/xsl/db_html.xsl b/lib/erl_docgen/priv/xsl/db_html.xsl index a9052f29e5..bdef7bfd3d 100644 --- a/lib/erl_docgen/priv/xsl/db_html.xsl +++ b/lib/erl_docgen/priv/xsl/db_html.xsl @@ -2184,7 +2184,7 @@ <xsl:choose> <xsl:when test="string-length($tmp1) > 0 or starts-with($string, $start)"> <xsl:variable name="tmp2"> - <xsl:value-of select="substring-after($string, $end)"/> + <xsl:value-of select="substring-after(substring-after($string, $start), $end)"/> </xsl:variable> <xsl:variable name="retstring"> <xsl:call-template name="remove-paren"> diff --git a/lib/erl_docgen/priv/xsl/db_man.xsl b/lib/erl_docgen/priv/xsl/db_man.xsl index 0aca74bc97..5234ba6bd0 100644 --- a/lib/erl_docgen/priv/xsl/db_man.xsl +++ b/lib/erl_docgen/priv/xsl/db_man.xsl @@ -586,7 +586,15 @@ </xsl:template> <xsl:template match="seealso"> - <xsl:text>\fB</xsl:text><xsl:apply-templates/><xsl:text>\fR\&</xsl:text> + <xsl:choose> + <xsl:when test="ancestor::head"> + <!-- The header of Dialyzer specs --> + <xsl:apply-templates/> + </xsl:when> + <xsl:otherwise> + <xsl:text>\fB</xsl:text><xsl:apply-templates/><xsl:text>\fR\&</xsl:text> + </xsl:otherwise> + </xsl:choose> </xsl:template> <!-- Code --> diff --git a/lib/erl_docgen/priv/xsl/db_pdf.xsl b/lib/erl_docgen/priv/xsl/db_pdf.xsl index 48a7a026c1..4ed4fa14c4 100644 --- a/lib/erl_docgen/priv/xsl/db_pdf.xsl +++ b/lib/erl_docgen/priv/xsl/db_pdf.xsl @@ -1680,7 +1680,7 @@ <xsl:choose> <xsl:when test="string-length($tmp1) > 0 or starts-with($string, $start)"> <xsl:variable name="tmp2"> - <xsl:value-of select="substring-after($string, $end)"/> + <xsl:value-of select="substring-after(substring-after($string, $start), $end)"/> </xsl:variable> <xsl:variable name="retstring"> <xsl:call-template name="remove-paren"> diff --git a/lib/erl_docgen/src/Makefile b/lib/erl_docgen/src/Makefile index 8e81bccd59..4a805697e6 100644 --- a/lib/erl_docgen/src/Makefile +++ b/lib/erl_docgen/src/Makefile @@ -35,7 +35,9 @@ RELSYSDIR = $(RELEASE_PATH)/lib/erl_docgen-$(VSN) # Target Specs # ---------------------------------------------------- MODULES = \ - otp_specs + docgen_otp_specs \ + docgen_edoc_xml_cb \ + docgen_xmerl_xml_cb HRL_FILES = diff --git a/lib/docbuilder/src/docb_edoc_xml_cb.erl b/lib/erl_docgen/src/docgen_edoc_xml_cb.erl index 90491bc007..dc9bc565ee 100644 --- a/lib/docbuilder/src/docb_edoc_xml_cb.erl +++ b/lib/erl_docgen/src/docgen_edoc_xml_cb.erl @@ -15,17 +15,13 @@ %% %% $Id$ %% --module(docb_edoc_xml_cb). +-module(docgen_edoc_xml_cb). -%% This is the EDoc callback module for creating DocBuilder erlref -%% documents (man pages) in XML format, and also a DocBuilder chapter +%% This is the EDoc callback module for creating erlref +%% documents (man pages) in XML format, and also a chapter %% document based on "overview.edoc". %% -%% Usage examples: -%% docb_gen File -%% docb_gen -chapter overview.edoc -%% or (from an Erlang shell) -%% edoc:file(File, [{layout,docb_edoc_xml_cb},{file_suffix,".xml"}, +%% edoc:file(File, [{layout,docgen_edoc_xml_cb},{file_suffix,".xml"}, %% {preprocess,true}]). %% %% The origin of this file is the edoc module otpsgml_layout.erl @@ -43,12 +39,12 @@ module(Element, Opts) -> SortP = proplists:get_value(sort_functions, Opts, true), XML = layout_module(Element, SortP), - xmerl:export_simple([XML], docb_xmerl_xml_cb, []). + xmerl:export_simple([XML], docgen_xmerl_xml_cb, []). %% CHAPTER overview(Element, _Opts) -> XML = layout_chapter(Element), - xmerl:export_simple([XML], docb_xmerl_xml_cb, []). + xmerl:export_simple([XML], docgen_xmerl_xml_cb, []). %%--Internal functions-------------------------------------------------- @@ -433,12 +429,11 @@ otp_xmlify_e(E) -> %% Takes an <a> element and filters the attributes to decide wheather %% its a seealso/url or a marker. %% In the case of a seealso/url, the href part is checked, making -%% sure a .xml/.html file extension is removed (as DocBuilder inserts -%% .html extension when resolving cross references). +%% sure a .xml/.html file extension is removed. %% Also, references to other applications //App has a href attribute -%% value "OTPROOT/..." (due to app_default being set to "OTPROOT" in -%% docb_gen.erl), in this case both href attribute and content must be -%% formatted correctly according to DocBuilder requirements. +%% value "OTPROOT/..." (due to app_default being set to "OTPROOT") +%% , in this case both href attribute and content must be +%% formatted correctly according to requirements. otp_xmlify_a(A) -> [Attr0] = filter_a_attrs(A#xmlElement.attributes), case Attr0 of @@ -521,9 +516,8 @@ otp_xmlify_a_fileref(FileRef1, AppS) -> File; [File, Ext, Marker0] -> %% Here is an awkward solution to an awkward problem - %% The marker automatically inserted by DocBuilder at - %% each function does not seem to work for EDoc generated - %% ERLREFs. + %% The marker automatically inserted at each function + %% does not seem to work for EDoc generated ERLREFs. %% So if the referenced marker is in an ERLREF generated %% by EDoc, keep it "as is", ie "function-arity". %% If the referenced marker is NOT in an ERLREF generated diff --git a/lib/erl_docgen/src/otp_specs.erl b/lib/erl_docgen/src/docgen_otp_specs.erl index edb437a942..3929e66515 100644 --- a/lib/erl_docgen/src/otp_specs.erl +++ b/lib/erl_docgen/src/docgen_otp_specs.erl @@ -17,7 +17,7 @@ %% %CopyrightEnd% %% --module(otp_specs). +-module(docgen_otp_specs). -export([module/2, package/2, overview/2, type/1]). diff --git a/lib/docbuilder/src/docb_xmerl_xml_cb.erl b/lib/erl_docgen/src/docgen_xmerl_xml_cb.erl index 089b8f0c7d..884932ed12 100644 --- a/lib/docbuilder/src/docb_xmerl_xml_cb.erl +++ b/lib/erl_docgen/src/docgen_xmerl_xml_cb.erl @@ -15,11 +15,11 @@ %% %% $Id$ %% --module(docb_xmerl_xml_cb). +-module(docgen_xmerl_xml_cb). -%% This is the callback module for exporting XHTML to a DocBuilder +%% This is the callback module for exporting XHTML to an %% erlref or chapter document in XML format. -%% See docb_edoc_xml_cb.erl for further information. +%% See docgen_edoc_xml_cb.erl for further information. %% %% The origin of this file is the xmerl module xmerl_otpsgml.erl %% written by Ulf Wiger and Richard Carlsson. @@ -83,6 +83,6 @@ is_url("http:"++_) -> true; is_url("../"++_) -> true; is_url(FileRef) -> case filename:extension(FileRef) of - "" -> false; % no extension = xml file, DocBuilder resolves - _Ext -> true % extension, DocBuilder must not resolve + "" -> false; % no extension = xml file + _Ext -> true % extension end. diff --git a/lib/docbuilder/src/docb_xml_check.erl b/lib/erl_docgen/src/docgen_xml_check.erl index 5912e22e7b..892a880269 100644 --- a/lib/docbuilder/src/docb_xml_check.erl +++ b/lib/erl_docgen/src/docgen_xml_check.erl @@ -15,7 +15,7 @@ %% %% $Id$ %% --module(docb_xml_check). +-module(docgen_xml_check). -export([validate/1]). -deprecated([{validate,1,next_major_release}]). @@ -31,7 +31,7 @@ validate(File0) -> end, case filelib:is_regular(File) of true -> - DtdDir = docb_util:dtd_dir(), + DtdDir = filename:join(code:priv_dir(erl_docgen), "dtd"), case catch xmerl_scan:file(File, [{validation,true}, {fetch_path,[DtdDir]}]) of {'EXIT', Error} -> diff --git a/lib/erl_docgen/src/erl_docgen.app.src b/lib/erl_docgen/src/erl_docgen.app.src index 1720464b6d..daad172106 100644 --- a/lib/erl_docgen/src/erl_docgen.app.src +++ b/lib/erl_docgen/src/erl_docgen.app.src @@ -1,7 +1,9 @@ {application, erl_docgen, [{description, "Misc tools for building documentation"}, {vsn, "%VSN%"}, - {modules, [otp_specs + {modules, [docgen_otp_specs, + docgen_edoc_xml_cb, + docgen_xmerl_xml_cb ] }, {registered,[]}, diff --git a/lib/erl_docgen/vsn.mk b/lib/erl_docgen/vsn.mk index 79c8c570bf..dbd7e017b0 100644 --- a/lib/erl_docgen/vsn.mk +++ b/lib/erl_docgen/vsn.mk @@ -1,2 +1,2 @@ -ERL_DOCGEN_VSN = 0.2.6 +ERL_DOCGEN_VSN = 0.3 diff --git a/lib/erl_interface/aclocal.m4 b/lib/erl_interface/aclocal.m4 index 151fd5ea5a..339a15a2bb 120000..100644 --- a/lib/erl_interface/aclocal.m4 +++ b/lib/erl_interface/aclocal.m4 @@ -1 +1,1766 @@ -../../erts/aclocal.m4
\ No newline at end of file +dnl +dnl %CopyrightBegin% +dnl +dnl Copyright Ericsson AB 1998-2011. All Rights Reserved. +dnl +dnl The contents of this file are subject to the Erlang Public License, +dnl Version 1.1, (the "License"); you may not use this file except in +dnl compliance with the License. You should have received a copy of the +dnl Erlang Public License along with this software. If not, it can be +dnl retrieved online at http://www.erlang.org/. +dnl +dnl Software distributed under the License is distributed on an "AS IS" +dnl basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +dnl the License for the specific language governing rights and limitations +dnl under the License. +dnl +dnl %CopyrightEnd% +dnl + +dnl +dnl aclocal.m4 +dnl +dnl Local macros used in configure.in. The Local Macros which +dnl could/should be part of autoconf are prefixed LM_, macros specific +dnl to the Erlang system are prefixed ERL_. +dnl + +AC_DEFUN(LM_PRECIOUS_VARS, +[ + +dnl ERL_TOP +AC_ARG_VAR(ERL_TOP, [Erlang/OTP top source directory]) + +dnl Tools +AC_ARG_VAR(CC, [C compiler]) +AC_ARG_VAR(CFLAGS, [C compiler flags]) +AC_ARG_VAR(STATIC_CFLAGS, [C compiler static flags]) +AC_ARG_VAR(CFLAG_RUNTIME_LIBRARY_PATH, [runtime library path linker flag passed via C compiler]) +AC_ARG_VAR(CPP, [C/C++ preprocessor]) +AC_ARG_VAR(CPPFLAGS, [C/C++ preprocessor flags]) +AC_ARG_VAR(CXX, [C++ compiler]) +AC_ARG_VAR(CXXFLAGS, [C++ compiler flags]) +AC_ARG_VAR(LD, [linker (is often overridden by configure)]) +AC_ARG_VAR(LDFLAGS, [linker flags (can be risky to set since LD may be overriden by configure)]) +AC_ARG_VAR(LIBS, [libraries]) +AC_ARG_VAR(DED_LD, [linker for Dynamic Erlang Drivers (set all DED_LD* variables or none)]) +AC_ARG_VAR(DED_LDFLAGS, [linker flags for Dynamic Erlang Drivers (set all DED_LD* variables or none)]) +AC_ARG_VAR(DED_LD_FLAG_RUNTIME_LIBRARY_PATH, [runtime library path linker flag for Dynamic Erlang Drivers (set all DED_LD* variables or none)]) +AC_ARG_VAR(LFS_CFLAGS, [large file support C compiler flags (set all LFS_* variables or none)]) +AC_ARG_VAR(LFS_LDFLAGS, [large file support linker flags (set all LFS_* variables or none)]) +AC_ARG_VAR(LFS_LIBS, [large file support libraries (set all LFS_* variables or none)]) +AC_ARG_VAR(RANLIB, [ranlib]) +AC_ARG_VAR(AR, [ar]) +AC_ARG_VAR(GETCONF, [getconf]) + +dnl Cross system root +AC_ARG_VAR(erl_xcomp_sysroot, [Absolute cross system root path (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_isysroot, [Absolute cross system root include path (only used when cross compiling)]) + +dnl Cross compilation variables +AC_ARG_VAR(erl_xcomp_bigendian, [big endian system: yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_linux_clock_gettime_correction, [clock_gettime() can be used for time correction: yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_linux_nptl, [have Native POSIX Thread Library: yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_linux_usable_sigusrx, [SIGUSR1 and SIGUSR2 can be used: yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_linux_usable_sigaltstack, [have working sigaltstack(): yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_poll, [have working poll(): yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_kqueue, [have working kqueue(): yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_putenv_copy, [putenv() stores key-value copy: yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_reliable_fpe, [have reliable floating point exceptions: yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_getaddrinfo, [have working getaddrinfo() for both IPv4 and IPv6: yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_gethrvtime_procfs_ioctl, [have working gethrvtime() which can be used with procfs ioctl(): yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_clock_gettime_cpu_time, [clock_gettime() can be used for retrieving process CPU time: yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_after_morecore_hook, [__after_morecore_hook can track malloc()s core memory usage: yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_dlsym_brk_wrappers, [dlsym(RTLD_NEXT, _) brk wrappers can track malloc()s core memory usage: yes|no (only used when cross compiling)]) + +]) + +AC_DEFUN(ERL_XCOMP_SYSROOT_INIT, +[ +erl_xcomp_without_sysroot=no +if test "$cross_compiling" = "yes"; then + test "$erl_xcomp_sysroot" != "" || erl_xcomp_without_sysroot=yes + test "$erl_xcomp_isysroot" != "" || erl_xcomp_isysroot="$erl_xcomp_sysroot" +else + erl_xcomp_sysroot= + erl_xcomp_isysroot= +fi +]) + +AC_DEFUN(LM_CHECK_GETCONF, +[ +if test "$cross_compiling" != "yes"; then + AC_CHECK_PROG([GETCONF], [getconf], [getconf], [false]) +else + dnl First check if we got a `<HOST>-getconf' in $PATH + host_getconf="$host_alias-getconf" + AC_CHECK_PROG([GETCONF], [$host_getconf], [$host_getconf], [false]) + if test "$GETCONF" = "false" && test "$erl_xcomp_sysroot" != ""; then + dnl We should perhaps give up if we have'nt found it by now, but at + dnl least in one Tilera MDE `getconf' under sysroot is a bourne + dnl shell script which we can use. We try to find `<HOST>-getconf' + dnl or `getconf' under sysconf, but only under sysconf since + dnl `getconf' in $PATH is almost guaranteed to be for the build + dnl machine. + GETCONF= + prfx="$erl_xcomp_sysroot" + AC_PATH_TOOL([GETCONF], [getconf], [false], + ["$prfx/usr/bin:$prfx/bin:$prfx/usr/local/bin"]) + fi +fi +]) + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_WINDOWS_ENVIRONMENT +dnl +dnl +dnl Tries to determine thw windows build environment, i.e. +dnl MIXED_CYGWIN_VC or MIXED_MSYS_VC +dnl + +AC_DEFUN(LM_WINDOWS_ENVIRONMENT, +[ +MIXED_CYGWIN=no +MIXED_MSYS=no + +AC_MSG_CHECKING(for mixed cygwin or msys and native VC++ environment) +if test "X$host" = "Xwin32" -a "x$GCC" != "xyes"; then + if test -x /usr/bin/cygpath; then + CFLAGS="-O2" + MIXED_CYGWIN=yes + AC_MSG_RESULT([Cygwin and VC]) + MIXED_CYGWIN_VC=yes + CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_VC" + elif test -x /usr/bin/msysinfo; then + CFLAGS="-O2" + MIXED_MSYS=yes + AC_MSG_RESULT([MSYS and VC]) + MIXED_MSYS_VC=yes + CPPFLAGS="$CPPFLAGS -DERTS_MIXED_MSYS_VC" + else + AC_MSG_RESULT([undeterminable]) + AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!) + fi +else + AC_MSG_RESULT([no]) + MIXED_CYGWIN_VC=no + MIXED_MSYS_VC=no +fi +AC_SUBST(MIXED_CYGWIN_VC) +AC_SUBST(MIXED_MSYS_VC) + +MIXED_VC=no +if test "x$MIXED_MSYS_VC" = "xyes" -o "x$MIXED_CYGWIN_VC" = "xyes" ; then + MIXED_VC=yes +fi + +AC_SUBST(MIXED_VC) + +if test "x$MIXED_MSYS" != "xyes"; then + AC_MSG_CHECKING(for mixed cygwin and native MinGW environment) + if test "X$host" = "Xwin32" -a "x$GCC" = x"yes"; then + if test -x /usr/bin/cygpath; then + CFLAGS="-O2" + MIXED_CYGWIN=yes + AC_MSG_RESULT([yes]) + MIXED_CYGWIN_MINGW=yes + CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_MINGW" + else + AC_MSG_RESULT([undeterminable]) + AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!) + fi + else + AC_MSG_RESULT([no]) + MIXED_CYGWIN_MINGW=no + fi +else + MIXED_CYGWIN_MINGW=no +fi +AC_SUBST(MIXED_CYGWIN_MINGW) + +AC_MSG_CHECKING(if we mix cygwin with any native compiler) +if test "X$MIXED_CYGWIN" = "Xyes"; then + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + +AC_SUBST(MIXED_CYGWIN) + +AC_MSG_CHECKING(if we mix msys with another native compiler) +if test "X$MIXED_MSYS" = "Xyes" ; then + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + +AC_SUBST(MIXED_MSYS) +]) + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_FIND_EMU_CC +dnl +dnl +dnl Tries fairly hard to find a C compiler that can handle jump tables. +dnl Defines the @EMU_CC@ variable for the makefiles and +dnl inserts NO_JUMP_TABLE in the header if one cannot be found... +dnl + +AC_DEFUN(LM_FIND_EMU_CC, + [AC_CACHE_CHECK(for a compiler that handles jumptables, + ac_cv_prog_emu_cc, + [ +AC_TRY_COMPILE([],[ +#if defined(__clang_major__) && __clang_major__ >= 3 + /* clang 3.x or later is fine */ +#elif defined(__llvm__) +#error "this version of llvm is unable to correctly compile beam_emu.c" +#endif + __label__ lbl1; + __label__ lbl2; + int x = magic(); + static void *jtab[2]; + + jtab[0] = &&lbl1; + jtab[1] = &&lbl2; + goto *jtab[x]; +lbl1: + return 1; +lbl2: + return 2; +],ac_cv_prog_emu_cc=$CC,ac_cv_prog_emu_cc=no) + +if test $ac_cv_prog_emu_cc = no; then + for ac_progname in emu_cc.sh gcc-4.2 gcc; do + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_progname; then + ac_cv_prog_emu_cc=$ac_dir/$ac_progname + break + fi + done + IFS="$ac_save_ifs" + if test $ac_cv_prog_emu_cc != no; then + break + fi + done +fi + +if test $ac_cv_prog_emu_cc != no; then + save_CC=$CC + save_CFLAGS=$CFLAGS + save_CPPFLAGS=$CPPFLAGS + CC=$ac_cv_prog_emu_cc + CFLAGS="" + CPPFLAGS="" + AC_TRY_COMPILE([],[ +#if defined(__clang_major__) && __clang_major__ >= 3 + /* clang 3.x or later is fine */ +#elif defined(__llvm__) +#error "this version of llvm is unable to correctly compile beam_emu.c" +#endif + __label__ lbl1; + __label__ lbl2; + int x = magic(); + static void *jtab[2]; + + jtab[0] = &&lbl1; + jtab[1] = &&lbl2; + goto *jtab[x]; + lbl1: + return 1; + lbl2: + return 2; + ],ac_cv_prog_emu_cc=$CC,ac_cv_prog_emu_cc=no) + CC=$save_CC + CFLAGS=$save_CFLAGS + CPPFLAGS=$save_CPPFLAGS +fi +]) +if test $ac_cv_prog_emu_cc = no; then + AC_DEFINE(NO_JUMP_TABLE,[],[Defined if no found C compiler can handle jump tables]) + EMU_CC=$CC +else + EMU_CC=$ac_cv_prog_emu_cc +fi +AC_SUBST(EMU_CC) +]) + + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_PROG_INSTALL_DIR +dnl +dnl This macro may be used by any OTP application. +dnl +dnl Figure out how to create directories with parents. +dnl (In my opinion INSTALL_DIR is a bad name, MKSUBDIRS or something is better) +dnl +dnl We prefer 'install -d', but use 'mkdir -p' if it exists. +dnl If none of these methods works, we give up. +dnl + + +AC_DEFUN(LM_PROG_INSTALL_DIR, +[AC_CACHE_CHECK(how to create a directory including parents, +ac_cv_prog_mkdir_p, +[ +temp_name_base=config.$$ +temp_name=$temp_name_base/x/y/z +$INSTALL -d $temp_name >/dev/null 2>&1 +ac_cv_prog_mkdir_p=none +if test -d $temp_name; then + ac_cv_prog_mkdir_p="$INSTALL -d" +else + mkdir -p $temp_name >/dev/null 2>&1 + if test -d $temp_name; then + ac_cv_prog_mkdir_p="mkdir -p" + fi +fi +rm -fr $temp_name_base +]) + +case "${ac_cv_prog_mkdir_p}" in + none) AC_MSG_ERROR(don't know how create directories with parents) ;; + *) INSTALL_DIR="$ac_cv_prog_mkdir_p" AC_SUBST(INSTALL_DIR) ;; +esac +]) + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_PROG_PERL5 +dnl +dnl Try to find perl version 5. If found set PERL to the absolute path +dnl of the program, if not found set PERL to false. +dnl +dnl On some systems /usr/bin/perl is perl 4 and e.g. +dnl /usr/local/bin/perl is perl 5. We try to handle this case by +dnl putting a couple of +dnl Tries to handle the case that there are two programs called perl +dnl in the path and one of them is perl 5 and the other isn't. +dnl +AC_DEFUN(LM_PROG_PERL5, +[AC_PATH_PROGS(PERL, perl5 perl, false, + /usr/local/bin:/opt/local/bin:/usr/local/gnu/bin:${PATH}) +changequote(, )dnl +dnl[ That bracket is needed to balance the right bracket below +if test "$PERL" = "false" || $PERL -e 'exit ($] >= 5)'; then +changequote([, ])dnl + ac_cv_path_PERL=false + PERL=false +dnl AC_MSG_WARN(perl version 5 not found) +fi +])dnl + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_DECL_SO_BSDCOMPAT +dnl +dnl Check if the system has the SO_BSDCOMPAT flag on sockets (linux) +dnl +AC_DEFUN(LM_DECL_SO_BSDCOMPAT, +[AC_CACHE_CHECK([for SO_BSDCOMPAT declaration], ac_cv_decl_so_bsdcompat, +AC_TRY_COMPILE([#include <sys/socket.h>], [int i = SO_BSDCOMPAT;], + ac_cv_decl_so_bsdcompat=yes, + ac_cv_decl_so_bsdcompat=no)) + +case "${ac_cv_decl_so_bsdcompat}" in + "yes" ) AC_DEFINE(HAVE_SO_BSDCOMPAT,[], + [Define if you have SO_BSDCOMPAT flag on sockets]) ;; + * ) ;; +esac +]) + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_DECL_INADDR_LOOPBACK +dnl +dnl Try to find declaration of INADDR_LOOPBACK, if nowhere provide a default +dnl + +AC_DEFUN(LM_DECL_INADDR_LOOPBACK, +[AC_CACHE_CHECK([for INADDR_LOOPBACK in netinet/in.h], + ac_cv_decl_inaddr_loopback, +[AC_TRY_COMPILE([#include <sys/types.h> +#include <netinet/in.h>], [int i = INADDR_LOOPBACK;], +ac_cv_decl_inaddr_loopback=yes, ac_cv_decl_inaddr_loopback=no) +]) + +if test ${ac_cv_decl_inaddr_loopback} = no; then + AC_CACHE_CHECK([for INADDR_LOOPBACK in rpc/types.h], + ac_cv_decl_inaddr_loopback_rpc, + AC_TRY_COMPILE([#include <rpc/types.h>], + [int i = INADDR_LOOPBACK;], + ac_cv_decl_inaddr_loopback_rpc=yes, + ac_cv_decl_inaddr_loopback_rpc=no)) + + case "${ac_cv_decl_inaddr_loopback_rpc}" in + "yes" ) + AC_DEFINE(DEF_INADDR_LOOPBACK_IN_RPC_TYPES_H,[], + [Define if you need to include rpc/types.h to get INADDR_LOOPBACK defined]) ;; + * ) + AC_CACHE_CHECK([for INADDR_LOOPBACK in winsock2.h], + ac_cv_decl_inaddr_loopback_winsock2, + AC_TRY_COMPILE([#define WIN32_LEAN_AND_MEAN + #include <winsock2.h>], + [int i = INADDR_LOOPBACK;], + ac_cv_decl_inaddr_loopback_winsock2=yes, + ac_cv_decl_inaddr_loopback_winsock2=no)) + case "${ac_cv_decl_inaddr_loopback_winsock2}" in + "yes" ) + AC_DEFINE(DEF_INADDR_LOOPBACK_IN_WINSOCK2_H,[], + [Define if you need to include winsock2.h to get INADDR_LOOPBACK defined]) ;; + * ) + # couldn't find it anywhere + AC_DEFINE(HAVE_NO_INADDR_LOOPBACK,[], + [Define if you don't have a definition of INADDR_LOOPBACK]) ;; + esac;; + esac +fi +]) + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_STRUCT_SOCKADDR_SA_LEN +dnl +dnl Check if the sockaddr structure has the field sa_len +dnl + +AC_DEFUN(LM_STRUCT_SOCKADDR_SA_LEN, +[AC_CACHE_CHECK([whether struct sockaddr has sa_len field], + ac_cv_struct_sockaddr_sa_len, +AC_TRY_COMPILE([#include <sys/types.h> +#include <sys/socket.h>], [struct sockaddr s; s.sa_len = 10;], + ac_cv_struct_sockaddr_sa_len=yes, ac_cv_struct_sockaddr_sa_len=no)) + +dnl FIXME convbreak +case ${ac_cv_struct_sockaddr_sa_len} in + "no" ) AC_DEFINE(NO_SA_LEN,[1],[Define if you dont have salen]) ;; + *) ;; +esac +]) + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_STRUCT_EXCEPTION +dnl +dnl Check to see whether the system supports the matherr function +dnl and its associated type "struct exception". +dnl + +AC_DEFUN(LM_STRUCT_EXCEPTION, +[AC_CACHE_CHECK([for struct exception (and matherr function)], + ac_cv_struct_exception, +AC_TRY_COMPILE([#include <math.h>], + [struct exception x; x.type = DOMAIN; x.type = SING;], + ac_cv_struct_exception=yes, ac_cv_struct_exception=no)) + +case "${ac_cv_struct_exception}" in + "yes" ) AC_DEFINE(USE_MATHERR,[1],[Define if you have matherr() function and struct exception type]) ;; + * ) ;; +esac +]) + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_SYS_IPV6 +dnl +dnl Check for ipv6 support and what the in6_addr structure is called. +dnl (early linux used in_addr6 insted of in6_addr) +dnl + +AC_DEFUN(LM_SYS_IPV6, +[AC_MSG_CHECKING(for IP version 6 support) +AC_CACHE_VAL(ac_cv_sys_ipv6_support, +[ok_so_far=yes + AC_TRY_COMPILE([#include <sys/types.h> +#ifdef __WIN32__ +#include <winsock2.h> +#include <ws2tcpip.h> +#else +#include <netinet/in.h> +#endif], + [struct in6_addr a6; struct sockaddr_in6 s6;], ok_so_far=yes, ok_so_far=no) + +if test $ok_so_far = yes; then + ac_cv_sys_ipv6_support=yes +else + AC_TRY_COMPILE([#include <sys/types.h> +#ifdef __WIN32__ +#include <winsock2.h> +#include <ws2tcpip.h> +#else +#include <netinet/in.h> +#endif], + [struct in_addr6 a6; struct sockaddr_in6 s6;], + ac_cv_sys_ipv6_support=in_addr6, ac_cv_sys_ipv6_support=no) +fi +])dnl + +dnl +dnl Have to use old style AC_DEFINE due to BC with old autoconf. +dnl + +case ${ac_cv_sys_ipv6_support} in + yes) + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_IN6,[1],[Define if ipv6 is present]) + ;; + in_addr6) + AC_MSG_RESULT([yes (but I am redefining in_addr6 to in6_addr)]) + AC_DEFINE(HAVE_IN6,[1],[Define if ipv6 is present]) + AC_DEFINE(HAVE_IN_ADDR6_STRUCT,[],[Early linux used in_addr6 instead of in6_addr, define if you have this]) + ;; + *) + AC_MSG_RESULT(no) + ;; +esac +]) + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_SYS_MULTICAST +dnl +dnl Check for multicast support. Only checks for multicast options in +dnl setsockopt(), no check is performed that multicasting actually works. +dnl If options are found defines HAVE_MULTICAST_SUPPORT +dnl + +AC_DEFUN(LM_SYS_MULTICAST, +[AC_CACHE_CHECK([for multicast support], ac_cv_sys_multicast_support, +[AC_EGREP_CPP(yes, +[#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#if defined(IP_MULTICAST_TTL) && defined(IP_MULTICAST_LOOP) && defined(IP_MULTICAST_IF) && defined(IP_ADD_MEMBERSHIP) && defined(IP_DROP_MEMBERSHIP) +yes +#endif +], ac_cv_sys_multicast_support=yes, ac_cv_sys_multicast_support=no)]) +if test $ac_cv_sys_multicast_support = yes; then + AC_DEFINE(HAVE_MULTICAST_SUPPORT,[1], + [Define if setsockopt() accepts multicast options]) +fi +])dnl + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_DECL_SYS_ERRLIST +dnl +dnl Define SYS_ERRLIST_DECLARED if the variable sys_errlist is declared +dnl in a system header file, stdio.h or errno.h. +dnl + +AC_DEFUN(LM_DECL_SYS_ERRLIST, +[AC_CACHE_CHECK([for sys_errlist declaration in stdio.h or errno.h], + ac_cv_decl_sys_errlist, +[AC_TRY_COMPILE([#include <stdio.h> +#include <errno.h>], [char *msg = *(sys_errlist + 1);], + ac_cv_decl_sys_errlist=yes, ac_cv_decl_sys_errlist=no)]) +if test $ac_cv_decl_sys_errlist = yes; then + AC_DEFINE(SYS_ERRLIST_DECLARED,[], + [define if the variable sys_errlist is declared in a system header file]) +fi +]) + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_CHECK_FUNC_DECL( funname, declaration [, extra includes +dnl [, action-if-found [, action-if-not-found]]] ) +dnl +dnl Checks if the declaration "declaration" of "funname" conflicts +dnl with the header files idea of how the function should be +dnl declared. It is useful on systems which lack prototypes and you +dnl need to provide your own (e.g. when you want to take the address +dnl of a function). The 4'th argument is expanded if conflicting, +dnl the 5'th argument otherwise +dnl +dnl + +AC_DEFUN(LM_CHECK_FUNC_DECL, +[AC_MSG_CHECKING([for conflicting declaration of $1]) +AC_CACHE_VAL(ac_cv_func_decl_$1, +[AC_TRY_COMPILE([#include <stdio.h> +$3],[$2 +char *c = (char *)$1; +], eval "ac_cv_func_decl_$1=no", eval "ac_cv_func_decl_$1=yes")]) +if eval "test \"`echo '$ac_cv_func_decl_'$1`\" = yes"; then + AC_MSG_RESULT(yes) + ifelse([$4], , :, [$4]) +else + AC_MSG_RESULT(no) +ifelse([$5], , , [$5 +])dnl +fi +]) + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_CHECK_THR_LIB +dnl +dnl This macro may be used by any OTP application. +dnl +dnl LM_CHECK_THR_LIB sets THR_LIBS, THR_DEFS, and THR_LIB_NAME. It also +dnl checks for some pthread headers which will appear in DEFS or config.h. +dnl + +AC_DEFUN(LM_CHECK_THR_LIB, +[ + +NEED_NPTL_PTHREAD_H=no + +dnl win32? +AC_MSG_CHECKING([for native win32 threads]) +if test "X$host_os" = "Xwin32"; then + AC_MSG_RESULT(yes) + THR_DEFS="-DWIN32_THREADS" + THR_LIBS= + THR_LIB_NAME=win32_threads + THR_LIB_TYPE=win32_threads +else + AC_MSG_RESULT(no) + THR_DEFS= + THR_LIBS= + THR_LIB_NAME= + THR_LIB_TYPE=posix_unknown + +dnl Try to find POSIX threads + +dnl The usual pthread lib... + AC_CHECK_LIB(pthread, pthread_create, THR_LIBS="-lpthread") + +dnl FreeBSD has pthreads in special c library, c_r... + if test "x$THR_LIBS" = "x"; then + AC_CHECK_LIB(c_r, pthread_create, THR_LIBS="-lc_r") + fi + +dnl On ofs1 the '-pthread' switch should be used + if test "x$THR_LIBS" = "x"; then + AC_MSG_CHECKING([if the '-pthread' switch can be used]) + saved_cflags=$CFLAGS + CFLAGS="$CFLAGS -pthread" + AC_TRY_LINK([#include <pthread.h>], + pthread_create((void*)0,(void*)0,(void*)0,(void*)0);, + [THR_DEFS="-pthread" + THR_LIBS="-pthread"]) + CFLAGS=$saved_cflags + if test "x$THR_LIBS" != "x"; then + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + fi + + if test "x$THR_LIBS" != "x"; then + THR_DEFS="$THR_DEFS -D_THREAD_SAFE -D_REENTRANT -DPOSIX_THREADS" + THR_LIB_NAME=pthread + case $host_os in + solaris*) + THR_DEFS="$THR_DEFS -D_POSIX_PTHREAD_SEMANTICS" ;; + linux*) + THR_DEFS="$THR_DEFS -D_POSIX_THREAD_SAFE_FUNCTIONS" + + LM_CHECK_GETCONF + AC_MSG_CHECKING(for Native POSIX Thread Library) + libpthr_vsn=`$GETCONF GNU_LIBPTHREAD_VERSION 2>/dev/null` + if test $? -eq 0; then + case "$libpthr_vsn" in + *nptl*|*NPTL*) nptl=yes;; + *) nptl=no;; + esac + elif test "$cross_compiling" = "yes"; then + case "$erl_xcomp_linux_nptl" in + "") nptl=cross;; + yes|no) nptl=$erl_xcomp_linux_nptl;; + *) AC_MSG_ERROR([Bad erl_xcomp_linux_nptl value: $erl_xcomp_linux_nptl]);; + esac + else + nptl=no + fi + AC_MSG_RESULT($nptl) + if test $nptl = cross; then + nptl=yes + AC_MSG_WARN([result yes guessed because of cross compilation]) + fi + if test $nptl = yes; then + THR_LIB_TYPE=posix_nptl + need_nptl_incldir=no + AC_CHECK_HEADER(nptl/pthread.h, + [need_nptl_incldir=yes + NEED_NPTL_PTHREAD_H=yes]) + if test $need_nptl_incldir = yes; then + # Ahh... + nptl_path="$C_INCLUDE_PATH:$CPATH" + if test X$cross_compiling != Xyes; then + nptl_path="$nptl_path:/usr/local/include:/usr/include" + else + IROOT="$erl_xcomp_isysroot" + test "$IROOT" != "" || IROOT="$erl_xcomp_sysroot" + test "$IROOT" != "" || AC_MSG_ERROR([Don't know where to search for includes! Please set erl_xcomp_isysroot]) + nptl_path="$nptl_path:$IROOT/usr/local/include:$IROOT/usr/include" + fi + nptl_ws_path= + save_ifs="$IFS"; IFS=":" + for dir in $nptl_path; do + if test "x$dir" != "x"; then + nptl_ws_path="$nptl_ws_path $dir" + fi + done + IFS=$save_ifs + nptl_incldir= + for dir in $nptl_ws_path; do + AC_CHECK_HEADER($dir/nptl/pthread.h, + nptl_incldir=$dir/nptl) + if test "x$nptl_incldir" != "x"; then + THR_DEFS="$THR_DEFS -isystem $nptl_incldir" + break + fi + done + if test "x$nptl_incldir" = "x"; then + AC_MSG_ERROR(Failed to locate nptl system include directory) + fi + fi + fi + ;; + *) ;; + esac + + dnl We sometimes need THR_DEFS in order to find certain headers + dnl (at least for pthread.h on osf1). + saved_cppflags=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $THR_DEFS" + + dnl + dnl Check for headers + dnl + + AC_CHECK_HEADER(pthread.h, + AC_DEFINE(HAVE_PTHREAD_H, 1, \ +[Define if you have the <pthread.h> header file.])) + + dnl Some Linuxes have <pthread/mit/pthread.h> instead of <pthread.h> + AC_CHECK_HEADER(pthread/mit/pthread.h, \ + AC_DEFINE(HAVE_MIT_PTHREAD_H, 1, \ +[Define if the pthread.h header file is in pthread/mit directory.])) + + dnl restore CPPFLAGS + CPPFLAGS=$saved_cppflags + + fi +fi + +]) + +AC_DEFUN(ERL_INTERNAL_LIBS, +[ + +ERTS_INTERNAL_X_LIBS= + +AC_CHECK_LIB(kstat, kstat_open, +[AC_DEFINE(HAVE_KSTAT, 1, [Define if you have kstat]) +ERTS_INTERNAL_X_LIBS="$ERTS_INTERNAL_X_LIBS -lkstat"]) + +AC_SUBST(ERTS_INTERNAL_X_LIBS) + +]) + +AC_DEFUN(ETHR_CHK_SYNC_OP, +[ + AC_MSG_CHECKING([for $3-bit $1()]) + case "$2" in + "1") sync_call="$1(&var);";; + "2") sync_call="$1(&var, ($4) 0);";; + "3") sync_call="$1(&var, ($4) 0, ($4) 0);";; + esac + have_sync_op=no + AC_TRY_LINK([], + [ + $4 res; + volatile $4 var; + res = $sync_call + ], + [have_sync_op=yes]) + test $have_sync_op = yes && $5 + AC_MSG_RESULT([$have_sync_op]) +]) + +AC_DEFUN(ETHR_CHK_INTERLOCKED, +[ + ilckd="$1" + AC_MSG_CHECKING([for ${ilckd}()]) + case "$2" in + "1") ilckd_call="${ilckd}(var);";; + "2") ilckd_call="${ilckd}(var, ($3) 0);";; + "3") ilckd_call="${ilckd}(var, ($3) 0, ($3) 0);";; + "4") ilckd_call="${ilckd}(var, ($3) 0, ($3) 0, arr);";; + esac + have_interlocked_op=no + AC_TRY_LINK( + [ + #define WIN32_LEAN_AND_MEAN + #include <windows.h> + #include <intrin.h> + ], + [ + volatile $3 *var; + volatile $3 arr[2]; + + $ilckd_call + return 0; + ], + [have_interlocked_op=yes]) + test $have_interlocked_op = yes && $4 + AC_MSG_RESULT([$have_interlocked_op]) +]) + +dnl ---------------------------------------------------------------------- +dnl +dnl ERL_FIND_ETHR_LIB +dnl +dnl NOTE! This macro may be changed at any time! Should *only* be used by +dnl ERTS! +dnl +dnl Find a thread library to use. Sets ETHR_LIBS to libraries to link +dnl with, ETHR_X_LIBS to extra libraries to link with (same as ETHR_LIBS +dnl except that the ethread lib itself is not included), ETHR_DEFS to +dnl defines to compile with, ETHR_THR_LIB_BASE to the name of the +dnl thread library which the ethread library is based on, and ETHR_LIB_NAME +dnl to the name of the library where the ethread implementation is located. +dnl ERL_FIND_ETHR_LIB currently searches for 'pthreads', and +dnl 'win32_threads'. If no thread library was found ETHR_LIBS, ETHR_X_LIBS, +dnl ETHR_DEFS, ETHR_THR_LIB_BASE, and ETHR_LIB_NAME are all set to the +dnl empty string. +dnl + +AC_DEFUN(ERL_FIND_ETHR_LIB, +[ + +LM_CHECK_THR_LIB +ERL_INTERNAL_LIBS + +ethr_have_native_atomics=no +ethr_have_native_spinlock=no +ETHR_THR_LIB_BASE="$THR_LIB_NAME" +ETHR_THR_LIB_BASE_TYPE="$THR_LIB_TYPE" +ETHR_DEFS="$THR_DEFS" +ETHR_X_LIBS="$THR_LIBS $ERTS_INTERNAL_X_LIBS" +ETHR_LIBS= +ETHR_LIB_NAME= + +ethr_modified_default_stack_size= + +dnl Name of lib where ethread implementation is located +ethr_lib_name=ethread + +case "$THR_LIB_NAME" in + + win32_threads) + ETHR_THR_LIB_BASE_DIR=win + # * _WIN32_WINNT >= 0x0400 is needed for + # TryEnterCriticalSection + # * _WIN32_WINNT >= 0x0403 is needed for + # InitializeCriticalSectionAndSpinCount + # The ethread lib will refuse to build if _WIN32_WINNT < 0x0403. + # + # -D_WIN32_WINNT should have been defined in $CPPFLAGS; fetch it + # and save it in ETHR_DEFS. + found_win32_winnt=no + for cppflag in $CPPFLAGS; do + case $cppflag in + -DWINVER*) + ETHR_DEFS="$ETHR_DEFS $cppflag" + ;; + -D_WIN32_WINNT*) + ETHR_DEFS="$ETHR_DEFS $cppflag" + found_win32_winnt=yes + ;; + *) + ;; + esac + done + if test $found_win32_winnt = no; then + AC_MSG_ERROR([-D_WIN32_WINNT missing in CPPFLAGS]) + fi + + AC_DEFINE(ETHR_WIN32_THREADS, 1, [Define if you have win32 threads]) + + ETHR_CHK_INTERLOCKED([_InterlockedDecrement], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT, 1, [Define if you have _InterlockedDecrement()])) + ETHR_CHK_INTERLOCKED([_InterlockedDecrement_rel], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT_REL, 1, [Define if you have _InterlockedDecrement_rel()])) + ETHR_CHK_INTERLOCKED([_InterlockedIncrement], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT, 1, [Define if you have _InterlockedIncrement()])) + ETHR_CHK_INTERLOCKED([_InterlockedIncrement_acq], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT_ACQ, 1, [Define if you have _InterlockedIncrement_acq()])) + ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD, 1, [Define if you have _InterlockedExchangeAdd()])) + ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd_acq], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD_ACQ, 1, [Define if you have _InterlockedExchangeAdd_acq()])) + ETHR_CHK_INTERLOCKED([_InterlockedAnd], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDAND, 1, [Define if you have _InterlockedAnd()])) + ETHR_CHK_INTERLOCKED([_InterlockedOr], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDOR, 1, [Define if you have _InterlockedOr()])) + ETHR_CHK_INTERLOCKED([_InterlockedExchange], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGE, 1, [Define if you have _InterlockedExchange()])) + ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE, 1, [Define if you have _InterlockedCompareExchange()])) + test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes + ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange_acq], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE_ACQ, 1, [Define if you have _InterlockedCompareExchange_acq()])) + test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes + ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange_rel], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE_REL, 1, [Define if you have _InterlockedCompareExchange_rel()])) + test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes + + ETHR_CHK_INTERLOCKED([_InterlockedDecrement64], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT64, 1, [Define if you have _InterlockedDecrement64()])) + ETHR_CHK_INTERLOCKED([_InterlockedDecrement64_rel], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT64_REL, 1, [Define if you have _InterlockedDecrement64_rel()])) + ETHR_CHK_INTERLOCKED([_InterlockedIncrement64], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT64, 1, [Define if you have _InterlockedIncrement64()])) + ETHR_CHK_INTERLOCKED([_InterlockedIncrement64_acq], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT64_ACQ, 1, [Define if you have _InterlockedIncrement64_acq()])) + ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD64, 1, [Define if you have _InterlockedExchangeAdd64()])) + ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd64_acq], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD64_ACQ, 1, [Define if you have _InterlockedExchangeAdd64_acq()])) + ETHR_CHK_INTERLOCKED([_InterlockedAnd64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDAND64, 1, [Define if you have _InterlockedAnd64()])) + ETHR_CHK_INTERLOCKED([_InterlockedOr64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDOR64, 1, [Define if you have _InterlockedOr64()])) + ETHR_CHK_INTERLOCKED([_InterlockedExchange64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGE64, 1, [Define if you have _InterlockedExchange64()])) + ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64, 1, [Define if you have _InterlockedCompareExchange64()])) + test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes + ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64_acq], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64_ACQ, 1, [Define if you have _InterlockedCompareExchange64_acq()])) + test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes + ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64_rel], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64_REL, 1, [Define if you have _InterlockedCompareExchange64_rel()])) + test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes + + ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange128], [4], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE128, 1, [Define if you have _InterlockedCompareExchange128()])) + + test "$ethr_have_native_atomics" = "yes" && ethr_have_native_spinlock=yes + ;; + + pthread) + ETHR_THR_LIB_BASE_DIR=pthread + AC_DEFINE(ETHR_PTHREADS, 1, [Define if you have pthreads]) + case $host_os in + openbsd*) + # The default stack size is insufficient for our needs + # on OpenBSD. We increase it to 256 kilo words. + ethr_modified_default_stack_size=256;; + linux*) + ETHR_DEFS="$ETHR_DEFS -D_GNU_SOURCE" + + if test X$cross_compiling = Xyes; then + case X$erl_xcomp_linux_usable_sigusrx in + X) usable_sigusrx=cross;; + Xyes|Xno) usable_sigusrx=$erl_xcomp_linux_usable_sigusrx;; + *) AC_MSG_ERROR([Bad erl_xcomp_linux_usable_sigusrx value: $erl_xcomp_linux_usable_sigusrx]);; + esac + case X$erl_xcomp_linux_usable_sigaltstack in + X) usable_sigaltstack=cross;; + Xyes|Xno) usable_sigaltstack=$erl_xcomp_linux_usable_sigaltstack;; + *) AC_MSG_ERROR([Bad erl_xcomp_linux_usable_sigaltstack value: $erl_xcomp_linux_usable_sigaltstack]);; + esac + else + # FIXME: Test for actual problems instead of kernel versions + linux_kernel_vsn_=`uname -r` + case $linux_kernel_vsn_ in + [[0-1]].*|2.[[0-1]]|2.[[0-1]].*) + usable_sigusrx=no + usable_sigaltstack=no;; + 2.[[2-3]]|2.[[2-3]].*) + usable_sigusrx=yes + usable_sigaltstack=no;; + *) + usable_sigusrx=yes + usable_sigaltstack=yes;; + esac + fi + + AC_MSG_CHECKING(if SIGUSR1 and SIGUSR2 can be used) + AC_MSG_RESULT($usable_sigusrx) + if test $usable_sigusrx = cross; then + usable_sigusrx=yes + AC_MSG_WARN([result yes guessed because of cross compilation]) + fi + if test $usable_sigusrx = no; then + ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGUSRX" + fi + + AC_MSG_CHECKING(if sigaltstack can be used) + AC_MSG_RESULT($usable_sigaltstack) + if test $usable_sigaltstack = cross; then + usable_sigaltstack=yes + AC_MSG_WARN([result yes guessed because of cross compilation]) + fi + if test $usable_sigaltstack = no; then + ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGALTSTACK" + fi + ;; + *) ;; + esac + + dnl We sometimes need ETHR_DEFS in order to find certain headers + dnl (at least for pthread.h on osf1). + saved_cppflags="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $ETHR_DEFS" + + dnl We need the thread library in order to find some functions + saved_libs="$LIBS" + LIBS="$LIBS $ETHR_X_LIBS" + + dnl + dnl Check for headers + dnl + + AC_CHECK_HEADER(pthread.h, \ + AC_DEFINE(ETHR_HAVE_PTHREAD_H, 1, \ +[Define if you have the <pthread.h> header file.])) + + dnl Some Linuxes have <pthread/mit/pthread.h> instead of <pthread.h> + AC_CHECK_HEADER(pthread/mit/pthread.h, \ + AC_DEFINE(ETHR_HAVE_MIT_PTHREAD_H, 1, \ +[Define if the pthread.h header file is in pthread/mit directory.])) + + if test $NEED_NPTL_PTHREAD_H = yes; then + AC_DEFINE(ETHR_NEED_NPTL_PTHREAD_H, 1, \ +[Define if you need the <nptl/pthread.h> header file.]) + fi + + AC_CHECK_HEADER(sched.h, \ + AC_DEFINE(ETHR_HAVE_SCHED_H, 1, \ +[Define if you have the <sched.h> header file.])) + + AC_CHECK_HEADER(sys/time.h, \ + AC_DEFINE(ETHR_HAVE_SYS_TIME_H, 1, \ +[Define if you have the <sys/time.h> header file.])) + + AC_TRY_COMPILE([#include <time.h> + #include <sys/time.h>], + [struct timeval *tv; return 0;], + AC_DEFINE(ETHR_TIME_WITH_SYS_TIME, 1, \ +[Define if you can safely include both <sys/time.h> and <time.h>.])) + + + dnl + dnl Check for functions + dnl + + AC_CHECK_FUNC(pthread_spin_lock, \ + [ethr_have_native_spinlock=yes \ + AC_DEFINE(ETHR_HAVE_PTHREAD_SPIN_LOCK, 1, \ +[Define if you have the pthread_spin_lock function.])]) + + have_sched_yield=no + have_librt_sched_yield=no + AC_CHECK_FUNC(sched_yield, [have_sched_yield=yes]) + if test $have_sched_yield = no; then + AC_CHECK_LIB(rt, sched_yield, + [have_librt_sched_yield=yes + ETHR_X_LIBS="$ETHR_X_LIBS -lrt"]) + fi + if test $have_sched_yield = yes || test $have_librt_sched_yield = yes; then + AC_DEFINE(ETHR_HAVE_SCHED_YIELD, 1, [Define if you have the sched_yield() function.]) + AC_MSG_CHECKING([whether sched_yield() returns an int]) + sched_yield_ret_int=no + AC_TRY_COMPILE([ + #ifdef ETHR_HAVE_SCHED_H + #include <sched.h> + #endif + ], + [int sched_yield();], + [sched_yield_ret_int=yes]) + AC_MSG_RESULT([$sched_yield_ret_int]) + if test $sched_yield_ret_int = yes; then + AC_DEFINE(ETHR_SCHED_YIELD_RET_INT, 1, [Define if sched_yield() returns an int.]) + fi + fi + + have_pthread_yield=no + AC_CHECK_FUNC(pthread_yield, [have_pthread_yield=yes]) + if test $have_pthread_yield = yes; then + AC_DEFINE(ETHR_HAVE_PTHREAD_YIELD, 1, [Define if you have the pthread_yield() function.]) + AC_MSG_CHECKING([whether pthread_yield() returns an int]) + pthread_yield_ret_int=no + AC_TRY_COMPILE([ + #if defined(ETHR_NEED_NPTL_PTHREAD_H) + #include <nptl/pthread.h> + #elif defined(ETHR_HAVE_MIT_PTHREAD_H) + #include <pthread/mit/pthread.h> + #elif defined(ETHR_HAVE_PTHREAD_H) + #include <pthread.h> + #endif + ], + [int pthread_yield();], + [pthread_yield_ret_int=yes]) + AC_MSG_RESULT([$pthread_yield_ret_int]) + if test $pthread_yield_ret_int = yes; then + AC_DEFINE(ETHR_PTHREAD_YIELD_RET_INT, 1, [Define if pthread_yield() returns an int.]) + fi + fi + + have_pthread_rwlock_init=no + AC_CHECK_FUNC(pthread_rwlock_init, [have_pthread_rwlock_init=yes]) + if test $have_pthread_rwlock_init = yes; then + + ethr_have_pthread_rwlockattr_setkind_np=no + AC_CHECK_FUNC(pthread_rwlockattr_setkind_np, + [ethr_have_pthread_rwlockattr_setkind_np=yes]) + + if test $ethr_have_pthread_rwlockattr_setkind_np = yes; then + AC_DEFINE(ETHR_HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP, 1, \ +[Define if you have the pthread_rwlockattr_setkind_np() function.]) + + AC_MSG_CHECKING([for PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP]) + ethr_pthread_rwlock_writer_nonrecursive_initializer_np=no + AC_TRY_LINK([ + #if defined(ETHR_NEED_NPTL_PTHREAD_H) + #include <nptl/pthread.h> + #elif defined(ETHR_HAVE_MIT_PTHREAD_H) + #include <pthread/mit/pthread.h> + #elif defined(ETHR_HAVE_PTHREAD_H) + #include <pthread.h> + #endif + ], + [ + pthread_rwlockattr_t *attr; + return pthread_rwlockattr_setkind_np(attr, + PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); + ], + [ethr_pthread_rwlock_writer_nonrecursive_initializer_np=yes]) + AC_MSG_RESULT([$ethr_pthread_rwlock_writer_nonrecursive_initializer_np]) + if test $ethr_pthread_rwlock_writer_nonrecursive_initializer_np = yes; then + AC_DEFINE(ETHR_HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, 1, \ +[Define if you have the PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP rwlock attribute.]) + fi + fi + fi + + if test "$force_pthread_rwlocks" = "yes"; then + + AC_DEFINE(ETHR_FORCE_PTHREAD_RWLOCK, 1, \ +[Define if you want to force usage of pthread rwlocks]) + + if test $have_pthread_rwlock_init = yes; then + AC_MSG_WARN([Forced usage of pthread rwlocks. Note that this implementation may suffer from starvation issues.]) + else + AC_MSG_ERROR([User forced usage of pthread rwlock, but no such implementation was found]) + fi + fi + + AC_CHECK_FUNC(pthread_attr_setguardsize, \ + AC_DEFINE(ETHR_HAVE_PTHREAD_ATTR_SETGUARDSIZE, 1, \ +[Define if you have the pthread_attr_setguardsize function.])) + + linux_futex=no + AC_MSG_CHECKING([for Linux futexes]) + AC_TRY_LINK([ + #include <sys/syscall.h> + #include <unistd.h> + #include <linux/futex.h> + #include <sys/time.h> + ], + [ + int i = 1; + syscall(__NR_futex, (void *) &i, FUTEX_WAKE, 1, + (void*)0,(void*)0, 0); + syscall(__NR_futex, (void *) &i, FUTEX_WAIT, 0, + (void*)0,(void*)0, 0); + return 0; + ], + linux_futex=yes) + AC_MSG_RESULT([$linux_futex]) + test $linux_futex = yes && AC_DEFINE(ETHR_HAVE_LINUX_FUTEX, 1, [Define if you have a linux futex implementation.]) + + AC_CHECK_SIZEOF(int) + AC_CHECK_SIZEOF(long) + AC_CHECK_SIZEOF(long long) + AC_CHECK_SIZEOF(__int128_t) + + if test "$ac_cv_sizeof_int" = "4"; then + int32="int" + elif test "$ac_cv_sizeof_long" = "4"; then + int32="long" + elif test "$ac_cv_sizeof_long_long" = "4"; then + int32="long long" + else + AC_MSG_ERROR([No 32-bit type found]) + fi + + if test "$ac_cv_sizeof_int" = "8"; then + int64="int" + elif test "$ac_cv_sizeof_long" = "8"; then + int64="long" + elif test "$ac_cv_sizeof_long_long" = "8"; then + int64="long long" + else + AC_MSG_ERROR([No 64-bit type found]) + fi + + int128=no + if test "$ac_cv_sizeof___int128_t" = "16"; then + int128="__int128_t" + fi + + ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP32, 1, [Define if you have __sync_val_compare_and_swap() for 32-bit integers])) + test "$have_sync_op" = "yes" && ethr_have_native_atomics=yes + ETHR_CHK_SYNC_OP([__sync_add_and_fetch], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_ADD_AND_FETCH32, 1, [Define if you have __sync_add_and_fetch() for 32-bit integers])) + ETHR_CHK_SYNC_OP([__sync_fetch_and_and], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_AND32, 1, [Define if you have __sync_fetch_and_and() for 32-bit integers])) + ETHR_CHK_SYNC_OP([__sync_fetch_and_or], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_OR32, 1, [Define if you have __sync_fetch_and_or() for 32-bit integers])) + + ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP64, 1, [Define if you have __sync_val_compare_and_swap() for 64-bit integers])) + test "$have_sync_op" = "yes" && ethr_have_native_atomics=yes + ETHR_CHK_SYNC_OP([__sync_add_and_fetch], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_ADD_AND_FETCH64, 1, [Define if you have __sync_add_and_fetch() for 64-bit integers])) + ETHR_CHK_SYNC_OP([__sync_fetch_and_and], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_AND64, 1, [Define if you have __sync_fetch_and_and() for 64-bit integers])) + ETHR_CHK_SYNC_OP([__sync_fetch_and_or], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_OR64, 1, [Define if you have __sync_fetch_and_or() for 64-bit integers])) + + if test $int128 != no; then + ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [128], [$int128], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP128, 1, [Define if you have __sync_val_compare_and_swap() for 128-bit integers])) + fi + + AC_MSG_CHECKING([for a usable libatomic_ops implementation]) + case "x$with_libatomic_ops" in + xno | xyes | x) + libatomic_ops_include= + ;; + *) + if test -d "${with_libatomic_ops}/include"; then + libatomic_ops_include="-I$with_libatomic_ops/include" + CPPFLAGS="$CPPFLAGS $libatomic_ops_include" + else + AC_MSG_ERROR([libatomic_ops include directory $with_libatomic_ops/include not found]) + fi;; + esac + ethr_have_libatomic_ops=no + AC_TRY_LINK([#include "atomic_ops.h"], + [ + volatile AO_t x; + AO_t y; + int z; + + AO_nop_full(); + AO_store(&x, (AO_t) 0); + z = AO_load(&x); + z = AO_compare_and_swap_full(&x, (AO_t) 0, (AO_t) 1); + ], + [ethr_have_native_atomics=yes + ethr_have_libatomic_ops=yes]) + AC_MSG_RESULT([$ethr_have_libatomic_ops]) + if test $ethr_have_libatomic_ops = yes; then + AC_CHECK_SIZEOF(AO_t, , + [ + #include <stdio.h> + #include "atomic_ops.h" + ]) + AC_DEFINE_UNQUOTED(ETHR_SIZEOF_AO_T, $ac_cv_sizeof_AO_t, [Define to the size of AO_t if libatomic_ops is used]) + + AC_DEFINE(ETHR_HAVE_LIBATOMIC_OPS, 1, [Define if you have libatomic_ops atomic operations]) + if test "x$with_libatomic_ops" != "xno" && test "x$with_libatomic_ops" != "x"; then + AC_DEFINE(ETHR_PREFER_LIBATOMIC_OPS_NATIVE_IMPLS, 1, [Define if you prefer libatomic_ops native ethread implementations]) + fi + ETHR_DEFS="$ETHR_DEFS $libatomic_ops_include" + elif test "x$with_libatomic_ops" != "xno" && test "x$with_libatomic_ops" != "x"; then + AC_MSG_ERROR([No usable libatomic_ops implementation found]) + fi + + case "$host_cpu" in + sparc | sun4u | sparc64 | sun4v) + case "$with_sparc_memory_order" in + "TSO") + AC_DEFINE(ETHR_SPARC_TSO, 1, [Define if only run in Sparc TSO mode]);; + "PSO") + AC_DEFINE(ETHR_SPARC_PSO, 1, [Define if only run in Sparc PSO, or TSO mode]);; + "RMO"|"") + AC_DEFINE(ETHR_SPARC_RMO, 1, [Define if run in Sparc RMO, PSO, or TSO mode]);; + *) + AC_MSG_ERROR([Unsupported Sparc memory order: $with_sparc_memory_order]);; + esac + ethr_have_native_atomics=yes;; + i86pc | i*86 | x86_64 | amd64) + if test "$enable_x86_out_of_order" = "yes"; then + AC_DEFINE(ETHR_X86_OUT_OF_ORDER, 1, [Define if x86/x86_64 out of order instructions should be synchronized]) + fi + ethr_have_native_atomics=yes;; + macppc | ppc | "Power Macintosh") + ethr_have_native_atomics=yes;; + tile) + ethr_have_native_atomics=yes;; + *) + ;; + esac + + test ethr_have_native_atomics = "yes" && ethr_have_native_spinlock=yes + + dnl Restore LIBS + LIBS=$saved_libs + dnl restore CPPFLAGS + CPPFLAGS=$saved_cppflags + + ;; + *) + ;; +esac + +AC_MSG_CHECKING([whether default stack size should be modified]) +if test "x$ethr_modified_default_stack_size" != "x"; then + AC_DEFINE_UNQUOTED(ETHR_MODIFIED_DEFAULT_STACK_SIZE, $ethr_modified_default_stack_size, [Define if you want to modify the default stack size]) + AC_MSG_RESULT([yes; to $ethr_modified_default_stack_size kilo words]) +else + AC_MSG_RESULT([no]) +fi + +if test "x$ETHR_THR_LIB_BASE" != "x"; then + ETHR_DEFS="-DUSE_THREADS $ETHR_DEFS" + ETHR_LIBS="-l$ethr_lib_name -lerts_internal_r $ETHR_X_LIBS" + ETHR_LIB_NAME=$ethr_lib_name +fi + +AC_CHECK_SIZEOF(void *) +AC_DEFINE_UNQUOTED(ETHR_SIZEOF_PTR, $ac_cv_sizeof_void_p, [Define to the size of pointers]) + +AC_CHECK_SIZEOF(int) +AC_DEFINE_UNQUOTED(ETHR_SIZEOF_INT, $ac_cv_sizeof_int, [Define to the size of int]) +AC_CHECK_SIZEOF(long) +AC_DEFINE_UNQUOTED(ETHR_SIZEOF_LONG, $ac_cv_sizeof_long, [Define to the size of long]) +AC_CHECK_SIZEOF(long long) +AC_DEFINE_UNQUOTED(ETHR_SIZEOF_LONG_LONG, $ac_cv_sizeof_long_long, [Define to the size of long long]) +AC_CHECK_SIZEOF(__int64) +AC_DEFINE_UNQUOTED(ETHR_SIZEOF___INT64, $ac_cv_sizeof___int64, [Define to the size of __int64]) +AC_CHECK_SIZEOF(__int128_t) +AC_DEFINE_UNQUOTED(ETHR_SIZEOF___INT128_T, $ac_cv_sizeof___int128_t, [Define to the size of __int128_t]) + + +case X$erl_xcomp_bigendian in + X) ;; + Xyes|Xno) ac_cv_c_bigendian=$erl_xcomp_bigendian;; + *) AC_MSG_ERROR([Bad erl_xcomp_bigendian value: $erl_xcomp_bigendian]);; +esac + +AC_C_BIGENDIAN + +if test "$ac_cv_c_bigendian" = "yes"; then + AC_DEFINE(ETHR_BIGENDIAN, 1, [Define if bigendian]) +fi + +AC_ARG_ENABLE(native-ethr-impls, + AS_HELP_STRING([--disable-native-ethr-impls], + [disable native ethread implementations]), +[ case "$enableval" in + no) disable_native_ethr_impls=yes ;; + *) disable_native_ethr_impls=no ;; + esac ], disable_native_ethr_impls=no) + +AC_ARG_ENABLE(x86-out-of-order, + AS_HELP_STRING([--enable-x86-out-of-order], + [enable x86/x84_64 out of order support (default disabled)])) + +test "X$disable_native_ethr_impls" = "Xyes" && + AC_DEFINE(ETHR_DISABLE_NATIVE_IMPLS, 1, [Define if you want to disable native ethread implementations]) + +AC_ARG_ENABLE(prefer-gcc-native-ethr-impls, + AS_HELP_STRING([--enable-prefer-gcc-native-ethr-impls], + [prefer gcc native ethread implementations]), +[ case "$enableval" in + yes) enable_prefer_gcc_native_ethr_impls=yes ;; + *) enable_prefer_gcc_native_ethr_impls=no ;; + esac ], enable_prefer_gcc_native_ethr_impls=no) + +test $enable_prefer_gcc_native_ethr_impls = yes && + AC_DEFINE(ETHR_PREFER_GCC_NATIVE_IMPLS, 1, [Define if you prefer gcc native ethread implementations]) + +AC_ARG_WITH(libatomic_ops, + AS_HELP_STRING([--with-libatomic_ops=PATH], + [specify and prefer usage of libatomic_ops in the ethread library])) + +AC_ARG_WITH(with_sparc_memory_order, + AS_HELP_STRING([--with-sparc-memory-order=TSO|PSO|RMO], + [specify sparc memory order (defaults to RMO)])) + +ETHR_X86_SSE2_ASM=no +case "$GCC-$ac_cv_sizeof_void_p-$host_cpu" in + yes-4-i86pc | yes-4-i*86 | yes-4-x86_64 | yes-4-amd64) + AC_MSG_CHECKING([for gcc sse2 asm support]) + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -msse2" + gcc_sse2_asm=no + AC_TRY_COMPILE([], + [ + long long x, *y; + __asm__ __volatile__("movq %1, %0\n\t" : "=x"(x) : "m"(*y) : "memory"); + ], + [gcc_sse2_asm=yes]) + CFLAGS="$save_CFLAGS" + AC_MSG_RESULT([$gcc_sse2_asm]) + if test "$gcc_sse2_asm" = "yes"; then + AC_DEFINE(ETHR_GCC_HAVE_SSE2_ASM_SUPPORT, 1, [Define if you use a gcc that supports -msse2 and understand sse2 specific asm statements]) + ETHR_X86_SSE2_ASM=yes + fi + ;; + *) + ;; +esac + +case "$GCC-$host_cpu" in + yes-i86pc | yes-i*86 | yes-x86_64 | yes-amd64) + gcc_dw_cmpxchg_asm=no + AC_MSG_CHECKING([for gcc double word cmpxchg asm support]) + AC_TRY_COMPILE([], + [ + char xchgd; + long new[2], xchg[2], *p; + __asm__ __volatile__( +#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__ + "pushl %%ebx\n\t" + "movl %8, %%ebx\n\t" +#endif +#if ETHR_SIZEOF_PTR == 4 + "lock; cmpxchg8b %0\n\t" +#else + "lock; cmpxchg16b %0\n\t" +#endif + "setz %3\n\t" +#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__ + "popl %%ebx\n\t" +#endif + : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd) + : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "3"(new[1]), +#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__ + "r"(new[0]) +#else + "b"(new[0]) +#endif + : "cc", "memory"); + + ], + [gcc_dw_cmpxchg_asm=yes]) + if test $gcc_dw_cmpxchg_asm = no && test $ac_cv_sizeof_void_p = 4; then + AC_TRY_COMPILE([], + [ + char xchgd; + long new[2], xchg[2], *p; +#if !defined(__PIC__) || !__PIC__ +# error nope +#endif + __asm__ __volatile__( + "pushl %%ebx\n\t" + "movl (%7), %%ebx\n\t" + "movl 4(%7), %%ecx\n\t" + "lock; cmpxchg8b %0\n\t" + "setz %3\n\t" + "popl %%ebx\n\t" + : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd) + : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "3"(new) + : "cc", "memory"); + + ], + [gcc_dw_cmpxchg_asm=yes]) + if test "$gcc_dw_cmpxchg_asm" = "yes"; then + AC_DEFINE(ETHR_CMPXCHG8B_REGISTER_SHORTAGE, 1, [Define if you get a register shortage with cmpxchg8b and position independent code]) + fi + fi + AC_MSG_RESULT([$gcc_dw_cmpxchg_asm]) + if test "$gcc_dw_cmpxchg_asm" = "yes"; then + AC_DEFINE(ETHR_GCC_HAVE_DW_CMPXCHG_ASM_SUPPORT, 1, [Define if you use a gcc that supports the double word cmpxchg instruction]) + fi;; + *) + ;; +esac + +AC_DEFINE(ETHR_HAVE_ETHREAD_DEFINES, 1, \ +[Define if you have all ethread defines]) + +AC_SUBST(ETHR_X_LIBS) +AC_SUBST(ETHR_LIBS) +AC_SUBST(ETHR_LIB_NAME) +AC_SUBST(ETHR_DEFS) +AC_SUBST(ETHR_THR_LIB_BASE) +AC_SUBST(ETHR_THR_LIB_BASE_DIR) +AC_SUBST(ETHR_X86_SSE2_ASM) + +]) + + + +dnl ---------------------------------------------------------------------- +dnl +dnl ERL_TIME_CORRECTION +dnl +dnl In the presence of a high resolution realtime timer Erlang can adapt +dnl its view of time relative to this timer. On solaris such a timer is +dnl available with the syscall gethrtime(). On other OS's a fallback +dnl solution using times() is implemented. (However on e.g. FreeBSD times() +dnl is implemented using gettimeofday so it doesn't make much sense to +dnl use it there...) On second thought, it seems to be safer to do it the +dnl other way around. I.e. only use times() on OS's where we know it will +dnl work... +dnl + +AC_DEFUN(ERL_TIME_CORRECTION, +[if test x$ac_cv_func_gethrtime = x; then + AC_CHECK_FUNC(gethrtime) +fi +if test x$clock_gettime_correction = xunknown; then + AC_TRY_COMPILE([#include <time.h>], + [struct timespec ts; + long long result; + clock_gettime(CLOCK_MONOTONIC,&ts); + result = ((long long) ts.tv_sec) * 1000000000LL + + ((long long) ts.tv_nsec);], + clock_gettime_compiles=yes, + clock_gettime_compiles=no) +else + clock_gettime_compiles=no +fi + + +AC_CACHE_CHECK([how to correct for time adjustments], erl_cv_time_correction, +[ +case $clock_gettime_correction in + yes) + erl_cv_time_correction=clock_gettime;; + no|unknown) + case $ac_cv_func_gethrtime in + yes) + erl_cv_time_correction=hrtime ;; + no) + case $host_os in + linux*) + case $clock_gettime_correction in + unknown) + if test x$clock_gettime_compiles = xyes; then + if test X$cross_compiling != Xyes; then + linux_kernel_vsn_=`uname -r` + case $linux_kernel_vsn_ in + [[0-1]].*|2.[[0-5]]|2.[[0-5]].*) + erl_cv_time_correction=times ;; + *) + erl_cv_time_correction=clock_gettime;; + esac + else + case X$erl_xcomp_linux_clock_gettime_correction in + X) + erl_cv_time_correction=cross;; + Xyes|Xno) + if test $erl_xcomp_linux_clock_gettime_correction = yes; then + erl_cv_time_correction=clock_gettime + else + erl_cv_time_correction=times + fi;; + *) + AC_MSG_ERROR([Bad erl_xcomp_linux_clock_gettime_correction value: $erl_xcomp_linux_clock_gettime_correction]);; + esac + fi + else + erl_cv_time_correction=times + fi + ;; + *) + erl_cv_time_correction=times ;; + esac + ;; + *) + erl_cv_time_correction=none ;; + esac + ;; + esac + ;; +esac +]) + +xrtlib="" +case $erl_cv_time_correction in + times) + AC_DEFINE(CORRECT_USING_TIMES,[], + [Define if you do not have a high-res. timer & want to use times() instead]) + ;; + clock_gettime|cross) + if test $erl_cv_time_correction = cross; then + erl_cv_time_correction=clock_gettime + AC_MSG_WARN([result clock_gettime guessed because of cross compilation]) + fi + xrtlib="-lrt" + AC_DEFINE(GETHRTIME_WITH_CLOCK_GETTIME,[1], + [Define if you want to use clock_gettime to simulate gethrtime]) + ;; +esac +dnl +dnl Check if gethrvtime is working, and if to use procfs ioctl +dnl or (yet to be written) write to the procfs ctl file. +dnl + +AC_MSG_CHECKING([if gethrvtime works and how to use it]) +AC_TRY_RUN([ +/* gethrvtime procfs ioctl test */ +/* These need to be undef:ed to not break activation of + * micro level process accounting on /proc/self + */ +#ifdef _LARGEFILE_SOURCE +# undef _LARGEFILE_SOURCE +#endif +#ifdef _FILE_OFFSET_BITS +# undef _FILE_OFFSET_BITS +#endif +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <stdio.h> +#include <sys/time.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/signal.h> +#include <sys/fault.h> +#include <sys/syscall.h> +#include <sys/procfs.h> +#include <fcntl.h> + +int main() { + long msacct = PR_MSACCT; + int fd; + long long start, stop; + int i; + pid_t pid = getpid(); + char proc_self[30] = "/proc/"; + + sprintf(proc_self+strlen(proc_self), "%lu", (unsigned long) pid); + if ( (fd = open(proc_self, O_WRONLY)) == -1) + exit(1); + if (ioctl(fd, PIOCSET, &msacct) < 0) + exit(2); + if (close(fd) < 0) + exit(3); + start = gethrvtime(); + for (i = 0; i < 100; i++) + stop = gethrvtime(); + if (start == 0) + exit(4); + if (start == stop) + exit(5); + exit(0); return 0; +} +], +erl_gethrvtime=procfs_ioctl, +erl_gethrvtime=false, +[ +case X$erl_xcomp_gethrvtime_procfs_ioctl in + X) + erl_gethrvtime=cross;; + Xyes|Xno) + if test $erl_xcomp_gethrvtime_procfs_ioctl = yes; then + erl_gethrvtime=procfs_ioctl + else + erl_gethrvtime=false + fi;; + *) + AC_MSG_ERROR([Bad erl_xcomp_gethrvtime_procfs_ioctl value: $erl_xcomp_gethrvtime_procfs_ioctl]);; +esac +]) + +case $erl_gethrvtime in + procfs_ioctl) + AC_DEFINE(HAVE_GETHRVTIME_PROCFS_IOCTL,[1], + [define if gethrvtime() works and uses ioctl() to /proc/self]) + AC_MSG_RESULT(uses ioctl to procfs) + ;; + *) + if test $erl_gethrvtime = cross; then + erl_gethrvtime=false + AC_MSG_RESULT(cross) + AC_MSG_WARN([result 'not working' guessed because of cross compilation]) + else + AC_MSG_RESULT(not working) + fi + + dnl + dnl Check if clock_gettime (linux) is working + dnl + + AC_MSG_CHECKING([if clock_gettime can be used to get process CPU time]) + save_libs=$LIBS + LIBS="-lrt" + AC_TRY_RUN([ + #include <stdlib.h> + #include <unistd.h> + #include <string.h> + #include <stdio.h> + #include <time.h> + int main() { + long long start, stop; + int i; + struct timespec tp; + + if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp) < 0) + exit(1); + start = ((long long)tp.tv_sec * 1000000000LL) + (long long)tp.tv_nsec; + for (i = 0; i < 100; i++) + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp); + stop = ((long long)tp.tv_sec * 1000000000LL) + (long long)tp.tv_nsec; + if (start == 0) + exit(4); + if (start == stop) + exit(5); + exit(0); return 0; + } + ], + erl_clock_gettime=yes, + erl_clock_gettime=no, + [ + case X$erl_xcomp_clock_gettime_cpu_time in + X) erl_clock_gettime=cross;; + Xyes|Xno) erl_clock_gettime=$erl_xcomp_clock_gettime_cpu_time;; + *) AC_MSG_ERROR([Bad erl_xcomp_clock_gettime_cpu_time value: $erl_xcomp_clock_gettime_cpu_time]);; + esac + ]) + LIBS=$save_libs + case $host_os in + linux*) + AC_MSG_RESULT([no; not stable]) + LIBRT=$xrtlib + ;; + *) + AC_MSG_RESULT($erl_clock_gettime) + case $erl_clock_gettime in + yes) + AC_DEFINE(HAVE_CLOCK_GETTIME,[], + [define if clock_gettime() works for getting process time]) + LIBRT=-lrt + ;; + cross) + erl_clock_gettime=no + AC_MSG_WARN([result no guessed because of cross compilation]) + LIBRT=$xrtlib + ;; + *) + LIBRT=$xrtlib + ;; + esac + ;; + esac + AC_SUBST(LIBRT) + ;; +esac +])dnl + +dnl ERL_TRY_LINK_JAVA(CLASSES, FUNCTION-BODY +dnl [ACTION_IF_FOUND [, ACTION-IF-NOT-FOUND]]) +dnl Freely inspired by AC_TRY_LINK. (Maybe better to create a +dnl AC_LANG_JAVA instead...) +AC_DEFUN(ERL_TRY_LINK_JAVA, +[java_link='$JAVAC conftest.java 1>&AC_FD_CC' +changequote(, )dnl +cat > conftest.java <<EOF +$1 +class conftest { public static void main(String[] args) { + $2 + ; return; }} +EOF +changequote([, ])dnl +if AC_TRY_EVAL(java_link) && test -s conftest.class; then + ifelse([$3], , :, [rm -rf conftest* + $3]) +else + echo "configure: failed program was:" 1>&AC_FD_CC + cat conftest.java 1>&AC_FD_CC + echo "configure: PATH was $PATH" 1>&AC_FD_CC +ifelse([$4], , , [ rm -rf conftest* + $4 +])dnl +fi +rm -f conftest*]) +#define UNSAFE_MASK 0xc0000000 /* Mask for bits that must be constant */ + + diff --git a/lib/erl_interface/configure.in b/lib/erl_interface/configure.in index 72ac8c7bbf..61433b0350 100644 --- a/lib/erl_interface/configure.in +++ b/lib/erl_interface/configure.in @@ -89,7 +89,7 @@ AC_PROG_CC AC_PROG_CPP dnl AC_PROG_LIBTOOL AC_PROG_RANLIB -AC_CHECK_PROG(LD, ld.sh) +AC_CHECK_PROGS(LD, ld.sh) AC_CHECK_TOOL(LD, ld, '$(CC)') AC_SUBST(LD) @@ -224,50 +224,8 @@ elif test "x$with_gmp" != "xno" -a -n "$with_gmp" ;then # FIXME return ERROR if no lib fi -MIXED_CYGWIN=no - -AC_MSG_CHECKING(for mixed cygwin and native VC++ environment) -if test "X$CC" = "Xcc.sh" -a "X$host" = "Xwin32" -a "x$GCC" != x"yes"; then - if test -x /usr/bin/cygpath; then - CFLAGS="-O2" - MIXED_CYGWIN=yes - AC_MSG_RESULT([yes]) - MIXED_CYGWIN_VC=yes - else - AC_MSG_RESULT([undeterminable]) - AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!) - fi -else - AC_MSG_RESULT([no]) - MIXED_CYGWIN_VC=no -fi -AC_SUBST(MIXED_CYGWIN_VC) - -AC_MSG_CHECKING(for mixed cygwin and native MinGW environment) -if test "X$CC" = "Xcc.sh" -a "X$host" = "Xwin32" -a "x$GCC" = x"yes"; then - if test -x /usr/bin/cygpath; then - CFLAGS="-O2" - MIXED_CYGWIN=yes - AC_MSG_RESULT([yes]) - MIXED_CYGWIN_MINGW=yes - else - AC_MSG_RESULT([undeterminable]) - AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!) - fi -else - AC_MSG_RESULT([no]) - MIXED_CYGWIN_MINGW=no -fi -AC_SUBST(MIXED_CYGWIN_MINGW) - -AC_MSG_CHECKING(if we mix cygwin with any native compiler) -if test "X$MIXED_CYGWIN" = "Xyes" ; then - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) -fi - -AC_SUBST(MIXED_CYGWIN) +LM_WINDOWS_ENVIRONMENT + dnl dnl Threads @@ -338,12 +296,6 @@ AC_SUBST(LIB_CFLAGS) if test "X$host" = "Xwin32"; then LIB_CFLAGS="$CFLAGS" else - case $host_os in - darwin*) - CFLAGS="$CFLAGS -no-cpp-precomp" - ;; - esac - if test "x$GCC" = xyes; then LIB_CFLAGS="$CFLAGS -fPIC" else diff --git a/lib/erl_interface/src/Makefile.in b/lib/erl_interface/src/Makefile.in index 0d841cfa48..63bb339eca 100644 --- a/lib/erl_interface/src/Makefile.in +++ b/lib/erl_interface/src/Makefile.in @@ -39,7 +39,9 @@ include ../vsn.mk include $(TARGET)/eidefs.mk USING_MINGW=@MIXED_CYGWIN_MINGW@ -USING_VC=@MIXED_CYGWIN_VC@ +USING_MSYS_VC==@MIXED_MSYS_VC@ +USING_CYGWIN_VC==@MIXED_MSYS_VC@ +USING_VC=@MIXED_VC@ ifdef TESTROOT RELEASE_PATH=$(TESTROOT) diff --git a/lib/erl_interface/src/auxdir/config.guess b/lib/erl_interface/src/auxdir/config.guess index fefabd7dd0..38a833903b 120000..100755 --- a/lib/erl_interface/src/auxdir/config.guess +++ b/lib/erl_interface/src/auxdir/config.guess @@ -1 +1,1519 @@ -../../../../erts/autoconf/config.guess
\ No newline at end of file +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, +# Inc. + +timestamp='2007-05-17' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner <[email protected]>. +# Please send patches to <[email protected]>. Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <[email protected]>." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# ([email protected] 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # [email protected] (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:SunOS:5.*:* | ix86xen:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include <stdio.h> /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <sys/systemcfg.h> + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include <stdlib.h> + #include <unistd.h> + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <unistd.h> + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:[3456]*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + EM64T | authenticamd) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + tile:Linux:*:*) + echo tile-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + xtensa:Linux:*:*) + echo xtensa-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <features.h> + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^LIBC/{ + s: ::g + p + }'`" + test x"${LIBC}" != x && { + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit + } + test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` + echo ${UNAME_MACHINE}-pc-isc$UNAME_REL + elif /bin/uname -X 2>/dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says <[email protected]> + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes <[email protected]>. + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From [email protected]. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From [email protected]. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From [email protected]. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c <<EOF +#ifdef _SEQUENT_ +# include <sys/types.h> +# include <sys/utsname.h> +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include <sys/param.h> + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include <sys/param.h> +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 <<EOF +$0: unable to guess system type + +This script, last modified $timestamp, has failed to recognize +the operating system you are using. It is advised that you +download the most up to date version of the config scripts from + + http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess +and + http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub + +If the version you run ($0) is already up to date, please +send the following data and any information you think might be +pertinent to <[email protected]> in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/lib/erl_interface/src/auxdir/config.sub b/lib/erl_interface/src/auxdir/config.sub index 90979e8924..f43233b104 120000..100755 --- a/lib/erl_interface/src/auxdir/config.sub +++ b/lib/erl_interface/src/auxdir/config.sub @@ -1 +1,1630 @@ -../../../../erts/autoconf/config.sub
\ No newline at end of file +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, +# Inc. + +timestamp='2007-04-29' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to <[email protected]>. Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <[email protected]>." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | mt \ + | msp430 \ + | nios | nios2 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | score \ + | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16c) + basic_machine=cr16c-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + tile*) + basic_machine=tile-tilera + os=-linux-gnu + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/lib/erl_interface/src/auxdir/install-sh b/lib/erl_interface/src/auxdir/install-sh index 9422c370df..a5897de6ea 120000..100755 --- a/lib/erl_interface/src/auxdir/install-sh +++ b/lib/erl_interface/src/auxdir/install-sh @@ -1 +1,519 @@ -../../../../erts/autoconf/install-sh
\ No newline at end of file +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2006-12-25.00 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + trap '(exit $?); exit' 1 2 13 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dst_arg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + -*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test -z "$d" && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl index 1483b2aee1..6f0141b0ca 100644 --- a/lib/hipe/cerl/erl_bif_types.erl +++ b/lib/hipe/cerl/erl_bif_types.erl @@ -3881,7 +3881,8 @@ arg_types(erlang, system_flag, 2) -> arg_types(erlang, system_info, 1) -> [t_sup([t_atom(), % documented t_tuple([t_atom(), t_any()]), % documented - t_tuple([t_atom(), t_atom(), t_any()])])]; + t_tuple([t_atom(), t_atom(), t_any()]), + t_tuple([t_atom(allocator_sizes), t_reference(), t_any()])])]; arg_types(erlang, system_monitor, 0) -> []; arg_types(erlang, system_monitor, 1) -> diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl index 0ff827ac37..387690df43 100644 --- a/lib/hipe/cerl/erl_types.erl +++ b/lib/hipe/cerl/erl_types.erl @@ -2533,29 +2533,26 @@ findfirst(N1, N2, U1, B1, U2, B2) -> t_subst(T, Dict) -> case t_has_var(T) of - true -> t_subst(T, Dict, fun(X) -> X end); + true -> t_subst_aux(T, Dict); false -> T end. -spec subst_all_vars_to_any(erl_type()) -> erl_type(). subst_all_vars_to_any(T) -> - case t_has_var(T) of - true -> t_subst(T, dict:new(), fun(_) -> ?any end); - false -> T - end. + t_subst(T, dict:new()). -t_subst(?var(Id) = V, Dict, Fun) -> +t_subst_aux(?var(Id), Dict) -> case dict:find(Id, Dict) of - error -> Fun(V); + error -> ?any; {ok, Type} -> Type end; -t_subst(?list(Contents, Termination, Size), Dict, Fun) -> - case t_subst(Contents, Dict, Fun) of +t_subst_aux(?list(Contents, Termination, Size), Dict) -> + case t_subst_aux(Contents, Dict) of ?none -> ?none; NewContents -> %% Be careful here to make the termination collapse if necessary. - case t_subst(Termination, Dict, Fun) of + case t_subst_aux(Termination, Dict) of ?nil -> ?list(NewContents, ?nil, Size); ?any -> ?list(NewContents, ?any, Size); Other -> @@ -2563,17 +2560,17 @@ t_subst(?list(Contents, Termination, Size), Dict, Fun) -> ?list(NewContents, NewTermination, Size) end end; -t_subst(?function(Domain, Range), Dict, Fun) -> - ?function(t_subst(Domain, Dict, Fun), t_subst(Range, Dict, Fun)); -t_subst(?product(Types), Dict, Fun) -> - ?product([t_subst(T, Dict, Fun) || T <- Types]); -t_subst(?tuple(?any, ?any, ?any) = T, _Dict, _Fun) -> +t_subst_aux(?function(Domain, Range), Dict) -> + ?function(t_subst_aux(Domain, Dict), t_subst_aux(Range, Dict)); +t_subst_aux(?product(Types), Dict) -> + ?product([t_subst_aux(T, Dict) || T <- Types]); +t_subst_aux(?tuple(?any, ?any, ?any) = T, _Dict) -> T; -t_subst(?tuple(Elements, _Arity, _Tag), Dict, Fun) -> - t_tuple([t_subst(E, Dict, Fun) || E <- Elements]); -t_subst(?tuple_set(_) = TS, Dict, Fun) -> - t_sup([t_subst(T, Dict, Fun) || T <- t_tuple_subtypes(TS)]); -t_subst(T, _Dict, _Fun) -> +t_subst_aux(?tuple(Elements, _Arity, _Tag), Dict) -> + t_tuple([t_subst_aux(E, Dict) || E <- Elements]); +t_subst_aux(?tuple_set(_) = TS, Dict) -> + t_sup([t_subst_aux(T, Dict) || T <- t_tuple_subtypes(TS)]); +t_subst_aux(T, _Dict) -> T. %%----------------------------------------------------------------------------- diff --git a/lib/hipe/icode/hipe_beam_to_icode.erl b/lib/hipe/icode/hipe_beam_to_icode.erl index 45b390acbd..992f387bd5 100644 --- a/lib/hipe/icode/hipe_beam_to_icode.erl +++ b/lib/hipe/icode/hipe_beam_to_icode.erl @@ -31,7 +31,7 @@ -module(hipe_beam_to_icode). --export([module/2, mfa/3]). +-export([module/2]). %%----------------------------------------------------------------------- @@ -111,55 +111,6 @@ trans_beam_function_chunk(FunBeamCode, ClosureInfo) -> {MFA,Icode}. %%----------------------------------------------------------------------- -%% @doc -%% Translates the BEAM code of a single function into Icode. -%% Returns a tuple whose first argument is list of {{M,F,A}, ICode} -%% pairs, where the first entry is that of the given MFA, and the -%% following (in undefined order) are those of the funs that are -%% defined in the function, and recursively, in the funs. The -%% second argument of the tuple is the HiPE compiler options -%% contained in the file. -%% @end -%%----------------------------------------------------------------------- - --spec mfa(list(), mfa(), comp_options()) -> hipe_beam_to_icode_ret(). - -mfa(BeamFuns, {M,F,A} = MFA, Options) - when is_atom(M), is_atom(F), is_integer(A) -> - BeamCode0 = [beam_disasm:function__code(Fn) || Fn <- BeamFuns], - {ModCode, ClosureInfo} = preprocess_code(BeamCode0), - mfa_loop([MFA], [], sets:new(), ModCode, ClosureInfo, Options). - -mfa_loop([{M,F,A} = MFA | MFAs], Acc, Seen, ModCode, ClosureInfo, - Options) when is_atom(M), is_atom(F), is_integer(A) -> - case sets:is_element(MFA, Seen) of - true -> - mfa_loop(MFAs, Acc, Seen, ModCode, ClosureInfo, Options); - false -> - {Icode, FunMFAs} = mfa_get(M, F, A, ModCode, ClosureInfo, Options), - mfa_loop(FunMFAs ++ MFAs, [{MFA, Icode} | Acc], - sets:add_element(MFA, Seen), - ModCode, ClosureInfo, Options) - end; -mfa_loop([], Acc, _, _, _, _) -> - lists:reverse(Acc). - -mfa_get(M, F, A, ModCode, ClosureInfo, Options) -> - BeamCode = get_fun(ModCode, M,F,A), - pp_beam([BeamCode], Options), % cheat by using a list - Icode = trans_mfa_code(M,F,A, BeamCode, ClosureInfo), - FunMFAs = get_fun_mfas(BeamCode), - {Icode, FunMFAs}. - -get_fun_mfas([{patched_make_fun,{M,F,A} = MFA,_,_,_}|BeamCode]) - when is_atom(M), is_atom(F), is_integer(A) -> - [MFA|get_fun_mfas(BeamCode)]; -get_fun_mfas([_|BeamCode]) -> - get_fun_mfas(BeamCode); -get_fun_mfas([]) -> - []. - -%%----------------------------------------------------------------------- %% The main translation function. %%----------------------------------------------------------------------- @@ -1884,16 +1835,6 @@ find_mfa([{func_info,{atom,M},{atom,F},A}|_]) when is_atom(M), is_atom(F), is_integer(A), 0 =< A, A =< 255 -> {M, F, A}. -%%----------------------------------------------------------------------- - -%% Localize a particular function in a module -get_fun([[L, {func_info,{atom,M},{atom,F},A} | Is] | _], M,F,A) -> - [L, {func_info,{atom,M},{atom,F},A} | Is]; -get_fun([[_L1,_L2, {func_info,{atom,M},{atom,F},A} = MFA| _Is] | _], M,F,A) -> - ?WARNING_MSG("Consecutive labels found; please re-create the .beam file~n", []), - [_L1,_L2, MFA | _Is]; -get_fun([_|Rest], M,F,A) -> - get_fun(Rest, M,F,A). %%----------------------------------------------------------------------- %% Takes a list of arguments and returns the constants of them into diff --git a/lib/hipe/icode/hipe_icode_coordinator.erl b/lib/hipe/icode/hipe_icode_coordinator.erl index a71e143192..d2defa0c90 100644 --- a/lib/hipe/icode/hipe_icode_coordinator.erl +++ b/lib/hipe/icode/hipe_icode_coordinator.erl @@ -49,6 +49,12 @@ coordinate(CG, Escaping, NonEscaping, Mod) -> fun (PM) -> last_action(PM, ServerPid, Mod, All) end, coordinate({Clean,All}, CG, gb_trees:empty(), Restart, LastAction, ServerPid). +-type mfalists() :: {[mfa()], [mfa()]}. + +-spec coordinate(mfalists(), hipe_digraph:hdg(), gb_tree(), + fun((mfalists(), gb_tree()) -> mfalists()), + fun((gb_tree()) -> 'ok'), pid()) -> no_return(). + coordinate(MFALists, CG, PM, Restart, LastAction, ServerPid) -> case MFALists of {[], []} -> @@ -106,8 +112,7 @@ last_action(PM, ServerPid, Mod, All) -> receive {done_rewrite, MFA} -> ok end - end, All), - ok. + end, All). restart_funs({Queue, Busy} = QB, PM, All, ServerPid) -> case ?MAX_CONCURRENT - length(Busy) of diff --git a/lib/hipe/icode/hipe_icode_mulret.erl b/lib/hipe/icode/hipe_icode_mulret.erl index a6529c8519..0579867e2f 100644 --- a/lib/hipe/icode/hipe_icode_mulret.erl +++ b/lib/hipe/icode/hipe_icode_mulret.erl @@ -595,9 +595,9 @@ optimizeDefine([I|Code], Dsts, DstLst, Res) -> [Ds] = Dsts, case isCallPrimop(I, mktuple) andalso DstLst =:= [] of true -> - case (hipe_icode:call_dstlist(I) =:= Dsts) of + case hipe_icode:call_dstlist(I) =:= Dsts of true -> - case (hipe_icode:call_args(I) > 1) of + case length(hipe_icode:call_args(I)) > 1 of true -> optimizeDefine(Code, Dsts, hipe_icode:call_args(I), Res); false -> diff --git a/lib/hipe/main/hipe.erl b/lib/hipe/main/hipe.erl index 570e4d9d17..7694b2fd95 100644 --- a/lib/hipe/main/hipe.erl +++ b/lib/hipe/main/hipe.erl @@ -47,9 +47,8 @@ %% %% <h3>Using the direct interface - for advanced users only</h3> %% -%% To compile a module or a specific function to native code and -%% automatically load the code into memory, call <a -%% href="#c-1"><code>hipe:c(Module)</code></a> or <a +%% To compile a module to native code and automatically load the code +%% into memory, call <a href="#c-1"><code>hipe:c(Module)</code></a> or <a %% href="#c-2"><code>hipe:c(Module, Options)</code></a>. Note that all %% options are specific to the HiPE compiler. See the <a %% href="#index">function index</a> for other compiler functions. @@ -221,11 +220,10 @@ %%------------------------------------------------------------------- -type mod() :: atom(). --type c_unit() :: mod() | mfa(). -type f_unit() :: mod() | binary(). -type ret_rtl() :: [_]. --type c_ret() :: {'ok', c_unit()} | {'error', term()} | - {'ok', c_unit(), ret_rtl()}. %% The last for debugging only +-type c_ret() :: {'ok', mod()} | {'error', term()} | + {'ok', mod(), ret_rtl()}. %% The last for debugging only -type compile_file() :: atom() | string() | binary(). -type compile_ret() :: {hipe_architecture(), binary()} | list(). @@ -278,47 +276,44 @@ load(Mod, BeamFileName) when is_list(BeamFileName) -> end. %% @spec c(Name) -> {ok, Name} | {error, Reason} -%% Name = mod() | mfa() +%% Name = mod() %% Reason = term() %% %% @equiv c(Name, []) --spec c(c_unit()) -> c_ret(). +-spec c(mod()) -> c_ret(). c(Name) -> c(Name, []). %% @spec c(Name, options()) -> {ok, Name} | {error, Reason} -%% Name = mod() | mfa() +%% Name = mod() %% options() = [option()] %% option() = term() %% Reason = term() %% -%% @type mfa() = {M::mod(),F::fun(),A::arity()}. -%% A fully qualified function name. -%% %% @type fun() = atom(). A function identifier. %% %% @type arity() = integer(). A function arity; always nonnegative. %% %% @doc User-friendly native code compiler interface. Reads BEAM code -%% from the corresponding "Module<code>.beam</code>" file in the system -%% path, and compiles either a single function or the whole module to -%% native code. By default, the compiled code is loaded directly. See -%% above for documentation of options. +%% from the corresponding "Module<code>.beam</code>" file in the +%% system path, and compiles the whole module to native code. By +%% default, the compiled code is loaded directly. See above for +%% documentation of options. %% %% @see c/1 %% @see c/3 %% @see f/2 %% @see compile/2 --spec c(c_unit(), comp_options()) -> c_ret(). +-spec c(mod(), comp_options()) -> c_ret(). c(Name, Options) -> c(Name, beam_file(Name), Options). %% @spec c(Name, File, options()) -> {ok, Name} | {error, Reason} -%% Name = mod() | mfa() +%% Name = mod() %% File = filename() | binary() %% Reason = term() %% @@ -329,7 +324,6 @@ c(Name, Options) -> %% @see f/2 c(Name, File, Opts) -> - %% No server if only one function is compiled Opts1 = user_compile_opts(Opts), case compile(Name, File, Opts1) of {ok, Res} -> @@ -359,8 +353,7 @@ f(File) -> %% Reason = term() %% %% @doc Like <code>c/3</code>, but takes the module name from the -%% specified <code>File</code>. This always compiles the whole module; -%% there is no possibility to compile just a single function. +%% specified <code>File</code>. %% %% @see c/3 @@ -381,26 +374,26 @@ user_compile_opts(Opts) -> %% @spec compile(Name) -> {ok, {Target,Binary}} | {error, Reason} -%% Name = mod() | mfa() +%% Name = mod() %% Binary = binary() %% Reason = term() %% %% @equiv compile(Name, []) --spec compile(c_unit()) -> {'ok', compile_ret()} | {'error', term()}. +-spec compile(mod()) -> {'ok', compile_ret()} | {'error', term()}. compile(Name) -> compile(Name, []). %% @spec compile(Name, options()) -> {ok, {Target,Binary}} | {error, Reason} -%% Name = mod() | mfa() +%% Name = mod() %% Binary = binary() %% Reason = term() %% -%% @doc Direct compiler interface, for advanced use. This just compiles -%% the named function or module, reading BEAM code from the -%% corresponding "Module<code>.beam</code>" file in the system path. -%% Returns <code>{ok, Binary}</code> if successful, or <code>{error, +%% @doc Direct compiler interface, for advanced use. This just +%% compiles the module, reading BEAM code from the corresponding +%% "Module<code>.beam</code>" file in the system path. Returns +%% <code>{ok, Binary}</code> if successful, or <code>{error, %% Reason}</code> otherwise. By default, it does <em>not</em> load the %% binary to memory (the <code>load</code> option can be used to %% activate automatic loading). <code>File</code> can be either a file @@ -412,15 +405,13 @@ compile(Name) -> %% @see file/2 %% @see load/2 --spec compile(c_unit(), comp_options()) -> {'ok', compile_ret()} | {'error', _}. +-spec compile(mod(), comp_options()) -> {'ok', compile_ret()} | {'error', _}. compile(Name, Options) -> compile(Name, beam_file(Name), Options). --spec beam_file(mod() | mfa()) -> string(). +-spec beam_file(mod()) -> string(). -beam_file({M,F,A}) when is_atom(M), is_atom(F), is_integer(A), A >= 0 -> - beam_file(M); beam_file(Module) when is_atom(Module) -> case code:which(Module) of non_existing -> @@ -432,7 +423,7 @@ beam_file(Module) when is_atom(Module) -> %% @spec compile(Name, File, options()) -> %% {ok, {Target, Binary}} | {error, Reason} -%% Name = mod() | mfa() +%% Name = mod() %% File = filename() | binary() %% Binary = binary() %% Reason = term() @@ -442,18 +433,11 @@ beam_file(Module) when is_atom(Module) -> %% %% @see compile/2 --spec compile(c_unit(), compile_file(), comp_options()) -> +-spec compile(mod(), compile_file(), comp_options()) -> {'ok', compile_ret()} | {'error', term()}. -compile(Name, File, Opts0) -> - Opts1 = expand_kt2(Opts0), - Opts = - case Name of - {_Mod, _Fun, _Arity} -> - [no_concurrent_comp|Opts1]; - _ -> - Opts1 - end, +compile(Name, File, Opts0) when is_atom(Name) -> + Opts = expand_kt2(Opts0), case proplists:get_value(core, Opts) of true when is_binary(File) -> ?error_msg("Cannot get Core Erlang code from BEAM binary.",[]), @@ -486,23 +470,11 @@ compile(Name, File, Opts0) -> ?EXIT({cant_compile_source_code, Error}) end; Other when Other =:= false; Other =:= undefined -> - NewOpts = - case proplists:get_value(use_callgraph, Opts) of - No when No =:= false; No =:= undefined -> Opts; - _ -> - case Name of - {_M,_F,_A} -> - %% There is no point in using the callgraph or concurrent_comp - %% when analyzing just one function. - [no_use_callgraph, no_concurrent_comp|Opts]; - _ -> Opts - end - end, DisasmFun = fun (_) -> disasm(File) end, IcodeFun = fun (Code, Opts_) -> get_beam_icode(Name, Code, File, Opts_) end, - run_compiler(Name, DisasmFun, IcodeFun, NewOpts) + run_compiler(Name, DisasmFun, IcodeFun, Opts) end. -spec compile_core(mod(), cerl:c_module(), compile_file(), comp_options()) -> @@ -602,9 +574,13 @@ file(File, Options) when is_atom(File) -> disasm(File) -> case beam_disasm:file(File) of #beam_file{labeled_exports = LabeledExports, - compile_info = CompInfo, + compile_info = CompInfo0, code = BeamCode} -> - {options, CompOpts} = lists:keyfind(options, 1, CompInfo), + CompInfo = case CompInfo0 of + none -> []; + _ -> CompInfo0 + end, + CompOpts = proplists:get_value(options, CompInfo, []), HCompOpts = case lists:keyfind(hipe, 1, CompOpts) of {hipe, L} when is_list(L) -> L; {hipe, X} -> [X]; @@ -625,11 +601,6 @@ fix_beam_exports([{F,A,_}|BeamExports], Exports) -> fix_beam_exports([], Exports) -> Exports. -get_beam_icode({M,_F,_A} = MFA, {BeamCode, Exports}, _File, Options) -> - ?option_time({ok, Icode} = - (catch {ok, hipe_beam_to_icode:mfa(BeamCode, MFA, Options)}), - "BEAM-to-Icode", Options), - {{M, Exports, Icode}, false}; get_beam_icode(Mod, {BeamCode, Exports}, File, Options) -> ?option_time({ok, Icode} = (catch {ok, hipe_beam_to_icode:module(BeamCode, Options)}), @@ -899,7 +870,8 @@ maybe_load(Mod, Bin, WholeModule, Opts) -> do_load(Mod, Bin, WholeModule) end. -do_load(Mod, Bin, WholeModule) -> +do_load(Mod, Bin, BeamBinOrPath) when is_binary(BeamBinOrPath); + is_list(BeamBinOrPath) -> HostArch = get(hipe_host_arch), TargetArch = get(hipe_target_arch), %% Make sure we can do the load. @@ -907,29 +879,22 @@ do_load(Mod, Bin, WholeModule) -> ?EXIT({host_and_target_arch_differ, HostArch, TargetArch}); true -> ok end, - case WholeModule of + case code:is_sticky(Mod) of + true -> + %% We unpack and repack the Beam binary as a workaround to + %% ensure that it is not compressed. + {ok, _, Chunks} = beam_lib:all_chunks(BeamBinOrPath), + {ok, Beam} = beam_lib:build_module(Chunks), + %% Don't purge or register sticky mods; just load native. + code:load_native_sticky(Mod, Bin, Beam); false -> - %% In this case, the emulated code for the module must be loaded. - {module, Mod} = code:ensure_loaded(Mod), - code:load_native_partial(Mod, Bin); - BeamBinOrPath when is_binary(BeamBinOrPath) orelse is_list(BeamBinOrPath) -> - case code:is_sticky(Mod) of - true -> - %% We unpack and repack the Beam binary as a workaround to - %% ensure that it is not compressed. - {ok, _, Chunks} = beam_lib:all_chunks(WholeModule), - {ok, Beam} = beam_lib:build_module(Chunks), - %% Don't purge or register sticky mods; just load native. - code:load_native_sticky(Mod, Bin, Beam); - false -> - %% Normal loading of a whole module - Architecture = erlang:system_info(hipe_architecture), - ChunkName = hipe_unified_loader:chunk_name(Architecture), - {ok, _, Chunks0} = beam_lib:all_chunks(WholeModule), - Chunks = [{ChunkName, Bin}|lists:keydelete(ChunkName, 1, Chunks0)], - {ok, BeamPlusNative} = beam_lib:build_module(Chunks), - code:load_binary(Mod, code:which(Mod), BeamPlusNative) - end + %% Normal loading of a whole module + Architecture = erlang:system_info(hipe_architecture), + ChunkName = hipe_unified_loader:chunk_name(Architecture), + {ok, _, Chunks0} = beam_lib:all_chunks(BeamBinOrPath), + Chunks = [{ChunkName, Bin}|lists:keydelete(ChunkName, 1, Chunks0)], + {ok, BeamPlusNative} = beam_lib:build_module(Chunks), + code:load_binary(Mod, code:which(Mod), BeamPlusNative) end. assemble(CompiledCode, Closures, Exports, Options) -> diff --git a/lib/hipe/opt/hipe_schedule.erl b/lib/hipe/opt/hipe_schedule.erl index 4925b2927b..ca3abf8cc6 100644 --- a/lib/hipe/opt/hipe_schedule.erl +++ b/lib/hipe/opt/hipe_schedule.erl @@ -797,7 +797,7 @@ dep_arc(N, Lat, M, {Dag,Preds}) -> %% Returns : A dependence graph sorted by To. %% Description : A new arc that is added is sorted in the right place, and if %% there is already an arc between nodes A and B, the one with -%% the greatest latency is choosen. +%% the greatest latency is chosen. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% add_arc(Lat,To, []) -> {[{Lat, To}], added}; add_arc(Lat1, To, [{Lat2, To} | Arcs]) -> diff --git a/lib/hipe/rtl/hipe_rtl.erl b/lib/hipe/rtl/hipe_rtl.erl index 29e9c8c8fe..4bf4eb6bd7 100644 --- a/lib/hipe/rtl/hipe_rtl.erl +++ b/lib/hipe/rtl/hipe_rtl.erl @@ -781,8 +781,11 @@ fstore_src_update(F, NewSrc) -> F#fstore{src=NewSrc}. %% fp %% + mk_fp(Dst, Src1, Op, Src2) -> - #fp{dst=Dst, src1=Src1, op=Op, src2=Src2}. + [#fp{dst=Dst, src1=Src1, op=Op, src2=Src2} + | hipe_rtl_arch:mk_fp_check_result(Dst)]. + fp_dst(#fp{dst=Dst}) -> Dst. fp_dst_update(Fp, NewDst) -> Fp#fp{dst=NewDst}. fp_src1(#fp{src1=Src1}) -> Src1. diff --git a/lib/hipe/rtl/hipe_rtl_arch.erl b/lib/hipe/rtl/hipe_rtl_arch.erl index 22cda57a3a..99eb80f3d1 100644 --- a/lib/hipe/rtl/hipe_rtl_arch.erl +++ b/lib/hipe/rtl/hipe_rtl_arch.erl @@ -65,7 +65,8 @@ %% alignment/0, nr_of_return_regs/0, log2_word_size/0, - word_size/0 + word_size/0, + mk_fp_check_result/1 ]). -include("hipe_literals.hrl"). @@ -558,6 +559,12 @@ eval_cond_bits(Cond, N, Z, V, C) -> %%---------------------------------------------------------------------- fwait() -> + case ?ERTS_NO_FPE_SIGNALS of + 1 -> []; + 0 -> fwait_real() + end. + +fwait_real() -> case get(hipe_target_arch) of x86 -> [hipe_rtl:mk_call([], 'fwait', [], [], [], not_remote)]; amd64 -> [hipe_rtl:mk_call([], 'fwait', [], [], [], not_remote)]; @@ -573,6 +580,12 @@ fwait() -> %% Returns RTL code to restore the FPU after a floating-point exception. %% @end handle_fp_exception() -> + case ?ERTS_NO_FPE_SIGNALS of + 1 -> []; + 0 -> handle_real_fp_exception() + end. + +handle_real_fp_exception() -> case get(hipe_target_arch) of x86 -> ContLbl = hipe_rtl:mk_new_label(), @@ -655,3 +668,15 @@ nr_of_return_regs() -> 1 %% hipe_amd64_registers:nr_rets(); end. + + +mk_fp_check_result(Result) -> + case ?ERTS_NO_FPE_SIGNALS of + 0 -> + []; + 1 -> + [hipe_rtl:mk_fstore(proc_pointer(), + hipe_rtl:mk_imm(?P_FLOAT_RESULT), + Result), + hipe_rtl:mk_call([], emulate_fpe, [], [], [], not_remote)] + end. diff --git a/lib/hipe/rtl/hipe_rtl_lcm.erl b/lib/hipe/rtl/hipe_rtl_lcm.erl index 9224623c8b..262aedb409 100644 --- a/lib/hipe/rtl/hipe_rtl_lcm.erl +++ b/lib/hipe/rtl/hipe_rtl_lcm.erl @@ -486,7 +486,7 @@ lcm_precalc(CFG, Options) -> ?option_time(NodeInfo2 = calc_down_exp(CFG, ExprMap, NodeInfo1, Labels), "RTL LCM calc_down_exp", Options), ?option_time(NodeInfo3 = calc_killed_expr(CFG, NodeInfo2, UseMap, AllExpr, - Labels), + IdMap, Labels), "RTL LCM calc_killed_exp", Options), ?option_time(NodeInfo4 = calc_avail(CFG, NodeInfo3), "RTL LCM calc_avail", Options), @@ -815,19 +815,19 @@ exp_kill_expr(Instr, [CheckedExpr|Exprs]) -> %%============================================================================= %% Calculates the killed expression sets for all given labels. -calc_killed_expr(_, NodeInfo, _, _, []) -> +calc_killed_expr(_, NodeInfo, _, _, _, []) -> NodeInfo; -calc_killed_expr(CFG, NodeInfo, UseMap, AllExpr, [Label|Labels]) -> +calc_killed_expr(CFG, NodeInfo, UseMap, AllExpr, IdMap, [Label|Labels]) -> Code = hipe_bb:code(hipe_rtl_cfg:bb(CFG, Label)), - KilledExprs = calc_killed_expr_bb(Code, UseMap, AllExpr, ?SETS:new()), + KilledExprs = calc_killed_expr_bb(Code, UseMap, AllExpr, IdMap, ?SETS:new()), NewNodeInfo = set_killed_expr(NodeInfo, Label, KilledExprs), - calc_killed_expr(CFG, NewNodeInfo, UseMap, AllExpr, Labels). + calc_killed_expr(CFG, NewNodeInfo, UseMap, AllExpr, IdMap, Labels). %%============================================================================= %% Calculates the killed expressions set for one basic block. -calc_killed_expr_bb([], _UseMap, _AllExpr, KilledExprs) -> +calc_killed_expr_bb([], _UseMap, _AllExpr, _IdMap, KilledExprs) -> KilledExprs; -calc_killed_expr_bb([Instr|Instrs], UseMap, AllExpr, KilledExprs) -> +calc_killed_expr_bb([Instr|Instrs], UseMap, AllExpr, IdMap, KilledExprs) -> %% Calls, gctests and stores potentially clobber everything case Instr of #call{} -> AllExpr; @@ -837,7 +837,8 @@ calc_killed_expr_bb([Instr|Instrs], UseMap, AllExpr, KilledExprs) -> %% Kill all float expressions %% FIXME: Make separate function is_fp_expr ?SETS:from_list - (lists:foldl(fun(Expr, Fexprs) -> + (lists:foldl(fun(ExprId, Fexprs) -> + Expr = expr_id_map_get_expr(IdMap, ExprId), [Define|_] = hipe_rtl:defines(Expr), case hipe_rtl:is_fpreg(Define) of true -> @@ -849,10 +850,10 @@ calc_killed_expr_bb([Instr|Instrs], UseMap, AllExpr, KilledExprs) -> _ -> case hipe_rtl:defines(Instr) of [] -> - calc_killed_expr_bb(Instrs, UseMap, AllExpr, KilledExprs); + calc_killed_expr_bb(Instrs, UseMap, AllExpr, IdMap, KilledExprs); [Define|_] -> NewKilledExprs = use_map_get_expr_uses(UseMap, Define), - calc_killed_expr_bb(Instrs, UseMap, AllExpr, + calc_killed_expr_bb(Instrs, UseMap, AllExpr, IdMap, ?SETS:union(NewKilledExprs, KilledExprs)) end end. diff --git a/lib/hipe/tools/Makefile b/lib/hipe/tools/Makefile index 0eaa3a7b05..e9745a6767 100644 --- a/lib/hipe/tools/Makefile +++ b/lib/hipe/tools/Makefile @@ -42,7 +42,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/hipe-$(VSN) # ---------------------------------------------------- # Target Specs # ---------------------------------------------------- -MODULES = hipe_tool hipe_profile hipe_ceach hipe_jit +MODULES = hipe_tool hipe_profile hipe_jit # hipe_timer HRL_FILES= diff --git a/lib/hipe/tools/hipe_ceach.erl b/lib/hipe/tools/hipe_ceach.erl deleted file mode 100644 index b29615e169..0000000000 --- a/lib/hipe/tools/hipe_ceach.erl +++ /dev/null @@ -1,74 +0,0 @@ -%% -*- erlang-indent-level: 2 -*- -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2002-2009. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Copyright (c) 2001 by Erik Johansson. All Rights Reserved -%% ==================================================================== -%% Module : hipe_ceach -%% Purpose : Compile each function in a module, possibly applying a -%% fun between each compilation. Useful for bug hunting by -%% pinpointing a function that when compiled causes a bug. -%% Notes : -%% History : * 2001-12-11 Erik Johansson ([email protected]): Created. -%% ==================================================================== -%% Exports : -%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - --module(hipe_ceach). - --export([c/1, c/2, c/3]). - --include("../main/hipe.hrl"). - -%%--------------------------------------------------------------------- - --spec c(atom()) -> 'ok'. - -c(M) -> - lists:foreach(fun({F,A}) -> comp(M, F, A) end, - M:module_info(functions)). - --spec c(atom(), comp_options()) -> 'ok'. - -c(M, Opts) -> - lists:foreach(fun({F,A}) -> comp(M, F, A, Opts) end, - M:module_info(functions)). - --spec c(atom(), comp_options(), fun(() -> any())) -> 'ok'. - -c(M, Opts, Fn) -> - lists:foreach(fun({F,A}) -> comp(M, F, A, Opts), Fn() end, - M:module_info(functions)). - --spec comp(atom(), atom(), arity()) -> 'ok'. - -comp(M, F, A) -> - io:format("~w:~w/~w... ", [M, F, A]), - MFA = {M, F, A}, - {ok, MFA} = hipe:c(MFA), - io:format("OK\n"). - --spec comp(atom(), atom(), arity(), comp_options()) -> 'ok'. - -comp(M, F, A, Opts) -> - io:format("~w:~w/~w... ", [M, F, A]), - MFA = {M, F, A}, - {ok, MFA} = hipe:c(MFA, Opts), - io:format("OK\n"). diff --git a/lib/hipe/tools/hipe_profile.erl b/lib/hipe/tools/hipe_profile.erl index 7566acb8f4..1284b64f13 100644 --- a/lib/hipe/tools/hipe_profile.erl +++ b/lib/hipe/tools/hipe_profile.erl @@ -89,7 +89,7 @@ calls() -> %% F(), %% %% Get result. %% R = res(), -%% %% Turn of profiling. +%% %% Turn off profiling. %% prof_off(), %% R. diff --git a/lib/inets/Makefile b/lib/inets/Makefile index 4765a2ca3c..d837a3396a 100644 --- a/lib/inets/Makefile +++ b/lib/inets/Makefile @@ -31,12 +31,16 @@ VSN = $(INETS_VSN) SPECIAL_TARGETS = +DIA_PLT = ./priv/plt/$(APPLICATION).plt +DIA_ANALYSIS = $(basename $(DIA_PLT)).dialyzer_analysis + + # ---------------------------------------------------- # Default Subdir Targets # ---------------------------------------------------- include $(ERL_TOP)/make/otp_subdir.mk -.PHONY: info gclean +.PHONY: info gclean dialyzer dialyzer_plt dclean info: @echo "OS: $(OS)" @@ -45,6 +49,29 @@ info: @echo "INETS_VSN: $(INETS_VSN)" @echo "APP_VSN: $(APP_VSN)" @echo "" + @echo "DIA_PLT: $(DIA_PLT)" + @echo "DIA_ANALYSIS: $(DIA_ANALYSIS)" + @echo "" gclean: git clean -fXd + +dclean: + rm -f $(DIA_PLT) + rm -f $(DIA_ANALYSIS) + +dialyzer_plt: $(DIA_PLT) + +$(DIA_PLT): + @echo "Building $(APPLICATION) plt file" + @dialyzer --build_plt \ + --output_plt $@ \ + -r ../$(APPLICATION)/ebin \ + --output $(DIA_ANALYSIS) \ + --verbose + +dialyzer: $(DIA_PLT) + @echo "Running dialyzer on $(APPLICATION)" + @dialyzer --plt $< \ + ../$(APPLICATION)/ebin \ + --verbose diff --git a/lib/inets/doc/src/httpc.xml b/lib/inets/doc/src/httpc.xml index b1f964ae69..48a2089605 100644 --- a/lib/inets/doc/src/httpc.xml +++ b/lib/inets/doc/src/httpc.xml @@ -178,13 +178,14 @@ filename() = string() <v>timeout() = integer() >= 0 | infinity</v> <v>Options = options()</v> <v>options() = [option()]</v> - <v>option() = {sync, boolean()} | - {stream, stream_to()} | - {body_format, body_format()} | - {full_result, boolean()} | - {headers_as_is, boolean() | - {socket_opts, socket_opts()} | - {receiver, receiver()}}</v> + <v>option() = {sync, boolean()} | + {stream, stream_to()} | + {body_format, body_format()} | + {full_result, boolean()} | + {headers_as_is, boolean() | + {socket_opts, socket_opts()} | + {receiver, receiver()}, + {ipv6_host_with_brackets, boolean()}}</v> <v>stream_to() = none | self | {self, once} | filename() </v> <v>socket_opts() = [socket_opt()]</v> <v>receiver() = pid() | function()/1 | {Module, Function, Args} </v> @@ -407,7 +408,18 @@ apply(Module, Function, [ReplyInfo | Args]) <p>Defaults to the <c>pid()</c> of the process calling the request function (<c>self()</c>). </p> + + <marker id="ipv6_host_with_brackets"></marker> + </item> + + <tag><c><![CDATA[ipv6_host_with_brackets]]></c></tag> + <item> + <p>When parsing the Host-Port part of an URI with a IPv6 address + with brackets, shall we retain those brackets (<c>true</c>) or + strip them (<c>false</c>). </p> + <p>Defaults to <c>false</c>. </p> </item> + </taglist> <marker id="cancel_request"></marker> @@ -572,17 +584,24 @@ apply(Module, Function, [ReplyInfo | Args]) <func> <name>cookie_header(Url) -> </name> - <name>cookie_header(Url, Profile) -> header() | {error, Reason}</name> + <name>cookie_header(Url, Profile | Opts) -> header() | {error, Reason}</name> + <name>cookie_header(Url, Opts, Profile) -> header() | {error, Reason}</name> <fsummary>Returns the cookie header that would be sent when making a request to Url using the profile <c>Profile</c>.</fsummary> <type> <v>Url = url()</v> + <v>Opts = [cookie_header_opt()]</v> <v>Profile = profile() | pid() (when started <c>stand_alone</c>)</v> + <v>cookie_header_opt() = {ipv6_host_with_brackets, boolean()}</v> </type> <desc> <p>Returns the cookie header that would be sent when making a request to <c>Url</c> using the profile <c>Profile</c>. If no profile is specified the default profile will be used. </p> + <p>The option <c>ipv6_host_with_bracket</c> deals with how to + parse IPv6 addresses. + See the <c>Options</c> argument of the + <seealso marker="#request2">request/4,5</seealso> for more info. </p> <marker id="reset_cookies"></marker> </desc> diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml index 59c2f8a2df..369762d0c6 100644 --- a/lib/inets/doc/src/notes.xml +++ b/lib/inets/doc/src/notes.xml @@ -50,24 +50,52 @@ <p>Own Id: OTP-9545</p> </item> + <item> + <p>[httpc] Wrong Host header in IPv6 HTTP requests. + When a URI with a IPv6 host is parsed, the brackets that encapsulates + the address part is removed. This value is then supplied as the host + header. This can cause problems with some servers. + A workaround for this is to use headers_as_is and provide the host + header with the requst call. + To solve this a new option has been added, + <seealso marker="httpc#ipv6_host_with_brackets">ipv6_host_with_brackets</seealso>. + This option specifies if the host value of the host header shall + include the brackets or not. By default, it does not (as before). + </p> + <p>Own Id: OTP-9628</p> + </item> + </list> </section> <section><title>Fixed Bugs and Malfunctions</title> +<!-- <p>-</p> +--> -<!-- <list> <item> - <p>[httpc] Remove unnecessary usage of iolist_to_binary when - processing body (for PUT and POST). </p> - <p>Filipe David Manana</p> - <p>Own Id: OTP-9317</p> + <p>[httpd] Fix logging of content length in mod_log. </p> + <p>Garrett Smith</p> + <p>Own Id: OTP-9715</p> + </item> + + <item> + <p>[httpd] Sometimes entries in the transfer log was written + with the message size as list of numbers. This list was actually + the size as a string, e.g. "123", written with the control + sequence ~w. This has now been corrected so that any string is + converted to an integer (if possible). </p> + <p>Own Id: OTP-9733</p> + </item> + + <item> + <p>Fixed various problems detected by Dialyzer. </p> + <p>Own Id: OTP-9736</p> </item> </list> ---> </section> diff --git a/lib/inets/priv/plt/.gitignore b/lib/inets/priv/plt/.gitignore new file mode 100644 index 0000000000..2051b52d48 --- /dev/null +++ b/lib/inets/priv/plt/.gitignore @@ -0,0 +1,2 @@ +/*.plt +/*.dialyzer_analysis diff --git a/lib/inets/src/http_client/httpc.erl b/lib/inets/src/http_client/httpc.erl index d72c34fa6b..ae87ceed93 100644 --- a/lib/inets/src/http_client/httpc.erl +++ b/lib/inets/src/http_client/httpc.erl @@ -34,7 +34,7 @@ set_option/2, set_option/3, set_options/1, set_options/2, store_cookies/2, store_cookies/3, - cookie_header/1, cookie_header/2, + cookie_header/1, cookie_header/2, cookie_header/3, which_cookies/0, which_cookies/1, reset_cookies/0, reset_cookies/1, stream_next/1, @@ -290,25 +290,36 @@ store_cookies(SetCookieHeaders, Url, Profile) %%-------------------------------------------------------------------------- -%% cookie_header(Url [, Profile]) -> Header | {error, Reason} -%% +%% cookie_header(Url) -> Header | {error, Reason} +%% cookie_header(Url, Profile) -> Header | {error, Reason} +%% cookie_header(Url, Opts, Profile) -> Header | {error, Reason} +%% %% Description: Returns the cookie header that would be sent when making %% a request to <Url>. %%------------------------------------------------------------------------- cookie_header(Url) -> cookie_header(Url, default_profile()). -cookie_header(Url, Profile) -> +cookie_header(Url, Profile) when is_atom(Profile) orelse is_pid(Profile) -> + cookie_header(Url, [], Profile); +cookie_header(Url, Opts) when is_list(Opts) -> + cookie_header(Url, Opts, default_profile()). + +cookie_header(Url, Opts, Profile) + when (is_list(Opts) andalso (is_atom(Profile) orelse is_pid(Profile))) -> ?hcrt("cookie header", [{url, Url}, + {opts, Opts}, {profile, Profile}]), try begin - httpc_manager:which_cookies(Url, profile_name(Profile)) + httpc_manager:which_cookies(Url, Opts, profile_name(Profile)) end catch exit:{noproc, _} -> {error, {not_started, Profile}} end. + + %%-------------------------------------------------------------------------- diff --git a/lib/inets/src/http_client/httpc_manager.erl b/lib/inets/src/http_client/httpc_manager.erl index ab575d867e..a97cbb83f1 100644 --- a/lib/inets/src/http_client/httpc_manager.erl +++ b/lib/inets/src/http_client/httpc_manager.erl @@ -37,7 +37,7 @@ delete_session/2, set_options/2, store_cookies/3, - which_cookies/1, which_cookies/2, + which_cookies/1, which_cookies/2, which_cookies/3, reset_cookies/1, session_type/1, info/1 @@ -271,9 +271,11 @@ reset_cookies(ProfileName) -> which_cookies(ProfileName) when is_atom(ProfileName) -> call(ProfileName, which_cookies). + which_cookies(Url, ProfileName) when is_list(Url) andalso is_atom(ProfileName) -> - call(ProfileName, {which_cookies, Url, []}). + which_cookies(Url, [], ProfileName). + which_cookies(Url, Options, ProfileName) when is_list(Url) andalso is_list(Options) andalso is_atom(ProfileName) -> call(ProfileName, {which_cookies, Url, Options}). diff --git a/lib/inets/src/http_server/httpd_acceptor.erl b/lib/inets/src/http_server/httpd_acceptor.erl index bcebb6a9e3..046e491bbf 100644 --- a/lib/inets/src/http_server/httpd_acceptor.erl +++ b/lib/inets/src/http_server/httpd_acceptor.erl @@ -139,11 +139,11 @@ acceptor_loop(Manager, SocketType, ListenSocket, ConfigDb, AcceptTimeout) -> handle_error(Reason, ConfigDb), ?MODULE:acceptor_loop(Manager, SocketType, ListenSocket, ConfigDb, AcceptTimeout); - {'EXIT', _Reason} = EXIT -> - ?hdri("accept exited", [{reason, _Reason}]), - handle_error(EXIT, ConfigDb), - ?MODULE:acceptor_loop(Manager, SocketType, ListenSocket, - ConfigDb, AcceptTimeout) + {'EXIT', Reason} -> + ?hdri("accept exited", [{reason, Reason}]), + ReasonString = + lists:flatten(io_lib:format("Accept exit: ~p", [Reason])), + accept_failed(ConfigDb, ReasonString) end. @@ -189,15 +189,13 @@ handle_error(esslaccept, _) -> %% not write an error message. ok; -handle_error({'EXIT', Reason}, ConfigDb) -> - String = lists:flatten(io_lib:format("Accept exit: ~p", [Reason])), - accept_failed(ConfigDb, String); - handle_error(Reason, ConfigDb) -> String = lists:flatten(io_lib:format("Accept error: ~p", [Reason])), accept_failed(ConfigDb, String). --spec accept_failed(_, string()) -> no_return(). + +-spec accept_failed(ConfigDB :: term(), + ReasonString :: string()) -> no_return(). accept_failed(ConfigDb, String) -> error_logger:error_report(String), diff --git a/lib/inets/src/http_server/httpd_log.erl b/lib/inets/src/http_server/httpd_log.erl index db1e2c627a..60ab326a20 100644 --- a/lib/inets/src/http_server/httpd_log.erl +++ b/lib/inets/src/http_server/httpd_log.erl @@ -24,68 +24,110 @@ -export([access_entry/8, error_entry/5, error_report_entry/5, security_entry/5]). + %%%========================================================================= %%% Internal Application API %%%========================================================================= -access_entry(Log, NoLog, Info, RFC931, AuthUser, Date, StatusCode, Bytes) -> - ConfigDB = Info#mod.config_db, - case httpd_util:lookup(ConfigDB, Log) of - undefined -> - NoLog; - LogRef -> - {_, RemoteHost} - = (Info#mod.init_data)#init_data.peername, - RequestLine = Info#mod.request_line, - Headers = Info#mod.parsed_header, - Entry = do_access_entry(ConfigDB, Headers, RequestLine, - RemoteHost, RFC931, AuthUser, - Date, StatusCode, Bytes), - {LogRef, Entry} - end. -error_entry(Log, NoLog, Info, Date, Reason) -> - ConfigDB = Info#mod.config_db, - case httpd_util:lookup(ConfigDB, Log) of - undefined -> - NoLog; - LogRef -> - {_, RemoteHost} = - (Info#mod.init_data)#init_data.peername, - URI = Info#mod.request_uri, - Entry = do_error_entry(ConfigDB, RemoteHost, URI, Date, Reason), - {LogRef, Entry} - end. +-spec access_entry(Log :: term(), % Id of the log + NoLog :: term(), % What to return when no log is found + Info :: #mod{}, + RFC931 :: string(), + AuthUser :: string(), + Date :: string(), + StatusCode :: pos_integer(), + Size :: pos_integer() | string()) -> + {Log :: atom() | pid(), Entry :: string()}. + +access_entry(Log, NoLog, Info, RFC931, AuthUser, Date, StatusCode, SizeStr) + when is_list(SizeStr) -> + Size = + case (catch list_to_integer(SizeStr)) of + I when is_integer(I) -> + I; + _ -> + SizeStr % This is better then nothing + end, + access_entry(Log, NoLog, Info, RFC931, AuthUser, Date, StatusCode, Size); +access_entry(Log, NoLog, + #mod{config_db = ConfigDB, + init_data = #init_data{peername = {_, RemoteHost}}, + request_line = RequestLine, + parsed_header = Headers}, + RFC931, AuthUser, Date, StatusCode, Size) -> + MakeEntry = + fun() -> + do_access_entry(ConfigDB, Headers, RequestLine, + RemoteHost, RFC931, AuthUser, + Date, StatusCode, Size) + end, + log_entry(Log, NoLog, ConfigDB, MakeEntry). + + +-spec error_entry(Log :: term(), % Id of the log + NoLog :: term(), % What to return when no log is found + Info :: #mod{}, + Date :: string(), + Reason :: term()) -> + {Log :: atom() | pid(), Entry :: string()}. + +error_entry(Log, NoLog, + #mod{config_db = ConfigDB, + init_data = #init_data{peername = {_, RemoteHost}}, + request_uri = URI}, Date, Reason) -> + MakeEntry = + fun() -> + do_error_entry(ConfigDB, RemoteHost, URI, Date, Reason) + end, + log_entry(Log, NoLog, ConfigDB, MakeEntry). + + +-spec error_report_entry(Log :: term(), + NoLog :: term(), + ConfigDB :: term(), + Date :: string(), + ErrroStr :: string()) -> + {Log :: atom() | pid(), Entry :: string()}. error_report_entry(Log, NoLog, ConfigDb, Date, ErrorStr) -> - case httpd_util:lookup(ConfigDb, Log) of - undefined -> - NoLog; - LogRef -> - Entry = io_lib:format("[~s], ~s~n", [Date, ErrorStr]), - {LogRef, Entry} - end. + MakeEntry = fun() -> io_lib:format("[~s], ~s~n", [Date, ErrorStr]) end, + log_entry(Log, NoLog, ConfigDb, MakeEntry). + -security_entry(Log, NoLog, #mod{config_db = ConfigDb}, Date, Reason) -> +-spec security_entry(Log :: term(), + NoLog :: term(), + ConfigDB :: term(), + Date :: string(), + Reason :: term()) -> + {Log :: atom() | pid(), Entry :: string()}. + +security_entry(Log, NoLog, #mod{config_db = ConfigDB}, Date, Reason) -> + MakeEntry = fun() -> io_lib:format("[~s] ~s~n", [Date, Reason]) end, + log_entry(Log, NoLog, ConfigDB, MakeEntry). + + +log_entry(Log, NoLog, ConfigDb, MakeEntry) when is_function(MakeEntry) -> case httpd_util:lookup(ConfigDb, Log) of undefined -> NoLog; LogRef -> - Entry = io_lib:format("[~s] ~s~n", [Date, Reason]), - {LogRef, Entry} + {LogRef, MakeEntry()} end. - + + %%%======================================================================== %%% Internal functions %%%======================================================================== + do_access_entry(ConfigDB, Headers, RequestLine, - RemoteHost, RFC931, AuthUser, Date, StatusCode, - Bytes) -> + RemoteHost, RFC931, AuthUser, Date, StatusCode, + Size) -> case httpd_util:lookup(ConfigDB, log_format, common) of common -> lists:flatten(io_lib:format("~s ~s ~s [~s] \"~s\" ~w ~w~n", [RemoteHost, RFC931, AuthUser, Date, RequestLine, - StatusCode, Bytes])); + StatusCode, Size])); combined -> Referer = proplists:get_value("referer", Headers, "-"), @@ -94,7 +136,7 @@ do_access_entry(ConfigDB, Headers, RequestLine, Headers, "-"), io_lib:format("~s ~s ~s [~s] \"~s\" ~w ~w ~s ~s~n", [RemoteHost, RFC931, AuthUser, Date, - RequestLine, StatusCode, Bytes, + RequestLine, StatusCode, Size, Referer, UserAgent]) end. diff --git a/lib/inets/src/http_server/httpd_request_handler.erl b/lib/inets/src/http_server/httpd_request_handler.erl index d2f22fce93..b62c10bbc7 100644 --- a/lib/inets/src/http_server/httpd_request_handler.erl +++ b/lib/inets/src/http_server/httpd_request_handler.erl @@ -162,7 +162,14 @@ continue_init(Manager, ConfigDB, SocketType, Socket, TimeOut) -> %% {stop, Reason, State} %% Description: Handling call messages %%-------------------------------------------------------------------- -handle_call(Request, From, State) -> +handle_call(Request, From, #state{mod = ModData} = State) -> + Error = + lists:flatten( + io_lib:format("Unexpected request: " + "~n~p" + "~nto request handler (~p) from ~p" + "~n", [Request, self(), From])), + error_log(Error, ModData), {stop, {call_api_violation, Request, From}, State}. %%-------------------------------------------------------------------- @@ -171,8 +178,15 @@ handle_call(Request, From, State) -> %% {stop, Reason, State} %% Description: Handling cast messages %%-------------------------------------------------------------------- -handle_cast(Msg, State) -> - {reply, {cast_api_violation, Msg}, State}. +handle_cast(Msg, #state{mod = ModData} = State) -> + Error = + lists:flatten( + io_lib:format("Unexpected message: " + "~n~p" + "~nto request handler (~p)" + "~n", [Msg, self()])), + error_log(Error, ModData), + {noreply, State}. %%-------------------------------------------------------------------- %% handle_info(Info, State) -> {noreply, State} | @@ -253,7 +267,10 @@ handle_info(timeout, #state{mod = ModData} = State) -> %% Default case handle_info(Info, #state{mod = ModData} = State) -> Error = lists:flatten( - io_lib:format("Unexpected message received: ~n~p~n", [Info])), + io_lib:format("Unexpected info: " + "~n~p" + "~nto request handler (~p)" + "~n", [Info, self()])), error_log(Error, ModData), {noreply, State}. diff --git a/lib/inets/src/http_server/mod_log.erl b/lib/inets/src/http_server/mod_log.erl index c8a2ec0dc4..62faa285df 100644 --- a/lib/inets/src/http_server/mod_log.erl +++ b/lib/inets/src/http_server/mod_log.erl @@ -100,7 +100,7 @@ do(Info) -> transfer_log(Info,"-",AuthUser,Date,StatusCode,Size), {proceed,Info#mod.data}; {response, Head, _Body} -> - Size = proplists:get_value(content_length,Head,unknown), + Size = content_length(Head), Code = proplists:get_value(code,Head,unknown), transfer_log(Info, "-", AuthUser, Date, Code, Size), {proceed, Info#mod.data}; @@ -254,4 +254,10 @@ auth_user(Data) -> RemoteUser end. - +content_length(Head) -> + case proplists:get_value(content_length, Head) of + undefined -> + unknown; + Size -> + list_to_integer(Size) + end. diff --git a/lib/inets/src/http_server/mod_responsecontrol.erl b/lib/inets/src/http_server/mod_responsecontrol.erl index 989f45db20..6af5f6211e 100644 --- a/lib/inets/src/http_server/mod_responsecontrol.erl +++ b/lib/inets/src/http_server/mod_responsecontrol.erl @@ -211,7 +211,7 @@ compare_etags(Tag,Etags) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% -%% Control if the file is modificated %% +%% Control if the file is modified %% %% %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl index d86e52f3d5..6e69c9a469 100644 --- a/lib/inets/test/httpc_SUITE.erl +++ b/lib/inets/test/httpc_SUITE.erl @@ -145,14 +145,6 @@ groups() -> ]. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - %%-------------------------------------------------------------------- %% Function: init_per_suite(Config) -> Config %% Config - [tuple()] @@ -226,9 +218,7 @@ init_per_testcase(initial_server_connect = Case, Config) -> %% this test case does not work unless it does try begin - ensure_started(crypto), - ensure_started(public_key), - ensure_started(ssl), + ?ENSURE_STARTED([crypto, public_key, ssl]), inets:start(), Config end @@ -267,10 +257,12 @@ init_per_testcase(Case, Timeout, Config) -> NewConfig = case atom_to_list(Case) of [$s, $s, $l | _] -> + ?ENSURE_STARTED([crypto, public_key, ssl]), init_per_testcase_ssl(ssl, PrivDir, SslConfFile, [{watchdog, Dog} | TmpConfig]); [$e, $s, $s, $l | _] -> + ?ENSURE_STARTED([crypto, public_key, ssl]), init_per_testcase_ssl(essl, PrivDir, SslConfFile, [{watchdog, Dog} | TmpConfig]); @@ -282,7 +274,7 @@ init_per_testcase(Case, Timeout, Config) -> inets:start(), tsp("init_per_testcase -> " "[proxy case] start crypto, public_key and ssl"), - try ensure_started([crypto, public_key, ssl]) of + try ?ENSURE_STARTED([crypto, public_key, ssl]) of ok -> [{watchdog, Dog} | TmpConfig] catch @@ -335,8 +327,8 @@ init_per_testcase(Case, Timeout, Config) -> end; "ipv6_" ++ _Rest -> - %% Ensure needed apps (crypto, public_key and ssl) started - try ensure_started([crypto, public_key, ssl]) of + %% Ensure needed apps (crypto, public_key and ssl) are started + try ?ENSURE_STARTED([crypto, public_key, ssl]) of ok -> Profile = ipv6, %% A stand-alone profile is represented by a pid() @@ -370,7 +362,7 @@ init_per_testcase(Case, Timeout, Config) -> %% This will fail for the ipv6_ - cases (but that is ok) ProxyExceptions = ["localhost", ?IPV6_LOCAL_HOST], - http:set_options([{proxy, {{?PROXY, ?PROXY_PORT}, ProxyExceptions}}]), + httpc:set_options([{proxy, {{?PROXY, ?PROXY_PORT}, ProxyExceptions}}]), inets:enable_trace(max, io, httpc), %% inets:enable_trace(max, io, all), %% snmp:set_trace([gen_tcp]), @@ -3553,21 +3545,5 @@ dummy_ssl_server_hang_loop(_) -> end. -ensure_started([]) -> - ok; -ensure_started([App|Apps]) -> - ensure_started(App), - ensure_started(Apps); -ensure_started(App) when is_atom(App) -> - case (catch application:start(App)) of - ok -> - ok; - {error, {already_started, _}} -> - ok; - Error -> - throw({error, {failed_starting, App, Error}}) - end. - - skip(Reason) -> {skip, Reason}. diff --git a/lib/inets/test/httpd_SUITE.erl b/lib/inets/test/httpd_SUITE.erl index ba31788ccc..5b571a9649 100644 --- a/lib/inets/test/httpd_SUITE.erl +++ b/lib/inets/test/httpd_SUITE.erl @@ -497,6 +497,7 @@ init_per_testcase2(Case, Config) -> _ -> NewConfig end; + _ -> NewConfig end, @@ -528,7 +529,7 @@ init_per_testcase3(Case, Config) -> application:stop(ssl), cleanup_mnesia(), - %% Set trace + %% Set trace level case lists:reverse(atom_to_list(Case)) of "tset_emit" ++ _Rest -> % test-cases ending with time_test io:format(user, "~w:init_per_testcase3(~w) -> disabling trace", @@ -581,9 +582,10 @@ init_per_testcase3(Case, Config) -> Rest; [X, $s, $s, $l, $_, $m, $o, $d, $_, $h, $t, $a, $c, $c, $e, $s, $s] -> + ?ENSURE_STARTED([crypto, public_key, ssl]), SslTag = case X of - $p -> ssl; % plain + $p -> ssl; % Plain $e -> essl % Erlang based ssl end, case inets_test_lib:start_http_server_ssl( @@ -597,6 +599,7 @@ init_per_testcase3(Case, Config) -> {skip, "SSL does not seem to be supported"} end; [X, $s, $s, $l, $_ | Rest] -> + ?ENSURE_STARTED([crypto, public_key, ssl]), SslTag = case X of $p -> ssl; @@ -679,36 +682,6 @@ end_per_testcase2(Case, Config) -> %%------------------------------------------------------------------------- %%------------------------------------------------------------------------- - - - - - - -%%------------------------------------------------------------------------- -http_1_1_ip(doc) -> - ["HTTP/1.1"]; -http_1_1_ip(suite) -> - [ - ip_host, - ip_chunked, - ip_expect, - ip_range, - ip_if_test, - ip_http_trace, - ip_http1_1_head, - ip_mod_cgi_chunked_encoding_test - ]. - -%%------------------------------------------------------------------------- - -%%------------------------------------------------------------------------- - -%%------------------------------------------------------------------------- - -%%------------------------------------------------------------------------- - -%%------------------------------------------------------------------------- ip_mod_alias(doc) -> ["Module test: mod_alias"]; ip_mod_alias(suite) -> @@ -717,6 +690,7 @@ ip_mod_alias(Config) when is_list(Config) -> httpd_mod:alias(ip_comm, ?IP_PORT, ?config(host, Config), ?config(node, Config)), ok. + %%------------------------------------------------------------------------- ip_mod_actions(doc) -> ["Module test: mod_actions"]; @@ -726,6 +700,7 @@ ip_mod_actions(Config) when is_list(Config) -> httpd_mod:actions(ip_comm, ?IP_PORT, ?config(host, Config), ?config(node, Config)), ok. + %%------------------------------------------------------------------------- ip_mod_security(doc) -> ["Module test: mod_security"]; diff --git a/lib/inets/test/httpd_time_test.erl b/lib/inets/test/httpd_time_test.erl index c54674be36..4e5f332122 100644 --- a/lib/inets/test/httpd_time_test.erl +++ b/lib/inets/test/httpd_time_test.erl @@ -333,51 +333,82 @@ poll(Error, _SocketType, _URI, _ExpRes) -> exit({failed_creating_socket, Error}). await_poll_response(ok, SocketType, Socket, ExpStatusCode) -> + await_poll_response2(SocketType, Socket, ExpStatusCode, []); +await_poll_response(Error, _SocketType, _Socket, _ExpStatusCode) -> + exit(Error). + +%% The reply *can* be split into two messages (this is a +%% result of OTP-9757 for ssl), so we read them all until +%% the sockets closes, then we analyze the response. +await_poll_response2(SocketType, Socket, ExpStatusCode, Data) -> receive %% SSL receives - {ssl, Socket, Data} -> - validate(ExpStatusCode, SocketType, Socket, Data); - {ssl_closed, Socket} -> - exit(connection_closed); + {ssl, Socket, NewData} -> + d("await_poll_response2 -> " + "received part (~w bytes) of the response", [sz(NewData)]), + await_poll_response2(SocketType, Socket, ExpStatusCode, + [NewData | Data]); + {ssl_closed, Socket} -> + %% We are done or we failed + d("await_poll_response2 -> " + "we are done after receiving ~w bytes data", [sz(Data)]), + validate(ExpStatusCode, SocketType, Socket, + lists:flatten(lists:reverse(Data))); {ssl_error, Socket, Error} -> exit({connection_error, Error}); %% TCP receives - {tcp, Socket, Response} -> - validate(ExpStatusCode, SocketType, Socket, Response); + {tcp, Socket, NewData} -> + d("await_poll_response2 -> " + "received part (~w bytes) of the response", [sz(NewData)]), + await_poll_response2(SocketType, Socket, ExpStatusCode, + [NewData | Data]); {tcp_closed, Socket} -> - exit(connection_closed); + %% We are done or we failed + d("await_poll_response2 -> " + "we are done after receiving ~w bytes data", [sz(Data)]), + validate(ExpStatusCode, SocketType, Socket, + lists:flatten(lists:reverse(Data))); {tcp_error, Socket, Error} -> exit({connection_error, Error}) after 10000 -> - exit(response_timed_out) - end; -await_poll_response(Error, _SocketType, _Socket, _ExpStatusCode) -> - exit(Error). - + d("we timed out while waiting for response, " + "validate whatever we got so far"), + validate(ExpStatusCode, SocketType, Socket, + lists:flatten(lists:reverse(Data))) + %% exit(response_timed_out) + end. -validate(ExpStatusCode, SocketType, Socket, Response) -> - Sz = sz(Response), - trash_the_rest(Socket, Sz), - inets_test_lib:close(SocketType, Socket), +validate(ExpStatusCode, _SocketType, _Socket, Response) -> + %% Sz = sz(Response), + %% trash_the_rest(Socket, Sz), + %% inets_test_lib:close(SocketType, Socket), case inets_regexp:split(Response," ") of - {ok,["HTTP/1.0", ExpStatusCode|_]} -> + {ok, ["HTTP/1.0", ExpStatusCode|_]} -> ok; - {ok,["HTTP/1.0", StatusCode|_]} -> + {ok, ["HTTP/1.0", StatusCode|_]} -> error_msg("Unexpected status code: ~p (~s). " "Expected status code: ~p (~s)", [StatusCode, status_to_message(StatusCode), ExpStatusCode, status_to_message(ExpStatusCode)]), exit({unexpected_response_code, StatusCode, ExpStatusCode}); - {ok,["HTTP/1.1", ExpStatusCode|_]} -> + {ok, ["HTTP/1.1", ExpStatusCode|_]} -> ok; - {ok,["HTTP/1.1", StatusCode|_]} -> + {ok, ["HTTP/1.1", StatusCode|_]} -> error_msg("Unexpected status code: ~p (~s). " "Expected status code: ~p (~s)", [StatusCode, status_to_message(StatusCode), ExpStatusCode, status_to_message(ExpStatusCode)]), - exit({unexpected_response_code, StatusCode, ExpStatusCode}) + exit({unexpected_response_code, StatusCode, ExpStatusCode}); + {ok, Unexpected} -> + error_msg("Unexpected response split: ~p (~s)", + [Unexpected, Response]), + exit({unexpected_response, Unexpected, Response}); + {error, Reason} -> + error_msg("Failed processing response: ~p (~s)", + [Reason, Response]), + exit({failed_response_processing, Reason, Response}) end. diff --git a/lib/inets/test/inets_app_test.erl b/lib/inets/test/inets_app_test.erl index 9d7202e087..db2218f3b6 100644 --- a/lib/inets/test/inets_app_test.erl +++ b/lib/inets/test/inets_app_test.erl @@ -45,8 +45,7 @@ end_per_testcase(_Case, Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% all() -> - [fields, modules, exportall, app_depend, - undef_funcs]. + [fields, modules, exportall, app_depend, undef_funcs]. groups() -> []. @@ -243,18 +242,11 @@ undef_funcs(doc) -> undef_funcs(Config) when is_list(Config) -> %% We need to check if there is a point to run this test. %% On some platforms, crypto will not build, which in turn - %% causes ssl to not to not build (at this time, this will + %% causes ssl to not build (at this time, this will %% change in the future). %% So, we first check if we can start crypto, and if not, %% we skip this test case! - case (catch crypto:start()) of - ok -> - ok; - {error, {already_started, crypto}} -> - ok; - _ -> - ?SKIP(crypto_start_check_failed) - end, + ?ENSURE_STARTED(crypto), App = inets, AppFile = key1search(app_file, Config), Mods = key1search(modules, AppFile), @@ -266,7 +258,7 @@ undef_funcs(Config) when is_list(Config) -> ok = xref:set_default(XRef, [{verbose,false},{warnings,false}]), XRefName = undef_funcs_make_name(App, xref_name), - {ok, XRefName} = xref:add_release(XRef, Root, {name,XRefName}), + {ok, XRefName} = xref:add_release(XRef, Root, {name, XRefName}), {ok, App} = xref:replace_application(XRef, App, EbinDir), {ok, Undefs} = xref:analyze(XRef, undefined_function_calls), xref:stop(XRef), diff --git a/lib/inets/test/inets_test_lib.erl b/lib/inets/test/inets_test_lib.erl index ddb1a49394..bbed35e1f8 100644 --- a/lib/inets/test/inets_test_lib.erl +++ b/lib/inets/test/inets_test_lib.erl @@ -35,6 +35,7 @@ -export([check_body/1]). -export([millis/0, millis_diff/2, hours/1, minutes/1, seconds/1, sleep/1]). -export([oscmd/1, has_ipv6_support/1]). +-export([ensure_started/1]). -export([non_pc_tc_maybe_skip/4, os_based_skip/1, skip/3, fail/3]). -export([flush/0]). -export([start_node/1, stop_node/1]). @@ -126,6 +127,37 @@ await_stopped(Node, N) -> %% ---------------------------------------------------------------- +%% Ensure apps are started +%% This to ensure we dont attempt to run teatcases on platforms +%% where there is no working ssl app. + +ensure_started([]) -> + ok; +ensure_started([App|Apps]) -> + ensure_started(App), + ensure_started(Apps); +ensure_started(crypto = App) -> + %% We have to treat crypto in this special way because + %% only this function ensures that the NIF lib is actually + %% loaded. And only by loading that lib can we know if it + %% is even possible to run crypto. + do_ensure_started(App, fun() -> crypto:start() end); +ensure_started(App) when is_atom(App) -> + do_ensure_started(App, fun() -> application:start(App) end). + +do_ensure_started(App, Start) when is_function(Start) -> + case (catch Start()) of + ok -> + ok; + {error, {already_started, _}} -> + ok; + Error -> + throw({error, {failed_starting, App, Error}}) + end. + + + +%% ---------------------------------------------------------------- %% HTTPD starter functions %% diff --git a/lib/inets/test/inets_test_lib.hrl b/lib/inets/test/inets_test_lib.hrl index 4dd81093a2..c578398c55 100644 --- a/lib/inets/test/inets_test_lib.hrl +++ b/lib/inets/test/inets_test_lib.hrl @@ -64,10 +64,11 @@ %% - Misc macros - --define(UPDATE(K,V,C), inets_test_lib:update_config(K,V,C)). --define(CONFIG(K,C), inets_test_lib:get_config(K,C)). --define(HOSTNAME(), inets_test_lib:hostname()). --define(SZ(X), inets_test_lib:sz(X)). +-define(ENSURE_STARTED(A), inets_test_lib:ensure_started(A)). +-define(UPDATE(K,V,C), inets_test_lib:update_config(K,V,C)). +-define(CONFIG(K,C), inets_test_lib:get_config(K,C)). +-define(HOSTNAME(), inets_test_lib:hostname()). +-define(SZ(X), inets_test_lib:sz(X)). %% - Test case macros - diff --git a/lib/kernel/doc/src/code.xml b/lib/kernel/doc/src/code.xml index 6b89711924..ee687511a3 100644 --- a/lib/kernel/doc/src/code.xml +++ b/lib/kernel/doc/src/code.xml @@ -229,10 +229,10 @@ <c>-code_path_choice Choice</c>. If the flag is set to <c>relaxed</c>, the code server will instead choose a suitable directory depending on the actual file structure. If there exists a regular - application ebin directory,situation it will be choosen. But if it does - not exist, the ebin directory in the archive is choosen if it + application ebin directory,situation it will be chosen. But if it does + not exist, the ebin directory in the archive is chosen if it exists. If neither of them exists the original directory will be - choosen.</p> + chosen.</p> <p>The command line flag <c>-code_path_choice Choice</c> does also affect how <c>init</c> interprets the <c>boot script</c>. The diff --git a/lib/kernel/doc/src/file.xml b/lib/kernel/doc/src/file.xml index 7db20e6343..719cbba2b8 100644 --- a/lib/kernel/doc/src/file.xml +++ b/lib/kernel/doc/src/file.xml @@ -149,6 +149,9 @@ <datatype> <name name="mode"/> </datatype> + <datatype> + <name name="sendfile_option"/> + </datatype> </datatypes> <funcs> @@ -536,7 +539,7 @@ <desc> <p>Makes a hard link from <c><anno>Existing</anno></c> to <c><anno>New</anno></c>, on - platforms that support links (Unix). This function returns + platforms that support links (Unix and Windows). This function returns <c>ok</c> if the link was successfully created, or <c>{error, <anno>Reason</anno>}</c>. On platforms that do not support links, <c>{error,enotsup}</c> is returned.</p> @@ -563,11 +566,12 @@ <name name="make_symlink" arity="2"/> <fsummary>Make a symbolic link to a file or directory</fsummary> <desc> - <p>This function creates a symbolic link <c><anno>Name2</anno></c> to - the file or directory <c><anno>Name1</anno></c>, on platforms that - support - symbolic links (most Unix systems). <c><anno>Name1</anno></c> need not - exist. This function returns <c>ok</c> if the link was + <p>This function creates a symbolic link <c><anno>New</anno></c> to + the file or directory <c><anno>Existing</anno></c>, on platforms that + support symbolic links (most Unix systems and Windows beginning with + Vista). + <c><anno>Existing</anno></c> need not exist. + This function returns <c>ok</c> if the link was successfully created, or <c>{error, <anno>Reason</anno>}</c>. On platforms that do not support symbolic links, <c>{error, enotsup}</c> @@ -577,11 +581,11 @@ <tag><c>eacces</c></tag> <item> <p>Missing read or write permissions for the parent directories - of <c><anno>Name1</anno></c> or <c><anno>Name2</anno></c>.</p> + of <c><anno>Existing</anno></c> or <c><anno>New</anno></c>.</p> </item> <tag><c>eexist</c></tag> <item> - <p><c><anno>Name2</anno></c> already exists.</p> + <p><c><anno>New</anno></c> already exists.</p> </item> <tag><c>enotsup</c></tag> <item> @@ -1574,6 +1578,48 @@ </desc> </func> <func> + <name name="sendfile" arity="2"/> + <fsummary>send a file to a socket</fsummary> + <desc> + <p>Sends the file <c>Filename</c> to <c>Socket</c>. + Returns <c>{ok, BytesSent}</c> if successful, + otherwise <c>{error, Reason}</c>.</p> + </desc> + </func> + <func> + <name name="sendfile" arity="5"/> + <fsummary>send a file to a socket</fsummary> + <desc> + <p>Sends <c>Bytes</c> from the file + referenced by <c>RawFile</c> beginning at <c>Offset</c> to + <c>Socket</c>. + Returns <c>{ok, BytesSent}</c> if successful, + otherwise <c>{error, Reason}</c>. If <c>Bytes</c> is set to + 0 all data after the given <c>Offset</c> is sent.</p> + <p>The file used must be opened using the raw flag, and the process + calling sendfile must be the controlling process of the socket. + See <seealso marker="gen_tcp#controlling_process-2">gen_tcp:controlling_process/2</seealso></p> + <p>If the OS used does not support sendfile, an Erlang fallback + using file:read and gen_tcp:send is used.</p> + <p>The option list can contain the following options: + <taglist> + <tag><c>chunk_size</c></tag> + <item>The chunk size used by the erlang fallback to send + data. If using the fallback, this should be set to a value + which comfortably fits in the systems memory. Default is 20 MB.</item> + </taglist> + </p> + <p>On operating systems with thread support, it is recommended to use + async threads. See the command line flag + <c>+A</c> in <seealso marker="erts:erl">erl(1)</seealso>. If it is not + possible to use async threads for sendfile, it is recommended to use + a relatively small value for the send buffer on the socket. Otherwise + the Erlang VM might loose some of its soft realtime guarantees. + Which size to use depends on the OS/hardware and the requirements + of the application.</p> + </desc> + </func> + <func> <name name="write" arity="2"/> <fsummary>Write to a file</fsummary> <desc> diff --git a/lib/kernel/doc/src/gen_sctp.xml b/lib/kernel/doc/src/gen_sctp.xml index 688cd0f78f..579b7f1f74 100644 --- a/lib/kernel/doc/src/gen_sctp.xml +++ b/lib/kernel/doc/src/gen_sctp.xml @@ -45,7 +45,15 @@ SUSE Linux Enterprise Server 10 (x86_64) kernel 2.6.16.27-0.6-smp, with lksctp-tools-1.0.6, briefly on Solaris 10, and later on SUSE Linux Enterprise Server 10 Service Pack 1 (x86_64) - kernel 2.6.16.54-0.2.3-smp with lksctp-tools-1.0.7.</p> + kernel 2.6.16.54-0.2.3-smp with lksctp-tools-1.0.7, + and later also on FreeBSD 8.2. + </p> + <p> + This module was written for one-to-many style sockets + (type <c>seqpacket</c>). With the addition of + <seealso marker="#peeloff/2">peeloff/2</seealso>, one-to-one style + sockets (type <c>stream</c>) were introduced. + </p> <p>Record definitions for the <c>gen_sctp</c> module can be found using:</p> <pre> -include_lib("kernel/include/inet_sctp.hrl"). </pre> <p>These record definitions use the "new" spelling 'adaptation', @@ -254,15 +262,19 @@ </desc> </func> <func> - <name name="listen" arity="2"/> + <name name="listen" arity="2" clause_i="1"/> + <name name="listen" arity="2" clause_i="2"/> <fsummary>Set up a socket to listen.</fsummary> <desc> <p>Sets up a socket to listen on the IP address and port number - it is bound to. <c><anno>IsServer</anno></c> must be <c>true</c> - or <c>false</c>. - In the contrast to TCP, in SCTP there is no listening queue length. - If <c><anno>IsServer</anno></c> is <c>true</c> the socket accepts new associations, i.e. - it will become an SCTP server socket.</p> + it is bound to.</p> + <p>For type <c>seqpacket</c> sockets (the default) + <c><anno>IsServer</anno></c> must be <c>true</c> or <c>false</c>. + In contrast to TCP, in SCTP there is no listening queue length. + If <c><anno>IsServer</anno></c> is <c>true</c> the socket accepts new associations, i.e. + it will become an SCTP server socket.</p> + <p>For type <c>stream</c> sockets <anno>Backlog</anno> defines + the backlog queue length just like in TCP.</p> </desc> </func> <func> @@ -295,12 +307,40 @@ is used. In particular, the socket is opened in <seealso marker="#option-binary">binary</seealso> and <seealso marker="#option-active">passive</seealso> mode, + with <anno>SockType</anno> <c>seqpacket</c>, and with reasonably large <seealso marker="#option-sndbuf">kernel</seealso> and driver <seealso marker="#option-buffer">buffers.</seealso></p> </desc> </func> <func> + <name name="peeloff" arity="2"/> + <fsummary> + Peel off a type <c>stream</c> socket from a type <c>seqpacket</c> one + </fsummary> + <desc> + <p> + Branch off an existing association <anno>Assoc</anno> + in a socket <anno>Socket</anno> of type <c>seqpacket</c> + (one-to-may style) into + a new socket <anno>NewSocket</anno> of type <c>stream</c> + (one-to-one style). + </p> + <p> + The existing association argument <anno>Assoc</anno> + can be either a + <seealso marker="#record-sctp_assoc_change"> + #sctp_assoc_change{} + </seealso> + record as returned from e.g + <seealso marker="#recv-2">recv/*</seealso>, + <seealso marker="#connect-5">connect/*</seealso> or + from a listening socket in active mode. Or it can be just + the field <c>assoc_id</c> integer from such a record. + </p> + </desc> + </func> + <func> <name name="recv" arity="1"/> <name name="recv" arity="2"/> <fsummary>Receive a message from a socket</fsummary> diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml index fad5af85bb..1a05b4ba99 100644 --- a/lib/kernel/doc/src/inet.xml +++ b/lib/kernel/doc/src/inet.xml @@ -573,6 +573,10 @@ fe80::204:acff:fe17:bf38 is longer than the max allowed length, the packet is considered invalid. The same happens if the packet header is too big for the socket receive buffer.</p> + <p>For line oriented protocols (<c>line</c>,<c>http*</c>), + option <c>packet_size</c> also guarantees that lines up to the + indicated length are accepted and not considered invalid due + to internal buffer limitations.</p> </item> <tag><c>{read_packets, Integer}</c>(UDP sockets)</tag> <item> diff --git a/lib/kernel/doc/src/kernel_app.xml b/lib/kernel/doc/src/kernel_app.xml index bf513b7815..0f71a4f0f2 100644 --- a/lib/kernel/doc/src/kernel_app.xml +++ b/lib/kernel/doc/src/kernel_app.xml @@ -4,7 +4,7 @@ <appref> <header> <copyright> - <year>1996</year><year>2009</year> + <year>1996</year><year>2011</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -231,6 +231,15 @@ MaxT = TickTime + TickTime / 4</code> <p><em>Note:</em> Normally, a terminating node is detected immediately.</p> </item> + <tag><c>shutdown_timeout = integer() | infinity</c></tag> + <item> + <p>Specifies the time <c>application_controller</c> will wait + for an application to terminate during node shutdown. If the + timer expires, <c>application_controller</c> will brutally + kill <c>application_master</c> of the hanging + application. If this parameter is undefined, it defaults + to <c>infinity</c>.</p> + </item> <tag><c>sync_nodes_mandatory = [NodeName]</c></tag> <item> <p>Specifies which other nodes <em>must</em> be alive in order diff --git a/lib/kernel/src/application.erl b/lib/kernel/src/application.erl index caac4d926c..c299fb085c 100644 --- a/lib/kernel/src/application.erl +++ b/lib/kernel/src/application.erl @@ -59,7 +59,7 @@ -callback start(StartType :: normal | {takeover, node()} | {failover, node()}, StartArgs :: term()) -> - {ok, pid()} | {ok, pid(), State :: term()} | {error, Reason :: term}. + {'ok', pid()} | {'ok', pid(), State :: term()} | {'error', Reason :: term()}. -callback stop(State :: term()) -> term(). diff --git a/lib/kernel/src/application_controller.erl b/lib/kernel/src/application_controller.erl index 42f527f400..ebfe84463a 100644 --- a/lib/kernel/src/application_controller.erl +++ b/lib/kernel/src/application_controller.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2010. All Rights Reserved. +%% Copyright Ericsson AB 1996-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -1180,10 +1180,27 @@ terminate(Reason, S) -> _ -> ok end, + ShutdownTimeout = + case application:get_env(kernel, shutdown_timeout) of + undefined -> infinity; + {ok,T} -> T + end, foreach(fun({_AppName, Id}) when is_pid(Id) -> + Ref = erlang:monitor(process, Id), + unlink(Id), exit(Id, shutdown), receive + %% Proc died before link {'EXIT', Id, _} -> ok + after 0 -> + receive + {'DOWN', Ref, process, Id, _} -> ok + after ShutdownTimeout -> + exit(Id, kill), + receive + {'DOWN', Ref, process, Id, _} -> ok + end + end end; (_) -> ok end, diff --git a/lib/kernel/src/code.erl b/lib/kernel/src/code.erl index 882e9625fe..b7fda69ce0 100644 --- a/lib/kernel/src/code.erl +++ b/lib/kernel/src/code.erl @@ -324,15 +324,7 @@ start_link(Flags) -> %%----------------------------------------------------------------- do_start(Flags) -> - %% The following module_info/1 calls are here to ensure - %% that these modules are loaded prior to their use elsewhere in - %% the code_server. - %% Otherwise a deadlock may occur when the code_server is starting. - code_server = code_server:module_info(module), - packages = packages:module_info(module), - catch hipe_unified_loader:load_hipe_modules(), - Modules2 = [gb_sets, gb_trees, ets, os, binary, unicode, filename, lists], - lists:foreach(fun (M) -> M = M:module_info(module) end, Modules2), + load_code_server_prerequisites(), Mode = get_mode(Flags), case init:get_argument(root) of @@ -360,6 +352,25 @@ do_start(Flags) -> {error, crash} end. +%% Make sure that all modules that the code_server process calls +%% (directly or indirectly) are loaded. Otherwise the code_server +%% process will deadlock. + +load_code_server_prerequisites() -> + %% Please keep the alphabetical order. + Needed = [binary, + ets, + filename, + gb_sets, + gb_trees, + hipe_unified_loader, + lists, + os, + packages, + unicode], + [M = M:module_info(module) || M <- Needed], + ok. + do_stick_dirs() -> do_s(compiler), do_s(stdlib), diff --git a/lib/kernel/src/code_server.erl b/lib/kernel/src/code_server.erl index e3d22e7999..32a12e2b52 100644 --- a/lib/kernel/src/code_server.erl +++ b/lib/kernel/src/code_server.erl @@ -32,6 +32,8 @@ -import(lists, [foreach/2]). +-define(ANY_NATIVE_CODE_LOADED, any_native_code_loaded). + -record(state, {supervisor, root, path, @@ -97,6 +99,8 @@ init(Ref, Parent, [Root,Mode0]) -> State0 end, + put(?ANY_NATIVE_CODE_LOADED, false), + Parent ! {Ref,{ok,self()}}, loop(State#state{supervisor = Parent}). @@ -1278,20 +1282,35 @@ load_native_code(Mod, Bin) -> %% Therefore we must test for that the loader modules are available %% before trying to to load native code. case erlang:module_loaded(hipe_unified_loader) of - false -> no_native; - true -> hipe_unified_loader:load_native_code(Mod, Bin) + false -> + no_native; + true -> + Result = hipe_unified_loader:load_native_code(Mod, Bin), + case Result of + {module,_} -> + put(?ANY_NATIVE_CODE_LOADED, true); + _ -> + ok + end, + Result end. hipe_result_to_status(Result) -> case Result of - {module,_} -> Result; - _ -> {error,Result} + {module,_} -> + put(?ANY_NATIVE_CODE_LOADED, true), + Result; + _ -> + {error,Result} end. post_beam_load(Mod) -> - case erlang:module_loaded(hipe_unified_loader) of - false -> ok; - true -> hipe_unified_loader:post_beam_load(Mod) + %% post_beam_load/1 can potentially be very expensive because it + %% blocks multi-scheduling; thus we want to avoid the call if we + %% know that it is not needed. + case get(?ANY_NATIVE_CODE_LOADED) of + true -> hipe_unified_loader:post_beam_load(Mod); + false -> ok end. int_list([H|T]) when is_integer(H) -> int_list(T); diff --git a/lib/kernel/src/disk_log.erl b/lib/kernel/src/disk_log.erl index d6bc23be6d..fb9415d440 100644 --- a/lib/kernel/src/disk_log.erl +++ b/lib/kernel/src/disk_log.erl @@ -64,7 +64,7 @@ %%-define(PROFILE(C), C). -define(PROFILE(C), void). --compile({inline,[{log_loop,4},{log_end_sync,2},{replies,2},{rflat,1}]}). +-compile({inline,[{log_loop,5},{log_end_sync,2},{replies,2},{rflat,1}]}). %%%---------------------------------------------------------------------- %%% Contract type specifications @@ -685,7 +685,7 @@ handle({From, {log, B}}, S) -> L when L#log.mode =:= read_only -> reply(From, {error, {read_only_mode, L#log.name}}, S); L when L#log.status =:= ok, L#log.format =:= internal -> - log_loop(S, From, [B], []); + log_loop(S, From, [B], [], iolist_size(B)); L when L#log.status =:= ok, L#log.format =:= external -> reply(From, {error, {format_external, L#log.name}}, S); L when L#log.status =:= {blocked, false} -> @@ -700,7 +700,7 @@ handle({From, {blog, B}}, S) -> L when L#log.mode =:= read_only -> reply(From, {error, {read_only_mode, L#log.name}}, S); L when L#log.status =:= ok -> - log_loop(S, From, [B], []); + log_loop(S, From, [B], [], iolist_size(B)); L when L#log.status =:= {blocked, false} -> reply(From, {error, {blocked_log, L#log.name}}, S); L when L#log.blocked_by =:= From -> @@ -714,7 +714,7 @@ handle({alog, B}, S) -> notify_owners({read_only,B}), loop(S); L when L#log.status =:= ok, L#log.format =:= internal -> - log_loop(S, [], [B], []); + log_loop(S, [], [B], [], iolist_size(B)); L when L#log.status =:= ok -> notify_owners({format_external, B}), loop(S); @@ -730,7 +730,7 @@ handle({balog, B}, S) -> notify_owners({read_only,B}), loop(S); L when L#log.status =:= ok -> - log_loop(S, [], [B], []); + log_loop(S, [], [B], [], iolist_size(B)); L when L#log.status =:= {blocked, false} -> notify_owners({blocked_log, B}), loop(S); @@ -1029,38 +1029,42 @@ handle(_, S) -> loop(S). sync_loop(From, S) -> - log_loop(S, [], [], From). + log_loop(S, [], [], From, 0). + +-define(MAX_LOOK_AHEAD, 64*1024). %% Inlined. -log_loop(S, Pids, _Bins, _Sync) when S#state.cache_error =/= ok -> +log_loop(S, Pids, _Bins, _Sync, _Sz) when S#state.cache_error =/= ok -> loop(cache_error(S, Pids)); -log_loop(S, Pids, Bins, Sync) when S#state.messages =:= [] -> +log_loop(#state{messages = []}=S, Pids, Bins, Sync, Sz) + when Sz > ?MAX_LOOK_AHEAD -> + loop(log_end(S, Pids, Bins, Sync)); +log_loop(#state{messages = []}=S, Pids, Bins, Sync, Sz) -> receive Message -> - log_loop(Message, Pids, Bins, Sync, S, get(log)) + log_loop(Message, Pids, Bins, Sync, Sz, S, get(log)) after 0 -> loop(log_end(S, Pids, Bins, Sync)) end; -log_loop(S, Pids, Bins, Sync) -> +log_loop(S, Pids, Bins, Sync, Sz) -> [M | Ms] = S#state.messages, S1 = S#state{messages = Ms}, - log_loop(M, Pids, Bins, Sync, S1, get(log)). + log_loop(M, Pids, Bins, Sync, Sz, S1, get(log)). %% Items logged after the last sync request found are sync:ed as well. -log_loop({alog,B}, Pids, Bins, Sync, S, L) when L#log.format =:= internal -> +log_loop({alog,B}, Pids, Bins, Sync, Sz, S, #log{format = internal}) -> %% {alog, _} allowed for the internal format only. - log_loop(S, Pids, [B | Bins], Sync); -log_loop({balog, B}, Pids, Bins, Sync, S, _L) -> - log_loop(S, Pids, [B | Bins], Sync); -log_loop({From, {log, B}}, Pids, Bins, Sync, S, L) - when L#log.format =:= internal -> + log_loop(S, Pids, [B | Bins], Sync, Sz+iolist_size(B)); +log_loop({balog, B}, Pids, Bins, Sync, Sz, S, _L) -> + log_loop(S, Pids, [B | Bins], Sync, Sz+iolist_size(B)); +log_loop({From, {log, B}}, Pids, Bins, Sync, Sz, S, #log{format = internal}) -> %% {log, _} allowed for the internal format only. - log_loop(S, [From | Pids], [B | Bins], Sync); -log_loop({From, {blog, B}}, Pids, Bins, Sync, S, _L) -> - log_loop(S, [From | Pids], [B | Bins], Sync); -log_loop({From, sync}, Pids, Bins, Sync, S, _L) -> - log_loop(S, Pids, Bins, [From | Sync]); -log_loop(Message, Pids, Bins, Sync, S, _L) -> + log_loop(S, [From | Pids], [B | Bins], Sync, Sz+iolist_size(B)); +log_loop({From, {blog, B}}, Pids, Bins, Sync, Sz, S, _L) -> + log_loop(S, [From | Pids], [B | Bins], Sync, Sz+iolist_size(B)); +log_loop({From, sync}, Pids, Bins, Sync, Sz, S, _L) -> + log_loop(S, Pids, Bins, [From | Sync], Sz); +log_loop(Message, Pids, Bins, Sync, _Sz, S, _L) -> NS = log_end(S, Pids, Bins, Sync), handle(Message, NS). diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl index 706c60caaf..7793009bb9 100644 --- a/lib/kernel/src/file.erl +++ b/lib/kernel/src/file.erl @@ -51,6 +51,9 @@ -export([pid2name/1]). +%% Sendfile functions +-export([sendfile/2,sendfile/5]). + %%% Obsolete exported functions -export([raw_read_file_info/1, raw_write_file_info/2]). @@ -103,7 +106,7 @@ -type date_time() :: calendar:datetime(). -type posix_file_advise() :: 'normal' | 'sequential' | 'random' | 'no_reuse' | 'will_need' | 'dont_need'. - +-type sendfile_option() :: {chunk_size, non_neg_integer()}. %%%----------------------------------------------------------------- %%% General functions @@ -264,9 +267,9 @@ read_file(Name) -> make_link(Old, New) -> check_and_call(make_link, [file_name(Old), file_name(New)]). --spec make_symlink(Name1, Name2) -> ok | {error, Reason} when - Name1 :: name(), - Name2 :: name(), +-spec make_symlink(Existing, New) -> ok | {error, Reason} when + Existing :: name(), + New :: name(), Reason :: posix() | badarg. make_symlink(Old, New) -> @@ -1100,8 +1103,9 @@ change_group(Name, GroupId) Mtime :: date_time(), Reason :: posix() | badarg. -change_time(Name, Time) - when is_tuple(Time) -> +change_time(Name, {{Y, M, D}, {H, Min, Sec}}=Time) + when is_integer(Y), is_integer(M), is_integer(D), + is_integer(H), is_integer(Min), is_integer(Sec)-> write_file_info(Name, #file_info{mtime=Time}). -spec change_time(Filename, Atime, Mtime) -> ok | {error, Reason} when @@ -1110,10 +1114,148 @@ change_time(Name, Time) Mtime :: date_time(), Reason :: posix() | badarg. -change_time(Name, Atime, Mtime) - when is_tuple(Atime), is_tuple(Mtime) -> +change_time(Name, {{AY, AM, AD}, {AH, AMin, ASec}}=Atime, + {{MY, MM, MD}, {MH, MMin, MSec}}=Mtime) + when is_integer(AY), is_integer(AM), is_integer(AD), + is_integer(AH), is_integer(AMin), is_integer(ASec), + is_integer(MY), is_integer(MM), is_integer(MD), + is_integer(MH), is_integer(MMin), is_integer(MSec)-> write_file_info(Name, #file_info{atime=Atime, mtime=Mtime}). +%% +%% Send data using sendfile +%% + +-define(MAX_CHUNK_SIZE, (1 bsl 20)*20). %% 20 MB, has to fit in primary memory + +-spec sendfile(RawFile, Socket, Offset, Bytes, Opts) -> + {'ok', non_neg_integer()} | {'error', inet:posix() | badarg | not_owner} when + RawFile :: file:fd(), + Socket :: inet:socket(), + Offset :: non_neg_integer(), + Bytes :: non_neg_integer(), + Opts :: [sendfile_option()]. +sendfile(File, _Sock, _Offet, _Bytes, _Opts) when is_pid(File) -> + {error, badarg}; +sendfile(File, Sock, Offset, Bytes, []) -> + sendfile(File, Sock, Offset, Bytes, ?MAX_CHUNK_SIZE, [], [], + false, false, false); +sendfile(File, Sock, Offset, Bytes, Opts) -> + ChunkSize0 = proplists:get_value(chunk_size, Opts, ?MAX_CHUNK_SIZE), + ChunkSize = if ChunkSize0 > ?MAX_CHUNK_SIZE -> + ?MAX_CHUNK_SIZE; + true -> ChunkSize0 + end, + %% Support for headers, trailers and options has been removed because the + %% Darwin and BSD API for using it does not play nice with + %% non-blocking sockets. See unix_efile.c for more info. + sendfile(File, Sock, Offset, Bytes, ChunkSize, [], [], + false,false,false). + +%% sendfile/2 +-spec sendfile(Filename, Socket) -> + {'ok', non_neg_integer()} | {'error', inet:posix() | badarg | not_owner} + when Filename :: file:name(), + Socket :: inet:socket(). +sendfile(Filename, Sock) -> + case file:open(Filename, [read, raw, binary]) of + {error, Reason} -> + {error, Reason}; + {ok, Fd} -> + Res = sendfile(Fd, Sock, 0, 0, []), + file:close(Fd), + Res + end. + +%% Internal sendfile functions +sendfile(#file_descriptor{ module = Mod } = Fd, Sock, Offset, Bytes, + ChunkSize, Headers, Trailers, Nodiskio, MNowait, Sync) + when is_port(Sock) -> + case Mod:sendfile(Fd, Sock, Offset, Bytes, ChunkSize, Headers, Trailers, + Nodiskio, MNowait, Sync) of + {error, enotsup} -> + sendfile_fallback(Fd, Sock, Offset, Bytes, ChunkSize, + Headers, Trailers); + Else -> + Else + end; +sendfile(_,_,_,_,_,_,_,_,_,_) -> + {error, badarg}. + +%%% +%% Sendfile Fallback +%%% +sendfile_fallback(File, Sock, Offset, Bytes, ChunkSize, + Headers, Trailers) + when Headers == []; is_integer(Headers) -> + case sendfile_fallback(File, Sock, Offset, Bytes, ChunkSize) of + {ok, BytesSent} when is_list(Trailers), + Trailers =/= [], + is_integer(Headers) -> + sendfile_send(Sock, Trailers, BytesSent+Headers); + {ok, BytesSent} when is_list(Trailers), Trailers =/= [] -> + sendfile_send(Sock, Trailers, BytesSent); + {ok, BytesSent} when is_integer(Headers) -> + {ok, BytesSent + Headers}; + Else -> + Else + end; +sendfile_fallback(File, Sock, Offset, Bytes, ChunkSize, Headers, Trailers) -> + case sendfile_send(Sock, Headers, 0) of + {ok, BytesSent} -> + sendfile_fallback(File, Sock, Offset, Bytes, ChunkSize, BytesSent, + Trailers); + Else -> + Else + end. + + +sendfile_fallback(File, Sock, Offset, Bytes, ChunkSize) -> + {ok, CurrPos} = file:position(File, {cur, 0}), + {ok, _NewPos} = file:position(File, {bof, Offset}), + Res = sendfile_fallback_int(File, Sock, Bytes, ChunkSize, 0), + file:position(File, {bof, CurrPos}), + Res. + + +sendfile_fallback_int(File, Sock, Bytes, ChunkSize, BytesSent) + when Bytes > BytesSent; Bytes == 0 -> + Size = if Bytes == 0 -> + ChunkSize; + (Bytes - BytesSent + ChunkSize) > 0 -> + Bytes - BytesSent; + true -> + ChunkSize + end, + case file:read(File, Size) of + {ok, Data} -> + case sendfile_send(Sock, Data, BytesSent) of + {ok,NewBytesSent} -> + sendfile_fallback_int( + File, Sock, Bytes, ChunkSize, + NewBytesSent); + Error -> + Error + end; + eof -> + {ok, BytesSent}; + Error -> + Error + end; +sendfile_fallback_int(_File, _Sock, BytesSent, _ChunkSize, BytesSent) -> + {ok, BytesSent}. + +sendfile_send(Sock, Data, Old) -> + Len = iolist_size(Data), + case gen_tcp:send(Sock, Data) of + ok -> + {ok, Len+Old}; + Else -> + Else + end. + + + %%%----------------------------------------------------------------- %%% Helpers diff --git a/lib/kernel/src/gen_sctp.erl b/lib/kernel/src/gen_sctp.erl index 6cebb7ab97..77ca26b845 100644 --- a/lib/kernel/src/gen_sctp.erl +++ b/lib/kernel/src/gen_sctp.erl @@ -27,7 +27,8 @@ -include("inet_sctp.hrl"). -export([open/0,open/1,open/2,close/1]). --export([listen/2,connect/4,connect/5,connect_init/4,connect_init/5]). +-export([listen/2,peeloff/2]). +-export([connect/4,connect/5,connect_init/4,connect_init/5]). -export([eof/2,abort/2]). -export([send/3,send/4,recv/1,recv/2]). -export([error_string/1]). @@ -109,9 +110,11 @@ open() -> | {ifaddr,IP} | inet:address_family() | {port,Port} + | {type,SockType} | option(), IP :: inet:ip_address() | any | loopback, Port :: inet:port_number(), + SockType :: seqpacket | stream, Socket :: sctp_socket(). open(Opts) when is_list(Opts) -> @@ -134,9 +137,11 @@ open(X) -> | {ifaddr,IP} | inet:address_family() | {port,Port} + | {type,SockType} | option(), IP :: inet:ip_address() | any | loopback, Port :: inet:port_number(), + SockType :: seqpacket | stream, Socket :: sctp_socket(). open(Port, Opts) when is_integer(Port), is_list(Opts) -> @@ -161,17 +166,38 @@ close(S) -> -spec listen(Socket, IsServer) -> ok | {error, Reason} when Socket :: sctp_socket(), IsServer :: boolean(), + Reason :: term(); + (Socket, Backlog) -> ok | {error, Reason} when + Socket :: sctp_socket(), + Backlog :: integer(), Reason :: term(). -listen(S, Flag) when is_port(S), is_boolean(Flag) -> +listen(S, Backlog) + when is_port(S), is_boolean(Backlog); + is_port(S), is_integer(Backlog) -> case inet_db:lookup_socket(S) of {ok,Mod} -> - Mod:listen(S, Flag); + Mod:listen(S, Backlog); Error -> Error end; listen(S, Flag) -> erlang:error(badarg, [S,Flag]). +-spec peeloff(Socket, Assoc) -> {ok, NewSocket} | {error, Reason} when + Socket :: sctp_socket(), + Assoc :: #sctp_assoc_change{} | assoc_id(), + NewSocket :: sctp_socket(), + Reason :: term(). + +peeloff(S, #sctp_assoc_change{assoc_id=AssocId}) when is_port(S) -> + peeloff(S, AssocId); +peeloff(S, AssocId) when is_port(S), is_integer(AssocId) -> + case inet_db:lookup_socket(S) of + {ok,Mod} -> + Mod:peeloff(S, AssocId); + Error -> Error + end. + -spec connect(Socket, Addr, Port, Opts) -> {ok, Assoc} | {error, inet:posix()} when Socket :: sctp_socket(), Addr :: inet:ip_address() | inet:hostname(), diff --git a/lib/kernel/src/gen_tcp.erl b/lib/kernel/src/gen_tcp.erl index 8ab18c01b4..4d6c7f5f1d 100644 --- a/lib/kernel/src/gen_tcp.erl +++ b/lib/kernel/src/gen_tcp.erl @@ -27,6 +27,7 @@ -export([fdopen/2]). -include("inet_int.hrl"). +-include("file.hrl"). -type option() :: {active, true | false | once} | @@ -302,7 +303,7 @@ unrecv(S, Data) when is_port(S) -> Mod:unrecv(S, Data); Error -> Error - end. + end. %% %% Set controlling process @@ -354,3 +355,4 @@ mod([_|Opts], Address) -> mod(Opts, Address); mod([], Address) -> mod(Address). + diff --git a/lib/kernel/src/hipe_unified_loader.erl b/lib/kernel/src/hipe_unified_loader.erl index 1d3eb926ca..8b3aa0286d 100644 --- a/lib/kernel/src/hipe_unified_loader.erl +++ b/lib/kernel/src/hipe_unified_loader.erl @@ -36,7 +36,6 @@ -export([chunk_name/1, %% Only the code and code_server modules may call the entries below! - load_hipe_modules/0, load_native_code/2, post_beam_load/1, load_module/3, @@ -78,16 +77,6 @@ chunk_name(Architecture) -> %%======================================================================== --spec load_hipe_modules() -> 'ok'. -%% @doc -%% Ensures HiPE's loader modules are loaded. -%% Called from code.erl at start-up. - -load_hipe_modules() -> - ok. - -%%======================================================================== - -spec load_native_code(Mod, binary()) -> 'no_native' | {'module', Mod} when is_subtype(Mod, atom()). %% @doc diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl index 48a6f3db65..49f64a9236 100644 --- a/lib/kernel/src/inet.erl +++ b/lib/kernel/src/inet.erl @@ -36,10 +36,14 @@ -export([i/0, i/1, i/2]). --export([getll/1, getfd/1, open/7, fdopen/5]). +-export([getll/1, getfd/1, open/8, fdopen/6]). -export([tcp_controlling_process/2, udp_controlling_process/2, tcp_close/1, udp_close/1]). + +%% used by sendfile +-export([lock_socket/2]). + %% used by socks5 -export([setsockname/2, setpeername/2]). @@ -115,7 +119,8 @@ 'mtu' | 'netmask' | 'flags' |'hwaddr'. -type address_family() :: 'inet' | 'inet6'. --type protocol_option() :: 'tcp' | 'udp' | 'sctp'. +-type socket_protocol() :: 'tcp' | 'udp' | 'sctp'. +-type socket_type() :: 'stream' | 'dgram' | 'seqpacket'. -type stat_option() :: 'recv_cnt' | 'recv_max' | 'recv_avg' | 'recv_oct' | 'recv_dvi' | 'send_cnt' | 'send_max' | 'send_avg' | 'send_oct' | 'send_pend'. @@ -748,6 +753,8 @@ sctp_opt([Opt|Opts], Mod, R, As) -> sctp_opt(Opts, Mod, R#sctp_opts{port=P}, As); Error -> Error end; + {type,Type} when Type =:= seqpacket; Type =:= stream -> + sctp_opt(Opts, Mod, R#sctp_opts{type=Type}, As); binary -> sctp_opt (Opts, Mod, R, As, mode, binary); list -> sctp_opt (Opts, Mod, R, As, mode, list); {sctp_module,_} -> sctp_opt (Opts, Mod, R, As); % Done with @@ -996,13 +1003,14 @@ gethostbyaddr_tm_native(Addr, Timer, Opts) -> Addr :: ip_address(), Port :: port_number(), Opts :: [socket_setopt()], - Protocol :: protocol_option(), - Family :: 'inet' | 'inet6', + Protocol :: socket_protocol(), + Family :: address_family(), + Type :: socket_type(), Module :: atom()) -> {'ok', socket()} | {'error', posix()}. -open(Fd, Addr, Port, Opts, Protocol, Family, Module) when Fd < 0 -> - case prim_inet:open(Protocol, Family) of +open(Fd, Addr, Port, Opts, Protocol, Family, Type, Module) when Fd < 0 -> + case prim_inet:open(Protocol, Family, Type) of {ok,S} -> case prim_inet:setopts(S, Opts) of ok -> @@ -1029,18 +1037,19 @@ open(Fd, Addr, Port, Opts, Protocol, Family, Module) when Fd < 0 -> Error -> Error end; -open(Fd, _Addr, _Port, Opts, Protocol, Family, Module) -> - fdopen(Fd, Opts, Protocol, Family, Module). +open(Fd, _Addr, _Port, Opts, Protocol, Family, Type, Module) -> + fdopen(Fd, Opts, Protocol, Family, Type, Module). -spec fdopen(Fd :: non_neg_integer(), Opts :: [socket_setopt()], - Protocol :: protocol_option(), + Protocol :: socket_protocol(), Family :: address_family(), + Type :: socket_type(), Module :: atom()) -> {'ok', socket()} | {'error', posix()}. -fdopen(Fd, Opts, Protocol, Family, Module) -> - case prim_inet:fdopen(Protocol, Fd, Family) of +fdopen(Fd, Opts, Protocol, Family, Type, Module) -> + case prim_inet:fdopen(Protocol, Family, Type, Fd) of {ok, S} -> case prim_inet:setopts(S, Opts) of ok -> @@ -1056,18 +1065,24 @@ fdopen(Fd, Opts, Protocol, Family, Module) -> %% socket stat %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -i() -> i(tcp), i(udp). +i() -> i(tcp), i(udp), i(sctp). i(Proto) -> i(Proto, [port, module, recv, sent, owner, - local_address, foreign_address, state]). + local_address, foreign_address, state, type]). i(tcp, Fs) -> ii(tcp_sockets(), Fs, tcp); i(udp, Fs) -> - ii(udp_sockets(), Fs, udp). + ii(udp_sockets(), Fs, udp); +i(sctp, Fs) -> + ii(sctp_sockets(), Fs, sctp). ii(Ss, Fs, Proto) -> - LLs = [h_line(Fs) | info_lines(Ss, Fs, Proto)], + LLs = + case info_lines(Ss, Fs, Proto) of + [] -> []; + InfoLines -> [h_line(Fs) | InfoLines] + end, Maxs = foldl( fun(Line,Max0) -> smax(Max0,Line) end, duplicate(length(Fs),0),LLs), @@ -1135,6 +1150,7 @@ info(S, F, Proto) -> case prim_inet:gettype(S) of {ok,{_,stream}} -> "STREAM"; {ok,{_,dgram}} -> "DGRAM"; + {ok,{_,seqpacket}} -> "SEQPACKET"; _ -> " " end; fd -> @@ -1186,6 +1202,7 @@ fmt_port(N, Proto) -> %% Return a list of all tcp sockets tcp_sockets() -> port_list("tcp_inet"). udp_sockets() -> port_list("udp_inet"). +sctp_sockets() -> port_list("sctp_inet"). %% Return all ports having the name 'Name' port_list(Name) -> @@ -1340,3 +1357,14 @@ stop_timer(Timer) -> end; T -> T end. + + +lock_socket(S,Val) -> + case erlang:port_info(S, connected) of + {connected, Pid} when Pid =/= self() -> + {error, not_owner}; + undefined -> + {error, einval}; + _ -> + prim_inet:ignorefd(S,Val) + end. diff --git a/lib/kernel/src/inet6_sctp.erl b/lib/kernel/src/inet6_sctp.erl index 5bf3fca647..c47483bbdd 100644 --- a/lib/kernel/src/inet6_sctp.erl +++ b/lib/kernel/src/inet6_sctp.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2010. All Rights Reserved. +%% Copyright Ericsson AB 2007-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -32,7 +32,8 @@ -define(FAMILY, inet6). -export([getserv/1,getaddr/1,getaddr/2,translate_ip/1]). --export([open/1,close/1,listen/2,connect/5,sendmsg/3,send/4,recv/2]). +-export([open/1,close/1,listen/2,peeloff/2,connect/5]). +-export([sendmsg/3,send/4,recv/2]). @@ -54,8 +55,8 @@ translate_ip(IP) -> open(Opts) -> case inet:sctp_options(Opts, ?MODULE) of - {ok,#sctp_opts{fd=Fd,ifaddr=Addr,port=Port,opts=SOs}} -> - inet:open(Fd, Addr, Port, SOs, sctp, ?FAMILY, ?MODULE); + {ok,#sctp_opts{fd=Fd,ifaddr=Addr,port=Port,type=Type,opts=SOs}} -> + inet:open(Fd, Addr, Port, SOs, sctp, ?FAMILY, Type, ?MODULE); Error -> Error end. @@ -65,6 +66,14 @@ close(S) -> listen(S, Flag) -> prim_inet:listen(S, Flag). +peeloff(S, AssocId) -> + case prim_inet:peeloff(S, AssocId) of + {ok, NewS}=Result -> + inet_db:register_socket(NewS, ?MODULE), + Result; + Error -> Error + end. + connect(S, Addr, Port, Opts, Timer) -> inet_sctp:connect(S, Addr, Port, Opts, Timer). diff --git a/lib/kernel/src/inet6_tcp.erl b/lib/kernel/src/inet6_tcp.erl index cc45f6c7f6..c714b2bee0 100644 --- a/lib/kernel/src/inet6_tcp.erl +++ b/lib/kernel/src/inet6_tcp.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. +%% Copyright Ericsson AB 1997-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -93,7 +93,7 @@ do_connect(Addr = {A,B,C,D,E,F,G,H}, Port, Opts, Time) when port=BPort, opts=SockOpts}} when ?ip6(Ab,Bb,Cb,Db,Eb,Fb,Gb,Hb), ?port(BPort) -> - case inet:open(Fd,BAddr,BPort,SockOpts,tcp,inet6,?MODULE) of + case inet:open(Fd,BAddr,BPort,SockOpts,tcp,inet6,stream,?MODULE) of {ok, S} -> case prim_inet:connect(S, Addr, Port, Time) of ok -> {ok,S}; @@ -115,7 +115,7 @@ listen(Port, Opts) -> port=BPort, opts=SockOpts}=R} when ?ip6(A,B,C,D,E,F,G,H), ?port(BPort) -> - case inet:open(Fd,BAddr,BPort,SockOpts,tcp,inet6,?MODULE) of + case inet:open(Fd,BAddr,BPort,SockOpts,tcp,inet6,stream,?MODULE) of {ok, S} -> case prim_inet:listen(S, R#listen_opts.backlog) of ok -> {ok, S}; @@ -149,5 +149,5 @@ accept(L,Timeout) -> %% Create a port/socket from a file descriptor %% fdopen(Fd, Opts) -> - inet:fdopen(Fd, Opts, tcp, inet6, ?MODULE). + inet:fdopen(Fd, Opts, tcp, inet6, stream, ?MODULE). diff --git a/lib/kernel/src/inet6_udp.erl b/lib/kernel/src/inet6_udp.erl index e81d417151..ca43c94211 100644 --- a/lib/kernel/src/inet6_udp.erl +++ b/lib/kernel/src/inet6_udp.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. +%% Copyright Ericsson AB 1997-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -45,7 +45,7 @@ open(Port, Opts) -> port=BPort, opts=SockOpts}} when ?ip6(A,B,C,D,E,F,G,H), ?port(BPort) -> - inet:open(Fd,BAddr,BPort,SockOpts,udp,inet6,?MODULE); + inet:open(Fd,BAddr,BPort,SockOpts,udp,inet6,dgram,?MODULE); {ok, _} -> exit(badarg) end. @@ -84,4 +84,4 @@ controlling_process(Socket, NewOwner) -> %% Create a port/socket from a file descriptor %% fdopen(Fd, Opts) -> - inet:fdopen(Fd, Opts, udp, inet6, ?MODULE). + inet:fdopen(Fd, Opts, udp, inet6, dgram, ?MODULE). diff --git a/lib/kernel/src/inet_int.hrl b/lib/kernel/src/inet_int.hrl index 6f1688c6a2..cf893c73eb 100644 --- a/lib/kernel/src/inet_int.hrl +++ b/lib/kernel/src/inet_int.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% Copyright Ericsson AB 1997-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -29,7 +29,7 @@ -define(INET_AF_ANY, 3). % Fake for ANY in any address family -define(INET_AF_LOOPBACK, 4). % Fake for LOOPBACK in any address family -%% type codes (gettype, INET_REQ_GETTYPE) +%% type codes to open and gettype - INET_REQ_GETTYPE -define(INET_TYPE_STREAM, 1). -define(INET_TYPE_DGRAM, 2). -define(INET_TYPE_SEQPACKET, 3). @@ -83,16 +83,21 @@ -define(INET_REQ_IFSET, 23). -define(INET_REQ_SUBSCRIBE, 24). -define(INET_REQ_GETIFADDRS, 25). +-define(INET_REQ_ACCEPT, 26). +-define(INET_REQ_LISTEN, 27). +-define(INET_REQ_IGNOREFD, 28). + %% TCP requests --define(TCP_REQ_ACCEPT, 40). --define(TCP_REQ_LISTEN, 41). +%%-define(TCP_REQ_ACCEPT, 40). MOVED +%%-define(TCP_REQ_LISTEN, 41). MERGED -define(TCP_REQ_RECV, 42). -define(TCP_REQ_UNRECV, 43). -define(TCP_REQ_SHUTDOWN, 44). %% UDP and SCTP requests -define(PACKET_REQ_RECV, 60). --define(SCTP_REQ_LISTEN, 61). +%%-define(SCTP_REQ_LISTEN, 61). MERGED -define(SCTP_REQ_BINDX, 62). %% Multi-home SCTP bind +-define(SCTP_REQ_PEELOFF, 63). %% subscribe codes, INET_REQ_SUBSCRIBE -define(INET_SUBS_EMPTY_OUT_Q, 1). @@ -100,7 +105,7 @@ %% reply codes for *_REQ_* -define(INET_REP_ERROR, 0). -define(INET_REP_OK, 1). --define(INET_REP_SCTP, 2). +-define(INET_REP, 2). %% INET, TCP and UDP options: -define(INET_OPT_REUSEADDR, 0). @@ -399,6 +404,7 @@ ifaddr, port = 0, fd = -1, + type = seqpacket, opts = [{mode, binary}, {buffer, ?SCTP_DEF_BUFSZ}, {sndbuf, ?SCTP_DEF_BUFSZ}, diff --git a/lib/kernel/src/inet_sctp.erl b/lib/kernel/src/inet_sctp.erl index de74b573bd..2d799d79fa 100644 --- a/lib/kernel/src/inet_sctp.erl +++ b/lib/kernel/src/inet_sctp.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2010. All Rights Reserved. +%% Copyright Ericsson AB 2007-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -31,7 +31,8 @@ -define(FAMILY, inet). -export([getserv/1,getaddr/1,getaddr/2,translate_ip/1]). --export([open/1,close/1,listen/2,connect/5,sendmsg/3,send/4,recv/2]). +-export([open/1,close/1,listen/2,peeloff/2,connect/5]). +-export([sendmsg/3,send/4,recv/2]). @@ -53,8 +54,8 @@ translate_ip(IP) -> open(Opts) -> case inet:sctp_options(Opts, ?MODULE) of - {ok,#sctp_opts{fd=Fd,ifaddr=Addr,port=Port,opts=SOs}} -> - inet:open(Fd, Addr, Port, SOs, sctp, ?FAMILY, ?MODULE); + {ok,#sctp_opts{fd=Fd,ifaddr=Addr,port=Port,type=Type,opts=SOs}} -> + inet:open(Fd, Addr, Port, SOs, sctp, ?FAMILY, Type, ?MODULE); Error -> Error end. @@ -64,6 +65,14 @@ close(S) -> listen(S, Flag) -> prim_inet:listen(S, Flag). +peeloff(S, AssocId) -> + case prim_inet:peeloff(S, AssocId) of + {ok, NewS}=Result -> + inet_db:register_socket(NewS, ?MODULE), + Result; + Error -> Error + end. + %% A non-blocking connect is implemented when the initial call is to %% gen_sctp:connect_init which passes the value nowait as the Timer connect(S, Addr, Port, Opts, Timer) -> @@ -102,7 +111,7 @@ connect(S, Addr, Port, Opts, Timer) -> connect_get_assoc(S, Addr, Port, false, Timer) -> case recv(S, inet:timeout(Timer)) of - {ok, {Addr, Port, [], #sctp_assoc_change{state=St}=Ev}} -> + {ok, {Addr, Port, _, #sctp_assoc_change{state=St}=Ev}} -> if St =:= comm_up -> %% Yes, successfully connected, return the whole %% sctp_assoc_change event (containing, in particular, @@ -123,7 +132,7 @@ connect_get_assoc(S, Addr, Port, false, Timer) -> connect_get_assoc(S, Addr, Port, Active, Timer) -> Timeout = inet:timeout(Timer), receive - {sctp,S,Addr,Port,{[],#sctp_assoc_change{state=St}=Ev}} -> + {sctp,S,Addr,Port,{_,#sctp_assoc_change{state=St}=Ev}} -> case Active of once -> prim_inet:setopt(S, active, once); diff --git a/lib/kernel/src/inet_tcp.erl b/lib/kernel/src/inet_tcp.erl index 6dadccd6a9..4c2db16ce3 100644 --- a/lib/kernel/src/inet_tcp.erl +++ b/lib/kernel/src/inet_tcp.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. +%% Copyright Ericsson AB 1997-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -95,7 +95,7 @@ do_connect({A,B,C,D}, Port, Opts, Time) when ?ip(A,B,C,D), ?port(Port) -> port=BPort, opts=SockOpts}} when ?ip(Ab,Bb,Cb,Db), ?port(BPort) -> - case inet:open(Fd,BAddr,BPort,SockOpts,tcp,inet,?MODULE) of + case inet:open(Fd,BAddr,BPort,SockOpts,tcp,inet,stream,?MODULE) of {ok, S} -> case prim_inet:connect(S, {A,B,C,D}, Port, Time) of ok -> {ok,S}; @@ -117,7 +117,7 @@ listen(Port, Opts) -> port=BPort, opts=SockOpts}=R} when ?ip(A,B,C,D), ?port(BPort) -> - case inet:open(Fd,BAddr,BPort,SockOpts,tcp,inet,?MODULE) of + case inet:open(Fd,BAddr,BPort,SockOpts,tcp,inet,stream,?MODULE) of {ok, S} -> case prim_inet:listen(S, R#listen_opts.backlog) of ok -> {ok, S}; @@ -150,4 +150,4 @@ accept(L,Timeout) -> %% Create a port/socket from a file descriptor %% fdopen(Fd, Opts) -> - inet:fdopen(Fd, Opts, tcp, inet, ?MODULE). + inet:fdopen(Fd, Opts, tcp, inet, stream, ?MODULE). diff --git a/lib/kernel/src/inet_udp.erl b/lib/kernel/src/inet_udp.erl index 60bd96f332..80d930fe10 100644 --- a/lib/kernel/src/inet_udp.erl +++ b/lib/kernel/src/inet_udp.erl @@ -52,7 +52,7 @@ open(Port, Opts) -> ifaddr=BAddr={A,B,C,D}, port=BPort, opts=SockOpts}} when ?ip(A,B,C,D), ?port(BPort) -> - inet:open(Fd,BAddr,BPort,SockOpts,udp,inet,?MODULE); + inet:open(Fd,BAddr,BPort,SockOpts,udp,inet,dgram,?MODULE); {ok, _} -> exit(badarg) end. @@ -93,7 +93,7 @@ controlling_process(Socket, NewOwner) -> fdopen(Fd, Opts) -> inet:fdopen(Fd, optuniquify([{recbuf, ?RECBUF} | Opts]), - udp, inet, ?MODULE). + udp, inet, dgram, ?MODULE). %% Remove all duplicate options from an option list. diff --git a/lib/kernel/src/kernel.appup.src b/lib/kernel/src/kernel.appup.src index 54a63833e6..bded2408a7 100644 --- a/lib/kernel/src/kernel.appup.src +++ b/lib/kernel/src/kernel.appup.src @@ -1 +1,27 @@ -{"%VSN%",[],[]}. +%% -*- erlang -*- +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2011. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +{"%VSN%", + %% Up from - max two major revisions back + [{<<"2\\.15(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R15 + {<<"2\\.14(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R14 + {<<"2\\.13(\\.[0-9]+)*">>,[restart_new_emulator]}],%% R13 + %% Down to - max two major revisions back + [{<<"2\\.15(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R15 + {<<"2\\.14(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R14 + {<<"2\\.13(\\.[0-9]+)*">>,[restart_new_emulator]}] %% R13 +}. diff --git a/lib/kernel/src/user_sup.erl b/lib/kernel/src/user_sup.erl index 35b7ff0cfe..7c97da189a 100644 --- a/lib/kernel/src/user_sup.erl +++ b/lib/kernel/src/user_sup.erl @@ -45,7 +45,7 @@ init([]) -> Pid = start_slave(Master), {ok, Pid, Pid}; {M, F, A} -> - case start_user({M, F}, A) of + case start_user(M, F, A) of {ok, Pid} -> {ok, Pid, Pid}; Error -> @@ -95,8 +95,8 @@ terminate(_Reason, UserPid) -> %% is guaranteed that the user is started. %%----------------------------------------------------------------- -start_user(Func,A) -> - apply(Func, A), +start_user(Mod, Func, A) -> + apply(Mod, Func, A), wait_for_user_p(100). wait_for_user_p(0) -> diff --git a/lib/kernel/test/Makefile b/lib/kernel/test/Makefile index 82bc3fc6d1..5dcaad3f5e 100644 --- a/lib/kernel/test/Makefile +++ b/lib/kernel/test/Makefile @@ -74,7 +74,8 @@ MODULES= \ wrap_log_reader_SUITE \ cleanup \ zlib_SUITE \ - loose_node + loose_node \ + sendfile_SUITE APP_FILES = \ appinc.app \ diff --git a/lib/kernel/test/application_SUITE.erl b/lib/kernel/test/application_SUITE.erl index 2c5b8ccb66..f469a0af98 100644 --- a/lib/kernel/test/application_SUITE.erl +++ b/lib/kernel/test/application_SUITE.erl @@ -33,7 +33,7 @@ -export([config_change/1, distr_changed_tc1/1, distr_changed_tc2/1, - shutdown_func/1, do_shutdown/1]). + shutdown_func/1, do_shutdown/1, shutdown_timeout/1]). -define(TESTCASE, testcase_name). -define(testcase, ?config(?TESTCASE, Config)). @@ -50,7 +50,7 @@ all() -> load_use_cache, {group, reported_bugs}, start_phases, script_start, nodedown_start, permit_false_start_local, permit_false_start_dist, get_key, - {group, distr_changed}, config_change, shutdown_func]. + {group, distr_changed}, config_change, shutdown_func, shutdown_timeout]. groups() -> [{reported_bugs, [], @@ -1915,6 +1915,32 @@ do_shutdown(Reason) -> +%%%----------------------------------------------------------------- +%%% Tests the 'shutdown_timeout' kernel config parameter +%%%----------------------------------------------------------------- +shutdown_timeout(Config) when is_list(Config) -> + DataDir = ?config(data_dir,Config), + {ok,Cp1} = start_node(?MODULE_STRING++"_shutdown_timeout"), + wait_for_ready_net(), + ok = rpc:call(Cp1, application, set_env, [kernel, shutdown_timeout, 1000]), + rpc:call(Cp1, code, add_path, [filename:join([DataDir,deadlock])]), + ok = rpc:call(Cp1, application, start, [sasl]), + ok = rpc:call(Cp1, application, start, [deadlock]), + rpc:call(Cp1, deadlock, restart_and_fail, []), + + ok = net_kernel:monitor_nodes(true), + _ = rpc:call(Cp1, init, stop, []), + receive + {nodedown,Cp1} -> + ok + after 10000 -> + ct:fail("timeout 10 sec: node termination hangs") + end, + ok. + + + + %%----------------------------------------------------------------- %% Utility functions %%----------------------------------------------------------------- diff --git a/lib/kernel/test/application_SUITE_data/Makefile.src b/lib/kernel/test/application_SUITE_data/Makefile.src index a237f6badb..abc3c82907 100644 --- a/lib/kernel/test/application_SUITE_data/Makefile.src +++ b/lib/kernel/test/application_SUITE_data/Makefile.src @@ -2,7 +2,8 @@ EFLAGS=+debug_info all: app_start_error.@EMULATOR@ trans_abnormal_sup.@EMULATOR@ \ trans_normal_sup.@EMULATOR@ transient.@EMULATOR@ \ - group_leader_sup.@EMULATOR@ group_leader.@EMULATOR@ + group_leader_sup.@EMULATOR@ group_leader.@EMULATOR@ \ + deadlock/deadlock.@EMULATOR@ app_start_error.@EMULATOR@: app_start_error.erl erlc $(EFLAGS) app_start_error.erl @@ -22,3 +23,5 @@ group_leader.@EMULATOR@: group_leader.erl group_leader_sup.@EMULATOR@: group_leader_sup.erl erlc $(EFLAGS) group_leader_sup.erl +deadlock/deadlock.@EMULATOR@: deadlock/deadlock.erl + erlc $(EFLAGS) -o deadlock deadlock/deadlock.erl
\ No newline at end of file diff --git a/lib/kernel/test/application_SUITE_data/deadlock/deadlock.app b/lib/kernel/test/application_SUITE_data/deadlock/deadlock.app new file mode 100644 index 0000000000..0c1001bed6 --- /dev/null +++ b/lib/kernel/test/application_SUITE_data/deadlock/deadlock.app @@ -0,0 +1,8 @@ +{application, deadlock, [ + {vsn, "1"}, + {registered, []}, + {applications, [kernel, stdlib, sasl]}, + {modules, [deadlock]}, + {mod, {deadlock, []}}, + {env, [{fail_start, false}]} +]}. diff --git a/lib/kernel/test/application_SUITE_data/deadlock/deadlock.erl b/lib/kernel/test/application_SUITE_data/deadlock/deadlock.erl new file mode 100644 index 0000000000..5f68bf9078 --- /dev/null +++ b/lib/kernel/test/application_SUITE_data/deadlock/deadlock.erl @@ -0,0 +1,69 @@ +-module(deadlock). +-behaviour(application). +-compile(export_all). +-define(SUP,deadlock_sup). +-define(CHILD,deadlock_child). + + +%%%----------------------------------------------------------------- +%%% application callbacks +start(_StartType, _StartArgs) -> + supervisor:start_link({local, ?SUP}, ?MODULE, [sup]). + +stop(_State) -> + ok. + + + +%%%----------------------------------------------------------------- +%%% supervisor callbacks +init([sup]) -> + {ok, {{one_for_one, 5, 10}, [ + { + sasl_syslog_dm, {?MODULE, start_link, []}, + permanent, brutal_kill, worker, + [deadlock] + } + ]}}; + + +%%%----------------------------------------------------------------- +%%% gen_server callbacks +init([child]) -> + case application:get_env(deadlock, fail_start) of + {ok, false} -> + %% we must not fail on the first init, otherwise supervisor + %% terminates immediately + {ok, []}; + {ok, true} -> + timer:sleep(infinity), % init hangs!!!! + {ok, []} + end. + +handle_call(_Req, _From, State) -> + {reply, ok, State}. + +handle_cast(restart, State) -> + {stop, error, State}. + +handle_info(_Msg, State) -> + {noreply, State}. + +terminate(_Reason, _State) -> + ok. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + + +%%%----------------------------------------------------------------- +%%% Start child +start_link() -> + gen_server:start_link({local, ?CHILD}, ?MODULE, [child], []). + + +%%%----------------------------------------------------------------- +%%% Provoke hanging +restart_and_fail() -> + application:set_env(deadlock, fail_start, true), % next init will hang + gen_server:cast(?CHILD, restart). diff --git a/lib/kernel/test/erl_boot_server_SUITE.erl b/lib/kernel/test/erl_boot_server_SUITE.erl index cea3715ce4..bb64c01058 100644 --- a/lib/kernel/test/erl_boot_server_SUITE.erl +++ b/lib/kernel/test/erl_boot_server_SUITE.erl @@ -346,7 +346,7 @@ good_hosts(_Config) -> [GoodHost1, GoodHost2, GoodHost3]. open_udp() -> - ?line {ok, S} = prim_inet:open(udp, inet), + ?line {ok, S} = prim_inet:open(udp, inet, dgram), ?line ok = prim_inet:setopts(S, [{mode,list},{active,true}, {deliver,term},{broadcast,true}]), ?line {ok,_} = prim_inet:bind(S, {0,0,0,0}, 0), diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl index 77fc7e73f9..85346762ac 100644 --- a/lib/kernel/test/file_SUITE.erl +++ b/lib/kernel/test/file_SUITE.erl @@ -3144,12 +3144,12 @@ ipread_int(Dir, ModeList) -> {fun (Bin) when is_binary(Bin) -> Bin; (List) when is_list(List) -> list_to_binary(List) end, - {erlang, size}}; + fun erlang:byte_size/1}; false -> {fun (Bin) when is_binary(Bin) -> binary_to_list(Bin); (List) when is_list(List) -> List end, - {erlang, length}} + fun erlang:length/1} end, ?line Pos = 4711, ?line Data = Conv("THE QUICK BROWN FOX JUMPS OVER A LAZY DOG"), diff --git a/lib/kernel/test/gen_sctp_SUITE.erl b/lib/kernel/test/gen_sctp_SUITE.erl index 1b534a5fc4..8f490b6643 100644 --- a/lib/kernel/test/gen_sctp_SUITE.erl +++ b/lib/kernel/test/gen_sctp_SUITE.erl @@ -30,33 +30,31 @@ -export( [basic/1, api_open_close/1,api_listen/1,api_connect_init/1,api_opts/1, - xfer_min/1,xfer_active/1,def_sndrcvinfo/1,implicit_inet6/1]). + xfer_min/1,xfer_active/1,def_sndrcvinfo/1,implicit_inet6/1, + basic_stream/1, xfer_stream_min/1, peeloff/1, buffers/1]). suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> [basic, api_open_close, api_listen, api_connect_init, - api_opts, xfer_min, xfer_active, def_sndrcvinfo, - implicit_inet6]. + api_opts, xfer_min, xfer_active, def_sndrcvinfo, implicit_inet6, + basic_stream, xfer_stream_min, peeloff, buffers]. groups() -> []. -init_per_suite(Config) -> - try gen_sctp:open() of +init_per_suite(_Config) -> + case gen_sctp:open() of {ok,Socket} -> gen_sctp:close(Socket), []; - _ -> - [] - catch - error:badarg -> - {skip,"SCTP not supported on this machine"}; - _:_ -> - Config + {error,Error} + when Error =:= eprotonosupport; + Error =:= esocktnosupport -> + {skip,"SCTP not supported on this machine"} end. -end_per_suite(_Conifig) -> +end_per_suite(_Config) -> ok. init_per_group(_GroupName, Config) -> @@ -96,7 +94,7 @@ xfer_min(Config) when is_list(Config) -> ?line Stream = 0, ?line Data = <<"The quick brown fox jumps over a lazy dog 0123456789">>, ?line Loopback = {127,0,0,1}, - ?line {ok,Sb} = gen_sctp:open(), + ?line {ok,Sb} = gen_sctp:open([{type,seqpacket}]), ?line {ok,Pb} = inet:port(Sb), ?line ok = gen_sctp:listen(Sb, true), @@ -108,29 +106,44 @@ xfer_min(Config) when is_list(Config) -> inbound_streams=SaInboundStreams, assoc_id=SaAssocId}=SaAssocChange} = gen_sctp:connect(Sa, Loopback, Pb, []), - ?line {ok,{Loopback, - Pa,[], + ?line {SbAssocId,SaOutboundStreams,SaInboundStreams} = + case recv_event(log_ok(gen_sctp:recv(Sb, infinity))) of + {Loopback,Pa, #sctp_assoc_change{state=comm_up, error=0, outbound_streams=SbOutboundStreams, inbound_streams=SbInboundStreams, - assoc_id=SbAssocId}}} = - gen_sctp:recv(Sb, infinity), - ?line SaOutboundStreams = SbInboundStreams, - ?line SbOutboundStreams = SaInboundStreams, + assoc_id=AssocId}} -> + {AssocId,SbInboundStreams,SbOutboundStreams}; + {Loopback,Pa, + #sctp_paddr_change{state=addr_confirmed, + addr={Loopback,Pa}, + error=0, + assoc_id=AssocId}} -> + {Loopback,Pa, + #sctp_assoc_change{state=comm_up, + error=0, + outbound_streams=SbOutboundStreams, + inbound_streams=SbInboundStreams, + assoc_id=AssocId}} = + ?line recv_event(log_ok(gen_sctp:recv(Sb, infinity))), + {AssocId,SbInboundStreams,SbOutboundStreams} + end, + ?line ok = gen_sctp:send(Sa, SaAssocId, 0, Data), - ?line case gen_sctp:recv(Sb, infinity) of - {ok,{Loopback, - Pa, - [#sctp_sndrcvinfo{stream=Stream, - assoc_id=SbAssocId}], - Data}} -> ok; - {ok,{Loopback, - Pa,[], + ?line case log_ok(gen_sctp:recv(Sb, infinity)) of + {Loopback, + Pa, + [#sctp_sndrcvinfo{stream=Stream, + assoc_id=SbAssocId}], + Data} -> ok; + Event1 -> + {Loopback,Pa, #sctp_paddr_change{addr = {Loopback,_}, state = addr_available, error = 0, - assoc_id = SbAssocId}}} -> + assoc_id = SbAssocId}} = + recv_event(Event1), {ok,{Loopback, Pa, [#sctp_sndrcvinfo{stream=Stream, @@ -138,30 +151,40 @@ xfer_min(Config) when is_list(Config) -> Data}} = gen_sctp:recv(Sb, infinity) end, ?line ok = gen_sctp:send(Sb, SbAssocId, 0, Data), - ?line {ok,{Loopback, - Pb, + ?line case log_ok(gen_sctp:recv(Sa, infinity)) of + {Loopback,Pb, [#sctp_sndrcvinfo{stream=Stream, assoc_id=SaAssocId}], - Data}} = - gen_sctp:recv(Sa, infinity), + Data} -> + ok; + Event2 -> + {Loopback,Pb, + #sctp_paddr_change{addr={_,Pb}, + state=addr_confirmed, + error=0, + assoc_id=SaAssocId}} = + ?line recv_event(Event2), + ?line {Loopback, + Pb, + [#sctp_sndrcvinfo{stream=Stream, + assoc_id=SaAssocId}], + Data} = + log_ok(gen_sctp:recv(Sa, infinity)) + end, %% ?line ok = gen_sctp:eof(Sa, SaAssocChange), - ?line {ok,{Loopback, - Pa,[], - #sctp_shutdown_event{assoc_id=SbAssocId}}} = - gen_sctp:recv(Sb, infinity), - ?line {ok,{Loopback, - Pb,[], - #sctp_assoc_change{state=shutdown_comp, - error=0, - assoc_id=SaAssocId}}} = - gen_sctp:recv(Sa, infinity), - ?line {ok,{Loopback, - Pa,[], - #sctp_assoc_change{state=shutdown_comp, - error=0, - assoc_id=SbAssocId}}} = - gen_sctp:recv(Sb, infinity), + ?line {Loopback,Pa,#sctp_shutdown_event{assoc_id=SbAssocId}} = + recv_event(log_ok(gen_sctp:recv(Sb, infinity))), + ?line {Loopback,Pb, + #sctp_assoc_change{state=shutdown_comp, + error=0, + assoc_id=SaAssocId}} = + recv_event(log_ok(gen_sctp:recv(Sa, infinity))), + ?line {Loopback,Pa, + #sctp_assoc_change{state=shutdown_comp, + error=0, + assoc_id=SbAssocId}} = + recv_event(log_ok(gen_sctp:recv(Sb, infinity))), ?line ok = gen_sctp:close(Sa), ?line ok = gen_sctp:close(Sb), @@ -186,32 +209,52 @@ xfer_active(Config) when is_list(Config) -> ?line {ok,Sa} = gen_sctp:open([{active,true}]), ?line {ok,Pa} = inet:port(Sa), - ?line {ok,#sctp_assoc_change{state=comm_up, - error=0, - outbound_streams=SaOutboundStreams, - inbound_streams=SaInboundStreams, - assoc_id=SaAssocId}=SaAssocChange} = - gen_sctp:connect(Sa, Loopback, Pb, []), + ?line ok = gen_sctp:connect_init(Sa, Loopback, Pb, []), + ?line #sctp_assoc_change{state=comm_up, + error=0, + outbound_streams=SaOutboundStreams, + inbound_streams=SaInboundStreams, + assoc_id=SaAssocId} = SaAssocChange = + recv_assoc_change(Sa, Loopback, Pb, Timeout), ?line io:format("Sa=~p, Pa=~p, Sb=~p, Pb=~p, SaAssocId=~p, " "SaOutboundStreams=~p, SaInboundStreams=~p~n", [Sa,Pa,Sb,Pb,SaAssocId, SaOutboundStreams,SaInboundStreams]), - ?line SbAssocId = - receive - {sctp,Sb,Loopback,Pa, - {[], - #sctp_assoc_change{state=comm_up, - error=0, - outbound_streams=SbOutboundStreams, - inbound_streams=SbInboundStreams, - assoc_id=SBAI}}} -> - ?line SaOutboundStreams = SbInboundStreams, - ?line SaInboundStreams = SbOutboundStreams, - SBAI - after Timeout -> - ?line test_server:fail({unexpected,flush()}) - end, + ?line #sctp_assoc_change{state=comm_up, + error=0, + outbound_streams=SbOutboundStreams, + inbound_streams=SbInboundStreams, + assoc_id=SbAssocId} = + recv_assoc_change(Sb, Loopback, Pa, Timeout), + ?line SbOutboundStreams = SaInboundStreams, + ?line SbInboundStreams = SaOutboundStreams, ?line io:format("SbAssocId=~p~n", [SbAssocId]), + + ?line case recv_paddr_change(Sa, Loopback, Pb, 314) of + #sctp_paddr_change{state=addr_confirmed, + addr={_,Pb}, + error=0, + assoc_id=SaAssocId} -> ok; + #sctp_paddr_change{state=addr_available, + addr={_,Pb}, + error=0, + assoc_id=SaAssocId} -> ok; + timeout -> ok + end, + ?line case recv_paddr_change(Sb, Loopback, Pa, 314) of + #sctp_paddr_change{state=addr_confirmed, + addr={Loopback,Pa}, + error=0, + assoc_id=SbAssocId} -> ok; + #sctp_paddr_change{state=addr_available, + addr={Loopback,P}, + error=0, + assoc_id=SbAssocId} -> + ?line match_unless_solaris(Pa, P); + timeout -> ok + end, + ?line [] = flush(), + ?line ok = do_from_other_process( fun () -> gen_sctp:send(Sa, SaAssocId, 0, Data) end), @@ -219,21 +262,9 @@ xfer_active(Config) when is_list(Config) -> {sctp,Sb,Loopback,Pa, {[#sctp_sndrcvinfo{stream=Stream, assoc_id=SbAssocId}], - Data}} -> ok; - {sctp,Sb,Loopback,Pa, - {[], - #sctp_paddr_change{addr = {Loopback,_}, - state = addr_available, - error = 0, - assoc_id = SbAssocId}}} -> - ?line receive - {sctp,Sb,Loopback,Pa, - {[#sctp_sndrcvinfo{stream=Stream, - assoc_id=SbAssocId}], - Data}} -> ok - end + Data}} -> ok after Timeout -> - ?line test_server:fail({unexpected,flush()}) + ?line test_server:fail({timeout,flush()}) end, ?line ok = gen_sctp:send(Sb, SbAssocId, 0, Data), ?line receive @@ -242,31 +273,28 @@ xfer_active(Config) when is_list(Config) -> assoc_id=SaAssocId}], Data}} -> ok after Timeout -> - ?line test_server:fail({unexpected,flush()}) + ?line test_server:fail({timeout,flush()}) end, %% ?line ok = gen_sctp:abort(Sa, SaAssocChange), - ?line receive - {sctp,Sb,Loopback,Pa, - {[], - #sctp_assoc_change{state=comm_lost, - assoc_id=SbAssocId}}} -> ok - after Timeout -> - ?line test_server:fail({unexpected,flush()}) + ?line case recv_assoc_change(Sb, Loopback, Pa, Timeout) of + #sctp_assoc_change{state=comm_lost, + assoc_id=SbAssocId} -> ok; + timeout -> + ?line test_server:fail({timeout,flush()}) end, ?line ok = gen_sctp:close(Sb), + ?line case recv_assoc_change(Sa, Loopback, Pb, Timeout) of + #sctp_assoc_change{state=comm_lost, + assoc_id=SaAssocId} -> ok; + timeout -> + ?line io:format("timeout waiting for comm_lost on Sa~n"), + ?line match_unless_solaris(ok, {timeout,flush()}) + end, ?line receive - {sctp,Sa,Loopback,Pb, - {[], - #sctp_assoc_change{state=comm_lost, - assoc_id=SaAssocId}}} -> ok - after Timeout -> - ?line test_server:fail({unexpected,flush()}) - end, - ?line receive - {sctp_error,Sa,enotconn} -> ok % Solaris - after 17 -> ok %% Only happens on Solaris - end, + {sctp_error,Sa,enotconn} -> ok % Solaris + after 17 -> ok + end, ?line ok = gen_sctp:close(Sa), %% ?line receive @@ -275,6 +303,30 @@ xfer_active(Config) when is_list(Config) -> end, ok. +recv_assoc_change(S, Addr, Port, Timeout) -> + receive + {sctp,S,Addr,Port,{[], #sctp_assoc_change{}=AssocChange}} -> + AssocChange; + {sctp,S,Addr,Port, + {[#sctp_sndrcvinfo{assoc_id=AssocId}], + #sctp_assoc_change{assoc_id=AssocId}=AssocChange}} -> + AssocChange + after Timeout -> + timeout + end. + +recv_paddr_change(S, Addr, Port, Timeout) -> + receive + {sctp,S,Addr,Port,{[], #sctp_paddr_change{}=PaddrChange}} -> + PaddrChange; + {sctp,S,Addr,Port, + {[#sctp_sndrcvinfo{assoc_id=AssocId}], + #sctp_paddr_change{assoc_id=AssocId}=PaddrChange}} -> + PaddrChange + after Timeout -> + timeout + end. + def_sndrcvinfo(doc) -> "Test that #sctp_sndrcvinfo{} parameters set on a socket " "are used by gen_sctp:send/4"; @@ -285,11 +337,11 @@ def_sndrcvinfo(Config) when is_list(Config) -> ?line Data = <<"What goes up, must come down.">>, %% ?line S1 = - ok(gen_sctp:open( + log_ok(gen_sctp:open( 0, [{sctp_default_send_param,#sctp_sndrcvinfo{ppid=17}}])), ?LOGVAR(S1), ?line P1 = - ok(inet:port(S1)), + log_ok(inet:port(S1)), ?LOGVAR(P1), ?line #sctp_sndrcvinfo{ppid=17, context=0, timetolive=0, assoc_id=0} = getopt(S1, sctp_default_send_param), @@ -297,10 +349,10 @@ def_sndrcvinfo(Config) when is_list(Config) -> gen_sctp:listen(S1, true), %% ?line S2 = - ok(gen_sctp:open()), + log_ok(gen_sctp:open()), ?LOGVAR(S2), ?line P2 = - ok(inet:port(S2)), + log_ok(inet:port(S2)), ?LOGVAR(P2), ?line #sctp_sndrcvinfo{ppid=0, context=0, timetolive=0, assoc_id=0} = getopt(S2, sctp_default_send_param), @@ -309,32 +361,57 @@ def_sndrcvinfo(Config) when is_list(Config) -> state=comm_up, error=0, assoc_id=S2AssocId} = S2AssocChange = - ok(gen_sctp:connect(S2, Loopback, P1, [])), + log_ok(gen_sctp:connect(S2, Loopback, P1, [])), ?LOGVAR(S2AssocChange), - ?line case ok(gen_sctp:recv(S1)) of - {Loopback, P2,[], + ?line case recv_event(log_ok(gen_sctp:recv(S1))) of + {Loopback,P2, #sctp_assoc_change{ + state=comm_up, + error=0, + assoc_id=S1AssocId}} -> + ?LOGVAR(S1AssocId); + {Loopback,P2, + #sctp_paddr_change{ + state=addr_confirmed, + error=0, + assoc_id=S1AssocId}} -> + ?LOGVAR(S1AssocId), + {Loopback,P2, + #sctp_assoc_change{ state=comm_up, error=0, - assoc_id=S1AssocId}} -> - ?LOGVAR(S1AssocId) + assoc_id=S1AssocId}} = + recv_event(log_ok(gen_sctp:recv(S1))) end, + ?line #sctp_sndrcvinfo{ - ppid=17, context=0, timetolive=0, assoc_id=S1AssocId} = + ppid=17, context=0, timetolive=0} = %, assoc_id=S1AssocId} = getopt( S1, sctp_default_send_param, #sctp_sndrcvinfo{assoc_id=S1AssocId}), ?line #sctp_sndrcvinfo{ - ppid=0, context=0, timetolive=0, assoc_id=S2AssocId} = + ppid=0, context=0, timetolive=0} = %, assoc_id=S2AssocId} = getopt( S2, sctp_default_send_param, #sctp_sndrcvinfo{assoc_id=S2AssocId}), %% ?line ok = gen_sctp:send(S1, S1AssocId, 1, <<"1: ",Data/binary>>), - ?line case ok(gen_sctp:recv(S2)) of + ?line case log_ok(gen_sctp:recv(S2)) of {Loopback,P1, [#sctp_sndrcvinfo{ stream=1, ppid=17, context=0, assoc_id=S2AssocId}], - <<"1: ",Data/binary>>} -> ok + <<"1: ",Data/binary>>} -> ok; + Event1 -> + ?line {Loopback,P1, + #sctp_paddr_change{state=addr_confirmed, + addr={_,P1}, + error=0, + assoc_id=S2AssocId}} = + recv_event(Event1), + ?line {Loopback,P1, + [#sctp_sndrcvinfo{ + stream=1, ppid=17, context=0, assoc_id=S2AssocId}], + <<"1: ",Data/binary>>} = + log_ok(gen_sctp:recv(S2)) end, %% ?line ok = @@ -354,7 +431,7 @@ def_sndrcvinfo(Config) when is_list(Config) -> %% ?line ok = gen_sctp:send(S1, S1AssocId, 0, <<"2: ",Data/binary>>), - ?line case ok(gen_sctp:recv(S2)) of + ?line case log_ok(gen_sctp:recv(S2)) of {Loopback,P1, [#sctp_sndrcvinfo{ stream=0, ppid=19, context=0, assoc_id=S2AssocId}], @@ -362,16 +439,18 @@ def_sndrcvinfo(Config) when is_list(Config) -> end, ?line ok = gen_sctp:send(S2, S2AssocChange, 1, <<"3: ",Data/binary>>), - ?line case ok(gen_sctp:recv(S1)) of + ?line case log_ok(gen_sctp:recv(S1)) of {Loopback,P2, [#sctp_sndrcvinfo{ stream=1, ppid=0, context=0, assoc_id=S1AssocId}], <<"3: ",Data/binary>>} -> ok; - {Loopback,P2,[], - #sctp_paddr_change{ - addr={Loopback,_}, state=addr_available, - error=0, assoc_id=S1AssocId}} -> - ?line case ok(gen_sctp:recv(S1)) of + Event2 -> + {Loopback,P2, + #sctp_paddr_change{ + addr={Loopback,_}, state=addr_available, + error=0, assoc_id=S1AssocId}} = + recv_event(Event2), + ?line case log_ok(gen_sctp:recv(S1)) of {Loopback,P2, [#sctp_sndrcvinfo{ stream=1, ppid=0, context=0, @@ -387,7 +466,7 @@ def_sndrcvinfo(Config) when is_list(Config) -> #sctp_sndrcvinfo{stream=0, ppid=20, assoc_id=S2AssocId}, <<"4: ",Data/binary>>) end), - ?line case ok(do_from_other_process(fun() -> gen_sctp:recv(S1) end)) of + ?line case log_ok(do_from_other_process(fun() -> gen_sctp:recv(S1) end)) of {Loopback,P2, [#sctp_sndrcvinfo{ stream=0, ppid=20, context=0, assoc_id=S1AssocId}], @@ -416,8 +495,12 @@ getopt(S, Opt, Param) -> setopt(S, Opt, Val) -> inet:setopts(S, [{Opt,Val}]). -ok({ok,X}) -> - io:format("OK: ~p~n", [X]), +log_ok(X) -> log(ok(X)). + +ok({ok,X}) -> X. + +log(X) -> + io:format("LOG[~w]: ~p~n", [self(),X]), X. flush() -> @@ -520,7 +603,10 @@ api_listen(Config) when is_list(Config) -> #sctp_assoc_change{ state=comm_lost}}} = gen_sctp:recv(Sa, infinity); - {error,#sctp_assoc_change{state=cant_assoc}} -> ok + {error,#sctp_assoc_change{state=cant_assoc}} -> + ok%; + %% {error,{Localhost,Pb,_,#sctp_assoc_change{state=cant_assoc}}} -> + %% ok end, ?line ok = gen_sctp:listen(Sb, true), ?line {ok,#sctp_assoc_change{state=comm_up, @@ -552,29 +638,41 @@ api_connect_init(Config) when is_list(Config) -> ?line {ok,Sa} = gen_sctp:open(), ?line case gen_sctp:connect_init(Sa, localhost, Pb, []) of {error,econnrefused} -> - ?line {ok,{Localhost, - Pb,[], - #sctp_assoc_change{state=comm_lost}}} = - gen_sctp:recv(Sa, infinity); + ?line {Localhost,Pb,#sctp_assoc_change{state=comm_lost}} = + recv_event(log_ok(gen_sctp:recv(Sa, infinity))); ok -> - ?line {ok,{Localhost, - Pb,[], - #sctp_assoc_change{state=cant_assoc}}} = - gen_sctp:recv(Sa, infinity) + ?line {Localhost,Pb,#sctp_assoc_change{state=cant_assoc}} = + recv_event(log_ok(gen_sctp:recv(Sa, infinity))) end, ?line ok = gen_sctp:listen(Sb, true), ?line case gen_sctp:connect_init(Sa, localhost, Pb, []) of ok -> - ?line {ok,{Localhost, - Pb,[], - #sctp_assoc_change{ - state = comm_up}}} = - gen_sctp:recv(Sa, infinity) + ?line {Localhost,Pb,#sctp_assoc_change{state=comm_up}} = + recv_event(log_ok(gen_sctp:recv(Sa, infinity))) end, ?line ok = gen_sctp:close(Sa), ?line ok = gen_sctp:close(Sb), ok. +recv_event({Addr,Port,[],#sctp_assoc_change{}=AssocChange}) -> + {Addr,Port,AssocChange}; +recv_event({Addr,Port, + [#sctp_sndrcvinfo{assoc_id=Assoc}], + #sctp_assoc_change{assoc_id=Assoc}=AssocChange}) -> + {Addr,Port,AssocChange}; +recv_event({Addr,Port,[],#sctp_paddr_change{}=PaddrChange}) -> + {Addr,Port,PaddrChange}; +recv_event({Addr,Port, + [#sctp_sndrcvinfo{assoc_id=Assoc}], + #sctp_paddr_change{assoc_id=Assoc}=PaddrChange}) -> + {Addr,Port,PaddrChange}; +recv_event({Addr,Port,[],#sctp_shutdown_event{}=ShutdownEvent}) -> + {Addr,Port,ShutdownEvent}; +recv_event({Addr,Port, + [#sctp_sndrcvinfo{assoc_id=Assoc}], + #sctp_shutdown_event{assoc_id=Assoc}=ShutdownEvent}) -> + {Addr,Port,ShutdownEvent}. + api_opts(doc) -> "Test socket options"; api_opts(suite) -> @@ -600,7 +698,7 @@ api_opts(Config) when is_list(Config) -> end. implicit_inet6(Config) when is_list(Config) -> - ?line Hostname = ok(inet:gethostname()), + ?line Hostname = log_ok(inet:gethostname()), ?line case gen_sctp:open(0, [inet6]) of {ok,S1} -> @@ -613,16 +711,16 @@ implicit_inet6(Config) when is_list(Config) -> ?line ok = gen_sctp:close(S1), %% ?line Localhost = - ok(inet:getaddr("localhost", inet6)), + log_ok(inet:getaddr("localhost", inet6)), ?line io:format("~s ~p~n", ["localhost",Localhost]), ?line S2 = - ok(gen_sctp:open(0, [{ip,Localhost}])), + log_ok(gen_sctp:open(0, [{ip,Localhost}])), ?line implicit_inet6(S2, Localhost), ?line ok = gen_sctp:close(S2), %% ?line io:format("~s ~p~n", [Hostname,Host]), ?line S3 = - ok(gen_sctp:open(0, [{ifaddr,Host}])), + log_ok(gen_sctp:open(0, [{ifaddr,Host}])), ?line implicit_inet6(S3, Host), ?line ok = gen_sctp:close(S1); {error,eafnosupport} -> @@ -635,25 +733,159 @@ implicit_inet6(Config) when is_list(Config) -> implicit_inet6(S1, Addr) -> ?line ok = gen_sctp:listen(S1, true), - ?line P1 = ok(inet:port(S1)), - ?line S2 = ok(gen_sctp:open(0, [inet6])), - ?line P2 = ok(inet:port(S2)), + ?line P1 = log_ok(inet:port(S1)), + ?line S2 = log_ok(gen_sctp:open(0, [inet6])), + ?line P2 = log_ok(inet:port(S2)), ?line #sctp_assoc_change{state=comm_up} = - ok(gen_sctp:connect(S2, Addr, P1, [])), - ?line case ok(gen_sctp:recv(S1)) of - {Addr,P2,[],#sctp_assoc_change{state=comm_up}} -> - ok + log_ok(gen_sctp:connect(S2, Addr, P1, [])), + ?line case recv_event(log_ok(gen_sctp:recv(S1))) of + {Addr,P2,#sctp_assoc_change{state=comm_up}} -> + ok; + {Addr,P2,#sctp_paddr_change{state=addr_confirmed, + addr={Addr,P2}, + error=0}} -> + {Addr,P2,#sctp_assoc_change{state=comm_up}} = + recv_event(log_ok(gen_sctp:recv(S1))) end, - ?line case ok(inet:sockname(S1)) of + ?line case log_ok(inet:sockname(S1)) of {Addr,P1} -> ok; {{0,0,0,0,0,0,0,0},P1} -> ok end, - ?line case ok(inet:sockname(S2)) of + ?line case log_ok(inet:sockname(S2)) of {Addr,P2} -> ok; {{0,0,0,0,0,0,0,0},P2} -> ok end, ?line ok = gen_sctp:close(S2). +basic_stream(doc) -> + "Hello world stream socket"; +basic_stream(suite) -> + []; +basic_stream(Config) when is_list(Config) -> + ?line {ok,S} = gen_sctp:open([{type,stream}]), + ?line ok = gen_sctp:listen(S, true), + ?line ok = + do_from_other_process( + fun () -> gen_sctp:listen(S, 10) end), + ?line ok = gen_sctp:close(S), + ok. + +xfer_stream_min(doc) -> + "Minimal data transfer"; +xfer_stream_min(suite) -> + []; +xfer_stream_min(Config) when is_list(Config) -> + ?line Stream = 0, + ?line Data = <<"The quick brown fox jumps over a lazy dog 0123456789">>, + ?line Loopback = {127,0,0,1}, + ?line {ok,Sb} = gen_sctp:open([{type,seqpacket}]), + ?line ?LOGVAR(Sb), + ?line {ok,Pb} = inet:port(Sb), + ?line ?LOGVAR(Pb), + ?line ok = gen_sctp:listen(Sb, true), + + ?line {ok,Sa} = gen_sctp:open([{type,stream}]), + ?line ?LOGVAR(Sa), + ?line {ok,Pa} = inet:port(Sa), + ?line ?LOGVAR(Pa), + ?line #sctp_assoc_change{state=comm_up, + error=0, + outbound_streams=SaOutboundStreams, + inbound_streams=SaInboundStreams, + assoc_id=SaAssocId_X} = + log_ok(gen_sctp:connect(Sa, Loopback, Pb, [])), + ?line ?LOGVAR(SaAssocId_X), + ?line [{_,#sctp_paddrinfo{assoc_id=SaAssocId,state=active}}] = + log_ok(inet:getopts(Sa, [{sctp_get_peer_addr_info, + #sctp_paddrinfo{address={Loopback,Pb}}}])), + ?line ?LOGVAR(SaAssocId), + ?line match_unless_solaris(SaAssocId_X, SaAssocId), + + ?line {SbOutboundStreams,SbInboundStreams,SbAssocId} = + case recv_event(log_ok(gen_sctp:recv(Sb, infinity))) of + {Loopback,Pa, + #sctp_assoc_change{state=comm_up, + error=0, + outbound_streams=OS, + inbound_streams=IS, + assoc_id=AI}} -> + {OS,IS,AI}; + {Loopback,Pa, + #sctp_paddr_change{state=addr_confirmed, + addr={Loopback,Pa}, + error=0, + assoc_id=AI}} -> + {Loopback,Pa, + ?line #sctp_assoc_change{state=comm_up, + error=0, + outbound_streams=OS, + inbound_streams=IS, + assoc_id=AI}} = + recv_event(log_ok(gen_sctp:recv(Sb, infinity))), + {OS,IS,AI} + end, + ?line ?LOGVAR(SbAssocId), + ?line SaOutboundStreams = SbInboundStreams, + ?line ?LOGVAR(SaOutboundStreams), + ?line SbOutboundStreams = SaInboundStreams, + ?line ?LOGVAR(SbOutboundStreams), + ?line ok = gen_sctp:send(Sa, SaAssocId, 0, Data), + ?line case gen_sctp:recv(Sb, infinity) of + {ok,{Loopback, + Pa, + [#sctp_sndrcvinfo{stream=Stream, + assoc_id=SbAssocId}], + Data}} -> ok; + {ok,{Loopback, + Pa,[], + #sctp_paddr_change{addr = {Loopback,_}, + state = addr_available, + error = 0, + assoc_id = SbAssocId}}} -> + {ok,{Loopback, + Pa, + [#sctp_sndrcvinfo{stream=Stream, + assoc_id=SbAssocId}], + Data}} = gen_sctp:recv(Sb, infinity) + end, + ?line ok = + do_from_other_process( + fun () -> gen_sctp:send(Sb, SbAssocId, 0, Data) end), + ?line case log_ok(gen_sctp:recv(Sa, infinity)) of + {Loopback,Pb, + [#sctp_sndrcvinfo{stream=Stream, + assoc_id=SaAssocId}], + Data} -> ok; + Event1 -> + ?line {Loopback,Pb, + #sctp_paddr_change{state=addr_confirmed, + addr={_,Pb}, + error=0, + assoc_id=SaAssocId}} = + recv_event(Event1), + ?line {Loopback,Pb, + [#sctp_sndrcvinfo{stream=Stream, + assoc_id=SaAssocId}], + Data} = + log_ok(gen_sctp:recv(Sa, infinity)) + end, + ?line ok = gen_sctp:close(Sa), + ?line {Loopback,Pa, + #sctp_shutdown_event{assoc_id=SbAssocId}} = + recv_event(log_ok(gen_sctp:recv(Sb, infinity))), + ?line {Loopback,Pa, + #sctp_assoc_change{state=shutdown_comp, + error=0, + assoc_id=SbAssocId}} = + recv_event(log_ok(gen_sctp:recv(Sb, infinity))), + ?line ok = gen_sctp:close(Sb), + + ?line receive + Msg -> test_server:fail({received,Msg}) + after 17 -> ok + end, + ok. + do_from_other_process(Fun) -> @@ -681,3 +913,419 @@ do_from_other_process(Fun) -> {'DOWN',Mref,_,_,Reason} -> erlang:exit(Reason) end. + + + +peeloff(doc) -> + "Peel off an SCTP stream socket"; +peeloff(suite) -> + []; +peeloff(Config) when is_list(Config) -> + ?line Addr = {127,0,0,1}, + ?line Stream = 0, + ?line Timeout = 333, + ?line S1 = socket_open([{ifaddr,Addr}], Timeout), + ?line ?LOGVAR(S1), + ?line P1 = socket_call(S1, get_port), + ?line ?LOGVAR(P1), + ?line Socket1 = socket_call(S1, get_socket), + ?line ?LOGVAR(Socket1), + ?line socket_call(S1, {listen,true}), + ?line S2 = socket_open([{ifaddr,Addr}], Timeout), + ?line ?LOGVAR(S2), + ?line P2 = socket_call(S2, get_port), + ?line ?LOGVAR(P2), + ?line Socket2 = socket_call(S2, get_socket), + ?line ?LOGVAR(Socket2), + %% + ?line socket_call(S2, {connect_init,Addr,P1,[]}), + ?line S2Ai = + receive + {S2,{Addr,P1, + #sctp_assoc_change{ + state=comm_up, + assoc_id=AssocId2}}} -> AssocId2 + after Timeout -> + socket_bailout([S1,S2]) + end, + ?line ?LOGVAR(S2Ai), + ?line S1Ai = + receive + {S1,{Addr,P2, + #sctp_assoc_change{ + state=comm_up, + assoc_id=AssocId1}}} -> AssocId1 + after Timeout -> + socket_bailout([S1,S2]) + end, + ?line ?LOGVAR(S1Ai), + %% + ?line socket_call(S2, {send,S2Ai,Stream,<<"Number one">>}), + ?line + receive + {S1,{Addr,P2,S1Ai,Stream,<<"Number one">>}} -> ok + after Timeout -> + socket_bailout([S1,S2]) + end, + ?line socket_call(S2, {send,Socket1,S1Ai,Stream,<<"Number two">>}), + ?line + receive + {S2,{Addr,P1,S2Ai,Stream,<<"Number two">>}} -> ok + after Timeout -> + socket_bailout([S1,S2]) + end, + %% + ?line S3 = socket_peeloff(Socket1, S1Ai, Timeout), + ?line ?LOGVAR(S3), + ?line P3_X = socket_call(S3, get_port), + ?line ?LOGVAR(P3_X), + ?line P3 = case P3_X of 0 -> P1; _ -> P3_X end, + ?line [{_,#sctp_paddrinfo{assoc_id=S3Ai,state=active}}] = + socket_call(S3, + {getopts,[{sctp_get_peer_addr_info, + #sctp_paddrinfo{address={Addr,P2}}}]}), + %%?line S3Ai = S1Ai, + ?line ?LOGVAR(S3Ai), + %% + ?line socket_call(S3, {send,S3Ai,Stream,<<"Number three">>}), + ?line + receive + {S2,{Addr,P3,S2Ai,Stream,<<"Number three">>}} -> ok + after Timeout -> + socket_bailout([S1,S2,S3]) + end, + ?line socket_call(S3, {send,Socket2,S2Ai,Stream,<<"Number four">>}), + ?line + receive + {S3,{Addr,P2,S3Ai,Stream,<<"Number four">>}} -> ok + after Timeout -> + socket_bailout([S1,S2,S3]) + end, + %% + ?line inet:i(sctp), + ?line socket_close_verbose(S1), + ?line socket_close_verbose(S2), + ?line + receive + {S3,{Addr,P2,#sctp_shutdown_event{assoc_id=S3Ai_X}}} -> + ?line match_unless_solaris(S3Ai, S3Ai_X) + after Timeout -> + socket_bailout([S3]) + end, + ?line + receive + {S3,{Addr,P2,#sctp_assoc_change{state=shutdown_comp, + assoc_id=S3Ai}}} -> ok + after Timeout -> + socket_bailout([S3]) + end, + ?line socket_close_verbose(S3), + ?line [] = flush(), + ok. + + + +buffers(doc) -> + ["Check sndbuf and recbuf behaviour"]; +buffers(suite) -> + []; +buffers(Config) when is_list(Config) -> + ?line Limit = 4096, + ?line Addr = {127,0,0,1}, + ?line Stream = 1, + ?line Timeout = 3333, + ?line S1 = socket_open([{ip,Addr}], Timeout), + ?line ?LOGVAR(S1), + ?line P1 = socket_call(S1, get_port), + ?line ?LOGVAR(P1), + ?line ok = socket_call(S1, {listen,true}), + ?line S2 = socket_open([{ip,Addr}], Timeout), + ?line ?LOGVAR(S2), + ?line P2 = socket_call(S2, get_port), + ?line ?LOGVAR(P2), + %% + ?line socket_call(S2, {connect_init,Addr,P1,[]}), + ?line S2Ai = + receive + {S2,{Addr,P1, + #sctp_assoc_change{ + state=comm_up, + assoc_id=AssocId2}}} -> AssocId2 + after Timeout -> + socket_bailout([S1,S2]) + end, + ?line S1Ai = + receive + {S1,{Addr,P2, + #sctp_assoc_change{ + state=comm_up, + assoc_id=AssocId1}}} -> AssocId1 + after Timeout -> + socket_bailout([S1,S2]) + end, + %% + ?line socket_call(S1, {setopts,[{recbuf,Limit}]}), + ?line Recbuf = + case socket_call(S1, {getopts,[recbuf]}) of + [{recbuf,RB1}] when RB1 >= Limit -> RB1 + end, + ?line Data = mk_data(Recbuf+Limit), + ?line socket_call(S2, {setopts,[{sndbuf,Recbuf+Limit}]}), + ?line socket_call(S2, {send,S2Ai,Stream,Data}), + ?line + receive + {S1,{Addr,P2,S1Ai,Stream,Data}} -> ok + after Timeout -> + socket_bailout([S1,S2]) + end, + %% + ?line socket_close_verbose(S1), + ?line + receive + {S2,{Addr,P1,#sctp_shutdown_event{assoc_id=S2Ai}}} -> ok + after Timeout -> + socket_bailout([S2]) + end, + ?line + receive + {S2,{Addr,P1,#sctp_assoc_change{state=shutdown_comp, + assoc_id=S2Ai}}} -> ok + after Timeout -> + socket_bailout([S2]) + end, + ?line socket_close_verbose(S2), + ?line [] = flush(), + ok. + +mk_data(Bytes) -> + mk_data(0, Bytes, <<>>). +%% +mk_data(N, Bytes, Bin) when N < Bytes -> + mk_data(N+4, Bytes, <<Bin/binary,N:32>>); +mk_data(_, _, Bin) -> + Bin. + +%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% socket gen_server ultra light + +socket_open(SocketOpts, Timeout) -> + Opts = [{type,seqpacket},{active,once},binary|SocketOpts], + Starter = + fun () -> + {ok,Socket} = + gen_sctp:open(Opts), + Socket + end, + s_start(Starter, Timeout). + +socket_peeloff(Socket, AssocId, Timeout) -> + Opts = [{active,once},binary], + Starter = + fun () -> + {ok,NewSocket} = + gen_sctp:peeloff(Socket, AssocId), + ok = inet:setopts(NewSocket, Opts), + NewSocket + end, + s_start(Starter, Timeout). + +socket_close_verbose(S) -> + History = socket_history(socket_close(S)), + io:format("socket_close ~p:~n ~p.~n", [S,History]), + History. + +socket_close(S) -> + s_req(S, close). + +socket_call(S, Request) -> + s_req(S, {Request}). + +%% socket_get(S, Key) -> +%% s_req(S, {get,Key}). + +socket_bailout([S|Ss]) -> + History = socket_history(socket_close(S)), + io:format("bailout ~p:~n ~p.~n", [S,History]), + socket_bailout(Ss); +socket_bailout([]) -> + io:format("flush: ~p.~n", [flush()]), + test_server:fail(socket_bailout). + +socket_history({State,Flush}) -> + {lists:keysort( + 2, + lists:flatten( + [[{Key,Val} || Val <- Vals] + || {Key,Vals} <- gb_trees:to_list(State)])), + Flush}. + +s_handler(Socket) -> + fun ({listen,Listen}) -> + ok = gen_sctp:listen(Socket, Listen); + (get_port) -> + ok(inet:port(Socket)); + (get_socket) -> + Socket; + ({connect_init,ConAddr,ConPort,ConOpts}) -> + ok = gen_sctp:connect_init(Socket, ConAddr, ConPort, ConOpts); + ({send,AssocId,Stream,Data}) -> + ok = gen_sctp:send(Socket, AssocId, Stream, Data); + ({send,OtherSocket,AssocId,Stream,Data}) -> + ok = gen_sctp:send(OtherSocket, AssocId, Stream, Data); + ({setopts,Opts}) -> + ok = inet:setopts(Socket, Opts); + ({getopts,Optnames}) -> + ok(inet:getopts(Socket, Optnames)) + end. + +s_req(S, Req) -> + Mref = erlang:monitor(process, S), + S ! {self(),Mref,Req}, + receive + {'DOWN',Mref,_,_,Error} -> + exit(Error); + {S,Mref,Reply} -> + erlang:demonitor(Mref), + receive {'DOWN',Mref,_,_,_} -> ok after 0 -> ok end, + Reply + end. + +s_start(Starter, Timeout) -> + Parent = self(), + Owner = + spawn_link( + fun () -> + s_start(Starter(), Timeout, Parent) + end), + Owner. + +s_start(Socket, Timeout, Parent) -> + Handler = s_handler(Socket), + try + s_loop(Socket, Timeout, Parent, Handler, gb_trees:empty()) + catch + Class:Reason -> + Stacktrace = erlang:get_stacktrace(), + io:format(?MODULE_STRING":socket exception ~w:~w at~n" + "~p.~n", [Class,Reason,Stacktrace]), + erlang:raise(Class, Reason, Stacktrace) + end. + +s_loop(Socket, Timeout, Parent, Handler, State) -> + receive + {Parent,Ref,close} -> % socket_close() + erlang:send_after(Timeout, self(), {Parent,Ref,exit}), + s_loop(Socket, Timeout, Parent, Handler, State); + {Parent,Ref,exit} -> + ok = gen_sctp:close(Socket), + Key = exit, + Val = {now(),Socket}, + NewState = gb_push(Key, Val, State), + Parent ! {self(),Ref,{NewState,flush()}}; + {Parent,Ref,{Msg}} -> + Result = Handler(Msg), + Key = req, + Val = {now(),{Msg,Result}}, + NewState = gb_push(Key, Val, State), + Parent ! {self(),Ref,Result}, + s_loop(Socket, Timeout, Parent, Handler, NewState); + %% {Parent,Ref,{get,Key}} -> + %% Parent ! {self(),Ref,gb_get(Key, State)}, + %% s_loop(Socket, Timeout, Parent, Handler, State); + {sctp,Socket,Addr,Port, + {[#sctp_sndrcvinfo{stream=Stream,assoc_id=AssocId}=SRI],Data}} + when not is_tuple(Data) -> + case gb_get({assoc_change,AssocId}, State) of + [{_,{Addr,Port, + #sctp_assoc_change{ + state=comm_up, + inbound_streams=Is}}}|_] + when 0 =< Stream, Stream < Is-> ok; + [] -> ok + end, + Key = {msg,AssocId,Stream}, + Val = {now(),{Addr,Port,SRI,Data}}, + NewState = gb_push(Key, Val, State), + Parent ! {self(),{Addr,Port,AssocId,Stream,Data}}, + again(Socket), + s_loop(Socket, Timeout, Parent, Handler, NewState); + {sctp,Socket,Addr,Port, + {SRI,#sctp_assoc_change{assoc_id=AssocId,state=St}=SAC}} -> + case SRI of + [#sctp_sndrcvinfo{assoc_id=AssocId,stream=0}] -> ok; + [] -> ok + end, + Key = {assoc_change,AssocId}, + Val = {now(),{Addr,Port,SAC}}, + case {gb_get(Key, State),St} of + {[],_} -> ok; + {[{_,{Addr,Port,#sctp_assoc_change{state=comm_up}}}|_],_} + when St =:= comm_lost; St =:= shutdown_comp -> ok + end, + NewState = gb_push(Key, Val, State), + Parent ! {self(),{Addr,Port,SAC}}, + again(Socket), + s_loop(Socket, Timeout, Parent, Handler, NewState); + {sctp,Socket,Addr,Port, + {SRI,#sctp_paddr_change{assoc_id=AssocId, + addr={_,P}, + state=St}=SPC}} -> + match_unless_solaris(Port, P), + case SRI of + [#sctp_sndrcvinfo{assoc_id=AssocId,stream=0}] -> ok; + [] -> ok + end, + case {gb_get({assoc_change,AssocId}, State),St} of + {[{_,{Addr,Port,#sctp_assoc_change{state=comm_up}}}|_], + addr_available} -> ok; + {[],addr_confirmed} -> ok + end, + Key = {paddr_change,AssocId}, + Val = {now(),{Addr,Port,SPC}}, + NewState = gb_push(Key, Val, State), + again(Socket), + s_loop(Socket, Timeout, Parent, Handler, NewState); + {sctp,Socket,Addr,Port, + {SRI,#sctp_shutdown_event{assoc_id=AssocId}=SSE}} -> + case SRI of + [#sctp_sndrcvinfo{assoc_id=AssocId,stream=0}] -> ok; + [] -> ok + end, + case gb_get({assoc_change,AssocId}, State) of + [{_,{Addr,Port,#sctp_assoc_change{state=comm_up}}}|_] -> ok; + [] -> ok + end, + Key = {shutdown_event,AssocId}, + Val = {now(),{Addr,Port}}, + NewState = gb_push(Key, Val, State), + Parent ! {self(), {Addr,Port,SSE}}, + again(Socket), + s_loop(Socket, Timeout, Parent, Handler, NewState); + Unexpected -> + erlang:error({unexpected,Unexpected}) + end. + +again(Socket) -> + inet:setopts(Socket, [{active,once}]). + +gb_push(Key, Val, GBT) -> + case gb_trees:lookup(Key, GBT) of + none -> + gb_trees:insert(Key, [Val], GBT); + {value,V} -> + gb_trees:update(Key, [Val|V], GBT) + end. + +gb_get(Key, GBT) -> + case gb_trees:lookup(Key, GBT) of + none -> + []; + {value,V} -> + V + end. + +match_unless_solaris(A, B) -> + case os:type() of + {unix,sunos} -> B; + _ -> A = B + end. diff --git a/lib/kernel/test/gen_tcp_api_SUITE.erl b/lib/kernel/test/gen_tcp_api_SUITE.erl index cbaec2d6dd..a7af00c12a 100644 --- a/lib/kernel/test/gen_tcp_api_SUITE.erl +++ b/lib/kernel/test/gen_tcp_api_SUITE.erl @@ -22,7 +22,7 @@ %% are not tested here, because they are tested indirectly in this and %% and other test suites. --include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). -include_lib("kernel/include/inet.hrl"). -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, @@ -46,6 +46,8 @@ groups() -> {t_connect, [], [t_connect_timeout, t_connect_bad]}, {t_recv, [], [t_recv_timeout, t_recv_eof]}]. + + init_per_suite(Config) -> Config. @@ -55,9 +57,8 @@ end_per_suite(_Config) -> init_per_group(_GroupName, Config) -> Config. -end_per_group(_GroupName, Config) -> - Config. - +end_per_group(_,_Config) -> + ok. init_per_testcase(_Func, Config) -> Dog = test_server:timetrap(test_server:seconds(60)), @@ -237,7 +238,6 @@ implicit_inet6(S, Addr) -> ?line ok = gen_tcp:close(S1). - %%% Utilities %% Calls M:F/length(A), which should return a timeout error, and complete diff --git a/lib/kernel/test/gen_tcp_echo_SUITE.erl b/lib/kernel/test/gen_tcp_echo_SUITE.erl index fffaaf4c45..5bbaeb02ad 100644 --- a/lib/kernel/test/gen_tcp_echo_SUITE.erl +++ b/lib/kernel/test/gen_tcp_echo_SUITE.erl @@ -167,8 +167,12 @@ echo_test_1(SockOpts, EchoFun, Config0) -> [{type, {cdr, little}}|Config]), ?line case lists:keymember(packet_size, 1, SockOpts) of false -> - ?line echo_packet([{packet, line}|SockOpts], - EchoFun, Config); + % This is cheating, we should test that packet_size + % also works for line and http. + echo_packet([{packet, line}|SockOpts], EchoFun, Config), + echo_packet([{packet, http}|SockOpts], EchoFun, Config), + echo_packet([{packet, http_bin}|SockOpts], EchoFun, Config); + true -> ok end, ?line echo_packet([{packet, tpkt}|SockOpts], EchoFun, Config), @@ -183,9 +187,6 @@ echo_test_1(SockOpts, EchoFun, Config0) -> [{type, {asn1, short, LongTag}}|Config]), ?line echo_packet([{packet, asn1}|SockOpts], EchoFun, [{type, {asn1, long, LongTag}}|Config]), - - ?line echo_packet([{packet, http}|SockOpts], EchoFun, Config), - ?line echo_packet([{packet, http_bin}|SockOpts], EchoFun, Config), ok. echo_packet(SockOpts, EchoFun, Opts) -> diff --git a/lib/kernel/test/gen_tcp_misc_SUITE.erl b/lib/kernel/test/gen_tcp_misc_SUITE.erl index b1ef8826d5..c1c5ff8b81 100644 --- a/lib/kernel/test/gen_tcp_misc_SUITE.erl +++ b/lib/kernel/test/gen_tcp_misc_SUITE.erl @@ -40,7 +40,8 @@ accept_timeouts_in_order3/1,accept_timeouts_mixed/1, killing_acceptor/1,killing_multi_acceptors/1,killing_multi_acceptors2/1, several_accepts_in_one_go/1,active_once_closed/1, send_timeout/1, send_timeout_active/1, - otp_7731/1, zombie_sockets/1, otp_7816/1, otp_8102/1]). + otp_7731/1, zombie_sockets/1, otp_7816/1, otp_8102/1, + otp_9389/1]). %% Internal exports. -export([sender/3, not_owner/1, passive_sockets_server/2, priority_server/1, @@ -72,7 +73,7 @@ all() -> killing_acceptor, killing_multi_acceptors, killing_multi_acceptors2, several_accepts_in_one_go, active_once_closed, send_timeout, send_timeout_active, otp_7731, - zombie_sockets, otp_7816, otp_8102]. + zombie_sockets, otp_7816, otp_8102, otp_9389]. groups() -> []. @@ -2479,4 +2480,63 @@ otp_8102_do(LSocket, PortNum, {Bin,PType}) -> io:format("Got error msg, ok.\n",[]), gen_tcp:close(SSocket), gen_tcp:close(RSocket). - + +otp_9389(doc) -> ["Verify packet_size handles long HTTP header lines"]; +otp_9389(suite) -> []; +otp_9389(Config) when is_list(Config) -> + ?line {ok, LS} = gen_tcp:listen(0, []), + ?line {ok, {_, PortNum}} = inet:sockname(LS), + io:format("Listening on ~w with port number ~p\n", [LS, PortNum]), + OrigLinkHdr = "/" ++ string:chars($S, 8192), + _Server = spawn_link( + fun() -> + ?line {ok, S} = gen_tcp:accept(LS), + ?line ok = inet:setopts(S, [{packet_size, 16384}]), + ?line ok = otp_9389_loop(S, OrigLinkHdr), + ?line ok = gen_tcp:close(S) + end), + ?line {ok, S} = gen_tcp:connect("localhost", PortNum, + [binary, {active, false}]), + Req = "GET / HTTP/1.1\r\n" + ++ "Host: localhost\r\n" + ++ "Link: " ++ OrigLinkHdr ++ "\r\n\r\n", + ?line ok = gen_tcp:send(S, Req), + ?line ok = inet:setopts(S, [{packet, http}]), + ?line {ok, {http_response, {1,1}, 200, "OK"}} = gen_tcp:recv(S, 0), + ?line ok = inet:setopts(S, [{packet, httph}, {packet_size, 16384}]), + ?line {ok, {http_header, _, 'Content-Length', _, "0"}} = gen_tcp:recv(S, 0), + ?line {ok, {http_header, _, "Link", _, LinkHdr}} = gen_tcp:recv(S, 0), + ?line true = (LinkHdr == OrigLinkHdr), + ok = gen_tcp:close(S), + ok = gen_tcp:close(LS), + ok. + +otp_9389_loop(S, OrigLinkHdr) -> + ?line ok = inet:setopts(S, [{active,once},{packet,http}]), + receive + {http, S, {http_request, 'GET', _, _}} -> + ?line ok = otp_9389_loop(S, OrigLinkHdr, undefined) + after + 3000 -> + ?line error({timeout,request_line}) + end. +otp_9389_loop(S, OrigLinkHdr, ok) -> + ?line Resp = "HTTP/1.1 200 OK\r\nContent-length: 0\r\n" ++ + "Link: " ++ OrigLinkHdr ++ "\r\n\r\n", + ?line ok = gen_tcp:send(S, Resp); +otp_9389_loop(S, OrigLinkHdr, State) -> + ?line ok = inet:setopts(S, [{active,once}, {packet,httph}]), + receive + {http, S, http_eoh} -> + ?line otp_9389_loop(S, OrigLinkHdr, ok); + {http, S, {http_header, _, "Link", _, LinkHdr}} -> + ?line LinkHdr = OrigLinkHdr, + ?line otp_9389_loop(S, OrigLinkHdr, State); + {http, S, {http_header, _, _Hdr, _, _Val}} -> + ?line otp_9389_loop(S, OrigLinkHdr, State); + {http, S, {http_error, Err}} -> + ?line error({error, Err}) + after + 3000 -> + ?line error({timeout,header}) + end. diff --git a/lib/kernel/test/gen_udp_SUITE.erl b/lib/kernel/test/gen_udp_SUITE.erl index 514deaf065..2354f8accd 100644 --- a/lib/kernel/test/gen_udp_SUITE.erl +++ b/lib/kernel/test/gen_udp_SUITE.erl @@ -99,9 +99,9 @@ buffer_size(Config) when is_list(Config) -> ?line Bin = list_to_binary(lists:seq(0, Len-1)), ?line M = 8192 div Len, ?line Spec0 = - [{opt,M},{safe,M-1},{long,M+1}, - {opt,2*M},{safe,2*M-1},{long,2*M+1}, - {opt,4*M},{safe,4*M-1},{long,4*M+1}], + [{opt,M},{safe,M-3},{long,M+1}, + {opt,2*M},{safe,2*M-3},{long,2*M+1}, + {opt,4*M},{safe,4*M-3},{long,4*M+1}], ?line Spec = [case Tag of opt -> @@ -145,16 +145,27 @@ buffer_size_client(_, _, _, _, _, []) -> ?line ok; buffer_size_client(Server, IP, Port, Socket, Cnt, [Opts|T]) when is_list(Opts) -> + ?line io:format("buffer_size_client Cnt=~w setopts ~p.~n", [Cnt,Opts]), ?line ok = inet:setopts(Socket, Opts), ?line Server ! {self(),setopts,Cnt}, ?line receive {Server,setopts,Cnt} -> ok end, ?line buffer_size_client(Server, IP, Port, Socket, Cnt+1, T); buffer_size_client(Server, IP, Port, - Socket, Cnt, [{B,Replies}|T]) when is_binary(B) -> - ?line ok = gen_udp:send(Socket, IP, Port, B), + Socket, Cnt, [{B,Replies}|T]=Opts) when is_binary(B) -> + ?line io:format( + "buffer_size_client Cnt=~w send size ~w expecting ~p.~n", + [Cnt,size(B),Replies]), + ?line ok = gen_udp:send(Socket, IP, Port, <<Cnt,B/binary>>), ?line receive {Server,Cnt,Reply} -> - ?line case lists:member(Reply, Replies) of + ?line Tag = + if + is_tuple(Reply) -> + element(1, Reply); + is_atom(Reply) -> + Reply + end, + ?line case lists:member(Tag, Replies) of true -> ok; false -> ?line @@ -162,34 +173,62 @@ buffer_size_client(Server, IP, Port, byte_size(B), inet:getopts(Socket, [sndbuf,recbuf])}) - end - end, - ?line buffer_size_client(Server, IP, Port, Socket, Cnt+1, T). + end, + ?line buffer_size_client(Server, IP, Port, Socket, Cnt+1, T) + after 1313 -> + ?line buffer_size_client(Server, IP, Port, Socket, Cnt, Opts) + end. buffer_size_server(_, _, _, _, _, []) -> ok; buffer_size_server(Client, IP, Port, Socket, Cnt, [Opts|T]) when is_list(Opts) -> receive {Client,setopts,Cnt} -> ok end, + ?line io:format("buffer_size_server Cnt=~w setopts ~p.~n", [Cnt,Opts]), ok = inet:setopts(Socket, Opts), Client ! {self(),setopts,Cnt}, buffer_size_server(Client, IP, Port, Socket, Cnt+1, T); buffer_size_server(Client, IP, Port, Socket, Cnt, [{B,_}|T]) when is_binary(B) -> + ?line io:format( + "buffer_size_server Cnt=~w expecting size ~w.~n", + [Cnt,size(B)]), Client ! {self(),Cnt, - receive - {udp,Socket,IP,Port,D} when is_binary(D) -> + case buffer_size_server_recv(Socket, IP, Port, Cnt) of + D when is_binary(D) -> SizeD = byte_size(D), + ?line io:format( + "buffer_size_server Cnt=~w received size ~w.~n", + [Cnt,SizeD]), case B of - D -> correct; - <<D:SizeD/binary,_/binary>> -> truncated + D -> + correct; + <<D:SizeD/binary,_/binary>> -> + truncated; + _ -> + {unexpected,D} end; - {udp_error,Socket,Error} -> Error - after 5000 -> timeout + Error -> + ?line io:format( + "buffer_size_server Cnt=~w received error ~w.~n", + [Cnt,Error]), + Error end}, buffer_size_server(Client, IP, Port, Socket, Cnt+1, T). +buffer_size_server_recv(Socket, IP, Port, Cnt) -> + receive + {udp,Socket,IP,Port,<<Cnt,B/binary>>} -> + B; + {udp,Socket,IP,Port,<<_/binary>>} -> + buffer_size_server_recv(Socket, IP, Port, Cnt); + {udp_error,Socket,Error} -> + Error + after 5000 -> + {timeout,flush()} + end. + %%------------------------------------------------------------- diff --git a/lib/kernel/test/inet_SUITE.erl b/lib/kernel/test/inet_SUITE.erl index aaa20b7398..7241b093d0 100644 --- a/lib/kernel/test/inet_SUITE.erl +++ b/lib/kernel/test/inet_SUITE.erl @@ -97,8 +97,12 @@ t_gethostbyaddr() -> required(v4). t_gethostbyaddr(doc) -> "Test the inet:gethostbyaddr/1 function."; t_gethostbyaddr(Config) when is_list(Config) -> - ?line {Name,FullName,IPStr,IP,Aliases,_,_} = + ?line {Name,FullName,IPStr,{A,B,C,D}=IP,Aliases,_,_} = ct:get_config(test_host_ipv4_only), + ?line Rname = integer_to_list(D) ++ "." ++ + integer_to_list(C) ++ "." ++ + integer_to_list(B) ++ "." ++ + integer_to_list(A) ++ ".in-addr.arpa", ?line {ok,HEnt} = inet:gethostbyaddr(IPStr), ?line {ok,HEnt} = inet:gethostbyaddr(IP), ?line {error,Error} = inet:gethostbyaddr(Name), @@ -116,7 +120,7 @@ t_gethostbyaddr(Config) when is_list(Config) -> ok; _ -> ?line check_elems([{HEnt#hostent.h_name,[Name,FullName]}, - {HEnt#hostent.h_aliases,[[],Aliases]}]) + {HEnt#hostent.h_aliases,[[],Aliases,[Rname]]}]) end, ?line {_DName, _DFullName, DIPStr, DIP, _, _, _} = diff --git a/lib/kernel/test/kernel_SUITE.erl b/lib/kernel/test/kernel_SUITE.erl index 16b6c54939..0f29d895e5 100644 --- a/lib/kernel/test/kernel_SUITE.erl +++ b/lib/kernel/test/kernel_SUITE.erl @@ -32,7 +32,7 @@ -export([init_per_testcase/2, end_per_testcase/2]). % Test cases must be exported. --export([app_test/1]). +-export([app_test/1, appup_test/1]). %% %% all/1 @@ -40,7 +40,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> - [app_test]. + [app_test, appup_test]. groups() -> []. @@ -76,3 +76,63 @@ app_test(suite) -> app_test(Config) when is_list(Config) -> ?line ok=?t:app_test(kernel), ok. + + +%% Test that appup allows upgrade from/downgrade to a maximum of two +%% major releases back. +appup_test(_Config) -> + application:load(kernel), + {_,_,Vsn} = lists:keyfind(kernel,1,application:loaded_applications()), + AppupFile = filename:join([code:lib_dir(kernel),ebin,"kernel.appup"]), + {ok,[{Vsn,UpFrom,DownTo}=AppupScript]} = file:consult(AppupFile), + ct:log("~p~n",[AppupScript]), + {OkVsns,NokVsns} = create_test_vsns(Vsn), + check_appup(OkVsns,UpFrom,{ok,[restart_new_emulator]}), + check_appup(OkVsns,DownTo,{ok,[restart_new_emulator]}), + check_appup(NokVsns,UpFrom,error), + check_appup(NokVsns,DownTo,error), + ok. + +create_test_vsns(Current) -> + [XStr,YStr|Rest] = string:tokens(Current,"."), + X = list_to_integer(XStr), + Y = list_to_integer(YStr), + SecondMajor = vsn(X,Y-2), + SecondMinor = SecondMajor ++ ".1.3", + FirstMajor = vsn(X,Y-1), + FirstMinor = FirstMajor ++ ".57", + ThisMajor = vsn(X,Y), + This = + case Rest of + [] -> + []; + ["1"] -> + [ThisMajor]; + _ -> + ThisMinor = ThisMajor ++ ".1", + [ThisMajor,ThisMinor] + end, + OkVsns = This ++ [FirstMajor, FirstMinor, SecondMajor, SecondMinor], + + ThirdMajor = vsn(X,Y-3), + ThirdMinor = ThirdMajor ++ ".10.12", + Illegal = ThisMajor ++ ",1", + Newer1Major = vsn(X,Y+1), + Newer1Minor = Newer1Major ++ ".1", + Newer2Major = ThisMajor ++ "1", + NokVsns = [ThirdMajor,ThirdMinor, + Illegal, + Newer1Major,Newer1Minor, + Newer2Major], + {OkVsns,NokVsns}. + +vsn(X,Y) -> + integer_to_list(X) ++ "." ++ integer_to_list(Y). + +check_appup([Vsn|Vsns],Instrs,Expected) -> + case systools_relup:appup_search_for_version(Vsn, Instrs) of + Expected -> check_appup(Vsns,Instrs,Expected); + Other -> ct:fail({unexpected_result_for_vsn,Vsn,Other}) + end; +check_appup([],_,_) -> + ok. diff --git a/lib/kernel/test/sendfile_SUITE.erl b/lib/kernel/test/sendfile_SUITE.erl new file mode 100644 index 0000000000..04af16a6b9 --- /dev/null +++ b/lib/kernel/test/sendfile_SUITE.erl @@ -0,0 +1,278 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2011-2011. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +-module(sendfile_SUITE). + +-include_lib("common_test/include/ct.hrl"). +-include_lib("kernel/include/file.hrl"). + +-compile(export_all). + +all() -> + [t_sendfile_small + ,t_sendfile_big + ,t_sendfile_partial + ,t_sendfile_offset + ,t_sendfile_sendafter + ,t_sendfile_recvafter + ,t_sendfile_sendduring + ,t_sendfile_recvduring + ]. + +init_per_suite(Config) -> + Priv = ?config(priv_dir, Config), + SFilename = filename:join(Priv, "sendfile_small.html"), + {ok, DS} = file:open(SFilename,[write,raw]), + file:write(DS,"yo baby yo"), + file:sync(DS), + file:close(DS), + BFilename = filename:join(Priv, "sendfile_big.html"), + {ok, DB} = file:open(BFilename,[write,raw]), + [file:write(DB,[<<0:(10*8*1024*1024)>>]) || _I <- lists:seq(1,51)], + file:sync(DB), + file:close(DB), + [{small_file, SFilename}, + {file_opts,[raw,binary]}, + {big_file, BFilename}|Config]. + +end_per_suite(Config) -> + file:delete(proplists:get_value(big_file, Config)). + +init_per_testcase(TC,Config) when TC == t_sendfile_recvduring; + TC == t_sendfile_sendduring -> + Filename = proplists:get_value(small_file, Config), + + Send = fun(Sock) -> + {_Size, Data} = sendfile_file_info(Filename), + {ok,D} = file:open(Filename, [raw,binary,read]), + prim_file:sendfile(D, Sock, 0, 0, 0, + [],[],false,false,false), + Data + end, + + %% Check if sendfile is supported on this platform + case catch sendfile_send(Send) of + ok -> + Config; + Error -> + ct:log("Error: ~p",[Error]), + {skip,"Not supported"} + end; +init_per_testcase(_Tc,Config) -> + Config. + + +t_sendfile_small(Config) when is_list(Config) -> + Filename = proplists:get_value(small_file, Config), + + Send = fun(Sock) -> + {Size, Data} = sendfile_file_info(Filename), + {ok, Size} = file:sendfile(Filename, Sock), + Data + end, + + ok = sendfile_send(Send). + +t_sendfile_big(Config) when is_list(Config) -> + Filename = proplists:get_value(big_file, Config), + + Send = fun(Sock) -> + {ok, #file_info{size = Size}} = + file:read_file_info(Filename), + {ok, Size} = file:sendfile(Filename, Sock), + Size + end, + + ok = sendfile_send("localhost", Send, 0). + +t_sendfile_partial(Config) -> + Filename = proplists:get_value(small_file, Config), + FileOpts = proplists:get_value(file_opts, Config, []), + + SendSingle = fun(Sock) -> + {_Size, <<Data:5/binary,_/binary>>} = + sendfile_file_info(Filename), + {ok,D} = file:open(Filename,[read|FileOpts]), + {ok,5} = file:sendfile(D,Sock,0,5,[]), + file:close(D), + Data + end, + ok = sendfile_send(SendSingle), + + {_Size, <<FData:5/binary,SData:3/binary,_/binary>>} = + sendfile_file_info(Filename), + {ok,D} = file:open(Filename,[read|FileOpts]), + {ok, <<FData/binary>>} = file:read(D,5), + FSend = fun(Sock) -> + {ok,5} = file:sendfile(D,Sock,0,5,[]), + FData + end, + + ok = sendfile_send(FSend), + + SSend = fun(Sock) -> + {ok,3} = file:sendfile(D,Sock,5,3,[]), + SData + end, + + ok = sendfile_send(SSend), + + {ok, <<SData/binary>>} = file:read(D,3), + + file:close(D). + +t_sendfile_offset(Config) -> + Filename = proplists:get_value(small_file, Config), + FileOpts = proplists:get_value(file_opts, Config, []), + + Send = fun(Sock) -> + {_Size, <<_:5/binary,Data:3/binary,_/binary>> = AllData} = + sendfile_file_info(Filename), + {ok,D} = file:open(Filename,[read|FileOpts]), + {ok,3} = file:sendfile(D,Sock,5,3,[]), + {ok, AllData} = file:read(D,100), + file:close(D), + Data + end, + ok = sendfile_send(Send). + + +t_sendfile_sendafter(Config) -> + Filename = proplists:get_value(small_file, Config), + + Send = fun(Sock) -> + {Size, Data} = sendfile_file_info(Filename), + {ok, Size} = file:sendfile(Filename, Sock), + ok = gen_tcp:send(Sock, <<2>>), + <<Data/binary,2>> + end, + + ok = sendfile_send(Send). + +t_sendfile_recvafter(Config) -> + Filename = proplists:get_value(small_file, Config), + + Send = fun(Sock) -> + {Size, Data} = sendfile_file_info(Filename), + {ok, Size} = file:sendfile(Filename, Sock), + ok = gen_tcp:send(Sock, <<1>>), + {ok,<<1>>} = gen_tcp:recv(Sock, 1), + <<Data/binary,1>> + end, + + ok = sendfile_send(Send). + +t_sendfile_sendduring(Config) -> + Filename = proplists:get_value(big_file, Config), + + Send = fun(Sock) -> + {ok, #file_info{size = Size}} = + file:read_file_info(Filename), + spawn_link(fun() -> + timer:sleep(10), + ok = gen_tcp:send(Sock, <<2>>) + end), + {ok, Size} = file:sendfile(Filename, Sock), + Size+1 + end, + + ok = sendfile_send("localhost", Send, 0). + +t_sendfile_recvduring(Config) -> + Filename = proplists:get_value(big_file, Config), + + Send = fun(Sock) -> + {ok, #file_info{size = Size}} = + file:read_file_info(Filename), + spawn_link(fun() -> + timer:sleep(10), + ok = gen_tcp:send(Sock, <<1>>), + {ok,<<1>>} = gen_tcp:recv(Sock, 1) + end), + {ok, Size} = file:sendfile(Filename, Sock), + timer:sleep(1000), + Size+1 + end, + + ok = sendfile_send("localhost", Send, 0). + +%% TODO: consolidate tests and reduce code +sendfile_send(Send) -> + sendfile_send("localhost",Send). +sendfile_send(Host, Send) -> + sendfile_send(Host, Send, []). +sendfile_send(Host, Send, Orig) -> + spawn_link(?MODULE, sendfile_server, [self(), Orig]), + receive + {server, Port} -> + {ok, Sock} = gen_tcp:connect(Host, Port, + [binary,{packet,0}, + {active,false}]), + Data = Send(Sock), + ok = gen_tcp:close(Sock), + receive + {ok, Bin} -> + Data = Bin, + ok + end + end. + +sendfile_server(ClientPid, Orig) -> + {ok, LSock} = gen_tcp:listen(0, [binary, {packet, 0}, + {active, true}, + {reuseaddr, true}]), + {ok, Port} = inet:port(LSock), + ClientPid ! {server, Port}, + {ok, Sock} = gen_tcp:accept(LSock), + {ok, Bin} = sendfile_do_recv(Sock, Orig), + ClientPid ! {ok, Bin}, + gen_tcp:send(Sock, <<1>>). + +-define(SENDFILE_TIMEOUT, 10000). +%% f(),{ok, S} = gen_tcp:connect("localhost",7890,[binary]),file:sendfile("/ldisk/lukas/otp/sendfiletest.dat",S). +sendfile_do_recv(Sock, Bs) -> + receive + {tcp, Sock, B} -> + case binary:match(B,<<1>>) of + nomatch when is_list(Bs) -> + sendfile_do_recv(Sock, [B|Bs]); + nomatch when is_integer(Bs) -> + sendfile_do_recv(Sock, byte_size(B) + Bs); + _ when is_list(Bs) -> + ct:log("Stopped due to a 1"), + {ok, iolist_to_binary(lists:reverse([B|Bs]))}; + _ when is_integer(Bs) -> + ct:log("Stopped due to a 1"), + {ok, byte_size(B) + Bs} + end; + {tcp_closed, Sock} when is_list(Bs) -> + ct:log("Stopped due to close"), + {ok, iolist_to_binary(lists:reverse(Bs))}; + {tcp_closed, Sock} when is_integer(Bs) -> + ct:log("Stopped due to close"), + {ok, Bs} + after ?SENDFILE_TIMEOUT -> + ct:log("Sendfile timeout"), + timeout + end. + +sendfile_file_info(File) -> + {ok, #file_info{size = Size}} = file:read_file_info(File), + {ok, Data} = file:read_file(File), + {Size, Data}. diff --git a/lib/kernel/test/wrap_log_reader_SUITE.erl b/lib/kernel/test/wrap_log_reader_SUITE.erl index ffc8def626..96dc3e6d33 100644 --- a/lib/kernel/test/wrap_log_reader_SUITE.erl +++ b/lib/kernel/test/wrap_log_reader_SUITE.erl @@ -561,4 +561,4 @@ rec(M, Where) -> end. pps() -> - {erlang:ports(), lists:filter({erlang, is_process_alive}, processes())}. + {erlang:ports(), lists:filter(fun erlang:is_process_alive/1, processes())}. diff --git a/lib/megaco/Makefile b/lib/megaco/Makefile index 10efaf667f..9dc84c122c 100644 --- a/lib/megaco/Makefile +++ b/lib/megaco/Makefile @@ -97,9 +97,8 @@ endif CONFIGURE_OPTS = $(FLEX_SCANNER_LINENO_ENABLER) $(FLEX_SCANNER_REENTRANT_ENABLER) -MEGACO_DIA_PLT = ./priv/megaco.plt -MEGACO_DIA_PLT_LOG = $(basename $(MEGACO_DIA_PLT)).dialyzer_plt_log -MEGACO_DIA_LOG = $(basename $(MEGACO_DIA_PLT)).dialyzer_log +DIA_PLT = ./priv/plt/$(APPLICATION).plt +DIA_ANALYSIS = $(basename $(DIA_PLT)).dialyzer_analysis # ---------------------------------------------------- @@ -140,8 +139,8 @@ info: @echo "OTP_INSTALL_DIR: $(OTP_INSTALL_DIR)" @echo "APP_INSTALL_DIR: $(APP_INSTALL_DIR)" @echo "" - @echo "MEGACO_PLT = $(MEGACO_PLT)" - @echo "MEGACO_DIA_LOG = $(MEGACO_DIA_LOG)" + @echo "DIA_PLT: $(DIA_PLT)" + @echo "DIA_ANALYSIS: $(DIA_ANALYSIS)" @echo "" version: @@ -201,18 +200,18 @@ tar: $(APP_TAR_FILE) $(APP_TAR_FILE): $(APP_DIR) (cd $(APP_RELEASE_DIR); gtar zcf $(APP_TAR_FILE) $(DIR_NAME)) -dialyzer_plt: $(MEGACO_DIA_PLT) +dialyzer_plt: $(DIA_PLT) -$(MEGACO_DIA_PLT): - @echo "Building megaco plt file" +$(DIA_PLT): + @echo "Building $(APPLICATION) plt file" @dialyzer --build_plt \ --output_plt $@ \ - -r ../megaco/ebin \ - -o $(MEGACO_DIA_PLT_LOG) \ + -r ../$(APPLICATION)/ebin \ + --output $(DIA_ANALYSIS) \ --verbose -dialyzer: $(MEGACO_DIA_PLT) - (dialyzer --plt $< \ - -o $(MEGACO_DIA_LOG) \ - ../megaco/ebin \ - && (shell cat $(MEGACO_DIA_LOG))) +dialyzer: $(DIA_PLT) + @echo "Running dialyzer on $(APPLICATION)" + @dialyzer --plt $< \ + ../$(APPLICATION)/ebin \ + --verbose diff --git a/lib/megaco/configure.in b/lib/megaco/configure.in index b88e17ec85..42c50b8961 100644 --- a/lib/megaco/configure.in +++ b/lib/megaco/configure.in @@ -208,7 +208,7 @@ if test "X$host" = "Xwin32"; then else case $host_os in darwin*) - CFLAGS="$CFLAGS -no-cpp-precomp -fno-common" + CFLAGS="$CFLAGS -fno-common" ;; esac diff --git a/lib/megaco/doc/src/megaco_run.xml b/lib/megaco/doc/src/megaco_run.xml index 9ed589b079..ca46983288 100644 --- a/lib/megaco/doc/src/megaco_run.xml +++ b/lib/megaco/doc/src/megaco_run.xml @@ -317,7 +317,7 @@ "in storage" (indicated by the transaction id) it is assumed to be a resend and everything stored is sent. This could happen if the values of the <c><![CDATA[trans_timer]]></c> and the - <c><![CDATA[request_timer]]></c> is not properly choosen.</p> + <c><![CDATA[request_timer]]></c> is not properly chosen.</p> </section> <section> diff --git a/lib/megaco/include/megaco_message_prev3a.hrl b/lib/megaco/include/megaco_message_prev3a.hrl index 7b7a60fdae..3e73f94761 100644 --- a/lib/megaco/include/megaco_message_prev3a.hrl +++ b/lib/megaco/include/megaco_message_prev3a.hrl @@ -563,7 +563,7 @@ %% This is the actual ASN.1 type and it is as this it will -%% be represented if the encoding config [native] is choosen. +%% be represented if the encoding config [native] is chosen. %% %% String of at least 1 character and at most 67 characters (ASN.1). %% %% 64 characters for name, 1 for "/", 2 for version to match ABNF %% -record('ServiceChangeProfile', diff --git a/lib/megaco/include/megaco_message_prev3b.hrl b/lib/megaco/include/megaco_message_prev3b.hrl index cfabb29941..b4bde2bb7e 100644 --- a/lib/megaco/include/megaco_message_prev3b.hrl +++ b/lib/megaco/include/megaco_message_prev3b.hrl @@ -563,7 +563,7 @@ %% This is the actual ASN.1 type and it is as this it will -%% be represented if the encoding config [native] is choosen. +%% be represented if the encoding config [native] is chosen. %% %% String of at least 1 character and at most 67 characters (ASN.1). %% %% 64 characters for name, 1 for "/", 2 for version to match ABNF %% -record('ServiceChangeProfile', diff --git a/lib/megaco/include/megaco_message_prev3c.hrl b/lib/megaco/include/megaco_message_prev3c.hrl index 32024c9a02..90612f66c8 100644 --- a/lib/megaco/include/megaco_message_prev3c.hrl +++ b/lib/megaco/include/megaco_message_prev3c.hrl @@ -748,7 +748,7 @@ %% This is the actual ASN.1 type and it is as this it will -%% be represented if the encoding config [native] is choosen. +%% be represented if the encoding config [native] is chosen. %% %% String of at least 1 character and at most 67 characters (ASN.1). %% %% 64 characters for name, 1 for "/", 2 for version to match ABNF %% -record('ServiceChangeProfile', diff --git a/lib/megaco/include/megaco_message_v1.hrl b/lib/megaco/include/megaco_message_v1.hrl index ba50b50c80..f196c26713 100644 --- a/lib/megaco/include/megaco_message_v1.hrl +++ b/lib/megaco/include/megaco_message_v1.hrl @@ -404,7 +404,7 @@ }). % with extension mark %% This is the actual ASN.1 type and it is as this it will -%% be represented if the encoding config [native] is choosen. +%% be represented if the encoding config [native] is chosen. % %% String of at least 1 character and at most 67 characters (ASN.1). % %% 64 characters for name, 1 for "/", 2 for version to match ABNF % -record('ServiceChangeProfile', diff --git a/lib/megaco/include/megaco_message_v2.hrl b/lib/megaco/include/megaco_message_v2.hrl index 6190ea7ac4..af79c4dc92 100644 --- a/lib/megaco/include/megaco_message_v2.hrl +++ b/lib/megaco/include/megaco_message_v2.hrl @@ -525,7 +525,7 @@ %% This is the actual ASN.1 type and it is as this it will -%% be represented if the encoding config [native] is choosen. +%% be represented if the encoding config [native] is chosen. %% %% String of at least 1 character and at most 67 characters (ASN.1). %% %% 64 characters for name, 1 for "/", 2 for version to match ABNF %% -record('ServiceChangeProfile', diff --git a/lib/megaco/include/megaco_message_v3.hrl b/lib/megaco/include/megaco_message_v3.hrl index 7a1bc80571..466cfa6856 100644 --- a/lib/megaco/include/megaco_message_v3.hrl +++ b/lib/megaco/include/megaco_message_v3.hrl @@ -743,7 +743,7 @@ %% This is the actual ASN.1 type and it is as this it will -%% be represented if the encoding config [native] is choosen. +%% be represented if the encoding config [native] is chosen. %% %% String of at least 1 character and at most 67 characters (ASN.1). %% %% 64 characters for name, 1 for "/", 2 for version to match ABNF %% -record('ServiceChangeProfile', diff --git a/lib/megaco/priv/plt/.gitignore b/lib/megaco/priv/plt/.gitignore new file mode 100644 index 0000000000..2051b52d48 --- /dev/null +++ b/lib/megaco/priv/plt/.gitignore @@ -0,0 +1,2 @@ +/*.plt +/*.dialyzer_analysis diff --git a/lib/megaco/src/engine/megaco_digit_map.erl b/lib/megaco/src/engine/megaco_digit_map.erl index de28686d6d..a904bd565a 100644 --- a/lib/megaco/src/engine/megaco_digit_map.erl +++ b/lib/megaco/src/engine/megaco_digit_map.erl @@ -362,7 +362,7 @@ collect(Event, State, Timers, STL, Letters) -> "~n Timers2: ~p" "~n Letters2: ~p", [State2, Timers2, Letters2]), MaxWait = choose_timer(State2, Event, Timers2), - ?d("collect -> Timer choosen: " + ?d("collect -> Timer chosen: " "~n MaxWait: ~p", [MaxWait]), receive {?MODULE, _FromPid, Event2} -> @@ -737,7 +737,7 @@ compute_cont([Next | Cont] = All, Mode, GlobalMode, State, STL) -> "~n Mode: ~p" "~n GlobalMode: ~p", [Next, Mode, GlobalMode]), case Next of - %% Retain long timer if that has already been choosen + %% Retain long timer if that has already been chosen use_short_timer when GlobalMode =:= use_long_timer -> compute_cont(Cont, Mode, GlobalMode, State, STL); use_short_timer -> diff --git a/lib/megaco/test/megaco_mess_test.erl b/lib/megaco/test/megaco_mess_test.erl index 383e3df774..8bafab1aba 100644 --- a/lib/megaco/test/megaco_mess_test.erl +++ b/lib/megaco/test/megaco_mess_test.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2010. All Rights Reserved. +%% Copyright Ericsson AB 1999-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -456,9 +456,20 @@ connect(Config) when is_list(Config) -> ?VERIFY(bad_send_mod, megaco:user_info(MgMid, send_mod)), ?VERIFY(bad_send_mod, megaco:conn_info(PrelCH, send_mod)), SC = service_change_request(), - ?VERIFY({1, {error, {send_message_failed, {'EXIT', - {undef, [{bad_send_mod, send_message, [sh, _]} | _]}}}}}, - megaco:call(PrelCH, [SC], [])), + case megaco:call(PrelCH, [SC], []) of + {error, + {send_message_failed, + {'EXIT', {undef, [{bad_send_mod, send_message, [sh, _]} | _]}}}} -> + ok; + + %% As of R15, we also get some extra info (e.g. line numbers) + {error, + {send_message_failed, + {'EXIT', {undef, [{bad_send_mod, send_message, [sh, _], _} | _]}}}} -> + ok; + Unexpected -> + ?ERROR(Unexpected) + end, ?VERIFY(ok, megaco:disconnect(PrelCH, shutdown)), diff --git a/lib/mnesia/doc/src/mnesia.xml b/lib/mnesia/doc/src/mnesia.xml index 19ec70118f..20133cb6cb 100644 --- a/lib/mnesia/doc/src/mnesia.xml +++ b/lib/mnesia/doc/src/mnesia.xml @@ -813,6 +813,21 @@ mnesia:change_table_copy_type(person, node(), disc_copies) </p> </item> <item> + <p><c>{storage_properties, [{Backend, Properties}]</c>. + Forwards additional properties to the backend storage. + <c>Backend</c> can currently be <c>ets</c> or <c>dets</c> and + <c>Properties</c> is a list of options sent to the backend storage + during table creation. <c>Properties</c> may not contain properties + already used by mnesia such as <c>type</c> or <c>named_table</c>. + </p> + <p>For example:</p> + <code type="none"> +mnesia:create_table(table, [{ram_copies, [node()]}, {disc_only_copies, nodes()}, + {storage_properties, + [{ets, [compressed]}, {dets, [{auto_save, 5000}]} ]}]) + </code> + </item> + <item> <p><c>{type, Type}</c>, where <c>Type</c> must be either of the atoms <c>set</c>, <c>ordered_set</c> or <c>bag</c>. The default value is <c>set</c>. In a diff --git a/lib/mnesia/src/mnesia.appup.src b/lib/mnesia/src/mnesia.appup.src index e0954ad206..304a15242f 100644 --- a/lib/mnesia/src/mnesia.appup.src +++ b/lib/mnesia/src/mnesia.appup.src @@ -1,14 +1,16 @@ %% -*- erlang -*- {"%VSN%", [ - {"4.5", [{restart_application, mnesia}]}, + {"4.5.1", [{restart_application, mnesia}]}, + {"4.5", [{restart_application, mnesia}]}, {"4.4.19", [{restart_application, mnesia}]}, {"4.4.18", [{restart_application, mnesia}]}, {"4.4.17", [{restart_application, mnesia}]}, {"4.4.16", [{restart_application, mnesia}]} ], [ - {"4.5", [{restart_application, mnesia}]}, + {"4.5.1", [{restart_application, mnesia}]}, + {"4.5", [{restart_application, mnesia}]}, {"4.4.19", [{restart_application, mnesia}]}, {"4.4.18", [{restart_application, mnesia}]}, {"4.4.17", [{restart_application, mnesia}]}, diff --git a/lib/mnesia/src/mnesia.hrl b/lib/mnesia/src/mnesia.hrl index 2375b72d59..2855792646 100644 --- a/lib/mnesia/src/mnesia.hrl +++ b/lib/mnesia/src/mnesia.hrl @@ -70,6 +70,7 @@ attributes = [key, val], % [Atom] user_properties = [], % [Record] frag_properties = [], % [{Key, Val] + storage_properties = [], % [{Key, Val] cookie = ?unique_cookie, % Term version = {{2, 0}, []}}). % {{Integer, Integer}, [Node]} diff --git a/lib/mnesia/src/mnesia_controller.erl b/lib/mnesia/src/mnesia_controller.erl index 6a561394d5..836510a80d 100644 --- a/lib/mnesia/src/mnesia_controller.erl +++ b/lib/mnesia/src/mnesia_controller.erl @@ -279,11 +279,8 @@ rec_tabs([], _, _, Init) -> unlink(Init), ok. -%% New function that does exactly what get_cstructs() used to do. -%% When this function is called, we know that the calling node knows -%% how to convert cstructs on the receiving end (should they differ). get_remote_cstructs() -> - call(get_cstructs). + get_cstructs(). %% Sigh not forward compatible always check version %% Old function kept for backwards compatibility; converts cstructs before sending. get_cstructs() -> diff --git a/lib/mnesia/src/mnesia_dumper.erl b/lib/mnesia/src/mnesia_dumper.erl index f8d7664156..9e7e1ad1c6 100644 --- a/lib/mnesia/src/mnesia_dumper.erl +++ b/lib/mnesia/src/mnesia_dumper.erl @@ -604,15 +604,19 @@ insert_op(Tid, _, {op, restore_recreate, TabDef}, InPlace, InitBy) -> mnesia_checkpoint:tm_del_copy(Tab, node()) end end, + StorageProps = Cs#cstruct.storage_properties, + %% And create new ones.. if (InitBy == startup) or (Storage == unknown) -> ignore; Storage == ram_copies -> - Args = [{keypos, 2}, public, named_table, Type], + EtsProps = proplists:get_value(ets, StorageProps, []), + Args = [{keypos, 2}, public, named_table, Type | EtsProps], mnesia_monitor:mktab(Tab, Args); Storage == disc_copies -> - Args = [{keypos, 2}, public, named_table, Type], + EtsProps = proplists:get_value(ets, StorageProps, []), + Args = [{keypos, 2}, public, named_table, Type | EtsProps], mnesia_monitor:mktab(Tab, Args), File = mnesia_lib:tab2dcd(Tab), FArg = [{file, File}, {name, {mnesia,create}}, @@ -622,10 +626,12 @@ insert_op(Tid, _, {op, restore_recreate, TabDef}, InPlace, InitBy) -> Storage == disc_only_copies -> File = mnesia_lib:tab2dat(Tab), file:delete(File), + DetsProps = proplists:get_value(dets, StorageProps, []), Args = [{file, mnesia_lib:tab2dat(Tab)}, {type, mnesia_lib:disk_type(Tab, Type)}, {keypos, 2}, - {repair, mnesia_monitor:get_env(auto_repair)}], + {repair, mnesia_monitor:get_env(auto_repair)} + | DetsProps ], mnesia_monitor:open_dets(Tab, Args) end, insert_op(Tid, ignore, {op, create_table, TabDef}, InPlace, InitBy); @@ -635,6 +641,7 @@ insert_op(Tid, _, {op, create_table, TabDef}, InPlace, InitBy) -> insert_cstruct(Tid, Cs, false, InPlace, InitBy), Tab = Cs#cstruct.name, Storage = mnesia_lib:cs_to_storage_type(node(), Cs), + StorageProps = Cs#cstruct.storage_properties, case InitBy of startup -> case Storage of @@ -656,10 +663,13 @@ insert_op(Tid, _, {op, create_table, TabDef}, InPlace, InitBy) -> mnesia_log:unsafe_close_log(temp) end; _ -> + DetsProps = proplists:get_value(dets, StorageProps, []), + Args = [{file, mnesia_lib:tab2dat(Tab)}, {type, mnesia_lib:disk_type(Tab, Cs#cstruct.type)}, {keypos, 2}, - {repair, mnesia_monitor:get_env(auto_repair)}], + {repair, mnesia_monitor:get_env(auto_repair)} + | DetsProps ], case mnesia_monitor:open_dets(Tab, Args) of {ok, _} -> mnesia_monitor:unsafe_close_dets(Tab); @@ -671,7 +681,7 @@ insert_op(Tid, _, {op, create_table, TabDef}, InPlace, InitBy) -> Copies = mnesia_lib:copy_holders(Cs), Active = mnesia_lib:intersect(Copies, val({current, db_nodes})), [mnesia_controller:add_active_replica(Tab, N, Cs) || N <- Active], - + case Storage of unknown -> mnesia_lib:unset({Tab, create_table}), @@ -944,11 +954,14 @@ open_files(Tab, Storage, UpdateInPlace, InitBy) Bool = open_disc_copies(Tab, InitBy), Bool; _ -> + Props = val({Tab, storage_properties}), + DetsProps = proplists:get_value(dets, Props, []), Fname = prepare_open(Tab, UpdateInPlace), Args = [{file, Fname}, {keypos, 2}, {repair, mnesia_monitor:get_env(auto_repair)}, - {type, mnesia_lib:disk_type(Tab, Type)}], + {type, mnesia_lib:disk_type(Tab, Type)} + | DetsProps], {ok, _} = mnesia_monitor:open_dets(Tab, Args), put({?MODULE, Tab}, {opened_dumper, dat}), true diff --git a/lib/mnesia/src/mnesia_frag_hash.erl b/lib/mnesia/src/mnesia_frag_hash.erl index 610ba2535c..d70579c3b3 100644 --- a/lib/mnesia/src/mnesia_frag_hash.erl +++ b/lib/mnesia/src/mnesia_frag_hash.erl @@ -101,21 +101,19 @@ del_frag(OldState) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -key_to_frag_number(#hash_state{function = phash, next_n_to_split = SplitN, n_doubles = L}, Key) -> - P = SplitN, - A = erlang:phash(Key, power2(L)), +key_to_frag_number(#hash_state{function = phash, n_fragments = N, n_doubles = L}, Key) -> + A = erlang:phash(Key, power2(L + 1)), if - A < P -> - erlang:phash(Key, power2(L + 1)); + A > N -> + A - power2(L); true -> A end; -key_to_frag_number(#hash_state{function = phash2, next_n_to_split = SplitN, n_doubles = L}, Key) -> - P = SplitN, - A = erlang:phash2(Key, power2(L)) + 1, +key_to_frag_number(#hash_state{function = phash2, n_fragments = N, n_doubles = L}, Key) -> + A = erlang:phash2(Key, power2(L + 1)) + 1, if - A < P -> - erlang:phash2(Key, power2(L + 1)) + 1; + A > N -> + A - power2(L); true -> A end; diff --git a/lib/mnesia/src/mnesia_loader.erl b/lib/mnesia/src/mnesia_loader.erl index c4b22814a8..e443b54016 100644 --- a/lib/mnesia/src/mnesia_loader.erl +++ b/lib/mnesia/src/mnesia_loader.erl @@ -61,9 +61,11 @@ do_get_disc_copy2(Tab, _Reason, Storage, _Type) when Storage == unknown -> do_get_disc_copy2(Tab, Reason, Storage, Type) when Storage == disc_copies -> %% NOW we create the actual table Repair = mnesia_monitor:get_env(auto_repair), - Args = [{keypos, 2}, public, named_table, Type], + StorageProps = val({Tab, storage_properties}), + EtsOpts = proplists:get_value(ets, StorageProps, []), + Args = [{keypos, 2}, public, named_table, Type | EtsOpts], case Reason of - {dumper, _} -> %% Resources allready allocated + {dumper, _} -> %% Resources already allocated ignore; _ -> mnesia_monitor:mktab(Tab, Args), @@ -82,7 +84,9 @@ do_get_disc_copy2(Tab, Reason, Storage, Type) when Storage == disc_copies -> {loaded, ok}; do_get_disc_copy2(Tab, Reason, Storage, Type) when Storage == ram_copies -> - Args = [{keypos, 2}, public, named_table, Type], + StorageProps = val({Tab, storage_properties}), + EtsOpts = proplists:get_value(ets, StorageProps, []), + Args = [{keypos, 2}, public, named_table, Type | EtsOpts], case Reason of {dumper, _} -> %% Resources allready allocated ignore; @@ -115,10 +119,14 @@ do_get_disc_copy2(Tab, Reason, Storage, Type) when Storage == ram_copies -> {loaded, ok}; do_get_disc_copy2(Tab, Reason, Storage, Type) when Storage == disc_only_copies -> + StorageProps = val({Tab, storage_properties}), + DetsOpts = proplists:get_value(dets, StorageProps, []), + Args = [{file, mnesia_lib:tab2dat(Tab)}, {type, mnesia_lib:disk_type(Tab, Type)}, {keypos, 2}, - {repair, mnesia_monitor:get_env(auto_repair)}], + {repair, mnesia_monitor:get_env(auto_repair)} + | DetsOpts], case Reason of {dumper, _} -> mnesia_index:init_index(Tab, Storage), @@ -349,17 +357,21 @@ do_init_table(Tab,Storage,Cs,SenderPid, end. create_table(Tab, TabSize, Storage, Cs) -> + StorageProps = val({Tab, storage_properties}), if Storage == disc_only_copies -> mnesia_lib:lock_table(Tab), Tmp = mnesia_lib:tab2tmp(Tab), Size = lists:max([TabSize, 256]), + DetsOpts = lists:keydelete(estimated_no_objects, 1, + proplists:get_value(dets, StorageProps, [])), Args = [{file, Tmp}, {keypos, 2}, %% {ram_file, true}, {estimated_no_objects, Size}, {repair, mnesia_monitor:get_env(auto_repair)}, - {type, mnesia_lib:disk_type(Tab, Cs#cstruct.type)}], + {type, mnesia_lib:disk_type(Tab, Cs#cstruct.type)} + | DetsOpts], file:delete(Tmp), case mnesia_lib:dets_sync_open(Tab, Args) of {ok, _} -> @@ -370,7 +382,8 @@ create_table(Tab, TabSize, Storage, Cs) -> Else end; (Storage == ram_copies) or (Storage == disc_copies) -> - Args = [{keypos, 2}, public, named_table, Cs#cstruct.type], + EtsOpts = proplists:get_value(ets, StorageProps, []), + Args = [{keypos, 2}, public, named_table, Cs#cstruct.type | EtsOpts], case mnesia_monitor:unsafe_mktab(Tab, Args) of Tab -> {Storage, Tab}; @@ -516,10 +529,13 @@ handle_last({disc_only_copies, Tab}, Type, nobin) -> Dat = mnesia_lib:tab2dat(Tab), case file:rename(Tmp, Dat) of ok -> + StorageProps = val({Tab, storage_properties}), + DetsOpts = proplists:get_value(dets, StorageProps, []), + Args = [{file, mnesia_lib:tab2dat(Tab)}, {type, mnesia_lib:disk_type(Tab, Type)}, {keypos, 2}, - {repair, mnesia_monitor:get_env(auto_repair)}], + {repair, mnesia_monitor:get_env(auto_repair)} | DetsOpts], mnesia_monitor:open_dets(Tab, Args), ok; {error, Reason} -> diff --git a/lib/mnesia/src/mnesia_monitor.erl b/lib/mnesia/src/mnesia_monitor.erl index 8cb2e92c08..c08bbc879f 100644 --- a/lib/mnesia/src/mnesia_monitor.erl +++ b/lib/mnesia/src/mnesia_monitor.erl @@ -80,9 +80,9 @@ going_down = [], tm_started = false, early_connects = [], connecting, mq = []}). --define(current_protocol_version, {8,0}). +-define(current_protocol_version, {8,1}). --define(previous_protocol_version, {7,6}). +-define(previous_protocol_version, {8,0}). start() -> gen_server:start_link({local, ?MODULE}, ?MODULE, @@ -188,7 +188,7 @@ protocol_version() -> %% A sorted list of acceptable protocols the %% preferred protocols are first in the list acceptable_protocol_versions() -> - [protocol_version(), ?previous_protocol_version]. + [protocol_version(), ?previous_protocol_version, {7,6}]. needs_protocol_conversion(Node) -> case {?catch_val({protocol, Node}), protocol_version()} of @@ -417,6 +417,8 @@ handle_call({negotiate_protocol, Mon, Version, Protocols}, From, State) case hd(Protocols) of ?previous_protocol_version -> accept_protocol(Mon, MyVersion, ?previous_protocol_version, From, State); + {7,6} -> + accept_protocol(Mon, MyVersion, {7,6}, From, State); _ -> verbose("Connection with ~p rejected. " "version = ~p, protocols = ~p, " diff --git a/lib/mnesia/src/mnesia_schema.erl b/lib/mnesia/src/mnesia_schema.erl index 179e15197e..6e43052fb0 100644 --- a/lib/mnesia/src/mnesia_schema.erl +++ b/lib/mnesia/src/mnesia_schema.erl @@ -188,6 +188,7 @@ do_set_schema(Tab, Cs) -> [set({Tab, user_property, element(1, P)}, P) || P <- Cs#cstruct.user_properties], set({Tab, frag_properties}, Cs#cstruct.frag_properties), mnesia_frag:set_frag_hash(Tab, Cs#cstruct.frag_properties), + set({Tab, storage_properties}, Cs#cstruct.storage_properties), set({Tab, attributes}, Cs#cstruct.attributes), Arity = length(Cs#cstruct.attributes) + 1, set({Tab, arity}, Arity), @@ -644,6 +645,14 @@ cs2list(Cs) when is_record(Cs, cstruct) -> rec2list(Tags, Tags, 2, Cs); cs2list(CreateList) when is_list(CreateList) -> CreateList; +%% 4.6 +cs2list(Cs) when element(1, Cs) == cstruct, tuple_size(Cs) == 19 -> + Tags = [name,type,ram_copies,disc_copies,disc_only_copies, + load_order,access_mode,majority,index,snmp,local_content, + record_name,attributes, + user_properties,frag_properties,storage_properties, + cookie,version], + rec2list(Tags, Tags, 2, Cs); %% 4.4.19 cs2list(Cs) when element(1, Cs) == cstruct, tuple_size(Cs) == 18 -> Tags = [name,type,ram_copies,disc_copies,disc_only_copies, @@ -674,8 +683,17 @@ cs2list(ver4_4_19, Cs) -> load_order,access_mode,majority,index,snmp,local_content, record_name,attributes,user_properties,frag_properties, cookie,version], + rec2list(Tags, Orig, 2, Cs); +cs2list(ver4_6, Cs) -> + Orig = record_info(fields, cstruct), + Tags = [name,type,ram_copies,disc_copies,disc_only_copies, + load_order,access_mode,majority,index,snmp,local_content, + record_name,attributes, + user_properties,frag_properties,storage_properties, + cookie,version], rec2list(Tags, Orig, 2, Cs). + rec2list([Tag | Tags], [Tag | Orig], Pos, Rec) -> Val = element(Pos, Rec), [{Tag, Val} | rec2list(Tags, Orig, Pos + 1, Rec)]; @@ -728,6 +746,29 @@ list2cs(List) when is_list(List) -> Frag = pick(Name, frag_properties, List, []), verify({alt, [nil, list]}, mnesia_lib:etype(Frag), {badarg, Name, {frag_properties, Frag}}), + + BEProps = pick(Name, storage_properties, List, []), + verify({alt, [nil, list]}, mnesia_lib:etype(Ix), + {badarg, Name, {storage_properties, BEProps}}), + CheckProp = fun(Opt, Opts) when is_atom(Opt) -> + lists:member(Opt, Opts) + andalso mnesia:abort({badarg, Name, Opt}); + (Tuple, Opts) when is_tuple(Tuple) -> + lists:member(element(1,Tuple), Opts) + andalso mnesia:abort({badarg, Name, Tuple}); + (What,_) -> + mnesia:abort({badarg, Name, What}) + end, + BadEtsOpts = [set, ordered_set, bag, duplicate_bag, + public, private, protected, + keypos, named_table], + EtsOpts = proplists:get_value(ets, BEProps, []), + is_list(EtsOpts) orelse mnesia:abort({badarg, Name, {ets, EtsOpts}}), + [CheckProp(Prop, BadEtsOpts) || Prop <- EtsOpts], + BadDetsOpts = [type, keypos, repair, access, file], + DetsOpts = proplists:get_value(dets, BEProps, []), + is_list(DetsOpts) orelse mnesia:abort({badarg, Name, {dets, DetsOpts}}), + [CheckProp(Prop, BadDetsOpts) || Prop <- DetsOpts], #cstruct{name = Name, ram_copies = Rc, disc_copies = Dc, @@ -743,6 +784,7 @@ list2cs(List) when is_list(List) -> attributes = Attrs, user_properties = lists:sort(UserProps), frag_properties = lists:sort(Frag), + storage_properties = lists:sort(BEProps), cookie = Cookie, version = Version}. @@ -1881,18 +1923,18 @@ prepare_op(Tid, {op, create_table, TabDef}, _WaitFor) -> mnesia:abort(UseDirReason); ram_copies -> mnesia_lib:set({Tab, create_table},true), - create_ram_table(Tab, Cs#cstruct.type), + create_ram_table(Tab, Cs), insert_cstruct(Tid, Cs, false), {true, optional}; disc_copies -> mnesia_lib:set({Tab, create_table},true), - create_ram_table(Tab, Cs#cstruct.type), + create_ram_table(Tab, Cs), create_disc_table(Tab), insert_cstruct(Tid, Cs, false), {true, optional}; disc_only_copies -> mnesia_lib:set({Tab, create_table},true), - create_disc_only_table(Tab,Cs#cstruct.type), + create_disc_only_table(Tab,Cs), insert_cstruct(Tid, Cs, false), {true, optional}; unknown -> %% No replica on this node @@ -2044,7 +2086,7 @@ prepare_op(_Tid, {op, change_table_copy_type, N, FromS, ToS, TabDef}, _WaitFor) mnesia_dumper:raw_named_dump_table(Tab, dmp); FromS == disc_only_copies -> Type = Cs#cstruct.type, - create_ram_table(Tab, Type), + create_ram_table(Tab, Cs), Datname = mnesia_lib:tab2dat(Tab), Repair = mnesia_monitor:get_env(auto_repair), case mnesia_lib:dets_to_ets(Tab, Tab, Datname, Type, Repair, no) of @@ -2132,8 +2174,9 @@ prepare_op(_Tid, {op, merge_schema, TabDef}, _WaitFor) -> prepare_op(_Tid, _Op, _WaitFor) -> {true, optional}. -create_ram_table(Tab, Type) -> - Args = [{keypos, 2}, public, named_table, Type], +create_ram_table(Tab, #cstruct{type=Type, storage_properties=Props}) -> + EtsOpts = proplists:get_value(ets, Props, []), + Args = [{keypos, 2}, public, named_table, Type | EtsOpts], case mnesia_monitor:unsafe_mktab(Tab, Args) of Tab -> ok; @@ -2141,6 +2184,7 @@ create_ram_table(Tab, Type) -> Err = "Failed to create ets table", mnesia:abort({system_limit, Tab, {Err,Reason}}) end. + create_disc_table(Tab) -> File = mnesia_lib:tab2dcd(Tab), file:delete(File), @@ -2154,13 +2198,15 @@ create_disc_table(Tab) -> Err = "Failed to create disc table", mnesia:abort({system_limit, Tab, {Err,Reason}}) end. -create_disc_only_table(Tab,Type) -> +create_disc_only_table(Tab, #cstruct{type=Type, storage_properties=Props}) -> File = mnesia_lib:tab2dat(Tab), file:delete(File), + DetsOpts = proplists:get_value(dets, Props, []), Args = [{file, mnesia_lib:tab2dat(Tab)}, {type, mnesia_lib:disk_type(Tab, Type)}, {keypos, 2}, - {repair, mnesia_monitor:get_env(auto_repair)}], + {repair, mnesia_monitor:get_env(auto_repair)} + | DetsOpts], case mnesia_monitor:unsafe_open_dets(Tab, Args) of {ok, _} -> ok; @@ -2688,17 +2734,17 @@ restore_schema([{schema, Tab, List} | Schema], R) -> R2 = R#r{tables = [{Tab, undefined, Snmp, RecName} | R#r.tables]}, restore_schema(Schema, R2); recreate_tables -> - case ?catch_val({Tab, cstruct}) of - {'EXIT', _} -> - TidTs = {_Mod, Tid, Ts} = get(mnesia_activity_state), - RunningNodes = val({current, db_nodes}), - Nodes = mnesia_lib:intersect(mnesia_lib:cs_to_nodes(list2cs(List)), - RunningNodes), - mnesia_locker:wlock_no_exist(Tid, Ts#tidstore.store, Tab, Nodes), - TidTs; - _ -> - TidTs = get_tid_ts_and_lock(Tab, write) - end, + TidTs = case ?catch_val({Tab, cstruct}) of + {'EXIT', _} -> + TTs = {_Mod, Tid, Ts} = get(mnesia_activity_state), + RunningNodes = val({current, db_nodes}), + Nodes = mnesia_lib:intersect(mnesia_lib:cs_to_nodes(list2cs(List)), + RunningNodes), + mnesia_locker:wlock_no_exist(Tid, Ts#tidstore.store, Tab, Nodes), + TTs; + _ -> + get_tid_ts_and_lock(Tab, write) + end, NC = {cookie, ?unique_cookie}, List2 = lists:keyreplace(cookie, 1, List, NC), Where = where_to_commit(Tab, List2), @@ -2839,15 +2885,15 @@ do_merge_schema(LockTabs0) -> end. fetch_cstructs(Node) -> - case mnesia_monitor:needs_protocol_conversion(Node) of - true -> + case need_old_cstructs([Node]) of + false -> + rpc:call(Node, mnesia_controller, get_remote_cstructs, []); + _Ver -> case rpc:call(Node, mnesia_controller, get_cstructs, []) of {cstructs, Cs0, RR} -> {cstructs, [list2cs(cs2list(Cs)) || Cs <- Cs0], RR}; Err -> Err - end; - false -> - rpc:call(Node, mnesia_controller, get_remote_cstructs, []) + end end. need_old_cstructs() -> @@ -2868,7 +2914,9 @@ need_old_cstructs(Nodes) -> Cs when element(1, Cs) == cstruct, tuple_size(Cs) == 17 -> ver4_4_18; % Without majority Cs when element(1, Cs) == cstruct, tuple_size(Cs) == 18 -> - ver4_4_19 % With majority + ver4_4_19; % With majority + Cs when element(1, Cs) == cstruct, tuple_size(Cs) == 19 -> + ver4_6 % With storage_properties end end. diff --git a/lib/mnesia/test/mnesia_evil_coverage_test.erl b/lib/mnesia/test/mnesia_evil_coverage_test.erl index 17d6c6c212..64b61288ef 100644 --- a/lib/mnesia/test/mnesia_evil_coverage_test.erl +++ b/lib/mnesia/test/mnesia_evil_coverage_test.erl @@ -37,7 +37,8 @@ end_per_testcase(Func, Conf) -> all() -> [system_info, table_info, error_description, db_node_lifecycle, evil_delete_db_node, start_and_stop, - checkpoint, table_lifecycle, add_copy_conflict, + checkpoint, table_lifecycle, storage_options, + add_copy_conflict, add_copy_when_going_down, replica_management, schema_availability, local_content, {group, table_access_modifications}, replica_location, @@ -244,7 +245,7 @@ db_node_lifecycle(Config) when is_list(Config) -> ?match([], mnesia_test_lib:start_mnesia(AllNodes)), ?match([SNs, SNs, SNs], - lists:map({lists, sort}, + lists:map(fun lists:sort/1, element(1, rpc:multicall(AllNodes, mnesia, table_info, [schema, disc_copies])))), @@ -259,7 +260,7 @@ db_node_lifecycle(Config) when is_list(Config) -> mnesia:change_table_copy_type(schema, Node2, disc_copies)), ?match([SNs, SNs, SNs], - lists:map({lists, sort}, + lists:map(fun lists:sort/1, element(1, rpc:multicall(AllNodes, mnesia, table_info, [schema, disc_copies])))), @@ -462,7 +463,7 @@ table_lifecycle(Config) when is_list(Config) -> ?match({atomic, ok}, mnesia:create_table([{name, already_exists}, {ram_copies, [Node1]}])), ?match({aborted, Reason23 } when element(1, Reason23) ==already_exists, - mnesia:create_table([{name, already_exists}, + mnesia:create_table([{name, already_exists}, {ram_copies, [Node1]}])), ?match({aborted, Reason21 } when element(1, Reason21) == bad_type, mnesia:create_table([{name, bad_node}, {ram_copies, ["foo"]}])), @@ -520,12 +521,57 @@ table_lifecycle(Config) when is_list(Config) -> ?match({atomic, ok}, mnesia:create_table([{name, create_with_index}, {index, [3]}, {ram_copies, [Node1]}])), - ets:new(ets_table, [named_table]), + ets:new(ets_table, [named_table]), ?match({aborted, _}, mnesia:create_table(ets_table, [{ram_copies, Nodes}])), + ?match({aborted, _}, mnesia:create_table(ets_table, [{ram_copies, [Node1]}])), + ets:delete(ets_table), + ?match({atomic, ok}, mnesia:create_table(ets_table, [{ram_copies, [Node1]}])), + ?match(Node1, rpc:call(Node1, mnesia_lib, val, [{ets_table,where_to_read}])), + ?match(Node1, rpc:call(Node2, mnesia_lib, val, [{ets_table,where_to_read}])), + ?match({atomic, ok}, mnesia:change_table_copy_type(ets_table, Node1, disc_only_copies)), + ?match(Node1, rpc:call(Node2, mnesia_lib, val, [{ets_table,where_to_read}])), + + ?verify_mnesia(Nodes, []). + + +storage_options(suite) -> []; +storage_options(Config) when is_list(Config) -> + [N1,N2,N3] = Nodes = ?acquire_nodes(3, Config), + + ?match({aborted,_}, mnesia:create_table(a, [{storage_properties, [{ets,foobar}]}])), + ?match({aborted,_}, mnesia:create_table(a, [{storage_properties, [{ets,[foobar]}]}])), + ?match({aborted,_}, mnesia:create_table(a, [{storage_properties, [{ets,[duplicate_bag]}]}])), + ?match({aborted,_}, mnesia:create_table(a, [{storage_properties, [{dets,[{type,bag}]}]}])), + + ?match({atomic, ok}, mnesia:create_table(a, [{ram_copies, [N1]}, + {disc_only_copies, [N2]}, + {storage_properties, + [{ets,[compressed]}, + {dets, [{auto_save, 5000}]} ]}])), + ?match(true, ets:info(a, compressed)), + ?match(5000, rpc:call(N2, dets, info, [a, auto_save])), + ?match(ok, mnesia:dirty_write({a,1,1})), + ?match([{a,1,1}], mnesia:dirty_read({a,1})), + mnesia:dump_log(), + W2C1 = [{N2, disc_only_copies}, {N1, ram_copies}], + ?match(W2C1, lists:sort(rpc:call(N2, mnesia_lib, val, [{a, where_to_commit}]))), + ?match(W2C1, lists:sort(rpc:call(N3, mnesia_lib, val, [{a, where_to_commit}]))), + ?match({atomic,ok}, mnesia:change_table_copy_type(a, N1, disc_only_copies)), + W2C2 = [{N2, disc_only_copies}, {N1, disc_only_copies}], + ?match(W2C2, lists:sort(rpc:call(N2, mnesia_lib, val, [{a, where_to_commit}]))), + ?match(W2C2, lists:sort(rpc:call(N3, mnesia_lib, val, [{a, where_to_commit}]))), + ?match(undefined, ets:info(a, compressed)), + ?match(5000, dets:info(a, auto_save)), + ?match({atomic,ok}, mnesia:change_table_copy_type(a, N1, disc_copies)), + ?match(true, ets:info(a, compressed)), ?verify_mnesia(Nodes, []). + + + + add_copy_conflict(suite) -> []; add_copy_conflict(doc) -> ["Verify that OTP-5065 doesn't happen again, whitebox testing"]; diff --git a/lib/mnesia/test/mnesia_frag_hash_test.erl b/lib/mnesia/test/mnesia_frag_hash_test.erl new file mode 100644 index 0000000000..095d25e74f --- /dev/null +++ b/lib/mnesia/test/mnesia_frag_hash_test.erl @@ -0,0 +1,94 @@ +-module(mnesia_frag_hash_test). + +-export([test/0]). + +-define(NUM_FRAGS, 20). +-define(NUM_KEYS, 10000). + +-record(hash_state, + {n_fragments, + next_n_to_split, + n_doubles, + function}). + +% OLD mnesia_frag_hash:key_to_frag_number/2. +old_key_to_frag_number(#hash_state{function = phash, next_n_to_split = SplitN, n_doubles = L}, Key) -> + P = SplitN, + A = erlang:phash(Key, power2(L)), + if + A < P -> + erlang:phash(Key, power2(L + 1)); + true -> + A + end; +old_key_to_frag_number(#hash_state{function = phash2, next_n_to_split = SplitN, n_doubles = L}, Key) -> + P = SplitN, + A = erlang:phash2(Key, power2(L)) + 1, + if + A < P -> + erlang:phash2(Key, power2(L + 1)) + 1; + true -> + A + end; +old_key_to_frag_number(OldState, Key) -> + State = convert_old_state(OldState), + old_key_to_frag_number(State, Key). + + +% NEW mnesia_frag_hash:key_to_frag_number/2. +new_key_to_frag_number(#hash_state{function = phash, n_fragments = N, n_doubles = L}, Key) -> + A = erlang:phash(Key, power2(L + 1)), + if + A > N -> + A - power2(L); + true -> + A + end; +new_key_to_frag_number(#hash_state{function = phash2, n_fragments = N, n_doubles = L}, Key) -> + A = erlang:phash2(Key, power2(L + 1)) + 1, + if + A > N -> + A - power2(L); + true -> + A + end; +new_key_to_frag_number(OldState, Key) -> + State = convert_old_state(OldState), + new_key_to_frag_number(State, Key). + + +% Helpers for key_to_frag_number functions. + +power2(Y) -> + 1 bsl Y. % trunc(math:pow(2, Y)). + +convert_old_state({hash_state, N, P, L}) -> + #hash_state{n_fragments = N, + next_n_to_split = P, + n_doubles = L, + function = phash}. + + +test() -> + test2(mnesia_frag_hash:init_state(undefined, undefined)), % phash2 + test2({hash_state, 1, 1, 0}). % phash + +test2(I) -> + test_keys(I), + lists:foldl( + fun(_, S) -> test_frag(S) end, + I, lists:seq(1, ?NUM_FRAGS)), + ok. + +test_frag(State) -> + {State2,_,_} = mnesia_frag_hash:add_frag(State), + test_keys(State2), + State2. + +test_keys(State) -> + [test_key(State, Key) || Key <- lists:seq(1, ?NUM_KEYS)]. + +test_key(State, Key) -> + Old = old_key_to_frag_number(State, Key), + New = new_key_to_frag_number(State, Key), + Old = New. diff --git a/lib/observer/priv/erlang_observer.png b/lib/observer/priv/erlang_observer.png Binary files differnew file mode 100644 index 0000000000..78e70461b1 --- /dev/null +++ b/lib/observer/priv/erlang_observer.png diff --git a/lib/observer/src/Makefile b/lib/observer/src/Makefile index 3875b62101..95954d8587 100644 --- a/lib/observer/src/Makefile +++ b/lib/observer/src/Makefile @@ -1,19 +1,19 @@ # # %CopyrightBegin% -# +# # Copyright Ericsson AB 2002-2011. All Rights Reserved. -# +# # The contents of this file are subject to the Erlang Public License, # Version 1.1, (the "License"); you may not use this file except in # compliance with the License. You should have received a copy of the # Erlang Public License along with this software. If not, it can be # retrieved online at http://www.erlang.org/. -# +# # Software distributed under the License is distributed on an "AS IS" # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See # the License for the specific language governing rights and limitations # under the License. -# +# # %CopyrightEnd% # include $(ERL_TOP)/make/target.mk @@ -41,8 +41,19 @@ MODULES= \ etop_gui \ etop_tr \ etop_txt \ + observer \ + observer_lib \ + observer_wx \ + observer_pro_wx \ + observer_procinfo \ + observer_sys_wx \ + observer_trace_wx \ + observer_traceoptions_wx \ + observer_tv_table \ + observer_tv_wx \ ttb \ ttb_et + HRL_FILES= \ ../include/etop.hrl INTERNAL_HRL_FILES= \ @@ -54,7 +65,7 @@ EXAMPLE_FILES= multitrace.erl TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) $(APP_TARGET) $(APPUP_TARGET) PRIVDIR= ../priv -WEBTOOLFILES= $(PRIVDIR)/crashdump_viewer.tool +WEBTOOLFILES= $(PRIVDIR)/crashdump_viewer.tool $(PRIVDIR)/erlang_observer.png BINDIR= $(PRIVDIR)/bin ifeq ($(findstring win32,$(TARGET)),win32) WIN32_EXECUTABLES= $(BINDIR)/etop.bat $(BINDIR)/getop.bat $(BINDIR)/cdv.bat @@ -109,7 +120,7 @@ docs: # ---------------------------------------------------- # Release Target -# ---------------------------------------------------- +# ---------------------------------------------------- include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt diff --git a/lib/observer/src/observer.erl b/lib/observer/src/observer.erl new file mode 100644 index 0000000000..098100e8ee --- /dev/null +++ b/lib/observer/src/observer.erl @@ -0,0 +1,25 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2011. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% + +-module(observer). + +-export([start/0]). + + +start() -> + observer_wx:start(). diff --git a/lib/observer/src/observer_defs.hrl b/lib/observer/src/observer_defs.hrl new file mode 100644 index 0000000000..d83a1e2fa5 --- /dev/null +++ b/lib/observer/src/observer_defs.hrl @@ -0,0 +1,62 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2011. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% + +-record(trace_options, {send = false, + treceive = false, + functions = false, + events = false, + on_1st_spawn = false, + on_all_spawn = false, + on_1st_link = false, + on_all_link = false, + main_window = true}). + +-record(match_spec, {name = "", + term = [], + str = [], + func = ""}). + +-record(tpattern, {m, fa, ms}). + +-record(traced_func, {func_name, %atom + arity, %integer + match_spec = #match_spec{}}). + +-record(on_spawn, {checkbox, all_spawn, first_spawn}). + +-record(on_link, {checkbox, all_link, first_link}). + +-record(pid, {window, traced}). + +-record(create_menu, + {id, + text, + type = append, + check = false + }). + +-record(attrs, {even, odd, deleted, changed, searched}). +-define(EVEN(Row), ((Row rem 2) =:= 0)). +-define(BG_EVEN, {230,230,250}). +-define(BG_ODD, {255,255,255}). +-define(BG_DELETED, {100,100,100}). +-define(FG_DELETED, {240,30,30}). +-define(BG_SEARCHED,{235,215,90}). +-define(BG_CHANGED, {230,230,250}). + +-define(LCTRL_WDECR, 4). %% Remove some pixels in column width to avoid creating unnecessary scrollbar diff --git a/lib/observer/src/observer_lib.erl b/lib/observer/src/observer_lib.erl new file mode 100644 index 0000000000..90c270e977 --- /dev/null +++ b/lib/observer/src/observer_lib.erl @@ -0,0 +1,297 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2011. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% + +-module(observer_lib). + +-export([get_wx_parent/1, + display_info_dialog/1, + interval_dialog/4, start_timer/1, stop_timer/1, + display_info/2, fill_info/2, update_info/2, to_str/1, + create_menus/3, create_menu_item/3, + create_attrs/0 + ]). + +-include_lib("wx/include/wx.hrl"). +-include("observer_defs.hrl"). + +get_wx_parent(Window) -> + Parent = wxWindow:getParent(Window), + case wx:is_null(Parent) of + true -> Window; + false -> get_wx_parent(Parent) + end. + +interval_dialog(Parent0, {Timer, Value}, Min, Max) -> + Parent = get_wx_parent(Parent0), + Dialog = wxDialog:new(Parent, ?wxID_ANY, "Update Interval", + [{style, ?wxDEFAULT_DIALOG_STYLE bor + ?wxRESIZE_BORDER}]), + Panel = wxPanel:new(Dialog), + Check = wxCheckBox:new(Panel, ?wxID_ANY, "Periodical refresh"), + wxCheckBox:setValue(Check, Timer /= false), + Style = ?wxSL_HORIZONTAL bor ?wxSL_AUTOTICKS bor ?wxSL_LABELS, + Slider = wxSlider:new(Panel, ?wxID_ANY, Value, Min, Max, + [{style, Style}, {size, {200, -1}}]), + wxWindow:enable(Slider, [{enable, Timer /= false}]), + InnerSizer = wxBoxSizer:new(?wxVERTICAL), + Buttons = wxDialog:createButtonSizer(Dialog, ?wxOK bor ?wxCANCEL), + Flags = [{flag, ?wxEXPAND bor ?wxALL}, {border, 2}], + wxSizer:add(InnerSizer, Check, Flags), + wxSizer:add(InnerSizer, Slider, Flags), + wxPanel:setSizer(Panel, InnerSizer), + TopSizer = wxBoxSizer:new(?wxVERTICAL), + wxSizer:add(TopSizer, Panel, [{flag, ?wxEXPAND bor ?wxALL}, {border, 5}]), + wxSizer:add(TopSizer, Buttons, [{flag, ?wxEXPAND}]), + wxWindow:setSizerAndFit(Dialog, TopSizer), + wxSizer:setSizeHints(TopSizer, Dialog), + wxCheckBox:connect(Check, command_checkbox_clicked, + [{callback, fun(#wx{event=#wxCommand{commandInt=Enable0}},_) -> + Enable = Enable0 > 0, + wxWindow:enable(Slider, [{enable, Enable}]) + end}]), + Res = case wxDialog:showModal(Dialog) of + ?wxID_OK -> + Enabled = wxCheckBox:isChecked(Check), + setup_timer(Enabled, {Timer, wxSlider:getValue(Slider)}); + ?wxID_CANCEL -> + {Timer, Value} + end, + wxDialog:destroy(Dialog), + Res. + +stop_timer(Timer = {false, _}) -> Timer; +stop_timer(Timer = {true, _}) -> Timer; +stop_timer(Timer = {_, Intv}) -> + setup_timer(false, Timer), + {true, Intv}. +start_timer(Intv) when is_integer(Intv) -> + setup_timer(true, {true, Intv}); +start_timer(Timer) -> + setup_timer(true, Timer). + +setup_timer(false, {Timer, Value}) + when is_boolean(Timer) -> + {false, Value}; +setup_timer(true, {false, Value}) -> + {ok, Timer} = timer:send_interval(Value * 1000, refresh_interval), + {Timer, Value}; +setup_timer(Bool, {Timer, Old}) -> + timer:cancel(Timer), + setup_timer(Bool, {false, Old}). + +display_info_dialog(Str) -> + Dlg = wxMessageDialog:new(wx:null(), Str), + wxMessageDialog:showModal(Dlg), + wxMessageDialog:destroy(Dlg), + ok. + +%% display_info(Parent, [{Title, [{Label, Info}]}]) -> {Panel, Sizer, InfoFieldsToUpdate} +display_info(Frame, Info) -> + Panel = wxPanel:new(Frame), + wxWindow:setBackgroundColour(Panel, {255,255,255}), + Sizer = wxBoxSizer:new(?wxVERTICAL), + wxSizer:addSpacer(Sizer, 5), + Add = fun(BoxInfo) -> + {Box, InfoFs} = create_box(Panel, BoxInfo), + wxSizer:add(Sizer, Box, [{flag, ?wxEXPAND bor ?wxALL}, + {border, 5}]), + wxSizer:addSpacer(Sizer, 5), + InfoFs + end, + InfoFs = [Add(I) || I <- Info], + wxWindow:setSizerAndFit(Panel, Sizer), + {Panel, Sizer, InfoFs}. + +fill_info([{Str, Key}|Rest], Data) when is_atom(Key); is_function(Key) -> + [{Str, get_value(Key, Data)} | fill_info(Rest, Data)]; +fill_info([{Str, {Format, Key}}|Rest], Data) + when is_atom(Key); is_function(Key), is_atom(Format) -> + [{Str, {Format, get_value(Key,Data)}} | fill_info(Rest, Data)]; +fill_info([{Str,SubStructure}|Rest], Data) when is_list(SubStructure) -> + [{Str, fill_info(SubStructure, Data)}|fill_info(Rest,Data)]; +fill_info([{Str,Attrib,SubStructure}|Rest], Data) -> + [{Str, Attrib, fill_info(SubStructure, Data)}|fill_info(Rest,Data)]; +fill_info([], _) -> []. + +get_value(Key, Data) when is_atom(Key) -> + proplists:get_value(Key,Data); +get_value(Fun, Data) when is_function(Fun) -> + Fun(Data). + +update_info([Fields|Fs], [{_Header, SubStructure}| Rest]) -> + update_info2(Fields, SubStructure), + update_info(Fs, Rest); +update_info([Fields|Fs], [{_Header, _Attrib, SubStructure}| Rest]) -> + update_info2(Fields, SubStructure), + update_info(Fs, Rest); +update_info([], []) -> + ok. + +update_info2([Field|Fs], [{_Str, Value}|Rest]) -> + wxStaticText:setLabel(Field, to_str(Value)), + update_info2(Fs, Rest); +update_info2([], []) -> ok. + + +to_str(Value) when is_atom(Value) -> + atom_to_list(Value); +to_str({bytes, B}) -> + KB = B div 1024, + MB = KB div 1024, + if + MB > 10 -> integer_to_list(MB) ++ " mB"; + KB > 0 -> integer_to_list(KB) ++ " kB"; + true -> integer_to_list(B) ++ " B " + end; +to_str({time_ms, MS}) -> + S = MS div 1000, + Min = S div 60, + Hours = Min div 60, + Days = Hours div 24, + if + Days > 0 -> integer_to_list(Days) ++ " Days"; + Hours > 0 -> integer_to_list(Hours) ++ " Hours"; + Min > 0 -> integer_to_list(Min) ++ " Mins"; + true -> integer_to_list(S) ++ " Secs" + end; + +to_str({func, {F,A}}) when is_atom(F), is_integer(A) -> + lists:concat([F, "/", A]); +to_str({func, {F,'_'}}) when is_atom(F) -> + atom_to_list(F); +to_str({A, B}) when is_atom(A), is_atom(B) -> + lists:concat([A, ":", B]); +to_str({M,F,A}) when is_atom(M), is_atom(F), is_integer(A) -> + lists:concat([M, ":", F, "/", A]); +to_str(Value) when is_list(Value) -> + case lists:all(fun(X) -> is_integer(X) end, Value) of + true -> Value; + false -> + lists:foldl(fun(X, Acc) -> + to_str(X) ++ " " ++ Acc end, + "", Value) + end; +to_str(Port) when is_port(Port) -> + erlang:port_to_list(Port); +to_str(Pid) when is_pid(Pid) -> + pid_to_list(Pid); +to_str(No) when is_integer(No) -> + integer_to_list(No); +to_str(Term) -> + io_lib:format("~w", [Term]). + +create_menus(Menus, MenuBar, Type) -> + Add = fun({Tag, Ms}, Index) -> + create_menu(Tag, Ms, Index, MenuBar, Type) + end, + [{First, _}|_] = Menus, + OnMac = os:type() =:= {unix, darwin}, + Index = if Type =:= default -> 0; + First =:= "File" -> 0; + OnMac -> 0; + true -> 1 + end, + wx:foldl(Add, Index, Menus), + ok. + +create_menu("File", MenuItems, Index, MenuBar, Type) -> + OnMac = os:type() =:= {unix, darwin}, + if OnMac, Type =:= default -> + Index; + not OnMac, Type =:= plugin -> + MenuId = wxMenuBar:findMenu(MenuBar, "File"), + Menu = wxMenuBar:getMenu(MenuBar, MenuId), + lists:foldl(fun(Record, N) -> + create_menu_item(Record, Menu, N) + end, 0, MenuItems), + Index + 1; + true -> + Menu = wxMenu:new(), + lists:foldl(fun(Record, N) -> + create_menu_item(Record, Menu, N) + end, 0, MenuItems), + wxMenuBar:insert(MenuBar, Index, Menu, "File"), + Index+1 + end; +create_menu(Name, MenuItems, Index, MenuBar, _Type) -> + Menu = wxMenu:new(), + lists:foldl(fun(Record, N) -> + create_menu_item(Record, Menu, N) + end, 0, MenuItems), + wxMenuBar:insert(MenuBar, Index, Menu, Name), + Index+1. + +create_menu_item(#create_menu{id = ?wxID_HELP=Id}, Menu, Index) -> + wxMenu:insert(Menu, Index, Id), + Index+1; +create_menu_item(#create_menu{id = Id, text = Text, type = Type, check = Check}, Menu, Index) -> + case Type of + append -> + wxMenu:insert(Menu, Index, Id, [{text, Text}]); + check -> + wxMenu:insertCheckItem(Menu, Index, Id, Text), + wxMenu:check(Menu, Id, Check); + radio -> + wxMenu:insertRadioItem(Menu, Index, Id, Text), + wxMenu:check(Menu, Id, Check); + separator -> + wxMenu:insertSeparator(Menu, Index) + end, + Index+1; +create_menu_item(separator, Menu, Index) -> + wxMenu:insertSeparator(Menu, Index), + Index+1. + +create_attrs() -> + Font = wxSystemSettings:getFont(?wxSYS_DEFAULT_GUI_FONT), + Text = case wxSystemSettings:getColour(?wxSYS_COLOUR_LISTBOXTEXT) of + {255,255,255,_} -> {10,10,10}; %% Is white on Mac for some reason + Color -> Color + end, + #attrs{even = wxListItemAttr:new(Text, ?BG_EVEN, Font), + odd = wxListItemAttr:new(Text, ?BG_ODD, Font), + deleted = wxListItemAttr:new(?FG_DELETED, ?BG_DELETED, Font), + changed = wxListItemAttr:new(Text, ?BG_CHANGED, Font), + searched = wxListItemAttr:new(Text, ?BG_SEARCHED, Font) + }. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +get_box_info({Title, List}) when is_list(List) -> {Title, ?wxALIGN_LEFT, List}; +get_box_info({Title, left, List}) -> {Title, ?wxALIGN_LEFT, List}; +get_box_info({Title, right, List}) -> {Title, ?wxALIGN_RIGHT, List}. + +create_box(Panel, Data) -> + {Title, Align, Info} = get_box_info(Data), + Box = wxStaticBoxSizer:new(?wxHORIZONTAL, Panel, [{label, Title}]), + Left = wxBoxSizer:new(?wxVERTICAL), + Right = wxBoxSizer:new(?wxVERTICAL), + Expand = [{flag, ?wxEXPAND}], + ExpAlign = [{flag, Align}], + AddRow = fun({Desc, Value}) -> + wxSizer:add(Left, wxStaticText:new(Panel, ?wxID_ANY, Desc ++ ":"), Expand), + Field = wxStaticText:new(Panel, ?wxID_ANY, to_str(Value)), + wxSizer:add(Right, Field, ExpAlign), + Field + end, + InfoFields = [AddRow(Entry) || Entry <- Info], + wxSizer:add(Box, Left), + wxSizer:addSpacer(Box, 10), + wxSizer:add(Box, Right), + wxSizer:addSpacer(Box, 30), + {Box, InfoFields}. diff --git a/lib/observer/src/observer_pro_wx.erl b/lib/observer/src/observer_pro_wx.erl new file mode 100644 index 0000000000..cfc1c0665f --- /dev/null +++ b/lib/observer/src/observer_pro_wx.erl @@ -0,0 +1,608 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2011. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +-module(observer_pro_wx). + +-behaviour(wx_object). + +-export([start_link/2]). + +%% wx_object callbacks +-export([init/1, handle_info/2, terminate/2, code_change/3, handle_call/3, + handle_event/2, handle_cast/2]). + +-include_lib("wx/include/wx.hrl"). +-include("../include/etop.hrl"). +-include("observer_defs.hrl"). +-include("etop_defs.hrl"). + +%% Defines +-define(COL_PID, 0). +-define(COL_NAME, 1). +-define(COL_TIME, 2). +-define(COL_REDS, 3). +-define(COL_MEM, 4). +-define(COL_MSG, 5). +-define(COL_FUN, 6). + +-define(ID_KILL, 201). +-define(ID_PROC, 202). +-define(ID_REFRESH, 203). +-define(ID_REFRESH_INTERVAL, 204). +-define(ID_DUMP_TO_FILE, 205). +-define(ID_TRACEMENU, 206). +-define(ID_TRACE_ALL_MENU, 207). +-define(ID_TRACE_NEW_MENU, 208). +-define(ID_ACCUMULATE, 209). + +%% Records + +-record(sort, + { + sort_key=?COL_REDS, + sort_incr=false + }). + +-record(holder, {parent, + info, + sort=#sort{}, + accum=[], + attrs, + node, + backend_pid + }). + +-record(state, {parent, + grid, + panel, + popup_menu, + parent_notebook, + timer, + procinfo_menu_pids=[], + sel={[], []}, + holder}). + +start_link(Notebook, Parent) -> + wx_object:start_link(?MODULE, [Notebook, Parent], []). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +init([Notebook, Parent]) -> + Attrs = observer_lib:create_attrs(), + Self = self(), + Holder = spawn_link(fun() -> init_table_holder(Self, Attrs) end), + {ProPanel, State} = setup(Notebook, Parent, Holder), + {ProPanel, State#state{holder=Holder}}. + +setup(Notebook, Parent, Holder) -> + ProPanel = wxPanel:new(Notebook, []), + + Grid = create_list_box(ProPanel, Holder), + Sizer = wxBoxSizer:new(?wxVERTICAL), + wxSizer:add(Sizer, Grid, [{flag, ?wxEXPAND bor ?wxALL}, + {proportion, 1}, + {border,4}]), + + wxWindow:setSizer(ProPanel, Sizer), + + Popup = create_popup_menu(ProPanel), + + State = #state{parent=Parent, + grid=Grid, + panel=ProPanel, + popup_menu=Popup, + parent_notebook=Notebook, + holder=Holder, + timer={false, 10} + }, + {ProPanel, State}. + + +%% UI-creation + +create_pro_menu(Parent, Holder) -> + MenuEntries = [{"File", + [#create_menu{id=?ID_DUMP_TO_FILE, text="Dump to file"}]}, + {"View", + [#create_menu{id=?ID_ACCUMULATE, text="Accumulate", + type=check, + check=call(Holder, {get_accum, self()})}, + separator, + #create_menu{id=?ID_REFRESH, text="Refresh\tCtrl-R"}, + #create_menu{id=?ID_REFRESH_INTERVAL, text="Refresh Interval"}]}, + {"Trace", + [#create_menu{id=?ID_TRACEMENU, text="Trace selected processes"}, + #create_menu{id=?ID_TRACE_NEW_MENU, text="Trace new processes"} + %% , #create_menu{id=?ID_TRACE_ALL_MENU, text="Trace all processes"} + ]} + ], + observer_wx:create_menus(Parent, MenuEntries). + +create_popup_menu(ParentFrame) -> + MiniFrame = wxMiniFrame:new(ParentFrame, ?wxID_ANY, "Options", [{style, ?wxFRAME_FLOAT_ON_PARENT}]), + Panel = wxPanel:new(MiniFrame), + Sizer = wxBoxSizer:new(?wxVERTICAL), + TraceBtn = wxButton:new(Panel, ?ID_TRACEMENU, [{label, "Trace selected"}, + {style, ?wxNO_BORDER}]), + ProcBtn = wxButton:new(Panel, ?ID_PROC, [{label, "Process info"}, + {style, ?wxNO_BORDER}]), + KillBtn = wxButton:new(Panel, ?ID_KILL, [{label, "Kill process"}, + {style, ?wxNO_BORDER}]), + + wxButton:connect(TraceBtn, command_button_clicked), + wxButton:connect(ProcBtn, command_button_clicked), + wxButton:connect(KillBtn, command_button_clicked), + wxSizer:add(Sizer, TraceBtn, [{flag, ?wxEXPAND}, {proportion, 1}]), + wxSizer:add(Sizer, ProcBtn, [{flag, ?wxEXPAND}, {proportion, 1}]), + wxSizer:add(Sizer, KillBtn, [{flag, ?wxEXPAND}, {proportion, 1}]), + wxPanel:setSizer(Panel, Sizer), + wxSizer:setSizeHints(Sizer, MiniFrame), + MiniFrame. + +create_list_box(Panel, Holder) -> + Style = ?wxLC_REPORT bor ?wxLC_VIRTUAL bor ?wxLC_HRULES, + ListCtrl = wxListCtrl:new(Panel, [{style, Style}, + {onGetItemText, + fun(_, Row, Col) -> + call(Holder, {get_row, self(), Row, Col}) + end}, + {onGetItemAttr, + fun(_, Item) -> + call(Holder, {get_attr, self(), Item}) + end} + ]), + Li = wxListItem:new(), + AddListEntry = fun({Name, Align, DefSize}, Col) -> + wxListItem:setText(Li, Name), + wxListItem:setAlign(Li, Align), + wxListCtrl:insertColumn(ListCtrl, Col, Li), + wxListCtrl:setColumnWidth(ListCtrl, Col, DefSize), + Col + 1 + end, + ListItems = [{"Pid", ?wxLIST_FORMAT_CENTRE, 120}, + {"Name or Initial Func", ?wxLIST_FORMAT_LEFT, 200}, + {"Time", ?wxLIST_FORMAT_CENTRE, 50}, + {"Reds", ?wxLIST_FORMAT_RIGHT, 100}, + {"Memory", ?wxLIST_FORMAT_RIGHT, 100}, + {"MsgQ", ?wxLIST_FORMAT_RIGHT, 50}, + {"Current Function", ?wxLIST_FORMAT_LEFT, 200}], + lists:foldl(AddListEntry, 0, ListItems), + wxListItem:destroy(Li), + + wxListCtrl:setItemCount(ListCtrl, 1), + wxListCtrl:connect(ListCtrl, size, [{skip, true}]), + wxListCtrl:connect(ListCtrl, command_list_item_activated), + wxListCtrl:connect(ListCtrl, command_list_item_right_click), + wxListCtrl:connect(ListCtrl, command_list_col_click), + %% Use focused instead of selected, selected doesn't generate events + %% for all multiple selections on Linux + wxListCtrl:connect(ListCtrl, command_list_item_focused), + ListCtrl. + +dump_to_file(Parent, FileName, Holder) -> + case file:open(FileName, [write]) of + {ok, Fd} -> + %% Holder closes the file when it's done + Holder ! {dump, Fd}; + {error, Reason} -> + FailMsg = file:format_error(Reason), + MD = wxMessageDialog:new(Parent, FailMsg), + wxDialog:showModal(MD), + wxDialog:destroy(MD) + end. + +start_procinfo(undefined, _Frame, Opened) -> + Opened; +start_procinfo(Pid, Frame, Opened) -> + case lists:member(Pid, Opened) of + true -> + Opened; + false -> + observer_procinfo:start(Pid, Frame, self()), + [Pid | Opened] + end. + +call(Holder, What) -> + Ref = erlang:monitor(process, Holder), + Holder ! What, + receive + {'DOWN', Ref, _, _, _} -> ""; + {Holder, Res} -> + erlang:demonitor(Ref), + Res + after 2000 -> + io:format("Hanging call ~p~n",[What]), + "" + end. + +%%%%%%%%%%%%%%%%%%%%%%% Callbacks %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +handle_info({holder_updated, Count}, State0=#state{grid=Grid}) -> + State = update_selection(State0), + + wxListCtrl:setItemCount(Grid, Count), + wxListCtrl:refreshItems(Grid, 0, Count-1), + + {noreply, State}; + +handle_info(refresh_interval, #state{holder=Holder}=State) -> + Holder ! refresh, + {noreply, State}; + +handle_info({procinfo_menu_closed, Pid}, + #state{procinfo_menu_pids=Opened}=State) -> + NewPids = lists:delete(Pid, Opened), + {noreply, State#state{procinfo_menu_pids=NewPids}}; + +handle_info({active, Node}, + #state{holder=Holder, timer=Timer, parent=Parent}=State) -> + create_pro_menu(Parent, Holder), + Holder ! {change_node, Node}, + {noreply, State#state{timer=observer_lib:start_timer(Timer)}}; + +handle_info(not_active, #state{timer=Timer0}=State) -> + Timer = observer_lib:stop_timer(Timer0), + {noreply, State#state{timer=Timer}}; + +handle_info({node, Node}, #state{holder=Holder}=State) -> + Holder ! {change_node, Node}, + {noreply, State}; + +handle_info(Info, State) -> + io:format("~p:~p, Unexpected info: ~p~n", [?MODULE, ?LINE, Info]), + {noreply, State}. + +terminate(_Reason, #state{holder=Holder}) -> + Holder ! stop, + etop:stop(), + ok. + +code_change(_, _, State) -> + {stop, not_yet_implemented, State}. + + +handle_call(Msg, _From, State) -> + io:format("~p:~p: Unhandled call ~p~n",[?MODULE, ?LINE, Msg]), + {reply, ok, State}. + + +handle_cast(Msg, State) -> + io:format("~p:~p: Unhandled cast ~p~n", [?MODULE, ?LINE, Msg]), + {noreply, State}. + +%%%%%%%%%%%%%%%%%%%%LOOP%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +handle_event(#wx{id=?ID_DUMP_TO_FILE}, #state{panel=Panel, holder=Holder}=State) -> + FD = wxFileDialog:new(Panel, + [{style,?wxFD_SAVE bor ?wxFD_OVERWRITE_PROMPT}]), + case wxFileDialog:showModal(FD) of + ?wxID_OK -> + Path = wxFileDialog:getPath(FD), + wxDialog:destroy(FD), + dump_to_file(Panel, Path, Holder); + _ -> + wxDialog:destroy(FD) + end, + {noreply, State}; + +handle_event(#wx{id=?ID_ACCUMULATE, + event=#wxCommand{type=command_menu_selected, commandInt=CmdInt}}, + #state{holder=Holder}=State) -> + Holder ! {accum, CmdInt =:= 1}, + {noreply, State}; + +handle_event(#wx{id=?ID_REFRESH, event=#wxCommand{type=command_menu_selected}}, + #state{holder=Holder}=State) -> + Holder ! refresh, + {noreply, State}; + +handle_event(#wx{id=?ID_REFRESH_INTERVAL}, + #state{panel=Panel, timer=Timer0}=State) -> + Timer = observer_lib:interval_dialog(Panel, Timer0, 1, 5*60), + {noreply, State#state{timer=Timer}}; + +handle_event(#wx{id=?ID_KILL}, + #state{popup_menu=Pop,sel={[_|Ids], [ToKill|Pids]}}=State) -> + wxWindow:show(Pop, [{show, false}]), + exit(ToKill, kill), + {noreply, State#state{sel={Ids,Pids}}}; + + +handle_event(#wx{id = ?ID_PROC}, + #state{panel=Panel, + popup_menu=Pop, + sel={_, [Pid|_]}, + procinfo_menu_pids=Opened}=State) -> + wxWindow:show(Pop, [{show, false}]), + Opened2 = start_procinfo(Pid, Panel, Opened), + {noreply, State#state{procinfo_menu_pids=Opened2}}; + +handle_event(#wx{id = ?ID_TRACEMENU}, + #state{popup_menu=Pop, sel={_, Pids}, panel=Panel}=State) -> + wxWindow:show(Pop, [{show, false}]), + case Pids of + [] -> + observer_wx:create_txt_dialog(Panel, "No selected processes", "Tracer", ?wxICON_EXCLAMATION), + {noreply, State}; + Pids -> + observer_trace_wx:add_processes(observer_wx:get_tracer(), Pids), + {noreply, State} + end; + +handle_event(#wx{id=?ID_TRACE_NEW_MENU, event=#wxCommand{type=command_menu_selected}}, State) -> + observer_trace_wx:add_processes(observer_wx:get_tracer(), [new]), + {noreply, State}; + +handle_event(#wx{event=#wxSize{size={W,_}}}, + #state{grid=Grid}=State) -> + wx:batch(fun() -> + Cols = wxListCtrl:getColumnCount(Grid), + Last = lists:foldl(fun(I, Last) -> + Last - wxListCtrl:getColumnWidth(Grid, I) + end, W-Cols*3-?LCTRL_WDECR, lists:seq(0, Cols - 2)), + Size = max(200, Last), + %% io:format("Width ~p ~p => ~p~n",[W, Last, Size]), + wxListCtrl:setColumnWidth(Grid, Cols-1, Size) + end), + {noreply, State}; + +handle_event(#wx{event=#wxList{type=command_list_item_right_click, + itemIndex=Row}}, + #state{popup_menu=Popup, + holder=Holder}=State) -> + + case call(Holder, {get_row, self(), Row, pid}) of + {error, undefined} -> + wxWindow:show(Popup, [{show, false}]), + undefined; + {ok, _} -> + wxWindow:move(Popup, wx_misc:getMousePosition()), + wxWindow:show(Popup) + end, + {noreply, State}; + +handle_event(#wx{event=#wxList{type=command_list_item_focused, + itemIndex=Row}}, + #state{grid=Grid,popup_menu=Pop,holder=Holder} = State) -> + case Row >= 0 of + true -> + wxWindow:show(Pop, [{show, false}]), + SelIds = [Row|lists:delete(Row, get_selected_items(Grid))], + Pids = call(Holder, {get_pids, self(), SelIds}), + %% io:format("Focused ~p -> ~p~n",[State#state.sel, {SelIds, Pids}]), + {noreply, State#state{sel={SelIds, Pids}}}; + false -> + %% io:format("Focused -1~n",[]), + {noreply, State} + end; + +handle_event(#wx{event=#wxList{type=command_list_col_click, col=Col}}, + #state{holder=Holder}=State) -> + Holder ! {change_sort, Col}, + {noreply, State}; + +handle_event(#wx{event=#wxList{type=command_list_item_activated}}, + #state{panel=Panel, procinfo_menu_pids=Opened, + sel={_, [Pid|_]}}=State) + when Pid =/= undefined -> + Opened2 = start_procinfo(Pid, Panel, Opened), + {noreply, State#state{procinfo_menu_pids=Opened2}}; + +handle_event(Event, State) -> + io:format("~p:~p: handle event ~p\n", [?MODULE, ?LINE, Event]), + {noreply, State}. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +update_selection(State=#state{holder=Holder, grid=Grid, + sel={SelIds0, SelPids0}}) -> + Sel = {SelIds,_SelPids} = call(Holder, {get_rows_from_pids, self(), SelPids0}), + set_focus(SelIds0, SelIds, Grid), + case SelIds =:= SelIds0 of + true -> ok; + false -> + wx:batch(fun() -> + [wxListCtrl:setItemState(Grid, I, 0, ?wxLIST_STATE_SELECTED) || + I <- SelIds0], + [wxListCtrl:setItemState(Grid, I, 16#FFFF, ?wxLIST_STATE_SELECTED) || + I <- SelIds] + end) + end, + %%io:format("Update ~p -> ~p~n",[{SelIds0, SelPids0}, Sel]), + State#state{sel=Sel}. + +get_selected_items(Grid) -> + get_selected_items(Grid, -1, []). + +get_selected_items(Grid, Index, ItemAcc) -> + Item = wxListCtrl:getNextItem(Grid, Index, [{geometry, ?wxLIST_NEXT_ALL}, + {state, ?wxLIST_STATE_SELECTED}]), + case Item of + -1 -> + lists:reverse(ItemAcc); + _ -> + get_selected_items(Grid, Item, [Item | ItemAcc]) + end. + +set_focus([], [], _Grid) -> ok; +set_focus([Same|_], [Same|_], _Grid) -> ok; +set_focus([], [New|_], Grid) -> + wxListCtrl:setItemState(Grid, New, 16#FFFF, ?wxLIST_STATE_FOCUSED); +set_focus([Old|_], [], Grid) -> + wxListCtrl:setItemState(Grid, Old, 0, ?wxLIST_STATE_FOCUSED); +set_focus([Old|_], [New|_], Grid) -> + wxListCtrl:setItemState(Grid, Old, 0, ?wxLIST_STATE_FOCUSED), + wxListCtrl:setItemState(Grid, New, 16#FFFF, ?wxLIST_STATE_FOCUSED). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%TABLE HOLDER%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +init_table_holder(Parent, Attrs) -> + Backend = spawn_link(node(), observer_backend,etop_collect,[self()]), + table_holder(#holder{parent=Parent, + info=#etop_info{procinfo=[]}, + node=node(), + backend_pid=Backend, + attrs=Attrs + }). + +table_holder(#holder{info=#etop_info{procinfo=Info}, attrs=Attrs, + node=Node, backend_pid=Backend}=S0) -> + receive + {get_row, From, Row, Col} -> + get_row(From, Row, Col, Info), + table_holder(S0); + {get_attr, From, Row} -> + get_attr(From, Row, Attrs), + table_holder(S0); + {Backend, EtopInfo=#etop_info{}} -> + State = handle_update(EtopInfo, S0), + table_holder(State#holder{backend_pid=undefined}); + refresh when is_pid(Backend)-> + table_holder(S0); %% Already updating + refresh -> + Pid = spawn_link(Node,observer_backend,etop_collect,[self()]), + table_holder(S0#holder{backend_pid=Pid}); + {change_sort, Col} -> + State = change_sort(Col, S0), + table_holder(State); + {get_pids, From, Indices} -> + get_pids(From, Indices, Info), + table_holder(S0); + {get_rows_from_pids, From, Pids} -> + get_rows_from_pids(From, Pids, Info), + table_holder(S0); + + {get_node, From} -> + From ! {self(), Node}, + table_holder(S0); + {change_node, NewNode} -> + case Node == NewNode of + true -> + table_holder(S0); + false -> + self() ! refresh, + table_holder(S0#holder{node=NewNode}) + end; + {accum, Bool} -> + table_holder(change_accum(Bool,S0)); + {get_accum, From} -> + From ! {self(), S0#holder.accum == true}, + table_holder(S0); + {dump, Fd} -> + etop_txt:do_update(Fd, S0#holder.info, #opts{node=Node}), + file:close(Fd), + table_holder(S0); + stop -> + ok; + What -> + io:format("Table holder got ~p~n",[What]), + table_holder(S0) + end. + +change_sort(Col, S0=#holder{parent=Parent, info=EI=#etop_info{procinfo=Data}, sort=Sort0}) -> + {Sort, ProcInfo}=sort(Col, Sort0, Data), + Parent ! {holder_updated, length(Data)}, + S0#holder{info=EI#etop_info{procinfo=ProcInfo}, sort=Sort}. + +change_accum(true, S0) -> + S0#holder{accum=true}; +change_accum(false, S0=#holder{info=#etop_info{procinfo=Info}}) -> + self() ! refresh, + S0#holder{accum=lists:sort(Info)}. + +handle_update(EI=#etop_info{procinfo=ProcInfo0}, + S0=#holder{parent=Parent, sort=Sort=#sort{sort_key=KeyField}}) -> + {ProcInfo1, S1} = accum(ProcInfo0, S0), + {_SO, ProcInfo} = sort(KeyField, Sort#sort{sort_key=undefined}, ProcInfo1), + Parent ! {holder_updated, length(ProcInfo)}, + S1#holder{info=EI#etop_info{procinfo=ProcInfo}}. + +accum(ProcInfo, State=#holder{accum=true}) -> + {ProcInfo, State}; +accum(ProcInfo0, State=#holder{accum=Previous}) -> + ProcInfo = lists:sort(ProcInfo0), + {accum2(ProcInfo,Previous,[]), State#holder{accum=ProcInfo}}. + +accum2([PI=#etop_proc_info{pid=Pid, reds=Reds, runtime=RT}|PIs], + [#etop_proc_info{pid=Pid, reds=OldReds, runtime=OldRT}|Old], Acc) -> + accum2(PIs, Old, [PI#etop_proc_info{reds=Reds-OldReds, runtime=RT-OldRT}|Acc]); +accum2(PIs=[#etop_proc_info{pid=Pid}|_], [#etop_proc_info{pid=OldPid}|Old], Acc) + when Pid > OldPid -> + accum2(PIs, Old, Acc); +accum2([PI|PIs], Old, Acc) -> + accum2(PIs, Old, [PI|Acc]); +accum2([], _, Acc) -> Acc. + +sort(Col, Opt=#sort{sort_key=Col, sort_incr=Bool}, Table) -> + {Opt#sort{sort_incr=not Bool}, lists:reverse(Table)}; +sort(Col, S=#sort{sort_incr=true}, Table) -> + {S#sort{sort_key=Col}, lists:keysort(col_to_element(Col), Table)}; +sort(Col, S=#sort{sort_incr=false}, Table) -> + {S#sort{sort_key=Col}, lists:reverse(lists:keysort(col_to_element(Col), Table))}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +get_procinfo_data(Col, Info) -> + element(col_to_element(Col), Info). +col_to_element(?COL_PID) -> #etop_proc_info.pid; +col_to_element(?COL_NAME) -> #etop_proc_info.name; +col_to_element(?COL_MEM) -> #etop_proc_info.mem; +col_to_element(?COL_TIME) -> #etop_proc_info.runtime; +col_to_element(?COL_REDS) -> #etop_proc_info.reds; +col_to_element(?COL_FUN) -> #etop_proc_info.cf; +col_to_element(?COL_MSG) -> #etop_proc_info.mq. + +get_pids(From, Indices, ProcInfo) -> + Processes = [(lists:nth(I+1, ProcInfo))#etop_proc_info.pid || I <- Indices], + From ! {self(), Processes}. + +get_row(From, Row, pid, Info) -> + Pid = case Row =:= -1 of + true -> {error, undefined}; + false -> {ok, get_procinfo_data(?COL_PID, lists:nth(Row+1, Info))} + end, + From ! {self(), Pid}; +get_row(From, Row, Col, Info) -> + Data = case Row+1 > length(Info) of + true -> + ""; + false -> + ProcInfo = lists:nth(Row+1, Info), + get_procinfo_data(Col, ProcInfo) + end, + From ! {self(), observer_lib:to_str(Data)}. + +get_rows_from_pids(From, Pids0, Info) -> + Res = lists:foldl(fun(Pid, Data = {Ids, Pids}) -> + case index(Pid, Info, 0) of + false -> Data; + Index -> {[Index|Ids], [Pid|Pids]} + end + end, {[],[]}, Pids0), + From ! {self(), Res}. + +get_attr(From, Row, Attrs) -> + Attribute = case Row rem 2 =:= 0 of + true -> Attrs#attrs.even; + false -> Attrs#attrs.odd + end, + From ! {self(), Attribute}. + +index(Pid, [#etop_proc_info{pid=Pid}|_], Index) -> Index; +index(Pid, [_|PI], Index) -> index(Pid, PI, Index+1); +index(_, _, _) -> false. diff --git a/lib/observer/src/observer_procinfo.erl b/lib/observer/src/observer_procinfo.erl new file mode 100644 index 0000000000..127599a39e --- /dev/null +++ b/lib/observer/src/observer_procinfo.erl @@ -0,0 +1,274 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2011. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% + +-module(observer_procinfo). + +-behaviour(wx_object). + +-export([start/3]). + +-export([init/1, handle_event/2, handle_cast/2, terminate/2, code_change/3, + handle_call/3, handle_info/2]). + +-include_lib("wx/include/wx.hrl"). +-include("observer_defs.hrl"). + +-define(REFRESH, 601). +-define(SELECT_ALL, 603). +-define(ID_NOTEBOOK, 604). + +-record(state, {parent, + frame, + pid, + pages=[] + }). + +-record(worker, {panel, callback}). + +start(Process, ParentFrame, Parent) -> + wx_object:start(?MODULE, [Process, ParentFrame, Parent], []). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +init([Pid, ParentFrame, Parent]) -> + try + Title=case observer_wx:try_rpc(node(Pid), erlang, process_info, [Pid, registered_name]) of + [] -> io_lib:format("~p",[Pid]); + {registered_name, Registered} -> atom_to_list(Registered) + end, + Frame=wxFrame:new(ParentFrame, ?wxID_ANY, [atom_to_list(node(Pid)), $:, Title], + [{style, ?wxDEFAULT_FRAME_STYLE}, {size, {800,700}}]), + MenuBar = wxMenuBar:new(), + create_menus(MenuBar), + wxFrame:setMenuBar(Frame, MenuBar), + + Notebook = wxNotebook:new(Frame, ?ID_NOTEBOOK, [{style, ?wxBK_DEFAULT}]), + + ProcessPage = init_panel(Notebook, "Process Information", Pid, fun init_process_page/2), + MessagePage = init_panel(Notebook, "Messages", Pid, fun init_message_page/2), + DictPage = init_panel(Notebook, "Dictionary", Pid, fun init_dict_page/2), + StackPage = init_panel(Notebook, "Stack Trace", Pid, fun init_stack_page/2), + + wxFrame:connect(Frame, close_window), + wxMenu:connect(Frame, command_menu_selected), + %% wxNotebook:connect(Notebook, command_notebook_page_changed, [{skip,true}]), + wxFrame:show(Frame), + {Frame, #state{parent=Parent, + pid=Pid, + frame=Frame, + pages=[ProcessPage,MessagePage,DictPage,StackPage] + }} + catch error:{badrpc, _} -> + observer_wx:return_to_localnode(ParentFrame, node(Pid)), + {stop, badrpc, #state{parent=Parent, pid=Pid}}; + Error:Reason -> + io:format("~p:~p: ~p ~p~n ~p~n", + [?MODULE, ?LINE, Error, Reason, erlang:get_stacktrace()]) + end. + +init_panel(Notebook, Str, Pid, Fun) -> + Panel = wxPanel:new(Notebook), + Sizer = wxBoxSizer:new(?wxHORIZONTAL), + {Window,Callback} = Fun(Panel, Pid), + wxSizer:add(Sizer, Window, [{flag, ?wxEXPAND bor ?wxALL}, {proportion, 1}, {border, 5}]), + wxPanel:setSizer(Panel, Sizer), + true = wxNotebook:addPage(Notebook, Panel, Str), + #worker{panel=Panel, callback=Callback}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Callbacks%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +handle_event(#wx{event=#wxClose{type=close_window}}, State) -> + {stop, shutdown, State}; + +handle_event(#wx{id=?wxID_CLOSE, event=#wxCommand{type=command_menu_selected}}, State) -> + {stop, shutdown, State}; + +handle_event(#wx{id=?REFRESH}, #state{pages=Pages}=State) -> + [(W#worker.callback)() || W <- Pages], + {noreply, State}; + +handle_event(Event, State) -> + io:format("~p: ~p, Handle event: ~p~n", [?MODULE, ?LINE, Event]), + {noreply, State}. + +handle_info(Info, State) -> + io:format("~p: ~p, Handle info: ~p~n", [?MODULE, ?LINE, Info]), + {noreply, State}. + +handle_call(Call, _From, State) -> + io:format("~p ~p: Got call ~p~n",[?MODULE, ?LINE, Call]), + {reply, ok, State}. + +handle_cast(Cast, State) -> + io:format("~p ~p: Got cast ~p~n", [?MODULE, ?LINE, Cast]), + {noreply, State}. + +terminate(_Reason, #state{parent=Parent,pid=Pid,frame=Frame}) -> + Parent ! {procinfo_menu_closed, Pid}, + case Frame of + undefined -> ok; + _ -> wxFrame:destroy(Frame) + end, + ok. + +code_change(_, _, State) -> + {stop, not_yet_implemented, State}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +init_process_page(Panel, Pid) -> + Fields = process_info_fields(Pid), + {FPanel, _, UpFields} = observer_lib:display_info(Panel, Fields), + {FPanel, fun() -> observer_lib:update_info(UpFields, process_info_fields(Pid)) end}. + +init_text_page(Parent) -> + Style = ?wxTE_MULTILINE bor ?wxTE_RICH2 bor ?wxTE_READONLY, + Text = wxTextCtrl:new(Parent, ?wxID_ANY, [{style, Style}]), + Font = observer_wx:get_attrib({font, fixed}), + Attr = wxTextAttr:new(?wxBLACK, [{font, Font}]), + true = wxTextCtrl:setDefaultStyle(Text, Attr), + wxTextAttr:destroy(Attr), + Text. + +init_message_page(Parent, Pid) -> + Text = init_text_page(Parent), + Format = fun(Message, Number) -> + {io_lib:format("~-4.w ~p~n", [Number, Message]), + Number+1} + end, + Update = fun() -> + {messages,RawMessages} = + observer_wx:try_rpc(node(Pid), erlang, process_info, [Pid, messages]), + {Messages,_} = lists:mapfoldl(Format, 1, RawMessages), + Last = wxTextCtrl:getLastPosition(Text), + wxTextCtrl:remove(Text, 0, Last), + case Messages =:= [] of + true -> + wxTextCtrl:writeText(Text, "No messages"); + false -> + wxTextCtrl:writeText(Text, Messages) + end + end, + Update(), + {Text, Update}. + +init_dict_page(Parent, Pid) -> + Text = init_text_page(Parent), + Update = fun() -> + {dictionary,RawDict} = + observer_wx:try_rpc(node(Pid), erlang, process_info, [Pid, dictionary]), + Dict = [io_lib:format("~-20.w ~p~n", [K, V]) || {K, V} <- RawDict], + Last = wxTextCtrl:getLastPosition(Text), + wxTextCtrl:remove(Text, 0, Last), + wxTextCtrl:writeText(Text, Dict) + end, + Update(), + {Text, Update}. + +init_stack_page(Parent, Pid) -> + Text = init_text_page(Parent), + Format = fun({Mod, Fun, Arg, Info}) -> + Str = io_lib:format("~w:~w/~w", [Mod,Fun,Arg]), + case Info of + [{file,File},{line,Line}] -> + io_lib:format("~-45.s ~s:~w~n", [Str,File,Line]); + _ -> + [Str,$\n] + end + end, + Update = fun() -> + {current_stacktrace,RawBt} = + observer_wx:try_rpc(node(Pid), erlang, process_info, + [Pid, current_stacktrace]), + Last = wxTextCtrl:getLastPosition(Text), + wxTextCtrl:remove(Text, 0, Last), + [wxTextCtrl:writeText(Text, Format(Entry)) || Entry <- RawBt] + end, + Update(), + {Text, Update}. + +create_menus(MenuBar) -> + Menus = [{"File", [#create_menu{id=?wxID_CLOSE, text="Close"}]}, + {"View", [#create_menu{id=?REFRESH, text="Refresh\tCtrl-R"}]}], + observer_lib:create_menus(Menus, MenuBar, new_window). + +process_info_fields(Pid) -> + RawInfo = observer_wx:try_rpc(node(Pid), erlang, process_info, [Pid, item_list()]), + Struct = [{"Overview", + [{"Initial Call", initial_call}, + {"Current Function", current_function}, + {"Registered Name", registered_name}, + {"Status", status}, + {"Message Queue Len",message_queue_len}, + {"Priority", priority}, + {"Trap Exit", trap_exit}, + {"Reductions", reductions}, + {"Binary", binary}, + {"Last Calls", last_calls}, + {"Catch Level", catchlevel}, + {"Trace", trace}, + {"Suspending", suspending}, + {"Sequential Trace Token", sequential_trace_token}, + {"Error Handler", error_handler}]}, + {"Connections", + [{"Group Leader", group_leader}, + {"Links", links}, + {"Monitors", monitors}, + {"Monitored by", monitored_by}]}, + {"Memory and Garbage Collection", right, + [{"Memory", {bytes, memory}}, + {"Stack and Heaps", {bytes, total_heap_size}}, + {"Heap Size", {bytes, heap_size}}, + {"Stack Size", {bytes, stack_size}}, + {"GC Min Heap Size", {bytes, get_gc_info(min_heap_size)}}, + {"GC FullSweep After", get_gc_info(fullsweep_after)} + ]}], + observer_lib:fill_info(Struct, RawInfo). + +item_list() -> + [ %% backtrace, + binary, + catchlevel, + current_function, + %% dictionary, + error_handler, + garbage_collection, + group_leader, + heap_size, + initial_call, + last_calls, + links, + memory, + message_queue_len, + %% messages, + monitored_by, + monitors, + priority, + reductions, + registered_name, + sequential_trace_token, + stack_size, + status, + suspending, + total_heap_size, + trace, + trap_exit]. + +get_gc_info(Arg) -> + fun(Data) -> + GC = proplists:get_value(garbage_collection, Data), + proplists:get_value(Arg, GC) + end. diff --git a/lib/observer/src/observer_sys_wx.erl b/lib/observer/src/observer_sys_wx.erl new file mode 100644 index 0000000000..ddedcf3829 --- /dev/null +++ b/lib/observer/src/observer_sys_wx.erl @@ -0,0 +1,223 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2011. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +-module(observer_sys_wx). + +-behaviour(wx_object). + +-export([start_link/2]). +%% wx_object callbacks +-export([init/1, handle_info/2, terminate/2, code_change/3, handle_call/3, + handle_event/2, handle_cast/2]). + +-export([sys_info/0]). + +-include_lib("wx/include/wx.hrl"). +-include("observer_defs.hrl"). + +-define(ID_REFRESH, 101). +-define(ID_REFRESH_INTERVAL, 102). + +%% Records +-record(sys_wx_state, + {parent, + node, + parent_notebook, + panel, sizer, + menubar, + fields, + timer}). + +start_link(Notebook, Parent) -> + wx_object:start_link(?MODULE, [Notebook, Parent], []). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +init([Notebook, Parent]) -> + SysInfo = sys_info(), + {Info, Stat} = info_fields(), + Panel = wxPanel:new(Notebook), + Sizer = wxBoxSizer:new(?wxHORIZONTAL), + {FPanel0, _FSizer0, Fields0} = + observer_lib:display_info(Panel, observer_lib:fill_info(Info, SysInfo)), + {FPanel1, _FSizer1, Fields1} = + observer_lib:display_info(Panel, observer_lib:fill_info(Stat, SysInfo)), + wxSizer:add(Sizer, FPanel0, [{flag, ?wxEXPAND bor ?wxTOP bor ?wxBOTTOM bor ?wxLEFT}, + {proportion, 1}, {border, 5}]), + wxSizer:add(Sizer, FPanel1, [{flag, ?wxEXPAND bor ?wxTOP bor ?wxBOTTOM bor ?wxRIGHT}, + {proportion, 1}, {border, 5}]), + wxPanel:setSizer(Panel, Sizer), + Timer = observer_lib:start_timer(10), + {Panel, #sys_wx_state{parent=Parent, + parent_notebook=Notebook, + panel=Panel, sizer=Sizer, + timer=Timer, fields=Fields0 ++ Fields1}}. + +create_sys_menu(Parent) -> + View = {"View", [#create_menu{id = ?ID_REFRESH, text = "Refresh\tCtrl-R"}, + #create_menu{id = ?ID_REFRESH_INTERVAL, text = "Refresh interval"}]}, + observer_wx:create_menus(Parent, [View]). + +update_syspage(#sys_wx_state{node = Node, fields=Fields, sizer=Sizer}) -> + SysInfo = observer_wx:try_rpc(Node, ?MODULE, sys_info, []), + {Info, Stat} = info_fields(), + observer_lib:update_info(Fields, observer_lib:fill_info(Info, SysInfo) ++ + observer_lib:fill_info(Stat, SysInfo)), + wxSizer:layout(Sizer). + +info_fields() -> + Info = [{"System and Architecture", + [{"System Version", otp_release}, + {"Erts Version", version}, + {"Compiled for", system_architecture}, + {"Emulator Wordsize", wordsize_external}, + {"Process Wordsize", wordsize_internal}, + {"Smp Support", smp_support}, + {"Thread Support", threads}, + {"Async thread pool size", thread_pool_size} + ]}, + {"CPU's and Threads", + [{"System Logical CPU's", logical_processors}, + {"Erlang Logical CPU's", logical_processors_online}, + {"Used Logical CPU's", logical_processors_available} + ]} + ], + Stat = [{"Memory Usage", right, + [{"Total", total}, + {"Processes", processes}, + {"Atoms", atom}, + {"Binaries", binary}, + {"Code", code}, + {"Ets", ets} + ]}, + {"Statistics", right, + [{"Up time", uptime}, + {"Max Processes", process_limit}, + {"Processes", process_count}, + {"Run Queue", run_queue}, + {"IO Input", io_input}, + {"IO Output", io_output} + ]} + ], + {Info, Stat}. + +%%%%%%%%%%%%%%%%%%%%%%% Callbacks %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +handle_info(refresh_interval, #sys_wx_state{panel = Panel, + node = Node} = State) -> + try + update_syspage(State) + catch error:{badrpc, _} -> + observer_wx:return_to_localnode(Panel, Node) + end, + {noreply, State}; + +handle_info({node, Node}, #sys_wx_state{panel = Panel} = State) -> + UpdState = State#sys_wx_state{node = Node}, + try + update_syspage(UpdState), + {noreply, UpdState} + catch error:{badrpc, _} -> + observer_wx:return_to_localnode(Panel, Node), + {noreply, State} + end; + +handle_info({active, Node}, #sys_wx_state{parent = Parent, panel = Panel, + timer = Timer} = State) -> + UpdState = State#sys_wx_state{node = Node}, + create_sys_menu(Parent), + try + update_syspage(UpdState), + {noreply, UpdState#sys_wx_state{timer=observer_lib:start_timer(Timer)}} + catch error:{badrpc, _} -> + observer_wx:return_to_localnode(Panel, Node), + {noreply, State} + end; + + +handle_info(not_active, #sys_wx_state{timer = Timer} = State) -> + {noreply, State#sys_wx_state{timer = observer_lib:stop_timer(Timer)}}; + +handle_info(Info, State) -> + io:format("~p:~p: Unhandled info: ~p~n", [?MODULE, ?LINE, Info]), + {noreply, State}. + +terminate(_Reason, _State) -> + ok. + +code_change(_, _, State) -> + {stop, not_yet_implemented, State}. + +handle_call(Msg, _From, State) -> + io:format("~p~p: Unhandled Call ~p~n",[?MODULE, ?LINE, Msg]), + {reply, ok, State}. + +handle_cast(Msg, State) -> + io:format("~p~p: Unhandled cast ~p~n",[?MODULE, ?LINE, Msg]), + {noreply, State}. + +handle_event(#wx{id = ?ID_REFRESH, event = #wxCommand{type = command_menu_selected}}, + #sys_wx_state{node = Node, panel = Panel} = State) -> + try + update_syspage(State) + catch error:{badrpc, _} -> + observer_wx:return_to_localnode(Panel, Node) + end, + {noreply, State}; + +handle_event(#wx{id = ?ID_REFRESH_INTERVAL, + event = #wxCommand{type = command_menu_selected}}, + #sys_wx_state{timer = Timer0, parent_notebook = Notebook} = State) -> + Timer = observer_lib:interval_dialog(Notebook, Timer0, 1, 5*60), + {noreply, State#sys_wx_state{timer=Timer}}; + +handle_event(Event, State) -> + io:format("~p:~p: Unhandled event ~p\n", [?MODULE,?LINE,Event]), + {noreply, State}. + + +sys_info() -> + {{_,Input},{_,Output}} = erlang:statistics(io), + [{process_count, erlang:system_info(process_count)}, + {process_limit, erlang:system_info(process_limit)}, + {uptime, {time_ms, element(1, erlang:statistics(wall_clock))}}, + {run_queue, erlang:statistics(run_queue)}, + {io_input, {bytes, Input}}, + {io_output, {bytes, Output}}, + {logical_processors, erlang:system_info(logical_processors)}, + {logical_processors_available, erlang:system_info(logical_processors_available)}, + {logical_processors_online, erlang:system_info(logical_processors_online)}, + + {total, {bytes, erlang:memory(total)}}, + %%{processes_used, erlang:memory(processes_used)}, + {processes, {bytes, erlang:memory(processes)}}, + %%{atom_used, erlang:memory(atom_used)}, + {atom, {bytes, erlang:memory(atom)}}, + {binary, {bytes, erlang:memory(binary)}}, + {code, {bytes, erlang:memory(code)}}, + {ets, {bytes, erlang:memory(ets)}}, + + {otp_release, erlang:system_info(otp_release)}, + {version, erlang:system_info(version)}, + {system_architecture, erlang:system_info(system_architecture)}, + {kernel_poll, erlang:system_info(kernel_poll)}, + {smp_support, erlang:system_info(smp_support)}, + {threads, erlang:system_info(threads)}, + {thread_pool_size, erlang:system_info(thread_pool_size)}, + {wordsize_internal, erlang:system_info({wordsize, internal})}, + {wordsize_external, erlang:system_info({wordsize, external})} + ]. diff --git a/lib/observer/src/observer_trace_wx.erl b/lib/observer/src/observer_trace_wx.erl new file mode 100644 index 0000000000..0ab7db121b --- /dev/null +++ b/lib/observer/src/observer_trace_wx.erl @@ -0,0 +1,628 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2011. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% + +-module(observer_trace_wx). + +-export([start_link/2, add_processes/2]). +-export([init/1, handle_info/2, terminate/2, code_change/3, handle_call/3, + handle_event/2, handle_cast/2]). + +-behaviour(wx_object). + +-include_lib("wx/include/wx.hrl"). +-include("observer_defs.hrl"). + +-define(OPTIONS, 301). +-define(SAVE_BUFFER, 302). +-define(CLOSE, 303). +-define(CLEAR, 304). +-define(SAVE_TRACEOPTS, 305). +-define(LOAD_TRACEOPTS, 306). +-define(TOGGLE_TRACE, 307). +-define(ADD_NEW, 308). +-define(ADD_TP, 309). +-define(PROCESSES, 350). +-define(MODULES, 351). +-define(FUNCTIONS, 352). +-define(TRACERWIN, 353). + +-record(state, + {parent, + panel, + p_view, + m_view, + f_view, + nodes = [], + toggle_button, + tpids = [], %% #tpid + def_trace_opts = [], + tpatterns = dict:new(), % Key =:= Module::atom, Value =:= {M, F, A, MatchSpec} + match_specs = []}). % [ #match_spec{} ] + +-record(tpid, {pid, opts}). + +start_link(Notebook, ParentPid) -> + wx_object:start_link(?MODULE, [Notebook, ParentPid], []). + +add_processes(Tracer, Pids) when is_list(Pids) -> + wx_object:cast(Tracer, {add_processes, Pids}). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +init([Notebook, ParentPid]) -> + wx:batch(fun() -> create_window(Notebook, ParentPid) end). + +create_window(Notebook, ParentPid) -> + %% Create the window + Panel = wxPanel:new(Notebook, [{size, wxWindow:getClientSize(Notebook)}]), + Sizer = wxBoxSizer:new(?wxVERTICAL), + Splitter = wxSplitterWindow:new(Panel, [{size, wxWindow:getClientSize(Panel)}]), + ProcessView = create_process_view(Splitter), + {MatchSpecView,ModView,FuncView} = create_matchspec_view(Splitter), + wxSplitterWindow:setSashGravity(Splitter, 0.5), + wxSplitterWindow:setMinimumPaneSize(Splitter,50), + wxSplitterWindow:splitHorizontally(Splitter, ProcessView, MatchSpecView), + wxSizer:add(Sizer, Splitter, [{flag, ?wxEXPAND bor ?wxALL}, {border, 5}, {proportion, 1}]), + %% Buttons + Buttons = wxBoxSizer:new(?wxHORIZONTAL), + ToggleButton = wxToggleButton:new(Panel, ?TOGGLE_TRACE, "Start Trace", []), + wxSizer:add(Buttons, ToggleButton), + New = wxButton:new(Panel, ?ADD_NEW, [{label, "Trace New Processes"}]), + wxSizer:add(Buttons, New), + ATP = wxButton:new(Panel, ?ADD_TP, [{label, "Add Trace Pattern"}]), + wxSizer:add(Buttons, ATP), + wxMenu:connect(Panel, command_togglebutton_clicked, []), + wxMenu:connect(Panel, command_button_clicked, []), + wxSizer:add(Sizer, Buttons, [{flag, ?wxALL},{border, 2}, {proportion,0}]), + wxWindow:setSizer(Panel, Sizer), + {Panel, #state{parent=ParentPid, panel=Panel, + p_view=ProcessView, m_view=ModView, f_view=FuncView, + toggle_button = ToggleButton, + match_specs=default_matchspecs()}}. + +default_matchspecs() -> + Ms = [{"Return Trace", [{'_', [], [{return_trace}]}], "fun(_) -> return_trace() end"}, + {"Exception Trace", [{'_', [], [{exception_trace}]}], "fun(_) -> exception_trace() end"}, + {"Message Caller", [{'_', [], [{message,{caller}}]}], "fun(_) -> message(caller()) end"}, + {"Message Dump", [{'_', [], [{message,{process_dump}}]}], "fun(_) -> message(process_dump()) end"}], + [make_ms(Name,Term,FunStr) || {Name,Term,FunStr} <- Ms]. + +create_process_view(Parent) -> + Style = ?wxLC_REPORT bor ?wxLC_SINGLE_SEL bor ?wxLC_HRULES, + Grid = wxListCtrl:new(Parent, [{winid, ?PROCESSES}, {style, Style}]), + Li = wxListItem:new(), + AddListEntry = fun({Name, Align, DefSize}, Col) -> + wxListItem:setText(Li, Name), + wxListItem:setAlign(Li, Align), + wxListCtrl:insertColumn(Grid, Col, Li), + wxListCtrl:setColumnWidth(Grid, Col, DefSize), + Col + 1 + end, + ListItems = [{"Process Id", ?wxLIST_FORMAT_CENTER, 120}, + {"Trace Options", ?wxLIST_FORMAT_LEFT, 300}], + lists:foldl(AddListEntry, 0, ListItems), + wxListItem:destroy(Li), + + %% wxListCtrl:connect(Grid, command_list_item_activated), + %% wxListCtrl:connect(Grid, command_list_item_selected), + wxListCtrl:connect(Grid, size, [{skip, true}]), + + wxWindow:setFocus(Grid), + Grid. + +create_matchspec_view(Parent) -> + Panel = wxPanel:new(Parent), + MainSz = wxBoxSizer:new(?wxHORIZONTAL), + Style = ?wxLC_REPORT bor ?wxLC_SINGLE_SEL bor ?wxLC_HRULES, + Splitter = wxSplitterWindow:new(Panel, []), + Modules = wxListCtrl:new(Splitter, [{winid, ?MODULES}, {style, Style}]), + Funcs = wxListCtrl:new(Splitter, [{winid, ?FUNCTIONS}, {style, Style}]), + Li = wxListItem:new(), + wxListItem:setText(Li, "Modules"), + wxListCtrl:insertColumn(Modules, 0, Li), + wxListItem:setText(Li, "Functions"), + wxListCtrl:insertColumn(Funcs, 0, Li), + wxListCtrl:setColumnWidth(Funcs, 0, 150), + wxListItem:setText(Li, "Match Spec"), + wxListCtrl:insertColumn(Funcs, 1, Li), + wxListCtrl:setColumnWidth(Funcs, 1, 300), + wxListItem:destroy(Li), + wxSplitterWindow:setSashGravity(Splitter, 0.0), + wxSplitterWindow:setMinimumPaneSize(Splitter,50), + wxSplitterWindow:splitVertically(Splitter, Modules, Funcs, [{sashPosition, 150}]), + wxSizer:add(MainSz, Splitter, [{flag, ?wxEXPAND}, {proportion, 1}]), + + wxListCtrl:connect(Modules, size, [{skip, true}]), + wxListCtrl:connect(Funcs, size, [{skip, true}]), + wxListCtrl:connect(Modules, command_list_item_selected), + %% wxListCtrl:connect(Funcs, command_list_item_selected), + wxPanel:setSizer(Panel, MainSz), + {Panel, Modules, Funcs}. + +create_menues(Parent) -> + Menus = [{"File", [#create_menu{id = ?LOAD_TRACEOPTS, text = "Load settings"}, + #create_menu{id = ?SAVE_TRACEOPTS, text = "Save settings"}] + }], + observer_wx:create_menus(Parent, Menus). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%Main window +handle_event(#wx{obj=Obj, event=#wxSize{size={W,_}}}, State) -> + case wx:getObjectType(Obj) =:= wxListCtrl of + true -> + wx:batch(fun() -> + Cols = wxListCtrl:getColumnCount(Obj), + Last = lists:foldl(fun(I, Last) -> + Last - wxListCtrl:getColumnWidth(Obj, I) + end, W-?LCTRL_WDECR, lists:seq(0, Cols - 2)), + Size = max(150, Last), + wxListCtrl:setColumnWidth(Obj, Cols-1, Size) + end); + false -> + ok + end, + {noreply, State}; + +handle_event(#wx{id=?ADD_NEW}, State = #state{panel=Parent, def_trace_opts=TraceOpts}) -> + case observer_traceoptions_wx:process_trace(Parent, TraceOpts) of + {ok, Opts} -> + Process = #tpid{pid=new, opts=Opts}, + {noreply, do_add_processes([Process], State#state{def_trace_opts=Opts})}; + cancel -> + {noreply, State} + end; + +handle_event(#wx{id=?ADD_TP}, + State = #state{panel=Parent, nodes=Nodes, match_specs=Ms}) -> + Node = case Nodes of + [N|_] -> N; + [] -> node() + end, + case observer_traceoptions_wx:trace_pattern(self(), Parent, Node, Ms) of + cancel -> + {noreply, State}; + Patterns -> + {noreply, do_add_patterns(Patterns, State)} + end; + +handle_event(#wx{id=?MODULES, event=#wxList{type=command_list_item_selected, itemIndex=Row}}, + State = #state{tpatterns=TPs, m_view=Mview, f_view=Fview}) -> + Module = list_to_atom(wxListCtrl:getItemText(Mview, Row)), + update_functions_view(dict:fetch(Module, TPs), Fview), + {noreply, State}; + + +handle_event(#wx{event = #wxCommand{type = command_togglebutton_clicked, commandInt = 1}}, + #state{panel = Panel, + nodes = Nodes, + tpids = TProcs, + tpatterns = TPs, + toggle_button = ToggleBtn} = State) -> + LogWin = wxFrame:new(Panel, ?TRACERWIN, "Trace Log", [{size, {750, 800}}]), + Text = wxTextCtrl:new(LogWin, ?wxID_ANY, + [{style, ?wxTE_MULTILINE bor ?wxTE_RICH2 bor + ?wxTE_DONTWRAP bor ?wxTE_READONLY}]), + Font = observer_wx:get_attrib({font, fixed}), + Attr = wxTextAttr:new(?wxBLACK, [{font, Font}]), + true = wxTextCtrl:setDefaultStyle(Text, Attr), + Env = wx:get_env(), + Write = fun(Trace) -> + wx:set_env(Env), + wxTextCtrl:appendText(Text, textformat(Trace)) + end, + {ok, _} = ttb:tracer(Nodes, [{file, {local,"/tmp/foo"}}, {shell, {only, Write}}]), + setup_ttb(dict:to_list(TPs), TProcs), + wxFrame:connect(LogWin, close_window, [{skip, true}]), + wxFrame:show(LogWin), + wxToggleButton:setLabel(ToggleBtn, "Stop Trace"), + {noreply, State}; + +handle_event(#wx{event = #wxCommand{type = command_togglebutton_clicked, commandInt = 0}}, + #state{toggle_button = ToggleBtn} = State) -> + %%Stop tracing + ttb:stop(nofetch), + wxToggleButton:setLabel(ToggleBtn, "Start Trace"), + {noreply, State}; + +handle_event(#wx{id=?TRACERWIN, event=#wxClose{}}, + #state{toggle_button = ToggleBtn} = State) -> + %%Stop tracing + ttb:stop(nofetch), + wxToggleButton:setLabel(ToggleBtn, "Start Trace"), + {noreply, State}; + +%% handle_event(#wx{id = ?CLEAR, event = #wxCommand{type = command_menu_selected}}, +%% #state{text_ctrl = TxtCtrl} = State) -> +%% wxTextCtrl:clear(TxtCtrl), +%% {noreply, State}; + +%% handle_event(#wx{id = ?SAVE_BUFFER, event = #wxCommand{type = command_menu_selected}}, +%% #state{frame = Frame, text_ctrl = TxtCtrl} = State) -> +%% Dialog = wxFileDialog:new(Frame, [{style, ?wxFD_SAVE bor ?wxFD_OVERWRITE_PROMPT}]), +%% case wxFileDialog:showModal(Dialog) of +%% ?wxID_OK -> +%% Path = wxFileDialog:getPath(Dialog), +%% wxDialog:destroy(Dialog), +%% case filelib:is_file(Path) of +%% true -> +%% observer_wx:create_txt_dialog(Frame, "File already exists: " ++ Path ++ "\n", +%% "Error", ?wxICON_ERROR); +%% false -> +%% wxTextCtrl:saveFile(TxtCtrl, [{file, Path}]) +%% end; +%% _ -> +%% wxDialog:destroy(Dialog), +%% ok +%% end, +%% {noreply, State}; + +handle_event(#wx{id = ?SAVE_TRACEOPTS, + event = #wxCommand{type = command_menu_selected}}, + #state{panel = Panel, + def_trace_opts = TraceOpts, + match_specs = MatchSpecs, + tpatterns = TracePatterns + } = State) -> + Dialog = wxFileDialog:new(Panel, [{style, ?wxFD_SAVE bor ?wxFD_OVERWRITE_PROMPT}]), + case wxFileDialog:showModal(Dialog) of + ?wxID_OK -> + Path = wxFileDialog:getPath(Dialog), + write_file(Panel, Path, TraceOpts, MatchSpecs, dict:to_list(TracePatterns)); + _ -> + ok + end, + wxDialog:destroy(Dialog), + {noreply, State}; + +handle_event(#wx{id = ?LOAD_TRACEOPTS, + event = #wxCommand{type = command_menu_selected}}, + #state{panel = Panel} = State) -> + Dialog = wxFileDialog:new(Panel, [{style, ?wxFD_FILE_MUST_EXIST}]), + State2 = case wxFileDialog:showModal(Dialog) of + ?wxID_OK -> + Path = wxFileDialog:getPath(Dialog), + read_settings(Path, State); + _ -> + State + end, + wxDialog:destroy(Dialog), + {noreply, State2}; + +handle_event(#wx{id=ID, event = What}, State) -> + io:format("~p:~p: Unhandled event: ~p, ~p ~n", [?MODULE, self(), ID, What]), + {noreply, State}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +handle_call(Msg, _From, State) -> + io:format("~p~p: Got Call ~p~n",[?MODULE, ?LINE, Msg]), + {reply, ok, State}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +handle_cast({add_processes, Pids}, State = #state{panel=Parent, def_trace_opts=TraceOpts}) -> + case observer_traceoptions_wx:process_trace(Parent, TraceOpts) of + {ok, Opts} -> + POpts = [#tpid{pid=Pid, opts=Opts} || Pid <- Pids], + {noreply, do_add_processes(POpts, State#state{def_trace_opts=Opts})}; + cancel -> + {noreply, State} + end; +handle_cast(Msg, State) -> + io:format("~p ~p: Unhandled cast ~p~n", [?MODULE, ?LINE, Msg]), + {noreply, State}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +handle_info({active, _Node}, State=#state{parent=Parent}) -> + create_menues(Parent), + {noreply, State}; + +handle_info(not_active, State) -> + {noreply, State}; + +handle_info({update_ms, NewMs}, State) -> + {noreply, State#state{match_specs=NewMs}}; + +handle_info(Any, State) -> + io:format("~p~p: received unexpected message: ~p\n", [?MODULE, self(), Any]), + {noreply, State}. + +terminate(_Reason, #state{nodes=_Nodes}) -> + %% case observer_wx:try_rpc(Node, erlang, whereis, [dbg]) of + %% undefined -> fine; + %% Pid -> exit(Pid, kill) + %% end, + ok. + +code_change(_, _, State) -> + {stop, not_yet_implemented, State}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +do_add_processes(POpts, S0=#state{p_view=LCtrl, tpids=OldPids, nodes=Ns0}) -> + case merge_pids(POpts, OldPids) of + {OldPids, [], []} -> + S0; + {Pids, New, _Changed} -> + update_process_view(Pids, LCtrl), + Ns1 = lists:usort([node(Pid) || #tpid{pid=Pid} <- New, is_pid(Pid)]), + Nodes = case ordsets:subtract(Ns1, Ns0) of + [] -> Ns0; %% No new Nodes + NewNs -> + %% Handle new nodes + %% BUGBUG add trace patterns for new nodes + ordsets:union(NewNs, Ns0) + end, + S0#state{tpids=Pids, nodes=Nodes} + end. + +update_process_view(Pids, LCtrl) -> + wxListCtrl:deleteAllItems(LCtrl), + wx:foldl(fun(#tpid{pid=Pid, opts=Opts}, Row) -> + _Item = wxListCtrl:insertItem(LCtrl, Row, ""), + ?EVEN(Row) andalso + wxListCtrl:setItemBackgroundColour(LCtrl, Row, ?BG_EVEN), + wxListCtrl:setItem(LCtrl, Row, 0, observer_lib:to_str(Pid)), + wxListCtrl:setItem(LCtrl, Row, 1, observer_lib:to_str(Opts)), + Row+1 + end, 0, Pids). + +do_add_patterns({Module, NewPs}, State=#state{tpatterns=TPs0, m_view=Mview, f_view=Fview}) -> + Old = case dict:find(Module, TPs0) of + {ok, Prev} -> Prev; + error -> [] + end, + case merge_patterns(NewPs, Old) of + {Old, [], []} -> + State; + {MPatterns, _New, _Changed} -> + TPs = dict:store(Module, MPatterns, TPs0), + update_modules_view(lists:sort(dict:fetch_keys(TPs)), Module, Mview), + update_functions_view(dict:fetch(Module, TPs), Fview), + State#state{tpatterns=TPs} + end. + +update_modules_view(Mods, Module, LCtrl) -> + wxListCtrl:deleteAllItems(LCtrl), + wx:foldl(fun(Mod, Row) -> + _Item = wxListCtrl:insertItem(LCtrl, Row, ""), + ?EVEN(Row) andalso + wxListCtrl:setItemBackgroundColour(LCtrl, Row, ?BG_EVEN), + wxListCtrl:setItem(LCtrl, Row, 0, observer_lib:to_str(Mod)), + (Mod =:= Module) andalso + wxListCtrl:setItemState(LCtrl, Row, 16#FFFF, ?wxLIST_STATE_SELECTED), + Row+1 + end, 0, Mods). + +update_functions_view(Funcs, LCtrl) -> + wxListCtrl:deleteAllItems(LCtrl), + wx:foldl(fun(#tpattern{fa=FA, ms=#match_spec{str=Ms}}, Row) -> + _Item = wxListCtrl:insertItem(LCtrl, Row, ""), + ?EVEN(Row) andalso wxListCtrl:setItemBackgroundColour(LCtrl, Row, ?BG_EVEN), + wxListCtrl:setItem(LCtrl, Row, 0, observer_lib:to_str({func,FA})), + wxListCtrl:setItem(LCtrl, Row, 1, Ms), + Row+1 + end, 0, Funcs). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +merge_pids([N1=#tpid{pid=new}|Ns], [N2=#tpid{pid=new}|Old]) -> + {Pids, New, Changed} = merge_pids_1(Ns,Old), + {[N1|Pids], New, [{N2,N2}|Changed]}; +merge_pids([N1=#tpid{pid=new}|Ns], Old) -> + {Pids, New, Changed} = merge_pids_1(Ns,Old), + {[N1|Pids], [N1|New], Changed}; +merge_pids(Ns, [N2=#tpid{pid=new}|Old]) -> + {Pids, New, Changed} = merge_pids_1(Ns,Old), + {[N2|Pids], New, Changed}; +merge_pids(New, Old) -> + merge_pids_1(New, Old). + +merge_pids_1(New, Old) -> + merge(lists:sort(New), Old, #tpid.pid, [], [], []). + +merge_patterns(New, Old) -> + merge(lists:sort(New), Old, #tpattern.fa, [], [], []). + + +merge([N|Ns], [N|Os], El, New, Ch, All) -> + merge(Ns, Os, El, New, Ch, [N|All]); +merge([N|Ns], [O|Os], El, New, Ch, All) + when element(El, N) == element(El, O) -> + merge(Ns, Os, El, New, [{O,N}|Ch], [N|All]); +merge([N|Ns], Os=[O|_], El, New, Ch, All) + when element(El, N) < element(El, O) -> + merge(Ns, Os, El, [N|New], Ch, [N|All]); +merge(Ns=[N|_], [O|Os], El, New, Ch, All) + when element(El, N) > element(El, O) -> + merge(Ns, Os, El, New, Ch, [O|All]); +merge([], Os, _El, New, Ch, All) -> + {lists:reverse(All, Os), New, Ch}; +merge(Ns, [], _El, New, Ch, All) -> + {lists:reverse(All, Ns), Ns++New, Ch}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +setup_ttb(TPs, TPids) -> + _R1 = [setup_tps(FTP, []) || {_, FTP} <- TPs], + _R2 = [ttb:p(Pid, dbg_flags(Flags)) || #tpid{pid=Pid, opts=Flags} <- TPids], + [#tpid{pid=_Pid, opts=_Flags}|_] = TPids, + %% io:format("ttb:p(pid(\"~w\", ~w).", [Pid, Flags]), + %% io:format("TTB ~w ~w~n",[R2, R1]), + ok. + +%% Sigh order is important +setup_tps([First=#tpattern{fa={_,'_'}}|Rest], Prev) -> + setup_tp(First), + [setup_tp(TP) || TP <- lists:reverse(Prev)], + setup_tps(Rest, []); +setup_tps([First=#tpattern{fa={F,_}}|Rest], Prev = [#tpattern{fa={F,_}}|_]) -> + setup_tps(Rest, [First|Prev]); +setup_tps([First|Rest], Prev) -> + [setup_tp(TP) || TP <- lists:reverse(Prev)], + setup_tps(Rest, [First]); +setup_tps([], Prev) -> + [setup_tp(TP) || TP <- lists:reverse(Prev)]. + +setup_tp(#tpattern{m=M,fa={F,A}, ms=#match_spec{term=Ms}}) -> + ttb:tpl(M,F,A,Ms). + +dbg_flags(Flags) -> + [dbg_flag(Flag) || Flag <- Flags]. + +dbg_flag(send) -> s; +dbg_flag('receive') -> r; +dbg_flag(functions) -> c; +dbg_flag(on_spawn) -> sos; +dbg_flag(on_link) -> sol; +dbg_flag(on_first_spawn) -> sofs; +dbg_flag(on_first_link) -> sofl; +dbg_flag(events) -> p. + +textformat(Trace) when element(1, Trace) == trace_ts, tuple_size(Trace) >= 4 -> + format_trace(Trace, tuple_size(Trace)-1, element(tuple_size(Trace),Trace)); +textformat(Trace) when element(1, Trace) == drop, tuple_size(Trace) =:= 2 -> + io_lib:format("*** Dropped ~p messages.~n", [element(2,Trace)]); +textformat(Trace) when element(1, Trace) == seq_trace, tuple_size(Trace) >= 3 -> + io_lib:format("*** Seq trace not implmented.~n", []); +textformat(_) -> + "". + +format_trace(Trace, Size, TS0={_,_,MS}) -> + {_,{H,M,S}} = calendar:now_to_local_time(TS0), + TS = io_lib:format("~.2.0w:~.2.0w:~.2.0w:~.6.0w", [H,M,S,MS]), + From = element(2, Trace), + case element(3, Trace) of + 'receive' -> + case element(4, Trace) of + {dbg,ok} -> ""; + Message -> + io_lib:format("~s (~100p) << ~100p ~n", [TS,From,Message]) + end; + 'send' -> + Message = element(4, Trace), + To = element(5, Trace), + io_lib:format("~s (~100p) ~100p ! ~100p ~n", [TS,From,To,Message]); + call -> + case element(4, Trace) of + MFA when Size == 5 -> + Message = element(5, Trace), + io_lib:format("~s (~100p) call ~s (~100p) ~n", [TS,From,ffunc(MFA),Message]); + MFA -> + io_lib:format("~s (~100p) call ~s ~n", [TS,From,ffunc(MFA)]) + end; + return_from -> + MFA = element(4, Trace), + Ret = element(5, Trace), + io_lib:format("~s (~100p) returned from ~s -> ~100p ~n", [TS,From,ffunc(MFA),Ret]); + return_to -> + MFA = element(4, Trace), + io_lib:format("~s (~100p) returning to ~s ~n", [TS,From,ffunc(MFA)]); + spawn when Size == 5 -> + Pid = element(4, Trace), + MFA = element(5, Trace), + io_lib:format("~s (~100p) spawn ~100p as ~s ~n", [TS,From,Pid,ffunc(MFA)]); + Op -> + io_lib:format("~s (~100p) ~100p ~s ~n", [TS,From,Op,ftup(Trace,4,Size)]) + end. + +%%% These f* functions returns non-flat strings + +%% {M,F,[A1, A2, ..., AN]} -> "M:F(A1, A2, ..., AN)" +%% {M,F,A} -> "M:F/A" +ffunc({M,F,Argl}) when is_list(Argl) -> + io_lib:format("~100p:~100p(~s)", [M, F, fargs(Argl)]); +ffunc({M,F,Arity}) -> + io_lib:format("~100p:~100p/~100p", [M,F,Arity]); +ffunc(X) -> io_lib:format("~100p", [X]). + +%% Integer -> "Integer" +%% [A1, A2, ..., AN] -> "A1, A2, ..., AN" +fargs(Arity) when is_integer(Arity) -> integer_to_list(Arity); +fargs([]) -> []; +fargs([A]) -> io_lib:format("~100p", [A]); %% last arg +fargs([A|Args]) -> [io_lib:format("~100p,", [A]) | fargs(Args)]; +fargs(A) -> io_lib:format("~100p", [A]). % last or only arg + +%% {A_1, A_2, ..., A_N} -> "A_Index A_Index+1 ... A_Size" +ftup(Trace, Index, Index) -> + io_lib:format("~100p", [element(Index, Trace)]); +ftup(Trace, Index, Size) -> + [io_lib:format("~100p ", [element(Index, Trace)]) + | ftup(Trace, Index+1, Size)]. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +write_file(Frame, Filename, TraceOps, MatchSpecs, TPs) -> + FormatMS = fun(#match_spec{name=Id, term=T, func=F}) -> + io_lib:format("[{name,\"~s\"}, {term, ~w}, {func, \"~s\"}]", + [Id, T, F]) + end, + FormatTP = fun({Module, FTPs}) -> + List = format_ftp(FTPs, FormatMS), + io_lib:format("{tp, ~w, [~s]}.~n",[Module, List]) + end, + Str = + ["%%%\n%%% This file is generated by Observer\n", + "%%%\n%%% DO NOT EDIT!\n%%%\n", + [["{ms, ", FormatMS(Ms), "}.\n"] || Ms <- MatchSpecs], + "{traceopts, ", io_lib:format("~w",[TraceOps]) ,"}.\n", + [FormatTP(TP) || TP <- TPs] + ], + case file:write_file(Filename, list_to_binary(Str)) of + ok -> + success; + {error, Reason} -> + FailMsg = file:format_error(Reason), + observer_wx:create_txt_dialog(Frame, FailMsg, "Error", ?wxICON_ERROR) + end. + +format_ftp([#tpattern{fa={F,A}, ms=Ms}], FormatMS) -> + io_lib:format("{~w, ~w, ~s}", [F,A,FormatMS(Ms)]); +format_ftp([#tpattern{fa={F,A}, ms=Ms}|Rest], FormatMS) -> + [io_lib:format("{~w, ~w, ~s},~n ", [F,A,FormatMS(Ms)]), + format_ftp(Rest, FormatMS)]. + +read_settings(Filename, #state{match_specs=Ms0, def_trace_opts=TO0} = State) -> + case file:consult(Filename) of + {ok, Terms} -> + Ms = lists:usort(Ms0 ++ [parse_ms(MsList) || {ms, MsList} <- Terms]), + TOs = lists:usort(TO0 ++ proplists:get_value(traceopts, Terms, [])), + lists:foldl(fun parse_tp/2, + State#state{match_specs=Ms, def_trace_opts=TOs}, + Terms); + {error, _} -> + observer_wx:create_txt_dialog(State#state.panel, "Could not load settings", + "Error", ?wxICON_ERROR), + State + end. + +parse_ms(Opts) -> + Name = proplists:get_value(name, Opts, "TracePattern"), + Term = proplists:get_value(term, Opts, [{'_',[],[ok]}]), + FunStr = proplists:get_value(term, Opts, "fun(_) -> ok end"), + make_ms(Name, Term, FunStr). + +make_ms(Name, Term, FunStr) -> + #match_spec{name=Name, term=Term, str=io_lib:format("~w", Term), func = FunStr}. + +parse_tp({tp, Mod, FAs}, State) -> + Patterns = [#tpattern{m=Mod,fa={F,A}, ms=parse_ms(List)} || + {F,A,List} <- FAs], + do_add_patterns({Mod, Patterns}, State); +parse_tp(_, State) -> + State. diff --git a/lib/observer/src/observer_traceoptions_wx.erl b/lib/observer/src/observer_traceoptions_wx.erl new file mode 100644 index 0000000000..bad05ec016 --- /dev/null +++ b/lib/observer/src/observer_traceoptions_wx.erl @@ -0,0 +1,572 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2011. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% + +-module(observer_traceoptions_wx). + +-include_lib("wx/include/wx.hrl"). +-include("observer_defs.hrl"). + +-export([process_trace/2, trace_pattern/4]). + +-compile(export_all). + +process_trace(Parent, Default) -> + Dialog = wxDialog:new(Parent, ?wxID_ANY, "Process Options", + [{style, ?wxDEFAULT_DIALOG_STYLE bor ?wxRESIZE_BORDER}]), + Panel = wxPanel:new(Dialog), + MainSz = wxBoxSizer:new(?wxVERTICAL), + PanelSz = wxBoxSizer:new(?wxHORIZONTAL), + LeftSz = wxStaticBoxSizer:new(?wxVERTICAL, Panel, [{label, "Tracing options"}]), + RightSz = wxStaticBoxSizer:new(?wxVERTICAL, Panel, [{label, "Inheritance options:"}]), + + FuncBox = wxCheckBox:new(Panel, ?wxID_ANY, "Trace function call", []), + check_box(FuncBox, lists:member(functions, Default)), + SendBox = wxCheckBox:new(Panel, ?wxID_ANY, "Trace send message", []), + check_box(SendBox, lists:member(send, Default)), + RecBox = wxCheckBox:new(Panel, ?wxID_ANY, "Trace receive message", []), + check_box(RecBox, lists:member('receive', Default)), + EventBox = wxCheckBox:new(Panel, ?wxID_ANY, "Trace process events", []), + check_box(EventBox, lists:member(events, Default)), + + {SpawnBox, SpwnAllRadio, SpwnFirstRadio} = + optionpage_top_right(Panel, RightSz, [{flag, ?wxBOTTOM},{border, 5}], "spawn"), + {LinkBox, LinkAllRadio, LinkFirstRadio} = + optionpage_top_right(Panel, RightSz, [{flag, ?wxBOTTOM},{border, 5}], "link"), + SpawnBool = lists:member(on_spawn, Default) orelse lists:member(on_first_spawn, Default), + LinkBool = lists:member(on_link, Default) orelse lists:member(on_first_link, Default), + check_box(SpawnBox, SpawnBool), + check_box(LinkBox, LinkBool), + enable(SpawnBox, [SpwnAllRadio, SpwnFirstRadio]), + enable(LinkBox, [LinkAllRadio, LinkFirstRadio]), + wxRadioButton:setValue(SpwnAllRadio, lists:member(on_spawn, Default)), + wxRadioButton:setValue(SpwnFirstRadio, lists:member(on_first_spawn, Default)), + wxRadioButton:setValue(LinkAllRadio, lists:member(on_link, Default)), + wxRadioButton:setValue(LinkFirstRadio, lists:member(on_first_link, Default)), + + wxSizer:add(LeftSz, FuncBox, []), + wxSizer:add(LeftSz, SendBox, []), + wxSizer:add(LeftSz, RecBox, []), + wxSizer:add(LeftSz, EventBox, []), + wxSizer:add(LeftSz, 150, -1), + + wxSizer:add(PanelSz, LeftSz, [{flag, ?wxEXPAND}]), + wxSizer:add(PanelSz, RightSz,[{flag, ?wxEXPAND}]), + wxPanel:setSizer(Panel, PanelSz), + wxSizer:add(MainSz, Panel, [{flag, ?wxEXPAND}, {proportion,1}]), + Buttons = wxDialog:createButtonSizer(Dialog, ?wxOK bor ?wxCANCEL), + wxSizer:add(MainSz, Buttons, [{flag, ?wxEXPAND bor ?wxALL}, {border, 5}]), + wxWindow:setSizerAndFit(Dialog, MainSz), + wxSizer:setSizeHints(MainSz, Dialog), + wxCheckBox:connect(SpawnBox, command_checkbox_clicked, + [{callback, fun(#wx{event=#wxCommand{}},_) -> + enable(SpawnBox, [SpwnAllRadio, SpwnFirstRadio]) + end}]), + wxCheckBox:connect(LinkBox, command_checkbox_clicked, + [{callback, fun(#wx{event=#wxCommand{}},_) -> + enable(LinkBox, [LinkAllRadio, LinkFirstRadio]) + end}]), + + Res = case wxDialog:showModal(Dialog) of + ?wxID_OK -> + All = [{SendBox, send}, {RecBox, 'receive'}, + {FuncBox, functions}, {EventBox, events}, + {{SpawnBox, SpwnAllRadio}, on_spawn}, + {{SpawnBox,SpwnFirstRadio}, on_first_spawn}, + {{LinkBox, LinkAllRadio}, on_link}, + {{LinkBox, LinkFirstRadio}, on_first_link}], + Check = fun({Box, Radio}) -> + wxCheckBox:getValue(Box) andalso wxRadioButton:getValue(Radio); + (Box) -> + wxCheckBox:getValue(Box) + end, + Opts = [Id || {Tick, Id} <- All, Check(Tick)], + {ok, lists:reverse(Opts)}; + ?wxID_CANCEL -> + cancel + end, + wxDialog:destroy(Dialog), + Res. + +trace_pattern(ParentPid, Parent, Node, MatchSpecs) -> + try + Module = module_selector(Parent, Node), + MFAs = function_selector(Parent, Node, Module), + MatchSpec = select_matchspec(ParentPid, Parent, MatchSpecs), + {Module, [#tpattern{m=M,fa={F,A},ms=MatchSpec} || {M,F,A} <- MFAs]} + catch cancel -> cancel + end. + +module_selector(Parent, Node) -> + Dialog = wxDialog:new(Parent, ?wxID_ANY, "Select Module", + [{style, ?wxDEFAULT_DIALOG_STYLE bor ?wxRESIZE_BORDER}, + {size, {400, 400}}]), + Panel = wxPanel:new(Dialog), + PanelSz = wxBoxSizer:new(?wxVERTICAL), + MainSz = wxBoxSizer:new(?wxVERTICAL), + + TxtCtrl = wxTextCtrl:new(Panel, ?wxID_ANY), + ListBox = wxListBox:new(Panel, ?wxID_ANY, [{style, ?wxLB_SINGLE}]), + wxSizer:add(PanelSz, TxtCtrl, [{flag, ?wxEXPAND}]), + wxSizer:add(PanelSz, ListBox, [{flag, ?wxEXPAND}, {proportion, 1}]), + wxPanel:setSizer(Panel, PanelSz), + wxSizer:add(MainSz, Panel, [{flag, ?wxEXPAND bor ?wxALL}, + {border, 5}, {proportion, 1}]), + Buttons = wxDialog:createButtonSizer(Dialog, ?wxOK bor ?wxCANCEL), + wxSizer:add(MainSz, Buttons, [{flag, ?wxEXPAND bor ?wxALL}, + {border, 5}, {proportion, 0}]), + wxWindow:setSizer(Dialog, MainSz), + OkId = wxDialog:getAffirmativeId(Dialog), + OkButt = wxWindow:findWindowById(OkId), + wxWindow:disable(OkButt), + wxWindow:setFocus(TxtCtrl), + %% init data + Modules = get_modules(Node), + AllModules = [{atom_to_list(X), X} || X <- Modules], + filter_listbox_data("", AllModules, ListBox), + wxTextCtrl:connect(TxtCtrl, command_text_updated, + [{callback, fun(#wx{event=#wxCommand{cmdString=Input}}, _) -> + filter_listbox_data(Input, AllModules, ListBox) + end}]), + wxListBox:connect(ListBox, command_listbox_doubleclicked, + [{callback, fun(_, _) -> wxDialog:endModal(Dialog, ?wxID_OK) end}]), + wxListBox:connect(ListBox, command_listbox_selected, + [{callback, fun(#wx{event=#wxCommand{commandInt=Id}}, _) -> + Id >= 0 andalso wxWindow:enable(OkButt) + end}]), + + case wxDialog:showModal(Dialog) of + ?wxID_OK -> + SelId = wxListBox:getSelection(ListBox), + case SelId >= 0 of + true -> + Module = wxListBox:getClientData(ListBox, SelId), + wxDialog:destroy(Dialog), + Module; + false -> + wxDialog:destroy(Dialog), + throw(cancel) + end; + ?wxID_CANCEL -> + wxDialog:destroy(Dialog), + throw(cancel) + end. + +function_selector(Parent, Node, Module) -> + Dialog = wxDialog:new(Parent, ?wxID_ANY, "Trace Functions", + [{style, ?wxDEFAULT_DIALOG_STYLE bor ?wxRESIZE_BORDER}, + {size, {400, 400}}]), + + Panel = wxPanel:new(Dialog), + PanelSz = wxBoxSizer:new(?wxVERTICAL), + MainSz = wxBoxSizer:new(?wxVERTICAL), + + TxtCtrl = wxTextCtrl:new(Panel, ?wxID_ANY), + ListBox = wxCheckListBox:new(Panel, ?wxID_ANY, [{style, ?wxLB_EXTENDED}]), + wxSizer:add(PanelSz, TxtCtrl, [{flag, ?wxEXPAND}]), + wxSizer:add(PanelSz, ListBox, [{flag, ?wxEXPAND}, {proportion, 1}]), + SelAllBtn = wxButton:new(Panel, ?wxID_ANY, [{label, "Check Visible"}]), + DeSelAllBtn = wxButton:new(Panel, ?wxID_ANY, [{label, "Uncheck Visible"}]), + ButtonSz = wxBoxSizer:new(?wxHORIZONTAL), + [wxSizer:add(ButtonSz, Button, []) || Button <- [SelAllBtn, DeSelAllBtn]], + wxSizer:add(PanelSz, ButtonSz, [{flag, ?wxEXPAND bor ?wxALL}, + {border, 5}, {proportion, 0}]), + wxPanel:setSizer(Panel, PanelSz), + wxSizer:add(MainSz, Panel, [{flag, ?wxEXPAND bor ?wxALL}, + {border, 5}, {proportion, 1}]), + + Buttons = wxDialog:createButtonSizer(Dialog, ?wxOK bor ?wxCANCEL), + wxSizer:add(MainSz, Buttons, [{flag, ?wxEXPAND bor ?wxALL}, + {border, 5}, {proportion, 0}]), + wxWindow:setSizer(Dialog, MainSz), + wxWindow:setFocus(TxtCtrl), + %% Init + Functions = observer_wx:try_rpc(Node, Module, module_info, [functions]), + Choices = lists:sort([{Name, Arity} || {Name, Arity} <- Functions, + not(erl_internal:guard_bif(Name, Arity))]), + ParsedChoices = parse_function_names(Choices), + filter_listbox_data("", ParsedChoices, ListBox, false), + %% Setup Event handling + wxTextCtrl:connect(TxtCtrl, command_text_updated, + [{callback, + fun(#wx{event=#wxCommand{cmdString=Input}}, _) -> + filter_listbox_data(Input, ParsedChoices, ListBox, false) + end}]), + Self = self(), + + %% Sigh clientdata in checklistbox crashes on windows, wx-bug I presume. + %% Don't have time to investigate now, workaround file bug report later + GetClientData = fun(LB, N) -> + String = wxListBox:getString(LB, N), + {_, Data} = lists:keyfind(String, 1, ParsedChoices), + Data + end, + wxCheckListBox:connect(ListBox, command_checklistbox_toggled, + [{callback, + fun(#wx{event=#wxCommand{commandInt=N}}, _) -> + Self ! {ListBox, wxCheckListBox:isChecked(ListBox, N), + GetClientData(ListBox, N)} + end}]), + Check = fun(Id, Bool) -> + wxCheckListBox:check(ListBox, Id, [{check, Bool}]), + Self ! {ListBox, Bool, GetClientData(ListBox, Id)} + end, + wxButton:connect(SelAllBtn, command_button_clicked, + [{callback, fun(#wx{}, _) -> + Count = wxListBox:getCount(ListBox), + [Check(SelId, true) || + SelId <- lists:seq(0, Count-1), + not wxCheckListBox:isChecked(ListBox, SelId)] + end}]), + wxButton:connect(DeSelAllBtn, command_button_clicked, + [{callback, fun(#wx{}, _) -> + Count = wxListBox:getCount(ListBox), + [Check(SelId, false) || + SelId <- lists:seq(0, Count-1), + wxCheckListBox:isChecked(ListBox, SelId)] + end}]), + case wxDialog:showModal(Dialog) of + ?wxID_OK -> + wxDialog:destroy(Dialog), + case get_checked_funcs(ListBox, []) of + [] -> [{Module, '_', '_'}]; + FAs -> + [{Module, F, A} || {F,A} <- FAs] + end; + ?wxID_CANCEL -> + wxDialog:destroy(Dialog), + throw(cancel) + end. + +get_checked_funcs(ListBox, Acc) -> + receive + {ListBox, true, FA} -> + get_checked_funcs(ListBox, [FA|lists:delete(FA,Acc)]); + {ListBox, false, FA} -> + get_checked_funcs(ListBox, lists:delete(FA,Acc)) + after 0 -> + lists:reverse(Acc) + end. + +select_matchspec(Pid, Parent, MatchSpecs) -> + Dialog = wxDialog:new(Parent, ?wxID_ANY, "Trace Match Specifications", + [{style, ?wxDEFAULT_DIALOG_STYLE bor ?wxRESIZE_BORDER}, + {size, {400, 400}}]), + + Panel = wxPanel:new(Dialog), + PanelSz = wxBoxSizer:new(?wxVERTICAL), + MainSz = wxBoxSizer:new(?wxVERTICAL), + TxtSz = wxStaticBoxSizer:new(?wxVERTICAL, Panel, [{label, "Match specification:"}]), + BtnSz = wxBoxSizer:new(?wxHORIZONTAL), + SavedSz = wxStaticBoxSizer:new(?wxVERTICAL, Panel, [{label, "Saved match specifications:"}]), + + TextCtrl = create_styled_txtctrl(Panel), + wxSizer:add(TxtSz, TextCtrl, [{flag, ?wxEXPAND}, {proportion, 1}]), + + AddMsBtn = wxButton:new(Panel, ?wxID_ANY, [{label, "New"}]), + EditMsBtn = wxButton:new(Panel, ?wxID_ANY, [{label, "Edit"}]), + DelMsBtn = wxButton:new(Panel, ?wxID_ANY, [{label, "Delete"}]), + wxSizer:add(BtnSz, AddMsBtn), + wxSizer:add(BtnSz, EditMsBtn), + wxSizer:add(BtnSz, DelMsBtn), + + ListBox = wxListBox:new(Panel, ?wxID_ANY, []), + wxSizer:add(SavedSz, ListBox, [{flag, ?wxEXPAND}, {proportion, 1}]), + wxSizer:add(PanelSz, TxtSz, [{flag, ?wxEXPAND}, {proportion, 1}]), + wxSizer:add(PanelSz, BtnSz), + wxSizer:add(PanelSz, SavedSz, [{flag, ?wxEXPAND}, {proportion, 1}]), + + wxWindow:setSizer(Panel, PanelSz), + wxSizer:add(MainSz, Panel, [{flag, ?wxEXPAND bor ?wxALL}, + {border, 5}, {proportion, 1}]), + Buttons = wxDialog:createButtonSizer(Dialog, ?wxOK bor ?wxCANCEL), + wxSizer:add(MainSz, Buttons, [{flag, ?wxEXPAND bor ?wxALL}, + {border, 5}, {proportion, 0}]), + wxWindow:setSizer(Dialog, MainSz), + OkId = wxDialog:getAffirmativeId(Dialog), + OkButt = wxWindow:findWindowById(OkId), + wxWindow:disable(OkButt), + wxWindow:disable(EditMsBtn), + wxWindow:disable(DelMsBtn), + + Choices = ms_names(MatchSpecs), + filter_listbox_data("", Choices, ListBox), + + Add = fun(_,_) -> + case edit_ms(TextCtrl, new, Parent) of + Ms = #match_spec{} -> add_and_select(-1, Ms, ListBox); + Else -> Else + end + end, + Edit = fun(_,_) -> + SelId = wxListBox:getSelection(ListBox), + case SelId >= 0 of + true -> + #match_spec{name=Name} = wxListBox:getClientData(ListBox,SelId), + case edit_ms(TextCtrl, Name, Parent) of + Ms = #match_spec{} -> add_and_select(SelId, Ms, ListBox); + Else -> Else + end; + false -> + ok + end + end, + Del = fun(_,_) -> + SelId = wxListBox:getSelection(ListBox), + case SelId >= 0 of + true -> + wxListBox:delete(ListBox, SelId); + false -> + ok + end + end, + Sel = fun(#wx{event=#wxCommand{commandInt=Id}}, _) -> + case Id >= 0 of + true -> + wxWindow:enable(OkButt), + wxWindow:enable(EditMsBtn), + wxWindow:enable(DelMsBtn), + #match_spec{func=Str} = wxListBox:getClientData(ListBox,Id), + wxStyledTextCtrl:setText(TextCtrl, Str); + false -> + try + wxWindow:disable(OkButt), + wxWindow:disable(EditMsBtn), + wxWindow:disable(DelMsBtn) + catch _:_ -> ok + end + end + end, + wxButton:connect(AddMsBtn, command_button_clicked, [{callback,Add}]), + wxButton:connect(EditMsBtn, command_button_clicked, [{callback,Edit}]), + wxButton:connect(DelMsBtn, command_button_clicked, [{callback,Del}]), + wxListBox:connect(ListBox, command_listbox_selected, [{callback, Sel}]), + case wxDialog:showModal(Dialog) of + ?wxID_OK -> + SelId = wxListBox:getSelection(ListBox), + Count = wxListBox:getCount(ListBox), + MSs = [wxListBox:getClientData(ListBox, Id) || + Id <- lists:seq(0, Count-1)], + Pid ! {update_ms, MSs}, + MS = lists:nth(SelId+1, MSs), + wxDialog:destroy(Dialog), + MS; + ?wxID_CANCEL -> + wxDialog:destroy(Dialog), + throw(cancel) + end. + +edit_ms(TextCtrl, Label0, Parent) -> + Str = ensure_last_is_dot(wxStyledTextCtrl:getText(TextCtrl)), + try + MatchSpec = ms_from_string(Str), + Label = case Label0 == new of + true -> get_label(Parent); + _ -> Label0 + end, + #match_spec{name=Label, term=MatchSpec, + str=io_lib:format("~w",[MatchSpec]), + func=Str} + catch + throw:cancel -> + ok; + throw:Error -> + observer_wx:create_txt_dialog(Parent, Error, "Error", ?wxICON_ERROR), + ok + end. + +get_label(Frame) -> + Dialog = wxTextEntryDialog:new(Frame, "Enter alias: "), + case wxDialog:showModal(Dialog) of + ?wxID_OK -> + wxTextEntryDialog:getValue(Dialog); + ?wxID_CANCEL -> + throw(cancel) + end. + +ms_from_string(Str) -> + try + Tokens = case erl_scan:string(Str) of + {ok, Ts, _} -> Ts; + {error, {SLine, SMod, SError}, _} -> + throw(io_lib:format("~w: ~s", [SLine,SMod:format_error(SError)])) + end, + Exprs = case erl_parse:parse_exprs(Tokens) of + {ok, T} -> T; + {error, {PLine, PMod, PError}} -> + throw(io_lib:format("~w: ~s", [PLine,PMod:format_error(PError)])) + end, + Term = case Exprs of + [{'fun', _, {clauses, Clauses}}|_] -> + case ms_transform:transform_from_shell(dbg,Clauses,orddict:new()) of + {error, [{_,[{MSLine,Mod,MSInfo}]}],_} -> + throw(io_lib:format("~w: ~p", [MSLine,Mod:format_error(MSInfo)])); + {error, _} -> + throw("Could not convert fun() to match spec"); + Ms -> + Ms + end; + [Expr|_] -> + erl_parse:normalise(Expr) + end, + case erlang:match_spec_test([], Term, trace) of + {ok, _, _, _} -> Term; + {error, List} -> throw([[Error, $\n] || {_, Error} <- List]) + end + catch error:_Reason -> + %% io:format("Bad term: ~s~n ~p in ~p~n", [Str, _Reason, erlang:get_stacktrace()]), + throw("Invalid term") + end. + +add_and_select(Id, MS0, ListBox) -> + [{Str,User}] = ms_names([MS0]), + Sel = case Id >= 0 of + true -> + wxListBox:setString(ListBox, Id, Str), + wxListBox:setClientData(ListBox, Id, User), + Id; + false -> + wxListBox:append(ListBox, Str, User) + end, + wxListBox:setSelection(ListBox, Sel). + +filter_listbox_data(Input, Data, ListBox) -> + filter_listbox_data(Input, Data, ListBox, true). + +filter_listbox_data(Input, Data, ListBox, AddClientData) -> + FilteredData = [X || X = {Str, _} <- Data, re:run(Str, Input) =/= nomatch], + wxListBox:clear(ListBox), + wxListBox:appendStrings(ListBox, [Str || {Str,_} <- FilteredData]), + AddClientData andalso + wx:foldl(fun({_, Term}, N) -> + wxListBox:setClientData(ListBox, N, Term), + N+1 + end, 0, FilteredData), + FilteredData. + +get_modules(Node) -> + lists:sort([Module || {Module, _} <- observer_wx:try_rpc(Node, code, all_loaded, [])]). + +optionpage_top_right(Panel, TopRightSz, Options, Text) -> + Sizer = wxBoxSizer:new(?wxVERTICAL), + ChkBox = wxCheckBox:new(Panel, ?wxID_ANY, "Inherit on " ++ Text, []), + RadioSz = wxBoxSizer:new(?wxVERTICAL), + Radio1 = wxRadioButton:new(Panel, ?wxID_ANY, "All " ++ Text, [{style, ?wxRB_GROUP}]), + Radio2 = wxRadioButton:new(Panel, ?wxID_ANY, "First " ++ Text ++ " only", []), + wxSizer:add(Sizer, ChkBox, []), + wxSizer:add(RadioSz, Radio1, []), + wxSizer:add(RadioSz, Radio2, []), + wxSizer:add(Sizer, RadioSz, [{flag, ?wxLEFT},{border, 20}]), + wxSizer:add(TopRightSz, Sizer, Options), + {ChkBox, Radio1, Radio2}. + + +create_styled_txtctrl(Parent) -> + FixedFont = observer_wx:get_attrib({font, fixed}), + Ed = wxStyledTextCtrl:new(Parent), + wxStyledTextCtrl:styleClearAll(Ed), + wxStyledTextCtrl:styleSetFont(Ed, ?wxSTC_STYLE_DEFAULT, FixedFont), + wxStyledTextCtrl:setLexer(Ed, ?wxSTC_LEX_ERLANG), + wxStyledTextCtrl:setMarginType(Ed, 1, ?wxSTC_MARGIN_NUMBER), + wxStyledTextCtrl:setSelectionMode(Ed, ?wxSTC_SEL_LINES), + wxStyledTextCtrl:setUseHorizontalScrollBar(Ed, false), + + Styles = [{?wxSTC_ERLANG_DEFAULT, {0,0,0}}, + {?wxSTC_ERLANG_COMMENT, {160,53,35}}, + {?wxSTC_ERLANG_VARIABLE, {150,100,40}}, + {?wxSTC_ERLANG_NUMBER, {5,5,100}}, + {?wxSTC_ERLANG_KEYWORD, {130,40,172}}, + {?wxSTC_ERLANG_STRING, {170,45,132}}, + {?wxSTC_ERLANG_OPERATOR, {30,0,0}}, + {?wxSTC_ERLANG_ATOM, {0,0,0}}, + {?wxSTC_ERLANG_FUNCTION_NAME, {64,102,244}}, + {?wxSTC_ERLANG_CHARACTER,{236,155,172}}, + {?wxSTC_ERLANG_MACRO, {40,144,170}}, + {?wxSTC_ERLANG_RECORD, {40,100,20}}, + {?wxSTC_ERLANG_SEPARATOR,{0,0,0}}, + {?wxSTC_ERLANG_NODE_NAME,{0,0,0}}], + SetStyle = fun({Style, Color}) -> + wxStyledTextCtrl:styleSetFont(Ed, Style, FixedFont), + wxStyledTextCtrl:styleSetForeground(Ed, Style, Color) + end, + [SetStyle(Style) || Style <- Styles], + wxStyledTextCtrl:setKeyWords(Ed, 0, keyWords()), + Ed. + + +keyWords() -> + L = ["after","begin","case","try","cond","catch","andalso","orelse", + "end","fun","if","let","of","query","receive","when","bnot","not", + "div","rem","band","and","bor","bxor","bsl","bsr","or","xor"], + lists:flatten([K ++ " " || K <- L] ++ [0]). + + +enable(CheckBox, Radio) -> + case wxCheckBox:isChecked(CheckBox) of + false -> + [wxWindow:disable(R) || R <- Radio]; + true -> + [wxWindow:enable(R) || R <- Radio] + end. + + +check_box(ChkBox, Bool) -> + case Bool of + true -> + wxCheckBox:set3StateValue(ChkBox, ?wxCHK_CHECKED); + false -> + ignore + end. + +parse_function_names(Choices) -> + StrList = [{atom_to_list(Name) ++ "/" ++ integer_to_list(Arity), Term} + || Term = {Name, Arity} <- Choices], + parse_function_names(StrList, []). + +parse_function_names([], Acc) -> + lists:reverse(Acc); +parse_function_names([{H, Term}|T], Acc) -> + IsFun = re:run(H, ".*-fun-\\d*?-"), + IsLc = re:run(H, ".*-lc\\$\\^\\d*?/\\d*?-\\d*?-"), + IsLbc = re:run(H, ".*-lbc\\$\\^\\d*?/\\d*?-\\d*?-"), + Parsed = + if IsFun =/= nomatch -> "Fun: " ++ H; + IsLc =/= nomatch -> "List comprehension: " ++ H; + IsLbc =/= nomatch -> "Bit comprehension: " ++ H; + true -> + H + end, + parse_function_names(T, [{Parsed, Term} | Acc]). + +ms_names(MatchSpecList) -> + MsOrAlias = fun(#match_spec{name = A, str = M}) -> + case A of + "" -> M; + _ -> A ++ " " ++ M + end + end, + [{MsOrAlias(X), X} || X <- MatchSpecList]. + +ensure_last_is_dot([]) -> + "."; +ensure_last_is_dot(String) -> + case lists:last(String) =:= $. of + true -> + String; + false -> + String ++ "." + end. diff --git a/lib/observer/src/observer_tv.hrl b/lib/observer/src/observer_tv.hrl new file mode 100644 index 0000000000..05e4f928d0 --- /dev/null +++ b/lib/observer/src/observer_tv.hrl @@ -0,0 +1,34 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2011. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% + +-record(tab, {name, + id = ignore, + size, + memory=0, %% In bytes + owner, + reg_name, + protection = public, + type=set, + keypos=1, + heir=none, + compressed=false, + fixed=false, + %% Mnesia Info + storage, + index + }). diff --git a/lib/observer/src/observer_tv_table.erl b/lib/observer/src/observer_tv_table.erl new file mode 100644 index 0000000000..7b5cdb44b9 --- /dev/null +++ b/lib/observer/src/observer_tv_table.erl @@ -0,0 +1,801 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2011. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% + +-module(observer_tv_table). + +-export([start_link/2]). + +%% wx_object callbacks +-export([init/1, handle_info/2, terminate/2, code_change/3, handle_call/3, + handle_event/2, handle_sync_event/3, handle_cast/2]). + +-export([get_table/3]). + +-include("observer_defs.hrl"). +-import(observer_lib, [to_str/1]). + +-behaviour(wx_object). +-include_lib("wx/include/wx.hrl"). +-include("observer_tv.hrl"). + +-define(ID_TABLE_INFO, 400). +-define(ID_REFRESH, 401). +-define(ID_REFRESH_INTERVAL, 402). +-define(ID_EDIT, 403). +-define(ID_DELETE, 404). +-define(ID_SEARCH, 405). + +-define(SEARCH_ENTRY, 420). +-define(GOTO_ENTRY, 421). + +-define(DEFAULT_COL_WIDTH, 150). + +-record(state, + { + parent, + frame, + grid, + status, + sizer, + search, + selected, + node=node(), + columns, + pid, + source, + tab, + attrs, + timer + }). + +-record(opt, + { + sort_key=2, + sort_incr=true + }). + +-record(search, + {enable=true, % Subwindow is enabled + win, % Sash Sub window obj + name, % name + + search, % Search input ctrl + goto, % Goto input ctrl + radio, % Radio buttons + + find % Search string + }). + +-record(find, {start, % start pos + strlen, % Found + found % false + }). + +start_link(Parent, Opts) -> + wx_object:start_link(?MODULE, [Parent, Opts], []). + +init([Parent, Opts]) -> + Source = proplists:get_value(type, Opts), + Table = proplists:get_value(table, Opts), + Node = proplists:get_value(node, Opts), + Title0 = atom_to_list(Table#tab.name) ++ " @ " ++ atom_to_list(Node), + Title = case Source of + ets -> "TV Ets: " ++ Title0; + mnesia -> "TV Mnesia: " ++ Title0 + end, + Frame = wxFrame:new(Parent, ?wxID_ANY, Title, [{size, {800, 300}}]), + IconFile = filename:join(code:priv_dir(observer), "erlang_observer.png"), + Icon = wxIcon:new(IconFile, [{type,?wxBITMAP_TYPE_PNG}]), + wxFrame:setIcon(Frame, Icon), + wxIcon:destroy(Icon), + MenuBar = wxMenuBar:new(), + create_menus(MenuBar), + wxFrame:setMenuBar(Frame, MenuBar), + %% wxFrame:setAcceleratorTable(Frame, AccelTable), + wxMenu:connect(Frame, command_menu_selected), + + StatusBar = wxFrame:createStatusBar(Frame, []), + try + TabId = table_id(Table), + ColumnNames = column_names(Node, Source, TabId), + KeyPos = key_pos(Node, Source, TabId), + + Attrs = observer_lib:create_attrs(), + + Self = self(), + Holder = spawn_link(fun() -> + init_table_holder(Self, Table, Source, + length(ColumnNames), Node, Attrs) + end), + + Panel = wxPanel:new(Frame), + Sizer = wxBoxSizer:new(?wxVERTICAL), + Style = ?wxLC_REPORT bor ?wxLC_VIRTUAL bor ?wxLC_SINGLE_SEL bor ?wxLC_HRULES, + Grid = wxListCtrl:new(Panel, [{style, Style}, + {onGetItemText, + fun(_, Item,Col) -> get_row(Holder, Item, Col+1) end}, + {onGetItemAttr, + fun(_, Item) -> get_attr(Holder, Item) end} + ]), + wxListCtrl:connect(Grid, command_list_item_activated), + wxListCtrl:connect(Grid, command_list_item_selected), + wxListCtrl:connect(Grid, command_list_col_click), + wxListCtrl:connect(Grid, size, [{skip, true}]), + wxWindow:setFocus(Grid), + + Search = search_area(Panel), + wxSizer:add(Sizer, Grid, + [{flag, ?wxEXPAND bor ?wxALL}, {proportion, 1}, {border, 5}]), + wxSizer:add(Sizer, Search#search.win, + [{flag,?wxEXPAND bor ?wxLEFT bor ?wxRIGHT bor + ?wxRESERVE_SPACE_EVEN_IF_HIDDEN}, + {border, 5}]), + wxWindow:setSizer(Panel, Sizer), + wxSizer:hide(Sizer, Search#search.win), + + Cols = add_columns(Grid, 0, ColumnNames), + wxFrame:show(Frame), + {Panel, #state{frame=Frame, grid=Grid, status=StatusBar, search=Search, + sizer = Sizer, + parent=Parent, columns=Cols, + pid=Holder, source=Source, tab=Table#tab{keypos=KeyPos}, + attrs=Attrs}} + catch node_or_table_down -> + wxFrame:destroy(Frame), + stop + end. + +add_columns(Grid, Start, ColumnNames) -> + Li = wxListItem:new(), + AddListEntry = fun(Name, Col) -> + wxListItem:setText(Li, to_str(Name)), + wxListItem:setAlign(Li, ?wxLIST_FORMAT_LEFT), + wxListCtrl:insertColumn(Grid, Col, Li), + wxListCtrl:setColumnWidth(Grid, Col, ?DEFAULT_COL_WIDTH), + Col + 1 + end, + Cols = lists:foldl(AddListEntry, Start, ColumnNames), + wxListItem:destroy(Li), + Cols. + +create_menus(MB) -> + File = wxMenu:new(), + wxMenu:append(File, ?ID_TABLE_INFO, "Table Information\tCtrl-I"), + wxMenu:append(File, ?wxID_CLOSE, "Close"), + wxMenuBar:append(MB, File, "File"), + Edit = wxMenu:new(), + wxMenu:append(Edit, ?ID_EDIT, "Edit Object"), + wxMenu:append(Edit, ?ID_DELETE, "Delete Object\tCtrl-D"), + wxMenu:appendSeparator(Edit), + wxMenu:append(Edit, ?ID_SEARCH, "Search\tCtrl-S"), + wxMenu:appendSeparator(Edit), + wxMenu:append(Edit, ?ID_REFRESH, "Refresh\tCtrl-R"), + wxMenu:append(Edit, ?ID_REFRESH_INTERVAL, "Refresh interval..."), + wxMenuBar:append(MB, Edit, "Edit"), + Help = wxMenu:new(), + wxMenu:append(Help, ?wxID_HELP, "Help"), + wxMenuBar:append(MB, Help, "Help"), + ok. + +search_area(Parent) -> + HSz = wxBoxSizer:new(?wxHORIZONTAL), + wxSizer:add(HSz, wxStaticText:new(Parent, ?wxID_ANY, "Find:"), + [{flag,?wxALIGN_CENTER_VERTICAL}]), + TC1 = wxTextCtrl:new(Parent, ?SEARCH_ENTRY, [{style, ?wxTE_PROCESS_ENTER}]), + wxSizer:add(HSz, TC1, [{proportion,3}, {flag, ?wxEXPAND}]), + Nbtn = wxRadioButton:new(Parent, ?wxID_ANY, "Next"), + wxRadioButton:setValue(Nbtn, true), + wxSizer:add(HSz,Nbtn,[{flag,?wxALIGN_CENTER_VERTICAL}]), + Pbtn = wxRadioButton:new(Parent, ?wxID_ANY, "Previous"), + wxSizer:add(HSz,Pbtn,[{flag,?wxALIGN_CENTER_VERTICAL}]), + Cbtn = wxCheckBox:new(Parent, ?wxID_ANY, "Match Case"), + wxSizer:add(HSz,Cbtn,[{flag,?wxALIGN_CENTER_VERTICAL}]), + wxSizer:add(HSz, 15,15, [{proportion,1}, {flag, ?wxEXPAND}]), + wxSizer:add(HSz, wxStaticText:new(Parent, ?wxID_ANY, "Goto Entry:"), + [{flag,?wxALIGN_CENTER_VERTICAL}]), + TC2 = wxTextCtrl:new(Parent, ?GOTO_ENTRY, [{style, ?wxTE_PROCESS_ENTER}]), + wxSizer:add(HSz, TC2, [{proportion,0}, {flag, ?wxEXPAND}]), + wxTextCtrl:connect(TC1, command_text_updated), + wxTextCtrl:connect(TC1, command_text_enter), + wxTextCtrl:connect(TC1, kill_focus), + wxTextCtrl:connect(TC2, command_text_enter), + wxWindow:connect(Parent, command_button_clicked), + + #search{name='Search Area', win=HSz, + search=TC1,goto=TC2,radio={Nbtn,Pbtn,Cbtn}}. + +edit(Index, #state{pid=Pid, frame=Frame}) -> + Str = get_row(Pid, Index, all), + Dialog = wxTextEntryDialog:new(Frame, "Edit object:", [{value, Str}]), + case wxTextEntryDialog:showModal(Dialog) of + ?wxID_OK -> + New = wxTextEntryDialog:getValue(Dialog), + wxTextEntryDialog:destroy(Dialog), + case Str =:= New of + true -> ok; + false -> + complete_edit(Index, New, Pid) + end; + ?wxID_CANCEL -> + wxTextEntryDialog:destroy(Dialog) + end. + +complete_edit(Row, New0, Pid) -> + New = case lists:reverse(New0) of + [$.|_] -> New0; + _ -> New0 ++ "." + end, + try + {ok, Tokens, _} = erl_scan:string(New), + {ok, Term} = erl_parse:parse_term(Tokens), + Pid ! {edit, Row, Term} + catch _:{badmatch, {error, {_, _, Err}}} -> + self() ! {error, ["Parse error: ", Err]}; + _Err -> + self() ! {error, ["Syntax error in: ", New]} + end. + +handle_event(#wx{id=?ID_REFRESH},State = #state{pid=Pid}) -> + Pid ! refresh, + {noreply, State}; + +handle_event(#wx{event=#wxList{type=command_list_col_click, col=Col}}, + State = #state{pid=Pid}) -> + Pid ! {sort, Col+1}, + {noreply, State}; + +handle_event(#wx{event=#wxSize{size={W,_}}}, State=#state{grid=Grid}) -> + wx:batch(fun() -> + Cols = wxListCtrl:getColumnCount(Grid), + Last = lists:foldl(fun(I, Last) -> + Last - wxListCtrl:getColumnWidth(Grid, I) + end, W-?LCTRL_WDECR, lists:seq(0, Cols - 2)), + Size = max(?DEFAULT_COL_WIDTH, Last), + wxListCtrl:setColumnWidth(Grid, Cols-1, Size) + end), + {noreply, State}; + +handle_event(#wx{event=#wxList{type=command_list_item_selected, itemIndex=Index}}, + State = #state{pid=Pid, grid=Grid, status=StatusBar}) -> + N = wxListCtrl:getItemCount(Grid), + Str = get_row(Pid, Index, all), + wxStatusBar:setStatusText(StatusBar, io_lib:format("Objects: ~w: ~s",[N, Str])), + {noreply, State#state{selected=Index}}; + +handle_event(#wx{event=#wxList{type=command_list_item_activated, itemIndex=Index}}, + State) -> + edit(Index, State), + {noreply, State}; + +handle_event(#wx{id=?ID_EDIT}, State = #state{selected=undefined}) -> + {noreply, State}; +handle_event(#wx{id=?ID_EDIT}, State = #state{selected=Index}) -> + edit(Index, State), + {noreply, State}; + +handle_event(#wx{id=?ID_DELETE}, State = #state{selected=undefined}) -> + {noreply, State}; +handle_event(#wx{id=?ID_DELETE}, + State = #state{pid=Pid, status=StatusBar, selected=Index}) -> + Str = get_row(Pid, Index, all), + Pid ! {delete, Index}, + wxStatusBar:setStatusText(StatusBar, io_lib:format("Deleted object: ~s",[Str])), + {noreply, State}; + +handle_event(#wx{id=?wxID_CLOSE}, State) -> + {stop, normal, State}; + +handle_event(Help = #wx{id=?wxID_HELP}, State = #state{parent=Parent}) -> + Parent ! Help, + {noreply, State}; + +handle_event(#wx{id=?GOTO_ENTRY, event=#wxCommand{cmdString=Str}}, + State = #state{grid=Grid}) -> + try + Row0 = list_to_integer(Str), + Row1 = min(0, Row0), + Row = max(wxListCtrl:getItemCount(Grid)-1,Row1), + wxListCtrl:ensureVisible(Grid, Row), + ok + catch _:_ -> ok + end, + {noreply, State}; + +%% Search functionality +handle_event(#wx{id=?ID_SEARCH}, + State = #state{sizer=Sz, search=Search}) -> + wxSizer:show(Sz, Search#search.win), + wxWindow:setFocus(Search#search.search), + wxSizer:layout(Sz), + {noreply, State}; +handle_event(#wx{id=?SEARCH_ENTRY, event=#wxFocus{}}, + State = #state{search=Search, pid=Pid}) -> + Pid ! {mark_search_hit, false}, + {noreply, State#state{search=Search#search{find=undefined}}}; +handle_event(#wx{id=?SEARCH_ENTRY, event=#wxCommand{cmdString=""}}, + State = #state{search=Search, pid=Pid}) -> + Pid ! {mark_search_hit, false}, + {noreply, State#state{search=Search#search{find=undefined}}}; +handle_event(#wx{id=?SEARCH_ENTRY, event=#wxCommand{type=command_text_enter,cmdString=Str}}, + State = #state{grid=Grid, pid=Pid, status=SB, + search=Search=#search{radio={Next0, _, Case0}, + find=Find}}) + when Find =/= undefined -> + Dir = wxRadioButton:getValue(Next0) xor wx_misc:getKeyState(?WXK_SHIFT), + Case = wxCheckBox:getValue(Case0), + Pos = if Find#find.found, Dir -> %% Forward Continuation + Find#find.start+1; + Find#find.found -> %% Backward Continuation + Find#find.start-1; + Dir -> %% Forward wrap + 0; + true -> %% Backward wrap + wxListCtrl:getItemCount(Grid)-1 + end, + Pid ! {mark_search_hit, false}, + case search(Pid, Str, Pos, Dir, Case) of + false -> + wxStatusBar:setStatusText(SB, "Not found"), + Pid ! {mark_search_hit, Find#find.start}, + wxListCtrl:refreshItem(Grid, Find#find.start), + {noreply, State#state{search=Search#search{find=#find{found=false}}}}; + Row -> + wxListCtrl:ensureVisible(Grid, Row), + wxListCtrl:refreshItem(Grid, Row), + Status = "Found: (Hit Enter for next, Shift-Enter for previous)", + wxStatusBar:setStatusText(SB, Status), + {noreply, State#state{search=Search#search{find=#find{start=Row, found=true}}}} + end; +handle_event(#wx{id=?SEARCH_ENTRY, event=#wxCommand{cmdString=Str}}, + State = #state{grid=Grid, pid=Pid, status=SB, + search=Search=#search{radio={Next0, _, Case0}, + find=Find}}) -> + try + Dir = wxRadioButton:getValue(Next0), + Case = wxCheckBox:getValue(Case0), + Start = case Dir of + true -> 0; + false -> wxListCtrl:getItemCount(Grid)-1 + end, + Cont = case Find of + undefined -> + #find{start=Start, strlen=length(Str)}; + #find{strlen=Old} when Old < length(Str) -> + Find#find{start=Start, strlen=length(Str)}; + _ -> + Find#find{strlen=length(Str)} + end, + + Pid ! {mark_search_hit, false}, + case search(Pid, Str, Cont#find.start, Dir, Case) of + false -> + wxStatusBar:setStatusText(SB, "Not found"), + {noreply, State}; + Row -> + wxListCtrl:ensureVisible(Grid, Row), + wxListCtrl:refreshItem(Grid, Row), + Status = "Found: (Hit Enter for next, Shift-Enter for previous)", + wxStatusBar:setStatusText(SB, Status), + {noreply, State#state{search=Search#search{find=#find{start=Row, found=true}}}} + end + catch _:_ -> {noreply, State} + end; + +handle_event(#wx{id=?ID_TABLE_INFO}, + State = #state{frame=Frame, node=Node, source=Source, tab=Table}) -> + observer_tv_wx:display_table_info(Frame, Node, Source, Table), + {noreply, State}; + +handle_event(#wx{id=?ID_REFRESH_INTERVAL}, + State = #state{grid=Grid, timer=Timer0}) -> + Timer = observer_lib:interval_dialog(Grid, Timer0, 10, 5*60), + {noreply, State#state{timer=Timer}}; + +handle_event(Event, State) -> + io:format("~p:~p, handle event ~p\n", [?MODULE, ?LINE, Event]), + {noreply, State}. + +handle_sync_event(Event, _Obj, _State) -> + io:format("~p:~p, handle sync_event ~p\n", [?MODULE, ?LINE, Event]), + ok. + +handle_call(Event, From, State) -> + io:format("~p:~p, handle call (~p) ~p\n", [?MODULE, ?LINE, From, Event]), + {noreply, State}. + +handle_cast(Event, State) -> + io:format("~p:~p, handle cast ~p\n", [?MODULE, ?LINE, Event]), + {noreply, State}. + +handle_info({no_rows, N}, State = #state{grid=Grid, status=StatusBar}) -> + wxListCtrl:setItemCount(Grid, N), + wxStatusBar:setStatusText(StatusBar, io_lib:format("Objects: ~w",[N])), + {noreply, State}; +handle_info({new_cols, New}, State = #state{grid=Grid, columns=Cols0}) -> + Cols = add_columns(Grid, Cols0, New), + {noreply, State#state{columns=Cols}}; +handle_info({refresh, Min, Max}, State = #state{grid=Grid}) -> + wxListCtrl:refreshItems(Grid, Min, Max), + {noreply, State}; +handle_info({error, Error}, State = #state{frame=Frame}) -> + Dlg = wxMessageDialog:new(Frame, Error), + wxMessageDialog:showModal(Dlg), + wxMessageDialog:destroy(Dlg), + {noreply, State}; + +handle_info(Event, State) -> + io:format("~p:~p, handle info ~p\n", [?MODULE, ?LINE, Event]), + {noreply, State}. + +terminate(_Event, #state{pid=Pid, attrs=Attrs}) -> + %% ListItemAttr are not auto deleted + #attrs{odd=Odd, deleted=D, changed=Ch, searched=S} = Attrs, + wxListItemAttr:destroy(Odd), + wxListItemAttr:destroy(D), + wxListItemAttr:destroy(Ch), + wxListItemAttr:destroy(S), + unlink(Pid), + exit(Pid, window_closed), + ok. + +code_change(_, _, State) -> + State. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Table holder needs to be in a separate process otherwise +%% the callback get_row/3 may deadlock if the process do +%% wx calls when callback is invoked. +get_row(Table, Item, Column) -> + Ref = erlang:monitor(process, Table), + Table ! {get_row, self(), Item, Column}, + receive + {'DOWN', Ref, _, _, _} -> ""; + {Table, Res} -> + erlang:demonitor(Ref), + Res + end. + +get_attr(Table, Item) -> + Ref = erlang:monitor(process, Table), + Table ! {get_attr, self(), Item}, + receive + {'DOWN', Ref, _, _, _} -> ""; + {Table, Res} -> + erlang:demonitor(Ref), + Res + end. + +search(Table, Str, Row, Dir, Case) -> + Ref = erlang:monitor(process, Table), + Table ! {search, [Str, Row, Dir, Case]}, + receive + {'DOWN', Ref, _, _, _} -> ""; + {Table, Res} -> + erlang:demonitor(Ref), + Res + end. + +-record(holder, {node, parent, pid, + table=[], n=0, columns, + temp=[], + search, + source, tabid, + sort, + key, + type, + attrs + }). + +init_table_holder(Parent, Table, MnesiaOrEts, Cols, Node, Attrs) -> + TabId = case Table#tab.id of + ignore -> Table#tab.name; + Id -> Id + end, + self() ! refresh, + table_holder(#holder{node=Node, parent=Parent, + source=MnesiaOrEts, tabid=TabId, columns=Cols, + sort=#opt{sort_key=Table#tab.keypos, sort_incr=true}, + type=Table#tab.type, key=Table#tab.keypos, + attrs=Attrs}). + +table_holder(S0 = #holder{parent=Parent, pid=Pid, table=Table}) -> + receive + {get_attr, From, Row} -> + get_attr(From, Row, S0), + table_holder(S0); + {get_row, From, Row, Col} -> + get_row(From, Row, Col, Table), + table_holder(S0); + {Pid, Data} -> + S1 = handle_new_data_chunk(Data, S0), + table_holder(S1); + {sort, Col} -> + table_holder(sort(Col, S0)); + {search, Data} -> + table_holder(search(Data, S0)); + {mark_search_hit, Row} -> + Old = S0#holder.search, + is_integer(Old) andalso (Parent ! {refresh, Old, Old}), + table_holder(S0#holder{search=Row}); + refresh when is_pid(Pid) -> + %% Already getting the table... + %% io:format("ignoring refresh", []), + table_holder(S0); + refresh -> + GetTab = rpc:call(S0#holder.node, ?MODULE, get_table, + [self(), S0#holder.tabid, S0#holder.source]), + table_holder(S0#holder{pid=GetTab}); + {delete, Row} -> + delete_row(Row, S0), + table_holder(S0); + {edit, Row, Term} -> + edit_row(Row, Term, S0), + table_holder(S0); + What -> + io:format("Table holder got ~p~n",[What]), + table_holder(S0) + end. + +handle_new_data_chunk(Data, S0 = #holder{columns=Cols, parent=Parent}) -> + S1 = #holder{columns=NewCols} = handle_new_data_chunk2(Data, S0), + case NewCols =:= Cols of + true -> S1; + false -> + Parent ! {new_cols, lists:seq(Cols+1, NewCols)}, + S1 + end. + +handle_new_data_chunk2('$end_of_table', + S0 = #holder{parent=Parent, sort=Opt, + key=Key, + table=Old, temp=New}) -> + Table = merge(Old, New, Key), + N = length(Table), + Parent ! {no_rows, N}, + sort(Opt#opt.sort_key, S0#holder{n=N, pid=undefine, + sort=Opt#opt{sort_key = undefined}, + table=Table, temp=[]}); +handle_new_data_chunk2(Data, S0 = #holder{columns=Cols0, source=ets, temp=Tab0}) -> + {Tab, Cols} = parse_ets_data(Data, Cols0, Tab0), + S0#holder{columns=Cols, temp=Tab}; +handle_new_data_chunk2(Data, S0 = #holder{source=mnesia, temp=Tab}) -> + S0#holder{temp=(Data ++ Tab)}. + +parse_ets_data([[Rec]|Rs], C, Tab) -> + parse_ets_data(Rs, max(tuple_size(Rec), C), [Rec|Tab]); +parse_ets_data([Recs|Rs], C0, Tab0) -> + {Tab, Cols} = parse_ets_data(Recs, C0, Tab0), + parse_ets_data(Rs, Cols, Tab); +parse_ets_data([], Cols, Tab) -> + {Tab, Cols}. + +sort(Col, S=#holder{n=N, parent=Parent, sort=Opt0, table=Table0}) -> + {Opt, Table} = sort(Col, Opt0, Table0), + Parent ! {refresh, 0, N-1}, + S#holder{sort=Opt, table=Table}. + +sort(Col, Opt = #opt{sort_key=Col, sort_incr=Bool}, Table) -> + {Opt#opt{sort_incr=not Bool}, lists:reverse(Table)}; +sort(Col, S=#opt{sort_incr=true}, Table) -> + {S#opt{sort_key=Col}, keysort(Col, Table)}; +sort(Col, S=#opt{sort_incr=false}, Table) -> + {S#opt{sort_key=Col}, lists:reverse(keysort(Col, Table))}. + +keysort(Col, Table) -> + Sort = fun([A0|_], [B0|_]) -> + A = try element(Col, A0) catch _:_ -> [] end, + B = try element(Col, B0) catch _:_ -> [] end, + case A == B of + true -> A0 =< B0; + false -> A < B + end; + (A0, B0) when is_tuple(A0), is_tuple(B0) -> + A = try element(Col, A0) catch _:_ -> [] end, + B = try element(Col, B0) catch _:_ -> [] end, + case A == B of + true -> A0 =< B0; + false -> A < B + end + end, + lists:sort(Sort, Table). + +search([Str, Row, Dir0, CaseSens], + S=#holder{parent=Parent, table=Table}) -> + Opt = case CaseSens of + true -> []; + false -> [caseless] + end, + {ok, Re} = re:compile(Str, Opt), + Dir = case Dir0 of + true -> 1; + false -> -1 + end, + Res = search(Row, Dir, Re, Table), + Parent ! {self(), Res}, + S#holder{search=Res}. + +search(Row, Dir, Re, Table) -> + Res = try lists:nth(Row+1, Table) of + Term -> + Str = io_lib:format("~w", [Term]), + re:run(Str, Re) + catch _:_ -> no_more + end, + case Res of + nomatch -> search(Row+Dir, Dir, Re, Table); + no_more -> false; + {match,_} -> Row + end. + +get_row(From, Row, Col, Table) -> + case lists:nth(Row+1, Table) of + [Object|_] when Col =:= all -> + From ! {self(), io_lib:format("~w", [Object])}; + [Object|_] when tuple_size(Object) >= Col -> + From ! {self(), io_lib:format("~w", [element(Col, Object)])}; + _ -> + From ! {self(), ""} + end. + +get_attr(From, Row, #holder{attrs=Attrs, search=Row}) -> + What = Attrs#attrs.searched, + From ! {self(), What}; +get_attr(From, Row, #holder{table=Table, attrs=Attrs}) -> + What = case lists:nth(Row+1, Table) of + [_|deleted] -> Attrs#attrs.deleted; + [_|changed] -> Attrs#attrs.changed; + [_|new] -> Attrs#attrs.changed; + _ when (Row rem 2) > 0 -> + Attrs#attrs.odd; + _ -> + Attrs#attrs.even + end, + From ! {self(), What}. + +merge([], New, _Key) -> + [[N] || N <- New]; %% First time +merge(Old, New, Key) -> + merge2(keysort(Key, Old), keysort(Key, New), Key). + +merge2([[Obj|_]|Old], [Obj|New], Key) -> + [[Obj]|merge2(Old, New, Key)]; +merge2([[A|_]|Old], [B|New], Key) + when element(Key, A) == element(Key, B) -> + [[B|changed]|merge2(Old, New, Key)]; +merge2([[A|_]|Old], New = [B|_], Key) + when element(Key, A) < element(Key, B) -> + [[A|deleted]|merge2(Old, New, Key)]; +merge2(Old = [[A|_]|_], [B|New], Key) + when element(Key, A) > element(Key, B) -> + [[B|new]|merge2(Old, New, Key)]; +merge2([], New, _Key) -> + [[N|new] || N <- New]; +merge2(Old, [], _Key) -> + [[O|deleted] || [O|_] <- Old]. + + +delete_row(Row, S0 = #holder{parent=Parent}) -> + case delete(Row, S0) of + ok -> + self() ! refresh; + {error, Err} -> + Parent ! {error, "Could not delete object: " ++ Err} + end. + + +delete(Row, #holder{tabid=Id, table=Table, + source=Source, node=Node}) -> + [Object|_] = lists:nth(Row+1, Table), + try + case Source of + ets -> + true = rpc:call(Node, ets, delete_object, [Id, Object]); + mnesia -> + ok = rpc:call(Node, mnesia, dirty_delete_object, [Id, Object]) + end, + ok + catch _:_Error -> + {error, "node or table is not available"} + end. + +edit_row(Row, Term, S0 = #holder{parent=Parent}) -> + case delete(Row, S0) of + ok -> + case insert(Term, S0) of + ok -> self() ! refresh; + Err -> Parent ! {error, Err} + end; + {error, Err} -> + Parent ! {error, "Could not edit object: " ++ Err} + end. + +insert(Object, #holder{tabid=Id, source=Source, node=Node}) -> + try + case Source of + ets -> + true = rpc:call(Node, ets, insert, [Id, Object]); + mnesia -> + ok = rpc:call(Node, mnesia, dirty_write, [Id, Object]) + end, + ok + catch _:_Error -> + {error, "node or table is not available"} + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +get_table(Parent, Table, Module) -> + spawn(fun() -> + link(Parent), + get_table2(Parent, Table, Module) + end). + +get_table2(Parent, Table, Type) -> + Size = case Type of + ets -> ets:info(Table, size); + mnesia -> mnesia:table_info(Table, size) + end, + case Size > 0 of + false -> + Parent ! {self(), '$end_of_table'}, + normal; + true when Type =:= ets -> + Mem = ets:info(Table, memory), + Average = Mem div Size, + NoElements = max(10, 20000 div Average), + get_ets_loop(Parent, ets:match(Table, '$1', NoElements)); + true -> + Mem = mnesia:table_info(Table, memory), + Average = Mem div Size, + NoElements = max(10, 20000 div Average), + Ms = [{'$1', [], ['$1']}], + Get = fun() -> + get_mnesia_loop(Parent, mnesia:select(Table, Ms, NoElements, read)) + end, + %% Not a transaction, we don't want to grab locks when inspecting the table + mnesia:async_dirty(Get) + end. + +get_ets_loop(Parent, '$end_of_table') -> + Parent ! {self(), '$end_of_table'}; +get_ets_loop(Parent, {Match, Cont}) -> + Parent ! {self(), Match}, + get_ets_loop(Parent, ets:match(Cont)). + +get_mnesia_loop(Parent, '$end_of_table') -> + Parent ! {self(), '$end_of_table'}; +get_mnesia_loop(Parent, {Match, Cont}) -> + Parent ! {self(), Match}, + get_ets_loop(Parent, mnesia:select(Cont)). + +column_names(Node, Type, Table) -> + case Type of + ets -> [1, 2]; + mnesia -> + Attrs = rpc:call(Node, mnesia, table_info, [Table, attributes]), + is_list(Attrs) orelse throw(node_or_table_down), + ["Record Name"|Attrs] + end. + +table_id(#tab{id=ignore, name=Name}) -> Name; +table_id(#tab{id=Id}) -> Id. + +key_pos(_, mnesia, _) -> 2; +key_pos(Node, ets, TabId) -> + KeyPos = rpc:call(Node, ets, info, [TabId, keypos]), + is_integer(KeyPos) orelse throw(node_or_table_down), + KeyPos. diff --git a/lib/observer/src/observer_tv_wx.erl b/lib/observer/src/observer_tv_wx.erl new file mode 100644 index 0000000000..ded03fadb1 --- /dev/null +++ b/lib/observer/src/observer_tv_wx.erl @@ -0,0 +1,475 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2011. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +-module(observer_tv_wx). + +-export([start_link/2, display_table_info/4]). + +%% wx_object callbacks +-export([init/1, handle_info/2, terminate/2, code_change/3, handle_call/3, + handle_event/2, handle_sync_event/3, handle_cast/2]). + +-export([get_table_list/1]). %% RPC called move to runtime tools? + +-behaviour(wx_object). +-include_lib("wx/include/wx.hrl"). +-include("observer_defs.hrl"). +-include("observer_tv.hrl"). + +-define(GRID, 500). +-define(ID_REFRESH, 401). +-define(ID_REFRESH_INTERVAL, 402). +-define(ID_ETS, 403). +-define(ID_MNESIA, 404). +-define(ID_UNREADABLE, 405). +-define(ID_SYSTEM_TABLES, 406). +-define(ID_TABLE_INFO, 407). + +-record(opt, {type=ets, + sys_hidden=true, + unread_hidden=true, + sort_key=2, + sort_incr=true + }). + +-record(state, + { + parent, + grid, + node=node(), + opt=#opt{}, + selected, + tabs, + timer + }). + +start_link(Notebook, Parent) -> + wx_object:start_link(?MODULE, [Notebook, Parent], []). + +init([Notebook, Parent]) -> + Panel = wxPanel:new(Notebook), + Sizer = wxBoxSizer:new(?wxVERTICAL), + Style = ?wxLC_REPORT bor ?wxLC_SINGLE_SEL bor ?wxLC_HRULES, + Grid = wxListCtrl:new(Panel, [{winid, ?GRID}, {style, Style}]), + wxSizer:add(Sizer, Grid, [{flag, ?wxEXPAND bor ?wxALL}, + {proportion, 1}, {border, 5}]), + wxWindow:setSizer(Panel, Sizer), + Li = wxListItem:new(), + AddListEntry = fun({Name, Align, DefSize}, Col) -> + wxListItem:setText(Li, Name), + wxListItem:setAlign(Li, Align), + wxListCtrl:insertColumn(Grid, Col, Li), + wxListCtrl:setColumnWidth(Grid, Col, DefSize), + Col + 1 + end, + ListItems = [{"Table Name", ?wxLIST_FORMAT_LEFT, 200}, + {"Table Id", ?wxLIST_FORMAT_RIGHT, 100}, + {"Objects", ?wxLIST_FORMAT_RIGHT, 100}, + {"Size (kB)", ?wxLIST_FORMAT_RIGHT, 100}, + {"Owner Pid", ?wxLIST_FORMAT_CENTER, 150}, + {"Owner Name", ?wxLIST_FORMAT_LEFT, 200} + ], + lists:foldl(AddListEntry, 0, ListItems), + wxListItem:destroy(Li), + + wxListCtrl:connect(Grid, command_list_item_activated), + wxListCtrl:connect(Grid, command_list_item_selected), + wxListCtrl:connect(Grid, command_list_col_click), + wxListCtrl:connect(Grid, size, [{skip, true}]), + + wxWindow:setFocus(Grid), + Timer = observer_lib:start_timer(10), + {Panel, #state{grid=Grid, parent=Parent, timer=Timer}}. + +handle_event(#wx{id=?ID_REFRESH}, + State = #state{node=Node, grid=Grid, opt=Opt}) -> + Tables = get_tables(Node, Opt), + Tabs = update_grid(Grid, Opt, Tables), + {noreply, State#state{tabs=Tabs}}; + +handle_event(#wx{event=#wxList{type=command_list_col_click, col=Col}}, + State = #state{node=Node, grid=Grid, + opt=Opt0=#opt{sort_key=Key, sort_incr=Bool}}) -> + Opt = case Col+2 of + Key -> Opt0#opt{sort_incr=not Bool}; + NewKey -> Opt0#opt{sort_key=NewKey} + end, + Tables = get_tables(Node, Opt), + Tabs = update_grid(Grid, Opt, Tables), + wxWindow:setFocus(Grid), + {noreply, State#state{opt=Opt, tabs=Tabs}}; + +handle_event(#wx{id=Id}, State = #state{node=Node, grid=Grid, opt=Opt0}) + when Id >= ?ID_ETS, Id =< ?ID_SYSTEM_TABLES -> + Opt = case Id of + ?ID_ETS -> Opt0#opt{type=ets}; + ?ID_MNESIA -> Opt0#opt{type=mnesia}; + ?ID_UNREADABLE -> Opt0#opt{unread_hidden= not Opt0#opt.unread_hidden}; + ?ID_SYSTEM_TABLES -> Opt0#opt{sys_hidden= not Opt0#opt.sys_hidden} + end, + Tables = get_tables(Node, Opt), + Tabs = update_grid(Grid, Opt, Tables), + wxWindow:setFocus(Grid), + {noreply, State#state{opt=Opt, tabs=Tabs}}; + +handle_event(#wx{event=#wxSize{size={W,_}}}, State=#state{grid=Grid}) -> + wx:batch(fun() -> + Cols = wxListCtrl:getColumnCount(Grid), + Last = lists:foldl(fun(I, Last) -> + Last - wxListCtrl:getColumnWidth(Grid, I) + end, W-?LCTRL_WDECR, lists:seq(0, Cols - 2)), + Size = max(200, Last), + wxListCtrl:setColumnWidth(Grid, Cols-1, Size) + end), + {noreply, State}; + +handle_event(#wx{obj=Grid, event=#wxList{type=command_list_item_activated, + itemIndex=Index}}, + State=#state{grid=Grid, node=Node, opt=#opt{type=Type}, tabs=Tabs}) -> + Table = lists:nth(Index+1, Tabs), + case Table#tab.protection of + private -> + self() ! {error, "Table has 'private' protection and can not be read"}; + _ -> + observer_tv_table:start_link(Grid, [{node,Node}, {type,Type}, {table,Table}]) + end, + {noreply, State}; + +handle_event(#wx{event=#wxList{type=command_list_item_selected, itemIndex=Index}}, + State) -> + {noreply, State#state{selected=Index}}; + +handle_event(#wx{id=?ID_TABLE_INFO}, + State = #state{grid=Grid, node=Node, opt=#opt{type=Type}, tabs=Tabs, selected=Sel}) -> + case Sel of + undefined -> + {noreply, State}; + R when is_integer(R) -> + Table = lists:nth(Sel+1, Tabs), + display_table_info(Grid, Node, Type, Table), + {noreply, State} + end; + +handle_event(#wx{id=?ID_REFRESH_INTERVAL}, + State = #state{grid=Grid, timer=Timer0}) -> + Timer = observer_lib:interval_dialog(Grid, Timer0, 10, 5*60), + {noreply, State#state{timer=Timer}}; + +handle_event(Event, State) -> + io:format("~p:~p, handle event ~p\n", [?MODULE, ?LINE, Event]), + {noreply, State}. + +handle_sync_event(_Event, _Obj, _State) -> + ok. + +handle_call(_Event, _From, State) -> + {noreply, State}. + +handle_cast(_Event, State) -> + {noreply, State}. + +handle_info(refresh_interval, State = #state{node=Node, grid=Grid, opt=Opt}) -> + Tables = get_tables(Node, Opt), + Tabs = update_grid(Grid, Opt, Tables), + {noreply, State#state{tabs=Tabs}}; + +handle_info({active, Node}, State = #state{parent=Parent, grid=Grid, opt=Opt, + timer=Timer0}) -> + Tables = get_tables(Node, Opt), + Tabs = update_grid(Grid, Opt, Tables), + wxWindow:setFocus(Grid), + create_menus(Parent, Opt), + Timer = observer_lib:start_timer(Timer0), + {noreply, State#state{node=Node, tabs=Tabs, timer=Timer}}; + +handle_info(not_active, State = #state{timer = Timer0}) -> + Timer = observer_lib:stop_timer(Timer0), + {noreply, State#state{timer=Timer}}; + +handle_info({node, Node}, State = #state{grid=Grid, opt=Opt}) -> + Tables = get_tables(Node, Opt), + Tabs = update_grid(Grid, Opt, Tables), + wxWindow:setFocus(Grid), + {noreply, State#state{node=Node, tabs=Tabs}}; + +handle_info({error, Error}, State) -> + handle_error(Error), + {noreply, State}; + +handle_info(_Event, State) -> + {noreply, State}. + +terminate(_Event, _State) -> + ok. + +code_change(_, _, State) -> + State. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +create_menus(Parent, #opt{sys_hidden=Sys, unread_hidden=UnR, type=Type}) -> + MenuEntries = [{"View", + [#create_menu{id = ?ID_TABLE_INFO, text = "Table information\tCtrl-I"}, + separator, + #create_menu{id = ?ID_ETS, text = "&Ets Tables", + type=radio, check=Type==ets}, + #create_menu{id = ?ID_MNESIA, text = "&Mnesia Tables", + type=radio, check=Type==mnesia}, + separator, + #create_menu{id = ?ID_UNREADABLE, text = "View &Unreadable Tables", + type=check, check=not UnR}, + #create_menu{id = ?ID_SYSTEM_TABLES, text = "View &System Tables", + type=check, check=not Sys}, + separator, + #create_menu{id = ?ID_REFRESH, text = "Refresh\tCtrl-R"}, + #create_menu{id = ?ID_REFRESH_INTERVAL, text = "Refresh Interval..."} + ]}], + observer_wx:create_menus(Parent, MenuEntries). + +get_tables(Node, Opt) -> + case rpc:call(Node, ?MODULE, get_table_list, [Opt]) of + {badrpc, Error} -> + self() ! {error, Error}, + []; + {error, Error} -> + self() ! {error, Error}, + []; + Result -> + Result + end. + +get_table_list(#opt{type=ets, unread_hidden=HideUnread, sys_hidden=HideSys}) -> + Info = fun(Id, Acc) -> + try + TabId = case ets:info(Id, named_table) of + true -> ignore; + false -> Id + end, + Name = ets:info(Id, name), + Protection = ets:info(Id, protection), + ignore(HideUnread andalso Protection == private, unreadable), + Owner = ets:info(Id, owner), + RegName = case catch process_info(Owner, registered_name) of + [] -> ignore; + {registered_name, ProcName} -> ProcName + end, + ignore(HideSys andalso ordsets:is_element(RegName, sys_processes()), system_tab), + ignore(HideSys andalso ordsets:is_element(Name, sys_tables()), system_tab), + ignore((RegName == mnesia_monitor) + andalso Name /= schema + andalso is_atom((catch mnesia:table_info(Name, where_to_read))), mnesia_tab), + Memory = ets:info(Id, memory) * erlang:system_info(wordsize), + Tab = #tab{name = Name, + id = TabId, + protection = Protection, + owner = Owner, + size = ets:info(Id, size), + reg_name = RegName, + type = ets:info(Id, type), + keypos = ets:info(Id, keypos), + heir = ets:info(Id, heir), + memory = Memory, + compressed = ets:info(Id, compressed), + fixed = ets:info(Id, fixed) + }, + [Tab|Acc] + catch _:_What -> + %% io:format("Skipped ~p: ~p ~n",[Id, _What]), + Acc + end + end, + lists:foldl(Info, [], ets:all()); +get_table_list(#opt{type=mnesia, sys_hidden=HideSys}) -> + Owner = ets:info(schema, owner), + Owner /= undefined orelse + throw({error, "Mnesia is not running on: " ++ atom_to_list(node())}), + {registered_name, RegName} = process_info(Owner, registered_name), + Info = fun(Id, Acc) -> + try + Name = Id, + ignore(HideSys andalso ordsets:is_element(Name, mnesia_tables()), system_tab), + ignore(Name =:= schema, mnesia_tab), + Storage = mnesia:table_info(Id, storage_type), + Tab0 = #tab{name = Name, + owner = Owner, + size = mnesia:table_info(Id, size), + reg_name = RegName, + type = mnesia:table_info(Id, type), + keypos = 2, + memory = mnesia:table_info(Id, memory) * erlang:system_info(wordsize), + storage = Storage, + index = mnesia:table_info(Id, index) + }, + Tab = if Storage == disc_only_copies -> + Tab0#tab{fixed = element(2, dets:info(Id, safe_fixed)) /= []}; + (Storage == ram_copies) orelse + (Storage == disc_copies) -> + Tab0#tab{fixed = ets:info(Id, fixed), + compressed = ets:info(Id, compressed)}; + true -> Tab0 + end, + [Tab|Acc] + catch _:_What -> + %% io:format("Skipped ~p: ~p ~n",[Id, _What]), + Acc + end + end, + lists:foldl(Info, [], mnesia:system_info(tables)). + +display_table_info(Parent0, Node, Source, Table) -> + Parent = observer_lib:get_wx_parent(Parent0), + Title = "Table Info: " ++ atom_to_list(Table#tab.name), + Frame = wxMiniFrame:new(Parent, ?wxID_ANY, Title, + [{style, ?wxSYSTEM_MENU bor ?wxCAPTION + bor ?wxCLOSE_BOX bor ?wxRESIZE_BORDER}]), + + IdInfo = {"Identification and Owner", + [{"Name", Table#tab.name}, + {"Id", case Table#tab.id of + ignore -> Table#tab.name; + Id -> Id + end}, + {"Named table", Table#tab.id == ignore}, + {"Owner", Table#tab.owner}, + {"Owner Name", case Table#tab.reg_name of + ignore -> "-"; + Id -> Id + end}, + {"Heir", Table#tab.heir}, + {"Node", Node}]}, + MnesiaSettings = case Source of + ets -> []; + mnesia -> + [{"Local storage type", case Table#tab.storage of + unknown -> "Not available"; + ST -> ST + end}, + {"Index positions", list_to_strings(Table#tab.index)}] + end, + Settings = {"Settings", + [{"Source", Source}, + {"Key Position", Table#tab.keypos}, + {"Table Type", Table#tab.type}, + {"Protection Mode", Table#tab.protection}, + {"Fixed", Table#tab.fixed} + | MnesiaSettings ]}, + Memory = {"Memory Usage", + [{"Number of objects", Table#tab.size}, + {"Memory allocated", {bytes, Table#tab.memory}}, + {"Compressed", Table#tab.compressed}]}, + + {_, Sizer, _} = observer_lib:display_info(Frame, [IdInfo,Settings,Memory]), + wxSizer:setSizeHints(Sizer, Frame), + wxFrame:center(Frame), + wxFrame:show(Frame). + +list_to_strings([]) -> "None"; +list_to_strings([A]) -> integer_to_list(A); +list_to_strings([A,B]) -> + integer_to_list(A) ++ " ," ++ list_to_strings(B). + +sys_tables() -> + [ac_tab, asn1, + cdv_dump_index_table, cdv_menu_table, cdv_decode_heap_table, + cell_id, cell_pos, clist, + cover_internal_data_table, cover_collected_remote_data_table, cover_binary_code_table, + code, code_names, cookies, + corba_policy, corba_policy_associations, + dets, dets_owners, dets_registry, + disk_log_names, disk_log_pids, + eprof, erl_atom_cache, erl_epmd_nodes, + etop_accum_tab, etop_tr, + ets_coverage_data, + file_io_servers, + gs_mapping, gs_names, gstk_db, + gstk_grid_cellid, gstk_grid_cellpos, gstk_grid_id, + httpd, + id, + ign_req_index, ign_requests, + index, + inet_cache, inet_db, inet_hosts, + 'InitialReferences', + int_db, + interpreter_includedirs_macros, + ir_WstringDef, + lmcounter, locks, +% mnesia_decision, + mnesia_gvar, mnesia_stats, +% mnesia_transient_decision, + pg2_table, + queue, + schema, + shell_records, + snmp_agent_table, snmp_local_db2, snmp_mib_data, snmp_note_store, snmp_symbolic_ets, + tkFun, tkLink, tkPriv, + ttb, ttb_history_table, + udp_fds, udp_pids + ]. + +sys_processes() -> + [auth, code_server, global_name_server, inet_db, + mnesia_recover, net_kernel, timer_server, wxe_master]. + +mnesia_tables() -> + [ir_AliasDef, ir_ArrayDef, ir_AttributeDef, ir_ConstantDef, + ir_Contained, ir_Container, ir_EnumDef, ir_ExceptionDef, + ir_IDLType, ir_IRObject, ir_InterfaceDef, ir_ModuleDef, + ir_ORB, ir_OperationDef, ir_PrimitiveDef, ir_Repository, + ir_SequenceDef, ir_StringDef, ir_StructDef, ir_TypedefDef, + ir_UnionDef, logTable, logTransferTable, mesh_meas, + mesh_type, mnesia_clist, orber_CosNaming, + orber_objkeys, user + ]. + +handle_error(Foo) -> + Str = io_lib:format("ERROR: ~s~n",[Foo]), + observer_lib:display_info_dialog(Str). + +update_grid(Grid, Opt, Tables) -> + wx:batch(fun() -> update_grid2(Grid, Opt, Tables) end). +update_grid2(Grid, #opt{sort_key=Sort,sort_incr=Dir}, Tables) -> + wxListCtrl:deleteAllItems(Grid), + Update = + fun(#tab{name = Name, id = Id, owner = Owner, size = Size, memory = Memory, + protection = Protection, reg_name = RegName}, Row) -> + _Item = wxListCtrl:insertItem(Grid, Row, ""), + if (Row rem 2) =:= 0 -> + wxListCtrl:setItemBackgroundColour(Grid, Row, ?BG_EVEN); + true -> ignore + end, + if Protection == private -> + wxListCtrl:setItemTextColour(Grid, Row, {200,130,50}); + true -> ignore + end, + + lists:foreach(fun({_, ignore}) -> ignore; + ({Col, Val}) -> + wxListCtrl:setItem(Grid, Row, Col, observer_lib:to_str(Val)) + end, + [{0,Name}, {1,Id}, {2,Size}, {3, Memory div 1024}, + {4,Owner}, {5,RegName}]), + Row + 1 + end, + ProcInfo = case Dir of + false -> lists:reverse(lists:keysort(Sort, Tables)); + true -> lists:keysort(Sort, Tables) + end, + lists:foldl(Update, 0, ProcInfo), + ProcInfo. + +ignore(true, Reason) -> throw(Reason); +ignore(_,_ ) -> ok. diff --git a/lib/observer/src/observer_wx.erl b/lib/observer/src/observer_wx.erl new file mode 100644 index 0000000000..f9dec1ab1b --- /dev/null +++ b/lib/observer/src/observer_wx.erl @@ -0,0 +1,537 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2011. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +-module(observer_wx). + +-behaviour(wx_object). + +-export([start/0]). +-export([create_menus/2, get_attrib/1, get_tracer/0, + create_txt_dialog/4, try_rpc/4, return_to_localnode/2]). + +-export([init/1, handle_event/2, handle_cast/2, terminate/2, code_change/3, + handle_call/3, handle_info/2, check_page_title/1]). + +%% Includes +-include_lib("wx/include/wx.hrl"). + +-include("observer_defs.hrl"). + +%% Defines + +-define(ID_PING, 1). +-define(ID_CONNECT, 2). +-define(ID_NOTEBOOK, 3). + +-define(FIRST_NODES_MENU_ID, 1000). +-define(LAST_NODES_MENU_ID, 2000). + +-define(TRACE_STR, "Trace Overview"). + +%% Records +-record(state, + {frame, + menubar, + menus = [], + status_bar, + notebook, + main_panel, + pro_panel, + tv_panel, + sys_panel, + trace_panel, + active_tab, + node, + nodes + }). + +start() -> + wx_object:start(?MODULE, [], []). + +create_menus(Object, Menus) when is_list(Menus) -> + wx_object:call(Object, {create_menus, Menus}). + +get_attrib(What) -> + wx_object:call(observer, {get_attrib, What}). + +get_tracer() -> + wx_object:call(observer, get_tracer). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +init(_Args) -> + register(observer, self()), + wx:new(), + catch wxSystemOptions:setOption("mac.listctrl.always_use_generic", 1), + Frame = wxFrame:new(wx:null(), ?wxID_ANY, "Observer", + [{size, {1000, 500}}, {style, ?wxDEFAULT_FRAME_STYLE}]), + IconFile = filename:join(code:priv_dir(observer), "erlang_observer.png"), + Icon = wxIcon:new(IconFile, [{type,?wxBITMAP_TYPE_PNG}]), + wxFrame:setIcon(Frame, Icon), + wxIcon:destroy(Icon), + + State = #state{frame = Frame}, + UpdState = setup(State), + net_kernel:monitor_nodes(true), + process_flag(trap_exit, true), + {Frame, UpdState}. + +setup(#state{frame = Frame} = State) -> + %% Setup Menubar & Menus + MenuBar = wxMenuBar:new(), + + {Nodes, NodeMenus} = get_nodes(), + DefMenus = default_menus(NodeMenus), + observer_lib:create_menus(DefMenus, MenuBar, default), + + wxFrame:setMenuBar(Frame, MenuBar), + StatusBar = wxFrame:createStatusBar(Frame, []), + wxFrame:setTitle(Frame, atom_to_list(node())), + wxStatusBar:setStatusText(StatusBar, atom_to_list(node())), + + %% Setup panels + Panel = wxPanel:new(Frame, []), + Notebook = wxNotebook:new(Panel, ?ID_NOTEBOOK, [{style, ?wxBK_DEFAULT}]), + + %% System Panel + SysPanel = observer_sys_wx:start_link(Notebook, self()), + wxNotebook:addPage(Notebook, SysPanel, "System", []), + + %% Setup sizer create early to get it when window shows + MainSizer = wxBoxSizer:new(?wxVERTICAL), + + wxSizer:add(MainSizer, Notebook, [{proportion, 1}, {flag, ?wxEXPAND}]), + wxPanel:setSizer(Panel, MainSizer), + + wxNotebook:connect(Notebook, command_notebook_page_changing), + wxFrame:connect(Frame, close_window, [{skip, true}]), + wxMenu:connect(Frame, command_menu_selected), + wxFrame:show(Frame), + + %% I postpone the creation of the other tabs so they can query/use + %% the window size + + %% Process Panel + ProPanel = observer_pro_wx:start_link(Notebook, self()), + wxNotebook:addPage(Notebook, ProPanel, "Processes", []), + + %% Table Viewer Panel + TVPanel = observer_tv_wx:start_link(Notebook, self()), + wxNotebook:addPage(Notebook, TVPanel, "Table Viewer", []), + + %% Trace Viewer Panel + TracePanel = observer_trace_wx:start_link(Notebook, self()), + wxNotebook:addPage(Notebook, TracePanel, ?TRACE_STR, []), + + %% Force redraw (window needs it) + wxWindow:refresh(Panel), + + SysPid = wx_object:get_pid(SysPanel), + SysPid ! {active, node()}, + UpdState = State#state{main_panel = Panel, + notebook = Notebook, + menubar = MenuBar, + status_bar = StatusBar, + sys_panel = SysPanel, + pro_panel = ProPanel, + tv_panel = TVPanel, + trace_panel = TracePanel, + active_tab = SysPid, + node = node(), + nodes = Nodes + }, + %% Create resources which we don't want to duplicate + SysFont = wxSystemSettings:getFont(?wxSYS_DEFAULT_GUI_FONT), + SysFontSize = wxFont:getPointSize(SysFont), + Modern = wxFont:new(SysFontSize, ?wxFONTFAMILY_MODERN, ?wxFONTSTYLE_NORMAL, ?wxFONTWEIGHT_NORMAL), + put({font, modern}, Modern), + put({font, fixed}, Modern), + UpdState. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%Callbacks +handle_event(#wx{event=#wxNotebook{type=command_notebook_page_changing}}, + #state{active_tab=Previous, node=Node} = State) -> + Pid = get_active_pid(State), + Previous ! not_active, + Pid ! {active, Node}, + {noreply, State#state{active_tab=Pid}}; + +handle_event(#wx{event = #wxClose{}}, State) -> + {stop, normal, State}; + +handle_event(#wx{id = ?wxID_EXIT, event = #wxCommand{type = command_menu_selected}}, State) -> + {stop, normal, State}; + +handle_event(#wx{id = ?wxID_HELP, event = #wxCommand{type = command_menu_selected}}, State) -> + External = "http://www.erlang.org/doc/apps/observer/index.html", + Internal = filename:join([code:lib_dir(observer),"doc", "html", "index.html"]), + Help = case filelib:is_file(Internal) of + true -> Internal; + false -> External + end, + wx_misc:launchDefaultBrowser(Help) orelse + create_txt_dialog(State#state.frame, "Could not launch browser: ~n " ++ Help, + "Error", ?wxICON_ERROR), + {noreply, State}; + +handle_event(#wx{id = ?wxID_ABOUT, event = #wxCommand{type = command_menu_selected}}, + State = #state{frame=Frame}) -> + AboutString = "Observe an erlang system\n" + "Authors: Olle Mattson & Magnus Eriksson & Dan Gudmundsson", + Style = [{style, ?wxOK bor ?wxSTAY_ON_TOP}, + {caption, "About"}], + wxMessageDialog:showModal(wxMessageDialog:new(Frame, AboutString, Style)), + {noreply, State}; + + +handle_event(#wx{id = ?ID_CONNECT, event = #wxCommand{type = command_menu_selected}}, + #state{frame = Frame} = State) -> + UpdState = case create_connect_dialog(connect, State) of + cancel -> + State; + {value, [], _, _} -> + create_txt_dialog(Frame, "Node must have a name", + "Error", ?wxICON_ERROR), + State; + {value, NodeName, LongOrShort, Cookie} -> %Shortname, + try + case connect(list_to_atom(NodeName), LongOrShort, list_to_atom(Cookie)) of + {ok, set_cookie} -> + change_node_view(node(), State); + {error, set_cookie} -> + create_txt_dialog(Frame, "Could not set cookie", + "Error", ?wxICON_ERROR), + State; + {error, net_kernel, _Reason} -> + create_txt_dialog(Frame, "Could not enable node", + "Error", ?wxICON_ERROR), + State + end + catch _:_ -> + create_txt_dialog(Frame, "Could not enable node", + "Error", ?wxICON_ERROR), + State + end + end, + {noreply, UpdState}; + +handle_event(#wx{id = ?ID_PING, event = #wxCommand{type = command_menu_selected}}, + #state{frame = Frame} = State) -> + UpdState = case create_connect_dialog(ping, State) of + cancel -> State; + {value, Value} when is_list(Value) -> + try + Node = list_to_atom(Value), + case net_adm:ping(Node) of + pang -> + create_txt_dialog(Frame, "Connect failed", "Pang", ?wxICON_EXCLAMATION), + State; + pong -> + change_node_view(Node, State) + end + catch _:_ -> + create_txt_dialog(Frame, "Connect failed", "Pang", ?wxICON_EXCLAMATION), + State + end + end, + {noreply, UpdState}; + +handle_event(#wx{id = Id, event = #wxCommand{type = command_menu_selected}}, State) + when Id > ?FIRST_NODES_MENU_ID, Id < ?LAST_NODES_MENU_ID -> + + Node = lists:nth(Id - ?FIRST_NODES_MENU_ID, State#state.nodes), + UpdState = change_node_view(Node, State), + {noreply, UpdState}; + +handle_event(Event, State) -> + Pid = get_active_pid(State), + Pid ! Event, + {noreply, State}. + +handle_cast(_Cast, State) -> + {noreply, State}. + +handle_call({create_menus, TabMenus}, _From, + State = #state{menubar=MenuBar, menus=PrevTabMenus}) -> + wx:batch(fun() -> + clean_menus(PrevTabMenus, MenuBar), + observer_lib:create_menus(TabMenus, MenuBar, plugin) + end), + {reply, ok, State#state{menus=TabMenus}}; + +handle_call({get_attrib, Attrib}, _From, State) -> + {reply, get(Attrib), State}; + +handle_call(get_tracer, _From, State=#state{trace_panel=TraceP}) -> + {reply, TraceP, State}; + +handle_call(_Msg, _From, State) -> + {reply, ok, State}. + +handle_info({nodeup, _Node}, State) -> + State2 = update_node_list(State), + {noreply, State2}; + +handle_info({nodedown, Node}, + #state{frame = Frame} = State) -> + State2 = case Node =:= State#state.node of + true -> + change_node_view(node(), State); + false -> + State + end, + State3 = update_node_list(State2), + Msg = ["Node down: " | atom_to_list(Node)], + create_txt_dialog(Frame, Msg, "Node down", ?wxICON_EXCLAMATION), + {noreply, State3}; + +handle_info(_Info, State) -> + {noreply, State}. + +terminate(_Reason, #state{frame = Frame}) -> + wxFrame:destroy(Frame), + ok. + +code_change(_, _, State) -> + {stop, not_yet_implemented, State}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +try_rpc(Node, Mod, Func, Args) -> + case + rpc:call(Node, Mod, Func, Args) of + {badrpc, Reason} -> + error_logger:error_report([{node, Node}, + {call, {Mod, Func, Args}}, + {reason, {badrpc, Reason}}]), + error({badrpc, Reason}); + Res -> + Res + end. + +return_to_localnode(Frame, Node) -> + case node() =/= Node of + true -> + create_txt_dialog(Frame, "Error occured on remote node", + "Error", ?wxICON_ERROR), + disconnect_node(Node); + false -> + ok + end. + +create_txt_dialog(Frame, Msg, Title, Style) -> + MD = wxMessageDialog:new(Frame, Msg, [{style, Style}]), + wxMessageDialog:setTitle(MD, Title), + wxDialog:showModal(MD), + wxDialog:destroy(MD). + +connect(NodeName, 0, Cookie) -> + connect2(NodeName, shortnames, Cookie); +connect(NodeName, 1, Cookie) -> + connect2(NodeName, longnames, Cookie). + +connect2(NodeName, Opts, Cookie) -> + case net_adm:names() of + {ok, _} -> %% Epmd is running + ok; + {error, address} -> + Epmd = os:find_executable("epmd"), + os:cmd(Epmd) + end, + case net_kernel:start([NodeName, Opts]) of + {ok, _} -> + case is_alive() of + true -> + erlang:set_cookie(node(), Cookie), + {ok, set_cookie}; + false -> + {error, set_cookie} + end; + {error, Reason} -> + {error, net_kernel, Reason} + end. + +change_node_view(Node, State = #state{pro_panel=Pro, sys_panel=Sys, tv_panel=Tv}) -> + lists:foreach(fun(Pid) -> wx_object:get_pid(Pid) ! {node, Node} end, + [Pro, Sys, Tv]), + StatusText = ["Observer - " | atom_to_list(Node)], + wxFrame:setTitle(State#state.frame, StatusText), + wxStatusBar:setStatusText(State#state.status_bar, StatusText), + State#state{node = Node}. + +check_page_title(Notebook) -> + Selection = wxNotebook:getSelection(Notebook), + wxNotebook:getPageText(Notebook, Selection). + +get_active_pid(#state{notebook=Notebook, pro_panel=Pro, sys_panel=Sys, tv_panel=Tv, trace_panel=Trace}) -> + Panel = case check_page_title(Notebook) of + "Processes" -> Pro; + "System" -> Sys; + "Table Viewer" -> Tv; + ?TRACE_STR -> Trace + end, + wx_object:get_pid(Panel). + +create_connect_dialog(ping, #state{frame = Frame}) -> + Dialog = wxTextEntryDialog:new(Frame, "Connect to node"), + case wxDialog:showModal(Dialog) of + ?wxID_OK -> + Value = wxTextEntryDialog:getValue(Dialog), + wxDialog:destroy(Dialog), + {value, Value}; + ?wxID_CANCEL -> + wxDialog:destroy(Dialog), + cancel + end; +create_connect_dialog(connect, #state{frame = Frame}) -> + Dialog = wxDialog:new(Frame, ?wxID_ANY, "Distribute node "), + + VSizer = wxBoxSizer:new(?wxVERTICAL), + RadioBoxSizer = wxBoxSizer:new(?wxHORIZONTAL), + + Choices = ["Short name", "Long name"], + RadioBox = wxRadioBox:new(Dialog, 1, "", + ?wxDefaultPosition, + ?wxDefaultSize, + Choices, + [{majorDim, 2}, + {style, ?wxHORIZONTAL}]), + + NameText = wxStaticText:new(Dialog, ?wxID_ANY, "Node name: "), + NameCtrl = wxTextCtrl:new(Dialog, ?wxID_ANY, [{size, {200, 25}}]), + wxTextCtrl:setValue(NameCtrl, "observer"), + CookieText = wxStaticText:new(Dialog, ?wxID_ANY, "Secret cookie: "), + CookieCtrl = wxTextCtrl:new(Dialog, ?wxID_ANY, + [{size, {200, 25}}, {style, ?wxTE_PASSWORD}]), + + BtnSizer = wxDialog:createStdDialogButtonSizer(Dialog, ?wxID_DEFAULT), + Flags = [{flag, ?wxEXPAND bor ?wxALL}, {border, 5}], + wxSizer:add(RadioBoxSizer, RadioBox, Flags), + + wxSizer:add(VSizer, RadioBoxSizer, Flags), + wxSizer:addSpacer(VSizer, 10), + wxSizer:add(VSizer, NameText), + wxSizer:add(VSizer, NameCtrl, Flags), + wxSizer:addSpacer(VSizer, 10), + wxSizer:add(VSizer, CookieText), + wxSizer:add(VSizer, CookieCtrl, Flags), + wxSizer:addSpacer(VSizer, 10), + wxSizer:add(VSizer, BtnSizer, [{flag, ?wxALIGN_LEFT}]), + + wxWindow:setSizer(Dialog, VSizer), + CookiePath = filename:join(os:getenv("HOME"), ".erlang.cookie"), + DefaultCookie = case filelib:is_file(CookiePath) of + true -> + {ok, Bin} = file:read_file(CookiePath), + binary_to_list(Bin); + false -> + "" + end, + wxTextCtrl:setValue(CookieCtrl, DefaultCookie), + case wxDialog:showModal(Dialog) of + ?wxID_OK -> + NameValue = wxTextCtrl:getValue(NameCtrl), + NameLngthValue = wxRadioBox:getSelection(RadioBox), + CookieValue = wxTextCtrl:getValue(CookieCtrl), + wxDialog:destroy(Dialog), + {value, NameValue, NameLngthValue, CookieValue}; + ?wxID_CANCEL -> + wxDialog:destroy(Dialog), + cancel + end. + +default_menus(NodesMenuItems) -> + Quit = #create_menu{id = ?wxID_EXIT, text = "Quit"}, + About = #create_menu{id = ?wxID_ABOUT, text = "About"}, + Help = #create_menu{id = ?wxID_HELP}, + NodeMenu = case erlang:is_alive() of + true -> {"Nodes", NodesMenuItems ++ + [#create_menu{id = ?ID_PING, text = "Connect Node"}]}; + false -> {"Nodes", NodesMenuItems ++ + [#create_menu{id = ?ID_CONNECT, text = "Enable distribution"}]} + end, + case os:type() =:= {unix, darwin} of + false -> + FileMenu = {"File", [Quit]}, + HelpMenu = {"Help", [About,Help]}, + [FileMenu, NodeMenu, HelpMenu]; + true -> + %% On Mac quit and about will be moved to the "default' place + %% automagicly, so just add them to a menu that always exist. + %% But not to the help menu for some reason + {Tag, Menus} = NodeMenu, + [{Tag, Menus ++ [Quit,About]}, {"&Help", [Help]}] + end. + +clean_menus(Menus, MenuBar) -> + remove_menu_items(Menus, MenuBar). + +remove_menu_items([{MenuStr = "File", Menus}|Rest], MenuBar) -> + MenuId = wxMenuBar:findMenu(MenuBar, MenuStr), + Menu = wxMenuBar:getMenu(MenuBar, MenuId), + Items = [wxMenu:findItem(Menu, Tag) || #create_menu{text=Tag} <- Menus], + [wxMenu:delete(Menu, MItem) || MItem <- Items], + case os:type() =:= {unix, darwin} of + true -> + wxMenuBar:remove(MenuBar, MenuId), + wxMenu:destroy(Menu); + false -> + ignore + end, + remove_menu_items(Rest, MenuBar); +remove_menu_items([{"Nodes", _}|_], _MB) -> + ok; +remove_menu_items([{Tag, _Menus}|Rest], MenuBar) -> + MenuId = wxMenuBar:findMenu(MenuBar, Tag), + Menu = wxMenuBar:getMenu(MenuBar, MenuId), + wxMenuBar:remove(MenuBar, MenuId), + Items = wxMenu:getMenuItems(Menu), + [wxMenu:'Destroy'(Menu, Item) || Item <- Items], + wxMenu:destroy(Menu), + remove_menu_items(Rest, MenuBar); +remove_menu_items([], _MB) -> + ok. + +get_nodes() -> + Nodes = [node()| nodes()], + {_, Menues} = + lists:foldl(fun(Node, {Id, Acc}) when Id < ?LAST_NODES_MENU_ID -> + {Id + 1, [#create_menu{id=Id + ?FIRST_NODES_MENU_ID, + text=atom_to_list(Node)} | Acc]} + end, {1, []}, Nodes), + {Nodes, lists:reverse(Menues)}. + +update_node_list(State = #state{menubar=MenuBar}) -> + {Nodes, NodesMenuItems} = get_nodes(), + NodeMenuId = wxMenuBar:findMenu(MenuBar, "Nodes"), + NodeMenu = wxMenuBar:getMenu(MenuBar, NodeMenuId), + wx:foreach(fun(Item) -> wxMenu:'Destroy'(NodeMenu, Item) end, + wxMenu:getMenuItems(NodeMenu)), + + Index = wx:foldl(fun(Record, Index) -> + observer_lib:create_menu_item(Record, NodeMenu, Index) + end, 0, NodesMenuItems), + + Dist = case erlang:is_alive() of + true -> #create_menu{id = ?ID_PING, text = "Connect node"}; + false -> #create_menu{id = ?ID_CONNECT, text = "Enable distribution"} + end, + observer_lib:create_menu_item(Dist, NodeMenu, Index), + State#state{nodes = Nodes}. diff --git a/lib/observer/src/ttb.erl b/lib/observer/src/ttb.erl index 1471be92e5..61fd6d1787 100644 --- a/lib/observer/src/ttb.erl +++ b/lib/observer/src/ttb.erl @@ -75,29 +75,41 @@ do_tracer(Nodes0,PI,Client,Traci) -> do_tracer(Clients,PI,Traci). do_tracer(Clients,PI,Traci) -> - ShellOutput = proplists:get_value(shell, Traci, false), - {ClientSucc,Succ} = + Shell = proplists:get_value(shell, Traci, false), + DefShell = fun(Trace) -> dbg:dhandler(Trace, standard_io) end, + {ClientSucc,Succ} = lists:foldl( - fun({N,{local,File},TF},{CS,S}) -> - TF2 = case ShellOutput of - only -> none; - _ -> TF - end, - [_Sname,Host] = string:tokens(atom_to_list(N),"@"), + fun({N,{local,File},TF},{CS,S}) -> + {TF2, FileInfo, ShellOutput} = + case Shell of + only -> {none, shell_only, DefShell}; + true -> {TF, {file,File}, DefShell}; + {only,Fun} -> {none, shell_only, Fun}; + Fun when is_function(Fun) -> {TF, {file,File}, Fun}; + _ -> {TF, {file,File}, false} + end, + Host = case N of + nonode@nohost -> + {ok, H} = inet:gethostname(), + H; + _ -> + [_,H] = string:tokens(atom_to_list(N),"@"), + H + end, case catch dbg:tracer(N,port,dbg:trace_port(ip,0)) of {ok,N} -> {ok,Port} = dbg:trace_port_control(N,get_listen_port), {ok,T} = dbg:get_tracer(N), rpc:call(N,seq_trace,set_system_tracer,[T]), dbg:trace_client(ip,{Host,Port}, - {fun ip_to_file/2,{{file,File}, ShellOutput}}), + {fun ip_to_file/2,{FileInfo, ShellOutput}}), {[{N,{local,File,Port},TF2}|CS], [N|S]}; Other -> display_warning(N,{cannot_open_ip_trace_port, Host, Other}), {CS, S} - end; + end; ({N,C,_}=Client,{CS,S}) -> case catch dbg:tracer(N,port,dbg:trace_port(file,C)) of {ok,N} -> @@ -620,7 +632,7 @@ stop_opts(Opts) -> case {FormatData, lists:member(return_fetch_dir, Opts)} of {false, true} -> {fetch, FetchDir}; % if we specify return_fetch_dir, the data should be fetched - {false, false} -> + {false, false} -> case lists:member(nofetch,Opts) of false -> {fetch, FetchDir}; true -> nofetch @@ -1275,10 +1287,10 @@ display_warning(Item,Warning) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Trace client which reads an IP port and puts data directly to a file. %%% This is used when tracing remote nodes with no file system. -ip_to_file({metadata,_,_},{_, only} = State) -> +ip_to_file({metadata,_,_},{shell_only, _} = State) -> State; -ip_to_file(Trace, {_, only} = State) -> - dbg:dhandler(Trace, standard_io), +ip_to_file(Trace, {shell_only, Fun} = State) -> + Fun(Trace), State; ip_to_file(Trace,{{file,File}, ShellOutput}) -> Fun = dbg:trace_port(file,File), %File can be a filename or a wrap spec @@ -1302,8 +1314,8 @@ ip_to_file(Trace,{Port, ShellOutput}) -> erlang:port_command(Port,B), {Port, ShellOutput}. -show_trace(Trace, true) -> - dbg:dhandler(Trace, standard_io); +show_trace(Trace, Fun) when is_function(Fun) -> + Fun(Trace); show_trace(_, _) -> ok. diff --git a/lib/observer/test/crashdump_helper.erl b/lib/observer/test/crashdump_helper.erl index d1c65f97e8..520fcdfd0d 100644 --- a/lib/observer/test/crashdump_helper.erl +++ b/lib/observer/test/crashdump_helper.erl @@ -19,7 +19,7 @@ -module(crashdump_helper). -export([n1_proc/2,remote_proc/2]). --compile(r12). +-compile(r13). -include("test_server.hrl"). n1_proc(N2,Creator) -> diff --git a/lib/observer/test/crashdump_viewer_SUITE.erl b/lib/observer/test/crashdump_viewer_SUITE.erl index fdc4a2f1ff..79ece7edf5 100644 --- a/lib/observer/test/crashdump_viewer_SUITE.erl +++ b/lib/observer/test/crashdump_viewer_SUITE.erl @@ -70,7 +70,7 @@ init_per_suite(Config) when is_list(Config) -> application:start(inets), % will be using the http client later httpc:set_options([{ipfamily,inet6fb4}]), DataDir = ?config(data_dir,Config), - Rels = [R || R <- [r12b,r13b], ?t:is_release_available(R)] ++ [current], + Rels = [R || R <- [r13b,r14b], ?t:is_release_available(R)] ++ [current], io:format("Creating crash dumps for the following releases: ~p", [Rels]), AllDumps = create_dumps(DataDir,Rels), ?t:timetrap_cancel(Dog), @@ -722,7 +722,8 @@ dump_prefix(Rel) -> r11b -> "r11b_dump."; r12b -> "r12b_dump."; r13b -> "r13b_dump."; - current -> "r14b_dump." + r14b -> "r14b_dump."; + current -> "r15b_dump." end. compat_rel(Rel) -> @@ -733,5 +734,6 @@ compat_rel(Rel) -> r11b -> "+R11 "; r12b -> "+R12 "; r13b -> "+R13 "; + r14b -> "+R13 "; current -> "" end. diff --git a/lib/odbc/aclocal.m4 b/lib/odbc/aclocal.m4 index 151fd5ea5a..339a15a2bb 120000..100644 --- a/lib/odbc/aclocal.m4 +++ b/lib/odbc/aclocal.m4 @@ -1 +1,1766 @@ -../../erts/aclocal.m4
\ No newline at end of file +dnl +dnl %CopyrightBegin% +dnl +dnl Copyright Ericsson AB 1998-2011. All Rights Reserved. +dnl +dnl The contents of this file are subject to the Erlang Public License, +dnl Version 1.1, (the "License"); you may not use this file except in +dnl compliance with the License. You should have received a copy of the +dnl Erlang Public License along with this software. If not, it can be +dnl retrieved online at http://www.erlang.org/. +dnl +dnl Software distributed under the License is distributed on an "AS IS" +dnl basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +dnl the License for the specific language governing rights and limitations +dnl under the License. +dnl +dnl %CopyrightEnd% +dnl + +dnl +dnl aclocal.m4 +dnl +dnl Local macros used in configure.in. The Local Macros which +dnl could/should be part of autoconf are prefixed LM_, macros specific +dnl to the Erlang system are prefixed ERL_. +dnl + +AC_DEFUN(LM_PRECIOUS_VARS, +[ + +dnl ERL_TOP +AC_ARG_VAR(ERL_TOP, [Erlang/OTP top source directory]) + +dnl Tools +AC_ARG_VAR(CC, [C compiler]) +AC_ARG_VAR(CFLAGS, [C compiler flags]) +AC_ARG_VAR(STATIC_CFLAGS, [C compiler static flags]) +AC_ARG_VAR(CFLAG_RUNTIME_LIBRARY_PATH, [runtime library path linker flag passed via C compiler]) +AC_ARG_VAR(CPP, [C/C++ preprocessor]) +AC_ARG_VAR(CPPFLAGS, [C/C++ preprocessor flags]) +AC_ARG_VAR(CXX, [C++ compiler]) +AC_ARG_VAR(CXXFLAGS, [C++ compiler flags]) +AC_ARG_VAR(LD, [linker (is often overridden by configure)]) +AC_ARG_VAR(LDFLAGS, [linker flags (can be risky to set since LD may be overriden by configure)]) +AC_ARG_VAR(LIBS, [libraries]) +AC_ARG_VAR(DED_LD, [linker for Dynamic Erlang Drivers (set all DED_LD* variables or none)]) +AC_ARG_VAR(DED_LDFLAGS, [linker flags for Dynamic Erlang Drivers (set all DED_LD* variables or none)]) +AC_ARG_VAR(DED_LD_FLAG_RUNTIME_LIBRARY_PATH, [runtime library path linker flag for Dynamic Erlang Drivers (set all DED_LD* variables or none)]) +AC_ARG_VAR(LFS_CFLAGS, [large file support C compiler flags (set all LFS_* variables or none)]) +AC_ARG_VAR(LFS_LDFLAGS, [large file support linker flags (set all LFS_* variables or none)]) +AC_ARG_VAR(LFS_LIBS, [large file support libraries (set all LFS_* variables or none)]) +AC_ARG_VAR(RANLIB, [ranlib]) +AC_ARG_VAR(AR, [ar]) +AC_ARG_VAR(GETCONF, [getconf]) + +dnl Cross system root +AC_ARG_VAR(erl_xcomp_sysroot, [Absolute cross system root path (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_isysroot, [Absolute cross system root include path (only used when cross compiling)]) + +dnl Cross compilation variables +AC_ARG_VAR(erl_xcomp_bigendian, [big endian system: yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_linux_clock_gettime_correction, [clock_gettime() can be used for time correction: yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_linux_nptl, [have Native POSIX Thread Library: yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_linux_usable_sigusrx, [SIGUSR1 and SIGUSR2 can be used: yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_linux_usable_sigaltstack, [have working sigaltstack(): yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_poll, [have working poll(): yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_kqueue, [have working kqueue(): yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_putenv_copy, [putenv() stores key-value copy: yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_reliable_fpe, [have reliable floating point exceptions: yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_getaddrinfo, [have working getaddrinfo() for both IPv4 and IPv6: yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_gethrvtime_procfs_ioctl, [have working gethrvtime() which can be used with procfs ioctl(): yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_clock_gettime_cpu_time, [clock_gettime() can be used for retrieving process CPU time: yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_after_morecore_hook, [__after_morecore_hook can track malloc()s core memory usage: yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_dlsym_brk_wrappers, [dlsym(RTLD_NEXT, _) brk wrappers can track malloc()s core memory usage: yes|no (only used when cross compiling)]) + +]) + +AC_DEFUN(ERL_XCOMP_SYSROOT_INIT, +[ +erl_xcomp_without_sysroot=no +if test "$cross_compiling" = "yes"; then + test "$erl_xcomp_sysroot" != "" || erl_xcomp_without_sysroot=yes + test "$erl_xcomp_isysroot" != "" || erl_xcomp_isysroot="$erl_xcomp_sysroot" +else + erl_xcomp_sysroot= + erl_xcomp_isysroot= +fi +]) + +AC_DEFUN(LM_CHECK_GETCONF, +[ +if test "$cross_compiling" != "yes"; then + AC_CHECK_PROG([GETCONF], [getconf], [getconf], [false]) +else + dnl First check if we got a `<HOST>-getconf' in $PATH + host_getconf="$host_alias-getconf" + AC_CHECK_PROG([GETCONF], [$host_getconf], [$host_getconf], [false]) + if test "$GETCONF" = "false" && test "$erl_xcomp_sysroot" != ""; then + dnl We should perhaps give up if we have'nt found it by now, but at + dnl least in one Tilera MDE `getconf' under sysroot is a bourne + dnl shell script which we can use. We try to find `<HOST>-getconf' + dnl or `getconf' under sysconf, but only under sysconf since + dnl `getconf' in $PATH is almost guaranteed to be for the build + dnl machine. + GETCONF= + prfx="$erl_xcomp_sysroot" + AC_PATH_TOOL([GETCONF], [getconf], [false], + ["$prfx/usr/bin:$prfx/bin:$prfx/usr/local/bin"]) + fi +fi +]) + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_WINDOWS_ENVIRONMENT +dnl +dnl +dnl Tries to determine thw windows build environment, i.e. +dnl MIXED_CYGWIN_VC or MIXED_MSYS_VC +dnl + +AC_DEFUN(LM_WINDOWS_ENVIRONMENT, +[ +MIXED_CYGWIN=no +MIXED_MSYS=no + +AC_MSG_CHECKING(for mixed cygwin or msys and native VC++ environment) +if test "X$host" = "Xwin32" -a "x$GCC" != "xyes"; then + if test -x /usr/bin/cygpath; then + CFLAGS="-O2" + MIXED_CYGWIN=yes + AC_MSG_RESULT([Cygwin and VC]) + MIXED_CYGWIN_VC=yes + CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_VC" + elif test -x /usr/bin/msysinfo; then + CFLAGS="-O2" + MIXED_MSYS=yes + AC_MSG_RESULT([MSYS and VC]) + MIXED_MSYS_VC=yes + CPPFLAGS="$CPPFLAGS -DERTS_MIXED_MSYS_VC" + else + AC_MSG_RESULT([undeterminable]) + AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!) + fi +else + AC_MSG_RESULT([no]) + MIXED_CYGWIN_VC=no + MIXED_MSYS_VC=no +fi +AC_SUBST(MIXED_CYGWIN_VC) +AC_SUBST(MIXED_MSYS_VC) + +MIXED_VC=no +if test "x$MIXED_MSYS_VC" = "xyes" -o "x$MIXED_CYGWIN_VC" = "xyes" ; then + MIXED_VC=yes +fi + +AC_SUBST(MIXED_VC) + +if test "x$MIXED_MSYS" != "xyes"; then + AC_MSG_CHECKING(for mixed cygwin and native MinGW environment) + if test "X$host" = "Xwin32" -a "x$GCC" = x"yes"; then + if test -x /usr/bin/cygpath; then + CFLAGS="-O2" + MIXED_CYGWIN=yes + AC_MSG_RESULT([yes]) + MIXED_CYGWIN_MINGW=yes + CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_MINGW" + else + AC_MSG_RESULT([undeterminable]) + AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!) + fi + else + AC_MSG_RESULT([no]) + MIXED_CYGWIN_MINGW=no + fi +else + MIXED_CYGWIN_MINGW=no +fi +AC_SUBST(MIXED_CYGWIN_MINGW) + +AC_MSG_CHECKING(if we mix cygwin with any native compiler) +if test "X$MIXED_CYGWIN" = "Xyes"; then + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + +AC_SUBST(MIXED_CYGWIN) + +AC_MSG_CHECKING(if we mix msys with another native compiler) +if test "X$MIXED_MSYS" = "Xyes" ; then + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + +AC_SUBST(MIXED_MSYS) +]) + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_FIND_EMU_CC +dnl +dnl +dnl Tries fairly hard to find a C compiler that can handle jump tables. +dnl Defines the @EMU_CC@ variable for the makefiles and +dnl inserts NO_JUMP_TABLE in the header if one cannot be found... +dnl + +AC_DEFUN(LM_FIND_EMU_CC, + [AC_CACHE_CHECK(for a compiler that handles jumptables, + ac_cv_prog_emu_cc, + [ +AC_TRY_COMPILE([],[ +#if defined(__clang_major__) && __clang_major__ >= 3 + /* clang 3.x or later is fine */ +#elif defined(__llvm__) +#error "this version of llvm is unable to correctly compile beam_emu.c" +#endif + __label__ lbl1; + __label__ lbl2; + int x = magic(); + static void *jtab[2]; + + jtab[0] = &&lbl1; + jtab[1] = &&lbl2; + goto *jtab[x]; +lbl1: + return 1; +lbl2: + return 2; +],ac_cv_prog_emu_cc=$CC,ac_cv_prog_emu_cc=no) + +if test $ac_cv_prog_emu_cc = no; then + for ac_progname in emu_cc.sh gcc-4.2 gcc; do + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_progname; then + ac_cv_prog_emu_cc=$ac_dir/$ac_progname + break + fi + done + IFS="$ac_save_ifs" + if test $ac_cv_prog_emu_cc != no; then + break + fi + done +fi + +if test $ac_cv_prog_emu_cc != no; then + save_CC=$CC + save_CFLAGS=$CFLAGS + save_CPPFLAGS=$CPPFLAGS + CC=$ac_cv_prog_emu_cc + CFLAGS="" + CPPFLAGS="" + AC_TRY_COMPILE([],[ +#if defined(__clang_major__) && __clang_major__ >= 3 + /* clang 3.x or later is fine */ +#elif defined(__llvm__) +#error "this version of llvm is unable to correctly compile beam_emu.c" +#endif + __label__ lbl1; + __label__ lbl2; + int x = magic(); + static void *jtab[2]; + + jtab[0] = &&lbl1; + jtab[1] = &&lbl2; + goto *jtab[x]; + lbl1: + return 1; + lbl2: + return 2; + ],ac_cv_prog_emu_cc=$CC,ac_cv_prog_emu_cc=no) + CC=$save_CC + CFLAGS=$save_CFLAGS + CPPFLAGS=$save_CPPFLAGS +fi +]) +if test $ac_cv_prog_emu_cc = no; then + AC_DEFINE(NO_JUMP_TABLE,[],[Defined if no found C compiler can handle jump tables]) + EMU_CC=$CC +else + EMU_CC=$ac_cv_prog_emu_cc +fi +AC_SUBST(EMU_CC) +]) + + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_PROG_INSTALL_DIR +dnl +dnl This macro may be used by any OTP application. +dnl +dnl Figure out how to create directories with parents. +dnl (In my opinion INSTALL_DIR is a bad name, MKSUBDIRS or something is better) +dnl +dnl We prefer 'install -d', but use 'mkdir -p' if it exists. +dnl If none of these methods works, we give up. +dnl + + +AC_DEFUN(LM_PROG_INSTALL_DIR, +[AC_CACHE_CHECK(how to create a directory including parents, +ac_cv_prog_mkdir_p, +[ +temp_name_base=config.$$ +temp_name=$temp_name_base/x/y/z +$INSTALL -d $temp_name >/dev/null 2>&1 +ac_cv_prog_mkdir_p=none +if test -d $temp_name; then + ac_cv_prog_mkdir_p="$INSTALL -d" +else + mkdir -p $temp_name >/dev/null 2>&1 + if test -d $temp_name; then + ac_cv_prog_mkdir_p="mkdir -p" + fi +fi +rm -fr $temp_name_base +]) + +case "${ac_cv_prog_mkdir_p}" in + none) AC_MSG_ERROR(don't know how create directories with parents) ;; + *) INSTALL_DIR="$ac_cv_prog_mkdir_p" AC_SUBST(INSTALL_DIR) ;; +esac +]) + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_PROG_PERL5 +dnl +dnl Try to find perl version 5. If found set PERL to the absolute path +dnl of the program, if not found set PERL to false. +dnl +dnl On some systems /usr/bin/perl is perl 4 and e.g. +dnl /usr/local/bin/perl is perl 5. We try to handle this case by +dnl putting a couple of +dnl Tries to handle the case that there are two programs called perl +dnl in the path and one of them is perl 5 and the other isn't. +dnl +AC_DEFUN(LM_PROG_PERL5, +[AC_PATH_PROGS(PERL, perl5 perl, false, + /usr/local/bin:/opt/local/bin:/usr/local/gnu/bin:${PATH}) +changequote(, )dnl +dnl[ That bracket is needed to balance the right bracket below +if test "$PERL" = "false" || $PERL -e 'exit ($] >= 5)'; then +changequote([, ])dnl + ac_cv_path_PERL=false + PERL=false +dnl AC_MSG_WARN(perl version 5 not found) +fi +])dnl + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_DECL_SO_BSDCOMPAT +dnl +dnl Check if the system has the SO_BSDCOMPAT flag on sockets (linux) +dnl +AC_DEFUN(LM_DECL_SO_BSDCOMPAT, +[AC_CACHE_CHECK([for SO_BSDCOMPAT declaration], ac_cv_decl_so_bsdcompat, +AC_TRY_COMPILE([#include <sys/socket.h>], [int i = SO_BSDCOMPAT;], + ac_cv_decl_so_bsdcompat=yes, + ac_cv_decl_so_bsdcompat=no)) + +case "${ac_cv_decl_so_bsdcompat}" in + "yes" ) AC_DEFINE(HAVE_SO_BSDCOMPAT,[], + [Define if you have SO_BSDCOMPAT flag on sockets]) ;; + * ) ;; +esac +]) + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_DECL_INADDR_LOOPBACK +dnl +dnl Try to find declaration of INADDR_LOOPBACK, if nowhere provide a default +dnl + +AC_DEFUN(LM_DECL_INADDR_LOOPBACK, +[AC_CACHE_CHECK([for INADDR_LOOPBACK in netinet/in.h], + ac_cv_decl_inaddr_loopback, +[AC_TRY_COMPILE([#include <sys/types.h> +#include <netinet/in.h>], [int i = INADDR_LOOPBACK;], +ac_cv_decl_inaddr_loopback=yes, ac_cv_decl_inaddr_loopback=no) +]) + +if test ${ac_cv_decl_inaddr_loopback} = no; then + AC_CACHE_CHECK([for INADDR_LOOPBACK in rpc/types.h], + ac_cv_decl_inaddr_loopback_rpc, + AC_TRY_COMPILE([#include <rpc/types.h>], + [int i = INADDR_LOOPBACK;], + ac_cv_decl_inaddr_loopback_rpc=yes, + ac_cv_decl_inaddr_loopback_rpc=no)) + + case "${ac_cv_decl_inaddr_loopback_rpc}" in + "yes" ) + AC_DEFINE(DEF_INADDR_LOOPBACK_IN_RPC_TYPES_H,[], + [Define if you need to include rpc/types.h to get INADDR_LOOPBACK defined]) ;; + * ) + AC_CACHE_CHECK([for INADDR_LOOPBACK in winsock2.h], + ac_cv_decl_inaddr_loopback_winsock2, + AC_TRY_COMPILE([#define WIN32_LEAN_AND_MEAN + #include <winsock2.h>], + [int i = INADDR_LOOPBACK;], + ac_cv_decl_inaddr_loopback_winsock2=yes, + ac_cv_decl_inaddr_loopback_winsock2=no)) + case "${ac_cv_decl_inaddr_loopback_winsock2}" in + "yes" ) + AC_DEFINE(DEF_INADDR_LOOPBACK_IN_WINSOCK2_H,[], + [Define if you need to include winsock2.h to get INADDR_LOOPBACK defined]) ;; + * ) + # couldn't find it anywhere + AC_DEFINE(HAVE_NO_INADDR_LOOPBACK,[], + [Define if you don't have a definition of INADDR_LOOPBACK]) ;; + esac;; + esac +fi +]) + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_STRUCT_SOCKADDR_SA_LEN +dnl +dnl Check if the sockaddr structure has the field sa_len +dnl + +AC_DEFUN(LM_STRUCT_SOCKADDR_SA_LEN, +[AC_CACHE_CHECK([whether struct sockaddr has sa_len field], + ac_cv_struct_sockaddr_sa_len, +AC_TRY_COMPILE([#include <sys/types.h> +#include <sys/socket.h>], [struct sockaddr s; s.sa_len = 10;], + ac_cv_struct_sockaddr_sa_len=yes, ac_cv_struct_sockaddr_sa_len=no)) + +dnl FIXME convbreak +case ${ac_cv_struct_sockaddr_sa_len} in + "no" ) AC_DEFINE(NO_SA_LEN,[1],[Define if you dont have salen]) ;; + *) ;; +esac +]) + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_STRUCT_EXCEPTION +dnl +dnl Check to see whether the system supports the matherr function +dnl and its associated type "struct exception". +dnl + +AC_DEFUN(LM_STRUCT_EXCEPTION, +[AC_CACHE_CHECK([for struct exception (and matherr function)], + ac_cv_struct_exception, +AC_TRY_COMPILE([#include <math.h>], + [struct exception x; x.type = DOMAIN; x.type = SING;], + ac_cv_struct_exception=yes, ac_cv_struct_exception=no)) + +case "${ac_cv_struct_exception}" in + "yes" ) AC_DEFINE(USE_MATHERR,[1],[Define if you have matherr() function and struct exception type]) ;; + * ) ;; +esac +]) + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_SYS_IPV6 +dnl +dnl Check for ipv6 support and what the in6_addr structure is called. +dnl (early linux used in_addr6 insted of in6_addr) +dnl + +AC_DEFUN(LM_SYS_IPV6, +[AC_MSG_CHECKING(for IP version 6 support) +AC_CACHE_VAL(ac_cv_sys_ipv6_support, +[ok_so_far=yes + AC_TRY_COMPILE([#include <sys/types.h> +#ifdef __WIN32__ +#include <winsock2.h> +#include <ws2tcpip.h> +#else +#include <netinet/in.h> +#endif], + [struct in6_addr a6; struct sockaddr_in6 s6;], ok_so_far=yes, ok_so_far=no) + +if test $ok_so_far = yes; then + ac_cv_sys_ipv6_support=yes +else + AC_TRY_COMPILE([#include <sys/types.h> +#ifdef __WIN32__ +#include <winsock2.h> +#include <ws2tcpip.h> +#else +#include <netinet/in.h> +#endif], + [struct in_addr6 a6; struct sockaddr_in6 s6;], + ac_cv_sys_ipv6_support=in_addr6, ac_cv_sys_ipv6_support=no) +fi +])dnl + +dnl +dnl Have to use old style AC_DEFINE due to BC with old autoconf. +dnl + +case ${ac_cv_sys_ipv6_support} in + yes) + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_IN6,[1],[Define if ipv6 is present]) + ;; + in_addr6) + AC_MSG_RESULT([yes (but I am redefining in_addr6 to in6_addr)]) + AC_DEFINE(HAVE_IN6,[1],[Define if ipv6 is present]) + AC_DEFINE(HAVE_IN_ADDR6_STRUCT,[],[Early linux used in_addr6 instead of in6_addr, define if you have this]) + ;; + *) + AC_MSG_RESULT(no) + ;; +esac +]) + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_SYS_MULTICAST +dnl +dnl Check for multicast support. Only checks for multicast options in +dnl setsockopt(), no check is performed that multicasting actually works. +dnl If options are found defines HAVE_MULTICAST_SUPPORT +dnl + +AC_DEFUN(LM_SYS_MULTICAST, +[AC_CACHE_CHECK([for multicast support], ac_cv_sys_multicast_support, +[AC_EGREP_CPP(yes, +[#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#if defined(IP_MULTICAST_TTL) && defined(IP_MULTICAST_LOOP) && defined(IP_MULTICAST_IF) && defined(IP_ADD_MEMBERSHIP) && defined(IP_DROP_MEMBERSHIP) +yes +#endif +], ac_cv_sys_multicast_support=yes, ac_cv_sys_multicast_support=no)]) +if test $ac_cv_sys_multicast_support = yes; then + AC_DEFINE(HAVE_MULTICAST_SUPPORT,[1], + [Define if setsockopt() accepts multicast options]) +fi +])dnl + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_DECL_SYS_ERRLIST +dnl +dnl Define SYS_ERRLIST_DECLARED if the variable sys_errlist is declared +dnl in a system header file, stdio.h or errno.h. +dnl + +AC_DEFUN(LM_DECL_SYS_ERRLIST, +[AC_CACHE_CHECK([for sys_errlist declaration in stdio.h or errno.h], + ac_cv_decl_sys_errlist, +[AC_TRY_COMPILE([#include <stdio.h> +#include <errno.h>], [char *msg = *(sys_errlist + 1);], + ac_cv_decl_sys_errlist=yes, ac_cv_decl_sys_errlist=no)]) +if test $ac_cv_decl_sys_errlist = yes; then + AC_DEFINE(SYS_ERRLIST_DECLARED,[], + [define if the variable sys_errlist is declared in a system header file]) +fi +]) + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_CHECK_FUNC_DECL( funname, declaration [, extra includes +dnl [, action-if-found [, action-if-not-found]]] ) +dnl +dnl Checks if the declaration "declaration" of "funname" conflicts +dnl with the header files idea of how the function should be +dnl declared. It is useful on systems which lack prototypes and you +dnl need to provide your own (e.g. when you want to take the address +dnl of a function). The 4'th argument is expanded if conflicting, +dnl the 5'th argument otherwise +dnl +dnl + +AC_DEFUN(LM_CHECK_FUNC_DECL, +[AC_MSG_CHECKING([for conflicting declaration of $1]) +AC_CACHE_VAL(ac_cv_func_decl_$1, +[AC_TRY_COMPILE([#include <stdio.h> +$3],[$2 +char *c = (char *)$1; +], eval "ac_cv_func_decl_$1=no", eval "ac_cv_func_decl_$1=yes")]) +if eval "test \"`echo '$ac_cv_func_decl_'$1`\" = yes"; then + AC_MSG_RESULT(yes) + ifelse([$4], , :, [$4]) +else + AC_MSG_RESULT(no) +ifelse([$5], , , [$5 +])dnl +fi +]) + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_CHECK_THR_LIB +dnl +dnl This macro may be used by any OTP application. +dnl +dnl LM_CHECK_THR_LIB sets THR_LIBS, THR_DEFS, and THR_LIB_NAME. It also +dnl checks for some pthread headers which will appear in DEFS or config.h. +dnl + +AC_DEFUN(LM_CHECK_THR_LIB, +[ + +NEED_NPTL_PTHREAD_H=no + +dnl win32? +AC_MSG_CHECKING([for native win32 threads]) +if test "X$host_os" = "Xwin32"; then + AC_MSG_RESULT(yes) + THR_DEFS="-DWIN32_THREADS" + THR_LIBS= + THR_LIB_NAME=win32_threads + THR_LIB_TYPE=win32_threads +else + AC_MSG_RESULT(no) + THR_DEFS= + THR_LIBS= + THR_LIB_NAME= + THR_LIB_TYPE=posix_unknown + +dnl Try to find POSIX threads + +dnl The usual pthread lib... + AC_CHECK_LIB(pthread, pthread_create, THR_LIBS="-lpthread") + +dnl FreeBSD has pthreads in special c library, c_r... + if test "x$THR_LIBS" = "x"; then + AC_CHECK_LIB(c_r, pthread_create, THR_LIBS="-lc_r") + fi + +dnl On ofs1 the '-pthread' switch should be used + if test "x$THR_LIBS" = "x"; then + AC_MSG_CHECKING([if the '-pthread' switch can be used]) + saved_cflags=$CFLAGS + CFLAGS="$CFLAGS -pthread" + AC_TRY_LINK([#include <pthread.h>], + pthread_create((void*)0,(void*)0,(void*)0,(void*)0);, + [THR_DEFS="-pthread" + THR_LIBS="-pthread"]) + CFLAGS=$saved_cflags + if test "x$THR_LIBS" != "x"; then + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + fi + + if test "x$THR_LIBS" != "x"; then + THR_DEFS="$THR_DEFS -D_THREAD_SAFE -D_REENTRANT -DPOSIX_THREADS" + THR_LIB_NAME=pthread + case $host_os in + solaris*) + THR_DEFS="$THR_DEFS -D_POSIX_PTHREAD_SEMANTICS" ;; + linux*) + THR_DEFS="$THR_DEFS -D_POSIX_THREAD_SAFE_FUNCTIONS" + + LM_CHECK_GETCONF + AC_MSG_CHECKING(for Native POSIX Thread Library) + libpthr_vsn=`$GETCONF GNU_LIBPTHREAD_VERSION 2>/dev/null` + if test $? -eq 0; then + case "$libpthr_vsn" in + *nptl*|*NPTL*) nptl=yes;; + *) nptl=no;; + esac + elif test "$cross_compiling" = "yes"; then + case "$erl_xcomp_linux_nptl" in + "") nptl=cross;; + yes|no) nptl=$erl_xcomp_linux_nptl;; + *) AC_MSG_ERROR([Bad erl_xcomp_linux_nptl value: $erl_xcomp_linux_nptl]);; + esac + else + nptl=no + fi + AC_MSG_RESULT($nptl) + if test $nptl = cross; then + nptl=yes + AC_MSG_WARN([result yes guessed because of cross compilation]) + fi + if test $nptl = yes; then + THR_LIB_TYPE=posix_nptl + need_nptl_incldir=no + AC_CHECK_HEADER(nptl/pthread.h, + [need_nptl_incldir=yes + NEED_NPTL_PTHREAD_H=yes]) + if test $need_nptl_incldir = yes; then + # Ahh... + nptl_path="$C_INCLUDE_PATH:$CPATH" + if test X$cross_compiling != Xyes; then + nptl_path="$nptl_path:/usr/local/include:/usr/include" + else + IROOT="$erl_xcomp_isysroot" + test "$IROOT" != "" || IROOT="$erl_xcomp_sysroot" + test "$IROOT" != "" || AC_MSG_ERROR([Don't know where to search for includes! Please set erl_xcomp_isysroot]) + nptl_path="$nptl_path:$IROOT/usr/local/include:$IROOT/usr/include" + fi + nptl_ws_path= + save_ifs="$IFS"; IFS=":" + for dir in $nptl_path; do + if test "x$dir" != "x"; then + nptl_ws_path="$nptl_ws_path $dir" + fi + done + IFS=$save_ifs + nptl_incldir= + for dir in $nptl_ws_path; do + AC_CHECK_HEADER($dir/nptl/pthread.h, + nptl_incldir=$dir/nptl) + if test "x$nptl_incldir" != "x"; then + THR_DEFS="$THR_DEFS -isystem $nptl_incldir" + break + fi + done + if test "x$nptl_incldir" = "x"; then + AC_MSG_ERROR(Failed to locate nptl system include directory) + fi + fi + fi + ;; + *) ;; + esac + + dnl We sometimes need THR_DEFS in order to find certain headers + dnl (at least for pthread.h on osf1). + saved_cppflags=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $THR_DEFS" + + dnl + dnl Check for headers + dnl + + AC_CHECK_HEADER(pthread.h, + AC_DEFINE(HAVE_PTHREAD_H, 1, \ +[Define if you have the <pthread.h> header file.])) + + dnl Some Linuxes have <pthread/mit/pthread.h> instead of <pthread.h> + AC_CHECK_HEADER(pthread/mit/pthread.h, \ + AC_DEFINE(HAVE_MIT_PTHREAD_H, 1, \ +[Define if the pthread.h header file is in pthread/mit directory.])) + + dnl restore CPPFLAGS + CPPFLAGS=$saved_cppflags + + fi +fi + +]) + +AC_DEFUN(ERL_INTERNAL_LIBS, +[ + +ERTS_INTERNAL_X_LIBS= + +AC_CHECK_LIB(kstat, kstat_open, +[AC_DEFINE(HAVE_KSTAT, 1, [Define if you have kstat]) +ERTS_INTERNAL_X_LIBS="$ERTS_INTERNAL_X_LIBS -lkstat"]) + +AC_SUBST(ERTS_INTERNAL_X_LIBS) + +]) + +AC_DEFUN(ETHR_CHK_SYNC_OP, +[ + AC_MSG_CHECKING([for $3-bit $1()]) + case "$2" in + "1") sync_call="$1(&var);";; + "2") sync_call="$1(&var, ($4) 0);";; + "3") sync_call="$1(&var, ($4) 0, ($4) 0);";; + esac + have_sync_op=no + AC_TRY_LINK([], + [ + $4 res; + volatile $4 var; + res = $sync_call + ], + [have_sync_op=yes]) + test $have_sync_op = yes && $5 + AC_MSG_RESULT([$have_sync_op]) +]) + +AC_DEFUN(ETHR_CHK_INTERLOCKED, +[ + ilckd="$1" + AC_MSG_CHECKING([for ${ilckd}()]) + case "$2" in + "1") ilckd_call="${ilckd}(var);";; + "2") ilckd_call="${ilckd}(var, ($3) 0);";; + "3") ilckd_call="${ilckd}(var, ($3) 0, ($3) 0);";; + "4") ilckd_call="${ilckd}(var, ($3) 0, ($3) 0, arr);";; + esac + have_interlocked_op=no + AC_TRY_LINK( + [ + #define WIN32_LEAN_AND_MEAN + #include <windows.h> + #include <intrin.h> + ], + [ + volatile $3 *var; + volatile $3 arr[2]; + + $ilckd_call + return 0; + ], + [have_interlocked_op=yes]) + test $have_interlocked_op = yes && $4 + AC_MSG_RESULT([$have_interlocked_op]) +]) + +dnl ---------------------------------------------------------------------- +dnl +dnl ERL_FIND_ETHR_LIB +dnl +dnl NOTE! This macro may be changed at any time! Should *only* be used by +dnl ERTS! +dnl +dnl Find a thread library to use. Sets ETHR_LIBS to libraries to link +dnl with, ETHR_X_LIBS to extra libraries to link with (same as ETHR_LIBS +dnl except that the ethread lib itself is not included), ETHR_DEFS to +dnl defines to compile with, ETHR_THR_LIB_BASE to the name of the +dnl thread library which the ethread library is based on, and ETHR_LIB_NAME +dnl to the name of the library where the ethread implementation is located. +dnl ERL_FIND_ETHR_LIB currently searches for 'pthreads', and +dnl 'win32_threads'. If no thread library was found ETHR_LIBS, ETHR_X_LIBS, +dnl ETHR_DEFS, ETHR_THR_LIB_BASE, and ETHR_LIB_NAME are all set to the +dnl empty string. +dnl + +AC_DEFUN(ERL_FIND_ETHR_LIB, +[ + +LM_CHECK_THR_LIB +ERL_INTERNAL_LIBS + +ethr_have_native_atomics=no +ethr_have_native_spinlock=no +ETHR_THR_LIB_BASE="$THR_LIB_NAME" +ETHR_THR_LIB_BASE_TYPE="$THR_LIB_TYPE" +ETHR_DEFS="$THR_DEFS" +ETHR_X_LIBS="$THR_LIBS $ERTS_INTERNAL_X_LIBS" +ETHR_LIBS= +ETHR_LIB_NAME= + +ethr_modified_default_stack_size= + +dnl Name of lib where ethread implementation is located +ethr_lib_name=ethread + +case "$THR_LIB_NAME" in + + win32_threads) + ETHR_THR_LIB_BASE_DIR=win + # * _WIN32_WINNT >= 0x0400 is needed for + # TryEnterCriticalSection + # * _WIN32_WINNT >= 0x0403 is needed for + # InitializeCriticalSectionAndSpinCount + # The ethread lib will refuse to build if _WIN32_WINNT < 0x0403. + # + # -D_WIN32_WINNT should have been defined in $CPPFLAGS; fetch it + # and save it in ETHR_DEFS. + found_win32_winnt=no + for cppflag in $CPPFLAGS; do + case $cppflag in + -DWINVER*) + ETHR_DEFS="$ETHR_DEFS $cppflag" + ;; + -D_WIN32_WINNT*) + ETHR_DEFS="$ETHR_DEFS $cppflag" + found_win32_winnt=yes + ;; + *) + ;; + esac + done + if test $found_win32_winnt = no; then + AC_MSG_ERROR([-D_WIN32_WINNT missing in CPPFLAGS]) + fi + + AC_DEFINE(ETHR_WIN32_THREADS, 1, [Define if you have win32 threads]) + + ETHR_CHK_INTERLOCKED([_InterlockedDecrement], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT, 1, [Define if you have _InterlockedDecrement()])) + ETHR_CHK_INTERLOCKED([_InterlockedDecrement_rel], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT_REL, 1, [Define if you have _InterlockedDecrement_rel()])) + ETHR_CHK_INTERLOCKED([_InterlockedIncrement], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT, 1, [Define if you have _InterlockedIncrement()])) + ETHR_CHK_INTERLOCKED([_InterlockedIncrement_acq], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT_ACQ, 1, [Define if you have _InterlockedIncrement_acq()])) + ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD, 1, [Define if you have _InterlockedExchangeAdd()])) + ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd_acq], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD_ACQ, 1, [Define if you have _InterlockedExchangeAdd_acq()])) + ETHR_CHK_INTERLOCKED([_InterlockedAnd], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDAND, 1, [Define if you have _InterlockedAnd()])) + ETHR_CHK_INTERLOCKED([_InterlockedOr], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDOR, 1, [Define if you have _InterlockedOr()])) + ETHR_CHK_INTERLOCKED([_InterlockedExchange], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGE, 1, [Define if you have _InterlockedExchange()])) + ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE, 1, [Define if you have _InterlockedCompareExchange()])) + test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes + ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange_acq], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE_ACQ, 1, [Define if you have _InterlockedCompareExchange_acq()])) + test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes + ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange_rel], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE_REL, 1, [Define if you have _InterlockedCompareExchange_rel()])) + test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes + + ETHR_CHK_INTERLOCKED([_InterlockedDecrement64], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT64, 1, [Define if you have _InterlockedDecrement64()])) + ETHR_CHK_INTERLOCKED([_InterlockedDecrement64_rel], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT64_REL, 1, [Define if you have _InterlockedDecrement64_rel()])) + ETHR_CHK_INTERLOCKED([_InterlockedIncrement64], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT64, 1, [Define if you have _InterlockedIncrement64()])) + ETHR_CHK_INTERLOCKED([_InterlockedIncrement64_acq], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT64_ACQ, 1, [Define if you have _InterlockedIncrement64_acq()])) + ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD64, 1, [Define if you have _InterlockedExchangeAdd64()])) + ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd64_acq], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD64_ACQ, 1, [Define if you have _InterlockedExchangeAdd64_acq()])) + ETHR_CHK_INTERLOCKED([_InterlockedAnd64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDAND64, 1, [Define if you have _InterlockedAnd64()])) + ETHR_CHK_INTERLOCKED([_InterlockedOr64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDOR64, 1, [Define if you have _InterlockedOr64()])) + ETHR_CHK_INTERLOCKED([_InterlockedExchange64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGE64, 1, [Define if you have _InterlockedExchange64()])) + ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64, 1, [Define if you have _InterlockedCompareExchange64()])) + test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes + ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64_acq], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64_ACQ, 1, [Define if you have _InterlockedCompareExchange64_acq()])) + test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes + ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64_rel], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64_REL, 1, [Define if you have _InterlockedCompareExchange64_rel()])) + test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes + + ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange128], [4], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE128, 1, [Define if you have _InterlockedCompareExchange128()])) + + test "$ethr_have_native_atomics" = "yes" && ethr_have_native_spinlock=yes + ;; + + pthread) + ETHR_THR_LIB_BASE_DIR=pthread + AC_DEFINE(ETHR_PTHREADS, 1, [Define if you have pthreads]) + case $host_os in + openbsd*) + # The default stack size is insufficient for our needs + # on OpenBSD. We increase it to 256 kilo words. + ethr_modified_default_stack_size=256;; + linux*) + ETHR_DEFS="$ETHR_DEFS -D_GNU_SOURCE" + + if test X$cross_compiling = Xyes; then + case X$erl_xcomp_linux_usable_sigusrx in + X) usable_sigusrx=cross;; + Xyes|Xno) usable_sigusrx=$erl_xcomp_linux_usable_sigusrx;; + *) AC_MSG_ERROR([Bad erl_xcomp_linux_usable_sigusrx value: $erl_xcomp_linux_usable_sigusrx]);; + esac + case X$erl_xcomp_linux_usable_sigaltstack in + X) usable_sigaltstack=cross;; + Xyes|Xno) usable_sigaltstack=$erl_xcomp_linux_usable_sigaltstack;; + *) AC_MSG_ERROR([Bad erl_xcomp_linux_usable_sigaltstack value: $erl_xcomp_linux_usable_sigaltstack]);; + esac + else + # FIXME: Test for actual problems instead of kernel versions + linux_kernel_vsn_=`uname -r` + case $linux_kernel_vsn_ in + [[0-1]].*|2.[[0-1]]|2.[[0-1]].*) + usable_sigusrx=no + usable_sigaltstack=no;; + 2.[[2-3]]|2.[[2-3]].*) + usable_sigusrx=yes + usable_sigaltstack=no;; + *) + usable_sigusrx=yes + usable_sigaltstack=yes;; + esac + fi + + AC_MSG_CHECKING(if SIGUSR1 and SIGUSR2 can be used) + AC_MSG_RESULT($usable_sigusrx) + if test $usable_sigusrx = cross; then + usable_sigusrx=yes + AC_MSG_WARN([result yes guessed because of cross compilation]) + fi + if test $usable_sigusrx = no; then + ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGUSRX" + fi + + AC_MSG_CHECKING(if sigaltstack can be used) + AC_MSG_RESULT($usable_sigaltstack) + if test $usable_sigaltstack = cross; then + usable_sigaltstack=yes + AC_MSG_WARN([result yes guessed because of cross compilation]) + fi + if test $usable_sigaltstack = no; then + ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGALTSTACK" + fi + ;; + *) ;; + esac + + dnl We sometimes need ETHR_DEFS in order to find certain headers + dnl (at least for pthread.h on osf1). + saved_cppflags="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $ETHR_DEFS" + + dnl We need the thread library in order to find some functions + saved_libs="$LIBS" + LIBS="$LIBS $ETHR_X_LIBS" + + dnl + dnl Check for headers + dnl + + AC_CHECK_HEADER(pthread.h, \ + AC_DEFINE(ETHR_HAVE_PTHREAD_H, 1, \ +[Define if you have the <pthread.h> header file.])) + + dnl Some Linuxes have <pthread/mit/pthread.h> instead of <pthread.h> + AC_CHECK_HEADER(pthread/mit/pthread.h, \ + AC_DEFINE(ETHR_HAVE_MIT_PTHREAD_H, 1, \ +[Define if the pthread.h header file is in pthread/mit directory.])) + + if test $NEED_NPTL_PTHREAD_H = yes; then + AC_DEFINE(ETHR_NEED_NPTL_PTHREAD_H, 1, \ +[Define if you need the <nptl/pthread.h> header file.]) + fi + + AC_CHECK_HEADER(sched.h, \ + AC_DEFINE(ETHR_HAVE_SCHED_H, 1, \ +[Define if you have the <sched.h> header file.])) + + AC_CHECK_HEADER(sys/time.h, \ + AC_DEFINE(ETHR_HAVE_SYS_TIME_H, 1, \ +[Define if you have the <sys/time.h> header file.])) + + AC_TRY_COMPILE([#include <time.h> + #include <sys/time.h>], + [struct timeval *tv; return 0;], + AC_DEFINE(ETHR_TIME_WITH_SYS_TIME, 1, \ +[Define if you can safely include both <sys/time.h> and <time.h>.])) + + + dnl + dnl Check for functions + dnl + + AC_CHECK_FUNC(pthread_spin_lock, \ + [ethr_have_native_spinlock=yes \ + AC_DEFINE(ETHR_HAVE_PTHREAD_SPIN_LOCK, 1, \ +[Define if you have the pthread_spin_lock function.])]) + + have_sched_yield=no + have_librt_sched_yield=no + AC_CHECK_FUNC(sched_yield, [have_sched_yield=yes]) + if test $have_sched_yield = no; then + AC_CHECK_LIB(rt, sched_yield, + [have_librt_sched_yield=yes + ETHR_X_LIBS="$ETHR_X_LIBS -lrt"]) + fi + if test $have_sched_yield = yes || test $have_librt_sched_yield = yes; then + AC_DEFINE(ETHR_HAVE_SCHED_YIELD, 1, [Define if you have the sched_yield() function.]) + AC_MSG_CHECKING([whether sched_yield() returns an int]) + sched_yield_ret_int=no + AC_TRY_COMPILE([ + #ifdef ETHR_HAVE_SCHED_H + #include <sched.h> + #endif + ], + [int sched_yield();], + [sched_yield_ret_int=yes]) + AC_MSG_RESULT([$sched_yield_ret_int]) + if test $sched_yield_ret_int = yes; then + AC_DEFINE(ETHR_SCHED_YIELD_RET_INT, 1, [Define if sched_yield() returns an int.]) + fi + fi + + have_pthread_yield=no + AC_CHECK_FUNC(pthread_yield, [have_pthread_yield=yes]) + if test $have_pthread_yield = yes; then + AC_DEFINE(ETHR_HAVE_PTHREAD_YIELD, 1, [Define if you have the pthread_yield() function.]) + AC_MSG_CHECKING([whether pthread_yield() returns an int]) + pthread_yield_ret_int=no + AC_TRY_COMPILE([ + #if defined(ETHR_NEED_NPTL_PTHREAD_H) + #include <nptl/pthread.h> + #elif defined(ETHR_HAVE_MIT_PTHREAD_H) + #include <pthread/mit/pthread.h> + #elif defined(ETHR_HAVE_PTHREAD_H) + #include <pthread.h> + #endif + ], + [int pthread_yield();], + [pthread_yield_ret_int=yes]) + AC_MSG_RESULT([$pthread_yield_ret_int]) + if test $pthread_yield_ret_int = yes; then + AC_DEFINE(ETHR_PTHREAD_YIELD_RET_INT, 1, [Define if pthread_yield() returns an int.]) + fi + fi + + have_pthread_rwlock_init=no + AC_CHECK_FUNC(pthread_rwlock_init, [have_pthread_rwlock_init=yes]) + if test $have_pthread_rwlock_init = yes; then + + ethr_have_pthread_rwlockattr_setkind_np=no + AC_CHECK_FUNC(pthread_rwlockattr_setkind_np, + [ethr_have_pthread_rwlockattr_setkind_np=yes]) + + if test $ethr_have_pthread_rwlockattr_setkind_np = yes; then + AC_DEFINE(ETHR_HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP, 1, \ +[Define if you have the pthread_rwlockattr_setkind_np() function.]) + + AC_MSG_CHECKING([for PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP]) + ethr_pthread_rwlock_writer_nonrecursive_initializer_np=no + AC_TRY_LINK([ + #if defined(ETHR_NEED_NPTL_PTHREAD_H) + #include <nptl/pthread.h> + #elif defined(ETHR_HAVE_MIT_PTHREAD_H) + #include <pthread/mit/pthread.h> + #elif defined(ETHR_HAVE_PTHREAD_H) + #include <pthread.h> + #endif + ], + [ + pthread_rwlockattr_t *attr; + return pthread_rwlockattr_setkind_np(attr, + PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); + ], + [ethr_pthread_rwlock_writer_nonrecursive_initializer_np=yes]) + AC_MSG_RESULT([$ethr_pthread_rwlock_writer_nonrecursive_initializer_np]) + if test $ethr_pthread_rwlock_writer_nonrecursive_initializer_np = yes; then + AC_DEFINE(ETHR_HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, 1, \ +[Define if you have the PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP rwlock attribute.]) + fi + fi + fi + + if test "$force_pthread_rwlocks" = "yes"; then + + AC_DEFINE(ETHR_FORCE_PTHREAD_RWLOCK, 1, \ +[Define if you want to force usage of pthread rwlocks]) + + if test $have_pthread_rwlock_init = yes; then + AC_MSG_WARN([Forced usage of pthread rwlocks. Note that this implementation may suffer from starvation issues.]) + else + AC_MSG_ERROR([User forced usage of pthread rwlock, but no such implementation was found]) + fi + fi + + AC_CHECK_FUNC(pthread_attr_setguardsize, \ + AC_DEFINE(ETHR_HAVE_PTHREAD_ATTR_SETGUARDSIZE, 1, \ +[Define if you have the pthread_attr_setguardsize function.])) + + linux_futex=no + AC_MSG_CHECKING([for Linux futexes]) + AC_TRY_LINK([ + #include <sys/syscall.h> + #include <unistd.h> + #include <linux/futex.h> + #include <sys/time.h> + ], + [ + int i = 1; + syscall(__NR_futex, (void *) &i, FUTEX_WAKE, 1, + (void*)0,(void*)0, 0); + syscall(__NR_futex, (void *) &i, FUTEX_WAIT, 0, + (void*)0,(void*)0, 0); + return 0; + ], + linux_futex=yes) + AC_MSG_RESULT([$linux_futex]) + test $linux_futex = yes && AC_DEFINE(ETHR_HAVE_LINUX_FUTEX, 1, [Define if you have a linux futex implementation.]) + + AC_CHECK_SIZEOF(int) + AC_CHECK_SIZEOF(long) + AC_CHECK_SIZEOF(long long) + AC_CHECK_SIZEOF(__int128_t) + + if test "$ac_cv_sizeof_int" = "4"; then + int32="int" + elif test "$ac_cv_sizeof_long" = "4"; then + int32="long" + elif test "$ac_cv_sizeof_long_long" = "4"; then + int32="long long" + else + AC_MSG_ERROR([No 32-bit type found]) + fi + + if test "$ac_cv_sizeof_int" = "8"; then + int64="int" + elif test "$ac_cv_sizeof_long" = "8"; then + int64="long" + elif test "$ac_cv_sizeof_long_long" = "8"; then + int64="long long" + else + AC_MSG_ERROR([No 64-bit type found]) + fi + + int128=no + if test "$ac_cv_sizeof___int128_t" = "16"; then + int128="__int128_t" + fi + + ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP32, 1, [Define if you have __sync_val_compare_and_swap() for 32-bit integers])) + test "$have_sync_op" = "yes" && ethr_have_native_atomics=yes + ETHR_CHK_SYNC_OP([__sync_add_and_fetch], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_ADD_AND_FETCH32, 1, [Define if you have __sync_add_and_fetch() for 32-bit integers])) + ETHR_CHK_SYNC_OP([__sync_fetch_and_and], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_AND32, 1, [Define if you have __sync_fetch_and_and() for 32-bit integers])) + ETHR_CHK_SYNC_OP([__sync_fetch_and_or], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_OR32, 1, [Define if you have __sync_fetch_and_or() for 32-bit integers])) + + ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP64, 1, [Define if you have __sync_val_compare_and_swap() for 64-bit integers])) + test "$have_sync_op" = "yes" && ethr_have_native_atomics=yes + ETHR_CHK_SYNC_OP([__sync_add_and_fetch], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_ADD_AND_FETCH64, 1, [Define if you have __sync_add_and_fetch() for 64-bit integers])) + ETHR_CHK_SYNC_OP([__sync_fetch_and_and], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_AND64, 1, [Define if you have __sync_fetch_and_and() for 64-bit integers])) + ETHR_CHK_SYNC_OP([__sync_fetch_and_or], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_OR64, 1, [Define if you have __sync_fetch_and_or() for 64-bit integers])) + + if test $int128 != no; then + ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [128], [$int128], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP128, 1, [Define if you have __sync_val_compare_and_swap() for 128-bit integers])) + fi + + AC_MSG_CHECKING([for a usable libatomic_ops implementation]) + case "x$with_libatomic_ops" in + xno | xyes | x) + libatomic_ops_include= + ;; + *) + if test -d "${with_libatomic_ops}/include"; then + libatomic_ops_include="-I$with_libatomic_ops/include" + CPPFLAGS="$CPPFLAGS $libatomic_ops_include" + else + AC_MSG_ERROR([libatomic_ops include directory $with_libatomic_ops/include not found]) + fi;; + esac + ethr_have_libatomic_ops=no + AC_TRY_LINK([#include "atomic_ops.h"], + [ + volatile AO_t x; + AO_t y; + int z; + + AO_nop_full(); + AO_store(&x, (AO_t) 0); + z = AO_load(&x); + z = AO_compare_and_swap_full(&x, (AO_t) 0, (AO_t) 1); + ], + [ethr_have_native_atomics=yes + ethr_have_libatomic_ops=yes]) + AC_MSG_RESULT([$ethr_have_libatomic_ops]) + if test $ethr_have_libatomic_ops = yes; then + AC_CHECK_SIZEOF(AO_t, , + [ + #include <stdio.h> + #include "atomic_ops.h" + ]) + AC_DEFINE_UNQUOTED(ETHR_SIZEOF_AO_T, $ac_cv_sizeof_AO_t, [Define to the size of AO_t if libatomic_ops is used]) + + AC_DEFINE(ETHR_HAVE_LIBATOMIC_OPS, 1, [Define if you have libatomic_ops atomic operations]) + if test "x$with_libatomic_ops" != "xno" && test "x$with_libatomic_ops" != "x"; then + AC_DEFINE(ETHR_PREFER_LIBATOMIC_OPS_NATIVE_IMPLS, 1, [Define if you prefer libatomic_ops native ethread implementations]) + fi + ETHR_DEFS="$ETHR_DEFS $libatomic_ops_include" + elif test "x$with_libatomic_ops" != "xno" && test "x$with_libatomic_ops" != "x"; then + AC_MSG_ERROR([No usable libatomic_ops implementation found]) + fi + + case "$host_cpu" in + sparc | sun4u | sparc64 | sun4v) + case "$with_sparc_memory_order" in + "TSO") + AC_DEFINE(ETHR_SPARC_TSO, 1, [Define if only run in Sparc TSO mode]);; + "PSO") + AC_DEFINE(ETHR_SPARC_PSO, 1, [Define if only run in Sparc PSO, or TSO mode]);; + "RMO"|"") + AC_DEFINE(ETHR_SPARC_RMO, 1, [Define if run in Sparc RMO, PSO, or TSO mode]);; + *) + AC_MSG_ERROR([Unsupported Sparc memory order: $with_sparc_memory_order]);; + esac + ethr_have_native_atomics=yes;; + i86pc | i*86 | x86_64 | amd64) + if test "$enable_x86_out_of_order" = "yes"; then + AC_DEFINE(ETHR_X86_OUT_OF_ORDER, 1, [Define if x86/x86_64 out of order instructions should be synchronized]) + fi + ethr_have_native_atomics=yes;; + macppc | ppc | "Power Macintosh") + ethr_have_native_atomics=yes;; + tile) + ethr_have_native_atomics=yes;; + *) + ;; + esac + + test ethr_have_native_atomics = "yes" && ethr_have_native_spinlock=yes + + dnl Restore LIBS + LIBS=$saved_libs + dnl restore CPPFLAGS + CPPFLAGS=$saved_cppflags + + ;; + *) + ;; +esac + +AC_MSG_CHECKING([whether default stack size should be modified]) +if test "x$ethr_modified_default_stack_size" != "x"; then + AC_DEFINE_UNQUOTED(ETHR_MODIFIED_DEFAULT_STACK_SIZE, $ethr_modified_default_stack_size, [Define if you want to modify the default stack size]) + AC_MSG_RESULT([yes; to $ethr_modified_default_stack_size kilo words]) +else + AC_MSG_RESULT([no]) +fi + +if test "x$ETHR_THR_LIB_BASE" != "x"; then + ETHR_DEFS="-DUSE_THREADS $ETHR_DEFS" + ETHR_LIBS="-l$ethr_lib_name -lerts_internal_r $ETHR_X_LIBS" + ETHR_LIB_NAME=$ethr_lib_name +fi + +AC_CHECK_SIZEOF(void *) +AC_DEFINE_UNQUOTED(ETHR_SIZEOF_PTR, $ac_cv_sizeof_void_p, [Define to the size of pointers]) + +AC_CHECK_SIZEOF(int) +AC_DEFINE_UNQUOTED(ETHR_SIZEOF_INT, $ac_cv_sizeof_int, [Define to the size of int]) +AC_CHECK_SIZEOF(long) +AC_DEFINE_UNQUOTED(ETHR_SIZEOF_LONG, $ac_cv_sizeof_long, [Define to the size of long]) +AC_CHECK_SIZEOF(long long) +AC_DEFINE_UNQUOTED(ETHR_SIZEOF_LONG_LONG, $ac_cv_sizeof_long_long, [Define to the size of long long]) +AC_CHECK_SIZEOF(__int64) +AC_DEFINE_UNQUOTED(ETHR_SIZEOF___INT64, $ac_cv_sizeof___int64, [Define to the size of __int64]) +AC_CHECK_SIZEOF(__int128_t) +AC_DEFINE_UNQUOTED(ETHR_SIZEOF___INT128_T, $ac_cv_sizeof___int128_t, [Define to the size of __int128_t]) + + +case X$erl_xcomp_bigendian in + X) ;; + Xyes|Xno) ac_cv_c_bigendian=$erl_xcomp_bigendian;; + *) AC_MSG_ERROR([Bad erl_xcomp_bigendian value: $erl_xcomp_bigendian]);; +esac + +AC_C_BIGENDIAN + +if test "$ac_cv_c_bigendian" = "yes"; then + AC_DEFINE(ETHR_BIGENDIAN, 1, [Define if bigendian]) +fi + +AC_ARG_ENABLE(native-ethr-impls, + AS_HELP_STRING([--disable-native-ethr-impls], + [disable native ethread implementations]), +[ case "$enableval" in + no) disable_native_ethr_impls=yes ;; + *) disable_native_ethr_impls=no ;; + esac ], disable_native_ethr_impls=no) + +AC_ARG_ENABLE(x86-out-of-order, + AS_HELP_STRING([--enable-x86-out-of-order], + [enable x86/x84_64 out of order support (default disabled)])) + +test "X$disable_native_ethr_impls" = "Xyes" && + AC_DEFINE(ETHR_DISABLE_NATIVE_IMPLS, 1, [Define if you want to disable native ethread implementations]) + +AC_ARG_ENABLE(prefer-gcc-native-ethr-impls, + AS_HELP_STRING([--enable-prefer-gcc-native-ethr-impls], + [prefer gcc native ethread implementations]), +[ case "$enableval" in + yes) enable_prefer_gcc_native_ethr_impls=yes ;; + *) enable_prefer_gcc_native_ethr_impls=no ;; + esac ], enable_prefer_gcc_native_ethr_impls=no) + +test $enable_prefer_gcc_native_ethr_impls = yes && + AC_DEFINE(ETHR_PREFER_GCC_NATIVE_IMPLS, 1, [Define if you prefer gcc native ethread implementations]) + +AC_ARG_WITH(libatomic_ops, + AS_HELP_STRING([--with-libatomic_ops=PATH], + [specify and prefer usage of libatomic_ops in the ethread library])) + +AC_ARG_WITH(with_sparc_memory_order, + AS_HELP_STRING([--with-sparc-memory-order=TSO|PSO|RMO], + [specify sparc memory order (defaults to RMO)])) + +ETHR_X86_SSE2_ASM=no +case "$GCC-$ac_cv_sizeof_void_p-$host_cpu" in + yes-4-i86pc | yes-4-i*86 | yes-4-x86_64 | yes-4-amd64) + AC_MSG_CHECKING([for gcc sse2 asm support]) + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -msse2" + gcc_sse2_asm=no + AC_TRY_COMPILE([], + [ + long long x, *y; + __asm__ __volatile__("movq %1, %0\n\t" : "=x"(x) : "m"(*y) : "memory"); + ], + [gcc_sse2_asm=yes]) + CFLAGS="$save_CFLAGS" + AC_MSG_RESULT([$gcc_sse2_asm]) + if test "$gcc_sse2_asm" = "yes"; then + AC_DEFINE(ETHR_GCC_HAVE_SSE2_ASM_SUPPORT, 1, [Define if you use a gcc that supports -msse2 and understand sse2 specific asm statements]) + ETHR_X86_SSE2_ASM=yes + fi + ;; + *) + ;; +esac + +case "$GCC-$host_cpu" in + yes-i86pc | yes-i*86 | yes-x86_64 | yes-amd64) + gcc_dw_cmpxchg_asm=no + AC_MSG_CHECKING([for gcc double word cmpxchg asm support]) + AC_TRY_COMPILE([], + [ + char xchgd; + long new[2], xchg[2], *p; + __asm__ __volatile__( +#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__ + "pushl %%ebx\n\t" + "movl %8, %%ebx\n\t" +#endif +#if ETHR_SIZEOF_PTR == 4 + "lock; cmpxchg8b %0\n\t" +#else + "lock; cmpxchg16b %0\n\t" +#endif + "setz %3\n\t" +#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__ + "popl %%ebx\n\t" +#endif + : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd) + : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "3"(new[1]), +#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__ + "r"(new[0]) +#else + "b"(new[0]) +#endif + : "cc", "memory"); + + ], + [gcc_dw_cmpxchg_asm=yes]) + if test $gcc_dw_cmpxchg_asm = no && test $ac_cv_sizeof_void_p = 4; then + AC_TRY_COMPILE([], + [ + char xchgd; + long new[2], xchg[2], *p; +#if !defined(__PIC__) || !__PIC__ +# error nope +#endif + __asm__ __volatile__( + "pushl %%ebx\n\t" + "movl (%7), %%ebx\n\t" + "movl 4(%7), %%ecx\n\t" + "lock; cmpxchg8b %0\n\t" + "setz %3\n\t" + "popl %%ebx\n\t" + : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd) + : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "3"(new) + : "cc", "memory"); + + ], + [gcc_dw_cmpxchg_asm=yes]) + if test "$gcc_dw_cmpxchg_asm" = "yes"; then + AC_DEFINE(ETHR_CMPXCHG8B_REGISTER_SHORTAGE, 1, [Define if you get a register shortage with cmpxchg8b and position independent code]) + fi + fi + AC_MSG_RESULT([$gcc_dw_cmpxchg_asm]) + if test "$gcc_dw_cmpxchg_asm" = "yes"; then + AC_DEFINE(ETHR_GCC_HAVE_DW_CMPXCHG_ASM_SUPPORT, 1, [Define if you use a gcc that supports the double word cmpxchg instruction]) + fi;; + *) + ;; +esac + +AC_DEFINE(ETHR_HAVE_ETHREAD_DEFINES, 1, \ +[Define if you have all ethread defines]) + +AC_SUBST(ETHR_X_LIBS) +AC_SUBST(ETHR_LIBS) +AC_SUBST(ETHR_LIB_NAME) +AC_SUBST(ETHR_DEFS) +AC_SUBST(ETHR_THR_LIB_BASE) +AC_SUBST(ETHR_THR_LIB_BASE_DIR) +AC_SUBST(ETHR_X86_SSE2_ASM) + +]) + + + +dnl ---------------------------------------------------------------------- +dnl +dnl ERL_TIME_CORRECTION +dnl +dnl In the presence of a high resolution realtime timer Erlang can adapt +dnl its view of time relative to this timer. On solaris such a timer is +dnl available with the syscall gethrtime(). On other OS's a fallback +dnl solution using times() is implemented. (However on e.g. FreeBSD times() +dnl is implemented using gettimeofday so it doesn't make much sense to +dnl use it there...) On second thought, it seems to be safer to do it the +dnl other way around. I.e. only use times() on OS's where we know it will +dnl work... +dnl + +AC_DEFUN(ERL_TIME_CORRECTION, +[if test x$ac_cv_func_gethrtime = x; then + AC_CHECK_FUNC(gethrtime) +fi +if test x$clock_gettime_correction = xunknown; then + AC_TRY_COMPILE([#include <time.h>], + [struct timespec ts; + long long result; + clock_gettime(CLOCK_MONOTONIC,&ts); + result = ((long long) ts.tv_sec) * 1000000000LL + + ((long long) ts.tv_nsec);], + clock_gettime_compiles=yes, + clock_gettime_compiles=no) +else + clock_gettime_compiles=no +fi + + +AC_CACHE_CHECK([how to correct for time adjustments], erl_cv_time_correction, +[ +case $clock_gettime_correction in + yes) + erl_cv_time_correction=clock_gettime;; + no|unknown) + case $ac_cv_func_gethrtime in + yes) + erl_cv_time_correction=hrtime ;; + no) + case $host_os in + linux*) + case $clock_gettime_correction in + unknown) + if test x$clock_gettime_compiles = xyes; then + if test X$cross_compiling != Xyes; then + linux_kernel_vsn_=`uname -r` + case $linux_kernel_vsn_ in + [[0-1]].*|2.[[0-5]]|2.[[0-5]].*) + erl_cv_time_correction=times ;; + *) + erl_cv_time_correction=clock_gettime;; + esac + else + case X$erl_xcomp_linux_clock_gettime_correction in + X) + erl_cv_time_correction=cross;; + Xyes|Xno) + if test $erl_xcomp_linux_clock_gettime_correction = yes; then + erl_cv_time_correction=clock_gettime + else + erl_cv_time_correction=times + fi;; + *) + AC_MSG_ERROR([Bad erl_xcomp_linux_clock_gettime_correction value: $erl_xcomp_linux_clock_gettime_correction]);; + esac + fi + else + erl_cv_time_correction=times + fi + ;; + *) + erl_cv_time_correction=times ;; + esac + ;; + *) + erl_cv_time_correction=none ;; + esac + ;; + esac + ;; +esac +]) + +xrtlib="" +case $erl_cv_time_correction in + times) + AC_DEFINE(CORRECT_USING_TIMES,[], + [Define if you do not have a high-res. timer & want to use times() instead]) + ;; + clock_gettime|cross) + if test $erl_cv_time_correction = cross; then + erl_cv_time_correction=clock_gettime + AC_MSG_WARN([result clock_gettime guessed because of cross compilation]) + fi + xrtlib="-lrt" + AC_DEFINE(GETHRTIME_WITH_CLOCK_GETTIME,[1], + [Define if you want to use clock_gettime to simulate gethrtime]) + ;; +esac +dnl +dnl Check if gethrvtime is working, and if to use procfs ioctl +dnl or (yet to be written) write to the procfs ctl file. +dnl + +AC_MSG_CHECKING([if gethrvtime works and how to use it]) +AC_TRY_RUN([ +/* gethrvtime procfs ioctl test */ +/* These need to be undef:ed to not break activation of + * micro level process accounting on /proc/self + */ +#ifdef _LARGEFILE_SOURCE +# undef _LARGEFILE_SOURCE +#endif +#ifdef _FILE_OFFSET_BITS +# undef _FILE_OFFSET_BITS +#endif +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <stdio.h> +#include <sys/time.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/signal.h> +#include <sys/fault.h> +#include <sys/syscall.h> +#include <sys/procfs.h> +#include <fcntl.h> + +int main() { + long msacct = PR_MSACCT; + int fd; + long long start, stop; + int i; + pid_t pid = getpid(); + char proc_self[30] = "/proc/"; + + sprintf(proc_self+strlen(proc_self), "%lu", (unsigned long) pid); + if ( (fd = open(proc_self, O_WRONLY)) == -1) + exit(1); + if (ioctl(fd, PIOCSET, &msacct) < 0) + exit(2); + if (close(fd) < 0) + exit(3); + start = gethrvtime(); + for (i = 0; i < 100; i++) + stop = gethrvtime(); + if (start == 0) + exit(4); + if (start == stop) + exit(5); + exit(0); return 0; +} +], +erl_gethrvtime=procfs_ioctl, +erl_gethrvtime=false, +[ +case X$erl_xcomp_gethrvtime_procfs_ioctl in + X) + erl_gethrvtime=cross;; + Xyes|Xno) + if test $erl_xcomp_gethrvtime_procfs_ioctl = yes; then + erl_gethrvtime=procfs_ioctl + else + erl_gethrvtime=false + fi;; + *) + AC_MSG_ERROR([Bad erl_xcomp_gethrvtime_procfs_ioctl value: $erl_xcomp_gethrvtime_procfs_ioctl]);; +esac +]) + +case $erl_gethrvtime in + procfs_ioctl) + AC_DEFINE(HAVE_GETHRVTIME_PROCFS_IOCTL,[1], + [define if gethrvtime() works and uses ioctl() to /proc/self]) + AC_MSG_RESULT(uses ioctl to procfs) + ;; + *) + if test $erl_gethrvtime = cross; then + erl_gethrvtime=false + AC_MSG_RESULT(cross) + AC_MSG_WARN([result 'not working' guessed because of cross compilation]) + else + AC_MSG_RESULT(not working) + fi + + dnl + dnl Check if clock_gettime (linux) is working + dnl + + AC_MSG_CHECKING([if clock_gettime can be used to get process CPU time]) + save_libs=$LIBS + LIBS="-lrt" + AC_TRY_RUN([ + #include <stdlib.h> + #include <unistd.h> + #include <string.h> + #include <stdio.h> + #include <time.h> + int main() { + long long start, stop; + int i; + struct timespec tp; + + if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp) < 0) + exit(1); + start = ((long long)tp.tv_sec * 1000000000LL) + (long long)tp.tv_nsec; + for (i = 0; i < 100; i++) + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp); + stop = ((long long)tp.tv_sec * 1000000000LL) + (long long)tp.tv_nsec; + if (start == 0) + exit(4); + if (start == stop) + exit(5); + exit(0); return 0; + } + ], + erl_clock_gettime=yes, + erl_clock_gettime=no, + [ + case X$erl_xcomp_clock_gettime_cpu_time in + X) erl_clock_gettime=cross;; + Xyes|Xno) erl_clock_gettime=$erl_xcomp_clock_gettime_cpu_time;; + *) AC_MSG_ERROR([Bad erl_xcomp_clock_gettime_cpu_time value: $erl_xcomp_clock_gettime_cpu_time]);; + esac + ]) + LIBS=$save_libs + case $host_os in + linux*) + AC_MSG_RESULT([no; not stable]) + LIBRT=$xrtlib + ;; + *) + AC_MSG_RESULT($erl_clock_gettime) + case $erl_clock_gettime in + yes) + AC_DEFINE(HAVE_CLOCK_GETTIME,[], + [define if clock_gettime() works for getting process time]) + LIBRT=-lrt + ;; + cross) + erl_clock_gettime=no + AC_MSG_WARN([result no guessed because of cross compilation]) + LIBRT=$xrtlib + ;; + *) + LIBRT=$xrtlib + ;; + esac + ;; + esac + AC_SUBST(LIBRT) + ;; +esac +])dnl + +dnl ERL_TRY_LINK_JAVA(CLASSES, FUNCTION-BODY +dnl [ACTION_IF_FOUND [, ACTION-IF-NOT-FOUND]]) +dnl Freely inspired by AC_TRY_LINK. (Maybe better to create a +dnl AC_LANG_JAVA instead...) +AC_DEFUN(ERL_TRY_LINK_JAVA, +[java_link='$JAVAC conftest.java 1>&AC_FD_CC' +changequote(, )dnl +cat > conftest.java <<EOF +$1 +class conftest { public static void main(String[] args) { + $2 + ; return; }} +EOF +changequote([, ])dnl +if AC_TRY_EVAL(java_link) && test -s conftest.class; then + ifelse([$3], , :, [rm -rf conftest* + $3]) +else + echo "configure: failed program was:" 1>&AC_FD_CC + cat conftest.java 1>&AC_FD_CC + echo "configure: PATH was $PATH" 1>&AC_FD_CC +ifelse([$4], , , [ rm -rf conftest* + $4 +])dnl +fi +rm -f conftest*]) +#define UNSAFE_MASK 0xc0000000 /* Mask for bits that must be constant */ + + diff --git a/lib/odbc/configure.in b/lib/odbc/configure.in index 2369e16813..f0fa40814a 100644 --- a/lib/odbc/configure.in +++ b/lib/odbc/configure.in @@ -63,25 +63,11 @@ AC_PROG_CC dnl --------------------------------------------------------------------- dnl Special windows stuff regarding CFLAGS and details in the environment... dnl --------------------------------------------------------------------- -AC_MSG_CHECKING(for mixed cygwin and native VC++ environment) -if test "X$CC" = "Xcc.sh" -a "X$host" = "Xwin32"; then - if test -x /usr/bin/cygpath; then - CFLAGS="-O2" - AC_MSG_RESULT([yes]) - MIXED_CYGWIN_VC=yes - else - AC_MSG_RESULT([undeterminable]) - AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!) - fi -else - AC_MSG_RESULT([no]) - MIXED_CYGWIN_VC=no -fi -AC_SUBST(MIXED_CYGWIN_VC) - +LM_WINDOWS_ENVIRONMENT + AC_PROG_MAKE_SET -AC_CHECK_PROG(LD, ld.sh) +AC_CHECK_PROGS(LD, ld.sh) AC_CHECK_TOOL(LD, ld, '$(CC)') AC_SUBST(LD) diff --git a/lib/odbc/src/odbc.appup.src b/lib/odbc/src/odbc.appup.src index f3a3af8c29..853323da09 100644 --- a/lib/odbc/src/odbc.appup.src +++ b/lib/odbc/src/odbc.appup.src @@ -1,10 +1,12 @@ %% -*- erlang -*- {"%VSN%", [ + {"2.10.11", [{restart_application, odbc}]}, {"2.10.10", [{restart_application, odbc}]}, {"2.10.9", [{restart_application, odbc}]} ], [ + {"2.10.11", [{restart_application, odbc}]}, {"2.10.10", [{restart_application, odbc}]}, {"2.10.9", [{restart_application, odbc}]} ]}. diff --git a/lib/odbc/src/odbc.erl b/lib/odbc/src/odbc.erl index 68497292db..36afd1abcf 100644 --- a/lib/odbc/src/odbc.erl +++ b/lib/odbc/src/odbc.erl @@ -748,6 +748,9 @@ handle_info({'DOWN', _Ref, _Type, _Process, normal}, State) -> handle_info({'DOWN', _Ref, _Type, _Process, timeout}, State) -> {stop, normal, State#state{reply_to = undefined}}; + +handle_info({'DOWN', _Ref, _Type, _Process, shutdown}, State) -> + {stop, normal, State#state{reply_to = undefined}}; handle_info({'DOWN', _Ref, _Type, Process, Reason}, State) -> {stop, {stopped, {'EXIT', Process, Reason}}, diff --git a/lib/orber/doc/src/ch_install.xml b/lib/orber/doc/src/ch_install.xml index dde4bf4006..de9c0e3a9d 100644 --- a/lib/orber/doc/src/ch_install.xml +++ b/lib/orber/doc/src/ch_install.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE chapter SYSTEM "chapter.dtd"> <chapter> <header> <copyright> - <year>1997</year><year>2010</year> + <year>1997</year><year>2011</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -394,84 +394,16 @@ nodeB@hostB> orber:start(). <cell align="left" valign="middle">The same as <c>iiop_ssl_port</c></cell> </row> <row> - <cell align="left" valign="middle">ssl_server_cacertfile</cell> - <cell align="left" valign="middle">string()</cell> - <cell align="left" valign="middle">-</cell> - </row> - <row> - <cell align="left" valign="middle">ssl_server_certfile</cell> - <cell align="left" valign="middle">string()</cell> - <cell align="left" valign="middle">-</cell> - </row> - <row> - <cell align="left" valign="middle">ssl_server_verify</cell> - <cell align="left" valign="middle">0 | 1 | 2</cell> - <cell align="left" valign="middle">-</cell> - </row> - <row> - <cell align="left" valign="middle">ssl_server_depth</cell> - <cell align="left" valign="middle">integer()</cell> - <cell align="left" valign="middle">-</cell> - </row> - <row> - <cell align="left" valign="middle">ssl_server_password</cell> - <cell align="left" valign="middle">string()</cell> - <cell align="left" valign="middle">-</cell> - </row> - <row> - <cell align="left" valign="middle">ssl_server_keyfile</cell> - <cell align="left" valign="middle">string()</cell> - <cell align="left" valign="middle">-</cell> - </row> - <row> - <cell align="left" valign="middle">ssl_server_ciphers</cell> - <cell align="left" valign="middle">string()</cell> - <cell align="left" valign="middle">-</cell> + <cell align="left" valign="middle">ssl_server_options</cell> + <cell align="left" valign="middle">list()</cell> + <cell align="left" valign="middle">See the <seealso marker="ssl:ssl">SSL</seealso> application + for valid options.</cell> </row> <row> - <cell align="left" valign="middle">ssl_server_cachetimeout</cell> - <cell align="left" valign="middle">integer() | infinity</cell> - <cell align="left" valign="middle">infinity</cell> - </row> - <row> - <cell align="left" valign="middle">ssl_client_cacertfile</cell> - <cell align="left" valign="middle">string()</cell> - <cell align="left" valign="middle">-</cell> - </row> - <row> - <cell align="left" valign="middle">ssl_client_certfile</cell> - <cell align="left" valign="middle">string()</cell> - <cell align="left" valign="middle">-</cell> - </row> - <row> - <cell align="left" valign="middle">ssl_client_verify</cell> - <cell align="left" valign="middle">0 | 1 | 2</cell> - <cell align="left" valign="middle">-</cell> - </row> - <row> - <cell align="left" valign="middle">ssl_client_depth</cell> - <cell align="left" valign="middle">integer()</cell> - <cell align="left" valign="middle">-</cell> - </row> - <row> - <cell align="left" valign="middle">ssl_client_password</cell> - <cell align="left" valign="middle">string()</cell> - <cell align="left" valign="middle">-</cell> - </row> - <row> - <cell align="left" valign="middle">ssl_client_keyfile</cell> - <cell align="left" valign="middle">string()</cell> - <cell align="left" valign="middle">-</cell> - </row> - <row> - <cell align="left" valign="middle">ssl_client_ciphers</cell> - <cell align="left" valign="middle">string()</cell> - <cell align="left" valign="middle">-</cell> - </row> - <row> - <cell align="left" valign="middle">ssl_client_cachetimeout</cell> - <cell align="left" valign="middle">integer() | infinity</cell> - <cell align="left" valign="middle">infinity</cell> + <cell align="left" valign="middle">ssl_client_options</cell> + <cell align="left" valign="middle">list()</cell> + <cell align="left" valign="middle">See the <seealso marker="ssl:ssl">SSL</seealso> application + for valid options.</cell> </row> <row> <cell align="left" valign="middle">iiop_ssl_out_keepalive</cell> @@ -698,40 +630,10 @@ nodeB@hostB> orber:start(). <item>If set, the value must be an integer greater than zero or <c>{local, DefaultNATPort, [{Port, NATPort}]}</c>. See also <seealso marker="ch_install#firewall">Firewall Configuration</seealso>.</item> - <tag><em>ssl_server_cacertfile</em></tag> + <tag><em>ssl_server_options</em></tag> <item>the file path to a server side CA certificate.</item> - <tag><em>ssl_server_certfile</em></tag> - <item>The path to a file containing a chain of PEM encoded certificates.</item> - <tag><em>ssl_server_verify</em></tag> - <item>The type of verification used by SSL during authentication of the - other peer for incoming calls.</item> - <tag><em>ssl_server_depth</em></tag> - <item>The SSL verification depth for outgoing calls.</item> - <tag><em>ssl_server_password</em></tag> - <item>The server side key string.</item> - <tag><em>ssl_server_keyfile</em></tag> - <item>The file path to a server side key.</item> - <tag><em>ssl_server_ciphers</em></tag> - <item>The server side cipher string.</item> - <tag><em>ssl_server_cachetimeout</em></tag> - <item>The server side cache timeout.</item> - <tag><em>ssl_client_cacertfile</em></tag> - <item>The file path to a client side CA certificate.</item> - <tag><em>ssl_client_certfile</em></tag> + <tag><em>ssl_client_options</em></tag> <item>The path to a file containing a chain of PEM encoded certificates.</item> - <tag><em>ssl_client_verify</em></tag> - <item>The type of verification used by SSL during authentication of the - other peer for outgoing calls.</item> - <tag><em>ssl_client_depth</em></tag> - <item>The SSL verification depth for incoming calls.</item> - <tag><em>ssl_client_password</em></tag> - <item>The client side key string.</item> - <tag><em>ssl_client_keyfile</em></tag> - <item>The file path to a client side key.</item> - <tag><em>ssl_client_ciphers</em></tag> - <item>The client side cipher string.</item> - <tag><em>ssl_client_cachetimeout</em></tag> - <item>The client side cache timeout.</item> <tag><em>iiop_ssl_out_keepalive</em></tag> <item>Enables periodic transmission on a connected socket, when no other data is being exchanged. If the other end does not respond, the diff --git a/lib/orber/doc/src/ch_security.xml b/lib/orber/doc/src/ch_security.xml index 938025a629..a25a8a5052 100644 --- a/lib/orber/doc/src/ch_security.xml +++ b/lib/orber/doc/src/ch_security.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE chapter SYSTEM "chapter.dtd"> <chapter> <header> <copyright> - <year>1999</year><year>2009</year> + <year>1999</year><year>2011</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -55,40 +55,15 @@ <section> <title>Configurations when Orber is Used on the Server Side</title> - <p>The following three configuration variables can be used to configure Orber's SSL - behavior on the server side.</p> + <p>There is a variable to conficure Orber's SSL behavior on the server side.</p> <list type="bulleted"> - <item><em>ssl_server_certfile</em> - which is a path to a file containing a - chain of PEM encoded certificates for the Orber domain as server.</item> - <item><em>ssl_server_cacertfile</em> - which is a path to a file containing - a chain of PEM encoded certificates for the Orber domain as server.</item> - <item><em>ssl_server_verify</em> - which specifies type of verification: - 0 = do not verify peer; 1 = verify peer, verify client once, - 2 = verify peer, verify client once, fail if no peer certificate. - The default value is 0.</item> - <item><em>ssl_server_depth</em> - which specifies verification depth, i.e. - how far in a chain of certificates the verification process shall - proceed before the verification is considered successful. The default - value is 1. </item> - <item><em>ssl_server_keyfile</em> - which is a path to a file containing a - PEM encoded key for the Orber domain as server.</item> - <item><em>ssl_server_password</em> - only used if the private keyfile is - password protected.</item> - <item><em>ssl_server_ciphers</em> - which is string of ciphers as a colon - separated list of ciphers.</item> - <item><em>ssl_server_cachetimeout</em> - which is the session cache timeout - in seconds.</item> + <item><em>ssl_server_options</em> - which is a list of options to ssl. + See the <seealso marker="ssl:ssl">SSL</seealso> application for further + descriptions on these options.</item> </list> - <p>There also exist a number of API functions for accessing the values of these variables:</p> + <p>There also exist an API function for accessing the value of this variable:</p> <list type="bulleted"> - <item>orber:ssl_server_certfile/0</item> - <item>orber:ssl_server_cacertfile/0</item> - <item>orber:ssl_server_verify/0</item> - <item>orber:ssl_server_depth/0</item> - <item>orber:ssl_server_keyfile/0</item> - <item>orber:ssl_server_password/0</item> - <item>orber:ssl_server_ciphers/0</item> - <item>orber:ssl_server_cachetimeout/0</item> + <item>orber:ssl_server_options/0</item> </list> </section> @@ -97,50 +72,22 @@ <p>When the Orber enabled application is the client side in the secure connection the different configurations can be set per client process instead and not for the whole domain as for incoming calls.</p> - <p>One can use configuration variables to set default values for the domain but they can be changed - per client process. Below is the list of client configuration variables.</p> + <p>There is a variable to set default values for the domain but they can be changed + per client process.</p> <list type="bulleted"> - <item><em>ssl_client_certfile</em> - which is a path to a file containing a - chain of PEM encoded certificates used in outgoing calls in the current - process.</item> - <item><em>ssl_client_cacertfile</em> - which is a path to a file containing a - chain of PEM encoded CA certificates used in outgoing calls in the - current process.</item> - <item><em>ssl_client_verify</em> - which specifies type of verification: - 0 = do not verify peer; 1 = verify peer, verify client once, - 2 = verify peer, verify client once, fail if no peer certificate. - The default value is 0.</item> - <item><em>ssl_client_depth</em> - which specifies verification depth, i.e. - how far in a chain of certificates the verification process shall proceed - before the verification is considered successful. The default value is 1. </item> - <item><em>ssl_client_keyfile</em> - which is a path to a file containing a - PEM encoded key when Orber act as client side ORB.</item> - <item><em>ssl_client_password</em> - only used if the private keyfile is - password protected.</item> - <item><em>ssl_client_ciphers</em> - which is string of ciphers as a colon - separated list of ciphers.</item> - <item><em>ssl_client_cachetimeout</em> - which is the session cache timeout - in seconds.</item> + <item><em>ssl_client_options</em> - which is a list of options to ssl. + See the <seealso marker="ssl:ssl">SSL</seealso> application for further + descriptions on these options.</item> </list> - <p>There also exist a number of API functions for accessing and changing the values of this - variables in the client processes.</p> - <p>Access functions:</p> + <p>There also exist two API functions for accessing and changing the values of this + variable in the client processes.</p> + <p>Access function:</p> <list type="bulleted"> - <item>orber:ssl_client_certfile/0</item> - <item>orber:ssl_client_cacertfile/0</item> - <item>orber:ssl_client_verify/0</item> - <item>orber:ssl_client_depth/0</item> - <item>orber:ssl_client_keyfile/0</item> - <item>orber:ssl_client_password/0</item> - <item>orber:ssl_client_ciphers/0</item> - <item>orber:ssl_client_cachetimeout/0</item> + <item>orber:ssl_client_options/0</item> </list> - <p>Modify functions:</p> + <p>Modify function:</p> <list type="bulleted"> - <item>orber:set_ssl_client_certfile/1</item> - <item>orber:set_ssl_client_cacertfile/1</item> - <item>orber:set_ssl_client_verify/1</item> - <item>orber:set_ssl_client_depth/1</item> + <item>orber:set_ssl_client_options/1</item> </list> </section> </section> diff --git a/lib/orber/doc/src/corba.xml b/lib/orber/doc/src/corba.xml index cae0e09b0b..08ec555f94 100644 --- a/lib/orber/doc/src/corba.xml +++ b/lib/orber/doc/src/corba.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE erlref SYSTEM "erlref.dtd"> <erlref> <header> <copyright> - <year>1997</year><year>2009</year> + <year>1997</year><year>2011</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -221,8 +221,7 @@ Example: <v>CtxData = {interface, Interface} | {userspecific, term()} | {configuration, Options}</v> <v>Interface = string()</v> <v>Options = [{Key, Value}]</v> - <v>Key = ssl_client_verify | ssl_client_depth | ssl_client_certfile | ssl_client_cacertfile | - ssl_client_password | ssl_client_keyfile | ssl_client_ciphers | ssl_client_cachetimeout</v> + <v>Key = ssl_client_options</v> <v>Value = allowed value associated with the given key</v> <v>Object = #objref</v> </type> @@ -287,8 +286,7 @@ Example: <v>CtxData = {interface, Interface} | {userspecific, term()} | {configuration, Options}</v> <v>Interface = string()</v> <v>Options = [{Key, Value}]</v> - <v>Key = ssl_client_verify | ssl_client_depth | ssl_client_certfile | ssl_client_cacertfile | - ssl_client_password | ssl_client_keyfile | ssl_client_ciphers | ssl_client_cachetimeout</v> + <v>Key = ssl_client_options</v> <v>Value = allowed value associated with the given key</v> <v>Object = #objref</v> </type> @@ -319,8 +317,7 @@ Example: <v>CtxData = {interface, Interface} | {userspecific, term()} | {configuration, Options}</v> <v>Interface = string()</v> <v>Options = [{Key, Value}]</v> - <v>Key = ssl_client_verify | ssl_client_depth | ssl_client_certfile | ssl_client_cacertfile | - ssl_client_password | ssl_client_keyfile | ssl_client_ciphers | ssl_client_cachetimeout</v> + <v>Key = ssl_client_options</v> <v>Value = allowed value associated with the given key</v> <v>ObjectId = string()</v> </type> @@ -360,8 +357,7 @@ Example: <v>CtxData = {interface, Interface} | {userspecific, term()} | {configuration, Options}</v> <v>Interface = string()</v> <v>Options = [{Key, Value}]</v> - <v>Key = ssl_client_verify | ssl_client_depth | ssl_client_certfile | ssl_client_cacertfile | - ssl_client_password | ssl_client_keyfile | ssl_client_ciphers | ssl_client_cachetimeout</v> + <v>Key = ssl_client_options</v> <v>Value = allowed value associated with the given key</v> <v>Object = #objref</v> </type> diff --git a/lib/orber/doc/src/corba_object.xml b/lib/orber/doc/src/corba_object.xml index e0f9a9f503..ef440f1a2d 100644 --- a/lib/orber/doc/src/corba_object.xml +++ b/lib/orber/doc/src/corba_object.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE erlref SYSTEM "erlref.dtd"> <erlref> @@ -75,8 +75,7 @@ <v>CtxData = {interface, Interface} | {userspecific, term()} | {configuration, Options}</v> <v>Interface = string()</v> <v>Options = [{Key, Value}]</v> - <v>Key = ssl_client_verify | ssl_client_depth | ssl_client_certfile | ssl_client_cacertfile | - ssl_client_password | ssl_client_keyfile | ssl_client_ciphers | ssl_client_cachetimeout</v> + <v>Key = ssl_client_options</v> <v>Value = allowed value associated with the given key</v> <v>Return = boolean() | {'EXCEPTION', E}</v> </type> @@ -117,8 +116,7 @@ <v>CtxData = {interface, Interface} | {userspecific, term()} | {configuration, Options}</v> <v>Interface = string()</v> <v>Options = [{Key, Value}]</v> - <v>Key = ssl_client_verify | ssl_client_depth | ssl_client_certfile | ssl_client_cacertfile | - ssl_client_password | ssl_client_keyfile | ssl_client_ciphers | ssl_client_cachetimeout</v> + <v>Key = ssl_client_options</v> <v>Value = allowed value associated with the given key</v> <v>Return = boolean() | {'EXCEPTION', E}</v> </type> @@ -149,8 +147,7 @@ <v>CtxData = {interface, Interface} | {userspecific, term()} | {configuration, Options}</v> <v>Interface = string()</v> <v>Options = [{Key, Value}]</v> - <v>Key = ssl_client_verify | ssl_client_depth | ssl_client_certfile | ssl_client_cacertfile | - ssl_client_password | ssl_client_keyfile | ssl_client_ciphers | ssl_client_cachetimeout</v> + <v>Key = ssl_client_options</v> <v>Value = allowed value associated with the given key</v> <v>Return = boolean() | {'EXCEPTION', E}</v> </type> diff --git a/lib/orber/doc/src/orber.xml b/lib/orber/doc/src/orber.xml index 5e38e4cf9f..35e9f57008 100644 --- a/lib/orber/doc/src/orber.xml +++ b/lib/orber/doc/src/orber.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE erlref SYSTEM "erlref.dtd"> <erlref> <header> <copyright> - <year>1997</year><year>2010</year> + <year>1997</year><year>2011</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -356,7 +356,7 @@ <v>Type = normal | ssl</v> <v>Port = integer() > 0</v> <v>ConfigurationParameters = [{Key, Value}]</v> - <v>Key = flags | iiop_in_connection_timeout | iiop_max_fragments | iiop_max_in_requests | interceptors | iiop_port | iiop_ssl_port</v> + <v>Key = flags | iiop_in_connection_timeout | iiop_max_fragments | iiop_max_in_requests | interceptors | iiop_port | iiop_ssl_port | ssl_server_options</v> <v>Value = as described in the User's Guide</v> <v>Result = {ok, Ref} | {error, Reason} | {'EXCEPTION', #'BAD_PARAM'{}}</v> <v>Ref = #Ref</v> @@ -378,7 +378,7 @@ counterparts (See the <seealso marker="ch_install#config">Configuration</seealso> chapter in the User's Guide). - But the following parameters there are a few restrictions:</p> + But for the following parameters there are a few restrictions:</p> <list type="bulleted"> <item><em>flags</em> - currently it is only possible to override the global setting for the <c>Use Current Interface in IOR</c> and @@ -450,92 +450,32 @@ </desc> </func> <func> - <name>ssl_server_certfile() -> string()</name> - <fsummary>Display the path to the server certificate</fsummary> + <name>ssl_server_options() -> list()</name> + <fsummary>Display the SSL server options</fsummary> <desc> - <p>This function returns a path to a file containing a chain of PEM encoded - certificates for the Orber domain as server. + <p>This function returns the list of SSL options set for the Orber domain as server. This is configured by setting the application variable - <em>ssl_server_certfile</em>.</p> + <em>ssl_server_options</em>.</p> </desc> </func> <func> - <name>ssl_client_certfile() -> string()</name> - <fsummary>Display the path to the client certificate</fsummary> + <name>ssl_client_options() -> list()</name> + <fsummary>Display the SSL client options</fsummary> <desc> - <p>This function returns a path to a file containing a chain of PEM encoded - certificates used in outgoing calls in the current process. + <p>This function returns the list of SSL options used in outgoing calls in the current process. The default value is configured by setting the application variable - <em>ssl_client_certfile</em>.</p> + <em>ssl_client_options</em>.</p> </desc> </func> <func> - <name>set_ssl_client_certfile(Path) -> ok</name> - <fsummary>Set the value of the client certificate</fsummary> + <name>set_ssl_client_options(Options) -> ok</name> + <fsummary>Set the SSL options for the client</fsummary> <type> - <v>Path = string()</v> + <v>Options = list()</v> </type> <desc> - <p>This function takes a path to a file containing a chain of PEM encoded - certificates as parameter and sets it for the current process.</p> - </desc> - </func> - <func> - <name>ssl_server_verify() -> 0 | 1 | 2</name> - <fsummary>Display the SSL verification type for incoming calls</fsummary> - <desc> - <p>This function returns the type of verification used by SSL during authentication of the other - peer for incoming calls. - It is configured by setting the application variable - <em>ssl_server_verify</em>.</p> - </desc> - </func> - <func> - <name>ssl_client_verify() -> 0 | 1 | 2</name> - <fsummary>Display the SSL verification type for outgoing calls</fsummary> - <desc> - <p>This function returns the type of verification used by SSL during authentication of the other - peer for outgoing calls. - The default value is configured by setting the application variable - <em>ssl_client_verify</em>.</p> - </desc> - </func> - <func> - <name>set_ssl_client_verify(Value) -> ok</name> - <fsummary>Set the value of the SSL verification type for outgoing calls</fsummary> - <type> - <v>Value = 0 | 1 | 2</v> - </type> - <desc> - <p>This function sets the SSL verification type for the other peer of outgoing calls.</p> - </desc> - </func> - <func> - <name>ssl_server_depth() -> int()</name> - <fsummary>Display the SSL verification depth for incoming calls</fsummary> - <desc> - <p>This function returns the SSL verification depth for incoming calls. - It is configured by setting the application variable - <em>ssl_server_depth</em>.</p> - </desc> - </func> - <func> - <name>ssl_client_depth() -> int()</name> - <fsummary>Display the SSL verification depth for outgoing calls</fsummary> - <desc> - <p>This function returns the SSL verification depth for outgoing calls. - The default value is configured by setting the application variable - <em>ssl_client_depth</em>.</p> - </desc> - </func> - <func> - <name>set_ssl_client_depth(Depth) -> ok</name> - <fsummary>Sets the value of the SSL verification depth for outgoing calls</fsummary> - <type> - <v>Depth = int()</v> - </type> - <desc> - <p>This function sets the SSL verification depth for the other peer of outgoing calls.</p> + <p>This function takes a list of SSL options as parameter and sets + it for the current process.</p> </desc> </func> <func> diff --git a/lib/orber/src/orber.erl b/lib/orber/src/orber.erl index 386c07d227..5ab240e046 100644 --- a/lib/orber/src/orber.erl +++ b/lib/orber/src/orber.erl @@ -36,6 +36,7 @@ -export([start/0, start/1, stop/0, install/1, install/2, orber_nodes/0, iiop_port/0, domain/0, iiop_ssl_port/0, iiop_out_ports/0, iiop_out_ports_random/0, iiop_out_ports_attempts/0, + ssl_server_options/0, ssl_client_options/0, set_ssl_client_options/1, ssl_server_certfile/0, ssl_client_certfile/0, set_ssl_client_certfile/1, ssl_server_verify/0, ssl_client_verify/0, set_ssl_client_verify/1, ssl_server_depth/0, ssl_client_depth/0, set_ssl_client_depth/1, @@ -524,6 +525,15 @@ iiop_ssl_port() -> nat_iiop_ssl_port() -> orber_env:nat_iiop_ssl_port(). +ssl_server_options() -> + orber_env:ssl_server_options(). + +ssl_client_options() -> + orber_env:ssl_client_options(). + +set_ssl_client_options(Value) -> + orber_env:set_ssl_client_options(Value). + ssl_server_certfile() -> orber_env:ssl_server_certfile(). diff --git a/lib/orber/src/orber_env.erl b/lib/orber/src/orber_env.erl index d80edb4ee0..b96c4ea7de 100644 --- a/lib/orber/src/orber_env.erl +++ b/lib/orber/src/orber_env.erl @@ -20,7 +20,7 @@ %% %%----------------------------------------------------------------- %% File: orber_env.erl -%% +%% %% Description: %% Handling environment parameters for Orber. %% @@ -49,20 +49,22 @@ iiop_max_in_connections/0, iiop_backlog/0, objectkeys_gc_time/0, get_ORBInitRef/0, get_ORBDefaultInitRef/0, get_interceptors/0, get_local_interceptors/0, get_cached_interceptors/0, - set_interceptors/1, is_lightweight/0, get_lightweight_nodes/0, secure/0, + set_interceptors/1, is_lightweight/0, get_lightweight_nodes/0, secure/0, iiop_ssl_backlog/0, iiop_ssl_port/0, nat_iiop_ssl_port/0, nat_iiop_ssl_port/1, + ssl_server_options/0, ssl_client_options/0, set_ssl_client_options/1, ssl_server_certfile/0, ssl_client_certfile/0, set_ssl_client_certfile/1, ssl_server_verify/0, ssl_client_verify/0, set_ssl_client_verify/1, ssl_server_depth/0, ssl_client_depth/0, set_ssl_client_depth/1, - ssl_server_cacertfile/0, ssl_client_cacertfile/0, + ssl_server_cacertfile/0, ssl_client_cacertfile/0, set_ssl_client_cacertfile/1, ssl_client_password/0, ssl_server_password/0, ssl_client_keyfile/0, ssl_server_keyfile/0, ssl_client_ciphers/0, ssl_server_ciphers/0, ssl_client_cachetimeout/0, - ssl_server_cachetimeout/0, get_flags/0, typechecking/0, + ssl_server_cachetimeout/0, + get_flags/0, typechecking/0, exclude_codeset_ctx/0, exclude_codeset_component/0, partial_security/0, use_CSIv2/0, use_FT/0, ip_version/0, light_ifr/0, bidir_context/0, get_debug_level/0, getaddrstr/2, addr2str/1, iiop_packet_size/0, - iiop_ssl_ip_address_local/0, ip_address_local/0, iiop_in_keepalive/0, + iiop_ssl_ip_address_local/0, ip_address_local/0, iiop_in_keepalive/0, iiop_out_keepalive/0, iiop_ssl_in_keepalive/0, iiop_ssl_out_keepalive/0, iiop_ssl_accept_timeout/0, ssl_generation/0]). @@ -87,38 +89,39 @@ [flags, iiop_port, nat_iiop_port, iiop_out_ports, domain, ip_address, nat_ip_address, giop_version, iiop_timeout, iiop_connection_timeout, iiop_setup_connection_timeout, iiop_in_connection_timeout, iiop_acl, - iiop_max_fragments, iiop_max_in_requests, iiop_max_in_connections, + iiop_max_fragments, iiop_max_in_requests, iiop_max_in_connections, iiop_backlog, objectkeys_gc_time, orbInitRef, orbDefaultInitRef, interceptors, local_interceptors, lightweight, ip_address_local, - secure, iiop_ssl_ip_address_local, iiop_ssl_backlog, - iiop_ssl_port, nat_iiop_ssl_port, ssl_server_certfile, - ssl_client_certfile, ssl_server_verify, ssl_client_verify, ssl_server_depth, - ssl_client_depth, ssl_server_cacertfile, ssl_client_cacertfile, - ssl_client_password, ssl_server_password, ssl_client_keyfile, - ssl_server_keyfile, ssl_client_ciphers, ssl_server_ciphers, + secure, iiop_ssl_ip_address_local, iiop_ssl_backlog, + iiop_ssl_port, nat_iiop_ssl_port, ssl_server_certfile, + ssl_client_certfile, ssl_server_verify, ssl_client_verify, ssl_server_depth, + ssl_client_depth, ssl_server_cacertfile, ssl_client_cacertfile, + ssl_client_password, ssl_server_password, ssl_client_keyfile, + ssl_server_keyfile, ssl_client_ciphers, ssl_server_ciphers, ssl_client_cachetimeout, ssl_server_cachetimeout, orber_debug_level, iiop_packet_size, iiop_in_keepalive, iiop_out_keepalive, - iiop_ssl_in_keepalive, iiop_ssl_out_keepalive, iiop_ssl_accept_timeout]). + iiop_ssl_in_keepalive, iiop_ssl_out_keepalive, iiop_ssl_accept_timeout, + ssl_server_options, ssl_client_options]). %% The 'flags' parameter must be first in the list. %-define(ENV_KEYS, -% [{flags, ?ORB_ENV_INIT_FLAGS}, {iiop_port, 4001}, nat_iiop_port, -% {iiop_out_ports, 0}, {domain, "ORBER"}, ip_address, nat_ip_address, -% {giop_version, {1, 1}}, {iiop_timeout, infinity}, -% {iiop_connection_timeout, infinity}, {iiop_setup_connection_timeout, infinity}, +% [{flags, ?ORB_ENV_INIT_FLAGS}, {iiop_port, 4001}, nat_iiop_port, +% {iiop_out_ports, 0}, {domain, "ORBER"}, ip_address, nat_ip_address, +% {giop_version, {1, 1}}, {iiop_timeout, infinity}, +% {iiop_connection_timeout, infinity}, {iiop_setup_connection_timeout, infinity}, % {iiop_in_connection_timeout, infinity}, {iiop_acl, []}, -% {iiop_max_fragments, infinity}, {iiop_max_in_requests, infinity}, -% {iiop_max_in_connections, infinity}, {iiop_backlog, 5}, -% {objectkeys_gc_time, infinity}, +% {iiop_max_fragments, infinity}, {iiop_max_in_requests, infinity}, +% {iiop_max_in_connections, infinity}, {iiop_backlog, 5}, +% {objectkeys_gc_time, infinity}, % {orbInitRef, undefined}, {orbDefaultInitRef, undefined}, % {interceptors, false}, {local_interceptors, false}, {lightweight, false}, -% {secure, no}, {iiop_ssl_backlog, 5}, {iiop_ssl_port, 4002}, +% {secure, no}, {iiop_ssl_backlog, 5}, {iiop_ssl_port, 4002}, % nat_iiop_ssl_port, {ssl_server_certfile, []}, {ssl_client_certfile, []}, -% {ssl_server_verify, 0}, {ssl_client_verify, 0}, {ssl_server_depth, 1}, -% {ssl_client_depth, 1}, {ssl_server_cacertfile, []}, +% {ssl_server_verify, 0}, {ssl_client_verify, 0}, {ssl_server_depth, 1}, +% {ssl_client_depth, 1}, {ssl_server_cacertfile, []}, % {ssl_client_cacertfile, []}, {ssl_client_password, []}, -% {ssl_server_password, []}, {ssl_client_keyfile, []}, -% {ssl_server_keyfile, []}, {ssl_client_ciphers, []}, +% {ssl_server_password, []}, {ssl_client_keyfile, []}, +% {ssl_server_keyfile, []}, {ssl_client_ciphers, []}, % {ssl_server_ciphers, []}, {ssl_client_cachetimeout, infinity}, % {ssl_server_cachetimeout, infinity}, {orber_debug_level, 0}]). @@ -129,33 +132,33 @@ %%----------------------------------------------------------------- %% External functions -%%----------------------------------------------------------------- %%----------------------------------------------------------------- -%% function : -%% Arguments: -%% Returns : -%% Exception: -%% Effect : +%%----------------------------------------------------------------- +%% function : +%% Arguments: +%% Returns : +%% Exception: +%% Effect : %%----------------------------------------------------------------- start(Opts) -> gen_server:start_link({local, orber_env}, ?MODULE, Opts, []). %%----------------------------------------------------------------- %% function : get_keys -%% Arguments: -%% Returns : -%% Exception: -%% Effect : +%% Arguments: +%% Returns : +%% Exception: +%% Effect : %%----------------------------------------------------------------- get_keys() -> ?ENV_KEYS. %%----------------------------------------------------------------- %% function : get_env -%% Arguments: -%% Returns : -%% Exception: -%% Effect : +%% Arguments: +%% Returns : +%% Exception: +%% Effect : %%----------------------------------------------------------------- get_env(Key) when is_atom(Key) -> case catch ets:lookup(?ENV_DB, Key) of @@ -164,13 +167,13 @@ get_env(Key) when is_atom(Key) -> _ -> undefined end. - + %%----------------------------------------------------------------- %% function : get_env -%% Arguments: -%% Returns : -%% Exception: -%% Effect : +%% Arguments: +%% Returns : +%% Exception: +%% Effect : %%----------------------------------------------------------------- set_env(Key, Value) when is_atom(Key) -> case catch ets:insert(?ENV_DB, #parameters{key = Key, value = Value}) of @@ -179,20 +182,20 @@ set_env(Key, Value) when is_atom(Key) -> _ -> undefined end. - + %%----------------------------------------------------------------- %% function : info %% Arguments: IoDervice - info_msg | string | io | {io, Dev} -%% Returns : -%% Exception: -%% Effect : +%% Returns : +%% Exception: +%% Effect : %%----------------------------------------------------------------- info() -> info(info_msg). info(IoDevice) -> - Info = + Info = case orber_tb:is_running() of true -> Info1 = create_main_info(), @@ -211,7 +214,7 @@ info(IoDevice) -> string -> Info; io -> - io:format("~s", [Info]); + io:format("~s", [Info]); {io, Dev} -> io:format(Dev, "~s", [Info]); _ -> @@ -220,14 +223,14 @@ info(IoDevice) -> create_main_info() -> {Major, Minor} = giop_version(), - [io_lib:format("======= Orber Execution Environment ======~n" + [io_lib:format("======= Orber Execution Environment ======~n" "Orber version.................: ~s~n" "Orber domain..................: ~s~n" "IIOP port number..............: ~p~n" "IIOP NAT port number..........: ~p~n" "Interface(s)..................: ~p~n" "Interface(s) NAT..............: ~p~n" - "Local Interface (default).....: ~p~n" + "Local Interface (default).....: ~p~n" "Nodes in domain...............: ~p~n" "GIOP version (default)........: ~p.~p~n" "IIOP out timeout..............: ~p msec~n" @@ -254,18 +257,18 @@ create_main_info() -> "Debug Level...................: ~p~n" "orbInitRef....................: ~p~n" "orbDefaultInitRef.............: ~p~n", - [?ORBVSN, domain(), iiop_port(), nat_iiop_port(), host(), + [?ORBVSN, domain(), iiop_port(), nat_iiop_port(), host(), nat_host(), ip_address_local(), orber:orber_nodes(), Major, Minor, - iiop_timeout(), iiop_connection_timeout(), + iiop_timeout(), iiop_connection_timeout(), iiop_setup_connection_timeout(), iiop_out_ports(), iiop_out_ports_attempts(), iiop_out_ports_random(), - orber:iiop_connections(out), orber:iiop_connections_pending(), - iiop_out_keepalive(), orber:iiop_connections(in), - iiop_in_connection_timeout(), iiop_in_keepalive(), - iiop_max_fragments(), iiop_max_in_requests(), + orber:iiop_connections(out), orber:iiop_connections_pending(), + iiop_out_keepalive(), orber:iiop_connections(in), + iiop_in_connection_timeout(), iiop_in_keepalive(), + iiop_max_fragments(), iiop_max_in_requests(), iiop_max_in_connections(), iiop_backlog(), iiop_acl(), - iiop_packet_size(), objectkeys_gc_time(), get_interceptors(), + iiop_packet_size(), objectkeys_gc_time(), get_interceptors(), get_local_interceptors(), get_debug_level(), get_ORBInitRef(), get_ORBDefaultInitRef()])]. @@ -277,7 +280,7 @@ create_flag_info(Info) -> FlagData = check_flags(?ORB_ENV_FLAGS, Flags, []), [Info, "System Flags Set..............: \n", FlagData, "\n"] end. - + check_flags([], _, Acc) -> Acc; check_flags([{Flag, Txt}|T], Flags, Acc) when ?ORB_FLAG_TEST(Flags, Flag) -> @@ -289,7 +292,7 @@ check_flags([_|T], Flags, Acc) -> create_security_info(no, Info) -> lists:flatten([Info, "=========================================\n"]); create_security_info(ssl, Info) -> - lists:flatten([Info, + lists:flatten([Info, io_lib:format("ORB security..................: ssl~n" "SSL generation................: ~p~n" "SSL IIOP in keepalive.........: ~p~n" @@ -316,26 +319,26 @@ create_security_info(ssl, Info) -> "SSL client ciphers............: ~p~n" "SSL client cachetimeout.......: ~p~n" "=========================================~n", - [ssl_generation(), iiop_ssl_port(), + [ssl_generation(), iiop_ssl_port(), iiop_ssl_in_keepalive(), iiop_ssl_out_keepalive(), - nat_iiop_ssl_port(), iiop_ssl_accept_timeout(), + nat_iiop_ssl_port(), iiop_ssl_accept_timeout(), iiop_ssl_backlog(), iiop_ssl_ip_address_local(), ssl_server_certfile(), ssl_server_verify(), - ssl_server_depth(), ssl_server_cacertfile(), - ssl_server_keyfile(), ssl_server_password(), + ssl_server_depth(), ssl_server_cacertfile(), + ssl_server_keyfile(), ssl_server_password(), ssl_server_ciphers(), ssl_server_cachetimeout(), - ssl_client_certfile(), ssl_client_verify(), - ssl_client_depth(), ssl_client_cacertfile(), + ssl_client_certfile(), ssl_client_verify(), + ssl_client_depth(), ssl_client_cacertfile(), ssl_client_keyfile(), ssl_client_password(), ssl_client_ciphers(), ssl_client_cachetimeout()])]). %%----------------------------------------------------------------- %% function : iiop_acl -%% Arguments: -%% Returns : -%% Exception: -%% Effect : +%% Arguments: +%% Returns : +%% Exception: +%% Effect : %%----------------------------------------------------------------- iiop_acl() -> case application:get_env(orber, iiop_acl) of @@ -352,7 +355,7 @@ iiop_packet_size() -> _ -> infinity end. - + iiop_port() -> case application:get_env(orber, iiop_port) of @@ -368,7 +371,7 @@ nat_iiop_port() -> Port; {ok, {local, Default, _NATList}} -> Default; - _ -> + _ -> iiop_port() end. @@ -378,7 +381,7 @@ nat_iiop_port(LocalPort) -> Port; {ok, {local, Default, NATList}} -> orber_tb:keysearch(LocalPort, NATList, Default); - _ -> + _ -> iiop_port() end. @@ -407,9 +410,9 @@ iiop_out_ports_attempts() -> _ -> 1 end. - -domain() -> + +domain() -> case application:get_env(orber, domain) of {ok, Domain} when is_list(Domain) -> Domain; @@ -449,7 +452,7 @@ nat_host([Host]) -> {ok,{multiple, [I|_] = IList}} when is_list(I) -> IList; {ok,{local, Default, NATList}} -> - [orber_tb:keysearch(Host, NATList, Default)]; + [orber_tb:keysearch(Host, NATList, Default)]; _ -> host() end. @@ -462,7 +465,7 @@ host() -> {ok,{multiple, [I|_] = IList}} when is_list(I) -> IList; %% IPv4. For IPv6 we only accept a string, but we must support this format - %% for IPv4 + %% for IPv4 {ok, {A1, A2, A3, A4}} when is_integer(A1+A2+A3+A4) -> [integer_to_list(A1) ++ "." ++ integer_to_list(A2) ++ "." ++ integer_to_list(A3) ++ "." ++ integer_to_list(A4)]; @@ -489,7 +492,7 @@ ip_address_local() -> _ -> [] end. - + ip_address() -> ip_address(ip_version()). @@ -526,7 +529,7 @@ addr2str({A1, A2, A3, A4, A5, A6, A7, A8}) -> int16_to_hex(A3) ++ ":" ++ int16_to_hex(A4) ++ ":" ++ int16_to_hex(A5) ++ ":" ++ int16_to_hex(A6) ++ ":" ++ int16_to_hex(A7) ++ ":" ++ int16_to_hex(A8). - + int16_to_hex(0) -> [$0]; @@ -613,7 +616,7 @@ iiop_max_fragments() -> _ -> infinity end. - + iiop_max_in_requests() -> case application:get_env(orber, iiop_max_in_requests) of {ok, Max} when is_integer(Max) andalso Max > 0 -> @@ -653,7 +656,7 @@ iiop_out_keepalive() -> _ -> false end. - + get_flags() -> @@ -706,9 +709,9 @@ bidir_context() -> ?ORB_FLAG_TEST(Flags, ?ORB_ENV_USE_BI_DIR_IIOP) -> [#'IOP_ServiceContext' {context_id=?IOP_BI_DIR_IIOP, - context_data = - #'IIOP_BiDirIIOPServiceContext'{listen_points = - [#'IIOP_ListenPoint'{host=host(), + context_data = + #'IIOP_BiDirIIOPServiceContext'{listen_points = + [#'IIOP_ListenPoint'{host=host(), port=iiop_port()}]}}]; true -> [] @@ -819,7 +822,7 @@ get_lightweight_nodes() -> _ -> false end. - + %%----------------------------------------------------------------- %% Security access operations (SSL) @@ -838,8 +841,8 @@ ssl_generation() -> V; _ -> 2 - end. - + end. + iiop_ssl_ip_address_local() -> case application:get_env(orber, iiop_ssl_ip_address_local) of {ok,I} when is_list(I) -> @@ -876,10 +879,10 @@ iiop_ssl_accept_timeout() -> case application:get_env(orber, iiop_ssl_accept_timeout) of {ok, N} when is_integer(N) -> N * 1000; - _ -> + _ -> infinity end. - + iiop_ssl_port() -> case application:get_env(orber, secure) of {ok, ssl} -> @@ -923,6 +926,52 @@ nat_iiop_ssl_port(LocalPort) -> -1 end. +ssl_server_options() -> + case application:get_env(orber, ssl_server_options) of + {ok, V1} when is_list(V1) -> + V1; + _ -> + [] + end. + +ssl_client_options() -> + case application:get_env(orber, ssl_client_options) of + {ok, V1} when is_list(V1) -> + V1; + _ -> + [] + end. + +check_ssl_opts(Value) -> + check_ssl_opts(Value, []). +check_ssl_opts([], []) -> + ok; +check_ssl_opts([], Acc) -> + {error, Acc}; +check_ssl_opts([{active, _} |T], Acc) -> + check_ssl_opts(T, [active |Acc]); +check_ssl_opts([{packet, _} |T], Acc) -> + check_ssl_opts(T, [packet |Acc]); +check_ssl_opts([{mode, _} |T], Acc) -> + check_ssl_opts(T, [mode |Acc]); +check_ssl_opts([list |T], Acc) -> + check_ssl_opts(T, [list |Acc]); +check_ssl_opts([binary |T], Acc) -> + check_ssl_opts(T, [binary |Acc]); +check_ssl_opts([_ |T], Acc) -> + check_ssl_opts(T, Acc). + +set_ssl_client_options(Value) when is_list(Value) -> + case check_ssl_opts(Value) of + ok -> + ok; + {error, List} -> + exit(lists:flatten( + io_lib:format("TCP options ~p is not allowed in set_ssl_client_options()", + [List]))) + end, + put(ssl_client_options, Value), ok. + ssl_server_certfile() -> case application:get_env(orber, ssl_server_certfile) of {ok, V1} when is_list(V1) -> @@ -932,7 +981,7 @@ ssl_server_certfile() -> _ -> [] end. - + ssl_client_certfile() -> case get(ssl_client_certfile) of undefined -> @@ -950,7 +999,7 @@ ssl_client_certfile() -> set_ssl_client_certfile(Value) when is_list(Value) -> put(ssl_client_certfile, Value). - + ssl_server_verify() -> Verify = case application:get_env(orber, ssl_server_verify) of {ok, V} when is_integer(V) -> @@ -964,7 +1013,7 @@ ssl_server_verify() -> true -> 0 end. - + ssl_client_verify() -> Verify = case get(ssl_client_verify) of undefined -> @@ -986,7 +1035,7 @@ ssl_client_verify() -> set_ssl_client_verify(Value) when is_integer(Value) andalso Value =< 2 andalso Value >= 0 -> put(ssl_client_verify, Value), ok. - + ssl_server_depth() -> case application:get_env(orber, ssl_server_depth) of {ok, V1} when is_integer(V1) -> @@ -994,7 +1043,7 @@ ssl_server_depth() -> _ -> 1 end. - + ssl_client_depth() -> case get(ssl_client_depth) of undefined -> @@ -1010,7 +1059,7 @@ ssl_client_depth() -> set_ssl_client_depth(Value) when is_integer(Value) -> put(ssl_client_depth, Value), ok. - + ssl_server_cacertfile() -> @@ -1022,7 +1071,7 @@ ssl_server_cacertfile() -> _ -> [] end. - + ssl_client_cacertfile() -> case get(ssl_client_cacertfile) of undefined -> @@ -1040,7 +1089,7 @@ ssl_client_cacertfile() -> set_ssl_client_cacertfile(Value) when is_list(Value) -> put(ssl_client_cacertfile, Value), ok. - + ssl_client_password() -> case application:get_env(orber, ssl_client_password) of @@ -1108,10 +1157,10 @@ ssl_server_cachetimeout() -> %%----------------------------------------------------------------- %% function : configure -%% Arguments: -%% Returns : -%% Exception: -%% Effect : +%% Arguments: +%% Returns : +%% Exception: +%% Effect : %%----------------------------------------------------------------- configure(Key, Value) when is_atom(Key) -> configure(Key, Value, check); @@ -1125,10 +1174,10 @@ configure_override(Key, _) -> %%----------------------------------------------------------------- %% function : multi_configure -%% Arguments: -%% Returns : -%% Exception: -%% Effect : +%% Arguments: +%% Returns : +%% Exception: +%% Effect : %%----------------------------------------------------------------- multi_configure(KeyValueList) when is_list(KeyValueList) -> case orber_tb:is_loaded() of @@ -1144,7 +1193,7 @@ multi_configure(KeyValueList) when is_list(KeyValueList) -> end end; multi_configure(KeyValueList) -> - ?EFORMAT("Given configuration parameters not a Key-Value-pair list: ~p", + ?EFORMAT("Given configuration parameters not a Key-Value-pair list: ~p", [KeyValueList]). multi_configure_helper([], _) -> @@ -1237,7 +1286,7 @@ configure(iiop_port, Value, Status) when is_integer(Value) -> %% Set the NAT listen port configure(nat_iiop_port, Value, Status) when is_integer(Value) andalso Value > 0 -> do_safe_configure(nat_iiop_port, Value, Status); -configure(nat_iiop_port, {local, Value1, Value2}, Status) when is_integer(Value1) andalso +configure(nat_iiop_port, {local, Value1, Value2}, Status) when is_integer(Value1) andalso Value1 > 0 andalso is_list(Value2) -> do_safe_configure(nat_iiop_port, {local, Value1, Value2}, Status); @@ -1312,12 +1361,20 @@ configure(iiop_ssl_backlog, Value, Status) when is_integer(Value) andalso Value do_safe_configure(iiop_ssl_backlog, Value, Status); configure(nat_iiop_ssl_port, Value, Status) when is_integer(Value) andalso Value > 0 -> do_safe_configure(nat_iiop_ssl_port, Value, Status); -configure(nat_iiop_ssl_port, {local, Value1, Value2}, Status) when is_integer(Value1) andalso +configure(nat_iiop_ssl_port, {local, Value1, Value2}, Status) when is_integer(Value1) andalso Value1 > 0 andalso is_list(Value2) -> do_safe_configure(nat_iiop_ssl_port, {local, Value1, Value2}, Status); configure(iiop_ssl_port, Value, Status) when is_integer(Value) -> do_safe_configure(iiop_ssl_port, Value, Status); + +%% New SSL options +configure(ssl_server_options, Value, Status) when is_list(Value) -> + do_safe_configure(ssl_server_options, Value, Status); +configure(ssl_client_options, Value, Status) when is_list(Value) -> + do_safe_configure(ssl_client_options, Value, Status); + +%% Old SSL options configure(ssl_server_certfile, Value, Status) when is_list(Value) -> do_safe_configure(ssl_server_certfile, Value, Status); configure(ssl_server_certfile, Value, Status) when is_atom(Value) -> @@ -1434,9 +1491,9 @@ code_change(_OldVsn, State, _Extra) -> %%----------------------------------------------------------------- %% function : env -%% Arguments: -%% Returns : -%% Exception: +%% Arguments: +%% Returns : +%% Exception: %% Effect : Used when Key always exists (Default Value) %%----------------------------------------------------------------- env(Key) -> @@ -1445,10 +1502,10 @@ env(Key) -> %%----------------------------------------------------------------- %% function : init_env -%% Arguments: -%% Returns : -%% Exception: -%% Effect : +%% Arguments: +%% Returns : +%% Exception: +%% Effect : %%----------------------------------------------------------------- init_env() -> application:load(orber), diff --git a/lib/orber/src/orber_iiop_net.erl b/lib/orber/src/orber_iiop_net.erl index 58eba9f039..55caa5dd33 100644 --- a/lib/orber/src/orber_iiop_net.erl +++ b/lib/orber/src/orber_iiop_net.erl @@ -161,31 +161,51 @@ terminate(_Reason, _State) -> %%----------------------------------------------------------------- get_options(normal, _Options) -> []; -get_options(ssl, Options) -> - Verify = orber_tb:keysearch(ssl_server_verify, Options, - orber_env:ssl_server_verify()), - Depth = orber_tb:keysearch(ssl_server_depth, Options, - orber_env:ssl_server_depth()), - Cert = orber_tb:keysearch(ssl_server_certfile, Options, - orber_env:ssl_server_certfile()), - CaCert = orber_tb:keysearch(ssl_server_cacertfile, Options, - orber_env:ssl_server_cacertfile()), - Pwd = orber_tb:keysearch(ssl_server_password, Options, - orber_env:ssl_server_password()), - Key = orber_tb:keysearch(ssl_server_keyfile, Options, - orber_env:ssl_server_keyfile()), - Ciphers = orber_tb:keysearch(ssl_server_ciphers, Options, - orber_env:ssl_server_ciphers()), - Timeout = orber_tb:keysearch(ssl_server_cachetimeout, Options, - orber_env:ssl_server_cachetimeout()), - [{verify, Verify}, - {depth, Depth} | - ssl_server_extra_options([{certfile, Cert}, - {cacertfile, CaCert}, - {password, Pwd}, - {keyfile, Key}, - {ciphers, Ciphers}, - {cachetimeout, Timeout}], [])]. +get_options(ssl, Options) -> + SSLOpts = + case orber_tb:keysearch(ssl_server_options, Options, + orber_env:ssl_server_options()) of + [] -> + Verify = orber_tb:keysearch(ssl_server_verify, Options, + orber_env:ssl_server_verify()), + Depth = orber_tb:keysearch(ssl_server_depth, Options, + orber_env:ssl_server_depth()), + Cert = orber_tb:keysearch(ssl_server_certfile, Options, + orber_env:ssl_server_certfile()), + CaCert = orber_tb:keysearch(ssl_server_cacertfile, Options, + orber_env:ssl_server_cacertfile()), + Pwd = orber_tb:keysearch(ssl_server_password, Options, + orber_env:ssl_server_password()), + Key = orber_tb:keysearch(ssl_server_keyfile, Options, + orber_env:ssl_server_keyfile()), + Ciphers = orber_tb:keysearch(ssl_server_ciphers, Options, + orber_env:ssl_server_ciphers()), + Timeout = orber_tb:keysearch(ssl_server_cachetimeout, Options, + orber_env:ssl_server_cachetimeout()), + KeepAlive = orber_tb:keysearch(ssl_server_cachetimeout, Options, + orber_env:iiop_ssl_in_keepalive()), + [{verify, Verify}, + {depth, Depth}, + {certfile, Cert}, + {cacertfile, CaCert}, + {password, Pwd}, + {keyfile, Key}, + {ciphers, Ciphers}, + {cachetimeout, Timeout}, + {keepalive, KeepAlive}]; + Opts -> + case orber_tb:check_illegal_tcp_options(Opts) of + ok -> + check_old_ssl_server_options(Options), + Opts; + {error, IllegalOpts} -> + error_logger:error_report([{application, orber}, + "TCP options not allowed to set on a connection", + IllegalOpts]), + error("Illegal TCP option") + end + end, + ssl_server_extra_options(SSLOpts, []). %%----------------------------------------------------------------- %% Func: parse_options/2 @@ -266,23 +286,28 @@ handle_call({add, IP, Type, Port, AllOptions}, _From, State) -> Family = orber_env:ip_version(), case inet:getaddr(IP, Family) of {ok, IPTuple} -> - Options = [{ip, IPTuple}|get_options(Type, AllOptions)], - Ref = make_ref(), - ProxyOptions = filter_options(AllOptions, []), - case orber_socket:listen(Type, Port, Options, false) of - {ok, Listen, NewPort} -> - {ok, Pid} = orber_iiop_socketsup:start_accept(Type, Listen, Ref, - ProxyOptions), - link(Pid), - ets:insert(?CONNECTION_DB, #listen{pid = Pid, - socket = Listen, - port = NewPort, - type = Type, ref = Ref, - options = Options, - proxy_options = ProxyOptions}), - {reply, {ok, Ref}, State}; - Error -> - {reply, Error, State} + try [{ip, IPTuple} |get_options(Type, AllOptions)] of + Options -> + Ref = make_ref(), + ProxyOptions = filter_options(AllOptions, []), + case orber_socket:listen(Type, Port, Options, false) of + {ok, Listen, NewPort} -> + {ok, Pid} = orber_iiop_socketsup:start_accept(Type, Listen, Ref, + ProxyOptions), + link(Pid), + ets:insert(?CONNECTION_DB, #listen{pid = Pid, + socket = Listen, + port = NewPort, + type = Type, ref = Ref, + options = Options, + proxy_options = ProxyOptions}), + {reply, {ok, Ref}, State}; + Error -> + {reply, Error, State} + end + catch + error:Reason -> + {reply, {error, Reason}, State} end; Other -> {reply, Other, State} @@ -461,3 +486,31 @@ update_counter(#state{max_connections = infinity} = State, _) -> update_counter(State, Value) -> State#state{counter = State#state.counter + Value}. + +check_old_ssl_server_options(Options) -> + try + 0 = orber_tb:keysearch(ssl_server_verify, Options, + orber_env:ssl_server_verify()), + 1 = orber_tb:keysearch(ssl_server_depth, Options, + orber_env:ssl_server_depth()), + [] = orber_tb:keysearch(ssl_server_certfile, Options, + orber_env:ssl_server_certfile()), + [] = orber_tb:keysearch(ssl_server_cacertfile, Options, + orber_env:ssl_server_cacertfile()), + [] = orber_tb:keysearch(ssl_server_password, Options, + orber_env:ssl_server_password()), + [] = orber_tb:keysearch(ssl_server_keyfile, Options, + orber_env:ssl_server_keyfile()), + [] = orber_tb:keysearch(ssl_server_ciphers, Options, + orber_env:ssl_server_ciphers()), + infinity = orber_tb:keysearch(ssl_server_cachetimeout, Options, + orber_env:ssl_server_cachetimeout()), + false = orber_tb:keysearch(iiop_ssl_in_keepalive, Options, + orber_env:iiop_ssl_in_keepalive()) + catch + _:_ -> + io:format("hej\n",[]), + error_logger:warning_report([{application, orber}, + "Ignoring deprecated ssl server options used together with the ssl_server_options"]) + end. + diff --git a/lib/orber/src/orber_iiop_pm.erl b/lib/orber/src/orber_iiop_pm.erl index bf36b353bc..3c8c7a09f4 100644 --- a/lib/orber/src/orber_iiop_pm.erl +++ b/lib/orber/src/orber_iiop_pm.erl @@ -108,44 +108,82 @@ connect(Host, Port, SocketType, Timeout, Chars, Wchars, Ctx) end. get_ssl_socket_options([]) -> - [{verify, orber:ssl_client_verify()}, - {depth, orber:ssl_client_depth()} | - ssl_client_extra_options([{certfile, orber:ssl_client_certfile()}, - {cacertfile, orber:ssl_client_cacertfile()}, - {password, orber:ssl_client_password()}, - {keyfile, orber:ssl_client_keyfile()}, - {ciphers, orber:ssl_client_ciphers()}, - {cachetimeout, orber:ssl_client_cachetimeout()}], [])]; + SSLOpts = + case orber_env:ssl_client_options() of + [] -> + [{verify, orber_env:ssl_client_verify()}, + {depth, orber_env:ssl_client_depth()}, + {certfile, orber_env:ssl_client_certfile()}, + {cacertfile, orber_env:ssl_client_cacertfile()}, + {password, orber_env:ssl_client_password()}, + {keyfile, orber_env:ssl_client_keyfile()}, + {ciphers, orber_env:ssl_client_ciphers()}, + {cachetimeout, orber_env:ssl_client_cachetimeout()}, + {keepalive, orber_env:iiop_ssl_out_keepalive()}]; + Opts -> + case orber_tb:check_illegal_tcp_options(Opts) of + ok -> + check_old_ssl_client_options([]), + Opts; + {error, IllegalOpts} -> + error_logger:error_report([{application, orber}, + "TCP options not allowed to set on a connection", + IllegalOpts]), + error("Illegal TCP option") + end + end, + ssl_client_extra_options(SSLOpts, []); get_ssl_socket_options([#'IOP_ServiceContext' {context_id=?ORBER_GENERIC_CTX_ID, context_data = {configuration, Options}}|_]) -> - Verify = orber_tb:keysearch(ssl_client_verify, Options, - orber_env:ssl_client_verify()), - Depth = orber_tb:keysearch(ssl_client_depth, Options, - orber_env:ssl_client_depth()), - Cert = orber_tb:keysearch(ssl_client_certfile, Options, - orber_env:ssl_client_certfile()), - CaCert = orber_tb:keysearch(ssl_client_cacertfile, Options, - orber_env:ssl_client_cacertfile()), - Pwd = orber_tb:keysearch(ssl_client_password, Options, - orber_env:ssl_client_password()), - Key = orber_tb:keysearch(ssl_client_keyfile, Options, - orber_env:ssl_client_keyfile()), - Ciphers = orber_tb:keysearch(ssl_client_ciphers, Options, - orber_env:ssl_client_ciphers()), - Timeout = orber_tb:keysearch(ssl_client_cachetimeout, Options, - orber_env:ssl_client_cachetimeout()), - [{verify, Verify}, - {depth, Depth} | - ssl_client_extra_options([{certfile, Cert}, - {cacertfile, CaCert}, - {password, Pwd}, - {keyfile, Key}, - {ciphers, Ciphers}, - {cachetimeout, Timeout}], [])]; + SSLOpts = + case orber_tb:keysearch(ssl_client_options, Options, + orber_env:ssl_client_options()) of + [] -> + Verify = orber_tb:keysearch(ssl_client_verify, Options, + orber_env:ssl_client_verify()), + Depth = orber_tb:keysearch(ssl_client_depth, Options, + orber_env:ssl_client_depth()), + Cert = orber_tb:keysearch(ssl_client_certfile, Options, + orber_env:ssl_client_certfile()), + CaCert = orber_tb:keysearch(ssl_client_cacertfile, Options, + orber_env:ssl_client_cacertfile()), + Pwd = orber_tb:keysearch(ssl_client_password, Options, + orber_env:ssl_client_password()), + Key = orber_tb:keysearch(ssl_client_keyfile, Options, + orber_env:ssl_client_keyfile()), + Ciphers = orber_tb:keysearch(ssl_client_ciphers, Options, + orber_env:ssl_client_ciphers()), + Timeout = orber_tb:keysearch(ssl_client_cachetimeout, Options, + orber_env:ssl_client_cachetimeout()), + KeepAlive = orber_tb:keysearch(ssl_server_cachetimeout, Options, + orber_env:iiop_ssl_out_keepalive()), + [{verify, Verify}, + {depth, Depth}, + {certfile, Cert}, + {cacertfile, CaCert}, + {password, Pwd}, + {keyfile, Key}, + {ciphers, Ciphers}, + {cachetimeout, Timeout}, + {keepalive, KeepAlive}]; + Opts -> + case orber_tb:check_illegal_tcp_options(Opts) of + ok -> + check_old_ssl_client_options(Options), + Opts; + {error, IllegalOpts} -> + error_logger:error_report([{application, orber}, + "TCP options not allowed to set on a connection", + IllegalOpts]), + error("Illegal TCP option") + end + end, + ssl_client_extra_options(SSLOpts, []); get_ssl_socket_options([_|T]) -> get_ssl_socket_options(T). + ssl_client_extra_options([], Acc) -> Acc; ssl_client_extra_options([{_Type, []}|T], Acc) -> @@ -814,6 +852,36 @@ init_interceptors(Host, Port, {SHost, SPort}) -> %% Either 'false' or {Type, PIs}. Other end. + + +check_old_ssl_client_options(Options) -> + try + 0 = orber_tb:keysearch(ssl_client_verify, Options, + orber_env:ssl_client_verify()), + 1 = orber_tb:keysearch(ssl_client_depth, Options, + orber_env:ssl_client_depth()), + [] = orber_tb:keysearch(ssl_client_certfile, Options, + orber_env:ssl_client_certfile()), + [] = orber_tb:keysearch(ssl_client_cacertfile, Options, + orber_env:ssl_client_cacertfile()), + [] = orber_tb:keysearch(ssl_client_password, Options, + orber_env:ssl_client_password()), + [] = orber_tb:keysearch(ssl_client_keyfile, Options, + orber_env:ssl_client_keyfile()), + [] = orber_tb:keysearch(ssl_client_ciphers, Options, + orber_env:ssl_client_ciphers()), + infinity = orber_tb:keysearch(ssl_client_cachetimeout, Options, + orber_env:ssl_client_cachetimeout()), + false = orber_tb:keysearch(iiop_ssl_out_keepalive, Options, + orber_env:iiop_ssl_out_keepalive()) + + catch + _:_ -> + error_logger:warning_report([{application, orber}, + "Ignoring deprecated ssl client options used together with the ssl_client_options"]) + end. + + %%----------------------------------------------------------------- diff --git a/lib/orber/src/orber_socket.erl b/lib/orber/src/orber_socket.erl index ec2cf8f42a..07a0e09ccc 100644 --- a/lib/orber/src/orber_socket.erl +++ b/lib/orber/src/orber_socket.erl @@ -14,8 +14,7 @@ %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% -%% %CopyrightEnd% +%%%% %CopyrightEnd% %% %% %%----------------------------------------------------------------- @@ -37,7 +36,7 @@ %%----------------------------------------------------------------- -export([start/0, connect/4, listen/3, listen/4, accept/2, accept/3, write/3, controlling_process/3, close/2, peername/2, sockname/2, - peerdata/2, peercert/2, sockdata/2, setopts/3, + peerdata/2, peercert/2, sockdata/2, setopts/3, clear/2, shutdown/3, post_accept/2, post_accept/3]). %%----------------------------------------------------------------- @@ -75,8 +74,6 @@ connect(Type, Host, Port, Options) -> case Type of normal -> [{keepalive, orber_env:iiop_out_keepalive()}|Options1]; - _ when Generation > 2 -> - [{keepalive, orber_env:iiop_ssl_out_keepalive()}|Options1]; _ -> Options1 end, @@ -251,8 +248,7 @@ listen(ssl, Port, Options, Exception) -> end, Options4 = if Generation > 2 -> - [{reuseaddr, true}, - {keepalive, orber_env:iiop_ssl_in_keepalive()}|Options3]; + [{reuseaddr, true} |Options3]; true -> Options3 end, @@ -362,8 +358,8 @@ peercert(ssl, Socket) -> ssl:peercert(Socket); peercert(Type, _Socket) -> orber:dbg("[~p] orber_socket:peercert(~p);~n" - "Only available for SSL sockets.", - [?LINE, Type], ?DEBUG_LEVEL), + "Only available for SSL sockets.", + [?LINE, Type], ?DEBUG_LEVEL), {error, ebadsocket}. %%----------------------------------------------------------------- diff --git a/lib/orber/src/orber_tb.erl b/lib/orber/src/orber_tb.erl index e6d5ee4400..cce95f7237 100644 --- a/lib/orber/src/orber_tb.erl +++ b/lib/orber/src/orber_tb.erl @@ -39,7 +39,8 @@ -compile({no_auto_import,[error/2]}). -export([wait_for_tables/1, wait_for_tables/2, wait_for_tables/3, is_loaded/0, is_loaded/1, is_running/0, is_running/1, - info/2, error/2, unique/1, keysearch/2, keysearch/3]). + info/2, error/2, unique/1, keysearch/2, keysearch/3, + check_illegal_tcp_options/1]). %%---------------------------------------------------------------------- %% Internal exports @@ -179,6 +180,38 @@ error(Format, Args) -> Args). + + + +%%---------------------------------------------------------------------- +%% function : check_illegal_tcp_options/1 +%% Arguments: +%% Returns : +%% Exception: +%% Effect : +%%---------------------------------------------------------------------- +check_illegal_tcp_options(Options) -> + check_illegal_tcp_options(Options, []). + +check_illegal_tcp_options([],[]) -> + ok; +check_illegal_tcp_options([],IllegalOpts) -> + {error, IllegalOpts}; +check_illegal_tcp_options([{active, V} |T], IllegalOpts) -> + check_illegal_tcp_options(T,[{active, V} |IllegalOpts]); +check_illegal_tcp_options([{packet, V} |T], IllegalOpts) -> + check_illegal_tcp_options(T,[{packet, V} |IllegalOpts]); +check_illegal_tcp_options([{mode, V} |T], IllegalOpts) -> + check_illegal_tcp_options(T,[{mode, V} |IllegalOpts]); +check_illegal_tcp_options([list |T], IllegalOpts) -> + check_illegal_tcp_options(T,[list |IllegalOpts]); +check_illegal_tcp_options([binary |T], IllegalOpts) -> + check_illegal_tcp_options(T,[binary |IllegalOpts]); +check_illegal_tcp_options([{reuseaddr, V} |T], IllegalOpts) -> + check_illegal_tcp_options(T,[{reuseaddr, V} |IllegalOpts]); +check_illegal_tcp_options([H|T], IllegalOpts) -> + check_illegal_tcp_options(T, IllegalOpts). + %%---------------------------------------------------------------------- %% Internal functions %%---------------------------------------------------------------------- diff --git a/lib/orber/test/Makefile b/lib/orber/test/Makefile index 996d0d1874..d4be009af3 100644 --- a/lib/orber/test/Makefile +++ b/lib/orber/test/Makefile @@ -176,6 +176,7 @@ clean: rm -f idl_output/* rm -f $(TARGET_FILES) rm -f errs core *~ + rm IDL-GENERATED docs: diff --git a/lib/orber/test/csiv2_SUITE.erl b/lib/orber/test/csiv2_SUITE.erl index 95cd8c56b3..60ffa1eb09 100644 --- a/lib/orber/test/csiv2_SUITE.erl +++ b/lib/orber/test/csiv2_SUITE.erl @@ -70,46 +70,46 @@ profiles = [#'IOP_TaggedProfile' {tag = ?TAG_INTERNET_IOP, - profile_data = + profile_data = #'IIOP_ProfileBody_1_1'{ iiop_version = #'IIOP_Version'{major = 1, minor = 2}, host = "127.0.0.1", port = 0, object_key = [0,86,66,1,0,0,0,24,47,70,77,65,95,67,73,82,80,77,65,78,95,80,79,65,95,83,69,67,85,82,69,0,0,0,0,4,0,0,4,186,0,0,2,10,81,218,65,185], - components = + components = [#'IOP_TaggedComponent'{tag = ?TAG_SSL_SEC_TRANS, component_data = #'SSLIOP_SSL'{ target_supports = 102, target_requires = 66, port = 49934}}, #'IOP_TaggedComponent'{tag = ?TAG_CSI_SEC_MECH_LIST, - component_data = + component_data = #'CSIIOP_CompoundSecMechList'{stateful = true, - mechanism_list = + mechanism_list = [#'CSIIOP_CompoundSecMech' {target_requires = 66, transport_mech = #'IOP_TaggedComponent'{ tag = ?TAG_TLS_SEC_TRANS, - component_data = + component_data = #'CSIIOP_TLS_SEC_TRANS'{ target_supports = 102, target_requires = 66, - addresses = + addresses = [#'CSIIOP_TransportAddress' {host_name = "127.0.0.1", port = 49934}]}}, - as_context_mech = + as_context_mech = #'CSIIOP_AS_ContextSec'{ target_supports = 0, target_requires = 0, client_authentication_mech = [], target_name = []}, - sas_context_mech = + sas_context_mech = #'CSIIOP_SAS_ContextSec'{ target_supports = 1024, target_requires = 0, - privilege_authorities = + privilege_authorities = [#'CSIIOP_ServiceConfiguration' {syntax = 1447174401, name = "Borland"}], @@ -124,7 +124,7 @@ supported_identity_types = 15}}]}}, #'IOP_TaggedComponent' {tag = ?TAG_CODE_SETS, - component_data = + component_data = #'CONV_FRAME_CodeSetComponentInfo'{'ForCharData' = #'CONV_FRAME_CodeSetComponent'{ native_code_set = 65537, @@ -151,15 +151,15 @@ -ifdef(false). %% PKIX1Explicit88 --define(AlgorithmIdentifier, +-define(AlgorithmIdentifier, #'AlgorithmIdentifier'{algorithm = ?OID, parameters = ?ANY}). -define(Validity, #'Validity'{notBefore = {utcTime, "19820102070533.8"}, notAfter = {generalTime, "19820102070533.8"}}). --define(SubjectPublicKeyInfo, - #'SubjectPublicKeyInfo'{algorithm = ?AlgorithmIdentifier, +-define(SubjectPublicKeyInfo, + #'SubjectPublicKeyInfo'{algorithm = ?AlgorithmIdentifier, subjectPublicKey = ?BIT_STR}). -define(AttributeTypeAndValue, @@ -178,26 +178,26 @@ -define(UniqueIdentifier, ?BIT_STR). --define(Extension, #'Extension'{extnID = ?OID, - critical = ?BOOLEAN, +-define(Extension, #'Extension'{extnID = ?OID, + critical = ?BOOLEAN, extnValue = ?OCTET_STR}). -define(Extensions, [?Extension]). -define(TBSCertificate, - #'TBSCertificate'{version = ?Version, - serialNumber = ?CertificateSerialNumber, - signature = ?AlgorithmIdentifier, - issuer = ?Name, - validity = ?Validity, - subject = ?Name, - subjectPublicKeyInfo = ?SubjectPublicKeyInfo, - issuerUniqueID = ?UniqueIdentifier, - subjectUniqueID = ?UniqueIdentifier, + #'TBSCertificate'{version = ?Version, + serialNumber = ?CertificateSerialNumber, + signature = ?AlgorithmIdentifier, + issuer = ?Name, + validity = ?Validity, + subject = ?Name, + subjectPublicKeyInfo = ?SubjectPublicKeyInfo, + issuerUniqueID = ?UniqueIdentifier, + subjectUniqueID = ?UniqueIdentifier, extensions = ?Extensions}). --define(Certificate, #'Certificate'{tbsCertificate = ?TBSCertificate, - signatureAlgorithm = ?AlgorithmIdentifier, +-define(Certificate, #'Certificate'{tbsCertificate = ?TBSCertificate, + signatureAlgorithm = ?AlgorithmIdentifier, signature = ?BIT_STR}). %% PKIX1Implicit88 @@ -206,66 +206,66 @@ -define(GeneralNames, [?GeneralName]). -%% PKIXAttributeCertificate --define(AttCertValidityPeriod, - #'AttCertValidityPeriod'{notBeforeTime = "19820102070533.8", +%% PKIXAttributeCertificate +-define(AttCertValidityPeriod, + #'AttCertValidityPeriod'{notBeforeTime = "19820102070533.8", notAfterTime = "19820102070533.8"}). --define(Attribute, #'Attribute'{type = ?OID, +-define(Attribute, #'Attribute'{type = ?OID, values = []}). -define(Attributes, [?Attribute]). --define(IssuerSerial, #'IssuerSerial'{issuer = ?GeneralNames, - serial = ?CertificateSerialNumber, +-define(IssuerSerial, #'IssuerSerial'{issuer = ?GeneralNames, + serial = ?CertificateSerialNumber, issuerUID = ?UniqueIdentifier}). -define(DigestedObjectType, publicKey). %% Enum --define(ObjectDigestInfo, - #'ObjectDigestInfo'{digestedObjectType = ?DigestedObjectType, - otherObjectTypeID = ?OID, - digestAlgorithm = ?AlgorithmIdentifier, +-define(ObjectDigestInfo, + #'ObjectDigestInfo'{digestedObjectType = ?DigestedObjectType, + otherObjectTypeID = ?OID, + digestAlgorithm = ?AlgorithmIdentifier, objectDigest = ?BIT_STR}). --define(V2Form, #'V2Form'{issuerName = ?GeneralNames, - baseCertificateID = ?IssuerSerial, +-define(V2Form, #'V2Form'{issuerName = ?GeneralNames, + baseCertificateID = ?IssuerSerial, objectDigestInfo = ?ObjectDigestInfo}). -define(AttCertVersion, v2). --define(Holder, #'Holder'{baseCertificateID = ?IssuerSerial, - entityName = ?GeneralNames, +-define(Holder, #'Holder'{baseCertificateID = ?IssuerSerial, + entityName = ?GeneralNames, objectDigestInfo = ?ObjectDigestInfo}). -define(AttCertIssuer, {v2Form, ?V2Form}). -define(AttributeCertificateInfo, - #'AttributeCertificateInfo'{version = ?AttCertVersion, - holder = ?Holder, - issuer = ?AttCertIssuer, - signature = ?AlgorithmIdentifier, - serialNumber = ?CertificateSerialNumber, + #'AttributeCertificateInfo'{version = ?AttCertVersion, + holder = ?Holder, + issuer = ?AttCertIssuer, + signature = ?AlgorithmIdentifier, + serialNumber = ?CertificateSerialNumber, attrCertValidityPeriod = ?AttCertValidityPeriod, - attributes = ?Attributes, - issuerUniqueID = ?UniqueIdentifier, + attributes = ?Attributes, + issuerUniqueID = ?UniqueIdentifier, extensions = ?Extensions}). --define(AttributeCertificate, - #'AttributeCertificate'{acinfo = ?AttributeCertificateInfo, - signatureAlgorithm = ?AlgorithmIdentifier, +-define(AttributeCertificate, + #'AttributeCertificate'{acinfo = ?AttributeCertificateInfo, + signatureAlgorithm = ?AlgorithmIdentifier, signatureValue = ?BIT_STR}). %% OrberCSIv2 --define(AttributeCertChain, - #'AttributeCertChain'{attributeCert = ?AttributeCertificate, +-define(AttributeCertChain, + #'AttributeCertChain'{attributeCert = ?AttributeCertificate, certificateChain = ?CertificateChain}). -define(CertificateChain, [?Certificate]). --define(VerifyingCertChain, [?Certificate]). +-define(VerifyingCertChain, [?Certificate]). -endif. @@ -314,15 +314,15 @@ %%----------------------------------------------------------------- %% Func: all/1 -%% Args: -%% Returns: +%% Args: +%% Returns: %%----------------------------------------------------------------- suite() -> [{ct_hooks,[ts_install_cth]}]. -all() -> +all() -> cases(). -groups() -> +groups() -> []. init_per_group(_GroupName, Config) -> @@ -335,7 +335,7 @@ end_per_group(_GroupName, Config) -> %% NOTE - the fragment test cases must bu first since we explicitly set a request %% id. Otherwise, the request-id counter would be increased and we cannot know %% what it is. -cases() -> +cases() -> [ssl_server_peercert_api, ssl_client_peercert_api]. %%----------------------------------------------------------------- @@ -361,14 +361,20 @@ end_per_testcase(_Case, Config) -> ok. init_per_suite(Config) -> - case orber_test_lib:ssl_version() of - no_ssl -> - {skip,"SSL is not installed!"}; - _ -> - Config + try crypto:start() of + ok -> + case orber_test_lib:ssl_version() of + no_ssl -> + {skip, "SSL is not installed!"}; + _ -> + Config + end + catch _:_ -> + {skip, "Crypto did not start"} end. end_per_suite(Config) -> + application:stop(crypto), Config. %%----------------------------------------------------------------- @@ -385,272 +391,272 @@ end_per_suite(Config) -> code_CertificateChain_api(doc) -> ["Code CertificateChain"]; code_CertificateChain_api(suite) -> []; code_CertificateChain_api(_Config) -> - {ok, Enc} = - ?match({ok, _}, + {ok, Enc} = + ?match({ok, _}, 'OrberCSIv2':encode('CertificateChain', ?CertificateChain)), - ?match({ok, [#'Certificate'{}]}, + ?match({ok, [#'Certificate'{}]}, 'OrberCSIv2':decode('CertificateChain', list_to_binary(Enc))), ok. code_AttributeCertChain_api(doc) -> ["Code AttributeCertChain"]; code_AttributeCertChain_api(suite) -> []; code_AttributeCertChain_api(_Config) -> - {ok, Enc} = - ?match({ok, _}, + {ok, Enc} = + ?match({ok, _}, 'OrberCSIv2':encode('AttributeCertChain', ?AttributeCertChain)), - ?match({ok, #'AttributeCertChain'{}}, - 'OrberCSIv2':decode('AttributeCertChain', list_to_binary(Enc))), + ?match({ok, #'AttributeCertChain'{}}, + 'OrberCSIv2':decode('AttributeCertChain', list_to_binary(Enc))), ok. code_VerifyingCertChain_api(doc) -> ["Code VerifyingCertChain"]; code_VerifyingCertChain_api(suite) -> []; code_VerifyingCertChain_api(_Config) -> - {ok, Enc} = - ?match({ok, _}, + {ok, Enc} = + ?match({ok, _}, 'OrberCSIv2':encode('VerifyingCertChain', ?VerifyingCertChain)), - ?match({ok, [#'Certificate'{}]}, - 'OrberCSIv2':decode('VerifyingCertChain', list_to_binary(Enc))), + ?match({ok, [#'Certificate'{}]}, + 'OrberCSIv2':decode('VerifyingCertChain', list_to_binary(Enc))), ok. %% PKIXAttributeCertificate code_AttributeCertificate_api(doc) -> ["Code AttributeCertificate"]; code_AttributeCertificate_api(suite) -> []; code_AttributeCertificate_api(_Config) -> - {ok, Enc} = - ?match({ok, _}, + {ok, Enc} = + ?match({ok, _}, 'OrberCSIv2':encode('AttributeCertificate', ?AttributeCertificate)), - ?match({ok, #'AttributeCertificate'{}}, - 'OrberCSIv2':decode('AttributeCertificate', list_to_binary(Enc))), + ?match({ok, #'AttributeCertificate'{}}, + 'OrberCSIv2':decode('AttributeCertificate', list_to_binary(Enc))), ok. code_AttributeCertificateInfo_api(doc) -> ["Code AttributeCertificateInfo"]; code_AttributeCertificateInfo_api(suite) -> []; code_AttributeCertificateInfo_api(_Config) -> - {ok, Enc} = - ?match({ok, _}, + {ok, Enc} = + ?match({ok, _}, 'OrberCSIv2':encode('AttributeCertificateInfo', ?AttributeCertificateInfo)), - ?match({ok, #'AttributeCertificateInfo'{}}, - 'OrberCSIv2':decode('AttributeCertificateInfo', list_to_binary(Enc))), + ?match({ok, #'AttributeCertificateInfo'{}}, + 'OrberCSIv2':decode('AttributeCertificateInfo', list_to_binary(Enc))), ok. code_AttCertVersion_api(doc) -> ["Code AttCertVersion"]; code_AttCertVersion_api(suite) -> []; code_AttCertVersion_api(_Config) -> - {ok, Enc} = - ?match({ok, _}, + {ok, Enc} = + ?match({ok, _}, 'OrberCSIv2':encode('AttCertVersion', ?AttCertVersion)), - ?match({ok, ?AttCertVersion}, - 'OrberCSIv2':decode('AttCertVersion', list_to_binary(Enc))), + ?match({ok, ?AttCertVersion}, + 'OrberCSIv2':decode('AttCertVersion', list_to_binary(Enc))), ok. code_Holder_api(doc) -> ["Code Holder"]; code_Holder_api(suite) -> []; code_Holder_api(_Config) -> - {ok, Enc} = - ?match({ok, _}, + {ok, Enc} = + ?match({ok, _}, 'OrberCSIv2':encode('Holder', ?Holder)), - ?match({ok, #'Holder'{}}, - 'OrberCSIv2':decode('Holder', list_to_binary(Enc))), + ?match({ok, #'Holder'{}}, + 'OrberCSIv2':decode('Holder', list_to_binary(Enc))), ok. code_AttCertIssuer_api(doc) -> ["Code AttCertIssuer"]; code_AttCertIssuer_api(suite) -> []; code_AttCertIssuer_api(_Config) -> - {ok, Enc} = - ?match({ok, _}, + {ok, Enc} = + ?match({ok, _}, 'OrberCSIv2':encode('AttCertIssuer', ?AttCertIssuer)), - ?match({ok, {v2Form, _}}, - 'OrberCSIv2':decode('AttCertIssuer', list_to_binary(Enc))), + ?match({ok, {v2Form, _}}, + 'OrberCSIv2':decode('AttCertIssuer', list_to_binary(Enc))), ok. code_AttCertValidityPeriod_api(doc) -> ["Code AttCertValidityPeriod"]; code_AttCertValidityPeriod_api(suite) -> []; code_AttCertValidityPeriod_api(_Config) -> - {ok, Enc} = + {ok, Enc} = ?match({ok, _}, 'OrberCSIv2':encode('AttCertValidityPeriod', ?AttCertValidityPeriod)), - ?match({ok, #'AttCertValidityPeriod'{}}, - 'OrberCSIv2':decode('AttCertValidityPeriod', list_to_binary(Enc))), + ?match({ok, #'AttCertValidityPeriod'{}}, + 'OrberCSIv2':decode('AttCertValidityPeriod', list_to_binary(Enc))), ok. code_V2Form_api(doc) -> ["Code V2Form"]; code_V2Form_api(suite) -> []; code_V2Form_api(_Config) -> - {ok, Enc} = - ?match({ok, _}, + {ok, Enc} = + ?match({ok, _}, 'OrberCSIv2':encode('V2Form', ?V2Form)), - ?match({ok, #'V2Form'{}}, - 'OrberCSIv2':decode('V2Form', list_to_binary(Enc))), + ?match({ok, #'V2Form'{}}, + 'OrberCSIv2':decode('V2Form', list_to_binary(Enc))), ok. code_IssuerSerial_api(doc) -> ["Code IssuerSerial"]; code_IssuerSerial_api(suite) -> []; code_IssuerSerial_api(_Config) -> - {ok, Enc} = - ?match({ok, _}, + {ok, Enc} = + ?match({ok, _}, 'OrberCSIv2':encode('IssuerSerial', ?IssuerSerial)), - ?match({ok, #'IssuerSerial'{}}, - 'OrberCSIv2':decode('IssuerSerial', list_to_binary(Enc))), + ?match({ok, #'IssuerSerial'{}}, + 'OrberCSIv2':decode('IssuerSerial', list_to_binary(Enc))), ok. code_ObjectDigestInfo_api(doc) -> ["Code ObjectDigestInfo"]; code_ObjectDigestInfo_api(suite) -> []; code_ObjectDigestInfo_api(_Config) -> - {ok, Enc} = - ?match({ok, _}, + {ok, Enc} = + ?match({ok, _}, 'OrberCSIv2':encode('ObjectDigestInfo', ?ObjectDigestInfo)), - ?match({ok, #'ObjectDigestInfo'{}}, - 'OrberCSIv2':decode('ObjectDigestInfo', list_to_binary(Enc))), + ?match({ok, #'ObjectDigestInfo'{}}, + 'OrberCSIv2':decode('ObjectDigestInfo', list_to_binary(Enc))), ok. %% PKIX1Explicit88 code_Certificate_api(doc) -> ["Code Certificate"]; code_Certificate_api(suite) -> []; code_Certificate_api(_Config) -> - {ok, Enc} = - ?match({ok, _}, + {ok, Enc} = + ?match({ok, _}, 'OrberCSIv2':encode('Certificate', ?Certificate)), - ?match({ok, #'Certificate'{}}, - 'OrberCSIv2':decode('Certificate', list_to_binary(Enc))), + ?match({ok, #'Certificate'{}}, + 'OrberCSIv2':decode('Certificate', list_to_binary(Enc))), ok. code_TBSCertificate_api(doc) -> ["Code TBSCertificate"]; code_TBSCertificate_api(suite) -> []; code_TBSCertificate_api(_Config) -> - {ok, Enc} = - ?match({ok, _}, + {ok, Enc} = + ?match({ok, _}, 'OrberCSIv2':encode('TBSCertificate', ?TBSCertificate)), - ?match({ok, #'TBSCertificate'{}}, - 'OrberCSIv2':decode('TBSCertificate', list_to_binary(Enc))), + ?match({ok, #'TBSCertificate'{}}, + 'OrberCSIv2':decode('TBSCertificate', list_to_binary(Enc))), ok. code_CertificateSerialNumber_api(doc) -> ["Code CertificateSerialNumber"]; code_CertificateSerialNumber_api(suite) -> []; code_CertificateSerialNumber_api(_Config) -> - {ok, Enc} = - ?match({ok, _}, + {ok, Enc} = + ?match({ok, _}, 'OrberCSIv2':encode('CertificateSerialNumber', ?CertificateSerialNumber)), - ?match({ok, ?CertificateSerialNumber}, - 'OrberCSIv2':decode('CertificateSerialNumber', list_to_binary(Enc))), + ?match({ok, ?CertificateSerialNumber}, + 'OrberCSIv2':decode('CertificateSerialNumber', list_to_binary(Enc))), ok. code_Version_api(doc) -> ["Code Version"]; code_Version_api(suite) -> []; code_Version_api(_Config) -> - {ok, Enc} = + {ok, Enc} = ?match({ok, _}, 'OrberCSIv2':encode('Version', ?Version)), - ?match({ok, ?Version}, 'OrberCSIv2':decode('Version', list_to_binary(Enc))), + ?match({ok, ?Version}, 'OrberCSIv2':decode('Version', list_to_binary(Enc))), ok. code_AlgorithmIdentifier_api(doc) -> ["Code AlgorithmIdentifier"]; code_AlgorithmIdentifier_api(suite) -> []; code_AlgorithmIdentifier_api(_Config) -> - {ok, Enc} = + {ok, Enc} = ?match({ok, _}, 'OrberCSIv2':encode('AlgorithmIdentifier', ?AlgorithmIdentifier)), - ?match({ok, #'AlgorithmIdentifier'{}}, - 'OrberCSIv2':decode('AlgorithmIdentifier', list_to_binary(Enc))), + ?match({ok, #'AlgorithmIdentifier'{}}, + 'OrberCSIv2':decode('AlgorithmIdentifier', list_to_binary(Enc))), ok. code_Name_api(doc) -> ["Code Name"]; code_Name_api(suite) -> []; code_Name_api(_Config) -> - {ok, Enc} = + {ok, Enc} = ?match({ok, _}, 'OrberCSIv2':encode('Name', ?Name)), - ?match({ok, {rdnSequence,_}}, - 'OrberCSIv2':decode('Name', list_to_binary(Enc))), + ?match({ok, {rdnSequence,_}}, + 'OrberCSIv2':decode('Name', list_to_binary(Enc))), ok. code_RDNSequence_api(doc) -> ["Code RDNSequence"]; code_RDNSequence_api(suite) -> []; code_RDNSequence_api(_Config) -> - {ok, Enc} = + {ok, Enc} = ?match({ok, _}, 'OrberCSIv2':encode('RDNSequence', ?RDNSequence)), - ?match({ok, [[#'AttributeTypeAndValue'{}]]}, - 'OrberCSIv2':decode('RDNSequence', list_to_binary(Enc))), + ?match({ok, [[#'AttributeTypeAndValue'{}]]}, + 'OrberCSIv2':decode('RDNSequence', list_to_binary(Enc))), ok. code_RelativeDistinguishedName_api(doc) -> ["Code RelativeDistinguishedName"]; code_RelativeDistinguishedName_api(suite) -> []; code_RelativeDistinguishedName_api(_Config) -> - {ok, Enc} = + {ok, Enc} = ?match({ok, _}, 'OrberCSIv2':encode('RelativeDistinguishedName', ?RelativeDistinguishedName)), - ?match({ok, [#'AttributeTypeAndValue'{}]}, - 'OrberCSIv2':decode('RelativeDistinguishedName', list_to_binary(Enc))), + ?match({ok, [#'AttributeTypeAndValue'{}]}, + 'OrberCSIv2':decode('RelativeDistinguishedName', list_to_binary(Enc))), ok. code_AttributeTypeAndValue_api(doc) -> ["Code AttributeTypeAndValue"]; code_AttributeTypeAndValue_api(suite) -> []; code_AttributeTypeAndValue_api(_Config) -> - {ok, Enc} = + {ok, Enc} = ?match({ok, _}, 'OrberCSIv2':encode('AttributeTypeAndValue', ?AttributeTypeAndValue)), - ?match({ok, #'AttributeTypeAndValue'{}}, - 'OrberCSIv2':decode('AttributeTypeAndValue', list_to_binary(Enc))), + ?match({ok, #'AttributeTypeAndValue'{}}, + 'OrberCSIv2':decode('AttributeTypeAndValue', list_to_binary(Enc))), ok. code_Attribute_api(doc) -> ["Code Attribute"]; code_Attribute_api(suite) -> []; code_Attribute_api(_Config) -> - {ok, Enc} = + {ok, Enc} = ?match({ok, _}, 'OrberCSIv2':encode('Attribute', ?Attribute)), - ?match({ok, #'Attribute'{}}, - 'OrberCSIv2':decode('Attribute', list_to_binary(Enc))), + ?match({ok, #'Attribute'{}}, + 'OrberCSIv2':decode('Attribute', list_to_binary(Enc))), ok. code_Validity_api(doc) -> ["Code Validity"]; code_Validity_api(suite) -> []; code_Validity_api(_Config) -> - {ok, Enc} = + {ok, Enc} = ?match({ok, _}, 'OrberCSIv2':encode('Validity', ?Validity)), - ?match({ok, #'Validity'{}}, - 'OrberCSIv2':decode('Validity', list_to_binary(Enc))), + ?match({ok, #'Validity'{}}, + 'OrberCSIv2':decode('Validity', list_to_binary(Enc))), ok. code_SubjectPublicKeyInfo_api(doc) -> ["Code SubjectPublicKeyInfo"]; code_SubjectPublicKeyInfo_api(suite) -> []; code_SubjectPublicKeyInfo_api(_Config) -> - {ok, Enc} = + {ok, Enc} = ?match({ok, _}, 'OrberCSIv2':encode('SubjectPublicKeyInfo', ?SubjectPublicKeyInfo)), - ?match({ok, #'SubjectPublicKeyInfo'{}}, - 'OrberCSIv2':decode('SubjectPublicKeyInfo', list_to_binary(Enc))), + ?match({ok, #'SubjectPublicKeyInfo'{}}, + 'OrberCSIv2':decode('SubjectPublicKeyInfo', list_to_binary(Enc))), ok. code_UniqueIdentifier_api(doc) -> ["Code UniqueIdentifier"]; code_UniqueIdentifier_api(suite) -> []; code_UniqueIdentifier_api(_Config) -> - {ok, Enc} = + {ok, Enc} = ?match({ok, _}, 'OrberCSIv2':encode('UniqueIdentifier', ?UniqueIdentifier)), - ?match({ok, _}, 'OrberCSIv2':decode('UniqueIdentifier', list_to_binary(Enc))), + ?match({ok, _}, 'OrberCSIv2':decode('UniqueIdentifier', list_to_binary(Enc))), ok. code_Extensions_api(doc) -> ["Code Extensions"]; code_Extensions_api(suite) -> []; code_Extensions_api(_Config) -> - {ok, Enc} = + {ok, Enc} = ?match({ok, _}, 'OrberCSIv2':encode('Extensions', ?Extensions)), - ?match({ok, [#'Extension'{}]}, - 'OrberCSIv2':decode('Extensions', list_to_binary(Enc))), + ?match({ok, [#'Extension'{}]}, + 'OrberCSIv2':decode('Extensions', list_to_binary(Enc))), ok. code_Extension_api(doc) -> ["Code Extension"]; code_Extension_api(suite) -> []; code_Extension_api(_Config) -> - {ok, Enc} = + {ok, Enc} = ?match({ok, _}, 'OrberCSIv2':encode('Extension', ?Extension)), - ?match({ok, #'Extension'{}}, - 'OrberCSIv2':decode('Extension', list_to_binary(Enc))), + ?match({ok, #'Extension'{}}, + 'OrberCSIv2':decode('Extension', list_to_binary(Enc))), ok. %% OpenSSL generated x509 Certificate code_OpenSSL509_api(doc) -> ["Code OpenSSL generated x509 Certificate"]; code_OpenSSL509_api(suite) -> []; code_OpenSSL509_api(_Config) -> - {ok, Cert} = - ?match({ok, #'Certificate'{}}, + {ok, Cert} = + ?match({ok, #'Certificate'{}}, 'OrberCSIv2':decode('Certificate', ?X509DER)), - AttrCertChain = #'AttributeCertChain'{attributeCert = ?AttributeCertificate, + AttrCertChain = #'AttributeCertChain'{attributeCert = ?AttributeCertificate, certificateChain = [Cert]}, - {ok, EAttrCertChain} = + {ok, EAttrCertChain} = ?match({ok, _}, 'OrberCSIv2':encode('AttributeCertChain', AttrCertChain)), - ?match({ok, #'AttributeCertChain'{}}, + ?match({ok, #'AttributeCertChain'{}}, 'OrberCSIv2':decode('AttributeCertChain', list_to_binary(EAttrCertChain))), ok. @@ -663,66 +669,65 @@ ssl_server_peercert_api(doc) -> ["Test ssl:peercert (server side)"]; ssl_server_peercert_api(suite) -> []; ssl_server_peercert_api(_Config) -> case os:type() of - vxworks -> - {skipped, "No SSL-support for VxWorks."}; - _ -> - Options = orber_test_lib:get_options(iiop_ssl, server, - 2, [{iiop_ssl_port, 0}]), - {ok, ServerNode, ServerHost} = - ?match({ok,_,_}, orber_test_lib:js_node(Options)), - ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_ssl_port, []), - SSLOptions = orber_test_lib:get_options(ssl, client), - {ok, Socket} = - ?match({ok, _}, fake_client_ORB(ssl, ServerHost, ServerPort, SSLOptions)), - {ok, _PeerCert} = ?match({ok, _}, orber_socket:peercert(ssl, Socket)), -%% ?match({ok, {rdnSequence, _}}, orber_socket:peercert(ssl, Socket, [pkix, subject])), -%% ?match({ok, {rdnSequence, _}}, orber_socket:peercert(ssl, Socket, [ssl, subject])), -% ?match({ok, #'Certificate'{}}, -% 'OrberCSIv2':decode('Certificate', PeerCert)), - destroy_fake_ORB(ssl, Socket), - ok + vxworks -> + {skipped, "No SSL-support for VxWorks."}; + _ -> + Options = orber_test_lib:get_options(iiop_ssl, server, + 2, [{iiop_ssl_port, 0}]), + {ok, ServerNode, ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node(Options)), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_ssl_port, []), + SSLOptions = orber_test_lib:get_options(ssl, client), + {ok, Socket} = + ?match({ok, _}, fake_client_ORB(ssl, ServerHost, ServerPort, SSLOptions)), + {ok, _PeerCert} = ?match({ok, _}, orber_socket:peercert(ssl, Socket)), + %% ?match({ok, {rdnSequence, _}}, orber_socket:peercert(ssl, Socket, [pkix, subject])), + %% ?match({ok, {rdnSequence, _}}, orber_socket:peercert(ssl, Socket, [ssl, subject])), + % ?match({ok, #'Certificate'{}}, + % 'OrberCSIv2':decode('Certificate', PeerCert)), + destroy_fake_ORB(ssl, Socket), + ok end. ssl_client_peercert_api(doc) -> ["Test ssl:peercert (client side)"]; ssl_client_peercert_api(suite) -> []; ssl_client_peercert_api(_Config) -> case os:type() of - vxworks -> - {skipped, "No SSL-support for VxWorks."}; - _ -> - Options = orber_test_lib:get_options(iiop_ssl, client, - 2, [{iiop_ssl_port, 0}]), - {ok, ClientNode, _ClientHost} = - ?match({ok,_,_}, orber_test_lib:js_node(Options)), - crypto:start(), - ssl:start(), - ssl:seed("testing"), - SSLOptions = orber_test_lib:get_options(ssl, server), - {ok, LSock} = ?match({ok, _}, ssl:listen(0, SSLOptions)), - {ok, {_Address, LPort}} = ?match({ok, {_, _}}, ssl:sockname(LSock)), - IOR = ?match({'IOP_IOR',_,_}, - iop_ior:create_external({1, 2}, "IDL:FAKE:1.0", - "localhost", 6004, "FAKE", - [#'IOP_TaggedComponent' - {tag=?TAG_SSL_SEC_TRANS, - component_data=#'SSLIOP_SSL' - {target_supports = 2, - target_requires = 2, - port = LPort}}])), - spawn(orber_test_lib, remote_apply, - [ClientNode, corba_object, non_existent, [IOR]]), - {ok, Socket} = ?match({ok, _}, ssl:transport_accept(LSock)), - ?match(ok, ssl:ssl_accept(Socket)), - - {ok, _PeerCert} = ?match({ok, _}, orber_socket:peercert(ssl, Socket)), -%% ?match({ok, {rdnSequence, _}}, orber_socket:peercert(ssl, Socket, [pkix, subject])), -%% ?match({ok, {rdnSequence, _}}, orber_socket:peercert(ssl, Socket, [ssl, subject])), -% ?match({ok, #'Certificate'{}}, -% 'OrberCSIv2':decode('Certificate', PeerCert)), - ssl:close(Socket), - ssl:close(LSock), - ssl:stop(), - ok + vxworks -> + {skipped, "No SSL-support for VxWorks."}; + _ -> + Options = orber_test_lib:get_options(iiop_ssl, client, + 2, [{iiop_ssl_port, 0}]), + {ok, ClientNode, _ClientHost} = + ?match({ok,_,_}, orber_test_lib:js_node(Options)), + crypto:start(), + ssl:start(), + SSLOptions = orber_test_lib:get_options(ssl, server), + {ok, LSock} = ?match({ok, _}, ssl:listen(0, SSLOptions)), + {ok, {_Address, LPort}} = ?match({ok, {_, _}}, ssl:sockname(LSock)), + IOR = ?match({'IOP_IOR',_,_}, + iop_ior:create_external({1, 2}, "IDL:FAKE:1.0", + "localhost", 6004, "FAKE", + [#'IOP_TaggedComponent' + {tag=?TAG_SSL_SEC_TRANS, + component_data=#'SSLIOP_SSL' + {target_supports = 2, + target_requires = 2, + port = LPort}}])), + spawn(orber_test_lib, remote_apply, + [ClientNode, corba_object, non_existent, [IOR]]), + {ok, Socket} = ?match({ok, _}, ssl:transport_accept(LSock)), + ?match(ok, ssl:ssl_accept(Socket)), + + {ok, _PeerCert} = ?match({ok, _}, orber_socket:peercert(ssl, Socket)), + %% ?match({ok, {rdnSequence, _}}, orber_socket:peercert(ssl, Socket, [pkix, subject])), + %% ?match({ok, {rdnSequence, _}}, orber_socket:peercert(ssl, Socket, [ssl, subject])), + % ?match({ok, #'Certificate'{}}, + % 'OrberCSIv2':decode('Certificate', PeerCert)), + ssl:close(Socket), + ssl:close(LSock), + ssl:stop(), + ok end. %%----------------------------------------------------------------- @@ -731,105 +736,105 @@ ssl_client_peercert_api(_Config) -> -ifdef(false). %% Not used yet. context_test(Obj) -> - IDToken1 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTAbsent, + IDToken1 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTAbsent, value = true}, - IDToken2 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTAnonymous, + IDToken2 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTAnonymous, value = false}, - IDToken3 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTPrincipalName, + IDToken3 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTPrincipalName, value = [0,255]}, - IDToken4 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTX509CertChain, + IDToken4 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTX509CertChain, value = [1,255]}, - IDToken5 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTDistinguishedName, + IDToken5 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTDistinguishedName, value = [2,255]}, - IDToken6 = #'CSI_IdentityToken'{label = ?ULONGMAX, + IDToken6 = #'CSI_IdentityToken'{label = ?ULONGMAX, value = [3,255]}, MTEstablishContext1 = #'CSI_SASContextBody' - {label = ?CSI_MsgType_MTEstablishContext, - value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, - authorization_token = + {label = ?CSI_MsgType_MTEstablishContext, + value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, + authorization_token = [#'CSI_AuthorizationElement' - {the_type = ?ULONGMAX, - the_element = [0,255]}], - identity_token = IDToken1, + {the_type = ?ULONGMAX, + the_element = [0,255]}], + identity_token = IDToken1, client_authentication_token = [1, 255]}}, MTEstablishContext2 = #'CSI_SASContextBody' - {label = ?CSI_MsgType_MTEstablishContext, - value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, - authorization_token = + {label = ?CSI_MsgType_MTEstablishContext, + value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, + authorization_token = [#'CSI_AuthorizationElement' - {the_type = ?ULONGMAX, - the_element = [0,255]}], - identity_token = IDToken2, + {the_type = ?ULONGMAX, + the_element = [0,255]}], + identity_token = IDToken2, client_authentication_token = [1, 255]}}, MTEstablishContext3 = #'CSI_SASContextBody' - {label = ?CSI_MsgType_MTEstablishContext, - value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, - authorization_token = + {label = ?CSI_MsgType_MTEstablishContext, + value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, + authorization_token = [#'CSI_AuthorizationElement' - {the_type = ?ULONGMAX, - the_element = [0,255]}], - identity_token = IDToken3, + {the_type = ?ULONGMAX, + the_element = [0,255]}], + identity_token = IDToken3, client_authentication_token = [1, 255]}}, MTEstablishContext4 = #'CSI_SASContextBody' - {label = ?CSI_MsgType_MTEstablishContext, - value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, - authorization_token = + {label = ?CSI_MsgType_MTEstablishContext, + value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, + authorization_token = [#'CSI_AuthorizationElement' - {the_type = ?ULONGMAX, - the_element = [0,255]}], - identity_token = IDToken4, + {the_type = ?ULONGMAX, + the_element = [0,255]}], + identity_token = IDToken4, client_authentication_token = [1, 255]}}, MTEstablishContext5 = #'CSI_SASContextBody' - {label = ?CSI_MsgType_MTEstablishContext, - value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, - authorization_token = + {label = ?CSI_MsgType_MTEstablishContext, + value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, + authorization_token = [#'CSI_AuthorizationElement' - {the_type = ?ULONGMAX, - the_element = [0,255]}], - identity_token = IDToken5, + {the_type = ?ULONGMAX, + the_element = [0,255]}], + identity_token = IDToken5, client_authentication_token = [1, 255]}}, MTEstablishContext6 = #'CSI_SASContextBody' - {label = ?CSI_MsgType_MTEstablishContext, - value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, - authorization_token = + {label = ?CSI_MsgType_MTEstablishContext, + value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, + authorization_token = [#'CSI_AuthorizationElement' - {the_type = ?ULONGMAX, - the_element = [0,255]}], - identity_token = IDToken6, + {the_type = ?ULONGMAX, + the_element = [0,255]}], + identity_token = IDToken6, client_authentication_token = [1, 255]}}, MTCompleteEstablishContext = #'CSI_SASContextBody' - {label = ?CSI_MsgType_MTCompleteEstablishContext, - value = #'CSI_CompleteEstablishContext'{client_context_id = ?ULONGLONGMAX, + {label = ?CSI_MsgType_MTCompleteEstablishContext, + value = #'CSI_CompleteEstablishContext'{client_context_id = ?ULONGLONGMAX, context_stateful = false, final_context_token = [1, 255]}}, MTContextError = #'CSI_SASContextBody' - {label = ?CSI_MsgType_MTContextError, + {label = ?CSI_MsgType_MTContextError, value = #'CSI_ContextError'{client_context_id = ?ULONGLONGMAX, - major_status = 1, - minor_status = 2, + major_status = 1, + minor_status = 2, error_token = [2,255]}}, MTMessageInContext = #'CSI_SASContextBody' - {label = ?CSI_MsgType_MTMessageInContext, - value = #'CSI_MessageInContext'{client_context_id = ?ULONGLONGMAX, + {label = ?CSI_MsgType_MTMessageInContext, + value = #'CSI_MessageInContext'{client_context_id = ?ULONGLONGMAX, discard_context = true}}, - Ctx = [#'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + Ctx = [#'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, context_data = MTEstablishContext1}, - #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, context_data = MTEstablishContext2}, - #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, context_data = MTEstablishContext3}, - #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, context_data = MTEstablishContext4}, - #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, context_data = MTEstablishContext5}, - #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, context_data = MTEstablishContext6}, - #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, context_data = MTCompleteEstablishContext}, - #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, context_data = MTContextError}, - #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, context_data = MTMessageInContext}], ?line ?match(ok, orber_test_server:testing_iiop_context(Obj, [{context, Ctx}])). @@ -837,7 +842,7 @@ context_test(Obj) -> fake_server_ORB(Type, Port, Options) -> start_ssl(Type), {ok, ListenSocket, NewPort} = - orber_socket:listen(Type, Port, + orber_socket:listen(Type, Port, [{active, false}|Options]), Socket = orber_socket:accept(Type, ListenSocket), orber_socket:post_accept(Type, Socket), @@ -847,7 +852,7 @@ fake_server_ORB(Type, Port, Options) -> fake_server_ORB(Type, Port, Options, Action, Data) -> start_ssl(Type), - {ok, ListenSocket, _NewPort} = + {ok, ListenSocket, _NewPort} = orber_socket:listen(Type, Port, [{active, false}|Options]), Socket = orber_socket:accept(Type, ListenSocket), orber_socket:post_accept(Type, Socket), @@ -857,8 +862,7 @@ fake_server_ORB(Type, Port, Options, Action, Data) -> start_ssl(ssl) -> crypto:start(), - ssl:start(), - ssl:seed("testing"); + ssl:start(); start_ssl(_) -> ok. @@ -887,13 +891,13 @@ fake_client_ORB(Type, Host, Port, Options, Action, Data) -> do_client_action(Type, Socket, fragments, FragList) -> ok = send_data(Type, Socket, FragList), {ok, Bytes} = gen_tcp:recv(Socket, 0), - {#reply_header{request_id = ?REQUEST_ID, reply_status = no_exception}, ok, [Par]} = + {#reply_header{request_id = ?REQUEST_ID, reply_status = no_exception}, ok, [Par]} = cdr_decode:dec_message({tk_void,[tk_any],[tk_any]}, Bytes), Par; do_client_action(Type, Socket, fragments_max, FragList) -> ok = send_data(Type, Socket, FragList), {ok, Bytes} = gen_tcp:recv(Socket, 0), - {#reply_header{request_id = ?REQUEST_ID, reply_status = system_exception}, Exc, []} = + {#reply_header{request_id = ?REQUEST_ID, reply_status = system_exception}, Exc, []} = cdr_decode:dec_message({tk_void,[tk_any],[tk_any]}, Bytes), Exc; do_client_action(Type, Socket, message_error, Data) -> @@ -918,4 +922,4 @@ send_data(_Type, _Socket, []) -> send_data(Type, Socket, [H|T]) -> orber_socket:write(Type, Socket, H), send_data(Type, Socket, T). - + diff --git a/lib/orber/test/multi_ORB_SUITE.erl b/lib/orber/test/multi_ORB_SUITE.erl index 608fb23f3e..3c1ffd59d3 100644 --- a/lib/orber/test/multi_ORB_SUITE.erl +++ b/lib/orber/test/multi_ORB_SUITE.erl @@ -50,30 +50,33 @@ %%----------------------------------------------------------------- %% External exports %%----------------------------------------------------------------- --export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2, cases/0, +-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2, cases/0, init_per_suite/1, end_per_suite/1, basic_PI_api/1, multi_orber_api/1, - init_per_testcase/2, end_per_testcase/2, multi_pseudo_orber_api/1, - light_orber_api/1, light_orber2_api/1, + init_per_testcase/2, end_per_testcase/2, multi_pseudo_orber_api/1, + light_orber_api/1, light_orber2_api/1, ssl_1_multi_orber_api/1, ssl_2_multi_orber_api/1, ssl_reconfigure_api/1, iiop_timeout_api/1, iiop_timeout_added_api/1, setup_connection_timeout_api/1, setup_multi_connection_timeout_api/1, setup_multi_connection_timeout_random_api/1, setup_multi_connection_timeout_attempts_api/1, - fragments_server_api/1, fragments_max_server_api/1, + fragments_server_api/1, fragments_max_server_api/1, fragments_max_server_added_api/1, fragments_client_api/1, light_ifr_api/1, max_requests_api/1, max_requests_added_api/1, - max_connections_api/1, max_packet_size_exceeded_api/1, + max_connections_api/1, max_packet_size_exceeded_api/1, max_packet_size_ok_api/1, proxy_interface_api/1, proxy_interface_ipv6_api/1, multiple_accept_api/1, implicit_context_api/1, - pseudo_implicit_context_api/1, pseudo_two_implicit_context_api/1, + pseudo_implicit_context_api/1, pseudo_two_implicit_context_api/1, oneway_implicit_context_api/1, implicit_context_roundtrip_api/1, oneway_pseudo_implicit_context_api/1, flags_added_api/1, - oneway_pseudo_two_implicit_context_api/1, + oneway_pseudo_two_implicit_context_api/1, local_interface_api/1, local_interface_ctx_override_api/1, local_interface_acl_override_api/1, bad_giop_header_api/1, bad_fragment_id_client_api/1, bad_id_cancel_request_api/1, close_connections_api/1, close_connections_local_interface_api/1, - close_connections_local_interface_ctx_override_api/1, ssl_reconfigure_generation_3_api/1, + close_connections_local_interface_ctx_override_api/1, ssl_1_multi_orber_generation_3_api/1, ssl_2_multi_orber_generation_3_api/1, + ssl_reconfigure_generation_3_api/1, + ssl_1_multi_orber_generation_3_api_old/1, ssl_2_multi_orber_generation_3_api_old/1, + ssl_reconfigure_generation_3_api_old/1, close_connections_alt_iiop_addr_api/1, close_connections_multiple_profiles_api/1]). @@ -84,15 +87,15 @@ %%----------------------------------------------------------------- %% Func: all/1 -%% Args: -%% Returns: +%% Args: +%% Returns: %%----------------------------------------------------------------- suite() -> [{ct_hooks,[ts_install_cth]}]. -all() -> +all() -> cases(). -groups() -> +groups() -> []. init_per_group(_GroupName, Config) -> @@ -105,7 +108,7 @@ end_per_group(_GroupName, Config) -> %% NOTE - the fragment test cases must be first since we explicitly set a request %% id. Otherwise, the request-id counter would be increased and we cannot know %% what it is. -cases() -> +cases() -> [fragments_server_api, fragments_max_server_api, fragments_max_server_added_api, fragments_client_api, flags_added_api, bad_fragment_id_client_api, @@ -134,21 +137,28 @@ cases() -> setup_multi_connection_timeout_attempts_api, setup_multi_connection_timeout_random_api, ssl_1_multi_orber_api, + ssl_1_multi_orber_generation_3_api_old, ssl_1_multi_orber_generation_3_api, ssl_2_multi_orber_api, + ssl_2_multi_orber_generation_3_api_old, ssl_2_multi_orber_generation_3_api, - ssl_reconfigure_generation_3_api, ssl_reconfigure_api]. + ssl_reconfigure_api, + ssl_reconfigure_generation_3_api_old, + ssl_reconfigure_generation_3_api]. %%----------------------------------------------------------------- %% Init and cleanup functions. %%----------------------------------------------------------------- -init_per_testcase(TC,Config) +init_per_testcase(TC,Config) when TC =:= ssl_1_multi_orber_api; TC =:= ssl_2_multi_orber_api; TC =:= ssl_reconfigure_api -> init_ssl(Config); -init_per_testcase(TC,Config) - when TC =:= ssl_1_multi_orber_generation_3_api; +init_per_testcase(TC,Config) + when TC =:= ssl_1_multi_orber_generation_3_api_old; + TC =:= ssl_2_multi_orber_generation_3_api_old; + TC =:= ssl_reconfigure_generation_3_api_old; + TC =:= ssl_1_multi_orber_generation_3_api; TC =:= ssl_2_multi_orber_generation_3_api; TC =:= ssl_reconfigure_generation_3_api -> init_ssl_3(Config); @@ -156,21 +166,31 @@ init_per_testcase(_Case, Config) -> init_all(Config). init_ssl(Config) -> - case orber_test_lib:ssl_version() of - no_ssl -> - {skip,"SSL is not installed!"}; - _ -> - init_all(Config) + case ?config(crypto_started, Config) of + true -> + case orber_test_lib:ssl_version() of + no_ssl -> + {skip, "SSL is not installed!"}; + _ -> + init_all(Config) + end; + false -> + {skip, "Crypto did not start"} end. init_ssl_3(Config) -> - case orber_test_lib:ssl_version() of - 3 -> - init_all(Config); - 2 -> - {skip,"Could not find the correct SSL version!"}; - no_ssl -> - {skip,"SSL is not installed!"} + case ?config(crypto_started, Config) of + true -> + case orber_test_lib:ssl_version() of + 3 -> + init_all(Config); + 2 -> + {skip, "Could not find the correct SSL version!"}; + no_ssl -> + {skip, "SSL is not installed!"} + end; + false -> + {skip, "Crypto did not start"} end. init_all(Config) -> @@ -194,12 +214,18 @@ end_per_testcase(_Case, Config) -> init_per_suite(Config) -> if is_list(Config) -> - Config; + try crypto:start() of + ok -> + [{crypto_started, true} | Config] + catch _:_ -> + [{crypto_started, false} | Config] + end; true -> exit("Config not a list") end. end_per_suite(Config) -> + application:stop(crypto), Config. %%----------------------------------------------------------------- @@ -211,238 +237,238 @@ implicit_context_api(suite) -> []; implicit_context_api(_Config) -> IP = orber_test_lib:get_host(), Loopback = orber_test_lib:get_loopback_interface(), - {ok, ServerNode, _ServerHost} = + {ok, ServerNode, _ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_LOCAL_INTERFACE}, {ip_address, IP}])), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), %% Create a remote server - ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, - install_test_data, + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, [nameservice])), IOR = ?match(#'IOP_IOR'{}, corba:string_to_object("corbaname::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService#mamba")), - + Relay = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([])), - ?match(ok, + ?match(ok, orber_test_server: - relay_call(Relay, + relay_call(Relay, [{context, - [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, - context_data = {interface, + [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, + context_data = {interface, Loopback}}]}], IOR)), - + ?match([_,_], orber:iiop_connections(out)), - Conns = ?match([_,_], + Conns = ?match([_,_], orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])), ?match(true, lists:keymember(Loopback, 1, Conns)), ok. -implicit_context_roundtrip_api(doc) -> +implicit_context_roundtrip_api(doc) -> ["IIOP Implicit Contex roundtrip tests"]; implicit_context_roundtrip_api(suite) -> []; implicit_context_roundtrip_api(_Config) -> IP = orber_test_lib:get_host(), Loopback = orber_test_lib:get_loopback_interface(), - {ok, ServerNode, _ServerHost} = + {ok, ServerNode, _ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_LOCAL_INTERFACE}, {ip_address, IP}])), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), %% Create a remote server - ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, - install_test_data, + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, [nameservice])), Relay = ?match(#'IOP_IOR'{}, corba:string_to_object("corbaname::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService#mamba")), - + IOR = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([], [])), - ?match(ok, + ?match(ok, orber_test_server: - relay_call(Relay, + relay_call(Relay, [{context, - [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, - context_data = {interface, + [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, + context_data = {interface, Loopback}}]}], IOR)), ?match([_,_], orber:iiop_connections(out)), - Conns = ?match([_,_], + Conns = ?match([_,_], orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])), ?match(true, lists:keymember(Loopback, 1, Conns)), ok. - - + + oneway_implicit_context_api(doc) -> ["IIOP Implicit Contex oneway tests"]; oneway_implicit_context_api(suite) -> []; oneway_implicit_context_api(_Config) -> IP = orber_test_lib:get_host(), Loopback = orber_test_lib:get_loopback_interface(), - {ok, ServerNode, _ServerHost} = + {ok, ServerNode, _ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_LOCAL_INTERFACE}, {ip_address, IP}])), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), %% Create a remote server - ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, - install_test_data, + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, [nameservice])), IOR = ?match(#'IOP_IOR'{}, corba:string_to_object("corbaname::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService#mamba")), - + Relay = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([])), - ?match(ok, + ?match(ok, orber_test_server: - relay_cast(Relay, + relay_cast(Relay, [{context, - [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, - context_data = {interface, + [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, + context_data = {interface, Loopback}}]}], IOR)), - %% We must wait for a few seconds for the client to be able to set up the + %% We must wait for a few seconds for the client to be able to set up the %% connection (since it's a oneway operation). timer:sleep(5000), ?match([_,_], orber:iiop_connections(out)), - Conns = ?match([_,_], + Conns = ?match([_,_], orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])), ?match(true, lists:keymember(Loopback, 1, Conns)), ok. - + pseudo_implicit_context_api(doc) -> ["IIOP Implicit Contex tests (via pseudo object)"]; pseudo_implicit_context_api(suite) -> []; pseudo_implicit_context_api(_Config) -> IP = orber_test_lib:get_host(), Loopback = orber_test_lib:get_loopback_interface(), - {ok, ServerNode, _ServerHost} = + {ok, ServerNode, _ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_LOCAL_INTERFACE}, {ip_address, IP}])), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), %% Create a remote server - ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, - install_test_data, + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, [nameservice])), IOR = ?match(#'IOP_IOR'{}, corba:string_to_object("corbaname::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService#mamba")), - + Relay = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([], [{pseudo,true}])), - ?match(ok, + ?match(ok, orber_test_server: - relay_call(Relay, + relay_call(Relay, [{context, - [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, - context_data = {interface, + [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, + context_data = {interface, Loopback}}]}], IOR)), ?match([_,_], orber:iiop_connections(out)), - Conns = ?match([_,_], + Conns = ?match([_,_], orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])), ?match(true, lists:keymember(Loopback, 1, Conns)), ok. - -pseudo_two_implicit_context_api(doc) -> + +pseudo_two_implicit_context_api(doc) -> ["IIOP two Implicit Contex tests (via pseudo object)"]; pseudo_two_implicit_context_api(suite) -> []; pseudo_two_implicit_context_api(_Config) -> IP = orber_test_lib:get_host(), Loopback = orber_test_lib:get_loopback_interface(), - {ok, ServerNode, _ServerHost} = + {ok, ServerNode, _ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_LOCAL_INTERFACE}, {ip_address, IP}])), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), %% Create a remote server - ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, - install_test_data, + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, [nameservice])), IOR = ?match(#'IOP_IOR'{}, corba:string_to_object("corbaname::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService#mamba")), - + Relay = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([], [{pseudo,true}])), - put(oe_server_in_context, - [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, + put(oe_server_in_context, + [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, context_data = {interface, IP}}]), - ?match(ok, + ?match(ok, orber_test_server: - relay_call(Relay, + relay_call(Relay, [{context, - [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, - context_data = {interface, + [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, + context_data = {interface, Loopback}}]}], IOR)), ?match([_,_], orber:iiop_connections(out)), - Conns = ?match([_,_], + Conns = ?match([_,_], orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])), ?match(true, lists:keymember(Loopback, 1, Conns)), ok. - + oneway_pseudo_implicit_context_api(doc) -> ["IIOP Implicit Contex tests (via pseudo object oneway)"]; oneway_pseudo_implicit_context_api(suite) -> []; oneway_pseudo_implicit_context_api(_Config) -> IP = orber_test_lib:get_host(), Loopback = orber_test_lib:get_loopback_interface(), - {ok, ServerNode, _ServerHost} = + {ok, ServerNode, _ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_LOCAL_INTERFACE}, {ip_address, IP}])), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), %% Create a remote server - ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, - install_test_data, + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, [nameservice])), IOR = ?match(#'IOP_IOR'{}, corba:string_to_object("corbaname::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService#mamba")), - + Relay = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([], [{pseudo,true}])), - ?match(ok, + ?match(ok, orber_test_server: - relay_cast(Relay, + relay_cast(Relay, [{context, - [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, - context_data = {interface, + [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, + context_data = {interface, Loopback}}]}], IOR)), ?match([_,_], orber:iiop_connections(out)), - Conns = ?match([_,_], + Conns = ?match([_,_], orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])), ?match(true, lists:keymember(Loopback, 1, Conns)), ok. - -oneway_pseudo_two_implicit_context_api(doc) -> + +oneway_pseudo_two_implicit_context_api(doc) -> ["IIOP two Implicit Contex tests (via pseudo object oneway)"]; oneway_pseudo_two_implicit_context_api(suite) -> []; oneway_pseudo_two_implicit_context_api(_Config) -> IP = orber_test_lib:get_host(), Loopback = orber_test_lib:get_loopback_interface(), - {ok, ServerNode, _ServerHost} = + {ok, ServerNode, _ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_LOCAL_INTERFACE}, {ip_address, IP}])), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), %% Create a remote server - ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, - install_test_data, + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, [nameservice])), IOR = ?match(#'IOP_IOR'{}, corba:string_to_object("corbaname::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService#mamba")), - + Relay = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([], [{pseudo,true}])), %% Add incoming implicit context which must be removed. - put(oe_server_in_context, - [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, + put(oe_server_in_context, + [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, context_data = {interface, IP}}]), - ?match(ok, + ?match(ok, orber_test_server: - relay_cast(Relay, + relay_cast(Relay, [{context, - [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, - context_data = {interface, + [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, + context_data = {interface, Loopback}}]}], IOR)), ?match([_,_], orber:iiop_connections(out)), - Conns = ?match([_,_], + Conns = ?match([_,_], orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])), ?match(true, lists:keymember(Loopback, 1, Conns)), ok. - + multiple_accept_api(doc) -> ["IIOP Multiple Accept tests"]; @@ -450,7 +476,7 @@ multiple_accept_api(suite) -> []; multiple_accept_api(_Config) -> IP = orber_test_lib:get_host(), Loopback = orber_test_lib:get_loopback_interface(), - {ok, ServerNode, _ServerHost} = + {ok, ServerNode, _ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_LOCAL_INTERFACE}, {ip_address, IP}])), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), @@ -461,84 +487,84 @@ multiple_accept_api(_Config) -> IOR1 = ?match(#'IOP_IOR'{}, corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")), - ?match({'external', {IP, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, + ?match({'external', {IP, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, iop_ior:get_key(IOR1)), ?match([_], orber:iiop_connections(out)), {ok, Ref1} = ?match({ok, _}, - orber_test_lib:remote_apply(ServerNode, orber, - add_listen_interface, + orber_test_lib:remote_apply(ServerNode, orber, + add_listen_interface, [Loopback, normal])), IOR2 = ?match(#'IOP_IOR'{}, corba:string_to_object("corbaloc::1.2@"++Loopback++":"++integer_to_list(ServerPort)++"/NameService")), - ?match({'external', {Loopback, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, + ?match({'external', {Loopback, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, iop_ior:get_key(IOR2)), ?match([_,_], orber:iiop_connections(out)), {ok, Ref2} = ?match({ok, _}, - orber_test_lib:remote_apply(ServerNode, orber, - add_listen_interface, + orber_test_lib:remote_apply(ServerNode, orber, + add_listen_interface, [Loopback, normal, 9543])), ?match({error, eaddrinuse}, - orber_test_lib:remote_apply(ServerNode, orber, - add_listen_interface, + orber_test_lib:remote_apply(ServerNode, orber, + add_listen_interface, [Loopback, normal, 9543])), IOR3 = ?match(#'IOP_IOR'{}, corba:string_to_object("corbaloc::1.2@"++Loopback++":9543/NameService")), - ?match({'external', {Loopback, 9543, _ObjectKey, _Counter, _TP, _NewHD}}, + ?match({'external', {Loopback, 9543, _ObjectKey, _Counter, _TP, _NewHD}}, iop_ior:get_key(IOR3)), ?match([_,_,_], orber:iiop_connections(out)), - ?match(ok, - orber_test_lib:remote_apply(ServerNode, orber, + ?match(ok, + orber_test_lib:remote_apply(ServerNode, orber, remove_listen_interface, [Ref1])), %% Wait a few seconds to be sure that the connections really has been removed. timer:sleep(4000), ?match([_,_], orber:iiop_connections(out)), - - ?match(ok, - orber_test_lib:remote_apply(ServerNode, orber, + + ?match(ok, + orber_test_lib:remote_apply(ServerNode, orber, remove_listen_interface, [Ref2])), %% Wait a few seconds to be sure that the connections really has been removed. timer:sleep(4000), ?match([_], orber:iiop_connections(out)), - + ?match({'EXCEPTION',_}, corba:string_to_object("corbaloc::1.2@"++Loopback++":9543/NameService")), ?match({'EXCEPTION',_}, corba:string_to_object("corbaloc::1.2@"++Loopback++":"++integer_to_list(ServerPort)++"/NameService")), - + IOR4 = ?match(#'IOP_IOR'{}, corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")), - ?match({'external', {IP, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, + ?match({'external', {IP, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, iop_ior:get_key(IOR4)), ok. -proxy_interface_api(doc) -> ["IIOP Proxy Interface tests", +proxy_interface_api(doc) -> ["IIOP Proxy Interface tests", "This case test if the server ORB use the correct", "interface when exporting IOR:s"]; proxy_interface_api(suite) -> []; proxy_interface_api(_Config) -> IP = orber_test_lib:get_host(), Loopback = orber_test_lib:get_loopback_interface(), - {ok, ServerNode, _ServerHost} = + {ok, ServerNode, _ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_LOCAL_INTERFACE}])), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), IOR1 = ?match(#'IOP_IOR'{}, corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")), - ?match({'external', {IP, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, + ?match({'external', {IP, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, iop_ior:get_key(IOR1)), IOR2 = ?match(#'IOP_IOR'{}, corba:string_to_object("corbaloc::1.2@"++Loopback++":"++integer_to_list(ServerPort)++"/NameService")), - ?match({'external', {Loopback, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, + ?match({'external', {Loopback, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, iop_ior:get_key(IOR2)), ok. -proxy_interface_ipv6_api(doc) -> ["IIOP Proxy Interface tests", +proxy_interface_ipv6_api(doc) -> ["IIOP Proxy Interface tests", "This case test if the server ORB use the correct", "IPv6 interface when exporting IOR:s"]; proxy_interface_ipv6_api(suite) -> []; @@ -550,103 +576,103 @@ proxy_interface_ipv6_api(_Config) -> Reason end. -proxy_interface_ipv6_api2() -> +proxy_interface_ipv6_api2() -> Loopback = orber_test_lib:get_loopback_interface(inet6), - {ok, ServerNode, _ServerHost} = - ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, (?ORB_ENV_USE_IPV6 bor ?ORB_ENV_LOCAL_INTERFACE)}])), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), - {ok, ClientNode, _ClientHost} = + {ok, ClientNode, _ClientHost} = ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_USE_IPV6}])), - + IP = orber_test_lib:remote_apply(ClientNode, orber_test_lib, get_host, []), IOR1 = ?match(#'IOP_IOR'{}, - orber_test_lib:remote_apply(ClientNode, corba, string_to_object, + orber_test_lib:remote_apply(ClientNode, corba, string_to_object, ["corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService"])), - ?match({'external', {IP, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, + ?match({'external', {IP, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, orber_test_lib:remote_apply(ClientNode, iop_ior, get_key, [IOR1])), IOR2 = ?match(#'IOP_IOR'{}, - orber_test_lib:remote_apply(ClientNode, corba, string_to_object, + orber_test_lib:remote_apply(ClientNode, corba, string_to_object, ["corbaloc::1.2@"++Loopback++":"++integer_to_list(ServerPort)++"/NameService"])), - ?match({'external', {Loopback, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, + ?match({'external', {Loopback, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, orber_test_lib:remote_apply(ClientNode, iop_ior, get_key, [IOR2])), ok. -local_interface_api(doc) -> ["IIOP Local Interface tests", +local_interface_api(doc) -> ["IIOP Local Interface tests", "This case test if the server ORB use the correct", "local interface when connecting to another ORB"]; local_interface_api(suite) -> []; local_interface_api(_Config) -> IP = orber_test_lib:get_host(), Loopback = orber_test_lib:get_loopback_interface(), - {ok, ClientNode, _ClientHost} = + {ok, ClientNode, _ClientHost} = ?match({ok,_,_}, orber_test_lib:js_node([{ip_address_local, Loopback}])), Port = orber:iiop_port(), ?match(#'IOP_IOR'{}, - orber_test_lib:remote_apply(ClientNode, corba, string_to_object, + orber_test_lib:remote_apply(ClientNode, corba, string_to_object, ["corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService"])), - [{Loopback, RemotePort}] = + [{Loopback, RemotePort}] = ?match([{Loopback,_RemotePort}], orber:iiop_connections(in)), - ?match([{IP, Port}], - orber_test_lib:remote_apply(ClientNode, orber, + ?match([{IP, Port}], + orber_test_lib:remote_apply(ClientNode, orber, iiop_connections, [out])), ?match([{IP, Port}], orber:find_sockname_by_peername(Loopback,RemotePort)), ?match([{Loopback, RemotePort}], orber:find_peername_by_sockname(IP, Port)), - ?match([{Loopback, RemotePort}], - orber_test_lib:remote_apply(ClientNode, orber, - find_sockname_by_peername, + ?match([{Loopback, RemotePort}], + orber_test_lib:remote_apply(ClientNode, orber, + find_sockname_by_peername, [IP, Port])), - ?match([{IP, Port}], - orber_test_lib:remote_apply(ClientNode, orber, - find_peername_by_sockname, + ?match([{IP, Port}], + orber_test_lib:remote_apply(ClientNode, orber, + find_peername_by_sockname, [Loopback,RemotePort])), ok. -local_interface_ctx_override_api(doc) -> - ["IIOP Local Interface tests", +local_interface_ctx_override_api(doc) -> + ["IIOP Local Interface tests", "This case test if the server ORB use the correct", "local interface when connecting to another ORB"]; local_interface_ctx_override_api(suite) -> []; local_interface_ctx_override_api(_Config) -> IP = orber_test_lib:get_host(), Loopback = orber_test_lib:get_loopback_interface(), - {ok, ClientNode, _ClientHost} = + {ok, ClientNode, _ClientHost} = ?match({ok,_,_}, orber_test_lib:js_node([{ip_address_local, IP}])), Port = orber:iiop_port(), ?match(#'IOP_IOR'{}, - orber_test_lib:remote_apply(ClientNode, corba, string_to_object, + orber_test_lib:remote_apply(ClientNode, corba, string_to_object, ["corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService", [#'IOP_ServiceContext' - {context_id=?ORBER_GENERIC_CTX_ID, + {context_id=?ORBER_GENERIC_CTX_ID, context_data = {interface, Loopback}}]])), - [{Loopback, RemotePort}] = + [{Loopback, RemotePort}] = ?match([{Loopback,_RemotePort}], orber:iiop_connections(in)), - ?match([{IP, Port, Loopback}], - orber_test_lib:remote_apply(ClientNode, orber, + ?match([{IP, Port, Loopback}], + orber_test_lib:remote_apply(ClientNode, orber, iiop_connections, [out])), ?match([{IP, Port}], orber:find_sockname_by_peername(Loopback,RemotePort)), ?match([{Loopback, RemotePort}], orber:find_peername_by_sockname(IP, Port)), - ?match([{Loopback, RemotePort}], - orber_test_lib:remote_apply(ClientNode, orber, - find_sockname_by_peername, + ?match([{Loopback, RemotePort}], + orber_test_lib:remote_apply(ClientNode, orber, + find_sockname_by_peername, [IP, Port])), - ?match([{IP, Port}], - orber_test_lib:remote_apply(ClientNode, orber, - find_peername_by_sockname, + ?match([{IP, Port}], + orber_test_lib:remote_apply(ClientNode, orber, + find_peername_by_sockname, [Loopback,RemotePort])), ok. -local_interface_acl_override_api(doc) -> - ["IIOP Local Interface tests", +local_interface_acl_override_api(doc) -> + ["IIOP Local Interface tests", "This case test if the server ORB use the correct", "local interface when connecting to another ORB"]; local_interface_acl_override_api(suite) -> []; @@ -654,74 +680,74 @@ local_interface_acl_override_api(_Config) -> IP = orber_test_lib:get_host(), Loopback = orber_test_lib:get_loopback_interface(), ACL = [{tcp_out, IP ++ "/18", [Loopback]}], - {ok, ClientNode, _ClientHost} = + {ok, ClientNode, _ClientHost} = ?match({ok,_,_}, orber_test_lib:js_node([{ip_address_local, IP}, {iiop_acl, ACL}, {flags, ?ORB_ENV_USE_ACL_OUTGOING}])), Port = orber:iiop_port(), ?match(#'IOP_IOR'{}, - orber_test_lib:remote_apply(ClientNode, corba, string_to_object, + orber_test_lib:remote_apply(ClientNode, corba, string_to_object, ["corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService", [#'IOP_ServiceContext' - {context_id=?ORBER_GENERIC_CTX_ID, + {context_id=?ORBER_GENERIC_CTX_ID, context_data = {interface, IP}}]])), ?match([{Loopback,_RemotePort}], orber:iiop_connections(in)), ?match(#'IOP_IOR'{}, - orber_test_lib:remote_apply(ClientNode, corba, string_to_object, + orber_test_lib:remote_apply(ClientNode, corba, string_to_object, ["corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService"])), - [{Loopback, RemotePort}] = + [{Loopback, RemotePort}] = ?match([{Loopback,_RemotePort}], orber:iiop_connections(in)), - ?match([{IP, Port, IP}], orber_test_lib:remote_apply(ClientNode, orber, + ?match([{IP, Port, IP}], orber_test_lib:remote_apply(ClientNode, orber, iiop_connections, [out])), ?match([{IP, Port}], orber:find_sockname_by_peername(Loopback,RemotePort)), ?match([{Loopback, RemotePort}], orber:find_peername_by_sockname(IP, Port)), - ?match([{Loopback, RemotePort}], - orber_test_lib:remote_apply(ClientNode, orber, - find_sockname_by_peername, + ?match([{Loopback, RemotePort}], + orber_test_lib:remote_apply(ClientNode, orber, + find_sockname_by_peername, [IP, Port])), - ?match([{IP, Port}], - orber_test_lib:remote_apply(ClientNode, orber, - find_peername_by_sockname, + ?match([{IP, Port}], + orber_test_lib:remote_apply(ClientNode, orber, + find_peername_by_sockname, [Loopback,RemotePort])), ok. -iiop_timeout_api(doc) -> ["IIOP TIMEOUT API tests", +iiop_timeout_api(doc) -> ["IIOP TIMEOUT API tests", "This case test if timeout configuration behaves correctly"]; iiop_timeout_api(suite) -> []; iiop_timeout_api(_Config) -> - + %% Install two secure orber. - {ok, ClientNode, ClientHost} = + {ok, ClientNode, ClientHost} = ?match({ok,_,_}, orber_test_lib:js_node([{iiop_timeout, 6}, {iiop_connection_timeout, 3}, {iiop_in_connection_timeout, 3}])), ClientPort = orber_test_lib:remote_apply(ClientNode, orber, iiop_port, []), - - {ok, ServerNode, ServerHost} = + + {ok, ServerNode, ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node([{iiop_timeout, 6}, {iiop_connection_timeout, 3}, {iiop_in_connection_timeout, 12}])), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), - - ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, - install_test_data, + + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, [timeout])), - %% Tell client_orb to interoperate with server_orb. - ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib, + %% Tell client_orb to interoperate with server_orb. + ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib, lookup, [ServerHost, ServerPort])), %% Interop worked fine, perform delay tests. - ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib, + ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib, timeouts, [ServerHost, ServerPort, 6000])), - + %% Create a connection to the "client_orb", which will now act as server. - ?match({'IOP_IOR',_,_}, + ?match({'IOP_IOR',_,_}, corba:string_to_object("corbaloc::1.2@"++ClientHost++":"++integer_to_list(ClientPort)++"/NameService")), %% Check that the connection is established. ?match([{_, ClientPort}], orber:iiop_connections(out)), @@ -729,13 +755,13 @@ iiop_timeout_api(_Config) -> %% have been closed. timer:sleep(8000), ?match([], orber:iiop_connections(out)), - - ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, - uninstall_test_data, + + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + uninstall_test_data, [timeout])), ok. -iiop_timeout_added_api(doc) -> ["IIOP TIMEOUT API tests", +iiop_timeout_added_api(doc) -> ["IIOP TIMEOUT API tests", "This case test if timeout configuration behaves correctly"]; iiop_timeout_added_api(suite) -> []; iiop_timeout_added_api(_Config) -> @@ -743,18 +769,18 @@ iiop_timeout_added_api(_Config) -> {ok, Node, _Host} = ?match({ok,_,_}, orber_test_lib:js_node([])), Port = 1 + orber_test_lib:remote_apply(Node, orber, iiop_port, []), ?match({ok, _}, - orber_test_lib:remote_apply(Node, orber, - add_listen_interface, - [IP, normal, + orber_test_lib:remote_apply(Node, orber, + add_listen_interface, + [IP, normal, [{iiop_in_connection_timeout, 3}, {flags, ?ORB_ENV_LOCAL_INTERFACE}, {iiop_port, Port}]])), - - ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, - install_test_data, + + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + install_test_data, [timeout])), - ?match({'IOP_IOR',_,_}, + ?match({'IOP_IOR',_,_}, corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService")), %% Check that the connection is established. ?match([{_, Port}], orber:iiop_connections(out)), @@ -762,9 +788,9 @@ iiop_timeout_added_api(_Config) -> %% have been closed. timer:sleep(8000), ?match([], orber:iiop_connections(out)), - - ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, - uninstall_test_data, + + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + uninstall_test_data, [timeout])), ok. @@ -772,27 +798,27 @@ iiop_timeout_added_api(_Config) -> %% API tests for ORB to ORB using pseudo call/cast, no security %%----------------------------------------------------------------- -multi_pseudo_orber_api(doc) -> - ["MULTI ORB PSEUDO API tests", +multi_pseudo_orber_api(doc) -> + ["MULTI ORB PSEUDO API tests", "This case test if data encode/decode (IIOP) for pseudo objects", "produce the correct result, i.e., the test_server echos", "the input parameter or an exception is raised (MARSHAL)."]; multi_pseudo_orber_api(suite) -> []; multi_pseudo_orber_api(_Config) -> %% --- Create a slave-node --- - {ok, Node, Host} = - ?match({ok,_,_}, orber_test_lib:js_node()), + {ok, Node, Host} = + ?match({ok,_,_}, orber_test_lib:js_node()), Port = orber_test_lib:remote_apply(Node, orber, iiop_port, []), - - ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, - install_test_data, + + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + install_test_data, [pseudo])), - + NSR = ?match({'IOP_IOR',"IDL:omg.org/CosNaming/NamingContextExt:1.0",_}, corba:string_to_object("corbaloc::1.1@"++Host++":"++ integer_to_list(Port)++"/NameService")), - Obj = - ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + Obj = + ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, 'CosNaming_NamingContext':resolve(NSR, lname:new(["mamba"]))), orber_test_lib:corba_object_tests(Obj, NSR), @@ -809,11 +835,11 @@ multi_pseudo_orber_api(_Config) -> orber_test_lib:test_coding(Obj), %% Test if exit is handled properly. - ?match({'EXCEPTION',{'TRANSIENT',_,_,_}}, + ?match({'EXCEPTION',{'TRANSIENT',_,_,_}}, orber_test_server:stop_brutal(Obj)), - ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, - uninstall_test_data, + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + uninstall_test_data, [pseudo])), ok. @@ -821,77 +847,77 @@ multi_pseudo_orber_api(_Config) -> %%----------------------------------------------------------------- %% API tests for ORB to ORB with local flags definition set. %%----------------------------------------------------------------- -flags_added_api(doc) -> +flags_added_api(doc) -> ["MULTI ORB PSEUDO with local flags definition set"]; flags_added_api(suite) -> []; flags_added_api(_Config) -> %% --- Create a slave-node --- IP = orber_test_lib:get_host(), - {ok, Node, _Host} = - ?match({ok,_,_}, orber_test_lib:js_node([])), + {ok, Node, _Host} = + ?match({ok,_,_}, orber_test_lib:js_node([])), Port = 1 + orber_test_lib:remote_apply(Node, orber, iiop_port, []), ?match({ok, _}, - orber_test_lib:remote_apply(Node, orber, - add_listen_interface, - [IP, normal, + orber_test_lib:remote_apply(Node, orber, + add_listen_interface, + [IP, normal, [{flags, (?ORB_ENV_LOCAL_INTERFACE bor ?ORB_ENV_EXCLUDE_CODESET_COMPONENT)}, {iiop_port, Port}]])), - ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, - install_test_data, + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + install_test_data, [pseudo])), Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, corba:string_to_object("corbaname::1.1@"++IP++":"++ integer_to_list(Port)++"/NameService#mamba")), - ?match({'external', {IP, Port, _ObjectKey, _Counter, - #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, - profile_data= - #'IIOP_ProfileBody_1_1'{components=[]}}, - _NewHD}}, + ?match({'external', {IP, Port, _ObjectKey, _Counter, + #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, + profile_data= + #'IIOP_ProfileBody_1_1'{components=[]}}, + _NewHD}}, iop_ior:get_key(Obj)), - ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, - uninstall_test_data, + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + uninstall_test_data, [pseudo])), ok. - + %%----------------------------------------------------------------- %% API tests for ORB to ORB with limited concurrent requests %%----------------------------------------------------------------- -max_requests_api(doc) -> +max_requests_api(doc) -> ["MULTI ORB PSEUDO with limited concurrent requests tests"]; max_requests_api(suite) -> []; max_requests_api(_Config) -> %% --- Create a slave-node --- - {ok, Node, Host} = - ?match({ok,_,_}, orber_test_lib:js_node([{iiop_max_in_requests, 1}])), + {ok, Node, Host} = + ?match({ok,_,_}, orber_test_lib:js_node([{iiop_max_in_requests, 1}])), Port = orber_test_lib:remote_apply(Node, orber, iiop_port, []), max_requests(Node, Host, Port). -max_requests_added_api(doc) -> +max_requests_added_api(doc) -> ["MULTI ORB PSEUDO with limited concurrent requests tests"]; max_requests_added_api(suite) -> []; max_requests_added_api(_Config) -> %% --- Create a slave-node --- [IP] = ?match([_], orber:host()), - {ok, Node, _Host} = - ?match({ok,_,_}, orber_test_lib:js_node([])), + {ok, Node, _Host} = + ?match({ok,_,_}, orber_test_lib:js_node([])), Port = 1 + orber_test_lib:remote_apply(Node, orber, iiop_port, []), ?match({ok, _}, - orber_test_lib:remote_apply(Node, orber, - add_listen_interface, - [IP, normal, + orber_test_lib:remote_apply(Node, orber, + add_listen_interface, + [IP, normal, [{iiop_max_in_requests, 1}, {flags, ?ORB_ENV_LOCAL_INTERFACE}, {iiop_port, Port}]])), max_requests(Node, IP, Port). -max_requests(Node, Host, Port) -> - ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, - install_test_data, +max_requests(Node, Host, Port) -> + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + install_test_data, [pseudo])), Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, corba:string_to_object("corbaname::1.1@"++Host++":"++ @@ -899,7 +925,7 @@ max_requests(Node, Host, Port) -> %% Can we even contact the object? ?match(ok, orber_test_server:print(Obj)), - + %% Invoke one blocking call followed by several invokations. spawn(orber_test_server, pseudo_call_delay, [Obj, 15000]), %% Wait for a second to be sure that the previous request has been sent @@ -912,8 +938,8 @@ max_requests(Node, Host, Port) -> %% allow one request at a time to the target ORB. ?match(true, (MegaSecsB + (Before+8)*1000000) < (MegaSecsA + After*1000000)), - ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, - uninstall_test_data, + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + uninstall_test_data, [pseudo])), ok. @@ -921,17 +947,17 @@ max_requests(Node, Host, Port) -> %%----------------------------------------------------------------- %% API tests for ORB to ORB with limited concurrent connections %%----------------------------------------------------------------- -max_connections_api(doc) -> +max_connections_api(doc) -> ["MULTI ORB PSEUDO with limited concurrent connections tests"]; max_connections_api(suite) -> []; max_connections_api(_Config) -> %% --- Create a slave-node --- - {ok, ServerNode, ServerHost} = + {ok, ServerNode, ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node([{iiop_backlog, 0}, {iiop_max_in_connections, 2}])), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), - ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, - install_test_data, + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, [nameservice])), %% Claim connection 1 & 2 @@ -939,26 +965,26 @@ max_connections_api(_Config) -> corba:string_to_object("corbaname::1.2@"++ServerHost++":"++ integer_to_list(ServerPort)++"/NameService#mamba")), %% Claim backlog - {ok, ClientNode, _ClientHost} = - ?match({ok,_,_}, orber_test_lib:js_node()), + {ok, ClientNode, _ClientHost} = + ?match({ok,_,_}, orber_test_lib:js_node()), spawn(ClientNode, orber_test_server, print, [Obj]), timer:sleep(5000), ?match([_], orber_test_lib:remote_apply(ClientNode, orber, iiop_connections, [])), - + %% Try to connect. Should fail. Due to the behavior of different TCP stacks, backlog 1 %% might not be the precise value. Hence, we also need to define the iiop_timeout. Otherwise %% this test case will fail. For the same reason we must GC this connection. - {ok, ClientNodeII, _ClientHostII} = + {ok, ClientNodeII, _ClientHostII} = ?match({ok,_,_}, orber_test_lib:js_node([{iiop_setup_connection_timeout, 5}, {iiop_timeout, 5}, {iiop_connection_timeout, 8}])), - ?match({'EXCEPTION', _}, - orber_test_lib:remote_apply(ClientNodeII, orber_test_server, + ?match({'EXCEPTION', _}, + orber_test_lib:remote_apply(ClientNodeII, orber_test_server, testing_iiop_string, [Obj, "Fail"])), - + %% Remove 2 connections. We need to wait a moment so that both sides has detected it. timer:sleep(5000), ?match([_,_], orber:iiop_connections()), @@ -968,23 +994,23 @@ max_connections_api(_Config) -> ?match(ok, orber_iiop_pm:close_connection([{Host, Port}])), timer:sleep(5000), ?match([], orber:iiop_connections()), - + ?match([_], orber_test_lib:remote_apply(ClientNode, orber, iiop_connections, [])), ?match([], orber_test_lib:remote_apply(ClientNodeII, orber, iiop_connections, [])), - ?match({ok, "OK"}, - orber_test_lib:remote_apply(ClientNodeII, orber_test_server, + ?match({ok, "OK"}, + orber_test_lib:remote_apply(ClientNodeII, orber_test_server, testing_iiop_string, [Obj, "OK"])), - + timer:sleep(4000), ?match([_], orber_test_lib:remote_apply(ClientNodeII, orber, iiop_connections, [])), - ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, - uninstall_test_data, + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + uninstall_test_data, [pseudo])), ok. @@ -993,18 +1019,18 @@ max_connections_api(_Config) -> %%----------------------------------------------------------------- %% API tests for terminating connection by using an IOR. %%----------------------------------------------------------------- -close_connections_api(doc) -> +close_connections_api(doc) -> ["Close outgoing connection "]; close_connections_api(suite) -> []; close_connections_api(_Config) -> %% --- Create a slave-node --- IP = orber_test_lib:get_host(), Loopback = orber_test_lib:get_loopback_interface(), - {ok, ServerNode, _ServerHost} = + {ok, ServerNode, _ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node([{ip_address, IP}])), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), - ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, - install_test_data, + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, [nameservice])), orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), IP = orber_test_lib:get_host(), @@ -1028,108 +1054,108 @@ close_connections_api(_Config) -> ok. -close_connections_local_interface_api(doc) -> - ["IIOP Local Interface disconnect tests", +close_connections_local_interface_api(doc) -> + ["IIOP Local Interface disconnect tests", "This case test if the server ORB use the correct", "local interface when connecting to another ORB"]; close_connections_local_interface_api(suite) -> []; close_connections_local_interface_api(_Config) -> IP = orber_test_lib:get_host(), Loopback = orber_test_lib:get_loopback_interface(), - {ok, ClientNode, _ClientHost} = + {ok, ClientNode, _ClientHost} = ?match({ok,_,_}, orber_test_lib:js_node([{ip_address_local, Loopback}])), - {ok, ServerNode, _ServerHost} = + {ok, ServerNode, _ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node([{ip_address, IP}])), Port = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), IOR = ?match(#'IOP_IOR'{}, - orber_test_lib:remote_apply(ClientNode, corba, string_to_object, + orber_test_lib:remote_apply(ClientNode, corba, string_to_object, ["corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService"])), %% Check that the connnection is up and running using the default interface - ?match([{Loopback,_RemotePort}], orber_test_lib:remote_apply(ServerNode, orber, + ?match([{Loopback,_RemotePort}], orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])), - ?match([{IP, Port}], - orber_test_lib:remote_apply(ClientNode, orber, + ?match([{IP, Port}], + orber_test_lib:remote_apply(ClientNode, orber, iiop_connections, [out])), %% Try to close the connection - ?match(ok, orber_test_lib:remote_apply(ClientNode, orber, + ?match(ok, orber_test_lib:remote_apply(ClientNode, orber, close_connection, [IOR])), %% Wait a moment so that both sides has detected it. timer:sleep(5000), %% Now the connection shall be gone. - ?match([], orber_test_lib:remote_apply(ClientNode, orber, + ?match([], orber_test_lib:remote_apply(ClientNode, orber, iiop_connections, [out])), - ?match([], orber_test_lib:remote_apply(ServerNode, orber, + ?match([], orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])), ok. -close_connections_local_interface_ctx_override_api(doc) -> - ["IIOP Local Interface disconnect tests", +close_connections_local_interface_ctx_override_api(doc) -> + ["IIOP Local Interface disconnect tests", "This case test if the server ORB use the correct", "local interface when connecting to another ORB"]; close_connections_local_interface_ctx_override_api(suite) -> []; close_connections_local_interface_ctx_override_api(_Config) -> IP = orber_test_lib:get_host(), Loopback = orber_test_lib:get_loopback_interface(), - {ok, ClientNode, _ClientHost} = + {ok, ClientNode, _ClientHost} = ?match({ok,_,_}, orber_test_lib:js_node([{ip_address_local, IP}, {ip_address, IP}])), - {ok, ServerNode, _ServerHost} = + {ok, ServerNode, _ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node([{ip_address, IP}])), Port = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), IOR = ?match(#'IOP_IOR'{}, - orber_test_lib:remote_apply(ClientNode, corba, string_to_object, + orber_test_lib:remote_apply(ClientNode, corba, string_to_object, ["corbaloc::1.2@"++IP++":"++integer_to_list(Port)++"/NameService", [#'IOP_ServiceContext' - {context_id=?ORBER_GENERIC_CTX_ID, + {context_id=?ORBER_GENERIC_CTX_ID, context_data = {interface, Loopback}}]])), timer:sleep(2000), %% Check that the connnection is up and running using the default interface - ?match([{Loopback,_RemotePort}], orber_test_lib:remote_apply(ServerNode, orber, + ?match([{Loopback,_RemotePort}], orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])), - - ?match([{IP, Port, Loopback}], - orber_test_lib:remote_apply(ClientNode, orber, + + ?match([{IP, Port, Loopback}], + orber_test_lib:remote_apply(ClientNode, orber, iiop_connections, [out])), %% Try to close not supplying the interface. - ?match(ok, orber_test_lib:remote_apply(ClientNode, orber, + ?match(ok, orber_test_lib:remote_apply(ClientNode, orber, close_connection, [IOR])), - + timer:sleep(2000), %% The connection shall still be up and running - ?match([{Loopback,_RemotePort}], orber_test_lib:remote_apply(ServerNode, orber, + ?match([{Loopback,_RemotePort}], orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])), - ?match([{IP, Port, Loopback}], - orber_test_lib:remote_apply(ClientNode, orber, + ?match([{IP, Port, Loopback}], + orber_test_lib:remote_apply(ClientNode, orber, iiop_connections, [out])), %% Try to close not supplying the interface. - ?match(ok, orber_test_lib:remote_apply(ClientNode, orber, + ?match(ok, orber_test_lib:remote_apply(ClientNode, orber, close_connection, [IOR, IP])), - timer:sleep(2000), + timer:sleep(2000), %% The connection shall still be up and running - ?match([{Loopback,_RemotePort}], orber_test_lib:remote_apply(ServerNode, orber, + ?match([{Loopback,_RemotePort}], orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])), - ?match([{IP, Port, Loopback}], - orber_test_lib:remote_apply(ClientNode, orber, + ?match([{IP, Port, Loopback}], + orber_test_lib:remote_apply(ClientNode, orber, iiop_connections, [out])), - + %% Try to close supplying the correct interface. - ?match(ok, orber_test_lib:remote_apply(ClientNode, orber, + ?match(ok, orber_test_lib:remote_apply(ClientNode, orber, close_connection, [IOR, Loopback])), %% Wait a moment so that both sides has detected it. timer:sleep(5000), %% Now the connection shall be gone. - ?match([], orber_test_lib:remote_apply(ServerNode, orber, + ?match([], orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])), - ?match([], orber_test_lib:remote_apply(ClientNode, orber, + ?match([], orber_test_lib:remote_apply(ClientNode, orber, iiop_connections, [out])), ok. -close_connections_alt_iiop_addr_api(doc) -> - ["IIOP alternate address disconnect tests", +close_connections_alt_iiop_addr_api(doc) -> + ["IIOP alternate address disconnect tests", "This case test if the server ORB use the correct", "local interface when connecting to another ORB"]; close_connections_alt_iiop_addr_api(suite) -> []; @@ -1137,12 +1163,12 @@ close_connections_alt_iiop_addr_api(_Config) -> %% --- Create a slave-node --- Loopback = orber_test_lib:get_loopback_interface(), IP = orber_test_lib:get_host(), - {ok, ServerNode, _ServerHost} = + {ok, ServerNode, _ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node([{giop_version, {1, 2}}, {ip_address, {multiple, [IP, Loopback]}}])), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), - ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, - install_test_data, + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, [{nameservice, Loopback, ServerPort}])), %% Create two connections Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, @@ -1151,25 +1177,25 @@ close_connections_alt_iiop_addr_api(_Config) -> ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, corba:string_to_object("corbaname::1.2@"++Loopback++":"++ integer_to_list(ServerPort)++"/NameService#mamba")), - timer:sleep(2000), + timer:sleep(2000), %% The connection shall still be up and running ?match([{_,_}, {_,_}], orber:iiop_connections(out)), ?match([{_,_}, {_,_}], - orber_test_lib:remote_apply(ServerNode, orber, + orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])), - + %% Try to close the connection ?match(ok, orber:close_connection(Obj)), %% Wait a moment so that both sides has detected it. timer:sleep(5000), %% Now the connections shall be gone. ?match([], orber:iiop_connections(out)), - ?match([], orber_test_lib:remote_apply(ServerNode, orber, + ?match([], orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])), ok. -close_connections_multiple_profiles_api(doc) -> - ["IIOP alternate address disconnect tests", +close_connections_multiple_profiles_api(doc) -> + ["IIOP alternate address disconnect tests", "This case test if the server ORB use the correct", "local interface when connecting to another ORB"]; close_connections_multiple_profiles_api(suite) -> []; @@ -1177,11 +1203,11 @@ close_connections_multiple_profiles_api(_Config) -> IP = orber_test_lib:get_host(), Loopback = orber_test_lib:get_loopback_interface(), %% --- Create a slave-node --- - {ok, ServerNode, _ServerHost} = - ?match({ok,_,_}, orber_test_lib:js_node([{ip_address, + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{ip_address, {multiple, [Loopback, IP]}}])), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), - ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, install_test_data, [nameservice])), %% Create two connections Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, @@ -1193,23 +1219,23 @@ close_connections_multiple_profiles_api(_Config) -> %% The connection shall still be up and running ?match([{_,_}, {_,_}], orber:iiop_connections(out)), ?match([{_,_}, {_,_}], - orber_test_lib:remote_apply(ServerNode, orber, + orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])), - + %% Try to close the connection ?match(ok, orber:close_connection(Obj)), %% Wait a moment so that both sides has detected it. timer:sleep(5000), %% Now the connections shall be gone. ?match([], orber:iiop_connections(out)), - ?match([], orber_test_lib:remote_apply(ServerNode, orber, + ?match([], orber_test_lib:remote_apply(ServerNode, orber, iiop_connections, [in])), ok. %%----------------------------------------------------------------- %% API tests for ORB to ORB with iiop_packet_size set %%----------------------------------------------------------------- -max_packet_size_exceeded_api(doc) -> +max_packet_size_exceeded_api(doc) -> ["Exceed the maximum request size"]; max_packet_size_exceeded_api(suite) -> []; max_packet_size_exceeded_api(_Config) -> @@ -1219,11 +1245,11 @@ max_packet_size_exceeded_api(_Config) -> {ok, LS} -> (catch gen_tcp:close(LS)), %% --- Create a slave-node --- - {ok, ServerNode, ServerHost} = + {ok, ServerNode, ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node([{iiop_packet_size, 1}])), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), - ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}}, + ?match({'EXCEPTION', #'CosNaming_NamingContextExt_InvalidAddress'{}}, corba:string_to_object("corbaloc::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService")), ok end. @@ -1231,7 +1257,7 @@ max_packet_size_exceeded_api(_Config) -> %%----------------------------------------------------------------- %% API tests for ORB to ORB with iiop_packet_size set %%----------------------------------------------------------------- -max_packet_size_ok_api(doc) -> +max_packet_size_ok_api(doc) -> ["Not exceed the maximum request size"]; max_packet_size_ok_api(suite) -> []; max_packet_size_ok_api(_Config) -> @@ -1241,7 +1267,7 @@ max_packet_size_ok_api(_Config) -> {ok, LS} -> (catch gen_tcp:close(LS)), %% --- Create a slave-node --- - {ok, ServerNode, ServerHost} = + {ok, ServerNode, ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node([{iiop_packet_size, 5000}])), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), @@ -1251,7 +1277,7 @@ max_packet_size_ok_api(_Config) -> end. - + %%----------------------------------------------------------------- %% API tests for ORB to ORB, no security %%----------------------------------------------------------------- @@ -1259,49 +1285,49 @@ max_packet_size_ok_api(_Config) -> light_ifr_api(doc) -> ["LIGHT IFR ORB API tests"]; light_ifr_api(suite) -> []; light_ifr_api(_Config) -> - - {ok, ClientNode, _ClientHost} = + + {ok, ClientNode, _ClientHost} = ?match({ok,_,_}, orber_test_lib:js_node([{flags, 128}])), ?match([_,_,_,_], orber_test_lib:remote_apply(ClientNode, orber, get_tables, [])), - ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib, - install_test_data, + ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib, + install_test_data, [nameservice])), - {ok, ServerNode, ServerHost} = - ?match({ok,_,_}, orber_test_lib:js_node([{flags, 128}])), + {ok, ServerNode, ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, 128}])), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), - ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, - install_test_data, + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, [nameservice])), ?match([_,_,_,_], orber_test_lib:remote_apply(ServerNode, orber, get_tables, [])), - Obj = ?match({'IOP_IOR',_,_}, + Obj = ?match({'IOP_IOR',_,_}, corba:string_to_object("corbaname::1.2@"++ServerHost++":"++integer_to_list(ServerPort)++"/NameService#mamba")), ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib, test_coding, [Obj])), ?match(0, orber_test_lib:remote_apply(ClientNode, orber_diagnostics, missing_modules, [])), - ?match(ok, orber_test_lib:remote_apply(ClientNode, mnesia, dirty_write, + ?match(ok, orber_test_lib:remote_apply(ClientNode, mnesia, dirty_write, [#orber_light_ifr{id = "FakeId1", - module=non_existing, + module=non_existing, type=?IFR_StructDef}])), - ?match(ok, orber_test_lib:remote_apply(ClientNode, mnesia, dirty_write, + ?match(ok, orber_test_lib:remote_apply(ClientNode, mnesia, dirty_write, [#orber_light_ifr{id = "FakeId2", - module=non_existing, + module=non_existing, type=?IFR_UnionDef}])), - ?match(ok, orber_test_lib:remote_apply(ClientNode, mnesia, dirty_write, + ?match(ok, orber_test_lib:remote_apply(ClientNode, mnesia, dirty_write, [#orber_light_ifr{id = "FakeId3", - module=non_existing, + module=non_existing, type=?IFR_ExceptionDef}])), - ?match(ok, orber_test_lib:remote_apply(ClientNode, mnesia, dirty_write, + ?match(ok, orber_test_lib:remote_apply(ClientNode, mnesia, dirty_write, [#orber_light_ifr{id = "FakeId4", - module=non_existing, + module=non_existing, type=?IFR_InterfaceDef}])), - ?match(ok, orber_test_lib:remote_apply(ClientNode, mnesia, dirty_write, + ?match(ok, orber_test_lib:remote_apply(ClientNode, mnesia, dirty_write, [#orber_light_ifr{id = "FakeId5", - module=orber_test_lib, + module=orber_test_lib, type=?IFR_InterfaceDef}])), ?match(5, orber_test_lib:remote_apply(ClientNode, orber_diagnostics, missing_modules, [])), @@ -1316,14 +1342,14 @@ light_ifr_api(_Config) -> absolute_name="::Module::NonExisting"})), ?match(ok, mnesia:dirty_write(#ir_InterfaceDef{ir_Internal_ID = "FakedIId5", absolute_name="::orber::test::lib"})), - + ?match(5, orber_diagnostics:missing_modules()), - ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, - uninstall_test_data, + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + uninstall_test_data, [nameservice])), - ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib, - uninstall_test_data, + ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib, + uninstall_test_data, [nameservice])), ok. @@ -1331,23 +1357,23 @@ light_ifr_api(_Config) -> %% API tests for ORB to ORB, no security %%----------------------------------------------------------------- -light_orber_api(doc) -> ["LIGHT ORB API tests", +light_orber_api(doc) -> ["LIGHT ORB API tests", "This case test if a light Orber can communicate correctly", "with an fully installed Orber."]; light_orber_api(suite) -> []; light_orber_api(_Config) -> %% --- Create a slave-node --- LocalHost = net_adm:localhost(), - {ok, Node, _Host} = + {ok, Node, _Host} = ?match({ok,_,_}, orber_test_lib:js_node([{lightweight, ["iiop://"++LocalHost++":"++integer_to_list(orber:iiop_port())]}], lightweight)), ?match(ok, orber:info(io)), ?match([_], orber_test_lib:remote_apply(Node, orber_env, get_lightweight_nodes,[])), - - ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, - install_test_data, + + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + install_test_data, [light])), - + Obj1=(catch orber_test_server:oe_create(state,[{pseudo,true}])), ?match({_,pseudo,orber_test_server_impl, _,_, _}, Obj1), Obj2=(catch orber_test_server:oe_create(state,[])), @@ -1357,11 +1383,11 @@ light_orber_api(_Config) -> 'CosNaming_NamingContext':bind(NS, lname:new(["mamba"]), Obj1), 'CosNaming_NamingContext':bind(NS, lname:new(["viper"]), Obj2), - ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, light_tests, [LocalHost, orber:iiop_port(), "viper"])), - ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, light_tests, [LocalHost, orber:iiop_port(), "mamba"])), @@ -1370,17 +1396,17 @@ light_orber_api(_Config) -> catch corba:dispose(Obj1), catch corba:dispose(Obj2), - catch 'CosNaming_NamingContext':destroy(NS), + catch 'CosNaming_NamingContext':destroy(NS), - ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, - uninstall_test_data, + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + uninstall_test_data, [light])), ok. %%----------------------------------------------------------------- %% API tests for ORB to ORB, no security %%----------------------------------------------------------------- -light_orber2_api(doc) -> ["LIGHT ORB API tests", +light_orber2_api(doc) -> ["LIGHT ORB API tests", "This case test if a light Orber can communicate correctly", "with an fully installed Orber. This case test if we can", "start as lightweight without first setting the environment", @@ -1389,16 +1415,16 @@ light_orber2_api(suite) -> []; light_orber2_api(_Config) -> %% --- Create a slave-node --- LocalHost = net_adm:localhost(), - {ok, Node, _Host} = - ?match({ok,_,_}, orber_test_lib:js_node([], + {ok, Node, _Host} = + ?match({ok,_,_}, orber_test_lib:js_node([], {lightweight, ["iiop://"++LocalHost++":"++integer_to_list(orber:iiop_port())]})), ?match(ok, orber:info(io)), ?match([_], orber_test_lib:remote_apply(Node, orber_env, get_lightweight_nodes,[])), - - ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, - install_test_data, + + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + install_test_data, [light])), - + Obj1=(catch orber_test_server:oe_create(state,[{pseudo,true}])), ?match({_,pseudo,orber_test_server_impl, _,_, _}, Obj1), Obj2=(catch orber_test_server:oe_create(state,[])), @@ -1407,12 +1433,12 @@ light_orber2_api(_Config) -> NS = corba:resolve_initial_references("NameService"), 'CosNaming_NamingContext':bind(NS, lname:new(["mamba"]), Obj1), 'CosNaming_NamingContext':bind(NS, lname:new(["viper"]), Obj2), - - ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, light_tests, [LocalHost, orber:iiop_port(), "viper"])), - ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, light_tests, [LocalHost, orber:iiop_port(), "mamba"])), @@ -1421,10 +1447,10 @@ light_orber2_api(_Config) -> catch corba:dispose(Obj1), catch corba:dispose(Obj2), - catch 'CosNaming_NamingContext':destroy(NS), + catch 'CosNaming_NamingContext':destroy(NS), - ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, - uninstall_test_data, + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + uninstall_test_data, [light])), ok. @@ -1432,13 +1458,13 @@ light_orber2_api(_Config) -> %% API tests for ORB to ORB, no security %%----------------------------------------------------------------- -multi_orber_api(doc) -> ["MULTI ORB API tests", +multi_orber_api(doc) -> ["MULTI ORB API tests", "This case test if data encode/decode (IIOP)", "produce the correct result, i.e., the test_server echos", "the input parameter or an exception is raised (MARSHAL)."]; multi_orber_api(suite) -> []; multi_orber_api(_Config) -> - + NewICObj1 = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([])), NewICObj2 = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([], [{regname, {local, newic2}}])), NewICObj3 = ?match({_,_,_,_,_,_}, orber_test_server:oe_create([], [{regname, {global, newic3}}])), @@ -1448,34 +1474,34 @@ multi_orber_api(_Config) -> catch corba:dispose(NewICObj1), catch corba:dispose(NewICObj2), catch corba:dispose(NewICObj3), - + %% --- Create a slave-node --- - {ok, Node, Host} = - ?match({ok,_,_}, orber_test_lib:js_node()), + {ok, Node, Host} = + ?match({ok,_,_}, orber_test_lib:js_node()), Port = orber_test_lib:remote_apply(Node, orber, iiop_port, []), - - ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, - install_test_data, + + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + install_test_data, [nameservice])), - + NSR = ?match({'IOP_IOR',"IDL:omg.org/CosNaming/NamingContextExt:1.0",_}, corba:string_to_object("corbaloc::1.2@"++Host++":"++ integer_to_list(Port)++"/NameService")), - + ?match({'EXCEPTION',{'CosNaming_NamingContext_NotFound',_,_,_}}, 'CosNaming_NamingContext':resolve(NSR, lname:new(["not_exist"]))), - Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, 'CosNaming_NamingContext':resolve(NSR, lname:new(["mamba"]))), ?match(ok, orber_test_server:print(Obj)), - Obj12B = ?match({'IOP_IOR',_,_}, + Obj12B = ?match({'IOP_IOR',_,_}, corba:string_to_object("corbaloc::1.2@"++Host++":"++integer_to_list(Port)++"/Mamba")), - - Obj11B = ?match({'IOP_IOR',_,_}, + + Obj11B = ?match({'IOP_IOR',_,_}, corba:string_to_object("corbaloc::1.1@"++Host++":"++integer_to_list(Port)++"/Mamba")), - Obj10B = ?match({'IOP_IOR',_,_}, + Obj10B = ?match({'IOP_IOR',_,_}, corba:string_to_object("corbaloc::1.0@"++Host++":"++integer_to_list(Port)++"/Mamba")), context_test(Obj12B), @@ -1484,7 +1510,7 @@ multi_orber_api(_Config) -> ?match(ok, orber_test_server:print(Obj12B)), ?match(ok, orber_test_server:print(Obj11B)), ?match(ok, orber_test_server:print(Obj10B)), - ?match({'EXCEPTION',{'CosNaming_NamingContextExt_InvalidAddress',_}}, + ?match({'EXCEPTION',{'CosNaming_NamingContextExt_InvalidAddress',_}}, corba:string_to_object("corbaloc::1.0@"++Host++":"++integer_to_list(Port)++"/Wrong")), ?match(ok, orber_test_lib:corba_object_tests(Obj12B, NSR)), @@ -1493,22 +1519,22 @@ multi_orber_api(_Config) -> %%--- Testing code and decode arguments --- orber_test_lib:test_coding(Obj), - - ?match({'EXCEPTION',#'BAD_CONTEXT'{}}, + + ?match({'EXCEPTION',#'BAD_CONTEXT'{}}, orber_test_server: - print(Obj12B, + print(Obj12B, [{context, - [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, - context_data = {interface, + [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, + context_data = {interface, {127,0,0,1}}}]}])), - - ?match({'EXCEPTION',{'TRANSIENT',_,_,_}}, + + ?match({'EXCEPTION',{'TRANSIENT',_,_,_}}, orber_test_server:stop_brutal(Obj12B)), - ?match({'EXCEPTION',{'TRANSIENT',_,_,_}}, + ?match({'EXCEPTION',{'TRANSIENT',_,_,_}}, orber_test_server:print(Obj12B)), - ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, - uninstall_test_data, + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + uninstall_test_data, [nameservice])), ok. @@ -1516,9 +1542,9 @@ multi_orber_api(_Config) -> %%----------------------------------------------------------------- %% API tests for ORB to ORB, no security, using basic interceptors %%----------------------------------------------------------------- -basic_PI_api(doc) -> ["MULTI ORB API tests", +basic_PI_api(doc) -> ["MULTI ORB API tests", "This case test if data encode/decode (IIOP)", - "produce the correct result when using basic interceptors,", + "produce the correct result when using basic interceptors,", "i.e., the test_server echos", "the input parameter or an exception is raised (MARSHAL)."]; basic_PI_api(suite) -> []; @@ -1526,21 +1552,21 @@ basic_PI_api(_Config) -> %% Change configuration to use Basic Interceptors. orber:configure_override(interceptors, {native, [orber_test_lib]}), %% --- Create a slave-node --- - {ok, Node, Host} = - ?match({ok,_,_}, orber_test_lib:js_node([{interceptors, {native, [orber_test_lib]}}])), + {ok, Node, Host} = + ?match({ok,_,_}, orber_test_lib:js_node([{interceptors, {native, [orber_test_lib]}}])), Port = orber_test_lib:remote_apply(Node, orber, iiop_port, []), - - ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, - install_test_data, + + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + install_test_data, [nameservice])), - - Obj12 = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + + Obj12 = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, corba:string_to_object("corbaname::1.2@"++Host++":"++integer_to_list(Port)++"/NameService#mamba")), - - Obj11 = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + + Obj11 = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, corba:string_to_object("corbaname::1.1@"++Host++":"++integer_to_list(Port)++"/NameService#mamba")), - - Obj10 = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + + Obj10 = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, corba:string_to_object("corbaname::1.0@"++Host++":"++integer_to_list(Port)++"/NameService#mamba")), ?match(ok, corba:print_object(Obj12)), @@ -1552,13 +1578,13 @@ basic_PI_api(_Config) -> ?match(ok, orber_test_server:print(Obj10)), - Obj12B = ?match({'IOP_IOR',_,_}, + Obj12B = ?match({'IOP_IOR',_,_}, corba:string_to_object("corbaloc::1.2@"++Host++":"++integer_to_list(Port)++"/Mamba")), - - Obj11B = ?match({'IOP_IOR',_,_}, + + Obj11B = ?match({'IOP_IOR',_,_}, corba:string_to_object("corbaloc::1.1@"++Host++":"++integer_to_list(Port)++"/Mamba")), - - Obj10B = ?match({'IOP_IOR',_,_}, + + Obj10B = ?match({'IOP_IOR',_,_}, corba:string_to_object("corbaloc::1.0@"++Host++":"++integer_to_list(Port)++"/Mamba")), ?match(ok, corba:print_object(Obj12B, info_msg)), @@ -1568,7 +1594,7 @@ basic_PI_api(_Config) -> ?match(ok, orber_test_server:print(Obj12B)), ?match(ok, orber_test_server:print(Obj11B)), ?match(ok, orber_test_server:print(Obj10B)), - ?match({'EXCEPTION',{'CosNaming_NamingContextExt_InvalidAddress',_}}, + ?match({'EXCEPTION',{'CosNaming_NamingContextExt_InvalidAddress',_}}, corba:string_to_object("corbaloc::1.0@"++Host++":"++integer_to_list(Port)++"/Wrong")), ?match(ok, orber_test_lib:alternate_iiop_address(Host, Port)), @@ -1583,8 +1609,8 @@ basic_PI_api(_Config) -> application:set_env(orber, interceptors, false), - ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, - uninstall_test_data, + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + uninstall_test_data, [nameservice])), ok. @@ -1593,62 +1619,95 @@ basic_PI_api(_Config) -> %% API tests for ORB to ORB, ssl security depth 1 %%----------------------------------------------------------------- -ssl_1_multi_orber_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth 1)", +ssl_1_multi_orber_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth 1)", "This case set up two secure orbs and test if they can", "communicate. The case also test to access one of the", "secure orbs which must raise a NO_PERMISSION exception."]; ssl_1_multi_orber_api(suite) -> []; ssl_1_multi_orber_api(_Config) -> - ServerOptions = orber_test_lib:get_options(iiop_ssl, server, + ServerOptions = orber_test_lib:get_options_old(iiop_ssl, server, 1, [{iiop_ssl_port, 0}]), - ClientOptions = orber_test_lib:get_options(iiop_ssl, client, + ClientOptions = orber_test_lib:get_options_old(iiop_ssl, client, 1, [{iiop_ssl_port, 0}]), ssl_suite(ServerOptions, ClientOptions). - -ssl_1_multi_orber_generation_3_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth 1)", + + +ssl_1_multi_orber_generation_3_api_old(doc) -> ["SECURE MULTI ORB API tests (SSL depth 1)", + "This case set up two secure orbs and test if they can", + "communicate. The case also test to access one of the", + "secure orbs which must raise a NO_PERMISSION exception."]; +ssl_1_multi_orber_generation_3_api_old(suite) -> []; +ssl_1_multi_orber_generation_3_api_old(_Config) -> + + ServerOptions = orber_test_lib:get_options_old(iiop_ssl, server, + 1, [{ssl_generation, 3}, + {iiop_ssl_port, 0}]), + ClientOptions = orber_test_lib:get_options_old(iiop_ssl, client, + 1, [{ssl_generation, 3}, + {iiop_ssl_port, 0}]), + ssl_suite(ServerOptions, ClientOptions). + + +ssl_1_multi_orber_generation_3_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth 1)", "This case set up two secure orbs and test if they can", "communicate. The case also test to access one of the", "secure orbs which must raise a NO_PERMISSION exception."]; ssl_1_multi_orber_generation_3_api(suite) -> []; ssl_1_multi_orber_generation_3_api(_Config) -> - - ServerOptions = orber_test_lib:get_options(iiop_ssl, server, + + ServerOptions = orber_test_lib:get_options(iiop_ssl, server, 1, [{ssl_generation, 3}, {iiop_ssl_port, 0}]), - ClientOptions = orber_test_lib:get_options(iiop_ssl, client, + ClientOptions = orber_test_lib:get_options(iiop_ssl, client, 1, [{ssl_generation, 3}, {iiop_ssl_port, 0}]), ssl_suite(ServerOptions, ClientOptions). - %%----------------------------------------------------------------- %% API tests for ORB to ORB, ssl security depth 2 %%----------------------------------------------------------------- -ssl_2_multi_orber_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth 2)", +ssl_2_multi_orber_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth 2)", "This case set up two secure orbs and test if they can", "communicate. The case also test to access one of the", "secure orbs which must raise a NO_PERMISSION exception."]; ssl_2_multi_orber_api(suite) -> []; -ssl_2_multi_orber_api(_Config) -> - - ServerOptions = orber_test_lib:get_options(iiop_ssl, server, +ssl_2_multi_orber_api(_Config) -> + + ServerOptions = orber_test_lib:get_options_old(iiop_ssl, server, 2, [{iiop_ssl_port, 0}]), - ClientOptions = orber_test_lib:get_options(iiop_ssl, client, + ClientOptions = orber_test_lib:get_options_old(iiop_ssl, client, 2, [{iiop_ssl_port, 0}]), ssl_suite(ServerOptions, ClientOptions). -ssl_2_multi_orber_generation_3_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth 2)", + +ssl_2_multi_orber_generation_3_api_old(doc) -> ["SECURE MULTI ORB API tests (SSL depth 2)", + "This case set up two secure orbs and test if they can", + "communicate. The case also test to access one of the", + "secure orbs which must raise a NO_PERMISSION exception."]; +ssl_2_multi_orber_generation_3_api_old(suite) -> []; +ssl_2_multi_orber_generation_3_api_old(_Config) -> + + ServerOptions = orber_test_lib:get_options_old(iiop_ssl, server, + 2, [{ssl_generation, 3}, + {iiop_ssl_port, 0}]), + ClientOptions = orber_test_lib:get_options_old(iiop_ssl, client, + 2, [{ssl_generation, 3}, + {iiop_ssl_port, 0}]), + ssl_suite(ServerOptions, ClientOptions). + + +ssl_2_multi_orber_generation_3_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth 2)", "This case set up two secure orbs and test if they can", "communicate. The case also test to access one of the", "secure orbs which must raise a NO_PERMISSION exception."]; ssl_2_multi_orber_generation_3_api(suite) -> []; -ssl_2_multi_orber_generation_3_api(_Config) -> - - ServerOptions = orber_test_lib:get_options(iiop_ssl, server, +ssl_2_multi_orber_generation_3_api(_Config) -> + + ServerOptions = orber_test_lib:get_options(iiop_ssl, server, 2, [{ssl_generation, 3}, {iiop_ssl_port, 0}]), - ClientOptions = orber_test_lib:get_options(iiop_ssl, client, + ClientOptions = orber_test_lib:get_options(iiop_ssl, client, 2, [{ssl_generation, 3}, {iiop_ssl_port, 0}]), ssl_suite(ServerOptions, ClientOptions). @@ -1656,79 +1715,135 @@ ssl_2_multi_orber_generation_3_api(_Config) -> %% API tests for ORB to ORB, ssl security depth 2 %%----------------------------------------------------------------- -ssl_reconfigure_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth 2)", +ssl_reconfigure_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth 2)", "This case set up two secure orbs and test if they can", "communicate. The case also test to access one of the", "secure orbs which must raise a NO_PERMISSION exception."]; ssl_reconfigure_api(suite) -> []; -ssl_reconfigure_api(_Config) -> - ssl_reconfigure([]). +ssl_reconfigure_api(_Config) -> + ssl_reconfigure_old([]). + -ssl_reconfigure_generation_3_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth 2)", +ssl_reconfigure_generation_3_api_old(doc) -> ["SECURE MULTI ORB API tests (SSL depth 2)", + "This case set up two secure orbs and test if they can", + "communicate. The case also test to access one of the", + "secure orbs which must raise a NO_PERMISSION exception."]; +ssl_reconfigure_generation_3_api_old(suite) -> []; +ssl_reconfigure_generation_3_api_old(_Config) -> + ssl_reconfigure_old([{ssl_generation, 3}]). + +ssl_reconfigure_old(ExtraSSLOptions) -> + + IP = orber_test_lib:get_host(), + Loopback = orber_test_lib:get_loopback_interface(), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, + orber_test_lib:js_node([{iiop_port, 0}, + {flags, ?ORB_ENV_LOCAL_INTERFACE}, + {ip_address, IP}|ExtraSSLOptions])), + orber_test_lib:remote_apply(ServerNode, ssl, start, []), + orber_test_lib:remote_apply(ServerNode, crypto, start, []), + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, + [ssl])), + ?match({ok, _}, + orber_test_lib:remote_apply(ServerNode, orber, + add_listen_interface, + [Loopback, normal, [{iiop_port, 5648}, + {iiop_ssl_port, 5649}, + {interceptors, {native, [orber_iiop_tracer_silent]}}|ExtraSSLOptions]])), + ServerOptions = orber_test_lib:get_options_old(iiop_ssl, server, + 2, [{flags, ?ORB_ENV_LOCAL_INTERFACE}, + {iiop_port, 5648}, + {iiop_ssl_port, 5649}, + {interceptors, {native, [orber_iiop_tracer_silent]}}|ExtraSSLOptions]), + ?match({ok, _}, + orber_test_lib:remote_apply(ServerNode, orber, + add_listen_interface, + [Loopback, ssl, ServerOptions])), + + ClientOptions = orber_test_lib:get_options_old(iiop_ssl, client, + 2, [{iiop_ssl_port, 0}|ExtraSSLOptions]), + {ok, ClientNode, _ClientHost} = + ?match({ok,_,_}, orber_test_lib:js_node(ClientOptions)), + + ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib, + install_test_data, + [ssl])), + orber_test_lib:remote_apply(ClientNode, ssl, start, []), + orber_test_lib:remote_apply(ServerNode, crypto, start, []), + Obj = ?match(#'IOP_IOR'{}, + orber_test_lib:remote_apply(ClientNode, corba, + string_to_object, ["corbaname:iiop:1.1@"++Loopback++":5648/NameService#mamba", + [{context, [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, + context_data = {configuration, ClientOptions}}]}]])), + ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_server, + print, [Obj])). + + +ssl_reconfigure_generation_3_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth 2)", "This case set up two secure orbs and test if they can", "communicate. The case also test to access one of the", "secure orbs which must raise a NO_PERMISSION exception."]; ssl_reconfigure_generation_3_api(suite) -> []; -ssl_reconfigure_generation_3_api(_Config) -> +ssl_reconfigure_generation_3_api(_Config) -> ssl_reconfigure([{ssl_generation, 3}]). + ssl_reconfigure(ExtraSSLOptions) -> IP = orber_test_lib:get_host(), Loopback = orber_test_lib:get_loopback_interface(), - {ok, ServerNode, _ServerHost} = - ?match({ok,_,_}, - orber_test_lib:js_node([{iiop_port, 0}, - {flags, ?ORB_ENV_LOCAL_INTERFACE}, + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, + orber_test_lib:js_node([{iiop_port, 0}, + {flags, ?ORB_ENV_LOCAL_INTERFACE}, {ip_address, IP}|ExtraSSLOptions])), orber_test_lib:remote_apply(ServerNode, ssl, start, []), orber_test_lib:remote_apply(ServerNode, crypto, start, []), - orber_test_lib:remote_apply(ServerNode, ssl, seed, ["testing"]), - ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, - install_test_data, + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, [ssl])), - ?match({ok, _}, - orber_test_lib:remote_apply(ServerNode, orber, - add_listen_interface, + ?match({ok, _}, + orber_test_lib:remote_apply(ServerNode, orber, + add_listen_interface, [Loopback, normal, [{iiop_port, 5648}, {iiop_ssl_port, 5649}, {interceptors, {native, [orber_iiop_tracer_silent]}}|ExtraSSLOptions]])), - ServerOptions = orber_test_lib:get_options(iiop_ssl, server, - 2, [{flags, ?ORB_ENV_LOCAL_INTERFACE}, + ServerOptions = orber_test_lib:get_options(iiop_ssl, server, + 2, [{flags, ?ORB_ENV_LOCAL_INTERFACE}, {iiop_port, 5648}, {iiop_ssl_port, 5649}, {interceptors, {native, [orber_iiop_tracer_silent]}}|ExtraSSLOptions]), - ?match({ok, _}, - orber_test_lib:remote_apply(ServerNode, orber, - add_listen_interface, + ?match({ok, _}, + orber_test_lib:remote_apply(ServerNode, orber, + add_listen_interface, [Loopback, ssl, ServerOptions])), - ClientOptions = orber_test_lib:get_options(iiop_ssl, client, + ClientOptions = orber_test_lib:get_options(iiop_ssl, client, 2, [{iiop_ssl_port, 0}|ExtraSSLOptions]), - {ok, ClientNode, _ClientHost} = + {ok, ClientNode, _ClientHost} = ?match({ok,_,_}, orber_test_lib:js_node(ClientOptions)), - ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib, - install_test_data, + ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib, + install_test_data, [ssl])), orber_test_lib:remote_apply(ClientNode, ssl, start, []), orber_test_lib:remote_apply(ServerNode, crypto, start, []), - orber_test_lib:remote_apply(ClientNode, ssl, seed, ["testing"]), - Obj = ?match(#'IOP_IOR'{}, + Obj = ?match(#'IOP_IOR'{}, orber_test_lib:remote_apply(ClientNode, corba, string_to_object, ["corbaname:iiop:1.1@"++Loopback++":5648/NameService#mamba", - [{context, [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, + [{context, [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, context_data = {configuration, ClientOptions}}]}]])), - ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_server, + ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_server, print, [Obj])). - %%----------------------------------------------------------------- %% API tests for Orber to Java ORB, no security %%----------------------------------------------------------------- -%orber_java_api(doc) -> ["ERLANG-ORB <-> JAVA-ORB API tests", +%orber_java_api(doc) -> ["ERLANG-ORB <-> JAVA-ORB API tests", % "This case test if data encode/decode (IIOP)", % "produce the correct result, i.e., the test_server echos", % "the input parameter or an exception is raised (MARSHAL)."]; @@ -1741,38 +1856,38 @@ ssl_reconfigure(ExtraSSLOptions) -> %% Arguments: Config %% Depth %% Returns : ok -%% Effect : +%% Effect : %%------------------------------------------------------------ ssl_suite(ServerOptions, ClientOptions) -> - {ok, ServerNode, ServerHost} = + {ok, ServerNode, ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node(ServerOptions)), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), SSLServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_ssl_port, []), - {ok, ClientNode, _ClientHost} = + {ok, ClientNode, _ClientHost} = ?match({ok,_,_}, orber_test_lib:js_node(ClientOptions)), - - ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, - install_test_data, + + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, [ssl])), %% Tell the client to interoperate with the server. The purpose of this %% operation is to look up, using NameService, an object reference and %% use it to contact the object. - ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib, + ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib, lookup, [ServerHost, ServerPort])), - - ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib, + + ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib, alternate_ssl_iiop_address, [ServerHost, ServerPort, SSLServerPort])), - + %% 'This' node is not secure. Contact the server. Must refuse connection. NSR = ?match({'IOP_IOR',"IDL:omg.org/CosNaming/NamingContextExt:1.0",_}, corba:string_to_object("corbaloc::1.2@"++ServerHost++":"++ integer_to_list(ServerPort)++"/NameService")), - + %% Should be 'NO_PERMISSION'?? ?match({'EXCEPTION',{'COMM_FAILURE',_,_,_}}, 'CosNaming_NamingContext':resolve(NSR, lname:new(["not_exist"]))), @@ -1782,8 +1897,8 @@ ssl_suite(ServerOptions, ClientOptions) -> 'CosNaming_NamingContext':resolve(NSR, lname:new(["mamba"]))), %% Uninstall. - ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, - uninstall_test_data, + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + uninstall_test_data, [ssl])), ok. @@ -1795,7 +1910,7 @@ setup_connection_timeout_api(suite) -> []; setup_connection_timeout_api(_Config) -> ?match(ok, application:set_env(orber, iiop_backlog, 0)), %% Wait to be sure that the configuration has kicked in. - timer:sleep(2000), + timer:sleep(2000), {ok, Ref, Port} = create_fake_server_ORB(normal, 0, [], listen, []), ?match(ok, orber:configure(iiop_setup_connection_timeout, 5)), ?match(ok, orber:info(io)), @@ -1815,7 +1930,7 @@ setup_connection_timeout_api(_Config) -> %%----------------------------------------------------------------- %% iiop_setup_connection_timeout API tests for ORB to ORB. %%----------------------------------------------------------------- -setup_multi_connection_timeout_api(doc) -> +setup_multi_connection_timeout_api(doc) -> ["iiop_multi_setup_connection_timeout API tests for ORB to ORB."]; setup_multi_connection_timeout_api(suite) -> []; setup_multi_connection_timeout_api(_Config) -> @@ -1840,7 +1955,7 @@ setup_multi_connection_timeout_api(_Config) -> ?match(ok, application:set_env(orber, iiop_out_ports, undefined)), ok. -setup_multi_connection_timeout_attempts_api(doc) -> +setup_multi_connection_timeout_attempts_api(doc) -> ["iiop_multi_setup_connection_timeout API tests for ORB to ORB."]; setup_multi_connection_timeout_attempts_api(suite) -> []; setup_multi_connection_timeout_attempts_api(_Config) -> @@ -1866,7 +1981,7 @@ setup_multi_connection_timeout_attempts_api(_Config) -> ?match(ok, application:set_env(orber, iiop_out_ports, undefined)), ok. -setup_multi_connection_timeout_random_api(doc) -> +setup_multi_connection_timeout_random_api(doc) -> ["iiop_multi_setup_connection_timeout API tests for ORB to ORB."]; setup_multi_connection_timeout_random_api(suite) -> []; setup_multi_connection_timeout_random_api(_Config) -> @@ -1901,17 +2016,17 @@ bad_giop_header_api(_Config) -> orber:configure_override(interceptors, {native,[orber_iiop_tracer]}), orber:configure(orber_debug_level, 10), ?match(ok, orber:info(io)), - {ok, ServerNode, ServerHost} = + {ok, ServerNode, ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node()), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), Req = <<"GIOP",1,2,0,100,0,0,0,5,0,0,0,10,50>> , - ?match(ok, fake_client_ORB(normal, ServerHost, ServerPort, [], + ?match(ok, fake_client_ORB(normal, ServerHost, ServerPort, [], message_error, [Req])), - + application:set_env(orber, interceptors, false), orber:configure(orber_debug_level, 0), ok. - + %%----------------------------------------------------------------- %% Fragmented IIOP tests (Server-side). @@ -1929,34 +2044,34 @@ fragments_server_api(doc) -> ["fragments API tests for server-side ORB."]; fragments_server_api(suite) -> []; fragments_server_api(_Config) -> %% --- Create a slave-node --- - {ok, Node, Host} = - ?match({ok,_,_}, orber_test_lib:js_node()), + {ok, Node, Host} = + ?match({ok,_,_}, orber_test_lib:js_node()), Port = orber_test_lib:remote_apply(Node, orber, iiop_port, []), - - ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, - install_test_data, + + ?match(ok, orber_test_lib:remote_apply(Node, orber_test_lib, + install_test_data, [nameservice])), - + NSR = ?match({'IOP_IOR',"IDL:omg.org/CosNaming/NamingContextExt:1.0",_}, corba:string_to_object("corbaloc::1.2@"++Host++":"++ integer_to_list(Port)++"/NameService")), - - Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + + Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, 'CosNaming_NamingContext':resolve(NSR, lname:new(["mamba"]))), Any = #any{typecode = {tk_string,0}, value = "123"}, - Target = #'GIOP_TargetAddress'{label = ?GIOP_KeyAddr, + Target = #'GIOP_TargetAddress'{label = ?GIOP_KeyAddr, value = iop_ior:get_objkey(Obj)}, - %% Fix a request header. + %% Fix a request header. {Hdr, Body, HdrLen, _What, _Flags} = cdr_encode:enc_request_split( - #giop_env{version = {1,2}, objkey = Target, + #giop_env{version = {1,2}, objkey = Target, request_id = ?REQUEST_ID, - response_expected = true, - op = testing_iiop_any, - parameters = [49], ctx = [], - tc = {tk_void,[tk_char],[]}, + response_expected = true, + op = testing_iiop_any, + parameters = [49], ctx = [], + tc = {tk_void,[tk_char],[]}, host = [orber_test_lib:get_host()], iiop_port = orber:iiop_port(), iiop_ssl_port = orber:iiop_ssl_port(), @@ -1971,11 +2086,11 @@ fragments_server_api(_Config) -> <<AligmnetData:Aligned/binary,49>> = Body, list_to_binary([AligmnetData, <<0,0,0,18,0,0,0,0,0,0,0,4,49>> ]) end, - + MessSize = HdrLen+size(NewBody), ReqFrag = list_to_binary([ <<"GIOP",1:8,2:8,2:8,0:8, MessSize:32/big-unsigned-integer>> , Hdr |NewBody]), - ?match(Any, fake_client_ORB(normal, Host, Port, [], fragments, + ?match(Any, fake_client_ORB(normal, Host, Port, [], fragments, [ReqFrag, ?FRAG_2, ?FRAG_3, ?FRAG_4])), ok. @@ -1988,9 +2103,9 @@ fragments_max_server_api(suite) -> []; fragments_max_server_api(_Config) -> %% --- Create a slave-node --- IP = orber_test_lib:get_host(), - {ok, ServerNode, _ServerHost} = + {ok, ServerNode, _ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node([{iiop_max_fragments, 2}, - {ip_address, IP}])), + {ip_address, IP}])), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), fragments_max_server(ServerNode, IP, ServerPort). @@ -1999,37 +2114,37 @@ fragments_max_server_added_api(suite) -> []; fragments_max_server_added_api(_Config) -> %% --- Create a slave-node --- IP = orber_test_lib:get_host(), - {ok, ServerNode, _ServerHost} = - ?match({ok,_,_}, orber_test_lib:js_node([])), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([])), ServerPort = 1 + orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), ?match({ok, _}, - orber_test_lib:remote_apply(ServerNode, orber, - add_listen_interface, - [IP, normal, + orber_test_lib:remote_apply(ServerNode, orber, + add_listen_interface, + [IP, normal, [{iiop_max_fragments, 2}, {flags, ?ORB_ENV_LOCAL_INTERFACE}, {iiop_port, ServerPort}]])), fragments_max_server(ServerNode, IP, ServerPort). fragments_max_server(ServerNode, ServerHost, ServerPort) -> - ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, - install_test_data, + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, [nameservice])), Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, corba:string_to_object("corbaname::1.2@"++ServerHost++":"++ integer_to_list(ServerPort)++"/NameService#mamba")), - Target = #'GIOP_TargetAddress'{label = ?GIOP_KeyAddr, + Target = #'GIOP_TargetAddress'{label = ?GIOP_KeyAddr, value = iop_ior:get_objkey(Obj)}, - %% Fix a request header. + %% Fix a request header. {Hdr, Body, HdrLen, _What, _Flags} = cdr_encode:enc_request_split( - #giop_env{version = {1,2}, - objkey = Target, - request_id = ?REQUEST_ID, - response_expected = true, - op = testing_iiop_any, - parameters = [49], ctx = [], - tc = {tk_void,[tk_char],[]}, + #giop_env{version = {1,2}, + objkey = Target, + request_id = ?REQUEST_ID, + response_expected = true, + op = testing_iiop_any, + parameters = [49], ctx = [], + tc = {tk_void,[tk_char],[]}, host = [orber_test_lib:get_host()], iiop_port = orber:iiop_port(), iiop_ssl_port = orber:iiop_ssl_port(), @@ -2048,8 +2163,8 @@ fragments_max_server(ServerNode, ServerHost, ServerPort) -> MessSize = HdrLen+size(NewBody), ReqFrag = list_to_binary([ <<"GIOP",1:8,2:8,2:8,0:8, MessSize:32/big-unsigned-integer>> , Hdr |NewBody]), - ?match(#'IMP_LIMIT'{}, - fake_client_ORB(normal, ServerHost, ServerPort, [], fragments_max, + ?match(#'IMP_LIMIT'{}, + fake_client_ORB(normal, ServerHost, ServerPort, [], fragments_max, [ReqFrag, ?FRAG_2, ?FRAG_3, ?FRAG_4])), ok. @@ -2065,11 +2180,11 @@ fragments_client_api(_Config) -> application:set_env(orber, interceptors, {native,[orber_iiop_tracer]}), orber:configure(orber_debug_level, 10), orber:info(), - IOR = ?match({'IOP_IOR',_,_}, - iop_ior:create_external({1, 2}, "IDL:FAKE:1.0", + IOR = ?match({'IOP_IOR',_,_}, + iop_ior:create_external({1, 2}, "IDL:FAKE:1.0", "localhost", 6004, "FAKE", [])), - spawn(?MODULE, create_fake_server_ORB, [normal, 6004, [], fragments, - [?REPLY_FRAG_1, ?FRAG_2, + spawn(?MODULE, create_fake_server_ORB, [normal, 6004, [], fragments, + [?REPLY_FRAG_1, ?FRAG_2, ?FRAG_3, ?FRAG_4]]), ?match({ok, Any}, orber_test_server:testing_iiop_any(IOR, Any)), application:set_env(orber, interceptors, false), @@ -2085,16 +2200,16 @@ bad_fragment_id_client_api(_Config) -> application:set_env(orber, interceptors, {native,[orber_iiop_tracer]}), orber:configure(orber_debug_level, 10), orber:info(), - {ok, ServerNode, ServerHost} = + {ok, ServerNode, ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node()), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), Req = <<71,73,79,80,1,2,2,7,0,0,0,5,0,0,0,100,50>> , - ?match(ok, fake_client_ORB(normal, ServerHost, ServerPort, [], + ?match(ok, fake_client_ORB(normal, ServerHost, ServerPort, [], message_error, [Req])), - + application:set_env(orber, interceptors, false), orber:configure(orber_debug_level, 0), - + ok. %%----------------------------------------------------------------- @@ -2102,22 +2217,22 @@ bad_fragment_id_client_api(_Config) -> %%----------------------------------------------------------------- bad_id_cancel_request_api(doc) -> ["Description", "more description"]; bad_id_cancel_request_api(suite) -> []; -bad_id_cancel_request_api(Config) when is_list(Config) -> - Req10 = cdr_encode:enc_cancel_request(#giop_env{version = {1, 0}, +bad_id_cancel_request_api(Config) when is_list(Config) -> + Req10 = cdr_encode:enc_cancel_request(#giop_env{version = {1, 0}, request_id = 556}), - Req11 = cdr_encode:enc_cancel_request(#giop_env{version = {1, 1}, + Req11 = cdr_encode:enc_cancel_request(#giop_env{version = {1, 1}, request_id = 556}), - Req12 = cdr_encode:enc_cancel_request(#giop_env{version = {1, 2}, + Req12 = cdr_encode:enc_cancel_request(#giop_env{version = {1, 2}, request_id = 556}), - {ok, ServerNode, ServerHost} = + {ok, ServerNode, ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node()), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), - ?match(ok, fake_client_ORB(normal, ServerHost, ServerPort, [], - message_error, [Req10])), - ?match(ok, fake_client_ORB(normal, ServerHost, ServerPort, [], - message_error, [Req11])), - ?match(ok, fake_client_ORB(normal, ServerHost, ServerPort, [], - message_error, [Req12])), + ?match(ok, fake_client_ORB(normal, ServerHost, ServerPort, [], + message_error, [Req10])), + ?match(ok, fake_client_ORB(normal, ServerHost, ServerPort, [], + message_error, [Req11])), + ?match(ok, fake_client_ORB(normal, ServerHost, ServerPort, [], + message_error, [Req12])), ok. %%----------------------------------------------------------------- @@ -2133,141 +2248,141 @@ pseudo_calls(0, _) -> pseudo_calls(Times, Obj) -> orber_test_server:pseudo_call(Obj), New = Times - 1, - pseudo_calls(New, Obj). + pseudo_calls(New, Obj). pseudo_casts(0, _) -> ok; pseudo_casts(Times, Obj) -> orber_test_server:pseudo_cast(Obj), New = Times - 1, - pseudo_casts(New, Obj). + pseudo_casts(New, Obj). context_test(Obj) -> - CodeSetCtx = #'CONV_FRAME_CodeSetContext'{char_data = 65537, + CodeSetCtx = #'CONV_FRAME_CodeSetContext'{char_data = 65537, wchar_data = 65801}, FTGrp = #'FT_FTGroupVersionServiceContext'{object_group_ref_version = ?ULONGMAX}, - FTReq = #'FT_FTRequestServiceContext'{client_id = "ClientId", - retention_id = ?LONGMAX, + FTReq = #'FT_FTRequestServiceContext'{client_id = "ClientId", + retention_id = ?LONGMAX, expiration_time = ?ULONGLONGMAX}, - IDToken1 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTAbsent, + IDToken1 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTAbsent, value = true}, - IDToken2 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTAnonymous, + IDToken2 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTAnonymous, value = false}, - IDToken3 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTPrincipalName, + IDToken3 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTPrincipalName, value = [0,255]}, - IDToken4 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTX509CertChain, + IDToken4 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTX509CertChain, value = [1,255]}, - IDToken5 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTDistinguishedName, + IDToken5 = #'CSI_IdentityToken'{label = ?CSI_IdentityTokenType_ITTDistinguishedName, value = [2,255]}, - IDToken6 = #'CSI_IdentityToken'{label = ?ULONGMAX, + IDToken6 = #'CSI_IdentityToken'{label = ?ULONGMAX, value = [3,255]}, MTEstablishContext1 = #'CSI_SASContextBody' - {label = ?CSI_MsgType_MTEstablishContext, - value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, - authorization_token = + {label = ?CSI_MsgType_MTEstablishContext, + value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, + authorization_token = [#'CSI_AuthorizationElement' - {the_type = ?ULONGMAX, - the_element = [0,255]}], - identity_token = IDToken1, + {the_type = ?ULONGMAX, + the_element = [0,255]}], + identity_token = IDToken1, client_authentication_token = [1, 255]}}, MTEstablishContext2 = #'CSI_SASContextBody' - {label = ?CSI_MsgType_MTEstablishContext, - value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, - authorization_token = + {label = ?CSI_MsgType_MTEstablishContext, + value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, + authorization_token = [#'CSI_AuthorizationElement' - {the_type = ?ULONGMAX, - the_element = [0,255]}], - identity_token = IDToken2, + {the_type = ?ULONGMAX, + the_element = [0,255]}], + identity_token = IDToken2, client_authentication_token = [1, 255]}}, MTEstablishContext3 = #'CSI_SASContextBody' - {label = ?CSI_MsgType_MTEstablishContext, - value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, - authorization_token = + {label = ?CSI_MsgType_MTEstablishContext, + value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, + authorization_token = [#'CSI_AuthorizationElement' - {the_type = ?ULONGMAX, - the_element = [0,255]}], - identity_token = IDToken3, + {the_type = ?ULONGMAX, + the_element = [0,255]}], + identity_token = IDToken3, client_authentication_token = [1, 255]}}, MTEstablishContext4 = #'CSI_SASContextBody' - {label = ?CSI_MsgType_MTEstablishContext, - value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, - authorization_token = + {label = ?CSI_MsgType_MTEstablishContext, + value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, + authorization_token = [#'CSI_AuthorizationElement' - {the_type = ?ULONGMAX, - the_element = [0,255]}], - identity_token = IDToken4, + {the_type = ?ULONGMAX, + the_element = [0,255]}], + identity_token = IDToken4, client_authentication_token = [1, 255]}}, MTEstablishContext5 = #'CSI_SASContextBody' - {label = ?CSI_MsgType_MTEstablishContext, - value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, - authorization_token = + {label = ?CSI_MsgType_MTEstablishContext, + value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, + authorization_token = [#'CSI_AuthorizationElement' - {the_type = ?ULONGMAX, - the_element = [0,255]}], - identity_token = IDToken5, + {the_type = ?ULONGMAX, + the_element = [0,255]}], + identity_token = IDToken5, client_authentication_token = [1, 255]}}, MTEstablishContext6 = #'CSI_SASContextBody' - {label = ?CSI_MsgType_MTEstablishContext, - value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, - authorization_token = + {label = ?CSI_MsgType_MTEstablishContext, + value = #'CSI_EstablishContext'{client_context_id = ?ULONGLONGMAX, + authorization_token = [#'CSI_AuthorizationElement' - {the_type = ?ULONGMAX, - the_element = [0,255]}], - identity_token = IDToken6, + {the_type = ?ULONGMAX, + the_element = [0,255]}], + identity_token = IDToken6, client_authentication_token = [1, 255]}}, MTCompleteEstablishContext = #'CSI_SASContextBody' - {label = ?CSI_MsgType_MTCompleteEstablishContext, - value = #'CSI_CompleteEstablishContext'{client_context_id = ?ULONGLONGMAX, + {label = ?CSI_MsgType_MTCompleteEstablishContext, + value = #'CSI_CompleteEstablishContext'{client_context_id = ?ULONGLONGMAX, context_stateful = false, final_context_token = [1, 255]}}, MTContextError = #'CSI_SASContextBody' - {label = ?CSI_MsgType_MTContextError, + {label = ?CSI_MsgType_MTContextError, value = #'CSI_ContextError'{client_context_id = ?ULONGLONGMAX, - major_status = 1, - minor_status = 2, + major_status = 1, + minor_status = 2, error_token = [2,255]}}, MTMessageInContext = #'CSI_SASContextBody' - {label = ?CSI_MsgType_MTMessageInContext, - value = #'CSI_MessageInContext'{client_context_id = ?ULONGLONGMAX, + {label = ?CSI_MsgType_MTMessageInContext, + value = #'CSI_MessageInContext'{client_context_id = ?ULONGLONGMAX, discard_context = true}}, - Ctx = [#'IOP_ServiceContext'{context_id=?IOP_CodeSets, + Ctx = [#'IOP_ServiceContext'{context_id=?IOP_CodeSets, context_data = CodeSetCtx}, - #'IOP_ServiceContext'{context_id=?IOP_FT_GROUP_VERSION, + #'IOP_ServiceContext'{context_id=?IOP_FT_GROUP_VERSION, context_data = FTGrp}, - #'IOP_ServiceContext'{context_id=?IOP_FT_REQUEST, + #'IOP_ServiceContext'{context_id=?IOP_FT_REQUEST, context_data = FTReq}, - #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, context_data = MTEstablishContext1}, - #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, context_data = MTEstablishContext2}, - #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, context_data = MTEstablishContext3}, - #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, context_data = MTEstablishContext4}, - #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, context_data = MTEstablishContext5}, - #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, context_data = MTEstablishContext6}, - #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, context_data = MTCompleteEstablishContext}, - #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, context_data = MTContextError}, - #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, + #'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, context_data = MTMessageInContext}, - #'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, + #'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, context_data = {any_kind_of_data, {127,0,0,1}, 4001}}], ?match(ok, orber_test_server:testing_iiop_context(Obj, [{context, Ctx}])). create_fake_server_ORB(Type, Port, Options, listen, _Data) -> {ok, _ListenSocket, NewPort} = - orber_socket:listen(Type, Port, + orber_socket:listen(Type, Port, [{backlog, 0}, {active, false}|Options]), Socket = orber_socket:connect(Type, 'localhost', NewPort, [{active, false}|Options]), {ok, {Type, Socket}, NewPort}; create_fake_server_ORB(Type, Port, Options, Action, Data) -> - {ok, ListenSocket, _NewPort} = + {ok, ListenSocket, _NewPort} = orber_socket:listen(Type, Port, [{active, false}|Options]), Socket = orber_socket:accept(Type, ListenSocket), do_server_action(Type, Socket, Action, Data), @@ -2301,14 +2416,14 @@ do_client_action(Type, Socket, fragments, FragList) -> ok = send_data(Type, Socket, FragList), timer:sleep(3000), {ok, Bytes} = gen_tcp:recv(Socket, 0), - {#reply_header{request_id = ?REQUEST_ID, reply_status = no_exception}, ok, [Par]} = + {#reply_header{request_id = ?REQUEST_ID, reply_status = no_exception}, ok, [Par]} = cdr_decode:dec_message({tk_void,[tk_any],[tk_any]}, Bytes), Par; do_client_action(Type, Socket, fragments_max, FragList) -> ok = send_data(Type, Socket, FragList), timer:sleep(3000), {ok, Bytes} = gen_tcp:recv(Socket, 0), - {#reply_header{request_id = ?REQUEST_ID, reply_status = system_exception}, Exc, []} = + {#reply_header{request_id = ?REQUEST_ID, reply_status = system_exception}, Exc, []} = cdr_decode:dec_message({tk_void,[tk_any],[tk_any]}, Bytes), Exc; do_client_action(Type, Socket, message_error, Data) -> @@ -2325,4 +2440,4 @@ send_data(_Type, _Socket, []) -> send_data(Type, Socket, [H|T]) -> orber_socket:write(Type, Socket, H), send_data(Type, Socket, T). - + diff --git a/lib/orber/test/orber_nat_SUITE.erl b/lib/orber/test/orber_nat_SUITE.erl index 625f168520..ee31b162c2 100644 --- a/lib/orber/test/orber_nat_SUITE.erl +++ b/lib/orber/test/orber_nat_SUITE.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% +%% %% Copyright Ericsson AB 2006-2011. All Rights Reserved. -%% +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% @@ -50,14 +50,15 @@ %%----------------------------------------------------------------- %% External exports %%----------------------------------------------------------------- --export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2, cases/0, +-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2, cases/0, init_per_suite/1, end_per_suite/1, - init_per_testcase/2, end_per_testcase/2, + init_per_testcase/2, end_per_testcase/2, nat_ip_address/1, nat_ip_address_multiple/1, nat_ip_address_local/1, nat_ip_address_local_local/1, nat_iiop_port/1, nat_iiop_port_local/1, - nat_iiop_port_local_local/1, nat_iiop_ssl_port/1, - nat_iiop_ssl_port_local/1]). + nat_iiop_port_local_local/1, + nat_iiop_ssl_port_old/1, nat_iiop_ssl_port_local_old/1, + nat_iiop_ssl_port/1, nat_iiop_ssl_port_local/1]). %%----------------------------------------------------------------- @@ -66,15 +67,15 @@ %%----------------------------------------------------------------- %% Func: all/1 -%% Args: -%% Returns: +%% Args: +%% Returns: %%----------------------------------------------------------------- suite() -> [{ct_hooks,[ts_install_cth]}]. -all() -> +all() -> cases(). -groups() -> +groups() -> []. init_per_group(_GroupName, Config) -> @@ -84,25 +85,38 @@ end_per_group(_GroupName, Config) -> Config. -cases() -> - [nat_ip_address, nat_ip_address_multiple, - nat_ip_address_local, nat_iiop_port, - nat_iiop_port_local, nat_ip_address_local_local, - nat_iiop_port_local_local, nat_iiop_ssl_port, +cases() -> + [nat_ip_address, + nat_ip_address_multiple, + nat_ip_address_local, + nat_iiop_port, + nat_iiop_port_local, + nat_ip_address_local_local, + nat_iiop_port_local_local, + nat_iiop_ssl_port_old, + nat_iiop_ssl_port_local_old, + nat_iiop_ssl_port, nat_iiop_ssl_port_local]. %%----------------------------------------------------------------- %% Init and cleanup functions. %%----------------------------------------------------------------- -init_per_testcase(TC, Config) +init_per_testcase(TC, Config) when TC =:= nat_iiop_ssl_port; - TC =:= nat_iiop_ssl_port_local -> - case orber_test_lib:ssl_version() of - no_ssl -> - {skip,"SSL not installed!"}; - _ -> - init_per_testcase(dummy_tc, Config) - end; + TC =:= nat_iiop_ssl_port_local; + TC =:= nat_iiop_ssl_port_old; + TC =:= nat_iiop_ssl_port_local_old -> + case ?config(crypto_started, Config) of + true -> + case orber_test_lib:ssl_version() of + no_ssl -> + {skip,"SSL not installed!"}; + _ -> + init_per_testcase(dummy_tc, Config) + end; + false -> + {skip, "Crypto did not start"} + end; init_per_testcase(_Case, Config) -> Path = code:which(?MODULE), code:add_pathz(filename:join(filename:dirname(Path), "idl_output")), @@ -125,12 +139,18 @@ end_per_testcase(_Case, Config) -> init_per_suite(Config) -> if is_list(Config) -> - Config; + try crypto:start() of + ok -> + [{crypto_started, true} | Config] + catch _:_ -> + [{crypto_started, false} | Config] + end; true -> exit("Config not a list") end. end_per_suite(Config) -> + application:stop(crypto), Config. %%----------------------------------------------------------------- @@ -143,13 +163,13 @@ nat_ip_address(suite) -> []; nat_ip_address(_Config) -> IP = orber_test_lib:get_host(), Loopback = orber_test_lib:get_loopback_interface(), - {ok, ServerNode, _ServerHost} = + {ok, ServerNode, _ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_ENABLE_NAT}, {nat_ip_address, Loopback}])), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), IOR = ?match(#'IOP_IOR'{}, corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")), - ?match({'external', {Loopback, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, + ?match({'external', {Loopback, ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, iop_ior:get_key(IOR)), ok. @@ -158,14 +178,14 @@ nat_ip_address_multiple(doc) -> ["This case test if the server ORB use the corre nat_ip_address_multiple(suite) -> []; nat_ip_address_multiple(_Config) -> IP = orber_test_lib:get_host(), - - {ok, ServerNode, _ServerHost} = + + {ok, ServerNode, _ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_ENABLE_NAT}, {nat_ip_address, {multiple, ["10.0.0.1"]}}])), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), IOR = ?match(#'IOP_IOR'{}, corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")), - ?match({'external', {"10.0.0.1", ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, + ?match({'external', {"10.0.0.1", ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, iop_ior:get_key(IOR)), ok. @@ -174,13 +194,13 @@ nat_ip_address_local(doc) -> ["This case test if the server ORB use the correct" nat_ip_address_local(suite) -> []; nat_ip_address_local(_Config) -> IP = orber_test_lib:get_host(), - {ok, ServerNode, _ServerHost} = + {ok, ServerNode, _ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_ENABLE_NAT}, {nat_ip_address, {local, "10.0.0.1", [{IP, "127.0.0.1"}]}}])), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), IOR = ?match(#'IOP_IOR'{}, corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")), - ?match({'external', {"10.0.0.1", ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, + ?match({'external', {"10.0.0.1", ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, iop_ior:get_key(IOR)), ok. @@ -190,19 +210,19 @@ nat_ip_address_local_local(suite) -> []; nat_ip_address_local_local(_Config) -> IP = orber_test_lib:get_host(), Loopback = orber_test_lib:get_loopback_interface(), - {ok, ServerNode, _ServerHost} = - ?match({ok,_,_}, orber_test_lib:js_node([{flags, - (?ORB_ENV_LOCAL_INTERFACE bor + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, + (?ORB_ENV_LOCAL_INTERFACE bor ?ORB_ENV_ENABLE_NAT)}, {nat_ip_address, {local, "10.0.0.1", [{IP, "10.0.0.2"}]}}])), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), IOR1 = ?match(#'IOP_IOR'{}, corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")), - ?match({'external', {"10.0.0.2", ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, + ?match({'external', {"10.0.0.2", ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, iop_ior:get_key(IOR1)), IOR2 = ?match(#'IOP_IOR'{}, corba:string_to_object("corbaloc::1.2@"++Loopback++":"++integer_to_list(ServerPort)++"/NameService")), - ?match({'external', {"10.0.0.1", ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, + ?match({'external', {"10.0.0.1", ServerPort, _ObjectKey, _Counter, _TP, _NewHD}}, iop_ior:get_key(IOR2)), ok. @@ -211,13 +231,13 @@ nat_iiop_port(doc) -> ["This case test if the server ORB use the correct", nat_iiop_port(suite) -> []; nat_iiop_port(_Config) -> IP = orber_test_lib:get_host(), - {ok, ServerNode, _ServerHost} = + {ok, ServerNode, _ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_ENABLE_NAT}, {nat_iiop_port, 42}])), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), IOR = ?match(#'IOP_IOR'{}, corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")), - ?match({'external', {_IP, 42, _ObjectKey, _Counter, _TP, _NewHD}}, + ?match({'external', {_IP, 42, _ObjectKey, _Counter, _TP, _NewHD}}, iop_ior:get_key(IOR)), ok. @@ -226,13 +246,13 @@ nat_iiop_port_local(doc) -> ["This case test if the server ORB use the correct", nat_iiop_port_local(suite) -> []; nat_iiop_port_local(_Config) -> IP = orber_test_lib:get_host(), - {ok, ServerNode, _ServerHost} = + {ok, ServerNode, _ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node([{flags, ?ORB_ENV_ENABLE_NAT}, {nat_iiop_port, {local, 42, [{4001, 43}]}}])), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), IOR = ?match(#'IOP_IOR'{}, corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")), - ?match({'external', {_IP, 42, _ObjectKey, _Counter, _TP, _NewHD}}, + ?match({'external', {_IP, 42, _ObjectKey, _Counter, _TP, _NewHD}}, iop_ior:get_key(IOR)), ok. @@ -242,27 +262,27 @@ nat_iiop_port_local_local(suite) -> []; nat_iiop_port_local_local(_Config) -> IP = orber_test_lib:get_host(), Loopback = orber_test_lib:get_loopback_interface(), - {ok, ServerNode, _ServerHost} = - ?match({ok,_,_}, orber_test_lib:js_node([{flags, - (?ORB_ENV_LOCAL_INTERFACE bor + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node([{flags, + (?ORB_ENV_LOCAL_INTERFACE bor ?ORB_ENV_ENABLE_NAT)}, {ip_address, IP}])), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), orber_test_lib:remote_apply(ServerNode, orber_env, configure_override, [nat_iiop_port, {local, 42, [{ServerPort, 43}]}]), IOR1 = ?match(#'IOP_IOR'{}, corba:string_to_object("corbaloc::1.2@"++IP++":"++integer_to_list(ServerPort)++"/NameService")), - ?match({'external', {IP, 43, _ObjectKey, _Counter, _TP, _NewHD}}, + ?match({'external', {IP, 43, _ObjectKey, _Counter, _TP, _NewHD}}, iop_ior:get_key(IOR1)), {ok, Ref} = ?match({ok, _}, - orber_test_lib:remote_apply(ServerNode, orber, - add_listen_interface, + orber_test_lib:remote_apply(ServerNode, orber, + add_listen_interface, [Loopback, normal, 10088])), IOR2 = ?match(#'IOP_IOR'{}, corba:string_to_object("corbaloc::1.2@"++Loopback++":10088/NameService")), - ?match({'external', {IP, 42, _ObjectKey, _Counter, _TP, _NewHD}}, + ?match({'external', {IP, 42, _ObjectKey, _Counter, _TP, _NewHD}}, iop_ior:get_key(IOR2)), - ?match(ok, - orber_test_lib:remote_apply(ServerNode, orber, + ?match(ok, + orber_test_lib:remote_apply(ServerNode, orber, remove_listen_interface, [Ref])), ok. @@ -271,103 +291,204 @@ nat_iiop_port_local_local(_Config) -> %% API tests for ORB to ORB, ssl security depth 1 %%----------------------------------------------------------------- -nat_iiop_ssl_port(doc) -> ["SECURE MULTI ORB API tests (SSL depth 1)", +nat_iiop_ssl_port_old(doc) -> ["SECURE MULTI ORB API tests (SSL depth 1)", + "Make sure NAT works for SSL"]; +nat_iiop_ssl_port_old(suite) -> []; +nat_iiop_ssl_port_old(_Config) -> + + IP = orber_test_lib:get_host(), + ServerOptions = orber_test_lib:get_options_old(iiop_ssl, server, + 1, [{iiop_ssl_port, 0}, + {flags, ?ORB_ENV_ENABLE_NAT}, + {ip_address, IP}]), + ClientOptions = orber_test_lib:get_options_old(iiop_ssl, client, + 1, [{iiop_ssl_port, 0}]), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node(ServerOptions)), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + SSLServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_ssl_port, []), + NATSSLServerPort = SSLServerPort+1, + {ok, Ref} = ?match({ok, _}, + orber_test_lib:remote_apply(ServerNode, orber, + add_listen_interface, + [IP, ssl, NATSSLServerPort])), + orber_test_lib:remote_apply(ServerNode, orber_env, configure_override, + [nat_iiop_ssl_port, + {local, NATSSLServerPort, [{4001, 43}]}]), + + {ok, ClientNode, _ClientHost} = + ?match({ok,_,_}, orber_test_lib:js_node(ClientOptions)), + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, + [ssl])), + + IOR1 = ?match(#'IOP_IOR'{}, + orber_test_lib:remote_apply(ClientNode, corba, + string_to_object, + ["corbaname::1.2@"++IP++":"++ + integer_to_list(ServerPort)++"/NameService#mamba"])), + + ?match({'external', {_IP, _Port, _ObjectKey, _Counter, _TP, + #host_data{protocol = ssl, + ssl_data = #'SSLIOP_SSL'{port = NATSSLServerPort}}}}, + iop_ior:get_key(IOR1)), + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + uninstall_test_data, + [ssl])), + ?match(ok, + orber_test_lib:remote_apply(ServerNode, orber, + remove_listen_interface, [Ref])), + ok. + +nat_iiop_ssl_port_local_old(doc) -> ["SECURE MULTI ORB API tests (SSL depth 1)", + "Make sure NAT works for SSL"]; +nat_iiop_ssl_port_local_old(suite) -> []; +nat_iiop_ssl_port_local_old(_Config) -> + + IP = orber_test_lib:get_host(), + ServerOptions = orber_test_lib:get_options_old(iiop_ssl, server, + 1, [{iiop_ssl_port, 0}, + {flags, + (?ORB_ENV_LOCAL_INTERFACE bor + ?ORB_ENV_ENABLE_NAT)}, + {ip_address, IP}]), + ClientOptions = orber_test_lib:get_options_old(iiop_ssl, client, + 1, [{iiop_ssl_port, 0}]), + {ok, ServerNode, _ServerHost} = + ?match({ok,_,_}, orber_test_lib:js_node(ServerOptions)), + ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), + SSLServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_ssl_port, []), + NATSSLServerPort = SSLServerPort+1, + {ok, Ref} = ?match({ok, _}, + orber_test_lib:remote_apply(ServerNode, orber, + add_listen_interface, + [IP, ssl, NATSSLServerPort])), + orber_test_lib:remote_apply(ServerNode, orber_env, configure_override, + [nat_iiop_ssl_port, + {local, NATSSLServerPort, [{NATSSLServerPort, NATSSLServerPort}]}]), + + {ok, ClientNode, _ClientHost} = + ?match({ok,_,_}, orber_test_lib:js_node(ClientOptions)), + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, + [ssl])), + + IOR1 = ?match(#'IOP_IOR'{}, + orber_test_lib:remote_apply(ClientNode, corba, + string_to_object, + ["corbaname::1.2@"++IP++":"++ + integer_to_list(ServerPort)++"/NameService#mamba"])), + + ?match({'external', {_IP, _Port, _ObjectKey, _Counter, _TP, + #host_data{protocol = ssl, + ssl_data = #'SSLIOP_SSL'{port = NATSSLServerPort}}}}, + iop_ior:get_key(IOR1)), + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + uninstall_test_data, + [ssl])), + ?match(ok, + orber_test_lib:remote_apply(ServerNode, orber, + remove_listen_interface, [Ref])), + ok. + + +nat_iiop_ssl_port(doc) -> ["SECURE MULTI ORB API tests (SSL depth 1)", "Make sure NAT works for SSL"]; nat_iiop_ssl_port(suite) -> []; nat_iiop_ssl_port(_Config) -> IP = orber_test_lib:get_host(), - ServerOptions = orber_test_lib:get_options(iiop_ssl, server, + ServerOptions = orber_test_lib:get_options(iiop_ssl, server, 1, [{iiop_ssl_port, 0}, {flags, ?ORB_ENV_ENABLE_NAT}, {ip_address, IP}]), - ClientOptions = orber_test_lib:get_options(iiop_ssl, client, + ClientOptions = orber_test_lib:get_options(iiop_ssl, client, 1, [{iiop_ssl_port, 0}]), - {ok, ServerNode, _ServerHost} = + {ok, ServerNode, _ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node(ServerOptions)), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), SSLServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_ssl_port, []), NATSSLServerPort = SSLServerPort+1, {ok, Ref} = ?match({ok, _}, - orber_test_lib:remote_apply(ServerNode, orber, - add_listen_interface, + orber_test_lib:remote_apply(ServerNode, orber, + add_listen_interface, [IP, ssl, NATSSLServerPort])), - orber_test_lib:remote_apply(ServerNode, orber_env, configure_override, - [nat_iiop_ssl_port, + orber_test_lib:remote_apply(ServerNode, orber_env, configure_override, + [nat_iiop_ssl_port, {local, NATSSLServerPort, [{4001, 43}]}]), - {ok, ClientNode, _ClientHost} = + {ok, ClientNode, _ClientHost} = ?match({ok,_,_}, orber_test_lib:js_node(ClientOptions)), - ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, - install_test_data, + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, [ssl])), - IOR1 = ?match(#'IOP_IOR'{}, - orber_test_lib:remote_apply(ClientNode, corba, + IOR1 = ?match(#'IOP_IOR'{}, + orber_test_lib:remote_apply(ClientNode, corba, string_to_object, ["corbaname::1.2@"++IP++":"++ integer_to_list(ServerPort)++"/NameService#mamba"])), - ?match({'external', {_IP, _Port, _ObjectKey, _Counter, _TP, - #host_data{protocol = ssl, - ssl_data = #'SSLIOP_SSL'{port = NATSSLServerPort}}}}, + ?match({'external', {_IP, _Port, _ObjectKey, _Counter, _TP, + #host_data{protocol = ssl, + ssl_data = #'SSLIOP_SSL'{port = NATSSLServerPort}}}}, iop_ior:get_key(IOR1)), - ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, - uninstall_test_data, + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + uninstall_test_data, [ssl])), - ?match(ok, - orber_test_lib:remote_apply(ServerNode, orber, + ?match(ok, + orber_test_lib:remote_apply(ServerNode, orber, remove_listen_interface, [Ref])), ok. -nat_iiop_ssl_port_local(doc) -> ["SECURE MULTI ORB API tests (SSL depth 1)", +nat_iiop_ssl_port_local(doc) -> ["SECURE MULTI ORB API tests (SSL depth 1)", "Make sure NAT works for SSL"]; nat_iiop_ssl_port_local(suite) -> []; nat_iiop_ssl_port_local(_Config) -> IP = orber_test_lib:get_host(), - ServerOptions = orber_test_lib:get_options(iiop_ssl, server, + ServerOptions = orber_test_lib:get_options(iiop_ssl, server, 1, [{iiop_ssl_port, 0}, - {flags, - (?ORB_ENV_LOCAL_INTERFACE bor + {flags, + (?ORB_ENV_LOCAL_INTERFACE bor ?ORB_ENV_ENABLE_NAT)}, {ip_address, IP}]), - ClientOptions = orber_test_lib:get_options(iiop_ssl, client, + ClientOptions = orber_test_lib:get_options(iiop_ssl, client, 1, [{iiop_ssl_port, 0}]), - {ok, ServerNode, _ServerHost} = + {ok, ServerNode, _ServerHost} = ?match({ok,_,_}, orber_test_lib:js_node(ServerOptions)), ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []), SSLServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_ssl_port, []), NATSSLServerPort = SSLServerPort+1, {ok, Ref} = ?match({ok, _}, - orber_test_lib:remote_apply(ServerNode, orber, - add_listen_interface, + orber_test_lib:remote_apply(ServerNode, orber, + add_listen_interface, [IP, ssl, NATSSLServerPort])), - orber_test_lib:remote_apply(ServerNode, orber_env, configure_override, - [nat_iiop_ssl_port, + orber_test_lib:remote_apply(ServerNode, orber_env, configure_override, + [nat_iiop_ssl_port, {local, NATSSLServerPort, [{NATSSLServerPort, NATSSLServerPort}]}]), - {ok, ClientNode, _ClientHost} = + {ok, ClientNode, _ClientHost} = ?match({ok,_,_}, orber_test_lib:js_node(ClientOptions)), - ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, - install_test_data, + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + install_test_data, [ssl])), - IOR1 = ?match(#'IOP_IOR'{}, - orber_test_lib:remote_apply(ClientNode, corba, + IOR1 = ?match(#'IOP_IOR'{}, + orber_test_lib:remote_apply(ClientNode, corba, string_to_object, ["corbaname::1.2@"++IP++":"++ integer_to_list(ServerPort)++"/NameService#mamba"])), - ?match({'external', {_IP, _Port, _ObjectKey, _Counter, _TP, - #host_data{protocol = ssl, - ssl_data = #'SSLIOP_SSL'{port = NATSSLServerPort}}}}, + ?match({'external', {_IP, _Port, _ObjectKey, _Counter, _TP, + #host_data{protocol = ssl, + ssl_data = #'SSLIOP_SSL'{port = NATSSLServerPort}}}}, iop_ior:get_key(IOR1)), - ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, - uninstall_test_data, + ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib, + uninstall_test_data, [ssl])), - ?match(ok, - orber_test_lib:remote_apply(ServerNode, orber, + ?match(ok, + orber_test_lib:remote_apply(ServerNode, orber, remove_listen_interface, [Ref])), ok. diff --git a/lib/orber/test/orber_test_lib.erl b/lib/orber/test/orber_test_lib.erl index ffc13d0e3c..0ddde49cd6 100644 --- a/lib/orber/test/orber_test_lib.erl +++ b/lib/orber/test/orber_test_lib.erl @@ -41,28 +41,31 @@ end end()). --export([js_node/2, +-export([js_node/2, js_node/1, js_node/0, - slave_sup/0, - remote_apply/4, + slave_sup/0, + remote_apply/4, install_test_data/1, light_tests/3, - uninstall_test_data/1, - destroy_node/2, + uninstall_test_data/1, + destroy_node/2, lookup/2, alternate_iiop_address/2, create_alternate_iiop_address/2, alternate_ssl_iiop_address/3, create_alternate_ssl_iiop_address/3, - test_coding/1, - test_coding/2, - corba_object_tests/2, + test_coding/1, + test_coding/2, + corba_object_tests/2, timeouts/3, precond/3, postcond/4, oe_get_interface/0, create_components_IOR/1, + get_options_old/2, + get_options_old/3, + get_options_old/4, get_options/2, get_options/3, get_options/4, @@ -89,13 +92,13 @@ %%------------------------------------------------------------ %% function : ssl_version -%% Arguments: +%% Arguments: %% Returns : integer() -%% Effect : -%% +%% Effect : +%% %%------------------------------------------------------------ ssl_version() -> - try + try ssl:module_info(), case catch erlang:system_info(otp_release) of Version when is_list(Version) -> @@ -114,10 +117,10 @@ ssl_version() -> %%------------------------------------------------------------ %% function : version_ok -%% Arguments: +%% Arguments: %% Returns : true | {skipped, Reason} -%% Effect : -%% +%% Effect : +%% %%------------------------------------------------------------ version_ok() -> {ok, Hostname} = inet:gethostname(), @@ -151,8 +154,8 @@ version_ok() -> %% function : get_host %% Arguments: Family - inet | inet6 %% Returns : string() -%% Effect : -%% +%% Effect : +%% %%------------------------------------------------------------ get_host() -> get_host(inet). @@ -172,13 +175,13 @@ get_host(Family) -> [IP] = ?match([_], orber:host()), IP end. - + %%------------------------------------------------------------ %% function : get_loopback_interface %% Arguments: Family - inet | inet6 %% Returns : string() -%% Effect : -%% +%% Effect : +%% %%------------------------------------------------------------ get_loopback_interface() -> get_loopback_interface(inet). @@ -193,12 +196,12 @@ get_loopback_interface(Family) -> _ when Family == inet -> "127.0.0.1"; _ -> - "0:0:0:0:0:FFFF:7F00:0001" + "0:0:0:0:0:FFFF:7F00:0001" end; _ when Family == inet -> "127.0.0.1"; _ -> - "0:0:0:0:0:FFFF:7F00:0001" + "0:0:0:0:0:FFFF:7F00:0001" end. %%------------------------------------------------------------ @@ -220,7 +223,7 @@ js_node(InitOptions, StartOptions) when is_list(InitOptions) -> {A,B,C} = erlang:now(), [_, Host] = string:tokens(atom_to_list(node()), [$@]), _NewInitOptions = check_options(InitOptions), - js_node_helper(Host, 0, lists:concat([A,'_',B,'_',C]), + js_node_helper(Host, 0, lists:concat([A,'_',B,'_',C]), InitOptions, 10, StartOptions). js_node_helper(Host, Port, Name, Options, Retries, StartOptions) -> @@ -234,8 +237,8 @@ js_node_helper(Host, Port, Name, Options, Retries, StartOptions) -> ok = rpc:call(NewNode, file, set_cwd, [Cwd]), true = rpc:call(NewNode, code, set_path, [Path]), rpc:call(NewNode, application, load, [orber]), - ok = rpc:call(NewNode, corba, orb_init, - [[{iiop_port, Port}, + ok = rpc:call(NewNode, corba, orb_init, + [[{iiop_port, Port}, {orber_debug_level, 10}|Options]]), start_orber(StartOptions, NewNode), spawn_link(NewNode, ?MODULE, slave_sup, []), @@ -247,8 +250,8 @@ js_node_helper(Host, Port, Name, Options, Retries, StartOptions) -> end; {error, Reason} when Retries == 0 -> {error, Reason}; - {error, Reason} -> - io:format("Could not start slavenode ~p:~p due to: ~p~n", + {error, Reason} -> + io:format("Could not start slavenode ~p:~p due to: ~p~n", [Host, Port, Reason]), timer:sleep(500), js_node_helper(Host, Port, Name, Options, Retries-1, StartOptions) @@ -285,7 +288,7 @@ starter(Host, Name, Args) -> slave_sup() -> process_flag(trap_exit, true), receive - {'EXIT', _, _} -> + {'EXIT', _, _} -> case os:type() of vxworks -> erlang:halt(); @@ -296,8 +299,7 @@ slave_sup() -> start_ssl(true, Node) -> rpc:call(Node, ssl, start, []), - rpc:call(Node, crypto, start, []), - rpc:call(Node, ssl, seed, ["testing"]); + rpc:call(Node, crypto, start, []); start_ssl(_, _) -> ok. @@ -310,68 +312,106 @@ start_orber(lightweight, Node) -> start_orber(_, Node) -> ok = rpc:call(Node, orber, jump_start, []). - %%----------------------------------------------------------------- %% Type - ssl | iiop_ssl %% Role - 'server' | 'client' %% Options - [{Key, Value}] %%----------------------------------------------------------------- -get_options(Type, Role) -> - get_options(Type, Role, 2, []). +get_options_old(Type, Role) -> + get_options_old(Type, Role, 2, []). -get_options(ssl, Role, Level) -> - get_options(ssl, Role, Level, []). +get_options_old(ssl, Role, Level) -> + get_options_old(ssl, Role, Level, []). -get_options(ssl, Role, 2, Options) -> +get_options_old(ssl, Role, 2, Options) -> Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]), [{depth, 2}, {verify, 2}, {keyfile, filename:join([Dir, Role, "key.pem"])}, - {cacertfile, filename:join([Dir, Role, "cacerts.pem"])}, - {certfile, filename:join([Dir, Role, "cert.pem"])}|Options]; -get_options(iiop_ssl, _Role, 2, Options) -> + {cacertfile, filename:join([Dir, Role, "cacerts.pem"])}, + {certfile, filename:join([Dir, Role, "cert.pem"])} |Options]; +get_options_old(iiop_ssl, _Role, 2, Options) -> Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]), [{ssl_server_depth, 2}, {ssl_server_verify, 2}, {ssl_server_certfile, filename:join([Dir, "server", "cert.pem"])}, - {ssl_server_cacertfile, filename:join([Dir, "server", "cacerts.pem"])}, + {ssl_server_cacertfile, filename:join([Dir, "server", "cacerts.pem"])}, {ssl_server_keyfile, filename:join([Dir, "server", "key.pem"])}, {ssl_client_depth, 2}, {ssl_client_verify, 2}, {ssl_client_certfile, filename:join([Dir, "client", "cert.pem"])}, - {ssl_client_cacertfile, filename:join([Dir, "client", "cacerts.pem"])}, + {ssl_client_cacertfile, filename:join([Dir, "client", "cacerts.pem"])}, {ssl_client_keyfile, filename:join([Dir, "client", "key.pem"])}, - {secure, ssl}|Options]; -get_options(iiop_ssl, _Role, 1, Options) -> + {secure, ssl} |Options]; +get_options_old(iiop_ssl, _Role, 1, Options) -> Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]), [{ssl_server_depth, 1}, {ssl_server_verify, 0}, {ssl_server_certfile, filename:join([Dir, "server", "cert.pem"])}, - {ssl_server_cacertfile, filename:join([Dir, "server", "cacerts.pem"])}, + {ssl_server_cacertfile, filename:join([Dir, "server", "cacerts.pem"])}, {ssl_server_keyfile, filename:join([Dir, "server", "key.pem"])}, {ssl_client_depth, 1}, {ssl_client_verify, 0}, {ssl_client_certfile, filename:join([Dir, "client", "cert.pem"])}, - {ssl_client_cacertfile, filename:join([Dir, "client", "cacerts.pem"])}, + {ssl_client_cacertfile, filename:join([Dir, "client", "cacerts.pem"])}, {ssl_client_keyfile, filename:join([Dir, "client", "key.pem"])}, - {secure, ssl}|Options]. + {secure, ssl} |Options]. +get_options(Type, Role) -> + get_options(Type, Role, 2, []). + +get_options(ssl, Role, Level) -> + get_options(ssl, Role, Level, []). + +get_options(ssl, Role, 2, Options) -> + Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]), + [{depth, 2}, + {verify, 2}, + {keyfile, filename:join([Dir, Role, "key.pem"])}, + {cacertfile, filename:join([Dir, Role, "cacerts.pem"])}, + {certfile, filename:join([Dir, Role, "cert.pem"])} |Options]; +get_options(iiop_ssl, _Role, 2, Options) -> + Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]), + [{ssl_server_options, [{depth, 2}, + {verify, 2}, + {certfile, filename:join([Dir, "server", "cert.pem"])}, + {cacertfile, filename:join([Dir, "server", "cacerts.pem"])}, + {keyfile, filename:join([Dir, "server", "key.pem"])}]}, + {ssl_client_options, [{depth, 2}, + {verify, 2}, + {certfile, filename:join([Dir, "client", "cert.pem"])}, + {cacertfile, filename:join([Dir, "client", "cacerts.pem"])}, + {keyfile, filename:join([Dir, "client", "key.pem"])}]}, + {secure, ssl} |Options]; +get_options(iiop_ssl, _Role, 1, Options) -> + Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]), + [{ssl_server_options, [{depth, 1}, + {verify, 0}, + {certfile, filename:join([Dir, "server", "cert.pem"])}, + {cacertfile, filename:join([Dir, "server", "cacerts.pem"])}, + {keyfile, filename:join([Dir, "server", "key.pem"])}]}, + {ssl_client_options, [{depth, 1}, + {verify, 0}, + {certfile, filename:join([Dir, "client", "cert.pem"])}, + {cacertfile, filename:join([Dir, "client", "cacerts.pem"])}, + {keyfile, filename:join([Dir, "client", "key.pem"])}]}, + {secure, ssl} |Options]. create_paths() -> Path = filename:dirname(code:which(?MODULE)), " -pa " ++ Path ++ " -pa " ++ - filename:join(Path, "idl_output") ++ + filename:join(Path, "idl_output") ++ " -pa " ++ - filename:join(Path, "all_SUITE_data") ++ - " -pa " ++ + filename:join(Path, "all_SUITE_data") ++ + " -pa " ++ filename:dirname(code:which(orber)). %%------------------------------------------------------------ %% function : destroy_node %% Arguments: Node - which node to destroy. %% Type - normal | ssl -%% Returns : -%% Effect : +%% Returns : +%% Effect : %%------------------------------------------------------------ destroy_node(Node, Type) -> @@ -385,13 +425,13 @@ stopper(Node, _Type) -> slave:stop(Node) end. - + %%------------------------------------------------------------ %% function : remote_apply %% Arguments: N - Node, M - Module, %% F - Function, A - Arguments (list) -%% Returns : -%% Effect : +%% Returns : +%% Effect : %%------------------------------------------------------------ remote_apply(N, M,F,A) -> case rpc:call(N, M, F, A) of @@ -412,7 +452,7 @@ remote_apply(N, M,F,A) -> install_test_data(nameservice) -> oe_orber_test_server:oe_register(), - Mamba = orber_test_server:oe_create([], [{regname, {local, mamba}}]), + Mamba = orber_test_server:oe_create([], [{regname, {local, mamba}}]), true = corba:add_initial_service("Mamba", Mamba), NS = corba:resolve_initial_references("NameService"), NC1 = lname_component:set_id(lname_component:create(), "mamba"), @@ -421,7 +461,7 @@ install_test_data(nameservice) -> install_test_data({nameservice, AltAddr, AltPort}) -> oe_orber_test_server:oe_register(), - Obj = orber_test_server:oe_create([], [{regname, {local, mamba}}]), + Obj = orber_test_server:oe_create([], [{regname, {local, mamba}}]), Mamba = corba:add_alternate_iiop_address(Obj, AltAddr, AltPort), true = corba:add_initial_service("Mamba", Mamba), NS = corba:resolve_initial_references("NameService"), @@ -431,8 +471,8 @@ install_test_data({nameservice, AltAddr, AltPort}) -> install_test_data(timeout) -> oe_orber_test_server:oe_register(), - Mamba = orber_test_server:oe_create([], {local, mamba}), - Viper = orber_test_timeout_server:oe_create([], {local, viper}), + Mamba = orber_test_server:oe_create([], {local, mamba}), + Viper = orber_test_timeout_server:oe_create([], {local, viper}), NS = corba:resolve_initial_references("NameService"), NC1 = lname_component:set_id(lname_component:create(), "mamba"), N1 = lname:insert_component(lname:create(), 1, NC1), @@ -451,7 +491,7 @@ install_test_data(pseudo) -> install_test_data(ssl) -> oe_orber_test_server:oe_register(), - Mamba = orber_test_server:oe_create([], [{regname, {local, mamba}}]), + Mamba = orber_test_server:oe_create([], [{regname, {local, mamba}}]), NS = corba:resolve_initial_references("NameService"), NC1 = lname_component:set_id(lname_component:create(), "mamba"), N = lname:insert_component(lname:create(), 1, NC1), @@ -459,7 +499,7 @@ install_test_data(ssl) -> install_test_data(ssl_simple) -> oe_orber_test_server:oe_register(); - + install_test_data(light) -> %% Nothing to do at the moment but we might in the future ok; @@ -480,7 +520,7 @@ uninstall_test_data(pseudo) -> NC1 = lname_component:set_id(lname_component:create(), "mamba"), N = lname:insert_component(lname:create(), 1, NC1), _Obj = (catch 'CosNaming_NamingContext':resolve(NS, N)), - catch 'CosNaming_NamingContext':destroy(NS), + catch 'CosNaming_NamingContext':destroy(NS), oe_orber_test_server:oe_unregister(); uninstall_test_data(timeout) -> @@ -494,7 +534,7 @@ uninstall_test_data(timeout) -> Viper = (catch 'CosNaming_NamingContext':resolve(NS, N2)), catch corba:dispose(Mamba), catch corba:dispose(Viper), - catch 'CosNaming_NamingContext':destroy(NS), + catch 'CosNaming_NamingContext':destroy(NS), oe_orber_test_server:oe_unregister(); uninstall_test_data(nameservice) -> @@ -504,7 +544,7 @@ uninstall_test_data(nameservice) -> N = lname:insert_component(lname:create(), 1, NC1), Obj = (catch 'CosNaming_NamingContext':resolve(NS, N)), catch corba:dispose(Obj), - catch 'CosNaming_NamingContext':destroy(NS), + catch 'CosNaming_NamingContext':destroy(NS), oe_orber_test_server:oe_unregister(); uninstall_test_data(ssl) -> @@ -513,7 +553,7 @@ uninstall_test_data(ssl) -> N = lname:insert_component(lname:create(), 1, NC1), Obj = (catch 'CosNaming_NamingContext':resolve(NS, N)), catch corba:dispose(Obj), - catch 'CosNaming_NamingContext':destroy(NS), + catch 'CosNaming_NamingContext':destroy(NS), oe_orber_test_server:oe_unregister(); uninstall_test_data(ssl_simple) -> @@ -531,27 +571,27 @@ uninstall_test_data(_) -> %% Arguments: TestServerObj a orber_test_server ref %% OtherObj - any other Orber object. %% Returns : term() -%% Effect : +%% Effect : %%------------------------------------------------------------ corba_object_tests(TestServerObj, OtherObj) -> - ?match(false, + ?match(false, corba_object:is_a(TestServerObj, "IDL:orber_parent/inherrit:1.0")), - ?match(true, + ?match(true, corba_object:is_a(TestServerObj, "IDL:omg.org/orber_parent/inherrit:1.0")), - ?match(true, + ?match(true, corba_object:is_a(TestServerObj, "IDL:omg.org/orber_test/server:1.0")), - ?match(false, + ?match(false, corba_object:is_a(TestServerObj, "IDL:orber_test/server:1.0")), - ?match(false, + ?match(false, corba_object:is_a(TestServerObj, "IDL:omg.org/orber_parent/inherrit:1.1")), - ?match(false, + ?match(false, corba_object:is_a(TestServerObj, "NotValidIFRID")), - ?match(false, + ?match(false, corba_object:is_nil(TestServerObj)), - ?match(false, + ?match(false, corba_object:is_equivalent(OtherObj,TestServerObj)), - ?match(true, + ?match(true, corba_object:is_equivalent(TestServerObj,TestServerObj)), ?match(false, corba_object:non_existent(TestServerObj)), ?match(false, corba_object:not_existent(TestServerObj)), @@ -563,32 +603,32 @@ corba_object_tests(TestServerObj, OtherObj) -> %% function : lookup %% Arguments: Port - which port the other orb uses. %% Returns : term() -%% Effect : +%% Effect : %%------------------------------------------------------------ lookup(Host, Port) -> Key = Host++":"++integer_to_list(Port), - NSR = corba:resolve_initial_references_remote("NameService", + NSR = corba:resolve_initial_references_remote("NameService", ["iiop://"++Key]), NC1 = lname_component:set_id(lname_component:create(), "not_exist"), N1 = lname:insert_component(lname:create(), 1, NC1), ?match({'EXCEPTION',{'CosNaming_NamingContext_NotFound',_,_,_}}, 'CosNaming_NamingContext':resolve(NSR, N1)), - + NC2 = lname_component:set_id(lname_component:create(), "mamba"), N2 = lname:insert_component(lname:create(), 1, NC2), - Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, 'CosNaming_NamingContext':resolve(NSR, N2)), orber_test_server:print(Obj), - Obj2 = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + Obj2 = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, corba:string_to_object("corbaname:iiop:1.1@"++Key++"/NameService#mamba")), - + orber_test_server:print(Obj2), - NSR2 = ?match({'IOP_IOR',"IDL:omg.org/CosNaming/NamingContextExt:1.0",_}, + NSR2 = ?match({'IOP_IOR',"IDL:omg.org/CosNaming/NamingContextExt:1.0",_}, corba:string_to_object("corbaloc:iiop:1.1@"++Key++"/NameService")), - Obj3 = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + Obj3 = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, 'CosNaming_NamingContext':resolve(NSR2, N2)), orber_test_server:print(Obj3). @@ -596,11 +636,11 @@ lookup(Host, Port) -> %% function : alternate_iiop_address %% Arguments: Port - which port the other orb uses. %% Returns : term() -%% Effect : +%% Effect : %%------------------------------------------------------------ alternate_iiop_address(Host, Port) -> IOR = create_alternate_iiop_address(Host, Port), - + ?match(false, corba_object:non_existent(IOR)), ?match({'object_forward',_}, corba:locate(IOR)), ?match({'object_forward',_}, corba:locate(IOR, 10000)), @@ -610,145 +650,145 @@ alternate_iiop_address(Host, Port) -> %% function : create_alternate_iiop_address %% Arguments: Port - which port the other orb uses. %% Returns : term() -%% Effect : +%% Effect : %%------------------------------------------------------------ create_alternate_iiop_address(Host, Port) -> - MC = [#'IOP_TaggedComponent'{tag = ?TAG_ORB_TYPE, + MC = [#'IOP_TaggedComponent'{tag = ?TAG_ORB_TYPE, component_data = ?ORBER_ORB_TYPE_1}, - #'IOP_TaggedComponent'{tag = ?TAG_CODE_SETS, + #'IOP_TaggedComponent'{tag = ?TAG_CODE_SETS, component_data = ?DEFAULT_CODESETS}, - #'IOP_TaggedComponent'{tag = ?TAG_ALTERNATE_IIOP_ADDRESS, + #'IOP_TaggedComponent'{tag = ?TAG_ALTERNATE_IIOP_ADDRESS, component_data = #'ALTERNATE_IIOP_ADDRESS'{ - 'HostID' = Host, + 'HostID' = Host, 'Port' = Port}}, - #'IOP_TaggedComponent'{tag = ?TAG_ALTERNATE_IIOP_ADDRESS, + #'IOP_TaggedComponent'{tag = ?TAG_ALTERNATE_IIOP_ADDRESS, component_data = #'ALTERNATE_IIOP_ADDRESS'{ - 'HostID' = Host, + 'HostID' = Host, 'Port' = 8000}}, - #'IOP_TaggedComponent'{tag = ?TAG_ALTERNATE_IIOP_ADDRESS, + #'IOP_TaggedComponent'{tag = ?TAG_ALTERNATE_IIOP_ADDRESS, component_data = #'ALTERNATE_IIOP_ADDRESS'{ - 'HostID' = Host, + 'HostID' = Host, 'Port' = 8000}}], #'IOP_IOR'{type_id=TypeID, - profiles=P1} = _IORA = iop_ior:create({1,2}, + profiles=P1} = _IORA = iop_ior:create({1,2}, "IDL:omg.org/CosNaming/NamingContextExt:1.0", - [Host], 8000, -1, + [Host], 8000, -1, "NameService", MC, 0, 0), - #'IOP_IOR'{profiles=P2} = _IORB = iop_ior:create({1,1}, + #'IOP_IOR'{profiles=P2} = _IORB = iop_ior:create({1,1}, "IDL:omg.org/CosNaming/NamingContextExt:1.0", [Host], 8000, -1, "NameService", [], 0, 0), #'IOP_IOR'{type_id=TypeID, profiles=P2++P1}. - + %%------------------------------------------------------------ %% function : create_components_IOR -%% Arguments: +%% Arguments: %% Returns : term() -%% Effect : +%% Effect : %%------------------------------------------------------------ create_components_IOR(Version) -> - MC = [#'IOP_TaggedComponent'{tag = ?TAG_ORB_TYPE, + MC = [#'IOP_TaggedComponent'{tag = ?TAG_ORB_TYPE, component_data = ?ORBER_ORB_TYPE_1}, - #'IOP_TaggedComponent'{tag = ?TAG_CODE_SETS, + #'IOP_TaggedComponent'{tag = ?TAG_CODE_SETS, component_data = ?DEFAULT_CODESETS}, - #'IOP_TaggedComponent'{tag = ?TAG_ALTERNATE_IIOP_ADDRESS, + #'IOP_TaggedComponent'{tag = ?TAG_ALTERNATE_IIOP_ADDRESS, component_data = #'ALTERNATE_IIOP_ADDRESS'{ - 'HostID' = "127.0.0.1", + 'HostID' = "127.0.0.1", 'Port' = 4001}}, - #'IOP_TaggedComponent'{tag = ?TAG_SSL_SEC_TRANS, - component_data = #'SSLIOP_SSL'{target_supports = 0, + #'IOP_TaggedComponent'{tag = ?TAG_SSL_SEC_TRANS, + component_data = #'SSLIOP_SSL'{target_supports = 0, target_requires = 1, port = 2}}, - #'IOP_TaggedComponent'{tag = ?TAG_FT_GROUP, - component_data = + #'IOP_TaggedComponent'{tag = ?TAG_FT_GROUP, + component_data = #'FT_TagFTGroupTaggedComponent' - {version = #'GIOP_Version'{major = 1, - minor = 2}, - ft_domain_id = "FT_FTDomainId", + {version = #'GIOP_Version'{major = 1, + minor = 2}, + ft_domain_id = "FT_FTDomainId", object_group_id = ?ULONGLONGMAX, object_group_ref_version = ?LONGMAX}}, - #'IOP_TaggedComponent'{tag = ?TAG_FT_PRIMARY, - component_data = + #'IOP_TaggedComponent'{tag = ?TAG_FT_PRIMARY, + component_data = #'FT_TagFTPrimaryTaggedComponent'{primary = true}}, - #'IOP_TaggedComponent'{tag = ?TAG_FT_HEARTBEAT_ENABLED, - component_data = + #'IOP_TaggedComponent'{tag = ?TAG_FT_HEARTBEAT_ENABLED, + component_data = #'FT_TagFTHeartbeatEnabledTaggedComponent'{heartbeat_enabled = true}}, - #'IOP_TaggedComponent'{tag = ?TAG_CSI_SEC_MECH_LIST, - component_data = + #'IOP_TaggedComponent'{tag = ?TAG_CSI_SEC_MECH_LIST, + component_data = #'CSIIOP_CompoundSecMechList' {stateful = false, - mechanism_list = + mechanism_list = [#'CSIIOP_CompoundSecMech' - {target_requires = 6, - transport_mech = + {target_requires = 6, + transport_mech = #'IOP_TaggedComponent' {tag=?TAG_TLS_SEC_TRANS, component_data=#'CSIIOP_TLS_SEC_TRANS' - {target_supports = 7, - target_requires = 8, - addresses = - [#'CSIIOP_TransportAddress'{host_name = "127.0.0.1", + {target_supports = 7, + target_requires = 8, + addresses = + [#'CSIIOP_TransportAddress'{host_name = "127.0.0.1", port = 6001}]}}, - as_context_mech = + as_context_mech = #'CSIIOP_AS_ContextSec' {target_supports = 9, target_requires = 10, - client_authentication_mech = [1, 255], - target_name = [2,255]}, - sas_context_mech = + client_authentication_mech = [1, 255], + target_name = [2,255]}, + sas_context_mech = #'CSIIOP_SAS_ContextSec' {target_supports = 11, target_requires = 12, - privilege_authorities = + privilege_authorities = [#'CSIIOP_ServiceConfiguration' - {syntax = ?ULONGMAX, - name = [3,255]}], + {syntax = ?ULONGMAX, + name = [3,255]}], supported_naming_mechanisms = [[4,255],[5,255]], supported_identity_types = ?ULONGMAX}}, #'CSIIOP_CompoundSecMech' - {target_requires = 6, - transport_mech = + {target_requires = 6, + transport_mech = #'IOP_TaggedComponent' {tag=?TAG_NULL_TAG, component_data=[]}, - as_context_mech = + as_context_mech = #'CSIIOP_AS_ContextSec' {target_supports = 9, target_requires = 10, - client_authentication_mech = [1, 255], - target_name = [2,255]}, - sas_context_mech = + client_authentication_mech = [1, 255], + target_name = [2,255]}, + sas_context_mech = #'CSIIOP_SAS_ContextSec' {target_supports = 11, target_requires = 12, - privilege_authorities = + privilege_authorities = [#'CSIIOP_ServiceConfiguration' - {syntax = ?ULONGMAX, - name = [3,255]}], + {syntax = ?ULONGMAX, + name = [3,255]}], supported_naming_mechanisms = [[4,255],[5,255]], supported_identity_types = ?ULONGMAX}}, #'CSIIOP_CompoundSecMech' - {target_requires = 6, - transport_mech = + {target_requires = 6, + transport_mech = #'IOP_TaggedComponent' {tag=?TAG_SECIOP_SEC_TRANS, component_data=#'CSIIOP_SECIOP_SEC_TRANS' - {target_supports = 7, - target_requires = 8, + {target_supports = 7, + target_requires = 8, mech_oid = [0,255], target_name = [0,255], - addresses = - [#'CSIIOP_TransportAddress'{host_name = "127.0.0.1", + addresses = + [#'CSIIOP_TransportAddress'{host_name = "127.0.0.1", port = 6001}]}}, - as_context_mech = + as_context_mech = #'CSIIOP_AS_ContextSec' {target_supports = 9, target_requires = 10, - client_authentication_mech = [1, 255], - target_name = [2,255]}, - sas_context_mech = + client_authentication_mech = [1, 255], + target_name = [2,255]}, + sas_context_mech = #'CSIIOP_SAS_ContextSec' {target_supports = 11, target_requires = 12, - privilege_authorities = + privilege_authorities = [#'CSIIOP_ServiceConfiguration' - {syntax = ?ULONGMAX, - name = [3,255]}], + {syntax = ?ULONGMAX, + name = [3,255]}], supported_naming_mechanisms = [[4,255],[5,255]], supported_identity_types = ?ULONGMAX}}]}}], iop_ior:create(Version, "IDL:omg.org/CosNaming/NamingContextExt:1.0", @@ -760,11 +800,11 @@ create_components_IOR(Version) -> %% function : alternate_ssl_iiop_address %% Arguments: Port - which port the other orb uses. %% Returns : term() -%% Effect : +%% Effect : %%------------------------------------------------------------ alternate_ssl_iiop_address(Host, Port, SSLPort) -> IOR = create_alternate_ssl_iiop_address(Host, Port, SSLPort), - + ?match(false, corba_object:non_existent(IOR)), ?match({'object_forward',_}, corba:locate(IOR)), ?match({'object_forward',_}, corba:locate(IOR, 10000)), @@ -775,37 +815,37 @@ alternate_ssl_iiop_address(Host, Port, SSLPort) -> %% function : create_alternate_ssl_iiop_address %% Arguments: Port - which port the other orb uses. %% Returns : term() -%% Effect : +%% Effect : %%------------------------------------------------------------ create_alternate_ssl_iiop_address(Host, Port, SSLPort) -> - MC = [#'IOP_TaggedComponent'{tag = ?TAG_ORB_TYPE, + MC = [#'IOP_TaggedComponent'{tag = ?TAG_ORB_TYPE, component_data = ?ORBER_ORB_TYPE_1}, - #'IOP_TaggedComponent'{tag = ?TAG_CODE_SETS, + #'IOP_TaggedComponent'{tag = ?TAG_CODE_SETS, component_data = ?DEFAULT_CODESETS}, - #'IOP_TaggedComponent'{tag = ?TAG_ALTERNATE_IIOP_ADDRESS, + #'IOP_TaggedComponent'{tag = ?TAG_ALTERNATE_IIOP_ADDRESS, component_data = #'ALTERNATE_IIOP_ADDRESS'{ - 'HostID' = Host, + 'HostID' = Host, 'Port' = Port}}, - #'IOP_TaggedComponent'{tag = ?TAG_ALTERNATE_IIOP_ADDRESS, + #'IOP_TaggedComponent'{tag = ?TAG_ALTERNATE_IIOP_ADDRESS, component_data = #'ALTERNATE_IIOP_ADDRESS'{ - 'HostID' = Host, + 'HostID' = Host, 'Port' = 8000}}, - #'IOP_TaggedComponent'{tag = ?TAG_ALTERNATE_IIOP_ADDRESS, + #'IOP_TaggedComponent'{tag = ?TAG_ALTERNATE_IIOP_ADDRESS, component_data = #'ALTERNATE_IIOP_ADDRESS'{ - 'HostID' = Host, + 'HostID' = Host, 'Port' = 8000}}, - #'IOP_TaggedComponent'{tag=?TAG_SSL_SEC_TRANS, - component_data=#'SSLIOP_SSL'{target_supports = 2, - target_requires = 2, + #'IOP_TaggedComponent'{tag=?TAG_SSL_SEC_TRANS, + component_data=#'SSLIOP_SSL'{target_supports = 2, + target_requires = 2, port = SSLPort}}], #'IOP_IOR'{type_id=TypeID, - profiles=P1} = _IORA = iop_ior:create_external({1,2}, + profiles=P1} = _IORA = iop_ior:create_external({1,2}, "IDL:omg.org/CosNaming/NamingContextExt:1.0", - Host, 8000, + Host, 8000, "NameService", MC), - #'IOP_IOR'{profiles=P2} = _IORB = iop_ior:create_external({1,1}, + #'IOP_IOR'{profiles=P2} = _IORB = iop_ior:create_external({1,1}, "IDL:omg.org/CosNaming/NamingContextExt:1.0", - Host, 8000, + Host, 8000, "NameService", []), #'IOP_IOR'{type_id=TypeID, profiles=P2++P1}. @@ -814,11 +854,11 @@ create_alternate_ssl_iiop_address(Host, Port, SSLPort) -> %% function : timeouts %% Arguments: Port - which port the other orb uses. %% Returns : term() -%% Effect : +%% Effect : %%------------------------------------------------------------ timeouts(Host, Port, ReqT) -> - NSR = corba:resolve_initial_references_remote("NameService", + NSR = corba:resolve_initial_references_remote("NameService", ["iiop://"++Host++":"++integer_to_list(Port)]), NC1 = lname_component:set_id(lname_component:create(), "mamba"), N1 = lname:insert_component(lname:create(), 1, NC1), @@ -828,21 +868,21 @@ timeouts(Host, Port, ReqT) -> Viper = 'CosNaming_NamingContext':resolve(NSR, N2), ?match({'EXCEPTION',{'TIMEOUT',_,_,_}}, - orber_test_timeout_server:twoway_function(Viper, ReqT, ReqT*2)), - ?match(ok, orber_test_timeout_server:oneway_function(Viper, ReqT*2)), + orber_test_timeout_server:twoway_function(Viper, ReqT, ReqT*2)), + ?match(ok, orber_test_timeout_server:oneway_function(Viper, ReqT*2)), ?match({'EXCEPTION',{'TIMEOUT',_,_,_}}, - orber_test_server:testing_iiop_twoway_delay(Mamba, ReqT)), + orber_test_server:testing_iiop_twoway_delay(Mamba, ReqT)), ?match(ok, orber_test_server:testing_iiop_oneway_delay(Mamba, ReqT)), - + %% Since the objects are stalled we must wait until they are available again %% to be able to run any more tests and get the correct results. timer:sleep(ReqT*4), - - ?match(ok, orber_test_timeout_server:twoway_function(Viper, ReqT*2, ReqT)), - ?match(ok, orber_test_timeout_server:oneway_function(Viper, ReqT*2)), - - ?match(ok, orber_test_server:testing_iiop_twoway_delay(Mamba, 0)), + + ?match(ok, orber_test_timeout_server:twoway_function(Viper, ReqT*2, ReqT)), + ?match(ok, orber_test_timeout_server:oneway_function(Viper, ReqT*2)), + + ?match(ok, orber_test_server:testing_iiop_twoway_delay(Mamba, 0)), ?match(ok, orber_test_server:testing_iiop_oneway_delay(Mamba, 0)), timer:sleep(ReqT*4), @@ -853,11 +893,11 @@ timeouts(Host, Port, ReqT) -> %% Arguments: Host - which node to contact. %% Port - which port the other orb uses. %% Returns : term() -%% Effect : +%% Effect : %%------------------------------------------------------------ light_tests(Host, Port, ObjName) -> - NSR = corba:resolve_initial_references_remote("NameService", + NSR = corba:resolve_initial_references_remote("NameService", ["iiop://"++Host++":"++integer_to_list(Port)]), NC1 = lname_component:set_id(lname_component:create(), "not_exist"), N1 = lname:insert_component(lname:create(), 1, NC1), @@ -868,7 +908,7 @@ light_tests(Host, Port, ObjName) -> 'CosNaming_NamingContext':resolve(NSR, N1)), NC2 = lname_component:set_id(lname_component:create(), ObjName), N2 = lname:insert_component(lname:create(), 1, NC2), - Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, + Obj = ?match({'IOP_IOR',"IDL:omg.org/orber_test/server:1.0",_}, 'CosNaming_NamingContext':resolve(NSR, N2)), Nodes = orber:get_lightweight_nodes(), io:format("Light Nodes: ~p~n", [Nodes]), @@ -890,165 +930,165 @@ test_coding(Obj) -> test_coding(Obj, Local) -> %%--- Testing code and decode arguments --- ?match({ok, 1.5}, orber_test_server:testing_iiop_float(Obj, 1.5)), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_float(Obj, atom)), ?match({ok,1.0}, orber_test_server:testing_iiop_double(Obj, 1.0)), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_double(Obj, "wrong")), - + ?match({ok,0}, orber_test_server:testing_iiop_short(Obj, 0)), ?match({ok,?SHORTMAX}, orber_test_server:testing_iiop_short(Obj, ?SHORTMAX)), ?match({ok,?SHORTMIN}, orber_test_server:testing_iiop_short(Obj, ?SHORTMIN)), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_short(Obj, atomic)), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_short(Obj, ?SHORTMAX+1)), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_short(Obj, ?SHORTMIN-1)), - + ?match({ok,0}, orber_test_server:testing_iiop_ushort(Obj, 0)), ?match({ok,?USHORTMAX}, orber_test_server:testing_iiop_ushort(Obj, ?USHORTMAX)), ?match({ok,?USHORTMIN}, orber_test_server:testing_iiop_ushort(Obj, ?USHORTMIN)), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_ushort(Obj, ?USHORTMAX+1)), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_ushort(Obj, ?USHORTMIN-1)), - + ?match({ok,0}, orber_test_server:testing_iiop_long(Obj, 0)), ?match({ok,?LONGMAX}, orber_test_server:testing_iiop_long(Obj, ?LONGMAX)), ?match({ok,?LONGMIN}, orber_test_server:testing_iiop_long(Obj, ?LONGMIN)), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_long(Obj, "wrong")), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_long(Obj, ?LONGMAX+1)), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_long(Obj, ?LONGMIN-1)), - + ?match({ok,0}, orber_test_server:testing_iiop_longlong(Obj, 0)), ?match({ok,?LONGLONGMAX}, orber_test_server:testing_iiop_longlong(Obj, ?LONGLONGMAX)), ?match({ok,?LONGLONGMIN}, orber_test_server:testing_iiop_longlong(Obj, ?LONGLONGMIN)), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_longlong(Obj, "wrong")), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_longlong(Obj, ?LONGLONGMAX+1)), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_longlong(Obj, ?LONGLONGMIN-1)), - + ?match({ok,0}, orber_test_server:testing_iiop_ulong(Obj, 0)), ?match({ok,?ULONGMAX}, orber_test_server:testing_iiop_ulong(Obj, ?ULONGMAX)), ?match({ok,?ULONGMIN}, orber_test_server:testing_iiop_ulong(Obj, ?ULONGMIN)), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_ulong(Obj, ?ULONGMAX+1)), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_ulong(Obj, ?ULONGMIN-1)), - + ?match({ok,0}, orber_test_server:testing_iiop_ulonglong(Obj, 0)), ?match({ok,?ULONGLONGMAX}, orber_test_server:testing_iiop_ulonglong(Obj, ?ULONGLONGMAX)), ?match({ok,?ULONGLONGMIN}, orber_test_server:testing_iiop_ulonglong(Obj, ?ULONGLONGMIN)), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_ulonglong(Obj, ?ULONGLONGMAX+1)), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_ulonglong(Obj, ?ULONGLONGMIN-1)), - + ?match({ok,98}, orber_test_server:testing_iiop_char(Obj, 98)), ?match({ok,$b}, orber_test_server:testing_iiop_char(Obj, $b)), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_char(Obj, atomic)), ?match({ok,65535}, orber_test_server:testing_iiop_wchar(Obj, 65535)), ?match({ok,$b}, orber_test_server:testing_iiop_wchar(Obj, $b)), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_wchar(Obj, atomic)), - + ?match({ok,true}, orber_test_server:testing_iiop_bool(Obj, true)), ?match({ok,false}, orber_test_server:testing_iiop_bool(Obj, false)), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_bool(Obj, atom)), - + ?match({ok,1}, orber_test_server:testing_iiop_octet(Obj, 1)), % No real guards for this case. -% ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, +% ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, % orber_test_server:testing_iiop_octet(Obj, 1.5)), IOR12 = create_components_IOR({1,2}), ?match({ok,Obj}, orber_test_server:testing_iiop_obj(Obj, Obj)), ?match({ok,IOR12}, orber_test_server:testing_iiop_obj(Obj, IOR12)), PObj = orber_test_server:oe_create([], [{pseudo,true}]), ?match({ok, _}, orber_test_server:testing_iiop_obj(Obj, PObj)), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_obj(Obj, "no_object")), ?match({ok,"string"}, orber_test_server:testing_iiop_string(Obj, "string")), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_string(Obj, "ToLongString")), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_string(Obj, atomic)), ?match({ok,[65535]}, orber_test_server:testing_iiop_wstring(Obj, [65535])), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_wstring(Obj, "ToLongWstring")), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_wstring(Obj, atomic)), - ?match({ok, one}, + ?match({ok, one}, orber_test_server:testing_iiop_enum(Obj, one)), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_enum(Obj, three)), - ?match({ok,[1,2,3]}, + ?match({ok,[1,2,3]}, orber_test_server:testing_iiop_seq(Obj, [1,2,3])), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_seq(Obj, [1,2,3,4])), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_seq(Obj, false)), - ?match({ok,[#orber_test_server_struc{a=1, b=2}]}, - orber_test_server:testing_iiop_struc_seq(Obj, + ?match({ok,[#orber_test_server_struc{a=1, b=2}]}, + orber_test_server:testing_iiop_struc_seq(Obj, [#orber_test_server_struc{a=1, b=2}])), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_struc_seq(Obj, false)), - ?match({ok,[#orber_test_server_uni{label=1, value=66}]}, - orber_test_server:testing_iiop_uni_seq(Obj, + ?match({ok,[#orber_test_server_uni{label=1, value=66}]}, + orber_test_server:testing_iiop_uni_seq(Obj, [#orber_test_server_uni{label=1, value=66}])), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_uni_seq(Obj, false)), - ?match({ok,{"one", "two"}}, + ?match({ok,{"one", "two"}}, orber_test_server:testing_iiop_array(Obj, {"one", "two"})), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_array(Obj, {"one", "two", "three"})), - ?match({ok,#orber_test_server_struc{a=1, b=2}}, - orber_test_server:testing_iiop_struct(Obj, + ?match({ok,#orber_test_server_struc{a=1, b=2}}, + orber_test_server:testing_iiop_struct(Obj, #orber_test_server_struc{a=1, b=2})), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, - orber_test_server:testing_iiop_struct(Obj, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_struct(Obj, #orber_test_server_struc{a="WRONG", b=2})), - ?match({ok,#orber_test_server_uni{label=1, value=66}}, - orber_test_server:testing_iiop_union(Obj, + ?match({ok,#orber_test_server_uni{label=1, value=66}}, + orber_test_server:testing_iiop_union(Obj, #orber_test_server_uni{label=1, value=66})), - ?match({ok,#orber_test_server_uni_d{label=1, value=66}}, - orber_test_server:testing_iiop_union_d(Obj, + ?match({ok,#orber_test_server_uni_d{label=1, value=66}}, + orber_test_server:testing_iiop_union_d(Obj, #orber_test_server_uni_d{label=1, value=66})), - ?match({ok,#orber_test_server_uni_d{label=2, value=true}}, - orber_test_server:testing_iiop_union_d(Obj, + ?match({ok,#orber_test_server_uni_d{label=2, value=true}}, + orber_test_server:testing_iiop_union_d(Obj, #orber_test_server_uni_d{label=2, value=true})), ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, - orber_test_server:testing_iiop_union_d(Obj, + orber_test_server:testing_iiop_union_d(Obj, #orber_test_server_uni_d{label=2, value=66})), case Local of true -> - ?match({ok,#orber_test_server_uni{label=2, value=66}}, - orber_test_server:testing_iiop_union(Obj, + ?match({ok,#orber_test_server_uni{label=2, value=66}}, + orber_test_server:testing_iiop_union(Obj, #orber_test_server_uni{label=2, value=66})); false -> - ?match({ok,#orber_test_server_uni{label=2, value=undefined}}, - orber_test_server:testing_iiop_union(Obj, + ?match({ok,#orber_test_server_uni{label=2, value=undefined}}, + orber_test_server:testing_iiop_union(Obj, #orber_test_server_uni{label=2, value=66})) end, @@ -1059,258 +1099,258 @@ test_coding(Obj, Local) -> C4 = orber_test_server:fixed52negconst1(), C5 = orber_test_server:fixed52negconst2(), C6 = orber_test_server:fixed52negconst3(), - + ?match({ok,C1}, orber_test_server:testing_iiop_fixed(Obj, C1)), ?match({ok,C2}, orber_test_server:testing_iiop_fixed(Obj, C2)), ?match({ok,C3}, orber_test_server:testing_iiop_fixed(Obj, C3)), ?match({ok,C4}, orber_test_server:testing_iiop_fixed(Obj, C4)), ?match({ok,C5}, orber_test_server:testing_iiop_fixed(Obj, C5)), ?match({ok,C6}, orber_test_server:testing_iiop_fixed(Obj, C6)), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, - orber_test_server:testing_iiop_fixed(Obj, #fixed{digits = 5, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_fixed(Obj, #fixed{digits = 5, scale = 2, value = 123450})), ?match(ok, orber_test_server:testing_iiop_void(Obj)), - ?match({'EXCEPTION',{'BAD_QOS',_,_,_}}, + ?match({'EXCEPTION',{'BAD_QOS',_,_,_}}, orber_test_server:pseudo_call_raise_exc(Obj, 1)), - ?match({'EXCEPTION',{'BAD_QOS',_,_,_}}, + ?match({'EXCEPTION',{'BAD_QOS',_,_,_}}, orber_test_server:pseudo_call_raise_exc(Obj, 2)), - ?match({'EXCEPTION',{'orber_test_server_UserDefinedException',_}}, + ?match({'EXCEPTION',{'orber_test_server_UserDefinedException',_}}, orber_test_server:raise_local_exception(Obj)), ?match({'EXCEPTION',{'orber_test_server_ComplexUserDefinedException',_, - [#orber_test_server_struc{a=1, b=2}]}}, + [#orber_test_server_struc{a=1, b=2}]}}, orber_test_server:raise_complex_local_exception(Obj)), %% Test all TypeCodes - ?match({ok, #any{typecode = tk_long, value = 1}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_long, + ?match({ok, #any{typecode = tk_long, value = 1}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_long, value = 1})), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_long, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_long, value = "wrong"})), - ?match({ok, #any{typecode = tk_float, value = 1.5}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_float, + ?match({ok, #any{typecode = tk_float, value = 1.5}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_float, value = 1.5})), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_long, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_long, value = "wrong"})), - ?match({ok, #any{typecode = tk_double}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_double, + ?match({ok, #any{typecode = tk_double}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_double, value = 1.0})), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_double, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_double, value = "wrong"})), - ?match({ok, #any{typecode = tk_short, value = -1}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_short, + ?match({ok, #any{typecode = tk_short, value = -1}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_short, value = -1})), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_short, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_short, value = atomic})), - ?match({ok, #any{typecode = tk_ushort, value = 1}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ushort, + ?match({ok, #any{typecode = tk_ushort, value = 1}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ushort, value = 1})), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ushort, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ushort, value = -1})), - ?match({ok, #any{typecode = tk_long, value = 1}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_long, + ?match({ok, #any{typecode = tk_long, value = 1}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_long, value = 1})), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_long, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_long, value = "wrong"})), - ?match({ok, #any{typecode = tk_longlong, value = 1}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_longlong, + ?match({ok, #any{typecode = tk_longlong, value = 1}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_longlong, value = 1})), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_longlong, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_longlong, value = "wrong"})), - ?match({ok, #any{typecode = tk_ulong, value = 1}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ulong, + ?match({ok, #any{typecode = tk_ulong, value = 1}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ulong, value = 1})), - ?match({ok, #any{typecode = tk_ulong, value = 4294967295}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ulong, + ?match({ok, #any{typecode = tk_ulong, value = 4294967295}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ulong, value = 4294967295})), ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ulong, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ulong, value = 4294967296})), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ulong, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ulong, value = -1})), - ?match({ok, #any{typecode = tk_ulonglong, value = 1}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ulonglong, + ?match({ok, #any{typecode = tk_ulonglong, value = 1}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ulonglong, value = 1})), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ulonglong, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_ulonglong, value = -1})), - ?match({ok, #any{typecode = tk_char, value = 98}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_char, + ?match({ok, #any{typecode = tk_char, value = 98}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_char, value = 98})), - ?match({ok, #any{typecode = tk_char, value = $b}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_char, + ?match({ok, #any{typecode = tk_char, value = $b}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_char, value = $b})), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_char, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_char, value = atomic})), - ?match({ok, #any{typecode = tk_wchar, value = 65535}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_wchar, + ?match({ok, #any{typecode = tk_wchar, value = 65535}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_wchar, value = 65535})), - ?match({ok, #any{typecode = tk_wchar, value = $b}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_wchar, + ?match({ok, #any{typecode = tk_wchar, value = $b}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_wchar, value = $b})), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_wchar, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_wchar, value = atomic})), - ?match({ok, #any{typecode = tk_boolean, value = true}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_boolean, + ?match({ok, #any{typecode = tk_boolean, value = true}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_boolean, value = true})), - ?match({ok, #any{typecode = tk_boolean, value = false}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_boolean, + ?match({ok, #any{typecode = tk_boolean, value = false}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_boolean, value = false})), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_boolean, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_boolean, value = 1})), - ?match({ok, #any{typecode = tk_octet, value = 1}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_octet, + ?match({ok, #any{typecode = tk_octet, value = 1}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_octet, value = 1})), - ?match({ok, #any{typecode = {tk_objref, "IDL:omg.org/orber_test/server:1.0", "server"}, value = Obj}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_objref, "IDL:omg.org/orber_test/server:1.0", "server"}, + ?match({ok, #any{typecode = {tk_objref, "IDL:omg.org/orber_test/server:1.0", "server"}, value = Obj}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_objref, "IDL:omg.org/orber_test/server:1.0", "server"}, value = Obj})), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_objref, "IDL:omg.org/orber_test/server:1.0", "server"}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_objref, "IDL:omg.org/orber_test/server:1.0", "server"}, value = "No Object"})), - ?match({ok, #any{typecode = {tk_string, 6}, value = "string"}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_string, 6}, + ?match({ok, #any{typecode = {tk_string, 6}, value = "string"}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_string, 6}, value = "string"})), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_string, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = tk_string, value = atomic})), - ?match({ok, #any{typecode = {tk_wstring, 1}, value = [65535]}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_wstring, 1}, + ?match({ok, #any{typecode = {tk_wstring, 1}, value = [65535]}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_wstring, 1}, value = [65535]})), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_wstring, 1}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_wstring, 1}, value = atomic})), - ?match({ok, #any{typecode = {tk_enum, "IDL:omg.org/orber_test/server/enumerant:1.0", "enumerant", ["one","two"]}, - value = two}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_enum, "IDL:omg.org/orber_test/server/enumerant:1.0", "enumerant", ["one","two"]}, + ?match({ok, #any{typecode = {tk_enum, "IDL:omg.org/orber_test/server/enumerant:1.0", "enumerant", ["one","two"]}, + value = two}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_enum, "IDL:omg.org/orber_test/server/enumerant:1.0", "enumerant", ["one","two"]}, value = two})), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_enum, "IDL:omg.org/orber_test/server/enumerant:1.0", "enumerant", ["one","two"]}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_enum, "IDL:omg.org/orber_test/server/enumerant:1.0", "enumerant", ["one","two"]}, value = three})), - ?match({ok, #any{typecode = {tk_sequence, tk_long, 3}, - value = [1,2,3]}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_sequence, tk_long, 3}, + ?match({ok, #any{typecode = {tk_sequence, tk_long, 3}, + value = [1,2,3]}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_sequence, tk_long, 3}, value = [1,2,3]})), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_sequence, tk_long, 3}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_sequence, tk_long, 3}, value = false})), - ?match({ok, #any{typecode = {tk_array,{tk_string,0},2}, - value = {"one", "two"}}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_array,{tk_string,0},2}, + ?match({ok, #any{typecode = {tk_array,{tk_string,0},2}, + value = {"one", "two"}}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_array,{tk_string,0},2}, value = {"one", "two"}})), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_array,{tk_string,0},2}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_array,{tk_string,0},2}, value = {"one", "two", "three"}})), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_array,{tk_string,0},2}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_array,{tk_string,0},2}, value = {1, 2}})), ?match({ok, #any{typecode = {tk_struct,"IDL:omg.org/orber_test/server/struc:1.0", "struc", - [{"a",tk_long},{"b",tk_short}]}, - value = #orber_test_server_struc{a=1, b=2}}}, + [{"a",tk_long},{"b",tk_short}]}, + value = #orber_test_server_struc{a=1, b=2}}}, orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_struct,"IDL:omg.org/orber_test/server/struc:1.0", "struc", [{"a",tk_long},{"b",tk_short}]}, value = #orber_test_server_struc{a=1, b=2}})), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_struct,"IDL:omg.org/orber_test/server/struc:1.0", "struc", - [{"a",tk_long},{"b",tk_short}]}, + [{"a",tk_long},{"b",tk_short}]}, value = #orber_test_server_struc{a=1, b="string"}})), - ?match({ok, #any{typecode = + ?match({ok, #any{typecode = {tk_union,"IDL:omg.org/orber_test/server/uni:1.0", - "uni", tk_long, -1, [{1,"a",tk_long}]}, - value = #orber_test_server_uni{label=1, value=66}}}, + "uni", tk_long, -1, [{1,"a",tk_long}]}, + value = #orber_test_server_uni{label=1, value=66}}}, orber_test_server: - testing_iiop_any(Obj, - #any{typecode = + testing_iiop_any(Obj, + #any{typecode = {tk_union,"IDL:omg.org/orber_test/server/uni:1.0", - "uni", tk_long, -1, [{1,"a",tk_long}]}, + "uni", tk_long, -1, [{1,"a",tk_long}]}, value = #orber_test_server_uni{label=1, value=66}})), case Local of true -> - ?match({ok, #any{typecode = + ?match({ok, #any{typecode = {tk_union,"IDL:omg.org/orber_test/server/uni:1.0", - "uni", tk_long, -1, [{1,"a",tk_long}]}, - value = #orber_test_server_uni{label=2, value=66}}}, + "uni", tk_long, -1, [{1,"a",tk_long}]}, + value = #orber_test_server_uni{label=2, value=66}}}, orber_test_server: testing_iiop_any(Obj, - #any{typecode = + #any{typecode = {tk_union,"IDL:omg.org/orber_test/server/uni:1.0", - "uni", tk_long, -1, [{1,"a",tk_long}]}, + "uni", tk_long, -1, [{1,"a",tk_long}]}, value = #orber_test_server_uni{label=2, value=66}})); false -> - ?match({ok, #any{typecode = + ?match({ok, #any{typecode = {tk_union,"IDL:omg.org/orber_test/server/uni:1.0", - "uni", tk_long, -1, [{1,"a",tk_long}]}, - value = #orber_test_server_uni{label=2, value=undefined}}}, + "uni", tk_long, -1, [{1,"a",tk_long}]}, + value = #orber_test_server_uni{label=2, value=undefined}}}, orber_test_server: testing_iiop_any(Obj, - #any{typecode = + #any{typecode = {tk_union,"IDL:omg.org/orber_test/server/uni:1.0", - "uni", tk_long, -1, [{1,"a",tk_long}]}, + "uni", tk_long, -1, [{1,"a",tk_long}]}, value = #orber_test_server_uni{label=2, value=66}})) end, - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server: - testing_iiop_any(Obj, - #any{typecode = + testing_iiop_any(Obj, + #any{typecode = {tk_union,"IDL:omg.org/orber_test/server/uni:1.0", - "uni", tk_long, -1, [{1,"a",tk_long}]}, + "uni", tk_long, -1, [{1,"a",tk_long}]}, value = #orber_test_server_uni{label=1, value="string"}})), - ?match({ok, #any{typecode = {tk_fixed,5,2}, - value = #fixed{digits = 5, scale = 2, value = 12345}}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_fixed,5,2}, - value = #fixed{digits = 5, - scale = 2, + ?match({ok, #any{typecode = {tk_fixed,5,2}, + value = #fixed{digits = 5, scale = 2, value = 12345}}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_fixed,5,2}, + value = #fixed{digits = 5, + scale = 2, value = 12345}})), - ?match({ok, #any{typecode = {tk_fixed,10,2}, - value = #fixed{digits = 10, scale = 2, value = 1234567890}}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_fixed,10,2}, - value = #fixed{digits = 10, - scale = 2, + ?match({ok, #any{typecode = {tk_fixed,10,2}, + value = #fixed{digits = 10, scale = 2, value = 1234567890}}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_fixed,10,2}, + value = #fixed{digits = 10, + scale = 2, value = 1234567890}})), - ?match({ok, #any{typecode = {tk_fixed,6,2}, - value = #fixed{digits = 6, scale = 2, value = 300000}}}, - orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_fixed,6,2}, - value = #fixed{digits = 6, - scale = 2, + ?match({ok, #any{typecode = {tk_fixed,6,2}, + value = #fixed{digits = 6, scale = 2, value = 300000}}}, + orber_test_server:testing_iiop_any(Obj, #any{typecode = {tk_fixed,6,2}, + value = #fixed{digits = 6, + scale = 2, value = 300000}})), - ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, + ?match({'EXCEPTION',{'MARSHAL',_,_,_}}, orber_test_server: testing_iiop_server_marshal(Obj, "string")), - + RecS = #orber_test_server_rec_struct{chain = [#orber_test_server_rec_struct{chain = []}]}, ?match(RecS, orber_test_server:testing_iiop_rec_struct(Obj, RecS)), - - RecU = #orber_test_server_rec_union{label = 'RecursiveType', + + RecU = #orber_test_server_rec_union{label = 'RecursiveType', value = [#orber_test_server_rec_union{label = 'RecursiveType', value = []}]}, ?match(RecU, orber_test_server:testing_iiop_rec_union(Obj, RecU)), %% RecA1 = #any{typecode = unsupported, value = RecS}, %% RecA2 = #any{typecode = unsupported, value = RecU}, -%% ?match(RecA1, -%% orber_test_server:testing_iiop_rec_any(Obj, RecA1)), -%% ?match(RecA2, -%% orber_test_server:testing_iiop_rec_any(Obj, RecA2)), +%% ?match(RecA1, +%% orber_test_server:testing_iiop_rec_any(Obj, RecA1)), +%% ?match(RecA2, +%% orber_test_server:testing_iiop_rec_any(Obj, RecA2)), ok. @@ -1333,14 +1373,14 @@ Result : ~p ok. %%--------------- Testing Missing Module --------------------- -oe_get_interface() -> +oe_get_interface() -> non_existing_module:tc(foo). %%--------------- INTERCEPTOR FUNCTIONS ---------------------- %%------------------------------------------------------------ %% function : new_in_connection -%% Arguments: -%% Returns : +%% Arguments: +%% Returns : %%------------------------------------------------------------ new_in_connection(Arg, CHost, Port) -> Host = node(), @@ -1354,14 +1394,14 @@ To Host : ~p To Port : ~p Peers : ~p Arg : ~p -==========================================~n", +==========================================~n", [Host, CHost, Port, SHost, SPort, Peers, Arg]), {Host}. %%------------------------------------------------------------ %% function : new_out_connection -%% Arguments: -%% Returns : +%% Arguments: +%% Returns : %%------------------------------------------------------------ new_out_connection(Arg, SHost, Port) -> Host = node(), @@ -1370,73 +1410,73 @@ Node : ~p To Host : ~p To Port : ~p Arg : ~p -==========================================~n", +==========================================~n", [Host, SHost, Port, Arg]), {Host}. %%------------------------------------------------------------ %% function : closed_in_connection -%% Arguments: -%% Returns : +%% Arguments: +%% Returns : %%------------------------------------------------------------ closed_in_connection(Arg) -> error_logger:info_msg("=============== closed_in_connection ===== Node : ~p Connection: ~p -==========================================~n", +==========================================~n", [node(), Arg]), Arg. %%------------------------------------------------------------ %% function : closed_out_connection -%% Arguments: -%% Returns : +%% Arguments: +%% Returns : %%------------------------------------------------------------ closed_out_connection(Arg) -> error_logger:info_msg("=============== closed_out_connection ==== Node : ~p Connection: ~p -==========================================~n", +==========================================~n", [node(), Arg]), Arg. %%------------------------------------------------------------ %% function : in_request_encoded -%% Arguments: -%% Returns : +%% Arguments: +%% Returns : %%------------------------------------------------------------ -in_request_encoded(Ref, _ObjKey, Ctx, Op, +in_request_encoded(Ref, _ObjKey, Ctx, Op, <<100:8,101:8,102:8,103:8,104:8,105:8,106:8,107:8,108:8,109:8,110:8,T/binary>>, _Args) -> error_logger:info_msg("=============== in_request_encoded ======= Connection: ~p Operation : ~p Body : ~p Context : ~p -==========================================~n", +==========================================~n", [Ref, Op, T, Ctx]), {T, "NewArgs"}. %%------------------------------------------------------------ %% function : in_reply_encoded -%% Arguments: -%% Returns : +%% Arguments: +%% Returns : %%------------------------------------------------------------ in_reply_encoded(Ref, _ObjKey, Ctx, Op, - <<100:8,101:8,102:8,103:8,104:8,105:8,106:8,107:8,108:8,109:8,110:8,T/binary>>, + <<100:8,101:8,102:8,103:8,104:8,105:8,106:8,107:8,108:8,109:8,110:8,T/binary>>, _Args) -> error_logger:info_msg("============== in_reply_encoded ========== Connection: ~p Operation : ~p Body : ~p Context : ~p -==========================================~n", +==========================================~n", [Ref, Op, T, Ctx]), {T, "NewArgs"}. %%------------------------------------------------------------ %% function : out_reply_encoded -%% Arguments: -%% Returns : +%% Arguments: +%% Returns : %%------------------------------------------------------------ out_reply_encoded(Ref, _ObjKey, Ctx, Op, List, _Args) -> error_logger:info_msg("============== out_reply_encoded ========= @@ -1444,14 +1484,14 @@ Connection: ~p Operation : ~p Body : ~p Context : ~p -==========================================~n", +==========================================~n", [Ref, Op, List, Ctx]), {list_to_binary([<<100:8,101:8,102:8,103:8,104:8,105:8,106:8,107:8,108:8,109:8,110:8>>|List]), "NewArgs"}. %%------------------------------------------------------------ %% function : out_request_encoded -%% Arguments: -%% Returns : +%% Arguments: +%% Returns : %%------------------------------------------------------------ out_request_encoded(Ref, _ObjKey, Ctx, Op, List, _Args) -> error_logger:info_msg("============== out_request_encoded ======= @@ -1459,14 +1499,14 @@ Connection: ~p Operation : ~p Body : ~p Context : ~p -==========================================~n", +==========================================~n", [Ref, Op, List, Ctx]), {list_to_binary([<<100:8,101:8,102:8,103:8,104:8,105:8,106:8,107:8,108:8,109:8,110:8>>|List]), "NewArgs"}. %%------------------------------------------------------------ %% function : in_request -%% Arguments: -%% Returns : +%% Arguments: +%% Returns : %%------------------------------------------------------------ in_request(Ref, _ObjKey, Ctx, Op, Params, _Args) -> error_logger:info_msg("=============== in_request =============== @@ -1474,14 +1514,14 @@ Connection: ~p Operation : ~p Parameters: ~p Context : ~p -==========================================~n", +==========================================~n", [Ref, Op, Params, Ctx]), {Params, "NewArgs"}. %%------------------------------------------------------------ %% function : in_reply -%% Arguments: -%% Returns : +%% Arguments: +%% Returns : %%------------------------------------------------------------ in_reply(Ref, _ObjKey, Ctx, Op, Reply, _Args) -> error_logger:info_msg("=============== in_reply ================= @@ -1489,14 +1529,14 @@ Connection: ~p Operation : ~p Reply : ~p Context : ~p -==========================================~n", +==========================================~n", [Ref, Op, Reply, Ctx]), {Reply, "NewArgs"}. %%------------------------------------------------------------ %% function : postinvoke -%% Arguments: -%% Returns : +%% Arguments: +%% Returns : %%------------------------------------------------------------ out_reply(Ref, _ObjKey, Ctx, Op, Reply, _Args) -> error_logger:info_msg("=============== out_reply ================ @@ -1504,14 +1544,14 @@ Connection: ~p Operation : ~p Reply : ~p Context : ~p -==========================================~n", +==========================================~n", [Ref, Op, Reply, Ctx]), {Reply, "NewArgs"}. %%------------------------------------------------------------ %% function : postinvoke -%% Arguments: -%% Returns : +%% Arguments: +%% Returns : %%------------------------------------------------------------ out_request(Ref, _ObjKey, Ctx, Op, Params, _Args) -> error_logger:info_msg("=============== out_request ============== @@ -1519,7 +1559,7 @@ Connection: ~p Operation : ~p Parameters: ~p Context : ~p -==========================================~n", +==========================================~n", [Ref, Op, Params, Ctx]), {Params, "NewArgs"}. diff --git a/lib/orber/vsn.mk b/lib/orber/vsn.mk index 29b21e8e01..0eac1e1410 100644 --- a/lib/orber/vsn.mk +++ b/lib/orber/vsn.mk @@ -1,3 +1,3 @@ -ORBER_VSN = 3.6.22 +ORBER_VSN = 3.6.23 diff --git a/lib/os_mon/src/os_mon_mib.erl b/lib/os_mon/src/os_mon_mib.erl index a4ce274a16..c972913b03 100644 --- a/lib/os_mon/src/os_mon_mib.erl +++ b/lib/os_mon/src/os_mon_mib.erl @@ -65,11 +65,11 @@ %% Shadow argument macros -define(loadShadowArgs, {loadTable, string, record_info(fields, loadTable), 5000, - {os_mon_mib, update_load_table}}). + fun os_mon_mib:update_load_table/0}). -define(diskShadowArgs, {diskTable, {integer, integer}, record_info(fields, diskTable), 5000, - {os_mon_mib, update_disk_table}}). + fun os_mon_mib:update_disk_table/0}). %% Misc -record(diskAlloc, {diskDescr, diskId}). diff --git a/lib/os_mon/test/os_mon_mib_SUITE.erl b/lib/os_mon/test/os_mon_mib_SUITE.erl index 4bd256a3f7..a137efc441 100644 --- a/lib/os_mon/test/os_mon_mib_SUITE.erl +++ b/lib/os_mon/test/os_mon_mib_SUITE.erl @@ -718,7 +718,7 @@ del_dir(Dir) -> {ok, Files} = file:list_dir(Dir), FullPathFiles = lists:map(fun(File) -> filename:join(Dir, File) end, Files), - lists:foreach({file, delete}, FullPathFiles), + lists:foreach(fun file:delete/1, FullPathFiles), file:del_dir(Dir). %%--------------------------------------------------------------------- diff --git a/lib/otp_mibs/src/otp_mib.erl b/lib/otp_mibs/src/otp_mib.erl index e8b0e51b91..1b0211df02 100644 --- a/lib/otp_mibs/src/otp_mib.erl +++ b/lib/otp_mibs/src/otp_mib.erl @@ -48,11 +48,11 @@ %% Shadow argument macros -define(erlNodeShadowArgs, {erlNodeTable, integer, record_info(fields, erlNodeTable), 5000, - {otp_mib, update_erl_node_table}}). + fun otp_mib:update_erl_node_table/0}). -define(applShadowArgs, {applTable, {integer, integer}, record_info(fields, applTable), - 5000, {otp_mib, update_appl_table}}). + 5000, fun otp_mib:update_appl_table/0}). %% Misc -record(erlNodeAlloc, {nodeName, nodeId}). diff --git a/lib/parsetools/include/yeccpre.hrl b/lib/parsetools/include/yeccpre.hrl index f638529aa4..3672394fc5 100644 --- a/lib/parsetools/include/yeccpre.hrl +++ b/lib/parsetools/include/yeccpre.hrl @@ -28,10 +28,11 @@ parse(Tokens) -> -spec parse_and_scan({function() | {atom(), atom()}, [_]} | {atom(), atom(), [_]}) -> yecc_ret(). -parse_and_scan({F, A}) -> % Fun or {M, F} +parse_and_scan({F, A}) -> yeccpars0([], {{F, A}, no_line}, 0, [], []); parse_and_scan({M, F, A}) -> - yeccpars0([], {{{M, F}, A}, no_line}, 0, [], []). + Arity = length(A), + yeccpars0([], {{fun M:F/Arity, A}, no_line}, 0, [], []). -spec format_error(any()) -> [char() | list()]. format_error(Message) -> diff --git a/lib/parsetools/test/yecc_SUITE.erl b/lib/parsetools/test/yecc_SUITE.erl index a5f66b48e9..3d26adf1be 100644 --- a/lib/parsetools/test/yecc_SUITE.erl +++ b/lib/parsetools/test/yecc_SUITE.erl @@ -1197,7 +1197,7 @@ yeccpre(Config) when is_list(Config) -> catch error: error -> ok end, - try parse_and_scan({{yecc_test, scan}, [exit]}) + try parse_and_scan({fun yecc_test:scan/1, [exit]}) catch exit: exit -> ok end, @@ -1650,10 +1650,11 @@ yeccpre_v1_2() -> parse(Tokens) -> yeccpars0(Tokens, false). -parse_and_scan({F, A}) -> % Fun or {M, F} +parse_and_scan({F, A}) -> yeccpars0([], {F, A}); parse_and_scan({M, F, A}) -> - yeccpars0([], {{M, F}, A}). + Arity = length(A), + yeccpars0([], {fun M:F/Arity, A}). format_error(Message) -> case io_lib:deep_char_list(Message) of diff --git a/lib/public_key/.gitignore b/lib/public_key/.gitignore new file mode 100644 index 0000000000..db24906676 --- /dev/null +++ b/lib/public_key/.gitignore @@ -0,0 +1,7 @@ +# public_key + +/lib/public_key/asn1/*.asn1db +/lib/public_key/asn1/*.erl +/lib/public_key/asn1/*.hrl +/lib/public_key/include/OTP-PUB-KEY.hrl +/lib/public_key/include/PKCS-FRAME.hrl diff --git a/lib/public_key/asn1/InformationFramework.asn1 b/lib/public_key/asn1/InformationFramework.asn1 deleted file mode 100644 index 40fbd11a2a..0000000000 --- a/lib/public_key/asn1/InformationFramework.asn1 +++ /dev/null @@ -1,682 +0,0 @@ -InformationFramework {joint-iso-itu-t ds(5) module(1) informationFramework(1) - 6} DEFINITIONS ::= -BEGIN - --- EXPORTS All --- The types and values defined in this module are exported for use in the other ASN.1 modules contained --- within the Directory Specifications, and for the use of other applications which will use them to access --- Directory services. Other applications may use them for their own purposes, but this will not constrain --- extensions and modifications needed to maintain or improve the Directory service. -IMPORTS - -- from ITU-T Rec. X.501 | ISO/IEC 9594-2 - directoryAbstractService, id-ar, id-at, id-mr, id-nf, id-oa, id-oc, - id-sc, selectedAttributeTypes, serviceAdministration - FROM UsefulDefinitions {joint-iso-itu-t ds(5) module(1) - usefulDefinitions(0) 6} - SearchRule - FROM ServiceAdministration serviceAdministration - -- from ITU-T Rec. X.511 | ISO/IEC 9594-3 - TypeAndContextAssertion - FROM DirectoryAbstractService directoryAbstractService - -- from ITU-T Rec. X.520 | ISO/IEC 9594-6 - booleanMatch, commonName, generalizedTimeMatch, generalizedTimeOrderingMatch, - integerFirstComponentMatch, integerMatch, integerOrderingMatch, - objectIdentifierFirstComponentMatch, UnboundedDirectoryString - FROM SelectedAttributeTypes selectedAttributeTypes; - --- attribute data types -Attribute{ATTRIBUTE:SupportedAttributes} ::= SEQUENCE { - type ATTRIBUTE.&id({SupportedAttributes}), - values - SET SIZE (0..MAX) OF ATTRIBUTE.&Type({SupportedAttributes}{@type}), - valuesWithContext - SET SIZE (1..MAX) OF - SEQUENCE {value ATTRIBUTE.&Type({SupportedAttributes}{@type}), - contextList SET SIZE (1..MAX) OF Context} OPTIONAL -} - -AttributeType ::= ATTRIBUTE.&id - -AttributeValue ::= ATTRIBUTE.&Type - -Context ::= SEQUENCE { - contextType CONTEXT.&id({SupportedContexts}), - contextValues - SET SIZE (1..MAX) OF CONTEXT.&Type({SupportedContexts}{@contextType}), - fallback BOOLEAN DEFAULT FALSE -} - -AttributeValueAssertion ::= SEQUENCE { - type ATTRIBUTE.&id({SupportedAttributes}), - assertion - ATTRIBUTE.&equality-match.&AssertionType - ({SupportedAttributes}{@type}), - assertedContexts - CHOICE {allContexts [0] NULL, - selectedContexts [1] SET SIZE (1..MAX) OF ContextAssertion - } OPTIONAL -} - -ContextAssertion ::= SEQUENCE { - contextType CONTEXT.&id({SupportedContexts}), - contextValues - SET SIZE (1..MAX) OF - CONTEXT.&Assertion({SupportedContexts}{@contextType}) -} - -AttributeTypeAssertion ::= SEQUENCE { - type ATTRIBUTE.&id({SupportedAttributes}), - assertedContexts SEQUENCE SIZE (1..MAX) OF ContextAssertion OPTIONAL -} - --- Definition of the following information object set is deferred, perhaps to standardized --- profiles or to protocol implementation conformance statements. The set is required to --- specify a table constraint on the values component of Attribute, the value component --- of AttributeTypeAndValue, and the assertion component of AttributeValueAssertion. -SupportedAttributes ATTRIBUTE ::= - {objectClass | aliasedEntryName, ...} - --- Definition of the following information object set is deferred, perhaps to standardized --- profiles or to protocol implementation conformance statements. The set is required to --- specify a table constraint on the context specifications -SupportedContexts CONTEXT ::= - {...} - --- naming data types -Name ::= CHOICE { -- only one possibility for now --rdnSequence RDNSequence -} - -RDNSequence ::= SEQUENCE OF RelativeDistinguishedName - -DistinguishedName ::= RDNSequence - -RelativeDistinguishedName ::= - SET SIZE (1..MAX) OF AttributeTypeAndDistinguishedValue - -AttributeTypeAndDistinguishedValue ::= SEQUENCE { - type ATTRIBUTE.&id({SupportedAttributes}), - value ATTRIBUTE.&Type({SupportedAttributes}{@type}), - primaryDistinguished BOOLEAN DEFAULT TRUE, - valuesWithContext - SET SIZE (1..MAX) OF - SEQUENCE {distingAttrValue - [0] ATTRIBUTE.&Type({SupportedAttributes}{@type}) - OPTIONAL, - contextList SET SIZE (1..MAX) OF Context} OPTIONAL -} - --- subtree data types -SubtreeSpecification ::= SEQUENCE { - base [0] LocalName DEFAULT {}, - COMPONENTS OF ChopSpecification, - specificationFilter [4] Refinement OPTIONAL -} - --- empty sequence specifies whole administrative area -LocalName ::= RDNSequence - -ChopSpecification ::= SEQUENCE { - specificExclusions - [1] SET SIZE (1..MAX) OF - CHOICE {chopBefore [0] LocalName, - chopAfter [1] LocalName} OPTIONAL, - minimum [2] BaseDistance DEFAULT 0, - maximum [3] BaseDistance OPTIONAL -} - -BaseDistance ::= INTEGER(0..MAX) - -Refinement ::= CHOICE { - item [0] OBJECT-CLASS.&id, - and [1] SET SIZE (1..MAX) OF Refinement, - or [2] SET SIZE (1..MAX) OF Refinement, - not [3] Refinement -} - --- OBJECT-CLASS information object class specification -OBJECT-CLASS ::= CLASS { - &Superclasses OBJECT-CLASS OPTIONAL, - &kind ObjectClassKind DEFAULT structural, - &MandatoryAttributes ATTRIBUTE OPTIONAL, - &OptionalAttributes ATTRIBUTE OPTIONAL, - &id OBJECT IDENTIFIER UNIQUE -} -WITH SYNTAX { - [SUBCLASS OF &Superclasses] - [KIND &kind] - [MUST CONTAIN &MandatoryAttributes] - [MAY CONTAIN &OptionalAttributes] - ID &id -} - -ObjectClassKind ::= ENUMERATED {abstract(0), structural(1), auxiliary(2)} - --- object classes -top OBJECT-CLASS ::= { - KIND abstract - MUST CONTAIN {objectClass} - ID id-oc-top -} - -alias OBJECT-CLASS ::= { - SUBCLASS OF {top} - MUST CONTAIN {aliasedEntryName} - ID id-oc-alias -} - -parent OBJECT-CLASS ::= {KIND abstract - ID id-oc-parent -} - -child OBJECT-CLASS ::= {KIND auxiliary - ID id-oc-child -} - --- ATTRIBUTE information object class specification -ATTRIBUTE ::= CLASS { - &derivation ATTRIBUTE OPTIONAL, - &Type OPTIONAL, -- either &Type or &derivation required - &equality-match MATCHING-RULE OPTIONAL, - &ordering-match MATCHING-RULE OPTIONAL, - &substrings-match MATCHING-RULE OPTIONAL, - &single-valued BOOLEAN DEFAULT FALSE, - &collective BOOLEAN DEFAULT FALSE, - &dummy BOOLEAN DEFAULT FALSE, - -- operational extensions - &no-user-modification BOOLEAN DEFAULT FALSE, - &usage AttributeUsage DEFAULT userApplications, - &id OBJECT IDENTIFIER UNIQUE -} -WITH SYNTAX { - [SUBTYPE OF &derivation] - [WITH SYNTAX &Type] - [EQUALITY MATCHING RULE &equality-match] - [ORDERING MATCHING RULE &ordering-match] - [SUBSTRINGS MATCHING RULE &substrings-match] - [SINGLE VALUE &single-valued] - [COLLECTIVE &collective] - [DUMMY &dummy] - [NO USER MODIFICATION &no-user-modification] - [USAGE &usage] - ID &id -} - -AttributeUsage ::= ENUMERATED { - userApplications(0), directoryOperation(1), distributedOperation(2), - dSAOperation(3)} - --- attributes -objectClass ATTRIBUTE ::= { - WITH SYNTAX OBJECT IDENTIFIER - EQUALITY MATCHING RULE objectIdentifierMatch - ID id-at-objectClass -} - -aliasedEntryName ATTRIBUTE ::= { - WITH SYNTAX DistinguishedName - EQUALITY MATCHING RULE distinguishedNameMatch - SINGLE VALUE TRUE - ID id-at-aliasedEntryName -} - --- MATCHING-RULE information object class specification -MATCHING-RULE ::= CLASS { - &ParentMatchingRules MATCHING-RULE OPTIONAL, - &AssertionType OPTIONAL, - &uniqueMatchIndicator ATTRIBUTE OPTIONAL, - &id OBJECT IDENTIFIER UNIQUE -} -WITH SYNTAX { - [PARENT &ParentMatchingRules] - [SYNTAX &AssertionType] - [UNIQUE-MATCH-INDICATOR &uniqueMatchIndicator] - ID &id -} - --- matching rules -objectIdentifierMatch MATCHING-RULE ::= { - SYNTAX OBJECT IDENTIFIER - ID id-mr-objectIdentifierMatch -} - -distinguishedNameMatch MATCHING-RULE ::= { - SYNTAX DistinguishedName - ID id-mr-distinguishedNameMatch -} - -MAPPING-BASED-MATCHING{SelectedBy, BOOLEAN:combinable, MappingResult, - OBJECT IDENTIFIER:matchingRule} ::= CLASS { - &selectBy SelectedBy OPTIONAL, - &ApplicableTo ATTRIBUTE, - &subtypesIncluded BOOLEAN DEFAULT TRUE, - &combinable BOOLEAN(combinable), - &mappingResults MappingResult OPTIONAL, - &userControl BOOLEAN DEFAULT FALSE, - &exclusive BOOLEAN DEFAULT TRUE, - &matching-rule MATCHING-RULE.&id(matchingRule), - &id OBJECT IDENTIFIER UNIQUE -} -WITH SYNTAX { - [SELECT BY &selectBy] - APPLICABLE TO &ApplicableTo - [SUBTYPES INCLUDED &subtypesIncluded] - COMBINABLE &combinable - [MAPPING RESULTS &mappingResults] - [USER CONTROL &userControl] - [EXCLUSIVE &exclusive] - MATCHING RULE &matching-rule - ID &id -} - --- NAME-FORM information object class specification -NAME-FORM ::= CLASS { - &namedObjectClass OBJECT-CLASS, - &MandatoryAttributes ATTRIBUTE, - &OptionalAttributes ATTRIBUTE OPTIONAL, - &id OBJECT IDENTIFIER UNIQUE -} -WITH SYNTAX { - NAMES &namedObjectClass - WITH ATTRIBUTES &MandatoryAttributes - [AND OPTIONALLY &OptionalAttributes] - ID &id -} - --- STRUCTURE-RULE class and DIT structure rule data types -DITStructureRule ::= SEQUENCE { - ruleIdentifier RuleIdentifier, - -- shall be unique within the scope of the subschema - nameForm NAME-FORM.&id, - superiorStructureRules SET SIZE (1..MAX) OF RuleIdentifier OPTIONAL -} - -RuleIdentifier ::= INTEGER - -STRUCTURE-RULE ::= CLASS { - &nameForm NAME-FORM, - &SuperiorStructureRules STRUCTURE-RULE OPTIONAL, - &id RuleIdentifier -} -WITH SYNTAX { - NAME FORM &nameForm - [SUPERIOR RULES &SuperiorStructureRules] - ID &id -} - --- DIT content rule data type and CONTENT-RULE class -DITContentRule ::= SEQUENCE { - structuralObjectClass OBJECT-CLASS.&id, - auxiliaries SET SIZE (1..MAX) OF OBJECT-CLASS.&id OPTIONAL, - mandatory [1] SET SIZE (1..MAX) OF ATTRIBUTE.&id OPTIONAL, - optional [2] SET SIZE (1..MAX) OF ATTRIBUTE.&id OPTIONAL, - precluded [3] SET SIZE (1..MAX) OF ATTRIBUTE.&id OPTIONAL -} - -CONTENT-RULE ::= CLASS { - &structuralClass OBJECT-CLASS.&id UNIQUE, - &Auxiliaries OBJECT-CLASS OPTIONAL, - &Mandatory ATTRIBUTE OPTIONAL, - &Optional ATTRIBUTE OPTIONAL, - &Precluded ATTRIBUTE OPTIONAL -} -WITH SYNTAX { - STRUCTURAL OBJECT-CLASS &structuralClass - [AUXILIARY OBJECT-CLASSES &Auxiliaries] - [MUST CONTAIN &Mandatory] - [MAY CONTAIN &Optional] - [MUST-NOT CONTAIN &Precluded] -} - -CONTEXT ::= CLASS { - &Type , - &DefaultValue OPTIONAL, - &Assertion OPTIONAL, - &absentMatch BOOLEAN DEFAULT TRUE, - &id OBJECT IDENTIFIER UNIQUE -} -WITH SYNTAX { - WITH SYNTAX &Type - [DEFAULT-VALUE &DefaultValue] - [ASSERTED AS &Assertion] - [ABSENT-MATCH &absentMatch] - ID &id -} - -DITContextUse ::= SEQUENCE { - attributeType ATTRIBUTE.&id, - mandatoryContexts [1] SET SIZE (1..MAX) OF CONTEXT.&id OPTIONAL, - optionalContexts [2] SET SIZE (1..MAX) OF CONTEXT.&id OPTIONAL -} - -DIT-CONTEXT-USE-RULE ::= CLASS { - &attributeType ATTRIBUTE.&id UNIQUE, - &Mandatory CONTEXT OPTIONAL, - &Optional CONTEXT OPTIONAL -} -WITH SYNTAX { - ATTRIBUTE TYPE &attributeType - [MANDATORY CONTEXTS &Mandatory] - [OPTIONAL CONTEXTS &Optional] -} - -FRIENDS ::= CLASS { - &anchor ATTRIBUTE.&id UNIQUE, - &Friends ATTRIBUTE -}WITH SYNTAX {ANCHOR &anchor - FRIENDS &Friends -} - --- system schema information objects --- object classes -subentry OBJECT-CLASS ::= { - SUBCLASS OF {top} - KIND structural - MUST CONTAIN {commonName | subtreeSpecification} - ID id-sc-subentry -} - -subentryNameForm NAME-FORM ::= { - NAMES subentry - WITH ATTRIBUTES {commonName} - ID id-nf-subentryNameForm -} - -subtreeSpecification ATTRIBUTE ::= { - WITH SYNTAX SubtreeSpecification - USAGE directoryOperation - ID id-oa-subtreeSpecification -} - -administrativeRole ATTRIBUTE ::= { - WITH SYNTAX OBJECT-CLASS.&id - EQUALITY MATCHING RULE objectIdentifierMatch - USAGE directoryOperation - ID id-oa-administrativeRole -} - -createTimestamp ATTRIBUTE ::= { - WITH SYNTAX GeneralizedTime - -- as per 46.3 b) or c) of ITU-T Rec. X.680 | ISO/IEC 8824-1 - EQUALITY MATCHING RULE generalizedTimeMatch - ORDERING MATCHING RULE generalizedTimeOrderingMatch - SINGLE VALUE TRUE - NO USER MODIFICATION TRUE - USAGE directoryOperation - ID id-oa-createTimestamp -} - -modifyTimestamp ATTRIBUTE ::= { - WITH SYNTAX GeneralizedTime - -- as per 46.3 b) or c) of ITU-T Rec. X.680 | ISO/IEC 8824-1 - EQUALITY MATCHING RULE generalizedTimeMatch - ORDERING MATCHING RULE generalizedTimeOrderingMatch - SINGLE VALUE TRUE - NO USER MODIFICATION TRUE - USAGE directoryOperation - ID id-oa-modifyTimestamp -} - -subschemaTimestamp ATTRIBUTE ::= { - WITH SYNTAX GeneralizedTime - -- as per 46.3 b) or c) of ITU-T Rec. X.680 | ISO/IEC 8824-1 - EQUALITY MATCHING RULE generalizedTimeMatch - ORDERING MATCHING RULE generalizedTimeOrderingMatch - SINGLE VALUE TRUE - NO USER MODIFICATION TRUE - USAGE directoryOperation - ID id-oa-subschemaTimestamp -} - -creatorsName ATTRIBUTE ::= { - WITH SYNTAX DistinguishedName - EQUALITY MATCHING RULE distinguishedNameMatch - SINGLE VALUE TRUE - NO USER MODIFICATION TRUE - USAGE directoryOperation - ID id-oa-creatorsName -} - -modifiersName ATTRIBUTE ::= { - WITH SYNTAX DistinguishedName - EQUALITY MATCHING RULE distinguishedNameMatch - SINGLE VALUE TRUE - NO USER MODIFICATION TRUE - USAGE directoryOperation - ID id-oa-modifiersName -} - -subschemaSubentryList ATTRIBUTE ::= { - WITH SYNTAX DistinguishedName - EQUALITY MATCHING RULE distinguishedNameMatch - SINGLE VALUE TRUE - NO USER MODIFICATION TRUE - USAGE directoryOperation - ID id-oa-subschemaSubentryList -} - -accessControlSubentryList ATTRIBUTE ::= { - WITH SYNTAX DistinguishedName - EQUALITY MATCHING RULE distinguishedNameMatch - NO USER MODIFICATION TRUE - USAGE directoryOperation - ID id-oa-accessControlSubentryList -} - -collectiveAttributeSubentryList ATTRIBUTE ::= { - WITH SYNTAX DistinguishedName - EQUALITY MATCHING RULE distinguishedNameMatch - NO USER MODIFICATION TRUE - USAGE directoryOperation - ID id-oa-collectiveAttributeSubentryList -} - -contextDefaultSubentryList ATTRIBUTE ::= { - WITH SYNTAX DistinguishedName - EQUALITY MATCHING RULE distinguishedNameMatch - NO USER MODIFICATION TRUE - USAGE directoryOperation - ID id-oa-contextDefaultSubentryList -} - -serviceAdminSubentryList ATTRIBUTE ::= { - WITH SYNTAX DistinguishedName - EQUALITY MATCHING RULE distinguishedNameMatch - NO USER MODIFICATION TRUE - USAGE directoryOperation - ID id-oa-serviceAdminSubentryList -} - -hasSubordinates ATTRIBUTE ::= { - WITH SYNTAX BOOLEAN - EQUALITY MATCHING RULE booleanMatch - SINGLE VALUE TRUE - NO USER MODIFICATION TRUE - USAGE directoryOperation - ID id-oa-hasSubordinates -} - -accessControlSubentry OBJECT-CLASS ::= { - KIND auxiliary - ID id-sc-accessControlSubentry -} - -collectiveAttributeSubentry OBJECT-CLASS ::= { - KIND auxiliary - ID id-sc-collectiveAttributeSubentry -} - -collectiveExclusions ATTRIBUTE ::= { - WITH SYNTAX OBJECT IDENTIFIER - EQUALITY MATCHING RULE objectIdentifierMatch - USAGE directoryOperation - ID id-oa-collectiveExclusions -} - -contextAssertionSubentry OBJECT-CLASS ::= { - KIND auxiliary - MUST CONTAIN {contextAssertionDefaults} - ID id-sc-contextAssertionSubentry -} - -contextAssertionDefaults ATTRIBUTE ::= { - WITH SYNTAX TypeAndContextAssertion - EQUALITY MATCHING RULE objectIdentifierFirstComponentMatch - USAGE directoryOperation - ID id-oa-contextAssertionDefault -} - -serviceAdminSubentry OBJECT-CLASS ::= { - KIND auxiliary - MUST CONTAIN {searchRules} - ID id-sc-serviceAdminSubentry -} - -searchRules ATTRIBUTE ::= { - WITH SYNTAX SearchRuleDescription - EQUALITY MATCHING RULE integerFirstComponentMatch - USAGE directoryOperation - ID id-oa-searchRules -} - -SearchRuleDescription ::= SEQUENCE { - COMPONENTS OF SearchRule, - name [28] SET SIZE (1..MAX) OF UnboundedDirectoryString OPTIONAL, - description [29] UnboundedDirectoryString OPTIONAL -} - -hierarchyLevel ATTRIBUTE ::= { - WITH SYNTAX HierarchyLevel - EQUALITY MATCHING RULE integerMatch - ORDERING MATCHING RULE integerOrderingMatch - SINGLE VALUE TRUE - NO USER MODIFICATION TRUE - USAGE directoryOperation - ID id-oa-hierarchyLevel -} - -HierarchyLevel ::= INTEGER - -hierarchyBelow ATTRIBUTE ::= { - WITH SYNTAX HierarchyBelow - EQUALITY MATCHING RULE booleanMatch - SINGLE VALUE TRUE - NO USER MODIFICATION TRUE - USAGE directoryOperation - ID id-oa-hierarchyBelow -} - -HierarchyBelow ::= BOOLEAN - -hierarchyParent ATTRIBUTE ::= { - WITH SYNTAX DistinguishedName - EQUALITY MATCHING RULE distinguishedNameMatch - SINGLE VALUE TRUE - USAGE directoryOperation - ID id-oa-hierarchyParent -} - -hierarchyTop ATTRIBUTE ::= { - WITH SYNTAX DistinguishedName - EQUALITY MATCHING RULE distinguishedNameMatch - SINGLE VALUE TRUE - USAGE directoryOperation - ID id-oa-hierarchyTop -} - --- object identifier assignments --- object classes -id-oc-top OBJECT IDENTIFIER ::= - {id-oc 0} - -id-oc-alias OBJECT IDENTIFIER ::= {id-oc 1} - -id-oc-parent OBJECT IDENTIFIER ::= {id-oc 28} - -id-oc-child OBJECT IDENTIFIER ::= {id-oc 29} - --- attributes -id-at-objectClass OBJECT IDENTIFIER ::= {id-at 0} - -id-at-aliasedEntryName OBJECT IDENTIFIER ::= {id-at 1} - --- matching rules -id-mr-objectIdentifierMatch OBJECT IDENTIFIER ::= {id-mr 0} - -id-mr-distinguishedNameMatch OBJECT IDENTIFIER ::= {id-mr 1} - --- operational attributes -id-oa-excludeAllCollectiveAttributes OBJECT IDENTIFIER ::= - {id-oa 0} - -id-oa-createTimestamp OBJECT IDENTIFIER ::= {id-oa 1} - -id-oa-modifyTimestamp OBJECT IDENTIFIER ::= {id-oa 2} - -id-oa-creatorsName OBJECT IDENTIFIER ::= {id-oa 3} - -id-oa-modifiersName OBJECT IDENTIFIER ::= {id-oa 4} - -id-oa-administrativeRole OBJECT IDENTIFIER ::= {id-oa 5} - -id-oa-subtreeSpecification OBJECT IDENTIFIER ::= {id-oa 6} - -id-oa-collectiveExclusions OBJECT IDENTIFIER ::= {id-oa 7} - -id-oa-subschemaTimestamp OBJECT IDENTIFIER ::= {id-oa 8} - -id-oa-hasSubordinates OBJECT IDENTIFIER ::= {id-oa 9} - -id-oa-subschemaSubentryList OBJECT IDENTIFIER ::= {id-oa 10} - -id-oa-accessControlSubentryList OBJECT IDENTIFIER ::= {id-oa 11} - -id-oa-collectiveAttributeSubentryList OBJECT IDENTIFIER ::= {id-oa 12} - -id-oa-contextDefaultSubentryList OBJECT IDENTIFIER ::= {id-oa 13} - -id-oa-contextAssertionDefault OBJECT IDENTIFIER ::= {id-oa 14} - -id-oa-serviceAdminSubentryList OBJECT IDENTIFIER ::= {id-oa 15} - -id-oa-searchRules OBJECT IDENTIFIER ::= {id-oa 16} - -id-oa-hierarchyLevel OBJECT IDENTIFIER ::= {id-oa 17} - -id-oa-hierarchyBelow OBJECT IDENTIFIER ::= {id-oa 18} - -id-oa-hierarchyParent OBJECT IDENTIFIER ::= {id-oa 19} - -id-oa-hierarchyTop OBJECT IDENTIFIER ::= {id-oa 20} - --- subentry classes -id-sc-subentry OBJECT IDENTIFIER ::= {id-sc 0} - -id-sc-accessControlSubentry OBJECT IDENTIFIER ::= {id-sc 1} - -id-sc-collectiveAttributeSubentry OBJECT IDENTIFIER ::= {id-sc 2} - -id-sc-contextAssertionSubentry OBJECT IDENTIFIER ::= {id-sc 3} - -id-sc-serviceAdminSubentry OBJECT IDENTIFIER ::= {id-sc 4} - --- Name forms -id-nf-subentryNameForm OBJECT IDENTIFIER ::= {id-nf 16} - --- administrative roles -id-ar-autonomousArea OBJECT IDENTIFIER ::= {id-ar 1} - -id-ar-accessControlSpecificArea OBJECT IDENTIFIER ::= {id-ar 2} - -id-ar-accessControlInnerArea OBJECT IDENTIFIER ::= {id-ar 3} - -id-ar-subschemaAdminSpecificArea OBJECT IDENTIFIER ::= {id-ar 4} - -id-ar-collectiveAttributeSpecificArea OBJECT IDENTIFIER ::= {id-ar 5} - -id-ar-collectiveAttributeInnerArea OBJECT IDENTIFIER ::= {id-ar 6} - -id-ar-contextDefaultSpecificArea OBJECT IDENTIFIER ::= {id-ar 7} - -id-ar-serviceSpecificArea OBJECT IDENTIFIER ::= {id-ar 8} - -END -- InformationFramework diff --git a/lib/public_key/asn1/Makefile b/lib/public_key/asn1/Makefile index 2ce1168349..943d97bdb8 100644 --- a/lib/public_key/asn1/Makefile +++ b/lib/public_key/asn1/Makefile @@ -40,7 +40,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/public_key-$(VSN) ASN_TOP = OTP-PUB-KEY PKCS-FRAME ASN_MODULES = PKIX1Explicit88 PKIX1Implicit88 PKIX1Algorithms88 \ - PKIXAttributeCertificate PKCS-1 PKCS-3 PKCS-8 InformationFramework PKCS5v2-0 OTP-PKIX + PKIXAttributeCertificate PKCS-1 PKCS-3 PKCS-8 PKCS5v2-0 OTP-PKIX ASN_ASNS = $(ASN_MODULES:%=%.asn1) ASN_ERLS = $(ASN_TOP:%=%.erl) ASN_HRLS = $(ASN_TOP:%=%.hrl) @@ -117,5 +117,4 @@ OTP-PUB-KEY.asn1db: PKIX1Algorithms88.asn1 \ $(EBIN)/PKCS-FRAME.beam: PKCS-FRAME.erl PKCS-FRAME.hrl PKCS-FRAME.erl PKCS-FRAME.hrl: PKCS-FRAME.asn1db PKCS-FRAME.asn1db: PKCS-8.asn1\ - InformationFramework.asn1\ PKCS5v2-0.asn1
\ No newline at end of file diff --git a/lib/public_key/asn1/PKCS-8.asn1 b/lib/public_key/asn1/PKCS-8.asn1 index 7413519b57..8412345b68 100644 --- a/lib/public_key/asn1/PKCS-8.asn1 +++ b/lib/public_key/asn1/PKCS-8.asn1 @@ -14,15 +14,15 @@ BEGIN -- All types and values defined in this module is exported for use in other -- ASN.1 modules. -IMPORTS +--IMPORTS -- informationFramework -- FROM UsefulDefinitions {joint-iso-itu-t(2) ds(5) module(1) -- usefulDefinitions(0) 3} -Attribute +--Attribute -- FROM InformationFramework informationFramework - FROM InformationFramework; +-- FROM InformationFramework; -- This import is really unnecessary since ALGORITHM-IDENTIFIER is defined as a -- TYPE-IDENTIFIER @@ -55,8 +55,8 @@ Version ::= INTEGER {v1(0)} (v1,...) PrivateKey ::= OCTET STRING --- Attributes ::= SET OF Attribute -Attributes ::= SET OF Attribute {{...}} +-- Attributes ::= SET OF PKAttribute +Attributes ::= SET OF PKAttribute {{...}} -- Encrypted private-key information syntax @@ -78,6 +78,66 @@ KeyEncryptionAlgorithms TYPE-IDENTIFIER ::= { ... -- For local profiles } +-- From InformationFramework +PKAttribute{ATTRIBUTE:SupportedAttributes} ::= SEQUENCE { + type ATTRIBUTE.&id({SupportedAttributes}), + values + SET SIZE (0..MAX) OF ATTRIBUTE.&Type({SupportedAttributes}{@type}), + valuesWithContext + SET SIZE (1..MAX) OF + SEQUENCE {value ATTRIBUTE.&Type({SupportedAttributes}{@type}), + contextList SET SIZE (1..MAX) OF Context} OPTIONAL +} + +Context ::= SEQUENCE { + contextType CONTEXT.&id({SupportedContexts}), + contextValues + SET SIZE (1..MAX) OF CONTEXT.&Type({SupportedContexts}{@contextType}), + fallback BOOLEAN DEFAULT FALSE +} +-- Definition of the following information object set is deferred, perhaps to standardized +-- profiles or to protocol implementation conformance statements. The set is required to +-- specify a table constraint on the context specifications +SupportedContexts CONTEXT ::= + {...} + + +CONTEXT ::= CLASS { + &Type , + &DefaultValue OPTIONAL, + &Assertion OPTIONAL, + &absentMatch BOOLEAN DEFAULT TRUE, + &id OBJECT IDENTIFIER UNIQUE +} + +-- ATTRIBUTE information object class specification +ATTRIBUTE ::= CLASS { + &derivation ATTRIBUTE OPTIONAL, + &Type OPTIONAL, -- either &Type or &derivation required + &equality-match MATCHING-RULE OPTIONAL, + &ordering-match MATCHING-RULE OPTIONAL, + &substrings-match MATCHING-RULE OPTIONAL, + &single-valued BOOLEAN DEFAULT FALSE, + &collective BOOLEAN DEFAULT FALSE, + &dummy BOOLEAN DEFAULT FALSE, + -- operational extensions + &no-user-modification BOOLEAN DEFAULT FALSE, + &usage AttributeUsage DEFAULT userApplications, + &id OBJECT IDENTIFIER UNIQUE +} + +-- MATCHING-RULE information object class specification +MATCHING-RULE ::= CLASS { + &ParentMatchingRules MATCHING-RULE OPTIONAL, + &AssertionType OPTIONAL, + &uniqueMatchIndicator ATTRIBUTE OPTIONAL, + &id OBJECT IDENTIFIER UNIQUE +} + +AttributeUsage ::= ENUMERATED { + userApplications(0), directoryOperation(1), distributedOperation(2), + dSAOperation(3)} + END diff --git a/lib/public_key/asn1/PKCS-FRAME.set.asn b/lib/public_key/asn1/PKCS-FRAME.set.asn index a0777ff260..69b6727bef 100644 --- a/lib/public_key/asn1/PKCS-FRAME.set.asn +++ b/lib/public_key/asn1/PKCS-FRAME.set.asn @@ -1,3 +1,2 @@ PKCS-8.asn1 -InformationFramework.asn1 PKCS5v2-0.asn1 diff --git a/lib/public_key/test/erl_make_certs.erl b/lib/public_key/test/erl_make_certs.erl index 8b01ca3ad4..254aa6d2f9 100644 --- a/lib/public_key/test/erl_make_certs.erl +++ b/lib/public_key/test/erl_make_certs.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010. All Rights Reserved. +%% Copyright Ericsson AB 2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -175,7 +175,7 @@ issuer(true, Opts, SubjectKey) -> issuer({Issuer, IssuerKey}, _Opts, _SubjectKey) when is_binary(Issuer) -> {issuer_der(Issuer), decode_key(IssuerKey)}; issuer({File, IssuerKey}, _Opts, _SubjectKey) when is_list(File) -> - {ok, [{cert, Cert, _}|_]} = public_key:pem_to_der(File), + {ok, [{cert, Cert, _}|_]} = pem_to_der(File), {issuer_der(Cert), decode_key(IssuerKey)}. issuer_der(Issuer) -> @@ -185,7 +185,7 @@ issuer_der(Issuer) -> Subject. subject(undefined, IsRootCA) -> - User = if IsRootCA -> "RootCA"; true -> os:getenv("USER") end, + User = if IsRootCA -> "RootCA"; true -> user() end, Opts = [{email, User ++ "@erlang.org"}, {name, User}, {city, "Stockholm"}, @@ -196,6 +196,14 @@ subject(undefined, IsRootCA) -> subject(Opts, _) -> subject(Opts). +user() -> + case os:getenv("USER") of + false -> + "test_user"; + User -> + User + end. + subject(SubjectOpts) when is_list(SubjectOpts) -> Encode = fun(Opt) -> {Type,Value} = subject_enc(Opt), diff --git a/lib/reltool/doc/src/reltool.xml b/lib/reltool/doc/src/reltool.xml index 31e15e34e7..60e886e8f5 100644 --- a/lib/reltool/doc/src/reltool.xml +++ b/lib/reltool/doc/src/reltool.xml @@ -558,7 +558,17 @@ target_spec() = [target_spec()] <c>true</c> there is no need to install the target system with <c>reltool:install/2</c> before it can be started. In that case the file tree containing the target system can be moved without - re-installation.</p></desc> + re-installation.</p> + + <p>In most cases, the <c>RootDir</c> parameter should be set to + the same as the <c>root_dir</c> configuration parameter used in + the call to <c>reltool:get_target_spec/1</c> + (or <c>code:root_dir()</c> if the configuration parameter is not + set). In some cases it might be useful to evaluate the same + target specification towards different root directories. This + should, however, be used with great care as it requires + equivalent file structures under all roots.</p> + </desc> </func> <func> @@ -640,7 +650,7 @@ target_spec() = [target_spec()] </func> <func> - <name>get_target_spec(Server) -> {ok, targetSpec} | {error, Reason}</name> + <name>get_target_spec(Server) -> {ok, TargetSpec} | {error, Reason}</name> <fsummary>Return a specification of the target system</fsummary> <type> <v>Server = server()</v> diff --git a/lib/sasl/doc/src/appup.xml b/lib/sasl/doc/src/appup.xml index 89bcf23b5e..195f9fe1d3 100644 --- a/lib/sasl/doc/src/appup.xml +++ b/lib/sasl/doc/src/appup.xml @@ -319,12 +319,37 @@ point_of_no_return <pre> restart_new_emulator </pre> - <p>Shuts down the current emulator and starts a ne one. All - processes are terminated gracefully. The new release must still - be made permanent when the new emulator is up and running. - Otherwise, the old emulator is started in case of a emulator - restart. This instruction should be used when a new emulator is - introduced, or if a complete reboot of the system should be done.</p> + <p>This instruction is used when erts, kernel, stdlib or sasl is + upgraded. It shuts down the current emulator and starts a new + one. All processes are terminated gracefully, and the new + version of erts, kernel, stdlib and sasl are used when the + emulator restarts. Only one <c>restart_new_emulator</c> + instruction is allowed in the relup, and it shall be placed + first. <seealso marker="systools#make_relup/3">systools:make_relup3,4</seealso> + will ensure this when the relup is generated. The rest of the + relup script is executed after the restart as a part of the boot + script.</p> + <p>An info report will be written when the upgrade is + completed. To programatically find out if the upgrade is + complete, + call <seealso marker="release_handler#which_release/0"> + release_handler:which_releases</seealso> and check if the + expected release has status <c>current</c>.</p> + <p>The new release must still be made permanent after the upgrade + is completed. Otherwise, the old emulator is started in case of + an emulator restart.</p> + <pre> +restart_emulator + </pre> + <p>This instruction is similar to <c>restart_new_emulator</c>, + except it shall be placed at the end of the relup script. It is + not related to an upgrade of the emulator or the core + applications, but can be used by any application when a complete + reboot of the system is reqiured. When generating the + relup, <seealso marker="systools#make_relup/3">systools:make_relup/3,4</seealso> + ensures that there is only one <c>restart_emulator</c> + instruction and that it is the last instruction of the + relup.</p> </section> <section> diff --git a/lib/sasl/doc/src/rb.xml b/lib/sasl/doc/src/rb.xml index f35ceb5777..3da825878e 100644 --- a/lib/sasl/doc/src/rb.xml +++ b/lib/sasl/doc/src/rb.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1996</year><year>2010</year> + <year>1996</year><year>2011</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -123,7 +123,9 @@ <fsummary>List all reports</fsummary> <type> <v>Type = type()</v> - <v>type() = crash_report | supervisor_report | error | progress</v> + <v>type() = error | error_report | info_msg | info_report | + warning_msg | warning_report | crash_report | + supervisor_report | progress</v> </type> <desc> <p>This function lists all reports loaded in the diff --git a/lib/sasl/doc/src/release_handler.xml b/lib/sasl/doc/src/release_handler.xml index 5ac0dc1acc..e3438ede41 100644 --- a/lib/sasl/doc/src/release_handler.xml +++ b/lib/sasl/doc/src/release_handler.xml @@ -64,10 +64,10 @@ downgraded to the specified version by evaluating the instructions in <c>relup</c>. An installed release can be made <em>permanent</em>. There can only be one permanent release in - the system, and this is the release that is used if the system is - restarted. An installed release, except the permanent one, can be - <em>removed</em>. When a release is removed, all files that - belong to that release only are deleted.</p> + the system, and this is the release that is used if the system + is restarted. An installed release, except the permanent one, + can be <em>removed</em>. When a release is removed, all files + that belong to that release only are deleted.</p> <p>Each version of the release has a status. The status can be <c>unpacked</c>, <c>current</c>, <c>permanent</c>, or <c>old</c>. There is always one latest release which either has status @@ -107,16 +107,17 @@ old reboot_old permanent restarted. This is taken care of automatically if Erlang is started as an embedded system. Read about this in <em>Embedded System</em>. In this case, the system configuration file <c>sys.config</c> is mandatory.</p> - <p>A new release may restart the system. Which program to use is - specified by the SASL configuration parameter <c>start_prg</c> - which defaults to <c>$ROOT/bin/start</c>.</p> + <p>The installation of a new release may restart the system. Which + program to use is specified by the SASL configuration + parameter <c>start_prg</c> which defaults + to <c>$ROOT/bin/start</c>.</p> <p>The emulator restart on Windows NT expects that the system is started using the <c>erlsrv</c> program (as a service). Furthermore the release handler expects that the service is named <em>NodeName</em>_<em>Release</em>, where <em>NodeName</em> is the first part of the Erlang nodename (up to, but not including - the "@") and <em>Release</em> is the current release of - the application. The release handler furthermore expects that a + the "@") and <em>Release</em> is the current version of + the release. The release handler furthermore expects that a program like <c>start_erl.exe</c> is specified as "machine" to <c>erlsrv</c>. During upgrading with restart, a new service will be registered and started. The new service will be set to @@ -238,7 +239,7 @@ old reboot_old permanent </func> <func> <name>install_release(Vsn) -> {ok, OtherVsn, Descr} | {error, Reason}</name> - <name>install_release(Vsn, [Opt]) -> {ok, OtherVsn, Descr} | {error, Reason}</name> + <name>install_release(Vsn, [Opt]) -> {ok, OtherVsn, Descr} | {continue_after_restart, OtherVsn, Descr} | {error, Reason}</name> <fsummary>Install a release in the system.</fsummary> <type> <v>Vsn = OtherVsn = string()</v> @@ -248,7 +249,8 @@ old reboot_old permanent <v> Timeout = default | infinity | int()>0</v> <v> Bool = boolean()</v> <v>Descr = term()</v> - <v>Reason = {illegal_option, Opt} | {already_installed, Vsn} | {change_appl_data, term()} | term()</v> + <v>Reason = {illegal_option, Opt} | {already_installed, Vsn} | {change_appl_data, term()} | {missing_base_app, OtherVsn, App} | {could_not_create_hybrid_boot, term()} | term()</v> + <v>App = atom()</v> </type> <desc> <p>Installs the specified version <c>Vsn</c> of the release. @@ -268,6 +270,15 @@ old reboot_old permanent <c>OtherVsn</c> and <c>Descr</c> are the version (<c>UpFromVsn</c> or <c>Vsn</c>) and description (<c>Descr1</c> or <c>Descr2</c>) as specified in the script.</p> + <p>If <c>{continue_after_restart,OtherVsn,Descr}</c> is + returned, it means that the emulator will be restarted + before the upgrade instructions are executed. This will + happen if the emulator or any of the applications kernel, + stdlib or sasl are updated. The new version of the emulator + and these core applications will execute after the restart, + but for all other applications the old versions will be + started and the upgrade will be performed as normal by + executing the upgrade instructions.</p> <p>If a recoverable error occurs, the function returns <c>{error,Reason}</c> and the original application specifications are restored. If a non-recoverable error @@ -325,6 +336,18 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). upgrade, but it will allow checks and purge to be executed in the background before the real upgrade is started.</p> </note> + <note> + <p>When upgrading the emulator from a version older than OTP + R15, there will be an attempt to load new application beam + code into the old emulator. In some cases, the new beam + format can not be read by the old emulator, and so the code + loading will fail and terminate the complete upgrade. To + overcome this problem, the new application code should be + compiled with the old emulator. See <seealso + marker="doc/design_principles:appup_cookbook">Design + Principles</seealso> for more information about emulator + upgrade from pre OTP R15 versions.</p> + </note> </desc> </func> <func> @@ -431,6 +454,18 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). <p>Returns all releases known to the release handler.</p> </desc> </func> + <func> + <name>which_releases(Status) -> [{Name, Vsn, Apps, Status}]</name> + <fsummary>Return all known releases of a specific status</fsummary> + <type> + <v>Name = Vsn = string()</v> + <v>Apps = ["App-Vsn"]</v> + <v>Status = unpacked | current | permanent | old</v> + </type> + <desc> + <p>Returns all releases known to the release handler of a specific status.</p> + </desc> + </func> </funcs> <section> @@ -442,7 +477,7 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). and evaluated exactly in the same way as <c>release_handler</c> does.</p> <warning> - <p>These function is primarily intended for simplified testing of + <p>These functions are primarily intended for simplified testing of <c>.appup</c> files. They are not run within the context of the <c>release_handler</c> process. They must therefore <em>not</em> be used together with calls to @@ -450,7 +485,7 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). <c>release_handler</c> to end up in an inconsistent state.</p> <p>No persistent information is updated, why these functions can be used on any Erlang node, embedded or not. Also, using these - functions does not effect which code will be loaded in case of + functions does not affect which code will be loaded in case of a reboot.</p> <p>If the upgrade or downgrade fails, the application may end up in an inconsistent state.</p> @@ -458,7 +493,7 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). </section> <funcs> <func> - <name>upgrade_app(App, Dir) -> {ok, Unpurged} | restart_new_emulator | {error, Reason}</name> + <name>upgrade_app(App, Dir) -> {ok, Unpurged} | restart_emulator | {error, Reason}</name> <fsummary>Upgrade to a new application version</fsummary> <type> <v>App = atom()</v> @@ -487,14 +522,21 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). does.</p> <p>Returns <c>{ok, Unpurged}</c> if evaluating the script is successful, where <c>Unpurged</c> is a list of unpurged - modules, or <c>restart_new_emulator</c> if this instruction is + modules, or <c>restart_emulator</c> if this instruction is encountered in the script, or <c>{error, Reason}</c> if an error occurred when finding or evaluating the script.</p> + <p>If the <c>restart_new_emulator</c> instruction is found in + the script, <c>upgrade_app/2</c> will return + <c>{error,restart_new_emulator}</c>. The reason for this is + that this instruction requires that a new version of the + emulator is started before the rest of the upgrade + instructions can be executed, and this can only be done by + <c>install_release/1,2</c>.</p> </desc> </func> <func> <name>downgrade_app(App, Dir) -></name> - <name>downgrade_app(App, OldVsn, Dir) -> {ok, Unpurged} | restart_new_emulator | {error, Reason}</name> + <name>downgrade_app(App, OldVsn, Dir) -> {ok, Unpurged} | restart_emulator | {error, Reason}</name> <fsummary>Downgrade to a previous application version</fsummary> <type> <v>App = atom()</v> @@ -528,7 +570,7 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). does.</p> <p>Returns <c>{ok, Unpurged}</c> if evaluating the script is successful, where <c>Unpurged</c> is a list of unpurged - modules, or <c>restart_new_emulator</c> if this instruction is + modules, or <c>restart_emulator</c> if this instruction is encountered in the script, or <c>{error, Reason}</c> if an error occurred when finding or evaluating the script.</p> </desc> @@ -604,7 +646,7 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). </desc> </func> <func> - <name>eval_appup_script(App, ToVsn, ToDir, Script) -> {ok, Unpurged} | restart_new_emulator | {error, Reason}</name> + <name>eval_appup_script(App, ToVsn, ToDir, Script) -> {ok, Unpurged} | restart_emulator | {error, Reason}</name> <fsummary>Evaluate an application upgrade or downgrade script</fsummary> <type> <v>App = atom()</v> @@ -617,8 +659,8 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). <desc> <p>Evaluates an application upgrade or downgrade script <c>Script</c>, the result from calling - <seealso marker="#upgrade_app/2">upgrade_app/2</seealso> or - <seealso marker="#downgrade_app/3">downgrade_app/2,3</seealso>, + <seealso marker="#upgrade_app/2">upgrade_script/2</seealso> or + <seealso marker="#downgrade_app/3">downgrade_script/3</seealso>, exactly in the same way as <seealso marker="#install_release/1">install_release/1,2</seealso> does.</p> @@ -629,9 +671,16 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). <c>.appup</c> files should be located under <c>Dir/ebin</c>.</p> <p>Returns <c>{ok, Unpurged}</c> if evaluating the script is successful, where <c>Unpurged</c> is a list of unpurged - modules, or <c>restart_new_emulator</c> if this instruction is + modules, or <c>restart_emulator</c> if this instruction is encountered in the script, or <c>{error, Reason}</c> if an error occurred when evaluating the script.</p> + <p>If the <c>restart_new_emulator</c> instruction is found in + the script, <c>eval_appup_script/4</c> will return + <c>{error,restart_new_emulator}</c>. The reason for this is + that this instruction requires that a new version of the + emulator is started before the rest of the upgrade + instructions can be executed, and this can only be done by + <c>install_release/1,2</c>.</p> </desc> </func> </funcs> diff --git a/lib/sasl/doc/src/systools.xml b/lib/sasl/doc/src/systools.xml index 8c1c327d74..32c2149a8d 100644 --- a/lib/sasl/doc/src/systools.xml +++ b/lib/sasl/doc/src/systools.xml @@ -111,6 +111,11 @@ low-level instruction to restart the emulator is appended to the relup scripts. This ensures that a complete reboot of the system is done when the system is upgraded or downgraded.</p> + <p>If an upgrade includes a change from an emulator earlier + than OTP R15 to OTP R15 or later, the warning + <c>pre_R15_emulator_upgrade</c> is issued. See <seealso + marker="doc/design_principles:appup_cookbook">Design + Principles</seealso> for more information about this.</p> <p>By default, errors and warnings are printed to tty and the function returns <c>ok</c> or <c>error</c>. If the option <c>silent</c> is provided, the function instead returns @@ -133,8 +138,9 @@ <fsummary>Generate a boot script <c>.script/.boot</c>.</fsummary> <type> <v>Name = string()</v> - <v>Opt = src_tests | {path,[Dir]} | local | {variables,[Var]} | exref | {exref,[App]}] - | silent | {outdir,Dir} | warnings_as_errors</v> + <v>Opt = src_tests | {path,[Dir]} | local | {variables,[Var]} | exref | + {exref,[App]}] | silent | {outdir,Dir} | no_warn_sasl | + warnings_as_errors</v> <v> Dir = string()</v> <v> Var = {VarName,Prefix}</v> <v> VarName = Prefix = string()</v> @@ -190,6 +196,10 @@ <p>The applications are sorted according to the dependencies between the applications. Where there are no dependencies, the order in the <c>.rel</c> file is kept.</p> + <p>If <c>sasl</c> is not included as an application in + the <c>.rel</c> file, a warning is emitted because such a + release can not be used in an upgrade. To turn off this + warning, add the option <c>no_warn_sasl</c>.</p> <p>All files are searched for in the current path. It is assumed that the <c>.app</c> and <c>.beam</c> files for an application is located in the same directory. The <c>.erl</c> @@ -220,7 +230,7 @@ <p>Example: If the option <c>{variables,[{"TEST","lib"}]}</c> is supplied, and <c>myapp.app</c> is found in <c>lib/myapp/ebin</c>, then the path to this application in - the boot script will be <c>$TEST/myapp-1/ebin"</c>. If + the boot script will be <c>"$TEST/myapp-1/ebin"</c>. If <c>myapp.app</c> is found in <c>lib/test</c>, then the path will be <c>$TEST/test/myapp-1/ebin</c>.</p> <p>The checks performed before the boot script is generated can diff --git a/lib/sasl/examples/src/target_system.erl b/lib/sasl/examples/src/target_system.erl index 0e1e0b2324..ffc0fcf443 100644 --- a/lib/sasl/examples/src/target_system.erl +++ b/lib/sasl/examples/src/target_system.erl @@ -16,6 +16,7 @@ %% %% %CopyrightEnd% %% +%module -module(target_system). -export([create/1, create/2, install/2]). @@ -130,14 +131,14 @@ install(RelFileName, RootDir) -> [ErlVsn, _RelVsn| _] = string:tokens(StartErlData, " \n"), ErtsBinDir = filename:join([RootDir, "erts-" ++ ErlVsn, "bin"]), BinDir = filename:join([RootDir, "bin"]), - io:fwrite("Substituting in erl.src, start.src and start_erl.src to\n" + io:fwrite("Substituting in erl.src, start.src and start_erl.src to " "form erl, start and start_erl ...\n"), subst_src_scripts(["erl", "start", "start_erl"], ErtsBinDir, BinDir, [{"FINAL_ROOTDIR", RootDir}, {"EMU", "beam"}], [preserve]), io:fwrite("Creating the RELEASES file ...\n"), - create_RELEASES(RootDir, - filename:join([RootDir, "releases", RelFileName])). + create_RELEASES(RootDir, filename:join([RootDir, "releases", + filename:basename(RelFileName)])). %% LOCALS @@ -257,3 +258,4 @@ remove_all_files(Dir, Files) -> file:delete(FilePath) end end, Files). +%module diff --git a/lib/sasl/src/release_handler.erl b/lib/sasl/src/release_handler.erl index bc08f94dff..522c7b496b 100644 --- a/lib/sasl/src/release_handler.erl +++ b/lib/sasl/src/release_handler.erl @@ -26,8 +26,9 @@ create_RELEASES/1, create_RELEASES/2, create_RELEASES/4, unpack_release/1, check_install_release/1, check_install_release/2, - install_release/1, install_release/2, remove_release/1, - which_releases/0, make_permanent/1, reboot_old_release/1, + install_release/1, install_release/2, new_emulator_upgrade/2, + remove_release/1, which_releases/0, which_releases/1, + make_permanent/1, reboot_old_release/1, set_unpacked/2, set_removed/1, install_file/2]). -export([upgrade_app/2, downgrade_app/2, downgrade_app/3, upgrade_script/2, downgrade_script/3, @@ -40,7 +41,7 @@ %% Internal exports, a client release_handler may call this functions. -export([do_write_release/3, do_copy_file/2, do_copy_files/2, do_copy_files/1, do_rename_files/1, do_remove_files/1, - do_write_file/2, do_ensure_RELEASES/1]). + remove_file/1, do_write_file/2, do_ensure_RELEASES/1]). -record(state, {unpurged = [], root, @@ -61,10 +62,11 @@ %% remove - %% current make_permanent permanent %% install other old +%% restart node unpacked %% remove - %% permanent make other permanent old %% install permanent -%% old reboot permanen +%% old reboot_old permanent %% install current %% remove - %%----------------------------------------------------------------- @@ -74,6 +76,14 @@ -define(timeout, 10000). %%----------------------------------------------------------------- +%% The version set on the temporary release that will be used when the +%% emulator is upgraded. +-define(tmp_vsn(__BaseVsn__), "__new_emulator__"++__BaseVsn__). + + + + +%%----------------------------------------------------------------- %% Assumes the following file structure: %% root --- lib --- Appl-Vsn1 --- <src> %% | | |- ebin @@ -183,11 +193,15 @@ check_check_install_options([],Purge) -> %%----------------------------------------------------------------- %% Purpose: Executes the relup script for the specified version. %% The release must be unpacked. -%% Returns: {ok, FromVsn, Descr} | {error, Reason} +%% Returns: {ok, FromVsn, Descr} | +%% {continue_after_restart, FromVsn, Descr} | +%% {error, Reason} %% Reason = {already_installed, Vsn} | %% {bad_relup_file, RelFile} | %% {no_such_release, Vsn} | %% {no_such_from_vsn, Vsn} | +%% {could_not_create_hybrid_boot,Why} | +%% {missing_base_app,Vsn,App} | %% {illegal_option, Opt}} | %% exit_reason() %%----------------------------------------------------------------- @@ -230,6 +244,21 @@ check_timeout(Int) when is_integer(Int), Int > 0 -> true; check_timeout(_Else) -> false. %%----------------------------------------------------------------- +%% Purpose: Called by boot script after emulator is restarted due to +%% new erts version. +%% Returns: Same as install_release/2 +%% If this crashes, the emulator restart will fail +%% (since the function is called from the boot script) +%% and there will be a rollback. +%%----------------------------------------------------------------- +new_emulator_upgrade(Vsn, Opts) -> + Result = call({install_release, Vsn, reboot, Opts}), + error_logger:info_msg( + "~p:install_release(~p,~p) completed after node restart " + "with new emulator version~nResult: ~p~n",[?MODULE,Vsn,Opts,Result]), + Result. + +%%----------------------------------------------------------------- %% Purpose: Makes the specified release version be the one that is %% used when the system starts (or restarts). %% The release must be installed (not unpacked). @@ -305,6 +334,14 @@ which_releases() -> call(which_releases). %%----------------------------------------------------------------- +%% Returns: [{Name, Vsn, [LibName], Status}] +%% Status = unpacked | current | permanent | old +%%----------------------------------------------------------------- +which_releases(Status) -> + Releases = which_releases(), + get_releases_with_status(Releases, Status, []). + +%%----------------------------------------------------------------- %% check_script(Script, LibDirs) -> ok | {error, Reason} %%----------------------------------------------------------------- check_script(Script, LibDirs) -> @@ -313,7 +350,7 @@ check_script(Script, LibDirs) -> %%----------------------------------------------------------------- %% eval_script(Script, Apps, LibDirs, NewLibs, Opts) -> %% {ok, UnPurged} | -%% restart_new_emulator | +%% restart_emulator | %% {error, Error} %% {'EXIT', Reason} %% If sync_nodes is present, the calling process must have called @@ -350,7 +387,7 @@ create_RELEASES(Root, RelDir, RelFile, LibDirs) -> %%----------------------------------------------------------------- %% Func: upgrade_app(App, Dir) -> {ok, Unpurged} -%% | restart_new_emulator +%% | restart_emulator %% | {error, Error} %% Types: %% App = atom() @@ -370,7 +407,7 @@ upgrade_app(App, NewDir) -> %%----------------------------------------------------------------- %% Func: downgrade_app(App, Dir) %% downgrade_app(App, Vsn, Dir) -> {ok, Unpurged} -%% | restart_new_emulator +%% | restart_emulator %% | {error, Error} %% Types: %% App = atom() @@ -578,7 +615,7 @@ handle_call({check_install_release, Vsn, Purge}, _From, S) -> handle_call({install_release, Vsn, ErrorAction, Opts}, From, S) -> NS = resend_sync_nodes(S), case catch do_install_release(S, Vsn, Opts) of - {ok, NewReleases, CurrentVsn, Descr} -> + {ok, NewReleases, [], CurrentVsn, Descr} -> {reply, {ok, CurrentVsn, Descr}, NS#state{releases=NewReleases}}; {ok, NewReleases, Unpurged, CurrentVsn, Descr} -> Timer = @@ -593,10 +630,14 @@ handle_call({install_release, Vsn, ErrorAction, Opts}, From, S) -> {reply, {ok, CurrentVsn, Descr}, NewS}; {error, Reason} -> {reply, {error, Reason}, NS}; - {restart_new_emulator, CurrentVsn, Descr} -> + {restart_emulator, CurrentVsn, Descr} -> gen_server:reply(From, {ok, CurrentVsn, Descr}), init:reboot(), {noreply, NS}; + {restart_new_emulator, CurrentVsn, Descr} -> + gen_server:reply(From, {continue_after_restart, CurrentVsn, Descr}), + init:reboot(), + {noreply, NS}; {'EXIT', Reason} -> io:format("release_handler:" "install_release(Vsn=~p Opts=~p) failed, " @@ -801,8 +842,13 @@ do_unpack_release(Root, RelDir, ReleaseName, Releases) -> extract_tar(Root, Tar), NewReleases = [Release#release{status = unpacked} | Releases], write_releases(RelDir, NewReleases, false), + + %% Keeping this for backwards compatibility reasons with older + %% systools:make_tar, where there is no copy of the .rel file in + %% the releases/<vsn> dir. See OTP-9746. Dir = filename:join([RelDir, Vsn]), copy_file(RelFile, Dir, false), + {ok, NewReleases, Vsn}. %% Note that this function is not executed by a client @@ -941,7 +987,38 @@ do_install_release(#state{start_prg = StartPrg, {value, Release} -> LatestRelease = get_latest_release(Releases), case get_rh_script(LatestRelease, Release, RelDir, Masters) of + {ok, {_CurrentVsn, _Descr, [restart_new_emulator|_Script]}} + when Static == true -> + throw(static_emulator); + {ok, {CurrentVsn, Descr, [restart_new_emulator|_Script]}} -> + %% This will only happen if the upgrade includes + %% an emulator upgrade (and it is not a downgrade) + %% - then the new emulator must be started before + %% new code can be loaded. + %% Create a temporary release which includes new + %% emulator, kernel, stdlib and sasl - and old + %% versions of other applications. + {TmpVsn,TmpRelease} = + new_emulator_make_tmp_release(LatestRelease,Release, + RelDir,Opts,Masters), + NReleases = [TmpRelease|Releases], + + %% Then uppgrade to the temporary release. + %% The rest of the upgrade will continue after the restart + prepare_restart_new_emulator(StartPrg, RootDir, + RelDir, TmpVsn, TmpRelease, + NReleases, Masters), + {restart_new_emulator, CurrentVsn, Descr}; {ok, {CurrentVsn, Descr, Script}} -> + %% In case there has been an emulator upgrade, + %% remove the temporary release + NReleases = + new_emulator_rm_tmp_release( + LatestRelease#release.vsn, + LatestRelease#release.erts_vsn, + Vsn,RelDir,Releases,Masters), + + %% Then execute the relup script mon_nodes(true), EnvBefore = application_controller:prep_config_change(), Apps = change_appl_data(RelDir, Release, Masters), @@ -949,31 +1026,19 @@ do_install_release(#state{start_prg = StartPrg, NewLibs = get_new_libs(LatestRelease#release.libs, Release#release.libs), case eval_script(Script, Apps, LibDirs, NewLibs, Opts) of - {ok, []} -> - application_controller:config_change(EnvBefore), - mon_nodes(false), - NewReleases = set_status(Vsn, current, Releases), - {ok, NewReleases, CurrentVsn, Descr}; {ok, Unpurged} -> application_controller:config_change(EnvBefore), mon_nodes(false), - NewReleases = set_status(Vsn, current, Releases), - {ok, NewReleases, Unpurged, CurrentVsn, Descr}; - restart_new_emulator when Static == true -> + NReleases1 = set_status(Vsn, current, NReleases), + {ok, NReleases1, Unpurged, CurrentVsn, Descr}; + restart_emulator when Static == true -> throw(static_emulator); - restart_new_emulator -> + restart_emulator -> mon_nodes(false), - {value, PermanentRelease} = - lists:keysearch(permanent, #release.status, - Releases), - NReleases = set_status(Vsn, current, Releases), - NReleases2 = set_status(Vsn,tmp_current,NReleases), - write_releases(RelDir, NReleases2, Masters), prepare_restart_new_emulator(StartPrg, RootDir, - RelDir, Release, - PermanentRelease, - Masters), - {restart_new_emulator, CurrentVsn, Descr}; + RelDir, Vsn, Release, + NReleases, Masters), + {restart_emulator, CurrentVsn, Descr}; Else -> application_controller:config_change(EnvBefore), mon_nodes(false), @@ -986,6 +1051,158 @@ do_install_release(#state{start_prg = StartPrg, {error, {no_such_release, Vsn}} end. +new_emulator_make_tmp_release(CurrentRelease,ToRelease,RelDir,Opts,Masters) -> + CurrentVsn = CurrentRelease#release.vsn, + ToVsn = ToRelease#release.vsn, + TmpVsn = ?tmp_vsn(CurrentVsn), + case get_base_libs(ToRelease#release.libs) of + {ok,{Kernel,Stdlib,Sasl}=BaseLibs,_} -> + case get_base_libs(ToRelease#release.libs) of + {ok,_,RestLibs} -> + TmpErtsVsn = ToRelease#release.erts_vsn, + TmpLibs = [Kernel,Stdlib,Sasl|RestLibs], + TmpRelease = CurrentRelease#release{vsn=TmpVsn, + erts_vsn=TmpErtsVsn, + libs = TmpLibs, + status = unpacked}, + new_emulator_make_hybrid_boot(CurrentVsn,ToVsn,TmpVsn, + BaseLibs,RelDir,Opts,Masters), + new_emulator_make_hybrid_config(CurrentVsn,ToVsn,TmpVsn, + RelDir,Masters), + {TmpVsn,TmpRelease}; + {error,{missing,Missing}} -> + throw({error,{missing_base_app,CurrentVsn,Missing}}) + end; + {error,{missing,Missing}} -> + throw({error,{missing_base_app,ToVsn,Missing}}) + end. + +%% Get kernel, stdlib and sasl libs, +%% and also return the rest of the libs as a list. +%% Return error if any of kernel, stdlib or sasl does not exist. +get_base_libs(Libs) -> + get_base_libs(Libs,undefined,undefined,undefined,[]). +get_base_libs([{kernel,_,_}=Kernel|Libs],undefined,Stdlib,Sasl,Rest) -> + get_base_libs(Libs,Kernel,Stdlib,Sasl,Rest); +get_base_libs([{stdlib,_,_}=Stdlib|Libs],Kernel,undefined,Sasl,Rest) -> + get_base_libs(Libs,Kernel,Stdlib,Sasl,Rest); +get_base_libs([{sasl,_,_}=Sasl|Libs],Kernel,Stdlib,undefined,Rest) -> + get_base_libs(Libs,Kernel,Stdlib,Sasl,Rest); +get_base_libs([Lib|Libs],Kernel,Stdlib,Sasl,Rest) -> + get_base_libs(Libs,Kernel,Stdlib,Sasl,[Lib|Rest]); +get_base_libs([],undefined,_Stdlib,_Sasl,_Rest) -> + {error,{missing,kernel}}; +get_base_libs([],_Kernel,undefined,_Sasl,_Rest) -> + {error,{missing,stdlib}}; +get_base_libs([],_Kernel,_Stdlib,undefined,_Rest) -> + {error,{missing,sasl}}; +get_base_libs([],Kernel,Stdlib,Sasl,Rest) -> + {ok,{Kernel,Stdlib,Sasl},lists:reverse(Rest)}. + +new_emulator_make_hybrid_boot(CurrentVsn,ToVsn,TmpVsn,BaseLibs,RelDir,Opts,Masters) -> + FromBootFile = filename:join([RelDir,CurrentVsn,"start.boot"]), + ToBootFile = filename:join([RelDir,ToVsn,"start.boot"]), + TmpBootFile = filename:join([RelDir,TmpVsn,"start.boot"]), + ensure_dir(TmpBootFile,Masters), + Args = [ToVsn,Opts], + {ok,FromBoot} = read_file(FromBootFile,Masters), + {ok,ToBoot} = read_file(ToBootFile,Masters), + {{_,_,KernelPath},{_,_,SaslPath},{_,_,StdlibPath}} = BaseLibs, + Paths = {filename:join(KernelPath,"ebin"), + filename:join(StdlibPath,"ebin"), + filename:join(SaslPath,"ebin")}, + case systools_make:make_hybrid_boot(TmpVsn,FromBoot,ToBoot,Paths,Args) of + {ok,TmpBoot} -> + write_file(TmpBootFile,TmpBoot,Masters); + {error,Reason} -> + throw({error,{could_not_create_hybrid_boot,Reason}}) + end. + +new_emulator_make_hybrid_config(CurrentVsn,ToVsn,TmpVsn,RelDir,Masters) -> + FromFile = filename:join([RelDir,CurrentVsn,"sys.config"]), + ToFile = filename:join([RelDir,ToVsn,"sys.config"]), + TmpFile = filename:join([RelDir,TmpVsn,"sys.config"]), + + FromConfig = + case consult(FromFile,Masters) of + {ok,[FC]} -> + FC; + {error,Error1} -> + io:format("Warning: ~p can not read ~p: ~p~n", + [?MODULE,FromFile,Error1]), + [] + end, + + [Kernel,Stdlib,Sasl] = + case consult(ToFile,Masters) of + {ok,[ToConfig]} -> + [lists:keyfind(App,1,ToConfig) || App <- [kernel,stdlib,sasl]]; + {error,Error2} -> + io:format("Warning: ~p can not read ~p: ~p~n", + [?MODULE,ToFile,Error2]), + [false,false,false] + end, + + Config1 = replace_config(kernel,FromConfig,Kernel), + Config2 = replace_config(stdlib,Config1,Stdlib), + Config3 = replace_config(sasl,Config2,Sasl), + + ConfigStr = io_lib:format("~p.~n",[Config3]), + write_file(TmpFile,ConfigStr,Masters). + +%% Take the configuration for application App from the new config and +%% insert in the old config. +%% If no entry exists in the new config, then delete the entry (if it exists) +%% from the old config. +%% If entry exists in the new config, but not in the old config, then +%% add the entry. +replace_config(App,Config,false) -> + lists:keydelete(App,1,Config); +replace_config(App,Config,AppConfig) -> + lists:keystore(App,1,Config,AppConfig). + +%% Remove all files related to the temporary release +new_emulator_rm_tmp_release(?tmp_vsn(_)=TmpVsn,EVsn,NewVsn, + RelDir,Releases,Masters) -> + case os:type() of + {win32, nt} -> + rename_tmp_service(EVsn,TmpVsn,NewVsn); + _ -> + ok + end, + remove_dir(filename:join(RelDir,TmpVsn),Masters), + lists:keydelete(TmpVsn,#release.vsn,Releases); +new_emulator_rm_tmp_release(_,_,_,_,Releases,_) -> + Releases. + +%% Rename the tempoarary service (for erts ugprade) to the real ToVsn +rename_tmp_service(EVsn,TmpVsn,NewVsn) -> + FromName = hd(string:tokens(atom_to_list(node()),"@")) ++ "_" ++ TmpVsn, + ToName = hd(string:tokens(atom_to_list(node()),"@")) ++ "_" ++ NewVsn, + case erlsrv:get_service(EVsn,ToName) of + {error, _Error} -> + ok; + _Data -> + erlsrv:remove_service(ToName) + end, + rename_service(EVsn,FromName,ToName). + + +%% Rename a service and check that it succeeded +rename_service(EVsn,FromName,ToName) -> + case erlsrv:rename_service(EVsn,FromName,ToName) of + {ok,_} -> + case erlsrv:get_service(EVsn,ToName) of + {error,Error1} -> + throw({error,Error1}); + _Data2 -> + ok + end; + Error2 -> + throw({error,{service_rename_failed, Error2}}) + end. + + %%% This code chunk updates the services in one of two ways, %%% Either the emulator is restarted, in which case the old service %%% is to be removed and the new enabled, or the emulator is NOT restarted @@ -1002,26 +1219,16 @@ do_make_services_permanent(PermanentVsn,Vsn, PermanentEVsn, EVsn) -> %% rename. case os:getenv("ERLSRV_SERVICE_NAME") == PermName of true -> - case erlsrv:rename_service(EVsn,PermName,Name) of - {ok,_} -> - case erlsrv:get_service(EVsn,Name) of - {error,Error2} -> - throw({error,Error2}); - _Data2 -> - %% The interfaces for doing this are - %% NOT published and may be subject to - %% change. Do NOT do this anywhere else! - - os:putenv("ERLSRV_SERVICE_NAME", Name), - - %% Restart heart port program, this - %% function is only to be used here. - heart:cycle(), - ok - end; - Error3 -> - throw({error,{service_rename_failed, Error3}}) - end; + rename_service(EVsn,PermName,Name), + %% The interfaces for doing this are + %% NOT published and may be subject to + %% change. Do NOT do this anywhere else! + + os:putenv("ERLSRV_SERVICE_NAME", Name), + + %% Restart heart port program, this + %% function is only to be used here. + heart:cycle(); false -> throw({error,service_name_missmatch}) end; @@ -1260,21 +1467,31 @@ do_set_removed(RelDir, Vsn, Releases, Masters) -> %% corresponding relup instructions, we check if it's possible to %% downgrade from CurrentVsn to ToVsn. %%----------------------------------------------------------------- +get_rh_script(#release{vsn = ?tmp_vsn(CurrentVsn)}, + #release{vsn = ToVsn}, + RelDir, + Masters) -> + {ok,{Vsn,Descr,[restart_new_emulator|Script]}} = + do_get_rh_script(CurrentVsn,ToVsn,RelDir,Masters), + {ok,{Vsn,Descr,Script}}; get_rh_script(#release{vsn = CurrentVsn}, - #release{vsn = Vsn}, + #release{vsn = ToVsn}, RelDir, Masters) -> - Relup = filename:join([RelDir, Vsn, "relup"]), - case try_upgrade(Vsn, CurrentVsn, Relup, Masters) of + do_get_rh_script(CurrentVsn,ToVsn,RelDir,Masters). + +do_get_rh_script(CurrentVsn, ToVsn, RelDir, Masters) -> + Relup = filename:join([RelDir, ToVsn, "relup"]), + case try_upgrade(ToVsn, CurrentVsn, Relup, Masters) of {ok, RhScript} -> {ok, RhScript}; _ -> Relup2 = filename:join([RelDir, CurrentVsn,"relup"]), - case try_downgrade(Vsn, CurrentVsn, Relup2, Masters) of + case try_downgrade(ToVsn, CurrentVsn, Relup2, Masters) of {ok, RhScript} -> {ok, RhScript}; _ -> - throw({error, {no_matching_relup, Vsn, CurrentVsn}}) + throw({error, {no_matching_relup, ToVsn, CurrentVsn}}) end end. @@ -1487,6 +1704,15 @@ prepare_restart_nt(#release{erts_vsn = EVsn, vsn = Vsn}, %% restart is performed by calling init:reboot() higher up. %%----------------------------------------------------------------- prepare_restart_new_emulator(StartPrg, RootDir, RelDir, + Vsn, Release, Releases, Masters) -> + {value, PRelease} = lists:keysearch(permanent, #release.status,Releases), + NReleases1 = set_status(Vsn, current, Releases), + NReleases2 = set_status(Vsn,tmp_current,NReleases1), + write_releases(RelDir, NReleases2, Masters), + prepare_restart_new_emulator(StartPrg, RootDir, RelDir, + Release, PRelease, Masters). + +prepare_restart_new_emulator(StartPrg, RootDir, RelDir, Release, PRelease, Masters) -> #release{erts_vsn = EVsn, vsn = Vsn} = Release, Data = EVsn ++ " " ++ Vsn, @@ -1512,19 +1738,10 @@ check_start_prg({do_check, StartPrg}, Masters) -> check_start_prg({_, StartPrg}, _) -> StartPrg. -write_new_start_erl(Data, RelDir, false) -> - DataFile = filename:join([RelDir, "new_start_erl.data"]), - case do_write_file(DataFile, Data) of - ok -> DataFile; - Error -> throw(Error) - end; write_new_start_erl(Data, RelDir, Masters) -> DataFile = filename:join([RelDir, "new_start_erl.data"]), - case at_all_masters(Masters, ?MODULE, do_write_file, - [DataFile, Data]) of - ok -> DataFile; - Error -> throw(Error) - end. + write_file(DataFile, Data, Masters), + DataFile. %%----------------------------------------------------------------- %% When a new emulator shall be restarted, the current release @@ -1538,27 +1755,41 @@ write_new_start_erl(Data, RelDir, Masters) -> %% If the release is made permanent, this is written to disk. %%----------------------------------------------------------------- transform_release(ReleaseDir, Releases, Masters) -> - F = fun(Release) when Release#release.status == tmp_current -> - Release#release{status = unpacked}; - (Release) -> Release - end, - case lists:map(F, Releases) of - Releases -> - Releases; - DReleases -> + case init:script_id() of + {Name, ?tmp_vsn(_)=TmpVsn} -> + %% This is was a reboot due to a new emulator version. The + %% current release is a temporary internal release, which + %% must be removed. It is the "real new release" that is + %% set to unpacked on disk and current in memory. + DReleases = lists:keydelete(TmpVsn,#release.vsn,Releases), write_releases(ReleaseDir, DReleases, Masters), - F1 = fun(Release) when Release#release.status == tmp_current -> - case init:script_id() of - {_Name, Vsn} when Release#release.vsn == Vsn -> - Release#release{status = current}; - _ -> - Release#release{status = unpacked} - end; - (Release) -> Release - end, - lists:map(F1, Releases) + set_current({Name,TmpVsn},Releases); + ScriptId -> + F = fun(Release) when Release#release.status == tmp_current -> + Release#release{status = unpacked}; + (Release) -> Release + end, + case lists:map(F, Releases) of + Releases -> + Releases; + DReleases -> + write_releases(ReleaseDir, DReleases, Masters), + set_current(ScriptId, Releases) + end end. +set_current(ScriptId, Releases) -> + F1 = fun(Release) when Release#release.status == tmp_current -> + case ScriptId of + {_Name,Vsn} when Release#release.vsn == Vsn -> + Release#release{status = current}; + _ -> + Release#release{status = unpacked} + end; + (Release) -> Release + end, + lists:map(F1, Releases). + %%----------------------------------------------------------------- %% Functions handling files, RELEASES, start_erl.data etc. %% This functions consider if the release_handler is a client and @@ -1617,12 +1848,25 @@ extract_tar(Root, Tar) -> throw({error, {cannot_extract_file, Name, Reason}}) end. -write_releases(Dir, NewReleases, false) -> +write_releases(Dir, Releases, Masters) -> + %% We must never write 'current' to disk, since this will confuse + %% us after a node restart - since we would then have a permanent + %% release running, but state set to current for a non-running + %% release. + NewReleases = lists:zf(fun(Release) when Release#release.status == current -> + {true, Release#release{status = unpacked}}; + (_) -> + true + end, Releases), + write_releases_1(Dir, NewReleases, Masters). + + +write_releases_1(Dir, NewReleases, false) -> case do_write_release(Dir, "RELEASES", NewReleases) of ok -> ok; Error -> throw(Error) end; -write_releases(Dir, NewReleases, Masters) -> +write_releases_1(Dir, NewReleases, Masters) -> all_masters(Masters), write_releases_m(Dir, NewReleases, Masters). @@ -1844,6 +2088,37 @@ read_file(File, false) -> read_file(File, Masters) -> read_master(Masters, File). +write_file(File, Data, false) -> + case file:write_file(File, Data) of + ok -> ok; + Error -> throw(Error) + end; +write_file(File, Data, Masters) -> + case at_all_masters(Masters, file, write_file, [File, Data]) of + ok -> ok; + Error -> throw(Error) + end. + +ensure_dir(File, false) -> + case filelib:ensure_dir(File) of + ok -> ok; + Error -> throw(Error) + end; +ensure_dir(File, Masters) -> + case at_all_masters(Masters,filelib,ensure_dir,[File]) of + ok -> ok; + Error -> throw(Error) + end. + +remove_dir(Dir, false) -> + remove_file(Dir); +remove_dir(Dir, Masters) -> + case at_all_masters(Masters,?MODULE,remove_file,[Dir]) of + ok -> ok; + Error -> throw(Error) + end. + + %% Ignore status of each delete ! remove_files(Master, Files, Masters) -> takewhile(Master, Masters, ?MODULE, do_remove_files, [Files]). @@ -2010,3 +2285,14 @@ get_new_libs([{App,Vsn,_LibDir}|CurrentLibs], NewLibs) -> end; get_new_libs([],_) -> []. + +%%----------------------------------------------------------------- +%% Return a list of releases witch a specific status +%%----------------------------------------------------------------- +get_releases_with_status([], _, Acc) -> + Acc; +get_releases_with_status([ {_, _, _, ReleaseStatus } = Head | Tail], + Status, Acc) when ReleaseStatus == Status -> + get_releases_with_status(Tail, Status, [Head | Acc]); +get_releases_with_status([_ | Tail], Status, Acc) -> + get_releases_with_status(Tail, Status, Acc). diff --git a/lib/sasl/src/release_handler_1.erl b/lib/sasl/src/release_handler_1.erl index 8d0baf3ab1..93d12cf609 100644 --- a/lib/sasl/src/release_handler_1.erl +++ b/lib/sasl/src/release_handler_1.erl @@ -47,26 +47,38 @@ %%%----------------------------------------------------------------- %%% This is a low-level release handler. %%%----------------------------------------------------------------- +check_script([restart_new_emulator|Script], LibDirs) -> + %% There is no need to check for old processes, since the node + %% will be restarted before anything else happens. + do_check_script(Script, LibDirs, []); check_script(Script, LibDirs) -> case catch check_old_processes(Script,soft_purge) of {ok, PurgeMods} -> - {Before, _After} = split_instructions(Script), - case catch lists:foldl(fun(Instruction, EvalState1) -> - eval(Instruction, EvalState1) - end, - #eval_state{libdirs = LibDirs}, - Before) of - EvalState2 when is_record(EvalState2, eval_state) -> - {ok,PurgeMods}; - {error, Error} -> - {error, Error}; - Other -> - {error, Other} - end; + do_check_script(Script, LibDirs, PurgeMods); {error, Mod} -> {error, {old_processes, Mod}} end. +do_check_script(Script, LibDirs, PurgeMods) -> + {Before, After} = split_instructions(Script), + case catch lists:foldl(fun(Instruction, EvalState1) -> + eval(Instruction, EvalState1) + end, + #eval_state{libdirs = LibDirs}, + Before) of + EvalState2 when is_record(EvalState2, eval_state) -> + case catch syntax_check_script(After) of + ok -> + {ok,PurgeMods}; + Other -> + {error,Other} + end; + {error, Error} -> + {error, Error}; + Other -> + {error, Other} + end. + %% eval_script/1 - For testing only - no apps added, just testing instructions eval_script(Script) -> eval_script(Script, [], [], [], []). @@ -83,22 +95,30 @@ eval_script(Script, Apps, LibDirs, NewLibs, Opts) -> newlibs = NewLibs, opts = Opts}, Before) of - EvalState2 when is_record(EvalState2, eval_state) -> - case catch lists:foldl(fun(Instruction, EvalState3) -> - eval(Instruction, EvalState3) - end, - EvalState2, - After) of - EvalState4 when is_record(EvalState4, eval_state) -> - {ok, EvalState4#eval_state.unpurged}; - restart_new_emulator -> - restart_new_emulator; - Error -> - {'EXIT', Error} - end; - {error, Error} -> {error, Error}; - Other -> {error, Other} - end; + EvalState2 when is_record(EvalState2, eval_state) -> + case catch syntax_check_script(After) of + ok -> + case catch lists:foldl( + fun(Instruction, EvalState3) -> + eval(Instruction, + EvalState3) + end, + EvalState2, + After) of + EvalState4 + when is_record(EvalState4, eval_state) -> + {ok, EvalState4#eval_state.unpurged}; + restart_emulator -> + restart_emulator; + Error -> + {'EXIT', Error} + end; + Other -> + {error,Other} + end; + {error, Error} -> {error, Error}; + Other -> {error, Other} + end; {error, Mod} -> {error, {old_processes, Mod}} end. @@ -174,6 +194,42 @@ do_check_old_code(Mod,Procs) -> [Mod]. +%% Check the last part of the script, i.e. the part after point_of_no_return. +%% More or less a syntax check in case the script was handwritten. +syntax_check_script([point_of_no_return | Script]) -> + syntax_check_script(Script); +syntax_check_script([{load, {_,_,_}} | Script]) -> + syntax_check_script(Script); +syntax_check_script([{remove, {_,_,_}} | Script]) -> + syntax_check_script(Script); +syntax_check_script([{purge, _} | Script]) -> + syntax_check_script(Script); +syntax_check_script([{suspend, _} | Script]) -> + syntax_check_script(Script); +syntax_check_script([{resume, _} | Script]) -> + syntax_check_script(Script); +syntax_check_script([{code_change, _} | Script]) -> + syntax_check_script(Script); +syntax_check_script([{code_change, _, _} | Script]) -> + syntax_check_script(Script); +syntax_check_script([{stop, _} | Script]) -> + syntax_check_script(Script); +syntax_check_script([{start, _} | Script]) -> + syntax_check_script(Script); +syntax_check_script([{sync_nodes, _, {_,_,_}} | Script]) -> + syntax_check_script(Script); +syntax_check_script([{sync_nodes, _, _} | Script]) -> + syntax_check_script(Script); +syntax_check_script([{apply, {_,_,_}} | Script]) -> + syntax_check_script(Script); +syntax_check_script([restart_emulator | Script]) -> + syntax_check_script(Script); +syntax_check_script([Illegal | _Script]) -> + throw({illegal_instruction_after_point_of_no_return,Illegal}); +syntax_check_script([]) -> + ok. + + %%----------------------------------------------------------------- %% An unpurged module is a module for which there exist an old %% version of the code. This should only be the case if there are @@ -243,7 +299,7 @@ do_check_old_code(Mod,Procs) -> %% must also exectue the same line. Waits for all these nodes to get %% to this line. %% point_of_no_return -%% restart_new_emulator +%% restart_emulator %% {stop_application, Appl} - Impl with apply %% {unload_application, Appl} - Impl with {remove..} %% {load_application, Appl} - Impl with {load..} @@ -402,6 +458,8 @@ eval({sync_nodes, Id, Nodes}, EvalState) -> eval({apply, {M, F, A}}, EvalState) -> apply(M, F, A), EvalState; +eval(restart_emulator, _EvalState) -> + throw(restart_emulator); eval(restart_new_emulator, _EvalState) -> throw(restart_new_emulator). @@ -447,15 +505,20 @@ resume(Pids) -> change_code(Pids, Mod, Vsn, Extra, Timeout) -> Fun = fun(Pid) -> - case Timeout of - default -> - ok = sys:change_code(Pid, Mod, Vsn, Extra); - _Else -> - ok = sys:change_code(Pid, Mod, Vsn, Extra, Timeout) + case sys_change_code(Pid, Mod, Vsn, Extra, Timeout) of + ok -> + ok; + {error,Reason} -> + throw({code_change_failed,Pid,Mod,Vsn,Reason}) end end, lists:foreach(Fun, Pids). +sys_change_code(Pid, Mod, Vsn, Extra, default) -> + sys:change_code(Pid, Mod, Vsn, Extra); +sys_change_code(Pid, Mod, Vsn, Extra, Timeout) -> + sys:change_code(Pid, Mod, Vsn, Extra, Timeout). + stop(Mod, Procs) -> lists:zf(fun({undefined, _Name, _Pid, _Mods}) -> false; diff --git a/lib/sasl/src/sasl.appup.src b/lib/sasl/src/sasl.appup.src index 64c653a4e5..ce4aa1f8f8 100644 --- a/lib/sasl/src/sasl.appup.src +++ b/lib/sasl/src/sasl.appup.src @@ -1,25 +1,27 @@ -%% +%% -*- erlang -*- %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1999-2011. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% -%% %CopyrightEnd% %% - +%% %CopyrightEnd% {"%VSN%", - [{"2.1.4", [{load_module, release_handler}, - {load_module, systools_relup}]}], - [{"2.1.4", [{load_module, release_handler}, - {load_module, systools_relup}]}] + %% Up from - max two major revisions back + [{<<"2\\.2(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R15 + {<<"2\\.1\\.10(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R14B04 (and later?) + {<<"2\\.1\\.[6-9](\\.[0-9]+)*">>,[restart_new_emulator]}],%% R13B-R14B03 + %% Down to - max two major revisions back + [{<<"2\\.2(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R15 + {<<"2\\.1\\.10(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R14B04 (and later?) + {<<"2\\.1\\.[6-9](\\.[0-9]+)*">>,[restart_new_emulator]}] %% R13B-R14B03 }. diff --git a/lib/sasl/src/systools_make.erl b/lib/sasl/src/systools_make.erl index 7f400f5cce..8fd90c50f9 100644 --- a/lib/sasl/src/systools_make.erl +++ b/lib/sasl/src/systools_make.erl @@ -31,6 +31,8 @@ -export([read_application/4]). +-export([make_hybrid_boot/5]). + -import(lists, [filter/2, keysort/2, keysearch/3, map/2, reverse/1, append/1, foldl/3, member/2, foreach/2]). @@ -56,6 +58,7 @@ %% {variables,[{Name,AbsString}]} %% {machine, jam | beam | vee} %% exref | {exref, [AppName]} +%% no_warn_sasl %%----------------------------------------------------------------- make_script(RelName) when is_list(RelName) -> @@ -86,7 +89,8 @@ make_script(RelName, Output, Flags) when is_list(RelName), Path = make_set(Path1 ++ code:get_path()), ModTestP = {member(src_tests, Flags),xref_p(Flags)}, case get_release(RelName, Path, ModTestP, machine(Flags)) of - {ok, Release, Appls, Warnings} -> + {ok, Release, Appls, Warnings0} -> + Warnings = wsasl(Flags, Warnings0), case systools_lib:werror(Flags, Warnings) of true -> return(ok,Warnings,Flags); @@ -110,7 +114,13 @@ make_script(RelName, _Output, Flags) when is_list(Flags) -> make_script(RelName, _Output, Flags) -> badarg(Flags,[RelName, Flags]). -%% Inlined. + +wsasl(Options, Warnings) -> + case lists:member(no_warn_sasl,Options) of + true -> lists:delete({warning,missing_sasl},Warnings); + false -> Warnings + end. + badarg(BadArg, Args) -> erlang:error({badarg,BadArg}, Args). @@ -162,6 +172,118 @@ return({error,Mod,Error},_,Flags) -> error end. + +%%----------------------------------------------------------------- +%% Make hybrid boot file for upgrading emulator. The resulting boot +%% file is a combination of the two input files, where kernel, stdlib +%% and sasl versions are taken from the second file (the boot file of +%% the new release), and all other application versions from the first +%% file (the boot file of the old release). +%% +%% The most important thing that can fail here is that the input boot +%% files do not contain all three base applications - kernel, stdlib +%% and sasl. +%% +%% TmpVsn = string(), +%% Paths = {KernelPath,StdlibPath,SaslPath} +%% Returns {ok,Boot} | {error,Reason} +%% Boot1 = Boot2 = Boot = binary() +%% Reason = {app_not_found,App} | {app_not_replaced,App} +%% App = kernel | stdlib | sasl +make_hybrid_boot(TmpVsn, Boot1, Boot2, Paths, Args) -> + catch do_make_hybrid_boot(TmpVsn, Boot1, Boot2, Paths, Args). +do_make_hybrid_boot(TmpVsn, Boot1, Boot2, Paths, Args) -> + {script,{_RelName1,_RelVsn1},Script1} = binary_to_term(Boot1), + {script,{RelName2,_RelVsn2},Script2} = binary_to_term(Boot2), + MatchPaths = get_regexp_path(Paths), + NewScript1 = replace_paths(Script1,MatchPaths), + {Kernel,Stdlib,Sasl} = get_apps(Script2,undefined,undefined,undefined), + NewScript2 = replace_apps(NewScript1,Kernel,Stdlib,Sasl), + NewScript3 = add_apply_upgrade(NewScript2,Args), + Boot = term_to_binary({script,{RelName2,TmpVsn},NewScript3}), + {ok,Boot}. + +%% For each app, compile a regexp that can be used for finding its path +get_regexp_path({KernelPath,StdlibPath,SaslPath}) -> + {ok,KernelMP} = re:compile("kernel-[0-9\.]+",[unicode]), + {ok,StdlibMP} = re:compile("stdlib-[0-9\.]+",[unicode]), + {ok,SaslMP} = re:compile("sasl-[0-9\.]+",[unicode]), + [{KernelMP,KernelPath},{StdlibMP,StdlibPath},{SaslMP,SaslPath}]. + +%% For each path in the script, check if it matches any of the MPs +%% found above, and if so replace it with the correct new path. +replace_paths([{path,Path}|Script],MatchPaths) -> + [{path,replace_path(Path,MatchPaths)}|replace_paths(Script,MatchPaths)]; +replace_paths([Stuff|Script],MatchPaths) -> + [Stuff|replace_paths(Script,MatchPaths)]; +replace_paths([],_) -> + []. + +replace_path([Path|Paths],MatchPaths) -> + [do_replace_path(Path,MatchPaths)|replace_path(Paths,MatchPaths)]; +replace_path([],_) -> + []. + +do_replace_path(Path,[{MP,ReplacePath}|MatchPaths]) -> + case re:run(Path,MP,[{capture,none}]) of + nomatch -> do_replace_path(Path,MatchPaths); + match -> ReplacePath + end; +do_replace_path(Path,[]) -> + Path. + +%% Return the entries for loading the three base applications +get_apps([{kernelProcess,application_controller, + {application_controller,start,[{application,kernel,_}]}}=Kernel| + Script],_,Stdlib,Sasl) -> + get_apps(Script,Kernel,Stdlib,Sasl); +get_apps([{apply,{application,load,[{application,stdlib,_}]}}=Stdlib|Script], + Kernel,_,Sasl) -> + get_apps(Script,Kernel,Stdlib,Sasl); +get_apps([{apply,{application,load,[{application,sasl,_}]}}=Sasl|_Script], + Kernel,Stdlib,_) -> + {Kernel,Stdlib,Sasl}; +get_apps([_|Script],Kernel,Stdlib,Sasl) -> + get_apps(Script,Kernel,Stdlib,Sasl); +get_apps([],undefined,_,_) -> + throw({error,{app_not_found,kernel}}); +get_apps([],_,undefined,_) -> + throw({error,{app_not_found,stdlib}}); +get_apps([],_,_,undefined) -> + throw({error,{app_not_found,sasl}}). + + +%% Replace the entries for loading the base applications +replace_apps([{kernelProcess,application_controller, + {application_controller,start,[{application,kernel,_}]}}| + Script],Kernel,Stdlib,Sasl) -> + [Kernel|replace_apps(Script,undefined,Stdlib,Sasl)]; +replace_apps([{apply,{application,load,[{application,stdlib,_}]}}|Script], + Kernel,Stdlib,Sasl) -> + [Stdlib|replace_apps(Script,Kernel,undefined,Sasl)]; +replace_apps([{apply,{application,load,[{application,sasl,_}]}}|Script], + _Kernel,_Stdlib,Sasl) -> + [Sasl|Script]; +replace_apps([Stuff|Script],Kernel,Stdlib,Sasl) -> + [Stuff|replace_apps(Script,Kernel,Stdlib,Sasl)]; +replace_apps([],undefined,undefined,_) -> + throw({error,{app_not_replaced,sasl}}); +replace_apps([],undefined,_,_) -> + throw({error,{app_not_replaced,stdlib}}); +replace_apps([],_,_,_) -> + throw({error,{app_not_replaced,kernel}}). + + +%% Finally add an apply of release_handler:new_emulator_upgrade - which will +%% complete the execution of the upgrade script (relup). +add_apply_upgrade(Script,Args) -> + [{progress, started} | RevScript] = lists:reverse(Script), + lists:reverse([{progress,started}, + {apply,{release_handler,new_emulator_upgrade,Args}} | + RevScript]). + + + %%----------------------------------------------------------------- %% Create a release package from a release file. %% Options is a list of {path, Path} | silent | @@ -250,13 +372,13 @@ get_release(File, Path, ModTestP, Machine) -> end. get_release1(File, Path, ModTestP, Machine) -> - {ok, Release} = read_release(File, Path), + {ok, Release, Warnings1} = read_release(File, Path), {ok, Appls0} = collect_applications(Release, Path), {ok, Appls1} = check_applications(Appls0), {ok, Appls2} = sort_included_applications(Appls1, Release), % OTP-4121 - {ok, Warnings} = check_modules(Appls2, Path, ModTestP, Machine), + {ok, Warnings2} = check_modules(Appls2, Path, ModTestP, Machine), {ok, Appls} = sort_appls(Appls2), - {ok, Release, Appls, Warnings}. + {ok, Release, Appls, Warnings1 ++ Warnings2}. %%______________________________________________________________________ %% read_release(File, Path) -> {ok, #release} | throw({error, What}) @@ -271,11 +393,12 @@ read_release(File, Path) -> check_rel(Release) -> case catch check_rel1(Release) of - {ok, {Name,Vsn,Evsn,Appl,Incl}} -> + {ok, {Name,Vsn,Evsn,Appl,Incl}, Ws} -> {ok, #release{name=Name, vsn=Vsn, erts_vsn=Evsn, applications=Appl, - incl_apps=Incl}}; + incl_apps=Incl}, + Ws}; {error, Error} -> throw({error,?MODULE,Error}); Error -> @@ -286,8 +409,8 @@ check_rel1({release,{Name,Vsn},{erts,EVsn},Appl}) when is_list(Appl) -> check_name(Name), check_vsn(Vsn), check_evsn(EVsn), - {Appls,Incls} = check_appl(Appl), - {ok, {Name,Vsn,EVsn,Appls,Incls}}; + {{Appls,Incls},Ws} = check_appl(Appl), + {ok, {Name,Vsn,EVsn,Appls,Incls},Ws}; check_rel1(_) -> {error, badly_formatted_release}. @@ -340,8 +463,8 @@ check_appl(Appl) -> end, Appl) of [] -> - mandatory_applications(Appl), - split_app_incl(Appl); + {ok,Ws} = mandatory_applications(Appl), + {split_app_incl(Appl),Ws}; Illegal -> throw({error, {illegal_applications,Illegal}}) end. @@ -352,7 +475,12 @@ mandatory_applications(Appl) -> Mand = mandatory_applications(), case filter(fun(X) -> member(X, AppNames) end, Mand) of Mand -> - ok; + case member(sasl,AppNames) of + true -> + {ok,[]}; + _ -> + {ok, [{warning,missing_sasl}]} + end; _ -> throw({error, {missing_mandatory_app, Mand}}) end. @@ -1510,8 +1638,19 @@ add_system_files(Tar, RelName, Release, Path1) -> SVsn = Release#release.vsn, RelName0 = filename:basename(RelName), + RelVsnDir = filename:join("releases", SVsn), + + %% OTP-9746: store rel file in releases/<vsn> + %% Adding rel file to + %% 1) releases directory - so it can be easily extracted + %% separately (see release_handler:unpack_release) + %% 2) releases/<vsn> - so the file must not be explicitly moved + %% after unpack. add_to_tar(Tar, RelName ++ ".rel", filename:join("releases", RelName0 ++ ".rel")), + add_to_tar(Tar, RelName ++ ".rel", + filename:join(RelVsnDir, RelName0 ++ ".rel")), + %% OTP-6226 Look for the system files not only in cwd %% -- @@ -1527,26 +1666,25 @@ add_system_files(Tar, RelName, Release, Path1) -> [RelDir, "."|Path1] end, - ToDir = filename:join("releases", SVsn), case lookup_file(RelName0 ++ ".boot", Path) of false -> throw({error, {tar_error,{add, RelName0++".boot",enoent}}}); Boot -> - add_to_tar(Tar, Boot, filename:join(ToDir, "start.boot")) + add_to_tar(Tar, Boot, filename:join(RelVsnDir, "start.boot")) end, case lookup_file("relup", Path) of false -> ignore; Relup -> - add_to_tar(Tar, Relup, filename:join(ToDir, "relup")) + add_to_tar(Tar, Relup, filename:join(RelVsnDir, "relup")) end, case lookup_file("sys.config", Path) of false -> ignore; Sys -> - add_to_tar(Tar, Sys, filename:join(ToDir, "sys.config")) + add_to_tar(Tar, Sys, filename:join(RelVsnDir, "sys.config")) end, ok. @@ -1850,90 +1988,67 @@ get_flag(_,_) -> false. %% Check Options for make_script check_args_script(Args) -> - cas(Args, - {undef, undef, undef, undef, undef, undef, undef, undef, - undef, []}). + cas(Args, []). -cas([], {_Path,_Sil,_Loc,_Test,_Var,_Mach,_Xref,_XrefApps,_Werror, X}) -> +cas([], X) -> X; %%% path --------------------------------------------------------------- -cas([{path, P} | Args], {Path, Sil, Loc, Test, Var, Mach, Xref, - XrefApps, Werror, X}) when is_list(P) -> +cas([{path, P} | Args], X) when is_list(P) -> case check_path(P) of ok -> - cas(Args, {P, Sil, Loc, Test, Var, Mach, Xref, XrefApps, - Werror, X}); + cas(Args, X); error -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, Xref, XrefApps, - Werror, X++[{path,P}]}) + cas(Args, X++[{path,P}]) end; %%% silent ------------------------------------------------------------- -cas([silent | Args], {Path, _Sil, Loc, Test, Var, Mach, Xref, - XrefApps, Werror, X}) -> - cas(Args, {Path, silent, Loc, Test, Var, Mach, Xref, XrefApps, - Werror, X}); +cas([silent | Args], X) -> + cas(Args, X); %%% local -------------------------------------------------------------- -cas([local | Args], {Path, Sil, _Loc, Test, Var, Mach, Xref, - XrefApps, Werror, X}) -> - cas(Args, {Path, Sil, local, Test, Var, Mach, Xref, XrefApps, - Werror, X}); +cas([local | Args], X) -> + cas(Args, X); %%% src_tests ------------------------------------------------------- -cas([src_tests | Args], {Path, Sil, Loc, _Test, Var, Mach, Xref, - XrefApps, Werror, X}) -> - cas(Args, - {Path, Sil, Loc, src_tests, Var, Mach, Xref, Werror, XrefApps,X}); +cas([src_tests | Args], X) -> + cas(Args, X); %%% variables ---------------------------------------------------------- -cas([{variables, V} | Args], {Path, Sil, Loc, Test, Var, Mach, Xref, - XrefApps, Werror, X}) when is_list(V) -> +cas([{variables, V} | Args], X) when is_list(V) -> case check_vars(V) of ok -> - cas(Args, - {Path, Sil, Loc, Test, V, Mach, Xref, XrefApps, Werror, X}); + cas(Args, X); error -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, Xref, XrefApps, - Werror, X++[{variables, V}]}) + cas(Args, X++[{variables, V}]) end; %%% machine ------------------------------------------------------------ -cas([{machine, M} | Args], {Path, Sil, Loc, Test, Var, Mach, Xref, - XrefApps, Werror, X}) when is_atom(M) -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, Xref, XrefApps, Werror, X}); +cas([{machine, M} | Args], X) when is_atom(M) -> + cas(Args, X); %%% exref -------------------------------------------------------------- -cas([exref | Args], {Path, Sil, Loc, Test, Var, Mach, _Xref, - XrefApps, Werror, X}) -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, exref, XrefApps, Werror, X}); +cas([exref | Args], X) -> + cas(Args, X); %%% exref Apps --------------------------------------------------------- -cas([{exref, Apps} | Args], {Path, Sil, Loc, Test, Var, Mach, Xref, - XrefApps, Werror, X}) when is_list(Apps) -> +cas([{exref, Apps} | Args], X) when is_list(Apps) -> case check_apps(Apps) of ok -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, - Xref, Apps, Werror, X}); + cas(Args, X); error -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, - Xref, XrefApps, Werror, X++[{exref, Apps}]}) + cas(Args, X++[{exref, Apps}]) end; %%% outdir Dir --------------------------------------------------------- -cas([{outdir, Dir} | Args], {Path, Sil, Loc, Test, Var, Mach, Xref, - XrefApps, Werror, X}) when is_list(Dir) -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, Xref, XrefApps, Werror, X}); +cas([{outdir, Dir} | Args], X) when is_list(Dir) -> + cas(Args, X); %%% otp_build (secret, not documented) --------------------------------- -cas([otp_build | Args], {Path, Sil, Loc, Test, Var, Mach, Xref, - XrefApps, Werror, X}) -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, Xref, XrefApps, Werror, X}); +cas([otp_build | Args], X) -> + cas(Args, X); +%%% warnings_as_errors ------------------------------------------------- +cas([warnings_as_errors | Args], X) -> + cas(Args, X); +%%% no_warn_sasl ------------------------------------------------------- +cas([no_warn_sasl | Args], X) -> + cas(Args, X); %%% no_module_tests (kept for backwards compatibility, but ignored) ---- -cas([no_module_tests | Args], {Path, Sil, Loc, Test, Var, Mach, Xref, - XrefApps, Werror, X}) -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, Xref, XrefApps, Werror, X}); -%%% warnings_as_errors (kept for backwards compatibility, but ignored) ---- -cas([warnings_as_errors | Args], {Path, Sil, Loc, Test, Var, Mach, Xref, - XrefApps, _Werror, X}) -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, Xref, XrefApps, - warnings_as_errors, X}); +cas([no_module_tests | Args], X) -> + cas(Args, X); %%% ERROR -------------------------------------------------------------- -cas([Y | Args], {Path, Sil, Loc, Test, Var, Mach, Xref, XrefApps, - Werror, X}) -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, Xref, XrefApps, Werror, - X++[Y]}). +cas([Y | Args], X) -> + cas(Args, X++[Y]). @@ -2198,5 +2313,9 @@ form_warn(Prefix, {exref_undef, Undef}) -> [Prefix,M,F,A]) end, map(F, Undef); +form_warn(Prefix, missing_sasl) -> + io_lib:format("~s: Missing application sasl. " + "Can not upgrade with this release~n", + [Prefix]); form_warn(Prefix, What) -> io_lib:format("~s ~p~n", [Prefix,What]). diff --git a/lib/sasl/src/systools_rc.erl b/lib/sasl/src/systools_rc.erl index daadb79967..c16f6aa845 100644 --- a/lib/sasl/src/systools_rc.erl +++ b/lib/sasl/src/systools_rc.erl @@ -54,6 +54,7 @@ %% {sync_nodes, Id, Nodes} %% {apply, {M, F, A}} %% restart_new_emulator +%% restart_emulator %%----------------------------------------------------------------- %% High-level instructions that contain dependencies @@ -144,7 +145,10 @@ translate_merged_script(Mode, Script, Appls, PreAppls) -> {Before2, After2} = translate_dependent_instrs(Mode, Before1, After1, Appls), Before3 = merge_load_object_code(Before2), - NewScript = Before3 ++ [point_of_no_return | After2], + + {Before4,After4} = sort_emulator_restart(Mode,Before3,After2), + NewScript = Before4 ++ [point_of_no_return | After4], + check_syntax(NewScript), {ok, NewScript}. @@ -699,6 +703,39 @@ mlo([{load_object_code, {Lib, LibVsn, Mods}} | T]) -> mlo([]) -> []. %%----------------------------------------------------------------- +%% RESTART EMULATOR +%% ----------------------------------------------------------------- +%% ----------------------------------------------------------------- +%% Check if there are any 'restart_new_emulator' instructions (i.e. if +%% the emulator or core application version is changed). If so, this +%% must be done first for upgrade and last for downgrade. +%% Check if there are any 'restart_emulator' instructions, if so +%% remove all and place one the end. +%% ----------------------------------------------------------------- +sort_emulator_restart(Mode,Before,After) -> + {Before1,After1} = + case filter_out(restart_new_emulator, After) of + After -> + {Before,After}; + A1 when Mode==up -> + {[restart_new_emulator|Before],A1}; + A1 when Mode==dn -> + {Before,A1++[restart_emulator]} + end, + After2 = + case filter_out(restart_emulator, After1) of + After1 -> + After1; + A2 -> + A2++[restart_emulator] + end, + {Before1,After2}. + + +filter_out(What,List) -> + lists:filter(fun(X) when X=:=What -> false; (_) -> true end, List). + +%%----------------------------------------------------------------- %% SYNTAX CHECK %%----------------------------------------------------------------- %%----------------------------------------------------------------- @@ -817,6 +854,7 @@ check_op({apply, {M, F, A}}) -> check_func(F), check_args(A); check_op(restart_new_emulator) -> ok; +check_op(restart_emulator) -> ok; check_op(X) -> throw({error, {bad_instruction, X}}). check_mod(Mod) when is_atom(Mod) -> ok; diff --git a/lib/sasl/src/systools_relup.erl b/lib/sasl/src/systools_relup.erl index 6d9e922900..7fb623bb85 100644 --- a/lib/sasl/src/systools_relup.erl +++ b/lib/sasl/src/systools_relup.erl @@ -112,6 +112,11 @@ -export([mk_relup/3, mk_relup/4, format_error/1, format_warning/1]). -include("systools.hrl"). +-define(R15_SASL_VSN,"2.2"). + +%% For test purposes only - used by kernel, stdlib and sasl tests +-export([appup_search_for_version/2]). + %%----------------------------------------------------------------- %% mk_relup(TopRelFile, BaseUpRelDcs, BaseDnRelDcs) %% mk_relup(TopRelFile, BaseUpRelDcs, BaseDnRelDcs, Opts) -> Ret @@ -200,7 +205,13 @@ do_mk_relup(TopRelFile, BaseUpRelDcs, BaseDnRelDcs, Path, Opts) -> %% TopRel = #release %% NameVsnApps = [{{Name, Vsn}, #application}] {ok, TopRel, NameVsnApps, Ws0} -> - %% + case lists:member({warning,missing_sasl},Ws0) of + true -> + throw({error,?MODULE,{missing_sasl,TopRel}}); + false -> + ok + end, + %% TopApps = [#application] TopApps = lists:map(fun({_, App}) -> App end, NameVsnApps), @@ -247,7 +258,21 @@ foreach_baserel_up(TopRel, TopApps, [BaseRelDc|BaseRelDcs], Path, Opts, Ws, Acc) -> BaseRelFile = extract_filename(BaseRelDc), - {ok, BaseRel} = systools_make:read_release(BaseRelFile, Path), + {BaseRel, {BaseNameVsns, BaseApps}, Ws0} = + case systools_make:get_release(BaseRelFile, Path) of + {ok, BR, NameVsnApps, Warns} -> + case lists:member({warning,missing_sasl},Warns) of + true -> + throw({error,?MODULE,{missing_sasl,BR}}); + false -> + %% NameVsnApps = [{{Name,Vsn},#application}] + %% Gives two lists - [{Name,Vsn}] and [#application] + {BR,lists:unzip(NameVsnApps),Warns} + end; + Other1 -> + throw(Other1) + end, + %% %% BaseRel = #release @@ -257,29 +282,23 @@ foreach_baserel_up(TopRel, TopApps, [BaseRelDc|BaseRelDcs], Path, Opts, %% application, one for each added applications, and one for %% each removed applications. %% - {RUs1, Ws1} = collect_appup_scripts(up, TopApps, BaseRel, Ws, []), + {RUs1, Ws1} = collect_appup_scripts(up, TopApps, BaseRel, Ws0++Ws, []), {RUs2, Ws2} = create_add_app_scripts(BaseRel, TopRel, RUs1, Ws1), {RUs3, Ws3} = create_remove_app_scripts(BaseRel, TopRel, RUs2, Ws2), - {RUs4, Ws4} = - check_for_emulator_restart(TopRel, BaseRel, RUs3, Ws3, Opts), - - BaseApps = - case systools_make:get_release(BaseRelFile, Path) of - {ok, _, NameVsnApps, _Warns} -> - lists:map(fun({_,App}) -> App end, NameVsnApps); - Other1 -> - throw(Other1) - end, + {RUs4, Ws4} = check_for_emulator_restart(TopRel, BaseRel, RUs3, Ws3, Opts), case systools_rc:translate_scripts(up, RUs4, TopApps, BaseApps) of - {ok, RUs} -> + {ok, RUs5} -> + + {RUs, Ws5} = fix_r15_sasl_upgrade(RUs5,Ws4,BaseNameVsns), + VDR = {BaseRel#release.vsn, extract_description(BaseRelDc), RUs}, foreach_baserel_up(TopRel, TopApps, BaseRelDcs, Path, - Opts, Ws4, [VDR| Acc]); + Opts, Ws5, [VDR| Acc]); XXX -> throw(XXX) end; @@ -294,42 +313,41 @@ foreach_baserel_dn(TopRel, TopApps, [BaseRelDc|BaseRelDcs], Path, Opts, Ws, Acc) -> BaseRelFile = extract_filename(BaseRelDc), - {ok, BaseRel} = systools_make:read_release(BaseRelFile, Path), - - %% BaseRel = #release - - %% RUs = (release upgrade scripts) - %% - {RUs1, Ws1} = collect_appup_scripts(dn, TopApps, BaseRel, Ws, []), - - {BaseApps, Ws2} = + {BaseRel, BaseApps, Ws0} = case systools_make:get_release(BaseRelFile, Path) of %% %% NameVsnApps = [{{Name, Vsn}, #application}] - {ok, _, NameVsnApps, Warns} -> - %% - %% NApps = [#application] - NApps = lists:map(fun({_,App}) -> App end, NameVsnApps), - {NApps, Warns ++ Ws1}; + {ok, BR, NameVsnApps, Warns} -> + case lists:member({warning,missing_sasl},Warns) of + true -> + throw({error,?MODULE,{missing_sasl,BR}}); + false -> + %% NApps = [#application] + NApps = lists:map(fun({_,App}) -> App end, NameVsnApps), + {BR, NApps, Warns} + end; Other -> throw(Other) end, - RUs2 = RUs1, + %% BaseRel = #release + + %% RUs = (release upgrade scripts) + %% + {RUs1, Ws1} = collect_appup_scripts(dn, TopApps, BaseRel, Ws0++Ws, []), - {RUs3, Ws3} = create_add_app_scripts(TopRel, BaseRel, RUs2, Ws2), + {RUs2, Ws2} = create_add_app_scripts(TopRel, BaseRel, RUs1, Ws1), - {RUs4, Ws4} = create_remove_app_scripts(TopRel, BaseRel, RUs3, Ws3), + {RUs3, Ws3} = create_remove_app_scripts(TopRel, BaseRel, RUs2, Ws2), - {RUs5, Ws5} = check_for_emulator_restart(TopRel, BaseRel, - RUs4, Ws4, Opts), + {RUs4, Ws4} = check_for_emulator_restart(TopRel, BaseRel, RUs3, Ws3, Opts), - case systools_rc:translate_scripts(dn, RUs5, BaseApps, TopApps) of + case systools_rc:translate_scripts(dn, RUs4, BaseApps, TopApps) of {ok, RUs} -> VDR = {BaseRel#release.vsn, extract_description(BaseRelDc), RUs}, foreach_baserel_dn(TopRel, TopApps, BaseRelDcs, Path, - Opts, Ws5, [VDR| Acc]); + Opts, Ws4, [VDR| Acc]); XXX -> throw(XXX) end; @@ -343,14 +361,42 @@ foreach_baserel_dn( _, _, [], _, _, Ws, Acc) -> %% check_for_emulator_restart(#release{erts_vsn = Vsn1, name = N1}, #release{erts_vsn = Vsn2, name = N2}, RUs, Ws, - _Opts) when Vsn1 /= Vsn2 -> - {RUs++[[restart_new_emulator]], [{erts_vsn_changed, {N1, N2}} | Ws]}; + Opts) when Vsn1 /= Vsn2 -> + %% Automatically insert a restart_new_emulator instruction when + %% erts version is changed. Also allow extra restart at the end of + %% the upgrade if restart_emulator option is given. + NewRUs = [[restart_new_emulator]|RUs], + NewWs = [{erts_vsn_changed, {{N1,Vsn1}, {N2,Vsn2}}} | Ws], + check_for_restart_emulator_opt(NewRUs, NewWs, Opts); check_for_emulator_restart(_, _, RUs, Ws, Opts) -> + check_for_restart_emulator_opt(RUs, Ws, Opts). + +check_for_restart_emulator_opt(RUs, Ws, Opts) -> case get_opt(restart_emulator, Opts) of - true -> {RUs++[[restart_new_emulator]], Ws}; + true -> {RUs++[[restart_emulator]], Ws}; _ -> {RUs, Ws} end. + +%% Special handling of the upgrade from pre R15 to post R15. In R15, +%% upgrade of the emulator was improved by moving the restart of the +%% emulator before the rest of the upgrade instructions. However, it +%% can only work if the release_handler is already upgraded to a post +%% R15 version. If not, the upgrade instructions must be backwards +%% compatible - i.e. restart_new_emulator will be the last +%% instruction, executed after all code loading, code_change etc. +fix_r15_sasl_upgrade([restart_new_emulator | RestRUs]=RUs, Ws, BaseApps) -> + case lists:keyfind(sasl,1,BaseApps) of + {sasl,Vsn} when Vsn < ?R15_SASL_VSN -> + {lists:delete(restart_emulator,RestRUs) ++ [restart_new_emulator], + [pre_R15_emulator_upgrade|Ws]}; + _ -> + {RUs,Ws} + end; +fix_r15_sasl_upgrade(RUs, Ws, _BaseApps) -> + {RUs,Ws}. + + %% collect_appup_scripts(Mode, TopApps, BaseRel, Ws, RUs) -> {NRUs, NWs} %% Mode = up | dn %% TopApps = [#application] @@ -440,13 +486,32 @@ get_script_from_appup(Mode, TopApp, BaseVsn, Ws, RUs) -> %% XXX Why is this a warning only? [{bad_vsn, {TopVsn, TopApp#application.vsn}}| Ws] end, - case lists:keysearch(BaseVsn, 1, VsnRUs) of - {value, {_, RU}} -> + case appup_search_for_version(BaseVsn, VsnRUs) of + {ok, RU} -> {RUs ++ [RU], Ws1}; - _ -> + error -> throw({error, ?MODULE, {no_relup, FName, TopApp, BaseVsn}}) end. +appup_search_for_version(BaseVsn, VsnRUs) -> + appup_search_for_version(BaseVsn, length(BaseVsn), VsnRUs). + +appup_search_for_version(BaseVsn,_,[{BaseVsn,RU}|_]) -> + {ok,RU}; +appup_search_for_version(BaseVsn,Size,[{Vsn,RU}|VsnRUs]) when is_binary(Vsn) -> + case re:run(BaseVsn,Vsn,[unicode,{capture,first,index}]) of + {match,[{0,Size}]} -> + {ok, RU}; + _ -> + appup_search_for_version(BaseVsn,Size,VsnRUs) + end; +appup_search_for_version(BaseVsn,Size,[_|VsnRUs]) -> + appup_search_for_version(BaseVsn,Size,VsnRUs); +appup_search_for_version(_,_,[]) -> + error. + + + %% Primitives for the "lists of release names" that we upgrade from %% and to. @@ -543,7 +608,9 @@ format_error({no_relup, File, App, Vsn}) -> "in file ~p~n", [App#application.name, App#application.vsn, App#application.name, Vsn, File]); - +format_error({missing_sasl,Release}) -> + io_lib:format("No sasl application in release ~p, ~p. Can not be upgraded.", + [Release#release.name, Release#release.vsn]); format_error(Error) -> io:format("~p~n", [Error]). diff --git a/lib/sasl/test/Makefile b/lib/sasl/test/Makefile index 65be134462..91a8c42484 100644 --- a/lib/sasl/test/Makefile +++ b/lib/sasl/test/Makefile @@ -36,6 +36,8 @@ MODULES= \ ERL_FILES= $(MODULES:%=%.erl) +HRL_FILES= test_lib.hrl + TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) INSTALL_PROGS= $(TARGET_FILES) @@ -84,7 +86,7 @@ release_spec: opt release_tests_spec: make_emakefile $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) $(ERL_FILES) $(RELSYSDIR) + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR) $(INSTALL_DATA) sasl.spec sasl.cover $(EMAKEFILE) $(RELSYSDIR) chmod -R u+w $(RELSYSDIR) @tar cfh - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) diff --git a/lib/sasl/test/alarm_handler_SUITE.erl b/lib/sasl/test/alarm_handler_SUITE.erl index a98e8c9c67..a4064ef27a 100644 --- a/lib/sasl/test/alarm_handler_SUITE.erl +++ b/lib/sasl/test/alarm_handler_SUITE.erl @@ -18,7 +18,7 @@ %% -module(alarm_handler_SUITE). --include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). %%----------------------------------------------------------------- %% We will add an own alarm handler in order to verify that the @@ -56,34 +56,32 @@ end_per_group(_GroupName, Config) -> %%----------------------------------------------------------------- -set_alarm(suite) -> []; set_alarm(Config) when is_list(Config) -> - ?line gen_event:add_handler(alarm_handler, ?MODULE, self()), + gen_event:add_handler(alarm_handler, ?MODULE, self()), Alarm1 = {alarm1, "this is the alarm"}, Alarm2 = {"alarm2", this_is_the_alarm}, Alarm3 = {{alarm3}, {this_is,"the_alarm"}}, - ?line ok = alarm_handler:set_alarm(Alarm1), + ok = alarm_handler:set_alarm(Alarm1), reported(set_alarm, Alarm1), - ?line ok = alarm_handler:set_alarm(Alarm2), + ok = alarm_handler:set_alarm(Alarm2), reported(set_alarm, Alarm2), - ?line ok = alarm_handler:set_alarm(Alarm3), + ok = alarm_handler:set_alarm(Alarm3), reported(set_alarm, Alarm3), - ?line [Alarm3,Alarm2,Alarm1] = alarm_handler:get_alarms(), + [Alarm3,Alarm2,Alarm1] = alarm_handler:get_alarms(), alarm_handler:clear_alarm(alarm1), alarm_handler:clear_alarm("alarm2"), alarm_handler:clear_alarm({alarm3}), - ?line [] = alarm_handler:get_alarms(), + [] = alarm_handler:get_alarms(), test_server:messages_get(), - ?line my_yes = gen_event:delete_handler(alarm_handler, ?MODULE, []), + my_yes = gen_event:delete_handler(alarm_handler, ?MODULE, []), ok. %%----------------------------------------------------------------- -clear_alarm(suite) -> []; clear_alarm(Config) when is_list(Config) -> - ?line gen_event:add_handler(alarm_handler, ?MODULE, self()), + gen_event:add_handler(alarm_handler, ?MODULE, self()), Alarm1 = {alarm1, "this is the alarm"}, Alarm2 = {"alarm2", this_is_the_alarm}, Alarm3 = {{alarm3}, {this_is,"the_alarm"}}, @@ -92,44 +90,42 @@ clear_alarm(Config) when is_list(Config) -> alarm_handler:set_alarm(Alarm3), test_server:messages_get(), - ?line ok = alarm_handler:clear_alarm(alarm1), + ok = alarm_handler:clear_alarm(alarm1), reported(clear_alarm, alarm1), - ?line ok = alarm_handler:clear_alarm("alarm2"), + ok = alarm_handler:clear_alarm("alarm2"), reported(clear_alarm, "alarm2"), - ?line ok = alarm_handler:clear_alarm({alarm3}), + ok = alarm_handler:clear_alarm({alarm3}), reported(clear_alarm, {alarm3}), - ?line [] = alarm_handler:get_alarms(), + [] = alarm_handler:get_alarms(), - ?line my_yes = gen_event:delete_handler(alarm_handler, ?MODULE, []), + my_yes = gen_event:delete_handler(alarm_handler, ?MODULE, []), ok. %%----------------------------------------------------------------- -swap(suite) -> []; swap(Config) when is_list(Config) -> - ?line Alarm1 = {alarm1, "this is the alarm"}, - ?line Alarm2 = {"alarm2", this_is_the_alarm}, - ?line Alarm3 = {{alarm3}, {this_is,"the_alarm"}}, - ?line alarm_handler:set_alarm(Alarm1), - ?line alarm_handler:set_alarm(Alarm2), - ?line alarm_handler:set_alarm(Alarm3), - - ?line foo, + Alarm1 = {alarm1, "this is the alarm"}, + Alarm2 = {"alarm2", this_is_the_alarm}, + Alarm3 = {{alarm3}, {this_is,"the_alarm"}}, + alarm_handler:set_alarm(Alarm1), + alarm_handler:set_alarm(Alarm2), + alarm_handler:set_alarm(Alarm3), + case gen_event:which_handlers(alarm_handler) of [alarm_handler] -> - ?line ok = gen_event:swap_handler(alarm_handler, - {alarm_handler, swap}, - {?MODULE, self()}), - ?line [?MODULE] = gen_event:which_handlers(alarm_handler), + ok = gen_event:swap_handler(alarm_handler, + {alarm_handler, swap}, + {?MODULE, self()}), + [?MODULE] = gen_event:which_handlers(alarm_handler), Alarms = [Alarm3, Alarm2, Alarm1], reported(swap_alarms, Alarms), %% get_alarms is only valid with the default handler installed. - ?line {error, _} = alarm_handler:get_alarms(), + {error, _} = alarm_handler:get_alarms(), - ?line my_yes = gen_event:delete_handler(alarm_handler, - ?MODULE, []), - ?line gen_event:add_handler(alarm_handler, alarm_handler, []), + my_yes = gen_event:delete_handler(alarm_handler, + ?MODULE, []), + gen_event:add_handler(alarm_handler, alarm_handler, []), ok; _ -> alarm_handler:clear_alarm(alarm1), diff --git a/lib/sasl/test/installer.erl b/lib/sasl/test/installer.erl index f5ceab0dc4..6942ec21ea 100644 --- a/lib/sasl/test/installer.erl +++ b/lib/sasl/test/installer.erl @@ -19,20 +19,33 @@ -module(installer). +-include("test_lib.hrl"). + %%-compile(export_all). -export([install_1/2]). -export([install_2/1]). -export([install_3/2]). --export([install_3a/1]). +-export([install_6a/1]). -export([install_4/1]). -export([install_5/1]). -export([install_5a/1]). -export([install_6/1]). -export([install_7/1]). +-export([install_7a/1]). -export([install_8/1]). +-export([install_8a/1]). -export([install_9/1]). -export([install_10/1]). -export([install_11/1]). +-export([install_12/1]). +-export([install_13/1]). +-export([install_14/1]). +-export([upgrade_restart_1/2]). +-export([upgrade_restart_1a/1]). +-export([upgrade_restart_2/1]). +-export([upgrade_restart_2a/1]). +-export([upgrade_restart_2b/1]). +-export([upgrade_restart_3/1]). -export([client1_1/4]). -export([client2/3]). -export([stop/1]). @@ -46,28 +59,35 @@ -define(fail(Term), exit({?MODULE, ?LINE, Term})). -define(fail_line(Line,Term), exit({?MODULE, Line, Term})). --define(check_release(Vsn,Status,Apps), - check_release(TestNode,node(),Vsn,Status,Apps,?LINE)). --define(check_release_client(Node,Vsn,Status,Apps), - check_release(TestNode,Node,Vsn,Status,Apps,?LINE)). +-define(check_release_states(States), + check_release_states(TestNode,node(),States,?LINE)). +-define(check_release_states_client(Node,States), + check_release_states(TestNode,Node,States,?LINE)). + +-define(check_release_lib(Vsn,Apps), + check_release_lib(TestNode,node(),Vsn,Apps,?LINE)). +-define(check_release_lib_client(Node,Vsn,Apps), + check_release_lib(TestNode,Node,Vsn,Apps,?LINE)). -define(check_running_app(App,Vsn), check_running_app(TestNode,node(),App,Vsn,?LINE)). -define(check_running_app_client(Node,App,Vsn), check_running_app(TestNode,Node,App,Vsn,?LINE)). +-define(check_disallowed_calls,check_disallowed_calls(TestNode,?LINE)). + install_1(TestNode,PrivDir) -> ?print([TestNode]), ?print(["install_1 start"]), + ?check_release_states([permanent]), % Unpack and install P1H {ok, "P1H"} = unpack_release(PrivDir,"rel1"), - ?print(["unpack_release P1H ok"]), - ?check_release("P1H",unpacked,["a-1.0"]), + ?check_release_states([permanent,unpacked]), + ?check_release_lib("P1H",["a-1.0"]), {ok,"P1G",[new_appl]} = release_handler:install_release("P1H"), - ?print(["install_release P1H ok"]), - ?check_release("P1H",current,["a-1.0"]), + ?check_release_states([permanent,current]), ?check_running_app(a,"1.0"), X = a:a(), ?print(["X", X]), @@ -81,173 +101,351 @@ install_2(TestNode) -> ?print(["install_2 start"]), % Check that P1H is still unpacked, install it and make_permanent - ?check_release("P1H",unpacked,["a-1.0"]), - ?print(["install_2 P1H unpacked"]), + ?check_release_states([permanent,unpacked]), {ok,"P1G",[new_appl]} = release_handler:install_release("P1H"), ?print(["install_2 install_release ok"]), - ?check_release("P1H",current,["a-1.0"]), + ?check_release_states([permanent,current]), + ?check_running_app(a,"1.0"), + ok = release_handler:make_permanent("P1H"), + ?print(["install_2 make permanent P1H ok"]), + ?check_release_states([old,permanent]), ?check_running_app(a,"1.0"), - ok = release_handler:make_permanent("P1H"). + ok. % release_handler_SUITE will reboot this node now! install_3(TestNode,PrivDir) -> ?print(["install_3 start"]), % Check that P1H is permanent - ?check_release("P1H",permanent,["a-1.0"]), + ?check_release_states([old,permanent]), + ?check_running_app(a,"1.0"), X = a:a(), {key2, val2} = lists:keyfind(key2, 1, X), {key1, val1} = lists:keyfind(key1, 1, X), % Unpack and install P1I {ok, "P1I"} = unpack_release(PrivDir,"rel2"), - ?print(["install_3 unpack_release P1I ok"]), - ?check_release("P1I",unpacked,["a-1.1"]), + ?check_release_states([old,permanent,unpacked]), + ?check_release_lib("P1I",["a-1.1"]), {ok,"P1H",[{extra, gott}]} = release_handler:check_install_release("P1I"), + ?print(["install_3 check_install_release P1I ok"]), {error,_} = release_handler:check_install_release("P1J"), + ?print(["install_3 check_install_release P1J fails - ok"]), {ok,"P1H",[{extra, gott}]} = release_handler:install_release("P1I"), - ?print(["install_3 install_release P1I ok"]), - ?check_release("P1I",current,["a-1.1"]), + ?check_release_states([old,permanent,current]), ?check_running_app(a,"1.1"), X2 = a:a(), {key2, newval2} = lists:keyfind(key2, 1, X2), {key1, val1} = lists:keyfind(key1, 1, X2), {ok, bval} = a:b(), + ?print(["install_3 env ok"]), - % Unpack and install P2A + % Unpack P2A {ok, "P2A"} = unpack_release(PrivDir,"rel3"), - ?print(["install_3 unpack_release P2A ok"]), - ?check_release("P2A",unpacked,["a-1.1"]), + ?check_release_states([old,permanent,current,unpacked]), + ?check_release_lib("P2A",["a-1.1"]), {ok, "P1I", [new_emu]} = release_handler:check_install_release("P2A"), ?print(["install_3 check_install_release P2A ok"]), - ok = release_handler:make_permanent("P1I"), - ?print(["install_3 make_permanent P1I ok"]), - ?check_release("P1I",permanent,["a-1.1"]), ok. + % release_handler_SUITE will reboot this node now! + +install_4(TestNode) -> + ?print(["install_4 start"]), -install_3a(TestNode) -> - {ok, "P1I", [new_emu]} = release_handler:install_release("P2A"), + %% Check that P1H is the one that is used + ?check_release_states([old,permanent,unpacked,unpacked]), + ?check_running_app(a,"1.0"), + + %% Install P2A + {continue_after_restart, "P1H", [new_emu,new_appl]} = + release_handler:install_release("P2A"), %% Node is rebooted by the release_handler:install_release %% (init:reboot) because P2A includes a new erts vsn and the relup %% file contains a 'restart_new_emulator' instruction. - ?print(["install_3 P2A installed"]), + ?print(["install_4 P2A installed"]), ok. +install_5(TestNode) -> + ?print(["install_5 start"]), -install_4(TestNode) -> - ?print(["install_4 start"]), + %% Check that the upgrade was done via a temporary release due to + %% new emulator version. + {"SASL-test","__new_emulator__P1H"} = init:script_id(), + + %% Check that P2A is in use. + ?check_release_states([old,permanent,unpacked,current]), + ?check_running_app(a,"1.1"), + X = a:a(), + {key2, newval2} = lists:keyfind(key2, 1, X), + {key1, val1} = lists:keyfind(key1, 1, X), + {ok, bval} = a:b(), + ?print(["install_5 check env ok"]), + ok. + +install_5a(TestNode) -> + ?print(["install_5a start"]), + + %% Install P1I (this will be a downgrade) + {ok, "P1I", [old_emu]} = release_handler:install_release("P1I"), + %% Node is rebooted by the release_handler:install_release + %% (init:reboot) because P2A includes a new erts vsn and the relup + %% file contains a 'restart_new_emulator' instruction. + ?print(["install_5a P1I installed"]), + ok. + +install_6(TestNode) -> + ?print(["install_6 start"]), + + %% Check that P1I is used + ?check_release_states([old,permanent,current,old]), + ?check_running_app(a,"1.1"), + + %% Make P1I permanent + ok = release_handler:make_permanent("P1I"), + ?check_release_states([old,old,permanent,old]), + ?check_running_app(a,"1.1"), + ok. + +install_6a(TestNode) -> + %% Install P2A + {continue_after_restart, "P1I", [new_emu]} = + release_handler:install_release("P2A"), + %% Node is rebooted by the release_handler:install_release + %% (init:reboot) because P2A includes a new erts vsn and the relup + %% file contains a 'restart_new_emulator' instruction. + ?print(["install_6a P2A installed"]), + ok. + +install_7(TestNode) -> + ?print(["install_7 start"]), + + %% Check that the upgrade was done via a temporary release due to + %% new emulator version. + {"SASL-test","__new_emulator__P1I"} = init:script_id(), % Check that P2A is in use. - ?check_release("P2A",current,["a-1.1"]), + ?check_release_states([old,old,permanent,current]), ?check_running_app(a,"1.1"), X = a:a(), {key2, newval2} = lists:keyfind(key2, 1, X), {key1, val1} = lists:keyfind(key1, 1, X), {ok, bval} = a:b(), + ?print(["install_7 check env ok"]), ok. - % release_handler_SUITE will reboot this node now! -install_5(TestNode) -> - ?print(["install_5 start"]), +install_7a(TestNode) -> + %% Install P1H (this will be a downgrade) + {ok, "P1H", [old_emu,old_appl]} = release_handler:install_release("P1H"), + %% Node is rebooted by the release_handler:install_release + %% (init:reboot) because P2A includes a new erts vsn and the relup + %% file contains a 'restart_new_emulator' instruction. + ?print(["install_7a P1H installed"]), + ok. - % Check that P1I is used - {ok, "P1I", [new_emu]} = release_handler:check_install_release("P2A"), +install_8(TestNode) -> + ?print(["install_8 start"]), + + %% Check that P1H is used + ?check_release_states([old,current,permanent,old]), + ?check_running_app(a,"1.0"), + {ok,"P1H",[new_emu,new_appl]} = release_handler:check_install_release("P2A"), + ?print(["install_8 check_install_release P2A ok"]), + + %% Install P1I and check that it is permanent + {ok,"P1H",[{extra, gott}]} = release_handler:install_release("P1I"), + ?check_release_states([old,old,permanent,old]), + ?check_running_app(a,"1.1"), ok. -install_5a(TestNode) -> +install_8a(TestNode) -> % Install P2A again - {ok, "P1I", [new_emu]} = release_handler:install_release("P2A"), + {continue_after_restart, "P1I", [new_emu]} = + release_handler:install_release("P2A"), %% Node is rebooted by the release_handler:install_release %% (init:reboot) because P2A includes a new erts vsn and the relup %% file contains a 'restart_new_emulator' instruction. - ?print(["install_5 P2A installed"]), + ?print(["install_8a P2A installed"]), ok. -install_6(TestNode) -> - ?print(["install_6 start"]), +install_9(TestNode) -> + ?print(["install_9 start"]), + + %% Check that the upgrade was done via a temporary release due to + %% new emulator version. + {"SASL-test","__new_emulator__P1I"} = init:script_id(), % Check that P2A is used - ?check_release("P2A",current,["a-1.1"]), + ?check_release_states([old,old,permanent,current]), ?check_running_app(a,"1.1"), X = a:a(), {key2, newval2} = lists:keyfind(key2, 1, X), {key1, val1} = lists:keyfind(key1, 1, X), {ok, bval} = a:b(), - ok = release_handler:make_permanent("P2A"). + ?print(["install_9 check env ok"]), + ok = release_handler:make_permanent("P2A"), + ?check_release_states([old,old,old,permanent]), + ?check_running_app(a,"1.1"), + ok. % release_handler_SUITE will reboot this node now! -install_7(TestNode) -> - ?print(["install_7 start"]), +install_10(TestNode) -> + ?print(["install_10 start"]), % Check that P2A is used - ?check_release("P2A",permanent,["a-1.1"]), + ?check_release_states([old,old,old,permanent]), + ?check_running_app(a,"1.1"), % Install old P1H ok = release_handler:reboot_old_release("P1H"), + ?print(["install_10 reboot_old ok"]), ok. -install_8(TestNode) -> - ?print(["install_8 start"]), + +install_11(TestNode) -> + ?print(["install_11 start"]), % Check that P1H is permanent - ?check_release("P1H",permanent,["a-1.0"]), + ?check_release_states([old,permanent,old,old]), + ?check_running_app(a,"1.0"), X = a:a(), {key2, val2} = lists:keyfind(key2, 1, X), {key1, val1} = lists:keyfind(key1, 1, X), + ?print(["install_11 check env ok"]), %% Remove P1I and P2A and check that a-1.1 and erts-<latest> are removed ok = release_handler:remove_release("P2A"), + ?check_release_states([old,permanent,old]), ok = release_handler:remove_release("P1I"), + ?check_release_states([old,permanent]), {ok, Libs} = file:list_dir(code:lib_dir()), {_,_,StdlibVsn} = lists:keyfind(stdlib,1,application:which_applications()), true = lists:member("stdlib-"++StdlibVsn, Libs), true = lists:member("a-1.0", Libs), false = lists:member("a-1.1", Libs), {ok, Dirs} = file:list_dir(code:root_dir()), - ["erts-4.4"] = lists:filter(fun(Dir) -> lists:prefix("erts-",Dir) end, Dirs), + ErtsDir = "erts-"++?ertsvsn, + [ErtsDir] = lists:filter(fun(Dir) -> lists:prefix("erts-",Dir) end, Dirs), + ?print(["install_11 file checks ok"]), ok. % release_handler_SUITE will reboot this node now! -install_9(TestNode) -> - ?print(["install_9 start"]), +install_12(TestNode) -> + ?print(["install_12 start"]), % Check that P1H is permanent - ?check_release("P1H",permanent,["a-1.0"]), + ?check_release_states([old,permanent]), + ?check_running_app(a,"1.0"), X = a:a(), {key2, val2} = lists:keyfind(key2, 1, X), {key1, val1} = lists:keyfind(key1, 1, X), + ?print(["install_12 check env ok"]), % Install old P1G ok = release_handler:reboot_old_release("P1G"), + ?print(["install_12 reboot_old ok"]), ok. -install_10(TestNode) -> - ?print(["install_10 start"]), +install_13(TestNode) -> + ?print(["install_13 start"]), % Check that P1G is permanent - ?check_release("P1G",permanent,[]), - ?check_release("P1H",old,["a-1.0"]), + ?check_release_states([permanent,old]), + false = lists:keysearch(a,1,application:loaded_applications()), + ?print(["install_13 no a application found - ok"]), %% Remove P1H and check that both versions of application a is removed ok = release_handler:remove_release("P1H"), + ?check_release_states([permanent]), {ok, Libs} = file:list_dir(code:lib_dir()), {_,_,StdlibVsn} = lists:keyfind(stdlib,1,application:which_applications()), true = lists:member("stdlib-"++StdlibVsn, Libs), false = lists:member("a-1.0", Libs), false = lists:member("a-1.1", Libs), + ?print(["install_13 file checks ok"]), ok. % release_handler_SUITE will reboot this node now! -install_11(TestNode) -> - ?print(["install_11 start"]), +install_14(TestNode) -> + ?print(["install_14 start"]), % Check that P1G is permanent - ?check_release("P1G",permanent,[]), + ?check_release_states([permanent]), + false = lists:keysearch(a,1,application:loaded_applications()), + ?print(["install_13 no a application found - ok"]), ok. +%%%----------------------------------------------------------------- +%%% Ths test checks that an upgrade which both upgrades to a new +%%% emulator version, and had a restart_emulator option to +%%% systools:make_relup will be restarted twice on upgrade. +%%% (On downgrade it will happen only once.) +upgrade_restart_1(TestNode,PrivDir) -> + ?print([TestNode]), + ?print(["upgrade_restart_1 start"]), + ?check_release_states([permanent]), + + {ok, "P2B"} = unpack_release(PrivDir,"rel4"), + ?check_release_states([permanent,unpacked]), + ?check_release_lib("P2B",["a-1.1"]), + ok. + +upgrade_restart_1a(TestNode) -> + ?print(["upgrade_restart_1a start"]), + + {continue_after_restart,"P1G",[new_emu,add_appl]} = + release_handler:install_release("P2B"), + ?print(["upgrade_restart_1a P2B installed"]), + ok. + +upgrade_restart_2(TestNode) -> + ?print(["upgrade_restart_2 start"]), + + %% Check that the node has been restarted once more after the tmp release + case init:script_id() of + {"SASL-test","P2B"} -> + upgrade_restart_2a(TestNode); + {"SASL-test","__new_emulator__P1G"} -> + %% catched the node too early - give it another try + {wait,whereis(init)} + end. + +upgrade_restart_2a(TestNode) -> + ?print(["upgrade_restart_2a start"]), + + %% This time we must be there, else something is definitely wrong + {"SASL-test","P2B"} = init:script_id(), + + ?check_release_states([permanent,current]), + ?check_running_app(a,"1.1"), + + ok = release_handler:make_permanent("P2B"), + ?check_release_states([old,permanent]), + + ok. + +upgrade_restart_2b(TestNode) -> + ?print(["upgrade_restart_2b start"]), + + {ok,"P1G",[old_emu,rm_appl]} = release_handler:install_release("P1G"), + ?print(["upgrade_restart_2b P1G installed"]), + ok. + +upgrade_restart_3(TestNode) -> + ?print(["upgrade_restart_3 start"]), + + %% Ideally we should test that the node has only been restarted + %% once... but that's not so easy. Let's just check that P1G is running. + ?check_release_states([current,permanent]), + false = lists:keysearch(a,1,application:loaded_applications()), + ?print(["upgrade_restart_3 no a application found - ok"]), + + ok. + + + %%----------------------------------------------------------------- %% This test starts a client node which uses this node as master @@ -272,6 +470,8 @@ client1_1(TestNode,PrivDir,MasterDir,ClientSname) -> Node = start_client(TestNode,client1,ClientSname), trace_disallowed_calls(Node), + ?check_release_states_client(Node,[permanent]), + %% Check env var for SASL on client node SaslEnv = rpc:call(Node, application, get_all_env, [sasl]), ?print([{client1_1,sasl_env},SaslEnv]), @@ -300,13 +500,14 @@ client1_1(TestNode,PrivDir,MasterDir,ClientSname) -> %% as default. But it is given here in order to force hitting the %% release_handler:check_path function so it can be checked that %% it does not use file:read_file_info on the client node, see - %% trace_disallowed_calls/1 and check_disallowed_calls/0 below. + %% trace_disallowed_calls/1 and check_disallowed_calls/2 below. %% (OTP-9142) {ok, "P1H"} = rpc:call(Node, release_handler, set_unpacked, [filename:join(P1HDir, "rel1.rel"), [{a,"1.0",filename:join(MasterDir,lib)}]]), - ?check_release_client(Node,"P1H",unpacked,["a-1.0"]), + ?check_release_states_client(Node,[permanent,unpacked]), + ?check_release_lib_client(Node,"P1H",["a-1.0"]), ok = rpc:call(Node, release_handler, install_file, ["P1H", filename:join(P1HDir, "start.boot")]), @@ -323,13 +524,16 @@ client1_1(TestNode,PrivDir,MasterDir,ClientSname) -> {ok,"P1G",[new_appl]} = rpc:call(Node, release_handler, install_release, ["P1H"]), + ?check_release_states_client(Node,[permanent,current]), + ?check_running_app_client(Node,a,"1.0"), + Apps = rpc:call(Node, application, which_applications, []), {a,"A CXC 138 11","1.0"} = lists:keyfind(a, 1, Apps), X = rpc:call(Node, a, a, []), {key2, val2} = lists:keyfind(key2, 1, X), {key1, val1} = lists:keyfind(key1, 1, X), - check_disallowed_calls(), + ?check_disallowed_calls, reboot(TestNode,Node), trace_disallowed_calls(Node), @@ -339,17 +543,17 @@ client1_2(TestNode,PrivDir,Node) -> ?print(["client1_2 start"]), %% Check that P1H is still unpacked, install it and make_permanent - ?check_release_client(Node,"P1H",unpacked,["a-1.0"]), + ?check_release_states_client(Node,[permanent,unpacked]), {ok,"P1G",[new_appl]} = rpc:call(Node, release_handler, install_release, ["P1H"]), - ?check_release_client(Node,"P1H",current,["a-1.0"]), + ?check_release_states_client(Node,[permanent,current]), ?check_running_app_client(Node,a,"1.0"), ok = rpc:call(Node, release_handler, make_permanent, ["P1H"]), - ?check_release_client(Node,"P1H",permanent,["a-1.0"]), + ?check_release_states_client(Node,[old,permanent]), - check_disallowed_calls(), + ?check_disallowed_calls, reboot(TestNode,Node), trace_disallowed_calls(Node), @@ -359,10 +563,8 @@ client1_3(TestNode,PrivDir,Node) -> ?print(["client1_3 start"]), %% Check that P1H is permanent - ?check_release_client(Node,"P1H",permanent,["a-1.0"]), - X = rpc:call(Node, a, a, []), - {key2, val2} = lists:keyfind(key2, 1, X), - {key1, val1} = lists:keyfind(key1, 1, X), + ?check_release_states_client(Node,[old,permanent]), + ?check_running_app_client(Node,a,"1.0"), %% Unpack P1I on master {ok, "P1I"} = unpack_release(PrivDir,"rel2"), @@ -374,7 +576,8 @@ client1_3(TestNode,PrivDir,Node) -> {ok, "P1I"} = rpc:call(Node, release_handler, set_unpacked, [filename:join(P1IDir, "rel2.rel"),[]]), - ?check_release_client(Node,"P1I",unpacked,["a-1.1"]), + ?check_release_states_client(Node,[old,permanent,unpacked]), + ?check_release_lib_client(Node,"P1I",["a-1.1"]), ok = rpc:call(Node, release_handler, install_file, ["P1I", filename:join(P1IDir, "start.boot")]), @@ -389,6 +592,7 @@ client1_3(TestNode,PrivDir,Node) -> {ok,"P1H",[{extra, gott}]} = rpc:call(Node, release_handler, install_release, ["P1I"]), + ?check_release_states_client(Node,[old,permanent,current]), ?check_running_app_client(Node,a,"1.1"), X2 = rpc:call(Node, a, a, []), {key2, newval2} = lists:keyfind(key2, 1, X2), @@ -404,6 +608,9 @@ client1_3(TestNode,PrivDir,Node) -> rpc:call(Node, release_handler, set_unpacked, [filename:join(P2ADir, "rel3.rel"),[]]), + ?check_release_states_client(Node,[old,permanent,current,unpacked]), + ?check_release_lib_client(Node,"P2A",["a-1.1"]), + ok = rpc:call(Node, release_handler, install_file, ["P2A", filename:join(P2ADir, "start.boot")]), ok = rpc:call(Node, release_handler, install_file, @@ -413,66 +620,136 @@ client1_3(TestNode,PrivDir,Node) -> {ok, "P1I", [new_emu]} = rpc:call(Node, release_handler, check_install_release, ["P2A"]), + + %% Reboot from P1H + ?check_disallowed_calls, + reboot(TestNode,Node), + trace_disallowed_calls(Node), + + client1_4(TestNode,Node). + +client1_4(TestNode,Node) -> + ?print(["client1_4 start"]), + + %% check that P1H is used + ?check_release_states_client(Node,[old,permanent,unpacked,unpacked]), + + %% since the install_release below reboot the node... + ?check_disallowed_calls, + cover_client(TestNode,Node,stop_cover), + + {continue_after_restart, "P1H", [new_emu,new_appl]} = + rpc:call(Node, release_handler, install_release, ["P2A"]), + %% Reboots the client ! + + check_reboot(TestNode,Node), + trace_disallowed_calls(Node), + + client1_5(TestNode,Node). + +client1_5(TestNode,Node) -> + ?print(["client1_5 start"]), + + %% Check that P2A is in use. + ?check_release_states_client(Node,[old,permanent,unpacked,current]), + ?check_running_app_client(Node,a,"1.1"), + X = rpc:call(Node, a, a, []), + {key2, newval2} = lists:keyfind(key2, 1, X), + {key1, val1} = lists:keyfind(key1, 1, X), + {ok, bval} = rpc:call(Node, a, b, []), + + %% since the install_release below reboot the node... + ?check_disallowed_calls, + cover_client(TestNode,Node,stop_cover), + + {ok,"P1I",[old_emu]} = + rpc:call(Node, release_handler, install_release, ["P1I"]), + + check_reboot(TestNode,Node), + trace_disallowed_calls(Node), + + client1_6(TestNode,Node). + +client1_6(TestNode,Node) -> + ?print(["client1_6 start"]), + + ?check_release_states_client(Node,[old,permanent,current,old]), + ?check_running_app_client(Node,a,"1.1"), + ok = rpc:call(Node, release_handler, make_permanent, ["P1I"]), - ?check_release_client(Node,"P1I",permanent,["a-1.1"]), + ?check_release_states_client(Node,[old,old,permanent,old]), %% since the install_release below reboot the node... - check_disallowed_calls(), + ?check_disallowed_calls, cover_client(TestNode,Node,stop_cover), - {ok, "P1I", [new_emu]} = + {continue_after_restart, "P1I", [new_emu]} = rpc:call(Node, release_handler, install_release, ["P2A"]), %% Reboots the client ! check_reboot(TestNode,Node), trace_disallowed_calls(Node), - client1_4(TestNode,Node). + client1_7(TestNode,Node). -client1_4(TestNode,Node) -> - ?print(["client1_4 start"]), +client1_7(TestNode,Node) -> + ?print(["client1_7 start"]), %% Check that P2A is in use. - ?check_release_client(Node,"P2A",current,["a-1.1"]), + ?check_release_states_client(Node,[old,old,permanent,current]), ?check_running_app_client(Node,a,"1.1"), X = rpc:call(Node, a, a, []), {key2, newval2} = lists:keyfind(key2, 1, X), {key1, val1} = lists:keyfind(key1, 1, X), {ok, bval} = rpc:call(Node, a, b, []), - %% Reboot from P1I - check_disallowed_calls(), - reboot(TestNode,Node), + %% since the install_release below reboot the node... + ?check_disallowed_calls, + cover_client(TestNode,Node,stop_cover), + + {ok,"P1H",[old_emu,old_appl]} = + rpc:call(Node, release_handler, install_release, ["P1H"]), + + check_reboot(TestNode,Node), trace_disallowed_calls(Node), - client1_5(TestNode,Node). + client1_8(TestNode,Node). -client1_5(TestNode,Node) -> - ?print(["client1_5 start"]), +client1_8(TestNode,Node) -> + ?print(["client1_8 start"]), - %% Check that P1I is used - {ok, "P1I", [new_emu]} = + %% Check that P1H is used + ?check_release_states_client(Node,[old,current,permanent,old]), + ?check_running_app_client(Node,a,"1.0"), + {ok, "P1H", [new_emu,new_appl]} = rpc:call(Node, release_handler, check_install_release, ["P2A"]), + + {ok,"P1H",[{extra, gott}]} = + rpc:call(Node, release_handler, install_release, ["P1I"]), + ?check_release_states_client(Node,[old,old,permanent,old]), + ?check_running_app_client(Node,a,"1.1"), + + %% since the install_release below will reboot the node... - check_disallowed_calls(), + ?check_disallowed_calls, cover_client(TestNode,Node,stop_cover), %% Install P2A again - {ok, "P1I", [new_emu]} = + {continue_after_restart, "P1I", [new_emu]} = rpc:call(Node, release_handler, install_release, ["P2A"]), %% We are rebooted again. check_reboot(TestNode,Node), trace_disallowed_calls(Node), - client1_6(TestNode,Node). + client1_9(TestNode,Node). -client1_6(TestNode,Node) -> - ?print(["client1_6 start"]), +client1_9(TestNode,Node) -> + ?print(["client1_9 start"]), %% Check that P2A is used - ?check_release_client(Node,"P2A",current,["a-1.1"]), + ?check_release_states_client(Node,[old,old,permanent,current]), ?check_running_app_client(Node,a,"1.1"), X = rpc:call(Node, a, a, []), {key2, newval2} = lists:keyfind(key2, 1, X), @@ -481,22 +758,23 @@ client1_6(TestNode,Node) -> %% Make P2A permanent ok = rpc:call(Node, release_handler, make_permanent, ["P2A"]), + ?check_release_states_client(Node,[old,old,old,permanent]), %% Reboot from P2A - check_disallowed_calls(), + ?check_disallowed_calls, reboot(TestNode,Node), trace_disallowed_calls(Node), - client1_7(TestNode,Node). + client1_10(TestNode,Node). -client1_7(TestNode,Node) -> - ?print(["client1_7 start"]), +client1_10(TestNode,Node) -> + ?print(["client1_10 start"]), %% Check that P2A is used - ?check_release_client(Node,"P2A",permanent,["a-1.1"]), + ?check_release_states_client(Node,[old,old,old,permanent]), %% since the reboot_old_release below will reboot the node - check_disallowed_calls(), + ?check_disallowed_calls, cover_client(TestNode,Node,stop_cover), %% Install old P1H @@ -505,41 +783,45 @@ client1_7(TestNode,Node) -> check_reboot(TestNode,Node), trace_disallowed_calls(Node), - client1_8(TestNode,Node). + client1_11(TestNode,Node). -client1_8(TestNode,Node) -> - ?print(["client1_8 start"]), +client1_11(TestNode,Node) -> + ?print(["client1_11 start"]), %% Check that P1H is permanent - ?check_release_client(Node,"P1H",permanent,["a-1.0"]), + ?check_release_states_client(Node,[old,permanent,old,old]), + ?check_running_app_client(Node,a,"1.0"), X = rpc:call(Node, a, a, []), {key2, val2} = lists:keyfind(key2, 1, X), {key1, val1} = lists:keyfind(key1, 1, X), - %% Remove P1I and P2I from client + %% Remove P1I and P2A from client ok = rpc:call(Node, release_handler, set_removed, ["P2A"]), + ?check_release_states_client(Node,[old,permanent,old]), ok = rpc:call(Node, release_handler, set_removed, ["P1I"]), + ?check_release_states_client(Node,[old,permanent]), - check_disallowed_calls(), - reboot(TestNode,Node), - trace_disallowed_calls(Node), - - client1_9(TestNode,Node). - -client1_9(TestNode,Node) -> - ?print(["client1_9 start"]), - - %% Check that P2A and P1I does not exists and that PiH is permanent. + %% Check that P2A and P1I does not exists Rels = rpc:call(Node, release_handler, which_releases, []), false = lists:keysearch("P2A", 2, Rels), false = lists:keysearch("P1I", 2, Rels), - ?check_release_client(Node,"P1H",permanent,["a-1.0"]), X = rpc:call(Node, a, a, []), {key2, val2} = lists:keyfind(key2, 1, X), {key1, val1} = lists:keyfind(key1, 1, X), + ?check_disallowed_calls, + reboot(TestNode,Node), + trace_disallowed_calls(Node), + + client1_12(TestNode,Node). + +client1_12(TestNode,Node) -> + ?print(["client1_12 start"]), + + ?check_release_states_client(Node,[old,permanent]), + %% since the reboot_old_release below will reboot the node - check_disallowed_calls(), + ?check_disallowed_calls, cover_client(TestNode,Node,stop_cover), %% Install old P1G @@ -548,33 +830,34 @@ client1_9(TestNode,Node) -> check_reboot(TestNode,Node), trace_disallowed_calls(Node), - client1_10(TestNode,Node). + client1_13(TestNode,Node). -client1_10(TestNode,Node) -> - ?print(["client1_10 start"]), +client1_13(TestNode,Node) -> + ?print(["client1_13 start"]), %% Check that P1G is permanent - ?check_release_client(Node,"P1G",permanent,[]), - ?check_release_client(Node,"P1H",old,["a-1.0"]), + ?check_release_states_client(Node,[permanent,old]), {error,client_node} = rpc:call(Node,release_handler,remove_release,["P1H"]), ok = rpc:call(Node, release_handler, set_removed, ["P1H"]), + ?check_release_states_client(Node,[permanent]), - check_disallowed_calls(), + ?check_disallowed_calls, reboot(TestNode,Node), trace_disallowed_calls(Node), - client1_11(TestNode,Node). + client1_14(TestNode,Node). -client1_11(TestNode,Node) -> - ?print(["client1_11 start"]), +client1_14(TestNode,Node) -> + ?print(["client1_14 start"]), %% Check that P1G is permanent - ?check_release_client(Node,"P1G",permanent,[]), + ?check_release_states_client(Node,[permanent]), - check_disallowed_calls(), + ?check_disallowed_calls, stop_client(TestNode,Node), %% TEST IS OK !! net_kernel:monitor_nodes(false), + %% Remove releases from master ok = release_handler:remove_release("P2A"), ok = release_handler:remove_release("P1I"), ok = release_handler:remove_release("P1H"), @@ -595,9 +878,10 @@ trace_disallowed_calls(Node) -> rpc:call(Node,dbg,p,[all,call]), rpc:call(Node,dbg,tp,[file,[{'_',[],[{message,{caller}}]}]]). -check_disallowed_calls() -> +check_disallowed_calls(TestNode,Line) -> receive Trace when element(1,Trace)==trace -> + ?print_line(Line,["Disallowed function called",Trace]), exit({disallowed_function_call,Trace}) after 0 -> ok @@ -628,7 +912,7 @@ start_client_unix(TestNode,Sname,Node) -> start_client_win32(TestNode,Client,ClientSname) -> Name = atom_to_list(ClientSname) ++ "_P1G", RootDir = code:root_dir(), - ErtsBinDir = filename:join(RootDir,"erts-4.4/bin"), + ErtsBinDir = filename:join([RootDir,"erts-"++?ertsvsn,"bin"]), {ClientArgs,RelClientDir} = rh_test_lib:get_client_args(Client,ClientSname, RootDir), @@ -729,8 +1013,10 @@ client2(TestNode,PrivDir,ClientSname) -> ok end, + %% Unpack P1H on master {ok, "P1H"} = unpack_release(PrivDir,"rel1"), + %% Try to set P1H unpacked on client Root = code:root_dir(), {error,{bad_masters,[Master2]}} = rpc:call(Node, release_handler, set_unpacked, @@ -755,15 +1041,17 @@ stop(Now) -> unpack_p1h(TestNode,PrivDir) -> {ok, "P1H"} = unpack_release(PrivDir,"rel1"), - ?check_release("P1H",unpacked,["a-1.0"]), + ?check_release_states([permanent,unpacked]), + ?check_release_lib("P1H",["a-1.0"]), ok. permanent_p1h(TestNode) -> - ?check_release("P1H",unpacked,["a-1.0"]), + ?check_release_states([permanent,unpacked]), + ?check_release_lib("P1H",["a-1.0"]), {ok,"P1G",[new_appl]} = release_handler:install_release("P1H"), - ?check_release("P1H",current,["a-1.0"]), + ?check_release_states([permanent,current]), ok = release_handler:make_permanent("P1H"), - ?check_release("P1H",permanent,["a-1.0"]), + ?check_release_states([old,permanent]), ok. @@ -779,24 +1067,38 @@ registered_loop(_Name) -> exit(killed) end. -check_release(TestNode,Node,Vsn,Status,Apps,Line) -> +%% Checks that the list of states for all releases (sorted on vsn) +%% equals the input States +check_release_states(TestNode,Node,States,Line) -> + case rpc:call(Node,release_handler,which_releases,[]) of + {badrpc,_}=Error -> + ?fail_line(Line,{check_release_states,Node,States,Error}); + Rels -> + ?print_line(Line,["check_release_states:", Rels]), + States = [Status || {_,_,_,Status} <- lists:keysort(2,Rels)], + ok + end. + +%% Check that the given release (Vsn) sees the correct vsn of App. +check_release_lib(TestNode,Node,Vsn,Apps,Line) -> case rpc:call(Node,release_handler,which_releases,[]) of {badrpc,_}=Error -> - ?fail_line(Line,{check_release,Node,Vsn,Status,Error}); + ?fail_line(Line,{check_release_lib,Node,Vsn,Apps,Error}); Rels -> - ?print_line(Line,["check_release:", Rels]), - {"SASL-test", Vsn, Libs, Status} = lists:keyfind(Vsn, 2, Rels), + ?print_line(Line,["check_release_lib:", Rels]), + {"SASL-test", Vsn, Libs, _Status} = lists:keyfind(Vsn, 2, Rels), true = lists:all(fun(App) -> lists:member(App,Libs) end,Apps), ok end. +%% Check that the given Vsn of App is executed check_running_app(TestNode,Node,App,Vsn,Line) -> case rpc:call(Node,application,which_applications,[]) of {badrpc,_}=Error -> ?fail_line(Line,{check_running_app,Node,App,Vsn,Error}); Apps -> ?print_line(Line,["check_running_app:", Apps]), - {App, _, Vsn} = lists:keyfind(a, 1, Apps), + {App, _, Vsn} = lists:keyfind(App, 1, Apps), ok end. diff --git a/lib/sasl/test/overload_SUITE.erl b/lib/sasl/test/overload_SUITE.erl index 92b1aaed6e..e7f180b2ea 100644 --- a/lib/sasl/test/overload_SUITE.erl +++ b/lib/sasl/test/overload_SUITE.erl @@ -18,14 +18,13 @@ %% -module(overload_SUITE). --include("test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). -compile(export_all). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% all() -> [info, set_config_data, set_env_vars, request, timeout]. -all(suite) -> all(). init_per_testcase(_Case,Config) -> restart_sasl(), @@ -38,37 +37,34 @@ end_per_testcase(Case,Config) -> ok. %%%----------------------------------------------------------------- -info(suite) -> []; info(_Config) -> - ?line Info = overload:get_overload_info(), - ?line [{total_intensity,0.0}, - {accept_intensity,0.0}, - {max_intensity,0.8}, - {weight,0.1}, - {total_requests,0}, - {accepted_requests,0}] = Info. + Info = overload:get_overload_info(), + [{total_intensity,0.0}, + {accept_intensity,0.0}, + {max_intensity,0.8}, + {weight,0.1}, + {total_requests,0}, + {accepted_requests,0}] = Info. %%%----------------------------------------------------------------- -set_config_data(suite) -> []; set_config_data(_Config) -> - ?line InfoDefault = overload:get_overload_info(), - ?line ok = check_info(0.8,0.1,InfoDefault), - ?line ok = overload:set_config_data(0.5,0.4), - ?line Info1 = overload:get_overload_info(), - ?line ok = check_info(0.5,0.4,Info1), + InfoDefault = overload:get_overload_info(), + ok = check_info(0.8,0.1,InfoDefault), + ok = overload:set_config_data(0.5,0.4), + Info1 = overload:get_overload_info(), + ok = check_info(0.5,0.4,Info1), ok. %%%----------------------------------------------------------------- -set_env_vars(suite) -> []; set_env_vars(_Config) -> - ?line InfoDefault = overload:get_overload_info(), - ?line ok = check_info(0.8,0.1,InfoDefault), - ?line ok = application:set_env(sasl,overload_max_intensity,0.5), - ?line ok = application:set_env(sasl,overload_weight,0.4), - ?line ok = application:stop(sasl), - ?line ok = application:start(sasl), - ?line Info1 = overload:get_overload_info(), - ?line ok = check_info(0.5,0.4,Info1), + InfoDefault = overload:get_overload_info(), + ok = check_info(0.8,0.1,InfoDefault), + ok = application:set_env(sasl,overload_max_intensity,0.5), + ok = application:set_env(sasl,overload_weight,0.4), + ok = application:stop(sasl), + ok = application:start(sasl), + Info1 = overload:get_overload_info(), + ok = check_info(0.5,0.4,Info1), ok. set_env_vars(cleanup,_Config) -> application:unset_env(sasl,overload_max_intensity), @@ -76,63 +72,61 @@ set_env_vars(cleanup,_Config) -> ok. %%%----------------------------------------------------------------- -request(suite) -> []; request(_Config) -> %% Find number of request that can be done with default settings %% and no delay - ?line overload:set_config_data(0.8, 0.1), - ?line NDefault = do_many_requests(0), - ?line restart_sasl(), - ?line ?t:format("NDefault: ~p",[NDefault]), - + overload:set_config_data(0.8, 0.1), + NDefault = do_many_requests(0), + restart_sasl(), + ?t:format("NDefault: ~p",[NDefault]), + %% Check that the number of requests increases when max_intensity %% increases - ?line overload:set_config_data(2, 0.1), - ?line NLargeMI = do_many_requests(0), - ?line restart_sasl(), - ?line ?t:format("NLargeMI: ~p",[NLargeMI]), - ?line true = NLargeMI > NDefault, + overload:set_config_data(2, 0.1), + NLargeMI = do_many_requests(0), + restart_sasl(), + ?t:format("NLargeMI: ~p",[NLargeMI]), + true = NLargeMI > NDefault, %% Check that the number of requests decreases when weight %% increases - ?line overload:set_config_data(0.8, 1), - ?line NLargeWeight = do_many_requests(0), - ?line restart_sasl(), - ?line ?t:format("NLargeWeight: ~p",[NLargeWeight]), - ?line true = NLargeWeight < NDefault, + overload:set_config_data(0.8, 1), + NLargeWeight = do_many_requests(0), + restart_sasl(), + ?t:format("NLargeWeight: ~p",[NLargeWeight]), + true = NLargeWeight < NDefault, %% Check that number of requests increases when delay between %% requests increases. %% (Keeping same config and comparing to large weight in order to %% minimize the time needed for this case.) - ?line overload:set_config_data(0.8, 1), - ?line NLargeTime = do_many_requests(500), - ?line restart_sasl(), - ?line ?t:format("NLargeTime: ~p",[NLargeTime]), - ?line true = NLargeTime > NLargeWeight, + overload:set_config_data(0.8, 1), + NLargeTime = do_many_requests(500), + restart_sasl(), + ?t:format("NLargeTime: ~p",[NLargeTime]), + true = NLargeTime > NLargeWeight, ok. %%%----------------------------------------------------------------- -timeout(suite) -> []; timeout(_Config) -> - ?line overload:set_config_data(0.8, 1), - ?line _N = do_many_requests(0), - + overload:set_config_data(0.8, 1), + _N = do_many_requests(0), + %% Check that the overload alarm is raised - ?line [{overload,_}] = alarm_handler:get_alarms(), + [{overload,_}] = alarm_handler:get_alarms(), %% Fake a clear timeout in overload.erl and check that, since it %% came very soon after the overload situation, the alarm is not %% cleared - ?line overload ! timeout, - ?line timer:sleep(1000), - ?line [{overload,_}] = alarm_handler:get_alarms(), + overload ! timeout, + timer:sleep(1000), + [{overload,_}] = alarm_handler:get_alarms(), %% A bit later, try again and check that this time the alarm is %% cleared - ?line overload ! timeout, - ?line timer:sleep(1000), - ?line [] = alarm_handler:get_alarms(), + overload ! timeout, + timer:sleep(1000), + [] = alarm_handler:get_alarms(), ok. @@ -171,5 +165,3 @@ check_info(MI,W,Info) -> {{_,MI},{_,W}} -> ok; _ -> ?t:fail({unexpected_info,MI,W,Info}) end. - - diff --git a/lib/sasl/test/rb_SUITE.erl b/lib/sasl/test/rb_SUITE.erl index b53c382609..35a4eb7e7b 100644 --- a/lib/sasl/test/rb_SUITE.erl +++ b/lib/sasl/test/rb_SUITE.erl @@ -18,7 +18,8 @@ %% -module(rb_SUITE). --include("test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). + -compile(export_all). @@ -45,19 +46,10 @@ groups() -> ]}]. -all(suite) -> - no_group_cases() ++ - [{conf, - install_mf_h, - element(3,lists:keyfind(running_error_logger,1,groups())), - remove_mf_h} - ]. - - init_per_suite(Config) -> - ?line PrivDir = ?config(priv_dir,Config), - ?line RbDir = filename:join(PrivDir,rb), - ?line ok = file:make_dir(RbDir), + PrivDir = ?config(priv_dir,Config), + RbDir = filename:join(PrivDir,rb), + ok = file:make_dir(RbDir), NewConfig = [{rb_dir,RbDir}|Config], reset_sasl(NewConfig), NewConfig. @@ -66,10 +58,18 @@ end_per_suite(_Config) -> ok. init_per_group(running_error_logger,Config) -> - install_mf_h(Config). + %% Install log_mf_h + RbDir = ?config(rb_dir,Config), + ok = application:set_env(sasl,error_logger_mf_dir,RbDir), + ok = application:set_env(sasl,error_logger_mf_maxbytes,5000), + ok = application:set_env(sasl,error_logger_mf_maxfiles,2), + restart_sasl(), + Config. end_per_group(running_error_logger,Config) -> - remove_mf_h(Config). + %% Remove log_mf_h??? + ok. + init_per_testcase(_Case,Config) -> case whereis(?SUP) of @@ -92,187 +92,152 @@ end_per_testcase(Case,Config) -> %%%----------------------------------------------------------------- +%%% Test cases -help() -> help(suite). -help(suite) -> []; help(_Config) -> - ?line Help = capture(fun() -> rb:h() end), - ?line "Report Browser Tool - usage" = hd(Help), - ?line "rb:stop - stop the rb_server" = lists:last(Help), + Help = capture(fun() -> rb:h() end), + "Report Browser Tool - usage" = hd(Help), + "rb:stop - stop the rb_server" = lists:last(Help), ok. - -start_error_stop() -> start_error_stop(suite). -start_error_stop(suite) -> []; +%% Test that all three sasl env vars must be set for a successful start of rb +%% Then stop rb. start_error_stop(Config) -> - ?line RbDir = ?config(rb_dir,Config), - - ?line {error,{"cannot locate report directory",_}} = rb:start(), - - - ?line ok = application:set_env(sasl,error_logger_mf_dir,"invaliddir"), - ?line ok = application:set_env(sasl,error_logger_mf_maxbytes,1000), - ?line ok = application:set_env(sasl,error_logger_mf_maxfiles,2), - ?line restart_sasl(), - ?line {error,{"cannot read the index file",_}} = rb:start(), - ?line ok = application:set_env(sasl,error_logger_mf_dir,RbDir), - ?line restart_sasl(), - ?line {ok,_} = rb:start(), - - ?line ok = rb:stop(), - ok. + RbDir = ?config(rb_dir,Config), + {error,{"cannot locate report directory",_}} = rb:start(), -%% start_opts(suite) -> []; -%% start_opts(Config) -> -%% PrivDir = ?config(priv_dir,Config), -%% RbDir = filename:join(PrivDir,rb_opts), -%% ok = file:make_dir(RbDir), - -install_mf_h(Config) -> - ?line RbDir = ?config(rb_dir,Config), - ?line ok = application:set_env(sasl,error_logger_mf_dir,RbDir), - ?line ok = application:set_env(sasl,error_logger_mf_maxbytes,5000), - ?line ok = application:set_env(sasl,error_logger_mf_maxfiles,2), - ?line restart_sasl(), - Config. + ok = application:set_env(sasl,error_logger_mf_dir,"invaliddir"), + ok = application:set_env(sasl,error_logger_mf_maxbytes,1000), + ok = application:set_env(sasl,error_logger_mf_maxfiles,2), + restart_sasl(), + {error,{"cannot read the index file",_}} = rb:start(), + ok = application:set_env(sasl,error_logger_mf_dir,RbDir), + restart_sasl(), + {ok,_} = rb:start(), -remove_mf_h(_Config) -> + ok = rb:stop(), ok. - - -show() -> show(suite). -show(suite) -> []; show(Config) -> - ?line PrivDir = ?config(priv_dir,Config), - ?line OutFile = filename:join(PrivDir,"rb_SUITE_log.txt"), - + PrivDir = ?config(priv_dir,Config), + OutFile = filename:join(PrivDir,"rb_SUITE_log.txt"), + %% Insert some reports in the error log and start rb init_error_logs(), - ?line ok = start_rb(OutFile), + ok = start_rb(OutFile), %% Show all reports - ?line All = check_report(fun() -> rb:show() end,OutFile), + All = check_report(fun() -> rb:show() end,OutFile), %% Show by number - ?line [{_,First}] = check_report(fun() -> rb:show(1) end,OutFile), - ?line {1,First} = lists:keyfind(1,1,All), + [{_,First}] = check_report(fun() -> rb:show(1) end,OutFile), + {1,First} = lists:keyfind(1,1,All), %% Show by type - ?line [{_,CR}] = check_report(fun() -> rb:show(crash_report) end,OutFile), - ?line true = contains(CR,"rb_test_crash"), - ?line [{_,EC},{_,EM}] = check_report(fun() -> rb:show(error) end,OutFile), - ?line true = contains(EC,"rb_test_crash"), - ?line true = contains(EM,"rb_test_error_msg"), - ?line [{_,ER}] = check_report(fun() -> rb:show(error_report) end,OutFile), - ?line true = contains(ER,"rb_test_error"), - ?line [{_,IR}] = check_report(fun() -> rb:show(info_report) end,OutFile), - ?line true = contains(IR,"rb_test_info"), - ?line [{_,IM}] = check_report(fun() -> rb:show(info_msg) end,OutFile), - ?line true = contains(IM,"rb_test_info_msg"), - ?line [_|_] = check_report(fun() -> rb:show(progress) end,OutFile), - ?line [{_,SR}] = check_report(fun() -> rb:show(supervisor_report) end, - OutFile), - ?line true = contains(SR,"child_terminated"), - ?line true = contains(SR,"{rb_SUITE,rb_test_crash}"), + [{_,CR}] = check_report(fun() -> rb:show(crash_report) end,OutFile), + true = contains(CR,"rb_test_crash"), + [{_,EC},{_,EM}] = check_report(fun() -> rb:show(error) end,OutFile), + true = contains(EC,"rb_test_crash"), + true = contains(EM,"rb_test_error_msg"), + [{_,ER}] = check_report(fun() -> rb:show(error_report) end,OutFile), + true = contains(ER,"rb_test_error"), + [{_,IR}] = check_report(fun() -> rb:show(info_report) end,OutFile), + true = contains(IR,"rb_test_info"), + [{_,IM}] = check_report(fun() -> rb:show(info_msg) end,OutFile), + true = contains(IM,"rb_test_info_msg"), + [_|_] = check_report(fun() -> rb:show(progress) end,OutFile), + [{_,SR}] = check_report(fun() -> rb:show(supervisor_report) end, + OutFile), + true = contains(SR,"child_terminated"), + true = contains(SR,"{rb_SUITE,rb_test_crash}"), ok. -list() -> list(suite). -list(suite) -> []; list(Config) -> - ?line PrivDir = ?config(priv_dir,Config), - ?line OutFile = filename:join(PrivDir,"rb_SUITE_log.txt"), + PrivDir = ?config(priv_dir,Config), + OutFile = filename:join(PrivDir,"rb_SUITE_log.txt"), %% Insert some reports in the error log and start rb init_error_logs(), - ?line ok = start_rb(OutFile), - - ?line All = capture(fun() -> rb:list() end), - ?line [{crash_report,[_]=CR}, - {error,[_,_]=EM}, - {error_report,[_]=ER}, - {info_msg,[_]=IM}, - {info_report,[_]=IR}, - {progress,[_|_]=P}, - {supervisor_report,[_]=SR}] = sort_list(All), - - ?line [{crash_report,CR}] = + ok = start_rb(OutFile), + + All = capture(fun() -> rb:list() end), + [{crash_report,[_]=CR}, + {error,[_,_]=EM}, + {error_report,[_]=ER}, + {info_msg,[_]=IM}, + {info_report,[_]=IR}, + {progress,[_|_]=P}, + {supervisor_report,[_]=SR}] = sort_list(All), + + [{crash_report,CR}] = sort_list(capture(fun() -> rb:list(crash_report) end)), - ?line [{error,EM}] = + [{error,EM}] = sort_list(capture(fun() -> rb:list(error) end)), - ?line [{error_report,ER}] = + [{error_report,ER}] = sort_list(capture(fun() -> rb:list(error_report) end)), - ?line [{info_msg,IM}] = + [{info_msg,IM}] = sort_list(capture(fun() -> rb:list(info_msg) end)), - ?line [{info_report,IR}] = + [{info_report,IR}] = sort_list(capture(fun() -> rb:list(info_report) end)), - ?line [{progress,P}] = + [{progress,P}] = sort_list(capture(fun() -> rb:list(progress) end)), - ?line [{supervisor_report,SR}] = + [{supervisor_report,SR}] = sort_list(capture(fun() -> rb:list(supervisor_report) end)), - - ok. + ok. -grep() -> grep(suite). -grep(suite) -> []; grep(Config) -> - ?line PrivDir = ?config(priv_dir,Config), - ?line OutFile = filename:join(PrivDir,"rb_SUITE_log.txt"), + PrivDir = ?config(priv_dir,Config), + OutFile = filename:join(PrivDir,"rb_SUITE_log.txt"), %% Insert some reports in the error log and start rb init_error_logs(), - ?line ok = start_rb(OutFile), - - ?line [{_,S}, - {_,CR}, - {_,EC}, - {_,IM}, - {_,IR}, - {_,EM}, - {_,ER}]= check_report(fun() -> rb:grep("rb_test_") end,OutFile), - ?line true = contains(S, "rb_test_crash"), - ?line true = contains(CR, "rb_test_crash"), - ?line true = contains(EC, "rb_test_crash"), - ?line true = contains(IM, "rb_test_info_msg"), - ?line true = contains(IR, "rb_test_info"), - ?line true = contains(EM, "rb_test_error_msg"), - ?line true = contains(ER, "rb_test_error"), + ok = start_rb(OutFile), + + [{_,S}, + {_,CR}, + {_,EC}, + {_,IM}, + {_,IR}, + {_,EM}, + {_,ER}]= check_report(fun() -> rb:grep("rb_test_") end,OutFile), + true = contains(S, "rb_test_crash"), + true = contains(CR, "rb_test_crash"), + true = contains(EC, "rb_test_crash"), + true = contains(IM, "rb_test_info_msg"), + true = contains(IR, "rb_test_info"), + true = contains(EM, "rb_test_error_msg"), + true = contains(ER, "rb_test_error"), ok. - -filter_filter() -> filter_filter(suite). -filter_filter(suite) -> []; filter_filter(Config) -> - ?line PrivDir = ?config(priv_dir,Config), - ?line OutFile = filename:join(PrivDir,"rb_SUITE_log.txt"), + PrivDir = ?config(priv_dir,Config), + OutFile = filename:join(PrivDir,"rb_SUITE_log.txt"), %% Insert some reports in the error log and start rb init_error_logs(), - ?line ok = start_rb(OutFile), + ok = start_rb(OutFile), - ?line All = check_report(fun() -> rb:show() end,OutFile), + All = check_report(fun() -> rb:show() end,OutFile), - ?line ER = [_] = rb_filter([{rb_SUITE,rb_test_error}],OutFile), - ?line [] = rb_filter([{rb_SUITE,rb_test}],OutFile), - ?line _E = [_,_] = rb_filter([{rb_SUITE,"rb_test",re}],OutFile), - ?line AllButER = rb_filter([{rb_SUITE,rb_test_error,no}],OutFile), + ER = [_] = rb_filter([{rb_SUITE,rb_test_error}],OutFile), + [] = rb_filter([{rb_SUITE,rb_test}],OutFile), + _E = [_,_] = rb_filter([{rb_SUITE,"rb_test",re}],OutFile), + AllButER = rb_filter([{rb_SUITE,rb_test_error,no}],OutFile), {_,AllRep} = lists:unzip(All), {_,ERRep} = lists:unzip(ER), {_,AllButERRep} = lists:unzip(AllButER), - ?line AllButERRep = AllRep -- ERRep, + AllButERRep = AllRep -- ERRep, ok. -filter_date() -> filter_date(suite). -filter_date(suite) -> []; filter_date(Config) -> - ?line PrivDir = ?config(priv_dir,Config), - ?line OutFile = filename:join(PrivDir,"rb_SUITE_log.txt"), + PrivDir = ?config(priv_dir,Config), + OutFile = filename:join(PrivDir,"rb_SUITE_log.txt"), %% Insert some reports in the error log and start rb @@ -280,35 +245,33 @@ filter_date(Config) -> Between1 = calendar:local_time(), timer:sleep(1000), Between2 = calendar:local_time(), - ?line ok = start_rb(OutFile), + ok = start_rb(OutFile), - ?line All = check_report(fun() -> rb:show() end,OutFile), + All = check_report(fun() -> rb:show() end,OutFile), Before = calendar:gregorian_seconds_to_datetime( - calendar:datetime_to_gregorian_seconds(calendar:local_time()) - 10), + calendar:datetime_to_gregorian_seconds(calendar:local_time()) - 10), After = calendar:gregorian_seconds_to_datetime( calendar:datetime_to_gregorian_seconds(calendar:local_time()) + 1), - ?line All = rb_filter([],{Before,from},OutFile), - ?line All = rb_filter([],{After,to},OutFile), - ?line [] = rb_filter([],{Before,to},OutFile), - ?line [] = rb_filter([],{After,from},OutFile), - ?line All = rb_filter([],{Before,After},OutFile), + All = rb_filter([],{Before,from},OutFile), + All = rb_filter([],{After,to},OutFile), + [] = rb_filter([],{Before,to},OutFile), + [] = rb_filter([],{After,from},OutFile), + All = rb_filter([],{Before,After},OutFile), %%?t:format("~p~n",[All]), - ?line AllButLast = [{N-1,R} || {N,R} <- tl(All)], - ?line AllButLast = rb_filter([],{Before,Between1},OutFile), + AllButLast = [{N-1,R} || {N,R} <- tl(All)], + AllButLast = rb_filter([],{Before,Between1},OutFile), - ?line Last = hd(All), - ?line [Last] = rb_filter([],{Between2,After},OutFile), + Last = hd(All), + [Last] = rb_filter([],{Between2,After},OutFile), ok. -filter_filter_and_date() -> filter_filter_and_date(suite). -filter_filter_and_date(suite) -> []; filter_filter_and_date(Config) -> - ?line PrivDir = ?config(priv_dir,Config), - ?line OutFile = filename:join(PrivDir,"rb_SUITE_log.txt"), + PrivDir = ?config(priv_dir,Config), + OutFile = filename:join(PrivDir,"rb_SUITE_log.txt"), %% Insert some reports in the error log and start rb @@ -316,102 +279,96 @@ filter_filter_and_date(Config) -> Between1 = calendar:local_time(), timer:sleep(1000), Between2 = calendar:local_time(), - ?line error_logger:error_report([{rb_SUITE,rb_test_filter}]), - ?line ok = start_rb(OutFile), + error_logger:error_report([{rb_SUITE,rb_test_filter}]), + ok = start_rb(OutFile), Before = calendar:gregorian_seconds_to_datetime( - calendar:datetime_to_gregorian_seconds(calendar:local_time()) - 10), + calendar:datetime_to_gregorian_seconds(calendar:local_time()) - 10), After = calendar:gregorian_seconds_to_datetime( calendar:datetime_to_gregorian_seconds(calendar:local_time()) + 1), - ?line All = check_report(fun() -> rb:show() end,OutFile), - ?line Last = hd(All), + All = check_report(fun() -> rb:show() end,OutFile), + Last = hd(All), - ?line [_,_,_] = rb_filter([{rb_SUITE,"rb_test",re}],{Before,After},OutFile), - ?line [_,_] = rb_filter([{rb_SUITE,"rb_test",re}],{Before,Between1},OutFile), - ?line [_] = rb_filter([{rb_SUITE,"rb_test",re}],{Between2,After},OutFile), - ?line [_] = rb_filter([{rb_SUITE,rb_test_filter}],{Before,After},OutFile), - ?line [] = rb_filter([{rb_SUITE,rb_test_filter}],{Before,Between1},OutFile), - ?line [Last] = rb_filter([{rb_SUITE,rb_test_filter,no}],{Between2,After},OutFile), - ?line {_,Str} = Last, - ?line false = contains(Str,"rb_test_filter"), + [_,_,_] = rb_filter([{rb_SUITE,"rb_test",re}],{Before,After},OutFile), + [_,_] = rb_filter([{rb_SUITE,"rb_test",re}],{Before,Between1},OutFile), + [_] = rb_filter([{rb_SUITE,"rb_test",re}],{Between2,After},OutFile), + [_] = rb_filter([{rb_SUITE,rb_test_filter}],{Before,After},OutFile), + [] = rb_filter([{rb_SUITE,rb_test_filter}],{Before,Between1},OutFile), + [Last] = rb_filter([{rb_SUITE,rb_test_filter,no}],{Between2,After},OutFile), + {_,Str} = Last, + false = contains(Str,"rb_test_filter"), ok. -filter_re_no() -> filter_re_no(suite). -filter_re_no(suite) -> []; filter_re_no(Config) -> - ?line PrivDir = ?config(priv_dir,Config), - ?line OutFile = filename:join(PrivDir,"rb_SUITE_log.txt"), + PrivDir = ?config(priv_dir,Config), + OutFile = filename:join(PrivDir,"rb_SUITE_log.txt"), %% Insert some reports in the error log and start rb init_error_logs(), - ?line ok = start_rb(OutFile), + ok = start_rb(OutFile), - ?line All = check_report(fun() -> rb:show() end,OutFile), + All = check_report(fun() -> rb:show() end,OutFile), - ?line E = [_,_] = rb_filter([{rb_SUITE,"rb_test",re}],OutFile), - ?line AllButE = rb_filter([{rb_SUITE,"rb_test",re,no}],OutFile), + E = [_,_] = rb_filter([{rb_SUITE,"rb_test",re}],OutFile), + AllButE = rb_filter([{rb_SUITE,"rb_test",re,no}],OutFile), {_,AllRep} = lists:unzip(All), {_,ERep} = lists:unzip(E), {_,AllButERep} = lists:unzip(AllButE), - ?line AllButERep = AllRep -- ERep, + AllButERep = AllRep -- ERep, ok. -rescan() -> rescan(suite). -rescan(suite) -> []; rescan(Config) -> - ?line PrivDir = ?config(priv_dir,Config), - ?line OutFile = filename:join(PrivDir,"rb_SUITE_log.txt"), - + PrivDir = ?config(priv_dir,Config), + OutFile = filename:join(PrivDir,"rb_SUITE_log.txt"), + %% Start rb - ?line ok = start_rb(OutFile), + ok = start_rb(OutFile), %% Insert one more report and check that the list is longer. Note %% that there might be two more reports, since the progress report %% from starting rb_server might not be included before the rescan. - ?line AllBefore = capture(fun() -> rb:list() end), - ?line error_logger:error_report([{rb_SUITE,rb_test_rescan}]), - ?line ok = rb:rescan(), - ?line AllAfter = capture(fun() -> rb:list() end), - ?line Diff = length(AllAfter) - length(AllBefore), - ?line true = (Diff >= 1), + AllBefore = capture(fun() -> rb:list() end), + error_logger:error_report([{rb_SUITE,rb_test_rescan}]), + ok = rb:rescan(), + AllAfter = capture(fun() -> rb:list() end), + Diff = length(AllAfter) - length(AllBefore), + true = (Diff >= 1), ok. -start_stop_log() -> start_stop_log(suite). -start_stop_log(suite) -> []; start_stop_log(Config) -> - ?line PrivDir = ?config(priv_dir,Config), - ?line OutFile = filename:join(PrivDir,"rb_SUITE_log.txt"), - ?line ok = file:write_file(OutFile,[]), + PrivDir = ?config(priv_dir,Config), + OutFile = filename:join(PrivDir,"rb_SUITE_log.txt"), + ok = file:write_file(OutFile,[]), %% Start rb and check that show is printed to standard_io - ?line ok = start_rb(), - ?line StdioResult = [_|_] = capture(fun() -> rb:show(1) end), - ?line {ok,<<>>} = file:read_file(OutFile), - + ok = start_rb(), + StdioResult = [_|_] = capture(fun() -> rb:show(1) end), + {ok,<<>>} = file:read_file(OutFile), + %% Start log and check that show is printed to log and not to standad_io - ?line ok = rb:start_log(OutFile), - ?line [] = capture(fun() -> rb:show(1) end), - ?line {ok,Bin} = file:read_file(OutFile), - ?line true = (Bin =/= <<>>), + ok = rb:start_log(OutFile), + [] = capture(fun() -> rb:show(1) end), + {ok,Bin} = file:read_file(OutFile), + true = (Bin =/= <<>>), %% Stop log and check that show is printed to standard_io and not to log - ?line ok = rb:stop_log(), - ?line ok = file:write_file(OutFile,[]), - ?line StdioResult = capture(fun() -> rb:show(1) end), - ?line {ok,<<>>} = file:read_file(OutFile), + ok = rb:stop_log(), + ok = file:write_file(OutFile,[]), + StdioResult = capture(fun() -> rb:show(1) end), + {ok,<<>>} = file:read_file(OutFile), %% Test that standard_io is used if log file can not be opened - ?line ok = rb:start_log(filename:join(nonexistingdir,"newfile.txt")), - ?line StdioResult = capture(fun() -> rb:show(1) end), - ?line {ok,<<>>} = file:read_file(OutFile), + ok = rb:start_log(filename:join(nonexistingdir,"newfile.txt")), + StdioResult = capture(fun() -> rb:show(1) end), + {ok,<<>>} = file:read_file(OutFile), ok. @@ -435,7 +392,7 @@ empty_error_logs(Config) -> catch delete_content(?config(rb_dir, Config)), ok = application:start(sasl), wait_for_sasl(). - + wait_for_sasl() -> wait_for_sasl(50). wait_for_sasl(0) -> @@ -448,7 +405,7 @@ wait_for_sasl(N) -> timer:sleep(100), wait_for_sasl(N-1) end. - + start_rb(OutFile) -> do_start_rb([{start_log,OutFile}]). start_rb() -> @@ -482,20 +439,20 @@ delete_content(Dir) -> Files). init_error_logs() -> - ?line error_logger:error_report([{rb_SUITE,rb_test_error}]), - ?line error_logger:error_msg("rb_test_error_msg"), - ?line error_logger:info_report([{rb_SUITE,rb_test_info}]), - ?line error_logger:info_msg("rb_test_info_msg"), - ?line _Pid = start(), - ?line Ref = erlang:monitor(process,?MODULE), - ?line gen_server:cast(?MODULE,crash), - ?line receive {'DOWN',Ref,process,_,{rb_SUITE,rb_test_crash}} -> ok - after 2000 -> - ?t:format("Got: ~p~n",[process_info(self(),messages)]), - ?t:fail("rb_SUITE server never died") - end, - ?line erlang:demonitor(Ref), - ?line wait_for_server(), + error_logger:error_report([{rb_SUITE,rb_test_error}]), + error_logger:error_msg("rb_test_error_msg"), + error_logger:info_report([{rb_SUITE,rb_test_info}]), + error_logger:info_msg("rb_test_info_msg"), + _Pid = start(), + Ref = erlang:monitor(process,?MODULE), + gen_server:cast(?MODULE,crash), + receive {'DOWN',Ref,process,_,{rb_SUITE,rb_test_crash}} -> ok + after 2000 -> + ?t:format("Got: ~p~n",[process_info(self(),messages)]), + ?t:fail("rb_SUITE server never died") + end, + erlang:demonitor(Ref), + wait_for_server(), ok. wait_for_server() -> diff --git a/lib/sasl/test/release_handler_SUITE.erl b/lib/sasl/test/release_handler_SUITE.erl index af2183bfff..ac616dab72 100644 --- a/lib/sasl/test/release_handler_SUITE.erl +++ b/lib/sasl/test/release_handler_SUITE.erl @@ -19,6 +19,7 @@ -module(release_handler_SUITE). -include_lib("common_test/include/ct.hrl"). +-include("test_lib.hrl"). -compile(export_all). @@ -30,6 +31,7 @@ suite() -> [{ct_hooks, [ts_install_cth]}]. init_per_suite(Config) -> + init_priv_dir(Config), application:start(sasl), Config. @@ -58,7 +60,10 @@ cases() -> [otp_2740, otp_2760, otp_5761, otp_9402, otp_9417, otp_9395_check_old_code, otp_9395_check_and_purge, otp_9395_update_many_mods, otp_9395_rm_many_mods, - instructions, eval_appup, supervisor_which_children_timeout]. + instructions, eval_appup, eval_appup_with_restart, + supervisor_which_children_timeout, + release_handler_which_releases, install_release_syntax_check, + upgrade_supervisor, upgrade_supervisor_fail]. groups() -> [{release,[], @@ -69,6 +74,7 @@ groups() -> {release_single,[], [ upgrade, + upgrade_restart, client1, client2 ]}, @@ -82,7 +88,7 @@ groups() -> init_per_group(release, Config) -> Dog = ?t:timetrap(?default_timeout), P1gInstall = filename:join(priv_dir(Config),p1g_install), - ok = do_create_p1g(Config,P1gInstall), + ok = create_p1g(Config,P1gInstall), ok = create_p1h(Config), ?t:timetrap_cancel(Dog); @@ -95,6 +101,7 @@ init_per_group(release_single, Config) -> %% Create some more releases to upgrade to ok = create_p1i(Config), ok = create_p2a(Config), + ok = create_p2b(Config), ?t:timetrap_cancel(Dog); @@ -155,7 +162,7 @@ end_per_group(release, Config) -> {win32,_} -> delete_all_services(); _ -> ok end, - delete_release(Config), + clean_priv_dir(Config,true), ?t:timetrap_cancel(Dog), Config; end_per_group(_GroupName, Config) -> @@ -191,7 +198,10 @@ end_per_testcase(Case, Config) -> FailDir = filename:join(SaveDir,lists:concat(["failed-",Case])), ok = filelib:ensure_dir(filename:join(FailDir,"*")), - LogDirs = filelib:wildcard(filename:join([PrivDir,"*",log])), + LogDirs = + filelib:wildcard(filename:join([PrivDir,"*",log])) ++ + filelib:wildcard(filename:join([PrivDir,"*",clients, + type1,"*",log])), lists:foreach( fun(LogDir) -> @@ -236,7 +246,7 @@ break(Config) -> ?t:break(priv_dir(Config)), ok. -%% Test upgrade and downgrade of erts +%% Test upgrade and downgrade of erts and other apps on embedded node upgrade(Conf) when is_list(Conf) -> reg_print_proc(), %% starts a printer process on test_server node ?t:format("upgrade ~p~n",[reg_print_proc]), @@ -259,54 +269,75 @@ upgrade(Conf) when is_list(Conf) -> stop_cover(TestNode), reboot_and_wait(TestNode,"install_2",[a]), - %% check that P1H is permanent, unpack and install P1I, unpack and install P2A - TestNodeInit1 = rpc:call(TestNode,erlang,whereis,[init]), + %% check that P1H is permanent, unpack and install P1I, unpack P2A ok = rpc_inst(TestNode, install_3, [PrivDir]), stop_cover(TestNode), - ok = rpc_inst(TestNode, install_3a, []), - wait_nodes_up([{TestNode,TestNodeInit1}],"install_3",[a]), + reboot_and_wait(TestNode,"install_3",[a]), - %% check that P2A is used, reboot from P1I - ok = rpc_inst(TestNode, install_4, []), + %% check that P1H is used, install P2A + TestNodeInit1 = rpc:call(TestNode,erlang,whereis,[init]), stop_cover(TestNode), - reboot_and_wait(TestNode,"install_4",[a]), + ok = rpc_inst(TestNode, install_4, []), + wait_nodes_up([{TestNode,TestNodeInit1}],"install_4",[a]), - %% check that P1I, reinstall P2A + %% check that P2A is used, then downgrade to P1I TestNodeInit2 = rpc:call(TestNode,erlang,whereis,[init]), ok = rpc_inst(TestNode, install_5, []), stop_cover(TestNode), ok = rpc_inst(TestNode, install_5a, []), wait_nodes_up([{TestNode,TestNodeInit2}],"install_5",[a]), - %% check that P2A is used, make P2A permanent + %% Check that P1I is used, then make P1I permanent and install P2A + TestNodeInit3 = rpc:call(TestNode,erlang,whereis,[init]), ok = rpc_inst(TestNode, install_6, []), stop_cover(TestNode), - reboot_and_wait(TestNode,"install_6",[a]), + ok = rpc_inst(TestNode, install_6a, []), + wait_nodes_up([{TestNode,TestNodeInit3}],"install_6",[a]), - %% check that P2A is permanent, install old P1H - TestNodeInit3 = rpc:call(TestNode,erlang,whereis,[init]), - stop_cover(TestNode), + %% check that P2A is used, then downgrade to P1H + TestNodeInit4 = rpc:call(TestNode,erlang,whereis,[init]), ok = rpc_inst(TestNode, install_7, []), - wait_nodes_up([{TestNode,TestNodeInit3}],"install_7",[a]), + stop_cover(TestNode), + ok = rpc_inst(TestNode, install_7a, []), + wait_nodes_up([{TestNode,TestNodeInit4}],"install_7",[a]), - %% check that P1H is permanent, remove P1I and P2A + %% check that P1H is used, then install P1I and check that it is permanent + %% then reinstall P2A + TestNodeInit5 = rpc:call(TestNode,erlang,whereis,[init]), ok = rpc_inst(TestNode, install_8, []), stop_cover(TestNode), - reboot_and_wait(TestNode,"install_8",[a]), + ok = rpc_inst(TestNode, install_8a, []), + wait_nodes_up([{TestNode,TestNodeInit5}],"install_8",[a]), + + %% check that P2A is used, make P2A permanent + ok = rpc_inst(TestNode, install_9, []), + stop_cover(TestNode), + reboot_and_wait(TestNode,"install_9",[a]), + + %% check that P2A is permanent, reboot to old P1H + TestNodeInit6 = rpc:call(TestNode,erlang,whereis,[init]), + stop_cover(TestNode), + ok = rpc_inst(TestNode, install_10, []), + wait_nodes_up([{TestNode,TestNodeInit6}],"install_10",[a]), + + %% check that P1H is permanent, remove P1I and P2A + ok = rpc_inst(TestNode, install_11, []), + stop_cover(TestNode), + reboot_and_wait(TestNode,"install_11",[a]), %% check that P1H is permanent, reboot old P1G - TestNodeInit4 = rpc:call(TestNode,erlang,whereis,[init]), + TestNodeInit7 = rpc:call(TestNode,erlang,whereis,[init]), stop_cover(TestNode), - ok = rpc_inst(TestNode, install_9, []), - wait_nodes_up([{TestNode,TestNodeInit4}],"install_9"), + ok = rpc_inst(TestNode, install_12, []), + wait_nodes_up([{TestNode,TestNodeInit7}],"install_12"), %% check that P1G is permanent, remove P1H - ok = rpc_inst(TestNode, install_10, []), + ok = rpc_inst(TestNode, install_13, []), stop_cover(TestNode), - reboot_and_wait(TestNode,"install_10"), + reboot_and_wait(TestNode,"install_13"), %% check that P1G is permanent - ok = rpc_inst(TestNode, install_11, []), + ok = rpc_inst(TestNode, install_14, []), ok. @@ -323,6 +354,54 @@ reboot_and_wait(Node,Tag,Apps) -> wait_nodes_up([{Node,InitPid}],Tag,Apps). +%% Test upgrade and downgrade of erts in combination with the +%% restart_emulator option to systools:make_relup. For upgrade, this +%% should cause one restart before the upgrade code, and one +%% after. For downgrade, there will be one restart only - at the end. +upgrade_restart(Conf) when is_list(Conf) -> + reg_print_proc(), %% starts a printer process on test_server node + ?t:format("upgrade_restart ~p~n",[reg_print_proc]), + PrivDir = priv_dir(Conf), + Sname = tc_sname(Conf), % nodename for use in this testcase + + %% Copy the P1G release to a directory for use in this testcase + ok = copy_installed(Conf,p1g_install,[Sname]), + + %% start the test node + [TestNode] = start_nodes(Conf,[Sname],"upgrade_restart start"), + + %% unpack and install P2B + TestNodeInit1 = rpc:call(TestNode,erlang,whereis,[init]), + ok = rpc_inst(TestNode, upgrade_restart_1, [PrivDir]), + stop_cover(TestNode), + ok = rpc_inst(TestNode, upgrade_restart_1a, []), + wait_nodes_up([{TestNode,TestNodeInit1}],"upgrade_restart_1",[a]), + + %% install P1G + case rpc_inst(TestNode, upgrade_restart_2, []) of + ok -> + ok; + {wait,TestNodeInit2a} -> + %% We catched the node too early - it was supposed to + %% restart twice, so let's wait for one more restart. + wait_nodes_up([{TestNode,TestNodeInit2a}],"upgrade_restart_2a",[]), + ok = rpc_inst(TestNode, upgrade_restart_2a, []) + end, + TestNodeInit2 = rpc:call(TestNode,erlang,whereis,[init]), + stop_cover(TestNode), + ok = rpc_inst(TestNode, upgrade_restart_2b, []), + wait_nodes_up([{TestNode,TestNodeInit2}],"upgrade_restart_2b",[]), + + %% Check that P1G is going again + ok = rpc_inst(TestNode, upgrade_restart_3, []), + + ok. + +upgrade_restart(cleanup,Config) -> + TestNode = tc_full_node_name(Config), + ok = stop_nodes([TestNode]). + + %% Test upgrade and downgrade of erts, diskless client1(Conf) when is_list(Conf) -> reg_print_proc(), %% starts a printer process on test_server node @@ -542,9 +621,51 @@ supervisor_which_children_timeout(Conf) -> ok. -supervisor_which_children_timeout(cleanup, Conf) -> +supervisor_which_children_timeout(cleanup, _Conf) -> stop_node(node_name(supervisor_which_children_timeout)). + +%% Test that check_install_release will fail for illegal relup +%% instructions, even after point of no return. +install_release_syntax_check(Conf) when is_list(Conf) -> + + S1 = [point_of_no_return, illegal_instruction], + {error,{illegal_instruction_after_point_of_no_return,illegal_instruction}} = + release_handler_1:check_script(S1,[]), + + S2 = [point_of_no_return,restart_new_emulator], + {error,{illegal_instruction_after_point_of_no_return,restart_new_emulator}} = + release_handler_1:check_script(S2,[]), + + ok. + + +%%----------------------------------------------------------------- +%% release_handler:which_releases/0 and 1 test +%%----------------------------------------------------------------- +release_handler_which_releases(Conf) -> + PrivDir = priv_dir(Conf), + Dir = filename:join(PrivDir,"release_handler_which_releases"), + DataDir = ?config(data_dir,Conf), + LibDir = filename:join([DataDir,release_handler_timeouts]), + + Rel1 = create_and_install_fake_first_release(Dir,[{dummy,"0.1",LibDir}]), + + {ok, Node} = t_start_node(release_handler_which_releases, Rel1, []), + Releases0 = rpc:call(Node, release_handler, which_releases, []), + Releases1 = rpc:call(Node, release_handler, which_releases, [permanent]), + Releases2 = rpc:call(Node, release_handler, which_releases, [old]), + + 1 = length(Releases0), + 1 = length(Releases1), + 0 = length(Releases2), + + ?t:format("release_handler:which_releases/0: ~p~n", [Releases0]), + ?t:format("release_handler:which_releases/1: ~p~n", [Releases1]), + ?t:format("release_handler:which_releases/1: ~p~n", [Releases2]), + + ok. + %%----------------------------------------------------------------- %% Ticket: OTP-2740 %% Slogan: vsn not numeric doesn't work so good in release_handling @@ -1085,6 +1206,109 @@ otp_9395_rm_many_mods(cleanup,_Conf) -> stop_node(node_name(otp_9395_rm_many_mods)). +upgrade_supervisor(Conf) when is_list(Conf) -> + %% Set some paths + PrivDir = priv_dir(Conf), + Dir = filename:join(PrivDir,"upgrade_supervisor"), + LibDir = filename:join(?config(data_dir, Conf), "lib"), + + %% Create the releases + Lib1 = [{a,"1.0",LibDir}], + Lib2 = [{a,"9.0",LibDir}], + Rel1 = create_and_install_fake_first_release(Dir,Lib1), + Rel2 = create_fake_upgrade_release(Dir,"2",Lib2,{[Rel1],[Rel1],[LibDir]}), + Rel1Dir = filename:dirname(Rel1), + Rel2Dir = filename:dirname(Rel2), + + %% Start a slave node + {ok, Node} = t_start_node(upgrade_supervisor, Rel1, + filename:join(Rel1Dir,"sys.config")), + + %% Check path + Dir1 = filename:join([LibDir, "a-1.0"]), + Dir1 = rpc:call(Node, code, lib_dir, [a]), + ASupBeam1 = filename:join([Dir1,ebin,"a_sup.beam"]), + ASupBeam1 = rpc:call(Node, code, which, [a_sup]), + + %% Install second release, with no changed modules + {ok, RelVsn2} = rpc:call(Node, release_handler, set_unpacked, + [Rel2++".rel", Lib2]), + ok = rpc:call(Node, release_handler, install_file, + [RelVsn2, filename:join(Rel2Dir, "relup")]), + ok = rpc:call(Node, release_handler, install_file, + [RelVsn2, filename:join(Rel2Dir, "start.boot")]), + ok = rpc:call(Node, release_handler, install_file, + [RelVsn2, filename:join(Rel2Dir, "sys.config")]), + + {ok, _RelVsn1, []} = + rpc:call(Node, release_handler, install_release, [RelVsn2]), + + %% Check that libdir is changed + Dir2 = filename:join([LibDir, "a-9.0"]), + Dir2 = rpc:call(Node, code, lib_dir, [a]), + ASupBeam2 = filename:join([Dir2,ebin,"a_sup.beam"]), + ASupBeam2 = rpc:call(Node, code, which, [a_sup]), + + %% Check that the restart strategy and child spec is updated + {status, _, {module, _}, [_, _, _, _, [_,_,{data,[{"State",State}]}]]} = + rpc:call(Node,sys,get_status,[a_sup]), + {state,_,RestartStrategy,[Child],_,_,_,_,_,_} = State, + one_for_all = RestartStrategy, % changed from one_for_one + {child,_,_,_,_,brutal_kill,_,_} = Child, % changed from timeout 2000 + + ok. + +%% Check that if the supervisor fails, then the upgrade is rolled back +%% and an ok error message is returned +upgrade_supervisor_fail(Conf) when is_list(Conf) -> + %% Set some paths + PrivDir = priv_dir(Conf), + Dir = filename:join(PrivDir,"upgrade_supervisor_fail"), + LibDir = filename:join(?config(data_dir, Conf), "lib"), + + %% Create the releases + Lib1 = [{a,"1.0",LibDir}], + Lib2 = [{a,"9.1",LibDir}], + Rel1 = create_and_install_fake_first_release(Dir,Lib1), + Rel2 = create_fake_upgrade_release(Dir,"2",Lib2,{[Rel1],[Rel1],[LibDir]}), + Rel1Dir = filename:dirname(Rel1), + Rel2Dir = filename:dirname(Rel2), + + %% Start a slave node + {ok, Node} = t_start_node(upgrade_supervisor_fail, Rel1, + filename:join(Rel1Dir,"sys.config")), + + %% Check path + Dir1 = filename:join([LibDir, "a-1.0"]), + Dir1 = rpc:call(Node, code, lib_dir, [a]), + ASupBeam1 = filename:join([Dir1,ebin,"a_sup.beam"]), + ASupBeam1 = rpc:call(Node, code, which, [a_sup]), + + %% Install second release, with no changed modules + {ok, RelVsn2} = rpc:call(Node, release_handler, set_unpacked, + [Rel2++".rel", Lib2]), + ok = rpc:call(Node, release_handler, install_file, + [RelVsn2, filename:join(Rel2Dir, "relup")]), + ok = rpc:call(Node, release_handler, install_file, + [RelVsn2, filename:join(Rel2Dir, "start.boot")]), + ok = rpc:call(Node, release_handler, install_file, + [RelVsn2, filename:join(Rel2Dir, "sys.config")]), + ok = net_kernel:monitor_nodes(true), + + {error,{code_change_failed,_Pid,a_sup,_Vsn, + {error,{invalid_shutdown,brutal_kil}}}} = + rpc:call(Node, release_handler, install_release, [RelVsn2]), + + %% Check that the upgrade is terminated - normally this would mean + %% rollback, but since this testcase is very simplified the node + %% is not started with heart supervision and will therefore not be + %% restarted. So we just check that the node goes down. + receive {nodedown,Node} -> ok + after 10000 -> ct:fail(failed_upgrade_never_restarted_node) + end, + + ok. + %% Test upgrade and downgrade of applications eval_appup(Conf) when is_list(Conf) -> @@ -1107,6 +1331,12 @@ eval_appup(Conf) when is_list(Conf) -> App11Dir = code:lib_dir(app1), ok = gen_server:call(harry, error), + %% Read appup script + {ok,"2.0",UpScript} = release_handler:upgrade_script(app1,App12Dir), + [{load_object_code,_}, + point_of_no_return, + {load,_}] = UpScript, + %% Upgrade to app1-2.0 {ok, []} = release_handler:upgrade_app(app1, App12Dir), App12Dir = code:lib_dir(app1), @@ -1117,6 +1347,12 @@ eval_appup(Conf) when is_list(Conf) -> %% (see myrel/lib2/app1-2.0/ebin/app1.app) [{var,val2}] = ets:lookup(otp_6162, var), + %% Read appup script + {ok,DnScript} = release_handler:downgrade_script(app1,"1.0",App11Dir), + [{load_object_code,_}, + point_of_no_return, + {load,_}] = DnScript, + %% Downgrade to app1-1.0 {ok, []} = release_handler:downgrade_app(app1,"1.0",App11Dir), App11Dir = code:lib_dir(app1), @@ -1134,6 +1370,85 @@ eval_appup(Conf) when is_list(Conf) -> ok. +%% Test upgrade and downgrade of applications when appup contains +%% restart_emulator and restart_new_emulator instructions +eval_appup_with_restart(Conf) when is_list(Conf) -> + + %% Set some paths + RelDir = filename:join(?config(data_dir, Conf), "app1_app2"), + App11Dir = filename:join([RelDir, "lib1", "app1-1.0"]), + App13Dir = filename:join([RelDir, "lib3", "app1-3.0"]), %restart_emulator + App14Dir = filename:join([RelDir, "lib4", "app1-4.0"]), %restart_new_emulator + EbinDir1 = filename:join(App11Dir, "ebin"), + EbinDir3 = filename:join(App13Dir, "ebin"), + EbinDir4 = filename:join(App14Dir, "ebin"), + + %% Start app1-1.0 + code:add_patha(EbinDir1), + ok = application:start(app1), + App11Dir = code:lib_dir(app1), + + %% Read appup script + {ok,"3.0",UpScript3} = release_handler:upgrade_script(app1,App13Dir), + [{load_object_code,_}, + point_of_no_return, + {load,_}, + restart_emulator] = UpScript3, + + %% Upgrade to app1-3.0 - restart_emulator + restart_emulator = release_handler:upgrade_app(app1, App13Dir), + App13Dir = code:lib_dir(app1), + + %% Fake full upgrade to 3.0 + {ok,AppSpec} = file:consult(filename:join([App13Dir,"ebin","app1.app"])), + application_controller:change_application_data(AppSpec,[]), + + %% Read appup script + {ok,"4.0",UpScript4} = release_handler:upgrade_script(app1,App14Dir), + [restart_new_emulator,point_of_no_return] = UpScript4, + + %% Try pgrade to app1-4.0 - restart_new_emulator + {error,restart_new_emulator} = release_handler:upgrade_app(app1, App14Dir), + App13Dir = code:lib_dir(app1), + + %% Read appup script + {ok,DnScript1} = release_handler:downgrade_script(app1,"1.0",App11Dir), + [{load_object_code,_}, + point_of_no_return, + {load,_}, + restart_emulator] = DnScript1, + + %% Still running 3.0 - downgrade to app1-1.0 - restart_emulator + restart_emulator = release_handler:downgrade_app(app1,"1.0",App11Dir), + App11Dir = code:lib_dir(app1), + + ok = application:stop(app1), + ok = application:unload(app1), + true = code:del_path(EbinDir1), + + %% Start again as version 4.0 + code:add_patha(EbinDir4), + ok = application:start(app1), + App14Dir = code:lib_dir(app1), + + %% Read appup script + {ok,DnScript3} = release_handler:downgrade_script(app1,"3.0",App13Dir), + [point_of_no_return,restart_emulator] = DnScript3, + + %% Downgrade to app1-3.0 - restart_new_emulator + restart_emulator = release_handler:downgrade_app(app1,"3.0",App13Dir), + App13Dir = code:lib_dir(app1), + + ok = application:stop(app1), + ok = application:unload(app1), + + true = code:del_path(EbinDir3), + false = code:del_path(EbinDir1), + false = code:del_path(EbinDir4), + + ok. + + %% Test the example/target_system.erl module target_system(Conf) when is_list(Conf) -> PrivDir = priv_dir(Conf), @@ -1147,11 +1462,10 @@ target_system(Conf) when is_list(Conf) -> %% Create the .rel file - ErtsVsn = erlang:system_info(version), RelName = filename:join(TargetCreateDir,"ts-1.0"), RelFile = RelName++".rel", RelVsn = "R1A", - create_rel_file(RelFile,RelName,RelVsn,ErtsVsn,[{a, "1.0"}]), + create_rel_file(RelFile,RelName,RelVsn,current,[{a, "1.0"}]), %% Build the target_system module ExamplesEbin = filename:join([code:lib_dir(sasl),examples,ebin]), @@ -1179,11 +1493,13 @@ target_system(Conf) when is_list(Conf) -> code:del_path(TSPath), %% Check that all files exist in installation - true = filelib:is_dir(filename:join(TargetInstallDir,"erts-"++ErtsVsn)), + ErtsDir = app_dir(erts,current), + true = filelib:is_dir(filename:join(TargetInstallDir,ErtsDir)), LibDir = filename:join(TargetInstallDir,lib), - {ok,KernelVsn} = application:get_key(kernel,vsn), - {ok,StdlibVsn} = application:get_key(stdlib,vsn), - {ok,SaslVsn} = application:get_key(sasl,vsn), + KernelVsn = vsn(kernel,current), + StdlibVsn = vsn(stdlib,current), + SaslVsn = vsn(sasl,current), + RelFileBasename = filename:basename(RelFile), true = filelib:is_dir(filename:join(LibDir,"kernel-"++KernelVsn)), true = filelib:is_dir(filename:join(LibDir,"stdlib-"++StdlibVsn)), true = filelib:is_dir(filename:join(LibDir,"sasl-"++SaslVsn)), @@ -1191,10 +1507,10 @@ target_system(Conf) when is_list(Conf) -> RelDir = filename:join(TargetInstallDir,releases), true = filelib:is_regular(filename:join(RelDir,"RELEASES")), true = filelib:is_regular(filename:join(RelDir,"start_erl.data")), - true = filelib:is_regular(filename:join(RelDir, - filename:basename(RelFile))), + true = filelib:is_regular(filename:join(RelDir,RelFileBasename)), true = filelib:is_dir(filename:join(RelDir,RelVsn)), true = filelib:is_regular(filename:join([RelDir,RelVsn,"start.boot"])), + true = filelib:is_regular(filename:join([RelDir,RelVsn,RelFileBasename])), BinDir = filename:join(TargetInstallDir,bin), true = filelib:is_regular(filename:join(BinDir,"start.boot")), true = filelib:is_regular(filename:join(BinDir,erl)), @@ -1205,6 +1521,7 @@ target_system(Conf) when is_list(Conf) -> true = filelib:is_regular(filename:join(BinDir,to_erl)), %% Check content of files + ErtsVsn = vsn(erts,current), {ok,SED} = file:read_file(filename:join(RelDir,"start_erl.data")), [ErtsVsn,RelVsn] = string:tokens(binary_to_list(SED),"\s\n"), ok. @@ -1456,7 +1773,7 @@ copy_client(Conf,Master,Sname,Client) -> ok. -delete_release(Conf) -> +clean_priv_dir(Conf,Save) -> PrivDir = priv_dir(Conf), {ok, OrigWd} = file:get_cwd(), @@ -1466,7 +1783,7 @@ delete_release(Conf) -> {ok, Dirs} = file:list_dir(PrivDir), ?t:format("======== deleting ~p~n",[Dirs]), - ok = delete_release_os(Dirs--["save"]), + ok = clean_dirs_os(Dirs,Save), {ok,Remaining} = file:list_dir(PrivDir), ?t:format("======== remaining ~p~n",[Remaining]), @@ -1474,7 +1791,7 @@ delete_release(Conf) -> [] -> ok; _ -> - delete_release_os(Remaining), + clean_dirs_os(Remaining,Save), Remaining2 = file:list_dir(PrivDir), ?t:format("======== remaining after second try ~p~n",[Remaining2]) end, @@ -1483,22 +1800,22 @@ delete_release(Conf) -> ok. -delete_release_os(Dirs) -> +clean_dirs_os(Dirs,Save) -> case os:type() of {unix, _} -> - delete_release_unix(Dirs); + clean_dirs_unix(Dirs,Save); {win32, _} -> - delete_release_win32(Dirs); + clean_dirs_win32(Dirs,Save); Os -> test_server:fail({error, {not_yet_implemented_os, Os}}) end. -delete_release_unix([]) -> +clean_dirs_unix([],_) -> ok; -delete_release_unix(["save"|Dirs]) -> - delete_release_unix(Dirs); -delete_release_unix([Dir|Dirs]) -> +clean_dirs_unix(["save"|Dirs],Save) when Save -> + clean_dirs_unix(Dirs,Save); +clean_dirs_unix([Dir|Dirs],Save) -> Rm = string:concat("rm -rf ", Dir), ?t:format("============== COMMAND ~p~n",[Rm]), case file:list_dir(Dir) of @@ -1515,13 +1832,13 @@ delete_release_unix([Dir|Dirs]) -> ?t:format("------- ls -al ~p~n",[os:cmd("ls -al " ++ Dir)]) end, - delete_release_unix(Dirs). + clean_dirs_unix(Dirs,Save). -delete_release_win32([]) -> +clean_dirs_win32([],_) -> ok; -delete_release_win32(["save"|Dirs]) -> - delete_release_win32(Dirs); -delete_release_win32([Dir|Dirs]) -> +clean_dirs_win32(["save"|Dirs],Save) when Save -> + clean_dirs_win32(Dirs,Save); +clean_dirs_win32([Dir|Dirs],Save) -> Rm = case filelib:is_dir(Dir) of true -> @@ -1531,7 +1848,7 @@ delete_release_win32([Dir|Dirs]) -> end, ?t:format("============== COMMAND ~p~n",[Rm]), [] = os:cmd(Rm), - delete_release_win32(Dirs). + clean_dirs_win32(Dirs,Save). node_name(Sname) when is_atom(Sname) -> @@ -1657,9 +1974,17 @@ priv_dir(Conf) -> %% filename:absname(?config(priv_dir, Conf)). % Get rid of trailing slash %% Due to problem with long paths on windows => creating a new %% priv_dir under data_dir + filename:absname(filename:join(?config(data_dir, Conf),priv_dir)). + +init_priv_dir(Conf) -> Dir = filename:absname(filename:join(?config(data_dir, Conf),priv_dir)), - filelib:ensure_dir(filename:join(Dir,"*")), - Dir. + case filelib:is_dir(Dir) of + true -> + clean_priv_dir(Conf,false); + false -> + ok + end, + filelib:ensure_dir(filename:join(Dir,"*")). latest_version(Dir) -> List = filelib:wildcard(Dir ++ "*"), @@ -1694,14 +2019,22 @@ stop_print_proc() -> %% Create the first target release, vsn P1G. This release is used for %% all test cases in {group,release} -create_p1g(Conf,Sname) -> - do_create_p1g(Conf,filename:join(priv_dir(Conf),Sname)). - -do_create_p1g(Conf,TargetDir) -> - PrivDir = priv_dir(Conf), +create_p1g(Conf,TargetDir) -> DataDir = ?config(data_dir,Conf), - ErtsVsn = "4.4", - ErtsDir = "erts-"++ErtsVsn, + PrivDir = priv_dir(Conf), + ErtsDir = app_dir(erts,old), + KernelDir = app_dir(kernel,old), + StdlibDir = app_dir(stdlib,old), + + %% Fake earlier version of kernel and stdlib + SystemLib = system_lib(PrivDir), + ok = filelib:ensure_dir(filename:join(SystemLib,"*")), + KernelLib = code:lib_dir(kernel), + StdlibLib = code:lib_dir(stdlib), + ok = copy_tree(Conf,KernelLib,KernelDir,SystemLib), + ok = copy_tree(Conf,StdlibLib,StdlibDir,SystemLib), + fix_version(SystemLib,kernel), + fix_version(SystemLib,stdlib), %% Create dirs BinDir = filename:join(TargetDir,bin), @@ -1745,17 +2078,15 @@ do_create_p1g(Conf,TargetDir) -> RelFileName = filename:join(RelDir,RelName), RelFile = RelFileName ++ ".rel", ok = filelib:ensure_dir(RelFile), - LibPath = filename:join([DataDir,lib,"*",ebin]), - TarFile = create_basic_release(Conf, RelFile, RelVsn, {ErtsVsn,false}, - LibPath, [], [], [], []), + TarFile = create_basic_release(Conf,RelFile,RelVsn,{old,false}), %% Extract tar file in target directory (i.e. same directory as erts etc.) ok = erl_tar:extract(TarFile, [{cwd, TargetDir}, compressed]), %% Create start_erl.data StartErlDataFile = filename:join([ReleasesDir, "start_erl.data"]), - StartErlData = io_lib:fwrite("~s ~s~n", [ErtsVsn, RelVsn]), + StartErlData = io_lib:fwrite("~s ~s~n", [vsn(erts,old), RelVsn]), ok = file:write_file(StartErlDataFile, StartErlData), %% Create RELEASES @@ -1763,60 +2094,98 @@ do_create_p1g(Conf,TargetDir) -> ok. +fix_version(SystemLib,App) -> + FromVsn = vsn(App,current), + ToVsn = vsn(App,old), + Rootname = filename:join([SystemLib,app_dir(App,old),ebin,atom_to_list(App)]), + + AppFile = Rootname ++ ".app", + {ok,OrigApp} = file:read_file(AppFile), + ok = file:write_file(AppFile,re:replace(OrigApp,FromVsn,ToVsn, + [{return,binary}])), + AppupFile = Rootname ++ ".appup", + {ok,OrigAppup} = file:read_file(AppupFile), + ok = file:write_file(AppupFile,re:replace(OrigAppup,FromVsn,ToVsn, + [{return,binary}])). + + %% Create version P1H - which is P1G + a-1.0 %% Must have run create_p1g first!! create_p1h(Conf) -> - create_upgrade_release(Conf,"rel1","P1H",{"4.4",false},[{a,"1.0"}], - [{a,[{key2,val2}]}],{"rel0",[new_appl]}). + create_upgrade_release(Conf,"rel1","P1H",{old,false},[{a,"1.0"}], + [{a,[{key2,val2}]}],[{"rel0",[new_appl]}]). %% Create version P1I - which is P1H, but with application a upgraded to a-1.1 %% Must have run create_p1h first!! create_p1i(Conf) -> - create_upgrade_release(Conf,"rel2","P1I",{"4.4",false},[{a,"1.1"}], + create_upgrade_release(Conf,"rel2","P1I",{old,false},[{a,"1.1"}], [{a,[{key2,newval2}]}], - {"rel1",[{extra,gott}]}). + [{"rel1",[{extra,gott}]}]). %% Create version P2A - which is P1I, but with erts-<latest> %% Must have run create_p1i first!! create_p2a(Conf) -> - ErtsVsn = erlang:system_info(version), - create_upgrade_release(Conf,"rel3","P2A",{ErtsVsn,code:root_dir()}, + create_upgrade_release(Conf,"rel3","P2A",{current,code:root_dir()}, [{a,"1.1"}],[{a,[{key2,newval2}]}], - {"rel2",[new_emu]}). + [{"rel1",[new_emu,new_appl]},{"rel2",[new_emu]}], + [{"rel1",[old_emu,old_appl]},{"rel2",[old_emu]}]). + +%% Create version P2B - which is P2A, but with relup containing an +%% extra reboot. +%% Can be upgraded to from P1G - so must have run create_p1g first!! +create_p2b(Conf) -> + create_upgrade_release(Conf,"rel4","P2B",{current,code:root_dir()}, + [{a,"1.1"}],[{a,[{key2,newval2}]}], + [{"rel0",[new_emu,add_appl]}], + [{"rel0",[old_emu,rm_appl]}], + [restart_emulator]). %% Create a release tar package which can be installed on top of P1G -create_upgrade_release(Conf,RelName,RelVsn,Erts,Apps,Config,{UpFromName,Descr}) -> +create_upgrade_release(Conf,RelName,RelVsn,Erts,Apps,Config,UpFrom) -> + create_upgrade_release(Conf,RelName,RelVsn,Erts,Apps,Config,UpFrom,[]). +create_upgrade_release(Conf,RelName,RelVsn,Erts,Apps,Config,UpFrom,DownTo) -> + create_upgrade_release(Conf,RelName,RelVsn,Erts,Apps,Config,UpFrom,DownTo,[]). +create_upgrade_release(Conf,RelName,RelVsn,Erts,Apps,Config,UpFrom0,DownTo0,RelupOpts) -> PrivDir = priv_dir(Conf), - DataDir = ?config(data_dir,Conf), - RelDir = filename:join(PrivDir,RelName), RelFileName = filename:join(RelDir,RelName), RelFile = RelFileName ++ ".rel", ok = filelib:ensure_dir(RelFile), - LibPath = filename:join([DataDir,lib,"*",ebin]), - UpFrom = [{filename:join([PrivDir,UpFromName,UpFromName]),Descr}], + UpFrom = [{filename:join([PrivDir,UpFromName,UpFromName]),Descr} || + {UpFromName,Descr} <- UpFrom0], + DownTo = [{filename:join([PrivDir,DownToName,DownToName]),Descr} || + {DownToName,Descr} <- DownTo0], - create_basic_release(Conf, RelFile, RelVsn, Erts, LibPath, - Apps, Config, UpFrom, []), + create_basic_release(Conf,RelFile,RelVsn,Erts,Apps,Config, + UpFrom,DownTo,RelupOpts), ok. %% Create .rel, .script, .boot, sys.config and tar -create_basic_release(Conf, RelFile,RelVsn,{ErtsVsn,ErtsDir},LibPath,ExtraApps,Config,UpFrom,DownTo) -> +create_basic_release(Conf,RelFile,RelVsn,{Erts,ErtsDir}) -> + create_basic_release(Conf, RelFile,RelVsn,{Erts,ErtsDir},[],[],[],[],[]). +create_basic_release(Conf,RelFile,RelVsn,{Erts,ErtsDir},ExtraApps,Config,UpFrom,DownTo,RelupOpts) -> + DataDir = ?config(data_dir,Conf), + PrivDir = priv_dir(Conf), + SystemLib = system_lib(PrivDir), + LibPath = [filename:join([SystemLib,"*",ebin]), + filename:join([DataDir,lib,"*",ebin])], + RelDir = filename:dirname(RelFile), RelFileName = filename:rootname(RelFile), %% Create .rel file - create_installer_rel_file(RelFile,RelVsn,ErtsVsn,ExtraApps), + create_installer_rel_file(RelFile,RelVsn,Erts,ExtraApps), %% Generate .script and .boot ok = systools:make_script(RelFileName, - [{path,[LibPath]}, + [{path,LibPath}, {outdir,RelDir}]), %% Generate relup - ok = systools:make_relup(RelFileName,UpFrom,DownTo,[{path,[LibPath]}, - {outdir,RelDir}]), + ok = systools:make_relup(RelFileName,UpFrom,DownTo,[{path,LibPath}, + {outdir,RelDir} | + RelupOpts]), %% Create sys.config ok = write_term_file(filename:join(RelDir,"sys.config"),Config), @@ -1824,7 +2193,7 @@ create_basic_release(Conf, RelFile,RelVsn,{ErtsVsn,ErtsDir},LibPath,ExtraApps,Co %% Create tar file (i.e. collect all lib/app-*/* and system files) ok = systools:make_tar(RelFileName, - [{path,[LibPath]}, + [{path,LibPath}, {outdir,RelDir} | case ErtsDir of false -> []; @@ -1841,18 +2210,19 @@ create_basic_release(Conf, RelFile,RelVsn,{ErtsVsn,ErtsDir},LibPath,ExtraApps,Co TarFileName. %% Create a .rel file -create_installer_rel_file(RelFile,RelVsn,ErtsVsn,ExtraApps) -> - create_rel_file(RelFile,"SASL-test",RelVsn,ErtsVsn, +create_installer_rel_file(RelFile,RelVsn,Erts,ExtraApps) -> + create_rel_file(RelFile,"SASL-test",RelVsn,Erts, [{installer,"1.0"}|ExtraApps]). -create_rel_file(RelFile,RelName,RelVsn,ErtsVsn,ExtraApps) -> - {ok,KernelVsn} = application:get_key(kernel,vsn), - {ok,StdlibVsn} = application:get_key(stdlib,vsn), - {ok,SaslVsn} = application:get_key(sasl,vsn), +create_rel_file(RelFile,RelName,RelVsn,Erts,ExtraApps) -> + ErtsVsn = vsn(erts,Erts), + KernelVsn = vsn(kernel,Erts), + StdlibVsn = vsn(stdlib,Erts), + SaslVsn = vsn(sasl,current), application:load(tools), - {ok,ToolsVsn} = application:get_key(tools,vsn), + ToolsVsn = vsn(tools,current), application:load(runtime_tools), - {ok,RuntimeToolsVsn} = application:get_key(runtime_tools,vsn), + RuntimeToolsVsn = vsn(runtime_tools,current), RelFileContent = {release, {RelName, RelVsn}, @@ -2033,7 +2403,7 @@ start_node_unix(Sname,NodeDir) -> start_node_win32(Sname,NodeDir) -> Name = atom_to_list(Sname) ++ "_P1G", - ErtsBinDir = filename:join(NodeDir,"erts-4.4/bin"), + ErtsBinDir = filename:join([NodeDir,app_dir(erts,old),"bin"]), StartErlArgs = rh_test_lib:get_start_erl_args(NodeDir), ServiceArgs = rh_test_lib:get_service_args(NodeDir, Sname, StartErlArgs), @@ -2158,7 +2528,6 @@ create_fake_release(Dir,RelName,RelVsn,AppDirs) -> RelDir = filename:join(Dir,"rel_" ++ RelVsn), Rel = filename:join([RelDir,"rel_" ++ RelVsn]), ok = filelib:ensure_dir(Rel), - ErtsVsn = erlang:system_info(version), {Apps,Paths} = lists:foldl(fun({App,Vsn,Lib},{As,Ps}) -> @@ -2168,7 +2537,7 @@ create_fake_release(Dir,RelName,RelVsn,AppDirs) -> {[],[]}, AppDirs), - create_rel_file(Rel++".rel",RelName,RelVsn,ErtsVsn,Apps), + create_rel_file(Rel++".rel",RelName,RelVsn,current,Apps), %% Generate boot scripts ok = systools:make_script(Rel,[local, @@ -2217,3 +2586,16 @@ modify_tar_win32(Conf, TarFileName) -> [ok = erl_tar:add(T,filename:join(TmpDir,F),F,[]) || F <- Fs], ok = erl_tar:close(T), ok. + +app_dir(App,Vsn) -> + atom_to_list(App) ++ "-" ++ vsn(App,Vsn). +vsn(erts,old) -> ?ertsvsn; +vsn(kernel,old) -> ?kernelvsn; +vsn(stdlib,old) -> ?stdlibvsn; +vsn(erts,current) -> erlang:system_info(version); +vsn(App,current) -> + {ok,Vsn} = application:get_key(App,vsn), + Vsn. + +system_lib(PrivDir) -> + filename:join(PrivDir,"system_lib"). diff --git a/lib/sasl/test/release_handler_SUITE_data/Makefile.src b/lib/sasl/test/release_handler_SUITE_data/Makefile.src index edb446413d..55d20aa8b6 100644 --- a/lib/sasl/test/release_handler_SUITE_data/Makefile.src +++ b/lib/sasl/test/release_handler_SUITE_data/Makefile.src @@ -5,6 +5,10 @@ P2B= \ P2B/a-2.0/ebin/a_sup.@EMULATOR@ LIB= \ + lib/a-9.1/ebin/a.@EMULATOR@ \ + lib/a-9.1/ebin/a_sup.@EMULATOR@ \ + lib/a-9.0/ebin/a.@EMULATOR@ \ + lib/a-9.0/ebin/a_sup.@EMULATOR@ \ lib/a-1.2/ebin/a.@EMULATOR@ \ lib/a-1.2/ebin/a_sup.@EMULATOR@ \ lib/a-1.1/ebin/a.@EMULATOR@ \ @@ -50,7 +54,13 @@ APP= \ app1_app2/lib2/app1-2.0/ebin/app1.@EMULATOR@ \ app1_app2/lib2/app2-1.0/ebin/app2_sup.@EMULATOR@ \ app1_app2/lib2/app2-1.0/ebin/app2_server.@EMULATOR@ \ - app1_app2/lib2/app2-1.0/ebin/app2.@EMULATOR@ + app1_app2/lib2/app2-1.0/ebin/app2.@EMULATOR@ \ + app1_app2/lib3/app1-3.0/ebin/app1_sup.@EMULATOR@ \ + app1_app2/lib3/app1-3.0/ebin/app1_server.@EMULATOR@ \ + app1_app2/lib3/app1-3.0/ebin/app1.@EMULATOR@ \ + app1_app2/lib4/app1-4.0/ebin/app1_sup.@EMULATOR@ \ + app1_app2/lib4/app1-4.0/ebin/app1_server.@EMULATOR@ \ + app1_app2/lib4/app1-4.0/ebin/app1.@EMULATOR@ OTP2740= \ otp_2740/vsn_atom.@EMULATOR@ \ @@ -95,6 +105,17 @@ lib/a-1.2/ebin/a.@EMULATOR@: lib/a-1.2/src/a.erl lib/a-1.2/ebin/a_sup.@EMULATOR@: lib/a-1.2/src/a_sup.erl erlc $(EFLAGS) -olib/a-1.2/ebin lib/a-1.2/src/a_sup.erl +lib/a-9.0/ebin/a.@EMULATOR@: lib/a-9.0/src/a.erl + erlc $(EFLAGS) -olib/a-9.0/ebin lib/a-9.0/src/a.erl +lib/a-9.0/ebin/a_sup.@EMULATOR@: lib/a-9.0/src/a_sup.erl + erlc $(EFLAGS) -olib/a-9.0/ebin lib/a-9.0/src/a_sup.erl + +lib/a-9.1/ebin/a.@EMULATOR@: lib/a-9.1/src/a.erl + erlc $(EFLAGS) -olib/a-9.1/ebin lib/a-9.1/src/a.erl +lib/a-9.1/ebin/a_sup.@EMULATOR@: lib/a-9.1/src/a_sup.erl + erlc $(EFLAGS) -olib/a-9.1/ebin lib/a-9.1/src/a_sup.erl + + lib/b-1.0/ebin/b_server.@EMULATOR@: lib/b-1.0/src/b_server.erl erlc $(EFLAGS) -olib/b-1.0/ebin lib/b-1.0/src/b_server.erl lib/b-1.0/ebin/b_lib.@EMULATOR@: lib/b-1.0/src/b_lib.erl @@ -183,6 +204,22 @@ app1_app2/lib2/app2-1.0/ebin/app2.@EMULATOR@: app1_app2/lib2/app2-1.0/src/app2.e erlc $(EFLAGS) -oapp1_app2/lib2/app2-1.0/ebin app1_app2/lib2/app2-1.0/src/app2.erl +app1_app2/lib3/app1-3.0/ebin/app1_sup.@EMULATOR@: app1_app2/lib3/app1-3.0/src/app1_sup.erl + erlc $(EFLAGS) -oapp1_app2/lib3/app1-3.0/ebin app1_app2/lib3/app1-3.0/src/app1_sup.erl +app1_app2/lib3/app1-3.0/ebin/app1_server.@EMULATOR@: app1_app2/lib3/app1-3.0/src/app1_server.erl + erlc $(EFLAGS) -oapp1_app2/lib3/app1-3.0/ebin app1_app2/lib3/app1-3.0/src/app1_server.erl +app1_app2/lib3/app1-3.0/ebin/app1.@EMULATOR@: app1_app2/lib3/app1-3.0/src/app1.erl + erlc $(EFLAGS) -oapp1_app2/lib3/app1-3.0/ebin app1_app2/lib3/app1-3.0/src/app1.erl + + +app1_app2/lib4/app1-4.0/ebin/app1_sup.@EMULATOR@: app1_app2/lib4/app1-4.0/src/app1_sup.erl + erlc $(EFLAGS) -oapp1_app2/lib4/app1-4.0/ebin app1_app2/lib4/app1-4.0/src/app1_sup.erl +app1_app2/lib4/app1-4.0/ebin/app1_server.@EMULATOR@: app1_app2/lib4/app1-4.0/src/app1_server.erl + erlc $(EFLAGS) -oapp1_app2/lib4/app1-4.0/ebin app1_app2/lib4/app1-4.0/src/app1_server.erl +app1_app2/lib4/app1-4.0/ebin/app1.@EMULATOR@: app1_app2/lib4/app1-4.0/src/app1.erl + erlc $(EFLAGS) -oapp1_app2/lib4/app1-4.0/ebin app1_app2/lib4/app1-4.0/src/app1.erl + + otp_2740/vsn_atom.@EMULATOR@: otp_2740/vsn_atom.erl erlc $(EFLAGS) -ootp_2740 otp_2740/vsn_atom.erl otp_2740/vsn_list.@EMULATOR@: otp_2740/vsn_list.erl diff --git a/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/ebin/app1.app b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/ebin/app1.app new file mode 100644 index 0000000000..4adc0540c4 --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/ebin/app1.app @@ -0,0 +1,9 @@ +{application, app1, + [{description, "very simple example application"}, + {id, "app1"}, + {vsn, "3.0"}, + {modules, [app1, app1_sup, app1_server]}, + {registered, [harry]}, + {applications, [kernel, stdlib, sasl]}, + {env, [{var,val2}]}, + {mod, {app1, []}}]}. diff --git a/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/ebin/app1.appup b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/ebin/app1.appup new file mode 100644 index 0000000000..a5cdfe9fcc --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/ebin/app1.appup @@ -0,0 +1,4 @@ +{"3.0", + [{"1.0", [{load_module, app1_server},restart_emulator]}], + [{"1.0", [{load_module, app1_server},restart_emulator]}] +}. diff --git a/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/src/app1.erl b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/src/app1.erl new file mode 100644 index 0000000000..f123c8f470 --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/src/app1.erl @@ -0,0 +1,22 @@ +-module(app1). + +-behaviour(application). + +%% Application callbacks +-export([start/2, stop/1]). +-export([config_change/3]). + +start(_Type, _StartArgs) -> + case app1_sup:start_link() of + {ok, Pid} -> + {ok, Pid}; + Error -> + Error + end. + +stop(_State) -> + ok. + +config_change(Changed, _New, _Removed) -> + catch ets:insert(otp_6162, hd(Changed)), + ok. diff --git a/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/src/app1_server.erl b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/src/app1_server.erl new file mode 100644 index 0000000000..660d095ebf --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/src/app1_server.erl @@ -0,0 +1,35 @@ +-module(app1_server). + +-behaviour(gen_server). + +%% API +-export([start_link/0]). + +%% gen_server callbacks +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, + terminate/2, code_change/3]). + +start_link() -> + gen_server:start_link({local, harry}, ?MODULE, [], []). + +init([]) -> + {ok, []}. + +handle_call(error, _From, State) -> + Reply = error, + {reply, Reply, State}; +handle_call(_Request, _From, State) -> + Reply = ok, + {reply, Reply, State}. + +handle_cast(_Msg, State) -> + {noreply, State}. + +handle_info(_Info, State) -> + {noreply, State}. + +terminate(_Reason, _State) -> + ok. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. diff --git a/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/src/app1_sup.erl b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/src/app1_sup.erl new file mode 100644 index 0000000000..e6ad9b6967 --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/src/app1_sup.erl @@ -0,0 +1,17 @@ +-module(app1_sup). + +-behaviour(supervisor). + +%% API +-export([start_link/0]). + +%% Supervisor callbacks +-export([init/1]). + +start_link() -> + supervisor:start_link(?MODULE, []). + +init([]) -> + AChild = {harry,{app1_server,start_link,[]}, + permanent,2000,worker,[app1_server]}, + {ok,{{one_for_all,0,1}, [AChild]}}. diff --git a/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/ebin/app1.app b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/ebin/app1.app new file mode 100644 index 0000000000..243bc21f02 --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/ebin/app1.app @@ -0,0 +1,9 @@ +{application, app1, + [{description, "very simple example application"}, + {id, "app1"}, + {vsn, "4.0"}, + {modules, [app1, app1_sup, app1_server]}, + {registered, [harry]}, + {applications, [kernel, stdlib, sasl]}, + {env, [{var,val2}]}, + {mod, {app1, []}}]}. diff --git a/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/ebin/app1.appup b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/ebin/app1.appup new file mode 100644 index 0000000000..72535c8b34 --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/ebin/app1.appup @@ -0,0 +1,4 @@ +{"4.0", + [{"3.0", [restart_new_emulator]}], + [{"3.0", [restart_new_emulator]}] +}. diff --git a/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/src/app1.erl b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/src/app1.erl new file mode 100644 index 0000000000..f123c8f470 --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/src/app1.erl @@ -0,0 +1,22 @@ +-module(app1). + +-behaviour(application). + +%% Application callbacks +-export([start/2, stop/1]). +-export([config_change/3]). + +start(_Type, _StartArgs) -> + case app1_sup:start_link() of + {ok, Pid} -> + {ok, Pid}; + Error -> + Error + end. + +stop(_State) -> + ok. + +config_change(Changed, _New, _Removed) -> + catch ets:insert(otp_6162, hd(Changed)), + ok. diff --git a/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/src/app1_server.erl b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/src/app1_server.erl new file mode 100644 index 0000000000..660d095ebf --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/src/app1_server.erl @@ -0,0 +1,35 @@ +-module(app1_server). + +-behaviour(gen_server). + +%% API +-export([start_link/0]). + +%% gen_server callbacks +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, + terminate/2, code_change/3]). + +start_link() -> + gen_server:start_link({local, harry}, ?MODULE, [], []). + +init([]) -> + {ok, []}. + +handle_call(error, _From, State) -> + Reply = error, + {reply, Reply, State}; +handle_call(_Request, _From, State) -> + Reply = ok, + {reply, Reply, State}. + +handle_cast(_Msg, State) -> + {noreply, State}. + +handle_info(_Info, State) -> + {noreply, State}. + +terminate(_Reason, _State) -> + ok. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. diff --git a/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/src/app1_sup.erl b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/src/app1_sup.erl new file mode 100644 index 0000000000..e6ad9b6967 --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/src/app1_sup.erl @@ -0,0 +1,17 @@ +-module(app1_sup). + +-behaviour(supervisor). + +%% API +-export([start_link/0]). + +%% Supervisor callbacks +-export([init/1]). + +start_link() -> + supervisor:start_link(?MODULE, []). + +init([]) -> + AChild = {harry,{app1_server,start_link,[]}, + permanent,2000,worker,[app1_server]}, + {ok,{{one_for_all,0,1}, [AChild]}}. diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/README b/lib/sasl/test/release_handler_SUITE_data/lib/README index 639a4ca0fb..ffb8c5120b 100644 --- a/lib/sasl/test/release_handler_SUITE_data/lib/README +++ b/lib/sasl/test/release_handler_SUITE_data/lib/README @@ -8,6 +8,14 @@ a-1.2: can be upgraded to from a-1.1. No module have changed, but priv dir is added including one 'file' +a-9.0: +can be upgrade to from a-1.0 +Changes a_sup correctly - to test successful upgrade of supervisor + +a-9.1: +can be upgrade to from a-1.0 +Changes a_sup faulty - to test failing upgrade of supervisor + b-1.0: start version, includes b_lib and b_server diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/a-1.1/ebin/a.appup b/lib/sasl/test/release_handler_SUITE_data/lib/a-1.1/ebin/a.appup index 05db4cb541..6ef67b869e 100644 --- a/lib/sasl/test/release_handler_SUITE_data/lib/a-1.1/ebin/a.appup +++ b/lib/sasl/test/release_handler_SUITE_data/lib/a-1.1/ebin/a.appup @@ -1,3 +1,3 @@ {"1.1", [{"1.0",[{update,a,{advanced,extra_par}}]}], - []}. + [{"1.0",[{update,a,{advanced,extra_par}}]}]}. diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/a-1.1/src/a.erl b/lib/sasl/test/release_handler_SUITE_data/lib/a-1.1/src/a.erl index c082ad5339..1050e53f35 100644 --- a/lib/sasl/test/release_handler_SUITE_data/lib/a-1.1/src/a.erl +++ b/lib/sasl/test/release_handler_SUITE_data/lib/a-1.1/src/a.erl @@ -51,4 +51,6 @@ terminate(_Reason, _State) -> ok. code_change(1, Extra, State) -> - {ok, {state, bval}}. + {ok, {state, bval}}; +code_change({down,1},Extra,State) -> + {ok, state}. diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/a-9.0/ebin/a.app b/lib/sasl/test/release_handler_SUITE_data/lib/a-9.0/ebin/a.app new file mode 100644 index 0000000000..aa436d3e8c --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/lib/a-9.0/ebin/a.app @@ -0,0 +1,8 @@ +{application, a, + [{description, "A CXC 138 11"}, + {vsn, "9.0"}, + {modules, [a, a_sup]}, + {registered, [a_sup]}, + {applications, [kernel, stdlib]}, + {env, [{key1, val1}]}, + {mod, {a_sup, []}}]}. diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/a-9.0/ebin/a.appup b/lib/sasl/test/release_handler_SUITE_data/lib/a-9.0/ebin/a.appup new file mode 100644 index 0000000000..c4071d57a3 --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/lib/a-9.0/ebin/a.appup @@ -0,0 +1,3 @@ +{"9.0", + [{"1.0",[{update,a_sup,{advanced,update_supervisor}}]}], + [{"1.0",[{update,a_sup,{advanced,update_supervisor}}]}]}. diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/a-9.0/src/a.erl b/lib/sasl/test/release_handler_SUITE_data/lib/a-9.0/src/a.erl new file mode 100644 index 0000000000..1050e53f35 --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/lib/a-9.0/src/a.erl @@ -0,0 +1,56 @@ +%% ``The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved via the world wide web at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. +%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings +%% AB. All Rights Reserved.'' +%% +%% $Id$ +%% +-module(a). + + +-behaviour(gen_server). + +%% External exports +-export([start_link/0, a/0, b/0]). +%% Internal exports +-export([init/1, handle_call/3, handle_info/2, terminate/2, code_change/3]). + +start_link() -> gen_server:start_link({local, aa}, a, [], []). + +a() -> gen_server:call(aa, a). +b() -> gen_server:call(aa, b). + +%%----------------------------------------------------------------- +%% Callback functions from gen_server +%%----------------------------------------------------------------- +init([]) -> + process_flag(trap_exit, true), + {ok, {state, bval}}. + +handle_call(a, _From, State) -> + X = application:get_all_env(a), + {reply, X, State}; + +handle_call(b, _From, State) -> + {reply, {ok, element(2, State)}, State}. + +handle_info(_, State) -> + {noreply, State}. + +terminate(_Reason, _State) -> + ok. + +code_change(1, Extra, State) -> + {ok, {state, bval}}; +code_change({down,1},Extra,State) -> + {ok, state}. diff --git a/lib/docbuilder/test/docb_SUITE.erl b/lib/sasl/test/release_handler_SUITE_data/lib/a-9.0/src/a_sup.erl index d286824539..ae1d080f58 100644 --- a/lib/docbuilder/test/docb_SUITE.erl +++ b/lib/sasl/test/release_handler_SUITE_data/lib/a-9.0/src/a_sup.erl @@ -3,48 +3,35 @@ %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved via the world wide web at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB. %% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings %% AB. All Rights Reserved.'' -%% +%% %% $Id$ %% --module(docb_SUITE). - --export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2,html/1]). - --include_lib("common_test/include/ct.hrl"). - --include_lib("kernel/include/file.hrl"). - -suite() -> [{ct_hooks,[ts_install_cth]}]. - -all() -> -[html]. - -groups() -> - []. - -init_per_suite(Config) -> - Config. +-module(a_sup). -end_per_suite(_Config) -> - ok. -init_per_group(_GroupName, Config) -> - Config. +-behaviour(supervisor). -end_per_group(_GroupName, Config) -> - Config. +%% External exports +-export([start/2]). +%% Internal exports +-export([init/1]). -html(suite) -> []; -html(Config) when is_list(Config) -> - ok. +start(_, _) -> + supervisor:start_link({local, a_sup}, a_sup, []). +init([]) -> + SupFlags = {one_for_all, 4, 3600}, + Config = {a, + {a, start_link, []}, + permanent, brutal_kill, worker, [a]}, + {ok, {SupFlags, [Config]}}. diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/a-9.1/ebin/a.app b/lib/sasl/test/release_handler_SUITE_data/lib/a-9.1/ebin/a.app new file mode 100644 index 0000000000..5b467ec4e8 --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/lib/a-9.1/ebin/a.app @@ -0,0 +1,8 @@ +{application, a, + [{description, "A CXC 138 11"}, + {vsn, "9.1"}, + {modules, [a, a_sup]}, + {registered, [a_sup]}, + {applications, [kernel, stdlib]}, + {env, [{key1, val1}]}, + {mod, {a_sup, []}}]}. diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/a-9.1/ebin/a.appup b/lib/sasl/test/release_handler_SUITE_data/lib/a-9.1/ebin/a.appup new file mode 100644 index 0000000000..efeb7f1fe3 --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/lib/a-9.1/ebin/a.appup @@ -0,0 +1,3 @@ +{"9.1", + [{"1.0",[{update,a_sup,{advanced,update_supervisor}}]}], + [{"1.0",[{update,a_sup,{advanced,update_supervisor}}]}]}. diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/a-9.1/src/a.erl b/lib/sasl/test/release_handler_SUITE_data/lib/a-9.1/src/a.erl new file mode 100644 index 0000000000..1050e53f35 --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/lib/a-9.1/src/a.erl @@ -0,0 +1,56 @@ +%% ``The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved via the world wide web at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. +%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings +%% AB. All Rights Reserved.'' +%% +%% $Id$ +%% +-module(a). + + +-behaviour(gen_server). + +%% External exports +-export([start_link/0, a/0, b/0]). +%% Internal exports +-export([init/1, handle_call/3, handle_info/2, terminate/2, code_change/3]). + +start_link() -> gen_server:start_link({local, aa}, a, [], []). + +a() -> gen_server:call(aa, a). +b() -> gen_server:call(aa, b). + +%%----------------------------------------------------------------- +%% Callback functions from gen_server +%%----------------------------------------------------------------- +init([]) -> + process_flag(trap_exit, true), + {ok, {state, bval}}. + +handle_call(a, _From, State) -> + X = application:get_all_env(a), + {reply, X, State}; + +handle_call(b, _From, State) -> + {reply, {ok, element(2, State)}, State}. + +handle_info(_, State) -> + {noreply, State}. + +terminate(_Reason, _State) -> + ok. + +code_change(1, Extra, State) -> + {ok, {state, bval}}; +code_change({down,1},Extra,State) -> + {ok, state}. diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/a-9.1/src/a_sup.erl b/lib/sasl/test/release_handler_SUITE_data/lib/a-9.1/src/a_sup.erl new file mode 100644 index 0000000000..b0597dc5c3 --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/lib/a-9.1/src/a_sup.erl @@ -0,0 +1,37 @@ +%% ``The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved via the world wide web at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. +%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings +%% AB. All Rights Reserved.'' +%% +%% $Id$ +%% +-module(a_sup). + + +-behaviour(supervisor). + +%% External exports +-export([start/2]). + +%% Internal exports +-export([init/1]). + +start(_, _) -> + supervisor:start_link({local, a_sup}, a_sup, []). + +init([]) -> + SupFlags = {one_for_all, 4, 3600}, + Config = {a, + {a, start_link, []}, + permanent, brutal_kil, worker, [a]}, + {ok, {SupFlags, [Config]}}. diff --git a/lib/sasl/test/sasl_SUITE.erl b/lib/sasl/test/sasl_SUITE.erl index 454095db6a..b6eaf41323 100644 --- a/lib/sasl/test/sasl_SUITE.erl +++ b/lib/sasl/test/sasl_SUITE.erl @@ -20,20 +20,21 @@ -include_lib("common_test/include/ct.hrl"). -% Default timetrap timeout (set in init_per_testcase). +%% Default timetrap timeout (set in init_per_testcase). -define(default_timeout, ?t:minutes(1)). -define(application, sasl). -% Test server specific exports +%% Test server specific exports -export([all/0,groups/0,init_per_group/2,end_per_group/2]). -export([init_per_testcase/2, end_per_testcase/2]). -% Test cases must be exported. +%% Test cases must be exported. -export([app_test/1, + appup_test/1, log_mf_h_env/1]). all() -> - [app_test, log_mf_h_env]. + [app_test, appup_test, log_mf_h_env]. groups() -> []. @@ -46,7 +47,7 @@ end_per_group(_GroupName, Config) -> init_per_testcase(_Case, Config) -> - ?line Dog=test_server:timetrap(?default_timeout), + Dog=test_server:timetrap(?default_timeout), [{watchdog, Dog}|Config]. end_per_testcase(_Case, Config) -> Dog=?config(watchdog, Config), @@ -54,9 +55,105 @@ end_per_testcase(_Case, Config) -> ok. app_test(Config) when is_list(Config) -> - ?line ?t:app_test(sasl, allow), + ?t:app_test(sasl, allow), ok. +%% Test that appup allows upgrade from/downgrade to a maximum of two +%% major releases back. +appup_test(_Config) -> + application:load(sasl), + {sasl,_,SaslVsn} = lists:keyfind(sasl,1,application:loaded_applications()), + Ebin = filename:join(code:lib_dir(sasl),ebin), + {ok,[{SaslVsn,UpFrom,DownTo}=Appup]} = + file:consult(filename:join(Ebin,"sasl.appup")), + ct:log("~p~n",[Appup]), + {OkVsns,NokVsns} = create_test_vsns(SaslVsn), + check_appup(OkVsns,UpFrom,{ok,[restart_new_emulator]}), + check_appup(OkVsns,DownTo,{ok,[restart_new_emulator]}), + check_appup(NokVsns,UpFrom,error), + check_appup(NokVsns,DownTo,error), + ok. + + +%% For sasl, the versions up to R14B03 were not according to the rule +%% used for other core applications - i.e. to change the second number +%% at major releases, the third at maintenance releases and the fourth +%% for patches - therefore test versions up to and including R16 are +%% hardcoded. +%% (All versions below are not necessarily existing.) +-define(r12_vsns,["2.1.5"]). +-define(r13_vsns,["2.1.6","2.1.7.1","2.1.9","2.1.9.1.2"]). +-define(r14_vsns,["2.1.9.2","2.1.9.2.20","2.1.9.4","2.1.10"]). +-define(r15_major,"2.2"). +-define(r16_major,"2.3"). +-define(r17_major,"2.4"). +create_test_vsns(?r15_major ++ Rest) -> + R15Vsns = + case string:tokens(Rest,".") of + [] -> []; + ["1"] -> [?r15_major]; + _ -> [?r15_major,?r15_major++".1"] + end, + OkVsns = ?r13_vsns ++ ?r14_vsns ++ R15Vsns, + NokVsns = ?r12_vsns ++ [?r15_major++",1", ?r16_major], + {OkVsns,NokVsns}; +create_test_vsns(?r16_major ++ Rest) -> + R16Vsns = + case string:tokens(Rest,".") of + [] -> []; + ["1"] -> [?r16_major]; + _ -> [?r16_major,?r16_major++".1"] + end, + OkVsns = ?r14_vsns ++ [?r15_major, ?r15_major ++ ".1.4"] ++ R16Vsns, + NokVsns = ?r13_vsns ++ [?r16_major++",1", ?r17_major], + {OkVsns,NokVsns}; +%% Normal erts case - i.e. for versions that comply to the erts standard +create_test_vsns(Current) -> + [XStr,YStr|Rest] = string:tokens(Current,"."), + X = list_to_integer(XStr), + Y = list_to_integer(YStr), + SecondMajor = vsn(X,Y-2), + SecondMinor = SecondMajor ++ ".1.3", + FirstMajor = vsn(X,Y-1), + FirstMinor = FirstMajor ++ ".57", + ThisMajor = vsn(X,Y), + This = + case Rest of + [] -> + []; + ["1"] -> + [ThisMajor]; + _ -> + ThisMinor = ThisMajor ++ ".1", + [ThisMajor,ThisMinor] + end, + OkVsns = This ++ [FirstMajor, FirstMinor, SecondMajor, SecondMinor], + + ThirdMajor = vsn(X,Y-3), + ThirdMinor = ThirdMajor ++ ".10.12", + Illegal = ThisMajor ++ ",1", + Newer1Major = vsn(X,Y+1), + Newer1Minor = Newer1Major ++ ".1", + Newer2Major = ThisMajor ++ "1", + NokVsns = [ThirdMajor,ThirdMinor, + Illegal, + Newer1Major,Newer1Minor, + Newer2Major], + {OkVsns,NokVsns}. + +vsn(X,Y) -> + integer_to_list(X) ++ "." ++ integer_to_list(Y). + +check_appup([Vsn|Vsns],Instrs,Expected) -> + case systools_relup:appup_search_for_version(Vsn, Instrs) of + Expected -> check_appup(Vsns,Instrs,Expected); + Other -> ct:fail({unexpected_result_for_vsn,Vsn,Other}) + end; +check_appup([],_,_) -> + ok. + + + %% OTP-9185 - fail sasl start if some but not all log_mf_h env vars %% are given. log_mf_h_env(Config) -> diff --git a/lib/sasl/test/systools_SUITE.erl b/lib/sasl/test/systools_SUITE.erl index e352247d44..43366d8917 100644 --- a/lib/sasl/test/systools_SUITE.erl +++ b/lib/sasl/test/systools_SUITE.erl @@ -28,9 +28,9 @@ -module(systools_SUITE). -%-define(debug, true). +%%-define(debug, true). --include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). -define(format(S, A), ok). -define(datadir, ?config(data_dir, Config)). -define(privdir, ?config(priv_dir, Config)). @@ -40,19 +40,20 @@ -export([all/0,suite/0,groups/0,init_per_group/2,end_per_group/2]). --export([ script_options/1, normal_script/1, no_mod_vsn_script/1, - wildcard_script/1, variable_script/1, - abnormal_script/1, src_tests_script/1, crazy_script/1, - warn_shadow_script/1, - included_script/1, included_override_script/1, - included_fail_script/1, included_bug_script/1, exref_script/1]). --export([ tar_options/1, normal_tar/1, no_mod_vsn_tar/1, variable_tar/1, - src_tests_tar/1, shadow_tar/1, var_tar/1, - exref_tar/1, link_tar/1, otp_9507/1]). --export([ normal_relup/1, abnormal_relup/1, no_appup_relup/1, - bad_appup_relup/1, app_start_type_relup/1, otp_3065/1]). --export([ - otp_6226/1]). +-export([script_options/1, normal_script/1, no_mod_vsn_script/1, + wildcard_script/1, variable_script/1, no_sasl_script/1, + abnormal_script/1, src_tests_script/1, crazy_script/1, + included_script/1, included_override_script/1, + included_fail_script/1, included_bug_script/1, exref_script/1, + otp_3065_circular_dependenies/1]). +-export([tar_options/1, normal_tar/1, no_mod_vsn_tar/1, variable_tar/1, + src_tests_tar/1, var_tar/1, + exref_tar/1, link_tar/1, otp_9507_path_ebin/1]). +-export([normal_relup/1, restart_relup/1, abnormal_relup/1, no_sasl_relup/1, + no_appup_relup/1, bad_appup_relup/1, app_start_type_relup/1, + regexp_relup/1]). +-export([normal_hybrid/1,hybrid_no_old_sasl/1,hybrid_no_new_sasl/1]). +-export([otp_6226_outdir/1]). -export([init_per_suite/1, end_per_suite/1, init_per_testcase/2, end_per_testcase/2]). @@ -67,25 +68,26 @@ suite() -> [{ct_hooks, [ts_install_cth]}]. all() -> - [{group, script}, {group, tar}, {group, relup}, - {group, tickets}]. + [{group, script}, {group, tar}, {group, relup}, {group, hybrid}, + {group, options}]. groups() -> [{script, [], [script_options, normal_script, no_mod_vsn_script, wildcard_script, variable_script, abnormal_script, - src_tests_script, crazy_script, warn_shadow_script, + no_sasl_script, src_tests_script, crazy_script, included_script, included_override_script, included_fail_script, included_bug_script, exref_script, - otp_3065]}, + otp_3065_circular_dependenies]}, {tar, [], [tar_options, normal_tar, no_mod_vsn_tar, variable_tar, - src_tests_tar, shadow_tar, var_tar, - exref_tar, link_tar, otp_9507]}, + src_tests_tar, var_tar, exref_tar, link_tar, otp_9507_path_ebin]}, {relup, [], - [normal_relup, abnormal_relup, no_appup_relup, - bad_appup_relup, app_start_type_relup]}, - {tickets, [], [otp_6226]}]. + [normal_relup, restart_relup, abnormal_relup, no_sasl_relup, + no_appup_relup, bad_appup_relup, app_start_type_relup, regexp_relup + ]}, + {hybrid, [], [normal_hybrid,hybrid_no_old_sasl,hybrid_no_new_sasl]}, + {options, [], [otp_6226_outdir]}]. init_per_group(_GroupName, Config) -> Config. @@ -100,17 +102,17 @@ init_per_suite(Config) when is_list(Config) -> %% Make of copy of the data directory. DataDir = ?datadir, PrivDir = ?privdir, - ?line CopyDir = fname(PrivDir, "datacopy"), - ?line TarFile = fname(PrivDir, "datacopy.tgz"), - ?line {ok, Tar} = erl_tar:open(TarFile, [write, compressed]), - ?line ok = erl_tar:add(Tar, DataDir, CopyDir, [compressed]), - ?line ok = erl_tar:close(Tar), - ?line ok = erl_tar:extract(TarFile, [compressed]), - ?line ok = file:delete(TarFile), + CopyDir = fname(PrivDir, "datacopy"), + TarFile = fname(PrivDir, "datacopy.tgz"), + {ok, Tar} = erl_tar:open(TarFile, [write, compressed]), + ok = erl_tar:add(Tar, DataDir, CopyDir, [compressed]), + ok = erl_tar:close(Tar), + ok = erl_tar:extract(TarFile, [compressed]), + ok = file:delete(TarFile), %% Compile source files in the copy directory. - ?line Sources = filelib:wildcard(fname([CopyDir,'*','*','*','*','*.erl'])), - ?line lists:foreach(fun compile_source/1, Sources), + Sources = filelib:wildcard(fname([CopyDir,'*','*','*','*','*.erl'])), + lists:foreach(fun compile_source/1, Sources), %% To use in end_per_testcase Path = code:get_path(), @@ -141,7 +143,7 @@ init_per_testcase(link_tar, Config) -> {win32, _} -> {skip, "Skip on windows"} end; init_per_testcase(_Case, Config) -> - ?line Dog = test_server:timetrap(?default_timeout), + Dog = test_server:timetrap(?default_timeout), [{watchdog, Dog}|Config]. end_per_testcase(_Case, Config) -> @@ -172,502 +174,460 @@ end_per_testcase(_Case, Config) -> %% -%% make_script -%% -script_options(suite) -> []; -script_options(doc) -> - ["Check illegal script options."]; +%% make_script: Check illegal script options script_options(Config) when is_list(Config) -> - ?line {'EXIT',{{badarg,[{path,["Path",12,"Another"]}]}, _}} = - (catch systools:make_script("release", [{path,["Path",12,"Another"]}])), - ?line {'EXIT',{{badarg,[sillent]}, _}} = + {'EXIT',{{badarg,[{path,["Path",12,"Another"]}]}, _}} = + (catch systools:make_script("release", [{path,["Path",12,"Another"]}])), + {'EXIT',{{badarg,[sillent]}, _}} = (catch systools:make_script("release", [{path,["Path","Another"]},sillent])), - ?line {'EXIT',{{badarg,[locall]}, _}} = + {'EXIT',{{badarg,[locall]}, _}} = (catch systools:make_script("release", [{path,["Path","Another"]},locall])), - ?line {'EXIT',{{badarg,[src_testsxx]}, _}} = + {'EXIT',{{badarg,[src_testsxx]}, _}} = (catch systools:make_script("release", [{path,["Path"]},src_testsxx])), - ?line {'EXIT',{{badarg,[{variables, {"TEST", "/home/lib"}}]}, _}} = + {'EXIT',{{badarg,[{variables, {"TEST", "/home/lib"}}]}, _}} = (catch systools:make_script("release", [{variables, {"TEST", "/home/lib"}}])), - ?line {'EXIT',{{badarg,[{variables, [{a, b}, {"a", "b"}]}]}, _}} = + {'EXIT',{{badarg,[{variables, [{a, b}, {"a", "b"}]}]}, _}} = (catch systools:make_script("release", [{variables, [{a, b}, {"a", "b"}]}])), - ?line {'EXIT',{{badarg,[exreff]}, _}} = + {'EXIT',{{badarg,[exreff]}, _}} = (catch systools:make_script("release", [{path,["Path","Another"]},exreff])), - ?line {'EXIT',{{badarg,[{exref,["appl"]}]}, _}} = + {'EXIT',{{badarg,[{exref,["appl"]}]}, _}} = (catch systools:make_script("release", [{exref,["appl"]}])), - ?line {'EXIT',{{badarg,[{machine, "appl"}]}, _}} = + {'EXIT',{{badarg,[{machine, "appl"}]}, _}} = (catch systools:make_script("release", [{machine,"appl"}])), ok. -%% make_script -%% -normal_script(suite) -> []; -normal_script(doc) -> - ["Check that make_script handles normal case."]; +%% make_script: Check that normal case normal_script(Config) when is_list(Config) -> - ?line {ok, OldDir} = file:get_cwd(), - ?line PSAVE = code:get_path(), % Save path + {ok, OldDir} = file:get_cwd(), + PSAVE = code:get_path(), % Save path - ?line {LatestDir, LatestName} = create_script(latest,Config), + {LatestDir, LatestName} = create_script(latest,Config), - ?line DataDir = filename:absname(?copydir), - ?line LibDir = fname([DataDir, d_normal, lib]), - ?line P1 = fname([LibDir, 'db-2.1', ebin]), - ?line P2 = fname([LibDir, 'fe-3.1', ebin]), + DataDir = filename:absname(?copydir), + LibDir = fname([DataDir, d_normal, lib]), + P1 = fname([LibDir, 'db-2.1', ebin]), + P2 = fname([LibDir, 'fe-3.1', ebin]), - ?line true = code:add_patha(P1), - ?line true = code:add_patha(P2), + true = code:add_patha(P1), + true = code:add_patha(P2), - ?line ok = file:set_cwd(LatestDir), + ok = file:set_cwd(LatestDir), - ?line ok = systools:make_script(filename:basename(LatestName)), - ?line {ok, _} = read_script_file(LatestName), % Check readabillity + ok = systools:make_script(filename:basename(LatestName)), + {ok, _} = read_script_file(LatestName), % Check readabillity %% Check the same but w. silent flag - ?line {ok, _, []} = systools:make_script(LatestName, [silent]), + {ok, _, []} = systools:make_script(LatestName, [silent]), %% Use the local option - ?line ok = systools:make_script(LatestName, [local]), - ?line ok = check_script_path(LatestName), + ok = systools:make_script(LatestName, [local]), + ok = check_script_path(LatestName), %% use the path option - ?line code:set_path(PSAVE), % Restore path + code:set_path(PSAVE), % Restore path %% Mess up std path: - ?line true = code:add_patha(fname([LibDir, 'db-1.0', ebin])), - ?line true = code:add_patha(fname([LibDir, 'fe-2.1', ebin])), + true = code:add_patha(fname([LibDir, 'db-1.0', ebin])), + true = code:add_patha(fname([LibDir, 'fe-2.1', ebin])), - ?line error = systools:make_script(LatestName), %should fail - ?line ok = systools:make_script(LatestName,[{path, [P1, P2]}]), + error = systools:make_script(LatestName), %should fail + ok = systools:make_script(LatestName,[{path, [P1, P2]}]), - ?line ok = file:set_cwd(OldDir), - ?line code:set_path(PSAVE), % Restore path + ok = file:set_cwd(OldDir), + code:set_path(PSAVE), % Restore path ok. -%% make_script -%% -no_mod_vsn_script(suite) -> []; -no_mod_vsn_script(doc) -> - ["Check that make_script handles normal case.", - "Modules specified without version in .app file (db-3.1)." - "Note that this is now the normal way - i.e. systools now " - "ignores the module versions in the .app file."]; +%% make_script: +%% Modules specified without version in .app file (db-3.1). +%% Note that this is now the normal way - i.e. systools now ignores +%% the module versions in the .app file. no_mod_vsn_script(Config) when is_list(Config) -> - ?line {ok, OldDir} = file:get_cwd(), - ?line PSAVE = code:get_path(), % Save path + {ok, OldDir} = file:get_cwd(), + PSAVE = code:get_path(), % Save path - ?line {LatestDir, LatestName} = create_script(latest_no_mod_vsn,Config), + {LatestDir, LatestName} = create_script(latest_no_mod_vsn,Config), - ?line DataDir = filename:absname(?copydir), - ?line LibDir = fname([DataDir, d_normal, lib]), - ?line P1 = fname([LibDir, 'db-3.1', ebin]), - ?line P2 = fname([LibDir, 'fe-3.1', ebin]), + DataDir = filename:absname(?copydir), + LibDir = fname([DataDir, d_normal, lib]), + P1 = fname([LibDir, 'db-3.1', ebin]), + P2 = fname([LibDir, 'fe-3.1', ebin]), - ?line true = code:add_patha(P1), - ?line true = code:add_patha(P2), + true = code:add_patha(P1), + true = code:add_patha(P2), - ?line ok = file:set_cwd(LatestDir), + ok = file:set_cwd(LatestDir), - ?line ok = systools:make_script(filename:basename(LatestName)), - ?line {ok, _} = read_script_file(LatestName), % Check readabillity + ok = systools:make_script(filename:basename(LatestName)), + {ok, _} = read_script_file(LatestName), % Check readabillity %% Check the same but w. silent flag - ?line {ok, _, []} = systools:make_script(LatestName, [silent]), + {ok, _, []} = systools:make_script(LatestName, [silent]), %% Use the local option - ?line ok = systools:make_script(LatestName, [local]), - ?line ok = check_script_path(LatestName), + ok = systools:make_script(LatestName, [local]), + ok = check_script_path(LatestName), %% use the path option - ?line code:set_path(PSAVE), % Restore path + code:set_path(PSAVE), % Restore path %% Mess up std path: - ?line true = code:add_patha(fname([LibDir, 'db-1.0', ebin])), - ?line true = code:add_patha(fname([LibDir, 'fe-2.1', ebin])), + true = code:add_patha(fname([LibDir, 'db-1.0', ebin])), + true = code:add_patha(fname([LibDir, 'fe-2.1', ebin])), - ?line error = systools:make_script(LatestName), %should fail - ?line ok = systools:make_script(LatestName, - [{path, [P1, P2]}]), + error = systools:make_script(LatestName), %should fail + ok = systools:make_script(LatestName, + [{path, [P1, P2]}]), - ?line ok = file:set_cwd(OldDir), - ?line code:set_path(PSAVE), % Restore path + ok = file:set_cwd(OldDir), + code:set_path(PSAVE), % Restore path ok. -%% make_script -%% -wildcard_script(suite) -> []; -wildcard_script(doc) -> - ["Check that make_script handles wildcards in path."]; +%% make_script: Check that make_script handles wildcards in path. wildcard_script(Config) when is_list(Config) -> - ?line {ok, OldDir} = file:get_cwd(), + {ok, OldDir} = file:get_cwd(), - ?line {LatestDir, LatestName} = create_script(latest,Config), + {LatestDir, LatestName} = create_script(latest,Config), - ?line DataDir = filename:absname(?copydir), - ?line LibDir = fname([DataDir, d_normal, lib]), - ?line WildDir = fname([LibDir, '*', ebin]), + DataDir = filename:absname(?copydir), + LibDir = fname([DataDir, d_normal, lib]), + WildDir = fname([LibDir, '*', ebin]), - ?line ok = file:set_cwd(LatestDir), + ok = file:set_cwd(LatestDir), - ?line error = systools:make_script(filename:basename(LatestName)), + error = systools:make_script(filename:basename(LatestName)), - ?line ok = systools:make_script(LatestName, - [{path, [WildDir]}]), + ok = systools:make_script(LatestName, + [{path, [WildDir]}]), - ?line {ok, _} = read_script_file(LatestName), % Check readabillity + {ok, _} = read_script_file(LatestName), % Check readabillity - ?line ok = file:set_cwd(OldDir), + ok = file:set_cwd(OldDir), ok. -%% make_script -%% -variable_script(suite) -> []; -variable_script(doc) -> - ["Add own installation dependent variable in script."]; +%% make_script: Add own installation dependent variable in script. variable_script(Config) when is_list(Config) -> - ?line {ok, OldDir} = file:get_cwd(), + {ok, OldDir} = file:get_cwd(), - ?line {LatestDir, LatestName} = create_script(latest,Config), + {LatestDir, LatestName} = create_script(latest,Config), - ?line DataDir = filename:absname(?copydir), - ?line LibDir = fname([DataDir, d_normal, lib]), - ?line P = [fname([LibDir, 'db-2.1', ebin]), - fname([LibDir, 'fe-3.1', ebin])], + DataDir = filename:absname(?copydir), + LibDir = fname([DataDir, d_normal, lib]), + P = [fname([LibDir, 'db-2.1', ebin]), + fname([LibDir, 'fe-3.1', ebin])], - ?line ok = file:set_cwd(LatestDir), + ok = file:set_cwd(LatestDir), - ?line ok = systools:make_script(LatestName, - [{path, P}, - {variables, [{"TEST", LibDir}]}]), + ok = systools:make_script(LatestName, + [{path, P}, + {variables, [{"TEST", LibDir}]}]), %% Check variables - ?line ok = check_var_script_file([fname(['$TEST', 'db-2.1', ebin]), - fname(['$TEST', 'fe-3.1', ebin])], - P, - LatestName), + ok = check_var_script_file([fname(['$TEST', 'db-2.1', ebin]), + fname(['$TEST', 'fe-3.1', ebin])], + P, + LatestName), - ?line ok = file:set_cwd(OldDir), + ok = file:set_cwd(OldDir), ok. -%% make_script -%% -abnormal_script(suite) -> []; -abnormal_script(doc) -> - ["Abnormal cases."]; +%% make_script: Abnormal cases. abnormal_script(Config) when is_list(Config) -> - ?line {ok, OldDir} = file:get_cwd(), + {ok, OldDir} = file:get_cwd(), - ?line {LatestDir, LatestName} = create_script(latest,Config), + {LatestDir, LatestName} = create_script(latest,Config), - ?line DataDir = filename:absname(?copydir), + DataDir = filename:absname(?copydir), - ?line ok = file:set_cwd(LatestDir), - ?line LibDir = fname([DataDir, d_bad_app_vsn, lib]), - ?line P = [fname([LibDir, 'db-2.1', ebin]), - fname([LibDir, 'fe-3.1', ebin])], + ok = file:set_cwd(LatestDir), + LibDir = fname([DataDir, d_bad_app_vsn, lib]), + P = [fname([LibDir, 'db-2.1', ebin]), + fname([LibDir, 'fe-3.1', ebin])], %% Check wrong app vsn - ?line error = systools:make_script(LatestName, [{path, P}]), - ?line {error, - systools_make, - [{error_reading, {db, {no_valid_version, - {{"should be","2.1"}, - {"found file", _, "2.0"}}}}}]} = + error = systools:make_script(LatestName, [{path, P}]), + {error, + systools_make, + [{error_reading, {db, {no_valid_version, + {{"should be","2.1"}, + {"found file", _, "2.0"}}}}}]} = systools:make_script(LatestName, [silent, {path, P}]), - ?line ok = file:set_cwd(OldDir), + ok = file:set_cwd(OldDir), ok. -%% make_script -%% -src_tests_script(suite) -> []; -src_tests_script(doc) -> - ["Do not check date of object file or that source code can be found."]; +%% make_script: Create script without sasl appl. Check warning. +no_sasl_script(Config) when is_list(Config) -> + {ok, OldDir} = file:get_cwd(), + + {LatestDir, LatestName} = create_script(latest1_no_sasl,Config), + + DataDir = filename:absname(?copydir), + LibDir = [fname([DataDir, d_normal, lib])], + P = [fname([LibDir, '*', ebin]), + fname([DataDir, lib, kernel, ebin]), + fname([DataDir, lib, stdlib, ebin]), + fname([DataDir, lib, sasl, ebin])], + + ok = file:set_cwd(LatestDir), + + {ok, _ , [{warning,missing_sasl}]} = + systools:make_script(LatestName,[{path, P},silent]), + + {ok, _ , []} = + systools:make_script(LatestName,[{path, P},silent, no_warn_sasl]), + + ok = file:set_cwd(OldDir), + ok. + + +%% make_script: Do not check date of object file or that source code +%% can be found. src_tests_script(Config) when is_list(Config) -> - ?line {ok, OldDir} = file:get_cwd(), - ?line PSAVE = code:get_path(), % Save path + {ok, OldDir} = file:get_cwd(), + PSAVE = code:get_path(), % Save path - ?line {LatestDir, LatestName} = create_script(latest,Config), - ?line BootFile = LatestName ++ ".boot", + {LatestDir, LatestName} = create_script(latest,Config), + BootFile = LatestName ++ ".boot", - ?line DataDir = filename:absname(?copydir), - ?line LibDir = fname([DataDir, d_missing_src, lib]), - ?line P1 = fname([LibDir, 'db-2.1', ebin]), - ?line P2 = fname([LibDir, 'fe-3.1', ebin]), + DataDir = filename:absname(?copydir), + LibDir = fname([DataDir, d_missing_src, lib]), + P1 = fname([LibDir, 'db-2.1', ebin]), + P2 = fname([LibDir, 'fe-3.1', ebin]), N = [P1, P2], - ?line ok = file:set_cwd(LatestDir), + ok = file:set_cwd(LatestDir), %% Manipulate the modification date of a beam file so it seems %% older than its .erl file - ?line Erl = filename:join([P1,"..","src","db1.erl"]), - ?line {ok, FileInfo=#file_info{mtime={{Y,M,D},T}}} = file:read_file_info(Erl), - ?line Beam = filename:join(P1,"db1.beam"), - ?line ok=file:write_file_info(Beam, FileInfo#file_info{mtime={{Y-1,M,D},T}}), + Erl = filename:join([P1,"..","src","db1.erl"]), + {ok, FileInfo=#file_info{mtime={{Y,M,D},T}}} = file:read_file_info(Erl), + Beam = filename:join(P1,"db1.beam"), + ok=file:write_file_info(Beam, FileInfo#file_info{mtime={{Y-1,M,D},T}}), %% Remove a .erl file - ?line Erl2 = filename:join([P1,"..","src","db2.erl"]), - ?line file:delete(Erl2), + Erl2 = filename:join([P1,"..","src","db2.erl"]), + file:delete(Erl2), %% Then make script %% .boot file should not exist - ?line ok = file:delete(BootFile), - ?line false = filelib:is_regular(BootFile), + ok = file:delete(BootFile), + false = filelib:is_regular(BootFile), %% With warnings_as_errors and src_tests option, an error should be issued - ?line error = + error = systools:make_script(LatestName, [silent, {path, N}, src_tests, warnings_as_errors]), - ?line error = + error = systools:make_script(LatestName, [{path, N}, src_tests, warnings_as_errors]), %% due to warnings_as_errors .boot file should still not exist - ?line false = filelib:is_regular(BootFile), + false = filelib:is_regular(BootFile), %% Two warnings should be issued when src_tests is given %% 1. old object code for db1.beam %% 2. missing source code for db2.beam - ?line {ok, _, [{warning,{obj_out_of_date,_}}, - {warning,{source_not_found,_}}]} = + {ok, _, [{warning,{obj_out_of_date,_}}, + {warning,{source_not_found,_}}]} = systools:make_script(LatestName, [silent, {path, N}, src_tests]), %% .boot file should exist now - ?line true = filelib:is_regular(BootFile), + true = filelib:is_regular(BootFile), %% Without the src_tests option, no warning should be issued - ?line {ok, _, []} = + {ok, _, []} = systools:make_script(LatestName, [silent, {path, N}]), %% Check that the old no_module_tests option (from the time when %% it was default to do the src_test) is ignored - ?line {ok, _, [{warning,{obj_out_of_date,_}}, - {warning,{source_not_found,_}}]} = + {ok, _, [{warning,{obj_out_of_date,_}}, + {warning,{source_not_found,_}}]} = systools:make_script(LatestName, [silent, {path, N}, no_module_tests, src_tests]), - ?line ok = file:set_cwd(OldDir), - ?line code:set_path(PSAVE), + ok = file:set_cwd(OldDir), + code:set_path(PSAVE), ok. -%% make_script -%% -warn_shadow_script(suite) -> []; -warn_shadow_script(doc) -> - ["Check that jam file out of date warning doesn't", - "shadow bad module version error."]; -warn_shadow_script(Config) when is_list(Config) -> - %% This test has been removed since the 'vsn' attribute is - %% not used any more, starting with R6. No warning - %% 'obj_out_of_date' seemed to be generated. - true. - - -%% make_script -%% -crazy_script(suite) -> []; -crazy_script(doc) -> - ["Do the crazy cases."]; +%% make_script: Do the crazy cases. crazy_script(Config) when is_list(Config) -> - ?line {ok, OldDir} = file:get_cwd(), + {ok, OldDir} = file:get_cwd(), - ?line {LatestDir, LatestName} = create_script(latest, Config), + {LatestDir, LatestName} = create_script(latest, Config), - ?line DataDir = filename:absname(?copydir), - ?line LibDir = fname([DataDir, d_normal, lib]), - ?line P = [fname([LibDir, 'db-2.1', ebin]), - fname([LibDir, 'fe-3.1', ebin])], + DataDir = filename:absname(?copydir), + LibDir = fname([DataDir, d_normal, lib]), + P = [fname([LibDir, 'db-2.1', ebin]), + fname([LibDir, 'fe-3.1', ebin])], - ?line ok = file:set_cwd(LatestDir), + ok = file:set_cwd(LatestDir), %% Run with bad path - ?line error = systools:make_script(LatestName), - ?line {error, _, [{error_reading, _}, {error_reading, _}]} = + error = systools:make_script(LatestName), + {error, _, [{error_reading, _}, {error_reading, _}]} = systools:make_script(LatestName, [silent]), %% Run with .rel file lacking kernel - ?line {LatestDir2, LatestName2} = create_script(latest_nokernel, Config), - ?line ok = file:set_cwd(LatestDir2), + {LatestDir2, LatestName2} = create_script(latest_nokernel, Config), + ok = file:set_cwd(LatestDir2), - ?line error = systools:make_script(LatestName2), - ?line {error, _, {missing_mandatory_app,[kernel,stdlib]}} = + error = systools:make_script(LatestName2), + {error, _, {missing_mandatory_app,[kernel,stdlib]}} = systools:make_script(LatestName2, [silent,{path,P}]), - ?line ok = file:set_cwd(OldDir), + ok = file:set_cwd(OldDir), ok. -%% make_script -%% -included_script(suite) -> []; -included_script(doc) -> - ["Check that make_script handles generation of script", - "for applications with included applications."]; +%% make_script: Check that make_script handles generation of script +%% for applications with included applications. included_script(Config) when is_list(Config) -> - ?line {ok, OldDir} = file:get_cwd(), - ?line {LatestDir, LatestName} = create_include_files(inc1, Config), - ?line ok = file:set_cwd(LatestDir), - ?line ok = systools:make_script(LatestName), - ?line ok = check_include_script(LatestName, - [t1, t2, t3, t5, t4, t6], - [t1, t3, t6]), - ?line ok = file:set_cwd(OldDir), + {ok, OldDir} = file:get_cwd(), + {LatestDir, LatestName} = create_include_files(inc1, Config), + ok = file:set_cwd(LatestDir), + ok = systools:make_script(LatestName), + ok = check_include_script(LatestName, + [t1, t2, t3, t5, t4, t6], + [t1, t3, t6]), + ok = file:set_cwd(OldDir), ok. -%% make_script -%% -included_override_script(suite) -> []; -included_override_script(doc) -> - ["Check that make_script handles generation of script", - "for applications with included applications which are override by", - "the .rel file."]; +%% make_script: Check that make_script handles generation of script +%% for applications with included applications which are override by +%% the .rel file. included_override_script(Config) when is_list(Config) -> - ?line {ok, OldDir} = file:get_cwd(), - ?line {LatestDir, LatestName} = create_include_files(inc2, Config), - ?line ok = file:set_cwd(LatestDir), - ?line ok = systools:make_script(LatestName), - ?line ok = check_include_script(LatestName, - [t1, t2, t3, t4, t6, t5], - [t1, t3, t6, t5]), - - ?line {_, LatestName1} = create_include_files(inc3, Config), - ?line ok = systools:make_script(LatestName1), - ?line ok = check_include_script(LatestName1, - [t3, t5, t4, t6, t1, t2], - [t3, t6, t1, t2]), - - ?line {_, LatestName2} = create_include_files(inc4, Config), - ?line ok = systools:make_script(LatestName2), - ?line ok = check_include_script(LatestName2, - [t3, t4, t6, t5, t1, t2], - [t3, t6, t5, t1, t2]), - - ?line {_, LatestName3} = create_include_files(inc5, Config), - ?line ok = systools:make_script(LatestName3), - ?line ok = check_include_script(LatestName3, - [t3, t4, t6, t1, t2], - [t3, t6, t1, t2]), - - ?line ok = file:set_cwd(OldDir), + {ok, OldDir} = file:get_cwd(), + {LatestDir, LatestName} = create_include_files(inc2, Config), + ok = file:set_cwd(LatestDir), + ok = systools:make_script(LatestName), + ok = check_include_script(LatestName, + [t1, t2, t3, t4, t6, t5], + [t1, t3, t6, t5]), + + {_, LatestName1} = create_include_files(inc3, Config), + ok = systools:make_script(LatestName1), + ok = check_include_script(LatestName1, + [t3, t5, t4, t6, t1, t2], + [t3, t6, t1, t2]), + + {_, LatestName2} = create_include_files(inc4, Config), + ok = systools:make_script(LatestName2), + ok = check_include_script(LatestName2, + [t3, t4, t6, t5, t1, t2], + [t3, t6, t5, t1, t2]), + + {_, LatestName3} = create_include_files(inc5, Config), + ok = systools:make_script(LatestName3), + ok = check_include_script(LatestName3, + [t3, t4, t6, t1, t2], + [t3, t6, t1, t2]), + + ok = file:set_cwd(OldDir), ok. -%% make_script -%% -included_fail_script(suite) -> []; -included_fail_script(doc) -> - ["Check that make_script handles errors then generating", - "script with included applications."]; +%% make_script: Check that make_script handles errors then generating +%% script with included applications. included_fail_script(Config) when is_list(Config) -> - ?line {ok, OldDir} = file:get_cwd(), - ?line {LatestDir, LatestName} = create_include_files(inc6, Config), - ?line ok = file:set_cwd(LatestDir), - ?line {error, _, {undefined_applications,[t2]}} = + {ok, OldDir} = file:get_cwd(), + {LatestDir, LatestName} = create_include_files(inc6, Config), + ok = file:set_cwd(LatestDir), + {error, _, {undefined_applications,[t2]}} = systools:make_script(LatestName, [silent]), - ?line {_, LatestName1} = create_include_files(inc7, Config), - ?line {error, _, {duplicate_include,[{{t5,t7,_,_},{t5,t6,_,_}}]}} = + {_, LatestName1} = create_include_files(inc7, Config), + {error, _, {duplicate_include,[{{t5,t7,_,_},{t5,t6,_,_}}]}} = systools:make_script(LatestName1, [silent]), - ?line {_, LatestName3} = create_include_files(inc9, Config), - ?line {error, _, {circular_dependencies,[{t10,_},{t8,_}]}} = + {_, LatestName3} = create_include_files(inc9, Config), + {error, _, {circular_dependencies,[{t10,_},{t8,_}]}} = systools:make_script(LatestName3, [silent]), - ?line {_, LatestName4} = create_include_files(inc10, Config), - ?line {error, _, [{error_reading,{t9,{override_include,[t7]}}}]} = + {_, LatestName4} = create_include_files(inc10, Config), + {error, _, [{error_reading,{t9,{override_include,[t7]}}}]} = systools:make_script(LatestName4, [silent]), - ?line ok = file:set_cwd(OldDir), + ok = file:set_cwd(OldDir), ok. -%% make_script -%% -included_bug_script(suite) -> []; -included_bug_script(doc) -> - ["Check that make_script handles generation of script", - "with difficult dependency for included applications."]; +%% make_script: Check that make_script handles generation of script +%% with difficult dependency for included applications. included_bug_script(Config) when is_list(Config) -> - ?line {ok, OldDir} = file:get_cwd(), - ?line {LatestDir, LatestName} = create_include_files(inc11, Config), - ?line ok = file:set_cwd(LatestDir), - ?line ok = systools:make_script(LatestName), - ?line ok = check_include_script(LatestName, - [t13, t11, t12], - [t11, t12]), - ?line ok = file:set_cwd(OldDir), + {ok, OldDir} = file:get_cwd(), + {LatestDir, LatestName} = create_include_files(inc11, Config), + ok = file:set_cwd(LatestDir), + ok = systools:make_script(LatestName), + ok = check_include_script(LatestName, + [t13, t11, t12], + [t11, t12]), + ok = file:set_cwd(OldDir), ok. -%% make_script -%% -otp_3065(suite) -> []; -otp_3065(doc) -> - ["Circular dependencies in systools:make_script()."]; -otp_3065(Config) when is_list(Config) -> - ?line {ok, OldDir} = file:get_cwd(), - ?line {LatestDir, LatestName} = create_include_files(otp_3065, Config), - ?line ok = file:set_cwd(LatestDir), - ?line ok = systools:make_script(LatestName), - ?line ok = check_include_script(LatestName, - [aa12, chAts, chTraffic], - [chTraffic]), - ?line ok = file:set_cwd(OldDir), +%% make_script: Circular dependencies in systools:make_script(). +otp_3065_circular_dependenies(Config) when is_list(Config) -> + {ok, OldDir} = file:get_cwd(), + {LatestDir, LatestName} = + create_include_files(otp_3065_circular_dependenies, Config), + ok = file:set_cwd(LatestDir), + ok = systools:make_script(LatestName), + ok = check_include_script(LatestName, + [aa12, chAts, chTraffic], + [chTraffic]), + ok = file:set_cwd(OldDir), ok. -%% make_script -%% -exref_script(suite) -> []; -exref_script(doc) -> - ["Check that make_script exref option works."]; +%% make_script: Check that make_script exref option works. exref_script(Config) when is_list(Config) -> - ?line {ok, OldDir} = file:get_cwd(), - ?line PSAVE = code:get_path(), % Save path + {ok, OldDir} = file:get_cwd(), + PSAVE = code:get_path(), % Save path - ?line {LatestDir, LatestName} = create_script(latest,Config), + {LatestDir, LatestName} = create_script(latest,Config), - ?line DataDir = filename:absname(?copydir), - ?line LibDir = fname([DataDir, d_normal, lib]), - ?line P = [fname([LibDir, 'db-2.1', ebin]), - fname([LibDir, 'fe-3.1', ebin])], + DataDir = filename:absname(?copydir), + LibDir = fname([DataDir, d_normal, lib]), + P = [fname([LibDir, 'db-2.1', ebin]), + fname([LibDir, 'fe-3.1', ebin])], - ?line ok = file:set_cwd(LatestDir), + ok = file:set_cwd(LatestDir), - ?line {ok, _, _} = systools:make_script(LatestName, [{path,P}, silent]), + {ok, _, _} = systools:make_script(LatestName, [{path,P}, silent]), %% Complete exref - ?line {ok, _, W1} = + {ok, _, W1} = systools:make_script(LatestName, [exref, {path,P}, silent]), - ?line check_exref_warnings(with_db1, W1), - ?line {ok, _} = read_script_file(LatestName), % Check readabillity + check_exref_warnings(with_db1, W1), + {ok, _} = read_script_file(LatestName), % Check readabillity %% Only exref the db application. - ?line {ok, _, W2} = + {ok, _, W2} = systools:make_script(LatestName, [{exref,[db]}, {path,P}, silent]), - ?line check_exref_warnings(with_db1, W2), - ?line {ok, _} = read_script_file(LatestName), % Check readabillity + check_exref_warnings(with_db1, W2), + {ok, _} = read_script_file(LatestName), % Check readabillity %% Only exref the fe application. - ?line {ok, _, W3} = + {ok, _, W3} = systools:make_script(LatestName, [{exref,[fe]}, {path,P}, silent]), - ?line check_exref_warnings(without_db1, W3), - ?line {ok, _} = read_script_file(LatestName), % Check readabillity + check_exref_warnings(without_db1, W3), + {ok, _} = read_script_file(LatestName), % Check readabillity %% exref the db and stdlib applications. - ?line {ok, _, W4} = + {ok, _, W4} = systools:make_script(LatestName, [{exref,[db,stdlib]}, {path,P}, silent]), - ?line check_exref_warnings(with_db1, W4), - ?line {ok, _} = read_script_file(LatestName), % Check readabillity - ?line ok = file:set_cwd(OldDir), - ?line code:set_path(PSAVE), % Restore path + check_exref_warnings(with_db1, W4), + {ok, _} = read_script_file(LatestName), % Check readabillity + ok = file:set_cwd(OldDir), + code:set_path(PSAVE), % Restore path ok. check_exref_warnings(with_db1, W) -> @@ -697,11 +657,11 @@ filter({ok, W}) -> {ok, filter(W)}; filter(L) -> lists:filter(fun%({hipe_consttab,_,_}) -> false; - ({int,_,_}) -> false; - ({i,_,_}) -> false; - ({crypto,_,_}) -> false; - (_) -> true - end, + ({int,_,_}) -> false; + ({i,_,_}) -> false; + ({crypto,_,_}) -> false; + (_) -> true + end, L). get_exref1(T, [{warning, {T, Value}}|_]) -> {ok, Value}; @@ -721,197 +681,172 @@ no_hipe({ok, Value}) -> {ok, Value} end. -%% tar_options -%% -tar_options(suite) -> []; -tar_options(doc) -> - ["Check illegal tar options."]; +%% tar_options: Check illegal tar options. tar_options(Config) when is_list(Config) -> - ?line {'EXIT',{{badarg,[{path,["Path",12,"Another"]}]}, _}} = + {'EXIT',{{badarg,[{path,["Path",12,"Another"]}]}, _}} = (catch systools:make_tar("release", [{path,["Path",12,"Another"]}])), - ?line {'EXIT',{{badarg,[sillent]}, _}} = + {'EXIT',{{badarg,[sillent]}, _}} = (catch systools:make_tar("release", [{path,["Path","Another"]},sillent])), - ?line {'EXIT',{{badarg,[{dirs,["dirs"]}]}, _}} = + {'EXIT',{{badarg,[{dirs,["dirs"]}]}, _}} = (catch systools:make_tar("release", [{dirs, ["dirs"]}])), - ?line {'EXIT',{{badarg,[{erts, illegal}]}, _}} = + {'EXIT',{{badarg,[{erts, illegal}]}, _}} = (catch systools:make_tar("release", [{erts, illegal}])), - ?line {'EXIT',{{badarg,[src_testsxx]}, _}} = + {'EXIT',{{badarg,[src_testsxx]}, _}} = (catch systools:make_tar("release", [{path,["Path"]},src_testsxx])), - ?line {'EXIT',{{badarg,[{variables, [{a, b}, {"a", "b"}]}]}, _}} = + {'EXIT',{{badarg,[{variables, [{a, b}, {"a", "b"}]}]}, _}} = (catch systools:make_tar("release", [{variables, [{a, b}, {"a", "b"}]}])), - ?line {'EXIT',{{badarg,[{var_tar, illegal}]}, _}} = + {'EXIT',{{badarg,[{var_tar, illegal}]}, _}} = (catch systools:make_tar("release", [{var_tar, illegal}])), - ?line {'EXIT',{{badarg,[exreff]}, _}} = + {'EXIT',{{badarg,[exreff]}, _}} = (catch systools:make_tar("release", [{path,["Path","Another"]},exreff])), - ?line {'EXIT',{{badarg,[{exref,["appl"]}]}, _}} = + {'EXIT',{{badarg,[{exref,["appl"]}]}, _}} = (catch systools:make_tar("release", [{exref,["appl"]}])), - ?line {'EXIT',{{badarg,[{machine, "appl"}]}, _}} = + {'EXIT',{{badarg,[{machine, "appl"}]}, _}} = (catch systools:make_tar("release", [{machine,"appl"}])), ok. -%% normal_tar -%% -normal_tar(suite) -> []; -normal_tar(doc) -> - ["Check normal case"]; +%% make_tar: Check normal case normal_tar(Config) when is_list(Config) -> - ?line {ok, OldDir} = file:get_cwd(), + {ok, OldDir} = file:get_cwd(), - ?line {LatestDir, LatestName} = create_script(latest,Config), + {LatestDir, LatestName} = create_script(latest,Config), - ?line DataDir = filename:absname(?copydir), - ?line LibDir = fname([DataDir, d_normal, lib]), - ?line P = [fname([LibDir, 'db-2.1', ebin]), - fname([LibDir, 'fe-3.1', ebin])], + DataDir = filename:absname(?copydir), + LibDir = fname([DataDir, d_normal, lib]), + P = [fname([LibDir, 'db-2.1', ebin]), + fname([LibDir, 'fe-3.1', ebin])], - ?line ok = file:set_cwd(LatestDir), + ok = file:set_cwd(LatestDir), - ?line {ok, _, _} = systools:make_script(LatestName, [silent, {path, P}]), - ?line ok = systools:make_tar(LatestName, [{path, P}]), - ?line ok = check_tar(fname([lib,'db-2.1',ebin,'db.app']), LatestName), - ?line {ok, _, _} = systools:make_tar(LatestName, [{path, P}, silent]), - ?line ok = check_tar(fname([lib,'fe-3.1',ebin,'fe.app']), LatestName), + {ok, _, _} = systools:make_script(LatestName, [silent, {path, P}]), + ok = systools:make_tar(LatestName, [{path, P}]), + ok = check_tar(fname([lib,'db-2.1',ebin,'db.app']), LatestName), + {ok, _, _} = systools:make_tar(LatestName, [{path, P}, silent]), + ok = check_tar(fname([lib,'fe-3.1',ebin,'fe.app']), LatestName), - ?line ok = file:set_cwd(OldDir), + ok = file:set_cwd(OldDir), ok. -%% no_mod_vsn_tar -%% -no_mod_vsn_tar(suite) -> []; -no_mod_vsn_tar(doc) -> - ["Check normal case", - "Modules specified without version in .app file (db-3.1)." - "Note that this is now the normal way - i.e. systools now " - "ignores the module versions in the .app file."]; +%% make_tar: Modules specified without version in .app file (db-3.1). +%% Note that this is now the normal way - i.e. systools now ignores +%% the module versions in the .app file. no_mod_vsn_tar(Config) when is_list(Config) -> - ?line {ok, OldDir} = file:get_cwd(), + {ok, OldDir} = file:get_cwd(), - ?line {LatestDir, LatestName} = create_script(latest_no_mod_vsn,Config), + {LatestDir, LatestName} = create_script(latest_no_mod_vsn,Config), - ?line DataDir = filename:absname(?copydir), - ?line LibDir = fname([DataDir, d_normal, lib]), - ?line P = [fname([LibDir, 'db-3.1', ebin]), - fname([LibDir, 'fe-3.1', ebin])], + DataDir = filename:absname(?copydir), + LibDir = fname([DataDir, d_normal, lib]), + P = [fname([LibDir, 'db-3.1', ebin]), + fname([LibDir, 'fe-3.1', ebin])], - ?line ok = file:set_cwd(LatestDir), + ok = file:set_cwd(LatestDir), - ?line {ok, _, _} = systools:make_script(LatestName, [silent, {path, P}]), - ?line ok = systools:make_tar(LatestName, [{path, P}]), - ?line ok = check_tar(fname([lib,'db-3.1',ebin,'db.app']), LatestName), - ?line {ok, _, _} = systools:make_tar(LatestName, [{path, P}, silent]), - ?line ok = check_tar(fname([lib,'fe-3.1',ebin,'fe.app']), LatestName), + {ok, _, _} = systools:make_script(LatestName, [silent, {path, P}]), + ok = systools:make_tar(LatestName, [{path, P}]), + ok = check_tar(fname([lib,'db-3.1',ebin,'db.app']), LatestName), + {ok, _, _} = systools:make_tar(LatestName, [{path, P}, silent]), + ok = check_tar(fname([lib,'fe-3.1',ebin,'fe.app']), LatestName), - ?line ok = file:set_cwd(OldDir), + ok = file:set_cwd(OldDir), ok. -%% variable_tar -%% -variable_tar(suite) -> []; -variable_tar(doc) -> - ["Use variable and create separate tar (included in generated tar)."]; +%% make_tar: Use variable and create separate tar (included in generated tar). variable_tar(Config) when is_list(Config) -> - ?line {ok, OldDir} = file:get_cwd(), + {ok, OldDir} = file:get_cwd(), - ?line {LatestDir, LatestName} = create_script(latest,Config), + {LatestDir, LatestName} = create_script(latest,Config), - ?line DataDir = filename:absname(?copydir), - ?line LibDir = fname([DataDir, d_normal, lib]), - ?line P = [fname([LibDir, 'db-2.1', ebin]), - fname([LibDir, 'fe-3.1', ebin])], + DataDir = filename:absname(?copydir), + LibDir = fname([DataDir, d_normal, lib]), + P = [fname([LibDir, 'db-2.1', ebin]), + fname([LibDir, 'fe-3.1', ebin])], - ?line ok = file:set_cwd(LatestDir), + ok = file:set_cwd(LatestDir), - ?line {ok, _, _} = systools:make_script(LatestName, - [silent, - {path, P}, - {variables,[{"TEST", LibDir}]}]), + {ok, _, _} = systools:make_script(LatestName, + [silent, + {path, P}, + {variables,[{"TEST", LibDir}]}]), - ?line ok = systools:make_tar(LatestName, [{path, P}, - {variables,[{"TEST", LibDir}]}]), - ?line ok = check_var_tar("TEST", LatestName), + ok = systools:make_tar(LatestName, [{path, P}, + {variables,[{"TEST", LibDir}]}]), + ok = check_var_tar("TEST", LatestName), - ?line {ok, _, _} = systools:make_tar(LatestName, - [{path, P}, silent, - {variables,[{"TEST", LibDir}]}]), - ?line ok = check_var_tar("TEST", LatestName), + {ok, _, _} = systools:make_tar(LatestName, + [{path, P}, silent, + {variables,[{"TEST", LibDir}]}]), + ok = check_var_tar("TEST", LatestName), - ?line ok = file:set_cwd(OldDir), + ok = file:set_cwd(OldDir), ok. -%% link_tar -%% -link_tar(suite) -> []; -link_tar(doc) -> - ["Check that symlinks in applications are handled correctly"]; +%% make_tar: Check that symlinks in applications are handled correctly. link_tar(Config) when is_list(Config) -> - ?line {ok, OldDir} = file:get_cwd(), + {ok, OldDir} = file:get_cwd(), - ?line {LatestDir, LatestName} = create_script(latest,Config), + {LatestDir, LatestName} = create_script(latest,Config), - ?line DataDir = filename:absname(?copydir), - ?line LibDir = fname([DataDir, d_links, lib]), - ?line P = [fname([LibDir, 'db-2.1', ebin]), - fname([LibDir, 'fe-3.1', ebin])], + DataDir = filename:absname(?copydir), + LibDir = fname([DataDir, d_links, lib]), + P = [fname([LibDir, 'db-2.1', ebin]), + fname([LibDir, 'fe-3.1', ebin])], %% Make some links - ?line Db1Erl = fname(['db-2.1',src,'db1.erl']), - ?line NormalDb1Erl = fname([DataDir,d_normal,lib,Db1Erl]), - ?line LinkDb1Erl = fname([LibDir, Db1Erl]), - ?line ok = file:make_symlink(NormalDb1Erl, LinkDb1Erl), - ?line Db1Beam = fname(['db-2.1',ebin,'db1.beam']), - ?line NormalDb1Beam = fname([DataDir,d_normal,lib,Db1Beam]), - ?line LinkDb1Beam = fname([LibDir, Db1Beam]), - ?line ok = file:make_symlink(NormalDb1Beam, LinkDb1Beam), - ?line FeApp = fname(['fe-3.1',ebin,'fe.app']), - ?line NormalFeApp = fname([DataDir,d_normal,lib,FeApp]), - ?line LinkFeApp = fname([LibDir, FeApp]), - ?line ok = file:make_symlink(NormalFeApp, LinkFeApp), - + Db1Erl = fname(['db-2.1',src,'db1.erl']), + NormalDb1Erl = fname([DataDir,d_normal,lib,Db1Erl]), + LinkDb1Erl = fname([LibDir, Db1Erl]), + ok = file:make_symlink(NormalDb1Erl, LinkDb1Erl), + Db1Beam = fname(['db-2.1',ebin,'db1.beam']), + NormalDb1Beam = fname([DataDir,d_normal,lib,Db1Beam]), + LinkDb1Beam = fname([LibDir, Db1Beam]), + ok = file:make_symlink(NormalDb1Beam, LinkDb1Beam), + FeApp = fname(['fe-3.1',ebin,'fe.app']), + NormalFeApp = fname([DataDir,d_normal,lib,FeApp]), + LinkFeApp = fname([LibDir, FeApp]), + ok = file:make_symlink(NormalFeApp, LinkFeApp), + %% Create the tar and check that the linked files are included as %% regular files - ?line ok = file:set_cwd(LatestDir), - - ?line {ok,_,[]} = systools:make_script(LatestName, [{path, P},silent]), - - ?line {ok, _, []} = systools:make_tar(LatestName, [{path, P}, silent]), - ?line ok = check_tar_regular(?privdir, - [fname([lib,FeApp]), - fname([lib,Db1Beam])], - LatestName), - - ?line {ok, _, []} = systools:make_tar(LatestName, [{path, P}, silent, - {dirs, [src]}]), - ?line ok = check_tar_regular(?privdir, - [fname([lib,FeApp]), - fname([lib,Db1Beam]), - fname([lib,Db1Erl])], - LatestName), - - ?line ok = file:set_cwd(OldDir), + ok = file:set_cwd(LatestDir), + + {ok,_,[]} = systools:make_script(LatestName, [{path, P},silent]), + + {ok, _, []} = systools:make_tar(LatestName, [{path, P}, silent]), + ok = check_tar_regular(?privdir, + [fname([lib,FeApp]), + fname([lib,Db1Beam])], + LatestName), + + {ok, _, []} = systools:make_tar(LatestName, [{path, P}, silent, + {dirs, [src]}]), + ok = check_tar_regular(?privdir, + [fname([lib,FeApp]), + fname([lib,Db1Beam]), + fname([lib,Db1Erl])], + LatestName), + + ok = file:set_cwd(OldDir), ok. -%% src_tests_tar -%% -src_tests_tar(suite) -> []; -src_tests_tar(doc) -> - ["Do not check date of object file or that source code can be found."]; +%% make_tar: Do not check date of object file or that source code can be found. src_tests_tar(Config) when is_list(Config) -> - ?line {ok, OldDir} = file:get_cwd(), + {ok, OldDir} = file:get_cwd(), - ?line {LatestDir, LatestName} = create_script(latest,Config), + {LatestDir, LatestName} = create_script(latest,Config), - ?line DataDir = filename:absname(?copydir), - ?line LibDir = fname([DataDir, d_missing_src, lib]), - ?line P1 = fname([LibDir, 'db-2.1', ebin]), - ?line P2 = fname([LibDir, 'fe-3.1', ebin]), + DataDir = filename:absname(?copydir), + LibDir = fname([DataDir, d_missing_src, lib]), + P1 = fname([LibDir, 'db-2.1', ebin]), + P2 = fname([LibDir, 'fe-3.1', ebin]), P = [P1, P2], - ?line ok = file:set_cwd(LatestDir), + ok = file:set_cwd(LatestDir), %% Manipulate the modification date of a beam file so it seems %% older than the .erl file @@ -921,282 +856,308 @@ src_tests_tar(Config) when is_list(Config) -> ok = file:write_file_info(Beam, FileInfo#file_info{mtime={{Y-1,M,D},T}}), %% Remove a .erl file - ?line Erl2 = filename:join([P1,"..","src","db2.erl"]), - ?line file:delete(Erl2), + Erl2 = filename:join([P1,"..","src","db2.erl"]), + file:delete(Erl2), - ?line ok = systools:make_script(LatestName, [{path, P}]), + ok = systools:make_script(LatestName, [{path, P}]), %% Then make tar - two warnings should be issued when %% src_tests is given %% 1. old object code for db1.beam %% 2. missing source code for db2.beam - ?line {ok, _, [{warning,{obj_out_of_date,_}}, - {warning,{source_not_found,_}}]} = + {ok, _, [{warning,{obj_out_of_date,_}}, + {warning,{source_not_found,_}}]} = systools:make_tar(LatestName, [{path, P}, silent, {dirs, [src]}, src_tests]), - ?line ok = check_tar(fname([lib,'db-2.1',src,'db1.erl']), LatestName), + ok = check_tar(fname([lib,'db-2.1',src,'db1.erl']), LatestName), %% Without the src_tests option, no warning should be issued - ?line {ok, _, []} = systools:make_tar(LatestName, [{path, P}, silent, - {dirs, [src]}]), - ?line ok = check_tar(fname([lib,'db-2.1',src,'db1.erl']), LatestName), + {ok, _, []} = systools:make_tar(LatestName, [{path, P}, silent, + {dirs, [src]}]), + ok = check_tar(fname([lib,'db-2.1',src,'db1.erl']), LatestName), %% Check that the old no_module_tests option (from the time when %% it was default to do the src_test) is ignored - ?line {ok, _, [{warning,{obj_out_of_date,_}}, - {warning,{source_not_found,_}}]} = + {ok, _, [{warning,{obj_out_of_date,_}}, + {warning,{source_not_found,_}}]} = systools:make_tar(LatestName, [{path, P}, silent, {dirs, [src]}, no_module_tests, src_tests]), - ?line ok = check_tar(fname([lib,'db-2.1',src,'db1.erl']), LatestName), + ok = check_tar(fname([lib,'db-2.1',src,'db1.erl']), LatestName), - ?line ok = file:set_cwd(OldDir), + ok = file:set_cwd(OldDir), ok. -%% shadow_tar -%% -shadow_tar(suite) -> []; -shadow_tar(doc) -> - ["Check that jam file out of date warning doesn't", - "shadow bad module version error."]; -shadow_tar(Config) when is_list(Config) -> - % This test has been commented out since the 'vsn' attribute is not used - % any more, starting with R6. No warning 'obj_out_of_date' seemed to be - % generated. - true; -shadow_tar(Config) when is_list(Config) -> - ?line {ok, OldDir} = file:get_cwd(), - ?line PSAVE = code:get_path(), % Save path - - ?line {LatestDir, LatestName} = create_script(latest,Config), - - ?line DataDir = filename:absname(?copydir), - ?line LibDir = fname([DataDir, 'd_bad_mod+warn', lib]), - ?line P = [fname([LibDir, 'db-2.1', ebin]), - fname([LibDir, 'fe-3.1', ebin])], - - ?line ok = file:set_cwd(LatestDir), - - ?line {error, _, _} = systools:make_tar(LatestName, [{path, P}, silent]), - ?line {error, _, _} = systools:make_tar(LatestName, [{path, P}, silent, - {dirs, [src]}]), - ?line ok = file:set_cwd(OldDir), - ?line code:set_path(PSAVE), - ok. - -%% var_tar -%% -var_tar(suite) -> []; -var_tar(doc) -> - ["Check that make_tar handles generation and placement of tar", - "files for variables outside the main tar file.", - "Test the {var_tar, include | ownfile | omit} option."]; +%% make_tar: Check that make_tar handles generation and placement of +%% tar files for variables outside the main tar file. +%% Test the {var_tar, include | ownfile | omit} optio. var_tar(Config) when is_list(Config) -> - ?line {ok, OldDir} = file:get_cwd(), - ?line PSAVE = code:get_path(), % Save path + {ok, OldDir} = file:get_cwd(), + PSAVE = code:get_path(), % Save path - ?line {LatestDir, LatestName} = create_script(latest,Config), + {LatestDir, LatestName} = create_script(latest,Config), - ?line DataDir = filename:absname(?copydir), - ?line LibDir = fname([DataDir, d_normal, lib]), - ?line P = [fname([LibDir, 'db-2.1', ebin]), - fname([LibDir, 'fe-3.1', ebin])], + DataDir = filename:absname(?copydir), + LibDir = fname([DataDir, d_normal, lib]), + P = [fname([LibDir, 'db-2.1', ebin]), + fname([LibDir, 'fe-3.1', ebin])], - ?line ok = file:set_cwd(LatestDir), + ok = file:set_cwd(LatestDir), - ?line {ok, _, _} = systools:make_script(LatestName, - [silent, - {path, P}, - {variables,[{"TEST", LibDir}]}]), + {ok, _, _} = systools:make_script(LatestName, + [silent, + {path, P}, + {variables,[{"TEST", LibDir}]}]), - ?line ok = systools:make_tar(LatestName, [{path, P}, - {var_tar, ownfile}, - {variables,[{"TEST", LibDir}]}]), + ok = systools:make_tar(LatestName, [{path, P}, + {var_tar, ownfile}, + {variables,[{"TEST", LibDir}]}]), - ?line true = exists_tar_file("TEST"), %% Also removes the file ! - ?line {error, {not_generated, _}} = check_var_tar("TEST", LatestName), + true = exists_tar_file("TEST"), %% Also removes the file ! + {error, {not_generated, _}} = check_var_tar("TEST", LatestName), - ?line ok = systools:make_tar(LatestName, [{path, P}, - {var_tar, omit}, - {variables,[{"TEST", LibDir}]}]), + ok = systools:make_tar(LatestName, [{path, P}, + {var_tar, omit}, + {variables,[{"TEST", LibDir}]}]), - ?line {error, {not_generated, _}} = check_var_tar("TEST", LatestName), - ?line false = exists_tar_file("TEST"), + {error, {not_generated, _}} = check_var_tar("TEST", LatestName), + false = exists_tar_file("TEST"), - ?line ok = systools:make_tar(LatestName, [{path, P}, - {var_tar, include}, - {variables,[{"TEST", LibDir}]}]), + ok = systools:make_tar(LatestName, [{path, P}, + {var_tar, include}, + {variables,[{"TEST", LibDir}]}]), - ?line ok = check_var_tar("TEST", LatestName), - ?line false = exists_tar_file("TEST"), + ok = check_var_tar("TEST", LatestName), + false = exists_tar_file("TEST"), - ?line ok = file:set_cwd(OldDir), - ?line code:set_path(PSAVE), + ok = file:set_cwd(OldDir), + code:set_path(PSAVE), ok. -%% exref_tar -%% -exref_tar(suite) -> []; -exref_tar(doc) -> - ["Check exref option."]; +%% make_tar: Check exref option. exref_tar(Config) when is_list(Config) -> - ?line {ok, OldDir} = file:get_cwd(), + {ok, OldDir} = file:get_cwd(), - ?line {LatestDir, LatestName} = create_script(latest,Config), + {LatestDir, LatestName} = create_script(latest,Config), - ?line DataDir = filename:absname(?copydir), - ?line LibDir = fname([DataDir, d_normal, lib]), - ?line P = [fname([LibDir, 'db-2.1', ebin]), - fname([LibDir, 'fe-3.1', ebin])], + DataDir = filename:absname(?copydir), + LibDir = fname([DataDir, d_normal, lib]), + P = [fname([LibDir, 'db-2.1', ebin]), + fname([LibDir, 'fe-3.1', ebin])], - ?line ok = file:set_cwd(LatestDir), + ok = file:set_cwd(LatestDir), - ?line {ok, _, _} = systools:make_script(LatestName, [silent, {path, P}]), + {ok, _, _} = systools:make_script(LatestName, [silent, {path, P}]), %% Complete exref - ?line {ok, _, W1} = + {ok, _, W1} = systools:make_tar(LatestName, [exref, {path, P}, silent]), - ?line check_exref_warnings(with_db1, W1), - ?line ok = check_tar(fname([lib,'db-2.1',ebin,'db.app']), LatestName), + check_exref_warnings(with_db1, W1), + ok = check_tar(fname([lib,'db-2.1',ebin,'db.app']), LatestName), %% Only exref the db application. - ?line {ok, _, W2} = + {ok, _, W2} = systools:make_tar(LatestName, [{exref, [db]}, {path, P}, silent]), - ?line check_exref_warnings(with_db1, W2), - ?line ok = check_tar(fname([lib,'fe-3.1',ebin,'fe.app']), LatestName), + check_exref_warnings(with_db1, W2), + ok = check_tar(fname([lib,'fe-3.1',ebin,'fe.app']), LatestName), %% Only exref the fe application. - ?line {ok, _, W3} = + {ok, _, W3} = systools:make_tar(LatestName, [{exref, [fe]}, {path, P}, silent]), - ?line check_exref_warnings(without_db1, W3), - ?line ok = check_tar(fname([lib,'db-2.1',ebin,'db.app']), LatestName), + check_exref_warnings(without_db1, W3), + ok = check_tar(fname([lib,'db-2.1',ebin,'db.app']), LatestName), %% exref the db and stdlib applications. - ?line {ok, _, W4} = + {ok, _, W4} = systools:make_tar(LatestName, [{exref, [db, stdlib]}, {path, P}, silent]), - ?line check_exref_warnings(with_db1, W4), - ?line ok = check_tar(fname([lib,'fe-3.1',ebin,'fe.app']), LatestName), + check_exref_warnings(with_db1, W4), + ok = check_tar(fname([lib,'fe-3.1',ebin,'fe.app']), LatestName), - ?line ok = file:set_cwd(OldDir), + ok = file:set_cwd(OldDir), ok. -%% otp_9507 -%% -otp_9507(suite) -> []; -otp_9507(doc) -> - ["make_tar failed when path given as just 'ebin'."]; -otp_9507(Config) when is_list(Config) -> - ?line {ok, OldDir} = file:get_cwd(), +%% make_tar: OTP-9507 - make_tar failed when path given as just 'ebin'. +otp_9507_path_ebin(Config) when is_list(Config) -> + {ok, OldDir} = file:get_cwd(), - ?line {LatestDir, LatestName} = create_script(latest_small,Config), + {LatestDir, LatestName} = create_script(latest_small,Config), - ?line DataDir = filename:absname(?copydir), - ?line LibDir = fname([DataDir, d_normal, lib]), - ?line FeDir = fname([LibDir, 'fe-3.1']), + DataDir = filename:absname(?copydir), + LibDir = fname([DataDir, d_normal, lib]), + FeDir = fname([LibDir, 'fe-3.1']), - ?line ok = file:set_cwd(FeDir), + ok = file:set_cwd(FeDir), RelName = fname([LatestDir,LatestName]), - ?line P1 = ["./ebin", - fname([DataDir, lib, kernel, ebin]), - fname([DataDir, lib, stdlib, ebin])], - ?line {ok, _, _} = systools:make_script(RelName, [silent, {path, P1}]), - ?line ok = systools:make_tar(RelName, [{path, P1}]), - ?line Content1 = tar_contents(RelName), + P1 = ["./ebin", + fname([DataDir, lib, kernel, ebin]), + fname([DataDir, lib, stdlib, ebin]), + fname([DataDir, lib, sasl, ebin])], + {ok, _, _} = systools:make_script(RelName, [silent, {path, P1}]), + ok = systools:make_tar(RelName, [{path, P1}]), + Content1 = tar_contents(RelName), - ?line P2 = ["ebin", - fname([DataDir, lib, kernel, ebin]), - fname([DataDir, lib, stdlib, ebin])], + P2 = ["ebin", + fname([DataDir, lib, kernel, ebin]), + fname([DataDir, lib, stdlib, ebin]), + fname([DataDir, lib, sasl, ebin])], %% Tickets solves the following line - it used to fail with %% {function_clause,[{filename,join,[[]]},...} - ?line ok = systools:make_tar(RelName, [{path, P2}]), - ?line Content2 = tar_contents(RelName), + ok = systools:make_tar(RelName, [{path, P2}]), + Content2 = tar_contents(RelName), true = (Content1 == Content2), - ?line ok = file:set_cwd(OldDir), + ok = file:set_cwd(OldDir), ok. -%% The relup stuff. -%% -%% - - -%% make_relup -%% -normal_relup(suite) -> []; -normal_relup(doc) -> - ["Check normal case"]; +%% make_relup: Check normal case normal_relup(Config) when is_list(Config) -> - ?line {ok, OldDir} = file:get_cwd(), + {ok, OldDir} = file:get_cwd(), - ?line {LatestDir,LatestName} = create_script(latest0,Config), - ?line {_LatestDir1,LatestName1} = create_script(latest1,Config), - ?line {_LatestDir2,LatestName2} = create_script(latest2,Config), + {LatestDir,LatestName} = create_script(latest0,Config), + {_LatestDir1,LatestName1} = create_script(latest1,Config), + {_LatestDir2,LatestName2} = create_script(latest2,Config), - ?line DataDir = filename:absname(?copydir), - ?line LibDir = [fname([DataDir, d_normal, lib])], - ?line P = [fname([LibDir, '*', ebin]), - fname([DataDir, lib, kernel, ebin]), - fname([DataDir, lib, stdlib, ebin])], + DataDir = filename:absname(?copydir), + LibDir = [fname([DataDir, d_normal, lib])], + P = [fname([LibDir, '*', ebin]), + fname([DataDir, lib, kernel, ebin]), + fname([DataDir, lib, stdlib, ebin]), + fname([DataDir, lib, sasl, ebin])], - ?line ok = file:set_cwd(LatestDir), - - %% OTP-2561: Check that the option 'restart_emulator' generates a - %% "restart_new_emulator" instruction. - ?line {ok, _ , _, []} = - systools:make_relup(LatestName, [LatestName1], [LatestName1], - [{path, P},restart_emulator,silent]), - ?line ok = check_relup([{db, "2.1"}], [{db, "1.0"}]), - ?line ok = check_restart_emulator(), + ok = file:set_cwd(LatestDir), %% This is the ultra normal case - ?line ok = systools:make_relup(LatestName, [LatestName1], [LatestName1], - [{path, P}]), - ?line ok = check_relup([{db, "2.1"}], [{db, "1.0"}]), - ?line {ok, _, _, []} = + ok = systools:make_relup(LatestName, [LatestName1], [LatestName1], + [{path, P}]), + ok = check_relup([{db, "2.1"}], [{db, "1.0"}]), + {ok, _, _, []} = systools:make_relup(LatestName, [LatestName1], [LatestName1], [{path, P}, silent]), - ?line ok = check_relup([{db, "2.1"}], [{db, "1.0"}]), + ok = check_relup([{db, "2.1"}], [{db, "1.0"}]), %% file should not be written if warnings_as_errors is enabled. %% delete before running tests. - ?line ok = file:delete("relup"), + ok = file:delete("relup"), %% Check that warnings are treated as errors - ?line error = + error = systools:make_relup(LatestName, [LatestName2], [LatestName1], [{path, P}, warnings_as_errors]), - ?line error = + error = systools:make_relup(LatestName, [LatestName2], [LatestName1], [{path, P}, silent, warnings_as_errors]), %% relup file should not exist - ?line false = filelib:is_regular("relup"), + false = filelib:is_regular("relup"), %% Check that warnings get through - ?line ok = systools:make_relup(LatestName, [LatestName2], [LatestName1], - [{path, P}]), - ?line ok = check_relup([{fe, "3.1"}, {db, "2.1"}], [{db, "1.0"}]), - ?line {ok, _, _, [{erts_vsn_changed, _}]} = + ok = systools:make_relup(LatestName, [LatestName2], [LatestName1], + [{path, P}]), + ok = check_relup([{fe, "3.1"}, {db, "2.1"}], [{db, "1.0"}]), + {ok, _, _, [pre_R15_emulator_upgrade,{erts_vsn_changed, _}]} = systools:make_relup(LatestName, [LatestName2], [LatestName1], [{path, P}, silent]), - ?line ok = check_relup([{fe, "3.1"}, {db, "2.1"}], [{db, "1.0"}]), + ok = check_relup([{fe, "3.1"}, {db, "2.1"}], [{db, "1.0"}]), %% relup file should exist now - ?line true = filelib:is_regular("relup"), + true = filelib:is_regular("relup"), - ?line ok = file:set_cwd(OldDir), + ok = file:set_cwd(OldDir), + ok. + + +%% make_relup: Test relup which includes emulator restart. +restart_relup(Config) when is_list(Config) -> + {ok, OldDir} = file:get_cwd(), + + {LatestDir,LatestName} = create_script(latest0,Config), + {_LatestDir1,LatestName1} = create_script(latest1,Config), + {_LatestDir0CurrErts,LatestName0CurrErts} = + create_script(latest0_current_erts,Config), + {_CurrentAllDir,CurrentAllName} = create_script(current_all,Config), + {_CurrentAllFutErtsDir,CurrentAllFutErtsName} = + create_script(current_all_future_erts,Config), + {_CurrentAllFutSaslDir,CurrentAllFutSaslName} = + create_script(current_all_future_sasl,Config), + + DataDir = filename:absname(?copydir), + LibDir = [fname([DataDir, d_normal, lib])], + P = [fname([LibDir, '*', ebin]), + fname([DataDir, lib, kernel, ebin]), + fname([DataDir, lib, stdlib, ebin]), + fname([DataDir, lib, sasl, ebin]), + fname([DataDir, lib, 'sasl-9.9', ebin])], + + ok = file:set_cwd(LatestDir), + + %% OTP-2561: Check that the option 'restart_emulator' generates a + %% "restart_emulator" instruction. + {ok, _ , _, []} = + systools:make_relup(LatestName, [LatestName1], [LatestName1], + [{path, P},restart_emulator,silent]), + ok = check_relup([{db, "2.1"}], [{db, "1.0"}]), + ok = check_restart_emulator(), + + + %% Pre-R15 to Post-R15 upgrade + {ok, _ , _, Ws} = + systools:make_relup(LatestName0CurrErts, + [LatestName1], + [LatestName1], + [{path, P},silent]), + ok = check_relup([{db,"2.1"}], [{db, "1.0"}]), + ok = check_pre_to_post_r15_restart_emulator(), + ok = check_pre_to_post_r15_warnings(Ws), + + + %% Check that new sasl version generates a restart_new_emulator + %% instruction + {ok, _ , _, []} = + systools:make_relup(CurrentAllFutSaslName, + [CurrentAllName], + [CurrentAllName], + [{path, P},silent]), + ok = check_relup([{fe, "3.1"}], []), + ok = check_restart_emulator_diff_coreapp(), + + + %% Check that new erts version generates a restart_new_emulator + %% instruction, if FromSaslVsn >= R15SaslVsn + %% (One erts_vsn_changed warning for upgrade and one for downgrade) + {ok, _ , _, [{erts_vsn_changed,_},{erts_vsn_changed,_}]} = + systools:make_relup(CurrentAllFutErtsName, + [CurrentAllName], + [CurrentAllName], + [{path, P},silent]), + ok = check_relup([{fe, "3.1"}], []), + ok = check_restart_emulator_diff_coreapp(), + + + %% Check that new erts version generates a restart_new_emulator + %% instruction, and can be combined with restart_emulator opt. + %% (One erts_vsn_changed warning for upgrade and one for downgrade) + {ok, _ , _, [{erts_vsn_changed,_},{erts_vsn_changed,_}]} = + systools:make_relup(CurrentAllFutErtsName, + [CurrentAllName], + [CurrentAllName], + [{path, P},restart_emulator,silent]), + ok = check_relup([{fe, "3.1"}], []), + ok = check_restart_emulator(), + ok = check_restart_emulator_diff_coreapp(), + + ok = file:set_cwd(OldDir), ok. @@ -1216,295 +1177,558 @@ check_relup(UpVsnL, DnVsnL) -> [{App, Vsn} || {load_object_code,{App,Vsn,_}} <- Dn]), ok. +check_relup_up_only(UpVsnL) -> + {ok, [{_V1, [{_, _, Up}], []}]} = file:consult(relup), + [] = foldl(fun(X, Acc) -> + true = lists:member(X, Acc), + lists:delete(X, Acc) end, + UpVsnL, + [{App, Vsn} || {load_object_code,{App,Vsn,_}} <- Up]), + ok. + check_restart_emulator() -> {ok, [{_V1, [{_, _, Up}], [{_, _, Dn}]}]} = file:consult(relup), + restart_emulator = lists:last(Up), + restart_emulator = lists:last(Dn), + ok. + +check_restart_emulator_up_only() -> + {ok, [{_V1, [{_, _, Up}], []}]} = file:consult(relup), + restart_emulator = lists:last(Up), + ok. + +check_restart_emulator_diff_coreapp() -> + {ok, [{_V1, [{_, _, Up}], [{_, _, Dn}]}]} = file:consult(relup), + [restart_new_emulator|_] = Up, + restart_emulator = lists:last(Dn), + ok. + +check_pre_to_post_r15_restart_emulator() -> + {ok, [{_V1, [{_, _, Up}], [{_, _, Dn}]}]} = file:consult(relup), restart_new_emulator = lists:last(Up), - restart_new_emulator = lists:last(Dn), + restart_emulator = lists:last(Dn), ok. -%% make_relup -%% -no_appup_relup(suite) -> []; -no_appup_relup(doc) -> - ["Check that appup files may be missing, but only if we don't need them."]; +check_pre_to_post_r15_warnings(Ws) -> + true = lists:member(pre_R15_emulator_upgrade,Ws), + ok. + +%% make_relup: Check that appup files may be missing, but only if we +%% don't need them. no_appup_relup(Config) when is_list(Config) -> - ?line {ok, OldDir} = file:get_cwd(), + {ok, OldDir} = file:get_cwd(), - ?line {LatestDir,LatestName} = create_script(latest_small,Config), - ?line {_LatestDir0,LatestName0} = create_script(latest_small0,Config), - ?line {_LatestDir1,LatestName1} = create_script(latest_small1,Config), + {LatestDir,LatestName} = create_script(latest_small,Config), + {_LatestDir0,LatestName0} = create_script(latest_small0,Config), + {_LatestDir1,LatestName1} = create_script(latest_small1,Config), - ?line DataDir = filename:absname(?copydir), - ?line P1 = [fname([DataDir, d_no_appup, lib, 'fe-3.1', ebin]), - fname([DataDir, lib, kernel, ebin]), - fname([DataDir, lib, stdlib, ebin])], + DataDir = filename:absname(?copydir), - ?line ok = file:set_cwd(LatestDir), + ok = file:set_cwd(LatestDir), %% Check that appup might be missing - ?line ok = + P1 = [fname([DataDir, d_no_appup, lib, 'fe-3.1', ebin]), + fname([DataDir, lib, kernel, ebin]), + fname([DataDir, lib, stdlib, ebin]), + fname([DataDir, lib, sasl, ebin])], + ok = systools:make_relup(LatestName, [LatestName], [], [{path, P1}]), - ?line {ok,_, _, []} = + {ok,_, _, []} = systools:make_relup(LatestName, [LatestName], [], [silent, {path, P1}]), %% Check that appup might NOT be missing when we need it - ?line error = - systools:make_relup(LatestName, [LatestName0], [], [{path, P1}]), - ?line {error,_,{file_problem, {_,{error,{open,_,_}}}}} = + P2 = [fname([DataDir, d_no_appup, lib, 'fe-3.1', ebin]), + fname([DataDir, d_no_appup, lib, 'fe-2.1', ebin]), + fname([DataDir, lib, kernel, ebin]), + fname([DataDir, lib, stdlib, ebin]), + fname([DataDir, lib, sasl, ebin])], + error = + systools:make_relup(LatestName, [LatestName0], [], [{path, P2}]), + {error,_,{file_problem, {_,{error,{open,_,_}}}}} = systools:make_relup(LatestName, [], [LatestName0], - [silent, {path, P1}]), + [silent, {path, P2}]), %% Check that appups missing vsn traps - ?line P2 = [fname([DataDir, d_no_appup, lib, 'fe-2.1', ebin]), - fname([DataDir, lib, kernel, ebin]), - fname([DataDir, lib, stdlib, ebin])], - - ?line error = - systools:make_relup(LatestName0, [LatestName1], [], [{path, P2}]), - ?line {error,_,{no_relup, _, _, _}} = + P3 = [fname([DataDir, d_no_appup, lib, 'fe-2.1', ebin]), + fname([DataDir, d_no_appup, lib, 'fe-500.18.7', ebin]), + fname([DataDir, lib, kernel, ebin]), + fname([DataDir, lib, stdlib, ebin]), + fname([DataDir, lib, sasl, ebin])], + + error = + systools:make_relup(LatestName0, [LatestName1], [], [{path, P3}]), + {error,_,{no_relup, _, _, _}} = systools:make_relup(LatestName0, [], [LatestName1], - [silent, {path, P2}]), + [silent, {path, P3}]), - ?line ok = file:set_cwd(OldDir), + ok = file:set_cwd(OldDir), ok. -%% make_relup -%% -bad_appup_relup(suite) -> []; -bad_appup_relup(doc) -> - ["Check that badly written appup files are detected"]; +%% make_relup: Check that badly written appup files are detected. bad_appup_relup(Config) when is_list(Config) -> - ?line {ok, OldDir} = file:get_cwd(), + {ok, OldDir} = file:get_cwd(), - ?line {LatestDir,LatestName} = create_script(latest_small,Config), - ?line {_LatestDir0,LatestName0} = create_script(latest_small0,Config), + {LatestDir,LatestName} = create_script(latest_small,Config), + {_LatestDir0,LatestName0} = create_script(latest_small0,Config), - ?line DataDir = filename:absname(?copydir), - ?line N2 = [fname([DataDir, d_bad_appup, lib, 'fe-3.1', ebin]), - fname([DataDir, lib, kernel, ebin]), - fname([DataDir, lib, stdlib, ebin])], + DataDir = filename:absname(?copydir), + N2 = [fname([DataDir, d_bad_appup, lib, 'fe-3.1', ebin]), + fname([DataDir, d_bad_appup, lib, 'fe-2.1', ebin]), + fname([DataDir, lib, kernel, ebin]), + fname([DataDir, lib, stdlib, ebin]), + fname([DataDir, lib, sasl, ebin])], - ?line ok = file:set_cwd(LatestDir), + ok = file:set_cwd(LatestDir), %% Check that bad appup is trapped - ?line error = + error = systools:make_relup(LatestName, [LatestName0], [], [{path, N2}]), - ?line {error,_,{file_problem, {_, {error, {parse,_, _}}}}} = + {error,_,{file_problem, {_, {error, {parse,_, _}}}}} = systools:make_relup(LatestName, [], [LatestName0], [silent, {path, N2}]), - ?line ok = file:set_cwd(OldDir), + ok = file:set_cwd(OldDir), ok. -%% make_relup -%% -abnormal_relup(suite) -> []; -abnormal_relup(doc) -> - ["Check some abnormal cases"]; +%% make_relup: Check some abnormal cases. abnormal_relup(Config) when is_list(Config) -> - ?line {ok, OldDir} = file:get_cwd(), + {ok, OldDir} = file:get_cwd(), - ?line {LatestDir,LatestName} = create_script(latest0,Config), - ?line {_LatestDir1,LatestName1} = create_script(latest1,Config), + {LatestDir,LatestName} = create_script(latest0,Config), + {_LatestDir1,LatestName1} = create_script(latest1,Config), %% Check wrong app vsn - ?line DataDir = filename:absname(?copydir), - ?line P = [fname([DataDir, d_bad_app_vsn, lib, 'db-2.1', ebin]), - fname([DataDir, d_bad_app_vsn, lib, 'fe-3.1', ebin]), - fname([DataDir, lib, kernel, ebin]), - fname([DataDir, lib, stdlib, ebin])], - - ?line ok = file:set_cwd(LatestDir), - - ?line error = systools:make_relup(LatestName, [LatestName1], [LatestName1], - [{path, P}]), - ?line R0 = systools:make_relup(LatestName, [LatestName1], [LatestName1], - [silent, {path, P}]), - ?line {error,systools_make, - [{error_reading,{db,{no_valid_version, - {{"should be","2.1"}, - {"found file", _, "2.0"}}}}}]} = R0, - ?line ok = file:set_cwd(OldDir), + DataDir = filename:absname(?copydir), + P = [fname([DataDir, d_bad_app_vsn, lib, 'db-2.1', ebin]), + fname([DataDir, d_bad_app_vsn, lib, 'fe-3.1', ebin]), + fname([DataDir, lib, kernel, ebin]), + fname([DataDir, lib, stdlib, ebin]), + fname([DataDir, lib, sasl, ebin])], + + ok = file:set_cwd(LatestDir), + + error = systools:make_relup(LatestName, [LatestName1], [LatestName1], + [{path, P}]), + R0 = systools:make_relup(LatestName, [LatestName1], [LatestName1], + [silent, {path, P}]), + {error,systools_make, + [{error_reading,{db,{no_valid_version, + {{"should be","2.1"}, + {"found file", _, "2.0"}}}}}]} = R0, + ok = file:set_cwd(OldDir), ok. -%% Check that application start type is used in relup -app_start_type_relup(suite) -> - []; -app_start_type_relup(doc) -> - ["Release upgrade file with various application start types"]; +%% make_relup: Check relup can not be created is sasl is not in rel file. +no_sasl_relup(Config) when is_list(Config) -> + {ok, OldDir} = file:get_cwd(), + {Dir1,Name1} = create_script(latest1_no_sasl,Config), + {_Dir2,Name2} = create_script(latest1,Config), + + DataDir = filename:absname(?copydir), + LibDir = [fname([DataDir, d_normal, lib])], + P = [fname([LibDir, '*', ebin]), + fname([DataDir, lib, kernel, ebin]), + fname([DataDir, lib, stdlib, ebin]), + fname([DataDir, lib, sasl, ebin])], + + ok = file:set_cwd(Dir1), + + error = systools:make_relup(Name2, [Name1], [Name1], [{path, P}]), + R1 = systools:make_relup(Name2, [Name1], [Name1],[silent, {path, P}]), + {error,systools_relup,{missing_sasl,_}} = R1, + + error = systools:make_relup(Name1, [Name2], [Name2], [{path, P}]), + R2 = systools:make_relup(Name1, [Name2], [Name2],[silent, {path, P}]), + {error,systools_relup,{missing_sasl,_}} = R2, + + ok = file:set_cwd(OldDir), + ok. + + +%% make_relup: Check that application start type is used in relup app_start_type_relup(Config) when is_list(Config) -> - ?line PrivDir = ?config(priv_dir, Config), - ?line {Dir1,Name1} = create_script(latest_app_start_type1,Config), - ?line {Dir2,Name2} = create_script(latest_app_start_type2,Config), - ?line Release1 = filename:join(Dir1,Name1), - ?line Release2 = filename:join(Dir2,Name2), - - ?line {ok, Release2Relup, systools_relup, []} = systools:make_relup(Release2, [Release1], [Release1], [{outdir, PrivDir}, silent]), - ?line {"2", [{"1",[], UpInstructions}], [{"1",[], DownInstructions}]} = Release2Relup, + PrivDir = ?config(priv_dir, Config), + {Dir1,Name1} = create_script(latest_app_start_type1,Config), + {Dir2,Name2} = create_script(latest_app_start_type2,Config), + Release1 = filename:join(Dir1,Name1), + Release2 = filename:join(Dir2,Name2), + + {ok, Release2Relup, systools_relup, []} = systools:make_relup(Release2, [Release1], [Release1], [{outdir, PrivDir}, silent]), + {"LATEST_APP_START_TYPE2", + [{"LATEST_APP_START_TYPE1",[], UpInstructions}], + [{"LATEST_APP_START_TYPE1",[], DownInstructions}]} = Release2Relup, %% ?t:format("Up: ~p",[UpInstructions]), %% ?t:format("Dn: ~p",[DownInstructions]), - ?line [{load_object_code, {mnesia, _, _}}, - {load_object_code, {sasl, _, _}}, - {load_object_code, {webtool, _, _}}, - {load_object_code, {snmp, _, _}}, - {load_object_code, {xmerl, _, _}}, - point_of_no_return - | UpInstructionsT] = UpInstructions, - ?line true = lists:member({apply,{application,start,[mnesia,permanent]}}, UpInstructionsT), - ?line true = lists:member({apply,{application,start,[sasl,transient]}}, UpInstructionsT), - ?line true = lists:member({apply,{application,start,[webtool,temporary]}}, UpInstructionsT), - ?line true = lists:member({apply,{application,load,[snmp]}}, UpInstructionsT), - ?line false = lists:any(fun({apply,{application,_,[xmerl|_]}}) -> true; (_) -> false end, UpInstructionsT), - ?line [point_of_no_return | DownInstructionsT] = DownInstructions, - ?line true = lists:member({apply,{application,stop,[mnesia]}}, DownInstructionsT), - ?line true = lists:member({apply,{application,stop,[sasl]}}, DownInstructionsT), - ?line true = lists:member({apply,{application,stop,[webtool]}}, DownInstructionsT), - ?line true = lists:member({apply,{application,stop,[snmp]}}, DownInstructionsT), - ?line true = lists:member({apply,{application,stop,[xmerl]}}, DownInstructionsT), - ?line true = lists:member({apply,{application,unload,[mnesia]}}, DownInstructionsT), - ?line true = lists:member({apply,{application,unload,[sasl]}}, DownInstructionsT), - ?line true = lists:member({apply,{application,unload,[webtool]}}, DownInstructionsT), - ?line true = lists:member({apply,{application,unload,[snmp]}}, DownInstructionsT), - ?line true = lists:member({apply,{application,unload,[xmerl]}}, DownInstructionsT), + [{load_object_code, {mnesia, _, _}}, + {load_object_code, {runtime_tools, _, _}}, + {load_object_code, {webtool, _, _}}, + {load_object_code, {snmp, _, _}}, + {load_object_code, {xmerl, _, _}}, + point_of_no_return + | UpInstructionsT] = UpInstructions, + true = lists:member({apply,{application,start,[mnesia,permanent]}}, UpInstructionsT), + true = lists:member({apply,{application,start,[runtime_tools,transient]}}, UpInstructionsT), + true = lists:member({apply,{application,start,[webtool,temporary]}}, UpInstructionsT), + true = lists:member({apply,{application,load,[snmp]}}, UpInstructionsT), + false = lists:any(fun({apply,{application,_,[xmerl|_]}}) -> true; (_) -> false end, UpInstructionsT), + [point_of_no_return | DownInstructionsT] = DownInstructions, + true = lists:member({apply,{application,stop,[mnesia]}}, DownInstructionsT), + true = lists:member({apply,{application,stop,[runtime_tools]}}, DownInstructionsT), + true = lists:member({apply,{application,stop,[webtool]}}, DownInstructionsT), + true = lists:member({apply,{application,stop,[snmp]}}, DownInstructionsT), + true = lists:member({apply,{application,stop,[xmerl]}}, DownInstructionsT), + true = lists:member({apply,{application,unload,[mnesia]}}, DownInstructionsT), + true = lists:member({apply,{application,unload,[runtime_tools]}}, DownInstructionsT), + true = lists:member({apply,{application,unload,[webtool]}}, DownInstructionsT), + true = lists:member({apply,{application,unload,[snmp]}}, DownInstructionsT), + true = lists:member({apply,{application,unload,[xmerl]}}, DownInstructionsT), + ok. + + +%% make_relup: Check that regexp can be used in .appup for UpFromVsn +%% and DownToVsn. +regexp_relup(Config) -> + {ok, OldDir} = file:get_cwd(), + + {LatestDir,LatestName} = create_script(latest_small,Config), + {_LatestDir0,LatestName0} = create_script(latest_small0,Config), + {_LatestDir1,LatestName1} = create_script(latest_small2,Config), + + DataDir = filename:absname(?copydir), + P = [fname([DataDir, d_regexp_appup, lib, '*', ebin]), + fname([DataDir, lib, kernel, ebin]), + fname([DataDir, lib, stdlib, ebin]), + fname([DataDir, lib, sasl, ebin])], + + ok = file:set_cwd(LatestDir), + + %% Upgrade fe 2.1 -> 3.1, and downgrade 2.1 -> 3.1 + %% Shall match the first entry if fe-3.1 appup. + {ok, _, _, []} = + systools:make_relup(LatestName, [LatestName0], [LatestName0], + [{path, P}, silent]), + ok = check_relup([{fe, "3.1"}], [{fe, "2.1"}]), + + %% Upgrade fe 2.1.1 -> 3.1 + %% Shall match the second entry in fe-3.1 appup. Have added a + %% restart_emulator instruction there to distinguish it from + %% the first entry... + {ok, _, _, []} = + systools:make_relup(LatestName, [LatestName1], [], [{path, P}, silent]), + ok = check_relup_up_only([{fe, "3.1"}]), + ok = check_restart_emulator_up_only(), + + %% Attempt downgrade fe 3.1 -> 2.1.1 + %% Shall not match any entry!! + {error,systools_relup,{no_relup,_,_,_}} = + systools:make_relup(LatestName, [], [LatestName1], [{path, P}, silent]), + + ok = file:set_cwd(OldDir), + + ok. + + +%% make_hybrid_boot: Normal case. +%% For upgrade of erts - create a boot file which is a hybrid between +%% old and new release - i.e. starts erts, kernel, stdlib, sasl from +%% new release, all other apps from old release. +normal_hybrid(Config) -> + {ok, OldDir} = file:get_cwd(), + {Dir1,Name1} = create_script(latest1,Config), + {_Dir2,Name2} = create_script(current_all,Config), + + DataDir = filename:absname(?copydir), + LibDir = [fname([DataDir, d_normal, lib])], + P = [fname([LibDir, '*', ebin]), + fname([DataDir, lib, kernel, ebin]), + fname([DataDir, lib, stdlib, ebin]), + fname([DataDir, lib, sasl, ebin])], + + ok = file:set_cwd(Dir1), + + {ok, _ , []} = systools:make_script(Name1,[{path, P},silent]), + {ok, _ , []} = systools:make_script(Name2,[{path, P},silent]), + {ok,Boot1} = file:read_file(Name1 ++ ".boot"), + {ok,Boot2} = file:read_file(Name2 ++ ".boot"), + + ok = file:set_cwd(OldDir), + + BasePaths = {"testkernelpath","teststdlibpath","testsaslpath"}, + {ok,Hybrid} = systools_make:make_hybrid_boot("tmp_vsn",Boot1,Boot2, + BasePaths, [dummy,args]), + + {script,{"Test release","tmp_vsn"},Script} = binary_to_term(Hybrid), + ct:log("~p.~n",[Script]), + + %% Check that all paths to base apps are replaced by paths from BaseLib + Boot1Str = io_lib:format("~p~n",[binary_to_term(Boot1)]), + HybridStr = io_lib:format("~p~n",[binary_to_term(Hybrid)]), + ReOpts = [global,{capture,first,list},unicode], + {match,OldKernelMatch} = re:run(Boot1Str,"kernel-[0-9\.]+",ReOpts), + {match,OldStdlibMatch} = re:run(Boot1Str,"stdlib-[0-9\.]+",ReOpts), + {match,OldSaslMatch} = re:run(Boot1Str,"sasl-[0-9\.]+",ReOpts), + + nomatch = re:run(HybridStr,"kernel-[0-9\.]+",ReOpts), + nomatch = re:run(HybridStr,"stdlib-[0-9\.]+",ReOpts), + nomatch = re:run(HybridStr,"sasl-[0-9\.]+",ReOpts), + {match,NewKernelMatch} = re:run(HybridStr,"testkernelpath",ReOpts), + {match,NewStdlibMatch} = re:run(HybridStr,"teststdlibpath",ReOpts), + {match,NewSaslMatch} = re:run(HybridStr,"testsaslpath",ReOpts), + + NewKernelN = length(NewKernelMatch), + NewKernelN = length(OldKernelMatch), + NewStdlibN = length(NewStdlibMatch), + NewStdlibN = length(OldStdlibMatch), + NewSaslN = length(NewSaslMatch), + NewSaslN = length(OldSaslMatch), + + %% Check that application load instruction has correct versions + Apps = application:loaded_applications(), + {_,_,KernelVsn} = lists:keyfind(kernel,1,Apps), + {_,_,StdlibVsn} = lists:keyfind(stdlib,1,Apps), + {_,_,SaslVsn} = lists:keyfind(sasl,1,Apps), + + [KernelInfo] = [I || {kernelProcess,application_controller, + {application_controller,start, + [{application,kernel,I}]}} <- Script], + [StdlibInfo] = [I || {apply, + {application,load, + [{application,stdlib,I}]}} <- Script], + [SaslInfo] = [I || {apply, + {application,load, + [{application,sasl,I}]}} <- Script], + + {vsn,KernelVsn} = lists:keyfind(vsn,1,KernelInfo), + {vsn,StdlibVsn} = lists:keyfind(vsn,1,StdlibInfo), + {vsn,SaslVsn} = lists:keyfind(vsn,1,SaslInfo), + + %% Check that new_emulator_upgrade call is added + [_,{apply,{release_handler,new_emulator_upgrade,[dummy,args]}}|_] = + lists:reverse(Script), + + %% Check that db-1.0 and fe-3.1 are used (i.e. vsns from old release) + %% And that fe is in there (it exists in old rel but not in new) + {match,DbMatch} = re:run(HybridStr,"db-[0-9\.]+",ReOpts), + {match,[_|_]=FeMatch} = re:run(HybridStr,"fe-[0-9\.]+",ReOpts), + true = lists:all(fun(["db-1.0"]) -> true; + (_) -> false + end, + DbMatch), + true = lists:all(fun(["fe-3.1"]) -> true; + (_) -> false + end, + FeMatch), + + %% Check that script has same length as old script, plus one (the + %% new_emulator_upgrade apply) + {_,_,Old} = binary_to_term(Boot1), + OldLength = length(Old), + NewLength = length(Script), + NewLength = OldLength + 1, + + ok. + +%% make_hybrid_boot: No sasl in from-release. +%% Check that systools_make:make_hybrid_boot fails with a meaningful +%% error message if the FromBoot does not include the sasl +%% application. +hybrid_no_old_sasl(Config) -> + {ok, OldDir} = file:get_cwd(), + {Dir1,Name1} = create_script(latest1_no_sasl,Config), + {_Dir2,Name2} = create_script(current_all,Config), + + DataDir = filename:absname(?copydir), + LibDir = [fname([DataDir, d_normal, lib])], + P = [fname([LibDir, '*', ebin]), + fname([DataDir, lib, kernel, ebin]), + fname([DataDir, lib, stdlib, ebin]), + fname([DataDir, lib, sasl, ebin])], + + ok = file:set_cwd(Dir1), + + {ok, _ , [{warning,missing_sasl}]} = + systools:make_script(Name1,[{path, P},silent]), + {ok, _ , []} = systools:make_script(Name2,[{path, P},silent]), + {ok,Boot1} = file:read_file(Name1 ++ ".boot"), + {ok,Boot2} = file:read_file(Name2 ++ ".boot"), + + BasePaths = {"testkernelpath","teststdlibpath","testsaslpath"}, + {error,{app_not_replaced,sasl}} = + systools_make:make_hybrid_boot("tmp_vsn",Boot1,Boot2, + BasePaths,[dummy,args]), + + ok = file:set_cwd(OldDir), + ok. + + +%% make_hybrid_boot: No sasl in to-release. +%% Check that systools_make:make_hybrid_boot fails with a meaningful +%% error message if the ToBoot does not include the sasl +%% application. +hybrid_no_new_sasl(Config) -> + {ok, OldDir} = file:get_cwd(), + {Dir1,Name1} = create_script(latest1,Config), + {_Dir2,Name2} = create_script(current_all_no_sasl,Config), + + DataDir = filename:absname(?copydir), + LibDir = [fname([DataDir, d_normal, lib])], + P = [fname([LibDir, '*', ebin]), + fname([DataDir, lib, kernel, ebin]), + fname([DataDir, lib, stdlib, ebin]), + fname([DataDir, lib, sasl, ebin])], + + ok = file:set_cwd(Dir1), + + {ok, _ , []} = systools:make_script(Name1,[{path, P},silent]), + {ok, _ , [{warning,missing_sasl}]} = + systools:make_script(Name2,[{path, P},silent]), + {ok,Boot1} = file:read_file(Name1 ++ ".boot"), + {ok,Boot2} = file:read_file(Name2 ++ ".boot"), + + BasePaths = {"testkernelpath","teststdlibpath","testsaslpath"}, + {error,{app_not_found,sasl}} = + systools_make:make_hybrid_boot("tmp_vsn",Boot1,Boot2, + BasePaths,[dummy,args]), + + ok = file:set_cwd(OldDir), ok. -otp_6226(suite) -> - []; -otp_6226(doc) -> - ["{outdir,Dir} option for systools:make_script()"]; -otp_6226(Config) when is_list(Config) -> + +%% options: {outdir,Dir} option +otp_6226_outdir(Config) when is_list(Config) -> PrivDir = ?privdir, - ?line {ok, OldDir} = file:get_cwd(), + {ok, OldDir} = file:get_cwd(), - ?line {LatestDir, LatestName} = create_script(latest0,Config), - ?line {_LatestDir, LatestName1} = create_script(latest1,Config), + {LatestDir, LatestName} = create_script(latest0,Config), + {_LatestDir, LatestName1} = create_script(latest1,Config), - ?line DataDir = filename:absname(?copydir), - ?line LibDir = fname([DataDir, d_normal, lib]), - ?line P = [fname([LibDir, 'db-2.1', ebin]), - fname([LibDir, 'db-1.0', ebin]), - fname([LibDir, 'fe-3.1', ebin]), - fname([DataDir, lib, kernel, ebin]), - fname([DataDir, lib, stdlib, ebin])], + DataDir = filename:absname(?copydir), + LibDir = fname([DataDir, d_normal, lib]), + P = [fname([LibDir, 'db-2.1', ebin]), + fname([LibDir, 'db-1.0', ebin]), + fname([LibDir, 'fe-3.1', ebin]), + fname([DataDir, lib, kernel, ebin]), + fname([DataDir, lib, stdlib, ebin]), + fname([DataDir, lib, sasl, ebin])], + + ok = file:set_cwd(LatestDir), - ?line ok = file:set_cwd(LatestDir), - %% Create an outdir1 directory - ?line ok = file:make_dir("outdir1"), + ok = file:make_dir("outdir1"), %% ==== Now test systools:make_script ==== %% a) badarg - ?line {'EXIT', {{badarg,[{outdir,outdir1}]}, _}} = + {'EXIT', {{badarg,[{outdir,outdir1}]}, _}} = (catch systools:make_script(LatestName, [{outdir,outdir1}, {path,P},silent])), %% b) absolute path Outdir1 = filename:join(PrivDir, "outdir1"), - ?line {ok,_,[]} = systools:make_script(LatestName, [{outdir,Outdir1}, - {path,P},silent]), - ?line Script1 = filename:join(Outdir1, LatestName ++ ".script"), - ?line Boot1 = filename:join(Outdir1, LatestName ++ ".boot"), - ?line true = filelib:is_file(Script1), - ?line true = filelib:is_file(Boot1), - ?line ok = file:delete(Script1), - ?line ok = file:delete(Boot1), + {ok,_,[]} = systools:make_script(LatestName, [{outdir,Outdir1}, + {path,P},silent]), + Script1 = filename:join(Outdir1, LatestName ++ ".script"), + Boot1 = filename:join(Outdir1, LatestName ++ ".boot"), + true = filelib:is_file(Script1), + true = filelib:is_file(Boot1), + ok = file:delete(Script1), + ok = file:delete(Boot1), %% c) relative path - ?line {ok,_,[]} = systools:make_script(LatestName, [{outdir,"./outdir1"}, - {path,P},silent]), - ?line true = filelib:is_file(Script1), - ?line true = filelib:is_file(Boot1), - ?line ok = file:delete(Script1), - ?line ok = file:delete(Boot1), + {ok,_,[]} = systools:make_script(LatestName, [{outdir,"./outdir1"}, + {path,P},silent]), + true = filelib:is_file(Script1), + true = filelib:is_file(Boot1), + ok = file:delete(Script1), + ok = file:delete(Boot1), %% d) absolute but incorrect path - ?line Outdir2 = filename:join(PrivDir, "outdir2"), - ?line Script2 = filename:join(Outdir2, LatestName ++ ".script"), - ?line {error,_,{open,Script2,_}} = + Outdir2 = filename:join(PrivDir, "outdir2"), + Script2 = filename:join(Outdir2, LatestName ++ ".script"), + {error,_,{open,Script2,_}} = systools:make_script(LatestName, [{outdir,Outdir2},{path,P},silent]), %% e) relative but incorrect path - ?line {error,_,{open,_,_}} = + {error,_,{open,_,_}} = systools:make_script(LatestName, [{outdir,"./outdir2"},{path,P},silent]), %% f) with .rel in another directory than cwd - ?line ok = file:set_cwd(Outdir1), - ?line {ok,_,[]} = systools:make_script(filename:join(PrivDir, LatestName), - [{outdir,"."},{path,P},silent]), - ?line true = filelib:is_file(LatestName ++ ".script"), - ?line true = filelib:is_file(LatestName ++ ".boot"), - ?line ok = file:delete(LatestName ++ ".script"), - ?line ok = file:delete(LatestName ++ ".boot"), - ?line ok = file:set_cwd(LatestDir), + ok = file:set_cwd(Outdir1), + {ok,_,[]} = systools:make_script(filename:join(PrivDir, LatestName), + [{outdir,"."},{path,P},silent]), + true = filelib:is_file(LatestName ++ ".script"), + true = filelib:is_file(LatestName ++ ".boot"), + ok = file:delete(LatestName ++ ".script"), + ok = file:delete(LatestName ++ ".boot"), + ok = file:set_cwd(LatestDir), %% ==== Now test systools:make_tar ===== - ?line {ok,_,[]} = systools:make_script(LatestName, [{path,P},silent]), + {ok,_,[]} = systools:make_script(LatestName, [{path,P},silent]), %% a) badarg - ?line {'EXIT', {{badarg, [{outdir,outdir1}]}, _}} = + {'EXIT', {{badarg, [{outdir,outdir1}]}, _}} = (catch systools:make_tar(LatestName,[{outdir,outdir1},{path,P},silent])), %% b) absolute path - ?line {ok,_,[]} = systools:make_tar(LatestName, [{outdir,Outdir1}, - {path,P},silent]), - ?line Tar1 = filename:join(Outdir1,LatestName++".tar.gz"), - ?line true = filelib:is_file(Tar1), - ?line ok = file:delete(Tar1), + {ok,_,[]} = systools:make_tar(LatestName, [{outdir,Outdir1}, + {path,P},silent]), + Tar1 = filename:join(Outdir1,LatestName++".tar.gz"), + true = filelib:is_file(Tar1), + ok = file:delete(Tar1), %% c) relative path - ?line {ok,_,[]} = systools:make_tar(LatestName, [{outdir,"./outdir1"}, - {path,P},silent]), - ?line true = filelib:is_file(Tar1), - ?line ok = file:delete(Tar1), + {ok,_,[]} = systools:make_tar(LatestName, [{outdir,"./outdir1"}, + {path,P},silent]), + true = filelib:is_file(Tar1), + ok = file:delete(Tar1), %% d) absolute but incorrect path - ?line Tar2 = filename:join(Outdir2,LatestName++".tar.gz"), - ?line {error,_,{tar_error,{open,Tar2,{Tar2,enoent}}}} = + Tar2 = filename:join(Outdir2,LatestName++".tar.gz"), + {error,_,{tar_error,{open,Tar2,{Tar2,enoent}}}} = systools:make_tar(LatestName, [{outdir,Outdir2},{path,P},silent]), - + %% e) relative but incorrect path - ?line {error,_,{tar_error,{open,_,_}}} = - systools:make_tar(LatestName, [{outdir,"./outdir2"},{path,P},silent]), + {error,_,{tar_error,{open,_,_}}} = + systools:make_tar(LatestName, [{outdir,"./outdir2"},{path,P},silent]), %% f) with .rel in another directory than cwd - ?line ok = file:set_cwd(Outdir1), - ?line {ok,_,[]} = systools:make_tar(filename:join(PrivDir, LatestName), - [{outdir,"."},{path,P},silent]), - ?line true = filelib:is_file(Tar1), - ?line ok = file:set_cwd(LatestDir), + ok = file:set_cwd(Outdir1), + {ok,_,[]} = systools:make_tar(filename:join(PrivDir, LatestName), + [{outdir,"."},{path,P},silent]), + true = filelib:is_file(Tar1), + ok = file:set_cwd(LatestDir), %% ===== Now test systools:make_relup ===== %% a) badarg - ?line {'EXIT', {{badarg, [{outdir,outdir1}]}, _}} = + {'EXIT', {{badarg, [{outdir,outdir1}]}, _}} = (catch systools:make_relup(LatestName,[LatestName1],[LatestName1], [{outdir,outdir1}, {path,P},silent])), %% b) absolute path Relup = filename:join(Outdir1, "relup"), - ?line {ok,_,_,[]} = systools:make_relup(LatestName,[LatestName1],[LatestName1], - [{outdir,Outdir1}, - {path,P},silent]), - ?line true = filelib:is_file(Relup), - ?line ok = file:delete(Relup), - + {ok,_,_,[]} = systools:make_relup(LatestName,[LatestName1],[LatestName1], + [{outdir,Outdir1}, + {path,P},silent]), + true = filelib:is_file(Relup), + ok = file:delete(Relup), + %% c) relative path - ?line {ok,_,_,[]} = systools:make_relup(LatestName,[LatestName1],[LatestName1], - [{outdir,"./outdir1"}, - {path,P},silent]), - ?line true = filelib:is_file(Relup), - ?line ok = file:delete(Relup), - + {ok,_,_,[]} = systools:make_relup(LatestName,[LatestName1],[LatestName1], + [{outdir,"./outdir1"}, + {path,P},silent]), + true = filelib:is_file(Relup), + ok = file:delete(Relup), + %% d) absolute but incorrect path - ?line {error,_,{file_problem,{"relup",enoent}}} = + {error,_,{file_problem,{"relup",enoent}}} = systools:make_relup(LatestName,[LatestName1],[LatestName1], [{outdir,Outdir2},{path,P},silent]), - + %% e) relative but incorrect path - ?line {error,_,{file_problem,{"relup",enoent}}} = + {error,_,{file_problem,{"relup",enoent}}} = systools:make_relup(LatestName,[LatestName1],[LatestName1], [{outdir,"./outdir2"},{path,P},silent]), @@ -1513,7 +1737,7 @@ otp_6226(Config) when is_list(Config) -> %% cwd, not in the same directory as the .rel file -- %% Change back to previous working directory - ?line ok = file:set_cwd(OldDir), + ok = file:set_cwd(OldDir), ok. @@ -1536,7 +1760,7 @@ check_var_script_file(VarDirs, NoExistDirs, RelName) -> AllPaths = lists:append(lists:map(fun({path, P}) -> P; (_) -> [] end, - ListOfThings)), + ListOfThings)), case lists:filter(fun(VarDir) -> lists:member(VarDir, AllPaths) end, VarDirs) of VarDirs -> @@ -1561,7 +1785,7 @@ check_include_script(RelName, ExpectedLoad, ExpectedStart) -> [App || {apply,{application,load,[{application,App,_}]}} <- ListOfThings, App=/=kernel, App=/=stdlib], - + if ActualLoad =:= ExpectedLoad -> ok; true -> test_server:fail({bad_load_order, ActualLoad, ExpectedLoad}) end, @@ -1636,7 +1860,7 @@ check_tar_regular(PrivDir, Files, RelName) -> NotThere -> {error,{erroneous_tar_file,tar_name(RelName),NotThere}} end. - + delete_tree(Dir) -> case filelib:is_dir(Dir) of true -> @@ -1656,532 +1880,462 @@ tar_name(Name) -> Name ++ ".tar.gz". create_script(latest,Config) -> - ?line PrivDir = ?privdir, - ?line Name = fname(PrivDir, latest), - ?line Apps = application_controller:which_applications(), - ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), - ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), - ?line {ok,Fd} = file:open(Name++".rel",write), - ?line io:format(Fd, - "{release, {\"Test release 3\", \"LATEST\"}, \n" - " {erts, \"4.4\"}, \n" - " [{kernel, \"~s\"}, {stdlib, \"~s\"}, \n" - " {db, \"2.1\"}, {fe, \"3.1\"}]}.\n", - [KernelVer,StdlibVer]), - ?line ok = file:close(Fd), - {filename:dirname(Name), filename:basename(Name)}; + Apps = core_apps(current) ++ [{db,"2.1"},{fe,"3.1"}], + do_create_script(latest,Config,"4.4",Apps); create_script(latest_no_mod_vsn,Config) -> - ?line PrivDir = ?privdir, - ?line Name = fname(PrivDir, latest), - ?line Apps = application_controller:which_applications(), - ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), - ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), - ?line {ok,Fd} = file:open(Name++".rel",write), - ?line io:format(Fd, - "{release, {\"Test release 3\", \"LATESTNOMOD\"}, \n" - " {erts, \"4.4\"}, \n" - " [{kernel, \"~s\"}, {stdlib, \"~s\"}, \n" - " {db, \"3.1\"}, {fe, \"3.1\"}]}.\n", - [KernelVer,StdlibVer]), - ?line ok = file:close(Fd), - {filename:dirname(Name), filename:basename(Name)}; + Apps = core_apps(current) ++ [{db,"3.1"},{fe,"3.1"}], + do_create_script(latest_no_mod_vsn,Config,"4.4",Apps); create_script(latest0,Config) -> - ?line PrivDir = ?privdir, - ?line Name = fname(PrivDir, 'latest-1'), - ?line {ok,Fd} = file:open(Name++".rel",write), - ?line io:format(Fd, - "{release, {\"Test release 2\", \"LATEST0\"}, \n" - " {erts, \"4.4\"}, \n" - " [{kernel, \"1.0\"}, {stdlib, \"1.0\"}, \n" - " {db, \"2.1\"}, {fe, \"3.1\"}]}.\n", - []), - ?line ok = file:close(Fd), - {filename:dirname(Name), filename:basename(Name)}; + Apps = core_apps("1.0") ++ [{db,"2.1"},{fe,"3.1"}], + do_create_script(latest0,Config,"4.4",Apps); +create_script(latest0_current_erts,Config) -> + Apps = core_apps("1.0") ++ [{db,"2.1"},{fe,"3.1"}], + do_create_script(latest0_current_erts,Config,current,Apps); create_script(latest1,Config) -> - ?line PrivDir = ?privdir, - ?line Name = fname(PrivDir, latest), - ?line {ok,Fd} = file:open(Name++".rel",write), - ?line io:format(Fd, - "{release, {\"Test release 2\", \"LATEST1\"}, \n" - " {erts, \"4.4\"}, \n" - " [{kernel, \"1.0\"}, {stdlib, \"1.0\"}, \n" - " {db, \"1.0\"}, {fe, \"3.1\"}]}.\n", - []), - ?line ok = file:close(Fd), - {filename:dirname(Name), filename:basename(Name)}; + Apps = core_apps("1.0") ++ [{db,"1.0"},{fe,"3.1"}], + do_create_script(latest1,Config,"4.4",Apps); +create_script(latest1_no_sasl,Config) -> + Apps = [{kernel,"1.0"},{stdlib,"1.0"},{db,"1.0"},{fe,"3.1"}], + do_create_script(latest1_no_sasl,Config,"4.4",Apps); create_script(latest2,Config) -> - ?line PrivDir = ?privdir, - ?line Name = fname(PrivDir, 'latest-2'), - ?line {ok,Fd} = file:open(Name++".rel",write), - ?line io:format(Fd, - "{release, {\"Test release 1\", \"LATEST2\"}, \n" - " {erts, \"4.3\"}, \n" - " [{kernel, \"1.0\"}, {stdlib, \"1.0\"}, \n" - " {db, \"1.0\"}, {fe, \"2.1\"}]}.\n", - []), - ?line ok = file:close(Fd), - {filename:dirname(Name), filename:basename(Name)}; + Apps = core_apps("1.0") ++ [{db,"1.0"},{fe,"2.1"}], + do_create_script(latest2,Config,"4.3",Apps); create_script(latest_small,Config) -> - ?line PrivDir = ?privdir, - ?line Name = fname(PrivDir, 'latest-small'), - ?line {ok,Fd} = file:open(Name++".rel",write), - ?line io:format(Fd, - "{release, {\"Test release 2\", \"LATEST_SMALL\"}, \n" - " {erts, \"4.4\"}, \n" - " [{kernel, \"1.0\"}, {stdlib, \"1.0\"}, \n" - " {fe, \"3.1\"}]}.\n", - []), - ?line ok = file:close(Fd), - {filename:dirname(Name), filename:basename(Name)}; + Apps = core_apps("1.0") ++ [{fe,"3.1"}], + do_create_script(latest_small,Config,"4.4",Apps); create_script(latest_small0,Config) -> %Differs in fe vsn - ?line PrivDir = ?privdir, - ?line Name = fname(PrivDir, 'latest-small0'), - ?line {ok,Fd} = file:open(Name++".rel",write), - ?line io:format(Fd, - "{release, {\"Test release 2\", \"LATEST_SMALL0\"}, \n" - " {erts, \"4.4\"}, \n" - " [{kernel, \"1.0\"}, {stdlib, \"1.0\"}, \n" - " {fe, \"2.1\"}]}.\n", - []), - ?line ok = file:close(Fd), - {filename:dirname(Name), filename:basename(Name)}; + Apps = core_apps("1.0") ++ [{fe,"2.1"}], + do_create_script(latest_small0,Config,"4.4",Apps); create_script(latest_small1,Config) -> - ?line PrivDir = ?privdir, - ?line Name = fname(PrivDir, 'latest-small1'), - ?line {ok,Fd} = file:open(Name++".rel",write), - ?line io:format(Fd, - "{release, {\"Test release 2\", \"LATEST_SMALL1\"}, \n" - " {erts, \"4.4\"}, \n" - " [{kernel, \"1.0\"}, {stdlib, \"1.0\"}, \n" - " {fe, \"500.18.7\"}]}.\n", - []), - ?line ok = file:close(Fd), - {filename:dirname(Name), filename:basename(Name)}; + Apps = core_apps("1.0") ++ [{fe,"500.18.7"}], + do_create_script(latest_small1,Config,"4.4",Apps); +create_script(latest_small2,Config) -> + Apps = core_apps("1.0") ++ [{fe,"2.1.1"}], + do_create_script(latest_small2,Config,"4.4",Apps); create_script(latest_nokernel,Config) -> - ?line PrivDir = ?privdir, - ?line Name = fname(PrivDir, 'latest-nokernel'), - ?line {ok,Fd} = file:open(Name++".rel",write), - ?line io:format(Fd, - "{release, {\"Test release 3\", \"LATEST_NOKERNEL\"}, \n" - " {erts, \"4.4\"}, \n" - " [{db, \"2.1\"}, {fe, \"3.1\"}]}.\n", - []), - ?line ok = file:close(Fd), - {filename:dirname(Name), filename:basename(Name)}; + Apps = [{db,"2.1"},{fe,"3.1"}], + do_create_script(latest_nokernel,Config,"4.4",Apps); create_script(latest_app_start_type1,Config) -> - ?line PrivDir = ?privdir, - ?line Name = fname(PrivDir, latest_app_start_type1), - ?line ErtsVer = erlang:system_info(version), - ?line Apps = application_controller:which_applications(), - ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), - ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), - ?line {ok,Fd} = file:open(Name++".rel",write), - ?line RelfileContent = - {release,{"Test release", "1"}, - {erts,ErtsVer}, - [{kernel,KernelVer}, - {stdlib,StdlibVer}]}, - ?line io:format(Fd,"~p.~n",[RelfileContent]), - ?line ok = file:close(Fd), - {filename:dirname(Name), filename:basename(Name)}; + Apps = core_apps(current), + do_create_script(latest_app_start_type1,Config,current,Apps); create_script(latest_app_start_type2,Config) -> - ?line PrivDir = ?privdir, - ?line Name = fname(PrivDir, latest_app_start_type2), - ?line ErtsVer = erlang:system_info(version), - ?line Apps = application_controller:which_applications(), - ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), - ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), - ?line OtherApps = [{mnesia,permanent}, - {sasl,transient}, - {webtool,temporary}, - {snmp,load}, - {xmerl,none}], - ?line lists:foreach(fun({App,_}) -> application:load(App) end, - OtherApps), - ?line Loaded = application:loaded_applications(), - ?line OtherAppsRel = - lists:map(fun({App,StartType}) -> - {_,_,Ver} = lists:keyfind(App,1,Loaded), - {App,Ver,StartType} - end, - OtherApps), - ?line {ok,Fd} = file:open(Name++".rel",write), - ?line RelfileContent = - {release,{"Test release", "2"}, - {erts,ErtsVer}, - [{kernel,KernelVer}, - {stdlib,StdlibVer} | OtherAppsRel]}, - ?line io:format(Fd,"~p.~n",[RelfileContent]), - ?line ok = file:close(Fd), + OtherApps = [{mnesia,current,permanent}, + {runtime_tools,current,transient}, + {webtool,current,temporary}, + {snmp,current,load}, + {xmerl,current,none}], + Apps = core_apps(current) ++ OtherApps, + do_create_script(latest_app_start_type2,Config,current,Apps); +create_script(current_all_no_sasl,Config) -> + Apps = [{kernel,current},{stdlib,current},{db,"2.1"},{fe,"3.1"}], + do_create_script(current_all_no_sasl,Config,current,Apps); +create_script(current_all,Config) -> + Apps = core_apps(current) ++ [{db,"2.1"}], + do_create_script(current_all,Config,current,Apps); +create_script(current_all_future_erts,Config) -> + Apps = core_apps(current) ++ [{db,"2.1"},{fe,"3.1"}], + do_create_script(current_all_future_erts,Config,"99.99",Apps); +create_script(current_all_future_sasl,Config) -> + Apps = [{kernel,current},{stdlib,current},{sasl,"9.9"},{db,"2.1"},{fe,"3.1"}], + do_create_script(current_all_future_sasl,Config,current,Apps). + + +do_create_script(Id,Config,ErtsVsn,AppVsns) -> + PrivDir = ?privdir, + Name = fname(PrivDir, Id), + {ok,Fd} = file:open(Name++".rel",write), + RelfileContent = + {release,{"Test release", string:to_upper(atom_to_list(Id))}, + {erts,erts_vsn(ErtsVsn)}, + app_vsns(AppVsns)}, + io:format(Fd,"~p.~n",[RelfileContent]), + ok = file:close(Fd), {filename:dirname(Name), filename:basename(Name)}. +core_apps(Vsn) -> + [{App,Vsn} || App <- [kernel,stdlib,sasl]]. + +app_vsns(AppVsns) -> + [{App,app_vsn(App,Vsn)} || {App,Vsn} <- AppVsns] ++ + [{App,app_vsn(App,Vsn),Type} || {App,Vsn,Type} <- AppVsns]. +app_vsn(App,current) -> + application:load(App), + {ok,Vsn} = application:get_key(App,vsn), + Vsn; +app_vsn(_App,Vsn) -> + Vsn. + +erts_vsn(current) -> erlang:system_info(version); +erts_vsn(Vsn) -> Vsn. + + create_include_files(inc1, Config) -> - ?line PrivDir = ?privdir, - ?line Name = fname(PrivDir, inc1), + PrivDir = ?privdir, + Name = fname(PrivDir, inc1), create_apps(PrivDir), - ?line Apps = application_controller:which_applications(), - ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), - ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), + Apps = application_controller:which_applications(), + {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), + {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" - " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" - ++ StdlibVer ++ "\"},\n" - " {t6, \"1.0\"}, {t5, \"1.0\"}, \n" - " {t4, \"1.0\"}, {t3, \"1.0\"}, {t2, \"1.0\"}, \n" - " {t1, \"1.0\"}]}.\n", + " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" + ++ StdlibVer ++ "\"},\n" + " {t6, \"1.0\"}, {t5, \"1.0\"}, \n" + " {t4, \"1.0\"}, {t3, \"1.0\"}, {t2, \"1.0\"}, \n" + " {t1, \"1.0\"}]}.\n", file:write_file(Name ++ ".rel", list_to_binary(Rel)), {filename:dirname(Name), filename:basename(Name)}; create_include_files(inc2, Config) -> - ?line PrivDir = ?privdir, - ?line Name = fname(PrivDir, inc2), + PrivDir = ?privdir, + Name = fname(PrivDir, inc2), create_apps(PrivDir), - ?line Apps = application_controller:which_applications(), - ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), - ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), + Apps = application_controller:which_applications(), + {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), + {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), %% t6 does not include t5 ! Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" - " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" - ++ StdlibVer ++ "\"},\n" - " {t6, \"1.0\", [t4]}, {t5, \"1.0\"}, \n" - " {t4, \"1.0\"}, {t3, \"1.0\"}, {t2, \"1.0\"}, \n" - " {t1, \"1.0\"}]}.\n", + " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" + ++ StdlibVer ++ "\"},\n" + " {t6, \"1.0\", [t4]}, {t5, \"1.0\"}, \n" + " {t4, \"1.0\"}, {t3, \"1.0\"}, {t2, \"1.0\"}, \n" + " {t1, \"1.0\"}]}.\n", file:write_file(Name ++ ".rel", list_to_binary(Rel)), {filename:dirname(Name), filename:basename(Name)}; create_include_files(inc3, Config) -> - ?line PrivDir = ?privdir, - ?line Name = fname(PrivDir, inc3), + PrivDir = ?privdir, + Name = fname(PrivDir, inc3), create_apps(PrivDir), - ?line Apps = application_controller:which_applications(), - ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), - ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), + Apps = application_controller:which_applications(), + {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), + {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), %% t3 does not include t2 ! Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" - " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" - ++ StdlibVer ++ "\"},\n" - " {t6, \"1.0\"}, {t5, \"1.0\"}, \n" - " {t4, \"1.0\"}, {t3, \"1.0\", []}, {t2, \"1.0\"}, \n" - " {t1, \"1.0\"}]}.\n", + " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" + ++ StdlibVer ++ "\"},\n" + " {t6, \"1.0\"}, {t5, \"1.0\"}, \n" + " {t4, \"1.0\"}, {t3, \"1.0\", []}, {t2, \"1.0\"}, \n" + " {t1, \"1.0\"}]}.\n", file:write_file(Name ++ ".rel", list_to_binary(Rel)), {filename:dirname(Name), filename:basename(Name)}; create_include_files(inc4, Config) -> - ?line PrivDir = ?privdir, - ?line Name = fname(PrivDir, inc4), + PrivDir = ?privdir, + Name = fname(PrivDir, inc4), create_apps(PrivDir), - ?line Apps = application_controller:which_applications(), - ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), - ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), + Apps = application_controller:which_applications(), + {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), + {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), %% t3 does not include t2 ! %% t6 does not include t5 ! Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" - " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" - ++ StdlibVer ++ "\"},\n" - " {t6, \"1.0\", [t4]}, {t5, \"1.0\"}, \n" - " {t4, \"1.0\"}, {t3, \"1.0\", []}, {t2, \"1.0\"}, \n" - " {t1, \"1.0\"}]}.\n", + " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" + ++ StdlibVer ++ "\"},\n" + " {t6, \"1.0\", [t4]}, {t5, \"1.0\"}, \n" + " {t4, \"1.0\"}, {t3, \"1.0\", []}, {t2, \"1.0\"}, \n" + " {t1, \"1.0\"}]}.\n", file:write_file(Name ++ ".rel", list_to_binary(Rel)), {filename:dirname(Name), filename:basename(Name)}; create_include_files(inc5, Config) -> - ?line PrivDir = ?privdir, - ?line Name = fname(PrivDir, inc5), + PrivDir = ?privdir, + Name = fname(PrivDir, inc5), create_apps(PrivDir), - ?line Apps = application_controller:which_applications(), - ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), - ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), + Apps = application_controller:which_applications(), + {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), + {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), %% t6 does not include t5 ! %% exclude t5. Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" - " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" - ++ StdlibVer ++ "\"},\n" - " {t6, \"1.0\", [t4]}, \n" - " {t4, \"1.0\"}, {t3, \"1.0\", []}, {t2, \"1.0\"}, \n" - " {t1, \"1.0\"}]}.\n", + " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" + ++ StdlibVer ++ "\"},\n" + " {t6, \"1.0\", [t4]}, \n" + " {t4, \"1.0\"}, {t3, \"1.0\", []}, {t2, \"1.0\"}, \n" + " {t1, \"1.0\"}]}.\n", file:write_file(Name ++ ".rel", list_to_binary(Rel)), {filename:dirname(Name), filename:basename(Name)}; create_include_files(inc6, Config) -> - ?line PrivDir = ?privdir, - ?line Name = fname(PrivDir, inc6), + PrivDir = ?privdir, + Name = fname(PrivDir, inc6), create_apps(PrivDir), - ?line Apps = application_controller:which_applications(), - ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), - ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), + Apps = application_controller:which_applications(), + {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), + {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), %% t3 does include non existing t2 ! Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" - " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" - ++ StdlibVer ++ "\"},\n" - " {t6, \"1.0\"}, {t5, \"1.0\"}, \n" - " {t4, \"1.0\"}, {t3, \"1.0\"}, \n" - " {t1, \"1.0\"}]}.\n", + " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" + ++ StdlibVer ++ "\"},\n" + " {t6, \"1.0\"}, {t5, \"1.0\"}, \n" + " {t4, \"1.0\"}, {t3, \"1.0\"}, \n" + " {t1, \"1.0\"}]}.\n", file:write_file(Name ++ ".rel", list_to_binary(Rel)), {filename:dirname(Name), filename:basename(Name)}; create_include_files(inc7, Config) -> - ?line PrivDir = ?privdir, - ?line Name = fname(PrivDir, inc7), + PrivDir = ?privdir, + Name = fname(PrivDir, inc7), create_apps(PrivDir), create_app(t7, PrivDir), - ?line Apps = application_controller:which_applications(), - ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), - ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), + Apps = application_controller:which_applications(), + {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), + {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), %% t7 and t6 does include t5 ! Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" - " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" - ++ StdlibVer ++ "\"},\n" - " {t7, \"1.0\"}, {t6, \"1.0\"}, {t5, \"1.0\"}, \n" - " {t4, \"1.0\"}, {t3, \"1.0\"}, {t2, \"1.0\"}, \n" - " {t1, \"1.0\"}]}.\n", + " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" + ++ StdlibVer ++ "\"},\n" + " {t7, \"1.0\"}, {t6, \"1.0\"}, {t5, \"1.0\"}, \n" + " {t4, \"1.0\"}, {t3, \"1.0\"}, {t2, \"1.0\"}, \n" + " {t1, \"1.0\"}]}.\n", file:write_file(Name ++ ".rel", list_to_binary(Rel)), {filename:dirname(Name), filename:basename(Name)}; create_include_files(inc8, Config) -> - ?line PrivDir = ?privdir, - ?line Name = fname(PrivDir, inc8), + PrivDir = ?privdir, + Name = fname(PrivDir, inc8), create_circular_apps(PrivDir), - ?line Apps = application_controller:which_applications(), - ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), - ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), + Apps = application_controller:which_applications(), + {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), + {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), %% t8 uses t9 and t10 includes t9 ! Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" - " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" - ++ StdlibVer ++ "\"},\n" - " {t8, \"1.0\"}, {t9, \"1.0\"}, {t10, \"1.0\"}]}.\n", + " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" + ++ StdlibVer ++ "\"},\n" + " {t8, \"1.0\"}, {t9, \"1.0\"}, {t10, \"1.0\"}]}.\n", file:write_file(Name ++ ".rel", list_to_binary(Rel)), {filename:dirname(Name), filename:basename(Name)}; create_include_files(inc9, Config) -> - ?line PrivDir = ?privdir, - ?line Name = fname(PrivDir, inc9), + PrivDir = ?privdir, + Name = fname(PrivDir, inc9), create_circular_apps(PrivDir), - ?line Apps = application_controller:which_applications(), - ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), - ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), + Apps = application_controller:which_applications(), + {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), + {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), %% t8 uses t9, t9 uses t10 and t10 includes t8 ==> circular !! Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" - " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" - ++ StdlibVer ++ "\"},\n" - " {t8, \"1.0\"}, {t9, \"1.0\"}, {t10, \"1.0\", [t8]}]}.\n", + " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" + ++ StdlibVer ++ "\"},\n" + " {t8, \"1.0\"}, {t9, \"1.0\"}, {t10, \"1.0\", [t8]}]}.\n", file:write_file(Name ++ ".rel", list_to_binary(Rel)), {filename:dirname(Name), filename:basename(Name)}; create_include_files(inc10, Config) -> - ?line PrivDir = ?privdir, - ?line Name = fname(PrivDir, inc10), + PrivDir = ?privdir, + Name = fname(PrivDir, inc10), create_circular_apps(PrivDir), - ?line Apps = application_controller:which_applications(), - ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), - ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), + Apps = application_controller:which_applications(), + {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), + {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), %% t9 tries to include not specified (in .app file) application ! Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" - " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" - ++ StdlibVer ++ "\"},\n" - " {t8, \"1.0\"}, {t9, \"1.0\", [t7]}, {t10, \"1.0\"}]}.\n", + " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" + ++ StdlibVer ++ "\"},\n" + " {t8, \"1.0\"}, {t9, \"1.0\", [t7]}, {t10, \"1.0\"}]}.\n", file:write_file(Name ++ ".rel", list_to_binary(Rel)), {filename:dirname(Name), filename:basename(Name)}; create_include_files(inc11, Config) -> - ?line PrivDir = ?privdir, - ?line Name = fname(PrivDir, inc11), + PrivDir = ?privdir, + Name = fname(PrivDir, inc11), create_apps2(PrivDir), - ?line Apps = application_controller:which_applications(), - ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), - ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), + Apps = application_controller:which_applications(), + {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), + {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" - " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" - ++ StdlibVer ++ "\"},\n" - " {t11, \"1.0\"}, \n" - " {t12, \"1.0\"}, \n" - " {t13, \"1.0\"}]}.\n", + " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" + ++ StdlibVer ++ "\"},\n" + " {t11, \"1.0\"}, \n" + " {t12, \"1.0\"}, \n" + " {t13, \"1.0\"}]}.\n", file:write_file(Name ++ ".rel", list_to_binary(Rel)), {filename:dirname(Name), filename:basename(Name)}; -create_include_files(otp_3065, Config) -> - ?line PrivDir = ?privdir, - ?line Name = fname(PrivDir, otp_3065), +create_include_files(otp_3065_circular_dependenies, Config) -> + PrivDir = ?privdir, + Name = fname(PrivDir, otp_3065_circular_dependenies), create_apps_3065(PrivDir), - ?line Apps = application_controller:which_applications(), - ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), - ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), + Apps = application_controller:which_applications(), + {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), + {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" - " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" - ++ StdlibVer ++ "\"},\n" - " {chAts, \"1.0\"}, {aa12, \"1.0\"}, \n" - " {chTraffic, \"1.0\"}]}.\n", + " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" + ++ StdlibVer ++ "\"},\n" + " {chAts, \"1.0\"}, {aa12, \"1.0\"}, \n" + " {chTraffic, \"1.0\"}]}.\n", file:write_file(Name ++ ".rel", list_to_binary(Rel)), {filename:dirname(Name), filename:basename(Name)}. create_apps(Dir) -> T1 = "{application, t1,\n" - " [{vsn, \"1.0\"},\n" - " {description, \"test\"},\n" - " {modules, []},\n" - " {applications, [kernel, stdlib]},\n" - " {registered, []}]}.\n", + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, [kernel, stdlib]},\n" + " {registered, []}]}.\n", file:write_file(fname(Dir, 't1.app'), list_to_binary(T1)), T2 = "{application, t2,\n" - " [{vsn, \"1.0\"},\n" - " {description, \"test\"},\n" - " {modules, []},\n" - " {applications, [t1]},\n" - " {registered, []}]}.\n", + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, [t1]},\n" + " {registered, []}]}.\n", file:write_file(fname(Dir, 't2.app'), list_to_binary(T2)), T3 = "{application, t3,\n" - " [{vsn, \"1.0\"},\n" - " {description, \"test\"},\n" - " {modules, []},\n" - " {applications, []},\n" - " {included_applications, [t2]},\n" - " {registered, []}]}.\n", + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, []},\n" + " {included_applications, [t2]},\n" + " {registered, []}]}.\n", file:write_file(fname(Dir, 't3.app'), list_to_binary(T3)), T4 = "{application, t4,\n" - " [{vsn, \"1.0\"},\n" - " {description, \"test\"},\n" - " {modules, []},\n" - " {applications, [t3]},\n" - " {included_applications, []},\n" - " {registered, []}]}.\n", + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, [t3]},\n" + " {included_applications, []},\n" + " {registered, []}]}.\n", file:write_file(fname(Dir, 't4.app'), list_to_binary(T4)), T5 = "{application, t5,\n" - " [{vsn, \"1.0\"},\n" - " {description, \"test\"},\n" - " {modules, []},\n" - " {applications, [t3]},\n" - " {included_applications, []},\n" - " {registered, []}]}.\n", + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, [t3]},\n" + " {included_applications, []},\n" + " {registered, []}]}.\n", file:write_file(fname(Dir, 't5.app'), list_to_binary(T5)), T6 = "{application, t6,\n" - " [{vsn, \"1.0\"},\n" - " {description, \"test\"},\n" - " {modules, []},\n" - " {applications, []},\n" - " {included_applications, [t4, t5]},\n" - " {registered, []}]}.\n", + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, []},\n" + " {included_applications, [t4, t5]},\n" + " {registered, []}]}.\n", file:write_file(fname(Dir, 't6.app'), list_to_binary(T6)). create_app(t7, Dir) -> T7 = "{application, t7,\n" - " [{vsn, \"1.0\"},\n" - " {description, \"test\"},\n" - " {modules, []},\n" - " {applications, []},\n" - " {included_applications, [t5]},\n" - " {registered, []}]}.\n", + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, []},\n" + " {included_applications, [t5]},\n" + " {registered, []}]}.\n", file:write_file(fname(Dir, 't7.app'), list_to_binary(T7)). create_circular_apps(Dir) -> T8 = "{application, t8,\n" - " [{vsn, \"1.0\"},\n" - " {description, \"test\"},\n" - " {modules, []},\n" - " {applications, [t9]},\n" - " {included_applications, []},\n" - " {registered, []}]}.\n", + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, [t9]},\n" + " {included_applications, []},\n" + " {registered, []}]}.\n", file:write_file(fname(Dir, 't8.app'), list_to_binary(T8)), T9 = "{application, t9,\n" - " [{vsn, \"1.0\"},\n" - " {description, \"test\"},\n" - " {modules, []},\n" - " {applications, [t10]},\n" - " {included_applications, []},\n" - " {registered, []}]}.\n", + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, [t10]},\n" + " {included_applications, []},\n" + " {registered, []}]}.\n", file:write_file(fname(Dir, 't9.app'), list_to_binary(T9)), T10 = "{application, t10,\n" - " [{vsn, \"1.0\"},\n" - " {description, \"test\"},\n" - " {modules, []},\n" - " {applications, []},\n" - " {included_applications, [t8, t9]},\n" - " {registered, []}]}.\n", + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, []},\n" + " {included_applications, [t8, t9]},\n" + " {registered, []}]}.\n", file:write_file(fname(Dir, 't10.app'), list_to_binary(T10)). create_apps2(Dir) -> T11 = "{application, t11,\n" - " [{vsn, \"1.0\"},\n" - " {description, \"test\"},\n" - " {modules, []},\n" - " {applications, []},\n" - " {included_applications, [t13]},\n" - " {registered, []}]}.\n", + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, []},\n" + " {included_applications, [t13]},\n" + " {registered, []}]}.\n", file:write_file(fname(Dir, 't11.app'), list_to_binary(T11)), T12 = "{application, t12,\n" - " [{vsn, \"1.0\"},\n" - " {description, \"test\"},\n" - " {modules, []},\n" - " {applications, [t11]},\n" - " {registered, []}]}.\n", + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, [t11]},\n" + " {registered, []}]}.\n", file:write_file(fname(Dir, 't12.app'), list_to_binary(T12)), T13 = "{application, t13,\n" - " [{vsn, \"1.0\"},\n" - " {description, \"test\"},\n" - " {modules, []},\n" - " {applications, []},\n" - " {included_applications, []},\n" - " {registered, []}]}.\n", + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, []},\n" + " {included_applications, []},\n" + " {registered, []}]}.\n", file:write_file(fname(Dir, 't13.app'), list_to_binary(T13)). create_apps_3065(Dir) -> T11 = "{application, chTraffic,\n" - " [{vsn, \"1.0\"},\n" - " {description, \"test\"},\n" - " {modules, []},\n" - " {applications, []},\n" - " {included_applications, [chAts]},\n" - " {registered, []}]}.\n", + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, []},\n" + " {included_applications, [chAts]},\n" + " {registered, []}]}.\n", file:write_file(fname(Dir, 'chTraffic.app'), list_to_binary(T11)), T12 = "{application, chAts,\n" - " [{vsn, \"1.0\"},\n" - " {description, \"test\"},\n" - " {modules, []},\n" - " {applications, []},\n" - " {included_applications, [aa12]},\n" - " {registered, []}]}.\n", + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, []},\n" + " {included_applications, [aa12]},\n" + " {registered, []}]}.\n", file:write_file(fname(Dir, 'chAts.app'), list_to_binary(T12)), T13 = "{application, aa12,\n" - " [{vsn, \"1.0\"},\n" - " {description, \"test\"},\n" - " {modules, []},\n" - " {applications, [chAts]},\n" - " {included_applications, []},\n" - " {registered, []}]}.\n", + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, [chAts]},\n" + " {included_applications, []},\n" + " {registered, []}]}.\n", file:write_file(fname(Dir, 'aa12.app'), list_to_binary(T13)). fname(N) -> diff --git a/lib/sasl/test/systools_SUITE_data/d_bad_appup/lib/fe-2.1/ebin/fe.app b/lib/sasl/test/systools_SUITE_data/d_bad_appup/lib/fe-2.1/ebin/fe.app new file mode 100644 index 0000000000..3cb0b0c2cf --- /dev/null +++ b/lib/sasl/test/systools_SUITE_data/d_bad_appup/lib/fe-2.1/ebin/fe.app @@ -0,0 +1,7 @@ +{application, fe, + [{description, "ERICSSON NR FOR FE"}, + {vsn, "2.1"}, + {modules, [{fe1, "1.0"}, {fe2, "1.0"}, {fe3, "2.0"}]}, + {registered, []}, + {applications, []}, + {mod, {fe1, []}}]}. diff --git a/lib/sasl/test/systools_SUITE_data/d_no_appup/lib/fe-500.18.7/ebin/fe.app b/lib/sasl/test/systools_SUITE_data/d_no_appup/lib/fe-500.18.7/ebin/fe.app new file mode 100644 index 0000000000..3a5c0ddd9b --- /dev/null +++ b/lib/sasl/test/systools_SUITE_data/d_no_appup/lib/fe-500.18.7/ebin/fe.app @@ -0,0 +1,7 @@ +{application, fe, + [{description, "ERICSSON NR FOR FE"}, + {vsn, "500.18.7"}, + {modules, [{fe1, "1.0"}, {fe2, "1.0"}, {fe3, "2.0"}]}, + {registered, []}, + {applications, []}, + {mod, {fe1, []}}]}. diff --git a/lib/sasl/test/systools_SUITE_data/d_regexp_appup/lib/fe-2.1.1/ebin/fe.app b/lib/sasl/test/systools_SUITE_data/d_regexp_appup/lib/fe-2.1.1/ebin/fe.app new file mode 100644 index 0000000000..c7ba1dfe91 --- /dev/null +++ b/lib/sasl/test/systools_SUITE_data/d_regexp_appup/lib/fe-2.1.1/ebin/fe.app @@ -0,0 +1,8 @@ +{application, fe, + [{description, "ERICSSON NR FOR FE"}, + {vsn, "2.1.1"}, + {modules, [{fe1, "1.0"}, {fe2, "1.0"}, {fe3, "2.0"}]}, + {registered, []}, + {applications, []}, + {env, []}, + {start, {fe2, start, []}}]}. diff --git a/lib/sasl/test/systools_SUITE_data/d_regexp_appup/lib/fe-2.1/ebin/fe.app b/lib/sasl/test/systools_SUITE_data/d_regexp_appup/lib/fe-2.1/ebin/fe.app new file mode 100644 index 0000000000..47ea248720 --- /dev/null +++ b/lib/sasl/test/systools_SUITE_data/d_regexp_appup/lib/fe-2.1/ebin/fe.app @@ -0,0 +1,8 @@ +{application, fe, + [{description, "ERICSSON NR FOR FE"}, + {vsn, "2.1"}, + {modules, [{fe1, "1.0"}, {fe2, "1.0"}, {fe3, "2.0"}]}, + {registered, []}, + {applications, []}, + {env, []}, + {start, {fe2, start, []}}]}. diff --git a/lib/sasl/test/systools_SUITE_data/d_regexp_appup/lib/fe-3.1/ebin/fe.app b/lib/sasl/test/systools_SUITE_data/d_regexp_appup/lib/fe-3.1/ebin/fe.app new file mode 100644 index 0000000000..0696e2494c --- /dev/null +++ b/lib/sasl/test/systools_SUITE_data/d_regexp_appup/lib/fe-3.1/ebin/fe.app @@ -0,0 +1,7 @@ +{application, fe, + [{description, "ERICSSON NR FOR FE"}, + {vsn, "3.1"}, + {modules, [{fe1, "1.0"}, {fe2, "1.0"}, {fe3, "2.0"}]}, + {registered, []}, + {applications, []}, + {mod, {fe1, []}}]}. diff --git a/lib/sasl/test/systools_SUITE_data/d_regexp_appup/lib/fe-3.1/ebin/fe.appup b/lib/sasl/test/systools_SUITE_data/d_regexp_appup/lib/fe-3.1/ebin/fe.appup new file mode 100644 index 0000000000..6b99c47e53 --- /dev/null +++ b/lib/sasl/test/systools_SUITE_data/d_regexp_appup/lib/fe-3.1/ebin/fe.appup @@ -0,0 +1,28 @@ +%% -*- erlang -*- +%% Release upgrade script for fe (front end) +%% + +{ + "3.1", + %% Upgrade from: + [ + {<<"2\\.[0-9]+">>, % matches 2.X in full length and 2.X.Y... only partly + [{update, fe1, soft, soft_purge, soft_purge, []}, + {update, fe2, soft, soft_purge, soft_purge, [fe1]}, + {update, fe3, {advanced, extra}, soft_purge, soft_purge, [fe1, fe2]} + ]}, + {<<"2(\\.[0-9]+)+">>, % matches 2.X.Y... in full length + [{update, fe1, soft, soft_purge, soft_purge, []}, + {update, fe2, soft, soft_purge, soft_purge, [fe1]}, + {update, fe3, {advanced, extra}, soft_purge, soft_purge,[fe1, fe2]}, + restart_emulator]} + ], + + %% Downgrade to: + [ + {<<"2\\.[0-9]+">>, % matches 2.X in full length and 2.X.Y... only partly + [{update, fe2, soft, soft_purge, soft_purge, []}, + {update, fe3, {advanced, extra}, soft_purge, soft_purge, [fe2]} + ]} + ] +}. diff --git a/lib/sasl/test/systools_SUITE_data/lib/sasl-9.9/ebin/sasl.app b/lib/sasl/test/systools_SUITE_data/lib/sasl-9.9/ebin/sasl.app new file mode 100644 index 0000000000..3bcc1a4619 --- /dev/null +++ b/lib/sasl/test/systools_SUITE_data/lib/sasl-9.9/ebin/sasl.app @@ -0,0 +1,6 @@ +{application, sasl, + [{description, "FAKE FUTURE SASL"}, + {vsn, "9.9"}, + {modules, []}, + {registered, []}, + {applications, []}]}. diff --git a/lib/sasl/test/systools_SUITE_data/lib/sasl-9.9/ebin/sasl.appup b/lib/sasl/test/systools_SUITE_data/lib/sasl-9.9/ebin/sasl.appup new file mode 100644 index 0000000000..cff0c69b6e --- /dev/null +++ b/lib/sasl/test/systools_SUITE_data/lib/sasl-9.9/ebin/sasl.appup @@ -0,0 +1,12 @@ +%% +%% Fake release upgrade script for sasl +%% + +{ + "9.9", + [{<<".+">>,[restart_new_emulator]} + ], + + [{<<".+">>,[restart_new_emulator]} + ] +}. diff --git a/lib/sasl/test/systools_SUITE_data/lib/sasl/ebin/sasl.app b/lib/sasl/test/systools_SUITE_data/lib/sasl/ebin/sasl.app new file mode 100644 index 0000000000..aaeb37fa4d --- /dev/null +++ b/lib/sasl/test/systools_SUITE_data/lib/sasl/ebin/sasl.app @@ -0,0 +1,6 @@ +{application, sasl, + [{description, "FAKE SASL"}, + {vsn, "1.0"}, + {modules, []}, + {registered, []}, + {applications, []}]}. diff --git a/lib/sasl/test/systools_SUITE_data/lib/sasl/ebin/sasl.appup b/lib/sasl/test/systools_SUITE_data/lib/sasl/ebin/sasl.appup new file mode 100644 index 0000000000..796a1e7368 --- /dev/null +++ b/lib/sasl/test/systools_SUITE_data/lib/sasl/ebin/sasl.appup @@ -0,0 +1,12 @@ +%% +%% Fake release upgrade script for sasl +%% + +{ + "1.0", + [ + ], + + [ + ] +}. diff --git a/lib/sasl/test/systools_rc_SUITE.erl b/lib/sasl/test/systools_rc_SUITE.erl index bb93f38fa7..bd4aa9e7a7 100644 --- a/lib/sasl/test/systools_rc_SUITE.erl +++ b/lib/sasl/test/systools_rc_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010. All Rights Reserved. +%% Copyright Ericsson AB 2010-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -18,17 +18,18 @@ %% -module(systools_rc_SUITE). --include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). -include_lib("sasl/src/systools.hrl"). -export([all/0,groups/0,init_per_group/2,end_per_group/2, - syntax_check/1, translate/1, translate_app/1]). + syntax_check/1, translate/1, translate_app/1, + translate_emulator_restarts/1]). %%----------------------------------------------------------------- %% erl -compile systools_rc_SUITE @i ../src/ @i ../../test_server/include/ %% c(systools_rc_SUITE, [{i, "../src"}, {i, "../../test_server/include"}]). %%----------------------------------------------------------------- all() -> - [syntax_check, translate, translate_app]. + [syntax_check, translate, translate_app, translate_emulator_restarts]. groups() -> []. @@ -40,7 +41,6 @@ end_per_group(_GroupName, Config) -> Config. -syntax_check(suite) -> []; syntax_check(Config) when is_list(Config) -> PreApps = [#application{name = test, @@ -68,8 +68,8 @@ syntax_check(Config) when is_list(Config) -> {update, baz, 5000, soft, brutal_purge, brutal_purge, []}, {add_module, new_mod}, {remove_application, snmp} - ], - ?line {ok, _} = systools_rc:translate_scripts([S1], Apps, PreApps), + ], + {ok, _} = systools_rc:translate_scripts([S1], Apps, PreApps), S2 = [ {apply, {m, f, [a]}}, {load_object_code, {tst, "1.0", [new_mod]}}, @@ -87,42 +87,42 @@ syntax_check(Config) when is_list(Config) -> {sync_nodes, id1, {m, f, [a]}}, {sync_nodes, id2, [cp1, cp2]}, {apply, {m,f,[a]}}, - restart_new_emulator - ], - ?line {ok, _} = systools_rc:translate_scripts([S2], Apps, []), + restart_new_emulator, + restart_emulator + ], + {ok, _} = systools_rc:translate_scripts([S2], Apps, []), S3 = [{apply, {m, f, a}}], - ?line {error, _, _} = systools_rc:translate_scripts([S3], Apps, []), + {error, _, _} = systools_rc:translate_scripts([S3], Apps, []), S3_1 = [{apply, {m, 3, a}}], - ?line {error, _, _} = systools_rc:translate_scripts([S3_1], Apps, []), + {error, _, _} = systools_rc:translate_scripts([S3_1], Apps, []), S4 = [{apply, {m, f}}], - ?line {error, _, _} = systools_rc:translate_scripts([S4], Apps, []), + {error, _, _} = systools_rc:translate_scripts([S4], Apps, []), S5 = [{load_object_code, hej}], - ?line {error, _, _} = systools_rc:translate_scripts([S5], Apps, []), + {error, _, _} = systools_rc:translate_scripts([S5], Apps, []), S6 = [{load_object_code, {342, "1.0", [foo]}}], - ?line {error, _, _} = systools_rc:translate_scripts([S6], Apps, []), + {error, _, _} = systools_rc:translate_scripts([S6], Apps, []), S7 = [{load_object_code, {tets, "1.0", foo}}], - ?line {error, _, _} = systools_rc:translate_scripts([S7], Apps, []), + {error, _, _} = systools_rc:translate_scripts([S7], Apps, []), S8 = [{suspend, [m1]}, point_of_no_return], - ?line {error, _, _} = systools_rc:translate_scripts([S8], Apps, []), + {error, _, _} = systools_rc:translate_scripts([S8], Apps, []), S9 = [{update, ba, {advanced, extra}, brutal_purge, brutal_purge, []}], - ?line {error, _, _} = systools_rc:translate_scripts([S9], Apps, []), + {error, _, _} = systools_rc:translate_scripts([S9], Apps, []), S10 = [{update, bar, {advanced, extra}, brutal_purge, brutal_purge, [baz]}], - ?line {error, _, _} = systools_rc:translate_scripts([S10], Apps, []), + {error, _, _} = systools_rc:translate_scripts([S10], Apps, []), S11 = [{update, bar, {advanced, extra}, brutal_purge, brutal_purge, [ba]}], - ?line {error, _, _} = systools_rc:translate_scripts([S11], Apps, []), + {error, _, _} = systools_rc:translate_scripts([S11], Apps, []), S12 = [{update, bar, advanced, brutal_purge, brutal_purge, []}], - ?line {error, _, _} = systools_rc:translate_scripts([S12], Apps, []), + {error, _, _} = systools_rc:translate_scripts([S12], Apps, []), S13 = [{update, bar, {advanced, extra}, rutal_purge, brutal_purge, [ba]}], - ?line {error, _, _} = systools_rc:translate_scripts([S13], Apps, []), + {error, _, _} = systools_rc:translate_scripts([S13], Apps, []), S14 = [{update, bar, {advanced, extra}, brutal_purge, rutal_purge, [ba]}], - ?line {error, _, _} = systools_rc:translate_scripts([S14], Apps, []), + {error, _, _} = systools_rc:translate_scripts([S14], Apps, []), S15 = [{update, bar, {advanced, extra}, brutal_purge, brutal_purge, ba}], - ?line {error, _, _} = systools_rc:translate_scripts([S15], Apps, []), + {error, _, _} = systools_rc:translate_scripts([S15], Apps, []), S16 = [{code_change, [module]}], - ?line {error, _, _} = systools_rc:translate_scripts([S16], Apps, []), - ?line ok. + {error, _, _} = systools_rc:translate_scripts([S16], Apps, []), + ok. -translate(suite) -> []; translate(Config) when is_list(Config) -> Apps = [#application{name = test, @@ -134,170 +134,170 @@ translate(Config) when is_list(Config) -> mod = {sasl, []}}], %% Simple translation (1) Up1 = [{update, foo, soft, soft_purge, soft_purge, []}], - ?line {ok, X1} = systools_rc:translate_scripts([Up1], Apps, []), - ?line [{load_object_code, {test,"1.0",[foo]}}, - point_of_no_return, - {suspend,[foo]}, - {load,{foo,soft_purge,soft_purge}}, - {resume,[foo]}] = X1, + {ok, X1} = systools_rc:translate_scripts([Up1], Apps, []), + [{load_object_code, {test,"1.0",[foo]}}, + point_of_no_return, + {suspend,[foo]}, + {load,{foo,soft_purge,soft_purge}}, + {resume,[foo]}] = X1, %% Simple translation (2) Up2 = [{update, foo, {advanced, extra}, soft_purge, soft_purge, []}], - ?line {ok, X2} = systools_rc:translate_scripts([Up2], Apps, []), - ?line [{load_object_code, {test,"1.0",[foo]}}, - point_of_no_return, - {suspend,[foo]}, - {load,{foo,soft_purge,soft_purge}}, - {code_change, up, [{foo, extra}]}, - {resume,[foo]}] = X2, - - ?line {ok, X22} = systools_rc:translate_scripts(dn,[Up2], Apps, []), - ?line [{load_object_code, {test,"1.0",[foo]}}, - point_of_no_return, - {suspend,[foo]}, - {code_change, down, [{foo, extra}]}, - {load,{foo,soft_purge,soft_purge}}, - {resume,[foo]}] = X22, + {ok, X2} = systools_rc:translate_scripts([Up2], Apps, []), + [{load_object_code, {test,"1.0",[foo]}}, + point_of_no_return, + {suspend,[foo]}, + {load,{foo,soft_purge,soft_purge}}, + {code_change, up, [{foo, extra}]}, + {resume,[foo]}] = X2, + + {ok, X22} = systools_rc:translate_scripts(dn,[Up2], Apps, []), + [{load_object_code, {test,"1.0",[foo]}}, + point_of_no_return, + {suspend,[foo]}, + {code_change, down, [{foo, extra}]}, + {load,{foo,soft_purge,soft_purge}}, + {resume,[foo]}] = X22, Up2a = [{update, foo, static, default, {advanced,extra}, soft_purge, soft_purge, []}], - ?line {ok, X2a} = systools_rc:translate_scripts([Up2a], Apps, []), - ?line [{load_object_code, {test,"1.0",[foo]}}, - point_of_no_return, - {suspend,[foo]}, - {load,{foo,soft_purge,soft_purge}}, - {code_change, up, [{foo, extra}]}, - {resume,[foo]}] = X2a, - - ?line {ok, X22a} = systools_rc:translate_scripts(dn,[Up2a], Apps, []), - ?line [{load_object_code, {test,"1.0",[foo]}}, - point_of_no_return, - {suspend,[foo]}, - {load,{foo,soft_purge,soft_purge}}, - {code_change, down, [{foo, extra}]}, - {resume,[foo]}] = X22a, + {ok, X2a} = systools_rc:translate_scripts([Up2a], Apps, []), + [{load_object_code, {test,"1.0",[foo]}}, + point_of_no_return, + {suspend,[foo]}, + {load,{foo,soft_purge,soft_purge}}, + {code_change, up, [{foo, extra}]}, + {resume,[foo]}] = X2a, + + {ok, X22a} = systools_rc:translate_scripts(dn,[Up2a], Apps, []), + [{load_object_code, {test,"1.0",[foo]}}, + point_of_no_return, + {suspend,[foo]}, + {load,{foo,soft_purge,soft_purge}}, + {code_change, down, [{foo, extra}]}, + {resume,[foo]}] = X22a, %% Simple dependency (1) Up3 = [{update, foo, soft, soft_purge, soft_purge, [bar]}, {update, bar, soft, soft_purge, soft_purge, []}], - ?line {ok, X31} = systools_rc:translate_scripts([Up3], Apps, []), - ?line [{load_object_code,{test,"1.0",[foo,bar]}}, - point_of_no_return, - {suspend,[foo,bar]}, - {load,{bar,soft_purge,soft_purge}}, - {load,{foo,soft_purge,soft_purge}}, - {resume,[bar,foo]}] = X31, - ?line {ok, X32} = systools_rc:translate_scripts(dn,[Up3], Apps, []), - ?line [{load_object_code,{test,"1.0",[foo,bar]}}, - point_of_no_return, - {suspend,[foo,bar]}, - {load,{foo,soft_purge,soft_purge}}, - {load,{bar,soft_purge,soft_purge}}, - {resume,[bar,foo]}] = X32, + {ok, X31} = systools_rc:translate_scripts([Up3], Apps, []), + [{load_object_code,{test,"1.0",[foo,bar]}}, + point_of_no_return, + {suspend,[foo,bar]}, + {load,{bar,soft_purge,soft_purge}}, + {load,{foo,soft_purge,soft_purge}}, + {resume,[bar,foo]}] = X31, + {ok, X32} = systools_rc:translate_scripts(dn,[Up3], Apps, []), + [{load_object_code,{test,"1.0",[foo,bar]}}, + point_of_no_return, + {suspend,[foo,bar]}, + {load,{foo,soft_purge,soft_purge}}, + {load,{bar,soft_purge,soft_purge}}, + {resume,[bar,foo]}] = X32, Up3a = [{update, foo, static, default, soft, soft_purge, soft_purge, [bar]}, {update, bar, static, default, soft, soft_purge, soft_purge, []}], - ?line {ok, X3a1} = systools_rc:translate_scripts([Up3a], Apps, []), - ?line [{load_object_code,{test,"1.0",[foo,bar]}}, - point_of_no_return, - {suspend,[foo, bar]}, - {load,{bar,soft_purge,soft_purge}}, - {load,{foo,soft_purge,soft_purge}}, - {resume,[bar,foo]}] = X3a1, - ?line {ok, X3a2} = systools_rc:translate_scripts(dn,[Up3a], Apps, []), - ?line [{load_object_code,{test,"1.0",[foo,bar]}}, - point_of_no_return, - {suspend,[foo,bar]}, - {load,{foo,soft_purge,soft_purge}}, - {load,{bar,soft_purge,soft_purge}}, - {resume,[bar,foo]}] = X3a2, + {ok, X3a1} = systools_rc:translate_scripts([Up3a], Apps, []), + [{load_object_code,{test,"1.0",[foo,bar]}}, + point_of_no_return, + {suspend,[foo, bar]}, + {load,{bar,soft_purge,soft_purge}}, + {load,{foo,soft_purge,soft_purge}}, + {resume,[bar,foo]}] = X3a1, + {ok, X3a2} = systools_rc:translate_scripts(dn,[Up3a], Apps, []), + [{load_object_code,{test,"1.0",[foo,bar]}}, + point_of_no_return, + {suspend,[foo,bar]}, + {load,{foo,soft_purge,soft_purge}}, + {load,{bar,soft_purge,soft_purge}}, + {resume,[bar,foo]}] = X3a2, %% Simple dependency (2) Up4 = [{update, foo, soft, soft_purge, soft_purge, [bar]}, {update, bar, {advanced, []}, soft_purge, soft_purge, []}], - ?line {ok, X4} = systools_rc:translate_scripts(up,[Up4], Apps, []), - ?line [{load_object_code,{test,"1.0",[foo,bar]}}, - point_of_no_return, - {suspend,[foo,bar]}, - {load,{bar,soft_purge,soft_purge}}, - {load,{foo,soft_purge,soft_purge}}, - {code_change,up,[{bar,[]}]}, - {resume,[bar,foo]}] = X4, - - ?line {ok, X42} = systools_rc:translate_scripts(dn,[Up4], Apps, []), - ?line [{load_object_code,{test,"1.0",[foo,bar]}}, - point_of_no_return, - {suspend,[foo,bar]}, - {code_change,down,[{bar,[]}]}, - {load,{foo,soft_purge,soft_purge}}, - {load,{bar,soft_purge,soft_purge}}, - {resume,[bar,foo]}] = X42, + {ok, X4} = systools_rc:translate_scripts(up,[Up4], Apps, []), + [{load_object_code,{test,"1.0",[foo,bar]}}, + point_of_no_return, + {suspend,[foo,bar]}, + {load,{bar,soft_purge,soft_purge}}, + {load,{foo,soft_purge,soft_purge}}, + {code_change,up,[{bar,[]}]}, + {resume,[bar,foo]}] = X4, + + {ok, X42} = systools_rc:translate_scripts(dn,[Up4], Apps, []), + [{load_object_code,{test,"1.0",[foo,bar]}}, + point_of_no_return, + {suspend,[foo,bar]}, + {code_change,down,[{bar,[]}]}, + {load,{foo,soft_purge,soft_purge}}, + {load,{bar,soft_purge,soft_purge}}, + {resume,[bar,foo]}] = X42, Up4a = [{update, foo, soft, soft_purge, soft_purge, [bar]}, {update, bar, static, infinity, {advanced, []}, soft_purge, soft_purge, []}], - ?line {ok, X4a} = systools_rc:translate_scripts(up,[Up4a], Apps, []), - ?line [{load_object_code,{test,"1.0",[foo,bar]}}, - point_of_no_return, - {suspend,[foo,{bar,infinity}]}, - {load,{bar,soft_purge,soft_purge}}, - {load,{foo,soft_purge,soft_purge}}, - {code_change,up,[{bar,[]}]}, - {resume,[bar,foo]}] = X4a, - - ?line {ok, X42a} = systools_rc:translate_scripts(dn,[Up4a], Apps, []), - ?line [{load_object_code,{test,"1.0",[foo,bar]}}, - point_of_no_return, - {suspend,[foo,{bar,infinity}]}, - {load,{foo,soft_purge,soft_purge}}, - {load,{bar,soft_purge,soft_purge}}, - {code_change,down,[{bar,[]}]}, - {resume,[bar,foo]}] = X42a, + {ok, X4a} = systools_rc:translate_scripts(up,[Up4a], Apps, []), + [{load_object_code,{test,"1.0",[foo,bar]}}, + point_of_no_return, + {suspend,[foo,{bar,infinity}]}, + {load,{bar,soft_purge,soft_purge}}, + {load,{foo,soft_purge,soft_purge}}, + {code_change,up,[{bar,[]}]}, + {resume,[bar,foo]}] = X4a, + + {ok, X42a} = systools_rc:translate_scripts(dn,[Up4a], Apps, []), + [{load_object_code,{test,"1.0",[foo,bar]}}, + point_of_no_return, + {suspend,[foo,{bar,infinity}]}, + {load,{foo,soft_purge,soft_purge}}, + {load,{bar,soft_purge,soft_purge}}, + {code_change,down,[{bar,[]}]}, + {resume,[bar,foo]}] = X42a, Up4b = [{update, foo, soft, soft_purge, soft_purge, [bar]}, {update, bar, dynamic, infinity, {advanced, []}, soft_purge, soft_purge, []}], - ?line {ok, X4b} = systools_rc:translate_scripts(up,[Up4b], Apps, []), - ?line [{load_object_code,{test,"1.0",[foo,bar]}}, - point_of_no_return, - {suspend,[foo,{bar,infinity}]}, - {load,{bar,soft_purge,soft_purge}}, - {load,{foo,soft_purge,soft_purge}}, - {code_change,up,[{bar,[]}]}, - {resume,[bar,foo]}] = X4b, - - ?line {ok, X42b} = systools_rc:translate_scripts(dn,[Up4b], Apps, []), - ?line [{load_object_code,{test,"1.0",[foo,bar]}}, - point_of_no_return, - {suspend,[foo,{bar,infinity}]}, - {code_change,down,[{bar,[]}]}, - {load,{foo,soft_purge,soft_purge}}, - {load,{bar,soft_purge,soft_purge}}, - {resume,[bar,foo]}] = X42b, + {ok, X4b} = systools_rc:translate_scripts(up,[Up4b], Apps, []), + [{load_object_code,{test,"1.0",[foo,bar]}}, + point_of_no_return, + {suspend,[foo,{bar,infinity}]}, + {load,{bar,soft_purge,soft_purge}}, + {load,{foo,soft_purge,soft_purge}}, + {code_change,up,[{bar,[]}]}, + {resume,[bar,foo]}] = X4b, + + {ok, X42b} = systools_rc:translate_scripts(dn,[Up4b], Apps, []), + [{load_object_code,{test,"1.0",[foo,bar]}}, + point_of_no_return, + {suspend,[foo,{bar,infinity}]}, + {code_change,down,[{bar,[]}]}, + {load,{foo,soft_purge,soft_purge}}, + {load,{bar,soft_purge,soft_purge}}, + {resume,[bar,foo]}] = X42b, %% More complex dependency Up5 = [{update, foo, soft, soft_purge, soft_purge, [bar, baz]}, {update, bar, {advanced, []}, soft_purge, soft_purge, []}, {update, baz, {advanced, baz}, soft_purge, soft_purge, [bar]}], - ?line {ok, X5} = systools_rc:translate_scripts([Up5], Apps, []), - ?line [{load_object_code,{test,"1.0",[foo,baz,bar]}}, - point_of_no_return, - {suspend,[foo,baz,bar]}, - {load,{bar,soft_purge,soft_purge}}, - {load,{baz,soft_purge,soft_purge}}, - {load,{foo,soft_purge,soft_purge}}, - {code_change,up,[{baz,baz},{bar,[]}]}, - {resume,[bar,baz,foo]}] = X5, - - ?line {ok, X52} = systools_rc:translate_scripts(dn,[Up5], Apps, []), - ?line [{load_object_code,{test,"1.0",[foo,baz,bar]}}, - point_of_no_return, - {suspend,[foo,baz,bar]}, - {code_change,down,[{baz,baz},{bar,[]}]}, - {load,{foo,soft_purge,soft_purge}}, - {load,{baz,soft_purge,soft_purge}}, - {load,{bar,soft_purge,soft_purge}}, - {resume,[bar,baz,foo]}] = X52, + {ok, X5} = systools_rc:translate_scripts([Up5], Apps, []), + [{load_object_code,{test,"1.0",[foo,baz,bar]}}, + point_of_no_return, + {suspend,[foo,baz,bar]}, + {load,{bar,soft_purge,soft_purge}}, + {load,{baz,soft_purge,soft_purge}}, + {load,{foo,soft_purge,soft_purge}}, + {code_change,up,[{baz,baz},{bar,[]}]}, + {resume,[bar,baz,foo]}] = X5, + + {ok, X52} = systools_rc:translate_scripts(dn,[Up5], Apps, []), + [{load_object_code,{test,"1.0",[foo,baz,bar]}}, + point_of_no_return, + {suspend,[foo,baz,bar]}, + {code_change,down,[{baz,baz},{bar,[]}]}, + {load,{foo,soft_purge,soft_purge}}, + {load,{baz,soft_purge,soft_purge}}, + {load,{bar,soft_purge,soft_purge}}, + {resume,[bar,baz,foo]}] = X52, Up5a = [{update, foo, dynamic, infinity, soft, soft_purge, soft_purge, [bar, baz]}, @@ -305,26 +305,26 @@ translate(Config) when is_list(Config) -> soft_purge, []}, {update, baz, dynamic, default, {advanced, baz}, soft_purge, soft_purge, [bar]}], - ?line {ok, X5a} = systools_rc:translate_scripts([Up5a], Apps, []), - ?line [{load_object_code,{test,"1.0",[foo,baz,bar]}}, - point_of_no_return, - {suspend,[{foo,infinity},baz,{bar,7000}]}, - {load,{bar,soft_purge,soft_purge}}, - {load,{baz,soft_purge,soft_purge}}, - {load,{foo,soft_purge,soft_purge}}, - {code_change,up,[{baz,baz}, {bar,[]}]}, - {resume,[bar,baz,foo]}] = X5a, - - ?line {ok, X52a} = systools_rc:translate_scripts(dn,[Up5a], Apps, []), - ?line [{load_object_code,{test,"1.0",[foo,baz,bar]}}, - point_of_no_return, - {suspend,[{foo,infinity},baz,{bar,7000}]}, - {code_change,down,[{baz,baz}]}, - {load,{foo,soft_purge,soft_purge}}, - {load,{baz,soft_purge,soft_purge}}, - {load,{bar,soft_purge,soft_purge}}, - {code_change,down,[{bar,[]}]}, - {resume,[bar,baz,foo]}] = X52a, + {ok, X5a} = systools_rc:translate_scripts([Up5a], Apps, []), + [{load_object_code,{test,"1.0",[foo,baz,bar]}}, + point_of_no_return, + {suspend,[{foo,infinity},baz,{bar,7000}]}, + {load,{bar,soft_purge,soft_purge}}, + {load,{baz,soft_purge,soft_purge}}, + {load,{foo,soft_purge,soft_purge}}, + {code_change,up,[{baz,baz}, {bar,[]}]}, + {resume,[bar,baz,foo]}] = X5a, + + {ok, X52a} = systools_rc:translate_scripts(dn,[Up5a], Apps, []), + [{load_object_code,{test,"1.0",[foo,baz,bar]}}, + point_of_no_return, + {suspend,[{foo,infinity},baz,{bar,7000}]}, + {code_change,down,[{baz,baz}]}, + {load,{foo,soft_purge,soft_purge}}, + {load,{baz,soft_purge,soft_purge}}, + {load,{bar,soft_purge,soft_purge}}, + {code_change,down,[{bar,[]}]}, + {resume,[bar,baz,foo]}] = X52a, Up5b = [{update, foo, dynamic, infinity, soft, soft_purge, soft_purge, [bar, baz]}, @@ -332,65 +332,65 @@ translate(Config) when is_list(Config) -> soft_purge, []}, {update, baz, static, default, {advanced, baz}, soft_purge, soft_purge, [bar]}], - ?line {ok, X5b} = systools_rc:translate_scripts([Up5b], Apps, []), - ?line [{load_object_code,{test,"1.0",[foo,baz,bar]}}, - point_of_no_return, - {suspend,[{foo,infinity},baz,{bar,7000}]}, - {load,{bar,soft_purge,soft_purge}}, - {load,{baz,soft_purge,soft_purge}}, - {load,{foo,soft_purge,soft_purge}}, - {code_change,up,[{baz,baz},{bar,[]}]}, - {resume,[bar,baz,foo]}] = X5b, - - ?line {ok, X52b} = systools_rc:translate_scripts(dn,[Up5b], Apps, []), - ?line [{load_object_code,{test,"1.0",[foo,baz,bar]}}, - point_of_no_return, - {suspend,[{foo,infinity},baz,{bar,7000}]}, - {code_change,down,[{bar,[]}]}, - {load,{foo,soft_purge,soft_purge}}, - {load,{baz,soft_purge,soft_purge}}, - {load,{bar,soft_purge,soft_purge}}, - {code_change,down,[{baz,baz}]}, - {resume,[bar,baz,foo]}] = X52b, + {ok, X5b} = systools_rc:translate_scripts([Up5b], Apps, []), + [{load_object_code,{test,"1.0",[foo,baz,bar]}}, + point_of_no_return, + {suspend,[{foo,infinity},baz,{bar,7000}]}, + {load,{bar,soft_purge,soft_purge}}, + {load,{baz,soft_purge,soft_purge}}, + {load,{foo,soft_purge,soft_purge}}, + {code_change,up,[{baz,baz},{bar,[]}]}, + {resume,[bar,baz,foo]}] = X5b, + + {ok, X52b} = systools_rc:translate_scripts(dn,[Up5b], Apps, []), + [{load_object_code,{test,"1.0",[foo,baz,bar]}}, + point_of_no_return, + {suspend,[{foo,infinity},baz,{bar,7000}]}, + {code_change,down,[{bar,[]}]}, + {load,{foo,soft_purge,soft_purge}}, + {load,{baz,soft_purge,soft_purge}}, + {load,{bar,soft_purge,soft_purge}}, + {code_change,down,[{baz,baz}]}, + {resume,[bar,baz,foo]}] = X52b, %% Simple circular dependency (1) Up6 = [{update, foo, soft, soft_purge, soft_purge, [bar]}, {update, bar, soft, soft_purge, soft_purge, [foo]}], - ?line {ok, X61} = systools_rc:translate_scripts([Up6], Apps, []), - ?line [{load_object_code,{test,"1.0",[foo,bar]}}, - point_of_no_return, - {suspend,[foo,bar]}, - {load,{bar,soft_purge,soft_purge}}, - {load,{foo,soft_purge,soft_purge}}, - {resume,[bar,foo]}] = X61, - ?line {ok, X62} = systools_rc:translate_scripts(dn,[Up6], Apps, []), - ?line [{load_object_code,{test,"1.0",[foo,bar]}}, - point_of_no_return, - {suspend,[foo,bar]}, - {load,{foo,soft_purge,soft_purge}}, - {load,{bar,soft_purge,soft_purge}}, - {resume,[bar,foo]}] = X62, + {ok, X61} = systools_rc:translate_scripts([Up6], Apps, []), + [{load_object_code,{test,"1.0",[foo,bar]}}, + point_of_no_return, + {suspend,[foo,bar]}, + {load,{bar,soft_purge,soft_purge}}, + {load,{foo,soft_purge,soft_purge}}, + {resume,[bar,foo]}] = X61, + {ok, X62} = systools_rc:translate_scripts(dn,[Up6], Apps, []), + [{load_object_code,{test,"1.0",[foo,bar]}}, + point_of_no_return, + {suspend,[foo,bar]}, + {load,{foo,soft_purge,soft_purge}}, + {load,{bar,soft_purge,soft_purge}}, + {resume,[bar,foo]}] = X62, %% Simple circular dependency (2) Up7 = [{update, foo, soft, soft_purge, soft_purge, [bar, baz]}, {update, bar, soft, soft_purge, soft_purge, [foo]}, {update, baz, soft, soft_purge, soft_purge, [bar]}], - ?line {ok, X71} = systools_rc:translate_scripts([Up7], Apps, []), - ?line [{load_object_code,{test,"1.0",[foo,bar,baz]}}, - point_of_no_return, - {suspend,[foo,bar,baz]}, - {load,{baz,soft_purge,soft_purge}}, - {load,{bar,soft_purge,soft_purge}}, - {load,{foo,soft_purge,soft_purge}}, - {resume,[baz, bar, foo]}] = X71, - ?line {ok, X72} = systools_rc:translate_scripts(dn,[Up7], Apps, []), - ?line [{load_object_code,{test,"1.0",[foo,bar,baz]}}, - point_of_no_return, - {suspend,[foo,bar,baz]}, - {load,{foo,soft_purge,soft_purge}}, - {load,{bar,soft_purge,soft_purge}}, - {load,{baz,soft_purge,soft_purge}}, - {resume,[baz,bar,foo]}] = X72, + {ok, X71} = systools_rc:translate_scripts([Up7], Apps, []), + [{load_object_code,{test,"1.0",[foo,bar,baz]}}, + point_of_no_return, + {suspend,[foo,bar,baz]}, + {load,{baz,soft_purge,soft_purge}}, + {load,{bar,soft_purge,soft_purge}}, + {load,{foo,soft_purge,soft_purge}}, + {resume,[baz, bar, foo]}] = X71, + {ok, X72} = systools_rc:translate_scripts(dn,[Up7], Apps, []), + [{load_object_code,{test,"1.0",[foo,bar,baz]}}, + point_of_no_return, + {suspend,[foo,bar,baz]}, + {load,{foo,soft_purge,soft_purge}}, + {load,{bar,soft_purge,soft_purge}}, + {load,{baz,soft_purge,soft_purge}}, + {resume,[baz,bar,foo]}] = X72, %% Complex circular dependencies, check only order %% @@ -400,20 +400,20 @@ translate(Config) when is_list(Config) -> {update, z, soft, soft_purge, soft_purge, [x]}, {update, bar, soft, soft_purge, soft_purge, [baz]}, {update, baz, soft, soft_purge, soft_purge, [bar]}], - ?line {ok, X8} = systools_rc:translate_scripts([Up8], Apps, []), - ?line {value, {suspend, Order}} = lists:keysearch(suspend, 1, X8), - ?line Rest = case lists:reverse(Order) of - [bar, baz | R] -> R; - [baz, bar | R] -> R - end, - ?line case Rest of - [y, z, x, foo] -> ok; - [y, x, z, foo] -> ok; - [foo, y, z, x] -> ok; - [foo, y, x, z] -> ok; - [y, foo, z, x] -> ok; - [y, foo, x, z] -> ok - end, + {ok, X8} = systools_rc:translate_scripts([Up8], Apps, []), + {value, {suspend, Order}} = lists:keysearch(suspend, 1, X8), + Rest = case lists:reverse(Order) of + [bar, baz | R] -> R; + [baz, bar | R] -> R + end, + case Rest of + [y, z, x, foo] -> ok; + [y, x, z, foo] -> ok; + [foo, y, z, x] -> ok; + [foo, y, x, z] -> ok; + [y, foo, z, x] -> ok; + [y, foo, x, z] -> ok + end, %% Check that order among other instructions isn't changed Up9 = [{update, foo, soft, soft_purge, soft_purge, [baz]}, @@ -428,13 +428,12 @@ translate(Config) when is_list(Config) -> {apply, {m, f, [5]}}, {update, baz, soft, soft_purge, soft_purge, [bar]}, {apply, {m, f, [6]}}], - ?line {ok, X9} = systools_rc:translate_scripts([Up9], Apps, []), + {ok, X9} = systools_rc:translate_scripts([Up9], Apps, []), Other2 = [X || {apply, {m, f, [X]}} <- X9], - ?line [1,2,3,4,5,6] = lists:sort(Other2), - ?line ok. + [1,2,3,4,5,6] = lists:sort(Other2), + ok. -translate_app(suite) -> []; translate_app(Config) when is_list(Config) -> PreApps = [#application{name = test, @@ -459,30 +458,112 @@ translate_app(Config) when is_list(Config) -> %% Simple translation (1) Up1 = [{add_module, foo}, {add_module, bar}], - ?line {ok, X1} = systools_rc:translate_scripts([Up1], Apps, []), - ?line [{load_object_code,{test,"1.0",[foo,bar]}}, - point_of_no_return, - {load,{foo,brutal_purge,brutal_purge}}, - {load,{bar,brutal_purge,brutal_purge}}] = X1, + {ok, X1} = systools_rc:translate_scripts([Up1], Apps, []), + [{load_object_code,{test,"1.0",[foo,bar]}}, + point_of_no_return, + {load,{foo,brutal_purge,brutal_purge}}, + {load,{bar,brutal_purge,brutal_purge}}] = X1, %% Simple translation (2) Up2 = [{add_application, test}], - ?line {ok, X2} = systools_rc:translate_scripts([Up2], Apps, []), -io:format("X2=~p~n", [X2]), - ?line [{load_object_code,{test,"1.0",[foo,bar,baz]}}, - point_of_no_return, - {load,{foo,brutal_purge,brutal_purge}}, - {load,{bar,brutal_purge,brutal_purge}}, - {load,{baz,brutal_purge,brutal_purge}}, - {apply,{application,start,[test,permanent]}}] = X2, + {ok, X2} = systools_rc:translate_scripts([Up2], Apps, []), + io:format("X2=~p~n", [X2]), + [{load_object_code,{test,"1.0",[foo,bar,baz]}}, + point_of_no_return, + {load,{foo,brutal_purge,brutal_purge}}, + {load,{bar,brutal_purge,brutal_purge}}, + {load,{baz,brutal_purge,brutal_purge}}, + {apply,{application,start,[test,permanent]}}] = X2, %% Simple translation (3) Up3 = [{remove_application, pelle}], - ?line {ok, X3} = systools_rc:translate_scripts([Up3], Apps, PreApps), - ?line [point_of_no_return, - {apply,{application,stop,[pelle]}}, - {remove,{pelle,brutal_purge,brutal_purge}}, - {remove,{kalle,brutal_purge,brutal_purge}}, - {purge,[pelle,kalle]}, - {apply,{application,unload,[pelle]}}] = X3, - ?line ok. + {ok, X3} = systools_rc:translate_scripts([Up3], Apps, PreApps), + [point_of_no_return, + {apply,{application,stop,[pelle]}}, + {remove,{pelle,brutal_purge,brutal_purge}}, + {remove,{kalle,brutal_purge,brutal_purge}}, + {purge,[pelle,kalle]}, + {apply,{application,unload,[pelle]}}] = X3, + ok. + + +translate_emulator_restarts(_Config) -> + Apps = + [#application{name = test, + description = "TEST", + vsn = "1.0", + modules = [{foo,1},{bar,1},{baz,1}], + regs = [], + mod = {sasl, []}}, + #application{name = test, + description = "TEST2", + vsn = "1.0", + modules = [{x,1},{y,1},{z,1}], + regs = [], + mod = {sasl, []}}], + %% restart_new_emulator + Up1 = [{update, foo, soft, soft_purge, soft_purge, []},restart_new_emulator], + {ok, X1} = systools_rc:translate_scripts([Up1], Apps, []), + [restart_new_emulator, + {load_object_code, {test,"1.0",[foo]}}, + point_of_no_return, + {suspend,[foo]}, + {load,{foo,soft_purge,soft_purge}}, + {resume,[foo]}] = X1, + + %% restart_emulator + Up2 = [{update, foo, soft, soft_purge, soft_purge, []},restart_emulator], + {ok, X2} = systools_rc:translate_scripts([Up2], Apps, []), + [{load_object_code, {test,"1.0",[foo]}}, + point_of_no_return, + {suspend,[foo]}, + {load,{foo,soft_purge,soft_purge}}, + {resume,[foo]}, + restart_emulator] = X2, + + %% restart_emulator + restart_new_emulator + Up3 = [{update, foo, soft, soft_purge, soft_purge, []}, + restart_emulator, + restart_new_emulator], + {ok, X3} = systools_rc:translate_scripts([Up3], Apps, []), + [restart_new_emulator, + {load_object_code, {test,"1.0",[foo]}}, + point_of_no_return, + {suspend,[foo]}, + {load,{foo,soft_purge,soft_purge}}, + {resume,[foo]}, + restart_emulator] = X3, + + %% restart_emulator + restart_new_emulator + Up4a = [{update, foo, soft, soft_purge, soft_purge, []}, + restart_emulator, + restart_new_emulator], + Up4b = [restart_new_emulator, + {update, x, soft, soft_purge, soft_purge, []}, + restart_emulator, + restart_emulator], + {ok, X4} = systools_rc:translate_scripts([Up4a,Up4b], Apps, []), + [restart_new_emulator, + {load_object_code, {test,"1.0",[foo,x]}}, + point_of_no_return, + {suspend,[foo]}, + {load,{foo,soft_purge,soft_purge}}, + {resume,[foo]}, + {suspend,[x]}, + {load,{x,soft_purge,soft_purge}}, + {resume,[x]}, + restart_emulator] = X4, + + %% only restart_new_emulator + Up5 = [restart_new_emulator], + {ok, X5} = systools_rc:translate_scripts([Up5], Apps, []), + [restart_new_emulator, + point_of_no_return] = X5, + + %% only restart_emulator + Up6 = [restart_emulator], + {ok, X6} = systools_rc:translate_scripts([Up6], Apps, []), + [point_of_no_return, + restart_emulator] = X6, + + ok. diff --git a/lib/sasl/test/test_lib.hrl b/lib/sasl/test/test_lib.hrl new file mode 100644 index 0000000000..eeef721647 --- /dev/null +++ b/lib/sasl/test/test_lib.hrl @@ -0,0 +1,3 @@ +-define(ertsvsn,"4.4"). +-define(kernelvsn,"2.14.3"). +-define(stdlibvsn,"1.17.3"). diff --git a/lib/sasl/vsn.mk b/lib/sasl/vsn.mk index 2db134af48..23694f1399 100644 --- a/lib/sasl/vsn.mk +++ b/lib/sasl/vsn.mk @@ -1 +1 @@ -SASL_VSN = 2.1.10 +SASL_VSN = 2.2 diff --git a/lib/snmp/Makefile b/lib/snmp/Makefile index 4264531112..ff6fad8ddc 100644 --- a/lib/snmp/Makefile +++ b/lib/snmp/Makefile @@ -54,6 +54,9 @@ else endif +DIA_PLT = ./priv/plt/$(APPLICATION).plt +DIA_ANALYSIS = $(basename $(DIA_PLT)).dialyzer_analysis + # ---------------------------------------------------- # Default Subdir Targets # ---------------------------------------------------- @@ -75,6 +78,11 @@ info: @echo "" @echo "SNMP_VSN: $(SNMP_VSN)" @echo "APP_VSN: $(APP_VSN)" + @echo "" + @echo "DIA_PLT: $(DIA_PLT)" + @echo "DIA_ANALYSIS: $(DIA_ANALYSIS)" + @echo "" + gclean: git clean -fXd @@ -120,3 +128,23 @@ tar: $(APP_TAR_FILE) $(APP_TAR_FILE): $(APP_DIR) (cd $(APP_RELEASE_DIR); gtar zcf $(APP_TAR_FILE) $(DIR_NAME)) + +dclean: + rm -f $(DIA_PLT) + rm -f $(DIA_ANALYSIS) + +dialyzer_plt: $(DIA_PLT) + +$(DIA_PLT): + @echo "Building $(APPLICATION) plt file" + @dialyzer --build_plt \ + --output_plt $@ \ + -r ../$(APPLICATION)/ebin \ + --output $(DIA_ANALYSIS) \ + --verbose + +dialyzer: $(DIA_PLT) + @echo "Running dialyzer on $(APPLICATION)" + @dialyzer --plt $< \ + ../$(APPLICATION)/ebin \ + --verbose
\ No newline at end of file diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml index decde4746a..64a0d1a13f 100644 --- a/lib/snmp/doc/src/notes.xml +++ b/lib/snmp/doc/src/notes.xml @@ -32,6 +32,141 @@ <file>notes.xml</file> </header> + + <section> + <title>SNMP Development Toolkit 4.21.4</title> + <p>Version 4.21.4 supports code replacement in runtime from/to + version 4.21.3, 4.21.2, 4.21.1, 4.21, 4.20.1, 4.20 and 4.19. </p> + + <section> + <title>Improvements and new features</title> + <p>-</p> + +<!-- + <list type="bulleted"> + <item> + <p>[compiler] Improved version info printout from the + <seealso marker="snmpc(command)#">MIB compiler frontend escript</seealso>. </p> + <p>Own Id: OTP-9618</p> + </item> + + </list> +--> + + </section> + + <section> + <title>Fixed Bugs and Malfunctions</title> +<!-- + <p>-</p> +--> + + <list type="bulleted"> + <item> + <p>[agent] Removed use of old style tuple funs. </p> + <p>Own Id: OTP-9779</p> + </item> + + </list> + </section> + + + <section> + <title>Incompatibilities</title> + <p>-</p> + +<!-- + <list type="bulleted"> + <item> + <p>foo. </p> + <p>Own Id: OTP-9718</p> + </item> + + </list> +--> + + </section> + + </section> <!-- 4.21.4 --> + + + <section> + <title>SNMP Development Toolkit 4.21.3</title> + <p>Version 4.21.3 supports code replacement in runtime from/to + version 4.21.2, 4.21.1, 4.21, 4.20.1, 4.20 and 4.19. </p> + + <section> + <title>Improvements and new features</title> +<!-- + <p>-</p> +--> + + <list type="bulleted"> + <item> + <p>[compiler] Improved version info printout from the + <seealso marker="snmpc(command)#">MIB compiler frontend escript</seealso>. </p> + <p>Own Id: OTP-9618</p> + </item> + + </list> + + </section> + + <section> + <title>Fixed Bugs and Malfunctions</title> +<!-- + <p>-</p> +--> + + <list type="bulleted"> + <item> + <p>[agent] Version 4.20 introduced a change that broke trap + sending from subagents. Due to a bug in the test code, + this was not discovered, until that bug was fixed. </p> + <p>Own Id: OTP-9745</p> + </item> + + <item> + <p>[agent] When sending an error message (reply) regarding + <c>snmpUnknownPDUHandlers</c>, the agent used the wrong OID. </p> + <p>Own Id: OTP-9747</p> + </item> + + <item> + <p>[compiler] Fix the <c>--warnings/--W</c> option parsing in the + <seealso marker="snmpc(command)#option_warnings">snmpc</seealso> + wrapper (e)script. + The short warning option was incorrectly <c>--w</c>, instead + of as documented <c>--W</c>. This has now been corrected. </p> + <p>*** POTENTIAL INCOMPATIBILITY ***</p> + <p>Tuncer Ayaz</p> + <p>Own Id: OTP-9718</p> + </item> + + </list> + </section> + + + <section> + <title>Incompatibilities</title> +<!-- + <p>-</p> +--> + + <list type="bulleted"> + <item> + <p>[compiler] The short warning option has been changed from + <c>--w</c> to <c>--W</c> to comply with the documentation. </p> + <p>Tuncer Ayaz</p> + <p>Own Id: OTP-9718</p> + </item> + + </list> + </section> + + </section> <!-- 4.21.3 --> + + <section> <title>SNMP Development Toolkit 4.21.2</title> <p>Version 4.21.2 supports code replacement in runtime from/to @@ -855,927 +990,6 @@ snmp_view_basec_acm_mib:vacmAccessTable(set, RowIndex, Cols). </section> <!-- 4.15 --> - <section> - <title>SNMP Development Toolkit 4.14</title> - - <p>Version 4.14 supports code replacement in runtime from/to - version 4.13.5, 4.13.4, 4.13.3, 4.13.2, 4.13.1 and 4.13.</p> - - <section> - <title>Improvements and new features</title> - <!-- - <p>-</p> - --> - - <list type="bulleted"> - <item> - <p>[compiler] Include object- and notification groups in the - compiled mib. - This will make it possible to import groups from other mibs. </p> - <p>Also the SNMPv2-MIB-file has been updated to a more - up-to-date version. </p> - <p>Own Id: OTP-8223</p> - <!-- <p>Aux Id: Seq 11383</p> --> - </item> - - <item> - <p>[manager] Added support for message filtering in the - network interface module provided with the application. - The component that actually make the filter decisions - is the network interface filter module. This module - must implement the - <seealso marker="snmpm_network_interface_filter">network interface filter behaviour</seealso> - for message filtering. - See also the Configuring chapter of - the User's Guide to see how to configure this feature. </p> - <p>See the - <seealso marker="snmp_app#configuration_params">configuration</seealso> - chapter for more info about the filter options.</p> - <p>Own Id: OTP-8228</p> - <p>Aux Id: Seq 11411</p> - </item> - - <item> - <p>The MIBs delivered as part of the application is now - also available as man pages, section 7. </p> - <p>Own Id: OTP-8237</p> - <!-- <p>Aux Id: Seq 11383</p> --> - </item> - - </list> - - </section> - - <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <p>-</p> - - <!-- - <list type="bulleted"> - <item> - <p>[agent] The main agent type header file contained some miss-information - regarding the type of the entrytype field of the me-record, causing - unneccessary confusion.</p> - <p>Own Id: OTP-8116</p> - <p>Aux Id: Seq 11312</p> - </item> - - </list> - --> - - </section> - - <section> - <title>Incompatibilities</title> - <p>-</p> - </section> - </section> <!-- 4.14 --> - - - <section> - <title>SNMP Development Toolkit 4.13.5</title> - - <p>Version 4.13.5 supports code replacement in runtime from/to - version 4.13.4, 4.13.3, 4.13.2, 4.13.1 and 4.13.</p> - - <section> - <title>Improvements and new features</title> - <!-- - <p>-</p> - --> - - <list type="bulleted"> - <item> - <p>[agent] Improved the cache handling of the mib server. </p> - <p>A number of new functions and config options for the mib server - cache has been added. </p> - <p>See - <seealso marker="snmpa#invalidate_mibs_cache">invalidate_mibs_cache/0,1</seealso>, - <seealso marker="snmpa#enable_mibs_cache">enable_mibs_cache/0,1</seealso>, - <seealso marker="snmpa#disable_mibs_cache">disable_mibs_cache/0,1</seealso>, - <seealso marker="snmpa#gc_mibs_cache">gc_mibs_cache/0,1,2,3</seealso>, - <seealso marker="snmpa#enable_mibs_cache_autogc">enable_mibs_cache_autogc/0,1</seealso>, - <seealso marker="snmpa#disable_mibs_cache_autogc">disable_mibs_cache_autogc/0,1</seealso>, - <seealso marker="snmpa#update_mibs_cache_age">update_mibs_cache_age/1,2</seealso> and - <seealso marker="snmpa#update_mibs_cache_gclimit">update_mibs_cache_gclimit/1,2</seealso> for more info. </p> - <p>See also the - <seealso marker="snmp_app#configuration_params">configuration</seealso> - chapter for more info about the mib server cache options.</p> - <p>Own Id: OTP-8182</p> - <p>Aux Id: Seq 11383</p> - </item> - - <item> - <p>[agent] A manager could no longer use the SNMPv3 user "initial" - as this was interpretated as the first step of the discovery. </p> - <p>Introduced a new terminating option, <c>trigger_username</c> to - make it possible to configure the username the agent reacts to. - Default is <c>""</c>. </p> - <p>See the - <seealso marker="snmp_app#configuration_params">configuration</seealso> - chapter for more info about the discovery options.</p> - <p>Own Id: OTP-8120</p> - <p>Aux Id: Seq 11361</p> - </item> - - </list> - - </section> - - <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <!-- - <p>-</p> - --> - <list type="bulleted"> - <item> - <p>[agent] The main agent type header file contained some miss-information - regarding the type of the entrytype field of the me-record, causing - unneccessary confusion.</p> - <p>Own Id: OTP-8116</p> - <p>Aux Id: Seq 11312</p> - </item> - - </list> - - </section> - - <section> - <title>Incompatibilities</title> - <p>-</p> - </section> - </section> <!-- 4.13.5 --> - - - <section> - <title>SNMP Development Toolkit 4.13.4</title> - - <p>Version 4.13.4 supports code replacement in runtime from/to - version 4.13.3, 4.13.2, 4.13.1 and 4.13.</p> - - <section> - <title>Improvements and new features</title> - <p>-</p> - - <!-- - <list type="bulleted"> - <item> - <p>[agent] Support for the discovery process. </p> - <p>The agent can both initiate discovery itself (see the - <seealso marker="snmp_agent_funct_descr#discovery">discovery</seealso> chapter - for more info) and respond to discovery initiated by a manager.</p> - <p>Own Id: OTP-7571</p> - <p>Aux Id: Seq 11053</p> - </item> - - </list> - --> - - </section> - - <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <!-- - <p>-</p> - --> - <list type="bulleted"> - <item> - <p>[agent] Originating discovery problems. </p> - <p>Invalid state variable update during second stage of - discovery causes master agent crash. </p> - <p>Also the net_if process failed to activate socket - ({active, once}) after first discovery response was sent. </p> - <p>Own Id: OTP-8044</p> - <p>Aux Id: Seq 11295</p> - </item> - - <item> - <p>[agent] Terminating discovery problem. </p> - <p>The reply to the second stage request should include a - varbind with <c>usmStatsNotInTimeWindows</c>.</p> - <p>Own Id: OTP-8062</p> - <p>Aux Id: Seq 11318</p> - </item> - - <item> - <p>[agent] Originating discovery improvement. </p> - <p>Added the ExtraInfo argument to the - <seealso marker="snmpa#discovery">discovery</seealso> function. - This argument will be passed on to the stage1_finish callback - function. Also, the - <seealso marker="snmpa#discovery">discovery</seealso> function - will now always return <c>{ok, ManagerEngineID}</c> on successful - discovery. </p> - <p>The <seealso marker="snmpa_discovery_handler">discovery handler</seealso> - behaviour updated accordingly. </p> - <p>Own Id: OTP-8098</p> - <p>Aux Id: Seq 11346</p> - </item> - - </list> - - </section> - - <section> - <title>Incompatibilities</title> - <p>-</p> - </section> - </section> <!-- 4.13.4 --> - - - <section> - <title>SNMP Development Toolkit 4.13.3</title> - - <p>Version 4.13.3 supports code replacement in runtime from/to - version 4.13.2, 4.13.1 and 4.13.</p> - - <section> - <title>Improvements and new features</title> - <p>-</p> - - <!-- - <list type="bulleted"> - <item> - <p>[agent] Support for the discovery process. </p> - <p>The agent can both initiate discovery itself (see the - <seealso marker="snmp_agent_funct_descr#discovery">discovery</seealso> chapter - for more info) and respond to discovery initiated by a manager.</p> - <p>Own Id: OTP-7571</p> - <p>Aux Id: Seq 11053</p> - </item> - - </list> - --> - - </section> - - <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <!-- - <p>-</p> - --> - <list type="bulleted"> - <item> - <p>[manager] A request for an oid of type BITS was actually - returned as OCTET STRING. </p> - <p>Values of type BITS are encoded as OCTET STRING, - which makes it impossible for the decoder to know that - they should really be of type BITS. - Instead, this has to be done higher up in the stack, where - there is knowledge of the MIB (assuming that the mib has - been loaded, there is info about the type of the mibentry). </p> - <p>This problem has now been fixed, but requires that the MIB - defining this mib-entry is loaded! </p> - <p>The utility function - <seealso marker="snmpm#oid_to_type">oid_to_type</seealso> - has been added, for debug purpose. </p> - <p>The utility function(s) - <seealso marker="snmp#octet_string_to_bits">octet_string_to_bits</seealso> - and - <seealso marker="snmp#bits_to_octet_string">bits_to_octet_string</seealso> - has also been added. These can be used if the user prefers to - handle the conversion on their own. </p> - <p>Own Id: OTP-8015</p> - <p>Aux Id: Seq 11285</p> - </item> - - <item> - <p>[agent] Fixed some issues with the discovery handling. </p> - <p>Changed the API of the - <seealso marker="snmpa#discovery">discovery</seealso> - function to solve some - of these problems. </p> - <p>Introduced various options for controlling the discovery - process. See the - <seealso marker="snmp_app#configuration_params">configuration</seealso> - chapter for more info about the discovery options.</p> - <p>Own Id: OTP-8020</p> - <p>Aux Id: Seq 11295</p> - </item> - - </list> - - </section> - - <section> - <title>Incompatibilities</title> - <p>-</p> - </section> - </section> <!-- 4.13.3 --> - - - <section> - <title>SNMP Development Toolkit 4.13.2</title> - - <p>Version 4.13.2 supports code replacement in runtime from/to - version 4.13.1 and 4.13.</p> - - <section> - <title>Improvements and new features</title> - <p>-</p> - - <!-- - <list type="bulleted"> - <item> - <p>[agent] Support for the discovery process. </p> - <p>The agent can both initiate discovery itself (see the - <seealso marker="snmp_agent_funct_descr#discovery">discovery</seealso> chapter - for more info) and respond to discovery initiated by a manager.</p> - <p>Own Id: OTP-7571</p> - <p>Aux Id: Seq 11053</p> - </item> - - </list> - --> - - </section> - - <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <!-- - <p>-</p> - --> - <list type="bulleted"> - <item> - <p>[manager] Failure during downed user cleanup. - As part of the cleanup after a crashed user, - the manager attempts to unregister the agents - registered by this user. This however failed, - causing a server crash. </p> - <p>Own Id: OTP-7961</p> - <p>Aux Id: Seq 11275</p> - </item> - - <item> - <p>[manager] Incorrectly documented value type for - IpAddress (ip). The value type for IpAddress is - documented as ip but is actually ia. The value type - ip has been added. The old (not documented) value - type ia still works. </p> - <p>Own Id: OTP-7977</p> - <p>Aux Id: Seq 11279</p> - </item> - - <item> - <p>[manager] EngineId lookup fails when using version-3. </p> - <p>Own Id: OTP-7983</p> - <p>Aux Id: Seq 11275</p> - </item> - - <item> - <p>[agent] As of version 4.13 the possible return values - of the function - <seealso marker="snmpa_mpd#process_packet">snmpa_mpd:process_packet/4</seealso> - changed, but this was not documented. </p> - <p>Own Id: OTP-7989</p> - <p>Aux Id: Seq 11275</p> - </item> - - </list> - - </section> - - <section> - <title>Incompatibilities</title> - <p>-</p> - </section> - </section> <!-- 4.13.2 --> - - <section> - <title>SNMP Development Toolkit 4.13.1</title> - - <p>Version 4.13.1 supports code replacement in runtime from/to - version 4.13.</p> - - <section> - <title>Improvements and new features</title> - <p>-</p> - - <!-- - <list type="bulleted"> - <item> - <p>[agent] Support for the discovery process. </p> - <p>The agent can both initiate discovery itself (see the - <seealso marker="snmp_agent_funct_descr#discovery">discovery</seealso> chapter - for more info) and respond to discovery initiated by a manager.</p> - <p>Own Id: OTP-7571</p> - <p>Aux Id: Seq 11053</p> - </item> - - </list> - --> - - </section> - - <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <!-- - <p>-</p> - --> - <list type="bulleted"> - <item> - <p>[manager] Registration of users had some issues. </p> - <p>Not all of the registration functions where actually exported - (<seealso marker="snmpm#register_user">register_user/4</seealso> - and - <seealso marker="snmpm#register_user_monitor">register_user_monitor/4</seealso>). - This has now been fixed. </p> - <p>Also, the registration did not succeed unless - user implemented the *new* behaviour. This has now - also been fixed (registration succeeds if the user - implements either the new (i.e. updated - <seealso marker="snmpm_user">snmpm_user</seealso>) - or the old user behaviour (<c>snmpm_user_old</c>)). </p> - <p>Own Id: OTP-7902</p> - <p>Aux Id: Seq 11240</p> - </item> - - </list> - - </section> - - <section> - <title>Incompatibilities</title> - <p>-</p> - </section> - </section> <!-- 4.13.1 --> - - <section> - <title>SNMP Development Toolkit 4.13</title> -<!-- - <p>Version 4.13 supports code replacement in runtime from/to - version 4.12.1.</p> ---> - - <section> - <title>Improvements and new features</title> - <!-- - <p>-</p> - --> - <list type="bulleted"> - <item> - <p>[agent] Support for the discovery process. </p> - <p>The agent can both initiate discovery itself (see the - <seealso marker="snmp_agent_funct_descr#discovery">discovery</seealso> chapter - for more info) and respond to discovery initiated by a manager.</p> - <p>Own Id: OTP-7571</p> - <p>Aux Id: Seq 11053</p> - </item> - - </list> - - </section> - - <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <!-- - <p>-</p> - --> - <list type="bulleted"> - <item> - <p>[agent] Unnecessary use of math:pow/2 could cause problems - on systems without floating point support. </p> - <p>Per Hedeland</p> - <p>Own Id: OTP-7735</p> - <!-- <p>Aux Id: Seq 10966</p> --> - </item> - - <item> - <p>[manager] A major flaw was discovered with the agent handling. </p> - <p>First, <c>TargetName</c> was never used as intended, as a unique - identifier for the target (agent in this case). </p> - <p>Second, <c>TargetName</c> had a <em>default value</em>, which meant - that several agents could have the same <c>TargetName</c>, causing - unpredictable behaviour in the manager. </p> - <p>Third, <c>EngineID</c> was not a mandatory config option and had - furthermore also a <em>default value</em>. </p> - - <p>These problems has been solved in the following way: </p> - <p>First, a new set of api functions has been introduced (and documented): - <seealso marker="snmpm#register_user">register_user/4</seealso>, - <seealso marker="snmpm#register_user_monitor">register_user_monitor/4</seealso>, - <seealso marker="snmpm#register_agent">register_agent/3</seealso>, - <seealso marker="snmpm#unregister_agent">unregister_agent/2</seealso>, - <seealso marker="snmpm#agent_info">agent_info/2</seealso>, - <seealso marker="snmpm#update_agent_info">update_agent_info/4</seealso>, - <seealso marker="snmpm#sync_get">sync_get/3,4,5,6</seealso>, - <seealso marker="snmpm#async_get">async_get/3,4,5,6</seealso>, - <seealso marker="snmpm#sync_get_next">sync_get_next/3,4,5,6</seealso>, - <seealso marker="snmpm#async_get_next">async_get_next/3,4,5,6</seealso>, - <seealso marker="snmpm#sync_set">sync_set/3,4,5,6</seealso>, - <seealso marker="snmpm#async_set">async_set/3,4,5,6</seealso>, - <seealso marker="snmpm#sync_get_bulk">sync_get_bulk/5,6,7,8</seealso> and - <seealso marker="snmpm#async_get_bulk">async_get_bulk/5,6,7,8</seealso> - that all use <c>TargetName</c> (and not, as previously, <c>Addr</c> - and <c>Port</c>) to identify the agent (also the return value of - <seealso marker="snmpm#which_agents">which_agents</seealso> has - been changed). </p> - <p>Second, for backward compatibility, the old functions still - exist, but are no longer documented and are now wrappers for the - new functions, including erroneous default value for EngineID and - all. The TargetName is however generated from the provided - <c>Addr</c>, <c>Port</c> and <c>Version</c> config options. </p> - <p>Third, the behaviour of the - <seealso marker="snmpm_user">SNMP manager user</seealso> has - been changed to reflect this, i.e. - <seealso marker="snmpm_user#handle_pdu">handle_pdu/4</seealso>, - <seealso marker="snmpm_user#handle_trap">handle_trap/3</seealso>, - <seealso marker="snmpm_user#handle_inform">handle_inform/3</seealso>, - <seealso marker="snmpm_user#handle_report">handle_report/3</seealso> - and the return-value of - <seealso marker="snmpm_user#handle_agent">handle_agent/4</seealso>. - The old (non-documented) callback-functions (using Addr and Port) - will still be called if the agent was registered using the old - registration functions. </p> - - <p>Own Id: OTP-7836</p> - <!-- <p>Aux Id: Seq 10966</p> --> - </item> - - </list> - - </section> - - <section> - <title>Incompatibilities</title> - <p>-</p> - </section> - </section> <!-- 4.13 --> - - <section> - <title>SNMP Development Toolkit 4.12.2</title> - <p>Version 4.12.2 supports code replacement in runtime from/to - version 4.12.1, 4.12, 4.11.2, 4.11.1 and 4.11.</p> - - <section> - <title>Improvements and new features</title> - <p>-</p> - <!-- - <list type="bulleted"> - <item> - <item> - <p>[agent] Improvement of the inform reporting. - It was previously not certain how many acks an - application received, 0, 1 or 2. This has now been - fixed, so that only 1 (one) ack is issued. </p> - <p>Per Hedeland</p> - <p>Own Id: OTP-7525</p> - </item> - - </list> - --> - - </section> - - <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <!-- - <p>-</p> - --> - <list type="bulleted"> - <item> - <p>[agent] Bad session cache (usm+camv-info) invalidation - could cause user crash, through call(s) to (a number of) - MIB API function(s) (undefined function). </p> - <p>Own Id: OTP-7868</p> - <!-- <p>Aux Id: Seq 11124</p> --> - </item> - - </list> - - </section> - - <section> - <title>Incompatibilities</title> - <p>-</p> - </section> - </section> <!-- 4.12.2 --> - - <section> - <title>SNMP Development Toolkit 4.12.1</title> - <p>Version 4.12.1 supports code replacement in runtime from/to - version 4.12, 4.11.2, 4.11.1 and 4.11.</p> - - <section> - <title>Improvements and new features</title> - <p>-</p> - <!-- - <list type="bulleted"> - <item> - <item> - <p>[agent] Improvement of the inform reporting. - It was previously not certain how many acks an - application received, 0, 1 or 2. This has now been - fixed, so that only 1 (one) ack is issued. </p> - <p>Per Hedeland</p> - <p>Own Id: OTP-7525</p> - </item> - - </list> - --> - - </section> - - <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <!-- - <p>-</p> - --> - <list type="bulleted"> - <item> - <p>Logging of messages with the GetBulk-request PDU - incorrectly produced an erroneous entry in the - log: "An error occurred". </p> - <p>The reason for this was that the PDU-fields - error_status and error_index is re-used for - Non-repeaters and Max-repetitions for - GetBulk-request PDUs, but this was not handled - by the logging code. </p> - <p>Own Id: OTP-7695</p> - <p>Aux Id: Seq 11124</p> - </item> - - <item> - <p>[agent] An attempt to set the row status to active for an - notReady table row, could result in an "inconsistentValue" - error. </p> - <p>The same problem existed when attempting to set row status - to notInService for a row in notReady. </p> - <p>Serge Aleynikov</p> - <p>Own Id: OTP-7698</p> - <!-- <p>Aux Id: Seq 10966</p> --> - </item> - - </list> - - </section> - - <section> - <title>Incompatibilities</title> - <p>-</p> - </section> - </section> <!-- 4.12.1 --> - - <section> - <title>SNMP Development Toolkit 4.12</title> - <p>Version 4.12 supports code replacement in runtime from/to - version 4.11.2, 4.11.1 and 4.11.</p> - - <section> - <title>Improvements and new features</title> - <!-- - <p>-</p> - --> - <list type="bulleted"> - <item> - <p>[agent] A simple lookup cache has been added to improve - the mib server lookup performance. </p> - <p>This can be disabled with the mib_server - <seealso marker="snmp_app">cache</seealso> option. </p> - <p>Own Id: OTP-7346</p> - </item> - - <item> - <p>[agent] Improvement of the inform reporting. - It was previously not certain how many acks an - application received, 0, 1 or 2. This has now been - fixed, so that only 1 (one) ack is issued. </p> - <p>Per Hedeland</p> - <p>Own Id: OTP-7525</p> - </item> - - </list> - - </section> - - <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <p>-</p> - <!-- - <list type="bulleted"> - <item> - <p>[manager] Encryption error when attempting to send - version 3 inform-requests. </p> - <p>Own Id: OTP-7432</p> - <p>Aux Id: Seq 10966</p> - </item> - - </list> - --> - - </section> - - <section> - <title>Incompatibilities</title> - <p>-</p> - </section> - </section> <!-- 4.12 --> - - <section> - <title>SNMP Development Toolkit 4.11.2</title> - <p>Version 4.11.2 supports code replacement in runtime from/to - version 4.11.1 and 4.11. </p> - - <section> - <title>Improvements and new features</title> - <p>-</p> - <!-- - <list type="bulleted"> - <item> - <p>Added utility functions for transforming DateAndTime - as [int()] to strings; - <seealso marker="snmp#dat2s">date_and_time_to_string/2</seealso> - and - <seealso marker="snmp#dat2s2">date_and_time_to_string2/1</seealso>. </p> - <p>Also added new validation function - <seealso marker="snmp#vdat">validate_date_and_time/2</seealso>. </p> - <p>Own Id: OTP-7412</p> - <p>Aux Id: Seq 10987</p> - </item> - </list> - --> - </section> - - <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <!-- - <p>-</p> - --> - <list type="bulleted"> - <item> - <p>[manager] Erroneous engine-id check when receiving version 3 - informs. </p> - <p>Own Id: OTP-7570</p> - <p>Aux Id: Seq 11060</p> - </item> - - <item> - <p>Receiving an snmp message with a very large version - number could cause the erlang node to run out of - memory and consequently crash. </p> - <p>The standard specifies the snmp version as an - (unlimited) INTEGER, but today only - 0 (version 1), 1 (version 2) and 3 (version 3) is - actually used. So, when decoding a message, a limit - has been put on the snmp version integer in order - to not allow this kind of a problem. </p> - <p>Own Id: OTP-7575</p> - <p>Aux Id: Seq 11064</p> - </item> - - </list> - </section> - - <section> - <title>Incompatibilities</title> - <p>-</p> - </section> - </section> <!-- 4.11.2 --> - - - <section> - <title>SNMP Development Toolkit 4.11.1</title> - <p>Version 4.11.1 supports code replacement in runtime from/to - version 4.11.</p> - - <section> - <title>Improvements and new features</title> - <!-- - <p>-</p> - --> - <list type="bulleted"> - <item> - <p>[compiler] The MIB compiler did not retrieve the REFERENCE part - of a SNMP MIB definition. </p> - <p>This problem has been partly solved. For SNMP tables, - the assocList field of the tables mib-entry record now contains - this info (as <c>{reference, string()}</c>), <em>if</em> the - MIB was compiled with the compiler option <em>+reference</em>. </p> - <p>This solution is temporary, until such time as a permanent - solution (and probably not backward compatible) is devised, which - retrieves and stores all REFERENCE part(s) of a MIB. </p> - <p>See the - <seealso marker="snmpc#compiler_opts">compiler options</seealso> - for more info. </p> - - <p>Serge Aleynikov</p> - <p>Own Id: OTP-7426</p> - </item> - - <item> - <p>Added utility functions for transforming DateAndTime - as [int()] to strings; - <seealso marker="snmp#dat2s">date_and_time_to_string/2</seealso> - and - <seealso marker="snmp#dat2s2">date_and_time_to_string2/1</seealso>. </p> - <p>Also added new validation function - <seealso marker="snmp#vdat">validate_date_and_time/2</seealso>. </p> - <p>Own Id: OTP-7412</p> - <p>Aux Id: Seq 10987</p> - </item> - - </list> - - </section> - - <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <!-- - <p>-</p> - --> - <list type="bulleted"> - <item> - <p>[manager] Encryption error when attempting to send - version 3 inform-requests. </p> - <p>Own Id: OTP-7432</p> - <p>Aux Id: Seq 10966</p> - </item> - - </list> - </section> - - <section> - <title>Incompatibilities</title> - <p>-</p> - </section> - </section> <!-- 4.11.1 --> - - <section> - <title>SNMP Development Toolkit 4.11</title> - <p>Version 4.11 supports code replacement in runtime from/to - version 4.10.3, 4.10.2, 4.10.1 and 4.10.</p> - - <section> - <title>Improvements and new features</title> - <!-- - <p>-</p> - --> - <list type="bulleted"> - <item> - <p>[agent] Performance improvements in the case when an SNMP - manager performs an snmpwalk. </p> - <p>Martin Björklund</p> - <p>Own Id: OTP-7201</p> - </item> - - <item> - <p>The API for sending inform(s) has been improved. Also - the documentation has been corrected and updated. See - <seealso marker="snmpa#send_notification">snmpa:send_notification</seealso> and - <seealso marker="snmpa_notification_delivery_info_receiver">snmpa_notification_delivery_info_receiver</seealso> - for more info.</p> - <p>Own Id: OTP-7287</p> - <p>Aux Id: Seq 10926</p> - </item> - - <item> - <p>[agent] Performance of the internal database (local-db) - has been improved.</p> - <p>Own Id: OTP-7319</p> - <p>Aux Id: Seq 10942</p> - </item> - - <item> - <p>[agent] Added utility functions, - <seealso marker="snmpa#restart_worker">snmpa:restart_worker/0,1</seealso> and - <seealso marker="snmpa#restart_set_worker">snmpa:restart_set_worker/0,1</seealso>, - for restarting the agent worker processes (in case the agent is - multi-threaded).</p> - <p>Own Id: OTP-7369</p> - </item> - - <item> - <p>Add utility function to - <seealso marker="snmp#read_mib">read</seealso> - a compiled mib. </p> - <p>Own Id: OTP-7371</p> - </item> - - </list> - </section> - - <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <!-- - <p>-</p> - --> - <list type="bulleted"> - <item> - <p>[manager] Encryption error when attempting to send - version 3 inform-requests. </p> - <p>Own Id: OTP-7377</p> - <p>Aux Id: Seq 10966</p> - </item> - - </list> - </section> - - <section> - <title>Incompatibilities</title> - <p>-</p> - </section> - </section> <!-- 4.11 --> - <!-- section> <title>Release notes history</title> <p>For information about older versions see diff --git a/lib/snmp/doc/src/notes_history.xml b/lib/snmp/doc/src/notes_history.xml index 934df87866..722d02afbd 100644 --- a/lib/snmp/doc/src/notes_history.xml +++ b/lib/snmp/doc/src/notes_history.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE chapter SYSTEM "chapter.dtd"> <chapter> @@ -33,6 +33,928 @@ </header> <section> + <title>SNMP Development Toolkit 4.14</title> + + <p>Version 4.14 supports code replacement in runtime from/to + version 4.13.5, 4.13.4, 4.13.3, 4.13.2, 4.13.1 and 4.13.</p> + + <section> + <title>Improvements and new features</title> + <!-- + <p>-</p> + --> + + <list type="bulleted"> + <item> + <p>[compiler] Include object- and notification groups in the + compiled mib. + This will make it possible to import groups from other mibs. </p> + <p>Also the SNMPv2-MIB-file has been updated to a more + up-to-date version. </p> + <p>Own Id: OTP-8223</p> + <!-- <p>Aux Id: Seq 11383</p> --> + </item> + + <item> + <p>[manager] Added support for message filtering in the + network interface module provided with the application. + The component that actually make the filter decisions + is the network interface filter module. This module + must implement the + <seealso marker="snmpm_network_interface_filter">network interface filter behaviour</seealso> + for message filtering. + See also the Configuring chapter of + the User's Guide to see how to configure this feature. </p> + <p>See the + <seealso marker="snmp_app#configuration_params">configuration</seealso> + chapter for more info about the filter options.</p> + <p>Own Id: OTP-8228</p> + <p>Aux Id: Seq 11411</p> + </item> + + <item> + <p>The MIBs delivered as part of the application is now + also available as man pages, section 7. </p> + <p>Own Id: OTP-8237</p> + <!-- <p>Aux Id: Seq 11383</p> --> + </item> + + </list> + + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <p>-</p> + + <!-- + <list type="bulleted"> + <item> + <p>[agent] The main agent type header file contained some miss-information + regarding the type of the entrytype field of the me-record, causing + unneccessary confusion.</p> + <p>Own Id: OTP-8116</p> + <p>Aux Id: Seq 11312</p> + </item> + + </list> + --> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.14 --> + + + <section> + <title>SNMP Development Toolkit 4.13.5</title> + + <p>Version 4.13.5 supports code replacement in runtime from/to + version 4.13.4, 4.13.3, 4.13.2, 4.13.1 and 4.13.</p> + + <section> + <title>Improvements and new features</title> + <!-- + <p>-</p> + --> + + <list type="bulleted"> + <item> + <p>[agent] Improved the cache handling of the mib server. </p> + <p>A number of new functions and config options for the mib server + cache has been added. </p> + <p>See + <seealso marker="snmpa#invalidate_mibs_cache">invalidate_mibs_cache/0,1</seealso>, + <seealso marker="snmpa#enable_mibs_cache">enable_mibs_cache/0,1</seealso>, + <seealso marker="snmpa#disable_mibs_cache">disable_mibs_cache/0,1</seealso>, + <seealso marker="snmpa#gc_mibs_cache">gc_mibs_cache/0,1,2,3</seealso>, + <seealso marker="snmpa#enable_mibs_cache_autogc">enable_mibs_cache_autogc/0,1</seealso>, + <seealso marker="snmpa#disable_mibs_cache_autogc">disable_mibs_cache_autogc/0,1</seealso>, + <seealso marker="snmpa#update_mibs_cache_age">update_mibs_cache_age/1,2</seealso> and + <seealso marker="snmpa#update_mibs_cache_gclimit">update_mibs_cache_gclimit/1,2</seealso> for more info. </p> + <p>See also the + <seealso marker="snmp_app#configuration_params">configuration</seealso> + chapter for more info about the mib server cache options.</p> + <p>Own Id: OTP-8182</p> + <p>Aux Id: Seq 11383</p> + </item> + + <item> + <p>[agent] A manager could no longer use the SNMPv3 user "initial" + as this was interpretated as the first step of the discovery. </p> + <p>Introduced a new terminating option, <c>trigger_username</c> to + make it possible to configure the username the agent reacts to. + Default is <c>""</c>. </p> + <p>See the + <seealso marker="snmp_app#configuration_params">configuration</seealso> + chapter for more info about the discovery options.</p> + <p>Own Id: OTP-8120</p> + <p>Aux Id: Seq 11361</p> + </item> + + </list> + + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[agent] The main agent type header file contained some miss-information + regarding the type of the entrytype field of the me-record, causing + unneccessary confusion.</p> + <p>Own Id: OTP-8116</p> + <p>Aux Id: Seq 11312</p> + </item> + + </list> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.13.5 --> + + + <section> + <title>SNMP Development Toolkit 4.13.4</title> + + <p>Version 4.13.4 supports code replacement in runtime from/to + version 4.13.3, 4.13.2, 4.13.1 and 4.13.</p> + + <section> + <title>Improvements and new features</title> + <p>-</p> + + <!-- + <list type="bulleted"> + <item> + <p>[agent] Support for the discovery process. </p> + <p>The agent can both initiate discovery itself (see the + <seealso marker="snmp_agent_funct_descr#discovery">discovery</seealso> chapter + for more info) and respond to discovery initiated by a manager.</p> + <p>Own Id: OTP-7571</p> + <p>Aux Id: Seq 11053</p> + </item> + + </list> + --> + + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[agent] Originating discovery problems. </p> + <p>Invalid state variable update during second stage of + discovery causes master agent crash. </p> + <p>Also the net_if process failed to activate socket + ({active, once}) after first discovery response was sent. </p> + <p>Own Id: OTP-8044</p> + <p>Aux Id: Seq 11295</p> + </item> + + <item> + <p>[agent] Terminating discovery problem. </p> + <p>The reply to the second stage request should include a + varbind with <c>usmStatsNotInTimeWindows</c>.</p> + <p>Own Id: OTP-8062</p> + <p>Aux Id: Seq 11318</p> + </item> + + <item> + <p>[agent] Originating discovery improvement. </p> + <p>Added the ExtraInfo argument to the + <seealso marker="snmpa#discovery">discovery</seealso> function. + This argument will be passed on to the stage1_finish callback + function. Also, the + <seealso marker="snmpa#discovery">discovery</seealso> function + will now always return <c>{ok, ManagerEngineID}</c> on successful + discovery. </p> + <p>The <seealso marker="snmpa_discovery_handler">discovery handler</seealso> + behaviour updated accordingly. </p> + <p>Own Id: OTP-8098</p> + <p>Aux Id: Seq 11346</p> + </item> + + </list> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.13.4 --> + + + <section> + <title>SNMP Development Toolkit 4.13.3</title> + + <p>Version 4.13.3 supports code replacement in runtime from/to + version 4.13.2, 4.13.1 and 4.13.</p> + + <section> + <title>Improvements and new features</title> + <p>-</p> + + <!-- + <list type="bulleted"> + <item> + <p>[agent] Support for the discovery process. </p> + <p>The agent can both initiate discovery itself (see the + <seealso marker="snmp_agent_funct_descr#discovery">discovery</seealso> chapter + for more info) and respond to discovery initiated by a manager.</p> + <p>Own Id: OTP-7571</p> + <p>Aux Id: Seq 11053</p> + </item> + + </list> + --> + + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[manager] A request for an oid of type BITS was actually + returned as OCTET STRING. </p> + <p>Values of type BITS are encoded as OCTET STRING, + which makes it impossible for the decoder to know that + they should really be of type BITS. + Instead, this has to be done higher up in the stack, where + there is knowledge of the MIB (assuming that the mib has + been loaded, there is info about the type of the mibentry). </p> + <p>This problem has now been fixed, but requires that the MIB + defining this mib-entry is loaded! </p> + <p>The utility function + <seealso marker="snmpm#oid_to_type">oid_to_type</seealso> + has been added, for debug purpose. </p> + <p>The utility function(s) + <seealso marker="snmp#octet_string_to_bits">octet_string_to_bits</seealso> + and + <seealso marker="snmp#bits_to_octet_string">bits_to_octet_string</seealso> + has also been added. These can be used if the user prefers to + handle the conversion on their own. </p> + <p>Own Id: OTP-8015</p> + <p>Aux Id: Seq 11285</p> + </item> + + <item> + <p>[agent] Fixed some issues with the discovery handling. </p> + <p>Changed the API of the + <seealso marker="snmpa#discovery">discovery</seealso> + function to solve some + of these problems. </p> + <p>Introduced various options for controlling the discovery + process. See the + <seealso marker="snmp_app#configuration_params">configuration</seealso> + chapter for more info about the discovery options.</p> + <p>Own Id: OTP-8020</p> + <p>Aux Id: Seq 11295</p> + </item> + + </list> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.13.3 --> + + + <section> + <title>SNMP Development Toolkit 4.13.2</title> + + <p>Version 4.13.2 supports code replacement in runtime from/to + version 4.13.1 and 4.13.</p> + + <section> + <title>Improvements and new features</title> + <p>-</p> + + <!-- + <list type="bulleted"> + <item> + <p>[agent] Support for the discovery process. </p> + <p>The agent can both initiate discovery itself (see the + <seealso marker="snmp_agent_funct_descr#discovery">discovery</seealso> chapter + for more info) and respond to discovery initiated by a manager.</p> + <p>Own Id: OTP-7571</p> + <p>Aux Id: Seq 11053</p> + </item> + + </list> + --> + + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[manager] Failure during downed user cleanup. + As part of the cleanup after a crashed user, + the manager attempts to unregister the agents + registered by this user. This however failed, + causing a server crash. </p> + <p>Own Id: OTP-7961</p> + <p>Aux Id: Seq 11275</p> + </item> + + <item> + <p>[manager] Incorrectly documented value type for + IpAddress (ip). The value type for IpAddress is + documented as ip but is actually ia. The value type + ip has been added. The old (not documented) value + type ia still works. </p> + <p>Own Id: OTP-7977</p> + <p>Aux Id: Seq 11279</p> + </item> + + <item> + <p>[manager] EngineId lookup fails when using version-3. </p> + <p>Own Id: OTP-7983</p> + <p>Aux Id: Seq 11275</p> + </item> + + <item> + <p>[agent] As of version 4.13 the possible return values + of the function + <seealso marker="snmpa_mpd#process_packet">snmpa_mpd:process_packet/4</seealso> + changed, but this was not documented. </p> + <p>Own Id: OTP-7989</p> + <p>Aux Id: Seq 11275</p> + </item> + + </list> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.13.2 --> + + <section> + <title>SNMP Development Toolkit 4.13.1</title> + + <p>Version 4.13.1 supports code replacement in runtime from/to + version 4.13.</p> + + <section> + <title>Improvements and new features</title> + <p>-</p> + + <!-- + <list type="bulleted"> + <item> + <p>[agent] Support for the discovery process. </p> + <p>The agent can both initiate discovery itself (see the + <seealso marker="snmp_agent_funct_descr#discovery">discovery</seealso> chapter + for more info) and respond to discovery initiated by a manager.</p> + <p>Own Id: OTP-7571</p> + <p>Aux Id: Seq 11053</p> + </item> + + </list> + --> + + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[manager] Registration of users had some issues. </p> + <p>Not all of the registration functions where actually exported + (<seealso marker="snmpm#register_user">register_user/4</seealso> + and + <seealso marker="snmpm#register_user_monitor">register_user_monitor/4</seealso>). + This has now been fixed. </p> + <p>Also, the registration did not succeed unless + user implemented the *new* behaviour. This has now + also been fixed (registration succeeds if the user + implements either the new (i.e. updated + <seealso marker="snmpm_user">snmpm_user</seealso>) + or the old user behaviour (<c>snmpm_user_old</c>)). </p> + <p>Own Id: OTP-7902</p> + <p>Aux Id: Seq 11240</p> + </item> + + </list> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.13.1 --> + + <section> + <title>SNMP Development Toolkit 4.13</title> +<!-- + <p>Version 4.13 supports code replacement in runtime from/to + version 4.12.1.</p> +--> + + <section> + <title>Improvements and new features</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[agent] Support for the discovery process. </p> + <p>The agent can both initiate discovery itself (see the + <seealso marker="snmp_agent_funct_descr#discovery">discovery</seealso> chapter + for more info) and respond to discovery initiated by a manager.</p> + <p>Own Id: OTP-7571</p> + <p>Aux Id: Seq 11053</p> + </item> + + </list> + + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[agent] Unnecessary use of math:pow/2 could cause problems + on systems without floating point support. </p> + <p>Per Hedeland</p> + <p>Own Id: OTP-7735</p> + <!-- <p>Aux Id: Seq 10966</p> --> + </item> + + <item> + <p>[manager] A major flaw was discovered with the agent handling. </p> + <p>First, <c>TargetName</c> was never used as intended, as a unique + identifier for the target (agent in this case). </p> + <p>Second, <c>TargetName</c> had a <em>default value</em>, which meant + that several agents could have the same <c>TargetName</c>, causing + unpredictable behaviour in the manager. </p> + <p>Third, <c>EngineID</c> was not a mandatory config option and had + furthermore also a <em>default value</em>. </p> + + <p>These problems has been solved in the following way: </p> + <p>First, a new set of api functions has been introduced (and documented): + <seealso marker="snmpm#register_user">register_user/4</seealso>, + <seealso marker="snmpm#register_user_monitor">register_user_monitor/4</seealso>, + <seealso marker="snmpm#register_agent">register_agent/3</seealso>, + <seealso marker="snmpm#unregister_agent">unregister_agent/2</seealso>, + <seealso marker="snmpm#agent_info">agent_info/2</seealso>, + <seealso marker="snmpm#update_agent_info">update_agent_info/4</seealso>, + <seealso marker="snmpm#sync_get">sync_get/3,4,5,6</seealso>, + <seealso marker="snmpm#async_get">async_get/3,4,5,6</seealso>, + <seealso marker="snmpm#sync_get_next">sync_get_next/3,4,5,6</seealso>, + <seealso marker="snmpm#async_get_next">async_get_next/3,4,5,6</seealso>, + <seealso marker="snmpm#sync_set">sync_set/3,4,5,6</seealso>, + <seealso marker="snmpm#async_set">async_set/3,4,5,6</seealso>, + <seealso marker="snmpm#sync_get_bulk">sync_get_bulk/5,6,7,8</seealso> and + <seealso marker="snmpm#async_get_bulk">async_get_bulk/5,6,7,8</seealso> + that all use <c>TargetName</c> (and not, as previously, <c>Addr</c> + and <c>Port</c>) to identify the agent (also the return value of + <seealso marker="snmpm#which_agents">which_agents</seealso> has + been changed). </p> + <p>Second, for backward compatibility, the old functions still + exist, but are no longer documented and are now wrappers for the + new functions, including erroneous default value for EngineID and + all. The TargetName is however generated from the provided + <c>Addr</c>, <c>Port</c> and <c>Version</c> config options. </p> + <p>Third, the behaviour of the + <seealso marker="snmpm_user">SNMP manager user</seealso> has + been changed to reflect this, i.e. + <seealso marker="snmpm_user#handle_pdu">handle_pdu/4</seealso>, + <seealso marker="snmpm_user#handle_trap">handle_trap/3</seealso>, + <seealso marker="snmpm_user#handle_inform">handle_inform/3</seealso>, + <seealso marker="snmpm_user#handle_report">handle_report/3</seealso> + and the return-value of + <seealso marker="snmpm_user#handle_agent">handle_agent/4</seealso>. + The old (non-documented) callback-functions (using Addr and Port) + will still be called if the agent was registered using the old + registration functions. </p> + + <p>Own Id: OTP-7836</p> + <!-- <p>Aux Id: Seq 10966</p> --> + </item> + + </list> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.13 --> + + <section> + <title>SNMP Development Toolkit 4.12.2</title> + <p>Version 4.12.2 supports code replacement in runtime from/to + version 4.12.1, 4.12, 4.11.2, 4.11.1 and 4.11.</p> + + <section> + <title>Improvements and new features</title> + <p>-</p> + <!-- + <list type="bulleted"> + <item> + <item> + <p>[agent] Improvement of the inform reporting. + It was previously not certain how many acks an + application received, 0, 1 or 2. This has now been + fixed, so that only 1 (one) ack is issued. </p> + <p>Per Hedeland</p> + <p>Own Id: OTP-7525</p> + </item> + + </list> + --> + + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[agent] Bad session cache (usm+camv-info) invalidation + could cause user crash, through call(s) to (a number of) + MIB API function(s) (undefined function). </p> + <p>Own Id: OTP-7868</p> + <!-- <p>Aux Id: Seq 11124</p> --> + </item> + + </list> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.12.2 --> + + <section> + <title>SNMP Development Toolkit 4.12.1</title> + <p>Version 4.12.1 supports code replacement in runtime from/to + version 4.12, 4.11.2, 4.11.1 and 4.11.</p> + + <section> + <title>Improvements and new features</title> + <p>-</p> + <!-- + <list type="bulleted"> + <item> + <item> + <p>[agent] Improvement of the inform reporting. + It was previously not certain how many acks an + application received, 0, 1 or 2. This has now been + fixed, so that only 1 (one) ack is issued. </p> + <p>Per Hedeland</p> + <p>Own Id: OTP-7525</p> + </item> + + </list> + --> + + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>Logging of messages with the GetBulk-request PDU + incorrectly produced an erroneous entry in the + log: "An error occurred". </p> + <p>The reason for this was that the PDU-fields + error_status and error_index is re-used for + Non-repeaters and Max-repetitions for + GetBulk-request PDUs, but this was not handled + by the logging code. </p> + <p>Own Id: OTP-7695</p> + <p>Aux Id: Seq 11124</p> + </item> + + <item> + <p>[agent] An attempt to set the row status to active for an + notReady table row, could result in an "inconsistentValue" + error. </p> + <p>The same problem existed when attempting to set row status + to notInService for a row in notReady. </p> + <p>Serge Aleynikov</p> + <p>Own Id: OTP-7698</p> + <!-- <p>Aux Id: Seq 10966</p> --> + </item> + + </list> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.12.1 --> + + <section> + <title>SNMP Development Toolkit 4.12</title> + <p>Version 4.12 supports code replacement in runtime from/to + version 4.11.2, 4.11.1 and 4.11.</p> + + <section> + <title>Improvements and new features</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[agent] A simple lookup cache has been added to improve + the mib server lookup performance. </p> + <p>This can be disabled with the mib_server + <seealso marker="snmp_app">cache</seealso> option. </p> + <p>Own Id: OTP-7346</p> + </item> + + <item> + <p>[agent] Improvement of the inform reporting. + It was previously not certain how many acks an + application received, 0, 1 or 2. This has now been + fixed, so that only 1 (one) ack is issued. </p> + <p>Per Hedeland</p> + <p>Own Id: OTP-7525</p> + </item> + + </list> + + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <p>-</p> + <!-- + <list type="bulleted"> + <item> + <p>[manager] Encryption error when attempting to send + version 3 inform-requests. </p> + <p>Own Id: OTP-7432</p> + <p>Aux Id: Seq 10966</p> + </item> + + </list> + --> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.12 --> + + <section> + <title>SNMP Development Toolkit 4.11.2</title> + <p>Version 4.11.2 supports code replacement in runtime from/to + version 4.11.1 and 4.11. </p> + + <section> + <title>Improvements and new features</title> + <p>-</p> + <!-- + <list type="bulleted"> + <item> + <p>Added utility functions for transforming DateAndTime + as [int()] to strings; + <seealso marker="snmp#dat2s">date_and_time_to_string/2</seealso> + and + <seealso marker="snmp#dat2s2">date_and_time_to_string2/1</seealso>. </p> + <p>Also added new validation function + <seealso marker="snmp#vdat">validate_date_and_time/2</seealso>. </p> + <p>Own Id: OTP-7412</p> + <p>Aux Id: Seq 10987</p> + </item> + </list> + --> + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[manager] Erroneous engine-id check when receiving version 3 + informs. </p> + <p>Own Id: OTP-7570</p> + <p>Aux Id: Seq 11060</p> + </item> + + <item> + <p>Receiving an snmp message with a very large version + number could cause the erlang node to run out of + memory and consequently crash. </p> + <p>The standard specifies the snmp version as an + (unlimited) INTEGER, but today only + 0 (version 1), 1 (version 2) and 3 (version 3) is + actually used. So, when decoding a message, a limit + has been put on the snmp version integer in order + to not allow this kind of a problem. </p> + <p>Own Id: OTP-7575</p> + <p>Aux Id: Seq 11064</p> + </item> + + </list> + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.11.2 --> + + + <section> + <title>SNMP Development Toolkit 4.11.1</title> + <p>Version 4.11.1 supports code replacement in runtime from/to + version 4.11.</p> + + <section> + <title>Improvements and new features</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[compiler] The MIB compiler did not retrieve the REFERENCE part + of a SNMP MIB definition. </p> + <p>This problem has been partly solved. For SNMP tables, + the assocList field of the tables mib-entry record now contains + this info (as <c>{reference, string()}</c>), <em>if</em> the + MIB was compiled with the compiler option <em>+reference</em>. </p> + <p>This solution is temporary, until such time as a permanent + solution (and probably not backward compatible) is devised, which + retrieves and stores all REFERENCE part(s) of a MIB. </p> + <p>See the + <seealso marker="snmpc#compiler_opts">compiler options</seealso> + for more info. </p> + + <p>Serge Aleynikov</p> + <p>Own Id: OTP-7426</p> + </item> + + <item> + <p>Added utility functions for transforming DateAndTime + as [int()] to strings; + <seealso marker="snmp#dat2s">date_and_time_to_string/2</seealso> + and + <seealso marker="snmp#dat2s2">date_and_time_to_string2/1</seealso>. </p> + <p>Also added new validation function + <seealso marker="snmp#vdat">validate_date_and_time/2</seealso>. </p> + <p>Own Id: OTP-7412</p> + <p>Aux Id: Seq 10987</p> + </item> + + </list> + + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[manager] Encryption error when attempting to send + version 3 inform-requests. </p> + <p>Own Id: OTP-7432</p> + <p>Aux Id: Seq 10966</p> + </item> + + </list> + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.11.1 --> + + <section> + <title>SNMP Development Toolkit 4.11</title> + <p>Version 4.11 supports code replacement in runtime from/to + version 4.10.3, 4.10.2, 4.10.1 and 4.10.</p> + + <section> + <title>Improvements and new features</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[agent] Performance improvements in the case when an SNMP + manager performs an snmpwalk. </p> + <p>Martin Björklund</p> + <p>Own Id: OTP-7201</p> + </item> + + <item> + <p>The API for sending inform(s) has been improved. Also + the documentation has been corrected and updated. See + <seealso marker="snmpa#send_notification">snmpa:send_notification</seealso> and + <seealso marker="snmpa_notification_delivery_info_receiver">snmpa_notification_delivery_info_receiver</seealso> + for more info.</p> + <p>Own Id: OTP-7287</p> + <p>Aux Id: Seq 10926</p> + </item> + + <item> + <p>[agent] Performance of the internal database (local-db) + has been improved.</p> + <p>Own Id: OTP-7319</p> + <p>Aux Id: Seq 10942</p> + </item> + + <item> + <p>[agent] Added utility functions, + <seealso marker="snmpa#restart_worker">snmpa:restart_worker/0,1</seealso> and + <seealso marker="snmpa#restart_set_worker">snmpa:restart_set_worker/0,1</seealso>, + for restarting the agent worker processes (in case the agent is + multi-threaded).</p> + <p>Own Id: OTP-7369</p> + </item> + + <item> + <p>Add utility function to + <seealso marker="snmp#read_mib">read</seealso> + a compiled mib. </p> + <p>Own Id: OTP-7371</p> + </item> + + </list> + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[manager] Encryption error when attempting to send + version 3 inform-requests. </p> + <p>Own Id: OTP-7377</p> + <p>Aux Id: Seq 10966</p> + </item> + + </list> + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.11 --> + + + <section> <title>SNMP Development Toolkit 4.10.3</title> <p>Version 4.10.3 supports code replacement in runtime from/to version 4.10.2, 4.10.1 and 4.10.</p> diff --git a/lib/snmp/priv/plt/.gitignore b/lib/snmp/priv/plt/.gitignore new file mode 100644 index 0000000000..174481f561 --- /dev/null +++ b/lib/snmp/priv/plt/.gitignore @@ -0,0 +1,3 @@ +/*.plt +/*.dialyzer_analysis + diff --git a/lib/snmp/src/agent/snmpa_agent.erl b/lib/snmp/src/agent/snmpa_agent.erl index 6322f0f21d..46c634969d 100644 --- a/lib/snmp/src/agent/snmpa_agent.erl +++ b/lib/snmp/src/agent/snmpa_agent.erl @@ -558,25 +558,6 @@ send_trap(Agent, Trap, NotifyName, CtxName, Recv, Varbinds) -> ], send_notification(Agent, Trap, SendOpts). -%% send_trap(Agent, Trap, NotifyName, CtxName, Recv, Varbinds) -> -%% ?d("send_trap -> entry with" -%% "~n self(): ~p" -%% "~n Agent: ~p [~p]" -%% "~n Trap: ~p" -%% "~n NotifyName: ~p" -%% "~n CtxName: ~p" -%% "~n Recv: ~p" -%% "~n Varbinds: ~p", -%% [self(), Agent, wis(Agent), -%% Trap, NotifyName, CtxName, Recv, Varbinds]), -%% Msg = {send_trap, Trap, NotifyName, CtxName, Recv, Varbinds}, -%% case (wis(Agent) =:= self()) of -%% false -> -%% call(Agent, Msg); -%% true -> -%% Agent ! Msg -%% end. - send_trap(Agent, Trap, NotifyName, CtxName, Recv, Varbinds, LocalEngineID) -> ?d("send_trap -> entry with" "~n self(): ~p" @@ -599,27 +580,6 @@ send_trap(Agent, Trap, NotifyName, CtxName, Recv, Varbinds, LocalEngineID) -> ], send_notification(Agent, Trap, SendOpts). -%% send_trap(Agent, Trap, NotifyName, CtxName, Recv, Varbinds, LocalEngineID) -> -%% ?d("send_trap -> entry with" -%% "~n self(): ~p" -%% "~n Agent: ~p [~p]" -%% "~n Trap: ~p" -%% "~n NotifyName: ~p" -%% "~n CtxName: ~p" -%% "~n Recv: ~p" -%% "~n Varbinds: ~p" -%% "~n LocalEngineID: ~p", -%% [self(), Agent, wis(Agent), -%% Trap, NotifyName, CtxName, Recv, Varbinds, LocalEngineID]), -%% Msg = -%% {send_trap, Trap, NotifyName, CtxName, Recv, Varbinds, LocalEngineID}, -%% case (wis(Agent) =:= self()) of -%% false -> -%% call(Agent, Msg); -%% true -> -%% Agent ! Msg -%% end. - %% </BACKWARD-COMPAT> @@ -709,11 +669,6 @@ wis(Atom) when is_atom(Atom) -> whereis(Atom). -forward_trap(Agent, TrapRecord, NotifyName, CtxName, Recv, Varbinds) -> - ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO, - forward_trap(Agent, TrapRecord, NotifyName, CtxName, Recv, Varbinds, - ExtraInfo). - forward_trap(Agent, TrapRecord, NotifyName, CtxName, Recv, Varbinds, ExtraInfo) -> Agent ! {forward_trap, TrapRecord, NotifyName, CtxName, Recv, Varbinds, @@ -808,11 +763,11 @@ handle_info(worker_available, S) -> {noreply, S#state{worker_state = ready}}; handle_info({send_notif, Notification, SendOpts}, S) -> - ?vlog("[handle_info] send trap request:" + ?vlog("[handle_info] send notif request:" "~n Notification: ~p" "~n SendOpts: ~p", [Notification, SendOpts]), - case (catch handle_send_trap(cast, S, Notification, SendOpts)) of + case (catch handle_send_trap(S, Notification, SendOpts)) of {ok, NewS} -> {noreply, NewS}; {'EXIT', R} -> @@ -832,7 +787,7 @@ handle_info({send_trap, Trap, NotifyName, ContextName, Recv, Varbinds}, S) -> "~n Varbinds: ~p", [Trap, NotifyName, ContextName, Recv, Varbinds]), ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO, - LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID, + LocalEngineID = local_engine_id(S), case (catch handle_send_trap(S, Trap, NotifyName, ContextName, Recv, Varbinds, LocalEngineID, ExtraInfo)) of {ok, NewS} -> @@ -1014,11 +969,11 @@ handle_call(restart_set_worker, _From, #state{set_worker = Pid} = S) -> {reply, ok, S}; handle_call({send_notif, Notification, SendOpts}, _From, S) -> - ?vlog("[handle_info] send trap request:" + ?vlog("[handle_call] send notif request:" "~n Notification: ~p" "~n SendOpts: ~p", [Notification, SendOpts]), - case (catch handle_send_trap(call, S, Notification, SendOpts)) of + case (catch handle_send_trap(S, Notification, SendOpts)) of {ok, NewS} -> {reply, ok, NewS}; {'EXIT', Reason} -> @@ -1039,18 +994,8 @@ handle_call({send_trap, Trap, NotifyName, ContextName, Recv, Varbinds}, "~n Recv: ~p" "~n Varbinds: ~p", [Trap, NotifyName, ContextName, Recv, Varbinds]), - ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO, - LocalEngineID = - case S#state.type of - master_agent -> - ?DEFAULT_LOCAL_ENGINE_ID; - _ -> - %% subagent - - %% we don't need this now, eventually the trap send - %% request will reach the master-agent and then it - %% will look up the proper engine id. - ignore - end, + ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO, + LocalEngineID = local_engine_id(S), case (catch handle_send_trap(S, Trap, NotifyName, ContextName, Recv, Varbinds, LocalEngineID, ExtraInfo)) of {ok, NewS} -> @@ -1595,7 +1540,7 @@ handle_backup_res([{Who, Crap}|Results], Acc) -> %% because we (for some reason) support the function %% snmpa:current_community(). %%----------------------------------------------------------------- -cheat({community, SecModel, Community, _TAddress}, Address, ContextName) -> +cheat({community, _SecModel, Community, _TAddress}, Address, ContextName) -> {Community, Address, ContextName}; cheat({community, _SecModel, Community, _TDomain, _TAddress}, Address, ContextName) -> @@ -1859,7 +1804,7 @@ handle_acm_error(Vsn, Reason, Pdu, ACMData, Address, Extra) -> ok end. -get_opt(Key, Default, SendOpts) -> +get_send_opt(Key, Default, SendOpts) -> case lists:keysearch(Key, 1, SendOpts) of {value, {Key, Value}} -> Value; @@ -1867,40 +1812,19 @@ get_opt(Key, Default, SendOpts) -> Default end. -handle_send_trap(call, #state{type = master_agent} = S, - Notification, SendOpts) -> - SendOpts2 = - case lists:keymember(local_engine_id, 1, SendOpts) of - true -> - SendOpts; - false -> - [{local_engine_id, ?DEFAULT_LOCAL_ENGINE_ID}|SendOpts] - end, - handle_send_trap(S, Notification, SendOpts2); -handle_send_trap(call, S, Notification, SendOpts) -> - SendOpts2 = - case lists:keymember(local_engine_id, 1, SendOpts) of - true -> - SendOpts; - false -> - %% subagent - - %% we don't need this now, eventually the trap send - %% request will reach the master-agent and then it - %% will look up the proper engine id. - [{local_engine_id, ignore}|SendOpts] - end, - handle_send_trap(S, Notification, SendOpts2); -handle_send_trap(_, S, Notification, SendOpts) -> - handle_send_trap(S, Notification, SendOpts). - handle_send_trap(S, Notification, SendOpts) -> - NotifyName = get_opt(name, "", SendOpts), - ContextName = get_opt(context, "", SendOpts), - Recv = get_opt(receiver, no_receiver, SendOpts), - Varbinds = get_opt(varbinds, [], SendOpts), - ExtraInfo = get_opt(extra, ?DEFAULT_NOTIF_EXTRA_INFO, SendOpts), + NotifyName = get_send_opt(name, "", SendOpts), + ContextName = get_send_opt(context, "", SendOpts), + Recv = get_send_opt(receiver, no_receiver, SendOpts), + Varbinds = get_send_opt(varbinds, [], SendOpts), + ExtraInfo = get_send_opt(extra, ?DEFAULT_NOTIF_EXTRA_INFO, SendOpts), LocalEngineID = - get_opt(local_engine_id, ?DEFAULT_LOCAL_ENGINE_ID, SendOpts), + case lists:keysearch(local_engine_id, 1, SendOpts) of + {value, {local_engine_id, Value}} -> + Value; + false -> + local_engine_id(S) + end, handle_send_trap(S, Notification, NotifyName, ContextName, Recv, Varbinds, LocalEngineID, ExtraInfo). @@ -1908,11 +1832,11 @@ handle_send_trap(#state{type = Type} = S, Notification, NotifyName, ContextName, Recv, Varbinds, LocalEngineID, ExtraInfo) -> ?vtrace("handle_send_trap -> entry with" - "~n Agent type: ~p" - "~n TrapName: ~p" - "~n NotifyName: ~p" - "~n ContextName: ~p" - "~n LocalEngineID: ~p", + "~n Agent type: ~p" + "~n TrapName: ~p" + "~n NotifyName: ~p" + "~n ContextName: ~p" + "~n LocalEngineID: ~p", [Type, Notification, NotifyName, ContextName, LocalEngineID]), case snmpa_trap:construct_trap(Notification, Varbinds) of {ok, TrapRecord, VarList} -> @@ -4001,6 +3925,18 @@ subagents_verbosity(_,_V) -> %% --------------------------------------------------------------------- +local_engine_id(#state{type = master_agent}) -> + ?DEFAULT_LOCAL_ENGINE_ID; +local_engine_id(_) -> + %% subagent - + %% we don't need this now, eventually the trap send + %% request will reach the master-agent and then it + %% will look up the proper engine id. + ignore. + + +%% --------------------------------------------------------------------- + handle_get_log_type(#state{net_if_mod = Mod}) when Mod =/= undefined -> case (catch Mod:get_log_type(get(net_if))) of diff --git a/lib/snmp/src/agent/snmpa_internal.hrl b/lib/snmp/src/agent/snmpa_internal.hrl index a490a78f84..20a36cc118 100644 --- a/lib/snmp/src/agent/snmpa_internal.hrl +++ b/lib/snmp/src/agent/snmpa_internal.hrl @@ -22,7 +22,8 @@ -include_lib("snmp/src/app/snmp_internal.hrl"). --define(DEFAULT_LOCAL_ENGINE_ID, snmp_framework_mib:get_engine_id()). +%% The DEFAULT_LOCAL_ENGINE_ID macro can only be used by the master_agent!! +-define(DEFAULT_LOCAL_ENGINE_ID, snmp_framework_mib:get_engine_id()). -define(DEFAULT_NOTIF_EXTRA_INFO, {snmpa_default_notification_extra_info}). -define(snmpa_info(F, A), ?snmp_info("agent", F, A)). diff --git a/lib/snmp/src/agent/snmpa_local_db.erl b/lib/snmp/src/agent/snmpa_local_db.erl index d9d6e633de..df01091d53 100644 --- a/lib/snmp/src/agent/snmpa_local_db.erl +++ b/lib/snmp/src/agent/snmpa_local_db.erl @@ -1110,7 +1110,7 @@ table_func(is_set_ok, RowIndex, Cols, NameDb) -> table_func(set, RowIndex, Cols, NameDb) -> snmp_generic:table_set_row(NameDb, nofunc, - {snmp_generic, table_try_make_consistent}, + fun snmp_generic:table_try_make_consistent/3, RowIndex, Cols); diff --git a/lib/snmp/src/agent/snmpa_mpd.erl b/lib/snmp/src/agent/snmpa_mpd.erl index 4f50b1a674..0305e1fbec 100644 --- a/lib/snmp/src/agent/snmpa_mpd.erl +++ b/lib/snmp/src/agent/snmpa_mpd.erl @@ -468,15 +468,10 @@ v3_proc(NoteStore, Packet, LocalEngineID, V3Hdr, Data, Log) -> _ -> %% 4.2.2.1.2 NIsReportable = snmp_misc:is_reportable_pdu(Type), - Val = inc(snmpUnknownPDUHandlers), ErrorInfo = - {#varbind{oid = ?snmpUnknownPDUHandlers, - variabletype = 'Counter32', - value = Val}, - SecName, - [{securityLevel, SecLevel}, - {contextEngineID, ContextEngineID}, - {contextName, ContextName}]}, + snmpUnknownPDUHandlers_ei(SecName, SecLevel, + ContextEngineID, + ContextName), case generate_v3_report_msg(MsgID, MsgSecurityModel, Data, LocalEngineID, @@ -507,6 +502,21 @@ v3_proc(NoteStore, Packet, LocalEngineID, V3Hdr, Data, Log) -> end end. +make_error_info(Variable, Oid, SecName, Opts) -> + Val = inc(Variable), + VB = #varbind{oid = Oid, + variabletype = 'Counter32', + value = Val}, + {VB, SecName, Opts}. + +snmpUnknownPDUHandlers_ei(SecName, SecLevel, + ContextEngineID, ContextName) -> + Opts = [{securityLevel, SecLevel}, + {contextEngineID, ContextEngineID}, + {contextName, ContextName}], + make_error_info(snmpUnknownPDUHandlers, + ?snmpUnknownPDUHandlers_instance, + SecName, Opts). get_security_module(?SEC_USM) -> snmpa_usm; diff --git a/lib/snmp/src/agent/snmpa_set_lib.erl b/lib/snmp/src/agent/snmpa_set_lib.erl index 00c77a0cdb..f5218d5409 100644 --- a/lib/snmp/src/agent/snmpa_set_lib.erl +++ b/lib/snmp/src/agent/snmpa_set_lib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. +%% Copyright Ericsson AB 1996-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -143,8 +143,8 @@ consistency_check(Varbinds) -> consistency_check(Varbinds, []). consistency_check([{TableOid, TableVbs} | Varbinds], Done) -> ?vtrace("consistency_check -> entry with" - "~n TableOid: ~p" - "~n TableVbs: ~p",[TableOid,TableVbs]), + "~n TableOid: ~p" + "~n TableVbs: ~p", [TableOid, TableVbs]), TableOpsWithShortOids = deletePrefixes(TableOid, TableVbs), [#ivarbind{mibentry = MibEntry}|_] = TableVbs, case is_set_ok_table(MibEntry, TableOpsWithShortOids) of @@ -158,7 +158,7 @@ consistency_check([{TableOid, TableVbs} | Varbinds], Done) -> end; consistency_check([IVarbind | Varbinds], Done) -> ?vtrace("consistency_check -> entry with" - "~n IVarbind: ~p",[IVarbind]), + "~n IVarbind: ~p", [IVarbind]), #ivarbind{varbind = Varbind, mibentry = MibEntry} = IVarbind, #varbind{value = Value, org_index = OrgIndex} = Varbind, case is_set_ok_variable(MibEntry, Value) of @@ -358,38 +358,54 @@ make_value_a_correct_value(Value, ASN1Type, Mfa) -> %% Runtime debug support %%----------------------------------------------------------------- -% XXX: This function match on the exakt return codes from EXIT -% messages. As of this writing it was not decided if this is -% the right way so don't blindly do things this way. -% -% We fake a real EXIT signal as the return value because the -% result is passed to the function snmpa_agent:validate_err() -% that expect it. +%% XYZ: This function match on the exakt return codes from EXIT +%% messages. As of this writing it was not decided if this is +%% the right way so don't blindly do things this way. +%% +%% We fake a real EXIT signal as the return value because the +%% result is passed to the function snmpa_agent:validate_err() +%% that expect it. dbg_apply(M,F,A) -> - Result = - case get(verbosity) of - false -> - (catch apply(M,F,A)); - _ -> - ?vlog("~n apply: ~w,~w,~p~n", [M,F,A]), - Res = (catch apply(M,F,A)), - ?vlog("~n returned: ~p", [Res]), - Res - end, - case Result of - {'EXIT', {undef, [{M, F, A, _} | _]}} -> - {'EXIT', {hook_undef, {M, F, A}}}; - {'EXIT', {function_clause, [{M, F, A, _} | _]}} -> - {'EXIT', {hook_function_clause, {M, F, A}}}; - - % XXX: Old format for compatibility - {'EXIT', {undef, {M, F, A, _}}} -> - {'EXIT', {hook_undef, {M, F, A}}}; - {'EXIT', {function_clause, {M, F, A, _}}} -> - {'EXIT', {hook_function_clause, {M, F, A}}}; - - Result -> - Result + case maybe_verbose_apply(M, F, A) of + %% <Future proofing> + %% As of R15 we get extra info containing, + %% among other things, line numbers. + {'EXIT', {undef, [{M, F, A, _} | _]}} -> + {'EXIT', {hook_undef, {M, F, A}}}; + {'EXIT', {function_clause, [{M, F, A, _} | _]}} -> + {'EXIT', {hook_function_clause, {M, F, A}}}; + + %% This is really overkill, but just to be on the safe side... + {'EXIT', {undef, {M, F, A, _}}} -> + {'EXIT', {hook_undef, {M, F, A}}}; + {'EXIT', {function_clause, {M, F, A, _}}} -> + {'EXIT', {hook_function_clause, {M, F, A}}}; + %% </Future proofing> + + %% Old format format for compatibility + {'EXIT', {undef, [{M, F, A} | _]}} -> + {'EXIT', {hook_undef, {M, F, A}}}; + {'EXIT', {function_clause, [{M, F, A} | _]}} -> + {'EXIT', {hook_function_clause, {M, F, A}}}; + + % XYZ: Older format for compatibility + {'EXIT', {undef, {M, F, A}}} -> + {'EXIT', {hook_undef, {M, F, A}}}; + {'EXIT', {function_clause, {M, F, A}}} -> + {'EXIT', {hook_function_clause, {M, F, A}}}; + + Result -> + Result end. +maybe_verbose_apply(M, F, A) -> + case get(verbosity) of + false -> + (catch apply(M,F,A)); + _ -> + ?vlog("~n apply: ~w,~w,~p~n", [M,F,A]), + Res = (catch apply(M,F,A)), + ?vlog("~n returned: ~p", [Res]), + Res + end. diff --git a/lib/snmp/src/agent/snmpa_trap.erl b/lib/snmp/src/agent/snmpa_trap.erl index 567de020c0..5b579efc13 100644 --- a/lib/snmp/src/agent/snmpa_trap.erl +++ b/lib/snmp/src/agent/snmpa_trap.erl @@ -379,8 +379,13 @@ send_discovery(TargetName, Record, ContextName, Vbs, NetIf, ExtraInfo) -> get_values(VariablesWithType) -> {Order, Varbinds} = extract_order(VariablesWithType, 1), + ?vtrace("get_values -> " + "~n Order: ~p" + "~n Varbinds: ~p", [Order, Varbinds]), case snmpa_agent:do_get(snmpa_acm:get_root_mib_view(), Varbinds, true) of {noError, _, NewVarbinds} -> + ?vtrace("get_values -> values retrieved" + "~n NewVarbinds: ~p", [NewVarbinds]), %% NewVarbinds is the result of: %% first a reverse, then a sort on the oid field and finally %% a reverse during the get-processing so we need to re-sort diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src index b4b5367169..219ac62a73 100644 --- a/lib/snmp/src/app/snmp.appup.src +++ b/lib/snmp/src/app/snmp.appup.src @@ -22,19 +22,45 @@ %% ----- U p g r a d e ------------------------------------------------------- [ + {"4.21.3", + [ + {update, snmpa_local_db, soft, soft_purge, soft_purge, []} + ] + }, + {"4.21.2", + [ + {load_module, snmpa_mpd, soft_purge, soft_purge, []}, + {load_module, snmpa_set_lib, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, []}, + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, + {update, snmpa_agent, soft, soft_purge, soft_purge, []} + ] + }, {"4.21.1", [ + {load_module, snmpa_mpd, soft_purge, soft_purge, []}, + {load_module, snmpa_set_lib, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, []}, + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, + {update, snmpa_agent, soft, soft_purge, soft_purge, []}, {update, snmp_note_store, soft, soft_purge, soft_purge, []} ] }, {"4.21", [ - {update, snmp_note_store, soft, soft_purge, soft_purge, []}, - {load_module, snmp_target_mib, soft_purge, soft_purge, []} + {load_module, snmpa_mpd, soft_purge, soft_purge, []}, + {load_module, snmpa_set_lib, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, []}, + {load_module, snmp_target_mib, soft_purge, soft_purge, []}, + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, + {update, snmpa_agent, soft, soft_purge, soft_purge, []}, + {update, snmp_note_store, soft, soft_purge, soft_purge, []} ] }, {"4.20.1", [ + {load_module, snmpa_set_lib, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, []}, {load_module, snmp_target_mib, soft_purge, soft_purge, []}, {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, {load_module, snmpm, soft_purge, soft_purge, @@ -47,6 +73,7 @@ [snmp_conf, snmp_config]}, {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_config]}, {update, snmp_note_store, soft, soft_purge, soft_purge, []}, + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mpd]}, {update, snmpm_config, soft, soft_purge, soft_purge, [snmp_conf]}, {update, snmpm_server, soft, soft_purge, soft_purge, @@ -57,6 +84,8 @@ }, {"4.20", [ + {load_module, snmpa_set_lib, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, []}, {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, {load_module, snmp_target_mib, soft_purge, soft_purge, [snmp_conf]}, {load_module, snmpm, soft_purge, soft_purge, @@ -69,6 +98,7 @@ [snmp_conf, snmp_config]}, {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_config]}, {update, snmp_note_store, soft, soft_purge, soft_purge, []}, + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mpd]}, {update, snmpm_config, soft, soft_purge, soft_purge, [snmp_conf]}, {update, snmpm_server, soft, soft_purge, soft_purge, @@ -79,6 +109,7 @@ }, {"4.19", [ + {load_module, snmpa_set_lib, soft_purge, soft_purge, []}, {load_module, snmpa, soft_purge, soft_purge, []}, {load_module, snmpm, soft_purge, soft_purge, [snmpm_server, snmpm_config, snmp_config]}, @@ -113,6 +144,7 @@ {update, snmpm_config, soft, soft_purge, soft_purge, [snmp_conf]}, {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_net_if, snmpm_mpd, snmpm_config]}, + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, {update, snmpa_net_if, soft, soft_purge, soft_purge, [snmp_conf, snmpa_mpd]}, {update, snmpa_agent, soft, soft_purge, soft_purge, @@ -124,19 +156,45 @@ %% ------D o w n g r a d e --------------------------------------------------- [ + {"4.21.3", + [ + {update, snmpa_local_db, soft, soft_purge, soft_purge, []} + ] + }, + {"4.21.2", + [ + {load_module, snmpa_mpd, soft_purge, soft_purge, []}, + {load_module, snmpa_set_lib, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, []}, + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, + {update, snmpa_agent, soft, soft_purge, soft_purge, []} + ] + }, {"4.21.1", [ + {load_module, snmpa_mpd, soft_purge, soft_purge, []}, + {load_module, snmpa_set_lib, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, []}, + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, + {update, snmpa_agent, soft, soft_purge, soft_purge, []}, {update, snmp_note_store, soft, soft_purge, soft_purge, []} ] }, {"4.21", [ - {update, snmp_note_store, soft, soft_purge, soft_purge, []}, - {load_module, snmp_target_mib, soft_purge, soft_purge, []} + {load_module, snmpa_mpd, soft_purge, soft_purge, []}, + {load_module, snmpa_set_lib, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, []}, + {load_module, snmp_target_mib, soft_purge, soft_purge, []}, + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, + {update, snmpa_agent, soft, soft_purge, soft_purge, []}, + {update, snmp_note_store, soft, soft_purge, soft_purge, []} ] }, {"4.20.1", [ + {load_module, snmpa_set_lib, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, []}, {load_module, snmp_target_mib, soft_purge, soft_purge, []}, {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, {load_module, snmpm, soft_purge, soft_purge, @@ -149,6 +207,7 @@ [snmp_conf, snmp_config]}, {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_config]}, {update, snmp_note_store, soft, soft_purge, soft_purge, []}, + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mpd]}, {update, snmpm_config, soft, soft_purge, soft_purge, [snmp_conf]}, {update, snmpm_server, soft, soft_purge, soft_purge, @@ -159,6 +218,8 @@ }, {"4.20", [ + {load_module, snmpa_set_lib, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, []}, {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, {load_module, snmp_target_mib, soft_purge, soft_purge, [snmp_conf]}, {load_module, snmpm, soft_purge, soft_purge, @@ -171,6 +232,7 @@ [snmp_conf, snmp_config]}, {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_config]}, {update, snmp_note_store, soft, soft_purge, soft_purge, []}, + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mpd]}, {update, snmpm_config, soft, soft_purge, soft_purge, [snmp_conf]}, {update, snmpm_server, soft, soft_purge, soft_purge, @@ -181,6 +243,7 @@ }, {"4.19", [ + {load_module, snmpa_set_lib, soft_purge, soft_purge, []}, {load_module, snmpa, soft_purge, soft_purge, []}, {load_module, snmpm, soft_purge, soft_purge, [snmpm_server, snmpm_config, snmp_config]}, @@ -215,6 +278,7 @@ {update, snmpm_config, soft, soft_purge, soft_purge, [snmp_conf]}, {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_net_if, snmpm_mpd, snmpm_config]}, + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, {update, snmpa_net_if, soft, soft_purge, soft_purge, [snmp_conf, snmpa_mpd]}, {update, snmpa_agent, soft, soft_purge, soft_purge, diff --git a/lib/snmp/src/compile/depend.mk b/lib/snmp/src/compile/depend.mk index f7084f8bcd..3ee8dc4bec 100644 --- a/lib/snmp/src/compile/depend.mk +++ b/lib/snmp/src/compile/depend.mk @@ -44,6 +44,6 @@ $(EBIN)/snmpc_mib_gram.$(EMULATOR): \ ../../include/snmp_types.hrl \ snmpc_mib_gram.erl -$(BIN)/snmpc: snmpc.src +$(BIN)/snmpc: snmpc.src ../../vsn.mk $(PERL) -p -e 's?%VSN%?$(VSN)? ' < $< > $@ chmod 755 $@ diff --git a/lib/snmp/src/compile/snmpc.src b/lib/snmp/src/compile/snmpc.src index f993335b89..6eb95be35e 100644 --- a/lib/snmp/src/compile/snmpc.src +++ b/lib/snmp/src/compile/snmpc.src @@ -74,7 +74,7 @@ %% --rrnac %% --version %% --verbosity V -%% --warnings +%% --warnings | --W %% --Werror | --wae | --warnings_as_errors main(Args) when is_list(Args) -> case (catch process_args(Args)) of @@ -221,7 +221,10 @@ process_args([], #state{verbosity = Verbosity0, file = MIB} = State) -> process_args(["--help"|_Args], _State) -> ok; process_args(["--version"|_Args], #state{version = Version, mfv = MFV} = _State) -> - {ok, lists:flatten(io_lib:format("snmpc ~s (~s)", [Version, MFV]))}; + OtpVersion = otp_release(), + {ok, lists:flatten( + io_lib:format("snmpc ~s [Mib format version ~s] (OTP ~s)", + [Version, MFV, OtpVersion]))}; process_args(["--verbosity", Verbosity0|Args], #state{verbosity = V} = State) when (V =:= undefined) -> Verbosity = list_to_atom(Verbosity0), @@ -234,7 +237,7 @@ process_args(["--verbosity", Verbosity0|Args], #state{verbosity = V} = State) process_args(["--verbosity"|_Args], #state{verbosity = V}) when (V =/= undefined) -> e(lists:flatten(io_lib:format("Verbosity already set to ~w", [V]))); -process_args(["--w"|Args], State) -> +process_args(["--W"|Args], State) -> process_args(Args, State#state{warnings = true}); process_args(["--warnings"|Args], State) -> process_args(Args, State#state{warnings = true}); @@ -398,3 +401,15 @@ usage() -> e(Reason) -> throw({error, Reason}). +otp_release() -> + system_info(otp_release, string). + +system_info(Tag, Type) -> + case (catch erlang:system_info(Tag)) of + {'EXIT', _} -> + "-"; + Info when is_list(Info) andalso (Type =:= string) -> + Info; + Info -> + lists:flatten(io_lib:format("~w", [Info])) + end. diff --git a/lib/snmp/test/snmp_agent_test.erl b/lib/snmp/test/snmp_agent_test.erl index 468280db02..c95346b5a6 100644 --- a/lib/snmp/test/snmp_agent_test.erl +++ b/lib/snmp/test/snmp_agent_test.erl @@ -92,7 +92,8 @@ all() -> Conf1 ++ Conf2. groups() -> - [{all_tcs, [], cases()}, + [ + {all_tcs, [], cases()}, {mib_storage, [], [ {group, mib_storage_ets}, @@ -1321,7 +1322,7 @@ finish_v3(Config) when is_list(Config) -> mt_cases() -> -[multi_threaded, mt_trap]. + [multi_threaded, mt_trap]. init_mt(Config) when is_list(Config) -> SaNode = ?config(snmp_sa, Config), @@ -1498,7 +1499,8 @@ mt_trap(Config) when is_list(Config) -> ?line load_master("TestTrapv2"), try_test(mt_trap_test, [MA]), ?line unload_master("TestTrapv2"), - ?line unload_master("Test1"). + ?line unload_master("Test1"), + ok. v2_types(suite) -> []; v2_types(Config) when is_list(Config) -> @@ -3134,8 +3136,9 @@ mt_trap_test(MA) -> ?DBG("mt_trap_test(01) -> issue testTrapv22 (standard trap)", []), snmpa:send_trap(MA, testTrapv22, "standard trap"), ?DBG("mt_trap_test(02) -> await v2trap", []), - ?line expect(1, v2trap, [{[sysUpTime, 0], any}, - {[snmpTrapOID, 0], ?system ++ [0,1]}]), + ?line expect(mt_trap_test_1, v2trap, + [{[sysUpTime, 0], any}, + {[snmpTrapOID, 0], ?system ++ [0,1]}]), ?DBG("mt_trap_test(03) -> issue mtTrap (standard trap)", []), snmpa:send_trap(MA, mtTrap, "standard trap"), @@ -3143,28 +3146,22 @@ mt_trap_test(MA) -> ?DBG("mt_trap_test(04) -> multi pid: ~p. Now request sysUpTime...", [Pid]), g([[sysUpTime,0]]), - %% Previously (before OTP-6784) this was done at 09 below - %% when the test1:multiStr was actually executed by the - %% worker-process, but as of 4.9.4, this is now executed - %% my the master_agent-process... - ?DBG("mt_trap_test(05) -> send continue to multi-pid", []), - Pid ! continue, - ?DBG("mt_trap_test(06) -> await sysUpTime", []), - ?line expect(2, [{[sysUpTime,0], any}]), + ?line expect(mt_trap_test_2, [{[sysUpTime,0], any}]), ?DBG("mt_trap_test(07) -> issue testTrapv22 (standard trap)", []), snmpa:send_trap(MA, testTrapv22, "standard trap"), ?DBG("mt_trap_test(08) -> await v2trap", []), - ?line expect(3, v2trap, [{[sysUpTime, 0], any}, - {[snmpTrapOID, 0], ?system ++ [0,1]}]), + ?line expect(mt_trap_test_3, v2trap, + [{[sysUpTime, 0], any}, + {[snmpTrapOID, 0], ?system ++ [0,1]}]), - %% ?DBG("mt_trap_test(09) -> send continue to multi-pid", []), - %% Pid ! continue, + ?DBG("mt_trap_test(09) -> send continue to multi-pid", []), + Pid ! continue, ?DBG("mt_trap_test(10) -> await v2trap", []), - ?line expect(4, v2trap, [{[sysUpTime, 0], any}, - {[snmpTrapOID, 0], ?testTrap ++ [2]}, - {[multiStr,0], "ok"}]), + ?line expect(mt_trap_test_4, v2trap, [{[sysUpTime, 0], any}, + {[snmpTrapOID, 0], ?testTrap ++ [2]}, + {[multiStr,0], "ok"}]), ?DBG("mt_trap_test(11) -> done", []), ok. @@ -3563,53 +3560,82 @@ do_mul_set_err() -> %% Req. SA-MIB sa_mib() -> g([[sa, [2,0]]]), - ?line expect(1, [{[sa, [2,0]], 3}]), + ?line expect(sa_mib_1, [{[sa, [2,0]], 3}]), s([{[sa, [1,0]], s, "sa_test"}]), - ?line expect(2, [{[sa, [1,0]], "sa_test"}]). + ?line expect(sa_mib_2, [{[sa, [1,0]], "sa_test"}]), + ok. ma_trap1(MA) -> ok = snmpa:send_trap(MA, testTrap2, "standard trap"), - ?line expect(1, trap, [system], 6, 1, [{[system, [4,0]], - "{mbj,eklas}@erlang.ericsson.se"}]), + ?line expect(ma_trap1_1, + trap, [system], 6, 1, [{[system, [4,0]], + "{mbj,eklas}@erlang.ericsson.se"}]), ok = snmpa:send_trap(MA, testTrap1, "standard trap"), - ?line expect(2, trap, [1,2,3] , 1, 0, [{[system, [4,0]], - "{mbj,eklas}@erlang.ericsson.se"}]). + ?line expect(ma_trap1_2, + trap, [1,2,3] , 1, 0, [{[system, [4,0]], + "{mbj,eklas}@erlang.ericsson.se"}]), + ok. ma_trap2(MA) -> snmpa:send_trap(MA,testTrap2,"standard trap",[{sysContact,"pelle"}]), - ?line expect(3, trap, [system], 6, 1, [{[system, [4,0]], "pelle"}]). + ?line expect(ma_trap2_3, + trap, [system], 6, 1, [{[system, [4,0]], "pelle"}]), + ok. ma_v2_2_v1_trap(MA) -> snmpa:send_trap(MA,testTrapv22,"standard trap",[{sysContact,"pelle"}]), - ?line expect(3, trap, [system], 6, 1, [{[system, [4,0]], "pelle"}]). + ?line expect(ma_v2_2_v1_trap_3, + trap, [system], 6, 1, [{[system, [4,0]], "pelle"}]), + ok. ma_v2_2_v1_trap2(MA) -> snmpa:send_trap(MA,linkUp,"standard trap",[{ifIndex, [1], 1}, {ifAdminStatus, [1], 1}, {ifOperStatus, [1], 2}]), - ?line expect(3, trap, [1,2,3], 3, 0, [{[ifIndex, 1], 1}, - {[ifAdminStatus, 1], 1}, - {[ifOperStatus, 1], 2}]). + ?line expect(ma_v2_2_v1_trap2_3, + trap, [1,2,3], 3, 0, [{[ifIndex, 1], 1}, + {[ifAdminStatus, 1], 1}, + {[ifOperStatus, 1], 2}]), + ok. sa_trap1(SA) -> - snmpa:send_trap(SA, saTrap, "standard trap"), - ?line expect(4, trap, [ericsson], 6, 1, [{[system, [4,0]], - "{mbj,eklas}@erlang.ericsson.se"}, - {[sa, [1,0]], "sa_test"}]). + %% io:format("sa_trap1 -> entry with" + %% "~n SA: ~p" + %% "~n node(SA): ~p" + %% "~n self(): ~p" + %% "~n node(): ~p" + %% "~n", [SA, node(SA), self(), node()]), + _VRes = (catch snmpa:verbosity(SA, {subagents, trace})), + %% io:format("sa_trap1 -> SA verbosity set: " + %% "~n VRes: ~p" + %% "~n", [VRes]), + _TSRes = (catch snmpa:send_trap(SA, saTrap, "standard trap")), + %% io:format("sa_trap1 -> SA trap send: " + %% "~n TSRes: ~p" + %% "~n", [TSRes]), + ?line expect(sa_trap1_4, + trap, [ericsson], 6, 1, [{[system, [4,0]], + "{mbj,eklas}@erlang.ericsson.se"}, + {[sa, [1,0]], "sa_test"}]), + snmpa:verbosity(SA, {subagents, silence}), + ok. sa_trap2(SA) -> snmpa:send_trap(SA, saTrap, "standard trap",[{sysContact,"pelle"}]), - ?line expect(5, trap, [ericsson], 6, 1, [{[system, [4,0]], - "pelle"}, - {[sa, [1,0]], "sa_test"}]). + ?line expect(sa_trap2_5, + trap, [ericsson], 6, 1, [{[system, [4,0]], "pelle"}, + {[sa, [1,0]], "sa_test"}]), + ok. sa_trap3(SA) -> snmpa:send_trap(SA, saTrap2, "standard trap", [{intViewSubtree, [4], [1,2,3,4]}]), - ?line expect(6, trap, [ericsson], 6, 2, [{[system, [4,0]], - "{mbj,eklas}@erlang.ericsson.se"}, - {[sa, [1,0]], "sa_test"}, - {[intViewSubtree,4],[1,2,3,4]}]). + ?line expect(sa_trap3_6, + trap, [ericsson], 6, 2, [{[system, [4,0]], + "{mbj,eklas}@erlang.ericsson.se"}, + {[sa, [1,0]], "sa_test"}, + {[intViewSubtree,4],[1,2,3,4]}]), + ok. ma_v2_trap1(MA) -> ?DBG("ma_v2_traps -> entry with MA = ~p => " @@ -4029,33 +4055,42 @@ ma_v1_2_v2_trap2(MA) -> sa_v1_2_v2_trap1(SA) -> + snmpa:verbosity(SA, {subagents, trace}), snmpa:send_trap(SA, saTrap, "standard trap"), - ?line expect(4, v2trap, [{[sysUpTime, 0], any}, - {[snmpTrapOID, 0], ?ericsson ++ [0, 1]}, - {[system, [4,0]], - "{mbj,eklas}@erlang.ericsson.se"}, - {[sa, [1,0]], "sa_test"}, - {[snmpTrapEnterprise, 0], ?ericsson}]). + ?line expect(trap1_4, v2trap, [{[sysUpTime, 0], any}, + {[snmpTrapOID, 0], ?ericsson ++ [0, 1]}, + {[system, [4,0]], + "{mbj,eklas}@erlang.ericsson.se"}, + {[sa, [1,0]], "sa_test"}, + {[snmpTrapEnterprise, 0], ?ericsson}]), + snmpa:verbosity(SA, {subagents, silence}), + ok. sa_v1_2_v2_trap2(SA) -> + snmpa:verbosity(SA, {subagents, trace}), snmpa:send_trap(SA, saTrap, "standard trap",[{sysContact,"pelle"}]), - ?line expect(4, v2trap, [{[sysUpTime, 0], any}, - {[snmpTrapOID, 0], ?ericsson ++ [0, 1]}, - {[system, [4,0]], "pelle"}, - {[sa, [1,0]], "sa_test"}, - {[snmpTrapEnterprise, 0], ?ericsson}]). - + ?line expect(trap2_4, v2trap, [{[sysUpTime, 0], any}, + {[snmpTrapOID, 0], ?ericsson ++ [0, 1]}, + {[system, [4,0]], "pelle"}, + {[sa, [1,0]], "sa_test"}, + {[snmpTrapEnterprise, 0], ?ericsson}]), + snmpa:verbosity(SA, {subagents, silence}), + ok. + sa_v1_2_v2_trap3(SA) -> + snmpa:verbosity(SA, {subagents, trace}), snmpa:send_trap(SA, saTrap2, "standard trap", [{intViewSubtree, [4], [1,2,3,4]}]), - ?line expect(4, v2trap, [{[sysUpTime, 0], any}, - {[snmpTrapOID, 0], ?ericsson ++ [0, 2]}, - {[system, [4,0]], - "{mbj,eklas}@erlang.ericsson.se"}, - {[sa, [1,0]], "sa_test"}, - {[intViewSubtree,4],[1,2,3,4]}, - {[snmpTrapEnterprise, 0], ?ericsson}]). + ?line expect(trap3_4, v2trap, [{[sysUpTime, 0], any}, + {[snmpTrapOID, 0], ?ericsson ++ [0, 2]}, + {[system, [4,0]], + "{mbj,eklas}@erlang.ericsson.se"}, + {[sa, [1,0]], "sa_test"}, + {[intViewSubtree,4],[1,2,3,4]}, + {[snmpTrapEnterprise, 0], ?ericsson}]), + snmpa:verbosity(SA, {subagents, silence}), + ok. %% Req. SA-MIB, OLD-SNMPEA-MIB @@ -4195,9 +4230,9 @@ snmp_standard_mib(Config) when is_list(Config) -> %% Req. SNMP-STANDARD-MIB standard_mib_a() -> - ?line [OutPkts] = get_req(2, [[snmpOutPkts,0]]), + ?line [OutPkts] = get_req(2, [[snmpOutPkts,0]]), ?line [OutPkts2] = get_req(3, [[snmpOutPkts,0]]), - ?line OutPkts2 = OutPkts + 1, + ?line OutPkts2 = OutPkts + 1, %% There are some more counters we could test here, but it's not that %% important, since they are removed from SNMPv2-MIB. ok. @@ -4207,27 +4242,27 @@ std_mib_init() -> %% disable authentication failure traps. (otherwise w'd get many of %% them - this is also a test to see that it works). s([{[snmpEnableAuthenTraps,0], 2}]), - ?line expect(1, [{[snmpEnableAuthenTraps, 0], 2}]). + ?line expect(std_mib_init_1, [{[snmpEnableAuthenTraps, 0], 2}]). %% Req. SNMP-STANDARD-MIB | SNMPv2-MIB std_mib_finish() -> %% enable again s([{[snmpEnableAuthenTraps,0], 1}]), - ?line expect(1, [{[snmpEnableAuthenTraps, 0], 1}]). + ?line expect(std_mib_finish_1, [{[snmpEnableAuthenTraps, 0], 1}]). %% Req. SNMP-STANDARD-MIB standard_mib_test_finish() -> - %% force a authenticationFailure + %% force a authenticationFailure (should result in a trap) std_mib_write(), %% check that we got a trap - ?line expect(2, trap, [1,2,3], 4, 0, []). + ?line expect(standard_mib_test_finish_2, trap, [1,2,3], 4, 0, []). %% Req. SNMP-STANDARD-MIB | SNMPv2-MIB std_mib_read() -> ?DBG("std_mib_read -> entry", []), g([[sysUpTime,0]]), % try a bad <something>; msg dropped, no reply ?DBG("std_mib_read -> await timeout (i.e. no reply)", []), - ?line expect(1, timeout). % make sure we don't get a trap! + ?line expect(std_mib_read_1, timeout). % make sure we don't get a trap! %% Req. SNMP-STANDARD-MIB | SNMPv2-MIB @@ -4362,10 +4397,10 @@ std_mib_c({InBadCommunityNames, InBadCommunityUses, InASNErrs}) -> snmpv2_mib_a() -> ?line [SetSerial] = get_req(2, [[snmpSetSerialNo,0]]), s([{[snmpSetSerialNo,0], SetSerial}, {[sysLocation, 0], "val2"}]), - ?line expect(3, [{[snmpSetSerialNo,0], SetSerial}, - {[sysLocation, 0], "val2"}]), + ?line expect(snmpv2_mib_a_3, [{[snmpSetSerialNo,0], SetSerial}, + {[sysLocation, 0], "val2"}]), s([{[sysLocation, 0], "val3"}, {[snmpSetSerialNo,0], SetSerial}]), - ?line expect(4, inconsistentValue, 2, + ?line expect(snmpv2_mib_a_4, inconsistentValue, 2, [{[sysLocation, 0], "val3"}, {[snmpSetSerialNo,0], SetSerial}]), ?line ["val2"] = get_req(5, [[sysLocation,0]]). @@ -4688,46 +4723,46 @@ snmp_view_based_acm_mib() -> do_set(Row) -> s(Row), - expect(1, Row). + expect(do_set_1, Row). add_row(RowStatus) -> s([{RowStatus, ?createAndGo}]), - expect(1, [{RowStatus, ?createAndGo}]). + expect(add_row_1, [{RowStatus, ?createAndGo}]). del_row(RowStatus) -> s([{RowStatus, ?destroy}]), - expect(1, [{RowStatus, ?destroy}]). + expect(del_row_1, [{RowStatus, ?destroy}]). use_no_rights() -> g([[xDescr,0]]), - ?v1_2_3(expect(11, noSuchName, 1, any), - expect(12, [{[xDescr,0], noSuchObject}]), - expect(13, authorizationError, 1, any)), + ?v1_2_3(expect(use_no_rights_11, noSuchName, 1, any), + expect(use_no_rights_12, [{[xDescr,0], noSuchObject}]), + expect(use_no_rights_13, authorizationError, 1, any)), g([[xDescr2,0]]), - ?v1_2_3(expect(21, noSuchName, 1, any), - expect(22, [{[xDescr2,0], noSuchObject}]), - expect(23, authorizationError, 1, any)), + ?v1_2_3(expect(use_no_rights_21, noSuchName, 1, any), + expect(use_no_rights_22, [{[xDescr2,0], noSuchObject}]), + expect(use_no_rights_23, authorizationError, 1, any)), gn([[xDescr]]), - ?v1_2_3(expect(31, noSuchName, 1, any), - expect(32, [{[xDescr], endOfMibView}]), - expect(33, authorizationError, 1, any)), + ?v1_2_3(expect(use_no_rights_31, noSuchName, 1, any), + expect(use_no_rights_32, [{[xDescr], endOfMibView}]), + expect(use_no_rights_33, authorizationError, 1, any)), s([{[xDescr,0], "tryit"}]), - ?v1_2_3(expect(41, noSuchName, 1, any), - expect(42, noAccess, 1, any), - expect(43, authorizationError, 1, any)). + ?v1_2_3(expect(use_no_rights_41, noSuchName, 1, any), + expect(use_no_rights_42, noAccess, 1, any), + expect(use_no_rights_43, authorizationError, 1, any)). use_rights() -> g([[xDescr,0]]), - expect(1, [{[xDescr,0], any}]), + expect(use_rights_1, [{[xDescr,0], any}]), g([[xDescr2,0]]), - expect(2, [{[xDescr2,0], any}]), + expect(use_rights_2, [{[xDescr2,0], any}]), s([{[xDescr,0], "tryit"}]), - expect(3, noError, 0, any), + expect(use_rights_3, noError, 0, any), g([[xDescr,0]]), - expect(4, [{[xDescr,0], "tryit"}]). + expect(use_rights_4, [{[xDescr,0], "tryit"}]). mk_ln(X) -> [length(X) | X]. diff --git a/lib/snmp/test/snmp_agent_test_lib.erl b/lib/snmp/test/snmp_agent_test_lib.erl index a18d9f3201..084b3ee8da 100644 --- a/lib/snmp/test/snmp_agent_test_lib.erl +++ b/lib/snmp/test/snmp_agent_test_lib.erl @@ -296,7 +296,12 @@ call(N,M,F,A) -> ?DBG("call -> done:" "~n Ret: ~p" "~n Zed: ~p", [Ret, Zed]), - Ret + case Ret of + {error, Reason} -> + exit(Reason); + OK -> + OK + end end. wait(From, Env, M, F, A) -> @@ -724,17 +729,13 @@ expect(Id, A, B, C, D, E) -> expect2(Id, Fun). expect2(Id, F) -> - io:format("~w:expect2 -> entry with" - "~n Id: ~w" - "~n", [?MODULE, Id]), + io:format("EXPECT for ~w~n", [Id]), case F() of {error, Reason} -> - {error, Id, Reason}; + io:format("EXPECT failed for ~w: ~n~p~n", [Id, Reason]), + throw({error, {expect, Id, Reason}}); Else -> - io:format("~w:expect2 -> " - "~n Id: ~w" - "~n Else: ~p" - "~n", [?MODULE, Id, Else]), + io:format("EXPECT result for ~w: ~n~p~n", [Id, Else]), Else end. @@ -769,21 +770,15 @@ do_expect(Expect) when is_atom(Expect) -> do_expect({any_pdu, To}) when is_integer(To) orelse (To =:= infinity) -> - io:format("~w:do_expect(any_pdu) -> entry with" - "~n To: ~w" - "~n", [?MODULE, To]), + io:format("EXPECT any PDU~n", []), receive_pdu(To); do_expect({any_trap, To}) -> - io:format("~w:do_expect(any_trap) -> entry with" - "~n To: ~w" - "~n", [?MODULE, To]), + io:format("EXPECT any TRAP within ~w~n", [To]), receive_trap(To); do_expect({timeout, To}) -> - io:format("~w:do_expect(timeout) -> entry with" - "~n To: ~w" - "~n", [?MODULE, To]), + io:format("EXPECT nothing within ~w~n", [To]), receive X -> {error, {unexpected, X}} @@ -794,13 +789,16 @@ do_expect({timeout, To}) -> do_expect({Err, To}) when is_atom(Err) andalso (is_integer(To) orelse (To =:= infinity)) -> + io:format("EXPECT error ~w within ~w~n", [Err, To]), do_expect({{error, Err}, To}); do_expect({error, Err}) when is_atom(Err) -> Check = fun(_, R) -> R end, + io:format("EXPECT error ~w~n", [Err]), do_expect2(Check, any, Err, any, any, get_timeout()); do_expect({{error, Err}, To}) -> Check = fun(_, R) -> R end, + io:format("EXPECT error ~w within ~w~n", [Err, To]), do_expect2(Check, any, Err, any, any, To); %% exp_varbinds() -> [exp_varbind()] @@ -810,16 +808,25 @@ do_expect({{error, Err}, To}) -> %% ExpVBs -> exp_varbinds() | {VbsCondition, exp_varbinds()} do_expect(ExpVBs) -> Check = fun(_, R) -> R end, + io:format("EXPECT 'get-response'" + "~n with" + "~n Varbinds: ~p~n", [ExpVBs]), do_expect2(Check, 'get-response', noError, 0, ExpVBs, get_timeout()). do_expect(v2trap, ExpVBs) -> Check = fun(_, R) -> R end, + io:format("EXPECT 'snmpv2-trap'" + "~n with" + "~n Varbinds: ~p~n", [ExpVBs]), do_expect2(Check, 'snmpv2-trap', noError, 0, ExpVBs, get_timeout()); do_expect(report, ExpVBs) -> Check = fun(_, R) -> R end, + io:format("EXPECT 'report'" + "~n with" + "~n Varbinds: ~p~n", [ExpVBs]), do_expect2(Check, 'report', noError, 0, ExpVBs, get_timeout()); @@ -827,16 +834,13 @@ do_expect(inform, ExpVBs) -> do_expect({inform, true}, ExpVBs); do_expect({inform, false}, ExpVBs) -> - io:format("~w:do_expect(inform, false) -> entry with" - "~n ExpVBs: ~p" - "~n", [?MODULE, ExpVBs]), Check = fun(_, R) -> R end, + io:format("EXPECT 'inform-request' (false)" + "~n with" + "~n Varbinds: ~p~n", [ExpVBs]), do_expect2(Check, 'inform-request', noError, 0, ExpVBs, get_timeout()); do_expect({inform, true}, ExpVBs) -> - io:format("~w:do_expect(inform, true) -> entry with" - "~n ExpVBs: ~p" - "~n", [?MODULE, ExpVBs]), Check = fun(PDU, ok) -> RespPDU = PDU#pdu{type = 'get-response', @@ -847,6 +851,9 @@ do_expect({inform, true}, ExpVBs) -> (_, Err) -> Err end, + io:format("EXPECT 'inform-request' (true)" + "~n with" + "~n Varbinds: ~p~n", [ExpVBs]), do_expect2(Check, 'inform-request', noError, 0, ExpVBs, get_timeout()); do_expect({inform, {error, EStat, EIdx}}, ExpVBs) @@ -861,6 +868,11 @@ do_expect({inform, {error, EStat, EIdx}}, ExpVBs) (_, Err) -> Err end, + io:format("EXPECT 'inform-request' (error)" + "~n with" + "~n Error Status: ~p" + "~n Error Index: ~p" + "~n Varbinds: ~p~n", [EStat, EIdx, ExpVBs]), do_expect2(Check, 'inform-request', noError, 0, ExpVBs, get_timeout()). @@ -871,6 +883,12 @@ do_expect(Err, Idx, ExpVBs, To) when is_atom(Err) andalso (is_integer(Idx) orelse is_list(Idx) orelse (Idx == any)) -> Check = fun(_, R) -> R end, + io:format("EXPECT 'get-response'" + "~n with" + "~n Error: ~p" + "~n Index: ~p" + "~n Varbinds: ~p" + "~n within ~w~n", [Err, Idx, ExpVBs, To]), do_expect2(Check, 'get-response', Err, Idx, ExpVBs, To). @@ -878,15 +896,13 @@ do_expect(Type, Enterp, Generic, Specific, ExpVBs) -> do_expect(Type, Enterp, Generic, Specific, ExpVBs, 3500). do_expect(trap, Enterp, Generic, Specific, ExpVBs, To) -> - io:format("~w:do_expect(trap) -> entry with" - "~n Enterp: ~w" - "~n Generic: ~w" - "~n Specific: ~w" - "~n ExpVBs: ~w" - "~n To: ~w" - "~nwhen" - "~n Time: ~w" - "~n", [?MODULE, Enterp, Generic, Specific, ExpVBs, To, t()]), + io:format("EXPECT trap" + "~n with" + "~n Enterp: ~w" + "~n Generic: ~w" + "~n Specific: ~w" + "~n Varbinds: ~w" + "~n within ~w~n", [Enterp, Generic, Specific, ExpVBs, To]), PureE = purify_oid(Enterp), case receive_trap(To) of #trappdu{enterprise = PureE, @@ -916,49 +932,51 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To) (is_list(ExpVBs) orelse (ExpVBs =:= any)) andalso (is_integer(To) orelse (To =:= infinity)) -> - io:format("~w:do_expect2 -> entry with" - "~n Type: ~w" - "~n Err: ~w" - "~n Idx: ~w" - "~n ExpVBs: ~w" - "~n To: ~w" - "~nwhen" - "~n Time: ~w" - "~n", [?MODULE, Type, Err, Idx, ExpVBs, To, t()]), - case receive_pdu(To) of #pdu{type = Type, error_status = Err, error_index = Idx} when ExpVBs =:= any -> + io:format("EXPECT received expected pdu (1)~n", []), ok; #pdu{type = Type, request_id = ReqId, error_status = Err2, error_index = Idx} when ExpVBs =:= any -> + io:format("EXPECT received expected pdu with " + "unexpected error status (2): " + "~n Error Status: ~p~n", [Err2]), {error, {unexpected_error_status, Err, Err2, ReqId}}; #pdu{error_status = Err} when (Type =:= any) andalso (Idx =:= any) andalso (ExpVBs =:= any) -> + io:format("EXPECT received expected pdu (3)~n", []), ok; #pdu{request_id = ReqId, error_status = Err2} when (Type =:= any) andalso (Idx =:= any) andalso (ExpVBs =:= any) -> + io:format("EXPECT received expected pdu with " + "unexpected error status (4): " + "~n Error Status: ~p~n", [Err2]), {error, {unexpected_error_status, Err, Err2, ReqId}}; #pdu{type = Type, error_status = Err} when (Idx =:= any) andalso (ExpVBs =:= any) -> + io:format("EXPECT received expected pdu (5)~n", []), ok; #pdu{type = Type, request_id = ReqId, error_status = Err2} when (Idx =:= any) andalso (ExpVBs =:= any) -> + io:format("EXPECT received expected pdu with " + "unexpected error status (6): " + "~n Error Status: ~p~n", [Err2]), {error, {unexpected_error_status, Err, Err2, ReqId}}; #pdu{type = Type, @@ -967,8 +985,13 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To) error_index = EI} when is_list(Idx) andalso (ExpVBs =:= any) -> case lists:member(EI, Idx) of true -> + io:format("EXPECT received expected pdu with " + "expected error index (7)~n", []), ok; false -> + io:format("EXPECT received expected pdu with " + "unexpected error index (8): " + "~n Error Index: ~p~n", [EI]), {error, {unexpected_error_index, EI, Idx, ReqId}} end; @@ -978,8 +1001,15 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To) error_index = EI} when is_list(Idx) andalso (ExpVBs =:= any) -> case lists:member(EI, Idx) of true -> + io:format("EXPECT received expected pdu with " + "unexpected error status (9): " + "~n Error Status: ~p~n", [Err2]), {error, {unexpected_error_status, Err, Err2, ReqId}}; false -> + io:format("EXPECT received expected pdu with " + "unexpected error (10): " + "~n Error Status: ~p" + "~n Error index: ~p~n", [Err2, EI]), {error, {unexpected_error, {Err, Idx}, {Err2, EI}, ReqId}} end; @@ -987,6 +1017,12 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To) request_id = ReqId, error_status = Err2, error_index = Idx2} when ExpVBs =:= any -> + io:format("EXPECT received unexpected pdu with (11) " + "~n Type: ~p" + "~n ReqId: ~p" + "~n Errot status: ~p" + "~n Error index: ~p" + "~n", [Type2, ReqId, Err2, Idx2]), {error, {unexpected_pdu, {Type, Err, Idx}, {Type2, Err2, Idx2}, ReqId}}; @@ -995,11 +1031,26 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To) error_status = Err, error_index = Idx, varbinds = VBs} = PDU -> + io:format("EXPECT received pdu (12): " + "~n [exp] Type: ~p" + "~n [exp] Error Status: ~p" + "~n [exp] Error Index: ~p" + "~n VBs: ~p" + "~nwhen" + "~n ExpVBs: ~p" + "~n", [Type, Err, Idx, VBs, ExpVBs]), Check(PDU, check_vbs(purify_oids(ExpVBs), VBs)); #pdu{type = Type, error_status = Err, varbinds = VBs} = PDU when Idx =:= any -> + io:format("EXPECT received pdu (13): " + "~n [exp] Type: ~p" + "~n [exp] Error Status: ~p" + "~n VBs: ~p" + "~nwhen" + "~n ExpVBs: ~p" + "~n", [Type, Err, VBs, ExpVBs]), Check(PDU, check_vbs(purify_oids(ExpVBs), VBs)); #pdu{type = Type, @@ -1007,6 +1058,15 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To) error_status = Err, error_index = EI, varbinds = VBs} = PDU when is_list(Idx) -> + io:format("EXPECT received pdu (14): " + "~n [exp] Type: ~p" + "~n ReqId: ~p" + "~n [exp] Error Status: ~p" + "~n [exp] Error Index: ~p" + "~n VBs: ~p" + "~nwhen" + "~n ExpVBs: ~p" + "~n", [Type, ReqId, Err, EI, VBs, ExpVBs]), PureVBs = purify_oids(ExpVBs), case lists:member(EI, Idx) of true -> @@ -1020,6 +1080,13 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To) error_status = Err2, error_index = Idx2, varbinds = VBs2} -> + io:format("EXPECT received unexpected pdu with (15) " + "~n Type: ~p" + "~n ReqId: ~p" + "~n Errot status: ~p" + "~n Error index: ~p" + "~n Varbinds: ~p" + "~n", [Type2, ReqId, Err2, Idx2, VBs2]), {error, {unexpected_pdu, {Type, Err, Idx, purify_oids(ExpVBs)}, @@ -1027,6 +1094,9 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To) ReqId}}; Error -> + io:format("EXPECT received error (16): " + "~n Error: ~p" + "~n", [Error]), Error end. @@ -1466,7 +1536,7 @@ rpc(Node, F, A) -> %% %% %% t() -> -%% {A,B,C} = erlang:now(), +%% {A,B,C} = os:timestamp(), %% A*1000000000+B*1000+(C div 1000). %% %% @@ -1478,6 +1548,6 @@ rpc(Node, F, A) -> %% Time in milli seconds -t() -> - {A,B,C} = erlang:now(), - A*1000000000+B*1000+(C div 1000). +%% t() -> +%% {A,B,C} = os:timestamp(), +%% A*1000000000+B*1000+(C div 1000). diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk index 0819ab9b36..ee2e633c69 100644 --- a/lib/snmp/vsn.mk +++ b/lib/snmp/vsn.mk @@ -17,6 +17,7 @@ # # %CopyrightEnd% -SNMP_VSN = 4.21.2 +APPLICATION = snmp +SNMP_VSN = 4.21.4 PRE_VSN = -APP_VSN = "snmp-$(SNMP_VSN)$(PRE_VSN)" +APP_VSN = "$(APPLICATION)-$(SNMP_VSN)$(PRE_VSN)" diff --git a/lib/ssl/src/ssl_app.erl b/lib/ssl/src/ssl_app.erl index c9f81726b9..0c475a6d01 100644 --- a/lib/ssl/src/ssl_app.erl +++ b/lib/ssl/src/ssl_app.erl @@ -27,16 +27,9 @@ -export([start/2, stop/1]). -%%-------------------------------------------------------------------- --spec start(normal | {takeover, node()} | {failover, node()}, list()) -> - ignore | {ok, pid()} | {error, term()}. -%%-------------------------------------------------------------------- start(_Type, _StartArgs) -> ssl_sup:start_link(). -%-------------------------------------------------------------------- --spec stop(term())-> ok. -%%-------------------------------------------------------------------- stop(_State) -> ok. diff --git a/lib/ssl/src/ssl_cipher.erl b/lib/ssl/src/ssl_cipher.erl index 95a5efd6d0..015265441e 100644 --- a/lib/ssl/src/ssl_cipher.erl +++ b/lib/ssl/src/ssl_cipher.erl @@ -166,7 +166,7 @@ block_decipher(Fun, #cipher_state{key=Key, iv=IV} = CipherState0, false -> %% decryption failed or invalid padding, %% intentionally break Content to make - %% sure a packet with a an invalid padding + %% sure a packet with invalid padding %% but otherwise correct data will fail %% the MAC test later {<<16#F0, Content/binary>>, Mac, CipherState1} @@ -523,7 +523,7 @@ hash_size(sha) -> %% %% implementation note: %% We return the original (possibly invalid) PadLength in any case. -%% A invalid PadLength will be cought by is_correct_padding/2 +%% An invalid PadLength will be caught by is_correct_padding/2 %% generic_block_cipher_from_bin(T, HashSize) -> Sz1 = byte_size(T) - 1, diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl index 0c44d3ae90..28dd0c85d0 100644 --- a/lib/ssl/src/ssl_connection.erl +++ b/lib/ssl/src/ssl_connection.erl @@ -87,15 +87,17 @@ bytes_to_read, % integer(), # bytes to read in passive mode user_data_buffer, % binary() log_alert, % boolean() - renegotiation, % {boolean(), From | internal | peer} - recv_during_renegotiation, %boolean() - send_queue, % queue() - terminated = false % + renegotiation, % {boolean(), From | internal | peer} + recv_from, % + send_queue, % queue() + terminated = false, % + allow_renegotiate = true }). -define(DEFAULT_DIFFIE_HELLMAN_PARAMS, - #'DHParameter'{prime = ?DEFAULT_DIFFIE_HELLMAN_PRIME, + #'DHParameter'{prime = ?DEFAULT_DIFFIE_HELLMAN_PRIME, base = ?DEFAULT_DIFFIE_HELLMAN_GENERATOR}). +-define(WAIT_TO_ALLOW_RENEGOTIATION, 12000). -type state_name() :: hello | abbreviated | certify | cipher | connection. -type gen_fsm_state_return() :: {next_state, state_name(), #state{}} | @@ -291,10 +293,6 @@ start_link(Role, Host, Port, Socket, Options, User, CbInfo) -> %% gen_fsm callbacks %%==================================================================== %%-------------------------------------------------------------------- --spec init(list()) -> {ok, state_name(), #state{}, timeout()} | {stop, term()}. -%% Possible return values not used now. -%% | {ok, state_name(), #state{}} | -%% ignore %% Description:Whenever a gen_fsm is started using gen_fsm:start/[3,4] or %% gen_fsm:start_link/3,4, this function is called by the new process to %% initialize. @@ -322,8 +320,6 @@ init([Role, Host, Port, Socket, {SSLOpts0, _} = Options, end. %%-------------------------------------------------------------------- -%% -spec state_name(event(), #state{}) -> gen_fsm_state_return() -%% %% Description:There should be one instance of this function for each %% possible state name. Whenever a gen_fsm receives an event sent %% using gen_fsm:send_event/2, the instance of this function with the @@ -355,15 +351,15 @@ hello(start, #state{host = Host, port = Port, role = client, Session0#session{session_id = Hello#client_hello.session_id}, tls_handshake_hashes = Hashes1}, {Record, State} = next_record(State1), - next_state(hello, Record, State); + next_state(hello, hello, Record, State); hello(start, #state{role = server} = State0) -> {Record, State} = next_record(State0), - next_state(hello, Record, State); + next_state(hello, hello, Record, State); hello(#hello_request{}, #state{role = client} = State0) -> {Record, State} = next_record(State0), - next_state(hello, Record, State); + next_state(hello, hello, Record, State); hello(#server_hello{cipher_suite = CipherSuite, compression_method = Compression} = Hello, @@ -426,7 +422,7 @@ hello(Msg, State) -> %%-------------------------------------------------------------------- abbreviated(#hello_request{}, State0) -> {Record, State} = next_record(State0), - next_state(hello, Record, State); + next_state(abbreviated, hello, Record, State); abbreviated(#finished{verify_data = Data} = Finished, #state{role = server, @@ -479,7 +475,7 @@ abbreviated(Msg, State) -> %%-------------------------------------------------------------------- certify(#hello_request{}, State0) -> {Record, State} = next_record(State0), - next_state(hello, Record, State); + next_state(certify, hello, Record, State); certify(#certificate{asn1_certificates = []}, #state{role = server, negotiated_version = Version, @@ -487,7 +483,7 @@ certify(#certificate{asn1_certificates = []}, fail_if_no_peer_cert = true}} = State) -> Alert = ?ALERT_REC(?FATAL,?HANDSHAKE_FAILURE), - handle_own_alert(Alert, Version, certify_certificate, State), + handle_own_alert(Alert, Version, certify, State), {stop, normal, State}; certify(#certificate{asn1_certificates = []}, @@ -496,7 +492,7 @@ certify(#certificate{asn1_certificates = []}, fail_if_no_peer_cert = false}} = State0) -> {Record, State} = next_record(State0#state{client_certificate_requested = false}), - next_state(certify, Record, State); + next_state(certify, certify, Record, State); certify(#certificate{} = Cert, #state{negotiated_version = Version, @@ -511,7 +507,7 @@ certify(#certificate{} = Cert, handle_peer_cert(PeerCert, PublicKeyInfo, State#state{client_certificate_requested = false}); #alert{} = Alert -> - handle_own_alert(Alert, Version, certify_certificate, State), + handle_own_alert(Alert, Version, certify, State), {stop, normal, State} end; @@ -522,10 +518,9 @@ certify(#server_key_exchange{} = KeyExchangeMsg, case handle_server_key(KeyExchangeMsg, State0) of #state{} = State1 -> {Record, State} = next_record(State1), - next_state(certify, Record, State); + next_state(certify, certify, Record, State); #alert{} = Alert -> - handle_own_alert(Alert, Version, certify_server_keyexchange, - State0), + handle_own_alert(Alert, Version, certify, State0), {stop, normal, State0} end; @@ -535,7 +530,7 @@ certify(#server_key_exchange{} = Msg, certify(#certificate_request{}, State0) -> {Record, State} = next_record(State0#state{client_certificate_requested = true}), - next_state(certify, Record, State); + next_state(certify, certify, Record, State); %% Master secret was determined with help of server-key exchange msg certify(#server_hello_done{}, @@ -550,8 +545,7 @@ certify(#server_hello_done{}, State = State0#state{connection_states = ConnectionStates1}, client_certify_and_key_exchange(State); #alert{} = Alert -> - handle_own_alert(Alert, Version, - certify_server_hello_done, State0), + handle_own_alert(Alert, Version, certify, State0), {stop, normal, State0} end; @@ -570,8 +564,7 @@ certify(#server_hello_done{}, session = Session}, client_certify_and_key_exchange(State); #alert{} = Alert -> - handle_own_alert(Alert, Version, - certify_server_hello_done, State0), + handle_own_alert(Alert, Version, certify, State0), {stop, normal, State0} end; @@ -588,7 +581,7 @@ certify(#client_key_exchange{exchange_keys = Keys}, certify_client_key_exchange(ssl_handshake:decode_client_key(Keys, KeyAlg, Version), State) catch #alert{} = Alert -> - handle_own_alert(Alert, Version, certify_client_key_exchange, State), + handle_own_alert(Alert, Version, certify, State), {stop, normal, State} end; @@ -611,10 +604,9 @@ certify_client_key_exchange(#encrypted_premaster_secret{premaster_secret= EncPMS State1 = State0#state{connection_states = ConnectionStates, session = Session}, {Record, State} = next_record(State1), - next_state(cipher, Record, State); + next_state(certify, cipher, Record, State); #alert{} = Alert -> - handle_own_alert(Alert, Version, - certify_client_key_exchange, State0), + handle_own_alert(Alert, Version, certify, State0), {stop, normal, State0} end; @@ -626,10 +618,9 @@ certify_client_key_exchange(#client_diffie_hellman_public{dh_public = ClientPubl case dh_master_secret(crypto:mpint(P), crypto:mpint(G), ClientPublicDhKey, ServerDhPrivateKey, State0) of #state{} = State1 -> {Record, State} = next_record(State1), - next_state(cipher, Record, State); + next_state(certify, cipher, Record, State); #alert{} = Alert -> - handle_own_alert(Alert, Version, - certify_client_key_exchange, State0), + handle_own_alert(Alert, Version, certify, State0), {stop, normal, State0} end. @@ -639,7 +630,7 @@ certify_client_key_exchange(#client_diffie_hellman_public{dh_public = ClientPubl %%-------------------------------------------------------------------- cipher(#hello_request{}, State0) -> {Record, State} = next_record(State0), - next_state(hello, Record, State); + next_state(cipher, hello, Record, State); cipher(#certificate_verify{signature = Signature}, #state{role = server, @@ -652,7 +643,7 @@ cipher(#certificate_verify{signature = Signature}, Version, MasterSecret, Hashes) of valid -> {Record, State} = next_record(State0), - next_state(cipher, Record, State); + next_state(cipher, cipher, Record, State); #alert{} = Alert -> handle_own_alert(Alert, Version, cipher, State0), {stop, normal, State0} @@ -705,20 +696,32 @@ connection(#hello_request{}, #state{host = Host, port = Port, {Record, State} = next_record(State0#state{connection_states = ConnectionStates1, tls_handshake_hashes = Hashes1}), - next_state(hello, Record, State); -connection(#client_hello{} = Hello, #state{role = server} = State) -> - hello(Hello, State); - + next_state(connection, hello, Record, State); +connection(#client_hello{} = Hello, #state{role = server, allow_renegotiate = true} = State) -> + %% Mitigate Computational DoS attack + %% http://www.educatedguesswork.org/2011/10/ssltls_and_computational_dos.html + %% http://www.thc.org/thc-ssl-dos/ Rather than disabling client + %% initiated renegotiation we will disallow many client initiated + %% renegotiations immediately after each other. + erlang:send_after(?WAIT_TO_ALLOW_RENEGOTIATION, self(), allow_renegotiate), + hello(Hello, State#state{allow_renegotiate = false}); + +connection(#client_hello{}, #state{role = server, allow_renegotiate = false, + connection_states = ConnectionStates0, + socket = Socket, transport_cb = Transport, + negotiated_version = Version} = State0) -> + Alert = ?ALERT_REC(?WARNING, ?NO_RENEGOTIATION), + {BinMsg, ConnectionStates} = + encode_alert(Alert, Version, ConnectionStates0), + Transport:send(Socket, BinMsg), + next_state_connection(connection, State0#state{connection_states = ConnectionStates}); + connection(timeout, State) -> {next_state, connection, State, hibernate}; connection(Msg, State) -> handle_unexpected_message(Msg, connection, State). %%-------------------------------------------------------------------- --spec handle_event(term(), state_name(), #state{}) -> term(). -%% As it is not currently used gen_fsm_state_return() makes -%% dialyzer unhappy! -%% %% Description: Whenever a gen_fsm receives an event sent using %% gen_fsm:send_all_state_event/2, this function is called to handle %% the event. Not currently used! @@ -727,47 +730,16 @@ handle_event(_Event, StateName, State) -> {next_state, StateName, State, get_timeout(State)}. %%-------------------------------------------------------------------- --spec handle_sync_event(term(), from(), state_name(), #state{}) -> - gen_fsm_state_return() | - {reply, reply(), state_name(), #state{}} | - {reply, reply(), state_name(), #state{}, timeout()} | - {stop, reason(), reply(), #state{}}. -%% %% Description: Whenever a gen_fsm receives an event sent using %% gen_fsm:sync_send_all_state_event/2,3, this function is called to handle %% the event. %%-------------------------------------------------------------------- -handle_sync_event({application_data, Data0}, From, connection, - #state{socket = Socket, - negotiated_version = Version, - transport_cb = Transport, - connection_states = ConnectionStates0, - send_queue = SendQueue, - socket_options = SockOpts, - ssl_options = #ssl_options{renegotiate_at = RenegotiateAt}} - = State) -> +handle_sync_event({application_data, Data}, From, connection, State) -> %% We should look into having a worker process to do this to %% parallize send and receive decoding and not block the receiver %% if sending is overloading the socket. try - Data = encode_packet(Data0, SockOpts), - case encode_data(Data, Version, ConnectionStates0, RenegotiateAt) of - {Msgs, [], ConnectionStates} -> - Result = Transport:send(Socket, Msgs), - {reply, Result, - connection, State#state{connection_states = ConnectionStates}, - get_timeout(State)}; - {Msgs, RestData, ConnectionStates} -> - if - Msgs =/= [] -> - Transport:send(Socket, Msgs); - true -> - ok - end, - renegotiate(State#state{connection_states = ConnectionStates, - send_queue = queue:in_r({From, RestData}, SendQueue), - renegotiation = {true, internal}}) - end + write_application_data(Data, From, State) catch throw:Error -> {reply, Error, connection, State, get_timeout(State)} end; @@ -824,14 +796,12 @@ handle_sync_event({shutdown, How0}, _, StateName, end; handle_sync_event({recv, N}, From, connection = StateName, State0) -> - passive_receive(State0#state{bytes_to_read = N, from = From}, StateName); + passive_receive(State0#state{bytes_to_read = N, recv_from = From}, StateName); %% Doing renegotiate wait with handling request until renegotiate is -%% finished. Will be handled by next_state_connection/2. +%% finished. Will be handled by next_state_is_connection/2. handle_sync_event({recv, N}, From, StateName, State) -> - {next_state, StateName, - State#state{bytes_to_read = N, from = From, - recv_during_renegotiation = true}, + {next_state, StateName, State#state{bytes_to_read = N, recv_from = From}, get_timeout(State)}; handle_sync_event({new_user, User}, _From, StateName, @@ -869,7 +839,7 @@ handle_sync_event({set_opts, Opts0}, _From, StateName, Buffer =:= <<>>, Opts1#socket_options.active =:= false -> %% Need data, set active once {Record, State2} = next_record_if_active(State1), - case next_state(StateName, Record, State2) of + case next_state(StateName, StateName, Record, State2) of {next_state, StateName, State, Timeout} -> {reply, Reply, StateName, State, Timeout}; {stop, Reason, State} -> @@ -879,11 +849,11 @@ handle_sync_event({set_opts, Opts0}, _From, StateName, %% Active once already set {reply, Reply, StateName, State1, get_timeout(State1)}; true -> - case application_data(<<>>, State1) of + case read_application_data(<<>>, State1) of Stop = {stop,_,_} -> Stop; {Record, State2} -> - case next_state(StateName, Record, State2) of + case next_state(StateName, StateName, Record, State2) of {next_state, StateName, State, Timeout} -> {reply, Reply, StateName, State, Timeout}; {stop, Reason, State} -> @@ -919,11 +889,6 @@ handle_sync_event(peer_certificate, _, StateName, {reply, {ok, Cert}, StateName, State, get_timeout(State)}. %%-------------------------------------------------------------------- --spec handle_info(msg(),state_name(), #state{}) -> - {next_state, state_name(), #state{}}| - {next_state, state_name(), #state{}, timeout()} | - {stop, reason(), #state{}}. -%% %% Description: This function is called by a gen_fsm when it receives any %% other message than a synchronous or asynchronous event %% (or a system message). @@ -931,22 +896,18 @@ handle_sync_event(peer_certificate, _, StateName, %% raw data from TCP, unpack records handle_info({Protocol, _, Data}, StateName, - #state{data_tag = Protocol, - negotiated_version = Version} = State0) -> + #state{data_tag = Protocol} = State0) -> case next_tls_record(Data, State0) of {Record, State} -> - next_state(StateName, Record, State); + next_state(StateName, StateName, Record, State); #alert{} = Alert -> - handle_own_alert(Alert, Version, StateName, State0), + handle_normal_shutdown(Alert, StateName, State0), {stop, normal, State0} end; -handle_info({CloseTag, Socket}, _StateName, +handle_info({CloseTag, Socket}, StateName, #state{socket = Socket, close_tag = CloseTag, - negotiated_version = Version, - socket_options = Opts, - user_application = {_Mon,Pid}, from = From, - role = Role} = State) -> + negotiated_version = Version} = State) -> %% Note that as of TLS 1.1, %% failure to properly close a connection no longer requires that a %% session not be resumed. This is a change from TLS 1.0 to conform @@ -961,8 +922,7 @@ handle_info({CloseTag, Socket}, _StateName, %%invalidate_session(Role, Host, Port, Session) ok end, - alert_user(Opts#socket_options.active, Pid, From, - ?ALERT_REC(?WARNING, ?CLOSE_NOTIFY), Role), + handle_normal_shutdown(?ALERT_REC(?FATAL, ?CLOSE_NOTIFY), StateName, State), {stop, normal, State}; handle_info({ErrorTag, Socket, econnaborted}, StateName, @@ -971,26 +931,26 @@ handle_info({ErrorTag, Socket, econnaborted}, StateName, alert_user(User, ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE), Role), {stop, normal, State}; -handle_info({ErrorTag, Socket, Reason}, _, - #state{socket = Socket, from = User, - role = Role, error_tag = ErrorTag} = State) -> +handle_info({ErrorTag, Socket, Reason}, StateName, #state{socket = Socket, + error_tag = ErrorTag} = State) -> Report = io_lib:format("SSL: Socket error: ~p ~n", [Reason]), error_logger:info_report(Report), - alert_user(User, ?ALERT_REC(?FATAL, ?CLOSE_NOTIFY), Role), + handle_normal_shutdown(?ALERT_REC(?FATAL, ?CLOSE_NOTIFY), StateName, State), {stop, normal, State}; handle_info({'DOWN', MonitorRef, _, _, _}, _, State = #state{user_application={MonitorRef,_Pid}}) -> {stop, normal, State}; +handle_info(allow_renegotiate, StateName, State) -> + {next_state, StateName, State#state{allow_renegotiate = true}, get_timeout(State)}; + handle_info(Msg, StateName, State) -> Report = io_lib:format("SSL: Got unexpected info: ~p ~n", [Msg]), error_logger:info_report(Report), {next_state, StateName, State, get_timeout(State)}. %%-------------------------------------------------------------------- --spec terminate(reason(), state_name(), #state{}) -> term(). -%% %% Description:This function is called by a gen_fsm when it is about %% to terminate. It should be the opposite of Module:init/1 and do any %% necessary cleaning up. When it returns, the gen_fsm terminates with @@ -1021,8 +981,6 @@ terminate(Reason, _StateName, #state{transport_cb = Transport, Transport:close(Socket). %%-------------------------------------------------------------------- --spec code_change(term(), state_name(), #state{}, list()) -> {ok, state_name(), #state{}}. -%% %% code_change(OldVsn, StateName, State, Extra) -> {ok, StateName, NewState} %% Description: Convert process state when code is changed %%-------------------------------------------------------------------- @@ -1218,7 +1176,7 @@ handle_peer_cert(PeerCert, PublicKeyInfo, Session#session{peer_certificate = PeerCert}, public_key_info = PublicKeyInfo}, {Record, State} = next_record(State1), - next_state(certify, Record, State). + next_state(certify, certify, Record, State). certify_client(#state{client_certificate_requested = true, role = client, connection_states = ConnectionStates0, @@ -1260,8 +1218,7 @@ verify_client_cert(#state{client_certificate_requested = true, role = client, ignore -> State; #alert{} = Alert -> - handle_own_alert(Alert, Version, certify, State) - + throw(Alert) end; verify_client_cert(#state{client_certificate_requested = false} = State) -> State. @@ -1293,7 +1250,7 @@ do_server_hello(Type, #state{negotiated_version = Version, ConnectionStates, tls_handshake_hashes = Hashes}, {Record, State} = next_record(State3), - next_state(abbreviated, Record, State); + next_state(hello, abbreviated, Record, State); #alert{} = Alert -> handle_own_alert(Alert, Version, hello, State1), {stop, normal, State1} @@ -1313,7 +1270,7 @@ new_server_hello(#server_hello{cipher_suite = CipherSuite, cipher_suite = CipherSuite, compression_method = Compression}, {Record, State} = next_record(State2#state{session = Session}), - next_state(certify, Record, State) + next_state(hello, certify, Record, State) catch #alert{} = Alert -> handle_own_alert(Alert, Version, hello, State0), @@ -1325,7 +1282,7 @@ handle_new_session(NewId, CipherSuite, Compression, #state{session = Session0} = cipher_suite = CipherSuite, compression_method = Compression}, {Record, State} = next_record(State0#state{session = Session}), - next_state(certify, Record, State). + next_state(hello, certify, Record, State). handle_resumed_session(SessId, #state{connection_states = ConnectionStates0, negotiated_version = Version, @@ -1340,7 +1297,7 @@ handle_resumed_session(SessId, #state{connection_states = ConnectionStates0, next_record(State0#state{ connection_states = ConnectionStates1, session = Session}), - next_state(abbreviated, Record, State); + next_state(hello, abbreviated, Record, State); #alert{} = Alert -> handle_own_alert(Alert, Version, hello, State0), {stop, normal, State0} @@ -1357,10 +1314,10 @@ client_certify_and_key_exchange(#state{negotiated_version = Version} = client_certificate_requested = false, tls_handshake_hashes = Hashes}, {Record, State} = next_record(State2), - next_state(cipher, Record, State) + next_state(certify, cipher, Record, State) catch - #alert{} = Alert -> - handle_own_alert(Alert, Version, client_certify_and_key_exchange, State0), + throw:#alert{} = Alert -> + handle_own_alert(Alert, Version, certify, State0), {stop, normal, State0} end. @@ -1671,15 +1628,12 @@ encode_packet(Data, #socket_options{packet=Packet}) -> end. encode_size_packet(Bin, Size, Max) -> - Len = byte_size(Bin), + Len = erlang:byte_size(Bin), case Len > Max of true -> throw({error, {badarg, {packet_to_large, Len, Max}}}); false -> <<Len:Size, Bin/binary>> end. -encode_data(Data, Version, ConnectionStates, RenegotiateAt) -> - ssl_record:encode_data(Data, Version, ConnectionStates, RenegotiateAt). - decode_alerts(Bin) -> decode_alerts(Bin, []). @@ -1693,20 +1647,20 @@ passive_receive(State0 = #state{user_data_buffer = Buffer}, StateName) -> case Buffer of <<>> -> {Record, State} = next_record(State0), - next_state(StateName, Record, State); + next_state(StateName, StateName, Record, State); _ -> - case application_data(<<>>, State0) of + case read_application_data(<<>>, State0) of Stop = {stop, _, _} -> Stop; {Record, State} -> - next_state(StateName, Record, State) + next_state(StateName, StateName, Record, State) end end. -application_data(Data, #state{user_application = {_Mon, Pid}, +read_application_data(Data, #state{user_application = {_Mon, Pid}, socket_options = SOpts, bytes_to_read = BytesToRead, - from = From, + recv_from = From, user_data_buffer = Buffer0} = State0) -> Buffer1 = if Buffer0 =:= <<>> -> Data; @@ -1717,7 +1671,7 @@ application_data(Data, #state{user_application = {_Mon, Pid}, {ok, ClientData, Buffer} -> % Send data SocketOpt = deliver_app_data(SOpts, ClientData, Pid, From), State = State0#state{user_data_buffer = Buffer, - from = undefined, + recv_from = undefined, bytes_to_read = 0, socket_options = SocketOpt }, @@ -1727,7 +1681,7 @@ application_data(Data, #state{user_application = {_Mon, Pid}, %% Active and empty, get more data next_record_if_active(State); true -> %% We have more data - application_data(<<>>, State) + read_application_data(<<>>, State) end; {more, Buffer} -> % no reply, we need more data next_record(State0#state{user_data_buffer = Buffer}); @@ -1736,6 +1690,39 @@ application_data(Data, #state{user_application = {_Mon, Pid}, {stop, normal, State0} end. +write_application_data(Data0, From, #state{socket = Socket, + negotiated_version = Version, + transport_cb = Transport, + connection_states = ConnectionStates0, + send_queue = SendQueue, + socket_options = SockOpts, + ssl_options = #ssl_options{renegotiate_at = RenegotiateAt}} = State) -> + Data = encode_packet(Data0, SockOpts), + + case time_to_renegotiate(Data, ConnectionStates0, RenegotiateAt) of + true -> + renegotiate(State#state{send_queue = queue:in_r({From, Data}, SendQueue), + renegotiation = {true, internal}}); + false -> + {Msgs, ConnectionStates} = ssl_record:encode_data(Data, Version, ConnectionStates0), + Result = Transport:send(Socket, Msgs), + {reply, Result, + connection, State#state{connection_states = ConnectionStates}, get_timeout(State)} + end. + +time_to_renegotiate(_Data, #connection_states{current_write = + #connection_state{sequence_number = Num}}, RenegotiateAt) -> + + %% We could do test: + %% is_time_to_renegotiate((erlang:byte_size(_Data) div ?MAX_PLAIN_TEXT_LENGTH) + 1, RenegotiateAt), + %% but we chose to have a some what lower renegotiateAt and a much cheaper test + is_time_to_renegotiate(Num, RenegotiateAt). + +is_time_to_renegotiate(N, M) when N < M-> + false; +is_time_to_renegotiate(_,_) -> + true. + %% Picks ClientData get_data(_, _, <<>>) -> {more, <<>>}; @@ -1837,6 +1824,10 @@ header(N, Binary) -> send_or_reply(false, _Pid, From, Data) when From =/= undefined -> gen_fsm:reply(From, Data); +%% Can happen when handling own alert or tcp error/close and there is +%% no outstanding gen_fsm sync events +send_or_reply(false, no_pid, _, _) -> + ok; send_or_reply(_, Pid, _From, Data) -> send_user(Pid, Data). @@ -1861,18 +1852,18 @@ handle_tls_handshake(Handle, StateName, #state{tls_packets = [Packet | Packets]} Stop end. -next_state(_, #alert{} = Alert, #state{negotiated_version = Version} = State) -> - handle_own_alert(Alert, Version, decipher_error, State), +next_state(Current,_, #alert{} = Alert, #state{negotiated_version = Version} = State) -> + handle_own_alert(Alert, Version, Current, State), {stop, normal, State}; -next_state(Next, no_record, State) -> +next_state(_,Next, no_record, State) -> {next_state, Next, State, get_timeout(State)}; -next_state(Next, #ssl_tls{type = ?ALERT, fragment = EncAlerts}, State) -> +next_state(_,Next, #ssl_tls{type = ?ALERT, fragment = EncAlerts}, State) -> Alerts = decode_alerts(EncAlerts), handle_alerts(Alerts, {next_state, Next, State, get_timeout(State)}); -next_state(StateName, #ssl_tls{type = ?HANDSHAKE, fragment = Data}, +next_state(Current, Next, #ssl_tls{type = ?HANDSHAKE, fragment = Data}, State0 = #state{tls_handshake_buffer = Buf0, negotiated_version = Version}) -> Handle = fun({#hello_request{} = Packet, _}, {next_state, connection = SName, State}) -> @@ -1898,30 +1889,30 @@ next_state(StateName, #ssl_tls{type = ?HANDSHAKE, fragment = Data}, try {Packets, Buf} = ssl_handshake:get_tls_handshake(Data,Buf0), State = State0#state{tls_packets = Packets, tls_handshake_buffer = Buf}, - handle_tls_handshake(Handle, StateName, State) + handle_tls_handshake(Handle, Next, State) catch throw:#alert{} = Alert -> - handle_own_alert(Alert, Version, StateName, State0), + handle_own_alert(Alert, Version, Current, State0), {stop, normal, State0} end; -next_state(StateName, #ssl_tls{type = ?APPLICATION_DATA, fragment = Data}, State0) -> - case application_data(Data, State0) of +next_state(_, StateName, #ssl_tls{type = ?APPLICATION_DATA, fragment = Data}, State0) -> + case read_application_data(Data, State0) of Stop = {stop,_,_} -> Stop; {Record, State} -> - next_state(StateName, Record, State) + next_state(StateName, StateName, Record, State) end; -next_state(StateName, #ssl_tls{type = ?CHANGE_CIPHER_SPEC, fragment = <<1>>} = +next_state(Current, Next, #ssl_tls{type = ?CHANGE_CIPHER_SPEC, fragment = <<1>>} = _ChangeCipher, #state{connection_states = ConnectionStates0} = State0) -> ConnectionStates1 = ssl_record:activate_pending_connection_state(ConnectionStates0, read), {Record, State} = next_record(State0#state{connection_states = ConnectionStates1}), - next_state(StateName, Record, State); -next_state(StateName, #ssl_tls{type = _Unknown}, State0) -> + next_state(Current, Next, Record, State); +next_state(Current, Next, #ssl_tls{type = _Unknown}, State0) -> %% Ignore unknown type {Record, State} = next_record(State0), - next_state(StateName, Record, State). + next_state(Current, Next, Record, State). next_tls_record(Data, #state{tls_record_buffer = Buf0, tls_cipher_texts = CT0} = State0) -> @@ -1960,50 +1951,36 @@ next_state_connection(StateName, #state{send_queue = Queue0, negotiated_version = Version, socket = Socket, transport_cb = Transport, - connection_states = ConnectionStates0, - ssl_options = #ssl_options{renegotiate_at = RenegotiateAt} + connection_states = ConnectionStates0 } = State) -> - %% Send queued up data + %% Send queued up data that was queued while renegotiating case queue:out(Queue0) of {{value, {From, Data}}, Queue} -> - case encode_data(Data, Version, ConnectionStates0, RenegotiateAt) of - {Msgs, [], ConnectionStates} -> - Result = Transport:send(Socket, Msgs), - gen_fsm:reply(From, Result), - next_state_connection(StateName, - State#state{connection_states = ConnectionStates, - send_queue = Queue}); - %% This is unlikely to happen. User configuration of the - %% undocumented test option renegotiation_at can make it more likely. - {Msgs, RestData, ConnectionStates} -> - if - Msgs =/= [] -> - Transport:send(Socket, Msgs); - true -> - ok - end, - renegotiate(State#state{connection_states = ConnectionStates, - send_queue = queue:in_r({From, RestData}, Queue), - renegotiation = {true, internal}}) - end; + {Msgs, ConnectionStates} = + ssl_record:encode_data(Data, Version, ConnectionStates0), + Result = Transport:send(Socket, Msgs), + gen_fsm:reply(From, Result), + next_state_connection(StateName, + State#state{connection_states = ConnectionStates, + send_queue = Queue}); {empty, Queue0} -> - next_state_is_connection(State) + next_state_is_connection(StateName, State) end. %% In next_state_is_connection/1: clear tls_handshake_hashes, %% premaster_secret and public_key_info (only needed during handshake) %% to reduce memory foot print of a connection. -next_state_is_connection(State = - #state{recv_during_renegotiation = true, socket_options = - #socket_options{active = false}}) -> - passive_receive(State#state{recv_during_renegotiation = false, - premaster_secret = undefined, +next_state_is_connection(_, State = + #state{recv_from = From, + socket_options = + #socket_options{active = false}}) when From =/= undefined -> + passive_receive(State#state{premaster_secret = undefined, public_key_info = undefined, tls_handshake_hashes = {<<>>, <<>>}}, connection); -next_state_is_connection(State0) -> +next_state_is_connection(StateName, State0) -> {Record, State} = next_record_if_active(State0), - next_state(connection, Record, State#state{premaster_secret = undefined, + next_state(StateName, connection, Record, State#state{premaster_secret = undefined, public_key_info = undefined, tls_handshake_hashes = {<<>>, <<>>}}). @@ -2059,7 +2036,7 @@ initial_state(Role, Host, Port, Socket, {SSLOptions, SocketOptions}, User, log_alert = true, session_cache_cb = SessionCacheCb, renegotiation = {false, first}, - recv_during_renegotiation = false, + recv_from = undefined, send_queue = queue:new() }. @@ -2172,16 +2149,14 @@ handle_alert(#alert{level = ?FATAL} = Alert, StateName, {stop, normal, State}; handle_alert(#alert{level = ?WARNING, description = ?CLOSE_NOTIFY} = Alert, - StateName, #state{from = From, role = Role, - user_application = {_Mon, Pid}, socket_options = Opts} = State) -> - alert_user(StateName, Opts, Pid, From, Alert, Role), + StateName, State) -> + handle_normal_shutdown(Alert, StateName, State), {stop, normal, State}; handle_alert(#alert{level = ?WARNING, description = ?NO_RENEGOTIATION} = Alert, StateName, - #state{log_alert = Log, renegotiation = {true, internal}, from = From, - role = Role} = State) -> + #state{log_alert = Log, renegotiation = {true, internal}} = State) -> log_alert(Log, StateName, Alert), - alert_user(From, Alert, Role), + handle_normal_shutdown(Alert, StateName, State), {stop, normal, State}; handle_alert(#alert{level = ?WARNING, description = ?NO_RENEGOTIATION} = Alert, StateName, @@ -2189,13 +2164,13 @@ handle_alert(#alert{level = ?WARNING, description = ?NO_RENEGOTIATION} = Alert, log_alert(Log, StateName, Alert), gen_fsm:reply(From, {error, renegotiation_rejected}), {Record, State} = next_record(State0), - next_state(connection, Record, State); + next_state(StateName, connection, Record, State); handle_alert(#alert{level = ?WARNING, description = ?USER_CANCELED} = Alert, StateName, #state{log_alert = Log} = State0) -> log_alert(Log, StateName, Alert), {Record, State} = next_record(State0), - next_state(StateName, Record, State). + next_state(StateName, StateName, Record, State). alert_user(connection, Opts, Pid, From, Alert, Role) -> alert_user(Opts#socket_options.active, Pid, From, Alert, Role); @@ -2227,13 +2202,11 @@ log_alert(true, Info, Alert) -> log_alert(false, _, _) -> ok. -handle_own_alert(Alert, Version, Info, +handle_own_alert(Alert, Version, StateName, #state{transport_cb = Transport, socket = Socket, - from = User, - role = Role, connection_states = ConnectionStates, - log_alert = Log}) -> + log_alert = Log} = State) -> try %% Try to tell the other side {BinMsg, _} = encode_alert(Alert, Version, ConnectionStates), @@ -2243,12 +2216,20 @@ handle_own_alert(Alert, Version, Info, ignore end, try %% Try to tell the local user - log_alert(Log, Info, Alert), - alert_user(User, Alert, Role) + log_alert(Log, StateName, Alert), + handle_normal_shutdown(Alert,StateName, State) catch _:_ -> ok end. +handle_normal_shutdown(Alert, _, #state{from = User, role = Role, renegotiation = {false, first}}) -> + alert_user(User, Alert, Role); + +handle_normal_shutdown(Alert, StateName, #state{socket_options = Opts, + user_application = {_Mon, Pid}, + from = User, role = Role}) -> + alert_user(StateName, Opts, Pid, User, Alert, Role). + handle_unexpected_message(Msg, Info, #state{negotiated_version = Version} = State) -> Alert = ?ALERT_REC(?FATAL,?UNEXPECTED_MESSAGE), handle_own_alert(Alert, Version, {Info, Msg}, State), @@ -2261,7 +2242,7 @@ make_premaster_secret(_, _) -> undefined. mpint_binary(Binary) -> - Size = byte_size(Binary), + Size = erlang:byte_size(Binary), <<?UINT32(Size), Binary/binary>>. @@ -2298,7 +2279,7 @@ renegotiate(#state{role = server, {Record, State} = next_record(State0#state{connection_states = ConnectionStates, tls_handshake_hashes = Hs0}), - next_state(hello, Record, State). + next_state(connection, hello, Record, State#state{allow_renegotiate = true}). notify_senders(SendQueue) -> lists:foreach(fun({From, _}) -> diff --git a/lib/ssl/src/ssl_dist_sup.erl b/lib/ssl/src/ssl_dist_sup.erl index c1912401d7..9d9afb7707 100644 --- a/lib/ssl/src/ssl_dist_sup.erl +++ b/lib/ssl/src/ssl_dist_sup.erl @@ -41,7 +41,6 @@ start_link() -> %%%========================================================================= %%% Supervisor callback %%%========================================================================= --spec init([]) -> {ok, {SupFlags :: tuple(), [ChildSpec :: tuple()]}}. init([]) -> SessionCertManager = session_and_cert_manager_child_spec(), diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl index 7eb7f44df6..371f475c85 100644 --- a/lib/ssl/src/ssl_handshake.erl +++ b/lib/ssl/src/ssl_handshake.erl @@ -447,7 +447,7 @@ server_hello_done() -> -spec encode_handshake(tls_handshake(), tls_version()) -> iolist(). %% %% Description: Encode a handshake packet to binary -%%-------------------------------------------------------------------- +%%--------------------------------------------------------------------x encode_handshake(Package, Version) -> {MsgType, Bin} = enc_hs(Package, Version), Len = byte_size(Bin), diff --git a/lib/ssl/src/ssl_manager.erl b/lib/ssl/src/ssl_manager.erl index 6a44ef8c3e..6389ff03f5 100644 --- a/lib/ssl/src/ssl_manager.erl +++ b/lib/ssl/src/ssl_manager.erl @@ -51,7 +51,7 @@ session_lifetime, certificate_db, session_validation_timer, - last_delay_timer %% Keep for testing purposes + last_delay_timer = {undefined, undefined}%% Keep for testing purposes }). -define('24H_in_msec', 8640000). @@ -427,7 +427,7 @@ delay_time() -> ?CLEAN_SESSION_DB end. -invalidate_session(Cache, CacheCb, Key, Session, State) -> +invalidate_session(Cache, CacheCb, Key, Session, #state{last_delay_timer = LastTimer} = State) -> case CacheCb:lookup(Cache, Key) of undefined -> %% Session is already invalidated {noreply, State}; @@ -441,5 +441,10 @@ invalidate_session(Cache, CacheCb, Key, Session, State) -> CacheCb:update(Cache, Key, Session#session{is_resumable = false}), TRef = erlang:send_after(delay_time(), self(), {delayed_clean_session, Key}), - {noreply, State#state{last_delay_timer = TRef}} + {noreply, State#state{last_delay_timer = last_delay_timer(Key, TRef, LastTimer)}} end. + +last_delay_timer({{_,_},_}, TRef, {LastServer, _}) -> + {LastServer, TRef}; +last_delay_timer({_,_}, TRef, {_, LastClient}) -> + {TRef, LastClient}. diff --git a/lib/ssl/src/ssl_record.erl b/lib/ssl/src/ssl_record.erl index 72091fdd5f..830026c825 100644 --- a/lib/ssl/src/ssl_record.erl +++ b/lib/ssl/src/ssl_record.erl @@ -48,7 +48,7 @@ %% Encoding records -export([encode_handshake/3, encode_alert_record/3, - encode_change_cipher_spec/2, encode_data/4]). + encode_change_cipher_spec/2, encode_data/3]). %% Decoding -export([decode_cipher_text/2]). @@ -503,36 +503,18 @@ decode_cipher_text(CipherText, ConnnectionStates0) -> Alert end. %%-------------------------------------------------------------------- --spec encode_data(iolist(), tls_version(), #connection_states{}, integer()) -> - {iolist(), iolist(), #connection_states{}}. +-spec encode_data(binary(), tls_version(), #connection_states{}) -> + {iolist(), #connection_states{}}. %% %% Description: Encodes data to send on the ssl-socket. %%-------------------------------------------------------------------- -encode_data(Frag, Version, ConnectionStates, RenegotiateAt) - when byte_size(Frag) < (?MAX_PLAIN_TEXT_LENGTH - 2048) -> - case encode_plain_text(?APPLICATION_DATA,Version,Frag,ConnectionStates, RenegotiateAt) of - {renegotiate, Data} -> - {[], Data, ConnectionStates}; - {Msg, CS} -> - {Msg, [], CS} - end; - -encode_data(Frag, Version, ConnectionStates, RenegotiateAt) when is_binary(Frag) -> - Data = split_bin(Frag, ?MAX_PLAIN_TEXT_LENGTH - 2048), - encode_data(Data, Version, ConnectionStates, RenegotiateAt); - -encode_data(Data, Version, ConnectionStates0, RenegotiateAt) when is_list(Data) -> - {ConnectionStates, EncodedMsg, NotEncdedData} = - lists:foldl(fun(B, {CS0, Encoded, Rest}) -> - case encode_plain_text(?APPLICATION_DATA, - Version, B, CS0, RenegotiateAt) of - {renegotiate, NotEnc} -> - {CS0, Encoded, [NotEnc | Rest]}; - {Enc, CS1} -> - {CS1, [Enc | Encoded], Rest} - end - end, {ConnectionStates0, [], []}, Data), - {lists:reverse(EncodedMsg), lists:reverse(NotEncdedData), ConnectionStates}. +encode_data(Frag, Version, + #connection_states{current_write = #connection_state{ + security_parameters = + #security_parameters{bulk_cipher_algorithm = BCA}}} = + ConnectionStates) -> + Data = split_bin(Frag, ?MAX_PLAIN_TEXT_LENGTH, Version, BCA), + encode_iolist(?APPLICATION_DATA, Data, Version, ConnectionStates). %%-------------------------------------------------------------------- -spec encode_handshake(iolist(), tls_version(), #connection_states{}) -> @@ -566,6 +548,14 @@ encode_change_cipher_spec(Version, ConnectionStates) -> %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- +encode_iolist(Type, Data, Version, ConnectionStates0) -> + {ConnectionStates, EncodedMsg} = + lists:foldl(fun(Text, {CS0, Encoded}) -> + {Enc, CS1} = encode_plain_text(Type, Version, Text, CS0), + {CS1, [Enc | Encoded]} + end, {ConnectionStates0, []}, Data), + {lists:reverse(EncodedMsg), ConnectionStates}. + highest_protocol_version() -> highest_protocol_version(supported_protocol_versions()). @@ -602,29 +592,23 @@ record_protocol_role(client) -> record_protocol_role(server) -> ?SERVER. -split_bin(Bin, ChunkSize) -> - split_bin(Bin, ChunkSize, []). +%% 1/n-1 splitting countermeasure Rizzo/Duong-Beast, RC4 chiphers are not vulnerable to this attack. +split_bin(<<FirstByte:8, Rest/binary>>, ChunkSize, Version, BCA) when BCA =/= ?RC4 andalso ({3, 1} == Version orelse + {3, 0} == Version) -> + do_split_bin(Rest, ChunkSize, [[FirstByte]]); +split_bin(Bin, ChunkSize, _, _) -> + do_split_bin(Bin, ChunkSize, []). -split_bin(<<>>, _, Acc) -> +do_split_bin(<<>>, _, Acc) -> lists:reverse(Acc); -split_bin(Bin, ChunkSize, Acc) -> +do_split_bin(Bin, ChunkSize, Acc) -> case Bin of <<Chunk:ChunkSize/binary, Rest/binary>> -> - split_bin(Rest, ChunkSize, [Chunk | Acc]); + do_split_bin(Rest, ChunkSize, [Chunk | Acc]); _ -> lists:reverse(Acc, [Bin]) end. -encode_plain_text(Type, Version, Data, ConnectionStates, RenegotiateAt) -> - #connection_states{current_write = - #connection_state{sequence_number = Num}} = ConnectionStates, - case renegotiate(Num, RenegotiateAt) of - false -> - encode_plain_text(Type, Version, Data, ConnectionStates); - true -> - {renegotiate, Data} - end. - encode_plain_text(Type, Version, Data, ConnectionStates) -> #connection_states{current_write=#connection_state{ compression_state=CompS0, @@ -637,11 +621,6 @@ encode_plain_text(Type, Version, Data, ConnectionStates) -> CTBin = encode_tls_cipher_text(Type, Version, CipherText), {CTBin, ConnectionStates#connection_states{current_write = CS2}}. -renegotiate(N, M) when N < M-> - false; -renegotiate(_,_) -> - true. - encode_tls_cipher_text(Type, {MajVer, MinVer}, Fragment) -> Length = erlang:iolist_size(Fragment), [<<?BYTE(Type), ?BYTE(MajVer), ?BYTE(MinVer), ?UINT16(Length)>>, Fragment]. diff --git a/lib/ssl/src/ssl_record.hrl b/lib/ssl/src/ssl_record.hrl index 5fb0070b91..282d642138 100644 --- a/lib/ssl/src/ssl_record.hrl +++ b/lib/ssl/src/ssl_record.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2010. All Rights Reserved. +%% Copyright Ericsson AB 2007-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -70,9 +70,10 @@ -define(MAX_SEQENCE_NUMBER, 18446744073709552000). %% math:pow(2, 64) - 1 = 1.8446744073709552e19 %% Sequence numbers can not wrap so when max is about to be reached we should renegotiate. %% We will renegotiate a little before so that there will be sequence numbers left -%% for the rehandshake and a little data. --define(MARGIN, 100). --define(DEFAULT_RENEGOTIATE_AT, ?MAX_SEQENCE_NUMBER - ?MARGIN). +%% for the rehandshake and a little data. Currently we decided to renegotiate a little more +%% often as we can have a cheaper test to check if it is time to renegotiate. It will still +%% be fairly seldom. +-define(DEFAULT_RENEGOTIATE_AT, 268435456). %% math:pow(2, 28) %% ConnectionEnd -define(SERVER, 0). diff --git a/lib/ssl/src/ssl_session_cache.erl b/lib/ssl/src/ssl_session_cache.erl index 93969f628f..f9bbf905e1 100644 --- a/lib/ssl/src/ssl_session_cache.erl +++ b/lib/ssl/src/ssl_session_cache.erl @@ -28,27 +28,19 @@ -export([init/1, terminate/1, lookup/2, update/3, delete/2, foldl/3, select_session/2]). --type key() :: {{host(), inet:port_number()}, session_id()} | {inet:port_number(), session_id()}. - %%-------------------------------------------------------------------- --spec init(list()) -> db_handle(). %% Returns reference to the cache (opaque) -%% %% Description: Return table reference. Called by ssl_manager process. %%-------------------------------------------------------------------- init(_) -> ets:new(cache_name(), [set, protected]). %%-------------------------------------------------------------------- --spec terminate(db_handle()) -> any(). -%% %% Description: Handles cache table at termination of ssl manager. %%-------------------------------------------------------------------- terminate(Cache) -> ets:delete(Cache). %%-------------------------------------------------------------------- --spec lookup(db_handle(), key()) -> #session{} | undefined. -%% %% Description: Looks up a cach entry. Should be callable from any %% process. %%-------------------------------------------------------------------- @@ -61,8 +53,6 @@ lookup(Cache, Key) -> end. %%-------------------------------------------------------------------- --spec update(db_handle(), key(), #session{}) -> any(). -%% %% Description: Caches a new session or updates a already cached one. %% Will only be called from the ssl_manager process. %%-------------------------------------------------------------------- @@ -70,8 +60,6 @@ update(Cache, Key, Session) -> ets:insert(Cache, {Key, Session}). %%-------------------------------------------------------------------- --spec delete(db_handle(), key()) -> any(). -%% %% Description: Delets a cache entry. %% Will only be called from the ssl_manager process. %%-------------------------------------------------------------------- @@ -79,8 +67,6 @@ delete(Cache, Key) -> ets:delete(Cache, Key). %%-------------------------------------------------------------------- --spec foldl(fun(), term(), db_handle()) -> term(). -%% %% Description: Calls Fun(Elem, AccIn) on successive elements of the %% cache, starting with AccIn == Acc0. Fun/2 must return a new %% accumulator which is passed to the next call. The function returns @@ -91,8 +77,6 @@ foldl(Fun, Acc0, Cache) -> ets:foldl(Fun, Acc0, Cache). %%-------------------------------------------------------------------- --spec select_session(db_handle(), {host(), inet:port_number()} | inet:port_number()) -> [#session{}]. -%% %% Description: Selects a session that could be reused. Should be callable %% from any process. %%-------------------------------------------------------------------- diff --git a/lib/ssl/src/ssl_session_cache_api.erl b/lib/ssl/src/ssl_session_cache_api.erl index f8416bf327..f2b22b0f1b 100644 --- a/lib/ssl/src/ssl_session_cache_api.erl +++ b/lib/ssl/src/ssl_session_cache_api.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -20,18 +20,15 @@ %% -module(ssl_session_cache_api). +-include("ssl_handshake.hrl"). +-include("ssl_internal.hrl"). --export([behaviour_info/1]). +-type key() :: {{host(), inet:port_number()}, session_id()} | {inet:port_number(), session_id()}. -behaviour_info(callbacks) -> - [ - {init, 1}, - {terminate, 1}, - {lookup, 2}, - {update, 3}, - {delete, 2}, - {foldl, 3}, - {select_session, 2} - ]; -behaviour_info(_) -> - undefined. +-callback init(list()) -> db_handle(). +-callback terminate(db_handle()) -> any(). +-callback lookup(db_handle(), key()) -> #session{} | undefined. +-callback update(db_handle(), key(), #session{}) -> any(). +-callback delete(db_handle(), key()) -> any(). +-callback foldl(fun(), term(), db_handle()) -> term(). +-callback select_session(db_handle(), {host(), inet:port_number()} | inet:port_number()) -> [#session{}]. diff --git a/lib/ssl/src/ssl_sup.erl b/lib/ssl/src/ssl_sup.erl index cb10b1362a..59039a6e0a 100644 --- a/lib/ssl/src/ssl_sup.erl +++ b/lib/ssl/src/ssl_sup.erl @@ -41,7 +41,6 @@ start_link() -> %%%========================================================================= %%% Supervisor callback %%%========================================================================= --spec init([]) -> {ok, {SupFlags :: tuple(), [ChildSpec :: tuple()]}}. init([]) -> %% OLD ssl - moved start to ssl.erl only if old diff --git a/lib/ssl/test/erl_make_certs.erl b/lib/ssl/test/erl_make_certs.erl index 8b01ca3ad4..254aa6d2f9 100644 --- a/lib/ssl/test/erl_make_certs.erl +++ b/lib/ssl/test/erl_make_certs.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010. All Rights Reserved. +%% Copyright Ericsson AB 2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -175,7 +175,7 @@ issuer(true, Opts, SubjectKey) -> issuer({Issuer, IssuerKey}, _Opts, _SubjectKey) when is_binary(Issuer) -> {issuer_der(Issuer), decode_key(IssuerKey)}; issuer({File, IssuerKey}, _Opts, _SubjectKey) when is_list(File) -> - {ok, [{cert, Cert, _}|_]} = public_key:pem_to_der(File), + {ok, [{cert, Cert, _}|_]} = pem_to_der(File), {issuer_der(Cert), decode_key(IssuerKey)}. issuer_der(Issuer) -> @@ -185,7 +185,7 @@ issuer_der(Issuer) -> Subject. subject(undefined, IsRootCA) -> - User = if IsRootCA -> "RootCA"; true -> os:getenv("USER") end, + User = if IsRootCA -> "RootCA"; true -> user() end, Opts = [{email, User ++ "@erlang.org"}, {name, User}, {city, "Stockholm"}, @@ -196,6 +196,14 @@ subject(undefined, IsRootCA) -> subject(Opts, _) -> subject(Opts). +user() -> + case os:getenv("USER") of + false -> + "test_user"; + User -> + User + end. + subject(SubjectOpts) when is_list(SubjectOpts) -> Encode = fun(Opt) -> {Type,Value} = subject_enc(Opt), diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl index d9cb8002ed..527263363c 100644 --- a/lib/ssl/test/ssl_basic_SUITE.erl +++ b/lib/ssl/test/ssl_basic_SUITE.erl @@ -36,6 +36,7 @@ -define(LONG_TIMEOUT, 600000). -define(EXPIRE, 10). -define(SLEEP, 500). +-define(RENEGOTIATION_DISABLE_TIME, 12000). %% Test server callback functions %%-------------------------------------------------------------------- @@ -256,7 +257,9 @@ all() -> %%different_ca_peer_sign, no_reuses_session_server_restart_new_cert, no_reuses_session_server_restart_new_cert_file, reuseaddr, - hibernate, connect_twice + hibernate, connect_twice, renegotiate_dos_mitigate_active, + renegotiate_dos_mitigate_passive, + tcp_error_propagation_in_active_mode, rizzo, no_rizzo_rc4 ]. groups() -> @@ -393,8 +396,8 @@ controlling_process(Config) when is_list(Config) -> ClientOpts = ?config(client_opts, Config), ServerOpts = ?config(server_opts, Config), {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), - ClientMsg = "Hello server", - ServerMsg = "Hello client", + ClientMsg = "Server hello", + ServerMsg = "Client hello", Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, {from, self()}, @@ -415,11 +418,15 @@ controlling_process(Config) when is_list(Config) -> [self(), Client, Server]), receive + {ssl, _, "S"} -> + receive_s_rizzo_duong_beast(); {ssl, _, ServerMsg} -> receive {ssl, _, ClientMsg} -> ok end; + {ssl, _, "C"} -> + receive_c_rizzo_duong_beast(); {ssl, _, ClientMsg} -> receive {ssl, _, ServerMsg} -> @@ -440,6 +447,28 @@ controlling_process_result(Socket, Pid, Msg) -> ssl:send(Socket, Msg), no_result_msg. +receive_s_rizzo_duong_beast() -> + receive + {ssl, _, "erver hello"} -> + receive + {ssl, _, "C"} -> + receive + {ssl, _, "lient hello"} -> + ok + end + end + end. +receive_c_rizzo_duong_beast() -> + receive + {ssl, _, "lient hello"} -> + receive + {ssl, _, "S"} -> + receive + {ssl, _, "erver hello"} -> + ok + end + end + end. %%-------------------------------------------------------------------- controller_dies(doc) -> ["Test that the socket is closed after controlling process dies"]; @@ -1231,6 +1260,11 @@ upgrade_result(Socket) -> %% Make sure binary is inherited from tcp socket and that we do %% not get the list default! receive + {ssl, _, <<"H">>} -> + receive + {ssl, _, <<"ello world">>} -> + ok + end; {ssl, _, <<"Hello world">>} -> ok end. @@ -1532,14 +1566,14 @@ eoptions(Config) when is_list(Config) -> {cacertfile, ""}, {dhfile,'dh.pem' }, {ciphers, [{foo, bar, sha, ignore}]}, - {reuse_session, foo}, - {reuse_sessions, 0}, + {reuse_session, foo}, + {reuse_sessions, 0}, {renegotiate_at, "10"}, - {debug, 1}, + {debug, 1}, {mode, depech}, - {packet, 8.0}, - {packet_size, "2"}, - {header, a}, + {packet, 8.0}, + {packet_size, "2"}, + {header, a}, {active, trice}, {key, 'key.pem' }], @@ -2313,8 +2347,8 @@ server_verify_client_once_passive(Config) when is_list(Config) -> {options, [{active, false} | ClientOpts]}]), ssl_test_lib:check_result(Server, ok, Client0, ok), - ssl_test_lib:close(Client0), Server ! {listen, {mfa, {ssl_test_lib, no_result, []}}}, + ssl_test_lib:close(Client0), Client1 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, {host, Hostname}, {from, self()}, @@ -2340,7 +2374,7 @@ server_verify_client_once_active(Config) when is_list(Config) -> Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, {from, self()}, {mfa, {?MODULE, send_recv_result_active, []}}, - {options, [{active, once}, {verify, verify_peer}, + {options, [{active, true}, {verify, verify_peer}, {verify_client_once, true} | ServerOpts]}]), Port = ssl_test_lib:inet_port(Server), @@ -2351,8 +2385,8 @@ server_verify_client_once_active(Config) when is_list(Config) -> {options, [{active, true} | ClientOpts]}]), ssl_test_lib:check_result(Server, ok, Client0, ok), - ssl_test_lib:close(Client0), Server ! {listen, {mfa, {ssl_test_lib, no_result, []}}}, + ssl_test_lib:close(Client0), Client1 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, {host, Hostname}, {from, self()}, @@ -2389,8 +2423,8 @@ server_verify_client_once_active_once(Config) when is_list(Config) -> {options, [{active, once} | ClientOpts]}]), ssl_test_lib:check_result(Server, ok, Client0, ok), - ssl_test_lib:close(Client0), Server ! {listen, {mfa, {ssl_test_lib, no_result, []}}}, + ssl_test_lib:close(Client0), Client1 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, {host, Hostname}, {from, self()}, @@ -2724,17 +2758,28 @@ client_no_wrap_sequence_number(Config) when is_list(Config) -> {options, ServerOpts}]), Port = ssl_test_lib:inet_port(Server), + Version = ssl_record:highest_protocol_version(ssl_record:supported_protocol_versions()), + Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, {host, Hostname}, {from, self()}, {mfa, {ssl_test_lib, - trigger_renegotiate, [[ErlData, N+2]]}}, + trigger_renegotiate, [[ErlData, treashold(N, Version)]]}}, {options, [{reuse_sessions, false}, {renegotiate_at, N} | ClientOpts]}]), ssl_test_lib:check_result(Client, ok), ssl_test_lib:close(Server), ssl_test_lib:close(Client). + + %% First two clauses handles 1/n-1 splitting countermeasure Rizzo/Duong-Beast +treashold(N, {3,0}) -> + (N div 2) + 1; +treashold(N, {3,1}) -> + (N div 2) + 1; +treashold(N, _) -> + N + 1. + %%-------------------------------------------------------------------- server_no_wrap_sequence_number(doc) -> ["Test that erlang server will renegotiate session when", @@ -2988,8 +3033,8 @@ invalid_signature_server(Config) when is_list(Config) -> {from, self()}, {options, [{verify, verify_peer} | ClientOpts]}]), - ssl_test_lib:check_result(Server, {error, "bad certificate"}, - Client, {error,"bad certificate"}). + tcp_delivery_workaround(Server, {error, "bad certificate"}, + Client, {error,"bad certificate"}). %%-------------------------------------------------------------------- @@ -3034,42 +3079,47 @@ invalid_signature_client(Config) when is_list(Config) -> tcp_delivery_workaround(Server, ServerMsg, Client, ClientMsg) -> receive {Server, ServerMsg} -> - receive - {Client, ClientMsg} -> - ok; - {Client, {error,closed}} -> - test_server:format("client got close"), - ok; - Unexpected -> - test_server:fail(Unexpected) - end; + client_msg(Client, ClientMsg); {Client, ClientMsg} -> - receive - {Server, ServerMsg} -> - ok; - Unexpected -> - test_server:fail(Unexpected) - end; + server_msg(Server, ServerMsg); {Client, {error,closed}} -> - receive - {Server, ServerMsg} -> - ok; - Unexpected -> - test_server:fail(Unexpected) - end; + server_msg(Server, ServerMsg); {Server, {error,closed}} -> - receive - {Client, ClientMsg} -> - ok; - {Client, {error,closed}} -> - test_server:format("client got close"), - ok; - Unexpected -> - test_server:fail(Unexpected) - end; + client_msg(Client, ClientMsg); + {Client, {error, esslconnect}} -> + server_msg(Server, ServerMsg); + {Server, {error, esslaccept}} -> + client_msg(Client, ClientMsg) + end. + +client_msg(Client, ClientMsg) -> + receive + {Client, ClientMsg} -> + ok; + {Client, {error,closed}} -> + test_server:format("client got close"), + ok; + {Client, {error, esslconnect}} -> + test_server:format("client got econnaborted"), + ok; Unexpected -> test_server:fail(Unexpected) end. + +server_msg(Server, ServerMsg) -> + receive + {Server, ServerMsg} -> + ok; + {Server, {error,closed}} -> + test_server:format("server got close"), + ok; + {Server, {error, esslaccept}} -> + test_server:format("server got econnaborted"), + ok; + Unexpected -> + test_server:fail(Unexpected) + end. + %%-------------------------------------------------------------------- cert_expired(doc) -> ["Test server with invalid signature"]; @@ -3647,6 +3697,166 @@ connect_twice(Config) when is_list(Config) -> ssl_test_lib:close(Client), ssl_test_lib:close(Client1). +%%-------------------------------------------------------------------- +renegotiate_dos_mitigate_active(doc) -> + ["Mitigate DOS computational attack by not allowing client to renegotiate many times in a row", + "immediately after each other"]; + +renegotiate_dos_mitigate_active(suite) -> + []; + +renegotiate_dos_mitigate_active(Config) when is_list(Config) -> + ServerOpts = ?config(server_opts, Config), + ClientOpts = ?config(client_opts, Config), + + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + + Server = + ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, send_recv_result_active, []}}, + {options, [ServerOpts]}]), + Port = ssl_test_lib:inet_port(Server), + + Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, + renegotiate_immediately, []}}, + {options, ClientOpts}]), + + ssl_test_lib:check_result(Client, ok, Server, ok), + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). + +%%-------------------------------------------------------------------- +renegotiate_dos_mitigate_passive(doc) -> + ["Mitigate DOS computational attack by not allowing client to renegotiate many times in a row", + "immediately after each other"]; + +renegotiate_dos_mitigate_passive(suite) -> + []; + +renegotiate_dos_mitigate_passive(Config) when is_list(Config) -> + ServerOpts = ?config(server_opts, Config), + ClientOpts = ?config(client_opts, Config), + + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + + Server = + ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, send_recv_result, []}}, + {options, [{active, false} | ServerOpts]}]), + Port = ssl_test_lib:inet_port(Server), + + Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, + renegotiate_immediately, []}}, + {options, ClientOpts}]), + + ssl_test_lib:check_result(Client, ok, Server, ok), + ssl_test_lib:close(Server), + ssl_test_lib:close(Client). + +%%-------------------------------------------------------------------- +tcp_error_propagation_in_active_mode(doc) -> + ["Test that process recives {ssl_error, Socket, closed} when tcp error ocurres"]; +tcp_error_propagation_in_active_mode(Config) when is_list(Config) -> + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_opts, Config), + + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + + Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {ssl_test_lib, no_result, []}}, + {options, ServerOpts}]), + Port = ssl_test_lib:inet_port(Server), + {Client, #sslsocket{pid=Pid} = SslSocket} = ssl_test_lib:start_client([return_socket, + {node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, receive_msg, []}}, + {options, ClientOpts}]), + + {status, _, _, StatusInfo} = sys:get_status(Pid), + [_, _,_, _, Prop] = StatusInfo, + State = ssl_test_lib:state(Prop), + Socket = element(10, State), + + %% Fake tcp error + Pid ! {tcp_error, Socket, etimedout}, + + ssl_test_lib:check_result(Client, {ssl_closed, SslSocket}). +%%-------------------------------------------------------------------- + +rizzo(doc) -> ["Test that there is a 1/n-1-split for non RC4 in 'TLS < 1.1' as it is + vunrable to Rizzo/Dungon attack"]; + +rizzo(Config) when is_list(Config) -> + Ciphers = [X || X ={_,Y,_} <- ssl:cipher_suites(), Y =/= rc4_128], + run_send_recv_rizzo(Ciphers, Config, sslv3, + {?MODULE, send_recv_result_active_rizzo, []}), + run_send_recv_rizzo(Ciphers, Config, tlsv1, + {?MODULE, send_recv_result_active_rizzo, []}). + +no_rizzo_rc4(doc) -> + ["Test that there is no 1/n-1-split for RC4 as it is not vunrable to Rizzo/Dungon attack"]; + +no_rizzo_rc4(Config) when is_list(Config) -> + Ciphers = [X || X ={_,Y,_} <- ssl:cipher_suites(),Y == rc4_128], + run_send_recv_rizzo(Ciphers, Config, sslv3, + {?MODULE, send_recv_result_active_no_rizzo, []}), + run_send_recv_rizzo(Ciphers, Config, tlsv1, + {?MODULE, send_recv_result_active_no_rizzo, []}). + +run_send_recv_rizzo(Ciphers, Config, Version, Mfa) -> + Result = lists:map(fun(Cipher) -> + rizzo_test(Cipher, Config, Version, Mfa) end, + Ciphers), + case lists:flatten(Result) of + [] -> + ok; + Error -> + test_server:format("Cipher suite errors: ~p~n", [Error]), + test_server:fail(cipher_suite_failed_see_test_case_log) + end. + +rizzo_test(Cipher, Config, Version, Mfa) -> + {ClientOpts, ServerOpts} = client_server_opts(Cipher, Config), + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, Mfa}, + {options, [{active, true}, {ciphers, [Cipher]}, + {versions, [Version]} + | ServerOpts]}]), + Port = ssl_test_lib:inet_port(Server), + Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, Mfa}, + {options, [{active, true} | ClientOpts]}]), + + Result = ssl_test_lib:check_result(Server, ok, Client, ok), + ssl_test_lib:close(Server), + ssl_test_lib:close(Client), + case Result of + ok -> + []; + Error -> + [{Cipher, Error}] + end. + +client_server_opts({KeyAlgo,_,_}, Config) when KeyAlgo == rsa orelse KeyAlgo == dhe_rsa -> + {?config(client_opts, Config), + ?config(server_opts, Config)}; +client_server_opts({KeyAlgo,_,_}, Config) when KeyAlgo == dss orelse KeyAlgo == dhe_dss -> + {?config(client_dsa_opts, Config), + ?config(server_dsa_opts, Config)}. %%-------------------------------------------------------------------- %%% Internal functions @@ -3659,6 +3869,28 @@ send_recv_result(Socket) -> send_recv_result_active(Socket) -> ssl:send(Socket, "Hello world"), receive + {ssl, Socket, "H"} -> + receive + {ssl, Socket, "ello world"} -> + ok + end; + {ssl, Socket, "Hello world"} -> + ok + end. + +send_recv_result_active_rizzo(Socket) -> + ssl:send(Socket, "Hello world"), + receive + {ssl, Socket, "H"} -> + receive + {ssl, Socket, "ello world"} -> + ok + end + end. + +send_recv_result_active_no_rizzo(Socket) -> + ssl:send(Socket, "Hello world"), + receive {ssl, Socket, "Hello world"} -> ok end. @@ -3666,6 +3898,12 @@ send_recv_result_active(Socket) -> send_recv_result_active_once(Socket) -> ssl:send(Socket, "Hello world"), receive + {ssl, Socket, "H"} -> + ssl:setopts(Socket, [{active, once}]), + receive + {ssl, Socket, "ello world"} -> + ok + end; {ssl, Socket, "Hello world"} -> ok end. @@ -3690,6 +3928,25 @@ renegotiate_reuse_session(Socket, Data) -> test_server:sleep(?SLEEP), renegotiate(Socket, Data). +renegotiate_immediately(Socket) -> + receive + {ssl, Socket, "Hello world"} -> + ok; + %% Handle 1/n-1 splitting countermeasure Rizzo/Duong-Beast + {ssl, Socket, "H"} -> + receive + {ssl, Socket, "ello world"} -> + ok + end + end, + ok = ssl:renegotiate(Socket), + {error, renegotiation_rejected} = ssl:renegotiate(Socket), + test_server:sleep(?RENEGOTIATION_DISABLE_TIME +1), + ok = ssl:renegotiate(Socket), + test_server:format("Renegotiated again"), + ssl:send(Socket, "Hello world"), + ok. + new_config(PrivDir, ServerOpts0) -> CaCertFile = proplists:get_value(cacertfile, ServerOpts0), CertFile = proplists:get_value(certfile, ServerOpts0), @@ -3863,8 +4120,17 @@ erlang_ssl_receive(Socket, Data) -> {ssl, Socket, Data} -> io:format("Received ~p~n",[Data]), ok; + {ssl, Socket, Byte} when length(Byte) == 1 -> %% Handle 1/n-1 splitting countermeasure Rizzo/Duong-Beast + io:format("Received ~p~n",[Byte]), + erlang_ssl_receive(Socket, tl(Data)); Other -> test_server:fail({unexpected_message, Other}) after ?SLEEP * 3 -> test_server:fail({did_not_get, Data}) end. + +receive_msg(_) -> + receive + Msg -> + Msg + end. diff --git a/lib/ssl/test/ssl_packet_SUITE.erl b/lib/ssl/test/ssl_packet_SUITE.erl index 9d2599b778..4b74f57a60 100644 --- a/lib/ssl/test/ssl_packet_SUITE.erl +++ b/lib/ssl/test/ssl_packet_SUITE.erl @@ -158,14 +158,24 @@ all() -> packet_asn1_decode, packet_asn1_decode_list, packet_tpkt_decode, packet_tpkt_decode_list, packet_sunrm_decode, packet_sunrm_decode_list, - header_decode_one_byte, header_decode_two_bytes, - header_decode_two_bytes_one_sent, - header_decode_two_bytes_two_sent]. + {group, header} + ]. groups() -> - []. + [{header, [], [ header_decode_one_byte, + header_decode_two_bytes, + header_decode_two_bytes_one_sent, + header_decode_two_bytes_two_sent]}]. + +init_per_group(header, Config) -> + case ssl_record:highest_protocol_version(ssl_record:supported_protocol_versions()) of + {3, N} when N < 2 -> + {skip, ""}; + _ -> + Config + end; -init_per_group(_GroupName, Config) -> +init_per_group(_, Config) -> Config. end_per_group(_GroupName, Config) -> @@ -2626,6 +2636,13 @@ active_once_raw(_, _, 0, _) -> ok; active_once_raw(Socket, Data, N, Acc) -> receive + {ssl, Socket, Byte} when length(Byte) == 1 -> + ssl:setopts(Socket, [{active, once}]), + receive + {ssl, Socket, _} -> + ssl:setopts(Socket, [{active, once}]), + active_once_raw(Socket, Data, N-1, []) + end; {ssl, Socket, Data} -> ssl:setopts(Socket, [{active, once}]), active_once_raw(Socket, Data, N-1, []); @@ -2648,7 +2665,14 @@ active_once_packet(Socket,_, 0) -> {other, Other, ssl:session_info(Socket), 0} end; active_once_packet(Socket, Data, N) -> - receive + receive + {ssl, Socket, Byte} when length(Byte) == 1 -> + ssl:setopts(Socket, [{active, once}]), + receive + {ssl, Socket, _} -> + ssl:setopts(Socket, [{active, once}]), + active_once_packet(Socket, Data, N-1) + end; {ssl, Socket, Data} -> ok end, @@ -2662,6 +2686,11 @@ active_raw(_Socket, _, 0, _) -> ok; active_raw(Socket, Data, N, Acc) -> receive + {ssl, Socket, Byte} when length(Byte) == 1 -> + receive + {ssl, Socket, _} -> + active_raw(Socket, Data, N -1) + end; {ssl, Socket, Data} -> active_raw(Socket, Data, N-1, []); {ssl, Socket, Other} -> @@ -2682,6 +2711,11 @@ active_packet(Socket, _, 0) -> end; active_packet(Socket, Data, N) -> receive + {ssl, Socket, Byte} when length(Byte) == 1 -> + receive + {ssl, Socket, _} -> + active_packet(Socket, Data, N -1) + end; {ssl, Socket, Data} -> active_packet(Socket, Data, N -1); Other -> diff --git a/lib/ssl/test/ssl_session_cache_SUITE.erl b/lib/ssl/test/ssl_session_cache_SUITE.erl index 8cdfdec2ce..491aa893c2 100644 --- a/lib/ssl/test/ssl_session_cache_SUITE.erl +++ b/lib/ssl/test/ssl_session_cache_SUITE.erl @@ -210,7 +210,7 @@ session_cleanup(Config)when is_list(Config) -> {status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)), [_, _,_, _, Prop] = StatusInfo, - State = state(Prop), + State = ssl_test_lib:state(Prop), Cache = element(2, State), SessionTimer = element(6, State), @@ -225,9 +225,10 @@ session_cleanup(Config)when is_list(Config) -> check_timer(SessionTimer), test_server:sleep(?DELAY *2), %% Delay time + some extra time - DelayTimer = get_delay_timer(), + {ServerDelayTimer, ClientDelayTimer} = get_delay_timers(), - check_timer(DelayTimer), + check_timer(ServerDelayTimer), + check_timer(ClientDelayTimer), test_server:sleep(?SLEEP), %% Make sure clean has had time to run @@ -238,31 +239,34 @@ session_cleanup(Config)when is_list(Config) -> ssl_test_lib:close(Server), ssl_test_lib:close(Client). -state([{data,[{"State", State}]} | _]) -> - State; -state([_ | Rest]) -> - state(Rest). - check_timer(Timer) -> case erlang:read_timer(Timer) of false -> {status, _, _, _} = sys:get_status(whereis(ssl_manager)), + timer:sleep(?SLEEP), + {status, _, _, _} = sys:get_status(whereis(ssl_manager)), ok; Int -> test_server:sleep(Int), check_timer(Timer) end. -get_delay_timer() -> +get_delay_timers() -> {status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)), [_, _,_, _, Prop] = StatusInfo, - State = state(Prop), + State = ssl_test_lib:state(Prop), case element(7, State) of - undefined -> + {undefined, undefined} -> + test_server:sleep(?SLEEP), + get_delay_timers(); + {undefined, _} -> + test_server:sleep(?SLEEP), + get_delay_timers(); + {_, undefined} -> test_server:sleep(?SLEEP), - get_delay_timer(); - DelayTimer -> - DelayTimer + get_delay_timers(); + DelayTimers -> + DelayTimers end. %%-------------------------------------------------------------------- session_cache_process_list(doc) -> diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl index 46a8112a41..fa8a1826f2 100644 --- a/lib/ssl/test/ssl_test_lib.erl +++ b/lib/ssl/test/ssl_test_lib.erl @@ -662,6 +662,9 @@ cipher_result(Socket, Result) -> %% to properly test "cipher state" handling ssl:send(Socket, "Hello\n"), receive + {ssl, Socket, "H"} -> + ssl:send(Socket, " world\n"), + receive_rizzo_duong_beast(); {ssl, Socket, "Hello\n"} -> ssl:send(Socket, " world\n"), receive @@ -687,3 +690,21 @@ public_key(#'PrivateKeyInfo'{privateKeyAlgorithm = public_key:der_decode('DSAPrivateKey', iolist_to_binary(Key)); public_key(Key) -> Key. +receive_rizzo_duong_beast() -> + receive + {ssl, _, "ello\n"} -> + receive + {ssl, _, " "} -> + receive + {ssl, _, "world\n"} -> + ok + end + end + end. + +state([{data,[{"State", State}]} | _]) -> + State; +state([{data,[{"StateData", State}]} | _]) -> + State; +state([_ | Rest]) -> + state(Rest). diff --git a/lib/ssl/test/ssl_to_openssl_SUITE.erl b/lib/ssl/test/ssl_to_openssl_SUITE.erl index f37baeb9de..f04ab9af50 100644 --- a/lib/ssl/test/ssl_to_openssl_SUITE.erl +++ b/lib/ssl/test/ssl_to_openssl_SUITE.erl @@ -849,7 +849,9 @@ ssl3_erlang_server_erlang_client_client_cert(Config) when is_list(Config) -> Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, {from, self()}, {mfa, {?MODULE, - erlang_ssl_receive, [Data]}}, + erlang_ssl_receive, + %% Due to 1/n-1 splitting countermeasure Rizzo/Duong-Beast + [Data]}}, {options, [{verify , verify_peer} | ServerOpts]}]), @@ -858,6 +860,7 @@ ssl3_erlang_server_erlang_client_client_cert(Config) when is_list(Config) -> Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, {host, Hostname}, {from, self()}, + %% Due to 1/n-1 splitting countermeasure Rizzo/Duong-Beast {mfa, {ssl, send, [Data]}}, {options, [{versions, [sslv3]} | ClientOpts]}]), @@ -869,6 +872,7 @@ ssl3_erlang_server_erlang_client_client_cert(Config) when is_list(Config) -> process_flag(trap_exit, false), ok. + %%-------------------------------------------------------------------- tls1_erlang_client_openssl_server(doc) -> @@ -1350,6 +1354,8 @@ erlang_ssl_receive(Socket, Data) -> %% open_ssl server sometimes hangs waiting in blocking read ssl:send(Socket, "Got it"), ok; + {ssl, Socket, Byte} when length(Byte) == 1 -> + erlang_ssl_receive(Socket, tl(Data)); {Port, {data,Debug}} when is_port(Port) -> io:format("openssl ~s~n",[Debug]), erlang_ssl_receive(Socket,Data); diff --git a/lib/stdlib/doc/src/Makefile b/lib/stdlib/doc/src/Makefile index 16e0a86e3b..6c92756ae7 100644 --- a/lib/stdlib/doc/src/Makefile +++ b/lib/stdlib/doc/src/Makefile @@ -83,7 +83,6 @@ XML_REF3_FILES = \ queue.xml \ random.xml \ re.xml \ - regexp.xml \ sets.xml \ shell.xml \ shell_default.xml \ diff --git a/lib/stdlib/doc/src/filename.xml b/lib/stdlib/doc/src/filename.xml index bc3a616d39..9296319b83 100644 --- a/lib/stdlib/doc/src/filename.xml +++ b/lib/stdlib/doc/src/filename.xml @@ -295,6 +295,12 @@ <p>Finds the source filename and compiler options for a module. The result can be fed to <c>compile:file/2</c> in order to compile the file again.</p> + + <warning><p>We don't recommend using this function. If possible, + use <seealso marker="beam_lib">beam_lib(3)</seealso> to extract + the abstract code format from the BEAM file and compile that + instead.</p></warning> + <p>The <c><anno>Beam</anno></c> argument, which can be a string or an atom, specifies either the module name or the path to the source code, with or without the <c>".erl"</c> extension. In either diff --git a/lib/stdlib/doc/src/gen_event.xml b/lib/stdlib/doc/src/gen_event.xml index 24bcb419fe..79a0c8ad89 100644 --- a/lib/stdlib/doc/src/gen_event.xml +++ b/lib/stdlib/doc/src/gen_event.xml @@ -195,12 +195,13 @@ gen_event:stop -----> Module:terminate/2 handlers using the same callback module.</p> <p><c>Args</c> is an arbitrary term which is passed as the argument to <c>Module:init/1</c>.</p> - <p>If <c>Module:init/1</c> returns a correct value, the event - manager adds the event handler and this function returns + <p>If <c>Module:init/1</c> returns a correct value indicating + successful completion, the event manager adds the event + handler and this function returns <c>ok</c>. If <c>Module:init/1</c> fails with <c>Reason</c> or - returns an unexpected value <c>Term</c>, the event handler is + returns <c>{error,Reason}</c>, the event handler is ignored and this function returns <c>{'EXIT',Reason}</c> or - <c>Term</c>, respectively.</p> + <c>{error,Reason}</c>, respectively.</p> </desc> </func> <func> @@ -448,12 +449,13 @@ gen_event:stop -----> Module:terminate/2 </section> <funcs> <func> - <name>Module:init(InitArgs) -> {ok,State} | {ok,State,hibernate}</name> + <name>Module:init(InitArgs) -> {ok,State} | {ok,State,hibernate} | {error,Reason}</name> <fsummary>Initialize an event handler.</fsummary> <type> <v>InitArgs = Args | {Args,Term}</v> <v> Args = Term = term()</v> <v>State = term()</v> + <v>Reason = term()</v> </type> <desc> <p>Whenever a new event handler is added to an event manager, @@ -470,8 +472,9 @@ gen_event:stop -----> Module:terminate/2 the argument provided in the function call/return tuple and <c>Term</c> is the result of terminating the old event handler, see <c>gen_event:swap_handler/3</c>.</p> - <p>The function should return <c>{ok,State}</c> or <c>{ok,State, hibernate}</c> - where <c>State</c> is the initial internal state of the event handler.</p> + <p>If successful, the function should return <c>{ok,State}</c> + or <c>{ok,State,hibernate}</c> where <c>State</c> is the + initial internal state of the event handler.</p> <p>If <c>{ok,State,hibernate}</c> is returned, the event manager will go into hibernation (by calling <seealso marker="proc_lib#hibernate/3">proc_lib:hibernate/3</seealso>), diff --git a/lib/stdlib/doc/src/gen_server.xml b/lib/stdlib/doc/src/gen_server.xml index 1045766e01..edeb7dff91 100644 --- a/lib/stdlib/doc/src/gen_server.xml +++ b/lib/stdlib/doc/src/gen_server.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1996</year><year>2010</year> + <year>1996</year><year>2011</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -570,13 +570,14 @@ gen_server:abcast -----> Module:handle_cast/2 </desc> </func> <func> - <name>Module:code_change(OldVsn, State, Extra) -> {ok, NewState}</name> + <name>Module:code_change(OldVsn, State, Extra) -> {ok, NewState} | {error, Reason}</name> <fsummary>Update the internal state during upgrade/downgrade.</fsummary> <type> <v>OldVsn = Vsn | {down, Vsn}</v> <v> Vsn = term()</v> <v>State = NewState = term()</v> <v>Extra = term()</v> + <v>Reason = term()</v> </type> <desc> <p>This function is called by a gen_server when it should @@ -595,7 +596,10 @@ gen_server:abcast -----> Module:handle_cast/2 <p><c>State</c> is the internal state of the gen_server.</p> <p><c>Extra</c> is passed as-is from the <c>{advanced,Extra}</c> part of the update instruction.</p> - <p>The function should return the updated internal state.</p> + <p>If successful, the function shall return the updated + internal state.</p> + <p>If the function returns <c>{error,Reason}</c>, the ongoing + upgrade will fail and roll back to the old release.</p> </desc> </func> <func> diff --git a/lib/stdlib/doc/src/io_protocol.xml b/lib/stdlib/doc/src/io_protocol.xml index 3e8ab1affc..0ff3d5c1ee 100644 --- a/lib/stdlib/doc/src/io_protocol.xml +++ b/lib/stdlib/doc/src/io_protocol.xml @@ -50,10 +50,10 @@ current I/O-protocol.</p> and execution time efficiency has triggered extensions to the protocol over the years, making the protocol larger and somewhat less easy to implement than the original. It can certainly be argumented that the -current protocol is to complex, but this text describes how it looks +current protocol is too complex, but this text describes how it looks today, not how it should have looked.</p> -<p>The basic ideas from the original protocol still holds. The io_server +<p>The basic ideas from the original protocol still hold. The io_server and client communicate with one single, rather simplistic protocol and no server state is ever present in the client. Any io_server can be used together with any client code and client code need not be aware @@ -62,7 +62,7 @@ of the actual device the io_server communicates with.</p> <section> <title>Protocol basics</title> -<p>As described in Roberts paper, servers and clients communicate using +<p>As described in Robert's paper, servers and clients communicate using io_request/io_reply tuples as follows:</p> <p><em>{io_request, From, ReplyAs, Request}</em><br/> @@ -103,7 +103,7 @@ Reply part.</p> <em>{put_chars, Encoding, Module, Function, Args}</em> </p> <list type="bulleted"> -<item>Encoding is either 'latin1' or 'unicode', meaning that the +<item>Encoding is either 'unicode' or 'latin1', meaning that the characters are (in case of binaries) encoded as either UTF-8 or iso-latin-1 (pure bytes). A well behaved io_server should also return error if list elements contain integers > 255 when the @@ -116,13 +116,13 @@ Reply part.</p> produces. Note that byte-oriented data is simplest sent using latin1 Encoding</item> -<item>Characters are the data to be put on the device. If encoding is - latin1, this is an iolist(). If encoding is unicode, this is an +<item>Characters are the data to be put on the device. If Encoding is + latin1, this is an iolist(). If Encoding is unicode, this is an Erlang standard mixed unicode list (one integer in a list per character, characters in binaries represented as UTF-8).</item> <item>Module, Function, Args denotes a function which will be called to - produce the data (like io_lib:format), Args is a list of arguments + produce the data (like io_lib:format). Args is a list of arguments to the function. The function should produce data in the given Encoding. The io_server should call the function as apply(Mod, Func, Args) and will put the returned data on the device as if it was sent @@ -164,7 +164,7 @@ latin1, Module, Function, Args} respectively. </p> <list type="bulleted"> <item>Encoding denotes how data is to be sent back to the client and what data is sent to the function denoted by - Module/Function/Arity. If the function supplied returns data as a + Module/Function/ExtraArgs. If the function supplied returns data as a list, the data is converted to this encoding. If however the function supplied returns data in some other format, no conversion can be done and it's up to the client supplied function to return @@ -179,7 +179,7 @@ latin1, Module, Function, Args} respectively. </p> <item>Prompt is a list of characters (not mixed, no binaries) or an atom() to be output as a prompt for input on the device. The Prompt is often ignored by the io_server and a Prompt set to '' should always - be ignored (and result in nothing being written to the device). </item> + be ignored (and result in nothing being written to the device).</item> <item><p>Module, Function, ExtraArgs denotes a function and arguments to determine when enough data is written. The function should take two @@ -550,7 +550,7 @@ request({get_line, Encoding, _Prompt}, State) -> </code> <p>Here we have cheated a little by more or less only implementing -get_until and using internal helpers to implement get__chars and +get_until and using internal helpers to implement get_chars and get_line. In production code, this might be to inefficient, but that of course depends on the frequency of the different requests. Before we start actually implementing the functions put_chars/2 and @@ -618,7 +618,7 @@ encounter an error or the list is exhausted. The last return value is sent back to the client (it's first returned to the main loop and then sent back by the function io_reply).</p> -<p>The getopt and setopt requests is also simple to handle, we just +<p>The getopt and setopt requests are also simple to handle, we just change or read our state record:</p> <code> diff --git a/lib/stdlib/doc/src/re.xml b/lib/stdlib/doc/src/re.xml index 18867cfb68..6d5336796c 100644 --- a/lib/stdlib/doc/src/re.xml +++ b/lib/stdlib/doc/src/re.xml @@ -41,8 +41,7 @@ strings and binaries.</p> <p>The regular expression syntax and semantics resemble that of - Perl. This library replaces the deprecated pure-Erlang regexp - library; it has a richer syntax, more options and is faster.</p> + Perl.</p> <p>The library's matching algorithms are currently based on the PCRE library, but not all of the PCRE library is interfaced and diff --git a/lib/stdlib/doc/src/ref_man.xml b/lib/stdlib/doc/src/ref_man.xml index 85aae6151d..6373922c92 100644 --- a/lib/stdlib/doc/src/ref_man.xml +++ b/lib/stdlib/doc/src/ref_man.xml @@ -80,7 +80,6 @@ <xi:include href="queue.xml"/> <xi:include href="random.xml"/> <xi:include href="re.xml"/> - <xi:include href="regexp.xml"/> <xi:include href="sets.xml"/> <xi:include href="shell.xml"/> <xi:include href="shell_default.xml"/> diff --git a/lib/stdlib/doc/src/regexp.xml b/lib/stdlib/doc/src/regexp.xml deleted file mode 100644 index 35d8e1c3f8..0000000000 --- a/lib/stdlib/doc/src/regexp.xml +++ /dev/null @@ -1,381 +0,0 @@ -<?xml version="1.0" encoding="latin1" ?> -<!DOCTYPE erlref SYSTEM "erlref.dtd"> - -<erlref> - <header> - <copyright> - <year>1996</year><year>2011</year> - <holder>Ericsson AB. All Rights Reserved.</holder> - </copyright> - <legalnotice> - The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved online at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - the License for the specific language governing rights and limitations - under the License. - - </legalnotice> - - <title>regexp</title> - <prepared>Robert Virding</prepared> - <responsible>Bjarne Dacker</responsible> - <docno>1</docno> - <approved>Bjarne Däcker</approved> - <checked></checked> - <date>96-09-28</date> - <rev>A</rev> - <file>regexp.sgml</file> - </header> - <module>regexp</module> - <modulesummary>Regular Expression Functions for Strings</modulesummary> - <description> - <note><p>This module has been obsoleted by the - <seealso marker="re">re</seealso> module and will be removed in a future - release.</p></note> - <p>This module contains functions for regular expression - matching and substitution.</p> - </description> - <datatypes> - <datatype> - <name name="errordesc"></name> - </datatype> - <datatype> - <name name="regexp"></name> - <desc><p>Internal representation of a regular expression.</p></desc> - </datatype> - </datatypes> - <funcs> - <func> - <name name="match" arity="2"/> - <fsummary>Match a regular expression</fsummary> - <desc> - <p>Finds the first, longest match of the regular expression <c><anno>RegExp</anno></c> in <c><anno>String</anno></c>. This function searches for the longest possible match and returns the first one found if there are several expressions of the same length. It returns as follows:</p> - <taglist> - <tag><c>{match,<anno>Start</anno>,<anno>Length</anno>}</c></tag> - <item> - <p>if the match succeeded. <c><anno>Start</anno></c> is the starting - position of the match, and <c><anno>Length</anno></c> is the length of - the matching string.</p> - </item> - <tag><c>nomatch</c></tag> - <item> - <p>if there were no matching characters.</p> - </item> - <tag><c>{error,<anno>Error</anno>}</c></tag> - <item> - <p>if there was an error in <c><anno>RegExp</anno></c>.</p> - </item> - </taglist> - </desc> - </func> - <func> - <name name="first_match" arity="2"/> - <fsummary>Match a regular expression</fsummary> - <desc> - <p>Finds the first match of the regular expression <c><anno>RegExp</anno></c> in <c><anno>String</anno></c>. This call is - usually faster than <c>match</c> and it is also a useful way to ascertain that a match exists. It returns as follows:</p> - <taglist> - <tag><c>{match,<anno>Start</anno>,<anno>Length</anno>}</c></tag> - <item> - <p>if the match succeeded. <c><anno>Start</anno></c> is the starting - position of the match and <c><anno>Length</anno></c> is the length of - the matching string.</p> - </item> - <tag><c>nomatch</c></tag> - <item> - <p>if there were no matching characters.</p> - </item> - <tag><c>{error,<anno>Error</anno>}</c></tag> - <item> - <p>if there was an error in <c><anno>RegExp</anno></c>.</p> - </item> - </taglist> - </desc> - </func> - <func> - <name name="matches" arity="2"/> - <fsummary>Match a regular expression</fsummary> - <desc> - <p>Finds all non-overlapping matches of the - expression <c><anno>RegExp</anno></c> in <c><anno>String</anno></c>. - It returns as follows:</p> - <taglist> - <tag><c>{match, <anno>Matches</anno>}</c></tag> - <item> - <p>if the regular expression was correct. - The list will be empty if there was no match. Each element in the list looks like <c>{<anno>Start</anno>, <anno>Length</anno>}</c>, where <c><anno>Start</anno></c> is the starting position of the match, and <c><anno>Length</anno></c> is the length of the matching string.</p> - </item> - <tag><c>{error,<anno>Error</anno>}</c></tag> - <item> - <p>if there was an error in <c><anno>RegExp</anno></c>.</p> - </item> - </taglist> - </desc> - </func> - <func> - <name name="sub" arity="3"/> - <fsummary>Substitute the first occurrence of a regular expression</fsummary> - <desc> - <p>Substitutes the first occurrence of a substring matching <c><anno>RegExp</anno></c> in <c><anno>String</anno></c> with the string <c><anno>New</anno></c>. A <c><![CDATA[&]]></c> in the string <c><anno>New</anno></c> is replaced by the matched substring of <c><anno>String</anno></c>. <c><![CDATA[\&]]></c> puts a literal <c><![CDATA[&]]></c> into the replacement string. It returns as follows:</p> - <taglist> - <tag><c>{ok,<anno>NewString</anno>,<anno>RepCount</anno>}</c></tag> - <item> - <p>if <c><anno>RegExp</anno></c> is correct. <c><anno>RepCount</anno></c> is the number of replacements which have been made - (this will be either 0 or 1).</p> - </item> - <tag><c>{error, <anno>Error</anno>}</c></tag> - <item> - <p>if there is an error in <c><anno>RegExp</anno></c>.</p> - </item> - </taglist> - </desc> - </func> - <func> - <name name="gsub" arity="3"/> - <fsummary>Substitute all occurrences of a regular expression</fsummary> - <desc> - <p>The same as <c>sub</c>, except that all non-overlapping - occurrences of a substring matching - <c><anno>RegExp</anno></c> in <c><anno>String</anno></c> are replaced by the string <c><anno>New</anno></c>. It returns:</p> - <taglist> - <tag><c>{ok,<anno>NewString</anno>,<anno>RepCount</anno>}</c></tag> - <item> - <p>if <c><anno>RegExp</anno></c> is correct. <c><anno>RepCount</anno></c> is the number of replacements which have been made.</p> - </item> - <tag><c>{error, <anno>Error</anno>}</c></tag> - <item> - <p>if there is an error in <c><anno>RegExp</anno></c>.</p> - </item> - </taglist> - </desc> - </func> - <func> - <name name="split" arity="2"/> - <fsummary>Split a string into fields</fsummary> - <desc> - <p><c><anno>String</anno></c> is split into fields (sub-strings) by the - regular expression <c><anno>RegExp</anno></c>.</p> - <p>If the separator expression is <c>" "</c> (a single space), - then the fields are separated by blanks and/or tabs and - leading and trailing blanks and tabs are discarded. For all - other values of the separator, leading and trailing blanks - and tabs are not discarded. It returns:</p> - <taglist> - <tag><c>{ok, <anno>FieldList</anno>}</c></tag> - <item> - <p>to indicate that the string has been split up into the fields of - <c><anno>FieldList</anno></c>.</p> - </item> - <tag><c>{error, <anno>Error</anno>}</c></tag> - <item> - <p>if there is an error in <c><anno>RegExp</anno></c>.</p> - </item> - </taglist> - </desc> - </func> - <func> - <name name="sh_to_awk" arity="1"/> - <fsummary>Convert an <c>sh</c>regular expression into an <c>AWK</c>one</fsummary> - <desc> - <p>Converts the <c>sh</c> type regular expression - <c><anno>ShRegExp</anno></c> into a full <c>AWK</c> regular - expression. Returns the converted regular expression - string. <c>sh</c> expressions are used in the shell for - matching file names and have the following special - characters:</p> - <taglist> - <tag><c>*</c></tag> - <item> - <p>matches any string including the null string.</p> - </item> - <tag><c>?</c></tag> - <item> - <p>matches any single character.</p> - </item> - <tag><c>[...]</c></tag> - <item> - <p>matches any of the enclosed characters. Character - ranges are specified by a pair of characters separated - by a <c>-</c>. If the first character after <c>[</c> is a - <c>!</c>, then any character not enclosed is matched.</p> - </item> - </taglist> - <p>It may sometimes be more practical to use <c>sh</c> type - expansions as they are simpler and easier to use, even though they are not as powerful.</p> - </desc> - </func> - <func> - <name name="parse" arity="1"/> - <fsummary>Parse a regular expression</fsummary> - <desc> - <p>Parses the regular expression <c><anno>RegExp</anno></c> and builds the - internal representation used in the other regular expression - functions. Such representations can be used in all of the - other functions instead of a regular expression string. This - is more efficient when the same regular expression is used - in many strings. It returns:</p> - <taglist> - <tag><c>{ok, <anno>RE</anno>}</c></tag> - <item> - <p>if <c>RegExp</c> is correct and <c><anno>RE</anno></c> is the internal representation.</p> - </item> - <tag><c>{error, <anno>Error</anno>}</c></tag> - <item> - <p>if there is an error in <c><anno>RegExp</anno></c>.</p> - </item> - </taglist> - </desc> - </func> - <func> - <name name="format_error" arity="1"/> - <fsummary>Format an error descriptor</fsummary> - <desc> - <p>Returns a string which describes the error <c><anno>ErrorDescriptor</anno></c> - returned when there is an error in a regular expression.</p> - </desc> - </func> - </funcs> - - <section> - <title>Regular Expressions</title> - <p>The regular expressions allowed here is a subset of the set found - in <c>egrep</c> and in the <c>AWK</c> programming language, as - defined in the book, <c>The AWK Programming Language, by A. V. Aho, B. W. Kernighan, P. J. Weinberger</c>. They are - composed of the following characters:</p> - <taglist> - <tag>c</tag> - <item> - <p>matches the non-metacharacter <c>c</c>.</p> - </item> - <tag>\c</tag> - <item> - <p>matches the escape sequence or literal character <c>c</c>.</p> - </item> - <tag>.</tag> - <item> - <p>matches any character.</p> - </item> - <tag>^</tag> - <item> - <p>matches the beginning of a string.</p> - </item> - <tag>$</tag> - <item> - <p>matches the end of a string.</p> - </item> - <tag>[abc...]</tag> - <item> - <p>character class, which matches any of the characters - <c>abc...</c> Character ranges are specified by a pair of - characters separated by a <c>-</c>.</p> - </item> - <tag>[^abc...]</tag> - <item> - <p>negated character class, which matches any character except - <c>abc...</c>.</p> - </item> - <tag>r1 | r2</tag> - <item> - <p>alternation. It matches either <c>r1</c> or <c>r2</c>.</p> - </item> - <tag>r1r2</tag> - <item> - <p>concatenation. It matches <c>r1</c> and then <c>r2</c>.</p> - </item> - <tag>r+</tag> - <item> - <p>matches one or more <c>r</c>s.</p> - </item> - <tag>r*</tag> - <item> - <p>matches zero or more <c>r</c>s.</p> - </item> - <tag>r?</tag> - <item> - <p>matches zero or one <c>r</c>s.</p> - </item> - <tag>(r)</tag> - <item> - <p>grouping. It matches <c>r</c>.</p> - </item> - </taglist> - <p>The escape sequences allowed are the same as for Erlang - strings:</p> - <taglist> - <tag><c>\b</c></tag> - <item> - <p>backspace</p> - </item> - <tag><c>\f</c></tag> - <item> - <p>form feed </p> - </item> - <tag><c>\n</c></tag> - <item> - <p>newline (line feed) </p> - </item> - <tag><c>\r</c></tag> - <item> - <p>carriage return </p> - </item> - <tag><c>\t</c></tag> - <item> - <p>tab </p> - </item> - <tag><c>\e</c></tag> - <item> - <p>escape </p> - </item> - <tag><c>\v</c></tag> - <item> - <p>vertical tab </p> - </item> - <tag><c>\s</c></tag> - <item> - <p>space </p> - </item> - <tag><c>\d</c></tag> - <item> - <p>delete </p> - </item> - <tag><c>\ddd</c></tag> - <item> - <p>the octal value ddd </p> - </item> - <tag><c>\xhh</c></tag> - <item> - <p>The hexadecimal value <c>hh</c>.</p> - </item> - <tag><c>\x{h...}</c></tag> - <item> - <p>The hexadecimal value <c>h...</c>.</p> - </item> - <tag><c>\c</c></tag> - <item> - <p>any other character literally, for example <c>\\</c> for backslash, - <c>\"</c> for ")</p> - </item> - </taglist> - <p>To make these functions easier to use, in combination with the - function <c>io:get_line</c> which terminates the input line with - a new line, the <c>$</c> characters also matches a string ending - with <c>"...\n"</c>. The following examples - define Erlang data types:</p> - <pre> -Atoms [a-z][0-9a-zA-Z_]* - -Variables [A-Z_][0-9a-zA-Z_]* - -Floats (\+|-)?[0-9]+\.[0-9]+((E|e)(\+|-)?[0-9]+)?</pre> - <p>Regular expressions are written as Erlang strings when used with the functions in this module. This means that any <c>\</c> or <c>"</c> characters in a regular expression - string must be written with <c>\</c> as they are also escape characters for the string. For example, the regular expression string for Erlang floats is: - <c>"(\\+|-)?[0-9]+\\.[0-9]+((E|e)(\\+|-)?[0-9]+)?"</c>.</p> - <p>It is not really necessary to have the escape sequences as part of the regular expression syntax as they can always be generated directly in the string. They are included for completeness and can they can also be useful when generating regular expressions, or when they are entered other than with Erlang strings.</p> - </section> -</erlref> - diff --git a/lib/stdlib/doc/src/specs.xml b/lib/stdlib/doc/src/specs.xml index 98338b5ec2..49c60529d2 100644 --- a/lib/stdlib/doc/src/specs.xml +++ b/lib/stdlib/doc/src/specs.xml @@ -46,7 +46,6 @@ <xi:include href="../specs/specs_queue.xml"/> <xi:include href="../specs/specs_random.xml"/> <xi:include href="../specs/specs_re.xml"/> - <xi:include href="../specs/specs_regexp.xml"/> <xi:include href="../specs/specs_sets.xml"/> <xi:include href="../specs/specs_shell.xml"/> <xi:include href="../specs/specs_shell_default.xml"/> diff --git a/lib/stdlib/doc/src/unicode_usage.xml b/lib/stdlib/doc/src/unicode_usage.xml index 0fa7de0a5c..a7e010a05f 100644 --- a/lib/stdlib/doc/src/unicode_usage.xml +++ b/lib/stdlib/doc/src/unicode_usage.xml @@ -59,7 +59,7 @@ <title>Standard Unicode representation in Erlang</title> <p>In Erlang, strings are actually lists of integers. A string is defined to be encoded in the ISO-latin-1 (ISO8859-1) character set, which is, codepoint by codepoint, a sub-range of the Unicode character set.</p> <p>The standard list encoding for strings is therefore easily extendible to cope with the whole Unicode range: A Unicode string in Erlang is simply a list containing integers, each integer being a valid Unicode codepoint and representing one character in the Unicode character set.</p> -<p>Regular Erlang strings in ISO-latin-1 are a subset of there Unicode strings.</p> +<p>Regular Erlang strings in ISO-latin-1 are a subset of their Unicode strings.</p> <p>Binaries on the other hand are more troublesome. For performance reasons, programs often store textual data in binaries instead of lists, mainly because they are more compact (one byte per character instead of two words per character, as is the case with lists). Using erlang:list_to_binary/1, an regular Erlang string can be converted into a binary, effectively using the ISO-latin-1 encoding in the binary - one byte per character. This is very convenient for those regular Erlang strings, but cannot be done for Unicode lists.</p> <p>As the UTF-8 encoding is widely spread and provides the most compact storage, it is selected as the standard encoding of Unicode characters in binaries for Erlang.</p> diff --git a/lib/stdlib/src/Makefile b/lib/stdlib/src/Makefile index 600303d7e1..9ce1f6f5c8 100644 --- a/lib/stdlib/src/Makefile +++ b/lib/stdlib/src/Makefile @@ -105,7 +105,6 @@ MODULES= \ qlc_pt \ queue \ random \ - regexp \ sets \ shell \ shell_default \ diff --git a/lib/stdlib/src/erl_eval.erl b/lib/stdlib/src/erl_eval.erl index 88a0094d57..bf3c7b3504 100644 --- a/lib/stdlib/src/erl_eval.erl +++ b/lib/stdlib/src/erl_eval.erl @@ -341,7 +341,7 @@ expr({call,_,{remote,_,Mod,Func},As0}, Bs0, Lf, Ef, RBs) -> true -> bif(F, As, Bs3, Ef, RBs); false -> - do_apply({M,F}, As, Bs3, Ef, RBs) + do_apply(M, F, As, Bs3, Ef, RBs) end; expr({call,_,{atom,_,Func},As0}, Bs0, Lf, Ef, RBs) -> case erl_internal:bif(Func, length(As0)) of @@ -499,11 +499,11 @@ local_func2({eval,F,As,Bs}, RBs) -> % This reply is not documented. bif(apply, [erlang,apply,As], Bs, Ef, RBs) -> bif(apply, As, Bs, Ef, RBs); bif(apply, [M,F,As], Bs, Ef, RBs) -> - do_apply({M,F}, As, Bs, Ef, RBs); + do_apply(M, F, As, Bs, Ef, RBs); bif(apply, [F,As], Bs, Ef, RBs) -> do_apply(F, As, Bs, Ef, RBs); bif(Name, As, Bs, Ef, RBs) -> - do_apply({erlang,Name}, As, Bs, Ef, RBs). + do_apply(erlang, Name, As, Bs, Ef, RBs). %% do_apply(MF, Arguments, Bindings, ExternalFuncHandler, RBs) -> %% {value,Value,Bindings} | Value when @@ -563,6 +563,19 @@ do_apply(Func, As, Bs0, Ef, RBs) -> ret_expr(F(Func, As), Bs0, RBs) end. +do_apply(Mod, Func, As, Bs0, Ef, RBs) -> + case Ef of + none when RBs =:= value -> + %% Make tail recursive calls when possible. + apply(Mod, Func, As); + none -> + ret_expr(apply(Mod, Func, As), Bs0, RBs); + {value,F} when RBs =:= value -> + F({Mod,Func}, As); + {value,F} -> + ret_expr(F({Mod,Func}, As), Bs0, RBs) + end. + %% eval_lc(Expr, [Qualifier], Bindings, LocalFunctionHandler, %% ExternalFuncHandler, RetBindings) -> %% {value,Value,Bindings} | Value @@ -731,10 +744,10 @@ expr_list([], Vs, _, Bs, _Lf, _Ef) -> {reverse(Vs),Bs}. eval_op(Op, Arg1, Arg2, Bs, Ef, RBs) -> - do_apply({erlang,Op}, [Arg1,Arg2], Bs, Ef, RBs). + do_apply(erlang, Op, [Arg1,Arg2], Bs, Ef, RBs). eval_op(Op, Arg, Bs, Ef, RBs) -> - do_apply({erlang,Op}, [Arg], Bs, Ef, RBs). + do_apply(erlang, Op, [Arg], Bs, Ef, RBs). %% if_clauses(Clauses, Bindings, LocalFuncHandler, ExtFuncHandler, RBs) @@ -920,8 +933,9 @@ guard0([], _Bs, _Lf, _Ef) -> true. guard_test({call,L,{atom,Ln,F},As0}, Bs0, Lf, Ef) -> TT = type_test(F), - guard_test({call,L,{tuple,Ln,[{atom,Ln,erlang},{atom,Ln,TT}]},As0}, - Bs0, Lf, Ef); + G = {call,L,{atom,Ln,TT},As0}, + try {value,true,_} = expr(G, Bs0, Lf, Ef, none) + catch error:_ -> {value,false,Bs0} end; guard_test({call,L,{remote,_Lr,{atom,_Lm,erlang},{atom,_Lf,_F}=T},As0}, Bs0, Lf, Ef) -> guard_test({call,L,T,As0}, Bs0, Lf, Ef); diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl index 5d45260fe9..e5adb84932 100644 --- a/lib/stdlib/src/erl_lint.erl +++ b/lib/stdlib/src/erl_lint.erl @@ -2767,12 +2767,6 @@ default_types() -> {var, 1}], dict:from_list([{T, -1} || T <- DefTypes]). -%% R12B-5 -is_newly_introduced_builtin_type({module, 0}) -> true; -is_newly_introduced_builtin_type({node, 0}) -> true; -is_newly_introduced_builtin_type({nonempty_string, 0}) -> true; -is_newly_introduced_builtin_type({term, 0}) -> true; -is_newly_introduced_builtin_type({timeout, 0}) -> true; %% R13 is_newly_introduced_builtin_type({arity, 0}) -> true; is_newly_introduced_builtin_type({array, 0}) -> true; % opaque diff --git a/lib/stdlib/src/filename.erl b/lib/stdlib/src/filename.erl index 2fc9128e4e..dbfcbea4f7 100644 --- a/lib/stdlib/src/filename.erl +++ b/lib/stdlib/src/filename.erl @@ -836,16 +836,18 @@ try_file(undefined, ObjFilename, Mod, Rules) -> Error -> Error end; try_file(Src, _ObjFilename, Mod, _Rules) -> - List = Mod:module_info(compile), - {options, Options} = lists:keyfind(options, 1, List), + List = case Mod:module_info(compile) of + none -> []; + List0 -> List0 + end, + Options = proplists:get_value(options, List, []), {ok, Cwd} = file:get_cwd(), AbsPath = make_abs_path(Cwd, Src), {AbsPath, filter_options(dirname(AbsPath), Options, [])}. %% Filters the options. %% -%% 1) Remove options that have no effect on the generated code, -%% such as report and verbose. +%% 1) Only keep options that have any effect on code generation. %% %% 2) The paths found in {i, Path} and {outdir, Path} are converted %% to absolute paths. When doing this, it is assumed that relatives @@ -857,14 +859,10 @@ filter_options(Base, [{outdir, Path}|Rest], Result) -> filter_options(Base, Rest, [{outdir, make_abs_path(Base, Path)}|Result]); filter_options(Base, [{i, Path}|Rest], Result) -> filter_options(Base, Rest, [{i, make_abs_path(Base, Path)}|Result]); -filter_options(Base, [Option|Rest], Result) when Option =:= trace -> - filter_options(Base, Rest, [Option|Result]); filter_options(Base, [Option|Rest], Result) when Option =:= export_all -> filter_options(Base, Rest, [Option|Result]); filter_options(Base, [Option|Rest], Result) when Option =:= binary -> filter_options(Base, Rest, [Option|Result]); -filter_options(Base, [Option|Rest], Result) when Option =:= fast -> - filter_options(Base, Rest, [Option|Result]); filter_options(Base, [Tuple|Rest], Result) when element(1, Tuple) =:= d -> filter_options(Base, Rest, [Tuple|Result]); filter_options(Base, [Tuple|Rest], Result) @@ -878,12 +876,7 @@ filter_options(_Base, [], Result) -> %% Gets the source file given path of object code and module name. get_source_file(Obj, Mod, Rules) -> - case catch Mod:module_info(source_file) of - {'EXIT', _Reason} -> - source_by_rules(dirname(Obj), packages:last(Mod), Rules); - File -> - {ok, File} - end. + source_by_rules(dirname(Obj), packages:last(Mod), Rules). source_by_rules(Dir, Base, [{From, To}|Rest]) -> case try_rule(Dir, Base, From, To) of diff --git a/lib/stdlib/src/gen_event.erl b/lib/stdlib/src/gen_event.erl index 9879b76391..3317b30e5c 100644 --- a/lib/stdlib/src/gen_event.erl +++ b/lib/stdlib/src/gen_event.erl @@ -70,7 +70,8 @@ -callback init(InitArgs :: term()) -> {ok, State :: term()} | - {ok, State :: term(), hibernate}. + {ok, State :: term(), hibernate} | + {error, Reason :: term()}. -callback handle_event(Event :: term(), State :: term()) -> {ok, NewState :: term()} | {ok, NewState :: term(), hibernate} | diff --git a/lib/stdlib/src/gen_server.erl b/lib/stdlib/src/gen_server.erl index 6f075bbe5a..af07bc988a 100644 --- a/lib/stdlib/src/gen_server.erl +++ b/lib/stdlib/src/gen_server.erl @@ -134,7 +134,7 @@ term(). -callback code_change(OldVsn :: (term() | {down, term()}), State :: term(), Extra :: term()) -> - {ok, NewState :: term()}. + {ok, NewState :: term()} | {error, Reason :: term()}. %%% ----------------------------------------------------------------- %%% Starts a generic server. diff --git a/lib/stdlib/src/otp_internal.erl b/lib/stdlib/src/otp_internal.erl index c1285dab60..ade79e710a 100644 --- a/lib/stdlib/src/otp_internal.erl +++ b/lib/stdlib/src/otp_internal.erl @@ -41,37 +41,12 @@ obsolete(Module, Name, Arity) -> no end. -obsolete_1(init, get_flag, 1) -> - {removed, {init, get_argument, 1}, "R12B"}; -obsolete_1(init, get_flags, 0) -> - {removed, {init, get_arguments, 0}, "R12B"}; -obsolete_1(init, get_args, 0) -> - {removed, {init, get_plain_arguments, 0}, "R12B"}; -obsolete_1(unix, cmd, 1) -> - {removed, {os,cmd,1}, "R9B"}; - obsolete_1(net, _, _) -> {deprecated, "module 'net' obsolete; use 'net_adm'"}; obsolete_1(erl_internal, builtins, 0) -> {deprecated, {erl_internal, bif, 2}}; -obsolete_1(string, re_sh_to_awk, 1) -> - {removed, {regexp, sh_to_awk, 1}, "R12B"}; -obsolete_1(string, re_parse, 1) -> - {removed, {regexp, parse, 1}, "R12B"}; -obsolete_1(string, re_match, 2) -> - {removed, {regexp, match, 2}, "R12B"}; -obsolete_1(string, re_sub, 3) -> - {removed, {regexp, sub, 3}, "R12B"}; -obsolete_1(string, re_gsub, 3) -> - {removed, {regexp, gsub, 3}, "R12B"}; -obsolete_1(string, re_split, 2) -> - {removed, {regexp, split, 2}, "R12B"}; - -obsolete_1(string, index, 2) -> - {removed, {string, str, 2}, "R12B"}; - obsolete_1(erl_eval, seq, 2) -> {deprecated, {erl_eval, exprs, 2}}; obsolete_1(erl_eval, seq, 3) -> @@ -81,99 +56,9 @@ obsolete_1(erl_eval, arg_list, 2) -> obsolete_1(erl_eval, arg_list, 3) -> {deprecated, {erl_eval, expr_list, 3}}; -obsolete_1(erl_pp, seq, 1) -> - {removed, {erl_pp, exprs, 1}, "R12B"}; -obsolete_1(erl_pp, seq, 2) -> - {removed, {erl_pp, exprs, 2}, "R12B"}; - -obsolete_1(io, scan_erl_seq, 1) -> - {removed, {io, scan_erl_exprs, 1}, "R12B"}; -obsolete_1(io, scan_erl_seq, 2) -> - {removed, {io, scan_erl_exprs, 2}, "R12B"}; -obsolete_1(io, scan_erl_seq, 3) -> - {removed, {io, scan_erl_exprs, 3}, "R12B"}; -obsolete_1(io, parse_erl_seq, 1) -> - {removed, {io, parse_erl_exprs, 1}, "R12B"}; -obsolete_1(io, parse_erl_seq, 2) -> - {removed, {io, parse_erl_exprs, 2}, "R12B"}; -obsolete_1(io, parse_erl_seq, 3) -> - {removed, {io, parse_erl_exprs, 3}, "R12B"}; -obsolete_1(io, parse_exprs, 2) -> - {removed, {io, parse_erl_exprs, 2}, "R12B"}; - -obsolete_1(io_lib, scan, 1) -> - {removed, {erl_scan, string, 1}, "R12B"}; -obsolete_1(io_lib, scan, 2) -> - {removed, {erl_scan, string, 2}, "R12B"}; -obsolete_1(io_lib, scan, 3) -> - {removed, {erl_scan, tokens, 3}, "R12B"}; -obsolete_1(io_lib, reserved_word, 1) -> - {removed, {erl_scan, reserved_word, 1}, "R12B"}; - -obsolete_1(lists, keymap, 4) -> - {removed, {lists, keymap, 3}, "R12B"}; -obsolete_1(lists, all, 3) -> - {removed, {lists, all, 2}, "R12B"}; -obsolete_1(lists, any, 3) -> - {removed, {lists, any, 2}, "R12B"}; -obsolete_1(lists, map, 3) -> - {removed, {lists, map, 2}, "R12B"}; -obsolete_1(lists, flatmap, 3) -> - {removed, {lists, flatmap, 2}, "R12B"}; -obsolete_1(lists, foldl, 4) -> - {removed, {lists, foldl, 3}, "R12B"}; -obsolete_1(lists, foldr, 4) -> - {removed, {lists, foldr, 3}, "R12B"}; -obsolete_1(lists, mapfoldl, 4) -> - {removed, {lists, mapfoldl, 3}, "R12B"}; -obsolete_1(lists, mapfoldr, 4) -> - {removed, {lists, mapfoldr, 3}, "R12B"}; -obsolete_1(lists, filter, 3) -> - {removed, {lists, filter, 2}, "R12B"}; -obsolete_1(lists, foreach, 3) -> - {removed, {lists, foreach, 2}, "R12B"}; -obsolete_1(lists, zf, 3) -> - {removed, {lists, zf, 2}, "R12B"}; - -obsolete_1(ets, fixtable, 2) -> - {removed, {ets, safe_fixtable, 2}, "R12B"}; - -obsolete_1(erlang, old_binary_to_term, 1) -> - {removed, {erlang, binary_to_term, 1}, "R12B"}; -obsolete_1(erlang, info, 1) -> - {removed, {erlang, system_info, 1}, "R12B"}; obsolete_1(erlang, hash, 2) -> {deprecated, {erlang, phash2, 2}}; -obsolete_1(file, file_info, 1) -> - {removed, {file, read_file_info, 1}, "R12B"}; - -obsolete_1(dict, dict_to_list, 1) -> - {removed, {dict,to_list,1}, "R12B"}; -obsolete_1(dict, list_to_dict, 1) -> - {removed, {dict,from_list,1}, "R12B"}; -obsolete_1(orddict, dict_to_list, 1) -> - {removed, {orddict,to_list,1}, "R12B"}; -obsolete_1(orddict, list_to_dict, 1) -> - {removed, {orddict,from_list,1}, "R12B"}; - -obsolete_1(sets, new_set, 0) -> - {removed, {sets, new, 0}, "R12B"}; -obsolete_1(sets, set_to_list, 1) -> - {removed, {sets, to_list, 1}, "R12B"}; -obsolete_1(sets, list_to_set, 1) -> - {removed, {sets, from_list, 1}, "R12B"}; -obsolete_1(sets, subset, 2) -> - {removed, {sets, is_subset, 2}, "R12B"}; -obsolete_1(ordsets, new_set, 0) -> - {removed, {ordsets, new, 0}, "R12B"}; -obsolete_1(ordsets, set_to_list, 1) -> - {removed, {ordsets, to_list, 1}, "R12B"}; -obsolete_1(ordsets, list_to_set, 1) -> - {removed, {ordsets, from_list, 1}, "R12B"}; -obsolete_1(ordsets, subset, 2) -> - {removed, {ordsets, is_subset, 2}, "R12B"}; - obsolete_1(calendar, local_time_to_universal_time, 1) -> {deprecated, {calendar, local_time_to_universal_time_dst, 1}}; @@ -302,17 +187,6 @@ obsolete_1(auth, node_cookie, 1) -> obsolete_1(auth, node_cookie, 2) -> {deprecated, "Deprecated; use erlang:set_cookie/2 and net_adm:ping/1 instead"}; -%% Added in R11B-5. -obsolete_1(http_base_64, _, _) -> - {removed, "The http_base_64 module was removed in R12B; use the base64 module instead"}; -obsolete_1(httpd_util, encode_base64, 1) -> - {removed, "Removed in R12B; use one of the encode functions in the base64 module instead"}; -obsolete_1(httpd_util, decode_base64, 1) -> - {removed, "Removed in R12B; use one of the decode functions in the base64 module instead"}; -obsolete_1(httpd_util, to_upper, 1) -> - {removed, {string, to_upper, 1}, "R12B"}; -obsolete_1(httpd_util, to_lower, 1) -> - {removed, {string, to_lower, 1}, "R12B"}; obsolete_1(erlang, is_constant, 1) -> {removed, "Removed in R13B"}; @@ -431,7 +305,7 @@ obsolete_1(ssh_sshd, stop, 1) -> %% Added in R13A. obsolete_1(regexp, _, _) -> - {deprecated, "the regexp module is deprecated (will be removed in R15A); use the re module instead"}; + {removed, "removed in R15; use the re module instead"}; obsolete_1(lists, flat_length, 1) -> {removed,{lists,flatlength,1},"R14"}; @@ -472,6 +346,8 @@ obsolete_1(docb_xml_check, _, _) -> %% Added in R15B obsolete_1(asn1rt, F, _) when F == load_driver; F == unload_driver -> {deprecated,"deprecated (will be removed in R16A); has no effect as drivers are no longer used."}; +obsolete_1(ssl, pid, 1) -> + {deprecated,"deprecated (will be removed in R17); is no longer needed"}; obsolete_1(_, _, _) -> no. diff --git a/lib/stdlib/src/regexp.erl b/lib/stdlib/src/regexp.erl deleted file mode 100644 index 65f9ca247d..0000000000 --- a/lib/stdlib/src/regexp.erl +++ /dev/null @@ -1,557 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2011. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% --module(regexp). - -%% This entire module is deprecated and will be removed in a future -%% release. Use the 're' module instead. -%% -%% This module provides a basic set of regular expression functions -%% for strings. The functions provided are taken from AWK. -%% -%% Note that we interpret the syntax tree of a regular expression -%% directly instead of converting it to an NFA and then interpreting -%% that. This method seems to go significantly faster. - --export([sh_to_awk/1,parse/1,format_error/1,match/2,first_match/2,matches/2]). --export([sub/3,gsub/3,split/2]). - --deprecated([sh_to_awk/1,parse/1,format_error/1,match/2,first_match/2,matches/2]). --deprecated([sub/3,gsub/3,split/2]). - --import(string, [substr/2,substr/3]). --import(lists, [reverse/1]). - --type errordesc() :: term(). --opaque regexp() :: term(). - -%% -type matchres() = {match,Start,Length} | nomatch | {error,E}. -%% -type subres() = {ok,RepString,RepCount} | {error,E}. -%% -type splitres() = {ok,[SubString]} | {error,E}. - -%%-compile([export_all]). - -%% This is the regular expression grammar used. It is equivalent to the -%% one used in AWK, except that we allow ^ $ to be used anywhere and fail -%% in the matching. -%% -%% reg -> reg1 : '$1'. -%% reg1 -> reg1 "|" reg2 : {'or','$1','$2'}. -%% reg1 -> reg2 : '$1'. -%% reg2 -> reg2 reg3 : {concat,'$1','$2'}. -%% reg2 -> reg3 : '$1'. -%% reg3 -> reg3 "*" : {kclosure,'$1'}. -%% reg3 -> reg3 "+" : {pclosure,'$1'}. -%% reg3 -> reg3 "?" : {optional,'$1'}. -%% reg3 -> reg4 : '$1'. -%% reg4 -> "(" reg ")" : '$2'. -%% reg4 -> "\\" char : '$2'. -%% reg4 -> "^" : bos. -%% reg4 -> "$" : eos. -%% reg4 -> "." : char. -%% reg4 -> "[" class "]" : {char_class,char_class('$2')} -%% reg4 -> "[" "^" class "]" : {comp_class,char_class('$3')} -%% reg4 -> "\"" chars "\"" : char_string('$2') -%% reg4 -> char : '$1'. -%% reg4 -> empty : epsilon. -%% The grammar of the current regular expressions. The actual parser -%% is a recursive descent implementation of the grammar. - -reg(S) -> reg1(S). - -%% reg1 -> reg2 reg1' -%% reg1' -> "|" reg2 -%% reg1' -> empty - -reg1(S0) -> - {L,S1} = reg2(S0), - reg1p(S1, L). - -reg1p([$||S0], L) -> - {R,S1} = reg2(S0), - reg1p(S1, {'or',L,R}); -reg1p(S, L) -> {L,S}. - -%% reg2 -> reg3 reg2' -%% reg2' -> reg3 -%% reg2' -> empty - -reg2(S0) -> - {L,S1} = reg3(S0), - reg2p(S1, L). - -reg2p([C|S0], L) when C =/= $|, C =/= $) -> - {R,S1} = reg3([C|S0]), - reg2p(S1, {concat,L,R}); -reg2p(S, L) -> {L,S}. - -%% reg3 -> reg4 reg3' -%% reg3' -> "*" reg3' -%% reg3' -> "+" reg3' -%% reg3' -> "?" reg3' -%% reg3' -> empty - -reg3(S0) -> - {L,S1} = reg4(S0), - reg3p(S1, L). - -reg3p([$*|S], L) -> reg3p(S, {kclosure,L}); -reg3p([$+|S], L) -> reg3p(S, {pclosure,L}); -reg3p([$?|S], L) -> reg3p(S, {optional,L}); -reg3p(S, L) -> {L,S}. - --define(HEX(C), C >= $0 andalso C =< $9 orelse - C >= $A andalso C =< $F orelse - C >= $a andalso C =< $f). - -reg4([$(|S0]) -> - case reg(S0) of - {R,[$)|S1]} -> {R,S1}; - {_R,_S} -> throw({error,{unterminated,"("}}) - end; -reg4([$\\,O1,O2,O3|S]) when - O1 >= $0, O1 =< $7, O2 >= $0, O2 =< $7, O3 >= $0, O3 =< $7 -> - {(O1*8 + O2)*8 + O3 - 73*$0,S}; -reg4([$\\,$x,H1,H2|S]) when ?HEX(H1), ?HEX(H2) -> - {erlang:list_to_integer([H1,H2], 16),S}; -reg4([$\\,$x,${|S]) -> - hex(S, []); -reg4([$\\,$x|_]) -> - throw({error,{illegal,[$x]}}); -reg4([$\\,C|S]) -> {escape_char(C),S}; -reg4([$\\]) -> throw({error,{unterminated,"\\"}}); -reg4([$^|S]) -> {bos,S}; -reg4([$$|S]) -> {eos,S}; -reg4([$.|S]) -> {{comp_class,"\n"},S}; -reg4("[^" ++ S0) -> - case char_class(S0) of - {Cc,[$]|S1]} -> {{comp_class,Cc},S1}; - {_Cc,_S} -> throw({error,{unterminated,"["}}) - end; -reg4([$[|S0]) -> - case char_class(S0) of - {Cc,[$]|S1]} -> {{char_class,Cc},S1}; - {_Cc,_S1} -> throw({error,{unterminated,"["}}) - end; -%reg4([$"|S0]) -> -% case char_string(S0) of -% {St,[$"|S1]} -> {St,S1}; -% {St,S1} -> throw({error,{unterminated,"\""}}) -% end; -reg4([C|S]) when C =/= $*, C =/= $+, C =/= $?, C =/= $] -> {C,S}; -reg4([C|_S]) -> throw({error,{illegal,[C]}}); -reg4([]) -> {epsilon,[]}. - -hex([C|Cs], L) when ?HEX(C) -> - hex(Cs, [C|L]); -hex([$}|S], L) -> - case catch erlang:list_to_integer(lists:reverse(L), 16) of - V when V =< 16#FF -> - {V,S}; - _ -> - throw({error,{illegal,[$}]}}) - end; -hex(_S, _) -> - throw({error,{unterminated,"\\x{"}}). - -escape_char($n) -> $\n; %\n = LF -escape_char($r) -> $\r; %\r = CR -escape_char($t) -> $\t; %\t = TAB -escape_char($v) -> $\v; %\v = VT -escape_char($b) -> $\b; %\b = BS -escape_char($f) -> $\f; %\f = FF -escape_char($e) -> $\e; %\e = ESC -escape_char($s) -> $\s; %\s = SPACE -escape_char($d) -> $\d; %\d = DEL -escape_char(C) -> C. - -char_class([$]|S]) -> char_class(S, [$]]); -char_class(S) -> char_class(S, []). - -char($\\, [O1,O2,O3|S]) when - O1 >= $0, O1 =< $7, O2 >= $0, O2 =< $7, O3 >= $0, O3 =< $7 -> - {(O1*8 + O2)*8 + O3 - 73*$0,S}; -char($\\, [$x,H1,H2|S]) when ?HEX(H1), ?HEX(H2) -> - {erlang:list_to_integer([H1,H2], 16),S}; -char($\\,[$x,${|S]) -> - hex(S, []); -char($\\,[$x|_]) -> - throw({error,{illegal,[$x]}}); -char($\\, [C|S]) -> {escape_char(C),S}; -char(C, S) -> {C,S}. - -char_class([C1|S0], Cc) when C1 =/= $] -> - case char(C1, S0) of - {Cf,[$-,C2|S1]} when C2 =/= $] -> - case char(C2, S1) of - {Cl,S2} when Cf < Cl -> char_class(S2, [{Cf,Cl}|Cc]); - {Cl,_S2} -> throw({error,{char_class,[Cf,$-,Cl]}}) - end; - {C,S1} -> char_class(S1, [C|Cc]) - end; -char_class(S, Cc) -> {Cc,S}. - -%char_string([C|S]) when C =/= $" -> char_string(S, C); -%char_string(S) -> {epsilon,S}. - -%char_string([C|S0], L) when C =/= $" -> -% char_string(S0, {concat,L,C}); -%char_string(S, L) -> {L,S}. - -%% -deftype re_app_res() = {match,RestPos,Rest} | nomatch. - -%% re_apply(String, StartPos, RegExp) -> re_app_res(). -%% -%% Apply the (parse of the) regular expression RegExp to String. If -%% there is a match return the position of the remaining string and -%% the string if else return 'nomatch'. BestMatch specifies if we want -%% the longest match, or just a match. -%% -%% StartPos should be the real start position as it is used to decide -%% if we ae at the beginning of the string. -%% -%% Pass two functions to re_apply_or so it can decide, on the basis -%% of BestMatch, whether to just any take any match or try both to -%% find the longest. This is slower but saves duplicatng code. - -re_apply(S, St, RE) -> re_apply(RE, [], S, St). - -re_apply(epsilon, More, S, P) -> %This always matches - re_apply_more(More, S, P); -re_apply({'or',RE1,RE2}, More, S, P) -> - re_apply_or(re_apply(RE1, More, S, P), - re_apply(RE2, More, S, P)); -re_apply({concat,RE1,RE2}, More, S0, P) -> - re_apply(RE1, [RE2|More], S0, P); -re_apply({kclosure,CE}, More, S, P) -> - %% Be careful with the recursion, explicitly do one call before - %% looping. - re_apply_or(re_apply_more(More, S, P), - re_apply(CE, [{kclosure,CE}|More], S, P)); -re_apply({pclosure,CE}, More, S, P) -> - re_apply(CE, [{kclosure,CE}|More], S, P); -re_apply({optional,CE}, More, S, P) -> - re_apply_or(re_apply_more(More, S, P), - re_apply(CE, More, S, P)); -re_apply(bos, More, S, 1) -> re_apply_more(More, S, 1); -re_apply(eos, More, [$\n|S], P) -> re_apply_more(More, S, P); -re_apply(eos, More, [], P) -> re_apply_more(More, [], P); -re_apply({char_class,Cc}, More, [C|S], P) -> - case in_char_class(C, Cc) of - true -> re_apply_more(More, S, P+1); - false -> nomatch - end; -re_apply({comp_class,Cc}, More, [C|S], P) -> - case in_char_class(C, Cc) of - true -> nomatch; - false -> re_apply_more(More, S, P+1) - end; -re_apply(C, More, [C|S], P) when is_integer(C) -> - re_apply_more(More, S, P+1); -re_apply(_RE, _More, _S, _P) -> nomatch. - -%% re_apply_more([RegExp], String, Length) -> re_app_res(). - -re_apply_more([RE|More], S, P) -> re_apply(RE, More, S, P); -re_apply_more([], S, P) -> {match,P,S}. - -%% in_char_class(Char, Class) -> bool(). - -in_char_class(C, [{C1,C2}|_Cc]) when C >= C1, C =< C2 -> true; -in_char_class(C, [C|_Cc]) -> true; -in_char_class(C, [_|Cc]) -> in_char_class(C, Cc); -in_char_class(_C, []) -> false. - -%% re_apply_or(Match1, Match2) -> re_app_res(). -%% If we want the best match then choose the longest match, else just -%% choose one by trying sequentially. - -re_apply_or({match,P1,S1}, {match,P2,_S2}) when P1 >= P2 -> {match,P1,S1}; -re_apply_or({match,_P1,_S1}, {match,P2,S2}) -> {match,P2,S2}; -re_apply_or(nomatch, R2) -> R2; -re_apply_or(R1, nomatch) -> R1. - -%% sh_to_awk(ShellRegExp) -%% Convert a sh style regexp into a full AWK one. The main difficulty is -%% getting character sets right as the conventions are different. - --spec sh_to_awk(ShRegExp) -> AwkRegExp when - ShRegExp :: string(), - AwkRegExp :: string(). - -sh_to_awk(Sh) -> "^(" ++ sh_to_awk_1(Sh). %Fix the beginning - -sh_to_awk_1([$*|Sh]) -> %This matches any string - ".*" ++ sh_to_awk_1(Sh); -sh_to_awk_1([$?|Sh]) -> %This matches any character - [$.|sh_to_awk_1(Sh)]; -sh_to_awk_1([$[,$^,$]|Sh]) -> %This takes careful handling - "\\^" ++ sh_to_awk_1(Sh); -sh_to_awk_1("[^" ++ Sh) -> [$[|sh_to_awk_2(Sh, true)]; -sh_to_awk_1("[!" ++ Sh) -> "[^" ++ sh_to_awk_2(Sh, false); -sh_to_awk_1([$[|Sh]) -> [$[|sh_to_awk_2(Sh, false)]; -sh_to_awk_1([C|Sh]) -> - %% Unspecialise everything else which is not an escape character. - case special_char(C) of - true -> [$\\,C|sh_to_awk_1(Sh)]; - false -> [C|sh_to_awk_1(Sh)] - end; -sh_to_awk_1([]) -> ")$". %Fix the end - -sh_to_awk_2([$]|Sh], UpArrow) -> [$]|sh_to_awk_3(Sh, UpArrow)]; -sh_to_awk_2(Sh, UpArrow) -> sh_to_awk_3(Sh, UpArrow). - -sh_to_awk_3([$]|Sh], true) -> "^]" ++ sh_to_awk_1(Sh); -sh_to_awk_3([$]|Sh], false) -> [$]|sh_to_awk_1(Sh)]; -sh_to_awk_3([C|Sh], UpArrow) -> [C|sh_to_awk_3(Sh, UpArrow)]; -sh_to_awk_3([], true) -> [$^|sh_to_awk_1([])]; -sh_to_awk_3([], false) -> sh_to_awk_1([]). - -%% -type special_char(char()) -> bool(). -%% Test if a character is a special character. - -special_char($|) -> true; -special_char($*) -> true; -special_char($+) -> true; -special_char($?) -> true; -special_char($() -> true; -special_char($)) -> true; -special_char($\\) -> true; -special_char($^) -> true; -special_char($$) -> true; -special_char($.) -> true; -special_char($[) -> true; -special_char($]) -> true; -special_char($") -> true; -special_char(_C) -> false. - -%% parse(RegExp) -> {ok,RE} | {error,E}. -%% Parse the regexp described in the string RegExp. - --spec parse(RegExp) -> ParseRes when - RegExp :: string(), - ParseRes :: {ok, RE} | {error, Error}, - RE :: regexp(), - Error :: errordesc(). - -parse(S) -> - case catch reg(S) of - {R,[]} -> {ok,R}; - {_R,[C|_]} -> {error,{illegal,[C]}}; - {error,E} -> {error,E} - end. - -%% format_error(Error) -> String. - --spec format_error(ErrorDescriptor) -> Chars when - ErrorDescriptor :: errordesc(), - Chars :: io_lib:chars(). - -format_error({illegal,What}) -> ["illegal character `",What,"'"]; -format_error({unterminated,What}) -> ["unterminated `",What,"'"]; -format_error({char_class,What}) -> - ["illegal character class ",io_lib:write_string(What)]. - -%% -type match(String, RegExp) -> matchres(). -%% Find the longest match of RegExp in String. - --spec match(String, RegExp) -> MatchRes when - String :: string(), - RegExp :: string() | regexp(), - MatchRes :: {match, Start, Length} | nomatch | {error, Error}, - Start :: pos_integer(), - Length :: pos_integer(), - Error :: errordesc(). - -match(S, RegExp) when is_list(RegExp) -> - case parse(RegExp) of - {ok,RE} -> match(S, RE); - {error,E} -> {error,E} - end; -match(S, RE) -> - case match(RE, S, 1, 0, -1) of - {Start,Len} when Len >= 0 -> - {match,Start,Len}; - {_Start,_Len} -> nomatch - end. - -match(RE, S, St, Pos, L) -> - case first_match(RE, S, St) of - {St1,L1} -> - Nst = St1 + 1, - if L1 > L -> match(RE, lists:nthtail(Nst-St, S), Nst, St1, L1); - true -> match(RE, lists:nthtail(Nst-St, S), Nst, Pos, L) - end; - nomatch -> {Pos,L} - end. - -%% -type first_match(String, RegExp) -> matchres(). -%% Find the first match of RegExp in String. - --spec first_match(String, RegExp) -> MatchRes when - String :: string(), - RegExp :: string() | regexp(), - MatchRes :: {match, Start, Length} | nomatch | {error, Error}, - Start :: pos_integer(), - Length :: pos_integer(), - Error :: errordesc(). - -first_match(S, RegExp) when is_list(RegExp) -> - case parse(RegExp) of - {ok,RE} -> first_match(S, RE); - {error,E} -> {error,E} - end; -first_match(S, RE) -> - case first_match(RE, S, 1) of - {Start,Len} when Len >= 0 -> - {match,Start,Len}; - nomatch -> nomatch - end. - -first_match(RE, S, St) when S =/= [] -> - case re_apply(S, St, RE) of - {match,P,_Rest} -> {St,P-St}; - nomatch -> first_match(RE, tl(S), St+1) - end; -first_match(_RE, [], _St) -> nomatch. - -%% -type matches(String, RegExp) -> {match,[{Start,Length}]} | {error,E}. -%% Return the all the non-overlapping matches of RegExp in String. - --spec matches(String, RegExp) -> MatchRes when - String :: string(), - RegExp :: string() | regexp(), - MatchRes :: {match, Matches} | {error, Error}, - Matches :: [{Start, Length}], - Start :: pos_integer(), - Length :: pos_integer(), - Error :: errordesc(). - -matches(S, RegExp) when is_list(RegExp) -> - case parse(RegExp) of - {ok,RE} -> matches(S, RE); - {error,E} -> {error,E} - end; -matches(S, RE) -> - {match,matches(S, RE, 1)}. - -matches(S, RE, St) -> - case first_match(RE, S, St) of - {St1,0} -> [{St1,0}|matches(substr(S, St1+2-St), RE, St1+1)]; - {St1,L1} -> [{St1,L1}|matches(substr(S, St1+L1+1-St), RE, St1+L1)]; - nomatch -> [] - end. - -%% -type sub(String, RegExp, Replace) -> subsres(). -%% Substitute the first match of the regular expression RegExp with -%% the string Replace in String. Accept pre-parsed regular -%% expressions. - --spec sub(String, RegExp, New) -> SubRes when - String :: string(), - RegExp :: string() | regexp(), - New :: string(), - NewString :: string(), - SubRes :: {ok, NewString, RepCount} | {error, Error}, - RepCount :: 0 | 1, - Error :: errordesc(). - -sub(String, RegExp, Rep) when is_list(RegExp) -> - case parse(RegExp) of - {ok,RE} -> sub(String, RE, Rep); - {error,E} -> {error,E} - end; -sub(String, RE, Rep) -> - Ss = sub_match(String, RE, 1), - {ok,sub_repl(Ss, Rep, String, 1),length(Ss)}. - -sub_match(S, RE, St) -> - case first_match(RE, S, St) of - {St1,L1} -> [{St1,L1}]; - nomatch -> [] - end. - -sub_repl([{St,L}|Ss], Rep, S, Pos) -> - Rs = sub_repl(Ss, Rep, S, St+L), - substr(S, Pos, St-Pos) ++ sub_repl(Rep, substr(S, St, L), Rs); -sub_repl([], _Rep, S, Pos) -> substr(S, Pos). - -sub_repl([$&|Rep], M, Rest) -> M ++ sub_repl(Rep, M, Rest); -sub_repl("\\&" ++ Rep, M, Rest) -> [$&|sub_repl(Rep, M, Rest)]; -sub_repl([C|Rep], M, Rest) -> [C|sub_repl(Rep, M, Rest)]; -sub_repl([], _M, Rest) -> Rest. - -%% -type gsub(String, RegExp, Replace) -> subres(). -%% Substitute every match of the regular expression RegExp with the -%% string New in String. Accept pre-parsed regular expressions. - --spec gsub(String, RegExp, New) -> SubRes when - String :: string(), - RegExp :: string() | regexp(), - New :: string(), - NewString :: string(), - SubRes :: {ok, NewString, RepCount} | {error, Error}, - RepCount :: non_neg_integer(), - Error :: errordesc(). - -gsub(String, RegExp, Rep) when is_list(RegExp) -> - case parse(RegExp) of - {ok,RE} -> gsub(String, RE, Rep); - {error,E} -> {error,E} - end; -gsub(String, RE, Rep) -> - Ss = matches(String, RE, 1), - {ok,sub_repl(Ss, Rep, String, 1),length(Ss)}. - -%% -type split(String, RegExp) -> splitres(). -%% Split a string into substrings where the RegExp describes the -%% field seperator. The RegExp " " is specially treated. - --spec split(String, RegExp) -> SplitRes when - String :: string(), - RegExp :: string() | regexp(), - SplitRes :: {ok, FieldList} | {error, Error}, - FieldList :: [string()], - Error :: errordesc(). - -split(String, " ") -> %This is really special - {ok,RE} = parse("[ \t]+"), - case split_apply(String, RE, true) of - [[]|Ss] -> {ok,Ss}; - Ss -> {ok,Ss} - end; -split(String, RegExp) when is_list(RegExp) -> - case parse(RegExp) of - {ok,RE} -> {ok,split_apply(String, RE, false)}; - {error,E} -> {error,E} - end; -split(String, RE) -> {ok,split_apply(String, RE, false)}. - -split_apply(S, RE, Trim) -> split_apply(S, 1, RE, Trim, []). - -split_apply([], _P, _RE, true, []) -> []; -split_apply([], _P, _RE, _T, Sub) -> [reverse(Sub)]; -split_apply(S, P, RE, T, Sub) -> - case re_apply(S, P, RE) of - {match,P,_Rest} -> - split_apply(tl(S), P+1, RE, T, [hd(S)|Sub]); - {match,P1,Rest} -> - [reverse(Sub)|split_apply(Rest, P1, RE, T, [])]; - nomatch -> - split_apply(tl(S), P+1, RE, T, [hd(S)|Sub]) - end. diff --git a/lib/stdlib/src/shell.erl b/lib/stdlib/src/shell.erl index 964697cae6..dc450f0ee6 100644 --- a/lib/stdlib/src/shell.erl +++ b/lib/stdlib/src/shell.erl @@ -1065,9 +1065,10 @@ local_func(F, As0, Bs0, _Shell, _RT, Lf, Ef) when is_atom(F) -> non_builtin_local_func(F,As,Bs). non_builtin_local_func(F,As,Bs) -> - case erlang:function_exported(user_default, F, length(As)) of + Arity = length(As), + case erlang:function_exported(user_default, F, Arity) of true -> - {eval,{user_default,F},As,Bs}; + {eval,erlang:make_fun(user_default, F, Arity),As,Bs}; false -> shell_default(F,As,Bs) end. @@ -1079,7 +1080,7 @@ shell_default(F,As,Bs) -> {module, _} -> case erlang:function_exported(M,F,A) of true -> - {eval,{M,F},As,Bs}; + {eval,erlang:make_fun(M, F, A),As,Bs}; false -> shell_undef(F,A) end; diff --git a/lib/stdlib/src/stdlib.app.src b/lib/stdlib/src/stdlib.app.src index 9d15f01683..da65db4b9d 100644 --- a/lib/stdlib/src/stdlib.app.src +++ b/lib/stdlib/src/stdlib.app.src @@ -85,7 +85,6 @@ queue, random, re, - regexp, sets, shell, shell_default, diff --git a/lib/stdlib/src/stdlib.appup.src b/lib/stdlib/src/stdlib.appup.src index 54a63833e6..94e81188b5 100644 --- a/lib/stdlib/src/stdlib.appup.src +++ b/lib/stdlib/src/stdlib.appup.src @@ -1 +1,27 @@ -{"%VSN%",[],[]}. +%% -*- erlang -*- +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2011. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +{"%VSN%", + %% Up from - max two major revisions back + [{<<"1\\.18(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R15 + {<<"1\\.17(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R14 + {<<"1\\.16(\\.[0-9]+)*">>,[restart_new_emulator]}],%% R13 + %% Down to - max two major revisions back + [{<<"1\\.18(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R15 + {<<"1\\.17(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R14 + {<<"1\\.16(\\.[0-9]+)*">>,[restart_new_emulator]}] %% R13 +}. diff --git a/lib/stdlib/src/supervisor.erl b/lib/stdlib/src/supervisor.erl index 2dd5ccce7a..42ea42f42e 100644 --- a/lib/stdlib/src/supervisor.erl +++ b/lib/stdlib/src/supervisor.erl @@ -37,7 +37,7 @@ %%-------------------------------------------------------------------------- --type child() :: pid() | 'undefined'. +-type child() :: 'undefined' | pid() | [pid()]. -type child_id() :: term(). -type mfargs() :: {M :: module(), F :: atom(), A :: [term()] | undefined}. -type modules() :: [module()] | 'dynamic'. diff --git a/lib/stdlib/test/binary_module_SUITE.erl b/lib/stdlib/test/binary_module_SUITE.erl index 8fb63f33bd..bac59a3107 100644 --- a/lib/stdlib/test/binary_module_SUITE.erl +++ b/lib/stdlib/test/binary_module_SUITE.erl @@ -20,7 +20,7 @@ -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2, - interesting/1,random_ref_comp/1,random_ref_sr_comp/1, + interesting/1,scope_return/1,random_ref_comp/1,random_ref_sr_comp/1, random_ref_fla_comp/1,parts/1, bin_to_list/1, list_to_bin/1, copy/1, referenced/1,guard/1,encode_decode/1,badargs/1,longest_common_trap/1]). @@ -67,7 +67,7 @@ end_per_testcase(_Case, Config) -> suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> - [interesting, random_ref_fla_comp, random_ref_sr_comp, + [scope_return,interesting, random_ref_fla_comp, random_ref_sr_comp, random_ref_comp, parts, bin_to_list, list_to_bin, copy, referenced, guard, encode_decode, badargs, longest_common_trap]. @@ -379,6 +379,20 @@ subj() -> Subject. +scope_return(doc) -> + ["Test correct return values for scopes (OTP-9701)."]; +scope_return(Config) when is_list(Config) -> + N=10000, + Bin=binary:copy(<<"a">>,N), + scope_loop(Bin,0,N). + +scope_loop(_,N,N) -> + ok; +scope_loop(Bin,N,M) -> + ?line {N,1} = binary:match(Bin,<<"a">>,[{scope,{N,1}}]), + ?line {N,1} = binary:match(Bin,[<<"a">>,<<"b">>],[{scope,{N,1}}]), + scope_loop(Bin,N+1,M). + interesting(doc) -> ["Try some interesting patterns"]; interesting(Config) when is_list(Config) -> diff --git a/lib/stdlib/test/filename_SUITE.erl b/lib/stdlib/test/filename_SUITE.erl index 70b0d413dc..4cfa589660 100644 --- a/lib/stdlib/test/filename_SUITE.erl +++ b/lib/stdlib/test/filename_SUITE.erl @@ -483,6 +483,22 @@ find_src(Config) when is_list(Config) -> %% Try to find the source for a preloaded module. ?line {error,{preloaded,init}} = filename:find_src(init), + + %% Make sure that find_src works for a slim BEAM file. + OldPath = code:get_path(), + try + PrivDir = ?config(priv_dir, Config), + code:add_patha(PrivDir), + Src = "simple", + SrcPath = filename:join(PrivDir, Src) ++ ".erl", + SrcContents = "-module(simple).\n", + ok = file:write_file(SrcPath, SrcContents), + {ok,simple} = compile:file(SrcPath, [slim,{outdir,PrivDir}]), + BeamPath = filename:join(PrivDir, Src), + {BeamPath,[]} = filename:find_src(simple) + after + code:set_path(OldPath) + end, ok. %% diff --git a/lib/stdlib/test/qlc_SUITE.erl b/lib/stdlib/test/qlc_SUITE.erl index 8a9d8f7883..50a76cdfb5 100644 --- a/lib/stdlib/test/qlc_SUITE.erl +++ b/lib/stdlib/test/qlc_SUITE.erl @@ -20,7 +20,6 @@ %%% Purpose:Test Suite for the 'qlc' module. %%%----------------------------------------------------------------- -module(qlc_SUITE). --compile(r12). -define(QLC, qlc). -define(QLCs, "qlc"). @@ -6118,6 +6117,7 @@ otp_6964(Config) when is_list(Config) -> qlc:e(Q, [{max_list_size,64*1024},{tmpdir_usage,Use}]) end, D = erlang:system_flag(backtrace_depth, 0), + try 20000 = length(F(allowed)), ErrReply = F(not_allowed), {error, qlc, {tmpdir_usage,joining}} = ErrReply, @@ -6129,8 +6129,10 @@ otp_6964(Config) when is_list(Config) -> 20000 = length(F(info_msg)), {info, joining} = qlc_SUITE:read_error_logger(), 20000 = length(F(error_msg)), - {error, joining} = qlc_SUITE:read_error_logger(), - _ = erlang:system_flag(backtrace_depth, D), + {error, joining} = qlc_SUITE:read_error_logger() + after + _ = erlang:system_flag(backtrace_depth, D) + end, qlc_SUITE:uninstall_error_logger()">>], ?line run(Config, T1), @@ -7399,70 +7401,37 @@ backward(doc) -> "OTP-6674. Join info and extra constants."; backward(suite) -> []; backward(Config) when is_list(Config) -> - case try_old_join_info(Config) of - ok -> - ok; - Reply -> - Reply - end. - --ifdef(debug). -try_old_join_info(_Config) -> + try_old_join_info(Config), ok. --else. + try_old_join_info(Config) -> - case ?t:is_release_available("r12b") of - true -> - %% Check join info for handlers of extra constants. Start R12B-0. - ?line {ok, R12} = start_node_rel(r12, r12b, slave), - File = filename("handle.erl", Config), - ?line file:write_file(File, - <<"-module(handle).\n" - "-export([create_handle/0, lookup_handle/0]).\n" - "-include_lib(\"stdlib/include/qlc.hrl\").\n" - "create_handle() ->\n" - " H1 = qlc:sort([{192.0,1,a},{192.0,2,b},{192.0,3,c}]),\n" - " qlc:q([{X, Y} || {B,X,_} <- H1,\n" - " B =:= 192.0,\n" - " {Y} <- [{0},{1},{2}],\n" - " X == Y]).\n", - "\n", - "lookup_handle() ->\n" - " E = qlc_SUITE:table([{1,a},{2,b},{3,c}], 1, [1]),\n" - " qlc:q([{X, Y} || {X,_} <- E,\n" - " {Y} <- [{0},{1},{2}],\n" - " X =:= Y]).\n">>), - ?line {ok, handle} = rpc:call(R12, compile, file, - [File, [{outdir,?privdir}]]), - ?line {module, handle} = rpc:call(R12, code, load_abs, - [filename:rootname(File)]), - ?line H = rpc:call(R12, handle, create_handle, []), - ?line {module, handle} = code:load_abs(filename:rootname(File)), - ?line {block,0, - [{match,_,_, - {call,_,_, - [{lc,_,_, - [_, - {op,_,'=:=', - {float,_,192.0}, - {call,_,{atom,_,element},[{integer,_,1},_]}}]}]}}, - _,_, - {call,_,_, - [{lc,_,_, - [_, - {op,_,'=:=',{var,_,'B'},{float,_,192.0}}, - {op,_,'==',{var,_,'X'},{var,_,'Y'}}]}]}]} - = qlc:info(H,{format,abstract_code}), - ?line [{1,1},{2,2}] = qlc:e(H), - ?line H2 = rpc:call(R12, handle, lookup_handle, []), - ?line {qlc,_,[{generate,_,{qlc,_,_,[{join,lookup}]}},_],[]} = - qlc:info(H2, {format,debug}), - ?line [{1,1},{2,2}] = qlc:e(H2), - stop_node(R12); - false -> - ?line {skipped, "No support for old node"} - end. --endif. + %% Check join info for handlers of extra constants. + File = filename:join(?datadir, "join_info_compat.erl"), + M = join_info_compat, + {ok, M} = compile:file(File, [{outdir, ?datadir}]), + {module, M} = code:load_abs(filename:rootname(File)), + H = M:create_handle(), + {block,0, + [{match,_,_, + {call,_,_, + [{lc,_,_, + [_, + {op,_,'=:=', + {float,_,192.0}, + {call,_,{atom,_,element},[{integer,_,1},_]}}]}]}}, + _,_, + {call,_,_, + [{lc,_,_, + [_, + {op,_,'=:=',{var,_,'B'},{float,_,192.0}}, + {op,_,'==',{var,_,'X'},{var,_,'Y'}}]}]}]} + = qlc:info(H,{format,abstract_code}), + [{1,1},{2,2}] = qlc:e(H), + + H2 = M:lookup_handle(), + {qlc,_,[{generate,_,{qlc,_,_,[{join,lookup}]}},_],[]} = + qlc:info(H2, {format,debug}), + [{1,1},{2,2}] = qlc:e(H2). forward(doc) -> ""; @@ -8127,27 +8096,6 @@ fail(Source) -> %% Copied from global_SUITE.erl. -start_node_rel(Name, Rel, How) -> - {Release, Compat} = case Rel of - this -> - {[this], "+R8"}; - Rel when is_atom(Rel) -> - {[{release, atom_to_list(Rel)}], ""}; - RelList -> - {RelList, ""} - end, - ?line Pa = filename:dirname(code:which(?MODULE)), - ?line Res = test_server:start_node(Name, How, - [{args, - Compat ++ - " -kernel net_setuptime 100 " - " -pa " ++ Pa}, - {erl, Release}]), - Res. - -stop_node(Node) -> - ?line ?t:stop_node(Node). - install_error_logger() -> error_logger:add_report_handler(?MODULE, self()). diff --git a/lib/stdlib/test/qlc_SUITE_data/join_info_compat.erl b/lib/stdlib/test/qlc_SUITE_data/join_info_compat.erl new file mode 100644 index 0000000000..e0db132c47 --- /dev/null +++ b/lib/stdlib/test/qlc_SUITE_data/join_info_compat.erl @@ -0,0 +1,1771 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +-module(join_info_compat). + +-compile(export_all). + +create_handle() -> + H1 = qlc:sort([{192.0,1,a},{192.0,2,b},{192.0,3,c}]), + qlc:q({qlc_lc, + % fun-info: {23,109048965,'-create_handle/0-fun-23-'} + fun() -> + {qlc_v1, + % fun-info: {2,105724313,'-create_handle/0-fun-2-'} + fun(S01_0_1, RL01_0_1, Go01_0_1) -> + Fun1_0_1 = + % fun-info: {1,131900588,'-create_handle/0-fun-1-'} + fun(0, RL1_0_1, _, _, _, _, _, _, _) + when is_list(RL1_0_1) -> + lists:reverse(RL1_0_1); + (0, _, _, _, _, _, _, _, _) -> + []; + (1, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_1_1, + B1, + X1) + when is_list(RL1_0_1) -> + Fun1_0_1(element(1, Go1_0_1), + [{X1,Y1}|RL1_0_1], + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_1_1, + B1, + X1); + (1, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_1_1, + B1, + X1) -> + [{X1,Y1}| + % fun-info: {0,27702789,'-create_handle/0-fun-0-'} + fun() -> + Fun1_0_1(element(1, + Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_1_1, + B1, + X1) + end]; + (2, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + _, + B1, + X1) -> + Fun1_0_1(3, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + element(4, Go1_0_1), + B1, + X1); + (3, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + [{B1,X1,_}|C1_0_1], + _, + _) -> + Fun1_0_1(element(3, Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_0_1, + B1, + X1); + (3, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + [_|C1_0_1], + _, + _) -> + Fun1_0_1(3, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_0_1, + [], + []); + (3, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + [], + _, + _) -> + Fun1_0_1(element(2, Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + [], + [], + []); + (3, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_1_1, + _, + _) -> + case C1_1_1() of + [{B1,X1,_}|C1_0_1] -> + Fun1_0_1(element(3, + Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_0_1, + B1, + X1); + [_|C1_0_1] -> + Fun1_0_1(3, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_0_1, + [], + []); + [] -> + Fun1_0_1(element(2, + Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + [], + [], + []); + E1_0_1 -> + E1_0_1 + end; + (4, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_1_1, + B1, + X1) -> + if + B1 =:= 192.0 -> + Fun1_0_1(element(6, + Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_1_1, + B1, + X1); + true -> + Fun1_0_1(element(5, + Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_1_1, + B1, + X1) + end; + (5, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + _, + Y1, + C1_1_1, + B1, + X1) -> + Fun1_0_1(6, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + element(9, Go1_0_1), + Y1, + C1_1_1, + B1, + X1); + (6, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + [{Y1}|C1_0_1], + _, + C1_1_1, + B1, + X1) -> + Fun1_0_1(element(8, Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_0_1, + Y1, + C1_1_1, + B1, + X1); + (6, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + [_|C1_0_1], + _, + C1_1_1, + B1, + X1) -> + Fun1_0_1(6, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_0_1, + [], + C1_1_1, + B1, + X1); + (6, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + [], + _, + C1_1_1, + B1, + X1) -> + Fun1_0_1(element(7, Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + [], + [], + C1_1_1, + B1, + X1); + (6, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + _, + C1_1_1, + B1, + X1) -> + case C1_3_1() of + [{Y1}|C1_0_1] -> + Fun1_0_1(element(8, + Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_0_1, + Y1, + C1_1_1, + B1, + X1); + [_|C1_0_1] -> + Fun1_0_1(6, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_0_1, + [], + C1_1_1, + B1, + X1); + [] -> + Fun1_0_1(element(7, + Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + [], + [], + C1_1_1, + B1, + X1); + E1_0_1 -> + E1_0_1 + end; + (7, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_1_1, + B1, + X1) -> + if + X1 == Y1 -> + Fun1_0_1(element(11, + Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_1_1, + B1, + X1); + true -> + Fun1_0_1(element(10, + Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_1_1, + B1, + X1) + end; + (8, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + _, + B1, + X1) -> + Fun1_0_1(9, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + element(14, Go1_0_1), + B1, + X1); + (9, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + _, + [[{B1,X1,_}|{Y1}]|C1_0_1], + _, + _) -> + Fun1_0_1(element(13, Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_0_1, + B1, + X1); + (9, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + _, + [_|C1_0_1], + _, + _) -> + Fun1_0_1(9, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + [], + C1_0_1, + [], + []); + (9, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + _, + [], + _, + _) -> + Fun1_0_1(element(12, Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + [], + [], + [], + []); + (9, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + _, + C1_1_1, + _, + _) -> + case C1_1_1() of + [[{B1,X1,_}|{Y1}]|C1_0_1] -> + Fun1_0_1(element(13, + Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_0_1, + B1, + X1); + [_|C1_0_1] -> + Fun1_0_1(9, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + [], + C1_0_1, + [], + []); + [] -> + Fun1_0_1(element(12, + Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + [], + [], + [], + []); + E1_0_1 -> + E1_0_1 + end + end, + Fun1_0_1(S01_0_1, + RL01_0_1, + Fun1_0_1, + Go01_0_1, + [], + [], + [], + [], + []) + end, + % fun-info: {3,41816426,'-create_handle/0-fun-3-'} + fun() -> + {<<$\203:8/integer-unit:1-unsigned-big, + $P:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $.:8/integer-unit:1-unsigned-big, + $x:8/integer-unit:1-unsigned-big, + $\234:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $N:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $-:8/integer-unit:1-unsigned-big, + $):8/integer-unit:1-unsigned-big, + $-:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $I:8/integer-unit:1-unsigned-big, + $M:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $0:8/integer-unit:1-unsigned-big, + $\227:8/integer-unit:1-unsigned-big, + $%:8/integer-unit:1-unsigned-big, + $\026:8/integer-unit:1-unsigned-big, + $%:8/integer-unit:1-unsigned-big, + $r:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $0:8/integer-unit:1-unsigned-big, + $0:8/integer-unit:1-unsigned-big, + $F:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $":8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big>>, + <<$\203:8/integer-unit:1-unsigned-big, + $P:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $<:8/integer-unit:1-unsigned-big, + $x:8/integer-unit:1-unsigned-big, + $\234:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $N:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $-:8/integer-unit:1-unsigned-big, + $):8/integer-unit:1-unsigned-big, + $-:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $I:8/integer-unit:1-unsigned-big, + $M:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $0:8/integer-unit:1-unsigned-big, + $\227:8/integer-unit:1-unsigned-big, + $%:8/integer-unit:1-unsigned-big, + $\026:8/integer-unit:1-unsigned-big, + $%:8/integer-unit:1-unsigned-big, + $r:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $0:8/integer-unit:1-unsigned-big, + $0:8/integer-unit:1-unsigned-big, + $::8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $":8/integer-unit:1-unsigned-big, + $P:8/integer-unit:1-unsigned-big, + $x:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $Y:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $9:8/integer-unit:1-unsigned-big, + $\r:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big>>, + <<$\203:8/integer-unit:1-unsigned-big, + $P:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $I:8/integer-unit:1-unsigned-big, + $x:8/integer-unit:1-unsigned-big, + $\234:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $M:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $/:8/integer-unit:1-unsigned-big, + $H:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $N:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $\006:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $e:8/integer-unit:1-unsigned-big, + $\211:8/integer-unit:1-unsigned-big, + $E:8/integer-unit:1-unsigned-big, + $\s:8/integer-unit:1-unsigned-big, + $>:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\023:8/integer-unit:1-unsigned-big, + $\210:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\232:8/integer-unit:1-unsigned-big, + $\226:8/integer-unit:1-unsigned-big, + $\223:8/integer-unit:1-unsigned-big, + $\237:8/integer-unit:1-unsigned-big, + $X:8/integer-unit:1-unsigned-big, + $\222:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\235:8/integer-unit:1-unsigned-big, + $l:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $g:8/integer-unit:1-unsigned-big, + $i:8/integer-unit:1-unsigned-big, + $d:8/integer-unit:1-unsigned-big, + $\200:8/integer-unit:1-unsigned-big, + $\001:8/integer-unit:1-unsigned-big, + $R:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\r:8/integer-unit:1-unsigned-big, + $\214:8/integer-unit:1-unsigned-big, + $\030:8/integer-unit:1-unsigned-big, + $@:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $c:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\017:8/integer-unit:1-unsigned-big, + $=:8/integer-unit:1-unsigned-big>>, + <<$\203:8/integer-unit:1-unsigned-big, + $h:8/integer-unit:1-unsigned-big, + $\003:8/integer-unit:1-unsigned-big, + $d:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\005:8/integer-unit:1-unsigned-big, + $t:8/integer-unit:1-unsigned-big, + $u:8/integer-unit:1-unsigned-big, + $p:8/integer-unit:1-unsigned-big, + $l:8/integer-unit:1-unsigned-big, + $e:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $\f:8/integer-unit:1-unsigned-big, + $l:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\001:8/integer-unit:1-unsigned-big, + $h:8/integer-unit:1-unsigned-big, + $\003:8/integer-unit:1-unsigned-big, + $d:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\003:8/integer-unit:1-unsigned-big, + $v:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $r:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $\f:8/integer-unit:1-unsigned-big, + $d:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\001:8/integer-unit:1-unsigned-big, + $Y:8/integer-unit:1-unsigned-big, + $j:8/integer-unit:1-unsigned-big>>, + <<$\203:8/integer-unit:1-unsigned-big, + $P:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $*:8/integer-unit:1-unsigned-big, + $x:8/integer-unit:1-unsigned-big, + $\234:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $M:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $/:8/integer-unit:1-unsigned-big, + $H:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\005:8/integer-unit:1-unsigned-big, + $R:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\031:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $):8/integer-unit:1-unsigned-big, + $\f:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $e:8/integer-unit:1-unsigned-big, + $\211:8/integer-unit:1-unsigned-big, + $E:8/integer-unit:1-unsigned-big, + $\s:8/integer-unit:1-unsigned-big, + $.:8/integer-unit:1-unsigned-big, + $c:8/integer-unit:1-unsigned-big, + $\004:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $/:8/integer-unit:1-unsigned-big, + $\022:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\205:8/integer-unit:1-unsigned-big, + $\t:8/integer-unit:1-unsigned-big, + $\216:8/integer-unit:1-unsigned-big>>, + <<$\203:8/integer-unit:1-unsigned-big, + $P:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $j:8/integer-unit:1-unsigned-big, + $x:8/integer-unit:1-unsigned-big, + $\234:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $I:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $I:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $+:8/integer-unit:1-unsigned-big, + $N:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\f:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\024:8/integer-unit:1-unsigned-big, + $\006:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\222:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\202:8/integer-unit:1-unsigned-big, + $\234:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $D:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\034:8/integer-unit:1-unsigned-big, + $\006:8/integer-unit:1-unsigned-big, + $\006:8/integer-unit:1-unsigned-big, + $\006:8/integer-unit:1-unsigned-big, + $f:8/integer-unit:1-unsigned-big, + $\220:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $s:8/integer-unit:1-unsigned-big, + $Y:8/integer-unit:1-unsigned-big, + $b:8/integer-unit:1-unsigned-big, + $Q:8/integer-unit:1-unsigned-big, + $":8/integer-unit:1-unsigned-big, + $W:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $\003:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\023:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $/:8/integer-unit:1-unsigned-big, + $\002:8/integer-unit:1-unsigned-big, + $\205:8/integer-unit:1-unsigned-big, + $\027:8/integer-unit:1-unsigned-big, + $\237:8/integer-unit:1-unsigned-big, + $\205:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\227:8/integer-unit:1-unsigned-big, + $\007:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\227:8/integer-unit:1-unsigned-big, + $\021:8/integer-unit:1-unsigned-big, + $.:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\003:8/integer-unit:1-unsigned-big, + $\224:8/integer-unit:1-unsigned-big, + $\217:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\002:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\203:8/integer-unit:1-unsigned-big, + $>:8/integer-unit:1-unsigned-big, + $\034:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big>>} + end, + [{1, + 2, + 2, + {gen, + % fun-info: {4,131674517,'-create_handle/0-fun-4-'} + fun() -> + H1 + end}}, + {2,5,4,fil}, + {3, + 7, + 5, + {gen, + % fun-info: {5,108000324,'-create_handle/0-fun-5-'} + fun() -> + [{0},{1},{2}] + end}}, + {4,10,7,fil}, + {5, + 12, + 8, + {gen, + {join, + '==', + 1, + 3, + % fun-info: {9,59718458,'-create_handle/0-fun-9-'} + fun(H1_0_1) -> + F1_0_1 = + % fun-info: {7,779460,'-create_handle/0-fun-7-'} + fun(_, []) -> + []; + (F1_0_1, [O1_0_1|C1_0_1]) -> + case O1_0_1 of + {_,_,_} + when + 192.0 + =:= + element(1, O1_0_1) -> + [O1_0_1| + % fun-info: {6,23729943,'-create_handle/0-fun-6-'} + fun() -> + F1_0_1(F1_0_1, + C1_0_1) + end]; + _ -> + F1_0_1(F1_0_1, C1_0_1) + end; + (F1_0_1, C1_0_1) + when is_function(C1_0_1) -> + F1_0_1(F1_0_1, C1_0_1()); + (_, C1_0_1) -> + C1_0_1 + end, + % fun-info: {8,43652904,'-create_handle/0-fun-8-'} + fun() -> + F1_0_1(F1_0_1, H1_0_1) + end + end, + % fun-info: {13,102310144,'-create_handle/0-fun-13-'} + fun(H1_0_1) -> + F1_0_1 = + % fun-info: {11,74362432,'-create_handle/0-fun-11-'} + fun(_, []) -> + []; + (F1_0_1, [O1_0_1|C1_0_1]) -> + case O1_0_1 of + {_} -> + [O1_0_1| + % fun-info: {10,23729943,'-create_handle/0-fun-10-'} + fun() -> + F1_0_1(F1_0_1, + C1_0_1) + end]; + _ -> + F1_0_1(F1_0_1, C1_0_1) + end; + (F1_0_1, C1_0_1) + when is_function(C1_0_1) -> + F1_0_1(F1_0_1, C1_0_1()); + (_, C1_0_1) -> + C1_0_1 + end, + % fun-info: {12,43652904,'-create_handle/0-fun-12-'} + fun() -> + F1_0_1(F1_0_1, H1_0_1) + end + end, + % fun-info: {14,17838355,'-create_handle/0-fun-14-'} + fun() -> + {[{1,[192.0]}],[],[]} + end}}}], + % fun-info: {22,31304647,'-create_handle/0-fun-22-'} + fun(join) -> + {[[{1,"\002"},{3,"\001"}]],[]}; + (size) -> + % fun-info: {15,31963143,'-create_handle/0-fun-15-'} + fun(0) -> + 2; + (1) -> + 3; + (3) -> + 1; + (_) -> + undefined + end; + (template) -> + % fun-info: {16,113413274,'-create_handle/0-fun-16-'} + fun({1,2}, '=:=') -> + "\001"; + ({1,2}, '==') -> + "\001\002"; + ({3,1}, '=:=') -> + "\002"; + ({3,1}, '==') -> + "\001\002"; + (_, _) -> + [] + end; + (constants) -> + % fun-info: {18,52148739,'-create_handle/0-fun-18-'} + fun(1) -> + % fun-info: {17,5864387,'-create_handle/0-fun-17-'} + fun(1) -> + {values,[192.0],{some,[2]}}; + (_) -> + false + end; + (_) -> + no_column_fun + end; + (n_leading_constant_columns) -> + % fun-info: {19,82183172,'-create_handle/0-fun-19-'} + fun(1) -> + 1; + (_) -> + 0 + end; + (constant_columns) -> + % fun-info: {20,80910005,'-create_handle/0-fun-20-'} + fun(1) -> + "\001"; + (_) -> + [] + end; + (match_specs) -> + % fun-info: {21,91764346,'-create_handle/0-fun-21-'} + fun(1) -> + {[{{'$1','$2','_'}, + [{'=:=','$1',192.0}], + ['$_']}], + "\002"}; + (_) -> + undefined + end; + (_) -> + undefined + end} + end, + undefined}). + +lookup_handle() -> + E = qlc_SUITE:table([{1,a},{2,b},{3,c}], 1, [1]), + qlc:q({qlc_lc, + % fun-info: {46,120768015,'-lookup_handle/0-fun-22-'} + fun() -> + {qlc_v1, + % fun-info: {26,82970908,'-lookup_handle/0-fun-2-'} + fun(S02_0_1, RL02_0_1, Go02_0_1) -> + Fun2_0_1 = + % fun-info: {25,75235357,'-lookup_handle/0-fun-1-'} + fun(0, RL2_0_1, _, _, _, _, _, _) + when is_list(RL2_0_1) -> + lists:reverse(RL2_0_1); + (0, _, _, _, _, _, _, _) -> + []; + (1, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + C2_1_1, + X2) + when is_list(RL2_0_1) -> + Fun2_0_1(element(1, Go2_0_1), + [{X2,Y2}|RL2_0_1], + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + C2_1_1, + X2); + (1, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + C2_1_1, + X2) -> + [{X2,Y2}| + % fun-info: {24,124255471,'-lookup_handle/0-fun-0-'} + fun() -> + Fun2_0_1(element(1, + Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + C2_1_1, + X2) + end]; + (2, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + _, + X2) -> + Fun2_0_1(3, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + element(4, Go2_0_1), + X2); + (3, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + [{X2,_}|C2_0_1], + _) -> + Fun2_0_1(element(3, Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + C2_0_1, + X2); + (3, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + [_|C2_0_1], + _) -> + Fun2_0_1(3, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + C2_0_1, + []); + (3, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + [], + _) -> + Fun2_0_1(element(2, Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + [], + []); + (3, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + C2_1_1, + _) -> + case C2_1_1() of + [{X2,_}|C2_0_1] -> + Fun2_0_1(element(3, + Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + C2_0_1, + X2); + [_|C2_0_1] -> + Fun2_0_1(3, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + C2_0_1, + []); + [] -> + Fun2_0_1(element(2, + Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + [], + []); + E2_0_1 -> + E2_0_1 + end; + (4, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + _, + Y2, + C2_1_1, + X2) -> + Fun2_0_1(5, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + element(7, Go2_0_1), + Y2, + C2_1_1, + X2); + (5, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + [{Y2}|C2_0_1], + _, + C2_1_1, + X2) -> + Fun2_0_1(element(6, Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_0_1, + Y2, + C2_1_1, + X2); + (5, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + [_|C2_0_1], + _, + C2_1_1, + X2) -> + Fun2_0_1(5, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_0_1, + [], + C2_1_1, + X2); + (5, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + [], + _, + C2_1_1, + X2) -> + Fun2_0_1(element(5, Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + [], + [], + C2_1_1, + X2); + (5, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + _, + C2_1_1, + X2) -> + case C2_2_1() of + [{Y2}|C2_0_1] -> + Fun2_0_1(element(6, + Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_0_1, + Y2, + C2_1_1, + X2); + [_|C2_0_1] -> + Fun2_0_1(5, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_0_1, + [], + C2_1_1, + X2); + [] -> + Fun2_0_1(element(5, + Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + [], + [], + C2_1_1, + X2); + E2_0_1 -> + E2_0_1 + end; + (6, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + C2_1_1, + X2) -> + if + X2 =:= Y2 -> + Fun2_0_1(element(9, + Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + C2_1_1, + X2); + true -> + Fun2_0_1(element(8, + Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + C2_1_1, + X2) + end; + (7, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + _, + X2) -> + Fun2_0_1(8, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + element(12, Go2_0_1), + X2); + (8, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + _, + [[{X2,_}|{Y2}]|C2_0_1], + _) -> + Fun2_0_1(element(11, Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + C2_0_1, + X2); + (8, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + _, + [_|C2_0_1], + _) -> + Fun2_0_1(8, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + [], + C2_0_1, + []); + (8, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + _, + [], + _) -> + Fun2_0_1(element(10, Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + [], + [], + []); + (8, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + _, + C2_1_1, + _) -> + case C2_1_1() of + [[{X2,_}|{Y2}]|C2_0_1] -> + Fun2_0_1(element(11, + Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + C2_0_1, + X2); + [_|C2_0_1] -> + Fun2_0_1(8, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + [], + C2_0_1, + []); + [] -> + Fun2_0_1(element(10, + Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + [], + [], + []); + E2_0_1 -> + E2_0_1 + end + end, + Fun2_0_1(S02_0_1, + RL02_0_1, + Fun2_0_1, + Go02_0_1, + [], + [], + [], + []) + end, + % fun-info: {27,111349661,'-lookup_handle/0-fun-3-'} + fun() -> + {<<$\203:8/integer-unit:1-unsigned-big, + $P:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $.:8/integer-unit:1-unsigned-big, + $x:8/integer-unit:1-unsigned-big, + $\234:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $N:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $-:8/integer-unit:1-unsigned-big, + $):8/integer-unit:1-unsigned-big, + $-:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $I:8/integer-unit:1-unsigned-big, + $M:8/integer-unit:1-unsigned-big, + $\024:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $0:8/integer-unit:1-unsigned-big, + $\227:8/integer-unit:1-unsigned-big, + $%:8/integer-unit:1-unsigned-big, + $\026:8/integer-unit:1-unsigned-big, + $%:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $0:8/integer-unit:1-unsigned-big, + $0:8/integer-unit:1-unsigned-big, + $F:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $":8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\206:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big>>, + <<$\203:8/integer-unit:1-unsigned-big, + $P:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $.:8/integer-unit:1-unsigned-big, + $x:8/integer-unit:1-unsigned-big, + $\234:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $N:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $-:8/integer-unit:1-unsigned-big, + $):8/integer-unit:1-unsigned-big, + $-:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $I:8/integer-unit:1-unsigned-big, + $M:8/integer-unit:1-unsigned-big, + $\024:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $0:8/integer-unit:1-unsigned-big, + $\227:8/integer-unit:1-unsigned-big, + $%:8/integer-unit:1-unsigned-big, + $\026:8/integer-unit:1-unsigned-big, + $%:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $0:8/integer-unit:1-unsigned-big, + $0:8/integer-unit:1-unsigned-big, + $F:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\222:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big>>, + <<$\203:8/integer-unit:1-unsigned-big, + $h:8/integer-unit:1-unsigned-big, + $\003:8/integer-unit:1-unsigned-big, + $d:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\005:8/integer-unit:1-unsigned-big, + $t:8/integer-unit:1-unsigned-big, + $u:8/integer-unit:1-unsigned-big, + $p:8/integer-unit:1-unsigned-big, + $l:8/integer-unit:1-unsigned-big, + $e:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $\022:8/integer-unit:1-unsigned-big, + $l:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\001:8/integer-unit:1-unsigned-big, + $h:8/integer-unit:1-unsigned-big, + $\003:8/integer-unit:1-unsigned-big, + $d:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\003:8/integer-unit:1-unsigned-big, + $v:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $r:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $\022:8/integer-unit:1-unsigned-big, + $d:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\001:8/integer-unit:1-unsigned-big, + $Y:8/integer-unit:1-unsigned-big, + $j:8/integer-unit:1-unsigned-big>>, + <<$\203:8/integer-unit:1-unsigned-big, + $P:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $+:8/integer-unit:1-unsigned-big, + $x:8/integer-unit:1-unsigned-big, + $\234:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $M:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $/:8/integer-unit:1-unsigned-big, + $H:8/integer-unit:1-unsigned-big, + $\024:8/integer-unit:1-unsigned-big, + $N:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $\006:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $e:8/integer-unit:1-unsigned-big, + $\211:8/integer-unit:1-unsigned-big, + $E:8/integer-unit:1-unsigned-big, + $\s:8/integer-unit:1-unsigned-big, + $>:8/integer-unit:1-unsigned-big, + $c:8/integer-unit:1-unsigned-big, + $\004:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $/:8/integer-unit:1-unsigned-big, + $\022:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\227:8/integer-unit:1-unsigned-big, + $\t:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big>>, + <<$\203:8/integer-unit:1-unsigned-big, + $P:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\\:8/integer-unit:1-unsigned-big, + $x:8/integer-unit:1-unsigned-big, + $\234:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $I:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $I:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $+:8/integer-unit:1-unsigned-big, + $N:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\f:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\024:8/integer-unit:1-unsigned-big, + $\006:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\222:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\202:8/integer-unit:1-unsigned-big, + $\234:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $D:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\034:8/integer-unit:1-unsigned-big, + $\006:8/integer-unit:1-unsigned-big, + $\006:8/integer-unit:1-unsigned-big, + $\006:8/integer-unit:1-unsigned-big, + $&:8/integer-unit:1-unsigned-big, + $\220:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $s:8/integer-unit:1-unsigned-big, + $Y:8/integer-unit:1-unsigned-big, + $b:8/integer-unit:1-unsigned-big, + $Q:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $\003:8/integer-unit:1-unsigned-big, + $c:8/integer-unit:1-unsigned-big, + $\004:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $/:8/integer-unit:1-unsigned-big, + $>:8/integer-unit:1-unsigned-big, + $\v:8/integer-unit:1-unsigned-big, + $I:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\020:8/integer-unit:1-unsigned-big, + $H:8/integer-unit:1-unsigned-big, + $5:8/integer-unit:1-unsigned-big, + $#:8/integer-unit:1-unsigned-big, + $\\:8/integer-unit:1-unsigned-big, + $^:8/integer-unit:1-unsigned-big, + $\b:8/integer-unit:1-unsigned-big, + $(:8/integer-unit:1-unsigned-big, + $\037:8/integer-unit:1-unsigned-big, + $\231:8/integer-unit:1-unsigned-big, + $\005:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\024:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\031:8/integer-unit:1-unsigned-big, + $M:8/integer-unit:1-unsigned-big>>} + end, + [{1, + 2, + 2, + {gen, + % fun-info: {28,75197307,'-lookup_handle/0-fun-4-'} + fun() -> + E + end}}, + {2, + 5, + 4, + {gen, + % fun-info: {29,86826511,'-lookup_handle/0-fun-5-'} + fun() -> + [{0},{1},{2}] + end}}, + {3,8,6,fil}, + {4, + 10, + 7, + {gen, + {join, + '==', + 1, + 2, + % fun-info: {33,129609919,'-lookup_handle/0-fun-9-'} + fun(H2_0_1) -> + F2_0_1 = + % fun-info: {31,45768082,'-lookup_handle/0-fun-7-'} + fun(_, []) -> + []; + (F2_0_1, [O2_0_1|C2_0_1]) -> + case O2_0_1 of + {_,_} -> + [O2_0_1| + % fun-info: {30,28136696,'-lookup_handle/0-fun-6-'} + fun() -> + F2_0_1(F2_0_1, + C2_0_1) + end]; + _ -> + F2_0_1(F2_0_1, C2_0_1) + end; + (F2_0_1, C2_0_1) + when is_function(C2_0_1) -> + F2_0_1(F2_0_1, C2_0_1()); + (_, C2_0_1) -> + C2_0_1 + end, + % fun-info: {32,48059625,'-lookup_handle/0-fun-8-'} + fun() -> + F2_0_1(F2_0_1, H2_0_1) + end + end, + % fun-info: {37,63676968,'-lookup_handle/0-fun-13-'} + fun(H2_0_1) -> + F2_0_1 = + % fun-info: {35,129320532,'-lookup_handle/0-fun-11-'} + fun(_, []) -> + []; + (F2_0_1, [O2_0_1|C2_0_1]) -> + case O2_0_1 of + {_} -> + [O2_0_1| + % fun-info: {34,28136696,'-lookup_handle/0-fun-10-'} + fun() -> + F2_0_1(F2_0_1, + C2_0_1) + end]; + _ -> + F2_0_1(F2_0_1, C2_0_1) + end; + (F2_0_1, C2_0_1) + when is_function(C2_0_1) -> + F2_0_1(F2_0_1, C2_0_1()); + (_, C2_0_1) -> + C2_0_1 + end, + % fun-info: {36,48059625,'-lookup_handle/0-fun-12-'} + fun() -> + F2_0_1(F2_0_1, H2_0_1) + end + end, + % fun-info: {38,3236543,'-lookup_handle/0-fun-14-'} + fun() -> + {[],[],[]} + end}}}], + % fun-info: {45,56361026,'-lookup_handle/0-fun-21-'} + fun(join) -> + [[{1,"\001"},{2,"\001"}]]; + (size) -> + % fun-info: {39,40607542,'-lookup_handle/0-fun-15-'} + fun(0) -> + 2; + (1) -> + 2; + (2) -> + 1; + (_) -> + undefined + end; + (template) -> + % fun-info: {40,34907048,'-lookup_handle/0-fun-16-'} + fun({1,1}, _) -> + "\001\002"; + ({2,1}, _) -> + "\001\002"; + (_, _) -> + [] + end; + (constants) -> + % fun-info: {41,11686091,'-lookup_handle/0-fun-17-'} + fun(_) -> + no_column_fun + end; + (n_leading_constant_columns) -> + % fun-info: {42,21492441,'-lookup_handle/0-fun-18-'} + fun(_) -> + 0 + end; + (constant_columns) -> + % fun-info: {43,55297177,'-lookup_handle/0-fun-19-'} + fun(_) -> + [] + end; + (match_specs) -> + % fun-info: {44,55081557,'-lookup_handle/0-fun-20-'} + fun(_) -> + undefined + end; + (_) -> + undefined + end} + end, + undefined}). diff --git a/lib/stdlib/test/stdlib_SUITE.erl b/lib/stdlib/test/stdlib_SUITE.erl index 0cca030b3d..8a2cb5ea6b 100644 --- a/lib/stdlib/test/stdlib_SUITE.erl +++ b/lib/stdlib/test/stdlib_SUITE.erl @@ -33,8 +33,7 @@ -export([init_per_testcase/2, end_per_testcase/2]). % Test cases must be exported. --export([app_test/1]). --define(cases, [app_test]). +-export([app_test/1, appup_test/1]). %% %% all/1 @@ -42,7 +41,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> - [app_test]. + [app_test, appup_test]. groups() -> []. @@ -79,3 +78,61 @@ app_test(Config) when is_list(Config) -> ?t:app_test(stdlib), ok. +%% Test that appup allows upgrade from/downgrade to a maximum of two +%% major releases back. +appup_test(_Config) -> + application:load(stdlib), + {_,_,Vsn} = lists:keyfind(stdlib,1,application:loaded_applications()), + AppupFile = filename:join([code:lib_dir(stdlib),ebin,"stdlib.appup"]), + {ok,[{Vsn,UpFrom,DownTo}=AppupScript]} = file:consult(AppupFile), + ct:log("~p~n",[AppupScript]), + {OkVsns,NokVsns} = create_test_vsns(Vsn), + check_appup(OkVsns,UpFrom,{ok,[restart_new_emulator]}), + check_appup(OkVsns,DownTo,{ok,[restart_new_emulator]}), + check_appup(NokVsns,UpFrom,error), + check_appup(NokVsns,DownTo,error), + ok. + +create_test_vsns(Current) -> + [XStr,YStr|Rest] = string:tokens(Current,"."), + X = list_to_integer(XStr), + Y = list_to_integer(YStr), + SecondMajor = vsn(X,Y-2), + SecondMinor = SecondMajor ++ ".1.3", + FirstMajor = vsn(X,Y-1), + FirstMinor = FirstMajor ++ ".57", + ThisMajor = vsn(X,Y), + This = + case Rest of + [] -> + []; + ["1"] -> + [ThisMajor]; + _ -> + ThisMinor = ThisMajor ++ ".1", + [ThisMajor,ThisMinor] + end, + OkVsns = This ++ [FirstMajor, FirstMinor, SecondMajor, SecondMinor], + + ThirdMajor = vsn(X,Y-3), + ThirdMinor = ThirdMajor ++ ".10.12", + Illegal = ThisMajor ++ ",1", + Newer1Major = vsn(X,Y+1), + Newer1Minor = Newer1Major ++ ".1", + Newer2Major = ThisMajor ++ "1", + NokVsns = [ThirdMajor,ThirdMinor, + Illegal, + Newer1Major,Newer1Minor, + Newer2Major], + {OkVsns,NokVsns}. + +vsn(X,Y) -> + integer_to_list(X) ++ "." ++ integer_to_list(Y). + +check_appup([Vsn|Vsns],Instrs,Expected) -> + case systools_relup:appup_search_for_version(Vsn, Instrs) of + Expected -> check_appup(Vsns,Instrs,Expected); + Other -> ct:fail({unexpected_result_for_vsn,Vsn,Other}) + end; +check_appup([],_,_) -> + ok. diff --git a/lib/stdlib/test/tar_SUITE.erl b/lib/stdlib/test/tar_SUITE.erl index 9ad3936928..5bc34e35af 100644 --- a/lib/stdlib/test/tar_SUITE.erl +++ b/lib/stdlib/test/tar_SUITE.erl @@ -533,7 +533,7 @@ symlinks(Config) when is_list(Config) -> ?line ok = file:make_dir(Dir), ?line ABadSymlink = filename:join(Dir, "bad_symlink"), ?line PointsTo = "/a/definitely/non_existing/path", - ?line Res = case file:make_symlink("/a/definitely/non_existing/path", ABadSymlink) of + ?line Res = case make_symlink("/a/definitely/non_existing/path", ABadSymlink) of {error, enotsup} -> {skip, "Symbolic links not supported on this platform"}; ok -> @@ -544,7 +544,30 @@ symlinks(Config) when is_list(Config) -> %% Clean up. ?line delete_files([Dir]), Res. - + +make_symlink(Path, Link) -> + case os:type() of + {win32,_} -> + %% Symlinks on Windows have two problems: + %% 1) file:read_link_info/1 cannot read out the target + %% of the symlink if the target does not exist. + %% That is possible (but not easy) to fix in the + %% efile driver. + %% + %% 2) Symlinks to files and directories are different + %% creatures. If the target is not existing, the + %% symlink will be created to be of the file-pointing + %% type. That can be partially worked around in erl_tar + %% by creating all symlinks when the end of the tar + %% file has been reached. + %% + %% But for now, pretend that there are no symlinks on + %% Windows. + {error, enotsup}; + _ -> + file:make_symlink(Path, Link) + end. + symlinks(Dir, BadSymlink, PointsTo) -> ?line Tar = filename:join(Dir, "symlink.tar"), ?line DerefTar = filename:join(Dir, "dereference.tar"), @@ -743,9 +766,9 @@ run_in_short_tempdir(Config, Fun) -> %% We need a base directory with a much shorter pathname than %% priv_dir. We KNOW that priv_dir is located four levels below %% the directory that common_test puts the ct_run.* directories - %% in. That fact is not documented, but an usually reliable source + %% in. That fact is not documented, but a usually reliable source %% assured me that the directory structure is unlikely to change - %% in future versions of common_test because of backward + %% in future versions of common_test because of backwards %% compatibility (tools developed by users of common_test depend %% on the current directory layout). Base = lists:foldl(fun(_, D) -> diff --git a/lib/test_server/doc/src/test_server.xml b/lib/test_server/doc/src/test_server.xml index 78bb922cc5..5bfa42c36f 100644 --- a/lib/test_server/doc/src/test_server.xml +++ b/lib/test_server/doc/src/test_server.xml @@ -203,7 +203,7 @@ <func> <name>format(Format) -> ok</name> <name>format(Format, Args)</name> - <name>format(Pri,Format)</name> + <name>format(Pri, Format)</name> <name>format(Pri, Format, Args)</name> <fsummary></fsummary> <type> diff --git a/lib/test_server/src/config.guess b/lib/test_server/src/config.guess index 6f1eeddfcc..38a833903b 120000..100755 --- a/lib/test_server/src/config.guess +++ b/lib/test_server/src/config.guess @@ -1 +1,1519 @@ -../../../erts/autoconf/config.guess
\ No newline at end of file +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, +# Inc. + +timestamp='2007-05-17' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner <[email protected]>. +# Please send patches to <[email protected]>. Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <[email protected]>." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# ([email protected] 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # [email protected] (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:SunOS:5.*:* | ix86xen:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include <stdio.h> /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <sys/systemcfg.h> + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include <stdlib.h> + #include <unistd.h> + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <unistd.h> + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:[3456]*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + EM64T | authenticamd) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + tile:Linux:*:*) + echo tile-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + xtensa:Linux:*:*) + echo xtensa-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <features.h> + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^LIBC/{ + s: ::g + p + }'`" + test x"${LIBC}" != x && { + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit + } + test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` + echo ${UNAME_MACHINE}-pc-isc$UNAME_REL + elif /bin/uname -X 2>/dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says <[email protected]> + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes <[email protected]>. + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From [email protected]. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From [email protected]. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From [email protected]. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c <<EOF +#ifdef _SEQUENT_ +# include <sys/types.h> +# include <sys/utsname.h> +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include <sys/param.h> + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include <sys/param.h> +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 <<EOF +$0: unable to guess system type + +This script, last modified $timestamp, has failed to recognize +the operating system you are using. It is advised that you +download the most up to date version of the config scripts from + + http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess +and + http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub + +If the version you run ($0) is already up to date, please +send the following data and any information you think might be +pertinent to <[email protected]> in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/lib/test_server/src/config.sub b/lib/test_server/src/config.sub index 47a0f10138..f43233b104 120000..100755 --- a/lib/test_server/src/config.sub +++ b/lib/test_server/src/config.sub @@ -1 +1,1630 @@ -../../../erts/autoconf/config.sub
\ No newline at end of file +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, +# Inc. + +timestamp='2007-04-29' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to <[email protected]>. Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <[email protected]>." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | mt \ + | msp430 \ + | nios | nios2 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | score \ + | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16c) + basic_machine=cr16c-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + tile*) + basic_machine=tile-tilera + os=-linux-gnu + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/lib/test_server/src/erl2html2.erl b/lib/test_server/src/erl2html2.erl index c94d4627f9..e2fd951d9e 100644 --- a/lib/test_server/src/erl2html2.erl +++ b/lib/test_server/src/erl2html2.erl @@ -32,32 +32,34 @@ %-------------------------------------------------------------------- -module(erl2html2). --export([convert/2]). +-export([convert/2, convert/3]). convert([], _Dest) -> % Fake clause. ok; convert(File, Dest) -> + %% The generated code uses the BGCOLOR attribute in the + %% BODY tag, which wasn't valid until HTML 3.2. Also, + %% good HTML should either override all colour attributes + %% or none of them -- *never* just a few. + %% + %% FIXME: The colours should *really* be set with + %% stylesheets... + Header = ["<!DOCTYPE HTML PUBLIC " + "\"-//W3C//DTD HTML 3.2 Final//EN\">\n" + "<!-- autogenerated by '"++atom_to_list(?MODULE)++"'. -->\n" + "<html>\n" + "<head><title>", File, "</title></head>\n\n" + "<body bgcolor=\"white\" text=\"black\"" + " link=\"blue\" vlink=\"purple\" alink=\"red\">\n"], + convert(File, Dest, Header). + +convert(File, Dest, Header) -> case file:read_file(File) of {ok, Bin} -> Code=binary_to_list(Bin), statistics(runtime), - %% The generated code uses the BGCOLOR attribute in the - %% BODY tag, which wasn't valid until HTML 3.2. Also, - %% good HTML should either override all colour attributes - %% or none of them -- *never* just a few. - %% - %% FIXME: The colours should *really* be set with - %% stylesheets... - Html0 - = ["<!DOCTYPE HTML PUBLIC " - "\"-//W3C//DTD HTML 3.2 Final//EN\">\n" - "<!-- autogenerated by '"++atom_to_list(?MODULE)++"'. -->\n" - "<html>\n" - "<head><title>", File, "</title></head>\n\n" - "<body bgcolor=\"white\" text=\"black\"" - " link=\"blue\" vlink=\"purple\" alink=\"red\">\n"], {Html1, Lines} = root(Code, [], 1), - Html = [Html0, + Html = [Header, "<pre>\n", Html1, "</pre>\n", footer(Lines),"</body>\n</html>\n"], file:write_file(Dest, Html); @@ -173,10 +175,11 @@ linenum(Line) -> end, [A,Pred,integer_to_list(Line),":"]. -footer(Lines) -> - {_, Time} = statistics(runtime), -% io:format("Converted ~p lines in ~.2f Seconds.~n", -% [Lines, Time/1000]), - S = "<i>The transformation of this file (~p lines) took ~.2f seconds</i>", - F = lists:flatten(io_lib:format(S, [Lines, Time/1000])), - ["<hr size=1>",F,"<br>\n"]. +footer(_Lines) -> + "". +%% {_, Time} = statistics(runtime), +%% io:format("Converted ~p lines in ~.2f Seconds.~n", +%% [Lines, Time/1000]), +%% S = "<i>The transformation of this file (~p lines) took ~.2f seconds</i>", +%% F = lists:flatten(io_lib:format(S, [Lines, Time/1000])), +%% ["<hr size=1>",F,"<br>\n"]. diff --git a/lib/test_server/src/install-sh b/lib/test_server/src/install-sh index a859cade7f..a5897de6ea 120000..100755 --- a/lib/test_server/src/install-sh +++ b/lib/test_server/src/install-sh @@ -1 +1,519 @@ -../../../erts/autoconf/install-sh
\ No newline at end of file +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2006-12-25.00 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + trap '(exit $?); exit' 1 2 13 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dst_arg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + -*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test -z "$d" && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/lib/test_server/src/test_server.erl b/lib/test_server/src/test_server.erl index 49f97686a0..98a2e21e21 100644 --- a/lib/test_server/src/test_server.erl +++ b/lib/test_server/src/test_server.erl @@ -611,6 +611,7 @@ do_run_test_case_apply(Mod, Func, Args, Name, RunInit, TimetrapData) -> print(minor, "Test case started with:\n~s:~s(~p)\n", [Mod,Func,Args2Print]), print(minor, "Current directory is ~p\n", [Cwd]), print_timestamp(minor,"Started at "), + print(minor, "", [], internal_raw), TCCallback = get(test_server_testcase_callback), LogOpts = get(test_server_logopts), Ref = make_ref(), @@ -1006,8 +1007,11 @@ spawn_fw_call(Mod,{end_per_testcase,Func},EndConf,Pid, end, %% if end_per_testcase fails a warning should be %% printed as comment - Comment1 = if Comment == "" -> ""; - true -> Comment ++ "<br>" + Comment1 = if Comment == "" -> + ""; + true -> + Comment ++ test_server_ctrl:xhtml("<br>", + "<br />") end, %% finished, report back SendTo ! {self(),fw_notify_done, @@ -1472,7 +1476,8 @@ do_end_per_testcase(Mod,EndFunc,Func,Conf) -> throw:Other -> Comment0 = case read_comment() of "" -> ""; - Cmt -> Cmt ++ "<br>" + Cmt -> Cmt ++ test_server_ctrl:xhtml("<br>", + "<br />") end, set_loc(erlang:get_stacktrace()), comment(io_lib:format("~s<font color=\"red\">" @@ -1495,7 +1500,8 @@ do_end_per_testcase(Mod,EndFunc,Func,Conf) -> end, Comment0 = case read_comment() of "" -> ""; - Cmt -> Cmt ++ "<br>" + Cmt -> Cmt ++ test_server_ctrl:xhtml("<br>", + "<br />") end, comment(io_lib:format("~s<font color=\"red\">" "WARNING: ~w crashed!" @@ -1525,7 +1531,7 @@ get_loc(Pid) -> get_mf(MFs) -> get_mf(MFs, {undefined,undefined}). -get_mf([MF|MFs], Found) when is_tuple(MF) -> +get_mf([MF|MFs], _Found) when is_tuple(MF) -> ModFunc = {Mod,_} = case MF of {M,F,_} -> {M,F}; MF -> MF @@ -1571,7 +1577,7 @@ fw_error_notify(Mod, Func, Args, Error, Loc) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% print(Detail,Format,Args) -> ok +%% print(Detail,Format,Args,Printer) -> ok %% Detail = integer() %% Format = string() %% Args = [term()] @@ -1582,6 +1588,9 @@ fw_error_notify(Mod, Func, Args, Error, Loc) -> print(Detail,Format,Args) -> local_or_remote_apply({test_server_ctrl,print,[Detail,Format,Args]}). +print(Detail,Format,Args,Printer) -> + local_or_remote_apply({test_server_ctrl,print,[Detail,Format,Args,Printer]}). + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% print_timsteamp(Detail,Leader) -> ok %% diff --git a/lib/test_server/src/test_server_ctrl.erl b/lib/test_server/src/test_server_ctrl.erl index 4fad86d16d..70422adccd 100644 --- a/lib/test_server/src/test_server_ctrl.erl +++ b/lib/test_server/src/test_server_ctrl.erl @@ -171,7 +171,7 @@ -export([kill_slavenodes/0]). %%% TEST_SERVER INTERFACE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export([output/2, print/2, print/3, print_timestamp/2]). +-export([output/2, print/2, print/3, print/4, print_timestamp/2]). -export([start_node/3, stop_node/1, wait_for_node/1, is_release_available/1]). -export([format/1, format/2, format/3, to_string/1]). -export([get_target_info/0]). @@ -187,6 +187,7 @@ -export([handle_call/3, handle_cast/2, handle_info/2]). -export([do_test_cases/4]). -export([do_spec/2, do_spec_list/2]). +-export([xhtml/2]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -214,6 +215,9 @@ X == auto_skip -> skipped; true -> X end). +-define(auto_skip_color, "#FFA64D"). +-define(user_skip_color, "#FF8000"). + -record(state,{jobs=[],levels={1,19,10}, multiply_timetraps=1,scale_timetraps=true, finish=false, @@ -1668,7 +1672,7 @@ do_test_cases(TopCases, SkipCases, do_test_cases(TopCases, SkipCases, Config, TimetrapData) when is_list(TopCases), is_tuple(TimetrapData) -> - start_log_file(), + {ok,TestDir} = start_log_file(), FwMod = case os:getenv("TEST_SERVER_FRAMEWORK") of FW when FW =:= false; FW =:= "undefined" -> ?MODULE; @@ -1692,60 +1696,86 @@ do_test_cases(TopCases, SkipCases, [print_if_known(N, {", ~w test cases",[N]}, {" (with repeated test cases)",[]})]), Test = get(test_server_name), - test_server_sup:framework_call(report, [tests_start,{Test,N}]), + TestName = if is_list(Test) -> + lists:flatten(io_lib:format("~s", [Test])); + true -> + lists:flatten(io_lib:format("~p", [Test])) + end, + TestDescr = "Test " ++ TestName ++ " results", - Header = - case test_server_sup:framework_call(overview_html_header, [Test], "") of - "" -> - TestName = lists:flatten(io_lib:format("~p", [Test])), - ["<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n", - "<!-- autogenerated by '", atom_to_list(?MODULE), "'. -->\n", - "<html>\n", - "<head><title>Test ", TestName, " results</title>\n", - "<meta http-equiv=\"cache-control\" content=\"no-cache\">\n", - "</head>\n", - "<body bgcolor=\"white\" text=\"black\" ", - "link=\"blue\" vlink=\"purple\" alink=\"red\">", - "<h2>Results from test ", TestName, "</h2>\n"]; - Html -> - ["<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n", - "<!-- autogenerated by '", atom_to_list(?MODULE), "'. -->\n" | Html] + test_server_sup:framework_call(report, [tests_start,{Test,N}]), + {Header,Footer} = + case test_server_sup:framework_call(get_html_wrapper, + [TestDescr,true,TestDir], "") of + Empty when (Empty == "") ; (element(2,Empty) == "") -> + put(basic_html, true), + {["<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n", + "<!-- autogenerated by '", atom_to_list(?MODULE), "'. -->\n", + "<html>\n", + "<head><title>", TestDescr, "</title>\n", + "<meta http-equiv=\"cache-control\" content=\"no-cache\">\n", + "</head>\n", + "<body bgcolor=\"white\" text=\"black\" ", + "link=\"blue\" vlink=\"purple\" alink=\"red\">", + "<h2>Results for test ", TestName, "</h2>\n"], + "\n</body>\n</html>\n"}; + {basic_html,Html0,Html1} -> + put(basic_html, true), + {Html0++["<h1>Results for <i>",TestName,"</i></h1>\n"], + Html1}; + {xhtml,Html0,Html1} -> + put(basic_html, false), + {Html0++["<h1>Results for <i>",TestName,"</i></h1>\n"], + Html1} end, - print(html, Header, []), - print_timestamp(html, "Test started at "), - print(html, "<p>Host:<br>\n"), + print(html, Header), + + print(html, xhtml("<p>", "<h4>")), + print_timestamp(html, "Test started at "), + print(html, xhtml("</p>", "</h4>")), + + print(html, xhtml("\n<p><b>Host info:</b><br>\n", + "\n<p><b>Host info:</b><br />\n")), print_who(test_server_sup:hoststr(), test_server_sup:get_username()), - print(html, "<br>Used Erlang ~s in <tt>~s</tt>.\n", + print(html, xhtml("<br>Used Erlang v~s in <tt>~s</tt></p>\n", + "<br />Used Erlang v~s in \"~s\"</p>\n"), [erlang:system_info(version), code:root_dir()]), - + if FwMod == ?MODULE -> - print(html, "<p>Target:<br>\n"), + print(html, xhtml("\n<p><b>Target Info:</b><br>\n", + "\n<p><b>Target Info:</b><br />\n")), print_who(TI#target_info.host, TI#target_info.username), - print(html, "<br>Used Erlang ~s in <tt>~s</tt>.\n", + print(html, xhtml("<br>Used Erlang v~s in <tt>~s</tt></p>\n", + "<br />Used Erlang v~s in \"~s\"</p>\n"), [TI#target_info.version, TI#target_info.root_dir]); - true -> + true -> case test_server_sup:framework_call(target_info, []) of TargetInfo when is_list(TargetInfo), length(TargetInfo) > 0 -> - print(html, "<p>Target:<br>\n"), - print(html, "~s\n", [TargetInfo]); + print(html, xhtml("\n<p><b>Target info:</b><br>\n", + "\n<p><b>Target info:</b><br />\n")), + print(html, "~s</p>\n", [TargetInfo]); _ -> ok end end, - + print(html, - "<p><a href=\"~s\">Full textual log</a>\n" - "<br><a href=\"~s\">Coverage log</a>\n", + "<p><ul>\n" + "<li><a href=\"~s\">Full textual log</a></li>\n" + "<li><a href=\"~s\">Coverage log</a></li>\n</ul></p>\n", [?suitelog_name,?coverlog_name]), - print(html,"<p>~s" - "<p>\n" - "<table bgcolor=\"white\" border=\"3\" cellpadding=\"5\">" - "<tr><th>Num</th><th>Module</th><th>Case</th><th>Log</th>" - "<th>Time</th><th>Result</th><th>Comment</th></tr>\n", - [print_if_known(N, {"Suite contains ~p test cases.\n",[N]}, + print(html, + "<p>~s</p>\n" ++ + xhtml("<table bgcolor=\"white\" border=\"3\" cellpadding=\"5\">", + "<table>") ++ + "<tr><th>Num</th><th>Module</th><th>Case</th><th>Log</th>" + "<th>Time</th><th>Result</th><th>Comment</th></tr>\n", + [print_if_known(N, {"<i>Executing <b>~p</b> test cases...</i>\n",[N]}, {"",[]})]), + print(html, xhtml("<br>", "<br />")), + print(major, "=cases ~p", [get(test_server_cases)]), print(major, "=user ~s", [TI#target_info.username]), print(major, "=host ~s", [TI#target_info.host]), @@ -1764,6 +1794,9 @@ do_test_cases(TopCases, SkipCases, print(major, "=otp_release ~s", [TI#target_info.otp_release]), print(major, "=started ~s", [lists:flatten(timestamp_get(""))]), + + put(test_server_html_footer, Footer), + run_test_cases(TestSpec, Config, TimetrapData) end; @@ -1773,7 +1806,7 @@ do_test_cases(TopCase, SkipCases, Config, TimetrapSpec) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% start_log_file() -> ok | exit({Error,Reason}) +%% start_log_file() -> {ok,TestDirName} | exit({Error,Reason}) %% Stem = string() %% %% Creates the log directories, the major log file and the html log file. @@ -1824,7 +1857,7 @@ start_log_file() -> LogInfo = [{topdir,Dir},{rundir,lists:flatten(TestDir)}], test_server_sup:framework_call(report, [loginfo,LogInfo]), - ok. + {ok,TestDir}. make_html_link(LinkName, Target, Explanation) -> %% if possible use a relative reference to Target. @@ -1881,16 +1914,32 @@ start_minor_log_file1(Mod, Func, LogDir, AbsName) -> {ok,Fd} = file:open(AbsName, [write]), Lev = get(test_server_minor_level)+1000, %% far down in the minor levels put(test_server_minor_fd, Fd), - io:fwrite(Fd, - "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n" - "<!-- autogenerated by '"++atom_to_list(?MODULE)++"'. -->\n" - "<html>\n" - "<head><title>"++cast_to_list(Mod)++"</title>\n" - "<meta http-equiv=\"cache-control\" content=\"no-cache\">\n" - "</head>\n" - "<body bgcolor=\"white\" text=\"black\"" - " link=\"blue\" vlink=\"purple\" alink=\"red\">\n", - []), + + TestDescr = io_lib:format("Test ~p:~p result", [Mod,Func]), + {Header,Footer} = + case test_server_sup:framework_call(get_html_wrapper, + [TestDescr,false, + filename:dirname(AbsName)], "") of + Empty when (Empty == "") ; (element(2,Empty) == "") -> + put(basic_html, true), + {["<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n", + "<!-- autogenerated by '", atom_to_list(?MODULE), "'. -->\n", + "<html>\n", + "<head><title>", TestDescr, "</title>\n", + "<meta http-equiv=\"cache-control\" content=\"no-cache\">\n", + "</head>\n", + "<body bgcolor=\"white\" text=\"black\" ", + "link=\"blue\" vlink=\"purple\" alink=\"red\">\n"], + "\n</body>\n</html>\n"}; + {basic_html,Html0,Html1} -> + put(basic_html, true), + {Html0,Html1}; + {xhtml,Html0,Html1} -> + put(basic_html, false), + {Html0,Html1} + end, + put(test_server_minor_footer, Footer), + io:fwrite(Fd, Header, []), SrcListing = downcase(cast_to_list(Mod)) ++ ?src_listing_ext, case {filelib:is_file(filename:join(LogDir, SrcListing)), @@ -1913,7 +1962,8 @@ start_minor_log_file1(Mod, Func, LogDir, AbsName) -> stop_minor_log_file() -> Fd = get(test_server_minor_fd), - io:fwrite(Fd, "</pre>\n</body>\n</html>\n", []), + Footer = get(test_server_minor_footer), + io:fwrite(Fd, "</pre>\n" ++ Footer, []), file:close(Fd), put(test_server_minor_fd, undefined). @@ -1992,12 +2042,29 @@ html_convert_modules([]) -> ok. %% Convert source code to HTML if possible and needed. html_possibly_convert(Src, SrcInfo, Dest) -> case file:read_file_info(Dest) of - {error,_Reason} -> % no dest file - erl2html2:convert(Src, Dest); - {ok,DestInfo} when DestInfo#file_info.mtime < SrcInfo#file_info.mtime -> - erl2html2:convert(Src, Dest); - {ok,_DestInfo} -> - ok % dest file up to date + {ok,DestInfo} when DestInfo#file_info.mtime >= SrcInfo#file_info.mtime -> + ok; % dest file up to date + _ -> + OutDir = get(test_server_log_dir_base), + Header = + case test_server_sup:framework_call(get_html_wrapper, + ["Module "++Src,false, + OutDir], "") of + Empty when (Empty == "") ; (element(2,Empty) == "") -> + ["<!DOCTYPE HTML PUBLIC", + "\"-//W3C//DTD HTML 3.2 Final//EN\">\n", + "<!-- autogenerated by 'erl2html2' -->\n", + "<html>\n", + "<head><title>Module ", Src, "</title>\n", + "<meta http-equiv=\"cache-control\" ", + "content=\"no-cache\">\n", + "</head>\n", + "<body bgcolor=\"white\" text=\"black\" ", + "link=\"blue\" vlink=\"purple\" alink=\"red\">\n"]; + {_,Html,_} -> + Html + end, + erl2html2:convert(Src, Dest, Header) end. %% Copy all HTML files in InDir to OutDir. @@ -3153,8 +3220,8 @@ skip_case(Type, Ref, CaseNum, Case, Comment, SendSync, Mode) -> skip_case1(Type, CaseNum, Mod, Func, Comment, Mode) -> {{Col0,Col1},_} = get_font_style((CaseNum > 0), Mode), - ResultCol = if Type == auto -> "#ffcc99"; - Type == user -> "#ff9933" + ResultCol = if Type == auto -> ?auto_skip_color; + Type == user -> ?user_skip_color end, Comment1 = reason_to_string(Comment), @@ -3163,9 +3230,9 @@ skip_case1(Type, CaseNum, Mod, Func, Comment, Mode) -> print(major, "=started ~s", [lists:flatten(timestamp_get(""))]), print(major, "=result skipped: ~s", [Comment1]), print(2,"*** Skipping test case #~w ~p ***", [CaseNum,{Mod,Func}]), + TR = xhtml("<tr valign=\"top\">", ["<tr class=\"",odd_or_even(),"\">"]), print(html, - "<tr valign=top>" - "<td>" ++ Col0 ++ "~s" ++ Col1 ++ "</td>" + TR ++ "<td>" ++ Col0 ++ "~s" ++ Col1 ++ "</td>" "<td>" ++ Col0 ++ "~p" ++ Col1 ++ "</td>" "<td>" ++ Col0 ++ "~p" ++ Col1 ++ "</td>" "<td>" ++ Col0 ++ "< >" ++ Col1 ++ "</td>" @@ -3558,25 +3625,29 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where, host -> ok end, - test_server_sup:framework_call(report, [tc_start,{?pl2a(Mod),Func}]), print(major, "=case ~p:~p", [Mod, Func]), MinorName = start_minor_log_file(Mod, Func), - print(minor, "<a name=top></a>", []), + print(minor, "<a name=\"top\"></a>", [], internal_raw), MinorBase = filename:basename(MinorName), print(major, "=logfile ~s", [filename:basename(MinorName)]), + + Args1 = [[{tc_logfile,MinorName} | proplists:delete(tc_logfile,hd(Args))]], + test_server_sup:framework_call(report, [tc_start,{{?pl2a(Mod),Func},MinorName}]), + print_props((RunInit==skip_init), get_props(Mode)), print(major, "=started ~s", [lists:flatten(timestamp_get(""))]), {{Col0,Col1},Style} = get_font_style((RunInit==run_init), Mode), - print(html, "<tr valign=top><td>" ++ Col0 ++ "~s" ++ Col1 ++ "</td>" - "<td>" ++ Col0 ++ "~p" ++ Col1 ++ "</td>" - "<td><a href=\"~s\">~p</a></td>" - "<td><a href=\"~s#top\"><</a> <a href=\"~s#end\">></a></td>", - [num2str(Num),Mod,MinorBase,Func,MinorBase,MinorBase]), + TR = xhtml("<tr valign=\"top\">", ["<tr class=\"",odd_or_even(),"\">"]), + print(html, TR ++ "<td>" ++ Col0 ++ "~s" ++ Col1 ++ "</td>" + "<td>" ++ Col0 ++ "~p" ++ Col1 ++ "</td>" + "<td><a href=\"~s\">~p</a></td>" + "<td><a href=\"~s#top\"><</a> <a href=\"~s#end\">></a></td>", + [num2str(Num),Mod,MinorBase,Func,MinorBase,MinorBase]), do_if_parallel(Main, ok, fun erlang:yield/0), %% run the test case {Result,DetectedFail,ProcsBefore,ProcsAfter} = - run_test_case_apply(Num, Mod, Func, Args, get_name(Mode), + run_test_case_apply(Num, Mod, Func, Args1, get_name(Mode), RunInit, Where, TimetrapData), {Time,RetVal,Loc,Opts,Comment} = case Result of @@ -3584,7 +3655,8 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where, {died,DReason,DLoc,DCmt} -> {died,DReason,DLoc,[],DCmt} end, - print(minor, "<a name=end></a>", []), + print(minor, "<a name=\"end\"></a>", [], internal_raw), + print(minor, "\n", [], internal_raw), print_timestamp(minor, "Ended at "), print(major, "=ended ~s", [lists:flatten(timestamp_get(""))]), @@ -3838,9 +3910,10 @@ check_new_crash_dumps(Where) -> progress(skip, CaseNum, Mod, Func, Loc, Reason, Time, Comment, {St0,St1}) -> - {Reason1,{Color,Ret}} = if_auto_skip(Reason, - fun() -> {"#ffcc99",auto_skip} end, - fun() -> {"#ff9933",skip} end), + {Reason1,{Color,Ret}} = + if_auto_skip(Reason, + fun() -> {?auto_skip_color,auto_skip} end, + fun() -> {?user_skip_color,skip} end), print(major, "=result skipped", []), print(1, "*** SKIPPED *** ~s", [get_info_str(Func, CaseNum, get(test_server_cases))]), @@ -3857,7 +3930,7 @@ progress(skip, CaseNum, Mod, Func, Loc, Reason, Time, end, Comment1 = case Comment of "" -> ""; - _ -> "<br>(" ++ to_string(Comment) ++ ")" + _ -> xhtml("<br>(","<br />(") ++ to_string(Comment) ++ ")" end, print(html, "<td>" ++ St0 ++ "~.3fs" ++ St1 ++ "</td>" @@ -3882,8 +3955,8 @@ progress(failed, CaseNum, Mod, Func, Loc, timetrap_timeout, T, Comment = case Comment0 of "" -> "<font color=\"red\">" ++ ErrorReason ++ "</font>"; - _ -> "<font color=\"red\">" ++ ErrorReason ++ "</font><br>" ++ - to_string(Comment0) + _ -> "<font color=\"red\">" ++ ErrorReason ++ + xhtml("</font><br>","</font><br />") ++ to_string(Comment0) end, print(html, "<td>" ++ St0 ++ "~.3fs" ++ St1 ++ "</td>" @@ -3908,8 +3981,8 @@ progress(failed, CaseNum, Mod, Func, Loc, {testcase_aborted,Reason}, _T, Comment = case Comment0 of "" -> "<font color=\"red\">" ++ ErrorReason ++ "</font>"; - _ -> "<font color=\"red\">" ++ ErrorReason ++ "</font><br>" ++ - to_string(Comment0) + _ -> "<font color=\"red\">" ++ ErrorReason ++ + xhtml("</font><br>","</font><br />") ++ to_string(Comment0) end, print(html, "<td>" ++ St0 ++ "died" ++ St1 ++ "</td>" @@ -3943,7 +4016,8 @@ progress(failed, CaseNum, Mod, Func, unknown, Reason, Time, Comment = case Comment0 of "" -> "<font color=\"red\">" ++ ErrorReason2 ++ "</font>"; - _ -> "<font color=\"red\">" ++ ErrorReason2 ++ "</font><br>" ++ + _ -> "<font color=\"red\">" ++ ErrorReason2 ++ + xhtml("</font><br>","</font><br />") ++ to_string(Comment0) end, print(html, @@ -3953,7 +4027,7 @@ progress(failed, CaseNum, Mod, Func, unknown, Reason, Time, [TimeStr,Comment]), print(minor, "=== location ~s", [unknown]), {FStr,FormattedReason} = format_exception(Reason), - print(minor, "=== reason = "++FStr, [FormattedReason]), + print(minor, "=== reason = " ++ FStr, [FormattedReason]), failed; progress(failed, CaseNum, Mod, Func, Loc, Reason, Time, @@ -3969,7 +4043,7 @@ progress(failed, CaseNum, Mod, Func, Loc, Reason, Time, Comment = case Comment0 of "" -> ""; - _ -> "<br>" ++ to_string(Comment0) + _ -> xhtml("<br>","<br />") ++ to_string(Comment0) end, FormatLastLoc = test_server_sup:format_loc(get_last_loc(Loc)), print(html, @@ -3980,7 +4054,7 @@ progress(failed, CaseNum, Mod, Func, Loc, Reason, Time, FormatLoc = test_server_sup:format_loc(Loc), print(minor, "=== location ~s", [FormatLoc]), {FStr,FormattedReason} = format_exception(Reason), - print(minor, "=== reason = "++FStr, [FormattedReason]), + print(minor, "=== reason = " ++ FStr, [FormattedReason]), failed; progress(ok, _CaseNum, Mod, Func, _Loc, RetVal, Time, @@ -3999,7 +4073,7 @@ progress(ok, _CaseNum, Mod, Func, _Loc, RetVal, Time, _ -> print(major, "=result ok", []), case Comment0 of - "" -> ""; + "" -> "<td></td>"; _ -> "<td>" ++ to_string(Comment0) ++ "</td>" end end, @@ -4349,7 +4423,13 @@ output({html,Msg}, _Sender) -> %% We are writing to a seekable file. Finalise so %% we get complete valid (and viewable) HTML code. %% Then rewind to overwrite the finalising code. - io:put_chars(Fd, "\n</table>\n</body>\n</html>\n"), + io:put_chars(Fd, "\n</table>\n"), + case get(test_server_html_footer) of + undefined -> + io:put_chars(Fd, "</body>\n</html>\n"); + Footer -> + io:put_chars(Fd, Footer) + end, file:position(Fd, Pos); {error, epipe} -> %% The file is not seekable. We cannot erase what @@ -4394,6 +4474,28 @@ output_to_fd(Fd, Msg, _Sender) -> end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% xhtml(BasicHtml, XHtml) -> BasicHtml | XHtml +%% +xhtml(HTML, XHTML) -> + case get(basic_html) of + true -> HTML; + _ -> XHTML + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% odd_or_even() -> "odd" | "even" +%% +odd_or_even() -> + case get(odd_or_even) of + even -> + put(odd_or_even, odd), + "even"; + _ -> + put(odd_or_even, even), + "odd" + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% timestamp_filename_get(Leader) -> string() %% Leader = string() %% @@ -5499,9 +5601,10 @@ write_default_cross_coverlog(TestDir) -> file:open(filename:join(TestDir,?cross_coverlog_name), [write]), write_coverlog_header(CrossCoverLog), io:fwrite(CrossCoverLog, - "No cross cover modules exist for this application,<br>" - "or cross cover analysis is not completed.\n" - "</body></html>\n", []), + ["No cross cover modules exist for this application,", + xhtml("<br>","<br />"), + "or cross cover analysis is not completed.\n" + "</body></html>\n"], []), file:close(CrossCoverLog). write_cover_result_table(CoverLog,Coverage) -> diff --git a/lib/tools/c_src/Makefile.in b/lib/tools/c_src/Makefile.in index 6921193154..604332a91e 100644 --- a/lib/tools/c_src/Makefile.in +++ b/lib/tools/c_src/Makefile.in @@ -20,7 +20,7 @@ include $(ERL_TOP)/make/target.mk include $(ERL_TOP)/erts/include/internal/$(TARGET)/ethread.mk USING_MINGW=@MIXED_CYGWIN_MINGW@ -USING_VC=@MIXED_CYGWIN_VC@ +USING_VC=@MIXED_VC@ CC=@CC@ LD=@LD@ diff --git a/lib/tools/emacs/erlang-flymake.el b/lib/tools/emacs/erlang-flymake.el index bc368e9454..2e447b55de 100644 --- a/lib/tools/emacs/erlang-flymake.el +++ b/lib/tools/emacs/erlang-flymake.el @@ -60,7 +60,8 @@ check on newline and when there are no changes)." (list (concat (erlang-flymake-get-app-dir) "ebin"))) (defun erlang-flymake-get-include-dirs () - (list (concat (erlang-flymake-get-app-dir) "include"))) + (list (concat (erlang-flymake-get-app-dir) "include") + (concat (erlang-flymake-get-app-dir) "deps"))) (defun erlang-flymake-get-app-dir () (let ((src-path (file-name-directory (buffer-file-name)))) diff --git a/lib/tools/src/fprof.erl b/lib/tools/src/fprof.erl index 155965a65a..1d85a55bd7 100644 --- a/lib/tools/src/fprof.erl +++ b/lib/tools/src/fprof.erl @@ -87,8 +87,10 @@ dbg(_, _, _) -> -apply({M, F} = Function, Args) +apply({M, F}, Args) when is_atom(M), is_atom(F), is_list(Args) -> + Arity = length(Args), + Function = fun M:F/Arity, apply_1(Function, Args, []); apply(Fun, Args) when is_function(Fun), is_list(Args) -> @@ -98,8 +100,10 @@ apply(A, B) -> apply(M, F, Args) when is_atom(M), is_atom(F), is_list(Args) -> apply_1({M, F}, Args, []); -apply({M, F} = Function, Args, Options) +apply({M, F}, Args, Options) when is_atom(M), is_atom(F), is_list(Args), is_list(Options) -> + Arity = length(Args), + Function = fun M:F/Arity, apply_1(Function, Args, Options); apply(Fun, Args, Options) when is_function(Fun), is_list(Args), is_list(Options) -> @@ -109,7 +113,9 @@ apply(A, B, C) -> apply(Module, Function, Args, Options) when is_atom(Module), is_atom(Function), is_list(Args), is_list(Options) -> - apply_1({Module, Function}, Args, Options); + Arity = length(Args), + Fun = fun Module:Function/Arity, + apply_1(Fun, Args, Options); apply(A, B, C, D) -> erlang:error(badarg, [A, B, C, D]). diff --git a/lib/tools/src/xref_compiler.erl b/lib/tools/src/xref_compiler.erl index 1445e135be..e6f492c62b 100644 --- a/lib/tools/src/xref_compiler.erl +++ b/lib/tools/src/xref_compiler.erl @@ -736,8 +736,11 @@ find_nodes(Tuple, I, T) when is_tuple(Tuple) -> end, {NL, NI, T1} = foldl(Fun, {[], I, T}, L), Tag = case Tag0 of - _ when is_function(Tag0) -> Tag0; - _ when is_atom(Tag0) -> {sofs, Tag0} + _ when is_function(Tag0) -> + Tag0; + _ when is_atom(Tag0) -> + Arity = length(NL), + fun sofs:Tag0/Arity end, find_node({apply, Tag, NL}, NI, T1). diff --git a/lib/tools/test/cover_SUITE.erl b/lib/tools/test/cover_SUITE.erl index 881a3c2997..576d7e261c 100644 --- a/lib/tools/test/cover_SUITE.erl +++ b/lib/tools/test/cover_SUITE.erl @@ -130,13 +130,20 @@ compile(Config) when is_list(Config) -> ?line {ok,_} = compile:file(x), ?line {ok,_} = compile:file("d/y",[debug_info,{outdir,"d"},report]), ?line Key = "A Krypto Key", - ?line {ok,_} = compile:file(crypt, [debug_info,{debug_info_key,Key},report]), + CryptoWorks = crypto_works(), + case CryptoWorks of + false -> + {ok,_} = compile:file(crypt, [debug_info,report]), + {ok,crypt} = cover:compile_beam("crypt.beam"); + true -> + {ok,_} = compile:file(crypt, [{debug_info_key,Key},report]), + {error,{encrypted_abstract_code,_}} = + cover:compile_beam("crypt.beam"), + ok = beam_lib:crypto_key_fun(simple_crypto_fun(Key)), + {ok,crypt} = cover:compile_beam("crypt.beam") + end, ?line {ok,v} = cover:compile_beam(v), ?line {ok,w} = cover:compile_beam("w.beam"), - ?line {error,{encrypted_abstract_code,_}} = - cover:compile_beam("crypt.beam"), - ?line ok = beam_lib:crypto_key_fun(simple_crypto_fun(Key)), - ?line {ok,crypt} = cover:compile_beam("crypt.beam"), ?line {error,{no_abstract_code,"./x.beam"}} = cover:compile_beam(x), ?line {error,{already_cover_compiled,no_beam_found,a}}=cover:compile_beam(a), ?line {error,non_existing} = cover:compile_beam(z), @@ -148,6 +155,15 @@ compile(Config) when is_list(Config) -> ?line Files = lsfiles(), ?line remove(files(Files, ".beam")). +crypto_works() -> + try crypto:start() of + {error,{already_started,crypto}} -> true; + ok -> true + catch + error:_ -> + false + end. + simple_crypto_fun(Key) -> fun(init) -> ok; ({debug_info, des3_cbc, crypt, _}) -> Key diff --git a/lib/tools/test/eprof_SUITE.erl b/lib/tools/test/eprof_SUITE.erl index ecdbc5ce57..3283fa571f 100644 --- a/lib/tools/test/eprof_SUITE.erl +++ b/lib/tools/test/eprof_SUITE.erl @@ -183,8 +183,14 @@ eed(Config) when is_list(Config) -> ?line ok = eprof:log("eprof_SUITE_logfile"), ?line stopped = eprof:stop(), ?line ?t:timetrap_cancel(TTrap), - S = lists:flatten(io_lib:format("~p times slower", [10*(T3-T2)/(T2-T1)])), - {comment,S}. + try + S = lists:flatten(io_lib:format("~p times slower", + [10*(T3-T2)/(T2-T1)])), + {comment,S} + catch + error:badarith -> + {comment,"No time elapsed. Bad clock? Fast computer?"} + end. ensure_eprof_stopped() -> Pid = whereis(eprof), diff --git a/lib/tools/test/lcnt_SUITE.erl b/lib/tools/test/lcnt_SUITE.erl index f2afa60e33..1bee6021ab 100644 --- a/lib/tools/test/lcnt_SUITE.erl +++ b/lib/tools/test/lcnt_SUITE.erl @@ -34,7 +34,7 @@ ]). %% Default timetrap timeout (set in init_per_testcase) --define(default_timeout, ?t:minutes(2)). +-define(default_timeout, ?t:minutes(4)). init_per_suite(Config) when is_list(Config) -> Config. @@ -49,6 +49,7 @@ init_per_testcase(_Case, Config) -> end_per_testcase(_Case, Config) -> Dog = ?config(watchdog, Config), ?t:timetrap_cancel(Dog), + catch lcnt:stop(), ok. suite() -> [{ct_hooks,[ts_install_cth]}]. diff --git a/lib/typer/src/typer.erl b/lib/typer/src/typer.erl index f2a70f49b7..6392f5765f 100644 --- a/lib/typer/src/typer.erl +++ b/lib/typer/src/typer.erl @@ -119,9 +119,9 @@ extract(#analysis{macros = Macros, {ok, RecDict} -> Mod = list_to_atom(filename:basename(File, ".erl")), case dialyzer_utils:get_spec_info(Mod, AbstractCode, RecDict) of - {ok, SpecDict} -> + {ok, SpecDict, CbDict} -> CS1 = dialyzer_codeserver:store_temp_records(Mod, RecDict, CS), - dialyzer_codeserver:store_temp_contracts(Mod, SpecDict, CS1); + dialyzer_codeserver:store_temp_contracts(Mod, SpecDict, CbDict, CS1); {error, Reason} -> compile_error([Reason]) end; {error, Reason} -> compile_error([Reason]) @@ -682,10 +682,10 @@ analyze_result(show_succ, Args, Analysis) -> analyze_result(no_spec, Args, Analysis) -> {Args, Analysis#analysis{no_spec = true}}; analyze_result({pa, Dir}, Args, Analysis) -> - code:add_patha(Dir), + true = code:add_patha(Dir), {Args, Analysis}; analyze_result({pz, Dir}, Args, Analysis) -> - code:add_pathz(Dir), + true = code:add_pathz(Dir), {Args, Analysis}. %%-------------------------------------------------------------------- @@ -873,16 +873,16 @@ collect_one_file_info(File, Analysis) -> Mod = cerl:concrete(cerl:module_name(Core)), case dialyzer_utils:get_spec_info(Mod, AbstractCode, Records) of {error, Reason} -> compile_error([Reason]); - {ok, SpecInfo} -> + {ok, SpecInfo, CbInfo} -> ExpTypes = get_exported_types_from_core(Core), - analyze_core_tree(Core, Records, SpecInfo, ExpTypes, - Analysis, File) + analyze_core_tree(Core, Records, SpecInfo, CbInfo, + ExpTypes, Analysis, File) end end end end. -analyze_core_tree(Core, Records, SpecInfo, ExpTypes, Analysis, File) -> +analyze_core_tree(Core, Records, SpecInfo, CbInfo, ExpTypes, Analysis, File) -> Module = cerl:concrete(cerl:module_name(Core)), TmpTree = cerl:from_records(Core), CS1 = Analysis#analysis.codeserver, @@ -894,7 +894,8 @@ analyze_core_tree(Core, Records, SpecInfo, ExpTypes, Analysis, File) -> CS5 = case Analysis#analysis.no_spec of true -> CS4; - false -> dialyzer_codeserver:store_temp_contracts(Module, SpecInfo, CS4) + false -> + dialyzer_codeserver:store_temp_contracts(Module, SpecInfo, CbInfo, CS4) end, OldExpTypes = dialyzer_codeserver:get_temp_exported_types(CS5), MergedExpTypes = sets:union(ExpTypes, OldExpTypes), diff --git a/lib/wx/aclocal.m4 b/lib/wx/aclocal.m4 new file mode 100644 index 0000000000..339a15a2bb --- /dev/null +++ b/lib/wx/aclocal.m4 @@ -0,0 +1,1766 @@ +dnl +dnl %CopyrightBegin% +dnl +dnl Copyright Ericsson AB 1998-2011. All Rights Reserved. +dnl +dnl The contents of this file are subject to the Erlang Public License, +dnl Version 1.1, (the "License"); you may not use this file except in +dnl compliance with the License. You should have received a copy of the +dnl Erlang Public License along with this software. If not, it can be +dnl retrieved online at http://www.erlang.org/. +dnl +dnl Software distributed under the License is distributed on an "AS IS" +dnl basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +dnl the License for the specific language governing rights and limitations +dnl under the License. +dnl +dnl %CopyrightEnd% +dnl + +dnl +dnl aclocal.m4 +dnl +dnl Local macros used in configure.in. The Local Macros which +dnl could/should be part of autoconf are prefixed LM_, macros specific +dnl to the Erlang system are prefixed ERL_. +dnl + +AC_DEFUN(LM_PRECIOUS_VARS, +[ + +dnl ERL_TOP +AC_ARG_VAR(ERL_TOP, [Erlang/OTP top source directory]) + +dnl Tools +AC_ARG_VAR(CC, [C compiler]) +AC_ARG_VAR(CFLAGS, [C compiler flags]) +AC_ARG_VAR(STATIC_CFLAGS, [C compiler static flags]) +AC_ARG_VAR(CFLAG_RUNTIME_LIBRARY_PATH, [runtime library path linker flag passed via C compiler]) +AC_ARG_VAR(CPP, [C/C++ preprocessor]) +AC_ARG_VAR(CPPFLAGS, [C/C++ preprocessor flags]) +AC_ARG_VAR(CXX, [C++ compiler]) +AC_ARG_VAR(CXXFLAGS, [C++ compiler flags]) +AC_ARG_VAR(LD, [linker (is often overridden by configure)]) +AC_ARG_VAR(LDFLAGS, [linker flags (can be risky to set since LD may be overriden by configure)]) +AC_ARG_VAR(LIBS, [libraries]) +AC_ARG_VAR(DED_LD, [linker for Dynamic Erlang Drivers (set all DED_LD* variables or none)]) +AC_ARG_VAR(DED_LDFLAGS, [linker flags for Dynamic Erlang Drivers (set all DED_LD* variables or none)]) +AC_ARG_VAR(DED_LD_FLAG_RUNTIME_LIBRARY_PATH, [runtime library path linker flag for Dynamic Erlang Drivers (set all DED_LD* variables or none)]) +AC_ARG_VAR(LFS_CFLAGS, [large file support C compiler flags (set all LFS_* variables or none)]) +AC_ARG_VAR(LFS_LDFLAGS, [large file support linker flags (set all LFS_* variables or none)]) +AC_ARG_VAR(LFS_LIBS, [large file support libraries (set all LFS_* variables or none)]) +AC_ARG_VAR(RANLIB, [ranlib]) +AC_ARG_VAR(AR, [ar]) +AC_ARG_VAR(GETCONF, [getconf]) + +dnl Cross system root +AC_ARG_VAR(erl_xcomp_sysroot, [Absolute cross system root path (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_isysroot, [Absolute cross system root include path (only used when cross compiling)]) + +dnl Cross compilation variables +AC_ARG_VAR(erl_xcomp_bigendian, [big endian system: yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_linux_clock_gettime_correction, [clock_gettime() can be used for time correction: yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_linux_nptl, [have Native POSIX Thread Library: yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_linux_usable_sigusrx, [SIGUSR1 and SIGUSR2 can be used: yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_linux_usable_sigaltstack, [have working sigaltstack(): yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_poll, [have working poll(): yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_kqueue, [have working kqueue(): yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_putenv_copy, [putenv() stores key-value copy: yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_reliable_fpe, [have reliable floating point exceptions: yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_getaddrinfo, [have working getaddrinfo() for both IPv4 and IPv6: yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_gethrvtime_procfs_ioctl, [have working gethrvtime() which can be used with procfs ioctl(): yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_clock_gettime_cpu_time, [clock_gettime() can be used for retrieving process CPU time: yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_after_morecore_hook, [__after_morecore_hook can track malloc()s core memory usage: yes|no (only used when cross compiling)]) +AC_ARG_VAR(erl_xcomp_dlsym_brk_wrappers, [dlsym(RTLD_NEXT, _) brk wrappers can track malloc()s core memory usage: yes|no (only used when cross compiling)]) + +]) + +AC_DEFUN(ERL_XCOMP_SYSROOT_INIT, +[ +erl_xcomp_without_sysroot=no +if test "$cross_compiling" = "yes"; then + test "$erl_xcomp_sysroot" != "" || erl_xcomp_without_sysroot=yes + test "$erl_xcomp_isysroot" != "" || erl_xcomp_isysroot="$erl_xcomp_sysroot" +else + erl_xcomp_sysroot= + erl_xcomp_isysroot= +fi +]) + +AC_DEFUN(LM_CHECK_GETCONF, +[ +if test "$cross_compiling" != "yes"; then + AC_CHECK_PROG([GETCONF], [getconf], [getconf], [false]) +else + dnl First check if we got a `<HOST>-getconf' in $PATH + host_getconf="$host_alias-getconf" + AC_CHECK_PROG([GETCONF], [$host_getconf], [$host_getconf], [false]) + if test "$GETCONF" = "false" && test "$erl_xcomp_sysroot" != ""; then + dnl We should perhaps give up if we have'nt found it by now, but at + dnl least in one Tilera MDE `getconf' under sysroot is a bourne + dnl shell script which we can use. We try to find `<HOST>-getconf' + dnl or `getconf' under sysconf, but only under sysconf since + dnl `getconf' in $PATH is almost guaranteed to be for the build + dnl machine. + GETCONF= + prfx="$erl_xcomp_sysroot" + AC_PATH_TOOL([GETCONF], [getconf], [false], + ["$prfx/usr/bin:$prfx/bin:$prfx/usr/local/bin"]) + fi +fi +]) + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_WINDOWS_ENVIRONMENT +dnl +dnl +dnl Tries to determine thw windows build environment, i.e. +dnl MIXED_CYGWIN_VC or MIXED_MSYS_VC +dnl + +AC_DEFUN(LM_WINDOWS_ENVIRONMENT, +[ +MIXED_CYGWIN=no +MIXED_MSYS=no + +AC_MSG_CHECKING(for mixed cygwin or msys and native VC++ environment) +if test "X$host" = "Xwin32" -a "x$GCC" != "xyes"; then + if test -x /usr/bin/cygpath; then + CFLAGS="-O2" + MIXED_CYGWIN=yes + AC_MSG_RESULT([Cygwin and VC]) + MIXED_CYGWIN_VC=yes + CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_VC" + elif test -x /usr/bin/msysinfo; then + CFLAGS="-O2" + MIXED_MSYS=yes + AC_MSG_RESULT([MSYS and VC]) + MIXED_MSYS_VC=yes + CPPFLAGS="$CPPFLAGS -DERTS_MIXED_MSYS_VC" + else + AC_MSG_RESULT([undeterminable]) + AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!) + fi +else + AC_MSG_RESULT([no]) + MIXED_CYGWIN_VC=no + MIXED_MSYS_VC=no +fi +AC_SUBST(MIXED_CYGWIN_VC) +AC_SUBST(MIXED_MSYS_VC) + +MIXED_VC=no +if test "x$MIXED_MSYS_VC" = "xyes" -o "x$MIXED_CYGWIN_VC" = "xyes" ; then + MIXED_VC=yes +fi + +AC_SUBST(MIXED_VC) + +if test "x$MIXED_MSYS" != "xyes"; then + AC_MSG_CHECKING(for mixed cygwin and native MinGW environment) + if test "X$host" = "Xwin32" -a "x$GCC" = x"yes"; then + if test -x /usr/bin/cygpath; then + CFLAGS="-O2" + MIXED_CYGWIN=yes + AC_MSG_RESULT([yes]) + MIXED_CYGWIN_MINGW=yes + CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_MINGW" + else + AC_MSG_RESULT([undeterminable]) + AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!) + fi + else + AC_MSG_RESULT([no]) + MIXED_CYGWIN_MINGW=no + fi +else + MIXED_CYGWIN_MINGW=no +fi +AC_SUBST(MIXED_CYGWIN_MINGW) + +AC_MSG_CHECKING(if we mix cygwin with any native compiler) +if test "X$MIXED_CYGWIN" = "Xyes"; then + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + +AC_SUBST(MIXED_CYGWIN) + +AC_MSG_CHECKING(if we mix msys with another native compiler) +if test "X$MIXED_MSYS" = "Xyes" ; then + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + +AC_SUBST(MIXED_MSYS) +]) + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_FIND_EMU_CC +dnl +dnl +dnl Tries fairly hard to find a C compiler that can handle jump tables. +dnl Defines the @EMU_CC@ variable for the makefiles and +dnl inserts NO_JUMP_TABLE in the header if one cannot be found... +dnl + +AC_DEFUN(LM_FIND_EMU_CC, + [AC_CACHE_CHECK(for a compiler that handles jumptables, + ac_cv_prog_emu_cc, + [ +AC_TRY_COMPILE([],[ +#if defined(__clang_major__) && __clang_major__ >= 3 + /* clang 3.x or later is fine */ +#elif defined(__llvm__) +#error "this version of llvm is unable to correctly compile beam_emu.c" +#endif + __label__ lbl1; + __label__ lbl2; + int x = magic(); + static void *jtab[2]; + + jtab[0] = &&lbl1; + jtab[1] = &&lbl2; + goto *jtab[x]; +lbl1: + return 1; +lbl2: + return 2; +],ac_cv_prog_emu_cc=$CC,ac_cv_prog_emu_cc=no) + +if test $ac_cv_prog_emu_cc = no; then + for ac_progname in emu_cc.sh gcc-4.2 gcc; do + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_progname; then + ac_cv_prog_emu_cc=$ac_dir/$ac_progname + break + fi + done + IFS="$ac_save_ifs" + if test $ac_cv_prog_emu_cc != no; then + break + fi + done +fi + +if test $ac_cv_prog_emu_cc != no; then + save_CC=$CC + save_CFLAGS=$CFLAGS + save_CPPFLAGS=$CPPFLAGS + CC=$ac_cv_prog_emu_cc + CFLAGS="" + CPPFLAGS="" + AC_TRY_COMPILE([],[ +#if defined(__clang_major__) && __clang_major__ >= 3 + /* clang 3.x or later is fine */ +#elif defined(__llvm__) +#error "this version of llvm is unable to correctly compile beam_emu.c" +#endif + __label__ lbl1; + __label__ lbl2; + int x = magic(); + static void *jtab[2]; + + jtab[0] = &&lbl1; + jtab[1] = &&lbl2; + goto *jtab[x]; + lbl1: + return 1; + lbl2: + return 2; + ],ac_cv_prog_emu_cc=$CC,ac_cv_prog_emu_cc=no) + CC=$save_CC + CFLAGS=$save_CFLAGS + CPPFLAGS=$save_CPPFLAGS +fi +]) +if test $ac_cv_prog_emu_cc = no; then + AC_DEFINE(NO_JUMP_TABLE,[],[Defined if no found C compiler can handle jump tables]) + EMU_CC=$CC +else + EMU_CC=$ac_cv_prog_emu_cc +fi +AC_SUBST(EMU_CC) +]) + + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_PROG_INSTALL_DIR +dnl +dnl This macro may be used by any OTP application. +dnl +dnl Figure out how to create directories with parents. +dnl (In my opinion INSTALL_DIR is a bad name, MKSUBDIRS or something is better) +dnl +dnl We prefer 'install -d', but use 'mkdir -p' if it exists. +dnl If none of these methods works, we give up. +dnl + + +AC_DEFUN(LM_PROG_INSTALL_DIR, +[AC_CACHE_CHECK(how to create a directory including parents, +ac_cv_prog_mkdir_p, +[ +temp_name_base=config.$$ +temp_name=$temp_name_base/x/y/z +$INSTALL -d $temp_name >/dev/null 2>&1 +ac_cv_prog_mkdir_p=none +if test -d $temp_name; then + ac_cv_prog_mkdir_p="$INSTALL -d" +else + mkdir -p $temp_name >/dev/null 2>&1 + if test -d $temp_name; then + ac_cv_prog_mkdir_p="mkdir -p" + fi +fi +rm -fr $temp_name_base +]) + +case "${ac_cv_prog_mkdir_p}" in + none) AC_MSG_ERROR(don't know how create directories with parents) ;; + *) INSTALL_DIR="$ac_cv_prog_mkdir_p" AC_SUBST(INSTALL_DIR) ;; +esac +]) + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_PROG_PERL5 +dnl +dnl Try to find perl version 5. If found set PERL to the absolute path +dnl of the program, if not found set PERL to false. +dnl +dnl On some systems /usr/bin/perl is perl 4 and e.g. +dnl /usr/local/bin/perl is perl 5. We try to handle this case by +dnl putting a couple of +dnl Tries to handle the case that there are two programs called perl +dnl in the path and one of them is perl 5 and the other isn't. +dnl +AC_DEFUN(LM_PROG_PERL5, +[AC_PATH_PROGS(PERL, perl5 perl, false, + /usr/local/bin:/opt/local/bin:/usr/local/gnu/bin:${PATH}) +changequote(, )dnl +dnl[ That bracket is needed to balance the right bracket below +if test "$PERL" = "false" || $PERL -e 'exit ($] >= 5)'; then +changequote([, ])dnl + ac_cv_path_PERL=false + PERL=false +dnl AC_MSG_WARN(perl version 5 not found) +fi +])dnl + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_DECL_SO_BSDCOMPAT +dnl +dnl Check if the system has the SO_BSDCOMPAT flag on sockets (linux) +dnl +AC_DEFUN(LM_DECL_SO_BSDCOMPAT, +[AC_CACHE_CHECK([for SO_BSDCOMPAT declaration], ac_cv_decl_so_bsdcompat, +AC_TRY_COMPILE([#include <sys/socket.h>], [int i = SO_BSDCOMPAT;], + ac_cv_decl_so_bsdcompat=yes, + ac_cv_decl_so_bsdcompat=no)) + +case "${ac_cv_decl_so_bsdcompat}" in + "yes" ) AC_DEFINE(HAVE_SO_BSDCOMPAT,[], + [Define if you have SO_BSDCOMPAT flag on sockets]) ;; + * ) ;; +esac +]) + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_DECL_INADDR_LOOPBACK +dnl +dnl Try to find declaration of INADDR_LOOPBACK, if nowhere provide a default +dnl + +AC_DEFUN(LM_DECL_INADDR_LOOPBACK, +[AC_CACHE_CHECK([for INADDR_LOOPBACK in netinet/in.h], + ac_cv_decl_inaddr_loopback, +[AC_TRY_COMPILE([#include <sys/types.h> +#include <netinet/in.h>], [int i = INADDR_LOOPBACK;], +ac_cv_decl_inaddr_loopback=yes, ac_cv_decl_inaddr_loopback=no) +]) + +if test ${ac_cv_decl_inaddr_loopback} = no; then + AC_CACHE_CHECK([for INADDR_LOOPBACK in rpc/types.h], + ac_cv_decl_inaddr_loopback_rpc, + AC_TRY_COMPILE([#include <rpc/types.h>], + [int i = INADDR_LOOPBACK;], + ac_cv_decl_inaddr_loopback_rpc=yes, + ac_cv_decl_inaddr_loopback_rpc=no)) + + case "${ac_cv_decl_inaddr_loopback_rpc}" in + "yes" ) + AC_DEFINE(DEF_INADDR_LOOPBACK_IN_RPC_TYPES_H,[], + [Define if you need to include rpc/types.h to get INADDR_LOOPBACK defined]) ;; + * ) + AC_CACHE_CHECK([for INADDR_LOOPBACK in winsock2.h], + ac_cv_decl_inaddr_loopback_winsock2, + AC_TRY_COMPILE([#define WIN32_LEAN_AND_MEAN + #include <winsock2.h>], + [int i = INADDR_LOOPBACK;], + ac_cv_decl_inaddr_loopback_winsock2=yes, + ac_cv_decl_inaddr_loopback_winsock2=no)) + case "${ac_cv_decl_inaddr_loopback_winsock2}" in + "yes" ) + AC_DEFINE(DEF_INADDR_LOOPBACK_IN_WINSOCK2_H,[], + [Define if you need to include winsock2.h to get INADDR_LOOPBACK defined]) ;; + * ) + # couldn't find it anywhere + AC_DEFINE(HAVE_NO_INADDR_LOOPBACK,[], + [Define if you don't have a definition of INADDR_LOOPBACK]) ;; + esac;; + esac +fi +]) + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_STRUCT_SOCKADDR_SA_LEN +dnl +dnl Check if the sockaddr structure has the field sa_len +dnl + +AC_DEFUN(LM_STRUCT_SOCKADDR_SA_LEN, +[AC_CACHE_CHECK([whether struct sockaddr has sa_len field], + ac_cv_struct_sockaddr_sa_len, +AC_TRY_COMPILE([#include <sys/types.h> +#include <sys/socket.h>], [struct sockaddr s; s.sa_len = 10;], + ac_cv_struct_sockaddr_sa_len=yes, ac_cv_struct_sockaddr_sa_len=no)) + +dnl FIXME convbreak +case ${ac_cv_struct_sockaddr_sa_len} in + "no" ) AC_DEFINE(NO_SA_LEN,[1],[Define if you dont have salen]) ;; + *) ;; +esac +]) + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_STRUCT_EXCEPTION +dnl +dnl Check to see whether the system supports the matherr function +dnl and its associated type "struct exception". +dnl + +AC_DEFUN(LM_STRUCT_EXCEPTION, +[AC_CACHE_CHECK([for struct exception (and matherr function)], + ac_cv_struct_exception, +AC_TRY_COMPILE([#include <math.h>], + [struct exception x; x.type = DOMAIN; x.type = SING;], + ac_cv_struct_exception=yes, ac_cv_struct_exception=no)) + +case "${ac_cv_struct_exception}" in + "yes" ) AC_DEFINE(USE_MATHERR,[1],[Define if you have matherr() function and struct exception type]) ;; + * ) ;; +esac +]) + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_SYS_IPV6 +dnl +dnl Check for ipv6 support and what the in6_addr structure is called. +dnl (early linux used in_addr6 insted of in6_addr) +dnl + +AC_DEFUN(LM_SYS_IPV6, +[AC_MSG_CHECKING(for IP version 6 support) +AC_CACHE_VAL(ac_cv_sys_ipv6_support, +[ok_so_far=yes + AC_TRY_COMPILE([#include <sys/types.h> +#ifdef __WIN32__ +#include <winsock2.h> +#include <ws2tcpip.h> +#else +#include <netinet/in.h> +#endif], + [struct in6_addr a6; struct sockaddr_in6 s6;], ok_so_far=yes, ok_so_far=no) + +if test $ok_so_far = yes; then + ac_cv_sys_ipv6_support=yes +else + AC_TRY_COMPILE([#include <sys/types.h> +#ifdef __WIN32__ +#include <winsock2.h> +#include <ws2tcpip.h> +#else +#include <netinet/in.h> +#endif], + [struct in_addr6 a6; struct sockaddr_in6 s6;], + ac_cv_sys_ipv6_support=in_addr6, ac_cv_sys_ipv6_support=no) +fi +])dnl + +dnl +dnl Have to use old style AC_DEFINE due to BC with old autoconf. +dnl + +case ${ac_cv_sys_ipv6_support} in + yes) + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_IN6,[1],[Define if ipv6 is present]) + ;; + in_addr6) + AC_MSG_RESULT([yes (but I am redefining in_addr6 to in6_addr)]) + AC_DEFINE(HAVE_IN6,[1],[Define if ipv6 is present]) + AC_DEFINE(HAVE_IN_ADDR6_STRUCT,[],[Early linux used in_addr6 instead of in6_addr, define if you have this]) + ;; + *) + AC_MSG_RESULT(no) + ;; +esac +]) + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_SYS_MULTICAST +dnl +dnl Check for multicast support. Only checks for multicast options in +dnl setsockopt(), no check is performed that multicasting actually works. +dnl If options are found defines HAVE_MULTICAST_SUPPORT +dnl + +AC_DEFUN(LM_SYS_MULTICAST, +[AC_CACHE_CHECK([for multicast support], ac_cv_sys_multicast_support, +[AC_EGREP_CPP(yes, +[#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#if defined(IP_MULTICAST_TTL) && defined(IP_MULTICAST_LOOP) && defined(IP_MULTICAST_IF) && defined(IP_ADD_MEMBERSHIP) && defined(IP_DROP_MEMBERSHIP) +yes +#endif +], ac_cv_sys_multicast_support=yes, ac_cv_sys_multicast_support=no)]) +if test $ac_cv_sys_multicast_support = yes; then + AC_DEFINE(HAVE_MULTICAST_SUPPORT,[1], + [Define if setsockopt() accepts multicast options]) +fi +])dnl + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_DECL_SYS_ERRLIST +dnl +dnl Define SYS_ERRLIST_DECLARED if the variable sys_errlist is declared +dnl in a system header file, stdio.h or errno.h. +dnl + +AC_DEFUN(LM_DECL_SYS_ERRLIST, +[AC_CACHE_CHECK([for sys_errlist declaration in stdio.h or errno.h], + ac_cv_decl_sys_errlist, +[AC_TRY_COMPILE([#include <stdio.h> +#include <errno.h>], [char *msg = *(sys_errlist + 1);], + ac_cv_decl_sys_errlist=yes, ac_cv_decl_sys_errlist=no)]) +if test $ac_cv_decl_sys_errlist = yes; then + AC_DEFINE(SYS_ERRLIST_DECLARED,[], + [define if the variable sys_errlist is declared in a system header file]) +fi +]) + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_CHECK_FUNC_DECL( funname, declaration [, extra includes +dnl [, action-if-found [, action-if-not-found]]] ) +dnl +dnl Checks if the declaration "declaration" of "funname" conflicts +dnl with the header files idea of how the function should be +dnl declared. It is useful on systems which lack prototypes and you +dnl need to provide your own (e.g. when you want to take the address +dnl of a function). The 4'th argument is expanded if conflicting, +dnl the 5'th argument otherwise +dnl +dnl + +AC_DEFUN(LM_CHECK_FUNC_DECL, +[AC_MSG_CHECKING([for conflicting declaration of $1]) +AC_CACHE_VAL(ac_cv_func_decl_$1, +[AC_TRY_COMPILE([#include <stdio.h> +$3],[$2 +char *c = (char *)$1; +], eval "ac_cv_func_decl_$1=no", eval "ac_cv_func_decl_$1=yes")]) +if eval "test \"`echo '$ac_cv_func_decl_'$1`\" = yes"; then + AC_MSG_RESULT(yes) + ifelse([$4], , :, [$4]) +else + AC_MSG_RESULT(no) +ifelse([$5], , , [$5 +])dnl +fi +]) + + +dnl ---------------------------------------------------------------------- +dnl +dnl LM_CHECK_THR_LIB +dnl +dnl This macro may be used by any OTP application. +dnl +dnl LM_CHECK_THR_LIB sets THR_LIBS, THR_DEFS, and THR_LIB_NAME. It also +dnl checks for some pthread headers which will appear in DEFS or config.h. +dnl + +AC_DEFUN(LM_CHECK_THR_LIB, +[ + +NEED_NPTL_PTHREAD_H=no + +dnl win32? +AC_MSG_CHECKING([for native win32 threads]) +if test "X$host_os" = "Xwin32"; then + AC_MSG_RESULT(yes) + THR_DEFS="-DWIN32_THREADS" + THR_LIBS= + THR_LIB_NAME=win32_threads + THR_LIB_TYPE=win32_threads +else + AC_MSG_RESULT(no) + THR_DEFS= + THR_LIBS= + THR_LIB_NAME= + THR_LIB_TYPE=posix_unknown + +dnl Try to find POSIX threads + +dnl The usual pthread lib... + AC_CHECK_LIB(pthread, pthread_create, THR_LIBS="-lpthread") + +dnl FreeBSD has pthreads in special c library, c_r... + if test "x$THR_LIBS" = "x"; then + AC_CHECK_LIB(c_r, pthread_create, THR_LIBS="-lc_r") + fi + +dnl On ofs1 the '-pthread' switch should be used + if test "x$THR_LIBS" = "x"; then + AC_MSG_CHECKING([if the '-pthread' switch can be used]) + saved_cflags=$CFLAGS + CFLAGS="$CFLAGS -pthread" + AC_TRY_LINK([#include <pthread.h>], + pthread_create((void*)0,(void*)0,(void*)0,(void*)0);, + [THR_DEFS="-pthread" + THR_LIBS="-pthread"]) + CFLAGS=$saved_cflags + if test "x$THR_LIBS" != "x"; then + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + fi + + if test "x$THR_LIBS" != "x"; then + THR_DEFS="$THR_DEFS -D_THREAD_SAFE -D_REENTRANT -DPOSIX_THREADS" + THR_LIB_NAME=pthread + case $host_os in + solaris*) + THR_DEFS="$THR_DEFS -D_POSIX_PTHREAD_SEMANTICS" ;; + linux*) + THR_DEFS="$THR_DEFS -D_POSIX_THREAD_SAFE_FUNCTIONS" + + LM_CHECK_GETCONF + AC_MSG_CHECKING(for Native POSIX Thread Library) + libpthr_vsn=`$GETCONF GNU_LIBPTHREAD_VERSION 2>/dev/null` + if test $? -eq 0; then + case "$libpthr_vsn" in + *nptl*|*NPTL*) nptl=yes;; + *) nptl=no;; + esac + elif test "$cross_compiling" = "yes"; then + case "$erl_xcomp_linux_nptl" in + "") nptl=cross;; + yes|no) nptl=$erl_xcomp_linux_nptl;; + *) AC_MSG_ERROR([Bad erl_xcomp_linux_nptl value: $erl_xcomp_linux_nptl]);; + esac + else + nptl=no + fi + AC_MSG_RESULT($nptl) + if test $nptl = cross; then + nptl=yes + AC_MSG_WARN([result yes guessed because of cross compilation]) + fi + if test $nptl = yes; then + THR_LIB_TYPE=posix_nptl + need_nptl_incldir=no + AC_CHECK_HEADER(nptl/pthread.h, + [need_nptl_incldir=yes + NEED_NPTL_PTHREAD_H=yes]) + if test $need_nptl_incldir = yes; then + # Ahh... + nptl_path="$C_INCLUDE_PATH:$CPATH" + if test X$cross_compiling != Xyes; then + nptl_path="$nptl_path:/usr/local/include:/usr/include" + else + IROOT="$erl_xcomp_isysroot" + test "$IROOT" != "" || IROOT="$erl_xcomp_sysroot" + test "$IROOT" != "" || AC_MSG_ERROR([Don't know where to search for includes! Please set erl_xcomp_isysroot]) + nptl_path="$nptl_path:$IROOT/usr/local/include:$IROOT/usr/include" + fi + nptl_ws_path= + save_ifs="$IFS"; IFS=":" + for dir in $nptl_path; do + if test "x$dir" != "x"; then + nptl_ws_path="$nptl_ws_path $dir" + fi + done + IFS=$save_ifs + nptl_incldir= + for dir in $nptl_ws_path; do + AC_CHECK_HEADER($dir/nptl/pthread.h, + nptl_incldir=$dir/nptl) + if test "x$nptl_incldir" != "x"; then + THR_DEFS="$THR_DEFS -isystem $nptl_incldir" + break + fi + done + if test "x$nptl_incldir" = "x"; then + AC_MSG_ERROR(Failed to locate nptl system include directory) + fi + fi + fi + ;; + *) ;; + esac + + dnl We sometimes need THR_DEFS in order to find certain headers + dnl (at least for pthread.h on osf1). + saved_cppflags=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $THR_DEFS" + + dnl + dnl Check for headers + dnl + + AC_CHECK_HEADER(pthread.h, + AC_DEFINE(HAVE_PTHREAD_H, 1, \ +[Define if you have the <pthread.h> header file.])) + + dnl Some Linuxes have <pthread/mit/pthread.h> instead of <pthread.h> + AC_CHECK_HEADER(pthread/mit/pthread.h, \ + AC_DEFINE(HAVE_MIT_PTHREAD_H, 1, \ +[Define if the pthread.h header file is in pthread/mit directory.])) + + dnl restore CPPFLAGS + CPPFLAGS=$saved_cppflags + + fi +fi + +]) + +AC_DEFUN(ERL_INTERNAL_LIBS, +[ + +ERTS_INTERNAL_X_LIBS= + +AC_CHECK_LIB(kstat, kstat_open, +[AC_DEFINE(HAVE_KSTAT, 1, [Define if you have kstat]) +ERTS_INTERNAL_X_LIBS="$ERTS_INTERNAL_X_LIBS -lkstat"]) + +AC_SUBST(ERTS_INTERNAL_X_LIBS) + +]) + +AC_DEFUN(ETHR_CHK_SYNC_OP, +[ + AC_MSG_CHECKING([for $3-bit $1()]) + case "$2" in + "1") sync_call="$1(&var);";; + "2") sync_call="$1(&var, ($4) 0);";; + "3") sync_call="$1(&var, ($4) 0, ($4) 0);";; + esac + have_sync_op=no + AC_TRY_LINK([], + [ + $4 res; + volatile $4 var; + res = $sync_call + ], + [have_sync_op=yes]) + test $have_sync_op = yes && $5 + AC_MSG_RESULT([$have_sync_op]) +]) + +AC_DEFUN(ETHR_CHK_INTERLOCKED, +[ + ilckd="$1" + AC_MSG_CHECKING([for ${ilckd}()]) + case "$2" in + "1") ilckd_call="${ilckd}(var);";; + "2") ilckd_call="${ilckd}(var, ($3) 0);";; + "3") ilckd_call="${ilckd}(var, ($3) 0, ($3) 0);";; + "4") ilckd_call="${ilckd}(var, ($3) 0, ($3) 0, arr);";; + esac + have_interlocked_op=no + AC_TRY_LINK( + [ + #define WIN32_LEAN_AND_MEAN + #include <windows.h> + #include <intrin.h> + ], + [ + volatile $3 *var; + volatile $3 arr[2]; + + $ilckd_call + return 0; + ], + [have_interlocked_op=yes]) + test $have_interlocked_op = yes && $4 + AC_MSG_RESULT([$have_interlocked_op]) +]) + +dnl ---------------------------------------------------------------------- +dnl +dnl ERL_FIND_ETHR_LIB +dnl +dnl NOTE! This macro may be changed at any time! Should *only* be used by +dnl ERTS! +dnl +dnl Find a thread library to use. Sets ETHR_LIBS to libraries to link +dnl with, ETHR_X_LIBS to extra libraries to link with (same as ETHR_LIBS +dnl except that the ethread lib itself is not included), ETHR_DEFS to +dnl defines to compile with, ETHR_THR_LIB_BASE to the name of the +dnl thread library which the ethread library is based on, and ETHR_LIB_NAME +dnl to the name of the library where the ethread implementation is located. +dnl ERL_FIND_ETHR_LIB currently searches for 'pthreads', and +dnl 'win32_threads'. If no thread library was found ETHR_LIBS, ETHR_X_LIBS, +dnl ETHR_DEFS, ETHR_THR_LIB_BASE, and ETHR_LIB_NAME are all set to the +dnl empty string. +dnl + +AC_DEFUN(ERL_FIND_ETHR_LIB, +[ + +LM_CHECK_THR_LIB +ERL_INTERNAL_LIBS + +ethr_have_native_atomics=no +ethr_have_native_spinlock=no +ETHR_THR_LIB_BASE="$THR_LIB_NAME" +ETHR_THR_LIB_BASE_TYPE="$THR_LIB_TYPE" +ETHR_DEFS="$THR_DEFS" +ETHR_X_LIBS="$THR_LIBS $ERTS_INTERNAL_X_LIBS" +ETHR_LIBS= +ETHR_LIB_NAME= + +ethr_modified_default_stack_size= + +dnl Name of lib where ethread implementation is located +ethr_lib_name=ethread + +case "$THR_LIB_NAME" in + + win32_threads) + ETHR_THR_LIB_BASE_DIR=win + # * _WIN32_WINNT >= 0x0400 is needed for + # TryEnterCriticalSection + # * _WIN32_WINNT >= 0x0403 is needed for + # InitializeCriticalSectionAndSpinCount + # The ethread lib will refuse to build if _WIN32_WINNT < 0x0403. + # + # -D_WIN32_WINNT should have been defined in $CPPFLAGS; fetch it + # and save it in ETHR_DEFS. + found_win32_winnt=no + for cppflag in $CPPFLAGS; do + case $cppflag in + -DWINVER*) + ETHR_DEFS="$ETHR_DEFS $cppflag" + ;; + -D_WIN32_WINNT*) + ETHR_DEFS="$ETHR_DEFS $cppflag" + found_win32_winnt=yes + ;; + *) + ;; + esac + done + if test $found_win32_winnt = no; then + AC_MSG_ERROR([-D_WIN32_WINNT missing in CPPFLAGS]) + fi + + AC_DEFINE(ETHR_WIN32_THREADS, 1, [Define if you have win32 threads]) + + ETHR_CHK_INTERLOCKED([_InterlockedDecrement], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT, 1, [Define if you have _InterlockedDecrement()])) + ETHR_CHK_INTERLOCKED([_InterlockedDecrement_rel], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT_REL, 1, [Define if you have _InterlockedDecrement_rel()])) + ETHR_CHK_INTERLOCKED([_InterlockedIncrement], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT, 1, [Define if you have _InterlockedIncrement()])) + ETHR_CHK_INTERLOCKED([_InterlockedIncrement_acq], [1], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT_ACQ, 1, [Define if you have _InterlockedIncrement_acq()])) + ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD, 1, [Define if you have _InterlockedExchangeAdd()])) + ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd_acq], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD_ACQ, 1, [Define if you have _InterlockedExchangeAdd_acq()])) + ETHR_CHK_INTERLOCKED([_InterlockedAnd], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDAND, 1, [Define if you have _InterlockedAnd()])) + ETHR_CHK_INTERLOCKED([_InterlockedOr], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDOR, 1, [Define if you have _InterlockedOr()])) + ETHR_CHK_INTERLOCKED([_InterlockedExchange], [2], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGE, 1, [Define if you have _InterlockedExchange()])) + ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE, 1, [Define if you have _InterlockedCompareExchange()])) + test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes + ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange_acq], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE_ACQ, 1, [Define if you have _InterlockedCompareExchange_acq()])) + test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes + ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange_rel], [3], [long], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE_REL, 1, [Define if you have _InterlockedCompareExchange_rel()])) + test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes + + ETHR_CHK_INTERLOCKED([_InterlockedDecrement64], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT64, 1, [Define if you have _InterlockedDecrement64()])) + ETHR_CHK_INTERLOCKED([_InterlockedDecrement64_rel], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDDECREMENT64_REL, 1, [Define if you have _InterlockedDecrement64_rel()])) + ETHR_CHK_INTERLOCKED([_InterlockedIncrement64], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT64, 1, [Define if you have _InterlockedIncrement64()])) + ETHR_CHK_INTERLOCKED([_InterlockedIncrement64_acq], [1], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDINCREMENT64_ACQ, 1, [Define if you have _InterlockedIncrement64_acq()])) + ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD64, 1, [Define if you have _InterlockedExchangeAdd64()])) + ETHR_CHK_INTERLOCKED([_InterlockedExchangeAdd64_acq], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGEADD64_ACQ, 1, [Define if you have _InterlockedExchangeAdd64_acq()])) + ETHR_CHK_INTERLOCKED([_InterlockedAnd64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDAND64, 1, [Define if you have _InterlockedAnd64()])) + ETHR_CHK_INTERLOCKED([_InterlockedOr64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDOR64, 1, [Define if you have _InterlockedOr64()])) + ETHR_CHK_INTERLOCKED([_InterlockedExchange64], [2], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDEXCHANGE64, 1, [Define if you have _InterlockedExchange64()])) + ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64, 1, [Define if you have _InterlockedCompareExchange64()])) + test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes + ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64_acq], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64_ACQ, 1, [Define if you have _InterlockedCompareExchange64_acq()])) + test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes + ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange64_rel], [3], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64_REL, 1, [Define if you have _InterlockedCompareExchange64_rel()])) + test "$have_interlocked_op" = "yes" && ethr_have_native_atomics=yes + + ETHR_CHK_INTERLOCKED([_InterlockedCompareExchange128], [4], [__int64], AC_DEFINE_UNQUOTED(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE128, 1, [Define if you have _InterlockedCompareExchange128()])) + + test "$ethr_have_native_atomics" = "yes" && ethr_have_native_spinlock=yes + ;; + + pthread) + ETHR_THR_LIB_BASE_DIR=pthread + AC_DEFINE(ETHR_PTHREADS, 1, [Define if you have pthreads]) + case $host_os in + openbsd*) + # The default stack size is insufficient for our needs + # on OpenBSD. We increase it to 256 kilo words. + ethr_modified_default_stack_size=256;; + linux*) + ETHR_DEFS="$ETHR_DEFS -D_GNU_SOURCE" + + if test X$cross_compiling = Xyes; then + case X$erl_xcomp_linux_usable_sigusrx in + X) usable_sigusrx=cross;; + Xyes|Xno) usable_sigusrx=$erl_xcomp_linux_usable_sigusrx;; + *) AC_MSG_ERROR([Bad erl_xcomp_linux_usable_sigusrx value: $erl_xcomp_linux_usable_sigusrx]);; + esac + case X$erl_xcomp_linux_usable_sigaltstack in + X) usable_sigaltstack=cross;; + Xyes|Xno) usable_sigaltstack=$erl_xcomp_linux_usable_sigaltstack;; + *) AC_MSG_ERROR([Bad erl_xcomp_linux_usable_sigaltstack value: $erl_xcomp_linux_usable_sigaltstack]);; + esac + else + # FIXME: Test for actual problems instead of kernel versions + linux_kernel_vsn_=`uname -r` + case $linux_kernel_vsn_ in + [[0-1]].*|2.[[0-1]]|2.[[0-1]].*) + usable_sigusrx=no + usable_sigaltstack=no;; + 2.[[2-3]]|2.[[2-3]].*) + usable_sigusrx=yes + usable_sigaltstack=no;; + *) + usable_sigusrx=yes + usable_sigaltstack=yes;; + esac + fi + + AC_MSG_CHECKING(if SIGUSR1 and SIGUSR2 can be used) + AC_MSG_RESULT($usable_sigusrx) + if test $usable_sigusrx = cross; then + usable_sigusrx=yes + AC_MSG_WARN([result yes guessed because of cross compilation]) + fi + if test $usable_sigusrx = no; then + ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGUSRX" + fi + + AC_MSG_CHECKING(if sigaltstack can be used) + AC_MSG_RESULT($usable_sigaltstack) + if test $usable_sigaltstack = cross; then + usable_sigaltstack=yes + AC_MSG_WARN([result yes guessed because of cross compilation]) + fi + if test $usable_sigaltstack = no; then + ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGALTSTACK" + fi + ;; + *) ;; + esac + + dnl We sometimes need ETHR_DEFS in order to find certain headers + dnl (at least for pthread.h on osf1). + saved_cppflags="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $ETHR_DEFS" + + dnl We need the thread library in order to find some functions + saved_libs="$LIBS" + LIBS="$LIBS $ETHR_X_LIBS" + + dnl + dnl Check for headers + dnl + + AC_CHECK_HEADER(pthread.h, \ + AC_DEFINE(ETHR_HAVE_PTHREAD_H, 1, \ +[Define if you have the <pthread.h> header file.])) + + dnl Some Linuxes have <pthread/mit/pthread.h> instead of <pthread.h> + AC_CHECK_HEADER(pthread/mit/pthread.h, \ + AC_DEFINE(ETHR_HAVE_MIT_PTHREAD_H, 1, \ +[Define if the pthread.h header file is in pthread/mit directory.])) + + if test $NEED_NPTL_PTHREAD_H = yes; then + AC_DEFINE(ETHR_NEED_NPTL_PTHREAD_H, 1, \ +[Define if you need the <nptl/pthread.h> header file.]) + fi + + AC_CHECK_HEADER(sched.h, \ + AC_DEFINE(ETHR_HAVE_SCHED_H, 1, \ +[Define if you have the <sched.h> header file.])) + + AC_CHECK_HEADER(sys/time.h, \ + AC_DEFINE(ETHR_HAVE_SYS_TIME_H, 1, \ +[Define if you have the <sys/time.h> header file.])) + + AC_TRY_COMPILE([#include <time.h> + #include <sys/time.h>], + [struct timeval *tv; return 0;], + AC_DEFINE(ETHR_TIME_WITH_SYS_TIME, 1, \ +[Define if you can safely include both <sys/time.h> and <time.h>.])) + + + dnl + dnl Check for functions + dnl + + AC_CHECK_FUNC(pthread_spin_lock, \ + [ethr_have_native_spinlock=yes \ + AC_DEFINE(ETHR_HAVE_PTHREAD_SPIN_LOCK, 1, \ +[Define if you have the pthread_spin_lock function.])]) + + have_sched_yield=no + have_librt_sched_yield=no + AC_CHECK_FUNC(sched_yield, [have_sched_yield=yes]) + if test $have_sched_yield = no; then + AC_CHECK_LIB(rt, sched_yield, + [have_librt_sched_yield=yes + ETHR_X_LIBS="$ETHR_X_LIBS -lrt"]) + fi + if test $have_sched_yield = yes || test $have_librt_sched_yield = yes; then + AC_DEFINE(ETHR_HAVE_SCHED_YIELD, 1, [Define if you have the sched_yield() function.]) + AC_MSG_CHECKING([whether sched_yield() returns an int]) + sched_yield_ret_int=no + AC_TRY_COMPILE([ + #ifdef ETHR_HAVE_SCHED_H + #include <sched.h> + #endif + ], + [int sched_yield();], + [sched_yield_ret_int=yes]) + AC_MSG_RESULT([$sched_yield_ret_int]) + if test $sched_yield_ret_int = yes; then + AC_DEFINE(ETHR_SCHED_YIELD_RET_INT, 1, [Define if sched_yield() returns an int.]) + fi + fi + + have_pthread_yield=no + AC_CHECK_FUNC(pthread_yield, [have_pthread_yield=yes]) + if test $have_pthread_yield = yes; then + AC_DEFINE(ETHR_HAVE_PTHREAD_YIELD, 1, [Define if you have the pthread_yield() function.]) + AC_MSG_CHECKING([whether pthread_yield() returns an int]) + pthread_yield_ret_int=no + AC_TRY_COMPILE([ + #if defined(ETHR_NEED_NPTL_PTHREAD_H) + #include <nptl/pthread.h> + #elif defined(ETHR_HAVE_MIT_PTHREAD_H) + #include <pthread/mit/pthread.h> + #elif defined(ETHR_HAVE_PTHREAD_H) + #include <pthread.h> + #endif + ], + [int pthread_yield();], + [pthread_yield_ret_int=yes]) + AC_MSG_RESULT([$pthread_yield_ret_int]) + if test $pthread_yield_ret_int = yes; then + AC_DEFINE(ETHR_PTHREAD_YIELD_RET_INT, 1, [Define if pthread_yield() returns an int.]) + fi + fi + + have_pthread_rwlock_init=no + AC_CHECK_FUNC(pthread_rwlock_init, [have_pthread_rwlock_init=yes]) + if test $have_pthread_rwlock_init = yes; then + + ethr_have_pthread_rwlockattr_setkind_np=no + AC_CHECK_FUNC(pthread_rwlockattr_setkind_np, + [ethr_have_pthread_rwlockattr_setkind_np=yes]) + + if test $ethr_have_pthread_rwlockattr_setkind_np = yes; then + AC_DEFINE(ETHR_HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP, 1, \ +[Define if you have the pthread_rwlockattr_setkind_np() function.]) + + AC_MSG_CHECKING([for PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP]) + ethr_pthread_rwlock_writer_nonrecursive_initializer_np=no + AC_TRY_LINK([ + #if defined(ETHR_NEED_NPTL_PTHREAD_H) + #include <nptl/pthread.h> + #elif defined(ETHR_HAVE_MIT_PTHREAD_H) + #include <pthread/mit/pthread.h> + #elif defined(ETHR_HAVE_PTHREAD_H) + #include <pthread.h> + #endif + ], + [ + pthread_rwlockattr_t *attr; + return pthread_rwlockattr_setkind_np(attr, + PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); + ], + [ethr_pthread_rwlock_writer_nonrecursive_initializer_np=yes]) + AC_MSG_RESULT([$ethr_pthread_rwlock_writer_nonrecursive_initializer_np]) + if test $ethr_pthread_rwlock_writer_nonrecursive_initializer_np = yes; then + AC_DEFINE(ETHR_HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, 1, \ +[Define if you have the PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP rwlock attribute.]) + fi + fi + fi + + if test "$force_pthread_rwlocks" = "yes"; then + + AC_DEFINE(ETHR_FORCE_PTHREAD_RWLOCK, 1, \ +[Define if you want to force usage of pthread rwlocks]) + + if test $have_pthread_rwlock_init = yes; then + AC_MSG_WARN([Forced usage of pthread rwlocks. Note that this implementation may suffer from starvation issues.]) + else + AC_MSG_ERROR([User forced usage of pthread rwlock, but no such implementation was found]) + fi + fi + + AC_CHECK_FUNC(pthread_attr_setguardsize, \ + AC_DEFINE(ETHR_HAVE_PTHREAD_ATTR_SETGUARDSIZE, 1, \ +[Define if you have the pthread_attr_setguardsize function.])) + + linux_futex=no + AC_MSG_CHECKING([for Linux futexes]) + AC_TRY_LINK([ + #include <sys/syscall.h> + #include <unistd.h> + #include <linux/futex.h> + #include <sys/time.h> + ], + [ + int i = 1; + syscall(__NR_futex, (void *) &i, FUTEX_WAKE, 1, + (void*)0,(void*)0, 0); + syscall(__NR_futex, (void *) &i, FUTEX_WAIT, 0, + (void*)0,(void*)0, 0); + return 0; + ], + linux_futex=yes) + AC_MSG_RESULT([$linux_futex]) + test $linux_futex = yes && AC_DEFINE(ETHR_HAVE_LINUX_FUTEX, 1, [Define if you have a linux futex implementation.]) + + AC_CHECK_SIZEOF(int) + AC_CHECK_SIZEOF(long) + AC_CHECK_SIZEOF(long long) + AC_CHECK_SIZEOF(__int128_t) + + if test "$ac_cv_sizeof_int" = "4"; then + int32="int" + elif test "$ac_cv_sizeof_long" = "4"; then + int32="long" + elif test "$ac_cv_sizeof_long_long" = "4"; then + int32="long long" + else + AC_MSG_ERROR([No 32-bit type found]) + fi + + if test "$ac_cv_sizeof_int" = "8"; then + int64="int" + elif test "$ac_cv_sizeof_long" = "8"; then + int64="long" + elif test "$ac_cv_sizeof_long_long" = "8"; then + int64="long long" + else + AC_MSG_ERROR([No 64-bit type found]) + fi + + int128=no + if test "$ac_cv_sizeof___int128_t" = "16"; then + int128="__int128_t" + fi + + ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP32, 1, [Define if you have __sync_val_compare_and_swap() for 32-bit integers])) + test "$have_sync_op" = "yes" && ethr_have_native_atomics=yes + ETHR_CHK_SYNC_OP([__sync_add_and_fetch], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_ADD_AND_FETCH32, 1, [Define if you have __sync_add_and_fetch() for 32-bit integers])) + ETHR_CHK_SYNC_OP([__sync_fetch_and_and], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_AND32, 1, [Define if you have __sync_fetch_and_and() for 32-bit integers])) + ETHR_CHK_SYNC_OP([__sync_fetch_and_or], [2], [32], [$int32], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_OR32, 1, [Define if you have __sync_fetch_and_or() for 32-bit integers])) + + ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP64, 1, [Define if you have __sync_val_compare_and_swap() for 64-bit integers])) + test "$have_sync_op" = "yes" && ethr_have_native_atomics=yes + ETHR_CHK_SYNC_OP([__sync_add_and_fetch], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_ADD_AND_FETCH64, 1, [Define if you have __sync_add_and_fetch() for 64-bit integers])) + ETHR_CHK_SYNC_OP([__sync_fetch_and_and], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_AND64, 1, [Define if you have __sync_fetch_and_and() for 64-bit integers])) + ETHR_CHK_SYNC_OP([__sync_fetch_and_or], [2], [64], [$int64], AC_DEFINE(ETHR_HAVE___SYNC_FETCH_AND_OR64, 1, [Define if you have __sync_fetch_and_or() for 64-bit integers])) + + if test $int128 != no; then + ETHR_CHK_SYNC_OP([__sync_val_compare_and_swap], [3], [128], [$int128], AC_DEFINE(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP128, 1, [Define if you have __sync_val_compare_and_swap() for 128-bit integers])) + fi + + AC_MSG_CHECKING([for a usable libatomic_ops implementation]) + case "x$with_libatomic_ops" in + xno | xyes | x) + libatomic_ops_include= + ;; + *) + if test -d "${with_libatomic_ops}/include"; then + libatomic_ops_include="-I$with_libatomic_ops/include" + CPPFLAGS="$CPPFLAGS $libatomic_ops_include" + else + AC_MSG_ERROR([libatomic_ops include directory $with_libatomic_ops/include not found]) + fi;; + esac + ethr_have_libatomic_ops=no + AC_TRY_LINK([#include "atomic_ops.h"], + [ + volatile AO_t x; + AO_t y; + int z; + + AO_nop_full(); + AO_store(&x, (AO_t) 0); + z = AO_load(&x); + z = AO_compare_and_swap_full(&x, (AO_t) 0, (AO_t) 1); + ], + [ethr_have_native_atomics=yes + ethr_have_libatomic_ops=yes]) + AC_MSG_RESULT([$ethr_have_libatomic_ops]) + if test $ethr_have_libatomic_ops = yes; then + AC_CHECK_SIZEOF(AO_t, , + [ + #include <stdio.h> + #include "atomic_ops.h" + ]) + AC_DEFINE_UNQUOTED(ETHR_SIZEOF_AO_T, $ac_cv_sizeof_AO_t, [Define to the size of AO_t if libatomic_ops is used]) + + AC_DEFINE(ETHR_HAVE_LIBATOMIC_OPS, 1, [Define if you have libatomic_ops atomic operations]) + if test "x$with_libatomic_ops" != "xno" && test "x$with_libatomic_ops" != "x"; then + AC_DEFINE(ETHR_PREFER_LIBATOMIC_OPS_NATIVE_IMPLS, 1, [Define if you prefer libatomic_ops native ethread implementations]) + fi + ETHR_DEFS="$ETHR_DEFS $libatomic_ops_include" + elif test "x$with_libatomic_ops" != "xno" && test "x$with_libatomic_ops" != "x"; then + AC_MSG_ERROR([No usable libatomic_ops implementation found]) + fi + + case "$host_cpu" in + sparc | sun4u | sparc64 | sun4v) + case "$with_sparc_memory_order" in + "TSO") + AC_DEFINE(ETHR_SPARC_TSO, 1, [Define if only run in Sparc TSO mode]);; + "PSO") + AC_DEFINE(ETHR_SPARC_PSO, 1, [Define if only run in Sparc PSO, or TSO mode]);; + "RMO"|"") + AC_DEFINE(ETHR_SPARC_RMO, 1, [Define if run in Sparc RMO, PSO, or TSO mode]);; + *) + AC_MSG_ERROR([Unsupported Sparc memory order: $with_sparc_memory_order]);; + esac + ethr_have_native_atomics=yes;; + i86pc | i*86 | x86_64 | amd64) + if test "$enable_x86_out_of_order" = "yes"; then + AC_DEFINE(ETHR_X86_OUT_OF_ORDER, 1, [Define if x86/x86_64 out of order instructions should be synchronized]) + fi + ethr_have_native_atomics=yes;; + macppc | ppc | "Power Macintosh") + ethr_have_native_atomics=yes;; + tile) + ethr_have_native_atomics=yes;; + *) + ;; + esac + + test ethr_have_native_atomics = "yes" && ethr_have_native_spinlock=yes + + dnl Restore LIBS + LIBS=$saved_libs + dnl restore CPPFLAGS + CPPFLAGS=$saved_cppflags + + ;; + *) + ;; +esac + +AC_MSG_CHECKING([whether default stack size should be modified]) +if test "x$ethr_modified_default_stack_size" != "x"; then + AC_DEFINE_UNQUOTED(ETHR_MODIFIED_DEFAULT_STACK_SIZE, $ethr_modified_default_stack_size, [Define if you want to modify the default stack size]) + AC_MSG_RESULT([yes; to $ethr_modified_default_stack_size kilo words]) +else + AC_MSG_RESULT([no]) +fi + +if test "x$ETHR_THR_LIB_BASE" != "x"; then + ETHR_DEFS="-DUSE_THREADS $ETHR_DEFS" + ETHR_LIBS="-l$ethr_lib_name -lerts_internal_r $ETHR_X_LIBS" + ETHR_LIB_NAME=$ethr_lib_name +fi + +AC_CHECK_SIZEOF(void *) +AC_DEFINE_UNQUOTED(ETHR_SIZEOF_PTR, $ac_cv_sizeof_void_p, [Define to the size of pointers]) + +AC_CHECK_SIZEOF(int) +AC_DEFINE_UNQUOTED(ETHR_SIZEOF_INT, $ac_cv_sizeof_int, [Define to the size of int]) +AC_CHECK_SIZEOF(long) +AC_DEFINE_UNQUOTED(ETHR_SIZEOF_LONG, $ac_cv_sizeof_long, [Define to the size of long]) +AC_CHECK_SIZEOF(long long) +AC_DEFINE_UNQUOTED(ETHR_SIZEOF_LONG_LONG, $ac_cv_sizeof_long_long, [Define to the size of long long]) +AC_CHECK_SIZEOF(__int64) +AC_DEFINE_UNQUOTED(ETHR_SIZEOF___INT64, $ac_cv_sizeof___int64, [Define to the size of __int64]) +AC_CHECK_SIZEOF(__int128_t) +AC_DEFINE_UNQUOTED(ETHR_SIZEOF___INT128_T, $ac_cv_sizeof___int128_t, [Define to the size of __int128_t]) + + +case X$erl_xcomp_bigendian in + X) ;; + Xyes|Xno) ac_cv_c_bigendian=$erl_xcomp_bigendian;; + *) AC_MSG_ERROR([Bad erl_xcomp_bigendian value: $erl_xcomp_bigendian]);; +esac + +AC_C_BIGENDIAN + +if test "$ac_cv_c_bigendian" = "yes"; then + AC_DEFINE(ETHR_BIGENDIAN, 1, [Define if bigendian]) +fi + +AC_ARG_ENABLE(native-ethr-impls, + AS_HELP_STRING([--disable-native-ethr-impls], + [disable native ethread implementations]), +[ case "$enableval" in + no) disable_native_ethr_impls=yes ;; + *) disable_native_ethr_impls=no ;; + esac ], disable_native_ethr_impls=no) + +AC_ARG_ENABLE(x86-out-of-order, + AS_HELP_STRING([--enable-x86-out-of-order], + [enable x86/x84_64 out of order support (default disabled)])) + +test "X$disable_native_ethr_impls" = "Xyes" && + AC_DEFINE(ETHR_DISABLE_NATIVE_IMPLS, 1, [Define if you want to disable native ethread implementations]) + +AC_ARG_ENABLE(prefer-gcc-native-ethr-impls, + AS_HELP_STRING([--enable-prefer-gcc-native-ethr-impls], + [prefer gcc native ethread implementations]), +[ case "$enableval" in + yes) enable_prefer_gcc_native_ethr_impls=yes ;; + *) enable_prefer_gcc_native_ethr_impls=no ;; + esac ], enable_prefer_gcc_native_ethr_impls=no) + +test $enable_prefer_gcc_native_ethr_impls = yes && + AC_DEFINE(ETHR_PREFER_GCC_NATIVE_IMPLS, 1, [Define if you prefer gcc native ethread implementations]) + +AC_ARG_WITH(libatomic_ops, + AS_HELP_STRING([--with-libatomic_ops=PATH], + [specify and prefer usage of libatomic_ops in the ethread library])) + +AC_ARG_WITH(with_sparc_memory_order, + AS_HELP_STRING([--with-sparc-memory-order=TSO|PSO|RMO], + [specify sparc memory order (defaults to RMO)])) + +ETHR_X86_SSE2_ASM=no +case "$GCC-$ac_cv_sizeof_void_p-$host_cpu" in + yes-4-i86pc | yes-4-i*86 | yes-4-x86_64 | yes-4-amd64) + AC_MSG_CHECKING([for gcc sse2 asm support]) + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -msse2" + gcc_sse2_asm=no + AC_TRY_COMPILE([], + [ + long long x, *y; + __asm__ __volatile__("movq %1, %0\n\t" : "=x"(x) : "m"(*y) : "memory"); + ], + [gcc_sse2_asm=yes]) + CFLAGS="$save_CFLAGS" + AC_MSG_RESULT([$gcc_sse2_asm]) + if test "$gcc_sse2_asm" = "yes"; then + AC_DEFINE(ETHR_GCC_HAVE_SSE2_ASM_SUPPORT, 1, [Define if you use a gcc that supports -msse2 and understand sse2 specific asm statements]) + ETHR_X86_SSE2_ASM=yes + fi + ;; + *) + ;; +esac + +case "$GCC-$host_cpu" in + yes-i86pc | yes-i*86 | yes-x86_64 | yes-amd64) + gcc_dw_cmpxchg_asm=no + AC_MSG_CHECKING([for gcc double word cmpxchg asm support]) + AC_TRY_COMPILE([], + [ + char xchgd; + long new[2], xchg[2], *p; + __asm__ __volatile__( +#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__ + "pushl %%ebx\n\t" + "movl %8, %%ebx\n\t" +#endif +#if ETHR_SIZEOF_PTR == 4 + "lock; cmpxchg8b %0\n\t" +#else + "lock; cmpxchg16b %0\n\t" +#endif + "setz %3\n\t" +#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__ + "popl %%ebx\n\t" +#endif + : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd) + : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "3"(new[1]), +#if ETHR_SIZEOF_PTR == 4 && defined(__PIC__) && __PIC__ + "r"(new[0]) +#else + "b"(new[0]) +#endif + : "cc", "memory"); + + ], + [gcc_dw_cmpxchg_asm=yes]) + if test $gcc_dw_cmpxchg_asm = no && test $ac_cv_sizeof_void_p = 4; then + AC_TRY_COMPILE([], + [ + char xchgd; + long new[2], xchg[2], *p; +#if !defined(__PIC__) || !__PIC__ +# error nope +#endif + __asm__ __volatile__( + "pushl %%ebx\n\t" + "movl (%7), %%ebx\n\t" + "movl 4(%7), %%ecx\n\t" + "lock; cmpxchg8b %0\n\t" + "setz %3\n\t" + "popl %%ebx\n\t" + : "=m"(*p), "=d"(xchg[1]), "=a"(xchg[0]), "=c"(xchgd) + : "m"(*p), "1"(xchg[1]), "2"(xchg[0]), "3"(new) + : "cc", "memory"); + + ], + [gcc_dw_cmpxchg_asm=yes]) + if test "$gcc_dw_cmpxchg_asm" = "yes"; then + AC_DEFINE(ETHR_CMPXCHG8B_REGISTER_SHORTAGE, 1, [Define if you get a register shortage with cmpxchg8b and position independent code]) + fi + fi + AC_MSG_RESULT([$gcc_dw_cmpxchg_asm]) + if test "$gcc_dw_cmpxchg_asm" = "yes"; then + AC_DEFINE(ETHR_GCC_HAVE_DW_CMPXCHG_ASM_SUPPORT, 1, [Define if you use a gcc that supports the double word cmpxchg instruction]) + fi;; + *) + ;; +esac + +AC_DEFINE(ETHR_HAVE_ETHREAD_DEFINES, 1, \ +[Define if you have all ethread defines]) + +AC_SUBST(ETHR_X_LIBS) +AC_SUBST(ETHR_LIBS) +AC_SUBST(ETHR_LIB_NAME) +AC_SUBST(ETHR_DEFS) +AC_SUBST(ETHR_THR_LIB_BASE) +AC_SUBST(ETHR_THR_LIB_BASE_DIR) +AC_SUBST(ETHR_X86_SSE2_ASM) + +]) + + + +dnl ---------------------------------------------------------------------- +dnl +dnl ERL_TIME_CORRECTION +dnl +dnl In the presence of a high resolution realtime timer Erlang can adapt +dnl its view of time relative to this timer. On solaris such a timer is +dnl available with the syscall gethrtime(). On other OS's a fallback +dnl solution using times() is implemented. (However on e.g. FreeBSD times() +dnl is implemented using gettimeofday so it doesn't make much sense to +dnl use it there...) On second thought, it seems to be safer to do it the +dnl other way around. I.e. only use times() on OS's where we know it will +dnl work... +dnl + +AC_DEFUN(ERL_TIME_CORRECTION, +[if test x$ac_cv_func_gethrtime = x; then + AC_CHECK_FUNC(gethrtime) +fi +if test x$clock_gettime_correction = xunknown; then + AC_TRY_COMPILE([#include <time.h>], + [struct timespec ts; + long long result; + clock_gettime(CLOCK_MONOTONIC,&ts); + result = ((long long) ts.tv_sec) * 1000000000LL + + ((long long) ts.tv_nsec);], + clock_gettime_compiles=yes, + clock_gettime_compiles=no) +else + clock_gettime_compiles=no +fi + + +AC_CACHE_CHECK([how to correct for time adjustments], erl_cv_time_correction, +[ +case $clock_gettime_correction in + yes) + erl_cv_time_correction=clock_gettime;; + no|unknown) + case $ac_cv_func_gethrtime in + yes) + erl_cv_time_correction=hrtime ;; + no) + case $host_os in + linux*) + case $clock_gettime_correction in + unknown) + if test x$clock_gettime_compiles = xyes; then + if test X$cross_compiling != Xyes; then + linux_kernel_vsn_=`uname -r` + case $linux_kernel_vsn_ in + [[0-1]].*|2.[[0-5]]|2.[[0-5]].*) + erl_cv_time_correction=times ;; + *) + erl_cv_time_correction=clock_gettime;; + esac + else + case X$erl_xcomp_linux_clock_gettime_correction in + X) + erl_cv_time_correction=cross;; + Xyes|Xno) + if test $erl_xcomp_linux_clock_gettime_correction = yes; then + erl_cv_time_correction=clock_gettime + else + erl_cv_time_correction=times + fi;; + *) + AC_MSG_ERROR([Bad erl_xcomp_linux_clock_gettime_correction value: $erl_xcomp_linux_clock_gettime_correction]);; + esac + fi + else + erl_cv_time_correction=times + fi + ;; + *) + erl_cv_time_correction=times ;; + esac + ;; + *) + erl_cv_time_correction=none ;; + esac + ;; + esac + ;; +esac +]) + +xrtlib="" +case $erl_cv_time_correction in + times) + AC_DEFINE(CORRECT_USING_TIMES,[], + [Define if you do not have a high-res. timer & want to use times() instead]) + ;; + clock_gettime|cross) + if test $erl_cv_time_correction = cross; then + erl_cv_time_correction=clock_gettime + AC_MSG_WARN([result clock_gettime guessed because of cross compilation]) + fi + xrtlib="-lrt" + AC_DEFINE(GETHRTIME_WITH_CLOCK_GETTIME,[1], + [Define if you want to use clock_gettime to simulate gethrtime]) + ;; +esac +dnl +dnl Check if gethrvtime is working, and if to use procfs ioctl +dnl or (yet to be written) write to the procfs ctl file. +dnl + +AC_MSG_CHECKING([if gethrvtime works and how to use it]) +AC_TRY_RUN([ +/* gethrvtime procfs ioctl test */ +/* These need to be undef:ed to not break activation of + * micro level process accounting on /proc/self + */ +#ifdef _LARGEFILE_SOURCE +# undef _LARGEFILE_SOURCE +#endif +#ifdef _FILE_OFFSET_BITS +# undef _FILE_OFFSET_BITS +#endif +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <stdio.h> +#include <sys/time.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/signal.h> +#include <sys/fault.h> +#include <sys/syscall.h> +#include <sys/procfs.h> +#include <fcntl.h> + +int main() { + long msacct = PR_MSACCT; + int fd; + long long start, stop; + int i; + pid_t pid = getpid(); + char proc_self[30] = "/proc/"; + + sprintf(proc_self+strlen(proc_self), "%lu", (unsigned long) pid); + if ( (fd = open(proc_self, O_WRONLY)) == -1) + exit(1); + if (ioctl(fd, PIOCSET, &msacct) < 0) + exit(2); + if (close(fd) < 0) + exit(3); + start = gethrvtime(); + for (i = 0; i < 100; i++) + stop = gethrvtime(); + if (start == 0) + exit(4); + if (start == stop) + exit(5); + exit(0); return 0; +} +], +erl_gethrvtime=procfs_ioctl, +erl_gethrvtime=false, +[ +case X$erl_xcomp_gethrvtime_procfs_ioctl in + X) + erl_gethrvtime=cross;; + Xyes|Xno) + if test $erl_xcomp_gethrvtime_procfs_ioctl = yes; then + erl_gethrvtime=procfs_ioctl + else + erl_gethrvtime=false + fi;; + *) + AC_MSG_ERROR([Bad erl_xcomp_gethrvtime_procfs_ioctl value: $erl_xcomp_gethrvtime_procfs_ioctl]);; +esac +]) + +case $erl_gethrvtime in + procfs_ioctl) + AC_DEFINE(HAVE_GETHRVTIME_PROCFS_IOCTL,[1], + [define if gethrvtime() works and uses ioctl() to /proc/self]) + AC_MSG_RESULT(uses ioctl to procfs) + ;; + *) + if test $erl_gethrvtime = cross; then + erl_gethrvtime=false + AC_MSG_RESULT(cross) + AC_MSG_WARN([result 'not working' guessed because of cross compilation]) + else + AC_MSG_RESULT(not working) + fi + + dnl + dnl Check if clock_gettime (linux) is working + dnl + + AC_MSG_CHECKING([if clock_gettime can be used to get process CPU time]) + save_libs=$LIBS + LIBS="-lrt" + AC_TRY_RUN([ + #include <stdlib.h> + #include <unistd.h> + #include <string.h> + #include <stdio.h> + #include <time.h> + int main() { + long long start, stop; + int i; + struct timespec tp; + + if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp) < 0) + exit(1); + start = ((long long)tp.tv_sec * 1000000000LL) + (long long)tp.tv_nsec; + for (i = 0; i < 100; i++) + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp); + stop = ((long long)tp.tv_sec * 1000000000LL) + (long long)tp.tv_nsec; + if (start == 0) + exit(4); + if (start == stop) + exit(5); + exit(0); return 0; + } + ], + erl_clock_gettime=yes, + erl_clock_gettime=no, + [ + case X$erl_xcomp_clock_gettime_cpu_time in + X) erl_clock_gettime=cross;; + Xyes|Xno) erl_clock_gettime=$erl_xcomp_clock_gettime_cpu_time;; + *) AC_MSG_ERROR([Bad erl_xcomp_clock_gettime_cpu_time value: $erl_xcomp_clock_gettime_cpu_time]);; + esac + ]) + LIBS=$save_libs + case $host_os in + linux*) + AC_MSG_RESULT([no; not stable]) + LIBRT=$xrtlib + ;; + *) + AC_MSG_RESULT($erl_clock_gettime) + case $erl_clock_gettime in + yes) + AC_DEFINE(HAVE_CLOCK_GETTIME,[], + [define if clock_gettime() works for getting process time]) + LIBRT=-lrt + ;; + cross) + erl_clock_gettime=no + AC_MSG_WARN([result no guessed because of cross compilation]) + LIBRT=$xrtlib + ;; + *) + LIBRT=$xrtlib + ;; + esac + ;; + esac + AC_SUBST(LIBRT) + ;; +esac +])dnl + +dnl ERL_TRY_LINK_JAVA(CLASSES, FUNCTION-BODY +dnl [ACTION_IF_FOUND [, ACTION-IF-NOT-FOUND]]) +dnl Freely inspired by AC_TRY_LINK. (Maybe better to create a +dnl AC_LANG_JAVA instead...) +AC_DEFUN(ERL_TRY_LINK_JAVA, +[java_link='$JAVAC conftest.java 1>&AC_FD_CC' +changequote(, )dnl +cat > conftest.java <<EOF +$1 +class conftest { public static void main(String[] args) { + $2 + ; return; }} +EOF +changequote([, ])dnl +if AC_TRY_EVAL(java_link) && test -s conftest.class; then + ifelse([$3], , :, [rm -rf conftest* + $3]) +else + echo "configure: failed program was:" 1>&AC_FD_CC + cat conftest.java 1>&AC_FD_CC + echo "configure: PATH was $PATH" 1>&AC_FD_CC +ifelse([$4], , , [ rm -rf conftest* + $4 +])dnl +fi +rm -f conftest*]) +#define UNSAFE_MASK 0xc0000000 /* Mask for bits that must be constant */ + + diff --git a/lib/wx/api_gen/wx_doxygen.conf b/lib/wx/api_gen/wx_doxygen.conf index df150fd154..829702cbbf 100644 --- a/lib/wx/api_gen/wx_doxygen.conf +++ b/lib/wx/api_gen/wx_doxygen.conf @@ -251,6 +251,7 @@ PREDEFINED = \ wxUSE_DATAOBJ=1 \ wxUSE_SLIDER=1 \ wxUSE_CLIPBOARD=1 \ + wxUSE_SYSTEM_OPTIONS=1 \ wxABI_VERSION=20809 \ __WXGTK24__=1 \ __WXGTK20__=1 \ diff --git a/lib/wx/api_gen/wx_extra/wxEvtHandler.erl b/lib/wx/api_gen/wx_extra/wxEvtHandler.erl index c6810eb32c..080ebfa49f 100644 --- a/lib/wx/api_gen/wx_extra/wxEvtHandler.erl +++ b/lib/wx/api_gen/wx_extra/wxEvtHandler.erl @@ -76,7 +76,7 @@ parse_opts([{callback,Fun}|R], Opts) when is_function(Fun) -> %% Check Fun Arity? parse_opts(R, Opts#evh{cb=Fun}); parse_opts([callback|R], Opts) -> - parse_opts(R, Opts#evh{cb=1}); + parse_opts(R, Opts#evh{cb=self()}); parse_opts([{userData, UserData}|R],Opts) -> parse_opts(R, Opts#evh{userdata=UserData}); parse_opts([{skip, Skip}|R],Opts) when is_boolean(Skip) -> diff --git a/lib/wx/api_gen/wx_gen_cpp.erl b/lib/wx/api_gen/wx_gen_cpp.erl index 4632fdbffe..1b4c32db24 100644 --- a/lib/wx/api_gen/wx_gen_cpp.erl +++ b/lib/wx/api_gen/wx_gen_cpp.erl @@ -1034,6 +1034,7 @@ gen_macros() -> w("#include <wx/html/htmlwin.h>~n"), w("#include <wx/html/htmlcell.h>~n"), w("#include <wx/filename.h>~n"), + w("#include <wx/sysopt.h>~n"), w("~n~n", []), w("#ifndef wxICON_DEFAULT_BITMAP_TYPE~n",[]), diff --git a/lib/wx/api_gen/wx_gen_erl.erl b/lib/wx/api_gen/wx_gen_erl.erl index e882ae87ca..5d73d93ead 100644 --- a/lib/wx/api_gen/wx_gen_erl.erl +++ b/lib/wx/api_gen/wx_gen_erl.erl @@ -830,7 +830,7 @@ doc_arg_type3(#type{base={comp,_,Tup}}) -> Doc = fun({int,V}) -> V ++ "::integer()"; ({double,V}) -> V ++ "::float()" end, - "{" ++ args(Doc, ",", Tup) ++ "}"; + "{" ++ args(Doc, ", ", Tup) ++ "}"; doc_arg_type3(T) -> ?error({unknown_type,T}). doc_return_types(T, Ps) -> @@ -839,9 +839,9 @@ doc_return_types2(void, []) -> "ok"; doc_return_types2(void, [#param{type=T}]) -> doc_arg_type2(T); doc_return_types2(T, []) -> doc_arg_type2(T); doc_return_types2(void, Ps) -> - "{" ++ args(fun doc_arg_type/1,",",Ps) ++ "}"; + "{" ++ args(fun doc_arg_type/1,", ",Ps) ++ "}"; doc_return_types2(T, Ps) -> - "{" ++ doc_arg_type2(T) ++ "," ++ args(fun doc_arg_type/1,",",Ps) ++ "}". + "{" ++ doc_arg_type2(T) ++ ", " ++ args(fun doc_arg_type/1,", ",Ps) ++ "}". break(xhtml) -> "<br />"; break(_) -> "". diff --git a/lib/wx/api_gen/wxapi.conf b/lib/wx/api_gen/wxapi.conf index 8ee4451057..ff618faf04 100644 --- a/lib/wx/api_gen/wxapi.conf +++ b/lib/wx/api_gen/wxapi.conf @@ -1755,6 +1755,9 @@ 'GetColour','GetFont','GetMetric','GetScreenType' ]}. +{class, wxSystemOptions, object, [], + ['GetOption', 'GetOptionInt', 'HasOption', 'IsFalse', 'SetOption']}. + {class, wxAuiNotebookEvent, wxNotifyEvent, [{acc, [{old_selection, "GetOldSelection()"}, {selection, "GetSelection()"}, diff --git a/lib/wx/c_src/Makefile.in b/lib/wx/c_src/Makefile.in index 69418f62ef..ae5a149d14 100644 --- a/lib/wx/c_src/Makefile.in +++ b/lib/wx/c_src/Makefile.in @@ -31,6 +31,8 @@ override TYPE=opt endif SO_EXT = @SO_EXT@ +OBJC_CC=@OBJC_CC@ +OBJC_CFLAGS=@OBJC_CFLAGS@ GENERAL = wxe_driver wxe_ps_init wxe_impl wxePrintout wxe_return wxe_gl GENERAL_H = wxe_driver.h wxe_impl.h wxe_return.h @@ -116,6 +118,7 @@ endif GL_LIBS = @GL_LIBS@ CC_O = $(CC) -c $(CFLAGS) $(WX_CFLAGS) $(COMMON_CFLAGS) +OBJC_CC_O = $(OBJC_CC) -c $(CFLAGS) $(OBJC_CFLAGS) $(WX_CFLAGS) $(COMMON_CFLAGS) CPP_O = $(CPP) -c $(CXX_FLAGS) $(WX_CXX_FLAGS) $(COMMON_CFLAGS) # Targets @@ -152,6 +155,10 @@ $(SYS_TYPE)/%.o: %.c mkdir -p $(SYS_TYPE) $(CC_O) $< -o $@ +$(SYS_TYPE)/wxe_ps_init.o: wxe_ps_init.c + mkdir -p $(SYS_TYPE) + $(OBJC_CC_O) $< -o $@ + $(SYS_TYPE)/%.o: gen/%.cpp mkdir -p $(SYS_TYPE) $(CPP_O) $< -o $@ diff --git a/lib/wx/c_src/egl_impl.cpp b/lib/wx/c_src/egl_impl.cpp index 6d873abc44..1379f07523 100644 --- a/lib/wx/c_src/egl_impl.cpp +++ b/lib/wx/c_src/egl_impl.cpp @@ -70,8 +70,8 @@ typedef char DL_CHAR; # define OPENGL_LIB "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib" # define OPENGLU_LIB "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGLU.dylib" # else -# define OPENGL_LIB "libGL.so" -# define OPENGLU_LIB "libGLU.so" +# define OPENGL_LIB "libGL.so.1" +# define OPENGLU_LIB "libGLU.so.1" # endif #endif extern "C" { @@ -121,7 +121,7 @@ int load_gl_functions() { } } } - dlclose(LIBhandle); + // dlclose(LIBhandle); // fprintf(stderr, "OPENGL library is loaded\r\n"); } else { fprintf(stderr, "Could NOT load OpenGL library: %s\r\n", DLName); @@ -150,7 +150,7 @@ int load_gl_functions() { } } } - dlclose(LIBhandle); + // dlclose(LIBhandle); // fprintf(stderr, "GLU library is loaded\r\n"); } else { fprintf(stderr, "Could NOT load OpenGL GLU library: %s\r\n", DLName); @@ -195,7 +195,7 @@ egl_ogla_error(GLenum errorCode) // msg.Printf(wxT("Tesselation error: %d: "), (int)errorCode); // msg += wxString::FromAscii((char *) err); // send_msg("error", &msg); - fprintf(stderr, "Tesselation error: %d\r\n", (int) errorCode); + fprintf(stderr, "Tesselation error: %d: %s\r\n", (int) errorCode, err); } void CALLBACK @@ -250,7 +250,7 @@ int erl_tess_impl(char* buff, ErlDrvPort port, ErlDrvTermData caller) int *vertices; int num_vertices; GLdouble *n; - int n_pos, AP, res; + int n_pos, AP; num_vertices = * (int *) buff; buff += 8; /* Align */ n = (double *) buff; buff += 8*3; @@ -293,7 +293,7 @@ int erl_tess_impl(char* buff, ErlDrvPort port, ErlDrvTermData caller) rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; // Return tuple {list, Bin} rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; // Result tuple - res = driver_send_term(port,caller,rt,AP); + driver_send_term(port,caller,rt,AP); /* fprintf(stderr, "List %d: %d %d %d \r\n", */ /* res, */ /* n_pos, */ diff --git a/lib/wx/c_src/gen/wxe_events.cpp b/lib/wx/c_src/gen/wxe_events.cpp index b9769318af..cda98bfc3f 100644 --- a/lib/wx/c_src/gen/wxe_events.cpp +++ b/lib/wx/c_src/gen/wxe_events.cpp @@ -266,41 +266,41 @@ void initEventTable() {wxEVT_COMMAND_SPLITTER_DOUBLECLICKED, 218, "command_splitter_doubleclicked"}, {wxEVT_COMMAND_SPLITTER_UNSPLIT, 218, "command_splitter_unsplit"}, {wxEVT_COMMAND_HTML_LINK_CLICKED, 220, "command_html_link_clicked"}, - {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE, 222, "command_auinotebook_page_close"}, - {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, 222, "command_auinotebook_page_changed"}, - {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING, 222, "command_auinotebook_page_changing"}, - {wxEVT_COMMAND_AUINOTEBOOK_BUTTON, 222, "command_auinotebook_button"}, - {wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG, 222, "command_auinotebook_begin_drag"}, - {wxEVT_COMMAND_AUINOTEBOOK_END_DRAG, 222, "command_auinotebook_end_drag"}, - {wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION, 222, "command_auinotebook_drag_motion"}, - {wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND, 222, "command_auinotebook_allow_dnd"}, + {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE, 223, "command_auinotebook_page_close"}, + {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, 223, "command_auinotebook_page_changed"}, + {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING, 223, "command_auinotebook_page_changing"}, + {wxEVT_COMMAND_AUINOTEBOOK_BUTTON, 223, "command_auinotebook_button"}, + {wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG, 223, "command_auinotebook_begin_drag"}, + {wxEVT_COMMAND_AUINOTEBOOK_END_DRAG, 223, "command_auinotebook_end_drag"}, + {wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION, 223, "command_auinotebook_drag_motion"}, + {wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND, 223, "command_auinotebook_allow_dnd"}, #if wxCHECK_VERSION(2,8,5) - {wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN, 222, "command_auinotebook_tab_middle_down"}, + {wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN, 223, "command_auinotebook_tab_middle_down"}, #endif #if wxCHECK_VERSION(2,8,5) - {wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP, 222, "command_auinotebook_tab_middle_up"}, + {wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP, 223, "command_auinotebook_tab_middle_up"}, #endif #if wxCHECK_VERSION(2,8,5) - {wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN, 222, "command_auinotebook_tab_right_down"}, + {wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN, 223, "command_auinotebook_tab_right_down"}, #endif #if wxCHECK_VERSION(2,8,5) - {wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP, 222, "command_auinotebook_tab_right_up"}, + {wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP, 223, "command_auinotebook_tab_right_up"}, #endif #if wxCHECK_VERSION(2,8,5) - {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSED, 222, "command_auinotebook_page_closed"}, + {wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSED, 223, "command_auinotebook_page_closed"}, #endif #if wxCHECK_VERSION(2,8,5) - {wxEVT_COMMAND_AUINOTEBOOK_DRAG_DONE, 222, "command_auinotebook_drag_done"}, + {wxEVT_COMMAND_AUINOTEBOOK_DRAG_DONE, 223, "command_auinotebook_drag_done"}, #endif #if wxCHECK_VERSION(2,8,5) - {wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK, 222, "command_auinotebook_bg_dclick"}, + {wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK, 223, "command_auinotebook_bg_dclick"}, #endif - {wxEVT_AUI_PANE_BUTTON, 223, "aui_pane_button"}, - {wxEVT_AUI_PANE_CLOSE, 223, "aui_pane_close"}, - {wxEVT_AUI_PANE_MAXIMIZE, 223, "aui_pane_maximize"}, - {wxEVT_AUI_PANE_RESTORE, 223, "aui_pane_restore"}, - {wxEVT_AUI_RENDER, 223, "aui_render"}, - {wxEVT_AUI_FIND_MANAGER, 223, "aui_find_manager"}, + {wxEVT_AUI_PANE_BUTTON, 224, "aui_pane_button"}, + {wxEVT_AUI_PANE_CLOSE, 224, "aui_pane_close"}, + {wxEVT_AUI_PANE_MAXIMIZE, 224, "aui_pane_maximize"}, + {wxEVT_AUI_PANE_RESTORE, 224, "aui_pane_restore"}, + {wxEVT_AUI_RENDER, 224, "aui_render"}, + {wxEVT_AUI_FIND_MANAGER, 224, "aui_find_manager"}, {-1, 0, } }; for(int i=0; event_types[i].ev_type != -1; i++) { @@ -778,7 +778,7 @@ case 220: {// wxHtmlLinkEvent rt.addTupleCount(3); break; } -case 222: {// wxAuiNotebookEvent +case 223: {// wxAuiNotebookEvent wxAuiNotebookEvent * ev = (wxAuiNotebookEvent *) event; wxAuiNotebook * GetDragSource = ev->GetDragSource(); evClass = (char*)"wxAuiNotebookEvent"; @@ -790,7 +790,7 @@ case 222: {// wxAuiNotebookEvent rt.addTupleCount(5); break; } -case 223: {// wxAuiManagerEvent +case 224: {// wxAuiManagerEvent wxAuiManagerEvent * ev = (wxAuiManagerEvent *) event; wxAuiManager * GetManager = ev->GetManager(); wxAuiPaneInfo * GetPane = ev->GetPane(); diff --git a/lib/wx/c_src/gen/wxe_funcs.cpp b/lib/wx/c_src/gen/wxe_funcs.cpp index afef2990b4..f456bd3287 100644 --- a/lib/wx/c_src/gen/wxe_funcs.cpp +++ b/lib/wx/c_src/gen/wxe_funcs.cpp @@ -31160,6 +31160,56 @@ case wxSystemSettings_GetScreenType: { // wxSystemSettings::GetScreenType rt.addInt(Result); break; } +case wxSystemOptions_GetOption: { // wxSystemOptions::GetOption + int * nameLen = (int *) bp; bp += 4; + wxString name = wxString(bp, wxConvUTF8); + bp += *nameLen+((8-((4+ *nameLen) & 7)) & 7); + wxString Result = wxSystemOptions::GetOption(name); + rt.add(Result); + break; +} +case wxSystemOptions_GetOptionInt: { // wxSystemOptions::GetOptionInt + int * nameLen = (int *) bp; bp += 4; + wxString name = wxString(bp, wxConvUTF8); + bp += *nameLen+((8-((4+ *nameLen) & 7)) & 7); + int Result = wxSystemOptions::GetOptionInt(name); + rt.addInt(Result); + break; +} +case wxSystemOptions_HasOption: { // wxSystemOptions::HasOption + int * nameLen = (int *) bp; bp += 4; + wxString name = wxString(bp, wxConvUTF8); + bp += *nameLen+((8-((4+ *nameLen) & 7)) & 7); + bool Result = wxSystemOptions::HasOption(name); + rt.addBool(Result); + break; +} +case wxSystemOptions_IsFalse: { // wxSystemOptions::IsFalse + int * nameLen = (int *) bp; bp += 4; + wxString name = wxString(bp, wxConvUTF8); + bp += *nameLen+((8-((4+ *nameLen) & 7)) & 7); + bool Result = wxSystemOptions::IsFalse(name); + rt.addBool(Result); + break; +} +case wxSystemOptions_SetOption_2_1: { // wxSystemOptions::SetOption + int * nameLen = (int *) bp; bp += 4; + wxString name = wxString(bp, wxConvUTF8); + bp += *nameLen+((8-((4+ *nameLen) & 7)) & 7); + int * valueLen = (int *) bp; bp += 4; + wxString value = wxString(bp, wxConvUTF8); + bp += *valueLen+((8-((4+ *valueLen) & 7)) & 7); + wxSystemOptions::SetOption(name,value); + break; +} +case wxSystemOptions_SetOption_2_0: { // wxSystemOptions::SetOption + int * nameLen = (int *) bp; bp += 4; + wxString name = wxString(bp, wxConvUTF8); + bp += *nameLen+((8-((4+ *nameLen) & 7)) & 7); + int * value = (int *) bp; bp += 4; + wxSystemOptions::SetOption(name,(int) *value); + break; +} case wxAuiNotebookEvent_SetSelection: { // wxAuiNotebookEvent::SetSelection wxAuiNotebookEvent *This = (wxAuiNotebookEvent *) getPtr(bp,memenv); bp += 4; int * s = (int *) bp; bp += 4; @@ -31294,7 +31344,7 @@ case wxAuiManagerEvent_CanVeto: { // wxAuiManagerEvent::CanVeto } case wxLogNull_new: { // wxLogNull::wxLogNull wxLogNull * Result = new wxLogNull(); - newPtr((void *) Result, 224, memenv); + newPtr((void *) Result, 225, memenv); rt.addRef(getRef((void *)Result,memenv), "wxLogNull"); break; } @@ -31347,7 +31397,7 @@ void WxeApp::delete_object(void *ptr, wxeRefData *refd) { case 212: /* delete (wxFileDataObject *) ptr;These objects must be deleted by owner object */ break; case 213: /* delete (wxTextDataObject *) ptr;These objects must be deleted by owner object */ break; case 214: /* delete (wxBitmapDataObject *) ptr;These objects must be deleted by owner object */ break; - case 224: delete (wxLogNull *) ptr; break; + case 225: delete (wxLogNull *) ptr; break; default: delete (wxObject *) ptr; }} diff --git a/lib/wx/c_src/gen/wxe_macros.h b/lib/wx/c_src/gen/wxe_macros.h index be0481564f..ddc7c0155f 100644 --- a/lib/wx/c_src/gen/wxe_macros.h +++ b/lib/wx/c_src/gen/wxe_macros.h @@ -60,6 +60,7 @@ #include <wx/html/htmlwin.h> #include <wx/html/htmlcell.h> #include <wx/filename.h> +#include <wx/sysopt.h> #ifndef wxICON_DEFAULT_BITMAP_TYPE @@ -3318,25 +3319,31 @@ #define wxSystemSettings_GetFont 3489 #define wxSystemSettings_GetMetric 3490 #define wxSystemSettings_GetScreenType 3491 -#define wxAuiNotebookEvent_SetSelection 3492 -#define wxAuiNotebookEvent_GetSelection 3493 -#define wxAuiNotebookEvent_SetOldSelection 3494 -#define wxAuiNotebookEvent_GetOldSelection 3495 -#define wxAuiNotebookEvent_SetDragSource 3496 -#define wxAuiNotebookEvent_GetDragSource 3497 -#define wxAuiManagerEvent_SetManager 3498 -#define wxAuiManagerEvent_GetManager 3499 -#define wxAuiManagerEvent_SetPane 3500 -#define wxAuiManagerEvent_GetPane 3501 -#define wxAuiManagerEvent_SetButton 3502 -#define wxAuiManagerEvent_GetButton 3503 -#define wxAuiManagerEvent_SetDC 3504 -#define wxAuiManagerEvent_GetDC 3505 -#define wxAuiManagerEvent_Veto 3506 -#define wxAuiManagerEvent_GetVeto 3507 -#define wxAuiManagerEvent_SetCanVeto 3508 -#define wxAuiManagerEvent_CanVeto 3509 -#define wxLogNull_new 3510 -#define wxLogNull_destroy 3511 +#define wxSystemOptions_GetOption 3492 +#define wxSystemOptions_GetOptionInt 3493 +#define wxSystemOptions_HasOption 3494 +#define wxSystemOptions_IsFalse 3495 +#define wxSystemOptions_SetOption_2_1 3496 +#define wxSystemOptions_SetOption_2_0 3497 +#define wxAuiNotebookEvent_SetSelection 3498 +#define wxAuiNotebookEvent_GetSelection 3499 +#define wxAuiNotebookEvent_SetOldSelection 3500 +#define wxAuiNotebookEvent_GetOldSelection 3501 +#define wxAuiNotebookEvent_SetDragSource 3502 +#define wxAuiNotebookEvent_GetDragSource 3503 +#define wxAuiManagerEvent_SetManager 3504 +#define wxAuiManagerEvent_GetManager 3505 +#define wxAuiManagerEvent_SetPane 3506 +#define wxAuiManagerEvent_GetPane 3507 +#define wxAuiManagerEvent_SetButton 3508 +#define wxAuiManagerEvent_GetButton 3509 +#define wxAuiManagerEvent_SetDC 3510 +#define wxAuiManagerEvent_GetDC 3511 +#define wxAuiManagerEvent_Veto 3512 +#define wxAuiManagerEvent_GetVeto 3513 +#define wxAuiManagerEvent_SetCanVeto 3514 +#define wxAuiManagerEvent_CanVeto 3515 +#define wxLogNull_new 3516 +#define wxLogNull_destroy 3517 diff --git a/lib/wx/c_src/wxe_impl.cpp b/lib/wx/c_src/wxe_impl.cpp index e430fbc7a2..69fcd4e362 100644 --- a/lib/wx/c_src/wxe_impl.cpp +++ b/lib/wx/c_src/wxe_impl.cpp @@ -331,9 +331,9 @@ void handle_event_callback(ErlDrvPort port, ErlDrvTermData process) driver_monitor_process(port, process, &monitor); // Should we be able to handle commands when recursing? probably erl_drv_mutex_lock(wxe_batch_locker_m); - // fprintf(stderr, "\r\nCB EV Start ");fflush(stderr); + //fprintf(stderr, "\r\nCB EV Start %lu \r\n", process);fflush(stderr); app->dispatch_cb(wxe_batch, wxe_batch_cb_saved, process); - // fprintf(stderr, ".. done \r\n");fflush(stderr); + //fprintf(stderr, "CB EV done %lu \r\n", process);fflush(stderr); wxe_batch_caller = 0; erl_drv_mutex_unlock(wxe_batch_locker_m); driver_demonitor_process(port, &monitor); @@ -430,8 +430,9 @@ void WxeApp::dispatch_cb(wxList * batch, wxList * temp, ErlDrvTermData process) wxeCommand *event = (wxeCommand *)node->GetData(); wxeMemEnv *memenv = getMemEnv(event->port); batch->Erase(node); + // fprintf(stderr, " Ev %d %lu\r\n", event->op, event->caller); if(event->caller == process || // Callbacks from CB process only - event->op == WXE_CB_START || // Recursive event callback allow + event->op == WXE_CB_START || // Event callback start change process // Allow connect_cb during CB i.e. msg from wxe_server. (memenv && event->caller == memenv->owner)) { @@ -453,6 +454,7 @@ void WxeApp::dispatch_cb(wxList * batch, wxList * temp, ErlDrvTermData process) break; default: erl_drv_mutex_unlock(wxe_batch_locker_m); + size_t start=temp->GetCount(); if(event->op < OPENGL_START) { // fprintf(stderr, " cb %d \r\n", event->op); wxe_dispatch(*event); @@ -460,9 +462,23 @@ void WxeApp::dispatch_cb(wxList * batch, wxList * temp, ErlDrvTermData process) gl_dispatch(event->op,event->buffer,event->caller,event->bin); } erl_drv_mutex_lock(wxe_batch_locker_m); - break; + if(temp->GetCount() > start) { + // We have recursed dispatch_cb and messages for this + // callback may be saved on temp list move them + // to orig list + for(wxList::compatibility_iterator node = temp->Item(start); + node; + node = node->GetNext()) { + wxeCommand *ev = (wxeCommand *)node->GetData(); + if(ev->caller == process) { + batch->Append(ev); + temp->Erase(node); + } + } + } if(callback_returned) return; + break; } delete event; } else { diff --git a/lib/wx/configure.in b/lib/wx/configure.in index f7128db23a..e00d5cba98 100755 --- a/lib/wx/configure.in +++ b/lib/wx/configure.in @@ -67,55 +67,14 @@ AC_PROG_RANLIB AC_PROG_CPP AC_MSG_NOTICE(Building for [$host_os]) -MIXED_CYGWIN=no WXERL_CAN_BUILD_DRIVER=true -AC_MSG_CHECKING(for mixed cygwin and native VC++ environment) -if test "X$CC" = "Xcc.sh" -a "X$host" = "Xwin32" -a "x$GCC" != x"yes"; then - if test -x /usr/bin/cygpath; then - CFLAGS="-Owx" - MIXED_CYGWIN=yes - AC_MSG_RESULT([yes]) - MIXED_CYGWIN_VC=yes - CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_VC" - else - AC_MSG_RESULT([undeterminable]) - AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!) - fi -else - AC_MSG_RESULT([no]) - MIXED_CYGWIN_VC=no -fi -AC_SUBST(MIXED_CYGWIN_VC) - -AC_MSG_CHECKING(for mixed cygwin and native MinGW environment) -if test "X$CC" = "Xcc.sh" -a "X$host" = "Xwin32" -a "x$GCC" = x"yes"; then - if test -x /usr/bin/cygpath; then - CFLAGS="-O2" - MIXED_CYGWIN=yes - AC_MSG_RESULT([yes]) - MIXED_CYGWIN_MINGW=yes - CPPFLAGS="$CPPFLAGS -DERTS_MIXED_CYGWIN_MINGW" - else - AC_MSG_RESULT([undeterminable]) - AC_MSG_ERROR(Seems to be mixed windows but not with cygwin, cannot handle this!) - fi -else - AC_MSG_RESULT([no]) - MIXED_CYGWIN_MINGW=no -fi -AC_SUBST(MIXED_CYGWIN_MINGW) +LM_WINDOWS_ENVIRONMENT -AC_MSG_CHECKING(if we mix cygwin with any native compiler) -if test "X$MIXED_CYGWIN" = "Xyes" ; then - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) +if test X"$MIXED_CYGWIN_VC" == X"yes" -o X"$MIXED_MSYS_VC" == X"yes"; then + CFLAGS="-Owx" fi -AC_SUBST(MIXED_CYGWIN) - - ## Check that we are in 32 bits mode on darwin ## (wxWidgets require that it currently uses 32-bits Carbon) ## Otherwise skip building wxErlang @@ -138,10 +97,65 @@ esac PTHR_CFLAGS="-D_THREAD_SAFE -D_REENTRANT" +OBJC_CC=$CC +OBJC_CFLAGS="" + dnl NOTE: CPPFLAGS will be included in CFLAGS at the end case $host_os in darwin*) - C_ONLY_FLAGS="-ObjC" + AC_MSG_CHECKING([if compiler accepts -ObjC]) + saved_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -ObjC" + AC_TRY_COMPILE([],[;], accept_objc_flag=true, accept_objc_flag=false) + if test "X$accept_objc_flag" = "Xtrue"; then + AC_MSG_RESULT([yes]) + C_ONLY_FLAGS="-ObjC" + else + dnl We are probebly trying to build with a non-Apple gcc, + dnl which is good as long as we do not try to build Cocoa + dnl code. We need an Apple compiler for just that (Objective C) + AC_MSG_RESULT([no]) + AC_MSG_CHECKING([for a Cocoa compliant Objective C compiler]) + SEARCHFOR="" + save_IFS=$IFS + IFS=: + set $PATH + IFS=$save_IFS + while test X"$1" != X""; do + dnl Add all possible paths to a real apple gcc + SEARCHFOR="$1/gcc-apple-4.2 $SEARCHFOR" + shift + done + dnl Add LLVM compilers, they will work in this case + SEARCHFOR="/usr/bin/clang /usr/bin/gcc $SEARCHFOR" + APPLE_CC="" + dnl SEARCHFOR is reversed, so we want to find the last existing + dnl executable in the list + for x in $SEARCHFOR; do + if test -x $x; then + APPLE_CC=$x + fi + done + if test X$APPLE_CC = X; then + AC_MSG_RESULT([no]) + dnl Complete failure, we cannot build Cocoa code + if test X"$WX_BUILDING_INSIDE_ERLSRC" != X"true" ; then + AC_MSG_ERROR([Can not find compiler to compile Cocoa applications]) + else + echo "Can not find compiler to compile Cocoa applications" > ./CONF_INFO + WXERL_CAN_BUILD_DRIVER=false + AC_MSG_WARN([Can not find compiler to compile Cocoa applications]) + fi + WXERL_CAN_BUILD_DRIVER=false + else + dnl We think we found an Apple compiler and will add + dnl Apple specific options + AC_MSG_RESULT($APPLE_CC) + OBJC_CC=$APPLE_CC + OBJC_CFLAGS="-ObjC" + fi + fi + CFLAGS=$saved_CFLAGS CPPFLAGS="$CPPFLAGS -D_MACOSX $PTHR_CFLAGS" ;; mingw32) @@ -159,10 +173,16 @@ case $host_os in ;; esac +AC_SUBST(OBJC_CC) +AC_SUBST(OBJC_CFLAGS) + case $host_os in darwin*) - CFLAGS="-no-cpp-precomp $CFLAGS" LDFLAGS="-bundle -flat_namespace -undefined warning -fPIC $LDFLAGS" + # Check sizof_void_p as future will hold 64bit MacOS wx + if test $ac_cv_sizeof_void_p = 4; then + LDFLAGS="-m32 $LDFLAGS" + fi GL_LIBS="-framework OpenGL" ;; win32) @@ -287,7 +307,7 @@ dnl if test "$cross_compiling" = "yes"; then echo "Cross compilation of the wx driver is not supported yet, wx will NOT be usable" > ./CONF_INFO WXERL_CAN_BUILD_DRIVER=false -elif test X"$MIXED_CYGWIN_VC" != X"yes" ; then +elif test X"$MIXED_CYGWIN_VC" == X"no" -a X"$MIXED_MSYS_VC" == X"no"; then m4_include(wxwin.m4) AM_OPTIONS_WXCONFIG @@ -357,7 +377,11 @@ define(wx_warn_text,[ else AC_MSG_CHECKING(for wxWidgets in standard locations) - CWXWIN_CONFIG=`cygpath $wx_config_name 2>/dev/null` + if test "x$MIXED_MSYS" = "xyes"; then + CWXWIN_CONFIG=`win2msys_path.sh $wx_config_name 2>/dev/null` + else + CWXWIN_CONFIG=`cygpath $wx_config_name 2>/dev/null` + fi CWXWIN1=`dirname $CWXWIN_CONFIG 2>/dev/null` CWXWIN2=`dirname $CWXWIN1 2>/dev/null` @@ -365,10 +389,24 @@ else PROGRAMFILES=c:/Program Files fi - CWXWIN_PROG=`cygpath -d "$PROGRAMFILES" | cygpath -f - 2>/dev/null` + + if test "x$MIXED_MSYS" = "xyes"; then + CWXWIN_PROG=`win2msys_path.sh "$PROGRAMFILES" 2>/dev/null` + else + CWXWIN_PROG=`cygpath -d "$PROGRAMFILES" | cygpath -f - 2>/dev/null` + fi CWXWIN3=$CWXWIN_PROG/wxWidgets-2.8 CWXWIN4=$CWXWIN_PROG/wxMSW-2.8 CWX_DOCUMENTED="/opt/local/pgm/wxMSW-2.8.* /opt/local/pgm/wxWidgets-2.8.*" + case $ac_cv_sizeof_void_p in + 8) + CWX_DOCUMENTED="/opt/local64/pgm/wxMSW-2.8.* /opt/local64/pgm/wxWidgets-2.8.* $CWX_DOCUMENTED" + ;; + *) + true + ;; + esac + CWXPATH="$CWXWIN1 $CWXWIN2 $CWX_DOCUMENTED $CWXWIN3.* $CWXWIN4.*" for dir in $CWXPATH; do @@ -377,11 +415,11 @@ else WXINCLUDE_PLAIN=$dir/include WXINCLUDE_CONTRIB=$dir/contrib/include WX_CFLAGS="-EHsc -D_UNICODE -DUNICODE -I$WXINCLUDE_MSVC -I$WXINCLUDE_PLAIN -I$WXINCLUDE_CONTRIB -D__WXMSW__" - WX_CXXFLAGS=$WX_CFLAGS + WX_CXXFLAGS="-TP $WX_CFLAGS" WX_LIBDIR=$dir/lib/vc_lib WX_RESCOMP="rc.sh -I$WXINCLUDE_PLAIN -D __WIN32__" RC_FILE_TYPE=res - for lib in $WX_LIBDIR/wxbase*.lib; do + for lib in $WX_LIBDIR/wxbase*.lib $WX_LIBDIR2/wxbase*.lib; do maybe=`echo $lib | egrep 'wxbase[[0-9]]*u\.lib'` if test '!' -z "$maybe"; then corelib_number=`echo $maybe | sed 's,.*\([[0-9]].\)u\.lib,\1,'` @@ -515,7 +553,7 @@ AC_CHECK_HEADERS([wx/stc/stc.h], [], [WXERL_CAN_BUILD_DRIVER=false echo "wxWidgets don't have wxStyledTextControl (stc.h), wx will NOT be useable" > ./CONF_INFO - AC_MSG_WARN([Can not find wx/stc/stc.h]) + AC_MSG_WARN([Can not find wx/stc/stc.h $CXXFLAGS]) ], [#ifdef WIN32 # include <windows.h> diff --git a/lib/wx/include/wx.hrl b/lib/wx/include/wx.hrl index 8659b71985..029b9a88df 100644 --- a/lib/wx/include/wx.hrl +++ b/lib/wx/include/wx.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -36,12 +36,12 @@ %% Callback event: {@link wxNavigationKeyEvent} -record(wxNavigationKey,{type, flags,focus}). -%% @type wxSash() = #wxSash{type=wxEventType(),edge=WxSashEdgePosition,dragRect={X::integer(),Y::integer(),W::integer(),H::integer()},dragStatus=WxSashDragStatus}. +%% @type wxSash() = #wxSash{type=wxEventType(),edge=WxSashEdgePosition,dragRect={X::integer(), Y::integer(), W::integer(), H::integer()},dragStatus=WxSashDragStatus}. %% <dl><dt>EventType:</dt> <dd><em>sash_dragged</em></dd></dl> %% Callback event: {@link wxSashEvent} -record(wxSash,{type, edge,dragRect,dragStatus}). -%% @type wxList() = #wxList{type=wxEventType(),code=integer(),oldItemIndex=integer(),itemIndex=integer(),col=integer(),pointDrag={X::integer(),Y::integer()}}. +%% @type wxList() = #wxList{type=wxEventType(),code=integer(),oldItemIndex=integer(),itemIndex=integer(),col=integer(),pointDrag={X::integer(), Y::integer()}}. %% <dl><dt>EventType:</dt> <dd><em>command_list_begin_drag</em>, <em>command_list_begin_rdrag</em>, <em>command_list_begin_label_edit</em>, <em>command_list_end_label_edit</em>, <em>command_list_delete_item</em>, <em>command_list_delete_all_items</em>, <em>command_list_key_down</em>, <em>command_list_insert_item</em>, <em>command_list_col_click</em>, <em>command_list_col_right_click</em>, <em>command_list_col_begin_drag</em>, <em>command_list_col_dragging</em>, <em>command_list_col_end_drag</em>, <em>command_list_item_selected</em>, <em>command_list_item_deselected</em>, <em>command_list_item_right_click</em>, <em>command_list_item_middle_click</em>, <em>command_list_item_activated</em>, <em>command_list_item_focused</em>, <em>command_list_cache_hint</em></dd></dl> %% Callback event: {@link wxListEvent} -record(wxList,{type, code,oldItemIndex,itemIndex,col,pointDrag}). @@ -186,7 +186,7 @@ %% Callback event: {@link wxUpdateUIEvent} -record(wxUpdateUI, {type}). -%% @type wxSize() = #wxSize{type=wxEventType(),size={W::integer(),H::integer()},rect={X::integer(),Y::integer(),W::integer(),H::integer()}}. +%% @type wxSize() = #wxSize{type=wxEventType(),size={W::integer(), H::integer()},rect={X::integer(), Y::integer(), W::integer(), H::integer()}}. %% <dl><dt>EventType:</dt> <dd><em>size</em></dd></dl> %% Callback event: {@link wxSizeEvent} -record(wxSize,{type, size,rect}). @@ -261,7 +261,7 @@ %% Callback event: {@link wxColourPickerEvent} -record(wxColourPicker,{type, colour}). -%% @type wxTree() = #wxTree{type=wxEventType(),item=integer(),itemOld=integer(),pointDrag={X::integer(),Y::integer()}}. +%% @type wxTree() = #wxTree{type=wxEventType(),item=integer(),itemOld=integer(),pointDrag={X::integer(), Y::integer()}}. %% <dl><dt>EventType:</dt> <dd><em>command_tree_begin_drag</em>, <em>command_tree_begin_rdrag</em>, <em>command_tree_begin_label_edit</em>, <em>command_tree_end_label_edit</em>, <em>command_tree_delete_item</em>, <em>command_tree_get_info</em>, <em>command_tree_set_info</em>, <em>command_tree_item_expanded</em>, <em>command_tree_item_expanding</em>, <em>command_tree_item_collapsed</em>, <em>command_tree_item_collapsing</em>, <em>command_tree_sel_changed</em>, <em>command_tree_sel_changing</em>, <em>command_tree_key_down</em>, <em>command_tree_item_activated</em>, <em>command_tree_item_right_click</em>, <em>command_tree_item_middle_click</em>, <em>command_tree_end_drag</em>, <em>command_tree_state_image_click</em>, <em>command_tree_item_gettooltip</em>, <em>command_tree_item_menu</em></dd></dl> %% Callback event: {@link wxTreeEvent} -record(wxTree,{type, item,itemOld,pointDrag}). diff --git a/lib/wx/src/gen/wxArtProvider.erl b/lib/wx/src/gen/wxArtProvider.erl index 7a45b0d79d..1955bd2e29 100644 --- a/lib/wx/src/gen/wxArtProvider.erl +++ b/lib/wx/src/gen/wxArtProvider.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -39,7 +39,7 @@ getBitmap(Id) getBitmap(Id, []). %% @spec (Id::string(), [Option]) -> wxBitmap:wxBitmap() -%% Option = {client, string()} | {size, {W::integer(),H::integer()}} +%% Option = {client, string()} | {size, {W::integer(), H::integer()}} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxartprovider.html#wxartprovidergetbitmap">external documentation</a>. getBitmap(Id, Options) when is_list(Id),is_list(Options) -> @@ -58,7 +58,7 @@ getIcon(Id) getIcon(Id, []). %% @spec (Id::string(), [Option]) -> wxIcon:wxIcon() -%% Option = {client, string()} | {size, {W::integer(),H::integer()}} +%% Option = {client, string()} | {size, {W::integer(), H::integer()}} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxartprovider.html#wxartprovidergeticon">external documentation</a>. getIcon(Id, Options) when is_list(Id),is_list(Options) -> diff --git a/lib/wx/src/gen/wxAuiManager.erl b/lib/wx/src/gen/wxAuiManager.erl index ad0af6652d..893867cec1 100644 --- a/lib/wx/src/gen/wxAuiManager.erl +++ b/lib/wx/src/gen/wxAuiManager.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -91,7 +91,7 @@ addPane(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=WindowT,ref=WindowRef},#wx_ wxe_util:call(?wxAuiManager_AddPane_2_1, <<ThisRef:32/?UI,WindowRef:32/?UI,Pane_infoRef:32/?UI>>). -%% @spec (This::wxAuiManager(), Window::wxWindow:wxWindow(), Pane_info::wxAuiPaneInfo:wxAuiPaneInfo(), Drop_pos::{X::integer(),Y::integer()}) -> bool() +%% @spec (This::wxAuiManager(), Window::wxWindow:wxWindow(), Pane_info::wxAuiPaneInfo:wxAuiPaneInfo(), Drop_pos::{X::integer(), Y::integer()}) -> bool() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxauimanager.html#wxauimanageraddpane">external documentation</a>. addPane(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=WindowT,ref=WindowRef},#wx_ref{type=Pane_infoT,ref=Pane_infoRef},{Drop_posX,Drop_posY}) when is_integer(Drop_posX),is_integer(Drop_posY) -> @@ -123,7 +123,7 @@ getArtProvider(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxAuiManager_GetArtProvider, <<ThisRef:32/?UI>>). -%% @spec (This::wxAuiManager()) -> {Width_pct::float(),Height_pct::float()} +%% @spec (This::wxAuiManager()) -> {Width_pct::float(), Height_pct::float()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxauimanager.html#wxauimanagergetdocksizeconstraint">external documentation</a>. getDockSizeConstraint(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxAuiManager), @@ -275,7 +275,7 @@ setManagedWindow(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=Managed_wndT,ref=M wxe_util:cast(?wxAuiManager_SetManagedWindow, <<ThisRef:32/?UI,Managed_wndRef:32/?UI>>). -%% @spec (This::wxAuiManager(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}) -> ok +%% @spec (This::wxAuiManager(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxauimanager.html#wxauimanagershowhint">external documentation</a>. showHint(#wx_ref{type=ThisT,ref=ThisRef},{RectX,RectY,RectW,RectH}) when is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH) -> diff --git a/lib/wx/src/gen/wxAuiNotebook.erl b/lib/wx/src/gen/wxAuiNotebook.erl index 5d486aeaa2..5862bb26c7 100644 --- a/lib/wx/src/gen/wxAuiNotebook.erl +++ b/lib/wx/src/gen/wxAuiNotebook.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -92,7 +92,7 @@ new(Parent) new(Parent, []). %% @spec (Parent::wxWindow:wxWindow(), [Option]) -> wxAuiNotebook() -%% Option = {id, integer()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {id, integer()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxauinotebook.html#wxauinotebookwxauinotebook">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef}, Options) when is_list(Options) -> @@ -134,7 +134,7 @@ create(This,Parent) create(This,Parent, []). %% @spec (This::wxAuiNotebook(), Parent::wxWindow:wxWindow(), [Option]) -> bool() -%% Option = {id, integer()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {id, integer()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxauinotebook.html#wxauinotebookcreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef}, Options) when is_list(Options) -> @@ -289,7 +289,7 @@ setTabCtrlHeight(#wx_ref{type=ThisT,ref=ThisRef},Height) wxe_util:cast(?wxAuiNotebook_SetTabCtrlHeight, <<ThisRef:32/?UI,Height:32/?UI>>). -%% @spec (This::wxAuiNotebook(), Size::{W::integer(),H::integer()}) -> ok +%% @spec (This::wxAuiNotebook(), Size::{W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxauinotebook.html#wxauinotebooksetuniformbitmapsize">external documentation</a>. setUniformBitmapSize(#wx_ref{type=ThisT,ref=ThisRef},{SizeW,SizeH}) when is_integer(SizeW),is_integer(SizeH) -> diff --git a/lib/wx/src/gen/wxAuiPaneInfo.erl b/lib/wx/src/gen/wxAuiPaneInfo.erl index 7b1401b069..b15f91c675 100644 --- a/lib/wx/src/gen/wxAuiPaneInfo.erl +++ b/lib/wx/src/gen/wxAuiPaneInfo.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -60,7 +60,7 @@ new(#wx_ref{type=CT,ref=CRef}) -> wxe_util:construct(?wxAuiPaneInfo_new_1, <<CRef:32/?UI>>). -%% @spec (This::wxAuiPaneInfo(), Size::{W::integer(),H::integer()}) -> wxAuiPaneInfo() +%% @spec (This::wxAuiPaneInfo(), Size::{W::integer(), H::integer()}) -> wxAuiPaneInfo() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxauipaneinfo.html#wxauipaneinfobestsize">external documentation</a>. bestSize(#wx_ref{type=ThisT,ref=ThisRef},{SizeW,SizeH}) when is_integer(SizeW),is_integer(SizeH) -> @@ -250,7 +250,7 @@ floatable(#wx_ref{type=ThisT,ref=ThisRef}, Options) wxe_util:call(?wxAuiPaneInfo_Floatable, <<ThisRef:32/?UI, 0:32,BinOpt/binary>>). -%% @spec (This::wxAuiPaneInfo(), Pos::{X::integer(),Y::integer()}) -> wxAuiPaneInfo() +%% @spec (This::wxAuiPaneInfo(), Pos::{X::integer(), Y::integer()}) -> wxAuiPaneInfo() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxauipaneinfo.html#wxauipaneinfofloatingposition">external documentation</a>. floatingPosition(#wx_ref{type=ThisT,ref=ThisRef},{PosX,PosY}) when is_integer(PosX),is_integer(PosY) -> @@ -266,7 +266,7 @@ floatingPosition(#wx_ref{type=ThisT,ref=ThisRef},X,Y) wxe_util:call(?wxAuiPaneInfo_FloatingPosition_2, <<ThisRef:32/?UI,X:32/?UI,Y:32/?UI>>). -%% @spec (This::wxAuiPaneInfo(), Size::{W::integer(),H::integer()}) -> wxAuiPaneInfo() +%% @spec (This::wxAuiPaneInfo(), Size::{W::integer(), H::integer()}) -> wxAuiPaneInfo() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxauipaneinfo.html#wxauipaneinfofloatingsize">external documentation</a>. floatingSize(#wx_ref{type=ThisT,ref=ThisRef},{SizeW,SizeH}) when is_integer(SizeW),is_integer(SizeH) -> @@ -513,7 +513,7 @@ leftDockable(#wx_ref{type=ThisT,ref=ThisRef}, Options) wxe_util:call(?wxAuiPaneInfo_LeftDockable, <<ThisRef:32/?UI, 0:32,BinOpt/binary>>). -%% @spec (This::wxAuiPaneInfo(), Size::{W::integer(),H::integer()}) -> wxAuiPaneInfo() +%% @spec (This::wxAuiPaneInfo(), Size::{W::integer(), H::integer()}) -> wxAuiPaneInfo() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxauipaneinfo.html#wxauipaneinfomaxsize">external documentation</a>. maxSize(#wx_ref{type=ThisT,ref=ThisRef},{SizeW,SizeH}) when is_integer(SizeW),is_integer(SizeH) -> @@ -547,7 +547,7 @@ maximizeButton(#wx_ref{type=ThisT,ref=ThisRef}, Options) wxe_util:call(?wxAuiPaneInfo_MaximizeButton, <<ThisRef:32/?UI, 0:32,BinOpt/binary>>). -%% @spec (This::wxAuiPaneInfo(), Size::{W::integer(),H::integer()}) -> wxAuiPaneInfo() +%% @spec (This::wxAuiPaneInfo(), Size::{W::integer(), H::integer()}) -> wxAuiPaneInfo() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxauipaneinfo.html#wxauipaneinfominsize">external documentation</a>. minSize(#wx_ref{type=ThisT,ref=ThisRef},{SizeW,SizeH}) when is_integer(SizeW),is_integer(SizeH) -> diff --git a/lib/wx/src/gen/wxBitmap.erl b/lib/wx/src/gen/wxBitmap.erl index 53c57e4393..bd2f83c6eb 100644 --- a/lib/wx/src/gen/wxBitmap.erl +++ b/lib/wx/src/gen/wxBitmap.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -194,7 +194,7 @@ getWidth(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxBitmap_GetWidth, <<ThisRef:32/?UI>>). -%% @spec (This::wxBitmap(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}) -> wxBitmap() +%% @spec (This::wxBitmap(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}) -> wxBitmap() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxbitmap.html#wxbitmapgetsubbitmap">external documentation</a>. getSubBitmap(#wx_ref{type=ThisT,ref=ThisRef},{RectX,RectY,RectW,RectH}) when is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH) -> diff --git a/lib/wx/src/gen/wxBitmapButton.erl b/lib/wx/src/gen/wxBitmapButton.erl index 0c187bf1c1..d2353466e7 100644 --- a/lib/wx/src/gen/wxBitmapButton.erl +++ b/lib/wx/src/gen/wxBitmapButton.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -92,7 +92,7 @@ new(Parent,Id,Bitmap) new(Parent,Id,Bitmap, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), Bitmap::wxBitmap:wxBitmap(), [Option]) -> wxBitmapButton() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxbitmapbutton.html#wxbitmapbuttonwxbitmapbutton">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id,#wx_ref{type=BitmapT,ref=BitmapRef}, Options) when is_integer(Id),is_list(Options) -> @@ -114,7 +114,7 @@ create(This,Parent,Id,Bitmap) create(This,Parent,Id,Bitmap, []). %% @spec (This::wxBitmapButton(), Parent::wxWindow:wxWindow(), Id::integer(), Bitmap::wxBitmap:wxBitmap(), [Option]) -> bool() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxbitmapbutton.html#wxbitmapbuttoncreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,#wx_ref{type=BitmapT,ref=BitmapRef}, Options) when is_integer(Id),is_list(Options) -> diff --git a/lib/wx/src/gen/wxBufferedDC.erl b/lib/wx/src/gen/wxBufferedDC.erl index 6e341a8552..9096f95612 100644 --- a/lib/wx/src/gen/wxBufferedDC.erl +++ b/lib/wx/src/gen/wxBufferedDC.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -74,7 +74,7 @@ new(Dc) %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxbuffereddc.html#wxbuffereddcwxbuffereddc">external documentation</a>. %% <br /> Alternatives: %% <p><c> -%% new(Dc::wxDC:wxDC(), Area::{W::integer(),H::integer()}) -> new(Dc,Area, []) </c></p> +%% new(Dc::wxDC:wxDC(), Area::{W::integer(), H::integer()}) -> new(Dc,Area, []) </c></p> %% <p><c> %% new(Dc::wxDC:wxDC(), [Option]) -> wxBufferedDC() </c> %%<br /> Option = {buffer, wxBitmap:wxBitmap()} | {style, integer()} @@ -93,7 +93,7 @@ new(#wx_ref{type=DcT,ref=DcRef}, Options) wxe_util:construct(?wxBufferedDC_new_2, <<DcRef:32/?UI, 0:32,BinOpt/binary>>). -%% @spec (Dc::wxDC:wxDC(), Area::{W::integer(),H::integer()}, [Option]) -> wxBufferedDC() +%% @spec (Dc::wxDC:wxDC(), Area::{W::integer(), H::integer()}, [Option]) -> wxBufferedDC() %% Option = {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxbuffereddc.html#wxbuffereddcwxbuffereddc">external documentation</a>. new(#wx_ref{type=DcT,ref=DcRef},{AreaW,AreaH}, Options) @@ -115,7 +115,7 @@ init(This,Dc) %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxbuffereddc.html#wxbuffereddcinit">external documentation</a>. %% <br /> Alternatives: %% <p><c> -%% init(This::wxBufferedDC(), Dc::wxDC:wxDC(), Area::{W::integer(),H::integer()}) -> init(This,Dc,Area, []) </c></p> +%% init(This::wxBufferedDC(), Dc::wxDC:wxDC(), Area::{W::integer(), H::integer()}) -> init(This,Dc,Area, []) </c></p> %% <p><c> %% init(This::wxBufferedDC(), Dc::wxDC:wxDC(), [Option]) -> ok </c> %%<br /> Option = {buffer, wxBitmap:wxBitmap()} | {style, integer()} @@ -135,7 +135,7 @@ init(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=DcT,ref=DcRef}, Options) wxe_util:cast(?wxBufferedDC_Init_2, <<ThisRef:32/?UI,DcRef:32/?UI, BinOpt/binary>>). -%% @spec (This::wxBufferedDC(), Dc::wxDC:wxDC(), Area::{W::integer(),H::integer()}, [Option]) -> ok +%% @spec (This::wxBufferedDC(), Dc::wxDC:wxDC(), Area::{W::integer(), H::integer()}, [Option]) -> ok %% Option = {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxbuffereddc.html#wxbuffereddcinit">external documentation</a>. init(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=DcT,ref=DcRef},{AreaW,AreaH}, Options) diff --git a/lib/wx/src/gen/wxButton.erl b/lib/wx/src/gen/wxButton.erl index c0e21a5657..a75c45c5a3 100644 --- a/lib/wx/src/gen/wxButton.erl +++ b/lib/wx/src/gen/wxButton.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -89,7 +89,7 @@ new(Parent,Id) new(Parent,Id, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> wxButton() -%% Option = {label, string()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {label, string()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxbutton.html#wxbuttonwxbutton">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> @@ -111,7 +111,7 @@ create(This,Parent,Id) create(This,Parent,Id, []). %% @spec (This::wxButton(), Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> bool() -%% Option = {label, string()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {label, string()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxbutton.html#wxbuttoncreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> @@ -127,7 +127,7 @@ create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id, O wxe_util:call(?wxButton_Create, <<ThisRef:32/?UI,ParentRef:32/?UI,Id:32/?UI, 0:32,BinOpt/binary>>). -%% @spec () -> {W::integer(),H::integer()} +%% @spec () -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxbutton.html#wxbuttongetdefaultsize">external documentation</a>. getDefaultSize() -> wxe_util:call(?wxButton_GetDefaultSize, diff --git a/lib/wx/src/gen/wxCalendarCtrl.erl b/lib/wx/src/gen/wxCalendarCtrl.erl index 8ad4d5954b..1bb4ecb1fa 100644 --- a/lib/wx/src/gen/wxCalendarCtrl.erl +++ b/lib/wx/src/gen/wxCalendarCtrl.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -93,7 +93,7 @@ new(Parent,Id) new(Parent,Id, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> wxCalendarCtrl() -%% Option = {date, wx:datetime()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {date, wx:datetime()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcalendarctrl.html#wxcalendarctrlwxcalendarctrl">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> @@ -114,7 +114,7 @@ create(This,Parent,Id) create(This,Parent,Id, []). %% @spec (This::wxCalendarCtrl(), Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> bool() -%% Option = {date, wx:datetime()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {date, wx:datetime()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcalendarctrl.html#wxcalendarctrlcreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> @@ -297,7 +297,7 @@ resetAttr(#wx_ref{type=ThisT,ref=ThisRef},Day) wxe_util:cast(?wxCalendarCtrl_ResetAttr, <<ThisRef:32/?UI,Day:32/?UI>>). -%% @spec (This::wxCalendarCtrl(), Pos::{X::integer(),Y::integer()}) -> {WxCalendarHitTestResult,Date::wx:datetime(),Wd::WeekDay} +%% @spec (This::wxCalendarCtrl(), Pos::{X::integer(), Y::integer()}) -> {WxCalendarHitTestResult, Date::wx:datetime(), Wd::WeekDay} %% WxCalendarHitTestResult = integer() %% WeekDay = integer() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcalendarctrl.html#wxcalendarctrlhittest">external documentation</a>. diff --git a/lib/wx/src/gen/wxCaret.erl b/lib/wx/src/gen/wxCaret.erl index 3e1a3d544c..cbd868f388 100644 --- a/lib/wx/src/gen/wxCaret.erl +++ b/lib/wx/src/gen/wxCaret.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -34,7 +34,7 @@ %% @hidden parent_class(_Class) -> erlang:error({badtype, ?MODULE}). -%% @spec (Window::wxWindow:wxWindow(), Size::{W::integer(),H::integer()}) -> wxCaret() +%% @spec (Window::wxWindow:wxWindow(), Size::{W::integer(), H::integer()}) -> wxCaret() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcaret.html#wxcaretwxcaret">external documentation</a>. new(#wx_ref{type=WindowT,ref=WindowRef},{SizeW,SizeH}) when is_integer(SizeW),is_integer(SizeH) -> @@ -50,7 +50,7 @@ new(#wx_ref{type=WindowT,ref=WindowRef},Width,Height) wxe_util:construct(?wxCaret_new_3, <<WindowRef:32/?UI,Width:32/?UI,Height:32/?UI>>). -%% @spec (This::wxCaret(), Window::wxWindow:wxWindow(), Size::{W::integer(),H::integer()}) -> bool() +%% @spec (This::wxCaret(), Window::wxWindow:wxWindow(), Size::{W::integer(), H::integer()}) -> bool() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcaret.html#wxcaretcreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=WindowT,ref=WindowRef},{SizeW,SizeH}) when is_integer(SizeW),is_integer(SizeH) -> @@ -74,14 +74,14 @@ getBlinkTime() -> wxe_util:call(?wxCaret_GetBlinkTime, <<>>). -%% @spec (This::wxCaret()) -> {X::integer(),Y::integer()} +%% @spec (This::wxCaret()) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcaret.html#wxcaretgetposition">external documentation</a>. getPosition(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxCaret), wxe_util:call(?wxCaret_GetPosition, <<ThisRef:32/?UI>>). -%% @spec (This::wxCaret()) -> {W::integer(),H::integer()} +%% @spec (This::wxCaret()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcaret.html#wxcaretgetsize">external documentation</a>. getSize(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxCaret), @@ -116,7 +116,7 @@ isVisible(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxCaret_IsVisible, <<ThisRef:32/?UI>>). -%% @spec (This::wxCaret(), Pt::{X::integer(),Y::integer()}) -> ok +%% @spec (This::wxCaret(), Pt::{X::integer(), Y::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcaret.html#wxcaretmove">external documentation</a>. move(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) when is_integer(PtX),is_integer(PtY) -> @@ -139,7 +139,7 @@ setBlinkTime(Milliseconds) wxe_util:cast(?wxCaret_SetBlinkTime, <<Milliseconds:32/?UI>>). -%% @spec (This::wxCaret(), Size::{W::integer(),H::integer()}) -> ok +%% @spec (This::wxCaret(), Size::{W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcaret.html#wxcaretsetsize">external documentation</a>. setSize(#wx_ref{type=ThisT,ref=ThisRef},{SizeW,SizeH}) when is_integer(SizeW),is_integer(SizeH) -> diff --git a/lib/wx/src/gen/wxCheckBox.erl b/lib/wx/src/gen/wxCheckBox.erl index c484483379..19f01645c1 100644 --- a/lib/wx/src/gen/wxCheckBox.erl +++ b/lib/wx/src/gen/wxCheckBox.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -90,7 +90,7 @@ new(Parent,Id,Label) new(Parent,Id,Label, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), Label::string(), [Option]) -> wxCheckBox() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcheckbox.html#wxcheckboxwxcheckbox">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id,Label, Options) when is_integer(Id),is_list(Label),is_list(Options) -> @@ -112,7 +112,7 @@ create(This,Parent,Id,Label) create(This,Parent,Id,Label, []). %% @spec (This::wxCheckBox(), Parent::wxWindow:wxWindow(), Id::integer(), Label::string(), [Option]) -> bool() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcheckbox.html#wxcheckboxcreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,Label, Options) when is_integer(Id),is_list(Label),is_list(Options) -> diff --git a/lib/wx/src/gen/wxCheckListBox.erl b/lib/wx/src/gen/wxCheckListBox.erl index c692997311..a1a07e1eec 100644 --- a/lib/wx/src/gen/wxCheckListBox.erl +++ b/lib/wx/src/gen/wxCheckListBox.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -96,7 +96,7 @@ new(Parent,Id) new(Parent,Id, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> wxCheckListBox() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {choices, [[string()]]} | {style, integer()} | {validator, wx:wx()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {choices, [[string()]]} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxchecklistbox.html#wxchecklistboxwxchecklistbox">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> diff --git a/lib/wx/src/gen/wxChoice.erl b/lib/wx/src/gen/wxChoice.erl index eaf2f0352f..fa967d8487 100644 --- a/lib/wx/src/gen/wxChoice.erl +++ b/lib/wx/src/gen/wxChoice.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -94,7 +94,7 @@ new(Parent,Id) new(Parent,Id, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> wxChoice() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {choices, [[string()]]} | {style, integer()} | {validator, wx:wx()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {choices, [[string()]]} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxchoice.html#wxchoicewxchoice">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> @@ -109,13 +109,13 @@ new(#wx_ref{type=ParentT,ref=ParentRef},Id, Options) wxe_util:construct(?wxChoice_new_3, <<ParentRef:32/?UI,Id:32/?UI, BinOpt/binary>>). -%% @spec (This::wxChoice(), Parent::wxWindow:wxWindow(), Id::integer(), Pos::{X::integer(),Y::integer()}, Size::{W::integer(),H::integer()}, Choices::[[string()]]) -> bool() +%% @spec (This::wxChoice(), Parent::wxWindow:wxWindow(), Id::integer(), Pos::{X::integer(), Y::integer()}, Size::{W::integer(), H::integer()}, Choices::[[string()]]) -> bool() %% @equiv create(This,Parent,Id,Pos,Size,Choices, []) create(This,Parent,Id,Pos={PosX,PosY},Size={SizeW,SizeH},Choices) when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Id),is_integer(PosX),is_integer(PosY),is_integer(SizeW),is_integer(SizeH),is_list(Choices) -> create(This,Parent,Id,Pos,Size,Choices, []). -%% @spec (This::wxChoice(), Parent::wxWindow:wxWindow(), Id::integer(), Pos::{X::integer(),Y::integer()}, Size::{W::integer(),H::integer()}, Choices::[[string()]], [Option]) -> bool() +%% @spec (This::wxChoice(), Parent::wxWindow:wxWindow(), Id::integer(), Pos::{X::integer(), Y::integer()}, Size::{W::integer(), H::integer()}, Choices::[[string()]], [Option]) -> bool() %% Option = {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxchoice.html#wxchoicecreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,{PosX,PosY},{SizeW,SizeH},Choices, Options) diff --git a/lib/wx/src/gen/wxChoicebook.erl b/lib/wx/src/gen/wxChoicebook.erl index b724d0cad2..f37457f0ed 100644 --- a/lib/wx/src/gen/wxChoicebook.erl +++ b/lib/wx/src/gen/wxChoicebook.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2009-2010. All Rights Reserved. +%% Copyright Ericsson AB 2009-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -93,7 +93,7 @@ new(Parent,Id) new(Parent,Id, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> wxChoicebook() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxchoicebook.html#wxchoicebookwxchoicebook">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> @@ -160,7 +160,7 @@ create(This,Parent,Id) create(This,Parent,Id, []). %% @spec (This::wxChoicebook(), Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> bool() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxchoicebook.html#wxchoicebookcreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> @@ -249,7 +249,7 @@ getSelection(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxChoicebook_GetSelection, <<ThisRef:32/?UI>>). -%% @spec (This::wxChoicebook(), Pt::{X::integer(),Y::integer()}) -> {integer(),Flags::integer()} +%% @spec (This::wxChoicebook(), Pt::{X::integer(), Y::integer()}) -> {integer(), Flags::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxchoicebook.html#wxchoicebookhittest">external documentation</a>. hitTest(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) when is_integer(PtX),is_integer(PtY) -> @@ -286,7 +286,7 @@ setImageList(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ImageListT,ref=ImageLi wxe_util:cast(?wxChoicebook_SetImageList, <<ThisRef:32/?UI,ImageListRef:32/?UI>>). -%% @spec (This::wxChoicebook(), Size::{W::integer(),H::integer()}) -> ok +%% @spec (This::wxChoicebook(), Size::{W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxchoicebook.html#wxchoicebooksetpagesize">external documentation</a>. setPageSize(#wx_ref{type=ThisT,ref=ThisRef},{SizeW,SizeH}) when is_integer(SizeW),is_integer(SizeH) -> diff --git a/lib/wx/src/gen/wxColourPickerCtrl.erl b/lib/wx/src/gen/wxColourPickerCtrl.erl index 4f0816e1fd..60776925b9 100644 --- a/lib/wx/src/gen/wxColourPickerCtrl.erl +++ b/lib/wx/src/gen/wxColourPickerCtrl.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -94,7 +94,7 @@ new(Parent,Id) new(Parent,Id, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> wxColourPickerCtrl() -%% Option = {col, wx:colour()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {col, wx:colour()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcolourpickerctrl.html#wxcolourpickerctrlwxcolourpickerctrl">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> @@ -116,7 +116,7 @@ create(This,Parent,Id) create(This,Parent,Id, []). %% @spec (This::wxColourPickerCtrl(), Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> bool() -%% Option = {col, wx:colour()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {col, wx:colour()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcolourpickerctrl.html#wxcolourpickerctrlcreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> diff --git a/lib/wx/src/gen/wxComboBox.erl b/lib/wx/src/gen/wxComboBox.erl index 061e886734..f743df4e93 100644 --- a/lib/wx/src/gen/wxComboBox.erl +++ b/lib/wx/src/gen/wxComboBox.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -96,7 +96,7 @@ new(Parent,Id) new(Parent,Id, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> wxComboBox() -%% Option = {value, string()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {choices, [[string()]]} | {style, integer()} | {validator, wx:wx()} +%% Option = {value, string()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {choices, [[string()]]} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcombobox.html#wxcomboboxwxcombobox">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> @@ -112,13 +112,13 @@ new(#wx_ref{type=ParentT,ref=ParentRef},Id, Options) wxe_util:construct(?wxComboBox_new_3, <<ParentRef:32/?UI,Id:32/?UI, BinOpt/binary>>). -%% @spec (This::wxComboBox(), Parent::wxWindow:wxWindow(), Id::integer(), Value::string(), Pos::{X::integer(),Y::integer()}, Size::{W::integer(),H::integer()}, Choices::[[string()]]) -> bool() +%% @spec (This::wxComboBox(), Parent::wxWindow:wxWindow(), Id::integer(), Value::string(), Pos::{X::integer(), Y::integer()}, Size::{W::integer(), H::integer()}, Choices::[[string()]]) -> bool() %% @equiv create(This,Parent,Id,Value,Pos,Size,Choices, []) create(This,Parent,Id,Value,Pos={PosX,PosY},Size={SizeW,SizeH},Choices) when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Id),is_list(Value),is_integer(PosX),is_integer(PosY),is_integer(SizeW),is_integer(SizeH),is_list(Choices) -> create(This,Parent,Id,Value,Pos,Size,Choices, []). -%% @spec (This::wxComboBox(), Parent::wxWindow:wxWindow(), Id::integer(), Value::string(), Pos::{X::integer(),Y::integer()}, Size::{W::integer(),H::integer()}, Choices::[[string()]], [Option]) -> bool() +%% @spec (This::wxComboBox(), Parent::wxWindow:wxWindow(), Id::integer(), Value::string(), Pos::{X::integer(), Y::integer()}, Size::{W::integer(), H::integer()}, Choices::[[string()]], [Option]) -> bool() %% Option = {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcombobox.html#wxcomboboxcreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,Value,{PosX,PosY},{SizeW,SizeH},Choices, Options) diff --git a/lib/wx/src/gen/wxContextMenuEvent.erl b/lib/wx/src/gen/wxContextMenuEvent.erl index 56ed82f37c..0050b97b89 100644 --- a/lib/wx/src/gen/wxContextMenuEvent.erl +++ b/lib/wx/src/gen/wxContextMenuEvent.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -45,14 +45,14 @@ parent_class(wxCommandEvent) -> true; parent_class(wxEvent) -> true; parent_class(_Class) -> erlang:error({badtype, ?MODULE}). -%% @spec (This::wxContextMenuEvent()) -> {X::integer(),Y::integer()} +%% @spec (This::wxContextMenuEvent()) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcontextmenuevent.html#wxcontextmenueventgetposition">external documentation</a>. getPosition(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxContextMenuEvent), wxe_util:call(?wxContextMenuEvent_GetPosition, <<ThisRef:32/?UI>>). -%% @spec (This::wxContextMenuEvent(), Pos::{X::integer(),Y::integer()}) -> ok +%% @spec (This::wxContextMenuEvent(), Pos::{X::integer(), Y::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxcontextmenuevent.html#wxcontextmenueventsetposition">external documentation</a>. setPosition(#wx_ref{type=ThisT,ref=ThisRef},{PosX,PosY}) when is_integer(PosX),is_integer(PosY) -> diff --git a/lib/wx/src/gen/wxDC.erl b/lib/wx/src/gen/wxDC.erl index 9bce1249f8..ba498c651a 100644 --- a/lib/wx/src/gen/wxDC.erl +++ b/lib/wx/src/gen/wxDC.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -52,14 +52,14 @@ %% @hidden parent_class(_Class) -> erlang:error({badtype, ?MODULE}). -%% @spec (This::wxDC(), DestPt::{X::integer(),Y::integer()}, Sz::{W::integer(),H::integer()}, Source::wxDC(), SrcPt::{X::integer(),Y::integer()}) -> bool() +%% @spec (This::wxDC(), DestPt::{X::integer(), Y::integer()}, Sz::{W::integer(), H::integer()}, Source::wxDC(), SrcPt::{X::integer(), Y::integer()}) -> bool() %% @equiv blit(This,DestPt,Sz,Source,SrcPt, []) blit(This,DestPt={DestPtX,DestPtY},Sz={SzW,SzH},Source,SrcPt={SrcPtX,SrcPtY}) when is_record(This, wx_ref),is_integer(DestPtX),is_integer(DestPtY),is_integer(SzW),is_integer(SzH),is_record(Source, wx_ref),is_integer(SrcPtX),is_integer(SrcPtY) -> blit(This,DestPt,Sz,Source,SrcPt, []). -%% @spec (This::wxDC(), DestPt::{X::integer(),Y::integer()}, Sz::{W::integer(),H::integer()}, Source::wxDC(), SrcPt::{X::integer(),Y::integer()}, [Option]) -> bool() -%% Option = {rop, integer()} | {useMask, bool()} | {srcPtMask, {X::integer(),Y::integer()}} +%% @spec (This::wxDC(), DestPt::{X::integer(), Y::integer()}, Sz::{W::integer(), H::integer()}, Source::wxDC(), SrcPt::{X::integer(), Y::integer()}, [Option]) -> bool() +%% Option = {rop, integer()} | {useMask, bool()} | {srcPtMask, {X::integer(), Y::integer()}} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcblit">external documentation</a>. blit(#wx_ref{type=ThisT,ref=ThisRef},{DestPtX,DestPtY},{SzW,SzH},#wx_ref{type=SourceT,ref=SourceRef},{SrcPtX,SrcPtY}, Options) when is_integer(DestPtX),is_integer(DestPtY),is_integer(SzW),is_integer(SzH),is_integer(SrcPtX),is_integer(SrcPtY),is_list(Options) -> @@ -95,7 +95,7 @@ computeScaleAndOrigin(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:cast(?wxDC_ComputeScaleAndOrigin, <<ThisRef:32/?UI>>). -%% @spec (This::wxDC(), Pt::{X::integer(),Y::integer()}) -> ok +%% @spec (This::wxDC(), Pt::{X::integer(), Y::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdccrosshair">external documentation</a>. crossHair(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) when is_integer(PtX),is_integer(PtY) -> @@ -142,7 +142,7 @@ deviceToLogicalYRel(#wx_ref{type=ThisT,ref=ThisRef},Y) wxe_util:call(?wxDC_DeviceToLogicalYRel, <<ThisRef:32/?UI,Y:32/?UI>>). -%% @spec (This::wxDC(), Pt1::{X::integer(),Y::integer()}, Pt2::{X::integer(),Y::integer()}, Centre::{X::integer(),Y::integer()}) -> ok +%% @spec (This::wxDC(), Pt1::{X::integer(), Y::integer()}, Pt2::{X::integer(), Y::integer()}, Centre::{X::integer(), Y::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcdrawarc">external documentation</a>. drawArc(#wx_ref{type=ThisT,ref=ThisRef},{Pt1X,Pt1Y},{Pt2X,Pt2Y},{CentreX,CentreY}) when is_integer(Pt1X),is_integer(Pt1Y),is_integer(Pt2X),is_integer(Pt2Y),is_integer(CentreX),is_integer(CentreY) -> @@ -150,13 +150,13 @@ drawArc(#wx_ref{type=ThisT,ref=ThisRef},{Pt1X,Pt1Y},{Pt2X,Pt2Y},{CentreX,CentreY wxe_util:cast(?wxDC_DrawArc, <<ThisRef:32/?UI,Pt1X:32/?UI,Pt1Y:32/?UI,Pt2X:32/?UI,Pt2Y:32/?UI,CentreX:32/?UI,CentreY:32/?UI>>). -%% @spec (This::wxDC(), Bmp::wxBitmap:wxBitmap(), Pt::{X::integer(),Y::integer()}) -> ok +%% @spec (This::wxDC(), Bmp::wxBitmap:wxBitmap(), Pt::{X::integer(), Y::integer()}) -> ok %% @equiv drawBitmap(This,Bmp,Pt, []) drawBitmap(This,Bmp,Pt={PtX,PtY}) when is_record(This, wx_ref),is_record(Bmp, wx_ref),is_integer(PtX),is_integer(PtY) -> drawBitmap(This,Bmp,Pt, []). -%% @spec (This::wxDC(), Bmp::wxBitmap:wxBitmap(), Pt::{X::integer(),Y::integer()}, [Option]) -> ok +%% @spec (This::wxDC(), Bmp::wxBitmap:wxBitmap(), Pt::{X::integer(), Y::integer()}, [Option]) -> ok %% Option = {useMask, bool()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcdrawbitmap">external documentation</a>. drawBitmap(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=BmpT,ref=BmpRef},{PtX,PtY}, Options) @@ -169,7 +169,7 @@ drawBitmap(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=BmpT,ref=BmpRef},{PtX,Pt wxe_util:cast(?wxDC_DrawBitmap, <<ThisRef:32/?UI,BmpRef:32/?UI,PtX:32/?UI,PtY:32/?UI, BinOpt/binary>>). -%% @spec (This::wxDC(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}) -> ok +%% @spec (This::wxDC(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcdrawcheckmark">external documentation</a>. drawCheckMark(#wx_ref{type=ThisT,ref=ThisRef},{RectX,RectY,RectW,RectH}) when is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH) -> @@ -177,7 +177,7 @@ drawCheckMark(#wx_ref{type=ThisT,ref=ThisRef},{RectX,RectY,RectW,RectH}) wxe_util:cast(?wxDC_DrawCheckMark, <<ThisRef:32/?UI,RectX:32/?UI,RectY:32/?UI,RectW:32/?UI,RectH:32/?UI>>). -%% @spec (This::wxDC(), Pt::{X::integer(),Y::integer()}, Radius::integer()) -> ok +%% @spec (This::wxDC(), Pt::{X::integer(), Y::integer()}, Radius::integer()) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcdrawcircle">external documentation</a>. drawCircle(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY},Radius) when is_integer(PtX),is_integer(PtY),is_integer(Radius) -> @@ -185,7 +185,7 @@ drawCircle(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY},Radius) wxe_util:cast(?wxDC_DrawCircle, <<ThisRef:32/?UI,PtX:32/?UI,PtY:32/?UI,Radius:32/?UI>>). -%% @spec (This::wxDC(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}) -> ok +%% @spec (This::wxDC(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcdrawellipse">external documentation</a>. drawEllipse(#wx_ref{type=ThisT,ref=ThisRef},{RectX,RectY,RectW,RectH}) when is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH) -> @@ -193,7 +193,7 @@ drawEllipse(#wx_ref{type=ThisT,ref=ThisRef},{RectX,RectY,RectW,RectH}) wxe_util:cast(?wxDC_DrawEllipse_1, <<ThisRef:32/?UI,RectX:32/?UI,RectY:32/?UI,RectW:32/?UI,RectH:32/?UI>>). -%% @spec (This::wxDC(), Pt::{X::integer(),Y::integer()}, Sz::{W::integer(),H::integer()}) -> ok +%% @spec (This::wxDC(), Pt::{X::integer(), Y::integer()}, Sz::{W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcdrawellipse">external documentation</a>. drawEllipse(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY},{SzW,SzH}) when is_integer(PtX),is_integer(PtY),is_integer(SzW),is_integer(SzH) -> @@ -201,7 +201,7 @@ drawEllipse(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY},{SzW,SzH}) wxe_util:cast(?wxDC_DrawEllipse_2, <<ThisRef:32/?UI,PtX:32/?UI,PtY:32/?UI,SzW:32/?UI,SzH:32/?UI>>). -%% @spec (This::wxDC(), Pt::{X::integer(),Y::integer()}, Sz::{W::integer(),H::integer()}, Sa::float(), Ea::float()) -> ok +%% @spec (This::wxDC(), Pt::{X::integer(), Y::integer()}, Sz::{W::integer(), H::integer()}, Sa::float(), Ea::float()) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcdrawellipticarc">external documentation</a>. drawEllipticArc(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY},{SzW,SzH},Sa,Ea) when is_integer(PtX),is_integer(PtY),is_integer(SzW),is_integer(SzH),is_float(Sa),is_float(Ea) -> @@ -209,7 +209,7 @@ drawEllipticArc(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY},{SzW,SzH},Sa,Ea) wxe_util:cast(?wxDC_DrawEllipticArc, <<ThisRef:32/?UI,PtX:32/?UI,PtY:32/?UI,SzW:32/?UI,SzH:32/?UI,0:32,Sa:64/?F,Ea:64/?F>>). -%% @spec (This::wxDC(), Icon::wxIcon:wxIcon(), Pt::{X::integer(),Y::integer()}) -> ok +%% @spec (This::wxDC(), Icon::wxIcon:wxIcon(), Pt::{X::integer(), Y::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcdrawicon">external documentation</a>. drawIcon(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=IconT,ref=IconRef},{PtX,PtY}) when is_integer(PtX),is_integer(PtY) -> @@ -218,13 +218,13 @@ drawIcon(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=IconT,ref=IconRef},{PtX,Pt wxe_util:cast(?wxDC_DrawIcon, <<ThisRef:32/?UI,IconRef:32/?UI,PtX:32/?UI,PtY:32/?UI>>). -%% @spec (This::wxDC(), Text::string(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}) -> ok +%% @spec (This::wxDC(), Text::string(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}) -> ok %% @equiv drawLabel(This,Text,Rect, []) drawLabel(This,Text,Rect={RectX,RectY,RectW,RectH}) when is_record(This, wx_ref),is_list(Text),is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH) -> drawLabel(This,Text,Rect, []). -%% @spec (This::wxDC(), Text::string(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}, [Option]) -> ok +%% @spec (This::wxDC(), Text::string(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}, [Option]) -> ok %% Option = {alignment, integer()} | {indexAccel, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcdrawlabel">external documentation</a>. drawLabel(#wx_ref{type=ThisT,ref=ThisRef},Text,{RectX,RectY,RectW,RectH}, Options) @@ -238,7 +238,7 @@ drawLabel(#wx_ref{type=ThisT,ref=ThisRef},Text,{RectX,RectY,RectW,RectH}, Option wxe_util:cast(?wxDC_DrawLabel, <<ThisRef:32/?UI,(byte_size(Text_UC)):32/?UI,(Text_UC)/binary, 0:(((8- ((0+byte_size(Text_UC)) band 16#7)) band 16#7))/unit:8,RectX:32/?UI,RectY:32/?UI,RectW:32/?UI,RectH:32/?UI, BinOpt/binary>>). -%% @spec (This::wxDC(), Pt1::{X::integer(),Y::integer()}, Pt2::{X::integer(),Y::integer()}) -> ok +%% @spec (This::wxDC(), Pt1::{X::integer(), Y::integer()}, Pt2::{X::integer(), Y::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcdrawline">external documentation</a>. drawLine(#wx_ref{type=ThisT,ref=ThisRef},{Pt1X,Pt1Y},{Pt2X,Pt2Y}) when is_integer(Pt1X),is_integer(Pt1Y),is_integer(Pt2X),is_integer(Pt2Y) -> @@ -246,13 +246,13 @@ drawLine(#wx_ref{type=ThisT,ref=ThisRef},{Pt1X,Pt1Y},{Pt2X,Pt2Y}) wxe_util:cast(?wxDC_DrawLine, <<ThisRef:32/?UI,Pt1X:32/?UI,Pt1Y:32/?UI,Pt2X:32/?UI,Pt2Y:32/?UI>>). -%% @spec (This::wxDC(), Points::[{X::integer(),Y::integer()}]) -> ok +%% @spec (This::wxDC(), Points::[{X::integer(), Y::integer()}]) -> ok %% @equiv drawLines(This,Points, []) drawLines(This,Points) when is_record(This, wx_ref),is_list(Points) -> drawLines(This,Points, []). -%% @spec (This::wxDC(), Points::[{X::integer(),Y::integer()}], [Option]) -> ok +%% @spec (This::wxDC(), Points::[{X::integer(), Y::integer()}], [Option]) -> ok %% Option = {xoffset, integer()} | {yoffset, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcdrawlines">external documentation</a>. drawLines(#wx_ref{type=ThisT,ref=ThisRef},Points, Options) @@ -266,13 +266,13 @@ drawLines(#wx_ref{type=ThisT,ref=ThisRef},Points, Options) <<ThisRef:32/?UI,(length(Points)):32/?UI, (<< <<X:32/?I,Y:32/?I>> || {X,Y} <- Points>>)/binary, BinOpt/binary>>). -%% @spec (This::wxDC(), Points::[{X::integer(),Y::integer()}]) -> ok +%% @spec (This::wxDC(), Points::[{X::integer(), Y::integer()}]) -> ok %% @equiv drawPolygon(This,Points, []) drawPolygon(This,Points) when is_record(This, wx_ref),is_list(Points) -> drawPolygon(This,Points, []). -%% @spec (This::wxDC(), Points::[{X::integer(),Y::integer()}], [Option]) -> ok +%% @spec (This::wxDC(), Points::[{X::integer(), Y::integer()}], [Option]) -> ok %% Option = {xoffset, integer()} | {yoffset, integer()} | {fillStyle, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcdrawpolygon">external documentation</a>. drawPolygon(#wx_ref{type=ThisT,ref=ThisRef},Points, Options) @@ -287,7 +287,7 @@ drawPolygon(#wx_ref{type=ThisT,ref=ThisRef},Points, Options) <<ThisRef:32/?UI,(length(Points)):32/?UI, (<< <<X:32/?I,Y:32/?I>> || {X,Y} <- Points>>)/binary, BinOpt/binary>>). -%% @spec (This::wxDC(), Pt::{X::integer(),Y::integer()}) -> ok +%% @spec (This::wxDC(), Pt::{X::integer(), Y::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcdrawpoint">external documentation</a>. drawPoint(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) when is_integer(PtX),is_integer(PtY) -> @@ -295,7 +295,7 @@ drawPoint(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) wxe_util:cast(?wxDC_DrawPoint, <<ThisRef:32/?UI,PtX:32/?UI,PtY:32/?UI>>). -%% @spec (This::wxDC(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}) -> ok +%% @spec (This::wxDC(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcdrawrectangle">external documentation</a>. drawRectangle(#wx_ref{type=ThisT,ref=ThisRef},{RectX,RectY,RectW,RectH}) when is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH) -> @@ -303,7 +303,7 @@ drawRectangle(#wx_ref{type=ThisT,ref=ThisRef},{RectX,RectY,RectW,RectH}) wxe_util:cast(?wxDC_DrawRectangle_1, <<ThisRef:32/?UI,RectX:32/?UI,RectY:32/?UI,RectW:32/?UI,RectH:32/?UI>>). -%% @spec (This::wxDC(), Pt::{X::integer(),Y::integer()}, Sz::{W::integer(),H::integer()}) -> ok +%% @spec (This::wxDC(), Pt::{X::integer(), Y::integer()}, Sz::{W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcdrawrectangle">external documentation</a>. drawRectangle(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY},{SzW,SzH}) when is_integer(PtX),is_integer(PtY),is_integer(SzW),is_integer(SzH) -> @@ -311,7 +311,7 @@ drawRectangle(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY},{SzW,SzH}) wxe_util:cast(?wxDC_DrawRectangle_2, <<ThisRef:32/?UI,PtX:32/?UI,PtY:32/?UI,SzW:32/?UI,SzH:32/?UI>>). -%% @spec (This::wxDC(), Text::string(), Pt::{X::integer(),Y::integer()}, Angle::float()) -> ok +%% @spec (This::wxDC(), Text::string(), Pt::{X::integer(), Y::integer()}, Angle::float()) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcdrawrotatedtext">external documentation</a>. drawRotatedText(#wx_ref{type=ThisT,ref=ThisRef},Text,{PtX,PtY},Angle) when is_list(Text),is_integer(PtX),is_integer(PtY),is_float(Angle) -> @@ -320,7 +320,7 @@ drawRotatedText(#wx_ref{type=ThisT,ref=ThisRef},Text,{PtX,PtY},Angle) wxe_util:cast(?wxDC_DrawRotatedText, <<ThisRef:32/?UI,(byte_size(Text_UC)):32/?UI,(Text_UC)/binary, 0:(((8- ((0+byte_size(Text_UC)) band 16#7)) band 16#7))/unit:8,PtX:32/?UI,PtY:32/?UI,Angle:64/?F>>). -%% @spec (This::wxDC(), R::{X::integer(),Y::integer(),W::integer(),H::integer()}, Radius::float()) -> ok +%% @spec (This::wxDC(), R::{X::integer(), Y::integer(), W::integer(), H::integer()}, Radius::float()) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcdrawroundedrectangle">external documentation</a>. drawRoundedRectangle(#wx_ref{type=ThisT,ref=ThisRef},{RX,RY,RW,RH},Radius) when is_integer(RX),is_integer(RY),is_integer(RW),is_integer(RH),is_float(Radius) -> @@ -328,7 +328,7 @@ drawRoundedRectangle(#wx_ref{type=ThisT,ref=ThisRef},{RX,RY,RW,RH},Radius) wxe_util:cast(?wxDC_DrawRoundedRectangle_2, <<ThisRef:32/?UI,RX:32/?UI,RY:32/?UI,RW:32/?UI,RH:32/?UI,0:32,Radius:64/?F>>). -%% @spec (This::wxDC(), Pt::{X::integer(),Y::integer()}, Sz::{W::integer(),H::integer()}, Radius::float()) -> ok +%% @spec (This::wxDC(), Pt::{X::integer(), Y::integer()}, Sz::{W::integer(), H::integer()}, Radius::float()) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcdrawroundedrectangle">external documentation</a>. drawRoundedRectangle(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY},{SzW,SzH},Radius) when is_integer(PtX),is_integer(PtY),is_integer(SzW),is_integer(SzH),is_float(Radius) -> @@ -336,7 +336,7 @@ drawRoundedRectangle(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY},{SzW,SzH},Radius) wxe_util:cast(?wxDC_DrawRoundedRectangle_3, <<ThisRef:32/?UI,PtX:32/?UI,PtY:32/?UI,SzW:32/?UI,SzH:32/?UI,0:32,Radius:64/?F>>). -%% @spec (This::wxDC(), Text::string(), Pt::{X::integer(),Y::integer()}) -> ok +%% @spec (This::wxDC(), Text::string(), Pt::{X::integer(), Y::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcdrawtext">external documentation</a>. drawText(#wx_ref{type=ThisT,ref=ThisRef},Text,{PtX,PtY}) when is_list(Text),is_integer(PtX),is_integer(PtY) -> @@ -359,13 +359,13 @@ endPage(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:cast(?wxDC_EndPage, <<ThisRef:32/?UI>>). -%% @spec (This::wxDC(), Pt::{X::integer(),Y::integer()}, Col::wx:colour()) -> bool() +%% @spec (This::wxDC(), Pt::{X::integer(), Y::integer()}, Col::wx:colour()) -> bool() %% @equiv floodFill(This,Pt,Col, []) floodFill(This,Pt={PtX,PtY},Col) when is_record(This, wx_ref),is_integer(PtX),is_integer(PtY),tuple_size(Col) =:= 3; tuple_size(Col) =:= 4 -> floodFill(This,Pt,Col, []). -%% @spec (This::wxDC(), Pt::{X::integer(),Y::integer()}, Col::wx:colour(), [Option]) -> bool() +%% @spec (This::wxDC(), Pt::{X::integer(), Y::integer()}, Col::wx:colour(), [Option]) -> bool() %% Option = {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcfloodfill">external documentation</a>. floodFill(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY},Col, Options) @@ -412,7 +412,7 @@ getCharWidth(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxDC_GetCharWidth, <<ThisRef:32/?UI>>). -%% @spec (This::wxDC(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}) -> ok +%% @spec (This::wxDC(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcgetclippingbox">external documentation</a>. getClippingBox(#wx_ref{type=ThisT,ref=ThisRef},{RectX,RectY,RectW,RectH}) when is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH) -> @@ -450,7 +450,7 @@ getMapMode(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxDC_GetMapMode, <<ThisRef:32/?UI>>). -%% @spec (This::wxDC(), String::string()) -> {W::integer(),H::integer()} +%% @spec (This::wxDC(), String::string()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcgetmultilinetextextent">external documentation</a>. getMultiLineTextExtent(#wx_ref{type=ThisT,ref=ThisRef},String) when is_list(String) -> @@ -459,7 +459,7 @@ getMultiLineTextExtent(#wx_ref{type=ThisT,ref=ThisRef},String) wxe_util:call(?wxDC_GetMultiLineTextExtent_1, <<ThisRef:32/?UI,(byte_size(String_UC)):32/?UI,(String_UC)/binary, 0:(((8- ((0+byte_size(String_UC)) band 16#7)) band 16#7))/unit:8>>). -%% @spec (This::wxDC(), String::string(), [Option]) -> {Width::integer(),Height::integer(),HeightLine::integer()} +%% @spec (This::wxDC(), String::string(), [Option]) -> {Width::integer(), Height::integer(), HeightLine::integer()} %% Option = {font, wxFont:wxFont()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcgetmultilinetextextent">external documentation</a>. getMultiLineTextExtent(#wx_ref{type=ThisT,ref=ThisRef},String, Options) @@ -489,7 +489,7 @@ getPen(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxDC_GetPen, <<ThisRef:32/?UI>>). -%% @spec (This::wxDC(), Pt::{X::integer(),Y::integer()}, Col::wx:colour()) -> bool() +%% @spec (This::wxDC(), Pt::{X::integer(), Y::integer()}, Col::wx:colour()) -> bool() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcgetpixel">external documentation</a>. getPixel(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY},Col) when is_integer(PtX),is_integer(PtY),tuple_size(Col) =:= 3; tuple_size(Col) =:= 4 -> @@ -497,21 +497,21 @@ getPixel(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY},Col) wxe_util:call(?wxDC_GetPixel, <<ThisRef:32/?UI,PtX:32/?UI,PtY:32/?UI,(wxe_util:colour_bin(Col)):16/binary>>). -%% @spec (This::wxDC()) -> {W::integer(),H::integer()} +%% @spec (This::wxDC()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcgetppi">external documentation</a>. getPPI(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxDC), wxe_util:call(?wxDC_GetPPI, <<ThisRef:32/?UI>>). -%% @spec (This::wxDC()) -> {W::integer(),H::integer()} +%% @spec (This::wxDC()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcgetsize">external documentation</a>. getSize(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxDC), wxe_util:call(?wxDC_GetSize, <<ThisRef:32/?UI>>). -%% @spec (This::wxDC()) -> {W::integer(),H::integer()} +%% @spec (This::wxDC()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcgetsizemm">external documentation</a>. getSizeMM(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxDC), @@ -525,7 +525,7 @@ getTextBackground(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxDC_GetTextBackground, <<ThisRef:32/?UI>>). -%% @spec (This::wxDC(), String::string()) -> {W::integer(),H::integer()} +%% @spec (This::wxDC(), String::string()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcgettextextent">external documentation</a>. getTextExtent(#wx_ref{type=ThisT,ref=ThisRef},String) when is_list(String) -> @@ -534,7 +534,7 @@ getTextExtent(#wx_ref{type=ThisT,ref=ThisRef},String) wxe_util:call(?wxDC_GetTextExtent_1, <<ThisRef:32/?UI,(byte_size(String_UC)):32/?UI,(String_UC)/binary, 0:(((8- ((0+byte_size(String_UC)) band 16#7)) band 16#7))/unit:8>>). -%% @spec (This::wxDC(), String::string(), [Option]) -> {X::integer(),Y::integer(),Descent::integer(),ExternalLeading::integer()} +%% @spec (This::wxDC(), String::string(), [Option]) -> {X::integer(), Y::integer(), Descent::integer(), ExternalLeading::integer()} %% Option = {theFont, wxFont:wxFont()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcgettextextent">external documentation</a>. getTextExtent(#wx_ref{type=ThisT,ref=ThisRef},String, Options) @@ -554,14 +554,14 @@ getTextForeground(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxDC_GetTextForeground, <<ThisRef:32/?UI>>). -%% @spec (This::wxDC()) -> {X::float(),Y::float()} +%% @spec (This::wxDC()) -> {X::float(), Y::float()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcgetuserscale">external documentation</a>. getUserScale(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxDC), wxe_util:call(?wxDC_GetUserScale, <<ThisRef:32/?UI>>). -%% @spec (This::wxDC(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}, InitialColour::wx:colour(), DestColour::wx:colour()) -> ok +%% @spec (This::wxDC(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}, InitialColour::wx:colour(), DestColour::wx:colour()) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcgradientfillconcentric">external documentation</a>. gradientFillConcentric(#wx_ref{type=ThisT,ref=ThisRef},{RectX,RectY,RectW,RectH},InitialColour,DestColour) when is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH),tuple_size(InitialColour) =:= 3; tuple_size(InitialColour) =:= 4,tuple_size(DestColour) =:= 3; tuple_size(DestColour) =:= 4 -> @@ -569,7 +569,7 @@ gradientFillConcentric(#wx_ref{type=ThisT,ref=ThisRef},{RectX,RectY,RectW,RectH} wxe_util:cast(?wxDC_GradientFillConcentric_3, <<ThisRef:32/?UI,RectX:32/?UI,RectY:32/?UI,RectW:32/?UI,RectH:32/?UI,(wxe_util:colour_bin(InitialColour)):16/binary,(wxe_util:colour_bin(DestColour)):16/binary>>). -%% @spec (This::wxDC(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}, InitialColour::wx:colour(), DestColour::wx:colour(), CircleCenter::{X::integer(),Y::integer()}) -> ok +%% @spec (This::wxDC(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}, InitialColour::wx:colour(), DestColour::wx:colour(), CircleCenter::{X::integer(), Y::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcgradientfillconcentric">external documentation</a>. gradientFillConcentric(#wx_ref{type=ThisT,ref=ThisRef},{RectX,RectY,RectW,RectH},InitialColour,DestColour,{CircleCenterX,CircleCenterY}) when is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH),tuple_size(InitialColour) =:= 3; tuple_size(InitialColour) =:= 4,tuple_size(DestColour) =:= 3; tuple_size(DestColour) =:= 4,is_integer(CircleCenterX),is_integer(CircleCenterY) -> @@ -577,13 +577,13 @@ gradientFillConcentric(#wx_ref{type=ThisT,ref=ThisRef},{RectX,RectY,RectW,RectH} wxe_util:cast(?wxDC_GradientFillConcentric_4, <<ThisRef:32/?UI,RectX:32/?UI,RectY:32/?UI,RectW:32/?UI,RectH:32/?UI,(wxe_util:colour_bin(InitialColour)):16/binary,(wxe_util:colour_bin(DestColour)):16/binary,CircleCenterX:32/?UI,CircleCenterY:32/?UI>>). -%% @spec (This::wxDC(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}, InitialColour::wx:colour(), DestColour::wx:colour()) -> ok +%% @spec (This::wxDC(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}, InitialColour::wx:colour(), DestColour::wx:colour()) -> ok %% @equiv gradientFillLinear(This,Rect,InitialColour,DestColour, []) gradientFillLinear(This,Rect={RectX,RectY,RectW,RectH},InitialColour,DestColour) when is_record(This, wx_ref),is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH),tuple_size(InitialColour) =:= 3; tuple_size(InitialColour) =:= 4,tuple_size(DestColour) =:= 3; tuple_size(DestColour) =:= 4 -> gradientFillLinear(This,Rect,InitialColour,DestColour, []). -%% @spec (This::wxDC(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}, InitialColour::wx:colour(), DestColour::wx:colour(), [Option]) -> ok +%% @spec (This::wxDC(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}, InitialColour::wx:colour(), DestColour::wx:colour(), [Option]) -> ok %% Option = {nDirection, WxDirection} %% WxDirection = integer() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcgradientfilllinear">external documentation</a>. @@ -710,7 +710,7 @@ setBrush(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=BrushT,ref=BrushRef}) -> %% setClippingRegion(This::wxDC(), Region::wxRegion:wxRegion()) -> ok </c> %% </p> %% <p><c> -%% setClippingRegion(This::wxDC(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}) -> ok </c> +%% setClippingRegion(This::wxDC(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}) -> ok </c> %% </p> setClippingRegion(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=RegionT,ref=RegionRef}) -> ?CLASS(ThisT,wxDC), @@ -723,7 +723,7 @@ setClippingRegion(#wx_ref{type=ThisT,ref=ThisRef},{RectX,RectY,RectW,RectH}) wxe_util:cast(?wxDC_SetClippingRegion_1_1, <<ThisRef:32/?UI,RectX:32/?UI,RectY:32/?UI,RectW:32/?UI,RectH:32/?UI>>). -%% @spec (This::wxDC(), Pt::{X::integer(),Y::integer()}, Sz::{W::integer(),H::integer()}) -> ok +%% @spec (This::wxDC(), Pt::{X::integer(), Y::integer()}, Sz::{W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdc.html#wxdcsetclippingregion">external documentation</a>. setClippingRegion(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY},{SzW,SzH}) when is_integer(PtX),is_integer(PtY),is_integer(SzW),is_integer(SzH) -> diff --git a/lib/wx/src/gen/wxDatePickerCtrl.erl b/lib/wx/src/gen/wxDatePickerCtrl.erl index 2de51ce71d..8a1700e9cd 100644 --- a/lib/wx/src/gen/wxDatePickerCtrl.erl +++ b/lib/wx/src/gen/wxDatePickerCtrl.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -94,7 +94,7 @@ new(Parent,Id) new(Parent,Id, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> wxDatePickerCtrl() -%% Option = {date, wx:datetime()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {date, wx:datetime()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdatepickerctrl.html#wxdatepickerctrlwxdatepickerctrl">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> diff --git a/lib/wx/src/gen/wxDialog.erl b/lib/wx/src/gen/wxDialog.erl index 8c0bd2cd76..514a62813e 100644 --- a/lib/wx/src/gen/wxDialog.erl +++ b/lib/wx/src/gen/wxDialog.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -95,7 +95,7 @@ new(Parent,Id,Title) new(Parent,Id,Title, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), Title::string(), [Option]) -> wxDialog() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdialog.html#wxdialogwxdialog">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id,Title, Options) when is_integer(Id),is_list(Title),is_list(Options) -> @@ -116,7 +116,7 @@ create(This,Parent,Id,Title) create(This,Parent,Id,Title, []). %% @spec (This::wxDialog(), Parent::wxWindow:wxWindow(), Id::integer(), Title::string(), [Option]) -> bool() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdialog.html#wxdialogcreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,Title, Options) when is_integer(Id),is_list(Title),is_list(Options) -> diff --git a/lib/wx/src/gen/wxDirDialog.erl b/lib/wx/src/gen/wxDirDialog.erl index 7849dce0a7..28db3daf1d 100644 --- a/lib/wx/src/gen/wxDirDialog.erl +++ b/lib/wx/src/gen/wxDirDialog.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -91,7 +91,7 @@ new(Parent) new(Parent, []). %% @spec (Parent::wxWindow:wxWindow(), [Option]) -> wxDirDialog() -%% Option = {title, string()} | {defaultPath, string()} | {style, integer()} | {pos, {X::integer(),Y::integer()}} | {sz, {W::integer(),H::integer()}} +%% Option = {title, string()} | {defaultPath, string()} | {style, integer()} | {pos, {X::integer(), Y::integer()}} | {sz, {W::integer(), H::integer()}} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdirdialog.html#wxdirdialogwxdirdialog">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef}, Options) when is_list(Options) -> diff --git a/lib/wx/src/gen/wxDirPickerCtrl.erl b/lib/wx/src/gen/wxDirPickerCtrl.erl index 7fb70b71e3..2b24bc4bb0 100644 --- a/lib/wx/src/gen/wxDirPickerCtrl.erl +++ b/lib/wx/src/gen/wxDirPickerCtrl.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -94,7 +94,7 @@ new(Parent,Id) new(Parent,Id, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> wxDirPickerCtrl() -%% Option = {path, string()} | {message, string()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {path, string()} | {message, string()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdirpickerctrl.html#wxdirpickerctrlwxdirpickerctrl">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> @@ -117,7 +117,7 @@ create(This,Parent,Id) create(This,Parent,Id, []). %% @spec (This::wxDirPickerCtrl(), Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> bool() -%% Option = {path, string()} | {message, string()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {path, string()} | {message, string()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxdirpickerctrl.html#wxdirpickerctrlcreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> diff --git a/lib/wx/src/gen/wxEvtHandler.erl b/lib/wx/src/gen/wxEvtHandler.erl index f155351b66..820c2b7a58 100644 --- a/lib/wx/src/gen/wxEvtHandler.erl +++ b/lib/wx/src/gen/wxEvtHandler.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -95,7 +95,7 @@ parse_opts([{callback,Fun}|R], Opts) when is_function(Fun) -> %% Check Fun Arity? parse_opts(R, Opts#evh{cb=Fun}); parse_opts([callback|R], Opts) -> - parse_opts(R, Opts#evh{cb=1}); + parse_opts(R, Opts#evh{cb=self()}); parse_opts([{userData, UserData}|R],Opts) -> parse_opts(R, Opts#evh{userdata=UserData}); parse_opts([{skip, Skip}|R],Opts) when is_boolean(Skip) -> diff --git a/lib/wx/src/gen/wxFileDialog.erl b/lib/wx/src/gen/wxFileDialog.erl index cba9705335..c6779927e9 100644 --- a/lib/wx/src/gen/wxFileDialog.erl +++ b/lib/wx/src/gen/wxFileDialog.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -93,7 +93,7 @@ new(Parent) new(Parent, []). %% @spec (Parent::wxWindow:wxWindow(), [Option]) -> wxFileDialog() -%% Option = {message, string()} | {defaultDir, string()} | {defaultFile, string()} | {wildCard, string()} | {style, integer()} | {pos, {X::integer(),Y::integer()}} | {sz, {W::integer(),H::integer()}} +%% Option = {message, string()} | {defaultDir, string()} | {defaultFile, string()} | {wildCard, string()} | {style, integer()} | {pos, {X::integer(), Y::integer()}} | {sz, {W::integer(), H::integer()}} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxfiledialog.html#wxfiledialogwxfiledialog">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef}, Options) when is_list(Options) -> diff --git a/lib/wx/src/gen/wxFilePickerCtrl.erl b/lib/wx/src/gen/wxFilePickerCtrl.erl index a3034aaa86..93bfa72380 100644 --- a/lib/wx/src/gen/wxFilePickerCtrl.erl +++ b/lib/wx/src/gen/wxFilePickerCtrl.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -94,7 +94,7 @@ new(Parent,Id) new(Parent,Id, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> wxFilePickerCtrl() -%% Option = {path, string()} | {message, string()} | {wildcard, string()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {path, string()} | {message, string()} | {wildcard, string()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxfilepickerctrl.html#wxfilepickerctrlwxfilepickerctrl">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> @@ -118,7 +118,7 @@ create(This,Parent,Id) create(This,Parent,Id, []). %% @spec (This::wxFilePickerCtrl(), Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> bool() -%% Option = {path, string()} | {message, string()} | {wildcard, string()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {path, string()} | {message, string()} | {wildcard, string()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxfilepickerctrl.html#wxfilepickerctrlcreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> diff --git a/lib/wx/src/gen/wxFontPickerCtrl.erl b/lib/wx/src/gen/wxFontPickerCtrl.erl index 93d63cc930..3050011b60 100644 --- a/lib/wx/src/gen/wxFontPickerCtrl.erl +++ b/lib/wx/src/gen/wxFontPickerCtrl.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -95,7 +95,7 @@ new(Parent,Id) new(Parent,Id, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> wxFontPickerCtrl() -%% Option = {initial, wxFont:wxFont()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {initial, wxFont:wxFont()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxfontpickerctrl.html#wxfontpickerctrlwxfontpickerctrl">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> @@ -117,7 +117,7 @@ create(This,Parent,Id) create(This,Parent,Id, []). %% @spec (This::wxFontPickerCtrl(), Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> bool() -%% Option = {initial, wxFont:wxFont()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {initial, wxFont:wxFont()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxfontpickerctrl.html#wxfontpickerctrlcreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> diff --git a/lib/wx/src/gen/wxFrame.erl b/lib/wx/src/gen/wxFrame.erl index 5cd1e3dfd3..7e25bc8762 100644 --- a/lib/wx/src/gen/wxFrame.erl +++ b/lib/wx/src/gen/wxFrame.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -97,7 +97,7 @@ new(Parent,Id,Title) new(Parent,Id,Title, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), Title::string(), [Option]) -> wxFrame() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxframe.html#wxframewxframe">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id,Title, Options) when is_integer(Id),is_list(Title),is_list(Options) -> @@ -118,7 +118,7 @@ create(This,Parent,Id,Title) create(This,Parent,Id,Title, []). %% @spec (This::wxFrame(), Parent::wxWindow:wxWindow(), Id::integer(), Title::string(), [Option]) -> bool() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxframe.html#wxframecreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,Title, Options) when is_integer(Id),is_list(Title),is_list(Options) -> @@ -172,7 +172,7 @@ createToolBar(#wx_ref{type=ThisT,ref=ThisRef}, Options) wxe_util:call(?wxFrame_CreateToolBar, <<ThisRef:32/?UI, 0:32,BinOpt/binary>>). -%% @spec (This::wxFrame()) -> {X::integer(),Y::integer()} +%% @spec (This::wxFrame()) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxframe.html#wxframegetclientareaorigin">external documentation</a>. getClientAreaOrigin(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxFrame), diff --git a/lib/wx/src/gen/wxGLCanvas.erl b/lib/wx/src/gen/wxGLCanvas.erl index 032d42535d..a30d8cefd9 100644 --- a/lib/wx/src/gen/wxGLCanvas.erl +++ b/lib/wx/src/gen/wxGLCanvas.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -86,7 +86,7 @@ new(Parent) %% new(Parent::wxWindow:wxWindow(), Shared::wxGLContext:wxGLContext() | wxGLCanvas()) -> new(Parent,Shared, []) </c></p> %% <p><c> %% new(Parent::wxWindow:wxWindow(), [Option]) -> wxGLCanvas() </c> -%%<br /> Option = {id, integer()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {name, string()} | {attribList, [integer()]} | {palette, wxPalette:wxPalette()} +%%<br /> Option = {id, integer()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {name, string()} | {attribList, [integer()]} | {palette, wxPalette:wxPalette()} %% </p> new(Parent,Shared) @@ -109,7 +109,7 @@ new(#wx_ref{type=ParentT,ref=ParentRef}, Options) <<ParentRef:32/?UI, 0:32,BinOpt/binary>>). %% @spec (Parent::wxWindow:wxWindow(), Shared::wxGLContext:wxGLContext() | wxGLCanvas(), [Option]) -> wxGLCanvas() -%% Option = {id, integer()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {name, string()} | {attribList, [integer()]} | {palette, wxPalette:wxPalette()} +%% Option = {id, integer()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {name, string()} | {attribList, [integer()]} | {palette, wxPalette:wxPalette()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxglcanvas.html#wxglcanvaswxglcanvas">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},#wx_ref{type=SharedT,ref=SharedRef}, Options) when is_list(Options) -> diff --git a/lib/wx/src/gen/wxGauge.erl b/lib/wx/src/gen/wxGauge.erl index 5028b29bba..484fd36936 100644 --- a/lib/wx/src/gen/wxGauge.erl +++ b/lib/wx/src/gen/wxGauge.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -90,7 +90,7 @@ new(Parent,Id,Range) new(Parent,Id,Range, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), Range::integer(), [Option]) -> wxGauge() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgauge.html#wxgaugewxgauge">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id,Range, Options) when is_integer(Id),is_integer(Range),is_list(Options) -> @@ -111,7 +111,7 @@ create(This,Parent,Id,Range) create(This,Parent,Id,Range, []). %% @spec (This::wxGauge(), Parent::wxWindow:wxWindow(), Id::integer(), Range::integer(), [Option]) -> bool() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgauge.html#wxgaugecreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,Range, Options) when is_integer(Id),is_integer(Range),is_list(Options) -> diff --git a/lib/wx/src/gen/wxGenericDirCtrl.erl b/lib/wx/src/gen/wxGenericDirCtrl.erl index 97944710f0..626a454d2a 100644 --- a/lib/wx/src/gen/wxGenericDirCtrl.erl +++ b/lib/wx/src/gen/wxGenericDirCtrl.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -91,7 +91,7 @@ new(Parent) new(Parent, []). %% @spec (Parent::wxWindow:wxWindow(), [Option]) -> wxGenericDirCtrl() -%% Option = {id, integer()} | {dir, string()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {filter, string()} | {defaultFilter, integer()} +%% Option = {id, integer()} | {dir, string()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {filter, string()} | {defaultFilter, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgenericdirctrl.html#wxgenericdirctrlwxgenericdirctrl">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef}, Options) when is_list(Options) -> @@ -115,7 +115,7 @@ create(This,Parent) create(This,Parent, []). %% @spec (This::wxGenericDirCtrl(), Parent::wxWindow:wxWindow(), [Option]) -> bool() -%% Option = {id, integer()} | {dir, string()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {filter, string()} | {defaultFilter, integer()} +%% Option = {id, integer()} | {dir, string()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {filter, string()} | {defaultFilter, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgenericdirctrl.html#wxgenericdirctrlcreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef}, Options) when is_list(Options) -> diff --git a/lib/wx/src/gen/wxGraphicsContext.erl b/lib/wx/src/gen/wxGraphicsContext.erl index 040867cb11..05c56dd4b2 100644 --- a/lib/wx/src/gen/wxGraphicsContext.erl +++ b/lib/wx/src/gen/wxGraphicsContext.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -192,13 +192,13 @@ drawIcon(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=IconT,ref=IconRef},X,Y,W,H wxe_util:cast(?wxGraphicsContext_DrawIcon, <<ThisRef:32/?UI,IconRef:32/?UI,X:64/?F,Y:64/?F,W:64/?F,H:64/?F>>). -%% @spec (This::wxGraphicsContext(), N::integer(), Points::{X::float(),Y::float()}) -> ok +%% @spec (This::wxGraphicsContext(), N::integer(), Points::{X::float(), Y::float()}) -> ok %% @equiv drawLines(This,N,Points, []) drawLines(This,N,Points={PointsX,PointsY}) when is_record(This, wx_ref),is_integer(N),is_number(PointsX),is_number(PointsY) -> drawLines(This,N,Points, []). -%% @spec (This::wxGraphicsContext(), N::integer(), Points::{X::float(),Y::float()}, [Option]) -> ok +%% @spec (This::wxGraphicsContext(), N::integer(), Points::{X::float(), Y::float()}, [Option]) -> ok %% Option = {fillStyle, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgraphicscontext.html#wxgraphicscontextdrawlines">external documentation</a>. drawLines(#wx_ref{type=ThisT,ref=ThisRef},N,{PointsX,PointsY}, Options) @@ -331,7 +331,7 @@ getPartialTextExtents(#wx_ref{type=ThisT,ref=ThisRef},Text,Widths) <<ThisRef:32/?UI,(byte_size(Text_UC)):32/?UI,(Text_UC)/binary, 0:(((8- ((0+byte_size(Text_UC)) band 16#7)) band 16#7))/unit:8,(length(Widths)):32/?UI, 0:32, (<< <<C:64/float>> || C <- Widths>>)/binary>>). -%% @spec (This::wxGraphicsContext(), Text::string()) -> {Width::float(),Height::float(),Descent::float(),ExternalLeading::float()} +%% @spec (This::wxGraphicsContext(), Text::string()) -> {Width::float(), Height::float(), Descent::float(), ExternalLeading::float()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgraphicscontext.html#wxgraphicscontextgettextextent">external documentation</a>. getTextExtent(#wx_ref{type=ThisT,ref=ThisRef},Text) when is_list(Text) -> @@ -438,7 +438,7 @@ strokeLine(#wx_ref{type=ThisT,ref=ThisRef},X1,Y1,X2,Y2) wxe_util:cast(?wxGraphicsContext_StrokeLine, <<ThisRef:32/?UI,0:32,X1:64/?F,Y1:64/?F,X2:64/?F,Y2:64/?F>>). -%% @spec (This::wxGraphicsContext(), N::integer(), Points::{X::float(),Y::float()}) -> ok +%% @spec (This::wxGraphicsContext(), N::integer(), Points::{X::float(), Y::float()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgraphicscontext.html#wxgraphicscontextstrokelines">external documentation</a>. strokeLines(#wx_ref{type=ThisT,ref=ThisRef},N,{PointsX,PointsY}) when is_integer(N),is_number(PointsX),is_number(PointsY) -> @@ -446,7 +446,7 @@ strokeLines(#wx_ref{type=ThisT,ref=ThisRef},N,{PointsX,PointsY}) wxe_util:cast(?wxGraphicsContext_StrokeLines_2, <<ThisRef:32/?UI,N:32/?UI,PointsX:64/float,PointsY:64/float>>). -%% @spec (This::wxGraphicsContext(), N::integer(), BeginPoints::{X::float(),Y::float()}, EndPoints::{X::float(),Y::float()}) -> ok +%% @spec (This::wxGraphicsContext(), N::integer(), BeginPoints::{X::float(), Y::float()}, EndPoints::{X::float(), Y::float()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgraphicscontext.html#wxgraphicscontextstrokelines">external documentation</a>. strokeLines(#wx_ref{type=ThisT,ref=ThisRef},N,{BeginPointsX,BeginPointsY},{EndPointsX,EndPointsY}) when is_integer(N),is_number(BeginPointsX),is_number(BeginPointsY),is_number(EndPointsX),is_number(EndPointsY) -> diff --git a/lib/wx/src/gen/wxGraphicsMatrix.erl b/lib/wx/src/gen/wxGraphicsMatrix.erl index 38ea007c58..635a2027b3 100644 --- a/lib/wx/src/gen/wxGraphicsMatrix.erl +++ b/lib/wx/src/gen/wxGraphicsMatrix.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -45,7 +45,7 @@ concat(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=TT,ref=TRef}) -> wxe_util:cast(?wxGraphicsMatrix_Concat, <<ThisRef:32/?UI,TRef:32/?UI>>). -%% @spec (This::wxGraphicsMatrix()) -> {A::float(),B::float(),C::float(),D::float(),Tx::float(),Ty::float()} +%% @spec (This::wxGraphicsMatrix()) -> {A::float(), B::float(), C::float(), D::float(), Tx::float(), Ty::float()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgraphicsmatrix.html#wxgraphicsmatrixget">external documentation</a>. get(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxGraphicsMatrix), @@ -128,14 +128,14 @@ set(#wx_ref{type=ThisT,ref=ThisRef}, Options) wxe_util:cast(?wxGraphicsMatrix_Set, <<ThisRef:32/?UI, 0:32,BinOpt/binary>>). -%% @spec (This::wxGraphicsMatrix()) -> {X::float(),Y::float()} +%% @spec (This::wxGraphicsMatrix()) -> {X::float(), Y::float()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgraphicsmatrix.html#wxgraphicsmatrixtransformpoint">external documentation</a>. transformPoint(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxGraphicsMatrix), wxe_util:call(?wxGraphicsMatrix_TransformPoint, <<ThisRef:32/?UI>>). -%% @spec (This::wxGraphicsMatrix()) -> {Dx::float(),Dy::float()} +%% @spec (This::wxGraphicsMatrix()) -> {Dx::float(), Dy::float()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgraphicsmatrix.html#wxgraphicsmatrixtransformdistance">external documentation</a>. transformDistance(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxGraphicsMatrix), diff --git a/lib/wx/src/gen/wxGraphicsPath.erl b/lib/wx/src/gen/wxGraphicsPath.erl index ff2dfb07a4..e41496c641 100644 --- a/lib/wx/src/gen/wxGraphicsPath.erl +++ b/lib/wx/src/gen/wxGraphicsPath.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -40,7 +40,7 @@ parent_class(wxGraphicsObject) -> true; parent_class(_Class) -> erlang:error({badtype, ?MODULE}). -%% @spec (This::wxGraphicsPath(), P::{X::float(),Y::float()}) -> ok +%% @spec (This::wxGraphicsPath(), P::{X::float(), Y::float()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgraphicspath.html#wxgraphicspathmovetopoint">external documentation</a>. moveToPoint(#wx_ref{type=ThisT,ref=ThisRef},{PX,PY}) when is_number(PX),is_number(PY) -> @@ -56,7 +56,7 @@ moveToPoint(#wx_ref{type=ThisT,ref=ThisRef},X,Y) wxe_util:cast(?wxGraphicsPath_MoveToPoint_2, <<ThisRef:32/?UI,0:32,X:64/?F,Y:64/?F>>). -%% @spec (This::wxGraphicsPath(), C::{X::float(),Y::float()}, R::float(), StartAngle::float(), EndAngle::float(), Clockwise::bool()) -> ok +%% @spec (This::wxGraphicsPath(), C::{X::float(), Y::float()}, R::float(), StartAngle::float(), EndAngle::float(), Clockwise::bool()) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgraphicspath.html#wxgraphicspathaddarc">external documentation</a>. addArc(#wx_ref{type=ThisT,ref=ThisRef},{CX,CY},R,StartAngle,EndAngle,Clockwise) when is_number(CX),is_number(CY),is_float(R),is_float(StartAngle),is_float(EndAngle),is_boolean(Clockwise) -> @@ -88,7 +88,7 @@ addCircle(#wx_ref{type=ThisT,ref=ThisRef},X,Y,R) wxe_util:cast(?wxGraphicsPath_AddCircle, <<ThisRef:32/?UI,0:32,X:64/?F,Y:64/?F,R:64/?F>>). -%% @spec (This::wxGraphicsPath(), C1::{X::float(),Y::float()}, C2::{X::float(),Y::float()}, E::{X::float(),Y::float()}) -> ok +%% @spec (This::wxGraphicsPath(), C1::{X::float(), Y::float()}, C2::{X::float(), Y::float()}, E::{X::float(), Y::float()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgraphicspath.html#wxgraphicspathaddcurvetopoint">external documentation</a>. addCurveToPoint(#wx_ref{type=ThisT,ref=ThisRef},{C1X,C1Y},{C2X,C2Y},{EX,EY}) when is_number(C1X),is_number(C1Y),is_number(C2X),is_number(C2Y),is_number(EX),is_number(EY) -> @@ -112,7 +112,7 @@ addEllipse(#wx_ref{type=ThisT,ref=ThisRef},X,Y,W,H) wxe_util:cast(?wxGraphicsPath_AddEllipse, <<ThisRef:32/?UI,0:32,X:64/?F,Y:64/?F,W:64/?F,H:64/?F>>). -%% @spec (This::wxGraphicsPath(), P::{X::float(),Y::float()}) -> ok +%% @spec (This::wxGraphicsPath(), P::{X::float(), Y::float()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgraphicspath.html#wxgraphicspathaddlinetopoint">external documentation</a>. addLineToPoint(#wx_ref{type=ThisT,ref=ThisRef},{PX,PY}) when is_number(PX),is_number(PY) -> @@ -167,7 +167,7 @@ closeSubpath(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:cast(?wxGraphicsPath_CloseSubpath, <<ThisRef:32/?UI>>). -%% @spec (This::wxGraphicsPath(), C::{X::float(),Y::float()}) -> bool() +%% @spec (This::wxGraphicsPath(), C::{X::float(), Y::float()}) -> bool() %% @equiv contains(This,C, []) contains(This,C={CX,CY}) when is_record(This, wx_ref),is_number(CX),is_number(CY) -> @@ -179,7 +179,7 @@ contains(This,C={CX,CY}) %% <p><c> %% contains(This::wxGraphicsPath(), X::float(), Y::float()) -> contains(This,X,Y, []) </c></p> %% <p><c> -%% contains(This::wxGraphicsPath(), C::{X::float(),Y::float()}, [Option]) -> bool() </c> +%% contains(This::wxGraphicsPath(), C::{X::float(), Y::float()}, [Option]) -> bool() </c> %%<br /> Option = {fillStyle, integer()} %% </p> @@ -207,14 +207,14 @@ contains(#wx_ref{type=ThisT,ref=ThisRef},X,Y, Options) wxe_util:call(?wxGraphicsPath_Contains_3, <<ThisRef:32/?UI,0:32,X:64/?F,Y:64/?F, BinOpt/binary>>). -%% @spec (This::wxGraphicsPath()) -> {X::float(),Y::float(),W::float(),H::float()} +%% @spec (This::wxGraphicsPath()) -> {X::float(), Y::float(), W::float(), H::float()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgraphicspath.html#wxgraphicspathgetbox">external documentation</a>. getBox(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxGraphicsPath), wxe_util:call(?wxGraphicsPath_GetBox, <<ThisRef:32/?UI>>). -%% @spec (This::wxGraphicsPath()) -> {X::float(),Y::float()} +%% @spec (This::wxGraphicsPath()) -> {X::float(), Y::float()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgraphicspath.html#wxgraphicspathgetcurrentpoint">external documentation</a>. getCurrentPoint(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxGraphicsPath), diff --git a/lib/wx/src/gen/wxGrid.erl b/lib/wx/src/gen/wxGrid.erl index 7b62ec33a4..531fed05c1 100644 --- a/lib/wx/src/gen/wxGrid.erl +++ b/lib/wx/src/gen/wxGrid.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -151,7 +151,7 @@ new(Parent,Id) %% new(Parent::wxWindow:wxWindow(), X::integer(), Y::integer()) -> new(Parent,X,Y, []) </c></p> %% <p><c> %% new(Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> wxGrid() </c> -%%<br /> Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%%<br /> Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% </p> new(Parent,X,Y) @@ -306,7 +306,7 @@ beginBatch(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:cast(?wxGrid_BeginBatch, <<ThisRef:32/?UI>>). -%% @spec (This::wxGrid(), TopLeft::{R::integer(),C::integer()}, BottomRight::{R::integer(),C::integer()}) -> {X::integer(),Y::integer(),W::integer(),H::integer()} +%% @spec (This::wxGrid(), TopLeft::{R::integer(), C::integer()}, BottomRight::{R::integer(), C::integer()}) -> {X::integer(), Y::integer(), W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgrid.html#wxgridblocktodevicerect">external documentation</a>. blockToDeviceRect(#wx_ref{type=ThisT,ref=ThisRef},{TopLeftR,TopLeftC},{BottomRightR,BottomRightC}) when is_integer(TopLeftR),is_integer(TopLeftC),is_integer(BottomRightR),is_integer(BottomRightC) -> @@ -342,7 +342,7 @@ canEnableCellControl(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxGrid_CanEnableCellControl, <<ThisRef:32/?UI>>). -%% @spec (This::wxGrid(), Coords::{R::integer(),C::integer()}) -> {X::integer(),Y::integer(),W::integer(),H::integer()} +%% @spec (This::wxGrid(), Coords::{R::integer(), C::integer()}) -> {X::integer(), Y::integer(), W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgrid.html#wxgridcelltorect">external documentation</a>. cellToRect(#wx_ref{type=ThisT,ref=ThisRef},{CoordsR,CoordsC}) when is_integer(CoordsR),is_integer(CoordsC) -> @@ -350,7 +350,7 @@ cellToRect(#wx_ref{type=ThisT,ref=ThisRef},{CoordsR,CoordsC}) wxe_util:call(?wxGrid_CellToRect_1, <<ThisRef:32/?UI,CoordsR:32/?UI,CoordsC:32/?UI>>). -%% @spec (This::wxGrid(), Row::integer(), Col::integer()) -> {X::integer(),Y::integer(),W::integer(),H::integer()} +%% @spec (This::wxGrid(), Row::integer(), Col::integer()) -> {X::integer(), Y::integer(), W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgrid.html#wxgridcelltorect">external documentation</a>. cellToRect(#wx_ref{type=ThisT,ref=ThisRef},Row,Col) when is_integer(Row),is_integer(Col) -> @@ -586,7 +586,7 @@ getBatchCount(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxGrid_GetBatchCount, <<ThisRef:32/?UI>>). -%% @spec (This::wxGrid(), Row::integer(), Col::integer()) -> {Horiz::integer(),Vert::integer()} +%% @spec (This::wxGrid(), Row::integer(), Col::integer()) -> {Horiz::integer(), Vert::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgrid.html#wxgridgetcellalignment">external documentation</a>. getCellAlignment(#wx_ref{type=ThisT,ref=ThisRef},Row,Col) when is_integer(Row),is_integer(Col) -> @@ -634,7 +634,7 @@ getCellTextColour(#wx_ref{type=ThisT,ref=ThisRef},Row,Col) wxe_util:call(?wxGrid_GetCellTextColour, <<ThisRef:32/?UI,Row:32/?UI,Col:32/?UI>>). -%% @spec (This::wxGrid(), Coords::{R::integer(),C::integer()}) -> string() +%% @spec (This::wxGrid(), Coords::{R::integer(), C::integer()}) -> string() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgrid.html#wxgridgetcellvalue">external documentation</a>. getCellValue(#wx_ref{type=ThisT,ref=ThisRef},{CoordsR,CoordsC}) when is_integer(CoordsR),is_integer(CoordsC) -> @@ -650,7 +650,7 @@ getCellValue(#wx_ref{type=ThisT,ref=ThisRef},Row,Col) wxe_util:call(?wxGrid_GetCellValue_2, <<ThisRef:32/?UI,Row:32/?UI,Col:32/?UI>>). -%% @spec (This::wxGrid()) -> {Horiz::integer(),Vert::integer()} +%% @spec (This::wxGrid()) -> {Horiz::integer(), Vert::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgrid.html#wxgridgetcollabelalignment">external documentation</a>. getColLabelAlignment(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxGrid), @@ -679,7 +679,7 @@ getColMinimalAcceptableWidth(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxGrid_GetColMinimalAcceptableWidth, <<ThisRef:32/?UI>>). -%% @spec (This::wxGrid()) -> {Horiz::integer(),Vert::integer()} +%% @spec (This::wxGrid()) -> {Horiz::integer(), Vert::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgrid.html#wxgridgetdefaultcellalignment">external documentation</a>. getDefaultCellAlignment(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxGrid), @@ -728,7 +728,7 @@ getDefaultEditor(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxGrid_GetDefaultEditor, <<ThisRef:32/?UI>>). -%% @spec (This::wxGrid(), C::{R::integer(),C::integer()}) -> wxGridCellEditor:wxGridCellEditor() +%% @spec (This::wxGrid(), C::{R::integer(), C::integer()}) -> wxGridCellEditor:wxGridCellEditor() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgrid.html#wxgridgetdefaulteditorforcell">external documentation</a>. getDefaultEditorForCell(#wx_ref{type=ThisT,ref=ThisRef},{CR,CC}) when is_integer(CR),is_integer(CC) -> @@ -869,7 +869,7 @@ getRowMinimalAcceptableHeight(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxGrid_GetRowMinimalAcceptableHeight, <<ThisRef:32/?UI>>). -%% @spec (This::wxGrid()) -> {Horiz::integer(),Vert::integer()} +%% @spec (This::wxGrid()) -> {Horiz::integer(), Vert::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgrid.html#wxgridgetrowlabelalignment">external documentation</a>. getRowLabelAlignment(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxGrid), @@ -913,7 +913,7 @@ getScrollLineY(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxGrid_GetScrollLineY, <<ThisRef:32/?UI>>). -%% @spec (This::wxGrid()) -> [{R::integer(),C::integer()}] +%% @spec (This::wxGrid()) -> [{R::integer(), C::integer()}] %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgrid.html#wxgridgetselectedcells">external documentation</a>. getSelectedCells(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxGrid), @@ -941,14 +941,14 @@ getSelectionBackground(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxGrid_GetSelectionBackground, <<ThisRef:32/?UI>>). -%% @spec (This::wxGrid()) -> [{R::integer(),C::integer()}] +%% @spec (This::wxGrid()) -> [{R::integer(), C::integer()}] %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgrid.html#wxgridgetselectionblocktopleft">external documentation</a>. getSelectionBlockTopLeft(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxGrid), wxe_util:call(?wxGrid_GetSelectionBlockTopLeft, <<ThisRef:32/?UI>>). -%% @spec (This::wxGrid()) -> [{R::integer(),C::integer()}] +%% @spec (This::wxGrid()) -> [{R::integer(), C::integer()}] %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgrid.html#wxgridgetselectionblockbottomright">external documentation</a>. getSelectionBlockBottomRight(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxGrid), @@ -1065,7 +1065,7 @@ isEditable(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxGrid_IsEditable, <<ThisRef:32/?UI>>). -%% @spec (This::wxGrid(), Coords::{R::integer(),C::integer()}) -> bool() +%% @spec (This::wxGrid(), Coords::{R::integer(), C::integer()}) -> bool() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgrid.html#wxgridisinselection">external documentation</a>. isInSelection(#wx_ref{type=ThisT,ref=ThisRef},{CoordsR,CoordsC}) when is_integer(CoordsR),is_integer(CoordsC) -> @@ -1096,7 +1096,7 @@ isSelection(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxGrid_IsSelection, <<ThisRef:32/?UI>>). -%% @spec (This::wxGrid(), Coords::{R::integer(),C::integer()}) -> bool() +%% @spec (This::wxGrid(), Coords::{R::integer(), C::integer()}) -> bool() %% @equiv isVisible(This,Coords, []) isVisible(This,Coords={CoordsR,CoordsC}) when is_record(This, wx_ref),is_integer(CoordsR),is_integer(CoordsC) -> @@ -1108,7 +1108,7 @@ isVisible(This,Coords={CoordsR,CoordsC}) %% <p><c> %% isVisible(This::wxGrid(), Row::integer(), Col::integer()) -> isVisible(This,Row,Col, []) </c></p> %% <p><c> -%% isVisible(This::wxGrid(), Coords::{R::integer(),C::integer()}, [Option]) -> bool() </c> +%% isVisible(This::wxGrid(), Coords::{R::integer(), C::integer()}, [Option]) -> bool() </c> %%<br /> Option = {wholeCellVisible, bool()} %% </p> @@ -1136,7 +1136,7 @@ isVisible(#wx_ref{type=ThisT,ref=ThisRef},Row,Col, Options) wxe_util:call(?wxGrid_IsVisible_3, <<ThisRef:32/?UI,Row:32/?UI,Col:32/?UI, 0:32,BinOpt/binary>>). -%% @spec (This::wxGrid(), Coords::{R::integer(),C::integer()}) -> ok +%% @spec (This::wxGrid(), Coords::{R::integer(), C::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgrid.html#wxgridmakecellvisible">external documentation</a>. makeCellVisible(#wx_ref{type=ThisT,ref=ThisRef},{CoordsR,CoordsC}) when is_integer(CoordsR),is_integer(CoordsC) -> @@ -1255,13 +1255,13 @@ selectAll(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:cast(?wxGrid_SelectAll, <<ThisRef:32/?UI>>). -%% @spec (This::wxGrid(), TopLeft::{R::integer(),C::integer()}, BottomRight::{R::integer(),C::integer()}) -> ok +%% @spec (This::wxGrid(), TopLeft::{R::integer(), C::integer()}, BottomRight::{R::integer(), C::integer()}) -> ok %% @equiv selectBlock(This,TopLeft,BottomRight, []) selectBlock(This,TopLeft={TopLeftR,TopLeftC},BottomRight={BottomRightR,BottomRightC}) when is_record(This, wx_ref),is_integer(TopLeftR),is_integer(TopLeftC),is_integer(BottomRightR),is_integer(BottomRightC) -> selectBlock(This,TopLeft,BottomRight, []). -%% @spec (This::wxGrid(), TopLeft::{R::integer(),C::integer()}, BottomRight::{R::integer(),C::integer()}, [Option]) -> ok +%% @spec (This::wxGrid(), TopLeft::{R::integer(), C::integer()}, BottomRight::{R::integer(), C::integer()}, [Option]) -> ok %% Option = {addToSelected, bool()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgrid.html#wxgridselectblock">external documentation</a>. selectBlock(#wx_ref{type=ThisT,ref=ThisRef},{TopLeftR,TopLeftC},{BottomRightR,BottomRightC}, Options) @@ -1434,7 +1434,7 @@ setCellTextColour(#wx_ref{type=ThisT,ref=ThisRef},Val,Row,Col) wxe_util:cast(?wxGrid_SetCellTextColour_3_1, <<ThisRef:32/?UI,(wxe_util:colour_bin(Val)):16/binary,Row:32/?UI,Col:32/?UI>>). -%% @spec (This::wxGrid(), Coords::{R::integer(),C::integer()}, S::string()) -> ok +%% @spec (This::wxGrid(), Coords::{R::integer(), C::integer()}, S::string()) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgrid.html#wxgridsetcellvalue">external documentation</a>. setCellValue(#wx_ref{type=ThisT,ref=ThisRef},{CoordsR,CoordsC},S) when is_integer(CoordsR),is_integer(CoordsC),is_list(S) -> diff --git a/lib/wx/src/gen/wxGridBagSizer.erl b/lib/wx/src/gen/wxGridBagSizer.erl index cfc182cf89..d2b8a2b045 100644 --- a/lib/wx/src/gen/wxGridBagSizer.erl +++ b/lib/wx/src/gen/wxGridBagSizer.erl @@ -90,7 +90,7 @@ add(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ItemT,ref=ItemRef}) -> %% <p><c> %% add(This::wxGridBagSizer(), Width::integer(), Height::integer()) -> add(This,Width,Height, []) </c></p> %% <p><c> -%% add(This::wxGridBagSizer(), Window::wxWindow:wxWindow() | wxSizer:wxSizer(), Pos::{R::integer(),C::integer()}) -> add(This,Window,Pos, []) </c></p> +%% add(This::wxGridBagSizer(), Window::wxWindow:wxWindow() | wxSizer:wxSizer(), Pos::{R::integer(), C::integer()}) -> add(This,Window,Pos, []) </c></p> %% <p><c> %% add(This::wxGridBagSizer(), Window::wxWindow:wxWindow() | wxSizer:wxSizer(), [Option]) -> wxSizerItem:wxSizerItem() </c> %%<br /> Option = {proportion, integer()} | {flag, integer()} | {border, integer()} | {userData, wx:wx()} @@ -125,14 +125,14 @@ add(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=WindowT,ref=WindowRef}, Options %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridbagsizer.html#wxgridbagsizeradd">external documentation</a>. %% <br /> Alternatives: %% <p><c> -%% add(This::wxGridBagSizer(), Width::integer(), Height::integer(), Pos::{R::integer(),C::integer()}) -> add(This,Width,Height,Pos, []) </c></p> +%% add(This::wxGridBagSizer(), Width::integer(), Height::integer(), Pos::{R::integer(), C::integer()}) -> add(This,Width,Height,Pos, []) </c></p> %% <p><c> %% add(This::wxGridBagSizer(), Width::integer(), Height::integer(), [Option]) -> wxSizerItem:wxSizerItem() </c> %%<br /> Option = {proportion, integer()} | {flag, integer()} | {border, integer()} | {userData, wx:wx()} %% </p> %% <p><c> -%% add(This::wxGridBagSizer(), Window::wxWindow:wxWindow() | wxSizer:wxSizer(), Pos::{R::integer(),C::integer()}, [Option]) -> wxSizerItem:wxSizerItem() </c> -%%<br /> Option = {span, {RS::integer(),CS::integer()}} | {flag, integer()} | {border, integer()} | {userData, wx:wx()} +%% add(This::wxGridBagSizer(), Window::wxWindow:wxWindow() | wxSizer:wxSizer(), Pos::{R::integer(), C::integer()}, [Option]) -> wxSizerItem:wxSizerItem() </c> +%%<br /> Option = {span, {RS::integer(), CS::integer()}} | {flag, integer()} | {border, integer()} | {userData, wx:wx()} %% </p> add(This,Width,Height,Pos={PosR,PosC}) @@ -167,8 +167,8 @@ add(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=WindowT,ref=WindowRef},{PosR,Po wxe_util:call(WindowOP, <<ThisRef:32/?UI,WindowRef:32/?UI,PosR:32/?UI,PosC:32/?UI, BinOpt/binary>>). -%% @spec (This::wxGridBagSizer(), Width::integer(), Height::integer(), Pos::{R::integer(),C::integer()}, [Option]) -> wxSizerItem:wxSizerItem() -%% Option = {span, {RS::integer(),CS::integer()}} | {flag, integer()} | {border, integer()} | {userData, wx:wx()} +%% @spec (This::wxGridBagSizer(), Width::integer(), Height::integer(), Pos::{R::integer(), C::integer()}, [Option]) -> wxSizerItem:wxSizerItem() +%% Option = {span, {RS::integer(), CS::integer()}} | {flag, integer()} | {border, integer()} | {userData, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridbagsizer.html#wxgridbagsizeradd">external documentation</a>. add(#wx_ref{type=ThisT,ref=ThisRef},Width,Height,{PosR,PosC}, Options) when is_integer(Width),is_integer(Height),is_integer(PosR),is_integer(PosC),is_list(Options) -> @@ -182,7 +182,7 @@ add(#wx_ref{type=ThisT,ref=ThisRef},Width,Height,{PosR,PosC}, Options) wxe_util:call(?wxGridBagSizer_Add_4, <<ThisRef:32/?UI,Width:32/?UI,Height:32/?UI,PosR:32/?UI,PosC:32/?UI, 0:32,BinOpt/binary>>). -%% @spec (This::wxGridBagSizer()) -> {W::integer(),H::integer()} +%% @spec (This::wxGridBagSizer()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridbagsizer.html#wxgridbagsizercalcmin">external documentation</a>. calcMin(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxGridBagSizer), @@ -199,7 +199,7 @@ checkForIntersection(This,Item) %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridbagsizer.html#wxgridbagsizercheckforintersection">external documentation</a>. %% <br /> Alternatives: %% <p><c> -%% checkForIntersection(This::wxGridBagSizer(), Pos::{R::integer(),C::integer()}, Span::{RS::integer(),CS::integer()}) -> checkForIntersection(This,Pos,Span, []) </c></p> +%% checkForIntersection(This::wxGridBagSizer(), Pos::{R::integer(), C::integer()}, Span::{RS::integer(), CS::integer()}) -> checkForIntersection(This,Pos,Span, []) </c></p> %% <p><c> %% checkForIntersection(This::wxGridBagSizer(), Item::wxGBSizerItem:wxGBSizerItem(), [Option]) -> bool() </c> %%<br /> Option = {excludeItem, wxGBSizerItem:wxGBSizerItem()} @@ -218,7 +218,7 @@ checkForIntersection(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ItemT,ref=Item wxe_util:call(?wxGridBagSizer_CheckForIntersection_2, <<ThisRef:32/?UI,ItemRef:32/?UI, BinOpt/binary>>). -%% @spec (This::wxGridBagSizer(), Pos::{R::integer(),C::integer()}, Span::{RS::integer(),CS::integer()}, [Option]) -> bool() +%% @spec (This::wxGridBagSizer(), Pos::{R::integer(), C::integer()}, Span::{RS::integer(), CS::integer()}, [Option]) -> bool() %% Option = {excludeItem, wxGBSizerItem:wxGBSizerItem()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridbagsizer.html#wxgridbagsizercheckforintersection">external documentation</a>. checkForIntersection(#wx_ref{type=ThisT,ref=ThisRef},{PosR,PosC},{SpanRS,SpanCS}, Options) @@ -243,7 +243,7 @@ findItem(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=WindowT,ref=WindowRef}) -> wxe_util:call(WindowOP, <<ThisRef:32/?UI,WindowRef:32/?UI>>). -%% @spec (This::wxGridBagSizer(), Pt::{X::integer(),Y::integer()}) -> wxGBSizerItem:wxGBSizerItem() +%% @spec (This::wxGridBagSizer(), Pt::{X::integer(), Y::integer()}) -> wxGBSizerItem:wxGBSizerItem() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridbagsizer.html#wxgridbagsizerfinditematpoint">external documentation</a>. findItemAtPoint(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) when is_integer(PtX),is_integer(PtY) -> @@ -251,7 +251,7 @@ findItemAtPoint(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) wxe_util:call(?wxGridBagSizer_FindItemAtPoint, <<ThisRef:32/?UI,PtX:32/?UI,PtY:32/?UI>>). -%% @spec (This::wxGridBagSizer(), Pos::{R::integer(),C::integer()}) -> wxGBSizerItem:wxGBSizerItem() +%% @spec (This::wxGridBagSizer(), Pos::{R::integer(), C::integer()}) -> wxGBSizerItem:wxGBSizerItem() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridbagsizer.html#wxgridbagsizerfinditematposition">external documentation</a>. findItemAtPosition(#wx_ref{type=ThisT,ref=ThisRef},{PosR,PosC}) when is_integer(PosR),is_integer(PosC) -> @@ -267,7 +267,7 @@ findItemWithData(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=UserDataT,ref=User wxe_util:call(?wxGridBagSizer_FindItemWithData, <<ThisRef:32/?UI,UserDataRef:32/?UI>>). -%% @spec (This::wxGridBagSizer(), Row::integer(), Col::integer()) -> {W::integer(),H::integer()} +%% @spec (This::wxGridBagSizer(), Row::integer(), Col::integer()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridbagsizer.html#wxgridbagsizergetcellsize">external documentation</a>. getCellSize(#wx_ref{type=ThisT,ref=ThisRef},Row,Col) when is_integer(Row),is_integer(Col) -> @@ -275,21 +275,21 @@ getCellSize(#wx_ref{type=ThisT,ref=ThisRef},Row,Col) wxe_util:call(?wxGridBagSizer_GetCellSize, <<ThisRef:32/?UI,Row:32/?UI,Col:32/?UI>>). -%% @spec (This::wxGridBagSizer()) -> {W::integer(),H::integer()} +%% @spec (This::wxGridBagSizer()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridbagsizer.html#wxgridbagsizergetemptycellsize">external documentation</a>. getEmptyCellSize(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxGridBagSizer), wxe_util:call(?wxGridBagSizer_GetEmptyCellSize, <<ThisRef:32/?UI>>). -%% @spec (This::wxGridBagSizer(),X::integer()|term()) -> {R::integer(),C::integer()} +%% @spec (This::wxGridBagSizer(),X::integer()|term()) -> {R::integer(), C::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridbagsizer.html#wxgridbagsizergetitemposition">external documentation</a>. %% <br /> Alternatives: %% <p><c> -%% getItemPosition(This::wxGridBagSizer(), Index::integer()) -> {R::integer(),C::integer()} </c> +%% getItemPosition(This::wxGridBagSizer(), Index::integer()) -> {R::integer(), C::integer()} </c> %% </p> %% <p><c> -%% getItemPosition(This::wxGridBagSizer(), Window::wxWindow:wxWindow() | wxSizer:wxSizer()) -> {R::integer(),C::integer()} </c> +%% getItemPosition(This::wxGridBagSizer(), Window::wxWindow:wxWindow() | wxSizer:wxSizer()) -> {R::integer(), C::integer()} </c> %% </p> getItemPosition(#wx_ref{type=ThisT,ref=ThisRef},Index) when is_integer(Index) -> @@ -307,14 +307,14 @@ getItemPosition(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=WindowT,ref=WindowR wxe_util:call(WindowOP, <<ThisRef:32/?UI,WindowRef:32/?UI>>). -%% @spec (This::wxGridBagSizer(),X::integer()|term()) -> {RS::integer(),CS::integer()} +%% @spec (This::wxGridBagSizer(),X::integer()|term()) -> {RS::integer(), CS::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridbagsizer.html#wxgridbagsizergetitemspan">external documentation</a>. %% <br /> Alternatives: %% <p><c> -%% getItemSpan(This::wxGridBagSizer(), Index::integer()) -> {RS::integer(),CS::integer()} </c> +%% getItemSpan(This::wxGridBagSizer(), Index::integer()) -> {RS::integer(), CS::integer()} </c> %% </p> %% <p><c> -%% getItemSpan(This::wxGridBagSizer(), Window::wxWindow:wxWindow() | wxSizer:wxSizer()) -> {RS::integer(),CS::integer()} </c> +%% getItemSpan(This::wxGridBagSizer(), Window::wxWindow:wxWindow() | wxSizer:wxSizer()) -> {RS::integer(), CS::integer()} </c> %% </p> getItemSpan(#wx_ref{type=ThisT,ref=ThisRef},Index) when is_integer(Index) -> @@ -332,7 +332,7 @@ getItemSpan(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=WindowT,ref=WindowRef}) wxe_util:call(WindowOP, <<ThisRef:32/?UI,WindowRef:32/?UI>>). -%% @spec (This::wxGridBagSizer(), Sz::{W::integer(),H::integer()}) -> ok +%% @spec (This::wxGridBagSizer(), Sz::{W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridbagsizer.html#wxgridbagsizersetemptycellsize">external documentation</a>. setEmptyCellSize(#wx_ref{type=ThisT,ref=ThisRef},{SzW,SzH}) when is_integer(SzW),is_integer(SzH) -> @@ -340,14 +340,14 @@ setEmptyCellSize(#wx_ref{type=ThisT,ref=ThisRef},{SzW,SzH}) wxe_util:cast(?wxGridBagSizer_SetEmptyCellSize, <<ThisRef:32/?UI,SzW:32/?UI,SzH:32/?UI>>). -%% @spec (This::wxGridBagSizer(),X::integer()|term(),Pos::{R::integer(),C::integer()}) -> bool() +%% @spec (This::wxGridBagSizer(),X::integer()|term(),Pos::{R::integer(), C::integer()}) -> bool() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridbagsizer.html#wxgridbagsizersetitemposition">external documentation</a>. %% <br /> Alternatives: %% <p><c> -%% setItemPosition(This::wxGridBagSizer(), Index::integer(), Pos::{R::integer(),C::integer()}) -> bool() </c> +%% setItemPosition(This::wxGridBagSizer(), Index::integer(), Pos::{R::integer(), C::integer()}) -> bool() </c> %% </p> %% <p><c> -%% setItemPosition(This::wxGridBagSizer(), Window::wxWindow:wxWindow() | wxSizer:wxSizer(), Pos::{R::integer(),C::integer()}) -> bool() </c> +%% setItemPosition(This::wxGridBagSizer(), Window::wxWindow:wxWindow() | wxSizer:wxSizer(), Pos::{R::integer(), C::integer()}) -> bool() </c> %% </p> setItemPosition(#wx_ref{type=ThisT,ref=ThisRef},Index,{PosR,PosC}) when is_integer(Index),is_integer(PosR),is_integer(PosC) -> @@ -366,14 +366,14 @@ setItemPosition(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=WindowT,ref=WindowR wxe_util:call(WindowOP, <<ThisRef:32/?UI,WindowRef:32/?UI,PosR:32/?UI,PosC:32/?UI>>). -%% @spec (This::wxGridBagSizer(),X::integer()|term(),Span::{RS::integer(),CS::integer()}) -> bool() +%% @spec (This::wxGridBagSizer(),X::integer()|term(),Span::{RS::integer(), CS::integer()}) -> bool() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridbagsizer.html#wxgridbagsizersetitemspan">external documentation</a>. %% <br /> Alternatives: %% <p><c> -%% setItemSpan(This::wxGridBagSizer(), Index::integer(), Span::{RS::integer(),CS::integer()}) -> bool() </c> +%% setItemSpan(This::wxGridBagSizer(), Index::integer(), Span::{RS::integer(), CS::integer()}) -> bool() </c> %% </p> %% <p><c> -%% setItemSpan(This::wxGridBagSizer(), Window::wxWindow:wxWindow() | wxSizer:wxSizer(), Span::{RS::integer(),CS::integer()}) -> bool() </c> +%% setItemSpan(This::wxGridBagSizer(), Window::wxWindow:wxWindow() | wxSizer:wxSizer(), Span::{RS::integer(), CS::integer()}) -> bool() </c> %% </p> setItemSpan(#wx_ref{type=ThisT,ref=ThisRef},Index,{SpanRS,SpanCS}) when is_integer(Index),is_integer(SpanRS),is_integer(SpanCS) -> diff --git a/lib/wx/src/gen/wxGridCellAttr.erl b/lib/wx/src/gen/wxGridCellAttr.erl index 3d23c2acfc..a9a0c1fb79 100644 --- a/lib/wx/src/gen/wxGridCellAttr.erl +++ b/lib/wx/src/gen/wxGridCellAttr.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -165,7 +165,7 @@ getFont(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxGridCellAttr_GetFont, <<ThisRef:32/?UI>>). -%% @spec (This::wxGridCellAttr()) -> {HAlign::integer(),VAlign::integer()} +%% @spec (This::wxGridCellAttr()) -> {HAlign::integer(), VAlign::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridcellattr.html#wxgridcellattrgetalignment">external documentation</a>. getAlignment(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxGridCellAttr), diff --git a/lib/wx/src/gen/wxGridCellEditor.erl b/lib/wx/src/gen/wxGridCellEditor.erl index a27ba7bd0f..de1ebc5a4c 100644 --- a/lib/wx/src/gen/wxGridCellEditor.erl +++ b/lib/wx/src/gen/wxGridCellEditor.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -50,7 +50,7 @@ isCreated(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxGridCellEditor_IsCreated, <<ThisRef:32/?UI>>). -%% @spec (This::wxGridCellEditor(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}) -> ok +%% @spec (This::wxGridCellEditor(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridcelleditor.html#wxgridcelleditorsetsize">external documentation</a>. setSize(#wx_ref{type=ThisT,ref=ThisRef},{RectX,RectY,RectW,RectH}) when is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH) -> @@ -76,7 +76,7 @@ show(#wx_ref{type=ThisT,ref=ThisRef},Show, Options) wxe_util:cast(?wxGridCellEditor_Show, <<ThisRef:32/?UI,(wxe_util:from_bool(Show)):32/?UI, BinOpt/binary>>). -%% @spec (This::wxGridCellEditor(), RectCell::{X::integer(),Y::integer(),W::integer(),H::integer()}, Attr::wxGridCellAttr:wxGridCellAttr()) -> ok +%% @spec (This::wxGridCellEditor(), RectCell::{X::integer(), Y::integer(), W::integer(), H::integer()}, Attr::wxGridCellAttr:wxGridCellAttr()) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridcelleditor.html#wxgridcelleditorpaintbackground">external documentation</a>. paintBackground(#wx_ref{type=ThisT,ref=ThisRef},{RectCellX,RectCellY,RectCellW,RectCellH},#wx_ref{type=AttrT,ref=AttrRef}) when is_integer(RectCellX),is_integer(RectCellY),is_integer(RectCellW),is_integer(RectCellH) -> diff --git a/lib/wx/src/gen/wxGridCellRenderer.erl b/lib/wx/src/gen/wxGridCellRenderer.erl index d9520c478f..765c116a48 100644 --- a/lib/wx/src/gen/wxGridCellRenderer.erl +++ b/lib/wx/src/gen/wxGridCellRenderer.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -32,7 +32,7 @@ %% @hidden parent_class(_Class) -> erlang:error({badtype, ?MODULE}). -%% @spec (This::wxGridCellRenderer(), Grid::wxGrid:wxGrid(), Attr::wxGridCellAttr:wxGridCellAttr(), Dc::wxDC:wxDC(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}, Row::integer(), Col::integer(), IsSelected::bool()) -> ok +%% @spec (This::wxGridCellRenderer(), Grid::wxGrid:wxGrid(), Attr::wxGridCellAttr:wxGridCellAttr(), Dc::wxDC:wxDC(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}, Row::integer(), Col::integer(), IsSelected::bool()) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridcellrenderer.html#wxgridcellrendererdraw">external documentation</a>. draw(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=GridT,ref=GridRef},#wx_ref{type=AttrT,ref=AttrRef},#wx_ref{type=DcT,ref=DcRef},{RectX,RectY,RectW,RectH},Row,Col,IsSelected) when is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH),is_integer(Row),is_integer(Col),is_boolean(IsSelected) -> @@ -43,7 +43,7 @@ draw(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=GridT,ref=GridRef},#wx_ref{typ wxe_util:cast(?wxGridCellRenderer_Draw, <<ThisRef:32/?UI,GridRef:32/?UI,AttrRef:32/?UI,DcRef:32/?UI,RectX:32/?UI,RectY:32/?UI,RectW:32/?UI,RectH:32/?UI,Row:32/?UI,Col:32/?UI,(wxe_util:from_bool(IsSelected)):32/?UI>>). -%% @spec (This::wxGridCellRenderer(), Grid::wxGrid:wxGrid(), Attr::wxGridCellAttr:wxGridCellAttr(), Dc::wxDC:wxDC(), Row::integer(), Col::integer()) -> {W::integer(),H::integer()} +%% @spec (This::wxGridCellRenderer(), Grid::wxGrid:wxGrid(), Attr::wxGridCellAttr:wxGridCellAttr(), Dc::wxDC:wxDC(), Row::integer(), Col::integer()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridcellrenderer.html#wxgridcellrenderergetbestsize">external documentation</a>. getBestSize(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=GridT,ref=GridRef},#wx_ref{type=AttrT,ref=AttrRef},#wx_ref{type=DcT,ref=DcRef},Row,Col) when is_integer(Row),is_integer(Col) -> diff --git a/lib/wx/src/gen/wxGridEvent.erl b/lib/wx/src/gen/wxGridEvent.erl index 9b7e0012ca..123088afb5 100644 --- a/lib/wx/src/gen/wxGridEvent.erl +++ b/lib/wx/src/gen/wxGridEvent.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -69,7 +69,7 @@ getCol(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxGridEvent_GetCol, <<ThisRef:32/?UI>>). -%% @spec (This::wxGridEvent()) -> {X::integer(),Y::integer()} +%% @spec (This::wxGridEvent()) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxgridevent.html#wxgrideventgetposition">external documentation</a>. getPosition(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxGridEvent), diff --git a/lib/wx/src/gen/wxHelpEvent.erl b/lib/wx/src/gen/wxHelpEvent.erl index ef3c666ab7..b80903c314 100644 --- a/lib/wx/src/gen/wxHelpEvent.erl +++ b/lib/wx/src/gen/wxHelpEvent.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -50,7 +50,7 @@ getOrigin(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxHelpEvent_GetOrigin, <<ThisRef:32/?UI>>). -%% @spec (This::wxHelpEvent()) -> {X::integer(),Y::integer()} +%% @spec (This::wxHelpEvent()) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxhelpevent.html#wxhelpeventgetposition">external documentation</a>. getPosition(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxHelpEvent), @@ -67,7 +67,7 @@ setOrigin(#wx_ref{type=ThisT,ref=ThisRef},Origin) wxe_util:cast(?wxHelpEvent_SetOrigin, <<ThisRef:32/?UI,Origin:32/?UI>>). -%% @spec (This::wxHelpEvent(), Pos::{X::integer(),Y::integer()}) -> ok +%% @spec (This::wxHelpEvent(), Pos::{X::integer(), Y::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxhelpevent.html#wxhelpeventsetposition">external documentation</a>. setPosition(#wx_ref{type=ThisT,ref=ThisRef},{PosX,PosY}) when is_integer(PosX),is_integer(PosY) -> diff --git a/lib/wx/src/gen/wxHtmlWindow.erl b/lib/wx/src/gen/wxHtmlWindow.erl index ba8278ff56..891e5481fb 100644 --- a/lib/wx/src/gen/wxHtmlWindow.erl +++ b/lib/wx/src/gen/wxHtmlWindow.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2009-2010. All Rights Reserved. +%% Copyright Ericsson AB 2009-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -99,7 +99,7 @@ new(Parent) new(Parent, []). %% @spec (Parent::wxWindow:wxWindow(), [Option]) -> wxHtmlWindow() -%% Option = {id, integer()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {id, integer()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxhtmlwindow.html#wxhtmlwindowwxhtmlwindow">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef}, Options) when is_list(Options) -> @@ -217,7 +217,7 @@ selectionToText(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxHtmlWindow_SelectionToText, <<ThisRef:32/?UI>>). -%% @spec (This::wxHtmlWindow(), Pos::{X::integer(),Y::integer()}) -> ok +%% @spec (This::wxHtmlWindow(), Pos::{X::integer(), Y::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxhtmlwindow.html#wxhtmlwindowselectline">external documentation</a>. selectLine(#wx_ref{type=ThisT,ref=ThisRef},{PosX,PosY}) when is_integer(PosX),is_integer(PosY) -> @@ -225,7 +225,7 @@ selectLine(#wx_ref{type=ThisT,ref=ThisRef},{PosX,PosY}) wxe_util:cast(?wxHtmlWindow_SelectLine, <<ThisRef:32/?UI,PosX:32/?UI,PosY:32/?UI>>). -%% @spec (This::wxHtmlWindow(), Pos::{X::integer(),Y::integer()}) -> ok +%% @spec (This::wxHtmlWindow(), Pos::{X::integer(), Y::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxhtmlwindow.html#wxhtmlwindowselectword">external documentation</a>. selectWord(#wx_ref{type=ThisT,ref=ThisRef},{PosX,PosY}) when is_integer(PosX),is_integer(PosY) -> diff --git a/lib/wx/src/gen/wxIconBundle.erl b/lib/wx/src/gen/wxIconBundle.erl index ee133cbcb9..011b2dd1ac 100644 --- a/lib/wx/src/gen/wxIconBundle.erl +++ b/lib/wx/src/gen/wxIconBundle.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -89,7 +89,7 @@ getIcon(This) %%<br /> Option = {size, integer()} %% </p> %% <p><c> -%% getIcon(This::wxIconBundle(), Size::{W::integer(),H::integer()}) -> wxIcon:wxIcon() </c> +%% getIcon(This::wxIconBundle(), Size::{W::integer(), H::integer()}) -> wxIcon:wxIcon() </c> %% </p> getIcon(#wx_ref{type=ThisT,ref=ThisRef}, Options) when is_list(Options) -> diff --git a/lib/wx/src/gen/wxImage.erl b/lib/wx/src/gen/wxImage.erl index 5fe105fbb2..ea41a78a40 100644 --- a/lib/wx/src/gen/wxImage.erl +++ b/lib/wx/src/gen/wxImage.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -303,13 +303,13 @@ create(#wx_ref{type=ThisT,ref=ThisRef},Width,Height,Data,Alpha, Options) wxe_util:cast(?wxImage_Destroy, <<ThisRef:32/?UI>>). -%% @spec (This::wxImage()) -> {bool(),R::integer(),G::integer(),B::integer()} +%% @spec (This::wxImage()) -> {bool(), R::integer(), G::integer(), B::integer()} %% @equiv findFirstUnusedColour(This, []) findFirstUnusedColour(This) when is_record(This, wx_ref) -> findFirstUnusedColour(This, []). -%% @spec (This::wxImage(), [Option]) -> {bool(),R::integer(),G::integer(),B::integer()} +%% @spec (This::wxImage(), [Option]) -> {bool(), R::integer(), G::integer(), B::integer()} %% Option = {startR, integer()} | {startG, integer()} | {startB, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wximage.html#wximagefindfirstunusedcolour">external documentation</a>. findFirstUnusedColour(#wx_ref{type=ThisT,ref=ThisRef}, Options) @@ -413,7 +413,7 @@ getMaskRed(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxImage_GetMaskRed, <<ThisRef:32/?UI>>). -%% @spec (This::wxImage()) -> {bool(),R::integer(),G::integer(),B::integer()} +%% @spec (This::wxImage()) -> {bool(), R::integer(), G::integer(), B::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wximage.html#wximagegetorfindmaskcolour">external documentation</a>. getOrFindMaskColour(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxImage), @@ -435,7 +435,7 @@ getRed(#wx_ref{type=ThisT,ref=ThisRef},X,Y) wxe_util:call(?wxImage_GetRed, <<ThisRef:32/?UI,X:32/?UI,Y:32/?UI>>). -%% @spec (This::wxImage(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}) -> wxImage() +%% @spec (This::wxImage(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}) -> wxImage() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wximage.html#wximagegetsubimage">external documentation</a>. getSubImage(#wx_ref{type=ThisT,ref=ThisRef},{RectX,RectY,RectW,RectH}) when is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH) -> @@ -615,13 +615,13 @@ rescale(#wx_ref{type=ThisT,ref=ThisRef},Width,Height, Options) wxe_util:call(?wxImage_Rescale, <<ThisRef:32/?UI,Width:32/?UI,Height:32/?UI, 0:32,BinOpt/binary>>). -%% @spec (This::wxImage(), Size::{W::integer(),H::integer()}, Pos::{X::integer(),Y::integer()}) -> wxImage() +%% @spec (This::wxImage(), Size::{W::integer(), H::integer()}, Pos::{X::integer(), Y::integer()}) -> wxImage() %% @equiv resize(This,Size,Pos, []) resize(This,Size={SizeW,SizeH},Pos={PosX,PosY}) when is_record(This, wx_ref),is_integer(SizeW),is_integer(SizeH),is_integer(PosX),is_integer(PosY) -> resize(This,Size,Pos, []). -%% @spec (This::wxImage(), Size::{W::integer(),H::integer()}, Pos::{X::integer(),Y::integer()}, [Option]) -> wxImage() +%% @spec (This::wxImage(), Size::{W::integer(), H::integer()}, Pos::{X::integer(), Y::integer()}, [Option]) -> wxImage() %% Option = {r, integer()} | {g, integer()} | {b, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wximage.html#wximageresize">external documentation</a>. resize(#wx_ref{type=ThisT,ref=ThisRef},{SizeW,SizeH},{PosX,PosY}, Options) @@ -635,14 +635,14 @@ resize(#wx_ref{type=ThisT,ref=ThisRef},{SizeW,SizeH},{PosX,PosY}, Options) wxe_util:call(?wxImage_Resize, <<ThisRef:32/?UI,SizeW:32/?UI,SizeH:32/?UI,PosX:32/?UI,PosY:32/?UI, 0:32,BinOpt/binary>>). -%% @spec (This::wxImage(), Angle::float(), Centre_of_rotation::{X::integer(),Y::integer()}) -> wxImage() +%% @spec (This::wxImage(), Angle::float(), Centre_of_rotation::{X::integer(), Y::integer()}) -> wxImage() %% @equiv rotate(This,Angle,Centre_of_rotation, []) rotate(This,Angle,Centre_of_rotation={Centre_of_rotationX,Centre_of_rotationY}) when is_record(This, wx_ref),is_float(Angle),is_integer(Centre_of_rotationX),is_integer(Centre_of_rotationY) -> rotate(This,Angle,Centre_of_rotation, []). -%% @spec (This::wxImage(), Angle::float(), Centre_of_rotation::{X::integer(),Y::integer()}, [Option]) -> wxImage() -%% Option = {interpolating, bool()} | {offset_after_rotation, {X::integer(),Y::integer()}} +%% @spec (This::wxImage(), Angle::float(), Centre_of_rotation::{X::integer(), Y::integer()}, [Option]) -> wxImage() +%% Option = {interpolating, bool()} | {offset_after_rotation, {X::integer(), Y::integer()}} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wximage.html#wximagerotate">external documentation</a>. rotate(#wx_ref{type=ThisT,ref=ThisRef},Angle,{Centre_of_rotationX,Centre_of_rotationY}, Options) when is_float(Angle),is_integer(Centre_of_rotationX),is_integer(Centre_of_rotationY),is_list(Options) -> @@ -730,13 +730,13 @@ scale(#wx_ref{type=ThisT,ref=ThisRef},Width,Height, Options) wxe_util:call(?wxImage_Scale, <<ThisRef:32/?UI,Width:32/?UI,Height:32/?UI, 0:32,BinOpt/binary>>). -%% @spec (This::wxImage(), Size::{W::integer(),H::integer()}, Pos::{X::integer(),Y::integer()}) -> wxImage() +%% @spec (This::wxImage(), Size::{W::integer(), H::integer()}, Pos::{X::integer(), Y::integer()}) -> wxImage() %% @equiv size(This,Size,Pos, []) size(This,Size={SizeW,SizeH},Pos={PosX,PosY}) when is_record(This, wx_ref),is_integer(SizeW),is_integer(SizeH),is_integer(PosX),is_integer(PosY) -> size(This,Size,Pos, []). -%% @spec (This::wxImage(), Size::{W::integer(),H::integer()}, Pos::{X::integer(),Y::integer()}, [Option]) -> wxImage() +%% @spec (This::wxImage(), Size::{W::integer(), H::integer()}, Pos::{X::integer(), Y::integer()}, [Option]) -> wxImage() %% Option = {r, integer()} | {g, integer()} | {b, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wximage.html#wximagesize">external documentation</a>. size(#wx_ref{type=ThisT,ref=ThisRef},{SizeW,SizeH},{PosX,PosY}, Options) @@ -881,7 +881,7 @@ setPalette(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=PaletteT,ref=PaletteRef} wxe_util:cast(?wxImage_SetPalette, <<ThisRef:32/?UI,PaletteRef:32/?UI>>). -%% @spec (This::wxImage(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}, R::integer(), G::integer(), B::integer()) -> ok +%% @spec (This::wxImage(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}, R::integer(), G::integer(), B::integer()) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wximage.html#wximagesetrgb">external documentation</a>. setRGB(#wx_ref{type=ThisT,ref=ThisRef},{RectX,RectY,RectW,RectH},R,G,B) when is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH),is_integer(R),is_integer(G),is_integer(B) -> diff --git a/lib/wx/src/gen/wxImageList.erl b/lib/wx/src/gen/wxImageList.erl index dbd51bc47b..f805a234df 100644 --- a/lib/wx/src/gen/wxImageList.erl +++ b/lib/wx/src/gen/wxImageList.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -150,7 +150,7 @@ getImageCount(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxImageList_GetImageCount, <<ThisRef:32/?UI>>). -%% @spec (This::wxImageList(), Index::integer()) -> {bool(),Width::integer(),Height::integer()} +%% @spec (This::wxImageList(), Index::integer()) -> {bool(), Width::integer(), Height::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wximagelist.html#wximagelistgetsize">external documentation</a>. getSize(#wx_ref{type=ThisT,ref=ThisRef},Index) when is_integer(Index) -> diff --git a/lib/wx/src/gen/wxJoystickEvent.erl b/lib/wx/src/gen/wxJoystickEvent.erl index 2c2d7f3968..2f149a50f8 100644 --- a/lib/wx/src/gen/wxJoystickEvent.erl +++ b/lib/wx/src/gen/wxJoystickEvent.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -118,7 +118,7 @@ getJoystick(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxJoystickEvent_GetJoystick, <<ThisRef:32/?UI>>). -%% @spec (This::wxJoystickEvent()) -> {X::integer(),Y::integer()} +%% @spec (This::wxJoystickEvent()) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxjoystickevent.html#wxjoystickeventgetposition">external documentation</a>. getPosition(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxJoystickEvent), diff --git a/lib/wx/src/gen/wxKeyEvent.erl b/lib/wx/src/gen/wxKeyEvent.erl index 00d1e2033a..edda5ee0a6 100644 --- a/lib/wx/src/gen/wxKeyEvent.erl +++ b/lib/wx/src/gen/wxKeyEvent.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -78,7 +78,7 @@ getModifiers(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxKeyEvent_GetModifiers, <<ThisRef:32/?UI>>). -%% @spec (This::wxKeyEvent()) -> {X::integer(),Y::integer()} +%% @spec (This::wxKeyEvent()) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxkeyevent.html#wxkeyeventgetposition">external documentation</a>. getPosition(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxKeyEvent), diff --git a/lib/wx/src/gen/wxLayoutAlgorithm.erl b/lib/wx/src/gen/wxLayoutAlgorithm.erl index 402d116338..c17abeaed1 100644 --- a/lib/wx/src/gen/wxLayoutAlgorithm.erl +++ b/lib/wx/src/gen/wxLayoutAlgorithm.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -65,7 +65,7 @@ layoutMDIFrame(This,Frame) layoutMDIFrame(This,Frame, []). %% @spec (This::wxLayoutAlgorithm(), Frame::wxMDIParentFrame:wxMDIParentFrame(), [Option]) -> bool() -%% Option = {rect, {X::integer(),Y::integer(),W::integer(),H::integer()}} +%% Option = {rect, {X::integer(), Y::integer(), W::integer(), H::integer()}} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlayoutalgorithm.html#wxlayoutalgorithmlayoutmdiframe">external documentation</a>. layoutMDIFrame(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=FrameT,ref=FrameRef}, Options) when is_list(Options) -> diff --git a/lib/wx/src/gen/wxListBox.erl b/lib/wx/src/gen/wxListBox.erl index 731209c586..cc30bf95e4 100644 --- a/lib/wx/src/gen/wxListBox.erl +++ b/lib/wx/src/gen/wxListBox.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -94,7 +94,7 @@ new(Parent,Id) new(Parent,Id, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> wxListBox() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {choices, [[string()]]} | {style, integer()} | {validator, wx:wx()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {choices, [[string()]]} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistbox.html#wxlistboxwxlistbox">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> @@ -109,13 +109,13 @@ new(#wx_ref{type=ParentT,ref=ParentRef},Id, Options) wxe_util:construct(?wxListBox_new_3, <<ParentRef:32/?UI,Id:32/?UI, BinOpt/binary>>). -%% @spec (This::wxListBox(), Parent::wxWindow:wxWindow(), Id::integer(), Pos::{X::integer(),Y::integer()}, Size::{W::integer(),H::integer()}, Choices::[[string()]]) -> bool() +%% @spec (This::wxListBox(), Parent::wxWindow:wxWindow(), Id::integer(), Pos::{X::integer(), Y::integer()}, Size::{W::integer(), H::integer()}, Choices::[[string()]]) -> bool() %% @equiv create(This,Parent,Id,Pos,Size,Choices, []) create(This,Parent,Id,Pos={PosX,PosY},Size={SizeW,SizeH},Choices) when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Id),is_integer(PosX),is_integer(PosY),is_integer(SizeW),is_integer(SizeH),is_list(Choices) -> create(This,Parent,Id,Pos,Size,Choices, []). -%% @spec (This::wxListBox(), Parent::wxWindow:wxWindow(), Id::integer(), Pos::{X::integer(),Y::integer()}, Size::{W::integer(),H::integer()}, Choices::[[string()]], [Option]) -> bool() +%% @spec (This::wxListBox(), Parent::wxWindow:wxWindow(), Id::integer(), Pos::{X::integer(), Y::integer()}, Size::{W::integer(), H::integer()}, Choices::[[string()]], [Option]) -> bool() %% Option = {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistbox.html#wxlistboxcreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,{PosX,PosY},{SizeW,SizeH},Choices, Options) @@ -139,7 +139,7 @@ deselect(#wx_ref{type=ThisT,ref=ThisRef},N) wxe_util:cast(?wxListBox_Deselect, <<ThisRef:32/?UI,N:32/?UI>>). -%% @spec (This::wxListBox()) -> {integer(),ASelections::[integer()]} +%% @spec (This::wxListBox()) -> {integer(), ASelections::[integer()]} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistbox.html#wxlistboxgetselections">external documentation</a>. getSelections(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxListBox), @@ -174,7 +174,7 @@ set(#wx_ref{type=ThisT,ref=ThisRef},Items) wxe_util:cast(?wxListBox_Set, <<ThisRef:32/?UI,(length(Items_UCA)):32/?UI, (<< <<(byte_size(UC_Str)):32/?UI, UC_Str/binary>>|| UC_Str <- Items_UCA>>)/binary, 0:(((8- ((0 + lists:sum([byte_size(S)+4||S<-Items_UCA])) band 16#7)) band 16#7))/unit:8>>). -%% @spec (This::wxListBox(), Point::{X::integer(),Y::integer()}) -> integer() +%% @spec (This::wxListBox(), Point::{X::integer(), Y::integer()}) -> integer() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistbox.html#wxlistboxhittest">external documentation</a>. hitTest(#wx_ref{type=ThisT,ref=ThisRef},{PointX,PointY}) when is_integer(PointX),is_integer(PointY) -> diff --git a/lib/wx/src/gen/wxListCtrl.erl b/lib/wx/src/gen/wxListCtrl.erl index 5799206b87..fa99897171 100644 --- a/lib/wx/src/gen/wxListCtrl.erl +++ b/lib/wx/src/gen/wxListCtrl.erl @@ -263,7 +263,7 @@ findItem(This,Start,Str) %%<br /> Option = {partial, bool()} %% </p> %% <p><c> -%% findItem(This::wxListCtrl(), Start::integer(), Pt::{X::integer(),Y::integer()}, Direction::integer()) -> integer() </c> +%% findItem(This::wxListCtrl(), Start::integer(), Pt::{X::integer(), Y::integer()}, Direction::integer()) -> integer() </c> %% </p> findItem(#wx_ref{type=ThisT,ref=ThisRef},Start,Str, Options) when is_integer(Start),is_list(Str),is_list(Options) -> @@ -365,7 +365,7 @@ getItemFont(#wx_ref{type=ThisT,ref=ThisRef},Item) wxe_util:call(?wxListCtrl_GetItemFont, <<ThisRef:32/?UI,Item:32/?UI>>). -%% @spec (This::wxListCtrl(), Item::integer(), Pos::{X::integer(),Y::integer()}) -> bool() +%% @spec (This::wxListCtrl(), Item::integer(), Pos::{X::integer(), Y::integer()}) -> bool() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistctrl.html#wxlistctrlgetitemposition">external documentation</a>. getItemPosition(#wx_ref{type=ThisT,ref=ThisRef},Item,{PosX,PosY}) when is_integer(Item),is_integer(PosX),is_integer(PosY) -> @@ -373,13 +373,13 @@ getItemPosition(#wx_ref{type=ThisT,ref=ThisRef},Item,{PosX,PosY}) wxe_util:call(?wxListCtrl_GetItemPosition, <<ThisRef:32/?UI,Item:32/?UI,PosX:32/?UI,PosY:32/?UI>>). -%% @spec (This::wxListCtrl(), Item::integer(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}) -> bool() +%% @spec (This::wxListCtrl(), Item::integer(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}) -> bool() %% @equiv getItemRect(This,Item,Rect, []) getItemRect(This,Item,Rect={RectX,RectY,RectW,RectH}) when is_record(This, wx_ref),is_integer(Item),is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH) -> getItemRect(This,Item,Rect, []). -%% @spec (This::wxListCtrl(), Item::integer(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}, [Option]) -> bool() +%% @spec (This::wxListCtrl(), Item::integer(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}, [Option]) -> bool() %% Option = {code, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistctrl.html#wxlistctrlgetitemrect">external documentation</a>. getItemRect(#wx_ref{type=ThisT,ref=ThisRef},Item,{RectX,RectY,RectW,RectH}, Options) @@ -391,7 +391,7 @@ getItemRect(#wx_ref{type=ThisT,ref=ThisRef},Item,{RectX,RectY,RectW,RectH}, Opti wxe_util:call(?wxListCtrl_GetItemRect, <<ThisRef:32/?UI,Item:32/?UI,RectX:32/?UI,RectY:32/?UI,RectW:32/?UI,RectH:32/?UI, BinOpt/binary>>). -%% @spec (This::wxListCtrl()) -> {W::integer(),H::integer()} +%% @spec (This::wxListCtrl()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistctrl.html#wxlistctrlgetitemspacing">external documentation</a>. getItemSpacing(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxListCtrl), @@ -462,14 +462,14 @@ getTopItem(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxListCtrl_GetTopItem, <<ThisRef:32/?UI>>). -%% @spec (This::wxListCtrl()) -> {X::integer(),Y::integer(),W::integer(),H::integer()} +%% @spec (This::wxListCtrl()) -> {X::integer(), Y::integer(), W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistctrl.html#wxlistctrlgetviewrect">external documentation</a>. getViewRect(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxListCtrl), wxe_util:call(?wxListCtrl_GetViewRect, <<ThisRef:32/?UI>>). -%% @spec (This::wxListCtrl(), Point::{X::integer(),Y::integer()}) -> {integer(),Flags::integer()} +%% @spec (This::wxListCtrl(), Point::{X::integer(), Y::integer()}) -> {integer(), Flags::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistctrl.html#wxlistctrlhittest">external documentation</a>. hitTest(#wx_ref{type=ThisT,ref=ThisRef},{PointX,PointY}) when is_integer(PointX),is_integer(PointY) -> @@ -692,7 +692,7 @@ setItemColumnImage(#wx_ref{type=ThisT,ref=ThisRef},Item,Column,Image) wxe_util:call(?wxListCtrl_SetItemColumnImage, <<ThisRef:32/?UI,Item:32/?UI,Column:32/?UI,Image:32/?UI>>). -%% @spec (This::wxListCtrl(), Item::integer(), Pos::{X::integer(),Y::integer()}) -> bool() +%% @spec (This::wxListCtrl(), Item::integer(), Pos::{X::integer(), Y::integer()}) -> bool() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistctrl.html#wxlistctrlsetitemposition">external documentation</a>. setItemPosition(#wx_ref{type=ThisT,ref=ThisRef},Item,{PosX,PosY}) when is_integer(Item),is_integer(PosX),is_integer(PosY) -> diff --git a/lib/wx/src/gen/wxListEvent.erl b/lib/wx/src/gen/wxListEvent.erl index 74f9e6095c..f7d8658acc 100644 --- a/lib/wx/src/gen/wxListEvent.erl +++ b/lib/wx/src/gen/wxListEvent.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -83,7 +83,7 @@ getColumn(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxListEvent_GetColumn, <<ThisRef:32/?UI>>). -%% @spec (This::wxListEvent()) -> {X::integer(),Y::integer()} +%% @spec (This::wxListEvent()) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistevent.html#wxlisteventgetpoint">external documentation</a>. getPoint(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxListEvent), diff --git a/lib/wx/src/gen/wxListbook.erl b/lib/wx/src/gen/wxListbook.erl index b1f0e3d9a4..c204dc87a1 100644 --- a/lib/wx/src/gen/wxListbook.erl +++ b/lib/wx/src/gen/wxListbook.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2009-2010. All Rights Reserved. +%% Copyright Ericsson AB 2009-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -93,7 +93,7 @@ new(Parent,Id) new(Parent,Id, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> wxListbook() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistbook.html#wxlistbookwxlistbook">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> @@ -160,7 +160,7 @@ create(This,Parent,Id) create(This,Parent,Id, []). %% @spec (This::wxListbook(), Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> bool() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistbook.html#wxlistbookcreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> @@ -249,7 +249,7 @@ getSelection(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxListbook_GetSelection, <<ThisRef:32/?UI>>). -%% @spec (This::wxListbook(), Pt::{X::integer(),Y::integer()}) -> {integer(),Flags::integer()} +%% @spec (This::wxListbook(), Pt::{X::integer(), Y::integer()}) -> {integer(), Flags::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistbook.html#wxlistbookhittest">external documentation</a>. hitTest(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) when is_integer(PtX),is_integer(PtY) -> @@ -286,7 +286,7 @@ setImageList(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ImageListT,ref=ImageLi wxe_util:cast(?wxListbook_SetImageList, <<ThisRef:32/?UI,ImageListRef:32/?UI>>). -%% @spec (This::wxListbook(), Size::{W::integer(),H::integer()}) -> ok +%% @spec (This::wxListbook(), Size::{W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxlistbook.html#wxlistbooksetpagesize">external documentation</a>. setPageSize(#wx_ref{type=ThisT,ref=ThisRef},{SizeW,SizeH}) when is_integer(SizeW),is_integer(SizeH) -> diff --git a/lib/wx/src/gen/wxMDIChildFrame.erl b/lib/wx/src/gen/wxMDIChildFrame.erl index 34edac4213..d3e1edda55 100644 --- a/lib/wx/src/gen/wxMDIChildFrame.erl +++ b/lib/wx/src/gen/wxMDIChildFrame.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -100,7 +100,7 @@ new(Parent,Id,Title) new(Parent,Id,Title, []). %% @spec (Parent::wxMDIParentFrame:wxMDIParentFrame(), Id::integer(), Title::string(), [Option]) -> wxMDIChildFrame() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmdichildframe.html#wxmdichildframewxmdichildframe">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id,Title, Options) when is_integer(Id),is_list(Title),is_list(Options) -> @@ -128,7 +128,7 @@ create(This,Parent,Id,Title) create(This,Parent,Id,Title, []). %% @spec (This::wxMDIChildFrame(), Parent::wxMDIParentFrame:wxMDIParentFrame(), Id::integer(), Title::string(), [Option]) -> bool() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmdichildframe.html#wxmdichildframecreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,Title, Options) when is_integer(Id),is_list(Title),is_list(Options) -> diff --git a/lib/wx/src/gen/wxMDIParentFrame.erl b/lib/wx/src/gen/wxMDIParentFrame.erl index db47e7ac74..7f8a305876 100644 --- a/lib/wx/src/gen/wxMDIParentFrame.erl +++ b/lib/wx/src/gen/wxMDIParentFrame.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -102,7 +102,7 @@ new(Parent,Id,Title) new(Parent,Id,Title, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), Title::string(), [Option]) -> wxMDIParentFrame() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmdiparentframe.html#wxmdiparentframewxmdiparentframe">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id,Title, Options) when is_integer(Id),is_list(Title),is_list(Options) -> @@ -151,7 +151,7 @@ create(This,Parent,Id,Title) create(This,Parent,Id,Title, []). %% @spec (This::wxMDIParentFrame(), Parent::wxWindow:wxWindow(), Id::integer(), Title::string(), [Option]) -> bool() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmdiparentframe.html#wxmdiparentframecreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,Title, Options) when is_integer(Id),is_list(Title),is_list(Options) -> diff --git a/lib/wx/src/gen/wxMessageDialog.erl b/lib/wx/src/gen/wxMessageDialog.erl index 916b201d3f..d13bb7cb6e 100644 --- a/lib/wx/src/gen/wxMessageDialog.erl +++ b/lib/wx/src/gen/wxMessageDialog.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -91,7 +91,7 @@ new(Parent,Message) new(Parent,Message, []). %% @spec (Parent::wxWindow:wxWindow(), Message::string(), [Option]) -> wxMessageDialog() -%% Option = {caption, string()} | {style, integer()} | {pos, {X::integer(),Y::integer()}} +%% Option = {caption, string()} | {style, integer()} | {pos, {X::integer(), Y::integer()}} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmessagedialog.html#wxmessagedialogwxmessagedialog">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Message, Options) when is_list(Message),is_list(Options) -> diff --git a/lib/wx/src/gen/wxMiniFrame.erl b/lib/wx/src/gen/wxMiniFrame.erl index b86f1d7cfa..108ebcfb0e 100644 --- a/lib/wx/src/gen/wxMiniFrame.erl +++ b/lib/wx/src/gen/wxMiniFrame.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -100,7 +100,7 @@ new(Parent,Id,Title) new(Parent,Id,Title, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), Title::string(), [Option]) -> wxMiniFrame() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxminiframe.html#wxminiframewxminiframe">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id,Title, Options) when is_integer(Id),is_list(Title),is_list(Options) -> @@ -121,7 +121,7 @@ create(This,Parent,Id,Title) create(This,Parent,Id,Title, []). %% @spec (This::wxMiniFrame(), Parent::wxWindow:wxWindow(), Id::integer(), Title::string(), [Option]) -> bool() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxminiframe.html#wxminiframecreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,Title, Options) when is_integer(Id),is_list(Title),is_list(Options) -> diff --git a/lib/wx/src/gen/wxMouseEvent.erl b/lib/wx/src/gen/wxMouseEvent.erl index fed9a33db7..a91d2a2e99 100644 --- a/lib/wx/src/gen/wxMouseEvent.erl +++ b/lib/wx/src/gen/wxMouseEvent.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -151,14 +151,14 @@ getButton(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxMouseEvent_GetButton, <<ThisRef:32/?UI>>). -%% @spec (This::wxMouseEvent()) -> {X::integer(),Y::integer()} +%% @spec (This::wxMouseEvent()) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmouseevent.html#wxmouseeventgetposition">external documentation</a>. getPosition(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxMouseEvent), wxe_util:call(?wxMouseEvent_GetPosition, <<ThisRef:32/?UI>>). -%% @spec (This::wxMouseEvent(), Dc::wxDC:wxDC()) -> {X::integer(),Y::integer()} +%% @spec (This::wxMouseEvent(), Dc::wxDC:wxDC()) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmouseevent.html#wxmouseeventgetlogicalposition">external documentation</a>. getLogicalPosition(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=DcT,ref=DcRef}) -> ?CLASS(ThisT,wxMouseEvent), diff --git a/lib/wx/src/gen/wxMoveEvent.erl b/lib/wx/src/gen/wxMoveEvent.erl index 80bf59074a..97cf803310 100644 --- a/lib/wx/src/gen/wxMoveEvent.erl +++ b/lib/wx/src/gen/wxMoveEvent.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -41,7 +41,7 @@ parent_class(wxEvent) -> true; parent_class(_Class) -> erlang:error({badtype, ?MODULE}). -%% @spec (This::wxMoveEvent()) -> {X::integer(),Y::integer()} +%% @spec (This::wxMoveEvent()) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmoveevent.html#wxmoveeventgetposition">external documentation</a>. getPosition(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxMoveEvent), diff --git a/lib/wx/src/gen/wxMultiChoiceDialog.erl b/lib/wx/src/gen/wxMultiChoiceDialog.erl index e69889a1e0..6fae0c4860 100644 --- a/lib/wx/src/gen/wxMultiChoiceDialog.erl +++ b/lib/wx/src/gen/wxMultiChoiceDialog.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -97,7 +97,7 @@ new(Parent,Message,Caption,Choices) new(Parent,Message,Caption,Choices, []). %% @spec (Parent::wxWindow:wxWindow(), Message::string(), Caption::string(), Choices::[[string()]], [Option]) -> wxMultiChoiceDialog() -%% Option = {style, integer()} | {pos, {X::integer(),Y::integer()}} +%% Option = {style, integer()} | {pos, {X::integer(), Y::integer()}} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxmultichoicedialog.html#wxmultichoicedialogwxmultichoicedialog">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Message,Caption,Choices, Options) when is_list(Message),is_list(Caption),is_list(Choices),is_list(Options) -> diff --git a/lib/wx/src/gen/wxNotebook.erl b/lib/wx/src/gen/wxNotebook.erl index da543d7ac6..b918de5bb4 100644 --- a/lib/wx/src/gen/wxNotebook.erl +++ b/lib/wx/src/gen/wxNotebook.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -93,7 +93,7 @@ new(Parent,Winid) new(Parent,Winid, []). %% @spec (Parent::wxWindow:wxWindow(), Winid::integer(), [Option]) -> wxNotebook() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxnotebook.html#wxnotebookwxnotebook">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Winid, Options) when is_integer(Winid),is_list(Options) -> @@ -160,7 +160,7 @@ create(This,Parent,Id) create(This,Parent,Id, []). %% @spec (This::wxNotebook(), Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> bool() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxnotebook.html#wxnotebookcreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> @@ -263,7 +263,7 @@ getThemeBackgroundColour(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxNotebook_GetThemeBackgroundColour, <<ThisRef:32/?UI>>). -%% @spec (This::wxNotebook(), Pt::{X::integer(),Y::integer()}) -> {integer(),Flags::integer()} +%% @spec (This::wxNotebook(), Pt::{X::integer(), Y::integer()}) -> {integer(), Flags::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxnotebook.html#wxnotebookhittest">external documentation</a>. hitTest(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) when is_integer(PtX),is_integer(PtY) -> @@ -300,7 +300,7 @@ setImageList(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ImageListT,ref=ImageLi wxe_util:cast(?wxNotebook_SetImageList, <<ThisRef:32/?UI,ImageListRef:32/?UI>>). -%% @spec (This::wxNotebook(), Padding::{W::integer(),H::integer()}) -> ok +%% @spec (This::wxNotebook(), Padding::{W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxnotebook.html#wxnotebooksetpadding">external documentation</a>. setPadding(#wx_ref{type=ThisT,ref=ThisRef},{PaddingW,PaddingH}) when is_integer(PaddingW),is_integer(PaddingH) -> @@ -308,7 +308,7 @@ setPadding(#wx_ref{type=ThisT,ref=ThisRef},{PaddingW,PaddingH}) wxe_util:cast(?wxNotebook_SetPadding, <<ThisRef:32/?UI,PaddingW:32/?UI,PaddingH:32/?UI>>). -%% @spec (This::wxNotebook(), Size::{W::integer(),H::integer()}) -> ok +%% @spec (This::wxNotebook(), Size::{W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxnotebook.html#wxnotebooksetpagesize">external documentation</a>. setPageSize(#wx_ref{type=ThisT,ref=ThisRef},{SizeW,SizeH}) when is_integer(SizeW),is_integer(SizeH) -> diff --git a/lib/wx/src/gen/wxPageSetupDialogData.erl b/lib/wx/src/gen/wxPageSetupDialogData.erl index 672ec7c083..00b4ca2a36 100644 --- a/lib/wx/src/gen/wxPageSetupDialogData.erl +++ b/lib/wx/src/gen/wxPageSetupDialogData.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -146,28 +146,28 @@ getDefaultInfo(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxPageSetupDialogData_GetDefaultInfo, <<ThisRef:32/?UI>>). -%% @spec (This::wxPageSetupDialogData()) -> {X::integer(),Y::integer()} +%% @spec (This::wxPageSetupDialogData()) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxpagesetupdialogdata.html#wxpagesetupdialogdatagetmargintopleft">external documentation</a>. getMarginTopLeft(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxPageSetupDialogData), wxe_util:call(?wxPageSetupDialogData_GetMarginTopLeft, <<ThisRef:32/?UI>>). -%% @spec (This::wxPageSetupDialogData()) -> {X::integer(),Y::integer()} +%% @spec (This::wxPageSetupDialogData()) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxpagesetupdialogdata.html#wxpagesetupdialogdatagetmarginbottomright">external documentation</a>. getMarginBottomRight(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxPageSetupDialogData), wxe_util:call(?wxPageSetupDialogData_GetMarginBottomRight, <<ThisRef:32/?UI>>). -%% @spec (This::wxPageSetupDialogData()) -> {X::integer(),Y::integer()} +%% @spec (This::wxPageSetupDialogData()) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxpagesetupdialogdata.html#wxpagesetupdialogdatagetminmargintopleft">external documentation</a>. getMinMarginTopLeft(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxPageSetupDialogData), wxe_util:call(?wxPageSetupDialogData_GetMinMarginTopLeft, <<ThisRef:32/?UI>>). -%% @spec (This::wxPageSetupDialogData()) -> {X::integer(),Y::integer()} +%% @spec (This::wxPageSetupDialogData()) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxpagesetupdialogdata.html#wxpagesetupdialogdatagetminmarginbottomright">external documentation</a>. getMinMarginBottomRight(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxPageSetupDialogData), @@ -181,7 +181,7 @@ getPaperId(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxPageSetupDialogData_GetPaperId, <<ThisRef:32/?UI>>). -%% @spec (This::wxPageSetupDialogData()) -> {W::integer(),H::integer()} +%% @spec (This::wxPageSetupDialogData()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxpagesetupdialogdata.html#wxpagesetupdialogdatagetpapersize">external documentation</a>. getPaperSize(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxPageSetupDialogData), @@ -218,7 +218,7 @@ setDefaultMinMargins(#wx_ref{type=ThisT,ref=ThisRef},Flag) wxe_util:cast(?wxPageSetupDialogData_SetDefaultMinMargins, <<ThisRef:32/?UI,(wxe_util:from_bool(Flag)):32/?UI>>). -%% @spec (This::wxPageSetupDialogData(), Pt::{X::integer(),Y::integer()}) -> ok +%% @spec (This::wxPageSetupDialogData(), Pt::{X::integer(), Y::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxpagesetupdialogdata.html#wxpagesetupdialogdatasetmargintopleft">external documentation</a>. setMarginTopLeft(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) when is_integer(PtX),is_integer(PtY) -> @@ -226,7 +226,7 @@ setMarginTopLeft(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) wxe_util:cast(?wxPageSetupDialogData_SetMarginTopLeft, <<ThisRef:32/?UI,PtX:32/?UI,PtY:32/?UI>>). -%% @spec (This::wxPageSetupDialogData(), Pt::{X::integer(),Y::integer()}) -> ok +%% @spec (This::wxPageSetupDialogData(), Pt::{X::integer(), Y::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxpagesetupdialogdata.html#wxpagesetupdialogdatasetmarginbottomright">external documentation</a>. setMarginBottomRight(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) when is_integer(PtX),is_integer(PtY) -> @@ -234,7 +234,7 @@ setMarginBottomRight(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) wxe_util:cast(?wxPageSetupDialogData_SetMarginBottomRight, <<ThisRef:32/?UI,PtX:32/?UI,PtY:32/?UI>>). -%% @spec (This::wxPageSetupDialogData(), Pt::{X::integer(),Y::integer()}) -> ok +%% @spec (This::wxPageSetupDialogData(), Pt::{X::integer(), Y::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxpagesetupdialogdata.html#wxpagesetupdialogdatasetminmargintopleft">external documentation</a>. setMinMarginTopLeft(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) when is_integer(PtX),is_integer(PtY) -> @@ -242,7 +242,7 @@ setMinMarginTopLeft(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) wxe_util:cast(?wxPageSetupDialogData_SetMinMarginTopLeft, <<ThisRef:32/?UI,PtX:32/?UI,PtY:32/?UI>>). -%% @spec (This::wxPageSetupDialogData(), Pt::{X::integer(),Y::integer()}) -> ok +%% @spec (This::wxPageSetupDialogData(), Pt::{X::integer(), Y::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxpagesetupdialogdata.html#wxpagesetupdialogdatasetminmarginbottomright">external documentation</a>. setMinMarginBottomRight(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) when is_integer(PtX),is_integer(PtY) -> @@ -265,7 +265,7 @@ setPaperId(#wx_ref{type=ThisT,ref=ThisRef},Id) %% setPaperSize(This::wxPageSetupDialogData(), Id::integer()) -> ok </c> %% </p> %% <p><c> -%% setPaperSize(This::wxPageSetupDialogData(), Sz::{W::integer(),H::integer()}) -> ok </c> +%% setPaperSize(This::wxPageSetupDialogData(), Sz::{W::integer(), H::integer()}) -> ok </c> %% </p> setPaperSize(#wx_ref{type=ThisT,ref=ThisRef},Id) when is_integer(Id) -> diff --git a/lib/wx/src/gen/wxPalette.erl b/lib/wx/src/gen/wxPalette.erl index ee1fd0016d..3d8e811988 100644 --- a/lib/wx/src/gen/wxPalette.erl +++ b/lib/wx/src/gen/wxPalette.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -75,7 +75,7 @@ getPixel(#wx_ref{type=ThisT,ref=ThisRef},Red,Green,Blue) wxe_util:call(?wxPalette_GetPixel, <<ThisRef:32/?UI,Red:32/?UI,Green:32/?UI,Blue:32/?UI>>). -%% @spec (This::wxPalette(), Pixel::integer()) -> {bool(),Red::integer(),Green::integer(),Blue::integer()} +%% @spec (This::wxPalette(), Pixel::integer()) -> {bool(), Red::integer(), Green::integer(), Blue::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxpalette.html#wxpalettegetrgb">external documentation</a>. getRGB(#wx_ref{type=ThisT,ref=ThisRef},Pixel) when is_integer(Pixel) -> diff --git a/lib/wx/src/gen/wxPanel.erl b/lib/wx/src/gen/wxPanel.erl index 55eaa9f404..59fba03102 100644 --- a/lib/wx/src/gen/wxPanel.erl +++ b/lib/wx/src/gen/wxPanel.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -86,7 +86,7 @@ new(Parent) new(Parent, []). %% @spec (Parent::wxWindow:wxWindow(), [Option]) -> wxPanel() -%% Option = {winid, integer()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {winid, integer()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxpanel.html#wxpanelwxpanel">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef}, Options) when is_list(Options) -> diff --git a/lib/wx/src/gen/wxPasswordEntryDialog.erl b/lib/wx/src/gen/wxPasswordEntryDialog.erl index f79734ab46..07a0bcef56 100644 --- a/lib/wx/src/gen/wxPasswordEntryDialog.erl +++ b/lib/wx/src/gen/wxPasswordEntryDialog.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -94,7 +94,7 @@ new(Parent,Message) new(Parent,Message, []). %% @spec (Parent::wxWindow:wxWindow(), Message::string(), [Option]) -> wxPasswordEntryDialog() -%% Option = {caption, string()} | {value, string()} | {style, integer()} | {pos, {X::integer(),Y::integer()}} +%% Option = {caption, string()} | {value, string()} | {style, integer()} | {pos, {X::integer(), Y::integer()}} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxpasswordentrydialog.html#wxpasswordentrydialogwxpasswordentrydialog">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Message, Options) when is_list(Message),is_list(Options) -> diff --git a/lib/wx/src/gen/wxPreviewControlBar.erl b/lib/wx/src/gen/wxPreviewControlBar.erl index 78d46d1b95..e85af625e2 100644 --- a/lib/wx/src/gen/wxPreviewControlBar.erl +++ b/lib/wx/src/gen/wxPreviewControlBar.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -83,7 +83,7 @@ new(Preview,Buttons,Parent) new(Preview,Buttons,Parent, []). %% @spec (Preview::wxPrintPreview:wxPrintPreview(), Buttons::integer(), Parent::wxWindow:wxWindow(), [Option]) -> wxPreviewControlBar() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxpreviewcontrolbar.html#wxpreviewcontrolbarwxpreviewcontrolbar">external documentation</a>. new(#wx_ref{type=PreviewT,ref=PreviewRef},Buttons,#wx_ref{type=ParentT,ref=ParentRef}, Options) when is_integer(Buttons),is_list(Options) -> diff --git a/lib/wx/src/gen/wxPreviewFrame.erl b/lib/wx/src/gen/wxPreviewFrame.erl index 91a32e9889..da43f86030 100644 --- a/lib/wx/src/gen/wxPreviewFrame.erl +++ b/lib/wx/src/gen/wxPreviewFrame.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -95,7 +95,7 @@ new(Preview,Parent) new(Preview,Parent, []). %% @spec (Preview::wxPrintPreview:wxPrintPreview(), Parent::wxWindow:wxWindow(), [Option]) -> wxPreviewFrame() -%% Option = {title, string()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {title, string()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxpreviewframe.html#wxpreviewframewxpreviewframe">external documentation</a>. new(#wx_ref{type=PreviewT,ref=PreviewRef},#wx_ref{type=ParentT,ref=ParentRef}, Options) when is_list(Options) -> diff --git a/lib/wx/src/gen/wxPrintout.erl b/lib/wx/src/gen/wxPrintout.erl index b5b93921e6..a34c030275 100644 --- a/lib/wx/src/gen/wxPrintout.erl +++ b/lib/wx/src/gen/wxPrintout.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -125,35 +125,35 @@ getDC(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxPrintout_GetDC, <<ThisRef:32/?UI>>). -%% @spec (This::wxPrintout()) -> {W::integer(),H::integer()} +%% @spec (This::wxPrintout()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxprintout.html#wxprintoutgetpagesizemm">external documentation</a>. getPageSizeMM(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxPrintout), wxe_util:call(?wxPrintout_GetPageSizeMM, <<ThisRef:32/?UI>>). -%% @spec (This::wxPrintout()) -> {W::integer(),H::integer()} +%% @spec (This::wxPrintout()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxprintout.html#wxprintoutgetpagesizepixels">external documentation</a>. getPageSizePixels(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxPrintout), wxe_util:call(?wxPrintout_GetPageSizePixels, <<ThisRef:32/?UI>>). -%% @spec (This::wxPrintout()) -> {X::integer(),Y::integer(),W::integer(),H::integer()} +%% @spec (This::wxPrintout()) -> {X::integer(), Y::integer(), W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxprintout.html#wxprintoutgetpaperrectpixels">external documentation</a>. getPaperRectPixels(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxPrintout), wxe_util:call(?wxPrintout_GetPaperRectPixels, <<ThisRef:32/?UI>>). -%% @spec (This::wxPrintout()) -> {X::integer(),Y::integer()} +%% @spec (This::wxPrintout()) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxprintout.html#wxprintoutgetppiprinter">external documentation</a>. getPPIPrinter(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxPrintout), wxe_util:call(?wxPrintout_GetPPIPrinter, <<ThisRef:32/?UI>>). -%% @spec (This::wxPrintout()) -> {X::integer(),Y::integer()} +%% @spec (This::wxPrintout()) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxprintout.html#wxprintoutgetppiscreen">external documentation</a>. getPPIScreen(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxPrintout), @@ -174,7 +174,7 @@ isPreview(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxPrintout_IsPreview, <<ThisRef:32/?UI>>). -%% @spec (This::wxPrintout(), ImageSize::{W::integer(),H::integer()}) -> ok +%% @spec (This::wxPrintout(), ImageSize::{W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxprintout.html#wxprintoutfitthissizetopaper">external documentation</a>. fitThisSizeToPaper(#wx_ref{type=ThisT,ref=ThisRef},{ImageSizeW,ImageSizeH}) when is_integer(ImageSizeW),is_integer(ImageSizeH) -> @@ -182,7 +182,7 @@ fitThisSizeToPaper(#wx_ref{type=ThisT,ref=ThisRef},{ImageSizeW,ImageSizeH}) wxe_util:cast(?wxPrintout_FitThisSizeToPaper, <<ThisRef:32/?UI,ImageSizeW:32/?UI,ImageSizeH:32/?UI>>). -%% @spec (This::wxPrintout(), ImageSize::{W::integer(),H::integer()}) -> ok +%% @spec (This::wxPrintout(), ImageSize::{W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxprintout.html#wxprintoutfitthissizetopage">external documentation</a>. fitThisSizeToPage(#wx_ref{type=ThisT,ref=ThisRef},{ImageSizeW,ImageSizeH}) when is_integer(ImageSizeW),is_integer(ImageSizeH) -> @@ -190,7 +190,7 @@ fitThisSizeToPage(#wx_ref{type=ThisT,ref=ThisRef},{ImageSizeW,ImageSizeH}) wxe_util:cast(?wxPrintout_FitThisSizeToPage, <<ThisRef:32/?UI,ImageSizeW:32/?UI,ImageSizeH:32/?UI>>). -%% @spec (This::wxPrintout(), ImageSize::{W::integer(),H::integer()}, PageSetupData::wxPageSetupDialogData:wxPageSetupDialogData()) -> ok +%% @spec (This::wxPrintout(), ImageSize::{W::integer(), H::integer()}, PageSetupData::wxPageSetupDialogData:wxPageSetupDialogData()) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxprintout.html#wxprintoutfitthissizetopagemargins">external documentation</a>. fitThisSizeToPageMargins(#wx_ref{type=ThisT,ref=ThisRef},{ImageSizeW,ImageSizeH},#wx_ref{type=PageSetupDataT,ref=PageSetupDataRef}) when is_integer(ImageSizeW),is_integer(ImageSizeH) -> @@ -228,21 +228,21 @@ mapScreenSizeToDevice(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:cast(?wxPrintout_MapScreenSizeToDevice, <<ThisRef:32/?UI>>). -%% @spec (This::wxPrintout()) -> {X::integer(),Y::integer(),W::integer(),H::integer()} +%% @spec (This::wxPrintout()) -> {X::integer(), Y::integer(), W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxprintout.html#wxprintoutgetlogicalpaperrect">external documentation</a>. getLogicalPaperRect(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxPrintout), wxe_util:call(?wxPrintout_GetLogicalPaperRect, <<ThisRef:32/?UI>>). -%% @spec (This::wxPrintout()) -> {X::integer(),Y::integer(),W::integer(),H::integer()} +%% @spec (This::wxPrintout()) -> {X::integer(), Y::integer(), W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxprintout.html#wxprintoutgetlogicalpagerect">external documentation</a>. getLogicalPageRect(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxPrintout), wxe_util:call(?wxPrintout_GetLogicalPageRect, <<ThisRef:32/?UI>>). -%% @spec (This::wxPrintout(), PageSetupData::wxPageSetupDialogData:wxPageSetupDialogData()) -> {X::integer(),Y::integer(),W::integer(),H::integer()} +%% @spec (This::wxPrintout(), PageSetupData::wxPageSetupDialogData:wxPageSetupDialogData()) -> {X::integer(), Y::integer(), W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxprintout.html#wxprintoutgetlogicalpagemarginsrect">external documentation</a>. getLogicalPageMarginsRect(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=PageSetupDataT,ref=PageSetupDataRef}) -> ?CLASS(ThisT,wxPrintout), diff --git a/lib/wx/src/gen/wxRadioBox.erl b/lib/wx/src/gen/wxRadioBox.erl index 06e8833972..766a691108 100644 --- a/lib/wx/src/gen/wxRadioBox.erl +++ b/lib/wx/src/gen/wxRadioBox.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -78,13 +78,13 @@ parent_class(wxWindow) -> true; parent_class(wxEvtHandler) -> true; parent_class(_Class) -> erlang:error({badtype, ?MODULE}). -%% @spec (Parent::wxWindow:wxWindow(), Id::integer(), Title::string(), Pos::{X::integer(),Y::integer()}, Size::{W::integer(),H::integer()}, Choices::[[string()]]) -> wxRadioBox() +%% @spec (Parent::wxWindow:wxWindow(), Id::integer(), Title::string(), Pos::{X::integer(), Y::integer()}, Size::{W::integer(), H::integer()}, Choices::[[string()]]) -> wxRadioBox() %% @equiv new(Parent,Id,Title,Pos,Size,Choices, []) new(Parent,Id,Title,Pos={PosX,PosY},Size={SizeW,SizeH},Choices) when is_record(Parent, wx_ref),is_integer(Id),is_list(Title),is_integer(PosX),is_integer(PosY),is_integer(SizeW),is_integer(SizeH),is_list(Choices) -> new(Parent,Id,Title,Pos,Size,Choices, []). -%% @spec (Parent::wxWindow:wxWindow(), Id::integer(), Title::string(), Pos::{X::integer(),Y::integer()}, Size::{W::integer(),H::integer()}, Choices::[[string()]], [Option]) -> wxRadioBox() +%% @spec (Parent::wxWindow:wxWindow(), Id::integer(), Title::string(), Pos::{X::integer(), Y::integer()}, Size::{W::integer(), H::integer()}, Choices::[[string()]], [Option]) -> wxRadioBox() %% Option = {majorDim, integer()} | {style, integer()} | {val, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxradiobox.html#wxradioboxwxradiobox">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id,Title,{PosX,PosY},{SizeW,SizeH},Choices, Options) @@ -101,13 +101,13 @@ new(#wx_ref{type=ParentT,ref=ParentRef},Id,Title,{PosX,PosY},{SizeW,SizeH},Choic wxe_util:construct(?wxRadioBox_new, <<ParentRef:32/?UI,Id:32/?UI,(byte_size(Title_UC)):32/?UI,(Title_UC)/binary, 0:(((8- ((4+byte_size(Title_UC)) band 16#7)) band 16#7))/unit:8,PosX:32/?UI,PosY:32/?UI,SizeW:32/?UI,SizeH:32/?UI,(length(Choices_UCA)):32/?UI, (<< <<(byte_size(UC_Str)):32/?UI, UC_Str/binary>>|| UC_Str <- Choices_UCA>>)/binary, 0:(((8- ((4 + lists:sum([byte_size(S)+4||S<-Choices_UCA])) band 16#7)) band 16#7))/unit:8, BinOpt/binary>>). -%% @spec (This::wxRadioBox(), Parent::wxWindow:wxWindow(), Id::integer(), Title::string(), Pos::{X::integer(),Y::integer()}, Size::{W::integer(),H::integer()}, Choices::[[string()]]) -> bool() +%% @spec (This::wxRadioBox(), Parent::wxWindow:wxWindow(), Id::integer(), Title::string(), Pos::{X::integer(), Y::integer()}, Size::{W::integer(), H::integer()}, Choices::[[string()]]) -> bool() %% @equiv create(This,Parent,Id,Title,Pos,Size,Choices, []) create(This,Parent,Id,Title,Pos={PosX,PosY},Size={SizeW,SizeH},Choices) when is_record(This, wx_ref),is_record(Parent, wx_ref),is_integer(Id),is_list(Title),is_integer(PosX),is_integer(PosY),is_integer(SizeW),is_integer(SizeH),is_list(Choices) -> create(This,Parent,Id,Title,Pos,Size,Choices, []). -%% @spec (This::wxRadioBox(), Parent::wxWindow:wxWindow(), Id::integer(), Title::string(), Pos::{X::integer(),Y::integer()}, Size::{W::integer(),H::integer()}, Choices::[[string()]], [Option]) -> bool() +%% @spec (This::wxRadioBox(), Parent::wxWindow:wxWindow(), Id::integer(), Title::string(), Pos::{X::integer(), Y::integer()}, Size::{W::integer(), H::integer()}, Choices::[[string()]], [Option]) -> bool() %% Option = {majorDim, integer()} | {style, integer()} | {val, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxradiobox.html#wxradioboxcreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,Title,{PosX,PosY},{SizeW,SizeH},Choices, Options) @@ -251,7 +251,7 @@ getItemToolTip(#wx_ref{type=ThisT,ref=ThisRef},Item) wxe_util:call(?wxRadioBox_GetItemToolTip, <<ThisRef:32/?UI,Item:32/?UI>>). -%% @spec (This::wxRadioBox(), Pt::{X::integer(),Y::integer()}) -> integer() +%% @spec (This::wxRadioBox(), Pt::{X::integer(), Y::integer()}) -> integer() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxradiobox.html#wxradioboxgetitemfrompoint">external documentation</a>. getItemFromPoint(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) when is_integer(PtX),is_integer(PtY) -> diff --git a/lib/wx/src/gen/wxRadioButton.erl b/lib/wx/src/gen/wxRadioButton.erl index c2c5a00be6..c4665837b5 100644 --- a/lib/wx/src/gen/wxRadioButton.erl +++ b/lib/wx/src/gen/wxRadioButton.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -88,7 +88,7 @@ new(Parent,Id,Label) new(Parent,Id,Label, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), Label::string(), [Option]) -> wxRadioButton() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxradiobutton.html#wxradiobuttonwxradiobutton">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id,Label, Options) when is_integer(Id),is_list(Label),is_list(Options) -> @@ -110,7 +110,7 @@ create(This,Parent,Id,Label) create(This,Parent,Id,Label, []). %% @spec (This::wxRadioButton(), Parent::wxWindow:wxWindow(), Id::integer(), Label::string(), [Option]) -> bool() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxradiobutton.html#wxradiobuttoncreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,Label, Options) when is_integer(Id),is_list(Label),is_list(Options) -> diff --git a/lib/wx/src/gen/wxRegion.erl b/lib/wx/src/gen/wxRegion.erl index 4e8d98a54f..9107a4d6b1 100644 --- a/lib/wx/src/gen/wxRegion.erl +++ b/lib/wx/src/gen/wxRegion.erl @@ -59,7 +59,7 @@ new({RectX,RectY,RectW,RectH}) wxe_util:construct(?wxRegion_new_1_1, <<RectX:32/?UI,RectY:32/?UI,RectW:32/?UI,RectH:32/?UI>>). -%% @spec (TopLeft::{X::integer(),Y::integer()}, BottomRight::{X::integer(),Y::integer()}) -> wxRegion() +%% @spec (TopLeft::{X::integer(), Y::integer()}, BottomRight::{X::integer(), Y::integer()}) -> wxRegion() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxregion.html#wxregionwxregion">external documentation</a>. new({TopLeftX,TopLeftY},{BottomRightX,BottomRightY}) when is_integer(TopLeftX),is_integer(TopLeftY),is_integer(BottomRightX),is_integer(BottomRightY) -> @@ -84,12 +84,12 @@ clear(#wx_ref{type=ThisT,ref=ThisRef}) -> %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxregion.html#wxregioncontains">external documentation</a>. %% <br /> Alternatives: %% <p><c> -%% contains(This::wxRegion(), Pt::{X::integer(),Y::integer()}) -> WxRegionContain </c> +%% contains(This::wxRegion(), Pt::{X::integer(), Y::integer()}) -> WxRegionContain </c> %%<br /> WxRegionContain = integer() %%<br /> WxRegionContain is one of ?wxOutRegion | ?wxPartRegion | ?wxInRegion %% </p> %% <p><c> -%% contains(This::wxRegion(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}) -> WxRegionContain </c> +%% contains(This::wxRegion(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}) -> WxRegionContain </c> %%<br /> WxRegionContain = integer() %%<br /> WxRegionContain is one of ?wxOutRegion | ?wxPartRegion | ?wxInRegion %% </p> @@ -131,7 +131,7 @@ convertToBitmap(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxRegion_ConvertToBitmap, <<ThisRef:32/?UI>>). -%% @spec (This::wxRegion()) -> {X::integer(),Y::integer(),W::integer(),H::integer()} +%% @spec (This::wxRegion()) -> {X::integer(), Y::integer(), W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxregion.html#wxregiongetbox">external documentation</a>. getBox(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxRegion), @@ -145,7 +145,7 @@ getBox(#wx_ref{type=ThisT,ref=ThisRef}) -> %% intersect(This::wxRegion(), Region::wxRegion()) -> bool() </c> %% </p> %% <p><c> -%% intersect(This::wxRegion(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}) -> bool() </c> +%% intersect(This::wxRegion(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}) -> bool() </c> %% </p> intersect(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=RegionT,ref=RegionRef}) -> ?CLASS(ThisT,wxRegion), @@ -180,7 +180,7 @@ isEmpty(#wx_ref{type=ThisT,ref=ThisRef}) -> %% subtract(This::wxRegion(), Region::wxRegion()) -> bool() </c> %% </p> %% <p><c> -%% subtract(This::wxRegion(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}) -> bool() </c> +%% subtract(This::wxRegion(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}) -> bool() </c> %% </p> subtract(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=RegionT,ref=RegionRef}) -> ?CLASS(ThisT,wxRegion), @@ -201,7 +201,7 @@ subtract(#wx_ref{type=ThisT,ref=ThisRef},X,Y,W,H) wxe_util:call(?wxRegion_Subtract_4, <<ThisRef:32/?UI,X:32/?UI,Y:32/?UI,W:32/?UI,H:32/?UI>>). -%% @spec (This::wxRegion(), Pt::{X::integer(),Y::integer()}) -> bool() +%% @spec (This::wxRegion(), Pt::{X::integer(), Y::integer()}) -> bool() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxregion.html#wxregionoffset">external documentation</a>. offset(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) when is_integer(PtX),is_integer(PtY) -> @@ -224,7 +224,7 @@ offset(#wx_ref{type=ThisT,ref=ThisRef},X,Y) %% union(This::wxRegion(), Region::wxRegion() | wxBitmap:wxBitmap()) -> bool() </c> %% </p> %% <p><c> -%% union(This::wxRegion(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}) -> bool() </c> +%% union(This::wxRegion(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}) -> bool() </c> %% </p> union(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=RegionT,ref=RegionRef}) -> ?CLASS(ThisT,wxRegion), @@ -276,7 +276,7 @@ union(#wx_ref{type=ThisT,ref=ThisRef},X,Y,W,H) %% 'Xor'(This::wxRegion(), Region::wxRegion()) -> bool() </c> %% </p> %% <p><c> -%% 'Xor'(This::wxRegion(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}) -> bool() </c> +%% 'Xor'(This::wxRegion(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}) -> bool() </c> %% </p> 'Xor'(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=RegionT,ref=RegionRef}) -> ?CLASS(ThisT,wxRegion), diff --git a/lib/wx/src/gen/wxSashEvent.erl b/lib/wx/src/gen/wxSashEvent.erl index 480e241807..f9c58a04b1 100644 --- a/lib/wx/src/gen/wxSashEvent.erl +++ b/lib/wx/src/gen/wxSashEvent.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -54,7 +54,7 @@ getEdge(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxSashEvent_GetEdge, <<ThisRef:32/?UI>>). -%% @spec (This::wxSashEvent()) -> {X::integer(),Y::integer(),W::integer(),H::integer()} +%% @spec (This::wxSashEvent()) -> {X::integer(), Y::integer(), W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsashevent.html#wxsasheventgetdragrect">external documentation</a>. getDragRect(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxSashEvent), diff --git a/lib/wx/src/gen/wxSashLayoutWindow.erl b/lib/wx/src/gen/wxSashLayoutWindow.erl index 9bc5a185ba..eb8eb38011 100644 --- a/lib/wx/src/gen/wxSashLayoutWindow.erl +++ b/lib/wx/src/gen/wxSashLayoutWindow.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -93,7 +93,7 @@ new(Parent) new(Parent, []). %% @spec (Parent::wxWindow:wxWindow(), [Option]) -> wxSashLayoutWindow() -%% Option = {id, integer()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {id, integer()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsashlayoutwindow.html#wxsashlayoutwindowwxsashlayoutwindow">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef}, Options) when is_list(Options) -> @@ -114,7 +114,7 @@ create(This,Parent) create(This,Parent, []). %% @spec (This::wxSashLayoutWindow(), Parent::wxWindow:wxWindow(), [Option]) -> bool() -%% Option = {id, integer()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {id, integer()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsashlayoutwindow.html#wxsashlayoutwindowcreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef}, Options) when is_list(Options) -> @@ -157,7 +157,7 @@ setAlignment(#wx_ref{type=ThisT,ref=ThisRef},Align) wxe_util:cast(?wxSashLayoutWindow_SetAlignment, <<ThisRef:32/?UI,Align:32/?UI>>). -%% @spec (This::wxSashLayoutWindow(), Size::{W::integer(),H::integer()}) -> ok +%% @spec (This::wxSashLayoutWindow(), Size::{W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsashlayoutwindow.html#wxsashlayoutwindowsetdefaultsize">external documentation</a>. setDefaultSize(#wx_ref{type=ThisT,ref=ThisRef},{SizeW,SizeH}) when is_integer(SizeW),is_integer(SizeH) -> diff --git a/lib/wx/src/gen/wxSashWindow.erl b/lib/wx/src/gen/wxSashWindow.erl index 49fb82f828..698cfb8fb6 100644 --- a/lib/wx/src/gen/wxSashWindow.erl +++ b/lib/wx/src/gen/wxSashWindow.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -88,7 +88,7 @@ new(Parent) new(Parent, []). %% @spec (Parent::wxWindow:wxWindow(), [Option]) -> wxSashWindow() -%% Option = {id, integer()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {id, integer()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsashwindow.html#wxsashwindowwxsashwindow">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef}, Options) when is_list(Options) -> diff --git a/lib/wx/src/gen/wxScrollBar.erl b/lib/wx/src/gen/wxScrollBar.erl index 41ca8d867f..5c7890009f 100644 --- a/lib/wx/src/gen/wxScrollBar.erl +++ b/lib/wx/src/gen/wxScrollBar.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -89,7 +89,7 @@ new(Parent,Id) new(Parent,Id, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> wxScrollBar() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxscrollbar.html#wxscrollbarwxscrollbar">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> @@ -110,7 +110,7 @@ create(This,Parent,Id) create(This,Parent,Id, []). %% @spec (This::wxScrollBar(), Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> bool() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxscrollbar.html#wxscrollbarcreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> diff --git a/lib/wx/src/gen/wxScrolledWindow.erl b/lib/wx/src/gen/wxScrolledWindow.erl index a6f813d1a2..0693a79760 100644 --- a/lib/wx/src/gen/wxScrolledWindow.erl +++ b/lib/wx/src/gen/wxScrolledWindow.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -91,7 +91,7 @@ new(Parent) new(Parent, []). %% @spec (Parent::wxWindow:wxWindow(), [Option]) -> wxScrolledWindow() -%% Option = {winid, integer()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {winid, integer()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxscrolledwindow.html#wxscrolledwindowwxscrolledwindow">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef}, Options) when is_list(Options) -> @@ -105,7 +105,7 @@ new(#wx_ref{type=ParentT,ref=ParentRef}, Options) wxe_util:construct(?wxScrolledWindow_new_2, <<ParentRef:32/?UI, 0:32,BinOpt/binary>>). -%% @spec (This::wxScrolledWindow(), Pt::{X::integer(),Y::integer()}) -> {X::integer(),Y::integer()} +%% @spec (This::wxScrolledWindow(), Pt::{X::integer(), Y::integer()}) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxscrolledwindow.html#wxscrolledwindowcalcscrolledposition">external documentation</a>. calcScrolledPosition(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) when is_integer(PtX),is_integer(PtY) -> @@ -113,7 +113,7 @@ calcScrolledPosition(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) wxe_util:call(?wxScrolledWindow_CalcScrolledPosition_1, <<ThisRef:32/?UI,PtX:32/?UI,PtY:32/?UI>>). -%% @spec (This::wxScrolledWindow(), X::integer(), Y::integer()) -> {Xx::integer(),Yy::integer()} +%% @spec (This::wxScrolledWindow(), X::integer(), Y::integer()) -> {Xx::integer(), Yy::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxscrolledwindow.html#wxscrolledwindowcalcscrolledposition">external documentation</a>. calcScrolledPosition(#wx_ref{type=ThisT,ref=ThisRef},X,Y) when is_integer(X),is_integer(Y) -> @@ -121,7 +121,7 @@ calcScrolledPosition(#wx_ref{type=ThisT,ref=ThisRef},X,Y) wxe_util:call(?wxScrolledWindow_CalcScrolledPosition_4, <<ThisRef:32/?UI,X:32/?UI,Y:32/?UI>>). -%% @spec (This::wxScrolledWindow(), Pt::{X::integer(),Y::integer()}) -> {X::integer(),Y::integer()} +%% @spec (This::wxScrolledWindow(), Pt::{X::integer(), Y::integer()}) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxscrolledwindow.html#wxscrolledwindowcalcunscrolledposition">external documentation</a>. calcUnscrolledPosition(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) when is_integer(PtX),is_integer(PtY) -> @@ -129,7 +129,7 @@ calcUnscrolledPosition(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) wxe_util:call(?wxScrolledWindow_CalcUnscrolledPosition_1, <<ThisRef:32/?UI,PtX:32/?UI,PtY:32/?UI>>). -%% @spec (This::wxScrolledWindow(), X::integer(), Y::integer()) -> {Xx::integer(),Yy::integer()} +%% @spec (This::wxScrolledWindow(), X::integer(), Y::integer()) -> {Xx::integer(), Yy::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxscrolledwindow.html#wxscrolledwindowcalcunscrolledposition">external documentation</a>. calcUnscrolledPosition(#wx_ref{type=ThisT,ref=ThisRef},X,Y) when is_integer(X),is_integer(Y) -> @@ -145,14 +145,14 @@ enableScrolling(#wx_ref{type=ThisT,ref=ThisRef},X_scrolling,Y_scrolling) wxe_util:cast(?wxScrolledWindow_EnableScrolling, <<ThisRef:32/?UI,(wxe_util:from_bool(X_scrolling)):32/?UI,(wxe_util:from_bool(Y_scrolling)):32/?UI>>). -%% @spec (This::wxScrolledWindow()) -> {PixelsPerUnitX::integer(),PixelsPerUnitY::integer()} +%% @spec (This::wxScrolledWindow()) -> {PixelsPerUnitX::integer(), PixelsPerUnitY::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxscrolledwindow.html#wxscrolledwindowgetscrollpixelsperunit">external documentation</a>. getScrollPixelsPerUnit(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxScrolledWindow), wxe_util:call(?wxScrolledWindow_GetScrollPixelsPerUnit, <<ThisRef:32/?UI>>). -%% @spec (This::wxScrolledWindow()) -> {X::integer(),Y::integer()} +%% @spec (This::wxScrolledWindow()) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxscrolledwindow.html#wxscrolledwindowgetviewstart">external documentation</a>. getViewStart(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxScrolledWindow), diff --git a/lib/wx/src/gen/wxSingleChoiceDialog.erl b/lib/wx/src/gen/wxSingleChoiceDialog.erl index 16e0c3d8ce..e2b835917e 100644 --- a/lib/wx/src/gen/wxSingleChoiceDialog.erl +++ b/lib/wx/src/gen/wxSingleChoiceDialog.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -97,7 +97,7 @@ new(Parent,Message,Caption,Choices) new(Parent,Message,Caption,Choices, []). %% @spec (Parent::wxWindow:wxWindow(), Message::string(), Caption::string(), Choices::[[string()]], [Option]) -> wxSingleChoiceDialog() -%% Option = {style, integer()} | {pos, {X::integer(),Y::integer()}} +%% Option = {style, integer()} | {pos, {X::integer(), Y::integer()}} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsinglechoicedialog.html#wxsinglechoicedialogwxsinglechoicedialog">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Message,Caption,Choices, Options) when is_list(Message),is_list(Caption),is_list(Choices),is_list(Options) -> diff --git a/lib/wx/src/gen/wxSizeEvent.erl b/lib/wx/src/gen/wxSizeEvent.erl index 9e7619ebbd..0898f4aed9 100644 --- a/lib/wx/src/gen/wxSizeEvent.erl +++ b/lib/wx/src/gen/wxSizeEvent.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -41,7 +41,7 @@ parent_class(wxEvent) -> true; parent_class(_Class) -> erlang:error({badtype, ?MODULE}). -%% @spec (This::wxSizeEvent()) -> {W::integer(),H::integer()} +%% @spec (This::wxSizeEvent()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizeevent.html#wxsizeeventgetsize">external documentation</a>. getSize(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxSizeEvent), diff --git a/lib/wx/src/gen/wxSizer.erl b/lib/wx/src/gen/wxSizer.erl index e9b83a7333..0f1a92f379 100644 --- a/lib/wx/src/gen/wxSizer.erl +++ b/lib/wx/src/gen/wxSizer.erl @@ -132,7 +132,7 @@ addStretchSpacer(#wx_ref{type=ThisT,ref=ThisRef}, Options) wxe_util:call(?wxSizer_AddStretchSpacer, <<ThisRef:32/?UI, 0:32,BinOpt/binary>>). -%% @spec (This::wxSizer()) -> {W::integer(),H::integer()} +%% @spec (This::wxSizer()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizer.html#wxsizercalcmin">external documentation</a>. calcMin(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxSizer), @@ -182,7 +182,7 @@ detach(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=WindowT,ref=WindowRef}) -> wxe_util:call(WindowOP, <<ThisRef:32/?UI,WindowRef:32/?UI>>). -%% @spec (This::wxSizer(), Window::wxWindow:wxWindow()) -> {W::integer(),H::integer()} +%% @spec (This::wxSizer(), Window::wxWindow:wxWindow()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizer.html#wxsizerfit">external documentation</a>. fit(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=WindowT,ref=WindowRef}) -> ?CLASS(ThisT,wxSizer), @@ -241,21 +241,21 @@ getItem(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=WindowT,ref=WindowRef}, Opt wxe_util:call(WindowOP, <<ThisRef:32/?UI,WindowRef:32/?UI, BinOpt/binary>>). -%% @spec (This::wxSizer()) -> {W::integer(),H::integer()} +%% @spec (This::wxSizer()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizer.html#wxsizergetsize">external documentation</a>. getSize(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxSizer), wxe_util:call(?wxSizer_GetSize, <<ThisRef:32/?UI>>). -%% @spec (This::wxSizer()) -> {X::integer(),Y::integer()} +%% @spec (This::wxSizer()) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizer.html#wxsizergetposition">external documentation</a>. getPosition(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxSizer), wxe_util:call(?wxSizer_GetPosition, <<ThisRef:32/?UI>>). -%% @spec (This::wxSizer()) -> {W::integer(),H::integer()} +%% @spec (This::wxSizer()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizer.html#wxsizergetminsize">external documentation</a>. getMinSize(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxSizer), @@ -596,7 +596,7 @@ setDimension(#wx_ref{type=ThisT,ref=ThisRef},X,Y,Width,Height) wxe_util:cast(?wxSizer_SetDimension, <<ThisRef:32/?UI,X:32/?UI,Y:32/?UI,Width:32/?UI,Height:32/?UI>>). -%% @spec (This::wxSizer(), Size::{W::integer(),H::integer()}) -> ok +%% @spec (This::wxSizer(), Size::{W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizer.html#wxsizersetminsize">external documentation</a>. setMinSize(#wx_ref{type=ThisT,ref=ThisRef},{SizeW,SizeH}) when is_integer(SizeW),is_integer(SizeH) -> @@ -612,14 +612,14 @@ setMinSize(#wx_ref{type=ThisT,ref=ThisRef},Width,Height) wxe_util:cast(?wxSizer_SetMinSize_2, <<ThisRef:32/?UI,Width:32/?UI,Height:32/?UI>>). -%% @spec (This::wxSizer(),X::integer()|term(),Size::{W::integer(),H::integer()}) -> bool() +%% @spec (This::wxSizer(),X::integer()|term(),Size::{W::integer(), H::integer()}) -> bool() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizer.html#wxsizersetitemminsize">external documentation</a>. %% <br /> Alternatives: %% <p><c> -%% setItemMinSize(This::wxSizer(), Index::integer(), Size::{W::integer(),H::integer()}) -> bool() </c> +%% setItemMinSize(This::wxSizer(), Index::integer(), Size::{W::integer(), H::integer()}) -> bool() </c> %% </p> %% <p><c> -%% setItemMinSize(This::wxSizer(), Window::wxWindow:wxWindow() | wxSizer(), Size::{W::integer(),H::integer()}) -> bool() </c> +%% setItemMinSize(This::wxSizer(), Window::wxWindow:wxWindow() | wxSizer(), Size::{W::integer(), H::integer()}) -> bool() </c> %% </p> setItemMinSize(#wx_ref{type=ThisT,ref=ThisRef},Index,{SizeW,SizeH}) when is_integer(Index),is_integer(SizeW),is_integer(SizeH) -> diff --git a/lib/wx/src/gen/wxSizerItem.erl b/lib/wx/src/gen/wxSizerItem.erl index 1e9f05d53c..41cb86eae2 100644 --- a/lib/wx/src/gen/wxSizerItem.erl +++ b/lib/wx/src/gen/wxSizerItem.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -89,7 +89,7 @@ new(Width,Height,Proportion,Flag,Border,#wx_ref{type=UserDataT,ref=UserDataRef}) wxe_util:construct(?wxSizerItem_new_6, <<Width:32/?UI,Height:32/?UI,Proportion:32/?UI,Flag:32/?UI,Border:32/?UI,UserDataRef:32/?UI>>). -%% @spec (This::wxSizerItem()) -> {W::integer(),H::integer()} +%% @spec (This::wxSizerItem()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizeritem.html#wxsizeritemcalcmin">external documentation</a>. calcMin(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxSizerItem), @@ -124,14 +124,14 @@ getFlag(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxSizerItem_GetFlag, <<ThisRef:32/?UI>>). -%% @spec (This::wxSizerItem()) -> {W::integer(),H::integer()} +%% @spec (This::wxSizerItem()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizeritem.html#wxsizeritemgetminsize">external documentation</a>. getMinSize(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxSizerItem), wxe_util:call(?wxSizerItem_GetMinSize, <<ThisRef:32/?UI>>). -%% @spec (This::wxSizerItem()) -> {X::integer(),Y::integer()} +%% @spec (This::wxSizerItem()) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizeritem.html#wxsizeritemgetposition">external documentation</a>. getPosition(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxSizerItem), @@ -152,14 +152,14 @@ getRatio(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxSizerItem_GetRatio, <<ThisRef:32/?UI>>). -%% @spec (This::wxSizerItem()) -> {X::integer(),Y::integer(),W::integer(),H::integer()} +%% @spec (This::wxSizerItem()) -> {X::integer(), Y::integer(), W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizeritem.html#wxsizeritemgetrect">external documentation</a>. getRect(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxSizerItem), wxe_util:call(?wxSizerItem_GetRect, <<ThisRef:32/?UI>>). -%% @spec (This::wxSizerItem()) -> {W::integer(),H::integer()} +%% @spec (This::wxSizerItem()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizeritem.html#wxsizeritemgetsize">external documentation</a>. getSize(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxSizerItem), @@ -173,7 +173,7 @@ getSizer(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxSizerItem_GetSizer, <<ThisRef:32/?UI>>). -%% @spec (This::wxSizerItem()) -> {W::integer(),H::integer()} +%% @spec (This::wxSizerItem()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizeritem.html#wxsizeritemgetspacer">external documentation</a>. getSpacer(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxSizerItem), @@ -230,7 +230,7 @@ setBorder(#wx_ref{type=ThisT,ref=ThisRef},Border) wxe_util:cast(?wxSizerItem_SetBorder, <<ThisRef:32/?UI,Border:32/?UI>>). -%% @spec (This::wxSizerItem(), Pos::{X::integer(),Y::integer()}, Size::{W::integer(),H::integer()}) -> ok +%% @spec (This::wxSizerItem(), Pos::{X::integer(), Y::integer()}, Size::{W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizeritem.html#wxsizeritemsetdimension">external documentation</a>. setDimension(#wx_ref{type=ThisT,ref=ThisRef},{PosX,PosY},{SizeW,SizeH}) when is_integer(PosX),is_integer(PosY),is_integer(SizeW),is_integer(SizeH) -> @@ -254,7 +254,7 @@ setInitSize(#wx_ref{type=ThisT,ref=ThisRef},X,Y) wxe_util:cast(?wxSizerItem_SetInitSize, <<ThisRef:32/?UI,X:32/?UI,Y:32/?UI>>). -%% @spec (This::wxSizerItem(), Size::{W::integer(),H::integer()}) -> ok +%% @spec (This::wxSizerItem(), Size::{W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizeritem.html#wxsizeritemsetminsize">external documentation</a>. setMinSize(#wx_ref{type=ThisT,ref=ThisRef},{SizeW,SizeH}) when is_integer(SizeW),is_integer(SizeH) -> @@ -285,7 +285,7 @@ setProportion(#wx_ref{type=ThisT,ref=ThisRef},Proportion) %% setRatio(This::wxSizerItem(), Ratio::float()) -> ok </c> %% </p> %% <p><c> -%% setRatio(This::wxSizerItem(), Size::{W::integer(),H::integer()}) -> ok </c> +%% setRatio(This::wxSizerItem(), Size::{W::integer(), H::integer()}) -> ok </c> %% </p> setRatio(#wx_ref{type=ThisT,ref=ThisRef},Ratio) when is_float(Ratio) -> @@ -314,7 +314,7 @@ setSizer(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=SizerT,ref=SizerRef}) -> wxe_util:cast(?wxSizerItem_SetSizer, <<ThisRef:32/?UI,SizerRef:32/?UI>>). -%% @spec (This::wxSizerItem(), Size::{W::integer(),H::integer()}) -> ok +%% @spec (This::wxSizerItem(), Size::{W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsizeritem.html#wxsizeritemsetspacer">external documentation</a>. setSpacer(#wx_ref{type=ThisT,ref=ThisRef},{SizeW,SizeH}) when is_integer(SizeW),is_integer(SizeH) -> diff --git a/lib/wx/src/gen/wxSlider.erl b/lib/wx/src/gen/wxSlider.erl index c70f127a5b..c7a3d6f5c0 100644 --- a/lib/wx/src/gen/wxSlider.erl +++ b/lib/wx/src/gen/wxSlider.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -90,7 +90,7 @@ new(Parent,Id,Value,MinValue,MaxValue) new(Parent,Id,Value,MinValue,MaxValue, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), Value::integer(), MinValue::integer(), MaxValue::integer(), [Option]) -> wxSlider() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxslider.html#wxsliderwxslider">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id,Value,MinValue,MaxValue, Options) when is_integer(Id),is_integer(Value),is_integer(MinValue),is_integer(MaxValue),is_list(Options) -> @@ -111,7 +111,7 @@ create(This,Parent,Id,Value,MinValue,MaxValue) create(This,Parent,Id,Value,MinValue,MaxValue, []). %% @spec (This::wxSlider(), Parent::wxWindow:wxWindow(), Id::integer(), Value::integer(), MinValue::integer(), MaxValue::integer(), [Option]) -> bool() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxslider.html#wxslidercreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,Value,MinValue,MaxValue, Options) when is_integer(Id),is_integer(Value),is_integer(MinValue),is_integer(MaxValue),is_list(Options) -> diff --git a/lib/wx/src/gen/wxSpinButton.erl b/lib/wx/src/gen/wxSpinButton.erl index 027699e295..e269dbe329 100644 --- a/lib/wx/src/gen/wxSpinButton.erl +++ b/lib/wx/src/gen/wxSpinButton.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -89,7 +89,7 @@ new(Parent) new(Parent, []). %% @spec (Parent::wxWindow:wxWindow(), [Option]) -> wxSpinButton() -%% Option = {id, integer()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {id, integer()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxspinbutton.html#wxspinbuttonwxspinbutton">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef}, Options) when is_list(Options) -> @@ -110,7 +110,7 @@ create(This,Parent) create(This,Parent, []). %% @spec (This::wxSpinButton(), Parent::wxWindow:wxWindow(), [Option]) -> bool() -%% Option = {id, integer()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {id, integer()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxspinbutton.html#wxspinbuttoncreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef}, Options) when is_list(Options) -> diff --git a/lib/wx/src/gen/wxSpinCtrl.erl b/lib/wx/src/gen/wxSpinCtrl.erl index 6b77376b40..c6e8ad2238 100644 --- a/lib/wx/src/gen/wxSpinCtrl.erl +++ b/lib/wx/src/gen/wxSpinCtrl.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -89,7 +89,7 @@ new(Parent) new(Parent, []). %% @spec (Parent::wxWindow:wxWindow(), [Option]) -> wxSpinCtrl() -%% Option = {id, integer()} | {value, string()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {min, integer()} | {max, integer()} | {initial, integer()} +%% Option = {id, integer()} | {value, string()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {min, integer()} | {max, integer()} | {initial, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxspinctrl.html#wxspinctrlwxspinctrl">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef}, Options) when is_list(Options) -> @@ -114,7 +114,7 @@ create(This,Parent) create(This,Parent, []). %% @spec (This::wxSpinCtrl(), Parent::wxWindow:wxWindow(), [Option]) -> bool() -%% Option = {id, integer()} | {value, string()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {min, integer()} | {max, integer()} | {initial, integer()} +%% Option = {id, integer()} | {value, string()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {min, integer()} | {max, integer()} | {initial, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxspinctrl.html#wxspinctrlcreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef}, Options) when is_list(Options) -> diff --git a/lib/wx/src/gen/wxSplashScreen.erl b/lib/wx/src/gen/wxSplashScreen.erl index 8806d07018..79ef8e413a 100644 --- a/lib/wx/src/gen/wxSplashScreen.erl +++ b/lib/wx/src/gen/wxSplashScreen.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -100,7 +100,7 @@ new(Bitmap,SplashStyle,Milliseconds,Parent,Id) new(Bitmap,SplashStyle,Milliseconds,Parent,Id, []). %% @spec (Bitmap::wxBitmap:wxBitmap(), SplashStyle::integer(), Milliseconds::integer(), Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> wxSplashScreen() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsplashscreen.html#wxsplashscreenwxsplashscreen">external documentation</a>. new(#wx_ref{type=BitmapT,ref=BitmapRef},SplashStyle,Milliseconds,#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(SplashStyle),is_integer(Milliseconds),is_integer(Id),is_list(Options) -> diff --git a/lib/wx/src/gen/wxSplitterWindow.erl b/lib/wx/src/gen/wxSplitterWindow.erl index 9e27be7475..b17fed3151 100644 --- a/lib/wx/src/gen/wxSplitterWindow.erl +++ b/lib/wx/src/gen/wxSplitterWindow.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2009-2010. All Rights Reserved. +%% Copyright Ericsson AB 2009-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -91,7 +91,7 @@ new(Parent) new(Parent, []). %% @spec (Parent::wxWindow:wxWindow(), [Option]) -> wxSplitterWindow() -%% Option = {id, integer()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {id, integer()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsplitterwindow.html#wxsplitterwindowwxsplitterwindow">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef}, Options) when is_list(Options) -> @@ -112,7 +112,7 @@ create(This,Parent) create(This,Parent, []). %% @spec (This::wxSplitterWindow(), Parent::wxWindow:wxWindow(), [Option]) -> bool() -%% Option = {id, integer()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {id, integer()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsplitterwindow.html#wxsplitterwindowcreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef}, Options) when is_list(Options) -> diff --git a/lib/wx/src/gen/wxStaticBitmap.erl b/lib/wx/src/gen/wxStaticBitmap.erl index 6fbc59236d..31e39b3a6c 100644 --- a/lib/wx/src/gen/wxStaticBitmap.erl +++ b/lib/wx/src/gen/wxStaticBitmap.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -88,7 +88,7 @@ new(Parent,Id,Label) new(Parent,Id,Label, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), Label::wxBitmap:wxBitmap(), [Option]) -> wxStaticBitmap() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxstaticbitmap.html#wxstaticbitmapwxstaticbitmap">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id,#wx_ref{type=LabelT,ref=LabelRef}, Options) when is_integer(Id),is_list(Options) -> @@ -109,7 +109,7 @@ create(This,Parent,Id,Label) create(This,Parent,Id,Label, []). %% @spec (This::wxStaticBitmap(), Parent::wxWindow:wxWindow(), Id::integer(), Label::wxBitmap:wxBitmap(), [Option]) -> bool() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxstaticbitmap.html#wxstaticbitmapcreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,#wx_ref{type=LabelT,ref=LabelRef}, Options) when is_integer(Id),is_list(Options) -> diff --git a/lib/wx/src/gen/wxStaticBox.erl b/lib/wx/src/gen/wxStaticBox.erl index ad54184867..ec83ff5fd9 100644 --- a/lib/wx/src/gen/wxStaticBox.erl +++ b/lib/wx/src/gen/wxStaticBox.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -88,7 +88,7 @@ new(Parent,Id,Label) new(Parent,Id,Label, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), Label::string(), [Option]) -> wxStaticBox() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxstaticbox.html#wxstaticboxwxstaticbox">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id,Label, Options) when is_integer(Id),is_list(Label),is_list(Options) -> @@ -109,7 +109,7 @@ create(This,Parent,Id,Label) create(This,Parent,Id,Label, []). %% @spec (This::wxStaticBox(), Parent::wxWindow:wxWindow(), Id::integer(), Label::string(), [Option]) -> bool() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxstaticbox.html#wxstaticboxcreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,Label, Options) when is_integer(Id),is_list(Label),is_list(Options) -> diff --git a/lib/wx/src/gen/wxStaticLine.erl b/lib/wx/src/gen/wxStaticLine.erl index e3a1bedbdc..a850065ba0 100644 --- a/lib/wx/src/gen/wxStaticLine.erl +++ b/lib/wx/src/gen/wxStaticLine.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -89,7 +89,7 @@ new(Parent) new(Parent, []). %% @spec (Parent::wxWindow:wxWindow(), [Option]) -> wxStaticLine() -%% Option = {id, integer()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {id, integer()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxstaticline.html#wxstaticlinewxstaticline">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef}, Options) when is_list(Options) -> @@ -110,7 +110,7 @@ create(This,Parent) create(This,Parent, []). %% @spec (This::wxStaticLine(), Parent::wxWindow:wxWindow(), [Option]) -> bool() -%% Option = {id, integer()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {id, integer()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxstaticline.html#wxstaticlinecreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef}, Options) when is_list(Options) -> diff --git a/lib/wx/src/gen/wxStaticText.erl b/lib/wx/src/gen/wxStaticText.erl index 46c73a5998..301999d49a 100644 --- a/lib/wx/src/gen/wxStaticText.erl +++ b/lib/wx/src/gen/wxStaticText.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -88,7 +88,7 @@ new(Parent,Id,Label) new(Parent,Id,Label, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), Label::string(), [Option]) -> wxStaticText() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxstatictext.html#wxstatictextwxstatictext">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id,Label, Options) when is_integer(Id),is_list(Label),is_list(Options) -> @@ -109,7 +109,7 @@ create(This,Parent,Id,Label) create(This,Parent,Id,Label, []). %% @spec (This::wxStaticText(), Parent::wxWindow:wxWindow(), Id::integer(), Label::string(), [Option]) -> bool() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxstatictext.html#wxstatictextcreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,Label, Options) when is_integer(Id),is_list(Label),is_list(Options) -> diff --git a/lib/wx/src/gen/wxStatusBar.erl b/lib/wx/src/gen/wxStatusBar.erl index 52467117d7..6e77761f1d 100644 --- a/lib/wx/src/gen/wxStatusBar.erl +++ b/lib/wx/src/gen/wxStatusBar.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -121,7 +121,7 @@ create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef}, Opti wxe_util:call(?wxStatusBar_Create, <<ThisRef:32/?UI,ParentRef:32/?UI, BinOpt/binary>>). -%% @spec (This::wxStatusBar(), I::integer(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}) -> bool() +%% @spec (This::wxStatusBar(), I::integer(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}) -> bool() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxstatusbar.html#wxstatusbargetfieldrect">external documentation</a>. getFieldRect(#wx_ref{type=ThisT,ref=ThisRef},I,{RectX,RectY,RectW,RectH}) when is_integer(I),is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH) -> diff --git a/lib/wx/src/gen/wxStyledTextCtrl.erl b/lib/wx/src/gen/wxStyledTextCtrl.erl index 71d1bd0d53..61f0e5afef 100644 --- a/lib/wx/src/gen/wxStyledTextCtrl.erl +++ b/lib/wx/src/gen/wxStyledTextCtrl.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -190,7 +190,7 @@ new(Parent) new(Parent, []). %% @spec (Parent::wxWindow:wxWindow(), [Option]) -> wxStyledTextCtrl() -%% Option = {id, integer()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {id, integer()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxstyledtextctrl.html#wxstyledtextctrlwxstyledtextctrl">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef}, Options) when is_list(Options) -> @@ -211,7 +211,7 @@ create(This,Parent) create(This,Parent, []). %% @spec (This::wxStyledTextCtrl(), Parent::wxWindow:wxWindow(), [Option]) -> bool() -%% Option = {id, integer()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {id, integer()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxstyledtextctrl.html#wxstyledtextctrlcreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef}, Options) when is_list(Options) -> @@ -385,7 +385,7 @@ setViewWhiteSpace(#wx_ref{type=ThisT,ref=ThisRef},ViewWS) wxe_util:cast(?wxStyledTextCtrl_SetViewWhiteSpace, <<ThisRef:32/?UI,ViewWS:32/?UI>>). -%% @spec (This::wxStyledTextCtrl(), Pt::{X::integer(),Y::integer()}) -> integer() +%% @spec (This::wxStyledTextCtrl(), Pt::{X::integer(), Y::integer()}) -> integer() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxstyledtextctrl.html#wxstyledtextctrlpositionfrompoint">external documentation</a>. positionFromPoint(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) when is_integer(PtX),is_integer(PtY) -> @@ -425,7 +425,7 @@ setAnchor(#wx_ref{type=ThisT,ref=ThisRef},PosAnchor) wxe_util:cast(?wxStyledTextCtrl_SetAnchor, <<ThisRef:32/?UI,PosAnchor:32/?UI>>). -%% @spec (This::wxStyledTextCtrl()) -> {string(),LinePos::integer()} +%% @spec (This::wxStyledTextCtrl()) -> {string(), LinePos::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxstyledtextctrl.html#wxstyledtextctrlgetcurline">external documentation</a>. getCurLine(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxStyledTextCtrl), @@ -1454,7 +1454,7 @@ findText(#wx_ref{type=ThisT,ref=ThisRef},MinPos,MaxPos,Text, Options) wxe_util:call(?wxStyledTextCtrl_FindText, <<ThisRef:32/?UI,MinPos:32/?UI,MaxPos:32/?UI,(byte_size(Text_UC)):32/?UI,(Text_UC)/binary, 0:(((8- ((0+byte_size(Text_UC)) band 16#7)) band 16#7))/unit:8, BinOpt/binary>>). -%% @spec (This::wxStyledTextCtrl(), DoDraw::bool(), StartPos::integer(), EndPos::integer(), Draw::wxDC:wxDC(), Target::wxDC:wxDC(), RenderRect::{X::integer(),Y::integer(),W::integer(),H::integer()}, PageRect::{X::integer(),Y::integer(),W::integer(),H::integer()}) -> integer() +%% @spec (This::wxStyledTextCtrl(), DoDraw::bool(), StartPos::integer(), EndPos::integer(), Draw::wxDC:wxDC(), Target::wxDC:wxDC(), RenderRect::{X::integer(), Y::integer(), W::integer(), H::integer()}, PageRect::{X::integer(), Y::integer(), W::integer(), H::integer()}) -> integer() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxstyledtextctrl.html#wxstyledtextctrlformatrange">external documentation</a>. formatRange(#wx_ref{type=ThisT,ref=ThisRef},DoDraw,StartPos,EndPos,#wx_ref{type=DrawT,ref=DrawRef},#wx_ref{type=TargetT,ref=TargetRef},{RenderRectX,RenderRectY,RenderRectW,RenderRectH},{PageRectX,PageRectY,PageRectW,PageRectH}) when is_boolean(DoDraw),is_integer(StartPos),is_integer(EndPos),is_integer(RenderRectX),is_integer(RenderRectY),is_integer(RenderRectW),is_integer(RenderRectH),is_integer(PageRectX),is_integer(PageRectY),is_integer(PageRectW),is_integer(PageRectH) -> @@ -3417,14 +3417,14 @@ setMargins(#wx_ref{type=ThisT,ref=ThisRef},Left,Right) wxe_util:cast(?wxStyledTextCtrl_SetMargins, <<ThisRef:32/?UI,Left:32/?UI,Right:32/?UI>>). -%% @spec (This::wxStyledTextCtrl()) -> {StartPos::integer(),EndPos::integer()} +%% @spec (This::wxStyledTextCtrl()) -> {StartPos::integer(), EndPos::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxstyledtextctrl.html#wxstyledtextctrlgetselection">external documentation</a>. getSelection(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxStyledTextCtrl), wxe_util:call(?wxStyledTextCtrl_GetSelection, <<ThisRef:32/?UI>>). -%% @spec (This::wxStyledTextCtrl(), Pos::integer()) -> {X::integer(),Y::integer()} +%% @spec (This::wxStyledTextCtrl(), Pos::integer()) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxstyledtextctrl.html#wxstyledtextctrlpointfromposition">external documentation</a>. pointFromPosition(#wx_ref{type=ThisT,ref=ThisRef},Pos) when is_integer(Pos) -> @@ -3562,7 +3562,7 @@ insertTextRaw(#wx_ref{type=ThisT,ref=ThisRef},Pos,Text) wxe_util:cast(?wxStyledTextCtrl_InsertTextRaw, <<ThisRef:32/?UI,Pos:32/?UI>>). -%% @spec (This::wxStyledTextCtrl()) -> {binary(),LinePos::integer()} +%% @spec (This::wxStyledTextCtrl()) -> {binary(), LinePos::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxstyledtextctrl.html#wxstyledtextctrlgetcurlineraw">external documentation</a>. getCurLineRaw(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxStyledTextCtrl), diff --git a/lib/wx/src/gen/wxSystemOptions.erl b/lib/wx/src/gen/wxSystemOptions.erl new file mode 100644 index 0000000000..d5e504632b --- /dev/null +++ b/lib/wx/src/gen/wxSystemOptions.erl @@ -0,0 +1,87 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% This file is generated DO NOT EDIT + +%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsystemoptions.html">wxSystemOptions</a>. +%% @type wxSystemOptions(). An object reference, The representation is internal +%% and can be changed without notice. It can't be used for comparsion +%% stored on disc or distributed for use on other nodes. + +-module(wxSystemOptions). +-include("wxe.hrl"). +-export([getOption/1,getOptionInt/1,hasOption/1,isFalse/1,setOption/2]). + +%% inherited exports +-export([parent_class/1]). + +%% @hidden +parent_class(_Class) -> erlang:error({badtype, ?MODULE}). + +%% @spec (Name::string()) -> string() +%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsystemoptions.html#wxsystemoptionsgetoption">external documentation</a>. +getOption(Name) + when is_list(Name) -> + Name_UC = unicode:characters_to_binary([Name,0]), + wxe_util:call(?wxSystemOptions_GetOption, + <<(byte_size(Name_UC)):32/?UI,(Name_UC)/binary, 0:(((8- ((4+byte_size(Name_UC)) band 16#7)) band 16#7))/unit:8>>). + +%% @spec (Name::string()) -> integer() +%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsystemoptions.html#wxsystemoptionsgetoptionint">external documentation</a>. +getOptionInt(Name) + when is_list(Name) -> + Name_UC = unicode:characters_to_binary([Name,0]), + wxe_util:call(?wxSystemOptions_GetOptionInt, + <<(byte_size(Name_UC)):32/?UI,(Name_UC)/binary, 0:(((8- ((4+byte_size(Name_UC)) band 16#7)) band 16#7))/unit:8>>). + +%% @spec (Name::string()) -> bool() +%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsystemoptions.html#wxsystemoptionshasoption">external documentation</a>. +hasOption(Name) + when is_list(Name) -> + Name_UC = unicode:characters_to_binary([Name,0]), + wxe_util:call(?wxSystemOptions_HasOption, + <<(byte_size(Name_UC)):32/?UI,(Name_UC)/binary, 0:(((8- ((4+byte_size(Name_UC)) band 16#7)) band 16#7))/unit:8>>). + +%% @spec (Name::string()) -> bool() +%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsystemoptions.html#wxsystemoptionsisfalse">external documentation</a>. +isFalse(Name) + when is_list(Name) -> + Name_UC = unicode:characters_to_binary([Name,0]), + wxe_util:call(?wxSystemOptions_IsFalse, + <<(byte_size(Name_UC)):32/?UI,(Name_UC)/binary, 0:(((8- ((4+byte_size(Name_UC)) band 16#7)) band 16#7))/unit:8>>). + +%% @spec (Name::string(),X::integer()|string()) -> ok +%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsystemoptions.html#wxsystemoptionssetoption">external documentation</a>. +%% <br /> Alternatives: +%% <p><c> +%% setOption(Name::string(), Value::integer()) -> ok </c> +%% </p> +%% <p><c> +%% setOption(Name::string(), Value::string()) -> ok </c> +%% </p> +setOption(Name,Value) + when is_list(Name),is_integer(Value) -> + Name_UC = unicode:characters_to_binary([Name,0]), + wxe_util:cast(?wxSystemOptions_SetOption_2_0, + <<(byte_size(Name_UC)):32/?UI,(Name_UC)/binary, 0:(((8- ((4+byte_size(Name_UC)) band 16#7)) band 16#7))/unit:8,Value:32/?UI>>); +setOption(Name,Value) + when is_list(Name),is_list(Value) -> + Name_UC = unicode:characters_to_binary([Name,0]), + Value_UC = unicode:characters_to_binary([Value,0]), + wxe_util:cast(?wxSystemOptions_SetOption_2_1, + <<(byte_size(Name_UC)):32/?UI,(Name_UC)/binary, 0:(((8- ((4+byte_size(Name_UC)) band 16#7)) band 16#7))/unit:8,(byte_size(Value_UC)):32/?UI,(Value_UC)/binary, 0:(((8- ((4+byte_size(Value_UC)) band 16#7)) band 16#7))/unit:8>>). + diff --git a/lib/wx/src/gen/wxTextCtrl.erl b/lib/wx/src/gen/wxTextCtrl.erl index b4af23bdd9..b32f45b83b 100644 --- a/lib/wx/src/gen/wxTextCtrl.erl +++ b/lib/wx/src/gen/wxTextCtrl.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -96,7 +96,7 @@ new(Parent,Id) new(Parent,Id, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> wxTextCtrl() -%% Option = {value, string()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {value, string()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtextctrl.html#wxtextctrlwxtextctrl">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> @@ -176,7 +176,7 @@ create(This,Parent,Id) create(This,Parent,Id, []). %% @spec (This::wxTextCtrl(), Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> bool() -%% Option = {value, string()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {value, string()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtextctrl.html#wxtextctrlcreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> @@ -266,7 +266,7 @@ getRange(#wx_ref{type=ThisT,ref=ThisRef},From,To) wxe_util:call(?wxTextCtrl_GetRange, <<ThisRef:32/?UI,From:32/?UI,To:32/?UI>>). -%% @spec (This::wxTextCtrl()) -> {From::integer(),To::integer()} +%% @spec (This::wxTextCtrl()) -> {From::integer(), To::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtextctrl.html#wxtextctrlgetselection">external documentation</a>. getSelection(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxTextCtrl), @@ -357,7 +357,7 @@ paste(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:cast(?wxTextCtrl_Paste, <<ThisRef:32/?UI>>). -%% @spec (This::wxTextCtrl(), Pos::integer()) -> {bool(),X::integer(),Y::integer()} +%% @spec (This::wxTextCtrl(), Pos::integer()) -> {bool(), X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtextctrl.html#wxtextctrlpositiontoxy">external documentation</a>. positionToXY(#wx_ref{type=ThisT,ref=ThisRef},Pos) when is_integer(Pos) -> diff --git a/lib/wx/src/gen/wxTextEntryDialog.erl b/lib/wx/src/gen/wxTextEntryDialog.erl index a30c32dd53..53694a47e6 100644 --- a/lib/wx/src/gen/wxTextEntryDialog.erl +++ b/lib/wx/src/gen/wxTextEntryDialog.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -91,7 +91,7 @@ new(Parent,Message) new(Parent,Message, []). %% @spec (Parent::wxWindow:wxWindow(), Message::string(), [Option]) -> wxTextEntryDialog() -%% Option = {caption, string()} | {value, string()} | {style, integer()} | {pos, {X::integer(),Y::integer()}} +%% Option = {caption, string()} | {value, string()} | {style, integer()} | {pos, {X::integer(), Y::integer()}} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtextentrydialog.html#wxtextentrydialogwxtextentrydialog">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Message, Options) when is_list(Message),is_list(Options) -> diff --git a/lib/wx/src/gen/wxToggleButton.erl b/lib/wx/src/gen/wxToggleButton.erl index ab595c1906..d7755cc50b 100644 --- a/lib/wx/src/gen/wxToggleButton.erl +++ b/lib/wx/src/gen/wxToggleButton.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -88,7 +88,7 @@ new(Parent,Id,Label) new(Parent,Id,Label, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), Label::string(), [Option]) -> wxToggleButton() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtogglebutton.html#wxtogglebuttonwxtogglebutton">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id,Label, Options) when is_integer(Id),is_list(Label),is_list(Options) -> @@ -110,7 +110,7 @@ create(This,Parent,Id,Label) create(This,Parent,Id,Label, []). %% @spec (This::wxToggleButton(), Parent::wxWindow:wxWindow(), Id::integer(), Label::string(), [Option]) -> bool() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtogglebutton.html#wxtogglebuttoncreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id,Label, Options) when is_integer(Id),is_list(Label),is_list(Options) -> diff --git a/lib/wx/src/gen/wxToolBar.erl b/lib/wx/src/gen/wxToolBar.erl index c68936d493..59369368f0 100644 --- a/lib/wx/src/gen/wxToolBar.erl +++ b/lib/wx/src/gen/wxToolBar.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -327,21 +327,21 @@ findToolForPosition(#wx_ref{type=ThisT,ref=ThisRef},X,Y) wxe_util:call(?wxToolBar_FindToolForPosition, <<ThisRef:32/?UI,X:32/?UI,Y:32/?UI>>). -%% @spec (This::wxToolBar()) -> {W::integer(),H::integer()} +%% @spec (This::wxToolBar()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtoolbar.html#wxtoolbargettoolsize">external documentation</a>. getToolSize(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxToolBar), wxe_util:call(?wxToolBar_GetToolSize, <<ThisRef:32/?UI>>). -%% @spec (This::wxToolBar()) -> {W::integer(),H::integer()} +%% @spec (This::wxToolBar()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtoolbar.html#wxtoolbargettoolbitmapsize">external documentation</a>. getToolBitmapSize(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxToolBar), wxe_util:call(?wxToolBar_GetToolBitmapSize, <<ThisRef:32/?UI>>). -%% @spec (This::wxToolBar()) -> {W::integer(),H::integer()} +%% @spec (This::wxToolBar()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtoolbar.html#wxtoolbargetmargins">external documentation</a>. getMargins(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxToolBar), @@ -504,7 +504,7 @@ setMargins(#wx_ref{type=ThisT,ref=ThisRef},X,Y) wxe_util:cast(?wxToolBar_SetMargins, <<ThisRef:32/?UI,X:32/?UI,Y:32/?UI>>). -%% @spec (This::wxToolBar(), Size::{W::integer(),H::integer()}) -> ok +%% @spec (This::wxToolBar(), Size::{W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtoolbar.html#wxtoolbarsettoolbitmapsize">external documentation</a>. setToolBitmapSize(#wx_ref{type=ThisT,ref=ThisRef},{SizeW,SizeH}) when is_integer(SizeW),is_integer(SizeH) -> diff --git a/lib/wx/src/gen/wxToolbook.erl b/lib/wx/src/gen/wxToolbook.erl index 4d188e979d..764f66c2e5 100644 --- a/lib/wx/src/gen/wxToolbook.erl +++ b/lib/wx/src/gen/wxToolbook.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2009-2010. All Rights Reserved. +%% Copyright Ericsson AB 2009-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -93,7 +93,7 @@ new(Parent,Id) new(Parent,Id, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> wxToolbook() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtoolbook.html#wxtoolbookwxtoolbook">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> @@ -160,7 +160,7 @@ create(This,Parent,Id) create(This,Parent,Id, []). %% @spec (This::wxToolbook(), Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> bool() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtoolbook.html#wxtoolbookcreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> @@ -249,7 +249,7 @@ getSelection(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxToolbook_GetSelection, <<ThisRef:32/?UI>>). -%% @spec (This::wxToolbook(), Pt::{X::integer(),Y::integer()}) -> {integer(),Flags::integer()} +%% @spec (This::wxToolbook(), Pt::{X::integer(), Y::integer()}) -> {integer(), Flags::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtoolbook.html#wxtoolbookhittest">external documentation</a>. hitTest(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) when is_integer(PtX),is_integer(PtY) -> @@ -286,7 +286,7 @@ setImageList(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ImageListT,ref=ImageLi wxe_util:cast(?wxToolbook_SetImageList, <<ThisRef:32/?UI,ImageListRef:32/?UI>>). -%% @spec (This::wxToolbook(), Size::{W::integer(),H::integer()}) -> ok +%% @spec (This::wxToolbook(), Size::{W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtoolbook.html#wxtoolbooksetpagesize">external documentation</a>. setPageSize(#wx_ref{type=ThisT,ref=ThisRef},{SizeW,SizeH}) when is_integer(SizeW),is_integer(SizeH) -> diff --git a/lib/wx/src/gen/wxTreeCtrl.erl b/lib/wx/src/gen/wxTreeCtrl.erl index e3fe4c9612..77705ec76e 100644 --- a/lib/wx/src/gen/wxTreeCtrl.erl +++ b/lib/wx/src/gen/wxTreeCtrl.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -108,7 +108,7 @@ new(Parent) new(Parent, []). %% @spec (Parent::wxWindow:wxWindow(), [Option]) -> wxTreeCtrl() -%% Option = {id, integer()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {id, integer()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlwxtreectrl">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef}, Options) when is_list(Options) -> @@ -204,7 +204,7 @@ create(This,Parent) create(This,Parent, []). %% @spec (This::wxTreeCtrl(), Parent::wxWindow:wxWindow(), [Option]) -> bool() -%% Option = {id, integer()} | {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} | {validator, wx:wx()} +%% Option = {id, integer()} | {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} | {validator, wx:wx()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlcreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef}, Options) when is_list(Options) -> @@ -267,13 +267,13 @@ expand(#wx_ref{type=ThisT,ref=ThisRef},Item) wxe_util:cast(?wxTreeCtrl_Expand, <<ThisRef:32/?UI,0:32,Item:64/?UI>>). -%% @spec (This::wxTreeCtrl(), Item::integer(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}) -> bool() +%% @spec (This::wxTreeCtrl(), Item::integer(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}) -> bool() %% @equiv getBoundingRect(This,Item,Rect, []) getBoundingRect(This,Item,Rect={RectX,RectY,RectW,RectH}) when is_record(This, wx_ref),is_integer(Item),is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH) -> getBoundingRect(This,Item,Rect, []). -%% @spec (This::wxTreeCtrl(), Item::integer(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}, [Option]) -> bool() +%% @spec (This::wxTreeCtrl(), Item::integer(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}, [Option]) -> bool() %% Option = {textOnly, bool()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetboundingrect">external documentation</a>. getBoundingRect(#wx_ref{type=ThisT,ref=ThisRef},Item,{RectX,RectY,RectW,RectH}, Options) @@ -317,7 +317,7 @@ getEditControl(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxTreeCtrl_GetEditControl, <<ThisRef:32/?UI>>). -%% @spec (This::wxTreeCtrl(), Item::integer()) -> {integer(),Cookie::integer()} +%% @spec (This::wxTreeCtrl(), Item::integer()) -> {integer(), Cookie::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetfirstchild">external documentation</a>. getFirstChild(#wx_ref{type=ThisT,ref=ThisRef},Item) when is_integer(Item) -> @@ -325,7 +325,7 @@ getFirstChild(#wx_ref{type=ThisT,ref=ThisRef},Item) wxe_util:call(?wxTreeCtrl_GetFirstChild, <<ThisRef:32/?UI,0:32,Item:64/?UI>>). -%% @spec (This::wxTreeCtrl(), Item::integer(), Cookie::integer()) -> {integer(),Cookie::integer()} +%% @spec (This::wxTreeCtrl(), Item::integer(), Cookie::integer()) -> {integer(), Cookie::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetnextchild">external documentation</a>. getNextChild(#wx_ref{type=ThisT,ref=ThisRef},Item,Cookie) when is_integer(Item),is_integer(Cookie) -> @@ -478,7 +478,7 @@ getSelection(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxTreeCtrl_GetSelection, <<ThisRef:32/?UI>>). -%% @spec (This::wxTreeCtrl()) -> {integer(),Val::[integer()]} +%% @spec (This::wxTreeCtrl()) -> {integer(), Val::[integer()]} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlgetselections">external documentation</a>. getSelections(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxTreeCtrl), @@ -492,7 +492,7 @@ getStateImageList(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxTreeCtrl_GetStateImageList, <<ThisRef:32/?UI>>). -%% @spec (This::wxTreeCtrl(), Point::{X::integer(),Y::integer()}) -> integer() +%% @spec (This::wxTreeCtrl(), Point::{X::integer(), Y::integer()}) -> integer() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreectrl.html#wxtreectrlhittest">external documentation</a>. hitTest(#wx_ref{type=ThisT,ref=ThisRef},{PointX,PointY}) when is_integer(PointX),is_integer(PointY) -> diff --git a/lib/wx/src/gen/wxTreeEvent.erl b/lib/wx/src/gen/wxTreeEvent.erl index d5379b7abe..0264d43568 100644 --- a/lib/wx/src/gen/wxTreeEvent.erl +++ b/lib/wx/src/gen/wxTreeEvent.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -83,7 +83,7 @@ getOldItem(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxTreeEvent_GetOldItem, <<ThisRef:32/?UI>>). -%% @spec (This::wxTreeEvent()) -> {X::integer(),Y::integer()} +%% @spec (This::wxTreeEvent()) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreeevent.html#wxtreeeventgetpoint">external documentation</a>. getPoint(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxTreeEvent), diff --git a/lib/wx/src/gen/wxTreebook.erl b/lib/wx/src/gen/wxTreebook.erl index a515ec9639..24f5d72c43 100644 --- a/lib/wx/src/gen/wxTreebook.erl +++ b/lib/wx/src/gen/wxTreebook.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2009-2010. All Rights Reserved. +%% Copyright Ericsson AB 2009-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -94,7 +94,7 @@ new(Parent,Id) new(Parent,Id, []). %% @spec (Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> wxTreebook() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreebook.html#wxtreebookwxtreebook">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> @@ -161,7 +161,7 @@ create(This,Parent,Id) create(This,Parent,Id, []). %% @spec (This::wxTreebook(), Parent::wxWindow:wxWindow(), Id::integer(), [Option]) -> bool() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreebook.html#wxtreebookcreate">external documentation</a>. create(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> @@ -276,7 +276,7 @@ isNodeExpanded(#wx_ref{type=ThisT,ref=ThisRef},Pos) wxe_util:call(?wxTreebook_IsNodeExpanded, <<ThisRef:32/?UI,Pos:32/?UI>>). -%% @spec (This::wxTreebook(), Pt::{X::integer(),Y::integer()}) -> {integer(),Flags::integer()} +%% @spec (This::wxTreebook(), Pt::{X::integer(), Y::integer()}) -> {integer(), Flags::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreebook.html#wxtreebookhittest">external documentation</a>. hitTest(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) when is_integer(PtX),is_integer(PtY) -> @@ -334,7 +334,7 @@ setImageList(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=ImageListT,ref=ImageLi wxe_util:cast(?wxTreebook_SetImageList, <<ThisRef:32/?UI,ImageListRef:32/?UI>>). -%% @spec (This::wxTreebook(), Size::{W::integer(),H::integer()}) -> ok +%% @spec (This::wxTreebook(), Size::{W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxtreebook.html#wxtreebooksetpagesize">external documentation</a>. setPageSize(#wx_ref{type=ThisT,ref=ThisRef},{SizeW,SizeH}) when is_integer(SizeW),is_integer(SizeH) -> diff --git a/lib/wx/src/gen/wxWindow.erl b/lib/wx/src/gen/wxWindow.erl index 031314bfe2..6b57cf508e 100644 --- a/lib/wx/src/gen/wxWindow.erl +++ b/lib/wx/src/gen/wxWindow.erl @@ -86,7 +86,7 @@ new(Parent,Id) new(Parent,Id, []). %% @spec (Parent::wxWindow(), Id::integer(), [Option]) -> wxWindow() -%% Option = {pos, {X::integer(),Y::integer()}} | {size, {W::integer(),H::integer()}} | {style, integer()} +%% Option = {pos, {X::integer(), Y::integer()}} | {size, {W::integer(), H::integer()}} | {style, integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowwxwindow">external documentation</a>. new(#wx_ref{type=ParentT,ref=ParentRef},Id, Options) when is_integer(Id),is_list(Options) -> @@ -99,7 +99,7 @@ new(#wx_ref{type=ParentT,ref=ParentRef},Id, Options) wxe_util:construct(?wxWindow_new_3, <<ParentRef:32/?UI,Id:32/?UI, BinOpt/binary>>). -%% @spec (This::wxWindow(), Size::{W::integer(),H::integer()}) -> ok +%% @spec (This::wxWindow(), Size::{W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowcachebestsize">external documentation</a>. cacheBestSize(#wx_ref{type=ThisT,ref=ThisRef},{SizeW,SizeH}) when is_integer(SizeW),is_integer(SizeH) -> @@ -193,7 +193,7 @@ clearBackground(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:cast(?wxWindow_ClearBackground, <<ThisRef:32/?UI>>). -%% @spec (This::wxWindow(), Pt::{X::integer(),Y::integer()}) -> {X::integer(),Y::integer()} +%% @spec (This::wxWindow(), Pt::{X::integer(), Y::integer()}) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowclienttoscreen">external documentation</a>. clientToScreen(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) when is_integer(PtX),is_integer(PtY) -> @@ -201,7 +201,7 @@ clientToScreen(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) wxe_util:call(?wxWindow_ClientToScreen_1, <<ThisRef:32/?UI,PtX:32/?UI,PtY:32/?UI>>). -%% @spec (This::wxWindow(), X::integer(), Y::integer()) -> {X::integer(),Y::integer()} +%% @spec (This::wxWindow(), X::integer(), Y::integer()) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowclienttoscreen">external documentation</a>. clientToScreen(#wx_ref{type=ThisT,ref=ThisRef},X,Y) when is_integer(X),is_integer(Y) -> @@ -227,7 +227,7 @@ close(#wx_ref{type=ThisT,ref=ThisRef}, Options) wxe_util:call(?wxWindow_Close, <<ThisRef:32/?UI, 0:32,BinOpt/binary>>). -%% @spec (This::wxWindow(), Sz::{W::integer(),H::integer()}) -> {W::integer(),H::integer()} +%% @spec (This::wxWindow(), Sz::{W::integer(), H::integer()}) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowconvertdialogtopixels">external documentation</a>. convertDialogToPixels(#wx_ref{type=ThisT,ref=ThisRef},{SzW,SzH}) when is_integer(SzW),is_integer(SzH) -> @@ -235,7 +235,7 @@ convertDialogToPixels(#wx_ref{type=ThisT,ref=ThisRef},{SzW,SzH}) wxe_util:call(?wxWindow_ConvertDialogToPixels, <<ThisRef:32/?UI,SzW:32/?UI,SzH:32/?UI>>). -%% @spec (This::wxWindow(), Sz::{W::integer(),H::integer()}) -> {W::integer(),H::integer()} +%% @spec (This::wxWindow(), Sz::{W::integer(), H::integer()}) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowconvertpixelstodialog">external documentation</a>. convertPixelsToDialog(#wx_ref{type=ThisT,ref=ThisRef},{SzW,SzH}) when is_integer(SzW),is_integer(SzH) -> @@ -406,7 +406,7 @@ getBackgroundStyle(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxWindow_GetBackgroundStyle, <<ThisRef:32/?UI>>). -%% @spec (This::wxWindow()) -> {W::integer(),H::integer()} +%% @spec (This::wxWindow()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowgetbestsize">external documentation</a>. getBestSize(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxWindow), @@ -447,7 +447,7 @@ getChildren(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxWindow_GetChildren, <<ThisRef:32/?UI>>). -%% @spec (This::wxWindow()) -> {W::integer(),H::integer()} +%% @spec (This::wxWindow()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowgetclientsize">external documentation</a>. getClientSize(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxWindow), @@ -538,14 +538,14 @@ getLabel(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxWindow_GetLabel, <<ThisRef:32/?UI>>). -%% @spec (This::wxWindow()) -> {W::integer(),H::integer()} +%% @spec (This::wxWindow()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowgetmaxsize">external documentation</a>. getMaxSize(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxWindow), wxe_util:call(?wxWindow_GetMaxSize, <<ThisRef:32/?UI>>). -%% @spec (This::wxWindow()) -> {W::integer(),H::integer()} +%% @spec (This::wxWindow()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowgetminsize">external documentation</a>. getMinSize(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxWindow), @@ -566,28 +566,28 @@ getParent(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxWindow_GetParent, <<ThisRef:32/?UI>>). -%% @spec (This::wxWindow()) -> {X::integer(),Y::integer()} +%% @spec (This::wxWindow()) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowgetposition">external documentation</a>. getPosition(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxWindow), wxe_util:call(?wxWindow_GetPosition, <<ThisRef:32/?UI>>). -%% @spec (This::wxWindow()) -> {X::integer(),Y::integer(),W::integer(),H::integer()} +%% @spec (This::wxWindow()) -> {X::integer(), Y::integer(), W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowgetrect">external documentation</a>. getRect(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxWindow), wxe_util:call(?wxWindow_GetRect, <<ThisRef:32/?UI>>). -%% @spec (This::wxWindow()) -> {X::integer(),Y::integer()} +%% @spec (This::wxWindow()) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowgetscreenposition">external documentation</a>. getScreenPosition(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxWindow), wxe_util:call(?wxWindow_GetScreenPosition, <<ThisRef:32/?UI>>). -%% @spec (This::wxWindow()) -> {X::integer(),Y::integer(),W::integer(),H::integer()} +%% @spec (This::wxWindow()) -> {X::integer(), Y::integer(), W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowgetscreenrect">external documentation</a>. getScreenRect(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxWindow), @@ -618,7 +618,7 @@ getScrollThumb(#wx_ref{type=ThisT,ref=ThisRef},Orient) wxe_util:call(?wxWindow_GetScrollThumb, <<ThisRef:32/?UI,Orient:32/?UI>>). -%% @spec (This::wxWindow()) -> {W::integer(),H::integer()} +%% @spec (This::wxWindow()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowgetsize">external documentation</a>. getSize(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxWindow), @@ -632,13 +632,13 @@ getSizer(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxWindow_GetSizer, <<ThisRef:32/?UI>>). -%% @spec (This::wxWindow(), String::string()) -> {X::integer(),Y::integer(),Descent::integer(),ExternalLeading::integer()} +%% @spec (This::wxWindow(), String::string()) -> {X::integer(), Y::integer(), Descent::integer(), ExternalLeading::integer()} %% @equiv getTextExtent(This,String, []) getTextExtent(This,String) when is_record(This, wx_ref),is_list(String) -> getTextExtent(This,String, []). -%% @spec (This::wxWindow(), String::string(), [Option]) -> {X::integer(),Y::integer(),Descent::integer(),ExternalLeading::integer()} +%% @spec (This::wxWindow(), String::string(), [Option]) -> {X::integer(), Y::integer(), Descent::integer(), ExternalLeading::integer()} %% Option = {theFont, wxFont:wxFont()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowgettextextent">external documentation</a>. getTextExtent(#wx_ref{type=ThisT,ref=ThisRef},String, Options) @@ -665,7 +665,7 @@ getUpdateRegion(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxWindow_GetUpdateRegion, <<ThisRef:32/?UI>>). -%% @spec (This::wxWindow()) -> {W::integer(),H::integer()} +%% @spec (This::wxWindow()) -> {W::integer(), H::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowgetvirtualsize">external documentation</a>. getVirtualSize(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxWindow), @@ -749,10 +749,10 @@ isEnabled(#wx_ref{type=ThisT,ref=ThisRef}) -> %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowisexposed">external documentation</a>. %% <br /> Alternatives: %% <p><c> -%% isExposed(This::wxWindow(), Pt::{X::integer(),Y::integer()}) -> bool() </c> +%% isExposed(This::wxWindow(), Pt::{X::integer(), Y::integer()}) -> bool() </c> %% </p> %% <p><c> -%% isExposed(This::wxWindow(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}) -> bool() </c> +%% isExposed(This::wxWindow(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}) -> bool() </c> %% </p> isExposed(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) when is_integer(PtX),is_integer(PtY) -> @@ -848,7 +848,7 @@ makeModal(#wx_ref{type=ThisT,ref=ThisRef}, Options) wxe_util:cast(?wxWindow_MakeModal, <<ThisRef:32/?UI, 0:32,BinOpt/binary>>). -%% @spec (This::wxWindow(), Pt::{X::integer(),Y::integer()}) -> ok +%% @spec (This::wxWindow(), Pt::{X::integer(), Y::integer()}) -> ok %% @equiv move(This,Pt, []) move(This,Pt={PtX,PtY}) when is_record(This, wx_ref),is_integer(PtX),is_integer(PtY) -> @@ -860,7 +860,7 @@ move(This,Pt={PtX,PtY}) %% <p><c> %% move(This::wxWindow(), X::integer(), Y::integer()) -> move(This,X,Y, []) </c></p> %% <p><c> -%% move(This::wxWindow(), Pt::{X::integer(),Y::integer()}, [Option]) -> ok </c> +%% move(This::wxWindow(), Pt::{X::integer(), Y::integer()}, [Option]) -> ok </c> %%<br /> Option = {flags, integer()} %% </p> @@ -961,7 +961,7 @@ popupMenu(This,Menu) popupMenu(This,Menu, []). %% @spec (This::wxWindow(), Menu::wxMenu:wxMenu(), [Option]) -> bool() -%% Option = {pos, {X::integer(),Y::integer()}} +%% Option = {pos, {X::integer(), Y::integer()}} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowpopupmenu">external documentation</a>. popupMenu(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=MenuT,ref=MenuRef}, Options) when is_list(Options) -> @@ -996,7 +996,7 @@ refresh(This) refresh(This, []). %% @spec (This::wxWindow(), [Option]) -> ok -%% Option = {eraseBackground, bool()} | {rect, {X::integer(),Y::integer(),W::integer(),H::integer()}} +%% Option = {eraseBackground, bool()} | {rect, {X::integer(), Y::integer(), W::integer(), H::integer()}} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowrefresh">external documentation</a>. refresh(#wx_ref{type=ThisT,ref=ThisRef}, Options) when is_list(Options) -> @@ -1008,13 +1008,13 @@ refresh(#wx_ref{type=ThisT,ref=ThisRef}, Options) wxe_util:cast(?wxWindow_Refresh, <<ThisRef:32/?UI, 0:32,BinOpt/binary>>). -%% @spec (This::wxWindow(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}) -> ok +%% @spec (This::wxWindow(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}) -> ok %% @equiv refreshRect(This,Rect, []) refreshRect(This,Rect={RectX,RectY,RectW,RectH}) when is_record(This, wx_ref),is_integer(RectX),is_integer(RectY),is_integer(RectW),is_integer(RectH) -> refreshRect(This,Rect, []). -%% @spec (This::wxWindow(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}, [Option]) -> ok +%% @spec (This::wxWindow(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}, [Option]) -> ok %% Option = {eraseBackground, bool()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowrefreshrect">external documentation</a>. refreshRect(#wx_ref{type=ThisT,ref=ThisRef},{RectX,RectY,RectW,RectH}, Options) @@ -1049,14 +1049,14 @@ reparent(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=NewParentT,ref=NewParentRe wxe_util:call(?wxWindow_Reparent, <<ThisRef:32/?UI,NewParentRef:32/?UI>>). -%% @spec (This::wxWindow()) -> {X::integer(),Y::integer()} +%% @spec (This::wxWindow()) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowscreentoclient">external documentation</a>. screenToClient(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxWindow), wxe_util:call(?wxWindow_ScreenToClient_2, <<ThisRef:32/?UI>>). -%% @spec (This::wxWindow(), Pt::{X::integer(),Y::integer()}) -> {X::integer(),Y::integer()} +%% @spec (This::wxWindow(), Pt::{X::integer(), Y::integer()}) -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowscreentoclient">external documentation</a>. screenToClient(#wx_ref{type=ThisT,ref=ThisRef},{PtX,PtY}) when is_integer(PtX),is_integer(PtY) -> @@ -1087,7 +1087,7 @@ scrollWindow(This,Dx,Dy) scrollWindow(This,Dx,Dy, []). %% @spec (This::wxWindow(), Dx::integer(), Dy::integer(), [Option]) -> ok -%% Option = {rect, {X::integer(),Y::integer(),W::integer(),H::integer()}} +%% Option = {rect, {X::integer(), Y::integer(), W::integer(), H::integer()}} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowscrollwindow">external documentation</a>. scrollWindow(#wx_ref{type=ThisT,ref=ThisRef},Dx,Dy, Options) when is_integer(Dx),is_integer(Dy),is_list(Options) -> @@ -1184,7 +1184,7 @@ setCursor(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=CursorT,ref=CursorRef}) - wxe_util:call(?wxWindow_SetCursor, <<ThisRef:32/?UI,CursorRef:32/?UI>>). -%% @spec (This::wxWindow(), MaxSize::{W::integer(),H::integer()}) -> ok +%% @spec (This::wxWindow(), MaxSize::{W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowsetmaxsize">external documentation</a>. setMaxSize(#wx_ref{type=ThisT,ref=ThisRef},{MaxSizeW,MaxSizeH}) when is_integer(MaxSizeW),is_integer(MaxSizeH) -> @@ -1192,7 +1192,7 @@ setMaxSize(#wx_ref{type=ThisT,ref=ThisRef},{MaxSizeW,MaxSizeH}) wxe_util:cast(?wxWindow_SetMaxSize, <<ThisRef:32/?UI,MaxSizeW:32/?UI,MaxSizeH:32/?UI>>). -%% @spec (This::wxWindow(), MinSize::{W::integer(),H::integer()}) -> ok +%% @spec (This::wxWindow(), MinSize::{W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowsetminsize">external documentation</a>. setMinSize(#wx_ref{type=ThisT,ref=ThisRef},{MinSizeW,MinSizeH}) when is_integer(MinSizeW),is_integer(MinSizeH) -> @@ -1353,9 +1353,9 @@ setScrollPos(#wx_ref{type=ThisT,ref=ThisRef},Orient,Pos, Options) %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowsetsize">external documentation</a>. %% <br /> Alternatives: %% <p><c> -%% setSize(This::wxWindow(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}) -> setSize(This,Rect, []) </c></p> +%% setSize(This::wxWindow(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}) -> setSize(This,Rect, []) </c></p> %% <p><c> -%% setSize(This::wxWindow(), Size::{W::integer(),H::integer()}) -> ok </c> +%% setSize(This::wxWindow(), Size::{W::integer(), H::integer()}) -> ok </c> %% </p> setSize(This,Rect={RectX,RectY,RectW,RectH}) @@ -1374,7 +1374,7 @@ setSize(#wx_ref{type=ThisT,ref=ThisRef},{SizeW,SizeH}) %% setSize(This::wxWindow(), Width::integer(), Height::integer()) -> ok </c> %% </p> %% <p><c> -%% setSize(This::wxWindow(), Rect::{X::integer(),Y::integer(),W::integer(),H::integer()}, [Option]) -> ok </c> +%% setSize(This::wxWindow(), Rect::{X::integer(), Y::integer(), W::integer(), H::integer()}, [Option]) -> ok </c> %%<br /> Option = {sizeFlags, integer()} %% </p> setSize(#wx_ref{type=ThisT,ref=ThisRef},Width,Height) @@ -1409,7 +1409,7 @@ setSize(#wx_ref{type=ThisT,ref=ThisRef},X,Y,Width,Height, Options) wxe_util:cast(?wxWindow_SetSize_5, <<ThisRef:32/?UI,X:32/?UI,Y:32/?UI,Width:32/?UI,Height:32/?UI, 0:32,BinOpt/binary>>). -%% @spec (This::wxWindow(), MinSize::{W::integer(),H::integer()}) -> ok +%% @spec (This::wxWindow(), MinSize::{W::integer(), H::integer()}) -> ok %% @equiv setSizeHints(This,MinSize, []) setSizeHints(This,MinSize={MinSizeW,MinSizeH}) when is_record(This, wx_ref),is_integer(MinSizeW),is_integer(MinSizeH) -> @@ -1421,8 +1421,8 @@ setSizeHints(This,MinSize={MinSizeW,MinSizeH}) %% <p><c> %% setSizeHints(This::wxWindow(), MinW::integer(), MinH::integer()) -> setSizeHints(This,MinW,MinH, []) </c></p> %% <p><c> -%% setSizeHints(This::wxWindow(), MinSize::{W::integer(),H::integer()}, [Option]) -> ok </c> -%%<br /> Option = {maxSize, {W::integer(),H::integer()}} | {incSize, {W::integer(),H::integer()}} +%% setSizeHints(This::wxWindow(), MinSize::{W::integer(), H::integer()}, [Option]) -> ok </c> +%%<br /> Option = {maxSize, {W::integer(), H::integer()}} | {incSize, {W::integer(), H::integer()}} %% </p> setSizeHints(This,MinW,MinH) @@ -1520,7 +1520,7 @@ setToolTip(#wx_ref{type=ThisT,ref=ThisRef},#wx_ref{type=TipT,ref=TipRef}) -> wxe_util:cast(?wxWindow_SetToolTip_1_1, <<ThisRef:32/?UI,TipRef:32/?UI>>). -%% @spec (This::wxWindow(), Size::{W::integer(),H::integer()}) -> ok +%% @spec (This::wxWindow(), Size::{W::integer(), H::integer()}) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindowsetvirtualsize">external documentation</a>. setVirtualSize(#wx_ref{type=ThisT,ref=ThisRef},{SizeW,SizeH}) when is_integer(SizeW),is_integer(SizeH) -> @@ -1536,7 +1536,7 @@ setVirtualSize(#wx_ref{type=ThisT,ref=ThisRef},X,Y) wxe_util:cast(?wxWindow_SetVirtualSize_2, <<ThisRef:32/?UI,X:32/?UI,Y:32/?UI>>). -%% @spec (This::wxWindow(), MinSize::{W::integer(),H::integer()}) -> ok +%% @spec (This::wxWindow(), MinSize::{W::integer(), H::integer()}) -> ok %% @equiv setVirtualSizeHints(This,MinSize, []) setVirtualSizeHints(This,MinSize={MinSizeW,MinSizeH}) when is_record(This, wx_ref),is_integer(MinSizeW),is_integer(MinSizeH) -> @@ -1548,8 +1548,8 @@ setVirtualSizeHints(This,MinSize={MinSizeW,MinSizeH}) %% <p><c> %% setVirtualSizeHints(This::wxWindow(), MinW::integer(), MinH::integer()) -> setVirtualSizeHints(This,MinW,MinH, []) </c></p> %% <p><c> -%% setVirtualSizeHints(This::wxWindow(), MinSize::{W::integer(),H::integer()}, [Option]) -> ok </c> -%%<br /> Option = {maxSize, {W::integer(),H::integer()}} +%% setVirtualSizeHints(This::wxWindow(), MinSize::{W::integer(), H::integer()}, [Option]) -> ok </c> +%%<br /> Option = {maxSize, {W::integer(), H::integer()}} %% </p> setVirtualSizeHints(This,MinW,MinH) diff --git a/lib/wx/src/gen/wx_misc.erl b/lib/wx/src/gen/wx_misc.erl index cf23d4cf8b..3382d898e4 100644 --- a/lib/wx/src/gen/wx_misc.erl +++ b/lib/wx/src/gen/wx_misc.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -39,7 +39,7 @@ getKeyState(Key) wxe_util:call(?utils_wxGetKeyState, <<Key:32/?UI>>). -%% @spec () -> {X::integer(),Y::integer()} +%% @spec () -> {X::integer(), Y::integer()} %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_miscellany.html#wxgetmouseposition">external documentation</a>. getMousePosition() -> wxe_util:call(?utils_wxGetMousePosition, @@ -74,14 +74,14 @@ findMenuItemId(#wx_ref{type=FrameT,ref=FrameRef},MenuString,ItemString) wxe_util:call(?utils_wxFindMenuItemId, <<FrameRef:32/?UI,(byte_size(MenuString_UC)):32/?UI,(MenuString_UC)/binary, 0:(((8- ((0+byte_size(MenuString_UC)) band 16#7)) band 16#7))/unit:8,(byte_size(ItemString_UC)):32/?UI,(ItemString_UC)/binary, 0:(((8- ((4+byte_size(ItemString_UC)) band 16#7)) band 16#7))/unit:8>>). -%% @spec (Pt::{X::integer(),Y::integer()}) -> wxWindow:wxWindow() +%% @spec (Pt::{X::integer(), Y::integer()}) -> wxWindow:wxWindow() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_miscellany.html#wxgenericfindwindowatpoint">external documentation</a>. genericFindWindowAtPoint({PtX,PtY}) when is_integer(PtX),is_integer(PtY) -> wxe_util:call(?utils_wxGenericFindWindowAtPoint, <<PtX:32/?UI,PtY:32/?UI>>). -%% @spec (Pt::{X::integer(),Y::integer()}) -> wxWindow:wxWindow() +%% @spec (Pt::{X::integer(), Y::integer()}) -> wxWindow:wxWindow() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_miscellany.html#wxfindwindowatpoint">external documentation</a>. findWindowAtPoint({PtX,PtY}) when is_integer(PtX),is_integer(PtY) -> diff --git a/lib/wx/src/gen/wxe_debug.hrl b/lib/wx/src/gen/wxe_debug.hrl index 960f67a1f6..4224c54200 100644 --- a/lib/wx/src/gen/wxe_debug.hrl +++ b/lib/wx/src/gen/wxe_debug.hrl @@ -3273,26 +3273,32 @@ wxdebug_table() -> {3489, {wxSystemSettings, getFont, 1}}, {3490, {wxSystemSettings, getMetric, 2}}, {3491, {wxSystemSettings, getScreenType, 0}}, - {3492, {wxAuiNotebookEvent, setSelection, 1}}, - {3493, {wxAuiNotebookEvent, getSelection, 0}}, - {3494, {wxAuiNotebookEvent, setOldSelection, 1}}, - {3495, {wxAuiNotebookEvent, getOldSelection, 0}}, - {3496, {wxAuiNotebookEvent, setDragSource, 1}}, - {3497, {wxAuiNotebookEvent, getDragSource, 0}}, - {3498, {wxAuiManagerEvent, setManager, 1}}, - {3499, {wxAuiManagerEvent, getManager, 0}}, - {3500, {wxAuiManagerEvent, setPane, 1}}, - {3501, {wxAuiManagerEvent, getPane, 0}}, - {3502, {wxAuiManagerEvent, setButton, 1}}, - {3503, {wxAuiManagerEvent, getButton, 0}}, - {3504, {wxAuiManagerEvent, setDC, 1}}, - {3505, {wxAuiManagerEvent, getDC, 0}}, - {3506, {wxAuiManagerEvent, veto, 1}}, - {3507, {wxAuiManagerEvent, getVeto, 0}}, - {3508, {wxAuiManagerEvent, setCanVeto, 1}}, - {3509, {wxAuiManagerEvent, canVeto, 0}}, - {3510, {wxLogNull, new, 0}}, - {3511, {wxLogNull, 'Destroy', undefined}}, + {3492, {wxSystemOptions, getOption, 1}}, + {3493, {wxSystemOptions, getOptionInt, 1}}, + {3494, {wxSystemOptions, hasOption, 1}}, + {3495, {wxSystemOptions, isFalse, 1}}, + {3496, {wxSystemOptions, setOption_2_1, 2}}, + {3497, {wxSystemOptions, setOption_2_0, 2}}, + {3498, {wxAuiNotebookEvent, setSelection, 1}}, + {3499, {wxAuiNotebookEvent, getSelection, 0}}, + {3500, {wxAuiNotebookEvent, setOldSelection, 1}}, + {3501, {wxAuiNotebookEvent, getOldSelection, 0}}, + {3502, {wxAuiNotebookEvent, setDragSource, 1}}, + {3503, {wxAuiNotebookEvent, getDragSource, 0}}, + {3504, {wxAuiManagerEvent, setManager, 1}}, + {3505, {wxAuiManagerEvent, getManager, 0}}, + {3506, {wxAuiManagerEvent, setPane, 1}}, + {3507, {wxAuiManagerEvent, getPane, 0}}, + {3508, {wxAuiManagerEvent, setButton, 1}}, + {3509, {wxAuiManagerEvent, getButton, 0}}, + {3510, {wxAuiManagerEvent, setDC, 1}}, + {3511, {wxAuiManagerEvent, getDC, 0}}, + {3512, {wxAuiManagerEvent, veto, 1}}, + {3513, {wxAuiManagerEvent, getVeto, 0}}, + {3514, {wxAuiManagerEvent, setCanVeto, 1}}, + {3515, {wxAuiManagerEvent, canVeto, 0}}, + {3516, {wxLogNull, new, 0}}, + {3517, {wxLogNull, 'Destroy', undefined}}, {-1, {mod, func, -1}} ]. diff --git a/lib/wx/src/gen/wxe_funcs.hrl b/lib/wx/src/gen/wxe_funcs.hrl index af74caaa25..55cbee5572 100644 --- a/lib/wx/src/gen/wxe_funcs.hrl +++ b/lib/wx/src/gen/wxe_funcs.hrl @@ -3270,23 +3270,29 @@ -define(wxSystemSettings_GetFont, 3489). -define(wxSystemSettings_GetMetric, 3490). -define(wxSystemSettings_GetScreenType, 3491). --define(wxAuiNotebookEvent_SetSelection, 3492). --define(wxAuiNotebookEvent_GetSelection, 3493). --define(wxAuiNotebookEvent_SetOldSelection, 3494). --define(wxAuiNotebookEvent_GetOldSelection, 3495). --define(wxAuiNotebookEvent_SetDragSource, 3496). --define(wxAuiNotebookEvent_GetDragSource, 3497). --define(wxAuiManagerEvent_SetManager, 3498). --define(wxAuiManagerEvent_GetManager, 3499). --define(wxAuiManagerEvent_SetPane, 3500). --define(wxAuiManagerEvent_GetPane, 3501). --define(wxAuiManagerEvent_SetButton, 3502). --define(wxAuiManagerEvent_GetButton, 3503). --define(wxAuiManagerEvent_SetDC, 3504). --define(wxAuiManagerEvent_GetDC, 3505). --define(wxAuiManagerEvent_Veto, 3506). --define(wxAuiManagerEvent_GetVeto, 3507). --define(wxAuiManagerEvent_SetCanVeto, 3508). --define(wxAuiManagerEvent_CanVeto, 3509). --define(wxLogNull_new, 3510). --define(wxLogNull_destroy, 3511). +-define(wxSystemOptions_GetOption, 3492). +-define(wxSystemOptions_GetOptionInt, 3493). +-define(wxSystemOptions_HasOption, 3494). +-define(wxSystemOptions_IsFalse, 3495). +-define(wxSystemOptions_SetOption_2_1, 3496). +-define(wxSystemOptions_SetOption_2_0, 3497). +-define(wxAuiNotebookEvent_SetSelection, 3498). +-define(wxAuiNotebookEvent_GetSelection, 3499). +-define(wxAuiNotebookEvent_SetOldSelection, 3500). +-define(wxAuiNotebookEvent_GetOldSelection, 3501). +-define(wxAuiNotebookEvent_SetDragSource, 3502). +-define(wxAuiNotebookEvent_GetDragSource, 3503). +-define(wxAuiManagerEvent_SetManager, 3504). +-define(wxAuiManagerEvent_GetManager, 3505). +-define(wxAuiManagerEvent_SetPane, 3506). +-define(wxAuiManagerEvent_GetPane, 3507). +-define(wxAuiManagerEvent_SetButton, 3508). +-define(wxAuiManagerEvent_GetButton, 3509). +-define(wxAuiManagerEvent_SetDC, 3510). +-define(wxAuiManagerEvent_GetDC, 3511). +-define(wxAuiManagerEvent_Veto, 3512). +-define(wxAuiManagerEvent_GetVeto, 3513). +-define(wxAuiManagerEvent_SetCanVeto, 3514). +-define(wxAuiManagerEvent_CanVeto, 3515). +-define(wxLogNull_new, 3516). +-define(wxLogNull_destroy, 3517). diff --git a/lib/wx/src/wx_object.erl b/lib/wx/src/wx_object.erl index 82c4cfbad5..bc85cd93d4 100644 --- a/lib/wx/src/wx_object.erl +++ b/lib/wx/src/wx_object.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -226,9 +226,11 @@ call(Name, Request, Timeout) when is_atom(Name) orelse is_pid(Name) -> %% Invokes handle_cast(Request, State) in the server cast(#wx_ref{state=Pid}, Request) when is_pid(Pid) -> - Pid ! {'$gen_cast',Request}; + Pid ! {'$gen_cast',Request}, + ok; cast(Name, Request) when is_atom(Name) orelse is_pid(Name) -> - Name ! {'$gen_cast',Request}. + Name ! {'$gen_cast',Request}, + ok. %% @spec (Ref::wxObject()) -> pid() %% @doc Get the pid of the object handle. @@ -258,9 +260,10 @@ init_it(Starter, self, Name, Mod, Args, Options) -> init_it(Starter, self(), Name, Mod, Args, Options); init_it(Starter, Parent, Name, Mod, Args, [WxEnv|Options]) -> case WxEnv of - undefined -> ok; + undefined -> ok; _ -> wx:set_env(WxEnv) end, + put('_wx_object_', {Mod,'_wx_init_'}), Debug = debug_options(Name, Options), case catch Mod:init(Args) of {#wx_ref{} = Ref, State} -> @@ -350,57 +353,16 @@ handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod) -> {noreply, NState, Time1} -> loop(Parent, Name, NState, Mod, Time1, []); {stop, Reason, Reply, NState} -> - {'EXIT', R} = + {'EXIT', R} = (catch terminate(Reason, Name, Msg, Mod, NState, [])), reply(From, Reply), exit(R); Other -> handle_common_reply(Other, Name, Msg, Mod, State, []) end; - -handle_msg(Msg = {_,_,'_wx_invoke_cb_'}, Parent, Name, State, Mod) -> - Reply = dispatch_cb(Msg, Mod, State), - handle_no_reply(Reply, Parent, Name, Msg, Mod, State, []); handle_msg(Msg, Parent, Name, State, Mod) -> Reply = (catch dispatch(Msg, Mod, State)), handle_no_reply(Reply, Parent, Name, Msg, Mod, State, []). -%% @hidden -dispatch_cb({{Msg=#wx{}, Obj=#wx_ref{}}, _, '_wx_invoke_cb_'}, Mod, State) -> - Callback = fun() -> - wxe_util:cast(?WXE_CB_START, <<>>), - case Mod:handle_sync_event(Msg, Obj, State) of - ok -> <<>>; - noreply -> <<>>; - Other -> - Args = [Msg, Obj, State], - MFA = {Mod, handle_sync_event, Args}, - exit({bad_return, Other, MFA}) - end - end, - wxe_server:invoke_callback(Callback), - {noreply, State}; -dispatch_cb({Func, ArgList, '_wx_invoke_cb_'}, Mod, State) -> - try %% This don't work yet.... - [#wx_ref{type=ThisClass}] = ArgList, - case Mod:handle_overloaded(Func, ArgList, State) of - {reply, CBReply, NState} -> - ThisClass:send_return_value(Func, CBReply), - {noreply, NState}; - {reply, CBReply, NState, Time1} -> - ThisClass:send_return_value(Func, CBReply), - {noreply, NState, Time1}; - {noreply, NState} -> - ThisClass:send_return_value(Func, <<>>), - {noreply, NState}; - {noreply, NState, Time1} -> - ThisClass:send_return_value(Func, <<>>), - {noreply, NState, Time1}; - Other -> Other - end - catch _Err:Reason -> - %% Hopefully we can release the wx-thread with this - wxe_util:cast(?WXE_CB_RETURN, <<>>), - {'EXIT', {Reason, erlang:get_stacktrace()}} - end. + %% @hidden handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod, Debug) -> case catch Mod:handle_call(Msg, From, State) of @@ -426,9 +388,6 @@ handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod, Debug) -> Other -> handle_common_reply(Other, Name, Msg, Mod, State, Debug) end; -handle_msg(Msg = {_,_,'_wx_invoke_cb_'}, Parent, Name, State, Mod, Debug) -> - Reply = dispatch_cb(Msg, Mod, State), - handle_no_reply(Reply, Parent, Name, Msg, Mod, State, Debug); handle_msg(Msg, Parent, Name, State, Mod, Debug) -> Reply = (catch dispatch(Msg, Mod, State)), handle_no_reply(Reply, Parent, Name, Msg, Mod, State, Debug). diff --git a/lib/wx/src/wxe_server.erl b/lib/wx/src/wxe_server.erl index 69e2189fac..6e982c97f6 100644 --- a/lib/wx/src/wxe_server.erl +++ b/lib/wx/src/wxe_server.erl @@ -221,7 +221,7 @@ handle_connect(Object, EvData, From, State0 = #state{users=Users}) -> Evs = [#event{object=Object,callback=Callback, cb_handler=CBHandler}|Evs0], User = User0#user{events=Evs, evt_handler=Handler}, State1 = State0#state{users=gb_trees:update(From, User, Users)}, - if is_function(Callback) -> + if is_function(Callback) orelse is_pid(Callback) -> {FunId, State} = attach_fun(Callback,State1), Res = wxEvtHandler:connect_impl(CBHandler,Object, wxEvtHandler:replace_fun_with_id(EvData,FunId)), @@ -229,6 +229,7 @@ handle_connect(Object, EvData, From, State0 = #state{users=Users}) -> ok -> {reply,Res,State}; _Error -> {reply,Res,State0} end; + true -> Res = {call_impl, connect_cb, CBHandler}, {reply, Res, State1} @@ -239,6 +240,8 @@ invoke_cb({{Ev=#wx{}, Ref=#wx_ref{}}, FunId,_}, _S) -> case get(FunId) of Fun when is_function(Fun) -> invoke_callback(fun() -> Fun(Ev, Ref), <<>> end); + Pid when is_pid(Pid) -> %% wx_object sync event + invoke_callback(Pid, Ev, Ref); Err -> ?log("Internal Error ~p~n",[Err]) end; @@ -270,6 +273,44 @@ invoke_callback(Fun) -> spawn(CB), ok. +invoke_callback(Pid, Ev, Ref) -> + Env = get(?WXE_IDENTIFIER), + CB = fun() -> + wx:set_env(Env), + wxe_util:cast(?WXE_CB_START, <<>>), + try + case get_wx_object_state(Pid) of + ignore -> + %% Ignore early events + wxEvent:skip(Ref); + {Mod, State} -> + case Mod:handle_sync_event(Ev, Ref, State) of + ok -> ok; + noreply -> ok; + Return -> exit({bad_return, Return}) + end + end + catch _:Reason -> + wxEvent:skip(Ref), + ?log("Callback fun crashed with {'EXIT, ~p, ~p}~n", + [Reason, erlang:get_stacktrace()]) + end, + wxe_util:cast(?WXE_CB_RETURN, <<>>) + end, + spawn(CB), + ok. + +get_wx_object_state(Pid) -> + case process_info(Pid, dictionary) of + {dictionary, Dict} -> + case lists:keysearch('_wx_object_',1,Dict) of + {value, {'_wx_object_', {_Mod, '_wx_init_'}}} -> ignore; + {value, {'_wx_object_', Value}} -> Value; + _ -> ignore + end; + _ -> ignore + end. + new_evt_listener(State) -> #wx_env{port=Port} = wx:get_env(), _ = erlang:port_control(Port,98,<<>>), diff --git a/lib/wx/test/Makefile b/lib/wx/test/Makefile index cf51d7918f..333711789f 100644 --- a/lib/wx/test/Makefile +++ b/lib/wx/test/Makefile @@ -27,7 +27,7 @@ PWD = $(shell pwd) APPDIR = $(shell dirname $(PWD)) ERL_COMPILE_FLAGS = -pa $(APPDIR)/ebin -Mods = wxt wx_test_lib \ +Mods = wxt wx_test_lib wx_obj_test \ wx_app_SUITE \ wx_basic_SUITE \ wx_event_SUITE \ diff --git a/lib/wx/test/wx_basic_SUITE.erl b/lib/wx/test/wx_basic_SUITE.erl index 9ad34248a9..46c72bb453 100644 --- a/lib/wx/test/wx_basic_SUITE.erl +++ b/lib/wx/test/wx_basic_SUITE.erl @@ -48,7 +48,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> [create_window, several_apps, wx_api, wx_misc, - data_types]. + data_types, wx_object]. groups() -> []. @@ -298,3 +298,77 @@ data_types(_Config) -> wxClientDC:destroy(CDC), %%wx_test_lib:wx_destroy(Frame,Config). wx:destroy(). + +wx_object(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo); +wx_object(Config) -> + wx:new(), + Frame = ?mt(wxFrame, wx_obj_test:start([])), + timer:sleep(500), + ?m(ok, check_events(flush())), + + Me = self(), + ?m({call, foobar, {Me, _}}, wx_object:call(Frame, foobar)), + ?m(ok, wx_object:cast(Frame, foobar2)), + ?m([{cast, foobar2}], flush()), + FramePid = wx_object:get_pid(Frame), + io:format("wx_object pid ~p~n",[FramePid]), + FramePid ! foo3, + ?m([{info, foo3}], flush()), + + ?m(ok, wx_object:cast(Frame, fun(_) -> hehe end)), + ?m([{cast, hehe}], flush()), + wxWindow:refresh(Frame), + ?m([{sync_event, #wx{event=#wxPaint{}}, _}], flush()), + ?m(ok, wx_object:cast(Frame, fun(_) -> timer:sleep(200), slept end)), + %% The sleep above should not hinder the Paint event below + %% Which it did in my buggy handling of the sync_callback + wxWindow:refresh(Frame), + ?m([{sync_event, #wx{event=#wxPaint{}}, _}], flush()), + ?m([{cast, slept}], flush()), + + Monitor = erlang:monitor(process, FramePid), + case proplists:get_value(user, Config, false) of + false -> + timer:sleep(100), + wxFrame:destroy(Frame); + true -> + timer:sleep(500), + ?m(ok, wxFrame:destroy(Frame)); + _ -> + ?m(ok, wxEvtHandler:connect(Frame, close_window, [{skip,true}])), + wx_test_lib:wait_for_close() + end, + ?m(ok, receive + {'DOWN', Monitor, _, _, _} -> + ?m([{terminate, wx_deleted}], flush()), + ok + after 1000 -> + Msgs = flush(), + io:format("Error ~p Alive ~p~n",[Msgs, is_process_alive(FramePid)]) + end), + catch wx:destroy(), + ok. + +check_events(Msgs) -> + check_events(Msgs, 0,0). + +check_events([{event, #wx{event=#wxSize{}}}|Rest], Async, Sync) -> + check_events(Rest, Async+1, Sync); +check_events([{sync_event, #wx{event=#wxPaint{}}, Obj}|Rest], Async, Sync) -> + ?mt(wxPaintEvent, Obj), + check_events(Rest, Async, Sync+1); +check_events([], Async, Sync) -> + case Async > 0 of %% Test sync explictly + true -> ok; + false -> {Async, Sync} + end. + +flush() -> + flush([], 500). + +flush(Acc, Wait) -> + receive + Msg -> flush([Msg|Acc], Wait div 10) + after Wait -> + lists:reverse(Acc) + end. diff --git a/lib/wx/test/wx_event_SUITE.erl b/lib/wx/test/wx_event_SUITE.erl index 0d8dd4852e..8f364049b4 100644 --- a/lib/wx/test/wx_event_SUITE.erl +++ b/lib/wx/test/wx_event_SUITE.erl @@ -47,7 +47,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> [connect, disconnect, connect_msg_20, connect_cb_20, - mouse_on_grid, spin_event, connect_in_callback]. + mouse_on_grid, spin_event, connect_in_callback, recursive]. groups() -> []. @@ -331,3 +331,35 @@ connect_in_callback(Config) -> wx_test_lib:flush(), wx_test_lib:wx_destroy(Frame, Config). + +%% Test that event callback which triggers another callback works +%% i.e. the callback invoker in driver will recurse +recursive(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo); +recursive(Config) -> + Wx = wx:new(), + Frame = wxFrame:new(Wx, ?wxID_ANY, "Connect in callback"), + Panel = wxPanel:new(Frame, []), + Sz = wxBoxSizer:new(?wxVERTICAL), + ListBox = wxListBox:new(Panel, ?wxID_ANY, [{choices, ["foo", "bar", "baz"]}]), + wxSizer:add(Sz, ListBox, [{proportion, 1},{flag, ?wxEXPAND}]), + wxWindow:setSizer(Panel, Sz), + wxListBox:connect(ListBox, command_listbox_selected, + [{callback, + fun(#wx{event=#wxCommand{commandInt=Id}}, _) -> + io:format("Selected ~p~n",[Id]) + end}]), + wxListBox:setSelection(ListBox, 0), + wxListBox:connect(ListBox, size, + [{callback, + fun(#wx{event=#wxSize{}}, _) -> + io:format("Size init ~n",[]), + case wxListBox:getCount(ListBox) > 0 of + true -> wxListBox:delete(ListBox, 0); + false -> ok + end, + io:format("Size done ~n",[]) + end}]), + wxFrame:show(Frame), + wx_test_lib:flush(), + + wx_test_lib:wx_destroy(Frame, Config). diff --git a/lib/wx/test/wx_obj_test.erl b/lib/wx/test/wx_obj_test.erl new file mode 100644 index 0000000000..b4d7640c7e --- /dev/null +++ b/lib/wx/test/wx_obj_test.erl @@ -0,0 +1,86 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2011. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +-module(wx_obj_test). +-include_lib("wx/include/wx.hrl"). + +-export([start/1]). + +%% wx_object callbacks +-export([init/1, handle_info/2, terminate/2, code_change/3, handle_call/3, + handle_sync_event/3, handle_event/2, handle_cast/2]). + +-record(state, {frame, panel, opts}). + +start(Opts) -> + wx_object:start_link(?MODULE, [{parent, self()}, Opts], []). + +init(Opts) -> + put(parent_pid, proplists:get_value(parent, Opts)), + Frame = wxFrame:new(wx:null(), ?wxID_ANY, "Test wx_object", [{size, {500, 400}}]), + Sz = wxBoxSizer:new(?wxHORIZONTAL), + Panel = wxPanel:new(Frame), + wxSizer:add(Sz, Panel, [{flag, ?wxEXPAND}, {proportion, 1}]), + wxPanel:connect(Panel, size, [{skip, true}]), + wxPanel:connect(Panel, paint, [callback, {userData, proplists:get_value(parent, Opts)}]), + wxWindow:show(Frame), + {Frame, #state{frame=Frame, panel=Panel, opts=Opts}}. + +handle_sync_event(Event = #wx{obj=Panel}, WxEvent, #state{opts=Opts}) -> + DC=wxPaintDC:new(Panel), %% We must create & destroy paintDC, or call wxEvent:skip(WxEvent)) + wxPaintDC:destroy(DC), %% in sync_event. Otherwise wx on windows keeps sending the events. + Pid = proplists:get_value(parent, Opts), + true = is_pid(Pid), + Pid ! {sync_event, Event, WxEvent}, + ok. + +handle_event(Event, State = #state{opts=Opts}) -> + Pid = proplists:get_value(parent, Opts), + Pid ! {event, Event}, + {noreply, State}. + +handle_call(What, From, State) when is_function(What) -> + Result = What(State), + {reply, {call, Result, From}, State}; +handle_call(What, From, State) -> + {reply, {call, What, From}, State}. + +handle_cast(What, State = #state{opts=Opts}) when is_function(What) -> + Result = What(State), + Pid = proplists:get_value(parent, Opts), + Pid ! {cast, Result}, + {noreply, State}; + +handle_cast(What, State = #state{opts=Opts}) -> + Pid = proplists:get_value(parent, Opts), + Pid ! {cast, What}, + {noreply, State}. + +handle_info(What, State = #state{opts=Opts}) -> + Pid = proplists:get_value(parent, Opts), + Pid ! {info, What}, + {noreply, State}. + +terminate(What, #state{opts=Opts}) -> + Pid = proplists:get_value(parent, Opts), + Pid ! {terminate, What}, + ok. + +code_change(Ver1, Ver2, State = #state{opts=Opts}) -> + Pid = proplists:get_value(parent, Opts), + Pid ! {code_change, Ver1, Ver2}, + State. diff --git a/lib/wx/test/wx_test_lib.hrl b/lib/wx/test/wx_test_lib.hrl index 34e1e9c6b8..820e8f0050 100644 --- a/lib/wx/test/wx_test_lib.hrl +++ b/lib/wx/test/wx_test_lib.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2009. All Rights Reserved. +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -40,7 +40,6 @@ -define(m(ExpectedRes, Expr), fun() -> - {TeStFILe, TeSTLiNe} = {?FILE, ?LINE}, AcTuAlReS = (catch (Expr)), case AcTuAlReS of ExpectedRes -> @@ -48,8 +47,8 @@ AcTuAlReS; _ -> wx_test_lib:error("Not Matching Actual result was:~n ~p ~n Expected ~s~n", - [AcTuAlReS, ??ExpectedRes], - TeStFILe,TeSTLiNe), + [AcTuAlReS, ??ExpectedRes], + ?FILE,?LINE), AcTuAlReS end end()). diff --git a/lib/xmerl/include/xmerl_xsd.hrl b/lib/xmerl/include/xmerl_xsd.hrl index 6dad7d8ff0..644cc2e433 100644 --- a/lib/xmerl/include/xmerl_xsd.hrl +++ b/lib/xmerl/include/xmerl_xsd.hrl @@ -184,7 +184,7 @@ %% allowed for a schema. %% chain, represents a series of ordered objects, some of whom may be %% optional. -%% alterantive, a collection of objects of which only one is choosen. +%% alterantive, a collection of objects of which only one is chosen. -record(chain,{ content, occurance={1,1} diff --git a/lib/xmerl/src/xmerl_xpath_scan.erl b/lib/xmerl/src/xmerl_xpath_scan.erl index 10e2756e74..a3240a1311 100644 --- a/lib/xmerl/src/xmerl_xpath_scan.erl +++ b/lib/xmerl/src/xmerl_xpath_scan.erl @@ -287,6 +287,7 @@ strip_ws(T) -> special_token('@') -> true; special_token('::') -> true; +special_token(',') -> true; special_token('(') -> true; special_token('[') -> true; special_token('/') -> true; |