1 ;;; poe-18.el --- poe API implementation for Emacs 18.*
3 ;; Copyright (C) 1995,1996,1997,1998,1999 Free Software Foundation, Inc.
4 ;; Copyright (C) 1999 Yuuichi Teranishi
6 ;; Author: MORIOKA Tomohiko <tomo@m17n.org>
7 ;; Shuhei KOBAYASHI <shuhei@aqua.ocn.ne.jp>
8 ;; Yuuichi Teranishi <teranisi@gohome.org>
9 ;; Keywords: emulation, compatibility
11 ;; This file is part of APEL (A Portable Emacs Library).
13 ;; This program is free software; you can redistribute it and/or
14 ;; modify it under the terms of the GNU General Public License as
15 ;; published by the Free Software Foundation; either version 2, or (at
16 ;; your option) any later version.
18 ;; This program is distributed in the hope that it will be useful, but
19 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 ;; General Public License for more details.
23 ;; You should have received a copy of the GNU General Public License
24 ;; along with this program; see the file COPYING. If not, write to the
25 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
26 ;; Boston, MA 02111-1307, USA.
30 ;; Note to APEL developers and APEL programmers:
32 ;; If old (v18) compiler is used, top-level macros are expanded at
33 ;; *load-time*, not compile-time. Therefore,
35 ;; (1) Definitions with `*-maybe' won't be compiled.
37 ;; (2) you cannot use macros defined with `defmacro-maybe' within function
38 ;; definitions in the same file.
39 ;; (`defmacro-maybe' is evaluated at load-time, therefore byte-compiler
40 ;; treats such use of macros as (unknown) functions and compiles them
41 ;; into function calls, which will cause errors at run-time.)
43 ;; (3) `eval-when-compile' and `eval-and-compile' are evaluated at
44 ;; load-time if used at top-level.
54 (defun defalias (sym newdef)
55 "Set SYMBOL's function definition to NEWVAL, and return NEWVAL.
56 Associates the function with the current load file, if any."
59 (defun byte-code-function-p (exp)
60 "T if OBJECT is a byte-compiled function object."
62 (let ((rest (cdr (cdr exp)))
64 (if (stringp (car rest))
65 (setq rest (cdr rest)))
70 (eq (car elt) 'byte-code))
72 (setq rest (cdr rest)))))))
74 ;;; Emulate all functions and macros of emacs-20.3/lisp/byte-run.el.
75 ;;; (note: jwz's original compiler and XEmacs compiler have some more
76 ;;; macros; they are "nuked" by rms in FSF version.)
78 ;; Use `*-maybe' here because new byte-compiler may be installed.
79 (put 'inline 'lisp-indent-hook 0)
80 (defmacro-maybe inline (&rest body)
81 "Eval BODY forms sequentially and return value of last one.
83 This emulating macro does not support function inlining because old \(v18\)
84 compiler does not support inlining feature."
87 (put 'defsubst 'lisp-indent-hook 'defun)
88 (put 'defsubst 'edebug-form-spec 'defun)
89 (defmacro-maybe defsubst (name arglist &rest body)
90 "Define an inline function. The syntax is just like that of `defun'.
92 This emulating macro does not support function inlining because old \(v18\)
93 compiler does not support inlining feature."
94 (cons 'defun (cons name (cons arglist body))))
96 (defun-maybe make-obsolete (fn new)
97 "Make the byte-compiler warn that FUNCTION is obsolete.
98 The warning will say that NEW should be used instead.
99 If NEW is a string, that is the `use instead' message.
101 This emulating function does nothing because old \(v18\) compiler does not
102 support this feature."
103 (interactive "aMake function obsolete: \nxObsoletion replacement: ")
106 (defun-maybe make-obsolete-variable (var new)
107 "Make the byte-compiler warn that VARIABLE is obsolete,
108 and NEW should be used instead. If NEW is a string, then that is the
109 `use instead' message.
111 This emulating function does nothing because old \(v18\) compiler does not
112 support this feature."
113 (interactive "vMake variable obsolete: \nxObsoletion replacement: ")
116 (put 'dont-compile 'lisp-indent-hook 0)
117 (defmacro-maybe dont-compile (&rest body)
118 "Like `progn', but the body always runs interpreted \(not compiled\).
119 If you think you need this, you're probably making a mistake somewhere."
120 (list 'eval (list 'quote (if (cdr body) (cons 'progn body) (car body)))))
122 (put 'eval-when-compile 'lisp-indent-hook 0)
123 (defmacro-maybe eval-when-compile (&rest body)
124 "Like progn, but evaluates the body at compile-time.
126 This emulating macro does not do compile-time evaluation at all because
127 of the limitation of old \(v18\) compiler."
130 (put 'eval-and-compile 'lisp-indent-hook 0)
131 (defmacro-maybe eval-and-compile (&rest body)
132 "Like progn, but evaluates the body at compile-time as well as at load-time.
134 This emulating macro does not do compile-time evaluation at all because
135 of the limitation of old \(v18\) compiler."
139 ;;; @ C primitives emulation.
142 (defun member (elt list)
143 "Return non-nil if ELT is an element of LIST. Comparison done with EQUAL.
144 The value is actually the tail of LIST whose car is ELT."
145 (while (and list (not (equal elt (car list))))
146 (setq list (cdr list)))
149 (defun delete (elt list)
150 "Delete by side effect any occurrences of ELT as a member of LIST.
151 The modified LIST is returned. Comparison is done with `equal'.
152 If the first member of LIST is ELT, deleting it is not a side effect;
153 it is simply using a different list.
154 Therefore, write `(setq foo (delete element foo))'
155 to be sure of changing the value of `foo'."
157 (if (equal elt (car list))
161 (while (and rrest (not (equal elt (car rrest))))
164 (setcdr rest (cdr rrest))
167 (defun default-boundp (symbol)
168 "Return t if SYMBOL has a non-void default value.
169 This is the value that is seen in buffers that do not have their own values
171 (condition-case error
173 (default-value symbol)
175 (void-variable nil)))
180 (or (fboundp 'si:current-time-string)
181 (fset 'si:current-time-string (symbol-function 'current-time-string)))
182 (defun current-time-string (&optional specified-time)
183 "Return the current time, as a human-readable string.
184 Programs can use this function to decode a time,
185 since the number of columns in each field is fixed.
186 The format is `Sun Sep 16 01:03:52 1973'.
187 If an argument is given, it specifies a time to format
188 instead of the current time. The argument should have the form:
191 (HIGH LOW . IGNORED).
192 Thus, you can use times obtained from `current-time'
193 and from `file-attributes'."
194 (if (null specified-time)
195 (si:current-time-string)
196 (or (consp specified-time)
197 (error "Wrong type argument %s" specified-time))
198 (let ((high (car specified-time))
199 (low (cdr specified-time))
200 (mdays '(31 28 31 30 31 30 31 31 30 31 30 31))
201 (mnames '("Jan" "Feb" "Mar" "Apr" "May" "Jun"
202 "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"))
203 (wnames '("Sun" "Mon" "Tue" "Wed" "Thu" "Fri" "Sat"))
204 days dd yyyy lyear mm HH MM SS)
206 (setq low (car low)))
208 (error "Wrong type argument %s" high))
210 (error "Wrong type argument %s" low))
211 (setq low (+ low 32400))
216 (while (or (> high 481)
223 (setq high (- high 481)
225 (if (and (zerop (% yyyy 4))
226 (or (not (zerop (% yyyy 100)))
227 (zerop (% yyyy 400))))
233 (setq high (- high 1)
235 (setq yyyy (1+ yyyy)))
237 (while (or (> high 1)
244 (setq high (- high 1)
249 (setq low (+ 65536 low)))
251 (setq lyear (and (zerop (% yyyy 4))
252 (or (not (zerop (% yyyy 100)))
253 (zerop (% yyyy 400)))))
254 (while (> (- dd (nth mm mdays)) 0)
255 (if (and (= mm 1) lyear)
257 (setq dd (- dd (nth mm mdays))))
259 (setq HH (/ low 3600)
263 (format "%s %s %2d %02d:%02d:%02d %4d"
265 (- (+ (* (1- yyyy) 365) (/ (1- yyyy) 400)
266 (/ (1- yyyy) 4)) (/ (1- yyyy) 100))) 7)
271 (defun current-time ()
272 "Return the current time, as the number of seconds since 1970-01-01 00:00:00.
273 The time is returned as a list of three integers. The first has the
274 most significant 16 bits of the seconds, while the second has the
275 least significant 16 bits. The third integer gives the microsecond
278 The microsecond count is zero on systems that do not provide
279 resolution finer than a second."
280 (let* ((str (current-time-string))
281 (yyyy (string-to-int (substring str 20 24)))
282 (mm (length (member (substring str 4 7)
283 '("Dec" "Nov" "Oct" "Sep" "Aug" "Jul"
284 "Jun" "May" "Apr" "Mar" "Feb" "Jan"))))
285 (dd (string-to-int (substring str 8 10)))
286 (HH (string-to-int (substring str 11 13)))
287 (MM (string-to-int (substring str 14 16)))
288 (SS (string-to-int (substring str 17 19)))
291 (setq ct1 0 ct2 0 i1 0 i2 0)
292 (setq year (- yyyy 1970))
300 (setq uru (- (+ (- (/ yyyy 4) (/ yyyy 100))
314 (setq dn (+ dd (* 31 (1- mm))))
316 (setq dn (+ (- dn (/ (+ 23 (* 4 mm)) 10))
317 (if (and (zerop (% yyyy 4))
318 (or (not (zerop (% yyyy 100)))
319 (zerop (% yyyy 400))))
331 (setq ct1 (+ (+ (+ ct1 i1) (/ ct2 65536))
332 (/ (+ (* HH 3600) (* MM 60) SS)
334 ct2 (+ (+ i2 (% ct2 65536))
335 (% (+ (* HH 3600) (* MM 60) SS)
337 (while (< (- ct2 32400) 0)
340 (setq ct2 (- ct2 32400))
347 ;;; @ Basic lisp subroutines.
350 (defmacro lambda (&rest cdr)
351 "Return a lambda expression.
352 A call of the form (lambda ARGS DOCSTRING INTERACTIVE BODY) is
353 self-quoting; the result of evaluating the lambda expression is the
354 expression itself. The lambda expression may then be treated as a
355 function, i.e., stored as the function value of a symbol, passed to
356 funcall or mapcar, etc.
358 ARGS should take the same form as an argument list for a `defun'.
359 DOCSTRING is an optional documentation string.
360 If present, it should describe how to call the function.
361 But documentation strings are usually not useful in nameless functions.
362 INTERACTIVE should be a call to the function `interactive', which see.
363 It may also be omitted.
364 BODY should be a list of lisp expressions."
365 ;; Note that this definition should not use backquotes; subr.el should not
366 ;; depend on backquote.el.
367 (list 'function (cons 'lambda cdr)))
369 (defun force-mode-line-update (&optional all)
370 "Force the mode-line of the current buffer to be redisplayed.
371 With optional non-nil ALL, force redisplay of all mode-lines."
372 (if all (save-excursion (set-buffer (other-buffer))))
373 (set-buffer-modified-p (buffer-modified-p)))
375 ;; (defalias 'save-match-data 'store-match-data)
378 ;;; @ Basic editing commands.
381 ;; 18.55 does not have this variable.
382 (defvar buffer-undo-list nil)
384 (defalias 'buffer-disable-undo 'buffer-flush-undo)
386 (defun generate-new-buffer-name (name &optional ignore)
387 "Return a string that is the name of no existing buffer based on NAME.
388 If there is no live buffer named NAME, then return NAME.
389 Otherwise modify name by appending `<NUMBER>', incrementing NUMBER
390 until an unused name is found, and then return that name.
391 Optional second argument IGNORE specifies a name that is okay to use
392 \(if it is in the sequence to be tried\)
393 even if a buffer with that name exists."
394 (if (get-buffer name)
396 (while (get-buffer (setq new (format "%s<%d>" name n)))
401 (or (fboundp 'si:mark)
402 (fset 'si:mark (symbol-function 'mark)))
403 (defun mark (&optional force)
407 ;;; @@ Environment variables.
410 (autoload 'setenv "env"
411 "Set the value of the environment variable named VARIABLE to VALUE.
412 VARIABLE should be a string. VALUE is optional; if not provided or is
413 `nil', the environment variable VARIABLE will be removed.
414 This function works by modifying `process-environment'."
418 ;;; @ File input and output commands.
421 (defvar data-directory exec-directory)
423 ;; In 18.55, `call-process' does not return exit status.
424 (defun file-executable-p (filename)
425 "Return t if FILENAME can be executed by you.
426 For a directory, this means you can access files in that directory."
427 (if (file-exists-p filename)
428 (let ((process (start-process "test" nil "test" "-x" filename)))
429 (while (eq 'run (process-status process)))
430 (zerop (process-exit-status process)))))
432 (defun make-directory-internal (dirname)
433 "Create a directory. One argument, a file name string."
434 (let ((dir (expand-file-name dirname)))
435 (if (file-exists-p dir)
436 (error "Creating directory: %s is already exist" dir)
437 (call-process "mkdir" nil nil nil dir))))
439 (defun make-directory (dir &optional parents)
440 "Create the directory DIR and any nonexistent parent dirs.
441 The second (optional) argument PARENTS says whether
442 to create parent directories if they don't exist."
443 (let ((len (length dir))
446 (while (and (< p len) (string-match "[^/]*/?" dir p))
447 (setq p1 (match-end 0))
450 (setq path (substring dir 0 p1))
451 (if (not (file-directory-p path))
452 (cond ((file-exists-p path)
453 (error "Creating directory: %s is not directory" path))
455 (error "Creating directory: %s is not exist" path))
457 (make-directory-internal path))))
459 (make-directory-internal dir)))
461 (defun parse-colon-path (cd-path)
462 "Explode a colon-separated list of paths into a string list."
464 (let (cd-prefix cd-list (cd-start 0) cd-colon)
465 (setq cd-path (concat cd-path path-separator))
466 (while (setq cd-colon (string-match path-separator cd-path cd-start))
469 (list (if (= cd-start cd-colon)
471 (substitute-in-file-name
472 (file-name-as-directory
473 (substring cd-path cd-start cd-colon)))))))
474 (setq cd-start (+ cd-colon 1)))
477 (defun file-relative-name (filename &optional directory)
478 "Convert FILENAME to be relative to DIRECTORY (default: default-directory)."
479 (setq filename (expand-file-name filename)
480 directory (file-name-as-directory (expand-file-name
481 (or directory default-directory))))
483 (while (not (string-match (concat "^" (regexp-quote directory)) filename))
484 (setq directory (file-name-directory (substring directory 0 -1))
485 ancestor (concat "../" ancestor)))
486 (concat ancestor (substring filename (match-end 0)))))
488 (or (fboundp 'si:directory-files)
489 (fset 'si:directory-files (symbol-function 'directory-files)))
490 (defun directory-files (directory &optional full match nosort)
491 "Return a list of names of files in DIRECTORY.
492 There are three optional arguments:
493 If FULL is non-nil, return absolute file names. Otherwise return names
494 that are relative to the specified directory.
495 If MATCH is non-nil, mention only file names that match the regexp MATCH.
496 If NOSORT is dummy for compatibility."
497 (si:directory-files directory full match))
503 ;; In Emacs 20.4, these functions are defined in src/textprop.c.
504 (defun text-properties-at (position &optional object))
505 (defun get-text-property (position prop &optional object))
506 (defun get-char-property (position prop &optional object))
507 (defun next-property-change (position &optional object limit))
508 (defun next-single-property-change (position prop &optional object limit))
509 (defun previous-property-change (position &optional object limit))
510 (defun previous-single-property-change (position prop &optional object limit))
511 (defun add-text-properties (start end properties &optional object))
512 (defun put-text-properties (start end property &optional object))
513 (defun set-text-properties (start end properties &optional object))
514 (defun remove-text-properties (start end properties &optional object))
515 (defun text-property-any (start end property value &optional object))
516 (defun text-property-not-all (start end property value &optional object))
517 ;; the following two functions are new in v20.
518 (defun next-char-property-change (position &optional object))
519 (defun previous-char-property-change (position &optional object))
520 ;; the following two functions are obsolete.
521 ;; (defun erase-text-properties (start end &optional object)
522 ;; (defun copy-text-properties (start end src pos dest &optional prop)
530 (defvar emu:available-face-attribute-alist
532 ;;(bold . inversed-region)
533 (italic . underlined-region)
534 (underline . underlined-region)))
536 ;; by YAMATE Keiichirou 1994/10/28
537 (defun attribute-add-narrow-attribute (attr from to)
538 (or (consp (symbol-value attr))
540 (let* ((attr-value (symbol-value attr))
541 (len (car attr-value))
544 (while (and (< posfrom len)
545 (> from (nth posfrom attr-value)))
546 (setq posfrom (1+ posfrom)))
548 (while (and (< posto len)
549 (> to (nth posto attr-value)))
550 (setq posto (1+ posto)))
551 (if (= posto posfrom)
552 (if (= (% posto 2) 1)
554 (= to (nth posto attr-value)))
555 (set-marker (nth posto attr-value) from)
556 (setcdr (nthcdr (1- posfrom) attr-value)
557 (cons (set-marker-type (set-marker (make-marker)
560 (cons (set-marker-type
561 (set-marker (make-marker)
564 (nthcdr posto attr-value))))
565 (setcar attr-value (+ len 2))))
566 (if (= (% posfrom 2) 0)
567 (setq posfrom (1- posfrom))
568 (set-marker (nth posfrom attr-value) from))
569 (if (= (% posto 2) 0)
571 (setq posto (1- posto))
572 (set-marker (nth posto attr-value) to))
573 (setcdr (nthcdr posfrom attr-value)
574 (nthcdr posto attr-value)))))
576 (defalias 'make-overlay 'cons)
578 (defun overlay-put (overlay prop value)
579 (let ((ret (and (eq prop 'face)
580 (assq value emu:available-face-attribute-alist))))
582 (attribute-add-narrow-attribute (cdr ret)
583 (car overlay)(cdr overlay))))))
585 (defun make-overlay (beg end &optional buffer type))
586 (defun overlay-put (overlay prop value))))
588 (defun overlay-buffer (overlay))
596 ;;; poe-18.el ends here