⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 makedoc.c

📁 mutt-1.5.12 源代码。linux 下邮件接受的工具。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 1999-2000 Thomas Roessler <roessler@does-not-exist.org> *  *     This program is free software; you can redistribute it and/or modify *     it under the terms of the GNU General Public License as published by *     the Free Software Foundation; either version 2 of the License, or *     (at your option) any later version. *  *     This program is distributed in the hope that it will be useful, *     but WITHOUT ANY WARRANTY; without even the implied warranty of *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *     GNU General Public License for more details. *  *     You should have received a copy of the GNU General Public License *     along with this program; if not, write to the Free Software *     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. */ /** ** This program parses mutt's init.h and generates documentation in ** three different formats: ** ** -> a commented muttrc configuration file ** -> nroff, suitable for inclusion in a manual page ** -> docbook-xml, suitable for inclusion in the  **    SGML-based manual ** **/#if HAVE_CONFIG_H# include "config.h"#endif#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <errno.h>#ifdef HAVE_UNISTD_H# include <unistd.h>#endif#ifdef HAVE_GETOPT_H# include <getopt.h>#endif#ifndef HAVE_STRERROR#ifndef STDC_HEADERSextern int sys_nerr;extern char *sys_errlist[];#endif#define strerror(x) ((x) > 0 && (x) < sys_nerr) ? sys_errlist[(x)] : 0#endif /* !HAVE_STRERROR */extern int optind;#define BUFFSIZE 2048enum output_formats_t{  F_CONF, F_MAN, F_SGML, F_NONE};#define D_NL 		(1 << 0)#define D_EM		(1 << 1)#define D_BF		(1 << 2)#define D_TAB		(1 << 3)#define D_NP		(1 << 4)#define D_INIT		(1 << 5)#define D_DL		(1 << 6)#define D_DT		(1 << 7)#define D_DD            (1 << 8)#define D_PA            (1 << 9)enum{  SP_START_EM,  SP_START_BF,  SP_END_FT,  SP_NEWLINE,  SP_NEWPAR,  SP_END_PAR,  SP_STR,  SP_START_TAB,  SP_END_TAB,  SP_START_DL,  SP_DT,  SP_DD,  SP_END_DD,  SP_END_DL,  SP_END_SECT,  SP_REFER};enum output_formats_t OutputFormat = F_NONE;char *Progname;short Debug = 0;static char *get_token (char *, size_t, char *);static char *skip_ws (char *);static const char *type2human (int);static int buff2type (const char *);static int flush_doc (int, FILE *);static int handle_docline (char *, FILE *, int);static int print_it (int, char *, FILE *, int);static void print_confline (const char *, int, const char *, FILE *);static void handle_confline (char *, FILE *);static void makedoc (FILE *, FILE *);static void pretty_default (char *, size_t, const char *, int);static int sgml_fputc (int, FILE *);static int sgml_fputs (const char *, FILE *);static int sgml_id_fputs (const char *, FILE *);int main (int argc, char *argv[]){  int c;  FILE *f;  if ((Progname = strrchr (argv[0], '/')))    Progname++;  else    Progname = argv[0];    while ((c = getopt (argc, argv, "cmsd")) != EOF)  {    switch (c)    {      case 'c': OutputFormat = F_CONF; break;      case 'm': OutputFormat = F_MAN; break;      case 's': OutputFormat = F_SGML; break;      case 'd': Debug++; break;      default:       {	fprintf (stderr, "%s: bad command line parameter.\n", Progname);	exit (1);      }    }  }  if (optind != argc)  {    if ((f = fopen (argv[optind], "r")) == NULL)    {      fprintf (stderr, "%s: Can't open %s (%s).\n",	       Progname, argv[optind], strerror (errno));      exit (1);    }  }  else     f = stdin;  switch (OutputFormat)  {    case F_CONF:     case F_MAN:      case F_SGML: makedoc (f, stdout); break;    default:    {      fprintf (stderr, "%s: No output format specified.\n",	       Progname);      exit (1);    }  }    if (f != stdin)    fclose (f);    exit (1);}static void makedoc (FILE *in, FILE *out){  char buffer[BUFFSIZE];  char token[BUFFSIZE];  char *p;  int active = 0;  int line = 0;  int docstat = D_INIT;  while ((fgets (buffer, sizeof (buffer), in)))  {    line++;    if ((p = strchr (buffer, '\n')) == NULL)    {      fprintf (stderr, "%s: Line %d too long.  Ask a wizard to enlarge\n"	               "%s: my buffer size.\n", Progname, line, Progname);      exit (1);    }    else      *p = '\0';    if (!(p = get_token (token, sizeof (token), buffer)))      continue;    if (Debug)    {      fprintf (stderr, "%s: line %d.  first token: \"%s\".\n",	       Progname, line, token);    }        if (!strcmp (token, "/*++*/"))      active = 1;    else if (!strcmp (token, "/*--*/"))    {      docstat = flush_doc (docstat, out);      active = 0;    }    else if (active && (!strcmp (token, "/**") || !strcmp (token, "**")))      docstat = handle_docline (p, out, docstat);    else if (active && !strcmp (token, "{"))    {      docstat = flush_doc (docstat, out);      handle_confline (p, out);    }  }  flush_doc (docstat, out);  fputs ("\n", out);}/* skip whitespace */static char *skip_ws (char *s){  while (*s && isspace ((unsigned char) *s))    s++;  return s;}/* isolate a token */static char single_char_tokens[] = "[]{},;|";static char *get_token (char *d, size_t l, char *s){  char *t;  short is_quoted = 0;  char *dd = d;  if (Debug)     fprintf (stderr, "%s: get_token called for `%s'.\n",	      Progname, s);    s = skip_ws (s);  if (Debug > 1)    fprintf (stderr, "%s: argumet after skip_ws():  `%s'.\n",	     Progname, s);  if (!*s)  {    if (Debug)      fprintf (stderr, "%s: no more tokens on this line.\n", Progname);    return NULL;  }  if (strchr (single_char_tokens, *s))  {    if (Debug)    {      fprintf (stderr, "%s: found single character token `%c'.\n",	       Progname, *s);    }    d[0] = *s++;    d[1] = 0;    return s;  }  if (*s == '"')  {    if (Debug)    {      fprintf (stderr, "%s: found quote character.\n", Progname);    }          s++;    is_quoted = 1;  }  for (t = s; *t && --l > 0; t++)  {    if (*t == '\\' && !t[1])      break;    if (is_quoted && *t == '\\')    {      switch ((*d = *++t))      {	case 'n': *d = '\n'; break;	case 't': *d = '\t'; break;	case 'r': *d = '\r'; break;	case 'a': *d = '\a'; break;      }      d++;      continue;    }    if (is_quoted && *t == '"')    {      t++;      break;    }    else if (!is_quoted && strchr (single_char_tokens, *t))      break;    else if (!is_quoted && isspace ((unsigned char) *t))      break;    else      *d++ = *t;  }  *d = '\0';  if (Debug)  {    fprintf (stderr, "%s: Got %stoken: `%s'.\n",	     Progname, is_quoted ? "quoted " : "", dd);    fprintf (stderr, "%s: Remainder: `%s'.\n",	     Progname, t);  }    return t;}/** ** Configuration line parser **  ** The following code parses a line from init.h which declares ** a configuration variable. ** **//* note: the following enum must be in the same order as the * following string definitions! */enum {  DT_NONE = 0,  DT_BOOL,  DT_NUM,  DT_STR,  DT_PATH,  DT_QUAD,  DT_SORT,  DT_RX,  DT_MAGIC,  DT_SYN,  DT_ADDR};struct {  char *machine;  char *human;}types[] = {  { "DT_NONE",	"-none-" 	},  { "DT_BOOL",  "boolean"	},  { "DT_NUM",   "number"	},  { "DT_STR",	"string"	},  { "DT_PATH",	"path"		},  { "DT_QUAD",	"quadoption"	},  { "DT_SORT",	"sort order"	},  { "DT_RX",	"regular expression" },  { "DT_MAGIC",	"folder magic" },  { "DT_SYN",	NULL },  { "DT_ADDR",	"e-mail address" },  { NULL, NULL }};    static int buff2type (const char *s){  int type;    for (type = DT_NONE; types[type].machine; type++)    if (!strcmp (types[type].machine, s))	return type;    return DT_NONE;}static const char *type2human (int type){  return types[type].human;}static void handle_confline (char *s, FILE *out){  char varname[BUFFSIZE];  char buff[BUFFSIZE];  char tmp[BUFFSIZE];  int type;    char val[BUFFSIZE];  /* xxx - put this into an actual state machine? */  /* variable name */  if (!(s = get_token (varname, sizeof (varname), s))) return;    /* comma */  if (!(s = get_token (buff, sizeof (buff), s))) return;      /* type */  if (!(s = get_token (buff, sizeof (buff), s))) return;  type = buff2type (buff);  /* possibly a "|" or comma */  if (!(s = get_token (buff, sizeof (buff), s))) return;  if (!strcmp (buff, "|"))  {    if (Debug) fprintf (stderr, "%s: Expecting <subtype> <comma>.\n", Progname);    /* ignore subtype and comma */    if (!(s = get_token (buff, sizeof (buff), s))) return;    if (!(s = get_token (buff, sizeof (buff), s))) return;  }  /* redraw, comma */    while (1)  {    if (!(s = get_token (buff, sizeof (buff), s))) return;    if (!strcmp (buff, ","))      break;  }  /* option name or UL &address */  if (!(s = get_token (buff, sizeof (buff), s))) return;  if (!strcmp (buff, "UL"))    if (!(s = get_token (buff, sizeof (buff), s))) return;  /* comma */  if (!(s = get_token (buff, sizeof (buff), s))) return;  if (Debug) fprintf (stderr, "%s: Expecting default value.\n", Progname);    /* <default value> or UL <default value> */  if (!(s = get_token (buff, sizeof (buff), s))) return;  if (!strcmp (buff, "UL"))  {    if (Debug) fprintf (stderr, "%s: Skipping UL.\n", Progname);    if (!(s = get_token (buff, sizeof (buff), s))) return;  }  memset (tmp, 0, sizeof (tmp));  do   {    if (!strcmp (buff, "}"))      break;    strncpy (tmp + strlen (tmp), buff, sizeof (tmp) - strlen (tmp));  }  while ((s = get_token (buff, sizeof (buff), s)));  pretty_default (val, sizeof (val), tmp, type);  print_confline (varname, type, val, out);}static void pretty_default (char *t, size_t l, const char *s, int type){  memset (t, 0, l);  l--;  switch (type)  {    case DT_QUAD:    {          if (!strcasecmp (s, "M_YES")) strncpy (t, "yes", l);      else if (!strcasecmp (s, "M_NO")) strncpy (t, "no", l);      else if (!strcasecmp (s, "M_ASKYES")) strncpy (t, "ask-yes", l);      else if (!strcasecmp (s, "M_ASKNO")) strncpy (t, "ask-no", l);      break;    }    case DT_BOOL:    {      if (atoi (s))	strncpy (t, "yes", l);      else	strncpy (t, "no", l);      break;    }    case DT_SORT:    {      /* heuristic! */      strncpy (t, s + 5, l);      for (; *t; t++) *t = tolower ((unsigned char) *t);      break;    }    case DT_MAGIC:    {      /* heuristic! */      strncpy (t, s + 2, l);      for (; *t; t++) *t = tolower ((unsigned char) *t);      break;    }    case DT_STR:    case DT_RX:    case DT_ADDR:    case DT_PATH:    {      if (!strcmp (s, "0"))	break;      /* fallthrough */    }    default:    {      strncpy (t, s, l);      break;    }  }}static void char_to_escape (char *dest, unsigned int c){  switch (c)  {    case '\r': strcpy (dest, "\\r"); break;	/* __STRCPY_CHECKED__ */    case '\n': strcpy (dest, "\\n"); break;	/* __STRCPY_CHECKED__ */    case '\t': strcpy (dest, "\\t"); break;	/* __STRCPY_CHECKED__ */    case '\f': strcpy (dest, "\\f"); break;	/* __STRCPY_CHECKED__ */    default: sprintf (dest, "\\%03o", c); break;  }}static void conf_char_to_escape (unsigned int c , FILE *out){  char buff[16];  char_to_escape (buff, c);  fputs (buff, out);}static void conf_print_strval (const char *v, FILE *out){  for (; *v; v++)  {    if (*v < ' ' || *v & 0x80)    {      conf_char_to_escape ((unsigned int) *v, out);      continue;    }    if (*v == '"'  || *v == '\\')      fputc ('\\', out);    fputc (*v, out);  }}static void man_print_strval (const char *v, FILE *out){  for (; *v; v++)  {    if (*v < ' ' || *v & 0x80)    {      fputc ('\\', out);      conf_char_to_escape ((unsigned int) *v, out);      continue;    }        if (*v == '"')      fputs ("\\(rq", out);    else if (*v == '\\')      fputs ("\\\\", out);    else      fputc (*v, out);  }}static void sgml_print_strval (const char *v, FILE *out){  char buff[16];  for (; *v; v++)  {    if (*v <  ' ' || *v & 0x80)    {      char_to_escape (buff, (unsigned int) *v);      sgml_fputs (buff, out);      continue;    }    sgml_fputc ((unsigned int) *v, out);  }}static int sgml_fputc (int c, FILE *out){  switch (c)  {    case '<': return fputs ("&lt;", out);    case '>': return fputs ("&gt;", out);    case '$': return fputs ("&dollar;", out);    case '_': return fputs ("&lowbar;", out);    case '%': return fputs ("&percnt;", out);    case '&': return fputs ("&amp;", out);    case '\\': return fputs ("&bsol;", out);    case '"': return fputs ("&quot;", out);    case '[': return fputs ("&lsqb;", out);    case ']': return fputs ("&rsqb;", out);    case '~': return fputs ("&tilde;", out);    default:  return fputc (c, out);  }}static int sgml_fputs (const char *s, FILE *out){  for (; *s; s++)    if (sgml_fputc ((unsigned int) *s, out) == EOF)      return EOF;    return 0;}/* reduce CDATA to ID */static int sgml_id_fputs (const char *s, FILE* out){  char id;  for (; *s; s++)  {    if (*s == '_')      id = '-';    else      id = *s;    if (fputc ((unsigned int) id, out) == EOF)      return EOF;  }  return 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -