]> git.cameronkatri.com Git - mandoc.git/blob - strings.c
NetBSD Lintified.
[mandoc.git] / strings.c
1 /* $Id: strings.c,v 1.19 2009/02/25 12:32:50 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 <assert.h>
20 #include <ctype.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #ifndef __OpenBSD__
25 #include <time.h>
26 #endif
27
28 /*
29 * Convert scalars to and from string format.
30 */
31
32 #include "private.h"
33
34 #ifdef __linux__
35 extern char *strptime(const char *, const char *, struct tm *);
36 #endif
37
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 ('.'):
61 /* FALLTHROUGH */
62 case ('e'):
63 return(2);
64 case ('('):
65 if (0 == *++p || ! isgraph((int)*p))
66 return(0);
67 if (0 == *++p || ! isgraph((int)*p))
68 return(0);
69 return(4);
70 case ('['):
71 break;
72 default:
73 return(0);
74 }
75
76 for (c = 3, p++; *p && ']' != *p; p++, c++)
77 if ( ! isgraph((int)*p))
78 break;
79
80 return(*p == ']' ? c : 0);
81 }
82
83
84 int
85 mdoc_iscdelim(char p)
86 {
87
88 switch (p) {
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 */
107 case(']'):
108 /* FALLTHROUGH */
109 case('{'):
110 /* FALLTHROUGH */
111 case('}'):
112 return(1);
113 default:
114 break;
115 }
116
117 return(0);
118 }
119
120
121 int
122 mdoc_isdelim(const char *p)
123 {
124
125 if (0 == *p)
126 return(0);
127 if (0 != *(p + 1))
128 return(0);
129 return(mdoc_iscdelim(*p));
130 }
131
132
133 enum mdoc_sec
134 mdoc_atosec(const char *p)
135 {
136
137 assert(p);
138 if (0 == strcmp(p, "NAME"))
139 return(SEC_NAME);
140 else if (0 == strcmp(p, "RETURN VALUES"))
141 return(SEC_RETURN_VALUES);
142 else if (0 == strcmp(p, "SEE ALSO"))
143 return(SEC_SEE_ALSO);
144 else if (0 == strcmp(p, "SYNOPSIS"))
145 return(SEC_SYNOPSIS);
146 else if (0 == strcmp(p, "DESCRIPTION"))
147 return(SEC_DESCRIPTION);
148 else if (0 == strcmp(p, "ENVIRONMENT"))
149 return(SEC_ENVIRONMENT);
150 else if (0 == strcmp(p, "FILES"))
151 return(SEC_FILES);
152 else if (0 == strcmp(p, "EXAMPLES"))
153 return(SEC_EXAMPLES);
154 else if (0 == strcmp(p, "DIAGNOSTICS"))
155 return(SEC_DIAGNOSTICS);
156 else if (0 == strcmp(p, "ERRORS"))
157 return(SEC_ERRORS);
158 else if (0 == strcmp(p, "STANDARDS"))
159 return(SEC_STANDARDS);
160 else if (0 == strcmp(p, "HISTORY"))
161 return(SEC_HISTORY);
162 else if (0 == strcmp(p, "AUTHORS"))
163 return(SEC_AUTHORS);
164 else if (0 == strcmp(p, "CAVEATS"))
165 return(SEC_CAVEATS);
166 else if (0 == strcmp(p, "BUGS"))
167 return(SEC_BUGS);
168
169 return(SEC_CUSTOM);
170 }
171
172
173 time_t
174 mdoc_atotime(const char *p)
175 {
176 struct tm tm;
177 char *pp;
178
179 (void)memset(&tm, 0, sizeof(struct tm));
180
181 if (xstrcmp(p, "$Mdocdate: February 25 2009 $"))
182 return(time(NULL));
183 if ((pp = strptime(p, "$Mdocdate: February 25 2009 $", &tm)) && 0 == *pp)
184 return(mktime(&tm));
185 /* XXX - this matches "June 1999", which is wrong. */
186 if ((pp = strptime(p, "%b %d %Y", &tm)) && 0 == *pp)
187 return(mktime(&tm));
188 if ((pp = strptime(p, "%b %d, %Y", &tm)) && 0 == *pp)
189 return(mktime(&tm));
190
191 return(0);
192 }
193
194
195 enum mdoc_msec
196 mdoc_atomsec(const char *p)
197 {
198
199 if (0 == strcmp(p, "1"))
200 return(MSEC_1);
201 else if (0 == strcmp(p, "2"))
202 return(MSEC_2);
203 else if (0 == strcmp(p, "3"))
204 return(MSEC_3);
205 else if (0 == strcmp(p, "3f"))
206 return(MSEC_3f);
207 else if (0 == strcmp(p, "3p"))
208 return(MSEC_3p);
209 else if (0 == strcmp(p, "4"))
210 return(MSEC_4);
211 else if (0 == strcmp(p, "5"))
212 return(MSEC_5);
213 else if (0 == strcmp(p, "6"))
214 return(MSEC_6);
215 else if (0 == strcmp(p, "7"))
216 return(MSEC_7);
217 else if (0 == strcmp(p, "8"))
218 return(MSEC_8);
219 else if (0 == strcmp(p, "9"))
220 return(MSEC_9);
221 else if (0 == strcmp(p, "X11"))
222 return(MSEC_X11);
223 else if (0 == strcmp(p, "X11R6"))
224 return(MSEC_X11R6);
225 else if (0 == strcmp(p, "local"))
226 return(MSEC_local);
227 else if (0 == strcmp(p, "n"))
228 return(MSEC_n);
229 else if (0 == strcmp(p, "unass"))
230 return(MSEC_unass);
231 else if (0 == strcmp(p, "draft"))
232 return(MSEC_draft);
233 else if (0 == strcmp(p, "paper"))
234 return(MSEC_paper);
235
236 return(MSEC_DEFAULT);
237 }
238
239
240 enum mdoc_vol
241 mdoc_atovol(const char *p)
242 {
243
244 if (0 == strcmp(p, "AMD"))
245 return(VOL_AMD);
246 else if (0 == strcmp(p, "IND"))
247 return(VOL_IND);
248 else if (0 == strcmp(p, "KM"))
249 return(VOL_KM);
250 else if (0 == strcmp(p, "LOCAL"))
251 return(VOL_LOCAL);
252 else if (0 == strcmp(p, "PRM"))
253 return(VOL_PRM);
254 else if (0 == strcmp(p, "PS1"))
255 return(VOL_PS1);
256 else if (0 == strcmp(p, "SMM"))
257 return(VOL_SMM);
258 else if (0 == strcmp(p, "URM"))
259 return(VOL_URM);
260 else if (0 == strcmp(p, "USD"))
261 return(VOL_USD);
262
263 return(VOL_DEFAULT);
264 }
265
266
267 enum mdoc_arch
268 mdoc_atoarch(const char *p)
269 {
270
271 if (0 == strcmp(p, "alpha"))
272 return(ARCH_alpha);
273 else if (0 == strcmp(p, "amd64"))
274 return(ARCH_amd64);
275 else if (0 == strcmp(p, "amiga"))
276 return(ARCH_amiga);
277 else if (0 == strcmp(p, "arc"))
278 return(ARCH_arc);
279 else if (0 == strcmp(p, "arm"))
280 return(ARCH_arm);
281 else if (0 == strcmp(p, "armish"))
282 return(ARCH_armish);
283 else if (0 == strcmp(p, "aviion"))
284 return(ARCH_aviion);
285 else if (0 == strcmp(p, "hp300"))
286 return(ARCH_hp300);
287 else if (0 == strcmp(p, "hppa"))
288 return(ARCH_hppa);
289 else if (0 == strcmp(p, "hppa64"))
290 return(ARCH_hppa64);
291 else if (0 == strcmp(p, "i386"))
292 return(ARCH_i386);
293 else if (0 == strcmp(p, "landisk"))
294 return(ARCH_landisk);
295 else if (0 == strcmp(p, "luna88k"))
296 return(ARCH_luna88k);
297 else if (0 == strcmp(p, "mac68k"))
298 return(ARCH_mac68k);
299 else if (0 == strcmp(p, "macppc"))
300 return(ARCH_macppc);
301 else if (0 == strcmp(p, "mvme68k"))
302 return(ARCH_mvme68k);
303 else if (0 == strcmp(p, "mvme88k"))
304 return(ARCH_mvme88k);
305 else if (0 == strcmp(p, "mvmeppc"))
306 return(ARCH_mvmeppc);
307 else if (0 == strcmp(p, "pmax"))
308 return(ARCH_pmax);
309 else if (0 == strcmp(p, "sgi"))
310 return(ARCH_sgi);
311 else if (0 == strcmp(p, "socppc"))
312 return(ARCH_socppc);
313 else if (0 == strcmp(p, "sparc"))
314 return(ARCH_sparc);
315 else if (0 == strcmp(p, "sparc64"))
316 return(ARCH_sparc64);
317 else if (0 == strcmp(p, "sun3"))
318 return(ARCH_sun3);
319 else if (0 == strcmp(p, "vax"))
320 return(ARCH_vax);
321 else if (0 == strcmp(p, "zaurus"))
322 return(ARCH_zaurus);
323
324 return(ARCH_DEFAULT);
325 }
326
327
328 enum mdoc_att
329 mdoc_atoatt(const char *p)
330 {
331
332 assert(p);
333 if (0 == strcmp(p, "v1"))
334 return(ATT_v1);
335 else if (0 == strcmp(p, "v2"))
336 return(ATT_v2);
337 else if (0 == strcmp(p, "v3"))
338 return(ATT_v3);
339 else if (0 == strcmp(p, "v4"))
340 return(ATT_v4);
341 else if (0 == strcmp(p, "v5"))
342 return(ATT_v5);
343 else if (0 == strcmp(p, "v6"))
344 return(ATT_v6);
345 else if (0 == strcmp(p, "v7"))
346 return(ATT_v7);
347 else if (0 == strcmp(p, "32v"))
348 return(ATT_32v);
349 else if (0 == strcmp(p, "V.1"))
350 return(ATT_V1);
351 else if (0 == strcmp(p, "V.2"))
352 return(ATT_V2);
353 else if (0 == strcmp(p, "V.3"))
354 return(ATT_V3);
355 else if (0 == strcmp(p, "V.4"))
356 return(ATT_V4);
357
358 return(ATT_DEFAULT);
359 }
360
361
362 char *
363 mdoc_type2a(enum mdoc_type type)
364 {
365 switch (type) {
366 case (MDOC_ROOT):
367 return("root");
368 case (MDOC_BLOCK):
369 return("block");
370 case (MDOC_HEAD):
371 return("block-head");
372 case (MDOC_BODY):
373 return("block-body");
374 case (MDOC_TAIL):
375 return("block-tail");
376 case (MDOC_ELEM):
377 return("elem");
378 case (MDOC_TEXT):
379 return("text");
380 default:
381 break;
382 }
383
384 abort();
385 /* NOTREACHED */
386 }
387
388
389 const char *
390 mdoc_arch2a(enum mdoc_arch arch)
391 {
392
393 switch (arch) {
394 case (ARCH_alpha):
395 return("Alpha");
396 case (ARCH_amd64):
397 return("AMD64");
398 case (ARCH_amiga):
399 return("Amiga");
400 case (ARCH_arc):
401 return("ARC");
402 case (ARCH_arm):
403 return("ARM");
404 case (ARCH_armish):
405 return("ARMISH");
406 case (ARCH_aviion):
407 return("AViion");
408 case (ARCH_hp300):
409 return("HP300");
410 case (ARCH_hppa):
411 return("HPPA");
412 case (ARCH_hppa64):
413 return("HPPA64");
414 case (ARCH_i386):
415 return("i386");
416 case (ARCH_landisk):
417 return("LANDISK");
418 case (ARCH_luna88k):
419 return("Luna88k");
420 case (ARCH_mac68k):
421 return("Mac68k");
422 case (ARCH_macppc):
423 return("MacPPC");
424 case (ARCH_mvme68k):
425 return("MVME68k");
426 case (ARCH_mvme88k):
427 return("MVME88k");
428 case (ARCH_mvmeppc):
429 return("MVMEPPC");
430 case (ARCH_pmax):
431 return("PMAX");
432 case (ARCH_sgi):
433 return("SGI");
434 case (ARCH_socppc):
435 return("SOCPPC");
436 case (ARCH_sparc):
437 return("SPARC");
438 case (ARCH_sparc64):
439 return("SPARC64");
440 case (ARCH_sun3):
441 return("Sun3");
442 case (ARCH_vax):
443 return("VAX");
444 case (ARCH_zaurus):
445 return("Zaurus");
446 case (ARCH_DEFAULT):
447 return(NULL);
448 default:
449 break;
450 }
451
452 abort();
453 /* NOTREACHED */
454 }
455
456
457 const char *
458 mdoc_vol2a(enum mdoc_vol vol)
459 {
460
461 switch (vol) {
462 case (VOL_AMD):
463 return("OpenBSD Ancestral Manual Documents");
464 case (VOL_IND):
465 return("OpenBSD Manual Master Index");
466 case (VOL_KM):
467 return("OpenBSD Kernel Manual");
468 case (VOL_LOCAL):
469 return("OpenBSD Local Manual");
470 case (VOL_PRM):
471 return("OpenBSD Programmer's Manual");
472 case (VOL_PS1):
473 return("OpenBSD Programmer's Supplementary Documents");
474 case (VOL_SMM):
475 return("OpenBSD System Manager's Manual");
476 case (VOL_URM):
477 return("OpenBSD Reference Manual");
478 case (VOL_USD):
479 return("OpenBSD User's Supplementary Documents");
480 case (VOL_DEFAULT):
481 return(NULL);
482 default:
483 break;
484 }
485
486 abort();
487 /* NOTREACHED */
488 }
489
490
491 const char *
492 mdoc_msec2a(enum mdoc_msec msec)
493 {
494
495 switch (msec) {
496 case(MSEC_1):
497 return("1");
498 case(MSEC_2):
499 return("2");
500 case(MSEC_3):
501 return("3");
502 case(MSEC_3f):
503 return("3f");
504 case(MSEC_3p):
505 return("3p");
506 case(MSEC_4):
507 return("4");
508 case(MSEC_5):
509 return("5");
510 case(MSEC_6):
511 return("6");
512 case(MSEC_7):
513 return("7");
514 case(MSEC_8):
515 return("8");
516 case(MSEC_9):
517 return("9");
518 case(MSEC_X11):
519 return("X11");
520 case(MSEC_X11R6):
521 return("X11R6");
522 case(MSEC_local):
523 return("local");
524 case(MSEC_n):
525 return("n");
526 case(MSEC_unass):
527 /* FALLTHROUGH */
528 case(MSEC_draft):
529 return("draft");
530 case(MSEC_paper):
531 return("paper");
532 case(MSEC_DEFAULT):
533 return(NULL);
534 default:
535 break;
536 }
537
538 abort();
539 /* NOTREACHED */
540 }
541
542
543 const char *
544 mdoc_st2a(int c)
545 {
546 char *p;
547
548 switch (c) {
549 case(MDOC_p1003_1_88):
550 p = "IEEE Std 1003.1-1988 (\\(lqPOSIX\\(rq)";
551 break;
552 case(MDOC_p1003_1_90):
553 p = "IEEE Std 1003.1-1990 (\\(lqPOSIX\\(rq)";
554 break;
555 case(MDOC_p1003_1_96):
556 p = "ISO/IEC 9945-1:1996 (\\(lqPOSIX\\(rq)";
557 break;
558 case(MDOC_p1003_1_2001):
559 p = "IEEE Std 1003.1-2001 (\\(lqPOSIX\\(rq)";
560 break;
561 case(MDOC_p1003_1_2004):
562 p = "IEEE Std 1003.1-2004 (\\(lqPOSIX\\(rq)";
563 break;
564 case(MDOC_p1003_1):
565 p = "IEEE Std 1003.1 (\\(lqPOSIX\\(rq)";
566 break;
567 case(MDOC_p1003_1b):
568 p = "IEEE Std 1003.1b (\\(lqPOSIX\\(rq)";
569 break;
570 case(MDOC_p1003_1b_93):
571 p = "IEEE Std 1003.1b-1993 (\\(lqPOSIX\\(rq)";
572 break;
573 case(MDOC_p1003_1c_95):
574 p = "IEEE Std 1003.1c-1995 (\\(lqPOSIX\\(rq)";
575 break;
576 case(MDOC_p1003_1g_2000):
577 p = "IEEE Std 1003.1g-2000 (\\(lqPOSIX\\(rq)";
578 break;
579 case(MDOC_p1003_2_92):
580 p = "IEEE Std 1003.2-1992 (\\(lqPOSIX.2\\(rq)";
581 break;
582 case(MDOC_p1387_2_95):
583 p = "IEEE Std 1387.2-1995 (\\(lqPOSIX.7.2\\(rq)";
584 break;
585 case(MDOC_p1003_2):
586 p = "IEEE Std 1003.2 (\\(lqPOSIX.2\\(rq)";
587 break;
588 case(MDOC_p1387_2):
589 p = "IEEE Std 1387.2 (\\(lqPOSIX.7.2\\(rq)";
590 break;
591 case(MDOC_isoC_90):
592 p = "ISO/IEC 9899:1990 (\\(lqISO C90\\(rq)";
593 break;
594 case(MDOC_isoC_amd1):
595 p = "ISO/IEC 9899/AMD1:1995 (\\(lqISO C90\\(rq)";
596 break;
597 case(MDOC_isoC_tcor1):
598 p = "ISO/IEC 9899/TCOR1:1994 (\\(lqISO C90\\(rq)";
599 break;
600 case(MDOC_isoC_tcor2):
601 p = "ISO/IEC 9899/TCOR2:1995 (\\(lqISO C90\\(rq)";
602 break;
603 case(MDOC_isoC_99):
604 p = "ISO/IEC 9899:1999 (\\(lqISO C99\\(rq)";
605 break;
606 case(MDOC_ansiC):
607 p = "ANSI X3.159-1989 (\\(lqANSI C\\(rq)";
608 break;
609 case(MDOC_ansiC_89):
610 p = "ANSI X3.159-1989 (\\(lqANSI C\\(rq)";
611 break;
612 case(MDOC_ansiC_99):
613 p = "ANSI/ISO/IEC 9899-1999 (\\(lqANSI C99\\(rq)";
614 break;
615 case(MDOC_ieee754):
616 p = "IEEE Std 754-1985";
617 break;
618 case(MDOC_iso8802_3):
619 p = "ISO 8802-3: 1989";
620 break;
621 case(MDOC_xpg3):
622 p = "X/Open Portability Guide Issue 3 "
623 "(\\(lqXPG3\\(rq)";
624 break;
625 case(MDOC_xpg4):
626 p = "X/Open Portability Guide Issue 4 "
627 "(\\(lqXPG4\\(rq)";
628 break;
629 case(MDOC_xpg4_2):
630 p = "X/Open Portability Guide Issue 4.2 "
631 "(\\(lqXPG4.2\\(rq)";
632 break;
633 case(MDOC_xpg4_3):
634 p = "X/Open Portability Guide Issue 4.3 "
635 "(\\(lqXPG4.3\\(rq)";
636 break;
637 case(MDOC_xbd5):
638 p = "X/Open System Interface Definitions Issue 5 "
639 "(\\(lqXBD5\\(rq)";
640 break;
641 case(MDOC_xcu5):
642 p = "X/Open Commands and Utilities Issue 5 "
643 "(\\(lqXCU5\\(rq)";
644 break;
645 case(MDOC_xsh5):
646 p = "X/Open System Interfaces and Headers Issue 5 "
647 "(\\(lqXSH5\\(rq)";
648 break;
649 case(MDOC_xns5):
650 p = "X/Open Networking Services Issue 5 "
651 "(\\(lqXNS5\\(rq)";
652 break;
653 case(MDOC_xns5_2d2_0):
654 p = "X/Open Networking Services Issue 5.2 Draft 2.0 "
655 "(\\(lqXNS5.2D2.0\\(rq)";
656 break;
657 case(MDOC_xcurses4_2):
658 p = "X/Open Curses Issue 4 Version 2 "
659 "(\\(lqXCURSES4.2\\(rq)";
660 break;
661 case(MDOC_susv2):
662 p = "Version 2 of the Single UNIX Specification";
663 break;
664 case(MDOC_susv3):
665 p = "Version 3 of the Single UNIX Specification";
666 break;
667 case(MDOC_svid4):
668 p = "System V Interface Definition, Fourth Edition "
669 "(\\(lqSVID4\\(rq)";
670 break;
671 default:
672 p = NULL;
673 break;
674 }
675
676 return(p);
677 }
678
679
680 const char *
681 mdoc_att2a(enum mdoc_att c)
682 {
683 char *p;
684
685 switch (c) {
686 case(ATT_v1):
687 p = "Version 1 AT&T UNIX";
688 break;
689 case(ATT_v2):
690 p = "Version 2 AT&T UNIX";
691 break;
692 case(ATT_v3):
693 p = "Version 3 AT&T UNIX";
694 break;
695 case(ATT_v4):
696 p = "Version 4 AT&T UNIX";
697 break;
698 case(ATT_v5):
699 p = "Version 5 AT&T UNIX";
700 break;
701 case(ATT_v6):
702 p = "Version 6 AT&T UNIX";
703 break;
704 case(ATT_v7):
705 p = "Version 7 AT&T UNIX";
706 break;
707 case(ATT_32v):
708 p = "Version 32V AT&T UNIX";
709 break;
710 case(ATT_V1):
711 p = "AT&T System V.1 UNIX";
712 break;
713 case(ATT_V2):
714 p = "AT&T System V.2 UNIX";
715 break;
716 case(ATT_V3):
717 p = "AT&T System V.3 UNIX";
718 break;
719 case(ATT_V4):
720 p = "AT&T System V.4 UNIX";
721 break;
722 default:
723 p = "AT&T UNIX";
724 break;
725 }
726
727 return(p);
728 }