Mercurial > projects > dang
comparison basic/SourceManager.d @ 91:1a24e61eb104 new_gen
Fixed the SourceLocation/SourceManager for files stretching by more then one CheckPoints
author | johnsen@johnsen-laptop |
---|---|
date | Mon, 05 May 2008 17:07:16 +0200 |
parents | a49bb982a7b0 |
children | 771ac63898e2 |
comparison
equal
deleted
inserted
replaced
90:4b6d8563e943 | 91:1a24e61eb104 |
---|---|
41 Returns a string slice containing the part of the file after loc (a | 41 Returns a string slice containing the part of the file after loc (a |
42 pointer might be better, it allows negative indexing) | 42 pointer might be better, it allows negative indexing) |
43 **/ | 43 **/ |
44 string getRawData(SourceLocation loc) | 44 string getRawData(SourceLocation loc) |
45 { | 45 { |
46 return checkpoints[loc.fileID].data[loc.fileOffset .. $]; | 46 CP cp = checkpoints[loc.fileID]; |
47 auto length = cp.data_end - cp.data.ptr; | |
48 return cp.data.ptr[loc.fileOffset .. length]; | |
47 } | 49 } |
48 | 50 |
49 /** | 51 /** |
50 Extracts the line number of the given location | 52 Extracts the line number of the given location |
51 O("file size") if cache isn't built, O(log "lines in file") else | 53 O("file size") if cache isn't built, O(log "lines in file") else |
57 assert(loc.fileID < checkpoints.length, "Non-existent location"); | 59 assert(loc.fileID < checkpoints.length, "Non-existent location"); |
58 | 60 |
59 CP* cp = &checkpoints[loc.fileID]; | 61 CP* cp = &checkpoints[loc.fileID]; |
60 auto cache = &linecache[cp.meta_index]; | 62 auto cache = &linecache[cp.meta_index]; |
61 if (!cache.isCached) | 63 if (!cache.isCached) |
62 cache.build(cp.data); | 64 cache.build(cp.data_start[0 .. cp.data_end - cp.data_start]); |
63 return cache.lineOf(getFileOffset(loc)); | 65 return cache.lineOf(getFileOffset(loc)); |
64 } | 66 } |
65 | 67 |
66 /** | 68 /** |
67 Extracts the full byte offset into a file, at which a location | 69 Extracts the full byte offset into a file, at which a location |
82 // and decreasing one until the nearest newline while the other ptr is | 84 // and decreasing one until the nearest newline while the other ptr is |
83 // increased to the nearest newline. | 85 // increased to the nearest newline. |
84 CP* cp = &checkpoints[loc.fileID]; | 86 CP* cp = &checkpoints[loc.fileID]; |
85 char* ptr = cp.data.ptr + loc.fileOffset; | 87 char* ptr = cp.data.ptr + loc.fileOffset; |
86 char* ptr_lo = ptr; | 88 char* ptr_lo = ptr; |
87 while (ptr_lo != cp.data.ptr && *ptr_lo != '\n' && *ptr_lo != '\r') | 89 while (cp.inRange(ptr_lo) && *ptr_lo != '\n' && *ptr_lo != '\r') |
88 --ptr_lo; | 90 --ptr_lo; |
89 while (ptr != cp.data.ptr + cp.data.length && *ptr != '\n' && *ptr != '\r') | 91 while (cp.inRange(ptr) && *ptr != '\n' && *ptr != '\r') |
90 ++ptr; | 92 ++ptr; |
91 return ptr_lo[1 .. ptr - ptr_lo]; | 93 return ptr_lo[1 .. ptr - ptr_lo]; |
92 } | 94 } |
93 | 95 |
94 /** | 96 /** |
100 // and decreasing one until the nearest newline while the other ptr is | 102 // and decreasing one until the nearest newline while the other ptr is |
101 // increased to the nearest newline. | 103 // increased to the nearest newline. |
102 CP* cp = &checkpoints[loc.fileID]; | 104 CP* cp = &checkpoints[loc.fileID]; |
103 char* ptr = cp.data.ptr + loc.fileOffset; | 105 char* ptr = cp.data.ptr + loc.fileOffset; |
104 char* ptr_lo = ptr; | 106 char* ptr_lo = ptr; |
105 while (ptr_lo != cp.data.ptr && *ptr_lo != '\n' && *ptr_lo != '\r') | 107 while (cp.inRange(ptr_lo) && *ptr_lo != '\n' && *ptr_lo != '\r') |
106 --ptr_lo; | 108 --ptr_lo; |
107 return cast(int)ptr - cast(int)ptr_lo - 1; | 109 return cast(int)ptr - cast(int)ptr_lo - 1; |
108 } | 110 } |
109 | 111 |
110 /** | 112 /** |
114 { | 116 { |
115 assert(loc.isValid, "Range is invalid"); | 117 assert(loc.isValid, "Range is invalid"); |
116 assert(loc.isReal, "Virtual locations not supported yet"); | 118 assert(loc.isReal, "Virtual locations not supported yet"); |
117 auto begin = getFileOffset(loc.begin); | 119 auto begin = getFileOffset(loc.begin); |
118 auto end = getFileOffset(loc.end); | 120 auto end = getFileOffset(loc.end); |
119 return checkpoints[loc.begin.fileID].data.ptr[begin .. end]; | 121 return checkpoints[loc.begin.fileID].data_start[begin .. end]; |
120 } | 122 } |
121 | 123 |
122 /** | 124 /** |
123 Get the original source text | 125 Get the original source text |
124 **/ | 126 **/ |
154 linecache ~= FileLineCache(); | 156 linecache ~= FileLineCache(); |
155 uint meta_index = linecache.length - 1; | 157 uint meta_index = linecache.length - 1; |
156 | 158 |
157 // SourceLocation's can only index relatively short buffers, therefore | 159 // SourceLocation's can only index relatively short buffers, therefore |
158 // the file is split into several checkpoints. | 160 // the file is split into several checkpoints. |
159 uint checkpoint_counter = checkpoints.length; | 161 uint checkpoint_counter = 0; |
162 char* data_start = data.ptr; | |
163 char* data_end = data.ptr + data.length; | |
160 while (data.length > 0) | 164 while (data.length > 0) |
161 { | 165 { |
162 uint to_take = min(data.length, SourceLocation.Bits.MaxFileOffset); | 166 uint to_take = min(data.length, SourceLocation.Bits.MaxFileOffset); |
163 checkpoints ~= | 167 checkpoints ~= |
164 CP(source_file, | 168 CP(source_file, |
169 data_start, | |
170 data_end, | |
165 data[0 .. to_take], | 171 data[0 .. to_take], |
166 checkpoint_counter++, | 172 checkpoint_counter++, |
167 meta_index); | 173 meta_index); |
168 data = data[to_take .. $]; | 174 data = data[to_take .. $]; |
169 // Stdout("Taking ")(to_take)(" from ")(source_file).newline; | |
170 } | 175 } |
171 checkpoint_counter = checkpoints.length - checkpoint_counter; | 176 checkpoint_counter = checkpoints.length - checkpoint_counter; |
172 return SourceLocation.fromFileID(checkpoint_counter); | 177 return SourceLocation.fromFileID(checkpoint_counter); |
173 } | 178 } |
174 | 179 |
189 struct CP | 194 struct CP |
190 { | 195 { |
191 // read-only | 196 // read-only |
192 char[] filename; | 197 char[] filename; |
193 // ditto | 198 // ditto |
199 char* data_start; | |
200 char* data_end; | |
201 // ditto | |
194 char[] data; | 202 char[] data; |
195 // ditto | 203 // ditto |
196 uint part = 0; | 204 uint part = 0; |
197 // ditto | 205 // ditto |
198 uint meta_index = 0; | 206 uint meta_index = 0; |
207 | |
208 bool inRange(char* p) | |
209 { | |
210 return p >= data_start && p < data_end; | |
211 } | |
199 } | 212 } |
200 | 213 |
201 struct FileLineCache | 214 struct FileLineCache |
202 { | 215 { |
203 /// Contains the offset of the i'th line on index i | 216 /// Contains the offset of the i'th line on index i |