struct file_name_list *));
static long read_and_prescan PROTO ((cpp_reader *, cpp_buffer *,
int, size_t));
-static void simplify_pathname PROTO ((char *));
-static struct file_name_list *actual_directory PROTO ((cpp_reader *, char *));
+static struct file_name_list *actual_directory PROTO ((cpp_reader *,
+ const char *));
+static void initialize_input_buffer PROTO ((cpp_reader *, int,
+ struct stat *));
+static int file_cleanup PROTO ((cpp_buffer *, cpp_reader *));
+static void find_position PROTO ((U_CHAR *, U_CHAR *,
+ unsigned long *,
+ unsigned long *));
#if 0
static void hack_vms_include_specification PROTO ((char *));
VMS has non-numeric inodes. */
#ifdef VMS
#define INO_T_EQ(a, b) (!bcmp((char *) &(a), (char *) &(b), sizeof (a)))
-#elif (defined _WIN32 && !defined CYGWIN) || defined __MSDOS__
+#elif (defined _WIN32 && !defined CYGWIN && ! defined (_UWIN)) \
+ || defined __MSDOS__
#define INO_T_EQ(a, b) 0
#else
#define INO_T_EQ(a, b) ((a) == (b))
#endif
-/* Append an entry for dir DIR to list LIST, simplifying it if
- possible. SYS says whether this is a system include directory.
- *** DIR is modified in place. It must be writable and permanently
- allocated. LIST is a pointer to the head pointer, because we actually
- *prepend* the dir, and reverse the list later (in merge_include_chains). */
-void
-append_include_chain (pfile, list, dir, sysp)
- cpp_reader *pfile;
- struct file_name_list **list;
- const char *dir;
- int sysp;
-{
- struct file_name_list *new;
- struct stat st;
- unsigned int len;
- char * newdir = xstrdup (dir);
-
- simplify_pathname (newdir);
- if (stat (newdir, &st))
- {
- /* Dirs that don't exist are silently ignored. */
- if (errno != ENOENT)
- cpp_perror_with_name (pfile, newdir);
- return;
- }
-
- if (!S_ISDIR (st.st_mode))
- {
- cpp_message (pfile, 1, "%s: %s: Not a directory", progname, newdir);
- return;
- }
-
- len = strlen(newdir);
- if (len > pfile->max_include_len)
- pfile->max_include_len = len;
-
- new = (struct file_name_list *)xmalloc (sizeof (struct file_name_list));
- new->name = newdir;
- new->nlen = len;
- new->next = *list;
- new->ino = st.st_ino;
- new->dev = st.st_dev;
- new->sysp = sysp;
- new->name_map = NULL;
-
- *list = new;
-}
-
/* Merge the four include chains together in the order quote, bracket,
system, after. Remove duplicate dirs (as determined by
INO_T_EQ()). The system_include and after_include chains are never
merge_include_chains (opts)
struct cpp_options *opts;
{
- struct file_name_list *prev, *next, *cur, *other;
+ struct file_name_list *prev, *cur, *other;
struct file_name_list *quote, *brack, *systm, *after;
struct file_name_list *qtail, *btail, *stail, *atail;
- qtail = opts->quote_include;
- btail = opts->bracket_include;
- stail = opts->system_include;
- atail = opts->after_include;
+ qtail = opts->pending->quote_tail;
+ btail = opts->pending->brack_tail;
+ stail = opts->pending->systm_tail;
+ atail = opts->pending->after_tail;
- /* Nreverse the four lists. */
- prev = 0;
- for (cur = qtail; cur; cur = next)
- {
- next = cur->next;
- cur->next = prev;
- prev = cur;
- }
- quote = prev;
-
- prev = 0;
- for (cur = btail; cur; cur = next)
- {
- next = cur->next;
- cur->next = prev;
- prev = cur;
- }
- brack = prev;
-
- prev = 0;
- for (cur = stail; cur; cur = next)
- {
- next = cur->next;
- cur->next = prev;
- prev = cur;
- }
- systm = prev;
-
- prev = 0;
- for (cur = atail; cur; cur = next)
- {
- next = cur->next;
- cur->next = prev;
- prev = cur;
- }
- after = prev;
+ quote = opts->pending->quote_head;
+ brack = opts->pending->brack_head;
+ systm = opts->pending->systm_head;
+ after = opts->pending->after_head;
/* Paste together bracket, system, and after include chains. */
if (stail)
then we may lose directories from the <> search path that should
be there; consider -Ifoo -Ibar -I- -Ifoo -Iquux. It is however
safe to treat -Ibar -Ifoo -I- -Ifoo -Iquux as if written
- -Ibar -I- -Ifoo -Iquux. */
+ -Ibar -I- -Ifoo -Iquux.
+
+ Note that this algorithm is quadratic in the number of -I switches,
+ which is acceptable since there aren't usually that many of them. */
- for (cur = quote; cur; cur = cur->next)
+ for (cur = quote, prev = NULL; cur; cur = cur->next)
{
for (other = quote; other != cur; other = other->next)
if (INO_T_EQ (cur->ino, other->ino)
&& cur->dev == other->dev)
{
+ if (opts->verbose)
+ cpp_notice ("ignoring duplicate directory `%s'\n", cur->name);
+
prev->next = cur->next;
free (cur->name);
free (cur);
if (INO_T_EQ (cur->ino, other->ino)
&& cur->dev == other->dev)
{
+ if (opts->verbose)
+ cpp_notice ("ignoring duplicate directory `%s'\n", cur->name);
+
prev->next = cur->next;
free (cur->name);
free (cur);
{
if (quote == qtail)
{
+ if (opts->verbose)
+ cpp_notice ("ignoring duplicate directory `%s'\n",
+ quote->name);
+
free (quote->name);
free (quote);
quote = brack;
while (cur->next != qtail)
cur = cur->next;
cur->next = brack;
+ if (opts->verbose)
+ cpp_notice ("ignoring duplicate directory `%s'\n",
+ qtail->name);
+
free (qtail->name);
free (qtail);
}
opts->quote_include = quote;
opts->bracket_include = brack;
- opts->system_include = NULL;
- opts->after_include = NULL;
}
/* Look up or add an entry to the table of all includes. This table
struct include_hash *
include_hash (pfile, fname, add)
cpp_reader *pfile;
- char *fname;
+ const char *fname;
int add;
{
unsigned int hash = 0;
struct include_hash *l, *m;
- char *f = fname;
+ const char *f = fname;
while (*f)
hash += *f++;
int
find_include_file (pfile, fname, search_start, ihash, before)
cpp_reader *pfile;
- char *fname;
+ const char *fname;
struct file_name_list *search_start;
struct include_hash **ihash;
int *before;
len = 20;
set = alloc = xmalloc (len + 1);
- if (! is_space[ch])
+ if (! is_space(ch))
{
*set++ = ch;
- while ((ch = getc (f)) != EOF && ! is_space[ch])
+ while ((ch = getc (f)) != EOF && ! is_space(ch))
{
if (set - alloc == len)
{
char *from, *to;
struct file_name_map *ptr;
- if (is_space[ch])
+ if (is_space(ch))
continue;
from = read_filename_string (ch, f);
- while ((ch = getc (f)) != EOF && is_hor_space[ch])
+ while ((ch = getc (f)) != EOF && is_hspace(ch))
;
to = read_filename_string (ch, f);
fp = CPP_BUFFER (pfile);
+ /* If fd points to a plain file, we know how big it is, so we can
+ allocate the buffer all at once. If fd is a pipe or terminal, we
+ can't. Most C source files are 4k or less, so we guess that. If
+ fd is something weird, like a block device or a directory, we
+ don't want to read it at all.
+
+ Unfortunately, different systems use different st.st_mode values
+ for pipes: some have S_ISFIFO, some S_ISSOCK, some are buggy and
+ zero the entire struct stat except a couple fields. Hence the
+ mess below.
+
+ In all cases, read_and_prescan will resize the buffer if it
+ turns out there's more data than we thought. */
+
if (S_ISREG (st.st_mode))
{
/* off_t might have a wider range than size_t - in other words,
the max size of a file might be bigger than the address
- space, and we need to detect that now. */
+ space. We can't handle a file that large. (Anyone with
+ a single source file bigger than 4GB needs to rethink
+ their coding style.) */
st_size = (size_t) st.st_size;
- if ((unsigned HOST_WIDE_INT) st_size
- != (unsigned HOST_WIDE_INT) st.st_size)
+ if ((unsigned HOST_WIDEST_INT) st_size
+ != (unsigned HOST_WIDEST_INT) st.st_size)
{
cpp_error (pfile, "file `%s' is too large", ihash->name);
goto fail;
}
}
- else if (S_ISFIFO (st.st_mode) || (S_ISCHR (st.st_mode) && isatty (fd)))
+ else if (S_ISFIFO (st.st_mode) || S_ISSOCK (st.st_mode)
+ /* Permit any kind of character device: the sensible ones are
+ ttys and /dev/null, but weeding out the others is too hard. */
+ || S_ISCHR (st.st_mode)
+ /* Some 4.x (x<4) derivatives have a bug that makes fstat() of a
+ socket or pipe return a stat struct with most fields zeroed. */
+ || (st.st_mode == 0 && st.st_nlink == 0 && st.st_size == 0))
{
/* Cannot get its file size before reading. 4k is a decent
first guess. */
goto fail;
}
+ if (pfile->input_buffer == NULL)
+ initialize_input_buffer (pfile, fd, &st);
+
/* Read the file, converting end-of-line characters and trigraphs
(if enabled). */
fp->ihash = ihash;
close (fd);
fp->rlimit = fp->alimit = fp->buf + length;
fp->cur = fp->buf;
- fp->system_header_p = (ihash->foundhere != ABSOLUTE_PATH
- && ihash->foundhere->sysp);
+ if (ihash->foundhere != ABSOLUTE_PATH)
+ fp->system_header_p = ihash->foundhere->sysp;
fp->lineno = 1;
fp->colno = 1;
+ fp->line_base = fp->buf;
fp->cleanup = file_cleanup;
/* The ->actual_dir field is only used when ignore_srcdir is not in effect;
return 0;
}
+/* Given a path FNAME, extract the directory component and place it
+ onto the actual_dirs list. Return a pointer to the allocated
+ file_name_list structure. These structures are used to implement
+ current-directory "" include searching. */
+
static struct file_name_list *
actual_directory (pfile, fname)
cpp_reader *pfile;
- char *fname;
+ const char *fname;
{
char *last_slash, *dir;
size_t dlen;
x->nlen = dlen;
x->next = CPP_OPTIONS (pfile)->quote_include;
x->alloc = pfile->actual_dirs;
- x->sysp = 0;
+ x->sysp = CPP_BUFFER (pfile)->system_header_p;
x->name_map = NULL;
pfile->actual_dirs = x;
return x;
}
-/* Read the entire contents of file DESC into buffer BUF, convert end-of-line
- markers to canonical form, and convert trigraphs if enabled. Also, make
- sure there is a newline at the end of the file. LEN is how much room we
- have to start with (this can be expanded if necessary).
- Returns -1 on failure, or the actual length of the data to be scanned.
+/* Determine the current line and column. Used only by read_and_prescan. */
+static void
+find_position (start, limit, linep, colp)
+ U_CHAR *start;
+ U_CHAR *limit;
+ unsigned long *linep;
+ unsigned long *colp;
+{
+ unsigned long line = *linep, col = 0;
+ while (start < limit)
+ {
+ U_CHAR ch = *start++;
+ if (ch == '\n' || ch == '\r')
+ line++, col = 1;
+ else
+ col++;
+ }
+ *linep = line, *colp = col;
+}
- N.B. This function has been rearranged to out-of-line the uncommon cases
- as much as possible; this is important to prevent it from being a
- performance bottleneck. */
+/* Read the entire contents of file DESC into buffer BUF. LEN is how
+ much memory to allocate initially; more will be allocated if
+ necessary. Convert end-of-line markers (\n, \r, \r\n, \n\r) to
+ canonical form (\n). If enabled, convert and/or warn about
+ trigraphs. Convert backslash-newline to a one-character escape
+ (\r) and remove it from "embarrassing" places (i.e. the middle of a
+ token). If there is no newline at the end of the file, add one and
+ warn. Returns -1 on failure, or the actual length of the data to
+ be scanned.
+
+ This function does a lot of work, and can be a serious performance
+ bottleneck. It has been tuned heavily; make sure you understand it
+ before hacking. The common case - no trigraphs, Unix style line
+ breaks, backslash-newline set off by whitespace, newline at EOF -
+ has been optimized at the expense of the others. The performance
+ penalty for DOS style line breaks (\r\n) is about 15%.
+
+ Warnings lose particularly heavily since we have to determine the
+ line number, which involves scanning from the beginning of the file
+ or from the last warning. The penalty for the absence of a newline
+ at the end of reload1.c is about 60%. (reload1.c is 329k.)
+
+ If your file has more than one kind of end-of-line marker, you
+ will get messed-up line numbering. */
+
+/* Table of characters that can't be handled in the inner loop.
+ Keep these contiguous to optimize the performance of the code generated
+ for the switch that uses them. */
+#define SPECCASE_EMPTY 0
+#define SPECCASE_NUL 1
+#define SPECCASE_CR 2
+#define SPECCASE_BACKSLASH 3
+#define SPECCASE_QUESTION 4
static long
read_and_prescan (pfile, fp, desc, len)
int desc;
size_t len;
{
-
U_CHAR *buf = (U_CHAR *) xmalloc (len);
U_CHAR *ip, *op, *line_base;
U_CHAR *ibase;
- unsigned int line;
- int count, seen_eof;
+ U_CHAR *speccase = pfile->input_speccase;
+ unsigned long line;
+ unsigned int deferred_newlines;
+ int count;
size_t offset;
- /* 4096 bytes of buffer proper, 2 to detect running off the end without
- address arithmetic all the time, and 2 for pushback in the case there's
- a potential trigraph or end-of-line digraph at the end of a block. */
-#define INTERMED_BUFFER_SIZE 4096
- U_CHAR intermed[INTERMED_BUFFER_SIZE + 2 + 2];
offset = 0;
op = buf;
line_base = buf;
line = 1;
- ibase = intermed + 2;
- seen_eof = 0;
+ ibase = pfile->input_buffer + 2;
+ deferred_newlines = 0;
for (;;)
{
read_next:
- count = read (desc, intermed + 2, INTERMED_BUFFER_SIZE);
+
+ count = read (desc, pfile->input_buffer + 2, pfile->input_buffer_len);
if (count < 0)
- goto error;
- if (count == 0)
- seen_eof = 1;
- count += 2 - (ibase - intermed);
- if (count == 0)
+ goto error;
+ else if (count == 0)
break;
- ip = ibase;
- ip[count] = ip[count+1] = '\0';
- ibase = intermed + 2;
offset += count;
+ ip = ibase;
+ ibase = pfile->input_buffer + 2;
+ ibase[count] = ibase[count+1] = '\0';
if (offset > len)
{
- size_t delta_op = op - buf;
- size_t delta_line_base = line_base - buf;
+ size_t delta_op;
+ size_t delta_line_base;
len *= 2;
if (offset > len)
- /* len overflowed.
- This could happen if the file is larger than half the
- maximum address space of the machine. */
+ /* len overflowed.
+ This could happen if the file is larger than half the
+ maximum address space of the machine. */
goto too_big;
- buf = xrealloc (buf, len);
+
+ delta_op = op - buf;
+ delta_line_base = line_base - buf;
+ buf = (U_CHAR *) xrealloc (buf, len);
op = buf + delta_op;
line_base = buf + delta_line_base;
}
for (;;)
{
- U_CHAR c;
- c = *ip++;
- switch (c)
+ unsigned int span = 0;
+
+ /* Deal with \-newline in the middle of a token. */
+ if (deferred_newlines)
{
- /* The default case is at the top so gcc will realize
- it's the common case, and leave c in a register.
- Also, cache utilization is a little better this way. */
- default:
- *op++ = c;
- break;
-
- case '\0':
- if (seen_eof)
- goto eof;
- else
- goto read_next;
- case '\r':
- if (*ip == '\n') ip++;
- else if (*ip == '\0' && !seen_eof)
+ while (speccase[ip[span]] == SPECCASE_EMPTY
+ && ip[span] != '\n'
+ && ip[span] != '\t'
+ && ip[span] != ' ')
+ span++;
+ memcpy (op, ip, span);
+ op += span;
+ ip += span;
+ if (*ip == '\n' || *ip == '\t'
+ || *ip == ' ' || *ip == ' ')
+ while (deferred_newlines)
+ deferred_newlines--, *op++ = '\r';
+ span = 0;
+ }
+
+ /* Copy as much as we can without special treatment. */
+ while (speccase[ip[span]] == SPECCASE_EMPTY) span++;
+ memcpy (op, ip, span);
+ op += span;
+ ip += span;
+
+ switch (speccase[*ip++])
+ {
+ case SPECCASE_NUL: /* \0 */
+ ibase[-1] = op[-1];
+ goto read_next;
+
+ case SPECCASE_CR: /* \r */
+ if (*ip == '\n')
+ ip++;
+ else if (*ip == '\0')
{
*--ibase = '\r';
- break;
+ goto read_next;
}
+ else if (ip[-2] == '\n')
+ continue;
*op++ = '\n';
- line++;
- line_base = op;
break;
- case '\n':
- if (*ip == '\r') ip++;
- else if (*ip == '\0' && !seen_eof)
+ case SPECCASE_BACKSLASH: /* \ */
+ backslash:
+ {
+ /* If we're at the end of the intermediate buffer,
+ we have to shift the backslash down to the start
+ and come back next pass. */
+ if (*ip == '\0')
{
- *--ibase = '\n';
- break;
+ *--ibase = '\\';
+ goto read_next;
}
- *op++ = '\n';
- line++;
- line_base = op;
- break;
-
- case '?':
- if (CPP_OPTIONS (pfile)->trigraphs
- || CPP_OPTIONS (pfile)->warn_trigraphs)
+ else if (*ip == '\n')
{
- /* If we're at the end of the intermediate buffer,
- we have to shift the ?'s down to the start and
- come back next pass. */
- c = ip[0];
- if (c == '\0' && !seen_eof)
- {
- *--ibase = '?';
- break;
- }
- if (c != '?')
- {
- *op++ = '?';
- break;
- }
- c = ip[1];
- if (c == '\0' && !seen_eof)
- {
- *--ibase = '?';
- *--ibase = '?';
- break;
- }
- if (!trigraph_table[c])
- {
- *op++ = '?';
- break;
- }
-
- if (CPP_OPTIONS (pfile)->warn_trigraphs)
- cpp_warning_with_line (pfile, line, op-line_base,
- "trigraph ??%c encountered", c);
- if (CPP_OPTIONS (pfile)->trigraphs)
- {
- *op++ = trigraph_table[c];
- ip += 2;
- break;
- }
+ ip++;
+ if (*ip == '\r') ip++;
+ if (*ip == '\n' || *ip == '\t' || *ip == ' ')
+ *op++ = '\r';
+ else if (op[-1] == '\t' || op[-1] == ' '
+ || op[-1] == '\r' || op[-1] == '\n')
+ *op++ = '\r';
else
+ deferred_newlines++;
+ line++;
+ line_base = op;
+ }
+ else if (*ip == '\r')
+ {
+ ip++;
+ if (*ip == '\n') ip++;
+ else if (*ip == '\0')
{
- *op++ = '?';
- *op++ = '?';
- *op++ = c;
- ip += 2;
+ *--ibase = '\r';
+ *--ibase = '\\';
+ goto read_next;
}
+ else if (*ip == '\r' || *ip == '\t' || *ip == ' ')
+ *op++ = '\r';
+ else
+ deferred_newlines++;
+ line++;
+ line_base = op;
}
else
- *op++ = c;
+ *op++ = '\\';
+ }
+ break;
+
+ case SPECCASE_QUESTION: /* ? */
+ {
+ unsigned int d, t;
+ /* If we're at the end of the intermediate buffer,
+ we have to shift the ?'s down to the start and
+ come back next pass. */
+ d = ip[0];
+ if (d == '\0')
+ {
+ *--ibase = '?';
+ goto read_next;
+ }
+ if (d != '?')
+ {
+ *op++ = '?';
+ break;
+ }
+ d = ip[1];
+ if (d == '\0')
+ {
+ *--ibase = '?';
+ *--ibase = '?';
+ goto read_next;
+ }
+
+ /* Trigraph map:
+ * from to from to from to
+ * ?? = # ?? ) ] ?? ! |
+ * ?? ( [ ?? ' ^ ?? > }
+ * ?? / \ ?? < { ?? - ~
+ */
+ if (d == '=') t = '#';
+ else if (d == ')') t = ']';
+ else if (d == '!') t = '|';
+ else if (d == '(') t = '[';
+ else if (d == '\'') t = '^';
+ else if (d == '>') t = '}';
+ else if (d == '/') t = '\\';
+ else if (d == '<') t = '{';
+ else if (d == '-') t = '~';
+ else
+ {
+ *op++ = '?';
+ break;
+ }
+ if (CPP_OPTIONS (pfile)->warn_trigraphs)
+ {
+ unsigned long col;
+ find_position (line_base, op, &line, &col);
+ line_base = op - col;
+ cpp_warning_with_line (pfile, line, col,
+ "trigraph ??%c encountered", d);
+ }
+ if (CPP_OPTIONS (pfile)->trigraphs)
+ {
+ if (t == '\\')
+ goto backslash;
+ else
+ *op++ = t;
+ }
+ else
+ {
+ *op++ = '?';
+ *op++ = '?';
+ *op++ = d;
+ }
+ ip += 2;
+ }
}
}
}
- eof:
- if (op == buf)
+ if (offset == 0)
return 0;
- if (op[-1] != '\n' || op[-2] == '\\')
+ /* Deal with pushed-back chars at true EOF.
+ This may be any of: ?? ? \ \r \n \\r \\n.
+ \r must become \n, \\r or \\n must become \r.
+ We know we have space already. */
+ if (ibase == pfile->input_buffer)
+ {
+ if (*ibase == '?')
+ {
+ *op++ = '?';
+ *op++ = '?';
+ }
+ else
+ *op++ = '\r';
+ }
+ else if (ibase == pfile->input_buffer + 1)
+ {
+ if (*ibase == '\r')
+ *op++ = '\n';
+ else
+ *op++ = *ibase;
+ }
+
+ if (op[-1] != '\n')
{
- cpp_pedwarn_with_line (pfile, line, op - line_base,
- "no newline at end of file");
- if (offset + 2 > len)
+ unsigned long col;
+ find_position (line_base, op, &line, &col);
+ cpp_warning_with_line (pfile, line, col, "no newline at end of file\n");
+ if (offset + 1 > len)
{
- len += 2;
- if (offset + 2 > len)
+ len += 1;
+ if (offset + 1 > len)
goto too_big;
- buf = xrealloc (buf, len);
+ buf = (U_CHAR *) xrealloc (buf, len);
op = buf + offset;
}
- if (op[-1] == '\\')
- *op++ = '\n';
*op++ = '\n';
}
- buf = xrealloc (buf, op - buf);
- fp->buf = buf;
+ fp->buf = ((len - offset < 20) ? buf : (U_CHAR *)xrealloc (buf, op - buf));
return op - buf;
too_big:
- cpp_error (pfile, "file is too large");
+ cpp_error (pfile, "file is too large (>%lu bytes)\n", (unsigned long)offset);
free (buf);
return -1;
return -1;
}
+/* Initialize the `input_buffer' and `input_speccase' tables.
+ These are only used by read_and_prescan, but they're large and
+ somewhat expensive to set up, so we want them allocated once for
+ the duration of the cpp run. */
+
+static void
+initialize_input_buffer (pfile, fd, st)
+ cpp_reader *pfile;
+ int fd;
+ struct stat *st;
+{
+ long pipe_buf;
+ U_CHAR *tmp;
+
+ /* Table of characters that cannot be handled by the
+ read_and_prescan inner loop. The number of non-EMPTY entries
+ should be as small as humanly possible. */
+
+ tmp = (U_CHAR *) xmalloc (1 << CHAR_BIT);
+ memset (tmp, SPECCASE_EMPTY, 1 << CHAR_BIT);
+ tmp['\0'] = SPECCASE_NUL;
+ tmp['\r'] = SPECCASE_CR;
+ tmp['\\'] = SPECCASE_BACKSLASH;
+ if (CPP_OPTIONS (pfile)->trigraphs || CPP_OPTIONS (pfile)->warn_trigraphs)
+ tmp['?'] = SPECCASE_QUESTION;
+
+ pfile->input_speccase = tmp;
+
+ /* Determine the appropriate size for the input buffer. Normal C
+ source files are smaller than eight K. If we are reading a pipe,
+ we want to make sure the input buffer is bigger than the kernel's
+ pipe buffer. */
+ pipe_buf = -1;
+
+ if (! S_ISREG (st->st_mode))
+ {
+#ifdef _PC_PIPE_BUF
+ pipe_buf = fpathconf (fd, _PC_PIPE_BUF);
+#endif
+ if (pipe_buf == -1)
+ {
+#ifdef PIPE_BUF
+ pipe_buf = PIPE_BUF;
+#else
+ pipe_buf = 8192;
+#endif
+ }
+ }
+
+ if (pipe_buf < 8192)
+ pipe_buf = 8192;
+ /* PIPE_BUF bytes of buffer proper, 2 to detect running off the end
+ without address arithmetic all the time, and 2 for pushback in
+ the case there's a potential trigraph or end-of-line digraph at
+ the end of a block. */
+
+ tmp = (U_CHAR *) xmalloc (pipe_buf + 2 + 2);
+ pfile->input_buffer = tmp;
+ pfile->input_buffer_len = pipe_buf;
+}
+
/* Add output to `deps_buffer' for the -M switch.
STRING points to the text to be output.
SPACER is ':' for targets, ' ' for dependencies, zero for text
void
deps_output (pfile, string, spacer)
cpp_reader *pfile;
- char *string;
+ const char *string;
int spacer;
{
int size;
if (pfile->deps_column > 0
&& (pfile->deps_column + size) > MAX_OUTPUT_COLUMNS)
{
- size += 5;
- cr = 1;
+ cr = 5;
pfile->deps_column = 0;
}
- if (pfile->deps_size + size + 8 > pfile->deps_allocated_size)
+ if (pfile->deps_size + size + cr + 8 > pfile->deps_allocated_size)
{
pfile->deps_allocated_size = (pfile->deps_size + size + 50) * 2;
pfile->deps_buffer = (char *) xrealloc (pfile->deps_buffer,
Guarantees no trailing slashes. All transforms reduce the length
of the string.
*/
-static void
+void
simplify_pathname (path)
char *path;
{
char *base;
int absolute = 0;
-#if defined _WIN32 || defined __MSDOS__
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
/* Convert all backslashes to slashes. */
for (from = path; *from; from++)
if (*from == '\\') *from = '/';