summaryrefslogtreecommitdiffstats
path: root/prologue.c
diff options
context:
space:
mode:
Diffstat (limited to 'prologue.c')
-rw-r--r--prologue.c217
1 files changed, 217 insertions, 0 deletions
diff --git a/prologue.c b/prologue.c
new file mode 100644
index 00000000..678851b6
--- /dev/null
+++ b/prologue.c
@@ -0,0 +1,217 @@
+/* $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 <stdlib.h>
+
+#include "private.h"
+
+static int prologue_dt(MACRO_PROT_ARGS);
+static int prologue_dd(MACRO_PROT_ARGS);
+static int prologue_os(MACRO_PROT_ARGS);
+
+static int
+prologue_dt(MACRO_PROT_ARGS)
+{
+ int lastarg, j;
+ char *args[MDOC_LINEARG_MAX];
+
+ if (SEC_PROLOGUE != mdoc->sec_lastn)
+ return(mdoc_err(mdoc, tok, ppos, ERR_SEC_NPROLOGUE));
+ if (0 == mdoc->meta.date)
+ return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE_OO));
+ if (mdoc->meta.title[0])
+ return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE_REP));
+
+ j = -1;
+ lastarg = ppos;
+
+again:
+ if (j == MDOC_LINEARG_MAX)
+ return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY));
+
+ lastarg = *pos;
+
+ switch (mdoc_args(mdoc, tok, pos, buf, 0, &args[++j])) {
+ case (ARGS_EOLN):
+ if (mdoc->meta.title)
+ return(1);
+ if ( ! mdoc_warn(mdoc, tok, ppos, WARN_ARGS_GE1))
+ return(0);
+ (void)xstrlcpy(mdoc->meta.title,
+ "UNTITLED", META_TITLE_SZ);
+ return(1);
+ case (ARGS_ERROR):
+ return(0);
+ default:
+ break;
+ }
+
+ if (MDOC_MAX != mdoc_find(mdoc, args[j]) && ! mdoc_warn
+ (mdoc, tok, lastarg, WARN_SYNTAX_MACLIKE))
+ return(0);
+
+ if (0 == j) {
+ if (xstrlcpy(mdoc->meta.title, args[0], META_TITLE_SZ))
+ goto again;
+ return(mdoc_err(mdoc, tok, lastarg, ERR_SYNTAX_ARGFORM));
+
+ } else if (1 == j) {
+ mdoc->meta.msec = mdoc_atomsec(args[1]);
+ if (MSEC_DEFAULT != mdoc->meta.msec)
+ goto again;
+ return(mdoc_err(mdoc, tok, -1, ERR_SYNTAX_ARGFORM));
+
+ } else if (2 == j) {
+ mdoc->meta.vol = mdoc_atovol(args[2]);
+ if (VOL_DEFAULT != mdoc->meta.vol)
+ goto again;
+ mdoc->meta.arch = mdoc_atoarch(args[2]);
+ if (ARCH_DEFAULT != mdoc->meta.arch)
+ goto again;
+ return(mdoc_err(mdoc, tok, lastarg, ERR_SYNTAX_ARGFORM));
+ }
+
+ return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY));
+}
+
+
+static int
+prologue_os(MACRO_PROT_ARGS)
+{
+ int lastarg, j;
+ char *args[MDOC_LINEARG_MAX];
+
+ /* FIXME: if we use `Os' again... ? */
+
+ if (SEC_PROLOGUE != mdoc->sec_lastn)
+ return(mdoc_err(mdoc, tok, ppos, ERR_SEC_NPROLOGUE));
+ if (0 == mdoc->meta.title[0])
+ return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE_OO));
+ if (mdoc->meta.os[0])
+ return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE_REP));
+
+ j = -1;
+ lastarg = ppos;
+
+again:
+ if (j == MDOC_LINEARG_MAX)
+ return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY));
+
+ lastarg = *pos;
+
+ switch (mdoc_args(mdoc, tok, pos, buf,
+ ARGS_QUOTED, &args[++j])) {
+ case (ARGS_EOLN):
+ mdoc->sec_lastn = mdoc->sec_last = SEC_BODY;
+ return(1);
+ case (ARGS_ERROR):
+ return(0);
+ default:
+ break;
+ }
+
+ if ( ! xstrlcat(mdoc->meta.os, args[j], sizeof(mdoc->meta.os)))
+ return(mdoc_err(mdoc, tok, lastarg, ERR_SYNTAX_ARGFORM));
+ if ( ! xstrlcat(mdoc->meta.os, " ", sizeof(mdoc->meta.os)))
+ return(mdoc_err(mdoc, tok, lastarg, ERR_SYNTAX_ARGFORM));
+
+ goto again;
+ /* NOTREACHED */
+}
+
+
+static int
+prologue_dd(MACRO_PROT_ARGS)
+{
+ int lastarg, j;
+ char *args[MDOC_LINEARG_MAX], date[64];
+
+ if (SEC_PROLOGUE != mdoc->sec_lastn)
+ return(mdoc_err(mdoc, tok, ppos, ERR_SEC_NPROLOGUE));
+ if (mdoc->meta.title[0])
+ return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE_OO));
+ if (mdoc->meta.date)
+ return(mdoc_err(mdoc, tok, ppos, ERR_SEC_PROLOGUE_REP));
+
+ j = -1;
+ date[0] = 0;
+ lastarg = ppos;
+
+again:
+ if (j == MDOC_LINEARG_MAX)
+ return(mdoc_err(mdoc, tok, lastarg, ERR_ARGS_MANY));
+
+ lastarg = *pos;
+ switch (mdoc_args(mdoc, tok, pos, buf, 0, &args[++j])) {
+ case (ARGS_EOLN):
+ if (mdoc->meta.date)
+ return(1);
+ mdoc->meta.date = mdoc_atotime(date);
+ if (mdoc->meta.date)
+ return(1);
+ return(mdoc_err(mdoc, tok, ppos, ERR_SYNTAX_ARGFORM));
+ case (ARGS_ERROR):
+ return(0);
+ default:
+ break;
+ }
+
+ if (MDOC_MAX != mdoc_find(mdoc, args[j]) && ! mdoc_warn
+ (mdoc, tok, lastarg, WARN_SYNTAX_MACLIKE))
+ return(0);
+
+ if (0 == j) {
+ if (xstrcmp("$Mdocdate$", args[j])) {
+ mdoc->meta.date = time(NULL);
+ goto again;
+ } else if (xstrcmp("$Mdocdate:", args[j]))
+ goto again;
+ } else if (4 == j)
+ if ( ! xstrcmp("$", args[j]))
+ goto again;
+
+ if ( ! xstrlcat(date, args[j], sizeof(date)))
+ return(mdoc_err(mdoc, tok, lastarg, ERR_SYNTAX_ARGFORM));
+ if ( ! xstrlcat(date, " ", sizeof(date)))
+ return(mdoc_err(mdoc, tok, lastarg, ERR_SYNTAX_ARGFORM));
+
+ goto again;
+ /* NOTREACHED */
+}
+
+
+int
+macro_prologue(MACRO_PROT_ARGS)
+{
+
+ switch (tok) {
+ case (MDOC_Dt):
+ return(prologue_dt(mdoc, tok, ppos, pos, buf));
+ case (MDOC_Dd):
+ return(prologue_dd(mdoc, tok, ppos, pos, buf));
+ case (MDOC_Os):
+ return(prologue_os(mdoc, tok, ppos, pos, buf));
+ default:
+ break;
+ }
+
+ abort();
+ /* NOTREACHED */
+}
+