LCOV - code coverage report
Current view: top level - libgnucash/engine - qoflog.cpp (source / functions) Coverage Total Hit
Test: gnucash.info Lines: 60.9 % 235 143
Test Date: 2025-02-07 16:25:45 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                 :         113 :     ModuleEntry(const std::string& name, QofLogLevel level) :
      84                 :         113 :         m_name{name}, m_level{level} {
      85                 :         113 :             m_children.reserve(parts);
      86                 :         113 :         }
      87                 :         113 :     ~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                 :       84335 : get_modules()
      97                 :             : {
      98                 :       84335 :     if (!_modules)
      99                 :         109 :         _modules = std::make_unique<ModuleEntry>("", default_level);
     100                 :       84335 :     return _modules.get();
     101                 :             : }
     102                 :             : 
     103                 :             : static StrVec
     104                 :       84210 : split_domain (const std::string_view domain)
     105                 :             : {
     106                 :       84210 :     StrVec domain_parts;
     107                 :       84210 :     domain_parts.reserve(parts);
     108                 :       84210 :     int start = 0;
     109                 :       84210 :     auto pos = domain.find(".");
     110                 :       84210 :     if (pos == std::string_view::npos)
     111                 :             :     {
     112                 :           1 :         domain_parts.emplace_back(domain);
     113                 :             :     }
     114                 :             :     else
     115                 :             :     {
     116                 :      168852 :         while (pos != std::string_view::npos)
     117                 :             :         {
     118                 :       84643 :             auto part_name{domain.substr(start, pos - start)};
     119                 :       84643 :             domain_parts.emplace_back(part_name);
     120                 :       84643 :             start = pos + 1;
     121                 :       84643 :             pos = domain.find(".", start);
     122                 :             :         }
     123                 :       84209 :         auto part_name{domain.substr(start, pos)};
     124                 :       84209 :         domain_parts.emplace_back(part_name);
     125                 :             :     }
     126                 :       84210 :     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                 :         125 : qof_log_init(void)
     157                 :             : {
     158                 :         125 :     qof_log_init_filename(nullptr);
     159                 :         125 : }
     160                 :             : 
     161                 :             : static void
     162                 :        7568 : log4glib_handler(const gchar     *log_domain,
     163                 :             :                  GLogLevelFlags  log_level,
     164                 :             :                  const gchar     *message,
     165                 :             :                  gpointer        user_data)
     166                 :             : {
     167                 :        7568 :     QofLogLevel level = static_cast<QofLogLevel>(log_level);
     168                 :        7568 :     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                 :        1705 :         const char *format_24hour =
     176                 :             : #ifdef G_OS_WIN32
     177                 :             :             "%H:%M:%S"
     178                 :             : #else
     179                 :             :             "%T"
     180                 :             : #endif
     181                 :             :             ;
     182                 :        1705 :         const char *level_str = qof_log_level_to_string(level);
     183                 :        1705 :         now = gnc_time (nullptr);
     184                 :        1705 :         gnc_localtime_r (&now, &now_tm);
     185                 :        1705 :         qof_strftime(timestamp_buf, 9, format_24hour, &now_tm);
     186                 :             : 
     187                 :        1705 :         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                 :        1705 :                 (g_str_has_suffix(message, "\n") ? "" : "\n"));
     194                 :        1705 :         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                 :         125 : qof_log_init_filename(const gchar* log_filename)
     208                 :             : {
     209                 :         125 :     gboolean warn_about_missing_permission = FALSE;
     210                 :         125 :     auto modules = get_modules();
     211                 :             : 
     212                 :         125 :     if (!qof_logger_format)
     213                 :          95 :         qof_logger_format = g_strdup ("* %s %*s <%s> %*s%s%s"); //default format
     214                 :             : 
     215                 :         125 :     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                 :         125 :     if (!fout)
     252                 :          95 :         fout = stderr;
     253                 :             : 
     254                 :         125 :     if (previous_handler == nullptr)
     255                 :         109 :         previous_handler = g_log_set_default_handler(log4glib_handler, modules);
     256                 :             : 
     257                 :         125 :     if (warn_about_missing_permission)
     258                 :             :     {
     259                 :           0 :         g_critical("Cannot open log output file \"%s\", using stderr.", log_filename);
     260                 :             :     }
     261                 :         125 : }
     262                 :             : 
     263                 :             : void
     264                 :          42 : qof_log_shutdown (void)
     265                 :             : {
     266                 :          42 :     if (fout && fout != stderr && fout != stdout)
     267                 :             :     {
     268                 :           0 :         fclose(fout);
     269                 :           0 :         fout = nullptr;
     270                 :             :     }
     271                 :             : 
     272                 :          42 :     if (function_buffer)
     273                 :             :     {
     274                 :           9 :         g_free(function_buffer);
     275                 :           9 :         function_buffer = nullptr;
     276                 :             :     }
     277                 :             : 
     278                 :          42 :     if (_modules != nullptr)
     279                 :             :     {
     280                 :          42 :         _modules = nullptr;
     281                 :             :     }
     282                 :             : 
     283                 :          42 :     if (previous_handler != nullptr)
     284                 :             :     {
     285                 :          42 :         g_log_set_default_handler(previous_handler, nullptr);
     286                 :          42 :         previous_handler = nullptr;
     287                 :             :     }
     288                 :          42 : }
     289                 :             : 
     290                 :             : void
     291                 :           3 : qof_log_set_level(QofLogModule log_module, QofLogLevel level)
     292                 :             : {
     293                 :           3 :     if (!log_module || level == QOF_LOG_FATAL)
     294                 :           0 :         return;
     295                 :             : 
     296                 :           3 :     if (level > current_max)
     297                 :           2 :         current_max = level;
     298                 :             : 
     299                 :           3 :     auto module_parts = split_domain(log_module);
     300                 :           3 :     auto module = get_modules();
     301                 :           8 :     for (auto part : module_parts)
     302                 :             :     {
     303                 :           5 :         auto iter = std::find_if(module->m_children.begin(),
     304                 :             :                               module->m_children.end(),
     305                 :          10 :                               [part](auto& child){
     306                 :           2 :                                   return child && part == child->m_name;
     307                 :             :                               });
     308                 :           5 :         if (iter == module->m_children.end())
     309                 :             :         {
     310                 :           4 :             auto child = std::make_unique<ModuleEntry>(part, default_level);
     311                 :           4 :             module->m_children.emplace_back(std::move(child));
     312                 :           4 :             module = module->m_children.back().get();
     313                 :           4 :         }
     314                 :             :         else
     315                 :             :         {
     316                 :           1 :             module = iter->get();
     317                 :             :         }
     318                 :           5 :     }
     319                 :           3 :     module->m_level = level;
     320                 :           3 : }
     321                 :             : 
     322                 :             : 
     323                 :             : gboolean
     324                 :     1274118 : qof_log_check(QofLogModule domain, QofLogLevel level)
     325                 :             : {
     326                 :             : // Check the global levels
     327                 :     1274118 :     if (level > current_max)
     328                 :     1188206 :         return FALSE;
     329                 :       85912 :     if (level <= default_level)
     330                 :        1705 :         return TRUE;
     331                 :       84207 :     auto module = get_modules();
     332                 :             :     // If the level <= the default then no need to look further.
     333                 :       84207 :     if (level <= module->m_level)
     334                 :           0 :         return TRUE;
     335                 :             : 
     336                 :       84207 :     if (!domain)
     337                 :           0 :         return FALSE;
     338                 :             : 
     339                 :       84207 :     auto domain_vec = split_domain(domain);
     340                 :             : 
     341                 :       85577 :     for (const auto& part : domain_vec)
     342                 :             :     {
     343                 :       85577 :         auto iter = std::find_if(module->m_children.begin(),
     344                 :             :                                module->m_children.end(),
     345                 :      171154 :                                [part](auto& child) {
     346                 :       86557 :                                    return child && part == child->m_name; });
     347                 :             : 
     348                 :       85577 :         if (iter == module->m_children.end())
     349                 :       84207 :             return FALSE;
     350                 :             : 
     351                 :        4572 :         if (level <= (*iter)->m_level)
     352                 :        3202 :             return TRUE;
     353                 :             : 
     354                 :        1370 :         module = iter->get();
     355                 :             :     }
     356                 :           0 :     return FALSE;
     357                 :       84207 : }
     358                 :             : 
     359                 :             : const char *
     360                 :        4504 : qof_log_prettify (const char *name)
     361                 :             : {
     362                 :             :     gchar *p, *buffer, *begin;
     363                 :             :     gint length;
     364                 :             : 
     365                 :        4504 :     if (!name)
     366                 :             :     {
     367                 :           0 :         return "";
     368                 :             :     }
     369                 :             : /* Clang's __func__ displays the whole signature, like a good C++
     370                 :             :  * compier should. Gcc displays only the name of the function. Strip
     371                 :             :  * the extras from Clang's output so that log messages are the same
     372                 :             :  * regardless of compiler.
     373                 :             :  */
     374                 :        4504 :     buffer = g_strndup(name, QOF_LOG_MAX_CHARS_WITH_ALLOWANCE - 1);
     375                 :        4504 :     length = strlen(buffer);
     376                 :        4504 :     p = g_strstr_len (buffer, length, "(");
     377                 :        4504 :     if (p) *p = '\0';
     378                 :        4504 :     begin = g_strrstr (buffer, "*");
     379                 :        4504 :     if (begin == nullptr)
     380                 :        3089 :         begin = g_strrstr (buffer, " ");
     381                 :        1415 :     else if (* (begin + 1) == ' ')
     382                 :        1413 :         ++ begin;
     383                 :        4504 :     if (begin != nullptr)
     384                 :        4466 :         p = begin + 1;
     385                 :             :     else
     386                 :          38 :         p = buffer;
     387                 :             : 
     388                 :        4504 :     if (function_buffer)
     389                 :        4472 :         g_free(function_buffer);
     390                 :        4504 :     function_buffer = g_strdup(p);
     391                 :        4504 :     g_free(buffer);
     392                 :        4504 :     return function_buffer;
     393                 :             : }
     394                 :             : 
     395                 :             : void
     396                 :           7 : qof_log_init_filename_special(const char *log_to_filename)
     397                 :             : {
     398                 :           7 :     if (g_ascii_strcasecmp("stderr", log_to_filename) == 0)
     399                 :             :     {
     400                 :           7 :         qof_log_init();
     401                 :           7 :         qof_log_set_file(stderr);
     402                 :             :     }
     403                 :           0 :     else if (g_ascii_strcasecmp("stdout", log_to_filename) == 0)
     404                 :             :     {
     405                 :           0 :         qof_log_init();
     406                 :           0 :         qof_log_set_file(stdout);
     407                 :             :     }
     408                 :             :     else
     409                 :             :     {
     410                 :           0 :         qof_log_init_filename(log_to_filename);
     411                 :             :     }
     412                 :           7 : }
     413                 :             : 
     414                 :             : void
     415                 :           0 : qof_log_parse_log_config(const char *filename)
     416                 :             : {
     417                 :           0 :     const gchar *levels_group = "levels", *output_group = "output";
     418                 :           0 :     GError *err = nullptr;
     419                 :           0 :     GKeyFile *conf = g_key_file_new();
     420                 :             : 
     421                 :           0 :     if (!g_key_file_load_from_file(conf, filename, G_KEY_FILE_NONE, &err))
     422                 :             :     {
     423                 :           0 :         g_warning("unable to parse [%s]: %s", filename, err->message);
     424                 :           0 :         g_error_free(err);
     425                 :           0 :         return;
     426                 :             :     }
     427                 :             : 
     428                 :           0 :     DEBUG("parsing log config from [%s]", filename);
     429                 :           0 :     if (g_key_file_has_group(conf, levels_group))
     430                 :             :     {
     431                 :             :         gsize num_levels;
     432                 :             :         unsigned int key_idx;
     433                 :             :         gchar **levels;
     434                 :           0 :         gint logger_max_name_length = 12;
     435                 :           0 :         gchar *str = nullptr;
     436                 :             : 
     437                 :           0 :         levels = g_key_file_get_keys(conf, levels_group, &num_levels, nullptr);
     438                 :             : 
     439                 :           0 :         for (key_idx = 0; key_idx < num_levels && levels[key_idx] != nullptr; key_idx++)
     440                 :             :         {
     441                 :             :             QofLogLevel level;
     442                 :           0 :             gchar *logger_name = nullptr, *level_str = nullptr;
     443                 :             : 
     444                 :           0 :             logger_name = g_strdup(levels[key_idx]);
     445                 :           0 :             logger_max_name_length = MAX (logger_max_name_length, (gint) strlen (logger_name));
     446                 :           0 :             level_str = g_key_file_get_string(conf, levels_group, logger_name, nullptr);
     447                 :           0 :             level = qof_log_level_from_string(level_str);
     448                 :             : 
     449                 :           0 :             DEBUG("setting log [%s] to level [%s=%d]", logger_name, level_str, level);
     450                 :           0 :             qof_log_set_level(logger_name, level);
     451                 :             : 
     452                 :           0 :             g_free(logger_name);
     453                 :           0 :             g_free(level_str);
     454                 :             :         }
     455                 :             : 
     456                 :           0 :         str = g_strdup_printf ("%d", logger_max_name_length);
     457                 :           0 :         if (qof_logger_format)
     458                 :           0 :             g_free (qof_logger_format);
     459                 :           0 :         qof_logger_format = g_strconcat ("* %s %*s <%-", str, ".", str, "s> %*s%s%s", nullptr);
     460                 :             : 
     461                 :           0 :         g_free (str);
     462                 :           0 :         g_strfreev(levels);
     463                 :             :     }
     464                 :             : 
     465                 :           0 :     if (g_key_file_has_group(conf, output_group))
     466                 :             :     {
     467                 :             :         gsize num_outputs;
     468                 :             :         unsigned int output_idx;
     469                 :             :         gchar **outputs;
     470                 :             : 
     471                 :           0 :         outputs = g_key_file_get_keys(conf, output_group, &num_outputs, nullptr);
     472                 :           0 :         for (output_idx = 0; output_idx < num_outputs && outputs[output_idx] != nullptr; output_idx++)
     473                 :             :         {
     474                 :           0 :             gchar *key = outputs[output_idx];
     475                 :             :             gchar *value;
     476                 :             : 
     477                 :           0 :             if (g_ascii_strcasecmp("to", key) != 0)
     478                 :             :             {
     479                 :           0 :                 g_warning("unknown key [%s] in [outputs], skipping", key);
     480                 :           0 :                 continue;
     481                 :             :             }
     482                 :             : 
     483                 :           0 :             value = g_key_file_get_string(conf, output_group, key, nullptr);
     484                 :           0 :             DEBUG("setting [output].to=[%s]", value);
     485                 :           0 :             qof_log_init_filename_special(value);
     486                 :           0 :             g_free(value);
     487                 :             :         }
     488                 :           0 :         g_strfreev(outputs);
     489                 :             :     }
     490                 :             : 
     491                 :           0 :     g_key_file_free(conf);
     492                 :             : }
     493                 :             : 
     494                 :             : const gchar*
     495                 :        1705 : qof_log_level_to_string(QofLogLevel log_level)
     496                 :             : {
     497                 :             :     const char *level_str;
     498                 :        1705 :     switch (log_level)
     499                 :             :     {
     500                 :           0 :     case QOF_LOG_FATAL:
     501                 :           0 :         level_str = "FATAL";
     502                 :           0 :         break;
     503                 :        1426 :     case QOF_LOG_ERROR:
     504                 :        1426 :         level_str = "ERROR";
     505                 :        1426 :         break;
     506                 :         279 :     case QOF_LOG_WARNING:
     507                 :         279 :         level_str = "WARN";
     508                 :         279 :         break;
     509                 :           0 :     case QOF_LOG_MESSAGE:
     510                 :           0 :         level_str = "MESSG";
     511                 :           0 :         break;
     512                 :           0 :     case QOF_LOG_INFO:
     513                 :           0 :         level_str = "INFO";
     514                 :           0 :         break;
     515                 :           0 :     case QOF_LOG_DEBUG:
     516                 :           0 :         level_str = "DEBUG";
     517                 :           0 :         break;
     518                 :           0 :     default:
     519                 :           0 :         level_str = "OTHER";
     520                 :           0 :         break;
     521                 :             :     }
     522                 :        1705 :     return level_str;
     523                 :             : }
     524                 :             : 
     525                 :             : QofLogLevel
     526                 :           0 : qof_log_level_from_string(const gchar *str)
     527                 :             : {
     528                 :           0 :     if (g_ascii_strncasecmp("error", str, 5) == 0) return QOF_LOG_FATAL;
     529                 :           0 :     if (g_ascii_strncasecmp("crit", str, 4) == 0) return QOF_LOG_ERROR;
     530                 :           0 :     if (g_ascii_strncasecmp("warn", str, 4) == 0) return QOF_LOG_WARNING;
     531                 :           0 :     if (g_ascii_strncasecmp("mess", str, 4) == 0) return QOF_LOG_MESSAGE;
     532                 :           0 :     if (g_ascii_strncasecmp("info", str, 4) == 0) return QOF_LOG_INFO;
     533                 :           0 :     if (g_ascii_strncasecmp("debug", str, 5) == 0) return QOF_LOG_DEBUG;
     534                 :           0 :     return QOF_LOG_DEBUG;
     535                 :             : }
        

Generated by: LCOV version 2.0-1