desktop/source/lib/init.cxx               |   30 ++++++++++++++
 include/LibreOfficeKit/LibreOfficeKit.h   |    3 +
 include/LibreOfficeKit/LibreOfficeKit.hxx |   33 +++++++++++++++
 include/sal/log.hxx                       |    2 
 sal/osl/all/log.cxx                       |   63 +++++++++++++++++-------------
 sal/util/sal.map                          |    1 
 6 files changed, 106 insertions(+), 26 deletions(-)

New commits:
commit 41ff704cc49b7097b717882616011962ecd7198f
Author:     Tor Lillqvist <t...@collabora.com>
AuthorDate: Wed Apr 21 17:37:57 2021 +0300
Commit:     Tor Lillqvist <t...@collabora.com>
CommitDate: Wed Apr 28 09:30:17 2021 +0200

    Add API to LibreOfficeKit to set arbitrary run-time options in core
    
    Add setOption(const char*, const char*)
    
    At the moment this enables starting and stopping the ProfileZone event
    recording and overriding the SAL_LOG environment variable.
    
    Change-Id: Ic3a934bb4246c755a91eee8a8343fafc15815116
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114439
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Tor Lillqvist <t...@collabora.com>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114559
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114656
    Tested-by: Tor Lillqvist <t...@collabora.com>

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 23400d906628..ecbd0f3f97e5 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -2076,6 +2076,8 @@ static void lo_sendDialogEvent(LibreOfficeKit* pThis,
                                unsigned long long int nLOKWindowId,
                                const char* pArguments);
 
+static void lo_setOption(LibreOfficeKit* pThis, const char* pOption, const 
char* pValue);
+
 LibLibreOffice_Impl::LibLibreOffice_Impl()
     : m_pOfficeClass( gOfficeClass.lock() )
     , maThread(nullptr)
@@ -2101,6 +2103,7 @@ LibLibreOffice_Impl::LibLibreOffice_Impl()
         m_pOfficeClass->signDocument = lo_signDocument;
         m_pOfficeClass->runLoop = lo_runLoop;
         m_pOfficeClass->sendDialogEvent = lo_sendDialogEvent;
+        m_pOfficeClass->setOption = lo_setOption;
 
         gOfficeClass = m_pOfficeClass;
     }
@@ -3842,6 +3845,33 @@ static void lo_sendDialogEvent(LibreOfficeKit* 
/*pThis*/, unsigned long long int
     lcl_sendDialogEvent(nWindowId, pArguments);
 }
 
+static void lo_setOption(LibreOfficeKit* /*pThis*/, const char *pOption, const 
char* pValue)
+{
+    static char* pCurrentSalLogOverride = nullptr;
+
+    if (strcmp(pOption, "profilezonerecording") == 0)
+    {
+        if (strcmp(pValue, "start") == 0)
+            comphelper::ProfileZone::startRecording();
+        else if (strcmp(pValue, "stop") == 0)
+            comphelper::ProfileZone::stopRecording();
+    }
+    else if (strcmp(pOption, "sallogoverride") == 0)
+    {
+        if (pCurrentSalLogOverride != nullptr)
+            free(pCurrentSalLogOverride);
+        if (pValue == nullptr)
+            pCurrentSalLogOverride = nullptr;
+        else
+            pCurrentSalLogOverride = strdup(pValue);
+
+        if (pCurrentSalLogOverride == nullptr || pCurrentSalLogOverride[0] == 
'\0')
+            sal_detail_set_log_selector(nullptr);
+        else
+            sal_detail_set_log_selector(pCurrentSalLogOverride);
+    }
+}
+
 static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* 
pCommand, const char* pArguments, bool bNotifyWhenFinished)
 {
     comphelper::ProfileZone aZone("doc_postUnoCommand");
diff --git a/include/LibreOfficeKit/LibreOfficeKit.h 
b/include/LibreOfficeKit/LibreOfficeKit.h
index 2279260d0e90..82738d65ff93 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/include/LibreOfficeKit/LibreOfficeKit.h
@@ -115,6 +115,9 @@ struct _LibreOfficeKitClass
     void (*sendDialogEvent) (LibreOfficeKit* pThis,
                             unsigned long long int nLOKWindowId,
                             const char* pArguments);
+
+    /// @see lok::Office::setOption
+    void (*setOption) (LibreOfficeKit* pThis, const char* pOption, const char* 
pValue);
 };
 
 #define LIBREOFFICEKIT_DOCUMENT_HAS(pDoc,member) 
LIBREOFFICEKIT_HAS_MEMBER(LibreOfficeKitDocumentClass,member,(pDoc)->pClass->nSize)
diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx 
b/include/LibreOfficeKit/LibreOfficeKit.hxx
index 962270452e20..06fe5abc19e2 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.hxx
+++ b/include/LibreOfficeKit/LibreOfficeKit.hxx
@@ -990,6 +990,39 @@ public:
     {
         mpThis->pClass->sendDialogEvent(mpThis, nWindowId, pArguments);
     }
+
+    /**
+     * Generic function to toggle and tweak various things in the core LO
+     *
+     * The currently available option names and their allowed values are:
+     *
+     * "profilezonerecording": "start" or "stop"
+     * Start or stop recording profile zone trace data in the process.
+     *
+     * "sallogoverride": "<string>"
+     * Override the SAL_LOG environment variable
+     *
+     * For the syntax of the string see the documentation for "Basic
+     * logging functionality" in LibreOffice internal API
+     * documentation (include/sal/log.hxx). If the logging selector
+     * has been set by this function to a non-empty value, that is used
+     * instead of the environment variable SAL_LOG.
+     *
+     * The parameter is not copied so you should pass a value that
+     * points to memory that will stay valid until you call setOption
+     * with this option name the next time.
+     *
+     * If you pass nullptr or an empty string as value, the
+     * environment variable SAL_LOG is again used as by default. You
+     * can switch back and forth as you like.
+     *
+     * @param pOption the option name
+     * @param pValue its value
+     */
+    void setOption(const char* pOption, const char* pValue)
+    {
+        mpThis->pClass->setOption(mpThis, pOption, pValue);
+    }
 };
 
 /// Factory method to create a lok::Office instance.
diff --git a/include/sal/log.hxx b/include/sal/log.hxx
index 6f9da7671b03..943ab3169bca 100644
--- a/include/sal/log.hxx
+++ b/include/sal/log.hxx
@@ -41,6 +41,8 @@ extern "C" SAL_DLLPUBLIC void SAL_CALL sal_detail_log(
     sal_detail_LogLevel level, char const * area, char const * where,
     char const * message, sal_uInt32 backtraceDepth);
 
+extern "C" SAL_DLLPUBLIC void SAL_CALL sal_detail_set_log_selector(char const 
*logSelector);
+
 // the return value is actually "enum sal_detail_LogAction", but due to ABI
 // compatibility, it's left as the original "sal_Bool" / "unsigned char".
 extern "C" SAL_DLLPUBLIC unsigned char SAL_CALL sal_detail_log_report(
diff --git a/sal/osl/all/log.cxx b/sal/osl/all/log.cxx
index 927e78b97064..c493f4ddf03e 100644
--- a/sal/osl/all/log.cxx
+++ b/sal/osl/all/log.cxx
@@ -125,7 +125,9 @@ char const* setEnvFromLoggingIniFile(const char* env, const 
char* key)
 }
 #endif
 
-char const * getLogLevel() {
+char const* pLogSelector = nullptr;
+
+char const* getLogLevelEnvVar() {
     static char const* const pLevel = [] {
         char const* pResult = nullptr;
 
@@ -176,33 +178,36 @@ std::ofstream * getLogFile() {
     return pFile;
 }
 
-void maybeOutputTimestamp(std::ostringstream &s) {
-    static const std::pair<bool, bool> aFlags = [] {
-        char const* env = getLogLevel();
-        bool outputTimestamp = false;
-        bool outputRelativeTimer = false;
-        for (char const* p = env; p && *p;)
+
+std::pair<bool, bool> getTimestampFlags(char const *selector)
+{
+    bool outputTimestamp = false;
+    bool outputRelativeTimer = false;
+    for (char const* p = selector; p && *p;)
         {
             if (*p++ == '+')
-            {
-                char const * p1 = p;
-                while (*p1 != '.' && *p1 != '+' && *p1 != '-' && *p1 != '\0') {
-                    ++p1;
-                }
-                if (equalStrings(p, p1 - p, 
RTL_CONSTASCII_STRINGPARAM("TIMESTAMP")))
-                    outputTimestamp = true;
-                else if (equalStrings(p, p1 - p, 
RTL_CONSTASCII_STRINGPARAM("RELATIVETIMER")))
-                    outputRelativeTimer = true;
-                char const * p2 = p1;
-                while (*p2 != '+' && *p2 != '-' && *p2 != '\0') {
-                    ++p2;
+                {
+                    char const * p1 = p;
+                    while (*p1 != '.' && *p1 != '+' && *p1 != '-' && *p1 != 
'\0') {
+                        ++p1;
+                    }
+                    if (equalStrings(p, p1 - p, 
RTL_CONSTASCII_STRINGPARAM("TIMESTAMP")))
+                        outputTimestamp = true;
+                    else if (equalStrings(p, p1 - p, 
RTL_CONSTASCII_STRINGPARAM("RELATIVETIMER")))
+                        outputRelativeTimer = true;
+                    char const * p2 = p1;
+                    while (*p2 != '+' && *p2 != '-' && *p2 != '\0') {
+                        ++p2;
+                    }
+                    p = p2;
                 }
-                p = p2;
-            }
         }
-        return std::pair(outputTimestamp, outputRelativeTimer);
-    }();
-    const auto& [outputTimestamp, outputRelativeTimer] = aFlags;
+    return std::pair(outputTimestamp, outputRelativeTimer);
+}
+
+void maybeOutputTimestamp(std::ostringstream &s) {
+    static const std::pair<bool, bool> aEnvFlags = 
getTimestampFlags(getLogLevelEnvVar());
+    const auto& [outputTimestamp, outputRelativeTimer] = (pLogSelector == 
nullptr ? aEnvFlags : getTimestampFlags(pLogSelector));
 
     if (outputTimestamp)
     {
@@ -340,6 +345,11 @@ void sal_detail_log(
 #endif
 }
 
+void sal_detail_set_log_selector(char const *logSelector)
+{
+    pLogSelector = logSelector;
+}
+
 void sal_detail_logFormat(
     sal_detail_LogLevel level, char const * area, char const * where,
     char const * format, ...)
@@ -372,12 +382,13 @@ unsigned char sal_detail_log_report(sal_detail_LogLevel 
level, char const * area
         return SAL_DETAIL_LOG_ACTION_LOG;
     }
     assert(area != nullptr);
-    static char const* const env = [] {
-        char const* pResult =  getLogLevel();
+    static char const* const envEnv = [] {
+        char const* pResult =  getLogLevelEnvVar();
         if (!pResult)
             pResult = "+WARN";
         return pResult;
     }();
+    char const* const env = (pLogSelector == nullptr ? envEnv : pLogSelector);
     std::size_t areaLen = std::strlen(area);
     enum Sense { POSITIVE = 0, NEGATIVE = 1 };
     std::size_t senseLen[2] = { 0, 1 };
diff --git a/sal/util/sal.map b/sal/util/sal.map
index dbd22c36ee16..49efb2a436cd 100644
--- a/sal/util/sal.map
+++ b/sal/util/sal.map
@@ -747,6 +747,7 @@ PRIVATE_1.6 { # LibreOffice 6.4
     global:
         rtl_str_toInt64_WithLength;
         rtl_ustr_toInt64_WithLength;
+        sal_detail_set_log_selector;
 } PRIVATE_1.5;
 
 PRIVATE_1.7 { # LibreOffice 7.1
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to