Narasimha Rao | 4 Feb 2006 21:22
Picon
Favicon

Re: Intended commits for L7dTestCase (LOGCXX-125)

Dear Arnold,
DO you know anybody using Log4CXX on HP UX with aCC compiler.
I need to compile Log4CXX with aCC compiler on HP UX 11.11.
I need a make file to compile the code and do we need any specific libraries lile xml2 etc.. before compile?
Can you pleae help me?
While compiling i got one error like error before or after ' ( '  in socket.h line 248 etc...
Thank you,
Nara

Curt Arnold <carnold <at> apache.org> wrote:

On Jan 30, 2006, at 9:12 AM, Andreas Fester wrote:

> This patch fixes the localized logging which was still #if 0'ed out.
>
> To read the resource files, a FileInputStream class was added.
> This aligns the class structure better with the java world,
> instead of having read/write methods directly on the File class.
>


log4cxx::InputStream and log4cxx::FileInputStream in the patch work
on characters and are therefore really aligned with java.io.Reader
and java.io.FileReader, not their java.io namesakes. If there is to
be a log4cxx::InputStream its methods should be using
std::vector instead of LogString.

I'd support either simply renaming the InputStream and
FileInputStream classes to Reader and FileReader and accepting the
patch as a basis for further work or let you try to split out the raw
byte-level IO classes from the character based classes.


Brings words and photos together (easily) with
PhotoMail - it's free and works with Yahoo! Mail.
Curt Arnold | 5 Feb 2006 03:09
Picon
Favicon

log4cxx on HP UX with aCC compiler (was Re: Intended commits for L7dTestCase (LOGCXX-125))


On Feb 4, 2006, at 2:22 PM, Narasimha Rao wrote:

> Dear Arnold,
> DO you know anybody using Log4CXX on HP UX with aCC compiler.
> I need to compile Log4CXX with aCC compiler on HP UX 11.11.
> I need a make file to compile the code and do we need any specific  
> libraries lile xml2 etc.. before compile?
> Can you pleae help me?
> While compiling i got one error like error before or after ' ( '   
> in socket.h line 248 etc...
> Thank you,
> Nara
>

I am not aware of anyone using log4cxx on HP UX with a aCC  
compiler.   If anyone else on the list knows, please speak up.

Do you have a Java VM on the machine?  Have you tried using the Ant  
based build?

1. Download Ant 1.6.5 from http://ant.apache.org
2. Checkout CVS HEAD of cpptasks (see http://sf.net/projects/ant- 
contrib) and build

cvs -d:pserver:anonymous <at> cvs.sourceforge.net:/cvsroot/ant-contrib login
cvs -z3 -d:pserver:anonymous <at> cvs.sourceforge.net:/cvsroot/ant-contrib  
co -P cpptasks
export PATH /home/foo/apache-ant-1.6.5/bin;$PATH$
cd cpptasks
ant

3. Put cpptasks.jar on classpath

export CLASSPATH /home/foo/cpptasks/build/lib/cpptasks.jar

4. Build log4cxx

I believe that the default mirror used for cppunit is no longer  
responding.  You can override it, but finding a mirror name from  
http://sf.net/projects/cppunit files page and then specifying

cd log4cxx
ant -Dcompiler=aCC -Dcppunit.mirror=http://example.com/example/ 
sourceforge -l build.log

If you do get a compiler error on aCC, file a JIRA issue and attach  
the full build session log (specified with the -l option switch)

carnold | 7 Feb 2006 20:47
Picon
Favicon

svn commit: r375672 - /logging/log4cxx/trunk/build.xml

Author: carnold
Date: Tue Feb  7 11:47:23 2006
New Revision: 375672

URL: http://svn.apache.org/viewcvs?rev=375672&view=rev
Log:
LOGCXX-127: Main build.xml not referencing environment variables properly

Modified:
    logging/log4cxx/trunk/build.xml

Modified: logging/log4cxx/trunk/build.xml
URL: http://svn.apache.org/viewcvs/logging/log4cxx/trunk/build.xml?rev=375672&r1=375671&r2=375672&view=diff
==============================================================================
--- logging/log4cxx/trunk/build.xml (original)
+++ logging/log4cxx/trunk/build.xml Tue Feb  7 11:47:23 2006
 <at>  <at>  -38,6 +38,7  <at>  <at> 
 -->
 <project name="log4cxx" default="check">

+<property environment="env"/>
 <property name="debug" value="true"/>
 <property name="base.dir" location="."/>
 <property name="src.dir" location="${base.dir}/src"/>

Andreas Fester | 20 Feb 2006 21:29
Picon
Favicon

LOGCXX-126: opinion for suggested fix

See http://issues.apache.org/jira/browse/LOGCXX-126

The suggested fix is to modify SystemErrWriter (and in the same way
SystemOutWriter) as follows:

OLD:
====

void SystemErrWriter::write(const LogString& str, Pool& p) {
#if LOG4CXX_HAS_WCHAR_T
    LOG4CXX_ENCODE_WCHAR(msg, str);
    std::wcerr << msg << std::flush;
#else
    LOG4CXX_ENCODE_CHAR(msg, str);
    std::cerr << msg << std::flush;
#endif
}

NEW:
====

void SystemErrWriter::write(const LogString& str, Pool& p) {
    LOG4CXX_ENCODE_CHAR(msg, str);
    std::cerr << msg << std::flush;
}

It is then, at least, assured that log4cxx always only writes on
the narrow streams, never on their wide counterparts. The application
which uses log4cxx must then also *always* write to the narrow
streams, if at all.

A more sophisticated solution would be to make it configurable
whether to use the wide or the narrow streams. This could be
a independant configuration, or be based on LOG4CXX_HAS_WCHAR_T.
There are a couple of files which do direct cout/cerr, which would
need to be adjusted.

Comments and thoughts? :-)

Thanks & best Regards,

	Andreas

Andreas Fester | 27 Feb 2006 22:12
Picon
Favicon

Intended commit ...

I indent to commit the attached patch. It adds the
possibility to set system properties (they are
still retrieved from the environment if they do not exist yet
when they are read the first time).
This will allow applications to set any kind of system
property to configure very basic behaviour of log4cxx.

Its primarily a preparation for LOGCXX-126:
it will allow to set a system property like "log4cxx.useWideStreams"
very early in the application to switch to wide streams output
(We need a runtime configuration there; see my comment
at http://issues.apache.org/jira/browse/LOGCXX-126#action_12367428).

Thanks,

	Andreas
Index: include/log4cxx/helpers/properties.h
===================================================================
--- include/log4cxx/helpers/properties.h	(Revision 378958)
+++ include/log4cxx/helpers/properties.h	(Arbeitskopie)
 <at>  <at>  -139,6 +139,15  <at>  <at> 
                         LogString getProperty(const LogString& key) const;

                         /**
+                        Tests if this property list contains the specified key.
+
+                         <at> param   key   possible key.
+                         <at> return  <code>true</code> if this property list contains the 
+                                 specified key, <code>false</code> otherwise.
+                        */
+                        bool containsKey(const LogString& key);
+
+                        /**
                         Returns an enumeration of all the keys in this property list,
                         including distinct keys in the default property list if a key
                         of the same name has not already been found from the main
Index: include/log4cxx/helpers/system.h
===================================================================
--- include/log4cxx/helpers/system.h	(Revision 378958)
+++ include/log4cxx/helpers/system.h	(Arbeitskopie)
 <at>  <at>  -31,6 +31,10  <at>  <at> 
                 */
                 class LOG4CXX_EXPORT System
                 {
+                static Properties* props;
+
+                static void initStatic();
+
                 public:

                 /**
 <at>  <at>  -45,6 +49,15  <at>  <at> 
                 */
                 static LogString getProperty(const LogString& key);

+                /**
+                 Sets the system property indicated by the specified key.
+
+                  <at> param  key   the name of the system property.
+                  <at> param  value the value of the system property.
+                  <at> return  the previous value of the system property or an empty string
+                          if it did not have one.
+                */
+                static LogString setProperty(const LogString& key, const LogString& value);
                 };
         } // namespace helpers
  } //  namespace log4cxx
Index: src/system.cpp
===================================================================
--- src/system.cpp	(Revision 378958)
+++ src/system.cpp	(Arbeitskopie)
 <at>  <at>  -37,65 +37,88  <at>  <at> 
 using namespace log4cxx::helpers;

 
-LogString System::getProperty(const LogString& lkey)
-{
-        if (lkey.empty())
-        {
-                throw IllegalArgumentException("key is empty");
+Properties* System::props;
+
+void System::initStatic() {
+        static bool isInitialized = false;
+        if (isInitialized) {
+          return;
         }
+        isInitialized = true;

-        LogString rv;
-        if (lkey == LOG4CXX_STR("java.io.tmpdir")) {
-          Pool p;
-          const char* dir = NULL;
-          apr_status_t stat = apr_temp_dir_get(&dir, (apr_pool_t*) p.getAPRPool());
-          if (stat == APR_SUCCESS) {
-            Transcoder::decode(dir, strlen(dir), rv);
-          }
-          return rv;
+        // system properties live until the application terminates
+        props = new Properties();
+
+        Pool pool;
+        apr_pool_t* p = (apr_pool_t*) pool.getAPRPool();
+
+        // java.io.tmpdir
+        LogString tempDir;
+        const char* dir = NULL;
+        apr_status_t stat = apr_temp_dir_get(&dir, p);
+        if (stat == APR_SUCCESS) {
+          Transcoder::decode(dir, strlen(dir), tempDir);
         }
+        props->setProperty(LOG4CXX_STR("java.io.tmpdir"), tempDir);

-        if (lkey == LOG4CXX_STR("user.dir")) {
-          Pool p;
-          char* dir = NULL;
-          apr_status_t stat = apr_filepath_get(&dir, APR_FILEPATH_NATIVE,
-              (apr_pool_t*) p.getAPRPool());
-          if (stat == APR_SUCCESS) {
-            Transcoder::decode(dir, strlen(dir), rv);
-          }
-          return rv;
+        // user.dir
+        char* userdir = NULL;
+        LogString userDir;
+        stat = apr_filepath_get(&userdir, APR_FILEPATH_NATIVE, p);
+        if (stat == APR_SUCCESS) {
+          Transcoder::decode(userdir, strlen(userdir), userDir);
         }
+        props->setProperty(LOG4CXX_STR("user.dir"), userDir);
+
+        // user.home
+        // user.name
 #if APR_HAS_USER
-        if (lkey == LOG4CXX_STR("user.home") || lkey == LOG4CXX_STR("user.name")) {
-          Pool pool;
-          apr_uid_t userid;
-          apr_gid_t groupid;
-          apr_pool_t* p = (apr_pool_t*) pool.getAPRPool();
-          apr_status_t stat = apr_uid_current(&userid, &groupid, p);
+        LogString userName;
+        LogString userHome;
+
+        apr_uid_t userid;
+        apr_gid_t groupid;
+        stat = apr_uid_current(&userid, &groupid, p);
+        if (stat == APR_SUCCESS) {
+          char* username = NULL;
+          stat = apr_uid_name_get(&username, userid, p);
           if (stat == APR_SUCCESS) {
-            char* username = NULL;
-            stat = apr_uid_name_get(&username, userid, p);
+            Transcoder::decode(username, strlen(username), userName);
+
+            char* dirname = NULL;
+            stat = apr_uid_homepath_get(&dirname, username, p);
             if (stat == APR_SUCCESS) {
-              if (lkey == LOG4CXX_STR("user.name")) {
-                Transcoder::decode(username, strlen(username), rv);
-              } else {
-                char* dirname = NULL;
-                stat = apr_uid_homepath_get(&dirname, username, p);
-                if (stat == APR_SUCCESS) {
-                  Transcoder::decode(dirname, strlen(dirname), rv);
-                }
-              }
+              Transcoder::decode(dirname, strlen(dirname), userHome);
             }
           }
-          return rv;
         }
+
+        props->setProperty(LOG4CXX_STR("user.home"), userHome);
+        props->setProperty(LOG4CXX_STR("user.name"), userName);
 #endif
+}

-        LOG4CXX_ENCODE_CHAR(key, lkey);
-        const char * value = ::getenv(key.c_str());
-        if (value != 0) {
-                Transcoder::decode(value, rv);
+
+LogString System::getProperty(const LogString& lkey)
+{
+        initStatic();
+
+        // if the key is not yet in the properties, then add it
+        if (!props->containsKey(lkey)) {
+          LogString envVar;
+          LOG4CXX_ENCODE_CHAR(key, lkey);
+          const char * value = ::getenv(key.c_str());
+          if (value != 0) {
+            Transcoder::decode(value, envVar);
+          }
+          props->setProperty(lkey, envVar);
         }
-        return rv;
+
+        return props->getProperty(lkey);
 }

+
+LogString System::setProperty(const LogString& key, const LogString& value) {
+        initStatic();
+        return props->setProperty(key, value);
+}
Index: src/properties.cpp
===================================================================
--- src/properties.cpp	(Revision 378958)
+++ src/properties.cpp	(Arbeitskopie)
 <at>  <at>  -318,6 +318,12  <at>  <at> 
         return oldValue;
 }

+bool Properties::containsKey(const LogString& key)
+{
+        std::map<LogString, LogString>::const_iterator it = properties.find(key);
+        return (it != properties.end());
+}
+
 LogString Properties::getProperty(const LogString& key) const
 {
         std::map<LogString, LogString>::const_iterator it = properties.find(key);
Index: tests/src/helpers/systemtestcase.cpp
===================================================================
--- tests/src/helpers/systemtestcase.cpp	(Revision 0)
+++ tests/src/helpers/systemtestcase.cpp	(Revision 0)
 <at>  <at>  -0,0 +1,59  <at>  <at> 
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <log4cxx/helpers/system.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <log4cxx/helpers/loglog.h>
+
+using namespace log4cxx;
+using namespace log4cxx::helpers;
+
+/**
+   Unit tests for the System class
+    <at> author Andreas Fester
+    <at> since 0.9.8
+*/
+class SystemTestCase : public CppUnit::TestFixture {
+
+    CPPUNIT_TEST_SUITE( SystemTestCase );
+      CPPUNIT_TEST( testSystemProperties );
+    CPPUNIT_TEST_SUITE_END();
+
+public:
+  /**
+   * Check that System::getProperty() returns some values
+   */
+  void testSystemProperties() {
+    // java.io.tmpdir and user.dir always exist
+    LogString tmpDir = System::getProperty("java.io.tmpdir");
+    CPPUNIT_ASSERT(!tmpDir.empty());
+
+    LogString usrDir = System::getProperty("user.dir");
+    CPPUNIT_ASSERT(!usrDir.empty());
+
+    // check propagation of environment variables
+    LogString totoValue = System::getProperty("TOTO");
+    CPPUNIT_ASSERT(totoValue == "wonderful");
+
+    // check unknown property
+    LogString unknown = System::getProperty("unknown.property");
+    CPPUNIT_ASSERT(unknown.empty());
+  }
+};
+
+
+CPPUNIT_TEST_SUITE_REGISTRATION(SystemTestCase);
Index: tests/src/Makefile.am
===================================================================
--- tests/src/Makefile.am	(Revision 378958)
+++ tests/src/Makefile.am	(Arbeitskopie)
 <at>  <at>  -37,6 +37,7  <at>  <at> 
         helpers/relativetimedateformattestcase.cpp \
         helpers/stringtokenizertestcase.cpp \
         helpers/stringhelpertestcase.cpp \
+        helpers/systemtestcase.cpp \
         helpers/timezonetestcase.cpp \
         helpers/transcodertestcase.cpp \
         helpers/unicodehelpertestcase.cpp 
Curt Arnold | 28 Feb 2006 01:18
Picon
Favicon

Re: Intended commit ...


On Feb 27, 2006, at 3:12 PM, Andreas Fester wrote:

> I indent to commit the attached patch. It adds the
> possibility to set system properties (they are
> still retrieved from the environment if they do not exist yet
> when they are read the first time).
> This will allow applications to set any kind of system
> property to configure very basic behaviour of log4cxx.
>
> Its primarily a preparation for LOGCXX-126:
> it will allow to set a system property like "log4cxx.useWideStreams"
> very early in the application to switch to wide streams output
> (We need a runtime configuration there; see my comment
> at http://issues.apache.org/jira/browse/LOGCXX-126#action_12367428).
>

I'll add comments back to that bug report.  I'm scrambling on this,  
but it looks like appropriate use of fwide() could ensure that  
ConsoleAppender uses the correct mode if somebody else already wrote  
to stdout before the first call to ConsoleAppender.  Using a system  
property to control this is down on my list of ways to approach the  
problem, I'd rather had configuration parameters or a distinct  
WideConsoleAppender before depending on a system property.

Comments on the proposed patch:

> Thanks,
>
> 	Andreas
> Index: include/log4cxx/helpers/properties.h
> ===================================================================
> --- include/log4cxx/helpers/properties.h	(Revision 378958)
> +++ include/log4cxx/helpers/properties.h	(Arbeitskopie)
>  <at>  <at>  -139,6 +139,15  <at>  <at> 
>                          LogString getProperty(const LogString&  
> key) const;
>
>                          /**
> +                        Tests if this property list contains the  
> specified key.
> +
> +                         <at> param   key   possible key.
> +                         <at> return  <code>true</code> if this  
> property list contains the
> +                                 specified key, <code>false</code>  
> otherwise.
> +                        */
> +                        bool containsKey(const LogString& key);
> +
> +                        /**
>                          Returns an enumeration of all the keys in  
> this property list,
>                          including distinct keys in the default  
> property list if a key
>                          of the same name has not already been  
> found from the main
>

Looks okay, follows the JDK's Properties.containsKey()

> Index: include/log4cxx/helpers/system.h
> ===================================================================
> --- include/log4cxx/helpers/system.h	(Revision 378958)
> +++ include/log4cxx/helpers/system.h	(Arbeitskopie)
>  <at>  <at>  -31,6 +31,10  <at>  <at> 
>                  */
>                  class LOG4CXX_EXPORT System
>                  {
> +                static Properties* props;
> +
> +                static void initStatic();
> +
>                  public:
>
>                  /**
>  <at>  <at>  -45,6 +49,15  <at>  <at> 
>                  */
>                  static LogString getProperty(const LogString& key);
>
> +                /**
> +                 Sets the system property indicated by the  
> specified key.
> +
> +                  <at> param  key   the name of the system property.
> +                  <at> param  value the value of the system property.
> +                  <at> return  the previous value of the system  
> property or an empty string
> +                          if it did not have one.
> +                */
> +                static LogString setProperty(const LogString& key,  
> const LogString& value);
>                  };
>          } // namespace helpers
>   } //  namespace log4cxx

Been trying to avoid non-local static variables.  In this case, I  
doubt that props is ever reclaimed.  I'd prefer something like:

static PropertiesPtr getProperties() {
      static PropertiesPtr properties(new Properties());
      return properties;
}

> Index: src/system.cpp
> ===================================================================
> --- src/system.cpp	(Revision 378958)
> +++ src/system.cpp	(Arbeitskopie)
>  <at>  <at>  -37,65 +37,88  <at>  <at> 
>  using namespace log4cxx::helpers;
>
>
> -LogString System::getProperty(const LogString& lkey)
> -{
> -        if (lkey.empty())
> -        {
> -                throw IllegalArgumentException("key is empty");
> +Properties* System::props;
> +
> +void System::initStatic() {
> +        static bool isInitialized = false;
> +        if (isInitialized) {
> +          return;
>          }
> +        isInitialized = true;
>
> -        LogString rv;
> -        if (lkey == LOG4CXX_STR("java.io.tmpdir")) {
> -          Pool p;
> -          const char* dir = NULL;
> -          apr_status_t stat = apr_temp_dir_get(&dir, (apr_pool_t*)  
> p.getAPRPool());
> -          if (stat == APR_SUCCESS) {
> -            Transcoder::decode(dir, strlen(dir), rv);
> -          }
> -          return rv;
> +        // system properties live until the application terminates
> +        props = new Properties();
> +
> +        Pool pool;
> +        apr_pool_t* p = (apr_pool_t*) pool.getAPRPool();
> +
> +        // java.io.tmpdir
> +        LogString tempDir;
> +        const char* dir = NULL;
> +        apr_status_t stat = apr_temp_dir_get(&dir, p);
> +        if (stat == APR_SUCCESS) {
> +          Transcoder::decode(dir, strlen(dir), tempDir);
>          }
> +        props->setProperty(LOG4CXX_STR("java.io.tmpdir"), tempDir);
>
> -        if (lkey == LOG4CXX_STR("user.dir")) {
> -          Pool p;
> -          char* dir = NULL;
> -          apr_status_t stat = apr_filepath_get(&dir,  
> APR_FILEPATH_NATIVE,
> -              (apr_pool_t*) p.getAPRPool());
> -          if (stat == APR_SUCCESS) {
> -            Transcoder::decode(dir, strlen(dir), rv);
> -          }
> -          return rv;
> +        // user.dir
> +        char* userdir = NULL;
> +        LogString userDir;
> +        stat = apr_filepath_get(&userdir, APR_FILEPATH_NATIVE, p);
> +        if (stat == APR_SUCCESS) {
> +          Transcoder::decode(userdir, strlen(userdir), userDir);
>          }
> +        props->setProperty(LOG4CXX_STR("user.dir"), userDir);
> +
> +        // user.home
> +        // user.name
>  #if APR_HAS_USER
> -        if (lkey == LOG4CXX_STR("user.home") || lkey == LOG4CXX_STR 
> ("user.name")) {
> -          Pool pool;
> -          apr_uid_t userid;
> -          apr_gid_t groupid;
> -          apr_pool_t* p = (apr_pool_t*) pool.getAPRPool();
> -          apr_status_t stat = apr_uid_current(&userid, &groupid, p);
> +        LogString userName;
> +        LogString userHome;
> +
> +        apr_uid_t userid;
> +        apr_gid_t groupid;
> +        stat = apr_uid_current(&userid, &groupid, p);
> +        if (stat == APR_SUCCESS) {
> +          char* username = NULL;
> +          stat = apr_uid_name_get(&username, userid, p);
>            if (stat == APR_SUCCESS) {
> -            char* username = NULL;
> -            stat = apr_uid_name_get(&username, userid, p);
> +            Transcoder::decode(username, strlen(username), userName);
> +
> +            char* dirname = NULL;
> +            stat = apr_uid_homepath_get(&dirname, username, p);
>              if (stat == APR_SUCCESS) {
> -              if (lkey == LOG4CXX_STR("user.name")) {
> -                Transcoder::decode(username, strlen(username), rv);
> -              } else {
> -                char* dirname = NULL;
> -                stat = apr_uid_homepath_get(&dirname, username, p);
> -                if (stat == APR_SUCCESS) {
> -                  Transcoder::decode(dirname, strlen(dirname), rv);
> -                }
> -              }
> +              Transcoder::decode(dirname, strlen(dirname), userHome);
>              }
>            }
> -          return rv;
>          }
> +
> +        props->setProperty(LOG4CXX_STR("user.home"), userHome);
> +        props->setProperty(LOG4CXX_STR("user.name"), userName);
>  #endif
> +}
>
> -        LOG4CXX_ENCODE_CHAR(key, lkey);
> -        const char * value = ::getenv(key.c_str());
> -        if (value != 0) {
> -                Transcoder::decode(value, rv);
> +
> +LogString System::getProperty(const LogString& lkey)
> +{
> +        initStatic();
> +
> +        // if the key is not yet in the properties, then add it
> +        if (!props->containsKey(lkey)) {
> +          LogString envVar;
> +          LOG4CXX_ENCODE_CHAR(key, lkey);
> +          const char * value = ::getenv(key.c_str());
> +          if (value != 0) {
> +            Transcoder::decode(value, envVar);
> +          }
> +          props->setProperty(lkey, envVar);
>          }
> -        return rv;
> +
> +        return props->getProperty(lkey);
>  }
>
> +
> +LogString System::setProperty(const LogString& key, const  
> LogString& value) {
> +        initStatic();
> +        return props->setProperty(key, value);
> +}

I could be misinterpreting this code since I'm looking at the patch  
itself and not the patched code.  It looks like your patch would  
likely cache the values of java.io.tmpdir, user.home, environment at  
initialization and would not reflect changes that occur after that time.

> Index: src/properties.cpp
> ===================================================================
> --- src/properties.cpp	(Revision 378958)
> +++ src/properties.cpp	(Arbeitskopie)
>  <at>  <at>  -318,6 +318,12  <at>  <at> 
>          return oldValue;
>  }
>
> +bool Properties::containsKey(const LogString& key)
> +{
> +        std::map<LogString, LogString>::const_iterator it =  
> properties.find(key);
> +        return (it != properties.end());
> +}
> +
>  LogString Properties::getProperty(const LogString& key) const
>  {
>          std::map<LogString, LogString>::const_iterator it =  
> properties.find(key);

Okay.

> Index: tests/src/helpers/systemtestcase.cpp
> ===================================================================
> --- tests/src/helpers/systemtestcase.cpp	(Revision 0)
> +++ tests/src/helpers/systemtestcase.cpp	(Revision 0)
>  <at>  <at>  -0,0 +1,59  <at>  <at> 
> +/*
> + * Copyright 2005 The Apache Software Foundation.
> + *
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at
> + *
> + *      http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,  
> software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or  
> implied.
> + * See the License for the specific language governing permissions  
> and
> + * limitations under the License.
> + */
> +
> +#include <log4cxx/helpers/system.h>
> +#include <cppunit/extensions/HelperMacros.h>
> +
> +#include <log4cxx/helpers/loglog.h>
> +
> +using namespace log4cxx;
> +using namespace log4cxx::helpers;
> +
> +/**
> +   Unit tests for the System class
> +    <at> author Andreas Fester
> +    <at> since 0.9.8
> +*/
> +class SystemTestCase : public CppUnit::TestFixture {
> +
> +    CPPUNIT_TEST_SUITE( SystemTestCase );
> +      CPPUNIT_TEST( testSystemProperties );
> +    CPPUNIT_TEST_SUITE_END();
> +
> +public:
> +  /**
> +   * Check that System::getProperty() returns some values
> +   */
> +  void testSystemProperties() {
> +    // java.io.tmpdir and user.dir always exist
> +    LogString tmpDir = System::getProperty("java.io.tmpdir");
> +    CPPUNIT_ASSERT(!tmpDir.empty());
> +
> +    LogString usrDir = System::getProperty("user.dir");
> +    CPPUNIT_ASSERT(!usrDir.empty());
> +
> +    // check propagation of environment variables
> +    LogString totoValue = System::getProperty("TOTO");
> +    CPPUNIT_ASSERT(totoValue == "wonderful");
> +
> +    // check unknown property
> +    LogString unknown = System::getProperty("unknown.property");
> +    CPPUNIT_ASSERT(unknown.empty());
> +  }
> +};
> +

Okay.

> +
> +CPPUNIT_TEST_SUITE_REGISTRATION(SystemTestCase);
> Index: tests/src/Makefile.am
> ===================================================================
> --- tests/src/Makefile.am	(Revision 378958)
> +++ tests/src/Makefile.am	(Arbeitskopie)
>  <at>  <at>  -37,6 +37,7  <at>  <at> 
>          helpers/relativetimedateformattestcase.cpp \
>          helpers/stringtokenizertestcase.cpp \
>          helpers/stringhelpertestcase.cpp \
> +        helpers/systemtestcase.cpp \
>          helpers/timezonetestcase.cpp \
>          helpers/transcodertestcase.cpp \
>          helpers/unicodehelpertestcase.cpp

Okay.

Andreas Fester | 28 Feb 2006 08:15
Picon
Favicon

Re: Intended commit ...

Curt Arnold wrote:
> On Feb 27, 2006, at 3:12 PM, Andreas Fester wrote:
>> I indent to commit the attached patch. It adds the
[...]
>> Its primarily a preparation for LOGCXX-126:
>> it will allow to set a system property like "log4cxx.useWideStreams"
>> very early in the application to switch to wide streams output
>> (We need a runtime configuration there; see my comment
>> at http://issues.apache.org/jira/browse/LOGCXX-126#action_12367428).
>>
> 
> I'll add comments back to that bug report.  I'm scrambling on this,  but
same to me; seems like a nightmare ;-)

> it looks like appropriate use of fwide() could ensure that 
I read about that some time ago, but IIRC there were also some
portability issues. Need to have a look at it...

> ConsoleAppender uses the correct mode if somebody else already wrote  to
> stdout before the first call to ConsoleAppender.  Using a system 
> property to control this is down on my list of ways to approach the 
> problem, I'd rather had configuration parameters or a distinct 
> WideConsoleAppender before depending on a system property.
I thought about that, but there is also the internal LogLog logger
which can not be configured through a ConsoleAppender parameter.
Thats why I took the "global" approach, to make sure that *all* output
is always printed through the same stream.

>> Index: include/log4cxx/helpers/properties.h
>> ===================================================================
[...]
> Looks okay, follows the JDK's Properties.containsKey()
Ok.

>> Index: include/log4cxx/helpers/system.h
>> ===================================================================
[...]
> Been trying to avoid non-local static variables.  In this case, I  doubt
> that props is ever reclaimed.  I'd prefer something like:
> 
> static PropertiesPtr getProperties() {
>      static PropertiesPtr properties(new Properties());
>      return properties;
> }
Agree.

>> Index: src/system.cpp
>> ===================================================================
[...]
> I could be misinterpreting this code since I'm looking at the patch 
> itself and not the patched code.  It looks like your patch would  likely
> cache the values of java.io.tmpdir, user.home, environment at 
Thats true. The values are written once into the appropriate system
properties.

> initialization and would not reflect changes that occur after that time.
They can be changed by the application by calling System::setProperty().
I dont know the internal implementation of the apr_()-Functions,
but is it possible that their return values (user name, temporary directory,
...) change at runtime?

Thanks,

	Andreas

Curt Arnold | 28 Feb 2006 08:35
Picon

Re: Intended commit ...


>
>> initialization and would not reflect changes that occur after that  
>> time.
> They can be changed by the application by calling  
> System::setProperty().
> I dont know the internal implementation of the apr_()-Functions,
> but is it possible that their return values (user name, temporary  
> directory,
> ...) change at runtime?
>
>

"user.dir", the current user directory, might be modified by chdir.   
Any of the environment variables could be changed by putenv.  I think  
it would be better to keep them retrieved on-demand if there is not a  
match in the map of property values. 

Andreas Fester | 28 Feb 2006 09:59
Picon
Favicon

Re: Intended commit ...

Curt Arnold wrote:
> 
>>
>>> initialization and would not reflect changes that occur after that 
>>> time.
>>
>> They can be changed by the application by calling  System::setProperty().
>> I dont know the internal implementation of the apr_()-Functions,
>> but is it possible that their return values (user name, temporary 
>> directory,
>> ...) change at runtime?
>>
>>
> 
> "user.dir", the current user directory, might be modified by chdir.  
> Any of the environment variables could be changed by putenv.  I think 
> it would be better to keep them retrieved on-demand if there is not a 
> match in the map of property values.

I was thinking more of Java, where no putenv exists :-) and properties
like user.dir are usually readonly http://www.devx.com/tips/Tip/13804
Anyway, its no problem to change it to still read the current values,
as it was before ...


Gmane