1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-05 22:20:24 -08:00

Remove ctags program

Remove our old ctags and suggest Universal Ctags instead.
This fixes a FIXME in lib-src/Makefile.in and speeds up compilation
quite a bit on my older CPU when I compile with	--enable-gcc-warnings.
It also lessens installation and runtime footprint. (Bug#76322)
* .gitignore: Remove lib-src/ctags.
* admin/authors.el (authors-renamed-files-alist): Remove ctags.1.
* admin/check-man-pages: ctags.1 is no longer a special case.
* admin/quick-install-emacs (PUBLIC_LIBSRC_BINARIES): Remove ctags.
* cross/Makefile.in (LIBSRC_BINARIES): Remove lib-src/ctags.
* doc/man/ctags.1, lib-src/ctags.c: Remove.
* java/Makefile.in (CROSS_LIBSRC_BINS): Remove ctags.
* lib-src/Makefile.in (INSTALLABLES): Remove ctags${EXEEXT}.
(ctags${EXEEXT}): Remove.
* lib-src/etags.c (CTAGS): Remove.  All uses replaced by ...
(ctags): ... this new static var.
(STDIN): Remove macro.  All uses replaced by new STDIN_OPTION constant.
(CTAGS_OPTION, STDIN_OPTION): New contants.
(longopts): New --ctags option.
(ctags_default_C_help): New constant,
to override default_C_help at runtime.
(default_C_help): Now always the etags version.
(C_LANG_NAMES_INDEX): New macro.
(print_language_names): Do not assume etags.
(PROGRAM_NAME): Remove.  All uses removed.
(print_help): Document --ctags if PRINT_UNDOCUMENTED_OPTIONS_HELP.
(main): Support new --ctags option, and support all [ce]tags options.
* test/manual/etags/Makefile (CTAGS_PROG):
Now etags --ctags, since there is no longer a ctags.
This commit is contained in:
Paul Eggert 2025-03-22 11:19:41 -07:00
parent 2658f4eab9
commit 25d7575358
21 changed files with 102 additions and 125 deletions

3
.gitignore vendored
View file

@ -209,7 +209,7 @@ test/infra/android/**/*.zip
test/infra/android/**/*.jar test/infra/android/**/*.jar
test/infra/android/bin/build.sh test/infra/android/bin/build.sh
# ctags, etags. # etags.
TAGS TAGS
!admin/notes/tags !admin/notes/tags
@ -234,7 +234,6 @@ a.out
lib-src/asset-directory-tool lib-src/asset-directory-tool
lib-src/be-resources lib-src/be-resources
lib-src/blessmail lib-src/blessmail
lib-src/ctags
lib-src/ebrowse lib-src/ebrowse
lib-src/emacsclient lib-src/emacsclient
lib-src/etags lib-src/etags

View file

@ -612,7 +612,7 @@ installed locations, with 'make install'. By default, Emacs's files
are installed in the following directories: are installed in the following directories:
'/usr/local/bin' holds the executable programs users normally run - '/usr/local/bin' holds the executable programs users normally run -
'emacs', 'etags', 'ctags', 'emacsclient'. 'emacs', 'etags', 'emacsclient'.
'/usr/local/share/emacs/VERSION/lisp' holds the Emacs Lisp library; '/usr/local/share/emacs/VERSION/lisp' holds the Emacs Lisp library;
'VERSION' stands for the number of the Emacs version 'VERSION' stands for the number of the Emacs version

View file

@ -812,9 +812,7 @@ install-info: info
## "gzip || true" is because some gzips exit with non-zero status ## "gzip || true" is because some gzips exit with non-zero status
## if compression would not reduce the file size. Eg, the gzip in ## if compression would not reduce the file size. Eg, the gzip in
## OpenBSD 4.9 seems to do this (2013/03). In Emacs, this can ## OpenBSD 4.9 seems to do this (2013/03). "gzip -f" is another option here,
## only happen with the tiny ctags.1 manpage. We don't really care if
## ctags.1 is compressed or not. "gzip -f" is another option here,
## but not sure if portable. ## but not sure if portable.
install-man: install-man:
umask 022; ${MKDIR_P} "$(DESTDIR)${man1dir}" umask 022; ${MKDIR_P} "$(DESTDIR)${man1dir}"

View file

@ -1471,7 +1471,6 @@ in the repository.")
("org/COPYRIGHT-AND-LICENSE" . "org/README") ("org/COPYRIGHT-AND-LICENSE" . "org/README")
("lisp/net/idna.el" . "puny.el") ("lisp/net/idna.el" . "puny.el")
;; Moved to different directories. ;; Moved to different directories.
("ctags.1" . "ctags.1")
("etags.1" . "etags.1") ("etags.1" . "etags.1")
("emacs.1" . "emacs.1") ("emacs.1" . "emacs.1")
("emacsclient.1" . "emacsclient.1") ("emacsclient.1" . "emacsclient.1")

View file

@ -32,13 +32,6 @@ exit_status=0
cd "$PD"/../doc/man cd "$PD"/../doc/man
for page in *.1; do for page in *.1; do
# ctags.1 just includes the man page etags.1, which AFAICT will
# default to the one installed on the system (!), instead of the
# one in the repository. So checking it is pointless, and we will
# in any case already check etags.1 separately.
if [ "$page" == "ctags.1" ]; then
continue
fi
log=$(emacs_mktemp) log=$(emacs_mktemp)
LC_ALL=C.UTF-8 MANROFFSEQ='' MANWIDTH=80 \ LC_ALL=C.UTF-8 MANROFFSEQ='' MANWIDTH=80 \
man --warnings=all,mac -E UTF-8 -l -Tutf8 -Z "$page" >/dev/null 2> "$log" man --warnings=all,mac -E UTF-8 -l -Tutf8 -Z "$page" >/dev/null 2> "$log"

View file

@ -27,7 +27,7 @@
## install emacs very often. See the --help output for more details. ## install emacs very often. See the --help output for more details.
PUBLIC_LIBSRC_BINARIES='emacsclient etags ctags ebrowse' PUBLIC_LIBSRC_BINARIES='emacsclient etags ebrowse'
AVOID="CVS -DIC README COPYING ChangeLog ~ [.]orig$ [.]rej$ Makefile$ Makefile.in$ makefile$ makefile.w32-in$ stamp-subdir [.]cvsignore [.]arch-ids [{]arch[}] [.][cho]$ make-docfile" AVOID="CVS -DIC README COPYING ChangeLog ~ [.]orig$ [.]rej$ Makefile$ Makefile.in$ makefile$ makefile.w32-in$ stamp-subdir [.]cvsignore [.]arch-ids [{]arch[}] [.][cho]$ make-docfile"

View file

@ -50,7 +50,7 @@ LIB_SRC_TOP_SRCDIR = $(realpath $(top_src))
# This is a list of binaries to build and install in lib-src. # This is a list of binaries to build and install in lib-src.
LIBSRC_BINARIES = lib-src/etags lib-src/ctags lib-src/emacsclient \ LIBSRC_BINARIES = lib-src/etags lib-src/emacsclient \
lib-src/ebrowse lib-src/hexl lib-src/movemail lib-src/ebrowse lib-src/hexl lib-src/movemail
CLEAN_SUBDIRS = $(wildcard src lib-src lib etc) CLEAN_SUBDIRS = $(wildcard src lib-src lib etc)

View file

@ -353,11 +353,11 @@ directories and the app data directories of other applications.
The Emacs distribution also incorporates several binaries. While The Emacs distribution also incorporates several binaries. While
being executable files, they are packaged as libraries in the library being executable files, they are packaged as libraries in the library
directory, because otherwise the system will not unpack them while directory, because otherwise the system will not unpack them while
Emacs is being installed. This means that instead of @code{ctags} or Emacs is being installed. This means that instead of
@code{emacsclient}, Lisp code must specify @code{libctags.so} or @code{emacsclient}, Lisp code must specify
@code{libemacsclient.so} on the command line when starting either of @code{libemacsclient.so} on the command line when starting either of
those programs in a subprocess; to determine which names to use, those programs in a subprocess; to determine which names to use,
consult the values of the variables @code{ctags-program-name}, consult the values of the variables
@code{etags-program-name}, @code{hexl-program-name}, @code{etags-program-name}, @code{hexl-program-name},
@code{emacsclient-program-name}, @code{movemail-program-name}, @code{emacsclient-program-name}, @code{movemail-program-name},
@code{ebrowse-program-name}, and @code{rcs2log-program-name}. @code{ebrowse-program-name}, and @code{rcs2log-program-name}.

View file

@ -186,7 +186,6 @@ the function returns just the value of the variable @code{exec-path}.
@end defun @end defun
@cindex programs distributed with Emacs, starting @cindex programs distributed with Emacs, starting
@vindex ctags-program-name
@vindex etags-program-name @vindex etags-program-name
@vindex hexl-program-name @vindex hexl-program-name
@vindex emacsclient-program-name @vindex emacsclient-program-name
@ -197,11 +196,11 @@ the function returns just the value of the variable @code{exec-path}.
must take into account that the program may have been renamed in order must take into account that the program may have been renamed in order
to comply with executable naming restrictions present on the system. to comply with executable naming restrictions present on the system.
Instead of starting @command{ctags}, for example, you should specify Instead of starting @command{emacsclient}, for example, you should specify
the value of @code{ctags-program-name} instead. Likewise, instead of the value of @code{emacsclient-program-name} instead. Likewise, instead of
starting @command{movemail}, you must start starting @command{movemail}, you must start
@code{movemail-program-name}, and the same goes for @command{etags}, @code{movemail-program-name}, and the same goes for @command{etags},
@command{hexl}, @command{emacsclient}, @code{rcs2log}, and @command{hexl}, @code{rcs2log}, and
@command{ebrowse}. @command{ebrowse}.
@node Shell Arguments @node Shell Arguments

View file

@ -1 +0,0 @@
.so man1/etags.1

View file

@ -1,5 +1,5 @@
.\" See section COPYING for copyright and redistribution information. .\" See section COPYING for copyright and redistribution information.
.TH ETAGS 1 "2024-12-21" "GNU Tools" "GNU" .TH ETAGS 1 "2025-03-22" "GNU Tools" "GNU"
.de BP .de BP
.sp .sp
.ti -.2i .ti -.2i
@ -7,7 +7,7 @@
.. ..
.SH NAME .SH NAME
etags, ctags \- generate tag file for Emacs, vi etags \- generate tag file for Emacs, vi
.SH SYNOPSIS .SH SYNOPSIS
.hy 0 .hy 0
.na .na
@ -27,7 +27,7 @@ etags, ctags \- generate tag file for Emacs, vi
[\|\-\-help\|] [\|\-\-version\|] [\|\-\-help\|] [\|\-\-version\|]
\fIfile\fP .\|.\|. \fIfile\fP .\|.\|.
\fBctags\fP [\|\-aCdgIQRVh\|] [\|\-BtTuvwx\|] [\|\-l \fIlanguage\fP\|] \fBetags \-\-ctags\fP [\|\-aCdgIQRVh\|] [\|\-BtTuvwx\|] [\|\-l \fIlanguage\fP\|]
.if n .br .if n .br
[\|\-o \fItagfile\fP\|] [\|\-r \fIregexp\fP\|] [\|\-o \fItagfile\fP\|] [\|\-r \fIregexp\fP\|]
[\|\-\-parse\-stdin=\fIfile\fP\|] [\|\-\-parse\-stdin=\fIfile\fP\|]
@ -47,17 +47,18 @@ etags, ctags \- generate tag file for Emacs, vi
The \|\fBetags\fP\| program is used to create a tag table file, in a format The \|\fBetags\fP\| program is used to create a tag table file, in a format
understood by understood by
.BR emacs ( 1 )\c .BR emacs ( 1 )\c
\&; the \|\fBctags\fP\| program is used to create a similar table in a \&; if the first argument is the obsolescent option \|\fB\-\-ctags\fP\|
the program instead creates a similar table in a
format understood by format understood by
.BR vi ( 1 )\c .BR vi ( 1 )\c
\&. Both forms of the program understand \&. The program understands
the syntax of C, Objective C, C++, Java, Fortran, Ada, Cobol, Erlang, the syntax of C, Objective C, C++, Java, Fortran, Ada, Cobol, Erlang,
Forth, Go, HTML, LaTeX, Emacs Lisp/Common Lisp, Lua, Makefile, Mercury, Pascal, Forth, Go, HTML, LaTeX, Emacs Lisp/Common Lisp, Lua, Makefile, Mercury, Pascal,
Perl, Ruby, Rust, PHP, PostScript, Python, Prolog, Scheme and most Perl, Ruby, Rust, PHP, PostScript, Python, Prolog, Scheme and most
assembler\-like syntaxes. assembler\-like syntaxes.
Both forms read the files specified on the command line, and write a tag It reads the files specified on the command line, and write a tag
table (defaults: \fBTAGS\fP for \fBetags\fP, \fBtags\fP for table (default: \fBTAGS\fP, or \fBtags\fP if
\fBctags\fP) in the current working directory. \fB\-\-ctags\fP is used) in the current working directory.
Files specified with relative file names will be recorded in the tag Files specified with relative file names will be recorded in the tag
table with file names relative to the directory where the tag table table with file names relative to the directory where the tag table
resides. If the tag table is in /dev or is the standard output, resides. If the tag table is in /dev or is the standard output,
@ -73,8 +74,7 @@ parsing of the file names following the switch according to the given
language, overriding guesses based on filename extensions. language, overriding guesses based on filename extensions.
.SH OPTIONS .SH OPTIONS
Some options make sense only for the \fBvi\fP style tag files produced Some options make sense only for the \fBvi\fP style tag files produced
by ctags; with the \fB\-\-ctags\fP option; they are ignored otherwise.
\fBetags\fP does not recognize them.
The programs accept unambiguous abbreviations for long option names. The programs accept unambiguous abbreviations for long option names.
.TP .TP
.B \-a, \-\-append .B \-a, \-\-append
@ -87,7 +87,7 @@ expression search instructions; the \fB\-B\fP option writes them using
the delimiter "\|\fB?\fP\|", to search \fIbackwards\fP through files. the delimiter "\|\fB?\fP\|", to search \fIbackwards\fP through files.
The default is to use the delimiter "\|\fB/\fP\|", to search \fIforwards\fP The default is to use the delimiter "\|\fB/\fP\|", to search \fIforwards\fP
through files. through files.
Only \fBctags\fP accepts this option. This option makes sense only if \fB\-\-ctags\fP is used.
.TP .TP
.B \-\-declarations .B \-\-declarations
In C and derived languages, create tags for function declarations, In C and derived languages, create tags for function declarations,
@ -185,7 +185,7 @@ the previous ones. The regexps are of one of the forms:
where \fItagregexp\fP is used to match the tag. It should not match where \fItagregexp\fP is used to match the tag. It should not match
useless characters. If the match is such that more characters than useless characters. If the match is such that more characters than
needed are unavoidably matched by \fItagregexp\fP, it may be useful to needed are unavoidably matched by \fItagregexp\fP, it may be useful to
add a \fInameregexp\fP, to narrow down the tag scope. \fBctags\fP add a \fInameregexp\fP, to narrow down the tag scope. \fB\-\-ctags\fP
ignores regexps without a \fInameregexp\fP. The syntax of regexps is ignores regexps without a \fInameregexp\fP. The syntax of regexps is
the same as in Emacs, except that backslash escapes are the same the same as in Emacs, except that backslash escapes are the same
as GNU grep (which means, for example, that shy groups are not supported), as GNU grep (which means, for example, that shy groups are not supported),
@ -281,15 +281,17 @@ tag entries for other files in place. Currently, this is implemented
by deleting the existing entries for the given files and then by deleting the existing entries for the given files and then
rewriting the new entries at the end of the tags file. It is often rewriting the new entries at the end of the tags file. It is often
faster to simply rebuild the entire tag file than to use this. faster to simply rebuild the entire tag file than to use this.
Only \fBctags\fP accepts this option. This option makes sense only if \fB\-\-ctags\fP is used.
.TP .TP
.B \-v, \-\-vgrind .B \-v, \-\-vgrind
Instead of generating a tag file, write index (in \fBvgrind\fP format) Instead of generating a tag file, write index (in \fBvgrind\fP format)
to standard output. Only \fBctags\fP accepts this option. to standard output.
This option makes sense only if \fB\-\-ctags\fP is used.
.TP .TP
.B \-x, \-\-cxref .B \-x, \-\-cxref
Instead of generating a tag file, write a cross reference (in Instead of generating a tag file, write a cross reference (in
\fBcxref\fP format) to standard output. Only \fBctags\fP accepts this option. \fBcxref\fP format) to standard output.
This option makes sense only if \fB\-\-ctags\fP is used.
.TP .TP
.B \-h, \-H, \-\-help .B \-h, \-H, \-\-help
Print usage information. Followed by one or more \-\-language=LANG Print usage information. Followed by one or more \-\-language=LANG

View file

@ -29,6 +29,12 @@ applies, and please also update docstrings as needed.
The traditional unexec dumper, deprecated since Emacs 27, has been The traditional unexec dumper, deprecated since Emacs 27, has been
removed. removed.
---
** Emacs's old ctags program is no longer built or installed.
You are encouraged to use Universal Ctags <https://ctags.io/> instead.
For now, to get the old ctags behavior you can can run 'etags --ctags'
or use a shell script named 'ctags' that runs 'etags --ctags "$@"'.
--- ---
** Changed GCC default options on 32-bit x86 systems. ** Changed GCC default options on 32-bit x86 systems.
When using GCC 4 or later to build Emacs on 32-bit x86 systems, When using GCC 4 or later to build Emacs on 32-bit x86 systems,

View file

@ -3973,7 +3973,7 @@ There are several known workarounds:
The linker error messages look like this: The linker error messages look like this:
oo-spd/i386/ctags.o:ctags.c:(.text+0x156e): undefined reference to `_imp__re_set_syntax' oo-spd/i386/etags.o:etags.c:(.text+0x156e): undefined reference to `_imp__re_set_syntax'
collect2: ld returned 1 exit status collect2: ld returned 1 exit status
This happens because GCC finds an incompatible regex.h header This happens because GCC finds an incompatible regex.h header
@ -4004,7 +4004,7 @@ Some versions of mingw32 make on some versions of Windows do not seem
to detect the shell correctly. Try "make SHELL=cmd.exe", or if that to detect the shell correctly. Try "make SHELL=cmd.exe", or if that
fails, try running make from Cygwin bash instead. fails, try running make from Cygwin bash instead.
*** Building 'ctags' for MS-Windows with the MinGW port of GCC fails. *** Building 'etags' for MS-Windows with the MinGW port of GCC fails.
This might happen due to a bug in the MinGW header assert.h, which This might happen due to a bug in the MinGW header assert.h, which
defines the 'assert' macro with a trailing semi-colon. The following defines the 'assert' macro with a trailing semi-colon. The following

View file

@ -128,7 +128,6 @@ IS_D8_R8 := @IS_D8_R8@
# containing the following files: # containing the following files:
# lib/$(ANDROID_ABI)/libemacs.so # lib/$(ANDROID_ABI)/libemacs.so
# lib/$(ANDROID_ABI)/libandroid-emacs.so # lib/$(ANDROID_ABI)/libandroid-emacs.so
# lib/$(ANDROID_ABI)/libctags.so
# lib/$(ANDROID_ABI)/libetags.so # lib/$(ANDROID_ABI)/libetags.so
# lib/$(ANDROID_ABI)/libhexl.so # lib/$(ANDROID_ABI)/libhexl.so
# lib/$(ANDROID_ABI)/libmovemail.so # lib/$(ANDROID_ABI)/libmovemail.so
@ -143,8 +142,7 @@ all: $(APK_NAME)
# Binaries to cross-compile. # Binaries to cross-compile.
CROSS_SRC_BINS := $(top_builddir)/cross/src/android-emacs CROSS_SRC_BINS := $(top_builddir)/cross/src/android-emacs
CROSS_LIBSRC_BINS := $(top_builddir)/cross/lib-src/ctags \ CROSS_LIBSRC_BINS := $(top_builddir)/cross/lib-src/hexl \
$(top_builddir)/cross/lib-src/hexl \
$(top_builddir)/cross/lib-src/ebrowse \ $(top_builddir)/cross/lib-src/ebrowse \
$(top_builddir)/cross/lib-src/emacsclient \ $(top_builddir)/cross/lib-src/emacsclient \
$(top_builddir)/cross/lib-src/etags $(top_builddir)/cross/lib-src/etags

View file

@ -155,7 +155,7 @@ ANDROID=@ANDROID@
CLIENTW = @CLIENTW@ CLIENTW = @CLIENTW@
# Things that a user might actually run, which should be installed in bindir. # Things that a user might actually run, which should be installed in bindir.
INSTALLABLES = etags${EXEEXT} ctags${EXEEXT} emacsclient${EXEEXT} $(CLIENTW) \ INSTALLABLES = etags${EXEEXT} emacsclient${EXEEXT} $(CLIENTW) \
ebrowse${EXEEXT} ebrowse${EXEEXT}
# Things that Emacs runs internally, or during the build process, # Things that Emacs runs internally, or during the build process,
@ -415,13 +415,6 @@ etags_libs = $(NTLIB) $(LOADLIBES) $(LIBS_ETAGS)
etags${EXEEXT}: ${etags_deps} etags${EXEEXT}: ${etags_deps}
$(AM_V_CCLD)$(CC) ${ALL_CFLAGS} -o $@ $< $(etags_libs) $(AM_V_CCLD)$(CC) ${ALL_CFLAGS} -o $@ $< $(etags_libs)
## ctags.c is distinct from etags.c so that parallel makes do not write two
## etags.o files on top of each other.
## FIXME?
## Can't we use a wrapper that calls 'etags --ctags'?
ctags${EXEEXT}: ${srcdir}/ctags.c ${etags_deps}
$(AM_V_CCLD)$(CC) ${ALL_CFLAGS} -o $@ $< $(etags_libs)
asset-directory-tool${EXEEXT}: ${srcdir}/asset-directory-tool.c $(config_h) asset-directory-tool${EXEEXT}: ${srcdir}/asset-directory-tool.c $(config_h)
$(AM_V_CCLD)$(CC) ${ALL_CFLAGS} $< $(LOADLIBES) -o $@ $(AM_V_CCLD)$(CC) ${ALL_CFLAGS} $< $(LOADLIBES) -o $@

View file

@ -1,2 +0,0 @@
#define CTAGS 1
#include "etags.c"

View file

@ -126,16 +126,6 @@ University of California, as described above. */
#include <getopt.h> #include <getopt.h>
#include <regex.h> #include <regex.h>
/* Define CTAGS to make the program "ctags" compatible with the usual one.
Leave it undefined to make the program "etags", which makes emacs-style
tag tables and tags typedefs, #defines and struct/union/enum by default. */
#ifdef CTAGS
# undef CTAGS
# define CTAGS true
#else
# define CTAGS false
#endif
/* Define MERCURY_HEURISTICS_RATIO as it was necessary to disambiguate /* Define MERCURY_HEURISTICS_RATIO as it was necessary to disambiguate
Mercury from Objective C, which have same file extensions .m Mercury from Objective C, which have same file extensions .m
See comments before function test_objc_is_mercury for details. */ See comments before function test_objc_is_mercury for details. */
@ -465,12 +455,12 @@ static bool typedefs_or_cplusplus; /* -T: create tags for C typedefs, level */
/* member functions. */ /* member functions. */
static bool constantypedefs; /* -d: create tags for C #define, enum */ static bool constantypedefs; /* -d: create tags for C #define, enum */
/* constants and variables. */ /* constants and variables. */
/* -D: opposite of -d. Default under ctags. */ /* -D: opposite of -d. Default if ctags. */
static int globals; /* create tags for global variables */ static int globals; /* create tags for global variables */
static int members; /* create tags for C member variables */ static int members; /* create tags for C member variables */
static int declarations; /* --declarations: tag them and extern in C&Co*/ static int declarations; /* --declarations: tag them and extern in C&Co*/
static int no_line_directive; /* ignore #line directives (undocumented) */ static int no_line_directive; /* ignore #line directives (undocumented) */
static int no_duplicates; /* no duplicate tags for ctags (undocumented) */ static int no_duplicates; /* no duplicate tags if ctags (undocumented) */
static bool update; /* -u: update tags */ static bool update; /* -u: update tags */
static bool vgrind_style; /* -v: create vgrind style index output */ static bool vgrind_style; /* -v: create vgrind style index output */
static bool no_warnings; /* -w: suppress warnings (undocumented) */ static bool no_warnings; /* -w: suppress warnings (undocumented) */
@ -479,18 +469,20 @@ static bool cplusplus; /* .[hc] means C++, not C (undocumented) */
static bool ignoreindent; /* -I: ignore indentation in C */ static bool ignoreindent; /* -I: ignore indentation in C */
static int packages_only; /* --packages-only: in Ada, only tag packages*/ static int packages_only; /* --packages-only: in Ada, only tag packages*/
static int class_qualify; /* -Q: produce class-qualified tags in C++/Java */ static int class_qualify; /* -Q: produce class-qualified tags in C++/Java */
static bool ctags; /* --ctags */
static int debug; /* --debug */ static int debug; /* --debug */
static int fallback_lang; /* --(no-)fallback-lang: Fortran/C fallbacks */ static int fallback_lang; /* --(no-)fallback-lang: Fortran/C fallbacks */
static int empty_files; /* --(no-)empty-file-entries */ static int empty_files; /* --(no-)empty-file-entries */
/* STDIN is defined in LynxOS system headers */
#ifdef STDIN
# undef STDIN
#endif
#define STDIN 0x1001 /* returned by getopt_long on --parse-stdin */
static bool parsing_stdin; /* --parse-stdin used */ static bool parsing_stdin; /* --parse-stdin used */
/* For long options that have no equivalent short option, use a
non-character as a pseudo short option, starting with CHAR_MAX + 1. */
enum
{
CTAGS_OPTION = CHAR_MAX + 1,
STDIN_OPTION
};
static regexp *p_head; /* list of all regexps */ static regexp *p_head; /* list of all regexps */
static bool need_filebuf; /* some regexes are multi-line */ static bool need_filebuf; /* some regexes are multi-line */
@ -499,6 +491,7 @@ static struct option longopts[] =
{ "append", no_argument, NULL, 'a' }, { "append", no_argument, NULL, 'a' },
{ "packages-only", no_argument, &packages_only, 1 }, { "packages-only", no_argument, &packages_only, 1 },
{ "c++", no_argument, NULL, 'C' }, { "c++", no_argument, NULL, 'C' },
{ "ctags", no_argument, NULL, CTAGS_OPTION },
{ "debug", no_argument, &debug, 1 }, { "debug", no_argument, &debug, 1 },
{ "declarations", no_argument, &declarations, 1 }, { "declarations", no_argument, &declarations, 1 },
{ "no-line-directive", no_argument, &no_line_directive, 1 }, { "no-line-directive", no_argument, &no_line_directive, 1 },
@ -514,10 +507,10 @@ static struct option longopts[] =
{ "regex", required_argument, NULL, 'r' }, { "regex", required_argument, NULL, 'r' },
{ "no-regex", no_argument, NULL, 'R' }, { "no-regex", no_argument, NULL, 'R' },
{ "ignore-case-regex", required_argument, NULL, 'c' }, { "ignore-case-regex", required_argument, NULL, 'c' },
{ "parse-stdin", required_argument, NULL, STDIN }, { "parse-stdin", required_argument, NULL, STDIN_OPTION },
{ "version", no_argument, NULL, 'V' }, { "version", no_argument, NULL, 'V' },
#if CTAGS /* Ctags options */ /* ctags options */
{ "backward-search", no_argument, NULL, 'B' }, { "backward-search", no_argument, NULL, 'B' },
{ "cxref", no_argument, NULL, 'x' }, { "cxref", no_argument, NULL, 'x' },
{ "defines", no_argument, NULL, 'd' }, { "defines", no_argument, NULL, 'd' },
@ -528,7 +521,7 @@ static struct option longopts[] =
{ "vgrind", no_argument, NULL, 'v' }, { "vgrind", no_argument, NULL, 'v' },
{ "no-warn", no_argument, NULL, 'w' }, { "no-warn", no_argument, NULL, 'w' },
#else /* Etags options */ /* etags options */
{ "no-defines", no_argument, NULL, 'D' }, { "no-defines", no_argument, NULL, 'D' },
{ "no-globals", no_argument, &globals, 0 }, { "no-globals", no_argument, &globals, 0 },
{ "include", required_argument, NULL, 'i' }, { "include", required_argument, NULL, 'i' },
@ -536,7 +529,7 @@ static struct option longopts[] =
{ "fallback-lang", no_argument, &fallback_lang, 1 }, { "fallback-lang", no_argument, &fallback_lang, 1 },
{ "no-empty-file-entries", no_argument, &empty_files, 0 }, { "no-empty-file-entries", no_argument, &empty_files, 0 },
{ "empty-file-entries", no_argument, &empty_files, 1 }, { "empty-file-entries", no_argument, &empty_files, 1 },
#endif
{ NULL } { NULL }
}; };
@ -598,15 +591,17 @@ followed by a colon, are tags.";
That is why default_C_entries is called for these. */ That is why default_C_entries is called for these. */
static const char *default_C_suffixes [] = static const char *default_C_suffixes [] =
{ "c", "h", NULL }; { "c", "h", NULL };
#if CTAGS /* C help for Ctags */
static const char default_C_help [] = /* C help for ctags */
static const char ctags_default_C_help[] =
"In C code, any C function is a tag. Use -t to tag typedefs.\n\ "In C code, any C function is a tag. Use -t to tag typedefs.\n\
Use -T to tag definitions of 'struct', 'union' and 'enum'.\n\ Use -T to tag definitions of 'struct', 'union' and 'enum'.\n\
Use -d to tag '#define' macro definitions and 'enum' constants.\n\ Use -d to tag '#define' macro definitions and 'enum' constants.\n\
Use --globals to tag global variables.\n\ Use --globals to tag global variables.\n\
You can tag function declarations and external variables by\n\ You can tag function declarations and external variables by\n\
using '--declarations', and struct members by using '--members'."; using '--declarations', and struct members by using '--members'.";
#else /* C help for Etags */
/* C help for etags */
static const char default_C_help [] = static const char default_C_help [] =
"In C code, any C function or typedef is a tag, and so are\n\ "In C code, any C function or typedef is a tag, and so are\n\
definitions of 'struct', 'union' and 'enum'. '#define' macro\n\ definitions of 'struct', 'union' and 'enum'. '#define' macro\n\
@ -617,7 +612,6 @@ definitions and 'enum' constants are tags unless you specify\n\
'--no-members' can make the tags table file much smaller.\n\ '--no-members' can make the tags table file much smaller.\n\
You can tag function declarations and external variables by\n\ You can tag function declarations and external variables by\n\
using '--declarations'."; using '--declarations'.";
#endif /* C help for Ctags and Etags */
static const char *Cplusplus_suffixes [] = static const char *Cplusplus_suffixes [] =
{ "C", "c++", "cc", "cpp", "cxx", "H", "h++", "hh", "hpp", "hxx", { "C", "c++", "cc", "cpp", "cxx", "H", "h++", "hh", "hpp", "hxx",
@ -862,6 +856,7 @@ static language lang_names [] =
{ {
{ "ada", Ada_help, Ada_funcs, Ada_suffixes }, { "ada", Ada_help, Ada_funcs, Ada_suffixes },
{ "asm", Asm_help, Asm_labels, Asm_suffixes }, { "asm", Asm_help, Asm_labels, Asm_suffixes },
#define C_LANG_NAMES_INDEX 2
{ "c", default_C_help, default_C_entries, default_C_suffixes }, { "c", default_C_help, default_C_entries, default_C_suffixes },
{ "c++", Cplusplus_help, Cplusplus_entries, Cplusplus_suffixes }, { "c++", Cplusplus_help, Cplusplus_entries, Cplusplus_suffixes },
{ "c*", no_lang_help, Cstar_entries, Cstar_suffixes }, { "c*", no_lang_help, Cstar_entries, Cstar_suffixes },
@ -934,15 +929,10 @@ For detailed help on a given language use, for example,\n\
etags --help --lang=ada."); etags --help --lang=ada.");
} }
#if CTAGS
# define PROGRAM_NAME "ctags"
#else
# define PROGRAM_NAME "etags"
#endif
static _Noreturn void static _Noreturn void
print_version (void) print_version (void)
{ {
fputs ((PROGRAM_NAME " (" PACKAGE_NAME " " PACKAGE_VERSION ")\n" fputs (("etags (" PACKAGE_NAME " " PACKAGE_VERSION ")\n"
COPYRIGHT "\n" COPYRIGHT "\n"
"This program is distributed under the terms in ETAGS.README\n"), "This program is distributed under the terms in ETAGS.README\n"),
stdout); stdout);
@ -984,7 +974,7 @@ Relative ones are stored relative to the output file's directory.\n");
puts ("--packages-only\n\ puts ("--packages-only\n\
For Ada files, only generate tags for packages."); For Ada files, only generate tags for packages.");
if (CTAGS) if (ctags)
puts ("-B, --backward-search\n\ puts ("-B, --backward-search\n\
Write the search commands for the tag entries using '?', the\n\ Write the search commands for the tag entries using '?', the\n\
backward-search command instead of '/', the forward-search command."); backward-search command instead of '/', the forward-search command.");
@ -997,9 +987,13 @@ Relative ones are stored relative to the output file's directory.\n");
Treat files whose name suffix defaults to C language as C++ files."); Treat files whose name suffix defaults to C language as C++ files.");
*/ */
if (PRINT_UNDOCUMENTED_OPTIONS_HELP && !ctags)
puts ("--ctags\n\
Implement ctags behavior.");
puts ("--declarations\n\ puts ("--declarations\n\
In C and derived languages, create tags for function declarations,"); In C and derived languages, create tags for function declarations,");
if (CTAGS) if (ctags)
puts ("\tand create tags for extern variables if --globals is used."); puts ("\tand create tags for extern variables if --globals is used.");
else else
puts puts
@ -1008,7 +1002,7 @@ Relative ones are stored relative to the output file's directory.\n");
puts ("\tIn Mercury, tag both declarations starting a line with ':-' and\n\ puts ("\tIn Mercury, tag both declarations starting a line with ':-' and\n\
first predicates or functions in clauses."); first predicates or functions in clauses.");
if (CTAGS) if (ctags)
puts ("-d, --defines\n\ puts ("-d, --defines\n\
Create tag entries for C #define constants and enum constants, too."); Create tag entries for C #define constants and enum constants, too.");
else else
@ -1016,7 +1010,7 @@ Relative ones are stored relative to the output file's directory.\n");
Don't create tag entries for C #define constants and enum constants.\n\ Don't create tag entries for C #define constants and enum constants.\n\
This makes the tags file smaller."); This makes the tags file smaller.");
if (!CTAGS) if (!ctags)
puts ("-i FILE, --include=FILE\n\ puts ("-i FILE, --include=FILE\n\
Include a note in tag file indicating that, when searching for\n\ Include a note in tag file indicating that, when searching for\n\
a tag, one should also consult the tags file FILE after\n\ a tag, one should also consult the tags file FILE after\n\
@ -1026,7 +1020,7 @@ Relative ones are stored relative to the output file's directory.\n");
Force the following files to be considered as written in the\n\ Force the following files to be considered as written in the\n\
named language up to the next --language=LANG option."); named language up to the next --language=LANG option.");
if (CTAGS) if (ctags)
puts ("--globals\n\ puts ("--globals\n\
Create tag entries for global variables in some languages."); Create tag entries for global variables in some languages.");
else else
@ -1037,7 +1031,7 @@ Relative ones are stored relative to the output file's directory.\n");
puts ("--no-line-directive\n\ puts ("--no-line-directive\n\
Ignore #line preprocessor directives in C and derived languages."); Ignore #line preprocessor directives in C and derived languages.");
if (CTAGS) if (ctags)
puts ("--members\n\ puts ("--members\n\
Create tag entries for members of structures in some languages."); Create tag entries for members of structures in some languages.");
else else
@ -1045,7 +1039,7 @@ Relative ones are stored relative to the output file's directory.\n");
Do not create tag entries for members of structures\n\ Do not create tag entries for members of structures\n\
in some languages."); in some languages.");
if (!CTAGS) if (!ctags)
{ {
puts ("--fallback-lang\n\ puts ("--fallback-lang\n\
If a file's language could not be determined, try to parse\n\ If a file's language could not be determined, try to parse\n\
@ -1092,7 +1086,7 @@ Relative ones are stored relative to the output file's directory.\n");
puts ("--parse-stdin=NAME\n\ puts ("--parse-stdin=NAME\n\
Read from standard input and record tags as belonging to file NAME."); Read from standard input and record tags as belonging to file NAME.");
if (CTAGS) if (ctags)
{ {
puts ("-t, --typedefs\n\ puts ("-t, --typedefs\n\
Generate tag entries for C and Ada typedefs."); Generate tag entries for C and Ada typedefs.");
@ -1101,7 +1095,7 @@ Relative ones are stored relative to the output file's directory.\n");
and C++ member functions."); and C++ member functions.");
} }
if (CTAGS) if (ctags)
puts ("-u, --update\n\ puts ("-u, --update\n\
Update the tag entries for the given files, leaving tag\n\ Update the tag entries for the given files, leaving tag\n\
entries for other files in place. Currently, this is\n\ entries for other files in place. Currently, this is\n\
@ -1110,7 +1104,7 @@ Relative ones are stored relative to the output file's directory.\n");
tags file. It is often faster to simply rebuild the entire\n\ tags file. It is often faster to simply rebuild the entire\n\
tag file than to use this."); tag file than to use this.");
if (CTAGS) if (ctags)
{ {
puts ("-v, --vgrind\n\ puts ("-v, --vgrind\n\
Print on the standard output an index of items intended for\n\ Print on the standard output an index of items intended for\n\
@ -1160,7 +1154,6 @@ main (int argc, char **argv)
linebuffer filename_lb; linebuffer filename_lb;
bool help_asked = false; bool help_asked = false;
ptrdiff_t len; ptrdiff_t len;
char *optstring;
int opt; int opt;
progname = argv[0]; progname = argv[0];
@ -1192,9 +1185,7 @@ main (int argc, char **argv)
/* When the optstring begins with a '-' getopt_long does not rearrange the /* When the optstring begins with a '-' getopt_long does not rearrange the
non-options arguments to be at the end, but leaves them alone. */ non-options arguments to be at the end, but leaves them alone. */
optstring = concat ("-ac:Cf:Il:o:Qr:RSVhH", static char const optstring[] = "-aBc:CdDf:hHi:Il:o:Qr:RStTuvVwx";
(CTAGS) ? "BxdtTuvw" : "Di:",
"");
while ((opt = getopt_long (argc, argv, optstring, longopts, NULL)) != EOF) while ((opt = getopt_long (argc, argv, optstring, longopts, NULL)) != EOF)
switch (opt) switch (opt)
@ -1215,7 +1206,13 @@ main (int argc, char **argv)
++file_count; ++file_count;
break; break;
case STDIN: case CTAGS_OPTION:
/* Operate as ctags, not etags. */
ctags = true;
lang_names[C_LANG_NAMES_INDEX].help = ctags_default_C_help;
break;
case STDIN_OPTION:
/* Parse standard input. Idea by Vivek <vivek@etla.org>. */ /* Parse standard input. Idea by Vivek <vivek@etla.org>. */
argbuffer[current_arg].arg_type = at_stdin; argbuffer[current_arg].arg_type = at_stdin;
argbuffer[current_arg].what = optarg; argbuffer[current_arg].what = optarg;
@ -1325,7 +1322,7 @@ main (int argc, char **argv)
} }
if (tagfile == NULL) if (tagfile == NULL)
tagfile = savestr (CTAGS ? "tags" : "TAGS"); tagfile = savestr (ctags ? "tags" : "TAGS");
cwd = etags_getcwd (); /* the current working directory */ cwd = etags_getcwd (); /* the current working directory */
if (cwd[strlen (cwd) - 1] != '/') if (cwd[strlen (cwd) - 1] != '/')
{ {
@ -1349,7 +1346,7 @@ main (int argc, char **argv)
linebuffer_init (&filebuf); linebuffer_init (&filebuf);
linebuffer_init (&token_name); linebuffer_init (&token_name);
if (!CTAGS) if (!ctags)
{ {
if (streq (tagfile, "-")) if (streq (tagfile, "-"))
{ {
@ -1407,13 +1404,13 @@ main (int argc, char **argv)
free (filebuf.buffer); free (filebuf.buffer);
free (token_name.buffer); free (token_name.buffer);
if (!CTAGS || cxref_style) if (!ctags || cxref_style)
{ {
/* Write the remaining tags to tagf (ETAGS) or stdout (CXREF). */ /* Write the remaining tags to tagf (ETAGS) or stdout (CXREF). */
put_entries (nodehead); put_entries (nodehead);
free_tree (nodehead); free_tree (nodehead);
nodehead = NULL; nodehead = NULL;
if (!CTAGS) if (!ctags)
{ {
fdesc *fdp; fdesc *fdp;
@ -1462,7 +1459,7 @@ main (int argc, char **argv)
if (fclose (tagf) == EOF) if (fclose (tagf) == EOF)
pfatal (tagfile); pfatal (tagfile);
if (CTAGS) if (ctags)
if (append_to_tagfile || update) if (append_to_tagfile || update)
{ {
/* Maybe these should be used: /* Maybe these should be used:
@ -1860,7 +1857,7 @@ process_file (FILE *fh, char *fn, language *lang)
/* If not Ctags, and if this is not metasource and if it contained no #line /* If not Ctags, and if this is not metasource and if it contained no #line
directives, we can write the tags and free all nodes pointing to directives, we can write the tags and free all nodes pointing to
curfdp. */ curfdp. */
if (!CTAGS if (!ctags
&& curfdp->usecharno /* no #line directives in this file */ && curfdp->usecharno /* no #line directives in this file */
&& !curfdp->lang->metasource) && !curfdp->lang->metasource)
{ {
@ -2092,7 +2089,7 @@ make_tag (const char *name, /* tag name, or NULL if unnamed */
fprintf (stderr, "%s on %s:%"PRIdMAX": %s\n", fprintf (stderr, "%s on %s:%"PRIdMAX": %s\n",
named ? name : "(unnamed)", curfdp->taggedfname, lno, linestart); named ? name : "(unnamed)", curfdp->taggedfname, lno, linestart);
if (!CTAGS && named) /* maybe set named to false */ if (!ctags && named) /* maybe set named to false */
/* Let's try to make an implicit tag name, that is, create an unnamed tag /* Let's try to make an implicit tag name, that is, create an unnamed tag
such that etags.el can guess a name from it. */ such that etags.el can guess a name from it. */
{ {
@ -2133,17 +2130,17 @@ pfnote (char *name, /* tag name, or NULL if unnamed */
{ {
register node *np; register node *np;
if ((CTAGS && name == NULL) if ((ctags && name == NULL)
/* We used to have an assertion here for the case below, but if we hit /* We used to have an assertion here for the case below, but if we hit
that case, it just means our parser got confused, and there's nothing that case, it just means our parser got confused, and there's nothing
to do about such empty "tags". */ to do about such empty "tags". */
|| (!CTAGS && name && name[0] == '\0')) || (!ctags && name && name[0] == '\0'))
return; return;
np = xmalloc (sizeof *np); np = xmalloc (sizeof *np);
/* If ctags mode, change name "main" to M<thisfilename>. */ /* If ctags mode, change name "main" to M<thisfilename>. */
if (CTAGS && !cxref_style && streq (name, "main")) if (ctags && !cxref_style && streq (name, "main"))
{ {
char *fp = strrchr (curfdp->taggedfname, '/'); char *fp = strrchr (curfdp->taggedfname, '/');
np->name = concat ("M", fp == NULL ? curfdp->taggedfname : fp + 1, ""); np->name = concat ("M", fp == NULL ? curfdp->taggedfname : fp + 1, "");
@ -2168,7 +2165,7 @@ pfnote (char *name, /* tag name, or NULL if unnamed */
else else
np->cno = invalidcharno; np->cno = invalidcharno;
np->left = np->right = NULL; np->left = np->right = NULL;
if (CTAGS && !cxref_style) if (ctags && !cxref_style)
{ {
if (strnlen (linestart, 50) < 50) if (strnlen (linestart, 50) < 50)
np->regex = concat (linestart, "$", ""); np->regex = concat (linestart, "$", "");
@ -2295,7 +2292,7 @@ add_node (node *np, node **cur_node_p)
return; return;
} }
if (!CTAGS) if (!ctags)
/* Etags Mode */ /* Etags Mode */
{ {
/* For each file name, tags are in a linked sublist on the right /* For each file name, tags are in a linked sublist on the right
@ -2394,7 +2391,7 @@ invalidate_nodes (fdesc *badfdp, node **npp)
node *np = *npp; node *np = *npp;
stkentry *stack = NULL; stkentry *stack = NULL;
if (CTAGS) if (ctags)
{ {
while (np) while (np)
{ {
@ -2504,7 +2501,7 @@ put_entry (node *np)
/* Output this entry */ /* Output this entry */
if (np->valid) if (np->valid)
{ {
if (!CTAGS) if (!ctags)
{ {
/* Etags mode */ /* Etags mode */
if (fdp != np->fdp) if (fdp != np->fdp)
@ -2576,7 +2573,7 @@ put_entries (node *np)
if (np == NULL) if (np == NULL)
return; return;
if (CTAGS) if (ctags)
{ {
while (np) while (np)
{ {

View file

@ -44,7 +44,7 @@
+ addpm.exe - A basic installer that creates Start Menu icons for Emacs. + addpm.exe - A basic installer that creates Start Menu icons for Emacs.
Running this is optional. Running this is optional.
+ ctags.exe, etags.exe - Tools for generating tag files. See the + etags.exe - Tool for generating tag files. See the
`Tags' node of the Emacs manual. `Tags' node of the Emacs manual.
+ ebrowse.exe - A tool for generating C++ browse information. See the + ebrowse.exe - A tool for generating C++ browse information. See the

View file

@ -104,7 +104,7 @@ See the end of the file for license conditions.
+ addpm.exe - A basic installer that adds Emacs to "Start" menus and + addpm.exe - A basic installer that adds Emacs to "Start" menus and
adds Emacs-related entries to the Windows Registry. adds Emacs-related entries to the Windows Registry.
+ ctags.exe, etags.exe - Tools for generating tag files. See the + etags.exe - Tool for generating tag files. See the
`Tags' node of the Emacs manual. `Tags' node of the Emacs manual.
+ ebrowse.exe - A tool for generating C++ browse information. See the + ebrowse.exe - A tool for generating C++ browse information. See the

View file

@ -2167,14 +2167,10 @@ See `setenv' and `getenv'. */);
Vprocess_environment = Qnil; Vprocess_environment = Qnil;
DEFVAR_LISP ("ctags-program-name", Vctags_program_name, DEFVAR_LISP ("ctags-program-name", Vctags_program_name,
doc: /* Name of the `ctags' program distributed with Emacs. doc: /* Name of the `ctags' program.
Use this instead of calling `ctags' directly, as `ctags' may have been Use this instead of calling `ctags' directly, as `ctags' may have been
renamed to comply with executable naming restrictions on the system. */); renamed to comply with executable naming restrictions on the system. */);
#if !defined HAVE_ANDROID || defined ANDROID_STUBIFY
Vctags_program_name = build_string ("ctags"); Vctags_program_name = build_string ("ctags");
#else
Vctags_program_name = build_string ("libctags.so");
#endif
DEFVAR_LISP ("etags-program-name", Vetags_program_name, DEFVAR_LISP ("etags-program-name", Vetags_program_name,
doc: /* Name of the `etags' program distributed with Emacs. doc: /* Name of the `etags' program distributed with Emacs.

View file

@ -37,7 +37,7 @@ SRCS=${ADASRC} ${ASRC} ${CSRC} ${CPSRC} ${ELSRC} ${ERLSRC} ${FSRC}\
NONSRCS=./f-src/entry.strange ./erl-src/lists.erl ./cp-src/clheir.hpp.gz NONSRCS=./f-src/entry.strange ./erl-src/lists.erl ./cp-src/clheir.hpp.gz
ETAGS_PROG=../../../lib-src/etags ETAGS_PROG=../../../lib-src/etags
CTAGS_PROG=../../../lib-src/ctags CTAGS_PROG=../../../lib-src/etags --ctags
REGEX=/[ \t]*DEFVAR_[A-Z_ \t\n(]+"\([^"]+\)"/ REGEX=/[ \t]*DEFVAR_[A-Z_ \t\n(]+"\([^"]+\)"/
xx="this line is here because of a fontlock bug xx="this line is here because of a fontlock bug