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 package: 29 // Position in a YAML stream, used for error messages. 30 struct Mark 31 { 32 package: 33 /// Line number. 34 ushort line_; 35 /// Column number. 36 ushort column_; 37 38 public: 39 /// Construct a Mark with specified line and column in the file. 40 this(const uint line, const uint column) @safe pure nothrow @nogc 41 { 42 line_ = cast(ushort)min(ushort.max, line); 43 // This *will* overflow on extremely wide files but saves CPU time 44 // (mark ctor takes ~5% of time) 45 column_ = cast(ushort)column; 46 } 47 48 /// Get a string representation of the mark. 49 string toString() @safe pure nothrow const 50 { 51 // Line/column numbers start at zero internally, make them start at 1. 52 static string clamped(ushort v) @safe pure nothrow 53 { 54 return text(v + 1, v == ushort.max ? " or higher" : ""); 55 } 56 return "line " ~ clamped(line_) ~ ",column " ~ clamped(column_); 57 } 58 } 59 60 // A struct storing parameters to the MarkedYAMLException constructor. 61 struct MarkedYAMLExceptionData 62 { 63 // Context of the error. 64 string context; 65 // Position of the context in a YAML buffer. 66 Mark contextMark; 67 // The error itself. 68 string problem; 69 // Position if the error. 70 Mark problemMark; 71 } 72 73 // Base class of YAML exceptions with marked positions of the problem. 74 abstract class MarkedYAMLException : YAMLException 75 { 76 // Construct a MarkedYAMLException with specified context and problem. 77 this(string context, const Mark contextMark, string problem, const Mark problemMark, 78 string file = __FILE__, size_t line = __LINE__) @safe pure nothrow 79 { 80 const msg = context ~ '\n' ~ 81 (contextMark != problemMark ? contextMark.toString() ~ '\n' : "") ~ 82 problem ~ '\n' ~ problemMark.toString() ~ '\n'; 83 super(msg, file, line); 84 } 85 86 // Construct a MarkedYAMLException with specified problem. 87 this(string problem, const Mark problemMark, 88 string file = __FILE__, size_t line = __LINE__) 89 @safe pure nothrow 90 { 91 super(problem ~ '\n' ~ problemMark.toString(), file, line); 92 } 93 94 /// Construct a MarkedYAMLException from a struct storing constructor parameters. 95 this(ref const(MarkedYAMLExceptionData) data) @safe pure nothrow 96 { 97 with(data) this(context, contextMark, problem, problemMark); 98 } 99 } 100 101 // Constructors of YAML exceptions are mostly the same, so we use a mixin. 102 // 103 // See_Also: YAMLException 104 template ExceptionCtors() 105 { 106 public this(string msg, string file = __FILE__, size_t line = __LINE__) 107 @safe pure nothrow 108 { 109 super(msg, file, line); 110 } 111 } 112 113 // Constructors of marked YAML exceptions are mostly the same, so we use a mixin. 114 // 115 // See_Also: MarkedYAMLException 116 template MarkedExceptionCtors() 117 { 118 public: 119 this(string context, const Mark contextMark, string problem, 120 const Mark problemMark, string file = __FILE__, size_t line = __LINE__) 121 @safe pure nothrow 122 { 123 super(context, contextMark, problem, problemMark, 124 file, line); 125 } 126 127 this(string problem, const Mark problemMark, 128 string file = __FILE__, size_t line = __LINE__) 129 @safe pure nothrow 130 { 131 super(problem, problemMark, file, line); 132 } 133 134 this(ref const(MarkedYAMLExceptionData) data) @safe pure nothrow 135 { 136 super(data); 137 } 138 }