Ejemplo n.º 1
0
static void
print_mdoc_head(struct termp *p, const struct roff_meta *meta)
{
	char			*volume, *title;
	size_t			 vollen, titlen;

	/*
	 * The header is strange.  It has three components, which are
	 * really two with the first duplicated.  It goes like this:
	 *
	 * IDENTIFIER              TITLE                   IDENTIFIER
	 *
	 * The IDENTIFIER is NAME(SECTION), which is the command-name
	 * (if given, or "unknown" if not) followed by the manual page
	 * section.  These are given in `Dt'.  The TITLE is a free-form
	 * string depending on the manual volume.  If not specified, it
	 * switches on the manual section.
	 */

	assert(meta->vol);
	if (NULL == meta->arch)
		volume = mandoc_strdup(meta->vol);
	else
		mandoc_asprintf(&volume, "%s (%s)",
		    meta->vol, meta->arch);
	vollen = term_strlen(p, volume);

	if (NULL == meta->msec)
		title = mandoc_strdup(meta->title);
	else
		mandoc_asprintf(&title, "%s(%s)",
		    meta->title, meta->msec);
	titlen = term_strlen(p, title);

	p->flags |= TERMP_NOBREAK | TERMP_NOSPACE;
	p->trailspace = 1;
	p->offset = 0;
	p->rmargin = 2 * (titlen+1) + vollen < p->maxrmargin ?
	    (p->maxrmargin - vollen + term_len(p, 1)) / 2 :
	    vollen < p->maxrmargin ?  p->maxrmargin - vollen : 0;

	term_word(p, title);
	term_flushln(p);

	p->flags |= TERMP_NOSPACE;
	p->offset = p->rmargin;
	p->rmargin = p->offset + vollen + titlen < p->maxrmargin ?
	    p->maxrmargin - titlen : p->maxrmargin;

	term_word(p, volume);
	term_flushln(p);

	p->flags &= ~TERMP_NOBREAK;
	p->trailspace = 0;
	if (p->rmargin + titlen <= p->maxrmargin) {
		p->flags |= TERMP_NOSPACE;
		p->offset = p->rmargin;
		p->rmargin = p->maxrmargin;
		term_word(p, title);
		term_flushln(p);
	}

	p->flags &= ~TERMP_NOSPACE;
	p->offset = 0;
	p->rmargin = p->maxrmargin;
	free(title);
	free(volume);
}
Ejemplo n.º 2
0
int
manconf_output(struct manoutput *conf, const char *cp, int fromfile)
{
	const char *const toks[] = {
	    "includes", "man", "paper", "style",
	    "indent", "width", "fragment", "mdoc", "noval"
	};

	const char	*errstr;
	char		*oldval;
	size_t		 len, tok;

	for (tok = 0; tok < sizeof(toks)/sizeof(toks[0]); tok++) {
		len = strlen(toks[tok]);
		if ( ! strncmp(cp, toks[tok], len) &&
		    strchr(" =	", cp[len]) != NULL) {
			cp += len;
			if (*cp == '=')
				cp++;
			while (isspace((unsigned char)*cp))
				cp++;
			break;
		}
	}

	if (tok < 6 && *cp == '\0') {
		warnx("-O %s=?: Missing argument value", toks[tok]);
		return -1;
	}
	if ((tok == 6 || tok == 7) && *cp != '\0') {
		warnx("-O %s: Does not take a value: %s", toks[tok], cp);
		return -1;
	}

	switch (tok) {
	case 0:
		if (conf->includes != NULL) {
			oldval = mandoc_strdup(conf->includes);
			break;
		}
		conf->includes = mandoc_strdup(cp);
		return 0;
	case 1:
		if (conf->man != NULL) {
			oldval = mandoc_strdup(conf->man);
			break;
		}
		conf->man = mandoc_strdup(cp);
		return 0;
	case 2:
		if (conf->paper != NULL) {
			oldval = mandoc_strdup(conf->paper);
			break;
		}
		conf->paper = mandoc_strdup(cp);
		return 0;
	case 3:
		if (conf->style != NULL) {
			oldval = mandoc_strdup(conf->style);
			break;
		}
		conf->style = mandoc_strdup(cp);
		return 0;
	case 4:
		if (conf->indent) {
			mandoc_asprintf(&oldval, "%zu", conf->indent);
			break;
		}
		conf->indent = strtonum(cp, 0, 1000, &errstr);
		if (errstr == NULL)
			return 0;
		warnx("-O indent=%s is %s", cp, errstr);
		return -1;
	case 5:
		if (conf->width) {
			mandoc_asprintf(&oldval, "%zu", conf->width);
			break;
		}
		conf->width = strtonum(cp, 58, 1000, &errstr);
		if (errstr == NULL)
			return 0;
		warnx("-O width=%s is %s", cp, errstr);
		return -1;
	case 6:
		conf->fragment = 1;
		return 0;
	case 7:
		conf->mdoc = 1;
		return 0;
	case 8:
		conf->noval = 1;
		return 0;
	default:
		if (fromfile)
			warnx("-O %s: Bad argument", cp);
		return -1;
	}
	if (fromfile == 0)
		warnx("-O %s=%s: Option already set to %s",
		    toks[tok], cp, oldval);
	free(oldval);
	return -1;
}
Ejemplo n.º 3
0
static void
format(const struct req *req, const char *file)
{
	struct mparse	*mp;
	struct mchars	*mchars;
	struct mdoc	*mdoc;
	struct man	*man;
	void		*vp;
	char		*opts;
	enum mandoclevel rc;
	int		 fd;
	int		 usepath;

	if (-1 == (fd = open(file, O_RDONLY, 0))) {
		puts("<P>You specified an invalid manual file.</P>");
		return;
	}

	mchars = mchars_alloc();
	mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_FATAL, NULL,
	    mchars, req->q.manpath);
	rc = mparse_readfd(mp, fd, file);
	close(fd);

	if (rc >= MANDOCLEVEL_FATAL) {
		fprintf(stderr, "fatal mandoc error: %s/%s\n",
		    req->q.manpath, file);
		pg_error_internal();
		return;
	}

	usepath = strcmp(req->q.manpath, req->p[0]);
	mandoc_asprintf(&opts,
	    "fragment,man=%s?query=%%N&sec=%%S%s%s%s%s",
	    scriptname,
	    req->q.arch	? "&arch="       : "",
	    req->q.arch	? req->q.arch    : "",
	    usepath	? "&manpath="    : "",
	    usepath	? req->q.manpath : "");

	mparse_result(mp, &mdoc, &man, NULL);
	if (NULL == man && NULL == mdoc) {
		fprintf(stderr, "fatal mandoc error: %s/%s\n",
		    req->q.manpath, file);
		pg_error_internal();
		mparse_free(mp);
		mchars_free(mchars);
		return;
	}

	vp = html_alloc(mchars, opts);

	if (NULL != mdoc)
		html_mdoc(vp, mdoc);
	else
		html_man(vp, man);

	html_free(vp);
	mparse_free(mp);
	mchars_free(mchars);
	free(opts);
}
Ejemplo n.º 4
0
static void
print_man_head(struct termp *p, const struct roff_meta *meta)
{
	const char		*volume;
	char			*title;
	size_t			 vollen, titlen;

	assert(meta->title);
	assert(meta->msec);

	volume = NULL == meta->vol ? "" : meta->vol;
	vollen = term_strlen(p, volume);

	/* Top left corner: manual title and section. */

	mandoc_asprintf(&title, "%s(%s)", meta->title, meta->msec);
	titlen = term_strlen(p, title);

	p->flags |= TERMP_NOBREAK | TERMP_NOSPACE;
	p->trailspace = 1;
	p->offset = 0;
	p->rmargin = 2 * (titlen+1) + vollen < p->maxrmargin ?
	    (p->maxrmargin - vollen + term_len(p, 1)) / 2 :
	    vollen < p->maxrmargin ? p->maxrmargin - vollen : 0;

	term_word(p, title);
	term_flushln(p);

	/* At the top in the middle: manual volume. */

	p->flags |= TERMP_NOSPACE;
	p->offset = p->rmargin;
	p->rmargin = p->offset + vollen + titlen < p->maxrmargin ?
	    p->maxrmargin - titlen : p->maxrmargin;

	term_word(p, volume);
	term_flushln(p);

	/* Top right corner: title and section, again. */

	p->flags &= ~TERMP_NOBREAK;
	p->trailspace = 0;
	if (p->rmargin + titlen <= p->maxrmargin) {
		p->flags |= TERMP_NOSPACE;
		p->offset = p->rmargin;
		p->rmargin = p->maxrmargin;
		term_word(p, title);
		term_flushln(p);
	}

	p->flags &= ~TERMP_NOSPACE;
	p->offset = 0;
	p->rmargin = p->maxrmargin;

	/*
	 * Groff prints three blank lines before the content.
	 * Do the same, except in the temporary, undocumented
	 * mode imitating mdoc(7) output.
	 */

	term_vspace(p);
	if ( ! p->mdocstyle) {
		term_vspace(p);
		term_vspace(p);
	}
	free(title);
}
Ejemplo n.º 5
0
static void
print_man_foot(struct termp *p, const struct roff_meta *meta)
{
	char			*title;
	size_t			 datelen, titlen;

	assert(meta->title);
	assert(meta->msec);
	assert(meta->date);

	term_fontrepl(p, TERMFONT_NONE);

	if (meta->hasbody)
		term_vspace(p);

	/*
	 * Temporary, undocumented option to imitate mdoc(7) output.
	 * In the bottom right corner, use the operating system
	 * instead of the title.
	 */

	if ( ! p->mdocstyle) {
		if (meta->hasbody) {
			term_vspace(p);
			term_vspace(p);
		}
		mandoc_asprintf(&title, "%s(%s)",
		    meta->title, meta->msec);
	} else if (meta->os) {
		title = mandoc_strdup(meta->os);
	} else {
		title = mandoc_strdup("");
	}
	datelen = term_strlen(p, meta->date);

	/* Bottom left corner: operating system. */

	p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;
	p->trailspace = 1;
	p->offset = 0;
	p->rmargin = p->maxrmargin > datelen ?
	    (p->maxrmargin + term_len(p, 1) - datelen) / 2 : 0;

	if (meta->os)
		term_word(p, meta->os);
	term_flushln(p);

	/* At the bottom in the middle: manual date. */

	p->offset = p->rmargin;
	titlen = term_strlen(p, title);
	p->rmargin = p->maxrmargin > titlen ? p->maxrmargin - titlen : 0;
	p->flags |= TERMP_NOSPACE;

	term_word(p, meta->date);
	term_flushln(p);

	/* Bottom right corner: manual title and section. */

	p->flags &= ~TERMP_NOBREAK;
	p->flags |= TERMP_NOSPACE;
	p->trailspace = 0;
	p->offset = p->rmargin;
	p->rmargin = p->maxrmargin;

	term_word(p, title);
	term_flushln(p);
	free(title);
}
Ejemplo n.º 6
0
static struct expr *
exprterm(const struct mansearch *search, char *buf, int cs)
{
	char		 errbuf[BUFSIZ];
	struct expr	*e;
	char		*key, *val;
	uint64_t	 iterbit;
	int		 i, irc;

	if ('\0' == *buf)
		return(NULL);

	e = mandoc_calloc(1, sizeof(struct expr));

	if (search->argmode == ARG_NAME) {
		e->bits = TYPE_Nm;
		e->substr = buf;
		e->equal = 1;
		return(e);
	}

	/*
	 * Separate macro keys from search string.
	 * If needed, request regular expression handling
	 * by setting e->substr to NULL.
	 */

	if (search->argmode == ARG_WORD) {
		e->bits = TYPE_Nm;
		e->substr = NULL;
		mandoc_asprintf(&val, "[[:<:]]%s[[:>:]]", buf);
		cs = 0;
	} else if ((val = strpbrk(buf, "=~")) == NULL) {
		e->bits = TYPE_Nm | TYPE_Nd;
		e->substr = buf;
	} else {
		if (val == buf)
			e->bits = TYPE_Nm | TYPE_Nd;
		if ('=' == *val)
			e->substr = val + 1;
		*val++ = '\0';
		if (NULL != strstr(buf, "arch"))
			cs = 0;
	}

	/* Compile regular expressions. */

	if (NULL == e->substr) {
		irc = regcomp(&e->regexp, val,
		    REG_EXTENDED | REG_NOSUB | (cs ? 0 : REG_ICASE));
		if (search->argmode == ARG_WORD)
			free(val);
		if (irc) {
			regerror(irc, &e->regexp, errbuf, sizeof(errbuf));
			fprintf(stderr, "regcomp: %s\n", errbuf);
			free(e);
			return(NULL);
		}
	}

	if (e->bits)
		return(e);

	/*
	 * Parse out all possible fields.
	 * If the field doesn't resolve, bail.
	 */

	while (NULL != (key = strsep(&buf, ","))) {
		if ('\0' == *key)
			continue;
		for (i = 0, iterbit = 1;
		     i < mansearch_keymax;
		     i++, iterbit <<= 1) {
			if (0 == strcasecmp(key,
			    mansearch_keynames[i])) {
				e->bits |= iterbit;
				break;
			}
		}
		if (i == mansearch_keymax) {
			if (strcasecmp(key, "any")) {
				free(e);
				return(NULL);
			}
			e->bits |= ~0ULL;
		}
	}

	return(e);
}
Ejemplo n.º 7
0
static void
buildnames(struct manpage *mpage, sqlite3 *db, sqlite3_stmt *s,
		uint64_t pageid, const char *path, int form)
{
	char		*newnames, *prevsec, *prevarch;
	const char	*oldnames, *sep1, *name, *sec, *sep2, *arch, *fsec;
	size_t		 i;
	int		 c;

	mpage->file = NULL;
	mpage->names = NULL;
	prevsec = prevarch = NULL;
	i = 1;
	SQL_BIND_INT64(db, s, i, pageid);
	while (SQLITE_ROW == (c = sqlite3_step(s))) {

		/* Decide whether we already have some names. */

		if (NULL == mpage->names) {
			oldnames = "";
			sep1 = "";
		} else {
			oldnames = mpage->names;
			sep1 = ", ";
		}

		/* Fetch the next name. */

		sec = (const char *)sqlite3_column_text(s, 0);
		arch = (const char *)sqlite3_column_text(s, 1);
		name = (const char *)sqlite3_column_text(s, 2);

		/* Remember the first section found. */

		if (9 < mpage->sec && '1' <= *sec && '9' >= *sec)
			mpage->sec = (*sec - '1') + 1;

		/* If the section changed, append the old one. */

		if (NULL != prevsec &&
		    (strcmp(sec, prevsec) ||
		     strcmp(arch, prevarch))) {
			sep2 = '\0' == *prevarch ? "" : "/";
			mandoc_asprintf(&newnames, "%s(%s%s%s)",
			    oldnames, prevsec, sep2, prevarch);
			free(mpage->names);
			oldnames = mpage->names = newnames;
			free(prevsec);
			free(prevarch);
			prevsec = prevarch = NULL;
		}

		/* Save the new section, to append it later. */

		if (NULL == prevsec) {
			prevsec = mandoc_strdup(sec);
			prevarch = mandoc_strdup(arch);
		}

		/* Append the new name. */

		mandoc_asprintf(&newnames, "%s%s%s",
		    oldnames, sep1, name);
		free(mpage->names);
		mpage->names = newnames;

		/* Also save the first file name encountered. */

		if (mpage->file != NULL)
			continue;

		if (form & FORM_SRC) {
			sep1 = "man";
			fsec = sec;
		} else {
			sep1 = "cat";
			fsec = "0";
		}
		sep2 = *arch == '\0' ? "" : "/";
		mandoc_asprintf(&mpage->file, "%s/%s%s%s%s/%s.%s",
		    path, sep1, sec, sep2, arch, name, fsec);
	}
	if (c != SQLITE_DONE)
		fprintf(stderr, "%s\n", sqlite3_errmsg(db));
	sqlite3_reset(s);

	/* Append one final section to the names. */

	if (prevsec != NULL) {
		sep2 = *prevarch == '\0' ? "" : "/";
		mandoc_asprintf(&newnames, "%s(%s%s%s)",
		    mpage->names, prevsec, sep2, prevarch);
		free(mpage->names);
		mpage->names = newnames;
		free(prevsec);
		free(prevarch);
	}
}
Ejemplo n.º 8
0
static void
print_man_foot(struct termp *p, const void *arg)
{
	const struct man_meta	*meta;
	char			*title;
	size_t			 datelen;

	meta = (const struct man_meta *)arg;
	assert(meta->title);
	assert(meta->msec);
	assert(meta->date);

	term_fontrepl(p, TERMFONT_NONE);

	if (meta->hasbody)
		term_vspace(p);

	/*
	 * Temporary, undocumented option to imitate mdoc(7) output.
	 * In the bottom right corner, use the source instead of
	 * the title.
	 */

	if ( ! p->mdocstyle) {
		if (meta->hasbody) {
			term_vspace(p);
			term_vspace(p);
		}
		mandoc_asprintf(&title, "%s(%s)",
		    meta->title, meta->msec);
	} else if (meta->source) {
		title = mandoc_strdup(meta->source);
	} else {
		title = mandoc_strdup("");
	}
	datelen = term_strlen(p, meta->date);

	/* Bottom left corner: manual source. */

	p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;
	p->trailspace = 1;
	p->offset = 0;
	p->rmargin = (p->maxrmargin - datelen + term_len(p, 1)) / 2;

	if (meta->source)
		term_word(p, meta->source);
	term_flushln(p);

	/* At the bottom in the middle: manual date. */

	p->flags |= TERMP_NOSPACE;
	p->offset = p->rmargin;
	p->rmargin = p->maxrmargin - term_strlen(p, title);
	if (p->offset + datelen >= p->rmargin)
		p->rmargin = p->offset + datelen;

	term_word(p, meta->date);
	term_flushln(p);

	/* Bottom right corner: manual title and section. */

	p->flags &= ~TERMP_NOBREAK;
	p->flags |= TERMP_NOSPACE;
	p->trailspace = 0;
	p->offset = p->rmargin;
	p->rmargin = p->maxrmargin;

	term_word(p, title);
	term_flushln(p);
	free(title);
}