diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..b62025d
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,2 @@
+debian/changelog merge=ours
+debian/source/format merge=ours
diff --git a/data/cn.kylinos.background.service b/data/cn.kylinos.background.service
index 1a1ebaa..a150865 100755
--- a/data/cn.kylinos.background.service
+++ b/data/cn.kylinos.background.service
@@ -1,3 +1,3 @@
[D-BUS Service]
Name=cn.kylinos.background
-Exec=/usr/lib/ukui-interface/ukui-backgroundserver
+Exec=/usr/libexec/ukui-backgroundserver
diff --git a/data/cn.kylinos.desktop.service b/data/cn.kylinos.desktop.service
index 66d2f6e..08860bf 100755
--- a/data/cn.kylinos.desktop.service
+++ b/data/cn.kylinos.desktop.service
@@ -1,3 +1,3 @@
[D-BUS Service]
Name=cn.kylinos.desktop
-Exec=/usr/lib/ukui-interface/ukui-desktopserver
+Exec=/usr/libexec/ukui-desktopserver
diff --git a/data/cn.kylinos.font.service b/data/cn.kylinos.font.service
index 4fd6bae..246ea8c 100755
--- a/data/cn.kylinos.font.service
+++ b/data/cn.kylinos.font.service
@@ -1,3 +1,3 @@
[D-BUS Service]
Name=cn.kylinos.font
-Exec=/usr/lib/ukui-interface/ukui-fontserver
+Exec=/usr/libexec/ukui-fontserver
diff --git a/data/cn.kylinos.interface.service b/data/cn.kylinos.interface.service
index dc0579f..c74ddc6 100755
--- a/data/cn.kylinos.interface.service
+++ b/data/cn.kylinos.interface.service
@@ -1,3 +1,3 @@
[D-BUS Service]
Name=cn.kylinos.interface
-Exec=/usr/lib/ukui-interface/ukui-interfaceserver
+Exec=/usr/libexec/ukui-interfaceserver
diff --git a/data/cn.kylinos.keyboard.service b/data/cn.kylinos.keyboard.service
index 971535e..f551895 100755
--- a/data/cn.kylinos.keyboard.service
+++ b/data/cn.kylinos.keyboard.service
@@ -1,3 +1,3 @@
[D-BUS Service]
Name=cn.kylinos.keyboard
-Exec=/usr/lib/ukui-interface/ukui-keyboardserver
+Exec=/usr/libexec/ukui-keyboardserver
diff --git a/data/cn.kylinos.marcogeneral.service b/data/cn.kylinos.marcogeneral.service
index a0f3d8c..77cf44c 100755
--- a/data/cn.kylinos.marcogeneral.service
+++ b/data/cn.kylinos.marcogeneral.service
@@ -1,3 +1,3 @@
[D-BUS Service]
Name=cn.kylinos.marcogeneral
-Exec=/usr/lib/ukui-interface/ukui-marcogeneralserver
+Exec=/usr/libexec/ukui-marcogeneralserver
diff --git a/data/cn.kylinos.mouse.service b/data/cn.kylinos.mouse.service
index 570d43f..9ec364a 100755
--- a/data/cn.kylinos.mouse.service
+++ b/data/cn.kylinos.mouse.service
@@ -1,3 +1,3 @@
[D-BUS Service]
Name=cn.kylinos.mouse
-Exec=/usr/lib/ukui-interface/ukui-mouseserver
+Exec=/usr/libexec/ukui-mouseserver
diff --git a/data/cn.kylinos.power.service b/data/cn.kylinos.power.service
index 638ad15..10a373c 100755
--- a/data/cn.kylinos.power.service
+++ b/data/cn.kylinos.power.service
@@ -1,3 +1,3 @@
[D-BUS Service]
Name=cn.kylinos.power
-Exec=/usr/lib/ukui-interface/ukui-powerserver
+Exec=/usr/libexec/ukui-powerserver
diff --git a/data/cn.kylinos.screensaver.service b/data/cn.kylinos.screensaver.service
index dbdf2de..99cf141 100755
--- a/data/cn.kylinos.screensaver.service
+++ b/data/cn.kylinos.screensaver.service
@@ -1,3 +1,3 @@
[D-BUS Service]
Name=cn.kylinos.screensaver
-Exec=/usr/lib/ukui-interface/ukui-screensaverserver
+Exec=/usr/libexec/ukui-screensaverserver
diff --git a/data/cn.kylinos.session.service b/data/cn.kylinos.session.service
index 622f8a0..51bdbe0 100755
--- a/data/cn.kylinos.session.service
+++ b/data/cn.kylinos.session.service
@@ -1,3 +1,3 @@
[D-BUS Service]
Name=cn.kylinos.session
-Exec=/usr/lib/ukui-interface/ukui-sessionserver
+Exec=/usr/libexec/ukui-sessionserver
diff --git a/data/cn.kylinos.touchpad.service b/data/cn.kylinos.touchpad.service
index 3e74e66..50791c2 100755
--- a/data/cn.kylinos.touchpad.service
+++ b/data/cn.kylinos.touchpad.service
@@ -1,3 +1,3 @@
[D-BUS Service]
Name=cn.kylinos.touchpad
-Exec=/usr/lib/ukui-interface/ukui-touchpadserver
+Exec=/usr/libexec/ukui-touchpadserver
diff --git a/data/cn.kylinos.xkbgeneral.service b/data/cn.kylinos.xkbgeneral.service
index a2da7e1..571e6cc 100755
--- a/data/cn.kylinos.xkbgeneral.service
+++ b/data/cn.kylinos.xkbgeneral.service
@@ -1,3 +1,3 @@
[D-BUS Service]
Name=cn.kylinos.xkbgeneral
-Exec=/usr/lib/ukui-interface/ukui-xkbgeneralserver
+Exec=/usr/libexec/ukui-xkbgeneralserver
diff --git a/debian/changelog b/debian/changelog
index 8e97170..d6b5401 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,9 +1,20 @@
-ukui-interface (1.0.0-2) UNRELEASED; urgency=low
+ukui-interface (1.0.1-2) unstable; urgency=medium
+ * Source only upload for migration to testing.
+
+ -- handsome_feng Tue, 02 Nov 2021 14:53:40 +0800
+
+ukui-interface (1.0.1-1) unstable; urgency=medium
+
+ [ handsome_feng ]
+ * New upstream release.
+ * debian: update copyright and watch.
+
+ [ Debian Janior ]
* Set upstream metadata fields: Bug-Database, Bug-Submit.
* Update standards version to 4.5.0, no changes needed.
- -- Debian Janitor Thu, 11 Jun 2020 02:24:40 -0000
+ -- handsome_feng Fri, 29 Oct 2021 17:17:52 +0800
ukui-interface (1.0.0-1) unstable; urgency=medium
diff --git a/debian/control b/debian/control
index 88f3ea4..66b0fde 100644
--- a/debian/control
+++ b/debian/control
@@ -8,7 +8,10 @@ Build-Depends: debhelper-compat (=12),
autoconf,
automake,
libtool,
- qtbase5-dev
+ qtbase5-dev,
+ libgsettings-qt-dev,
+ qttools5-dev-tools,
+ libiniparser-dev
Standards-Version: 4.5.0
Rules-Requires-Root: no
Homepage: https://github.com/ukui/ukui-interface
@@ -18,6 +21,7 @@ Vcs-Git: https://github.com/ukui/ukui-interface.git
Package: libukui-print0
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
+Multi-Arch: same
Description: print module
UKUI interface provides the interface for system configuration
and related libraries.
@@ -27,8 +31,7 @@ Description: print module
Package: libukui-print-dev
Architecture: any
Section: libdevel
-Depends: ${shlibs:Depends},
- ${misc:Depends},
+Depends: ${misc:Depends},
libukui-print0 (= ${binary:Version})
Description: print interface
UKUI interface provides the interface for system configuration
@@ -39,6 +42,7 @@ Description: print interface
Package: libukui-gsettings0
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
+Multi-Arch: same
Description: application settings module
UKUI interface provides the interface for system configuration
and related libraries.
@@ -48,8 +52,7 @@ Description: application settings module
Package: libukui-gsettings-dev
Architecture: any
Section: libdevel
-Depends: ${shlibs:Depends},
- ${misc:Depends},
+Depends: ${misc:Depends},
libukui-gsettings0 (= ${binary:Version})
Description: application settings interface
UKUI interface provides the interface for system configuration
@@ -85,8 +88,7 @@ Description: background settings module
Package: libukui-backgroundclient-dev
Architecture: any
Section: libdevel
-Depends: ${shlibs:Depends},
- ${misc:Depends},
+Depends: ${misc:Depends},
libukui-backgroundclient0 (= ${binary:Version})
Description: background settings interfaces
UKUI interface provides the interface for system configuration
@@ -94,48 +96,6 @@ Description: background settings interfaces
.
The package contains development files for background settings.
-Package: libukui-datesetting0
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}
-Description: date settings module
- UKUI interface provides the interface for system configuration
- and related libraries.
- .
- The package contains date settings libraries.
-
-Package: libukui-datesetting-dev
-Architecture: any
-Section: libdevel
-Depends: ${shlibs:Depends},
- ${misc:Depends},
- libukui-datesetting0 (= ${binary:Version})
-Description: date settings interfaces
- UKUI interface provides the interface for system configuration
- and related libraries.
- .
- The package contains development files for date settings.
-
-Package: libukui-defaultprograms0
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}
-Description: default programs settings module
- UKUI interface provides the interface for system configuration
- and related libraries.
- .
- The package contains default programs settings libraries.
-
-Package: libukui-defaultprograms-dev
-Architecture: any
-Section: libdevel
-Depends: ${shlibs:Depends},
- ${misc:Depends},
- libukui-defaultprograms0 (= ${binary:Version})
-Description: default programs settings interfaces
- UKUI interface provides the interface for system configuration
- and related libraries.
- .
- The package contains development files for default programs settings.
-
Package: ukui-desktopserver
Architecture: any
Depends: ${shlibs:Depends},
@@ -164,8 +124,7 @@ Description: desktop settings module
Package: libukui-desktopclient-dev
Architecture: any
Section: libdevel
-Depends: ${shlibs:Depends},
- ${misc:Depends},
+Depends: ${misc:Depends},
libukui-desktopclient0 (= ${binary:Version})
Description: desktop settings interfaces
UKUI interface provides the interface for system configuration
@@ -201,8 +160,7 @@ Description: font settings module
Package: libukui-fontclient-dev
Architecture: any
Section: libdevel
-Depends: ${shlibs:Depends},
- ${misc:Depends},
+Depends: ${misc:Depends},
libukui-fontclient0 (= ${binary:Version})
Description: font settings interfaces
UKUI interface provides the interface for system configuration
@@ -238,8 +196,7 @@ Description: interface settings module
Package: libukui-interfaceclient-dev
Architecture: any
Section: libdevel
-Depends: ${shlibs:Depends},
- ${misc:Depends},
+Depends: ${misc:Depends},
libukui-interfaceclient0 (= ${binary:Version})
Description: interface settings interfaces
UKUI interface provides the interface for system configuration
@@ -275,8 +232,7 @@ Description: keyboard settings module
Package: libukui-keyboardclient-dev
Architecture: any
Section: libdevel
-Depends: ${shlibs:Depends},
- ${misc:Depends},
+Depends: ${misc:Depends},
libukui-keyboardclient0 (= ${binary:Version})
Description: keyboard settings interfaces
UKUI interface provides the interface for system configuration
@@ -307,8 +263,7 @@ Description: marcogeneral settings module
Package: libukui-marcogeneralclient-dev
Architecture: any
Section: libdevel
-Depends: ${shlibs:Depends},
- ${misc:Depends},
+Depends: ${misc:Depends},
libukui-marcogeneralclient0 (= ${binary:Version})
Description: marcogeneral settings interfaces
UKUI interface provides the interface for system configuration
@@ -339,8 +294,7 @@ Description: mouse settings module
Package: libukui-mouseclient-dev
Architecture: any
Section: libdevel
-Depends: ${shlibs:Depends},
- ${misc:Depends},
+Depends: ${misc:Depends},
libukui-mouseclient0 (= ${binary:Version})
Description: mouse settings interfaces
UKUI interface provides the interface for system configuration
@@ -351,6 +305,7 @@ Description: mouse settings interfaces
Package: libukui-network0
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
+Multi-Arch: same
Description: network settings module
UKUI interface provides the interface for system configuration
and related libraries.
@@ -360,8 +315,7 @@ Description: network settings module
Package: libukui-network-dev
Architecture: any
Section: libdevel
-Depends: ${shlibs:Depends},
- ${misc:Depends},
+Depends: ${misc:Depends},
libukui-network0 (= ${binary:Version})
Description: network settings interfaces
UKUI interface provides the interface for system configuration
@@ -397,8 +351,7 @@ Description: power settings module
Package: libukui-powerclient-dev
Architecture: any
Section: libdevel
-Depends: ${shlibs:Depends},
- ${misc:Depends},
+Depends: ${misc:Depends},
libukui-powerclient0 (= ${binary:Version})
Description: power settings interfaces
UKUI interface provides the interface for system configuration
@@ -429,8 +382,7 @@ Description: screensaver settings module
Package: libukui-screensaverclient-dev
Architecture: any
Section: libdevel
-Depends: ${shlibs:Depends},
- ${misc:Depends},
+Depends: ${misc:Depends},
libukui-screensaverclient0 (= ${binary:Version})
Description: screensaver settings interfaces
UKUI interface provides the interface for system configuration
@@ -461,8 +413,7 @@ Description: session settings module
Package: libukui-sessionclient-dev
Architecture: any
Section: libdevel
-Depends: ${shlibs:Depends},
- ${misc:Depends},
+Depends: ${misc:Depends},
libukui-sessionclient0 (= ${binary:Version})
Description: session settings interfaces
UKUI interface provides the interface for system configuration
@@ -470,48 +421,6 @@ Description: session settings interfaces
.
The package contains development files for session settings.
-Package: libukui-subversion0
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}
-Description: Subversion check module
- UKUI interface provides the interface for system configuration
- and related libraries.
- .
- The package contains Subversion check libraries.
-
-Package: libukui-subversion-dev
-Architecture: any
-Section: libdevel
-Depends: ${shlibs:Depends},
- ${misc:Depends},
- libukui-subversion0 (= ${binary:Version})
-Description: Subversion check interfaces
- UKUI interface provides the interface for system configuration
- and related libraries.
- .
- The package contains development files for Subversion check.
-
-Package: libukui-sysinfo0
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}
-Description: system information gettings module
- UKUI interface provides the interface for system configuration
- and related libraries.
- .
- The package contains system information gettings libraries.
-
-Package: libukui-sysinfo-dev
-Architecture: any
-Section: libdevel
-Depends: ${shlibs:Depends},
- ${misc:Depends},
- libukui-sysinfo0 (= ${binary:Version})
-Description: system information gettings interfaces
- UKUI interface provides the interface for system configuration
- and related libraries.
- .
- The package contains development files for system information gettings.
-
Package: ukui-touchpadserver
Architecture: any
Depends: ${shlibs:Depends},
@@ -540,8 +449,7 @@ Description: touchpad settings module
Package: libukui-touchpadclient-dev
Architecture: any
Section: libdevel
-Depends: ${shlibs:Depends},
- ${misc:Depends},
+Depends: ${misc:Depends},
libukui-touchpadclient0 (= ${binary:Version})
Description: touchpad settings interfaces
UKUI interface provides the interface for system configuration
@@ -552,6 +460,7 @@ Description: touchpad settings interfaces
Package: libukui-usersetting0
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
+Multi-Arch: same
Description: user settings module
UKUI interface provides the interface for system configuration
and related libraries.
@@ -561,8 +470,7 @@ Description: user settings module
Package: libukui-usersetting-dev
Architecture: any
Section: libdevel
-Depends: ${shlibs:Depends},
- ${misc:Depends},
+Depends: ${misc:Depends},
libukui-usersetting0 (= ${binary:Version})
Description: user settings interfaces
UKUI interface provides the interface for system configuration
@@ -579,25 +487,46 @@ Description: xkbgeneral settings service process
.
The package contains xkbgeneral settings service process.
-Package: libukui-xkbgeneralclient0
+Package: libukui-log4qt1
Architecture: any
-Depends: ${shlibs:Depends},
- ${misc:Depends},
- ukui-xkbgeneralserver (= ${binary:Version})
-Description: xkbgeneral settings module
+Depends: ${shlibs:Depends}, ${misc:Depends}, libglib2.0-bin
+Breaks: libukui-log4qt0
+Replaces: libukui-log4qt0
+Description: log4qt module
UKUI interface provides the interface for system configuration
and related libraries.
.
- The package contains xkbgeneral settings libraries.
+ The package contains log4qt libraries.
-Package: libukui-xkbgeneralclient-dev
+Package: libukui-log4qt-dev
Architecture: any
Section: libdevel
-Depends: ${shlibs:Depends},
- ${misc:Depends},
- libukui-xkbgeneralclient0 (= ${binary:Version})
-Description: xkbgeneral settings interfaces
+Depends: ${misc:Depends},
+ libukui-log4qt1 (= ${binary:Version}),
+ libglib2.0-bin
+Description: log4qt interface
+ UKUI interface provides the interface for system configuration
+ and related libraries.
+ .
+ The package contains development files for qt logging.
+
+Package: libukui-common0
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Multi-Arch: same
+Description: common module
+ UKUI interface provides the interface for system configuration
+ and related libraries.
+ .
+ The package contains common libraries.
+
+Package: libukui-common-dev
+Architecture: any
+Section: libdevel
+Depends: ${misc:Depends},
+ libukui-common0 (= ${binary:Version})
+Description: common interface
UKUI interface provides the interface for system configuration
and related libraries.
.
- The package contains development files for xkbgeneral settings.
+ The package contains development files for platform common info.
diff --git a/debian/copyright b/debian/copyright
index 00597c3..7e07100 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -4,14 +4,21 @@ Upstream-Contact: liuhao
Source: https://github.com/ukui/ukui-interface
Files: *
-Copyright: 2019 Tianjin KYLIN Information Technology Co., Ltd.
-License: GPL-3.0+
+Copyright: 2019, Tianjin KYLIN Information Technology Co., Ltd.
+License: GPL-3+
Files: debian/*
-Copyright: 2019 liuhao
-License: GPL-3.0+
+Copyright: 2019, liuhao
+ 2021, handsome_feng
+License: GPL-3+
-License: GPL-3.0+
+Files: src/log4qt/doc/*
+ src/log4qt/tests/*
+ src/log4qt/log4qt/*
+Copyright: 2007 - 2009 Martin Heinrich
+License: Apache-2.0
+
+License: GPL-3+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
@@ -27,3 +34,19 @@ License: GPL-3.0+
.
On Debian systems, the complete text of the GNU General
Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
+
+License: Apache-2.0
+ 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.
+ .
+ On Debian systems, the complete text of the Apache License Version 2.0
+ can be found in `/usr/share/common-licenses/Apache-2.0'.
diff --git a/debian/libukui-backgroundclient-dev.install b/debian/libukui-backgroundclient-dev.install
index 2ce7946..5ef2cec 100644
--- a/debian/libukui-backgroundclient-dev.install
+++ b/debian/libukui-backgroundclient-dev.install
@@ -1,3 +1,4 @@
usr/include/ukuisdk/kylin-background-interface.h
usr/lib/*/libukui-backgroundclient.a
+usr/lib/*/libukui-backgroundclient.la
usr/lib/*/libukui-backgroundclient.so
diff --git a/debian/libukui-common-dev.install b/debian/libukui-common-dev.install
new file mode 100644
index 0000000..92cadbb
--- /dev/null
+++ b/debian/libukui-common-dev.install
@@ -0,0 +1,8 @@
+usr/include/ukuisdk/kylin-com4c.h
+usr/include/ukuisdk/kylin-com4cxx.h
+usr/lib/*/libukui-com4c.a
+usr/lib/*/libukui-com4cxx.a
+usr/lib/*/libukui-com4c.la
+usr/lib/*/libukui-com4cxx.la
+usr/lib/*/libukui-com4c.so
+usr/lib/*/libukui-com4cxx.so
diff --git a/debian/libukui-common0.install b/debian/libukui-common0.install
new file mode 100644
index 0000000..2b2a7ce
--- /dev/null
+++ b/debian/libukui-common0.install
@@ -0,0 +1,2 @@
+usr/lib/*/libukui-com4c.so.*
+usr/lib/*/libukui-com4cxx.so.*
diff --git a/debian/libukui-datesetting-dev.install b/debian/libukui-datesetting-dev.install
deleted file mode 100644
index 5d5057d..0000000
--- a/debian/libukui-datesetting-dev.install
+++ /dev/null
@@ -1,3 +0,0 @@
-usr/include/ukuisdk/kylin-date-interface.h
-usr/lib/*/libukui-datesetting.a
-usr/lib/*/libukui-datesetting.so
diff --git a/debian/libukui-datesetting0.install b/debian/libukui-datesetting0.install
deleted file mode 100644
index 21bc83e..0000000
--- a/debian/libukui-datesetting0.install
+++ /dev/null
@@ -1 +0,0 @@
-usr/lib/*/libukui-datesetting.so.*
diff --git a/debian/libukui-datesetting0.symbols b/debian/libukui-datesetting0.symbols
deleted file mode 100644
index 7b53e0b..0000000
--- a/debian/libukui-datesetting0.symbols
+++ /dev/null
@@ -1,8 +0,0 @@
-libukui-datesetting.so.0 libukui-datesetting0 #MINVER#
-* Build-Depends-Package: libukui-datesetting-dev
- init_timedb@Base 1.0.0
- kylin_date_dt_chgdt@Base 1.0.0
- kylin_date_dt_sethrfmt@Base 1.0.0
- kylin_date_dt_setnetsync@Base 1.0.0
- kylin_date_dt_settz@Base 1.0.0
- timedata@Base 1.0.0
diff --git a/debian/libukui-defaultprograms-dev.install b/debian/libukui-defaultprograms-dev.install
deleted file mode 100644
index fa46493..0000000
--- a/debian/libukui-defaultprograms-dev.install
+++ /dev/null
@@ -1,3 +0,0 @@
-usr/include/ukuisdk/kylin-defaultprograms-interface.h
-usr/lib/*/libukui-defaultprograms.a
-usr/lib/*/libukui-defaultprograms.so
diff --git a/debian/libukui-defaultprograms0.install b/debian/libukui-defaultprograms0.install
deleted file mode 100644
index b67107e..0000000
--- a/debian/libukui-defaultprograms0.install
+++ /dev/null
@@ -1 +0,0 @@
-usr/lib/*/libukui-defaultprograms.so.*
diff --git a/debian/libukui-defaultprograms0.symbols b/debian/libukui-defaultprograms0.symbols
deleted file mode 100644
index 020cf76..0000000
--- a/debian/libukui-defaultprograms0.symbols
+++ /dev/null
@@ -1,14 +0,0 @@
-libukui-defaultprograms.so.0 libukui-defaultprograms0 #MINVER#
-* Build-Depends-Package: libukui-defaultprograms-dev
- kylin_software_defaultprograms_addapptype@Base 1.0.0
- kylin_software_defaultprograms_delapptype@Base 1.0.0
- kylin_software_defaultprograms_getappcontenttype@Base 1.0.0
- kylin_software_defaultprograms_getappidlist@Base 1.0.0
- kylin_software_defaultprograms_getdefaultappid@Base 1.0.0
- kylin_software_defaultprograms_setaudioplayers@Base 1.0.0
- kylin_software_defaultprograms_setdefaultapp@Base 1.0.0
- kylin_software_defaultprograms_setimageviewers@Base 1.0.0
- kylin_software_defaultprograms_setmailreaders@Base 1.0.0
- kylin_software_defaultprograms_settexteditors@Base 1.0.0
- kylin_software_defaultprograms_setvideoplayers@Base 1.0.0
- kylin_software_defaultprograms_setwebbrowsers@Base 1.0.0
diff --git a/debian/libukui-desktopclient-dev.install b/debian/libukui-desktopclient-dev.install
index c3a29df..3fcbe56 100644
--- a/debian/libukui-desktopclient-dev.install
+++ b/debian/libukui-desktopclient-dev.install
@@ -1,3 +1,4 @@
usr/include/ukuisdk/kylin-desktop-interface.h
usr/lib/*/libukui-desktopclient.a
+usr/lib/*/libukui-desktopclient.la
usr/lib/*/libukui-desktopclient.so
diff --git a/debian/libukui-fontclient-dev.install b/debian/libukui-fontclient-dev.install
index 2ed144f..48e0d81 100644
--- a/debian/libukui-fontclient-dev.install
+++ b/debian/libukui-fontclient-dev.install
@@ -1,3 +1,4 @@
usr/include/ukuisdk/kylin-font-interface.h
usr/lib/*/libukui-fontclient.a
+usr/lib/*/libukui-fontclient.la
usr/lib/*/libukui-fontclient.so
diff --git a/debian/libukui-gsettings-dev.install b/debian/libukui-gsettings-dev.install
index 08dec84..ac6498e 100644
--- a/debian/libukui-gsettings-dev.install
+++ b/debian/libukui-gsettings-dev.install
@@ -1,3 +1,4 @@
usr/include/ukuisdk/kylin-gsettings-set.h
usr/lib/*/libukui-gsettings.a
+usr/lib/*/libukui-gsettings.la
usr/lib/*/libukui-gsettings.so
diff --git a/debian/libukui-interfaceclient-dev.install b/debian/libukui-interfaceclient-dev.install
index 4ecacba..03aff39 100644
--- a/debian/libukui-interfaceclient-dev.install
+++ b/debian/libukui-interfaceclient-dev.install
@@ -1,3 +1,4 @@
usr/include/ukuisdk/kylin-interface-interface.h
usr/lib/*/libukui-interfaceclient.a
+usr/lib/*/libukui-interfaceclient.la
usr/lib/*/libukui-interfaceclient.so
diff --git a/debian/libukui-keyboardclient-dev.install b/debian/libukui-keyboardclient-dev.install
index 4a9203c..4003aea 100644
--- a/debian/libukui-keyboardclient-dev.install
+++ b/debian/libukui-keyboardclient-dev.install
@@ -1,3 +1,4 @@
usr/include/ukuisdk/kylin-keyboard-interface.h
usr/lib/*/libukui-keyboardclient.a
+usr/lib/*/libukui-keyboardclient.la
usr/lib/*/libukui-keyboardclient.so
diff --git a/debian/libukui-log4qt-dev.install b/debian/libukui-log4qt-dev.install
new file mode 100644
index 0000000..436cbbd
--- /dev/null
+++ b/debian/libukui-log4qt-dev.install
@@ -0,0 +1,2 @@
+usr/include/ukui-log4qt.h
+usr/lib/libukui-log4qt.so
diff --git a/debian/libukui-log4qt1.install b/debian/libukui-log4qt1.install
new file mode 100644
index 0000000..5d3e9a7
--- /dev/null
+++ b/debian/libukui-log4qt1.install
@@ -0,0 +1,2 @@
+usr/lib/libukui-log4qt.so.*
+usr/share/glib-2.0/schemas/org.ukui.log4qt.gschema.xml
diff --git a/debian/libukui-log4qt1.postinst b/debian/libukui-log4qt1.postinst
new file mode 100644
index 0000000..d370a3f
--- /dev/null
+++ b/debian/libukui-log4qt1.postinst
@@ -0,0 +1,6 @@
+#!/bin/sh
+set -e
+
+glib-compile-schemas /usr/share/glib-2.0/schemas/
+
+#DEBHELPER#
diff --git a/debian/libukui-marcogeneralclient-dev.install b/debian/libukui-marcogeneralclient-dev.install
index 3f1c68a..f578da2 100644
--- a/debian/libukui-marcogeneralclient-dev.install
+++ b/debian/libukui-marcogeneralclient-dev.install
@@ -1,3 +1,4 @@
usr/include/ukuisdk/kylin-marcogeneral-interface.h
usr/lib/*/libukui-marcogeneralclient.a
+usr/lib/*/libukui-marcogeneralclient.la
usr/lib/*/libukui-marcogeneralclient.so
diff --git a/debian/libukui-mouseclient-dev.install b/debian/libukui-mouseclient-dev.install
index cdda61c..d27b0ef 100644
--- a/debian/libukui-mouseclient-dev.install
+++ b/debian/libukui-mouseclient-dev.install
@@ -1,3 +1,4 @@
usr/include/ukuisdk/kylin-mouse-interface.h
usr/lib/*/libukui-mouseclient.a
+usr/lib/*/libukui-mouseclient.la
usr/lib/*/libukui-mouseclient.so
diff --git a/debian/libukui-network-dev.install b/debian/libukui-network-dev.install
index 019c694..d4e9890 100644
--- a/debian/libukui-network-dev.install
+++ b/debian/libukui-network-dev.install
@@ -1,3 +1,4 @@
usr/include/ukuisdk/kylin-network-interface.h
usr/lib/*/libukui-network.a
+usr/lib/*/libukui-network.la
usr/lib/*/libukui-network.so
diff --git a/debian/libukui-powerclient-dev.install b/debian/libukui-powerclient-dev.install
index bc9ec08..f7e4726 100644
--- a/debian/libukui-powerclient-dev.install
+++ b/debian/libukui-powerclient-dev.install
@@ -1,3 +1,4 @@
usr/include/ukuisdk/kylin-power-interface.h
usr/lib/*/libukui-powerclient.a
+usr/lib/*/libukui-powerclient.la
usr/lib/*/libukui-powerclient.so
diff --git a/debian/libukui-print-dev.install b/debian/libukui-print-dev.install
index dba095a..19462df 100644
--- a/debian/libukui-print-dev.install
+++ b/debian/libukui-print-dev.install
@@ -1,3 +1,4 @@
usr/include/ukuisdk/kylin-print.h
usr/lib/*/libukui-print.a
+usr/lib/*/libukui-print.la
usr/lib/*/libukui-print.so
diff --git a/debian/libukui-screensaverclient-dev.install b/debian/libukui-screensaverclient-dev.install
index ca2a445..d5b667d 100644
--- a/debian/libukui-screensaverclient-dev.install
+++ b/debian/libukui-screensaverclient-dev.install
@@ -1,3 +1,4 @@
usr/include/ukuisdk/kylin-screensaver-interface.h
usr/lib/*/libukui-screensaverclient.a
+usr/lib/*/libukui-screensaverclient.la
usr/lib/*/libukui-screensaverclient.so
diff --git a/debian/libukui-sessionclient-dev.install b/debian/libukui-sessionclient-dev.install
index 7613c06..232a76c 100644
--- a/debian/libukui-sessionclient-dev.install
+++ b/debian/libukui-sessionclient-dev.install
@@ -1,3 +1,4 @@
usr/include/ukuisdk/kylin-session-interface.h
usr/lib/*/libukui-sessionclient.a
+usr/lib/*/libukui-sessionclient.la
usr/lib/*/libukui-sessionclient.so
diff --git a/debian/libukui-subversion-dev.install b/debian/libukui-subversion-dev.install
deleted file mode 100644
index fbdb01f..0000000
--- a/debian/libukui-subversion-dev.install
+++ /dev/null
@@ -1,3 +0,0 @@
-usr/include/ukuisdk/kylin-version-interface.h
-usr/lib/*/libukui-subversion.a
-usr/lib/*/libukui-subversion.so
diff --git a/debian/libukui-subversion0.install b/debian/libukui-subversion0.install
deleted file mode 100644
index c1c9b4b..0000000
--- a/debian/libukui-subversion0.install
+++ /dev/null
@@ -1 +0,0 @@
-usr/lib/*/libukui-subversion.so.*
diff --git a/debian/libukui-subversion0.symbols b/debian/libukui-subversion0.symbols
deleted file mode 100644
index 397880f..0000000
--- a/debian/libukui-subversion0.symbols
+++ /dev/null
@@ -1,12 +0,0 @@
-libukui-subversion.so.0 libukui-subversion0 #MINVER#
-* Build-Depends-Package: libukui-subversion-dev
- _Z10searchFilePKc@Base 1.0.0
- _Z6cmpKeyPKc@Base 1.0.0
- _ZN10QByteArrayD1Ev@Base 1.0.0
- _ZN10QByteArrayD2Ev@Base 1.0.0
- _ZN5QListI7QStringED1Ev@Base 1.0.0
- _ZN5QListI7QStringED2Ev@Base 1.0.0
- _ZN7QStringD1Ev@Base 1.0.0
- _ZN7QStringD2Ev@Base 1.0.0
- kylin_os_sysinfo_getchildrroup@Base 1.0.0
- kylin_os_sysinfo_verifysubversion@Base 1.0.0
diff --git a/debian/libukui-sysinfo-dev.install b/debian/libukui-sysinfo-dev.install
deleted file mode 100644
index fd82601..0000000
--- a/debian/libukui-sysinfo-dev.install
+++ /dev/null
@@ -1,3 +0,0 @@
-usr/include/ukuisdk/kylin-sysinfo-interface.h
-usr/lib/*/libukui-sysinfo.a
-usr/lib/*/libukui-sysinfo.so
diff --git a/debian/libukui-sysinfo0.install b/debian/libukui-sysinfo0.install
deleted file mode 100644
index 285ee0a..0000000
--- a/debian/libukui-sysinfo0.install
+++ /dev/null
@@ -1 +0,0 @@
-usr/lib/*/libukui-sysinfo.so.*
diff --git a/debian/libukui-sysinfo0.symbols b/debian/libukui-sysinfo0.symbols
deleted file mode 100644
index 7784c06..0000000
--- a/debian/libukui-sysinfo0.symbols
+++ /dev/null
@@ -1,7 +0,0 @@
-libukui-sysinfo.so.0 libukui-sysinfo0 #MINVER#
-* Build-Depends-Package: libukui-sysinfo-dev
- kylin_os_sysinfo_machine@Base 1.0.0
- kylin_os_sysinfo_nodename@Base 1.0.0
- kylin_os_sysinfo_release@Base 1.0.0
- kylin_os_sysinfo_sysname@Base 1.0.0
- kylin_os_sysinfo_version@Base 1.0.0
diff --git a/debian/libukui-touchpadclient-dev.install b/debian/libukui-touchpadclient-dev.install
index 7f0ecd9..4da0d7d 100644
--- a/debian/libukui-touchpadclient-dev.install
+++ b/debian/libukui-touchpadclient-dev.install
@@ -1,3 +1,4 @@
usr/include/ukuisdk/kylin-touchpad-interface.h
usr/lib/*/libukui-touchpadclient.a
+usr/lib/*/libukui-touchpadclient.la
usr/lib/*/libukui-touchpadclient.so
diff --git a/debian/libukui-usersetting-dev.install b/debian/libukui-usersetting-dev.install
index 14913df..17473c3 100644
--- a/debian/libukui-usersetting-dev.install
+++ b/debian/libukui-usersetting-dev.install
@@ -1,3 +1,4 @@
usr/include/ukuisdk/kylin-user-interface.h
usr/lib/*/libukui-usersetting.a
+usr/lib/*/libukui-usersetting.la
usr/lib/*/libukui-usersetting.so
diff --git a/debian/libukui-xkbgeneralclient-dev.install b/debian/libukui-xkbgeneralclient-dev.install
deleted file mode 100644
index 24951c1..0000000
--- a/debian/libukui-xkbgeneralclient-dev.install
+++ /dev/null
@@ -1,3 +0,0 @@
-usr/include/ukuisdk/kylin-xkbgeneral-interface.h
-usr/lib/*/libukui-xkbgeneralclient.a
-usr/lib/*/libukui-xkbgeneralclient.so
diff --git a/debian/libukui-xkbgeneralclient0.install b/debian/libukui-xkbgeneralclient0.install
deleted file mode 100644
index 1fb506c..0000000
--- a/debian/libukui-xkbgeneralclient0.install
+++ /dev/null
@@ -1 +0,0 @@
-usr/lib/*/libukui-xkbgeneralclient.so.*
diff --git a/debian/libukui-xkbgeneralclient0.symbols b/debian/libukui-xkbgeneralclient0.symbols
deleted file mode 100644
index e58583f..0000000
--- a/debian/libukui-xkbgeneralclient0.symbols
+++ /dev/null
@@ -1,28 +0,0 @@
-libukui-xkbgeneralclient.so.0 libukui-xkbgeneralclient0 #MINVER#
-* Build-Depends-Package: libukui-xkbgeneralclient-dev
- DeInitDBusXkbgeneral@Base 1.0.0
- InitDBusXkbgeneral@Base 1.0.0
- kylin_hardware_keyboard_get_groupperwindow@Base 1.0.0
- kylin_hardware_keyboard_set_groupperwindow@Base 1.0.0
- run@Base 1.0.0
- thread_create@Base 1.0.0
- xkbgeneral_call_get_bool_value@Base 1.0.0
- xkbgeneral_call_get_bool_value_finish@Base 1.0.0
- xkbgeneral_call_get_bool_value_sync@Base 1.0.0
- xkbgeneral_call_transfer_bool_value@Base 1.0.0
- xkbgeneral_call_transfer_bool_value_finish@Base 1.0.0
- xkbgeneral_call_transfer_bool_value_sync@Base 1.0.0
- xkbgeneral_complete_get_bool_value@Base 1.0.0
- xkbgeneral_complete_transfer_bool_value@Base 1.0.0
- xkbgeneral_get_type@Base 1.0.0
- xkbgeneral_interface_info@Base 1.0.0
- xkbgeneral_override_properties@Base 1.0.0
- xkbgeneral_proxy_get_type@Base 1.0.0
- xkbgeneral_proxy_new@Base 1.0.0
- xkbgeneral_proxy_new_finish@Base 1.0.0
- xkbgeneral_proxy_new_for_bus@Base 1.0.0
- xkbgeneral_proxy_new_for_bus_finish@Base 1.0.0
- xkbgeneral_proxy_new_for_bus_sync@Base 1.0.0
- xkbgeneral_proxy_new_sync@Base 1.0.0
- xkbgeneral_skeleton_get_type@Base 1.0.0
- xkbgeneral_skeleton_new@Base 1.0.0
diff --git a/debian/rules b/debian/rules
index b251c92..c32bfa0 100755
--- a/debian/rules
+++ b/debian/rules
@@ -6,12 +6,38 @@ include /usr/share/dpkg/default.mk
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic
#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
-
+QT_INSTALL_DIR:=$(shell pwd)/debian/tmp/
+LOG4QT_BUILD_DIR:=$(shell pwd)/src/log4qt/build
%:
dh $@
+override_dh_auto_clean:
+ dh_auto_clean
+ rm -fr $(LOG4QT_BUILD_DIR)
+
+override_dh_install:
+ mkdir -p $(QT_INSTALL_DIR) && \
+ make install INSTALL_ROOT=$(QT_INSTALL_DIR) -C $(LOG4QT_BUILD_DIR)
+ dh_install
+ sed -i "/dependency_libs/ s/'.*'/''/" `find . -name '*.la'`
+
override_dh_auto_configure:
./autogen.sh
dh_auto_configure -- \
- --includedir=/usr/include/ukuisdk --bindir=/usr/lib/ukui-interface
+ --includedir=/usr/include/ukuisdk --bindir=/usr/libexec
+
+override_dh_auto_build:
+ dh_auto_build
+ mkdir -p $(LOG4QT_BUILD_DIR)
+ cd $(LOG4QT_BUILD_DIR) && qmake -makefile "QMAKE_CFLAGS_RELEASE=-g -O2 -fdebug-prefix-map=$(LOG4QT_BUILD_DIR)=. \
+ -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2" \
+ "QMAKE_CFLAGS_DEBUG=-g -O2 -fdebug-prefix-map=$(LOG4QT_BUILD_DIR)=. -fstack-protector-strong \
+ -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2" \
+ "QMAKE_CXXFLAGS_RELEASE=-g -O2 -fdebug-prefix-map=$(LOG4QT_BUILD_DIR)=. -fstack-protector-strong \
+ -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2" \
+ "QMAKE_CXXFLAGS_DEBUG=-g -O2 -fdebug-prefix-map=$(LOG4QT_BUILD_DIR)=. \
+ -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2" \
+ "QMAKE_LFLAGS_RELEASE=-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now" \
+ "QMAKE_LFLAGS_DEBUG=-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now" QMAKE_STRIP=: PREFIX=/usr ..
+ make -C $(LOG4QT_BUILD_DIR)
diff --git a/debian/ukui-backgroundserver.install b/debian/ukui-backgroundserver.install
index 5fb4052..eb516be 100644
--- a/debian/ukui-backgroundserver.install
+++ b/debian/ukui-backgroundserver.install
@@ -1,2 +1,2 @@
-usr/lib/ukui-interface/ukui-backgroundserver
+usr/libexec/ukui-backgroundserver
usr/share/dbus-1/services/cn.kylinos.background.service
diff --git a/debian/ukui-desktopserver.install b/debian/ukui-desktopserver.install
index 5751421..c4db8fa 100644
--- a/debian/ukui-desktopserver.install
+++ b/debian/ukui-desktopserver.install
@@ -1,2 +1,2 @@
-usr/lib/ukui-interface/ukui-desktopserver
+usr/libexec/ukui-desktopserver
usr/share/dbus-1/services/cn.kylinos.desktop.service
diff --git a/debian/ukui-fontserver.install b/debian/ukui-fontserver.install
index c7c12bf..89e2666 100644
--- a/debian/ukui-fontserver.install
+++ b/debian/ukui-fontserver.install
@@ -1,2 +1,2 @@
-usr/lib/ukui-interface/ukui-fontserver
+usr/libexec/ukui-fontserver
usr/share/dbus-1/services/cn.kylinos.font.service
diff --git a/debian/ukui-interfaceserver.install b/debian/ukui-interfaceserver.install
index dbc0c2c..c3852b1 100644
--- a/debian/ukui-interfaceserver.install
+++ b/debian/ukui-interfaceserver.install
@@ -1,2 +1,2 @@
-usr/lib/ukui-interface/ukui-interfaceserver
+usr/libexec/ukui-interfaceserver
usr/share/dbus-1/services/cn.kylinos.interface.service
diff --git a/debian/ukui-keyboardserver.install b/debian/ukui-keyboardserver.install
index 436f114..3eec720 100644
--- a/debian/ukui-keyboardserver.install
+++ b/debian/ukui-keyboardserver.install
@@ -1,2 +1,2 @@
-usr/lib/ukui-interface/ukui-keyboardserver
+usr/libexec/ukui-keyboardserver
usr/share/dbus-1/services/cn.kylinos.keyboard.service
diff --git a/debian/ukui-marcogeneralserver.install b/debian/ukui-marcogeneralserver.install
index 123d8b1..434e477 100644
--- a/debian/ukui-marcogeneralserver.install
+++ b/debian/ukui-marcogeneralserver.install
@@ -1,2 +1,2 @@
-usr/lib/ukui-interface/ukui-marcogeneralserver
+usr/libexec/ukui-marcogeneralserver
usr/share/dbus-1/services/cn.kylinos.marcogeneral.service
diff --git a/debian/ukui-mouseserver.install b/debian/ukui-mouseserver.install
index 049cbf0..393a548 100644
--- a/debian/ukui-mouseserver.install
+++ b/debian/ukui-mouseserver.install
@@ -1,2 +1,2 @@
-usr/lib/ukui-interface/ukui-mouseserver
+usr/libexec/ukui-mouseserver
usr/share/dbus-1/services/cn.kylinos.mouse.service
diff --git a/debian/ukui-powerserver.install b/debian/ukui-powerserver.install
index c4ce14b..c9143aa 100644
--- a/debian/ukui-powerserver.install
+++ b/debian/ukui-powerserver.install
@@ -1,2 +1,2 @@
-usr/lib/ukui-interface/ukui-powerserver
+usr/libexec/ukui-powerserver
usr/share/dbus-1/services/cn.kylinos.power.service
diff --git a/debian/ukui-screensaverserver.install b/debian/ukui-screensaverserver.install
index 4e7647e..aabc00c 100644
--- a/debian/ukui-screensaverserver.install
+++ b/debian/ukui-screensaverserver.install
@@ -1,2 +1,2 @@
-usr/lib/ukui-interface/ukui-screensaverserver
+usr/libexec/ukui-screensaverserver
usr/share/dbus-1/services/cn.kylinos.screensaver.service
diff --git a/debian/ukui-sessionserver.install b/debian/ukui-sessionserver.install
index 236d475..40be13b 100644
--- a/debian/ukui-sessionserver.install
+++ b/debian/ukui-sessionserver.install
@@ -1,2 +1,2 @@
-usr/lib/ukui-interface/ukui-sessionserver
+usr/libexec/ukui-sessionserver
usr/share/dbus-1/services/cn.kylinos.session.service
diff --git a/debian/ukui-touchpadserver.install b/debian/ukui-touchpadserver.install
index 612b8d4..8c5588c 100644
--- a/debian/ukui-touchpadserver.install
+++ b/debian/ukui-touchpadserver.install
@@ -1,2 +1,2 @@
-usr/lib/ukui-interface/ukui-touchpadserver
+usr/libexec/ukui-touchpadserver
usr/share/dbus-1/services/cn.kylinos.touchpad.service
diff --git a/debian/ukui-xkbgeneralserver.install b/debian/ukui-xkbgeneralserver.install
index df2dd09..0e08e5a 100644
--- a/debian/ukui-xkbgeneralserver.install
+++ b/debian/ukui-xkbgeneralserver.install
@@ -1,2 +1,2 @@
-usr/lib/ukui-interface/ukui-xkbgeneralserver
+usr/libexec/ukui-xkbgeneralserver
usr/share/dbus-1/services/cn.kylinos.xkbgeneral.service
diff --git a/debian/upstream/metadata b/debian/upstream/metadata
index 5840756..a71fcf6 100644
--- a/debian/upstream/metadata
+++ b/debian/upstream/metadata
@@ -1,3 +1,2 @@
----
Bug-Database: https://github.com/ukui/ukui-interface/issues
Bug-Submit: https://github.com/ukui/ukui-interface/issues/new
diff --git a/debian/watch b/debian/watch
index a0d6f97..dd56e12 100644
--- a/debian/watch
+++ b/debian/watch
@@ -1,3 +1,2 @@
version=4
-opts=filenamemangle=s/.+\/v?(\d\S+)\.tar\.gz/ukui-interface-$1\.tar\.gz/ \
- https://github.com/ukui/ukui-interface/releases .*/v?(\d\S+)\.tar\.gz
+https://github.com/ukui/ukui-interface/releases .*/ukui-interface_(\d\S+)\.orig\.tar\.gz
diff --git a/src/Makefile.am b/src/Makefile.am
index dd953a0..089176d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,5 +1,5 @@
NULL =
-SUBDIRS = accounts common date hardware language network os \
- other personal security software updates \
+SUBDIRS = accounts common hardware language network \
+ other personal security updates \
$(NULL)
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index fe913d5..3a09c4a 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -1,10 +1,42 @@
#Generata binary file
-lib_LTLIBRARIES = libukui-print.la libukui-gsettings.la
+lib_LTLIBRARIES = libukui-print.la libukui-gsettings.la libukui-com4c.la libukui-com4cxx.la
#gcc -wall: displays all the errors and warning information when compiling
#gcc -g: add the debugging code when compiling
COMM_CFS = -Wall -g
+#Add the dependent source file for libukui-com4c.la
+libukui_com4c_la_SOURCES = kylin-com4c.c \
+ kylin-ini.c \
+ $(NULL)
+
+#Additional C compiler flags
+libukui_com4c_la_CFLAGS= $(COMM_CFS) \
+ -liniparser \
+ $(NULL)
+
+#Additional link objects
+libukui_com4c_la_LDFLAGS= \
+ $(NULL)
+
+#Add the dependent source file for libukui-com4cxx.la
+libukui_com4cxx_la_SOURCES = kylin-com4cxx.cpp \
+ kylin-ini.c \
+ $(NULL)
+
+#Additional CXX compiler flags
+libukui_com4cxx_la_CXXFLAGS= $(COMM_CFS) \
+ -liniparser \
+ $(NULL)
+
+#Additional C compiler flags
+libukui_com4cxx_la_CFLAGS= $(COMM_CFS) \
+ $(NULL)
+
+#Additional link objects
+libukui_com4cxx_la_LDFLAGS= \
+ $(NULL)
+
#Add the dependent source file for libukui-print.la
libukui_print_la_SOURCES = kylin-print.c \
$(NULL)
@@ -15,6 +47,8 @@ libukui_gsettings_la_SOURCES = kylin-gsettings-set.c \
#The header files that need to be installed
include_HEADERS= \
+ kylin-com4c.h \
+ kylin-com4cxx.h \
kylin-print.h \
kylin-gsettings-set.h \
$(NULL)
diff --git a/src/common/kylin-com4c.c b/src/common/kylin-com4c.c
new file mode 100644
index 0000000..ef744c2
--- /dev/null
+++ b/src/common/kylin-com4c.c
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+#include
+#include
+#include
+#include
+
+#include "kylin-ini.h"
+
+#define LSB_RELEASE_FILE "/etc/lsb-release" /* lsb-release文件路径 */
+#define OS_RELEASE_FILE "/etc/os-release" /* os-release文件路径 */
+#define KYINFO_FILE "/etc/.kyinfo" /* kyinfo文件路径 */
+#define CPUINFO_FILE "/proc/cpuinfo" /* cpuinfo文件路径 */
+#define RELEASEFILE_LINE_MAX 256 /* 最大解析行行数 */
+#define RELEASEFILE_LINE_MAX_LEN 256 /* 最大解析行长度 */
+#define RELEASEFILE_KEY_MAX_LEN 128 /* 最大key长度 */
+#define RELEASEFILE_VALUE_MAX_LEN 256 /* 最大value长度 预留'\0', '='*/
+#define RELEASEFILE_SPLIT_EQUAL '=' /* key和value的分隔符 */
+#define RELEASEFILE_SPLIT_COLON ':' /* key和value的分隔符 */
+#define PROJECT_CODENAME "PROJECT_CODENAME"
+#define CPUINFO_MODELNAME "model name"
+
+// 根据key获取value,成功返回 >0 否则 返回 <= 0
+static int file_get_keyvalue(const char *path, const char *key, char *value, int value_max_len, const char chSplit)
+{
+ if (path == NULL || key == NULL || value == NULL || value_max_len <= 0) {
+ return -1;
+ }
+ int ret = 0;
+ int cnt = 0;
+ int key_len = 0;
+ int line_len = 0;
+ int value_len = 0;
+ FILE *fp = NULL;
+ char line_buf[RELEASEFILE_LINE_MAX_LEN] = {0};
+
+ /* 合法性判断 */
+ if (NULL == path || NULL == key || NULL == value || 0 >= value_max_len) {
+ return -1;
+ }
+
+ key_len = strlen(key);
+ if (0 >= key_len || RELEASEFILE_KEY_MAX_LEN < key_len) {
+ return -2;
+ }
+
+ if (F_OK != access(path, F_OK)) {
+ return -3;
+ }
+
+ /* 打开文件 */
+ fp = fopen(path, "r");
+ if (NULL == fp) {
+ return -4;
+ }
+
+ /* 遍历行,匹配Key */
+ while(NULL != fgets(line_buf, RELEASEFILE_LINE_MAX_LEN-1, fp)) {
+ line_len = strlen(line_buf);
+ if (line_len > key_len) {
+ /* 找到key */
+ //找到非空格的首字符
+ char *pStart = line_buf;
+ int nSplitIndex = 0;
+ while(pStart != (line_buf+line_len) && isspace(*pStart)) {
+ ++pStart; ++nSplitIndex;
+ }
+ if (0 == strncmp(pStart, key, key_len)) {
+ pStart = pStart + key_len;
+ nSplitIndex = nSplitIndex + key_len;
+ //跳过空格字符
+ while(pStart != (line_buf+line_len) && isspace(*pStart)) {
+ ++pStart; ++nSplitIndex;
+ }
+ if (pStart != (line_buf+line_len) && *pStart == chSplit) {
+ ret = 1;
+ key_len = nSplitIndex;
+ break;
+ }
+ }
+ }
+ memset(line_buf, 0, sizeof(line_buf));
+
+ /* 最大查找行限制 */
+ cnt++;
+ if (RELEASEFILE_LINE_MAX < cnt) {
+ break;
+ }
+ }
+
+ /* 关闭文件 */
+ fclose(fp);
+ fp = NULL;
+
+ /* 找到key,返回value */
+ if (1 == ret) {
+ value_len = line_len - key_len - 1;
+ if (0 < value_len) {
+ if (value_len > value_max_len) {
+ value_len = value_max_len;
+ }
+ /* 拷贝value */
+ snprintf(value, value_max_len, "%s", &line_buf[key_len + 1]);
+ value[value_len] = '\0';
+
+ /* 去掉结尾的换行符 */
+ strstrip(value, 1);
+ } else {
+ value[0] = '\0';
+ }
+ }
+ return ret;
+}
+
+/**
+ * @fn kdk_get_xdgsessiontype
+ * @brief 获取区分x11与wayland的环境变量值
+ * @retval char* !NULL 成功 否则失败
+ */
+char* kdk_get_xdgsessiontype()
+{
+ return getenv("XDG_SESSION_TYPE");
+}
+
+int kdk_get_lsbrelease(const char *key, char *value, int value_max_len)
+{
+ int nRet = -1;
+ if (NULL == key || NULL == value || 0 >= value_max_len)
+ return nRet;
+ dictionary *iniHandle = iniparser_load(LSB_RELEASE_FILE);
+ if (iniHandle) {
+ char sessionKey[256] = {0};
+ snprintf(sessionKey, 256, ":%s", key);
+ const char *tempValue = iniparser_getstring(iniHandle, sessionKey, "");
+ snprintf(value, value_max_len, "%s", tempValue);
+ iniparser_freedict(iniHandle);
+ iniHandle = NULL;
+ nRet = strlen(value);
+ }
+ return nRet;
+}
+
+int kdk_get_osrelease(const char *key, char *value, int value_max_len)
+{
+ int nRet = -1;
+ if (NULL == key || NULL == value || 0 >= value_max_len)
+ return nRet;
+ dictionary *iniHandle = iniparser_load(OS_RELEASE_FILE);
+ if (iniHandle) {
+ char sessionKey[256] = {0};
+ snprintf(sessionKey, 256, ":%s", key);
+ const char *tempValue = iniparser_getstring(iniHandle, sessionKey, "");
+ snprintf(value, value_max_len, "%s", tempValue);
+ iniparser_freedict(iniHandle);
+ iniHandle = NULL;
+ nRet = strlen(value);
+ }
+ return nRet;
+}
+
+int kdk_get_prjcodename(char *value, int value_max_len)
+{
+ int nResult = kdk_get_lsbrelease(PROJECT_CODENAME, value, value_max_len);
+ if (nResult <= 0) {
+ nResult = kdk_get_osrelease(PROJECT_CODENAME, value, value_max_len);
+ }
+ return nResult;
+}
+
+int kdk_get_kyinfo(const char *session, const char *key, char *value, int value_max_len)
+{
+ int nRet = -1;
+ if (NULL == session || NULL == key || NULL == value || 0 >= value_max_len)
+ return nRet;
+ dictionary *iniHandle = iniparser_load(KYINFO_FILE);
+ if (iniHandle) {
+ char sessionKey[256] = {0};
+ snprintf(sessionKey, 256, "%s:%s", session, key);
+ const char *tempValue = iniparser_getstring(iniHandle, sessionKey, "");
+ snprintf(value, value_max_len, "%s", tempValue);
+ iniparser_freedict(iniHandle);
+ iniHandle = NULL;
+ nRet = strlen(value);
+ }
+ return nRet;
+}
+
+int kdk_get_cpumodelname(char *modelName, int max_len)
+{
+ return file_get_keyvalue(CPUINFO_FILE, CPUINFO_MODELNAME, modelName, max_len, RELEASEFILE_SPLIT_COLON);
+}
+
+int kdk_get_spechdplatform(char *platformName, int max_len)
+{
+ if (platformName == NULL || max_len <= 0)
+ return -1;
+ char strDefault[128] = "default";
+ int validLen = strlen(strDefault);
+ validLen = validLen > max_len ? max_len : validLen;
+ snprintf(platformName, max_len, "%s", strDefault);
+ return validLen;
+}
\ No newline at end of file
diff --git a/src/common/kylin-com4c.h b/src/common/kylin-com4c.h
new file mode 100644
index 0000000..f890120
--- /dev/null
+++ b/src/common/kylin-com4c.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @fn kdk_get_lsbrelease
+ * @brief 根据lsbrelease信息的键获取值
+ * @param[in] key lsbrelease信息的键
+ * @param[out] value lsbrelease信息的值
+ * @param[in] value_max_len 值缓存区的大小
+ * @retval int > 0 成功 否则失败
+ */
+int kdk_get_lsbrelease(const char *key, char *value, int value_max_len);
+
+/**
+ * @fn kdk_get_osrelease
+ * @brief 根据osrelease信息的键获取值
+ * @param[in] key osrelease信息的键
+ * @param[out] value osrelease信息的值
+ * @param[in] value_max_len 值缓存区的大小
+ * @retval int > 0 成功 否则失败
+ */
+int kdk_get_osrelease(const char *key, char *value, int value_max_len);
+
+/**
+ * @fn kdk_get_kyinfo
+ * @brief 根据kyinfo的键获取值
+ * @param[in] session kyinfo的session值
+ * @param[in] key kyinfo的键
+ * @param[out] value kyinfo的值
+ * @param[in] value_max_len 值缓存区的大小
+ * @retval int >= 0 成功 否则失败
+ */
+int kdk_get_kyinfo(const char *session, const char *key, char *value, int value_max_len);
+
+/**
+ * @fn kdk_get_prjcodename
+ * @brief 根据PROJECT_CODENAME字段的值
+ * @param[out] value PROJECT_CODENAME字段的值
+ * @param[in] value_max_len 值缓存区的大小
+ * @retval int > 0 成功 否则失败
+ */
+int kdk_get_prjcodename(char *value, int value_max_len);
+
+/**
+ * @fn kdk_get_cpumodelname
+ * @brief 获取CPU型号
+ * @param[out] modelName CPU型号信息
+ * @param[in] max_len CPU型号缓存区的大小
+ * @retval int > 0 成功 否则失败
+ */
+int kdk_get_cpumodelname(char *modelName, int max_len);
+
+/**
+ * @fn kdk_get_spechdplatform
+ * @brief 获取特定硬件平台信息
+ * @param[out] platformName 特定硬件平台信息
+ * @param[in] max_len 特定硬件平台缓存区的大小
+ * @retval int > 0 成功 否则失败
+ */
+int kdk_get_spechdplatform(char *platformName, int max_len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __KYLINCOMM4C_H__
\ No newline at end of file
diff --git a/src/common/kylin-com4cxx.cpp b/src/common/kylin-com4cxx.cpp
new file mode 100644
index 0000000..6cbe950
--- /dev/null
+++ b/src/common/kylin-com4cxx.cpp
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+#include
+#include
+#include
+#include
+
+#include "kylin-ini.h"
+
+#define LSB_RELEASE_FILE "/etc/lsb-release" /* lsb-release文件路径 */
+#define OS_RELEASE_FILE "/etc/os-release" /* os-release文件路径 */
+#define KYINFO_FILE "/etc/.kyinfo" /* kyinfo文件路径 */
+#define CPUINFO_FILE "/proc/cpuinfo" /* cpuinfo文件路径 */
+#define RELEASEFILE_LINE_MAX 256 /* 最大解析行行数 */
+#define RELEASEFILE_LINE_MAX_LEN 256 /* 最大解析行长度 */
+#define RELEASEFILE_KEY_MAX_LEN 128 /* 最大key长度 */
+#define RELEASEFILE_VALUE_MAX_LEN 256 /* 最大value长度 预留'\0', '='*/
+#define RELEASEFILE_SPLIT_EQUAL '=' /* key和value的分隔符 */
+#define RELEASEFILE_SPLIT_COLON ':' /* key和value的分隔符 */
+#define PROJECT_CODENAME "PROJECT_CODENAME"
+#define CPUINFO_MODELNAME "model name"
+
+// 根据key获取value,成功返回 >0 否则 返回 <= 0
+static int file_get_keyvalue(const char *path, const char *key, char *value, int value_max_len, const char chSplit)
+{
+ if (path == NULL || key == NULL || value == NULL || value_max_len <= 0) {
+ return -1;
+ }
+ int ret = 0;
+ int cnt = 0;
+ int key_len = 0;
+ int line_len = 0;
+ int value_len = 0;
+ FILE *fp = NULL;
+ char line_buf[RELEASEFILE_LINE_MAX_LEN] = {0};
+
+ /* 合法性判断 */
+ if (NULL == path || NULL == key || NULL == value || 0 >= value_max_len) {
+ return -1;
+ }
+
+ key_len = strlen(key);
+ if (0 >= key_len || RELEASEFILE_KEY_MAX_LEN < key_len) {
+ return -2;
+ }
+
+ if (F_OK != access(path, F_OK)) {
+ return -3;
+ }
+
+ /* 打开文件 */
+ fp = fopen(path, "r");
+ if (NULL == fp) {
+ return -4;
+ }
+
+ /* 遍历行,匹配Key */
+ while(NULL != fgets(line_buf, RELEASEFILE_LINE_MAX_LEN-1, fp)) {
+ line_len = strlen(line_buf);
+ if (line_len > key_len) {
+ /* 找到key */
+ //找到非空格的首字符
+ char *pStart = line_buf;
+ int nSplitIndex = 0;
+ while(pStart != (line_buf+line_len) && isspace(*pStart)) {
+ ++pStart; ++nSplitIndex;
+ }
+ if (0 == strncmp(pStart, key, key_len)) {
+ pStart = pStart + key_len;
+ nSplitIndex = nSplitIndex + key_len;
+ //跳过空格字符
+ while(pStart != (line_buf+line_len) && isspace(*pStart)) {
+ ++pStart; ++nSplitIndex;
+ }
+ if (pStart != (line_buf+line_len) && *pStart == chSplit) {
+ ret = 1;
+ key_len = nSplitIndex;
+ break;
+ }
+ }
+ }
+ memset(line_buf, 0, sizeof(line_buf));
+
+ /* 最大查找行限制 */
+ cnt++;
+ if (RELEASEFILE_LINE_MAX < cnt) {
+ break;
+ }
+ }
+
+ /* 关闭文件 */
+ fclose(fp);
+ fp = NULL;
+
+ /* 找到key,返回value */
+ if (1 == ret) {
+ value_len = line_len - key_len - 1;
+ if (0 < value_len) {
+ if (value_len > value_max_len) {
+ value_len = value_max_len;
+ }
+ /* 拷贝value */
+ snprintf(value, value_max_len, "%s", &line_buf[key_len + 1]);
+ value[value_len] = '\0';
+
+ /* 去掉结尾的换行符 */
+ strstrip(value, 1);
+ } else {
+ value[0] = '\0';
+ }
+ }
+ return ret;
+}
+
+/**
+ * @fn KDKGetXdgSessionType
+ * @brief 获取区分x11与wayland的环境变量值
+ * @param None 无参
+ * @retval string xdg会话类型字符串,empty 失败,否则成功
+ */
+string KDKGetXdgSessionType()
+{
+ char *strSessionType = getenv("XDG_SESSION_TYPE");
+ if (!strSessionType) {
+ return "";
+ }
+ return string(strSessionType);
+}
+
+string KDKGetLSBRelease(const string key)
+{
+ if (key.empty()) {
+ return "";
+ }
+ dictionary *iniHandle = iniparser_load(LSB_RELEASE_FILE);
+ if (iniHandle) {
+ string sessionKey = ":"+key;
+ string strValue = "";
+ strValue = iniparser_getstring(iniHandle, sessionKey.c_str(), "");
+ iniparser_freedict(iniHandle);
+ iniHandle = NULL;
+ return strValue;
+ }
+ return "";
+}
+
+string KDKGetOSRelease(const string key)
+{
+ if (key.empty()) {
+ return "";
+ }
+ dictionary *iniHandle = iniparser_load(OS_RELEASE_FILE);
+ if (iniHandle) {
+ string sessionKey = ":"+key;
+ string strValue = "";
+ strValue = iniparser_getstring(iniHandle, sessionKey.c_str(), "");
+ iniparser_freedict(iniHandle);
+ iniHandle = NULL;
+ return strValue;
+ }
+ return "";
+}
+
+string KDKGetPrjCodeName()
+{
+ string strValue = KDKGetLSBRelease(PROJECT_CODENAME);
+ if (strValue.empty()) {
+ strValue = KDKGetOSRelease(PROJECT_CODENAME);
+ }
+ return strValue;
+}
+
+string KDKGetKYInfo(const string session, const string key)
+{
+ if (session.empty() || key.empty()) {
+ return "";
+ }
+ dictionary *iniHandle = iniparser_load(KYINFO_FILE);
+ if (iniHandle) {
+ string sessionKey = session+":"+key;
+ string strValue = "";
+ strValue = iniparser_getstring(iniHandle, sessionKey.c_str(), "");
+ iniparser_freedict(iniHandle);
+ iniHandle = NULL;
+ return strValue;
+ }
+ return "";
+}
+
+string KDKGetCpuModelName()
+{
+ char strValue[256] = {0};
+ int nRet = file_get_keyvalue(CPUINFO_FILE, CPUINFO_MODELNAME, strValue, 256, RELEASEFILE_SPLIT_COLON);
+ if (nRet > 0) {
+ return string(strValue);
+ } else {
+ return "";
+ }
+}
+
+string KDKGetSpecHDPlatform()
+{
+ string strDefaultValue = "default";
+ return strDefaultValue;
+}
\ No newline at end of file
diff --git a/src/common/kylin-com4cxx.h b/src/common/kylin-com4cxx.h
new file mode 100644
index 0000000..c3ac8f3
--- /dev/null
+++ b/src/common/kylin-com4cxx.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+using namespace std;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @fn KDKGetLsbRelease
+ * @brief 根据lsbrelease信息的键获取值
+ * @param[in] key lsbrelease信息的键
+ * @param[out] value lsbrelease信息的值
+ * @param[in] value_max_len 值缓存区的大小
+ * @retval string lsbrelease信息的值,empty 失败,否则成功
+ */
+string KDKGetLSBRelease(const string key);
+
+/**
+ * @fn KDKGetOSRelease
+ * @brief 根据osrelease信息的键获取值
+ * @param[in] key osrelease信息的键
+ * @retval string osrelease信息的值,empty 失败,否则成功
+ */
+string KDKGetOSRelease(const string key);
+
+/**
+ * @fn KDKGetKYInfo
+ * @brief 根据kyinfo的键获取值
+ * @param[in] session kyinfo的session值
+ * @param[in] key kyinfo的键
+ * @retval string kyinfo信息的键值,empty 失败,否则成功
+ */
+string KDKGetKYInfo(const string session, const string key);
+
+/**
+ * @fn KDKGetPrjCodeName
+ * @brief 根据PROJECT_CODENAME字段的值
+ * @param None 无参
+ * @retval string PROJECT_CODENAME字段的值,empty 失败,否则成功
+ */
+string KDKGetPrjCodeName();
+
+/**
+ * @fn KDKGetCpuModelName
+ * @brief 获取CPU型号
+ * @param None 无参
+ * @retval string CPU型号信息,empty 失败,否则成功
+ */
+string KDKGetCpuModelName();
+
+/**
+ * @fn KDKGetSpecHDPlatform
+ * @brief 获取特定硬件平台信息
+ * @param None 无参
+ * @retval string 特定硬件平台信息,empty 失败,否则成功
+ */
+string KDKGetSpecHDPlatform();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __KYLINCOMM4C_H__
\ No newline at end of file
diff --git a/src/common/kylin-ini.c b/src/common/kylin-ini.c
new file mode 100644
index 0000000..3965919
--- /dev/null
+++ b/src/common/kylin-ini.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+#include
+#include
+#include
+
+//去除尾部空白字符 包括\t \n \r
+/*
+标准的空白字符包括:
+' ' (0x20) space (SPC) 空格符
+'\t' (0x09) horizontal tab (TAB) 水平制表符
+'\n' (0x0a) newline (LF) 换行符
+'\v' (0x0b) vertical tab (VT) 垂直制表符
+'\f' (0x0c) feed (FF) 换页符
+'\r' (0x0d) carriage return (CR) 回车符
+//windows \r\n linux \n mac \r
+*/
+char *strstripr(char *str, int containQuot)
+{
+ if(str == NULL || *str == '\0') {
+ return str;
+ }
+ int len = strlen(str);
+ char *p = str + len - 1;
+ if (containQuot) {
+ while(p >= str && (isspace(*p) || *p == '\"')) {
+ *p = '\0'; --p;
+ }
+ } else {
+ while(p >= str && isspace(*p)) {
+ *p = '\0'; --p;
+ }
+ }
+ return str;
+}
+
+//去除首部空格
+char *strstripl(char *str, int containQuot)
+{
+ if(str == NULL || *str == '\0') {
+ return str;
+ }
+ int len = 0;
+ char *p = str;
+ if (containQuot) {
+ while(*p != '\0' && (isspace(*p) || *p == '\"')) {
+ ++p; ++len;
+ }
+ } else {
+ while(*p != '\0' && isspace(*p)) {
+ ++p; ++len;
+ }
+ }
+ memmove(str, p, strlen(str) - len + 1);
+ return str;
+}
+
+//去除首尾空格
+char *strstrip(char *str, int containQuot)
+{
+ str = strstripr(str, containQuot);
+ str = strstripl(str, containQuot);
+ return str;
+}
diff --git a/src/common/kylin-ini.h b/src/common/kylin-ini.h
new file mode 100644
index 0000000..7cc94fd
--- /dev/null
+++ b/src/common/kylin-ini.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// 去除尾部空格
+char *strstripr(char *str, int containQuot);
+
+// 去除头部空格
+char *strstripl(char *str, int containQuot);
+
+// 去除前后空格
+char *strstrip(char *str, int containQuot);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //__KYLININI_H__
\ No newline at end of file
diff --git a/src/hardware/keyboard/Makefile.am b/src/hardware/keyboard/Makefile.am
index 48c5043..2d56e83 100644
--- a/src/hardware/keyboard/Makefile.am
+++ b/src/hardware/keyboard/Makefile.am
@@ -22,32 +22,16 @@ keyboard-generated.h keyboard-generated.c: $(KEY_XML)
#Generata binary file
-lib_LTLIBRARIES = libukui-xkbgeneralclient.la libukui-interfaceclient.la libukui-keyboardclient.la
+lib_LTLIBRARIES = libukui-interfaceclient.la libukui-keyboardclient.la
#gcc -wall: displays all the errors and warning information when compiling
#gcc -g: add the debugging code when compiling
COMM_CFS = -Wall -g
-#Add the dependent source file for libxkbgeneralclient.la
-#xkbgeneral-generated.c must be front of kylin-xkbgeneral-interface.c
-libukui_xkbgeneralclient_la_SOURCES = xkbgeneral-generated.c kylin-xkbgeneral-interface.c \
- $(NULL)
-
#The header files that need to be installed
-include_HEADERS= kylin-xkbgeneral-interface.h \
- kylin-interface-interface.h \
- kylin-keyboard-interface.h \
- $(NULL)
-
-#Additional C compiler flags
-libukui_xkbgeneralclient_la_CFLAGS= $(COMM_CFS) \
- $(GLIB_2_CFLAGS) $(GIO_2_CFLAGS) $(GIO_UNIX_2_CFLAGS) \
- $(NULL)
-
-#Additional link objects
-libukui_xkbgeneralclient_la_LDFLAGS= $(COMM_PRINT) \
- $(GLIB_2_LIBS) $(GIO_2_LIBS) $(GIO_UNIX_2_LIBS) \
- $(NULL)
+include_HEADERS= kylin-interface-interface.h \
+ kylin-keyboard-interface.h \
+ $(NULL)
#Add the dependent source file for libinterfaceclient.la
#interface-generated.c must be front of kylin-interface-interface.c
diff --git a/src/hardware/keyboard/interface-generated.c b/src/hardware/keyboard/interface-generated.c
index 2e1d8bd..0ad29d5 100644
--- a/src/hardware/keyboard/interface-generated.c
+++ b/src/hardware/keyboard/interface-generated.c
@@ -1,8 +1,19 @@
/*
- * Generated by gdbus-codegen 2.62.4 from cn.kylinos.interface.xml. DO NOT EDIT.
+ * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see Flags; " \
+ Q_WS_WIN=1 \
+ Q_WS_MAC=1 \
+ Q_WS_X11=1
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+TAGFILES =
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+PERL_PATH =
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = YES
+MSCGEN_PATH =
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = NO
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+GROUP_GRAPHS = YES
+UML_LOOK = NO
+TEMPLATE_RELATIONS = NO
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+CALL_GRAPH = NO
+CALLER_GRAPH = NO
+GRAPHICAL_HIERARCHY = YES
+DIRECTORY_GRAPH = YES
+DOT_IMAGE_FORMAT = png
+DOT_PATH =
+DOTFILE_DIRS =
+DOT_GRAPH_MAX_NODES = 50
+MAX_DOT_GRAPH_DEPTH = 0
+DOT_TRANSPARENT = NO
+DOT_MULTI_TARGETS = NO
+GENERATE_LEGEND = YES
+DOT_CLEANUP = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+SEARCHENGINE = NO
diff --git a/src/log4qt/LICENSE-2.0.txt b/src/log4qt/LICENSE-2.0.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/src/log4qt/LICENSE-2.0.txt
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/src/log4qt/README.txt b/src/log4qt/README.txt
new file mode 100644
index 0000000..1fbddd7
--- /dev/null
+++ b/src/log4qt/README.txt
@@ -0,0 +1 @@
+See HTML documentation under doc/index.html
\ No newline at end of file
diff --git a/src/log4qt/doc/default.css b/src/log4qt/doc/default.css
new file mode 100644
index 0000000..d619f8d
--- /dev/null
+++ b/src/log4qt/doc/default.css
@@ -0,0 +1,44 @@
+BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {
+ font-family: Geneva, Arial, Helvetica, sans-serif;
+}
+BODY,TD {
+ font-size: 90%;
+}
+H1 {
+ text-align: center;
+ font-size: 160%;
+}
+H2 {
+ font-size: 120%;
+}
+H3 {
+ font-size: 100%;
+}
+H2 {
+ background-color: #e8eef2;
+ color: #1a419d;
+ font-weight: bold;
+ padding-right : 10px;
+ padding-top : 2px;
+ padding-left : 10px;
+ padding-bottom : 2px;
+ margin-left : 0px;
+ margin-right : 0px;
+ margin-top : 2px;
+ margin-bottom : 2px;
+ border: 1px solid #cccccc;
+}
+A {
+ text-decoration: none;
+ font-weight: bold;
+ color: #1A419D;
+}
+A:visited {
+ text-decoration: none;
+ font-weight: bold;
+ color: #1A419D
+}
+A:hover {
+ text-decoration: none;
+ background-color: #ddddff;
+}
diff --git a/src/log4qt/doc/index.html b/src/log4qt/doc/index.html
new file mode 100644
index 0000000..7b79fbc
--- /dev/null
+++ b/src/log4qt/doc/index.html
@@ -0,0 +1,155 @@
+
+
+
+ Log4Qt
+
+
+
+
+
Log4Qt
+
Introduction
+
+Log4Qt is a C++ port of the Apache Software Foundation Log4j package using the
+Trolltech Qt Framework. It is intended to be used by open source and commercial
+Qt projects.
+
+
+
Documentation
+
+The documentation describes classes and methods that have been added or changed
+compared to Log4j. The documentation was generated from the source code using
+Doxygen. It can be accessed here.
+
+
+
How to use
+
+To use Log4Qt within your software project include the Log4Qt source into your project
+
+ Add the log4qt source to the Qt project file by adding the following line
+ include(<unpackdir>/src/log4qt/log4qt.pri)
+
+ Include the Logger class, a layout and an appender class to configure Log4Qt to generate output. The example uses the ConsoleAppender with a TTCCLayout
+ include "log4qt/consoleappender.h"
+ include "log4qt/logger.h"
+ include "log4qt/ttcclayout.h"
+
+ Configure a logger to generate output. The example uses the root logger
+ // Create a layout
+ Log4Qt::LogManager::rootLogger();
+ TTCCLayout *p_layout = new TTCCLayout();
+ p_layout->setName(QLatin1String("My Layout"));
+ p_layout->activateOptions();
+ // Create an appender
+ ConsoleAppender *p_appender = new ConsoleAppender(p_layout, ConsoleAppender::STDOUT_TARGET);
+ p_appender->setName(QLatin1String("My Appender"));
+ p_appender->activateOptions();
+ // Set appender on root logger
+ Log4Qt::Logger::rootLogger()->setAppender(p_appender);
+
+ Request a logger by either calling Log4Qt::Logger::logger or using LOG4QT_DECLARE_QCLASS_LOGGER
+ // Request a logger and output "Hello World!"
+ Log4Qt::Logger::logger(QLatin1String("My Logger"))->info("Hello World!");
+
+
+
+
+
Releases
+
+
+
+ 0.3 - 01 March 2009
+ Bug fixes, compatibility with VS 2008 and Qt 4.5 RC1
+
+
+ Fixed a problem where the pParent parameter of the constructor was not passed on to the QObject constructor (logobject.h)
+
+
+ Fixed a problem were OptionConverter::toBoolean would not return the default value, if the conversion fails (optionconverter.cpp)
+
+
+ Fixed a compile error on VS 2008 by using Q_UNUSED(&rEvent) instead of Q_UNUSED(rEvent) (varia/denyallfilter.h.h)
+
+
+ Fixed VS 2008 unreferenced formal parameter warning by using Q_UNUSED (logmanager.cpp, mdc.cpp, ndc.cpp, propertyconfigurator.cpp, helpers/initialisationhelper.cpp, helpers/patternformatter.cpp)
+
+
+
+
+ 0.2 - 30 January 2009
+ Bug fixes and compatibility with Qt 4.4
+
+
+ Added a compile time version check for the Qt version (log4qt.h)
+
+
+ Replaced usage of q_atomic_increment and q_atomic_decrement with QAtomicInt for compilation with Qt 4.4 (helpers/logobject.h)
+
+
+ Replaced usage of q_atomic_test_and_set_ptr with QAtomicPointer for compilation with Qt 4.4 (logger.h, helpers/classlogger.cpp, helpers/classlogger.h, helpers/initialisationhelper.h)
+
+
+ Fixed a problem with Qt 4.4 where QReadWriteLock is by default non-recursive (hierarchy.cpp, logger.cpp)
+
+
+ Resolved compilation problem with Microsoft Visual Studio 2005 (logmanager.cpp, helpers/datetime.cpp)
+
+
+
+
+ 0.1 - 29 December 2007
+ Initial Version
+
+
+
+
+
Known Problems
+
+
+
+ The Eclipse CDT console does not display the log output of a correctly
+ when using a ConsoleAppender with a TTCCLayout and relative time format.
+ The millisecond count is stripped from the output.
+
+Log4Qt requires the Qt framework that is available under several licensing options
+(Qt licensing).
+The package is intended to be used under the
+Nokia Corporation Qt GPL Exception.
+
+
+
+
diff --git a/src/log4qt/log4qt.conf b/src/log4qt/log4qt.conf
new file mode 100644
index 0000000..bb9c8e3
--- /dev/null
+++ b/src/log4qt/log4qt.conf
@@ -0,0 +1,66 @@
+#设置储存log文件的根目录
+logpath=.
+
+#全局设置
+#是否重置所有配置,恢复全局设置默认值
+log4j.reset=true
+#设置Log4Qt记录器输入级别
+log4j.Debug=INFO
+#日志记录器存储库的阈值
+log4j.threshold=NULL
+#设置是否监听QDebug输出的字符串
+log4j.handleQtMessages=true
+
+#设置根Logger的输出log等级为INFO
+#设置Log输出的几种输出源(appender):console, daily
+log4j.rootLogger=DEBUG,console,daily
+
+#设置终端打印记录器
+#记录器类别 --控制台输出
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+#记录器输出目标
+log4j.appender.console.target=STDOUT_TARGET
+#记录器输出布局 (包含日志产生的时间、线程、类别等信息)
+log4j.appender.console.layout=org.apache.log4j.TTCCLayout
+#记录器布局日期格式 (年-月-日 时:分:秒.毫秒)
+log4j.appender.console.layout.dateFormat=yyy-MM-dd hh:mm:ss.zzz
+#记录器布局包含上下文
+log4j.appender.console.layout.contextPrinting=false
+#记录器布局包含线程信息
+#log4j.appender.console.layout.ThreadPrinting=false
+
+#设置一个每日储存一个log文件的记录器
+#记录器类别 --一天一个文件输出
+log4j.appender.daily=org.apache.log4j.DailyRollingFileAppender
+#记录器输出文件路径
+log4j.appender.daily.file=${logpath}/log4qt.log
+#记录器追加文件内容
+log4j.appender.daily.appendFile=true
+#记录器是否直接写入文件
+#log4j.appender.daily.immediateFlush=true
+#记录器文件名日期后缀 按天
+log4j.appender.daily.datePattern=.yyyy-MM-dd
+#记录器布局分隔符 (根据patten符号格式化输出数据,类似printf的格式化方式)
+log4j.appender.daily.layout=org.apache.log4j.PatternLayout
+log4j.appender.daily.layout.conversionPattern=%-5p|%d{yyyy-MM-dd HH:mm:ss,zzz}(%-4r)|%m%n
+#记录器输出格式
+#日志信息格式中几个符号所代表的含义:
+# -X号: X信息输出时左对齐;
+# %p: 输出日志信息优先级,即DEBUG,INFO,WARN,ERROR,FATAL,
+# %d: 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921
+# %r: 输出自应用启动到输出该log信息耗费的毫秒数
+# %c: 输出日志信息所属的类目,通常就是所在类的全名 (无效)
+# %t: 输出产生该日志事件的线程名 (无效)
+# %l: 输出日志事件的发生位置,相当于%C.%M(%F:%L)的组合,包括类目名、发生的线程,以及在代码中的行数(无效)。举例:Testlog4.main (TestLog4.java:10)
+# %x: 输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中。
+# %%: 输出一个"%"字符
+# %F: 输出日志消息产生时所在的文件名称(无效)
+# %L: 输出代码中的行号(无效)
+# %m: 输出代码中指定的消息,产生的日志具体信息(默认在消息内容前追加了文件名,行号,函数名)
+# %n: 输出一个回车换行符,Windows平台为"\r\n",Unix平台为"\n"输出日志信息换行
+# 可以在%与模式字符之间加上修饰符来控制其最小宽度、最大宽度、和文本的对齐方式。如:
+# 1) c:指定输出category的名称,最小的宽度是20,如果category的名称小于20的话,默认的情况下右对齐。
+# 2)%-20c:指定输出category的名称,最小的宽度是20,如果category的名称小于20的话,"-"号指定左对齐。
+# 3)%.30c:指定输出category的名称,最大的宽度是30,如果category的名称大于30的话,就会将左边多出的字符截掉,但小于30的话也不会有空格。
+# 4) .30c:如果category的名称小于20就补空格,并且右对齐,如果其名称长于30字符,就从左边较远输出的字符截掉。
+
diff --git a/src/log4qt/log4qt/appender.h b/src/log4qt/log4qt/appender.h
new file mode 100644
index 0000000..cb7a217
--- /dev/null
+++ b/src/log4qt/log4qt/appender.h
@@ -0,0 +1,137 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: appender.h
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ********************************************************************************/
+
+#ifndef LOG4QT_APPENDER_H
+#define LOG4QT_APPENDER_H
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+#include "log4qt/helpers/logobject.h"
+
+#include "log4qt/helpers/logobjectptr.h"
+
+#include "log4qt/logger.h"
+
+#include "ukui-logmacros.h"
+
+
+/******************************************************************************
+ * Declarations
+ ******************************************************************************/
+
+namespace Log4Qt
+{
+
+ class Filter;
+ class Layout;
+ class LoggingEvent;
+
+ /*!
+ * \brief The class Appender is the base class for all Appenders.
+ *
+ * To allow the whole hirarchy to be an ascendant of QObject Appender is
+ * not an interface.
+ *
+ * \note All the functions declared in this class are thread-safe.
+ *
+ * \note The ownership and lifetime of objects of this class are managed.
+ * See \ref Ownership "Object ownership" for more details.
+ */
+ class LIBUKUILOG4QT_EXPORT Appender : public LogObject
+ {
+ Q_OBJECT
+
+ /*!
+ * The property holds the Layout used by the Appender.
+ *
+ * \sa layout(), setLayout()
+ */
+ Q_PROPERTY(Layout* layout READ layout WRITE setLayout)
+
+ /*!
+ * The property holds the name of the Appender.
+ *
+ * \sa name(), setName()
+ */
+ Q_PROPERTY(QString name READ name WRITE setName)
+
+ /*!
+ * The property holds if the Appender requires a Layout or not.
+ *
+ * \sa requiresLayout(), setRequiresLayout()
+ */
+ Q_PROPERTY(bool requiresLayout READ requiresLayout)
+
+ public:
+ Appender(QObject *pParent = 0);
+ virtual ~Appender();
+ private:
+ Appender(const Appender &rOther); // Not implemented
+ Appender &operator=(const Appender &rOther); // Not implemented
+
+ public:
+ // JAVA: ErrorHandler* errorHandler();
+ virtual Filter *filter() const = 0;
+ virtual QString name() const = 0;
+ virtual Layout *layout() const = 0;
+ virtual bool requiresLayout() const = 0;
+ // JAVA: void setErrorHandler(ErrorHandler *pErrorHandler);
+ virtual void setLayout(Layout *pLayout) = 0;
+ virtual void setName(const QString &rName) = 0;
+
+ virtual void addFilter(Filter *pFilter) = 0;
+ virtual void clearFilters() = 0;
+ virtual void close() = 0;
+ virtual void doAppend(const LoggingEvent &rEvent) = 0;
+ };
+
+
+ /**************************************************************************
+ * Operators, Helper
+ **************************************************************************/
+
+
+ /**************************************************************************
+ * Inline
+ **************************************************************************/
+
+ inline Appender::Appender(QObject *pParent) :
+ LogObject(pParent)
+ {}
+
+ inline Appender::~Appender()
+ {}
+
+
+} // namespace Log4Qt
+
+
+// Q_DECLARE_TYPEINFO(Log4Qt::Appender, Q_COMPLEX_TYPE); // Use default
+Q_DECLARE_TYPEINFO(Log4Qt::LogObjectPtr, Q_MOVABLE_TYPE);
+
+
+#endif // LOG4QT_APPENDER_H
diff --git a/src/log4qt/log4qt/appenderskeleton.cpp b/src/log4qt/log4qt/appenderskeleton.cpp
new file mode 100644
index 0000000..d9f784b
--- /dev/null
+++ b/src/log4qt/log4qt/appenderskeleton.cpp
@@ -0,0 +1,261 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: appenderskeleton.cpp
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+
+#include "log4qt/appenderskeleton.h"
+
+#include
+#include "log4qt/layout.h"
+#include "log4qt/loggingevent.h"
+#include "log4qt/logmanager.h"
+#include "log4qt/spi/filter.h"
+
+
+namespace Log4Qt
+{
+
+
+ /**************************************************************************
+ * Declarations
+ ***************************************************************************/
+
+
+ /*!
+ * \brief The class RecursionGuardLocker controls a boolean flag.
+ *
+ * It is a helper class to control a boolean flag. The class sets the flag
+ * on creation and resets it on destruction.
+ */
+ class RecursionGuardLocker
+ {
+ public:
+ RecursionGuardLocker(bool *pGuard);
+ ~RecursionGuardLocker();
+ private:
+ RecursionGuardLocker(const RecursionGuardLocker &rOther); // Not implemented
+ RecursionGuardLocker &operator=(const RecursionGuardLocker &rOther); // Not implemented
+ private:
+ bool *mpGuard;
+ };
+
+
+
+ /**************************************************************************
+ * C helper functions
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * Class implementation: RecursionGuardLocker
+ ***************************************************************************/
+
+
+ inline RecursionGuardLocker::RecursionGuardLocker(bool *pGuard)
+ {
+ Q_ASSERT_X(pGuard != 0, "RecursionGuardLocker::RecursionGuardLocker()", "Pointer to guard bool must not be null");
+
+ mpGuard = pGuard;
+ *mpGuard = true;
+ }
+
+
+ inline RecursionGuardLocker::~RecursionGuardLocker()
+ {
+ *mpGuard = false;
+ };
+
+
+
+ /**************************************************************************
+ * Class implementation: AppenderSkeleton
+ **************************************************************************/
+
+
+ AppenderSkeleton::AppenderSkeleton(QObject *pParent) :
+ Appender(pParent),
+ mObjectGuard(QMutex::Recursive), // Recursive for doAppend()
+ mAppendRecursionGuard(false),
+ mIsActive(true),
+ mIsClosed(false),
+ mpLayout(0),
+ mThreshold(Level::NULL_INT),
+ mpHeadFilter(0),
+ mpTailFilter(0)
+ {
+ }
+
+
+ AppenderSkeleton::AppenderSkeleton(const bool isActive,
+ QObject *pParent) :
+ Appender(pParent),
+ mObjectGuard(QMutex::Recursive), // Recursive for doAppend()
+ mAppendRecursionGuard(false),
+ mIsActive(isActive),
+ mIsClosed(false),
+ mpLayout(0),
+ mThreshold(Level::NULL_INT),
+ mpHeadFilter(0),
+ mpTailFilter(0)
+ {
+ }
+
+
+ void AppenderSkeleton::activateOptions()
+ {
+ QMutexLocker locker(&mObjectGuard);
+
+ if (requiresLayout() && !layout())
+ {
+ LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Activation of appender '%1' that requires layout and has no layout set"),
+ APPENDER_ACTIVATE_MISSING_LAYOUT_ERROR);
+ e << name();
+ logger()->error(e);
+ return;
+ }
+ mIsActive = true;
+ }
+
+
+ void AppenderSkeleton::addFilter(Filter *pFilter)
+ {
+ if(!pFilter)
+ {
+ logger()->warn("Adding null Filter to Appender '%1'", name());
+ return;
+ }
+
+ QMutexLocker locker(&mObjectGuard);
+
+ mpTailFilter = pFilter;
+ if (mpHeadFilter)
+ mpHeadFilter->setNext(pFilter);
+ else
+ mpHeadFilter = pFilter;
+ }
+
+
+ void AppenderSkeleton::clearFilters()
+ {
+ QMutexLocker locker(&mObjectGuard);
+
+ mpTailFilter = 0;
+ mpHeadFilter = 0;
+ }
+
+
+ void AppenderSkeleton::close()
+ {
+ QMutexLocker locker(&mObjectGuard);
+
+ mIsClosed = true;
+ mIsActive = false;
+ }
+
+
+ void AppenderSkeleton::doAppend(const LoggingEvent &rEvent)
+ {
+ // The mutex serialises concurrent access from multiple threads.
+ // - e.g. two threads using the same logger
+ // - e.g. two threads using different logger with the same appender
+ //
+ // A call from the same thread will pass the mutex (QMutex::Recursive)
+ // and get to the recursion guard. The recursion guard blocks recursive
+ // invocation and prevents a possible endless loop.
+ // - e.g. an appender logs an error with a logger that uses it
+
+ QMutexLocker locker(&mObjectGuard);
+
+ if (mAppendRecursionGuard)
+ return;
+
+ RecursionGuardLocker recursion_locker(&mAppendRecursionGuard);
+
+ if (!checkEntryConditions())
+ return;
+ if (!isAsSevereAsThreshold(rEvent.level()))
+ return;
+
+ Filter *p_filter = mpHeadFilter;
+ while(p_filter)
+ {
+ Filter::Decision decision = p_filter->decide(rEvent);
+ if (decision == Filter::ACCEPT)
+ break;
+ else if (decision == Filter::DENY)
+ return;
+ else
+ p_filter = p_filter->next();
+ }
+
+ append(rEvent);
+ }
+
+
+ bool AppenderSkeleton::checkEntryConditions() const
+ {
+ // Q_ASSERT_X(, "WriterAppender::checkEntryConditions()", "Lock must be held by caller")
+
+ if (!isActive())
+ {
+ LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Use of non activated appender '%1'"),
+ APPENDER_NOT_ACTIVATED_ERROR);
+ e << name();
+ logger()->error(e);
+ return false;
+ }
+ if (isClosed())
+ {
+ LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Use of closed appender '%1'"),
+ APPENDER_CLOSED_ERROR);
+ e << name();
+ logger()->error(e);
+ return false;
+ }
+ if (requiresLayout() && !layout())
+ {
+ LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Use of appender '%1' that requires layout and has no layout set"),
+ APPENDER_USE_MISSING_LAYOUT_ERROR);
+ e << name();
+ logger()->error(e);
+ return false;
+ }
+
+ return true;
+ }
+
+
+
+ /**************************************************************************
+ * Implementation: Operators, Helper
+ **************************************************************************/
+
+
+} // namespace Log4Qt
diff --git a/src/log4qt/log4qt/appenderskeleton.h b/src/log4qt/log4qt/appenderskeleton.h
new file mode 100644
index 0000000..8438ac1
--- /dev/null
+++ b/src/log4qt/log4qt/appenderskeleton.h
@@ -0,0 +1,229 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: appenderskeleton.h
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef LOG4QT_APPENDERSKELETON_H
+#define LOG4QT_APPENDERSKELETON_H
+
+
+/******************************************************************************
+ * Dependencies
+******************************************************************************/
+
+#include "log4qt/appender.h"
+
+#include
+#include "log4qt/helpers/logobjectptr.h"
+#include "ukui-logmacros.h"
+
+/******************************************************************************
+ * Declarations
+ ******************************************************************************/
+
+namespace Log4Qt
+{
+
+ class Filter;
+ class Layout;
+ class Logger;
+ class LoggingEvent;
+
+ /*!
+ * \brief The class AppenderSkeleton implements general Appender functionality.
+ *
+ * \note All the functions declared in this class are thread-safe.
+ *
+ * \note The ownership and lifetime of objects of this class are managed. See
+ * \ref Ownership "Object ownership" for more details.
+ */
+ class LIBUKUILOG4QT_EXPORT AppenderSkeleton : public Appender
+ {
+ Q_OBJECT
+
+ /*!
+ * The property holds if the Appender has been activated.
+ *
+ * \sa isActive()
+ */
+ Q_PROPERTY(bool isActive READ isActive)
+
+ /*!
+ * The property holds if the Appender has been closed.
+ *
+ * \sa isClosed()
+ */
+ Q_PROPERTY(bool isClosed READ isClosed)
+
+ /*!
+ * The property holds the threshold level used by the Appender.
+ *
+ * \sa threshold(), setThreshold()
+ */
+ Q_PROPERTY(Level threshold READ threshold WRITE setThreshold)
+
+ public:
+ AppenderSkeleton(QObject *pParent = 0);
+ protected:
+ AppenderSkeleton(const bool isActive,
+ QObject *pParent = 0);
+ public:
+ // virtual ~AppenderSkeleton(); Use compiler default
+ private:
+ AppenderSkeleton(const AppenderSkeleton &rOther); // Not implemented
+ AppenderSkeleton &operator=(const AppenderSkeleton &rOther); // Not implemented
+
+ public:
+ // JAVA: ErrorHandler* errorHandler();
+ virtual Filter *filter() const;
+ virtual Layout *layout() const;
+ bool isActive() const;
+ bool isClosed() const;
+ virtual QString name() const;
+ Level threshold() const;
+ // JAVA: void setErrorHandler(ErrorHandler *pErrorHandler);
+ virtual void setLayout(Layout *pLayout);
+ virtual void setName(const QString &rName);
+ void setThreshold(Level level);
+
+ virtual void activateOptions();
+ virtual void addFilter(Filter *pFilter);
+ virtual void clearFilters();
+ virtual void close();
+
+ /*!
+ * Performs checks and delegates the actuall appending to the subclass
+ * specific append() function.
+ *
+ * \sa append(), checkEntryConditions(), isAsSevereAsThreshold(), Filter
+ */
+ virtual void doAppend(const LoggingEvent &rEvent);
+
+ // JAVA: void finalize();
+ Filter* firstFilter() const;
+ bool isAsSevereAsThreshold(Level level) const;
+
+ protected:
+ virtual void append(const LoggingEvent &rEvent) = 0;
+ virtual void asyncAppend(const LoggingEvent &rEvent) = 0;
+
+ /*!
+ * Tests if all entry conditions for using append() in this class are
+ * met.
+ *
+ * If a conditions is not met, an error is logged and the function
+ * returns false.
+ *
+ * The checked conditions are:
+ * - That the appender has been activated (APPENDER_NOT_ACTIVATED_ERROR)
+ * - That the appender was not closed (APPENDER_CLOSED_ERROR)
+ * - That the appender has a layout set, if it requires one
+ * (logging_error(APPENDER_USE_MISSING_LAYOUT_ERROR)
+ *
+ * The function is called as part of the checkEntryConditions() chain
+ * started by doAppend(). The doAppend() function calls the subclass
+ * specific checkEntryConditions() function. The function checks the
+ * class specific conditions and calls checkEntryConditions() of
+ * it's parent class. The last function called is
+ * AppenderSkeleton::checkEntryConditions().
+ *
+ * \sa doAppend()
+ */
+ virtual bool checkEntryConditions() const;
+
+ protected:
+ mutable QMutex mObjectGuard;
+ private:
+ bool mAppendRecursionGuard;
+ volatile bool mIsActive;
+ volatile bool mIsClosed;
+ LogObjectPtr mpLayout;
+ Level mThreshold;
+ LogObjectPtr mpHeadFilter;
+ LogObjectPtr mpTailFilter;
+
+ // need AsyncDispatcher to call asyncAppend method
+ friend class AsyncDispatcher;
+ };
+
+
+ /**************************************************************************
+ * Operators, Helper
+ **************************************************************************/
+
+
+ /**************************************************************************
+ * Inline
+ **************************************************************************/
+
+ inline Filter *AppenderSkeleton::filter() const
+ { QMutexLocker locker(&mObjectGuard);
+ return mpHeadFilter; }
+
+ inline Layout *AppenderSkeleton::layout() const
+ { QMutexLocker locker(&mObjectGuard);
+ return mpLayout; }
+
+ inline QString AppenderSkeleton::name() const
+ { QMutexLocker locker(&mObjectGuard);
+ return objectName(); }
+
+ inline Level AppenderSkeleton::threshold() const
+ { // QMutexLocker locker(&mObjectGuard); // Level is threadsafe
+ return mThreshold; }
+
+ inline void AppenderSkeleton::setLayout(Layout *pLayout)
+ { QMutexLocker locker(&mObjectGuard);
+ mpLayout = pLayout; }
+
+ inline void AppenderSkeleton::setName(const QString &rName)
+ { QMutexLocker locker(&mObjectGuard);
+ setObjectName(rName); }
+
+ inline void AppenderSkeleton::setThreshold(Level level)
+ { // QMutexLocker locker(&mObjectGuard); // Level is threadsafe
+ mThreshold = level; }
+
+ inline bool AppenderSkeleton::isActive() const
+ { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe
+ return mIsActive; }
+
+ inline bool AppenderSkeleton::isClosed() const
+ { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe
+ return mIsClosed; }
+
+ inline Filter *AppenderSkeleton::firstFilter() const
+ { QMutexLocker locker(&mObjectGuard);
+ return filter(); }
+
+ inline bool AppenderSkeleton::isAsSevereAsThreshold(Level level) const
+ { // QMutexLocker locker(&mObjectGuard); // Level is threadsafe
+ return (mThreshold <= level); }
+
+
+} // namespace Log4Qt
+
+
+// Q_DECLARE_TYPEINFO(Log4Qt::AppenderSkeleton, Q_COMPLEX_TYPE); // Use default
+
+
+#endif // LOG4QT_APPENDERSKELETON_H
diff --git a/src/log4qt/log4qt/basicconfigurator.cpp b/src/log4qt/log4qt/basicconfigurator.cpp
new file mode 100644
index 0000000..280b88d
--- /dev/null
+++ b/src/log4qt/log4qt/basicconfigurator.cpp
@@ -0,0 +1,107 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: basicconfigurator.cpp
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+
+#include "log4qt/basicconfigurator.h"
+
+#include
+#include
+#include
+#include "log4qt/consoleappender.h"
+#include "log4qt/helpers/configuratorhelper.h"
+#include "log4qt/helpers/logobjectptr.h"
+#include "log4qt/logmanager.h"
+#include "log4qt/patternlayout.h"
+#include "log4qt/varia/listappender.h"
+
+
+
+namespace Log4Qt
+{
+
+
+ /**************************************************************************
+ * Declarations
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * C helper functions
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * Class implementation: BasicConfigurator
+ **************************************************************************/
+
+
+ bool BasicConfigurator::configure()
+ {
+ LogObjectPtr list = new ListAppender;
+ list->setName(QLatin1String("BasicConfigurator"));
+ list->setConfiguratorList(true);
+ list->setThreshold(Level::ERROR_INT);
+ LogManager::logLogger()->addAppender(list);
+
+ PatternLayout *p_layout = new PatternLayout(PatternLayout::TTCC_CONVERSION_PATTERN);
+ p_layout->setName(QLatin1String("BasicConfigurator TTCC"));
+ p_layout->activateOptions();
+ ConsoleAppender *p_appender = new ConsoleAppender(p_layout, ConsoleAppender::STDOUT_TARGET);
+ p_appender->setName(QLatin1String("BasicConfigurator stdout"));
+ p_appender->activateOptions();
+ LogManager::rootLogger()->addAppender(p_appender);
+
+ LogManager::logLogger()->removeAppender(list);
+ ConfiguratorHelper::setConfigureError(list->list());
+ return (list->list().count() == 0);
+ }
+
+
+ void BasicConfigurator::configure(Appender *pAppender)
+ {
+ LogManager::rootLogger()->addAppender(pAppender);
+ }
+
+
+ void BasicConfigurator::resetConfiguration()
+ {
+ LogManager::resetConfiguration();
+ }
+
+
+
+ /**************************************************************************
+ * Implementation: Operators, Helper
+ **************************************************************************/
+
+
+} // namespace Log4Qt
diff --git a/src/log4qt/log4qt/basicconfigurator.h b/src/log4qt/log4qt/basicconfigurator.h
new file mode 100644
index 0000000..5dfa62f
--- /dev/null
+++ b/src/log4qt/log4qt/basicconfigurator.h
@@ -0,0 +1,85 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: basicconfigurator.h
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef LOG4QT_BASICCONFIGURATOR_H
+#define LOG4QT_BASICCONFIGURATOR_H
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+
+#include
+#include "log4qt/log4qt.h"
+#include "ukui-logmacros.h"
+
+
+/******************************************************************************
+ * Declarations
+ ******************************************************************************/
+
+namespace Log4Qt
+{
+
+ class Appender;
+
+ /*!
+ * \brief The class BasicConfigurator provides a simple package
+ * configuration.
+ *
+ * \note All the functions declared in this class are thread-safe.
+ */
+ class LIBUKUILOG4QT_EXPORT BasicConfigurator
+ {
+ private:
+ BasicConfigurator(); // Not implemented
+ // BasicConfigurator(const BasicConfigurator &rOther); // Use compiler default
+ // virtual ~BasicConfigurator(); // Use compiler default
+ // BasicConfigurator &operator=(const BasicConfigurator &rOther); // Use compiler default
+
+ public:
+ static bool configure();
+ static void configure(Appender *pAppender);
+ static void resetConfiguration();
+ };
+
+
+ /**************************************************************************
+ * Operators, Helper
+ **************************************************************************/
+
+
+ /**************************************************************************
+ * Inline
+ **************************************************************************/
+
+
+} // namspace Log4Qt
+
+
+// Q_DECLARE_TYPEINFO(Log4Qt::BasicConfigurator, Q_MOVABLE_TYPE); // Use default
+
+
+#endif // LOG4QT_BASICCONFIGURATOR_H
diff --git a/src/log4qt/log4qt/consoleappender.cpp b/src/log4qt/log4qt/consoleappender.cpp
new file mode 100644
index 0000000..1b4fe03
--- /dev/null
+++ b/src/log4qt/log4qt/consoleappender.cpp
@@ -0,0 +1,198 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: consoleappender.cpp
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+
+#include "log4qt/consoleappender.h"
+
+#include
+#include
+#include "log4qt/helpers/optionconverter.h"
+#include "log4qt/layout.h"
+#include "log4qt/loggingevent.h"
+
+
+
+namespace Log4Qt
+{
+
+
+ /**************************************************************************
+ * Declarations
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * C helper functions
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * Class implementation: ConsoleAppender
+ **************************************************************************/
+
+
+ ConsoleAppender::ConsoleAppender(QObject *pParent) :
+ WriterAppender(pParent),
+ mTarget(STDOUT_TARGET),
+ mpTextStream(0)
+ {
+ }
+
+
+ ConsoleAppender::ConsoleAppender(Layout *pLayout,
+ QObject *pParent) :
+ WriterAppender(pLayout, pParent),
+ mTarget(STDOUT_TARGET),
+ mpTextStream(0)
+ {
+ }
+
+
+ ConsoleAppender::ConsoleAppender(Layout *pLayout,
+ const QString &rTarget,
+ QObject *pParent) :
+ WriterAppender(pLayout, pParent),
+ mTarget(STDOUT_TARGET),
+ mpTextStream(0)
+ {
+ setTarget(rTarget);
+ }
+
+
+ ConsoleAppender::ConsoleAppender(Layout *pLayout,
+ Target target,
+ QObject *pParent) :
+ WriterAppender(pLayout, pParent),
+ mTarget(target),
+ mpTextStream(0)
+ {
+ }
+
+
+ ConsoleAppender::~ConsoleAppender()
+ {
+ close();
+ }
+
+
+ QString ConsoleAppender::target() const
+ {
+ // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe
+
+ if (mTarget == STDOUT_TARGET)
+ return QLatin1String("STDOUT_TARGET");
+ else
+ return QLatin1String("STDERR_TARGET");
+ }
+
+
+ void ConsoleAppender::setTarget(const QString &rTarget)
+ {
+ bool ok;
+ Target target = (Target)OptionConverter::toTarget(rTarget, &ok);
+ if (ok)
+ setTarget(target);
+ }
+
+
+ void ConsoleAppender::activateOptions()
+ {
+ QMutexLocker locker(&mObjectGuard);
+
+ closeStream();
+
+ if (mTarget == STDOUT_TARGET)
+ mpTextStream = new QTextStream(stdout);
+ else
+ mpTextStream = new QTextStream(stderr);
+ setWriter(mpTextStream);
+
+ WriterAppender::activateOptions();
+ }
+
+
+ void ConsoleAppender::close()
+ {
+ QMutexLocker locker(&mObjectGuard);
+
+ if (isClosed())
+ return;
+
+ WriterAppender::close();
+ closeStream();
+ }
+
+
+ void ConsoleAppender::closeStream()
+ {
+ // Q_ASSERT_X(, "ConsoleAppender::closeStream()", "Lock must be held by caller")
+
+ setWriter(0);
+ delete mpTextStream;
+ mpTextStream = 0;
+ }
+
+
+#ifndef QT_NO_DEBUG_STREAM
+ QDebug ConsoleAppender::debug(QDebug &rDebug) const
+ {
+ QString layout_name;
+ if (layout())
+ layout_name = layout()->name();
+ QString target;
+ if (mTarget == STDOUT_TARGET)
+ target = QLatin1String("STDOUT");
+ else
+ target = QLatin1String("STDERR");
+
+ rDebug.nospace() << "ConsoleAppender("
+ << "name:" << name() << " "
+ << "filter:" << firstFilter() << " "
+ << "isactive:" << isActive() << " "
+ << "isclosed:" << isClosed() << " "
+ << "layout:" << layout_name << " "
+ << "target:" << target << " "
+ << "referencecount:" << referenceCount() << " "
+ << "threshold:" << threshold().toString()
+ << ")";
+ return rDebug.space();
+ }
+#endif // QT_NO_DEBUG_STREAM
+
+
+
+ /******************************************************************************
+ * Implementation: Operators, Helper
+ ******************************************************************************/
+
+
+} // namespace Log4Qt
diff --git a/src/log4qt/log4qt/consoleappender.h b/src/log4qt/log4qt/consoleappender.h
new file mode 100644
index 0000000..17fd969
--- /dev/null
+++ b/src/log4qt/log4qt/consoleappender.h
@@ -0,0 +1,160 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: consoleappender.h
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef LOG4QT_CONSOLEAPPENDER_H
+#define LOG4QT_CONSOLEAPPENDER_H
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+#include "log4qt/writerappender.h"
+#include "ukui-logmacros.h"
+
+/******************************************************************************
+ * Declarations
+ ******************************************************************************/
+
+class QFile;
+class QTextStream;
+
+namespace Log4Qt
+{
+
+ /*!
+ * \brief The class ConsoleAppender appends to stdout or stderr.
+ *
+ * \note All the functions declared in this class are thread-safe.
+ *
+ * \note The ownership and lifetime of objects of this class are managed.
+ * See \ref Ownership "Object ownership" for more details.
+ */
+ class LIBUKUILOG4QT_EXPORT ConsoleAppender : public WriterAppender
+ {
+ Q_OBJECT
+
+ /*!
+ * The property holds the target used by the appender.
+ *
+ * The default is STDOUT_TARGET for the standard output.
+ *
+ * \sa Target, target(), setTarget()
+ */
+ Q_PROPERTY(QString target READ target WRITE setTarget)
+
+ public:
+ /*!
+ * The enum defines the possible output targets
+ *
+ * \sa target(), setTarget()
+ */
+ enum Target {
+ /*! The output target is standard out. */
+ STDOUT_TARGET,
+ /*! The output target is standard error. */
+ STDERR_TARGET
+ };
+ Q_ENUMS(Target)
+
+ ConsoleAppender(QObject *pParent = 0);
+ ConsoleAppender(Layout *pLayout,
+ QObject *pParent = 0);
+ ConsoleAppender(Layout *pLayout,
+ const QString &rTarget,
+ QObject *pParent = 0);
+
+ /*!
+ * Creates a ConsoleAppender with the layout \a pLayout, the target
+ * value specified by the \a target constant and the parent
+ * \a pParent.
+ */
+ ConsoleAppender(Layout *pLayout,
+ Target target,
+ QObject *pParent = 0);
+
+ virtual ~ConsoleAppender();
+ private:
+ ConsoleAppender(const ConsoleAppender &rOther); // Not implemented
+ ConsoleAppender &operator=(const ConsoleAppender &rOther); // Not implemented
+
+ public:
+ // JAVA: bool follow() const;
+ QString target() const;
+ // JAVA: void setFollow(bool follow);
+ void setTarget(const QString &rTarget);
+
+ /*!
+ * Sets the target to the value specified by the \a target constant.
+ */
+ void setTarget(Target target);
+
+ virtual void activateOptions();
+ virtual void close();
+
+ protected:
+ void closeStream();
+
+ #ifndef QT_NO_DEBUG_STREAM
+ /*!
+ * Writes all object member variables to the given debug stream
+ * \a rDebug and returns the stream.
+ *
+ *
+ * %ConsoleAppender(name:"CA" filter:0x0 isactive:true isclosed:false
+ * layout:"PL" target:"STDERR" referenceCount:1
+ * threshold:"WARN_SET")
+ *
+ * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject)
+ */
+ virtual QDebug debug(QDebug &rDebug) const;
+ #endif // QT_NO_DEBUG_STREAM
+
+ private:
+ volatile Target mTarget;
+ QTextStream *mpTextStream;
+ };
+
+
+ /**************************************************************************
+ * Operators, Helper
+ **************************************************************************/
+
+
+ /**************************************************************************
+ * Inline
+ **************************************************************************/
+
+ inline void ConsoleAppender::setTarget(Target target)
+ { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe
+ mTarget = target; }
+
+
+} // namespace Log4Qt
+
+
+// Q_DECLARE_TYPEINFO(Log4Qt::ConsoleAppender, Q_COMPLEX_TYPE); // Use default
+
+
+#endif // LOG4QT_CONSOLEAPPENDER_H
diff --git a/src/log4qt/log4qt/dailyrollingfileappender.cpp b/src/log4qt/log4qt/dailyrollingfileappender.cpp
new file mode 100644
index 0000000..682f8d5
--- /dev/null
+++ b/src/log4qt/log4qt/dailyrollingfileappender.cpp
@@ -0,0 +1,457 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: dailyrollingfileappender.cpp
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+
+#include "log4qt/dailyrollingfileappender.h"
+
+#include
+#include
+#include
+#include
+#include
+#include "log4qt/helpers/datetime.h"
+#include "log4qt/layout.h"
+#include "log4qt/loggingevent.h"
+
+
+
+namespace Log4Qt
+{
+
+
+ /**************************************************************************
+ * Declarations
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * C helper functions
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * Class implementation: DailyRollingFileAppender
+ **************************************************************************/
+
+
+ DailyRollingFileAppender::DailyRollingFileAppender(QObject *pParent) :
+ FileAppender(pParent),
+ mDatePattern()
+ {
+ setDatePattern(DAILY_ROLLOVER);
+ }
+
+
+ DailyRollingFileAppender::DailyRollingFileAppender(Layout *pLayout,
+ const QString &rFileName,
+ const QString &rDatePattern,
+ QObject *pParent) :
+ FileAppender(pLayout, rFileName, pParent),
+ mDatePattern()
+ {
+ setDatePattern(rDatePattern);
+ }
+
+
+ DailyRollingFileAppender::~DailyRollingFileAppender()
+ {
+ close();
+ }
+
+
+ void DailyRollingFileAppender::setDatePattern(DatePattern datePattern)
+ {
+ switch (datePattern)
+ {
+ case MINUTELY_ROLLOVER:
+ setDatePattern(QLatin1String("'.'yyyy-MM-dd-hh-mm"));
+ break;
+ case HOURLY_ROLLOVER:
+ setDatePattern(QLatin1String("'.'yyyy-MM-dd-hh"));
+ break;
+ case HALFDAILY_ROLLOVER:
+ setDatePattern(QLatin1String("'.'yyyy-MM-dd-a"));
+ break;
+ case DAILY_ROLLOVER:
+ setDatePattern(QLatin1String("'.'yyyy-MM-dd"));
+ break;
+ case WEEKLY_ROLLOVER:
+ setDatePattern(QLatin1String("'.'yyyy-ww"));
+ break;
+ case MONTHLY_ROLLOVER:
+ setDatePattern(QLatin1String("'.'yyyy-MM"));
+ break;
+ default:
+ Q_ASSERT_X(false, "DailyRollingFileAppender::setDatePattern()", "Invalid datePattern constant");
+ setDatePattern(DAILY_ROLLOVER);
+ };
+ }
+
+
+ void DailyRollingFileAppender::activateOptions()
+ {
+ QMutexLocker locker(&mObjectGuard);
+
+ computeFrequency();
+ if (!mActiveDatePattern.isEmpty())
+ {
+ #ifdef UKUILOG4QT_EXTRA_ENABLE
+ QFileInfo fileInfo(file());
+ if (!fileInfo.exists()) {
+ computeRollOverTime();
+ } else {
+ computeRollOverTime(fileInfo.birthTime().isNull()?fileInfo.lastModified():fileInfo.birthTime());
+ }
+ #else
+ computeRollOverTime();
+ #endif
+ FileAppender::activateOptions();
+ }
+ }
+
+
+ void DailyRollingFileAppender::append(const LoggingEvent &rEvent)
+ {
+ // Q_ASSERT_X(, "DailyRollingFileAppender::append()", "Lock must be held by caller")
+ #ifndef UKUILOG4QT_EXTRA_ENABLE
+ if (QDateTime::currentDateTime() > mRollOverTime)
+ rollOver();
+ #endif
+ FileAppender::append(rEvent);
+ }
+
+ void DailyRollingFileAppender::asyncAppend(const LoggingEvent &rEvent)
+ {
+ // Q_ASSERT_X(, "DailyRollingFileAppender::asyncAppend()", "Lock must be held by caller")
+
+ if (QDateTime::currentDateTime() > mRollOverTime)
+ rollOver();
+ FileAppender::asyncAppend(rEvent);
+ }
+
+
+ bool DailyRollingFileAppender::checkEntryConditions() const
+ {
+ // Q_ASSERT_X(, "DailyRollingFileAppender::checkEntryConditions()", "Lock must be held by caller")
+
+ if (mActiveDatePattern.isEmpty())
+ {
+ LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Use of appender '%1' without having a valid date pattern set"),
+ APPENDER_USE_INVALID_PATTERN_ERROR);
+ e << name();
+ logger()->error(e);
+ return false;
+ }
+
+ return FileAppender::checkEntryConditions();
+ }
+
+
+#ifndef QT_NO_DEBUG_STREAM
+ QDebug DailyRollingFileAppender::debug(QDebug &rDebug) const
+ {
+ QString layout_name;
+ if (layout())
+ layout_name = layout()->name();
+ QString codec_name;
+ if (encoding())
+ codec_name = QLatin1String(encoding()->name());
+
+ rDebug.nospace() << "DailyRollingFileAppender("
+ << "name:" << name() << " "
+ << "activedatepattern:" << mActiveDatePattern << " "
+ << "appendfile:" << appendFile() << " "
+ << "bufferedio:" << bufferedIo() << " "
+ << "datepattern:" << datePattern() << " "
+ << "encoding:" << codec_name << " "
+ << "frequency:" << frequencyToString() << " "
+ << "file:" << file() << " "
+ << "filter:" << firstFilter() << " "
+ << "immediateflush:" << immediateFlush() << " "
+ << "isactive:" << isActive() << " "
+ << "isclosed:" << isClosed() << " "
+ << "layout:" << layout_name << " "
+ << "referencecount:" << referenceCount() << " "
+ << "rollovertime:" << mRollOverTime
+ << "threshold:" << threshold().toString()
+ << "writer:" << writer()
+ << ")";
+ return rDebug.space();
+ }
+#endif // QT_NO_DEBUG_STREAM
+
+
+ void DailyRollingFileAppender::computeFrequency()
+ {
+ // Q_ASSERT_X(, "DailyRollingFileAppender::computeFrequency()", "Lock must be held by caller")
+
+ const DateTime start_time(QDate(1999, 1, 1), QTime(0, 0));
+ const QString start_string = start_time.toString(mDatePattern);
+ mActiveDatePattern.clear();
+
+ if (start_string != static_cast(start_time.addSecs(60)).toString(mDatePattern))
+ mFrequency = MINUTELY_ROLLOVER;
+ else if (start_string != static_cast(start_time.addSecs(60 * 60)).toString(mDatePattern))
+ mFrequency = HOURLY_ROLLOVER;
+ else if (start_string != static_cast(start_time.addSecs(60 * 60 * 12)).toString(mDatePattern))
+ mFrequency = HALFDAILY_ROLLOVER;
+ else if (start_string != static_cast(start_time.addDays(1)).toString(mDatePattern))
+ mFrequency = DAILY_ROLLOVER;
+ else if (start_string != static_cast(start_time.addDays(7)).toString(mDatePattern))
+ mFrequency = WEEKLY_ROLLOVER;
+ else if (start_string != static_cast(start_time.addMonths(1)).toString(mDatePattern))
+ mFrequency = MONTHLY_ROLLOVER;
+ else
+ {
+ LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("The pattern '%1' does not specify a frequency for appender '%2'"),
+ APPENDER_INVALID_PATTERN_ERROR);
+ e << mDatePattern << name();
+ logger()->error(e);
+ return;
+ }
+
+ mActiveDatePattern = mDatePattern;
+ logger()->trace("Frequency set to %2 using date pattern %1",
+ mActiveDatePattern,
+ frequencyToString());
+ }
+
+ void DailyRollingFileAppender::computeRollOverTime(QDateTime startTime)
+ {
+ // Q_ASSERT_X(, "DailyRollingFileAppender::computeRollOverTime()", "Lock must be held by caller")
+ Q_ASSERT_X(!mActiveDatePattern.isEmpty(), "DailyRollingFileAppender::computeRollOverTime()", "No active date pattern");
+
+ QDateTime now = startTime;
+ QDate now_date = now.date();
+ QTime now_time = now.time();
+ QDateTime start;
+
+ switch (mFrequency)
+ {
+ case MINUTELY_ROLLOVER:
+ {
+ start = QDateTime(now_date,
+ QTime(now_time.hour(),
+ now_time.minute(),
+ 0, 0));
+ mRollOverTime = start.addSecs(60);
+ }
+ break;
+ case HOURLY_ROLLOVER:
+ {
+ start = QDateTime(now_date,
+ QTime(now_time.hour(),
+ 0, 0, 0));
+ mRollOverTime = start.addSecs(60*60);
+ }
+ break;
+ case HALFDAILY_ROLLOVER:
+ {
+ int hour = now_time.hour();
+ if (hour >= 12)
+ hour = 12;
+ else
+ hour = 0;
+ start = QDateTime(now_date,
+ QTime(hour, 0, 0, 0));
+ mRollOverTime = start.addSecs(60*60*12);
+ }
+ break;
+ case DAILY_ROLLOVER:
+ {
+ start = QDateTime(now_date,
+ QTime(0, 0, 0, 0));
+ mRollOverTime = start.addDays(1);
+ }
+ break;
+ case WEEKLY_ROLLOVER:
+ {
+ // QT numbers the week days 1..7. The week starts on Monday.
+ // Change it to being numbered 0..6, starting with Sunday.
+ int day = now_date.dayOfWeek();
+ if (day == Qt::Sunday)
+ day = 0;
+ start = QDateTime(now_date,
+ QTime(0, 0, 0, 0)).addDays(-1 * day);
+ mRollOverTime = start.addDays(7);
+ }
+ break;
+ case MONTHLY_ROLLOVER:
+ {
+ start = QDateTime(QDate(now_date.year(),
+ now_date.month(),
+ 1),
+ QTime(0, 0, 0, 0));
+ mRollOverTime = start.addMonths(1);
+ }
+ break;
+ default:
+ Q_ASSERT_X(false, "DailyRollingFileAppender::computeInterval()", "Invalid datePattern constant");
+ mRollOverTime = QDateTime::fromTime_t(0);
+ }
+
+ mRollOverSuffix = static_cast(start).toString(mActiveDatePattern);
+ Q_ASSERT_X(static_cast(now).toString(mActiveDatePattern) == mRollOverSuffix,
+ "DailyRollingFileAppender::computeRollOverTime()", "File name changes within interval");
+ Q_ASSERT_X(mRollOverSuffix != static_cast(mRollOverTime).toString(mActiveDatePattern),
+ "DailyRollingFileAppender::computeRollOverTime()", "File name does not change with rollover");
+
+ logger()->trace("Computing roll over time from %1: The interval start time is %2. The roll over time is %3",
+ now,
+ start,
+ mRollOverTime);
+ }
+
+ void DailyRollingFileAppender::computeRollOverTime()
+ {
+ // Q_ASSERT_X(, "DailyRollingFileAppender::computeRollOverTime()", "Lock must be held by caller")
+ Q_ASSERT_X(!mActiveDatePattern.isEmpty(), "DailyRollingFileAppender::computeRollOverTime()", "No active date pattern");
+
+ QDateTime now = QDateTime::currentDateTime();
+ QDate now_date = now.date();
+ QTime now_time = now.time();
+ QDateTime start;
+
+ switch (mFrequency)
+ {
+ case MINUTELY_ROLLOVER:
+ {
+ start = QDateTime(now_date,
+ QTime(now_time.hour(),
+ now_time.minute(),
+ 0, 0));
+ mRollOverTime = start.addSecs(60);
+ }
+ break;
+ case HOURLY_ROLLOVER:
+ {
+ start = QDateTime(now_date,
+ QTime(now_time.hour(),
+ 0, 0, 0));
+ mRollOverTime = start.addSecs(60*60);
+ }
+ break;
+ case HALFDAILY_ROLLOVER:
+ {
+ int hour = now_time.hour();
+ if (hour >= 12)
+ hour = 12;
+ else
+ hour = 0;
+ start = QDateTime(now_date,
+ QTime(hour, 0, 0, 0));
+ mRollOverTime = start.addSecs(60*60*12);
+ }
+ break;
+ case DAILY_ROLLOVER:
+ {
+ start = QDateTime(now_date,
+ QTime(0, 0, 0, 0));
+ mRollOverTime = start.addDays(1);
+ }
+ break;
+ case WEEKLY_ROLLOVER:
+ {
+ // QT numbers the week days 1..7. The week starts on Monday.
+ // Change it to being numbered 0..6, starting with Sunday.
+ int day = now_date.dayOfWeek();
+ if (day == Qt::Sunday)
+ day = 0;
+ start = QDateTime(now_date,
+ QTime(0, 0, 0, 0)).addDays(-1 * day);
+ mRollOverTime = start.addDays(7);
+ }
+ break;
+ case MONTHLY_ROLLOVER:
+ {
+ start = QDateTime(QDate(now_date.year(),
+ now_date.month(),
+ 1),
+ QTime(0, 0, 0, 0));
+ mRollOverTime = start.addMonths(1);
+ }
+ break;
+ default:
+ Q_ASSERT_X(false, "DailyRollingFileAppender::computeInterval()", "Invalid datePattern constant");
+ mRollOverTime = QDateTime::fromTime_t(0);
+ }
+
+ mRollOverSuffix = static_cast(start).toString(mActiveDatePattern);
+ Q_ASSERT_X(static_cast(now).toString(mActiveDatePattern) == mRollOverSuffix,
+ "DailyRollingFileAppender::computeRollOverTime()", "File name changes within interval");
+ Q_ASSERT_X(mRollOverSuffix != static_cast(mRollOverTime).toString(mActiveDatePattern),
+ "DailyRollingFileAppender::computeRollOverTime()", "File name does not change with rollover");
+
+ logger()->trace("Computing roll over time from %1: The interval start time is %2. The roll over time is %3",
+ now,
+ start,
+ mRollOverTime);
+ }
+
+
+ QString DailyRollingFileAppender::frequencyToString() const
+ {
+ QMetaEnum meta_enum = metaObject()->enumerator(metaObject()->indexOfEnumerator("DatePattern"));
+ return QLatin1String(meta_enum.valueToKey(mFrequency));
+ }
+
+
+ void DailyRollingFileAppender::rollOver()
+ {
+ // Q_ASSERT_X(, "DailyRollingFileAppender::rollOver()", "Lock must be held by caller")
+ Q_ASSERT_X(!mActiveDatePattern.isEmpty(), "DailyRollingFileAppender::rollOver()", "No active date pattern");
+
+ QString roll_over_suffix = mRollOverSuffix;
+ computeRollOverTime();
+ if (roll_over_suffix == mRollOverSuffix)
+ return;
+
+ closeFile();
+
+ QString target_file_name = file() + roll_over_suffix;
+ QFile f(target_file_name);
+ if (f.exists() && !removeFile(f))
+ return;
+ f.setFileName(file());
+ if (!renameFile(f, target_file_name))
+ return;
+ openFile();
+ }
+
+
+
+ /**************************************************************************
+ * Implementation: Operators, Helper
+ **************************************************************************/
+
+
+} // namespace Log4Qt
diff --git a/src/log4qt/log4qt/dailyrollingfileappender.h b/src/log4qt/log4qt/dailyrollingfileappender.h
new file mode 100644
index 0000000..3228c4f
--- /dev/null
+++ b/src/log4qt/log4qt/dailyrollingfileappender.h
@@ -0,0 +1,199 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: dailyrollingfileappender.h
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef LOG4QT_DAILYROLLINGFILEAPPENDER_H
+#define LOG4QT_DAILYROLLINGFILEAPPENDER_H
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+#include "log4qt/fileappender.h"
+#include "ukui-logmacros.h"
+
+#include
+
+
+/******************************************************************************
+ * Declarations
+ ******************************************************************************/
+
+namespace Log4Qt
+{
+
+ /*!
+ * \brief The class DailyRollingFileAppender extends FileAppender so that the
+ * underlying file is rolled over at a specified frequency.
+ *
+ * \note All the functions declared in this class are thread-safe.
+ *
+ * \note The ownership and lifetime of objects of this class are managed. See
+ * \ref Ownership "Object ownership" for more details.
+ */
+ class LIBUKUILOG4QT_EXPORT DailyRollingFileAppender : public FileAppender
+ {
+ Q_OBJECT
+
+ /*!
+ * The property holds the date pattern used by the appender.
+ *
+ * The default is DAILY_ROLLOVER for rollover at midnight each day.
+ *
+ * \sa datePattern(), setDatePattern()
+ */
+ Q_PROPERTY(QString datePattern READ datePattern WRITE setDatePattern)
+
+ public:
+ /*!
+ * The enum DatePattern defines constants for date patterns.
+ *
+ * \sa setDatePattern(DatePattern)
+ */
+ enum DatePattern
+ {
+ /*! The minutely date pattern string is "'.'yyyy-MM-dd-hh-mm". */
+ MINUTELY_ROLLOVER = 0,
+ /*! The hourly date pattern string is "'.'yyyy-MM-dd-hh". */
+ HOURLY_ROLLOVER,
+ /*! The half-daily date pattern string is "'.'yyyy-MM-dd-a". */
+ HALFDAILY_ROLLOVER,
+ /*! The daily date pattern string is "'.'yyyy-MM-dd". */
+ DAILY_ROLLOVER,
+ /*! The weekly date pattern string is "'.'yyyy-ww". */
+ WEEKLY_ROLLOVER,
+ /*! The monthly date pattern string is "'.'yyyy-MM". */
+ MONTHLY_ROLLOVER
+ };
+ Q_ENUMS(DatePattern)
+
+ DailyRollingFileAppender(QObject *pParent = 0);
+ DailyRollingFileAppender(Layout *pLayout,
+ const QString &rFileName,
+ const QString &rDatePattern,
+ QObject *pParent = 0);
+ virtual ~DailyRollingFileAppender();
+ private:
+ DailyRollingFileAppender(const DailyRollingFileAppender &rOther); // Not implemented
+ DailyRollingFileAppender &operator=(const DailyRollingFileAppender &rOther); // Not implemented
+
+ public:
+ QString datePattern() const;
+
+ /*!
+ * Sets the datePattern to the value specified by the \a datePattern
+ * constant.
+ */
+ void setDatePattern(DatePattern datePattern);
+
+ void setDatePattern(const QString &rDatePattern);
+
+ virtual void activateOptions();
+
+ protected:
+ virtual void append(const LoggingEvent &rEvent);
+ virtual void asyncAppend(const LoggingEvent &rEvent);
+
+ /*!
+ * Tests if all entry conditions for using append() in this class are
+ * met.
+ *
+ * If a conditions is not met, an error is logged and the function
+ * returns false. Otherwise the result of
+ * FileAppender::checkEntryConditions() is returned.
+ *
+ * The checked conditions are:
+ * - A valid pattern has been set (APPENDER_USE_INVALID_PATTERN_ERROR)
+ *
+ * The function is called as part of the checkEntryConditions() chain
+ * started by AppenderSkeleton::doAppend().
+ *
+ * \sa AppenderSkeleton::doAppend(),
+ * AppenderSkeleton::checkEntryConditions()
+ */
+ virtual bool checkEntryConditions() const;
+
+ protected:
+#ifndef QT_NO_DEBUG_STREAM
+ /*!
+ * Writes all object member variables to the given debug stream
+ * \a rDebug and returns the stream.
+ *
+ *
+ * %DailyRollingFileAppender(name:"DRFA" activedatepattern:"'.'yyyy-MM-dd-hh-mm"
+ * appendfile:false bufferedio:true
+ * datepattern:"'.'yyyy-MM-dd-hh-mm"
+ * encoding:"" frequency:"MINUTELY_ROLLOVER"
+ * file:"/log.txt" filter:0x0 immediateflush:true
+ * isactive:true isclosed:false layout:"TTCC"
+ * referencecount:1
+ * rollovertime:QDateTime("Mon Oct 22 05:23:00 2007")
+ * threshold: "NULL" writer: 0x0 )
+ *
+ * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject)
+ */
+ virtual QDebug debug(QDebug &rDebug) const;
+#endif // QT_NO_DEBUG_STREAM
+
+ private:
+ void computeFrequency();
+ void computeRollOverTime();
+ void computeRollOverTime(QDateTime startTime);
+ QString frequencyToString() const;
+ void rollOver();
+
+ private:
+ QString mDatePattern;
+ DatePattern mFrequency;
+ QString mActiveDatePattern;
+ QDateTime mRollOverTime;
+ QString mRollOverSuffix;
+ };
+
+
+ /**************************************************************************
+ * Operators, Helper
+ **************************************************************************/
+
+
+ /**************************************************************************
+ * Inline
+ **************************************************************************/
+
+ inline QString DailyRollingFileAppender::datePattern() const
+ { QMutexLocker locker(&mObjectGuard);
+ return mDatePattern; }
+
+ inline void DailyRollingFileAppender::setDatePattern(const QString &rDatePattern)
+ { QMutexLocker locker(&mObjectGuard);
+ mDatePattern = rDatePattern; }
+
+
+} // namespace Log4Qt
+
+
+// Q_DECLARE_TYPEINFO(Log4Qt::DailyRollingFileAppender, Q_COMPLEX_TYPE); // Use default
+
+
+#endif // LOG4QT_DAILYROLLINGFILEAPPENDER_H
diff --git a/src/log4qt/log4qt/fileappender.cpp b/src/log4qt/log4qt/fileappender.cpp
new file mode 100644
index 0000000..77db664
--- /dev/null
+++ b/src/log4qt/log4qt/fileappender.cpp
@@ -0,0 +1,310 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: fileappender.cpp
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+
+#include "log4qt/fileappender.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include "log4qt/layout.h"
+#include "log4qt/loggingevent.h"
+
+
+
+namespace Log4Qt
+{
+
+
+ /**************************************************************************
+ * Declarations
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * C helper functions
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * Class implementation: FileAppender
+ **************************************************************************/
+
+
+ FileAppender::FileAppender(QObject *pParent) :
+ WriterAppender(pParent),
+ mAppendFile(false),
+ mBufferedIo(true),
+ mFileName(),
+ mpFile(0),
+ mpTextStream(0)
+ {
+ }
+
+
+ FileAppender::FileAppender(Layout *pLayout,
+ const QString &rFileName,
+ QObject *pParent) :
+ WriterAppender(pLayout, pParent),
+ mAppendFile(false),
+ mBufferedIo(true),
+ mFileName(rFileName),
+ mpFile(0),
+ mpTextStream(0)
+ {
+ }
+
+
+ FileAppender::FileAppender(Layout *pLayout,
+ const QString &rFileName,
+ bool append,
+ QObject *pParent) :
+ WriterAppender(pLayout, pParent),
+ mAppendFile(append),
+ mBufferedIo(true),
+ mFileName(rFileName),
+ mpFile(0),
+ mpTextStream(0)
+ {
+ }
+
+
+ FileAppender::FileAppender(Layout *pLayout,
+ const QString &rFileName,
+ bool append,
+ bool buffered,
+ QObject *pParent) :
+ WriterAppender(pLayout, pParent),
+ mAppendFile(append),
+ mBufferedIo(buffered),
+ mFileName(rFileName),
+ mpFile(0),
+ mpTextStream(0)
+ {
+ }
+
+
+ FileAppender::~FileAppender()
+ {
+ close();
+ }
+
+
+ void FileAppender::activateOptions()
+ {
+ QMutexLocker locker(&mObjectGuard);
+
+ if (mFileName.isEmpty())
+ {
+ LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Activation of Appender '%1' that requires file and has no file set"),
+ APPENDER_ACTIVATE_MISSING_FILE_ERROR);
+ e << name();
+ logger()->error(e);
+ return;
+ }
+ closeFile();
+ openFile();
+ WriterAppender::activateOptions();
+ }
+
+
+ void FileAppender::close()
+ {
+ QMutexLocker locker(&mObjectGuard);
+
+ if (isClosed())
+ return;
+
+ WriterAppender::close();
+ closeFile();
+ }
+
+
+ bool FileAppender::checkEntryConditions() const
+ {
+ // Q_ASSERT_X(, "FileAppender::checkEntryConditions()", "Lock must be held by caller")
+
+ if (!mpFile || !mpTextStream)
+ {
+ LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Use of appender '%1' without open file"),
+ APPENDER_NO_OPEN_FILE_ERROR);
+ e << name();
+ logger()->error(e);
+ return false;
+ }
+
+ return WriterAppender::checkEntryConditions();
+ }
+
+
+ void FileAppender::closeFile()
+ {
+ // Q_ASSERT_X(, "FileAppender::closeFile()", "Lock must be held by caller")
+
+ if (mpFile)
+ logger()->debug("Closing file '%1' for appender '%2'", mpFile->fileName(), name());
+
+ setWriter(0);
+ delete mpTextStream;
+ mpTextStream = 0;
+ delete mpFile;
+ mpFile = 0;
+ }
+
+
+#ifndef QT_NO_DEBUG_STREAM
+ QDebug FileAppender::debug(QDebug &rDebug) const
+ {
+ QString layout_name;
+ if (layout())
+ layout_name = layout()->name();
+ QString codec_name;
+ if (encoding())
+ codec_name = QLatin1String(encoding()->name());
+
+ rDebug.nospace() << "FileAppender("
+ << "name:" << name() << " "
+ << "appendfile:" << appendFile() << " "
+ << "bufferedio:" << bufferedIo() << " "
+ << "encoding:" << codec_name << " "
+ << "file:" << file() << " "
+ << "filter:" << firstFilter() << " "
+ << "immediateflush:" << immediateFlush() << " "
+ << "isactive:" << isActive() << " "
+ << "isclosed:" << isClosed() << " "
+ << "layout:" << layout_name << " "
+ << "referencecount:" << referenceCount() << " "
+ << "threshold:" << threshold().toString() << " "
+ << "writer:" << writer()
+ << ")";
+ return rDebug.space();
+ }
+#endif // QT_NO_DEBUG_STREAM
+
+
+ bool FileAppender::handleIoErrors() const
+ {
+ // Q_ASSERT_X(, "FileAppender::handleIoErrors()", "Lock must be held by caller")
+
+ if (mpFile->error() == QFile::NoError)
+ return false;
+
+ LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Unable to write to file '%1' for appender '%2'"),
+ APPENDER_WRITING_FILE_ERROR);
+ e << mFileName << name();
+ e.addCausingError(LogError(mpFile->errorString(), mpFile->error()));
+ logger()->error(e);
+ return true;
+ }
+
+
+ void FileAppender::openFile()
+ {
+ Q_ASSERT_X(mpFile == 0 && mpTextStream == 0, "FileAppender::openFile()", "Opening file without closing previous file");
+
+ QFileInfo file_info(mFileName);
+ QDir parent_dir = file_info.dir();
+ if (!parent_dir.exists())
+ {
+ logger()->trace("Creating missing parent directory for file %1", mFileName);
+ QString name = parent_dir.dirName();
+ parent_dir.cdUp();
+ parent_dir.mkdir(name);
+ }
+
+
+ mpFile = new QFile(mFileName);
+ QFile::OpenMode mode = QIODevice::WriteOnly | QIODevice::Text;
+ if (mAppendFile)
+ mode |= QIODevice::Append;
+ else
+ mode |= QIODevice::Truncate;
+ if (!mBufferedIo)
+ mode |= QIODevice::Unbuffered;
+ if (!mpFile->open(mode))
+ {
+ LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Unable to open file '%1' for appender '%2'"),
+ APPENDER_OPENING_FILE_ERROR);
+ e << mFileName << name();
+ e.addCausingError(LogError(mpFile->errorString(), mpFile->error()));
+ logger()->error(e);
+ return;
+ }
+ mpTextStream = new QTextStream(mpFile);
+ setWriter(mpTextStream);
+ logger()->debug("Opened file '%1' for appender '%2'", mpFile->fileName(), name());
+ }
+
+
+ bool FileAppender::removeFile(QFile &rFile) const
+ {
+ if (rFile.remove())
+ return true;
+
+ LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Unable to remove file '%1' for appender '%2'"),
+ APPENDER_REMOVE_FILE_ERROR);
+ e << rFile.fileName() << name();
+ e.addCausingError(LogError(rFile.errorString(), rFile.error()));
+ logger()->error(e);
+ return false;
+ }
+
+
+ bool FileAppender::renameFile(QFile &rFile,
+ const QString &rFileName) const
+ {
+ logger()->debug("Renaming file '%1' to '%2'", rFile.fileName(), rFileName);
+ if (!rFileName.compare(rFile.fileName()))
+ return true;
+
+ if (rFile.rename(rFileName))
+ return true;
+
+ LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Unable to rename file '%1' to '%2' for appender '%3'"),
+ APPENDER_RENAMING_FILE_ERROR);
+ e << rFile.fileName() << rFileName << name();
+ e.addCausingError(LogError(rFile.errorString(), rFile.error()));
+ logger()->error(e);
+ return false;
+ }
+
+
+
+ /**************************************************************************
+ * Implementation: Operators, Helper
+ **************************************************************************/
+
+
+} // namespace Log4Qt
diff --git a/src/log4qt/log4qt/fileappender.h b/src/log4qt/log4qt/fileappender.h
new file mode 100644
index 0000000..29181ab
--- /dev/null
+++ b/src/log4qt/log4qt/fileappender.h
@@ -0,0 +1,233 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: fileappender.h
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef LOG4QT_FILEAPPENDER_H
+#define LOG4QT_FILEAPPENDER_H
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+#include "log4qt/writerappender.h"
+#include "ukui-logmacros.h"
+
+/******************************************************************************
+ * Declarations
+ ******************************************************************************/
+
+class QFile;
+class QTextStream;
+
+namespace Log4Qt
+{
+
+ /*!
+ * \brief The class FileAppender appends log events to a file.
+ *
+ * \note All the functions declared in this class are thread-safe.
+ *
+ * \note The ownership and lifetime of objects of this class are managed. See
+ * \ref Ownership "Object ownership" for more details.
+ */
+ class LIBUKUILOG4QT_EXPORT FileAppender : public WriterAppender
+ {
+ Q_OBJECT
+
+ /*!
+ * The property holds, if the output is appended to the file.
+ *
+ * The default is false for not appending.
+ *
+ * \sa appendFile(), setAppendFile()
+ */
+ Q_PROPERTY(bool appendFile READ appendFile WRITE setAppendFile)
+
+ /*!
+ * The property holds, if the output is buffered.
+ *
+ * The default is true for buffering.
+ *
+ * \sa bufferedIo(), setBufferedIo()
+ */
+ Q_PROPERTY(bool bufferedIo READ bufferedIo WRITE setBufferedIo)
+
+ /*!
+ * The property holds the name of the file.
+ *
+ * \sa file(), setFile()
+ */
+ Q_PROPERTY(QString file READ file WRITE setFile)
+
+ public:
+ FileAppender(QObject *pParent = 0);
+ FileAppender(Layout *pLayout,
+ const QString &rFileName,
+ QObject *pParent = 0);
+ FileAppender(Layout *pLayout,
+ const QString &rFileName,
+ bool append,
+ QObject *pParent = 0);
+ FileAppender(Layout *pLayout,
+ const QString &rFileName,
+ bool append,
+ bool buffered,
+ QObject *pParent = 0);
+ virtual ~FileAppender();
+ private:
+ FileAppender(const FileAppender &rOther); // Not implemented
+ FileAppender &operator=(const FileAppender &rOther); // Not implemented
+
+ public:
+ bool appendFile() const;
+ QString file() const;
+ bool bufferedIo() const;
+ // JAVA: int bufferSize() const;
+ void setAppendFile(bool append);
+ void setBufferedIo(bool buffered);
+ // JAVA: void setBufferSize(int bufferSize);
+ void setFile(const QString &rFileName);
+
+ virtual void activateOptions();
+ virtual void close();
+
+ protected:
+ /*!
+ * Tests if all entry conditions for using append() in this class are met.
+ *
+ * If a conditions is not met, an error is logged and the function returns
+ * false. Otherwise the result of WriterAppender::checkEntryConditions()
+ * is returned.
+ *
+ * The checked conditions are:
+ * - That a file is set and open (APPENDER_NO_OPEN_FILE_ERROR)
+ *
+ * The function is called as part of the checkEntryConditions() chain
+ * started by AppenderSkeleton::doAppend().
+ *
+ * \sa AppenderSkeleton::doAppend(), AppenderSkeleton::checkEntryConditions()
+ */
+ virtual bool checkEntryConditions() const;
+
+ void closeFile();
+
+#ifndef QT_NO_DEBUG_STREAM
+ /*!
+ * Writes all object member variables to the given debug stream \a rDebug
+ * and returns the stream.
+ *
+ *
+ * %FileAppender(name:"FA" appendfile:false bufferedio:true encoding:""
+ * file:"/log.txt" filter: 0x0 immediateflush:true isactive:false
+ * isclosed:false layout:"TTCC" referencecount:2
+ * threshold:"NULL" writer:0x0)
+ *
+ * \sa QDebug, operator<<(QDebug debug, const LogObject &rLogObject)
+ */
+ virtual QDebug debug(QDebug &rDebug) const;
+#endif // QT_NO_DEBUG_STREAM
+
+ /*!
+ * Checks for file I/O errrors. If an error is found it is logged and the
+ * function returns true. Otherwise false is returned.
+ */
+ virtual bool handleIoErrors() const;
+
+ /*!
+ * Opens the file for the appender based on the specified file name and
+ * mode. A text stream is created and passed on to the super class
+ * WriterAppender.
+ *
+ * If the parent directory of the specified file does not exists,
+ * it is created.
+ */
+ void openFile();
+
+ /*!
+ * Removes the file \a rFile. If the operation is successful, true is
+ * returned. Otherwise an APPENDER_REMOVE_FILE_ERROR error is logged
+ * and false is returned.
+ */
+ bool removeFile(QFile &rFile) const;
+
+ /*!
+ * Renames the file \a rFile to \a rFileName. If the operation is
+ * successful, true is returned. Otherwise an
+ * APPENDER_RENAMING_FILE_ERROR error is logged and false is returned.
+ */
+ bool renameFile(QFile &rFile,
+ const QString &rFileName) const;
+
+ // JAVA: void setQWForFiles(Writer writer);
+
+ private:
+ volatile bool mAppendFile;
+ volatile bool mBufferedIo;
+ QString mFileName;
+ QFile *mpFile;
+ QTextStream *mpTextStream;
+ };
+
+
+ /**************************************************************************
+ * Operators, Helper
+ **************************************************************************/
+
+
+ /**************************************************************************
+ * Inline
+ **************************************************************************/
+
+ inline bool FileAppender::appendFile() const
+ { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe
+ return mAppendFile; }
+
+ inline QString FileAppender::file() const
+ { QMutexLocker locker(&mObjectGuard);
+ return mFileName; }
+
+ inline bool FileAppender::bufferedIo() const
+ { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe
+ return mBufferedIo; }
+
+ inline void FileAppender::setAppendFile(bool append)
+ { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe
+ mAppendFile = append; }
+
+ inline void FileAppender::setBufferedIo(bool buffered)
+ { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe
+ mBufferedIo = buffered; }
+
+ inline void FileAppender::setFile(const QString &rFileName)
+ { QMutexLocker locker(&mObjectGuard);
+ mFileName = rFileName; }
+
+
+} // namespace Log4Qt
+
+
+// Q_DECLARE_TYPEINFO(Log4Qt::FileAppender, Q_COMPLEX_TYPE); // Use default
+
+
+#endif // LOG4QT_FILEAPPENDER_H
diff --git a/src/log4qt/log4qt/helpers/asyncdispatcher.cpp b/src/log4qt/log4qt/helpers/asyncdispatcher.cpp
new file mode 100644
index 0000000..b0b3e83
--- /dev/null
+++ b/src/log4qt/log4qt/helpers/asyncdispatcher.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+
+namespace Log4Qt
+{
+
+AsyncDispatcher::AsyncDispatcher(QObject *parent) : QObject(parent)
+ , mAsyncAppender(nullptr)
+{}
+
+void AsyncDispatcher::customEvent(QEvent *event)
+{
+ if (event->type() == LoggingEvent::eventId)
+ {
+ auto *logEvent = static_cast(event);
+ if (mAsyncAppender != nullptr)
+ mAsyncAppender->asyncAppend(*logEvent);
+ }
+ QObject::customEvent(event);
+}
+
+void AsyncDispatcher::setAsyncAppender(AppenderSkeleton *asyncAppender)
+{
+ mAsyncAppender = asyncAppender;
+}
+
+} // namespace Log4Qt
\ No newline at end of file
diff --git a/src/log4qt/log4qt/helpers/asyncdispatcher.h b/src/log4qt/log4qt/helpers/asyncdispatcher.h
new file mode 100644
index 0000000..91c30ce
--- /dev/null
+++ b/src/log4qt/log4qt/helpers/asyncdispatcher.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2021 Tianjin KYLIN Information Technology Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+#include "ukui-logmacros.h"
+
+namespace Log4Qt
+{
+
+class AppenderSkeleton;
+
+/*!
+ * \brief The class AsyncDispatcher does the actual logging to the attached appanders.
+ *
+ * The Dispatcher is the worker object which class the attached apperders in the
+ * the context of the AsyncDispatcherThread.
+ *
+ * \note All the functions declared in this class are thread-safe.
+ */
+class LIBUKUILOG4QT_EXPORT AsyncDispatcher : public QObject
+{
+ Q_OBJECT
+public:
+ explicit AsyncDispatcher(QObject *parent = nullptr);
+
+ void setAsyncAppender(AppenderSkeleton *asyncAppender);
+
+protected:
+ void customEvent(QEvent *event) override;
+
+private:
+ AppenderSkeleton *mAsyncAppender;
+};
+
+} // namespace Log4Qt
+
+#endif // LOG4QT_ASYNCDISPATCHER_H
diff --git a/src/log4qt/log4qt/helpers/classlogger.cpp b/src/log4qt/log4qt/helpers/classlogger.cpp
new file mode 100644
index 0000000..50b6c7f
--- /dev/null
+++ b/src/log4qt/log4qt/helpers/classlogger.cpp
@@ -0,0 +1,100 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: classlogger.cpp
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * changes: Sep 2008, Martin Heinrich:
+ * - Replaced usage of q_atomic_test_and_set_ptr with
+ * QAtomicPointer
+ *
+ *
+ * Copyright 2007 - 2008 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+
+#include "log4qt/helpers/classlogger.h"
+
+#include
+#include "log4qt/logmanager.h"
+
+
+namespace Log4Qt
+{
+
+
+ /**************************************************************************
+ * Declarations
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * C helper functions
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * Class implementation: ClassLogger
+ **************************************************************************/
+
+
+ ClassLogger::ClassLogger() :
+ mpLogger(0)
+ {
+ }
+
+
+ Logger *ClassLogger::logger(const QObject *pObject)
+ {
+ Q_ASSERT_X(pObject, "ClassLogger::logger()", "pObject must not be null");
+#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0)
+ if (!mpLogger)
+ q_atomic_test_and_set_ptr(&mpLogger,
+ 0,
+ LogManager::logger(QLatin1String(pObject->metaObject()->className())));
+ return const_cast(mpLogger);
+#elif QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ if (!static_cast(mpLogger))
+ mpLogger.testAndSetOrdered(0,
+ LogManager::logger(QLatin1String(pObject->metaObject()->className())));
+ return const_cast(static_cast(mpLogger));
+#else
+ if (!static_cast(mpLogger.loadAcquire()))
+ mpLogger.testAndSetOrdered(0,
+ LogManager::logger(QLatin1String(pObject->metaObject()->className())));
+ return const_cast(static_cast(mpLogger.loadAcquire()));
+#endif
+ }
+
+
+
+ /**************************************************************************
+ * Implementation: Operators, Helper
+ **************************************************************************/
+
+
+
+} // namespace Log4Qt
diff --git a/src/log4qt/log4qt/helpers/classlogger.h b/src/log4qt/log4qt/helpers/classlogger.h
new file mode 100644
index 0000000..9e10399
--- /dev/null
+++ b/src/log4qt/log4qt/helpers/classlogger.h
@@ -0,0 +1,117 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: classlogger.h
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * changes: Sep 2008, Martin Heinrich:
+ * - Replaced usage of q_atomic_test_and_set_ptr with
+ * QAtomicPointer
+ *
+ *
+ * Copyright 2007 - 2008 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef LOG4QT_CLASSLOGGER_H
+#define LOG4QT_CLASSLOGGER_H
+
+#include "ukui-logmacros.h"
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+#include
+#if QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)
+# include
+# ifndef Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
+# warning "QAtomicPointer test and set is not native. The class Log4Qt::ClassLogger is not thread-safe."
+# endif
+#endif
+
+
+/******************************************************************************
+ * Declarations
+ ******************************************************************************/
+
+namespace Log4Qt
+{
+ class Logger;
+
+ /*!
+ * \brief The class ClassLogger provides logging for a QObject derived
+ * class.
+ *
+ * The class ClassLogger provides a logger for a specified QObject derived
+ * object. It is used by \ref LOG4QT_DECLARE_QCLASS_LOGGER to implement the
+ * member functions provided by the macro.
+ *
+ * \note All the functions declared in this class are thread-safe.
+ *
+ * \sa LOG4QT_DECLARE_QCLASS_LOGGER
+ */
+ class LIBUKUILOG4QT_EXPORT ClassLogger
+ {
+ public:
+ /*!
+ * Creates a ClassLogger object.
+ */
+ ClassLogger();
+ // ~ClassLogger(); // Use compiler default
+ // ClassLogger(const ClassLogger &rOther); // Use compiler default
+ // ClassLogger &operator=(const ClassLogger &rOther); // Use compiler default
+
+ /*!
+ * Returns a pointer to a Logger named after the class of the object
+ * \a pObject.
+ *
+ * On the first invocation the Logger is requested by a call to
+ * LogManager::logger(const char *pName). The pointer is stored to be
+ * returned on subsequent invocations.
+ *
+ * \sa LogManager::logger(const char *pName)
+ */
+ Logger *logger(const QObject *pObject);
+
+ private:
+#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0)
+ volatile Logger *mpLogger;
+#else
+ mutable QAtomicPointer mpLogger;
+#endif
+ };
+
+
+ /******************************************************************************
+ * Operators, Helper
+ ******************************************************************************/
+
+
+ /**************************************************************************
+ * Inline
+ **************************************************************************/
+
+
+} // namespace Log4Qt
+
+
+// Q_DECLARE_TYPEinfo(Log4Qt::ClassLogger, Q_COMPLEX_TYPE); // Use default
+
+
+#endif // LOG4QT_CLASSLOGGER_H
diff --git a/src/log4qt/log4qt/helpers/configuratorhelper.cpp b/src/log4qt/log4qt/helpers/configuratorhelper.cpp
new file mode 100644
index 0000000..3b34f40
--- /dev/null
+++ b/src/log4qt/log4qt/helpers/configuratorhelper.cpp
@@ -0,0 +1,136 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: configuratorhelper.cpp
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+
+#include "log4qt/helpers/configuratorhelper.h"
+
+#include
+#include
+#include "log4qt/helpers/initialisationhelper.h"
+
+
+
+namespace Log4Qt
+{
+
+
+ /**************************************************************************
+ * Declarations
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * C helper functions
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * Class implementation: ConfiguratorHelper
+ **************************************************************************/
+
+
+ ConfiguratorHelper::ConfiguratorHelper() :
+ mObjectGuard(),
+ mConfigurationFile(),
+ mpConfigureFunc(0),
+ mpConfigurationFileWatch(0),
+ mConfigureError()
+ {
+ }
+
+
+ ConfiguratorHelper::~ConfiguratorHelper()
+ {
+ delete mpConfigurationFileWatch;
+ }
+
+
+ LOG4QT_IMPLEMENT_INSTANCE(ConfiguratorHelper)
+
+
+ void ConfiguratorHelper::doConfigurationFileChanged(const QString &rFileName)
+ {
+ QMutexLocker locker(&mObjectGuard);
+
+ if (!mpConfigureFunc)
+ return;
+ mpConfigureFunc(rFileName);
+ // Shall we hold the lock while emitting the signal?
+ emit configurationFileChanged(rFileName, mConfigureError.count() > 0);
+ }
+
+
+
+ void ConfiguratorHelper::doSetConfigurationFile(const QString &rFileName,
+ ConfigureFunc pConfigureFunc)
+ {
+ QMutexLocker locker(&mObjectGuard);
+
+ mConfigurationFile.clear();
+ mpConfigureFunc = 0;
+ delete mpConfigurationFileWatch;
+ if (rFileName.isEmpty())
+ return;
+
+ mConfigurationFile = rFileName;
+ mpConfigureFunc = pConfigureFunc;
+ mpConfigurationFileWatch = new QFileSystemWatcher();
+ mpConfigurationFileWatch->addPath(rFileName);
+ connect(mpConfigurationFileWatch,
+ SIGNAL(fileChanged(const QString &)),
+ SLOT(configurationFileChanged(const QString &)));
+ }
+
+
+
+ /**************************************************************************
+ * Implementation: Operators, Helper
+ **************************************************************************/
+
+
+#ifndef QT_NO_DEBUG_STREAM
+ QDebug operator<<(QDebug debug,
+ const ConfiguratorHelper &rConfiguratorHelper)
+ {
+ debug.nospace() << "ConfiguratorHelper("
+ << "configurationfile:" << ConfiguratorHelper::configurationFile()
+ << "configurefunc:" << rConfiguratorHelper.mpConfigureFunc
+ << "filesystemwatcher:" << rConfiguratorHelper.mpConfigurationFileWatch
+ << ")";
+ return debug.space();
+ }
+#endif // QT_NO_DEBUG_STREAM
+
+
+
+} // namespace Log4Qt
+
diff --git a/src/log4qt/log4qt/helpers/configuratorhelper.h b/src/log4qt/log4qt/helpers/configuratorhelper.h
new file mode 100644
index 0000000..fd55252
--- /dev/null
+++ b/src/log4qt/log4qt/helpers/configuratorhelper.h
@@ -0,0 +1,211 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: configuratorhelper.h
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef LOG4QT_HELPERS_CONFIGURATORHELPER_H
+#define LOG4QT_HELPERS_CONFIGURATORHELPER_H
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+#include
+
+#include
+#include
+#include "log4qt/loggingevent.h"
+#include "ukui-logmacros.h"
+
+
+/******************************************************************************
+ * Declarations
+ ******************************************************************************/
+
+class QFileSystemWatcher;
+
+
+namespace Log4Qt
+{
+
+ /*!
+ * \brief The class ConfiguratorHelper provides a confiuration file watch
+ * and last error for configurator classes.
+ *
+ * A configuration file can be set using setConfigurationFile(). The file
+ * is watched for changes. If a change occurs the configuration is reloaded
+ * and the ConfigurationFileChanged() signal is emitted. Error information
+ * for the last call to a configure function or the last configuration file
+ * change can be accessed using configureError().
+ *
+ * \note All the functions declared in this class are thread-safe.
+ */
+ class LIBUKUILOG4QT_EXPORT ConfiguratorHelper : public QObject
+ {
+ Q_OBJECT
+
+ public:
+ /*!
+ * Prototype for a configure callback function. The function is called
+ * when then configuration file is changed and takes the
+ * configuration file as a parameter.
+ *
+ * \sa setConfigurationFile(),
+ * PropertyConfigurator::configure(const QString &)
+ */
+ typedef bool (*ConfigureFunc)(const QString &rFileName);
+
+ private:
+ ConfiguratorHelper();
+ ConfiguratorHelper(const ConfiguratorHelper &rOther); // Not implemented
+ virtual ~ConfiguratorHelper();
+ ConfiguratorHelper &operator=(const ConfiguratorHelper &rOther); // Not implemented
+
+ public:
+
+ /*!
+ * Returns the error information for the last configuration operation
+ * that took place. The configuration operation could be the result of
+ * a call to one of the configure methods or through a change
+ * to the configuration file.
+ *
+ * \sa setConfigureError(), PropertyConfigurator::configure(),
+ * setConfigurationFile()
+ */
+ static QList configureError();
+
+ /*!
+ * Returns the current configuration file.
+ *
+ * \sa setConfigurationFile()
+ */
+ static QString configurationFile();
+
+ /*!
+ * Returns the ConfiguratorHelper instance.
+ */
+ static ConfiguratorHelper *instance();
+
+ /*!
+ * Sets the configuration error information for the last configuration
+ * operation.
+ *
+ * \sa configureError()
+ */
+ static void setConfigureError(const QList &rConfigureError);
+
+ /*!
+ * Sets the configuration file to \a rFileName. The file is watched for
+ * changes. On a file change the function \a pConfigureFunc will be called
+ * and the signal configurationFileChange() will be emitted.
+ *
+ * Setting the configuration file to an empty string stops the file watch.
+ *
+ * \sa configurationFile(), PropertyConfigurator::configureAndWatch(),
+ * configureError()
+ */
+ static void setConfigurationFile(const QString &rFileName = QString(),
+ ConfigureFunc pConfigureFunc = 0);
+
+ signals:
+ /*!
+ * The signal is emitted after a change to the file \a rFileName
+ * was processed. If an error occured during the configuration, the
+ * flag \a error will be true and error information is available
+ * over configureError().
+ */
+ void configurationFileChanged(const QString &rFileName,
+ bool error);
+
+ private slots:
+ void doConfigurationFileChanged(const QString &rFileName);
+
+ private:
+ void doSetConfigurationFile(const QString &rFileName,
+ ConfigureFunc pConfigureFunc);
+
+ private:
+ mutable QMutex mObjectGuard;
+ QString mConfigurationFile;
+ ConfigureFunc mpConfigureFunc;
+ QFileSystemWatcher *mpConfigurationFileWatch;
+ QList mConfigureError;
+
+#ifndef QT_NO_DEBUG_STREAM
+ // Needs to be friend to access details
+ friend QDebug operator<<(QDebug debug,
+ const ConfiguratorHelper &rConfiguratorHelper);
+#endif // QT_NO_DEBUG_STREAM
+ };
+
+
+ /**************************************************************************
+ * Operators, Helper
+ **************************************************************************/
+
+#ifndef QT_NO_DEBUG_STREAM
+ /*!
+ * \relates ConfiguratorHelper
+ *
+ * Writes all object member variables to the given debug stream \a rDebug and
+ * returns the stream.
+ *
+ *
+ * %ConfiguratorHelper(configurationfile: "" configurefunc: false
+ * filesystemwatcher: QObject(0x0) )
+ *
+ * \sa QDebug, ConfiguratorHelper::logManager()
+ */
+ QDebug operator<<(QDebug debug,
+ const ConfiguratorHelper &rConfiguratorHelper);
+#endif // QT_NO_DEBUG_STREAM
+
+
+
+ /**************************************************************************
+ * Inline
+ **************************************************************************/
+
+ inline QList ConfiguratorHelper::configureError()
+ { QMutexLocker locker(&instance()->mObjectGuard);
+ return instance()->mConfigureError; }
+
+ inline QString ConfiguratorHelper::configurationFile()
+ { QMutexLocker locker(&instance()->mObjectGuard);
+ return instance()->mConfigurationFile; }
+
+ inline void ConfiguratorHelper::setConfigureError(const QList &rConfigureError)
+ { QMutexLocker locker(&instance()->mObjectGuard);
+ instance()->mConfigureError = rConfigureError; }
+
+ inline void ConfiguratorHelper::setConfigurationFile(const QString &rFileName,
+ ConfigureFunc pConfigureFunc)
+ { instance()->doSetConfigurationFile(rFileName, pConfigureFunc); }
+
+} // namespace Log4Qt
+
+
+// Q_DECLARE_TYPEINFO(Log4Qt::ConfiguratorHelper, Q_COMPLEX_TYPE); // use default
+
+
+#endif // LOG4QT_HELPERS_CONFIGURATORHELPER_H
diff --git a/src/log4qt/log4qt/helpers/datetime.cpp b/src/log4qt/log4qt/helpers/datetime.cpp
new file mode 100644
index 0000000..1fb7d87
--- /dev/null
+++ b/src/log4qt/log4qt/helpers/datetime.cpp
@@ -0,0 +1,326 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: datetime.cpp
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+
+#include "log4qt/helpers/datetime.h"
+
+#include
+#include "log4qt/helpers/initialisationhelper.h"
+
+
+
+namespace Log4Qt
+{
+
+
+ /**************************************************************************
+ *Declarations
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * C helper functions
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * Class implementation: DateTime
+ **************************************************************************/
+
+
+ QString DateTime::toString(const QString &rFormat) const
+ {
+ QString format(rFormat);
+
+ if (format.isEmpty())
+ return QString();
+ if (!isValid())
+ return QString();
+ if (format == QLatin1String("NONE"))
+ return QString();
+
+ if (format == QLatin1String("TIME_RELATIVE"))
+ return QString::number(toMilliSeconds() - InitialisationHelper::startTime());
+
+ if (format == QLatin1String("ISO8601"))
+ format = QLatin1String("yyyy-MM-dd hh:mm:ss.zzz");
+ if (format == QLatin1String("TIME_ABSOLUTE"))
+ format = QLatin1String("HH:mm:ss.zzz");
+ if (format == QLatin1String("DATE"))
+ format = QLatin1String("dd MMM YYYY HH:mm:ss.zzzz");
+
+ return formatDateTime(format);
+ }
+
+
+ QString DateTime::formatDateTime(const QString &rFormat) const
+ {
+ if (rFormat.isEmpty())
+ return QString();
+ if (!isValid())
+ return QString();
+
+ const QLatin1Char null('0');
+ const QLatin1Char quote('\'');
+ const QString tokens = QLatin1String("\'dMyhHmszAPapw");
+ const bool am_pm = hasAMPM(rFormat);
+
+ QString result;
+ QString token;
+ QChar expected = null;
+
+ QChar c;
+ int i;
+ for (i = 0; i < rFormat.length(); i++)
+ {
+ c = rFormat.at(i);
+
+ // Handle literal text
+ if (expected == quote)
+ {
+ if (c == quote)
+ {
+ Q_ASSERT_X(i > 0, "DateTime::toString()", "Found quote with status quote at i = 0");
+ if (i > 0 && rFormat.at(i - 1) == quote)
+ // Second of two quotes
+ result += quote;
+ expected = null;
+ }
+ else
+ // Next literal character
+ result += c;
+ }
+ else if (c == expected)
+ {
+ // Extend token
+ token += c;
+ }
+ else
+ {
+ // Close last token
+ result += formatToken(token, am_pm);
+ token.clear();
+ expected = null;
+
+ // Test for valid character
+ if (tokens.indexOf(c) >= 0)
+ {
+ if (c == QLatin1Char('a'))
+ expected = QLatin1Char('p');
+ else if (c == QLatin1Char('A'))
+ expected = QLatin1Char('P');
+ else if (c.toLower() == QLatin1Char('p'))
+ expected = null;
+ else
+ expected = c;
+ if (c != quote)
+ token += c;
+ } else
+ result += c;
+ }
+ }
+
+ result += formatToken(token, am_pm);
+ return result;
+ }
+
+
+ QString DateTime::formatToken(const QString &rToken, bool am_pm) const
+ {
+ if (rToken.isEmpty())
+ return QString();
+
+ const QChar c = rToken.at(0);
+ QString result;
+ int used = 0;
+
+ // Qt data format strings
+ if (rToken.startsWith(QLatin1String("dddd")))
+ {
+ result = QDate::longDayName(date().dayOfWeek());
+ used = 4;
+ }
+ else if (rToken.startsWith(QLatin1String("ddd")))
+ {
+ result = QDate::shortDayName(date().dayOfWeek());
+ used = 3;
+ }
+ else if (rToken.startsWith(QLatin1String("dd")))
+ {
+ result = QString::number(date().day()).rightJustified(2, QLatin1Char('0'), true);
+ used = 2;
+ }
+ else if (c == QLatin1Char('d'))
+ {
+ result = QString::number(date().day());
+ used = 1;
+ }
+ else if (rToken.startsWith(QLatin1String("MMMM")))
+ {
+ result = QDate::longMonthName(date().month());
+ used = 4;
+ }
+ else if (rToken.startsWith(QLatin1String("MMM")))
+ {
+ result = QDate::shortMonthName(date().month());
+ used = 3;
+ }
+ else if (rToken.startsWith(QLatin1String("MM")))
+ {
+ result = QString::number(date().month()).rightJustified(2, QLatin1Char('0'), true);
+ used = 2;
+ }
+ else if (c == QLatin1Char('M'))
+ {
+ result = QString::number(date().month());
+ used = 1;
+ }
+ else if (rToken.startsWith(QLatin1String("yyyy")))
+ {
+ result = QString::number(date().year());
+ used = 4;
+ }
+ else if (rToken.startsWith(QLatin1String("yy")))
+ {
+ result = QString::number(date().year() % 100).rightJustified(2, QLatin1Char('0'), true);
+ used = 2;
+ }
+
+ // Qt time format strings
+ else if (rToken.startsWith(QLatin1String("hh")) || rToken.startsWith(QLatin1String("HH")))
+ {
+ int hour = time().hour();
+ if (am_pm && c == QLatin1Char('h') && hour > 12)
+ hour -= 12;
+ result = QString::number(hour).rightJustified(2, QLatin1Char('0'), true);
+ used = 2;
+ }
+ else if (c == QLatin1Char('h') || c == QLatin1Char('H'))
+ {
+ int hour = time().hour();
+ if (am_pm && c == QLatin1Char('h') && hour > 12)
+ hour -= 12;
+ result = QString::number(hour);
+ used = 2;
+ }
+ else if (rToken.startsWith(QLatin1String("mm")))
+ {
+ result = QString::number(time().minute()).rightJustified(2, QLatin1Char('0'), true);
+ used = 2;
+ }
+ else if (c == (QLatin1Char('m')))
+ {
+ result = QString::number(time().minute());
+ used = 1;
+ }
+ else if (rToken.startsWith(QLatin1String("ss")))
+ {
+ result = QString::number(time().second()).rightJustified(2, QLatin1Char('0'), true);
+ used = 2;
+ }
+ else if (c == QLatin1Char('s'))
+ {
+ result = QString::number(time().second());
+ used = 1;
+ }
+ else if (rToken.startsWith(QLatin1String("zzz")))
+ {
+ result = QString::number(time().msec()).rightJustified(3, QLatin1Char('0'), true);
+ used = 3;
+ }
+ else if (c == QLatin1Char('z'))
+ {
+ result = QString::number(time().msec());
+ used = 1;
+ }
+ else if (c.toLower() == QLatin1Char('a'))
+ {
+ bool is_lower = c == QLatin1Char('a');
+ if (time().hour() < 12)
+ result = QLatin1String("AM");
+ else
+ result = QLatin1String("PM");
+ if (is_lower)
+ result = result.toLower();
+ if (rToken.size() > 1 &&
+ ((is_lower && rToken.at(1) == QLatin1Char('p')) ||
+ (!is_lower && rToken.at(1) == QLatin1Char('P')))
+ )
+ used = 2;
+ else
+ used = 1;
+ }
+
+ // Extension for week number
+ else if (rToken.startsWith(QLatin1String("ww")))
+ {
+ result = QString::number(date().weekNumber()).rightJustified(2, QLatin1Char('0'), true);
+ used = 2;
+ }
+ else if (c == QLatin1Char('w'))
+ {
+ result = QString::number(date().weekNumber());
+ used = 1;
+ }
+
+ if (used)
+ return result + formatToken(rToken.mid(used), am_pm);
+ else
+ return result;
+ }
+
+
+ bool DateTime::hasAMPM(const QString &rToken)
+ {
+ bool in_literal = false;
+ QChar c;
+ int i;
+ for (i = 0; i < rToken.length(); i++)
+ {
+ c = rToken.at(i);
+ if (c == QLatin1Char('\''))
+ in_literal = !in_literal;
+ else if (!in_literal && c.toLower() == QLatin1Char('a'))
+ return true;
+ }
+ return false;
+ }
+
+
+
+ /**************************************************************************
+ * Implementation: Operators, Helper
+ **************************************************************************/
+
+
+
+} // namespace Log4Qt
diff --git a/src/log4qt/log4qt/helpers/datetime.h b/src/log4qt/log4qt/helpers/datetime.h
new file mode 100644
index 0000000..e9c79ce
--- /dev/null
+++ b/src/log4qt/log4qt/helpers/datetime.h
@@ -0,0 +1,213 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: datetime.h
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * changes: Sep 2008, Martin Heinrich:
+ * - Resolved compilation problem with Microsoft Visual Studio 2005
+ *
+ *
+ * Copyright 2007 - 2008 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef LOG4QT_HELPERS_DATETIME_H
+#define LOG4QT_HELPERS_DATETIME_H
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+#include
+#include "ukui-logmacros.h"
+
+
+/******************************************************************************
+ * Declarations
+ ******************************************************************************/
+
+
+namespace Log4Qt
+{
+
+ /*!
+ * \brief The class DateTime provides extended functionality for QDateTime.
+ *
+ * The class DateTime implements additional formatting options for
+ * toString() and provides conversion functions from and to milliseconds.
+ */
+ class LIBUKUILOG4QT_EXPORT DateTime : public QDateTime
+ {
+ public:
+ /*!
+ * Constructs a null date time.
+ *
+ * \sa QDateTime::QDateTime()
+ */
+ DateTime();
+
+ // DateTime(const DateTime &rOther); // Use compiler default
+
+ /*!
+ * Constructs a copy of another QDateTime.
+ *
+ * \sa QDateTime::QDateTime(const QDateTime &rOther)
+ */
+ DateTime(const QDateTime &rOther);
+
+ /*!
+ * Constructs a datetime with the given \a rDate and \a rTime, using
+ * the time specification defined by \a timeSpec.
+ *
+ * \sa QDateTime::QDateTime(const QDate &rDate, const QTime &rTime,
+ * Qt::TimeSpec timeSpec = Qt::LocalTime)
+ */
+ DateTime(const QDate &rDate,
+ const QTime &rTime,
+ Qt::TimeSpec timeSpec = Qt::LocalTime);
+
+ // virtual ~DateTime(); // Use compiler default
+
+ /*!
+ * Assigns \a rOther to this DateTime and returns a reference to it.
+ */
+ DateTime &operator=(const DateTime &rOther);
+
+ /*!
+ * Returns the datetime as the number of milliseconds that have passed
+ * since 1970-01-01T00:00:00,000, Coordinated Universal Time (Qt::UTC).
+ *
+ * \sa QDateTime::toTime_t()
+ */
+ qint64 toMilliSeconds() const;
+
+ /*!
+ * Returns the datetime as a string. The \a rFormat parameter
+ * determines the format of the result string.
+ *
+ * In addition to the expressions of QDateTime::toString(const QString
+ * &rFormat) the following expression can be used.
+ *
+ *
+ *
+ *
Expression
+ *
Output
+ *
+ *
w
+ *
the week of the year as number without a leading zero (1 to 53)
+ *
+ *
ww
+ *
the week of the year as number with a leading zero (01 to 53)
+ *
+ *
+ *
+ * Alternatively the \a rFormat parameter can specify one of the
+ * following strings.
+ *
+ *
+ *
+ *
String
+ *
Format
+ *
+ *
TIME_ABSOLUTE
+ *
uses the format HH:mm:ss.zzz
+ *
+ *
DATE
+ *
uses the format dd MMM YYYY HH:mm:ss.zzzz
+ *
+ *
ISO8601
+ *
uses the format yyyy-MM-dd hh:mm:ss.zzz
+ *
+ *
NONE
+ *
uses an empty string as format
+ *
+ *
TIME_RELATIVE
+ *
returns the milliseconds since start of the program
+ *
+ *
+ *
+ * \sa QDateTime::toString(const QString &rFormat)
+ */
+ QString toString(const QString &rFormat) const;
+
+ /*!
+ * Returns the current datetime, as reported by the system clock, in
+ * the local time zone.
+ *
+ * \sa QDateTime::currentDateTime()
+ */
+ static DateTime currentDateTime();
+
+ /*!
+ * Returns a datetime whose date and time are the number of
+ * milliseconds that have passed since 1970-01-01T00:00:00,
+ * Coordinated Universal Time (Qt::UTC).
+ *
+ * \sa QDateTime::fromTime_t(uint seconds)
+ */
+ static DateTime fromMilliSeconds(qint64 milliSeconds);
+
+ private:
+ QString formatDateTime(const QString &rFormat) const;
+ QString formatToken(const QString &rToken, bool am_pm) const;
+ static bool hasAMPM(const QString &rFormat);
+ };
+
+
+ /**************************************************************************
+ * Operators, Helper
+ **************************************************************************/
+
+
+ /**************************************************************************
+ * Inline
+ **************************************************************************/
+
+ inline DateTime::DateTime() : QDateTime()
+ {}
+
+ inline DateTime::DateTime(const QDateTime &rOther) : QDateTime(rOther)
+ {}
+
+ inline DateTime::DateTime(const QDate &rDate,
+ const QTime &rTime,
+ Qt::TimeSpec timeSpec) :
+ QDateTime(rDate, rTime, timeSpec)
+ {}
+
+ inline DateTime &DateTime::operator=(const DateTime &rOther)
+ { QDateTime::operator=(rOther); return *this; }
+
+ inline qint64 DateTime::toMilliSeconds() const
+ { return (qint64)1000 * toTime_t() + time().msec(); }
+
+ inline DateTime DateTime::currentDateTime()
+ { return DateTime(QDateTime::currentDateTime()); }
+
+ inline DateTime DateTime::fromMilliSeconds(qint64 milliSeconds)
+ { return DateTime(QDateTime::fromTime_t(milliSeconds / 1000).addMSecs(milliSeconds % 1000)); }
+
+
+} // namespace Log4Qt
+
+
+Q_DECLARE_TYPEINFO(Log4Qt::DateTime, Q_MOVABLE_TYPE);
+
+
+#endif // LOG4QT_HELPERS_DATETIME_H
diff --git a/src/log4qt/log4qt/helpers/factory.cpp b/src/log4qt/log4qt/helpers/factory.cpp
new file mode 100644
index 0000000..bf2f449
--- /dev/null
+++ b/src/log4qt/log4qt/helpers/factory.cpp
@@ -0,0 +1,459 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: factory.cpp
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+
+#include "log4qt/helpers/factory.h"
+
+#include
+#include
+#include
+#include "log4qt/consoleappender.h"
+#include "log4qt/dailyrollingfileappender.h"
+#include "log4qt/fileappender.h"
+#include "log4qt/helpers/logerror.h"
+#include "log4qt/helpers/initialisationhelper.h"
+#include "log4qt/helpers/optionconverter.h"
+#include "log4qt/patternlayout.h"
+#include "log4qt/rollingfileappender.h"
+#include "log4qt/simplelayout.h"
+#include "log4qt/ttcclayout.h"
+#include "log4qt/varia/debugappender.h"
+#include "log4qt/varia/denyallfilter.h"
+#include "log4qt/varia/levelmatchfilter.h"
+#include "log4qt/varia/levelrangefilter.h"
+#include "log4qt/varia/listappender.h"
+#include "log4qt/varia/nullappender.h"
+#include "log4qt/varia/stringmatchfilter.h"
+
+
+
+namespace Log4Qt
+{
+
+
+ /**************************************************************************
+ * Declarations
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * C helper functions
+ **************************************************************************/
+
+
+ LOG4QT_DECLARE_STATIC_LOGGER(logger, Log4Qt::Factory)
+
+
+ // Appenders
+
+ Appender *console_file_appender()
+ { return new ConsoleAppender; }
+
+ Appender *create_daily_rolling_file_appender()
+ { return new DailyRollingFileAppender; }
+
+ Appender *create_debug_appender()
+ { return new DebugAppender; }
+
+ Appender *create_file_appender()
+ { return new FileAppender; }
+
+ Appender *create_list_appender()
+ { return new ListAppender; }
+
+ Appender *create_null_appender()
+ { return new NullAppender; }
+
+ Appender *create_rolling_file_appender()
+ { return new RollingFileAppender; }
+
+
+ // Filters
+
+ Filter *create_deny_all_filter()
+ { return new DenyAllFilter; }
+
+ Filter *create_level_match_filter()
+ { return new LevelMatchFilter; }
+
+ Filter *create_level_range_filter()
+ { return new LevelRangeFilter; }
+
+ Filter *create_string_match_filter()
+ { return new StringMatchFilter; }
+
+
+ // Layouts
+
+ Layout *create_pattern_layout()
+ { return new PatternLayout; }
+
+ Layout *create_simple_layout()
+ { return new SimpleLayout; }
+
+ Layout *create_ttcc_layout()
+ { return new TTCCLayout; }
+
+
+
+ /**************************************************************************
+ * Class implementation: Factory
+ **************************************************************************/
+
+
+ Factory::Factory() :
+ mObjectGuard(),
+ mAppenderRegistry(),
+ mFilterRegistry(),
+ mLayoutRegistry()
+ {
+ registerDefaultAppenders();
+ registerDefaultFilters();
+ registerDefaultLayouts();
+ }
+
+
+ LOG4QT_IMPLEMENT_INSTANCE(Factory)
+
+
+ Appender *Factory::doCreateAppender(const QString &rAppenderClassName)
+ {
+ QMutexLocker locker(&mObjectGuard);
+
+ if (!mAppenderRegistry.contains(rAppenderClassName))
+ {
+ logger()->warn("Request for the creation of Appender with class '%1', which is not registered", rAppenderClassName);
+ return 0;
+ }
+ return mAppenderRegistry.value(rAppenderClassName)();
+ }
+
+
+ Filter *Factory::doCreateFilter(const QString &rFilterClassName)
+ {
+ QMutexLocker locker(&mObjectGuard);
+
+ if (!mFilterRegistry.contains(rFilterClassName))
+ {
+ logger()->warn("Request for the creation of Filter with class '%1', which is not registered", rFilterClassName);
+ return 0;
+ }
+ return mFilterRegistry.value(rFilterClassName)();
+ }
+
+
+ Layout *Factory::doCreateLayout(const QString &rLayoutClassName)
+ {
+ QMutexLocker locker(&mObjectGuard);
+
+ if (!mLayoutRegistry.contains(rLayoutClassName))
+ {
+ logger()->warn("Request for the creation of Layout with class '%1', which is not registered", rLayoutClassName);
+ return 0;
+ }
+ return mLayoutRegistry.value(rLayoutClassName)();
+ }
+
+
+ void Factory::doRegisterAppender(const QString &rAppenderClassName,
+ AppenderFactoryFunc pAppenderFactoryFunc)
+ {
+ QMutexLocker locker(&mObjectGuard);
+
+ if(rAppenderClassName.isEmpty())
+ {
+ logger()->warn("Registering Appender factory function with empty class name");
+ return;
+ }
+ mAppenderRegistry.insert(rAppenderClassName, pAppenderFactoryFunc);
+ }
+
+
+ void Factory::doRegisterFilter(const QString &rFilterClassName,
+ FilterFactoryFunc pFilterFactoryFunc)
+ {
+ QMutexLocker locker(&mObjectGuard);
+
+ if(rFilterClassName.isEmpty())
+ {
+ logger()->warn("Registering Filter factory function with empty class name");
+ return;
+ }
+ mFilterRegistry.insert(rFilterClassName, pFilterFactoryFunc);
+ }
+
+
+ void Factory::doRegisterLayout(const QString &rLayoutClassName,
+ LayoutFactoryFunc pLayoutFactoryFunc)
+ {
+ QMutexLocker locker(&mObjectGuard);
+
+ if(rLayoutClassName.isEmpty())
+ {
+ logger()->warn("Registering Layout factory function with empty class name");
+ return;
+ }
+ mLayoutRegistry.insert(rLayoutClassName, pLayoutFactoryFunc);
+ }
+
+
+ void Factory::doSetObjectProperty(QObject *pObject,
+ const QString &rProperty,
+ const QString &rValue)
+ {
+ // - Validate property
+ // - Get correct property name from meta object
+ // - Find specific property setter
+ // - If no specfifc propery setter can be found,
+ // find general property setter
+ // - Call property setter
+
+ QMetaProperty meta_property;
+ if (!validateObjectProperty(meta_property, rProperty, pObject))
+ return;
+
+ QString property = QLatin1String(meta_property.name());
+ QString type = QLatin1String(meta_property.typeName());
+ logger()->debug("Setting property '%1' on object of class '%2' to value '%3'",
+ property,
+ QLatin1String(pObject->metaObject()->className()),
+ rValue);
+
+ QVariant value;
+ bool ok = true;
+ if (type == QLatin1String("bool"))
+ value = OptionConverter::toBoolean(rValue, &ok);
+ else if (type == QLatin1String("int"))
+ value = OptionConverter::toInt(rValue, &ok);
+ else if (type == QLatin1String("qint64") || type == QLatin1String("qlonglong"))
+ value = OptionConverter::toQInt64(rValue, &ok);
+ else if (type == QLatin1String("Log4Qt::Level"))
+ value = QVariant::fromValue(OptionConverter::toLevel(rValue, &ok));
+ else if (type == QLatin1String("QString"))
+ value = rValue;
+ else
+ {
+ LogError e = LOG4QT_ERROR(QT_TR_NOOP("Cannot convert to type '%1' for property '%2' on object of class '%3'"),
+ CONFIGURATOR_UNKNOWN_TYPE_ERROR,
+ "Log4Qt::Factory");
+ e << type
+ << property
+ << QString::fromLatin1(pObject->metaObject()->className());
+ logger()->error(e);
+ return;
+ }
+ if (!ok)
+ return;
+
+ // Everything is checked and the type is the one of the property.
+ // Write should never return false
+ if (!meta_property.write(pObject, value))
+ logger()->warn("Unxpected error result from QMetaProperty.write()");
+ }
+
+
+ void Factory::doUnregisterAppender(const QString &rAppenderClassName)
+ {
+ QMutexLocker locker(&mObjectGuard);
+
+ if (!mAppenderRegistry.contains(rAppenderClassName))
+ {
+ logger()->warn("Request to unregister not registered Appender factory function for class '%1'", rAppenderClassName);
+ return;
+ }
+ mAppenderRegistry.remove(rAppenderClassName);
+ }
+
+
+ void Factory::doUnregisterFilter(const QString &rFilterClassName)
+ {
+ QMutexLocker locker(&mObjectGuard);
+
+ if (!mFilterRegistry.contains(rFilterClassName))
+ {
+ logger()->warn("Request to unregister not registered Filter factory function for class '%1'", rFilterClassName);
+ return;
+ }
+ mFilterRegistry.remove(rFilterClassName);
+ }
+
+
+ void Factory::doUnregisterLayout(const QString &rLayoutClassName)
+ {
+ QMutexLocker locker(&mObjectGuard);
+
+ if (!mLayoutRegistry.contains(rLayoutClassName))
+ {
+ logger()->warn("Request to unregister not registered Layout factory function for class '%1'", rLayoutClassName);
+ return;
+ }
+ mLayoutRegistry.remove(rLayoutClassName);
+ }
+
+
+ void Factory::registerDefaultAppenders()
+ {
+ mAppenderRegistry.insert(QLatin1String("org.apache.log4j.ConsoleAppender"), console_file_appender);
+ mAppenderRegistry.insert(QLatin1String("Log4Qt::ConsoleAppender"), console_file_appender);
+ mAppenderRegistry.insert(QLatin1String("org.apache.log4j.DailyRollingFileAppender"), create_daily_rolling_file_appender);
+ mAppenderRegistry.insert(QLatin1String("Log4Qt::DailyRollingFileAppender"), create_daily_rolling_file_appender);
+ mAppenderRegistry.insert(QLatin1String("org.apache.log4j.varia.DebugAppender"), create_debug_appender);
+ mAppenderRegistry.insert(QLatin1String("Log4Qt::DebugAppender"), create_debug_appender);
+ mAppenderRegistry.insert(QLatin1String("org.apache.log4j.FileAppender"), create_file_appender);
+ mAppenderRegistry.insert(QLatin1String("Log4Qt::FileAppender"), create_file_appender);
+ mAppenderRegistry.insert(QLatin1String("org.apache.log4j.varia.ListAppender"), create_list_appender);
+ mAppenderRegistry.insert(QLatin1String("Log4Qt::ListAppender"), create_list_appender);
+ mAppenderRegistry.insert(QLatin1String("org.apache.log4j.varia.NullAppender"), create_null_appender);
+ mAppenderRegistry.insert(QLatin1String("Log4Qt::NullAppender"), create_null_appender);
+ mAppenderRegistry.insert(QLatin1String("org.apache.log4j.RollingFileAppender"), create_rolling_file_appender);
+ mAppenderRegistry.insert(QLatin1String("Log4Qt::RollingFileAppender"), create_rolling_file_appender);
+ }
+
+
+ void Factory::registerDefaultFilters()
+ {
+ mFilterRegistry.insert(QLatin1String("org.apache.log4j.varia.DenyAllFilter"), create_deny_all_filter);
+ mFilterRegistry.insert(QLatin1String("Log4Qt::DenyAllFilter"), create_deny_all_filter);
+ mFilterRegistry.insert(QLatin1String("org.apache.log4j.varia.LevelMatchFilter"), create_level_match_filter);
+ mFilterRegistry.insert(QLatin1String("Log4Qt::LevelMatchFilter"), create_level_match_filter);
+ mFilterRegistry.insert(QLatin1String("org.apache.log4j.varia.LevelRangeFilter"), create_level_range_filter);
+ mFilterRegistry.insert(QLatin1String("Log4Qt::LevelRangeFilter"), create_level_range_filter);
+ mFilterRegistry.insert(QLatin1String("org.apache.log4j.varia.StringMatchFilter"), create_string_match_filter);
+ mFilterRegistry.insert(QLatin1String("Log4Qt::StringMatchFilter"), create_string_match_filter);
+ }
+
+
+ void Factory::registerDefaultLayouts()
+ {
+ mLayoutRegistry.insert(QLatin1String("org.apache.log4j.PatternLayout"), create_pattern_layout);
+ mLayoutRegistry.insert(QLatin1String("Log4Qt::PatternLayout"), create_pattern_layout);
+ mLayoutRegistry.insert(QLatin1String("org.apache.log4j.SimpleLayout"), create_simple_layout);
+ mLayoutRegistry.insert(QLatin1String("Log4Qt::SimpleLayout"), create_simple_layout);
+ mLayoutRegistry.insert(QLatin1String("org.apache.log4j.TTCCLayout"), create_ttcc_layout);
+ mLayoutRegistry.insert(QLatin1String("Log4Qt::TTCCLayout"), create_ttcc_layout);
+ }
+
+
+ bool Factory::validateObjectProperty(QMetaProperty &rMetaProperty,
+ const QString &rProperty,
+ QObject *pObject)
+ {
+ // Validate:
+ // - No null object pointer
+ // - No empty property name
+ // - Property exists on the object (QT or Java name)
+ // - Property is readable
+ // - Property is writable
+
+ const char *p_context = "Log4Qt::Factory";
+ LogError e = LOG4QT_ERROR(QT_TR_NOOP("Unable to set property value on object"),
+ CONFIGURATOR_PROPERTY_ERROR,
+ p_context);
+
+ if (!pObject)
+ {
+ LogError ce = LOG4QT_ERROR(QT_TR_NOOP("Invalid null object pointer"),
+ 0,
+ p_context);
+ e.addCausingError(ce);
+ logger()->error(e);
+ return false;
+ }
+ if (rProperty.isEmpty())
+ {
+ LogError ce = LOG4QT_ERROR(QT_TR_NOOP("Invalid empty property name"),
+ 0,
+ p_context);
+ e.addCausingError(ce);
+ logger()->error(e);
+ return false;
+ }
+ const QMetaObject *p_meta_object = pObject->metaObject();
+ QString property = rProperty;
+ int i = p_meta_object->indexOfProperty(property.toLatin1());
+ if (i < 0)
+ {
+ // Try name with lower case first character. Java properties names
+ // start upper case
+ property[0] = property[0].toLower();
+ i = p_meta_object->indexOfProperty(property.toLatin1());
+ if (i < 0)
+ {
+ LogError ce = LOG4QT_ERROR(QT_TR_NOOP("Property '%1' does not exist in class '%2'"),
+ 0,
+ p_context);
+ ce << property
+ << QString::fromLatin1(pObject->metaObject()->className());
+ e.addCausingError(ce);
+ logger()->error(e);
+ return false;
+ }
+ }
+ rMetaProperty = p_meta_object->property(i);
+ if (!rMetaProperty.isWritable())
+ {
+ LogError ce = LOG4QT_ERROR(QT_TR_NOOP("Property '%1' is not writable in class '%2'"),
+ 0,
+ p_context);
+ ce << property
+ << QString::fromLatin1(pObject->metaObject()->className());
+ e.addCausingError(ce);
+ logger()->error(e);
+ return false;
+ }
+
+ return true;
+ }
+
+
+
+ /**************************************************************************
+ * Implementation: Operators, Helper
+ **************************************************************************/
+
+
+#ifndef QT_NO_DEBUG_STREAM
+ QDebug operator<<(QDebug debug,
+ const Factory &rFactory)
+ {
+ debug.nospace() << "Factory("
+ << "appenderfactories:" << rFactory.registeredAppenders()
+ << "filterfactories:" << rFactory.registeredFilters()
+ << "layoutfactories:" << rFactory.registeredLayouts()
+ << ")";
+ return debug.space();
+ }
+#endif // QT_NO_DEBUG_STREAM
+
+
+
+} // namespace Log4Qt
+
diff --git a/src/log4qt/log4qt/helpers/factory.h b/src/log4qt/log4qt/helpers/factory.h
new file mode 100644
index 0000000..b70104f
--- /dev/null
+++ b/src/log4qt/log4qt/helpers/factory.h
@@ -0,0 +1,494 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: factory.h
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef LOG4QT_HELPERS_FACTORY_H
+#define LOG4QT_HELPERS_FACTORY_H
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+#include
+#include
+#include
+
+#include "ukui-logmacros.h"
+
+QT_BEGIN_NAMESPACE
+class QMetaProperty;
+class QObject;
+QT_END_NAMESPACE
+
+/******************************************************************************
+ * Declarations
+ ******************************************************************************/
+
+namespace Log4Qt
+{
+
+ class Appender;
+ class Filter;
+ class Layout;
+
+ /*!
+ * \brief The class Factory provides factories for Appender, Filter and
+ * Layout objects.
+ *
+ * The functions createAppender(), createFilter() and createLayout()
+ * allow to create objects by specifying their class names. By default
+ * all classes of the package are recognised with their Log4j and Log4Qt
+ * classanmes. For example an object of the class FileAppender can be
+ * craeted using "org.apache.log4j.FileAppender" or "Log4Qt::FileAppender".
+ * Additional classes can be registered using registerAppender(),
+ * registerFilter() and registerLayout().
+ *
+ * An QObject property can be set from a string value with
+ * setObjectProperty(). The function handles the required error checking
+ * and type conversion.
+ *
+ * \note All the functions declared in this class are thread-safe.
+ *
+ * \sa PropertyConfigurator
+ */
+ class LIBUKUILOG4QT_EXPORT Factory
+ {
+ public:
+ /*!
+ * Prototype for an Appender factory function. The function creates
+ * an Appender object on the heap and returns a pointer to it.
+ *
+ * \sa registerAppender(), createAppender()
+ */
+ typedef Appender *(*AppenderFactoryFunc)();
+
+ /*!
+ * Prototype for a Filter factory function. The function creates
+ * a Filter object on the heap and returns a pointer to it.
+ *
+ * \sa registerFilter(), createFilter()
+ */
+ typedef Filter *(*FilterFactoryFunc)();
+
+ /*!
+ * Prototype for a Layout factory function. The function creates
+ * a Layout object on the heap and returns a pointer to it.
+ *
+ * \sa registerLayout(), createLayout()
+ */
+ typedef Layout *(*LayoutFactoryFunc)();
+
+ private:
+ Factory();
+ Q_DISABLE_COPY(Factory)
+
+ public:
+ /*!
+ * Creates an object for the class \a rAppenderClassName on the heap
+ * and returns a pointer to it. If the class has no registered factory
+ * function a null pointer is returned.
+ *
+ * \sa registerAppender(), unregisterAppender(), registeredAppenders()
+ */
+ static Appender *createAppender(const QString &rAppenderClassName);
+
+ /*!
+ * This is an overloaded member function, provided for convenience.
+ */
+ static Appender *createAppender(const char *pAppenderClassName);
+
+ /*!
+ * Creates an object for the class \a rFilterClassName on the heap
+ * and returns a pointer to it. If the class has no registered factory
+ * function a null pointer is returned.
+ *
+ * \sa registerFilter(), unregisterFilter(), registeredFilters()
+ */
+ static Filter *createFilter(const QString &rFilterClassName);
+
+ /*!
+ * This is an overloaded member function, provided for convenience.
+ */
+ static Filter *createFilter(const char *pFilterClassName);
+
+ /*!
+ * Creates an object for the class \a rLayoutClassName on the heap
+ * and returns a pointer to it. If the class has no registered factory
+ * function a null pointer is returned.
+ *
+ * \sa registerLayout(), unregisterLayout(), registeredLayouts()
+ */
+ static Layout *createLayout(const QString &rLayoutClassName);
+
+ /*!
+ * This is an overloaded member function, provided for convenience.
+ */
+ static Layout *createLayout(const char *pLayoutClassName);
+
+ /*!
+ * Returns the Factory instance.
+ */
+ static Factory *instance();
+
+ /*!
+ * Registers the Appender factory function \a pAppenderFactoryFunc
+ * for the class \a rAppenderClassName. If a registered factory
+ * function exists for the class, it is replaced with
+ * \a pAppenderFactoryFunc.
+ *
+ * \sa unregisterAppender(), registeredAppenders(), createAppender()
+ */
+ static void registerAppender(const QString &rAppenderClassName,
+ AppenderFactoryFunc pAppenderFactoryFunc);
+
+ /*!
+ * This is an overloaded member function, provided for convenience.
+ */
+ static void registerAppender(const char *pAppenderClassName,
+ AppenderFactoryFunc pAppenderFactoryFunc);
+
+ /*!
+ * Registers the Filter factory function \a pFilterFactoryFunc
+ * for the class \a rFilterClassName. If a registered factory
+ * function exists for the class, it is replaced with
+ * \a pFilterFactoryFunc.
+ *
+ * \sa unregisterFilter(), registeredFilters(), createFilter()
+ */
+ static void registerFilter(const QString &rFilterClassName,
+ FilterFactoryFunc pFilterFactoryFunc);
+
+ /*!
+ * This is an overloaded member function, provided for convenience.
+ */
+ static void registerFilter(const char *pFilterClassName,
+ FilterFactoryFunc pFilterFactoryFunc);
+
+ /*!
+ * Registers the Layout factory function \a pLayoutFactoryFunc
+ * for the class \a rLayoutClassName. If a registered factory
+ * function exists for the class, it is replaced with
+ * \a pLayoutFactoryFunc.
+ *
+ * \sa unregisterLayout(), registeredLayout(), createLayout()
+ */
+ static void registerLayout(const QString &rLayoutClassName,
+ LayoutFactoryFunc pLayoutFactoryFunc);
+
+ /*!
+ * This is an overloaded member function, provided for convenience.
+ */
+ static void registerLayout(const char *pLayoutClassName,
+ LayoutFactoryFunc pLayoutFactoryFunc);
+
+ /*!
+ * Returns a list of the class names for registered Appender factory
+ * functions.
+ *
+ * \sa registerAppender(), unregisterAppender()
+ */
+ static QStringList registeredAppenders();
+
+ /*!
+ * Returns a list of the class names for registered Filter factory
+ * functions.
+ *
+ * \sa registerFilter(), unregisterFilter()
+ */
+ static QStringList registeredFilters();
+
+ /*!
+ * Returns a list of the class names for registered Layout factory
+ * functions.
+ *
+ * \sa registerLayout(), unregisterLayout()
+ */
+ static QStringList registeredLayouts();
+
+ /*!
+ * Sets the property \a rProperty of the object \a pObject to the
+ * value \a rValue. The function will test that the property
+ * \a rProperty is writeable and of a type the function can convert to.
+ * The types bool, int, Level and QString are supported.
+ *
+ * \sa OptionConverter
+ */
+ static void setObjectProperty(QObject *pObject,
+ const QString &rProperty,
+ const QString &rValue);
+
+ /*!
+ * This is an overloaded member function, provided for convenience.
+ */
+ static void setObjectProperty(QObject *pObject,
+ const char *pProperty,
+ const QString &rValue);
+
+ /*!
+ * Unregisters the Appender factory function for the class
+ * \a rAppenderClassName.
+ *
+ * \sa registerAppender(), registeredAppenders()
+ */
+ static void unregisterAppender(const QString &rAppenderClassName);
+
+ /*!
+ * This is an overloaded member function, provided for convenience.
+ */
+ static void unregisterAppender(const char *pAppenderClassName);
+
+ /*!
+ * Unregisters the Filter factory function for the class
+ * \a rFilterClassName.
+ *
+ * \sa registerFilter(), registeredFilters()
+ */
+ static void unregisterFilter(const QString &rFilterClassName);
+
+ /*!
+ * This is an overloaded member function, provided for convenience.
+ */
+ static void unregisterFilter(const char *pFilterClassName);
+
+ /*!
+ * Unregisters the Layout factory function for the class
+ * \a rLayoutClassName.
+ *
+ * \sa registerLayout(), registeredLayouts()
+ */
+ static void unregisterLayout(const QString &rLayoutClassName);
+
+ /*!
+ * This is an overloaded member function, provided for convenience.
+ */
+ static void unregisterLayout(const char *pLayoutClassName);
+
+ private:
+ Appender *doCreateAppender(const QString &rAppenderClassName);
+ Filter *doCreateFilter(const QString &rFilterClassName);
+ Layout *doCreateLayout(const QString &rLayoutClassName);
+ void doRegisterAppender(const QString &rAppenderClassName,
+ AppenderFactoryFunc pAppenderFactoryFunc);
+ void doRegisterFilter(const QString &rFilterClassName,
+ FilterFactoryFunc pFilterFactoryFunc);
+ void doRegisterLayout(const QString &rLayoutClassName,
+ LayoutFactoryFunc pLayoutFactoryFunc);
+ void doSetObjectProperty(QObject *pObject,
+ const QString &rProperty,
+ const QString &rValue);
+ void doUnregisterAppender(const QString &rAppenderClassName);
+ void doUnregisterFilter(const QString &rFilterClassName);
+ void doUnregisterLayout(const QString &rLayoutClassName);
+ void registerDefaultAppenders();
+ void registerDefaultFilters();
+ void registerDefaultLayouts();
+ bool validateObjectProperty(QMetaProperty &rMetaProperty,
+ const QString &rProperty,
+ QObject *pObject);
+
+ private:
+ mutable QMutex mObjectGuard;
+ QHash mAppenderRegistry;
+ QHash mFilterRegistry;
+ QHash mLayoutRegistry;
+ };
+
+
+ /**************************************************************************
+ * Operators, Helper
+ **************************************************************************/
+
+#ifndef QT_NO_DEBUG_STREAM
+ /*!
+ * \relates Factory
+ *
+ * Writes all object member variables to the given debug stream \a rDebug and
+ * returns the stream.
+ *
+ *
+ * %Factory(appenderfactories:("Log4Qt::DebugAppender", "Log4Qt::NullAppender",
+ * "Log4Qt::ConsoleAppender", "org.apache.log4j.varia.DebugAppender",
+ * "org.apache.log4j.FileAppender", "org.apache.log4j.RollingFileAppender",
+ * "org.apache.log4j.DailyRollingFileAppender",
+ * "org.apache.log4j.varia.ListAppender",
+ * "org.apache.log4j.varia.NullAppender",
+ * "Log4Qt::FileAppender", "org.apache.log4j.ConsoleAppender",
+ * "Log4Qt::DailyRollingFileAppender", "Log4Qt::ListAppender",
+ * "Log4Qt::RollingFileAppender") filterfactories:
+ * ("Log4Qt::DenyAllFilter", "Log4Qt::StringMatchFilter",
+ * "Log4Qt::LevelRangeFilter", "org.apache.log4j.varia.DenyAllFilter",
+ * "org.apache.log4j.varia.LevelRangeFilter",
+ * "org.apache.log4j.varia.StringMatchFilter", "Log4Qt::LevelMatchFilter",
+ * "org.apache.log4j.varia.LevelMatchFilter") layoutfactories:
+ * ("org.apache.log4j.SimpleLayout", "Log4Qt::PatternLayout",
+ * "Log4Qt::SimpleLayout", "org.apache.log4j.TTCCLayout",
+ * "Log4Qt::TTCCLayout", "org.apache.log4j.PatternLayout") )
+ *
+ * \sa QDebug, Factory::logManager()
+ */
+ QDebug operator<<(QDebug debug,
+ const Factory &rFactory);
+#endif // QT_NO_DEBUG_STREAM
+
+
+
+ /**************************************************************************
+ * Inline
+ **************************************************************************/
+
+ inline Appender *Factory::createAppender(const QString &rAppenderClassName)
+ {
+ return instance()->doCreateAppender(rAppenderClassName);
+ }
+
+ inline Appender *Factory::createAppender(const char *pAppenderClassName)
+ {
+ return instance()->doCreateAppender(QLatin1String(pAppenderClassName));
+ }
+
+ inline Filter *Factory::createFilter(const QString &rFilterClassName)
+ {
+ return instance()->doCreateFilter(rFilterClassName);
+ }
+
+ inline Filter *Factory::createFilter(const char *pFilterClassName)
+ {
+ return instance()->doCreateFilter(QLatin1String(pFilterClassName));
+ }
+
+ inline Layout *Factory::createLayout(const QString &rLayoutClassName)
+ {
+ return instance()->doCreateLayout(rLayoutClassName);
+ }
+
+ inline Layout *Factory::createLayout(const char *pLayoutClassName)
+ {
+ return instance()->doCreateLayout(QLatin1String(pLayoutClassName));
+ }
+
+ inline void Factory::registerAppender(const QString &rAppenderClassName,
+ AppenderFactoryFunc pAppenderFactoryFunc)
+ {
+ instance()->doRegisterAppender(rAppenderClassName, pAppenderFactoryFunc);
+ }
+
+ inline void Factory::registerAppender(const char *pAppenderClassName,
+ AppenderFactoryFunc pAppenderFactoryFunc)
+ {
+ instance()->doRegisterAppender(QLatin1String(pAppenderClassName), pAppenderFactoryFunc);
+ }
+
+ inline void Factory::registerFilter(const QString &rFilterClassName,
+ FilterFactoryFunc pFilterFactoryFunc)
+ {
+ instance()->doRegisterFilter(rFilterClassName, pFilterFactoryFunc);
+ }
+
+ inline void Factory::registerFilter(const char *pFilterClassName,
+ FilterFactoryFunc pFilterFactoryFunc)
+ {
+ instance()->doRegisterFilter(QLatin1String(pFilterClassName), pFilterFactoryFunc);
+ }
+
+ inline void Factory::registerLayout(const QString &rLayoutClassName,
+ LayoutFactoryFunc pLayoutFactoryFunc)
+ {
+ instance()->doRegisterLayout(rLayoutClassName, pLayoutFactoryFunc);
+ }
+
+ inline void Factory::registerLayout(const char *pLayoutClassName,
+ LayoutFactoryFunc pLayoutFactoryFunc)
+ {
+ instance()->doRegisterLayout(QLatin1String(pLayoutClassName), pLayoutFactoryFunc);
+ }
+
+ inline QStringList Factory::registeredAppenders()
+ {
+ QMutexLocker locker(&instance()->mObjectGuard);
+ return instance()->mAppenderRegistry.keys();
+ }
+
+ inline QStringList Factory::registeredFilters()
+ {
+ QMutexLocker locker(&instance()->mObjectGuard);
+ return instance()->mFilterRegistry.keys();
+ }
+
+ inline QStringList Factory::registeredLayouts()
+ {
+ QMutexLocker locker(&instance()->mObjectGuard);
+ return instance()->mLayoutRegistry.keys();
+ }
+
+ inline void Factory::setObjectProperty(QObject *pObject,
+ const QString &rProperty,
+ const QString &rValue)
+ {
+ instance()->doSetObjectProperty(pObject, rProperty, rValue);
+ }
+
+ inline void Factory::setObjectProperty(QObject *pObject,
+ const char *pProperty,
+ const QString &rValue)
+ {
+ instance()->doSetObjectProperty(pObject, QLatin1String(pProperty), rValue);
+ }
+
+ inline void Factory::unregisterAppender(const QString &rAppenderClassName)
+ {
+ instance()->doUnregisterAppender(rAppenderClassName);
+ }
+
+ inline void Factory::unregisterAppender(const char *pAppenderClassName)
+ {
+ instance()->doUnregisterAppender(QLatin1String(pAppenderClassName));
+ }
+
+ inline void Factory::unregisterFilter(const QString &rFilterClassName)
+ {
+ instance()->doUnregisterFilter(rFilterClassName);
+ }
+
+ inline void Factory::unregisterFilter(const char *pFilterClassName)
+ {
+ instance()->doUnregisterFilter(QLatin1String(pFilterClassName));
+ }
+
+ inline void Factory::unregisterLayout(const QString &rLayoutClassName)
+ {
+ instance()->doUnregisterLayout(rLayoutClassName);
+ }
+
+ inline void Factory::unregisterLayout(const char *pLayoutClassName)
+ {
+ instance()->doUnregisterLayout(QLatin1String(pLayoutClassName));
+ }
+
+} // namespace Log4Qt
+
+
+// Q_DECLARE_TYPEINFO(Log4Qt::Factory, Q_COMPLEX_TYPE); // use default
+
+
+#endif // LOG4QT_HELPERS_FACTORY_H
diff --git a/src/log4qt/log4qt/helpers/initialisationhelper.cpp b/src/log4qt/log4qt/helpers/initialisationhelper.cpp
new file mode 100644
index 0000000..e8ba59b
--- /dev/null
+++ b/src/log4qt/log4qt/helpers/initialisationhelper.cpp
@@ -0,0 +1,185 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: initialisationhelper.cpp
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * changes Feb 2009, Martin Heinrich
+ * - Fixed VS 2008 unreferenced formal parameter warning by using
+ * Q_UNUSED in operator<<.
+ *
+ *
+ * Copyright 2007 - 2009 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+
+#include "log4qt/helpers/initialisationhelper.h"
+
+#include
+#include
+#include
+#include
+#include
+#ifndef QT_NO_DATASTREAM
+#include
+#endif
+#include "log4qt/helpers/datetime.h"
+#include "log4qt/helpers/logerror.h"
+#include "log4qt/loggingevent.h"
+
+
+
+namespace Log4Qt
+{
+
+
+ /**************************************************************************
+ *Declarations
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * C helper functions
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * Class implementation: InitialisationHelper
+ **************************************************************************/
+
+
+ InitialisationHelper::InitialisationHelper() :
+ mStartTime(DateTime::currentDateTime().toMilliSeconds()),
+ mEnvironmentSettings()
+ {
+ doRegisterTypes();
+ doInitialiseEnvironmentSettings();
+ }
+
+
+ InitialisationHelper::~InitialisationHelper()
+ {
+ Q_ASSERT_X(false, "InitialisationHelper::~InitialisationHelper()", "Unexpected destruction of singleton object");
+ }
+
+
+ LOG4QT_IMPLEMENT_INSTANCE(InitialisationHelper)
+
+
+ void InitialisationHelper::doInitialiseEnvironmentSettings()
+ {
+ // Is Process::systemEnvironment() safe to be used before a QCoreApplication
+ // object has been created?
+
+ QStringList setting_keys;
+ setting_keys << QLatin1String("Debug");
+ setting_keys << QLatin1String("DefaultInitOverride");
+ setting_keys << QLatin1String("Configuration");
+ setting_keys << QLatin1String("ConfiguratorClass");
+
+ QHash env_keys;
+ QString entry;
+ Q_FOREACH(entry, setting_keys)
+ env_keys.insert(QString::fromLatin1("log4qt_").append(entry).toUpper(), entry);
+
+ QStringList sys_env = QProcess::systemEnvironment();
+ Q_FOREACH(entry, sys_env)
+ {
+ int i = entry.indexOf(QLatin1Char('='));
+ if (i == -1)
+ continue;
+ QString key = entry.left(i);
+ QString value = entry.mid(i + 1).trimmed();
+ if (env_keys.contains(key))
+ mEnvironmentSettings.insert(env_keys.value(key), value);
+ }
+ }
+
+
+ void InitialisationHelper::doRegisterTypes()
+ {
+ qRegisterMetaType("Log4Qt::LogError");
+ qRegisterMetaType("Log4Qt::Level");
+ qRegisterMetaType("Log4Qt::LoggingEvent");
+
+ #ifndef QT_NO_DATASTREAM
+ qRegisterMetaTypeStreamOperators("Log4Qt::LogError");
+ qRegisterMetaTypeStreamOperators("Log4Qt::Level");
+ qRegisterMetaTypeStreamOperators("Log4Qt::LoggingEvent");
+ #endif
+ }
+
+
+ QString InitialisationHelper::doSetting(const QString &rKey,
+ const QString &rDefault) const
+ {
+ if (mEnvironmentSettings.contains(rKey))
+ return mEnvironmentSettings.value(rKey);
+
+ if (QCoreApplication::instance())
+ {
+ QSettings s;
+ s.beginGroup(QLatin1String("Log4Qt"));
+ return s.value(rKey, rDefault).toString().trimmed();
+ }
+ else
+ return rDefault;
+ }
+
+
+ bool InitialisationHelper::staticInitialisation()
+ {
+ instance();
+ return true;
+ }
+
+
+ bool InitialisationHelper::msStaticInitialisation = staticInitialisation();
+
+
+
+ /**************************************************************************
+ * Implementation: Operators, Helper
+ **************************************************************************/
+
+
+#ifndef QT_NO_DEBUG_STREAM
+ QDebug operator<<(QDebug debug,
+ const InitialisationHelper &rInitialisationHelper)
+ {
+ Q_UNUSED(rInitialisationHelper);
+ debug.nospace() << "InitialisationHelper("
+ << "starttime:" << InitialisationHelper::startTime()
+ << "(" << DateTime::fromMilliSeconds(InitialisationHelper::startTime()) << ")"
+ << "environmentsettings:" << InitialisationHelper::environmentSettings()
+ << ")";
+ return debug.space();
+ }
+#endif // QT_NO_DEBUG_STREAM
+
+
+
+} // namespace Log4Qt
diff --git a/src/log4qt/log4qt/helpers/initialisationhelper.h b/src/log4qt/log4qt/helpers/initialisationhelper.h
new file mode 100644
index 0000000..f6c531c
--- /dev/null
+++ b/src/log4qt/log4qt/helpers/initialisationhelper.h
@@ -0,0 +1,437 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: initialisationhelper.h
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * changes: Sep 2008, Martin Heinrich:
+ * - Replaced usage of q_atomic_test_and_set_ptr with
+ * QBasicAtomicPointer
+ *
+ *
+ * Copyright 2007 - 2008 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef LOG4QT_HELPERS_INITIALISATIONHELPER_H
+#define LOG4QT_HELPERS_INITIALISATIONHELPER_H
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+#include
+#include
+#include
+
+#include "ukui-logmacros.h"
+
+#if QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)
+# ifndef Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
+# warning "QAtomicPointer test and set is not native. The macros Log4Qt::LOG4QT_GLOBAL_STATIC and Log4Qt::LOG4QT_IMPLEMENT_INSTANCE are not thread-safe."
+# endif
+#endif
+
+
+/******************************************************************************
+ * Declarations
+ ******************************************************************************/
+
+class QMutex;
+
+namespace Log4Qt
+{
+ /*!
+ * LOG4QT_GLOBAL_STATIC declares a static function \a FUNCTION that
+ * returns a pointer to a singleton object of the type \a TYPE.
+ *
+ * The macro uses a static variable to store a pointer to the singleton
+ * object. On the first invocation an object of the type \a TYPE is created
+ * on the heap and the pointer is set. Any further invocations will return
+ * the stored pointer. If multiple threads are accessing the function
+ * without the pointer being set, each thread will create an object of the
+ * type \a TYPE. The threads that find the pointer already been set will
+ * delete their object. The singleton object will not be deleted during static
+ * de-initialisation.
+ *
+ * The following example uses a global global mutex object to synchronise
+ * access to a static member variable.
+ *
+ * \code
+ * #file: myclass.h
+ *
+ * class MyClass
+ * {
+ * public:
+ * MyClass();
+ * ~MyClass();
+ * private:
+ * static qint64 msObjectCount;
+ * }
+ * \endcode
+ * \code
+ * #file: myclass.cpp
+ *
+ * #include myclass.h
+ *
+ * LOG4QT_GLOBAL_STATIC(QMutex, class_guard)
+ *
+ * MyClass::MyClass()
+ * {
+ * QMutexLocker(class_guard());
+ * msObjectCount++;
+ * }
+ *
+ * MyClass::~MyClass()
+ * {
+ * QMutexLocker(class_guard());
+ * msObjectCount--;
+ * }
+ *
+ * qint64 MyClass::msObjectCount = 0;
+ * \endcode
+ *
+ * \note The function created by the macro is thread-safe.
+ *
+ * \sa \ref Log4Qt::LOG4QT_IMPLEMENT_INSTANCE "LOG4QT_IMPLEMENT_INSTANCE",
+ * \ref Log4Qt::InitialisationHelper "InitialisationHelper"
+ */
+#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0)
+ #define LOG4QT_GLOBAL_STATIC(TYPE, FUNCTION) \
+ static volatile TYPE *sp_global_static_##FUNCTION = 0; \
+ TYPE *FUNCTION() \
+ { \
+ if (!sp_global_static_##FUNCTION) \
+ { \
+ TYPE *p_temp = new TYPE; \
+ if (!q_atomic_test_and_set_ptr(&sp_global_static_##FUNCTION, \
+ 0, p_temp)) \
+ delete p_temp; \
+ } \
+ return const_cast(sp_global_static_##FUNCTION); \
+ }
+#elif QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ #define LOG4QT_GLOBAL_STATIC(TYPE, FUNCTION) \
+ static QBasicAtomicPointer sp_global_static_##FUNCTION = \
+ Q_BASIC_ATOMIC_INITIALIZER(0); \
+ TYPE *FUNCTION() \
+ { \
+ if (!sp_global_static_##FUNCTION) \
+ { \
+ TYPE *p_temp = new TYPE; \
+ if (!sp_global_static_##FUNCTION.testAndSetOrdered(0, \
+ p_temp)) \
+ delete p_temp; \
+ } \
+ return sp_global_static_##FUNCTION; \
+ }
+#else
+ #define LOG4QT_GLOBAL_STATIC(TYPE, FUNCTION) \
+ static QBasicAtomicPointer sp_global_static_##FUNCTION = \
+ Q_BASIC_ATOMIC_INITIALIZER(0); \
+ TYPE *FUNCTION() \
+ { \
+ if (!sp_global_static_##FUNCTION.loadAcquire()) \
+ { \
+ TYPE *p_temp = new TYPE; \
+ if (!sp_global_static_##FUNCTION.testAndSetOrdered(0, \
+ p_temp)) \
+ delete p_temp; \
+ } \
+ return sp_global_static_##FUNCTION.loadAcquire(); \
+ }
+#endif
+
+ /*!
+ * LOG4QT_IMPLEMENT_INSTANCE implements an instance function for a
+ * singleton class \a TYPE.
+ *
+ * The function works like the one created by
+ * \ref Log4Qt::LOG4QT_GLOBAL_STATIC "LOG4QT_GLOBAL_STATIC".
+ *
+ * The following example illustrates how to use the macro to create a
+ * singleton class:
+ *
+ * \code
+ * #file: mysingleton.h
+ *
+ * class MySingleton
+ * {
+ * private:
+ * MySingleton();
+ * ~MySingleton();
+ * public:
+ * MySingleton *instance();
+ * }
+ * \endcode
+ * \code
+ * #file: mysingleton.cpp
+ *
+ * #include mysingleton.h
+ *
+ * MySingleton::MySingleton()
+ * {}
+ *
+ * MySingleton::~MySingleton()
+ * {}
+ *
+ * LOG4QT_IMPLEMENT_INSTANCE(MySingleton)
+ *
+ * \endcode
+ *
+ * \note The function created by the macro is thread-safe.
+ *
+ * \sa \ref Log4Qt::LOG4QT_GLOBAL_STATIC "LOG4QT_GLOBAL_STATIC",
+ * \ref Log4Qt::InitialisationHelper "InitialisationHelper"
+ */
+#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0)
+ #define LOG4QT_IMPLEMENT_INSTANCE(TYPE) \
+ static TYPE *sp_singleton_##TYPE = 0; \
+ TYPE *TYPE::instance() \
+ { \
+ if (!sp_singleton_##TYPE) \
+ { \
+ TYPE *p_temp = new TYPE; \
+ if (!q_atomic_test_and_set_ptr(&sp_singleton_##TYPE, \
+ 0, p_temp)) \
+ delete p_temp; \
+ } \
+ return sp_singleton_##TYPE; \
+ }
+#elif QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ #define LOG4QT_IMPLEMENT_INSTANCE(TYPE) \
+ static QBasicAtomicPointer sp_singleton_##TYPE = \
+ Q_BASIC_ATOMIC_INITIALIZER(0); \
+ TYPE *TYPE::instance() \
+ { \
+ if (!sp_singleton_##TYPE) \
+ { \
+ TYPE *p_temp = new TYPE; \
+ if (!sp_singleton_##TYPE.testAndSetOrdered(0, p_temp)) \
+ delete p_temp; \
+ } \
+ return sp_singleton_##TYPE; \
+ }
+#else
+ #define LOG4QT_IMPLEMENT_INSTANCE(TYPE) \
+ static QBasicAtomicPointer sp_singleton_##TYPE = \
+ Q_BASIC_ATOMIC_INITIALIZER(0); \
+ TYPE *TYPE::instance() \
+ { \
+ if (!sp_singleton_##TYPE.loadAcquire()) \
+ { \
+ TYPE *p_temp = new TYPE; \
+ if (!sp_singleton_##TYPE.testAndSetOrdered(0, p_temp)) \
+ delete p_temp; \
+ } \
+ return sp_singleton_##TYPE.loadAcquire(); \
+ }
+#endif
+
+ /*!
+ * \brief The class InitialisationHelper performs static initialisation
+ * tasks.
+ *
+ * The InitialisationHelper is either created on the first call or through
+ * static initialisation. It will capture the programs startup time,
+ * which can be retrieved using startTime(). The system environment
+ * is analysed for package related definitions. The result is available
+ * over environmentSettings(). The packages custom types are registered with
+ * the Qt type system.
+ *
+ * Settings for the package can be retrieved using setting(). Two macros
+ * are available to help with the creation of singletons / global static
+ * objects (\ref Log4Qt::LOG4QT_GLOBAL_STATIC "LOG4QT_GLOBAL_STATIC" and
+ * \ref Log4Qt::LOG4QT_IMPLEMENT_INSTANCE "LOG4QT_IMPLEMENT_INSTANCE").
+ *
+ * \note All the functions declared in this class are thread-safe.
+ *
+ * \sa \ref Init "Initialization procedure",
+ */
+ class LIBUKUILOG4QT_EXPORT InitialisationHelper
+ {
+ private:
+ InitialisationHelper();
+ InitialisationHelper(const InitialisationHelper &rOther); // Not implemented
+ virtual ~InitialisationHelper();
+ InitialisationHelper &operator=(const InitialisationHelper &rOther); // Not implemented
+
+ public:
+
+ /*!
+ * Returns a hash with the settings retrieved from the system
+ * environment on startup.
+ *
+ * The following table shows the environment variables taken into
+ * account and the setting key used for them.
+ *
+ *
+ *
+ *
Environment variable
+ *
Setting key
+ *
+ *
LOG4QT_DEBUG
+ *
Debug
+ *
+ *
LOG4QT_DEFAULTINITOVERRIDE
+ *
DefaultInitOverride
+ *
+ *
LOG4QT_CONFIGURATION
+ *
Configuration
+ *
+ *
LOG4QT_CONFIGURATORCLASS
+ *
ConfiguratorClass
+ *
+ *
+ *
+ * \sa \ref Env "Environment Variables",
+ * setting()
+ */
+ static QHash environmentSettings();
+
+ /*!
+ * Returns the InitialisationHelper instance.
+ */
+ static InitialisationHelper *instance();
+
+ /*!
+ * Returns the value for the setting \a rKey or \a rDefault, if it is
+ * not defined.
+ *
+ * A setting can be either defined by an environment variable or by a
+ * key in the application setting. The function will first test the
+ * settings made by environment variables for the key \a rKey using
+ * environmentSettings(). If the key is not present and a
+ * QCoreApplication exists, the application settings are tested for
+ * the key \a rKey in the group \c %Log4Qt.
+ *
+ * The following setting exists:
+ *
+ *
+ *
+ *
Setting key
+ *
Description
+ *
+ *
Debug
+ *
The variable controls the Level value for the logger
+ * LogManager::logLogger(). If the value is a valid Level string,
+ * the level for the logger is set to the level. If the value is not
+ * a valid Level string, \ref Level::DEBUG_INT "DEBUG_INT" is used.
+ * Otherwise \ref Level::ERROR_INT "ERROR_INT" is used.
+ *
+ *
DefaultInitOverride
+ *
The variable controls the \ref Init "initialization procedure"
+ * performed by the \ref LogManager "LogManager" on startup.
+ * If it is set to any other value then \c false the \ref Init
+ * "initialization procedure" is skipped.
+ *
+ *
Configuration
+ *
Specifies the configuration file used for initialising the package.
+ *
+ *
ConfiguratorClass
+ *
Specifies the configurator class used for initialising the package.
+ *
+ *
+ *
+ * \sa environmentSettings(), \ref Env "Environment Variables",
+ * \ref Init "Initialization procedure",
+ * LogManager::configureLogLogger(), LogManager::startup()
+ */
+ static QString setting(const QString &rKey,
+ const QString &rDefault = QString());
+
+ /*!
+ * Returns the start time of the program as the number of milliseconds
+ * that have passed since 1970-01-01T00:00:00,000, Coordinated
+ * Universal Time (Qt::UTC).
+ *
+ * \sa DateTime::fromMilliSeconds(),
+ * DateTime::toMilliSeconds()
+ */
+ static qint64 startTime();
+
+ private:
+ void doInitialiseEnvironmentSettings();
+ void doRegisterTypes();
+ QString doSetting(const QString &rKey,
+ const QString &rDefault) const;
+ static bool shutdown();
+ static bool staticInitialisation();
+
+ private:
+ // QMutex mObjectGuard;
+ const qint64 mStartTime;
+ QHash mEnvironmentSettings;
+ static bool msStaticInitialisation;
+
+#ifndef QT_NO_DEBUG_STREAM
+ // Needs to be friend to access details
+ friend QDebug operator<<(QDebug debug,
+ const InitialisationHelper &rInitialisationHelper);
+#endif // QT_NO_DEBUG_STREAM
+ };
+
+
+ /**************************************************************************
+ * Operators, Helper
+ **************************************************************************/
+
+#ifndef QT_NO_DEBUG_STREAM
+ /*!
+ * \relates InitialisationHelper
+ *
+ * Writes all object member variables to the given debug stream \a rDebug and
+ * returns the stream.
+ *
+ *
+ * %InitialisationHelper(InitialisationHelper(starttime:1193883677438(
+ * QDateTime("Wed Oct 31 21:21:17 2007") )
+ * environmentsettings: QHash(("configuration", "\myapp.log4j")
+ * ("Debug", "DEBUG")) ) )
+ *
+ * \sa QDebug, InitialisationHelper::logManager()
+ */
+ QDebug operator<<(QDebug debug,
+ const InitialisationHelper &rInitialisationHelper);
+#endif // QT_NO_DEBUG_STREAM
+
+
+ /**************************************************************************
+ * Inline
+ **************************************************************************/
+
+ inline QHash InitialisationHelper::environmentSettings()
+ { // QMutexLocker locker(&instance()->mObjectGuard); // Constant for object lifetime
+ return instance()->mEnvironmentSettings; }
+
+ inline QString InitialisationHelper::setting(const QString &rKey,
+ const QString &rDefault)
+ { // QMutexLocker locker(&instance()->mObjectGuard); // Reentrant and const
+ return instance()->doSetting(rKey, rDefault); }
+
+ inline qint64 InitialisationHelper::startTime()
+ { // QMutexLocker locker(&instance()->mObjectGuard); // Constant for object lifetime
+ return instance()->mStartTime; }
+
+} // namespace Log4Qt
+
+
+// Q_DECLARE_TYPEINFO(Log4Qt::InitialisationHelper, Q_COMPLEX_TYPE); // use default
+
+
+#endif // LOG4QT_HELPERS_INITIALISATIONHELPER_H
diff --git a/src/log4qt/log4qt/helpers/logerror.cpp b/src/log4qt/log4qt/helpers/logerror.cpp
new file mode 100644
index 0000000..f78d2ab
--- /dev/null
+++ b/src/log4qt/log4qt/helpers/logerror.cpp
@@ -0,0 +1,354 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: logerror.cpp
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+
+
+/******************************************************************************
+ * Dependencies
+ *****************************************************************************/
+
+
+#include "log4qt/helpers/logerror.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "log4qt/helpers/initialisationhelper.h"
+
+
+namespace Log4Qt
+{
+
+
+ /**************************************************************************
+ * Declarations
+ **************************************************************************/
+
+
+ typedef QThreadStorage ThreadError;
+
+
+
+ /**************************************************************************
+ * C helper functions
+ **************************************************************************/
+
+
+ LOG4QT_GLOBAL_STATIC(ThreadError, thread_error)
+
+
+
+ /**************************************************************************
+ * Class implementation: LogError
+ **************************************************************************/
+
+
+ LogError::LogError() :
+ mCode(0),
+ mContext(),
+ mMessage(),
+ mSymbol(),
+ mArgs(),
+ mCausingErrors()
+ {
+ }
+
+
+ LogError::LogError(const QString &rMessage,
+ int code,
+ const QString &rSymbol,
+ const QString &rContext) :
+ mCode(code),
+ mContext(rContext),
+ mMessage(cleanMessage(rMessage)),
+ mSymbol(rSymbol),
+ mArgs(),
+ mCausingErrors()
+ {
+ }
+
+
+ LogError::LogError(const char *pMessage,
+ int code,
+ const char *pSymbol,
+ const char *pContext,
+ Encoding encoding) :
+ mCode(code),
+ mContext(QString::fromLatin1(pContext)),
+ mMessage(),
+ mSymbol(QString::fromLatin1(pSymbol)),
+ mArgs(),
+ mCausingErrors()
+ {
+ switch(encoding)
+ {
+ case LATIN1:
+ mMessage = QString::fromLatin1(pMessage);
+ break;
+ case CODECFORTR:
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ mMessage = QTextCodec::codecForTr()->toUnicode(pMessage);
+#else
+ mMessage = QString::fromUtf8(pMessage);
+#endif
+ break;
+ case UNICODEUTF8:
+ mMessage = QString::fromUtf8(pMessage);
+ break;
+ default:
+ Q_ASSERT_X(false, "LogError::LogError", "Unkown encoding constant");
+ mMessage = QString::fromLatin1(pMessage);
+ }
+ mMessage = cleanMessage(mMessage);
+
+ if (mSymbol == QString::number(mCode))
+ mSymbol.clear();
+ }
+
+
+ QString LogError::translatedMessage() const
+ {
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ return QCoreApplication::translate(mContext.toLatin1(), mMessage.toUtf8().data(), 0, QCoreApplication::UnicodeUTF8);
+#else
+ return QCoreApplication::translate(mContext.toLatin1(), mMessage.toUtf8().data(), 0);
+#endif
+ }
+
+
+ LogError LogError::lastError()
+ {
+ if (!thread_error()->hasLocalData())
+ return LogError();
+ else
+ return *thread_error()->localData();
+ }
+
+
+ void LogError::setLastError(const LogError &rLogError)
+ {
+ if (!thread_error()->hasLocalData())
+ thread_error()->setLocalData(new LogError);
+
+ *thread_error()->localData() = rLogError;
+ }
+
+
+ QString LogError::toString() const
+ {
+ QString result = messageWithArgs();
+
+ QString context_symbol = mContext;
+ if (!context_symbol.isEmpty() && !mSymbol.isEmpty())
+ context_symbol.append(QLatin1String("::"));
+ context_symbol.append(mSymbol);
+
+ if (!context_symbol.isEmpty() || mCode)
+ {
+ result.append(QLatin1String(" ("));
+ if (!context_symbol.isEmpty())
+ result.append(context_symbol);
+ if (!context_symbol.isEmpty() && mCode)
+ result.append(QLatin1String(", "));
+ if (mCode)
+ result.append(QString::number(mCode));
+ result.append(QLatin1String(")"));
+ }
+
+ if (!mCausingErrors.isEmpty())
+ {
+ QString causing_errors_str = QLatin1String(": ") + mCausingErrors.at(0).toString();
+ int i = 1;
+ while (i < mCausingErrors.count())
+ {
+ causing_errors_str.append(QLatin1String(", ")).append(mCausingErrors.at(i).toString());
+ i++;
+ }
+ result.append(causing_errors_str);
+ }
+
+ return result;
+ }
+
+
+ QString LogError::insertArgs(const QString &rMessage) const
+ {
+ QString result;
+
+ /*
+
+ // Don't use a loop to be able to handle arguments that conatin strings
+ // like %1.
+ // Using this method only 9 arguments can be handled as the %1
+ // in %11 gets also replaced with the first argument.
+
+ switch (mArgs.count())
+ {
+ case 0:
+ break;
+ case 1:
+ result = rMessage.arg(mArgs.at(0));
+ break;
+ case 2:
+ result = rMessage.arg(mArgs.at(0), mArgs.at(1));
+ break;
+ case 3:
+ result = rMessage.arg(mArgs.at(0), mArgs.at(1), mArgs.at(2));
+ break;
+ case 4:
+ result = rMessage.arg(mArgs.at(0), mArgs.at(1), mArgs.at(2), mArgs.at(3));
+ break;
+ case 5:
+ result = rMessage.arg(mArgs.at(0), mArgs.at(1), mArgs.at(2), mArgs.at(3), mArgs.at(4));
+ break;
+ case 6:
+ result = rMessage.arg(mArgs.at(0), mArgs.at(1), mArgs.at(2), mArgs.at(3), mArgs.at(4), mArgs.at(5));
+ break;
+ case 7:
+ result = rMessage.arg(mArgs.at(0), mArgs.at(1), mArgs.at(2), mArgs.at(3), mArgs.at(4), mArgs.at(5), mArgs.at(6));
+ break;
+ case 8:
+ result = rMessage.arg(mArgs.at(0), mArgs.at(1), mArgs.at(2), mArgs.at(3), mArgs.at(4), mArgs.at(5), mArgs.at(6), mArgs.at(7));
+ break;
+ default:
+ result = rMessage.arg(mArgs.at(0), mArgs.at(1), mArgs.at(2), mArgs.at(3), mArgs.at(4), mArgs.at(5), mArgs.at(6), mArgs.at(7), mArgs.at(8));
+ break;
+ }
+
+ if (mArgs.count() > 9)
+ {
+ int i = 9;
+ while(i < mArgs.count())
+ {
+ result = result.arg(mArgs.at(i));
+ i++;
+ }
+ }
+ */
+
+ result = rMessage;
+ QVariant arg;
+ Q_FOREACH(arg, mArgs)
+ result = result.arg(arg.toString());
+ return result;
+ }
+
+
+ QString LogError::cleanMessage(const QString &rMessage)
+ {
+ if (rMessage.isEmpty())
+ return rMessage;
+
+ QString result = rMessage;
+ if (rMessage.at(rMessage.size() - 1) == QLatin1Char('.'))
+ result = rMessage.left(rMessage.size() - 1);
+ return result;
+ }
+
+
+
+ /**************************************************************************
+ * Implementation: Operators, Helper
+ **************************************************************************/
+
+
+#ifndef QT_NO_DATASTREAM
+ QDataStream &operator<<(QDataStream &rStream,
+ const LogError &rLogError)
+ {
+ QBuffer buffer;
+ buffer.open(QIODevice::WriteOnly);
+ QDataStream stream(&buffer);
+
+ // version
+ quint16 version = 0;
+ stream << version;
+ // version 0 data
+ stream << rLogError.mCode
+ << rLogError.mContext
+ << rLogError.mMessage
+ << rLogError.mSymbol
+ << rLogError.mArgs
+ << rLogError.mCausingErrors;
+
+ buffer.close();
+ rStream << buffer.buffer();
+ return rStream;
+ }
+
+
+ QDataStream &operator>>(QDataStream &rStream,
+ LogError &rLogError)
+ {
+ QByteArray array;
+ rStream >> array;
+ QBuffer buffer(&array);
+ buffer.open(QIODevice::ReadOnly);
+ QDataStream stream(&buffer);
+
+ // version
+ quint16 version;
+ stream >> version;
+ // Version 0 data
+ QString level;
+ QString logger;
+ stream >> rLogError.mCode
+ >> rLogError.mContext
+ >> rLogError.mMessage
+ >> rLogError.mSymbol
+ >> rLogError.mArgs
+ >> rLogError.mCausingErrors;
+
+ buffer.close();
+ return rStream;
+ }
+#endif // QT_NO_DATASTREAM
+
+
+#ifndef QT_NO_DEBUG_STREAM
+ QDebug operator<<(QDebug debug,
+ const LogError &rLogError)
+ {
+ // Escape % sign
+ QString message = rLogError.message();
+ message.replace(QLatin1String("%"), QLatin1String("%%"));
+
+ debug.nospace() << "LogError("
+ << "code:" << rLogError.code() << " "
+ << "context:" << rLogError.context() << " "
+ << "message:" << message << " "
+ << "symbol:" << rLogError.symbol() << " "
+ << "args:" << rLogError.args()
+ << "translatedMessage:" << rLogError.translatedMessage()
+ << ")";
+ return debug.maybeSpace();
+ }
+#endif // QT_NO_DEBUG_STREAM
+
+
+} // namespace Log4Qt
diff --git a/src/log4qt/log4qt/helpers/logerror.h b/src/log4qt/log4qt/helpers/logerror.h
new file mode 100644
index 0000000..3c83135
--- /dev/null
+++ b/src/log4qt/log4qt/helpers/logerror.h
@@ -0,0 +1,552 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: logerror.h
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef LOG4QT_LOGERROR_H
+#define LOG4QT_LOGERROR_H
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+#include
+#include
+
+#include "ukui-logmacros.h"
+
+
+/******************************************************************************
+ * Declarations
+ ******************************************************************************/
+
+namespace Log4Qt
+{
+ /*!
+ * Creates an LogError object with the error message \a message, the error
+ * code \a code and the context \a context. The symbol of the error is
+ * set to \a code as string value.
+ *
+ * The following example logs an error, if a character is not a digit.
+ *
+ * \code
+ * if (!c.isDigit())
+ * {
+ * Error e = LOG4QT_ERROR(QT_TR_NOOP("Found character '%1' where digit was expected."),
+ * LAYOUT_EXPECTED_DIGIT_ERROR,
+ * "Log4Qt::PatternFormatter");
+ * e << QString(c);
+ * logger()->error(e);
+ * }
+ * \endcode
+ */
+ #define LOG4QT_ERROR(message, code, context) \
+ LogError(message, code, #code, context)
+
+ /*!
+ * Creates an LogError object with the error message \a message and the
+ * error code \a code. The symbol of the error is set to \a code as string
+ * value. The context is set to the class name of the current object. The
+ * current objects class must be derived from QObject.
+ *
+ * The following example handles an error while opening a file.
+ *
+ * \code
+ * if (!mpFile->open(mode))
+ * {
+ * LogError e = LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Unable to open file '%1' for appender '%2'"),
+ * APPENDER_OPENING_FILE_ERROR);
+ * e << mFileName << name();
+ * e.addCausingError(LogError(mpFile->errorString(), mpFile->error()));
+ * logger()->error(e);
+ * return;
+ * }
+ * \endcode
+ */
+ #define LOG4QT_QCLASS_ERROR(message, code) \
+ LogError(message, code, #code, this->metaObject()->className())
+
+ /*!
+ * \brief The class LogError represents an error.
+ *
+ * The class error allows storing error information in a structured way.
+ * The error message is stored separately from the information that may be
+ * substituted into the message string. This way it is possible to access
+ * all information after the error has been raised. It also allows to
+ * translate the error at a later point in time or to get a translated and
+ * a not translated error text (e.g. translated for the UI and not
+ * translated for a log).
+ *
+ * The message is accessed using message() and setMessage(). Arguments for
+ * the message can be added using addArg() or operator<<(). The arguments
+ * can be retrieved using args(). The message with substituted arguments
+ * is returned by messageWithArgs().
+ *
+ * An error code can be set as integer value code() and/or a symbolic value
+ * symbol().
+ *
+ * To allow the translation of the message the error stores the translation
+ * context (context(), setContext()). The translated message can be accessed
+ * using translatedMessage() or using translatedMessageWithArgs(), if it
+ * should contain the arguments.
+ *
+ * An error can have one or more related errors that caused it. An error is
+ * related using addCausingError(). All causing errors can be retrieved using
+ * causingErrors().
+ *
+ * A per thread error can be maintained using lastError() and setLastError().
+ *
+ * There are two macros avaiable to simplify the error creation. The macro
+ * \ref Log4Qt::LOG4QT_ERROR "LOG4QT_ERROR" is used with classes not derived
+ * from QObject. The macro \ref Log4Qt::LOG4QT_QCLASS_ERROR "LOG4QT_QCLASS_ERROR"
+ * is used with classes derived from QObject.
+ */
+ class LIBUKUILOG4QT_EXPORT LogError
+ {
+ public:
+
+ /*!
+ * The enum Encoding defines the 8-bit encoding of a character string
+ * arguments to \ref LogError::LogError(const char *, int, const char *,
+ * const char *, Encoding) "LogError::LogError()".
+ *
+ * \sa \ref LogError::LogError(const char *, int, const char *, const char *, Encoding) "LogError::LogError()"
+ */
+ enum Encoding
+ {
+ /*! LATIN-1 */
+ LATIN1,
+ /*!
+ * The encoding specified by QTextCodec::codecForTr()
+ * (Latin-1 if none has been set).
+ */
+ CODECFORTR,
+ /*! UTF-8 */
+ UNICODEUTF8
+ };
+ Q_ENUMS(Encoding)
+
+ /*!
+ * Creates an empty error. The error code is set to 0 and all other
+ * members are set to be empty.
+ *
+ * \sa isEmpty()
+ */
+ LogError();
+
+ /*!
+ * Creates an error with the Message \a rMessage and the error code
+ * \a code. The symbol for the error code is set to \a rSymbol and the
+ * context to \a rContext.
+ *
+ * \a rContext must be string that can be converted to Latin-1. The
+ * Latin-1 representation of the string is used with
+ * QApplication::translate(), if a translation for \a rMessage is
+ * requested.
+ *
+ * \sa translatedMessage(), translatedMessageWithArgs()
+ */
+ LogError(const QString &rMessage,
+ int code = 0,
+ const QString &rSymbol = QString(),
+ const QString &rContext = QString());
+
+ /*!
+ * Creates an error with the Message \a pMessage and the error code
+ * \a code. The symbol for the error code is set to \a pSymbol and the
+ * context to \a pContext.
+ *
+ * \a encoding specifies the encoding of \a pMessage. \a pSymbol and
+ * \a pContext are expected to be Latin-1.
+ *
+ * \note To support the macros \ref Log4Qt::LOG4QT_ERROR "LOG4QT_ERROR"
+ * and \ref Log4Qt::LOG4QT_QCLASS_ERROR "LOG4QT_QCLASS_ERROR"
+ * the function tests, if \a pSymbol is the string representation of
+ * \a code. If it is, the symbol is set to be empty. Otherwise symbol
+ * is set to \a pSymbol.
+ *
+ * \sa translatedMessage(), translatedMessageWithArgs()
+ */
+ LogError(const char *pMessage,
+ int code = 0,
+ const char *pSymbol = 0,
+ const char *pContext = 0,
+ Encoding encoding = LATIN1);
+
+ // LogError(const LogError &rOther); // Use compiler default
+ // virtual ~LogError(); // Use compiler default
+ // LogError &operator=(const LogError &rOther); // Use compiler default
+
+ /*!
+ * Returns the error code.
+ *
+ * \sa setCode()
+ */
+ int code() const;
+
+ /*!
+ * Returns the context for the error.
+ *
+ * \sa setContext()
+ */
+ QString context() const;
+
+ /*!
+ * Returns the error message.
+ *
+ * \sa setMessage()
+ */
+ QString message() const;
+
+ /*!
+ * Returns the symbol for the error code.
+ *
+ * \sa setSymbol()
+ */
+ QString symbol() const;
+
+ /*!
+ * Returns the translated error message.
+ *
+ * The translated message is created by calling
+ * QCoreApplication::translate() using context().toLatin1() as
+ * context and message.toUtf8() as message.
+ *
+ * \sa translatedMessageWithArgs()
+ */
+ QString translatedMessage() const;
+
+ /*!
+ * Sets the error code to \a code.
+ *
+ * \sa code()
+ */
+ void setCode(int code);
+
+ /*!
+ * Sets the context to \a rClassName.
+ *
+ * \a rContext must be string that can be converted to Latin-1. The
+ * Latin-1 representation of the string is used with
+ * QApplication::translate(), if a translation for \a rMessage is
+ * requestd.
+ *
+ * \sa context(), translatedMessage(), translatedMessageWithArgs()
+ */
+ void setContext(const QString &rClassName);
+
+ /*!
+ * Sets the error message to \a rMessage
+ *
+ * \sa message()
+ */
+ void setMessage(const QString &rMessage);
+
+ /*!
+ * Sets the symbol for the error code to \a rSymbol.
+ *
+ * \sa symbol()
+ */
+ void setSymbol(const QString &rSymbol);
+
+ /*!
+ * Returns the last error set for the current thread using
+ * setLastError().
+ *
+ * \note: This function is thread-safe.
+ *
+ * \sa setLastError()
+ */
+ static LogError lastError();
+
+ /*!
+ * Sets the last error for the current thread to \a rLogError.
+ *
+ * \note: This function is thread-safe.
+ *
+ * \sa lastError()
+ */
+ static void setLastError(const LogError &rLogError);
+
+ /*!
+ * Appends \a rArg to the list of arguments and returns a reference to
+ * this error.
+ *
+ * \sa operator<<(), args(), clearArgs()
+ */
+ LogError &addArg(const QVariant &rArg);
+
+ /*!
+ * This is an overloaded member function, provided for convenience.
+ */
+ LogError &addArg(int arg);
+
+ /*!
+ * This is an overloaded member function, provided for convenience.
+ */
+ LogError &addArg(const QString &rArg);
+
+ /*!
+ * Appends \a rLogError to the list of causing errors and returns a
+ * reference to this error.
+ *
+ * \sa causingErrors(), clearCausingErrors()
+ */
+ LogError &addCausingError(const LogError &rLogError);
+
+ /*!
+ * Returns the list of arguments that have been added to this error.
+ *
+ * \sa addArg(), operator<<(), clearArgs()
+ */
+ QList args() const;
+
+ /*!
+ * Returns the list of causing errors that have been added to this error.
+ *
+ * \sa addArg(), operator<<(), clearArgs()
+ */
+ QList causingErrors() const;
+
+ /*!
+ * Clears the list of arguments that have been added to this error.
+ *
+ * \sa addArg(), operator<<(), args()
+ */
+ void clearArgs();
+
+ /*!
+ * Clears the list of causing errors that have been added to this error.
+ *
+ * \sa addCausingError(), causingErrors()
+ */
+ void clearCausingErrors();
+
+ /*!
+ * Returns true, if the error code is 0 and the message is empty.
+ * Otherwise it returns false.
+ *
+ * \sa code(), message()
+ */
+ bool isEmpty() const;
+
+ /*!
+ * Returns the message with arguments. The arguments are incoorporated
+ * into the messag using QString::arg().
+ *
+ * \sa QString::arg(), translatedMessageWithArgs()
+ */
+ QString messageWithArgs() const;
+
+ /*!
+ * Returns the translated message with arguments. The arguments are
+ * incoorporated into the messag using QString::arg().
+ *
+ * \sa QString::arg(), messageWithArgs(), translatedMessage()
+ */
+ QString translatedMessageWithArgs() const;
+
+ /*!
+ * Appends \a rArg to the list of arguments and returns a reference to
+ * this error.
+ *
+ * \sa addArg()
+ */
+ LogError &operator<<(const QVariant &rArg);
+
+ /*!
+ * This is an overloaded member function, provided for convenience.
+ */
+ LogError &operator<<(int arg);
+
+ /*!
+ * This is an overloaded member function, provided for convenience.
+ */
+ LogError &operator<<(const QString &rArg);
+
+ /*!
+ * Returns a string representation of the error.
+ *
+ * The string has the following format:
+ *
+ *
+ * message (context::symbol, code): causing_error, causing_error
+ *
+ *
+ * If members are empty they are omitted:
+ * - Omit context, if empty
+ * - Omit symbol, if empty
+ * - Omit double colon with context and symbol, if both are empty
+ * - Omit code, if 0
+ * - Omit bracket with context/symbol and code, if all are empty
+ * - Omit colon with causing errors, if no causing errors exist
+ */
+ QString toString() const;
+
+ private:
+ QString insertArgs(const QString &rMessage) const;
+ QString cleanMessage(const QString &rMessage);
+
+ private:
+ int mCode;
+ QString mContext;
+ QString mMessage;
+ QString mSymbol;
+ QList mArgs;
+ QList mCausingErrors;
+
+#ifndef QT_NO_DATASTREAM
+ // Needs to be friend to stream objects
+ friend QDataStream &operator<<(QDataStream &rStream,
+ const LogError &rLogError);
+ friend QDataStream &operator>>(QDataStream &rStream,
+ LogError &rLogError);
+#endif // QT_NO_DATASTREAM
+ };
+
+
+ /**************************************************************************
+ * Operators, Helper
+ **************************************************************************/
+
+#ifndef QT_NO_DATASTREAM
+ /*!
+ * \relates LogError
+ *
+ * Writes the given error \a rLogError to the given stream \a rStream,
+ * and returns a reference to the stream.
+ */
+ QDataStream &operator<<(QDataStream &rStream,
+ const LogError &rLogError);
+
+ /*!
+ * \relates LogError
+ *
+ * Reads an error from the given stream \a rStream into the given
+ * error \a rLogError, and returns a reference to the stream.
+ */
+ QDataStream &operator>>(QDataStream &rStream,
+ LogError &rLogError);
+#endif // QT_NO_DATASTREAM
+
+#ifndef QT_NO_DEBUG_STREAM
+ /*!
+ * \relates LogError
+ *
+ * Writes all object member variables to the given debug stream \a debug and
+ * returns the stream.
+ *
+ *
+ * %LogError(code:7 context:"Log4Qt::FileAppender"
+ * message:"Unable to open file '%1' for appender '%2'"
+ * symbol:"APPENDER_OPENING_FILE_ERROR"
+ * args:(QVariant(QString, "G:\logs\client.log") , QVariant(QString, "Client FileAppender") )
+ * translatedMessage: "Unable to open file '%1' for appender '%2'" )
+ *
+ *
+ * \sa QDebug
+ */
+ QDebug operator<<(QDebug debug,
+ const LogError &rLogError);
+#endif // QT_NO_DEBUG_STREAM
+
+
+ /**************************************************************************
+ * Inline
+ **************************************************************************/
+
+ inline int LogError::code() const
+ { return mCode; }
+
+ inline QString LogError::context() const
+ { return mContext; }
+
+ inline QString LogError::message() const
+ { return mMessage; }
+
+ inline QString LogError::symbol() const
+ { return mSymbol; }
+
+ inline void LogError::setCode(int code)
+ { mCode = code; }
+
+ inline void LogError::setContext(const QString &rContext)
+ { mContext = rContext; }
+
+ inline void LogError::setMessage(const QString &rMessage)
+ { mMessage = cleanMessage(rMessage); }
+
+ inline void LogError::setSymbol(const QString &rSymbol)
+ { mSymbol = rSymbol; }
+
+ inline LogError &LogError::addArg(const QVariant &rArg)
+ { mArgs << rArg; return *this; }
+
+ inline LogError &LogError::addArg(int arg)
+ { mArgs << QVariant(arg); return *this; }
+
+ inline LogError &LogError::addArg(const QString &rArg)
+ { mArgs << QVariant(rArg); return *this; }
+
+ inline LogError &LogError::addCausingError(const LogError &rLogError)
+ { mCausingErrors << rLogError; return *this; }
+
+ inline QList LogError::args() const
+ { return mArgs; }
+
+ inline void LogError::clearArgs()
+ { mArgs.clear(); }
+
+ inline void LogError::clearCausingErrors()
+ { mCausingErrors.clear(); }
+
+ inline QList LogError::causingErrors() const
+ { return mCausingErrors; }
+
+ inline bool LogError::isEmpty() const
+ { return mCode || !mMessage.isEmpty(); }
+
+ inline QString LogError::messageWithArgs() const
+ { return insertArgs(message()); }
+
+ inline QString LogError::translatedMessageWithArgs() const
+ { return insertArgs(translatedMessage()); }
+
+ inline LogError &LogError::operator<<(const QVariant &rArg)
+ { return addArg(rArg); }
+
+ inline LogError &LogError::operator<<(int arg)
+ { return addArg(arg); }
+
+ inline LogError &LogError::operator<<(const QString &rArg)
+ { return addArg(rArg); }
+
+
+} // namespace Log4Qt
+
+
+Q_DECLARE_METATYPE(Log4Qt::LogError)
+Q_DECLARE_TYPEINFO(Log4Qt::LogError, Q_MOVABLE_TYPE);
+
+
+#endif // LOG4QT_ERROR_H
diff --git a/src/log4qt/log4qt/helpers/logobject.cpp b/src/log4qt/log4qt/helpers/logobject.cpp
new file mode 100644
index 0000000..44f1121
--- /dev/null
+++ b/src/log4qt/log4qt/helpers/logobject.cpp
@@ -0,0 +1,74 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: logobject.cpp
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+
+#include "log4qt/helpers/logobject.h"
+
+#include
+
+
+
+namespace Log4Qt
+{
+
+
+ /**************************************************************************
+ * Declarations
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * C helper functions
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * Class implementation: LogObject
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * Implementation: Operators, Helper
+ **************************************************************************/
+
+
+#ifndef QT_NO_DEBUG_STREAM
+ QDebug operator<<(QDebug debug,
+ const LogObject &rLogObject)
+ {
+ return rLogObject.debug(debug);
+ }
+#endif // QT_NO_DEBUG_STREAM
+
+
+
+} // namespace Log4Qt
diff --git a/src/log4qt/log4qt/helpers/logobject.h b/src/log4qt/log4qt/helpers/logobject.h
new file mode 100644
index 0000000..1c4efaf
--- /dev/null
+++ b/src/log4qt/log4qt/helpers/logobject.h
@@ -0,0 +1,218 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: logobject.h
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * changes: Sep 2008, Martin Heinrich:
+ * - Replaced usage of q_atomic_increment and q_atomic_decrement
+ * with QAtomicInt.
+ * Feb 2009, Martin Heinrich
+ * - Fixed a problem where the pParent parameter of the constructor
+ * was not passed on to the QObject constructor
+ *
+ *
+ * Copyright 2007 - 2009 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef LOG4QT_LOGOBJECT_H
+#define LOG4QT_LOGOBJECT_H
+
+#include "ukui-logmacros.h"
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+#include
+
+#include "log4qt/helpers/classlogger.h"
+#if QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)
+# include
+# ifndef Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
+# warning "QAtomicInt reference counting is not native. The class Log4Qt::LogObject is not thread-safe."
+# endif
+#endif
+
+
+namespace Log4Qt
+{
+
+ class Logger;
+
+ /*!
+ * \brief The class LogObject is the common base class for many classes
+ * in the package.
+ *
+ * The class inherits QObject to allow its subclass to be accessed using
+ * the Qt property system.
+ *
+ * LogObject objects provide a reference counter. A reference to the
+ * object is established by calling retain() and freed by calling
+ * release(). The object will delete itself when the reference counter
+ * is decremented to 0.
+ *
+ * A class specific logger can be accessed over logger().
+ *
+ * The class also implements generic streaming to QDebug. Streaming an
+ * object to QDebug will invoke debug() to create class specific output.
+ *
+ * \note All the functions declared in this class are thread-safe.
+ *
+ * \sa \ref Ownership "Object ownership",
+ * LOG4QT_DECLARE_QCLASS_LOGGER
+ */
+ class LIBUKUILOG4QT_EXPORT LogObject : public QObject
+ {
+ Q_OBJECT
+
+ public:
+ /*!
+ * Creates a LogObject which is a child of \a pObject.
+ */
+ LogObject(QObject *pObject = 0);
+
+ /*!
+ * Destroys the LogObject.
+ */
+ virtual ~LogObject();
+
+ private:
+ LogObject(const LogObject &rOther); // Not implemented
+ LogObject &operator=(const LogObject &rOther); // Not implemented
+
+ public:
+ /*!
+ * Returns the value of the reference counter.
+ */
+ int referenceCount() const;
+
+ /*!
+ * Decrements the reference count of the object. If the reference count
+ * count reaches zero and the object does not have a parent the object
+ * is deleted.
+ */
+ void release();
+
+ /*!
+ * Increments the reference count of the object.
+ */
+ void retain();
+
+ protected:
+ #ifndef QT_NO_DEBUG_STREAM
+ /*!
+ * Writes all object member variables to the given debug stream
+ * \a rDebug and returns the stream.
+ *
+ * The member function is used by
+ * QDebug operator<<(QDebug debug, const LogObject &rLogObject) to
+ * generate class specific output.
+ *
+ * \sa QDebug operator<<(QDebug debug, const LogObject &rLogObject)
+ */
+ virtual QDebug debug(QDebug &rDebug) const = 0;
+
+ // Needs to be friend to access internal data
+ friend QDebug operator<<(QDebug debug,
+ const LogObject &rLogObject);
+ #endif // QT_NO_DEBUG_STREAM
+
+ /*!
+ * Returns a pointer to a Logger named after of the object.
+ *
+ * \sa Logger::logger(const char *pName)
+ */
+ Logger* logger() const;
+
+ private:
+#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0)
+ volatile int mReferenceCount;
+#else
+ mutable QAtomicInt mReferenceCount;
+#endif
+ mutable ClassLogger mLog4QtClassLogger;
+ };
+
+
+ /**************************************************************************
+ * Operators, Helper
+ **************************************************************************/
+
+ #ifndef QT_NO_DEBUG_STREAM
+ /*!
+ * \relates LogObject
+ *
+ * Writes all object member variables to the given debug stream \a debug
+ * and returns the stream.
+ *
+ * To handle sub-classing the function uses the virtual member function
+ * debug(). This allows each class to generate its own output.
+ *
+ * \sa QDebug, debug()
+ */
+ QDebug operator<<(QDebug debug,
+ const LogObject &rLogObject);
+ #endif
+
+
+ /**************************************************************************
+ * Inline
+ **************************************************************************/
+
+ inline LogObject::LogObject(QObject *pParent) :
+ QObject(pParent),
+ mReferenceCount()
+ {}
+
+ inline LogObject::~LogObject()
+ {}
+
+ inline int LogObject::referenceCount() const
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ { return mReferenceCount; }
+#else
+ { return mReferenceCount.loadAcquire(); }
+#endif
+
+ inline void LogObject::release()
+#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0)
+ { if ((q_atomic_decrement(&mReferenceCount) == 0) && !parent())
+ delete(this); }
+#else
+ { if (!mReferenceCount.deref())
+ delete(this); }
+#endif
+
+ inline void LogObject::retain()
+#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0)
+ { q_atomic_increment(&mReferenceCount); }
+#else
+ { mReferenceCount.ref(); }
+#endif
+
+ inline Logger *LogObject::logger() const
+ { return mLog4QtClassLogger.logger(this); }
+
+} // namespace Log4Qt
+
+
+// Q_DECLARE_TYPEINFO(Log4Qt::LogObject, Q_COMPLEX_TYPE); // Use default
+
+
+#endif // LOG4QT_LOGOBJECT_H
diff --git a/src/log4qt/log4qt/helpers/logobjectptr.cpp b/src/log4qt/log4qt/helpers/logobjectptr.cpp
new file mode 100644
index 0000000..8084a79
--- /dev/null
+++ b/src/log4qt/log4qt/helpers/logobjectptr.cpp
@@ -0,0 +1,65 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: logobjectptr.cpp
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+
+#include "log4qt/helpers/logobjectptr.h"
+
+#include
+
+
+
+namespace Log4Qt
+{
+
+
+ /**************************************************************************
+ * Declarations
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * C helper functions
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * Class implementation: LogObjectPtr
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * Implementation: Operators, Helper
+ **************************************************************************/
+
+
+
+} // namespace Log4Qt
diff --git a/src/log4qt/log4qt/helpers/logobjectptr.h b/src/log4qt/log4qt/helpers/logobjectptr.h
new file mode 100644
index 0000000..7b86508
--- /dev/null
+++ b/src/log4qt/log4qt/helpers/logobjectptr.h
@@ -0,0 +1,188 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: logobjectptr.h
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef LOG4QT_LOGOBJECTPTR_H
+#define LOG4QT_LOGOBJECTPTR_H
+
+#include "ukui-logmacros.h"
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+#include "log4qt/helpers/logobject.h"
+
+namespace Log4Qt
+{
+ /*!
+ * \brief The class LogObjectPtr implements automatic reference counting
+ * for LogObject objects.
+ */
+ template
+ class LIBUKUILOG4QT_EXPORT LogObjectPtr
+ {
+ public:
+ /*!
+ * Constructs a 0 LogObject pointer.
+ */
+ LogObjectPtr();
+
+ /*!
+ * Constructs a LogObject pointer that points to the same object then
+ * \a rOther. The reference counter of the object is incremented by
+ * one.
+ */
+ LogObjectPtr(const LogObjectPtr &rOther);
+
+ /*!
+ * Constructs a LogObject pointer that points to the object
+ * \a LogObject. The reference counter of the object is incremented by
+ * one.
+ */
+ LogObjectPtr(T *pLogObject);
+
+ /*!
+ * Assignment operator. Sets the LogObject pointer to point to the
+ * same object that \a rOther points to. The reference counter of the
+ * object the LogObjectPtr pointed to before the assignment is
+ * decremented by one. The reference counter of the object \a rOther
+ * is pointing to is incremented by one.
+ */
+ LogObjectPtr &operator=(const LogObjectPtr &rOther);
+
+ /*!
+ * Destructs the object. The reference counter of the object the
+ * LogObjectPtr points to is decremented by one.
+ */
+ ~LogObjectPtr();
+
+ /*!
+ * Assignment operator. Sets the LogObject pointer to point to the
+ * object \a pLogObject. The reference counter of the object the
+ * LogObjectPtr pointed to before the assignment is decremented by
+ * one. The reference counter of the object \a pLogObject is pointing
+ * to is incremented by one.
+ */
+ LogObjectPtr &operator=(T *pLogObject);
+
+ /*!
+ * Arrow operator. Returns the LogObject the object points to.
+ */
+ T *operator->() const;
+
+ /*!
+ * Dereference operator. Returns a pointer to the LogObject the
+ * object points to.
+ */
+ T &operator*() const;
+
+ /*!
+ * Cast operator. Cast the object to the LogObject the object points
+ * to.
+ */
+ operator T*() const;
+
+ private:
+ void retain() const;
+ void release() const;
+
+ private:
+ T *mpLogObject;
+ };
+
+
+ /**************************************************************************
+ * Operators, Helper
+ **************************************************************************/
+
+
+ /**************************************************************************
+ * Inline
+ **************************************************************************/
+
+ template
+ inline LogObjectPtr::LogObjectPtr() :
+ mpLogObject(0)
+ {}
+
+ template
+ inline LogObjectPtr::LogObjectPtr(const LogObjectPtr &rOther) :
+ mpLogObject(rOther.mpLogObject)
+ { retain(); }
+
+ template
+ inline LogObjectPtr::LogObjectPtr(T *pLogObject) :
+ mpLogObject(pLogObject)
+ { retain(); }
+
+ template
+ inline LogObjectPtr &LogObjectPtr::operator=(const LogObjectPtr &rOther)
+ { rOther.retain();
+ release();
+ mpLogObject = rOther.mpLogObject;
+ return *this; }
+
+ template
+ inline LogObjectPtr::~LogObjectPtr()
+ { release(); }
+
+ template
+ inline LogObjectPtr &LogObjectPtr::operator=(T *pLogObject)
+ { if (pLogObject)
+ reinterpret_cast(pLogObject)->retain();
+ release();
+ mpLogObject = pLogObject;
+ return *this; }
+
+ template
+ inline T *LogObjectPtr::operator->() const
+ { return mpLogObject; }
+
+ template
+ inline T &LogObjectPtr::operator*() const
+ { return *mpLogObject; }
+
+ template
+ inline LogObjectPtr::operator T*() const
+ { return mpLogObject; }
+
+ template
+ inline void LogObjectPtr::retain() const
+ { if (mpLogObject)
+ reinterpret_cast(mpLogObject)->retain(); }
+
+ template
+ inline void LogObjectPtr::release() const
+ {
+ if (mpLogObject)
+ reinterpret_cast(mpLogObject)->release();
+ }
+
+} // namespace Log4Qt
+
+
+//Q_DECLARE_TYPEINFO(Log4Qt::LogObjectPtr, Q_MOVABLE_TYPE); // Declare within T
+
+
+#endif // LOG4QT_LOGOBJECTPTR_H
diff --git a/src/log4qt/log4qt/helpers/optionconverter.cpp b/src/log4qt/log4qt/helpers/optionconverter.cpp
new file mode 100644
index 0000000..a0a7b34
--- /dev/null
+++ b/src/log4qt/log4qt/helpers/optionconverter.cpp
@@ -0,0 +1,315 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: optionconverter.cpp
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * changes Feb 2009, Martin Heinrich
+ * - Fixed a problem were OptionConverter::toBoolean would not
+ * return the default value, if the conversion fails.
+ *
+ *
+ * Copyright 2007 - 2009 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+
+#include "log4qt/helpers/optionconverter.h"
+
+#include
+#include "log4qt/helpers/logerror.h"
+#include "log4qt/helpers/properties.h"
+#include "log4qt/logger.h"
+#include "log4qt/consoleappender.h"
+
+
+
+namespace Log4Qt
+{
+
+
+ /**************************************************************************
+ * Declarations
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * C helper functions
+ **************************************************************************/
+
+
+ LOG4QT_DECLARE_STATIC_LOGGER(logger, Log4Qt::OptionConverter)
+
+
+
+ /**************************************************************************
+ * Class implementation: OptionConverter
+ **************************************************************************/
+
+
+ QString OptionConverter::findAndSubst(const Properties &rProperties,
+ const QString &rKey)
+ {
+ QString value = rProperties.property(rKey);
+ if (value.isNull())
+ return value;
+
+ const QString begin_subst = QLatin1String("${");
+ const QString end_subst = QLatin1String("}");
+ const int begin_length = begin_subst.length();
+ const int end_length = end_subst.length();
+
+ // Don't return a null string, the null string indicates that the
+ // property key does not exist.
+ QString result = QLatin1String("");
+
+ int i = 0;
+ int begin;
+ int end;
+ while (i < value.length())
+ {
+ begin = value.indexOf(begin_subst, i);
+ if (begin == -1)
+ {
+ result += value.mid(i);
+ i = value.length();
+ }
+ else
+ {
+ result += value.mid(i, begin - i);
+ end = value.indexOf(end_subst, i + begin_length);
+ if (end == -1)
+ {
+ LogError e = LOG4QT_ERROR(QT_TR_NOOP("Missing closing bracket for opening bracket at %1. Invalid substitution in value %2."),
+ CONFIGURATOR_INVALID_SUBSTITUTION_ERROR,
+ "Log4Qt::OptionConverter");
+ e << begin << value;
+ logger()->error(e);
+ return result;
+ }
+ else
+ {
+ result += findAndSubst(rProperties, value.mid(begin + begin_length, end - begin - end_length - 1));
+ i = end + end_length;
+ }
+ }
+ }
+ return result;
+ }
+
+
+ QString OptionConverter::classNameJavaToCpp(const QString &rClassName)
+ {
+ const QLatin1String java_class_delimiter(".");
+ const QLatin1String cpp_class_delimiter("::");
+
+ QString result = rClassName;
+ return result.replace(java_class_delimiter, cpp_class_delimiter);
+ }
+
+
+ bool OptionConverter::toBoolean(const QString &rOption,
+ bool *p_ok)
+ {
+ const QLatin1String str_true("true");
+ const QLatin1String str_enabled("enabled");
+ const QLatin1String str_one("1");
+ const QLatin1String str_false("false");
+ const QLatin1String str_disabled("disabled");
+ const QLatin1String str_zero("0");
+
+ if (p_ok)
+ *p_ok = true;
+ QString s = rOption.trimmed().toLower();
+ if (s == str_true || s == str_enabled || s == str_one)
+ return true;
+ if (s == str_false || s == str_disabled || s == str_zero)
+ return false;
+
+ if (p_ok)
+ *p_ok = false;
+ LogError e = LOG4QT_ERROR(QT_TR_NOOP("Invalid option string '%1' for a boolean"),
+ CONFIGURATOR_INVALID_OPTION_ERROR,
+ "Log4Qt::OptionConverter");
+ e << rOption;
+ logger()->error(e);
+ return false;
+ }
+
+
+ bool OptionConverter::toBoolean(const QString &rOption,
+ bool default_value)
+ {
+ bool ok;
+ bool result = toBoolean(rOption, &ok);
+ if (ok)
+ return result;
+ else
+ return default_value;
+ }
+
+ qint64 OptionConverter::toFileSize(const QString &rOption,
+ bool *p_ok)
+ {
+ // - Search for unit
+ // - Convert characters befor unit to int
+ // - Error, if
+ // - the conversion failed
+ // - the value < 0
+ // - there is text after the unit characters
+
+ if (p_ok)
+ *p_ok = false;
+ QString s = rOption.trimmed().toLower();
+ qint64 f = 1;
+ int i;
+ i = s.indexOf(QLatin1String("kb"));
+ if (i >= 0)
+ f = 1024;
+ else
+ {
+ i = s.indexOf(QLatin1String("mb"));
+ if (i >= 0)
+ f = 1024 * 1024;
+ else
+ {
+ i = s.indexOf(QLatin1String("gb"));
+ if (i >= 0)
+ f = 1024 * 1024 * 1024;
+ }
+ }
+ if (i < 0)
+ i = s.length();
+ bool ok;
+ qint64 value = s.left(i).toLongLong(&ok);
+ if (!ok || value < 0 || s.length() > i + 2)
+ {
+ LogError e = LOG4QT_ERROR(QT_TR_NOOP("Invalid option string '%1' for a file size"),
+ CONFIGURATOR_INVALID_OPTION_ERROR,
+ "Log4Qt::OptionConverter");
+ e << rOption;
+ logger()->error(e);
+ return 0;
+ }
+ if (p_ok)
+ *p_ok = true;
+ return value * f;
+ }
+
+
+ int OptionConverter::toInt(const QString &rOption,
+ bool *p_ok)
+ {
+ int value = rOption.trimmed().toInt(p_ok);
+ if (*p_ok)
+ return value;
+
+ LogError e = LOG4QT_ERROR(QT_TR_NOOP("Invalid option string '%1' for an integer"),
+ CONFIGURATOR_INVALID_OPTION_ERROR,
+ "Log4Qt::OptionConverter");
+ e << rOption;
+ logger()->error(e);
+ return 0;
+ }
+
+ qint64 OptionConverter::toQInt64(const QString &rOption,
+ bool *p_ok)
+ {
+ int value = rOption.trimmed().toLongLong(p_ok);
+ if (*p_ok)
+ return value;
+
+ LogError e = LOG4QT_ERROR(QT_TR_NOOP("Invalid option string '%1' for an qint64"),
+ CONFIGURATOR_INVALID_OPTION_ERROR,
+ "Log4Qt::OptionConverter");
+ e << rOption;
+ logger()->error(e);
+ return 0;
+ }
+
+ Level OptionConverter::toLevel(const QString &rOption,
+ bool *p_ok)
+ {
+ bool ok;
+ Level level = Level::fromString(rOption.toUpper().trimmed(), &ok);
+ if (p_ok)
+ *p_ok = ok;
+ if (ok)
+ return level;
+
+ LogError e = LOG4QT_ERROR(QT_TR_NOOP("Invalid option string '%1' for a level"),
+ CONFIGURATOR_INVALID_OPTION_ERROR,
+ "Log4Qt::OptionConverter");
+ e << rOption;
+ logger()->error(e);
+ return level;
+ }
+
+
+ Level OptionConverter::toLevel(const QString &rOption,
+ const Level &rDefaultValue)
+ {
+ bool ok;
+ Level result = toLevel(rOption, &ok);
+ if (ok)
+ return result;
+ else
+ return rDefaultValue;
+ }
+
+
+ int OptionConverter::toTarget(const QString &rOption,
+ bool *p_ok)
+ {
+ const QLatin1String java_stdout("system.out");
+ const QLatin1String cpp_stdout("stdout_target");
+ const QLatin1String java_stderr("system.err");
+ const QLatin1String cpp_stderr("stderr_target");
+
+ if (p_ok)
+ *p_ok = true;
+ QString s = rOption.trimmed().toLower();
+ if (s == java_stdout || s == cpp_stdout)
+ return ConsoleAppender::STDOUT_TARGET;
+ if (s == java_stderr || s == cpp_stderr)
+ return ConsoleAppender::STDERR_TARGET;
+
+ if (p_ok)
+ *p_ok = false;
+ LogError e = LOG4QT_ERROR(QT_TR_NOOP("Invalid option string '%1' for a target"),
+ CONFIGURATOR_INVALID_OPTION_ERROR,
+ "Log4Qt::OptionConverter");
+ e << rOption;
+ logger()->error(e);
+ return ConsoleAppender::STDOUT_TARGET;
+ }
+
+
+
+ /**************************************************************************
+ * Implementation: Operators, Helper
+ **************************************************************************/
+
+
+
+} // namespace Log4Qt
diff --git a/src/log4qt/log4qt/helpers/optionconverter.h b/src/log4qt/log4qt/helpers/optionconverter.h
new file mode 100644
index 0000000..c29cbda
--- /dev/null
+++ b/src/log4qt/log4qt/helpers/optionconverter.h
@@ -0,0 +1,151 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: optionconverter.h
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef LOG4QT_OPTIONCONVERTER_H
+#define LOG4QT_OPTIONCONVERTER_H
+
+#include "ukui-logmacros.h"
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+#include
+#include "log4qt/level.h"
+
+namespace Log4Qt
+{
+ class Properties;
+
+ /*!
+ * \brief The class OptionConverter provides functions to convert strings
+ * to property values.
+ */
+ class LIBUKUILOG4QT_EXPORT OptionConverter
+ {
+ private:
+ OptionConverter();
+ OptionConverter(const OptionConverter &rOther); // Not implemented
+ // virtual ~OptionConverter(); // Use compiler default
+ OptionConverter &operator=(const OptionConverter &rOther); // Not implemented
+
+ public:
+ static QString findAndSubst(const Properties &rProperties,
+ const QString &rKey);
+
+ /*!
+ * Returns the JAVA class name \a rClassName as C++ class name by
+ * replacing all . characters with ::.
+ */
+ static QString classNameJavaToCpp(const QString &rClassName);
+
+ /*!
+ * Converts the option \a rOption to a boolean value. Valid strings
+ * for true are "true", "enabled" and "1". Valid strings
+ * for false are "false", "disabled" and "0". If the conversion is
+ * successful, the target is returned and \a p_ok is set to true.
+ * Otherwise an error is written to the log, \a p_ok is set to false
+ * and false is returned.
+ */
+ static bool toBoolean(const QString &rOption,
+ bool *p_ok = 0);
+
+ static bool toBoolean(const QString &rOption,
+ bool default_value);
+
+ /*!
+ * Converts the option string \a rOption to a file size. The string can
+ * be a positive integer followed by an optional unit suffix "KB", "MB"
+ * or "GB". If a unit suffix is specified the the integer is
+ * interpreted as kilobytes, megabytes or gigabytes. If the conversion
+ * is successful, the size is returned and \a p_ok is set to true.
+ * Otherwise an error is written to the log, \a p_ok is set to false
+ * and 0 is returned.
+ */
+ static qint64 toFileSize(const QString &rOption,
+ bool *p_ok = 0);
+
+ /*!
+ * Converts the option \a rOption to a integer value using
+ * QString::toInt(). If the conversion is successful, the integer is
+ * returned and \a p_ok is set to true. Otherwise an error is written
+ * to the log, \a p_ok is set to false and 0 is returned.
+ */
+ static int toInt(const QString &rOption,
+ bool *p_ok = 0);
+
+ /*!
+ * Converts the option \a rOption to a qint64 value using
+ * QString::toLongLong(). If the conversion is successful, the qint64 is
+ * returned and \a p_ok is set to true. Otherwise an error is written
+ * to the log, \a p_ok is set to false and 0 is returned.
+ */
+ static qint64 toQInt64(const QString &rOption,
+ bool *p_ok = 0);
+
+ /*!
+ * Converts the option \a rOption to a level value using
+ * Level::fromString(). If the conversion is successful, the level
+ * is returned and \a p_ok is set to true. Otherwise an error is
+ * written to the log, \a p_ok is set to false and a level with
+ * the value Level::NULL_INT is returned.
+ *
+ * \sa Level::fromString()
+ */
+ static Level toLevel(const QString &rOption,
+ bool *p_ok = 0);
+
+ static Level toLevel(const QString &rOption,
+ const Level &rDefaultValue);
+
+ /*!
+ * Converts the option \a rOption to a ConsoleAppender::Target value.
+ * Valid strings for \a rOption are "System.out", "STDOUT_TARGET",
+ * "System.err" and "STDERR_TARGET". If the conversion is successful,
+ * the target is returned and \a p_ok is set to true. Otherwise an
+ * error is written to the log, \a p_ok is set to false and
+ * ConsoleAppender::STDOUT_TARGET is returned.
+ */
+ static int toTarget(const QString &rOption,
+ bool *p_ok = 0);
+ };
+
+
+ /**************************************************************************
+ * Operators, Helper
+ **************************************************************************/
+
+
+ /**************************************************************************
+ * Inline
+ **************************************************************************/
+
+
+} // namespace Log4Qt
+
+
+Q_DECLARE_TYPEINFO(Log4Qt::OptionConverter, Q_MOVABLE_TYPE);
+
+
+#endif // LOG4QT_OPTIONCONVERTER_H
diff --git a/src/log4qt/log4qt/helpers/patternformatter.cpp b/src/log4qt/log4qt/helpers/patternformatter.cpp
new file mode 100644
index 0000000..60f5271
--- /dev/null
+++ b/src/log4qt/log4qt/helpers/patternformatter.cpp
@@ -0,0 +1,893 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: patternformatter.cpp
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * changes Feb 2009, Martin Heinrich
+ * - Fixed VS 2008 unreferenced formal parameter warning by using
+ * Q_UNUSED in LiteralPatternConverter::convert.
+ *
+ *
+ * Copyright 2007 - 2009 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+#include "log4qt/helpers/patternformatter.h"
+
+#include
+#include
+#include
+#include "log4qt/helpers/datetime.h"
+#include "log4qt/helpers/logerror.h"
+#include "log4qt/layout.h"
+#include "log4qt/logger.h"
+#include "log4qt/loggingevent.h"
+
+
+
+namespace Log4Qt
+{
+
+
+ /**************************************************************************
+ *Declarations
+ **************************************************************************/
+
+
+ /*!
+ * \brief The class FormattingInfo stores the formatting modifier for a
+ * pattern converter.
+ *
+ * \sa PatternConverter
+ */
+ class FormattingInfo
+ {
+ public:
+ FormattingInfo()
+ { clear(); }
+ // FormattingInfo(const FormattingInfo &rOther); // Use compiler default
+ // virtual ~FormattingInfo(); // Use compiler default
+ // FormattingInfo &operator=(const FormattingInfo &rOther); // Use compiler default
+
+ void clear();
+ static QString intToString(int i);
+
+ public:
+ int mMinLength;
+ int mMaxLength;
+ bool mLeftAligned;
+ };
+
+
+ /*!
+ * \brief The class PatternConverter is the abstract base class for all
+ * pattern converters.
+ *
+ * PatternConverter handles the minimum and maximum modifier for a
+ * conversion character. The actual conversion is by calling the
+ * convert() member function of the derived class.
+ *
+ * \sa PatternLayout::format()
+ */
+ class PatternConverter
+ {
+ public:
+ PatternConverter(const FormattingInfo &rFormattingInfo = FormattingInfo()) :
+ mFormattingInfo(rFormattingInfo)
+ {};
+ virtual ~PatternConverter()
+ {};
+ private:
+ PatternConverter(const PatternConverter &rOther); // Not implemented
+ PatternConverter &operator=(const PatternConverter &rOther); // Not implemented
+
+ public:
+ void format(QString &rFormat, const LoggingEvent &rLoggingEvent) const;
+
+ protected:
+ virtual QString convert(const LoggingEvent &rLoggingEvent) const = 0;
+ #ifndef QT_NO_DEBUG_STREAM
+ virtual QDebug debug(QDebug &rDebug) const = 0;
+ friend QDebug operator<<(QDebug, const PatternConverter &rPatternConverter);
+ #endif
+
+ protected:
+ FormattingInfo mFormattingInfo;
+ };
+
+
+ /*!
+ * \brief The class BasicPatternConverter converts several members of a
+ * LoggingEvent to a string.
+ *
+ * BasicPatternConverter is used by PatternLayout to convert members that
+ * do not reuquire additional formatting to a string as part of formatting
+ * the LoggingEvent. It handles the following conversion characters:
+ * 'm', 'p', 't', 'x'
+ *
+ * \sa PatternLayout::format()
+ * \sa PatternConverter::format()
+ */
+ class BasicPatternConverter : public PatternConverter
+ {
+ public:
+ enum Type {
+ MESSAGE_CONVERTER,
+ NDC_CONVERTER,
+ LEVEL_CONVERTER,
+ THREAD_CONVERTER,
+ };
+
+ public:
+ BasicPatternConverter(const FormattingInfo &rFormattingInfo,
+ Type type) :
+ PatternConverter(rFormattingInfo),
+ mType(type)
+ {};
+ // virtual ~BasicPatternConverter(); // Use compiler default
+ private:
+ BasicPatternConverter(const BasicPatternConverter &rOther); // Not implemented
+ BasicPatternConverter &operator=(const BasicPatternConverter &rOther); // Not implemented
+
+ protected:
+ virtual QString convert(const LoggingEvent &rLoggingEvent) const;
+ #ifndef QT_NO_DEBUG_STREAM
+ virtual QDebug debug(QDebug &rDebug) const;
+ #endif
+
+ private:
+ Type mType;
+ };
+
+
+ /*!
+ * \brief The class DatePatternConverter converts the time stamp of a
+ * LoggingEvent to a string.
+ *
+ * DatePatternConverter is used by PatternLayout to convert the time stamp
+ * of a LoggingEvent to a string as part of formatting the LoggingEvent.
+ * It handles the 'd' and 'r' conversion character.
+ *
+ * \sa PatternLayout::format()
+ * \sa PatternConverter::format()
+ */
+ class DatePatternConverter : public PatternConverter
+ {
+ public:
+ DatePatternConverter(const FormattingInfo &rFormattingInfo,
+ const QString &rFormat) :
+ PatternConverter(rFormattingInfo),
+ mFormat(rFormat)
+ {};
+ // virtual ~DatePatternConverter(); // Use compiler default
+ private:
+ DatePatternConverter(const DatePatternConverter &rOther); // Not implemented
+ DatePatternConverter &operator=(const DatePatternConverter &rOther); // Not implemented
+
+ protected:
+ virtual QString convert(const LoggingEvent &rLoggingEvent) const;
+ #ifndef QT_NO_DEBUG_STREAM
+ virtual QDebug debug(QDebug &rDebug) const;
+ #endif
+
+ private:
+ QString mFormat;
+ };
+
+
+ /*!
+ * \brief The class LiteralPatternConverter provides string literals.
+ *
+ * LiteralPatternConverter is used by PatternLayout to embed string
+ * literals as part of formatting the LoggingEvent. It handles string
+ * literals and the 'n' conversion character.
+ *
+ * \sa PatternLayout::format()
+ * \sa PatternConverter::format()
+ */
+ class LiteralPatternConverter : public PatternConverter
+ {
+ public:
+ LiteralPatternConverter(const QString &rLiteral) :
+ PatternConverter(),
+ mLiteral(rLiteral)
+ {};
+ // virtual ~LiteralPatternConverter(); // Use compiler default
+ private:
+ LiteralPatternConverter(const LiteralPatternConverter &rOther); // Not implemented
+ LiteralPatternConverter &operator=(const LiteralPatternConverter &rOther); // Not implemented
+
+ protected:
+ virtual QString convert(const LoggingEvent &rLoggingEvent) const;
+ #ifndef QT_NO_DEBUG_STREAM
+ virtual QDebug debug(QDebug &rDebug) const;
+ #endif
+
+ private:
+ QString mLiteral;
+ };
+
+
+ /*!
+ * \brief The class LoggerPatternConverter converts the Logger name of a
+ * LoggingEvent to a string.
+ *
+ * LoggerPatternConverter is used by PatternLayout to convert the Logger
+ * name of a LoggingEvent to a string as part of formatting the
+ * LoggingEvent. It handles the 'c' conversion character.
+ *
+ * \sa PatternLayout::format()
+ * \sa PatternConverter::format()
+ */
+ class LoggerPatternConverter : public PatternConverter
+ {
+ public:
+ LoggerPatternConverter(const FormattingInfo &rFormattingInfo,
+ int precision) :
+ PatternConverter(rFormattingInfo),
+ mPrecision(precision)
+ {};
+ // virtual ~LoggerPatternConverter(); // Use compiler default
+ private:
+ LoggerPatternConverter(const LoggerPatternConverter &rOther); // Not implemented
+ LoggerPatternConverter &operator=(const LoggerPatternConverter &rOther); // Not implemented
+
+ protected:
+ virtual QString convert(const LoggingEvent &rLoggingEvent) const;
+ #ifndef QT_NO_DEBUG_STREAM
+ virtual QDebug debug(QDebug &rDebug) const;
+ #endif
+
+ private:
+ int mPrecision;
+ };
+
+
+
+ /*!
+ * \brief The class MDCPatternConverter converts the MDC data of a
+ * LoggingEvent to a string.
+ *
+ * MDCPatternConverter is used by PatternLayout to convert the MDC data of
+ * a LoggingEvent to a string as part of formatting the LoggingEvent. It
+ * handles the 'X' conversion character.
+ *
+ * \sa PatternLayout::format()
+ * \sa PatternConverter::format()
+ */
+ class MDCPatternConverter : public PatternConverter
+ {
+ public:
+ MDCPatternConverter(const FormattingInfo &rFormattingInfo,
+ const QString &rKey) :
+ PatternConverter(rFormattingInfo),
+ mKey(rKey)
+ {};
+ // virtual ~MDCPatternConverter(); // Use compiler default
+ private:
+ MDCPatternConverter(const MDCPatternConverter &rOther); // Not implemented
+ MDCPatternConverter &operator=(const MDCPatternConverter &rOther); // Not implemented
+
+ protected:
+ virtual QString convert(const LoggingEvent &rLoggingEvent) const;
+ #ifndef QT_NO_DEBUG_STREAM
+ virtual QDebug debug(QDebug &rDebug) const;
+ #endif
+
+ private:
+ QString mKey;
+ };
+
+
+ #ifndef QT_NO_DEBUG_STREAM
+ QDebug operator<<(QDebug, const FormattingInfo &rFormattingInfo);
+ #endif
+
+
+ #ifndef QT_NO_DEBUG_STREAM
+ QDebug operator<<(QDebug, const PatternConverter &rPatternConverter);
+ #endif
+
+
+
+ /**************************************************************************
+ * C helper functions
+ **************************************************************************/
+
+
+ LOG4QT_DECLARE_STATIC_LOGGER(logger, Log4Qt::PatternFormatter)
+
+
+
+ /**************************************************************************
+ * Class implementation: PatternFormatter
+ **************************************************************************/
+
+
+ PatternFormatter::PatternFormatter(const QString &rPattern) :
+ mIgnoreCharacters(QLatin1String("CFlLM")),
+ mConversionCharacters(QLatin1String("cdmprtxX")),
+ mOptionCharacters(QLatin1String("cd")),
+ mPattern(rPattern),
+ mPatternConverters()
+ {
+ parse();
+ }
+
+
+ PatternFormatter::~PatternFormatter()
+ {
+ PatternConverter *p_converter;
+ Q_FOREACH(p_converter, mPatternConverters)
+ delete p_converter;
+ }
+
+
+ QString PatternFormatter::format(const LoggingEvent &rLoggingEvent) const
+ {
+ QString result;
+ PatternConverter *p_converter;
+ Q_FOREACH(p_converter, mPatternConverters)
+ p_converter->format(result, rLoggingEvent);
+ return result;
+ }
+
+
+ bool PatternFormatter::addDigit(const QChar &rDigit,
+ int &rValue)
+ {
+ if (!rDigit.isDigit())
+ return false;
+
+ int digit_value = rDigit.digitValue();
+ if (rValue > (INT_MAX - digit_value) / 10)
+ rValue = INT_MAX;
+ else
+ rValue = rValue * 10 + digit_value;
+ return true;
+ }
+
+
+ void PatternFormatter::createConverter(const QChar &rChar,
+ const FormattingInfo &rFormattingInfo,
+ const QString &rOption)
+ {
+ Q_ASSERT_X(mConversionCharacters.indexOf(rChar) >= 0, "PatternFormatter::createConverter", "Unknown conversion character" );
+
+ LogError e("Creating Converter for character '%1' min %2, max %3, left %4 and option '%5'");
+ e << QString(rChar)
+ << FormattingInfo::intToString(rFormattingInfo.mMinLength)
+ << FormattingInfo::intToString(rFormattingInfo.mMaxLength)
+ << rFormattingInfo.mLeftAligned
+ << rOption;
+ logger()->trace(e);
+
+ switch (rChar.toLatin1())
+ {
+ case 'c':
+ mPatternConverters << new LoggerPatternConverter(rFormattingInfo,
+ parseIntegerOption(rOption));
+ break;
+ case 'd':
+ {
+ QString option = rOption;
+ if (rOption.isEmpty())
+ option = QLatin1String("ISO8601");
+ mPatternConverters << new DatePatternConverter(rFormattingInfo,
+ option);
+ break;
+ }
+ case 'm':
+ mPatternConverters << new BasicPatternConverter(rFormattingInfo,
+ BasicPatternConverter::MESSAGE_CONVERTER);
+ break;
+ case 'p':
+ mPatternConverters << new BasicPatternConverter(rFormattingInfo,
+ BasicPatternConverter::LEVEL_CONVERTER);
+ break;
+ case 'r':
+ mPatternConverters << new DatePatternConverter(rFormattingInfo,
+ QLatin1String("TIME_RELATIVE"));
+ break;
+ case 't':
+ mPatternConverters << new BasicPatternConverter(rFormattingInfo,
+ BasicPatternConverter::THREAD_CONVERTER);
+ break;
+ case 'x':
+ mPatternConverters << new BasicPatternConverter(rFormattingInfo,
+ BasicPatternConverter::NDC_CONVERTER);
+ break;
+ case 'X':
+ mPatternConverters << new MDCPatternConverter(rFormattingInfo,
+ rOption);
+ break;
+ default:
+ Q_ASSERT_X(false, "PatternFormatter::createConverter", "Unknown pattern character");
+ }
+ }
+
+
+ void PatternFormatter::createLiteralConverter(const QString &rLiteral)
+ {
+ logger()->trace("Creating literal LiteralConverter with Literal '%1'",
+ rLiteral);
+ mPatternConverters << new LiteralPatternConverter(rLiteral);
+ }
+
+
+ void PatternFormatter::parse()
+ {
+ enum State {
+ LITERAL_STATE,
+ ESCAPE_STATE,
+ MIN_STATE,
+ DOT_STATE,
+ MAX_STATE,
+ CHARACTER_STATE,
+ POSSIBLEOPTION_STATE,
+ OPTION_STATE
+ };
+
+ int i = 0;
+ QChar c;
+ char ch;
+ State state = LITERAL_STATE;
+ FormattingInfo formatting_info;
+ QString literal;
+ int converter_start;
+ int option_start;
+ while (i < mPattern.length())
+ {
+ // i points to the current character
+ // c contains the current character
+ // ch contains the Latin1 equivalent of the current character
+ // i is incremented at the end of the loop to consume the character
+ // continue is used to change state without consuming the character
+
+ c = mPattern.at(i);
+ ch = c.toLatin1();
+ switch (state)
+ {
+ case LITERAL_STATE:
+ if (ch == '%')
+ {
+ formatting_info.clear();
+ converter_start = i;
+ state = ESCAPE_STATE;
+ } else
+ literal += c;
+ break;
+ case ESCAPE_STATE:
+ if (ch == '%')
+ {
+ literal += c;
+ state = LITERAL_STATE;
+ }
+ else if (ch == 'n')
+ {
+ literal += Layout::endOfLine();
+ state = LITERAL_STATE;
+ }
+ else
+ {
+ if (!literal.isEmpty())
+ {
+ createLiteralConverter(literal);
+ literal.clear();
+ }
+ if (ch == '-')
+ formatting_info.mLeftAligned = true;
+ else if (c.isDigit())
+ {
+ formatting_info.mMinLength = c.digitValue();
+ state = MIN_STATE;
+ }
+ else if (ch == '.')
+ state = DOT_STATE;
+ else
+ {
+ state = CHARACTER_STATE;
+ continue;
+ }
+ }
+ break;
+ case MIN_STATE:
+ if (!addDigit(c, formatting_info.mMinLength))
+ {
+ if (ch == '.')
+ state = DOT_STATE;
+ else
+ {
+ state = CHARACTER_STATE;
+ continue;
+ }
+ }
+ break;
+ case DOT_STATE:
+ if (c.isDigit())
+ {
+ formatting_info.mMaxLength = c.digitValue();
+ state = MAX_STATE;
+ }
+ else
+ {
+ LogError e = LOG4QT_ERROR(QT_TR_NOOP("Found character '%1' where digit was expected."),
+ LAYOUT_EXPECTED_DIGIT_ERROR,
+ "Log4Qt::PatternFormatter");
+ e << QString(c);
+ logger()->error(e);
+ }
+ break;
+ case MAX_STATE:
+ if (!addDigit(c, formatting_info.mMaxLength))
+ {
+ state = CHARACTER_STATE;
+ continue;
+ }
+ break;
+ case CHARACTER_STATE:
+ if (mIgnoreCharacters.indexOf(c) >= 0)
+ state = LITERAL_STATE;
+ else if (mOptionCharacters.indexOf(c) >= 0)
+ state = POSSIBLEOPTION_STATE;
+ else if (mConversionCharacters.indexOf(c) >= 0)
+ {
+ createConverter(c, formatting_info);
+ state = LITERAL_STATE;
+ }
+ else
+ {
+ logger()->warn("Invalid conversion character '%1' at %2 in pattern '%3'",
+ c, i, mPattern);
+ createLiteralConverter(mPattern.mid(converter_start, i - converter_start + 1));
+ state = LITERAL_STATE;
+ }
+ break;
+ case POSSIBLEOPTION_STATE:
+ if (ch == '{')
+ {
+ option_start = i;
+ state = OPTION_STATE;
+ }
+ else
+ {
+ createConverter(mPattern.at(i - 1),
+ formatting_info);
+ state = LITERAL_STATE;
+ continue;
+ }
+ break;
+ case OPTION_STATE:
+ if (ch == '}')
+ {
+ createConverter(mPattern.at(option_start - 1),
+ formatting_info,
+ mPattern.mid(option_start + 1, i - option_start - 1));
+ state = LITERAL_STATE;
+ }
+ break;
+ default:
+ Q_ASSERT_X(false, "PatternFormatter::parse()", "Unknown parsing state constant");
+ state = LITERAL_STATE;
+ }
+ i++;
+ }
+
+ if (state != LITERAL_STATE)
+ {
+ logger()->warn("Unexptected end of pattern '%1'", mPattern);
+ if (state == ESCAPE_STATE)
+ literal += c;
+ else
+ literal += mPattern.mid(converter_start);
+ }
+
+ if (!literal.isEmpty())
+ createLiteralConverter(literal);
+ }
+
+
+ int PatternFormatter::parseIntegerOption(const QString &rOption)
+ {
+ if (rOption.isEmpty())
+ return 0;
+
+ bool ok;
+ int result = rOption.toInt(&ok);
+ if (!ok)
+ {
+ LogError e = LOG4QT_ERROR(QT_TR_NOOP("Option '%1' cannot be converted into an integer"),
+ LAYOUT_OPTION_IS_NOT_INTEGER_ERROR,
+ "Log4Qt::PatterFormatter");
+ e << rOption;
+ logger()->error(e);
+ }
+ if (result < 0)
+ {
+ LogError e = LOG4QT_ERROR(QT_TR_NOOP("Option %1 isn't a positive integer"),
+ LAYOUT_INTEGER_IS_NOT_POSITIVE_ERROR,
+ "Log4Qt::PatterFormatter");
+ e << result;
+ logger()->error(e);
+ result = 0;
+ }
+ return result;
+ }
+
+
+ /**************************************************************************
+ * Class implementation: FormattingInfo
+ **************************************************************************/
+
+
+ void FormattingInfo::clear()
+ {
+ mMinLength = 0;
+ mMaxLength = INT_MAX;
+ mLeftAligned = false;
+ };
+
+
+ QString FormattingInfo::intToString(int i)
+ {
+ if (i == INT_MAX)
+ return QLatin1String("INT_MAX");
+ else
+ return QString::number(i);
+ }
+
+
+
+ /**************************************************************************
+ * Class implementation: PatternConverter
+ **************************************************************************/
+
+
+ void PatternConverter::format(QString &rFormat, const LoggingEvent &rLoggingEvent) const
+ {
+ const QLatin1Char space(' ');
+ QString s = convert(rLoggingEvent);
+
+ if (s.length() > mFormattingInfo.mMaxLength)
+ rFormat += s.left(mFormattingInfo.mMaxLength);
+ else if (mFormattingInfo.mLeftAligned)
+ rFormat += s.leftJustified(mFormattingInfo.mMinLength, space, false);
+ else
+ rFormat += s.rightJustified(mFormattingInfo.mMinLength, space, false);
+ }
+
+
+
+ /**************************************************************************
+ * Class implementation: BasicPatternConverter
+ **************************************************************************/
+
+
+ QString BasicPatternConverter::convert(const LoggingEvent &rLoggingEvent) const
+ {
+ switch (mType)
+ {
+ case MESSAGE_CONVERTER:
+ return rLoggingEvent.message();
+ break;
+ case NDC_CONVERTER:
+ return rLoggingEvent.ndc();
+ break;
+ case LEVEL_CONVERTER:
+ return rLoggingEvent.level().toString();
+ break;
+ case THREAD_CONVERTER:
+ return rLoggingEvent.threadName();
+ break;
+ default:
+ Q_ASSERT_X(false, "BasicPatternConverter::convert()", "Unkown type constant");
+ return QString();
+ }
+ }
+
+
+ QDebug BasicPatternConverter::debug(QDebug &rDebug) const
+ {
+ QString type;
+ switch (mType)
+ {
+ case MESSAGE_CONVERTER:
+ type = QLatin1String("MESSAGE_CONVERTER");
+ break;
+ case NDC_CONVERTER:
+ type = QLatin1String("NDC_CONVERTER");
+ break;
+ case LEVEL_CONVERTER:
+ type = QLatin1String("LEVEL_CONVERTER");
+ break;
+ case THREAD_CONVERTER:
+ type = QLatin1String("THREAD_CONVERTER");
+ break;
+ default:
+ Q_ASSERT_X(false, "BasicPatternConverter::debug()", "Unkown type constant");
+ }
+ rDebug.nospace() << "BasicPatternConverter("
+ << mFormattingInfo
+ << "type:" << type
+ << ")";
+ return rDebug.space();
+ }
+
+
+
+ /**************************************************************************
+ * Class implementation: DatePatternConverter
+ **************************************************************************/
+
+
+ QString DatePatternConverter::convert(const LoggingEvent &rLoggingEvent) const
+ {
+ return DateTime::fromMilliSeconds(rLoggingEvent.timeStamp()).toString(mFormat);
+ }
+
+
+ QDebug DatePatternConverter::debug(QDebug &rDebug) const
+ {
+ rDebug.nospace() << "DatePatternConverter("
+ << mFormattingInfo
+ << "format:" << mFormat
+ << ")";
+ return rDebug.space();
+ }
+
+
+
+ /**************************************************************************
+ * Class implementation: LiteralPatternConverter
+ **************************************************************************/
+
+
+ QString LiteralPatternConverter::convert(const LoggingEvent &rLoggingEvent) const
+ {
+ Q_UNUSED(rLoggingEvent);
+ return mLiteral;
+ };
+
+
+ QDebug LiteralPatternConverter::debug(QDebug &rDebug) const
+ {
+ rDebug.nospace() << "LiteralPatternConverter("
+ << mFormattingInfo
+ << "literal:" << mLiteral
+ << ")";
+ return rDebug.space();
+ }
+
+
+
+ /**************************************************************************
+ * Class implementation: LoggerPatternConverter
+ **************************************************************************/
+
+
+ QString LoggerPatternConverter::convert(const LoggingEvent &rLoggingEvent) const
+ {
+ if (!rLoggingEvent.logger())
+ return QString();
+ QString name = rLoggingEvent.logger()->name();
+ if (mPrecision <= 0 || (name.isEmpty()))
+ return name;
+
+ const QString separator(QLatin1String("::"));
+
+ int i = mPrecision;
+ int begin = name.length();
+ while ((i > 0) && (begin >= 0))
+ {
+ begin = name.lastIndexOf(separator, begin - name.length() - 1);
+ i--;
+ }
+ if (begin < 0)
+ begin = 0;
+ else
+ begin += 2;
+ return name.mid(begin);
+ }
+
+
+ QDebug LoggerPatternConverter::debug(QDebug &rDebug) const
+ {
+ rDebug.nospace() << "LoggerPatternConverter("
+ << mFormattingInfo
+ << "precision:" << mPrecision
+ << ")";
+ return rDebug.space();
+ }
+
+
+
+ /******************************************************************************
+ * Class implementation: MDCPatternConverter
+ ******************************************************************************/
+
+
+ QString MDCPatternConverter::convert(const LoggingEvent &rLoggingEvent) const
+ {
+ return rLoggingEvent.mdc().value(mKey);
+ };
+
+
+ QDebug MDCPatternConverter::debug(QDebug &rDebug) const
+ {
+ rDebug.nospace() << "MDCPatternConverter("
+ << mFormattingInfo
+ << "key:" << mKey
+ << ")";
+ return rDebug.space();
+ }
+
+
+
+ /**************************************************************************
+ * Implementation: Operators, Helper
+ **************************************************************************/
+
+
+ #ifndef QT_NO_DEBUG_STREAM
+ QDebug operator<<(QDebug debug, const PatternFormatter &rPatternFormatter)
+ {
+ debug.nospace() << "PatternFormatter("
+ << "pattern:" << rPatternFormatter.mPattern << " "
+ << "converters:(";
+ int i;
+ for (i = 0; i < rPatternFormatter.mPatternConverters.size(); i++)
+ {
+ if (i > 0)
+ debug.nospace() << ", ";
+ debug.nospace() << *rPatternFormatter.mPatternConverters.at(i);
+ }
+ debug.nospace() << ") )";
+ return debug.space();
+ }
+ #endif
+
+
+#ifndef QT_NO_DEBUG_STREAM
+ QDebug operator<<(QDebug debug, const FormattingInfo &rFormattingInfo)
+ {
+ debug.nospace() << "FormattingInfo("
+ << "min:" << FormattingInfo::intToString(rFormattingInfo.mMinLength) << " "
+ << "max:" << FormattingInfo::intToString(rFormattingInfo.mMaxLength) << " "
+ << "left:" << rFormattingInfo.mLeftAligned
+ << ")";
+ return debug.space();
+ }
+#endif // QT_NO_DEBUG_STREAM
+
+
+#ifndef QT_NO_DEBUG_STREAM
+ QDebug operator<<(QDebug debug, const PatternConverter &rPatternConverter)
+ {
+ return rPatternConverter.debug(debug);
+ }
+#endif // QT_NO_DEBUG_STREAM
+
+
+
+} // namespace Log4Qt
diff --git a/src/log4qt/log4qt/helpers/patternformatter.h b/src/log4qt/log4qt/helpers/patternformatter.h
new file mode 100644
index 0000000..fa21a19
--- /dev/null
+++ b/src/log4qt/log4qt/helpers/patternformatter.h
@@ -0,0 +1,196 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: patternformatter.h
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef LOG4QT_PATTERNFORMATTER_H
+#define LOG4QT_PATTERNFORMATTER_H
+
+#include "ukui-logmacros.h"
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+#include
+#include
+
+
+/******************************************************************************
+ * Declarations
+ ******************************************************************************/
+
+
+namespace Log4Qt
+{
+
+ class FormattingInfo;
+ class PatternConverter;
+ class LoggingEvent;
+
+ /*!
+ * \brief The class PatternFormatter formats a logging event based on a
+ * pattern string.
+ *
+ * The class PatternFormatter formats a LoggingEvent base on a pattern
+ * string. It is used by the patternLayout and TTCCLayout class to
+ * implement the formatting.
+ *
+ * On object construction the provided patterns tring is parsed. Based on
+ * the information found a chain of PatternConverter is created. Each
+ * PatternConverter handles a certain member of a LoggingEvent.
+ *
+ * \sa PatternLayout::format()
+ * \sa TTCCLayout::format()
+ */
+ class LIBUKUILOG4QT_EXPORT PatternFormatter
+ {
+ public:
+ /*!
+ * Creates a PatternFormatter using a the specified \a rPattern.
+ */
+ PatternFormatter(const QString &rPattern);
+
+ /*!
+ * Destroys the PatternFormatter and all PatternConverter.
+ */
+ virtual ~PatternFormatter();
+
+ private:
+ PatternFormatter(const PatternFormatter &rOther); // Not implemented
+ PatternFormatter &operator=(const PatternFormatter &rOther); // Not implemented
+
+ public:
+ /*!
+ * Formats the given \a rLoggingEvent using the chain of
+ * PatternConverter created during construction from the specified
+ * pattern.
+ */
+ QString format(const LoggingEvent &rLoggingEvent) const;
+
+ private:
+ /*!
+ * If the character \a rDigit is a digit the digit is added to the
+ * integer \a rValue and the function returns true. Otherwise the
+ * function returns false.
+ *
+ * The function adds the digit by multiplying the existing value
+ * with ten and adding the numerical value of the digit. If the
+ * maximum integer value would be exceeded by the operation
+ * \a rValue is set to INT_MAX.
+ */
+ bool addDigit(const QChar &rDigit,
+ int &rValue);
+
+ /*!
+ * Creates a PatternConverter based on the specified conversion
+ * character \a rChar, the formatting information
+ * \a rFormattingInfo and the option \a rOption.
+ *
+ * The PatternConverter converter is appended to the list of
+ * PatternConverters.
+ */
+ void createConverter(const QChar &rChar,
+ const FormattingInfo &rFormattingInfo,
+ const QString &rOption = QString());
+
+ /*!
+ * Creates a LiteralPatternConverter with the string literal
+ * \a rLiteral.
+ *
+ * The PatternConverter converter is appended to the list of
+ * PatternConverters.
+ */
+ void createLiteralConverter(const QString &rLiteral);
+
+ /*!
+ * Parses the pattern string specified on construction and creates
+ * PatternConverter according to it.
+ */
+ void parse();
+
+ /*!
+ * Parses an integer option from an option string. If the string is
+ * not a valid integer or the integer value is less then zero, zero
+ * is returned. Returns the end of line seperator for the operating
+ * system.
+ */
+ int parseIntegerOption(const QString &rOption);
+
+ private:
+ const QString mIgnoreCharacters;
+ const QString mConversionCharacters;
+ const QString mOptionCharacters;
+ QString mPattern;
+ QList mPatternConverters;
+
+ // Needs to be friend to access internal data
+ friend QDebug operator<<(QDebug, const PatternFormatter &rPatternFormatter);
+ };
+
+
+ /**************************************************************************
+ * Operators, Helper
+ **************************************************************************/
+
+#ifndef QT_NO_DEBUG_STREAM
+ /*!
+ * \relates PatternFormatter
+ *
+ * Writes all object member variables to the given debug stream \a rDebug and
+ * returns the stream.
+ *
+ *
+ * %PatternFormatter(pattern:"%r [%t] %p %c %x - %m%n"
+ * converters:(
+ * DatePatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) format: "TIME_RELATIVE" ) ,
+ * LiteralPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) literal: " [" ) ,
+ * BasicPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) type: "THREAD_CONVERTER" ) ,
+ * LiteralPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) literal: "] " ) ,
+ * BasicPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) type: "LEVEL_CONVERTER" ) ,
+ * LiteralPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) literal: " " ) ,
+ * LoggerPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) precision: 0 ) ,
+ * LiteralPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) literal: " " ) ,
+ * BasicPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) type: "NDC_CONVERTER" ) ,
+ * LiteralPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) literal: " - " ) ,
+ * BasicPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) type: "MESSAGE_CONVERTER" ) ,
+ * LiteralPatternConverter(FormattingInfo(min:"0" max:"INT_MAX" left:false) literal: "" ) ) )
+ *
+ * \sa QDebug
+ */
+ QDebug operator<<(QDebug debug,
+ const PatternFormatter &rPatternFormatter);
+#endif // QT_NO_DEBUG_STREAM
+
+
+ /**************************************************************************
+ * Inline
+ **************************************************************************/
+
+
+} // namespace Log4Qt
+
+
+Q_DECLARE_TYPEINFO(Log4Qt::PatternFormatter, Q_MOVABLE_TYPE);
+
+
+#endif // LOG4QT_PATTERNFORMATTER_H
diff --git a/src/log4qt/log4qt/helpers/properties.cpp b/src/log4qt/log4qt/helpers/properties.cpp
new file mode 100644
index 0000000..96d04d7
--- /dev/null
+++ b/src/log4qt/log4qt/helpers/properties.cpp
@@ -0,0 +1,364 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: properties.cpp
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+
+#include "log4qt/helpers/properties.h"
+
+#include
+#include
+#include
+#include
+#include "log4qt/logger.h"
+
+
+
+namespace Log4Qt
+{
+
+
+
+ /**************************************************************************
+ *Declarations
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * C helper functions
+ **************************************************************************/
+
+
+ LOG4QT_DECLARE_STATIC_LOGGER(logger, Log4Qt::Properties)
+
+
+
+ /**************************************************************************
+ * Class implementation: Properties
+ **************************************************************************/
+
+
+ void Properties::load(QIODevice *pDevice)
+ {
+ const QLatin1Char append_char(msEscapeChar);
+
+ if (!pDevice)
+ {
+ logger()->warn("No device specified for load.");
+ return;
+ }
+
+ QTextStream stream(pDevice);
+ QString line;
+ int line_number = 0;
+ QString property;
+ int property_start_line = 1;
+
+ do {
+ line = trimLeft(stream.readLine());
+ line_number++;
+
+ if (!line.isEmpty() && line.at(line.length() - 1) == append_char)
+ property += line.left(line.length() - 1);
+ else
+ {
+ property += line;
+ parseProperty(property, property_start_line);
+ property.clear();
+ property_start_line = line_number + 1;
+ }
+ }
+ while (!line.isNull());
+ }
+
+
+ void Properties::load(const QSettings &rSettings)
+ {
+ QStringList keys = rSettings.childKeys();
+ QString key;
+ Q_FOREACH(key, keys)
+ insert(key, rSettings.value(key).toString());
+ }
+
+
+ QString Properties::property(const QString &rKey) const
+ {
+ // Null string indicates the property does not contain the key.
+
+ if (contains(rKey))
+ {
+ QString value = this->value(rKey);
+ if (value.isNull())
+ return QString(QLatin1String(""));
+ else
+ return value;
+ }
+
+ if (mpDefaultProperties)
+ return mpDefaultProperties->property(rKey);
+ else
+ return QString();
+ }
+
+
+ QString Properties::property(const QString &rKey,
+ const QString &rDefaultValue) const
+ {
+ QString value = property(rKey);
+ if (value.isNull())
+ return rDefaultValue;
+ else
+ return value;
+ }
+
+
+ QStringList Properties::propertyNames() const
+ {
+ QStringList default_keys;
+ if (mpDefaultProperties)
+ default_keys = mpDefaultProperties->propertyNames();
+
+ QStringList keys = this->keys();
+ QString key;
+ Q_FOREACH(key, default_keys)
+ if (!keys.contains(key))
+ keys << key;
+
+ return keys;
+ }
+
+
+ void Properties::parseProperty(const QString &rProperty,
+ int line)
+ {
+ Q_ASSERT_X(rProperty == trimLeft(rProperty), "parseProperty()", "rProperty has leading spaces");
+
+ enum State
+ {
+ KEY_STATE,
+ KEYSPACE_STATE,
+ SPACEVALUE_STATE,
+ VALUE_STATE,
+ KEYESCAPE_STATE,
+ VALUEESCAPE_STATE,
+ UNICODEESCAPE_STATE
+ };
+ const QString value_escape_codes =QLatin1String(msValueEscapeCodes);
+ const QString value_escape_chars = QLatin1String(msValueEscapeChars);
+ Q_ASSERT_X(value_escape_codes.length() == value_escape_chars.length(), "parseProperty()", "Value escape sequence character definition does not map");
+ const QString key_escape_codes = QLatin1String(msKeyEscapeCodes);
+ const QString key_escape_chars = QLatin1String(msKeyEscapeChars);
+ Q_ASSERT_X(key_escape_codes.length() == key_escape_chars.length(), "parseProperty()", "Key escape sequence character definition does not map");
+
+ if (rProperty.isEmpty())
+ return;
+
+ int i = 0;
+ QChar c;
+ char ch;
+ State state = KEY_STATE;
+ QString key;
+ QString value;
+ QString *p_string = &key;
+ uint ucs;
+ int ucs_digits;
+ while (i < rProperty.length())
+ {
+ // i points to the current character.
+ // c contains the current character
+ // ch contains the Latin1 equivalent of the current character
+ // i is incremented at the end of the loop to consume the character.
+ // continue is used to change state without consuming the character
+
+ c = rProperty.at(i);
+ ch = c.toLatin1();
+
+ switch (state)
+ {
+ case KEY_STATE:
+ if (ch == '!' || ch == '#' )
+ return;
+ else if (c.isSpace())
+ {
+ p_string = &value;
+ state = KEYSPACE_STATE;
+ }
+ else if (ch == '=' || ch == ':')
+ {
+ p_string = &value;
+ state = SPACEVALUE_STATE;
+ }
+ else if (ch == msEscapeChar)
+ state = KEYESCAPE_STATE;
+ else
+ *p_string += c;
+ break;
+ case KEYSPACE_STATE:
+ if (ch == '=' || ch == ':')
+ state = SPACEVALUE_STATE;
+ else if (!c.isSpace())
+ {
+ *p_string += c;
+ state = VALUE_STATE;
+ }
+ break;
+ case SPACEVALUE_STATE:
+ if (!c.isSpace())
+ {
+ *p_string += c;
+ state = VALUE_STATE;
+ }
+ break;
+ case VALUE_STATE:
+ if (ch == msEscapeChar)
+ state = VALUEESCAPE_STATE;
+ else
+ *p_string += c;
+ break;
+ case KEYESCAPE_STATE:
+ {
+ int convert = key_escape_codes.indexOf(c);
+ if (convert >= 0)
+ *p_string += key_escape_chars.at(convert);
+ else
+ {
+ logger()->warn("Unknown escape sequence '\\%1' in key of property starting at line %2",
+ QString(c),
+ line);
+ *p_string += c;
+ }
+ state = KEY_STATE;
+ break;
+ }
+ case VALUEESCAPE_STATE:
+ {
+ int convert = value_escape_codes.indexOf(c);
+ if (convert >= 0)
+ {
+ *p_string += value_escape_chars.at(convert);
+ state = VALUE_STATE;
+ }
+ else if (ch == 'u')
+ {
+ ucs = 0;
+ ucs_digits = 0;
+ state = UNICODEESCAPE_STATE;
+ }
+ else
+ {
+ logger()->warn("Unknown escape sequence '\\%1' in value of property starting at line %2", QString(c), line);
+ *p_string += c;
+ state = VALUE_STATE;
+ }
+ break;
+ }
+ case UNICODEESCAPE_STATE:
+ {
+ int hex = hexDigitValue(c);
+ if (hex >= 0)
+ {
+ ucs = ucs * 16 + hex;
+ ucs_digits++;
+ if (ucs_digits == 4 || i == rProperty.length() - 1)
+ {
+ *p_string += QChar(ucs);
+ state = VALUE_STATE;
+ }
+ }
+ else
+ {
+ if (ucs_digits > 0)
+ *p_string += QChar(ucs);
+ state = VALUE_STATE;
+ continue;
+ }
+ break;
+ }
+ default:
+ Q_ASSERT_X(false, "Properties::parseProperty()", "Unknown state constant");
+ return;
+ }
+ i++;
+ }
+
+ if (key.isEmpty() && !value.isEmpty())
+ logger()->warn("Found value with no key in property starting at line %1", line);
+
+ logger()->trace("Loaded property '%1' : '%2'", key, value);
+ insert(key, value);
+ }
+
+
+ int Properties::hexDigitValue(const QChar &rDigit)
+ {
+ bool ok;
+ int result = QString(rDigit).toInt(&ok, 16);
+ if (!ok)
+ return -1;
+ else
+ return result;
+ }
+
+
+ QString Properties::trimLeft(const QString &rLine)
+ {
+ int i = 0;
+ while (i < rLine.length() && rLine.at(i).isSpace())
+ i++;
+ return rLine.right(rLine.length() - i);
+ }
+
+
+ const char Properties::msEscapeChar ='\\';
+ const char *Properties::msValueEscapeCodes = "tnr\\\"\' ";
+ const char *Properties::msValueEscapeChars = "\t\n\r\\\"\' ";
+ const char *Properties::msKeyEscapeCodes = " :=";
+ const char *Properties::msKeyEscapeChars = " :=";
+
+
+
+ /**************************************************************************
+ * Implementation: Operators, Helper
+ **************************************************************************/
+
+
+#ifndef QT_NO_DEBUG_STREAM
+ QDebug operator<<(QDebug debug, const Properties &rProperties)
+ {
+ debug.nospace() << "Properties("
+ << "default:" << rProperties.defaultProperties() << " "
+ << "properties:" << *reinterpret_cast *>(&rProperties)
+ << ")";
+ return debug.space();
+ }
+#endif
+
+
+
+} // namespace Log4Qt
diff --git a/src/log4qt/log4qt/helpers/properties.h b/src/log4qt/log4qt/helpers/properties.h
new file mode 100644
index 0000000..71566fc
--- /dev/null
+++ b/src/log4qt/log4qt/helpers/properties.h
@@ -0,0 +1,162 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: properties.h
+ * created: September
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef LOG4QT_PROPERTIES_H
+#define LOG4QT_PROPERTIES_H
+
+#include "ukui-logmacros.h"
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+#include
+#include
+
+
+/******************************************************************************
+ * Declarations
+ ******************************************************************************/
+
+class QIODevice;
+class QSettings;
+
+
+namespace Log4Qt
+{
+ /*!
+ * \brief The class Properties implements a JAVA property hash.
+ */
+ class LIBUKUILOG4QT_EXPORT Properties : public QHash
+ {
+ public:
+ Properties(Properties *pDefaultProperties = 0);
+ // virtual ~Properties(); // Use compiler default
+ // Properties(const Properties &rOther); // Use compiler default
+ // Properties &operator=(const Properties &rOther); // Not implemented
+
+ public:
+ Properties *defaultProperties() const;
+ QString property(const QString &rKey) const;
+ QString property(const QString &rKey,
+ const QString &rDefaultValue) const;
+ void setDefaultProperties(Properties *pDefault);
+ void setProperty(const QString &rKey,
+ const QString &rValue);
+
+ // JAVA: void list(QTextStream &rTextStream);
+ void load(QIODevice *pDevice);
+
+ /*!
+ * Reads all child keys from the QSettings object \a rSettings and
+ * inserts them into this object. The value is created using
+ * QVariant::toString(). Types that do not support toString() are
+ * resulting in an empty string.
+ *
+ * \code
+ * QSettings settings;
+ * settings.setValue("Package", "Full");
+ * settings.setValue("Background", Qt::white);
+ * settings.setValue("Support", true);
+ * settings.setValue("Help/Language", "en_UK");
+ *
+ * Properties properties
+ * properties.load(&settings)
+ *
+ * // properties (("Package", "Full"), ("Background", ""), ("Support", "true"))
+ * \endcode
+ */
+ void load(const QSettings &rSettings);
+
+ QStringList propertyNames() const;
+ // JAVA: void save(QIODevice *pDevice) const;
+
+ private:
+ void parseProperty(const QString &rProperty,
+ int line);
+ static int hexDigitValue(const QChar &rDigit);
+ static QString trimLeft(const QString &rString);
+
+ private:
+ Properties *mpDefaultProperties;
+ static const char msEscapeChar;
+ static const char *msValueEscapeCodes;
+ static const char *msValueEscapeChars;
+ static const char *msKeyEscapeCodes;
+ static const char *msKeyEscapeChars;
+ };
+
+
+ /**************************************************************************
+ * Operators, Helper
+ **************************************************************************/
+
+#ifndef QT_NO_DEBUG_STREAM
+ /*!
+ * \relates Properties
+ *
+ * Writes all object member variables to the given debug stream \a rDebug and
+ * returns the stream.
+ *
+ *
+ * %Properties(default:0x0 properties:QHash(("log4j.appender.testAppender.layout", "org.apache.log4j.PatternLayout ")
+ * ("log4j.appender.testAppender.layout.ConversionPattern", "[%t] %-5p %l: %m%n")
+ * ("log4j.appender.testAppender.Append", "false ")
+ * ("log4j.appender.testAppender.File", "output/temp ")
+ * ("log4j.rootCategory", "TRACE, testAppender")
+ * ("log4j.appender.testAppender", "org.apache.log4j.FileAppender")) )
+ *
+ * \sa QDebug
+ */
+ QDebug operator<<(QDebug debug,
+ const Properties &rProperties);
+#endif // QT_NO_DEBUG_STREAM
+
+
+ /**************************************************************************
+ * Inline
+ **************************************************************************/
+
+ inline Properties::Properties(Properties *pDefaultProperties) :
+ mpDefaultProperties(pDefaultProperties)
+ {}
+
+ inline Properties *Properties::defaultProperties() const
+ { return mpDefaultProperties; }
+
+ inline void Properties::setDefaultProperties(Properties *pDefaultProperties)
+ { mpDefaultProperties = pDefaultProperties; }
+
+ inline void Properties::setProperty(const QString &rKey,
+ const QString &rValue)
+ { insert(rKey, rValue); }
+
+
+} // namespace Log4Qt
+
+
+Q_DECLARE_TYPEINFO(Log4Qt::Properties, Q_MOVABLE_TYPE);
+
+
+#endif // LOG4QT_PROPERTIES_H
diff --git a/src/log4qt/log4qt/hierarchy.cpp b/src/log4qt/log4qt/hierarchy.cpp
new file mode 100644
index 0000000..283c7fd
--- /dev/null
+++ b/src/log4qt/log4qt/hierarchy.cpp
@@ -0,0 +1,212 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: hierarchy.cpp
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * changes: Sep 2008, Martin Heinrich:
+ * - Fixed problem in Qt 4.4 where QReadWriteLock is by default
+ * non-recursive.
+ *
+ *
+ * Copyright 2007 - 2008 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+
+#include "log4qt/hierarchy.h"
+
+#include
+#include "log4qt/logger.h"
+
+
+
+namespace Log4Qt
+{
+
+
+ /**************************************************************************
+ * Declarations
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * C helper functions
+ **************************************************************************/
+
+
+ LOG4QT_DECLARE_STATIC_LOGGER(static_logger, Log4Qt::LoggerRepository)
+
+
+
+ /**************************************************************************
+ * Class implementation: Hierarchy
+ **************************************************************************/
+
+
+ Hierarchy::Hierarchy() :
+#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0)
+ mObjectGuard(),
+#else
+ mObjectGuard(QReadWriteLock::Recursive),
+#endif
+ mLoggers(),
+ mThreshold(Level::NULL_INT),
+ mpRootLogger(logger(QString()))
+ {
+ // Store root logger to allow rootLogger() to be const
+ }
+
+
+ Hierarchy::~Hierarchy()
+ {
+ static_logger()->warn("Unexpected destruction of Hierarchy");
+
+ // QWriteLocker locker(&mObjectGuard);
+ //
+ // resetConfiguration();
+ // clear();
+ // delete mpRootLogger;
+ }
+
+
+ bool Hierarchy::exists(const QString &rName) const
+ {
+ QReadLocker locker(&mObjectGuard);
+
+ return mLoggers.contains(rName);
+ }
+
+
+ Logger *Hierarchy::logger(const QString &rName)
+ {
+ QWriteLocker locker(&mObjectGuard);
+
+ return createLogger(rName);
+ }
+
+
+ QList Hierarchy::loggers() const
+ {
+ QReadLocker locker(&mObjectGuard);
+
+ return mLoggers.values();
+ }
+
+
+ void Hierarchy::setThreshold(const QString &rThreshold)
+ {
+ setThreshold(Level::fromString(rThreshold));
+ }
+
+
+ void Hierarchy::resetConfiguration()
+ {
+ QWriteLocker locker(&mObjectGuard);
+
+ // Reset all loggers.
+ // Leave log, qt and root logger to the last to allow debugging of shutdown.
+
+ Logger *p_logging_logger = logger(QLatin1String("Log4Qt"));
+ Logger *p_qt_logger = logger(QLatin1String("Qt"));
+ Logger *p_root_logger = rootLogger();
+
+ Logger *p_logger;
+ Q_FOREACH(p_logger, mLoggers)
+ {
+ if ((p_logger == p_logging_logger) || (p_logger == p_qt_logger) || (p_logger == p_root_logger))
+ continue;
+ resetLogger(p_logger, Level::NULL_INT);
+ }
+ resetLogger(p_qt_logger, Level::NULL_INT);
+ resetLogger(p_logging_logger, Level::NULL_INT);
+ resetLogger(p_root_logger, Level::DEBUG_INT);
+ }
+
+
+ void Hierarchy::shutdown()
+ {
+ static_logger()->debug("Shutting down Hierarchy");
+ resetConfiguration();
+ }
+
+
+#ifndef QT_NO_DEBUG_STREAM
+ QDebug Hierarchy::debug(QDebug &rDebug) const
+ {
+ rDebug.nospace() << "Hierarchy("
+ << "loggers:" << loggers().count() << " "
+ << "threshold:" << threshold().toString() << " "
+ << "root-level:" << rootLogger()->level().toString() << " "
+ << "root-appenders:" << rootLogger()->appenders().count()
+ << ")";
+ return rDebug.space();
+ }
+#endif // QT_NO_DEBUG_STREAM
+
+
+ Logger *Hierarchy::createLogger(const QString &rName)
+ {
+ // Q_ASSERT_X(, "Hierarchy::createLogger", "Lock must be held by caller")
+
+ const QString name_separator = QLatin1String("::");
+
+ Logger *p_logger = mLoggers.value(rName, 0);
+ if (p_logger != 0)
+ return p_logger;
+
+ if (rName.isEmpty())
+ {
+ p_logger = new Logger(this, Level::DEBUG_INT, QLatin1String("root"), 0);
+ mLoggers.insert(QString(), p_logger);
+ return p_logger;
+ }
+ QString parent_name;
+ int index = rName.lastIndexOf(name_separator);
+ if (index >=0)
+ parent_name = rName.left(index);
+ p_logger = new Logger(this, Level::NULL_INT, rName, createLogger(parent_name));
+ mLoggers.insert(rName, p_logger);
+ return p_logger;
+ }
+
+
+ void Hierarchy::resetLogger(Logger *pLogger, Level level) const
+ {
+ // Q_ASSERT_X(, "Hierarchy::resetLogger", "Lock must be held by caller")
+
+ pLogger->removeAllAppenders();
+ pLogger->setAdditivity(true);
+ pLogger->setLevel(level);
+ }
+
+
+
+ /**************************************************************************
+ * Implementation: Operators, Helper
+ **************************************************************************/
+
+
+
+} // namespace Log4Qt
diff --git a/src/log4qt/log4qt/hierarchy.h b/src/log4qt/log4qt/hierarchy.h
new file mode 100644
index 0000000..089980c
--- /dev/null
+++ b/src/log4qt/log4qt/hierarchy.h
@@ -0,0 +1,142 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: hierarchy.h
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef LOG4QT_HIERARCHY_H
+#define LOG4QT_HIERARCHY_H
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+#include "log4qt/loggerrepository.h"
+#include "ukui-logmacros.h"
+
+#include
+#include
+
+
+/******************************************************************************
+ * Declarations
+ ******************************************************************************/
+
+namespace Log4Qt
+{
+
+ /*!
+ * \brief The class Hierarchy implements a logger repository.
+ *
+ * \note All the functions declared in this class are thread-safe.
+ */
+ class LIBUKUILOG4QT_EXPORT Hierarchy : public LoggerRepository
+ {
+ public:
+ Hierarchy();
+ // Hierarchy(const Hierarchy &rOther); // Use compiler default
+ virtual ~Hierarchy();
+ // Hierarchy &operator=(const Hierarchy &rOther); // Use compiler default
+
+ public:
+ virtual bool exists(const QString &rName) const;
+ virtual Logger *logger(const QString &rName);
+ virtual QList loggers() const;
+ // JAVA: virtual Logger *logger(const String &rName, LoggerFactory *pFactory);
+ virtual Logger *rootLogger() const;
+ virtual Level threshold() const;
+ virtual void setThreshold(Level level);
+ virtual void setThreshold(const QString &rThreshold);
+
+ // JAVA: void clear();
+ virtual bool isDisabled(Level level);
+ virtual void resetConfiguration();
+ virtual void shutdown();
+
+ // JAVA: virtual void addHierarchyEventListener(HierarchyEventListener *pEventListener);
+ // JAVA: virtual void emitNoAppenderWarning(Logger *plogger) const;
+ // JAVA: virtual void fireAddAppenderEvent(Logger *plogger, Appender *pAppender) const;
+
+ // JAVA: void addRenderer(const QString &rClass, ObjectRenderer *pObjectRenderer);
+ // JAVA: QHash getRendererMap() const;
+ // JAVA: setRenderer(const QString &rClass, ObjectRenderer *pObjectRenderer);
+
+ protected:
+#ifndef QT_NO_DEBUG_STREAM
+ /*!
+ * Writes all object member variables to the given debug stream \a rDebug and
+ * returns the stream.
+ *
+ *
+ * %Hierarchy(loggers:6 threshold:"ALL" root-level:"DEBUG" root-appenders:0)
+ *
+ * \sa QDebug, operator<<(QDebug debug, const LoggerRepository &rLoggerRepository)
+ */
+ virtual QDebug debug(QDebug &rdebug) const;
+#endif
+
+ private:
+ Logger *createLogger(const QString &rName);
+ void resetLogger(Logger *pLogger, Level level) const;
+
+ private:
+ mutable QReadWriteLock mObjectGuard;
+ QHash mLoggers;
+ volatile bool mHandleQtMessages;
+ Level mThreshold;
+ Logger *mpRootLogger;
+ };
+
+
+ /**************************************************************************
+ * Operators, Helper
+ **************************************************************************/
+
+
+ /**************************************************************************
+ * Inline
+ **************************************************************************/
+
+ inline Logger *Hierarchy::rootLogger() const
+ { // QReadLocker locker(&mObjectGuard); // Constant for object lifetime
+ return mpRootLogger; }
+
+ inline Level Hierarchy::threshold() const
+ { // QReadLocker locker(&mObjectGuard); // Level is threadsafe
+ return mThreshold; }
+
+ inline void Hierarchy::setThreshold(Level level)
+ { // QReadLocker locker(&mObjectGuard); // Level is threadsafe
+ mThreshold = level; }
+
+ inline bool Hierarchy::isDisabled(Level level)
+ { // QReadLocker locker(&mObjectGuard); // Level is threadsafe
+ return level < mThreshold; }
+
+
+} // namespace Log4Qt
+
+
+// Q_DECLARE_TYPEINFO(Log4Qt::Hierarchy, Q_COMPLEX_TYPE); // Use default
+
+
+#endif // LOG4QT_HIERARCHY_H
diff --git a/src/log4qt/log4qt/layout.cpp b/src/log4qt/log4qt/layout.cpp
new file mode 100644
index 0000000..160f80d
--- /dev/null
+++ b/src/log4qt/log4qt/layout.cpp
@@ -0,0 +1,91 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: layout.cpp
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+
+#include "log4qt/layout.h"
+
+#include
+#include "log4qt/loggingevent.h"
+#include "log4qt/logmanager.h"
+
+
+
+namespace Log4Qt
+{
+
+
+ /***************************************************************************
+ * Declarations
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * C helper functions
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * Class implementation: Layout
+ **************************************************************************/
+
+
+ QString Layout::contentType() const
+ {
+ return QString::fromLatin1("text/plain");
+ }
+
+
+ void Layout::activateOptions()
+ {
+ }
+
+
+ QString Layout::endOfLine()
+ {
+ // There seams to be no function in Qt for this
+
+#ifdef Q_OS_WIN32
+ return QLatin1String("\r\n");
+#endif // Q_OS_WIN32
+//#ifdef Q_OS_MAC
+// return QLatin1String("\r");
+//#endif // Q_OS_MAC
+ return QLatin1String("\n");
+ }
+
+
+ /**************************************************************************
+ * Implementation: Operators, Helper
+ **************************************************************************/
+
+
+} // namespace Log4Qt
diff --git a/src/log4qt/log4qt/layout.h b/src/log4qt/log4qt/layout.h
new file mode 100644
index 0000000..117cbef
--- /dev/null
+++ b/src/log4qt/log4qt/layout.h
@@ -0,0 +1,157 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: layout.h
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef LOG4QT_LAYOUT_H
+#define LOG4QT_LAYOUT_H
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+#include "log4qt/helpers/logobject.h"
+
+#include "log4qt/helpers/logobjectptr.h"
+#include "log4qt/log4qt.h"
+#include "ukui-logmacros.h"
+
+
+/******************************************************************************
+ * Declarations
+ ******************************************************************************/
+
+namespace Log4Qt
+{
+
+ class LoggingEvent;
+
+ /*!
+ * \brief The class Layout is the base class for all layouts.
+ *
+ * \note The ownership and lifetime of objects of this class are managed. See
+ * \ref Ownership "Object ownership" for more details.
+ */
+ class LIBUKUILOG4QT_EXPORT Layout : public LogObject
+ {
+ Q_OBJECT
+
+ /*!
+ * The property holds the content type of the layout.
+ *
+ * \sa contentType()
+ */
+ Q_PROPERTY(QString footercontentType READ contentType)
+ /*!
+ * The property holds the footer used by the layout.
+ *
+ * \sa footer(), setFooter()
+ */
+ Q_PROPERTY(QString footer READ footer WRITE setFooter)
+ /*!
+ * The property holds the header used by the layout.
+ *
+ * \sa header(), setHeader()
+ */
+ Q_PROPERTY(QString header READ header WRITE setHeader)
+
+ public:
+ Layout(QObject *pParent = 0);
+ virtual ~Layout();
+ private:
+ Layout(const Layout &rOther); // Not implemented
+ Layout &operator=(const Layout &rOther); // Not implemented
+
+ public:
+ virtual QString contentType() const;
+ QString footer() const;
+ QString header() const;
+ // JAVA: virtual bool ignoresThrowable() const;
+ QString name() const;
+ void setFooter(const QString &rFooter);
+ void setHeader(const QString &rHeader);
+ void setName(const QString &rName);
+ // JAVA: void setIgnoresThrowable(bool) const;
+
+ virtual void activateOptions();
+ virtual QString format(const LoggingEvent &rEvent) = 0;
+
+ /*!
+ * Returns the end of line seperator for the operating system.
+ *
+ * Windows: \\r\\n
+ * Mac: \\r
+ * UNIX: \\n
+ */
+ static QString endOfLine();
+
+ // Member variables
+ private:
+ QString mFooter;
+ QString mHeader;
+ };
+
+
+ /**************************************************************************
+ * Operators, Helper
+ **************************************************************************/
+
+
+ /**************************************************************************
+ * Inline
+ **************************************************************************/
+
+ inline Layout::Layout(QObject *pParent) :
+ LogObject(pParent)
+ {}
+
+ inline Layout::~Layout()
+ {}
+
+ inline QString Layout::footer() const
+ { return mFooter; }
+
+ inline QString Layout::header() const
+ { return mHeader; }
+
+ inline QString Layout::name() const
+ { return objectName(); }
+
+ inline void Layout::setFooter(const QString &rFooter)
+ { mFooter = rFooter; }
+
+ inline void Layout::setHeader(const QString &rHeader)
+ { mHeader = rHeader; }
+
+ inline void Layout::setName(const QString &rName)
+ { setObjectName(rName); }
+
+
+} // namespace Log4Qt
+
+
+// Q_DECLARE_TYPEINFO(Log4Qt::Layout, Q_COMPLEX_TYPE); // Use default
+Q_DECLARE_TYPEINFO(Log4Qt::LogObjectPtr, Q_MOVABLE_TYPE);
+
+
+#endif // LOG4QT_LAYOUT_H
diff --git a/src/log4qt/log4qt/level.cpp b/src/log4qt/log4qt/level.cpp
new file mode 100644
index 0000000..9188581
--- /dev/null
+++ b/src/log4qt/log4qt/level.cpp
@@ -0,0 +1,238 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: level.cpp
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+
+#include "log4qt/level.h"
+
+#include
+#include
+#include
+#include "log4qt/logger.h"
+
+
+namespace Log4Qt
+{
+
+
+ /**************************************************************************
+ * Declarations
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * C helper functions
+ **************************************************************************/
+
+
+ LOG4QT_DECLARE_STATIC_LOGGER(logger, Log4Qt::Level)
+
+
+
+ /**************************************************************************
+ * Class implementation: Level
+ **************************************************************************/
+
+
+ int Level::syslogEquivalent() const
+ {
+ // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe
+
+ switch (mValue)
+ {
+ case NULL_INT:
+ case ALL_INT:
+ case TRACE_INT:
+ case DEBUG_INT:
+ return 7;
+ case INFO_INT:
+ return 6;
+ case WARN_INT:
+ return 4;
+ case ERROR_INT:
+ return 3;
+ case FATAL_INT:
+ case OFF_INT:
+ return 0;
+ default:
+ Q_ASSERT_X(false, "Level::syslogEquivalent()", "Unknown level value");
+ return 7;
+ }
+ }
+
+
+ QString Level::toString() const
+ {
+ // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe
+
+ const char *p_context = "Level";
+
+ switch (mValue)
+ {
+ case NULL_INT:
+ return QCoreApplication::translate(p_context, "NULL");
+ case ALL_INT:
+ return QCoreApplication::translate(p_context, "ALL");
+ case TRACE_INT:
+ return QCoreApplication::translate(p_context, "TRACE");
+ case DEBUG_INT:
+ return QCoreApplication::translate(p_context, "DEBUG");
+ case INFO_INT:
+ return QCoreApplication::translate(p_context, "INFO");
+ case WARN_INT:
+ return QCoreApplication::translate(p_context, "WARN");
+ case ERROR_INT:
+ return QCoreApplication::translate(p_context, "ERROR");
+ case FATAL_INT:
+ return QCoreApplication::translate(p_context, "FATAL");
+ case OFF_INT:
+ return QCoreApplication::translate(p_context, "OFF");
+ default:
+ Q_ASSERT_X(false, "Level::toString()", "Unknown level value");
+ return QCoreApplication::translate(p_context, "NULL");
+ }
+ }
+
+
+ Level Level::fromString(const QString &rLevel, bool *pOk)
+ {
+ const char *p_context = "Level";
+ if (pOk)
+ *pOk = true;
+ #if 1
+ if (!rLevel.compare(QLatin1String("OFF"), Qt::CaseInsensitive) ||
+ !rLevel.compare(QCoreApplication::translate(p_context, "OFF"), Qt::CaseInsensitive))
+ return OFF_INT;
+ if (!rLevel.compare(QLatin1String("FATAL"), Qt::CaseInsensitive) ||
+ !rLevel.compare(QCoreApplication::translate(p_context, "FATAL"), Qt::CaseInsensitive))
+ return FATAL_INT;
+ if (!rLevel.compare(QLatin1String("ERROR"), Qt::CaseInsensitive) ||
+ !rLevel.compare(QCoreApplication::translate(p_context, "ERROR"), Qt::CaseInsensitive))
+ return ERROR_INT;
+ if (!rLevel.compare(QLatin1String("WARN"), Qt::CaseInsensitive) ||
+ !rLevel.compare(QCoreApplication::translate(p_context, "WARN"), Qt::CaseInsensitive))
+ return WARN_INT;
+ if (!rLevel.compare(QLatin1String("INFO"), Qt::CaseInsensitive) ||
+ !rLevel.compare(QCoreApplication::translate(p_context, "INFO"), Qt::CaseInsensitive))
+ return INFO_INT;
+ if (!rLevel.compare(QLatin1String("DEBUG"), Qt::CaseInsensitive) ||
+ !rLevel.compare(QCoreApplication::translate(p_context, "DEBUG"), Qt::CaseInsensitive))
+ return DEBUG_INT;
+ if (!rLevel.compare(QLatin1String("TRACE"), Qt::CaseInsensitive) ||
+ !rLevel.compare(QCoreApplication::translate(p_context, "TRACE"), Qt::CaseInsensitive))
+ return TRACE_INT;
+ if (!rLevel.compare(QLatin1String("ALL"), Qt::CaseInsensitive) ||
+ !rLevel.compare(QCoreApplication::translate(p_context, "ALL"), Qt::CaseInsensitive))
+ return ALL_INT;
+ if (!rLevel.compare(QLatin1String("NULL"), Qt::CaseInsensitive) ||
+ !rLevel.compare(QCoreApplication::translate(p_context, "NULL"), Qt::CaseInsensitive))
+ return NULL_INT;
+
+ logger()->warn("Use of invalid level string '%1'. Using 'Level::OFF_INT' instead.", rLevel);
+ if (pOk)
+ *pOk = false;
+ return OFF_INT;
+ #else
+ if (rLevel == QLatin1String("OFF") ||
+ rLevel == QCoreApplication::translate(p_context, "OFF"))
+ return OFF_INT;
+ if (rLevel == QLatin1String("FATAL") ||
+ rLevel == QCoreApplication::translate(p_context, "FATAL"))
+ return FATAL_INT;
+ if (rLevel == QLatin1String("ERROR") ||
+ rLevel == QCoreApplication::translate(p_context, "ERROR"))
+ return ERROR_INT;
+ if (rLevel == QLatin1String("WARN") ||
+ rLevel == QCoreApplication::translate(p_context, "WARN"))
+ return WARN_INT;
+ if (rLevel == QLatin1String("INFO") ||
+ rLevel == QCoreApplication::translate(p_context, "INFO"))
+ return INFO_INT;
+ if (rLevel == QLatin1String("DEBUG") ||
+ rLevel == QCoreApplication::translate(p_context, "DEBUG"))
+ return DEBUG_INT;
+ if (rLevel == QLatin1String("TRACE") ||
+ rLevel == QCoreApplication::translate(p_context, "TRACE"))
+ return TRACE_INT;
+ if (rLevel == QLatin1String("ALL") ||
+ rLevel == QCoreApplication::translate(p_context, "ALL"))
+ return ALL_INT;
+ if (rLevel == QLatin1String("NULL") ||
+ rLevel == QCoreApplication::translate(p_context, "NULL"))
+ return NULL_INT;
+
+ logger()->warn("Use of invalid level string '%1'. Using 'Level::NULL_INT' instead.", rLevel);
+ if (pOk)
+ *pOk = false;
+ return NULL_INT;
+ #endif
+ }
+
+
+
+ /**************************************************************************
+ * Implementation: Operators, Helper
+ **************************************************************************/
+
+
+#ifndef QT_NO_DATASTREAM
+ QDataStream &operator<<(QDataStream &rStream,
+ const Level &rLevel)
+ {
+ quint8 l = rLevel.mValue;
+ rStream << l;
+ return rStream;
+ }
+
+
+ QDataStream &operator>>(QDataStream &rStream,
+ Level &rLevel)
+ {
+ quint8 l;
+ rStream >> l;
+ rLevel.mValue = (Level::Value)l;
+ return rStream;
+ }
+#endif // QT_NO_DATASTREAM
+
+
+#ifndef QT_NO_DEBUG_STREAM
+ QDebug operator<<(QDebug debug,
+ const Level &rLevel)
+ {
+ debug.nospace() << "Level("
+ << rLevel.toString()
+ << ")";
+ return debug.space();
+ }
+#endif // QT_NO_DEBUG_STREAM
+
+
+} // namespace Log4Qt
diff --git a/src/log4qt/log4qt/level.h b/src/log4qt/log4qt/level.h
new file mode 100644
index 0000000..6fd26f1
--- /dev/null
+++ b/src/log4qt/log4qt/level.h
@@ -0,0 +1,194 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: level.h
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef LOG4QT_LEVEL_H
+#define LOG4QT_LEVEL_H
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+#include
+#include
+#include "log4qt/log4qt.h"
+#include "ukui-logmacros.h"
+
+
+/******************************************************************************
+ * Declarations
+ ******************************************************************************/
+
+namespace Log4Qt
+{
+
+ /*!
+ * \brief The class Level defines the level of a logging event.
+ *
+ * \note All the functions declared in this class are thread-safe.
+ */
+ class LIBUKUILOG4QT_EXPORT Level
+ {
+ public:
+ // Comparisson operators rely on the order:
+ // NULL_INT < ALL_INT < TRACE_INT < ...
+ // Serialisation uses unsigned 8 bit int
+
+ /*!
+ * The enumeration Value contains all possible Level values.
+ */
+ enum Value
+ {
+ /*! NULL_INT is used for no level has been specified */
+ NULL_INT = 0,
+ ALL_INT = 32,
+ TRACE_INT = 64,
+ DEBUG_INT = 96,
+ INFO_INT = 128,
+ WARN_INT = 150,
+ ERROR_INT = 182,
+ FATAL_INT = 214,
+ OFF_INT = 255
+ };
+
+ public:
+ Level(Value value = NULL_INT);
+ // Level(const Level &rOther); // Use compiler default
+ // virtual ~Level(); // Use compiler default
+ // Level &operator=(const Level &rOther); // Use compiler default
+
+ int syslogEquivalent() const;
+ int toInt() const;
+
+ bool operator==(const Level &rOther) const;
+ bool operator!=(const Level &rOther) const;
+ bool operator<(const Level &rOther) const;
+ bool operator<=(const Level &rOther) const;
+ bool operator>(const Level &rOther) const;
+ bool operator>=(const Level &rOther) const;
+ QString toString() const;
+
+ static Level fromString(const QString &rName, bool *pOk = 0);
+
+ private:
+ // QMutex mObjectGuard;
+ volatile Value mValue;
+
+#ifndef QT_NO_DATASTREAM
+ // Needs to be friend to stream objects
+ friend QDataStream &operator<<(QDataStream &rStream,
+ const Level &rLevel);
+ friend QDataStream &operator>>(QDataStream &rStream,
+ Level &rLevel);
+#endif // QT_NO_DATASTREAM
+ };
+
+
+ /**************************************************************************
+ * Operators, Helper
+ **************************************************************************/
+
+#ifndef QT_NO_DATASTREAM
+ /*!
+ * \relates Level
+ *
+ * Writes the given error \a rLevel to the given stream \a rStream,
+ * and returns a reference to the stream.
+ */
+ QDataStream &operator<<(QDataStream &rStream,
+ const Level &rLevel);
+
+ /*!
+ * \relates Level
+ *
+ * Reads an error from the given stream \a rStream into the given
+ * error \a rLevel, and returns a reference to the stream.
+ */
+ QDataStream &operator>>(QDataStream &rStream,
+ Level &rLevel);
+#endif // QT_NO_DATASTREAM
+
+#ifndef QT_NO_DEBUG_STREAM
+ /*!
+ * \relates Level
+ *
+ * Writes all object member variables to the given debug stream \a rDebug
+ * and returns the stream.
+ *
+ *
+ * %Level("ERROR")
+ *
+ * \sa QDebug
+ */
+ QDebug operator<<(QDebug debug,
+ const Level &rLevel);
+#endif // QT_NO_DEBUG_STREAM
+
+
+ /**************************************************************************
+ * Inline
+ **************************************************************************/
+
+
+ inline Level::Level(Value value) :
+ mValue(value)
+ {}
+
+ inline int Level::toInt() const
+ { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe
+ return mValue; }
+
+ inline bool Level::operator==(const Level &rOther) const
+ { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe
+ return mValue == rOther.mValue; }
+
+ inline bool Level::operator!=(const Level &rOther) const
+ { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe
+ return mValue != rOther.mValue; }
+
+ inline bool Level::operator<(const Level &rOther) const
+ { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe
+ return mValue < rOther.mValue; }
+
+ inline bool Level::operator<=(const Level &rOther) const
+ { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe
+ return mValue <= rOther.mValue; }
+
+ inline bool Level::operator>(const Level &rOther) const
+ { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe
+ return mValue > rOther.mValue; }
+
+ inline bool Level::operator>=(const Level &rOther) const
+ { // QMutexLocker locker(&mObjectGuard); // Read/Write of int is safe
+ return mValue >= rOther.mValue; }
+
+
+} // namespace Log4Qt
+
+
+Q_DECLARE_METATYPE(Log4Qt::Level)
+Q_DECLARE_TYPEINFO(Log4Qt::Level, Q_MOVABLE_TYPE);
+
+
+#endif // LOG4QT_LEVEL_H
diff --git a/src/log4qt/log4qt/log4qt.cpp b/src/log4qt/log4qt/log4qt.cpp
new file mode 100644
index 0000000..9378f46
--- /dev/null
+++ b/src/log4qt/log4qt/log4qt.cpp
@@ -0,0 +1,58 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: logging.cpp
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * Copyright 2007 Martin Heinrich
+ *
+ * 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.
+ *
+ *****************************************************************************/
+
+
+
+/******************************************************************************
+ *Dependencies
+ ******************************************************************************/
+
+
+#include "log4qt/log4qt.h"
+
+
+
+namespace Log4Qt
+{
+
+
+ /**************************************************************************
+ * Declarations
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * C helper functions
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ *Implementation: Operators, Helper
+ **************************************************************************/
+
+
+
+} // namespace Log4Qt
diff --git a/src/log4qt/log4qt/log4qt.h b/src/log4qt/log4qt/log4qt.h
new file mode 100644
index 0000000..641f196
--- /dev/null
+++ b/src/log4qt/log4qt/log4qt.h
@@ -0,0 +1,616 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: logging.h
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * changes: Sep 2008, Martin Heinrich:
+ * - Added a compile time version check for the Qt version
+ * Jan 2009, Martin Heinrich:
+ * - Updated documentation and version information for version 0.2
+ * Feb 2009, Martin Heinrich:
+ * - Updated version information for version 0.3
+ *
+ *
+ * Copyright 2007 - 2009 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef LOG4QT_H
+#define LOG4QT_H
+
+
+/*!
+ * \mainpage
+ *
+ * %Log4Qt is a C++ port of the Apache Software Foundation Log4j package
+ * using the Trolltech Qt Framework.
+ *
+ * The documentation describes classes and methods that have been added or
+ * changed compared to Log4j.
+ *
+ * The following sections are describing the implementation in more detail:
+ * - \ref Changes "Differences to Log4j"
+ * - \ref Ownership "Object ownership"
+ * - \ref LogLog "Logging within the package"
+ * - \ref Init "Initialization procedure"
+ * - \ref Env "Environment Variables"
+ * - \ref Undocumented "Undocumented functions"
+ * - \ref Assumptions "Assumptions"
+ *
+ * \author Martin Heinrich
+ * \version 0.3 (January 2009)
+ *
+ */
+
+/*!
+ * \page Changes Differences to Log4j
+ *
+ * The following fundamental differences exist between %Log4Qt and Log4j:
+ *
+ * - As a JAVA package Log4j does not have to manage object ownership and
+ * lifetime in the same way then it is required in C++. For details on
+ * how object ownership is handled see \ref Ownership "Object ownership".
+ * - The package uses itself for its internal logging similar to Log4j 1.3.
+ * For details see \ref LogLog "Logging within the package".
+ * - The configuration using system properties was replaced with a combination
+ * of environment variables and application settings. For details see
+ * \ref Env "Environment Variables".
+ * - Custom levels are not supported.
+ * - Multiple Logger Repositories are not supported
+ *
+ * The following classes have been changed:
+ *
+ * - \ref Log4Qt::AppenderSkeleton "AppenderSkeleton"
+ * - The procedure of checking, if logging is possible, originally used by
+ * \ref Log4Qt::WriterAppender "WriterAppender" was generalised and is used
+ * in \ref Log4Qt::AppenderSkeleton "AppenderSkeleton" and derived classes
+ * (\ref Log4Qt::AppenderSkeleton::checkEntryConditions() "checkEntryConditions()").
+ * - The \ref Log4Qt::AppenderSkeleton::doAppend() "doAppend()" member function will
+ * check the entry conditions by calling the sub-class specific
+ * \ref Log4Qt::AppenderSkeleton::checkEntryConditions() "checkEntryConditions()".
+ * If successful the sub-class specific
+ * \ref Log4Qt::AppenderSkeleton::append() "append()" function is called.
+ *
+ * - Configurator
+ * - Configure functions return a boolean indicating, if the configuration
+ * was successful.
+ * - Configure errors are accessible over
+ * \ref Log4Qt::ConfiguratorHelper::configureError()
+ * "ConfiguratorHelper::configureError()".
+ * - Watching for configuration file changes is a function performed
+ * centrally by the \ref Log4Qt::ConfiguratorHelper "ConfiguratorHelper".
+ * The class provides signals to notify on configuration change and errors.
+ * - The class \ref Log4Qt::PropertyConfigurator "PropertyConfigurator" was
+ * extended to be able to read configuration data from a QSettings object.
+ *
+ * - \ref Log4Qt::Level "Level"
+ * - A new value \ref Log4Qt::Level::NULL_INT "Level::NULL_INT" was
+ * introduced to indicate there is no level set.
+ *
+ * - \ref Log4Qt::Logger "Logger"
+ * - The method \ref Log4Qt::Logger::isEnabledFor() "isEnabledFor()"
+ * does also take the repository threshold into account.
+ * - Several overloaded convenience member function are available to log
+ * messages with arguments of different types.
+ * - Two macros, \ref Log4Qt::LOG4QT_DECLARE_STATIC_LOGGER "LOG4QT_DECLARE_STATIC_LOGGER"
+ * and \ref Log4Qt::LOG4QT_DECLARE_QCLASS_LOGGER "LOG4QT_DECLARE_QCLASS_LOGGER",
+ * allows retrieving and caching of a pointer to a logger object.
+ *
+ * - \ref Log4Qt::LogManager "LogManager"
+ * - A QtMessage handler can be installed via
+ * \ref Log4Qt::LogManager::setHandleQtMessages() "setHandleQtMessages()",
+ * to redirect all messages created by calls to qDebug(), qWarning(),
+ * qCritical() and qFatal() to a logger. The logger is named Qt and can be
+ * accessed using \ref Log4Qt::LogManager::qtLogger() "qtLogger()".
+ * - The initialisation procedure is available over a public method
+ * (\ref Log4Qt::LogManager::startup() "startup()").
+ * - The LogManager provides access to the logger used internally by the
+ * package (\ref Log4Qt::LogManager::logLogger() "logLogger()") and to
+ * its default initialisation procedure
+ * (\ref Log4Qt::LogManager::configureLogLogger() "configureLogLogger()").
+ *
+ * - \ref Log4Qt::WriterAppender "WriterAppender"
+ * - The class will call \ref Log4Qt::WriterAppender::handleIoErrors()
+ * "handleIoErrors()" after all I/O operations. Sub-classes should
+ * re-implement the function to handle errors.
+ *
+ * The following classes have been added:
+ *
+ * - An additional appender class, \ref Log4Qt::DebugAppender "DebugAppender",
+ * was added. The class appends logging events to the platform specific debug
+ * output.
+ * - Various helper class have been introduced:
+ * - \ref Log4Qt::ClassLogger "ClassLogger": The class ClassLogger provides
+ * logging for a QObject derived class.
+ * - \ref Log4Qt::ConfiguratorHelper "ConfiguratorHelper": The class
+ * ConfiguratorHelper provides a configuration file watch and last error
+ * for configurator classes.
+ * - \ref Log4Qt::DateTime "DateTime": The class DateTime provides extended
+ * functionality for QDateTime.
+ * - \ref Log4Qt::LogError "LogError": The class LogError represents an error.
+ * - \ref Log4Qt::Factory "Factory": The class Factory provides factories
+ * for Appender, Filter and Layout objects.
+ * - \ref Log4Qt::InitialisationHelper "InitialisationHelper": The class
+ * InitialisationHelper performs static initialisation tasks.
+ * - \ref Log4Qt::LogObject "LogObject": The class LogObject is the common
+ * base class for many classes in the package.
+ * - \ref Log4Qt::LogObjectPtr "LogObjectPtr": The class LogObjectPtr
+ * implements automatic reference counting for LogObject objects.
+ * - \ref Log4Qt::PatternFormatter "PatternFormatter": The class
+ * PatternFormatter formats a logging event based on a pattern string.
+ * - \ref Log4Qt::Properties "Properties": The class Properties implements a
+ * JAVA property hash.
+ */
+
+/*!
+ * \page Ownership Object ownership
+ *
+ * In difference to the JAVA Log4j package %Log4Qt must manage ownership and
+ * lifetime of the objects used. This is non trivial as objects are created
+ * and used in different ways.
+ *
+ * In general an object can be created explicitly for example an application
+ * may create Loggers, Appenders and Layouts during creation of a QApplication
+ * object. But they can also be automatically created by the package on
+ * startup using a \ref Log4Qt::PropertyConfigurator "PropertyConfigurator"
+ * configuration file. Objects may also be created the one way and then used
+ * the other. Object may be used by multiple other objects. A Layout for example
+ * may be used by multiple Appenders. Objects are also created from multiple
+ * threads. The creation may happen during static initialisation and the
+ * deletion during static de-initialization.
+ *
+ * The parent child model used by QObject cannot be used to handle this. It
+ * cannot automatically delete an object that is used by multiple others as
+ * for example an Appender used by multiple Loggers. In addition to this
+ * QObjects and their children must reside in the same thread. This would
+ * either mean to impose restriction on how objects can be created or to move
+ * objects to a specific thread.
+ *
+ * To allow an automatic deletion of not required objects the package
+ * implements reference counting for Appenders, Layouts and Filters. The
+ * reference counting is implemented in \ref Log4Qt::LogObject "LogObject",
+ * which is used as a common base class. The reference count can be explicitly
+ * changed using the methods \ref Log4Qt::LogObject::retain() "retain()" and
+ * \ref Log4Qt::LogObject::release() "release()". Alternatively an auto pointer
+ * is available \ref Log4Qt::LogObjectPtr "LogObjectPtr", which is used
+ * throughout the package.
+ *
+ * The reference counting mechanism will test, if an object has a QObject
+ * parent object set. If a parent is set, the object will not be deleted, if
+ * the reference count reaches 0. This allows to mix the reference counted
+ * paradigm with the QObject parent child one.
+ *
+ * The following example configures a logger and uses reference counting to
+ * manage the ownership of objects.
+ *
+ * \code
+ * // Create layout
+ * TTCCLayout *p_layout = new TTCCLayout();
+ *
+ * // Create appender
+ * ConsoleAppender *p_appender = new ConsoleAppender(p_layout, ConsoleAppender::STDOUT_TARGET);
+ * p_appender->activateOptions();
+ *
+ * // Get logger
+ * Logger *p_logger = Logger::logger("MyClass");
+ * p_logger->addAppender(p_appender);
+ *
+ * // ...
+ *
+ * // Remove appender from Logger
+ * p_logger->removeAllAppenders(); // p_appender and p_layout are deleted here
+ * \endcode
+ *
+ * The following example configures a logger and uses QObject ownership of
+ * objects.
+ *
+ * \code
+ * QObject *p_parent = new MyObject;
+ *
+ * // Create objects
+ * ConsoleAppender *p_appender = new ConsoleAppender(p_parent);
+ * TTCCLayout *p_layout = new TTCCLayout(p_appender);
+ *
+ * // Configure appender
+ * p_appender->setTarget(ConsoleAppender::STDOUT_TARGET);
+ * p_appender->setLayout(p_layout);
+ * p_appender->activateOptions();
+ *
+ * // Get logger
+ * Logger *p_logger = Logger::logger("MyClass");
+ * p_logger->addAppender(p_appender);
+ *
+ * // ...
+ *
+ * // Remove appender from Logger
+ * p_logger->removeAllAppenders();
+ *
+ * delete p_parent; // p_appender and p_layout are deleted here
+ * \endcode
+ *
+ * The following example shows how to use objects created on the stack.
+ *
+ * \code
+ * {
+ * // Create layout
+ * TTCCLayout layout;
+ * layout.retain();
+ *
+ * // Create appender
+ * ConsoleAppender appender(&layout, ConsoleAppender::STDOUT_TARGET);
+ * appender.retain();
+ * appender.activateOptions();
+ *
+ * // Get logger
+ * Logger *p_logger = Logger::logger("MyClass");
+ * p_logger->addAppender(&appender);
+ *
+ * // ...
+ *
+ * // Remove appender from Logger
+ * p_logger->removeAllAppenders(); // Without retain() program crashes here
+ *
+ * } // p_appender and p_layout are deleted here
+ * \endcode
+ */
+
+/*!
+ * \page LogLog Logging within the package
+ *
+ * The package uses itself for logging similar to Log4j 1.3. This brings much
+ * more flexibility over logging to stdout, stderr like in Log4j 1.2 using
+ * logLog. It also enables the program to capture and handle errors raised by
+ * the package.
+ *
+ * Using this approach introduces the issue of recursion. The following example
+ * explains a situation where this happens. Let's say all logger are configured
+ * to be additive and only the root logger has an appender set. The appender
+ * is a \ref Log4Qt::FileAppender "FileAppender". During the logging of an
+ * event an I/O error occurs. The \ref Log4Qt::FileAppender "FileAppender" logs
+ * an event by itself using the logger %Log4Qt::FileAppender. The event is
+ * passed to the root logger, which calls then the \ref Log4Qt::FileAppender
+ * "FileAppender". This causes another I/O error, which is logged by
+ * the \ref Log4Qt::FileAppender "FileAppender".
+ *
+ * To avoid an endless loop the appender will drop the event on a recursive
+ * invocation. This check is done by \ref Log4Qt::AppenderSkeleton
+ * "AppenderSkeleton" in \ref Log4Qt::AppenderSkeleton::doAppend()
+ * "doAppend()".
+ *
+ * The problem only occurs, if a logger, appender, layout or filter log an
+ * event while an event is appended. Neither the logger class nor any of the
+ * layout or filter classes log events during appending of an event. Most of
+ * the appender classes may log errors during appending. Only the
+ * \ref Log4Qt::ListAppender "ListAppender" and
+ * \ref Log4Qt::ListAppender "ConsoleAppender" are not logging events.
+ *
+ * The default configuration uses two \ref Log4Qt::ListAppender
+ * "ConsoleAppender", one for stderr and one for stdout. No event will be
+ * dropped, because no recursive invocations can occur.
+ */
+
+/*!
+ * \page Init Initialization procedure
+ *
+ * The package is initialised in two stages. The first stage takes place during
+ * static initialization. The second stage takes place when the
+ * \ref Log4Qt::LogManager "LogManager" singleton is created.
+ *
+ * During static initialisation the \ref Log4Qt::InitialisationHelper
+ * "InitialisationHelper" singleton is created . On construction it captures
+ * the program startup time, reads the required values from the system
+ * environment and registers the package types with the Qt type system.
+ *
+ * The \ref Log4Qt::LogManager "LogManager" singleton is created on first use.
+ * The creation is usually triggered by the request for a \ref Log4Qt::Logger
+ * "Logger" object. The call to \ref Log4Qt::Logger::logger()
+ * "Logger::logger()" is passed through to \ref Log4Qt::LogManager::logger()
+ * "LogManager::logger()". On creation the \ref Log4Qt::LogManager "LogManager"
+ * creates a \ref Log4Qt::Hierarchy "Hierarchy" object as logger repository.
+ *
+ * After the singleton is created the logging of the package is configured to
+ * its default by a call to \ref Log4Qt::LogManager::configureLogLogger()
+ * "LogManager::configureLogLogger()". The logger
+ * \ref Log4Qt::LogManager::logLogger() "logLogger()" is configured to be not
+ * additive. Messages with the level \ref Log4Qt::Level::ERROR_INT
+ * "Level::ERROR_INT" and \ref Log4Qt::Level::FATAL_INT "Level::FATAL_INT" are
+ * written to \c stderr using a ConsoleAppender. The remaining messages are
+ * written to \c stdout using a second ConsoleAppender. The level is read from
+ * the system environment or application settings using
+ * \ref Log4Qt::InitialisationHelper::setting()
+ * "InitialisationHelper::setting()" with the key \c Debug. If a level value
+ * is found, but it is not a valid Level string,
+ * \ref Log4Qt::Level::DEBUG_INT "Level::DEBUG_INT" is used. If no level string
+ * is found \ref Log4Qt::Level::ERROR_INT "Level::ERROR_INT" is used.
+ *
+ * Once the logging is configured the package is initialised by a call to
+ * \ref Log4Qt::LogManager::startup() "LogManager::startup()". The function
+ * will test for the setting \c DefaultInitOverride in the system environment
+ * and application settings using \ref Log4Qt::InitialisationHelper::setting()
+ * "InitialisationHelper::setting()". If the value is present and set to
+ * anything else then \c false, the initialisation is aborted.
+ * The system environment and application settings are tested for the setting
+ * \c Configuration. If it is found and it is a valid path to a file, the
+ * package is configured with the file using
+ * \ref Log4Qt::PropertyConfigurator::doConfigure(const QString &, LoggerRepository *)
+ * "PropertyConfigurator::doConfigure()". If the setting \c Configuration is
+ * not available and a QCoreApplication object is present, the application
+ * settings are tested for a group \c Log4Qt/Properties. If the group exists,
+ * the package is configured with the setting using the
+ * \ref Log4Qt::PropertyConfigurator::doConfigure(const QSettings &r, LoggerRepository *)
+ * "PropertyConfiguratordoConfigure()". If neither a configuration file nor
+ * configuration settings could be found, the current working directory is
+ * searched for the file \c "log4qt.properties". If it is found, the package
+ * is configured with the file using
+ * \ref Log4Qt::PropertyConfigurator::doConfigure(const QString &, LoggerRepository *)
+ * "PropertyConfigurator::doConfigure()".
+ *
+ * The following example shows how to use application settings to initialise the
+ * package.
+ *
+ * \code
+ * # file: myapplication.h
+ *
+ * #include qapplication.h
+ *
+ * class MyApplication : public QApplication
+ * {
+ * Q_OBJECT
+ *
+ * public:
+ * MyApplication();
+ * ~MyApplication();
+ * void setupLog4Qt();
+ * }
+ * \endcode
+ * \code
+ * # file: myapplication.cpp
+ *
+ * #include myapplication.h
+ *
+ * MyApplication::MyApplication(
+ * {
+ * // Set Application data to allow Log4Qt initialisation to read the
+ * // correct values
+ * setApplicationName("MyApplication");
+ * setOrganisationName("MyOrganisation");
+ * setOrganizationDomain("www.myorganisation.com");
+ *
+ * // Log first message, which initialises Log4Qt
+ * Log4Qt::Logger::logger("MyApplication")->info("Hello World");
+ * }
+ *
+ * MyApplication::~MyApplication()
+ * {
+ * }
+ *
+ * void MyApplication::setupLog4Qt()
+ * {
+ * QSettings s;
+ *
+ * // Set logging level for Log4Qt to TRACE
+ * s.beginGroup("Log4Qt");
+ * s.setValue("Debug", "TRACE");
+ *
+ * // Configure logging to log to the file C:/myapp.log using the level TRACE
+ * s.beginGroup("Properties");
+ * s.setValue("log4j.appender.A1", "org.apache.log4j.FileAppender");
+ * s.setValue("log4j.appender.A1.file", "C:/myapp.log");
+ * s.setValue("log4j.appender.A1.layout", "org.apache.log4j.TTCCLayout");
+ * s.setValue("log4j.appender.A1.layout.DateFormat", "ISO8601");
+ * s.setValue("log4j.rootLogger", "TRACE, A1");
+ *
+ * // Settings will become active on next application startup
+ * }
+ * \endcode
+ */
+
+/*!
+ * \page Env Environment Variables
+ *
+ * The package uses environment variables to control the initialization
+ * procedure. The environment variables replace the system property entries
+ * used by Log4j.
+ *
+ * For compability reasons the Log4j entry is recognised. Alternatively a
+ * environment variable style Log4Qt form can be used. The following entries
+ * are used:
+ *
+ * - LOG4QT_DEBUG
+ * The variable controls the \ref Log4Qt::Level "Level" value for the
+ * logger \ref Log4Qt::LogManager::logLogger() "LogManager::logLogger()".
+ * If the value is a valid \ref Log4Qt::Level "Level" string, the level for
+ * the is set to the level. If the value is not a valid
+ * \ref Log4Qt::Level "Level" string, \ref Log4Qt::Level::DEBUG_INT
+ * "DEBUG_INT" is used. Otherwise \ref Log4Qt::Level::ERROR_INT "ERROR_INT"
+ * is used.
+ * - \ref Log4Qt::LogManager::configureLogLogger()
+ * "LogManager::configureLogLogger()"
+ *
+ * - LOG4QT_DEFAULTINITOVERRIDE
+ * The variable controls the \ref Init "initialization procedure" performed
+ * by the \ref Log4Qt::LogManager "LogManager" on startup. If it is set to
+ * any other value then \c false the \ref Init "initialization procedure"
+ * is skipped.
+ * - \ref Log4Qt::LogManager::startup() "LogManager::startup()"
+ *
+ * - LOG4QT_CONFIGURATION
+ * The variable specifies the configuration file used for initialising the
+ * package.
+ * - \ref Log4Qt::LogManager::startup() "LogManager::startup()"
+ *
+ * - LOG4QT_CONFIGURATORCLASS
+ * The variable specifies the configurator class used for initialising the
+ * package.
+ *
+ * Environment variables are read during static initialisation on creation of
+ * the \ref Log4Qt::InitialisationHelper "InitialisationHelper". They can be
+ * accessed by calling \ref Log4Qt::InitialisationHelper::environmentSettings()
+ * "InitialisationHelper::environmentSettings()".
+ *
+ * All settings can also be made in the application settings under the group
+ * \c %Log4Qt. For example the environment variable \c LOG4QT_DEBUG is
+ * equivalent to the setting \c Log4Qt/Debug. If an environment variable is
+ * set it takes precedence over the application setting. Settings are only
+ * used, if an QApplication object is available, when the
+ * \ref Log4Qt::LogManager "LogManager" is
+ * initialised (see \ref Log4Qt::InitialisationHelper::setting()
+ * "InitialisationHelper::setting()" for details).
+ */
+
+/*!
+ * \page Undocumented Undocumented functions
+ *
+ * In general it was tried to avoid the usage of undocumented features of Qt.
+ * Nice to have features like for example Q_DECLARE_PRIVATE are not used. Only
+ * features that would have been resulted in re-coding the same functionality
+ * are used.
+ *
+ * - QT_WA: The macro is used to call Windows A/W functions
+ * - \ref Log4Qt::DebugAppender "DebugAppender"
+ * - QBasicAtomicPointer: The class is used instead of QAtomicPointer, because
+ * it allows the initialisation as plain old data type.
+ * - \ref Log4Qt::LOG4QT_GLOBAL_STATIC "LOG4QT_GLOBAL_STATIC"
+ * - \ref Log4Qt::LOG4QT_IMPLEMENT_INSTANCE "LOG4QT_IMPLEMENT_INSTANCE"
+ * - \ref Log4Qt::LOG4QT_DECLARE_STATIC_LOGGER "LOG4QT_DECLARE_STATIC_LOGGER"
+ * - Q_BASIC_ATOMIC_INITIALIZER: The macro is used to initialise QAtomicPointer
+ * objects as plain old data type.
+ * - \ref Log4Qt::LOG4QT_GLOBAL_STATIC "LOG4QT_GLOBAL_STATIC"
+ * - \ref Log4Qt::LOG4QT_IMPLEMENT_INSTANCE "LOG4QT_IMPLEMENT_INSTANCE"
+ * - \ref Log4Qt::LOG4QT_DECLARE_STATIC_LOGGER "LOG4QT_DECLARE_STATIC_LOGGER"
+ */
+
+/*!
+ * \page Assumptions Assumptions
+ *
+ * The following assumptions are used throughout the package:
+ *
+ * - Reading / writing of bool or int is thread-safe, if declared volatile
+ * - \ref Log4Qt::ListAppender "ListAppender"
+ * - \ref Log4Qt::AppenderSkeleton "AppenderSkeleton"
+ * - \ref Log4Qt::ConsoleAppender "ConsoleAppender"
+ * - \ref Log4Qt::FileAppender "FileAppender"
+ * - \ref Log4Qt::Hierarchy "Hierarchy"
+ * - \ref Log4Qt::Level "Level"
+ * - \ref Log4Qt::Logger "Logger"
+ * - \ref Log4Qt::WriterAppender "WriterAppender"
+ * - \ref Log4Qt::Layout::format() "Layout::format()" is implemented reentrant
+ * in all sub-classes.
+ * - \ref Log4Qt::AppenderSkeleton "AppenderSkeleton"
+ * - Being able to use singleton objects during static de-initialization without
+ * order issues is more valuable then their destruction.
+ * - \ref Log4Qt::LogManager "LogManager"
+ * - \ref Log4Qt::LOG4QT_GLOBAL_STATIC "LOG4QT_GLOBAL_STATIC"
+ * - \ref Log4Qt::LOG4QT_IMPLEMENT_INSTANCE "LOG4QT_IMPLEMENT_INSTANCE"
+ */
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+#include
+
+#include "ukui-logmacros.h"
+
+#if QT_VERSION < QT_VERSION_CHECK(4, 3, 0)
+# error "Log4Qt requires Qt version 4.3.0 or higher"
+#endif
+
+
+/******************************************************************************
+ * Declarations
+ ******************************************************************************/
+
+/*!
+ * \brief The namespace %Log4Qt encloses all parts of the package.
+ */
+namespace Log4Qt
+{
+ /*!
+ * This macro expands a numeric value of the form 0xMMmmPP (MM = major,
+ * mm = minor, PP = patch) that specifies Log4Qt's version number.
+ * This is the version against which the application is compiled.
+ *
+ * \sa \ref Log4Qt::LOG4QT_VERSION_STR "LOG4QT_VERSION_STR",
+ * \ref Log4Qt::LogManager::version() "LogManager::version()"
+ */
+ #define LOG4QT_VERSION 0x000200
+
+ /*!
+ * The macro expands to a string that specifies the Log4Qt's version
+ * number. This is the version against which the application is compiled.
+ *
+ * \sa \ref Log4Qt::LOG4QT_VERSION "LOG4QT_VERSION",
+ * \ref Log4Qt::LogManager::version() "LogManager::version()"
+ */
+ #define LOG4QT_VERSION_STR "0.3.0"
+
+ enum ErrorCode
+ {
+ OK = 0,
+ // AppenderSkeleton, FileAppender, WriterAppender
+ APPENDER_ACTIVATE_MISSING_LAYOUT_ERROR,
+ APPENDER_ACTIVATE_MISSING_WRITER_ERROR,
+ APPENDER_ACTIVATE_MISSING_FILE_ERROR,
+ APPENDER_CLOSED_ERROR,
+ APPENDER_INVALID_PATTERN_ERROR,
+ APPENDER_NO_OPEN_FILE_ERROR,
+ APPENDER_NOT_ACTIVATED_ERROR,
+ APPENDER_OPENING_FILE_ERROR,
+ APPENDER_RENAMING_FILE_ERROR,
+ APPENDER_REMOVE_FILE_ERROR,
+ APPENDER_USE_INVALID_PATTERN_ERROR,
+ APPENDER_USE_MISSING_LAYOUT_ERROR,
+ APPENDER_USE_MISSING_WRITER_ERROR,
+ APPENDER_WRITING_FILE_ERROR,
+ // Level
+ LEVEL_INVALID_LEVEL_STRING,
+ // Layouts, PatternFormatter
+ LAYOUT_EXPECTED_DIGIT_ERROR,
+ LAYOUT_OPTION_IS_NOT_INTEGER_ERROR,
+ LAYOUT_INTEGER_IS_NOT_POSITIVE_ERROR,
+ // Logger
+ LOGGER_INVALID_LEVEL_FOR_ROOT,
+ // PropertyConfigurator, OptionHandler
+ CONFIGURATOR_OPENING_FILE_ERROR,
+ CONFIGURATOR_READING_FILE_ERROR,
+ CONFIGURATOR_INVALID_SUBSTITUTION_ERROR,
+ CONFIGURATOR_INVALID_OPTION_ERROR,
+ CONFIGURATOR_MISSING_APPENDER_ERROR,
+ CONFIGURATOR_UNKNOWN_APPENDER_CLASS_ERROR,
+ CONFIGURATOR_MISSING_LAYOUT_ERROR,
+ CONFIGURATOR_UNKNOWN_LAYOUT_CLASS_ERROR,
+ CONFIGURATOR_PROPERTY_ERROR,
+ CONFIGURATOR_UNKNOWN_TYPE_ERROR
+ };
+
+
+ /******************************************************************************
+ * Operators, Helpers
+ ******************************************************************************/
+
+
+ /******************************************************************************
+ * Inline
+ ******************************************************************************/
+
+
+} // namespace Log4Qt
+
+
+#endif // LOG4QT_H
diff --git a/src/log4qt/log4qt/log4qt.pri b/src/log4qt/log4qt/log4qt.pri
new file mode 100644
index 0000000..3c3b111
--- /dev/null
+++ b/src/log4qt/log4qt/log4qt.pri
@@ -0,0 +1,113 @@
+# *******************************************************************************
+#
+# package: Log4Qt
+# file: log4qt.pri
+# created: September 2007
+# author: Martin Heinrich
+#
+#
+# Copyright 2007 Martin Heinrich
+#
+# 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.
+#
+# *******************************************************************************
+
+INCLUDEPATH += $$PWD/..
+DEPENDPATH += $$PWD/..
+HEADERS += \
+ $$PWD/appender.h \
+ $$PWD/appenderskeleton.h \
+ $$PWD/basicconfigurator.h \
+ $$PWD/consoleappender.h \
+ $$PWD/dailyrollingfileappender.h \
+ $$PWD/fileappender.h \
+ $$PWD/helpers/classlogger.h \
+ $$PWD/helpers/configuratorhelper.h \
+ $$PWD/helpers/datetime.h \
+ $$PWD/helpers/factory.h \
+ $$PWD/helpers/initialisationhelper.h \
+ $$PWD/helpers/logerror.h \
+ $$PWD/helpers/logobject.h \
+ $$PWD/helpers/logobjectptr.h \
+ $$PWD/helpers/optionconverter.h \
+ $$PWD/helpers/patternformatter.h \
+ $$PWD/helpers/properties.h \
+ $$PWD/helpers/asyncdispatcher.h \
+ $$PWD/hierarchy.h \
+ $$PWD/layout.h \
+ $$PWD/level.h \
+ $$PWD/log4qt.h \
+ $$PWD/logger.h \
+ $$PWD/loggerrepository.h \
+ $$PWD/loggingevent.h \
+ $$PWD/logmanager.h \
+ $$PWD/mdc.h \
+ $$PWD/ndc.h \
+ $$PWD/patternlayout.h \
+ $$PWD/propertyconfigurator.h \
+ $$PWD/rollingfileappender.h \
+ $$PWD/simplelayout.h \
+ $$PWD/spi/filter.h \
+ $$PWD/ttcclayout.h \
+ $$PWD/writerappender.h \
+ $$PWD/varia/debugappender.h \
+ $$PWD/varia/denyallfilter.h \
+ $$PWD/varia/nullappender.h \
+ $$PWD/varia/levelmatchfilter.h \
+ $$PWD/varia/levelrangefilter.h \
+ $$PWD/varia/listappender.h \
+ $$PWD/varia/stringmatchfilter.h
+
+SOURCES += \
+ $$PWD/appenderskeleton.cpp \
+ $$PWD/basicconfigurator.cpp \
+ $$PWD/consoleappender.cpp \
+ $$PWD/dailyrollingfileappender.cpp \
+ $$PWD/fileappender.cpp \
+ $$PWD/helpers/classlogger.cpp \
+ $$PWD/helpers/configuratorhelper.cpp \
+ $$PWD/helpers/datetime.cpp \
+ $$PWD/helpers/factory.cpp \
+ $$PWD/helpers/initialisationhelper.cpp \
+ $$PWD/helpers/logerror.cpp \
+ $$PWD/helpers/logobject.cpp \
+ $$PWD/helpers/logobjectptr.cpp \
+ $$PWD/helpers/optionconverter.cpp \
+ $$PWD/helpers/patternformatter.cpp \
+ $$PWD/helpers/properties.cpp \
+ $$PWD/helpers/asyncdispatcher.cpp \
+ $$PWD/hierarchy.cpp \
+ $$PWD/layout.cpp \
+ $$PWD/level.cpp \
+ $$PWD/log4qt.cpp \
+ $$PWD/logger.cpp \
+ $$PWD/loggerrepository.cpp \
+ $$PWD/loggingevent.cpp \
+ $$PWD/logmanager.cpp \
+ $$PWD/mdc.cpp \
+ $$PWD/ndc.cpp \
+ $$PWD/patternlayout.cpp \
+ $$PWD/propertyconfigurator.cpp \
+ $$PWD/rollingfileappender.cpp \
+ $$PWD/simplelayout.cpp \
+ $$PWD/spi/filter.cpp \
+ $$PWD/ttcclayout.cpp \
+ $$PWD/writerappender.cpp \
+ $$PWD/varia/debugappender.cpp \
+ $$PWD/varia/denyallfilter.cpp \
+ $$PWD/varia/nullappender.cpp \
+ $$PWD/varia/levelmatchfilter.cpp \
+ $$PWD/varia/levelrangefilter.cpp \
+ $$PWD/varia/listappender.cpp \
+ $$PWD/varia/stringmatchfilter.cpp
+
\ No newline at end of file
diff --git a/src/log4qt/log4qt/logger.cpp b/src/log4qt/log4qt/logger.cpp
new file mode 100644
index 0000000..d5dc936
--- /dev/null
+++ b/src/log4qt/log4qt/logger.cpp
@@ -0,0 +1,349 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: logger.cpp
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * changes: Sep 2008, Martin Heinrich:
+ * - Fixed problem in Qt 4.4 where QReadWriteLock is by default
+ * non-recursive.
+ *
+ *
+ * Copyright 2007 - 2008 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+
+#include "log4qt/logger.h"
+
+#include
+#include "log4qt/appenderskeleton.h"
+#include "log4qt/varia/listappender.h"
+#include "log4qt/loggingevent.h"
+#include "log4qt/log4qt.h"
+#include "log4qt/loggerrepository.h"
+#include "log4qt/logmanager.h"
+
+
+namespace Log4Qt
+{
+
+
+ /**************************************************************************
+ * Declarations
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * C helper functions
+ **************************************************************************/
+
+
+
+ /**************************************************************************
+ * Class implementation: Logger
+ **************************************************************************/
+
+
+ Logger::Logger(LoggerRepository* pLoggerRepository, Level level, const QString &rName, Logger *pParent) :
+ QObject(0),
+#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0)
+ mObjectGuard(),
+#else
+ mObjectGuard(QReadWriteLock::Recursive),
+#endif
+ mName(rName),
+ mpLoggerRepository(pLoggerRepository),
+ mAdditivity(true),
+ mAppenders(),
+ mLevel(level),
+ mpParent(pParent)
+ {
+ Q_ASSERT_X(pLoggerRepository, "Logger::Logger()", "Construction of Logger with null LoggerRepository");
+
+ setObjectName(mName);
+ }
+
+
+ Logger::~Logger()
+ {
+ logger()->warn("Unexpected destruction of Logger");
+
+ // QWriteLocker locker(&mObjectGuard);
+ //
+ // QMutableListIterator< LogObjectPtr > i(mAppenders);
+ // while (i.hasNext())
+ // {
+ // i.next();
+ // i.remove();
+ // }
+ }
+
+
+ QList Logger::appenders() const
+ {
+ QReadLocker locker(&mObjectGuard);
+
+ QList result;
+ Appender *p_appender;
+ Q_FOREACH(p_appender, mAppenders)
+ result << p_appender;
+ return result;
+ }
+
+
+ void Logger::setLevel(Level level)
+ {
+ // QWriteLocker locker(&mObjectGuard); // Read/Write int is safe
+
+ if ((parentLogger() == 0) && (level == Level::NULL_INT))
+ {
+ logger()->warn("Invalid root logger level NULL_INT. Using DEBUG_INT instead");
+ level = Level::DEBUG_INT;
+ }
+ mLevel = level;
+ }
+
+
+ void Logger::addAppender(Appender *pAppender)
+ {
+ // Avoid deadlock:
+ // - Handle warnings, before write lock is aquired
+
+ // Keep objects with a 0 reference count safe
+ LogObjectPtr p_appender = pAppender;
+
+ {
+ QReadLocker locker(&mObjectGuard);
+
+ if(!p_appender)
+ {
+ logger()->warn("Adding null Appender to Logger '%1'", name());
+ return;
+ }
+ if(mAppenders.contains(p_appender))
+ {
+ logger()->warn("Adding of duplicate appender '%2' to logger '%1'", name(), p_appender->name());
+ return;
+ }
+ }
+ {
+ QWriteLocker locker(&mObjectGuard);
+
+ if(mAppenders.contains(p_appender))
+ return;
+ mAppenders.append(p_appender);
+ }
+ }
+
+
+ Appender *Logger::appender(const QString &rName) const
+ {
+ QReadLocker locker(&mObjectGuard);
+
+ Appender *p_appender;
+ Q_FOREACH(p_appender, mAppenders)
+ if (p_appender->name() == rName)
+ return p_appender;
+ return 0;
+ }
+
+
+
+ void Logger::callAppenders(const LoggingEvent &rEvent) const
+ {
+ QReadLocker locker(&mObjectGuard);
+
+ Appender *p_appender;
+ Q_FOREACH(p_appender, mAppenders)
+ p_appender->doAppend(rEvent);
+ if (additivity() && (parentLogger() != 0))
+ parentLogger()->callAppenders(rEvent);
+ }
+
+
+ bool Logger::isAttached(Appender *pAppender) const
+ {
+ QReadLocker locker(&mObjectGuard);
+
+ // Keep objects with a 0 reference count safe
+ LogObjectPtr p_appender = pAppender;
+
+ return mAppenders.contains(p_appender);
+ }
+
+
+ void Logger::removeAllAppenders()
+ {
+ // Avoid deadlock:
+ // - Only log warnings without having the write log aquired
+ // - Hold a reference to all appenders so that the remove does not
+ // destruct the appender over the reference count while the write
+ // log is held. The appender may log messages.
+
+ logger()->trace("Removing all appenders from logger '%1'", name());
+
+ QList< LogObjectPtr > appenders;
+ {
+ QWriteLocker locker(&mObjectGuard);
+ QMutableListIterator< LogObjectPtr > i(mAppenders);
+ while (i.hasNext())
+ {
+ Appender *p_appender = i.next();
+ ListAppender *p_listappender = qobject_cast(p_appender);
+ if (p_listappender && p_listappender->configuratorList())
+ continue;
+ else
+ {
+ appenders << p_appender;
+ i.remove();
+ }
+ }
+ }
+ appenders.clear();
+ }
+
+
+ void Logger::removeAppender(Appender *pAppender)
+ {
+ // Avoid deadlock:
+ // - Only log warnings without having the write log aquired
+ // - Hold a reference to the appender so that the remove does not
+ // destruct the appender over the reference count while the write
+ // log is held. The appender may log messages.
+
+ LogObjectPtr p_appender = pAppender;
+
+ if(!p_appender)
+ {
+ logger()->warn("Request to remove null Appender from Logger '%1'", name());
+ return;
+ }
+ int n;
+ {
+ QWriteLocker locker(&mObjectGuard);
+
+ n = mAppenders.removeAll(p_appender);
+ }
+ if (n == 0)
+ {
+ logger()->warn("Request to remove Appender '%2', which is not part of Logger '%1' appenders", name(), p_appender->name());
+ return;
+ }
+ }
+
+
+ void Logger::removeAppender(const QString &rName)
+ {
+ Appender *p_appender = appender(rName);
+ if (p_appender)
+ removeAppender(p_appender);
+ }
+
+
+ Level Logger::effectiveLevel() const
+ {
+ Q_ASSERT_X(LogManager::rootLogger()->level() != Level::NULL_INT, "Logger::effectiveLevel()", "Root logger level must not be NULL_INT");
+
+ QReadLocker locker(&mObjectGuard);
+
+ const Logger *p_logger = this;
+ while (p_logger->level() == Level::NULL_INT)
+ p_logger = p_logger->parentLogger();
+ return p_logger->level();
+ }
+
+
+ bool Logger::isEnabledFor(Level level) const
+ {
+ if (mpLoggerRepository->isDisabled(level))
+ return false;
+ return (effectiveLevel() <= level);
+ }
+
+
+ Logger *Logger::logger(const QString &rName)
+ {
+ return LogManager::logger(rName);
+ }
+
+
+ Logger *Logger::logger(const char *pName)
+ {
+ return LogManager::logger(QLatin1String(pName));
+ }
+
+
+ Logger *Logger::rootLogger()
+ {
+ return LogManager::rootLogger();
+ }
+
+
+#ifndef QT_NO_DEBUG_STREAM
+ QDebug Logger::debug(QDebug &rDebug) const
+ {
+ QReadLocker locker(&mObjectGuard);
+
+ QString parent_logger;
+ if (mpParent)
+ parent_logger = mpParent->name();
+
+ rDebug.nospace() << "Logger("
+ << "name:" << name() << " "
+ << "appenders:" << mAppenders.count() << " "
+ << "additivity:" << mAdditivity << " "
+ << mLevel
+ << "parentLogger:" << parent_logger
+ << ")";
+ return rDebug.space();
+ }
+#endif // QT_NO_DEBUG_STREAM
+
+
+ void Logger::forcedLog(Level level, const QString &rMessage) const
+ {
+ QReadLocker locker(&mObjectGuard);
+
+ LoggingEvent event(this, level, rMessage);
+ callAppenders(event);
+ }
+
+
+
+ /**************************************************************************
+ * Implementation: Operators, Helper
+ **************************************************************************/
+
+
+#ifndef QT_NO_DEBUG_STREAM
+ QDebug operator<<(QDebug debug, const Logger &rLogger)
+ {
+ return rLogger.debug(debug);
+ }
+#endif // QT_NO_DEBUG_STREAM
+
+
+
+} // namespace Log4Qt
diff --git a/src/log4qt/log4qt/logger.h b/src/log4qt/log4qt/logger.h
new file mode 100644
index 0000000..73a877d
--- /dev/null
+++ b/src/log4qt/log4qt/logger.h
@@ -0,0 +1,1666 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: logger.h
+ * created: September 2007
+ * author: Martin Heinrich
+ *
+ *
+ * changes: Sep 2008, Martin Heinrich:
+ * - Replaced usage of q_atomic_test_and_set_ptr with
+ * QBasicAtomicPointer
+ *
+ *
+ * Copyright 2007 - 2008 Martin Heinrich
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef LOG4QT_LOGGER_H
+#define LOG4QT_LOGGER_H
+
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+#include
+
+#include
+#include
+#include
+#include "log4qt/helpers/logerror.h"
+#include "log4qt/helpers/classlogger.h"
+#include "log4qt/helpers/logobjectptr.h"
+#include "log4qt/level.h"
+#include "ukui-logmacros.h"
+
+#if QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)
+# ifndef Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
+# warning "QAtomicPointer test and set is not native. The macro Log4Qt::LOG4QT_DECLARE_STATIC_LOGGER is not thread-safe."
+# endif
+#endif
+
+
+/******************************************************************************
+ * Declarations
+ ******************************************************************************/
+
+namespace Log4Qt
+{
+
+ /*!
+ * LOG4QT_DECLARE_STATIC_LOGGER declares a static function \a FUNCTION that
+ * returns a pointer to a \ref Log4Qt::Logger "Logger" named after \a CLASS.
+ *
+ * On the first invocation the \ref Log4Qt::Logger "Logger" is requested
+ * by calling \ref Log4Qt::Logger::logger(const char *pName)
+ * "Logger::logger( #CLASS )". The pointer is stored to be returned on
+ * subsequent invocations.
+ *
+ * The following example shows how to use the macro to define a logger to be
+ * used within a class not derived from QObject.
+ *
+ * \code
+ * #file: counter.h
+ *
+ * #include logger.h
+ *
+ * class Counter
+ * {
+ * public:
+ * Counter();
+ * Counter(int preset);
+ * private:
+ * int mCount;
+ * }
+ * \endcode
+ * \code
+ * #file: counter.cpp
+ *
+ * #include counter.h
+ *
+ * LOG4QT_DECLARE_STATIC_LOGGER(logger, Counter)
+ *
+ * Counter::Counter() :
+ * mCount(0)
+ * {}
+ *
+ * void Counter::Counter(int preset) :
+ * mCount(preset)
+ * {
+ * if (preset < 0)
+ * {
+ * logger()->warn("Invalid negative counter preset %1. Using 0 instead.", preset);
+ * mCount = 0;
+ * }
+ * }
+ * \endcode
+ *
+ * \note The function created by the macro is thread-safe.
+ *
+ * \sa \ref Log4Qt::Logger::logger(const char *pName) "Logger::logger(const char *pName)"
+ */
+#if QT_VERSION < QT_VERSION_CHECK(4, 4, 0)
+ #define LOG4QT_DECLARE_STATIC_LOGGER(FUNCTION, CLASS) \
+ static Log4Qt::Logger *FUNCTION() \
+ { \
+ static Log4Qt::Logger *p_logger = 0; \
+ if (!p_logger) \
+ { \
+ q_atomic_test_and_set_ptr( \
+ &p_logger, \
+ 0, \
+ Log4Qt::Logger::logger( #CLASS )); \
+ } \
+ return p_logger; \
+ }
+#elif QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ #define LOG4QT_DECLARE_STATIC_LOGGER(FUNCTION, CLASS) \
+ static Log4Qt::Logger *FUNCTION() \
+ { \
+ static QBasicAtomicPointer p_logger = \
+ Q_BASIC_ATOMIC_INITIALIZER(0); \
+ if (!p_logger) \
+ { \
+ p_logger.testAndSetOrdered(0, \
+ Log4Qt::Logger::logger( #CLASS )); \
+ } \
+ return p_logger; \
+ }
+#else
+ #define LOG4QT_DECLARE_STATIC_LOGGER(FUNCTION, CLASS) \
+ static Log4Qt::Logger *FUNCTION() \
+ { \
+ static QBasicAtomicPointer p_logger = \
+ Q_BASIC_ATOMIC_INITIALIZER(0); \
+ if (!p_logger.loadAcquire()) \
+ { \
+ p_logger.testAndSetOrdered(0, \
+ Log4Qt::Logger::logger( #CLASS )); \
+ } \
+ return p_logger.loadAcquire(); \
+ }
+#endif
+
+ /*!
+ * LOG4QT_DECLARE_QCLASS_LOGGER declares member functions to retrieve
+ * \ref Log4Qt::Logger "Logger" for the class it is used in.
+ *
+ * On the first invocation the \ref Log4Qt::Logger "Logger" is requested
+ * by a call to \ref Log4Qt::Logger::logger(const char *pName)
+ * "Logger::logger(const char *pName)". The pointer is stored to be
+ * returned on subsequent invocations.
+ *
+ * The following example shows how to use the macro to define a logger to be
+ * used within a class derived from QObject.
+ *
+ * \code
+ * #file: counter.h
+ *
+ * #include qobject.h
+ * #include logger.h
+ *
+ * class Counter : public QObject
+ * {
+ * Q_OBJECT
+ * LOG4QT_DECLARE_QCLASS_LOGGER
+ * public:
+ * Counter();
+ * Counter(int preset);
+ * private:
+ * int mCount;
+ * }
+ * \endcode
+ * \code
+ * #file: counter.cpp
+ *
+ * #include counter.h
+ *
+ * Counter::Counter() :
+ * mCount(0)
+ * {}
+ *
+ * void Counter::Counter(int preset)
+ * mCount(preset)
+ * {
+ * if (preset < 0)
+ * {
+ * logger()->warn("Invalid negative counter preset %1. Using 0 instead.", preset);
+ * mCount = 0;
+ * }
+ * }
+ * \endcode
+ *
+ * \note The function created by the macro is thread-safe.
+ *
+ * \sa \ref Log4Qt::Logger::logger(const char *pName) "Logger::logger(const char *pName)",
+ * \ref Log4Qt::ClassLogger "ClassLogger"
+ */
+ #define LOG4QT_DECLARE_QCLASS_LOGGER \
+ private: \
+ mutable Log4Qt::ClassLogger mLog4QtClassLogger; \
+ public: \
+ inline Log4Qt::Logger *logger() const \
+ { return mLog4QtClassLogger.logger(this); } \
+ private:
+
+ class Appender;
+ class LoggingEvent;
+ class LoggerRepository;
+
+ /*!
+ * \brief The class Logger provides logging services.
+ *
+ * A pointer to a logger can be retrieved by calling Logger::logger() or
+ * LogManager::logger() with the class name as argument. Because a logger
+ * is never destroyed it is possible to store the pointer to the logger.
+ * This way the lookup of the pointer in the repository is only required
+ * on the first logging operation. The macros \ref
+ * Log4Qt::LOG4QT_DECLARE_STATIC_LOGGER "LOG4QT_DECLARE_STATIC_LOGGER" and
+ * \ref Log4Qt::LOG4QT_DECLARE_QCLASS_LOGGER "LOG4QT_DECLARE_QCLASS_LOGGER"
+ * provide a thread-safe implementation to store the logger pointer.
+ *
+ * \note All the functions declared in this class are thread-safe.
+ */
+ class LIBUKUILOG4QT_EXPORT Logger : public QObject
+ {
+ Q_OBJECT
+
+ /*!
+ * The property holds, if the logger is additive.
+ *
+ * The default is true for being additive.
+ *
+ * \sa additive(), setAdditive()
+ */
+ Q_PROPERTY(bool additivity READ additivity WRITE setAdditivity)
+
+ /*!
+ * The property holds the level used by the logger.
+ *
+ * The default is Level::NULL_INT.
+ * \sa level(), setLevel()
+ */
+ Q_PROPERTY(Level level READ level WRITE setLevel)
+
+ /*!
+ * The property holds the LoggerRepository of the logger.
+ *
+ * \sa loggerRepository()
+ */
+ Q_PROPERTY(LoggerRepository* loggerRepository READ loggerRepository)
+
+ /*!
+ * The property holds the name of the logger.
+ *
+ * \sa name()
+ */
+ Q_PROPERTY(QString name READ name)
+
+ /*!
+ * The property holds the parent logger of the logger.
+ *
+ * \sa parentLogger()
+ */
+ Q_PROPERTY(Logger* parentLogger READ parentLogger)
+
+ LOG4QT_DECLARE_QCLASS_LOGGER
+
+ protected:
+ Logger(LoggerRepository* pLoggerRepository, Level level, const QString &rName, Logger *pParent = 0);
+ virtual ~Logger();
+ private:
+ Logger(const Logger &rOther); // Not implemented
+ Logger &operator=(const Logger &rOther); // Not implemented
+
+ public:
+ bool additivity() const;
+ QList appenders() const;
+ Level level() const;
+ LoggerRepository *loggerRepository() const;
+ QString name() const;
+ Logger *parentLogger() const;
+ // JAVA: ResourceBundle *resourceBundle() const;
+ // JAVA: void setResourceBundle(ResourceBundle *pResourceBundle);
+ void setAdditivity(bool additivity);
+ virtual void setLevel(Level level);
+
+ void addAppender(Appender *pAppender);
+ Appender *appender(const QString &rName) const;
+ void callAppenders(const LoggingEvent &rEvent) const;
+ bool isAttached(Appender *pAppender) const;
+
+ /*!
+ * Removes all appenders that have been previously added from this
+ * Logger.
+ *
+ * To allow configurators to collect events during the configuration
+ * process ListAppenders with the configuratorList property set, will
+ * not be removed.
+ *
+ * \sa LisAppender::setConfiguratorList()
+ */
+ void removeAllAppenders();
+
+ void removeAppender(Appender *pAppender);
+ void removeAppender(const QString &rName);
+ // JAVA: QString resourceBundleString(const QString &rKey) const;
+
+ Level effectiveLevel() const;
+ bool isDebugEnabled() const;
+
+ /*!
+ * Checks if this logger is enabled for a given Level \a level. If the
+ * logger is enabled the function returns true. Otherwise it returns
+ * false.
+ *
+ * A logger is enabled for a level, if the level is greater or equal
+ * then the repository threshold and greater and equal then the loggers
+ * effective level.
+ *
+ * \sa LoggerRepository::isDisabled(), effectiveLevel()
+ */
+ bool isEnabledFor(Level level) const;
+
+ bool isErrorEnabled() const;
+ bool isFatalEnabled() const;
+ bool isInfoEnabled() const;
+ bool isTraceEnabled() const;
+ bool isWarnEnabled() const;
+
+ void debug(const QString &rMessage) const;
+ void debug(const LogError &rLogError) const;
+ void debug(const char *pMessage) const;
+ void debug(const char *pMessage,
+ const QString &rArg1) const;
+ void debug(const char *pMessage,
+ int arg1) const;
+ void debug(const char *pMessage,
+ const QString &rArg1,
+ const QString &rArg2) const;
+ void debug(const char *pMessage,
+ const QString &rArg1,
+ int arg2) const;
+ void debug(const char *pMessage,
+ int arg1,
+ const QString &rArg2) const;
+ void debug(const char *pMessage,
+ int arg1,
+ int arg2) const;
+ void debug(const char *pMessage,
+ const QString &rArg1,
+ const QString &rArg2,
+ const QString &rArg3) const;
+ void debug(const char *pMessage,
+ const QString &rArg1,
+ const QString &rArg2,
+ int arg3) const;
+ void debug(const char *pMessage,
+ const QString &rArg1,
+ int arg2,
+ const QString &rArg3) const;
+ void debug(const char *pMessage,
+ const QString &rArg1,
+ int arg2,
+ int arg3) const;
+ void debug(const char *pMessage,
+ int arg1,
+ const QString &rArg2,
+ const QString &rArg3) const;
+ void debug(const char *pMessage,
+ int arg1,
+ const QString &rArg2,
+ int arg3) const;
+ void debug(const char *pMessage,
+ int arg1,
+ int arg2,
+ const QString &rArg3) const;
+ void debug(const char *pMessage,
+ int arg1,
+ int arg2,
+ int arg3) const;
+ void debug(const char *pMessage,
+ const QVariant &rArg1,
+ const QVariant &rArg2,
+ const QVariant &rArg3) const;
+
+ void error(const QString &rMessage) const;
+ void error(const LogError &rLogError) const;
+ void error(const char *pMessage) const;
+ void error(const char *pMessage,
+ const QString &rArg1) const;
+ void error(const char *pMessage,
+ int arg1) const;
+ void error(const char *pMessage,
+ const QString &rArg1,
+ const QString &rArg2) const;
+ void error(const char *pMessage,
+ const QString &rArg1, int arg2) const;
+ void error(const char *pMessage,
+ int arg1,
+ const QString &rArg2) const;
+ void error(const char *pMessage,
+ int arg1,
+ int arg2) const;
+ void error(const char *pMessage,
+ const QString &rArg1,
+ const QString &rArg2,
+ const QString &rArg3) const;
+ void error(const char *pMessage,
+ const QString &rArg1,
+ const QString &rArg2,
+ int arg3) const;
+ void error(const char *pMessage,
+ const QString &rArg1,
+ int arg2,
+ const QString &rArg3) const;
+ void error(const char *pMessage,
+ const QString &rArg1,
+ int arg2,
+ int arg3) const;
+ void error(const char *pMessage,
+ int arg1,
+ const QString &rArg2,
+ const QString &rArg3) const;
+ void error(const char *pMessage,
+ int arg1,
+ const QString &rArg2,
+ int arg3) const;
+ void error(const char *pMessage,
+ int arg1,
+ int arg2,
+ const QString &rArg3) const;
+ void error(const char *pMessage,
+ int arg1,
+ int arg2,
+ int arg3) const;
+ void error(const char *pMessage,
+ const QVariant &rArg1,
+ const QVariant &rArg2,
+ const QVariant &rArg3) const;
+
+ void fatal(const QString &rMessage) const;
+ void fatal(const LogError &rLogError) const;
+ void fatal(const char *pMessage) const;
+ void fatal(const char *pMessage,
+ const QString &rArg1) const;
+ void fatal(const char *pMessage,
+ int arg1) const;
+ void fatal(const char *pMessage,
+ const QString &rArg1,
+ const QString &rArg2) const;
+ void fatal(const char *pMessage,
+ const QString &rArg1,
+ int arg2) const;
+ void fatal(const char *pMessage,
+ int arg1,
+ const QString &rArg2) const;
+ void fatal(const char *pMessage,
+ int arg1,
+ int arg2) const;
+ void fatal(const char *pMessage,
+ const QString &rArg1,
+ const QString &rArg2,
+ const QString &rArg3) const;
+ void fatal(const char *pMessage,
+ const QString &rArg1,
+ const QString &rArg2,
+ int arg3) const;
+ void fatal(const char *pMessage,
+ const QString &rArg1,
+ int arg2,
+ const QString &rArg3) const;
+ void fatal(const char *pMessage,
+ const QString &rArg1,
+ int arg2,
+ int arg3) const;
+ void fatal(const char *pMessage,
+ int arg1,
+ const QString &rArg2,
+ const QString &rArg3) const;
+ void fatal(const char *pMessage,
+ int arg1,
+ const QString &rArg2,
+ int arg3) const;
+ void fatal(const char *pMessage,
+ int arg1,
+ int arg2,
+ const QString &rArg3) const;
+ void fatal(const char *pMessage,
+ int arg1,
+ int arg2,
+ int arg3) const;
+ void fatal(const char *pMessage,
+ const QVariant &rArg1,
+ const QVariant &rArg2,
+ const QVariant &rArg3) const;
+
+ void info(const QString &rMessage) const;
+ void info(const LogError &rLogError) const;
+ void info(const char *pMessage) const;
+ void info(const char *pMessage,
+ const QString &rArg1) const;
+ void info(const char *pMessage,
+ int arg1) const;
+ void info(const char *pMessage,
+ const QString &rArg1,
+ const QString &rArg2) const;
+ void info(const char *pMessage,
+ const QString &rArg1,
+ int arg2) const;
+ void info(const char *pMessage,
+ int arg1,
+ const QString &rArg2) const;
+ void info(const char *pMessage,
+ int arg1,
+ int arg2) const;
+ void info(const char *pMessage,
+ const QString &rArg1,
+ const QString &rArg2,
+ const QString &rArg3) const;
+ void info(const char *pMessage,
+ const QString &rArg1,
+ const QString &rArg2,
+ int arg3) const;
+ void info(const char *pMessage,
+ const QString &rArg1,
+ int arg2,
+ const QString &rArg3) const;
+ void info(const char *pMessage,
+ const QString &rArg1,
+ int arg2,
+ int arg3) const;
+ void info(const char *pMessage,
+ int arg1,
+ const QString &rArg2,
+ const QString &rArg3) const;
+ void info(const char *pMessage,
+ int arg1,
+ const QString &rArg2,
+ int arg3) const;
+ void info(const char *pMessage,
+ int arg1,
+ int arg2,
+ const QString &rArg3) const;
+ void info(const char *pMessage,
+ int arg1,
+ int arg2,
+ int arg3) const;
+ void info(const char *pMessage,
+ const QVariant &rArg1,
+ const QVariant &rArg2,
+ const QVariant &rArg3) const;
+
+ void log(Level level,
+ const QString &rMessage) const;
+ void log(Level level,
+ const LogError &rLogError) const;
+ void log(Level level,
+ const char *pMessage) const;
+ void log(Level level,
+ const char *pMessage,
+ const QString &rArg1) const;
+ void log(Level level,
+ const char *pMessage,
+ int arg1) const;
+ void log(Level level,
+ const char *pMessage,
+ const QString &rArg1,
+ const QString &rArg2) const;
+ void log(Level level,
+ const char *pMessage,
+ const QString &rArg1,
+ int arg2) const;
+ void log(Level level,
+ const char *pMessage,
+ int arg1,
+ const QString &rArg2) const;
+ void log(Level level,
+ const char *pMessage,
+ int arg1,
+ int arg2) const;
+ void log(Level level,
+ const char *pMessage,
+ const QString &rArg1,
+ const QString &rArg2,
+ const QString &rArg3) const;
+ void log(Level level,
+ const char *pMessage,
+ const QString &rArg1,
+ const QString &rArg2,
+ int arg3) const;
+ void log(Level level,
+ const char *pMessage,
+ const QString &rArg1,
+ int arg2,
+ const QString &rArg3) const;
+ void log(Level level,
+ const char *pMessage,
+ const QString &rArg1,
+ int arg2,
+ int arg3) const;
+ void log(Level level,
+ const char *pMessage,
+ int arg1,
+ const QString &rArg2,
+ const QString &rArg3) const;
+ void log(Level level,
+ const char *pMessage,
+ int arg1,
+ const QString &rArg2,
+ int arg3) const;
+ void log(Level level,
+ const char *pMessage,
+ int arg1,
+ int arg2,
+ const QString &rArg3) const;
+ void log(Level level,
+ const char *pMessage,
+ int arg1,
+ int arg2,
+ int arg3) const;
+ void log(Level level,
+ const char *pMessage,
+ const QVariant &rArg1,
+ const QVariant &rArg2,
+ const QVariant &rArg3) const;
+
+ // JAVA: void l7dlog(Level level,
+ // const QString &rKey);
+ // JAVA: void l7dlog(Level level,
+ // const QString &rKey,
+ // const QList