Annotation of mandoc/strings.c, Revision 1.16
1.16 ! kristaps 1: /* $Id: strings.c,v 1.15 2009/02/23 15:34:53 kristaps Exp $ */
1.1 kristaps 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 <assert.h>
20: #include <ctype.h>
21: #include <stdlib.h>
22: #include <stdio.h>
1.2 kristaps 23: #include <string.h>
1.15 kristaps 24: #ifndef __OpenBSD__
1.4 kristaps 25: #include <time.h>
26: #endif
1.1 kristaps 27:
1.14 kristaps 28: /*
29: * Convert scalars to and from string format.
30: */
31:
1.1 kristaps 32: #include "private.h"
33:
1.4 kristaps 34: #ifdef __linux__
35: extern char *strptime(const char *, const char *, struct tm *);
36: #endif
37:
1.16 ! kristaps 38:
! 39: size_t
! 40: mdoc_isescape(const char *p)
! 41: {
! 42: size_t c;
! 43:
! 44: if ('\\' != *p++)
! 45: return(0);
! 46:
! 47: switch (*p) {
! 48: case ('\\'):
! 49: /* FALLTHROUGH */
! 50: case ('\''):
! 51: /* FALLTHROUGH */
! 52: case ('`'):
! 53: /* FALLTHROUGH */
! 54: case ('-'):
! 55: /* FALLTHROUGH */
! 56: case (' '):
! 57: /* FALLTHROUGH */
! 58: case ('.'):
! 59: /* FALLTHROUGH */
! 60: case ('e'):
! 61: return(2);
! 62: case ('('):
! 63: if (0 == *++p)
! 64: return(0);
! 65: if (0 == *++p)
! 66: return(0);
! 67: return(4);
! 68: case ('['):
! 69: break;
! 70: default:
! 71: return(0);
! 72: }
! 73:
! 74: for (c = 3, p++; *p && ']' != *p; p++, c++)
! 75: if (isspace(*p))
! 76: break;
! 77:
! 78: return(*p == ']' ? c : 0);
! 79: }
! 80:
! 81:
1.1 kristaps 82: int
1.3 kristaps 83: mdoc_iscdelim(char p)
1.1 kristaps 84: {
85:
1.3 kristaps 86: switch (p) {
1.1 kristaps 87: case('.'):
88: /* FALLTHROUGH */
89: case(','):
90: /* FALLTHROUGH */
91: case(';'):
92: /* FALLTHROUGH */
93: case(':'):
94: /* FALLTHROUGH */
95: case('?'):
96: /* FALLTHROUGH */
97: case('!'):
98: /* FALLTHROUGH */
99: case('('):
100: /* FALLTHROUGH */
101: case(')'):
102: /* FALLTHROUGH */
103: case('['):
104: /* FALLTHROUGH */
105: case(']'):
106: /* FALLTHROUGH */
1.7 kristaps 107: case('{'):
108: /* FALLTHROUGH */
1.1 kristaps 109: case('}'):
110: return(1);
111: default:
112: break;
113: }
114:
115: return(0);
116: }
117:
1.2 kristaps 118:
1.3 kristaps 119: int
120: mdoc_isdelim(const char *p)
121: {
122:
123: if (0 == *p)
124: return(0);
125: if (0 != *(p + 1))
126: return(0);
127: return(mdoc_iscdelim(*p));
128: }
129:
130:
1.2 kristaps 131: enum mdoc_sec
1.9 kristaps 132: mdoc_atosec(const char *p)
1.2 kristaps 133: {
134:
1.9 kristaps 135: assert(p);
136: if (0 == strcmp(p, "NAME"))
1.2 kristaps 137: return(SEC_NAME);
1.9 kristaps 138: else if (0 == strcmp(p, "RETURN VALUES"))
139: return(SEC_RETURN_VALUES);
140: else if (0 == strcmp(p, "SEE ALSO"))
141: return(SEC_SEE_ALSO);
142: else if (0 == strcmp(p, "SYNOPSIS"))
1.2 kristaps 143: return(SEC_SYNOPSIS);
1.9 kristaps 144: else if (0 == strcmp(p, "DESCRIPTION"))
1.2 kristaps 145: return(SEC_DESCRIPTION);
1.9 kristaps 146: else if (0 == strcmp(p, "ENVIRONMENT"))
1.2 kristaps 147: return(SEC_ENVIRONMENT);
1.9 kristaps 148: else if (0 == strcmp(p, "FILES"))
1.2 kristaps 149: return(SEC_FILES);
1.9 kristaps 150: else if (0 == strcmp(p, "EXAMPLES"))
1.2 kristaps 151: return(SEC_EXAMPLES);
1.9 kristaps 152: else if (0 == strcmp(p, "DIAGNOSTICS"))
1.2 kristaps 153: return(SEC_DIAGNOSTICS);
1.9 kristaps 154: else if (0 == strcmp(p, "ERRORS"))
1.2 kristaps 155: return(SEC_ERRORS);
1.9 kristaps 156: else if (0 == strcmp(p, "STANDARDS"))
1.2 kristaps 157: return(SEC_STANDARDS);
1.9 kristaps 158: else if (0 == strcmp(p, "HISTORY"))
1.2 kristaps 159: return(SEC_HISTORY);
1.9 kristaps 160: else if (0 == strcmp(p, "AUTHORS"))
1.2 kristaps 161: return(SEC_AUTHORS);
1.9 kristaps 162: else if (0 == strcmp(p, "CAVEATS"))
1.2 kristaps 163: return(SEC_CAVEATS);
1.9 kristaps 164: else if (0 == strcmp(p, "BUGS"))
1.2 kristaps 165: return(SEC_BUGS);
166:
167: return(SEC_CUSTOM);
168: }
169:
170:
171: time_t
172: mdoc_atotime(const char *p)
173: {
174: struct tm tm;
1.11 kristaps 175: char *pp;
1.2 kristaps 176:
1.5 kristaps 177: (void)memset(&tm, 0, sizeof(struct tm));
178:
1.11 kristaps 179: if (xstrcmp(p, "$Mdocdate$"))
180: return(time(NULL));
181: if ((pp = strptime(p, "$Mdocdate: %b %d %Y $", &tm)) && 0 == *pp)
1.2 kristaps 182: return(mktime(&tm));
1.11 kristaps 183: /* XXX - this matches "June 1999", which is wrong. */
184: if ((pp = strptime(p, "%b %d %Y", &tm)) && 0 == *pp)
185: return(mktime(&tm));
186: if ((pp = strptime(p, "%b %d, %Y", &tm)) && 0 == *pp)
1.2 kristaps 187: return(mktime(&tm));
188:
189: return(0);
190: }
191:
192:
193: enum mdoc_msec
194: mdoc_atomsec(const char *p)
195: {
196:
197: if (0 == strcmp(p, "1"))
198: return(MSEC_1);
199: else if (0 == strcmp(p, "2"))
200: return(MSEC_2);
201: else if (0 == strcmp(p, "3"))
202: return(MSEC_3);
203: else if (0 == strcmp(p, "3f"))
204: return(MSEC_3f);
205: else if (0 == strcmp(p, "3p"))
206: return(MSEC_3p);
207: else if (0 == strcmp(p, "4"))
208: return(MSEC_4);
209: else if (0 == strcmp(p, "5"))
210: return(MSEC_5);
211: else if (0 == strcmp(p, "6"))
212: return(MSEC_6);
213: else if (0 == strcmp(p, "7"))
214: return(MSEC_7);
215: else if (0 == strcmp(p, "8"))
216: return(MSEC_8);
217: else if (0 == strcmp(p, "9"))
218: return(MSEC_9);
219: else if (0 == strcmp(p, "X11"))
220: return(MSEC_X11);
221: else if (0 == strcmp(p, "X11R6"))
222: return(MSEC_X11R6);
223: else if (0 == strcmp(p, "local"))
224: return(MSEC_local);
225: else if (0 == strcmp(p, "n"))
226: return(MSEC_n);
227: else if (0 == strcmp(p, "unass"))
228: return(MSEC_unass);
229: else if (0 == strcmp(p, "draft"))
230: return(MSEC_draft);
231: else if (0 == strcmp(p, "paper"))
232: return(MSEC_paper);
233:
234: return(MSEC_DEFAULT);
235: }
236:
237:
238: enum mdoc_vol
239: mdoc_atovol(const char *p)
240: {
241:
242: if (0 == strcmp(p, "AMD"))
243: return(VOL_AMD);
244: else if (0 == strcmp(p, "IND"))
245: return(VOL_IND);
246: else if (0 == strcmp(p, "KM"))
247: return(VOL_KM);
248: else if (0 == strcmp(p, "LOCAL"))
249: return(VOL_LOCAL);
250: else if (0 == strcmp(p, "PRM"))
251: return(VOL_PRM);
252: else if (0 == strcmp(p, "PS1"))
253: return(VOL_PS1);
254: else if (0 == strcmp(p, "SMM"))
255: return(VOL_SMM);
256: else if (0 == strcmp(p, "URM"))
257: return(VOL_URM);
258: else if (0 == strcmp(p, "USD"))
259: return(VOL_USD);
260:
261: return(VOL_DEFAULT);
262: }
263:
264:
265: enum mdoc_arch
266: mdoc_atoarch(const char *p)
267: {
268:
269: if (0 == strcmp(p, "alpha"))
270: return(ARCH_alpha);
271: else if (0 == strcmp(p, "amd64"))
272: return(ARCH_amd64);
273: else if (0 == strcmp(p, "amiga"))
274: return(ARCH_amiga);
275: else if (0 == strcmp(p, "arc"))
276: return(ARCH_arc);
1.8 kristaps 277: else if (0 == strcmp(p, "arm"))
278: return(ARCH_arm);
1.2 kristaps 279: else if (0 == strcmp(p, "armish"))
280: return(ARCH_armish);
281: else if (0 == strcmp(p, "aviion"))
282: return(ARCH_aviion);
283: else if (0 == strcmp(p, "hp300"))
284: return(ARCH_hp300);
285: else if (0 == strcmp(p, "hppa"))
286: return(ARCH_hppa);
287: else if (0 == strcmp(p, "hppa64"))
288: return(ARCH_hppa64);
289: else if (0 == strcmp(p, "i386"))
290: return(ARCH_i386);
291: else if (0 == strcmp(p, "landisk"))
292: return(ARCH_landisk);
293: else if (0 == strcmp(p, "luna88k"))
294: return(ARCH_luna88k);
295: else if (0 == strcmp(p, "mac68k"))
296: return(ARCH_mac68k);
297: else if (0 == strcmp(p, "macppc"))
298: return(ARCH_macppc);
299: else if (0 == strcmp(p, "mvme68k"))
300: return(ARCH_mvme68k);
301: else if (0 == strcmp(p, "mvme88k"))
302: return(ARCH_mvme88k);
303: else if (0 == strcmp(p, "mvmeppc"))
304: return(ARCH_mvmeppc);
305: else if (0 == strcmp(p, "pmax"))
306: return(ARCH_pmax);
307: else if (0 == strcmp(p, "sgi"))
308: return(ARCH_sgi);
309: else if (0 == strcmp(p, "socppc"))
310: return(ARCH_socppc);
311: else if (0 == strcmp(p, "sparc"))
312: return(ARCH_sparc);
313: else if (0 == strcmp(p, "sparc64"))
314: return(ARCH_sparc64);
315: else if (0 == strcmp(p, "sun3"))
316: return(ARCH_sun3);
317: else if (0 == strcmp(p, "vax"))
318: return(ARCH_vax);
319: else if (0 == strcmp(p, "zaurus"))
320: return(ARCH_zaurus);
321:
322: return(ARCH_DEFAULT);
323: }
1.4 kristaps 324:
325:
326: enum mdoc_att
327: mdoc_atoatt(const char *p)
328: {
329:
330: assert(p);
331: if (0 == strcmp(p, "v1"))
332: return(ATT_v1);
333: else if (0 == strcmp(p, "v2"))
334: return(ATT_v2);
335: else if (0 == strcmp(p, "v3"))
336: return(ATT_v3);
337: else if (0 == strcmp(p, "v4"))
338: return(ATT_v4);
339: else if (0 == strcmp(p, "v5"))
340: return(ATT_v5);
341: else if (0 == strcmp(p, "v6"))
342: return(ATT_v6);
343: else if (0 == strcmp(p, "v7"))
344: return(ATT_v7);
345: else if (0 == strcmp(p, "32v"))
346: return(ATT_32v);
347: else if (0 == strcmp(p, "V.1"))
348: return(ATT_V1);
349: else if (0 == strcmp(p, "V.2"))
350: return(ATT_V2);
351: else if (0 == strcmp(p, "V.3"))
352: return(ATT_V3);
353: else if (0 == strcmp(p, "V.4"))
354: return(ATT_V4);
355:
356: return(ATT_DEFAULT);
357: }
1.6 kristaps 358:
359:
360: char *
361: mdoc_type2a(enum mdoc_type type)
362: {
363: switch (type) {
364: case (MDOC_ROOT):
365: return("root");
366: case (MDOC_BLOCK):
367: return("block");
368: case (MDOC_HEAD):
369: return("block-head");
370: case (MDOC_BODY):
371: return("block-body");
372: case (MDOC_TAIL):
373: return("block-tail");
374: case (MDOC_ELEM):
375: return("elem");
376: case (MDOC_TEXT):
377: return("text");
378: default:
379: break;
380: }
381:
382: abort();
383: /* NOTREACHED */
384: }
1.12 kristaps 385:
386:
1.13 kristaps 387: const char *
1.12 kristaps 388: mdoc_arch2a(enum mdoc_arch arch)
389: {
390:
391: switch (arch) {
392: case (ARCH_alpha):
393: return("Alpha");
394: case (ARCH_amd64):
395: return("AMD64");
396: case (ARCH_amiga):
397: return("Amiga");
398: case (ARCH_arc):
399: return("ARC");
400: case (ARCH_arm):
401: return("ARM");
402: case (ARCH_armish):
403: return("ARMISH");
404: case (ARCH_aviion):
405: return("AViion");
406: case (ARCH_hp300):
407: return("HP300");
408: case (ARCH_hppa):
409: return("HPPA");
410: case (ARCH_hppa64):
411: return("HPPA64");
412: case (ARCH_i386):
413: return("i386");
414: case (ARCH_landisk):
415: return("LANDISK");
416: case (ARCH_luna88k):
417: return("Luna88k");
418: case (ARCH_mac68k):
419: return("Mac68k");
420: case (ARCH_macppc):
421: return("MacPPC");
422: case (ARCH_mvme68k):
423: return("MVME68k");
424: case (ARCH_mvme88k):
425: return("MVME88k");
426: case (ARCH_mvmeppc):
427: return("MVMEPPC");
428: case (ARCH_pmax):
429: return("PMAX");
430: case (ARCH_sgi):
431: return("SGI");
432: case (ARCH_socppc):
433: return("SOCPPC");
434: case (ARCH_sparc):
435: return("SPARC");
436: case (ARCH_sparc64):
437: return("SPARC64");
438: case (ARCH_sun3):
439: return("Sun3");
440: case (ARCH_vax):
441: return("VAX");
442: case (ARCH_zaurus):
443: return("Zaurus");
444: case (ARCH_DEFAULT):
445: return(NULL);
446: default:
447: break;
448: }
449:
450: abort();
451: /* NOTREACHED */
452: }
453:
454:
1.13 kristaps 455: const char *
1.12 kristaps 456: mdoc_vol2a(enum mdoc_vol vol)
457: {
458:
459: switch (vol) {
460: case (VOL_AMD):
461: return("OpenBSD Ancestral Manual Documents");
462: case (VOL_IND):
463: return("OpenBSD Manual Master Index");
464: case (VOL_KM):
465: return("OpenBSD Kernel Manual");
466: case (VOL_LOCAL):
467: return("OpenBSD Local Manual");
468: case (VOL_PRM):
469: return("OpenBSD Programmer's Manual");
470: case (VOL_PS1):
471: return("OpenBSD Programmer's Supplementary Documents");
472: case (VOL_SMM):
473: return("OpenBSD System Manager's Manual");
474: case (VOL_URM):
475: return("OpenBSD Reference Manual");
476: case (VOL_USD):
477: return("OpenBSD User's Supplementary Documents");
478: case (VOL_DEFAULT):
479: return(NULL);
480: default:
481: break;
482: }
483:
484: abort();
485: /* NOTREACHED */
486: }
487:
488:
1.13 kristaps 489: const char *
1.12 kristaps 490: mdoc_msec2a(enum mdoc_msec msec)
491: {
492:
493: switch (msec) {
494: case(MSEC_1):
495: return("1");
496: case(MSEC_2):
497: return("2");
498: case(MSEC_3):
499: return("3");
500: case(MSEC_3f):
501: return("3f");
502: case(MSEC_3p):
503: return("3p");
504: case(MSEC_4):
505: return("4");
506: case(MSEC_5):
507: return("5");
508: case(MSEC_6):
509: return("6");
510: case(MSEC_7):
511: return("7");
512: case(MSEC_8):
513: return("8");
514: case(MSEC_9):
515: return("9");
516: case(MSEC_X11):
517: return("X11");
518: case(MSEC_X11R6):
519: return("X11R6");
520: case(MSEC_local):
521: return("local");
522: case(MSEC_n):
523: return("n");
524: case(MSEC_unass):
525: /* FALLTHROUGH */
526: case(MSEC_draft):
527: return("draft");
528: case(MSEC_paper):
529: return("paper");
530: case(MSEC_DEFAULT):
531: return(NULL);
532: default:
533: break;
534: }
535:
536: abort();
537: /* NOTREACHED */
538: }
539:
CVSweb