1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-08 22:50:27 +02:00
guile/libguile/filter-doc-snarfage.c
Michael Livshin c99f960518 * guile-snarf-docs.in, guile-snarf-docs-texi.in,
filter-doc-snarfage.c: new files.

* Makefile.am: add stuff to [build,] use and distribute
guile-snarf-docs, guile-snarf-docs-texi, guile_filter_doc_snarfage.

* guile-snarf.in: grok the new snarf output.

* snarf.h: make the output both texttools- and `read'-friendly.

* guile-doc-snarf.in (bindir): reimplement in terms of guile-snarf
and guile-snarf-docs.  (should also deprecate, I guess.  maybe
not).
2001-05-31 13:15:54 +00:00

234 lines
4 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
static void init_state_machine (void);
static void process (void);
static void check_end_conditions (void);
int
main (int argc, char *argv[])
{
init_state_machine ();
process ();
check_end_conditions ();
return EXIT_SUCCESS;
}
typedef enum state_t
{
SKIP,
SKIP_COOKIE,
MULTILINE,
MULTILINE_COOKIE,
STRINGS,
SINGLELINE,
} state_t;
state_t state = SKIP;
static void die (const char *msg);
static void process_strings (void);
static void process_single_line (void);
void
process ()
{
int want_cookie = 0;
int ch;
while ((ch = getc (stdin)) != EOF) {
char c = (char)ch;
switch (state) {
case SKIP:
if (c == '^') {
if (want_cookie) {
state = SKIP_COOKIE;
want_cookie = 0;
} else
want_cookie = 1;
} else
want_cookie = 0;
break;
case SKIP_COOKIE:
switch (c) {
case '[':
fputs ("(doc-check\n", stdout);
state = SINGLELINE;
break;
case '{':
fputs ("(doc-block (\n", stdout);
state = MULTILINE;
break;
default:
die ("bad snarf cookie");
break;
}
break;
case MULTILINE:
if (c == '^') {
if (want_cookie) {
fputs ("\n)\n(\n", stdout);
state = MULTILINE_COOKIE;
want_cookie = 0;
} else
want_cookie = 1;
} else {
want_cookie = 0;
putc (c, stdout);
}
break;
case MULTILINE_COOKIE:
switch (c) {
case '(':
state = STRINGS;
break;
case ' ':
state = MULTILINE;
break;
case '}':
fputs ("))\n", stdout);
state = SKIP;
break;
default:
die ("bad snarf cookie in multiline context");
break;
}
break;
case STRINGS:
process_strings ();
state = MULTILINE;
break;
case SINGLELINE:
process_single_line ();
fputs ("\n)\n", stdout);
state = SKIP;
break;
default:
abort ();
break;
}
}
}
void
init_state_machine ()
{}
void
die (const char *msg)
{
fprintf (stderr, "%s\n", msg);
exit (EXIT_FAILURE);
}
void
check_end_conditions ()
{
if (state != SKIP)
die ("something is unterminated");
}
typedef enum str_state_t
{
STR_SKIP,
STR_INSIDE,
STR_HAD_ESCAPE,
STR_EXIT
} str_state_t;
void
process_strings ()
{
/* read well-formed strings up to a ')', and break them up in the
process if they are too long */
int count = 0;
int ch;
str_state_t state = STR_SKIP;
fputs ("docstring\n", stdout);
#define PUTC(c) putc (c, stdout); if (++count >= 512) { fputs ("\"\nstring \"", stdout); count = 0; }
while (!(((ch = getc (stdin)) == EOF)
|| (state == STR_EXIT))) {
char c = (char) ch;
switch (state) {
case STR_SKIP:
switch (c) {
case '"':
fputs ("\nstring ", stdout);
count = 0;
PUTC (c);
state = STR_INSIDE;
break;
case ')':
state = STR_EXIT;
break;
default:
if (!isspace (c))
die ("stray stuff where should be only strings");
break;
}
break;
case STR_INSIDE:
switch (c) {
case '\\':
putc (c, stdout);
++count;
state = STR_HAD_ESCAPE;
break;
case '"':
putc (c, stdout);
state = STR_SKIP;
break;
default:
PUTC (c);
break;
}
break;
case STR_HAD_ESCAPE:
PUTC (c);
state = STR_INSIDE;
break;
default:
abort ();
break;
}
}
if (state != STR_EXIT)
die ("docstrings don't terminate");
}
void
process_single_line ()
{
/* read up to a ']' */
int ch;
while (!(((ch = getc (stdin)) == EOF)
|| ((char) ch == ']'))) {
char c = (char) ch;
putc (c, stdout);
}
if ((char) ch != ']')
die ("bad checking snarfage");
}
/*
Local Variables:
c-file-style: "gnu"
End:
*/