Annotation of mandoc/demandoc.c, Revision 1.2
1.2 ! kristaps 1: /* $Id: demandoc.c,v 1.1 2011/09/01 10:46:28 kristaps Exp $ */
1.1 kristaps 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: #ifdef HAVE_CONFIG_H
18: #include "config.h"
19: #endif
20:
21: #include <assert.h>
22: #include <getopt.h>
23: #include <stdio.h>
24: #include <stdlib.h>
25: #include <string.h>
1.2 ! kristaps 26: #include <unistd.h>
1.1 kristaps 27:
28: #include "man.h"
29: #include "mdoc.h"
30: #include "mandoc.h"
31:
32: static void pline(int, int *, int *);
33: static void pman(const struct man_node *, int *, int *);
34: static void pmandoc(struct mparse *, int, const char *);
35: static void pmdoc(const struct mdoc_node *, int *, int *);
36: static void pstring(const char *, int, int *);
37: static void usage(void);
38:
39: static const char *progname;
40:
41: int
42: main(int argc, char *argv[])
43: {
44: struct mparse *mp;
45: int ch, i;
46: extern int optind;
47: extern char *optarg;
48:
49: progname = strrchr(argv[0], '/');
50: if (progname == NULL)
51: progname = argv[0];
52: else
53: ++progname;
54:
55: mp = NULL;
56:
57: while (-1 != (ch = getopt(argc, argv, "")))
58: switch (ch) {
59: default:
60: usage();
61: return((int)MANDOCLEVEL_BADARG);
62: }
63:
64: argc -= optind;
65: argv += optind;
66:
67: mp = mparse_alloc(MPARSE_AUTO, MANDOCLEVEL_FATAL, NULL, NULL);
68: assert(mp);
69:
70: if (0 == argc)
71: pmandoc(mp, STDIN_FILENO, "<stdin>");
72:
73: for (i = 0; i < argc; i++) {
74: mparse_reset(mp);
75: pmandoc(mp, -1, argv[i]);
76: }
77:
78: mparse_free(mp);
79: return(MANDOCLEVEL_OK);
80: }
81:
82: static void
83: usage(void)
84: {
85:
86: fprintf(stderr, "usage: %s [files...]\n", progname);
87: }
88:
89: static void
90: pmandoc(struct mparse *mp, int fd, const char *fn)
91: {
92: struct mdoc *mdoc;
93: struct man *man;
94: int line, col;
95:
96: if (mparse_readfd(mp, fd, fn) >= MANDOCLEVEL_FATAL) {
97: fprintf(stderr, "%s: Parse failure\n", fn);
98: return;
99: }
100:
101: mparse_result(mp, &mdoc, &man);
102: line = 1;
103: col = 0;
104:
105: if (mdoc)
106: pmdoc(mdoc_node(mdoc), &line, &col);
107: else if (man)
108: pman(man_node(man), &line, &col);
109: else
110: return;
111:
112: putchar('\n');
113: }
114:
115: /*
116: * Strip the escapes out of a string, emitting the results.
117: */
118: static void
119: pstring(const char *p, int col, int *colp)
120: {
121: enum mandoc_esc esc;
122:
123: while (*colp < col) {
124: putchar(' ');
125: (*colp)++;
126: }
127:
128: while ('\0' != *p) {
129: if ('\\' == *p) {
130: p++;
131: esc = mandoc_escape(&p, NULL, NULL);
132: if (ESCAPE_ERROR == esc)
133: return;
134: } else {
135: putchar(*p++);
136: (*colp)++;
137: }
138: }
139: }
140:
141: /*
142: * Emit lines until we're in sync with our input.
143: */
144: static void
145: pline(int line, int *linep, int *col)
146: {
147:
148: while (*linep < line) {
149: putchar('\n');
150: (*linep)++;
151: }
152: *col = 0;
153: }
154:
155: static void
156: pmdoc(const struct mdoc_node *p, int *line, int *col)
157: {
158:
159: for ( ; p; p = p->next) {
160: if (MDOC_LINE & p->flags)
161: pline(p->line, line, col);
162: if (MDOC_TEXT == p->type)
163: pstring(p->string, p->pos, col);
164: if (p->child)
165: pmdoc(p->child, line, col);
166: }
167: }
168:
169: static void
170: pman(const struct man_node *p, int *line, int *col)
171: {
172:
173: for ( ; p; p = p->next) {
174: if (MAN_LINE & p->flags)
175: pline(p->line, line, col);
176: if (MAN_TEXT == p->type)
177: pstring(p->string, p->pos, col);
178: if (p->child)
179: pman(p->child, line, col);
180: }
181: }
CVSweb