From cb895f50d5c08976c0f5ecbb82e6bd19d9ea090d Mon Sep 17 00:00:00 2001 From: Konstantin Tokarev Date: Sun, 7 Jan 2018 19:43:21 +0300 Subject: Import WebKit commit 69d327017a8d700cbfc7e1120270db4d55416f41 Change-Id: I38406c67ba681f7693a45b0fa2d8c2e44a6d9a0e Reviewed-by: Konstantin Tokarev --- Source/WTF/wtf/CurrentTime.cpp | 22 ++++---- .../bindings/js/JSHTMLFormElementCustom.cpp | 6 +-- Source/WebCore/html/HTMLAnchorElement.cpp | 10 +--- Source/WebCore/page/Performance.cpp | 2 +- Source/WebCore/page/Settings.in | 4 +- Source/WebCore/platform/graphics/GraphicsContext.h | 1 + .../platform/graphics/qt/GraphicsContextQt.cpp | 35 ++++++++++--- .../WebCore/platform/graphics/qt/ImageBufferQt.cpp | 1 - Source/WebKit/PlatformQt.cmake | 2 + .../WebKit/qt/WebCoreSupport/QWebPageAdapter.cpp | 5 +- Source/cmake/ECMGeneratePkgConfigFile.cmake | 60 +++++++++++++++++----- Source/cmake/FindICU.cmake | 4 +- Source/cmake/OptionsQt.cmake | 24 +++++++-- Tools/qmake/projects/run_cmake.pro | 4 -- Tools/qt/make-snapshot.pl | 2 +- 15 files changed, 123 insertions(+), 59 deletions(-) diff --git a/Source/WTF/wtf/CurrentTime.cpp b/Source/WTF/wtf/CurrentTime.cpp index 7de52f779..8774314fe 100644 --- a/Source/WTF/wtf/CurrentTime.cpp +++ b/Source/WTF/wtf/CurrentTime.cpp @@ -261,18 +261,7 @@ double monotonicallyIncreasingTime() return ecore_time_get(); } -#elif PLATFORM(QT) - -double monotonicallyIncreasingTime() -{ - ASSERT(QElapsedTimer::isMonotonic()); - static QElapsedTimer timer; - if (!timer.isValid()) - timer.start(); - return timer.nsecsElapsed() / 1.0e9; -} - -#elif USE(GLIB) +#elif USE(GLIB) && !PLATFORM(QT) double monotonicallyIncreasingTime() { @@ -295,6 +284,15 @@ double monotonicallyIncreasingTime() return (mach_absolute_time() * timebaseInfo.numer) / (1.0e9 * timebaseInfo.denom); } +#elif OS(LINUX) || OS(FREEBSD) || OS(OPENBSD) || OS(NETBSD) + +double monotonicallyIncreasingTime() +{ + struct timespec ts { }; + clock_gettime(CLOCK_MONOTONIC, &ts); + return static_cast(ts.tv_sec) + ts.tv_nsec / 1.0e9; +} + #else double monotonicallyIncreasingTime() diff --git a/Source/WebCore/bindings/js/JSHTMLFormElementCustom.cpp b/Source/WebCore/bindings/js/JSHTMLFormElementCustom.cpp index 3aed7052f..cb2119b10 100644 --- a/Source/WebCore/bindings/js/JSHTMLFormElementCustom.cpp +++ b/Source/WebCore/bindings/js/JSHTMLFormElementCustom.cpp @@ -30,8 +30,7 @@ #include "HTMLCollection.h" #include "HTMLFormElement.h" #include "JSDOMWindowCustom.h" -#include "JSNodeList.h" -#include "StaticNodeList.h" +#include "JSRadioNodeList.h" using namespace JSC; @@ -48,8 +47,7 @@ bool JSHTMLFormElement::nameGetter(ExecState* exec, PropertyName propertyName, J return true; } - // FIXME: HTML5 specifies that this should be a RadioNodeList. - value = toJS(exec, globalObject(), StaticElementList::adopt(namedItems).get()); + value = toJS(exec, globalObject(), wrapped().radioNodeList(propertyNameToAtomicString(propertyName)).get()); return true; } diff --git a/Source/WebCore/html/HTMLAnchorElement.cpp b/Source/WebCore/html/HTMLAnchorElement.cpp index bc100a870..75eb7a2a3 100644 --- a/Source/WebCore/html/HTMLAnchorElement.cpp +++ b/Source/WebCore/html/HTMLAnchorElement.cpp @@ -46,6 +46,7 @@ #include "SecurityOrigin.h" #include "SecurityPolicy.h" #include "Settings.h" +#include "URLUtils.h" #include namespace WebCore { @@ -76,15 +77,6 @@ HTMLAnchorElement::~HTMLAnchorElement() clearRootEditableElementForSelectionOnMouseDown(); } -// This function does not allow leading spaces before the port number. -static unsigned parsePortFromStringPosition(const String& value, unsigned portStart, unsigned& portEnd) -{ - portEnd = portStart; - while (isASCIIDigit(value[portEnd])) - ++portEnd; - return value.substring(portStart, portEnd - portStart).toUInt(); -} - bool HTMLAnchorElement::supportsFocus() const { if (hasEditableStyle()) diff --git a/Source/WebCore/page/Performance.cpp b/Source/WebCore/page/Performance.cpp index ed39a1d15..1c491da5d 100644 --- a/Source/WebCore/page/Performance.cpp +++ b/Source/WebCore/page/Performance.cpp @@ -233,7 +233,7 @@ void Performance::webkitClearMeasures(const String& measureName) double Performance::now() const { double nowSeconds = monotonicallyIncreasingTime() - m_referenceTime; - const double resolutionSeconds = 0.000005; + const double resolutionSeconds = 0.0001; return 1000.0 * floor(nowSeconds / resolutionSeconds) * resolutionSeconds; } diff --git a/Source/WebCore/page/Settings.in b/Source/WebCore/page/Settings.in index 84a9f0cd0..74d9e0709 100644 --- a/Source/WebCore/page/Settings.in +++ b/Source/WebCore/page/Settings.in @@ -79,7 +79,6 @@ needsSiteSpecificQuirks initial=false domTimersThrottlingEnabled initial=true webArchiveDebugModeEnabled initial=false, conditional=WEB_ARCHIVE localFileContentSniffingEnabled initial=false -offlineStorageDatabaseEnabled initial=false offlineWebApplicationCacheEnabled initial=false enforceCSSMIMETypeInNoQuirksMode initial=true usesEncodingDetector initial=false @@ -91,6 +90,9 @@ acceleratedFiltersEnabled initial=false useLegacyTextAlignPositionedElementBehavior initial=false javaScriptRuntimeFlags type=JSC::RuntimeFlags +# PLATFORM(QT) only +offlineStorageDatabaseEnabled initial=true + # FIXME: This should really be disabled by default as it makes platforms that don't support the feature download files # they can't use by. Leaving enabled for now to not change existing behavior. downloadableBinaryFontsEnabled initial=true diff --git a/Source/WebCore/platform/graphics/GraphicsContext.h b/Source/WebCore/platform/graphics/GraphicsContext.h index d7f529cf8..8b821fa98 100644 --- a/Source/WebCore/platform/graphics/GraphicsContext.h +++ b/Source/WebCore/platform/graphics/GraphicsContext.h @@ -563,6 +563,7 @@ public: #if PLATFORM(QT) void pushTransparencyLayerInternal(const QRect&, qreal, QPixmap&); + void popTransparencyLayerInternal(); void takeOwnershipOfPlatformContext(); #endif diff --git a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp index 260081946..1e041050e 100644 --- a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp +++ b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp @@ -358,7 +358,7 @@ void GraphicsContext::restorePlatformState() { if (!m_data->layers.isEmpty() && !m_data->layers.top()->alphaMask.isNull()) if (!--m_data->layers.top()->saveCounter) - endPlatformTransparencyLayer(); + popTransparencyLayerInternal(); m_data->p()->restore(); } @@ -1313,18 +1313,39 @@ void GraphicsContext::beginPlatformTransparencyLayer(float opacity) ++m_data->layerCount; } +void GraphicsContext::popTransparencyLayerInternal() +{ + TransparencyLayer* layer = m_data->layers.pop(); + ASSERT(!layer->alphaMask.isNull()); + ASSERT(layer->saveCounter == 0); + layer->painter.resetTransform(); + layer->painter.setCompositionMode(QPainter::CompositionMode_DestinationIn); + layer->painter.drawPixmap(QPoint(), layer->alphaMask); + layer->painter.end(); + + QPainter* p = m_data->p(); + p->save(); + p->resetTransform(); + p->setOpacity(layer->opacity); + p->drawPixmap(layer->offset, layer->pixmap); + p->restore(); + + delete layer; +} + void GraphicsContext::endPlatformTransparencyLayer() { if (paintingDisabled()) return; + while ( ! m_data->layers.top()->alphaMask.isNull() ){ + --m_data->layers.top()->saveCounter; + popTransparencyLayerInternal(); + if (m_data->layers.isEmpty()) + return; + } TransparencyLayer* layer = m_data->layers.pop(); - if (!layer->alphaMask.isNull()) { - layer->painter.resetTransform(); - layer->painter.setCompositionMode(QPainter::CompositionMode_DestinationIn); - layer->painter.drawPixmap(QPoint(), layer->alphaMask); - } else - --m_data->layerCount; // see the comment for layerCount + --m_data->layerCount; // see the comment for layerCount layer->painter.end(); QPainter* p = m_data->p(); diff --git a/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp b/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp index 2295362aa..af798f761 100644 --- a/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp +++ b/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp @@ -34,7 +34,6 @@ #include "IntRect.h" #include "MIMETypeRegistry.h" #include "StillImageQt.h" -#include "TransparencyLayer.h" #include #include #include diff --git a/Source/WebKit/PlatformQt.cmake b/Source/WebKit/PlatformQt.cmake index cf5f36700..909efc00d 100644 --- a/Source/WebKit/PlatformQt.cmake +++ b/Source/WebKit/PlatformQt.cmake @@ -502,6 +502,7 @@ endif () if (NOT MACOS_BUILD_FRAMEWORKS) ecm_generate_pkgconfig_file( BASE_NAME Qt5WebKit + DESCRIPTION "Qt WebKit module" DEPS "${WEBKIT_PKGCONGIG_DEPS}" FILENAME_VAR WebKit_PKGCONFIG_FILENAME ) @@ -726,6 +727,7 @@ install( if (NOT MACOS_BUILD_FRAMEWORKS) ecm_generate_pkgconfig_file( BASE_NAME Qt5WebKitWidgets + DESCRIPTION "Qt WebKitWidgets module" DEPS "${WEBKITWIDGETS_PKGCONFIG_DEPS}" FILENAME_VAR WebKitWidgets_PKGCONFIG_FILENAME ) diff --git a/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.cpp b/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.cpp index 89e872fb2..00dc0c488 100644 --- a/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.cpp +++ b/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.cpp @@ -390,7 +390,10 @@ QString QWebPageAdapter::selectedText() const QString QWebPageAdapter::selectedHtml() const { - return page->focusController().focusedOrMainFrame().editor().selectedRange()->toHTML(); + RefPtr range = page->focusController().focusedOrMainFrame().editor().selectedRange(); + if (!range) + return QString(); + return range->toHTML(); } bool QWebPageAdapter::isContentEditable() const diff --git a/Source/cmake/ECMGeneratePkgConfigFile.cmake b/Source/cmake/ECMGeneratePkgConfigFile.cmake index b4e686630..09d7e2b47 100644 --- a/Source/cmake/ECMGeneratePkgConfigFile.cmake +++ b/Source/cmake/ECMGeneratePkgConfigFile.cmake @@ -16,6 +16,7 @@ # [INCLUDE_INSTALL_DIR ] # [LIB_INSTALL_DIR ] # [DEFINES -D...] +# [DESCRIPTION ] # [INSTALL]) # # ``BASE_NAME`` is the name of the module. It's the name projects will use to @@ -42,6 +43,10 @@ # ``DEFINES`` is a list of preprocessor defines that it is recommended users of # the library pass to the compiler when using it. # +# ``DESCRIPTION`` describes what this library is. If it's not specified, CMake +# will first try to get the description from the metainfo.yaml file or will +# create one based on ``LIB_NAME``. +# # ``INSTALL`` will cause the module to be installed to the ``pkgconfig`` # subdirectory of ``LIB_INSTALL_DIR``, unless the ``ECM_PKGCONFIG_INSTALL_DIR`` # cache variable is set to something different. Note that the first call to @@ -66,24 +71,39 @@ # ) # # Since 1.3.0. +# ``DESCRIPTION`` available since 5.1.41 +# #============================================================================= # Copyright 2014 Aleix Pol Gonzalez # Copyright 2014 David Faure # -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file COPYING-CMAKE-SCRIPTS for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distribute this file outside of extra-cmake-modules, substitute the full -# License text for the above reference.) +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. function(ECM_GENERATE_PKGCONFIG_FILE) set(options INSTALL) - set(oneValueArgs BASE_NAME LIB_NAME FILENAME_VAR INCLUDE_INSTALL_DIR LIB_INSTALL_DIR) + set(oneValueArgs BASE_NAME LIB_NAME FILENAME_VAR INCLUDE_INSTALL_DIR LIB_INSTALL_DIR DESCRIPTION) set(multiValueArgs DEPS DEFINES) cmake_parse_arguments(EGPF "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) @@ -119,6 +139,17 @@ function(ECM_GENERATE_PKGCONFIG_FILE) set(EGPF_LIB_INSTALL_DIR "lib") endif() endif() + if(NOT EGPF_DESCRIPTION) + if(EXISTS ${CMAKE_SOURCE_DIR}/metainfo.yaml) + file(STRINGS "${CMAKE_SOURCE_DIR}/metainfo.yaml" _EGPF_METAINFO_DESCRIPTION_STRING REGEX "^description:.*$") + if(_EGPF_METAINFO_DESCRIPTION_STRING) + string(REGEX REPLACE "^description:[ ]*(.*)" "\\1" EGPF_DESCRIPTION ${_EGPF_METAINFO_DESCRIPTION_STRING}) + endif() + endif() + if("${EGPF_DESCRIPTION}" STREQUAL "") + set(EGPF_DESCRIPTION "${EGPF_LIB_NAME} library.") + endif() + endif() set(PKGCONFIG_TARGET_BASENAME ${EGPF_BASE_NAME}) set(PKGCONFIG_TARGET_LIBNAME ${EGPF_LIB_NAME}) @@ -135,6 +166,7 @@ function(ECM_GENERATE_PKGCONFIG_FILE) else() set(PKGCONFIG_TARGET_LIBS "${CMAKE_INSTALL_PREFIX}/${EGPF_LIB_INSTALL_DIR}") endif() + set(PKGCONFIG_TARGET_DESCRIPTION "${EGPF_DESCRIPTION}") set(PKGCONFIG_TARGET_DEFINES "") if(EGPF_DEFINES) set(PKGCONFIG_TARGET_DEFINES "${EGPF_DEFINE}") @@ -148,6 +180,7 @@ function(ECM_GENERATE_PKGCONFIG_FILE) file(WRITE ${PKGCONFIG_FILENAME} " Name: ${PKGCONFIG_TARGET_LIBNAME} +Description: ${PKGCONFIG_TARGET_DESCRIPTION} Version: ${PROJECT_VERSION} Libs: -L${CMAKE_INSTALL_PREFIX}/${EGPF_LIB_INSTALL_DIR} -l${PKGCONFIG_TARGET_LIBNAME} Cflags: ${PKGCONFIG_TARGET_INCLUDES} ${PKGCONFIG_TARGET_DEFINES} @@ -156,8 +189,11 @@ Requires: ${PKGCONFIG_TARGET_DEPS} ) if(EGPF_INSTALL) - set(ECM_PKGCONFIG_INSTALL_DIR "${EGPF_LIB_INSTALL_DIR}/pkgconfig" CACHE PATH "The directory where pkgconfig will be installed to.") + if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + set(ECM_PKGCONFIG_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/libdata/pkgconfig" CACHE PATH "The directory where pkgconfig will be installed to.") + else() + set(ECM_PKGCONFIG_INSTALL_DIR "${EGPF_LIB_INSTALL_DIR}/pkgconfig" CACHE PATH "The directory where pkgconfig will be installed to.") + endif() install(FILES ${PKGCONFIG_FILENAME} DESTINATION ${ECM_PKGCONFIG_INSTALL_DIR}) endif() endfunction() - diff --git a/Source/cmake/FindICU.cmake b/Source/cmake/FindICU.cmake index 4e93286f3..c0de36338 100644 --- a/Source/cmake/FindICU.cmake +++ b/Source/cmake/FindICU.cmake @@ -24,7 +24,7 @@ mark_as_advanced(ICU_INCLUDE_DIR) # Look for the library. find_library( ICU_LIBRARY - NAMES icuuc cygicuuc cygicuuc32 + NAMES sicuuc icuuc cygicuuc cygicuuc32 HINTS ${PC_ICU_LIBRARY_DIRS} ${PC_ICU_LIBDIR} DOC "Libraries to link against for the common parts of ICU") @@ -49,7 +49,7 @@ if (ICU_INCLUDE_DIR AND ICU_LIBRARY) pkg_check_modules(PC_ICU_I18N icu-i18n) find_library( ICU_I18N_LIBRARY - NAMES icui18n icuin cygicuin cygicuin32 + NAMES sicui18n sicuin icui18n icuin cygicuin cygicuin32 HINTS ${PC_ICU_I18N_LIBRARY_DIRS} ${PC_ICU_I18N_LIBDIR} DOC "Libraries to link against for ICU internationalization") diff --git a/Source/cmake/OptionsQt.cmake b/Source/cmake/OptionsQt.cmake index cbdaa192b..9ca197f72 100644 --- a/Source/cmake/OptionsQt.cmake +++ b/Source/cmake/OptionsQt.cmake @@ -183,6 +183,13 @@ if (QT_CORE_TYPE MATCHES STATIC) set(MACOS_BUILD_FRAMEWORKS OFF) endif () +# static icu libraries on windows are build with 's' prefix +if (QT_STATIC_BUILD AND MSVC) + set(ICU_LIBRARY_PREFIX "s") +else () + set(ICU_LIBRARY_PREFIX "") +endif () + if (QT_STATIC_BUILD) set(ENABLE_WEBKIT2_DEFAULT OFF) else () @@ -662,10 +669,19 @@ if (ENABLE_OPENGL) SET_AND_EXPOSE_TO_BUILD(USE_TEXTURE_MAPPER_GL TRUE) SET_AND_EXPOSE_TO_BUILD(ENABLE_GRAPHICS_CONTEXT_3D TRUE) - # TODO: Add proper support of DynamicGL detection to Qt and use it - if (WIN32 AND NOT QT_USES_GLES2_ONLY) - set(Qt5Gui_OPENGL_IMPLEMENTATION GL) + if (WIN32) + include(CheckCXXSymbolExists) + set(CMAKE_REQUIRED_INCLUDES ${Qt5Gui_INCLUDE_DIRS}) + set(CMAKE_REQUIRED_FLAGS ${Qt5Gui_EXECUTABLE_COMPILE_FLAGS}) + check_cxx_symbol_exists(QT_OPENGL_DYNAMIC qopenglcontext.h HAVE_QT_OPENGL_DYNAMIC) + if (HAVE_QT_OPENGL_DYNAMIC) + set(Qt5Gui_OPENGL_IMPLEMENTATION DynamicGL) + endif () + unset(CMAKE_REQUIRED_INCLUDES) + unset(CMAKE_REQUIRED_FLAGS) endif () + + message("Qt OpenGL implementation: ${Qt5Gui_OPENGL_IMPLEMENTATION}") endif () if (NOT ENABLE_VIDEO) @@ -857,7 +873,7 @@ if (MSVC) endif () if (NOT QT_CONAN_DIR) - set(ICU_LIBRARIES icuuc${CMAKE_DEBUG_POSTFIX} icuin${CMAKE_DEBUG_POSTFIX} icudt${CMAKE_DEBUG_POSTFIX}) + set(ICU_LIBRARIES ${ICU_LIBRARY_PREFIX}icuuc${CMAKE_DEBUG_POSTFIX} ${ICU_LIBRARY_PREFIX}icuin${CMAKE_DEBUG_POSTFIX} ${ICU_LIBRARY_PREFIX}icudt${CMAKE_DEBUG_POSTFIX}) endif () endif () diff --git a/Tools/qmake/projects/run_cmake.pro b/Tools/qmake/projects/run_cmake.pro index 74579c57e..fadfda059 100644 --- a/Tools/qmake/projects/run_cmake.pro +++ b/Tools/qmake/projects/run_cmake.pro @@ -62,10 +62,6 @@ build_pass|!debug_and_release { else: CMAKE_CONFIG += ZLIB_INCLUDE_DIRS=$$QTBASE_DIR/src/3rdparty/zlib } - qtConfig(opengles2):!qtConfig(dynamicgl) { - CMAKE_CONFIG += QT_USES_GLES2_ONLY=1 - } - exists($$ROOT_BUILD_DIR/conanbuildinfo.cmake):exists($$ROOT_BUILD_DIR/conanfile.txt) { CMAKE_CONFIG += QT_CONAN_DIR=$$ROOT_BUILD_DIR } diff --git a/Tools/qt/make-snapshot.pl b/Tools/qt/make-snapshot.pl index 667890de0..2c2af1a9f 100755 --- a/Tools/qt/make-snapshot.pl +++ b/Tools/qt/make-snapshot.pl @@ -36,7 +36,7 @@ scalar @ARGV == 0 || usage(); -f "ChangeLog" && die "This script must be run in snapshots repository"; -d ".git" || usage(); -`git status` =~ "nothing to commit, working tree clean" or die "Target working tree is dirty"; +`LC_ALL=C LANG=C git status` =~ "nothing to commit, working tree clean" or die "Target working tree is dirty"; my $src_repo = dirname(dirname(dirname(__FILE__))); my $target_repo = getcwd(); -- cgit v1.2.3