LCOV - code coverage report
Current view: top level - libgnucash/engine - qoflog.cpp (source / functions) Coverage Total Hit
Test: gnucash.info Lines: 61.3 % 238 146
Test Date: 2025-10-25 17:50:22 Functions: 90.0 % 20 18
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* **************************************************************************
       2                 :             :  *            qoflog.c
       3                 :             :  *
       4                 :             :  *  Mon Nov 21 14:41:59 2005
       5                 :             :  *  Author: Rob Clark (rclark@cs.hmc.edu)
       6                 :             :  *  Copyright (C) 1997-2003 Linas Vepstas <linas@linas.org>
       7                 :             :  *  Copyright  2005  Neil Williams <linux@codehelp.co.uk>
       8                 :             :  *  Copyright 2007 Joshua Sled <jsled@asynchronous.org>
       9                 :             :  *************************************************************************** */
      10                 :             : 
      11                 :             : /*
      12                 :             :  *  This program is free software; you can redistribute it and/or modify
      13                 :             :  *  it under the terms of the GNU General Public License as published by
      14                 :             :  *  the Free Software Foundation; either version 2 of the License, or
      15                 :             :  *  (at your option) any later version.
      16                 :             :  *
      17                 :             :  *  This program is distributed in the hope that it will be useful,
      18                 :             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      19                 :             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      20                 :             :  *  GNU General Public License for more details.
      21                 :             :  *
      22                 :             :  *  You should have received a copy of the GNU General Public License
      23                 :             :  *  along with this program; if not, write to the Free Software
      24                 :             :  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
      25                 :             :  *  02110-1301,  USA
      26                 :             :  */
      27                 :             : #include <glib.h>
      28                 :             : #include <glib/gstdio.h>
      29                 :             : 
      30                 :             : #include <config.h>
      31                 :             : 
      32                 :             : #include <platform.h>
      33                 :             : #if PLATFORM(WINDOWS)
      34                 :             : #include <windows.h>
      35                 :             : #endif
      36                 :             : 
      37                 :             : #ifdef HAVE_UNISTD_H
      38                 :             : # include <unistd.h>
      39                 :             : #else
      40                 :             : # ifdef __GNUC__
      41                 :             : #  warning "<unistd.h> required."
      42                 :             : # endif
      43                 :             : #endif
      44                 :             : #include <stdarg.h>
      45                 :             : #include <stdlib.h>
      46                 :             : #include <string.h>
      47                 :             : #include <stdio.h>
      48                 :             : 
      49                 :             : #undef G_LOG_DOMAIN
      50                 :             : #define G_LOG_DOMAIN "qof.log"
      51                 :             : #include "qof.h"
      52                 :             : #include "qoflog.h"
      53                 :             : #include <string>
      54                 :             : #include <string_view>
      55                 :             : #include <vector>
      56                 :             : #include <memory>
      57                 :             : #include <algorithm>
      58                 :             : 
      59                 :             : #define QOF_LOG_MAX_CHARS 50
      60                 :             : #define QOF_LOG_MAX_CHARS_WITH_ALLOWANCE 100
      61                 :             : #define QOF_LOG_INDENT_WIDTH 4
      62                 :             : #define NUM_CLOCKS 10
      63                 :             : 
      64                 :             : static FILE *fout = nullptr;
      65                 :             : static gchar* function_buffer = nullptr;
      66                 :             : static gint qof_log_num_spaces = 0;
      67                 :             : static GLogFunc previous_handler = nullptr;
      68                 :             : static gchar* qof_logger_format = nullptr;
      69                 :             : static QofLogModule log_module = "qof";
      70                 :             : 
      71                 :             : using StrVec = std::vector<std::string>;
      72                 :             : 
      73                 :             : struct ModuleEntry;
      74                 :             : using ModuleEntryPtr = std::unique_ptr<ModuleEntry>;
      75                 :             : using MEVec = std::vector<ModuleEntryPtr>;
      76                 :             : 
      77                 :             : static constexpr int parts = 4; //Log domain parts vector preallocation size
      78                 :             : static constexpr QofLogLevel default_level = QOF_LOG_WARNING;
      79                 :             : static QofLogLevel current_max{default_level};
      80                 :             : 
      81                 :             : struct ModuleEntry
      82                 :             : {
      83                 :         114 :     ModuleEntry(const std::string& name, QofLogLevel level) :
      84                 :         114 :         m_name{name}, m_level{level} {
      85                 :         114 :             m_children.reserve(parts);
      86                 :         114 :         }
      87                 :         114 :     ~ModuleEntry() = default;
      88                 :             :     std::string m_name;
      89                 :             :     QofLogLevel m_level;
      90                 :             :     MEVec m_children;
      91                 :             : };
      92                 :             : 
      93                 :             : static ModuleEntryPtr _modules = nullptr;
      94                 :             : 
      95                 :             : static ModuleEntry*
      96                 :       85039 : get_modules()
      97                 :             : {
      98                 :       85039 :     if (!_modules)
      99                 :         110 :         _modules = std::make_unique<ModuleEntry>("", default_level);
     100                 :       85039 :     return _modules.get();
     101                 :             : }
     102                 :             : 
     103                 :             : static StrVec
     104                 :       84913 : split_domain (const std::string_view domain)
     105                 :             : {
     106                 :       84913 :     StrVec domain_parts;
     107                 :       84913 :     domain_parts.reserve(parts);
     108                 :       84913 :     int start = 0;
     109                 :       84913 :     auto pos = domain.find(".");
     110                 :       84913 :     if (pos == std::string_view::npos)
     111                 :             :     {
     112                 :           1 :         domain_parts.emplace_back(domain);
     113                 :             :     }
     114                 :             :     else
     115                 :             :     {
     116                 :      170258 :         while (pos != std::string_view::npos)
     117                 :             :         {
     118                 :       85346 :             auto part_name{domain.substr(start, pos - start)};
     119                 :       85346 :             domain_parts.emplace_back(part_name);
     120                 :       85346 :             start = pos + 1;
     121                 :       85346 :             pos = domain.find(".", start);
     122                 :             :         }
     123                 :       84912 :         auto part_name{domain.substr(start, pos)};
     124                 :       84912 :         domain_parts.emplace_back(part_name);
     125                 :             :     }
     126                 :       84913 :     return domain_parts;
     127                 :           0 : }
     128                 :             : 
     129                 :             : void
     130                 :         943 : qof_log_indent(void)
     131                 :             : {
     132                 :         943 :     qof_log_num_spaces += QOF_LOG_INDENT_WIDTH;
     133                 :         943 : }
     134                 :             : 
     135                 :             : void
     136                 :         943 : qof_log_dedent(void)
     137                 :             : {
     138                 :             :     qof_log_num_spaces
     139                 :         943 :     = (qof_log_num_spaces < QOF_LOG_INDENT_WIDTH)
     140                 :         943 :       ? 0
     141                 :             :       : qof_log_num_spaces - QOF_LOG_INDENT_WIDTH;
     142                 :         943 : }
     143                 :             : 
     144                 :             : void
     145                 :           7 : qof_log_set_file(FILE *outfile)
     146                 :             : {
     147                 :           7 :     if (!outfile)
     148                 :             :     {
     149                 :           0 :         fout = stderr;
     150                 :           0 :         return;
     151                 :             :     }
     152                 :           7 :     fout = outfile;
     153                 :             : }
     154                 :             : 
     155                 :             : void
     156                 :         126 : qof_log_init(void)
     157                 :             : {
     158                 :         126 :     qof_log_init_filename(nullptr);
     159                 :         126 : }
     160                 :             : 
     161                 :             : static void
     162                 :        7563 : log4glib_handler(const gchar     *log_domain,
     163                 :             :                  GLogLevelFlags  log_level,
     164                 :             :                  const gchar     *message,
     165                 :             :                  gpointer        user_data)
     166                 :             : {
     167                 :        7563 :     QofLogLevel level = static_cast<QofLogLevel>(log_level);
     168                 :        7563 :     if (G_LIKELY(!qof_log_check(log_domain, level)))
     169                 :        5863 :         return;
     170                 :             : 
     171                 :             :     {
     172                 :             :         char timestamp_buf[10];
     173                 :             :         time64 now;
     174                 :             :         struct tm now_tm;
     175                 :        1700 :         const char *format_24hour =
     176                 :             : #ifdef G_OS_WIN32
     177                 :             :             "%H:%M:%S"
     178                 :             : #else
     179                 :             :             "%T"
     180                 :             : #endif
     181                 :             :             ;
     182                 :        1700 :         const char *level_str = qof_log_level_to_string(level);
     183                 :        1700 :         now = gnc_time (nullptr);
     184                 :        1700 :         gnc_localtime_r (&now, &now_tm);
     185                 :        1700 :         qof_strftime(timestamp_buf, 9, format_24hour, &now_tm);
     186                 :             : 
     187                 :        1700 :         fprintf(fout, qof_logger_format,
     188                 :             :                 timestamp_buf,
     189                 :             :                 5, level_str,
     190                 :             :                 (log_domain == nullptr ? "" : log_domain),
     191                 :             :                 qof_log_num_spaces, "",
     192                 :             :                 message,
     193                 :        1700 :                 (g_str_has_suffix(message, "\n") ? "" : "\n"));
     194                 :        1700 :         fflush(fout);
     195                 :             :     }
     196                 :             : 
     197                 :             :     /* chain?  ignore?  Only chain if it's going to be quiet...
     198                 :             :     else
     199                 :             :     {
     200                 :             :          // chain
     201                 :             :          previous_handler(log_domain, log_level, message, nullptr);
     202                 :             :     }
     203                 :             :     */
     204                 :             : }
     205                 :             : 
     206                 :             : void
     207                 :         126 : qof_log_init_filename(const gchar* log_filename)
     208                 :             : {
     209                 :         126 :     gboolean warn_about_missing_permission = FALSE;
     210                 :         126 :     auto modules = get_modules();
     211                 :             : 
     212                 :         126 :     if (!qof_logger_format)
     213                 :         110 :         qof_logger_format = g_strdup ("* %s %*s <%s> %*s%s%s"); //default format
     214                 :             : 
     215                 :         126 :     if (log_filename)
     216                 :             :     {
     217                 :             :         int fd;
     218                 :             :         gchar *fname;
     219                 :             : 
     220                 :           0 :         if (fout != nullptr && fout != stderr && fout != stdout)
     221                 :           0 :             fclose(fout);
     222                 :             : 
     223                 :           0 :         fname = g_strconcat(log_filename, ".XXXXXX.log", nullptr);
     224                 :             : 
     225                 :           0 :         if ((fd = g_mkstemp(fname)) != -1)
     226                 :             :         {
     227                 :             : #if PLATFORM(WINDOWS)
     228                 :             :             /* MSVC compiler: Somehow the OS thinks file descriptor from above
     229                 :             :              * still isn't open. So we open normally with the file name and that's it. */
     230                 :             :             fout = g_fopen(fname, "wb");
     231                 :             : #else
     232                 :             :             /* We must not overwrite /dev/null */
     233                 :           0 :             g_assert(g_strcmp0(log_filename, "/dev/null") != 0);
     234                 :             : 
     235                 :             :             /* Windows prevents renaming of open files, so the next command silently fails there
     236                 :             :              * No problem, the filename on Windows will simply have the random characters */
     237                 :           0 :             g_rename(fname, log_filename);
     238                 :           0 :             fout = fdopen(fd, "w");
     239                 :             : #endif
     240                 :           0 :             if (!fout)
     241                 :           0 :                 warn_about_missing_permission = TRUE;
     242                 :             :         }
     243                 :             :         else
     244                 :             :         {
     245                 :           0 :             warn_about_missing_permission = TRUE;
     246                 :           0 :             fout = stderr;
     247                 :             :         }
     248                 :           0 :         g_free(fname);
     249                 :             :     }
     250                 :             : 
     251                 :         126 :     if (!fout)
     252                 :          96 :         fout = stderr;
     253                 :             : 
     254                 :         126 :     if (previous_handler == nullptr)
     255                 :         110 :         previous_handler = g_log_set_default_handler(log4glib_handler, modules);
     256                 :             : 
     257                 :         126 :     if (warn_about_missing_permission)
     258                 :             :     {
     259                 :           0 :         g_critical("Cannot open log output file \"%s\", using stderr.", log_filename);
     260                 :             :     }
     261                 :         126 : }
     262                 :             : 
     263                 :             : void
     264                 :          43 : qof_log_shutdown (void)
     265                 :             : {
     266                 :          43 :     if (fout && fout != stderr && fout != stdout)
     267                 :             :     {
     268                 :           0 :         fclose(fout);
     269                 :           0 :         fout = nullptr;
     270                 :             :     }
     271                 :             : 
     272                 :          43 :     if (qof_logger_format)
     273                 :             :     {
     274                 :          43 :         g_free (qof_logger_format);
     275                 :          43 :         qof_logger_format = nullptr;
     276                 :             :     }
     277                 :             : 
     278                 :          43 :     if (function_buffer)
     279                 :             :     {
     280                 :           9 :         g_free(function_buffer);
     281                 :           9 :         function_buffer = nullptr;
     282                 :             :     }
     283                 :             : 
     284                 :          43 :     if (_modules != nullptr)
     285                 :             :     {
     286                 :          43 :         _modules = nullptr;
     287                 :             :     }
     288                 :             : 
     289                 :          43 :     if (previous_handler != nullptr)
     290                 :             :     {
     291                 :          43 :         g_log_set_default_handler(previous_handler, nullptr);
     292                 :          43 :         previous_handler = nullptr;
     293                 :             :     }
     294                 :          43 : }
     295                 :             : 
     296                 :             : void
     297                 :           3 : qof_log_set_level(QofLogModule log_module, QofLogLevel level)
     298                 :             : {
     299                 :           3 :     if (!log_module || level == QOF_LOG_FATAL)
     300                 :           0 :         return;
     301                 :             : 
     302                 :           3 :     if (level > current_max)
     303                 :           2 :         current_max = level;
     304                 :             : 
     305                 :           3 :     auto module_parts = split_domain(log_module);
     306                 :           3 :     auto module = get_modules();
     307                 :           8 :     for (auto part : module_parts)
     308                 :             :     {
     309                 :           5 :         auto iter = std::find_if(module->m_children.begin(),
     310                 :             :                               module->m_children.end(),
     311                 :          10 :                               [part](auto& child){
     312                 :           2 :                                   return child && part == child->m_name;
     313                 :             :                               });
     314                 :           5 :         if (iter == module->m_children.end())
     315                 :             :         {
     316                 :           4 :             auto child = std::make_unique<ModuleEntry>(part, default_level);
     317                 :           4 :             module->m_children.emplace_back(std::move(child));
     318                 :           4 :             module = module->m_children.back().get();
     319                 :           4 :         }
     320                 :             :         else
     321                 :             :         {
     322                 :           1 :             module = iter->get();
     323                 :             :         }
     324                 :           5 :     }
     325                 :           3 :     module->m_level = level;
     326                 :           3 : }
     327                 :             : 
     328                 :             : 
     329                 :             : gboolean
     330                 :     1180657 : qof_log_check(QofLogModule domain, QofLogLevel level)
     331                 :             : {
     332                 :             : // Check the global levels
     333                 :     1180657 :     if (level > current_max)
     334                 :     1094047 :         return FALSE;
     335                 :       86610 :     if (level <= default_level)
     336                 :        1700 :         return TRUE;
     337                 :       84910 :     auto module = get_modules();
     338                 :             :     // If the level <= the default then no need to look further.
     339                 :       84910 :     if (level <= module->m_level)
     340                 :           0 :         return TRUE;
     341                 :             : 
     342                 :       84910 :     if (!domain)
     343                 :           0 :         return FALSE;
     344                 :             : 
     345                 :       84910 :     auto domain_vec = split_domain(domain);
     346                 :             : 
     347                 :       86324 :     for (const auto& part : domain_vec)
     348                 :             :     {
     349                 :       86324 :         auto iter = std::find_if(module->m_children.begin(),
     350                 :             :                                module->m_children.end(),
     351                 :      172648 :                                [part](auto& child) {
     352                 :       87340 :                                    return child && part == child->m_name; });
     353                 :             : 
     354                 :       86324 :         if (iter == module->m_children.end())
     355                 :       84910 :             return FALSE;
     356                 :             : 
     357                 :        4648 :         if (level <= (*iter)->m_level)
     358                 :        3234 :             return TRUE;
     359                 :             : 
     360                 :        1414 :         module = iter->get();
     361                 :             :     }
     362                 :           0 :     return FALSE;
     363                 :       84910 : }
     364                 :             : 
     365                 :             : const char *
     366                 :        4475 : qof_log_prettify (const char *name)
     367                 :             : {
     368                 :             :     gchar *p, *buffer, *begin;
     369                 :             :     gint length;
     370                 :             : 
     371                 :        4475 :     if (!name)
     372                 :             :     {
     373                 :           0 :         return "";
     374                 :             :     }
     375                 :             : /* Clang's __func__ displays the whole signature, like a good C++
     376                 :             :  * compier should. Gcc displays only the name of the function. Strip
     377                 :             :  * the extras from Clang's output so that log messages are the same
     378                 :             :  * regardless of compiler.
     379                 :             :  */
     380                 :        4475 :     buffer = g_strndup(name, QOF_LOG_MAX_CHARS_WITH_ALLOWANCE - 1);
     381                 :        4475 :     length = strlen(buffer);
     382                 :        4475 :     p = g_strstr_len (buffer, length, "(");
     383                 :        4475 :     if (p) *p = '\0';
     384                 :        4475 :     begin = g_strrstr (buffer, "*");
     385                 :        4475 :     if (begin == nullptr)
     386                 :        3060 :         begin = g_strrstr (buffer, " ");
     387                 :        1415 :     else if (* (begin + 1) == ' ')
     388                 :        1413 :         ++ begin;
     389                 :        4475 :     if (begin != nullptr)
     390                 :        4437 :         p = begin + 1;
     391                 :             :     else
     392                 :          38 :         p = buffer;
     393                 :             : 
     394                 :        4475 :     if (function_buffer)
     395                 :        4444 :         g_free(function_buffer);
     396                 :        4475 :     function_buffer = g_strdup(p);
     397                 :        4475 :     g_free(buffer);
     398                 :        4475 :     return function_buffer;
     399                 :             : }
     400                 :             : 
     401                 :             : void
     402                 :           7 : qof_log_init_filename_special(const char *log_to_filename)
     403                 :             : {
     404                 :           7 :     if (g_ascii_strcasecmp("stderr", log_to_filename) == 0)
     405                 :             :     {
     406                 :           7 :         qof_log_init();
     407                 :           7 :         qof_log_set_file(stderr);
     408                 :             :     }
     409                 :           0 :     else if (g_ascii_strcasecmp("stdout", log_to_filename) == 0)
     410                 :             :     {
     411                 :           0 :         qof_log_init();
     412                 :           0 :         qof_log_set_file(stdout);
     413                 :             :     }
     414                 :             :     else
     415                 :             :     {
     416                 :           0 :         qof_log_init_filename(log_to_filename);
     417                 :             :     }
     418                 :           7 : }
     419                 :             : 
     420                 :             : void
     421                 :           0 : qof_log_parse_log_config(const char *filename)
     422                 :             : {
     423                 :           0 :     const gchar *levels_group = "levels", *output_group = "output";
     424                 :           0 :     GError *err = nullptr;
     425                 :           0 :     GKeyFile *conf = g_key_file_new();
     426                 :             : 
     427                 :           0 :     if (!g_key_file_load_from_file(conf, filename, G_KEY_FILE_NONE, &err))
     428                 :             :     {
     429                 :           0 :         g_warning("unable to parse [%s]: %s", filename, err->message);
     430                 :           0 :         g_error_free(err);
     431                 :           0 :         return;
     432                 :             :     }
     433                 :             : 
     434                 :           0 :     DEBUG("parsing log config from [%s]", filename);
     435                 :           0 :     if (g_key_file_has_group(conf, levels_group))
     436                 :             :     {
     437                 :             :         gsize num_levels;
     438                 :             :         unsigned int key_idx;
     439                 :             :         gchar **levels;
     440                 :           0 :         gint logger_max_name_length = 12;
     441                 :           0 :         gchar *str = nullptr;
     442                 :             : 
     443                 :           0 :         levels = g_key_file_get_keys(conf, levels_group, &num_levels, nullptr);
     444                 :             : 
     445                 :           0 :         for (key_idx = 0; key_idx < num_levels && levels[key_idx] != nullptr; key_idx++)
     446                 :             :         {
     447                 :             :             QofLogLevel level;
     448                 :           0 :             gchar *logger_name = nullptr, *level_str = nullptr;
     449                 :             : 
     450                 :           0 :             logger_name = g_strdup(levels[key_idx]);
     451                 :           0 :             logger_max_name_length = MAX (logger_max_name_length, (gint) strlen (logger_name));
     452                 :           0 :             level_str = g_key_file_get_string(conf, levels_group, logger_name, nullptr);
     453                 :           0 :             level = qof_log_level_from_string(level_str);
     454                 :             : 
     455                 :           0 :             DEBUG("setting log [%s] to level [%s=%d]", logger_name, level_str, level);
     456                 :           0 :             qof_log_set_level(logger_name, level);
     457                 :             : 
     458                 :           0 :             g_free(logger_name);
     459                 :           0 :             g_free(level_str);
     460                 :             :         }
     461                 :             : 
     462                 :           0 :         str = g_strdup_printf ("%d", logger_max_name_length);
     463                 :           0 :         if (qof_logger_format)
     464                 :           0 :             g_free (qof_logger_format);
     465                 :           0 :         qof_logger_format = g_strconcat ("* %s %*s <%-", str, ".", str, "s> %*s%s%s", nullptr);
     466                 :             : 
     467                 :           0 :         g_free (str);
     468                 :           0 :         g_strfreev(levels);
     469                 :             :     }
     470                 :             : 
     471                 :           0 :     if (g_key_file_has_group(conf, output_group))
     472                 :             :     {
     473                 :             :         gsize num_outputs;
     474                 :             :         unsigned int output_idx;
     475                 :             :         gchar **outputs;
     476                 :             : 
     477                 :           0 :         outputs = g_key_file_get_keys(conf, output_group, &num_outputs, nullptr);
     478                 :           0 :         for (output_idx = 0; output_idx < num_outputs && outputs[output_idx] != nullptr; output_idx++)
     479                 :             :         {
     480                 :           0 :             gchar *key = outputs[output_idx];
     481                 :             :             gchar *value;
     482                 :             : 
     483                 :           0 :             if (g_ascii_strcasecmp("to", key) != 0)
     484                 :             :             {
     485                 :           0 :                 g_warning("unknown key [%s] in [outputs], skipping", key);
     486                 :           0 :                 continue;
     487                 :             :             }
     488                 :             : 
     489                 :           0 :             value = g_key_file_get_string(conf, output_group, key, nullptr);
     490                 :           0 :             DEBUG("setting [output].to=[%s]", value);
     491                 :           0 :             qof_log_init_filename_special(value);
     492                 :           0 :             g_free(value);
     493                 :             :         }
     494                 :           0 :         g_strfreev(outputs);
     495                 :             :     }
     496                 :             : 
     497                 :           0 :     g_key_file_free(conf);
     498                 :             : }
     499                 :             : 
     500                 :             : const gchar*
     501                 :        1700 : qof_log_level_to_string(QofLogLevel log_level)
     502                 :             : {
     503                 :             :     const char *level_str;
     504                 :        1700 :     switch (log_level)
     505                 :             :     {
     506                 :           0 :     case QOF_LOG_FATAL:
     507                 :           0 :         level_str = "FATAL";
     508                 :           0 :         break;
     509                 :        1520 :     case QOF_LOG_ERROR:
     510                 :        1520 :         level_str = "ERROR";
     511                 :        1520 :         break;
     512                 :         180 :     case QOF_LOG_WARNING:
     513                 :         180 :         level_str = "WARN";
     514                 :         180 :         break;
     515                 :           0 :     case QOF_LOG_MESSAGE:
     516                 :           0 :         level_str = "MESSG";
     517                 :           0 :         break;
     518                 :           0 :     case QOF_LOG_INFO:
     519                 :           0 :         level_str = "INFO";
     520                 :           0 :         break;
     521                 :           0 :     case QOF_LOG_DEBUG:
     522                 :           0 :         level_str = "DEBUG";
     523                 :           0 :         break;
     524                 :           0 :     default:
     525                 :           0 :         level_str = "OTHER";
     526                 :           0 :         break;
     527                 :             :     }
     528                 :        1700 :     return level_str;
     529                 :             : }
     530                 :             : 
     531                 :             : QofLogLevel
     532                 :           0 : qof_log_level_from_string(const gchar *str)
     533                 :             : {
     534                 :           0 :     if (g_ascii_strncasecmp("error", str, 5) == 0) return QOF_LOG_FATAL;
     535                 :           0 :     if (g_ascii_strncasecmp("crit", str, 4) == 0) return QOF_LOG_ERROR;
     536                 :           0 :     if (g_ascii_strncasecmp("warn", str, 4) == 0) return QOF_LOG_WARNING;
     537                 :           0 :     if (g_ascii_strncasecmp("mess", str, 4) == 0) return QOF_LOG_MESSAGE;
     538                 :           0 :     if (g_ascii_strncasecmp("info", str, 4) == 0) return QOF_LOG_INFO;
     539                 :           0 :     if (g_ascii_strncasecmp("debug", str, 5) == 0) return QOF_LOG_DEBUG;
     540                 :           0 :     return QOF_LOG_DEBUG;
     541                 :             : }
        

Generated by: LCOV version 2.0-1