home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
browser2.zip
/
br-add.el
next >
Wrap
Lisp/Scheme
|
1995-02-17
|
8KB
|
235 lines
;;; CLASS BROWSER FOR C++
;;; $Id: br-add.el,v 3.1 1995/02/17 18:19:36 mmann Exp $
;;;
;;; **********************************************************************
;;; Copyright (C) 1993, 1994 Gerd Moellmann. All rights reserved.
;;; Altenbergstr. 6, D-40235 Duesseldorf, Germany
;;; 100025.3303@COMPUSERVE.COM
;;; Suggestions, comments and requests for improvements are welcome.
;;; **********************************************************************
;;;
;;; This version works with both Emacs version 18 and 19, and I want
;;; to keep it that way. It requires the CL-19 Common Lisp compatibility
;;; package for Emacs 18 and 19.
;;;
;;; This file contains the code for adding regions and buffers to a tree.
;;; The regions are parsed by `ebrowse'; the result is merged into an
;;; existing tree.
;;;
;; This file may be made part of the Emacs distribution at the option
;; of the FSF.
;; This code is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY. No author or distributor
;; accepts responsibility to anyone for the consequences of using it
;; or for whether it serves any particular purpose or works at all,
;; unless he says so in writing. Refer to the GNU Emacs General Public
;; License for full details.
;; Everyone is granted permission to copy, modify and redistribute
;; this code, but only under the conditions described in the
;; GNU Emacs General Public License. A copy of this license is
;; supposed to have been given to you along with GNU Emacs so you
;; can know your rights and responsibilities. It should be in a
;; file named COPYING. Among other things, the copyright notice
;; and this notice must be preserved on all copies.
(require 'cl-19 "cl")
(require 'backquote)
(require 'br-macro)
(require 'br-struc)
;;;
;;; The program used to parse regions. For MS-DOS and OS/2, a
;;; silly extension has to be supplied.
;;;
(defvar browse-ebrowse-path
(concat "ebrowse" (if (memq system-type '(ms-dos OS/2)) ".exe"))
"The name and path of the EBROWSE program.")
;;;
;;; Given a list of TREE structures, merge this list with the list of TREEs
;;; in the current buffer (in buffer-local variable @tree).
;;;
(defun browse-merge-tree-list (tree-list)
(dolist (tree tree-list) (browse-merge-tree tree))
(setq @tree (browse-sort-tree-list @tree)
@tree-obarray (browse-build-tree-obarray @tree))
(set-buffer-modified-p t))
;;;
;;; Merge a single TREE structure with an existing tree in the
;;; current buffer (@tree). #### What if the inheritance structure changes?
;;;
(defun browse-merge-tree (tree &optional derived-tree-p)
(let* ((sym (intern-soft (class-name (tree-class tree)) @tree-obarray))
(existing-tree (get sym 'browse-root)))
(if existing-tree
(let ((old-tree existing-tree))
(browse-merge-subclasses tree old-tree)
(dolist (func member-lists)
(let* ((new-list (funcall func tree)))
(when new-list
(if (null (funcall func old-tree))
(tree-set-member-list old-tree func new-list)
(browse-merge-member-list old-tree tree func))))))
;; Add to root tree list if TREE isn't a derived class.
(unless derived-tree-p
(setq @tree (list* tree @tree)))))
;; Merge subclasses.
(dolist (c (tree-subclasses tree))
(browse-merge-tree c t)))
;;;
;;; Return T is CLASS is a superclass of SUBCLASS
;;;
(defun browse-superclass-p (class subclass)
(loop for c in (tree-subclasses class)
with subclass-name = (class-name (tree-class subclass))
if (string= subclass-name (class-name (tree-class c))) return t))
;;;
;;; Add new subclasses defined in NEW but not in OLD to OLD.
;;;
(defun browse-merge-subclasses (new old)
(let ((new-list (loop for s in (tree-subclasses new)
unless (browse-superclass-p old s) collect s)))
(setf (tree-subclasses old)
(browse-sort-tree-list (nconc (tree-subclasses old)
new-list)))))
;;;
;;; Merge member list with accessor FUNC of two TREE structures
;;; OLD-CLASS and NEW-CLASS.
;;;
(defun browse-merge-member-list (old-class new-class func)
(let ((list (funcall func old-class)))
;; Add members
(loop for m in (funcall func new-class) do
(setq list (browse-merge-member old-class new-class list m)))
;; Insert new member list into class structure.
(tree-set-member-list old-class
func
(sort list (function
(lambda (m1 m2)
(string< (member-name m1)
(member-name m2))))))))
;;;
;;; Merge a single member that has different settings in OLD and
;;; NEW class.
;;;
(defun browse-merge-member (old-class new-class member-list member)
(let* (found
(list (loop for m in member-list
with name = (member-name member)
with hash = (member-hash member)
when (and (= (member-hash m) hash)
(string= (member-name m) name))
do (progn
(setq found t)
(browse-merge-member-structs old-class
new-class m member))
collect m)))
(if found
list
(cons member member-list))))
;;;
;;; Given two member structures OLD-MEMBER and MEMBER, replace
;;; information in OLD-MEMBER with new information in MEMBER."
;;;
(defun browse-merge-member-structs (old-tree new-tree old-member new-member)
(let ((old-class (tree-class old-tree))
(new-class (tree-class new-tree))
(new-name (member-name new-member))
(file (member-file new-member))
(pattern (member-pattern new-member))
(flags (member-flags new-member))
(point (member-point new-member)))
;; When we know something about the member declaration...
(when (member-pattern pattern)
(setf (member-name old-member) new-name
(member-file old-member) (or file (class-file new-class))
(member-pattern old-member) pattern
(member-point old-member) point
(member-flags old-member) flags))
(when (member-definition-pattern new-member)
(setf (member-definition-file old-member)
(or (member-definition-file new-member)
(class-source-file new-class)))
(setf (member-definition-pattern old-member)
(member-definition-pattern new-member))
(setf (member-definition-point old-member)
(member-definition-point new-member)))))
;;;
;;; Add a buffer to some class tree.
;;;
;;;###autoload
(defun browse-add-buffer (&optional buffer)
"Parse BUFFER (default current buffer), and add result to some class
tree. If more than one tree exists, ask which one to use."
(interactive)
(save-excursion
(when buffer (set-buffer buffer))
(browse-add-region (point-min) (point-max))))
;;;
;;; Add a region to some class tree.
;;;
;;;###autoload
(defun browse-add-region (region-begin region-end)
"Parse current region and add result to a class tree."
(interactive "r")
(let* ((buffer (get-buffer-create " *Temp*"))
(region-buffer (current-buffer))
(tree-buffer (tree-choose-buffer))
(header (browse-@value '@header tree-buffer))
(options (read-from-minibuffer
"Ebrowse options: "
(tree-header-command-line-options header))))
(save-excursion
(unwind-protect
(progn
(message "Parsing...")
(call-process-region region-begin
region-end
browse-ebrowse-path
nil
buffer
nil
options
" "
"-e"
(or (buffer-file-name) "unknown"))
(set-buffer buffer)
(goto-char (point-min))
(multiple-value-bind
(options class-list) (browse-read-class-list)
(set-buffer tree-buffer)
(browse-merge-tree-list class-list)
(tree-redisplay 'quietly)))
(message "Parsing...done.")
(kill-buffer buffer)))))
;; end of `br-add.el'.