BR3392226 preproc: Rework line readin procedure

It's been reported that we handle MacOS eol wrong.
This patch fixes the problem.

http://bugzilla.nasm.us/show_bug.cgi?id=3392226

Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
This commit is contained in:
Cyrill Gorcunov 2012-10-27 19:27:18 +04:00
parent 4dab7a000f
commit f1fe4fdeab

119
preproc.c
View File

@ -799,81 +799,80 @@ static char *line_from_stdmac(void)
return line; return line;
} }
#define BUF_DELTA 512
/*
* Read a line from the top file in istk, handling multiple CR/LFs
* at the end of the line read, and handling spurious ^Zs. Will
* return lines from the standard macro set if this has not already
* been done.
*/
static char *read_line(void) static char *read_line(void)
{ {
char *buffer, *p, *q; unsigned int size, c, next;
int bufsize, continued_count; const unsigned int delta = 512;
const unsigned int pad = 8;
unsigned int nr_cont = 0;
bool cont = false;
char *buffer, *p;
/* /* Standart macros set (predefined) goes first */
* standart macros set (predefined) goes first
*/
p = line_from_stdmac(); p = line_from_stdmac();
if (p) if (p)
return p; return p;
/* size = delta;
* regular read from a file p = buffer = nasm_malloc(size);
*/
bufsize = BUF_DELTA; for (;;) {
buffer = nasm_malloc(BUF_DELTA); c = fgetc(istk->fp);
p = buffer; if ((int)(c) == EOF) {
continued_count = 0; p[0] = 0;
while (1) {
q = fgets(p, bufsize - (p - buffer), istk->fp);
if (!q)
break; break;
p += strlen(p);
if (p > buffer && p[-1] == '\n') {
/*
* Convert backslash-CRLF line continuation sequences into
* nothing at all (for DOS and Windows)
*/
if (((p - 2) > buffer) && (p[-3] == '\\') && (p[-2] == '\r')) {
p -= 3;
*p = 0;
continued_count++;
}
/*
* Also convert backslash-LF line continuation sequences into
* nothing at all (for Unix)
*/
else if (((p - 1) > buffer) && (p[-2] == '\\')) {
p -= 2;
*p = 0;
continued_count++;
} else {
break;
}
}
if (p - buffer > bufsize - 10) {
int32_t offset = p - buffer;
bufsize += BUF_DELTA;
buffer = nasm_realloc(buffer, bufsize);
p = buffer + offset; /* prevent stale-pointer problems */
}
} }
if (!q && p == buffer) { switch (c) {
case '\r':
next = fgetc(istk->fp);
if (next != '\n')
ungetc(next, istk->fp);
if (cont) {
cont = false;
continue;
}
break;
case '\n':
if (cont) {
cont = false;
continue;
}
break;
case '\\':
next = fgetc(istk->fp);
ungetc(next, istk->fp);
if (next == ' ' || next == '\r' || next == '\n') {
cont = true;
nr_cont++;
continue;
}
break;
}
if (c == '\r' || c == '\n') {
*p++ = 0;
break;
}
if (p >= (buffer + size - pad)) {
buffer = nasm_realloc(buffer, size + delta);
p = buffer + size - pad;
size += delta;
}
*p++ = (unsigned char)c;
}
if (p == buffer) {
nasm_free(buffer); nasm_free(buffer);
return NULL; return NULL;
} }
src_set_linnum(src_get_linnum() + istk->lineinc + src_set_linnum(src_get_linnum() + istk->lineinc +
(continued_count * istk->lineinc)); (nr_cont * istk->lineinc));
/*
* Play safe: remove CRs as well as LFs, if any of either are
* present at the end of the line.
*/
while (--p >= buffer && (*p == '\n' || *p == '\r'))
*p = '\0';
/* /*
* Handle spurious ^Z, which may be inserted into source files * Handle spurious ^Z, which may be inserted into source files