From: Richard Russon Date: Sat, 25 Mar 2017 16:20:01 +0000 (+0000) Subject: build: remove forward declarations X-Git-Tag: neomutt-20170414~19^2~1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=24febad172a92903938d80bc96fc2451f7762eab;p=neomutt build: remove forward declarations --- diff --git a/doc/makedoc.c b/doc/makedoc.c index 05d580266..5b7d485f6 100644 --- a/doc/makedoc.c +++ b/doc/makedoc.c @@ -98,128 +98,6 @@ 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 = NULL; - - 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); - - return 0; -} - - -static void makedoc (FILE *in, FILE *out) -{ - char buffer[BUFFSIZE]; - char token[BUFFSIZE]; - char *p = NULL; - 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, "/*++*/") == 0) - active = 1; - else if (strcmp (token, "/*--*/") == 0) - { - docstat = flush_doc (docstat, out); - active = 0; - } - else if (active && ((strcmp (token, "/**") == 0) || (strcmp (token, "**") == 0))) - docstat = handle_docline (p, out, docstat); - else if (active && (strcmp (token, "{") == 0)) - { - docstat = flush_doc (docstat, out); - handle_confline (p, out); - } - } - flush_doc (docstat, out); - fputs ("\n", out); -} - /* skip whitespace */ static char *skip_ws (char *s) @@ -325,417 +203,519 @@ static char *get_token (char *d, size_t l, char *s) 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, - DT_MBCHARTBL -}; - -struct +static int sgml_fputc (int c, FILE *out) { - char *machine; - char *human; + switch (c) + { + /* the bare minimum for escaping */ + case '<': return fputs ("<", out); + case '>': return fputs (">", out); + case '&': return fputs ("&", out); + default: return fputc (c, out); + } } -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" }, - { "DT_MBCHARTBL", "string" }, - { NULL, NULL } -}; - -static int buff2type (const char *s) +static int sgml_fputs (const char *s, FILE *out) { - int type; - - for (type = DT_NONE; types[type].machine; type++) - if (strcmp (types[type].machine, s) == 0) - return type; - - return DT_NONE; -} + for (; *s; s++) + if (sgml_fputc ((unsigned int) *s, out) == EOF) + return EOF; -static const char *type2human (int type) -{ - return types[type].human; + return 0; } -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; +/* print something. */ - type = buff2type (buff); +static int print_it (int special, char *str, FILE *out, int docstat) +{ + int onl = docstat & (D_NL|D_NP); - /* possibly a "|" or comma */ - if (!(s = get_token (buff, sizeof (buff), s))) return; + docstat &= ~(D_NL|D_NP|D_INIT); - if (strcmp (buff, "|") == 0) + switch (OutputFormat) { - if (Debug) fprintf (stderr, "%s: Expecting .\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 */ + /* configuration file */ + case F_CONF: + { + switch (special) + { + static int Continuation = 0; - while (1) - { - if (!(s = get_token (buff, sizeof (buff), s))) return; - if (strcmp (buff, ",") == 0) - break; - } + case SP_END_FT: docstat &= ~(D_EM|D_BF|D_TT); break; + case SP_START_BF: docstat |= D_BF; break; + case SP_START_EM: docstat |= D_EM; break; + case SP_START_TT: docstat |= D_TT; break; + case SP_NEWLINE: + { + if (onl) + docstat |= onl; + else + { + fputs ("\n# ", out); + docstat |= D_NL; + } + if (docstat & D_DL) + ++ Continuation; + break; + } + case SP_NEWPAR: + { + if (onl & D_NP) + { + docstat |= onl; + break; + } - /* option name or UL &address */ - if (!(s = get_token (buff, sizeof (buff), s))) return; - if (strcmp (buff, "UL") == 0) - 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); - - /* or UL */ - if (!(s = get_token (buff, sizeof (buff), s))) return; - if (strcmp (buff, "UL") == 0) - { - if (Debug) fprintf (stderr, "%s: Skipping UL.\n", Progname); - if (!(s = get_token (buff, sizeof (buff), s))) return; - } - - memset (tmp, 0, sizeof (tmp)); + if (!(onl & D_NL)) + fputs ("\n# ", out); + fputs ("\n# ", out); + docstat |= D_NP; + break; + } + case SP_START_TAB: + { + if (!onl) + fputs ("\n# ", out); + docstat |= D_TAB; + break; + } + case SP_END_TAB: + { + docstat &= ~D_TAB; + docstat |= D_NL; + break; + } + case SP_START_DL: + { + docstat |= D_DL; + break; + } + case SP_DT: + { + Continuation = 0; + docstat |= D_DT; + break; + } + case SP_DD: + { + if (docstat & D_IL) + fputs ("- ", out); + Continuation = 0; + break; + } + case SP_END_DL: + { + Continuation = 0; + docstat &= ~D_DL; + break; + } + case SP_START_IL: + { + docstat |= D_IL; + break; + } + case SP_END_IL: + { + Continuation = 0; + docstat &= ~D_IL; + break; + } + case SP_STR: + { + if (Continuation) + { + Continuation = 0; + fputs (" ", out); + } + fputs (str, out); + if (docstat & D_DT) + { + int i; - do - { - if (strcmp (buff, "}") == 0) + for (i = strlen (str) ; i < 8 ; i++) + putc (' ', out); + docstat &= ~D_DT; + docstat |= D_NL; + } + break; + } + } 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); -} + /* manual page */ + case F_MAN: + { + switch (special) + { + case SP_END_FT: + { + fputs ("\\fP", out); + docstat &= ~(D_EM|D_BF|D_TT); + break; + } + case SP_START_BF: + { + fputs ("\\fB", out); + docstat |= D_BF; + docstat &= ~(D_EM|D_TT); + break; + } + case SP_START_EM: + { + fputs ("\\fI", out); + docstat |= D_EM; + docstat &= ~(D_BF|D_TT); + break; + } + case SP_START_TT: + { + fputs ("\\fC", out); + docstat |= D_TT; + docstat &= ~(D_BF|D_EM); + break; + } + case SP_NEWLINE: + { + if (onl) + docstat |= onl; + else + { + fputc ('\n', out); + docstat |= D_NL; + } + break; + } + case SP_NEWPAR: + { + if (onl & D_NP) + { + docstat |= onl; + break; + } -static void pretty_default (char *t, size_t l, const char *s, int type) -{ - memset (t, 0, l); - l--; + if (!(onl & D_NL)) + fputc ('\n', out); + fputs (".IP\n", out); - switch (type) - { - case DT_QUAD: - { - if (strcasecmp (s, "MUTT_YES") == 0) strncpy (t, "yes", l); - else if (strcasecmp (s, "MUTT_NO") == 0) strncpy (t, "no", l); - else if (strcasecmp (s, "MUTT_ASKYES") == 0) strncpy (t, "ask-yes", l); - else if (strcasecmp (s, "MUTT_ASKNO") == 0) strncpy (t, "ask-no", l); + docstat |= D_NP; + break; + } + case SP_START_TAB: + { + fputs ("\n.IP\n.EX\n", out); + docstat |= D_TAB | D_NL; + break; + } + case SP_END_TAB: + { + fputs ("\n.EE\n", out); + docstat &= ~D_TAB; + docstat |= D_NL; + break; + } + case SP_START_DL: + { + fputs (".RS\n.PD 0\n", out); + docstat |= D_DL; + break; + } + case SP_DT: + { + fputs (".TP\n", out); + break; + } + case SP_DD: + { + if (docstat & D_IL) + fputs (".TP\n\\(hy ", out); + else + fputs ("\n", out); + break; + } + case SP_END_DL: + { + fputs (".RE\n.PD 1", out); + docstat &= ~D_DL; + break; + } + case SP_START_IL: + { + fputs (".RS\n.PD 0\n", out); + docstat |= D_IL; + break; + } + case SP_END_IL: + { + fputs (".RE\n.PD 1", out); + docstat &= ~D_DL; + break; + } + case SP_STR: + { + while (*str) + { + for (; *str; str++) + { + if (*str == '"') + fputs ("\"", out); + else if (*str == '\\') + fputs ("\\\\", out); + else if (*str == '-') + fputs ("\\-", out); + else if (strncmp (str, "``", 2) == 0) + { + fputs ("\\(lq", out); + str++; + } + else if (strncmp (str, "''", 2) == 0) + { + fputs ("\\(rq", out); + str++; + } + else + fputc (*str, out); + } + } + break; + } + } break; } - case DT_BOOL: + + /* SGML based manual */ + case F_SGML: { - if (atoi (s)) - strncpy (t, "yes", l); - else - strncpy (t, "no", l); - break; - } - case DT_SORT: - { - /* heuristic! */ - if (strncmp (s, "SORT_", 5) != 0) - fprintf (stderr, - "WARNING: expected prefix of SORT_ for type DT_SORT instead of %s\n", s); - strncpy (t, s + 5, l); - for (; *t; t++) *t = tolower ((unsigned char) *t); - break; - } - case DT_MAGIC: - { - /* heuristic! */ - if (strncmp (s, "MUTT_", 5) != 0) - fprintf (stderr, - "WARNING: expected prefix of MUTT_ for type DT_MAGIC instead of %s\n", s); - strncpy (t, s + 5, l); - for (; *t; t++) *t = tolower ((unsigned char) *t); + switch (special) + { + case SP_END_FT: + { + if (docstat & D_EM) fputs ("", out); + if (docstat & D_BF) fputs ("", out); + if (docstat & D_TT) fputs ("", out); + docstat &= ~(D_EM|D_BF|D_TT); + break; + } + case SP_START_BF: + { + fputs ("", out); + docstat |= D_BF; + docstat &= ~(D_EM|D_TT); + break; + } + case SP_START_EM: + { + fputs ("", out); + docstat |= D_EM; + docstat &= ~(D_BF|D_TT); + break; + } + case SP_START_TT: + { + fputs ("", out); + docstat |= D_TT; + docstat &= ~(D_BF|D_EM); + break; + } + case SP_NEWLINE: + { + if (onl) + docstat |= onl; + else + { + fputc ('\n', out); + docstat |= D_NL; + } + break; + } + case SP_NEWPAR: + { + if (onl & D_NP) + { + docstat |= onl; + break; + } + + if (!(onl & D_NL)) + fputc ('\n', out); + if (docstat & D_PA) + fputs("\n", out); + fputs ("\n", out); + + docstat |= D_NP; + docstat |= D_PA; + + break; + } + case SP_END_PAR: + { + fputs ("\n", out); + docstat &= ~D_PA; + break; + } + case SP_START_TAB: + { + if (docstat & D_PA) + { + fputs ("\n\n", out); + docstat &= ~D_PA; + } + fputs ("\n\n", out); + docstat |= D_TAB | D_NL; + break; + } + case SP_END_TAB: + { + fputs ("", out); + docstat &= ~D_TAB; + docstat |= D_NL; + break; + } + case SP_START_DL: + { + if (docstat & D_PA) + { + fputs ("\n\n", out); + docstat &= ~D_PA; + } + fputs ("\n\n\n\n", out); + docstat |= D_DL; + break; + } + case SP_DT: + { + fputs ("", out); + break; + } + case SP_DD: + { + docstat |= D_DD; + if (docstat & D_DL) + fputs("", out); + else + fputs ("", out); + break; + } + case SP_END_DD: + { + if (docstat & D_DL) + fputs ("\n", out); + else + fputs ("", out); + docstat &= ~D_DD; + break; + } + case SP_END_DL: + { + fputs ("\n", out); + docstat &= ~(D_DD|D_DL); + break; + } + case SP_START_IL: + { + if (docstat & D_PA) + { + fputs ("\n\n", out); + docstat &= ~D_PA; + } + fputs ("\n\n", out); + docstat |= D_IL; + break; + } + case SP_END_IL: + { + fputs ("\n", out); + docstat &= ~(D_DD|D_DL); + break; + } + case SP_END_SECT: + { + fputs ("", out); + break; + } + case SP_STR: + { + if (docstat & D_TAB) + sgml_fputs (str, out); + else + { + while (*str) + { + for (; *str; str++) + { + if (strncmp (str, "``", 2) == 0) + { + fputs ("", out); + str++; + } + else if (strncmp (str, "''", 2) == 0) + { + fputs ("", out); + str++; + } + else + sgml_fputc (*str, out); + } + } + } + break; + } + } break; } - case DT_STR: - case DT_RX: - case DT_ADDR: - case DT_PATH: - case DT_MBCHARTBL: - { - if (strcmp (s, "0") == 0) - break; - /* fallthrough */ - } + /* make gcc happy (unreached) */ default: - { - strncpy (t, s, l); break; - } } + + return docstat; } -static void char_to_escape (char *dest, unsigned int c) +/* close eventually-open environments. */ + +static int fd_recurse = 0; + +static int flush_doc (int docstat, FILE *out) { - switch (c) + if (docstat & D_INIT) + return D_INIT; + + if (fd_recurse++) { - 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; + fprintf (stderr, "%s: Internal error, recursion in flush_doc()!\n", Progname); + exit (1); } -} -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 (docstat & (D_PA)) + docstat = print_it (SP_END_PAR, NULL, out, docstat); - if (*v == '"' || *v == '\\') - fputc ('\\', out); - fputc (*v, out); - } -} + if (docstat & (D_TAB)) + docstat = print_it (SP_END_TAB, NULL, out, docstat); -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 ("\"", out); - else if (*v == '\\') - fputs ("\\\\", out); - else if (*v == '-') - fputs ("\\-", out); - else - fputc (*v, out); - } -} + if (docstat & (D_DL)) + docstat = print_it (SP_END_DL, NULL, out, docstat); -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); - } -} + if (docstat & (D_EM | D_BF | D_TT)) + docstat = print_it (SP_END_FT, NULL, out, docstat); -static int sgml_fputc (int c, FILE *out) -{ - switch (c) - { - /* the bare minimum for escaping */ - case '<': return fputs ("<", out); - case '>': return fputs (">", out); - case '&': return fputs ("&", out); - default: return fputc (c, out); - } -} + docstat = print_it (SP_END_SECT, NULL, out, docstat); -static int sgml_fputs (const char *s, FILE *out) -{ - for (; *s; s++) - if (sgml_fputc ((unsigned int) *s, out) == EOF) - return EOF; + docstat = print_it (SP_NEWLINE, NULL, out, 0); - return 0; + fd_recurse--; + return D_INIT; } -/* reduce CDATA to ID */ -static int sgml_id_fputs (const char *s, FILE* out) +static int commit_buff (char *buff, char **d, FILE *out, int docstat) { - char id; - - if (*s == '<') - s++; - - for (; *s; s++) + if (*d > buff) { - if (*s == '_') - id = '-'; - else - id = *s; - if (*s == '>' && !*(s+1)) - break; - - if (fputc ((unsigned int) id, out) == EOF) - return EOF; + **d = '\0'; + docstat = print_it (SP_STR, buff, out, docstat); + *d = buff; } - return 0; -} - -static void print_confline (const char *varname, int type, const char *val, FILE *out) -{ - if (type == DT_SYN) return; - - switch (OutputFormat) - { - /* configuration file */ - case F_CONF: - { - if (type == DT_STR || type == DT_RX || type == DT_ADDR || type == DT_PATH || - type == DT_MBCHARTBL) - { - fprintf (out, "\n# set %s=\"", varname); - conf_print_strval (val, out); - fputs ("\"", out); - } - else if (type != DT_SYN) - fprintf (out, "\n# set %s=%s", varname, val); - - fprintf (out, "\n#\n# Name: %s", varname); - fprintf (out, "\n# Type: %s", type2human (type)); - if (type == DT_STR || type == DT_RX || type == DT_ADDR || type == DT_PATH || - type == DT_MBCHARTBL) - { - fputs ("\n# Default: \"", out); - conf_print_strval (val, out); - fputs ("\"", out); - } - else - fprintf (out, "\n# Default: %s", val); - - fputs ("\n# ", out); - break; - } - - /* manual page */ - case F_MAN: - { - fprintf (out, "\n.TP\n.B %s\n", varname); - fputs (".nf\n", out); - fprintf (out, "Type: %s\n", type2human (type)); - if (type == DT_STR || type == DT_RX || type == DT_ADDR || type == DT_PATH || - type == DT_MBCHARTBL) - { - fputs ("Default: \"", out); - man_print_strval (val, out); - fputs ("\"\n", out); - } - else { - fputs ("Default: ", out); - man_print_strval (val, out); - fputs ("\n", out); - } - - fputs (".fi", out); - - break; - } - - /* SGML based manual */ - case F_SGML: - { - fputs ("\n\n", out); - sgml_fputs (varname, out); - fprintf (out, "\nType: %s", type2human (type)); - - - if (type == DT_STR || type == DT_RX || type == DT_ADDR || type == DT_PATH || - type == DT_MBCHARTBL) - { - if (val && *val) - { - fputs ("\nDefault: ", out); - sgml_print_strval (val, out); - fputs ("", out); - } - else - { - fputs ("\nDefault: (empty)", out); - } - fputs ("\n", out); - } - else - fprintf (out, "\nDefault: %s\n", val); - break; - } - /* make gcc happy */ - default: - break; - } + return docstat; } /** @@ -767,644 +747,648 @@ static void print_confline (const char *varname, int type, const char *val, FILE ** This is used to protect indentations in tables. **/ -/* close eventually-open environments. */ - -static int fd_recurse = 0; - -static int flush_doc (int docstat, FILE *out) +/* reduce CDATA to ID */ +static int sgml_id_fputs (const char *s, FILE* out) { - if (docstat & D_INIT) - return D_INIT; - - if (fd_recurse++) - { - fprintf (stderr, "%s: Internal error, recursion in flush_doc()!\n", Progname); - exit (1); - } + char id; - if (docstat & (D_PA)) - docstat = print_it (SP_END_PAR, NULL, out, docstat); + if (*s == '<') + s++; - if (docstat & (D_TAB)) - docstat = print_it (SP_END_TAB, NULL, out, docstat); + for (; *s; s++) + { + if (*s == '_') + id = '-'; + else + id = *s; + if (*s == '>' && !*(s+1)) + break; - if (docstat & (D_DL)) - docstat = print_it (SP_END_DL, NULL, out, docstat); + if (fputc ((unsigned int) id, out) == EOF) + return EOF; + } - if (docstat & (D_EM | D_BF | D_TT)) - docstat = print_it (SP_END_FT, NULL, out, docstat); + return 0; +} - docstat = print_it (SP_END_SECT, NULL, out, docstat); +void print_ref (FILE *out, int output_dollar, const char *ref) +{ + switch (OutputFormat) + { + case F_CONF: + case F_MAN: + if (output_dollar) + putc ('$', out); + fputs (ref, out); + break; - docstat = print_it (SP_NEWLINE, NULL, out, 0); + case F_SGML: + fputs ("", out); + if (output_dollar) + fputc ('$', out); + sgml_fputs (ref, out); + fputs ("", out); + break; - fd_recurse--; - return D_INIT; + default: + break; + } } -/* print something. */ - -static int print_it (int special, char *str, FILE *out, int docstat) +static int handle_docline (char *l, FILE *out, int docstat) { - int onl = docstat & (D_NL|D_NP); + char buff[BUFFSIZE]; + char *s = NULL, *d = NULL; + l = skip_ws (l); - docstat &= ~(D_NL|D_NP|D_INIT); + if (Debug) + fprintf (stderr, "%s: handle_docline `%s'\n", Progname, l); - switch (OutputFormat) - { - /* configuration file */ - case F_CONF: + if (strncmp (l, ".pp", 3) == 0) + return print_it (SP_NEWPAR, NULL, out, docstat); + else if (strncmp (l, ".ts", 3) == 0) + return print_it (SP_START_TAB, NULL, out, docstat); + else if (strncmp (l, ".te", 3) == 0) + return print_it (SP_END_TAB, NULL, out, docstat); + else if (strncmp (l, ".dl", 3) == 0) + return print_it (SP_START_DL, NULL, out, docstat); + else if (strncmp (l, ".de", 3) == 0) + return print_it (SP_END_DL, NULL, out, docstat); + else if (strncmp (l, ".il", 3) == 0) + return print_it (SP_START_IL, NULL, out, docstat); + else if (strncmp (l, ".ie", 3) == 0) + return print_it (SP_END_IL, NULL, out, docstat); + else if (strncmp (l, ". ", 2) == 0) + *l = ' '; + + for (s = l, d = buff; *s; s++) + { + if (strncmp (s, "\\(as", 4) == 0) { - switch (special) + *d++ = '*'; + s += 3; + } + else if (strncmp (s, "\\(rs", 4) == 0) + { + *d++ = '\\'; + s += 3; + } + else if (strncmp (s, "\\fI", 3) == 0) + { + docstat = commit_buff (buff, &d, out, docstat); + docstat = print_it (SP_START_EM, NULL, out, docstat); + s += 2; + } + else if (strncmp (s, "\\fB", 3) == 0) + { + docstat = commit_buff (buff, &d, out, docstat); + docstat = print_it (SP_START_BF, NULL, out, docstat); + s += 2; + } + else if (strncmp (s, "\\fC", 3) == 0) + { + docstat = commit_buff (buff, &d, out, docstat); + docstat = print_it (SP_START_TT, NULL, out, docstat); + s += 2; + } + else if (strncmp (s, "\\fP", 3) == 0) + { + docstat = commit_buff (buff, &d, out, docstat); + docstat = print_it (SP_END_FT, NULL, out, docstat); + s += 2; + } + else if (strncmp (s, ".dt", 3) == 0) + { + if (docstat & D_DD) { - static int Continuation = 0; - - case SP_END_FT: docstat &= ~(D_EM|D_BF|D_TT); break; - case SP_START_BF: docstat |= D_BF; break; - case SP_START_EM: docstat |= D_EM; break; - case SP_START_TT: docstat |= D_TT; break; - case SP_NEWLINE: - { - if (onl) - docstat |= onl; - else - { - fputs ("\n# ", out); - docstat |= D_NL; - } - if (docstat & D_DL) - ++ Continuation; - break; - } - case SP_NEWPAR: - { - if (onl & D_NP) - { - docstat |= onl; - break; - } - - if (!(onl & D_NL)) - fputs ("\n# ", out); - fputs ("\n# ", out); - docstat |= D_NP; - break; - } - case SP_START_TAB: - { - if (!onl) - fputs ("\n# ", out); - docstat |= D_TAB; - break; - } - case SP_END_TAB: - { - docstat &= ~D_TAB; - docstat |= D_NL; - break; - } - case SP_START_DL: - { - docstat |= D_DL; - break; - } - case SP_DT: - { - Continuation = 0; - docstat |= D_DT; - break; - } - case SP_DD: - { - if (docstat & D_IL) - fputs ("- ", out); - Continuation = 0; - break; - } - case SP_END_DL: - { - Continuation = 0; - docstat &= ~D_DL; - break; - } - case SP_START_IL: - { - docstat |= D_IL; - break; - } - case SP_END_IL: - { - Continuation = 0; - docstat &= ~D_IL; - break; - } - case SP_STR: - { - if (Continuation) - { - Continuation = 0; - fputs (" ", out); - } - fputs (str, out); - if (docstat & D_DT) - { - int i; - - for (i = strlen (str) ; i < 8 ; i++) - putc (' ', out); - docstat &= ~D_DT; - docstat |= D_NL; - } - break; - } + docstat = commit_buff (buff, &d, out, docstat); + docstat = print_it (SP_END_DD, NULL, out, docstat); } - break; + docstat = commit_buff (buff, &d, out, docstat); + docstat = print_it (SP_DT, NULL, out, docstat); + s += 3; } - - /* manual page */ - case F_MAN: + else if (strncmp (s, ".dd", 3) == 0) { - switch (special) + if ((docstat & D_IL) && (docstat & D_DD)) { - case SP_END_FT: - { - fputs ("\\fP", out); - docstat &= ~(D_EM|D_BF|D_TT); - break; - } - case SP_START_BF: - { - fputs ("\\fB", out); - docstat |= D_BF; - docstat &= ~(D_EM|D_TT); - break; - } - case SP_START_EM: - { - fputs ("\\fI", out); - docstat |= D_EM; - docstat &= ~(D_BF|D_TT); - break; - } - case SP_START_TT: - { - fputs ("\\fC", out); - docstat |= D_TT; - docstat &= ~(D_BF|D_EM); - break; - } - case SP_NEWLINE: - { - if (onl) - docstat |= onl; - else - { - fputc ('\n', out); - docstat |= D_NL; - } - break; - } - case SP_NEWPAR: - { - if (onl & D_NP) - { - docstat |= onl; - break; - } + docstat = commit_buff (buff, &d, out, docstat); + docstat = print_it (SP_END_DD, NULL, out, docstat); + } + docstat = commit_buff (buff, &d, out, docstat); + docstat = print_it (SP_DD, NULL, out, docstat); + s += 3; + } + else if (*s == '$') + { + int output_dollar = 0; + char *ref = NULL; + char save; - if (!(onl & D_NL)) - fputc ('\n', out); - fputs (".IP\n", out); + ++s; + if (*s == '$') + { + output_dollar = 1; + ++s; + } + if (*s == '$') + { + *d++ = '$'; + } + else + { + ref = s; + while (isalnum ((unsigned char) *s) || (*s && strchr("-_<>", *s))) + ++s; - docstat |= D_NP; - break; - } - case SP_START_TAB: - { - fputs ("\n.IP\n.EX\n", out); - docstat |= D_TAB | D_NL; - break; - } - case SP_END_TAB: - { - fputs ("\n.EE\n", out); - docstat &= ~D_TAB; - docstat |= D_NL; - break; - } - case SP_START_DL: - { - fputs (".RS\n.PD 0\n", out); - docstat |= D_DL; - break; - } - case SP_DT: - { - fputs (".TP\n", out); - break; - } - case SP_DD: - { - if (docstat & D_IL) - fputs (".TP\n\\(hy ", out); - else - fputs ("\n", out); - break; - } - case SP_END_DL: - { - fputs (".RE\n.PD 1", out); - docstat &= ~D_DL; - break; - } - case SP_START_IL: - { - fputs (".RS\n.PD 0\n", out); - docstat |= D_IL; - break; - } - case SP_END_IL: - { - fputs (".RE\n.PD 1", out); - docstat &= ~D_DL; - break; - } - case SP_STR: - { - while (*str) - { - for (; *str; str++) - { - if (*str == '"') - fputs ("\"", out); - else if (*str == '\\') - fputs ("\\\\", out); - else if (*str == '-') - fputs ("\\-", out); - else if (strncmp (str, "``", 2) == 0) - { - fputs ("\\(lq", out); - str++; - } - else if (strncmp (str, "''", 2) == 0) - { - fputs ("\\(rq", out); - str++; - } - else - fputc (*str, out); - } - } - break; - } + docstat = commit_buff (buff, &d, out, docstat); + save = *s; + *s = 0; + print_ref (out, output_dollar, ref); + *s = save; + --s; + } + } + else + *d++ = *s; + } + + docstat = commit_buff (buff, &d, out, docstat); + return print_it (SP_NEWLINE, NULL, out, docstat); +} + +/* 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, + DT_MBCHARTBL +}; + +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" }, + { "DT_MBCHARTBL", "string" }, + { NULL, NULL } +}; + +static int buff2type (const char *s) +{ + int type; + + for (type = DT_NONE; types[type].machine; type++) + if (strcmp (types[type].machine, s) == 0) + return type; + + return DT_NONE; +} + +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, "MUTT_YES") == 0) strncpy (t, "yes", l); + else if (strcasecmp (s, "MUTT_NO") == 0) strncpy (t, "no", l); + else if (strcasecmp (s, "MUTT_ASKYES") == 0) strncpy (t, "ask-yes", l); + else if (strcasecmp (s, "MUTT_ASKNO") == 0) 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! */ + if (strncmp (s, "SORT_", 5) != 0) + fprintf (stderr, + "WARNING: expected prefix of SORT_ for type DT_SORT instead of %s\n", s); + strncpy (t, s + 5, l); + for (; *t; t++) *t = tolower ((unsigned char) *t); + break; + } + case DT_MAGIC: + { + /* heuristic! */ + if (strncmp (s, "MUTT_", 5) != 0) + fprintf (stderr, + "WARNING: expected prefix of MUTT_ for type DT_MAGIC instead of %s\n", s); + strncpy (t, s + 5, l); + for (; *t; t++) *t = tolower ((unsigned char) *t); + break; + } + case DT_STR: + case DT_RX: + case DT_ADDR: + case DT_PATH: + case DT_MBCHARTBL: + { + if (strcmp (s, "0") == 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 const char *type2human (int type) +{ + return types[type].human; +} + +/** + ** Configuration line parser + ** + ** The following code parses a line from init.h which declares + ** a configuration variable. + ** + **/ + +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 ("\"", out); + else if (*v == '\\') + fputs ("\\\\", 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 void print_confline (const char *varname, int type, const char *val, FILE *out) +{ + if (type == DT_SYN) return; + + switch (OutputFormat) + { + /* configuration file */ + case F_CONF: + { + if (type == DT_STR || type == DT_RX || type == DT_ADDR || type == DT_PATH || + type == DT_MBCHARTBL) + { + fprintf (out, "\n# set %s=\"", varname); + conf_print_strval (val, out); + fputs ("\"", out); + } + else if (type != DT_SYN) + fprintf (out, "\n# set %s=%s", varname, val); + + fprintf (out, "\n#\n# Name: %s", varname); + fprintf (out, "\n# Type: %s", type2human (type)); + if (type == DT_STR || type == DT_RX || type == DT_ADDR || type == DT_PATH || + type == DT_MBCHARTBL) + { + fputs ("\n# Default: \"", out); + conf_print_strval (val, out); + fputs ("\"", out); } + else + fprintf (out, "\n# Default: %s", val); + + fputs ("\n# ", out); break; } - /* SGML based manual */ - case F_SGML: + /* manual page */ + case F_MAN: { - switch (special) + fprintf (out, "\n.TP\n.B %s\n", varname); + fputs (".nf\n", out); + fprintf (out, "Type: %s\n", type2human (type)); + if (type == DT_STR || type == DT_RX || type == DT_ADDR || type == DT_PATH || + type == DT_MBCHARTBL) { - case SP_END_FT: - { - if (docstat & D_EM) fputs ("", out); - if (docstat & D_BF) fputs ("", out); - if (docstat & D_TT) fputs ("", out); - docstat &= ~(D_EM|D_BF|D_TT); - break; - } - case SP_START_BF: - { - fputs ("", out); - docstat |= D_BF; - docstat &= ~(D_EM|D_TT); - break; - } - case SP_START_EM: - { - fputs ("", out); - docstat |= D_EM; - docstat &= ~(D_BF|D_TT); - break; - } - case SP_START_TT: - { - fputs ("", out); - docstat |= D_TT; - docstat &= ~(D_BF|D_EM); - break; - } - case SP_NEWLINE: - { - if (onl) - docstat |= onl; - else - { - fputc ('\n', out); - docstat |= D_NL; - } - break; - } - case SP_NEWPAR: - { - if (onl & D_NP) - { - docstat |= onl; - break; - } + fputs ("Default: \"", out); + man_print_strval (val, out); + fputs ("\"\n", out); + } + else { + fputs ("Default: ", out); + man_print_strval (val, out); + fputs ("\n", out); + } - if (!(onl & D_NL)) - fputc ('\n', out); - if (docstat & D_PA) - fputs("\n", out); - fputs ("\n", out); + fputs (".fi", out); - docstat |= D_NP; - docstat |= D_PA; + break; + } - break; - } - case SP_END_PAR: - { - fputs ("\n", out); - docstat &= ~D_PA; - break; - } - case SP_START_TAB: - { - if (docstat & D_PA) - { - fputs ("\n\n", out); - docstat &= ~D_PA; - } - fputs ("\n\n", out); - docstat |= D_TAB | D_NL; - break; - } - case SP_END_TAB: - { - fputs ("", out); - docstat &= ~D_TAB; - docstat |= D_NL; - break; - } - case SP_START_DL: - { - if (docstat & D_PA) - { - fputs ("\n\n", out); - docstat &= ~D_PA; - } - fputs ("\n\n\n\n", out); - docstat |= D_DL; - break; - } - case SP_DT: - { - fputs ("", out); - break; - } - case SP_DD: - { - docstat |= D_DD; - if (docstat & D_DL) - fputs("", out); - else - fputs ("", out); - break; - } - case SP_END_DD: - { - if (docstat & D_DL) - fputs ("\n", out); - else - fputs ("", out); - docstat &= ~D_DD; - break; - } - case SP_END_DL: - { - fputs ("\n", out); - docstat &= ~(D_DD|D_DL); - break; - } - case SP_START_IL: - { - if (docstat & D_PA) - { - fputs ("\n\n", out); - docstat &= ~D_PA; - } - fputs ("\n\n", out); - docstat |= D_IL; - break; - } - case SP_END_IL: + /* SGML based manual */ + case F_SGML: + { + fputs ("\n\n", out); + sgml_fputs (varname, out); + fprintf (out, "\nType: %s", type2human (type)); + + if (type == DT_STR || type == DT_RX || type == DT_ADDR || type == DT_PATH || + type == DT_MBCHARTBL) + { + if (val && *val) { - fputs ("\n", out); - docstat &= ~(D_DD|D_DL); - break; + fputs ("\nDefault: ", out); + sgml_print_strval (val, out); + fputs ("", out); } - case SP_END_SECT: - { - fputs ("", out); - break; - } - case SP_STR: + else { - if (docstat & D_TAB) - sgml_fputs (str, out); - else - { - while (*str) - { - for (; *str; str++) - { - if (strncmp (str, "``", 2) == 0) - { - fputs ("", out); - str++; - } - else if (strncmp (str, "''", 2) == 0) - { - fputs ("", out); - str++; - } - else - sgml_fputc (*str, out); - } - } - } - break; + fputs ("\nDefault: (empty)", out); } + fputs ("\n", out); } + else + fprintf (out, "\nDefault: %s\n", val); break; } - /* make gcc happy (unreached) */ + /* make gcc happy */ default: break; } +} + +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, "|") == 0) + { + if (Debug) fprintf (stderr, "%s: Expecting .\n", Progname); + /* ignore subtype and comma */ + if (!(s = get_token (buff, sizeof (buff), s))) return; + if (!(s = get_token (buff, sizeof (buff), s))) return; + } - return docstat; -} + /* redraw, comma */ -void print_ref (FILE *out, int output_dollar, const char *ref) -{ - switch (OutputFormat) + while (1) { - case F_CONF: - case F_MAN: - if (output_dollar) - putc ('$', out); - fputs (ref, out); - break; + if (!(s = get_token (buff, sizeof (buff), s))) return; + if (strcmp (buff, ",") == 0) + break; + } - case F_SGML: - fputs ("", out); - if (output_dollar) - fputc ('$', out); - sgml_fputs (ref, out); - fputs ("", out); - break; + /* option name or UL &address */ + if (!(s = get_token (buff, sizeof (buff), s))) return; + if (strcmp (buff, "UL") == 0) + if (!(s = get_token (buff, sizeof (buff), s))) return; - default: - break; + /* comma */ + if (!(s = get_token (buff, sizeof (buff), s))) return; + + if (Debug) fprintf (stderr, "%s: Expecting default value.\n", Progname); + + /* or UL */ + if (!(s = get_token (buff, sizeof (buff), s))) return; + if (strcmp (buff, "UL") == 0) + { + if (Debug) fprintf (stderr, "%s: Skipping UL.\n", Progname); + if (!(s = get_token (buff, sizeof (buff), s))) return; } -} -static int commit_buff (char *buff, char **d, FILE *out, int docstat) -{ - if (*d > buff) + memset (tmp, 0, sizeof (tmp)); + + do { - **d = '\0'; - docstat = print_it (SP_STR, buff, out, docstat); - *d = buff; + if (strcmp (buff, "}") == 0) + break; + + strncpy (tmp + strlen (tmp), buff, sizeof (tmp) - strlen (tmp)); } + while ((s = get_token (buff, sizeof (buff), s))); - return docstat; + pretty_default (val, sizeof (val), tmp, type); + print_confline (varname, type, val, out); } -static int handle_docline (char *l, FILE *out, int docstat) +static void makedoc (FILE *in, FILE *out) { - char buff[BUFFSIZE]; - char *s = NULL, *d = NULL; - l = skip_ws (l); - - if (Debug) - fprintf (stderr, "%s: handle_docline `%s'\n", Progname, l); - - if (strncmp (l, ".pp", 3) == 0) - return print_it (SP_NEWPAR, NULL, out, docstat); - else if (strncmp (l, ".ts", 3) == 0) - return print_it (SP_START_TAB, NULL, out, docstat); - else if (strncmp (l, ".te", 3) == 0) - return print_it (SP_END_TAB, NULL, out, docstat); - else if (strncmp (l, ".dl", 3) == 0) - return print_it (SP_START_DL, NULL, out, docstat); - else if (strncmp (l, ".de", 3) == 0) - return print_it (SP_END_DL, NULL, out, docstat); - else if (strncmp (l, ".il", 3) == 0) - return print_it (SP_START_IL, NULL, out, docstat); - else if (strncmp (l, ".ie", 3) == 0) - return print_it (SP_END_IL, NULL, out, docstat); - else if (strncmp (l, ". ", 2) == 0) - *l = ' '; + char buffer[BUFFSIZE]; + char token[BUFFSIZE]; + char *p = NULL; + int active = 0; + int line = 0; + int docstat = D_INIT; - for (s = l, d = buff; *s; s++) + while ((fgets (buffer, sizeof (buffer), in))) { - if (strncmp (s, "\\(as", 4) == 0) - { - *d++ = '*'; - s += 3; - } - else if (strncmp (s, "\\(rs", 4) == 0) - { - *d++ = '\\'; - s += 3; - } - else if (strncmp (s, "\\fI", 3) == 0) + line++; + if ((p = strchr (buffer, '\n')) == NULL) { - docstat = commit_buff (buff, &d, out, docstat); - docstat = print_it (SP_START_EM, NULL, out, docstat); - s += 2; + fprintf (stderr, "%s: Line %d too long. Ask a wizard to enlarge\n" + "%s: my buffer size.\n", Progname, line, Progname); + exit (1); } - else if (strncmp (s, "\\fB", 3) == 0) + else + *p = '\0'; + + if (!(p = get_token (token, sizeof (token), buffer))) + continue; + + if (Debug) { - docstat = commit_buff (buff, &d, out, docstat); - docstat = print_it (SP_START_BF, NULL, out, docstat); - s += 2; + fprintf (stderr, "%s: line %d. first token: \"%s\".\n", + Progname, line, token); } - else if (strncmp (s, "\\fC", 3) == 0) + + if (strcmp (token, "/*++*/") == 0) + active = 1; + else if (strcmp (token, "/*--*/") == 0) { - docstat = commit_buff (buff, &d, out, docstat); - docstat = print_it (SP_START_TT, NULL, out, docstat); - s += 2; + docstat = flush_doc (docstat, out); + active = 0; } - else if (strncmp (s, "\\fP", 3) == 0) + else if (active && ((strcmp (token, "/**") == 0) || (strcmp (token, "**") == 0))) + docstat = handle_docline (p, out, docstat); + else if (active && (strcmp (token, "{") == 0)) { - docstat = commit_buff (buff, &d, out, docstat); - docstat = print_it (SP_END_FT, NULL, out, docstat); - s += 2; + docstat = flush_doc (docstat, out); + handle_confline (p, out); } - else if (strncmp (s, ".dt", 3) == 0) + } + flush_doc (docstat, out); + fputs ("\n", out); +} + +int main (int argc, char *argv[]) +{ + int c; + FILE *f = NULL; + + if ((Progname = strrchr (argv[0], '/'))) + Progname++; + else + Progname = argv[0]; + + while ((c = getopt (argc, argv, "cmsd")) != EOF) + { + switch (c) { - if (docstat & D_DD) + case 'c': OutputFormat = F_CONF; break; + case 'm': OutputFormat = F_MAN; break; + case 's': OutputFormat = F_SGML; break; + case 'd': Debug++; break; + default: { - docstat = commit_buff (buff, &d, out, docstat); - docstat = print_it (SP_END_DD, NULL, out, docstat); + fprintf (stderr, "%s: bad command line parameter.\n", Progname); + exit (1); } - docstat = commit_buff (buff, &d, out, docstat); - docstat = print_it (SP_DT, NULL, out, docstat); - s += 3; } - else if (strncmp (s, ".dd", 3) == 0) + } + + if (optind != argc) + { + if ((f = fopen (argv[optind], "r")) == NULL) { - if ((docstat & D_IL) && (docstat & D_DD)) - { - docstat = commit_buff (buff, &d, out, docstat); - docstat = print_it (SP_END_DD, NULL, out, docstat); - } - docstat = commit_buff (buff, &d, out, docstat); - docstat = print_it (SP_DD, NULL, out, docstat); - s += 3; + fprintf (stderr, "%s: Can't open %s (%s).\n", + Progname, argv[optind], strerror (errno)); + exit (1); } - else if (*s == '$') - { - int output_dollar = 0; - char *ref = NULL; - char save; - - ++s; - if (*s == '$') - { - output_dollar = 1; - ++s; - } - if (*s == '$') - { - *d++ = '$'; - } - else - { - ref = s; - while (isalnum ((unsigned char) *s) || (*s && strchr("-_<>", *s))) - ++s; + } + else + f = stdin; - docstat = commit_buff (buff, &d, out, docstat); - save = *s; - *s = 0; - print_ref (out, output_dollar, ref); - *s = save; - --s; - } + 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); } - else - *d++ = *s; } - docstat = commit_buff (buff, &d, out, docstat); - return print_it (SP_NEWLINE, NULL, out, docstat); + if (f != stdin) + fclose (f); + + return 0; } +