+ run_directive (pfile, type, BUF_CL_OPTION, str, count);
+}
+
+/* Push a new buffer on the buffer stack. Returns the new buffer; it
+ doesn't fail. It does not generate a file change call back; that
+ is the responsibility of the caller. */
+cpp_buffer *
+cpp_push_buffer (pfile, buffer, len, type, filename)
+ cpp_reader *pfile;
+ const U_CHAR *buffer;
+ size_t len;
+ enum cpp_buffer_type type;
+ const char *filename;
+{
+ cpp_buffer *new = xobnew (pfile->buffer_ob, cpp_buffer);
+
+ if (type == BUF_FAKE)
+ {
+ /* A copy of the current buffer, just with a new name and type. */
+ memcpy (new, pfile->buffer, sizeof (cpp_buffer));
+ new->type = BUF_FAKE;
+ }
+ else
+ {
+ if (type == BUF_BUILTIN)
+ filename = _("<builtin>");
+ else if (type == BUF_CL_OPTION)
+ filename = _("<command line>");
+ else if (type == BUF_PRAGMA)
+ filename = "<_Pragma>";
+
+ /* Clears, amongst other things, if_stack and mi_cmacro. */
+ memset (new, 0, sizeof (cpp_buffer));
+
+ new->line_base = new->buf = new->cur = buffer;
+ new->rlimit = buffer + len;
+ new->sysp = 0;
+
+ /* No read ahead or extra char initially. */
+ new->read_ahead = EOF;
+ new->extra_char = EOF;
+
+ /* Preprocessed files, builtins, _Pragma and command line
+ options don't do trigraph and escaped newline processing. */
+ new->from_stage3 = type != BUF_FILE || CPP_OPTION (pfile, preprocessed);
+
+ pfile->lexer_pos.output_line = 1;
+ }
+
+ new->nominal_fname = filename;
+ new->type = type;
+ new->prev = pfile->buffer;
+ new->pfile = pfile;
+ new->include_stack_listed = 0;
+ new->lineno = 1;
+
+ pfile->state.next_bol = 1;
+ pfile->buffer_stack_depth++;
+ pfile->buffer = new;
+
+ return new;
+}
+
+/* If called from do_line, pops a single buffer. Otherwise pops all
+ buffers until a real file is reached. Generates appropriate
+ call-backs. */
+cpp_buffer *
+cpp_pop_buffer (pfile)
+ cpp_reader *pfile;
+{
+ cpp_buffer *buffer;
+ struct if_stack *ifs;
+
+ for (;;)
+ {
+ buffer = pfile->buffer;
+ /* Walk back up the conditional stack till we reach its level at
+ entry to this file, issuing error messages. */
+ for (ifs = buffer->if_stack; ifs; ifs = ifs->next)
+ cpp_error_with_line (pfile, ifs->pos.line, ifs->pos.col,
+ "unterminated #%s", dtable[ifs->type].name);
+
+ if (buffer->type == BUF_FAKE)
+ buffer->prev->cur = buffer->cur;
+ else if (buffer->type == BUF_FILE)
+ _cpp_pop_file_buffer (pfile, buffer);
+
+ pfile->buffer = buffer->prev;
+ pfile->buffer_stack_depth--;
+
+ /* Callbacks only generated for faked or real files. */
+ if (buffer->type != BUF_FILE && buffer->type != BUF_FAKE)
+ break;
+
+ /* No callback for EOF of last file. */
+ if (!pfile->buffer)
+ break;
+
+ /* do_line does its own call backs. */
+ pfile->buffer->include_stack_listed = 0;
+ if (pfile->directive == &dtable[T_LINE])
+ break;
+
+ _cpp_do_file_change (pfile, FC_LEAVE, buffer->nominal_fname,
+ buffer->lineno);
+ if (pfile->buffer->type == BUF_FILE)
+ break;
+
+ cpp_warning (pfile, "file \"%s\" entered but not left",
+ buffer->nominal_fname);
+ }
+
+ obstack_free (pfile->buffer_ob, buffer);
+ return pfile->buffer;
+}
+
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free free
+void
+_cpp_init_stacks (pfile)