summaryrefslogtreecommitdiff
path: root/sc/inc/formulalogger.hxx
blob: 9e8da1f681b08f233feb54f79eb7dee5f41860b3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#pragma once

#include <rtl/ustring.hxx>

#include <memory>
#include <string_view>
#include <vector>

#include <config_options_calc.h>

class ScFormulaCell;
class ScDocument;
class ScAddress;
struct ScFormulaCellGroup;

namespace formula {

class FormulaToken;
struct VectorRefArray;

}

namespace osl { class File; }

namespace sc {

#if ENABLE_FORMULA_LOGGER

/**
 * Outputs formula calculation log outputs to specified file.
 */
class FormulaLogger
{
    std::unique_ptr<osl::File> mpLogFile;

    sal_Int32 mnNestLevel = 0;
    const ScFormulaCellGroup* mpLastGroup = nullptr;

    void writeAscii( const char* s );
    void writeAscii( const char* s, size_t n );
    void write( std::u16string_view ou );
    void write( sal_Int32 n );

    void sync();

    void writeNestLevel();

public:

    static FormulaLogger& get();

    /**
     * This class is only moveable.
     */
    class GroupScope
    {
        friend class FormulaLogger;

        struct Impl;
        std::unique_ptr<Impl> mpImpl;

    public:
        GroupScope() = delete;
        GroupScope( const GroupScope& ) = delete;
        GroupScope& operator= ( const GroupScope& ) = delete;

    private:
        GroupScope(
            FormulaLogger& rLogger, const OUString& rPrefix,
            const ScDocument& rDoc, const ScFormulaCell& rCell,
            bool bOutputEnabled );

    public:
        GroupScope(GroupScope&& r) noexcept;
        ~GroupScope();

        /**
         * Add an arbitrary message to dump to the log.
         */
        void addMessage( const OUString& rMsg );

        /**
         * Add to the log a vector reference information for a single
         * reference.
         */
        void addRefMessage(
            const ScAddress& rCellPos, const ScAddress& rRefPos, size_t nLen,
            const formula::VectorRefArray& rArray );

        /**
         * Add to the log a vector reference information for a range
         * reference.
         */
        void addRefMessage(
            const ScAddress& rCellPos, const ScAddress& rRefPos, size_t nLen,
            const std::vector<formula::VectorRefArray>& rArrays );

        /**
         * Add to the log a single cell reference information.
         */
        void addRefMessage(
            const ScAddress& rCellPos, const ScAddress& rRefPos,
            const formula::FormulaToken& rToken );

        void addGroupSizeThresholdMessage( const ScFormulaCell& rCell );

        /**
         * Call this when the group calculation has finished successfully.
         */
        void setCalcComplete();
    };

    FormulaLogger( const FormulaLogger& ) = delete;
    FormulaLogger& operator= ( const FormulaLogger& ) = delete;

    FormulaLogger();
    ~FormulaLogger();

    GroupScope enterGroup( const ScDocument& rDoc, const ScFormulaCell& rCell );
};

#else

/**
 * Dummy class with all empty inline methods.
 */
class FormulaLogger
{
public:

    static FormulaLogger get()
    {
        return FormulaLogger();
    }

    class GroupScope
    {
    public:
        void addMessage( [[maybe_unused]] const OUString& /*rMsg*/ ) { (void) this; /* loplugin:staticmethods */ }

        void addRefMessage(
            const ScAddress& /*rCellPos*/, const ScAddress& /*rRefPos*/, size_t /*nLen*/,
            const formula::VectorRefArray& /*rArray*/ )
        {
            (void) this; /* loplugin:staticmethods */
        }

        void addRefMessage(
            const ScAddress& /*rCellPos*/, const ScAddress& /*rRefPos*/, size_t /*nLen*/,
            const std::vector<formula::VectorRefArray>& /*rArrays*/ )
        {
            (void) this; /* loplugin:staticmethods */
        }

        void addRefMessage(
            const ScAddress& /*rCellPos*/, const ScAddress& /*rRefPos*/,
            const formula::FormulaToken& /*rToken*/ )
        {
            (void) this; /* loplugin:staticmethods */
        }

        void addGroupSizeThresholdMessage( const ScFormulaCell& /*rCell*/ )
        {
            (void) this; /* loplugin:staticmethods */
        }

        void setCalcComplete() { (void) this; /* loplugin:staticmethods */ }
    };

    GroupScope enterGroup( const ScDocument& /*rDoc*/, const ScFormulaCell& /*rCell*/ )
    {
        (void) this; /* loplugin:staticmethods */
        return GroupScope();
    }
};

#endif // ENABLE_FORMULA_LOGGER

}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */