Index: htags/htags.c
===================================================================
RCS file: /sources/global/global/htags/htags.c,v
retrieving revision 1.112
diff -u -p -r1.112 htags.c
--- htags/htags.c	22 Aug 2006 11:51:10 -0000	1.112
+++ htags/htags.c	25 Aug 2006 16:26:08 -0000
@@ -107,6 +107,7 @@ int caution;				/* --caution option		*/
 int dynamic;				/* --dynamic(-D) option		*/
 int symbol;				/* --symbol(-s) option          */
 int statistics;				/* --statistics option		*/
+int use_cvs_module;			/* --use-cvs-module		*/
 
 int copy_files;				/* 1: copy tag files		*/
 int no_map_file;			/* 1: doesn't make map file	*/
@@ -267,6 +268,7 @@ static struct option const long_options[
         {"insert-header", required_argument, NULL, 1},
         {"insert-footer", required_argument, NULL, 1},
         {"statistics", no_argument, &statistics, 1},
+        {"use-cvs-module", no_argument, &use_cvs_module, 1},
         {"version", no_argument, &show_version, 1},
         {"help", no_argument, &show_help, 1},
         { 0 }
Index: htags/htags.h
===================================================================
RCS file: /sources/global/global/htags/htags.h,v
retrieving revision 1.28
diff -u -p -r1.28 htags.h
--- htags/htags.h	4 Aug 2006 13:34:56 -0000	1.28
+++ htags/htags.h	25 Aug 2006 16:26:08 -0000
@@ -88,6 +88,7 @@ extern int caution;
 extern int dynamic;
 extern int symbol;
 extern int statistics;
+extern int use_cvs_module;
 
 extern int no_map_file;
 extern int no_order_list;
Index: htags/src2html.c
===================================================================
RCS file: /sources/global/global/htags/src2html.c,v
retrieving revision 1.51
diff -u -p -r1.51 src2html.c
--- htags/src2html.c	23 Aug 2006 11:41:36 -0000	1.51
+++ htags/src2html.c	25 Aug 2006 16:26:08 -0000
@@ -686,6 +686,49 @@ encode(STRBUF *sb, const char *url)
 	}
 }
 /*
+ * get_cvs_module: return CVS module of source file.
+ *
+ *	i)	file		source path
+ *	o)	basename	If basename is not NULL, store pointer to
+ *				the last component of source path.
+ *	r)		!=NULL : relative path from repository top
+ *			==NULL : CVS/Repository is not readable.
+ */
+static const char *
+get_cvs_module(const char *file, const char **basename)
+{
+	const char *p;
+	STATIC_STRBUF(dir);
+	static char prev_dir[MAXPATHLEN+1];
+	STATIC_STRBUF(module);
+	FILE *ip;
+
+	strbuf_clear(dir);
+	p = locatestring(file, "/", MATCH_LAST);
+	if (p != NULL) {
+		strbuf_nputs(dir, file, p - file);
+		p++;
+	} else {
+		strbuf_putc(dir, '.');
+		p = file;
+	}
+	if (basename != NULL)
+		*basename = p;
+	if (strcmp(strbuf_value(dir), prev_dir) != 0) {
+		strlimcpy(prev_dir, strbuf_value(dir), sizeof(prev_dir));
+		strbuf_clear(module);
+		strbuf_puts(dir, "/CVS/Repository");
+		ip = fopen(strbuf_value(dir), "r");
+		if (ip != NULL) {
+			strbuf_fgets(module, ip, STRBUF_NOCRLF);
+			fclose(ip);
+		}
+	}
+	if (strbuf_getlen(module) > 0)
+		return strbuf_value(module);
+	return NULL;
+}
+/*
  *
  * src2html: convert source code into HTML
  *
@@ -722,10 +765,18 @@ src2html(const char *src, const char *ht
         fputs(fill_anchor(indexlink, src), out);
 	if (cvsweb_url) {
 		STATIC_STRBUF(sb);
+		const char *module, *basename;
 
 		strbuf_clear(sb);
 		strbuf_puts(sb, cvsweb_url);
-		encode(sb, src);
+		if (use_cvs_module
+		 && (module = get_cvs_module(src, &basename)) != NULL) {
+			encode(sb, module);
+			strbuf_putc(sb, '/');
+			encode(sb, basename);
+		} else {
+			encode(sb, src);
+		}
 		if (cvsweb_cvsroot) {
 			strbuf_puts(sb, "?cvsroot=");
 			strbuf_puts(sb, cvsweb_cvsroot);
