#include #include #include #include /* This program is a quick hack to turn the run-time library .tm files into * a decent looking ascii text file. The currently available SGML-tools are * not up to my standards for doing that. */ static int Run_Silent; typedef struct { char *name; char *value; } Macro_String_Type; static Macro_String_Type Macro_Strings [] = { {"slang", "S-Lang"}, {"jed", "jed"}, {"-1", "-1"}, {"0", "0"}, {NULL, NULL} }; typedef struct Section_Type { char *section_name; int (*format_fun) (struct Section_Type *); unsigned int flags; } Section_Type; static int format_function (Section_Type *); static int format_synopsis (Section_Type *); static int format_usage (Section_Type *); static int format_description (Section_Type *); static int format_example (Section_Type *); static int format_notes (Section_Type *); static int format_see_also (Section_Type *); static int format_done (Section_Type *); static Section_Type Sections [] = { { "function", format_function, 0 }, { "synopsis", format_synopsis, 0 }, { "usage", format_usage, 0 }, { "description", format_description, 0 }, { "example", format_example, 0 }, { "notes", format_notes, 0 }, { "seealso", format_see_also, 0 }, { "done", format_done, 0 }, { "variable", format_function, 0 }, { NULL, NULL, 0 } }; static FILE *Input_File_Ptr; static FILE *Output_File_Ptr; #define MAX_BUF_LEN 1024 static char Input_Buffer [MAX_BUF_LEN]; static unsigned int Line_Number; static int Input_Buffer_Pushed; static int Line_Type; #define END_OF_FILE 1 #define SECTION_LINE 2 #define VERBATUM_LINE 3 static int unget_input (char *buf) { if (buf != NULL) { char *inp = Input_Buffer; while (*buf != 0) { *inp++ = *buf++; } *inp = 0; } Input_Buffer_Pushed++; return 0; } static int begin_verbatum (void); static int end_verbatum (void); static int indent (void); static void verbatum_mode (void) { begin_verbatum (); while (NULL != fgets (Input_Buffer, MAX_BUF_LEN, Input_File_Ptr)) { if (Input_Buffer[0] == '#') break; indent (); fputs (Input_Buffer, stdout); } end_verbatum (); } static int get_next_line (void) { unsigned int len; while (1) { if (Input_Buffer_Pushed == 0) { if (NULL == fgets (Input_Buffer, MAX_BUF_LEN, Input_File_Ptr)) { Line_Type = END_OF_FILE; return -1; } Line_Number++; } Input_Buffer_Pushed = 0; len = strlen (Input_Buffer); if (len && (Input_Buffer[len - 1] == '\n')) Input_Buffer [len - 1] = 0; switch (*Input_Buffer) { case ';': case '%': break; case '#': if (Input_Buffer[1] == 'v') { if (Input_Buffer[2] == '+') verbatum_mode (); } break; case '\\': Line_Type = SECTION_LINE; return 1; default: Line_Type = 0; return 0; } } } static Section_Type *get_section (char *buf) { char *name; Section_Type *sec; int has_colon; if (*buf == '\\') buf++; name = buf; has_colon = 0; while (*buf != 0) { if (*buf == '\n') { *buf = 0; break; } if (*buf == '{') { has_colon = 1; *buf = 0; break; } buf++; } sec = Sections; while (1) { if (sec->section_name == NULL) { if (Run_Silent == 0) fprintf (stderr, "Unknown section %s\n", name); return NULL; } if (0 == strcmp (sec->section_name, name)) break; sec++; } if (has_colon) { unget_input (buf + 1); } return sec; } int main (int argc, char **argv) { int type; Section_Type *sec; Input_File_Ptr = stdin; Output_File_Ptr = stdout; if ((argc > 1) && (0 == strcmp (argv[1], "--quiet"))) Run_Silent = 1; Line_Type = 0; while (1) { while ((Line_Type != SECTION_LINE) && (Line_Type != END_OF_FILE)) get_next_line (); if (Line_Type == END_OF_FILE) break; if (NULL == (sec = get_section (Input_Buffer))) { if (Run_Silent == 0) fprintf (stderr, "Error on line %u\n", Line_Number); get_next_line (); continue; } if (sec->format_fun == NULL) { get_next_line (); continue; } if (-1 == (*sec->format_fun)(sec)) { fprintf (stderr, "Error on line %u\n", Line_Number); exit (1); } } return 0; } static int write_boldface (char *s) { fprintf (Output_File_Ptr, "%s", s); return 0; } static int write_tt (char *s) { fprintf (Output_File_Ptr, "`%s'", s); return 0; } static int newline (void) { fputs ("\n", Output_File_Ptr); return 0; } static int write_section_name (char *s) { newline (); fputs (" ", Output_File_Ptr); write_boldface (s); newline (); return 0; } static char *write_verbatum_output (char *buf) { while (*buf && (*buf != '}')) { if (*buf == '\\') { buf++; if (*buf == 0) break; } putc (*buf, Output_File_Ptr); buf++; } if (*buf == '}') buf++; return buf; } static char *write_macro (char *s) { char *s1; char ch; Macro_String_Type *m; s1 = s; while ((ch = *s1) != 0) { if ((0 == isalnum (ch)) && (ch != '-') && (ch != '_')) break; s1++; } *s1 = 0; m = Macro_Strings; while (m->name != NULL) { if (0 == strcmp (m->name, s)) { fputs (m->value, Output_File_Ptr); *s1 = ch; return s1; } m++; } fprintf (Output_File_Ptr, "\\%s", s); if (Run_Silent == 0) fprintf (stderr, "%s not defined\n", s); *s1 = ch; return s1; } static int write_with_escape (char *buf) { char ch; while (1) { ch = *buf++; switch (ch) { case 0: return 0; case '\\': if (*buf == '\\') { putc (*buf, Output_File_Ptr); buf++; break; } if (0 == strncmp ("var{", buf, 4)) { putc ('`', Output_File_Ptr); buf = write_verbatum_output (buf + 4); putc ('\'', Output_File_Ptr); break; } if (0 == strncmp ("exmp{", buf, 5)) { putc ('`', Output_File_Ptr); buf = write_verbatum_output (buf + 5); putc ('\'', Output_File_Ptr); break; } if (0 == strncmp ("em{", buf, 3)) { putc ('_', Output_File_Ptr); buf = write_verbatum_output (buf + 3); putc ('_', Output_File_Ptr); break; } buf = write_macro (buf); break; default: putc (ch, Output_File_Ptr); break; } } } static int indent (void) { fputs (" ", Output_File_Ptr); return 0; } static int write_line (void) { write_with_escape (Input_Buffer); newline (); return 0; } static int format_function (Section_Type *sec) { write_verbatum_output (Input_Buffer); newline (); get_next_line (); return 0; } static int format_usage (Section_Type *sec) { write_section_name ("USAGE"); indent (); write_verbatum_output (Input_Buffer); newline (); get_next_line (); return 0; } static int format_description (Section_Type *sec) { write_section_name ("DESCRIPTION"); while (0 == get_next_line ()) { write_line (); } return 0; } static int format_example (Section_Type *sec) { write_section_name ("EXAMPLE"); while (0 == get_next_line ()) { write_line (); } return 0; } static int format_notes (Section_Type *sec) { write_section_name ("NOTES"); while (0 == get_next_line ()) { write_line (); } return 0; } static int format_see_also (Section_Type *sec) { write_section_name ("SEE ALSO"); indent (); write_verbatum_output (Input_Buffer); newline (); get_next_line (); return 0; } int format_synopsis (Section_Type *sec) { write_section_name ("SYNOPSIS"); indent (); write_verbatum_output (Input_Buffer); newline (); get_next_line (); return 0; } int format_done (Section_Type *sec) { fputs ("--------------------------------------------------------------\n", Output_File_Ptr); newline (); while (0 == get_next_line ()) ; return 0; } static int begin_verbatum (void) { newline (); return 0; } static int end_verbatum (void) { newline (); return 0; }