source@mandoc.bsd.lv
 help / color / mirror / Atom feed
From: schwarze@mandoc.bsd.lv
To: source@mandoc.bsd.lv
Subject: mandoc: In man(1) mode, do the search for each name independently, and
Date: Sun, 28 Jul 2019 13:23:47 -0500 (EST)	[thread overview]
Message-ID: <862a41bf6316999b@mandoc.bsd.lv> (raw)

Log Message:
-----------
In man(1) mode, do the search for each name independently, and
show the results in the order of the command line arguments.
Implemented by separating the code for man(1) and apropos(1)
in the main() program.
Surprisingly, the number of lines of code remains unchanged.
Issue reported by deraadt@, additional input from millert@.

Modified Files:
--------------
    mandoc:
        main.c

Revision Data
-------------
Index: main.c
===================================================================
RCS file: /home/cvs/mandoc/mandoc/main.c,v
retrieving revision 1.337
retrieving revision 1.338
diff -Lmain.c -Lmain.c -u -p -r1.337 -r1.338
--- main.c
+++ main.c
@@ -120,7 +120,8 @@ main(int argc, char *argv[])
 	struct outstate	 outst;		/* Output state. */
 	struct winsize	 ws;		/* Result of ioctl(TIOCGWINSZ). */
 	struct mansearch search;	/* Search options. */
-	struct manpage	*res, *resp;	/* Search results. */
+	struct manpage	*res;		/* Complete list of search results. */
+	struct manpage	*resn;		/* Search results for one name. */
 	struct mparse	*mp;		/* Opaque parser object. */
 	const char	*conf_file;	/* -C: alternate config file. */
 	const char	*os_s;		/* -I: Operating system for display. */
@@ -130,8 +131,9 @@ main(int argc, char *argv[])
 	char		*oarg;		/* -O: output option string. */
 	char		*tagarg;	/* -O tag: default value. */
 	unsigned char	*uc;
-	size_t		 sz;		/* Number of elements in res[]. */
-	size_t		 i, ssz;
+	size_t		 ressz;		/* Number of elements in res[]. */
+	size_t		 resnsz;	/* Number of elements in resn[]. */
+	size_t		 i, ib, ssz;
 	int		 options;	/* Parser options. */
 	int		 show_usage;	/* Invalid argument: give up. */
 	int		 prio, best_prio;
@@ -384,11 +386,10 @@ main(int argc, char *argv[])
 		argc -= optind;
 		argv += optind;
 	}
-	resp = NULL;
 
 	/*
-	 * Quirks for help(1)
-	 * and for a man(1) section argument without -s.
+	 * Quirks for help(1) and man(1),
+	 * in particular for a section argument without -s.
 	 */
 
 	if (search.argmode == ARG_NAME) {
@@ -412,6 +413,8 @@ main(int argc, char *argv[])
 		if (search.arch == NULL)
 			search.arch = MACHINE;
 #endif
+		if (outmode == OUTMODE_ONE)
+			search.firstmatch = 1;
 	}
 
 	/*
@@ -425,80 +428,54 @@ main(int argc, char *argv[])
 		conf.output.tag = tagarg == NULL ? *argv : tagarg + 1;
 	}
 
-	/* man(1), whatis(1), apropos(1) */
-
-	if (search.argmode != ARG_FILE) {
-		if (search.argmode == ARG_NAME &&
-		    outmode == OUTMODE_ONE)
-			search.firstmatch = 1;
-
-		/* Access the mandoc database. */
+	/* Read the configuration file. */
 
+	if (search.argmode != ARG_FILE)
 		manconf_parse(&conf, conf_file, defpaths, auxpaths);
-		if ( ! mansearch(&search, &conf.manpath,
-		    argc, argv, &res, &sz))
-			usage(search.argmode);
 
-		if (sz == 0 && search.argmode == ARG_NAME)
-			(void)fs_search(&search, &conf.manpath,
-			    argc, argv, &res, &sz);
-
-		if (search.argmode == ARG_NAME) {
-			for (c = 0; c < argc; c++) {
-				if (strchr(argv[c], '/') == NULL)
+	/* man(1): Resolve each name individually. */
+
+	if (search.argmode == ARG_NAME) {
+		if (argc < 1)
+			usage(ARG_NAME);
+		for (res = NULL, ressz = 0; argc > 0; argc--, argv++) {
+			(void)mansearch(&search, &conf.manpath,
+			    1, argv, &resn, &resnsz);
+			if (resnsz == 0)
+				(void)fs_search(&search, &conf.manpath,
+				    1, argv, &resn, &resnsz);
+			if (resnsz == 0) {
+				if (strchr(*argv, '/') == NULL) {
+					mandoc_msg_setrc(MANDOCLEVEL_BADARG);
 					continue;
-				if (access(argv[c], R_OK) == -1) {
-					mandoc_msg_setinfilename(argv[c]);
+				}
+				if (access(*argv, R_OK) == -1) {
+					mandoc_msg_setinfilename(*argv);
 					mandoc_msg(MANDOCERR_BADARG_BAD,
 					    0, 0, "%s", strerror(errno));
 					mandoc_msg_setinfilename(NULL);
 					continue;
 				}
+				resnsz = 1;
+				resn = mandoc_calloc(resnsz, sizeof(*res));
+				resn->file = mandoc_strdup(*argv);
+				resn->ipath = SIZE_MAX;
+				resn->form = FORM_SRC;
+			}
+			if (outmode != OUTMODE_ONE || resnsz == 1) {
 				res = mandoc_reallocarray(res,
-				    sz + 1, sizeof(*res));
-				res[sz].file = mandoc_strdup(argv[c]);
-				res[sz].names = NULL;
-				res[sz].output = NULL;
-				res[sz].bits = 0;
-				res[sz].ipath = SIZE_MAX;
-				res[sz].sec = 10;
-				res[sz].form = FORM_SRC;
-				sz++;
+				    ressz + resnsz, sizeof(*res));
+				memcpy(res + ressz, resn,
+				    sizeof(*resn) * resnsz);
+				ressz += resnsz;
+				continue;
 			}
-		}
 
-		if (sz == 0) {
-			if (search.argmode != ARG_NAME)
-				warnx("nothing appropriate");
-			mandoc_msg_setrc(MANDOCLEVEL_BADARG);
-			goto out;
-		}
-
-		/*
-		 * For standard man(1) and -a output mode,
-		 * prepare for copying filename pointers
-		 * into the program parameter array.
-		 */
+			/* Search for the best section. */
 
-		if (outmode == OUTMODE_ONE) {
-			argc = 1;
 			best_prio = 40;
-		} else if (outmode == OUTMODE_ALL)
-			argc = (int)sz;
-
-		/* Iterate all matching manuals. */
-
-		resp = res;
-		for (i = 0; i < sz; i++) {
-			if (outmode == OUTMODE_FLN)
-				puts(res[i].file);
-			else if (outmode == OUTMODE_LST)
-				printf("%s - %s\n", res[i].names,
-				    res[i].output == NULL ? "" :
-				    res[i].output);
-			else if (outmode == OUTMODE_ONE) {
-				/* Search for the best section. */
-				sec = res[i].file;
+			for (ib = i = 0; i < resnsz; i++) {
+				sec = resn[i].file;
 				sec += strcspn(sec, "123456789");
 				if (sec[0] == '\0')
 					continue; /* No section at all. */
@@ -519,32 +496,53 @@ main(int argc, char *argv[])
 				if (prio >= best_prio)
 					continue;
 				best_prio = prio;
-				resp = res + i;
+				ib = i;
 			}
+			res = mandoc_reallocarray(res, ressz + 1,
+			    sizeof(*res));
+			memcpy(res + ressz++, resn + ib, sizeof(*resn));
 		}
 
-		/*
-		 * For man(1), -a and -i output mode, fall through
-		 * to the main mandoc(1) code iterating files
-		 * and running the parsers on each of them.
-		 */
+	/* apropos(1), whatis(1): Process the full search expression. */
+
+	} else if (search.argmode != ARG_FILE) {
+		if (mansearch(&search, &conf.manpath,
+		    argc, argv, &res, &ressz) == 0)
+			usage(search.argmode);
 
-		if (outmode == OUTMODE_FLN || outmode == OUTMODE_LST)
+		if (ressz == 0) {
+			warnx("nothing appropriate");
+			mandoc_msg_setrc(MANDOCLEVEL_BADARG);
 			goto out;
+		}
+
+	/* mandoc(1): Take command line arguments as file names. */
+
 	} else {
-		sz = argc > 0 ? argc : 1;
-		resp = res = mandoc_recallocarray(NULL, 0, sz, sizeof(*res));
-		for (i = 0; i < sz; i++) {
+		ressz = argc > 0 ? argc : 1;
+		res = mandoc_calloc(ressz, sizeof(*res));
+		for (i = 0; i < ressz; i++) {
 			if (argc > 0)
 				res[i].file = mandoc_strdup(argv[i]);
 			res[i].ipath = SIZE_MAX;
 			res[i].form = FORM_SRC;
 		}
-		if (argc < 1)
-			argc = 1;
 	}
 
-	/* mandoc(1) */
+	switch (outmode) {
+	case OUTMODE_FLN:
+		for (i = 0; i < ressz; i++)
+			puts(res[i].file);
+		goto out;
+	case OUTMODE_LST:
+		for (i = 0; i < ressz; i++)
+			printf("%s - %s\n", res[i].names,
+			    res[i].output == NULL ? "" :
+			    res[i].output);
+		goto out;
+	default:
+		break;
+	}
 
 #if HAVE_PLEDGE
 	if (outst.use_pager) {
@@ -581,8 +579,8 @@ main(int argc, char *argv[])
 	 */
 	startdir = open(".", O_RDONLY | O_DIRECTORY);
 
-	while (argc-- > 0) {
-		process_onefile(mp, resp++, startdir, &outst, &conf);
+	for (i = 0; i < ressz; i++) {
+		process_onefile(mp, res + i, startdir, &outst, &conf);
 		if (outst.wstop && mandoc_msg_getrc() != MANDOCLEVEL_OK)
 			break;
 	}
@@ -614,7 +612,7 @@ main(int argc, char *argv[])
 	mchars_free();
 
 out:
-	mansearch_free(res, sz);
+	mansearch_free(res, ressz);
 	if (search.argmode != ARG_FILE)
 		manconf_free(&conf);
 
--
 To unsubscribe send an email to source+unsubscribe@mandoc.bsd.lv

                 reply	other threads:[~2019-07-28 18:23 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=862a41bf6316999b@mandoc.bsd.lv \
    --to=schwarze@mandoc.bsd.lv \
    --cc=source@mandoc.bsd.lv \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).