Mercurial > emacs
comparison lisp/files.el @ 84440:2311575b5cd3
(file-modes-char-to-who, file-modes-char-to-right)
(file-modes-rights-to-number): Auxiliary functions for symbolic to
numeric notation of file modes.
(file-modes-symbolic-to-number): New. Convert symbolic modes to its
numeric value.
(read-file-modes): New. Read either an octal value of a file mode or a
symbolic value, and return its numeric value.
author | Michaël Cadilhac <michael.cadilhac@lrde.org> |
---|---|
date | Mon, 10 Sep 2007 09:51:25 +0000 |
parents | d2159c231849 |
children | 04f3172e88f3 |
comparison
equal
deleted
inserted
replaced
84439:aed070a1f09b | 84440:2311575b5cd3 |
---|---|
5405 (setq buffer-file-name (concat "/:" buffer-file-name)) | 5405 (setq buffer-file-name (concat "/:" buffer-file-name)) |
5406 res)) | 5406 res)) |
5407 (t | 5407 (t |
5408 (apply operation arguments))))) | 5408 (apply operation arguments))))) |
5409 | 5409 |
5410 ;; Symbolic modes and read-file-modes. | |
5411 | |
5412 (defun file-modes-char-to-who (char) | |
5413 "Convert CHAR to a who-mask from a symbolic mode notation. | |
5414 CHAR is in [ugoa] and represents the users on which rights are applied." | |
5415 (cond ((= char ?u) #o4700) | |
5416 ((= char ?g) #o2070) | |
5417 ((= char ?o) #o1007) | |
5418 ((= char ?a) #o7777) | |
5419 (t (error "%c: bad `who' character" char)))) | |
5420 | |
5421 (defun file-modes-char-to-right (char &optional from) | |
5422 "Convert CHAR to a right-mask from a symbolic mode notation. | |
5423 CHAR is in [rwxXstugo] and represents a right. | |
5424 If CHAR is in [Xugo], the value is extracted from FROM (or 0 if nil)." | |
5425 (or from (setq from 0)) | |
5426 (cond ((= char ?r) #o0444) | |
5427 ((= char ?w) #o0222) | |
5428 ((= char ?x) #o0111) | |
5429 ((= char ?s) #o1000) | |
5430 ((= char ?t) #o6000) | |
5431 ;; Rights relative to the previous file modes. | |
5432 ((= char ?X) (if (= (logand from #o111) 0) 0 #o0111)) | |
5433 ((= char ?u) (let ((uright (logand #o4700 from))) | |
5434 (+ uright (/ uright #o10) (/ uright #o100)))) | |
5435 ((= char ?g) (let ((gright (logand #o2070 from))) | |
5436 (+ gright (/ gright #o10) (* gright #o10)))) | |
5437 ((= char ?o) (let ((oright (logand #o1007 from))) | |
5438 (+ oright (* oright #o10) (* oright #o100)))) | |
5439 (t (error "%c: bad right character" char)))) | |
5440 | |
5441 (defun file-modes-rights-to-number (rights who-mask &optional from) | |
5442 "Convert a right string to a right-mask from a symbolic modes notation. | |
5443 RIGHTS is the right string, it should match \"([+=-][rwxXstugo]+)+\". | |
5444 WHO-MASK is the mask number of the users on which the rights are to be applied. | |
5445 FROM (or 0 if nil) is the orginal modes of the file to be chmod'ed." | |
5446 (let* ((num-rights (or from 0)) | |
5447 (list-rights (string-to-list rights)) | |
5448 (op (pop list-rights))) | |
5449 (while (memq op '(?+ ?- ?=)) | |
5450 (let ((num-right 0) | |
5451 char-right) | |
5452 (while (memq (setq char-right (pop list-rights)) | |
5453 '(?r ?w ?x ?X ?s ?t ?u ?g ?o)) | |
5454 (setq num-right | |
5455 (logior num-right | |
5456 (file-modes-char-to-right char-right num-rights)))) | |
5457 (setq num-right (logand who-mask num-right) | |
5458 num-rights | |
5459 (cond ((= op ?+) (logior num-rights num-right)) | |
5460 ((= op ?-) (logand num-rights (lognot num-right))) | |
5461 (t (logior (logand num-rights (lognot who-mask)) num-right))) | |
5462 op char-right))) | |
5463 num-rights)) | |
5464 | |
5465 (defun file-modes-symbolic-to-number (modes &optional from) | |
5466 "Convert symbolic file modes to numeric file modes. | |
5467 MODES is the string to convert, it should match | |
5468 \"[ugoa]*([+-=][rwxXstugo]+)+,...\". | |
5469 See (info \"(coreutils)File permissions\") for more information on this | |
5470 notation. | |
5471 FROM (or 0 if nil) is the orginal modes of the file to be chmod'ed." | |
5472 (save-match-data | |
5473 (let ((case-fold-search nil) | |
5474 (num-modes (or from 0))) | |
5475 (while (/= (string-to-char modes) 0) | |
5476 (if (string-match "^\\([ugoa]*\\)\\([+=-][rwxXstugo]+\\)+\\(,\\|\\)" modes) | |
5477 (let ((num-who (apply 'logior 0 | |
5478 (mapcar 'file-modes-char-to-who | |
5479 (match-string 1 modes))))) | |
5480 (when (= num-who 0) | |
5481 (setq num-who (default-file-modes))) | |
5482 (setq num-modes | |
5483 (file-modes-rights-to-number (substring modes (match-end 1)) | |
5484 num-who num-modes) | |
5485 modes (substring modes (match-end 3)))) | |
5486 (error "Parse error in modes near `%s'" (substring modes 0)))) | |
5487 num-modes))) | |
5488 | |
5489 (defun read-file-modes (&optional prompt orig-file) | |
5490 "Read file modes in octal or symbolic notation. | |
5491 PROMPT is used as the prompt, default to `File modes (octal or symbolic): '. | |
5492 ORIG-FILE is the original file of which modes will be change." | |
5493 (let* ((modes (or (if orig-file (file-modes orig-file) 0) | |
5494 (error "File not found"))) | |
5495 (value (read-string (or prompt "File modes (octal or symbolic): ")))) | |
5496 (save-match-data | |
5497 (if (string-match "^[0-7]+" value) | |
5498 (string-to-number value 8) | |
5499 (file-modes-symbolic-to-number value modes))))) | |
5500 | |
5501 | |
5410 (define-key ctl-x-map "\C-f" 'find-file) | 5502 (define-key ctl-x-map "\C-f" 'find-file) |
5411 (define-key ctl-x-map "\C-r" 'find-file-read-only) | 5503 (define-key ctl-x-map "\C-r" 'find-file-read-only) |
5412 (define-key ctl-x-map "\C-v" 'find-alternate-file) | 5504 (define-key ctl-x-map "\C-v" 'find-alternate-file) |
5413 (define-key ctl-x-map "\C-s" 'save-buffer) | 5505 (define-key ctl-x-map "\C-s" 'save-buffer) |
5414 (define-key ctl-x-map "s" 'save-some-buffers) | 5506 (define-key ctl-x-map "s" 'save-some-buffers) |