/*
Copyright (C) 1999 John W. Eaton
This file is part of Octave.
Octave 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, or (at your option) any
later version.
Octave 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 Octave; see the file COPYING. If not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#if defined (__DECCXX)
#define __USE_STD_IOSTREAM
#endif
#include <cctype>
#include <iostream>
#include <fstream>
#include <string>
#include <map>
static const char doc_delim = '';
static std::map<std::string, std::string> help_text;
static void
fatal (const std::string& msg)
{
std::cerr << msg << "\n";
exit (1);
}
static void
usage (void)
{
std::cerr << "usage: munge-texi -d DOCSTRING-FILE file ...\n";
exit (1);
}
static std::string
extract_symbol_name (std::istream& is)
{
std::string symbol_name;
int c;
while ((c = is.get ()) != EOF && c != '\n')
symbol_name += (char) c;
return symbol_name;
}
static std::string
extract_docstring (std::istream& is)
{
std::string doc;
int c;
while ((c = is.get ()) != EOF && c != doc_delim)
doc += (char) c;
return doc;
}
static void
process_doc_file (const std::string& fname)
{
std::ifstream infile (fname.c_str ());
if (infile)
{
if (infile.get () != doc_delim)
fatal ("invalid doc file format");
std::string symbol_name;
do
{
symbol_name = extract_symbol_name (infile);
if (! symbol_name.empty ())
{
std::string doc_string = extract_docstring (infile);
if (help_text.find (symbol_name) != help_text.end ())
std::cerr << "ignoring duplicate entry for "
<< symbol_name << "\n";
else
help_text[symbol_name] = doc_string;
}
}
while (! symbol_name.empty ());
}
else
fatal ("unable to open docfile");
}
static void
process_texi_input_file (std::istream& is, std::ostream& os)
{
os << "@c DO NOT EDIT! Generated automatically by munge-texi.\n\n";
bool bol = true;
int c;
while ((c = is.get ()) != EOF)
{
if (bol)
{
if (c == '@')
{
std::string symbol_name;
char buf[16];
int i = 0;
buf[i++] = c;
if ((buf[i++] = (char) is.get ()) == 'D'
&& (buf[i++] = (char) is.get ()) == 'O'
&& (buf[i++] = (char) is.get ()) == 'C'
&& (buf[i++] = (char) is.get ()) == 'S'
&& (buf[i++] = (char) is.get ()) == 'T'
&& (buf[i++] = (char) is.get ()) == 'R'
&& (buf[i++] = (char) is.get ()) == 'I'
&& (buf[i++] = (char) is.get ()) == 'N'
&& (buf[i++] = (char) is.get ()) == 'G'
&& (buf[i++] = (char) is.get ()) == '(')
{
while ((c = is.get ()) != EOF && c != ')')
symbol_name += (char) c;
if (is.eof ())
fatal ("end of file while reading @DOCSTRING command");
else
{
std::string doc_string = help_text[symbol_name];
int j = 0;
while (doc_string[j] == ' ')
j++;
if (doc_string.substr (j, 15) == "-*- texinfo -*-")
{
j += 15;
while (isspace (doc_string[j]))
j++;
// Make `see also' references in functions
// possible using @anchor{TAG} (new with
// Texinfo 4.0).
os << "@anchor{doc-" << symbol_name << "}\n";
os << doc_string.substr (j);
}
else
os << doc_string;
}
}
else
{
buf[i] = '\0';
os << buf;
if (buf[i - 1] == '\n')
bol = true;
}
}
else
os.put ((char) c);
}
else
{
if (c == '\n')
bol = true;
os.put ((char) (c));
}
}
}
int
main (int argc, char **argv)
{
while (*++argv)
{
if (! strcmp (*argv, "-d"))
{
if (*++argv)
process_doc_file (*argv);
else
usage ();
}
else
break;
}
process_texi_input_file (std::cin, std::cout);
return 0;
}
/*
;;; Local Variables: ***
;;; mode: C++ ***
;;; End: ***
*/
syntax highlighted by Code2HTML, v. 0.9.1