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