1/* $Id: demandoc.c,v 1.12 2014/10/28 17:36:19 schwarze Exp $ */
| 1/* $Id: demandoc.c,v 1.15 2015/02/10 08:05:30 schwarze Exp $ */
|
2/* 3 * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv> 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 "config.h" 18 19#include <sys/types.h> 20 21#include <assert.h> 22#include <ctype.h> 23#include <getopt.h> 24#include <stdio.h> 25#include <stdlib.h> 26#include <string.h> 27#include <unistd.h> 28 29#include "man.h" 30#include "mdoc.h" 31#include "mandoc.h" 32 33static void pline(int, int *, int *, int); 34static void pman(const struct man_node *, int *, int *, int); 35static void pmandoc(struct mparse *, int, const char *, int); 36static void pmdoc(const struct mdoc_node *, int *, int *, int); 37static void pstring(const char *, int, int *, int); 38static void usage(void); 39 40static const char *progname; 41 42int 43main(int argc, char *argv[]) 44{ 45 struct mparse *mp; 46 struct mchars *mchars;
| 2/* 3 * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv> 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 "config.h" 18 19#include <sys/types.h> 20 21#include <assert.h> 22#include <ctype.h> 23#include <getopt.h> 24#include <stdio.h> 25#include <stdlib.h> 26#include <string.h> 27#include <unistd.h> 28 29#include "man.h" 30#include "mdoc.h" 31#include "mandoc.h" 32 33static void pline(int, int *, int *, int); 34static void pman(const struct man_node *, int *, int *, int); 35static void pmandoc(struct mparse *, int, const char *, int); 36static void pmdoc(const struct mdoc_node *, int *, int *, int); 37static void pstring(const char *, int, int *, int); 38static void usage(void); 39 40static const char *progname; 41 42int 43main(int argc, char *argv[]) 44{ 45 struct mparse *mp; 46 struct mchars *mchars;
|
47 int ch, i, list;
| 47 int ch, fd, i, list;
|
48 extern int optind; 49
| 48 extern int optind; 49
|
50 progname = strrchr(argv[0], '/'); 51 if (progname == NULL)
| 50 if (argc < 1) 51 progname = "demandoc"; 52 else if ((progname = strrchr(argv[0], '/')) == NULL)
|
52 progname = argv[0]; 53 else 54 ++progname; 55 56 mp = NULL; 57 list = 0; 58 59 while (-1 != (ch = getopt(argc, argv, "ikm:pw"))) 60 switch (ch) { 61 case ('i'): 62 /* FALLTHROUGH */ 63 case ('k'): 64 /* FALLTHROUGH */ 65 case ('m'): 66 /* FALLTHROUGH */ 67 case ('p'): 68 break; 69 case ('w'): 70 list = 1; 71 break; 72 default: 73 usage(); 74 return((int)MANDOCLEVEL_BADARG); 75 } 76 77 argc -= optind; 78 argv += optind; 79 80 mchars = mchars_alloc();
| 53 progname = argv[0]; 54 else 55 ++progname; 56 57 mp = NULL; 58 list = 0; 59 60 while (-1 != (ch = getopt(argc, argv, "ikm:pw"))) 61 switch (ch) { 62 case ('i'): 63 /* FALLTHROUGH */ 64 case ('k'): 65 /* FALLTHROUGH */ 66 case ('m'): 67 /* FALLTHROUGH */ 68 case ('p'): 69 break; 70 case ('w'): 71 list = 1; 72 break; 73 default: 74 usage(); 75 return((int)MANDOCLEVEL_BADARG); 76 } 77 78 argc -= optind; 79 argv += optind; 80 81 mchars = mchars_alloc();
|
81 mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_FATAL, NULL, mchars, NULL);
| 82 mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_BADARG, NULL, mchars, NULL);
|
82 assert(mp); 83
| 83 assert(mp); 84
|
84 if (0 == argc)
| 85 if (argc < 1)
|
85 pmandoc(mp, STDIN_FILENO, "<stdin>", list); 86 87 for (i = 0; i < argc; i++) { 88 mparse_reset(mp);
| 86 pmandoc(mp, STDIN_FILENO, "<stdin>", list); 87 88 for (i = 0; i < argc; i++) { 89 mparse_reset(mp);
|
89 pmandoc(mp, -1, argv[i], list);
| 90 if (mparse_open(mp, &fd, argv[i]) != MANDOCLEVEL_OK) { 91 perror(argv[i]); 92 continue; 93 } 94 pmandoc(mp, fd, argv[i], list);
|
90 } 91 92 mparse_free(mp); 93 mchars_free(mchars); 94 return((int)MANDOCLEVEL_OK); 95} 96 97static void 98usage(void) 99{ 100 101 fprintf(stderr, "usage: %s [-w] [files...]\n", progname); 102} 103 104static void 105pmandoc(struct mparse *mp, int fd, const char *fn, int list) 106{ 107 struct mdoc *mdoc; 108 struct man *man; 109 int line, col; 110
| 95 } 96 97 mparse_free(mp); 98 mchars_free(mchars); 99 return((int)MANDOCLEVEL_OK); 100} 101 102static void 103usage(void) 104{ 105 106 fprintf(stderr, "usage: %s [-w] [files...]\n", progname); 107} 108 109static void 110pmandoc(struct mparse *mp, int fd, const char *fn, int list) 111{ 112 struct mdoc *mdoc; 113 struct man *man; 114 int line, col; 115
|
111 if (mparse_readfd(mp, fd, fn) >= MANDOCLEVEL_FATAL) { 112 fprintf(stderr, "%s: Parse failure\n", fn); 113 return; 114 } 115
| 116 mparse_readfd(mp, fd, fn);
|
116 mparse_result(mp, &mdoc, &man, NULL); 117 line = 1; 118 col = 0; 119
| 117 mparse_result(mp, &mdoc, &man, NULL); 118 line = 1; 119 col = 0; 120
|
120 if (mdoc)
| 121 if (mdoc)
|
121 pmdoc(mdoc_node(mdoc), &line, &col, list); 122 else if (man) 123 pman(man_node(man), &line, &col, list); 124 else 125 return; 126 127 if ( ! list) 128 putchar('\n'); 129} 130 131/* 132 * Strip the escapes out of a string, emitting the results. 133 */ 134static void 135pstring(const char *p, int col, int *colp, int list) 136{ 137 enum mandoc_esc esc; 138 const char *start, *end; 139 int emit; 140 141 /* 142 * Print as many column spaces til we achieve parity with the 143 * input document. 144 */ 145 146again: 147 if (list && '\0' != *p) { 148 while (isspace((unsigned char)*p)) 149 p++; 150 151 while ('\'' == *p || '(' == *p || '"' == *p) 152 p++; 153 154 emit = isalpha((unsigned char)p[0]) && 155 isalpha((unsigned char)p[1]); 156 157 for (start = p; '\0' != *p; p++) 158 if ('\\' == *p) { 159 p++; 160 esc = mandoc_escape(&p, NULL, NULL); 161 if (ESCAPE_ERROR == esc) 162 return; 163 emit = 0; 164 } else if (isspace((unsigned char)*p)) 165 break; 166 167 end = p - 1; 168 169 while (end > start)
| 122 pmdoc(mdoc_node(mdoc), &line, &col, list); 123 else if (man) 124 pman(man_node(man), &line, &col, list); 125 else 126 return; 127 128 if ( ! list) 129 putchar('\n'); 130} 131 132/* 133 * Strip the escapes out of a string, emitting the results. 134 */ 135static void 136pstring(const char *p, int col, int *colp, int list) 137{ 138 enum mandoc_esc esc; 139 const char *start, *end; 140 int emit; 141 142 /* 143 * Print as many column spaces til we achieve parity with the 144 * input document. 145 */ 146 147again: 148 if (list && '\0' != *p) { 149 while (isspace((unsigned char)*p)) 150 p++; 151 152 while ('\'' == *p || '(' == *p || '"' == *p) 153 p++; 154 155 emit = isalpha((unsigned char)p[0]) && 156 isalpha((unsigned char)p[1]); 157 158 for (start = p; '\0' != *p; p++) 159 if ('\\' == *p) { 160 p++; 161 esc = mandoc_escape(&p, NULL, NULL); 162 if (ESCAPE_ERROR == esc) 163 return; 164 emit = 0; 165 } else if (isspace((unsigned char)*p)) 166 break; 167 168 end = p - 1; 169 170 while (end > start)
|
170 if ('.' == *end || ',' == *end ||
| 171 if ('.' == *end || ',' == *end ||
|
171 '\'' == *end || '"' == *end || 172 ')' == *end || '!' == *end || 173 '?' == *end || ':' == *end || 174 ';' == *end) 175 end--; 176 else 177 break; 178 179 if (emit && end - start >= 1) { 180 for ( ; start <= end; start++) 181 if (ASCII_HYPH == *start) 182 putchar('-'); 183 else 184 putchar((unsigned char)*start); 185 putchar('\n'); 186 } 187 188 if (isspace((unsigned char)*p)) 189 goto again; 190 191 return; 192 } 193 194 while (*colp < col) { 195 putchar(' '); 196 (*colp)++; 197 } 198 199 /* 200 * Print the input word, skipping any special characters. 201 */
| 172 '\'' == *end || '"' == *end || 173 ')' == *end || '!' == *end || 174 '?' == *end || ':' == *end || 175 ';' == *end) 176 end--; 177 else 178 break; 179 180 if (emit && end - start >= 1) { 181 for ( ; start <= end; start++) 182 if (ASCII_HYPH == *start) 183 putchar('-'); 184 else 185 putchar((unsigned char)*start); 186 putchar('\n'); 187 } 188 189 if (isspace((unsigned char)*p)) 190 goto again; 191 192 return; 193 } 194 195 while (*colp < col) { 196 putchar(' '); 197 (*colp)++; 198 } 199 200 /* 201 * Print the input word, skipping any special characters. 202 */
|
202 while ('\0' != *p)
| 203 while ('\0' != *p)
|
203 if ('\\' == *p) { 204 p++; 205 esc = mandoc_escape(&p, NULL, NULL); 206 if (ESCAPE_ERROR == esc) 207 break; 208 } else { 209 putchar((unsigned char )*p++); 210 (*colp)++; 211 } 212} 213 214static void 215pline(int line, int *linep, int *col, int list) 216{ 217 218 if (list) 219 return; 220 221 /* 222 * Print out as many lines as needed to reach parity with the
| 204 if ('\\' == *p) { 205 p++; 206 esc = mandoc_escape(&p, NULL, NULL); 207 if (ESCAPE_ERROR == esc) 208 break; 209 } else { 210 putchar((unsigned char )*p++); 211 (*colp)++; 212 } 213} 214 215static void 216pline(int line, int *linep, int *col, int list) 217{ 218 219 if (list) 220 return; 221 222 /* 223 * Print out as many lines as needed to reach parity with the
|
223 * original input.
| 224 * original input.
|
224 */ 225 226 while (*linep < line) { 227 putchar('\n'); 228 (*linep)++; 229 } 230 231 *col = 0; 232} 233 234static void 235pmdoc(const struct mdoc_node *p, int *line, int *col, int list) 236{ 237 238 for ( ; p; p = p->next) { 239 if (MDOC_LINE & p->flags) 240 pline(p->line, line, col, list); 241 if (MDOC_TEXT == p->type) 242 pstring(p->string, p->pos, col, list);
| 225 */ 226 227 while (*linep < line) { 228 putchar('\n'); 229 (*linep)++; 230 } 231 232 *col = 0; 233} 234 235static void 236pmdoc(const struct mdoc_node *p, int *line, int *col, int list) 237{ 238 239 for ( ; p; p = p->next) { 240 if (MDOC_LINE & p->flags) 241 pline(p->line, line, col, list); 242 if (MDOC_TEXT == p->type) 243 pstring(p->string, p->pos, col, list);
|
243 if (p->child)
| 244 if (p->child)
|
244 pmdoc(p->child, line, col, list); 245 } 246} 247 248static void 249pman(const struct man_node *p, int *line, int *col, int list) 250{ 251 252 for ( ; p; p = p->next) { 253 if (MAN_LINE & p->flags) 254 pline(p->line, line, col, list); 255 if (MAN_TEXT == p->type) 256 pstring(p->string, p->pos, col, list);
| 245 pmdoc(p->child, line, col, list); 246 } 247} 248 249static void 250pman(const struct man_node *p, int *line, int *col, int list) 251{ 252 253 for ( ; p; p = p->next) { 254 if (MAN_LINE & p->flags) 255 pline(p->line, line, col, list); 256 if (MAN_TEXT == p->type) 257 pstring(p->string, p->pos, col, list);
|
257 if (p->child)
| 258 if (p->child)
|
258 pman(p->child, line, col, list); 259 } 260}
| 259 pman(p->child, line, col, list); 260 } 261}
|