Subject: Adding arch prefix to whatis
To: None <tech-userlevel@netbsd.org>
From: Jaromir Dolecek <jaromir.dolecek@artisys.cz>
List: tech-userlevel
Date: 03/07/2002 12:41:41
--ELM720180282-3875-0_
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset=US-ASCII

Hi,
quite some time now, I've recognized the whatis output is not
as helpful as it could be for arch-specific manpages. Specifically,
it's output did not indicate the specific architecture the
manpage belongs to, unless the manpage NAME section mentioned
the architecture name. This made it a bit inconvenient
to actually look on the arch-specific manpage with 'man'.

I've changed makewhatis to generate entries with the (arch)
manpage subdirectory included. The output looks like this
(excerpt from man -k boot with regenerated whatis.db):

arm26/BBBB (8) - Bootloader for NetBSD/arm26
pc532/bim (8) - pc532 boot image manager
sparc/binstall (8) - install sparc and sparc64 boot blocks
alpha/boot (8) - Alpha system bootstrapping procedures
amiga/boot (8) - system bootstrapping procedures
arm26/boot26 (8) - Bootloader for NetBSD/arm26
i386/boot_console (8) - selection of a console device in the i386 bootloader
bootparamd, rpc.bootparamd (8) - boot parameter server
bootparams (5) - boot parameter database

This is implemented in such a way that this is not dependant
on any specific architecture name list, nor specific file hierarchy.
The only assumption is that one more directory level from the full path
to the manpage should be ignored (besides the manpage root). This
is normally the case (those cat[0-9]/, man[0-9]/ subdirectories).

I find this useful. Would anyone have any problem with this
makewhatis change being committed?

Jaromir
-- 
Jaromir Dolecek <jaromir.dolecek@artisys.cz>
ARTISYS, s.r.o., Stursova 71, 61600 Brno, Czech Republic
phone: +420-5-41224836 / fax: +420-5-41224870 / http://www.artisys.cz

--ELM720180282-3875-0_
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset=ISO-8859-2
Content-Disposition: attachment; filename=makewhatis.diff

Index: makewhatis.c
===================================================================
RCS file: /cvsroot/basesrc/libexec/makewhatis/makewhatis.c,v
retrieving revision 1.21
diff -u -p -b -r1.21 makewhatis.c
--- makewhatis.c	2002/01/31 22:43:41	1.21
+++ makewhatis.c	2002/03/07 11:29:46
@@ -73,6 +73,8 @@ typedef struct manpagestruct manpage;
 struct manpagestruct {
 	manpage *mp_left,*mp_right;
 	ino_t	 mp_inode;
+	size_t	 mp_sdoff;
+	size_t	 mp_sdlen;
 	char	 mp_name[1];
 };
 
@@ -80,16 +82,17 @@ typedef struct whatisstruct whatis;
 struct whatisstruct {
 	whatis	*wi_left,*wi_right;
 	char	*wi_data;
+	char	wi_prefix[1];
 };
 
-int	 main(int, char **);
+int	 main(int, char * const *);
 char	*findwhitespace(char *);
 char	*strmove(char *,char *);
 char	*GetS(gzFile, char *, size_t);
 int	 manpagesection(char *);
 char	*createsectionstring(char *);
-void	 addmanpage(manpage **, ino_t, char *);
-void	 addwhatis(whatis **, char *);
+void	 addmanpage(manpage **, ino_t, char *, size_t, size_t);
+void	 addwhatis(whatis **, char *, char *);
 char	*replacestring(char *, char *, char *);
 void	 catpreprocess(char *);
 char	*parsecatpage(gzFile *);
@@ -102,23 +105,24 @@ void	 dumpwhatis(FILE *, whatis *);
 void	*emalloc(size_t);
 char	*estrdup(const char *);
 
-char *default_manpath[] = {
+char * const default_manpath[] = {
 	"/usr/share/man",
 	NULL
 };
 
-char sectionext[] = "0123456789ln";
-char whatisdb[]	  = "whatis.db";
+const char *sectionext	= "0123456789ln";
+const char *whatisdb	= "whatis.db";
 
 int
-main(int argc, char **argv)
+main(int argc, char *const *argv)
 {
-	char	**manpath;
+	char	* const *manpath;
 	FTS	*fts;
 	FTSENT	*fe;
 	manpage *source;
 	whatis	*dest;
 	FILE	*out;
+	size_t	sdoff, sdlen;
 
 	(void)setlocale(LC_ALL, "");
 
@@ -131,9 +135,35 @@ main(int argc, char **argv)
 	while ((fe = fts_read(fts)) != NULL) {
 		switch (fe->fts_info) {
 		case FTS_F:
-			if (manpagesection(fe->fts_path) >= 0)
+			if (manpagesection(fe->fts_path) >= 0) {
+				/*
+				 * Get manpage subdirectory prefix. Most
+				 * commonly, this is arch-specific subdirectory.
+				 */
+				if (fe->fts_level >= 3) {
+					int sl = fe->fts_level - 1;
+					const char *s, *lsl=NULL;
+
+					s = &fe->fts_path[fe->fts_pathlen-1];
+					for(; sl > 0; sl--) {
+						s--;
+						while(s[0] != '/') s--;
+						if (!lsl)
+							lsl = s;
+					}
+					
+					/* Include trailing '/', so we get
+					 * 'arch/'. */
+					sdoff = s + 1 - fe->fts_path;
+					sdlen = lsl - s + 1;
+				} else {
+					sdoff = 0;
+					sdlen = 0;
+				}
+
 				addmanpage(&source, fe->fts_statp->st_ino,
-				    fe->fts_path);
+				    fe->fts_path, sdoff, sdlen);
+			}
 			/*FALLTHROUGH*/
 		case FTS_D:
 		case FTS_DC:
@@ -233,7 +263,7 @@ createsectionstring(char *section_id)
 }
 
 void
-addmanpage(manpage **tree,ino_t inode,char *name)
+addmanpage(manpage **tree,ino_t inode,char *name, size_t sdoff, size_t sdlen)
 {
 	manpage *mp;
 
@@ -247,12 +277,14 @@ addmanpage(manpage **tree,ino_t inode,ch
 	mp->mp_left = NULL;
 	mp->mp_right = NULL;
 	mp->mp_inode = inode;
+	mp->mp_sdoff = sdoff;
+	mp->mp_sdlen = sdlen;
 	(void)strcpy(mp->mp_name, name);
 	*tree = mp;
 }
 
 void
-addwhatis(whatis **tree, char *data)
+addwhatis(whatis **tree, char *data, char *prefix)
 {
 	whatis *wi;
 	int result;
@@ -275,11 +307,15 @@ addwhatis(whatis **tree, char *data)
 		tree = result < 0 ? &wi->wi_left : &wi->wi_right;
 	}
 
-	wi = emalloc(sizeof(whatis) + strlen(data));
+	wi = emalloc(sizeof(whatis) + strlen(prefix));
 
 	wi->wi_left = NULL;
 	wi->wi_right = NULL;
 	wi->wi_data = data;
+	if (prefix[0] != '\0')
+		(void) strcpy(wi->wi_prefix, prefix);
+	else
+		wi->wi_prefix[0] = '\0';
 	*tree = wi;
 }
 
@@ -817,6 +853,7 @@ void
 processmanpages(manpage **source, whatis **dest)
 {
 	manpage *mp;
+	char sd[128];
 
 	mp = *source;
 	*source = NULL;
@@ -827,9 +864,17 @@ processmanpages(manpage **source, whatis
 
 		if (mp->mp_left != NULL)
 			processmanpages(&mp->mp_left,dest);
+
+		if ((data = getwhatisdata(mp->mp_name)) != NULL) {
+			/* Pass eventual directory prefix to addwhatis() */
+			if (mp->mp_sdlen > 0 && mp->mp_sdlen < sizeof(sd)-1)
+				strlcpy(sd, &mp->mp_name[mp->mp_sdoff],
+					mp->mp_sdlen);
+			else
+				sd[0] = '\0';
 
-		if ((data = getwhatisdata(mp->mp_name)) != NULL)
-			addwhatis(dest,data);
+			addwhatis(dest, data, sd);
+		}
 
 		obsolete = mp;
 		mp = mp->mp_right;
@@ -844,7 +889,8 @@ dumpwhatis(FILE *out, whatis *tree)
 		if (tree->wi_left)
 			dumpwhatis(out, tree->wi_left);
 
-		if ((fputs(tree->wi_data, out) == EOF) ||
+		if ((tree->wi_data[0] && fputs(tree->wi_prefix, out) == EOF) ||
+		    (fputs(tree->wi_data, out) == EOF) ||
 		    (fputc('\n', out) == EOF))
 			err(EXIT_FAILURE, "Write failed");
 

--ELM720180282-3875-0_--