Newer
Older
dub_jkp / source / dub / internal / dyaml / exception.d
  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 dub.internal.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 @nogc
  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. /// Duplicate a mark
  69. Mark dup () const scope @safe pure nothrow
  70. {
  71. return Mark(this.name_.idup, this.line_, this.column_);
  72. }
  73.  
  74. /// Get a string representation of the mark.
  75. string toString() const scope @safe pure nothrow
  76. {
  77. // Line/column numbers start at zero internally, make them start at 1.
  78. static string clamped(ushort v) @safe pure nothrow
  79. {
  80. return text(v + 1, v == ushort.max ? " or higher" : "");
  81. }
  82. return "file " ~ name_ ~ ",line " ~ clamped(line_) ~ ",column " ~ clamped(column_);
  83. }
  84. }
  85.  
  86. // Base class of YAML exceptions with marked positions of the problem.
  87. abstract class MarkedYAMLException : YAMLException
  88. {
  89. /// Position of the error.
  90. Mark mark;
  91.  
  92. // Construct a MarkedYAMLException with specified context and problem.
  93. this(string context, scope const Mark contextMark,
  94. string problem, scope const Mark problemMark,
  95. string file = __FILE__, size_t line = __LINE__) @safe pure nothrow
  96. {
  97. const msg = context ~ '\n' ~
  98. (contextMark != problemMark ? contextMark.toString() ~ '\n' : "") ~
  99. problem ~ '\n' ~ problemMark.toString() ~ '\n';
  100. super(msg, file, line);
  101. mark = problemMark.dup;
  102. }
  103.  
  104. // Construct a MarkedYAMLException with specified problem.
  105. this(string problem, scope const Mark problemMark,
  106. string file = __FILE__, size_t line = __LINE__)
  107. @safe pure nothrow
  108. {
  109. super(problem ~ '\n' ~ problemMark.toString(), file, line);
  110. mark = problemMark.dup;
  111. }
  112.  
  113. /// Construct a MarkedYAMLException from a struct storing constructor parameters.
  114. this(ref const(MarkedYAMLExceptionData) data) @safe pure nothrow
  115. {
  116. with(data) this(context, contextMark, problem, problemMark);
  117. }
  118. }
  119.  
  120. package:
  121. // A struct storing parameters to the MarkedYAMLException constructor.
  122. struct MarkedYAMLExceptionData
  123. {
  124. // Context of the error.
  125. string context;
  126. // Position of the context in a YAML buffer.
  127. Mark contextMark;
  128. // The error itself.
  129. string problem;
  130. // Position if the error.
  131. Mark problemMark;
  132. }
  133.  
  134. // Constructors of YAML exceptions are mostly the same, so we use a mixin.
  135. //
  136. // See_Also: YAMLException
  137. template ExceptionCtors()
  138. {
  139. public this(string msg, string file = __FILE__, size_t line = __LINE__)
  140. @safe pure nothrow
  141. {
  142. super(msg, file, line);
  143. }
  144. }
  145.  
  146. // Constructors of marked YAML exceptions are mostly the same, so we use a mixin.
  147. //
  148. // See_Also: MarkedYAMLException
  149. template MarkedExceptionCtors()
  150. {
  151. public:
  152. this(string context, const Mark contextMark, string problem,
  153. const Mark problemMark, string file = __FILE__, size_t line = __LINE__)
  154. @safe pure nothrow
  155. {
  156. super(context, contextMark, problem, problemMark,
  157. file, line);
  158. }
  159.  
  160. this(string problem, const Mark problemMark,
  161. string file = __FILE__, size_t line = __LINE__)
  162. @safe pure nothrow
  163. {
  164. super(problem, problemMark, file, line);
  165. }
  166.  
  167. this(ref const(MarkedYAMLExceptionData) data) @safe pure nothrow
  168. {
  169. super(data);
  170. }
  171. }