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