From bd26da950b7144cb234ef8d0864173a897d2fd28 Mon Sep 17 00:00:00 2001 From: Kristaps Dzonsons Date: Wed, 25 Mar 2009 16:07:36 +0000 Subject: Actions in place for prologue parsing. --- man.c | 6 +-- man.h | 6 +-- man_action.c | 163 +++++++++++++++++++++++++++-------------------------------- man_macro.c | 27 +++++++--- 4 files changed, 101 insertions(+), 101 deletions(-) diff --git a/man.c b/man.c index 0e272452..4b20b728 100644 --- a/man.c +++ b/man.c @@ -1,4 +1,4 @@ -/* $Id: man.c,v 1.5 2009/03/25 15:36:05 kristaps Exp $ */ +/* $Id: man.c,v 1.6 2009/03/25 16:07:36 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -133,8 +133,8 @@ man_free1(struct man *man) man_node_freelist(man->first); if (man->meta.title) free(man->meta.title); - if (man->meta.os) - free(man->meta.os); + if (man->meta.source) + free(man->meta.source); if (man->meta.vol) free(man->meta.vol); } diff --git a/man.h b/man.h index cc26bc5f..0ca0c187 100644 --- a/man.h +++ b/man.h @@ -1,4 +1,4 @@ -/* $Id: man.h,v 1.3 2009/03/25 15:17:49 kristaps Exp $ */ +/* $Id: man.h,v 1.4 2009/03/25 16:07:36 kristaps Exp $ */ /* * Copyright (c) 2009 Kristaps Dzonsons * @@ -51,10 +51,10 @@ enum man_type { struct man_meta { int msec; - char *vol; time_t date; + char *vol; char *title; - char *os; + char *source; }; struct man_node { diff --git a/man_action.c b/man_action.c index 547a819a..cb82b6f1 100644 --- a/man_action.c +++ b/man_action.c @@ -1,4 +1,4 @@ -/* $Id: man_action.c,v 1.1 2009/03/25 15:36:05 kristaps Exp $ */ +/* $Id: man_action.c,v 1.2 2009/03/25 16:07:36 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -33,9 +33,12 @@ struct actions { }; +static int post_TH(struct man *); +static time_t man_atotime(const char *); + const struct actions man_actions[MAN_MAX] = { { NULL }, /* __ */ - { NULL }, /* TH */ + { post_TH }, /* TH */ { NULL }, /* SH */ { NULL }, /* SS */ { NULL }, /* TP */ @@ -78,119 +81,103 @@ man_action_post(struct man *m) return(1); } -#if 0 + static int -post_dt(POST_ARGS) +post_TH(struct man *m) { - struct mdoc_node *n; - const char *cp; - char *ep; - long lval; + struct man_node *n; + char *ep; + long lval; if (m->meta.title) free(m->meta.title); if (m->meta.vol) free(m->meta.vol); - if (m->meta.arch) - free(m->meta.arch); + if (m->meta.source) + free(m->meta.source); - m->meta.title = m->meta.vol = m->meta.arch = NULL; + m->meta.title = m->meta.vol = m->meta.source = NULL; m->meta.msec = 0; + m->meta.date = 0; - /* Handles: `.Dt' - * --> title = unknown, volume = local, msec = 0, arch = NULL - */ + /* ->TITLE<- MSEC DATE SOURCE VOL */ - if (NULL == (n = m->last->child)) { - m->meta.title = xstrdup("unknown"); - m->meta.vol = xstrdup("local"); - return(post_prol(m)); - } + n = m->last->child; + assert(n); - /* Handles: `.Dt TITLE' - * --> title = TITLE, volume = local, msec = 0, arch = NULL - */ + if (NULL == (m->meta.title = strdup(n->string))) + return(man_verr(m, n->line, n->pos, "malloc")); + + /* TITLE ->MSEC<- DATE SOURCE VOL */ + + n = n->next; + assert(n); - m->meta.title = xstrdup(n->string); + errno = 0; + lval = strtol(n->string, &ep, 10); + if (n->string[0] != '\0' && *ep == '\0') + m->meta.msec = (int)lval; + else if ( ! man_vwarn(m, n->line, n->pos, "invalid section")) + return(0); + + /* TITLE MSEC ->DATE<- SOURCE VOL */ if (NULL == (n = n->next)) { - m->meta.vol = xstrdup("local"); - return(post_prol(m)); + m->meta.date = time(NULL); + return(1); } - /* Handles: `.Dt TITLE SEC' - * --> title = TITLE, volume = SEC is msec ? - * format(msec) : SEC, - * msec = SEC is msec ? atoi(msec) : 0, - * arch = NULL - */ + if (0 == (m->meta.date = man_atotime(n->string))) { + if ( ! man_vwarn(m, n->line, n->pos, "invalid date")) + return(0); + m->meta.date = time(NULL); + } - cp = mdoc_a2msec(n->string); - if (cp) { - m->meta.vol = xstrdup(cp); - errno = 0; - lval = strtol(n->string, &ep, 10); - if (n->string[0] != '\0' && *ep == '\0') - m->meta.msec = (int)lval; - } else - m->meta.vol = xstrdup(n->string); - - if (NULL == (n = n->next)) - return(post_prol(m)); - - /* Handles: `.Dt TITLE SEC VOL' - * --> title = TITLE, volume = VOL is vol ? - * format(VOL) : - * VOL is arch ? format(arch) : - * VOL - */ + /* TITLE MSEC DATE ->SOURCE<- VOL */ - cp = mdoc_a2vol(n->string); - if (cp) { - free(m->meta.vol); - m->meta.vol = xstrdup(cp); - n = n->next; - } else { - cp = mdoc_a2arch(n->string); - if (NULL == cp) { - free(m->meta.vol); - m->meta.vol = xstrdup(n->string); - } else - m->meta.arch = xstrdup(cp); - } - - /* Ignore any subsequent parameters... */ - - return(post_prol(m)); -} + if ((n = n->next)) + if (NULL == (m->meta.source = strdup(n->string))) + return(man_verr(m, n->line, n->pos, "malloc")); -static int -post_prol(POST_ARGS) -{ - struct mdoc_node *n; + /* TITLE MSEC DATE SOURCE ->VOL<- */ + + if ((n = n->next)) + if (NULL == (m->meta.vol = strdup(n->string))) + return(man_verr(m, n->line, n->pos, "malloc")); /* * The end document shouldn't have the prologue macros as part * of the syntax tree (they encompass only meta-data). */ - if (m->last->parent->child == m->last) - m->last->parent->child = m->last->prev; - if (m->last->prev) - m->last->prev->next = NULL; - + assert(MAN_ROOT == m->last->parent->type); + m->last->parent->child = NULL; n = m->last; - assert(NULL == m->last->next); - - if (m->last->prev) { - m->last = m->last->prev; - m->next = MDOC_NEXT_SIBLING; - } else { - m->last = m->last->parent; - m->next = MDOC_NEXT_CHILD; - } + m->last = m->last->parent; + m->next = MAN_NEXT_CHILD; + assert(m->last == m->first); - mdoc_node_freelist(n); + man_node_freelist(n); return(1); } -#endif + + +static time_t +man_atotime(const char *p) +{ + struct tm tm; + char *pp; + + (void)memset(&tm, 0, sizeof(struct tm)); + + if ((pp = strptime(p, "%b %d %Y", &tm)) && 0 == *pp) + return(mktime(&tm)); + if ((pp = strptime(p, "%d %b %Y", &tm)) && 0 == *pp) + return(mktime(&tm)); + if ((pp = strptime(p, "%b %d, %Y", &tm)) && 0 == *pp) + return(mktime(&tm)); + if ((pp = strptime(p, "%b %Y", &tm)) && 0 == *pp) + return(mktime(&tm)); + + return(0); +} diff --git a/man_macro.c b/man_macro.c index d03d12c5..7121e490 100644 --- a/man_macro.c +++ b/man_macro.c @@ -1,4 +1,4 @@ -/* $Id: man_macro.c,v 1.6 2009/03/25 15:36:05 kristaps Exp $ */ +/* $Id: man_macro.c,v 1.7 2009/03/25 16:07:36 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -56,8 +56,16 @@ man_macro(struct man *man, int tok, int line, man->next = MAN_NEXT_SIBLING; } - for ( ; man->last && man->last != n; - man->last = man->last->parent) { + /* + * Note that when TH is pruned, we'll be back at the root, so + * make sure that we don't clobber as its sibling. + */ + + for ( ; man->last; man->last = man->last->parent) { + if (man->last == n) + break; + if (man->last->type == MAN_ROOT) + break; if ( ! man_valid_post(man)) return(0); if ( ! man_action_post(man)) @@ -66,12 +74,16 @@ man_macro(struct man *man, int tok, int line, assert(man->last); - if ( ! man_valid_post(man)) + /* + * Same here regarding whether we're back at the root. + */ + + if (man->last->type != MAN_ROOT && ! man_valid_post(man)) return(0); - if ( ! man_action_post(man)) + if (man->last->type != MAN_ROOT && ! man_action_post(man)) return(0); - - man->next = MAN_NEXT_SIBLING; + if (man->last->type != MAN_ROOT) + man->next = MAN_NEXT_SIBLING; return(1); } @@ -88,6 +100,7 @@ man_macroend(struct man *m) if ( ! man_action_post(m)) return(0); } + assert(m->last == m->first); if ( ! man_valid_post(m)) return(0); -- cgit v1.2.3-56-ge451