-/* $Id: strings.c,v 1.2 2008/12/17 17:18:38 kristaps Exp $ */
+/* $Id: strings.c,v 1.28 2009/03/13 07:46:10 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
+#include <sys/types.h>
+
#include <assert.h>
#include <ctype.h>
#include <stdlib.h>
#include "private.h"
-int
-mdoc_isdelim(const char *p)
-{
+/*
+ * Various string-literal operations: converting scalars to and from
+ * strings, etc.
+ */
- if (0 == *p)
- return(0);
- if (0 != *(p + 1))
+struct mdoc_secname {
+ const char *name;
+ int flag;
+#define MSECNAME_META (1 << 0)
+};
+
+/* Section names corresponding to mdoc_sec. */
+
+static const struct mdoc_secname secnames[] = {
+ { "PROLOGUE", MSECNAME_META },
+ { "BODY", MSECNAME_META },
+ { "NAME", 0 },
+ { "LIBRARY", 0 },
+ { "SYNOPSIS", 0 },
+ { "DESCRIPTION", 0 },
+ { "IMPLEMENTATION NOTES", 0 },
+ { "RETURN VALUES", 0 },
+ { "ENVIRONMENT", 0 },
+ { "FILES", 0 },
+ { "EXAMPLES", 0 },
+ { "DIAGNOSTICS", 0 },
+ { "COMPATIBILITY", 0 },
+ { "ERRORS", 0 },
+ { "SEE ALSO", 0 },
+ { "STANDARDS", 0 },
+ { "HISTORY", 0 },
+ { "AUTHORS", 0 },
+ { "CAVEATS", 0 },
+ { "BUGS", 0 },
+ { NULL, 0 }
+};
+
+#ifdef __linux__
+extern char *strptime(const char *, const char *, struct tm *);
+#endif
+
+
+size_t
+mdoc_isescape(const char *p)
+{
+ size_t c;
+
+ if ('\\' != *p++)
return(0);
switch (*p) {
- case('{'):
+ case ('\\'):
+ /* FALLTHROUGH */
+ case ('\''):
/* FALLTHROUGH */
+ case ('`'):
+ /* FALLTHROUGH */
+ case ('q'):
+ /* FALLTHROUGH */
+ case ('-'):
+ /* FALLTHROUGH */
+ case (' '):
+ /* FALLTHROUGH */
+ case ('&'):
+ /* FALLTHROUGH */
+ case ('.'):
+ /* FALLTHROUGH */
+ case ('e'):
+ return(2);
+ case ('*'):
+ if (0 == *++p || ! isgraph((u_char)*p))
+ return(0);
+ switch (*p) {
+ case ('('):
+ if (0 == *++p || ! isgraph((u_char)*p))
+ return(0);
+ return(4);
+ case ('['):
+ for (c = 3, p++; *p && ']' != *p; p++, c++)
+ if ( ! isgraph((u_char)*p))
+ break;
+ return(*p == ']' ? c : 0);
+ default:
+ break;
+ }
+ return(3);
+ case ('('):
+ if (0 == *++p || ! isgraph((u_char)*p))
+ return(0);
+ if (0 == *++p || ! isgraph((u_char)*p))
+ return(0);
+ return(4);
+ case ('['):
+ break;
+ default:
+ return(0);
+ }
+
+ for (c = 3, p++; *p && ']' != *p; p++, c++)
+ if ( ! isgraph((u_char)*p))
+ break;
+
+ return(*p == ']' ? c : 0);
+}
+
+
+int
+mdoc_iscdelim(char p)
+{
+
+ switch (p) {
case('.'):
/* FALLTHROUGH */
case(','):
/* FALLTHROUGH */
case(']'):
/* FALLTHROUGH */
+ case('{'):
+ /* FALLTHROUGH */
case('}'):
return(1);
default:
}
-enum mdoc_sec
-mdoc_atosec(size_t sz, const char **p)
+int
+mdoc_isdelim(const char *p)
{
- assert(sz > 0);
- if (sz > 2)
- return(SEC_CUSTOM);
- if (sz == 2) {
- if (0 == strcmp(*p, "RETURN") &&
- 0 == strcmp(*(p + 1), "VALUES"))
- return(SEC_RETURN_VALUES);
- if (0 == strcmp(*p, "SEE") &&
- 0 == strcmp(*(p + 1), "ALSO"))
- return(SEC_SEE_ALSO);
- return(SEC_CUSTOM);
- }
+ if (0 == *p)
+ return(0);
+ if (0 != *(p + 1))
+ return(0);
+ return(mdoc_iscdelim(*p));
+}
+
- if (0 == strcmp(*p, "NAME"))
- return(SEC_NAME);
- else if (0 == strcmp(*p, "SYNOPSIS"))
- return(SEC_SYNOPSIS);
- else if (0 == strcmp(*p, "DESCRIPTION"))
- return(SEC_DESCRIPTION);
- else if (0 == strcmp(*p, "ENVIRONMENT"))
- return(SEC_ENVIRONMENT);
- else if (0 == strcmp(*p, "FILES"))
- return(SEC_FILES);
- else if (0 == strcmp(*p, "EXAMPLES"))
- return(SEC_EXAMPLES);
- else if (0 == strcmp(*p, "DIAGNOSTICS"))
- return(SEC_DIAGNOSTICS);
- else if (0 == strcmp(*p, "ERRORS"))
- return(SEC_ERRORS);
- else if (0 == strcmp(*p, "STANDARDS"))
- return(SEC_STANDARDS);
- else if (0 == strcmp(*p, "HISTORY"))
- return(SEC_HISTORY);
- else if (0 == strcmp(*p, "AUTHORS"))
- return(SEC_AUTHORS);
- else if (0 == strcmp(*p, "CAVEATS"))
- return(SEC_CAVEATS);
- else if (0 == strcmp(*p, "BUGS"))
- return(SEC_BUGS);
+enum mdoc_sec
+mdoc_atosec(const char *p)
+{
+ const struct mdoc_secname *n;
+ int i;
+
+ for (i = 0, n = secnames; n->name; n++, i++)
+ if ( ! (n->flag & MSECNAME_META))
+ if (xstrcmp(p, n->name))
+ return((enum mdoc_sec)i);
return(SEC_CUSTOM);
}
mdoc_atotime(const char *p)
{
struct tm tm;
+ char *pp;
+
+ (void)memset(&tm, 0, sizeof(struct tm));
- if (strptime(p, "%b %d %Y", &tm))
+ if (xstrcmp(p, "$Mdocdate: March 13 2009 $"))
+ return(time(NULL));
+ if ((pp = strptime(p, "$Mdocdate: March 13 2009 $", &tm)) && 0 == *pp)
return(mktime(&tm));
- if (strptime(p, "%b %d, %Y", &tm))
+ /* XXX - this matches "June 1999", which is wrong. */
+ if ((pp = strptime(p, "%b %d %Y", &tm)) && 0 == *pp)
+ return(mktime(&tm));
+ if ((pp = strptime(p, "%b %d, %Y", &tm)) && 0 == *pp)
return(mktime(&tm));
return(0);
}
-enum mdoc_msec
-mdoc_atomsec(const char *p)
+size_t
+mdoc_macro2len(int macro)
{
- if (0 == strcmp(p, "1"))
- return(MSEC_1);
- else if (0 == strcmp(p, "2"))
- return(MSEC_2);
- else if (0 == strcmp(p, "3"))
- return(MSEC_3);
- else if (0 == strcmp(p, "3f"))
- return(MSEC_3f);
- else if (0 == strcmp(p, "3p"))
- return(MSEC_3p);
- else if (0 == strcmp(p, "4"))
- return(MSEC_4);
- else if (0 == strcmp(p, "5"))
- return(MSEC_5);
- else if (0 == strcmp(p, "6"))
- return(MSEC_6);
- else if (0 == strcmp(p, "7"))
- return(MSEC_7);
- else if (0 == strcmp(p, "8"))
- return(MSEC_8);
- else if (0 == strcmp(p, "9"))
- return(MSEC_9);
- else if (0 == strcmp(p, "X11"))
- return(MSEC_X11);
- else if (0 == strcmp(p, "X11R6"))
- return(MSEC_X11R6);
- else if (0 == strcmp(p, "local"))
- return(MSEC_local);
- else if (0 == strcmp(p, "n"))
- return(MSEC_n);
- else if (0 == strcmp(p, "unass"))
- return(MSEC_unass);
- else if (0 == strcmp(p, "draft"))
- return(MSEC_draft);
- else if (0 == strcmp(p, "paper"))
- return(MSEC_paper);
-
- return(MSEC_DEFAULT);
-}
-
-
-enum mdoc_vol
-mdoc_atovol(const char *p)
-{
-
- if (0 == strcmp(p, "AMD"))
- return(VOL_AMD);
- else if (0 == strcmp(p, "IND"))
- return(VOL_IND);
- else if (0 == strcmp(p, "KM"))
- return(VOL_KM);
- else if (0 == strcmp(p, "LOCAL"))
- return(VOL_LOCAL);
- else if (0 == strcmp(p, "PRM"))
- return(VOL_PRM);
- else if (0 == strcmp(p, "PS1"))
- return(VOL_PS1);
- else if (0 == strcmp(p, "SMM"))
- return(VOL_SMM);
- else if (0 == strcmp(p, "URM"))
- return(VOL_URM);
- else if (0 == strcmp(p, "USD"))
- return(VOL_USD);
-
- return(VOL_DEFAULT);
-}
-
-
-enum mdoc_arch
-mdoc_atoarch(const char *p)
-{
-
- if (0 == strcmp(p, "alpha"))
- return(ARCH_alpha);
- else if (0 == strcmp(p, "amd64"))
- return(ARCH_amd64);
- else if (0 == strcmp(p, "amiga"))
- return(ARCH_amiga);
- else if (0 == strcmp(p, "arc"))
- return(ARCH_arc);
- else if (0 == strcmp(p, "armish"))
- return(ARCH_armish);
- else if (0 == strcmp(p, "aviion"))
- return(ARCH_aviion);
- else if (0 == strcmp(p, "hp300"))
- return(ARCH_hp300);
- else if (0 == strcmp(p, "hppa"))
- return(ARCH_hppa);
- else if (0 == strcmp(p, "hppa64"))
- return(ARCH_hppa64);
- else if (0 == strcmp(p, "i386"))
- return(ARCH_i386);
- else if (0 == strcmp(p, "landisk"))
- return(ARCH_landisk);
- else if (0 == strcmp(p, "luna88k"))
- return(ARCH_luna88k);
- else if (0 == strcmp(p, "mac68k"))
- return(ARCH_mac68k);
- else if (0 == strcmp(p, "macppc"))
- return(ARCH_macppc);
- else if (0 == strcmp(p, "mvme68k"))
- return(ARCH_mvme68k);
- else if (0 == strcmp(p, "mvme88k"))
- return(ARCH_mvme88k);
- else if (0 == strcmp(p, "mvmeppc"))
- return(ARCH_mvmeppc);
- else if (0 == strcmp(p, "pmax"))
- return(ARCH_pmax);
- else if (0 == strcmp(p, "sgi"))
- return(ARCH_sgi);
- else if (0 == strcmp(p, "socppc"))
- return(ARCH_socppc);
- else if (0 == strcmp(p, "sparc"))
- return(ARCH_sparc);
- else if (0 == strcmp(p, "sparc64"))
- return(ARCH_sparc64);
- else if (0 == strcmp(p, "sun3"))
- return(ARCH_sun3);
- else if (0 == strcmp(p, "vax"))
- return(ARCH_vax);
- else if (0 == strcmp(p, "zaurus"))
- return(ARCH_zaurus);
-
- return(ARCH_DEFAULT);
+ switch (macro) {
+ case(MDOC_Ad):
+ return(12);
+ case(MDOC_Ao):
+ return(12);
+ case(MDOC_An):
+ return(12);
+ case(MDOC_Aq):
+ return(12);
+ case(MDOC_Ar):
+ return(12);
+ case(MDOC_Bo):
+ return(12);
+ case(MDOC_Bq):
+ return(12);
+ case(MDOC_Cd):
+ return(12);
+ case(MDOC_Cm):
+ return(10);
+ case(MDOC_Do):
+ return(10);
+ case(MDOC_Dq):
+ return(12);
+ case(MDOC_Dv):
+ return(12);
+ case(MDOC_Eo):
+ return(12);
+ case(MDOC_Em):
+ return(10);
+ case(MDOC_Er):
+ return(12);
+ case(MDOC_Ev):
+ return(15);
+ case(MDOC_Fa):
+ return(12);
+ case(MDOC_Fl):
+ return(10);
+ case(MDOC_Fo):
+ return(16);
+ case(MDOC_Fn):
+ return(16);
+ case(MDOC_Ic):
+ return(10);
+ case(MDOC_Li):
+ return(16);
+ case(MDOC_Ms):
+ return(6);
+ case(MDOC_Nm):
+ return(10);
+ case(MDOC_No):
+ return(12);
+ case(MDOC_Oo):
+ return(10);
+ case(MDOC_Op):
+ return(14);
+ case(MDOC_Pa):
+ return(32);
+ case(MDOC_Pf):
+ return(12);
+ case(MDOC_Po):
+ return(12);
+ case(MDOC_Pq):
+ return(12);
+ case(MDOC_Ql):
+ return(16);
+ case(MDOC_Qo):
+ return(12);
+ case(MDOC_So):
+ return(12);
+ case(MDOC_Sq):
+ return(12);
+ case(MDOC_Sy):
+ return(6);
+ case(MDOC_Sx):
+ return(16);
+ case(MDOC_Tn):
+ return(10);
+ case(MDOC_Va):
+ return(12);
+ case(MDOC_Vt):
+ return(12);
+ case(MDOC_Xr):
+ return(10);
+ default:
+ break;
+ };
+ return(0);
}