1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * Version: MPL 1.1 / GPLv3+ / LGPLv3+
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License or as specified alternatively below. You may obtain a copy of
8 * the License at http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * Major Contributor(s):
16 * Copyright (C) 2011 Red Hat, Inc., Stephan Bergmann <sbergman@redhat.com>
19 * All Rights Reserved.
21 * For minor contributions see the git repository.
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
25 * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
26 * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
27 * instead of those above.
30 #include "sal/config.h"
40 #include <stdio.h> // vsnprintf
42 #include "osl/thread.hxx"
43 #include "rtl/string.h"
44 #include "sal/detail/log.h"
45 #include "sal/log.hxx"
46 #include "sal/types.h"
48 #include "logformat.hxx"
52 #define OSL_DETAIL_GETPID _getpid()
55 #define OSL_DETAIL_GETPID getpid()
58 // Avoid the use of other sal code in this file as much as possible, so that
59 // this code can be called from other sal code without causing endless
65 char const * string1
, std::size_t length1
, char const * string2
,
68 return length1
== length2
&& std::memcmp(string1
, string2
, length1
) == 0;
71 char const * toString(sal_detail_LogLevel level
) {
74 assert(false); // this cannot happen
76 case SAL_DETAIL_LOG_LEVEL_INFO
:
78 case SAL_DETAIL_LOG_LEVEL_WARN
:
80 case SAL_DETAIL_LOG_LEVEL_DEBUG
:
85 bool report(sal_detail_LogLevel level
, char const * area
) {
86 if (level
== SAL_DETAIL_LOG_LEVEL_DEBUG
)
89 char const * env
= std::getenv("SAL_LOG");
93 std::size_t areaLen
= std::strlen(area
);
94 enum Sense
{ POSITIVE
= 0, NEGATIVE
= 1 };
95 std::size_t senseLen
[2] = { 0, 1 };
96 // initial senseLen[POSITIVE] < senseLen[NEGATIVE], so that if there are
97 // no matching switches at all, the result will be negative (and
98 // initializing with 1 is safe as the length of a valid switch, even
99 // without the "+"/"-" prefix, will always be > 1)
100 for (char const * p
= env
;;) {
104 return senseLen
[POSITIVE
] >= senseLen
[NEGATIVE
];
105 // if a specific item is both postiive and negative
106 // (senseLen[POSITIVE] == senseLen[NEGATIVE]), default to
115 return true; // upon an illegal SAL_LOG value, enable everything
118 while (*p1
!= '.' && *p1
!= '+' && *p1
!= '-' && *p1
!= '\0') {
122 if (equalStrings(p
, p1
- p
, RTL_CONSTASCII_STRINGPARAM("INFO"))) {
123 match
= level
== SAL_DETAIL_LOG_LEVEL_INFO
;
124 } else if (equalStrings(p
, p1
- p
, RTL_CONSTASCII_STRINGPARAM("WARN")))
126 match
= level
== SAL_DETAIL_LOG_LEVEL_WARN
;
129 // upon an illegal SAL_LOG value, everything is considered
132 char const * p2
= p1
;
133 while (*p2
!= '+' && *p2
!= '-' && *p2
!= '\0') {
139 std::size_t n
= p2
- p1
;
140 if ((n
== areaLen
&& equalStrings(p1
, n
, area
, areaLen
))
141 || (n
< areaLen
&& area
[n
] == '.'
142 && equalStrings(p1
, n
, area
, n
)))
144 senseLen
[sense
] = p2
- p
;
147 senseLen
[sense
] = p1
- p
;
155 sal_detail_LogLevel level
, char const * area
, char const * where
,
156 char const * message
)
158 std::ostringstream s
;
159 if (level
== SAL_DETAIL_LOG_LEVEL_DEBUG
) {
160 s
<< toString(level
) << ':' << /*no where*/' ' << message
<< '\n';
162 s
<< toString(level
) << ':' << area
<< ':' << OSL_DETAIL_GETPID
<< ':'
163 << osl::Thread::getCurrentIdentifier() << ':' << where
<< message
166 std::fputs(s
.str().c_str(), stderr
);
171 SAL_DLLPUBLIC
void sal_detail_log(
172 sal_detail_LogLevel level
, char const * area
, char const * where
,
173 char const * message
)
175 if (report(level
, area
)) {
176 log(level
, area
, where
, message
);
180 SAL_DLLPUBLIC
void sal_detail_logFormat(
181 sal_detail_LogLevel level
, char const * area
, char const * where
,
182 char const * format
, ...)
184 if (report(level
, area
)) {
186 va_start(args
, format
);
187 osl::detail::logFormat(level
, area
, where
, format
, args
);
192 void osl::detail::logFormat(
193 sal_detail_LogLevel level
, char const * area
, char const * where
,
194 char const * format
, std::va_list arguments
)
197 int const len
= sizeof buf
- RTL_CONSTASCII_LENGTH("...");
198 int n
= vsnprintf(buf
, len
, format
, arguments
);
200 std::strcpy(buf
, "???");
201 } else if (n
>= len
) {
202 std::strcpy(buf
+ len
- 1, "...");
204 log(level
, area
, where
, buf
);
207 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */