This commit was manufactured by cvs2svn to create branch 'apel-shubit'.
[elisp/apel.git] / poe-18.el
1 ;;; poe-18.el --- poe API implementation for Emacs 18.*
2
3 ;; Copyright (C) 1995,1996,1997,1998,1999 Free Software Foundation, Inc.
4 ;; Copyright (C) 1999 Yuuichi Teranishi
5
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
10
11 ;; This file is part of APEL (A Portable Emacs Library).
12
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.
17
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.
22
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.
27
28 ;;; Commentary:
29
30 ;; Note to APEL developers and APEL programmers:
31 ;;
32 ;; If old (v18) compiler is used, top-level macros are expanded at
33 ;; *load-time*, not compile-time. Therefore,
34 ;;
35 ;; (1) Definitions with `*-maybe' won't be compiled.
36 ;;
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.)
42 ;;
43 ;; (3) `eval-when-compile' and `eval-and-compile' are evaluated at
44 ;;     load-time if used at top-level.
45
46 ;;; Code:
47
48 (require 'pym)
49
50
51 ;;; @ Compilation.
52 ;;;
53
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."
57   (fset sym newdef))
58
59 (defun byte-code-function-p (object)
60   "Return t if OBJECT is a byte-compiled function object."
61   (and (consp object)
62        (let ((rest (cdr (cdr object)))
63              elt)
64          (if (stringp (car rest))
65              (setq rest (cdr rest)))
66          (catch 'tag
67            (while rest
68              (setq elt (car rest))
69              (if (and (consp elt)
70                       (eq (car elt) 'byte-code))
71                  (throw 'tag t))
72              (setq rest (cdr rest)))))))
73
74 ;; (symbol-plist 'cyclic-function-indirection)
75 (put 'cyclic-function-indirection
76      'error-conditions
77      '(cyclic-function-indirection error))
78 (put 'cyclic-function-indirection
79      'error-message
80      "Symbol's chain of function indirections contains a loop")
81
82 ;; The following function definition is a direct translation of its
83 ;; C definition in emacs-20.4/src/data.c.
84 (defun indirect-function (object)
85   "Return the function at the end of OBJECT's function chain.
86 If OBJECT is a symbol, follow all function indirections and return the final
87 function binding.
88 If OBJECT is not a symbol, just return it.
89 Signal a void-function error if the final symbol is unbound.
90 Signal a cyclic-function-indirection error if there is a loop in the
91 function chain of symbols."
92   (let* ((hare object)
93          (tortoise hare))
94     (catch 'found
95       (while t
96         (or (symbolp hare) (throw 'found hare))
97         (or (fboundp hare) (signal 'void-function (cons object nil)))
98         (setq hare (symbol-function hare))
99         (or (symbolp hare) (throw 'found hare))
100         (or (fboundp hare) (signal 'void-function (cons object nil)))
101         (setq hare (symbol-function hare))
102
103         (setq tortoise (symbol-function tortoise))
104
105         (if (eq hare tortoise)
106             (signal 'cyclic-function-indirection (cons object nil)))))
107     hare))
108
109 ;;; Emulate all functions and macros of emacs-20.3/lisp/byte-run.el.
110 ;;; (note: jwz's original compiler and XEmacs compiler have some more
111 ;;;  macros; they are "nuked" by rms in FSF version.)
112
113 ;; Use `*-maybe' here because new byte-compiler may be installed.
114 (put 'inline 'lisp-indent-hook 0)
115 (defmacro-maybe inline (&rest body)
116   "Eval BODY forms sequentially and return value of last one.
117
118 This emulating macro does not support function inlining because old \(v18\)
119 compiler does not support inlining feature."
120   (cons 'progn body))
121
122 (put 'defsubst 'lisp-indent-hook 'defun)
123 (put 'defsubst 'edebug-form-spec 'defun)
124 (defmacro-maybe defsubst (name arglist &rest body)
125   "Define an inline function.  The syntax is just like that of `defun'.
126
127 This emulating macro does not support function inlining because old \(v18\)
128 compiler does not support inlining feature."
129   (cons 'defun (cons name (cons arglist body))))
130
131 (defun-maybe make-obsolete (fn new)
132   "Make the byte-compiler warn that FUNCTION is obsolete.
133 The warning will say that NEW should be used instead.
134 If NEW is a string, that is the `use instead' message.
135
136 This emulating function does nothing because old \(v18\) compiler does not
137 support this feature."
138   (interactive "aMake function obsolete: \nxObsoletion replacement: ")
139   fn)
140
141 (defun-maybe make-obsolete-variable (var new)
142   "Make the byte-compiler warn that VARIABLE is obsolete,
143 and NEW should be used instead.  If NEW is a string, then that is the
144 `use instead' message.
145
146 This emulating function does nothing because old \(v18\) compiler does not
147 support this feature."
148   (interactive "vMake variable obsolete: \nxObsoletion replacement: ")
149   var)
150
151 (put 'dont-compile 'lisp-indent-hook 0)
152 (defmacro-maybe dont-compile (&rest body)
153   "Like `progn', but the body always runs interpreted \(not compiled\).
154 If you think you need this, you're probably making a mistake somewhere."
155   (list 'eval (list 'quote (if (cdr body) (cons 'progn body) (car body)))))
156
157 (put 'eval-when-compile 'lisp-indent-hook 0)
158 (defmacro-maybe eval-when-compile (&rest body)
159   "Like progn, but evaluates the body at compile-time.
160
161 This emulating macro does not do compile-time evaluation at all because
162 of the limitation of old \(v18\) compiler."
163   (cons 'progn body))
164
165 (put 'eval-and-compile 'lisp-indent-hook 0)
166 (defmacro-maybe eval-and-compile (&rest body)
167   "Like progn, but evaluates the body at compile-time as well as at load-time.
168
169 This emulating macro does not do compile-time evaluation at all because
170 of the limitation of old \(v18\) compiler."
171   (cons 'progn body))
172
173
174 ;;; @ C primitives emulation.
175 ;;;
176
177 (defun member (elt list)
178   "Return non-nil if ELT is an element of LIST.  Comparison done with EQUAL.
179 The value is actually the tail of LIST whose car is ELT."
180   (while (and list (not (equal elt (car list))))
181     (setq list (cdr list)))
182   list)
183
184 (defun delete (elt list)
185   "Delete by side effect any occurrences of ELT as a member of LIST.
186 The modified LIST is returned.  Comparison is done with `equal'.
187 If the first member of LIST is ELT, deleting it is not a side effect;
188 it is simply using a different list.
189 Therefore, write `(setq foo (delete element foo))'
190 to be sure of changing the value of `foo'."
191   (if list
192       (if (equal elt (car list))
193           (cdr list)
194         (let ((rest list)
195               (rrest (cdr list)))
196           (while (and rrest (not (equal elt (car rrest))))
197             (setq rest rrest
198                   rrest (cdr rrest)))
199           (setcdr rest (cdr rrest))
200           list))))
201
202 (defun default-boundp (symbol)
203   "Return t if SYMBOL has a non-void default value.
204 This is the value that is seen in buffers that do not have their own values
205 for this variable."
206   (condition-case error
207       (progn
208         (default-value symbol)
209         t)
210     (void-variable nil)))
211
212 ;;; @@ current-time.
213 ;;;
214
215 (or (fboundp 'si:current-time-string)
216     (fset 'si:current-time-string (symbol-function 'current-time-string)))
217 (defun current-time-string (&optional specified-time)
218   "Return the current time, as a human-readable string.
219 Programs can use this function to decode a time,
220 since the number of columns in each field is fixed.
221 The format is `Sun Sep 16 01:03:52 1973'.
222 If an argument is given, it specifies a time to format
223 instead of the current time.  The argument should have the form:
224   (HIGH . LOW)
225 or the form:
226   (HIGH LOW . IGNORED).
227 Thus, you can use times obtained from `current-time'
228 and from `file-attributes'."
229   (if (null specified-time)
230       (si:current-time-string)
231     (or (consp specified-time)
232         (error "Wrong type argument %s" specified-time))
233     (let ((high (car specified-time))
234           (low  (cdr specified-time))
235           (mdays '(31 28 31 30 31 30 31 31 30 31 30 31))
236           (mnames '("Jan" "Feb" "Mar" "Apr" "May" "Jun" 
237                     "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"))
238           (wnames '("Sun" "Mon" "Tue" "Wed" "Thu" "Fri" "Sat"))
239           days dd yyyy lyear mm HH MM SS)
240       (if (consp low)
241           (setq low (car low)))
242       (or (integerp high)
243           (error "Wrong type argument %s" high))
244       (or (integerp low)
245           (error "Wrong type argument %s" low))
246       (setq low (+ low 32400))
247       (while (> low 65535)
248         (setq high (1+ high)
249               low (- low 65536)))
250       (setq yyyy 1970)
251       (while (or (> high 481)
252                  (and (= high 481)
253                       (>= low 13184)))
254         (if (and (> high 0)
255                  (< low 13184))
256             (setq high (1- high)
257                   low  (+ 65536 low)))
258         (setq high (- high 481)
259               low  (- low 13184))
260         (if (and (zerop (% yyyy 4))
261                  (or (not (zerop (% yyyy 100)))
262                      (zerop (% yyyy 400))))
263             (progn
264               (if (and (> high 0) 
265                        (< low 20864))
266                   (setq high (1- high)
267                         low  (+ 65536 low)))
268               (setq high (- high 1)
269                     low (- low 20864))))
270         (setq yyyy (1+ yyyy)))
271       (setq dd 1)
272       (while (or (> high 1)
273                  (and (= high 1)
274                       (>= low 20864)))
275         (if (and (> high 0)
276                  (< low 20864))
277             (setq high (1- high)
278                   low  (+ 65536 low)))
279         (setq high (- high 1)
280               low  (- low 20864)
281               dd (1+ dd)))
282       (setq days dd)
283       (if (= high 1)
284           (setq low (+ 65536 low)))
285       (setq mm 0)
286       (setq lyear (and (zerop (% yyyy 4))
287                        (or (not (zerop (% yyyy 100)))
288                            (zerop (% yyyy 400)))))
289       (while (> (- dd (nth mm mdays)) 0)
290         (if (and (= mm 1) lyear)
291             (setq dd (- dd 29))
292           (setq dd (- dd (nth mm mdays))))
293         (setq mm (1+ mm)))
294       (setq HH (/ low 3600)
295             low (% low 3600)
296             MM (/ low 60)
297             SS (% low 60))
298       (format "%s %s %2d %02d:%02d:%02d %4d"
299               (nth (% (+ days
300                          (- (+ (* (1- yyyy) 365) (/ (1- yyyy) 400) 
301                                (/ (1- yyyy) 4)) (/ (1- yyyy) 100))) 7)
302                    wnames)
303               (nth mm mnames)
304               dd HH MM SS yyyy))))
305
306 (defun current-time ()
307   "Return the current time, as the number of seconds since 1970-01-01 00:00:00.
308 The time is returned as a list of three integers.  The first has the
309 most significant 16 bits of the seconds, while the second has the
310 least significant 16 bits.  The third integer gives the microsecond
311 count.
312
313 The microsecond count is zero on systems that do not provide
314 resolution finer than a second."
315   (let* ((str (current-time-string))
316          (yyyy (string-to-int (substring str 20 24)))
317          (mm (length (member (substring str 4 7)
318                              '("Dec" "Nov" "Oct" "Sep" "Aug" "Jul"
319                                "Jun" "May" "Apr" "Mar" "Feb" "Jan"))))
320          (dd (string-to-int (substring str 8 10)))
321          (HH (string-to-int (substring str 11 13)))
322          (MM (string-to-int (substring str 14 16)))
323          (SS (string-to-int (substring str 17 19)))
324          dn ct1 ct2 i1 i2
325          year uru)
326     (setq ct1 0 ct2 0 i1 0 i2 0)
327     (setq year (- yyyy 1970))
328     (while (> year 0)
329       (setq year (1- year)
330             ct1 (+ ct1 481)
331             ct2 (+ ct2 13184))
332       (while (> ct2 65535)
333         (setq ct1 (1+ ct1)
334               ct2 (- ct2 65536))))
335     (setq uru (- (+ (- (/ yyyy 4) (/ yyyy 100)) 
336                     (/ yyyy 400)) 477))
337     (while (> uru 0)
338       (setq uru (1- uru)
339             i1 (1+ i1)
340             i2 (+ i2 20864))
341       (if (> i2 65535)
342           (setq i1 (1+ i1)
343                 i2 (- i2 65536))))
344     (setq ct1 (+ ct1 i1)
345           ct2 (+ ct2 i2))
346     (while (> ct2 65535)
347       (setq ct1 (1+ ct1)
348             ct2 (- ct2 65536)))
349     (setq dn (+ dd (* 31 (1- mm))))
350     (if (> mm 2)
351         (setq dn (+ (- dn (/ (+ 23 (* 4 mm)) 10))
352                     (if (and (zerop (% yyyy 4))
353                              (or (not (zerop (% yyyy 100)))
354                                  (zerop (% yyyy 400))))
355                         1 0))))
356     (setq dn (1- dn)
357           i1 0 
358           i2 0)
359     (while (> dn 0)
360       (setq dn (1- dn)
361             i1 (1+ i1)
362             i2 (+ i2 20864))
363       (if (> i2 65535)
364           (setq i1 (1+ i1)
365                 i2 (- i2 65536))))
366     (setq ct1 (+ (+ (+ ct1 i1) (/ ct2 65536)) 
367                  (/ (+ (* HH 3600) (* MM 60) SS)
368                     65536))
369           ct2 (+ (+ i2 (% ct2 65536))
370                  (% (+ (* HH 3600) (* MM 60) SS)
371                     65536)))
372     (while (< (- ct2 32400) 0)
373       (setq ct1 (1- ct1)
374             ct2 (+ ct2 65536)))
375     (setq ct2 (- ct2 32400))
376     (while (> ct2 65535)
377       (setq ct1 (1+ ct1)
378             ct2 (- ct2 65536)))
379     (list ct1 ct2 0)))
380
381 ;;; @@ Floating point numbers.
382 ;;;
383
384 (defalias 'numberp 'integerp)
385
386 (defun abs (arg)
387   "Return the absolute value of ARG."
388   (if (< arg 0) (- arg) arg))
389
390
391 ;;; @ Basic lisp subroutines.
392 ;;;
393
394 (defmacro lambda (&rest cdr)
395   "Return a lambda expression.
396 A call of the form (lambda ARGS DOCSTRING INTERACTIVE BODY) is
397 self-quoting; the result of evaluating the lambda expression is the
398 expression itself.  The lambda expression may then be treated as a
399 function, i.e., stored as the function value of a symbol, passed to
400 funcall or mapcar, etc.
401
402 ARGS should take the same form as an argument list for a `defun'.
403 DOCSTRING is an optional documentation string.
404  If present, it should describe how to call the function.
405  But documentation strings are usually not useful in nameless functions.
406 INTERACTIVE should be a call to the function `interactive', which see.
407 It may also be omitted.
408 BODY should be a list of lisp expressions."
409   ;; Note that this definition should not use backquotes; subr.el should not
410   ;; depend on backquote.el.
411   (list 'function (cons 'lambda cdr)))
412
413 (defun force-mode-line-update (&optional all)
414   "Force the mode-line of the current buffer to be redisplayed.
415 With optional non-nil ALL, force redisplay of all mode-lines."
416   (if all (save-excursion (set-buffer (other-buffer))))
417   (set-buffer-modified-p (buffer-modified-p)))
418
419 ;; (defalias 'save-match-data 'store-match-data)
420
421
422 ;;; @ Basic editing commands.
423 ;;;
424
425 ;; 18.55 does not have this variable.
426 (defvar buffer-undo-list nil)
427
428 (defalias 'buffer-disable-undo 'buffer-flush-undo)
429
430 (defun generate-new-buffer-name (name &optional ignore)
431   "Return a string that is the name of no existing buffer based on NAME.
432 If there is no live buffer named NAME, then return NAME.
433 Otherwise modify name by appending `<NUMBER>', incrementing NUMBER
434 until an unused name is found, and then return that name.
435 Optional second argument IGNORE specifies a name that is okay to use
436 \(if it is in the sequence to be tried\)
437 even if a buffer with that name exists."
438   (if (get-buffer name)
439       (let ((n 2) new)
440         (while (get-buffer (setq new (format "%s<%d>" name n)))
441           (setq n (1+ n)))
442         new)
443     name))
444
445 (or (fboundp 'si:mark)
446     (fset 'si:mark (symbol-function 'mark)))
447 (defun mark (&optional force)
448   (si:mark))
449
450
451 ;;; @@ Environment variables.
452 ;;;
453
454 (autoload 'setenv "env"
455   "Set the value of the environment variable named VARIABLE to VALUE.
456 VARIABLE should be a string.  VALUE is optional; if not provided or is
457 `nil', the environment variable VARIABLE will be removed.
458 This function works by modifying `process-environment'."
459   t)
460
461
462 ;;; @ File input and output commands.
463 ;;;
464
465 (defvar data-directory exec-directory)
466
467 ;; In 18.55, `call-process' does not return exit status.
468 (defun file-executable-p (filename)
469   "Return t if FILENAME can be executed by you.
470 For a directory, this means you can access files in that directory."
471   (if (file-exists-p filename)
472       (let ((process (start-process "test" nil "test" "-x" filename)))
473         (while (eq 'run (process-status process)))
474         (zerop (process-exit-status process)))))
475
476 (defun make-directory-internal (dirname)
477   "Create a directory. One argument, a file name string."
478  (let ((dir (expand-file-name dirname)))
479    (if (file-exists-p dir)
480        (error "Creating directory: %s is already exist" dir)
481      (call-process "mkdir" nil nil nil dir))))
482
483 (defun make-directory (dir &optional parents)
484   "Create the directory DIR and any nonexistent parent dirs.
485 The second (optional) argument PARENTS says whether
486 to create parent directories if they don't exist."
487   (let ((len (length dir))
488         (p 0) p1 path)
489     (catch 'tag
490       (while (and (< p len) (string-match "[^/]*/?" dir p))
491         (setq p1 (match-end 0))
492         (if (= p1 len)
493             (throw 'tag nil))
494         (setq path (substring dir 0 p1))
495         (if (not (file-directory-p path))
496             (cond ((file-exists-p path)
497                    (error "Creating directory: %s is not directory" path))
498                   ((null parents)
499                    (error "Creating directory: %s is not exist" path))
500                   (t
501                    (make-directory-internal path))))
502         (setq p p1)))
503     (make-directory-internal dir)))
504
505 (defun parse-colon-path (cd-path)
506   "Explode a colon-separated list of paths into a string list."
507   (and cd-path
508        (let (cd-prefix cd-list (cd-start 0) cd-colon)
509          (setq cd-path (concat cd-path path-separator))
510          (while (setq cd-colon (string-match path-separator cd-path cd-start))
511            (setq cd-list
512                  (nconc cd-list
513                         (list (if (= cd-start cd-colon)
514                                   nil
515                                 (substitute-in-file-name
516                                  (file-name-as-directory
517                                   (substring cd-path cd-start cd-colon)))))))
518            (setq cd-start (+ cd-colon 1)))
519          cd-list)))
520
521 (defun file-relative-name (filename &optional directory)
522   "Convert FILENAME to be relative to DIRECTORY (default: default-directory)."
523   (setq filename (expand-file-name filename)
524         directory (file-name-as-directory (expand-file-name
525                                            (or directory default-directory))))
526   (let ((ancestor ""))
527     (while (not (string-match (concat "^" (regexp-quote directory)) filename))
528       (setq directory (file-name-directory (substring directory 0 -1))
529             ancestor (concat "../" ancestor)))
530     (concat ancestor (substring filename (match-end 0)))))
531
532 (or (fboundp 'si:directory-files)
533     (fset 'si:directory-files (symbol-function 'directory-files)))
534 (defun directory-files (directory &optional full match nosort)
535   "Return a list of names of files in DIRECTORY.
536 There are three optional arguments:
537 If FULL is non-nil, return absolute file names.  Otherwise return names
538  that are relative to the specified directory.
539 If MATCH is non-nil, mention only file names that match the regexp MATCH.
540 If NOSORT is dummy for compatibility."
541   (si:directory-files directory full match))
542
543
544 ;;; @ Text property.
545 ;;;
546
547 ;; In Emacs 20.4, these functions are defined in src/textprop.c.
548 (defun text-properties-at (position &optional object))
549 (defun get-text-property (position prop &optional object))
550 (defun get-char-property (position prop &optional object))
551 (defun next-property-change (position &optional object limit))
552 (defun next-single-property-change (position prop &optional object limit))
553 (defun previous-property-change (position &optional object limit))
554 (defun previous-single-property-change (position prop &optional object limit))
555 (defun add-text-properties (start end properties &optional object))
556 (defun put-text-properties (start end property &optional object))
557 (defun set-text-properties (start end properties &optional object))
558 (defun remove-text-properties (start end properties &optional object))
559 (defun text-property-any (start end property value &optional object))
560 (defun text-property-not-all (start end property value &optional object))
561 ;; the following two functions are new in v20.
562 (defun next-char-property-change (position &optional object))
563 (defun previous-char-property-change (position &optional object))
564 ;; the following two functions are obsolete.
565 ;; (defun erase-text-properties (start end &optional object)
566 ;; (defun copy-text-properties (start end src pos dest &optional prop)
567
568
569 ;;; @ Overlay.
570 ;;;
571
572 (cond
573  ((boundp 'NEMACS)
574   (defvar emu:available-face-attribute-alist
575     '(
576       ;;(bold      . inversed-region)
577       (italic    . underlined-region)
578       (underline . underlined-region)))
579
580   ;; by YAMATE Keiichirou 1994/10/28
581   (defun attribute-add-narrow-attribute (attr from to)
582     (or (consp (symbol-value attr))
583         (set attr (list 1)))
584     (let* ((attr-value (symbol-value attr))
585            (len (car attr-value))
586            (posfrom 1)
587            posto)
588       (while (and (< posfrom len)
589                   (> from (nth posfrom attr-value)))
590         (setq posfrom (1+ posfrom)))
591       (setq posto posfrom)
592       (while (and (< posto len)
593                   (> to (nth posto attr-value)))
594         (setq posto (1+ posto)))
595       (if  (= posto posfrom)
596           (if (= (% posto 2) 1)
597               (if (and (< to len)
598                        (= to (nth posto attr-value)))
599                   (set-marker (nth posto attr-value) from)
600                 (setcdr (nthcdr (1- posfrom) attr-value)
601                         (cons (set-marker-type (set-marker (make-marker)
602                                                            from)
603                                                'point-type)
604                               (cons (set-marker-type
605                                      (set-marker (make-marker)
606                                                  to)
607                                      nil)
608                                     (nthcdr posto attr-value))))
609                 (setcar attr-value (+ len 2))))
610         (if (= (% posfrom 2) 0)
611             (setq posfrom (1- posfrom))
612           (set-marker (nth posfrom attr-value) from))
613         (if (= (% posto 2) 0)
614             nil
615           (setq posto (1- posto))
616           (set-marker (nth posto attr-value) to))
617         (setcdr (nthcdr posfrom attr-value)
618                 (nthcdr posto attr-value)))))
619
620   (defalias 'make-overlay 'cons)
621
622   (defun overlay-put (overlay prop value)
623     (let ((ret (and (eq prop 'face)
624                     (assq value emu:available-face-attribute-alist))))
625       (if ret
626           (attribute-add-narrow-attribute (cdr ret)
627                                           (car overlay)(cdr overlay))))))
628  (t
629   (defun make-overlay (beg end &optional buffer type))
630   (defun overlay-put (overlay prop value))))
631
632 (defun overlay-buffer (overlay))
633
634
635 ;;; @ End.
636 ;;;
637
638 (provide 'poe-18)
639
640 ;;; poe-18.el ends here