xref: /haiku/src/kits/debugger/model/FileSourceCode.cpp (revision 21258e2674226d6aa732321b6f8494841895af5f)
1 /*
2  * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "FileSourceCode.h"
8 
9 #include <string.h>
10 
11 #include "LocatableFile.h"
12 #include "SourceFile.h"
13 #include "SourceLanguage.h"
14 #include "SourceLocation.h"
15 
16 
17 FileSourceCode::FileSourceCode(LocatableFile* file, SourceFile* sourceFile,
18 	SourceLanguage* language)
19 	:
20 	fLock("source code"),
21 	fFile(file),
22 	fSourceFile(sourceFile),
23 	fLanguage(language)
24 {
25 	fFile->AcquireReference();
26 	fSourceFile->AcquireReference();
27 	fLanguage->AcquireReference();
28 }
29 
30 
31 FileSourceCode::~FileSourceCode()
32 {
33 	fLanguage->ReleaseReference();
34 	fSourceFile->ReleaseReference();
35 	fFile->ReleaseReference();
36 }
37 
38 
39 status_t
40 FileSourceCode::Init()
41 {
42 	return fLock.InitCheck();
43 }
44 
45 
46 status_t
47 FileSourceCode::AddSourceLocation(const SourceLocation& location)
48 {
49 	// Find the insertion index; don't insert twice.
50 	bool foundMatch;
51 	int32 index = _FindSourceLocationIndex(location, foundMatch);
52 	if (foundMatch)
53 		return B_OK;
54 
55 	return fSourceLocations.Insert(location, index) ? B_OK : B_NO_MEMORY;
56 }
57 
58 
59 bool
60 FileSourceCode::Lock()
61 {
62 	return fLock.Lock();
63 }
64 
65 
66 void
67 FileSourceCode::Unlock()
68 {
69 	fLock.Unlock();
70 }
71 
72 
73 SourceLanguage*
74 FileSourceCode::GetSourceLanguage() const
75 {
76 	return fLanguage;
77 }
78 
79 
80 int32
81 FileSourceCode::CountLines() const
82 {
83 	return fSourceFile->CountLines();
84 }
85 
86 
87 const char*
88 FileSourceCode::LineAt(int32 index) const
89 {
90 	return fSourceFile->LineAt(index);
91 }
92 
93 
94 int32
95 FileSourceCode::LineLengthAt(int32 index) const
96 {
97 	return fSourceFile->LineLengthAt(index);
98 }
99 
100 
101 bool
102 FileSourceCode::GetStatementLocationRange(const SourceLocation& location,
103 	SourceLocation& _start, SourceLocation& _end) const
104 {
105 	int32 lineCount = CountLines();
106 	if (location.Line() >= lineCount)
107 		return false;
108 
109 	bool foundMatch;
110 	int32 index = _FindSourceLocationIndex(location, foundMatch);
111 
112 	if (!foundMatch) {
113 		if (index == 0)
114 			return false;
115 		index--;
116 	}
117 
118 	_start = fSourceLocations[index];
119 	_end = index + 1 < lineCount
120 		? fSourceLocations[index + 1] : SourceLocation(lineCount);
121 	return true;
122 }
123 
124 
125 LocatableFile*
126 FileSourceCode::GetSourceFile() const
127 {
128 	return fFile;
129 }
130 
131 
132 int32
133 FileSourceCode::_FindSourceLocationIndex(const SourceLocation& location,
134 	bool& _foundMatch) const
135 {
136 	int32 lower = 0;
137 	int32 upper = fSourceLocations.Size();
138 	while (lower < upper) {
139 		int32 mid = (lower + upper) / 2;
140 		if (location <= fSourceLocations[mid])
141 			upper = mid;
142 		else
143 			lower = mid + 1;
144 	}
145 
146 	_foundMatch = lower < fSourceLocations.Size()
147 		&& location == fSourceLocations[lower];
148 	return lower;
149 }
150