From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?UTF-8?q?=E5=AE=8B=E6=96=87=E6=AD=A6?= Subject: [PATCH 1/3] utils: Add 'edit-expression'. Date: Wed, 6 Apr 2016 18:37:24 +0800 Message-ID: <1459939046-10573-1-git-send-email-iyzsong@gmail.com> Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:52990) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ankqb-0001ZO-TY for guix-devel@gnu.org; Wed, 06 Apr 2016 06:38:06 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ankqX-0007vT-Sd for guix-devel@gnu.org; Wed, 06 Apr 2016 06:38:05 -0400 Received: from smtp24.openmailbox.org ([62.4.1.58]:48464) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ankqX-0007vA-MY for guix-devel@gnu.org; Wed, 06 Apr 2016 06:38:01 -0400 List-Id: "Development of GNU Guix and the GNU System distribution." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-devel-bounces+gcggd-guix-devel=m.gmane.org@gnu.org Sender: guix-devel-bounces+gcggd-guix-devel=m.gmane.org@gnu.org To: guix-devel@gnu.org Cc: =?UTF-8?q?=E5=AE=8B=E6=96=87=E6=AD=A6?= * guix/utils.scm (edit-expression): New procedure. * tests/utils.scm (edit-expression): New test. --- guix/utils.scm | 37 +++++++++++++++++++++++++++++++++++++ tests/utils.scm | 13 +++++++++++++ 2 files changed, 50 insertions(+) diff --git a/guix/utils.scm b/guix/utils.scm index de54179..1318dac 100644 --- a/guix/utils.scm +++ b/guix/utils.scm @@ -86,6 +86,7 @@ split cache-directory readlink* + edit-expression filtered-port compressed-port @@ -318,6 +319,42 @@ a list of command-line arguments passed to the compression program." (unless (every (compose zero? cdr waitpid) pids) (error "compressed-output-port failure" pids)))))) +(define* (edit-expression source-properties proc #:key (encoding "UTF-8")) + "Edit the expression specified by SOURCE-PROPERTIES using PROC, which should +be a procedure that take the original expression in string and returns a new +one. ENCODING will be used to interpret all port I/O, it default to UTF-8." + (with-fluids ((%default-port-encoding encoding)) + (let*-values (((file line column) + (values + (assoc-ref source-properties 'filename) + (assoc-ref source-properties 'line) + (assoc-ref source-properties 'column))) + ((start end) ; start and end byte positions of the expression + (call-with-input-file file + (lambda (port) + (values + (begin (while (not (and (= line (port-line port)) + (= column (port-column port)))) + (when (eof-object? (read-char port)) + (error 'end-of-file file))) + (ftell port)) + (begin (read port) + (ftell port)))))) + ((pre-bv expr post-bv) + (call-with-input-file file + (lambda (port) + (values (get-bytevector-n port start) + (get-string-n port (- end start)) + (get-bytevector-all port)))))) + (with-atomic-file-output file + (lambda (port) + (put-bytevector port pre-bv) + (display (proc expr) port) + ;; post-bv maybe the end-of-file object. + (when (not (eof-object? post-bv)) + (put-bytevector port post-bv)) + #t))))) + ;;; ;;; Advisory file locking. diff --git a/tests/utils.scm b/tests/utils.scm index 6b77255..d0ee02a 100644 --- a/tests/utils.scm +++ b/tests/utils.scm @@ -333,6 +333,19 @@ "This is a journey\r\nInto the sound\r\nA journey ...\n"))) (get-string-all (canonical-newline-port port)))) + +(test-equal "edit-expression" + "(display \"GNU Guix\")\n(newline)\n" + (begin + (call-with-output-file temp-file + (lambda (port) + (display "(display \"xiuG UNG\")\n(newline)\n" port))) + (edit-expression `((filename . ,temp-file) + (line . 0) + (column . 9)) + string-reverse) + (call-with-input-file temp-file get-string-all))) + (test-end) (false-if-exception (delete-file temp-file)) -- 2.6.3