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