summaryrefslogblamecommitdiffstats
path: root/noop.c
blob: 258c059ffd3dde3f060b9eba0462767bd52cf00b (plain) (tree)



































































































































































































































































































                                                                        
/* $Id$ */
/*
 * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all
 * copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */
#include <assert.h>
#include <err.h>
#include <stdlib.h>

#include "private.h"


struct	md_noop {
	const struct md_args	*args;
	const struct md_rbuf	*rbuf;
	struct rofftree	 	*tree;
};


static	int		 noop_roffmsg(void *arg, 
				enum roffmsg, const char *, 
				const char *, const char *);
static	int		 noop_roffhead(void *, const struct tm *, 
				const char *, const char *, 
				enum roffmsec, enum roffvol);
static	int		 noop_rofftail(void *, const struct tm *, 
				const char *, const char *, 
				enum roffmsec, enum roffvol);
static	int		 noop_roffin(void *, int, 
				int *, const char **);
static	int		 noop_roffdata(void *, int, 
				const char *, const char *);
static	int		 noop_roffout(void *, int);
static	int		 noop_roffblkin(void *, int, int *, 
				const char **);
static	int		 noop_roffblkout(void *, int);
static	int		 noop_roffspecial(void *, int, 
				const char *, const int *,
				const char **, const char **);
static	int		 noop_roffblkheadin(void *, int, 
				int *, const char **);
static	int		 noop_roffblkheadout(void *, int);
static	int		 noop_roffblkbodyin(void *, int, 
				int *, const char **);
static	int		 noop_roffblkbodyout(void *, int);

#ifdef __linux__
extern	size_t		 strlcat(char *, const char *, size_t);
extern	size_t		 strlcpy(char *, const char *, size_t);
#endif


int
md_exit_noop(void *data, int flush)
{
	struct md_noop	*noop;
	int		 c;

	noop = (struct md_noop *)data;
	c = roff_free(noop->tree, flush);
	free(noop);
	return(c);
}


int
md_line_noop(void *data, char *buf)
{
	struct md_noop	*noop;

	noop = (struct md_noop *)data;
	return(roff_engine(noop->tree, buf));
}


void *
md_init_noop(const struct md_args *args, 
		struct md_mbuf *mbuf, const struct md_rbuf *rbuf)
{
	struct roffcb	 cb;
	struct md_noop	*noop;

	if (NULL == (noop = calloc(1, sizeof(struct md_noop))))
		err(1, "calloc");

	noop->args = args;
	noop->rbuf = rbuf;

	cb.roffhead = noop_roffhead;
	cb.rofftail = noop_rofftail;
	cb.roffin = noop_roffin;
	cb.roffout = noop_roffout;
	cb.roffblkin = noop_roffblkin;
	cb.roffblkheadin = noop_roffblkheadin;
	cb.roffblkheadout = noop_roffblkheadout;
	cb.roffblkbodyin = noop_roffblkbodyin;
	cb.roffblkbodyout = noop_roffblkbodyout;
	cb.roffblkout = noop_roffblkout;
	cb.roffspecial = noop_roffspecial;
	cb.roffmsg = noop_roffmsg;
	cb.roffdata = noop_roffdata;

	if (NULL == (noop->tree = roff_alloc(&cb, noop))) {
		free(noop);
		return(NULL);
	}
	return(noop);
}


/* ARGSUSED */
static int
noop_roffhead(void *arg, const struct tm *tm, const char *os, 
		const char *title, enum roffmsec sec, enum roffvol vol)
{

	return(1);
}


/* ARGSUSED */
static int
noop_rofftail(void *arg, const struct tm *tm, const char *os, 
		const char *title, enum roffmsec sec, enum roffvol vol)
{

	return(1);
}


/* ARGSUSED */
static int
noop_roffspecial(void *arg, int tok, const char *start, 
		const int *argc, const char **argv, const char **more)
{

	return(1);
}


/* ARGSUSED */
static int
noop_roffblkin(void *arg, int tok, 
		int *argc, const char **argv)
{

	return(1);
}


/* ARGSUSED */
static int
noop_roffblkout(void *arg, int tok)
{

	return(1);
}


/* ARGSUSED */
static int
noop_roffblkbodyin(void *arg, int tok, 
		int *argc, const char **argv)
{

	return(1);
}


/* ARGSUSED */
static int
noop_roffblkbodyout(void *arg, int tok)
{

	return(1);
}


/* ARGSUSED */
static int
noop_roffblkheadin(void *arg, int tok, 
		int *argc, const char **argv)
{

	return(1);
}


/* ARGSUSED */
static int
noop_roffblkheadout(void *arg, int tok)
{

	return(1);
}


/* ARGSUSED */
static int
noop_roffin(void *arg, int tok, int *argc, const char **argv)
{

	return(1);
}


/* ARGSUSED */
static int
noop_roffout(void *arg, int tok)
{

	return(1);
}


/* ARGSUSED */
static int
noop_roffdata(void *arg, int tok, 
		const char *start, const char *buf)
{

	return(1);
}


static int
noop_roffmsg(void *arg, enum roffmsg lvl, 
		const char *buf, const char *pos, const char *msg)
{
	struct md_noop	*p;
	char		*level;
	char		 b[256];
	int		 i;

	p = (struct md_noop *)arg;
	assert(p);

	switch (lvl) {
	case (ROFF_WARN):
		level = "warning";
		if ( ! (MD_WARN_ALL & p->args->warnings))
			return(1);
		break;
	case (ROFF_ERROR):
		level = "error";
		break;
	default:
		abort();
		/* NOTREACHED */
	}

	if (pos) {
		assert(pos >= buf);
		if (0 < p->args->verbosity) {
			(void)snprintf(b, sizeof(b), 
					"%s:%zu: %s: %s\n",
					p->rbuf->name, p->rbuf->line, 
					level, msg);
			(void)strlcat(b, "Error at: ", sizeof(b));
			(void)strlcat(b, p->rbuf->linebuf, sizeof(b));

			(void)strlcat(b, "\n          ", sizeof(b));
			for (i = 0; i < pos - buf; i++)
				(void)strlcat(b, " ", sizeof(b));
			(void)strlcat(b, "^", sizeof(b));

		} else
			(void)snprintf(b, sizeof(b), 
					"%s:%zu: %s: %s (col %zu)", 
					p->rbuf->name, p->rbuf->line, 
					level, msg, pos - buf);
	} else 
		(void)snprintf(b, sizeof(b), "%s: %s: %s", 
				p->rbuf->name, level, msg);

	(void)fprintf(stderr, "%s\n", b);
	return(lvl == ROFF_WARN ? 1 : 0);
}