| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 | ;;; ob-eval.el --- Babel Functions for External Code Evaluation -*- lexical-binding: t; -*-;; Copyright (C) 2009-2018 Free Software Foundation, Inc.;; Author: Eric Schulte;; Keywords: literate programming, reproducible research, comint;; Homepage: http://orgmode.org;; This file is part of GNU Emacs.;; GNU Emacs is free software: you can redistribute it and/or modify;; it under the terms of the GNU General Public License as published by;; the Free Software Foundation, either version 3 of the License, or;; (at your option) any later version.;; GNU Emacs is distributed in the hope that it will be useful,;; but WITHOUT ANY WARRANTY; without even the implied warranty of;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the;; GNU General Public License for more details.;; You should have received a copy of the GNU General Public License;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.;;; Commentary:;; These functions build existing Emacs support for executing external;; shell commands.;;; Code:(require 'org-macs)(defvar org-babel-error-buffer-name "*Org-Babel Error Output*")(declare-function org-babel-temp-file "ob-core" (prefix &optional suffix))(defun org-babel-eval-error-notify (exit-code stderr)  "Open a buffer to display STDERR and a message with the value of EXIT-CODE."  (let ((buf (get-buffer-create org-babel-error-buffer-name)))    (with-current-buffer buf      (goto-char (point-max))      (save-excursion (insert stderr)))    (display-buffer buf))  (message "Babel evaluation exited with code %S" exit-code))(defun org-babel-eval (cmd body)  "Run CMD on BODY.If CMD succeeds then return its results, otherwise displaySTDERR with `org-babel-eval-error-notify'."  (let ((err-buff (get-buffer-create " *Org-Babel Error*")) exit-code)    (with-current-buffer err-buff (erase-buffer))    (with-temp-buffer      (insert body)      (setq exit-code	    (org-babel--shell-command-on-region	     (point-min) (point-max) cmd err-buff))      (if (or (not (numberp exit-code)) (> exit-code 0))	  (progn	    (with-current-buffer err-buff	      (org-babel-eval-error-notify exit-code (buffer-string)))	    (save-excursion	      (when (get-buffer org-babel-error-buffer-name)		(with-current-buffer org-babel-error-buffer-name		  (unless (derived-mode-p 'compilation-mode)		    (compilation-mode))		  ;; Compilation-mode enforces read-only, but Babel expects the buffer modifiable.		  (setq buffer-read-only nil))))	    nil)	(buffer-string)))))(defun org-babel-eval-read-file (file)  "Return the contents of FILE as a string."  (with-temp-buffer (insert-file-contents file)		    (buffer-string)))(defun org-babel--shell-command-on-region (start end command error-buffer)  "Execute COMMAND in an inferior shell with region as input.Stripped down version of shell-command-on-region for internal usein Babel only.  This lets us work around errors in the originalfunction in various versions of Emacs."  (let ((input-file (org-babel-temp-file "ob-input-"))	(error-file (if error-buffer (org-babel-temp-file "ob-error-") nil))	;; Unfortunately, `executable-find' does not support file name	;; handlers.  Therefore, we could use it in the local case	;; only.	(shell-file-name	 (cond ((and (not (file-remote-p default-directory))		     (executable-find shell-file-name))		shell-file-name)	       ((file-executable-p		 (concat (file-remote-p default-directory) shell-file-name))		shell-file-name)	       ("/bin/sh")))	exit-status)    ;; There is an error in `process-file' when `error-file' exists.    ;; This is fixed in Emacs trunk as of 2012-12-21; let's use this    ;; workaround for now.    (unless (file-remote-p default-directory)      (delete-file error-file))    ;; we always call this with 'replace, remove conditional    ;; Replace specified region with output from command.    (let ((swap (< start end)))      (goto-char start)      (push-mark (point) 'nomsg)      (write-region start end input-file)      (delete-region start end)      (setq exit-status	    (process-file shell-file-name input-file			  (if error-file			      (list t error-file)			    t)			  nil shell-command-switch command))      (when swap (exchange-point-and-mark)))    (when (and input-file (file-exists-p input-file)	       ;; bind org-babel--debug-input around the call to keep	       ;; the temporary input files available for inspection	       (not (when (boundp 'org-babel--debug-input)		      org-babel--debug-input)))      (delete-file input-file))    (when (and error-file (file-exists-p error-file))      (when (< 0 (nth 7 (file-attributes error-file)))	(with-current-buffer (get-buffer-create error-buffer)	  (let ((pos-from-end (- (point-max) (point))))	    (or (bobp)		(insert "\f\n"))	    ;; Do no formatting while reading error file,	    ;; because that can run a shell command, and we	    ;; don't want that to cause an infinite recursion.	    (format-insert-file error-file nil)	    ;; Put point after the inserted errors.	    (goto-char (- (point-max) pos-from-end)))	  (current-buffer)))      (delete-file error-file))    exit-status))(defun org-babel-eval-wipe-error-buffer ()  "Delete the contents of the Org code block error buffer.This buffer is named by `org-babel-error-buffer-name'."  (when (get-buffer org-babel-error-buffer-name)    (with-current-buffer org-babel-error-buffer-name      (delete-region (point-min) (point-max)))))(provide 'ob-eval);;; ob-eval.el ends here
 |