]> git.cameronkatri.com Git - mandoc.git/blobdiff - mandoc.c
Back out OpenBSD special case (ok Ingo Schwarze).
[mandoc.git] / mandoc.c
index 91a0fa928c1f227875a9b74b46da9ccd9ddcab78..17d6d1037489f20f319242e2d3f14929a17d3e29 100644 (file)
--- a/mandoc.c
+++ b/mandoc.c
@@ -1,4 +1,4 @@
-/*     $Id: mandoc.c,v 1.4 2009/10/28 19:21:59 kristaps Exp $ */
+/*     $Id: mandoc.c,v 1.11 2010/04/07 11:25:38 kristaps Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <sys/types.h>
 
 #include <assert.h>
 #include <sys/types.h>
 
 #include <assert.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <time.h>
 
 #include "libmandoc.h"
 
 
 #include "libmandoc.h"
 
+static int      a2time(time_t *, const char *, const char *);
+
+
 int
 mandoc_special(const char *p)
 {
 int
 mandoc_special(const char *p)
 {
-       int              c;
+       int              terminator;    /* Terminator for \s. */
+       int              lim;           /* Limit for N in \s. */
+       int              c, i;
        
        if ('\\' != *p++)
                return(0);
 
        switch (*p) {
        
        if ('\\' != *p++)
                return(0);
 
        switch (*p) {
-       case ('\\'):
-               /* FALLTHROUGH */
        case ('\''):
                /* FALLTHROUGH */
        case ('`'):
        case ('\''):
                /* FALLTHROUGH */
        case ('`'):
@@ -65,10 +73,85 @@ mandoc_special(const char *p)
                return(2);
        case ('e'):
                return(2);
                return(2);
        case ('e'):
                return(2);
-       case ('f'):
-               if (0 == *++p || ! isgraph((u_char)*p))
+       case ('s'):
+               if ('\0' == *++p)
+                       return(2);
+
+               c = 2;
+               terminator = 0;
+               lim = 1;
+
+               if (*p == '\'') {
+                       lim = 0;
+                       terminator = 1;
+                       ++p;
+                       ++c;
+               } else if (*p == '[') {
+                       lim = 0;
+                       terminator = 2;
+                       ++p;
+                       ++c;
+               } else if (*p == '(') {
+                       lim = 2;
+                       terminator = 3;
+                       ++p;
+                       ++c;
+               }
+
+               if (*p == '+' || *p == '-') {
+                       ++p;
+                       ++c;
+               }
+
+               if (*p == '\'') {
+                       if (terminator)
+                               return(0);
+                       lim = 0;
+                       terminator = 1;
+                       ++p;
+                       ++c;
+               } else if (*p == '[') {
+                       if (terminator)
+                               return(0);
+                       lim = 0;
+                       terminator = 2;
+                       ++p;
+                       ++c;
+               } else if (*p == '(') {
+                       if (terminator)
+                               return(0);
+                       lim = 2;
+                       terminator = 3;
+                       ++p;
+                       ++c;
+               }
+
+               /* TODO: needs to handle floating point. */
+
+               if ( ! isdigit((u_char)*p))
                        return(0);
                        return(0);
-               return(3);
+
+               for (i = 0; isdigit((u_char)*p); i++) {
+                       if (lim && i >= lim)
+                               break;
+                       ++p;
+                       ++c;
+               }
+
+               if (terminator && terminator < 3) {
+                       if (1 == terminator && *p != '\'')
+                               return(0);
+                       if (2 == terminator && *p != ']')
+                               return(0);
+                       ++p;
+                       ++c;
+               }
+
+               return(c);
+       case ('f'):
+               /* FALLTHROUGH */
+       case ('F'):
+               /* FALLTHROUGH */
        case ('*'):
                if (0 == *++p || ! isgraph((u_char)*p))
                        return(0);
        case ('*'):
                if (0 == *++p || ! isgraph((u_char)*p))
                        return(0);
@@ -113,7 +196,7 @@ mandoc_calloc(size_t num, size_t size)
 
        ptr = calloc(num, size);
        if (NULL == ptr) {
 
        ptr = calloc(num, size);
        if (NULL == ptr) {
-               fprintf(stderr, "memory exhausted\n");
+               perror(NULL);
                exit(EXIT_FAILURE);
        }
 
                exit(EXIT_FAILURE);
        }
 
@@ -128,7 +211,7 @@ mandoc_malloc(size_t size)
 
        ptr = malloc(size);
        if (NULL == ptr) {
 
        ptr = malloc(size);
        if (NULL == ptr) {
-               fprintf(stderr, "memory exhausted\n");
+               perror(NULL);
                exit(EXIT_FAILURE);
        }
 
                exit(EXIT_FAILURE);
        }
 
@@ -142,7 +225,7 @@ mandoc_realloc(void *ptr, size_t size)
 
        ptr = realloc(ptr, size);
        if (NULL == ptr) {
 
        ptr = realloc(ptr, size);
        if (NULL == ptr) {
-               fprintf(stderr, "memory exhausted\n");
+               perror(NULL);
                exit(EXIT_FAILURE);
        }
 
                exit(EXIT_FAILURE);
        }
 
@@ -150,19 +233,6 @@ mandoc_realloc(void *ptr, size_t size)
 }
 
 
 }
 
 
-void *
-mandoc_reallocf(void *old_ptr, size_t size) /* FIXME: remove (not used) */
-{
-       void            *ptr;
-
-       ptr = realloc(old_ptr, size);
-       if (NULL == ptr)
-               free(old_ptr);
-
-       return(ptr);
-}
-
-
 char *
 mandoc_strdup(const char *ptr)
 {
 char *
 mandoc_strdup(const char *ptr)
 {
@@ -170,9 +240,63 @@ mandoc_strdup(const char *ptr)
 
        p = strdup(ptr);
        if (NULL == p) {
 
        p = strdup(ptr);
        if (NULL == p) {
-               fprintf(stderr, "memory exhausted\n");
+               perror(NULL);
                exit(EXIT_FAILURE);
        }
 
        return(p);
 }
                exit(EXIT_FAILURE);
        }
 
        return(p);
 }
+
+
+static int
+a2time(time_t *t, const char *fmt, const char *p)
+{
+       struct tm        tm;
+       char            *pp;
+
+       memset(&tm, 0, sizeof(struct tm));
+
+       pp = strptime(p, fmt, &tm);
+       if (NULL != pp && '\0' == *pp) {
+               *t = mktime(&tm);
+               return(1);
+       }
+
+       return(0);
+}
+
+
+/*
+ * Convert from a manual date string (see mdoc(7) and man(7)) into a
+ * date according to the stipulated date type.
+ */
+time_t
+mandoc_a2time(int flags, const char *p)
+{
+       time_t           t;
+
+       if (MTIME_MDOCDATE & flags) {
+               if (0 == strcmp(p, "$" "Mdocdate$"))
+                       return(time(NULL));
+               if (a2time(&t, "$" "Mdocdate: %b %d %Y $", p))
+                       return(t);
+       }
+
+       if (MTIME_CANONICAL & flags || MTIME_REDUCED & flags) 
+               if (a2time(&t, "%b %d, %Y", p))
+                       return(t);
+
+       if (MTIME_ISO_8601 & flags) 
+               if (a2time(&t, "%Y-%m-%d", p))
+                       return(t);
+
+       if (MTIME_REDUCED & flags) {
+               if (a2time(&t, "%d, %Y", p))
+                       return(t);
+               if (a2time(&t, "%Y", p))
+                       return(t);
+       }
+
+       return(0);
+}
+