From: shuhei Date: Sat, 13 Nov 1999 11:37:17 +0000 (+0000) Subject: New file. X-Git-Tag: apel-shubit-10_0~26 X-Git-Url: http://git.chise.org/gitweb/?a=commitdiff_plain;h=50ed1440c8517e0582849735199c248bfb329242;p=elisp%2Fapel.git New file. (defun-maybe, defmacro-maybe, defsubst-maybe, defalias-maybe, defvar-maybe, defconst-maybe, defun-maybe-cond, defmacro-maybe-cond, def-edebug-spec): Moved from poe.el. (defsubst-maybe-cond): New macro. --- diff --git a/pym.el b/pym.el new file mode 100644 index 0000000..c37b738 --- /dev/null +++ b/pym.el @@ -0,0 +1,262 @@ +;;; pym.el --- Macros for Your Poe. + +;; Copyright (C) 1995,1996,1997,1998,1999 Free Software Foundation, Inc. + +;; Author: MORIOKA Tomohiko +;; Shuhei KOBAYASHI +;; Keywords: byte-compile, evaluation, edebug, internal + +;; This file is part of APEL (A Portable Emacs Library). + +;; This program 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. + +;; This program 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 GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; This module provides `def*-maybe' macros for conditional definition. +;; +;; Many APEL modules use these macros to provide emulation version of +;; Emacs builtins (both C primitives and lisp subroutines) for backward +;; compatibility. While compilation time, if `def*-maybe' find that +;; functions/variables being defined is already provided by Emacs used +;; for compilation, it does not leave the definitions in compiled code +;; and resulting .elc will be highly specialized for your environment. + +;; For `find-function' lovers, the following definitions may work with +;; `def*-maybe'. +;; +;; (setq find-function-regexp +;; "^\\s-*(def[^cgvW]\\(\\w\\|-\\)+\\*?\\s-+'?%s\\(\\s-\\|$\\)") +;; (setq find-variable-regexp +;; "^\\s-*(def[^umaW]\\(\\w\\|-\\)+\\*?\\s-+%s\\(\\s-\\|$\\)") +;; +;; I'm too lazy to write better regexps, sorry. -- shuhei + +;;; Code: + +(or (boundp 'current-load-list) (setq current-load-list nil)) + +;; we cannot use `eval-when-compile' here because v18 does not have it. +(require 'static) + + +;;; Conditional define. + +(put 'defun-maybe 'lisp-indent-function 'defun) +(defmacro defun-maybe (name &rest everything-else) + "Define NAME as a function if NAME is not defined. +See also the function `defun'." + (or (and (fboundp name) + (not (get name 'defun-maybe))) + (` (or (fboundp (quote (, name))) + (prog1 + (defun (, name) (,@ everything-else)) + ;; This `defun' will be compiled to `fset', which does + ;; not update `load-history'. + ;; We must update `current-load-list' explicitly. + (setq current-load-list + (cons (quote (, name)) current-load-list)) + (put (quote (, name)) 'defun-maybe t)))))) + +(put 'defmacro-maybe 'lisp-indent-function 'defun) +(defmacro defmacro-maybe (name &rest everything-else) + "Define NAME as a macro if NAME is not defined. +See also the function `defmacro'." + (or (and (fboundp name) + (not (get name 'defmacro-maybe))) + (` (or (fboundp (quote (, name))) + (prog1 + (defmacro (, name) (,@ everything-else)) + (setq current-load-list + (cons (quote (, name)) current-load-list)) + (put (quote (, name)) 'defmacro-maybe t)))))) + +(put 'defsubst-maybe 'lisp-indent-function 'defun) +(defmacro defsubst-maybe (name &rest everything-else) + "Define NAME as an inline function if NAME is not defined. +See also the macro `defsubst'." + (or (and (fboundp name) + (not (get name 'defsubst-maybe))) + (` (or (fboundp (quote (, name))) + (prog1 + (defsubst (, name) (,@ everything-else)) + (setq current-load-list + (cons (quote (, name)) current-load-list)) + (put (quote (, name)) 'defsubst-maybe t)))))) + +(defmacro defalias-maybe (symbol definition) + "Define SYMBOL as an alias for DEFINITION if SYMBOL is not defined. +See also the function `defalias'." + (setq symbol (eval symbol)) + (or (and (fboundp symbol) + (not (get symbol 'defalias-maybe))) + (` (or (fboundp (quote (, symbol))) + (prog1 + (defalias (quote (, symbol)) (, definition)) + (setq current-load-list + (cons (quote (, symbol)) current-load-list)) + (put (quote (, symbol)) 'defalias-maybe t)))))) + +(defmacro defvar-maybe (name &rest everything-else) + "Define NAME as a variable if NAME is not defined. +See also the function `defvar'." + (or (and (boundp name) + (not (get name 'defvar-maybe))) + (` (or (boundp (quote (, name))) + (prog1 + (defvar (, name) (,@ everything-else)) + ;; byte-compiler will generate code to update + ;; `load-history'. + (put (quote (, name)) 'defvar-maybe t)))))) + +(defmacro defconst-maybe (name &rest everything-else) + "Define NAME as a constant variable if NAME is not defined. +See also the function `defconst'." + (or (and (boundp name) + (not (get name 'defconst-maybe))) + (` (or (boundp (quote (, name))) + (prog1 + (defconst (, name) (,@ everything-else)) + (put (quote (, name)) 'defconst-maybe t)))))) + +(defmacro defun-maybe-cond (name args &optional doc &rest clauses) + "Define NAME as a function if NAME is not defined. +CLAUSES are like those of `cond' expression, but each condition is evaluated +at compile-time and, if the value is non-nil, the body of the clause is used +for function definition of NAME. +See also the function `defun'." + (or (stringp doc) + (setq clauses (cons doc clauses) + doc nil)) + (or (and (fboundp name) + (not (get name 'defun-maybe))) + (` (or (fboundp (quote (, name))) + (prog1 + (static-cond + (,@ (mapcar + (function + (lambda (case) + (list (car case) + (if doc + (` (defun (, name) (, args) + (, doc) + (,@ (cdr case)))) + (` (defun (, name) (, args) + (,@ (cdr case)))))))) + clauses))) + (setq current-load-list + (cons (quote (, name)) current-load-list)) + (put (quote (, name)) 'defun-maybe t)))))) + +(defmacro defmacro-maybe-cond (name args &optional doc &rest clauses) + "Define NAME as a macro if NAME is not defined. +CLAUSES are like those of `cond' expression, but each condition is evaluated +at compile-time and, if the value is non-nil, the body of the clause is used +for macro definition of NAME. +See also the function `defmacro'." + (or (stringp doc) + (setq clauses (cons doc clauses) + doc nil)) + (or (and (fboundp name) + (not (get name 'defmacro-maybe))) + (` (or (fboundp (quote (, name))) + (prog1 + (static-cond + (,@ (mapcar + (function + (lambda (case) + (list (car case) + (if doc + (` (defmacro (, name) (, args) + (, doc) + (,@ (cdr case)))) + (` (defmacro (, name) (, args) + (,@ (cdr case)))))))) + clauses))) + (setq current-load-list + (cons (quote (, name)) current-load-list)) + (put (quote (, name)) 'defmacro-maybe t)))))) + +(defmacro defsubst-maybe-cond (name args &optional doc &rest clauses) + "Define NAME as an inline function if NAME is not defined. +CLAUSES are like those of `cond' expression, but each condition is evaluated +at compile-time and, if the value is non-nil, the body of the clause is used +for function definition of NAME. +See also the macro `defsubst'." + (or (stringp doc) + (setq clauses (cons doc clauses) + doc nil)) + (or (and (fboundp name) + (not (get name 'defsubst-maybe))) + (` (or (fboundp (quote (, name))) + (prog1 + (static-cond + (,@ (mapcar + (function + (lambda (case) + (list (car case) + (if doc + (` (defsubst (, name) (, args) + (, doc) + (,@ (cdr case)))) + (` (defsubst (, name) (, args) + (,@ (cdr case)))))))) + clauses))) + (setq current-load-list + (cons (quote (, name)) current-load-list)) + (put (quote (, name)) 'defsubst-maybe t)))))) + + +;;; Edebug spec. + +;; `def-edebug-spec' is an autoloaded macro in v19 and later. +;; (Note that recent XEmacs provides "edebug" as a separate package.) +(defmacro-maybe def-edebug-spec (symbol spec) + "Set the edebug-form-spec property of SYMBOL according to SPEC. +Both SYMBOL and SPEC are unevaluated. The SPEC can be 0, t, a symbol +\(naming a function\), or a list." + (` (put (quote (, symbol)) 'edebug-form-spec (quote (, spec))))) + +;; edebug-spec for `def*-maybe' macros. +(def-edebug-spec defun-maybe defun) +(def-edebug-spec defmacro-maybe defmacro) +(def-edebug-spec defsubst-maybe defun) +(def-edebug-spec defun-maybe-cond + (&define name lambda-list + [&optional stringp] + [&rest ([¬ eval] [&rest sexp])] + [&optional (eval [&optional ("interactive" interactive)] def-body)] + &rest (&rest sexp))) +(def-edebug-spec defmacro-maybe-cond + (&define name lambda-list + [&rest ([¬ eval] [&rest sexp])] + [&optional (eval def-body)] + &rest (&rest sexp))) + +;; edebug-spec for `static-*' macros are also defined here. +;; XXX: not defined yet. FIXME! +;; (def-edebug-spec static-if ...) +;; (def-edebug-spec static-when ...) +;; (def-edebug-spec static-unless ...) +;; (def-edebug-spec static-condition-case ...) +;; (def-edebug-spec static-defconst ...) +;; (def-edebug-spec static-cond ...) + + +;;; End. + +(provide 'pym) + +;;; pym.el ends here