]> git.cameronkatri.com Git - mandoc.git/blobdiff - mandoc.c
Whitespace fix.
[mandoc.git] / mandoc.c
index 7839c37d61645f61b4c49c7eb158b6f611cb3ffd..3bdb171b9a499a4bc68d88e1b9f3d0bcbf14bd8e 100644 (file)
--- a/mandoc.c
+++ b/mandoc.c
@@ -1,4 +1,4 @@
-/*     $Id: mandoc.c,v 1.3 2009/07/24 20:22:24 kristaps Exp $ */
+/*     $Id: mandoc.c,v 1.10 2010/01/05 19:51:10 kristaps Exp $ */
 /*
  * 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.
  */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <sys/types.h>
 
 #include <assert.h>
 #include <ctype.h>
 #include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
 
 #include "libmandoc.h"
 
+static int      a2time(time_t *, const char *, const char *);
+
+
 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) {
-       case ('\\'):
-               /* FALLTHROUGH */
        case ('\''):
                /* FALLTHROUGH */
        case ('`'):
@@ -64,9 +74,84 @@ mandoc_special(const char *p)
        case ('e'):
                return(2);
        case ('f'):
-               if (0 == *++p || ! isgraph((u_char)*p))
+               if ('\0' == *++p || ! isgraph((u_char)*p))
                        return(0);
                return(3);
+       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);
+
+               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 ('*'):
                if (0 == *++p || ! isgraph((u_char)*p))
                        return(0);
@@ -103,3 +188,115 @@ mandoc_special(const char *p)
        return(*p == ']' ? c : 0);
 }
 
+
+void *
+mandoc_calloc(size_t num, size_t size)
+{
+       void            *ptr;
+
+       ptr = calloc(num, size);
+       if (NULL == ptr) {
+               perror(NULL);
+               exit(EXIT_FAILURE);
+       }
+
+       return(ptr);
+}
+
+
+void *
+mandoc_malloc(size_t size)
+{
+       void            *ptr;
+
+       ptr = malloc(size);
+       if (NULL == ptr) {
+               perror(NULL);
+               exit(EXIT_FAILURE);
+       }
+
+       return(ptr);
+}
+
+
+void *
+mandoc_realloc(void *ptr, size_t size)
+{
+
+       ptr = realloc(ptr, size);
+       if (NULL == ptr) {
+               perror(NULL);
+               exit(EXIT_FAILURE);
+       }
+
+       return(ptr);
+}
+
+
+char *
+mandoc_strdup(const char *ptr)
+{
+       char            *p;
+
+       p = strdup(ptr);
+       if (NULL == p) {
+               perror(NULL);
+               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);
+}
+