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