diff options
Diffstat (limited to 'noop.c')
-rw-r--r-- | noop.c | 292 |
1 files changed, 292 insertions, 0 deletions
@@ -0,0 +1,292 @@ +/* $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); +} + |