tm2txt.c
来自「一个C格式的脚本处理函数库源代码,可让你的C程序具有执行C格式的脚本文件」· C语言 代码 · 共 727 行
C
727 行
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <ctype.h>/* 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;static int Top_Level;typedef struct { char *name; char *value;}Macro_String_Type; static Macro_String_Type Macro_Strings [] = { {"slang", "S-Lang"}, {"jed", "jed"}, {"NULL", "NULL"}, {"-1", "-1"}, {"0", "0"}, {"1", "1"}, {"2", "2"}, {"3", "3"}, {"4", "4"}, {"5", "5"}, {"6", "6"}, {"7", "7"}, {"8", "8"}, {"9", "9"}, {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 1024static char Input_Buffer [MAX_BUF_LEN];static unsigned int Line_Number;static int Input_Buffer_Pushed;static int Line_Type;static char *This_Filename;#define END_OF_FILE 1#define SECTION_LINE 2#define VERBATUM_LINE 3static char Source_File[MAX_BUF_LEN];static int set_source_file (char *s){ strncpy (Source_File, s, MAX_BUF_LEN); Source_File[MAX_BUF_LEN-1] = 0; This_Filename = Source_File; return 0;}static int set_source_linenum (char *s){ unsigned int n; if (1 == sscanf (s, "%u", &n)) Line_Number = n; return 0;}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 (unsigned int);static int verbatum_mode (void){ begin_verbatum (); while (NULL != fgets (Input_Buffer, MAX_BUF_LEN, Input_File_Ptr)) { Line_Number++; if (Input_Buffer[0] == '#') { if ((Input_Buffer[1] != 'v') || (Input_Buffer[2] != '-')) { fprintf (stderr, "%s:%u:Expecting verbatum end\n", This_Filename, Line_Number); return -1; } break; } indent (3); fputs (Input_Buffer, stdout); } end_verbatum (); return 0;} 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] == '+') { if (-1 == verbatum_mode ()) return -1; } else { fprintf (stderr, "%s:%u:Expecting verbatum start\n", This_Filename, Line_Number); return -1; } break; } if (Input_Buffer[1] == 'c') { if (0 == strncmp (Input_Buffer, "#c __FILE__: ", 13)) { set_source_file (Input_Buffer + 13); break; } if (0 == strncmp (Input_Buffer, "#c __LINE__: ", 13)) { set_source_linenum (Input_Buffer + 13); break; } break; } 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 == ' ') || (*buf == '\t')) { *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, "%s:%u:Unknown section '%s'\n", This_Filename, Line_Number, name); return NULL; } if (0 == strcmp (sec->section_name, name)) break; sec++; } if (has_colon) { unget_input (buf + 1); } return sec;} static int process_file (FILE *fp){ Section_Type *sec; Input_File_Ptr = fp; Output_File_Ptr = stdout; Line_Number = 0; Top_Level = 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, "%s:%u:Error ignored.\n", This_Filename, Line_Number); get_next_line (); continue; } if (sec->format_fun == NULL) { get_next_line (); continue; } if (-1 == (*sec->format_fun)(sec)) { fprintf (stderr, "%s:%u:Fatal error\n", This_Filename, Line_Number); return -1; } } return 0;} static void usage (void){ char *pgm = "tm2txt"; fprintf (stderr, "%s usage:\n", pgm); fprintf (stderr, "%s [--help] [--quiet] [files...]\n", pgm);}int main (int argc, char **argv){ if ((argc > 1) && ((0 == strcmp (argv[1], "--help")) || (0 == strcmp (argv[1], "-h")))) { usage (); return 1; } if ((argc > 1) && (0 == strcmp (argv[1], "--quiet"))) { Run_Silent = 1; argc--; argv++; } if ((argc == 1) && isatty (fileno(stdin))) { usage (); return 1; } if (argc == 1) { This_Filename = "<stdin>"; process_file (stdin); } else { int i; for (i = 1; i < argc; i++) { char *file = argv[i]; FILE *fp; if (NULL == (fp = fopen (file, "r"))) { fprintf (stderr, "Unable to open %s, skipping it.\n", file); continue; } This_Filename = file; if (-1 == process_file (fp)) { fprintf (stderr, "Fatal error encountered processing %s\n", file); fclose (fp); return 1; } fclose (fp); } } return 0;}static int write_boldface (char *s){ fprintf (Output_File_Ptr, "%s", s); return 0;}#if 0static int write_tt (char *s){ fprintf (Output_File_Ptr, "`%s'", s); return 0;}#endifstatic 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:%u:%s not defined\n", This_Filename, Line_Number, 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)) || (0 == strncmp ("par{", buf, 4)) || (0 == strncmp ("fun{", buf, 4))) { putc ('`', Output_File_Ptr); buf = write_verbatum_output (buf + 4); putc ('\'', Output_File_Ptr); break; } if ((0 == strncmp ("exmp{", buf, 5)) || (0 == strncmp ("ifun{", buf, 5)) || (0 == strncmp ("cfun{", buf, 5)) || (0 == strncmp ("sfun{", buf, 5)) || (0 == strncmp ("ivar{", buf, 5)) || (0 == strncmp ("cvar{", buf, 5)) || (0 == strncmp ("svar{", 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 (unsigned int n){ while (n) { putc (' ', Output_File_Ptr); n--; } return 0;}static int write_line (void){ char *s = Input_Buffer; unsigned int min_indent = 3; while ((*s == ' ') && min_indent) { s++; min_indent--; } indent (min_indent); write_with_escape (Input_Buffer); newline (); return 0;}static int format_function (Section_Type *sec){ (void) sec; if (Top_Level == 0) { fprintf (stderr, "%s:%u:\\function or \\variable not at top-level\n", This_Filename, Line_Number); fprintf (stderr, " Input line: %s\n", Input_Buffer); return -1; } Top_Level = 0; write_verbatum_output (Input_Buffer); newline (); get_next_line (); return 0;}static int format_usage (Section_Type *sec){ (void) sec; write_section_name ("USAGE"); indent (3); write_verbatum_output (Input_Buffer); newline (); get_next_line (); return 0;}static int format_description (Section_Type *sec){ (void) sec; write_section_name ("DESCRIPTION"); while (0 == get_next_line ()) { write_line (); } return 0; }static int format_example (Section_Type *sec){ (void) sec; write_section_name ("EXAMPLE"); while (0 == get_next_line ()) { write_line (); } return 0; }static int format_notes (Section_Type *sec){ (void) sec; write_section_name ("NOTES"); while (0 == get_next_line ()) { write_line (); } return 0; }static int format_see_also (Section_Type *sec){ (void) sec; write_section_name ("SEE ALSO"); indent (3); write_verbatum_output (Input_Buffer); newline (); get_next_line (); return 0;}int format_synopsis (Section_Type *sec){ (void) sec; write_section_name ("SYNOPSIS"); indent (3); write_verbatum_output (Input_Buffer); newline (); get_next_line (); return 0;}int format_done (Section_Type *sec){ (void) sec; if (Top_Level) { fprintf (stderr, "%s:%u:\\done seen at top-level\n", This_Filename, Line_Number); return -1; } fputs ("--------------------------------------------------------------\n", Output_File_Ptr); newline (); while (0 == get_next_line ()) ; Top_Level = 1; return 0;}static int begin_verbatum (void){ newline (); return 0;}static int end_verbatum (void){ newline (); return 0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?