- /* $Id: mmain.c,v 1.1 2009/02/22 22:58:39 kristaps Exp $ */
+ /* $Id: mmain.c,v 1.4 2009/02/23 15:38:20 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
struct mdoc *mdoc; /* Active parser. */
char *buf; /* Input buffer. */
u_long bufsz; /* Input buffer size. */
- char in[MAXPATHLEN]; /* Input file name. */
+ char *in; /* Input file name. */
int fdin; /* Input file desc. */
};
#ifdef __linux__
extern int getsubopt(char **, char *const *, char **);
+extern size_t strlcpy(char *, const char *, size_t);
+extern size_t strlcat(char *, const char *, size_t);
#endif
+/*
+ * Print our and our caller's usage message.
+ */
void
mmain_usage(const char *help)
{
}
+/*
+ * Allocate the convenience library and initialise some values.
+ */
struct mmain *
mmain_alloc(void)
{
if (NULL == (p = calloc(1, sizeof(struct mmain))))
err(1, "malloc");
- (void)strlcpy(p->in, "-", MAXPATHLEN);
+ p->in = "-";
p->fdin = STDIN_FILENO;
return(p);
}
+/*
+ * Parse command-line options. Accepts a small (<28 char) opstring "u"
+ * parameter (e.g. "ho:") or NULL, a corresponding "help" string (e.g.
+ * "[-h] [-o output]" or NULL, a callback function for parsed arguments
+ * and an opaque pointer argument for that function.
+ */
int
-mmain_isopt(int c)
+mmain_getopt(struct mmain *p, int argc, char *argv[],
+ const char *help, const char *u, void *arg,
+ int (*getopt_cb)(void *, int, const char *))
{
-
- switch (c) {
- case ('v'):
- /* FALLTHROUGH */
- case ('W'):
- return(1);
- default:
- break;
- }
- return(0);
-}
+ int c;
+ char opts[32]; /* XXX */
+ size_t sz;
+ extern int optind;
-int
-mmain_getopt(struct mmain *p, int argc,
- char *argv[], const char *help)
-{
- int c;
+ sz = strlcpy(opts, "vW:", 32);
+ assert(sz < 32);
- while (-1 != (c = getopt(argc, argv, ":vW:")))
+ if (u) {
+ sz = strlcat(opts, u, 32);
+ assert(sz < 32);
+ }
+
+ optind = 1;
+
+ /* LINTED */
+ while (-1 != (c = getopt(argc, argv, opts)))
switch (c) {
case ('v'):
p->dbg++;
return(0);
break;
case ('?'):
- break;
- default:
mmain_usage(help);
return(0);
+ default:
+ assert(getopt_cb);
+ if ((*getopt_cb)(arg, c, optarg))
+ break;
+ return(0);
}
argv += optind;
- argc -= optind;
+ if ((argc -= optind) > 0)
+ p->in = *argv++;
- if (0 == argc)
- return(1);
-
- if (strlcpy(p->in, *argv++, MAXPATHLEN) < MAXPATHLEN)
- return(1);
-
- warnx("filename too long");
- return(0);
+ return(1);
}
-__dead void
-mmain_exit(struct mmain *p, int code)
+dead_pre void
+mmain_exit(struct mmain *p, int code)
{
if (p->mdoc)