1 //          Copyright Brian Schott (Hackerpilot) 2014.
2 // Distributed under the Boost Software License, Version 1.0.
3 //    (See accompanying file LICENSE_1_0.txt or copy at
4 //          http://www.boost.org/LICENSE_1_0.txt)
5 
6 module analysis.linespan;
7 
8 /**
9  * Used for determining which lines to include as context in the generated HTML
10  * report.
11  */
12 struct LineSpans
13 {
14 public:
15 	/**
16 	 * Returns: true if any of the spans contain the given line number
17 	 */
18 	bool containsLine(size_t line) pure const nothrow @safe
19 	{
20 		foreach (span; spans)
21 		{
22 			if (line >= span.low && line <= span.high)
23 				return true;
24 		}
25 		return false;
26 	}
27 
28 	/**
29 	 * Params: line = the line to add
30 	 */
31 	void addLine(size_t line) pure nothrow @safe
32 	{
33 		immutable size_t low = line >= context ? line - context : 0;
34 		immutable size_t high = line + context;
35 		foreach (ref span; spans)
36 		{
37 			if (low <= span.low && high >= span.low && high <= span.high)
38 			{
39 				span.low = low;
40 				return;
41 			}
42 			else if (high >= span.high && low <= span.high && low >= span.low)
43 			{
44 				span.high = high;
45 				return;
46 			}
47 		}
48 		spans ~= Span(low, high);
49 	}
50 
51 private:
52 
53 	static struct Span
54 	{
55 		size_t low;
56 		size_t high;
57 	}
58 
59 	Span[] spans;
60 
61 	enum context = 3;
62 }
63 
64 unittest
65 {
66 	import std.stdio:stderr;
67 
68 	LineSpans l;
69 	l.addLine(5);
70 	foreach (i; 2 .. 9)
71 		assert (l.containsLine(i));
72 	assert (!l.containsLine(1));
73 	assert (!l.containsLine(9));
74 	l.addLine(5);
75 	assert (l.containsLine(7));
76 	l.addLine(40);
77 	l.addLine(35);
78 	foreach (i; 33 .. 43)
79 		assert (l.containsLine(i));
80 	stderr.writeln("Unittest for LineSpans passed.");
81 }
82