aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/ext_depends/D-YAML/source/dyaml/exception.d
blob: 46d3047b6f47ab97a5edb3913b79c49a0925ab20 (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
//          Copyright Ferdinand Majerech 2011.
// Distributed under the Boost Software License, Version 1.0.
//    (See accompanying file LICENSE_1_0.txt or copy at
//          http://www.boost.org/LICENSE_1_0.txt)

///Exceptions thrown by D:YAML and _exception related code.
module dyaml.exception;


import std.algorithm;
import std.array;
import std.string;
import std.conv;


/// Base class for all exceptions thrown by D:YAML.
class YAMLException : Exception
{
    /// Construct a YAMLException with specified message and position where it was thrown.
    public this(string msg, string file = __FILE__, size_t line = __LINE__)
        @safe pure nothrow
    {
        super(msg, file, line);
    }
}

/// Position in a YAML stream, used for error messages.
struct Mark
{
    package:
        /// File name.
        string name_;
        /// Line number.
        ushort line_;
        /// Column number.
        ushort column_;

    public:
        /// Construct a Mark with specified line and column in the file.
        this(string name, const uint line, const uint column) @safe pure nothrow @nogc
        {
            name_   = name;
            line_   = cast(ushort)min(ushort.max, line);
            // This *will* overflow on extremely wide files but saves CPU time
            // (mark ctor takes ~5% of time)
            column_ = cast(ushort)column;
        }

        /// Get a file name.
        @property string name() @safe pure nothrow @nogc const
        {
            return name_;
        }

        /// Get a line number.
        @property ushort line() @safe pure nothrow @nogc const
        {
            return line_;
        }

        /// Get a column number.
        @property ushort column() @safe pure nothrow @nogc const
        {
            return column_;
        }

        /// Get a string representation of the mark.
        string toString() @safe pure nothrow const
        {
            // Line/column numbers start at zero internally, make them start at 1.
            static string clamped(ushort v) @safe pure nothrow
            {
                return text(v + 1, v == ushort.max ? " or higher" : "");
            }
            return "file " ~ name_ ~ ",line " ~ clamped(line_) ~ ",column " ~ clamped(column_);
        }
}

package:
// A struct storing parameters to the MarkedYAMLException constructor.
struct MarkedYAMLExceptionData
{
    // Context of the error.
    string context;
    // Position of the context in a YAML buffer.
    Mark contextMark;
    // The error itself.
    string problem;
    // Position if the error.
    Mark problemMark;
}

// Base class of YAML exceptions with marked positions of the problem.
abstract class MarkedYAMLException : YAMLException
{
    /// Position of the error.
    Mark mark;

    // Construct a MarkedYAMLException with specified context and problem.
    this(string context, const Mark contextMark, string problem, const Mark problemMark,
         string file = __FILE__, size_t line = __LINE__) @safe pure nothrow
    {
        const msg = context ~ '\n' ~
                    (contextMark != problemMark ? contextMark.toString() ~ '\n' : "") ~
                    problem ~ '\n' ~ problemMark.toString() ~ '\n';
        super(msg, file, line);
        mark = problemMark;
    }

    // Construct a MarkedYAMLException with specified problem.
    this(string problem, const Mark problemMark,
         string file = __FILE__, size_t line = __LINE__)
        @safe pure nothrow
    {
        super(problem ~ '\n' ~ problemMark.toString(), file, line);
        mark = problemMark;
    }

    /// Construct a MarkedYAMLException from a struct storing constructor parameters.
    this(ref const(MarkedYAMLExceptionData) data) @safe pure nothrow
    {
        with(data) this(context, contextMark, problem, problemMark);
    }
}

// Constructors of YAML exceptions are mostly the same, so we use a mixin.
//
// See_Also: YAMLException
template ExceptionCtors()
{
    public this(string msg, string file = __FILE__, size_t line = __LINE__)
        @safe pure nothrow
    {
        super(msg, file, line);
    }
}

// Constructors of marked YAML exceptions are mostly the same, so we use a mixin.
//
// See_Also: MarkedYAMLException
template MarkedExceptionCtors()
{
    public:
        this(string context, const Mark contextMark, string problem,
             const Mark problemMark, string file = __FILE__, size_t line = __LINE__)
            @safe pure nothrow
        {
            super(context, contextMark, problem, problemMark,
                  file, line);
        }

        this(string problem, const Mark problemMark,
             string file = __FILE__, size_t line = __LINE__)
            @safe pure nothrow
        {
            super(problem, problemMark, file, line);
        }

        this(ref const(MarkedYAMLExceptionData) data) @safe pure nothrow
        {
            super(data);
        }
}