comparison files.c @ 75:980ed7cb620a

More multiline comment fixes. It looks like the only rational way to handle multiline comments is to treat the newlines as fully part of the comment text.
author David A. Holland
date Mon, 10 Jun 2013 19:56:55 -0400
parents 2e25e55dba6b
children 27c9aafcaca1
comparison
equal deleted inserted replaced
74:bbbf71859a21 75:980ed7cb620a
113 } 113 }
114 114
115 //////////////////////////////////////////////////////////// 115 ////////////////////////////////////////////////////////////
116 // parsing 116 // parsing
117 117
118 /*
119 * Find the end of the logical line. End of line characters that are
120 * commented out do not count.
121 */
118 static 122 static
119 size_t 123 size_t
120 findnl(const char *buf, size_t start, size_t limit) 124 findeol(const char *buf, size_t start, size_t limit)
121 { 125 {
122 size_t i; 126 size_t i;
127 int incomment = 0;
128
129 for (i=start; i<limit; i++) {
130 if (incomment) {
131 if (i+1 < limit && buf[i] == '*' && buf[i+1] == '/') {
132 i++;
133 incomment = 0;
134 }
135 }
136 else {
137 if (i+1 < limit && buf[i] == '/' && buf[i+1] == '*') {
138 i++;
139 incomment = 1;
140 }
141 else {
142 if (buf[i] == '\n') {
143 return i;
144 }
145 }
146 }
147 }
148 return limit;
149 }
150
151 static
152 unsigned
153 countnls(const char *buf, size_t start, size_t limit)
154 {
155 size_t i;
156 unsigned count = 0;
123 157
124 for (i=start; i<limit; i++) { 158 for (i=start; i<limit; i++) {
125 if (buf[i] == '\n') { 159 if (buf[i] == '\n') {
126 return i; 160 count++;
127 } 161 }
128 } 162 }
129 return limit; 163 return count;
130 } 164 }
131 165
132 static 166 static
133 void 167 void
134 file_read(const struct placefile *pf, int fd, const char *name, bool toplevel) 168 file_read(const struct placefile *pf, int fd, const char *name, bool toplevel)
149 buf = domalloc(bufmax); 183 buf = domalloc(bufmax);
150 184
151 while (1) { 185 while (1) {
152 if (lineend >= bufend) { 186 if (lineend >= bufend) {
153 /* do not have a whole line in the buffer; read more */ 187 /* do not have a whole line in the buffer; read more */
188 assert(bufend >= linestart);
154 if (linestart > 0 && bufend > linestart) { 189 if (linestart > 0 && bufend > linestart) {
155 /* slide to beginning of buffer */ 190 /* slide to beginning of buffer */
156 memmove(buf, buf+linestart, bufend-linestart); 191 memmove(buf, buf+linestart, bufend-linestart);
157 bufend -= linestart; 192 bufend -= linestart;
158 lineend -= linestart; 193 lineend -= linestart;
192 lineend = bufend++; 227 lineend = bufend++;
193 buf[lineend] = '\n'; 228 buf[lineend] = '\n';
194 } else { 229 } else {
195 tmp = bufend; 230 tmp = bufend;
196 bufend += (size_t)result; 231 bufend += (size_t)result;
197 lineend = findnl(buf, tmp, bufend); 232 lineend = findeol(buf, tmp, bufend);
198 } 233 }
199 /* loop in case we still don't have a whole line */ 234 /* loop in case we still don't have a whole line */
200 continue; 235 continue;
201 } 236 }
202 237
220 memmove(buf+lineend, buf+nextlinestart, 255 memmove(buf+lineend, buf+nextlinestart,
221 bufend - nextlinestart); 256 bufend - nextlinestart);
222 } 257 }
223 bufend -= tmp; 258 bufend -= tmp;
224 nextlinestart -= tmp; 259 nextlinestart -= tmp;
225 lineend = findnl(buf, lineend, bufend); 260 lineend = findeol(buf, lineend, bufend);
226 /* might not have a whole line, so loop */ 261 /* might not have a whole line, so loop */
227 continue; 262 continue;
228 } 263 }
229 264
230 /* line now goes from linestart to lineend */ 265 /* line now goes from linestart to lineend */
231 assert(buf[lineend] == '\0'); 266 assert(buf[lineend] == '\0');
267
268 /* count how many commented-out newlines we swallowed */
269 nextlinestartplace.line += countnls(buf, linestart, lineend);
270
271 /* if the line isn't empty, process it */
232 if (lineend > linestart) { 272 if (lineend > linestart) {
233 directive_gotline(&linestartplace, 273 directive_gotline(&linestartplace,
234 buf+linestart, lineend-linestart); 274 buf+linestart, lineend-linestart);
235 } 275 }
236 276
237 linestart = nextlinestart; 277 linestart = nextlinestart;
238 lineend = findnl(buf, linestart, bufend); 278 lineend = findeol(buf, linestart, bufend);
239 linestartplace = nextlinestartplace; 279 linestartplace = nextlinestartplace;
240 } 280 }
241 281
242 if (toplevel) { 282 if (toplevel) {
243 directive_goteof(&linestartplace); 283 directive_goteof(&linestartplace);