Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83; site pegasus.UUCP Path: utzoo!watmath!clyde!burl!ulysses!mhuxj!houxm!hogpc!pegasus!hansen From: hansen@pegasus.UUCP Newsgroups: net.emacs Subject: Re: tags.ml and ctags - (nf) Message-ID: <1890@pegasus.UUCP> Date: Wed, 7-Nov-84 13:29:33 EST Article-I.D.: pegasus.1890 Posted: Wed Nov 7 13:29:33 1984 Date-Received: Fri, 9-Nov-84 06:24:38 EST References: <21600001@uiucuxc.UUCP> Organization: AT&T Information Systems, Lincroft NJ Lines: 413 < Apparently our 1981 version of 'tags.ml' is not compatible with the current < version of 'ctags', as the format of the tags file is different. For example, < tags.ml expacts to see ^A and ^B as delimiters. < Is there a more recent version of tags.ml around? Any help would be < appreciated. The ctags program does not produce a file which can be used directly by the tags package. The tags file that tags.ml creates is what produces the ^A and ^B characters; the ctags format is totally different. Enclosed below is our most recent version of the tags library plus a macro package to take a tags file created by the ctags program and convert it into a format usable by the tags package. Tony Hansen pegasus!hansen #!/bin/sh # This is a shar archive. # The rest of this file is a shell script which will extract: # tags-pkg.ml ctags.ml # Archive created: Wed Nov 7 13:25:47 EST 1984 echo x - tags-pkg.ml sed 's/^X//' > tags-pkg.ml << '~FUNKY STUFF~' ; Edit 7 ; Fri Jul 16 18:05:28 1982 ; twenex-like tags package J. Gosling, November 81 ; ; A tag file is a sequence of lines of the following forms: ; ^_filename ; ^Atagline^Bposition ; A tagline/position pair refers to the preceeding file (declare-global last-search-tag) (defun (to-tag-buffer (temp-use-buffer "*TAG*") (if (& (= (buffer-size) 0) (= (current-file-name) "")) (progn (if (error-occured (read-file ".tags")) (progn (write-named-file ".tags") (message "New tag file"))) (beginning-of-file))) )) (defun (visit-tag-table tagfn (setq tagfn (arg 1 ": visit-tag-table ")) (save-excursion (temp-use-buffer "*TAG*") (read-file tagfn)) )) (defun (goto-tag fn str pos restart (setq restart 0) (if (! prefix-argument-provided) (progn (setq last-search-tag (concat "\^A[^\^B]*" (quote (arg 1 ": goto-tag ")))) (setq restart 1))) (save-excursion (to-tag-buffer) (if restart (beginning-of-file)) (re-search-forward last-search-tag) (beginning-of-line) (re-search-forward "\^A\\([^\^B]*\\)\^B\\(.*\\)") (region-around-match 1) (setq str (region-to-string)) (region-around-match 2) (setq pos (- (region-to-string) 300)) (save-excursion (re-search-reverse "\^_\\(.*\\)") (region-around-match 1) (setq fn (region-to-string))) ) (visit-file fn) (goto-character pos) (if (error-occured (search-forward str)) (search-reverse "")) (beginning-of-line) (line-to-top-of-window) )) (defun (find-pos-str (beginning-of-line) (setq pos (+ (dot) 0)) (set-mark) (end-of-line) (setq str (region-to-string)))) (defun (store-pos-str (insert-character '^A') (insert-string str) (insert-character '^B') (insert-string pos) (newline))) (defun (add-tag (save-excursion pos str fn (find-pop-str) (setq fn (current-file-name)) (to-tag-buffer) (beginning-of-file) (if (error-occured (re-search-forward (concat "\^_" fn "[^\^_]*"))) (progn (beginning-of-file) (insert-character '^_') (insert-string fn) (newline))) (store-pos-str) (beginning-of-file)))) (defun (add-tag* pos str (find-pos-str) (save-excursion (temp-use-buffer "*TAG*") (store-pos-str)))) (defun (add-all-tags pattern fn (setq pattern (arg 1 ": add-all-tags (pattern) ")) (setq fn (current-file-name)) (save-excursion (to-tag-buffer) (if (error-occured (search-forward (concat "\^_" fn "\n"))) (progn (beginning-of-file) (insert-character '^_') (insert-string fn) (newline)) (progn (set-mark) (while (= (following-char) '^A') (next-line)) (erase-region)) ) ) (save-excursion (error-occured (beginning-of-file) (while 1 (re-search-forward pattern) (add-tag*)))) (novalue) ) ) (defun (add-typed-tags ext pattern (setq ext (substr (current-file-name) -2 2)) (add-all-tags (if (= ext ".l") "^(def" ;(= ext ".c") "^[A-z].*(.*)" ; TLH (| (= ext ".c") (= ext ".h") (= ext ".C") (= ext ".H")) "^[A-z].*(.*)\\|^#[ \t]*define[ \t][ \t]*[A-Za-z_][A-Za-z_]*(" (= ext "ml") "^(defun[ \t\n]*(" (= ext "ss") "@section\\|@chapter\\|@subsection" (= ext ".p") "function\\|procedure" (error (concat "Can't tag " (current-file-name))) ) ) )) (defun (tag-file fn cur-file ; TLH added cur-file (if (is-bound current-file) (setq cur-file current-file) (setq cur-file "")) (setq fn (arg 1 ": tag-file (filename) ")) (message (concat "Tagging " fn)) (save-window-excursion (error-occured (visit-file fn) (add-typed-tags) (if (& (!= cur-file fn) ; TLH (= buffer-is-modified 0)); TLH (delete-buffer fn)) ; TLH )))) (defun (recompute-all-tags current-file ; TLH added current-file (setq current-file (current-file-name)); TLH (save-window-excursion (to-tag-buffer) (beginning-of-file) (error-occured (while 1 (re-search-forward "\^_\\(.*\\)") (region-around-match 1) (tag-file (region-to-string))) ) (write-named-file ".tags")))) (defun (make-tag-table fns current-file ; TLH added current-file (setq fns (arg 1 ": make-tag-table (from filenames) ")) (setq current-file (current-file-name)); TLH (save-window-excursion (temp-use-buffer "*TEMP*") (erase-buffer) (set-mark) (filter-region (concat "ls " fns)) (beginning-of-file) (while (! (eobp)) (set-mark) (end-of-line) (tag-file (region-to-string)) (next-line) (beginning-of-line)) (delete-buffer "*TEMP*") (temp-use-buffer "*TAG*") (write-named-file ".tags")) (novalue) )) (defun (visit-function func (save-window-excursion (forward-character) (backward-word) (set-mark) (forward-word) (setq func (region-to-string)) (goto-tag func) (message "Type ^C to go back") (recursive-edit) ) ) ) ~FUNKY STUFF~ ls -l tags-pkg.ml echo x - ctags.ml sed 's/^X//' > ctags.ml << '~FUNKY STUFF~' ; ctags-to-tags ; - take a file created by the BSD ctags(1) program and change it into the ; format usable by the emacs tags facility. ; ; Tony Hansen, 1983 ; ctags files are made of lines of the form: ; function-name\tfilename\t?regular-expression? ; ; emacs tag files are of the form ; ^_filename ; ^Aregular-expression^Bposition ; (defun (ctags-to-tags tag-file new-tag-file (setq tag-file (arg 1 "Name of ctags file? [tags is default] ")) (if (= tag-file "") (setq tag-file "tags")) (setq new-tag-file (arg 2 "New tag file name [.tags by default] ")) (if (= new-tag-file "") (setq new-tag-file ".tags")) (message "Working....") (sit-for 0) (save-window-excursion (switch-to-buffer "*temp-ctag*") (setq needs-checkpointing 0) (erase-buffer) (insert-file tag-file) ; change over-all format from ; function-name\tfilename\t?regular-expression? ; ... ; into ; ^_filename ; ^A?regular-expression?^Bfunction-name ; ^_filename ; ^A?regular-expression?^Bfunction-name ; ... ; sorted by filenames. (progn (beginning-of-file) (re-replace-string "^\\([^\t]*\\)\t\\([^\t]*\\)\t\\(.*\\)$" "\^_\\2\^A\\3\^B\\1") (set-mark) (end-of-file) (filter-region "sort") (beginning-of-file) (re-replace-string "\\(\^_[^\^A]*\\)\^A" "\\1\n\^A")) ; Get rid of extra file names. ; from ; ^_filename ; ^A?regular-expression?^Bfunction-name ; ^_filename ; ^A?regular-expression?^Bfunction-name ; ... ; into ; ^_filename ; ^A?regular-expression?^Bfunction-name ; ^A?regular-expression?^Bfunction-name ; ^A?regular-expression?^Bfunction-name ; ... (progn last-file current-file (beginning-of-file) (setq last-file "") (while (! (error-occured (search-forward "\^_"))) (set-mark) (end-of-line) (setq current-file (region-to-string)) (if (= current-file last-file) (progn (beginning-of-line) (kill-to-end-of-line) (delete-next-character)) (setq last-file current-file)))) ; Change relative filename references into absolute ones. (progn (beginning-of-file) (re-replace-string "\^_\\([^/]\\)" (concat "\^_" (working-directory) "\\1") )) ; change ctags ?regular-expression? lines into .tags format ; and change function-name into absolute position reference ; ; from ; ^_filename ; ^A?regular-expression?^Bfunction-name ; ^A?regular-expression?^Bfunction-name ; ^A?regular-expression?^Bfunction-name ; ... ; into ; ^_filename ; ^Aregular-expression^Blocation ; ^Aregular-expression^Blocation ; ^Aregular-expression^Blocation ; ... (progn current-file last-file (setq current-file "") (beginning-of-file) (if (! (looking-at "\^_")) (error-message "Missing file name!")) (while (! (eobp)) ; looking at a file name? (if (looking-at "\^_\\(.*\\)") (progn (if (!= current-file "") (save-window-excursion (visit-file current-file) (if (! buffer-is-modified) (delete-buffer (current-buffer-name))))) (region-around-match 1) (setq current-file (region-to-string))) ; looking at a function name? (looking-at "\^A\\([^\^B]*\\)\^B\\(.*\\)") (progn pattern function-name location (region-around-match 1) (setq pattern (region-to-string)) (region-around-match 2) (setq function-name (region-to-string)) ; strip '?^' from beginning and ; strip '$?' from end. (if (= "?" (substr pattern 1 1)) (setq pattern (substr pattern 2 -1))) (if (= "^" (substr pattern 1 1)) (setq pattern (substr pattern 2 -1))) (if (= "?" (substr pattern -1 1)) (setq pattern (substr pattern 1 -1))) (if (= "$" (substr pattern -1 1)) (setq pattern (substr pattern 1 -1))) (save-excursion (visit-file current-file) (if (error-occured (re-search-forward pattern)) (if (error-occured (re-search-reverse pattern)) (if (error-occured (re-search-forward function-name)) (if (error-occured (re-search-reverse function-name)) (error-message "Cannot find " function-name " in " current-file))))) (beginning-of-line) (setq location (+ (dot) 0))) (beginning-of-line) (kill-to-end-of-line) (insert-string (concat "\^A" pattern "\^B" location)) (end-of-line)) (error-message "Mal-formed tags line") ) (error-occured (forward-character)))) (write-named-file new-tag-file)) (delete-buffer "*temp-ctag*") (message "Done!") (novalue) ) ) ~FUNKY STUFF~ ls -l ctags.ml # The following exit is to ensure that extra garbage # after the end of the shar file will be ignored. exit 0