openSUSE Commits
Threads by month
- ----- 2024 -----
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
April 2018
- 1 participants
- 1679 discussions
Hello community,
here is the log from the commit of package instsource-susedata for openSUSE:Factory checked in at 2018-04-26 13:35:10
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/instsource-susedata (Old)
and /work/SRC/openSUSE:Factory/.instsource-susedata.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "instsource-susedata"
Thu Apr 26 13:35:10 2018 rev:7 rq:600764 version:0.3.3
Changes:
--------
--- /work/SRC/openSUSE:Factory/instsource-susedata/instsource-susedata.changes 2018-04-23 15:25:14.307906384 +0200
+++ /work/SRC/openSUSE:Factory/.instsource-susedata.new/instsource-susedata.changes 2018-04-26 13:35:14.542212821 +0200
@@ -1,0 +2,7 @@
+Tue Apr 24 11:31:39 UTC 2018 - adrian(a)suse.de
+
+- update to version 0.3.3
+ * fix missing perl depency
+ * dependency check during build
+
+-------------------------------------------------------------------
Old:
----
instsource-susedata-0.3.2.obscpio
New:
----
instsource-susedata-0.3.3.obscpio
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ instsource-susedata.spec ++++++
--- /var/tmp/diff_new_pack.aMzAju/_old 2018-04-26 13:35:15.166189956 +0200
+++ /var/tmp/diff_new_pack.aMzAju/_new 2018-04-26 13:35:15.170189809 +0200
@@ -20,7 +20,7 @@
Summary: Utility to add susedata to repomd metadata
License: GPL-2.0-only
Group: System/Management
-Version: 0.3.2
+Version: 0.3.3
Release: 0
Source: %{name}-%{version}.tar.xz
BuildRoot: %{_tmppath}/%{name}-%{version}-build
@@ -29,8 +29,12 @@
%else
Requires: SLE-EULAs
%endif
+BuildRequires: inst-source-utils
+BuildRequires: perl(Locale::gettext)
+BuildRequires: perl(XML::Structured)
Requires: inst-source-utils
-Requires: perl-XML-Structured
+Requires: perl(Locale::gettext)
+Requires: perl(XML::Structured)
Supplements: kiwi-instsource
BuildArch: noarch
@@ -41,7 +45,7 @@
%setup -q
%build
-# empty because of rpmlint warning rpm-buildroot-usage
+perl -wc add_product_susedata || exit 1
%install
mkdir -p $RPM_BUILD_ROOT/usr/bin
++++++ _service ++++++
--- /var/tmp/diff_new_pack.aMzAju/_old 2018-04-26 13:35:15.202188637 +0200
+++ /var/tmp/diff_new_pack.aMzAju/_new 2018-04-26 13:35:15.206188491 +0200
@@ -2,8 +2,8 @@
<service name="obs_scm" mode="disabled">
<param name="url">https://github.com/openSUSE/instsource-susedata.git</param>
<param name="scm">git</param>
- <param name="version">0.3.2</param>
- <param name="revision">0.3.2</param>
+ <param name="version">0.3.3</param>
+ <param name="revision">0.3.3</param>
<param name="extract">instsource-susedata.changes</param>
<param name="extract">instsource-susedata.spec</param>
</service>
++++++ instsource-susedata-0.3.2.obscpio -> instsource-susedata-0.3.3.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/instsource-susedata-0.3.2/instsource-susedata.spec new/instsource-susedata-0.3.3/instsource-susedata.spec
--- old/instsource-susedata-0.3.2/instsource-susedata.spec 2018-04-17 17:34:39.000000000 +0200
+++ new/instsource-susedata-0.3.3/instsource-susedata.spec 2018-04-24 12:00:01.000000000 +0200
@@ -29,7 +29,10 @@
%else
Requires: SLE-EULAs
%endif
-Requires: perl-XML-Structured
+BuildRequires: perl(XML::Structured)
+BuildRequires: perl(Locale::gettext)
+Requires: perl(XML::Structured)
+Requires: perl(Locale::gettext)
Requires: inst-source-utils
Supplements: kiwi-instsource
BuildArch: noarch
@@ -41,7 +44,7 @@
%setup -q
%build
-# empty because of rpmlint warning rpm-buildroot-usage
+perl -wc add_product_susedata || exit 1
%install
mkdir -p $RPM_BUILD_ROOT/usr/bin
++++++ instsource-susedata.obsinfo ++++++
--- /var/tmp/diff_new_pack.aMzAju/_old 2018-04-26 13:35:15.338183653 +0200
+++ /var/tmp/diff_new_pack.aMzAju/_new 2018-04-26 13:35:15.338183653 +0200
@@ -1,5 +1,5 @@
name: instsource-susedata
-version: 0.3.2
-mtime: 1523979279
-commit: fc07a1432b41cfe53a9c755445436be5c1d79465
+version: 0.3.3
+mtime: 1524564001
+commit: b4a4206541b2f514f5224a6ac671dbe1062efc49
1
0
Hello community,
here is the log from the commit of package package-translations for openSUSE:Factory checked in at 2018-04-26 13:35:03
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/package-translations (Old)
and /work/SRC/openSUSE:Factory/.package-translations.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "package-translations"
Thu Apr 26 13:35:03 2018 rev:117 rq:600386 version:84.87.20180423.8e00def2
Changes:
--------
--- /work/SRC/openSUSE:Factory/package-translations/package-translations.changes 2017-07-21 22:38:09.399883316 +0200
+++ /work/SRC/openSUSE:Factory/.package-translations.new/package-translations.changes 2018-04-26 13:35:06.830495409 +0200
@@ -1,0 +2,25 @@
+Tue Apr 24 10:24:12 UTC 2018 - opensuse-packaging(a)opensuse.org
+
+- Update to version 84.87.20180423.8e00def2:
+ * Translated using Weblate (Arabic)
+ * Translated using Weblate (Chinese (China))
+ * Translated using Weblate (Czech)
+ * Translated using Weblate (Dutch)
+ * Translated using Weblate (French)
+ * Translated using Weblate (German)
+ * Translated using Weblate (Hungarian)
+ * Translated using Weblate (Italian)
+ * Translated using Weblate (Japanese)
+ * Translated using Weblate (Polish)
+ * Translated using Weblate (Portuguese (Brazil))
+ * Translated using Weblate (Russian)
+ * Translated using Weblate (Spanish)
+
+-------------------------------------------------------------------
+Mon Apr 16 12:03:31 UTC 2018 - opensuse-packaging(a)opensuse.org
+
+- Update to version 84.87.20180416.1a836422:
+ * Adjust for Leap 15
+- remove translate_packages.pl, no longer needed with product builder
+
+-------------------------------------------------------------------
Old:
----
package-translations-84.87.20170719.aabc165.tar.xz
translate_packages.pl
New:
----
package-translations-84.87.20180423.8e00def2.tar.xz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ package-translations.spec ++++++
--- /var/tmp/diff_new_pack.Yvz6c5/_old 2018-04-26 13:35:08.474435168 +0200
+++ /var/tmp/diff_new_pack.Yvz6c5/_new 2018-04-26 13:35:08.478435022 +0200
@@ -1,7 +1,7 @@
#
# spec file for package package-translations
#
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -17,16 +17,14 @@
Name: package-translations
-Version: 84.87.20170719.aabc165
+Version: 84.87.20180423.8e00def2
Release: 0
Summary: Summary and Descriptions Translations
License: BSD-3-Clause
Group: System/GUI/Other
BuildRoot: %{_tmppath}/%{name}-%{version}-build
Source0: %{name}-%{version}.tar.xz
-Source1: translate_packages.pl
BuildArch: noarch
-Requires: perl-gettext
Url: https://github.com/openSUSE/packages-i18n/
%define build_languages cs de es fr hu it ja lt nl nn ru uk zh_CN
@@ -46,12 +44,9 @@
for lang in %build_languages; do
msgcat --use-first $lang/po/*.po | msgfmt -o $target_dir/package-translations-$lang.mo -
done
-#cp -a mo/* $RPM_BUILD_ROOT/usr/share/locale/en_US/LC_MESSAGES
-install -D -m 755 %{SOURCE1} $RPM_BUILD_ROOT/usr/bin/translate_packages.pl
%files
%defattr(-,root,root)
%lang(en) /usr/share/locale/en_US/LC_MESSAGES/*
-/usr/bin/translate_packages.pl
%changelog
++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.Yvz6c5/_old 2018-04-26 13:35:08.526433263 +0200
+++ /var/tmp/diff_new_pack.Yvz6c5/_new 2018-04-26 13:35:08.530433117 +0200
@@ -1,4 +1,4 @@
<servicedata>
<service name="tar_scm">
<param name="url">git://github.com/openSUSE/packages-i18n.git</param>
- <param name="changesrevision">aabc1653ead4fd8918d934a34c37f746c7566851</param></service></servicedata>
\ No newline at end of file
+ <param name="changesrevision">8e00def2e114f2e55d6c044cb59678241cee1444</param></service></servicedata>
\ No newline at end of file
++++++ package-translations-84.87.20170719.aabc165.tar.xz -> package-translations-84.87.20180423.8e00def2.tar.xz ++++++
/work/SRC/openSUSE:Factory/package-translations/package-translations-84.87.20170719.aabc165.tar.xz /work/SRC/openSUSE:Factory/.package-translations.new/package-translations-84.87.20180423.8e00def2.tar.xz differ: char 26, line 1
1
0
Hello community,
here is the log from the commit of package bash-completion for openSUSE:Factory checked in at 2018-04-26 13:34:57
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/bash-completion (Old)
and /work/SRC/openSUSE:Factory/.bash-completion.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "bash-completion"
Thu Apr 26 13:34:57 2018 rev:38 rq:600355 version:2.7
Changes:
--------
--- /work/SRC/openSUSE:Factory/bash-completion/bash-completion.changes 2017-12-29 18:46:28.145416122 +0100
+++ /work/SRC/openSUSE:Factory/.bash-completion.new/bash-completion.changes 2018-04-26 13:34:59.890749705 +0200
@@ -1,0 +2,11 @@
+Tue Apr 24 09:21:58 UTC 2018 - werner(a)suse.de
+
+- Add patch bash-completion-2.7-unRAR-remove.patch that is due legal
+ issue the unRAR part of 7z had been removed (boo#1077978, boo#1090515)
+
+-------------------------------------------------------------------
+Tue Apr 3 15:30:09 CEST 2018 - kukuk(a)suse.de
+
+- Use %license instead of %doc [bsc#1082318]
+
+-------------------------------------------------------------------
New:
----
bash-completion-2.7-unRAR-remove.patch
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ bash-completion-doc.spec ++++++
--- /var/tmp/diff_new_pack.9OQDYY/_old 2018-04-26 13:35:00.714719512 +0200
+++ /var/tmp/diff_new_pack.9OQDYY/_new 2018-04-26 13:35:00.714719512 +0200
@@ -1,7 +1,7 @@
#
# spec file for package bash-completion-doc
#
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -23,7 +23,7 @@
Version: 2.7
Release: 0
Summary: The Documentation of Programmable Completion for Bash
-License: GPL-2.0+
+License: GPL-2.0-or-later
Group: Development/Libraries/C and C++
Url: https://github.com/scop/bash-completion/
Source0: https://github.com/scop/bash-completion/releases/download/%{version}/%{_nam…
++++++ bash-completion.spec ++++++
--- /var/tmp/diff_new_pack.9OQDYY/_old 2018-04-26 13:35:00.734718780 +0200
+++ /var/tmp/diff_new_pack.9OQDYY/_new 2018-04-26 13:35:00.734718780 +0200
@@ -1,7 +1,7 @@
#
# spec file for package bash-completion
#
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -25,7 +25,7 @@
Version: 2.7
Release: 0
Summary: Programmable Completion for Bash
-License: GPL-2.0+
+License: GPL-2.0-or-later
Group: System/Shells
Url: https://github.com/scop/bash-completion/
Source0: https://github.com/scop/bash-completion/releases/download/%{version}/%{name…
@@ -52,6 +52,8 @@
Patch10: backticks-bsc963140.patch
# PATCH-FIX-SUSE boo#977336
Patch11: sh-script-completion-boo977336.patch
+# PATCH-FIX-SUSE boo#1090515
+Patch12: bash-completion-2.7-unRAR-remove.patch
%if %build_doc
BuildRequires: asciidoc
BuildRequires: libxslt-tools
@@ -105,6 +107,7 @@
%patch9 -b .p9
%patch10 -b .p10 -p1
%patch11 -b .p11 -p0
+%patch12 -b .p12 -p0
%build
%configure
@@ -159,7 +162,7 @@
%if %build_core
%files
%defattr(-,root,root)
-%doc COPYING
+%license COPYING
%if %build_doc
%exclude %{_defaultdocdir}/%{name}/AUTHORS
%exclude %{_defaultdocdir}/%{name}/README
++++++ bash-completion-2.7-unRAR-remove.patch ++++++
Due legal issue the unRAR part of 7z had been removed (boo#1077978, boo#1090515)
---
completions/7z | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- completions/7z
+++ completions/7z 2018-04-24 09:17:49.392549710 +0000
@@ -75,7 +75,7 @@ _7z()
else
COMPREPLY=( $( compgen -P${cur:0:2} -W '7z apm arj bzip2 cab
chm cpio cramfs deb dmg elf fat flv gzip hfs iso lzh lzma
- lzma86 macho mbr mslz mub nsis ntfs pe ppmd rar rpm
+ lzma86 macho mbr mslz mub nsis ntfs pe ppmd rpm
squashfs swf swfc tar udf vhd wim xar xz z zip' \
-- "${cur:2}" ) )
fi
@@ -101,7 +101,7 @@ _7z()
_filedir_xspec unzip
[[ $mode == w ]] &&
_filedir '@(7z|bz2|swf|?(g)tar|?(t)[bglx]z|tb?(z)2|wim)' ||
- _filedir '@(7z|arj|bz2|cab|chm|cpio|deb|dmg|flv|gem|img|iso|lz[ah]|lzma?(86)|pmd|[rx]ar|rpm|sw[fm]|?(g)tar|taz|?(t)[bglx]z|tb?(z)2|vhd|wim|Z)'
+ _filedir '@(7z|arj|bz2|cab|chm|cpio|deb|dmg|flv|gem|img|iso|lz[ah]|lzma?(86)|pmd|xar|rpm|sw[fm]|?(g)tar|taz|?(t)[bglx]z|tb?(z)2|vhd|wim|Z)'
else
if [[ ${words[1]} == d ]]; then
local IFS=$'\n'
1
0
Hello community,
here is the log from the commit of package libquicktime for openSUSE:Factory checked in at 2018-04-26 13:34:51
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libquicktime (Old)
and /work/SRC/openSUSE:Factory/.libquicktime.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libquicktime"
Thu Apr 26 13:34:51 2018 rev:58 rq:599788 version:1.2.4cvs20150223
Changes:
--------
--- /work/SRC/openSUSE:Factory/libquicktime/libquicktime.changes 2017-12-03 10:11:25.099358360 +0100
+++ /work/SRC/openSUSE:Factory/.libquicktime.new/libquicktime.changes 2018-04-26 13:34:52.839008104 +0200
@@ -1,0 +2,5 @@
+Sat Apr 21 12:56:48 UTC 2018 - jengelh(a)inai.de
+
+- Explicitly request ffmpeg 3.x for building
+
+-------------------------------------------------------------------
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ libquicktime.spec ++++++
--- /var/tmp/diff_new_pack.4BUyfh/_old 2018-04-26 13:34:53.514983334 +0200
+++ /var/tmp/diff_new_pack.4BUyfh/_new 2018-04-26 13:34:53.518983187 +0200
@@ -1,7 +1,7 @@
#
# spec file for package libquicktime
#
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -27,7 +27,7 @@
Release: 0
#to_be_filled_by_service
Summary: Library for Reading and Writing Quicktime Movie Files
-License: GPL-2.0+
+License: GPL-2.0-or-later
Group: Development/Libraries/C and C++
Url: http://libquicktime.sf.net
Source0: %{name}-%{version}.tar.gz
@@ -51,9 +51,9 @@
BuildRequires: pkg-config
BuildRequires: schroedinger-devel
BuildRequires: pkgconfig(gl)
-BuildRequires: pkgconfig(libavcodec)
+BuildRequires: pkgconfig(libavcodec) < 58
BuildRequires: pkgconfig(libpng)
-BuildRequires: pkgconfig(libswscale)
+BuildRequires: pkgconfig(libswscale) < 5
BuildRequires: pkgconfig(x11)
BuildRequires: pkgconfig(xaw7)
BuildRequires: pkgconfig(xext)
1
0
Hello community,
here is the log from the commit of package hdparm for openSUSE:Factory checked in at 2018-04-26 13:34:45
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/hdparm (Old)
and /work/SRC/openSUSE:Factory/.hdparm.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "hdparm"
Thu Apr 26 13:34:45 2018 rev:70 rq:599787 version:9.56
Changes:
--------
--- /work/SRC/openSUSE:Factory/hdparm/hdparm.changes 2017-12-19 10:47:42.880553298 +0100
+++ /work/SRC/openSUSE:Factory/.hdparm.new/hdparm.changes 2018-04-26 13:34:48.159179587 +0200
@@ -1,0 +2,17 @@
+Fri Apr 20 14:20:48 UTC 2018 - kstreitova(a)suse.com
+
+- update to version 9.56
+ * 9.56 - fixed byte order for --Istdout so that --Istdin can
+ grok it
+ - added --Iraw for raw binary output of IDENTIFY data
+ to a file
+ * 9.55 - added #include <sys/sysmacros.h> for major()/minor()
+ macros
+ * 9.54 - Partial revert of Jmicron changes, from Jan Friesse.
+ * 9.53 - Read Drive Capacity fixes from Iestyn Walters.
+ - SET MAX ADDRESS fixes from Tom Yan <tom.ty89(a)gmail.com>
+ - added --security-prompt-for-password to --security-help
+ output
+ - fwdownload changes from Jihoon Lee.
+
+-------------------------------------------------------------------
Old:
----
hdparm-9.52.tar.gz
New:
----
hdparm-9.56.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ hdparm.spec ++++++
--- /var/tmp/diff_new_pack.5DwEg0/_old 2018-04-26 13:34:48.955150420 +0200
+++ /var/tmp/diff_new_pack.5DwEg0/_new 2018-04-26 13:34:48.959150273 +0200
@@ -1,7 +1,7 @@
#
# spec file for package hdparm
#
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
Name: hdparm
-Version: 9.52
+Version: 9.56
Release: 0
Summary: A Program to get and set hard disk parameters
License: SUSE-Permissive
@@ -65,7 +65,7 @@
%files
%doc Changelog README.acoustic contrib/README.contrib README.wiper
-%{_mandir}/man8/hdparm.8%{ext_man}
+%{_mandir}/man8/hdparm.8%{?ext_man}
#UsrMerge
/sbin/hdparm
/sbin/wiper.sh
++++++ hdparm-9.52.tar.gz -> hdparm-9.56.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.52/Changelog new/hdparm-9.56/Changelog
--- old/hdparm-9.52/Changelog 2017-05-01 21:12:59.000000000 +0200
+++ new/hdparm-9.56/Changelog 2018-03-25 19:07:14.000000000 +0200
@@ -1,3 +1,17 @@
+hdparm-9.56:
+ - fixed byte order for --Istdout so that --Istdin can grok it
+ - added --Iraw for raw binary output of IDENTIFY data to a file
+hdparm-9.55:
+ - added #include <sys/sysmacros.h> for major()/minor() macros
+hdparm-9.54:
+ - Partial revert of Jmicron changes, from Jan Friesse.
+hdparm-9.53:
+ - Read Drive Capacity fixes from Iestyn Walters.
+ - SET MAX ADDRESS fixes from Tom Yan <tom.ty89(a)gmail.com>.
+ - added --security-prompt-for-password to --security-help output.
+ - fwdownload changes from Jihoon Lee.
+hdparm-9.52:
+ - Jmicron SATA-USB bridge support from Jan Friesse <jfriesse(a)gmail.com>.
hdparm-9.51:
- add support for Jmicron USB-SATA bridges, courtesy Jan Friesse <jfriesse(a)gmail.com>.
hdparm-9.51:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.52/apt.c new/hdparm-9.56/apt.c
--- old/hdparm-9.52/apt.c 2017-05-01 21:10:11.000000000 +0200
+++ new/hdparm-9.56/apt.c 2018-02-03 19:10:16.000000000 +0100
@@ -264,47 +264,8 @@
static int apt_jmicron_sg16(int fd, int rw, int dma, struct ata_tf *tf,
void *data, unsigned int data_bytes, unsigned int timeout_secs)
{
- int res;
- unsigned char regs[16];
- memset(regs, 0, sizeof(tf));
-
- res = apt_jmicron_int_sg(fd, rw, dma, tf, data, data_bytes, timeout_secs, 0);
-
- if (res == -1) return res;
-
- if ((res = apt_jmicron_int_get_registers(fd,
- (apt_data.jmicron.port == 0xa0 ? 0x8000 : 0x9000), regs, sizeof(regs))) == -1) {
- return res;
- }
-
- tf->is_lba48 = 0;
- tf->error = regs[13];
- tf->lob.nsect = regs[ 0];
- tf->lob.lbal = regs[ 6];
- tf->lob.lbam = regs[ 4];
- tf->lob.lbah = regs[10];
- tf->dev = regs[ 9];
- tf->status = regs[14];
- tf->hob.feat = 0;
- tf->hob.nsect = 0;
- tf->hob.lbal = 0;
- tf->hob.lbam = 0;
- tf->hob.lbah = 0;
-
- if (apt_data.verbose)
- fprintf(stderr, " ATA_%u stat=%02x err=%02x nsect=%02x lbal=%02x lbam=%02x lbah=%02x dev=%02x\n",
- 12, tf->status, tf->error, tf->lob.nsect, tf->lob.lbal, tf->lob.lbam, tf->lob.lbah, tf->dev);
-
- if (tf->status & (ATA_STAT_ERR | ATA_STAT_DRQ)) {
- if (apt_data.verbose) {
- fprintf(stderr, "I/O error, ata_op=0x%02x ata_status=0x%02x ata_error=0x%02x\n",
- tf->command, tf->status, tf->error);
- }
- errno = EIO;
- return -1;
- }
- return 0;
+ return apt_jmicron_int_sg(fd, rw, dma, tf, data, data_bytes, timeout_secs, 0);
}
#else
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.52/fwdownload.c new/hdparm-9.56/fwdownload.c
--- old/hdparm-9.52/fwdownload.c 2016-10-17 20:01:05.000000000 +0200
+++ new/hdparm-9.56/fwdownload.c 2017-12-06 13:41:40.000000000 +0100
@@ -160,9 +160,16 @@
} else if (xfer_mode == 3) {
xfer_size = xfer_min;
} else if (xfer_mode == 0x0e) {
+#if 0
xfer_size = xfer_max;
} else if (xfer_mode == 0xe0) {
xfer_size = xfer_min;
+#else
+ xfer_size = xfer_min;
+ } else if (xfer_mode == 0xe0) {
+ xfer_mode = 0x0e;
+ xfer_size = xfer_max;
+#endif
} else {
xfer_size = st.st_size / 512;
if (xfer_size > 0xffff) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.52/geom.c new/hdparm-9.56/geom.c
--- old/hdparm-9.52/geom.c 2016-10-13 01:50:52.000000000 +0200
+++ new/hdparm-9.56/geom.c 2018-03-15 20:27:21.000000000 +0100
@@ -15,6 +15,7 @@
#include <errno.h>
#include <dirent.h>
#include <sys/stat.h>
+#include <sys/sysmacros.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/fs.h>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.52/hdparm.8 new/hdparm-9.56/hdparm.8
--- old/hdparm-9.52/hdparm.8 2017-01-19 18:07:27.000000000 +0100
+++ new/hdparm-9.56/hdparm.8 2018-03-25 19:08:09.000000000 +0200
@@ -1,4 +1,4 @@
-.TH HDPARM 8 "January 2017" "Version 9.51"
+.TH HDPARM 8 "March 2018" "Version 9.55"
.SH NAME
hdparm \- get/set SATA/IDE device parameters
@@ -282,6 +282,9 @@
.B -i
option.
.TP
+.I --Iraw <pathname>
+This option dumps the drive's identify data in raw binary to the specified file.
+.TP
.I --Istdin
This is a special variation on the
.B -I
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.52/hdparm.c new/hdparm-9.56/hdparm.c
--- old/hdparm-9.52/hdparm.c 2017-05-01 21:14:16.000000000 +0200
+++ new/hdparm-9.56/hdparm.c 2018-03-25 19:06:24.000000000 +0200
@@ -2,7 +2,7 @@
* hdparm.c - Command line interface to get/set hard disk parameters.
* - by Mark Lord (C) 1994-2017 -- freely distributable.
*/
-#define HDPARM_VERSION "v9.52"
+#define HDPARM_VERSION "v9.56"
#define _LARGEFILE64_SOURCE /*for lseek64*/
#define _BSD_SOURCE /* for strtoll() */
@@ -95,7 +95,7 @@
static int do_dco_freeze = 0, do_dco_restore = 0, do_dco_identify = 0, do_dco_setmax = 0;
static unsigned int security_command = ATA_OP_SECURITY_UNLOCK;
-static char security_password[33], *fwpath;
+static char security_password[33], *fwpath, *raw_identify_path;
static int do_sanitize = 0;
static __u16 sanitize_feature = 0;
@@ -427,6 +427,11 @@
}
static __u16 *id;
+
+#define SUPPORTS_ACS3(id) ((id)[80] & 0x400)
+#define SUPPORTS_AMAX_ADDR(id) (SUPPORTS_ACS3(id) && ((id)[119] & (1u << 8)))
+#define SUPPORTS_48BIT_ADDR(id) ((((id)[83] & 0xc400) == 0x4400) && ((id)[86] & 0x0400))
+
static void get_identify_data (int fd);
static __u64 get_lba_capacity (__u16 *idw)
@@ -865,7 +870,6 @@
r.cmd_req = TASKFILE_CMD_REQ_NODATA;
r.dphase = TASKFILE_DPHASE_NONE;
- r.oflags.bits.lob.dev = 1;
r.oflags.bits.lob.command = 1;
r.oflags.bits.lob.feat = 1;
r.oflags.bits.lob.lbal = 1;
@@ -875,7 +879,6 @@
r.oflags.bits.hob.lbam = 1;
r.oflags.bits.hob.lbah = 1;
- r.lob.dev = 0x40;
r.lob.command = ATA_OP_SANITIZE;
r.lob.feat = sanitize_feature;
r.lob.lbal = lba;
@@ -1135,23 +1138,23 @@
return err;
}
-static void dump_sectors (__u16 *w, unsigned int count)
+static void dump_sectors (__u16 *w, unsigned int count, int raw)
{
unsigned int i;
for (i = 0; i < (count*256/8); ++i) {
-#if 0
- printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",
- w[0], w[1], w[2], w[3], w[4], w[5], w[6], w[7]);
- w += 8;
-#else
- int word;
- for (word = 0; word < 8; ++word) {
- unsigned char *b = (unsigned char *)w++;
- printf("%02x%02x", b[0], b[1]);
- putchar(word == 7 ? '\n' : ' ');
+ if (raw) {
+ printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",
+ w[0], w[1], w[2], w[3], w[4], w[5], w[6], w[7]);
+ w += 8;
+ } else {
+ int word;
+ for (word = 0; word < 8; ++word) {
+ unsigned char *b = (unsigned char *)w++;
+ printf("%02x%02x", b[0], b[1]);
+ putchar(word == 7 ? '\n' : ' ');
+ }
}
-#endif
}
}
@@ -1208,7 +1211,7 @@
unsigned char *b = (unsigned char *)&dco[i];
dco[i] = b[0] | (b[1] << 8); /* le16_to_cpu */
}
- //dump_sectors(dco, 1);
+ //dump_sectors(dco, 1, 0);
return dco;
}
}
@@ -1240,7 +1243,7 @@
}
if (verbose) {
printf("Original DCO:\n");
- dump_sectors(dco, 1);
+ dump_sectors(dco, 1, 0);
}
// set the new MAXLBA to the requested sectors - 1
*maxlba = set_max_addr - 1;
@@ -1248,7 +1251,7 @@
dco[255] = (dco[255] & 0xFF) | ((__u16) dco_verify_checksum(dco) << 8);
if (verbose) {
printf("New DCO:\n");
- dump_sectors(dco, 1);
+ dump_sectors(dco, 1, 0);
}
} else {
@@ -1288,47 +1291,40 @@
memset(&r, 0, sizeof(r));
r.cmd_req = TASKFILE_CMD_REQ_NODATA;
r.dphase = TASKFILE_DPHASE_NONE;
- r.oflags.bits.lob.dev = 1;
r.oflags.bits.lob.command = 1;
r.iflags.bits.lob.command = 1;
r.iflags.bits.lob.lbal = 1;
r.iflags.bits.lob.lbam = 1;
r.iflags.bits.lob.lbah = 1;
- r.lob.dev = 0x40;
- if((id[80]&0x400)==0x400) { //ACS3 supported
- if (((id[83] & 0xc400) == 0x4400) && (id[86] & 0x0400)) {
- r.iflags.bits.hob.lbal = 1;
- r.iflags.bits.hob.lbam = 1;
- r.iflags.bits.hob.lbah = 1;
- r.lob.command = ATA_OP_GET_NATIVE_MAX_EXT;
- if (do_taskfile_cmd(fd, &r, 10)) {
- err = errno;
- perror (" READ_NATIVE_MAX_ADDRESS_EXT failed");
- } else {
- if (verbose)
- printf("READ_NATIVE_MAX_ADDRESS_EXT response: hob={%02x %02x %02x} lob={%02x %02x %02x}\n",
- r.hob.lbah, r.hob.lbam, r.hob.lbal, r.lob.lbah, r.lob.lbam, r.lob.lbal);
- max = (((__u64)((r.hob.lbah << 16) | (r.hob.lbam << 8) | r.hob.lbal) << 24)
- | ((r.lob.lbah << 16) | (r.lob.lbam << 8) | r.lob.lbal)) + 1;
- }
+ if (SUPPORTS_AMAX_ADDR(id)) {
+ /* ACS3 supported, no 28-bit variant defined in spec */
+ r.iflags.bits.hob.lbal = 1;
+ r.iflags.bits.hob.lbam = 1;
+ r.iflags.bits.hob.lbah = 1;
+ r.oflags.bits.lob.feat = 1;
+ r.lob.command = ATA_OP_GET_NATIVE_MAX_EXT;
+ r.lob.feat = 0x00; //GET NATIVE MAX ADDRESS EXT is 78h/0000h
+ //bit 6 of DEVICE field is defined as "N/A"
+ if (do_taskfile_cmd(fd, &r, 0)) {
+ err = errno;
+ perror (" GET_NATIVE_MAX_ADDRESS_EXT failed");
} else {
- r.iflags.bits.lob.dev = 1;
- r.lob.command = ATA_OP_GET_NATIVE_MAX_EXT;
- if (do_taskfile_cmd(fd, &r, timeout_15secs)) {
- err = errno;
- perror (" READ_NATIVE_MAX_ADDRESS failed");
- } else {
- max = ((r.lob.lbah << 16) | (r.lob.lbam << 8) | r.lob.lbal) + 1;
- }
- }
- } else { //ACS2 supported
- if (((id[83] & 0xc400) == 0x4400) && (id[86] & 0x0400)) {
+ if (verbose)
+ printf("GET_NATIVE_MAX_ADDRESS_EXT response: hob={%02x %02x %02x} lob={%02x %02x %02x}\n",
+ r.hob.lbah, r.hob.lbam, r.hob.lbal, r.lob.lbah, r.lob.lbam, r.lob.lbal);
+ max = (((__u64)((r.hob.lbah << 16) | (r.hob.lbam << 8) | r.hob.lbal) << 24)
+ | ((r.lob.lbah << 16) | (r.lob.lbam << 8) | r.lob.lbal)) + 1;
+ }
+ } else { // ACS2 or below, or optional AMAX not present
+ if (SUPPORTS_48BIT_ADDR(id)) {
r.iflags.bits.hob.lbal = 1;
r.iflags.bits.hob.lbam = 1;
r.iflags.bits.hob.lbah = 1;
+ r.oflags.bits.lob.dev = 1;
r.lob.command = ATA_OP_READ_NATIVE_MAX_EXT;
- if (do_taskfile_cmd(fd, &r, 10)) {
+ r.lob.dev = 0x40;
+ if (do_taskfile_cmd(fd, &r, timeout_15secs)) { //timeout for pre-ACS3 case of do_set_max_sectors
err = errno;
perror (" READ_NATIVE_MAX_ADDRESS_EXT failed");
} else {
@@ -1339,16 +1335,19 @@
| ((r.lob.lbah << 16) | (r.lob.lbam << 8) | r.lob.lbal)) + 1;
}
} else {
- r.iflags.bits.lob.dev = 1;
+ /* DEVICE (3:0) / LBA (27:24) "remap" does NOT apply in ATA Status Return */
+ r.iflags.bits.hob.lbal = 1;
r.lob.command = ATA_OP_READ_NATIVE_MAX;
- if (do_taskfile_cmd(fd, &r, 0)) {
+ //bit 7:5 of DEVICE field is defined as "Obsolete"
+ if (do_taskfile_cmd(fd, &r, timeout_15secs)) { //timeout for pre-ACS3 case of do_set_max_sectors
err = errno;
perror (" READ_NATIVE_MAX_ADDRESS failed");
} else {
- max = (((r.lob.dev & 0x0f) << 24) | (r.lob.lbah << 16) | (r.lob.lbam << 8) | r.lob.lbal) + 1;
+ max = (((r.hob.lbal & 0x0f) << 24) | (r.lob.lbah << 16) | (r.lob.lbam << 8) | r.lob.lbal) + 1;
}
}
}
+
errno = err;
return max;
@@ -1681,7 +1680,7 @@
perror("FAILED");
} else {
printf("succeeded\n");
- dump_sectors(r->data, 1);
+ dump_sectors(r->data, 1, 0);
}
free(r);
return err;
@@ -1714,45 +1713,40 @@
if (!id)
exit(EIO);
- if((id[80]&0x400)==0x400){
- //ACS3 supported
- if ((max_lba >> 28) || (id && ((id[83] & 0xc400) == 0x4400) && (id[86] & 0x0400))) {
-
- init_hdio_taskfile(&r, ATA_OP_GET_NATIVE_MAX_EXT, RW_READ, LBA48_FORCE, max_lba, nsect, 0);
- r.oflags.bits.lob.feat = 1;
- r.lob.feat = 0x01;
- } else {
- init_hdio_taskfile(&r, ATA_OP_GET_NATIVE_MAX_EXT, RW_READ, LBA28_OK, max_lba, nsect, 0);
- r.oflags.bits.lob.feat = 1; /*this ATA op requires feat == 0 */
- }
+ if (SUPPORTS_AMAX_ADDR(id)) {
+ /* ACS3 supported, no 28-bit variant defined in spec */
+ init_hdio_taskfile(&r, ATA_OP_GET_NATIVE_MAX_EXT, RW_READ, LBA48_FORCE, max_lba, nsect, 0);
+ r.oflags.bits.lob.feat = 1;
+ r.lob.feat = 0x01; //SET ACCESSIBLE MAX ADDRESS EXT is 78h/0001h
+ //bit 6 of DEVICE field is defined as "N/A"
+ /* No more "racey" in ACS3+AMAX case? */
if (do_taskfile_cmd(fd, &r, timeout_15secs)) {
err = errno;
- perror(" SET_MAX_ADDRESS failed");
+ perror(" SET_ACCESSIBLE_MAX_ADDRESS_EXT failed");
+ }
+ } else {
+ if ((max_lba >= lba28_limit) || SUPPORTS_48BIT_ADDR(id)) {
+ init_hdio_taskfile(&r, ATA_OP_SET_MAX_EXT, RW_READ, LBA48_FORCE, max_lba, nsect, 0);
+ r.oflags.bits.lob.dev = 1;
+ r.lob.dev = 0x40;
+ } else {
+ init_hdio_taskfile(&r, ATA_OP_SET_MAX, RW_READ, LBA28_OK, max_lba, nsect, 0);
+ //bit 7:5 of DEVICE field is defined as "Obsolete"
}
- return err;
+ /* spec requires that we do this immediately in front.. racey */
+ if (!do_get_native_max_sectors(fd))
+ return errno;
+ /* now set the new value */
+ if (do_taskfile_cmd(fd, &r, 0)) {
+ err = errno;
+ perror(" SET_MAX_ADDRESS(_EXT) failed");
}
- else{
- if ((max_lba >= lba28_limit) || (id && ((id[83] & 0xc400) == 0x4400) && (id[86] & 0x0400))) {
- init_hdio_taskfile(&r, ATA_OP_SET_MAX_EXT, RW_READ, LBA48_FORCE, max_lba, nsect, 0);
- } else {
- init_hdio_taskfile(&r, ATA_OP_SET_MAX, RW_READ, LBA28_OK, max_lba, nsect, 0);
- r.oflags.bits.lob.feat = 1; /* this ATA op requires feat==0 */
}
- /* spec requires that we do this immediately in front.. racey */
- if (!do_get_native_max_sectors(fd))
- return errno;
-
- /* now set the new value */
- if (do_taskfile_cmd(fd, &r, 0)) {
- err = errno;
- perror(" SET_MAX_ADDRESS failed");
- }
return err;
- }
}
static void usage_help (int clue, int rc)
@@ -1825,6 +1819,7 @@
" --fwdownload-modee-max Download firmware using mode E (max-size segments) (EXTREMELY DANGEROUS)\n"
" --idle-immediate Idle drive immediately\n"
" --idle-unload Idle immediately and unload heads\n"
+ " --Iraw filename Write raw binary identify data to the specfied file\n"
" --Istdin Read identify data from stdin as ASCII hex\n"
" --Istdout Write identify data to stdout as ASCII hex\n"
" --make-bad-sector Deliberately corrupt a sector directly on the media (VERY DANGEROUS)\n"
@@ -1862,6 +1857,8 @@
" --security-set-pass PASSWD Lock drive, using password PASSWD:\n"
" Use 'NULL' to set empty password.\n"
" Drive gets locked if user-passwd is selected.\n"
+ " --security-prompt-for-password Prompt user to enter the drive password.\n"
+ "\n"
" --security-unlock PASSWD Unlock drive.\n"
" --security-disable PASSWD Disable drive locking.\n"
" --security-erase PASSWD Erase a (locked) drive.\n"
@@ -2538,10 +2535,31 @@
if (do_IDentity) {
get_identify_data(fd);
if (id) {
- if (do_IDentity == 2)
- dump_sectors(id, 1);
- else
+ if (do_IDentity == 2) {
+ dump_sectors(id, 1, 1);
+ } else if (do_IDentity == 3) {
+ /* Write raw binary IDENTIFY DEVICE data to the specified file */
+ int rfd = open(raw_identify_path, O_WRONLY|O_TRUNC|O_CREAT, 0644);
+ if (rfd == -1) {
+ err = errno;
+ perror(raw_identify_path);
+ exit(err);
+ }
+ err = write(rfd, id, 0x200);
+ if (err == -1) {
+ err = errno;
+ perror(raw_identify_path);
+ exit(err);
+ } else if (err != 0x200) {
+ fprintf(stderr, "Error writing IDENTIFY DEVICE data to \"%s\"\n", raw_identify_path);
+ exit(EIO);
+ } else {
+ fprintf(stderr, "Wrote IDENTIFY DEVICE data to \"%s\"\n", raw_identify_path);
+ close(rfd);
+ }
+ } else {
identify(fd, (void *)id);
+ }
}
}
if (get_lookahead) {
@@ -2612,30 +2630,27 @@
}
}
if (get_native_max_sectors) {
- __u64 visible, native;
get_identify_data(fd);
if (id) {
- visible = get_lba_capacity(id);
- native = do_get_native_max_sectors(fd);
+ __u64 visible = get_lba_capacity(id);
+ __u64 native = do_get_native_max_sectors(fd);
if (!native) {
err = errno;
} else {
printf(" max sectors = %llu/%llu", visible, native);
if (visible < native){
-
- if((id[80]&0x400)==0x400){
+ if (SUPPORTS_AMAX_ADDR(id)) {
printf(", ACCESSIBLE MAX ADDRESS enabled\n");
printf("Power cycle your device after every ACCESSIBLE MAX ADDRESS\n");
-
}
else
- printf(", HPA is enabled\n");
+ printf(", HPA is enabled\n");
}
else if (visible == native){
- if((id[80]&0x400)==0x400)
+ if (SUPPORTS_AMAX_ADDR(id))
printf(", ACCESSIBLE MAX ADDRESS disabled\n");
- else
- printf(", HPA is disabled\n");
+ else
+ printf(", HPA is disabled\n");
}
else {
__u16 *dco = get_dco_identify_data(fd, 1);
@@ -3182,6 +3197,9 @@
get_u64_parm(0, 0, NULL, &read_sector_addr, 0, lba_limit, name, lba_emsg);
} else if (0 == strcasecmp(name, "Istdout")) {
do_IDentity = 2;
+ } else if (0 == strcasecmp(name, "Iraw")) {
+ do_IDentity = 3;
+ get_filename_parm(&raw_identify_path, name);
} else if (0 == strcasecmp(name, "security-mode")) {
if (argc && isalpha(**argv)) {
argp = *argv++, --argc;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.52/hdparm.lsm new/hdparm-9.56/hdparm.lsm
--- old/hdparm-9.52/hdparm.lsm 2017-05-01 21:16:35.000000000 +0200
+++ new/hdparm-9.56/hdparm.lsm 2018-03-25 19:08:50.000000000 +0200
@@ -1,8 +1,12 @@
Begin4
Title: hdparm
-Version: 9.52
-Entered-date: 2017-05-01
+Version: 9.56
+Entered-date: 2018-03-25
Description: hdparm - get/set hard disk parameters for Linux SATA/IDE drives.
+ v9.56 fixed --Istdout, added --Iraw
+ v9.55 #include <sys/sysmacros.h>
+ v9.54 partial revert of JMicron changes.
+ v9.53 Read Drive Capacity fixes, SET MAX ADDRESS fixes, fwdownload fixes.
v9.52 added JMicron USB-SATA bridge support, courtesy Jan Friesse <jfriesse(a)gmail.com>.
v9.51 minor fixes/tweaks, new --security-prompt-for-password flag.
v9.50 minor fixes for sanitize device stuff.
@@ -126,7 +130,7 @@
Maintained-by: mlord(a)pobox.com (Mark Lord)
Primary-site: http://sourceforge.net/projects/hdparm/
Alternate-site: http://www.ibiblio.org/pub/Linux/system/hardware
- 140K hdparm-9.52.tar.gz
+ 137K hdparm-9.56.tar.gz
7K hdparm.lsm
Platforms: Linux
Copying-policy: BSD License
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.52/jmicron-usb-try1.patch new/hdparm-9.56/jmicron-usb-try1.patch
--- old/hdparm-9.52/jmicron-usb-try1.patch 2017-05-01 21:05:00.000000000 +0200
+++ new/hdparm-9.56/jmicron-usb-try1.patch 1970-01-01 01:00:00.000000000 +0100
@@ -1,491 +0,0 @@
-diff --git a/Makefile b/Makefile
-index d28b703..44aaefb 100644
---- a/Makefile
-+++ b/Makefile
-@@ -22,7 +22,7 @@ INSTALL_DATA = $(INSTALL) -m 644
- INSTALL_DIR = $(INSTALL) -m 755 -d
- INSTALL_PROGRAM = $(INSTALL)
-
--OBJS = hdparm.o identify.o sgio.o sysfs.o geom.o fibmap.o fwdownload.o dvdspeed.o
-+OBJS = hdparm.o identify.o sgio.o sysfs.o geom.o fibmap.o fwdownload.o dvdspeed.o apt.o
-
- all: hdparm
-
-@@ -38,6 +38,8 @@ dvdspeed.o: dvdspeed.c
-
- sgio.o: sgio.c sgio.h hdparm.h
-
-+apt.o: apt.c
-+
- install: all hdparm.8
- if [ ! -z $(DESTDIR) ]; then $(INSTALL_DIR) $(DESTDIR) ; fi
- if [ ! -z $(DESTDIR)$(sbindir) ]; then $(INSTALL_DIR) $(DESTDIR)$(sbindir) ; fi
-diff --git a/apt.c b/apt.c
-new file mode 100644
-index 0000000..afbb992
---- /dev/null
-+++ b/apt.c
-@@ -0,0 +1,334 @@
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <fcntl.h>
-+#include <string.h>
-+#include <unistd.h>
-+#include <sys/ioctl.h>
-+#include <linux/cdrom.h>
-+#include <scsi/scsi.h>
-+#include <scsi/sg.h>
-+#include <sys/types.h>
-+#include <errno.h>
-+#include "hdparm.h"
-+#include "sgio.h"
-+
-+/*
-+ * apt - Support for ATA PASS THROUGH devices. Currently supported only
-+ * JMicron devices.
-+ *
-+ * Copyright (c) 2009 Jan Friesse <jfriesse(a)gmail.com>
-+ *
-+ * Magic numbers are taken from smartmontools source code
-+ * (http://smartmontools.sourceforge.net/)
-+ *
-+ * You may use/distribute this freely, under the terms of either
-+ * (your choice) the GNU General Public License version 2,
-+ * or a BSD style license.
-+ */
-+
-+#ifdef SG_IO
-+
-+/* External functions*/
-+int sysfs_get_attr_recursive (int fd, const char *attr, const char *fmt, void *val1, void *val2, int verbose);
-+
-+/* Device initialization functions */
-+static int apt_jmicron_int_init(int fd);
-+
-+/* Device sg16 functions*/
-+static int apt_jmicron_sg16(int fd, int rw, int dma, struct ata_tf *tf,
-+ void *data, unsigned int data_bytes, unsigned int timeout_secs);
-+
-+/* Structs */
-+struct apt_usb_id_entry {
-+ int vendor_id;
-+ int product_id;
-+ int version;
-+ const char *type;
-+ int (*init_func)(int fd);
-+ int (*sg16_func)(int fd, int rw, int dma, struct ata_tf *tf,
-+ void *data, unsigned int data_bytes, unsigned int timeout_secs);
-+
-+};
-+
-+struct apt_data_struct {
-+ int is_apt;
-+ struct apt_usb_id_entry id;
-+ int verbose;
-+ union {
-+ struct {
-+ int port;
-+ } jmicron;
-+ };
-+};
-+
-+static struct apt_data_struct apt_data;
-+
-+const char apt_ds_jmicron[] = "jmicron";
-+const char apt_ds_unsup[] = "unsupported";
-+
-+const struct apt_usb_id_entry apt_usb_id_map[] = {
-+ {0x152d, 0x2329, 0x0100, apt_ds_jmicron,
-+ apt_jmicron_int_init, apt_jmicron_sg16}, /* JMicron JM20329 (USB->SATA) */
-+ {0x152d, 0x2336, 0x0100, apt_ds_jmicron,
-+ apt_jmicron_int_init, apt_jmicron_sg16}, /* JMicron JM20336 (USB+SATA->SATA, USB->2xSATA) */
-+ {0x152d, 0x2338, 0x0100, apt_ds_jmicron,
-+ apt_jmicron_int_init, apt_jmicron_sg16}, /* JMicron JM20337/8 (USB->SATA+PATA, USB+SATA->PATA) */
-+ {0x152d, 0x2339, 0x0100, apt_ds_jmicron,
-+ apt_jmicron_int_init, apt_jmicron_sg16} /* JMicron JM20339 (USB->SATA) */
-+};
-+
-+int apt_detect (int fd, int verbose)
-+{
-+ int err;
-+ unsigned int i;
-+
-+ apt_data.is_apt = 0;
-+
-+ err = sysfs_get_attr_recursive(fd, "idVendor", "%x", &apt_data.id.vendor_id, NULL, verbose);
-+ if (err) {
-+ if (verbose) printf("APT: No idVendor found -> not USB bridge device\n");
-+ return 0;
-+ }
-+
-+ err = sysfs_get_attr_recursive(fd, "idProduct", "%x", &apt_data.id.product_id, NULL, verbose);
-+ if (err) return 0;
-+
-+ err = sysfs_get_attr_recursive(fd, "bcdDevice", "%x", &apt_data.id.version, NULL, verbose);
-+ if (err) return 0;
-+
-+ if (verbose)
-+ printf("APT: USB ID = 0x%04x:0x%04x (0x%03x)\n", apt_data.id.vendor_id, apt_data.id.product_id,
-+ apt_data.id.version);
-+
-+ /* We have all needed informations, let's find if we support that device*/
-+ for (i = 0; i < sizeof(apt_usb_id_map)/sizeof(*apt_usb_id_map); i++) {
-+ if (apt_data.id.vendor_id == apt_usb_id_map[i].vendor_id &&
-+ apt_data.id.product_id == apt_usb_id_map[i].product_id) {
-+ /* Maybe two devices with same vendor and product id -> use version*/
-+ if (apt_usb_id_map[i].version > 0 && apt_data.id.type &&
-+ apt_usb_id_map[i].version == apt_data.id.version) {
-+ apt_data.id.type = apt_usb_id_map[i].type;
-+ apt_data.id.init_func = apt_usb_id_map[i].init_func;
-+ apt_data.id.sg16_func = apt_usb_id_map[i].sg16_func;
-+ }
-+
-+ /* We don't have type -> set it (don't care about version) */
-+ if (!apt_data.id.type) {
-+ apt_data.id.type = apt_usb_id_map[i].type;
-+ apt_data.id.init_func = apt_usb_id_map[i].init_func;
-+ apt_data.id.sg16_func = apt_usb_id_map[i].sg16_func;
-+ }
-+ }
-+ }
-+
-+ if (!apt_data.id.type || apt_data.id.type == apt_ds_unsup) {
-+ if (verbose)
-+ printf("APT: Unsupported device\n");
-+
-+ return 0;
-+ }
-+
-+ apt_data.is_apt = 1;
-+ if (verbose)
-+ printf("APT: Found supported device %s\n", apt_data.id.type);
-+
-+ apt_data.verbose = verbose;
-+
-+ return (apt_data.id.init_func(fd));
-+}
-+
-+int apt_is_apt (void)
-+{
-+ return apt_data.is_apt;
-+}
-+
-+int apt_sg16(int fd, int rw, int dma, struct ata_tf *tf,
-+ void *data, unsigned int data_bytes, unsigned int timeout_secs)
-+{
-+ return apt_data.id.sg16_func(fd, rw, dma, tf, data, data_bytes, timeout_secs);
-+}
-+
-+static void dump_bytes (const char *prefix, unsigned char *p, int len)
-+{
-+ int i;
-+
-+ if (prefix)
-+ fprintf(stderr, "%s: ", prefix);
-+ for (i = 0; i < len; ++i)
-+ fprintf(stderr, " %02x", p[i]);
-+ fprintf(stderr, "\n");
-+}
-+
-+/***** JMicron support ********/
-+static int apt_jmicron_int_sg(int fd, int rw, int dma, struct ata_tf *tf,
-+ void *data, unsigned int data_bytes, unsigned int timeout_secs,
-+ int port)
-+{
-+ unsigned char cdb[12];
-+ struct scsi_sg_io_hdr io_hdr;
-+
-+ if (dma && apt_data.verbose)
-+ printf("APT: JMicron doesn't support DMA\n");
-+
-+ if (tf->is_lba48) {
-+ if (apt_data.verbose)
-+ fprintf(stderr, "APT: JMicron doesn't support 48-bit ATA commands\n");
-+ errno = EBADE;
-+ return -1;
-+ }
-+
-+ memset(&cdb, 0, sizeof(cdb));
-+ memset(&io_hdr, 0, sizeof(struct scsi_sg_io_hdr));
-+
-+ // Build pass through command
-+ cdb[ 0] = 0xdf;
-+ cdb[ 1] = (rw ? 0x00 : 0x10);
-+ cdb[ 2] = 0x00;
-+ cdb[ 3] = (unsigned char)((data ? data_bytes : 0) >> 8);
-+ cdb[ 4] = (unsigned char)((data ? data_bytes : 0) );
-+ cdb[ 5] = tf->lob.feat;
-+ cdb[ 6] = tf->lob.nsect;
-+ cdb[ 7] = tf->lob.lbal;
-+ cdb[ 8] = tf->lob.lbam;
-+ cdb[ 9] = tf->lob.lbah;
-+ cdb[10] = (port ? port : apt_data.jmicron.port);
-+ cdb[11] = tf->command;
-+
-+ io_hdr.interface_id = 'S';
-+ io_hdr.mx_sb_len = 0;
-+ io_hdr.dxfer_direction = data ? (rw ? SG_DXFER_TO_DEV : SG_DXFER_FROM_DEV) : SG_DXFER_NONE;
-+ io_hdr.dxfer_len = data ? data_bytes : 0;
-+ io_hdr.dxferp = data;
-+ io_hdr.cmdp = cdb;
-+ io_hdr.pack_id = tf_to_lba(tf);
-+ io_hdr.timeout = (timeout_secs ? timeout_secs : 5) * 1000; /* msecs */
-+ io_hdr.cmd_len = sizeof(cdb);
-+
-+ if (apt_data.verbose)
-+ dump_bytes("outgoing cdb", cdb, sizeof(cdb));
-+ if (ioctl(fd, SG_IO, &io_hdr) == -1) {
-+ if (apt_data.verbose)
-+ perror("ioctl(fd,SG_IO)");
-+ return -1; /* SG_IO not supported */
-+ }
-+ if (apt_data.verbose)
-+ fprintf(stderr, "SG_IO: ATA_%u status=0x%x, host_status=0x%x, driver_status=0x%x\n",
-+ io_hdr.cmd_len, io_hdr.status, io_hdr.host_status, io_hdr.driver_status);
-+
-+ if (io_hdr.host_status || io_hdr.driver_status) {
-+ errno = EBADE;
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
-+static int apt_jmicron_int_get_registers(int fd, unsigned short addr,
-+ unsigned char * buf, unsigned short size)
-+{
-+ struct ata_tf tf;
-+
-+ memset(&tf, 0, sizeof(tf));
-+
-+ tf.lob.feat = 0x00;
-+ tf.lob.nsect = (unsigned char)(addr >> 8);
-+ tf.lob.lbal = (unsigned char)(addr);
-+ tf.lob.lbam = 0x00;
-+ tf.lob.lbah = 0x00;
-+ tf.command = 0xfd;
-+
-+ return apt_jmicron_int_sg(fd, 0, 0, &tf, buf, (unsigned int)size, 0, 0x00);
-+}
-+
-+static int apt_jmicron_int_init(int fd)
-+{
-+ unsigned char regbuf = 0;
-+ int res;
-+
-+ if ((res = apt_jmicron_int_get_registers(fd, 0x720F, ®buf, 1)) == -1) {
-+ return res;
-+ }
-+
-+ if (regbuf & 0x04) {
-+ apt_data.jmicron.port = 0xa0;
-+ } else if (regbuf & 0x40) {
-+ apt_data.jmicron.port = 0xb0;
-+ } else {
-+ perror("APT: No JMicron device connected");
-+ errno = ENODEV;
-+ return -1;
-+ }
-+
-+ if (apt_data.verbose)
-+ printf("APT: JMicron Port: 0x%X\n", apt_data.jmicron.port);
-+ return 0;
-+}
-+
-+static int apt_jmicron_sg16(int fd, int rw, int dma, struct ata_tf *tf,
-+ void *data, unsigned int data_bytes, unsigned int timeout_secs)
-+{
-+ int res;
-+ unsigned char regs[16];
-+
-+ memset(regs, 0, sizeof(tf));
-+
-+ res = apt_jmicron_int_sg(fd, rw, dma, tf, data, data_bytes, timeout_secs, 0);
-+
-+ if (res == -1) return res;
-+
-+ if ((res = apt_jmicron_int_get_registers(fd,
-+ (apt_data.jmicron.port == 0xa0 ? 0x8000 : 0x9000), regs, sizeof(regs))) == -1) {
-+ return res;
-+ }
-+
-+ tf->is_lba48 = 0;
-+ tf->error = regs[13];
-+ tf->lob.nsect = regs[ 0];
-+ tf->lob.lbal = regs[ 6];
-+ tf->lob.lbam = regs[ 4];
-+ tf->lob.lbah = regs[10];
-+ tf->dev = regs[ 9];
-+ tf->status = regs[14];
-+ tf->hob.feat = 0;
-+ tf->hob.nsect = 0;
-+ tf->hob.lbal = 0;
-+ tf->hob.lbam = 0;
-+ tf->hob.lbah = 0;
-+
-+ if (apt_data.verbose)
-+ fprintf(stderr, " ATA_%u stat=%02x err=%02x nsect=%02x lbal=%02x lbam=%02x lbah=%02x dev=%02x\n",
-+ 12, tf->status, tf->error, tf->lob.nsect, tf->lob.lbal, tf->lob.lbam, tf->lob.lbah, tf->dev);
-+
-+ if (tf->status & (ATA_STAT_ERR | ATA_STAT_DRQ)) {
-+ if (apt_data.verbose) {
-+ fprintf(stderr, "I/O error, ata_op=0x%02x ata_status=0x%02x ata_error=0x%02x\n",
-+ tf->command, tf->status, tf->error);
-+ }
-+ errno = EIO;
-+ return -1;
-+ }
-+ return 0;
-+}
-+
-+#else
-+/* No SGIO -> no support*/
-+int apt_detect (int fd, int verbose)
-+{
-+ if (verbose)
-+ printf("APT: SGIO Support needed for fd %d\n", fd);
-+ return 0;
-+}
-+
-+int apt_is_apt (void)
-+{
-+ return 0;
-+}
-+
-+int apt_sg16(int fd, int rw, int dma, struct ata_tf *tf,
-+ void *data, unsigned int data_bytes, unsigned int timeout_secs)
-+{
-+ printf("APT: SG16 fd %d rw %d dma %d tf %p data %p data_bytes %d timeout %d need SGIO\n",
-+ fd, rw, dma, tf, data, data_bytes, timeout_secs);
-+ return -1;
-+}
-+#endif
-diff --git a/hdparm.c b/hdparm.c
-index f18ec6e..55d75bc 100644
---- a/hdparm.c
-+++ b/hdparm.c
-@@ -1194,6 +1194,13 @@ void process_dev (char *devname)
- if (!quiet)
- printf("\n%s:\n", devname);
-
-+ if (apt_detect(fd, verbose) == -1) {
-+ err = errno;
-+ perror(devname);
-+ close(fd);
-+ exit(err);
-+ }
-+
- if (set_fsreadahead) {
- if (get_fsreadahead)
- printf(" setting fs readahead to %d\n", fsreadahead);
-diff --git a/hdparm.h b/hdparm.h
-index 60a0045..0f38b16 100644
---- a/hdparm.h
-+++ b/hdparm.h
-@@ -21,6 +21,10 @@ int fwdownload(int fd, __u16 *id, const char *fwpath);
- void dco_identify_print (__u16 *dco);
- int set_dvdspeed(int fd, int speed);
-
-+/* APT Functions */
-+int apt_detect (int fd, int verbose);
-+int apt_is_apt (void);
-+
- extern const char *BuffType[4];
-
- struct local_hd_big_geometry {
-diff --git a/sgio.c b/sgio.c
-index e3de83e..18f3926 100644
---- a/sgio.c
-+++ b/sgio.c
-@@ -148,6 +148,10 @@ int sg16 (int fd, int rw, int dma, struct ata_tf *tf,
- unsigned char sb[32], *desc;
- struct scsi_sg_io_hdr io_hdr;
-
-+ if (apt_is_apt()) {
-+ return apt_sg16(fd, rw, dma, tf, data, data_bytes, timeout_secs);
-+ }
-+
- memset(&cdb, 0, sizeof(cdb));
- memset(&sb, 0, sizeof(sb));
- memset(&io_hdr, 0, sizeof(struct scsi_sg_io_hdr));
-diff --git a/sgio.h b/sgio.h
-index 7ad2d11..155c4d8 100644
---- a/sgio.h
-+++ b/sgio.h
-@@ -228,3 +228,7 @@ int do_taskfile_cmd (int fd, struct hdio_taskfile *r, unsigned int timeout_secs)
- int dev_has_sgio (int fd);
- void init_hdio_taskfile (struct hdio_taskfile *r, __u8 ata_op, int rw, int force_lba48,
- __u64 lba, unsigned int nsect, int data_bytes);
-+
-+/* APT */
-+int apt_sg16(int fd, int rw, int dma, struct ata_tf *tf,
-+ void *data, unsigned int data_bytes, unsigned int timeout_secs);
-diff --git a/sysfs.c b/sysfs.c
-index d21e678..fd51d5c 100644
---- a/sysfs.c
-+++ b/sysfs.c
-@@ -194,3 +194,64 @@ int sysfs_set_attr (int fd, const char *attr, const char *fmt, void *val_p, int
- err = sysfs_write_attr(path, attr, fmt, val_p, verbose);
- return err;
- }
-+
-+static int sysfs_find_attr_file_path (const char *start_path, char **dest_path, const char *attr)
-+{
-+ static char path[PATH_MAX];
-+ static char have_prev = 0;
-+ char file_path[PATH_MAX + FILENAME_MAX];
-+ struct stat st;
-+ ino_t stop_inode;
-+ int depth = 0;
-+
-+ if (have_prev) {
-+ *dest_path = path;
-+
-+ return 0;
-+ }
-+
-+ stat("/sys/devices", &st);
-+ stop_inode = st.st_ino;
-+
-+ strcpy(path, start_path);
-+
-+ while (depth < 20) {
-+ strcat(path, "/..");
-+
-+ if (stat(path, &st) != 0)
-+ return errno;
-+
-+ if (st.st_ino == stop_inode)
-+ return EINVAL;
-+
-+ strcpy(file_path, path);
-+ strcat(file_path, "/");
-+ strcat(file_path, attr);
-+
-+ if (access(file_path, F_OK | R_OK) == 0) {
-+ *dest_path = path;
-+
-+ return 0;
-+ }
-+ }
-+
-+ return EINVAL;
-+}
-+
-+int sysfs_get_attr_recursive (int fd, const char *attr, const char *fmt, void *val1, void *val2, int verbose)
-+{
-+ char *path;
-+ char *attr_path;
-+ int err;
-+
-+ err = sysfs_find_fd(fd, &path, verbose);
-+ if (!err) {
-+ err = sysfs_find_attr_file_path(path, &attr_path, attr);
-+
-+ if (!err) {
-+ err = sysfs_read_attr(attr_path, attr, fmt, val1, val2, verbose);
-+ }
-+ }
-+
-+ return err;
-+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.52/sysfs.c new/hdparm-9.56/sysfs.c
--- old/hdparm-9.52/sysfs.c 2017-05-01 21:07:50.000000000 +0200
+++ new/hdparm-9.56/sysfs.c 2018-03-15 20:27:21.000000000 +0100
@@ -15,6 +15,7 @@
#include <dirent.h>
#include <limits.h>
#include <sys/stat.h>
+#include <sys/sysmacros.h>
#include <linux/types.h>
#include "hdparm.h"
1
0
Hello community,
here is the log from the commit of package xfsprogs for openSUSE:Factory checked in at 2018-04-26 13:34:40
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/xfsprogs (Old)
and /work/SRC/openSUSE:Factory/.xfsprogs.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "xfsprogs"
Thu Apr 26 13:34:40 2018 rev:51 rq:599764 version:4.15.1
Changes:
--------
--- /work/SRC/openSUSE:Factory/xfsprogs/xfsprogs.changes 2018-03-12 12:08:01.555401854 +0100
+++ /work/SRC/openSUSE:Factory/.xfsprogs.new/xfsprogs.changes 2018-04-26 13:34:41.731415117 +0200
@@ -1,0 +2,15 @@
+Thu Apr 19 20:46:25 UTC 2018 - lurodriguez(a)suse.com
+
+- Fix SLE15 build (bsc#1090290) due to systemd. Systemd is present since
+ OpenSUSE Leap 42.1 and SLE12-SP1, so we need to ensure the build
+ has systemd available on these release. We also then need to indicate
+ the new files installed when on systemd. So this fixes the build issue
+ on SLE15 and also makes available the systemd service unit files now
+ on all releases which support systemd.
+
+-------------------------------------------------------------------
+Tue Apr 17 21:02:42 UTC 2018 - olaf(a)aepfle.de
+
+- xfsprogs-devel needs uuid/uuid.h, Require pkgconfig(uuid) (bsc#1089947)
+
+-------------------------------------------------------------------
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ xfsprogs.spec ++++++
--- /var/tmp/diff_new_pack.fZei7j/_old 2018-04-26 13:34:42.415390054 +0200
+++ /var/tmp/diff_new_pack.fZei7j/_new 2018-04-26 13:34:42.419389908 +0200
@@ -48,7 +48,11 @@
%endif
BuildRequires: xz
Requires(post): coreutils
-
+# Starting with OpenSUSE Leap 42.1 and SLE12-SP1 we get systemd
+%if 0%{?sle_version} >= 120100
+BuildRequires: pkgconfig
+BuildRequires: pkgconfig(systemd)
+%endif
%description
A set of commands to use the XFS file system, including mkfs.xfs.
@@ -67,6 +71,7 @@
Summary: XFS Filesystem-specific Static Libraries and Headers
Group: Development/Libraries/C and C++
Requires: xfsprogs = %{version}
+Requires: pkgconfig(uuid)
%description devel
xfsprogs-devel contains the libraries and header files needed to
@@ -90,7 +95,10 @@
export OPTIMIZER="-fPIC"
export DEBUG=-DNDEBUG
export LIBUUID=%{_libdir}/libuuid.a
-%configure --enable-readline=yes
+%if 0%{?sle_version} >= 120100
+export USE_SYSTEMD="--with-systemd-unit-dir=%{_unitdir}"
+%endif
+%configure --enable-readline=yes $USE_SYSTEMD
make %{?_smp_mflags} V=1
PATH_TO_HELP="%{_dracutmodulesdir}/95suse-xfs/dracut-fsck-help.txt"
@@ -137,6 +145,13 @@
%{_libdir}/libhandle.so.*
%dir %{_libdir}/xfsprogs/
%{_libdir}/xfsprogs/xfs_scrub_all.cron
+%if 0%{?sle_version} >= 120100
+%{_libdir}/xfsprogs/xfs_scrub_fail
+%{_unitdir}/xfs_scrub@.service
+%{_unitdir}/xfs_scrub_all.service
+%{_unitdir}/xfs_scrub_all.timer
+%{_unitdir}/xfs_scrub_fail@.service
+%endif
%doc %{_mandir}/man[258]/*
%doc %{_defaultdocdir}/%{name}
%dir %{_libexecdir}/dracut
1
0
Hello community,
here is the log from the commit of package python-pytest-mock for openSUSE:Factory checked in at 2018-04-26 13:34:36
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pytest-mock (Old)
and /work/SRC/openSUSE:Factory/.python-pytest-mock.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pytest-mock"
Thu Apr 26 13:34:36 2018 rev:6 rq:599637 version:1.9.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pytest-mock/python-pytest-mock.changes 2018-03-05 13:36:19.603267363 +0100
+++ /work/SRC/openSUSE:Factory/.python-pytest-mock.new/python-pytest-mock.changes 2018-04-26 13:34:37.675563733 +0200
@@ -1,0 +2,11 @@
+Sat Apr 21 16:39:10 UTC 2018 - arun(a)gmx.de
+
+- update to version 1.9.0:
+ * Add support for the recently added assert_called_once method in
+ Python 3.6 and mock-2.0. Thanks @rouge8 for the PR (#113).
+
+- changes from version 1.8.0:
+ * Add aliases for NonCallableMock and create_autospec to
+ mocker. Thanks @mlhamel for the PR (#111).
+
+-------------------------------------------------------------------
Old:
----
pytest-mock-1.7.1.tar.gz
New:
----
pytest-mock-1.9.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-pytest-mock.spec ++++++
--- /var/tmp/diff_new_pack.2P8m4H/_old 2018-04-26 13:34:38.191544827 +0200
+++ /var/tmp/diff_new_pack.2P8m4H/_new 2018-04-26 13:34:38.195544680 +0200
@@ -18,16 +18,15 @@
%define oldpython python
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
-%define modname pytest-mock
%bcond_without python2
-Name: python-%{modname}
-Version: 1.7.1
+Name: python-pytest-mock
+Version: 1.9.0
Release: 0
Summary: Thin-wrapper around the mock package for easier use with pytest
License: MIT
Group: Development/Languages/Python
-Url: https://github.com/pytest-dev/%{modname}
-Source: https://files.pythonhosted.org/packages/source/p/pytest-mock/%{modname}-%{v…
+URL: https://github.com/pytest-dev/pytest-mock
+Source: https://files.pythonhosted.org/packages/source/p/pytest-mock/pytest-mock-%{…
BuildRequires: %{python_module pytest}
BuildRequires: %{python_module setuptools >= 36}
BuildRequires: %{python_module setuptools_scm}
@@ -52,7 +51,7 @@
of a test
%prep
-%setup -q -n %{modname}-%{version}
+%setup -q -n pytest-mock-%{version}
%build
%python_build
++++++ pytest-mock-1.7.1.tar.gz -> pytest-mock-1.9.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-mock-1.7.1/CHANGELOG.rst new/pytest-mock-1.9.0/CHANGELOG.rst
--- old/pytest-mock-1.7.1/CHANGELOG.rst 2018-03-01 11:53:08.000000000 +0100
+++ new/pytest-mock-1.9.0/CHANGELOG.rst 2018-04-10 04:43:04.000000000 +0200
@@ -1,3 +1,18 @@
+1.9.0
+-----
+
+* Add support for the recently added ``assert_called_once`` method in Python 3.6 and ``mock-2.0``. Thanks `@rouge8`_ for the PR (`#113`_).
+
+.. _#113: https://github.com/pytest-dev/pytest-mock/pull/113
+
+
+1.8.0
+-----
+
+* Add aliases for ``NonCallableMock`` and ``create_autospec`` to ``mocker``. Thanks `@mlhamel`_ for the PR (`#111`_).
+
+.. _#111: https://github.com/pytest-dev/pytest-mock/pull/111
+
1.7.1
-----
@@ -300,13 +315,14 @@
.. _#2: https://github.com/pytest-dev/pytest-qt/issues/2
-.. _@mathrick: https://github.com/mathrick
-.. _@tigarmo: https://github.com/tigarmo
-.. _@rouge8: https://github.com/rouge8
.. _@fogo: https://github.com/fogo
+.. _@kmosher: https://github.com/kmosher
.. _@marcwebbie: https://github.com/marcwebbie
+.. _@mathrick: https://github.com/mathrick
+.. _@mlhamel: https://github.com/mlhamel
.. _@RonnyPfannschmidt: https://github.com/RonnyPfannschmidt
+.. _@rouge8: https://github.com/rouge8
.. _@The-Compiler: https://github.com/The-Compiler
-.. _@kmosher: https://github.com/kmosher
+.. _@tigarmo: https://github.com/tigarmo
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-mock-1.7.1/PKG-INFO new/pytest-mock-1.9.0/PKG-INFO
--- old/pytest-mock-1.7.1/PKG-INFO 2018-03-01 11:53:25.000000000 +0100
+++ new/pytest-mock-1.9.0/PKG-INFO 2018-04-10 04:43:24.000000000 +0200
@@ -1,12 +1,11 @@
Metadata-Version: 1.2
Name: pytest-mock
-Version: 1.7.1
+Version: 1.9.0
Summary: Thin-wrapper around the mock package for easier use with py.test
Home-page: https://github.com/pytest-dev/pytest-mock/
Author: Bruno Oliveira
Author-email: nicoddemus(a)gmail.com
License: MIT
-Description-Content-Type: UNKNOWN
Description: ===========
pytest-mock
===========
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-mock-1.7.1/_pytest_mock_version.py new/pytest-mock-1.9.0/_pytest_mock_version.py
--- old/pytest-mock-1.7.1/_pytest_mock_version.py 2018-03-01 11:53:25.000000000 +0100
+++ new/pytest-mock-1.9.0/_pytest_mock_version.py 2018-04-10 04:43:24.000000000 +0200
@@ -1,4 +1,4 @@
# coding: utf-8
# file generated by setuptools_scm
# don't change, don't track in version control
-version = '1.7.1'
+version = '1.9.0'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-mock-1.7.1/pytest_mock.egg-info/PKG-INFO new/pytest-mock-1.9.0/pytest_mock.egg-info/PKG-INFO
--- old/pytest-mock-1.7.1/pytest_mock.egg-info/PKG-INFO 2018-03-01 11:53:25.000000000 +0100
+++ new/pytest-mock-1.9.0/pytest_mock.egg-info/PKG-INFO 2018-04-10 04:43:24.000000000 +0200
@@ -1,12 +1,11 @@
Metadata-Version: 1.2
Name: pytest-mock
-Version: 1.7.1
+Version: 1.9.0
Summary: Thin-wrapper around the mock package for easier use with py.test
Home-page: https://github.com/pytest-dev/pytest-mock/
Author: Bruno Oliveira
Author-email: nicoddemus(a)gmail.com
License: MIT
-Description-Content-Type: UNKNOWN
Description: ===========
pytest-mock
===========
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-mock-1.7.1/pytest_mock.py new/pytest-mock-1.9.0/pytest_mock.py
--- old/pytest-mock-1.7.1/pytest_mock.py 2018-03-01 11:53:08.000000000 +0100
+++ new/pytest-mock-1.9.0/pytest_mock.py 2018-04-10 04:43:04.000000000 +0200
@@ -48,10 +48,12 @@
# aliases for convenience
self.Mock = mock_module.Mock
self.MagicMock = mock_module.MagicMock
+ self.NonCallableMock = mock_module.NonCallableMock
self.PropertyMock = mock_module.PropertyMock
self.call = mock_module.call
self.ANY = mock_module.ANY
self.DEFAULT = mock_module.DEFAULT
+ self.create_autospec = mock_module.create_autospec
self.sentinel = mock_module.sentinel
self.mock_open = mock_module.mock_open
@@ -219,6 +221,12 @@
*args, **kwargs)
+def wrap_assert_called_once(*args, **kwargs):
+ __tracebackhide__ = True
+ assert_wrapper(_mock_module_originals["assert_called_once"],
+ *args, **kwargs)
+
+
def wrap_assert_called_once_with(*args, **kwargs):
__tracebackhide__ = True
assert_wrapper(_mock_module_originals["assert_called_once_with"],
@@ -252,6 +260,7 @@
'assert_not_called': wrap_assert_not_called,
'assert_called_with': wrap_assert_called_with,
'assert_called_once_with': wrap_assert_called_once_with,
+ 'assert_called_once': wrap_assert_called_once,
'assert_has_calls': wrap_assert_has_calls,
'assert_any_call': wrap_assert_any_call,
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-mock-1.7.1/test_pytest_mock.py new/pytest-mock-1.9.0/test_pytest_mock.py
--- old/pytest-mock-1.7.1/test_pytest_mock.py 2018-03-01 11:53:08.000000000 +0100
+++ new/pytest-mock-1.9.0/test_pytest_mock.py 2018-04-10 04:43:04.000000000 +0200
@@ -137,7 +137,7 @@
assert os.listdir(str(tmpdir)) == []
-(a)pytest.mark.parametrize('name', ['MagicMock', 'PropertyMock', 'Mock', 'call', 'ANY', 'sentinel', 'mock_open'])
+(a)pytest.mark.parametrize('name', ['MagicMock', 'NonCallableMock', 'PropertyMock', 'Mock', 'call', 'ANY', 'create_autospec', 'sentinel', 'mock_open'])
def test_mocker_aliases(name, pytestconfig):
from pytest_mock import _get_mock_module, MockFixture
@@ -388,6 +388,17 @@
stub.assert_called_once_with("foo")
+def test_assert_called_once_wrapper(mocker):
+ stub = mocker.stub()
+ if not hasattr(stub, 'assert_called_once'):
+ pytest.skip('assert_called_once not available')
+ stub("foo")
+ stub.assert_called_once()
+ stub("foo")
+ with assert_traceback():
+ stub.assert_called_once()
+
+
@pytest.mark.usefixtures('needs_assert_rewrite')
def test_assert_called_args_with_introspection(mocker):
stub = mocker.stub()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-mock-1.7.1/tox.ini new/pytest-mock-1.9.0/tox.ini
--- old/pytest-mock-1.7.1/tox.ini 2018-03-01 11:53:08.000000000 +0100
+++ new/pytest-mock-1.9.0/tox.ini 2018-04-10 04:43:04.000000000 +0200
@@ -1,15 +1,12 @@
[tox]
-envlist = py{27,34,35,36}-pytest{30,31,32,33,34},linting,norewrite
+envlist = py{27,34,35,36}-pytest{34,35},linting,norewrite
[testenv]
passenv = USER USERNAME
deps =
coverage
- pytest30: pytest~=3.0
- pytest31: pytest~=3.1
- pytest32: pytest~=3.2
- pytest33: pytest~=3.3
pytest34: pytest~=3.4
+ pytest35: pytest~=3.5
commands =
coverage run --append --source=pytest_mock.py -m pytest test_pytest_mock.py
@@ -21,8 +18,8 @@
skip_install=True
deps =
pytest-flakes
- restructuredtext_lint
+ restructuredtext_lint
pygments
commands =
py.test --flakes pytest_mock.py test_pytest_mock.py -m flakes
- rst-lint CHANGELOG.rst README.rst
+ rst-lint CHANGELOG.rst README.rst
1
0
Hello community,
here is the log from the commit of package kdump for openSUSE:Factory checked in at 2018-04-26 13:34:30
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/kdump (Old)
and /work/SRC/openSUSE:Factory/.kdump.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "kdump"
Thu Apr 26 13:34:30 2018 rev:98 rq:599443 version:0.8.16
Changes:
--------
--- /work/SRC/openSUSE:Factory/kdump/kdump.changes 2018-04-07 20:55:07.670580126 +0200
+++ /work/SRC/openSUSE:Factory/.kdump.new/kdump.changes 2018-04-26 13:34:32.887739170 +0200
@@ -1,0 +2,8 @@
+Fri Apr 20 16:06:40 UTC 2018 - ptesarik(a)suse.com
+
+- kdump-additional-mounts-in-dracut-module.patch: Handle additional
+ mounts in the kdump dracut module (bsc#1089917).
+- kdump-run-mkinitrd-if-fadump-is-active.patch: Run mkinitrd if
+ fadump is active (bsc#1089917).
+
+-------------------------------------------------------------------
New:
----
kdump-additional-mounts-in-dracut-module.patch
kdump-run-mkinitrd-if-fadump-is-active.patch
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ kdump.spec ++++++
--- /var/tmp/diff_new_pack.62fPnB/_old 2018-04-26 13:34:34.259688899 +0200
+++ /var/tmp/diff_new_pack.62fPnB/_new 2018-04-26 13:34:34.259688899 +0200
@@ -96,6 +96,8 @@
Patch47: %{name}-pass-all-IP-routes-to-kdump-environment.patch
Patch48: %{name}-remove-IPv6-brackets-for-getaddrinfo.patch
Patch49: %{name}-skip-IPv4-if-no-address.patch
+Patch50: %{name}-additional-mounts-in-dracut-module.patch
+Patch51: %{name}-run-mkinitrd-if-fadump-is-active.patch
BuildRequires: asciidoc
BuildRequires: cmake
BuildRequires: gcc-c++
@@ -207,6 +209,8 @@
%patch47 -p1
%patch48 -p1
%patch49 -p1
+%patch50 -p1
+%patch51 -p1
%build
export CFLAGS="%{optflags}"
++++++ kdump-additional-mounts-in-dracut-module.patch ++++++
From: Petr Tesarik <ptesarik(a)suse.com>
Date: Fri, 20 Apr 2018 17:26:22 +0200
Subject: Handle additional mounts in the kdump dracut module
References: bsc#1089917
Upstream: merged
Git-commit: bd3cc31f3b91e81e6acc00f314142bbda9ace495
This change is needed to fix FADUMP, because in that case the kdump
initrd is also used during normal boot, so it can get overwritten
with an invocation of "mkinitrd".
Currently, dracut does not provide an API to add more mounts from a
module, so part of the logic which sets up host devices and
filesystem mappings must be copied to the kdump module.
The approach is not clean, but probably still better than passing
some variables from mkdumprd to the kdump dracut module through
environment variables, which was done before. Yes, this means that
the ugly export/import functions can be removed and forgotten.
Signed-off-by: Petr Tesarik <ptesarik(a)suse.com>
---
init/mkdumprd | 14 --------
init/module-setup.sh | 75 +++++++++++++++++++++++++++++++++++++--------
init/setup-kdump.functions | 53 -------------------------------
3 files changed, 62 insertions(+), 80 deletions(-)
--- a/init/mkdumprd
+++ b/init/mkdumprd
@@ -128,20 +128,6 @@ function run_dracut()
KERNELVERSION=$(get_kernel_version "$KERNEL")
fi
- # add mount points
- kdump_get_mountpoints || return 1
- i=0
- while [ $i -lt ${#kdump_mnt[@]} ]
- do
- if [ -n "${kdump_mnt[i]}" ] ; then
- DRACUT_ARGS="$DRACUT_ARGS --mount '${kdump_dev[i]} ${kdump_mnt[i]} ${kdump_fstype[i]} ${kdump_opts[i]}'"
- fi
- i=$((i+1))
- done
-
- # Make resolved variables visible to the dracut module
- kdump_export_targets
-
DRACUT_ARGS="$DRACUT_ARGS --add 'kdump' $INITRD $KERNELVERSION"
echo "Regenerating kdump initrd ..." >&2
eval "bash -$- $DRACUT $DRACUT_ARGS"
--- a/init/module-setup.sh
+++ b/init/module-setup.sh
@@ -45,10 +45,71 @@ kdump_check_net() {
kdump_ifname_config "$kdump_host_if"
}
+kdump_get_fs_type() {
+ local _dev="/dev/block/$1"
+ local _fstype
+ if [ -b "$_dev" ] && _fstype=$(get_fs_env "$_dev") ; then
+ host_fs_types["$(readlink -f "$_dev")"]="$_fstype"
+ elif _fstype=$(find_dev_fstype "$_dev"); then
+ host_fs_types["$_dev"]="$_fstype"
+ fi
+ return 1
+}
+
+kdump_add_host_dev() {
+ local _dev=$1
+ [[ " ${host_devs[@]} " == *" $_dev "* ]] && return
+ host_devs+=( "$_dev" )
+ check_block_and_slaves_all kdump_get_fs_type "$(get_maj_min "$_dev")"
+}
+
+kdump_add_mnt() {
+ local _idx=$1
+ local _dev="${kdump_dev[_idx]}"
+ local _mp="${kdump_mnt[_idx]}"
+
+ # Convert system root mounts to bind mounts
+ if [ "$KDUMP_FADUMP" = "yes" -a "${_mp%/*}" = "/kdump" ] ; then
+ mkdir -p "$initdir/etc"
+ echo "/sysroot $_mp none bind 0 0" >> "$initdir/etc/fstab"
+ return
+ fi
+
+ case "$_dev" in
+ UUID=*|LABEL=*|PARTUUID=*|PARTLABLE=*)
+ _dev=$(blkid -l -t "$_dev" -o device)
+ ;;
+ esac
+ kdump_add_host_dev "$_dev"
+ host_fs_types["$_dev"]="${kdump_fstype[_idx]}"
+ if [ "${kdump_fstype[_idx]}" = btrfs ] ; then
+ for _dev in $() ; do
+ kdump_add_host_dev "$_dev"
+ done
+ fi
+
+ mkdir -p "$initdir/etc"
+ local _passno=2
+ [ "${kdump_fstype[_idx]}" = nfs ] && _passno=0
+ echo "${kdump_dev[_idx]} ${kdump_mnt[_idx]} ${kdump_fstype[_idx]} ${kdump_opts[_idx]} 0 $_passno" >> "$initdir/etc/fstab"
+}
+
check() {
# Get configuration
- kdump_import_targets || return 1
kdump_get_config || return 1
+
+ # add mount points
+ if ! [[ $mount_needs ]] ; then
+ kdump_get_mountpoints || return 1
+
+ local _i=0
+ while [ $_i -lt ${#kdump_mnt[@]} ]
+ do
+ [ -n "${kdump_mnt[_i]}" ] && kdump_add_mnt $_i
+ _i=$((_i+1))
+ done
+ fi
+
kdump_check_net
return 255
@@ -188,18 +249,6 @@ install() {
kdump_map_mpath_wwid
for_each_host_dev_and_slaves_all kdump_add_mpath_dev
- # Convert system root mounts to bind mounts
- if [ "$KDUMP_FADUMP" = "yes" ] ; then
- local i line
- for i in "${!fstab_lines[@]}"
- do
- line=( ${fstab_lines[i]} )
- if [ "${line[1]%/*}" = "/kdump" ] ; then
- fstab_lines[i]="/sysroot ${line[1]} none bind 0 0"
- fi
- done
- fi
-
kdump_setup_files "$initdir" "$kdump_mpath_wwids"
inst_hook cmdline 50 "$moddir/kdump-root.sh"
--- a/init/setup-kdump.functions
+++ b/init/setup-kdump.functions
@@ -666,59 +666,6 @@ function kdump_get_targets() # {
} # }}}
#
-# Print array content so that it can be used as bash input
-#
-# Parameters:
-# 1) name array variable to be printed
-# Output:
-# shell code that can be passed to eval to restore the array
-function kdump_print_array()
-{
- local name="$1"
- local i
- echo -n "( "
- for i in $(eval printf \"%q \" \"\${!$name[@]}\")
- do
- printf "[%s]=%q " "$i" "$(eval echo \"\${$name[i]}\")"
- done
- echo ")"
-}
-
-#
-# Export kdump_*[] arrays, returned by kdump_get_targets.
-#
-# Input variables:
-# kdump_URL[], kdump_Protocol[], kdump_Host[], kdump_Realpath,
-# kdump_mnt[]
-# Output variables (exported):
-# KDUMP_x_URL, KDUMP_x_Protocol, KDUMP_x_Host, KDUMP_x_Realpath,
-# KDUMP_x_mnt
-function kdump_export_targets() # {{{
-{
- export KDUMP_x_URL=$( kdump_print_array kdump_URL )
- export KDUMP_x_Protocol=$( kdump_print_array kdump_Protocol )
- export KDUMP_x_Host=$( kdump_print_array kdump_Host )
- export KDUMP_x_Realpath=$( kdump_print_array kdump_Realpath )
- export KDUMP_x_mnt=$( kdump_print_array kdump_mnt )
- export kdump_max
-} # }}}
-
-#
-# Import kdump_*[] arrays from environment.
-#
-# Input/Output Variables:
-# reverse of kdump_export_arrays
-function kdump_import_targets() # {{{
-{
- eval "kdump_URL=$KDUMP_x_URL"
- eval "kdump_Protocol=$KDUMP_x_Protocol"
- eval "kdump_Host=$KDUMP_x_Host"
- eval "kdump_Realpath=$KDUMP_x_Realpath"
- eval "kdump_mnt=$KDUMP_x_mnt"
- test ${#kdump_URL[@]} -gt 0
-} # }}}
-
-#
# Read and normalize /etc/fstab and /proc/mounts (if exists).
# The following transformations are done:
# - initial TABs and SPACEs are removed
++++++ kdump-run-mkinitrd-if-fadump-is-active.patch ++++++
From: Petr Tesarik <ptesarik(a)suse.com>
Date: Fri, 20 Apr 2018 17:54:19 +0200
Subject: Run mkinitrd if fadump is active
References: bsc#1089917
Upstream: merged
Git-commit: a25562cb0ff7d2b6d6df2dded8bd29c2e4d7e9ea
With fadump, the default initrd is used. It is better to call the
normal mkinitrd script to achieve consistent behaviour between
updates triggered by kdump and other changes that may require a
rebuild of the initrd.
Signed-off-by: Petr Tesarik <ptesarik(a)suse.com>
---
init/mkdumprd | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
--- a/init/mkdumprd
+++ b/init/mkdumprd
@@ -117,6 +117,25 @@ function run_mkinitrd()
} # }}}
#
+# Create a new fadump initrd using mkinitrd {{{
+function run_mkinitrd_fadump()
+{
+ # With fadump, we have no control over which kernel will be booted
+ # to save the dump, so do not add any versions here.
+ MKINITRD_ARGS=""
+
+ #
+ # if -q is specified, don't print mkinitrd output
+ if (( $QUIET )) ; then
+ MKINITRD_ARGS="$MKINITRD_ARGS &>/dev/null"
+ fi
+
+ status_message "Calling mkinitrd $MKINITRD_ARGS"
+ echo "Regenerating initrd ..." >&2
+ eval "bash -$- /sbin/mkinitrd $MKINITRD_ARGS"
+} # }}}
+
+#
# Create a new initrd using dracut {{{
function run_dracut()
{
@@ -219,7 +238,11 @@ if (( ! $FORCE )) ; then
fi
if [ -e $DRACUT ] ; then
- run_dracut
+ if [ "$KDUMP_FADUMP" = "yes" ] ; then
+ run_mkinitrd_fadump
+ else
+ run_dracut
+ fi
ret=$?
else
run_mkinitrd
1
0
Hello community,
here is the log from the commit of package python-pip for openSUSE:Factory checked in at 2018-04-26 13:34:24
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pip (Old)
and /work/SRC/openSUSE:Factory/.python-pip.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pip"
Thu Apr 26 13:34:24 2018 rev:36 rq:599442 version:10.0.1
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pip/python-pip.changes 2017-04-19 18:04:56.843733237 +0200
+++ /work/SRC/openSUSE:Factory/.python-pip.new/python-pip.changes 2018-04-26 13:34:26.623968687 +0200
@@ -1,0 +2,8 @@
+Fri Apr 20 07:48:59 UTC 2018 - mimi.vx(a)gmail.com
+
+- update to 10.0.1
+- refactor pip-8.1.2-shipped-requests-cabundle.patch
+ * Switch the default repository to the new "PyPI 2.0" running at https://pypi.org/
+ * big bunch of changes from 9.0.1 in NEWS.rst
+
+-------------------------------------------------------------------
Old:
----
pip-9.0.1.tar.gz
New:
----
pip-10.0.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-pip.spec ++++++
--- /var/tmp/diff_new_pack.vWZh54/_old 2018-04-26 13:34:27.327942892 +0200
+++ /var/tmp/diff_new_pack.vWZh54/_new 2018-04-26 13:34:27.327942892 +0200
@@ -1,7 +1,7 @@
#
# spec file for package python-pip
#
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -16,41 +16,41 @@
#
+%{?!python_module:%define python_module() python-%{**} python3-%{**}}
# NOTE(saschpe): git invocation and pythonpath issues with testrepository
# enable testing with a build conditional (off by default):
%bcond_with test
-
-%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-pip
-Version: 9.0.1
+Version: 10.0.1
Release: 0
-Url: http://www.pip-installer.org
Summary: Pip installs packages. Python packages. An easy_install replacement
License: MIT
Group: Development/Languages/Python
-Source: https://pypi.io/packages/source/p/pip/pip-%{version}.tar.gz
+URL: http://www.pip-installer.org
+Source: https://files.pythonhosted.org/packages/source/p/pip/pip-%{version}.tar.gz
Patch0: pip-8.1.2-shipped-requests-cabundle.patch
-BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildRequires: %{python_module devel}
BuildRequires: %{python_module setuptools}
BuildRequires: fdupes
BuildRequires: python-rpm-macros
-%if %{with test}
-# Test requirements:
-BuildRequires: %{python_module mock}
-BuildRequires: %{python_module pytest}
-BuildRequires: %{python_module scripttest >= 1.3}
-BuildRequires: %{python_module virtualenv >= 1.10}
-%endif
Requires: ca-certificates
Requires: coreutils
Requires: python-setuptools
Requires: python-xml
-Recommends: ca-certificates-mozilla
Requires(post): update-alternatives
Requires(postun): update-alternatives
+Recommends: ca-certificates-mozilla
BuildArch: noarch
-
+%if %{with test}
+# Test requirements:
+BuildRequires: %{python_module docutils}
+BuildRequires: %{python_module freezegun}
+BuildRequires: %{python_module mock}
+BuildRequires: %{python_module pretend}
+BuildRequires: %{python_module pytest}
+BuildRequires: %{python_module scripttest >= 1.3}
+BuildRequires: %{python_module virtualenv >= 1.10}
+%endif
%python_subpackages
%description
@@ -58,14 +58,13 @@
finding packages, so packages that were made easy_installable should be
pip-installable as well.
-
%prep
%setup -q -n pip-%{version}
%patch0 -p1
-find pip/_vendor -name *.py -exec \
- sed -i "s|#!/usr/bin/env python||g" {} ";" # Fix non-executable script
+find src/pip/_vendor -name *.py -exec \
+ sed -i "s|#!%{_bindir}/env python||g" {} ";" # Fix non-executable script
#sed -i "s|#!/usr/bin/env python||g" pip/__init__.py # Fix non-executable script
-rm pip/_vendor/requests/cacert.pem
+rm src/pip/_vendor/certifi/cacert.pem
%build
%python_build
@@ -77,7 +76,7 @@
%if %{with test}
%check
-%python_exec setup.py test
+%python_expand py.test-%{$python_version}
%endif
%pre
@@ -102,8 +101,8 @@
%endif
%files %{python_files}
-%defattr(-,root,root,-)
-%doc AUTHORS.txt CHANGES.txt LICENSE.txt README.rst
+%license LICENSE.txt
+%doc AUTHORS.txt NEWS.rst README.rst
%{_bindir}/pip
%python2_only %{_bindir}/pip2
%python3_only %{_bindir}/pip3
++++++ pip-9.0.1.tar.gz -> pip-10.0.1.tar.gz ++++++
++++ 201708 lines of diff (skipped)
++++++ pip-8.1.2-shipped-requests-cabundle.patch ++++++
--- /var/tmp/diff_new_pack.vWZh54/_old 2018-04-26 13:34:27.699929262 +0200
+++ /var/tmp/diff_new_pack.vWZh54/_new 2018-04-26 13:34:27.703929116 +0200
@@ -1,13 +1,24 @@
-diff -ruN a/pip/_vendor/requests/certs.py b/pip/_vendor/requests/certs.py
---- a/pip/_vendor/requests/certs.py 2014-05-16 20:03:31.000000000 +0200
-+++ b/pip/_vendor/requests/certs.py 2014-07-03 09:54:46.751966582 +0200
-@@ -19,8 +19,7 @@
- except ImportError:
- def where():
- """Return the preferred certificate bundle."""
-- # vendored bundle inside Requests
-- return os.path.join(os.path.dirname(__file__), 'cacert.pem')
-+ return "/etc/ssl/ca-bundle.pem"
-
- if __name__ == '__main__':
- print(where())
+Index: pip-10.0.1/src/pip/_vendor/certifi/core.py
+===================================================================
+--- pip-10.0.1.orig/src/pip/_vendor/certifi/core.py
++++ pip-10.0.1/src/pip/_vendor/certifi/core.py
+@@ -7,7 +7,6 @@ certifi.py
+
+ This module returns the installation location of cacert.pem.
+ """
+-import os
+ import warnings
+
+
+@@ -19,10 +18,7 @@ class DeprecatedBundleWarning(Deprecatio
+
+
+ def where():
+- f = os.path.dirname(__file__)
+-
+- return os.path.join(f, 'cacert.pem')
+-
++ return '/etc/ssl/ca-bundle.pem'
+
+ def old_where():
+ warnings.warn(
1
0
Hello community,
here is the log from the commit of package perl-Text-BibTeX for openSUSE:Factory checked in at 2018-04-26 13:34:18
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/perl-Text-BibTeX (Old)
and /work/SRC/openSUSE:Factory/.perl-Text-BibTeX.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-Text-BibTeX"
Thu Apr 26 13:34:18 2018 rev:12 rq:599331 version:0.85
Changes:
--------
--- /work/SRC/openSUSE:Factory/perl-Text-BibTeX/perl-Text-BibTeX.changes 2017-06-25 19:20:39.896723382 +0200
+++ /work/SRC/openSUSE:Factory/.perl-Text-BibTeX.new/perl-Text-BibTeX.changes 2018-04-26 13:34:19.992211686 +0200
@@ -1,0 +2,26 @@
+Fri Apr 13 05:20:31 UTC 2018 - werner(a)suse.de
+
+- updated to 0.85
+ see /usr/share/doc/packages/perl-Text-BibTeX/Changes
+
+ 0.85 2017-08-31
+ * FreeBSD includes a definition of strlcat, so no need to redefine it.
+
+ 0.84 2017-08-31
+ * Further buffer overflow fixes.
+ * Spellchecking fixes by Julián Moreno Patiño, Lucas Kanashiro, and
+ Gregor Herrmann (debian community)
+
+ 0.83 2017-08-28
+ * Remove unecessary depedency to YAML.
+ * Fix further buffer overflow situations.
+
+ 0.82 2017-08-27
+ * Fix buffer overflow (thanks to Hamid Ebadi).
+ * Hide error messages on tests, and use them for testing purposes.
+
+ 0.81 2017-07-19
+ * Fix issue with NameFormat and unitialized join-tokens.
+ (thanks to Karl Wette for the bug report).
+
+-------------------------------------------------------------------
Old:
----
Text-BibTeX-0.80.tar.gz
New:
----
Text-BibTeX-0.85.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ perl-Text-BibTeX.spec ++++++
--- /var/tmp/diff_new_pack.FI3GiI/_old 2018-04-26 13:34:20.548191314 +0200
+++ /var/tmp/diff_new_pack.FI3GiI/_new 2018-04-26 13:34:20.552191167 +0200
@@ -1,7 +1,7 @@
#
# spec file for package perl-Text-BibTeX
#
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -17,11 +17,11 @@
Name: perl-Text-BibTeX
-Version: 0.80
+Version: 0.85
Release: 0
%define cpan_name Text-BibTeX
Summary: Interface to Read and Parse BibTeX Files
-License: Artistic-1.0 or GPL-1.0+
+License: Artistic-1.0 OR GPL-1.0-or-later
Group: Development/Libraries/Perl
Url: http://search.cpan.org/dist/Text-BibTeX/
Source0: https://cpan.metacpan.org/authors/id/A/AM/AMBS/%{cpan_name}-%{version}.tar.…
++++++ Text-BibTeX-0.80.tar.gz -> Text-BibTeX-0.85.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/Changes new/Text-BibTeX-0.85/Changes
--- old/Text-BibTeX-0.80/Changes 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/Changes 2017-08-31 12:35:39.000000000 +0200
@@ -1,5 +1,25 @@
Revision history for Perl module Text::BibTeX
+0.85 2017-08-31
+ * FreeBSD includes a definition of strlcat, so no need to redefine it.
+
+0.84 2017-08-31
+ * Further buffer overflow fixes.
+ * Spellchecking fixes by Julián Moreno Patiño, Lucas Kanashiro, and
+ Gregor Herrmann (debian community)
+
+0.83 2017-08-28
+ * Remove unecessary depedency to YAML.
+ * Fix further buffer overflow situations.
+
+0.82 2017-08-27
+ * Fix buffer overflow (thanks to Hamid Ebadi).
+ * Hide error messages on tests, and use them for testing purposes.
+
+0.81 2017-07-19
+ * Fix issue with NameFormat and unitialized join-tokens.
+ (thanks to Karl Wette for the bug report).
+
0.80 2017-03-25
* Fix tests in order to work without dot in @INC (thanks Kent Fredric for the bug report)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/MANIFEST new/Text-BibTeX-0.85/MANIFEST
--- old/Text-BibTeX-0.80/MANIFEST 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/MANIFEST 2017-08-31 12:35:39.000000000 +0200
@@ -29,7 +29,7 @@
lib/Text/BibTeX/BibFormat.pm
lib/Text/BibTeX/BibSort.pm
-## t/00.init.t
+t/00_system_info.t
t/common.pl
t/bib.t
t/macro.t
@@ -43,7 +43,11 @@
t/parse_s.t
t/purify.t
t/split_names
-## t/zz.cleanup.t
+t/unlimited.bib
+t/unlimited.t
+t/corpora.bib
+t/errors.bib
+t/from_file.t
examples/append_entries
@@ -150,6 +154,3 @@
README.OLD
META.json
MANIFEST.SKIP
-t/corpora.bib
-t/errors.bib
-t/from_file.t
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/META.json new/Text-BibTeX-0.85/META.json
--- old/Text-BibTeX-0.80/META.json 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/META.json 2017-08-31 12:35:39.000000000 +0200
@@ -5,13 +5,13 @@
"Greg Ward <gward(a)python.net>"
],
"dynamic_config" : 1,
- "generated_by" : "Module::Build version 0.422",
+ "generated_by" : "Module::Build version 0.4224",
"license" : [
"perl_5"
],
"meta-spec" : {
"url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
- "version" : "2"
+ "version" : 2
},
"name" : "Text-BibTeX",
"prereqs" : {
@@ -44,55 +44,55 @@
"provides" : {
"Text::BibTeX" : {
"file" : "lib/Text/BibTeX.pm",
- "version" : "0.80"
+ "version" : "0.85"
},
"Text::BibTeX::BibEntry" : {
"file" : "lib/Text/BibTeX/Bib.pm",
- "version" : "0.80"
+ "version" : "0.85"
},
"Text::BibTeX::BibFormat" : {
"file" : "lib/Text/BibTeX/BibFormat.pm",
- "version" : "0.8"
+ "version" : "0.85"
},
"Text::BibTeX::BibSort" : {
"file" : "lib/Text/BibTeX/BibSort.pm",
- "version" : "0.8"
+ "version" : "0.85"
},
"Text::BibTeX::BibStructure" : {
"file" : "lib/Text/BibTeX/Bib.pm",
- "version" : "0.80"
+ "version" : "0.85"
},
"Text::BibTeX::Entry" : {
"file" : "lib/Text/BibTeX/Entry.pm",
- "version" : "0.8"
+ "version" : "0.85"
},
"Text::BibTeX::File" : {
"file" : "lib/Text/BibTeX/File.pm",
- "version" : "0.8"
+ "version" : "0.85"
},
"Text::BibTeX::Name" : {
"file" : "lib/Text/BibTeX/Name.pm",
- "version" : "0.8"
+ "version" : "0.85"
},
"Text::BibTeX::NameFormat" : {
"file" : "lib/Text/BibTeX/NameFormat.pm",
- "version" : "0.8"
+ "version" : "0.85"
},
"Text::BibTeX::SimpleValue" : {
"file" : "lib/Text/BibTeX/Value.pm",
- "version" : "0.80"
+ "version" : "0.85"
},
"Text::BibTeX::Structure" : {
"file" : "lib/Text/BibTeX/Structure.pm",
- "version" : "0.8"
+ "version" : "0.85"
},
"Text::BibTeX::StructuredEntry" : {
"file" : "lib/Text/BibTeX/Structure.pm",
- "version" : "0.8"
+ "version" : "0.85"
},
"Text::BibTeX::Value" : {
"file" : "lib/Text/BibTeX/Value.pm",
- "version" : "0.8"
+ "version" : "0.85"
}
},
"release_status" : "stable",
@@ -104,6 +104,6 @@
"url" : "http://github.com/ambs/Text-BibTeX"
}
},
- "version" : "0.80",
- "x_serialization_backend" : "JSON::PP version 2.27400_02"
+ "version" : "0.85",
+ "x_serialization_backend" : "JSON::PP version 2.94"
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/META.yml new/Text-BibTeX-0.85/META.yml
--- old/Text-BibTeX-0.80/META.yml 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/META.yml 2017-08-31 12:35:39.000000000 +0200
@@ -16,7 +16,7 @@
ExtUtils::LibBuilder: '0.02'
Module::Build: '0.36'
dynamic_config: 1
-generated_by: 'Module::Build version 0.422, CPAN::Meta::Converter version 2.150010'
+generated_by: 'Module::Build version 0.4224, CPAN::Meta::Converter version 2.150010'
license: perl
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -25,43 +25,43 @@
provides:
Text::BibTeX:
file: lib/Text/BibTeX.pm
- version: '0.80'
+ version: '0.85'
Text::BibTeX::BibEntry:
file: lib/Text/BibTeX/Bib.pm
- version: '0.80'
+ version: '0.85'
Text::BibTeX::BibFormat:
file: lib/Text/BibTeX/BibFormat.pm
- version: '0.8'
+ version: '0.85'
Text::BibTeX::BibSort:
file: lib/Text/BibTeX/BibSort.pm
- version: '0.8'
+ version: '0.85'
Text::BibTeX::BibStructure:
file: lib/Text/BibTeX/Bib.pm
- version: '0.80'
+ version: '0.85'
Text::BibTeX::Entry:
file: lib/Text/BibTeX/Entry.pm
- version: '0.8'
+ version: '0.85'
Text::BibTeX::File:
file: lib/Text/BibTeX/File.pm
- version: '0.8'
+ version: '0.85'
Text::BibTeX::Name:
file: lib/Text/BibTeX/Name.pm
- version: '0.8'
+ version: '0.85'
Text::BibTeX::NameFormat:
file: lib/Text/BibTeX/NameFormat.pm
- version: '0.8'
+ version: '0.85'
Text::BibTeX::SimpleValue:
file: lib/Text/BibTeX/Value.pm
- version: '0.80'
+ version: '0.85'
Text::BibTeX::Structure:
file: lib/Text/BibTeX/Structure.pm
- version: '0.8'
+ version: '0.85'
Text::BibTeX::StructuredEntry:
file: lib/Text/BibTeX/Structure.pm
- version: '0.8'
+ version: '0.85'
Text::BibTeX::Value:
file: lib/Text/BibTeX/Value.pm
- version: '0.8'
+ version: '0.85'
requires:
Encode: '0'
Scalar::Util: '1.42'
@@ -69,5 +69,5 @@
resources:
license: http://dev.perl.org/licenses/
repository: http://github.com/ambs/Text-BibTeX
-version: '0.80'
+version: '0.85'
x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/btparse/doc/bt_language.pod new/Text-BibTeX-0.85/btparse/doc/bt_language.pod
--- old/Text-BibTeX-0.80/btparse/doc/bt_language.pod 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/btparse/doc/bt_language.pod 2017-08-31 12:35:39.000000000 +0200
@@ -94,7 +94,7 @@
JUNK ~[\@\n\ \r\t]+
(Note that this is PCCTS regular expression syntax, which should be
-fairly familar to users of other regex engines. One oddity is that a
+fairly familiar to users of other regex engines. One oddity is that a
character class is negated as C<~[...]> rather than C<[^...]>.)
On seeing C<at> at top-level, we enter in-entry mode. Whitespace, junk,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/btparse/pccts/dlgauto.h new/Text-BibTeX-0.85/btparse/pccts/dlgauto.h
--- old/Text-BibTeX-0.80/btparse/pccts/dlgauto.h 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/btparse/pccts/dlgauto.h 2017-08-31 12:35:39.000000000 +0200
@@ -252,12 +252,12 @@
{
/* points to base of dfa table */
if (m<MAX_MODE){
- zzauto = m;
- /* have to redo class since using different compression */
- zzclass = ZZSHIFT(zzchar);
+ zzauto = m;
+ /* have to redo class since using different compression */
+ zzclass = ZZSHIFT(zzchar);
}else{
- sprintf(zzebuf,"Invalid automaton mode = %d ",m);
- zzerr(zzebuf);
+ snprintf(zzebuf, 69, "Invalid automaton mode = %d ",m); // easier to track bugs
+ zzerr(zzebuf);
}
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/btparse/pccts/err.h new/Text-BibTeX-0.85/btparse/pccts/err.h
--- old/Text-BibTeX-0.80/btparse/pccts/err.h 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/btparse/pccts/err.h 2017-08-31 12:35:39.000000000 +0200
@@ -809,7 +809,7 @@
#endif
{
if(zzmdep == ZZMAXSTK - 1) {
- sprintf(zzmbuf, "Mode stack overflow ");
+ snprintf(zzmbuf, 69, "Mode stack overflow "); // slower but easier to track pointer overflows
zzerr(zzmbuf);
} else {
zzmstk[zzmdep++] = zzauto;
@@ -824,8 +824,8 @@
zzmpop( )
#endif
{
- if(zzmdep == 0)
- { sprintf(zzmbuf, "Mode stack underflow ");
+ if(zzmdep == 0) {
+ snprintf(zzmbuf, 69, "Mode stack underflow ");
zzerr(zzmbuf);
}
else
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/btparse/src/bt_config.h.in new/Text-BibTeX-0.85/btparse/src/bt_config.h.in
--- old/Text-BibTeX-0.80/btparse/src/bt_config.h.in 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/btparse/src/bt_config.h.in 2017-08-31 12:35:39.000000000 +0200
@@ -15,6 +15,12 @@
*/
#[% ALLOCA_H %]
+#undef HAVE_STRLCAT
+/* Have strlcat? */
+#[% STRLCAT %]
+
+
+
/* Define to 1 if the system has the type `boolean'. */
#undef HAVE_BOOLEAN
@@ -70,7 +76,7 @@
#undef HAVE_VPRINTF
/* Define to 1 if you have the `vsnprintf' function. */
-#undef HAVE_VSNPRINTF
+#[% VSNPRINTF %]
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/btparse/src/error.c new/Text-BibTeX-0.85/btparse/src/error.c
--- old/Text-BibTeX-0.80/btparse/src/error.c 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/btparse/src/error.c 2017-08-31 12:35:39.000000000 +0200
@@ -175,7 +175,7 @@
#if HAVE_VSNPRINTF
vsnprintf (error_buf, MAX_ERROR, fmt, arglist);
#else
- msg_len = vsprintf (error_buf, fmt, arglist);
+ msg_len = vsprintf (error_buf, fmt, arglist); // protected by cpp
if (msg_len > MAX_ERROR)
internal_error ("static error message buffer overflowed");
#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/btparse/src/format_name.c new/Text-BibTeX-0.85/btparse/src/format_name.c
--- old/Text-BibTeX-0.80/btparse/src/format_name.c 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/btparse/src/format_name.c 2017-08-31 12:35:39.000000000 +0200
@@ -147,7 +147,9 @@
* discretionary tie, and the join between parts is a space (except for
* 'von': if followed by 'last', we will have a discretionary tie).
*/
- for (i = 0; i < num_parts; i++)
+
+ // INITIALIZA ALL!!!! PARTS
+ for (i = 0; i < BT_MAX_NAMEPARTS; i++)
{
format->join_tokens[i] = BTJ_MAYTIE;
format->join_part[i] = BTJ_SPACE;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/btparse/src/parse_auxiliary.c new/Text-BibTeX-0.85/btparse/src/parse_auxiliary.c
--- old/Text-BibTeX-0.80/btparse/src/parse_auxiliary.c 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/btparse/src/parse_auxiliary.c 2017-08-31 12:35:39.000000000 +0200
@@ -67,6 +67,60 @@
#endif
+#ifndef HAVE_STRLCAT
+/********************************* AMBS **********************/
+/*
+ * Appends src to string dst of size dsize (unlike strlcat, dsize is the
+ * full size of dst, not space left). At most dsize-1 characters
+ * will be copied. Always NUL terminates (unless dsize <= strlen(dst)).
+ * Returns strlen(src) + MIN(dsize, strlen(initial dst)).
+ * If retval >= dsize, truncation occurred.
+ */
+static size_t
+strlcat(char *dst, const char *src, size_t dsize)
+{
+ const char *odst = dst;
+ const char *osrc = src;
+ size_t n = dsize;
+ size_t dlen;
+
+ /* Find the end of dst and adjust bytes left but don't go past end. */
+ while (n-- != 0 && *dst != '\0')
+ dst++;
+ dlen = dst - odst;
+ n = dsize - dlen;
+
+ if (n-- == 0)
+ return(dlen + strlen(src));
+ while (*src != '\0') {
+ if (n != 0) {
+ *dst++ = *src;
+ n--;
+ }
+ src++;
+ }
+ *dst = '\0';
+
+ return(dlen + (src - osrc)); /* count does not include NUL */
+}
+/********************************* AMBS **********************/
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
void
fix_token_names (void)
{
@@ -120,12 +174,12 @@
{
if (t & *b)
{
- strcat (msg, zztokens[e]);
+ strlcat (msg, zztokens[e], MAX_ERROR);
tokens_printed++;
if (tokens_printed < zzset_deg (a) - 1)
- strcat (msg, ", ");
+ strlcat (msg, ", ", MAX_ERROR);
else if (tokens_printed == zzset_deg (a) - 1)
- strcat (msg, " or ");
+ strlcat (msg, " or ", MAX_ERROR);
}
e++;
} while (++b < &(bitmask[sizeof(SetWordType)*8]));
@@ -153,9 +207,9 @@
msg[0] = (char) 0; /* make sure string is empty to start! */
if (tok == zzEOF_TOKEN)
- strcat (msg, "at end of input");
+ strlcat (msg, "at end of input", MAX_ERROR);
else
- sprintf (msg, "found \"%s\"", bad_text);
+ snprintf (msg, MAX_ERROR - 1, "found \"%s\"", bad_text);
len = strlen (msg);
@@ -169,7 +223,7 @@
}
else
{
- strcat (msg, ", ");
+ strlcat (msg, ", ", MAX_ERROR);
len += 2;
}
@@ -178,7 +232,7 @@
if (k != 1)
{
- sprintf (msg+len, "; \"%s\" not", bad_text);
+ snprintf (msg+len, MAX_ERROR - len - 1, "; \"%s\" not", bad_text);
if (zzset_deg (eset) > 1) strcat (msg, " in");
len = strlen (msg);
}
@@ -189,25 +243,26 @@
if (zzset_deg (eset) > 0)
{
if (zzset_deg (eset) == 1)
- strcat (msg, "expected ");
+ strlcat (msg, "expected ", MAX_ERROR);
else
- strcat (msg, "expected one of: ");
+ strlcat (msg, "expected one of: ", MAX_ERROR);
append_token_set (msg, eset);
}
else
{
- sprintf (msg+len, "expected %s", zztokens[etok]);
+ if (MAX_ERROR - len > 0) // Check if we have space for more info...
+ snprintf (msg+len, MAX_ERROR - len - 1, "expected %s", zztokens[etok]);
if (etok == ENTRY_CLOSE)
{
- strcat (msg, " (skipping to next \"@\")");
+ strlcat (msg, " (skipping to next \"@\")", MAX_ERROR);
initialize_lexer_state ();
}
}
len = strlen (msg);
if (egroup && strlen (egroup) > 0)
- sprintf (msg+len, " in %s", egroup);
+ snprintf (msg+len, MAX_ERROR - len - 1, " in %s", egroup);
syntax_error (msg);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/btparse/tests/read_test.c new/Text-BibTeX-0.85/btparse/tests/read_test.c
--- old/Text-BibTeX-0.80/btparse/tests/read_test.c 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/btparse/tests/read_test.c 2017-08-31 12:35:39.000000000 +0200
@@ -28,7 +28,7 @@
* at eof -- but doesn't do the eof processing (that's for the next
* call).
*/
- infile = open_file ("empty.bib", DATA_DIR, filename);
+ infile = open_file ("empty.bib", DATA_DIR, filename, 255);
CHECK (!feof (infile))
entry = bt_parse_entry (infile, filename, 0, &entry_ok);
CHECK (feof (infile))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/btparse/tests/simple_test.c new/Text-BibTeX-0.85/btparse/tests/simple_test.c
--- old/Text-BibTeX-0.80/btparse/tests/simple_test.c 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/btparse/tests/simple_test.c 2017-08-31 12:35:39.000000000 +0200
@@ -552,7 +552,7 @@
for (i = 0; i < NUM_TESTS; i++)
{
- infile = open_file (tests[i].filename, DATA_DIR, filename);
+ infile = open_file (tests[i].filename, DATA_DIR, filename, 255);
/* Override string-processing options for all entry metatypes */
set_all_stringopts (tests[i].options);
@@ -569,7 +569,7 @@
if (!ok) num_failures++;
} /* for i */
- infile = open_file ("simple.bib", DATA_DIR, filename);
+ infile = open_file ("simple.bib", DATA_DIR, filename, 255);
if (! test_multiple (infile, filename, BTO_MINIMAL, options, 4, tests+4))
num_failures++;
rewind (infile);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/btparse/tests/testlib.c new/Text-BibTeX-0.85/btparse/tests/testlib.c
--- old/Text-BibTeX-0.80/btparse/tests/testlib.c 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/btparse/tests/testlib.c 2017-08-31 12:35:39.000000000 +0200
@@ -19,11 +19,11 @@
#include "my_dmalloc.h"
-FILE *open_file (char *basename, char *dirname, char *filename)
+FILE *open_file (char *basename, char *dirname, char *filename, int len)
{
FILE * file;
- sprintf (filename, "%s/%s", dirname, basename);
+ snprintf (filename, len-1, "%s/%s", dirname, basename);
file = fopen (filename, "r");
if (file == NULL)
{
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/btparse/tests/testlib.h new/Text-BibTeX-0.85/btparse/tests/testlib.h
--- old/Text-BibTeX-0.80/btparse/tests/testlib.h 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/btparse/tests/testlib.h 2017-08-31 12:35:39.000000000 +0200
@@ -39,7 +39,7 @@
}
-FILE *open_file (char *basename, char *dirname, char *filename);
+FILE *open_file (char *basename, char *dirname, char *filename, int len);
void set_all_stringopts (btshort options);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/inc/MyBuilder.pm new/Text-BibTeX-0.85/inc/MyBuilder.pm
--- old/Text-BibTeX-0.80/inc/MyBuilder.pm 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/inc/MyBuilder.pm 2017-08-31 12:35:39.000000000 +0200
@@ -77,14 +77,24 @@
$self->notes('libbuilder', $libbuilder);
my $version = $self->notes('btparse_version');
+
my $alloca_h = 'undef HAVE_ALLOCA_H';
$alloca_h = 'define HAVE_ALLOCA_H 1' if Config::AutoConf->check_header("alloca.h");
+
+ my $vsnprintf = 'undef HAVE_VSNPRINTF';
+ $vsnprintf = 'define HAVE_VSNPRINTF 1' if Config::AutoConf->check_func('vsnprintf');
+
+ my $strlcat = 'undef HAVE_STRLCAT';
+ $strlcat = 'define HAVE_STRLCAT 1' if Config::AutoConf->check_func('strlcat');
+
_interpolate("btparse/src/bt_config.h.in",
"btparse/src/bt_config.h",
PACKAGE => "\"libbtparse\"",
FPACKAGE => "\"libbtparse $version\"",
VERSION => "\"$version\"",
- ALLOCA_H => $alloca_h
+ ALLOCA_H => $alloca_h,
+ VSNPRINTF => $vsnprintf,
+ STRLCAT => $strlcat
);
@@ -377,7 +387,7 @@
sub _interpolate {
my ($from, $to, %config) = @_;
-
+
print "Creating new '$to' from '$from'.\n";
open FROM, $from or die "Cannot open file '$from' for reading.\n";
open TO, ">", $to or die "Cannot open file '$to' for writing.\n";
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/lib/Text/BibTeX/Bib.pm new/Text-BibTeX-0.85/lib/Text/BibTeX/Bib.pm
--- old/Text-BibTeX-0.80/lib/Text/BibTeX/Bib.pm 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/lib/Text/BibTeX/Bib.pm 2017-08-31 12:35:39.000000000 +0200
@@ -111,7 +111,7 @@
use strict;
use vars qw(@ISA $VERSION);
@ISA = qw(Text::BibTeX::Structure);
-$VERSION = '0.80';
+$VERSION = '0.85';
=head1 STRUCTURE OPTIONS
@@ -450,7 +450,7 @@
use strict;
use vars qw(@ISA $VERSION);
-$VERSION = '0.80';
+$VERSION = '0.85';
use Text::BibTeX::BibSort;
use Text::BibTeX::BibFormat;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/lib/Text/BibTeX/BibFormat.pm new/Text-BibTeX-0.85/lib/Text/BibTeX/BibFormat.pm
--- old/Text-BibTeX-0.80/lib/Text/BibTeX/BibFormat.pm 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/lib/Text/BibTeX/BibFormat.pm 2017-08-31 12:35:39.000000000 +0200
@@ -26,7 +26,7 @@
use Text::BibTeX::Structure;
@ISA = qw(Text::BibTeX::StructuredEntry);
-$VERSION = 0.80;
+$VERSION = 0.85;
use Text::BibTeX qw(:subs display_list :nameparts :joinmethods);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/lib/Text/BibTeX/BibSort.pm new/Text-BibTeX-0.85/lib/Text/BibTeX/BibSort.pm
--- old/Text-BibTeX-0.80/lib/Text/BibTeX/BibSort.pm 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/lib/Text/BibTeX/BibSort.pm 2017-08-31 12:35:39.000000000 +0200
@@ -23,7 +23,7 @@
use Text::BibTeX::Structure;
@ISA = qw(Text::BibTeX::StructuredEntry);
-$VERSION = 0.80;
+$VERSION = 0.85;
use Text::BibTeX qw(purify_string change_case);
@@ -70,7 +70,7 @@
non-alphabetic characters are stripped, and everything is forced to
lowercase. (The first two steps are done by the C<purify_string> routine;
see L<Text::BibTeX/"Generic string-processing functions"> for a brief
-description, and the descripton of the C function C<bt_purify_string()> in
+description, and the description of the C function C<bt_purify_string()> in
L<bt_misc> for all the gory details.)
=cut
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/lib/Text/BibTeX/Entry.pm new/Text-BibTeX-0.85/lib/Text/BibTeX/Entry.pm
--- old/Text-BibTeX-0.80/lib/Text/BibTeX/Entry.pm 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/lib/Text/BibTeX/Entry.pm 2017-08-31 12:35:39.000000000 +0200
@@ -23,7 +23,7 @@
use Carp;
use Text::BibTeX qw(:metatypes :nodetypes);
-$VERSION = 0.80;
+$VERSION = 0.85;
=head1 NAME
@@ -534,7 +534,7 @@
=item value ()
-Retuns the single string associated with C<@comment> and C<@preamble>
+Returns the single string associated with C<@comment> and C<@preamble>
entries. For instance, the entry
@preamble{" This is a preamble" #
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/lib/Text/BibTeX/File.pm new/Text-BibTeX-0.85/lib/Text/BibTeX/File.pm
--- old/Text-BibTeX-0.80/lib/Text/BibTeX/File.pm 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/lib/Text/BibTeX/File.pm 2017-08-31 12:35:39.000000000 +0200
@@ -23,7 +23,7 @@
use Text::BibTeX::Entry;
use vars qw'$VERSION';
-$VERSION = 0.80;
+$VERSION = 0.85;
=head1 NAME
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/lib/Text/BibTeX/Name.pm new/Text-BibTeX-0.85/lib/Text/BibTeX/Name.pm
--- old/Text-BibTeX-0.80/lib/Text/BibTeX/Name.pm 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/lib/Text/BibTeX/Name.pm 2017-08-31 12:35:39.000000000 +0200
@@ -23,7 +23,7 @@
use strict;
use Carp;
use vars qw'$VERSION';
-$VERSION = 0.80;
+$VERSION = 0.85;
use Text::BibTeX;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/lib/Text/BibTeX/NameFormat.pm new/Text-BibTeX-0.85/lib/Text/BibTeX/NameFormat.pm
--- old/Text-BibTeX-0.80/lib/Text/BibTeX/NameFormat.pm 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/lib/Text/BibTeX/NameFormat.pm 2017-08-31 12:35:39.000000000 +0200
@@ -23,7 +23,7 @@
use strict;
use Carp;
use vars qw'$VERSION';
-$VERSION = 0.80;
+$VERSION = 0.85;
=head1 NAME
@@ -123,7 +123,7 @@
$parts ||= "fvlj";
$abbrev_first = defined($abbrev_first)? $abbrev_first : 0;
- die unless $parts =~ /[fvlj]{1,4}/;
+ die unless $parts =~ /^[fvlj]{1,4}$/;
$class = ref ($class) || $class;
my $self = bless {}, $class;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/lib/Text/BibTeX/Structure.pm new/Text-BibTeX-0.85/lib/Text/BibTeX/Structure.pm
--- old/Text-BibTeX-0.80/lib/Text/BibTeX/Structure.pm 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/lib/Text/BibTeX/Structure.pm 2017-08-31 12:35:39.000000000 +0200
@@ -24,7 +24,7 @@
use Carp;
use vars qw'$VERSION';
-$VERSION = 0.80;
+$VERSION = 0.85;
use Text::BibTeX ('check_class');
@@ -80,7 +80,7 @@
database structures are defined and imposed on BibTeX files, and
provides an elegant synthesis of object-oriented techniques with
BibTeX-style database structures. Nothing described here is
-particularly deep or subtle; anyone familar with object-oriented
+particularly deep or subtle; anyone familiar with object-oriented
programming should be able to follow it. However, a fair bit of jargon
in invented and tossed around, so pay attention.
@@ -870,7 +870,7 @@
package Text::BibTeX::StructuredEntry;
use strict;
use vars qw(@ISA $VERSION);
-$VERSION = 0.80;
+$VERSION = 0.85;
use Carp;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/lib/Text/BibTeX/Value.pm new/Text-BibTeX-0.85/lib/Text/BibTeX/Value.pm
--- old/Text-BibTeX-0.80/lib/Text/BibTeX/Value.pm 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/lib/Text/BibTeX/Value.pm 2017-08-31 12:35:39.000000000 +0200
@@ -22,7 +22,7 @@
use Carp;
use vars qw'$VERSION';
-$VERSION = 0.80;
+$VERSION = 0.85;
=head1 NAME
@@ -245,7 +245,7 @@
use Text::BibTeX qw(:nodetypes);
use vars qw($VERSION);
-$VERSION = '0.80';
+$VERSION = '0.85';
=head2 Text::BibTeX::SimpleValue methods
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/lib/Text/BibTeX.pm new/Text-BibTeX-0.85/lib/Text/BibTeX.pm
--- old/Text-BibTeX-0.80/lib/Text/BibTeX.pm 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/lib/Text/BibTeX.pm 2017-08-31 12:35:39.000000000 +0200
@@ -25,7 +25,7 @@
require Exporter;
require DynaLoader;
-our $VERSION='0.80';
+our $VERSION='0.85';
@ISA = qw(Exporter DynaLoader);
%EXPORT_TAGS = (nodetypes => [qw(BTAST_STRING BTAST_MACRO BTAST_NUMBER)],
@@ -667,7 +667,7 @@
OPTIONS is currently unused.
-=item change_case (TRANFORM, STRING [, OPTIONS])
+=item change_case (TRANSFORM, STRING [, OPTIONS])
Transforms the case of STRING according to TRANSFORM (a single
character, one of C<'u'>, C<'l'>, or C<'t'>). See L<bt_misc> for
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/t/00_system_info.t new/Text-BibTeX-0.85/t/00_system_info.t
--- old/Text-BibTeX-0.80/t/00_system_info.t 1970-01-01 01:00:00.000000000 +0100
+++ new/Text-BibTeX-0.85/t/00_system_info.t 2017-08-31 12:35:39.000000000 +0200
@@ -0,0 +1,12 @@
+#!perl
+
+use strict;
+use warnings;
+use Test::More tests => 1;
+
+open my $f, '<', "btparse/src/bt_config.h";
+while (<$f>) {
+ diag $_ if /#define/;
+}
+close $f;
+ok(1);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/t/from_file.t new/Text-BibTeX-0.85/t/from_file.t
--- old/Text-BibTeX-0.80/t/from_file.t 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/t/from_file.t 2017-08-31 12:35:39.000000000 +0200
@@ -1,14 +1,21 @@
use strict;
use warnings;
-use Test::More tests => 11;
+use Test::More tests => 12;
use utf8;
+use Cwd;
use Text::BibTeX;
+BEGIN {
+ my $common = getcwd()."/t/common.pl";
+ require $common;
+}
+
##### parse t/corpora.bib #####
my $bibtex = Text::BibTeX::File->new("t/corpora.bib", { binmode => 'utf-8'});
+
is ref($bibtex), "Text::BibTeX::File";
my @entries;
@@ -54,9 +61,11 @@
is ref($bibtex), "Text::BibTeX::File";
@entries = ();
-while (my $entry = Text::BibTeX::Entry->new($bibtex)) {
- push @entries, $entry;
-}
+err_like sub {
+ while (my $entry = Text::BibTeX::Entry->new($bibtex)) {
+ push @entries, $entry;
+ }
+}, qr!syntax error: found "\{error\}", expected "="!;
is scalar(@entries), 1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/t/nameformat.t new/Text-BibTeX-0.85/t/nameformat.t
--- old/Text-BibTeX-0.80/t/nameformat.t 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/t/nameformat.t 2017-08-31 12:35:39.000000000 +0200
@@ -2,7 +2,7 @@
use strict;
use vars qw($DEBUG);
use IO::Handle;
-use Test::More tests=>26;
+use Test::More tests=>27;
use utf8;
use Encode 'decode';
use Unicode::Normalize;
@@ -186,3 +186,12 @@
$format->set_options (BTN_FIRST, 0, BTJ_SPACE, BTJ_NOTHING);
is $format->apply($name), "de la Vall{\\'e}e~Poussin, Charles Louis Xavier Joseph";
}
+
+{
+ # test 27
+ my $entry = new Text::BibTeX::Entry;
+ $entry->parse_s('@' . "article{key,\n author = {Firstlastname Secondlastname, Firstname and others},\n}");
+ my @authors = $entry->names("author");
+ my $format = new Text::BibTeX::NameFormat("vl");
+ is $format->apply($authors[0]), "Firstlastname~Secondlastname";
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/t/namelist.t new/Text-BibTeX-0.85/t/namelist.t
--- old/Text-BibTeX-0.80/t/namelist.t 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/t/namelist.t 2017-08-31 12:35:39.000000000 +0200
@@ -3,7 +3,7 @@
use warnings;
use IO::Handle;
-use Test::More tests => 12;
+use Test::More tests => 13;
use vars qw($DEBUG);
use Cwd;
@@ -35,16 +35,24 @@
);
while (@names) {
- my ($name, $should_split) = (shift @names, shift @names);
- my $actual_split = [Text::BibTeX::split_list ($name, 'and')];
+ my ($name, $should_split) = (shift @names, shift @names);
- if ($DEBUG) {
- printf "name = >%s<\n", $name;
- print "should split to:\n ";
- print join ("\n ", @$should_split) . "\n";
- print "actually split to:\n ";
- print join ("\n ", @$actual_split) . "\n";
- }
+ my $actual_split;
+ if (!$should_split->[1]) {
+ # these should issue a warning
+ err_like sub { $actual_split = [Text::BibTeX::split_list ($name, 'and')] },
+ qr!empty substring!;
+ } else {
+ $actual_split = [Text::BibTeX::split_list ($name, 'and')];
+ }
+
+ if ($DEBUG) {
+ printf "name = >%s<\n", $name;
+ print "should split to:\n ";
+ print join ("\n ", @$should_split) . "\n";
+ print "actually split to:\n ";
+ print join ("\n ", @$actual_split) . "\n";
+ }
- ok(slist_equal ($should_split, $actual_split));
+ ok(slist_equal ($should_split, $actual_split));
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/t/parse_s.t new/Text-BibTeX-0.85/t/parse_s.t
--- old/Text-BibTeX-0.80/t/parse_s.t 2017-03-25 21:41:12.000000000 +0100
+++ new/Text-BibTeX-0.85/t/parse_s.t 2017-08-31 12:35:39.000000000 +0200
@@ -3,7 +3,7 @@
use warnings;
use utf8;
use IO::Handle;
-use Test::More tests => 50;
+use Test::More tests => 54;
use vars qw($DEBUG);
use Cwd;
@@ -79,12 +79,24 @@
# just returns false
$entry = Text::BibTeX::Entry->new();
-$result = $entry->parse_s ('');
+
+err_like sub {
+ $result = $entry->parse_s ('');
+ ok(! $result);
+}, qr!expected "@"!;
ok(! $result);
-$result = $entry->parse_s (undef);
+
+err_like sub {
+ $result = $entry->parse_s (undef);
+ $result = $entry->parse_s ('top-level junk that is not caught');
+}, qr!expected "@"!;
ok(! $result);
-$result = $entry->parse_s ('top-level junk that is not caught');
+
+err_like sub {
+ $result = $entry->parse_s ('top-level junk that is not caught');
+}, qr!expected "@"!;
ok(! $result);
+
$result = $entry->parse_s (undef);
ok(! $result);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/t/unlimited.bib new/Text-BibTeX-0.85/t/unlimited.bib
--- old/Text-BibTeX-0.80/t/unlimited.bib 1970-01-01 01:00:00.000000000 +0100
+++ new/Text-BibTeX-0.85/t/unlimited.bib 2017-08-31 12:35:39.000000000 +0200
@@ -0,0 +1,3 @@
+@AAAAA{
+@BBBBB{
+CCCCCC={FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA}}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-BibTeX-0.80/t/unlimited.t new/Text-BibTeX-0.85/t/unlimited.t
--- old/Text-BibTeX-0.80/t/unlimited.t 1970-01-01 01:00:00.000000000 +0100
+++ new/Text-BibTeX-0.85/t/unlimited.t 2017-08-31 12:35:39.000000000 +0200
@@ -0,0 +1,29 @@
+# -*- cperl -*-
+use strict;
+use warnings;
+
+use Capture::Tiny 'capture';
+use IO::Handle;
+use Test::More tests => 4;
+
+use vars qw($DEBUG);
+use Cwd;
+BEGIN {
+ use_ok('Text::BibTeX');
+ my $common = getcwd()."/t/common.pl";
+ require $common;
+}
+
+$DEBUG = 0;
+
+
+# ----------------------------------------------------------------------
+# entry creation and parsing from a Text::BibTeX::File object
+
+my ($bibfile, $entry);
+my $multiple_file = 't/unlimited.bib';
+
+ok($bibfile = Text::BibTeX::File->new( $multiple_file));
+err_like sub { ok($entry = Text::BibTeX::Entry->new( $bibfile)) },
+ qr!warning: possible runaway string started at line!;
+
++++++ manual-pages-for-libbtparse.patch ++++++
--- /var/tmp/diff_new_pack.FI3GiI/_old 2018-04-26 13:34:20.692186038 +0200
+++ /var/tmp/diff_new_pack.FI3GiI/_new 2018-04-26 13:34:20.692186038 +0200
@@ -1,6 +1,6 @@
--- Text-BibTeX-0.80/inc/MyBuilder.pm 2017-03-25 20:41:12.000000000 +0000
+++ Text-BibTeX-0.80/inc/MyBuilder.pm 2017-05-31 09:58:18.898289185 +0000
-@@ -162,8 +162,8 @@ sub ACTION_create_manpages {
+@@ -172,8 +172,8 @@ sub ACTION_create_manpages {
my $version = $self->notes('btparse_version');
for my $pod (@$pods) {
my $man = $pod;
1
0