Coverage Report

Created: 2025-12-31 10:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/include/comphelper/errcode.hxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
#pragma once
20
21
#include <config_options.h>
22
#include <rtl/ustring.hxx>
23
#include <comphelper/comphelperdllapi.h>
24
#include <climits>
25
#include <ostream>
26
#include <o3tl/typed_flags_set.hxx>
27
#include <optional>
28
29
#if defined(DBG_UTIL)
30
#include <o3tl/source_location.hxx>
31
#ifdef LIBO_USE_SOURCE_LOCATION
32
// LIBO_USE_SOURCE_LOCATION may be defined without DBG_UTIL, so a separate define is needed
33
#define LIBO_ERRMSG_USE_SOURCE_LOCATION
34
#endif
35
#endif
36
37
/*
38
39
01234567012345670123456701234567
40
||   ||           ||   ||      |
41
Warning           ||   ||      |
42
 |   ||           ||   ||      |
43
 Unused           ||   ||      |
44
      |           ||   ||      |
45
      Subsystemarea|   ||      |
46
                   |   ||      |
47
                   |   ||      |
48
                   |   ||      |
49
                   Class|      |
50
                        |      |
51
                        |      |
52
                        |      |
53
                        Code
54
*/
55
56
1.14G
#define ERRCODE_ERROR_MASK               0x3fffffffUL
57
1.14G
#define ERRCODE_WARNING_MASK             0x80000000UL
58
59
794M
#define ERRCODE_CLASS_SHIFT              8
60
794M
#define ERRCODE_AREA_SHIFT               13
61
#define ERRCODE_DYNAMIC_SHIFT            26
62
63
#define ERRCODE_CLASS_MASK               (31UL << ERRCODE_CLASS_SHIFT)
64
65
enum class ErrCodeArea;
66
enum class ErrCodeClass;
67
68
enum class WarningFlag { Yes };
69
70
class SAL_WARN_UNUSED ErrCode final
71
{
72
public:
73
    explicit constexpr ErrCode(WarningFlag, ErrCodeArea nArea, ErrCodeClass nClass, sal_uInt16 nCode)
74
1.70k
        : m_value(ERRCODE_WARNING_MASK | (sal_uInt32(nArea) << ERRCODE_AREA_SHIFT) | (sal_uInt32(nClass) << ERRCODE_CLASS_SHIFT) | nCode)
75
1.70k
    {
76
1.70k
        assert(nCode <= 0xff && "code out of range");
77
1.70k
    }
78
    explicit constexpr ErrCode(ErrCodeArea nArea, ErrCodeClass nClass, sal_uInt16 nCode)
79
794M
        : m_value((sal_uInt32(nArea) << ERRCODE_AREA_SHIFT) | (sal_uInt32(nClass) << ERRCODE_CLASS_SHIFT) | nCode)
80
794M
    {
81
794M
        assert(nCode <= 0xff && "code out of range");
82
794M
    }
83
    explicit constexpr ErrCode(ErrCodeArea nArea, sal_uInt16 nClassAndCode)
84
9.39k
        : m_value((sal_uInt32(nArea) << ERRCODE_AREA_SHIFT) | nClassAndCode) {}
85
    explicit constexpr ErrCode(sal_uInt32 nValue)
86
2.57G
        : m_value(nValue) {}
87
    constexpr ErrCode()
88
11.5M
        : m_value(0) {}
89
90
89.0k
    explicit operator sal_uInt32() const { return m_value; }
91
230M
    explicit operator bool() const { return m_value != 0; }
92
93
    auto operator<=>(ErrCode const & other) const = default;
94
95
    /** convert to ERRCODE_NONE if it's a warning, else return the error */
96
1.14G
    ErrCode IgnoreWarning() const {
97
1.14G
        return (m_value & ERRCODE_WARNING_MASK)
98
1.14G
              ? ErrCode(0)
99
1.14G
              : ErrCode(static_cast<sal_uInt32>(m_value & ERRCODE_ERROR_MASK));
100
1.14G
    }
101
102
3.70M
    bool IsWarning() const {
103
3.70M
        return m_value & ERRCODE_WARNING_MASK;
104
3.70M
    }
105
106
0
    ErrCode MakeWarning() const {
107
0
        return ErrCode(m_value | ERRCODE_WARNING_MASK);
108
0
    }
Unexecuted instantiation: ErrCode::MakeWarning() const
Unexecuted instantiation: ErrCode::MakeWarning() const
109
110
38.7k
    bool IsError() const {
111
38.7k
        return m_value && !IsWarning();
112
38.7k
    }
113
114
0
    constexpr ErrCode StripWarning() const {
115
0
        return ErrCode(m_value & ~ERRCODE_WARNING_MASK);
116
0
    }
Unexecuted instantiation: ErrCode::StripWarning() const
Unexecuted instantiation: ErrCode::StripWarning() const
117
118
0
    constexpr ErrCodeArea GetArea() const {
119
0
        return static_cast<ErrCodeArea>((m_value >> ERRCODE_AREA_SHIFT) & 0x01fff);
120
0
    }
121
122
0
    constexpr ErrCodeClass GetClass() const {
123
0
        return static_cast<ErrCodeClass>((m_value >> ERRCODE_CLASS_SHIFT) & 0x1f);
124
0
    }
125
126
0
    constexpr sal_uInt8 GetCode() const {
127
0
        return static_cast<sal_uInt8>(m_value & 0xff);
128
0
    }
129
130
0
    OUString toHexString() const {
131
0
        return "0x" + OUString::number(m_value, 16);
132
0
    }
133
134
    /// Return a string suitable for debug output, the same as the operator<< function
135
    COMPHELPER_DLLPUBLIC OUString toString() const;
136
137
    template <typename... Args> bool anyOf(Args... args) const
138
    {
139
        static_assert(sizeof...(args) > 0);
140
        return (... || (*this == args));
141
    }
142
143
private:
144
    sal_uInt32 m_value;
145
};
146
147
COMPHELPER_DLLPUBLIC std::ostream& operator<<(std::ostream& os, const ErrCode& err);
148
149
enum class DialogMask
150
{
151
    NONE                    = 0x0000,
152
    ButtonsOk               = 0x0001,
153
    ButtonsCancel           = 0x0002,
154
    ButtonsRetry            = 0x0004,
155
    ButtonsNo               = 0x0008,
156
    ButtonsYes              = 0x0010,
157
    ButtonsYesNo            = 0x0018,
158
159
    ButtonDefaultsOk        = 0x0100,
160
    ButtonDefaultsCancel    = 0x0200,
161
    ButtonDefaultsYes       = 0x0300,
162
    ButtonDefaultsNo        = 0x0400,
163
164
    MessageError            = 0x1000,
165
    MessageWarning          = 0x2000,
166
    MessageInfo             = 0x3000,
167
168
    MAX                     = USHRT_MAX,
169
};
170
namespace o3tl
171
{
172
    template<> struct typed_flags<DialogMask> : is_typed_flags<DialogMask, 0xffff> {};
173
}
174
175
/** Wrap up an ErrCode and an explanation and the source location where the error was created,
176
    helps with debugging when finding the source of a problem.
177
*/
178
class SAL_WARN_UNUSED ErrCodeMsg
179
{
180
public:
181
0
    ErrCodeMsg() : mnCode(0), mnDialogMask(DialogMask::NONE) {}
182
#ifdef LIBO_ERRMSG_USE_SOURCE_LOCATION
183
    ErrCodeMsg(ErrCode code, const OUString& arg, o3tl::source_location loc = o3tl::source_location::current())
184
        : mnCode(code), maArg1(arg),  mnDialogMask(DialogMask::NONE), moLoc(loc) {}
185
    ErrCodeMsg(ErrCode code, const OUString& arg1, const OUString& arg2, o3tl::source_location loc = o3tl::source_location::current())
186
        : mnCode(code), maArg1(arg1), maArg2(arg2), mnDialogMask(DialogMask::NONE), moLoc(loc) {}
187
    ErrCodeMsg(ErrCode code, o3tl::source_location loc = o3tl::source_location::current())
188
        : mnCode(code), mnDialogMask(DialogMask::NONE), moLoc(loc) {}
189
    ErrCodeMsg(ErrCode code, const OUString& arg, DialogMask mask, o3tl::source_location loc = o3tl::source_location::current())
190
        : mnCode(code), maArg1(arg), mnDialogMask(mask), moLoc(loc) {}
191
    ErrCodeMsg(ErrCode code, const OUString& arg1, const OUString& arg2, DialogMask mask, o3tl::source_location loc = o3tl::source_location::current())
192
        : mnCode(code), maArg1(arg1), maArg2(arg2), mnDialogMask(mask), moLoc(loc) {}
193
#else
194
    ErrCodeMsg(ErrCode code, const OUString& arg)
195
0
        : mnCode(code), maArg1(arg), mnDialogMask(DialogMask::NONE) {}
196
    ErrCodeMsg(ErrCode code, const OUString& arg1, const OUString& arg2)
197
0
        : mnCode(code), maArg1(arg1), maArg2(arg2), mnDialogMask(DialogMask::NONE) {}
198
    ErrCodeMsg(ErrCode code)
199
1.30M
        : mnCode(code), mnDialogMask(DialogMask::NONE) {}
200
    ErrCodeMsg(ErrCode code, const OUString& arg, DialogMask mask)
201
50
        : mnCode(code), maArg1(arg), mnDialogMask(mask) {}
202
    ErrCodeMsg(ErrCode code, const OUString& arg1, const OUString& arg2, DialogMask mask)
203
0
        : mnCode(code), maArg1(arg1), maArg2(arg2), mnDialogMask(mask) {}
204
#endif
205
206
195k
    const ErrCode & GetCode() const { return mnCode; }
207
0
    const OUString & GetArg1() const { return maArg1; }
208
0
    const OUString & GetArg2() const { return maArg2; }
209
0
    DialogMask GetDialogMask() const { return mnDialogMask; }
210
211
#ifdef LIBO_ERRMSG_USE_SOURCE_LOCATION
212
    const std::optional<o3tl::source_location>& GetSourceLocation() const { return moLoc; }
213
#endif
214
215
    /** convert to ERRCODE_NONE if it's a warning, else return the error */
216
324k
    ErrCodeMsg IgnoreWarning() const { return mnCode.IsWarning() ? ErrCodeMsg(ErrCode(0)) : *this; }
217
218
0
    bool IsWarning() const { return mnCode.IsWarning(); }
219
25.2k
    bool IsError() const { return mnCode.IsError(); }
220
919k
    explicit operator bool() const { return bool(mnCode); }
221
0
    bool operator==(const ErrCodeMsg& rOther) const { return mnCode == rOther.mnCode; }
222
0
    bool operator!=(const ErrCodeMsg& rOther) const { return mnCode != rOther.mnCode; }
223
224
    /// Return a string suitable for debug output, the same as the operator<< function
225
    UNLESS_MERGELIBS(COMPHELPER_DLLPUBLIC) OUString toString() const;
226
227
private:
228
    ErrCode mnCode;
229
    OUString maArg1;
230
    OUString maArg2;
231
    DialogMask mnDialogMask;
232
#ifdef LIBO_ERRMSG_USE_SOURCE_LOCATION
233
    std::optional<o3tl::source_location> moLoc;
234
#endif
235
};
236
237
COMPHELPER_DLLPUBLIC std::ostream& operator<<(std::ostream& os, const ErrCodeMsg& err);
238
239
106k
inline bool operator==(const ErrCodeMsg& lhs, ErrCode rhs) { return lhs.GetCode() == rhs; }
240
0
inline bool operator!=(const ErrCodeMsg& lhs, ErrCode rhs) { return lhs.GetCode() != rhs; }
241
0
inline bool operator==(ErrCode lhs, const ErrCodeMsg& rhs) { return lhs == rhs.GetCode(); }
242
0
inline bool operator!=(ErrCode lhs, const ErrCodeMsg& rhs) { return lhs != rhs.GetCode(); }
243
244
enum class ErrCodeArea {
245
    Io                  = 0 ,
246
    Sfx                 = 2 ,
247
    Inet                = 3 ,
248
    Vcl                 = 4 ,
249
    Svx                 = 8 ,
250
    So                  = 9 ,
251
    Sbx                 = 10,
252
    Uui                 = 13,
253
    Sc                  = 32,
254
    Sd                  = 40,
255
    Sw                  = 56,
256
};
257
258
enum class ErrCodeClass {
259
    NONE               =  0,
260
    Abort              =  1,
261
    General            =  2,
262
    NotExists          =  3,
263
    AlreadyExists      =  4,
264
    Access             =  5,
265
    Path               =  6,
266
    Locking            =  7,
267
    Parameter          =  8,
268
    Space              =  9,
269
    NotSupported       = 10,
270
    Read               = 11,
271
    Write              = 12,
272
    Unknown            = 13,
273
    Version            = 14,
274
    Format             = 15,
275
    Create             = 16,
276
    Import             = 17,
277
    Export             = 18,
278
    So                 = 20,
279
    Sbx                = 21,
280
    Runtime            = 22,
281
    Compiler           = 23
282
};
283
284
1.58G
#define ERRCODE_NONE                     ErrCode(0)
285
286
0
#define ERRCODE_IO_MISPLACEDCHAR         ErrCode( ErrCodeArea::Io, ErrCodeClass::Parameter, 1 )
287
108k
#define ERRCODE_IO_NOTEXISTS             ErrCode( ErrCodeArea::Io, ErrCodeClass::NotExists, 2 )
288
0
#define ERRCODE_IO_ALREADYEXISTS         ErrCode( ErrCodeArea::Io, ErrCodeClass::AlreadyExists, 3 )
289
0
#define ERRCODE_IO_NOTADIRECTORY         ErrCode( ErrCodeArea::Io, ErrCodeClass::Parameter, 4 )
290
0
#define ERRCODE_IO_NOTAFILE              ErrCode( ErrCodeArea::Io, ErrCodeClass::Parameter, 5 )
291
0
#define ERRCODE_IO_INVALIDDEVICE         ErrCode( ErrCodeArea::Io, ErrCodeClass::Path, 6 )
292
1.74M
#define ERRCODE_IO_ACCESSDENIED          ErrCode( ErrCodeArea::Io, ErrCodeClass::Access, 7 )
293
8
#define ERRCODE_IO_LOCKVIOLATION         ErrCode( ErrCodeArea::Io, ErrCodeClass::Locking, 8 )
294
4
#define ERRCODE_IO_OUTOFSPACE            ErrCode( ErrCodeArea::Io, ErrCodeClass::Space, 9 )
295
0
#define ERRCODE_IO_ISWILDCARD            ErrCode( ErrCodeArea::Io, ErrCodeClass::Parameter, 11 )
296
0
#define ERRCODE_IO_NOTSUPPORTED          ErrCode( ErrCodeArea::Io, ErrCodeClass::NotSupported, 12 )
297
86.4k
#define ERRCODE_IO_GENERAL               ErrCode( ErrCodeArea::Io, ErrCodeClass::General, 13 )
298
8
#define ERRCODE_IO_TOOMANYOPENFILES      ErrCode( ErrCodeArea::Io, ErrCodeClass::Space, 14 )
299
2.35M
#define ERRCODE_IO_CANTREAD              ErrCode( ErrCodeArea::Io, ErrCodeClass::Read, 15 )
300
48.4k
#define ERRCODE_IO_CANTWRITE             ErrCode( ErrCodeArea::Io, ErrCodeClass::Write, 16 )
301
7
#define ERRCODE_IO_OUTOFMEMORY           ErrCode( ErrCodeArea::Io, ErrCodeClass::Space, 17 )
302
26.6k
#define ERRCODE_IO_CANTSEEK              ErrCode( ErrCodeArea::Io, ErrCodeClass::General, 18 )
303
160
#define ERRCODE_IO_CANTTELL              ErrCode( ErrCodeArea::Io, ErrCodeClass::General, 19 )
304
0
#define ERRCODE_IO_WRONGVERSION          ErrCode( ErrCodeArea::Io, ErrCodeClass::Version, 20 )
305
59.8k
#define ERRCODE_IO_WRONGFORMAT           ErrCode( ErrCodeArea::Io, ErrCodeClass::Format, 21 )
306
0
#define ERRCODE_IO_INVALIDCHAR           ErrCode( ErrCodeArea::Io, ErrCodeClass::Parameter, 22 )
307
0
#define ERRCODE_IO_UNKNOWN               ErrCode( ErrCodeArea::Io, ErrCodeClass::Unknown, 23 )
308
0
#define ERRCODE_IO_INVALIDACCESS         ErrCode( ErrCodeArea::Io, ErrCodeClass::Access, 24 )
309
115k
#define ERRCODE_IO_CANTCREATE            ErrCode( ErrCodeArea::Io, ErrCodeClass::Create, 25 )
310
4
#define ERRCODE_IO_INVALIDPARAMETER      ErrCode( ErrCodeArea::Io, ErrCodeClass::Parameter, 26 )
311
26
#define ERRCODE_IO_ABORT                 ErrCode( ErrCodeArea::Io, ErrCodeClass::Abort, 27 )
312
20
#define ERRCODE_IO_NOTEXISTSPATH         ErrCode( ErrCodeArea::Io, ErrCodeClass::NotExists, 28 )
313
792M
#define ERRCODE_IO_PENDING               ErrCode( ErrCodeArea::Io, ErrCodeClass::NotExists, 29 )
314
0
#define ERRCODE_IO_RECURSIVE             ErrCode( ErrCodeArea::Io, ErrCodeClass::Parameter, 30 )
315
0
#define ERRCODE_IO_NAMETOOLONG           ErrCode( ErrCodeArea::Io, ErrCodeClass::Parameter, 31 )
316
0
#define ERRCODE_IO_INVALIDLENGTH         ErrCode( ErrCodeArea::Io, ErrCodeClass::Parameter, 32 )
317
0
#define ERRCODE_IO_CURRENTDIR            ErrCode( ErrCodeArea::Io, ErrCodeClass::Parameter, 33 )
318
0
#define ERRCODE_IO_NOTSAMEDEVICE         ErrCode( ErrCodeArea::Io, ErrCodeClass::Parameter, 34 )
319
0
#define ERRCODE_IO_DEVICENOTREADY        ErrCode( ErrCodeArea::Io, ErrCodeClass::Read, 35 )
320
0
#define ERRCODE_IO_BADCRC                ErrCode( ErrCodeArea::Io, ErrCodeClass::Read, 36 )
321
0
#define ERRCODE_IO_WRITEPROTECTED        ErrCode( ErrCodeArea::Io, ErrCodeClass::Access, 37 )
322
4.57k
#define ERRCODE_IO_BROKENPACKAGE         ErrCode( ErrCodeArea::Io, ErrCodeClass::Format, 38 )
323
#define ERRCODE_IO_NOTSTORABLEINBINARYFORMAT ErrCode( ErrCodeArea::Io, ErrCodeClass::Format, 39 )
324
0
#define ERRCODE_IO_FILTERDISABLED        ErrCode( ErrCodeArea::Io, ErrCodeClass::Format, 40 )
325
326
// StreamErrorCodes
327
328
86.3k
#define SVSTREAM_GENERALERROR            ERRCODE_IO_GENERAL
329
108k
#define SVSTREAM_FILE_NOT_FOUND          ERRCODE_IO_NOTEXISTS
330
20
#define SVSTREAM_PATH_NOT_FOUND          ERRCODE_IO_NOTEXISTSPATH
331
8
#define SVSTREAM_TOO_MANY_OPEN_FILES     ERRCODE_IO_TOOMANYOPENFILES
332
1.62M
#define SVSTREAM_ACCESS_DENIED           ERRCODE_IO_ACCESSDENIED
333
#define SVSTREAM_SHARING_VIOLATION       ERRCODE_IO_LOCKVIOLATION
334
8
#define SVSTREAM_LOCKING_VIOLATION       ERRCODE_IO_LOCKVIOLATION
335
#define SVSTREAM_SHARE_BUFF_EXCEEDED     ERRCODE_IO_LOCKVIOLATION
336
337
0
#define SVSTREAM_INVALID_ACCESS          ERRCODE_IO_INVALIDACCESS
338
4
#define SVSTREAM_INVALID_HANDLE          ERRCODE_IO_GENERAL
339
127
#define SVSTREAM_CANNOT_MAKE             ERRCODE_IO_CANTCREATE
340
4
#define SVSTREAM_INVALID_PARAMETER       ERRCODE_IO_INVALIDPARAMETER
341
342
2.35M
#define SVSTREAM_READ_ERROR              ERRCODE_IO_CANTREAD
343
7
#define SVSTREAM_WRITE_ERROR             ERRCODE_IO_CANTWRITE
344
11.3k
#define SVSTREAM_SEEK_ERROR              ERRCODE_IO_CANTSEEK
345
346
7
#define SVSTREAM_OUTOFMEMORY             ERRCODE_IO_OUTOFMEMORY
347
348
59.5k
#define SVSTREAM_FILEFORMAT_ERROR        ERRCODE_IO_WRONGFORMAT
349
0
#define SVSTREAM_WRONGVERSION            ERRCODE_IO_WRONGVERSION
350
351
4
#define SVSTREAM_DISK_FULL               ERRCODE_IO_OUTOFSPACE
352
353
0
#define PRINTER_ABORT                    ERRCODE_IO_ABORT
354
0
#define PRINTER_GENERALERROR             ERRCODE_IO_GENERAL
355
356
2
#define ERRCODE_ABORT                    ERRCODE_IO_ABORT
357
358
0
#define ERRCODE_INET_NAME_RESOLVE        ErrCode(ErrCodeArea::Inet, ErrCodeClass::Read,  1)
359
0
#define ERRCODE_INET_CONNECT             ErrCode(ErrCodeArea::Inet, ErrCodeClass::Read,  2)
360
0
#define ERRCODE_INET_READ                ErrCode(ErrCodeArea::Inet, ErrCodeClass::Read,  3)
361
0
#define ERRCODE_INET_WRITE               ErrCode(ErrCodeArea::Inet, ErrCodeClass::Write, 4)
362
0
#define ERRCODE_INET_GENERAL             ErrCode(ErrCodeArea::Inet, ErrCodeClass::Write, 5)
363
0
#define ERRCODE_INET_OFFLINE             ErrCode(ErrCodeArea::Inet, ErrCodeClass::Read,  6)
364
0
#define ERRCODE_INET_CONNECT_MSG         ErrCode(ErrCodeArea::Inet, ErrCodeClass::Read,  7)
365
366
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */