You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4cxx-dev@logging.apache.org by ca...@apache.org on 2005/02/18 18:18:54 UTC
cvs commit: logging-log4cxx/tests/src/pattern num343patternconverter.cpp num343patternconverter.h patternparsertestcase.cpp
carnold 2005/02/18 09:18:54
Modified: . build.xml
include/log4cxx patternlayout.h
include/log4cxx/helpers patternparser.h
src patternlayout.cpp patternparser.cpp timezone.cpp
tests/input Makefile.am
tests/src/helpers timezonetestcase.cpp
tests/src/pattern num343patternconverter.cpp
num343patternconverter.h patternparsertestcase.cpp
Log:
LOGCXX-49: PatternParser refresh, timezones in patterns now supported
Revision Changes Path
1.44 +5 -3 logging-log4cxx/build.xml
Index: build.xml
===================================================================
RCS file: /home/cvs/logging-log4cxx/build.xml,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -r1.43 -r1.44
--- build.xml 17 Feb 2005 00:55:34 -0000 1.43
+++ build.xml 18 Feb 2005 17:18:53 -0000 1.44
@@ -518,8 +518,7 @@
<foreach target="make-header-check" param="header">
<path><fileset dir="${build.dir}/header-check" includes="**/*.h"/></path>
</foreach>
- <mkdir dir="${obj.dir}/header-check"/>
- <cc objdir="${obj.dir}/header-check"
+ <cc objdir="${build.dir}/header-check"
name="gcc"
exceptions="true"
subsystem="gui"
@@ -1033,6 +1032,9 @@
<include name="tests/witness/*"/>
<include name="tests/witness/ndc/*"/>
<include name="tests/log4j.dtd"/>
+ <include name="**/*.am"/>
+ <include name="**/*.in"/>
+ <include name="**/*.patch"/>
<exclude name="**/.cvsignore"/>
</tarfileset>
</tar>
@@ -1042,7 +1044,7 @@
<target name="fixcrlf" depends="init" description="repair end-of-line sequences">
<fixcrlf srcDir="${base.dir}" tab="remove" tablength="3"
- fixlast="true" includes="**/*.cpp **/*.h" excludes="lib/**/*"/>
+ eof="remove" fixlast="true" includes="**/*.cpp **/*.h" excludes="lib/**/*"/>
</target>
</project>
1.21 +1 -14 logging-log4cxx/include/log4cxx/patternlayout.h
Index: patternlayout.h
===================================================================
RCS file: /home/cvs/logging-log4cxx/include/log4cxx/patternlayout.h,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- patternlayout.h 26 Dec 2004 07:31:52 -0000 1.20
+++ patternlayout.h 18 Feb 2005 17:18:53 -0000 1.21
@@ -1,5 +1,5 @@
/*
- * Copyright 2003,2004 The Apache Software Foundation.
+ * Copyright 2003,2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -383,7 +383,6 @@
LogString sbuf;
LogString pattern;
helpers::PatternConverterPtr head;
- LogString timeZone;
public:
DECLARE_LOG4CXX_OBJECT(PatternLayout)
@@ -436,18 +435,6 @@
virtual void format(LogString& output,
const spi::LoggingEventPtr& event, log4cxx::helpers::Pool& pool) const;
- /**
- The <b>TimeZoneID</b> option is a time zone ID string in the format
- expected by the <code>locale</code> C++ standard class.
- */
- inline void setTimeZone(const LogString& timeZone)
- { this->timeZone.assign(timeZone); }
-
- /**
- Returns value of the <b>TimeZone</b> option.
- */
- inline const LogString& getTimeZone() const
- { return timeZone; }
protected:
/**
1.20 +131 -95 logging-log4cxx/include/log4cxx/helpers/patternparser.h
Index: patternparser.h
===================================================================
RCS file: /home/cvs/logging-log4cxx/include/log4cxx/helpers/patternparser.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- patternparser.h 15 Feb 2005 23:55:59 -0000 1.19
+++ patternparser.h 18 Feb 2005 17:18:53 -0000 1.20
@@ -1,5 +1,5 @@
/*
- * Copyright 2003,2004 The Apache Software Foundation.
+ * Copyright 2003,2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +22,29 @@
#include <log4cxx/helpers/objectimpl.h>
#include <log4cxx/helpers/formattinginfo.h>
#include <log4cxx/helpers/patternconverter.h>
+#include <log4cxx/helpers/dateformat.h>
+#include <log4cxx/helpers/relativetimedateformat.h>
+#include <map>
+#include <vector>
+
+#define DEFINE_PATTERN_CONVERTER(classname) \
+class LOG4CXX_EXPORT classname : public PatternConverter { \
+public: \
+classname(const FormattingInfo& formattingInfo, \
+ const std::vector<LogString>& options); \
+virtual void convert(LogString& sbuf, \
+ const spi::LoggingEventPtr& event, \
+ log4cxx::helpers::Pool& pool) const; \
+static PatternConverter* newInstance( \
+ const FormattingInfo& formattingInfo, \
+ const std::vector<LogString>& options) { \
+ return new classname(formattingInfo, options); } \
+private: \
+classname(const classname&); \
+classname& operator=(const classname&); \
+
+#define END_DEFINE_PATTERN_CONVERTER(classname) };
+
namespace log4cxx
{
@@ -45,133 +68,146 @@
*/
class LOG4CXX_EXPORT PatternParser
{
- protected:
- int state;
- LogString currentLiteral;
- size_t patternLength;
- size_t i;
- PatternConverterPtr head;
- PatternConverterPtr tail;
- FormattingInfo formattingInfo;
- LogString pattern;
- LogString timeZone;
+ public:
+ typedef PatternConverter* (*PatternConverterFactory)(
+ const FormattingInfo& info,
+ const std::vector<LogString>& options);
+ typedef std::map<LogString, PatternConverterFactory> PatternConverterMap;
+
+ private:
+ enum {
+ LITERAL_STATE = 0,
+ CONVERTER_STATE = 1,
+ MINUS_STATE = 2,
+ DOT_STATE = 3,
+ MIN_STATE = 4,
+ MAX_STATE = 5 } state;
+
+ static const PatternConverterMap& getGlobalRulesRegistry();
+
+ LogString currentLiteral;
+ int patternLength;
+ int i;
+ PatternConverterPtr head;
+ PatternConverterPtr tail;
+ FormattingInfo formattingInfo;
+ LogString pattern;
+
+ /**
+ * Additional rules for this particular instance.
+ * key: the conversion word (as String)
+ * value: the pattern converter class (as String)
+ */
+ PatternConverterMap converterRegistry;
+
+
public:
- PatternParser(const LogString& pattern, const LogString& timeZone);
+ PatternParser(const LogString& pattern);
private:
void addToList(PatternConverterPtr& pc);
+ LogString extractConverter(logchar lastChar);
+ std::vector<LogString> extractOptions();
- protected:
- LogString extractOption();
-
- /**
- The option is expected to be in decimal and positive. In case of
- error, zero is returned. */
- int extractPrecisionOption();
public:
PatternConverterPtr parse();
- protected:
+ PatternConverterMap getConverterRegistry() const;
+ void setConverterRegistry(const PatternConverterMap&);
+
+
+ private:
+ PatternConverterFactory findConverterClass(const LogString& converterId);
+
void finalizeConverter(logchar c);
void addConverter(PatternConverterPtr& pc);
+ bool isUnicodeIdentifierStart(logchar ch);
+ bool isUnicodeIdentifierPart(logchar ch);
+
+ static void logError(const LogString& msg);
+ static void logWarn(const LogString& msg);
+ static int getPrecision(const std::vector<LogString>& options);
+
+
// ---------------------------------------------------------------------
// PatternConverters
// ---------------------------------------------------------------------
private:
- class LOG4CXX_EXPORT BasicPatternConverter : public PatternConverter
- {
- private:
- int type;
- public:
- BasicPatternConverter(const FormattingInfo& formattingInfo, int type);
- virtual void convert(LogString& sbuf,
- const spi::LoggingEventPtr& event,
- log4cxx::helpers::Pool& pool) const;
- };
-
- class LOG4CXX_EXPORT LiteralPatternConverter : public PatternConverter
- {
- private:
- LogString literal;
+ class LOG4CXX_EXPORT LiteralPatternConverter : public PatternConverter {
public:
- LiteralPatternConverter(const LogString& value);
- virtual void convert(LogString& sbuf,
- const spi::LoggingEventPtr& event,
- log4cxx::helpers::Pool& pool) const;
+ LiteralPatternConverter(const LogString& literal);
+ virtual void convert(LogString& sbuf,
+ const spi::LoggingEventPtr& event,
+ log4cxx::helpers::Pool& pool) const;
private:
- // prevent copy and assignment
- LiteralPatternConverter(const LiteralPatternConverter&);
- LiteralPatternConverter& operator=(const LiteralPatternConverter&);
+ LiteralPatternConverter(LiteralPatternConverter&);
+ LiteralPatternConverter& operator=(LiteralPatternConverter&);
+ LogString literal;
};
- class LOG4CXX_EXPORT DatePatternConverter : public PatternConverter
- {
- private:
- DateFormat * df;
- public:
- DatePatternConverter(const FormattingInfo& formattingInfo,
- DateFormat * df);
- ~DatePatternConverter();
-
- virtual void convert(LogString& sbuf,
- const spi::LoggingEventPtr& event,
- log4cxx::helpers::Pool& pool) const;
+ DEFINE_PATTERN_CONVERTER(DatePatternConverter)
+ DateFormatPtr df;
+ static DateFormatPtr createDateFormat(const std::vector<LogString>& options);
+ END_DEFINE_PATTERN_CONVERTER(DatePatternConverter)
- private:
- // prevent copy and assignment
- DatePatternConverter(const DatePatternConverter&);
- DatePatternConverter& operator=(const DatePatternConverter&);
- };
+ DEFINE_PATTERN_CONVERTER(FullLocationPatternConverter)
+ END_DEFINE_PATTERN_CONVERTER(FullLocationPatternConverter)
- class LOG4CXX_EXPORT MDCPatternConverter : public PatternConverter
- {
- private:
- LogString key;
+ DEFINE_PATTERN_CONVERTER(LineLocationPatternConverter)
+ END_DEFINE_PATTERN_CONVERTER(LineLocationPatternConverter)
- public:
- MDCPatternConverter(const FormattingInfo& formattingInfo,
- const LogString& key);
- virtual void convert(LogString& sbuf,
- const spi::LoggingEventPtr& event,
- log4cxx::helpers::Pool& pool) const;
- private:
- // prevent copy and assignment
- MDCPatternConverter(const MDCPatternConverter&);
- MDCPatternConverter& operator=(const MDCPatternConverter&);
- };
+ DEFINE_PATTERN_CONVERTER(FileLocationPatternConverter)
+ END_DEFINE_PATTERN_CONVERTER(FileLocationPatternConverter)
- class LOG4CXX_EXPORT LocationPatternConverter : public PatternConverter
- {
- private:
- int type;
+ DEFINE_PATTERN_CONVERTER(MethodLocationPatternConverter)
+ END_DEFINE_PATTERN_CONVERTER(MethodLocationPatternConverter)
- public:
- LocationPatternConverter(const FormattingInfo& formattingInfo, int type);
- virtual void convert(LogString& sbuf,
- const spi::LoggingEventPtr& event,
- log4cxx::helpers::Pool& pool) const;
- };
+ DEFINE_PATTERN_CONVERTER(ClassNamePatternConverter)
+ END_DEFINE_PATTERN_CONVERTER(ClassNamePatternConverter)
+
+ DEFINE_PATTERN_CONVERTER(LoggerPatternConverter)
+ int precision;
+ END_DEFINE_PATTERN_CONVERTER(LoggerPatternConverter)
+
+ DEFINE_PATTERN_CONVERTER(MessagePatternConverter)
+ END_DEFINE_PATTERN_CONVERTER(MessagePatternConverter)
+
+ DEFINE_PATTERN_CONVERTER(LineSeparatorPatternConverter)
+ END_DEFINE_PATTERN_CONVERTER(LineSeparatorPatternConverter)
+
+ DEFINE_PATTERN_CONVERTER(LevelPatternConverter)
+ END_DEFINE_PATTERN_CONVERTER(LevelPatternConverter)
+
+ DEFINE_PATTERN_CONVERTER(RelativeTimePatternConverter)
+ RelativeTimeDateFormat formatter;
+ END_DEFINE_PATTERN_CONVERTER(RelativeTimePatternConverter)
+
+ DEFINE_PATTERN_CONVERTER(ThreadPatternConverter)
+ END_DEFINE_PATTERN_CONVERTER(ThreadPatternConverter)
+
+ DEFINE_PATTERN_CONVERTER(NDCPatternConverter)
+ END_DEFINE_PATTERN_CONVERTER(NDCPatternConverter)
+
+ DEFINE_PATTERN_CONVERTER(PropertiesPatternConverter)
+ LogString key;
+ static LogString getKey(const std::vector<LogString>& options);
+ END_DEFINE_PATTERN_CONVERTER(PropertiesPatternConverter)
+
+ DEFINE_PATTERN_CONVERTER(ThrowableInformationPatternConverter)
+ END_DEFINE_PATTERN_CONVERTER(ThrowableInformationPatternConverter)
- class LOG4CXX_EXPORT CategoryPatternConverter : public PatternConverter
- {
- private:
- int precision;
- public:
- CategoryPatternConverter(const FormattingInfo& formattingInfo,
- int precision);
- virtual void convert(LogString& sbuf,
- const spi::LoggingEventPtr& event,
- log4cxx::helpers::Pool& pool) const;
- };
}; // class PatternParser
} // namespace helpers
} // namespace log4cxx
+#undef DEFINE_PATTERN_CONVERTER
+#undef END_DEFINE_PATTERN_CONVERTER
+
#endif //_LOG4CXX_HELPER_PATTERN_PARSER_H
1.17 +1 -7 logging-log4cxx/src/patternlayout.cpp
Index: patternlayout.cpp
===================================================================
RCS file: /home/cvs/logging-log4cxx/src/patternlayout.cpp,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- patternlayout.cpp 15 Feb 2005 23:56:01 -0000 1.16
+++ patternlayout.cpp 18 Feb 2005 17:18:53 -0000 1.17
@@ -68,7 +68,7 @@
PatternConverterPtr PatternLayout::createPatternParser(const LogString& pattern)
{
- return PatternParser(pattern, timeZone).parse();
+ return PatternParser(pattern).parse();
}
void PatternLayout::setOption(const LogString& option, const LogString& value)
@@ -79,12 +79,6 @@
{
pattern = OptionConverter::convertSpecialChars(value);
}
- else if (StringHelper::equalsIgnoreCase(option,
- LOG4CXX_STR("TIMEZONE"),
- LOG4CXX_STR("timezone")))
- {
- timeZone = value;
- }
}
void PatternLayout::activateOptions(Pool& p)
1.29 +560 -362 logging-log4cxx/src/patternparser.cpp
Index: patternparser.cpp
===================================================================
RCS file: /home/cvs/logging-log4cxx/src/patternparser.cpp,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- patternparser.cpp 15 Feb 2005 23:56:01 -0000 1.28
+++ patternparser.cpp 18 Feb 2005 17:18:53 -0000 1.29
@@ -26,6 +26,7 @@
#include <log4cxx/level.h>
#include <log4cxx/mdc.h>
#include <log4cxx/helpers/transcoder.h>
+#include <sstream>
#include <apr_pools.h>
@@ -35,43 +36,105 @@
#define ESCAPE_CHAR LOG4CXX_STR('%')
-enum ParserState
-{
- LITERAL_STATE,
- CONVERTER_STATE,
- MINUS_STATE,
- DOT_STATE,
- MIN_STATE,
- MAX_STATE,
-
- FULL_LOCATION_CONVERTER,
- //METHOD_LOCATION_CONVERTER = 1001;
- CLASS_LOCATION_CONVERTER,
- LINE_LOCATION_CONVERTER,
- FILE_LOCATION_CONVERTER,
-
- RELATIVE_TIME_CONVERTER,
- THREAD_CONVERTER,
- LEVEL_CONVERTER,
- NDC_CONVERTER,
- MESSAGE_CONVERTER
-};
+const PatternParser::PatternConverterMap& PatternParser::getGlobalRulesRegistry() {
+ static PatternConverterMap globalRulesRegistry;
+ globalRulesRegistry.insert(PatternConverterMap::value_type(LOG4CXX_STR("c"),
+ LoggerPatternConverter::newInstance));
+ globalRulesRegistry.insert(PatternConverterMap::value_type(LOG4CXX_STR("logger"),
+ LoggerPatternConverter::newInstance));
+
+ globalRulesRegistry.insert(PatternConverterMap::value_type(LOG4CXX_STR("C"),
+ ClassNamePatternConverter::newInstance));
+ globalRulesRegistry.insert(PatternConverterMap::value_type(LOG4CXX_STR("class"),
+ ClassNamePatternConverter::newInstance));
+
+ globalRulesRegistry.insert(PatternConverterMap::value_type(LOG4CXX_STR("d"),
+ DatePatternConverter::newInstance));
+ globalRulesRegistry.insert(PatternConverterMap::value_type(LOG4CXX_STR("date"),
+ DatePatternConverter::newInstance));
+
+ globalRulesRegistry.insert(PatternConverterMap::value_type(LOG4CXX_STR("F"),
+ FileLocationPatternConverter::newInstance));
+ globalRulesRegistry.insert(PatternConverterMap::value_type(LOG4CXX_STR("file"),
+ FileLocationPatternConverter::newInstance));
+
+ globalRulesRegistry.insert(PatternConverterMap::value_type(LOG4CXX_STR("l"),
+ FullLocationPatternConverter::newInstance));
+
+ globalRulesRegistry.insert(PatternConverterMap::value_type(LOG4CXX_STR("L"),
+ LineLocationPatternConverter::newInstance));
+ globalRulesRegistry.insert(PatternConverterMap::value_type(LOG4CXX_STR("line"),
+ LineLocationPatternConverter::newInstance));
+
+ globalRulesRegistry.insert(PatternConverterMap::value_type(LOG4CXX_STR("m"),
+ MessagePatternConverter::newInstance));
+ globalRulesRegistry.insert(PatternConverterMap::value_type(LOG4CXX_STR("message"),
+ MessagePatternConverter::newInstance));
+
+ globalRulesRegistry.insert(PatternConverterMap::value_type(LOG4CXX_STR("n"),
+ LineSeparatorPatternConverter::newInstance));
+
+ globalRulesRegistry.insert(
+ PatternConverterMap::value_type(LOG4CXX_STR("M"),
+ MethodLocationPatternConverter::newInstance));
+ globalRulesRegistry.insert(
+ PatternConverterMap::value_type(LOG4CXX_STR("method"),
+ MethodLocationPatternConverter::newInstance));
+
+ globalRulesRegistry.insert(PatternConverterMap::value_type(LOG4CXX_STR("p"),
+ LevelPatternConverter::newInstance));
+ globalRulesRegistry.insert(PatternConverterMap::value_type(LOG4CXX_STR("level"),
+ LevelPatternConverter::newInstance));
+
+ globalRulesRegistry.insert(PatternConverterMap::value_type(LOG4CXX_STR("r"),
+ RelativeTimePatternConverter::newInstance));
+ globalRulesRegistry.insert(PatternConverterMap::value_type(LOG4CXX_STR("relative"),
+ RelativeTimePatternConverter::newInstance));
+
+ globalRulesRegistry.insert(PatternConverterMap::value_type(LOG4CXX_STR("t"),
+ ThreadPatternConverter::newInstance));
+ globalRulesRegistry.insert(PatternConverterMap::value_type(LOG4CXX_STR("thread"),
+ ThreadPatternConverter::newInstance));
+
+ globalRulesRegistry.insert(PatternConverterMap::value_type(LOG4CXX_STR("x"),
+ NDCPatternConverter::newInstance));
+ globalRulesRegistry.insert(PatternConverterMap::value_type(LOG4CXX_STR("ndc"),
+ NDCPatternConverter::newInstance));
+ globalRulesRegistry.insert(PatternConverterMap::value_type(LOG4CXX_STR("X"),
+ PropertiesPatternConverter::newInstance));
+ globalRulesRegistry.insert(PatternConverterMap::value_type(LOG4CXX_STR("properties"),
+ PropertiesPatternConverter::newInstance));
-PatternParser::PatternParser(const LogString& pattern, const LogString& timeZone)
+
+ globalRulesRegistry.insert(PatternConverterMap::value_type(LOG4CXX_STR("throwable"),
+ ThrowableInformationPatternConverter::newInstance));
+
+ return globalRulesRegistry;
+}
+
+void PatternParser::logError(const LogString& msg) {
+ LogLog::error(msg);
+}
+
+void PatternParser::logWarn(const LogString& msg) {
+ LogLog::warn(msg);
+}
+
+
+PatternParser::PatternParser(const LogString& pattern)
:
state(LITERAL_STATE),
- currentLiteral(),
patternLength(pattern.length()),
i(0),
head(),
tail(),
formattingInfo(),
- pattern(pattern),
- timeZone(timeZone)
+ pattern(pattern)
{
}
+
void PatternParser::addToList(PatternConverterPtr& pc)
{
if(head == 0)
@@ -85,305 +148,258 @@
}
}
-LogString PatternParser::extractOption()
-{
- if((i < patternLength) && (pattern.at(i) == LOG4CXX_STR('{')))
- {
- size_t end = pattern.find(LOG4CXX_STR('}'), i);
- if (end > i)
- {
- LogString r = pattern.substr(i + 1, end - (i + 1));
- i = end+1;
- return r;
- }
- }
+bool PatternParser::isUnicodeIdentifierStart(logchar ch) {
+ //
+ // greatly simplified version checks if
+ // character is USACII alpha or number
+ //
+ return (ch >= LOG4CXX_STR('A') && ch <= LOG4CXX_STR('Z')) ||
+ (ch >= LOG4CXX_STR('a') && ch <= LOG4CXX_STR('z')) ||
+ (ch >= LOG4CXX_STR('0') && ch <= LOG4CXX_STR('9'));
+}
- return LogString();
+bool PatternParser::isUnicodeIdentifierPart(logchar ch) {
+ //
+ // greatly simplified version checks if
+ // character is USACII alpha or number
+ //
+ return (ch >= LOG4CXX_STR('A') && ch <= LOG4CXX_STR('Z')) ||
+ (ch >= LOG4CXX_STR('a') && ch <= LOG4CXX_STR('z')) ||
+ (ch >= LOG4CXX_STR('0') && ch <= LOG4CXX_STR('9')) ||
+ (ch == LOG4CXX_STR('_'));
}
-int PatternParser::extractPrecisionOption()
-{
- LogString opt = extractOption();
- int r = 0;
- if(!opt.empty())
- {
- r = StringHelper::toInt(opt);
- if(r <= 0)
- {
- LogLog::error(
- ((LogString) LOG4CXX_STR("Precision option ("))
- + opt + LOG4CXX_STR(") isn't a positive integer."));
- r = 0;
- }
- }
- return r;
+/** Extract the converter identifier found at position i.
+ *
+ * After this function returns, the variable i will point to the
+ * first char after the end of the converter identifier.
+ *
+ * If i points to a char which is not a character acceptable at the
+ * start of a unicode identifier, the value null is returned.
+ *
+ */
+LogString PatternParser::extractConverter(logchar lastChar) {
+
+ // When this method is called, lastChar points to the first character of the
+ // conersion word. For example:
+ // For "%hello" lastChar = 'h'
+ // For "%-5hello" lastChar = 'h'
+
+ //System.out.println("lastchar is "+lastChar);
+
+ if(!isUnicodeIdentifierStart(lastChar)) {
+ return LogString();
+ }
+
+ LogString convBuf(1, lastChar);
+
+ while ((i < patternLength)
+ && isUnicodeIdentifierPart(pattern.at(i))) {
+ convBuf.append(1, pattern.at(i));
+ i++;
+ }
+
+ return convBuf;
}
-PatternConverterPtr PatternParser::parse()
+
+std::vector<LogString> PatternParser::extractOptions()
{
- logchar c;
- i = 0;
- while(i < patternLength)
- {
- c = pattern.at(i++);
- switch(state)
- {
- case LITERAL_STATE:
- // In literal state, the last char is always a literal.
- if(i == patternLength)
- {
- currentLiteral.append(1, c);
- continue;
- }
- if(c == ESCAPE_CHAR)
- {
- // peek at the next char.
- switch(pattern.at(i))
- {
- case ESCAPE_CHAR:
- currentLiteral.append(1, c);
- i++; // move pointer
- break;
- case LOG4CXX_STR('n'):
-#if defined(_WIN32)
- currentLiteral.append(LOG4CXX_STR("\x0D\x0A"));
-#else
- currentLiteral.append(1, LOG4CXX_STR('\x0A'));
-#endif
- i++; // move pointer
- break;
- default:
- // test if currentLiteral is not empty
- if(!currentLiteral.empty())
- {
- PatternConverterPtr patternConverter(new LiteralPatternConverter(
- currentLiteral));
- addToList(patternConverter);
- //LogLog.debug("Parsed LITERAL converter: \""
- // +currentLiteral+"\".");
- }
- currentLiteral.erase(currentLiteral.begin(), currentLiteral.end());
- currentLiteral.append(1, c); // append %
- state = CONVERTER_STATE;
- formattingInfo.reset();
- }
- }
- else
- {
- currentLiteral.append(1, c);
- }
- break;
- case CONVERTER_STATE:
- currentLiteral.append(1, c);
- switch(c)
- {
- case LOG4CXX_STR('-'):
- formattingInfo.leftAlign = true;
- break;
- case LOG4CXX_STR('.'):
- state = DOT_STATE;
- break;
- default:
- if(c >= LOG4CXX_STR('0') && c <= LOG4CXX_STR('9'))
- {
- formattingInfo.minChar = c - LOG4CXX_STR('0');
- state = MIN_STATE;
- }
- else
- finalizeConverter(c);
- } // switch
- break;
- case MIN_STATE:
- currentLiteral.append(1, c);
- if(c >= LOG4CXX_STR('0') && c <= LOG4CXX_STR('9'))
- formattingInfo.minChar = formattingInfo.minChar*10 + (c - LOG4CXX_STR('0'));
- else if(c == LOG4CXX_STR('.'))
- state = DOT_STATE;
- else
- {
- finalizeConverter(c);
- }
- break;
- case DOT_STATE:
- currentLiteral.append(1, c);
- if(c >= LOG4CXX_STR('0') && c <= LOG4CXX_STR('9'))
- {
- formattingInfo.maxChar = c - LOG4CXX_STR('0');
- state = MAX_STATE;
- }
- else {
- Pool p;
- LogLog::error(((LogString) LOG4CXX_STR("Error occured in position "))
- + StringHelper::toString(i, p)
- + LOG4CXX_STR(".") LOG4CXX_EOL LOG4CXX_STR(" Was expecting digit, instead got char \"")
- + LogString(1, c)
- + LOG4CXX_STR("\"."));
- state = LITERAL_STATE;
- }
- break;
- case MAX_STATE:
- currentLiteral.append(1, c);
- if(c >= LOG4CXX_STR('0') && c <= LOG4CXX_STR('9'))
- formattingInfo.maxChar = formattingInfo.maxChar*10 + (c - LOG4CXX_STR('0'));
- else
- {
- finalizeConverter(c);
- state = LITERAL_STATE;
- }
- break;
- } // switch
- } // while
- // test if currentLiteral is not empty
- if(!currentLiteral.empty())
- {
- PatternConverterPtr patternConverter(
- new LiteralPatternConverter(currentLiteral));
- addToList(patternConverter);
- //LogLog.debug("Parsed LITERAL converter: \""+currentLiteral+"\".");
- }
- return head;
+ std::vector<LogString> options;
+ while ((i < patternLength) && (pattern.at(i) == LOG4CXX_STR('{'))) {
+ size_t end = pattern.find(LOG4CXX_STR('}'), i);
+
+ if (end > i) {
+ LogString r(pattern.substr(i + 1, end - (i + 1)));
+ options.push_back(r);
+ i = end+1;
+ }
+ }
+
+ return options;
}
-void PatternParser::finalizeConverter(logchar c)
-{
- PatternConverterPtr pc;
+PatternConverterPtr PatternParser::parse() {
+ logchar c;
+ i = 0;
- switch(c)
- {
- case LOG4CXX_STR('c'):
- pc = new CategoryPatternConverter(formattingInfo,
- extractPrecisionOption());
- //LogLog::debug(LOG4CXX_STR("CATEGORY converter."));
- //formattingInfo.dump();
- currentLiteral.erase(currentLiteral.begin(), currentLiteral.end());
- break;
- case LOG4CXX_STR('d'):
- {
- DateFormat * df = 0;
- LogString dateFormatStr(extractOption());
- if(dateFormatStr.empty() ||
- StringHelper::equalsIgnoreCase(dateFormatStr,
- LOG4CXX_STR("ISO8601"), LOG4CXX_STR("iso8601")))
- df = new ISO8601DateFormat();
- else if(StringHelper::equalsIgnoreCase(dateFormatStr,
- LOG4CXX_STR("ABSOLUTE"), LOG4CXX_STR("absolute")))
- df = new AbsoluteTimeDateFormat();
- else if(StringHelper::equalsIgnoreCase(dateFormatStr,
- LOG4CXX_STR("DATE"), LOG4CXX_STR("date")))
- df = new DateTimeDateFormat();
- else
- {
- if (dateFormatStr.find(LOG4CXX_STR('%')) == std::string::npos) {
- df = new SimpleDateFormat(dateFormatStr);
- } else {
- df = new StrftimeDateFormat(dateFormatStr);
- }
- }
- DateFormatPtr formatter(df);
- df = new CachedDateFormat(formatter);
- pc = new DatePatternConverter(formattingInfo, df);
- //LogLog.debug("DATE converter {"+dateFormatStr+"}.");
- //formattingInfo.dump();
- currentLiteral.erase(currentLiteral.begin(), currentLiteral.end());
- break;
- }
- case LOG4CXX_STR('F'):
- pc = new LocationPatternConverter(formattingInfo,
- FILE_LOCATION_CONVERTER);
- //LogLog.debug("File name converter.");
- //formattingInfo.dump();
- currentLiteral.erase(currentLiteral.begin(), currentLiteral.end());
- break;
- case LOG4CXX_STR('l'):
- pc = new LocationPatternConverter(formattingInfo,
- FULL_LOCATION_CONVERTER);
- //LogLog.debug("Location converter.");
- //formattingInfo.dump();
- currentLiteral.erase(currentLiteral.begin(), currentLiteral.end());
- break;
- case LOG4CXX_STR('L'):
-
- pc = new LocationPatternConverter(formattingInfo,
- LINE_LOCATION_CONVERTER);
- //LogLog.debug("LINE NUMBER converter.");
- //formattingInfo.dump();
- currentLiteral.erase(currentLiteral.begin(), currentLiteral.end());
- break;
- case LOG4CXX_STR('m'):
- pc = new BasicPatternConverter(formattingInfo, MESSAGE_CONVERTER);
- //LogLog.debug("MESSAGE converter.");
- //formattingInfo.dump();
- currentLiteral.erase(currentLiteral.begin(), currentLiteral.end());
- break;
- case LOG4CXX_STR('p'):
- {
- pc = new BasicPatternConverter(formattingInfo, LEVEL_CONVERTER);
- //LogLog.debug("LEVEL converter.");
- //formattingInfo.dump();
- currentLiteral.erase(currentLiteral.begin(), currentLiteral.end());
- }
- break;
- case LOG4CXX_STR('r'):
- pc = new BasicPatternConverter(formattingInfo,
- RELATIVE_TIME_CONVERTER);
- //LogLog.debug("RELATIVE time converter.");
- //formattingInfo.dump();
- currentLiteral.erase(currentLiteral.begin(), currentLiteral.end());
- break;
-
- case LOG4CXX_STR('t'):
- pc = new BasicPatternConverter(formattingInfo, THREAD_CONVERTER);
- //LogLog.debug("THREAD converter.");
- //formattingInfo.dump();
- currentLiteral.erase(currentLiteral.begin(), currentLiteral.end());
- break;
+ while (i < patternLength) {
+ c = pattern.at(i++);
+ switch (state) {
+ case LITERAL_STATE:
- /*case 'u':
- if(i < patternLength) {
- char cNext = pattern.charAt(i);
- if(cNext >= '0' && cNext <= '9') {
- pc = new UserFieldPatternConverter(formattingInfo, cNext - '0');
- LogLog.debug("USER converter ["+cNext+"].");
- formattingInfo.dump();
- currentLiteral.setLength(0);
- i++;
- }
- else
- LogLog.error("Unexpected char" +cNext+" at position "+i);
- }
- break;*/
+ // In literal state, the last char is always a literal.
+ if (i == patternLength) {
+ currentLiteral.append(1, c);
+
+ continue;
+ }
- case LOG4CXX_STR('x'):
- pc = new BasicPatternConverter(formattingInfo, NDC_CONVERTER);
- //LogLog.debug("NDC converter.");
- currentLiteral.erase(currentLiteral.begin(), currentLiteral.end());
- break;
+ if (c == ESCAPE_CHAR) {
+ // peek at the next char.
+ switch (pattern.at(i)) {
+ case ESCAPE_CHAR:
+ currentLiteral.append(1, c);
+ i++; // move pointer
- case LOG4CXX_STR('X'):
- {
- LogString xOpt = extractOption();
- pc = new MDCPatternConverter(formattingInfo, xOpt);
- currentLiteral.erase(currentLiteral.begin(), currentLiteral.end());
- break;
+ break;
+
+ default:
+
+ if (currentLiteral.length() != 0) {
+ PatternConverterPtr converter(
+ new LiteralPatternConverter(currentLiteral));
+ addToList(converter);
+
+ }
+
+ currentLiteral.erase(currentLiteral.begin(), currentLiteral.end());
+ currentLiteral.append(1, c); // append %
+ state = CONVERTER_STATE;
+ formattingInfo.reset();
+ }
+ } else {
+ currentLiteral.append(1, c);
}
+ break;
+
+ case CONVERTER_STATE:
+ currentLiteral.append(1, c);
+
+ switch (c) {
+ case '-':
+ formattingInfo.leftAlign = true;
+
+ break;
+
+ case '.':
+ state = DOT_STATE;
+
+ break;
+
default:
- {
- Pool p;
- LogLog::error(((LogString) LOG4CXX_STR("Unexpected char ["))
- + LogString(1, c)
- + LOG4CXX_STR("] at position ")
- + StringHelper::toString(i, p)
- + LOG4CXX_STR(" in conversion pattern."));
- pc = new LiteralPatternConverter(currentLiteral);
- currentLiteral.erase(currentLiteral.begin(), currentLiteral.end());
- }
- }
- addConverter(pc);
+ if ((c >= LOG4CXX_STR('0')) && (c <= LOG4CXX_STR('9'))) {
+ formattingInfo.minChar = c - LOG4CXX_STR('0');
+ state = MIN_STATE;
+ } else {
+ finalizeConverter(c);
+ }
+ } // switch
+
+ break;
+
+ case MIN_STATE:
+ currentLiteral.append(1, c);
+
+ if ((c >= LOG4CXX_STR('0')) && (c <= LOG4CXX_STR('9'))) {
+ formattingInfo.minChar = (formattingInfo.minChar * 10) + (c - LOG4CXX_STR('0'));
+ } else if (c == LOG4CXX_STR('.')) {
+ state = DOT_STATE;
+ } else {
+ finalizeConverter(c);
+ }
+
+ break;
+
+ case DOT_STATE:
+ currentLiteral.append(1, c);
+
+ if ((c >= LOG4CXX_STR('0')) && (c <= LOG4CXX_STR('9'))) {
+ formattingInfo.maxChar = c - LOG4CXX_STR('0');
+ state = MAX_STATE;
+ } else {
+ std::basic_ostringstream<logchar> os;
+ os << LOG4CXX_STR("Error occured in position ") << i
+ << LOG4CXX_STR(".\n Was expecting digit, instead got char \"")
+ << c + LOG4CXX_STR("\".");
+ logError(os.str());
+ state = LITERAL_STATE;
+ }
+
+ break;
+
+ case MAX_STATE:
+ currentLiteral.append(1, c);
+
+ if ((c >= LOG4CXX_STR('0')) && (c <= LOG4CXX_STR('9'))) {
+ formattingInfo.maxChar = (formattingInfo.maxChar * 10) + (c - LOG4CXX_STR('0'));
+ } else {
+ finalizeConverter(c);
+ state = LITERAL_STATE;
+ }
+
+ break;
+ } // switch
+ }
+
+ // while
+ if (currentLiteral.length() != 0) {
+ PatternConverterPtr converter(new LiteralPatternConverter(currentLiteral));
+ addToList(converter);
+
+ //LogLog.debug("Parsed LITERAL converter: \""+currentLiteral+"\".");
+ }
+
+ return head;
+ }
+
+PatternParser::PatternConverterFactory PatternParser::findConverterClass(
+ const LogString& converterId) {
+
+ PatternConverterMap::const_iterator r = converterRegistry.find(converterId);
+ if(r != converterRegistry.end()) {
+ return r->second;
+ }
+
+ r = getGlobalRulesRegistry().find(converterId);
+ if(r != getGlobalRulesRegistry().end()) {
+ return r->second;
+ }
+
+ return NULL;
+}
+
+
+/**
+ * When finalizeConverter is called 'c' is the current conversion caracter
+ * and i points to the character following 'c'.
+ */
+void PatternParser::finalizeConverter(logchar c) {
+ PatternConverterPtr pc;
+
+ LogString converterId(extractConverter(c));
+
+ PatternConverterFactory factory = findConverterClass(converterId);
+
+ std::vector<LogString> options(extractOptions());
+
+
+ //System.out.println("Option is [" + option + "]");
+ if (factory != NULL) {
+ pc = (*factory)(formattingInfo, options);
+ currentLiteral.erase(currentLiteral.begin(), currentLiteral.end());
+ } else {
+ std::basic_ostringstream<logchar> os;
+ if (converterId.empty()) {
+ os << LOG4CXX_STR("Empty conversion specifier starting at position ");
+ } else {
+ os << LOG4CXX_STR("Unrecognized conversion specifier [")
+ << converterId
+ << LOG4CXX_STR("] starting at position ");
+ }
+ os << i << LOG4CXX_STR(" in conversion pattern.");
+ logError(os.str());
+ pc = new LiteralPatternConverter(currentLiteral);
+ currentLiteral.erase(currentLiteral.begin(), currentLiteral.end());
+ }
+ addConverter(pc);
}
+
+
void PatternParser::addConverter(PatternConverterPtr& pc)
{
currentLiteral.erase(currentLiteral.begin(), currentLiteral.end());
@@ -395,39 +411,34 @@
formattingInfo.reset();
}
-// ---------------------------------------------------------------------
-// PatternConverters
-// ---------------------------------------------------------------------
-PatternParser::BasicPatternConverter::BasicPatternConverter(const FormattingInfo& formattingInfo, int type)
-: PatternConverter(formattingInfo), type(type)
-{
+PatternParser::PatternConverterMap PatternParser::getConverterRegistry() const {
+ return converterRegistry;
}
-void PatternParser::BasicPatternConverter::convert(LogString& sbuf,
- const spi::LoggingEventPtr& event,
- Pool& pool) const
-{
- switch(type)
- {
- case RELATIVE_TIME_CONVERTER:
- sbuf.append(
- StringHelper::toString((event->getTimeStamp() - LoggingEvent::getStartTime())/1000, pool));
- break;
- case THREAD_CONVERTER:
- sbuf.append(event->getThreadName());
- break;
- case LEVEL_CONVERTER:
- sbuf.append(event->getLevel()->toString());
- break;
- case NDC_CONVERTER:
- sbuf.append(event->getNDC());
- break;
- case MESSAGE_CONVERTER:
- sbuf.append(event->getRenderedMessage());
- break;
+void PatternParser::setConverterRegistry(const PatternConverterMap& newRegistry) {
+ converterRegistry = newRegistry;
+}
+
+
+int PatternParser::getPrecision(
+ const std::vector<LogString>& options) {
+ int r = 0;
+ if (options.size() > 0 && !options[0].empty()) {
+ r = StringHelper::toInt(options[0]);
+ if (r < 0) {
+ LogString msg(LOG4CXX_STR("Precision options ("));
+ msg.append(options[0]);
+ msg.append(LOG4CXX_STR(") isn't a positive integer."));
+ PatternParser::logError(msg);
}
+ }
+ return r;
}
+
+// ---------------------------------------------------------------------
+// PatternConverters
+// ---------------------------------------------------------------------
PatternParser::LiteralPatternConverter::LiteralPatternConverter(const LogString& value)
: literal(value)
{
@@ -441,28 +452,70 @@
sbuf.append(literal);
}
-PatternParser::DatePatternConverter::DatePatternConverter(const FormattingInfo& formattingInfo, DateFormat * df)
-: PatternConverter(formattingInfo), df(df)
+PatternParser::DatePatternConverter::DatePatternConverter(const FormattingInfo& formattingInfo,
+ const std::vector<LogString>& options)
+: PatternConverter(formattingInfo), df(createDateFormat(options))
{
}
-PatternParser::DatePatternConverter::~DatePatternConverter()
-{
- delete df;
+DateFormatPtr PatternParser::DatePatternConverter::createDateFormat(
+ const std::vector<LogString>& options) {
+ DateFormatPtr df;
+ if (options.size() == 0) {
+ df = new ISO8601DateFormat();
+ } else {
+ LogString dateFormatStr(options[0]);
+
+ if(dateFormatStr.empty() ||
+ StringHelper::equalsIgnoreCase(dateFormatStr,
+ LOG4CXX_STR("ISO8601"), LOG4CXX_STR("iso8601"))) {
+ df = new ISO8601DateFormat();
+ } else if(StringHelper::equalsIgnoreCase(dateFormatStr,
+ LOG4CXX_STR("ABSOLUTE"), LOG4CXX_STR("absolute"))) {
+ df = new AbsoluteTimeDateFormat();
+ } else if(StringHelper::equalsIgnoreCase(dateFormatStr,
+ LOG4CXX_STR("DATE"), LOG4CXX_STR("date"))) {
+ df = new DateTimeDateFormat();
+ } else {
+ if (dateFormatStr.find(LOG4CXX_STR('%')) == std::string::npos) {
+ df = new SimpleDateFormat(dateFormatStr);
+ } else {
+ df = new StrftimeDateFormat(dateFormatStr);
+ }
+ }
+ if (options.size() >= 2) {
+ TimeZonePtr tz(TimeZone::getTimeZone(options[1]));
+ if (tz != NULL) {
+ df->setTimeZone(tz);
+ }
+ }
+ }
+ df = new CachedDateFormat(df);
+ return df;
}
+
+
void PatternParser::DatePatternConverter::convert(LogString& sbuf,
const spi::LoggingEventPtr& event, Pool& p) const
{
df->format(sbuf, event->getTimeStamp(), p);
}
-PatternParser::MDCPatternConverter::MDCPatternConverter(const FormattingInfo& formattingInfo, const LogString& key)
-: PatternConverter(formattingInfo), key(key)
+PatternParser::PropertiesPatternConverter::PropertiesPatternConverter(const FormattingInfo& formattingInfo,
+ const std::vector<LogString>& options)
+: PatternConverter(formattingInfo), key(getKey(options))
{
}
-void PatternParser::MDCPatternConverter::convert(LogString& sbuf,
+LogString PatternParser::PropertiesPatternConverter::getKey(const std::vector<LogString>& options) {
+ if (options.size() > 0) {
+ return options[0];
+ }
+ return LogString();
+}
+
+void PatternParser::PropertiesPatternConverter::convert(LogString& sbuf,
const spi::LoggingEventPtr& event,
Pool& pool) const
{
@@ -498,38 +551,91 @@
}
-PatternParser::LocationPatternConverter::LocationPatternConverter(const FormattingInfo& formattingInfo, int type)
-: PatternConverter(formattingInfo), type(type)
+PatternParser::FullLocationPatternConverter::FullLocationPatternConverter(
+ const FormattingInfo& formattingInfo,
+ const std::vector<LogString>& opions)
+: PatternConverter(formattingInfo)
{
}
-void PatternParser::LocationPatternConverter::convert(LogString& sbuf,
+void PatternParser::FullLocationPatternConverter::convert(LogString& sbuf,
const spi::LoggingEventPtr& event, Pool& pool) const
{
const LocationInfo& locInfo = event->getLocationInformation();
- switch(type)
- {
- case FULL_LOCATION_CONVERTER:
- Transcoder::decode(locInfo.getFileName(), sbuf);
- sbuf.append(1, LOG4CXX_STR('('));
- sbuf.append(StringHelper::toString(locInfo.getLineNumber(), pool));
- sbuf.append(1, LOG4CXX_STR(')'));
- break;
- case LINE_LOCATION_CONVERTER:
- sbuf.append(StringHelper::toString(locInfo.getLineNumber(), pool));
- break;
- case FILE_LOCATION_CONVERTER:
- Transcoder::decode(locInfo.getFileName(), sbuf);
- }
+ Transcoder::decode(locInfo.getFileName(), sbuf);
+ sbuf.append(1, LOG4CXX_STR('('));
+ sbuf.append(StringHelper::toString(locInfo.getLineNumber(), pool));
+ sbuf.append(1, LOG4CXX_STR(')'));
+}
+
+PatternParser::LineLocationPatternConverter::LineLocationPatternConverter(
+ const FormattingInfo& formattingInfo,
+ const std::vector<LogString>& opions)
+: PatternConverter(formattingInfo)
+{
+}
+
+void PatternParser::LineLocationPatternConverter::convert(LogString& sbuf,
+ const spi::LoggingEventPtr& event, Pool& pool) const
+{
+ const LocationInfo& locInfo = event->getLocationInformation();
+ sbuf.append(StringHelper::toString(locInfo.getLineNumber(), pool));
+}
+
+PatternParser::FileLocationPatternConverter::FileLocationPatternConverter(
+ const FormattingInfo& formattingInfo,
+ const std::vector<LogString>& opions)
+: PatternConverter(formattingInfo)
+{
+}
+
+void PatternParser::FileLocationPatternConverter::convert(LogString& sbuf,
+ const spi::LoggingEventPtr& event, Pool& pool) const
+{
+ const LocationInfo& locInfo = event->getLocationInformation();
+ Transcoder::decode(locInfo.getFileName(), sbuf);
+}
+
+PatternParser::MethodLocationPatternConverter::MethodLocationPatternConverter(
+ const FormattingInfo& formattingInfo,
+ const std::vector<LogString>& opions)
+: PatternConverter(formattingInfo)
+{
+}
+
+void PatternParser::MethodLocationPatternConverter::convert(LogString& sbuf,
+ const spi::LoggingEventPtr& event, Pool& pool) const
+{
+ const LocationInfo& locInfo = event->getLocationInformation();
+ Transcoder::decode(locInfo.getMethodName(), sbuf);
+}
+
+PatternParser::ClassNamePatternConverter::ClassNamePatternConverter(
+ const FormattingInfo& formattingInfo,
+ const std::vector<LogString>& opions)
+: PatternConverter(formattingInfo)
+{
}
-PatternParser::CategoryPatternConverter::CategoryPatternConverter(const FormattingInfo&
- formattingInfo, int precision)
-: PatternConverter(formattingInfo), precision(precision)
+void PatternParser::ClassNamePatternConverter::convert(LogString& sbuf,
+ const spi::LoggingEventPtr& event, Pool& pool) const
+{
+ const LocationInfo& locInfo = event->getLocationInformation();
+ Transcoder::decode(locInfo.getClassName(), sbuf);
+}
+
+
+
+PatternParser::LoggerPatternConverter::LoggerPatternConverter(const FormattingInfo&
+ formattingInfo, const std::vector<LogString>& options)
+: PatternConverter(formattingInfo), precision(PatternParser::getPrecision(options))
{
}
-void PatternParser::CategoryPatternConverter::convert(LogString& sbuf,
+
+
+
+void PatternParser::LoggerPatternConverter::convert(LogString& sbuf,
const spi::LoggingEventPtr& event,
Pool& pool) const
{
@@ -562,3 +668,95 @@
+PatternParser::MessagePatternConverter::MessagePatternConverter(
+ const FormattingInfo& formattingInfo,
+ const std::vector<LogString>& opions)
+: PatternConverter(formattingInfo)
+{
+}
+
+void PatternParser::MessagePatternConverter::convert(LogString& sbuf,
+ const spi::LoggingEventPtr& event, Pool& pool) const
+{
+ sbuf.append(event->getRenderedMessage());
+}
+
+PatternParser::LineSeparatorPatternConverter::LineSeparatorPatternConverter(
+ const FormattingInfo& formattingInfo,
+ const std::vector<LogString>& opions)
+: PatternConverter(formattingInfo)
+{
+}
+
+void PatternParser::LineSeparatorPatternConverter::convert(LogString& sbuf,
+ const spi::LoggingEventPtr& event, Pool& pool) const
+{
+ sbuf.append(LOG4CXX_EOL);
+}
+
+PatternParser::RelativeTimePatternConverter::RelativeTimePatternConverter(
+ const FormattingInfo& formattingInfo,
+ const std::vector<LogString>& opions)
+: PatternConverter(formattingInfo)
+{
+}
+
+void PatternParser::RelativeTimePatternConverter::convert(LogString& sbuf,
+ const spi::LoggingEventPtr& event, Pool& pool) const
+{
+ formatter.format(sbuf, event->getTimeStamp(), pool);
+}
+
+PatternParser::ThreadPatternConverter::ThreadPatternConverter(
+ const FormattingInfo& formattingInfo,
+ const std::vector<LogString>& opions)
+: PatternConverter(formattingInfo)
+{
+}
+
+void PatternParser::ThreadPatternConverter::convert(LogString& sbuf,
+ const spi::LoggingEventPtr& event, Pool& pool) const
+{
+ sbuf.append(event->getThreadName());
+}
+
+
+
+PatternParser::ThrowableInformationPatternConverter::ThrowableInformationPatternConverter(
+ const FormattingInfo& formattingInfo,
+ const std::vector<LogString>& opions)
+: PatternConverter(formattingInfo)
+{
+}
+
+void PatternParser::ThrowableInformationPatternConverter::convert(LogString& sbuf,
+ const spi::LoggingEventPtr& event, Pool& pool) const
+{
+ sbuf.append(LOG4CXX_STR("ThrowableInformation not implemented"));
+}
+
+PatternParser::NDCPatternConverter::NDCPatternConverter(
+ const FormattingInfo& formattingInfo,
+ const std::vector<LogString>& opions)
+: PatternConverter(formattingInfo)
+{
+}
+
+void PatternParser::NDCPatternConverter::convert(LogString& sbuf,
+ const spi::LoggingEventPtr& event, Pool& pool) const
+{
+ sbuf.append(event->getNDC());
+}
+
+PatternParser::LevelPatternConverter::LevelPatternConverter(
+ const FormattingInfo& formattingInfo,
+ const std::vector<LogString>& opions)
+: PatternConverter(formattingInfo)
+{
+}
+
+void PatternParser::LevelPatternConverter::convert(LogString& sbuf,
+ const spi::LoggingEventPtr& event, Pool& pool) const
+{
+ sbuf.append(event->getLevel()->toString());
+}
1.12 +16 -7 logging-log4cxx/src/timezone.cpp
Index: timezone.cpp
===================================================================
RCS file: /home/cvs/logging-log4cxx/src/timezone.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- timezone.cpp 15 Feb 2005 23:56:01 -0000 1.11
+++ timezone.cpp 18 Feb 2005 17:18:54 -0000 1.12
@@ -1,9 +1,18 @@
-/* * Copyright 2003,2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License. * You may obtain a copy of the License at *
-* http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and * limitations under the License. */
+/*
+ * Copyright 2003,2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
#include <log4cxx/helpers/timezone.h>
#include <stdlib.h>
@@ -139,7 +148,7 @@
{
if ( id == LOG4CXX_STR("GMT") )
{
- return log4cxx::helpers::TimeZoneImpl::LocalTimeZone::getInstance();
+ return log4cxx::helpers::TimeZoneImpl::GMTTimeZone::getInstance();
}
if ( id.length() >= 5 && id.substr( 0, 3 ) == LOG4CXX_STR("GMT") )
{
1.3 +1 -1 logging-log4cxx/tests/input/Makefile.am
Index: Makefile.am
===================================================================
RCS file: /home/cvs/logging-log4cxx/tests/input/Makefile.am,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Makefile.am 10 Feb 2005 05:07:31 -0000 1.2
+++ Makefile.am 18 Feb 2005 17:18:54 -0000 1.3
@@ -1,2 +1,2 @@
-SUBDIRS = ndb performance xml
+SUBDIRS = ndc performance xml
EXTRA_DIST = *.properties
1.7 +9 -1 logging-log4cxx/tests/src/helpers/timezonetestcase.cpp
Index: timezonetestcase.cpp
===================================================================
RCS file: /home/cvs/logging-log4cxx/tests/src/helpers/timezonetestcase.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- timezonetestcase.cpp 15 Feb 2005 23:56:04 -0000 1.6
+++ timezonetestcase.cpp 18 Feb 2005 17:18:54 -0000 1.7
@@ -1,5 +1,5 @@
/*
- * Copyright 2004 The Apache Software Foundation.
+ * Copyright 2004,2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,6 +40,7 @@
CPPUNIT_TEST(test3);
CPPUNIT_TEST(test4);
CPPUNIT_TEST(test5);
+ CPPUNIT_TEST(test6);
CPPUNIT_TEST_SUITE_END();
#define MICROSECONDS_PER_DAY APR_INT64_C(86400000000)
@@ -108,6 +109,13 @@
CPPUNIT_ASSERT_EQUAL(6, exploded.tm_hour);
}
+/**
+ * Checks the GMT timezone
+ */
+void test6() {
+ TimeZonePtr tz(TimeZone::getTimeZone(LOG4CXX_STR("GMT")));
+ CPPUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("GMT"), tz->getID());
+}
};
1.4 +15 -2 logging-log4cxx/tests/src/pattern/num343patternconverter.cpp
Index: num343patternconverter.cpp
===================================================================
RCS file: /home/cvs/logging-log4cxx/tests/src/pattern/num343patternconverter.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- num343patternconverter.cpp 11 Dec 2004 04:53:29 -0000 1.3
+++ num343patternconverter.cpp 18 Feb 2005 17:18:54 -0000 1.4
@@ -1,5 +1,5 @@
/*
- * Copyright 2003,2004 The Apache Software Foundation.
+ * Copyright 2003,2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,8 +18,21 @@
using namespace log4cxx;
using namespace log4cxx::helpers;
+using namespace log4cxx::pattern;
-void Num343PatternConverter::convert(LogString& sbuf, const spi::LoggingEventPtr& event)
+Num343PatternConverter::Num343PatternConverter() {
+}
+
+PatternConverter* Num343PatternConverter::newInstance(
+ const FormattingInfo& info,
+ const std::vector<LogString>& options) {
+ return new Num343PatternConverter();
+}
+
+
+void Num343PatternConverter::convert(LogString& sbuf,
+ const spi::LoggingEventPtr& event,
+ Pool& pool) const
{
sbuf.append(LOG4CXX_STR("343"));
}
1.6 +17 -6 logging-log4cxx/tests/src/pattern/num343patternconverter.h
Index: num343patternconverter.h
===================================================================
RCS file: /home/cvs/logging-log4cxx/tests/src/pattern/num343patternconverter.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- num343patternconverter.h 15 Feb 2005 23:56:04 -0000 1.5
+++ num343patternconverter.h 18 Feb 2005 17:18:54 -0000 1.6
@@ -1,5 +1,5 @@
/*
- * Copyright 2003,2004 The Apache Software Foundation.
+ * Copyright 2003,2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,12 +15,23 @@
*/
#include <log4cxx/helpers/patternconverter.h>
+#include <vector>
namespace log4cxx
{
- class Num343PatternConverter : public helpers::PatternConverter
- {
- public:
- void convert(LogString& sbuf, const spi::LoggingEventPtr& event);
- };
+ namespace pattern {
+ class Num343PatternConverter : public log4cxx::helpers::PatternConverter
+ {
+ public:
+ Num343PatternConverter();
+ static log4cxx::helpers::PatternConverter* newInstance(
+ const log4cxx::helpers::FormattingInfo& info,
+ const std::vector<LogString>& options);
+
+ protected:
+ virtual void convert(LogString& sbuf,
+ const log4cxx::spi::LoggingEventPtr& event,
+ log4cxx::helpers::Pool& pool) const;
+ };
+ }
}
1.8 +152 -2 logging-log4cxx/tests/src/pattern/patternparsertestcase.cpp
Index: patternparsertestcase.cpp
===================================================================
RCS file: /home/cvs/logging-log4cxx/tests/src/pattern/patternparsertestcase.cpp,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- patternparsertestcase.cpp 15 Feb 2005 23:56:04 -0000 1.7
+++ patternparsertestcase.cpp 18 Feb 2005 17:18:54 -0000 1.8
@@ -1,5 +1,5 @@
/*
- * Copyright 2003,2004 The Apache Software Foundation.
+ * Copyright 2003,2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,16 +24,29 @@
#include "num343patternconverter.h"
#include "../testchar.h"
+#include "../insertwide.h"
#include <log4cxx/spi/loggerrepository.h>
-
+#include <log4cxx/helpers/patternparser.h>
+#include <log4cxx/helpers/patternconverter.h>
+#include <log4cxx/helpers/relativetimedateformat.h>
+#include <log4cxx/helpers/simpledateformat.h>
using namespace log4cxx;
using namespace log4cxx::helpers;
using namespace log4cxx::spi;
+using namespace log4cxx::pattern;
+
class PatternParserTestCase : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(PatternParserTestCase);
+ CPPUNIT_TEST(testNewWord);
+ CPPUNIT_TEST(testNewWord2);
+ CPPUNIT_TEST(testBogusWord1);
+ CPPUNIT_TEST(testBogusWord2);
+ CPPUNIT_TEST(testBasic1);
+ CPPUNIT_TEST(testBasic2);
+ CPPUNIT_TEST(testMultiOption);
CPPUNIT_TEST_SUITE_END();
LoggerPtr logger;
@@ -52,6 +65,143 @@
{
logger->getLoggerRepository()->resetConfiguration();
}
+
+ void convert(LoggingEventPtr& event,
+ PatternConverterPtr& head,
+ Pool& p,
+ LogString& dst) {
+ PatternConverterPtr c(head);
+
+ while (c != NULL) {
+ c->format(dst, event, p);
+ c = c->next;
+ }
+ }
+
+
+ void testNewWord() {
+ PatternParser patternParser(LOG4CXX_STR("%z343"));
+ PatternParser::PatternConverterMap ruleRegistry;
+ LogString name(LOG4CXX_STR("z343"));
+ ruleRegistry.insert(
+ PatternParser::PatternConverterMap::value_type(name,
+ Num343PatternConverter::newInstance));
+
+ patternParser.setConverterRegistry(ruleRegistry);
+
+ PatternConverterPtr head(patternParser.parse());
+
+ Pool p;
+ LogString result;
+ convert(event, head, p, result);
+ CPPUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("343"), result);
+ }
+
+
+ /* Test whether words starting with the letter 'n' are treated differently,
+ * which was previously the case by mistake.
+ */
+ void testNewWord2() {
+ PatternParser patternParser(LOG4CXX_STR("%n343"));
+
+ PatternParser::PatternConverterMap ruleRegistry;
+ LogString name(LOG4CXX_STR("n343"));
+ ruleRegistry.insert(
+ PatternParser::PatternConverterMap::value_type(name,
+ Num343PatternConverter::newInstance));
+
+ patternParser.setConverterRegistry(ruleRegistry);
+
+ PatternConverterPtr head(patternParser.parse());
+
+ Pool p;
+ LogString result;
+ convert(event, head, p, result);
+ CPPUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("343"), result);
+ }
+
+ void testBogusWord1() {
+ PatternParser patternParser(LOG4CXX_STR("%, foobar"));
+ PatternConverterPtr head(patternParser.parse());
+
+ Pool p;
+ LogString result;
+ convert(event, head, p, result);
+
+ CPPUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("%, foobar"), result);
+ }
+
+ void testBogusWord2() {
+ PatternParser patternParser(LOG4CXX_STR("xyz %, foobar"));
+ PatternConverterPtr head = patternParser.parse();
+
+ Pool p;
+ LogString result;
+ convert(event, head, p, result);
+
+
+ CPPUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("xyz %, foobar"), result);
+ }
+
+ void testBasic1() {
+ PatternParser patternParser(LOG4CXX_STR("hello %-5level - %m%n"));
+ PatternConverterPtr head = patternParser.parse();
+
+ Pool p;
+ LogString result;
+ convert(event, head, p, result);
+
+ CPPUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("hello INFO - msg 1") LOG4CXX_EOL, result);
+ }
+
+ void testBasic2() {
+ PatternParser patternParser(
+ LOG4CXX_STR("%relative %-5level [%thread] %logger - %m%n"));
+ PatternConverterPtr head = patternParser.parse();
+
+ Pool pool;
+ LogString result;
+ convert(event, head, pool, result);
+
+
+ RelativeTimeDateFormat relativeFormat;
+ LogString expected;
+ relativeFormat.format(expected, event->getTimeStamp(), pool);
+
+ expected.append(LOG4CXX_STR(" INFO ["));
+ expected.append(event->getThreadName());
+ expected.append(LOG4CXX_STR("] "));
+ expected.append(logger->getName());
+ expected.append(LOG4CXX_STR(" - msg 1") LOG4CXX_EOL);
+
+ CPPUNIT_ASSERT_EQUAL(expected, result);
+ }
+
+ void testMultiOption() {
+ PatternParser patternParser
+ (LOG4CXX_STR("%d{HH:mm:ss}{GMT} %d{HH:mm:ss} %c - %m"));
+ PatternConverterPtr head = patternParser.parse();
+
+ Pool pool;
+ LogString result;
+ convert(event, head, pool, result);
+
+ SimpleDateFormat dateFormat(LOG4CXX_STR("HH:mm:ss"));
+ LogString localTime;
+ dateFormat.format(localTime, event->getTimeStamp(), pool);
+
+ dateFormat.setTimeZone(TimeZone::getGMT());
+ LogString utcTime;
+ dateFormat.format(utcTime, event->getTimeStamp(), pool);
+
+ LogString buf(utcTime);
+ buf.append(1, LOG4CXX_STR(' '));
+ buf.append(localTime);
+ buf.append(LOG4CXX_STR(" org.foobar - msg 1"));
+ CPPUNIT_ASSERT_EQUAL(buf, result);
+
+ }
+
};
CPPUNIT_TEST_SUITE_REGISTRATION(PatternParserTestCase);