1 2 // Copyright Ferdinand Majerech 2011. 3 // Distributed under the Boost Software License, Version 1.0. 4 // (See accompanying file LICENSE_1_0.txt or copy at 5 // http://www.boost.org/LICENSE_1_0.txt) 6 7 ///Exceptions thrown by D:YAML and _exception related code. 8 module dyaml.exception; 9 10 11 import std.algorithm; 12 import std.array; 13 import std..string; 14 import std.conv; 15 16 17 /// Base class for all exceptions thrown by D:YAML. 18 class YAMLException : Exception 19 { 20 /// Construct a YAMLException with specified message and position where it was thrown. 21 public this(string msg, string file = __FILE__, size_t line = __LINE__) 22 @safe pure nothrow 23 { 24 super(msg, file, line); 25 } 26 } 27 28 /// Position in a YAML stream, used for error messages. 29 struct Mark 30 { 31 package: 32 /// File name. 33 string name_; 34 /// Line number. 35 ushort line_; 36 /// Column number. 37 ushort column_; 38 39 public: 40 /// Construct a Mark with specified line and column in the file. 41 this(string name, const uint line, const uint column) @safe pure nothrow @nogc 42 { 43 name_ = name; 44 line_ = cast(ushort)min(ushort.max, line); 45 // This *will* overflow on extremely wide files but saves CPU time 46 // (mark ctor takes ~5% of time) 47 column_ = cast(ushort)column; 48 } 49 50 /// Get a file name. 51 @property string name() @safe pure nothrow @nogc const 52 { 53 return name_; 54 } 55 56 /// Get a line number. 57 @property ushort line() @safe pure nothrow @nogc const 58 { 59 return line_; 60 } 61 62 /// Get a column number. 63 @property ushort column() @safe pure nothrow @nogc const 64 { 65 return column_; 66 } 67 68 /// Get a string representation of the mark. 69 string toString() @safe pure nothrow const 70 { 71 // Line/column numbers start at zero internally, make them start at 1. 72 static string clamped(ushort v) @safe pure nothrow 73 { 74 return text(v + 1, v == ushort.max ? " or higher" : ""); 75 } 76 return "file " ~ name_ ~ ",line " ~ clamped(line_) ~ ",column " ~ clamped(column_); 77 } 78 } 79 80 package: 81 // A struct storing parameters to the MarkedYAMLException constructor. 82 struct MarkedYAMLExceptionData 83 { 84 // Context of the error. 85 string context; 86 // Position of the context in a YAML buffer. 87 Mark contextMark; 88 // The error itself. 89 string problem; 90 // Position if the error. 91 Mark problemMark; 92 } 93 94 // Base class of YAML exceptions with marked positions of the problem. 95 abstract class MarkedYAMLException : YAMLException 96 { 97 // Construct a MarkedYAMLException with specified context and problem. 98 this(string context, const Mark contextMark, string problem, const Mark problemMark, 99 string file = __FILE__, size_t line = __LINE__) @safe pure nothrow 100 { 101 const msg = context ~ '\n' ~ 102 (contextMark != problemMark ? contextMark.toString() ~ '\n' : "") ~ 103 problem ~ '\n' ~ problemMark.toString() ~ '\n'; 104 super(msg, file, line); 105 } 106 107 // Construct a MarkedYAMLException with specified problem. 108 this(string problem, const Mark problemMark, 109 string file = __FILE__, size_t line = __LINE__) 110 @safe pure nothrow 111 { 112 super(problem ~ '\n' ~ problemMark.toString(), file, line); 113 } 114 115 /// Construct a MarkedYAMLException from a struct storing constructor parameters. 116 this(ref const(MarkedYAMLExceptionData) data) @safe pure nothrow 117 { 118 with(data) this(context, contextMark, problem, problemMark); 119 } 120 } 121 122 // Constructors of YAML exceptions are mostly the same, so we use a mixin. 123 // 124 // See_Also: YAMLException 125 template ExceptionCtors() 126 { 127 public this(string msg, string file = __FILE__, size_t line = __LINE__) 128 @safe pure nothrow 129 { 130 super(msg, file, line); 131 } 132 } 133 134 // Constructors of marked YAML exceptions are mostly the same, so we use a mixin. 135 // 136 // See_Also: MarkedYAMLException 137 template MarkedExceptionCtors() 138 { 139 public: 140 this(string context, const Mark contextMark, string problem, 141 const Mark problemMark, string file = __FILE__, size_t line = __LINE__) 142 @safe pure nothrow 143 { 144 super(context, contextMark, problem, problemMark, 145 file, line); 146 } 147 148 this(string problem, const Mark problemMark, 149 string file = __FILE__, size_t line = __LINE__) 150 @safe pure nothrow 151 { 152 super(problem, problemMark, file, line); 153 } 154 155 this(ref const(MarkedYAMLExceptionData) data) @safe pure nothrow 156 { 157 super(data); 158 } 159 }