xref: /openbsd-src/usr.bin/mandoc/mandoc.c (revision 43003dfe3ad45d1698bed8a37f2b0f5b14f20d4f)
1 /*	$Id: mandoc.c,v 1.3 2009/08/22 15:18:11 schwarze Exp $ */
2 /*
3  * Copyright (c) 2008, 2009 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 above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 #include <sys/types.h>
18 
19 #include <assert.h>
20 #include <ctype.h>
21 #include <stdlib.h>
22 
23 #include "libmandoc.h"
24 
25 int
26 mandoc_special(const char *p)
27 {
28 	int		 c;
29 
30 	if ('\\' != *p++)
31 		return(0);
32 
33 	switch (*p) {
34 	case ('\\'):
35 		/* FALLTHROUGH */
36 	case ('\''):
37 		/* FALLTHROUGH */
38 	case ('`'):
39 		/* FALLTHROUGH */
40 	case ('q'):
41 		/* FALLTHROUGH */
42 	case ('-'):
43 		/* FALLTHROUGH */
44 	case ('~'):
45 		/* FALLTHROUGH */
46 	case ('^'):
47 		/* FALLTHROUGH */
48 	case ('%'):
49 		/* FALLTHROUGH */
50 	case ('0'):
51 		/* FALLTHROUGH */
52 	case (' '):
53 		/* FALLTHROUGH */
54 	case ('|'):
55 		/* FALLTHROUGH */
56 	case ('&'):
57 		/* FALLTHROUGH */
58 	case ('.'):
59 		/* FALLTHROUGH */
60 	case (':'):
61 		/* FALLTHROUGH */
62 	case ('c'):
63 		return(2);
64 	case ('e'):
65 		return(2);
66 	case ('f'):
67 		if (0 == *++p || ! isgraph((u_char)*p))
68 			return(0);
69 		return(3);
70 	case ('*'):
71 		if (0 == *++p || ! isgraph((u_char)*p))
72 			return(0);
73 		switch (*p) {
74 		case ('('):
75 			if (0 == *++p || ! isgraph((u_char)*p))
76 				return(0);
77 			return(4);
78 		case ('['):
79 			for (c = 3, p++; *p && ']' != *p; p++, c++)
80 				if ( ! isgraph((u_char)*p))
81 					break;
82 			return(*p == ']' ? c : 0);
83 		default:
84 			break;
85 		}
86 		return(3);
87 	case ('('):
88 		if (0 == *++p || ! isgraph((u_char)*p))
89 			return(0);
90 		if (0 == *++p || ! isgraph((u_char)*p))
91 			return(0);
92 		return(4);
93 	case ('['):
94 		break;
95 	default:
96 		return(0);
97 	}
98 
99 	for (c = 3, p++; *p && ']' != *p; p++, c++)
100 		if ( ! isgraph((u_char)*p))
101 			break;
102 
103 	return(*p == ']' ? c : 0);
104 }
105 
106