summaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib')
-rw-r--r--contrib/Makefile.am6
-rw-r--r--contrib/Makefile.in328
-rw-r--r--contrib/README11
-rwxr-xr-xcontrib/ocs308
-rw-r--r--contrib/webcscope/CVS/Entries7
-rw-r--r--contrib/webcscope/CVS/Repository1
-rw-r--r--contrib/webcscope/CVS/Root1
-rw-r--r--contrib/webcscope/INSTALL31
-rw-r--r--contrib/webcscope/LICENSE340
-rw-r--r--contrib/webcscope/TODO5
-rw-r--r--contrib/webcscope/cgi-lib.pl471
-rwxr-xr-xcontrib/webcscope/cscope446
-rw-r--r--contrib/webcscope/hilite.c360
-rw-r--r--contrib/webcscope/icons/CVS/Entries10
-rw-r--r--contrib/webcscope/icons/CVS/Repository1
-rw-r--r--contrib/webcscope/icons/CVS/Root1
-rw-r--r--contrib/webcscope/icons/back.gifbin0 -> 216 bytes
-rw-r--r--contrib/webcscope/icons/bomb.gifbin0 -> 308 bytes
-rw-r--r--contrib/webcscope/icons/c.gifbin0 -> 242 bytes
-rw-r--r--contrib/webcscope/icons/down.gifbin0 -> 163 bytes
-rw-r--r--contrib/webcscope/icons/folder.gifbin0 -> 225 bytes
-rw-r--r--contrib/webcscope/icons/folder.open.gifbin0 -> 242 bytes
-rw-r--r--contrib/webcscope/icons/left.gifbin0 -> 172 bytes
-rw-r--r--contrib/webcscope/icons/up.gifbin0 -> 164 bytes
-rw-r--r--contrib/webcscope/icons/world2.gifbin0 -> 261 bytes
-rw-r--r--contrib/xcscope/CVS/Entries3
-rw-r--r--contrib/xcscope/CVS/Repository1
-rw-r--r--contrib/xcscope/CVS/Root1
-rwxr-xr-xcontrib/xcscope/cscope-indexer166
-rw-r--r--contrib/xcscope/xcscope.el2463
30 files changed, 4961 insertions, 0 deletions
diff --git a/contrib/Makefile.am b/contrib/Makefile.am
new file mode 100644
index 0000000..5e9b75f
--- /dev/null
+++ b/contrib/Makefile.am
@@ -0,0 +1,6 @@
+## Process this file with automake to produce Makefile.in
+
+bin_SCRIPTS = ocs
+
+EXTRA_DIST = ocs README xcscope webcscope
+
diff --git a/contrib/Makefile.in b/contrib/Makefile.in
new file mode 100644
index 0000000..0951263
--- /dev/null
+++ b/contrib/Makefile.in
@@ -0,0 +1,328 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = contrib
+DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)"
+binSCRIPT_INSTALL = $(INSTALL_SCRIPT)
+SCRIPTS = $(bin_SCRIPTS)
+SOURCES =
+DIST_SOURCES =
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CURSES_INCLUDEDIR = @CURSES_INCLUDEDIR@
+CURSES_LIBS = @CURSES_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GNOME_LINUX_FALSE = @GNOME_LINUX_FALSE@
+GNOME_LINUX_TRUE = @GNOME_LINUX_TRUE@
+HAS_CURSES_FALSE = @HAS_CURSES_FALSE@
+HAS_CURSES_TRUE = @HAS_CURSES_TRUE@
+HAS_GNOME_FALSE = @HAS_GNOME_FALSE@
+HAS_GNOME_TRUE = @HAS_GNOME_TRUE@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+USING_GNOME2_FALSE = @USING_GNOME2_FALSE@
+USING_GNOME2_TRUE = @USING_GNOME2_TRUE@
+USING_LEX_FALSE = @USING_LEX_FALSE@
+USING_LEX_TRUE = @USING_LEX_TRUE@
+VERSION = @VERSION@
+YACC = @YACC@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+gnome1 = @gnome1@
+gnome2 = @gnome2@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+bin_SCRIPTS = ocs
+EXTRA_DIST = ocs README xcscope webcscope
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu contrib/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-binSCRIPTS: $(bin_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
+ @list='$(bin_SCRIPTS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ if test -f $$d$$p; then \
+ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+ echo " $(binSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(binSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(bindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-binSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_SCRIPTS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
+ done
+uninstall-info-am:
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(SCRIPTS)
+installdirs:
+ for dir in "$(DESTDIR)$(bindir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-binSCRIPTS
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binSCRIPTS uninstall-info-am
+
+.PHONY: all all-am check check-am clean clean-generic distclean \
+ distclean-generic distdir dvi dvi-am html html-am info info-am \
+ install install-am install-binSCRIPTS install-data \
+ install-data-am install-exec install-exec-am install-info \
+ install-info-am install-man install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
+ pdf-am ps ps-am uninstall uninstall-am uninstall-binSCRIPTS \
+ uninstall-info-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/contrib/README b/contrib/README
new file mode 100644
index 0000000..9bd66c6
--- /dev/null
+++ b/contrib/README
@@ -0,0 +1,11 @@
+Contributed addons and wrappers for cscope
+$Id: README,v 1.3 2001/07/02 20:57:45 petr Exp $
+
+ocs - wrapper for cscope providing database generation through recursive
+ directory set (among other things) - docced in script itself.
+ contributed from SCO osr5.
+
+webcscope - a web cgi interface to cscope. Contributed by Ragho Mahalingam,
+ using code from Dmitry Obukhovi and Steven E. Brenner.
+
+xcscope - An (X)Emacs interface to cscope.
diff --git a/contrib/ocs b/contrib/ocs
new file mode 100755
index 0000000..736de94
--- /dev/null
+++ b/contrib/ocs
@@ -0,0 +1,308 @@
+#!/bin/sh
+# $Id: ocs,v 1.4 2004/06/21 18:13:21 broeker Exp $
+# This utility maintains the database for cscope on a recursive dir set
+# Author: donwo Tue Jun 25 15:36:39 PDT 1996
+# Modified: hops Jan 2000 chg defaults to not update if files exist and force
+#
+# These comments ARE the manual. What more do you really need?
+# if using unadorned cscope with this use cscope -d so not trash db
+# cscope -L -0 <ptn> - to display ptn matches on stdout
+#
+# The lists of files are kept in two forms:
+# TMP cscope.tmplst
+# The list generated by this program
+# This list will be updated each time this program
+# is executed.
+#
+# LST cscope.lst
+# The fixed list generated by some other process
+# This list will be used, if found, rather than
+# the TMP form generated here.
+#
+# CSD cscope.csd
+# The fixed list generated by some other process
+# This list will be used, if found, rather than
+# the LST or TMP forms. CSD differs from LST in
+# that the CSD list is used where the source files
+# change only seldom. Cscope is requested not to
+# check for changed files. This can be
+# significantly faster on large source trees.
+#
+# INC cscope.inc
+# This is a list of additional directories
+# in which to search for include files.
+#
+# Three hierarchies of libraries are supported:
+# Local In the current directory ./
+# This is most useful for transient projects or
+# where the information is of no use to others on
+# the system. This type is NOT usable on source
+# directories that are read-only.
+# Home In users home directory $HOME/lib/cs/`pwd`
+# This is good for items that seldom change but are
+# of use only the the current user. This type is
+# usable on source directories that are read-only.
+# System In a global system directory $SYSDIR/`pwd`
+# This is for items that are of interest to all accounts.
+# This option is not available unless the system directory
+# is writable by the current user. This type is usable
+# on source directories that are read-only.
+#
+# If a shell script named ./cscope.rc is found and is
+# executable, the execution of it will be included within this
+# script after defaults_set/cmdline_parse and locating the
+# database.
+#
+# Command line options:
+# -x set shell debugging
+# -f force
+# o Do not ask about regenerating TMP. Just do it.
+# o Allow cscope to regenerate libraries for CSD lists.
+# -q Tell cscope to build an inverted index for quick
+# symbol searching. There is a SIGNIFICANT
+# increase in speed with this option however the
+# disk space used is doubled. Once the quick
+# database is generated, cs will detect the files
+# and continue to use them.
+# -d Do not regenerate. Intended for cscope sub-tasks.
+# -u Update/regenerate.
+
+#
+# Here is where we put things
+
+CSCOPE=cscope
+HOMEDIR=${HOME}/lib/cs
+
+#set the default value for SYSDIR
+if [ -z "${SYSDIR}" ]; then
+ SYSDIR=/usr/local/lib/cs
+ echo setting default sysdir
+fi
+
+#check that SYSDIR exists
+if [ ! -d ${SYSDIR} ]; then
+ echo -n $SYSDIR does not exist.
+ echo Please create the directory and set SYSDIR appropriately
+ exit
+fi
+
+# Check that cscope is in PATH
+type cscope 1>/dev/null 2>&1
+
+if [ $? -ne 0 ]
+then
+ echo "ERROR: cscope is not in \$PATH" >&2
+ echo " Please set \$PATH correctly or make sure cscope is installed" >&2
+ exit 1
+fi
+
+# popup editor
+#XCS_EDITOR=${HOME}/bin/x_cscope_editor
+XCS_EDITOR=${HOME}/bin/xme
+if [ -n "$DISPLAY" -a -x ${XCS_EDITOR} ]
+then
+ EDITOR=${XCS_EDITOR}
+ export EDITOR
+fi
+unset XCS_EDITOR
+
+#
+# Misc defaults
+
+#FORCE=N
+#NOUPDATE=
+FORCE=Y # hops - default to force rather than query
+NOUPDATE=-d # hops - default to no update if files already exist
+QUICK=
+SPECDEST= # hops - query for files
+
+#
+# Parse the command line
+
+set -- `getopt xfqdu $*`
+
+if [ $? -ne 0 ]
+then
+ echo "Use: cs [-x] [-f] [-q] [-u]" >&2
+ echo " -x debug on " >&2
+ echo " -q quick Index - faster search but larger index" >&2
+ echo " -f ask about about regeneration" >&2
+ echo " -d don't update database (default)" >&2
+ echo " -u update database" >&2
+ echo " -s specify where files go" >&2
+ exit 1
+fi
+
+for arg
+do
+ case $arg in
+ -x ) set -x; shift ;;
+ -f ) FORCE=N; NOUPDATE=; shift;;
+ -q ) QUICK=-q; shift ;;
+ -d ) NOUPDATE=-d; shift ;;
+ -u ) NOUPDATE=; shift ;;
+ -s ) SPECDEST=Y; shift ;;
+ esac
+done
+
+#
+# Here is the security hole. Execute whatever is needed for
+# this project. A per-project setup script may be available.
+
+[ -x ./cscope.rc ] && {
+ . ./cscope.rc
+}
+
+#
+# We look hard for appropriate files to scope. We ignore items
+# containing "SCCS" assuming that these are directories of
+# source code control data.
+
+create_list()
+{
+ LIST=$1
+
+ if [ -f ${LIST} ]
+ then
+ [ -n "${NOUPDATE}" ] && return
+
+ if [ "${FORCE}" != "Y" ]
+ then
+ echo "\n${LIST}"
+ echo "Update the library? <(Y)es, (N)o, (Q)uit> [n] \c"
+ read x y
+ case $x in
+ [Yy]* ) ;;
+ [Qq]* ) exit 1 ;;
+ *) return ;;
+ esac
+ fi
+ echo "Updating library:\n ${LIST} \c"
+ else
+ echo "Creating library:\n ${LIST} \c"
+ fi
+
+ (
+ find . -follow -type f \( -name \*.[sScChHlyG] -o \
+ -name \*.asm -o \
+ -name \*.cc -o \
+ -name \*.cxx -o \
+ -name \*.ccP -o \
+ -name \*.hP -o \
+ -name \*.inc -o \
+ -name \*.ed -o \
+ -name vuifile -o \
+ -name Gensymvals -o \
+ -name \[mM\]ake\* \) \
+ -print
+ ) | grep -v SCCS | sort -u > ${LIST}
+
+ echo "\n`cat ${LIST} | wc -l` files listed"
+}
+
+#
+# Expand the include file list into command line arguments
+
+exp_inc()
+{
+ theInc=$1
+
+ if [ -s "${theInc}" ]
+ then
+ for i in `cat ${theInc}`
+ do
+ echo "-I $i \c"
+ done
+ fi
+}
+
+#
+# This routine does not return to the caller
+
+do_cscope()
+{
+ LIST=$1
+ CSLIB=$2
+ INC=$3
+ shift;shift;shift
+ ARGS="$*"
+
+ INCARGS=`exp_inc ${INC}`
+
+ echo "exec cscope"
+ exec $CSCOPE ${ARGS} -p 2 ${INCARGS} -i ${LIST} -f ${CSLIB}
+ echo "exec of $CSCOPE failed" >&2
+ exit 1
+}
+
+#
+# If we have existing libraries, we should use them.
+std_libs()
+{
+ DIR=$1
+ OUT=${DIR}/cscope.out
+ LST=${DIR}/cscope.lst
+ CSD=${DIR}/cscope.csd
+ TMP=${DIR}/cscope.tmplst
+ INC=${DIR}/cscope.inc
+ QCK=${DIR}/cscope.out.po
+
+ [ -s ${QCK} ] && QUICK=-q
+
+ [ -f ${CSD} ] && {
+ if [ "${FORCE}" = "Y" ]
+ then
+ do_cscope ${CSD} ${OUT} ${INC} ${QUICK}
+ else
+ do_cscope ${CSD} ${OUT} ${INC} ${QUICK} -d
+ fi
+ }
+
+ [ -f ${LST} ] && do_cscope ${LST} ${OUT} ${INC} ${QUICK} ${NOUPDATE}
+
+ [ -f ${TMP} ] && {
+ create_list ${TMP}
+ do_cscope ${TMP} ${OUT} ${INC} ${QUICK} ${NOUPDATE}
+ }
+}
+
+#
+# ######## main() #######
+
+umask 0
+PWD=`pwd`
+
+umask 02
+
+#
+# Check for existing libraries
+
+std_libs $PWD
+std_libs ${HOMEDIR}$PWD
+std_libs ${SYSDIR}$PWD
+
+#
+# We may need to create one for this area
+
+DIR=$PWD
+if [ ! -n "${NOUPDATE}" -o -n "${SPECDEST}" ] ; then
+echo "Create new library? <(L)ocal, (H)ome, (S)ystem, (Q)uit> [q] \c"
+read x y
+case $x in
+ [Ll]* ) DIR=$PWD ;;
+ [Hh]* ) DIR=${HOMEDIR}$PWD ;;
+ [Ss]* ) DIR=${SYSDIR}$PWD ;;
+ *) exit 1 ;;
+esac
+fi
+[ -d $DIR ] || {
+ mkdir -p $DIR || exit $?
+}
+
+OUT=${DIR}/cscope.out
+TMP=${DIR}/cscope.tmplst
+INC=${DIR}/cscope.inc
+
+create_list ${TMP}
+do_cscope ${TMP} ${OUT} ${INC} ${QUICK}
+
diff --git a/contrib/webcscope/CVS/Entries b/contrib/webcscope/CVS/Entries
new file mode 100644
index 0000000..998a8cd
--- /dev/null
+++ b/contrib/webcscope/CVS/Entries
@@ -0,0 +1,7 @@
+D/icons////
+/INSTALL/1.1/Fri Jun 29 14:20:16 2001//
+/LICENSE/1.1/Fri Jun 29 14:20:16 2001//
+/TODO/1.1/Fri Jun 29 14:20:16 2001//
+/cgi-lib.pl/1.1/Fri Jun 29 14:20:16 2001//
+/cscope/1.1/Fri Jun 29 14:20:16 2001//
+/hilite.c/1.1/Fri Jun 29 14:20:16 2001//
diff --git a/contrib/webcscope/CVS/Repository b/contrib/webcscope/CVS/Repository
new file mode 100644
index 0000000..1868bd7
--- /dev/null
+++ b/contrib/webcscope/CVS/Repository
@@ -0,0 +1 @@
+cscope/contrib/webcscope
diff --git a/contrib/webcscope/CVS/Root b/contrib/webcscope/CVS/Root
new file mode 100644
index 0000000..e0eb551
--- /dev/null
+++ b/contrib/webcscope/CVS/Root
@@ -0,0 +1 @@
+broeker@cscope.cvs.sourceforge.net:/cvsroot/cscope
diff --git a/contrib/webcscope/INSTALL b/contrib/webcscope/INSTALL
new file mode 100644
index 0000000..0ea0d9c
--- /dev/null
+++ b/contrib/webcscope/INSTALL
@@ -0,0 +1,31 @@
+WebCScope Installation
+
+Quick Install
+
+0. Create a directory called cscope under your /cgi-bin (virtual) directory.
+ Copy all the files in the distribution to this directory.
+
+1. Edit the 'cscope' file and change the following items:
+ - Location to the perl interpreter
+ - Location of the cscope database and other modifiable parameters
+ - Feedback name and email
+ - Location of the syntax highlighter, if you wish to use it
+
+2. Syntax highlighter
+ - The syntax highlighter must be built if you decide to use it. If you
+ do not want syntax highlighting, you can ignore this step and set the
+ highlighter to /bin/cat.
+ - Compile 'hilite.c' using 'gcc -o hilite hilite.c'
+
+3. Icons
+ - Copy the images from the icons directory into the /icons (virtual)
+ directory on the web server. You can also replace these images with
+ whatever you choose.
+
+4. Organizing your CScope databases
+ - WebCScope supports multiple databases in $cscopedir
+ - Create a directory for each project or sub-source in $cscopedir and,
+ generate your cscope database using the following commands.
+ - find /some/source/dir -name '*.[chyls]' -print > cscope.files
+ - cscope -b -q
+ - Repeat the above step for each database you wish to create
diff --git a/contrib/webcscope/LICENSE b/contrib/webcscope/LICENSE
new file mode 100644
index 0000000..5b6e7c6
--- /dev/null
+++ b/contrib/webcscope/LICENSE
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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 of the License, 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 this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/contrib/webcscope/TODO b/contrib/webcscope/TODO
new file mode 100644
index 0000000..4e61555
--- /dev/null
+++ b/contrib/webcscope/TODO
@@ -0,0 +1,5 @@
+
+- Better error checking and the like
+- Add a more robust cookie mechanism
+- More efficient way of searching 'all' databases
+- Fix bugs
diff --git a/contrib/webcscope/cgi-lib.pl b/contrib/webcscope/cgi-lib.pl
new file mode 100644
index 0000000..97d0caa
--- /dev/null
+++ b/contrib/webcscope/cgi-lib.pl
@@ -0,0 +1,471 @@
+# Perl Routines to Manipulate CGI input
+# cgi-lib@pobox.com
+# $Id: cgi-lib.pl,v 1.1 2001/06/29 14:20:16 petr Exp $
+#
+# Copyright (c) 1993-1999 Steven E. Brenner
+# Unpublished work.
+# Permission granted to use and modify this library so long as the
+# copyright above is maintained, modifications are documented, and
+# credit is given for any use of the library.
+#
+# Thanks are due to many people for reporting bugs and suggestions
+
+# For more information, see:
+# http://cgi-lib.stanford.edu/cgi-lib/
+
+$cgi_lib'version = sprintf("%d.%02d", q$Revision: 1.1 $ =~ /(\d+)\.(\d+)/);
+
+
+# Parameters affecting cgi-lib behavior
+# User-configurable parameters affecting file upload.
+$cgi_lib'maxdata = 131072; # maximum bytes to accept via POST - 2^17
+$cgi_lib'writefiles = 0; # directory to which to write files, or
+ # 0 if files should not be written
+$cgi_lib'filepre = "cgi-lib"; # Prefix of file names, in directory above
+
+# Do not change the following parameters unless you have special reasons
+$cgi_lib'bufsize = 8192; # default buffer size when reading multipart
+$cgi_lib'maxbound = 100; # maximum boundary length to be encounterd
+$cgi_lib'headerout = 0; # indicates whether the header has been printed
+
+
+# ReadParse
+# Reads in GET or POST data, converts it to unescaped text, and puts
+# key/value pairs in %in, using "\0" to separate multiple selections
+
+# Returns >0 if there was input, 0 if there was no input
+# undef indicates some failure.
+
+# Now that cgi scripts can be put in the normal file space, it is useful
+# to combine both the form and the script in one place. If no parameters
+# are given (i.e., ReadParse returns FALSE), then a form could be output.
+
+# If a reference to a hash is given, then the data will be stored in that
+# hash, but the data from $in and @in will become inaccessable.
+# If a variable-glob (e.g., *cgi_input) is the first parameter to ReadParse,
+# information is stored there, rather than in $in, @in, and %in.
+# Second, third, and fourth parameters fill associative arrays analagous to
+# %in with data relevant to file uploads.
+
+# If no method is given, the script will process both command-line arguments
+# of the form: name=value and any text that is in $ENV{'QUERY_STRING'}
+# This is intended to aid debugging and may be changed in future releases
+
+sub ReadParse {
+ # Disable warnings as this code deliberately uses local and environment
+ # variables which are preset to undef (i.e., not explicitly initialized)
+ local ($perlwarn);
+ $perlwarn = $^W;
+ $^W = 0;
+
+ local (*in) = shift if @_; # CGI input
+ local (*incfn, # Client's filename (may not be provided)
+ *inct, # Client's content-type (may not be provided)
+ *insfn) = @_; # Server's filename (for spooled files)
+ local ($len, $type, $meth, $errflag, $cmdflag, $got, $name);
+
+ binmode(STDIN); # we need these for DOS-based systems
+ binmode(STDOUT); # and they shouldn't hurt anything else
+ binmode(STDERR);
+
+ # Get several useful env variables
+ $type = $ENV{'CONTENT_TYPE'};
+ $len = $ENV{'CONTENT_LENGTH'};
+ $meth = $ENV{'REQUEST_METHOD'};
+
+ if ($len > $cgi_lib'maxdata) { #'
+ &CgiDie("cgi-lib.pl: Request to receive too much data: $len bytes\n");
+ }
+
+ if (!defined $meth || $meth eq '' || $meth eq 'GET' ||
+ $meth eq 'HEAD' ||
+ $type eq 'application/x-www-form-urlencoded') {
+ local ($key, $val, $i);
+
+ # Read in text
+ if (!defined $meth || $meth eq '') {
+ $in = $ENV{'QUERY_STRING'};
+ $cmdflag = 1; # also use command-line options
+ } elsif($meth eq 'GET' || $meth eq 'HEAD') {
+ $in = $ENV{'QUERY_STRING'};
+ } elsif ($meth eq 'POST') {
+ if (($got = read(STDIN, $in, $len) != $len))
+ {$errflag="Short Read: wanted $len, got $got\n";};
+ } else {
+ &CgiDie("cgi-lib.pl: Unknown request method: $meth\n");
+ }
+
+ @in = split(/[&;]/,$in);
+ push(@in, @ARGV) if $cmdflag; # add command-line parameters
+
+ foreach $i (0 .. $#in) {
+ # Convert plus to space
+ $in[$i] =~ s/\+/ /g;
+
+ # Split into key and value.
+ ($key, $val) = split(/=/,$in[$i],2); # splits on the first =.
+
+ # Convert %XX from hex numbers to alphanumeric
+ $key =~ s/%([A-Fa-f0-9]{2})/pack("c",hex($1))/ge;
+ $val =~ s/%([A-Fa-f0-9]{2})/pack("c",hex($1))/ge;
+
+ # Associate key and value
+ $in{$key} .= "\0" if (defined($in{$key})); # \0 is the multiple separator
+ $in{$key} .= $val;
+ }
+
+ } elsif ($ENV{'CONTENT_TYPE'} =~ m#^multipart/form-data#) {
+ # for efficiency, compile multipart code only if needed
+$errflag = !(eval <<'END_MULTIPART');
+
+ local ($buf, $boundary, $head, @heads, $cd, $ct, $fname, $ctype, $blen);
+ local ($bpos, $lpos, $left, $amt, $fn, $ser);
+ local ($bufsize, $maxbound, $writefiles) =
+ ($cgi_lib'bufsize, $cgi_lib'maxbound, $cgi_lib'writefiles);
+
+
+ # The following lines exist solely to eliminate spurious warning messages
+ $buf = '';
+
+ ($boundary) = $type =~ /boundary="([^"]+)"/; #"; # find boundary
+ ($boundary) = $type =~ /boundary=(\S+)/ unless $boundary;
+ &CgiDie ("Boundary not provided: probably a bug in your server")
+ unless $boundary;
+ $boundary = "--" . $boundary;
+ $blen = length ($boundary);
+
+ if ($ENV{'REQUEST_METHOD'} ne 'POST') {
+ &CgiDie("Invalid request method for multipart/form-data: $meth\n");
+ }
+
+ if ($writefiles) {
+ local($me);
+ stat ($writefiles);
+ $writefiles = "/tmp" unless -d _ && -w _;
+ # ($me) = $0 =~ m#([^/]*)$#;
+ $writefiles .= "/$cgi_lib'filepre";
+ }
+
+ # read in the data and split into parts:
+ # put headers in @in and data in %in
+ # General algorithm:
+ # There are two dividers: the border and the '\r\n\r\n' between
+ # header and body. Iterate between searching for these
+ # Retain a buffer of size(bufsize+maxbound); the latter part is
+ # to ensure that dividers don't get lost by wrapping between two bufs
+ # Look for a divider in the current batch. If not found, then
+ # save all of bufsize, move the maxbound extra buffer to the front of
+ # the buffer, and read in a new bufsize bytes. If a divider is found,
+ # save everything up to the divider. Then empty the buffer of everything
+ # up to the end of the divider. Refill buffer to bufsize+maxbound
+ # Note slightly odd organization. Code before BODY: really goes with
+ # code following HEAD:, but is put first to 'pre-fill' buffers. BODY:
+ # is placed before HEAD: because we first need to discard any 'preface,'
+ # which would be analagous to a body without a preceeding head.
+
+ $left = $len;
+ PART: # find each part of the multi-part while reading data
+ while (1) {
+ die $@ if $errflag;
+
+ $amt = ($left > $bufsize+$maxbound-length($buf)
+ ? $bufsize+$maxbound-length($buf): $left);
+ $errflag = (($got = read(STDIN, $buf, $amt, length($buf))) != $amt);
+ die "Short Read: wanted $amt, got $got\n" if $errflag;
+ $left -= $amt;
+
+ $in{$name} .= "\0" if defined $in{$name};
+ $in{$name} .= $fn if $fn;
+
+ $name=~/([-\w]+)/; # This allows $insfn{$name} to be untainted
+ if (defined $1) {
+ $insfn{$1} .= "\0" if defined $insfn{$1};
+ $insfn{$1} .= $fn if $fn;
+ }
+
+ BODY:
+ while (($bpos = index($buf, $boundary)) == -1) {
+ if ($left == 0 && $buf eq '') {
+ foreach $value (values %insfn) {
+ unlink(split("\0",$value));
+ }
+ &CgiDie("cgi-lib.pl: reached end of input while seeking boundary " .
+ "of multipart. Format of CGI input is wrong.\n");
+ }
+ die $@ if $errflag;
+ if ($name) { # if no $name, then it's the prologue -- discard
+ if ($fn) { print FILE substr($buf, 0, $bufsize); }
+ else { $in{$name} .= substr($buf, 0, $bufsize); }
+ }
+ $buf = substr($buf, $bufsize);
+ $amt = ($left > $bufsize ? $bufsize : $left); #$maxbound==length($buf);
+ $errflag = (($got = read(STDIN, $buf, $amt, length($buf))) != $amt);
+ die "Short Read: wanted $amt, got $got\n" if $errflag;
+ $left -= $amt;
+ }
+ if (defined $name) { # if no $name, then it's the prologue -- discard
+ if ($fn) { print FILE substr($buf, 0, $bpos-2); }
+ else { $in {$name} .= substr($buf, 0, $bpos-2); } # kill last \r\n
+ }
+ close (FILE);
+ last PART if substr($buf, $bpos + $blen, 2) eq "--";
+ substr($buf, 0, $bpos+$blen+2) = '';
+ $amt = ($left > $bufsize+$maxbound-length($buf)
+ ? $bufsize+$maxbound-length($buf) : $left);
+ $errflag = (($got = read(STDIN, $buf, $amt, length($buf))) != $amt);
+ die "Short Read: wanted $amt, got $got\n" if $errflag;
+ $left -= $amt;
+
+
+ undef $head; undef $fn;
+ HEAD:
+ while (($lpos = index($buf, "\r\n\r\n")) == -1) {
+ if ($left == 0 && $buf eq '') {
+ foreach $value (values %insfn) {
+ unlink(split("\0",$value));
+ }
+ &CgiDie("cgi-lib: reached end of input while seeking end of " .
+ "headers. Format of CGI input is wrong.\n$buf");
+ }
+ die $@ if $errflag;
+ $head .= substr($buf, 0, $bufsize);
+ $buf = substr($buf, $bufsize);
+ $amt = ($left > $bufsize ? $bufsize : $left); #$maxbound==length($buf);
+ $errflag = (($got = read(STDIN, $buf, $amt, length($buf))) != $amt);
+ die "Short Read: wanted $amt, got $got\n" if $errflag;
+ $left -= $amt;
+ }
+ $head .= substr($buf, 0, $lpos+2);
+ push (@in, $head);
+ @heads = split("\r\n", $head);
+ ($cd) = grep (/^\s*Content-Disposition:/i, @heads);
+ ($ct) = grep (/^\s*Content-Type:/i, @heads);
+
+ ($name) = $cd =~ /\bname="([^"]+)"/i; #";
+ ($name) = $cd =~ /\bname=([^\s:;]+)/i unless defined $name;
+
+ ($fname) = $cd =~ /\bfilename="([^"]*)"/i; #"; # filename can be null-str
+ ($fname) = $cd =~ /\bfilename=([^\s:;]+)/i unless defined $fname;
+ $incfn{$name} .= (defined $in{$name} ? "\0" : "") .
+ (defined $fname ? $fname : "");
+
+ ($ctype) = $ct =~ /^\s*Content-type:\s*"([^"]+)"/i; #";
+ ($ctype) = $ct =~ /^\s*Content-Type:\s*([^\s:;]+)/i unless defined $ctype;
+ $inct{$name} .= (defined $in{$name} ? "\0" : "") . $ctype;
+
+ if ($writefiles && defined $fname) {
+ $ser++;
+ $fn = $writefiles . ".$$.$ser";
+ open (FILE, ">$fn") || &CgiDie("Couldn't open $fn\n");
+ binmode (FILE); # write files accurately
+ }
+ substr($buf, 0, $lpos+4) = '';
+ undef $fname;
+ undef $ctype;
+ }
+
+1;
+END_MULTIPART
+ if ($errflag) {
+ local ($errmsg, $value);
+ $errmsg = $@ || $errflag;
+ foreach $value (values %insfn) {
+ unlink(split("\0",$value));
+ }
+ &CgiDie($errmsg);
+ } else {
+ # everything's ok.
+ }
+ } else {
+ &CgiDie("cgi-lib.pl: Unknown Content-type: $ENV{'CONTENT_TYPE'}\n");
+ }
+
+ # no-ops to avoid warnings
+ $insfn = $insfn;
+ $incfn = $incfn;
+ $inct = $inct;
+
+ $^W = $perlwarn;
+
+ return ($errflag ? undef : scalar(@in));
+}
+
+
+# PrintHeader
+# Returns the magic line which tells WWW that we're an HTML document
+
+sub PrintHeader {
+ return "Content-type: text/html\n\n";
+}
+
+
+# HtmlTop
+# Returns the <head> of a document and the beginning of the body
+# with the title and a body <h1> header as specified by the parameter
+
+sub HtmlTop
+{
+ local ($title) = @_;
+
+ return <<END_OF_TEXT;
+<html>
+<head>
+<title>$title</title>
+</head>
+<body>
+<h1>$title</h1>
+END_OF_TEXT
+}
+
+
+# HtmlBot
+# Returns the </body>, </html> codes for the bottom of every HTML page
+
+sub HtmlBot
+{
+ return "</body>\n</html>\n";
+}
+
+
+# SplitParam
+# Splits a multi-valued parameter into a list of the constituent parameters
+
+sub SplitParam
+{
+ local ($param) = @_;
+ local (@params) = split ("\0", $param);
+ return (wantarray ? @params : $params[0]);
+}
+
+
+# MethGet
+# Return true if this cgi call was using the GET request, false otherwise
+
+sub MethGet {
+ return (defined $ENV{'REQUEST_METHOD'} && $ENV{'REQUEST_METHOD'} eq "GET");
+}
+
+
+# MethPost
+# Return true if this cgi call was using the POST request, false otherwise
+
+sub MethPost {
+ return (defined $ENV{'REQUEST_METHOD'} && $ENV{'REQUEST_METHOD'} eq "POST");
+}
+
+
+# MyBaseUrl
+# Returns the base URL to the script (i.e., no extra path or query string)
+sub MyBaseUrl {
+ local ($ret, $perlwarn);
+ $perlwarn = $^W; $^W = 0;
+ $ret = 'http://' . $ENV{'SERVER_NAME'} .
+ ($ENV{'SERVER_PORT'} != 80 ? ":$ENV{'SERVER_PORT'}" : '') .
+ $ENV{'SCRIPT_NAME'};
+ $^W = $perlwarn;
+ return $ret;
+}
+
+
+# MyFullUrl
+# Returns the full URL to the script (i.e., with extra path or query string)
+sub MyFullUrl {
+ local ($ret, $perlwarn);
+ $perlwarn = $^W; $^W = 0;
+ $ret = 'http://' . $ENV{'SERVER_NAME'} .
+ ($ENV{'SERVER_PORT'} != 80 ? ":$ENV{'SERVER_PORT'}" : '') .
+ $ENV{'SCRIPT_NAME'} . $ENV{'PATH_INFO'} .
+ (length ($ENV{'QUERY_STRING'}) ? "?$ENV{'QUERY_STRING'}" : '');
+ $^W = $perlwarn;
+ return $ret;
+}
+
+
+# MyURL
+# Returns the base URL to the script (i.e., no extra path or query string)
+# This is obsolete and will be removed in later versions
+sub MyURL {
+ return &MyBaseUrl;
+}
+
+
+# CgiError
+# Prints out an error message which which containes appropriate headers,
+# markup, etcetera.
+# Parameters:
+# If no parameters, gives a generic error message
+# Otherwise, the first parameter will be the title and the rest will
+# be given as different paragraphs of the body
+
+sub CgiError {
+ local (@msg) = @_;
+ local ($i,$name);
+
+ if (!@msg) {
+ $name = &MyFullUrl;
+ @msg = ("Error: script $name encountered fatal error\n");
+ };
+
+ if (!$cgi_lib'headerout) { #')
+ print &PrintHeader;
+ print "<html>\n<head>\n<title>$msg[0]</title>\n</head>\n<body>\n";
+ }
+ print "<h1>$msg[0]</h1>\n";
+ foreach $i (1 .. $#msg) {
+ print "<p>$msg[$i]</p>\n";
+ }
+
+ $cgi_lib'headerout++;
+}
+
+
+# CgiDie
+# Identical to CgiError, but also quits with the passed error message.
+
+sub CgiDie {
+ local (@msg) = @_;
+ &CgiError (@msg);
+ die @msg;
+}
+
+
+# PrintVariables
+# Nicely formats variables. Three calling options:
+# A non-null associative array - prints the items in that array
+# A type-glob - prints the items in the associated assoc array
+# nothing - defaults to use %in
+# Typical use: &PrintVariables()
+
+sub PrintVariables {
+ local (*in) = @_ if @_ == 1;
+ local (%in) = @_ if @_ > 1;
+ local ($out, $key, $output);
+
+ $output = "\n<dl compact>\n";
+ foreach $key (sort keys(%in)) {
+ foreach (split("\0", $in{$key})) {
+ ($out = $_) =~ s/\n/<br>\n/g;
+ $output .= "<dt><b>$key</b>\n <dd>:<i>$out</i>:<br>\n";
+ }
+ }
+ $output .= "</dl>\n";
+
+ return $output;
+}
+
+# PrintEnv
+# Nicely formats all environment variables and returns HTML string
+sub PrintEnv {
+ &PrintVariables(*ENV);
+}
+
+
+# The following lines exist only to avoid warning messages
+$cgi_lib'writefiles = $cgi_lib'writefiles;
+$cgi_lib'bufsize = $cgi_lib'bufsize ;
+$cgi_lib'maxbound = $cgi_lib'maxbound;
+$cgi_lib'version = $cgi_lib'version;
+$cgi_lib'filepre = $cgi_lib'filepre;
+
+1; #return true
+
diff --git a/contrib/webcscope/cscope b/contrib/webcscope/cscope
new file mode 100755
index 0000000..7d98fce
--- /dev/null
+++ b/contrib/webcscope/cscope
@@ -0,0 +1,446 @@
+#!/bin/perl
+
+# $Id: cscope,v 1.1 2001/06/29 14:20:16 petr Exp $
+#
+# WebCscope: A web interface to the cscope application
+# Copyright (C) 2001, Ragho Mahalingam <ragho@mahalingam.com>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, 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 this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Change History:
+#
+# $Log: cscope,v $
+# Revision 1.1 2001/06/29 14:20:16 petr
+# Added webcscope to contribs.
+#
+# Revision 1.3.4.1 2001/02/05 15:14:34 rmahalin
+# initial release with some bug fixes
+#
+# Revision 1.3.3.1 2001/01/22 22:21:23 rmahalin
+# added multi-database support
+# fixed cookie support for trivial functions; removed global trivials
+# added syntax highlighting for files displayed on browser
+#
+# Revision 1.3.1.1 2001/01/11 22:17:30 rmahalin
+# added direct download with mime-type 'text/c-source' and made cosmetic changes
+#
+# Revision 1.3 2001/01/11 21:36:39 rmahalin
+# *** empty log message ***
+#
+# Revision 1.2 2001/01/11 21:34:13 rmahalin
+# incorporated draft feedback changes
+#
+# Revision 1.1 2001/01/11 21:19:32 rmahalin
+# Initial revision
+#
+
+require "cgi-lib.pl";
+
+# current code version being used
+$version = "iSOS 2.5/int16";
+# full path to the cscope binary
+$cscopecmd = "/usr/global/bin/cscope";
+# cscope working directory, where all the in/out and db files are stored
+$cscopedir = "/usr/local/cscope";
+# trivial functions not to display, one per line in the trivs file
+$trivs = "/usr/local/htdocs/cscope/trivials";
+# temporary storage directory
+$tmpdir = "/tmp";
+$tmpinfile = $tmpdir . "/cscopein.$$";
+$tmpoutfile = $tmpdir . "/cscopeout.$$";
+$showfile = $tmpdir . "/showfile.$$";
+# C syntax highlighting application or uncomment the line beneath to just cat
+#$hiliter = "/bin/cat";
+$hiliter = "/usr/local/cgi-bin/cscope/hilite";
+($sec,$min,$hour,$mday,$mon,$year,$wday,$yday) = gmtime(time+1000000);
+$cookie_exp = sprintf("%s %02d-%s-%s %02d:%02d:%02d GMT", $wday, $mday, $mon, $year, $hour, $min, $sec);
+
+# standard images, from the apache distribution
+$img{openfile} = "/icons/folder.gif";
+$img{downloadfile} = "/icons/folder.open.gif";
+$img{csymbol} = "/icons/c.gif";
+$img{upfunc} = "/icons/up.gif";
+$img{downfunc} = "/icons/down.gif";
+$img{globalfunc} = "/icons/world2.gif";
+$img{trashfunc} = "/icons/bomb.gif";
+$img{untrashfunc} = "/icons/back.gif";
+$img{back} = "/icons/left.gif";
+
+# feedback details
+$comment{name} = "Ragho Mahalingam";
+$comment{email} = "ragho\@mahalingam.com";
+
+# operations allowed
+@oper = ( "Find this C symbol",
+"Find this global symbol",
+"Find functions called by",
+"Find functions calling",
+"Find this text string",
+"---------------------",
+"Find this egrep pattern",
+"Find this file",
+"Find files #including this file" );
+
+# -- removed global trivial function list in favor of customized trivials
+#open(TRIVIAL_FUNC, $trivs);
+#@trivial = <TRIVIAL_FUNC>;
+#close(TRIVIAL_FUNC);
+@trivial = ();
+
+MAIN:
+
+{
+ $starttime = time;
+
+ if (&ReadParse(*input)) {
+ &ProcessCookie;
+ &ProcessForm;
+ } else {
+ &PrintForm;
+ }
+}
+
+sub ProcessCookie {
+
+ if ( defined $ENV{HTTP_COOKIE} ) {
+ ($var, $val) = split('=',$ENV{HTTP_COOKIE});
+ $Cookie{$var} = $val;
+ if ( defined $Cookie{'cs-trivf'} ) {
+ # do nothing, else initialize it to null
+ } else {
+ $Cookie{'cs-trivf'} = "defined";
+ }
+ @loc_trivial = split(',', $Cookie{'cs-trivf'});
+ @trivial = ( @loc_trivial );
+
+ }
+}
+
+sub ProcessTrashForm {
+
+ if ( defined $input{'trash'} ) {
+ @trivial = (@trivial, $input{'func'});
+ } else {
+ @tmptriv = ();
+ for ($i=0; $i <= $#trivial; $i++) {
+ $fhash = unpack('H*', $input{'func'});
+ $thash = unpack('H*', $trivial[$i]);
+ if ( $fhash != $thash ) {
+ @tmptriv = ( @tmptriv, $trivial[$i] );
+ }
+ }
+ @trivial = @tmptriv;
+ }
+
+ $Cookie{'cs-trivf'} = join(',',@trivial);
+
+ print "Content-type: text/html\n";
+ print "Set-Cookie: cs-trivf=$Cookie{'cs-trivf'}; path=$ENV{SCRIPT_NAME}; expires $cookie_exp\n\n";
+ print &HtmlTop("Your WebCScope Trivial Functions");
+ print "<ul>";
+ for ($i=0; $i <= $#trivial; $i++) {
+ print "<li><a href=\"$ENV{SCRIPT_NAME}?untrash=&func=$trivial[$i]\"><img src=$img{untrashfunc} border=0></a>&nbsp; $trivial[$i]";
+ }
+ print "</ul><hr>\n";
+ print "Click <a href=\"#\" onClick=\"history.back();\"><img src=$img{back} border=0></a> to go back.\n";
+ print &HtmlBot;
+
+}
+
+sub ProcessForm {
+
+ chdir $cscopedir;
+ opendir(DIRLIST,$cscopedir);
+ @dirlist = readdir(DIRLIST);
+ closedir(DIRLIST);
+
+ if ( $input{'db'} eq "all" ) {
+ @csdirs = ();
+ for ($i=0; $i <= $#dirlist; $i++ ) {
+ if ( ($dirlist[$i] ne ".") && ($dirlist[$i] ne "..") && ( -d $dirlist[$i] ) ) {
+ @csdirs = ( @csdirs, $dirlist[$i] );
+ }
+ }
+ } else {
+ @csdirs = ( $input{'db'} );
+ }
+
+ $op = $input{'op'};
+ $arg = $input{'arg'};
+ $shtriv = $input{'triv'};
+ $db = $input{'db'};
+
+ if ( defined $input{'fshow'} ) { &ShowFileForm; exit; }
+ if ( defined $input{'load'} ) { &DownloadFileForm; exit; }
+ if ( (defined $input{'trash'}) || (defined $input{'untrash'}) ) {
+ &ProcessTrashForm; exit; }
+
+ print &PrintHeader;
+ print &HtmlTop ("WebCscope");
+ print <<ENDOFHDR;
+<h3>Instructions</h3><p>
+<ul>
+<li><img src=$img{csymbol}> will find a symbol with this name<br>
+<li><img src=$img{upfunc}> will find functions <i>calling</i> this function<br>
+<li><img src=$img{downfunc}> will find functions <i>called</i> by this
+function<br>
+<li><img src=$img{globalfunc}> will locate a global definition of this name<br>
+<li><img src=$img{openfile}> will display this file and highlight
+the fragment line<br>
+<li><img src=$img{downloadfile}> will download this file with mimetype "text/c-source"<br>
+<li><img src=$img{trashfunc}> will add this symbol/function to your trivial list<br>
+</ul>
+<p><hr>
+ENDOFHDR
+
+ foreach $index ( 0 .. $#csdirs ) {
+
+ unlink $tmpinfile, $tmpoutfile;
+ open(CSCOPEIN, ">$tmpinfile");
+ print CSCOPEIN "$op$arg\n";
+ print CSCOPEIN "exit\n";
+ close(CSCOPEIN);
+
+ $dbdir = $cscopedir . "/" . $csdirs[$index];
+ chdir($dbdir);
+
+ $syscmd = "cd $dbdir; $cscopecmd -d -l < $tmpinfile > $tmpoutfile;";
+ system($syscmd);
+
+ $count = 1;
+ open(CSCOPEIN, "$tmpoutfile");
+
+ $line = <CSCOPEIN>;
+ @temp = split(' ',$line);
+ $numresult = $temp[2];
+
+ print <<ENDOFHDRs;
+<h2>Search Results from <b>$csdirs[$index]</b></h2>
+<font size=+1>$oper[$op]: <b>$arg</b></font><br>
+Matches: $numresult<p>
+<table border=1 cellpadding=2 cellspacing=2>
+<tr><td><b>Num</b></td><td><b>File</b></td><td><b>Function</b></td>
+<td><b>Line</b></td><td><b>Fragment</b></td></tr>
+ENDOFHDRs
+
+ $trivs_rm = 0;
+
+ for ($i=0; $i < $numresult; $i++ ) {
+ $line = <CSCOPEIN>;
+ @fields = split(' ',$line);
+ $file = shift @fields;
+ $fshowfile = $file;
+ $func = shift @fields;
+ $lnum = shift @fields;
+ @filef = split('/',$file);
+ $file = $filef[$#filef];
+ $frag = join(' ',@fields);
+
+ if ( ! $shtriv ) {
+ for ( $j=0; $j <= $#trivial; $j++ )
+ {
+ $fhash = unpack('H*', $func);
+ $thash = unpack('H*', $trivial[$j]);
+ if ( $fhash == $thash ) { $trivs_rm++; goto done; }
+ }
+ }
+
+ if ( $func ne "<global>" && $func ne "<unknown>" ) {
+ print <<ENDOFBODY1;
+<tr><td>$count</td>
+<td><a href="$ENV{SCRIPT_NAME}?fshow=1&fshowfile=$fshowfile&line=$lnum&db=$db">
+<img src=$img{openfile} border=0></a> $file
+ <a href="$ENV{SCRIPT_NAME}?load=1&file=$fshowfile&db=$db">
+<img src=$img{downloadfile} border=0></a>
+</td>
+<td><a href="$ENV{SCRIPT_NAME}?op=0&triv=$shtriv&arg=$func&db=$db">
+<img src=$img{csymbol} border=0></a>
+<a href="$ENV{SCRIPT_NAME}?op=3&triv=$shtriv&arg=$func&db=$db">
+<img src=$img{upfunc} border=0></a>
+$func
+<a href="$ENV{SCRIPT_NAME}?op=2&triv=$shtriv&arg=$func&db=$db">
+<img src=$img{downfunc} border=0></a>
+<a href="$ENV{SCRIPT_NAME}?op=1&triv=$shtriv&arg=$func&db=$db">
+<img src=$img{globalfunc} border=0></a>
+<a href="$ENV{SCRIPT_NAME}?trash=&func=$func&db=$db">
+<img src=$img{trashfunc} border=0></a>
+</td>
+<td>$lnum</td>
+<td>$frag</td></tr>
+ENDOFBODY1
+
+} else {
+ $func =~ tr/<>/[]/;
+ print <<ENDOFBODY2;
+<tr><td>$count</td>
+<td><a href="$ENV{SCRIPT_NAME}?fshow=1&fshowfile=$fshowfile&line=$lnum&db=$db">
+<img src=$img{openfile} border=0></a> $file
+ <a href="$ENV{SCRIPT_NAME}?load=1&file=$fshowfile&db=$db">
+<img src=$img{downloadfile} border=0></a>
+</td>
+<td>$func</td>
+<td>$lnum</td>
+<td><$frag</td></tr>
+ENDOFBODY2
+
+}
+
+ $count++;
+done:
+
+ }
+
+ close(CSCOPEIN);
+ print "</table>\n";
+ print "<br>Eliminated $trivs_rm line item(s) as trivial functions<p><hr>\n";
+ unlink $tmpinfile, $tmpoutfile;
+
+}
+
+ print &OperationTime;
+ print &Feedback;
+ print &HtmlBot;
+
+}
+
+sub DownloadFileForm {
+ $file = $input{'file'};
+ print "Content-type: text/c-source\n\n";
+ open(SHOWFILE, $file);
+ while (<SHOWFILE>) { print; }
+ close(SHOWFILE);
+}
+
+sub ShowFileForm {
+
+ $file = $input{'fshowfile'};
+ $lnum = $input{'line'};
+
+ print &PrintHeader;
+ print &HtmlTop ("WebCscope");
+ print "<b>Note</b>: Click <a href=#ref><img src=$img{downfunc} border=0></a> to go to the reference line<p><hr>\n";
+ print "<hr>";
+
+ unlink $showfile;
+ system("$hiliter $file > $showfile");
+ open(SHOWFILE, $showfile);
+
+ $curline = 1;
+ while ( <SHOWFILE> ) {
+ $line = $_;
+ if ( $curline == $lnum ) {
+ print "<a name=ref><blink>$line</blink>";
+ } else {
+ print $line;
+ }
+ $curline++;
+ }
+
+ close (SHOWFILE);
+
+
+
+ print &OperationTime;
+ print &Feedback;
+ print &HtmlBot;
+}
+
+sub PrintForm {
+
+ chdir $cscopedir;
+ opendir(DIRLIST,$cscopedir);
+ @dirlist = readdir(DIRLIST);
+ closedir(DIRLIST);
+
+ @csdirs = ();
+ for ($i=0; $i <= $#dirlist; $i++ ) {
+ if ( ($dirlist[$i] ne ".") && ($dirlist[$i] ne "..") && ( -d $dirlist[$i] ) ) {
+ @csdirs = ( @csdirs, $dirlist[$i] );
+ }
+ }
+
+ print &PrintHeader;
+ print &HtmlTop ("Web-CScope");
+
+ print <<ENDOFTEXTA;
+Select an operation below and enter a symbol, function or text to search in
+the database. The active version is $version. Input is case-sensitive,
+so if your search returns no results, check the case and the symbol name.<hr>
+<form method="get" action="$ENV{SCRIPT_NAME}">
+<table border=0 cellpadding=2 cellspacing=2>
+<tr>
+<td>Operation:</td>
+<td>
+<select name="op">
+ENDOFTEXTA
+
+ foreach $opi ( 0 .. $#oper ) {
+ print "<option value=$opi>$oper[$opi]";
+ }
+
+ print <<ENDOFTEXTB;
+</select>
+</td>
+</tr>
+<tr>
+<td>CScope Database:</td>
+<td>
+<select name="db">
+ <option selected value="all">All Databases
+ENDOFTEXTB
+
+ for ($i=0; $i <= $#csdirs; $i++) {
+ print " <option value=\"$csdirs[$i]\">$csdirs[$i]\n";
+ }
+
+ print <<ENDOFTEXT2;
+</select>
+<tr>
+<td>Symbol, function or text:</td>
+<td><input name="arg" size=30></td>
+</tr>
+<tr>
+<td></td>
+<td halign=center>Show trivial functions:
+<input type=radio name="triv" value=1>Yes
+<input type=radio name="triv" value=0 checked>No
+<br><br>
+<input type="submit" value="Scope It!"></td>
+</tr>
+</table>
+<hr>
+</form>
+ENDOFTEXT2
+
+ print &Feedback;
+ print &HtmlBot;
+}
+
+sub Feedback {
+
+ $feedback = "<font size=-1>";
+ $feedback .= '$Id: cscope,v 1.1 2001/06/29 14:20:16 petr Exp $<br>';
+ $feedback .= "$comment{name}<i>&lt;";
+ $feedback .= "<a href=\"mailto:$comment{email}\">";
+ $feedback .= "$comment{email}</a>&gt;</i></font>";
+ return $feedback;
+}
+
+sub OperationTime {
+
+ $deltime = time - $starttime;
+ return "Operation took $deltime second(s)<br>";
+
+}
diff --git a/contrib/webcscope/hilite.c b/contrib/webcscope/hilite.c
new file mode 100644
index 0000000..4f5af07
--- /dev/null
+++ b/contrib/webcscope/hilite.c
@@ -0,0 +1,360 @@
+/*
+ CopyRight (C) 1999, Dmitry Obukhov, dso@usa.net
+ mailto: dso@usa.net
+ http://www.EmbeddedStuff.com
+
+ ----------------------------------------------
+ Last modified 6 Apr 97
+ ----------------------------------------------
+ Converts C (C++) source to HTML code fragment
+ with syntax highlighting.
+ Since program written for personal purpose
+ the <TABLE> tags generated. This is optional
+ page format specific thing.
+
+ Usage: CTHM <input_file>. All output is done
+ to STDOUTPUT, error messages to STDERR.
+ For HTML fragment generation:
+ CHTM file.c > file.htm
+
+ - Some input convertion required to use this
+ code as CGI module. Will be done soon.
+ - Optimization required for blocks of EOL
+ comments
+*/
+
+#include <stdio.h>
+
+// ------------------- Decoding status values
+
+#define START 0
+#define INLINE 1
+#define DEFINE 2
+// ------------------- Decoding Remark
+#define REM1 20
+#define REM2 21
+#define REM_END 22
+#define REM_STAR 23
+#define REM_STAR_1 24
+#define STRING 25 // String is "like" remark
+
+
+// ------------------- HTML TAG Generation
+#define ON 1
+#define OFF 0
+
+// ------------------- HTML TAG type
+#define MODE_KEYWORD 0
+#define MODE_REMARK 2
+#define MODE_REMARK_EOL 4
+#define MODE_DEFINE 6
+#define MODE_STRING 8
+
+
+int is_delimeter(char c)
+{
+ int ii=0;
+ char dlms[] =
+ "\t\r\n (){}[]+-*/%\"'&|^~:;<>.,";
+ //--------------------------------
+ while (dlms[ii])
+ {
+ if (c==dlms[ii++]) return 1;
+ }
+ return 0;
+}
+
+int is_keyword(char * str)
+{
+ char * kwords[] =
+ {
+ "asm", "auto",
+ "break", "case",
+ "cdecl", "char",
+ "class", "const",
+ "continue", "default",
+ "delete", "do",
+ "double", "else",
+ "enum", "extern",
+ "far", "float",
+ "for", "friend",
+ "goto", "huge",
+ "if", "inline",
+ "int", "interrupt",
+ "long", "near",
+ "new", "operator",
+ "pascal", "private",
+ "protected", "public",
+ "register", "return",
+ "short", "signed",
+ "sizeof", "static",
+ "struct", "switch",
+ "template", "this",
+ "typedef", "union",
+ "unsigned", "virtual",
+ "void", "volatile",
+ "while", NULL
+ };
+ int ii=0;
+ int jj;
+ int check;
+
+ while (kwords[ii])
+ {
+ jj = 0;
+ check = 1;
+ while (kwords[ii][jj] && check)
+ {
+ if (str[jj] != kwords[ii][jj])
+ {
+ check = 0;
+ }
+ jj++;
+ }
+ if (check) return 1;
+ ii++;
+ }
+ return 0;
+}
+
+
+void set_mode(int on_off, int mode)
+{
+ char * tags[] =
+ {
+ //-------------------- KEYWORD
+ "<strong>",
+ "</strong>",
+ //-------------------- Classic remarks
+ "<font color=\"#336600\">",
+ "</font>",
+ //-------------------- EOL Remarks
+ "<font color=\"#336600\">",
+ "</font>",
+ //-------------------- #DEFINE
+ "<font color=\"#663300\"><strong>",
+ "</strong></font>",
+ //-------------------- "string"
+ "<font color=\"#0000CC\">",
+ "</font>",
+ NULL, NULL
+ };
+ fprintf(stdout,tags[mode + 1 - on_off]);
+}
+
+void print_char_html(char c)
+{
+ switch (c)
+ {
+ case '<':
+ fprintf(stdout,"&lt;");
+ break;
+ case '>':
+ fprintf(stdout,"&gt;");
+ break;
+ case '"':
+ fprintf(stdout,"&quot;");
+ break;
+ case '&':
+ fprintf(stdout,"&amp;");
+ break;
+ case '|':
+ fprintf(stdout,"&brvbar;");
+ break;
+ default:
+ fprintf(stdout,"%c",c);
+ }
+}
+
+
+
+int main(int _argc, char** _argv)
+{
+ FILE *in, *out;
+ char c;
+ int mode;
+ char buf[80];
+ int bufidx = 0;
+ int progress = 1;
+ int echo;
+ int saved_mode;
+ int kw;
+ char tmpc;
+ char prevc;
+
+ if (_argc < 2)
+ {
+ fprintf(stderr,
+ "USAGE: c2html <file>\n");
+ return 1;
+ }
+
+
+ if ((in = fopen(_argv[1], "rt")) == NULL)
+ {
+ fprintf(stderr,
+ "Cannot open input file.\n");
+ return 1;
+ }
+
+ fprintf(stdout, "<pre>");
+ mode = START;
+
+ while (!feof(in) && progress)
+ {
+ echo = 1;
+ prevc = c;
+ c = fgetc(in);
+
+ if (c=='/' && (mode < REM1))
+ {
+ saved_mode = mode;
+ mode = REM1;
+ }
+
+ switch (mode)
+ {
+ case REM1:
+ echo = 0;
+ mode = REM2;
+ break;
+
+ case REM2:
+ if (c=='/')
+ {
+ if (saved_mode == DEFINE)
+ {
+ set_mode(OFF, MODE_DEFINE);
+ }
+ mode = REM_END;
+ set_mode(ON, MODE_REMARK_EOL);
+ }
+ else if (c=='*')
+ {
+ if (saved_mode == DEFINE)
+ {
+ set_mode(OFF, MODE_DEFINE);
+ }
+ mode = REM_STAR;
+ set_mode(ON, MODE_REMARK);
+ }
+ else
+ {
+ mode = saved_mode;
+ }
+ printf("/");
+ break;
+
+ case REM_END:
+ if (c=='\n')
+ {
+ set_mode(OFF, MODE_REMARK_EOL);
+ }
+ break;
+
+ case REM_STAR:
+ if (c=='*')
+ {
+ mode = REM_STAR_1;
+ }
+ break;
+
+ case REM_STAR_1:
+ if (c=='/')
+ {
+ mode = INLINE;
+ fprintf(stdout,"/");
+ echo = 0;
+ set_mode(OFF, MODE_REMARK);
+ }
+ else mode = REM_STAR;
+ break;
+
+ case START:
+ if (c=='#')
+ {
+ mode = DEFINE;
+ set_mode(ON, MODE_DEFINE);
+ break;
+ }
+ else if (c==' ') break;
+
+ mode = INLINE;
+ // and continue in next case
+
+ case INLINE:
+ if (c=='"' && //
+ prevc != 0x27 && //
+ prevc != '\\') //
+ {
+ set_mode(ON, MODE_STRING);
+ mode = STRING;
+ }
+ break;
+
+ case STRING:
+ if (c=='"' && prevc != '\\')
+ {
+ print_char_html('"');
+ set_mode(OFF, MODE_STRING);
+ echo = 0;
+ mode = INLINE;
+ }
+ break;
+
+ case DEFINE:
+ if (c=='\n')
+ {
+ set_mode(OFF, MODE_DEFINE);
+ }
+ break;
+
+ }
+
+ if (echo && //
+ (mode == INLINE || //
+ (mode!=INLINE && //
+ bufidx))) //
+ {
+ buf[bufidx++] = c;
+ buf[bufidx] = 0;
+ if (is_delimeter(c))
+ {
+ kw = 0;
+ if (bufidx>2)
+ {
+ kw = is_keyword(buf);
+ }
+ if (kw)
+ {
+ set_mode(ON, MODE_KEYWORD);
+ }
+ tmpc = buf[bufidx-1];
+ buf[bufidx-1] = 0;
+ fprintf(stdout,"%s",buf);
+ if (kw)
+ {
+ set_mode(OFF, MODE_KEYWORD);
+ }
+ print_char_html(tmpc);
+ bufidx = 0;
+ buf[0] = 0;
+ }
+ }
+ else if (echo) print_char_html(c);
+
+ if (c=='\n' && mode != REM_STAR)
+ {
+ mode = START;
+ }
+ }
+
+ fclose(in);
+ fprintf(stdout,"</pre>\n");
+ fprintf(stdout,
+ "<!-- == Generated by CHTM convertor -->\n");
+ fprintf(stdout,
+ "<!-- == CopyRight (C) 1999, Dmitry Obukhov, dso@usa.net -->\n");
+
+ return 0;
+}
diff --git a/contrib/webcscope/icons/CVS/Entries b/contrib/webcscope/icons/CVS/Entries
new file mode 100644
index 0000000..22f20b0
--- /dev/null
+++ b/contrib/webcscope/icons/CVS/Entries
@@ -0,0 +1,10 @@
+/back.gif/1.3/Fri Jun 29 15:58:07 2001/-kb/
+/bomb.gif/1.3/Fri Jun 29 15:58:07 2001/-kb/
+/c.gif/1.3/Fri Jun 29 15:58:07 2001/-kb/
+/down.gif/1.3/Fri Jun 29 15:58:07 2001/-kb/
+/folder.gif/1.3/Fri Jun 29 15:58:07 2001/-kb/
+/folder.open.gif/1.3/Fri Jun 29 15:58:07 2001/-kb/
+/left.gif/1.3/Fri Jun 29 15:58:07 2001/-kb/
+/up.gif/1.3/Fri Jun 29 15:58:07 2001/-kb/
+/world2.gif/1.3/Fri Jun 29 15:58:07 2001/-kb/
+D
diff --git a/contrib/webcscope/icons/CVS/Repository b/contrib/webcscope/icons/CVS/Repository
new file mode 100644
index 0000000..cf072b6
--- /dev/null
+++ b/contrib/webcscope/icons/CVS/Repository
@@ -0,0 +1 @@
+cscope/contrib/webcscope/icons
diff --git a/contrib/webcscope/icons/CVS/Root b/contrib/webcscope/icons/CVS/Root
new file mode 100644
index 0000000..e0eb551
--- /dev/null
+++ b/contrib/webcscope/icons/CVS/Root
@@ -0,0 +1 @@
+broeker@cscope.cvs.sourceforge.net:/cvsroot/cscope
diff --git a/contrib/webcscope/icons/back.gif b/contrib/webcscope/icons/back.gif
new file mode 100644
index 0000000..a694ae1
--- /dev/null
+++ b/contrib/webcscope/icons/back.gif
Binary files differ
diff --git a/contrib/webcscope/icons/bomb.gif b/contrib/webcscope/icons/bomb.gif
new file mode 100644
index 0000000..270fdb1
--- /dev/null
+++ b/contrib/webcscope/icons/bomb.gif
Binary files differ
diff --git a/contrib/webcscope/icons/c.gif b/contrib/webcscope/icons/c.gif
new file mode 100644
index 0000000..7555b6c
--- /dev/null
+++ b/contrib/webcscope/icons/c.gif
Binary files differ
diff --git a/contrib/webcscope/icons/down.gif b/contrib/webcscope/icons/down.gif
new file mode 100644
index 0000000..a354c87
--- /dev/null
+++ b/contrib/webcscope/icons/down.gif
Binary files differ
diff --git a/contrib/webcscope/icons/folder.gif b/contrib/webcscope/icons/folder.gif
new file mode 100644
index 0000000..4826460
--- /dev/null
+++ b/contrib/webcscope/icons/folder.gif
Binary files differ
diff --git a/contrib/webcscope/icons/folder.open.gif b/contrib/webcscope/icons/folder.open.gif
new file mode 100644
index 0000000..30979cb
--- /dev/null
+++ b/contrib/webcscope/icons/folder.open.gif
Binary files differ
diff --git a/contrib/webcscope/icons/left.gif b/contrib/webcscope/icons/left.gif
new file mode 100644
index 0000000..279e671
--- /dev/null
+++ b/contrib/webcscope/icons/left.gif
Binary files differ
diff --git a/contrib/webcscope/icons/up.gif b/contrib/webcscope/icons/up.gif
new file mode 100644
index 0000000..6d6d6d1
--- /dev/null
+++ b/contrib/webcscope/icons/up.gif
Binary files differ
diff --git a/contrib/webcscope/icons/world2.gif b/contrib/webcscope/icons/world2.gif
new file mode 100644
index 0000000..e3203f7
--- /dev/null
+++ b/contrib/webcscope/icons/world2.gif
Binary files differ
diff --git a/contrib/xcscope/CVS/Entries b/contrib/xcscope/CVS/Entries
new file mode 100644
index 0000000..f7439f6
--- /dev/null
+++ b/contrib/xcscope/CVS/Entries
@@ -0,0 +1,3 @@
+/cscope-indexer/1.2/Thu Jun 28 04:39:47 2001//
+/xcscope.el/1.14/Wed Apr 10 16:59:00 2002//
+D
diff --git a/contrib/xcscope/CVS/Repository b/contrib/xcscope/CVS/Repository
new file mode 100644
index 0000000..f1ac4c6
--- /dev/null
+++ b/contrib/xcscope/CVS/Repository
@@ -0,0 +1 @@
+cscope/contrib/xcscope
diff --git a/contrib/xcscope/CVS/Root b/contrib/xcscope/CVS/Root
new file mode 100644
index 0000000..e0eb551
--- /dev/null
+++ b/contrib/xcscope/CVS/Root
@@ -0,0 +1 @@
+broeker@cscope.cvs.sourceforge.net:/cvsroot/cscope
diff --git a/contrib/xcscope/cscope-indexer b/contrib/xcscope/cscope-indexer
new file mode 100755
index 0000000..13c0ae2
--- /dev/null
+++ b/contrib/xcscope/cscope-indexer
@@ -0,0 +1,166 @@
+#! /bin/sh
+###############################################################################
+#
+# File: cscope-indexer
+# RCS: $Header: /cvsroot/cscope/cscope/contrib/xcscope/cscope-indexer,v 1.2 2001/06/28 04:39:47 darrylo Exp $
+# Description: Script to index files for cscope
+#
+# This script generates a list of files to index
+# (cscope.out), which is then (optionally) used to
+# generate a cscope database. You can use this script
+# to just build a list of files, or it can be used to
+# build a list and database. This script is not used to
+# just build a database (skipping the list of files
+# step), as this can be simply done by just calling
+# "cscope -b".
+#
+# Normally, cscope will do its own indexing, but this
+# script can be used to force indexing. This is useful
+# if you need to recurse into subdirectories, or have
+# many files to index (you can run this script from a
+# cron job, during the night). It is especially useful
+# for large projects, which can contstantly have source
+# files added and deleted; by using this script, the
+# changing sources files are automatically handled.
+#
+# Currently, any paths containing "/CVS/" or "/RCS/" are
+# stripped out (ignored).
+#
+# This script is written to use only basic shell features, as
+# not all shells have advanced features.
+#
+# Author: Darryl Okahata
+# Created: Thu Apr 27 17:12:14 2000
+# Modified: Tue Jun 19 09:47:45 2001 (Darryl Okahata) darrylo@soco.agilent.com
+# Language: Shell-script
+# Package: N/A
+# Status: Experimental
+#
+# (C) Copyright 2000, Darryl Okahata, all rights reserved.
+#
+###############################################################################
+#
+# Usage:
+#
+# cscope-indexer [ -v ] [-f database_file ] [-i list_file ] [ -l ] [ -r ]
+#
+# where:
+#
+# -f database_file
+# Specifies the cscope database file (default: cscope.out).
+#
+# -i list_file
+# Specifies the name of the file into which the list of files
+# to index is placed (default: cscope.files).
+#
+# -l
+# Suppress the generation/updating of the cscope database
+# file. Only a list of files is generated.
+#
+# -r
+# Recurse into subdirectories to locate files to index.
+# Without this option, only the current directory is
+# searched.
+#
+# -v
+# Be verbose. Output simple progress messages.
+#
+#
+###############################################################################
+set -e
+
+# May have to edit this:
+PATH="/usr/local/bin:/sbin:/usr/sbin:/bin:/usr/bin:$PATH"
+export PATH
+
+LIST_ONLY=
+DIR='.'
+LIST_FILE='cscope.files'
+DATABASE_FILE='cscope.out'
+RECURSE=
+VERBOSE=
+export DIR RECURSE # Need to pass these to subprocesses
+
+while [ -n "$1" ]
+do
+ case "$1" in
+ -f)
+ if [ "X$2" = "X" ]
+ then
+ echo "$0: No database file specified" >&2
+ exit 1
+ fi
+ DATABASE_FILE="$2"
+ shift
+ ;;
+ -i)
+ if [ "X$2" = "X" ]
+ then
+ echo "$0: No list file specified" >&2
+ exit 1
+ fi
+ LIST_FILE="$2"
+ shift
+ ;;
+ -l)
+ LIST_ONLY=1
+ ;;
+ -r)
+ RECURSE=1
+ ;;
+ -v)
+ VERBOSE=1
+ ;;
+ *)
+ DIR="$1"
+ ;;
+ esac
+ shift
+done
+
+cd $DIR
+
+if [ "X$VERBOSE" != "X" ]
+then
+ echo "Creating list of files to index ..."
+fi
+
+(
+ if [ "X$RECURSE" = "X" ]
+ then
+ # Ugly, inefficient, but it works.
+ for f in *
+ do
+ echo "$DIR/$f"
+ done
+ else
+ find $DIR \( -type f -o -type l \)
+ fi
+) | \
+ egrep -i '\.([chly](xx|pp)*|cc|hh)$' | \
+ sed -e '/\/CVS\//d' -e '/\/RCS\//d' -e 's/^\.\///' | \
+ sort > $LIST_FILE
+
+if [ "X$VERBOSE" != "X" ]
+then
+ echo "Creating list of files to index ... done"
+fi
+
+if [ "X$LIST_ONLY" != "X" ]
+then
+ exit 0
+fi
+
+if [ "X$VERBOSE" != "X" ]
+then
+ echo "Indexing files ..."
+fi
+
+cscope -b -i $LIST_FILE -f $DATABASE_FILE
+
+if [ "X$VERBOSE" != "X" ]
+then
+ echo "Indexing files ... done"
+fi
+
+exit 0
diff --git a/contrib/xcscope/xcscope.el b/contrib/xcscope/xcscope.el
new file mode 100644
index 0000000..ce382a4
--- /dev/null
+++ b/contrib/xcscope/xcscope.el
@@ -0,0 +1,2463 @@
+; -*-Emacs-Lisp-*-
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+; File: xcscope.el
+; RCS: $RCSfile: xcscope.el,v $ $Revision: 1.14 $ $Date: 2002/04/10 16:59:00 $ $Author: darrylo $
+; Description: cscope interface for (X)Emacs
+; Author: Darryl Okahata
+; Created: Wed Apr 19 17:03:38 2000
+; Modified: Thu Apr 4 17:22:22 2002 (Darryl Okahata) darrylo@soco.agilent.com
+; Language: Emacs-Lisp
+; Package: N/A
+; Status: Experimental
+;
+; (C) Copyright 2000, 2001, 2002, Darryl Okahata <darrylo@sonic.net>,
+; all rights reserved.
+; GNU Emacs enhancements (C) Copyright 2001,
+; Triet H. Lai <thlai@mail.usyd.edu.au>
+; Fuzzy matching and navigation code (C) Copyright 2001,
+; Steven Elliott <selliott4@austin.rr.com>
+;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; ALPHA VERSION 0.96
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This is a cscope interface for (X)Emacs.
+;; It currently runs under Unix only.
+;;
+;; Using cscope, you can easily search for where symbols are used and defined.
+;; Cscope is designed to answer questions like:
+;;
+;; Where is this variable used?
+;; What is the value of this preprocessor symbol?
+;; Where is this function in the source files?
+;; What functions call this function?
+;; What functions are called by this function?
+;; Where does the message "out of space" come from?
+;; Where is this source file in the directory structure?
+;; What files include this header file?
+;;
+;; Send comments to one of: darrylo@soco.agilent.com
+;; darryl_okahata@agilent.com
+;; darrylo@sonic.net
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; ***** INSTALLATION *****
+;;
+;; * NOTE: this interface currently runs under Unix only.
+;;
+;; This module needs a shell script called "cscope-indexer", which
+;; should have been supplied along with this emacs-lisp file. The
+;; purpose of "cscope-indexer" is to create and optionally maintain
+;; the cscope databases. If all of your source files are in one
+;; directory, you don't need this script; it's very nice to have,
+;; though, as it handles recursive subdirectory indexing, and can be
+;; used in a nightly or weekly cron job to index very large source
+;; repositories. See the beginning of the file, "cscope-indexer", for
+;; usage information.
+;;
+;; Installation steps:
+;;
+;; 0. (It is, of course, assumed that cscope is already properly
+;; installed on the current system.)
+;;
+;; 1. Install the "cscope-indexer" script into some convenient
+;; directory in $PATH. The only real constraint is that (X)Emacs
+;; must be able to find and execute it. You may also have to edit
+;; the value of PATH in the script, although this is unlikely; the
+;; majority of people should be able to use the script, "as-is".
+;;
+;; 2. Make sure that the "cscope-indexer" script is executable. In
+;; particular, if you had to ftp this file, it is probably no
+;; longer executable.
+;;
+;; 3. Put this emacs-lisp file somewhere where (X)Emacs can find it. It
+;; basically has to be in some directory listed in "load-path".
+;;
+;; 4. Edit your ~/.emacs file to add the line:
+;;
+;; (require 'xcscope)
+;;
+;; 5. If you intend to use xcscope.el often you can optionally edit your
+;; ~/.emacs file to add keybindings that reduce the number of keystrokes
+;; required. For example, the following will add "C-f#" keybindings, which
+;; are easier to type than the usual "C-c s" prefixed keybindings. Note
+;; that specifying "global-map" instead of "cscope:map" makes the
+;; keybindings available in all buffers:
+;;
+;; (define-key global-map [(control f3)] 'cscope-set-initial-directory)
+;; (define-key global-map [(control f4)] 'cscope-unset-initial-directory)
+;; (define-key global-map [(control f5)] 'cscope-find-this-symbol)
+;; (define-key global-map [(control f6)] 'cscope-find-global-definition)
+;; (define-key global-map [(control f7)]
+;; 'cscope-find-global-definition-no-prompting)
+;; (define-key global-map [(control f8)] 'cscope-pop-mark)
+;; (define-key global-map [(control f9)] 'cscope-next-symbol)
+;; (define-key global-map [(control f10)] 'cscope-next-file)
+;; (define-key global-map [(control f11)] 'cscope-prev-symbol)
+;; (define-key global-map [(control f12)] 'cscope-prev-file)
+;; (define-key global-map [(meta f9)] 'cscope-display-buffer)
+;; (defin-ekey global-map [(meta f10)] 'cscope-display-buffer-toggle)
+;;
+;; 6. Restart (X)Emacs. That's it.
+;;
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; ***** USING THIS MODULE *****
+;;
+;; * Basic usage:
+;;
+;; If all of your C/C++/lex/yacc source files are in the same
+;; directory, you can just start using this module. If your files are
+;; spread out over multiple directories, see "Advanced usage", below.
+;;
+;; Just edit a source file, and use the pull-down or pop-up (button 3)
+;; menus to select one of:
+;;
+;; Find symbol
+;; Find global definition
+;; Find called functions
+;; Find functions calling a function
+;; Find text string
+;; Find egrep pattern
+;; Find a file
+;; Find files #including a file
+;;
+;; The cscope database will be automatically created in the same
+;; directory as the source files (assuming that you've never used
+;; cscope before), and a buffer will pop-up displaying the results.
+;; You can then use button 2 (the middle button) on the mouse to edit
+;; the selected file, or you can move the text cursor over a selection
+;; and press [Enter].
+;;
+;; Hopefully, the interface should be fairly intuitive.
+;;
+;;
+;; * Locating the cscope databases:
+;;
+;; This module will first use the variable, `cscope-database-regexps',
+;; to search for a suitable database directory. If a database location
+;; cannot be found using this variable then a search is begun at the
+;; variable, `cscope-initial-directory', if set, or the current
+;; directory otherwise. If the directory is not a cscope database
+;; directory then the directory's parent, parent's parent, etc. is
+;; searched until a cscope database directory is found, or the root
+;; directory is reached. If the root directory is reached, the current
+;; directory will be used.
+;;
+;; A cscope database directory is one in which EITHER a cscope database
+;; file (e.g., "cscope.out") OR a cscope file list (e.g.,
+;; "cscope.files") exists. If only "cscope.files" exists, the
+;; corresponding "cscope.out" will be automatically created by cscope
+;; when a search is done. By default, the cscope database file is called
+;; "cscope.out", but this can be changed (on a global basis) via the
+;; variable, `cscope-database-file'. There is limited support for cscope
+;; databases that are named differently than that given by
+;; `cscope-database-file', using the variable, `cscope-database-regexps'.
+;;
+;; Note that the variable, `cscope-database-regexps', is generally not
+;; needed, as the normal hierarchical database search is sufficient
+;; for placing and/or locating the cscope databases. However, there
+;; may be cases where it makes sense to place the cscope databases
+;; away from where the source files are kept; in this case, this
+;; variable is used to determine the mapping. One use for this
+;; variable is when you want to share the database file with other
+;; users; in this case, the database may be located in a directory
+;; separate from the source files.
+;;
+;; Setting the variable, `cscope-initial-directory', is useful when a
+;; search is to be expanded by specifying a cscope database directory
+;; that is a parent of the directory that this module would otherwise
+;; use. For example, consider a project that contains the following
+;; cscope database directories:
+;;
+;; /users/jdoe/sources
+;; /users/jdoe/sources/proj1
+;; /users/jdoe/sources/proj2
+;;
+;; If a search is initiated from a .c file in /users/jdoe/sources/proj1
+;; then (assuming the variable, `cscope-database-regexps', is not set)
+;; /users/jdoe/sources/proj1 will be used as the cscope data base directory.
+;; Only matches in files in /users/jdoe/sources/proj1 will be found. This
+;; can be remedied by typing "C-c s a" and then "M-del" to remove single
+;; path element in order to use a cscope database directory of
+;; /users/jdoe/sources. Normal searching can be restored by typing "C-c s A".
+;;
+;;
+;; * Keybindings:
+;;
+;; All keybindings use the "C-c s" prefix, but are usable only while
+;; editing a source file, or in the cscope results buffer:
+;;
+;; C-c s s Find symbol.
+;; C-c s d Find global definition.
+;; C-c s g Find global definition (alternate binding).
+;; C-c s G Find global definition without prompting.
+;; C-c s c Find functions calling a function.
+;; C-c s C Find called functions (list functions called
+;; from a function).
+;; C-c s t Find text string.
+;; C-c s e Find egrep pattern.
+;; C-c s f Find a file.
+;; C-c s i Find files #including a file.
+;;
+;; These pertain to navigation through the search results:
+;;
+;; C-c s b Display *cscope* buffer.
+;; C-c s B Auto display *cscope* buffer toggle.
+;; C-c s n Next symbol.
+;; C-c s N Next file.
+;; C-c s p Previous symbol.
+;; C-c s P Previous file.
+;; C-c s u Pop mark.
+;;
+;; These pertain to setting and unsetting the variable,
+;; `cscope-initial-directory', (location searched for the cscope database
+;; directory):
+;;
+;; C-c s a Set initial directory.
+;; C-c s A Unset initial directory.
+;;
+;; These pertain to cscope database maintenance:
+;;
+;; C-c s L Create list of files to index.
+;; C-c s I Create list and index.
+;; C-c s E Edit list of files to index.
+;; C-c s W Locate this buffer's cscope directory
+;; ("W" --> "where").
+;; C-c s S Locate this buffer's cscope directory.
+;; (alternate binding: "S" --> "show").
+;; C-c s T Locate this buffer's cscope directory.
+;; (alternate binding: "T" --> "tell").
+;; C-c s D Dired this buffer's directory.
+;;
+;;
+;; * Advanced usage:
+;;
+;; If the source files are spread out over multiple directories,
+;; you've got a few choices:
+;;
+;; [ NOTE: you will need to have the script, "cscope-indexer",
+;; properly installed in order for the following to work. ]
+;;
+;; 1. If all of the directories exist below a common directory
+;; (without any extraneous, unrelated subdirectories), you can tell
+;; this module to place the cscope database into the top-level,
+;; common directory. This assumes that you do not have any cscope
+;; databases in any of the subdirectories. If you do, you should
+;; delete them; otherwise, they will take precedence over the
+;; top-level database.
+;;
+;; If you do have cscope databases in any subdirectory, the
+;; following instructions may not work right.
+;;
+;; It's pretty easy to tell this module to use a top-level, common
+;; directory:
+;;
+;; a. Make sure that the menu pick, "Cscope/Index recursively", is
+;; checked (the default value).
+;;
+;; b. Select the menu pick, "Cscope/Create list and index", and
+;; specify the top-level directory. This will run the script,
+;; "cscope-indexer", in the background, so you can do other
+;; things if indexing takes a long time. A list of files to
+;; index will be created in "cscope.files", and the cscope
+;; database will be created in "cscope.out".
+;;
+;; Once this has been done, you can then use the menu picks
+;; (described in "Basic usage", above) to search for symbols.
+;;
+;; Note, however, that, if you add or delete source files, you'll
+;; have to either rebuild the database using the above procedure,
+;; or edit the file, "cscope.files" to add/delete the names of the
+;; source files. To edit this file, you can use the menu pick,
+;; "Cscope/Edit list of files to index".
+;;
+;;
+;; 2. If most of the files exist below a common directory, but a few
+;; are outside, you can use the menu pick, "Cscope/Create list of
+;; files to index", and specify the top-level directory. Make sure
+;; that "Cscope/Index recursively", is checked before you do so,
+;; though. You can then edit the list of files to index using the
+;; menu pick, "Cscope/Edit list of files to index". Just edit the
+;; list to include any additional source files not already listed.
+;;
+;; Once you've created, edited, and saved the list, you can then
+;; use the menu picks described under "Basic usage", above, to
+;; search for symbols. The first time you search, you will have to
+;; wait a while for cscope to fully index the source files, though.
+;; If you have a lot of source files, you may want to manually run
+;; cscope to build the database:
+;;
+;; cd top-level-directory # or wherever
+;; rm -f cscope.out # not always necessary
+;; cscope -b
+;;
+;;
+;; 3. If the source files are scattered in many different, unrelated
+;; places, you'll have to manually create cscope.files and put a
+;; list of all pathnames into it. Then build the database using:
+;;
+;; cd some-directory # wherever cscope.files exists
+;; rm -f cscope.out # not always necessary
+;; cscope -b
+;;
+;; Next, read the documentation for the variable,
+;; "cscope-database-regexps", and set it appropriately, such that
+;; the above-created cscope database will be referenced when you
+;; edit a related source file.
+;;
+;; Once this has been done, you can then use the menu picks
+;; described under "Basic usage", above, to search for symbols.
+;;
+;;
+;; * Interesting configuration variables:
+;;
+;; "cscope-truncate-lines"
+;; This is the value of `truncate-lines' to use in cscope
+;; buffers; the default is the current setting of
+;; `truncate-lines'. This variable exists because it can be
+;; easier to read cscope buffers with truncated lines, while
+;; other buffers do not have truncated lines.
+;;
+;; "cscope-use-relative-paths"
+;; If non-nil, use relative paths when creating the list of files
+;; to index. The path is relative to the directory in which the
+;; cscope database will be created. If nil, absolute paths will
+;; be used. Absolute paths are good if you plan on moving the
+;; database to some other directory (if you do so, you'll
+;; probably also have to modify `cscope-database-regexps').
+;; Absolute paths may also be good if you share the database file
+;; with other users (you'll probably want to specify some
+;; automounted network path for this).
+;;
+;; "cscope-index-recursively"
+;; If non-nil, index files in the current directory and all
+;; subdirectories. If nil, only files in the current directory
+;; are indexed. This variable is only used when creating the
+;; list of files to index, or when creating the list of files and
+;; the corresponding cscope database.
+;;
+;; "cscope-name-line-width"
+;; The width of the combined "function name:line number" field in
+;; the cscope results buffer. If negative, the field is
+;; left-justified.
+;;
+;; "cscope-do-not-update-database"
+;; If non-nil, never check and/or update the cscope database when
+;; searching. Beware of setting this to non-nil, as this will
+;; disable automatic database creation, updating, and
+;; maintenance.
+;;
+;; "cscope-display-cscope-buffer"
+;; If non-nil, display the *cscope* buffer after each search
+;; (default). This variable can be set in order to reduce the
+;; number of keystrokes required to navigate through the matches.
+;;
+;; "cscope-database-regexps"
+;; List to force directory-to-cscope-database mappings.
+;; This is a list of `(REGEXP DBLIST [ DBLIST ... ])', where:
+;;
+;; REGEXP is a regular expression matched against the current buffer's
+;; current directory. The current buffer is typically some source file,
+;; and you're probably searching for some symbol in or related to this
+;; file. Basically, this regexp is used to relate the current directory
+;; to a cscope database. You need to start REGEXP with "^" if you want
+;; to match from the beginning of the current directory.
+;;
+;; DBLIST is a list that contains one or more of:
+;;
+;; ( DBDIR )
+;; ( DBDIR ( OPTIONS ) )
+;; ( t )
+;; t
+;;
+;; Here, DBDIR is a directory (or a file) that contains a cscope
+;; database. If DBDIR is a directory, then it is expected that the
+;; cscope database, if present, has the filename given by the variable,
+;; `cscope-database-file'; if DBDIR is a file, then DBDIR is the path
+;; name to a cscope database file (which does not have to be the same as
+;; that given by `cscope-database-file'). If only DBDIR is specified,
+;; then that cscope database will be searched without any additional
+;; cscope command-line options. If OPTIONS is given, then OPTIONS is a
+;; list of strings, where each string is a separate cscope command-line
+;; option.
+;;
+;; In the case of "( t )", this specifies that the search is to use the
+;; normal hierarchical database search. This option is used to
+;; explicitly search using the hierarchical database search either before
+;; or after other cscope database directories.
+;;
+;; If "t" is specified (not inside a list), this tells the searching
+;; mechanism to stop searching if a match has been found (at the point
+;; where "t" is encountered). This is useful for those projects that
+;; consist of many subprojects. You can specify the most-used
+;; subprojects first, followed by a "t", and then followed by a master
+;; cscope database directory that covers all subprojects. This will
+;; cause the most-used subprojects to be searched first (hopefully
+;; quickly), and the search will then stop if a match was found. If not,
+;; the search will continue using the master cscope database directory.
+;;
+;; Here, `cscope-database-regexps' is generally not used, as the normal
+;; hierarchical database search is sufficient for placing and/or locating
+;; the cscope databases. However, there may be cases where it makes
+;; sense to place the cscope databases away from where the source files
+;; are kept; in this case, this variable is used to determine the
+;; mapping.
+;;
+;; This module searches for the cscope databases by first using this
+;; variable; if a database location cannot be found using this variable,
+;; then the current directory is searched, then the parent, then the
+;; parent's parent, until a cscope database directory is found, or the
+;; root directory is reached. If the root directory is reached, the
+;; current directory will be used.
+;;
+;; A cscope database directory is one in which EITHER a cscope database
+;; file (e.g., "cscope.out") OR a cscope file list (e.g.,
+;; "cscope.files") exists. If only "cscope.files" exists, the
+;; corresponding "cscope.out" will be automatically created by cscope
+;; when a search is done. By default, the cscope database file is called
+;; "cscope.out", but this can be changed (on a global basis) via the
+;; variable, `cscope-database-file'. There is limited support for cscope
+;; databases that are named differently than that given by
+;; `cscope-database-file', using the variable, `cscope-database-regexps'.
+;;
+;; Here is an example of `cscope-database-regexps':
+;;
+;; (setq cscope-database-regexps
+;; '(
+;; ( "^/users/jdoe/sources/proj1"
+;; ( t )
+;; ( "/users/jdoe/sources/proj2")
+;; ( "/users/jdoe/sources/proj3/mycscope.out")
+;; ( "/users/jdoe/sources/proj4")
+;; t
+;; ( "/some/master/directory" ("-d" "-I/usr/local/include") )
+;; )
+;; ( "^/users/jdoe/sources/gnome/"
+;; ( "/master/gnome/database" ("-d") )
+;; )
+;; ))
+;;
+;; If the current buffer's directory matches the regexp,
+;; "^/users/jdoe/sources/proj1", then the following search will be
+;; done:
+;;
+;; 1. First, the normal hierarchical database search will be used to
+;; locate a cscope database.
+;;
+;; 2. Next, searches will be done using the cscope database
+;; directories, "/users/jdoe/sources/proj2",
+;; "/users/jdoe/sources/proj3/mycscope.out", and
+;; "/users/jdoe/sources/proj4". Note that, instead of the file,
+;; "cscope.out", the file, "mycscope.out", will be used in the
+;; directory "/users/jdoe/sources/proj3".
+;;
+;; 3. If a match was found, searching will stop.
+;;
+;; 4. If a match was not found, searching will be done using
+;; "/some/master/directory", and the command-line options "-d"
+;; and "-I/usr/local/include" will be passed to cscope.
+;;
+;; If the current buffer's directory matches the regexp,
+;; "^/users/jdoe/sources/gnome", then the following search will be
+;; done:
+;;
+;; The search will be done only using the directory,
+;; "/master/gnome/database". The "-d" option will be passed to
+;; cscope.
+;;
+;; If the current buffer's directory does not match any of the above
+;; regexps, then only the normal hierarchical database search will be
+;; done.
+;;
+;;
+;; * Other notes:
+;;
+;; 1. The script, "cscope-indexer", uses a sed command to determine
+;; what is and is not a C/C++/lex/yacc source file. It's idea of a
+;; source file may not correspond to yours.
+;;
+;; 2. This module is called, "xcscope", because someone else has
+;; already written a "cscope.el" (although it's quite old).
+;;
+;;
+;; * KNOWN BUGS:
+;;
+;; 1. Cannot handle whitespace in directory or file names.
+;;
+;; 2. By default, colored faces are used to display results. If you happen
+;; to use a black background, part of the results may be invisible
+;; (because the foreground color may be black, too). There are at least
+;; two solutions for this:
+;;
+;; 2a. Turn off colored faces, by setting `cscope-use-face' to `nil',
+;; e.g.:
+;;
+;; (setq cscope-use-face nil)
+;;
+;; 2b. Explicitly set colors for the faces used by cscope. The faces
+;; are:
+;;
+;; cscope-file-face
+;; cscope-function-face
+;; cscope-line-number-face
+;; cscope-line-face
+;; cscope-mouse-face
+;;
+;; The face most likely to cause problems (e.g., black-on-black
+;; color) is `cscope-line-face'.
+;;
+;; 3. The support for cscope databases different from that specified by
+;; `cscope-database-file' is quirky. If the file does not exist, it
+;; will not be auto-created (unlike files names by
+;; `cscope-database-file'). You can manually force the file to be
+;; created by using touch(1) to create a zero-length file; the
+;; database will be created the next time a search is done.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(require 'easymenu)
+
+
+(defgroup cscope nil
+ "Cscope interface for (X)Emacs.
+Using cscope, you can easily search for where symbols are used and defined.
+It is designed to answer questions like:
+
+ Where is this variable used?
+ What is the value of this preprocessor symbol?
+ Where is this function in the source files?
+ What functions call this function?
+ What functions are called by this function?
+ Where does the message \"out of space\" come from?
+ Where is this source file in the directory structure?
+ What files include this header file?
+"
+ :prefix "cscope-"
+ :group 'tools)
+
+
+(defcustom cscope-do-not-update-database nil
+ "*If non-nil, never check and/or update the cscope database when searching.
+Beware of setting this to non-nil, as this will disable automatic database
+creation, updating, and maintenance."
+ :type 'boolean
+ :group 'cscope)
+
+
+(defcustom cscope-database-regexps nil
+ "*List to force directory-to-cscope-database mappings.
+This is a list of `(REGEXP DBLIST [ DBLIST ... ])', where:
+
+REGEXP is a regular expression matched against the current buffer's
+current directory. The current buffer is typically some source file,
+and you're probably searching for some symbol in or related to this
+file. Basically, this regexp is used to relate the current directory
+to a cscope database. You need to start REGEXP with \"^\" if you want
+to match from the beginning of the current directory.
+
+DBLIST is a list that contains one or more of:
+
+ ( DBDIR )
+ ( DBDIR ( OPTIONS ) )
+ ( t )
+ t
+
+Here, DBDIR is a directory (or a file) that contains a cscope database.
+If DBDIR is a directory, then it is expected that the cscope database,
+if present, has the filename given by the variable,
+`cscope-database-file'; if DBDIR is a file, then DBDIR is the path name
+to a cscope database file (which does not have to be the same as that
+given by `cscope-database-file'). If only DBDIR is specified, then that
+cscope database will be searched without any additional cscope
+command-line options. If OPTIONS is given, then OPTIONS is a list of
+strings, where each string is a separate cscope command-line option.
+
+In the case of \"( t )\", this specifies that the search is to use the
+normal hierarchical database search. This option is used to
+explicitly search using the hierarchical database search either before
+or after other cscope database directories.
+
+If \"t\" is specified (not inside a list), this tells the searching
+mechanism to stop searching if a match has been found (at the point
+where \"t\" is encountered). This is useful for those projects that
+consist of many subprojects. You can specify the most-used
+subprojects first, followed by a \"t\", and then followed by a master
+cscope database directory that covers all subprojects. This will
+cause the most-used subprojects to be searched first (hopefully
+quickly), and the search will then stop if a match was found. If not,
+the search will continue using the master cscope database directory.
+
+Here, `cscope-database-regexps' is generally not used, as the normal
+hierarchical database search is sufficient for placing and/or locating
+the cscope databases. However, there may be cases where it makes
+sense to place the cscope databases away from where the source files
+are kept; in this case, this variable is used to determine the
+mapping.
+
+This module searches for the cscope databases by first using this
+variable; if a database location cannot be found using this variable,
+then the current directory is searched, then the parent, then the
+parent's parent, until a cscope database directory is found, or the
+root directory is reached. If the root directory is reached, the
+current directory will be used.
+
+A cscope database directory is one in which EITHER a cscope database
+file (e.g., \"cscope.out\") OR a cscope file list (e.g.,
+\"cscope.files\") exists. If only \"cscope.files\" exists, the
+corresponding \"cscope.out\" will be automatically created by cscope
+when a search is done. By default, the cscope database file is called
+\"cscope.out\", but this can be changed (on a global basis) via the
+variable, `cscope-database-file'. There is limited support for cscope
+databases that are named differently than that given by
+`cscope-database-file', using the variable, `cscope-database-regexps'.
+
+Here is an example of `cscope-database-regexps':
+
+ (setq cscope-database-regexps
+ '(
+ ( \"^/users/jdoe/sources/proj1\"
+ ( t )
+ ( \"/users/jdoe/sources/proj2\")
+ ( \"/users/jdoe/sources/proj3/mycscope.out\")
+ ( \"/users/jdoe/sources/proj4\")
+ t
+ ( \"/some/master/directory\" (\"-d\" \"-I/usr/local/include\") )
+ )
+ ( \"^/users/jdoe/sources/gnome/\"
+ ( \"/master/gnome/database\" (\"-d\") )
+ )
+ ))
+
+If the current buffer's directory matches the regexp,
+\"^/users/jdoe/sources/proj1\", then the following search will be
+done:
+
+ 1. First, the normal hierarchical database search will be used to
+ locate a cscope database.
+
+ 2. Next, searches will be done using the cscope database
+ directories, \"/users/jdoe/sources/proj2\",
+ \"/users/jdoe/sources/proj3/mycscope.out\", and
+ \"/users/jdoe/sources/proj4\". Note that, instead of the file,
+ \"cscope.out\", the file, \"mycscope.out\", will be used in the
+ directory \"/users/jdoe/sources/proj3\".
+
+ 3. If a match was found, searching will stop.
+
+ 4. If a match was not found, searching will be done using
+ \"/some/master/directory\", and the command-line options \"-d\"
+ and \"-I/usr/local/include\" will be passed to cscope.
+
+If the current buffer's directory matches the regexp,
+\"^/users/jdoe/sources/gnome\", then the following search will be
+done:
+
+ The search will be done only using the directory,
+ \"/master/gnome/database\". The \"-d\" option will be passed to
+ cscope.
+
+If the current buffer's directory does not match any of the above
+regexps, then only the normal hierarchical database search will be
+done.
+
+"
+ :type '(repeat (list :format "%v"
+ (choice :value ""
+ (regexp :tag "Buffer regexp")
+ string)
+ (choice :value ""
+ (directory :tag "Cscope database directory")
+ string)
+ (string :value ""
+ :tag "Optional cscope command-line arguments")
+ ))
+ :group 'cscope)
+(defcustom cscope-name-line-width -30
+ "*The width of the combined \"function name:line number\" field in the
+cscope results buffer. If negative, the field is left-justified."
+ :type 'integer
+ :group 'cscope)
+
+
+(defcustom cscope-truncate-lines truncate-lines
+ "*The value of `truncate-lines' to use in cscope buffers.
+This variable exists because it can be easier to read cscope buffers
+with truncated lines, while other buffers do not have truncated lines."
+ :type 'boolean
+ :group 'cscope)
+
+
+(defcustom cscope-display-times t
+ "*If non-nil, display how long each search took.
+The elasped times are in seconds. Floating-point support is required
+for this to work."
+ :type 'boolean
+ :group 'cscope)
+
+
+(defcustom cscope-program "cscope"
+ "*The pathname of the cscope executable to use."
+ :type 'string
+ :group 'cscope)
+
+
+(defcustom cscope-index-file "cscope.files"
+ "*The name of the cscope file list file."
+ :type 'string
+ :group 'cscope)
+
+
+(defcustom cscope-database-file "cscope.out"
+ "*The name of the cscope database file."
+ :type 'string
+ :group 'cscope)
+
+
+(defcustom cscope-edit-single-match t
+ "*If non-nil and only one match is output, edit the matched location."
+ :type 'boolean
+ :group 'cscope)
+
+
+(defcustom cscope-display-cscope-buffer t
+ "*If non-nil automatically display the *cscope* buffer after each search."
+ :type 'boolean
+ :group 'cscope)
+
+
+(defcustom cscope-stop-at-first-match-dir nil
+ "*If non-nil, stop searching through multiple databases if a match is found.
+This option is useful only if multiple cscope database directories are being
+used. When multiple databases are searched, setting this variable to non-nil
+will cause searches to stop when a search outputs anything; no databases after
+this one will be searched."
+ :type 'boolean
+ :group 'cscope)
+
+
+(defcustom cscope-use-relative-paths t
+ "*If non-nil, use relative paths when creating the list of files to index.
+The path is relative to the directory in which the cscope database
+will be created. If nil, absolute paths will be used. Absolute paths
+are good if you plan on moving the database to some other directory
+(if you do so, you'll probably also have to modify
+\`cscope-database-regexps\'). Absolute paths may also be good if you
+share the database file with other users (you\'ll probably want to
+specify some automounted network path for this)."
+ :type 'boolean
+ :group 'cscope)
+
+
+(defcustom cscope-index-recursively t
+ "*If non-nil, index files in the current directory and all subdirectories.
+If nil, only files in the current directory are indexed. This
+variable is only used when creating the list of files to index, or
+when creating the list of files and the corresponding cscope database."
+ :type 'boolean
+ :group 'cscope)
+
+
+(defcustom cscope-no-mouse-prompts nil
+ "*If non-nil, use the symbol under the cursor instead of prompting.
+Do not prompt for a value, except for when seaching for a egrep pattern
+or a file."
+ :type 'boolean
+ :group 'cscope)
+
+
+(defcustom cscope-suppress-empty-matches t
+ "*If non-nil, delete empty matches.")
+
+
+(defcustom cscope-indexing-script "cscope-indexer"
+ "*The shell script used to create cscope indices."
+ :type 'string
+ :group 'cscope)
+
+
+(defcustom cscope-symbol-chars "A-Za-z0-9_"
+ "*A string containing legal characters in a symbol.
+The current syntax table should really be used for this."
+ :type 'string
+ :group 'cscope)
+
+
+(defcustom cscope-filename-chars "-.,/A-Za-z0-9_~!@#$%&+=\\\\"
+ "*A string containing legal characters in a symbol.
+The current syntax table should really be used for this."
+ :type 'string
+ :group 'cscope)
+
+
+(defcustom cscope-allow-arrow-overlays t
+ "*If non-nil, use an arrow overlay to show target lines.
+Arrow overlays are only used when the following functions are used:
+
+ cscope-show-entry-other-window
+ cscope-show-next-entry-other-window
+ cscope-show-prev-entry-other-window
+
+The arrow overlay is removed when other cscope functions are used.
+Note that the arrow overlay is not an actual part of the text, and can
+be removed by quitting the cscope buffer."
+ :type 'boolean
+ :group 'cscope)
+
+
+(defcustom cscope-overlay-arrow-string "=>"
+ "*The overlay string to use when displaying arrow overlays."
+ :type 'string
+ :group 'cscope)
+
+
+(defvar cscope-minor-mode-hooks nil
+ "List of hooks to call when entering cscope-minor-mode.")
+
+
+(defconst cscope-separator-line
+ "-------------------------------------------------------------------------------\n"
+ "Line of text to use as a visual separator.
+Must end with a newline.")
+
+
+;;;;
+;;;; Faces for fontification
+;;;;
+
+(defcustom cscope-use-face t
+ "*Whether to use text highlighting (à la font-lock) or not."
+ :group 'cscope
+ :type '(boolean))
+
+
+(defface cscope-file-face
+ '((((class color) (background dark))
+ (:foreground "yellow"))
+ (((class color) (background light))
+ (:foreground "blue"))
+ (t (:bold t)))
+ "Face used to highlight file name in the *cscope* buffer."
+ :group 'cscope)
+
+
+(defface cscope-function-face
+ '((((class color) (background dark))
+ (:foreground "cyan"))
+ (((class color) (background light))
+ (:foreground "magenta"))
+ (t (:bold t)))
+ "Face used to highlight function name in the *cscope* buffer."
+ :group 'cscope)
+
+
+(defface cscope-line-number-face
+ '((((class color) (background dark))
+ (:foreground "red"))
+ (((class color) (background light))
+ (:foreground "red"))
+ (t (:bold t)))
+ "Face used to highlight line number in the *cscope* buffer."
+ :group 'cscope)
+
+
+(defface cscope-line-face
+ '((((class color) (background dark))
+ (:foreground "green"))
+ (((class color) (background light))
+ (:foreground "black"))
+ (t (:bold nil)))
+ "Face used to highlight the rest of line in the *cscope* buffer."
+ :group 'cscope)
+
+
+(defface cscope-mouse-face
+ '((((class color) (background dark))
+ (:foreground "white" :background "blue"))
+ (((class color) (background light))
+ (:foreground "white" :background "blue"))
+ (t (:bold nil)))
+ "Face used when mouse pointer is within the region of an entry."
+ :group 'cscope)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Probably, nothing user-customizable past this point.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(defconst cscope-running-in-xemacs (string-match "XEmacs\\|Lucid" emacs-version))
+
+(defvar cscope-list-entry-keymap nil
+ "The keymap used in the *cscope* buffer which lists search results.")
+(if cscope-list-entry-keymap
+ nil
+ (setq cscope-list-entry-keymap (make-keymap))
+ (suppress-keymap cscope-list-entry-keymap)
+ ;; The following section does not appear in the "Cscope" menu.
+ (if cscope-running-in-xemacs
+ (define-key cscope-list-entry-keymap [button2] 'cscope-mouse-select-entry-other-window)
+ (define-key cscope-list-entry-keymap [mouse-2] 'cscope-mouse-select-entry-other-window))
+ (define-key cscope-list-entry-keymap [return] 'cscope-select-entry-other-window)
+ (define-key cscope-list-entry-keymap " " 'cscope-show-entry-other-window)
+ (define-key cscope-list-entry-keymap "o" 'cscope-select-entry-one-window)
+ (define-key cscope-list-entry-keymap "q" 'cscope-bury-buffer)
+ (define-key cscope-list-entry-keymap "Q" 'cscope-quit)
+ (define-key cscope-list-entry-keymap "h" 'cscope-help)
+ (define-key cscope-list-entry-keymap "?" 'cscope-help)
+ ;; The following line corresponds to be beginning of the "Cscope" menu.
+ (define-key cscope-list-entry-keymap "s" 'cscope-find-this-symbol)
+ (define-key cscope-list-entry-keymap "d" 'cscope-find-this-symbol)
+ (define-key cscope-list-entry-keymap "g" 'cscope-find-global-definition)
+ (define-key cscope-list-entry-keymap "G"
+ 'cscope-find-global-definition-no-prompting)
+ (define-key cscope-list-entry-keymap "c" 'cscope-find-functions-calling-this-function)
+ (define-key cscope-list-entry-keymap "C" 'cscope-find-called-functions)
+ (define-key cscope-list-entry-keymap "t" 'cscope-find-this-text-string)
+ (define-key cscope-list-entry-keymap "e" 'cscope-find-egrep-pattern)
+ (define-key cscope-list-entry-keymap "f" 'cscope-find-this-file)
+ (define-key cscope-list-entry-keymap "i" 'cscope-find-files-including-file)
+ ;; --- (The '---' indicates that this line corresponds to a menu separator.)
+ (define-key cscope-list-entry-keymap "n" 'cscope-next-symbol)
+ (define-key cscope-list-entry-keymap "N" 'cscope-next-file)
+ (define-key cscope-list-entry-keymap "p" 'cscope-prev-symbol)
+ (define-key cscope-list-entry-keymap "P" 'cscope-prev-file)
+ (define-key cscope-list-entry-keymap "u" 'cscope-pop-mark)
+ ;; ---
+ (define-key cscope-list-entry-keymap "a" 'cscope-set-initial-directory)
+ (define-key cscope-list-entry-keymap "A" 'cscope-unset-initial-directory)
+ ;; ---
+ (define-key cscope-list-entry-keymap "L" 'cscope-create-list-of-files-to-index)
+ (define-key cscope-list-entry-keymap "I" 'cscope-index-files)
+ (define-key cscope-list-entry-keymap "E" 'cscope-edit-list-of-files-to-index)
+ (define-key cscope-list-entry-keymap "W" 'cscope-tell-user-about-directory)
+ (define-key cscope-list-entry-keymap "S" 'cscope-tell-user-about-directory)
+ (define-key cscope-list-entry-keymap "T" 'cscope-tell-user-about-directory)
+ (define-key cscope-list-entry-keymap "D" 'cscope-dired-directory)
+ ;; The previous line corresponds to be end of the "Cscope" menu.
+ )
+
+
+(defvar cscope-list-entry-hook nil
+ "*Hook run after cscope-list-entry-mode entered.")
+
+
+(defun cscope-list-entry-mode ()
+ "Major mode for jumping/showing entry from the list in the *cscope* buffer.
+
+\\{cscope-list-entry-keymap}"
+ (use-local-map cscope-list-entry-keymap)
+ (setq buffer-read-only t
+ mode-name "cscope"
+ major-mode 'cscope-list-entry-mode
+ overlay-arrow-string cscope-overlay-arrow-string)
+ (or overlay-arrow-position
+ (setq overlay-arrow-position (make-marker)))
+ (run-hooks 'cscope-list-entry-hook))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar cscope-output-buffer-name "*cscope*"
+ "The name of the cscope output buffer.")
+
+
+(defvar cscope-info-buffer-name "*cscope-info*"
+ "The name of the cscope information buffer.")
+
+
+(defvar cscope-process nil
+ "The current cscope process.")
+(make-variable-buffer-local 'cscope-process)
+
+
+(defvar cscope-process-output nil
+ "A buffer for holding partial cscope process output.")
+(make-variable-buffer-local 'cscope-process-output)
+
+
+(defvar cscope-command-args nil
+ "Internal variable for holding major command args to pass to cscope.")
+(make-variable-buffer-local 'cscope-command-args)
+
+
+(defvar cscope-start-directory nil
+ "Internal variable used to save the initial start directory.
+The results buffer gets reset to this directory when a search has
+completely finished.")
+(make-variable-buffer-local 'cscope-start-directory)
+
+
+(defvar cscope-search-list nil
+ "A list of (DIR . FLAGS) entries.
+This is a list of database directories to search. Each entry in the list
+is a (DIR . FLAGS) cell. DIR is the directory to search, and FLAGS are the
+flags to pass to cscope when using this database directory. FLAGS can be
+nil (meaning, \"no flags\").")
+(make-variable-buffer-local 'cscope-search-list)
+
+
+(defvar cscope-searched-dirs nil
+ "The list of database directories already searched.")
+(make-variable-buffer-local 'cscope-searched-dirs)
+
+
+(defvar cscope-filter-func nil
+ "Internal variable for holding the filter function to use (if any) when
+searching.")
+(make-variable-buffer-local 'cscope-filter-func)
+
+
+(defvar cscope-sentinel-func nil
+ "Internal variable for holding the sentinel function to use (if any) when
+searching.")
+(make-variable-buffer-local 'cscope-filter-func)
+
+
+(defvar cscope-last-file nil
+ "The file referenced by the last line of cscope process output.")
+(make-variable-buffer-local 'cscope-last-file)
+
+
+(defvar cscope-start-time nil
+ "The search start time, in seconds.")
+(make-variable-buffer-local 'cscope-start-time)
+
+
+(defvar cscope-first-match nil
+ "The first match result output by cscope.")
+(make-variable-buffer-local 'cscope-first-match)
+
+
+(defvar cscope-first-match-point nil
+ "Buffer location of the first match.")
+(make-variable-buffer-local 'cscope-first-match-point)
+
+
+(defvar cscope-item-start nil
+ "The point location of the start of a search's output, before header info.")
+(make-variable-buffer-local 'cscope-output-start)
+
+
+(defvar cscope-output-start nil
+ "The point location of the start of a search's output.")
+(make-variable-buffer-local 'cscope-output-start)
+
+
+(defvar cscope-matched-multiple nil
+ "Non-nil if cscope output multiple matches.")
+(make-variable-buffer-local 'cscope-matched-multiple)
+
+
+(defvar cscope-stop-at-first-match-dir-meta nil
+ "")
+(make-variable-buffer-local 'cscope-stop-at-first-match-dir-meta)
+
+
+(defvar cscope-symbol nil
+ "The last symbol searched for.")
+
+
+(defvar cscope-adjust t
+ "True if the symbol searched for (cscope-symbol) should be on
+the line specified by the cscope database. In such cases the point will be
+adjusted if need be (fuzzy matching).")
+
+
+(defvar cscope-adjust-range 1000
+ "How far the point should be adjusted if the symbol is not on the line
+specified by the cscope database.")
+
+
+(defvar cscope-marker nil
+ "The location from which cscope was invoked.")
+
+
+(defvar cscope-marker-window nil
+ "The window which should contain cscope-marker. This is the window from
+which cscope-marker is set when searches are launched from the *cscope*
+buffer.")
+
+
+(defvar cscope-marker-ring-length 16
+ "Length of the cscope marker ring.")
+
+
+(defvar cscope-marker-ring (make-ring cscope-marker-ring-length)
+ "Ring of markers which are locations from which cscope was invoked.")
+
+
+(defvar cscope-initial-directory nil
+ "When set the directory in which searches for the cscope database
+directory should begin.")
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar cscope:map nil
+ "The cscope keymap.")
+(if cscope:map
+ nil
+ (setq cscope:map (make-sparse-keymap))
+ ;; The following line corresponds to be beginning of the "Cscope" menu.
+ (define-key cscope:map "\C-css" 'cscope-find-this-symbol)
+ (define-key cscope:map "\C-csd" 'cscope-find-global-definition)
+ (define-key cscope:map "\C-csg" 'cscope-find-global-definition)
+ (define-key cscope:map "\C-csG" 'cscope-find-global-definition-no-prompting)
+ (define-key cscope:map "\C-csc" 'cscope-find-functions-calling-this-function)
+ (define-key cscope:map "\C-csC" 'cscope-find-called-functions)
+ (define-key cscope:map "\C-cst" 'cscope-find-this-text-string)
+ (define-key cscope:map "\C-cse" 'cscope-find-egrep-pattern)
+ (define-key cscope:map "\C-csf" 'cscope-find-this-file)
+ (define-key cscope:map "\C-csi" 'cscope-find-files-including-file)
+ ;; --- (The '---' indicates that this line corresponds to a menu separator.)
+ (define-key cscope:map "\C-csb" 'cscope-display-buffer)
+ (define-key cscope:map "\C-csB" 'cscope-display-buffer-toggle)
+ (define-key cscope:map "\C-csn" 'cscope-next-symbol)
+ (define-key cscope:map "\C-csN" 'cscope-next-file)
+ (define-key cscope:map "\C-csp" 'cscope-prev-symbol)
+ (define-key cscope:map "\C-csP" 'cscope-prev-file)
+ (define-key cscope:map "\C-csu" 'cscope-pop-mark)
+ ;; ---
+ (define-key cscope:map "\C-csa" 'cscope-set-initial-directory)
+ (define-key cscope:map "\C-csA" 'cscope-unset-initial-directory)
+ ;; ---
+ (define-key cscope:map "\C-csL" 'cscope-create-list-of-files-to-index)
+ (define-key cscope:map "\C-csI" 'cscope-index-files)
+ (define-key cscope:map "\C-csE" 'cscope-edit-list-of-files-to-index)
+ (define-key cscope:map "\C-csW" 'cscope-tell-user-about-directory)
+ (define-key cscope:map "\C-csS" 'cscope-tell-user-about-directory)
+ (define-key cscope:map "\C-csT" 'cscope-tell-user-about-directory)
+ (define-key cscope:map "\C-csD" 'cscope-dired-directory))
+ ;; The previous line corresponds to be end of the "Cscope" menu.
+
+(easy-menu-define cscope:menu
+ (list cscope:map cscope-list-entry-keymap)
+ "cscope menu"
+ '("Cscope"
+ [ "Find symbol" cscope-find-this-symbol t ]
+ [ "Find global definition" cscope-find-global-definition t ]
+ [ "Find global definition no prompting"
+ cscope-find-global-definition-no-prompting t ]
+ [ "Find functions calling a function"
+ cscope-find-functions-calling-this-function t ]
+ [ "Find called functions" cscope-find-called-functions t ]
+ [ "Find text string" cscope-find-this-text-string t ]
+ [ "Find egrep pattern" cscope-find-egrep-pattern t ]
+ [ "Find a file" cscope-find-this-file t ]
+ [ "Find files #including a file"
+ cscope-find-files-including-file t ]
+ "-----------"
+ [ "Display *cscope* buffer" cscope-display-buffer t ]
+ [ "Auto display *cscope* buffer toggle"
+ cscope-display-buffer-toggle t ]
+ [ "Next symbol" cscope-next-symbol t ]
+ [ "Next file" cscope-next-file t ]
+ [ "Previous symbol" cscope-prev-symbol t ]
+ [ "Previous file" cscope-prev-file t ]
+ [ "Pop mark" cscope-pop-mark t ]
+ "-----------"
+ ( "Cscope Database"
+ [ "Set initial directory"
+ cscope-set-initial-directory t ]
+ [ "Unset initial directory"
+ cscope-unset-initial-directory t ]
+ "-----------"
+ [ "Create list of files to index"
+ cscope-create-list-of-files-to-index t ]
+ [ "Create list and index"
+ cscope-index-files t ]
+ [ "Edit list of files to index"
+ cscope-edit-list-of-files-to-index t ]
+ [ "Locate this buffer's cscope directory"
+ cscope-tell-user-about-directory t ]
+ [ "Dired this buffer's cscope directory"
+ cscope-dired-directory t ]
+ )
+ "-----------"
+ ( "Options"
+ [ "Auto edit single match"
+ (setq cscope-edit-single-match
+ (not cscope-edit-single-match))
+ :style toggle :selected cscope-edit-single-match ]
+ [ "Auto display *cscope* buffer"
+ (setq cscope-display-cscope-buffer
+ (not cscope-display-cscope-buffer))
+ :style toggle :selected cscope-display-cscope-buffer ]
+ [ "Stop at first matching database"
+ (setq cscope-stop-at-first-match-dir
+ (not cscope-stop-at-first-match-dir))
+ :style toggle
+ :selected cscope-stop-at-first-match-dir ]
+ [ "Never update cscope database"
+ (setq cscope-do-not-update-database
+ (not cscope-do-not-update-database))
+ :style toggle :selected cscope-do-not-update-database ]
+ [ "Index recursively"
+ (setq cscope-index-recursively
+ (not cscope-index-recursively))
+ :style toggle :selected cscope-index-recursively ]
+ [ "Suppress empty matches"
+ (setq cscope-suppress-empty-matches
+ (not cscope-suppress-empty-matches))
+ :style toggle :selected cscope-suppress-empty-matches ]
+ [ "Use relative paths"
+ (setq cscope-use-relative-paths
+ (not cscope-use-relative-paths))
+ :style toggle :selected cscope-use-relative-paths ]
+ [ "No mouse prompts" (setq cscope-no-mouse-prompts
+ (not cscope-no-mouse-prompts))
+ :style toggle :selected cscope-no-mouse-prompts ]
+ )
+ ))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Internal functions and variables
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar cscope-common-text-plist
+ (let (plist)
+ (setq plist (plist-put plist 'mouse-face 'cscope-mouse-face))
+ plist)
+ "List of common text properties to be added to the entry line.")
+
+
+(defun cscope-insert-with-text-properties (text filename &optional line-number)
+ "Insert an entry with given TEXT, add entry attributes as text properties.
+The text properties to be added:
+- common property: mouse-face,
+- properties are used to open target file and its location: cscope-file,
+ cscope-line-number"
+ (let ((plist cscope-common-text-plist)
+ beg end)
+ (setq beg (point))
+ (insert text)
+ (setq end (point)
+ plist (plist-put plist 'cscope-file filename))
+ (if line-number
+ (progn
+ (if (stringp line-number)
+ (setq line-number (string-to-number line-number)))
+ (setq plist (plist-put plist 'cscope-line-number line-number))
+ ))
+ (add-text-properties beg end plist)
+ ))
+
+
+(if cscope-running-in-xemacs
+ (progn
+ (defalias 'cscope-event-window 'event-window)
+ (defalias 'cscope-event-point 'event-point)
+ (defalias 'cscope-recenter 'recenter)
+ )
+ (defun cscope-event-window (event)
+ "Return the window at which the mouse EVENT occurred."
+ (posn-window (event-start event)))
+ (defun cscope-event-point (event)
+ "Return the point at which the mouse EVENT occurred."
+ (posn-point (event-start event)))
+ (defun cscope-recenter (&optional n window)
+ "Center point in WINDOW and redisplay frame. With N, put point on line N."
+ (save-selected-window
+ (if (windowp window)
+ (select-window window))
+ (recenter n)))
+ )
+
+
+(defun cscope-show-entry-internal (file line-number
+ &optional save-mark-p window arrow-p)
+ "Display the buffer corresponding to FILE and LINE-NUMBER
+in some window. If optional argument WINDOW is given,
+display the buffer in that WINDOW instead. The window is
+not selected. Save point on mark ring before goto
+LINE-NUMBER if optional argument SAVE-MARK-P is non-nil.
+Put `overlay-arrow-string' if arrow-p is non-nil.
+Returns the window displaying BUFFER."
+ (let (buffer old-pos old-point new-point forward-point backward-point
+ line-end line-length)
+ (if (and (stringp file)
+ (integerp line-number))
+ (progn
+ (unless (file-readable-p file)
+ (error "%s is not readable or exists" file))
+ (setq buffer (find-file-noselect file))
+ (if (windowp window)
+ (set-window-buffer window buffer)
+ (setq window (display-buffer buffer)))
+ (set-buffer buffer)
+ (if (> line-number 0)
+ (progn
+ (setq old-pos (point))
+ (goto-line line-number)
+ (setq old-point (point))
+ (if (and cscope-adjust cscope-adjust-range)
+ (progn
+ ;; Calculate the length of the line specified by cscope.
+ (end-of-line)
+ (setq line-end (point))
+ (goto-char old-point)
+ (setq line-length (- line-end old-point))
+
+ ;; Search forward and backward for the pattern.
+ (setq forward-point (search-forward
+ cscope-symbol
+ (+ old-point
+ cscope-adjust-range) t))
+ (goto-char old-point)
+ (setq backward-point (search-backward
+ cscope-symbol
+ (- old-point
+ cscope-adjust-range) t))
+ (if forward-point
+ (progn
+ (if backward-point
+ (setq new-point
+ ;; Use whichever of forward-point or
+ ;; backward-point is closest to old-point.
+ ;; Give forward-point a line-length advantage
+ ;; so that if the symbol is on the current
+ ;; line the current line is chosen.
+ (if (<= (- (- forward-point line-length)
+ old-point)
+ (- old-point backward-point))
+ forward-point
+ backward-point))
+ (setq new-point forward-point)))
+ (if backward-point
+ (setq new-point backward-point)
+ (setq new-point old-point)))
+ (goto-char new-point)
+ (beginning-of-line)
+ (setq new-point (point)))
+ (setq new-point old-point))
+ (set-window-point window new-point)
+ (if (and cscope-allow-arrow-overlays arrow-p)
+ (set-marker overlay-arrow-position (point))
+ (set-marker overlay-arrow-position nil))
+ (or (not save-mark-p)
+ (= old-pos (point))
+ (push-mark old-pos))
+ ))
+
+ (if cscope-marker
+ (progn ;; The search was successful. Save the marker so it
+ ;; can be returned to by cscope-pop-mark.
+ (ring-insert cscope-marker-ring cscope-marker)
+ ;; Unset cscope-marker so that moving between matches
+ ;; (cscope-next-symbol, etc.) does not fill
+ ;; cscope-marker-ring.
+ (setq cscope-marker nil)))
+ (setq cscope-marker-window window)
+ )
+ (message "No entry found at point."))
+ )
+ window)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; functions in *cscope* buffer which lists the search results
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun cscope-select-entry-other-window ()
+ "Display the entry at point in other window, select the window.
+Push current point on mark ring and select the entry window."
+ (interactive)
+ (let ((file (get-text-property (point) 'cscope-file))
+ (line-number (get-text-property (point) 'cscope-line-number))
+ window)
+ (setq window (cscope-show-entry-internal file line-number t))
+ (if (windowp window)
+ (select-window window))
+ ))
+
+
+(defun cscope-select-entry-one-window ()
+ "Display the entry at point in one window, select the window."
+ (interactive)
+ (let ((file (get-text-property (point) 'cscope-file))
+ (line-number (get-text-property (point) 'cscope-line-number))
+ window)
+ (setq window (cscope-show-entry-internal file line-number t))
+ (if (windowp window)
+ (progn
+ (select-window window)
+ (sit-for 0) ;; Redisplay hack to allow delete-other-windows
+ ;; to continue displaying the correct location.
+ (delete-other-windows window)
+ ))
+ ))
+
+
+(defun cscope-select-entry-specified-window (window)
+ "Display the entry at point in a specified window, select the window."
+ (interactive)
+ (let ((file (get-text-property (point) 'cscope-file))
+ (line-number (get-text-property (point) 'cscope-line-number)))
+ (setq window (cscope-show-entry-internal file line-number t window))
+ (if (windowp window)
+ (select-window window))
+ ))
+
+
+(defun cscope-mouse-select-entry-other-window (event)
+ "Display the entry over which the mouse event occurred, select the window."
+ (interactive "e")
+ (let ((ep (cscope-event-point event))
+ (win (cscope-event-window event))
+ buffer file line-number window)
+ (if ep
+ (progn
+ (setq buffer (window-buffer win)
+ file (get-text-property ep 'cscope-file buffer)
+ line-number (get-text-property ep 'cscope-line-number buffer))
+ (select-window win)
+ (setq window (cscope-show-entry-internal file line-number t))
+ (if (windowp window)
+ (select-window window))
+ )
+ (message "No entry found at point.")
+ )
+ ))
+
+
+(defun cscope-show-entry-other-window ()
+ "Display the entry at point in other window.
+Point is not saved on mark ring."
+ (interactive)
+ (let ((file (get-text-property (point) 'cscope-file))
+ (line-number (get-text-property (point) 'cscope-line-number)))
+ (cscope-show-entry-internal file line-number nil nil t)
+ ))
+
+
+(defun cscope-buffer-search (do-symbol do-next)
+ "The body of the following four functions."
+ (let* (line-number old-point point
+ (search-file (not do-symbol))
+ (search-prev (not do-next))
+ (direction (if do-next 1 -1))
+ (old-buffer (current-buffer))
+ (old-buffer-window (get-buffer-window old-buffer))
+ (buffer (get-buffer cscope-output-buffer-name))
+ (buffer-window (get-buffer-window (or buffer (error "The *cscope* buffer does not exist yet"))))
+ )
+ (set-buffer buffer)
+ (setq old-point (point))
+ (forward-line direction)
+ (setq point (point))
+ (setq line-number (get-text-property point 'cscope-line-number))
+ (while (or (not line-number)
+ (or (and do-symbol (= line-number -1))
+ (and search-file (/= line-number -1))))
+ (forward-line direction)
+ (setq point (point))
+ (if (or (and do-next (>= point (point-max)))
+ (and search-prev (<= point (point-min))))
+ (progn
+ (goto-char old-point)
+ (error "The %s of the *cscope* buffer has been reached"
+ (if do-next "end" "beginning"))))
+ (setq line-number (get-text-property point 'cscope-line-number)))
+ (if (eq old-buffer buffer) ;; In the *cscope* buffer.
+ (cscope-show-entry-other-window)
+ (cscope-select-entry-specified-window old-buffer-window) ;; else
+ (if (windowp buffer-window)
+ (set-window-point buffer-window point)))
+ (set-buffer old-buffer)
+ ))
+
+
+(defun cscope-display-buffer ()
+ "Display the *cscope* buffer."
+ (interactive)
+ (let ((buffer (get-buffer cscope-output-buffer-name)))
+ (if buffer
+ (pop-to-buffer buffer)
+ (error "The *cscope* buffer does not exist yet"))))
+
+
+(defun cscope-display-buffer-toggle ()
+ "Toggle cscope-display-cscope-buffer, which corresponds to
+\"Auto display *cscope* buffer\"."
+ (interactive)
+ (setq cscope-display-cscope-buffer (not cscope-display-cscope-buffer))
+ (message "The cscope-display-cscope-buffer variable is now %s."
+ (if cscope-display-cscope-buffer "set" "unset")))
+
+
+(defun cscope-next-symbol ()
+ "Move to the next symbol in the *cscope* buffer."
+ (interactive)
+ (cscope-buffer-search t t))
+
+
+(defun cscope-next-file ()
+ "Move to the next file in the *cscope* buffer."
+ (interactive)
+ (cscope-buffer-search nil t))
+
+
+(defun cscope-prev-symbol ()
+ "Move to the previous symbol in the *cscope* buffer."
+ (interactive)
+ (cscope-buffer-search t nil))
+
+
+(defun cscope-prev-file ()
+ "Move to the previous file in the *cscope* buffer."
+ (interactive)
+ (cscope-buffer-search nil nil))
+
+
+(defun cscope-pop-mark ()
+ "Pop back to where cscope was last invoked."
+ (interactive)
+
+ ;; This function is based on pop-tag-mark, which can be found in
+ ;; lisp/progmodes/etags.el.
+
+ (if (ring-empty-p cscope-marker-ring)
+ (error "There are no marked buffers in the cscope-marker-ring yet"))
+ (let* ( (marker (ring-remove cscope-marker-ring 0))
+ (old-buffer (current-buffer))
+ (marker-buffer (marker-buffer marker))
+ marker-window
+ (marker-point (marker-position marker))
+ (cscope-buffer (get-buffer cscope-output-buffer-name)) )
+
+ ;; After the following both cscope-marker-ring and cscope-marker will be
+ ;; in the state they were immediately after the last search. This way if
+ ;; the user now makes a selection in the previously generated *cscope*
+ ;; buffer things will behave the same way as if that selection had been
+ ;; made immediately after the last search.
+ (setq cscope-marker marker)
+
+ (if marker-buffer
+ (if (eq old-buffer cscope-buffer)
+ (progn ;; In the *cscope* buffer.
+ (set-buffer marker-buffer)
+ (setq marker-window (display-buffer marker-buffer))
+ (set-window-point marker-window marker-point)
+ (select-window marker-window))
+ (switch-to-buffer marker-buffer))
+ (error "The marked buffer has been deleted"))
+ (goto-char marker-point)
+ (set-buffer old-buffer)))
+
+
+(defun cscope-set-initial-directory (cs-id)
+ "Set the cscope-initial-directory variable. The
+cscope-initial-directory variable, when set, specifies the directory
+where searches for the cscope database directory should begin. This
+overrides the current directory, which would otherwise be used."
+ (interactive "DCscope Initial Directory: ")
+ (setq cscope-initial-directory cs-id))
+
+
+(defun cscope-unset-initial-directory ()
+ "Unset the cscope-initial-directory variable."
+ (interactive)
+ (setq cscope-initial-directory nil)
+ (message "The cscope-initial-directory variable is now unset."))
+
+
+(defun cscope-help ()
+ (interactive)
+ (message
+ (format "RET=%s, SPC=%s, o=%s, n=%s, p=%s, q=%s, h=%s"
+ "Select"
+ "Show"
+ "SelectOneWin"
+ "ShowNext"
+ "ShowPrev"
+ "Quit"
+ "Help")))
+
+
+(defun cscope-bury-buffer ()
+ "Clean up cscope, if necessary, and bury the buffer."
+ (interactive)
+ (let ()
+ (if overlay-arrow-position
+ (set-marker overlay-arrow-position nil))
+ (setq overlay-arrow-position nil
+ overlay-arrow-string nil)
+ (bury-buffer (get-buffer cscope-output-buffer-name))
+ ))
+
+
+(defun cscope-quit ()
+ (interactive)
+ (cscope-bury-buffer)
+ (kill-buffer cscope-output-buffer-name)
+ )
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun cscope-canonicalize-directory (dir)
+ (or dir
+ (setq dir default-directory))
+ (setq dir (file-name-as-directory
+ (expand-file-name (substitute-in-file-name dir))))
+ dir
+ )
+
+
+(defun cscope-search-directory-hierarchy (directory)
+ "Look for a cscope database in the directory hierarchy.
+Starting from DIRECTORY, look upwards for a cscope database."
+ (let (this-directory database-dir)
+ (catch 'done
+ (if (file-regular-p directory)
+ (throw 'done directory))
+ (setq directory (cscope-canonicalize-directory directory)
+ this-directory directory)
+ (while this-directory
+ (if (or (file-exists-p (concat this-directory cscope-database-file))
+ (file-exists-p (concat this-directory cscope-index-file)))
+ (progn
+ (setq database-dir this-directory)
+ (throw 'done database-dir)
+ ))
+ (if (string-match "^\\(/\\|[A-Za-z]:[\\/]\\)$" this-directory)
+ (throw 'done directory))
+ (setq this-directory (file-name-as-directory
+ (file-name-directory
+ (directory-file-name this-directory))))
+ ))
+ ))
+
+
+(defun cscope-find-info (top-directory)
+ "Locate a suitable cscope database directory.
+First, `cscope-database-regexps' is used to search for a suitable
+database directory. If a database location cannot be found using this
+variable, then the current directory is searched, then the parent,
+then the parent's parent, until a cscope database directory is found,
+or the root directory is reached. If the root directory is reached,
+the current directory will be used."
+ (let (info regexps dir-regexp this-directory)
+ (setq top-directory (cscope-canonicalize-directory
+ (or top-directory cscope-initial-directory)))
+ (catch 'done
+ ;; Try searching using `cscope-database-regexps' ...
+ (setq regexps cscope-database-regexps)
+ (while regexps
+ (setq dir-regexp (car (car regexps)))
+ (cond
+ ( (stringp dir-regexp)
+ (if (string-match dir-regexp top-directory)
+ (progn
+ (setq info (cdr (car regexps)))
+ (throw 'done t)
+ )) )
+ ( (and (symbolp dir-regexp) dir-regexp)
+ (progn
+ (setq info (cdr (car regexps)))
+ (throw 'done t)
+ ) ))
+ (setq regexps (cdr regexps))
+ )
+
+ ;; Try looking in the directory hierarchy ...
+ (if (setq this-directory
+ (cscope-search-directory-hierarchy top-directory))
+ (progn
+ (setq info (list (list this-directory)))
+ (throw 'done t)
+ ))
+
+ ;; Should we add any more places to look?
+
+ ) ;; end catch
+ (if (not info)
+ (setq info (list (list top-directory))))
+ info
+ ))
+
+
+(defun cscope-make-entry-line (func-name line-number line)
+ ;; The format of entry line:
+ ;; func-name[line-number]______line
+ ;; <- cscope-name-line-width ->
+ ;; `format' of Emacs doesn't have "*s" spec.
+ (let* ((fmt (format "%%%ds %%s" cscope-name-line-width))
+ (str (format fmt (format "%s[%s]" func-name line-number) line))
+ beg end)
+ (if cscope-use-face
+ (progn
+ (setq end (length func-name))
+ (put-text-property 0 end 'face 'cscope-function-face str)
+ (setq beg (1+ end)
+ end (+ beg (length line-number)))
+ (put-text-property beg end 'face 'cscope-line-number-face str)
+ (setq end (length str)
+ beg (- end (length line)))
+ (put-text-property beg end 'face 'cscope-line-face str)
+ ))
+ str))
+
+
+(defun cscope-process-filter (process output)
+ "Accept cscope process output and reformat it for human readability.
+Magic text properties are added to allow the user to select lines
+using the mouse."
+ (let ( (old-buffer (current-buffer)) )
+ (unwind-protect
+ (progn
+ (set-buffer (process-buffer process))
+ ;; Make buffer-read-only nil
+ (let (buffer-read-only line file function-name line-number moving)
+ (setq moving (= (point) (process-mark process)))
+ (save-excursion
+ (goto-char (process-mark process))
+ ;; Get the output thus far ...
+ (if cscope-process-output
+ (setq cscope-process-output (concat cscope-process-output
+ output))
+ (setq cscope-process-output output))
+ ;; Slice and dice it into lines.
+ ;; While there are whole lines left ...
+ (while (and cscope-process-output
+ (string-match "\\([^\n]+\n\\)\\(\\(.\\|\n\\)*\\)"
+ cscope-process-output))
+ (setq file nil
+ glimpse-stripped-directory nil
+ )
+ ;; Get a line
+ (setq line (substring cscope-process-output
+ (match-beginning 1) (match-end 1)))
+ (setq cscope-process-output (substring cscope-process-output
+ (match-beginning 2)
+ (match-end 2)))
+ (if (= (length cscope-process-output) 0)
+ (setq cscope-process-output nil))
+
+ ;; This should always match.
+ (if (string-match
+ "^\\([^ \t]+\\)[ \t]+\\([^ \t]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\(.*\\)\n"
+ line)
+ (progn
+ (let (str)
+ (setq file (substring line (match-beginning 1)
+ (match-end 1))
+ function-name (substring line (match-beginning 2)
+ (match-end 2))
+ line-number (substring line (match-beginning 3)
+ (match-end 3))
+ line (substring line (match-beginning 4)
+ (match-end 4))
+ )
+ ;; If the current file is not the same as the previous
+ ;; one ...
+ (if (not (and cscope-last-file
+ (string= file cscope-last-file)))
+ (progn
+ ;; The current file is different.
+
+ ;; Insert a separating blank line if
+ ;; necessary.
+ (if cscope-last-file (insert "\n"))
+ ;; Insert the file name
+ (setq str (concat "*** " file ":"))
+ (if cscope-use-face
+ (put-text-property 0 (length str)
+ 'face 'cscope-file-face
+ str))
+ (cscope-insert-with-text-properties
+ str
+ (expand-file-name file)
+ ;; Yes, -1 is intentional
+ -1)
+ (insert "\n")
+ ))
+ (if (not cscope-first-match)
+ (setq cscope-first-match-point (point)))
+ ;; ... and insert the line, with the
+ ;; appropriate indentation.
+ (cscope-insert-with-text-properties
+ (cscope-make-entry-line function-name
+ line-number
+ line)
+ (expand-file-name file)
+ line-number)
+ (insert "\n")
+ (setq cscope-last-file file)
+ (if cscope-first-match
+ (setq cscope-matched-multiple t)
+ (setq cscope-first-match
+ (cons (expand-file-name file)
+ (string-to-number line-number))))
+ ))
+ (insert line "\n")
+ ))
+ (set-marker (process-mark process) (point))
+ )
+ (if moving
+ (goto-char (process-mark process)))
+ (set-buffer-modified-p nil)
+ ))
+ (set-buffer old-buffer))
+ ))
+
+
+(defun cscope-process-sentinel (process event)
+ "Sentinel for when the cscope process dies."
+ (let* ( (buffer (process-buffer process)) window update-window
+ (done t) (old-buffer (current-buffer))
+ (old-buffer-window (get-buffer-window old-buffer)) )
+ (set-buffer buffer)
+ (save-window-excursion
+ (save-excursion
+ (if (or (and (setq window (get-buffer-window buffer))
+ (= (window-point window) (point-max)))
+ (= (point) (point-max)))
+ (progn
+ (setq update-window t)
+ ))
+ (delete-process process)
+ (let (buffer-read-only continue)
+ (goto-char (point-max))
+ (if (and cscope-suppress-empty-matches
+ (= cscope-output-start (point)))
+ (delete-region cscope-item-start (point-max))
+ (progn
+ (if (not cscope-start-directory)
+ (setq cscope-start-directory default-directory))
+ (insert cscope-separator-line)
+ ))
+ (setq continue
+ (and cscope-search-list
+ (not (and cscope-first-match
+ cscope-stop-at-first-match-dir
+ (not cscope-stop-at-first-match-dir-meta)))))
+ (if continue
+ (setq continue (cscope-search-one-database)))
+ (if continue
+ (progn
+ (setq done nil)
+ )
+ (progn
+ (insert "\nSearch complete.")
+ (if cscope-display-times
+ (let ( (times (current-time)) cscope-stop elapsed-time )
+ (setq cscope-stop (+ (* (car times) 65536.0)
+ (car (cdr times))
+ (* (car (cdr (cdr times))) 1.0E-6)))
+ (setq elapsed-time (- cscope-stop cscope-start-time))
+ (insert (format " Search time = %.2f seconds."
+ elapsed-time))
+ ))
+ (setq cscope-process nil)
+ (if cscope-running-in-xemacs
+ (setq modeline-process ": Search complete"))
+ (if cscope-start-directory
+ (setq default-directory cscope-start-directory))
+ (if (not cscope-first-match)
+ (message "No matches were found."))
+ )
+ ))
+ (set-buffer-modified-p nil)
+ ))
+ (if (and done cscope-first-match-point update-window)
+ (if window
+ (set-window-point window cscope-first-match-point)
+ (goto-char cscope-first-match-point))
+ )
+ (cond
+ ( (not done) ;; we're not done -- do nothing for now
+ (if update-window
+ (if window
+ (set-window-point window (point-max))
+ (goto-char (point-max))))
+ )
+ ( cscope-first-match
+ (if cscope-display-cscope-buffer
+ (if (and cscope-edit-single-match (not cscope-matched-multiple))
+ (cscope-show-entry-internal(car cscope-first-match)
+ (cdr cscope-first-match) t))
+ (cscope-select-entry-specified-window old-buffer-window))
+ )
+ )
+ (if (and done (eq old-buffer buffer) cscope-first-match)
+ (cscope-help))
+ (set-buffer old-buffer)
+ ))
+
+
+(defun cscope-search-one-database ()
+ "Pop a database entry from cscope-search-list and do a search there."
+ (let ( next-item options cscope-directory database-file outbuf done
+ base-database-file-name)
+ (setq outbuf (get-buffer-create cscope-output-buffer-name))
+ (save-excursion
+ (catch 'finished
+ (set-buffer outbuf)
+ (setq options '("-L"))
+ (while (and (not done) cscope-search-list)
+ (setq next-item (car cscope-search-list)
+ cscope-search-list (cdr cscope-search-list)
+ base-database-file-name cscope-database-file
+ )
+ (if (listp next-item)
+ (progn
+ (setq cscope-directory (car next-item))
+ (if (not (stringp cscope-directory))
+ (setq cscope-directory
+ (cscope-search-directory-hierarchy
+ default-directory)))
+ (if (file-regular-p cscope-directory)
+ (progn
+ ;; Handle the case where `cscope-directory' is really
+ ;; a full path name to a cscope database.
+ (setq base-database-file-name
+ (file-name-nondirectory cscope-directory)
+ cscope-directory
+ (file-name-directory cscope-directory))
+ ))
+ (setq cscope-directory
+ (file-name-as-directory cscope-directory))
+ (if (not (member cscope-directory cscope-searched-dirs))
+ (progn
+ (setq cscope-searched-dirs (cons cscope-directory
+ cscope-searched-dirs)
+ done t)
+ ))
+ )
+ (progn
+ (if (and cscope-first-match
+ cscope-stop-at-first-match-dir
+ cscope-stop-at-first-match-dir-meta)
+ (throw 'finished nil))
+ ))
+ )
+ (if (not done)
+ (throw 'finished nil))
+ (if (car (cdr next-item))
+ (let (newopts)
+ (setq newopts (car (cdr next-item)))
+ (if (not (listp newopts))
+ (error (format "Cscope options must be a list: %s" newopts)))
+ (setq options (append options newopts))
+ ))
+ (if cscope-command-args
+ (setq options (append options cscope-command-args)))
+ (setq database-file (concat cscope-directory base-database-file-name)
+ cscope-searched-dirs (cons cscope-directory
+ cscope-searched-dirs)
+ )
+
+ ;; The database file and the directory containing the database file
+ ;; must both be writable.
+ (if (or (not (file-writable-p database-file))
+ (not (file-writable-p (file-name-directory database-file)))
+ cscope-do-not-update-database)
+ (setq options (cons "-d" options)))
+
+ (goto-char (point-max))
+ (setq cscope-item-start (point))
+ (if (string= base-database-file-name cscope-database-file)
+ (insert "\nDatabase directory: " cscope-directory "\n"
+ cscope-separator-line)
+ (insert "\nDatabase directory/file: "
+ cscope-directory base-database-file-name "\n"
+ cscope-separator-line))
+ ;; Add the correct database file to search
+ (setq options (cons base-database-file-name options))
+ (setq options (cons "-f" options))
+ (setq cscope-output-start (point))
+ (setq default-directory cscope-directory)
+ (if cscope-filter-func
+ (progn
+ (setq cscope-process-output nil
+ cscope-last-file nil
+ )
+ (setq cscope-process
+ (apply 'start-process "cscope" outbuf
+ cscope-program options))
+ (set-process-filter cscope-process cscope-filter-func)
+ (set-process-sentinel cscope-process cscope-sentinel-func)
+ (set-marker (process-mark cscope-process) (point))
+ (process-kill-without-query cscope-process)
+ (if cscope-running-in-xemacs
+ (setq modeline-process ": Searching ..."))
+ (setq buffer-read-only t)
+ )
+ (apply 'call-process cscope-program nil outbuf t options)
+ )
+ t
+ ))
+ ))
+
+
+(defun cscope-call (msg args &optional directory filter-func sentinel-func)
+ "Generic function to call to process cscope requests.
+ARGS is a list of command-line arguments to pass to the cscope
+process. DIRECTORY is the current working directory to use (generally,
+the directory in which the cscope database is located, but not
+necessarily), if different that the current one. FILTER-FUNC and
+SENTINEL-FUNC are optional process filter and sentinel, respectively."
+ (let ( (outbuf (get-buffer-create cscope-output-buffer-name))
+ (old-buffer (current-buffer)) )
+ (if cscope-process
+ (error "A cscope search is still in progress -- only one at a time is allowed"))
+ (setq directory (cscope-canonicalize-directory
+ (or cscope-initial-directory directory)))
+ (if (eq outbuf old-buffer) ;; In the *cscope* buffer.
+ (if cscope-marker-window
+ (progn
+ ;; Assume that cscope-marker-window is the window, from the
+ ;; users perspective, from which the search was launched and the
+ ;; window that should be returned to upon cscope-pop-mark.
+ (set-buffer (window-buffer cscope-marker-window))
+ (setq cscope-marker (point-marker))
+ (set-buffer old-buffer)))
+ (progn ;; Not in the *cscope buffer.
+ ;; Set the cscope-marker-window to whichever window this search
+ ;; was launched from.
+ (setq cscope-marker-window (get-buffer-window old-buffer))
+ (setq cscope-marker (point-marker))))
+ (save-excursion
+ (set-buffer outbuf)
+ (if cscope-display-times
+ (let ( (times (current-time)) )
+ (setq cscope-start-time (+ (* (car times) 65536.0) (car (cdr times))
+ (* (car (cdr (cdr times))) 1.0E-6)))))
+ (setq default-directory directory
+ cscope-start-directory nil
+ cscope-search-list (cscope-find-info directory)
+ cscope-searched-dirs nil
+ cscope-command-args args
+ cscope-filter-func filter-func
+ cscope-sentinel-func sentinel-func
+ cscope-first-match nil
+ cscope-first-match-point nil
+ cscope-stop-at-first-match-dir-meta (memq t cscope-search-list)
+ cscope-matched-multiple nil
+ buffer-read-only nil)
+ (buffer-disable-undo)
+ (erase-buffer)
+ (setq truncate-lines cscope-truncate-lines)
+ (if msg
+ (insert msg "\n"))
+ (cscope-search-one-database)
+ )
+ (if cscope-display-cscope-buffer
+ (progn
+ (pop-to-buffer outbuf)
+ (cscope-help))
+ (set-buffer outbuf))
+ (goto-char (point-max))
+ (cscope-list-entry-mode)
+ ))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar cscope-unix-index-process-buffer-name "*cscope-indexing-buffer*"
+ "The name of the buffer to use for displaying indexing status/progress.")
+
+
+(defvar cscope-unix-index-process-buffer nil
+ "The buffer to use for displaying indexing status/progress.")
+
+
+(defvar cscope-unix-index-process nil
+ "The current indexing process.")
+
+
+(defun cscope-unix-index-files-sentinel (process event)
+ "Simple sentinel to print a message saying that indexing is finished."
+ (let (buffer)
+ (save-window-excursion
+ (save-excursion
+ (setq buffer (process-buffer process))
+ (set-buffer buffer)
+ (goto-char (point-max))
+ (insert cscope-separator-line "\nIndexing finished\n")
+ (delete-process process)
+ (setq cscope-unix-index-process nil)
+ (set-buffer-modified-p nil)
+ ))
+ ))
+
+
+(defun cscope-unix-index-files-internal (top-directory header-text args)
+ "Core function to call the indexing script."
+ (let ()
+ (save-excursion
+ (setq top-directory (cscope-canonicalize-directory top-directory))
+ (setq cscope-unix-index-process-buffer
+ (get-buffer-create cscope-unix-index-process-buffer-name))
+ (display-buffer cscope-unix-index-process-buffer)
+ (set-buffer cscope-unix-index-process-buffer)
+ (setq buffer-read-only nil)
+ (setq default-directory top-directory)
+ (buffer-disable-undo)
+ (erase-buffer)
+ (if header-text
+ (insert header-text))
+ (setq args (append args
+ (list "-v"
+ "-i" cscope-index-file
+ "-f" cscope-database-file
+ (if cscope-use-relative-paths
+ "." top-directory))))
+ (if cscope-index-recursively
+ (setq args (cons "-r" args)))
+ (setq cscope-unix-index-process
+ (apply 'start-process "cscope-indexer"
+ cscope-unix-index-process-buffer
+ cscope-indexing-script args))
+ (set-process-sentinel cscope-unix-index-process
+ 'cscope-unix-index-files-sentinel)
+ (process-kill-without-query cscope-unix-index-process)
+ )
+ ))
+
+
+(defun cscope-index-files (top-directory)
+ "Index files in a directory.
+This function creates a list of files to index, and then indexes
+the listed files.
+The variable, \"cscope-index-recursively\", controls whether or not
+subdirectories are indexed."
+ (interactive "DIndex files in directory: ")
+ (let ()
+ (cscope-unix-index-files-internal
+ top-directory
+ (format "Creating cscope index `%s' in:\n\t%s\n\n%s"
+ cscope-database-file top-directory cscope-separator-line)
+ nil)
+ ))
+
+
+(defun cscope-create-list-of-files-to-index (top-directory)
+ "Create a list of files to index.
+The variable, \"cscope-index-recursively\", controls whether or not
+subdirectories are indexed."
+ (interactive "DCreate file list in directory: ")
+ (let ()
+ (cscope-unix-index-files-internal
+ top-directory
+ (format "Creating cscope file list `%s' in:\n\t%s\n\n"
+ cscope-index-file top-directory)
+ '("-l"))
+ ))
+
+
+(defun cscope-edit-list-of-files-to-index ()
+ "Search for and edit the list of files to index.
+If this functions causes a new file to be edited, that means that a
+cscope.out file was found without a corresponding cscope.files file."
+ (interactive)
+ (let (info directory file)
+ (setq info (cscope-find-info nil))
+ (if (/= (length info) 1)
+ (error "There is no unique cscope database directory!"))
+ (setq directory (car (car info)))
+ (if (not (stringp directory))
+ (setq directory
+ (cscope-search-directory-hierarchy default-directory)))
+ (setq file (concat (file-name-as-directory directory) cscope-index-file))
+ (find-file file)
+ (message (concat "File: " file))
+ ))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun cscope-tell-user-about-directory ()
+ "Display the name of the directory containing the cscope database."
+ (interactive)
+ (let (info directory)
+ (setq info (cscope-find-info nil))
+ (if (= (length info) 1)
+ (progn
+ (setq directory (car (car info)))
+ (message (concat "Cscope directory: " directory))
+ )
+ (let ( (outbuf (get-buffer-create cscope-info-buffer-name)) )
+ (display-buffer outbuf)
+ (save-excursion
+ (set-buffer outbuf)
+ (buffer-disable-undo)
+ (erase-buffer)
+ (insert "Cscope search directories:\n")
+ (while info
+ (if (listp (car info))
+ (progn
+ (setq directory (car (car info)))
+ (if (not (stringp directory))
+ (setq directory
+ (cscope-search-directory-hierarchy
+ default-directory)))
+ (insert "\t" directory "\n")
+ ))
+ (setq info (cdr info))
+ )
+ )
+ ))
+ ))
+
+
+(defun cscope-dired-directory ()
+ "Run dired upon the cscope database directory.
+If possible, the cursor is moved to the name of the cscope database
+file."
+ (interactive)
+ (let (info directory buffer p1 p2 pos)
+ (setq info (cscope-find-info nil))
+ (if (/= (length info) 1)
+ (error "There is no unique cscope database directory!"))
+ (setq directory (car (car info)))
+ (if (not (stringp directory))
+ (setq directory
+ (cscope-search-directory-hierarchy default-directory)))
+ (setq buffer (dired-noselect directory nil))
+ (switch-to-buffer buffer)
+ (set-buffer buffer)
+ (save-excursion
+ (goto-char (point-min))
+ (setq p1 (search-forward cscope-index-file nil t))
+ (if p1
+ (setq p1 (- p1 (length cscope-index-file))))
+ )
+ (save-excursion
+ (goto-char (point-min))
+ (setq p2 (search-forward cscope-database-file nil t))
+ (if p2
+ (setq p2 (- p2 (length cscope-database-file))))
+ )
+ (cond
+ ( (and p1 p2)
+ (if (< p1 p2)
+ (setq pos p1)
+ (setq pos p2))
+ )
+ ( p1
+ (setq pos p1)
+ )
+ ( p2
+ (setq pos p2)
+ )
+ )
+ (if pos
+ (set-window-point (get-buffer-window buffer) pos))
+ ))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun cscope-extract-symbol-at-cursor (extract-filename)
+ (let* ( (symbol-chars (if extract-filename
+ cscope-filename-chars
+ cscope-symbol-chars))
+ (symbol-char-regexp (concat "[" symbol-chars "]"))
+ )
+ (save-excursion
+ (buffer-substring-no-properties
+ (progn
+ (if (not (looking-at symbol-char-regexp))
+ (re-search-backward "\\w" nil t))
+ (skip-chars-backward symbol-chars)
+ (point))
+ (progn
+ (skip-chars-forward symbol-chars)
+ (point)
+ )))
+ ))
+
+
+(defun cscope-prompt-for-symbol (prompt extract-filename)
+ "Prompt the user for a cscope symbol."
+ (let (sym)
+ (setq sym (cscope-extract-symbol-at-cursor extract-filename))
+ (if (or (not sym)
+ (string= sym "")
+ (not (and cscope-running-in-xemacs
+ cscope-no-mouse-prompts current-mouse-event
+ (or (mouse-event-p current-mouse-event)
+ (misc-user-event-p current-mouse-event))))
+ ;; Always prompt for symbol in dired mode.
+ (eq major-mode 'dired-mode)
+ )
+ (setq sym (read-from-minibuffer prompt sym))
+ sym)
+ ))
+
+
+(defun cscope-find-this-symbol (symbol)
+ "Locate a symbol in source code."
+ (interactive (list
+ (cscope-prompt-for-symbol "Find this symbol: " nil)
+ ))
+ (let ( (cscope-adjust t) ) ;; Use fuzzy matching.
+ (setq cscope-symbol symbol)
+ (cscope-call (format "Finding symbol: %s" symbol)
+ (list "-0" symbol) nil 'cscope-process-filter
+ 'cscope-process-sentinel)
+ ))
+
+
+(defun cscope-find-global-definition (symbol)
+ "Find a symbol's global definition."
+ (interactive (list
+ (cscope-prompt-for-symbol "Find this global definition: " nil)
+ ))
+ (let ( (cscope-adjust t) ) ;; Use fuzzy matching.
+ (setq cscope-symbol symbol)
+ (cscope-call (format "Finding global definition: %s" symbol)
+ (list "-1" symbol) nil 'cscope-process-filter
+ 'cscope-process-sentinel)
+ ))
+
+
+(defun cscope-find-global-definition-no-prompting ()
+ "Find a symbol's global definition without prompting."
+ (interactive)
+ (let ( (symbol (cscope-extract-symbol-at-cursor nil))
+ (cscope-adjust t) ) ;; Use fuzzy matching.
+ (setq cscope-symbol symbol)
+ (cscope-call (format "Finding global definition: %s" symbol)
+ (list "-1" symbol) nil 'cscope-process-filter
+ 'cscope-process-sentinel)
+ ))
+
+
+(defun cscope-find-called-functions (symbol)
+ "Display functions called by a function."
+ (interactive (list
+ (cscope-prompt-for-symbol
+ "Find functions called by this function: " nil)
+ ))
+ (let ( (cscope-adjust nil) ) ;; Disable fuzzy matching.
+ (setq cscope-symbol symbol)
+ (cscope-call (format "Finding functions called by: %s" symbol)
+ (list "-2" symbol) nil 'cscope-process-filter
+ 'cscope-process-sentinel)
+ ))
+
+
+(defun cscope-find-functions-calling-this-function (symbol)
+ "Display functions calling a function."
+ (interactive (list
+ (cscope-prompt-for-symbol
+ "Find functions calling this function: " nil)
+ ))
+ (let ( (cscope-adjust t) ) ;; Use fuzzy matching.
+ (setq cscope-symbol symbol)
+ (cscope-call (format "Finding functions calling: %s" symbol)
+ (list "-3" symbol) nil 'cscope-process-filter
+ 'cscope-process-sentinel)
+ ))
+
+
+(defun cscope-find-this-text-string (symbol)
+ "Locate where a text string occurs."
+ (interactive (list
+ (cscope-prompt-for-symbol "Find this text string: " nil)
+ ))
+ (let ( (cscope-adjust t) ) ;; Use fuzzy matching.
+ (setq cscope-symbol symbol)
+ (cscope-call (format "Finding text string: %s" symbol)
+ (list "-4" symbol) nil 'cscope-process-filter
+ 'cscope-process-sentinel)
+ ))
+
+
+(defun cscope-find-egrep-pattern (symbol)
+ "Run egrep over the cscope database."
+ (interactive (list
+ (let (cscope-no-mouse-prompts)
+ (cscope-prompt-for-symbol "Find this egrep pattern: " nil))
+ ))
+ (let ( (cscope-adjust t) ) ;; Use fuzzy matching.
+ (setq cscope-symbol symbol)
+ (cscope-call (format "Finding egrep pattern: %s" symbol)
+ (list "-6" symbol) nil 'cscope-process-filter
+ 'cscope-process-sentinel)
+ ))
+
+
+(defun cscope-find-this-file (symbol)
+ "Locate a file."
+ (interactive (list
+ (let (cscope-no-mouse-prompts)
+ (cscope-prompt-for-symbol "Find this file: " t))
+ ))
+ (let ( (cscope-adjust nil) ) ;; Disable fuzzy matching.
+ (setq cscope-symbol symbol)
+ (cscope-call (format "Finding file: %s" symbol)
+ (list "-7" symbol) nil 'cscope-process-filter
+ 'cscope-process-sentinel)
+ ))
+
+
+(defun cscope-find-files-including-file (symbol)
+ "Locate all files #including a file."
+ (interactive (list
+ (let (cscope-no-mouse-prompts)
+ (cscope-prompt-for-symbol
+ "Find files #including this file: " t))
+ ))
+ (let ( (cscope-adjust t) ) ;; Use fuzzy matching.
+ (setq cscope-symbol symbol)
+ (cscope-call (format "Finding files #including file: %s" symbol)
+ (list "-8" symbol) nil 'cscope-process-filter
+ 'cscope-process-sentinel)
+ ))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar cscope-minor-mode nil
+ "")
+(make-variable-buffer-local 'cscope-minor-mode)
+(put 'cscope-minor-mode 'permanent-local t)
+
+
+(defun cscope-minor-mode (&optional arg)
+ ""
+ (progn
+ (setq cscope-minor-mode (if (null arg) t (car arg)))
+ (if cscope-minor-mode
+ (progn
+ (easy-menu-add cscope:menu cscope:map)
+ (run-hooks 'cscope-minor-mode-hooks)
+ ))
+ cscope-minor-mode
+ ))
+
+
+(defun cscope:hook ()
+ ""
+ (progn
+ (cscope-minor-mode)
+ ))
+
+
+(or (assq 'cscope-minor-mode minor-mode-map-alist)
+ (setq minor-mode-map-alist (cons (cons 'cscope-minor-mode cscope:map)
+ minor-mode-map-alist)))
+
+(add-hook 'c-mode-hook (function cscope:hook))
+(add-hook 'c++-mode-hook (function cscope:hook))
+(add-hook 'dired-mode-hook (function cscope:hook))
+
+(provide 'xcscope)