1
/* yat2m.c - Yet Another Texi 2 Man converter
2
* Copyright (C) 2005 g10 Code GmbH
3
* Copyright (C) 2006 2006 Free Software Foundation, Inc.
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22
This is a simple textinfo to man page converter. It needs some
23
special markup in th e texinfo and tries best to get a create man
24
page. It has been designed for the GnuPG man pages and thus only
25
a few texinfo commands are supported.
27
To use this you need to add the following macros into your texinfo
39
They are used by yat2m to select parts of the Texinfo which should
40
go into the man page. These macros need to be used without leading
41
left space. Processing starts after a "manpage" macro has been
42
seen. "mansect" identifies the section and yat2m make sure to
43
emit the sections in the proper order. Note that @mansect skips
44
the next input line if that line begins with @section, @subsection or
47
To insert verbatim troff markup, the follwing texinfo code may be
54
alternativly a special comment may be used:
56
@c man:.B whatever you want
58
This is useful in case you need just one line. If you want to
59
include parts only in the man page but keep the texinfo
60
translation you may use:
63
stuff to be rendered only on man pages
66
or to exclude stuff from man pages:
69
stuff not to be rendered on man pages
72
the keyword @section is ignored, however @subsection gets rendered
73
as ".SS". @menu is completely skipped. Several man pages may be
74
extracted from one file, either using the --store or the --select
94
/* The maximum length of a line including the linefeed and one extra
102
static const char *opt_source;
103
static const char *opt_release;
104
static const char *opt_select;
105
static const char *opt_include;
106
static int opt_store;
108
/* The only define we understand is -D gpgone. Thus we need a simple
109
boolean tro track it. */
110
static int gpgone_defined;
112
/* Flag to keep track whether any error occurred. */
113
static int any_error;
116
/* Object to keep macro definitions. */
119
struct macro_s *next;
120
char *value; /* Malloced value. */
123
typedef struct macro_s *macro_t;
125
/* List of all defined macros. */
126
static macro_t macrolist;
129
/* Object to store one line of content. */
132
struct line_buffer_s *next;
133
int verbatim; /* True if LINE contains verbatim data. The default
134
is Texinfo source. */
137
typedef struct line_buffer_s *line_buffer_t;
140
/* Object to collect the data of a section. */
141
struct section_buffer_s
143
char *name; /* Malloced name of the section. This may be
144
NULL to indicate this slot is not used. */
145
line_buffer_t lines; /* Linked list with the lines of the section. */
146
line_buffer_t *lines_tail; /* Helper for faster appending to the
148
line_buffer_t last_line; /* Points to the last line appended. */
150
typedef struct section_buffer_s *section_buffer_t;
152
/* Variable to keep info about the current page together. */
155
/* Filename of the current page or NULL if no page is active. Malloced. */
158
/* Number of allocated elements in SECTIONS below. */
160
/* Array with the data of the sections. */
161
section_buffer_t sections;
166
/* The list of standard section names. COMMANDS and ASSUAN are GnuPG
168
static const char * const standard_sections[] =
169
{ "NAME", "SYNOPSIS", "DESCRIPTION",
170
"RETURN VALUE", "EXIT STATUS", "ERROR HANDLING", "ERRORS",
171
"COMMANDS", "OPTIONS", "USAGE", "EXAMPLES", "FILES",
172
"ENVIRONMENT", "DIAGNOSTICS", "SECURITY", "CONFORMING TO",
173
"ASSUAN", "NOTES", "BUGS", "AUTHOR", "SEE ALSO", NULL };
176
/*-- Local prototypes. --*/
177
static void proc_texi_buffer (FILE *fp, const char *line, size_t len,
178
int *table_level, int *eol_action);
182
/* Print diagnostic message and exit with failure. */
184
die (const char *format, ...)
189
fprintf (stderr, "%s: ", PGM);
191
va_start (arg_ptr, format);
192
vfprintf (stderr, format, arg_ptr);
200
/* Print diagnostic message. */
202
err (const char *format, ...)
207
if (strncmp (format, "%s:%d:", 6))
208
fprintf (stderr, "%s: ", PGM);
210
va_start (arg_ptr, format);
211
vfprintf (stderr, format, arg_ptr);
217
/* Print diagnostic message. */
219
inf (const char *format, ...)
224
fprintf (stderr, "%s: ", PGM);
226
va_start (arg_ptr, format);
227
vfprintf (stderr, format, arg_ptr);
236
void *p = malloc (n);
238
die ("out of core: %s", strerror (errno));
243
xcalloc (size_t n, size_t m)
245
void *p = calloc (n, m);
247
die ("out of core: %s", strerror (errno));
252
xrealloc (void *old, size_t n)
254
void *p = realloc (old, n);
256
die ("out of core: %s", strerror (errno));
261
xstrdup (const char *string)
263
void *p = malloc (strlen (string)+1);
265
die ("out of core: %s", strerror (errno));
271
/* Uppercase the ascii characters in STRING. */
273
ascii_strupr (char *string)
277
for (p = string; *p; p++)
284
/* Return the current date as an ISO string. */
288
static char buffer[11+5];
290
time_t atime = time (NULL);
293
strcpy (buffer, "????" "-??" "-??");
296
tp = gmtime (&atime);
297
sprintf (buffer,"%04d-%02d-%02d",
298
1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
305
/* Return a section buffer for the section NAME. Allocate a new buffer
306
if this is a new section. Keep track of the sections in THEPAGE.
307
This function may reallocate the section array in THEPAGE. */
308
static section_buffer_t
309
get_section_buffer (const char *name)
312
section_buffer_t sect;
314
/* If there is no section we put everything into the required NAME
315
section. Given that this is the first one listed it is likely
316
that error are easily visible. */
320
for (i=0; i < thepage.n_sections; i++)
322
sect = thepage.sections + i;
323
if (sect->name && !strcmp (name, sect->name))
326
for (i=0; i < thepage.n_sections; i++)
327
if (!thepage.sections[i].name)
329
if (i < thepage.n_sections)
330
sect = thepage.sections + i;
333
/* We need to allocate or reallocate the section array. */
334
size_t old_n = thepage.n_sections;
338
thepage.sections = xcalloc (new_n, sizeof *thepage.sections);
341
thepage.sections = xrealloc (thepage.sections,
343
* sizeof *thepage.sections));
344
memset (thepage.sections + old_n, 0,
345
new_n * sizeof *thepage.sections);
347
thepage.n_sections += new_n;
349
/* Setup the tail pointers. */
350
for (i=old_n; i < thepage.n_sections; i++)
352
sect = thepage.sections + i;
353
sect->lines_tail = §->lines;
355
sect = thepage.sections + old_n;
358
/* Store the name. */
359
assert (!sect->name);
360
sect->name = xstrdup (name);
366
/* Add the content of LINE to the section named SECTNAME. */
368
add_content (const char *sectname, char *line, int verbatim)
370
section_buffer_t sect;
373
sect = get_section_buffer (sectname);
374
if (sect->last_line && !sect->last_line->verbatim == !verbatim)
376
/* Lets append that line to the last one. We do this to keep
377
all lines of the same kind (i.e.verbatim or not) together in
381
lb = sect->last_line;
382
n1 = strlen (lb->line);
383
n = n1 + 1 + strlen (line) + 1;
384
lb->line = xrealloc (lb->line, n);
385
strcpy (lb->line+n1, "\n");
386
strcpy (lb->line+n1+1, line);
390
lb = xcalloc (1, sizeof *lb);
391
lb->verbatim = verbatim;
392
lb->line = xstrdup (line);
393
sect->last_line = lb;
394
*sect->lines_tail = lb;
395
sect->lines_tail = &lb->next;
400
/* Prepare for a new man page using the filename NAME. */
402
start_page (char *name)
405
inf ("starting page `%s'", name);
406
assert (!thepage.name);
407
thepage.name = xstrdup (name);
408
thepage.n_sections = 0;
412
/* Write the .TH entry of the current page. Return -1 if there is a
413
problem with the page. */
419
name = ascii_strupr (xstrdup (thepage.name));
420
p = strrchr (name, '.');
423
err ("no section name in man page `%s'", thepage.name);
428
fprintf (fp, ".TH %s %s %s \"%s\" \"%s\"\n",
429
name, p, isodatestring (), opt_release, opt_source);
434
/* Process the texinfo command COMMAND (without the leading @) and
435
write output if needed to FP. REST is the remainer of the line
436
which should either point to an opening brace or to a white space.
437
The function returns the number of characters already processed
438
from REST. LEN is the usable length of REST. TABLE_LEVEL is used to
439
control the indentation of tables. */
441
proc_texi_cmd (FILE *fp, const char *command, const char *rest, size_t len,
442
int *table_level, int *eol_action)
445
const char *name; /* Name of the command. */
446
int what; /* What to do with this command. */
447
const char *lead_in; /* String to print with a opening brace. */
448
const char *lead_out;/* String to print with the closing brace. */
450
{ "command", 0, "\\fB", "\\fR" },
451
{ "code", 0, "\\fB", "\\fR" },
452
{ "sc", 0, "\\fB", "\\fR" },
453
{ "var", 0, "\\fI", "\\fR" },
454
{ "samp", 0, "\n'", "'\n" },
455
{ "file", 0, "`\\fI","\\fR'" },
456
{ "env", 0, "`\\fI","\\fR'" },
459
{ "option", 0, "\\fB", "\\fR" },
460
{ "example", 1, ".RS 2\n.nf\n" },
461
{ "smallexample", 1, ".RS 2\n.nf\n" },
465
{ "xref", 0, "see: [", "]" },
466
{ "pxref", 0, "see: [", "]" },
467
{ "uref", 0, "(\\fB", "\\fR)" },
468
{ "footnote",0, " ([", "])" },
469
{ "emph", 0, "\\fI", "\\fR" },
478
{ "subsection", 6, "\n.SS " },
480
{ "item", 2, ".TP\n.B " },
481
{ "itemx", 2, ".TP\n.B " },
484
{ "bullet", 0, "* " },
486
{ "quotation",1, ".RS\n\\fB" },
492
const char *lead_out = NULL;
495
for (i=0; cmdtbl[i].name && strcmp (cmdtbl[i].name, command); i++)
499
s = cmdtbl[i].lead_in;
502
lead_out = cmdtbl[i].lead_out;
503
switch (cmdtbl[i].what)
505
case 1: /* Throw away the entire line. */
506
s = memchr (rest, '\n', len);
507
return s? (s-rest)+1 : len;
508
case 2: /* Handle @item. */
510
case 3: /* Handle table. */
511
if (++(*table_level) > 1)
513
/* Now throw away the entire line. */
514
s = memchr (rest, '\n', len);
515
return s? (s-rest)+1 : len;
517
case 4: /* Handle end. */
518
for (s=rest, n=len; n && (*s == ' ' || *s == '\t'); s++, n--)
520
if (n >= 5 && !memcmp (s, "table", 5)
521
&& (!n || s[5] == ' ' || s[5] == '\t' || s[5] == '\n'))
523
if ((*table_level)-- > 1)
526
else if (n >= 7 && !memcmp (s, "example", 7)
527
&& (!n || s[7] == ' ' || s[7] == '\t' || s[7] == '\n'))
529
fputs (".fi\n.RE\n", fp);
531
else if (n >= 12 && !memcmp (s, "smallexample", 12)
532
&& (!n || s[12] == ' ' || s[12] == '\t' || s[12] == '\n'))
534
fputs (".fi\n.RE\n", fp);
536
else if (n >= 9 && !memcmp (s, "quotation", 9)
537
&& (!n || s[9] == ' ' || s[9] == '\t' || s[9] == '\n'))
539
fputs ("\\fR\n.RE\n", fp);
541
/* Now throw away the entire line. */
542
s = memchr (rest, '\n', len);
543
return s? (s-rest)+1 : len;
544
case 5: /* Handle special comments. */
545
for (s=rest, n=len; n && (*s == ' ' || *s == '\t'); s++, n--)
547
if (n >= 4 && !memcmp (s, "man:", 4))
549
for (s+=4, n-=4; n && *s != '\n'; n--, s++)
553
/* Now throw away the entire line. */
554
s = memchr (rest, '\n', len);
555
return s? (s-rest)+1 : len;
570
for (m = macrolist; m ; m = m->next)
571
if (!strcmp (m->name, command))
575
proc_texi_buffer (fp, m->value, strlen (m->value),
576
table_level, eol_action);
577
ignore_args = 1; /* Parameterized macros are not yet supported. */
580
inf ("texinfo command `%s' not supported (%.*s)", command,
581
((s = memchr (rest, '\n', len)), (s? (s-rest) : len)), rest);
586
/* Find matching closing brace. */
587
for (s=rest+1, n=1, i=1; i && *s && n < len; s++, n++)
594
err ("closing brace for command `%s' not found", command);
597
if (n > 2 && !ignore_args)
598
proc_texi_buffer (fp, rest+1, n-2, table_level, eol_action);
604
fputs (lead_out, fp);
611
/* Process the string LINE with LEN bytes of Texinfo content. */
613
proc_texi_buffer (FILE *fp, const char *line, size_t len,
614
int *table_level, int *eol_action)
622
for (s=line; *s && len; s++, len--)
630
case '@': case '{': case '}':
631
putc (*s, fp); in_cmd = 0;
633
case ':': /* Not ending a sentence flag. */
636
case '.': case '!': case '?': /* Ending a sentence. */
637
putc (*s, fp); in_cmd = 0;
639
case ' ': case '\t': case '\n': /* Non collapsing spaces. */
640
putc (*s, fp); in_cmd = 0;
644
cmdbuf[cmdidx++] = *s;
649
else if (*s == '{' || *s == ' ' || *s == '\t' || *s == '\n')
652
n = proc_texi_cmd (fp, cmdbuf, s, len, table_level, eol_action);
658
else if (cmdidx < sizeof cmdbuf -1)
659
cmdbuf[cmdidx++] = *s;
662
err ("texinfo command too long - ignored");
672
case 1: /* Create a dummy paragraph. */
673
fputs ("\n\\ \n", fp);
687
n = proc_texi_cmd (fp, cmdbuf, s, len, table_level, eol_action);
696
/* Do something with the Texinfo line LINE. */
698
parse_texi_line (FILE *fp, const char *line, int *table_level)
702
/* A quick test whether there are any texinfo commands. */
703
if (!strchr (line, '@'))
709
proc_texi_buffer (fp, line, strlen (line), table_level, &eol_action);
714
/* Write all the lines LINES to FP. */
716
write_content (FILE *fp, line_buffer_t lines)
721
for (line = lines; line; line = line->next)
725
fputs (line->line, fp);
730
/* fputs ("TEXI---", fp); */
731
/* fputs (line->line, fp); */
732
/* fputs ("---\n", fp); */
733
parse_texi_line (fp, line->line, &table_level);
741
is_standard_section (const char *name)
746
for (i=0; (s=standard_sections[i]); i++)
747
if (!strcmp (s, name))
753
/* Finish a page; that is sort the data and write it out to the file. */
758
section_buffer_t sect;
764
return; /* No page active. */
767
inf ("finishing page `%s'", thepage.name);
771
if (!strcmp (opt_select, thepage.name))
773
inf ("selected `%s'", thepage.name );
778
fp = fopen ( "/dev/null", "w" );
780
die ("failed to open /dev/null: %s\n", strerror (errno));
785
inf ("writing `%s'", thepage.name );
786
fp = fopen ( thepage.name, "w" );
788
die ("failed to create `%s': %s\n", thepage.name, strerror (errno));
796
for (idx=0; (s=standard_sections[idx]); idx++)
798
for (i=0; i < thepage.n_sections; i++)
800
sect = thepage.sections + i;
801
if (sect->name && !strcmp (s, sect->name))
804
if (i == thepage.n_sections)
809
fprintf (fp, ".SH %s\n", sect->name);
810
write_content (fp, sect->lines);
811
/* Now continue with all non standard sections directly
812
following this one. */
813
for (i++; i < thepage.n_sections; i++)
815
sect = thepage.sections + i;
816
if (sect->name && is_standard_section (sect->name))
820
fprintf (fp, ".SH %s\n", sect->name);
821
write_content (fp, sect->lines);
834
/* FIXME: Cleanup the content. */
840
/* Parse one Texinfo file and create manpages according to the
841
embedded instructions. */
843
parse_file (const char *fname, FILE *fp, char **section_name, int in_pause)
847
/* Fixme: The follwing state variables don't carry over to include
850
int skip_to_end = 0; /* Used to skip over menu entries. */
851
int skip_sect_line = 0; /* Skip after @mansect. */
852
int ifset_nesting = 0; /* How often a ifset has been seen. */
853
int ifclear_nesting = 0; /* How often a ifclear has been seen. */
854
int in_gpgone = 0; /* Keep track of "@ifset gpgone" parts. */
855
int not_in_gpgone = 0; /* Keep track of "@ifclear gpgone" parts. */
856
int not_in_man = 0; /* Keep track of "@ifclear isman" parts. */
858
/* Helper to define a macro. */
859
char *macroname = NULL;
860
char *macrovalue = NULL;
861
size_t macrovaluesize = 0;
862
size_t macrovalueused = 0;
864
line = xmalloc (LINESIZE);
865
while (fgets (line, LINESIZE, fp))
867
size_t n = strlen (line);
872
if (!n || line[n-1] != '\n')
874
err ("%s:%d: trailing linefeed missing, line too long or "
875
"embedded Nul character", fname, lnr);
882
for (p=line+1, n=1; *p && *p != ' ' && *p != '\t'; p++)
884
while (*p == ' ' || *p == '\t')
890
/* Take action on macro. */
893
if (n == 4 && !memcmp (line, "@end", 4)
894
&& (line[4]==' '||line[4]=='\t'||!line[4])
895
&& !strncmp (p, "macro", 5)
896
&& (p[5]==' '||p[5]=='\t'||!p[5]))
901
macrovalue[--macrovalueused] = 0; /* Kill the last LF. */
902
macrovalue[macrovalueused] = 0; /* Terminate macro. */
903
macrovalue = xrealloc (macrovalue, macrovalueused+1);
905
for (m= macrolist; m; m = m->next)
906
if (!strcmp (m->name, macroname))
912
m = xcalloc (1, sizeof *m + strlen (macroname));
913
strcpy (m->name, macroname);
917
m->value = macrovalue;
924
if (macrovalueused + strlen (line) + 2 >= macrovaluesize)
926
macrovaluesize += strlen (line) + 256;
927
macrovalue = xrealloc (macrovalue, macrovaluesize);
929
strcpy (macrovalue+macrovalueused, line);
930
macrovalueused += strlen (line);
931
macrovalue[macrovalueused++] = '\n';
937
if (n >= 5 && !memcmp (line, "@node", 5)
938
&& (line[5]==' '||line[5]=='\t'||!line[5]))
940
/* Completey ignore @node lines. */
948
if (!strncmp (line, "@section", 8)
949
|| !strncmp (line, "@subsection", 11)
950
|| !strncmp (line, "@chapheading", 12))
954
/* We only parse lines we need and ignore the rest. There are a
955
few macros used to control this as well as one @ifset
956
command. Parts we know about are saved away into containers
957
separate for each section. */
959
/* First process ifset/ifclear commands. */
962
if (n == 6 && !memcmp (line, "@ifset", 6)
963
&& (line[6]==' '||line[6]=='\t'))
967
if (!strncmp (p, "manverb", 7) && (p[7]==' '||p[7]=='\t'||!p[7]))
970
err ("%s:%d: nested \"@ifset manverb\"", fname, lnr);
972
in_verbatim = ifset_nesting;
974
else if (!strncmp (p, "gpgone", 6)
975
&& (p[6]==' '||p[6]=='\t'||!p[6]))
978
err ("%s:%d: nested \"@ifset gpgone\"", fname, lnr);
980
in_gpgone = ifset_nesting;
984
else if (n == 4 && !memcmp (line, "@end", 4)
985
&& (line[4]==' '||line[4]=='\t')
986
&& !strncmp (p, "ifset", 5)
987
&& (p[5]==' '||p[5]=='\t'||!p[5]))
989
if (in_verbatim && ifset_nesting == in_verbatim)
991
if (in_gpgone && ifset_nesting == in_gpgone)
997
err ("%s:%d: unbalanced \"@end ifset\"", fname, lnr);
1000
else if (n == 8 && !memcmp (line, "@ifclear", 8)
1001
&& (line[8]==' '||line[8]=='\t'))
1005
if (!strncmp (p, "gpgone", 6)
1006
&& (p[6]==' '||p[6]=='\t'||!p[6]))
1009
err ("%s:%d: nested \"@ifclear gpgone\"", fname, lnr);
1011
not_in_gpgone = ifclear_nesting;
1014
else if (!strncmp (p, "isman", 5)
1015
&& (p[5]==' '||p[5]=='\t'||!p[5]))
1018
err ("%s:%d: nested \"@ifclear isman\"", fname, lnr);
1020
not_in_man = ifclear_nesting;
1025
else if (n == 4 && !memcmp (line, "@end", 4)
1026
&& (line[4]==' '||line[4]=='\t')
1027
&& !strncmp (p, "ifclear", 7)
1028
&& (p[7]==' '||p[7]=='\t'||!p[7]))
1030
if (not_in_gpgone && ifclear_nesting == not_in_gpgone)
1032
if (not_in_man && ifclear_nesting == not_in_man)
1035
if (ifclear_nesting)
1038
err ("%s:%d: unbalanced \"@end ifclear\"", fname, lnr);
1043
/* Take action on ifset/ifclear. */
1044
if ( (in_gpgone && !gpgone_defined)
1045
|| (not_in_gpgone && gpgone_defined)
1049
/* Process commands. */
1053
&& n == 4 && !memcmp (line, "@end", 4)
1054
&& (line[4]==' '||line[4]=='\t'||!line[4]))
1058
else if (in_verbatim)
1062
else if (n == 6 && !memcmp (line, "@macro", 6))
1064
macroname = xstrdup (p);
1065
macrovalue = xmalloc ((macrovaluesize = 1024));
1068
else if (n == 8 && !memcmp (line, "@manpage", 8))
1070
free (*section_name);
1071
*section_name = NULL;
1076
else if (n == 8 && !memcmp (line, "@mansect", 8))
1079
err ("%s:%d: section outside of a man page", fname, lnr);
1082
free (*section_name);
1083
*section_name = ascii_strupr (xstrdup (p));
1088
else if (n == 9 && !memcmp (line, "@manpause", 9))
1091
err ("%s:%d: pausing outside of a man section", fname, lnr);
1093
err ("%s:%d: already pausing", fname, lnr);
1097
else if (n == 8 && !memcmp (line, "@mancont", 8))
1100
err ("%s:%d: continue outside of a man section", fname, lnr);
1102
err ("%s:%d: continue while not pausing", fname, lnr);
1106
else if (n == 5 && !memcmp (line, "@menu", 5)
1107
&& (line[5]==' '||line[5]=='\t'||!line[5]))
1111
else if (n == 8 && !memcmp (line, "@include", 8)
1112
&& (line[8]==' '||line[8]=='\t'||!line[8]))
1114
char *incname = xstrdup (p);
1115
FILE *incfp = fopen (incname, "r");
1117
if (!incfp && opt_include && *opt_include && *p != '/')
1120
incname = xmalloc (strlen (opt_include) + 1
1122
strcpy (incname, opt_include);
1123
if ( incname[strlen (incname)-1] != '/' )
1124
strcat (incname, "/");
1125
strcat (incname, p);
1126
incfp = fopen (incname, "r");
1130
err ("can't open include file `%s':%s",
1131
incname, strerror (errno));
1134
parse_file (incname, incfp, section_name, in_pause);
1139
else if (n == 4 && !memcmp (line, "@bye", 4)
1140
&& (line[4]==' '||line[4]=='\t'||!line[4]))
1144
else if (!skip_to_end)
1147
else if (!skip_to_end)
1150
if (got_line && in_verbatim)
1151
add_content (*section_name, line, 1);
1152
else if (got_line && thepage.name && *section_name && !in_pause)
1153
add_content (*section_name, line, 0);
1157
err ("%s:%d: read error: %s", fname, lnr, strerror (errno));
1165
top_parse_file (const char *fname, FILE *fp)
1167
char *section_name = NULL; /* Name of the current section or NULL
1168
if not in a section. */
1171
macro_t m = macrolist->next;
1177
parse_file (fname, fp, §ion_name, 0);
1178
free (section_name);
1184
main (int argc, char **argv)
1195
while (argc && last_argc != argc )
1198
if (!strcmp (*argv, "--"))
1203
else if (!strcmp (*argv, "--help"))
1206
"Usage: " PGM " [OPTION] [FILE]\n"
1207
"Extract man pages from a Texinfo source.\n\n"
1208
" --source NAME use NAME as source field\n"
1209
" --release STRING use STRING as the release field\n"
1210
" --store write output using @manpage name\n"
1211
" --select NAME only output pages with @manpage NAME\n"
1212
" --verbose enable extra informational output\n"
1213
" --debug enable additional debug output\n"
1214
" --help display this help and exit\n"
1215
" -I DIR also search in include DIR\n"
1216
" -D gpgone the only useable define\n\n"
1217
"With no FILE, or when FILE is -, read standard input.\n\n"
1218
"Report bugs to <bugs@g10code.com>.");
1221
else if (!strcmp (*argv, "--version"))
1223
puts (PGM " " VERSION "\n"
1224
"Copyright (C) 2005 g10 Code GmbH\n"
1225
"This program comes with ABSOLUTELY NO WARRANTY.\n"
1226
"This is free software, and you are welcome to redistribute it\n"
1227
"under certain conditions. See the file COPYING for details.");
1230
else if (!strcmp (*argv, "--verbose"))
1235
else if (!strcmp (*argv, "--quiet"))
1240
else if (!strcmp (*argv, "--debug"))
1242
verbose = debug = 1;
1245
else if (!strcmp (*argv, "--source"))
1254
else if (!strcmp (*argv, "--release"))
1259
opt_release = *argv;
1263
else if (!strcmp (*argv, "--store"))
1268
else if (!strcmp (*argv, "--select"))
1273
opt_select = strrchr (*argv, '/');
1281
else if (!strcmp (*argv, "-I"))
1286
opt_include = *argv;
1290
else if (!strcmp (*argv, "-D"))
1295
if (!strcmp (*argv, "gpgone"))
1303
die ("usage: " PGM " [OPTION] [FILE] (try --help for more information)\n");
1305
/* Start processing. */
1306
if (argc && strcmp (*argv, "-"))
1308
FILE *fp = fopen (*argv, "rb");
1310
die ("%s:0: can't open file: %s", *argv, strerror (errno));
1311
top_parse_file (*argv, fp);
1315
top_parse_file ("-", stdin);
1323
compile-command: "gcc -Wall -g -Wall -o yat2m yat2m.c"