Coverage Report

Created: 2025-11-09 06:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/logging-log4cxx/src/main/cpp/optionconverter.cpp
Line
Count
Source
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
#include <log4cxx/logstring.h>
19
#include <log4cxx/spi/loggerfactory.h>
20
#include <log4cxx/spi/loggerrepository.h>
21
#include <log4cxx/appenderskeleton.h>
22
#include <log4cxx/helpers/optionconverter.h>
23
#include <algorithm>
24
#include <ctype.h>
25
#include <log4cxx/helpers/stringhelper.h>
26
#include <log4cxx/helpers/exception.h>
27
#include <stdlib.h>
28
#include <log4cxx/helpers/properties.h>
29
#include <log4cxx/helpers/loglog.h>
30
#include <log4cxx/level.h>
31
#include <log4cxx/helpers/object.h>
32
#include <log4cxx/helpers/class.h>
33
#include <log4cxx/helpers/loader.h>
34
#include <log4cxx/helpers/system.h>
35
#include <log4cxx/propertyconfigurator.h>
36
#include <log4cxx/helpers/transcoder.h>
37
#include <log4cxx/file.h>
38
#include <log4cxx/xml/domconfigurator.h>
39
#include <log4cxx/logmanager.h>
40
#if !defined(LOG4CXX)
41
  #define LOG4CXX 1
42
#endif
43
#include <log4cxx/helpers/aprinitializer.h>
44
#include <log4cxx/helpers/filewatchdog.h>
45
#include <log4cxx/helpers/singletonholder.h>
46
47
namespace LOG4CXX_NS
48
{
49
50
class ConfiguratorWatchdog  : public helpers::FileWatchdog
51
{
52
  spi::ConfiguratorPtr m_config;
53
  public:
54
    ConfiguratorWatchdog(const spi::ConfiguratorPtr& config, const File& filename)
55
0
        : helpers::FileWatchdog(filename)
56
0
        , m_config(config)
57
0
    {
58
0
    }
59
60
    /**
61
    Call PropertyConfigurator#doConfigure(const String& configFileName,
62
    const spi::LoggerRepositoryPtr& hierarchy) with the
63
    <code>filename</code> to reconfigure log4cxx.
64
    */
65
    void doOnChange() override
66
0
    {
67
0
        m_config->doConfigure(file(), LogManager::getLoggerRepository());
68
0
    }
69
70
  static void startWatching(const spi::ConfiguratorPtr& config, const File& filename, long delay)
71
0
  {
72
0
    using WatchdogHolder = helpers::SingletonHolder<ConfiguratorWatchdog>;
73
0
    auto pHolder = helpers::APRInitializer::getOrAddUnique<WatchdogHolder>
74
0
      ( [&config, &filename]() -> helpers::ObjectPtr
75
0
        { return std::make_shared<WatchdogHolder>(config, filename); }
76
0
      );
77
0
    auto& dog = pHolder->value();
78
0
    dog.m_config = config;
79
0
    dog.setFile(filename);
80
0
    dog.setDelay(delay);
81
0
    dog.start();
82
0
  }
83
};
84
85
}
86
87
using namespace LOG4CXX_NS;
88
using namespace LOG4CXX_NS::helpers;
89
using namespace LOG4CXX_NS::spi;
90
91
92
LogString OptionConverter::convertSpecialChars(const LogString& s)
93
2
{
94
2
  logchar c;
95
2
  LogString sbuf;
96
97
2
  LogString::const_iterator i = s.begin();
98
99
48
  while (i != s.end())
100
46
  {
101
46
    c = *i++;
102
103
46
    if (i != s.end() && c == 0x5C /* '\\' */)
104
0
    {
105
0
      c =  *i++;
106
107
0
      switch (c)
108
0
      {
109
0
        case 0x6E: //'n'
110
0
          c = 0x0A;
111
0
          break;
112
113
0
        case 0x72: //'r'
114
0
          c = 0x0D;
115
0
          break;
116
117
0
        case 0x74: //'t'
118
0
          c = 0x09;
119
0
          break;
120
121
0
        case 0x66: //'f'
122
0
          c = 0x0C;
123
0
          break;
124
125
0
        default:
126
0
          break;
127
0
      }
128
0
    }
129
130
46
    sbuf.append(1, c);
131
46
  }
132
133
2
  return sbuf;
134
2
}
log4cxx::helpers::OptionConverter::convertSpecialChars(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Line
Count
Source
93
1
{
94
1
  logchar c;
95
1
  LogString sbuf;
96
97
1
  LogString::const_iterator i = s.begin();
98
99
24
  while (i != s.end())
100
23
  {
101
23
    c = *i++;
102
103
23
    if (i != s.end() && c == 0x5C /* '\\' */)
104
0
    {
105
0
      c =  *i++;
106
107
0
      switch (c)
108
0
      {
109
0
        case 0x6E: //'n'
110
0
          c = 0x0A;
111
0
          break;
112
113
0
        case 0x72: //'r'
114
0
          c = 0x0D;
115
0
          break;
116
117
0
        case 0x74: //'t'
118
0
          c = 0x09;
119
0
          break;
120
121
0
        case 0x66: //'f'
122
0
          c = 0x0C;
123
0
          break;
124
125
0
        default:
126
0
          break;
127
0
      }
128
0
    }
129
130
23
    sbuf.append(1, c);
131
23
  }
132
133
1
  return sbuf;
134
1
}
log4cxx::helpers::OptionConverter::convertSpecialChars(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&)
Line
Count
Source
93
1
{
94
1
  logchar c;
95
1
  LogString sbuf;
96
97
1
  LogString::const_iterator i = s.begin();
98
99
24
  while (i != s.end())
100
23
  {
101
23
    c = *i++;
102
103
23
    if (i != s.end() && c == 0x5C /* '\\' */)
104
0
    {
105
0
      c =  *i++;
106
107
0
      switch (c)
108
0
      {
109
0
        case 0x6E: //'n'
110
0
          c = 0x0A;
111
0
          break;
112
113
0
        case 0x72: //'r'
114
0
          c = 0x0D;
115
0
          break;
116
117
0
        case 0x74: //'t'
118
0
          c = 0x09;
119
0
          break;
120
121
0
        case 0x66: //'f'
122
0
          c = 0x0C;
123
0
          break;
124
125
0
        default:
126
0
          break;
127
0
      }
128
0
    }
129
130
23
    sbuf.append(1, c);
131
23
  }
132
133
1
  return sbuf;
134
1
}
135
136
137
bool OptionConverter::toBoolean(const LogString& value, bool dEfault)
138
11.3k
{
139
11.3k
  if (value.length() >= 4)
140
11.3k
  {
141
11.3k
    if (StringHelper::equalsIgnoreCase(value.substr(0, 4),
142
11.3k
        LOG4CXX_STR("TRUE"), LOG4CXX_STR("true")))
143
11.0k
    {
144
11.0k
      return true;
145
11.0k
    }
146
11.3k
  }
147
148
355
  if (dEfault && value.length() >= 5)
149
274
  {
150
274
    if (StringHelper::equalsIgnoreCase(value.substr(0, 5),
151
274
        LOG4CXX_STR("FALSE"), LOG4CXX_STR("false")))
152
2
    {
153
2
      return false;
154
2
    }
155
274
  }
156
157
353
  return dEfault;
158
355
}
log4cxx::helpers::OptionConverter::toBoolean(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool)
Line
Count
Source
138
5.37k
{
139
5.37k
  if (value.length() >= 4)
140
5.36k
  {
141
5.36k
    if (StringHelper::equalsIgnoreCase(value.substr(0, 4),
142
5.36k
        LOG4CXX_STR("TRUE"), LOG4CXX_STR("true")))
143
5.17k
    {
144
5.17k
      return true;
145
5.17k
    }
146
5.36k
  }
147
148
201
  if (dEfault && value.length() >= 5)
149
168
  {
150
168
    if (StringHelper::equalsIgnoreCase(value.substr(0, 5),
151
168
        LOG4CXX_STR("FALSE"), LOG4CXX_STR("false")))
152
1
    {
153
1
      return false;
154
1
    }
155
168
  }
156
157
200
  return dEfault;
158
201
}
log4cxx::helpers::OptionConverter::toBoolean(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, bool)
Line
Count
Source
138
6.00k
{
139
6.00k
  if (value.length() >= 4)
140
5.96k
  {
141
5.96k
    if (StringHelper::equalsIgnoreCase(value.substr(0, 4),
142
5.96k
        LOG4CXX_STR("TRUE"), LOG4CXX_STR("true")))
143
5.84k
    {
144
5.84k
      return true;
145
5.84k
    }
146
5.96k
  }
147
148
154
  if (dEfault && value.length() >= 5)
149
106
  {
150
106
    if (StringHelper::equalsIgnoreCase(value.substr(0, 5),
151
106
        LOG4CXX_STR("FALSE"), LOG4CXX_STR("false")))
152
1
    {
153
1
      return false;
154
1
    }
155
106
  }
156
157
153
  return dEfault;
158
154
}
159
160
int OptionConverter::toInt(const LogString& value, int dEfault)
161
0
{
162
0
  LogString trimmed(StringHelper::trim(value));
163
164
0
  if (trimmed.empty())
165
0
  {
166
0
    return dEfault;
167
0
  }
168
169
0
  LOG4CXX_ENCODE_CHAR(cvalue, trimmed);
170
171
0
  return (int) atol(cvalue.c_str());
172
0
}
Unexecuted instantiation: log4cxx::helpers::OptionConverter::toInt(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int)
Unexecuted instantiation: log4cxx::helpers::OptionConverter::toInt(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, int)
173
174
long OptionConverter::toFileSize(const LogString& s, long dEfault)
175
0
{
176
0
  if (s.empty())
177
0
  {
178
0
    return dEfault;
179
0
  }
180
181
0
  size_t index = s.find_first_of(LOG4CXX_STR("bB"));
182
183
0
  if (index != LogString::npos && index > 0)
184
0
  {
185
0
    long multiplier = 1;
186
0
    index--;
187
188
0
    if (s[index] == 0x6B /* 'k' */ || s[index] == 0x4B /* 'K' */)
189
0
    {
190
0
      multiplier = 1024;
191
0
    }
192
0
    else if (s[index] == 0x6D /* 'm' */ || s[index] == 0x4D /* 'M' */)
193
0
    {
194
0
      multiplier = 1024 * 1024;
195
0
    }
196
0
    else if (s[index] == 0x67 /* 'g'*/ || s[index] == 0x47 /* 'G' */)
197
0
    {
198
0
      multiplier = 1024 * 1024 * 1024;
199
0
    }
200
201
0
    return toInt(s.substr(0, index), 1) * multiplier;
202
0
  }
203
204
0
  return toInt(s, 1);
205
0
}
Unexecuted instantiation: log4cxx::helpers::OptionConverter::toFileSize(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, long)
Unexecuted instantiation: log4cxx::helpers::OptionConverter::toFileSize(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, long)
206
207
LogString OptionConverter::findAndSubst(const LogString& key, Properties& props)
208
16
{
209
16
  LogString value(props.getProperty(key));
210
211
16
  if (value.empty())
212
6
  {
213
6
    return value;
214
6
  }
215
216
10
  try
217
10
  {
218
10
    return substVars(value, props);
219
10
  }
220
10
  catch (IllegalArgumentException& e)
221
10
  {
222
0
    LogLog::error(((LogString) LOG4CXX_STR("Bad option value ["))
223
0
      + value + LOG4CXX_STR("]."), e);
224
0
    return value;
225
0
  }
226
10
}
log4cxx::helpers::OptionConverter::findAndSubst(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, log4cxx::helpers::Properties&)
Line
Count
Source
208
8
{
209
8
  LogString value(props.getProperty(key));
210
211
8
  if (value.empty())
212
3
  {
213
3
    return value;
214
3
  }
215
216
5
  try
217
5
  {
218
5
    return substVars(value, props);
219
5
  }
220
5
  catch (IllegalArgumentException& e)
221
5
  {
222
0
    LogLog::error(((LogString) LOG4CXX_STR("Bad option value ["))
223
0
      + value + LOG4CXX_STR("]."), e);
224
0
    return value;
225
0
  }
226
5
}
log4cxx::helpers::OptionConverter::findAndSubst(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, log4cxx::helpers::Properties&)
Line
Count
Source
208
8
{
209
8
  LogString value(props.getProperty(key));
210
211
8
  if (value.empty())
212
3
  {
213
3
    return value;
214
3
  }
215
216
5
  try
217
5
  {
218
5
    return substVars(value, props);
219
5
  }
220
5
  catch (IllegalArgumentException& e)
221
5
  {
222
0
    LogLog::error(((LogString) LOG4CXX_STR("Bad option value ["))
223
0
      + value + LOG4CXX_STR("]."), e);
224
0
    return value;
225
0
  }
226
5
}
227
228
LogString OptionConverter::substVars(const LogString& val, Properties& props)
229
59.0k
{
230
59.0k
  LogString sbuf;
231
59.0k
  const logchar delimStartArray[] = { 0x24, 0x7B, 0 }; // '$', '{'
232
59.0k
  const LogString delimStart(delimStartArray);
233
59.0k
  const logchar delimStop = 0x7D; // '}';
234
59.0k
  const size_t DELIM_START_LEN = 2;
235
59.0k
  const size_t DELIM_STOP_LEN = 1;
236
237
59.0k
  size_t i = 0;
238
239
123k
  while (true)
240
123k
  {
241
123k
    size_t j = val.find(delimStart, i);
242
243
123k
    if (j == val.npos)
244
58.8k
    {
245
      // no more variables
246
58.8k
      if (i == 0)
247
58.1k
      {
248
        // this is a simple string
249
58.1k
        return val;
250
58.1k
      }
251
713
      else
252
713
      {
253
        // add the tail string which contails no variables and return the result.
254
713
        sbuf.append(val.substr(i, val.length() - i));
255
713
        return sbuf;
256
713
      }
257
58.8k
    }
258
64.7k
    else
259
64.7k
    {
260
64.7k
      sbuf.append(val.substr(i, j - i));
261
64.7k
      size_t k = val.find(delimStop, j);
262
263
64.7k
      if (k == val.npos)
264
224
      {
265
224
        LogString msg(1, (logchar) 0x22 /* '\"' */);
266
224
        msg.append(val);
267
224
        msg.append(LOG4CXX_STR("\" has no closing brace. Opening brace at position "));
268
224
        Pool p;
269
224
        StringHelper::toString(j, p, msg);
270
224
        msg.append(1, (logchar) 0x2E /* '.' */);
271
224
        throw IllegalArgumentException(msg);
272
224
      }
273
64.5k
      else
274
64.5k
      {
275
64.5k
        j += DELIM_START_LEN;
276
64.5k
        LogString key = val.substr(j, k - j);
277
        // first try in System properties
278
64.5k
        LogString replacement(getSystemProperty(key, LogString()));
279
280
        // then try props parameter
281
64.5k
        if (replacement.empty())
282
10.9k
        {
283
10.9k
          replacement = props.getProperty(key);
284
10.9k
        }
285
286
64.5k
        if (!replacement.empty())
287
54.7k
        {
288
          // Do variable substitution on the replacement string
289
          // such that we can solve "Hello ${x2}" as "Hello p1"
290
          // the where the properties are
291
          // x1=p1
292
          // x2=${x1}
293
54.7k
          LogString recursiveReplacement = substVars(replacement, props);
294
54.7k
          sbuf.append(recursiveReplacement);
295
54.7k
        }
296
297
64.5k
        i = k + DELIM_STOP_LEN;
298
64.5k
      }
299
64.7k
    }
300
123k
  }
301
59.0k
}
log4cxx::helpers::OptionConverter::substVars(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, log4cxx::helpers::Properties&)
Line
Count
Source
229
47.4k
{
230
47.4k
  LogString sbuf;
231
47.4k
  const logchar delimStartArray[] = { 0x24, 0x7B, 0 }; // '$', '{'
232
47.4k
  const LogString delimStart(delimStartArray);
233
47.4k
  const logchar delimStop = 0x7D; // '}';
234
47.4k
  const size_t DELIM_START_LEN = 2;
235
47.4k
  const size_t DELIM_STOP_LEN = 1;
236
237
47.4k
  size_t i = 0;
238
239
100k
  while (true)
240
100k
  {
241
100k
    size_t j = val.find(delimStart, i);
242
243
100k
    if (j == val.npos)
244
47.3k
    {
245
      // no more variables
246
47.3k
      if (i == 0)
247
46.8k
      {
248
        // this is a simple string
249
46.8k
        return val;
250
46.8k
      }
251
479
      else
252
479
      {
253
        // add the tail string which contails no variables and return the result.
254
479
        sbuf.append(val.substr(i, val.length() - i));
255
479
        return sbuf;
256
479
      }
257
47.3k
    }
258
53.0k
    else
259
53.0k
    {
260
53.0k
      sbuf.append(val.substr(i, j - i));
261
53.0k
      size_t k = val.find(delimStop, j);
262
263
53.0k
      if (k == val.npos)
264
128
      {
265
128
        LogString msg(1, (logchar) 0x22 /* '\"' */);
266
128
        msg.append(val);
267
128
        msg.append(LOG4CXX_STR("\" has no closing brace. Opening brace at position "));
268
128
        Pool p;
269
128
        StringHelper::toString(j, p, msg);
270
128
        msg.append(1, (logchar) 0x2E /* '.' */);
271
128
        throw IllegalArgumentException(msg);
272
128
      }
273
52.9k
      else
274
52.9k
      {
275
52.9k
        j += DELIM_START_LEN;
276
52.9k
        LogString key = val.substr(j, k - j);
277
        // first try in System properties
278
52.9k
        LogString replacement(getSystemProperty(key, LogString()));
279
280
        // then try props parameter
281
52.9k
        if (replacement.empty())
282
9.53k
        {
283
9.53k
          replacement = props.getProperty(key);
284
9.53k
        }
285
286
52.9k
        if (!replacement.empty())
287
44.6k
        {
288
          // Do variable substitution on the replacement string
289
          // such that we can solve "Hello ${x2}" as "Hello p1"
290
          // the where the properties are
291
          // x1=p1
292
          // x2=${x1}
293
44.6k
          LogString recursiveReplacement = substVars(replacement, props);
294
44.6k
          sbuf.append(recursiveReplacement);
295
44.6k
        }
296
297
52.9k
        i = k + DELIM_STOP_LEN;
298
52.9k
      }
299
53.0k
    }
300
100k
  }
301
47.4k
}
log4cxx::helpers::OptionConverter::substVars(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, log4cxx::helpers::Properties&)
Line
Count
Source
229
11.5k
{
230
11.5k
  LogString sbuf;
231
11.5k
  const logchar delimStartArray[] = { 0x24, 0x7B, 0 }; // '$', '{'
232
11.5k
  const LogString delimStart(delimStartArray);
233
11.5k
  const logchar delimStop = 0x7D; // '}';
234
11.5k
  const size_t DELIM_START_LEN = 2;
235
11.5k
  const size_t DELIM_STOP_LEN = 1;
236
237
11.5k
  size_t i = 0;
238
239
23.0k
  while (true)
240
23.0k
  {
241
23.0k
    size_t j = val.find(delimStart, i);
242
243
23.0k
    if (j == val.npos)
244
11.4k
    {
245
      // no more variables
246
11.4k
      if (i == 0)
247
11.2k
      {
248
        // this is a simple string
249
11.2k
        return val;
250
11.2k
      }
251
234
      else
252
234
      {
253
        // add the tail string which contails no variables and return the result.
254
234
        sbuf.append(val.substr(i, val.length() - i));
255
234
        return sbuf;
256
234
      }
257
11.4k
    }
258
11.6k
    else
259
11.6k
    {
260
11.6k
      sbuf.append(val.substr(i, j - i));
261
11.6k
      size_t k = val.find(delimStop, j);
262
263
11.6k
      if (k == val.npos)
264
96
      {
265
96
        LogString msg(1, (logchar) 0x22 /* '\"' */);
266
96
        msg.append(val);
267
96
        msg.append(LOG4CXX_STR("\" has no closing brace. Opening brace at position "));
268
96
        Pool p;
269
96
        StringHelper::toString(j, p, msg);
270
96
        msg.append(1, (logchar) 0x2E /* '.' */);
271
96
        throw IllegalArgumentException(msg);
272
96
      }
273
11.5k
      else
274
11.5k
      {
275
11.5k
        j += DELIM_START_LEN;
276
11.5k
        LogString key = val.substr(j, k - j);
277
        // first try in System properties
278
11.5k
        LogString replacement(getSystemProperty(key, LogString()));
279
280
        // then try props parameter
281
11.5k
        if (replacement.empty())
282
1.42k
        {
283
1.42k
          replacement = props.getProperty(key);
284
1.42k
        }
285
286
11.5k
        if (!replacement.empty())
287
10.1k
        {
288
          // Do variable substitution on the replacement string
289
          // such that we can solve "Hello ${x2}" as "Hello p1"
290
          // the where the properties are
291
          // x1=p1
292
          // x2=${x1}
293
10.1k
          LogString recursiveReplacement = substVars(replacement, props);
294
10.1k
          sbuf.append(recursiveReplacement);
295
10.1k
        }
296
297
11.5k
        i = k + DELIM_STOP_LEN;
298
11.5k
      }
299
11.6k
    }
300
23.0k
  }
301
11.5k
}
302
303
LogString OptionConverter::getSystemProperty(const LogString& key, const LogString& def)
304
64.5k
{
305
64.5k
  if (!key.empty())
306
62.8k
  {
307
62.8k
    LogString value(System::getProperty(key));
308
309
62.8k
    if (!value.empty())
310
53.5k
    {
311
53.5k
      return value;
312
53.5k
    }
313
62.8k
  }
314
315
10.9k
  return def;
316
64.5k
}
log4cxx::helpers::OptionConverter::getSystemProperty(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Line
Count
Source
304
52.9k
{
305
52.9k
  if (!key.empty())
306
51.4k
  {
307
51.4k
    LogString value(System::getProperty(key));
308
309
51.4k
    if (!value.empty())
310
43.4k
    {
311
43.4k
      return value;
312
43.4k
    }
313
51.4k
  }
314
315
9.54k
  return def;
316
52.9k
}
log4cxx::helpers::OptionConverter::getSystemProperty(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&)
Line
Count
Source
304
11.5k
{
305
11.5k
  if (!key.empty())
306
11.3k
  {
307
11.3k
    LogString value(System::getProperty(key));
308
309
11.3k
    if (!value.empty())
310
10.1k
    {
311
10.1k
      return value;
312
10.1k
    }
313
11.3k
  }
314
315
1.43k
  return def;
316
11.5k
}
317
318
LevelPtr OptionConverter::toLevel(const LogString& value,
319
  const LevelPtr& defaultValue)
320
465
{
321
465
  size_t hashIndex = value.find(LOG4CXX_STR("#"));
322
323
465
  if (hashIndex == LogString::npos)
324
118
  {
325
    // no class name specified : use standard Level class
326
118
    if (value.empty())
327
0
    {
328
0
      return defaultValue;
329
0
    }
330
118
    else
331
118
    {
332
118
      return Level::toLevelLS(value, defaultValue);
333
118
    }
334
118
  }
335
336
347
  LogString clazz = value.substr(hashIndex + 1);
337
347
  LogString levelName = value.substr(0, hashIndex);
338
339
  // This is degenerate case but you never know.
340
347
  if (levelName.empty() || clazz.empty())
341
40
  {
342
40
    return Level::toLevelLS(value, defaultValue);
343
40
  }
344
307
  if (LogLog::isDebugEnabled())
345
305
  {
346
305
    LogLog::debug(LOG4CXX_STR("Desired ") + Level::getStaticClass().getName()
347
305
        + LOG4CXX_STR(" sub-class: [") + clazz + LOG4CXX_STR("]"));
348
305
  }
349
350
307
  try
351
307
  {
352
    // Note: the dynamic_cast could fail across DLL boundaries.
353
    // However, without the dynamic_cast a poorly formed XML file
354
    // could attempt to load an invalid class as a filter, causing
355
    // a crash.  If it can't be converted, a std::bad_cast should be
356
    // thrown(and caught by the exception handler below)
357
307
    const Level::LevelClass& levelClass =
358
307
      dynamic_cast<const Level::LevelClass&>(Loader::loadClass(clazz));
359
307
    return levelClass.toLevel(levelName);
360
307
  }
361
307
  catch (Exception& oops)
362
307
  {
363
299
    LogLog::error(LOG4CXX_STR("Could not create ") + Level::getStaticClass().getName() + LOG4CXX_STR(" sub-class"), oops);
364
299
  }
365
307
  catch (const std::bad_cast&)
366
307
  {
367
4
    LogLog::warn(
368
4
      LOG4CXX_STR("class [") + clazz + LOG4CXX_STR("] unable to be converted to "
369
4
      "Level::LevelClass"));
370
4
  }
371
307
  catch (...)
372
307
  {
373
0
    LogLog::warn(
374
0
      LOG4CXX_STR("class [") + clazz + LOG4CXX_STR("], level [") + levelName +
375
0
      LOG4CXX_STR("] conversion) failed."));
376
0
  }
377
378
303
  return defaultValue;
379
307
}
log4cxx::helpers::OptionConverter::toLevel(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::shared_ptr<log4cxx::Level> const&)
Line
Count
Source
320
320
{
321
320
  size_t hashIndex = value.find(LOG4CXX_STR("#"));
322
323
320
  if (hashIndex == LogString::npos)
324
73
  {
325
    // no class name specified : use standard Level class
326
73
    if (value.empty())
327
0
    {
328
0
      return defaultValue;
329
0
    }
330
73
    else
331
73
    {
332
73
      return Level::toLevelLS(value, defaultValue);
333
73
    }
334
73
  }
335
336
247
  LogString clazz = value.substr(hashIndex + 1);
337
247
  LogString levelName = value.substr(0, hashIndex);
338
339
  // This is degenerate case but you never know.
340
247
  if (levelName.empty() || clazz.empty())
341
33
  {
342
33
    return Level::toLevelLS(value, defaultValue);
343
33
  }
344
214
  if (LogLog::isDebugEnabled())
345
213
  {
346
213
    LogLog::debug(LOG4CXX_STR("Desired ") + Level::getStaticClass().getName()
347
213
        + LOG4CXX_STR(" sub-class: [") + clazz + LOG4CXX_STR("]"));
348
213
  }
349
350
214
  try
351
214
  {
352
    // Note: the dynamic_cast could fail across DLL boundaries.
353
    // However, without the dynamic_cast a poorly formed XML file
354
    // could attempt to load an invalid class as a filter, causing
355
    // a crash.  If it can't be converted, a std::bad_cast should be
356
    // thrown(and caught by the exception handler below)
357
214
    const Level::LevelClass& levelClass =
358
214
      dynamic_cast<const Level::LevelClass&>(Loader::loadClass(clazz));
359
214
    return levelClass.toLevel(levelName);
360
214
  }
361
214
  catch (Exception& oops)
362
214
  {
363
210
    LogLog::error(LOG4CXX_STR("Could not create ") + Level::getStaticClass().getName() + LOG4CXX_STR(" sub-class"), oops);
364
210
  }
365
214
  catch (const std::bad_cast&)
366
214
  {
367
2
    LogLog::warn(
368
2
      LOG4CXX_STR("class [") + clazz + LOG4CXX_STR("] unable to be converted to "
369
2
      "Level::LevelClass"));
370
2
  }
371
214
  catch (...)
372
214
  {
373
0
    LogLog::warn(
374
0
      LOG4CXX_STR("class [") + clazz + LOG4CXX_STR("], level [") + levelName +
375
0
      LOG4CXX_STR("] conversion) failed."));
376
0
  }
377
378
212
  return defaultValue;
379
214
}
log4cxx::helpers::OptionConverter::toLevel(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, std::__1::shared_ptr<log4cxx::Level> const&)
Line
Count
Source
320
145
{
321
145
  size_t hashIndex = value.find(LOG4CXX_STR("#"));
322
323
145
  if (hashIndex == LogString::npos)
324
45
  {
325
    // no class name specified : use standard Level class
326
45
    if (value.empty())
327
0
    {
328
0
      return defaultValue;
329
0
    }
330
45
    else
331
45
    {
332
45
      return Level::toLevelLS(value, defaultValue);
333
45
    }
334
45
  }
335
336
100
  LogString clazz = value.substr(hashIndex + 1);
337
100
  LogString levelName = value.substr(0, hashIndex);
338
339
  // This is degenerate case but you never know.
340
100
  if (levelName.empty() || clazz.empty())
341
7
  {
342
7
    return Level::toLevelLS(value, defaultValue);
343
7
  }
344
93
  if (LogLog::isDebugEnabled())
345
92
  {
346
92
    LogLog::debug(LOG4CXX_STR("Desired ") + Level::getStaticClass().getName()
347
92
        + LOG4CXX_STR(" sub-class: [") + clazz + LOG4CXX_STR("]"));
348
92
  }
349
350
93
  try
351
93
  {
352
    // Note: the dynamic_cast could fail across DLL boundaries.
353
    // However, without the dynamic_cast a poorly formed XML file
354
    // could attempt to load an invalid class as a filter, causing
355
    // a crash.  If it can't be converted, a std::bad_cast should be
356
    // thrown(and caught by the exception handler below)
357
93
    const Level::LevelClass& levelClass =
358
93
      dynamic_cast<const Level::LevelClass&>(Loader::loadClass(clazz));
359
93
    return levelClass.toLevel(levelName);
360
93
  }
361
93
  catch (Exception& oops)
362
93
  {
363
89
    LogLog::error(LOG4CXX_STR("Could not create ") + Level::getStaticClass().getName() + LOG4CXX_STR(" sub-class"), oops);
364
89
  }
365
93
  catch (const std::bad_cast&)
366
93
  {
367
2
    LogLog::warn(
368
2
      LOG4CXX_STR("class [") + clazz + LOG4CXX_STR("] unable to be converted to "
369
2
      "Level::LevelClass"));
370
2
  }
371
93
  catch (...)
372
93
  {
373
0
    LogLog::warn(
374
0
      LOG4CXX_STR("class [") + clazz + LOG4CXX_STR("], level [") + levelName +
375
0
      LOG4CXX_STR("] conversion) failed."));
376
0
  }
377
378
91
  return defaultValue;
379
93
}
380
381
382
ObjectPtr OptionConverter::instantiateByKey(Properties& props, const LogString& key,
383
  const Class& superClass, const ObjectPtr& defaultValue)
384
4
{
385
  // Get the value of the property in string form
386
4
  LogString className(findAndSubst(key, props));
387
388
4
  if (className.empty())
389
0
  {
390
0
    LogLog::error(
391
0
      ((LogString) LOG4CXX_STR("Could not find value for key ")) + key);
392
0
    return defaultValue;
393
0
  }
394
395
  // Trim className to avoid trailing spaces that cause problems.
396
4
  return OptionConverter::instantiateByClassName(
397
4
      StringHelper::trim(className), superClass, defaultValue);
398
4
}
log4cxx::helpers::OptionConverter::instantiateByKey(log4cxx::helpers::Properties&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, log4cxx::helpers::Class const&, std::__1::shared_ptr<log4cxx::helpers::Object> const&)
Line
Count
Source
384
2
{
385
  // Get the value of the property in string form
386
2
  LogString className(findAndSubst(key, props));
387
388
2
  if (className.empty())
389
0
  {
390
0
    LogLog::error(
391
0
      ((LogString) LOG4CXX_STR("Could not find value for key ")) + key);
392
0
    return defaultValue;
393
0
  }
394
395
  // Trim className to avoid trailing spaces that cause problems.
396
2
  return OptionConverter::instantiateByClassName(
397
2
      StringHelper::trim(className), superClass, defaultValue);
398
2
}
log4cxx::helpers::OptionConverter::instantiateByKey(log4cxx::helpers::Properties&, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, log4cxx::helpers::Class const&, std::__1::shared_ptr<log4cxx::helpers::Object> const&)
Line
Count
Source
384
2
{
385
  // Get the value of the property in string form
386
2
  LogString className(findAndSubst(key, props));
387
388
2
  if (className.empty())
389
0
  {
390
0
    LogLog::error(
391
0
      ((LogString) LOG4CXX_STR("Could not find value for key ")) + key);
392
0
    return defaultValue;
393
0
  }
394
395
  // Trim className to avoid trailing spaces that cause problems.
396
2
  return OptionConverter::instantiateByClassName(
397
2
      StringHelper::trim(className), superClass, defaultValue);
398
2
}
399
400
ObjectPtr OptionConverter::instantiateByClassName(const LogString& className,
401
  const Class& superClass, const ObjectPtr& defaultValue)
402
4
{
403
4
  if (LogLog::isDebugEnabled())
404
0
  {
405
0
    LogLog::debug(LOG4CXX_STR("Desired ") + superClass.getName()
406
0
      + LOG4CXX_STR(" sub-class: [") + className + LOG4CXX_STR("]"));
407
0
  }
408
4
  try
409
4
  {
410
4
    const Class& classObj = Loader::loadClass(className);
411
4
    ObjectPtr newObject =  ObjectPtr(classObj.newInstance());
412
413
4
    if (!newObject->instanceof(superClass))
414
0
    {
415
0
      LogLog::error(LOG4CXX_STR("Not a ") + superClass.getName() + LOG4CXX_STR(" sub-class"));
416
0
      return defaultValue;
417
0
    }
418
419
4
    return newObject;
420
4
  }
421
4
  catch (Exception& e)
422
4
  {
423
0
    LogLog::error(LOG4CXX_STR("Could not create ") + superClass.getName() + LOG4CXX_STR(" sub-class"), e);
424
0
  }
425
426
0
  return defaultValue;
427
4
}
log4cxx::helpers::OptionConverter::instantiateByClassName(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, log4cxx::helpers::Class const&, std::__1::shared_ptr<log4cxx::helpers::Object> const&)
Line
Count
Source
402
2
{
403
2
  if (LogLog::isDebugEnabled())
404
0
  {
405
0
    LogLog::debug(LOG4CXX_STR("Desired ") + superClass.getName()
406
0
      + LOG4CXX_STR(" sub-class: [") + className + LOG4CXX_STR("]"));
407
0
  }
408
2
  try
409
2
  {
410
2
    const Class& classObj = Loader::loadClass(className);
411
2
    ObjectPtr newObject =  ObjectPtr(classObj.newInstance());
412
413
2
    if (!newObject->instanceof(superClass))
414
0
    {
415
0
      LogLog::error(LOG4CXX_STR("Not a ") + superClass.getName() + LOG4CXX_STR(" sub-class"));
416
0
      return defaultValue;
417
0
    }
418
419
2
    return newObject;
420
2
  }
421
2
  catch (Exception& e)
422
2
  {
423
0
    LogLog::error(LOG4CXX_STR("Could not create ") + superClass.getName() + LOG4CXX_STR(" sub-class"), e);
424
0
  }
425
426
0
  return defaultValue;
427
2
}
log4cxx::helpers::OptionConverter::instantiateByClassName(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, log4cxx::helpers::Class const&, std::__1::shared_ptr<log4cxx::helpers::Object> const&)
Line
Count
Source
402
2
{
403
2
  if (LogLog::isDebugEnabled())
404
0
  {
405
0
    LogLog::debug(LOG4CXX_STR("Desired ") + superClass.getName()
406
0
      + LOG4CXX_STR(" sub-class: [") + className + LOG4CXX_STR("]"));
407
0
  }
408
2
  try
409
2
  {
410
2
    const Class& classObj = Loader::loadClass(className);
411
2
    ObjectPtr newObject =  ObjectPtr(classObj.newInstance());
412
413
2
    if (!newObject->instanceof(superClass))
414
0
    {
415
0
      LogLog::error(LOG4CXX_STR("Not a ") + superClass.getName() + LOG4CXX_STR(" sub-class"));
416
0
      return defaultValue;
417
0
    }
418
419
2
    return newObject;
420
2
  }
421
2
  catch (Exception& e)
422
2
  {
423
0
    LogLog::error(LOG4CXX_STR("Could not create ") + superClass.getName() + LOG4CXX_STR(" sub-class"), e);
424
0
  }
425
426
0
  return defaultValue;
427
2
}
428
429
void OptionConverter::selectAndConfigure(const File& configFileName,
430
  const LogString& _clazz, spi::LoggerRepositoryPtr hierarchy, int delay)
431
0
{
432
0
  ConfiguratorPtr configurator;
433
0
  LogString clazz = _clazz;
434
435
0
  LogString filename(configFileName.getPath());
436
437
0
#if LOG4CXX_HAS_DOMCONFIGURATOR
438
0
  if (clazz.empty()
439
0
    && filename.length() > 4
440
0
    && StringHelper::equalsIgnoreCase(
441
0
      filename.substr(filename.length() - 4),
442
0
      LOG4CXX_STR(".XML"), LOG4CXX_STR(".xml")))
443
0
  {
444
0
    clazz = LOG4CXX_NS::xml::DOMConfigurator::getStaticClass().getName();
445
0
  }
446
0
#endif
447
448
0
  if (!clazz.empty())
449
0
  {
450
0
    if (LogLog::isDebugEnabled())
451
0
      LogLog::debug(LOG4CXX_STR("Preferred configurator class: ") + clazz);
452
0
    const Class& clazzObj = Loader::loadClass(clazz);
453
0
    ObjectPtr obj = ObjectPtr(clazzObj.newInstance());
454
0
    configurator = LOG4CXX_NS::cast<Configurator>(obj);
455
456
0
    if (configurator == 0)
457
0
    {
458
0
      LogLog::error(LOG4CXX_STR("Could not instantiate configurator [")
459
0
        + clazz + LOG4CXX_STR("]."));
460
0
      return;
461
0
    }
462
0
  }
463
0
  else
464
0
  {
465
0
    configurator = std::make_shared<PropertyConfigurator>();
466
0
  }
467
468
0
  if (0 < delay)
469
0
    ConfiguratorWatchdog::startWatching(configurator, configFileName, delay);
470
0
  else
471
0
    configurator->doConfigure(configFileName, hierarchy);
472
0
}
Unexecuted instantiation: log4cxx::helpers::OptionConverter::selectAndConfigure(log4cxx::File const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::shared_ptr<log4cxx::spi::LoggerRepository>, int)
Unexecuted instantiation: log4cxx::helpers::OptionConverter::selectAndConfigure(log4cxx::File const&, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, std::__1::shared_ptr<log4cxx::spi::LoggerRepository>, int)