Mercurial > hg > xemacs-beta
diff lisp/win32-native.el @ 442:abe6d1db359e r21-2-36
Import from CVS: tag r21-2-36
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:35:02 +0200 |
parents | |
children | 5aa1854ad537 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lisp/win32-native.el Mon Aug 13 11:35:02 2007 +0200 @@ -0,0 +1,280 @@ +;;; win32-native.el --- Lisp routines for MS Windows. + +;; Copyright (C) 1994 Free Software Foundation, Inc. +;; Copyright (C) 2000 Ben Wing. + +;; Maintainer: XEmacs Development Team +;; Keywords: mouse, dumped + +;; This file is part of XEmacs. + +;; XEmacs 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 2, or (at your option) +;; any later version. + +;; XEmacs 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 XEmacs; see the file COPYING. If not, write to the +;; Free Software Foundation, 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Synched up with: Not synched with FSF. Almost completely divergent. +;;; (FSF has stuff in w32-fns.el and term/w32-win.el.) + +;;; Commentary: + +;; This file is dumped with XEmacs for MS Windows (without cygwin). + +;; Based on NT Emacs version by Geoff Voelker (voelker@cs.washington.edu) +;; Ported to XEmacs by Marc Paquette <marcpa@cam.org> +;; Largely modified by Kirill M. Katsnelson <kkm@kis.ru> + +;;; Code: + +;; The cmd.exe shell uses the "/c" switch instead of the "-c" switch +;; for executing its command line argument (from simple.el). +;; #### Oh if we had an alist of shells and their command switches. +(setq shell-command-switch "/c") + +;; For appending suffixes to directories and files in shell +;; completions. This screws up cygwin users so we leave it out for +;; now. Uncomment this if you only ever want to use cmd. + +;(defun nt-shell-mode-hook () +; (setq comint-completion-addsuffix '("\\" . " ") +; comint-process-echoes t)) +;(add-hook 'shell-mode-hook 'nt-shell-mode-hook) + +;; Use ";" instead of ":" as a path separator (from files.el). +(setq path-separator ";") + +;; Set the null device (for compile.el). +;; #### There should be such a global thingy as null-device - kkm +(setq grep-null-device "NUL") + +;; Set the grep regexp to match entries with drive letters. +(setq grep-regexp-alist + '(("^\\(\\([a-zA-Z]:\\)?[^:( \t\n]+\\)[:( \t]+\\([0-9]+\\)[:) \t]" 1 3))) + +;;---------------------------------------------------------------------- +;; Autosave hack +;;-------------------- + +;; Avoid creating auto-save file names containing invalid characters +;; (primarily "*", eg. for the *mail* buffer). +;; Avoid "doc lost for function" warning +(defun original-make-auto-save-file-name (&optional junk) + "You do not want to call this." + ) +(fset 'original-make-auto-save-file-name + (symbol-function 'make-auto-save-file-name)) + +(defun make-auto-save-file-name () + "Return file name to use for auto-saves of current buffer. +Does not consider `auto-save-visited-file-name' as that variable is checked +before calling this function. You can redefine this for customization. +See also `auto-save-file-name-p'." + (let ((name (original-make-auto-save-file-name)) + (start 0)) + ;; destructively replace occurrences of * or ? with $ + (while (string-match "[?*]" name start) + (aset name (match-beginning 0) ?$) + (setq start (1+ (match-end 0)))) + name)) + +;;---------------------------------------------------------------------- +;; Quoting process args +;;-------------------- + +(defvar debug-mswindows-process-command-lines nil + "If non-nil, output debug information about the command lines constructed. +This can be useful if you are getting process errors where the arguments +to the process appear to be getting passed incorrectly.") + +;; properly quotify one arg for the vc runtime argv constructor. +(defun mswindows-quote-one-vc-runtime-arg (arg &optional quote-shell) + ;; we mess with any arg with whitespace, quotes, or globbing chars in it. + ;; we also include shell metachars if asked. + ;; note that \ is NOT included! it's perfectly OK to include an + ;; arg like c:\ or c:\foo. + (if (string-match (if quote-shell "[ \t\n\r\f*?\"<>|&^%]" "[ \t\n\r\f*?\"]") + arg) + (progn + ;; handle nested quotes, possibly preceded by backslashes + (setq arg (replace-in-string arg "\\([\\]*\\)\"" "\\1\\1\\\\\"")) + ;; handle trailing backslashes + (setq arg (replace-in-string arg "\\([\\]+\\)$" "\\1\\1")) + (concat "\"" arg "\"")) + arg)) + +(defun mswindows-quote-one-simple-arg (arg &optional quote-shell) + ;; just put double quotes around args with spaces (and maybe shell + ;; metachars). + (if (string-match (if quote-shell "[ \t\n\r\f*?\"<>|&^%]" "[ \t\n\r\f*?]") + arg) + (concat "\"" arg "\"") + arg)) + +(defun mswindows-quote-one-command-arg (arg) + ;; quote an arg to get it past COMMAND.COM/CMD.EXE: need to quote shell + ;; metachars with ^. + (replace-in-string "[<>|&^%]" "^\\1" arg)) + +(defun mswindows-construct-verbatim-command-line (program args) + (mapconcat #'identity args " ")) + +;; for use with either standard VC++ compiled programs or Cygwin programs, +;; which emulate the same behavior. +(defun mswindows-construct-vc-runtime-command-line (program args) + (mapconcat #'mswindows-quote-one-vc-runtime-arg args " ")) + +;; note: for pulling apart an arg: +;; each arg consists of either + +;; something surrounded by single quotes + +;; or + +;; one or more of + +;; 1. a non-ws, non-" char +;; 2. a section of double-quoted text +;; 3. a section of double-quoted text with end-of-string instead of the final +;; quote. + +;; 2 and 3 get handled together. + +;; quoted text is one of +;; +;; 1. quote + even number of backslashes + quote, or +;; 2. quote + non-greedy anything + non-backslash + even number of +;; backslashes + quote. + +;; we need to separate the two because we unfortunately have no non-greedy +;; ? operator. (urk! we actually do, but it wasn't documented.) --ben + +;; if you want to mess around, keep this test case in mind: + +;; this string + +;; " as'f 'FOO BAR' '' \"\" \"asdf \\ \\\" \\\\\\\" asdfasdf\\\\\" foo\" " + +;; should tokenize into this: + +;; (" " "as'f" " " "'FOO BAR' " "'' " "\"\"" " " "\"asdf \\ \\\" \\\\\\\" asdfasdf\\\\\"" " " "foo" "\" ") + +;; this regexp actually separates the arg into individual args, like a +;; shell (such as sh) does, but using vc-runtime rules. it's easy to +;; derive the tokenizing regexp from it, and that's exactly what i did. +;; but oh was it hard to get this first regexp right. --ben +;(defvar mswindows-match-one-cmd-exe-arg-regexp +; (concat +; "^\\(" +; "'\\([\\]*\\)\\2'" "\\|" +; "'.*?[^\\]\\(\\([\\]*\\)\\4'\\)" "\\|" +; "\\(" +; "[^ \t\n\r\f\v\"]" "\\|" +; "\"\\([\\]*\\)\\6\"" "\\|" +; "\".*?[^\\]\\(\\([\\]*\\)\\8\"\\|$\\)" +; "\\)+" +; "\\)" +; "\\([ \t\n\r\f\v]+\\|$\\)")) + +(defvar mswindows-match-one-cmd-exe-token-regexp + (concat + "^\\(" + "[ \t\n\r\f\v]+" "\\|" + "'\\([\\]*\\)\\2'" "\\([ \t\n\r\f\v]+\\|$\\)" "\\|" + "'.*?[^\\]\\(\\([\\]*\\)\\5'\\)" "\\([ \t\n\r\f\v]+\\|$\\)" "\\|" + "[^ \t\n\r\f\v\"]+" "\\|" + "\"\\([\\]*\\)\\7\"" "\\|" + "\".*?[^\\]\\(\\([\\]*\\)\\9\"\\|$\\)" + "\\)")) + +(defun mswindows-construct-command-command-line (program args) + ;; for use with COMMAND.COM and CMD.EXE: + ;; for each arg, tokenize it into quoted and non-quoted sections; + ;; then quote all the shell meta-chars with ^; then put everything + ;; back together. the truly hard part is the tokenizing -- typically + ;; we get a single argument (the command to execute) and we have to + ;; worry about quotes that are backslash-quoted and such. + (mapconcat + #'(lambda (arg) + (mapconcat + #'(lambda (part) + (if (string-match "^'" part) + (replace-in-string part "\\([<>|^&%]\\)" "^\\1") + part)) + (let (parts) + (while (and (> (length arg) 0) + (string-match + mswindows-match-one-cmd-exe-token-regexp + arg)) + (push (match-string 0 arg) parts) + (setq arg (substring arg (match-end 0)))) + (if (> (length arg) 0) + (push arg parts)) + (nreverse parts)) + "")) + args " ")) + +(defvar mswindows-construct-process-command-line-alist + '(("[\\/].?.?sh\\." . mswindows-construct-verbatim-command-line) + ("[\\/]command\\.com$" . mswindows-construct-command-command-line) + ("[\\/]cmd\\.exe$" . mswindows-construct-command-command-line) + ("" . mswindows-construct-vc-runtime-command-line)) + "An alist for determining proper argument quoting given executable +file name. Car of each cons should be a string, a regexp against +which the file name is matched. Matching is case-insensitive but does +include the directory, so you should begin your regexp with [\\\\/] if +you don't want the directory to matter. Alternatively, the car can be +a function of one arg, which is called with the executable's name and +should return t if this entry should be processed. Cdr is a function +symbol, which is called with two args, the executable name and a list +of the args passed to it. It should return a string, which includes +the executable's args (but not the executable name itself) properly +quoted and pasted together. The list is matched in order, and the +first matching entry specifies how the processing will happen.") + +(defun mswindows-construct-process-command-line (args) + ;;Properly quote process ARGS for executing (car ARGS). + ;;Called from the C code. + (let ((fname (car args)) + (alist mswindows-construct-process-command-line-alist) + (case-fold-search t) + (return-me nil) + (assoc nil)) + (while (and alist + (null return-me)) + (setq assoc (pop alist)) + (if (if (stringp (car assoc)) + (string-match (car assoc) fname) + (funcall (car assoc) fname)) + (setq return-me (cdr assoc)))) + (let* ((called-fun (or return-me + #'mswindows-construct-vc-runtime-command-line)) + (retval + (let ((str (funcall called-fun fname (cdr args))) + (quoted-fname (mswindows-quote-one-simple-arg fname))) + (if (and str (> (length str) 0)) + (concat quoted-fname " " str) + quoted-fname)))) + (when debug-mswindows-process-command-lines + (debug-print "mswindows-construct-process-command-line called:\n") + (debug-print "received args: \n%s" + (let ((n -1)) + (mapconcat #'(lambda (arg) + (incf n) + (format " %d %s\n" n arg)) + args + ""))) + (debug-print "called fun %s\n" called-fun) + (debug-print "resulting command line: %s\n" retval)) + retval))) + +;;; win32-native.el ends here