* snarf.h, filter-doc-snarfage.c: more changes to cope with
[bpt/guile.git] / libguile / filter-doc-snarfage.c
CommitLineData
c99f9605
ML
1#include <stdio.h>
2#include <stdlib.h>
3#include <ctype.h>
4
5static void init_state_machine (void);
6
7static void process (void);
8
9static void check_end_conditions (void);
10
11int
12main (int argc, char *argv[])
13{
14 init_state_machine ();
15 process ();
16 check_end_conditions ();
17
18 return EXIT_SUCCESS;
19}
20
21typedef enum state_t
22 {
23 SKIP,
24 SKIP_COOKIE,
25
a88ff5b6 26 MULTILINE_BEGINNING_OF_LINE,
c99f9605
ML
27 MULTILINE,
28
29 MULTILINE_COOKIE,
30 STRINGS,
31
32 SINGLELINE,
33
34 } state_t;
35
36state_t state = SKIP;
37
38static void die (const char *msg);
39static void process_strings (void);
40static void process_single_line (void);
41
42void
43process ()
44{
45 int want_cookie = 0;
46 int ch;
47
48 while ((ch = getc (stdin)) != EOF) {
49 char c = (char)ch;
50
51 switch (state) {
52 case SKIP:
53 if (c == '^') {
54 if (want_cookie) {
55 state = SKIP_COOKIE;
56 want_cookie = 0;
57 } else
58 want_cookie = 1;
47bcd646 59 } else if (c != ' ')
c99f9605
ML
60 want_cookie = 0;
61 break;
62 case SKIP_COOKIE:
63 switch (c) {
64 case '[':
65 fputs ("(doc-check\n", stdout);
66 state = SINGLELINE;
67 break;
68 case '{':
69 fputs ("(doc-block (\n", stdout);
70 state = MULTILINE;
71 break;
a88ff5b6
ML
72 case ' ':
73 break;
c99f9605
ML
74 default:
75 die ("bad snarf cookie");
76 break;
77 }
78 break;
a88ff5b6
ML
79 case MULTILINE_BEGINNING_OF_LINE:
80 if (c != ' ') {
81 state = MULTILINE;
82 putc (c, stdout);
83 }
84 break;
c99f9605
ML
85 case MULTILINE:
86 if (c == '^') {
87 if (want_cookie) {
88 fputs ("\n)\n(\n", stdout);
89 state = MULTILINE_COOKIE;
90 want_cookie = 0;
91 } else
92 want_cookie = 1;
93 } else {
47bcd646
ML
94 if (c != ' ')
95 want_cookie = 0;
c99f9605
ML
96 putc (c, stdout);
97 }
98 break;
99 case MULTILINE_COOKIE:
100 switch (c) {
101 case '(':
102 state = STRINGS;
103 break;
a88ff5b6
ML
104 case '%':
105 state = MULTILINE_BEGINNING_OF_LINE;
c99f9605
ML
106 break;
107 case '}':
108 fputs ("))\n", stdout);
109 state = SKIP;
110 break;
a88ff5b6
ML
111 case ' ':
112 break;
c99f9605
ML
113 default:
114 die ("bad snarf cookie in multiline context");
115 break;
116 }
117 break;
118 case STRINGS:
119 process_strings ();
120 state = MULTILINE;
121 break;
122 case SINGLELINE:
123 process_single_line ();
124 fputs ("\n)\n", stdout);
125 state = SKIP;
126 break;
127 default:
128 abort ();
129 break;
130 }
131 }
132}
133
134void
135init_state_machine ()
136{}
137
138void
139die (const char *msg)
140{
141 fprintf (stderr, "%s\n", msg);
142 exit (EXIT_FAILURE);
143}
144
145void
146check_end_conditions ()
147{
148 if (state != SKIP)
149 die ("something is unterminated");
150}
151
152typedef enum str_state_t
153 {
154 STR_SKIP,
155 STR_INSIDE,
156 STR_HAD_ESCAPE,
157 STR_EXIT
158 } str_state_t;
159
160void
161process_strings ()
162{
163 /* read well-formed strings up to a ')', and break them up in the
164 process if they are too long */
165 int count = 0;
166 int ch;
167 str_state_t state = STR_SKIP;
168
169 fputs ("docstring\n", stdout);
170
171#define PUTC(c) putc (c, stdout); if (++count >= 512) { fputs ("\"\nstring \"", stdout); count = 0; }
172
173 while (!(((ch = getc (stdin)) == EOF)
174 || (state == STR_EXIT))) {
175 char c = (char) ch;
176
177 switch (state) {
178 case STR_SKIP:
179 switch (c) {
180 case '"':
181 fputs ("\nstring ", stdout);
182 count = 0;
183 PUTC (c);
184 state = STR_INSIDE;
185 break;
186 case ')':
187 state = STR_EXIT;
188 break;
189 default:
190 if (!isspace (c))
191 die ("stray stuff where should be only strings");
192 break;
193 }
194 break;
195 case STR_INSIDE:
196 switch (c) {
197 case '\\':
198 putc (c, stdout);
199 ++count;
200 state = STR_HAD_ESCAPE;
201 break;
202 case '"':
203 putc (c, stdout);
204 state = STR_SKIP;
205 break;
206 default:
207 PUTC (c);
208 break;
209 }
210 break;
211 case STR_HAD_ESCAPE:
212 PUTC (c);
213 state = STR_INSIDE;
214 break;
215 default:
216 abort ();
217 break;
218 }
219 }
220
221 if (state != STR_EXIT)
222 die ("docstrings don't terminate");
223}
224
225void
226process_single_line ()
227{
228 /* read up to a ']' */
229 int ch;
230 while (!(((ch = getc (stdin)) == EOF)
231 || ((char) ch == ']'))) {
232 char c = (char) ch;
233
234 putc (c, stdout);
235 }
236
237 if ((char) ch != ']')
238 die ("bad checking snarfage");
239}
240
241
242/*
243 Local Variables:
244 c-file-style: "gnu"
245 End:
246*/