[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] feature/stdout-stderr-stream 957e9d2 3/3: Add support for
From: |
Phillip Lord |
Subject: |
[Emacs-diffs] feature/stdout-stderr-stream 957e9d2 3/3: Add support for standard input, output and error streams |
Date: |
Wed, 28 Dec 2016 16:38:12 +0000 (UTC) |
branch: feature/stdout-stderr-stream
commit 957e9d22cdc96b5dbac82f3cd1426409c544bb0a
Author: Phillip Lord <address@hidden>
Commit: Phillip Lord <address@hidden>
Add support for standard input, output and error streams
* doc/lispref/streams.texi: Update doc
* lisp/simple.el (external-standard-input): New function
* src/fns.c (external-standard-input-read-char,
external-standard-input-read-line): New functions
* src/print.c: (external-standard-output,
external-standard-input): New functions
---
doc/lispref/streams.texi | 29 +++++++++++++++++-----
lisp/simple.el | 15 +++++++++++
src/fns.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++
src/print.c | 39 ++++++++++++++---------------
4 files changed, 119 insertions(+), 26 deletions(-)
diff --git a/doc/lispref/streams.texi b/doc/lispref/streams.texi
index acc5400..63a6494 100644
--- a/doc/lispref/streams.texi
+++ b/doc/lispref/streams.texi
@@ -265,6 +265,20 @@ reader encountered the open parenthesis, decided that it
ended the
input, and unread it. Another attempt to read from the stream at this
point would read @samp{()} and return @code{nil}.
+One function that is specifically designed for use as an input stream
+is:
+
address@hidden @code{external-standard-input}
address@hidden external-standard-input &optional char
+This function reads a single character from the system standard input
+(as opposed to @var{standard-input}) and functions as a stream. Note,
+however, that if Emacs is running in a terminal its use can be
+unpredictable.
address@hidden defun
+
+As with @code{external-standard-output}, this function is
+predominately useful for debugging.
+
@node Input Functions
@section Input Functions
@@ -533,20 +547,23 @@ contents more clearly.
Two functions which are specifically designed for use as output
streams:
address@hidden @asis
address@hidden @code{stdout} output stream
address@hidden @var{stdout}
address@hidden external-standard-output
address@hidden @code{external-standard-output} output stream
Prints to the system standard output (as opposed to the
@var{standard-output}), regardless of whether Emacs is running
interactively or not.
address@hidden defun
address@hidden @var{stderr} output stream
address@hidden external-standard-error
address@hidden @code{external-standard-error} output stream
Prints to the system standard error, regardless of whether Emacs is
running interactively or not.
address@hidden table
address@hidden defun
These functions are predominately useful for debugging, as they are a
-mechanism for producing output that does not change any buffer.
+mechanism for producing output that does not change any buffer. Note,
+however, that if Emacs is running in a terminal their use can affect
+the display unpredictably.
@node Output Functions
diff --git a/lisp/simple.el b/lisp/simple.el
index a757876..17697f9 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -8718,6 +8718,21 @@ to capitalize ARG words."
(capitalize-region (region-beginning) (region-end))
(capitalize-word arg)))
+(defvar external-standard-input-pushback nil
+ "Pushback character for `external-standard-input'.")
+
+(defun external-standard-input (&optional char)
+ "Read a character from the system standard input.
+
+If CHAR is non-nil, then do not read but return CHAR
+on the next invocation."
+ (if char
+ (setq external-standard-input-pushback char)
+ (if (eq nil external-standard-input-pushback)
+ (external-standard-input-read-char)
+ (let ((rtn external-standard-input-pushback))
+ (setq external-standard-input-pushback nil)
+ rtn))))
(provide 'simple)
diff --git a/src/fns.c b/src/fns.c
index c318608..72a7e3a 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -5082,6 +5082,65 @@ If nil, use the current buffer." */ )
return make_digest_string (digest, SHA1_DIGEST_SIZE);
}
+DEFUN ("external-standard-input-read-char",Fexternal_standard_input_read_char,
Sexternal_standard_input_read_char, 0, 0, 0,
+ doc: /* Read a single character from the system standard input.
+
+Returns -1 if standard input is at the end.*/)
+ (void)
+{
+ int c;
+ Lisp_Object val;
+
+ c = getchar();
+ XSETINT(val,c);
+
+ return val;
+}
+
+DEFUN ("external-standard-input-read-line",
Fexternal_standard_input_read_line, Sexternal_standard_input_read_line, 0, 0, 0,
+ doc: /* Read a line from the system standard input.*/)
+ (void)
+{
+ ptrdiff_t size, len;
+ char *line;
+ Lisp_Object val;
+ int c;
+
+ val = Qnil;
+ size = 100;
+ len = 0;
+ line = xmalloc (size);
+
+ while ((c = getchar ()) != '\n' && c != '\r')
+ {
+ if (c == EOF)
+ {
+ if (errno != 0)
+ break;
+ }
+ else
+ {
+ if (len == size)
+ line = xpalloc (line, &size, 1, -1, sizeof *line);
+ line[len++] = c;
+ }
+ }
+
+ if (len || c == '\n' || c == '\r')
+ {
+ val = make_string (line, len);
+ xfree (line);
+ }
+ else
+ {
+ xfree (line);
+ error ("Error reading from stdin");
+ }
+
+ return val;
+}
+
+
void
syms_of_fns (void)
@@ -5249,4 +5308,7 @@ this variable. */);
defsubr (&Ssecure_hash);
defsubr (&Sbuffer_hash);
defsubr (&Slocale_info);
+ defsubr (&Sexternal_standard_input_read_char);
+ defsubr (&Sexternal_standard_input_read_line);
+
}
diff --git a/src/print.c b/src/print.c
index f5a38c3..25f0afb 100644
--- a/src/print.c
+++ b/src/print.c
@@ -264,24 +264,6 @@ printchar_to_stream (unsigned int ch, FILE *stream)
}
}
-DEFUN ("stdout", Fstdout, Sstdout, 1, 1, 0,
- doc: /* Output character CHARACTER to system standard output. */)
- (Lisp_Object character)
-{
- CHECK_NUMBER (character);
- printchar_to_stream (XINT(character), stdout);
- return character;
-}
-
-DEFUN ("stderr", Fstderr, Sstderr, 1, 1, 0,
- doc: /* Output character CHARACTER to system standard error. */)
- (Lisp_Object character)
-{
- CHECK_NUMBER (character);
- printchar_to_stream (XINT(character), stderr);
- return character;
-}
-
/* Print character CH using method FUN. FUN nil means print to
print_buffer. FUN t means print to echo area or stdout if
non-interactive. If FUN is neither nil nor t, call FUN with CH as
@@ -787,6 +769,22 @@ to make it write to the debugging output. */)
return character;
}
+DEFUN ("external-standard-output", Fexternal_standard_output,
Sexternal_standard_output, 1, 1, 0,
+ doc: /* Output character CHARACTER to system standard output. */)
+ (Lisp_Object character)
+{
+ CHECK_NUMBER (character);
+ printchar_to_stream (XINT(character), stdout);
+ return character;
+}
+
+DEFUN ("external-standard-error", Fexternal_standard_error,
Sexternal_standard_error, 1, 1, 0,
+ doc: /* Output character CHARACTER to system standard error. */)
+ (Lisp_Object character)
+{
+ return Fexternal_debugging_output (character);
+}
+
/* This function is never called. Its purpose is to prevent
print_output_debug_flag from being optimized away. */
@@ -2319,15 +2317,16 @@ priorities. */);
/* prin1_to_string_buffer initialized in init_buffer_once in buffer.c */
staticpro (&Vprin1_to_string_buffer);
- defsubr (&Sstdout);
- defsubr (&Sstderr);
defsubr (&Sprin1);
defsubr (&Sprin1_to_string);
defsubr (&Serror_message_string);
defsubr (&Sprinc);
defsubr (&Sprint);
defsubr (&Sterpri);
+ defsubr (&Sexternal_standard_output);
+ defsubr (&Sexternal_standard_error);
defsubr (&Swrite_char);
+
defsubr (&Sredirect_debugging_output);
DEFSYM (Qprint_escape_newlines, "print-escape-newlines");