source@mandoc.bsd.lv
 help / color / mirror / Atom feed
* mdocml: Without bloating mandoc(1) itself, let mandocdb(8) support files
@ 2014-03-26 21:39 schwarze
  0 siblings, 0 replies; only message in thread
From: schwarze @ 2014-03-26 21:39 UTC (permalink / raw)
  To: source

Log Message:
-----------
Without bloating mandoc(1) itself, let mandocdb(8) support files
called manN/X.N.gz and catN/X.0.gz, reading them through a pipe(2)
from gunzip(1) -c.  Asked for by various people in the past.

Modified Files:
--------------
    mdocml:
        mandocdb.c

Revision Data
-------------
Index: mandocdb.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mandocdb.c,v
retrieving revision 1.123
retrieving revision 1.124
diff -Lmandocdb.c -Lmandocdb.c -u -p -r1.123 -r1.124
--- mandocdb.c
+++ mandocdb.c
@@ -119,6 +119,7 @@ struct	mlink {
 	char		*fsec;    /* section from file name suffix */
 	struct mlink	*next;    /* singly linked list */
 	struct mpage	*mpage;   /* parent */
+	int		 gzip;	  /* filename has a .gz suffix */
 };
 
 enum	stmt {
@@ -151,7 +152,7 @@ static	void	 mlink_free(struct mlink *);
 static	void	 mlinks_undupe(struct mpage *);
 static	void	 mpages_free(void);
 static	void	 mpages_merge(struct mchars *, struct mparse *);
-static	void	 parse_cat(struct mpage *);
+static	void	 parse_cat(struct mpage *, int);
 static	void	 parse_man(struct mpage *, const struct man_node *);
 static	void	 parse_mdoc(struct mpage *, const struct mdoc_node *);
 static	int	 parse_mdoc_body(struct mpage *, const struct mdoc_node *);
@@ -536,7 +537,7 @@ treescan(void)
 	FTS		*f;
 	FTSENT		*ff;
 	struct mlink	*mlink;
-	int		 dform;
+	int		 dform, gzip;
 	char		*dsec, *arch, *fsec, *cp;
 	const char	*path;
 	const char	*argv[2];
@@ -571,8 +572,18 @@ treescan(void)
 				if (warnings)
 					say(path, "Extraneous file");
 				continue;
-			} else if (NULL == (fsec =
-					strrchr(ff->fts_name, '.'))) {
+			}
+			gzip = 0;
+			fsec = NULL;
+			while (NULL == fsec) {
+				fsec = strrchr(ff->fts_name, '.');
+				if (NULL == fsec || strcmp(fsec+1, "gz"))
+					break;
+				gzip = 1;
+				*fsec = '\0';
+				fsec = NULL;
+			}
+			if (NULL == fsec) {
 				if ( ! use_all) {
 					if (warnings)
 						say(path,
@@ -583,10 +594,6 @@ treescan(void)
 				if (warnings)
 					say(path, "Skip html");
 				continue;
-			} else if (0 == strcmp(fsec, "gz")) {
-				if (warnings)
-					say(path, "Skip gz");
-				continue;
 			} else if (0 == strcmp(fsec, "ps")) {
 				if (warnings)
 					say(path, "Skip ps");
@@ -611,6 +618,7 @@ treescan(void)
 			mlink->arch = arch;
 			mlink->name = ff->fts_name;
 			mlink->fsec = fsec;
+			mlink->gzip = gzip;
 			mlink_add(mlink, ff->fts_statp);
 			continue;
 		} else if (FTS_D != ff->fts_info &&
@@ -964,13 +972,15 @@ mpages_merge(struct mchars *mc, struct m
 {
 	char			 any[] = "any";
 	struct ohash_info	 str_info;
+	int			 fd[2];
 	struct mpage		*mpage, *mpage_dest;
 	struct mlink		*mlink, *mlink_dest;
 	struct mdoc		*mdoc;
 	struct man		*man;
 	char			*sodest;
 	char			*cp;
-	int			 match;
+	pid_t			 child_pid;
+	int			 match, status;
 	unsigned int		 pslot;
 	enum mandoclevel	 lvl;
 
@@ -994,6 +1004,41 @@ mpages_merge(struct mchars *mc, struct m
 		mparse_reset(mp);
 		mdoc = NULL;
 		man = NULL;
+		sodest = NULL;
+		child_pid = 0;
+		fd[0] = -1;
+		fd[1] = -1;
+
+		if (mpage->mlinks->gzip) {
+			if (-1 == pipe(fd)) {
+				exitcode = (int)MANDOCLEVEL_SYSERR;
+				say(mpage->mlinks->file, "&pipe gunzip");
+				goto nextpage;
+			}
+			switch (child_pid = fork()) {
+			case (-1):
+				exitcode = (int)MANDOCLEVEL_SYSERR;
+				say(mpage->mlinks->file, "&fork gunzip");
+				child_pid = 0;
+				close(fd[1]);
+				close(fd[0]);
+				goto nextpage;
+			case (0):
+				close(fd[0]);
+				if (-1 == dup2(fd[1], STDOUT_FILENO)) {
+					say(mpage->mlinks->file,
+					    "&dup gunzip");
+					exit(1);
+				}
+				execlp("gunzip", "gunzip", "-c",
+				    mpage->mlinks->file, NULL);
+				say(mpage->mlinks->file, "&exec gunzip");
+				exit(1);
+			default:
+				close(fd[1]);
+				break;
+			}
+		}
 
 		/*
 		 * Try interpreting the file as mdoc(7) or man(7)
@@ -1002,7 +1047,7 @@ mpages_merge(struct mchars *mc, struct m
 		 */
 		if (FORM_CAT != mpage->mlinks->dform ||
 		    FORM_CAT != mpage->mlinks->fform) {
-			lvl = mparse_readfd(mp, -1, mpage->mlinks->file);
+			lvl = mparse_readfd(mp, fd[0], mpage->mlinks->file);
 			if (lvl < MANDOCLEVEL_FATAL)
 				mparse_result(mp, &mdoc, &man, &sodest);
 		}
@@ -1042,9 +1087,7 @@ mpages_merge(struct mchars *mc, struct m
 				mlink_dest->next = mpage->mlinks;
 				mpage->mlinks = NULL;
 			}
-			ohash_delete(&strings);
-			mpage = ohash_next(&mpages, &pslot);
-			continue;
+			goto nextpage;
 		} else if (NULL != mdoc) {
 			mpage->form = FORM_SRC;
 			mpage->sec =
@@ -1104,9 +1147,27 @@ mpages_merge(struct mchars *mc, struct m
 		} else if (NULL != man)
 			parse_man(mpage, man_node(man));
 		else
-			parse_cat(mpage);
+			parse_cat(mpage, fd[0]);
 
 		dbadd(mpage, mc);
+
+nextpage:
+		if (child_pid) {
+			if (-1 == waitpid(child_pid, &status, 0)) {
+				exitcode = (int)MANDOCLEVEL_SYSERR;
+				say(mpage->mlinks->file, "&wait gunzip");
+			} else if (WIFSIGNALED(status)) {
+				exitcode = (int)MANDOCLEVEL_SYSERR;
+				say(mpage->mlinks->file,
+				    "gunzip died from signal %d",
+				    WTERMSIG(status));
+			} else if (WEXITSTATUS(status)) {
+				exitcode = (int)MANDOCLEVEL_SYSERR;
+				say(mpage->mlinks->file,
+				    "gunzip failed with code %d",
+				    WEXITSTATUS(status));
+			}
+		}
 		ohash_delete(&strings);
 		mpage = ohash_next(&mpages, &pslot);
 	}
@@ -1116,13 +1177,16 @@ mpages_merge(struct mchars *mc, struct m
 }
 
 static void
-parse_cat(struct mpage *mpage)
+parse_cat(struct mpage *mpage, int fd)
 {
 	FILE		*stream;
 	char		*line, *p, *title;
 	size_t		 len, plen, titlesz;
 
-	if (NULL == (stream = fopen(mpage->mlinks->file, "r"))) {
+	stream = (-1 == fd) ?
+	    fopen(mpage->mlinks->file, "r") :
+	    fdopen(fd, "r");
+	if (NULL == stream) {
 		if (warnings)
 			say(mpage->mlinks->file, "&fopen");
 		return;
--
 To unsubscribe send an email to source+unsubscribe@mdocml.bsd.lv

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2014-03-26 21:39 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-26 21:39 mdocml: Without bloating mandoc(1) itself, let mandocdb(8) support files schwarze

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).