]> git.eshelyaron.com Git - emacs.git/commitdiff
Support standard input, output and error streams feature/stdout-stderr-stream
authorPhillip Lord <phillip.lord@russet.org.uk>
Mon, 18 Jul 2016 22:28:05 +0000 (23:28 +0100)
committerPhillip Lord <phillip.lord@russet.org.uk>
Sat, 14 Jan 2017 12:07:27 +0000 (12:07 +0000)
* 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
lisp/simple.el
src/fns.c
src/print.c

index 41bc71e6aea0b4f05129afb22c0d80b94f478337..63a649476188706c4ca9b0637e766ddc6cb832ac 100644 (file)
@@ -142,7 +142,7 @@ A symbol as input stream is equivalent to the symbol's function
 definition (if any).
 @end table
 
-  Here is an example of reading from a stream that is a buffer, showing
+Here is an example of reading from a stream that is a buffer, showing
 where point is located before and after:
 
 @example
@@ -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:
+
+@cindex @code{external-standard-input}
+@defun 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.
+@end defun
+
+As with @code{external-standard-output}, this function is
+predominately useful for debugging.
+
 @node Input Functions
 @section Input Functions
 
@@ -530,6 +544,28 @@ Now we can put the output in the proper order by reversing the list:
 Calling @code{concat} converts the list to a string so you can see its
 contents more clearly.
 
+Two functions which are specifically designed for use as output
+streams:
+
+@defun external-standard-output
+@cindex @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.
+@end defun
+
+@defun external-standard-error
+@cindex @code{external-standard-error} output stream
+Prints to the system standard error, regardless of whether Emacs is
+running interactively or not.
+@end defun
+
+These functions are predominately useful for debugging, as they are a
+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
 @section Output Functions
 
index a757876328b5f61871c670d025752fe6438ed12a..17697f9be2b1c01a6eaaa2c4a7ac5a1ffdbdf580 100644 (file)
@@ -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))))
 \f
 
 (provide 'simple)
index c318608e4ceb7a741bc2c3bfd5b653956363823b..72a7e3ab8204b2779dc260e5205d24de77ce1a25 100644 (file)
--- 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;
+}
+
+
 \f
 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);
+
 }
index 5531210e1b8e6faad5704f0ae30ae722eb16df3f..25f0afbf9724c53f315f8316487051fba0e83abc 100644 (file)
@@ -769,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.  */
 
@@ -2307,7 +2323,10 @@ priorities.  */);
   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");