Annotation of mandoc/mdoc_strings.c, Revision 1.1
1.1 ! kristaps 1: /* $Id: strings.c,v 1.33 2009/03/27 13:44:24 kristaps Exp $ */
! 2: /*
! 3: * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
! 4: *
! 5: * Permission to use, copy, modify, and distribute this software for any
! 6: * purpose with or without fee is hereby granted, provided that the
! 7: * above copyright notice and this permission notice appear in all
! 8: * copies.
! 9: *
! 10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
! 11: * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
! 12: * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
! 13: * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
! 14: * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
! 15: * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
! 16: * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
! 17: * PERFORMANCE OF THIS SOFTWARE.
! 18: */
! 19: #include <sys/types.h>
! 20:
! 21: #include <assert.h>
! 22: #include <ctype.h>
! 23: #include <stdlib.h>
! 24: #include <stdio.h>
! 25: #include <string.h>
! 26:
! 27: #include "libmdoc.h"
! 28:
! 29: /*
! 30: * Various string-literal operations: converting scalars to and from
! 31: * strings, etc.
! 32: */
! 33:
! 34: struct mdoc_secname {
! 35: const char *name;
! 36: int flag;
! 37: #define MSECNAME_META (1 << 0)
! 38: };
! 39:
! 40: /* Section names corresponding to mdoc_sec. */
! 41:
! 42: static const struct mdoc_secname secnames[] = {
! 43: { "PROLOGUE", MSECNAME_META },
! 44: { "BODY", MSECNAME_META },
! 45: { "NAME", 0 },
! 46: { "LIBRARY", 0 },
! 47: { "SYNOPSIS", 0 },
! 48: { "DESCRIPTION", 0 },
! 49: { "IMPLEMENTATION NOTES", 0 },
! 50: { "RETURN VALUES", 0 },
! 51: { "ENVIRONMENT", 0 },
! 52: { "FILES", 0 },
! 53: { "EXAMPLES", 0 },
! 54: { "DIAGNOSTICS", 0 },
! 55: { "COMPATIBILITY", 0 },
! 56: { "ERRORS", 0 },
! 57: { "SEE ALSO", 0 },
! 58: { "STANDARDS", 0 },
! 59: { "HISTORY", 0 },
! 60: { "AUTHORS", 0 },
! 61: { "CAVEATS", 0 },
! 62: { "BUGS", 0 },
! 63: { NULL, 0 }
! 64: };
! 65:
! 66: #ifdef __linux__
! 67: extern char *strptime(const char *, const char *, struct tm *);
! 68: #endif
! 69:
! 70:
! 71: size_t
! 72: mdoc_isescape(const char *p)
! 73: {
! 74: size_t c;
! 75:
! 76: if ('\\' != *p++)
! 77: return(0);
! 78:
! 79: switch (*p) {
! 80: case ('\\'):
! 81: /* FALLTHROUGH */
! 82: case ('\''):
! 83: /* FALLTHROUGH */
! 84: case ('`'):
! 85: /* FALLTHROUGH */
! 86: case ('q'):
! 87: /* FALLTHROUGH */
! 88: case ('-'):
! 89: /* FALLTHROUGH */
! 90: case ('%'):
! 91: /* FALLTHROUGH */
! 92: case ('0'):
! 93: /* FALLTHROUGH */
! 94: case (' '):
! 95: /* FALLTHROUGH */
! 96: case ('|'):
! 97: /* FALLTHROUGH */
! 98: case ('&'):
! 99: /* FALLTHROUGH */
! 100: case ('.'):
! 101: /* FALLTHROUGH */
! 102: case (':'):
! 103: /* FALLTHROUGH */
! 104: case ('e'):
! 105: return(2);
! 106: case ('*'):
! 107: if (0 == *++p || ! isgraph((u_char)*p))
! 108: return(0);
! 109: switch (*p) {
! 110: case ('('):
! 111: if (0 == *++p || ! isgraph((u_char)*p))
! 112: return(0);
! 113: return(4);
! 114: case ('['):
! 115: for (c = 3, p++; *p && ']' != *p; p++, c++)
! 116: if ( ! isgraph((u_char)*p))
! 117: break;
! 118: return(*p == ']' ? c : 0);
! 119: default:
! 120: break;
! 121: }
! 122: return(3);
! 123: case ('('):
! 124: if (0 == *++p || ! isgraph((u_char)*p))
! 125: return(0);
! 126: if (0 == *++p || ! isgraph((u_char)*p))
! 127: return(0);
! 128: return(4);
! 129: case ('['):
! 130: break;
! 131: default:
! 132: return(0);
! 133: }
! 134:
! 135: for (c = 3, p++; *p && ']' != *p; p++, c++)
! 136: if ( ! isgraph((u_char)*p))
! 137: break;
! 138:
! 139: return(*p == ']' ? c : 0);
! 140: }
! 141:
! 142:
! 143: int
! 144: mdoc_iscdelim(char p)
! 145: {
! 146:
! 147: switch (p) {
! 148: case('.'):
! 149: /* FALLTHROUGH */
! 150: case(','):
! 151: /* FALLTHROUGH */
! 152: case(';'):
! 153: /* FALLTHROUGH */
! 154: case(':'):
! 155: /* FALLTHROUGH */
! 156: case('?'):
! 157: /* FALLTHROUGH */
! 158: case('!'):
! 159: /* FALLTHROUGH */
! 160: case('('):
! 161: /* FALLTHROUGH */
! 162: case(')'):
! 163: /* FALLTHROUGH */
! 164: case('['):
! 165: /* FALLTHROUGH */
! 166: case(']'):
! 167: /* FALLTHROUGH */
! 168: case('{'):
! 169: /* FALLTHROUGH */
! 170: case('}'):
! 171: return(1);
! 172: default:
! 173: break;
! 174: }
! 175:
! 176: return(0);
! 177: }
! 178:
! 179:
! 180: int
! 181: mdoc_isdelim(const char *p)
! 182: {
! 183:
! 184: if (0 == *p)
! 185: return(0);
! 186: if (0 != *(p + 1))
! 187: return(0);
! 188: return(mdoc_iscdelim(*p));
! 189: }
! 190:
! 191:
! 192: enum mdoc_sec
! 193: mdoc_atosec(const char *p)
! 194: {
! 195: const struct mdoc_secname *n;
! 196: int i;
! 197:
! 198: for (i = 0, n = secnames; n->name; n++, i++)
! 199: if ( ! (n->flag & MSECNAME_META))
! 200: if (0 == strcmp(p, n->name))
! 201: return((enum mdoc_sec)i);
! 202:
! 203: return(SEC_CUSTOM);
! 204: }
! 205:
! 206:
! 207: time_t
! 208: mdoc_atotime(const char *p)
! 209: {
! 210: struct tm tm;
! 211: char *pp;
! 212:
! 213: (void)memset(&tm, 0, sizeof(struct tm));
! 214:
! 215: if (0 == strcmp(p, "$Mdocdate$"))
! 216: return(time(NULL));
! 217: if ((pp = strptime(p, "$Mdocdate: %b %d %Y $", &tm)) && 0 == *pp)
! 218: return(mktime(&tm));
! 219: /* XXX - this matches "June 1999", which is wrong. */
! 220: if ((pp = strptime(p, "%b %d %Y", &tm)) && 0 == *pp)
! 221: return(mktime(&tm));
! 222: if ((pp = strptime(p, "%b %d, %Y", &tm)) && 0 == *pp)
! 223: return(mktime(&tm));
! 224:
! 225: return(0);
! 226: }
! 227:
! 228:
! 229: size_t
! 230: mdoc_macro2len(int macro)
! 231: {
! 232:
! 233: switch (macro) {
! 234: case(MDOC_Ad):
! 235: return(12);
! 236: case(MDOC_Ao):
! 237: return(12);
! 238: case(MDOC_An):
! 239: return(12);
! 240: case(MDOC_Aq):
! 241: return(12);
! 242: case(MDOC_Ar):
! 243: return(12);
! 244: case(MDOC_Bo):
! 245: return(12);
! 246: case(MDOC_Bq):
! 247: return(12);
! 248: case(MDOC_Cd):
! 249: return(12);
! 250: case(MDOC_Cm):
! 251: return(10);
! 252: case(MDOC_Do):
! 253: return(10);
! 254: case(MDOC_Dq):
! 255: return(12);
! 256: case(MDOC_Dv):
! 257: return(12);
! 258: case(MDOC_Eo):
! 259: return(12);
! 260: case(MDOC_Em):
! 261: return(10);
! 262: case(MDOC_Er):
! 263: return(12);
! 264: case(MDOC_Ev):
! 265: return(15);
! 266: case(MDOC_Fa):
! 267: return(12);
! 268: case(MDOC_Fl):
! 269: return(10);
! 270: case(MDOC_Fo):
! 271: return(16);
! 272: case(MDOC_Fn):
! 273: return(16);
! 274: case(MDOC_Ic):
! 275: return(10);
! 276: case(MDOC_Li):
! 277: return(16);
! 278: case(MDOC_Ms):
! 279: return(6);
! 280: case(MDOC_Nm):
! 281: return(10);
! 282: case(MDOC_No):
! 283: return(12);
! 284: case(MDOC_Oo):
! 285: return(10);
! 286: case(MDOC_Op):
! 287: return(14);
! 288: case(MDOC_Pa):
! 289: return(32);
! 290: case(MDOC_Pf):
! 291: return(12);
! 292: case(MDOC_Po):
! 293: return(12);
! 294: case(MDOC_Pq):
! 295: return(12);
! 296: case(MDOC_Ql):
! 297: return(16);
! 298: case(MDOC_Qo):
! 299: return(12);
! 300: case(MDOC_So):
! 301: return(12);
! 302: case(MDOC_Sq):
! 303: return(12);
! 304: case(MDOC_Sy):
! 305: return(6);
! 306: case(MDOC_Sx):
! 307: return(16);
! 308: case(MDOC_Tn):
! 309: return(10);
! 310: case(MDOC_Va):
! 311: return(12);
! 312: case(MDOC_Vt):
! 313: return(12);
! 314: case(MDOC_Xr):
! 315: return(10);
! 316: default:
! 317: break;
! 318: };
! 319: return(0);
! 320: }
CVSweb